use of herddb.model.ExecutionPlan in project herddb by diennea.
the class CompiledInExpression method validate.
@Override
public void validate(StatementEvaluationContext context) throws StatementExecutionException {
if (this.left != null) {
left.validate(context);
}
if (this.inExpressions != null) {
this.inExpressions.forEach(s -> s.validate(context));
}
if (inSubSelectPlain != null) {
ExecutionPlan plan = context.compileSubplan(inSubSelectPlain);
plan.validateContext(context);
}
}
use of herddb.model.ExecutionPlan 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 {
ensureDefaultTableSpaceBootedLocally(defaultTableSpace);
/* Strips out leading comments */
int idx = SQLUtils.findQueryStart(query);
if (idx != -1) {
query = query.substring(idx);
}
if (parameters == null) {
parameters = Collections.emptyList();
}
String cacheKey = "scan:" + scan + ",defaultTableSpace:" + defaultTableSpace + ",query:" + query + ",returnValues:" + returnValues + ",maxRows:" + maxRows;
boolean forceAcquireWriteLock;
if (// this looks very hacky
query.endsWith(" FOR UPDATE") && query.substring(0, 6).toLowerCase().equals("select")) {
forceAcquireWriteLock = true;
query = query.substring(0, query.length() - " FOR UPDATE".length());
} else {
forceAcquireWriteLock = false;
}
if (allowCache) {
ExecutionPlan cached = cache.get(cacheKey);
if (cached != null) {
return new TranslatedQuery(cached, new SQLStatementEvaluationContext(query, parameters, forceAcquireWriteLock, false));
}
}
if (isDDL(query)) {
query = JSQLParserPlanner.rewriteExecuteSyntax(query);
return fallback.translate(defaultTableSpace, query, parameters, scan, allowCache, returnValues, maxRows);
}
if (query.startsWith(TABLE_CONSISTENCY_COMMAND)) {
query = JSQLParserPlanner.rewriteExecuteSyntax(query);
return fallback.translate(defaultTableSpace, query, parameters, scan, allowCache, returnValues, maxRows);
}
if (query.startsWith(TABLESPACE_CONSISTENCY_COMMAND)) {
query = JSQLParserPlanner.rewriteExecuteSyntax(query);
return fallback.translate(defaultTableSpace, query, parameters, scan, allowCache, returnValues, maxRows);
}
if (!isCachable(query)) {
allowCache = false;
}
try {
if (query.startsWith("EXPLAIN ")) {
query = query.substring("EXPLAIN ".length());
PlannerResult plan = runPlanner(defaultTableSpace, query);
boolean upsert = detectUpsert(plan);
PlannerOp finalPlan = convertRelNode(plan.topNode, plan.originalRowType, returnValues, upsert).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", ColumnTypes.NOTNULL_STRING), new ConstantExpression(query, ColumnTypes.NOTNULL_STRING)), java.util.Arrays.asList(new ConstantExpression("logicalplan", ColumnTypes.NOTNULL_STRING), new ConstantExpression(RelOptUtil.dumpPlan("", plan.logicalPlan, SqlExplainFormat.TEXT, SqlExplainLevel.ALL_ATTRIBUTES), ColumnTypes.NOTNULL_STRING)), java.util.Arrays.asList(new ConstantExpression("plan", ColumnTypes.NOTNULL_STRING), new ConstantExpression(RelOptUtil.dumpPlan("", plan.topNode, SqlExplainFormat.TEXT, SqlExplainLevel.ALL_ATTRIBUTES), ColumnTypes.NOTNULL_STRING)), java.util.Arrays.asList(new ConstantExpression("finalplan", ColumnTypes.NOTNULL_STRING), new ConstantExpression(finalPlan + "", ColumnTypes.NOTNULL_STRING))));
ExecutionPlan executionPlan = ExecutionPlan.simple(new SQLPlannedOperationStatement(values), values);
return new TranslatedQuery(executionPlan, new SQLStatementEvaluationContext(query, parameters, false, false));
}
if (query.startsWith("SHOW")) {
return calculateShowCreateTable(query, defaultTableSpace, parameters, manager);
}
PlannerResult plan = runPlanner(defaultTableSpace, query);
boolean upsert = detectUpsert(plan);
SQLPlannedOperationStatement sqlPlannedOperationStatement = new SQLPlannedOperationStatement(convertRelNode(plan.topNode, plan.originalRowType, returnValues, upsert).optimize());
if (LOG.isLoggable(DUMP_QUERY_LEVEL)) {
LOG.log(DUMP_QUERY_LEVEL, "Query: {0} --HerdDB Plan\n{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 = IndexUtils.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, forceAcquireWriteLock, false));
}
}
if (maxRows > 0) {
PlannerOp op = new LimitOp(sqlPlannedOperationStatement.getRootOp(), new ConstantExpression(maxRows, ColumnTypes.NOTNULL_LONG), new ConstantExpression(0, ColumnTypes.NOTNULL_LONG)).optimize();
sqlPlannedOperationStatement = new SQLPlannedOperationStatement(op);
}
PlannerOp rootOp = sqlPlannedOperationStatement.getRootOp();
ExecutionPlan executionPlan;
if (rootOp.isSimpleStatementWrapper()) {
executionPlan = ExecutionPlan.simple(rootOp.unwrap(herddb.model.Statement.class), rootOp);
} else {
executionPlan = ExecutionPlan.simple(sqlPlannedOperationStatement, rootOp);
}
if (allowCache) {
cache.put(cacheKey, executionPlan);
}
return new TranslatedQuery(executionPlan, new SQLStatementEvaluationContext(query, parameters, forceAcquireWriteLock, false));
} 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: ", ""), ex);
} catch (MetadataStorageManagerException ex) {
LOG.log(Level.INFO, "Error while parsing '" + query + "'", ex);
throw new StatementExecutionException(ex);
}
}
use of herddb.model.ExecutionPlan in project herddb by diennea.
the class ShowCreateTableCalculator method calculateShowCreateTable.
public static TranslatedQuery calculateShowCreateTable(String query, String defaultTablespace, List<Object> parameters, DBManager manager) {
String[] items = { "SHOW", "CREATE", "TABLE" };
if (Arrays.stream(items).allMatch(query::contains)) {
query = query.substring(Arrays.stream(items).collect(Collectors.joining(" ")).length()).trim();
String tableSpace = defaultTablespace;
String tableName;
boolean showCreateIndex = query.contains("WITH INDEXES");
if (showCreateIndex) {
query = query.substring(0, query.indexOf("WITH INDEXES"));
}
if (query.contains(".")) {
String[] tokens = query.split("\\.");
tableSpace = tokens[0].trim();
tableName = tokens[1].trim();
} else {
tableName = query.trim();
}
tableName = tableName.toLowerCase();
TableSpaceManager tableSpaceManager = manager.getTableSpaceManager(tableSpace);
if (tableSpaceManager == null) {
throw new TableSpaceDoesNotExistException(String.format("Tablespace %s does not exist.", tableSpace));
}
AbstractTableManager tableManager = tableSpaceManager.getTableManager(tableName);
if (tableManager == null || tableManager.getCreatedInTransaction() > 0) {
throw new TableDoesNotExistException(String.format("Table %s does not exist.", tableName));
}
String showCreateResult = calculate(showCreateIndex, tableName, tableSpace, tableManager);
ValuesOp values = new ValuesOp(manager.getNodeId(), new String[] { "tabledef" }, new Column[] { column("tabledef", ColumnTypes.STRING) }, Arrays.asList(Arrays.asList(new ConstantExpression(showCreateResult, ColumnTypes.NOTNULL_STRING))));
ExecutionPlan executionPlan = ExecutionPlan.simple(new SQLPlannedOperationStatement(values), values);
return new TranslatedQuery(executionPlan, new SQLStatementEvaluationContext(query, parameters, false, false));
} else {
throw new StatementExecutionException(String.format("Incorrect Syntax for SHOW CREATE TABLE tablespace.tablename"));
}
}
Aggregations