Search in sources :

Example 16 with StatementEvaluationContext

use of herddb.model.StatementEvaluationContext in project herddb by diennea.

the class MemoryHashIndexManager method scanner.

@Override
public Stream<Bytes> scanner(IndexOperation operation, StatementEvaluationContext context, TableContext tableContext) throws StatementExecutionException {
    if (operation instanceof SecondaryIndexSeek) {
        SecondaryIndexSeek sis = (SecondaryIndexSeek) operation;
        SQLRecordKeyFunction value = sis.value;
        byte[] refvalue = value.computeNewValue(null, context, tableContext);
        List<Bytes> result = data.get(Bytes.from_array(refvalue));
        if (result != null) {
            return result.stream();
        } else {
            return Stream.empty();
        }
    } else if (operation instanceof SecondaryIndexPrefixScan) {
        SecondaryIndexPrefixScan sis = (SecondaryIndexPrefixScan) operation;
        SQLRecordKeyFunction value = sis.value;
        byte[] refvalue = value.computeNewValue(null, context, tableContext);
        Predicate<Map.Entry<Bytes, List<Bytes>>> predicate = (Map.Entry<Bytes, List<Bytes>> entry) -> {
            Bytes recordValue = entry.getKey();
            return recordValue.startsWith(refvalue.length, refvalue);
        };
        return data.entrySet().stream().filter(predicate).map(entry -> entry.getValue()).flatMap(l -> l.stream());
    } else if (operation instanceof SecondaryIndexRangeScan) {
        Bytes refminvalue;
        SecondaryIndexRangeScan sis = (SecondaryIndexRangeScan) operation;
        SQLRecordKeyFunction minKey = sis.minValue;
        if (minKey != null) {
            refminvalue = Bytes.from_nullable_array(minKey.computeNewValue(null, context, tableContext));
        } else {
            refminvalue = null;
        }
        Bytes refmaxvalue;
        SQLRecordKeyFunction maxKey = sis.maxValue;
        if (maxKey != null) {
            refmaxvalue = Bytes.from_nullable_array(maxKey.computeNewValue(null, context, tableContext));
        } else {
            refmaxvalue = null;
        }
        Predicate<Map.Entry<Bytes, List<Bytes>>> predicate;
        if (refminvalue != null && refmaxvalue == null) {
            predicate = (Map.Entry<Bytes, List<Bytes>> entry) -> {
                Bytes datum = entry.getKey();
                return datum.compareTo(refminvalue) >= 0;
            };
        } else if (refminvalue == null && refmaxvalue != null) {
            predicate = (Map.Entry<Bytes, List<Bytes>> entry) -> {
                Bytes datum = entry.getKey();
                return datum.compareTo(refmaxvalue) <= 0;
            };
        } else if (refminvalue != null && refmaxvalue != null) {
            predicate = (Map.Entry<Bytes, List<Bytes>> entry) -> {
                Bytes datum = entry.getKey();
                return datum.compareTo(refmaxvalue) <= 0 && datum.compareTo(refminvalue) >= 0;
            };
        } else {
            predicate = (Map.Entry<Bytes, List<Bytes>> entry) -> {
                return true;
            };
        }
        return data.entrySet().stream().filter(predicate).map(entry -> entry.getValue()).flatMap(l -> l.stream());
    } else {
        throw new UnsupportedOperationException("unsuppported index access type " + operation);
    }
}
Also used : Bytes(herddb.utils.Bytes) AbstractTableManager(herddb.core.AbstractTableManager) Holder(herddb.utils.Holder) TableSpaceManager(herddb.core.TableSpaceManager) Table(herddb.model.Table) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) Level(java.util.logging.Level) Map(java.util.Map) DataStorageManagerException(herddb.storage.DataStorageManagerException) Index(herddb.model.Index) SQLRecordKeyFunction(herddb.sql.SQLRecordKeyFunction) DataAccessor(herddb.utils.DataAccessor) StatementExecutionException(herddb.model.StatementExecutionException) TableContext(herddb.model.TableContext) Predicate(java.util.function.Predicate) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) LogSequenceNumber(herddb.log.LogSequenceNumber) PostCheckpointAction(herddb.core.PostCheckpointAction) DataStorageManager(herddb.storage.DataStorageManager) IndexStatus(herddb.storage.IndexStatus) Logger(java.util.logging.Logger) RecordSerializer(herddb.codec.RecordSerializer) Objects(java.util.Objects) AtomicLong(java.util.concurrent.atomic.AtomicLong) CommitLog(herddb.log.CommitLog) List(java.util.List) Stream(java.util.stream.Stream) StatementEvaluationContext(herddb.model.StatementEvaluationContext) AbstractIndexManager(herddb.core.AbstractIndexManager) Collections(java.util.Collections) Predicate(java.util.function.Predicate) Bytes(herddb.utils.Bytes) ArrayList(java.util.ArrayList) List(java.util.List) SQLRecordKeyFunction(herddb.sql.SQLRecordKeyFunction) HashMap(java.util.HashMap) Map(java.util.Map) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap)

Example 17 with StatementEvaluationContext

use of herddb.model.StatementEvaluationContext in project herddb by diennea.

the class TableManager method validateAlterTable.

