Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New Locking, Various Bugfixes, UI Improvements #502

Merged
merged 23 commits into from
Jul 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
1a6a259
safety in statistic to prevent random race-conditions
datomo Jun 24, 2024
40a1ae5
fixed notebooks queries
datomo Jun 27, 2024
297d0e8
adjusting of locking mechanism
datomo Jun 28, 2024
42602df
removed non-thread safe locking, replaced with conservative locking
datomo Jul 1, 2024
6162f18
added missing case, where xLock already is held by tx
datomo Jul 1, 2024
8ab9092
reverted to default store
datomo Jul 1, 2024
1b3c093
fixed extraction of partitions
datomo Jul 1, 2024
2cb3fdb
finally fixed deadlock scenario
datomo Jul 2, 2024
3199905
fixed wrong transaction times
datomo Jul 3, 2024
8bca347
added more robust locking, with starving protection
datomo Jul 3, 2024
cfa8dda
fix for materialized views from derived values
datomo Jul 3, 2024
479d266
fixed some cases where lock already acquired
datomo Jul 3, 2024
bfa7f63
fix for namespace syntax in mql
datomo Jul 3, 2024
08e0238
stop creation of document views
datomo Jul 3, 2024
7c97562
adjusted waiting of threads
datomo Jul 3, 2024
f2998e7
fix for local and current time and date functions
datomo Jul 4, 2024
5832df0
added enforcement of new constraints for during creation and during r…
datomo Jul 4, 2024
c1fe145
fixed incorrect remove of table for constraint
datomo Jul 4, 2024
16caf79
reformating, optimized imports, adjusted headers
datomo Jul 7, 2024
13278ea
Use Transaction instead of TransactionImpl
gartens Jul 15, 2024
507ff75
Remove unused variable
gartens Jul 15, 2024
3e0c17e
Remove unused Runnable interface from LockManager
gartens Jul 15, 2024
adce9cc
Minor code and formatting improvements
vogti Jul 28, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions core/src/main/java/org/polypheny/db/algebra/AlgNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.jetbrains.annotations.Nullable;
import org.polypheny.db.algebra.core.Correlate;
import org.polypheny.db.algebra.core.CorrelationId;
Expand Down Expand Up @@ -392,6 +394,13 @@ default boolean containsEntity() {
return getInputs().stream().anyMatch( AlgNode::containsEntity );
}

default Set<Entity> getEntities() {
if ( getEntity() != null ) {
return Set.of( getEntity() );
}
return getInputs().stream().map( AlgNode::getEntities ).reduce( ( a, b ) -> Stream.concat( a.stream(), b.stream() ).collect( Collectors.toSet() ) ).orElse( Set.of() );
}

/**
* Context of an algebra expression, for purposes of checking validity.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,10 @@ protected ConverterImpl( AlgCluster cluster, AlgTraitDef<?> traitDef, AlgTraitSe

@Override
public AlgOptCost computeSelfCost( AlgPlanner planner, AlgMetadataQuery mq ) {
double dRows = mq.getTupleCount( getInput() );
Double dRows = mq.getTupleCount( getInput() );
if ( dRows == null ) {
dRows = Double.MAX_VALUE;
}
double dIo = 0;
return planner.getCostFactory().makeCost( dRows, dRows, dIo );
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,14 @@
package org.polypheny.db.algebra.enumerable.common;


import lombok.SneakyThrows;
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.core.common.ConditionalExecute;
import org.polypheny.db.algebra.core.common.ConditionalExecute.Condition;
import org.polypheny.db.algebra.enumerable.EnumerableConvention;
import org.polypheny.db.algebra.logical.common.LogicalConditionalExecute;
import org.polypheny.db.catalog.exceptions.GenericRuntimeException;
import org.polypheny.db.plan.Convention;


Expand All @@ -38,11 +38,14 @@ public EnumerableConditionalExecuteFalseRule() {
}


@SneakyThrows
@Override
public AlgNode convert( AlgNode alg ) {
ConditionalExecute ce = (ConditionalExecute) alg;
throw ce.getExceptionClass().getConstructor( String.class ).newInstance( ce.getExceptionMessage() );
try {
throw ce.getExceptionClass().getConstructor( String.class ).newInstance( ce.getExceptionMessage() );
} catch ( Exception e ) {
throw new GenericRuntimeException( e );
}
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,9 @@ public static EnforcementInformation getControl( LogicalTable table, Statement s
constraints.add( pkc );
}

// get new constraints
constraints.addAll( statement.getTransaction().getUsedConstraints( table.id ).stream().filter( c -> c.type != ConstraintType.FOREIGN ).toList() );

AlgNode constrainedNode;

//
Expand Down Expand Up @@ -397,7 +400,7 @@ public AlgNode accept( AlgShuttle shuttle ) {
}


public record EnforcementInformation(AlgNode control, List<Class<? extends Exception>> errorClasses, List<String> errorMessages) {
public record EnforcementInformation( AlgNode control, List<Class<? extends Exception>> errorClasses, List<String> errorMessages ) {

/**
* {@link EnforcementInformation} holds all needed information regarding a constraint.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1456,4 +1456,4 @@ public enum OperatorName {
MQL_LT,
MQL_LTE
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import org.polypheny.db.catalog.logistic.ForeignKeyOption;
import org.polypheny.db.catalog.logistic.IndexType;
import org.polypheny.db.languages.QueryLanguage;
import org.polypheny.db.transaction.Statement;
import org.polypheny.db.type.PolyType;
import org.polypheny.db.type.entity.PolyValue;

Expand Down Expand Up @@ -178,7 +179,7 @@ public interface LogicalRelationalCatalog extends LogicalCatalog {
* @param columnId The id of the column
* @param type The type of the default value
* @param defaultValue True if the column should allow null values, false if not.
* @return
* @return LogicalColumn
*/
LogicalColumn setDefaultValue( long columnId, PolyType type, PolyValue defaultValue );

