Search in sources :

Example 16 with DataScannerException

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

the class DeleteOp method executeAsync.

@Override
public CompletableFuture<StatementExecutionResult> executeAsync(TableSpaceManager tableSpaceManager, TransactionContext transactionContext, StatementEvaluationContext context, boolean lockRequired, boolean forWrite) {
    // not supported for deletes
    final boolean returnValues = false;
    StatementExecutionResult input = this.input.execute(tableSpaceManager, transactionContext, context, true, true);
    ScanResult downstreamScanResult = (ScanResult) input;
    final Table table = tableSpaceManager.getTableManager(tableName).getTable();
    long transactionId = transactionContext.transactionId;
    List<DMLStatement> statements = new ArrayList<>();
    try (DataScanner inputScanner = downstreamScanResult.dataScanner) {
        while (inputScanner.hasNext()) {
            DataAccessor row = inputScanner.next();
            long transactionIdFromScanner = inputScanner.getTransactionId();
            if (transactionIdFromScanner > 0 && transactionIdFromScanner != transactionId) {
                transactionId = transactionIdFromScanner;
                transactionContext = new TransactionContext(transactionId);
            }
            Bytes key = RecordSerializer.serializeIndexKey(row, table, table.getPrimaryKey());
            DMLStatement deleteStatement = new DeleteStatement(tableSpace, tableName, null, new RawKeyEquals(key));
            statements.add(deleteStatement);
        }
        if (statements.isEmpty()) {
            return CompletableFuture.completedFuture(new DMLStatementExecutionResult(transactionId, 0, null, null));
        }
        if (statements.size() == 1) {
            return tableSpaceManager.executeStatementAsync(statements.get(0), context, transactionContext);
        }
        CompletableFuture<StatementExecutionResult> finalResult = new CompletableFuture<>();
        AtomicInteger updateCounts = new AtomicInteger();
        AtomicReference<Bytes> lastKey = new AtomicReference<>();
        AtomicReference<Bytes> lastNewValue = new AtomicReference<>();
        class ComputeNext implements BiConsumer<StatementExecutionResult, Throwable> {

            int current;

            public ComputeNext(int current) {
                this.current = current;
            }

            @Override
            public void accept(StatementExecutionResult res, Throwable error) {
                if (error != null) {
                    finalResult.completeExceptionally(error);
                    return;
                }
                DMLStatementExecutionResult dml = (DMLStatementExecutionResult) res;
                updateCounts.addAndGet(dml.getUpdateCount());
                if (returnValues) {
                    lastKey.set(dml.getKey());
                    lastNewValue.set(dml.getNewvalue());
                }
                long newTransactionId = res.transactionId;
                if (current == statements.size()) {
                    DMLStatementExecutionResult finalDMLResult = new DMLStatementExecutionResult(newTransactionId, updateCounts.get(), lastKey.get(), lastNewValue.get());
                    finalResult.complete(finalDMLResult);
                    return;
                }
                DMLStatement nextStatement = statements.get(current);
                TransactionContext transactionContext = new TransactionContext(newTransactionId);
                CompletableFuture<StatementExecutionResult> nextPromise = tableSpaceManager.executeStatementAsync(nextStatement, context, transactionContext);
                nextPromise.whenComplete(new ComputeNext(current + 1));
            }
        }
        DMLStatement firstStatement = statements.get(0);
        tableSpaceManager.executeStatementAsync(firstStatement, context, transactionContext).whenComplete(new ComputeNext(1));
        return finalResult;
    } catch (DataScannerException err) {
        throw new StatementExecutionException(err);
    }
}
Also used : RawKeyEquals(herddb.model.predicates.RawKeyEquals) DataAccessor(herddb.utils.DataAccessor) ArrayList(java.util.ArrayList) DeleteStatement(herddb.model.commands.DeleteStatement) StatementExecutionException(herddb.model.StatementExecutionException) Bytes(herddb.utils.Bytes) CompletableFuture(java.util.concurrent.CompletableFuture) DataScanner(herddb.model.DataScanner) DMLStatementExecutionResult(herddb.model.DMLStatementExecutionResult) StatementExecutionResult(herddb.model.StatementExecutionResult) DataScannerException(herddb.model.DataScannerException) ScanResult(herddb.model.ScanResult) Table(herddb.model.Table) AtomicReference(java.util.concurrent.atomic.AtomicReference) DMLStatementExecutionResult(herddb.model.DMLStatementExecutionResult) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) TransactionContext(herddb.model.TransactionContext) DMLStatement(herddb.model.DMLStatement) BiConsumer(java.util.function.BiConsumer)

