Search in sources :

Example 26 with StatementExecutionException

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

the class TableManager method executeInsert.

private StatementExecutionResult executeInsert(InsertStatement insert, Transaction transaction, StatementEvaluationContext context) throws StatementExecutionException, DataStorageManagerException {
    /*
         an insert can succeed only if the row is valid and the "keys" structure  does not contain the requested key
         the insert will add the row in the 'buffer' without assigning a page to it
         locks: the insert uses global 'insert' lock on the table
         the insert will update the 'maxKey' for auto_increment primary keys
         */
    Bytes key = new Bytes(insert.getKeyFunction().computeNewValue(null, context, tableContext));
    byte[] value = insert.getValuesFunction().computeNewValue(new Record(key, null), context, tableContext);
    final long size = DataPage.estimateEntrySize(key, value);
    if (size > maxLogicalPageSize) {
        throw new RecordTooBigException("New record " + key + " is to big to be inserted: size " + size + ", max size " + maxLogicalPageSize);
    }
    LockHandle lock = lockForWrite(key, transaction);
    try {
        if (transaction != null) {
            if (transaction.recordDeleted(table.name, key)) {
            // OK, INSERT on a DELETED record inside this transaction
            } else if (transaction.recordInserted(table.name, key) != null) {
                // ERROR, INSERT on a INSERTED record inside this transaction
                throw new DuplicatePrimaryKeyException(key, "key " + key + ", decoded as " + RecordSerializer.deserializePrimaryKey(key.data, table) + ", already exists in table " + table.name + " inside transaction " + transaction.transactionId);
            } else if (keyToPage.containsKey(key)) {
                throw new DuplicatePrimaryKeyException(key, "key " + key + ", decoded as " + RecordSerializer.deserializePrimaryKey(key.data, table) + ", already exists in table " + table.name + " during transaction " + transaction.transactionId);
            }
        } else if (keyToPage.containsKey(key)) {
            throw new DuplicatePrimaryKeyException(key, "key " + key + ", decoded as " + RecordSerializer.deserializePrimaryKey(key.data, table) + ", already exists in table " + table.name);
        }
        LogEntry entry = LogEntryFactory.insert(table, key.data, value, transaction);
        CommitLogResult pos = log.log(entry, entry.transactionId <= 0);
        apply(pos, entry, false);
        return new DMLStatementExecutionResult(entry.transactionId, 1, key, insert.isReturnValues() ? Bytes.from_array(value) : null);
    } catch (LogNotAvailableException err) {
        throw new StatementExecutionException(err);
    } finally {
        if (transaction == null) {
            locksManager.releaseWriteLockForKey(key, lock);
        }
    }
}
Also used : Bytes(herddb.utils.Bytes) LockHandle(herddb.utils.LockHandle) DMLStatementExecutionResult(herddb.model.DMLStatementExecutionResult) DuplicatePrimaryKeyException(herddb.model.DuplicatePrimaryKeyException) Record(herddb.model.Record) CommitLogResult(herddb.log.CommitLogResult) RecordTooBigException(herddb.model.RecordTooBigException) LogEntry(herddb.log.LogEntry) StatementExecutionException(herddb.model.StatementExecutionException) LogNotAvailableException(herddb.log.LogNotAvailableException)

Example 27 with StatementExecutionException

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

the class SystablespacereplicastateTableManager method buildVirtualRecordList.

@Override
protected Iterable<Record> buildVirtualRecordList() throws StatementExecutionException {
    try {
        Collection<String> names = tableSpaceManager.getMetadataStorageManager().listTableSpaces();
        long now = System.currentTimeMillis();
        List<Record> result = new ArrayList<>();
        for (String name : names) {
            TableSpace t = tableSpaceManager.getMetadataStorageManager().describeTableSpace(name);
            if (t != null) {
                List<TableSpaceReplicaState> tableSpaceReplicaStates = tableSpaceManager.getMetadataStorageManager().getTableSpaceReplicaState(t.uuid);
                for (TableSpaceReplicaState state : tableSpaceReplicaStates) {
                    result.add(RecordSerializer.makeRecord(table, "tablespace_name", t.name, "uuid", t.uuid, "nodeid", state.nodeId, "timestamp", new java.sql.Timestamp(state.timestamp), "maxleaderinactivitytime", t.maxLeaderInactivityTime, "inactivitytime", now - state.timestamp, "mode", TableSpaceReplicaState.modeToSQLString(state.mode)));
                }
            }
        }
        return result;
    } catch (MetadataStorageManagerException error) {
        throw new StatementExecutionException(error);
    }
}
Also used : TableSpace(herddb.model.TableSpace) ArrayList(java.util.ArrayList) StatementExecutionException(herddb.model.StatementExecutionException) MetadataStorageManagerException(herddb.metadata.MetadataStorageManagerException) Record(herddb.model.Record) TableSpaceReplicaState(herddb.model.TableSpaceReplicaState)