@Override
public void validateAlterTable(Table table, StatementEvaluationContext context) throws StatementExecutionException {
    List<String> columnsChangedFromNullToNotNull = new ArrayList<>();
    for (Column c : this.table.columns) {
        Column newColumnSpecs = table.getColumn(c.name);
        if (newColumnSpecs == null) {
            // dropped column
            LOGGER.log(Level.INFO, "Table {0}.{1} dropping column {2}", new Object[] { table.tablespace, table.name, c.name });
        } else if (newColumnSpecs.type == c.type) {
        // no data type change
        } else if (ColumnTypes.isNotNullToNullConversion(c.type, newColumnSpecs.type)) {
            LOGGER.log(Level.INFO, "Table {0}.{1} making column {2} NULLABLE", new Object[] { table.tablespace, table.name, newColumnSpecs.name });
        } else if (ColumnTypes.isNullToNotNullConversion(c.type, newColumnSpecs.type)) {
            LOGGER.log(Level.INFO, "Table {0}.{1} making column {2} NOT NULL", new Object[] { table.tablespace, table.name, newColumnSpecs.name });
            columnsChangedFromNullToNotNull.add(c.name);
        }
    }
    for (final String column : columnsChangedFromNullToNotNull) {
        LOGGER.log(Level.INFO, "Table {0}.{1} validating column {2}, check for NULL values", new Object[] { table.tablespace, table.name, column });
        ScanStatement scan = new ScanStatement(this.table.tablespace, this.table, new Predicate() {

            @Override
            public boolean evaluate(Record record, StatementEvaluationContext context) throws StatementExecutionException {
                return record.getDataAccessor(table).get(column) == null;
            }
        });
        // fast fail
        scan.setLimits(new ScanLimitsImpl(1, 0));
        boolean foundOneNull = false;
        try (DataScanner scanner = this.scan(scan, context, null, false, false)) {
            foundOneNull = scanner.hasNext();
        } catch (DataScannerException err) {
            throw new StatementExecutionException(err);
        }
        if (foundOneNull) {
            throw new StatementExecutionException("Found a record in table " + table.name + " that contains a NULL value for column " + column + " ALTER command is not possible");
        }
    }
    // if we are adding new FK we have to check that the FK is not violated
    if (table.foreignKeys != null) {
        List<ForeignKeyDef> newForeignKeys;
        if (this.table.foreignKeys == null) {
            newForeignKeys = Arrays.asList(table.foreignKeys);
        } else {
            Set<String> currentKfs = Stream.of(this.table.foreignKeys).map(f -> f.name.toLowerCase()).collect(Collectors.toSet());
            newForeignKeys = Stream.of(table.foreignKeys).filter(fk -> !currentKfs.contains(fk.name)).collect(Collectors.toList());
        }
        for (ForeignKeyDef newFk : newForeignKeys) {
            validateForeignKeyConsistency(newFk, context, null);
        }
    }
}
Also used : Arrays(java.util.Arrays) NullLockManager(herddb.utils.NullLockManager) Table(herddb.model.Table) TruncateTableStatement(herddb.model.commands.TruncateTableStatement) DuplicatePrimaryKeyException(herddb.model.DuplicatePrimaryKeyException) TableStatus(herddb.storage.TableStatus) Map(java.util.Map) DataAccessor(herddb.utils.DataAccessor) LogNotAvailableException(herddb.log.LogNotAvailableException) CommitLogResult(herddb.log.CommitLogResult) LogSequenceNumber(herddb.log.LogSequenceNumber) UniqueIndexContraintViolationException(herddb.model.UniqueIndexContraintViolationException) Set(java.util.Set) RecordSerializer(herddb.codec.RecordSerializer) JSQLParserPlanner.delimit(herddb.sql.JSQLParserPlanner.delimit) DataPageMetaData(herddb.core.PageSet.DataPageMetaData) ScanStatement(herddb.model.commands.ScanStatement) Stream(java.util.stream.Stream) StatsLogger(org.apache.bookkeeper.stats.StatsLogger) Bytes(herddb.utils.Bytes) Holder(herddb.utils.Holder) LockHandle(herddb.utils.LockHandle) ForeignKeyViolationException(herddb.model.ForeignKeyViolationException) LogEntry(herddb.log.LogEntry) ArrayList(java.util.ArrayList) TransactionContext(herddb.model.TransactionContext) Transaction(herddb.model.Transaction) ThreadLocalRandom(java.util.concurrent.ThreadLocalRandom) Projection(herddb.model.Projection) ForeignKeyDef(herddb.model.ForeignKeyDef) EnsureLongIncrementAccumulator(herddb.utils.EnsureLongIncrementAccumulator) LogEntryType(herddb.log.LogEntryType) Record(herddb.model.Record) LogEntryFactory(herddb.log.LogEntryFactory) KeyToPageIndex(herddb.index.KeyToPageIndex) DataStorageManager(herddb.storage.DataStorageManager) ColumnTypes(herddb.model.ColumnTypes) ILocalLockManager(herddb.utils.ILocalLockManager) AtomicLong(java.util.concurrent.atomic.AtomicLong) Lock(java.util.concurrent.locks.Lock) IndexOperation(herddb.index.IndexOperation) Column(herddb.model.Column) StampedLock(java.util.concurrent.locks.StampedLock) UpdateStatement(herddb.model.commands.UpdateStatement) ScanLimitsImpl(herddb.model.ScanLimitsImpl) TupleComparator(herddb.model.TupleComparator) ServerConfiguration(herddb.server.ServerConfiguration) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) RecordTooBigException(herddb.model.RecordTooBigException) DMLStatementExecutionResult(herddb.model.DMLStatementExecutionResult) LocalLockManager(herddb.utils.LocalLockManager) Futures(herddb.utils.Futures) DataStorageManagerException(herddb.storage.DataStorageManagerException) Index(herddb.model.Index) InsertStatement(herddb.model.commands.InsertStatement) DataScanner(herddb.model.DataScanner) DDLException(herddb.model.DDLException) RecordFunction(herddb.model.RecordFunction) StatementExecutionException(herddb.model.StatementExecutionException) TableContext(herddb.model.TableContext) Collection(java.util.Collection) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Logger(java.util.logging.Logger) Collectors(java.util.stream.Collectors) List(java.util.List) FullTableScanConsumer(herddb.storage.FullTableScanConsumer) GetStatement(herddb.model.commands.GetStatement) Entry(java.util.Map.Entry) Statement(herddb.model.Statement) LongAdder(java.util.concurrent.atomic.LongAdder) DataScannerException(herddb.model.DataScannerException) GetResult(herddb.model.GetResult) PrimaryIndexSeek(herddb.index.PrimaryIndexSeek) HashMap(java.util.HashMap) CompletableFuture(java.util.concurrent.CompletableFuture) Function(java.util.function.Function) BatchOrderedExecutor(herddb.utils.BatchOrderedExecutor) ConcurrentMap(java.util.concurrent.ConcurrentMap) Level(java.util.logging.Level) HashSet(java.util.HashSet) BooleanHolder(herddb.utils.BooleanHolder) ScanLimits(herddb.model.ScanLimits) DeleteStatement(herddb.model.commands.DeleteStatement) Iterator(java.util.Iterator) ReentrantLock(java.util.concurrent.locks.ReentrantLock) Semaphore(java.util.concurrent.Semaphore) DataPageDoesNotExistException(herddb.storage.DataPageDoesNotExistException) Counter(org.apache.bookkeeper.stats.Counter) StatementExecutionResult(herddb.model.StatementExecutionResult) TimeUnit(java.util.concurrent.TimeUnit) Consumer(java.util.function.Consumer) CommitLog(herddb.log.CommitLog) AbstractMap(java.util.AbstractMap) TableConsistencyCheckStatement(herddb.model.commands.TableConsistencyCheckStatement) Predicate(herddb.model.Predicate) StatementEvaluationContext(herddb.model.StatementEvaluationContext) Comparator(java.util.Comparator) Collections(java.util.Collections) SECONDS(java.util.concurrent.TimeUnit.SECONDS) TableManagerStats(herddb.core.stats.TableManagerStats) SystemProperties(herddb.utils.SystemProperties) ArrayList(java.util.ArrayList) ScanLimitsImpl(herddb.model.ScanLimitsImpl) StatementExecutionException(herddb.model.StatementExecutionException) Predicate(herddb.model.Predicate) DataScanner(herddb.model.DataScanner) Column(herddb.model.Column) Record(herddb.model.Record) StatementEvaluationContext(herddb.model.StatementEvaluationContext) ForeignKeyDef(herddb.model.ForeignKeyDef) ScanStatement(herddb.model.commands.ScanStatement) DataScannerException(herddb.model.DataScannerException)