Example 17 with DataScannerException

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

the class InsertOp method executeAsync.

@Override
public CompletableFuture<StatementExecutionResult> executeAsync(TableSpaceManager tableSpaceManager, TransactionContext transactionContext, StatementEvaluationContext context, boolean lockRequired, boolean forWrite) {
    StatementExecutionResult input = this.input.execute(tableSpaceManager, transactionContext, context, true, true);
    ScanResult downstreamScanResult = (ScanResult) input;
    final Table table = tableSpaceManager.getTableManager(tableName).getTable();
    long transactionId = transactionContext.transactionId;
    List<DMLStatement> statements = new ArrayList<>();
    try (DataScanner inputScanner = downstreamScanResult.dataScanner) {
        while (inputScanner.hasNext()) {
            DataAccessor row = inputScanner.next();
            long transactionIdFromScanner = inputScanner.getTransactionId();
            if (transactionIdFromScanner > 0 && transactionIdFromScanner != transactionId) {
                transactionId = transactionIdFromScanner;
                transactionContext = new TransactionContext(transactionId);
            }
            int index = 0;
            List<CompiledSQLExpression> keyValueExpression = new ArrayList<>();
            List<String> keyExpressionToColumn = new ArrayList<>();
            List<CompiledSQLExpression> valuesExpressions = new ArrayList<>();
            List<String> valuesColumns = new ArrayList<>();
            for (Column column : table.getColumns()) {
                Object value = row.get(index++);
                if (value != null) {
                    ConstantExpression exp = new ConstantExpression(value, column.type);
                    if (table.isPrimaryKeyColumn(column.name)) {
                        keyExpressionToColumn.add(column.name);
                        keyValueExpression.add(exp);
                    }
                    valuesColumns.add(column.name);
                    valuesExpressions.add(exp);
                }
            }
            RecordFunction keyfunction;
            if (keyValueExpression.isEmpty() && table.auto_increment) {
                keyfunction = new AutoIncrementPrimaryKeyRecordFunction();
            } else {
                if (keyValueExpression.size() != table.primaryKey.length) {
                    throw new StatementExecutionException("you must set a value for the primary key (expressions=" + keyValueExpression.size() + ")");
                }
                keyfunction = new SQLRecordKeyFunction(keyExpressionToColumn, keyValueExpression, table);
            }
            RecordFunction valuesfunction = new SQLRecordFunction(valuesColumns, table, valuesExpressions);
            DMLStatement insertStatement = new InsertStatement(tableSpace, tableName, keyfunction, valuesfunction, upsert).setReturnValues(returnValues);
            statements.add(insertStatement);
        }
        if (statements.isEmpty()) {
            return CompletableFuture.completedFuture(new DMLStatementExecutionResult(transactionId, 0, null, null));
        }
        if (statements.size() == 1) {
            return tableSpaceManager.executeStatementAsync(statements.get(0), context, transactionContext);
        }
        if (returnValues) {
            return Futures.exception(new StatementExecutionException("cannot 'return values' on multi-values insert"));
        }
        CompletableFuture<StatementExecutionResult> finalResult = new CompletableFuture<>();
        AtomicInteger updateCounts = new AtomicInteger();
        AtomicReference<Bytes> lastKey = new AtomicReference<>();
        AtomicReference<Bytes> lastNewValue = new AtomicReference<>();
        class ComputeNext implements BiConsumer<StatementExecutionResult, Throwable> {

            int current;

            public ComputeNext(int current) {
                this.current = current;
            }

            @Override
            public void accept(StatementExecutionResult res, Throwable error) {
                if (error != null) {
                    finalResult.completeExceptionally(error);
                    return;
                }
                DMLStatementExecutionResult dml = (DMLStatementExecutionResult) res;
                updateCounts.addAndGet(dml.getUpdateCount());
                if (returnValues) {
                    lastKey.set(dml.getKey());
                    lastNewValue.set(dml.getNewvalue());
                }
                long newTransactionId = res.transactionId;
                if (current == statements.size()) {
                    DMLStatementExecutionResult finalDMLResult = new DMLStatementExecutionResult(newTransactionId, updateCounts.get(), lastKey.get(), lastNewValue.get());
                    finalResult.complete(finalDMLResult);
                    return;
                }
                DMLStatement nextStatement = statements.get(current);
                TransactionContext transactionContext = new TransactionContext(newTransactionId);
                CompletableFuture<StatementExecutionResult> nextPromise = tableSpaceManager.executeStatementAsync(nextStatement, context, transactionContext);
                nextPromise.whenComplete(new ComputeNext(current + 1));
            }
        }
        DMLStatement firstStatement = statements.get(0);
        tableSpaceManager.executeStatementAsync(firstStatement, context, transactionContext).whenComplete(new ComputeNext(1));
        return finalResult;
    } catch (DataScannerException err) {
        throw new StatementExecutionException(err);
    }
}
Also used : DataAccessor(herddb.utils.DataAccessor) ConstantExpression(herddb.sql.expressions.ConstantExpression) ArrayList(java.util.ArrayList) CompiledSQLExpression(herddb.sql.expressions.CompiledSQLExpression) StatementExecutionException(herddb.model.StatementExecutionException) InsertStatement(herddb.model.commands.InsertStatement) Bytes(herddb.utils.Bytes) CompletableFuture(java.util.concurrent.CompletableFuture) DataScanner(herddb.model.DataScanner) Column(herddb.model.Column) DMLStatementExecutionResult(herddb.model.DMLStatementExecutionResult) StatementExecutionResult(herddb.model.StatementExecutionResult) SQLRecordFunction(herddb.sql.SQLRecordFunction) SQLRecordFunction(herddb.sql.SQLRecordFunction) RecordFunction(herddb.model.RecordFunction) AutoIncrementPrimaryKeyRecordFunction(herddb.model.AutoIncrementPrimaryKeyRecordFunction) SQLRecordKeyFunction(herddb.sql.SQLRecordKeyFunction) DataScannerException(herddb.model.DataScannerException) ScanResult(herddb.model.ScanResult) Table(herddb.model.Table) AtomicReference(java.util.concurrent.atomic.AtomicReference) DMLStatementExecutionResult(herddb.model.DMLStatementExecutionResult) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) TransactionContext(herddb.model.TransactionContext) DMLStatement(herddb.model.DMLStatement) AutoIncrementPrimaryKeyRecordFunction(herddb.model.AutoIncrementPrimaryKeyRecordFunction) BiConsumer(java.util.function.BiConsumer)