Example 28 with StatementExecutionException

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

the class SystablespacesTableManager method buildVirtualRecordList.

@Override
protected Iterable<Record> buildVirtualRecordList() throws StatementExecutionException {
    try {
        Collection<String> names = tableSpaceManager.getMetadataStorageManager().listTableSpaces();
        List<Record> result = new ArrayList<>();
        for (String name : names) {
            TableSpace t = tableSpaceManager.getMetadataStorageManager().describeTableSpace(name);
            if (t != null) {
                result.add(RecordSerializer.makeRecord(table, "tablespace_name", t.name, "uuid", t.uuid, "leader", t.leaderId, "expectedreplicacount", t.expectedReplicaCount, "maxleaderinactivitytime", t.maxLeaderInactivityTime, "replica", t.replicas.stream().collect(Collectors.joining(","))));
            }
        }
        return result;
    } catch (MetadataStorageManagerException error) {
        throw new StatementExecutionException(error);
    }
}
Also used : MetadataStorageManagerException(herddb.metadata.MetadataStorageManagerException) TableSpace(herddb.model.TableSpace) ArrayList(java.util.ArrayList) Record(herddb.model.Record) StatementExecutionException(herddb.model.StatementExecutionException)

Example 29 with StatementExecutionException

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

the class TableManager method executeGetAsync.

private CompletableFuture<StatementExecutionResult> executeGetAsync(GetStatement get, Transaction transaction, StatementEvaluationContext context) {
    Bytes key;
    try {
        key = Bytes.from_nullable_array(get.getKey().computeNewValue(null, context, tableContext));
    } catch (StatementExecutionException validationError) {
        return Futures.exception(validationError);
    }
    Predicate predicate = get.getPredicate();
    boolean requireLock = get.isRequireLock();
    boolean useWriteLock = requireLock && context.isForceAcquireWriteLock();
    long transactionId = transaction != null ? transaction.transactionId : 0;
    LockHandle lock = (transaction != null || requireLock) ? (useWriteLock ? lockForWrite(key, transaction) : lockForRead(key, transaction)) : null;
    CompletableFuture<StatementExecutionResult> res = null;
    try {
        if (transaction != null) {
            if (transaction.recordDeleted(table.name, key)) {
                res = CompletableFuture.completedFuture(GetResult.NOT_FOUND(transactionId));
            } else {
                Record loadedInTransaction = transaction.recordUpdated(table.name, key);
                if (loadedInTransaction != null) {
                    if (predicate != null && !predicate.evaluate(loadedInTransaction, context)) {
                        res = CompletableFuture.completedFuture(GetResult.NOT_FOUND(transactionId));
                    } else {
                        res = CompletableFuture.completedFuture(new GetResult(transactionId, loadedInTransaction, table));
                    }
                } else {
                    loadedInTransaction = transaction.recordInserted(table.name, key);
                    if (loadedInTransaction != null) {
                        if (predicate != null && !predicate.evaluate(loadedInTransaction, context)) {
                            res = CompletableFuture.completedFuture(GetResult.NOT_FOUND(transactionId));
                        } else {
                            res = CompletableFuture.completedFuture(new GetResult(transactionId, loadedInTransaction, table));
                        }
                    }
                }
            }
        }
        if (res == null) {
            Long pageId = keyToPage.get(key);
            if (pageId == null) {
                res = CompletableFuture.completedFuture(GetResult.NOT_FOUND(transactionId));
            } else {
                Record loaded = fetchRecord(key, pageId, null);
                if (loaded == null || (predicate != null && !predicate.evaluate(loaded, context))) {
                    res = CompletableFuture.completedFuture(GetResult.NOT_FOUND(transactionId));
                } else {
                    res = CompletableFuture.completedFuture(new GetResult(transactionId, loaded, table));
                }
            }
        }
        if (lock != null) {
            if (transaction == null) {
                res.whenComplete((r, e) -> {
                    locksManager.releaseReadLock(lock);
                });
            } else if (!context.isForceRetainReadLock() && !lock.write) {
                transaction.releaseLockOnKey(table.name, key, locksManager);
            }
        }
        return res;
    } catch (HerdDBInternalException err) {
        return Futures.exception(err);
    }
}
Also used : Bytes(herddb.utils.Bytes) LockHandle(herddb.utils.LockHandle) GetResult(herddb.model.GetResult) DMLStatementExecutionResult(herddb.model.DMLStatementExecutionResult) StatementExecutionResult(herddb.model.StatementExecutionResult) AtomicLong(java.util.concurrent.atomic.AtomicLong) Record(herddb.model.Record) StatementExecutionException(herddb.model.StatementExecutionException) Predicate(herddb.model.Predicate)