Example 18 with StatementEvaluationContext

use of herddb.model.StatementEvaluationContext in project herddb by diennea.

the class TableManager method executeForeignKeyConstraintsAsParentTable.

private void executeForeignKeyConstraintsAsParentTable(Table childTable, DataAccessor previousValuesOnParentTable, StatementEvaluationContext context, Transaction transaction, boolean delete) throws StatementExecutionException {
    // invalidated consistently during DML operations.
    for (ForeignKeyDef fk : childTable.foreignKeys) {
        String query = parentForeignKeyQueries.computeIfAbsent(childTable.name + "." + fk.name + ".#" + delete, (l -> {
            if (fk.onDeleteAction == ForeignKeyDef.ACTION_CASCADE && delete) {
                StringBuilder q = new StringBuilder("DELETE FROM ");
                q.append(delimit(childTable.tablespace));
                q.append(".");
                q.append(delimit(childTable.name));
                q.append(" WHERE ");
                for (int i = 0; i < fk.columns.length; i++) {
                    if (i > 0) {
                        q.append(" AND ");
                    }
                    q.append(delimit(fk.columns[i]));
                    q.append("=?");
                }
                return q.toString();
            } else if (fk.onUpdateAction == ForeignKeyDef.ACTION_CASCADE && !delete) {
                // the change is more complex, let's keep it for a future work
                throw new StatementExecutionException("No supported ON UPDATE CASCADE");
            } else if ((fk.onDeleteAction == ForeignKeyDef.ACTION_SETNULL && delete) || (fk.onUpdateAction == ForeignKeyDef.ACTION_SETNULL && !delete)) {
                // delete or update it is the same for SET NULL
                StringBuilder q = new StringBuilder("UPDATE ");
                q.append(delimit(childTable.tablespace));
                q.append(".");
                q.append(delimit(childTable.name));
                q.append(" SET ");
                for (int i = 0; i < fk.columns.length; i++) {
                    if (i > 0) {
                        q.append(",");
                    }
                    q.append(delimit(fk.columns[i]));
                    q.append("= NULL ");
                }
                q.append(" WHERE ");
                for (int i = 0; i < fk.columns.length; i++) {
                    if (i > 0) {
                        q.append(" AND ");
                    }
                    q.append(delimit(fk.columns[i]));
                    q.append("=?");
                }
                return q.toString();
            } else {
                // NO ACTION case, check that there is no matching record in the child table that wouble be invalidated
                // with '*' we are not going to perform projections or copies
                StringBuilder q = new StringBuilder("SELECT * FROM ");
                q.append(delimit(childTable.tablespace));
                q.append(".");
                q.append(delimit(childTable.name));
                q.append(" WHERE ");
                for (int i = 0; i < fk.columns.length; i++) {
                    if (i > 0) {
                        q.append(" AND ");
                    }
                    q.append(delimit(fk.columns[i]));
                    q.append("=?");
                }
                return q.toString();
            }
        }));
        final List<Object> valuesToMatch = new ArrayList<>(fk.parentTableColumns.length);
        for (int i = 0; i < fk.parentTableColumns.length; i++) {
            valuesToMatch.add(previousValuesOnParentTable.get(fk.parentTableColumns[i]));
        }
        TransactionContext tx = transaction != null ? new TransactionContext(transaction.transactionId) : TransactionContext.NO_TRANSACTION;
        if (fk.onDeleteAction == ForeignKeyDef.ACTION_CASCADE && delete || fk.onUpdateAction == ForeignKeyDef.ACTION_CASCADE && !delete || fk.onUpdateAction == ForeignKeyDef.ACTION_SETNULL && !delete || fk.onDeleteAction == ForeignKeyDef.ACTION_SETNULL && delete) {
            tableSpaceManager.getDbmanager().executeSimpleStatement(tableSpaceManager.getTableSpaceName(), query, valuesToMatch, // every record
            -1, // keep read locks in TransactionContext
            true, tx, null);
        } else {
            boolean fkOk;
            try (DataScanner scan = tableSpaceManager.getDbmanager().executeSimpleQuery(tableSpaceManager.getTableSpaceName(), query, valuesToMatch, // only one record
            1, // keep read locks in TransactionContext
            true, tx, null)) {
                List<DataAccessor> resultSet = scan.consume();
                // we are on the parent side of the relation
                // we are okay if there is no matching record
                // TODO: return the list of PKs in order to implement CASCADE operations
                fkOk = resultSet.isEmpty();
            } catch (DataScannerException err) {
                throw new StatementExecutionException(err);
            }
            if (!fkOk) {
                throw new ForeignKeyViolationException(fk.name, "foreignKey " + childTable.name + "." + fk.name + " violated");
            }
        }
    }
}
Also used : Arrays(java.util.Arrays) NullLockManager(herddb.utils.NullLockManager) Table(herddb.model.Table) TruncateTableStatement(herddb.model.commands.TruncateTableStatement) DuplicatePrimaryKeyException(herddb.model.DuplicatePrimaryKeyException) TableStatus(herddb.storage.TableStatus) Map(java.util.Map) DataAccessor(herddb.utils.DataAccessor) LogNotAvailableException(herddb.log.LogNotAvailableException) CommitLogResult(herddb.log.CommitLogResult) LogSequenceNumber(herddb.log.LogSequenceNumber) UniqueIndexContraintViolationException(herddb.model.UniqueIndexContraintViolationException) Set(java.util.Set) RecordSerializer(herddb.codec.RecordSerializer) JSQLParserPlanner.delimit(herddb.sql.JSQLParserPlanner.delimit) DataPageMetaData(herddb.core.PageSet.DataPageMetaData) ScanStatement(herddb.model.commands.ScanStatement) Stream(java.util.stream.Stream) StatsLogger(org.apache.bookkeeper.stats.StatsLogger) Bytes(herddb.utils.Bytes) Holder(herddb.utils.Holder) LockHandle(herddb.utils.LockHandle) ForeignKeyViolationException(herddb.model.ForeignKeyViolationException) LogEntry(herddb.log.LogEntry) ArrayList(java.util.ArrayList) TransactionContext(herddb.model.TransactionContext) Transaction(herddb.model.Transaction) ThreadLocalRandom(java.util.concurrent.ThreadLocalRandom) Projection(herddb.model.Projection) ForeignKeyDef(herddb.model.ForeignKeyDef) EnsureLongIncrementAccumulator(herddb.utils.EnsureLongIncrementAccumulator) LogEntryType(herddb.log.LogEntryType) Record(herddb.model.Record) LogEntryFactory(herddb.log.LogEntryFactory) KeyToPageIndex(herddb.index.KeyToPageIndex) DataStorageManager(herddb.storage.DataStorageManager) ColumnTypes(herddb.model.ColumnTypes) ILocalLockManager(herddb.utils.ILocalLockManager) AtomicLong(java.util.concurrent.atomic.AtomicLong) Lock(java.util.concurrent.locks.Lock) IndexOperation(herddb.index.IndexOperation) Column(herddb.model.Column) StampedLock(java.util.concurrent.locks.StampedLock) UpdateStatement(herddb.model.commands.UpdateStatement) ScanLimitsImpl(herddb.model.ScanLimitsImpl) TupleComparator(herddb.model.TupleComparator) ServerConfiguration(herddb.server.ServerConfiguration) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) RecordTooBigException(herddb.model.RecordTooBigException) DMLStatementExecutionResult(herddb.model.DMLStatementExecutionResult) LocalLockManager(herddb.utils.LocalLockManager) Futures(herddb.utils.Futures) DataStorageManagerException(herddb.storage.DataStorageManagerException) Index(herddb.model.Index) InsertStatement(herddb.model.commands.InsertStatement) DataScanner(herddb.model.DataScanner) DDLException(herddb.model.DDLException) RecordFunction(herddb.model.RecordFunction) StatementExecutionException(herddb.model.StatementExecutionException) TableContext(herddb.model.TableContext) Collection(java.util.Collection) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Logger(java.util.logging.Logger) Collectors(java.util.stream.Collectors) List(java.util.List) FullTableScanConsumer(herddb.storage.FullTableScanConsumer) GetStatement(herddb.model.commands.GetStatement) Entry(java.util.Map.Entry) Statement(herddb.model.Statement) LongAdder(java.util.concurrent.atomic.LongAdder) DataScannerException(herddb.model.DataScannerException) GetResult(herddb.model.GetResult) PrimaryIndexSeek(herddb.index.PrimaryIndexSeek) HashMap(java.util.HashMap) CompletableFuture(java.util.concurrent.CompletableFuture) Function(java.util.function.Function) BatchOrderedExecutor(herddb.utils.BatchOrderedExecutor) ConcurrentMap(java.util.concurrent.ConcurrentMap) Level(java.util.logging.Level) HashSet(java.util.HashSet) BooleanHolder(herddb.utils.BooleanHolder) ScanLimits(herddb.model.ScanLimits) DeleteStatement(herddb.model.commands.DeleteStatement) Iterator(java.util.Iterator) ReentrantLock(java.util.concurrent.locks.ReentrantLock) Semaphore(java.util.concurrent.Semaphore) DataPageDoesNotExistException(herddb.storage.DataPageDoesNotExistException) Counter(org.apache.bookkeeper.stats.Counter) StatementExecutionResult(herddb.model.StatementExecutionResult) TimeUnit(java.util.concurrent.TimeUnit) Consumer(java.util.function.Consumer) CommitLog(herddb.log.CommitLog) AbstractMap(java.util.AbstractMap) TableConsistencyCheckStatement(herddb.model.commands.TableConsistencyCheckStatement) Predicate(herddb.model.Predicate) StatementEvaluationContext(herddb.model.StatementEvaluationContext) Comparator(java.util.Comparator) Collections(java.util.Collections) SECONDS(java.util.concurrent.TimeUnit.SECONDS) TableManagerStats(herddb.core.stats.TableManagerStats) SystemProperties(herddb.utils.SystemProperties) DataAccessor(herddb.utils.DataAccessor) ArrayList(java.util.ArrayList) StatementExecutionException(herddb.model.StatementExecutionException) DataScanner(herddb.model.DataScanner) ForeignKeyViolationException(herddb.model.ForeignKeyViolationException) TransactionContext(herddb.model.TransactionContext) ForeignKeyDef(herddb.model.ForeignKeyDef) DataScannerException(herddb.model.DataScannerException)

