diff --git a/core/src/main/java/org/polypheny/db/algebra/enumerable/EnumerableRelIdentifier.java b/core/src/main/java/org/polypheny/db/algebra/enumerable/EnumerableRelIdentifier.java index d8048d2c19..41749a2843 100644 --- a/core/src/main/java/org/polypheny/db/algebra/enumerable/EnumerableRelIdentifier.java +++ b/core/src/main/java/org/polypheny/db/algebra/enumerable/EnumerableRelIdentifier.java @@ -50,9 +50,11 @@ public Result implement( EnumerableAlgImplementor implementor, Prefer pref ) { final PhysType physType = result.physType(); Expression input_ = builder.append( "input", result.block() ); - Expression identification_ = builder.append( "identification", Expressions.call( input_, BuiltInMethod.ADD_REL_IDENTIFIERS.method ) ); + Expression entity_ = Expressions.constant(entity); + Expression identification_ = builder.append( "identification", Expressions.call(BuiltInMethod.ADD_REL_IDENTIFIERS.method, input_, entity_ ) ); builder.add( Expressions.return_( null, identification_ ) ); + return implementor.result( physType, builder.toBlock() ); } diff --git a/core/src/main/java/org/polypheny/db/algebra/enumerable/EnumerableRelIdentifierRule.java b/core/src/main/java/org/polypheny/db/algebra/enumerable/EnumerableRelIdentifierRule.java index 176d391b51..73fcbd95b3 100644 --- a/core/src/main/java/org/polypheny/db/algebra/enumerable/EnumerableRelIdentifierRule.java +++ b/core/src/main/java/org/polypheny/db/algebra/enumerable/EnumerableRelIdentifierRule.java @@ -18,6 +18,7 @@ import org.polypheny.db.algebra.AlgNode; import org.polypheny.db.algebra.convert.ConverterRule; +import org.polypheny.db.algebra.core.AlgFactories; import org.polypheny.db.algebra.logical.relational.LogicalRelIdentifier; import org.polypheny.db.plan.AlgTraitSet; import org.polypheny.db.plan.Convention; @@ -25,7 +26,7 @@ public class EnumerableRelIdentifierRule extends ConverterRule { EnumerableRelIdentifierRule() { - super( LogicalRelIdentifier.class, Convention.NONE, EnumerableConvention.INSTANCE, "EnumerableRelIdentifierRule" ); + super( LogicalRelIdentifier.class, operand -> true, Convention.NONE, EnumerableConvention.INSTANCE, AlgFactories.LOGICAL_BUILDER,"EnumerableRelIdentifierRule" ); } diff --git a/core/src/main/java/org/polypheny/db/algebra/enumerable/document/EnumerableDocIdentifier.java b/core/src/main/java/org/polypheny/db/algebra/enumerable/document/EnumerableDocIdentifier.java index cf0604e170..3f83c4034b 100644 --- a/core/src/main/java/org/polypheny/db/algebra/enumerable/document/EnumerableDocIdentifier.java +++ b/core/src/main/java/org/polypheny/db/algebra/enumerable/document/EnumerableDocIdentifier.java @@ -54,7 +54,8 @@ public Result implement( EnumerableAlgImplementor implementor, Prefer pref ) { final PhysType physType = result.physType(); Expression input_ = builder.append( "input", result.block() ); - Expression identification_ = builder.append( "identification", Expressions.call( input_, BuiltInMethod.ADD_DOC_IDENTIFIERS.method ) ); + Expression entity_ = Expressions.constant(entity); + Expression identification_ = builder.append( "identification", Expressions.call(BuiltInMethod.ADD_REL_IDENTIFIERS.method, input_, entity_ ) ); builder.add( Expressions.return_( null, identification_ ) ); return implementor.result( physType, builder.toBlock() ); diff --git a/core/src/main/java/org/polypheny/db/algebra/enumerable/lpg/EnumerableLpgIdentifier.java b/core/src/main/java/org/polypheny/db/algebra/enumerable/lpg/EnumerableLpgIdentifier.java index 373034f5e3..23af27e281 100644 --- a/core/src/main/java/org/polypheny/db/algebra/enumerable/lpg/EnumerableLpgIdentifier.java +++ b/core/src/main/java/org/polypheny/db/algebra/enumerable/lpg/EnumerableLpgIdentifier.java @@ -56,7 +56,8 @@ public Result implement( EnumerableAlgImplementor implementor, Prefer pref ) { final PhysType physType = result.physType(); Expression input_ = builder.append( "input", result.block() ); - Expression identification_ = builder.append( "identification", Expressions.call( input_, BuiltInMethod.ADD_LPG_IDENTIFIERS.method ) ); + Expression entity_ = Expressions.constant(entity); + Expression identification_ = builder.append( "identification", Expressions.call(BuiltInMethod.ADD_REL_IDENTIFIERS.method, input_, entity_ ) ); builder.add( Expressions.return_( null, identification_ ) ); return implementor.result( physType, builder.toBlock() ); diff --git a/core/src/main/java/org/polypheny/db/catalog/entity/Entity.java b/core/src/main/java/org/polypheny/db/catalog/entity/Entity.java index 8235d96ae8..50830c5cd5 100644 --- a/core/src/main/java/org/polypheny/db/catalog/entity/Entity.java +++ b/core/src/main/java/org/polypheny/db/catalog/entity/Entity.java @@ -38,7 +38,7 @@ import org.polypheny.db.schema.Statistics; import org.polypheny.db.schema.types.Expressible; import org.polypheny.db.schema.types.Typed; -import org.polypheny.db.transaction.locking.Lockable; +import org.polypheny.db.transaction.locking.EntityIdentifierRegistry; import org.polypheny.db.transaction.locking.LockableObject; import org.polypheny.db.util.ImmutableBitSet; import org.polypheny.db.util.Wrapper; @@ -72,6 +72,8 @@ public abstract class Entity implements PolyObject, Wrapper, Serializable, Catal @JsonProperty public boolean modifiable; + public EntityIdentifierRegistry entryIdentifiers; + public Entity( long id, @@ -86,6 +88,7 @@ public Entity( this.entityType = type; this.dataModel = dataModel; this.modifiable = modifiable; + this.entryIdentifiers = new EntityIdentifierRegistry(); } @@ -97,7 +100,8 @@ public AlgDataType getTupleType() { }; } - public AlgDataType getTupleType(boolean hideIdentifier) { + + public AlgDataType getTupleType( boolean hideIdentifier ) { return switch ( dataModel ) { case RELATIONAL -> throw new UnsupportedOperationException( "Should be overwritten by child" ); //TODO TH: adjust where necessary @@ -172,6 +176,7 @@ public int compareTo( @NotNull Entity o ) { return Long.compare( this.id, o.id ); } + public ObjectType getLockableObjectType() { throw new UnsupportedOperationException( "Should be overwritten by child" ); } diff --git a/core/src/main/java/org/polypheny/db/functions/Functions.java b/core/src/main/java/org/polypheny/db/functions/Functions.java index cc6d3f59dc..4808e10c69 100644 --- a/core/src/main/java/org/polypheny/db/functions/Functions.java +++ b/core/src/main/java/org/polypheny/db/functions/Functions.java @@ -96,12 +96,12 @@ import org.polypheny.db.algebra.type.AlgDataType; import org.polypheny.db.algebra.type.AlgDataTypeFactory; import org.polypheny.db.algebra.type.AlgDataTypeSystem; +import org.polypheny.db.catalog.entity.Entity; import org.polypheny.db.catalog.exceptions.GenericRuntimeException; import org.polypheny.db.functions.util.ProductPolyListEnumerator; import org.polypheny.db.interpreter.Row; import org.polypheny.db.runtime.ComparableList; import org.polypheny.db.runtime.Like; -import org.polypheny.db.transaction.locking.IdentifierRegistry; import org.polypheny.db.transaction.locking.IdentifierUtils; import org.polypheny.db.type.PolyType; import org.polypheny.db.type.PolyTypeFactoryImpl; @@ -291,20 +291,20 @@ public static Enumerable batch( final DataContext context, final Enumerable

addRelIdentifiers(final Enumerable input) { + public static Enumerable addRelIdentifiers(final Enumerable input, Entity entity) { return input.select( oldRow -> { PolyValue[] newRow = new PolyValue[oldRow.length + 1]; - newRow[0] = IdentifierUtils.getIdentifierAsPolyLong(); + newRow[0] = entity.getEntryIdentifiers().getNextEntryIdentifierAsPolyLong(); System.arraycopy( oldRow, 0, newRow, 1, oldRow.length ); return newRow; } ); } @SuppressWarnings("unused") - public static Enumerable addDocIdentifiers(final Enumerable input) { + public static Enumerable addDocIdentifiers(final Enumerable input, Entity entity) { return input.select( oldRow -> { PolyDocument document = (PolyDocument) oldRow[0]; - document.put( IdentifierUtils.getIdentifierKeyAsPolyString(), IdentifierUtils.getIdentifierAsPolyLong() ); + document.put( IdentifierUtils.getIdentifierKeyAsPolyString(), entity.getEntryIdentifiers().getNextEntryIdentifierAsPolyLong() ); return new PolyValue[]{document}; } ); } diff --git a/core/src/main/java/org/polypheny/db/transaction/locking/IdentifierRegistry.java b/core/src/main/java/org/polypheny/db/transaction/locking/EntityIdentifierRegistry.java similarity index 73% rename from core/src/main/java/org/polypheny/db/transaction/locking/IdentifierRegistry.java rename to core/src/main/java/org/polypheny/db/transaction/locking/EntityIdentifierRegistry.java index f1deba35c5..0f7a6cef63 100644 --- a/core/src/main/java/org/polypheny/db/transaction/locking/IdentifierRegistry.java +++ b/core/src/main/java/org/polypheny/db/transaction/locking/EntityIdentifierRegistry.java @@ -1,23 +1,32 @@ package org.polypheny.db.transaction.locking; +import java.math.BigDecimal; import java.util.Set; import java.util.TreeSet; +import org.polypheny.db.algebra.type.AlgDataTypeFactoryImpl; +import org.polypheny.db.rex.RexBuilder; +import org.polypheny.db.rex.RexLiteral; +import org.polypheny.db.type.entity.numerical.PolyLong; -public class IdentifierRegistry { +public class EntityIdentifierRegistry { private static final Long MAX_IDENTIFIER_VALUE = Long.MAX_VALUE; - public static final IdentifierRegistry INSTANCE = new IdentifierRegistry( MAX_IDENTIFIER_VALUE ); - + private static final RexBuilder REX_BUILDER = new RexBuilder( AlgDataTypeFactoryImpl.DEFAULT ); private final TreeSet availableIdentifiers; - IdentifierRegistry( long maxIdentifierValue ) { + public EntityIdentifierRegistry() { + this.availableIdentifiers = new TreeSet<>(); + this.availableIdentifiers.add( new IdentifierInterval( IdentifierUtils.MISSING_IDENTIFIER + 1, MAX_IDENTIFIER_VALUE ) ); + } + + public EntityIdentifierRegistry(long maxIdentifierValue) { this.availableIdentifiers = new TreeSet<>(); this.availableIdentifiers.add( new IdentifierInterval( IdentifierUtils.MISSING_IDENTIFIER + 1, maxIdentifierValue ) ); } - public long getEntryIdentifier() { + public long getNextEntryIdentifier() { while ( !availableIdentifiers.first().hasNextIdentifier() ) { availableIdentifiers.pollFirst(); if ( availableIdentifiers.isEmpty() ) { @@ -27,6 +36,15 @@ public long getEntryIdentifier() { return availableIdentifiers.first().getNextIdentifier(); } + public RexLiteral getNextEntryIdentifierAsLiteral() { + return REX_BUILDER.makeExactLiteral( BigDecimal.valueOf( getNextEntryIdentifier() ) ); + } + + + public PolyLong getNextEntryIdentifierAsPolyLong() { + return PolyLong.of( getNextEntryIdentifier() ); + } + public void releaseEntryIdentifiers( Set identifiers ) { if ( identifiers.isEmpty() ) { diff --git a/core/src/main/java/org/polypheny/db/transaction/locking/IdentifierUtils.java b/core/src/main/java/org/polypheny/db/transaction/locking/IdentifierUtils.java index 83d0786ccf..53ce58cf41 100644 --- a/core/src/main/java/org/polypheny/db/transaction/locking/IdentifierUtils.java +++ b/core/src/main/java/org/polypheny/db/transaction/locking/IdentifierUtils.java @@ -16,7 +16,6 @@ package org.polypheny.db.transaction.locking; -import java.math.BigDecimal; import java.text.MessageFormat; import java.util.LinkedList; import java.util.List; @@ -24,11 +23,10 @@ import java.util.stream.Collectors; import org.polypheny.db.algebra.type.AlgDataType; import org.polypheny.db.algebra.type.AlgDataTypeFactoryImpl; +import org.polypheny.db.catalog.entity.Entity; import org.polypheny.db.catalog.logistic.Collation; import org.polypheny.db.ddl.DdlManager.ColumnTypeInformation; import org.polypheny.db.ddl.DdlManager.FieldInformation; -import org.polypheny.db.rex.RexBuilder; -import org.polypheny.db.rex.RexLiteral; import org.polypheny.db.type.PolyType; import org.polypheny.db.type.PolyTypeFactoryImpl; import org.polypheny.db.type.entity.PolyString; @@ -59,16 +57,12 @@ public class IdentifierUtils { 1 ); - private static final RexBuilder REX_BUILDER = new RexBuilder( AlgDataTypeFactoryImpl.DEFAULT ); - public static RexLiteral getIdentifierAsLiteral() { - return REX_BUILDER.makeExactLiteral( BigDecimal.valueOf( IdentifierRegistry.INSTANCE.getEntryIdentifier() ) ); - } - public static PolyLong getIdentifierAsPolyLong() { - return PolyLong.of( IdentifierRegistry.INSTANCE.getEntryIdentifier() ); + public static PolyLong getIdentifierAsPolyLong( Entity entity) { + return PolyLong.of( entity.getEntryIdentifiers().getNextEntryIdentifier() ); } diff --git a/core/src/main/java/org/polypheny/db/util/BuiltInMethod.java b/core/src/main/java/org/polypheny/db/util/BuiltInMethod.java index 26d28ed6bb..c922ca649a 100644 --- a/core/src/main/java/org/polypheny/db/util/BuiltInMethod.java +++ b/core/src/main/java/org/polypheny/db/util/BuiltInMethod.java @@ -105,6 +105,7 @@ import org.polypheny.db.algebra.metadata.BuiltInMetadata.TupleCount; import org.polypheny.db.algebra.metadata.BuiltInMetadata.UniqueKeys; import org.polypheny.db.algebra.metadata.Metadata; +import org.polypheny.db.catalog.entity.Entity; import org.polypheny.db.catalog.snapshot.Snapshot; import org.polypheny.db.functions.CrossModelFunctions; import org.polypheny.db.functions.CypherFunctions; @@ -155,9 +156,9 @@ public enum BuiltInMethod { SWITCH_CONTEXT( DataContext.class, "switchContext" ), BATCH( Functions.class, "batch", DataContext.class, Enumerable.class ), STREAM_RIGHT( Functions.class, "streamRight", DataContext.class, Enumerable.class, Function0.class, List.class ), - ADD_REL_IDENTIFIERS(Functions.class, "addRelIdentifiers", Enumerable.class), - ADD_DOC_IDENTIFIERS(Functions.class, "addDocIdentifiers", Enumerable.class), - ADD_LPG_IDENTIFIERS(Functions.class, "addLpgIdentifiers", Enumerable.class), + ADD_REL_IDENTIFIERS(Functions.class, "addRelIdentifiers", Enumerable.class, Entity.class), + ADD_DOC_IDENTIFIERS(Functions.class, "addDocIdentifiers", Enumerable.class, Entity.class), + ADD_LPG_IDENTIFIERS(Functions.class, "addLpgIdentifiers", Enumerable.class, Entity.class), ENFORCE_CONSTRAINT( Functions.class, "enforceConstraint", DataContext.class, Function0.class, Function0.class, List.class, List.class ), PARSE_ARRAY_FROM_TEXT( Functions.class, "reparse", String.class ), QUERYABLE_SELECT( Queryable.class, "select", FunctionExpression.class ), diff --git a/core/src/test/java/org/polypheny/db/transaction/locking/IdentifierRegistryTest.java b/core/src/test/java/org/polypheny/db/transaction/locking/EntityIdentifierRegistryTest.java similarity index 68% rename from core/src/test/java/org/polypheny/db/transaction/locking/IdentifierRegistryTest.java rename to core/src/test/java/org/polypheny/db/transaction/locking/EntityIdentifierRegistryTest.java index c03cc76d65..29aae41536 100644 --- a/core/src/test/java/org/polypheny/db/transaction/locking/IdentifierRegistryTest.java +++ b/core/src/test/java/org/polypheny/db/transaction/locking/EntityIdentifierRegistryTest.java @@ -24,21 +24,21 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -public class IdentifierRegistryTest { +public class EntityIdentifierRegistryTest { - private IdentifierRegistry registry; + private EntityIdentifierRegistry registry; @BeforeEach void setUp() { - registry = new IdentifierRegistry( 100 ); + registry = new EntityIdentifierRegistry( 100 ); } @Test - void testGetEntryIdentifierSequential() { - long firstId = registry.getEntryIdentifier(); - long secondId = registry.getEntryIdentifier(); + void testGetNextEntryIdentifierSequential() { + long firstId = registry.getNextEntryIdentifier(); + long secondId = registry.getNextEntryIdentifier(); assertEquals( 1, firstId ); assertEquals( 2, secondId ); @@ -46,36 +46,36 @@ void testGetEntryIdentifierSequential() { @Test - void testGetEntryIdentifierUntilOverflow() { + void testGetNextEntryIdentifierUntilOverflow() { for ( int i = 0; i < 99; i++ ) { - registry.getEntryIdentifier(); + registry.getNextEntryIdentifier(); } - Exception exception = assertThrows( IllegalStateException.class, registry::getEntryIdentifier ); + Exception exception = assertThrows( IllegalStateException.class, registry::getNextEntryIdentifier ); assertEquals( "No identifiers available", exception.getMessage() ); } @Test void testReleaseSingleIdentifierBeginning() { - long firstIdentifier = registry.getEntryIdentifier(); - registry.getEntryIdentifier(); + long firstIdentifier = registry.getNextEntryIdentifier(); + registry.getNextEntryIdentifier(); registry.releaseEntryIdentifiers( Set.of( firstIdentifier ) ); - assertEquals( 1, registry.getEntryIdentifier() ); + assertEquals( 1, registry.getNextEntryIdentifier() ); } @Test void testReleaseSingleIdentifierMiddle() { for ( int i = 0; i < 25; i++ ) { - registry.getEntryIdentifier(); + registry.getNextEntryIdentifier(); } - long middleIdentifier = registry.getEntryIdentifier(); + long middleIdentifier = registry.getNextEntryIdentifier(); for ( int i = 0; i < 25; i++ ) { - registry.getEntryIdentifier(); + registry.getNextEntryIdentifier(); } registry.releaseEntryIdentifiers( Set.of( middleIdentifier ) ); - assertEquals( 26, registry.getEntryIdentifier() ); + assertEquals( 26, registry.getNextEntryIdentifier() ); } @@ -83,17 +83,17 @@ void testReleaseSingleIdentifierMiddle() { void testReleaseMultipleIdentifiersConsequtive() { Set identifiers = new HashSet<>(); for ( int i = 0; i < 20; i++ ) { - registry.getEntryIdentifier(); + registry.getNextEntryIdentifier(); } for ( int i = 0; i < 20; i++ ) { - identifiers.add( registry.getEntryIdentifier() ); + identifiers.add( registry.getNextEntryIdentifier() ); } for ( int i = 0; i < 20; i++ ) { - registry.getEntryIdentifier(); + registry.getNextEntryIdentifier(); } registry.releaseEntryIdentifiers( identifiers ); for ( int i = 21; i < 40; i++ ) { - assertEquals( i, registry.getEntryIdentifier() ); + assertEquals( i, registry.getNextEntryIdentifier() ); } } @@ -104,7 +104,7 @@ void testReleaseMultipleIdentifiersInterleaved() { Set oddIdentifiers = new HashSet<>(); for ( int i = 0; i < 60; i++ ) { - long id = registry.getEntryIdentifier(); + long id = registry.getNextEntryIdentifier(); if ( id % 2 == 0 ) { evenIdentifiers.add( id ); continue; @@ -115,7 +115,7 @@ void testReleaseMultipleIdentifiersInterleaved() { registry.releaseEntryIdentifiers( evenIdentifiers ); for ( int i = 0; i < 30; i++ ) { - long id = registry.getEntryIdentifier(); + long id = registry.getNextEntryIdentifier(); assertEquals( 0, id % 2); } } diff --git a/dbms/src/main/java/org/polypheny/db/transaction/TransactionImpl.java b/dbms/src/main/java/org/polypheny/db/transaction/TransactionImpl.java index 6a3004ac8d..927d26f1d2 100644 --- a/dbms/src/main/java/org/polypheny/db/transaction/TransactionImpl.java +++ b/dbms/src/main/java/org/polypheny/db/transaction/TransactionImpl.java @@ -124,6 +124,9 @@ public class TransactionImpl implements Transaction, Comparable { @Getter private Set lockedEntities = new HashSet<>(); + @Getter + private Set readSet = new HashSet<>(); + TransactionImpl( PolyXid xid, diff --git a/plugins/mql-language/src/main/java/org/polypheny/db/languages/mql/MqlInsert.java b/plugins/mql-language/src/main/java/org/polypheny/db/languages/mql/MqlInsert.java index ae1ef5733a..17f073fabe 100644 --- a/plugins/mql-language/src/main/java/org/polypheny/db/languages/mql/MqlInsert.java +++ b/plugins/mql-language/src/main/java/org/polypheny/db/languages/mql/MqlInsert.java @@ -20,14 +20,11 @@ import lombok.Getter; import org.bson.BsonArray; import org.bson.BsonDocument; -import org.bson.BsonInt64; import org.bson.BsonValue; import org.jetbrains.annotations.Nullable; import org.polypheny.db.catalog.exceptions.GenericRuntimeException; import org.polypheny.db.languages.ParserPos; import org.polypheny.db.languages.mql.Mql.Type; -import org.polypheny.db.transaction.locking.IdentifierRegistry; -import org.polypheny.db.transaction.locking.IdentifierUtils; @Getter