Expand All @@ -195,8 +196,9 @@ public interface LogicalRelationalCatalog extends LogicalCatalog {
*
* @param tableId The id of the table
* @param columnIds The id of key which will be part of the primary keys
* @param statement The statement used to attach constraint enforcement on commit
*/
void addPrimaryKey( long tableId, List<Long> columnIds );
void addPrimaryKey( long tableId, List<Long> columnIds, Statement statement );


/**
Expand All @@ -218,8 +220,9 @@ public interface LogicalRelationalCatalog extends LogicalCatalog {
* @param tableId The id of the table
* @param constraintName The name of the constraint
* @param columnIds A list of column ids
* @param statement The statement to attach the constraint checks on commit
*/
void addUniqueConstraint( long tableId, String constraintName, List<Long> columnIds );
void addUniqueConstraint( long tableId, String constraintName, List<Long> columnIds, Statement statement );


/**
Expand All @@ -229,8 +232,9 @@ public interface LogicalRelationalCatalog extends LogicalCatalog {
* @param constraintName The name of the constraint
* @param columnIds A list of column ids
* @param type The type of the constraint
* @param statement
*/
void addConstraint( long tableId, String constraintName, List<Long> columnIds, ConstraintType type );
long addConstraint( long tableId, String constraintName, List<Long> columnIds, ConstraintType type, Statement statement );

/**
* Deletes the specified primary key (including the entry in the key table). If there is an index on this key, make sure to delete it first.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,14 @@
import lombok.EqualsAndHashCode;
import lombok.NonNull;
import lombok.Value;
import org.jetbrains.annotations.NotNull;
import org.polypheny.db.catalog.entity.logical.LogicalKey;
import org.polypheny.db.catalog.logistic.ConstraintType;


@EqualsAndHashCode
@Value
public class LogicalConstraint implements Serializable {
public class LogicalConstraint implements Serializable, Comparable<LogicalConstraint> {

@Serialize
public long id;
Expand Down Expand Up @@ -57,4 +58,12 @@ public LogicalConstraint(
}


@Override
public int compareTo( @NotNull LogicalConstraint o ) {
if ( this == o ) {
return 0;
}
return Long.compare( id, o.id );
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
import lombok.EqualsAndHashCode;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.Value;
import org.polypheny.db.catalog.Catalog;
import org.polypheny.db.catalog.entity.PolyObject;
Expand Down Expand Up @@ -152,7 +151,6 @@ public static class LogicalForeignKeyField implements PolyObject {
private final String foreignKeyFieldName;


@SneakyThrows
@Override
public PolyValue[] getParameterArray() {
return Catalog.snapshot()
Expand All @@ -163,7 +161,7 @@ public PolyValue[] getParameterArray() {
}


public record PrimitiveCatalogForeignKeyColumn(String pktableCat, String pktableSchem, String pktableName, String pkcolumnName, String fktableCat, String fktableSchem, String fktableName, String fkcolumnName, int keySeq, Integer updateRule, Integer deleteRule, String fkName, String pkName, Integer deferrability) {
public record PrimitiveCatalogForeignKeyColumn( String pktableCat, String pktableSchem, String pktableName, String pkcolumnName, String fktableCat, String fktableSchem, String fktableName, String fkcolumnName, int keySeq, Integer updateRule, Integer deleteRule, String fkName, String pkName, Integer deferrability ) {

}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
import org.polypheny.db.catalog.snapshot.Snapshot;
import org.polypheny.db.catalog.util.CatalogEvent;
import org.polypheny.db.languages.QueryLanguage;
import org.polypheny.db.transaction.Statement;
import org.polypheny.db.type.PolySerializable;
import org.polypheny.db.type.PolyType;
import org.polypheny.db.type.entity.PolyValue;
Expand Down Expand Up @@ -217,9 +218,8 @@ public void deleteTable( long tableId ) {

@Override
public void setPrimaryKey( long tableId, @Nullable Long keyId ) {
LogicalTable oldTable = tables.get( tableId );
// we temporarily can remove the primary, to clean-up old primaries before adding a new one
tables.put( tableId, oldTable.toBuilder().primaryKey( keyId ).build() );
tables.computeIfPresent( tableId, ( k, oldTable ) -> oldTable.toBuilder().primaryKey( keyId ).build() );

if ( keyId != null ) {
keys.put( keyId, new LogicalPrimaryKey( keys.get( keyId ) ) );
Expand Down Expand Up @@ -371,18 +371,15 @@ public void deleteDefaultValue( long columnId ) {


@Override
public void addPrimaryKey( long tableId, List<Long> columnIds ) {
public void addPrimaryKey( long tableId, List<Long> columnIds, Statement statement ) {
if ( columnIds.stream().anyMatch( id -> columns.get( id ).nullable ) ) {
throw new GenericRuntimeException( "Primary key is not allowed to use nullable columns." );
}

// TODO: Check if the current values are unique

// Check if there is already a primary key defined for this table and if so, delete it.
LogicalTable table = tables.get( tableId );

if ( table.primaryKey != null ) {
// CatalogCombinedKey combinedKey = getCombinedKey( table.primaryKey );
if ( getKeyUniqueCount( table.primaryKey ) == 1 && isForeignKey( table.primaryKey ) ) {
// This primary key is the only constraint for the uniqueness of this key.
throw new GenericRuntimeException( "This key is referenced by at least one foreign key which requires this key to be unique. To drop this primary key, first drop the foreign keys or create a unique constraint." );
Expand All @@ -394,8 +391,8 @@ public void addPrimaryKey( long tableId, List<Long> columnIds ) {
}
long keyId = getOrAddKey( tableId, columnIds, EnforcementTime.ON_QUERY );
setPrimaryKey( tableId, keyId );

change( CatalogEvent.PRIMARY_KEY_CREATED, tableId, keyId );
tables.get( tableId );
}


Expand Down Expand Up @@ -507,7 +504,7 @@ public void addForeignKey( long tableId, List<Long> columnIds, long referencesTa


@Override
public void addUniqueConstraint( long tableId, String constraintName, List<Long> columnIds ) {
public void addUniqueConstraint( long tableId, String constraintName, List<Long> columnIds, Statement statement ) {
long keyId = getOrAddKey( tableId, columnIds, EnforcementTime.ON_QUERY );
// Check if there is already a unique constraint
List<LogicalConstraint> logicalConstraints = constraints.values().stream()
Expand All @@ -516,20 +513,23 @@ public void addUniqueConstraint( long tableId, String constraintName, List<Long>
if ( !logicalConstraints.isEmpty() ) {
throw new GenericRuntimeException( "There is already a unique constraint!" );
}
addConstraint( tableId, constraintName, columnIds, ConstraintType.UNIQUE );
long id = addConstraint( tableId, constraintName, columnIds, ConstraintType.UNIQUE, statement );
statement.getTransaction().addNewConstraint( tableId, constraints.get( id ) );
}


@Override
public void addConstraint( long tableId, String constraintName, List<Long> columnIds, ConstraintType type ) {
public long addConstraint( long tableId, String constraintName, List<Long> columnIds, ConstraintType type, Statement statement ) {
long keyId = getOrAddKey( tableId, columnIds, EnforcementTime.ON_QUERY );

long id = idBuilder.getNewConstraintId();
LogicalConstraint constraint = new LogicalConstraint( id, keyId, type, constraintName, Objects.requireNonNull( keys.get( keyId ) ) );
synchronized ( this ) {
constraints.put( id, new LogicalConstraint( id, keyId, type, constraintName, Objects.requireNonNull( keys.get( keyId ) ) ) );
constraints.put( id, constraint );
change( CatalogEvent.CONSTRAINT_CREATED, null, id );
}
tables.get( tableId );
statement.getTransaction().addNewConstraint( tableId, constraint );
return id;
}


Expand Down
5 changes: 5 additions & 0 deletions core/src/main/java/org/polypheny/db/config/RuntimeConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -505,6 +505,11 @@ public enum RuntimeConfig {
"runtime/serialization",
"How big the buffersize for catalog objects should be.",
200000,
ConfigType.INTEGER ),
LOCKING_MAX_TIMEOUT_SECONDS(
"runtime/maxTimeout",
"How long a transactions should wait for a lock until it is aborted",
30,
ConfigType.INTEGER );


Expand Down
2 changes: 1 addition & 1 deletion core/src/main/java/org/polypheny/db/ddl/DdlManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -476,7 +476,7 @@ public static DdlManager getInstance() {
/**
* Adds a new constraint to a table
*/
public abstract void createConstraint( ConstraintInformation information, long namespaceId, List<Long> columnIds, long tableId );
public abstract void createConstraint( ConstraintInformation information, long namespaceId, List<Long> columnIds, long tableId, Statement statement );

/**
* Drop a NAMESPACE
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,12 @@
package org.polypheny.db.functions;

import java.sql.Timestamp;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.Date;
import java.util.TimeZone;
import org.apache.calcite.linq4j.function.NonDeterministic;
import org.jetbrains.annotations.NotNull;
import org.polypheny.db.adapter.DataContext;
import org.polypheny.db.nodes.TimeUnitRange;
import org.polypheny.db.type.entity.PolyInterval;
Expand All @@ -38,6 +41,7 @@
public class TemporalFunctions {

public static final TimeZone LOCAL_TZ = TimeZone.getDefault();
public static final String TIMEZONE = System.getProperty( "user.timezone" );


@SuppressWarnings("unused")
Expand Down Expand Up @@ -477,8 +481,8 @@ public static Integer toIntOptional( java.util.Date v, TimeZone timeZone ) {
@NonDeterministic
@SuppressWarnings("unused")
public static PolyTimestamp currentTimestamp( DataContext root ) {
// Cast required for JDK 1.6.
return PolyTimestamp.of( (long) DataContext.Variable.CURRENT_TIMESTAMP.get( root ) );
Date date = new Date();
return PolyTimestamp.of( date.getTime() + timeZone( root ).getRawOffset() );
}


Expand Down Expand Up @@ -508,17 +512,18 @@ public static PolyDate currentDate( DataContext root ) {
if ( time < 0 ) {
--date;
}
return PolyDate.of( date );
return PolyDate.ofDays( date );
}


/**
* SQL {@code LOCAL_TIMESTAMP} function.
*/
@NotNull
@NonDeterministic
public static long localTimestamp( DataContext root ) {
// Cast required for JDK 1.6.
return DataContext.Variable.LOCAL_TIMESTAMP.get( root );
public static PolyTimestamp localTimestamp( DataContext root ) {
ZonedDateTime now = ZonedDateTime.now( ZoneId.of( TIMEZONE ) );
return PolyTimestamp.of( (now.toEpochSecond() + now.getOffset().getTotalSeconds()) * DateTimeUtils.MILLIS_PER_SECOND );
}


Expand All @@ -528,13 +533,14 @@ public static long localTimestamp( DataContext root ) {
@SuppressWarnings("unused")
@NonDeterministic
public static PolyTime localTime( DataContext root ) {
return PolyTime.of( (int) (localTimestamp( root ) % DateTimeUtils.MILLIS_PER_DAY) );
ZonedDateTime now = ZonedDateTime.now( ZoneId.of( TIMEZONE ) );
return PolyTime.of( ((now.toEpochSecond() + now.getOffset().getTotalSeconds()) * DateTimeUtils.MILLIS_PER_SECOND) % DateTimeUtils.MILLIS_PER_DAY );
}


@NonDeterministic
public static TimeZone timeZone( DataContext root ) {
return DataContext.Variable.TIME_ZONE.get( root );
return TimeZone.getTimeZone( TIMEZONE );
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,6 @@ private static void cancelTransaction( @Nullable Transaction transaction ) {

public List<ExecutedContext> anyQuery( QueryContext context ) {
List<ImplementationContext> prepared = anyPrepareQuery( context, context.getTransactions().get( context.getTransactions().size() - 1 ) );

List<ExecutedContext> executedContexts = new ArrayList<>();

for ( ImplementationContext implementation : prepared ) {
Expand Down
Loading