Example 19 with StatementEvaluationContext

use of herddb.model.StatementEvaluationContext in project herddb by diennea.

the class TableManager method executeDeleteAsync.

private CompletableFuture<StatementExecutionResult> executeDeleteAsync(DeleteStatement delete, Transaction transaction, StatementEvaluationContext context) {
    AtomicInteger updateCount = new AtomicInteger();
    Holder<Bytes> lastKey = new Holder<>();
    Holder<Bytes> lastValue = new Holder<>();
    long transactionId = transaction != null ? transaction.transactionId : 0;
    Predicate predicate = delete.getPredicate();
    List<CompletableFuture<PendingLogEntryWork>> writes = new ArrayList<>();
    Map<String, AbstractIndexManager> indexes = tableSpaceManager.getIndexesOnTable(table.name);
    ScanStatement scan = new ScanStatement(table.tablespace, table, predicate);
    try {
        accessTableData(scan, context, new ScanResultOperation() {

            @Override
            public void accept(Record current, LockHandle lockHandle) throws StatementExecutionException, LogNotAvailableException, DataStorageManagerException {
                // ensure we are holding the write locks on every unique index
                List<UniqueIndexLockReference> uniqueIndexes = null;
                try {
                    if (indexes != null || childrenTables != null) {
                        DataAccessor dataAccessor = current.getDataAccessor(table);
                        if (childrenTables != null) {
                            for (Table childTable : childrenTables) {
                                executeForeignKeyConstraintsAsParentTable(childTable, dataAccessor, context, transaction, true);
                            }
                        }
                        if (indexes != null) {
                            for (AbstractIndexManager index : indexes.values()) {
                                if (index.isUnique()) {
                                    Bytes indexKey = RecordSerializer.serializeIndexKey(dataAccessor, index.getIndex(), index.getColumnNames());
                                    if (uniqueIndexes == null) {
                                        uniqueIndexes = new ArrayList<>(1);
                                    }
                                    UniqueIndexLockReference uniqueIndexLock = new UniqueIndexLockReference(index, indexKey);
                                    uniqueIndexes.add(uniqueIndexLock);
                                    LockHandle lockForIndex = lockForWrite(uniqueIndexLock.key, transaction, index.getIndexName(), index.getLockManager());
                                    if (transaction == null) {
                                        uniqueIndexLock.lockHandle = lockForIndex;
                                    }
                                }
                            }
                        }
                    }
                } catch (IllegalArgumentException | herddb.utils.IllegalDataAccessException | StatementExecutionException err) {
                    locksManager.releaseLock(lockHandle);
                    StatementExecutionException finalError;
                    if (!(err instanceof StatementExecutionException)) {
                        finalError = new StatementExecutionException(err.getMessage(), err);
                    } else {
                        finalError = (StatementExecutionException) err;
                    }
                    CompletableFuture<PendingLogEntryWork> res = Futures.exception(finalError);
                    if (uniqueIndexes != null) {
                        for (UniqueIndexLockReference lock : uniqueIndexes) {
                            res = releaseWriteLock(res, lockHandle, lock.indexManager.getLockManager());
                        }
                    }
                    writes.add(res);
                    return;
                }
                LogEntry entry = LogEntryFactory.delete(table, current.key, transaction);
                CommitLogResult pos = log.log(entry, entry.transactionId <= 0);
                final List<UniqueIndexLockReference> _uniqueIndexes = uniqueIndexes;
                writes.add(pos.logSequenceNumber.thenApply(lsn -> new PendingLogEntryWork(entry, pos, lockHandle, _uniqueIndexes)));
                lastKey.value = current.key;
                lastValue.value = current.value;
                updateCount.incrementAndGet();
            }
        }, transaction, true, true);
    } catch (HerdDBInternalException err) {
        LOGGER.log(Level.SEVERE, "bad error during a delete", err);
        return Futures.exception(err);
    }
    if (writes.isEmpty()) {
        return CompletableFuture.completedFuture(new DMLStatementExecutionResult(transactionId, 0, null, null));
    }
    if (writes.size() == 1) {
        return writes.get(0).whenCompleteAsync((pending, error) -> {
            try {
                // apply any of the DML operations
                if (error == null) {
                    apply(pending.pos, pending.entry, false);
                }
            } finally {
                releaseMultiplePendingLogEntryWorks(writes);
            }
        }, tableSpaceManager.getCallbacksExecutor()).thenApply((pending) -> {
            return new DMLStatementExecutionResult(transactionId, updateCount.get(), lastKey.value, delete.isReturnValues() ? lastValue.value : null);
        });
    } else {
        return Futures.collect(writes).whenCompleteAsync((pendings, error) -> {
            try {
                // apply any of the DML operations
                if (error == null) {
                    for (PendingLogEntryWork pending : pendings) {
                        apply(pending.pos, pending.entry, false);
                    }
                }
            } finally {
                releaseMultiplePendingLogEntryWorks(writes);
            }
        }, tableSpaceManager.getCallbacksExecutor()).thenApply((pendings) -> {
            return new DMLStatementExecutionResult(transactionId, updateCount.get(), lastKey.value, delete.isReturnValues() ? lastValue.value : null);
        });
    }
}
Also used : Arrays(java.util.Arrays) NullLockManager(herddb.utils.NullLockManager) Table(herddb.model.Table) TruncateTableStatement(herddb.model.commands.TruncateTableStatement) DuplicatePrimaryKeyException(herddb.model.DuplicatePrimaryKeyException) TableStatus(herddb.storage.TableStatus) Map(java.util.Map) DataAccessor(herddb.utils.DataAccessor) LogNotAvailableException(herddb.log.LogNotAvailableException) CommitLogResult(herddb.log.CommitLogResult) LogSequenceNumber(herddb.log.LogSequenceNumber) UniqueIndexContraintViolationException(herddb.model.UniqueIndexContraintViolationException) Set(java.util.Set) RecordSerializer(herddb.codec.RecordSerializer) JSQLParserPlanner.delimit(herddb.sql.JSQLParserPlanner.delimit) DataPageMetaData(herddb.core.PageSet.DataPageMetaData) ScanStatement(herddb.model.commands.ScanStatement) Stream(java.util.stream.Stream) StatsLogger(org.apache.bookkeeper.stats.StatsLogger) Bytes(herddb.utils.Bytes) Holder(herddb.utils.Holder) LockHandle(herddb.utils.LockHandle) ForeignKeyViolationException(herddb.model.ForeignKeyViolationException) LogEntry(herddb.log.LogEntry) ArrayList(java.util.ArrayList) TransactionContext(herddb.model.TransactionContext) Transaction(herddb.model.Transaction) ThreadLocalRandom(java.util.concurrent.ThreadLocalRandom) Projection(herddb.model.Projection) ForeignKeyDef(herddb.model.ForeignKeyDef) EnsureLongIncrementAccumulator(herddb.utils.EnsureLongIncrementAccumulator) LogEntryType(herddb.log.LogEntryType) Record(herddb.model.Record) LogEntryFactory(herddb.log.LogEntryFactory) KeyToPageIndex(herddb.index.KeyToPageIndex) DataStorageManager(herddb.storage.DataStorageManager) ColumnTypes(herddb.model.ColumnTypes) ILocalLockManager(herddb.utils.ILocalLockManager) AtomicLong(java.util.concurrent.atomic.AtomicLong) Lock(java.util.concurrent.locks.Lock) IndexOperation(herddb.index.IndexOperation) Column(herddb.model.Column) StampedLock(java.util.concurrent.locks.StampedLock) UpdateStatement(herddb.model.commands.UpdateStatement) ScanLimitsImpl(herddb.model.ScanLimitsImpl) TupleComparator(herddb.model.TupleComparator) ServerConfiguration(herddb.server.ServerConfiguration) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) RecordTooBigException(herddb.model.RecordTooBigException) DMLStatementExecutionResult(herddb.model.DMLStatementExecutionResult) LocalLockManager(herddb.utils.LocalLockManager) Futures(herddb.utils.Futures) DataStorageManagerException(herddb.storage.DataStorageManagerException) Index(herddb.model.Index) InsertStatement(herddb.model.commands.InsertStatement) DataScanner(herddb.model.DataScanner) DDLException(herddb.model.DDLException) RecordFunction(herddb.model.RecordFunction) StatementExecutionException(herddb.model.StatementExecutionException) TableContext(herddb.model.TableContext) Collection(java.util.Collection) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Logger(java.util.logging.Logger) Collectors(java.util.stream.Collectors) List(java.util.List) FullTableScanConsumer(herddb.storage.FullTableScanConsumer) GetStatement(herddb.model.commands.GetStatement) Entry(java.util.Map.Entry) Statement(herddb.model.Statement) LongAdder(java.util.concurrent.atomic.LongAdder) DataScannerException(herddb.model.DataScannerException) GetResult(herddb.model.GetResult) PrimaryIndexSeek(herddb.index.PrimaryIndexSeek) HashMap(java.util.HashMap) CompletableFuture(java.util.concurrent.CompletableFuture) Function(java.util.function.Function) BatchOrderedExecutor(herddb.utils.BatchOrderedExecutor) ConcurrentMap(java.util.concurrent.ConcurrentMap) Level(java.util.logging.Level) HashSet(java.util.HashSet) BooleanHolder(herddb.utils.BooleanHolder) ScanLimits(herddb.model.ScanLimits) DeleteStatement(herddb.model.commands.DeleteStatement) Iterator(java.util.Iterator) ReentrantLock(java.util.concurrent.locks.ReentrantLock) Semaphore(java.util.concurrent.Semaphore) DataPageDoesNotExistException(herddb.storage.DataPageDoesNotExistException) Counter(org.apache.bookkeeper.stats.Counter) StatementExecutionResult(herddb.model.StatementExecutionResult) TimeUnit(java.util.concurrent.TimeUnit) Consumer(java.util.function.Consumer) CommitLog(herddb.log.CommitLog) AbstractMap(java.util.AbstractMap) TableConsistencyCheckStatement(herddb.model.commands.TableConsistencyCheckStatement) Predicate(herddb.model.Predicate) StatementEvaluationContext(herddb.model.StatementEvaluationContext) Comparator(java.util.Comparator) Collections(java.util.Collections) SECONDS(java.util.concurrent.TimeUnit.SECONDS) TableManagerStats(herddb.core.stats.TableManagerStats) SystemProperties(herddb.utils.SystemProperties) DataStorageManagerException(herddb.storage.DataStorageManagerException) DataAccessor(herddb.utils.DataAccessor) ArrayList(java.util.ArrayList) CommitLogResult(herddb.log.CommitLogResult) StatementExecutionException(herddb.model.StatementExecutionException) Predicate(herddb.model.Predicate) Bytes(herddb.utils.Bytes) CompletableFuture(java.util.concurrent.CompletableFuture) Record(herddb.model.Record) ArrayList(java.util.ArrayList) List(java.util.List) LogEntry(herddb.log.LogEntry) ScanStatement(herddb.model.commands.ScanStatement) LockHandle(herddb.utils.LockHandle) Table(herddb.model.Table) Holder(herddb.utils.Holder) BooleanHolder(herddb.utils.BooleanHolder) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) DMLStatementExecutionResult(herddb.model.DMLStatementExecutionResult) LogNotAvailableException(herddb.log.LogNotAvailableException)