Example 30 with StatementExecutionException

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

the class TableManager method executeInsertAsync.

private CompletableFuture<StatementExecutionResult> executeInsertAsync(InsertStatement insert, Transaction transaction, StatementEvaluationContext context) {
    /*
         an insert can succeed only if the row is valid and the "keys" structure  does not contain the requested key
         the insert will add the row in the 'buffer' without assigning a page to it
         locks: the insert uses global 'insert' lock on the table
         the insert will update the 'maxKey' for auto_increment primary keys
         */
    Bytes key;
    byte[] value;
    try {
        key = Bytes.from_array(insert.getKeyFunction().computeNewValue(null, context, tableContext));
        value = insert.getValuesFunction().computeNewValue(new Record(key, null), context, tableContext);
    } catch (StatementExecutionException validationError) {
        return Futures.exception(validationError);
    } catch (Throwable validationError) {
        return Futures.exception(new StatementExecutionException(validationError));
    }
    List<UniqueIndexLockReference> uniqueIndexes = null;
    Map<String, AbstractIndexManager> indexes = tableSpaceManager.getIndexesOnTable(table.name);
    if (indexes != null || table.foreignKeys != null) {
        try {
            DataAccessor values = new Record(key, Bytes.from_array(value)).getDataAccessor(table);
            if (table.foreignKeys != null) {
                for (ForeignKeyDef fk : table.foreignKeys) {
                    checkForeignKeyConstraintsAsChildTable(fk, values, context, transaction);
                }
            }
            if (indexes != null) {
                for (AbstractIndexManager index : indexes.values()) {
                    if (index.isUnique()) {
                        Bytes indexKey = RecordSerializer.serializeIndexKey(values, index.getIndex(), index.getColumnNames());
                        if (uniqueIndexes == null) {
                            uniqueIndexes = new ArrayList<>(1);
                        }
                        uniqueIndexes.add(new UniqueIndexLockReference(index, indexKey));
                    } else {
                        RecordSerializer.validateIndexableValue(values, index.getIndex(), index.getColumnNames());
                    }
                }
            }
        } catch (IllegalArgumentException | herddb.utils.IllegalDataAccessException | StatementExecutionException err) {
            if (err instanceof StatementExecutionException) {
                return Futures.exception(err);
            } else {
                return Futures.exception(new StatementExecutionException(err.getMessage(), err));
            }
        }
    }
    final long size = DataPage.estimateEntrySize(key, value);
    if (size > maxLogicalPageSize) {
        return Futures.exception(new RecordTooBigException("New record " + key + " is to big to be inserted: size " + size + ", max size " + maxLogicalPageSize));
    }
    CompletableFuture<StatementExecutionResult> res = null;
    LockHandle lock = null;
    try {
        lock = lockForWrite(key, transaction);
        if (uniqueIndexes != null) {
            for (UniqueIndexLockReference uniqueIndexLock : uniqueIndexes) {
                AbstractIndexManager index = uniqueIndexLock.indexManager;
                LockHandle lockForIndex = lockForWrite(uniqueIndexLock.key, transaction, index.getIndexName(), index.getLockManager());
                if (transaction == null) {
                    uniqueIndexLock.lockHandle = lockForIndex;
                }
                if (index.valueAlreadyMapped(uniqueIndexLock.key, null)) {
                    res = Futures.exception(new UniqueIndexContraintViolationException(index.getIndexName(), key, "key " + key + ", already exists in table " + table.name + " on UNIQUE index " + index.getIndexName()));
                }
                if (res != null) {
                    break;
                }
            }
        }
    } catch (HerdDBInternalException err) {
        res = Futures.exception(err);
    }
    boolean fallbackToUpsert = false;
    if (res == null) {
        if (transaction != null) {
            if (transaction.recordDeleted(table.name, key)) {
            // OK, INSERT on a DELETED record inside this transaction
            } else if (transaction.recordInserted(table.name, key) != null) {
                // ERROR, INSERT on a INSERTED record inside this transaction
                res = Futures.exception(new DuplicatePrimaryKeyException(key, "key " + key + ", decoded as " + RecordSerializer.deserializePrimaryKey(key, table) + ", already exists in table " + table.name + " inside transaction " + transaction.transactionId));
            } else if (keyToPage.containsKey(key)) {
                if (insert.isUpsert()) {
                    fallbackToUpsert = true;
                } else {
                    res = Futures.exception(new DuplicatePrimaryKeyException(key, "key " + key + ", decoded as " + RecordSerializer.deserializePrimaryKey(key, table) + ", already exists in table " + table.name + " during transaction " + transaction.transactionId));
                }
            }
        } else if (keyToPage.containsKey(key)) {
            if (insert.isUpsert()) {
                fallbackToUpsert = true;
            } else {
                res = Futures.exception(new DuplicatePrimaryKeyException(key, "key " + key + ", decoded as " + RecordSerializer.deserializePrimaryKey(key, table) + ", already exists in table " + table.name));
            }
        }
    }
    if (res == null) {
        LogEntry entry;
        if (fallbackToUpsert) {
            entry = LogEntryFactory.update(table, key, Bytes.from_array(value), transaction);
        } else {
            entry = LogEntryFactory.insert(table, key, Bytes.from_array(value), transaction);
        }
        CommitLogResult pos = log.log(entry, entry.transactionId <= 0);
        res = pos.logSequenceNumber.thenApplyAsync((lsn) -> {
            apply(pos, entry, false);
            return new DMLStatementExecutionResult(entry.transactionId, 1, key, insert.isReturnValues() ? Bytes.from_array(value) : null);
        }, tableSpaceManager.getCallbacksExecutor());
    }
    if (uniqueIndexes != null) {
        // TODO: reverse order
        for (UniqueIndexLockReference uniqueIndexLock : uniqueIndexes) {
            res = releaseWriteLock(res, uniqueIndexLock.lockHandle, uniqueIndexLock.indexManager.getLockManager());
        }
    }
    if (transaction == null) {
        res = releaseWriteLock(res, lock);
    }
    return res;
}
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) CommitLogResult(herddb.log.CommitLogResult) RecordTooBigException(herddb.model.RecordTooBigException) StatementExecutionException(herddb.model.StatementExecutionException) Bytes(herddb.utils.Bytes) DMLStatementExecutionResult(herddb.model.DMLStatementExecutionResult) StatementExecutionResult(herddb.model.StatementExecutionResult) DuplicatePrimaryKeyException(herddb.model.DuplicatePrimaryKeyException) Record(herddb.model.Record) LogEntry(herddb.log.LogEntry) LockHandle(herddb.utils.LockHandle) UniqueIndexContraintViolationException(herddb.model.UniqueIndexContraintViolationException) DMLStatementExecutionResult(herddb.model.DMLStatementExecutionResult) ForeignKeyDef(herddb.model.ForeignKeyDef)

Aggregations

StatementExecutionException (herddb.model.StatementExecutionException)163 Table (herddb.model.Table)69 ArrayList (java.util.ArrayList)57 DataScanner (herddb.model.DataScanner)49 TransactionContext (herddb.model.TransactionContext)47 DataStorageManagerException (herddb.storage.DataStorageManagerException)40 List (java.util.List)40 DataScannerException (herddb.model.DataScannerException)39 StatementExecutionResult (herddb.model.StatementExecutionResult)39 Column (herddb.model.Column)37 DataAccessor (herddb.utils.DataAccessor)36 LogNotAvailableException (herddb.log.LogNotAvailableException)35 LogEntry (herddb.log.LogEntry)34 Test (org.junit.Test)34 InsertStatement (herddb.model.commands.InsertStatement)32 Bytes (herddb.utils.Bytes)32 CommitLogResult (herddb.log.CommitLogResult)31 Record (herddb.model.Record)31 DMLStatementExecutionResult (herddb.model.DMLStatementExecutionResult)30 Map (java.util.Map)30