use of io.crate.analyze.AnalyzedStatement in project crate by crate.
the class BatchPortalTest method testEachStatementReceivesCorrectParams.
@Test
public void testEachStatementReceivesCorrectParams() throws Throwable {
SQLExecutor sqlExecutor = SQLExecutor.builder(clusterService).addTable("create table t1 (x int)").build();
Plan insertPlan = new Plan() {
@Override
public StatementType type() {
return StatementType.INSERT;
}
@Override
public void executeOrFail(DependencyCarrier executor, PlannerContext plannerContext, RowConsumer consumer, Row params, SubQueryResults subQueryResults) {
consumer.accept(InMemoryBatchIterator.of(params, null), null);
}
};
Planner planner = new Planner(Settings.EMPTY, clusterService, sqlExecutor.nodeCtx, new TableStats(), null, null, sqlExecutor.schemas(), new StubUserManager(), mock(SessionSettingRegistry.class)) {
@Override
public Plan plan(AnalyzedStatement analyzedStatement, PlannerContext plannerContext) {
return insertPlan;
}
};
DependencyCarrier executor = mock(DependencyCarrier.class, Answers.RETURNS_MOCKS);
Session session = new Session(sqlExecutor.nodeCtx, sqlExecutor.analyzer, planner, new JobsLogs(() -> false), false, executor, AccessControl.DISABLED, SessionContext.systemSessionContext());
session.parse("S_1", "insert into t1(x) values(1)", Collections.emptyList());
session.bind("Portal", "S_1", Collections.emptyList(), null);
final ArrayList<Object[]> s1Rows = new ArrayList<>();
session.execute("Portal", 0, new BaseResultReceiver() {
@Override
public void setNextRow(Row row) {
s1Rows.add(row.materialize());
}
});
session.parse("S_2", "insert into t1(x) values(?)", Collections.emptyList());
session.bind("Portal", "S_2", Collections.singletonList(2), null);
final ArrayList<Object[]> s2Rows = new ArrayList<>();
session.execute("Portal", 0, new BaseResultReceiver() {
@Override
public void setNextRow(Row row) {
s2Rows.add(row.materialize());
}
});
session.sync().get(5, TimeUnit.SECONDS);
assertThat(s1Rows, contains(emptyArray()));
assertThat(s2Rows, contains(arrayContaining(is(2))));
}
use of io.crate.analyze.AnalyzedStatement in project crate by crate.
the class Session method quickExec.
/**
* Execute a query in one step, avoiding the parse/bind/execute/sync procedure.
* Opposed to using parse/bind/execute/sync this method is thread-safe.
*
* @param parse A function to parse the statement; This can be used to cache the parsed statement.
* Use {@link #quickExec(String, ResultReceiver, Row)} to use the regular parser
*/
public void quickExec(String statement, Function<String, Statement> parse, ResultReceiver<?> resultReceiver, Row params) {
CoordinatorTxnCtx txnCtx = new CoordinatorTxnCtx(sessionContext);
Statement parsedStmt = parse.apply(statement);
AnalyzedStatement analyzedStatement = analyzer.analyze(parsedStmt, sessionContext, ParamTypeHints.EMPTY);
RoutingProvider routingProvider = new RoutingProvider(Randomness.get().nextInt(), planner.getAwarenessAttributes());
UUID jobId = UUIDs.dirtyUUID();
ClusterState clusterState = planner.currentClusterState();
PlannerContext plannerContext = new PlannerContext(clusterState, routingProvider, jobId, txnCtx, nodeCtx, 0, params);
Plan plan;
try {
plan = planner.plan(analyzedStatement, plannerContext);
} catch (Throwable t) {
jobsLogs.logPreExecutionFailure(jobId, statement, SQLExceptions.messageOf(t), sessionContext.sessionUser());
throw t;
}
StatementClassifier.Classification classification = StatementClassifier.classify(plan);
jobsLogs.logExecutionStart(jobId, statement, sessionContext.sessionUser(), classification);
JobsLogsUpdateListener jobsLogsUpdateListener = new JobsLogsUpdateListener(jobId, jobsLogs);
if (!analyzedStatement.isWriteOperation()) {
resultReceiver = new RetryOnFailureResultReceiver(executor.clusterService(), clusterState, // clusterState at the time of the index check is used
indexName -> clusterState.metadata().hasIndex(indexName), resultReceiver, jobId, (newJobId, retryResultReceiver) -> retryQuery(newJobId, analyzedStatement, routingProvider, new RowConsumerToResultReceiver(retryResultReceiver, 0, jobsLogsUpdateListener), params, txnCtx, nodeCtx));
}
RowConsumerToResultReceiver consumer = new RowConsumerToResultReceiver(resultReceiver, 0, jobsLogsUpdateListener);
plan.execute(executor, plannerContext, consumer, params, SubQueryResults.EMPTY);
}
use of io.crate.analyze.AnalyzedStatement in project crate by crate.
the class Session method describe.
public DescribeResult describe(char type, String portalOrStatement) {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("method=describe type={} portalOrStatement={}", type, portalOrStatement);
}
switch(type) {
case 'P':
Portal portal = getSafePortal(portalOrStatement);
var analyzedStmt = portal.analyzedStatement();
return new DescribeResult(portal.preparedStmt().parameterTypes(), analyzedStmt.outputs(), resolveTableFromSelect(analyzedStmt));
case 'S':
/*
* describe might be called without prior bind call.
*
* If the client uses server-side prepared statements this is usually the case.
*
* E.g. the statement is first prepared:
*
* parse stmtName=S_1 query=insert into t (x) values ($1) paramTypes=[integer]
* describe type=S portalOrStatement=S_1
* sync
*
* and then used with different bind calls:
*
* bind portalName= statementName=S_1 params=[0]
* describe type=P portalOrStatement=
* execute
*
* bind portalName= statementName=S_1 params=[1]
* describe type=P portalOrStatement=
* execute
*/
PreparedStmt preparedStmt = preparedStatements.get(portalOrStatement);
AnalyzedStatement analyzedStatement = preparedStmt.analyzedStatement();
return new DescribeResult(preparedStmt.parameterTypes(), analyzedStatement.outputs(), resolveTableFromSelect(analyzedStatement));
default:
throw new AssertionError("Unsupported type: " + type);
}
}
use of io.crate.analyze.AnalyzedStatement in project crate by crate.
the class Session method bulkExec.
private CompletableFuture<?> bulkExec(Statement statement, List<DeferredExecution> toExec) {
assert toExec.size() >= 1 : "Must have at least 1 deferred execution for bulk exec";
var jobId = UUIDs.dirtyUUID();
var routingProvider = new RoutingProvider(Randomness.get().nextInt(), planner.getAwarenessAttributes());
var clusterState = executor.clusterService().state();
var txnCtx = new CoordinatorTxnCtx(sessionContext);
var plannerContext = new PlannerContext(clusterState, routingProvider, jobId, txnCtx, nodeCtx, 0, null);
PreparedStmt firstPreparedStatement = toExec.get(0).portal().preparedStmt();
AnalyzedStatement analyzedStatement = firstPreparedStatement.analyzedStatement();
Plan plan;
try {
plan = planner.plan(analyzedStatement, plannerContext);
} catch (Throwable t) {
jobsLogs.logPreExecutionFailure(jobId, firstPreparedStatement.rawStatement(), SQLExceptions.messageOf(t), sessionContext.sessionUser());
throw t;
}
jobsLogs.logExecutionStart(jobId, firstPreparedStatement.rawStatement(), sessionContext.sessionUser(), StatementClassifier.classify(plan));
var bulkArgs = Lists2.map(toExec, x -> (Row) new RowN(x.portal().params().toArray()));
List<CompletableFuture<Long>> rowCounts = plan.executeBulk(executor, plannerContext, bulkArgs, SubQueryResults.EMPTY);
CompletableFuture<Void> allRowCounts = CompletableFuture.allOf(rowCounts.toArray(new CompletableFuture[0]));
List<CompletableFuture<?>> resultReceiverFutures = Lists2.map(toExec, x -> x.resultReceiver().completionFuture());
CompletableFuture<Void> allResultReceivers = CompletableFuture.allOf(resultReceiverFutures.toArray(new CompletableFuture[0]));
return allRowCounts.exceptionally(// swallow exception - failures are set per item in emitResults
t -> null).thenAccept(ignored -> emitRowCountsToResultReceivers(jobId, jobsLogs, toExec, rowCounts)).runAfterBoth(allResultReceivers, () -> {
});
}
use of io.crate.analyze.AnalyzedStatement in project crate by crate.
the class Session method analyze.
public void analyze(String statementName, Statement statement, List<DataType> paramTypes, @Nullable String query) {
AnalyzedStatement analyzedStatement;
DataType[] parameterTypes;
try {
analyzedStatement = analyzer.analyze(statement, sessionContext, new ParamTypeHints(paramTypes));
parameterTypes = parameterTypeExtractor.getParameterTypes(x -> Relations.traverseDeepSymbols(analyzedStatement, x));
} catch (Throwable t) {
jobsLogs.logPreExecutionFailure(UUIDs.dirtyUUID(), query == null ? statementName : query, SQLExceptions.messageOf(t), sessionContext.sessionUser());
throw t;
}
preparedStatements.put(statementName, new PreparedStmt(statement, analyzedStatement, query, parameterTypes));
}
Aggregations