Search in sources :

Example 1 with SQLPlannedOperationStatement

use of herddb.model.commands.SQLPlannedOperationStatement in project herddb by diennea.

the class ServerSideConnectionPeer method handleOpenScanner.

private void handleOpenScanner(Message message, Channel _channel) {
    String tableSpace = (String) message.parameters.get("tableSpace");
    Long tx = (Long) message.parameters.get("tx");
    long txId = tx != null ? tx : 0;
    String query = (String) message.parameters.get("query");
    String scannerId = (String) message.parameters.get("scannerId");
    int fetchSize = 10;
    if (message.parameters.containsKey("fetchSize")) {
        fetchSize = (Integer) message.parameters.get("fetchSize");
    }
    int maxRows = 0;
    if (message.parameters.containsKey("maxRows")) {
        maxRows = (Integer) message.parameters.get("maxRows");
    }
    List<Object> parameters = (List<Object>) message.parameters.get("params");
    if (LOGGER.isLoggable(Level.FINEST)) {
        LOGGER.log(Level.FINEST, "openScanner txId+" + txId + ", fetchSize " + fetchSize + ", maxRows " + maxRows + "," + query + " with " + parameters);
    }
    try {
        TranslatedQuery translatedQuery = server.getManager().getPlanner().translate(tableSpace, query, parameters, true, true, false, maxRows);
        if (LOGGER.isLoggable(Level.FINEST)) {
            LOGGER.log(Level.FINEST, query + " -> " + translatedQuery.plan.mainStatement);
        }
        TransactionContext transactionContext = new TransactionContext(txId);
        if (translatedQuery.plan.mainStatement instanceof SQLPlannedOperationStatement || translatedQuery.plan.mainStatement instanceof ScanStatement || translatedQuery.plan.joinStatements != null) {
            ScanResult scanResult = (ScanResult) server.getManager().executePlan(translatedQuery.plan, translatedQuery.context, transactionContext);
            DataScanner dataScanner = scanResult.dataScanner;
            ServerSideScannerPeer scanner = new ServerSideScannerPeer(dataScanner);
            String[] columns = dataScanner.getFieldNames();
            List<DataAccessor> records = dataScanner.consume(fetchSize);
            TuplesList tuplesList = new TuplesList(columns, records);
            boolean last = dataScanner.isFinished();
            LOGGER.log(Level.FINEST, "sending first {0} records to scanner {1} query {2}", new Object[] { records.size(), scannerId, query });
            if (!last) {
                scanners.put(scannerId, scanner);
            }
            _channel.sendReplyMessage(message, Message.RESULTSET_CHUNK(null, scannerId, tuplesList, last, dataScanner.transactionId));
        } else {
            _channel.sendReplyMessage(message, Message.ERROR(null, new Exception("unsupported query type for scan " + query + ": PLAN is " + translatedQuery.plan)));
        }
    } catch (DataScannerException | RuntimeException err) {
        LOGGER.log(Level.SEVERE, "error on scanner " + scannerId + ": " + err, err);
        scanners.remove(scannerId);
        Message error = Message.ERROR(null, err);
        if (err instanceof NotLeaderException) {
            error.setParameter("notLeader", "true");
        }
        _channel.sendReplyMessage(message, error);
    }
}
Also used : NotLeaderException(herddb.model.NotLeaderException) Message(herddb.network.Message) DataAccessor(herddb.utils.DataAccessor) SQLPlannedOperationStatement(herddb.model.commands.SQLPlannedOperationStatement) DataScanner(herddb.model.DataScanner) List(java.util.List) TuplesList(herddb.utils.TuplesList) ArrayList(java.util.ArrayList) ScanStatement(herddb.model.commands.ScanStatement) TuplesList(herddb.utils.TuplesList) DataScannerException(herddb.model.DataScannerException) ScanResult(herddb.model.ScanResult) TranslatedQuery(herddb.sql.TranslatedQuery) DuplicatePrimaryKeyException(herddb.model.DuplicatePrimaryKeyException) HerdDBInternalException(herddb.core.HerdDBInternalException) StatementExecutionException(herddb.model.StatementExecutionException) NotLeaderException(herddb.model.NotLeaderException) DataScannerException(herddb.model.DataScannerException) TransactionContext(herddb.model.TransactionContext) AtomicLong(java.util.concurrent.atomic.AtomicLong)