Example 18 with DataScannerException

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

the class JoinOp method execute.

@Override
public StatementExecutionResult execute(TableSpaceManager tableSpaceManager, TransactionContext transactionContext, StatementEvaluationContext context, boolean lockRequired, boolean forWrite) throws StatementExecutionException {
    ScanResult resLeft = (ScanResult) left.execute(tableSpaceManager, transactionContext, context, lockRequired, forWrite);
    transactionContext = new TransactionContext(resLeft.transactionId);
    ScanResult resRight = (ScanResult) right.execute(tableSpaceManager, transactionContext, context, lockRequired, forWrite);
    final long resTransactionId = resRight.transactionId;
    DataScanner leftScanner = resLeft.dataScanner;
    final String[] fieldNamesFromLeft = leftScanner.getFieldNames();
    final String[] fieldNamesFromRight = resRight.dataScanner.getFieldNames();
    Function2<DataAccessor, DataAccessor, DataAccessor> resultProjection = resultProjection(fieldNamesFromLeft, fieldNamesFromRight);
    final Predicate2 predicate;
    DataScanner rightScanner = resRight.dataScanner;
    if (nonEquiConditions != null && !nonEquiConditions.isEmpty()) {
        if (mergeJoin) {
            throw new IllegalStateException("Unspected nonEquiConditions " + nonEquiConditions + "" + "for merge join");
        }
        predicate = (Predicate2) (Object t0, Object t1) -> {
            DataAccessor da0 = (DataAccessor) t0;
            DataAccessor da1 = (DataAccessor) t1;
            DataAccessor currentRow = resultProjection.apply(da0, da1);
            for (CompiledSQLExpression exp : nonEquiConditions) {
                Object result = exp.evaluate(currentRow, context);
                boolean asBoolean = SQLRecordPredicateFunctions.toBoolean(result);
                if (!asBoolean) {
                    return false;
                }
            }
            return true;
        };
    } else {
        predicate = null;
    }
    if (!mergeJoin && !leftScanner.isRewindSupported()) {
        try {
            MaterializedRecordSet recordSet = tableSpaceManager.getDbmanager().getRecordSetFactory().createRecordSet(leftScanner.getFieldNames(), leftScanner.getSchema());
            leftScanner.forEach(d -> {
                recordSet.add(d);
            });
            recordSet.writeFinished();
            SimpleDataScanner materialized = new SimpleDataScanner(leftScanner.getTransaction(), recordSet);
            leftScanner.close();
            leftScanner = materialized;
        } catch (DataScannerException err) {
            throw new StatementExecutionException(err);
        }
    }
    if (!mergeJoin && !rightScanner.isRewindSupported()) {
        try {
            MaterializedRecordSet recordSet = tableSpaceManager.getDbmanager().getRecordSetFactory().createRecordSet(rightScanner.getFieldNames(), rightScanner.getSchema());
            rightScanner.forEach(d -> {
                recordSet.add(d);
            });
            recordSet.writeFinished();
            SimpleDataScanner materialized = new SimpleDataScanner(rightScanner.getTransaction(), recordSet);
            rightScanner.close();
            rightScanner = materialized;
        } catch (DataScannerException err) {
            throw new StatementExecutionException(err);
        }
    }
    Enumerable<DataAccessor> result = mergeJoin ? EnumerableDefaults.mergeJoin(leftScanner.createNonRewindableEnumerable(), rightScanner.createNonRewindableEnumerable(), JoinKey.keyExtractor(leftKeys), JoinKey.keyExtractor(rightKeys), resultProjection, generateNullsOnLeft, generateNullsOnRight) : EnumerableDefaults.hashJoin(leftScanner.createRewindOnCloseEnumerable(), rightScanner.createRewindOnCloseEnumerable(), JoinKey.keyExtractor(leftKeys), JoinKey.keyExtractor(rightKeys), resultProjection, null, generateNullsOnLeft, generateNullsOnRight, predicate);
    EnumerableDataScanner joinedScanner = new EnumerableDataScanner(rightScanner.getTransaction(), fieldNames, columns, result, leftScanner, rightScanner);
    return new ScanResult(resTransactionId, joinedScanner);
}
Also used : ScanResult(herddb.model.ScanResult) MaterializedRecordSet(herddb.core.MaterializedRecordSet) DataAccessor(herddb.utils.DataAccessor) CompiledSQLExpression(herddb.sql.expressions.CompiledSQLExpression) StatementExecutionException(herddb.model.StatementExecutionException) SimpleDataScanner(herddb.core.SimpleDataScanner) DataScanner(herddb.model.DataScanner) TransactionContext(herddb.model.TransactionContext) Predicate2(org.apache.calcite.linq4j.function.Predicate2) SimpleDataScanner(herddb.core.SimpleDataScanner) DataScannerException(herddb.model.DataScannerException)

