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);
}
}
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;
}
}
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);
}
}
Aggregations