Example 2 with SQLPlannedOperationStatement

use of herddb.model.commands.SQLPlannedOperationStatement in project herddb by diennea.

the class TableSpaceManager method executeStatement.

public StatementExecutionResult executeStatement(Statement statement, StatementEvaluationContext context, TransactionContext transactionContext) throws StatementExecutionException {
    boolean rollbackOnError = false;
    /* Do not autostart transaction on alter table statements */
    if (transactionContext.transactionId == TransactionContext.AUTOTRANSACTION_ID && statement.supportsTransactionAutoCreate()) {
        StatementExecutionResult newTransaction = beginTransaction();
        transactionContext = new TransactionContext(newTransaction.transactionId);
        rollbackOnError = true;
    }
    Transaction transaction = transactions.get(transactionContext.transactionId);
    if (transaction != null && !transaction.tableSpace.equals(tableSpaceName)) {
        throw new StatementExecutionException("transaction " + transaction.transactionId + " is for tablespace " + transaction.tableSpace + ", not for " + tableSpaceName);
    }
    if (transactionContext.transactionId > 0 && transaction == null) {
        throw new StatementExecutionException("transaction " + transactionContext.transactionId + " not found on tablespace " + tableSpaceName);
    }
    try {
        if (statement instanceof TableAwareStatement) {
            return executeTableAwareStatement(statement, transaction, context);
        }
        if (statement instanceof SQLPlannedOperationStatement) {
            return executePlannedOperationStatement(statement, transactionContext, context);
        }
        if (statement instanceof BeginTransactionStatement) {
            if (transaction != null) {
                throw new IllegalArgumentException("transaction already started");
            }
            return beginTransaction();
        }
        if (statement instanceof RollbackTransactionStatement) {
            return rollbackTransaction((RollbackTransactionStatement) statement);
        }
        if (statement instanceof CommitTransactionStatement) {
            return commitTransaction((CommitTransactionStatement) statement);
        }
        if (statement instanceof CreateTableStatement) {
            return createTable((CreateTableStatement) statement, transaction);
        }
        if (statement instanceof CreateIndexStatement) {
            return createIndex((CreateIndexStatement) statement, transaction);
        }
        if (statement instanceof DropTableStatement) {
            return dropTable((DropTableStatement) statement, transaction);
        }
        if (statement instanceof DropIndexStatement) {
            return dropIndex((DropIndexStatement) statement, transaction);
        }
        if (statement instanceof AlterTableStatement) {
            return alterTable((AlterTableStatement) statement, transactionContext);
        }
        throw new StatementExecutionException("unsupported statement " + statement);
    } catch (StatementExecutionException error) {
        if (rollbackOnError) {
            rollbackTransaction(new RollbackTransactionStatement(tableSpaceName, transactionContext.transactionId));
        }
        throw error;
    }
}
Also used : AlterTableStatement(herddb.model.commands.AlterTableStatement) CommitTransactionStatement(herddb.model.commands.CommitTransactionStatement) CreateTableStatement(herddb.model.commands.CreateTableStatement) RollbackTransactionStatement(herddb.model.commands.RollbackTransactionStatement) CreateIndexStatement(herddb.model.commands.CreateIndexStatement) TableAwareStatement(herddb.model.TableAwareStatement) StatementExecutionException(herddb.model.StatementExecutionException) SQLPlannedOperationStatement(herddb.model.commands.SQLPlannedOperationStatement) DropIndexStatement(herddb.model.commands.DropIndexStatement) Transaction(herddb.model.Transaction) TransactionContext(herddb.model.TransactionContext) DDLStatementExecutionResult(herddb.model.DDLStatementExecutionResult) StatementExecutionResult(herddb.model.StatementExecutionResult) BeginTransactionStatement(herddb.model.commands.BeginTransactionStatement) DropTableStatement(herddb.model.commands.DropTableStatement)

Example 3 with SQLPlannedOperationStatement

use of herddb.model.commands.SQLPlannedOperationStatement in project herddb by diennea.