Example 19 with DataScannerException

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

the class ReplaceOp method executeAsync.

@Override
public CompletableFuture<StatementExecutionResult> executeAsync(TableSpaceManager tableSpaceManager, TransactionContext transactionContext, StatementEvaluationContext context, boolean lockRequired, boolean forWrite) {
    StatementExecutionResult input = this.input.execute(tableSpaceManager, transactionContext, context, true, true);
    ScanResult downstreamScanResult = (ScanResult) input;
    TableManager tableManager = (TableManager) tableSpaceManager.getTableManager(tableName);
    final Table table = tableManager.getTable();
    TableContext tableContext = tableManager.buildTableContext();
    long transactionId = transactionContext.transactionId;
    List<DMLStatement> statements = new ArrayList<>();
    try (DataScanner inputScanner = downstreamScanResult.dataScanner) {
        while (inputScanner.hasNext()) {
            DataAccessor row = inputScanner.next();
            long transactionIdFromScanner = inputScanner.getTransactionId();
            if (transactionIdFromScanner > 0 && transactionIdFromScanner != transactionId) {
                transactionId = transactionIdFromScanner;
                transactionContext = new TransactionContext(transactionId);
            }
            Bytes oldKey = RecordSerializer.serializeIndexKey(row, table, table.getPrimaryKey());
            byte[] oldValue = RecordSerializer.serializeValueRaw(row.toMap(), table, -1);
            DMLStatement deleteStatement = new DeleteStatement(tableSpace, tableName, oldKey, null);
            statements.add(deleteStatement);
            Record oldRecord = new Record(oldKey, Bytes.from_array(oldValue));
            byte[] newKey = this.keyFunction.computeNewValue(oldRecord, context, tableContext);
            byte[] newValue = this.recordFunction.computeNewValue(oldRecord, context, tableContext);
            DMLStatement insertStatement = new InsertStatement(tableSpace, tableName, new Record(Bytes.from_array(newKey), Bytes.from_array(newValue))).setReturnValues(returnValues);
            statements.add(insertStatement);
        }
        if (statements.isEmpty()) {
            return CompletableFuture.completedFuture(new DMLStatementExecutionResult(transactionId, 0, null, null));
        }
        if (statements.size() == 1) {
            return tableSpaceManager.executeStatementAsync(statements.get(0), context, transactionContext);
        }
        CompletableFuture<StatementExecutionResult> finalResult = new CompletableFuture<>();
        AtomicInteger updateCounts = new AtomicInteger();
        AtomicReference<Bytes> lastKey = new AtomicReference<>();
        AtomicReference<Bytes> lastNewValue = new AtomicReference<>();
        class ComputeNext implements BiConsumer<StatementExecutionResult, Throwable> {

            int current;

            public ComputeNext(int current) {
                this.current = current;
            }

            @Override
            public void accept(StatementExecutionResult res, Throwable error) {
                if (error != null) {
                    finalResult.completeExceptionally(error);
                    return;
                }
                DMLStatementExecutionResult dml = (DMLStatementExecutionResult) res;
                updateCounts.addAndGet(dml.getUpdateCount());
                if (returnValues) {
                    lastKey.set(dml.getKey());
                    lastNewValue.set(dml.getNewvalue());
                }
                long newTransactionId = res.transactionId;
                if (current == statements.size()) {
                    DMLStatementExecutionResult finalDMLResult = new DMLStatementExecutionResult(newTransactionId, updateCounts.get(), lastKey.get(), lastNewValue.get());
                    finalResult.complete(finalDMLResult);
                    return;
                }
                DMLStatement nextStatement = statements.get(current);
                TransactionContext transactionContext = new TransactionContext(newTransactionId);
                CompletableFuture<StatementExecutionResult> nextPromise = tableSpaceManager.executeStatementAsync(nextStatement, context, transactionContext);
                nextPromise.whenComplete(new ComputeNext(current + 1));
            }
        }
        DMLStatement firstStatement = statements.get(0);
        tableSpaceManager.executeStatementAsync(firstStatement, context, transactionContext).whenComplete(new ComputeNext(1));
        return finalResult;
    } catch (DataScannerException err) {
        throw new StatementExecutionException(err);
    }
}
Also used : DataAccessor(herddb.utils.DataAccessor) ArrayList(java.util.ArrayList) DeleteStatement(herddb.model.commands.DeleteStatement) InsertStatement(herddb.model.commands.InsertStatement) StatementExecutionException(herddb.model.StatementExecutionException) Bytes(herddb.utils.Bytes) CompletableFuture(java.util.concurrent.CompletableFuture) DataScanner(herddb.model.DataScanner) TableContext(herddb.model.TableContext) DMLStatementExecutionResult(herddb.model.DMLStatementExecutionResult) StatementExecutionResult(herddb.model.StatementExecutionResult) TableManager(herddb.core.TableManager) Record(herddb.model.Record) DataScannerException(herddb.model.DataScannerException) ScanResult(herddb.model.ScanResult) Table(herddb.model.Table) AtomicReference(java.util.concurrent.atomic.AtomicReference) DMLStatementExecutionResult(herddb.model.DMLStatementExecutionResult) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) TransactionContext(herddb.model.TransactionContext) DMLStatement(herddb.model.DMLStatement) BiConsumer(java.util.function.BiConsumer)