Example 20 with StatementEvaluationContext

use of herddb.model.StatementEvaluationContext in project herddb by diennea.

the class TableSpaceManager method executeTableAwareStatement.

private CompletableFuture<StatementExecutionResult> executeTableAwareStatement(Statement statement, Transaction transaction, StatementEvaluationContext context) throws StatementExecutionException {
    long lockStamp = context.getTableSpaceLock();
    boolean lockAcquired = false;
    if (lockStamp == 0) {
        lockStamp = acquireReadLock(statement);
        context.setTableSpaceLock(lockStamp);
        lockAcquired = true;
    }
    TableAwareStatement st = (TableAwareStatement) statement;
    String table = st.getTable();
    AbstractTableManager manager = tables.get(table);
    CompletableFuture<StatementExecutionResult> res;
    if (manager == null) {
        res = Futures.exception(new TableDoesNotExistException("no table " + table + " in tablespace " + tableSpaceName));
    } else if (manager.getCreatedInTransaction() > 0 && (transaction == null || transaction.transactionId != manager.getCreatedInTransaction())) {
        res = Futures.exception(new TableDoesNotExistException("no table " + table + " in tablespace " + tableSpaceName + ". created temporary in transaction " + manager.getCreatedInTransaction()));
    } else {
        res = manager.executeStatementAsync(statement, transaction, context);
    }
    if (lockAcquired) {
        res = releaseReadLock(res, lockStamp, statement).whenComplete((s, err) -> {
            context.setTableSpaceLock(0);
        });
    }
    return res;
}
Also used : TableDoesNotExistException(herddb.model.TableDoesNotExistException) HDBException(herddb.client.HDBException) SystablesTableManager(herddb.core.system.SystablesTableManager) CommitTransactionStatement(herddb.model.commands.CommitTransactionStatement) TableCheckpoint(herddb.core.AbstractTableManager.TableCheckpoint) Table(herddb.model.Table) ClientConfiguration(herddb.client.ClientConfiguration) SyslogstatusManager(herddb.core.system.SyslogstatusManager) OpStatsLogger(org.apache.bookkeeper.stats.OpStatsLogger) IndexAlreadyExistsException(herddb.model.IndexAlreadyExistsException) Map(java.util.Map) DDLStatementExecutionResult(herddb.model.DDLStatementExecutionResult) LogNotAvailableException(herddb.log.LogNotAvailableException) PduCodec(herddb.proto.PduCodec) CommitLogResult(herddb.log.CommitLogResult) ClientSideMetadataProviderException(herddb.client.ClientSideMetadataProviderException) LogSequenceNumber(herddb.log.LogSequenceNumber) Set(java.util.Set) ScanStatement(herddb.model.commands.ScanStatement) CountDownLatch(java.util.concurrent.CountDownLatch) Stream(java.util.stream.Stream) HDBClient(herddb.client.HDBClient) TranslatedQuery(herddb.sql.TranslatedQuery) StatsLogger(org.apache.bookkeeper.stats.StatsLogger) TableDataChecksum(herddb.data.consistency.TableDataChecksum) DropTableStatement(herddb.model.commands.DropTableStatement) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) Bytes(herddb.utils.Bytes) SysdualTableManager(herddb.core.system.SysdualTableManager) LogEntry(herddb.log.LogEntry) SysnodesTableManager(herddb.core.system.SysnodesTableManager) ArrayList(java.util.ArrayList) CreateIndexStatement(herddb.model.commands.CreateIndexStatement) TableSpaceDoesNotExistException(herddb.model.TableSpaceDoesNotExistException) TransactionContext(herddb.model.TransactionContext) Transaction(herddb.model.Transaction) BRINIndexManager(herddb.index.brin.BRINIndexManager) SystablestatsTableManager(herddb.core.system.SystablestatsTableManager) BiConsumer(java.util.function.BiConsumer) CommitLogListener(herddb.log.CommitLogListener) ForeignKeyDef(herddb.model.ForeignKeyDef) IndexDoesNotExistException(herddb.model.IndexDoesNotExistException) TableSpaceManagerStats(herddb.core.stats.TableSpaceManagerStats) LogEntryType(herddb.log.LogEntryType) LogEntryFactory(herddb.log.LogEntryFactory) IOException(java.io.IOException) DataStorageManager(herddb.storage.DataStorageManager) DropIndexStatement(herddb.model.commands.DropIndexStatement) ColumnTypes(herddb.model.ColumnTypes) ExecutionException(java.util.concurrent.ExecutionException) AtomicLong(java.util.concurrent.atomic.AtomicLong) Column(herddb.model.Column) KeyValue(herddb.utils.KeyValue) FullRecoveryNeededException(herddb.log.FullRecoveryNeededException) StampedLock(java.util.concurrent.locks.StampedLock) ServerHostData(herddb.network.ServerHostData) TableAlreadyExistsException(herddb.model.TableAlreadyExistsException) RollbackTransactionStatement(herddb.model.commands.RollbackTransactionStatement) CreateTableStatement(herddb.model.commands.CreateTableStatement) TimeoutException(java.util.concurrent.TimeoutException) JMXUtils(herddb.jmx.JMXUtils) TransactionResult(herddb.model.TransactionResult) MetadataStorageManager(herddb.metadata.MetadataStorageManager) Channel(herddb.network.Channel) ServerConfiguration(herddb.server.ServerConfiguration) Futures(herddb.utils.Futures) DataStorageManagerException(herddb.storage.DataStorageManagerException) Index(herddb.model.Index) TableDoesNotExistException(herddb.model.TableDoesNotExistException) AlterTableStatement(herddb.model.commands.AlterTableStatement) SysindexcolumnsTableManager(herddb.core.system.SysindexcolumnsTableManager) DataScanner(herddb.model.DataScanner) DDLException(herddb.model.DDLException) StatementExecutionException(herddb.model.StatementExecutionException) Collection(java.util.Collection) SysstatementsTableManager(herddb.core.system.SysstatementsTableManager) BeginTransactionStatement(herddb.model.commands.BeginTransactionStatement) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) CompletionException(java.util.concurrent.CompletionException) TableAwareStatement(herddb.model.TableAwareStatement) Logger(java.util.logging.Logger) EOFException(java.io.EOFException) Collectors(java.util.stream.Collectors) Objects(java.util.Objects) HDBConnection(herddb.client.HDBConnection) List(java.util.List) FullTableScanConsumer(herddb.storage.FullTableScanConsumer) SystransactionsTableManager(herddb.core.system.SystransactionsTableManager) NodeMetadata(herddb.model.NodeMetadata) Entry(java.util.Map.Entry) Optional(java.util.Optional) TableSpace(herddb.model.TableSpace) SysconfigTableManager(herddb.core.system.SysconfigTableManager) SuppressFBWarnings(edu.umd.cs.findbugs.annotations.SuppressFBWarnings) SysindexesTableManager(herddb.core.system.SysindexesTableManager) Statement(herddb.model.Statement) MetadataStorageManagerException(herddb.metadata.MetadataStorageManagerException) DataScannerException(herddb.model.DataScannerException) SystablespacesTableManager(herddb.core.system.SystablespacesTableManager) HashMap(java.util.HashMap) CompletableFuture(java.util.concurrent.CompletableFuture) Pdu(herddb.proto.Pdu) Level(java.util.logging.Level) HashSet(java.util.HashSet) SysclientsTableManager(herddb.core.system.SysclientsTableManager) TableChecksum(herddb.data.consistency.TableChecksum) ExecutorService(java.util.concurrent.ExecutorService) DumpedLogEntry(herddb.backup.DumpedLogEntry) SysforeignkeysTableManager(herddb.core.system.SysforeignkeysTableManager) ObjectMapper(com.fasterxml.jackson.databind.ObjectMapper) StatementExecutionResult(herddb.model.StatementExecutionResult) TimeUnit(java.util.concurrent.TimeUnit) CommitLog(herddb.log.CommitLog) ClientSideMetadataProvider(herddb.client.ClientSideMetadataProvider) ConcurrentSkipListSet(java.util.concurrent.ConcurrentSkipListSet) SystablespacereplicastateTableManager(herddb.core.system.SystablespacereplicastateTableManager) SQLPlannedOperationStatement(herddb.model.commands.SQLPlannedOperationStatement) StatementEvaluationContext(herddb.model.StatementEvaluationContext) SyscolumnsTableManager(herddb.core.system.SyscolumnsTableManager) Comparator(java.util.Comparator) Collections(java.util.Collections) TableManagerStats(herddb.core.stats.TableManagerStats) MemoryHashIndexManager(herddb.index.MemoryHashIndexManager) SystemProperties(herddb.utils.SystemProperties) DDLStatementExecutionResult(herddb.model.DDLStatementExecutionResult) StatementExecutionResult(herddb.model.StatementExecutionResult) TableAwareStatement(herddb.model.TableAwareStatement)

Aggregations

StatementEvaluationContext (herddb.model.StatementEvaluationContext)24 StatementExecutionException (herddb.model.StatementExecutionException)21 HashMap (java.util.HashMap)21 ScanStatement (herddb.model.commands.ScanStatement)20 List (java.util.List)20 DataScanner (herddb.model.DataScanner)19 Table (herddb.model.Table)19 Map (java.util.Map)18 Column (herddb.model.Column)17 DataStorageManagerException (herddb.storage.DataStorageManagerException)17 Collections (java.util.Collections)17 HashSet (java.util.HashSet)17 TableManagerStats (herddb.core.stats.TableManagerStats)16 CommitLog (herddb.log.CommitLog)16 LogSequenceNumber (herddb.log.LogSequenceNumber)16 DDLException (herddb.model.DDLException)16 Index (herddb.model.Index)16 Statement (herddb.model.Statement)16 StatementExecutionResult (herddb.model.StatementExecutionResult)16 TransactionContext (herddb.model.TransactionContext)16