the class CalcitePlanner method translate.

@Override
public TranslatedQuery translate(String defaultTableSpace, String query, List<Object> parameters, boolean scan, boolean allowCache, boolean returnValues, int maxRows) throws StatementExecutionException {
    query = SQLPlanner.rewriteExecuteSyntax(query);
    if (query.startsWith("EXECUTE") || query.startsWith("CREATE") || query.startsWith("DROP") || query.startsWith("ALTER") || query.startsWith("TRUNCATE")) {
        return fallback.translate(defaultTableSpace, query, parameters, scan, allowCache, returnValues, maxRows);
    }
    if (parameters == null) {
        parameters = Collections.emptyList();
    }
    String cacheKey = "scan:" + scan + ",defaultTableSpace:" + defaultTableSpace + ",query:" + query + ",returnValues:" + returnValues + ",maxRows:" + maxRows;
    if (allowCache) {
        ExecutionPlan cached = cache.get(cacheKey);
        if (cached != null) {
            return new TranslatedQuery(cached, new SQLStatementEvaluationContext(query, parameters));
        }
    }
    if (!isCachable(query)) {
        allowCache = false;
    }
    try {
        if (query.startsWith("EXPLAIN ")) {
            query = query.substring("EXPLAIN ".length());
            PlannerResult plan = runPlanner(defaultTableSpace, query);
            PlannerOp finalPlan = convertRelNode(plan.topNode, plan.originalRowType, returnValues).optimize();
            ValuesOp values = new ValuesOp(manager.getNodeId(), new String[] { "name", "value" }, new Column[] { column("name", ColumnTypes.STRING), column("value", ColumnTypes.STRING) }, java.util.Arrays.asList(java.util.Arrays.asList(new ConstantExpression("query"), new ConstantExpression(query)), java.util.Arrays.asList(new ConstantExpression("logicalplan"), new ConstantExpression(RelOptUtil.dumpPlan("", plan.logicalPlan, SqlExplainFormat.TEXT, SqlExplainLevel.ALL_ATTRIBUTES))), java.util.Arrays.asList(new ConstantExpression("plan"), new ConstantExpression(RelOptUtil.dumpPlan("", plan.topNode, SqlExplainFormat.TEXT, SqlExplainLevel.ALL_ATTRIBUTES))), java.util.Arrays.asList(new ConstantExpression("finalplan"), new ConstantExpression(finalPlan + ""))));
            ExecutionPlan executionPlan = ExecutionPlan.simple(new SQLPlannedOperationStatement(values));
            return new TranslatedQuery(executionPlan, new SQLStatementEvaluationContext(query, parameters));
        }
        PlannerResult plan = runPlanner(defaultTableSpace, query);
        SQLPlannedOperationStatement sqlPlannedOperationStatement = new SQLPlannedOperationStatement(convertRelNode(plan.topNode, plan.originalRowType, returnValues).optimize());
        if (LOG.isLoggable(Level.FINE)) {
            LOG.log(Level.FINE, "Query: {0} --HerdDB Plan {1}", new Object[] { query, sqlPlannedOperationStatement.getRootOp() });
        }
        if (!scan) {
            ScanStatement scanStatement = sqlPlannedOperationStatement.unwrap(ScanStatement.class);
            if (scanStatement != null) {
                Table tableDef = scanStatement.getTableDef();
                CompiledSQLExpression where = scanStatement.getPredicate().unwrap(CompiledSQLExpression.class);
                SQLRecordKeyFunction keyFunction = findIndexAccess(where, tableDef.getPrimaryKey(), tableDef, "=", tableDef);
                if (keyFunction == null || !keyFunction.isFullPrimaryKey()) {
                    throw new StatementExecutionException("unsupported GET not on PK, bad where clause: " + query);
                }
                GetStatement get = new GetStatement(scanStatement.getTableSpace(), scanStatement.getTable(), keyFunction, scanStatement.getPredicate(), true);
                ExecutionPlan executionPlan = ExecutionPlan.simple(get);
                if (allowCache) {
                    cache.put(cacheKey, executionPlan);
                }
                return new TranslatedQuery(executionPlan, new SQLStatementEvaluationContext(query, parameters));
            }
        }
        if (maxRows > 0) {
            PlannerOp op = new LimitOp(sqlPlannedOperationStatement.getRootOp(), new ConstantExpression(maxRows), new ConstantExpression(0)).optimize();
            sqlPlannedOperationStatement = new SQLPlannedOperationStatement(op);
        }
        ExecutionPlan executionPlan = ExecutionPlan.simple(sqlPlannedOperationStatement);
        if (allowCache) {
            cache.put(cacheKey, executionPlan);
        }
        return new TranslatedQuery(executionPlan, new SQLStatementEvaluationContext(query, parameters));
    } catch (CalciteContextException ex) {
        LOG.log(Level.INFO, "Error while parsing '" + ex.getOriginalStatement() + "'", ex);
        // TODO can this be done better ?
        throw new StatementExecutionException(ex.getMessage());
    } catch (RelConversionException | ValidationException | SqlParseException ex) {
        LOG.log(Level.INFO, "Error while parsing '" + query + "'", ex);
        // TODO can this be done better ?
        throw new StatementExecutionException(ex.getMessage().replace("org.apache.calcite.runtime.CalciteContextException: ", ""));
    } catch (MetadataStorageManagerException ex) {
        LOG.log(Level.INFO, "Error while parsing '" + query + "'", ex);
        throw new StatementExecutionException(ex);
    }
}
Also used : PlannerOp(herddb.model.planner.PlannerOp) Table(herddb.model.Table) RelOptTable(org.apache.calcite.plan.RelOptTable) ProjectableFilterableTable(org.apache.calcite.schema.ProjectableFilterableTable) ScannableTable(org.apache.calcite.schema.ScannableTable) AbstractTable(org.apache.calcite.schema.impl.AbstractTable) ModifiableTable(org.apache.calcite.schema.ModifiableTable) ValidationException(org.apache.calcite.tools.ValidationException) SqlParseException(org.apache.calcite.sql.parser.SqlParseException) ConstantExpression(herddb.sql.expressions.ConstantExpression) CompiledSQLExpression(herddb.sql.expressions.CompiledSQLExpression) LimitOp(herddb.model.planner.LimitOp) ValuesOp(herddb.model.planner.ValuesOp) StatementExecutionException(herddb.model.StatementExecutionException) RelConversionException(org.apache.calcite.tools.RelConversionException) SQLPlannedOperationStatement(herddb.model.commands.SQLPlannedOperationStatement) MetadataStorageManagerException(herddb.metadata.MetadataStorageManagerException) CalciteContextException(org.apache.calcite.runtime.CalciteContextException) ExecutionPlan(herddb.model.ExecutionPlan) GetStatement(herddb.model.commands.GetStatement) ScanStatement(herddb.model.commands.ScanStatement)