Example 20 with DataScannerException

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

the class SortOp method execute.

@Override
public StatementExecutionResult execute(TableSpaceManager tableSpaceManager, TransactionContext transactionContext, StatementEvaluationContext context, boolean lockRequired, boolean forWrite) throws StatementExecutionException {
    // TODO merge projection + scan + sort + limit
    StatementExecutionResult input = this.input.execute(tableSpaceManager, transactionContext, context, lockRequired, forWrite);
    ScanResult downstreamScanResult = (ScanResult) input;
    final DataScanner inputScanner = downstreamScanResult.dataScanner;
    try (DataScanner dataScanner = inputScanner) {
        MaterializedRecordSet recordSet = tableSpaceManager.getDbmanager().getRecordSetFactory().createRecordSet(inputScanner.getFieldNames(), inputScanner.getSchema());
        while (dataScanner.hasNext()) {
            DataAccessor row = dataScanner.next();
            recordSet.add(row);
        }
        recordSet.writeFinished();
        recordSet.sort(this);
        SimpleDataScanner result = new SimpleDataScanner(downstreamScanResult.dataScanner.getTransaction(), recordSet);
        return new ScanResult(downstreamScanResult.transactionId, result);
    } catch (DataScannerException ex) {
        throw new StatementExecutionException(ex);
    }
}
Also used : ScanResult(herddb.model.ScanResult) SimpleDataScanner(herddb.core.SimpleDataScanner) DataScanner(herddb.model.DataScanner) MaterializedRecordSet(herddb.core.MaterializedRecordSet) DataAccessor(herddb.utils.DataAccessor) StatementExecutionResult(herddb.model.StatementExecutionResult) SimpleDataScanner(herddb.core.SimpleDataScanner) StatementExecutionException(herddb.model.StatementExecutionException) DataScannerException(herddb.model.DataScannerException)

Aggregations

DataScannerException (herddb.model.DataScannerException)30 DataScanner (herddb.model.DataScanner)26 StatementExecutionException (herddb.model.StatementExecutionException)25 DataAccessor (herddb.utils.DataAccessor)24 ScanResult (herddb.model.ScanResult)19 TransactionContext (herddb.model.TransactionContext)18 StatementExecutionResult (herddb.model.StatementExecutionResult)15 Table (herddb.model.Table)13 DMLStatementExecutionResult (herddb.model.DMLStatementExecutionResult)12 ArrayList (java.util.ArrayList)12 Bytes (herddb.utils.Bytes)10 DMLStatement (herddb.model.DMLStatement)8 InsertStatement (herddb.model.commands.InsertStatement)8 ScanStatement (herddb.model.commands.ScanStatement)8 Column (herddb.model.Column)6 CompletableFuture (java.util.concurrent.CompletableFuture)6 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)6 HerdDBInternalException (herddb.core.HerdDBInternalException)5 DuplicatePrimaryKeyException (herddb.model.DuplicatePrimaryKeyException)5 RecordFunction (herddb.model.RecordFunction)5