use of io.crate.common.collections.Lists2.mapTail 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.common.collections.Lists2.mapTail in project crate by crate.
the class RestoreSnapshotPlan method bind.
@VisibleForTesting
public static BoundRestoreSnapshot bind(AnalyzedRestoreSnapshot restoreSnapshot, CoordinatorTxnCtx txnCtx, NodeContext nodeCtx, Row parameters, SubQueryResults subQueryResults, Schemas schemas) {
Function<? super Symbol, Object> eval = x -> SymbolEvaluator.evaluate(txnCtx, nodeCtx, x, parameters, subQueryResults);
Settings settings = GenericPropertiesConverter.genericPropertiesToSettings(restoreSnapshot.properties().map(eval), SnapshotSettings.SETTINGS);
HashSet<BoundRestoreSnapshot.RestoreTableInfo> restoreTables = new HashSet<>(restoreSnapshot.tables().size());
for (Table<Symbol> table : restoreSnapshot.tables()) {
var relationName = RelationName.of(table.getName(), txnCtx.sessionContext().searchPath().currentSchema());
try {
DocTableInfo docTableInfo = schemas.getTableInfo(relationName, Operation.RESTORE_SNAPSHOT);
if (table.partitionProperties().isEmpty()) {
throw new RelationAlreadyExists(relationName);
}
var partitionName = toPartitionName(docTableInfo, Lists2.map(table.partitionProperties(), x -> x.map(eval)));
if (docTableInfo.partitions().contains(partitionName)) {
throw new PartitionAlreadyExistsException(partitionName);
}
restoreTables.add(new BoundRestoreSnapshot.RestoreTableInfo(relationName, partitionName));
} catch (RelationUnknown | SchemaUnknownException e) {
if (table.partitionProperties().isEmpty()) {
restoreTables.add(new BoundRestoreSnapshot.RestoreTableInfo(relationName, null));
} else {
var partitionName = toPartitionName(relationName, Lists2.map(table.partitionProperties(), x -> x.map(eval)));
restoreTables.add(new BoundRestoreSnapshot.RestoreTableInfo(relationName, partitionName));
}
}
}
return new BoundRestoreSnapshot(restoreSnapshot.repository(), restoreSnapshot.snapshot(), restoreTables, restoreSnapshot.includeTables(), restoreSnapshot.includeCustomMetadata(), restoreSnapshot.customMetadataTypes(), restoreSnapshot.includeGlobalSettings(), restoreSnapshot.globalSettings(), settings);
}
use of io.crate.common.collections.Lists2.mapTail in project crate by crate.
the class CopyAnalyzer method analyzeCopyTo.
AnalyzedCopyTo analyzeCopyTo(CopyTo<Expression> node, ParamTypeHints paramTypeHints, CoordinatorTxnCtx txnCtx) {
if (!node.directoryUri()) {
throw new UnsupportedOperationException("Using COPY TO without specifying a DIRECTORY is not supported");
}
TableInfo tableInfo = schemas.resolveTableInfo(node.table().getName(), Operation.COPY_TO, txnCtx.sessionContext().sessionUser(), txnCtx.sessionContext().searchPath());
Operation.blockedRaiseException(tableInfo, Operation.READ);
DocTableRelation tableRelation = new DocTableRelation((DocTableInfo) tableInfo);
EvaluatingNormalizer normalizer = new EvaluatingNormalizer(nodeCtx, RowGranularity.CLUSTER, null, tableRelation);
var exprCtx = new ExpressionAnalysisContext(txnCtx.sessionContext());
var expressionAnalyzer = new ExpressionAnalyzer(txnCtx, nodeCtx, paramTypeHints, new NameFieldProvider(tableRelation), null);
var exprAnalyzerWithFieldsAsString = new ExpressionAnalyzer(txnCtx, nodeCtx, paramTypeHints, FieldProvider.FIELDS_AS_LITERAL, null);
var uri = expressionAnalyzer.convert(node.targetUri(), exprCtx);
var table = node.table().map(x -> exprAnalyzerWithFieldsAsString.convert(x, exprCtx));
var properties = node.properties().map(x -> expressionAnalyzer.convert(x, exprCtx));
var columns = Lists2.map(node.columns(), c -> normalizer.normalize(expressionAnalyzer.convert(c, exprCtx), txnCtx));
var whereClause = node.whereClause().map(w -> normalizer.normalize(expressionAnalyzer.convert(w, exprCtx), txnCtx)).orElse(null);
return new AnalyzedCopyTo(tableInfo, table, normalizer.normalize(uri, txnCtx), properties, columns, whereClause);
}
use of io.crate.common.collections.Lists2.mapTail in project crate by crate.
the class RelationAnalyzer method visitValues.
@Override
public AnalyzedRelation visitValues(Values values, StatementAnalysisContext context) {
var expressionAnalyzer = new ExpressionAnalyzer(context.transactionContext(), nodeCtx, context.paramTyeHints(), FieldProvider.UNSUPPORTED, new SubqueryAnalyzer(this, context));
var expressionAnalysisContext = new ExpressionAnalysisContext(context.sessionContext());
// prevent normalization of the values array, otherwise the value literals are converted to an array literal
// and a special per-value-literal casting logic won't be executed (e.g. FloatLiteral.cast())
expressionAnalysisContext.allowEagerNormalize(false);
java.util.function.Function<Expression, Symbol> expressionToSymbol = e -> expressionAnalyzer.convert(e, expressionAnalysisContext);
// There is a first pass to convert expressions from row oriented format:
// `[[1, a], [2, b]]` to columns `[[1, 2], [a, b]]`
//
// At the same time we determine the column type with the highest precedence,
// so that we don't fail with slight type miss-matches (long vs. int)
List<ValuesList> rows = values.rows();
assert rows.size() > 0 : "Parser grammar enforces at least 1 row";
ValuesList firstRow = rows.get(0);
int numColumns = firstRow.values().size();
ArrayList<List<Symbol>> columns = new ArrayList<>();
ArrayList<DataType<?>> targetTypes = new ArrayList<>(numColumns);
var parentOutputColumns = context.parentOutputColumns();
for (int c = 0; c < numColumns; c++) {
ArrayList<Symbol> columnValues = new ArrayList<>();
DataType<?> targetType;
boolean usePrecedence = true;
if (parentOutputColumns.size() > c) {
targetType = parentOutputColumns.get(c).valueType();
usePrecedence = false;
} else {
targetType = DataTypes.UNDEFINED;
}
for (int r = 0; r < rows.size(); r++) {
List<Expression> row = rows.get(r).values();
if (row.size() != numColumns) {
throw new IllegalArgumentException("VALUES lists must all be the same length. " + "Found row with " + numColumns + " items and another with " + columns.size() + " items");
}
Symbol cell = expressionToSymbol.apply(row.get(c));
columnValues.add(cell);
var cellType = cell.valueType();
if (// skip first cell, we don't have to check for self-conversion
r > 0 && !cellType.isConvertableTo(targetType, false) && targetType.id() != DataTypes.UNDEFINED.id()) {
throw new IllegalArgumentException("The types of the columns within VALUES lists must match. " + "Found `" + targetType + "` and `" + cellType + "` at position: " + c);
}
if (usePrecedence && cellType.precedes(targetType)) {
targetType = cellType;
} else if (targetType == DataTypes.UNDEFINED) {
targetType = cellType;
}
}
targetTypes.add(targetType);
columns.add(columnValues);
}
var normalizer = EvaluatingNormalizer.functionOnlyNormalizer(nodeCtx, f -> f.isDeterministic());
ArrayList<Symbol> arrays = new ArrayList<>(columns.size());
for (int c = 0; c < numColumns; c++) {
DataType<?> targetType = targetTypes.get(c);
ArrayType<?> arrayType = new ArrayType<>(targetType);
List<Symbol> columnValues = Lists2.map(columns.get(c), s -> normalizer.normalize(s.cast(targetType), context.transactionContext()));
arrays.add(new Function(ArrayFunction.SIGNATURE, columnValues, arrayType));
}
FunctionImplementation implementation = nodeCtx.functions().getQualified(ValuesFunction.SIGNATURE, Symbols.typeView(arrays), RowType.EMPTY);
Function function = new Function(implementation.signature(), arrays, RowType.EMPTY);
TableFunctionImplementation<?> tableFunc = TableFunctionFactory.from(implementation);
TableFunctionRelation relation = new TableFunctionRelation(tableFunc, function);
context.startRelation();
context.currentRelationContext().addSourceRelation(relation);
context.endRelation();
return relation;
}
use of io.crate.common.collections.Lists2.mapTail in project crate by crate.
the class WhereClauseAnalyzer method tieBreakPartitionQueries.
@Nullable
private static PartitionResult tieBreakPartitionQueries(EvaluatingNormalizer normalizer, Map<Symbol, List<Literal>> queryPartitionMap, CoordinatorTxnCtx coordinatorTxnCtx) throws UnsupportedOperationException {
/*
* Got multiple normalized queries which all could match.
* This might be the case if one partition resolved to null
*
* e.g.
*
* p = 1 and x = 2
*
* might lead to
*
* null and x = 2
* true and x = 2
*
* At this point it is unknown if they really match.
* In order to figure out if they could potentially match all conditions involving references are now set to true
*
* null and true -> can't match
* true and true -> can match, can use this query + partition
*
* If there is still more than 1 query that can match it's not possible to execute the query :(
*/
List<Tuple<Symbol, List<Literal>>> canMatch = new ArrayList<>();
for (Map.Entry<Symbol, List<Literal>> entry : queryPartitionMap.entrySet()) {
Symbol query = entry.getKey();
List<Literal> partitions = entry.getValue();
Symbol normalized = normalizer.normalize(ScalarsAndRefsToTrue.rewrite(query), coordinatorTxnCtx);
assert normalized instanceof Literal : "after normalization and replacing all reference occurrences with true there must only be a literal left";
Object value = ((Literal) normalized).value();
if (value != null && (Boolean) value) {
canMatch.add(new Tuple<>(query, partitions));
}
}
if (canMatch.size() == 1) {
Tuple<Symbol, List<Literal>> symbolListTuple = canMatch.get(0);
return new PartitionResult(symbolListTuple.v1(), Lists2.map(symbolListTuple.v2(), literal -> nullOrString(literal.value())));
}
return null;
}
Aggregations