Aggregations

StatementExecutionException (herddb.model.StatementExecutionException)3 SQLPlannedOperationStatement (herddb.model.commands.SQLPlannedOperationStatement)3 TransactionContext (herddb.model.TransactionContext)2 ScanStatement (herddb.model.commands.ScanStatement)2 HerdDBInternalException (herddb.core.HerdDBInternalException)1 MetadataStorageManagerException (herddb.metadata.MetadataStorageManagerException)1 DDLStatementExecutionResult (herddb.model.DDLStatementExecutionResult)1 DataScanner (herddb.model.DataScanner)1 DataScannerException (herddb.model.DataScannerException)1 DuplicatePrimaryKeyException (herddb.model.DuplicatePrimaryKeyException)1 ExecutionPlan (herddb.model.ExecutionPlan)1 NotLeaderException (herddb.model.NotLeaderException)1 ScanResult (herddb.model.ScanResult)1 StatementExecutionResult (herddb.model.StatementExecutionResult)1 Table (herddb.model.Table)1 TableAwareStatement (herddb.model.TableAwareStatement)1 Transaction (herddb.model.Transaction)1 AlterTableStatement (herddb.model.commands.AlterTableStatement)1 BeginTransactionStatement (herddb.model.commands.BeginTransactionStatement)1 CommitTransactionStatement (herddb.model.commands.CommitTransactionStatement)1