use of io.crate.expression.symbol.Function in project crate by crate.
the class NotPredicate method toQuery.
@Override
public Query toQuery(Function input, LuceneQueryBuilder.Context context) {
assert input != null : "function must not be null";
assert input.arguments().size() == 1 : "function's number of arguments must be 1";
/**
* not null -> null -> no match
* not true -> false -> no match
* not false -> true -> match
*/
// handles not true / not false
Symbol arg = input.arguments().get(0);
// Optimize `NOT (<ref> IS NULL)`
if (arg instanceof Function && ((Function) arg).name().equals(IsNullPredicate.NAME)) {
Function innerFunction = (Function) arg;
if (innerFunction.arguments().size() == 1 && innerFunction.arguments().get(0) instanceof Reference) {
Reference ref = (Reference) innerFunction.arguments().get(0);
// Ignored objects have no field names in the index, need function filter fallback
if (ref.columnPolicy() == ColumnPolicy.IGNORED) {
return null;
}
return IsNullPredicate.refExistsQuery(ref, context);
}
}
Query innerQuery = arg.accept(context.visitor(), context);
Query notX = Queries.not(innerQuery);
// not x = not x & x is not null
BooleanQuery.Builder builder = new BooleanQuery.Builder();
builder.add(notX, BooleanClause.Occur.MUST);
SymbolToNotNullContext ctx = new SymbolToNotNullContext();
arg.accept(INNER_VISITOR, ctx);
for (Reference reference : ctx.references()) {
if (reference.isNullable()) {
builder.add(IsNullPredicate.refExistsQuery(reference, context), BooleanClause.Occur.MUST);
}
}
if (ctx.hasStrictThreeValuedLogicFunction) {
Function isNullFunction = new Function(IsNullPredicate.SIGNATURE, Collections.singletonList(arg), DataTypes.BOOLEAN);
builder.add(Queries.not(LuceneQueryBuilder.genericFunctionFilter(isNullFunction, context)), BooleanClause.Occur.MUST);
}
return builder.build();
}
use of io.crate.expression.symbol.Function in project crate by crate.
the class HashAggregate method pruneOutputsExcept.
@Override
public LogicalPlan pruneOutputsExcept(TableStats tableStats, Collection<Symbol> outputsToKeep) {
ArrayList<Function> newAggregates = new ArrayList<>();
for (Symbol outputToKeep : outputsToKeep) {
SymbolVisitors.intersection(outputToKeep, aggregates, newAggregates::add);
}
LinkedHashSet<Symbol> toKeep = new LinkedHashSet<>();
for (Function newAggregate : newAggregates) {
SymbolVisitors.intersection(newAggregate, source.outputs(), toKeep::add);
}
LogicalPlan newSource = source.pruneOutputsExcept(tableStats, toKeep);
if (source == newSource && newAggregates == aggregates) {
return this;
}
return new HashAggregate(newSource, newAggregates);
}
use of io.crate.expression.symbol.Function in project crate by crate.
the class SwapCastsInComparisonOperators method apply.
@Override
public Symbol apply(Function operator, Captures captures, NodeContext nodeCtx, Symbol parentNode) {
var literal = operator.arguments().get(1);
var castFunction = captures.get(castCapture);
var reference = castFunction.arguments().get(0);
DataType<?> targetType = reference.valueType();
Symbol castedLiteral = literal.cast(targetType, CastFunctionResolver.getCastMode(castFunction.name()));
// and re-add casts if there is a text/varchar(n) missmatch.
return new Function(operator.signature(), List.of(reference, castedLiteral), operator.valueType());
}
use of io.crate.expression.symbol.Function in project crate by crate.
the class InputColumns method tryCreateSubscriptOnRoot.
@Nullable
private static Symbol tryCreateSubscriptOnRoot(Symbol symbol, ColumnIdent column, HashMap<Symbol, InputColumn> inputs) {
if (column.isTopLevel()) {
return null;
}
ColumnIdent root = column.getRoot();
InputColumn rootIC = lookupValueByColumn(inputs, root);
if (rootIC == null) {
return symbol;
}
DataType<?> returnType = symbol.valueType();
List<String> path = column.path();
List<Symbol> arguments = mapTail(rootIC, path, Literal::of);
return new Function(SubscriptObjectFunction.SIGNATURE, arguments, returnType);
}
use of io.crate.expression.symbol.Function in project crate by crate.
the class SplitPointsBuilder method create.
public static SplitPoints create(QueriedSelectRelation relation) {
Context context = new Context();
INSTANCE.process(relation.outputs(), context);
OrderBy orderBy = relation.orderBy();
if (orderBy != null) {
INSTANCE.process(orderBy.orderBySymbols(), context);
}
Symbol having = relation.having();
if (having != null) {
having.accept(INSTANCE, context);
}
LinkedHashSet<Symbol> toCollect = new LinkedHashSet<>();
for (Function tableFunction : context.tableFunctions) {
toCollect.addAll(extractColumns(tableFunction.arguments()));
}
for (Function aggregate : context.aggregates) {
toCollect.addAll(aggregate.arguments());
if (aggregate.filter() != null) {
toCollect.add(aggregate.filter());
}
}
for (WindowFunction windowFunction : context.windowFunctions) {
toCollect.addAll(extractColumns(windowFunction.arguments()));
if (windowFunction.filter() != null) {
toCollect.add(windowFunction.filter());
}
INSTANCE.process(windowFunction.windowDefinition().partitions(), context);
OrderBy windowOrderBy = windowFunction.windowDefinition().orderBy();
if (windowOrderBy != null) {
INSTANCE.process(windowOrderBy.orderBySymbols(), context);
}
}
// group-by symbols must be processed on a dedicated context to be able extract table functions which must
// be processed *below* a grouping operator
var groupByContext = new Context();
if (relation.groupBy().isEmpty() == false) {
INSTANCE.process(relation.groupBy(), groupByContext);
for (Function tableFunction : groupByContext.tableFunctions) {
toCollect.addAll(extractColumns(tableFunction.arguments()));
}
toCollect.addAll(groupByContext.standalone);
context.tableFunctions.removeAll(groupByContext.tableFunctions);
} else if (context.aggregates.isEmpty() && relation.groupBy().isEmpty()) {
toCollect.addAll(context.standalone);
}
return new SplitPoints(new ArrayList<>(toCollect), context.aggregates, context.tableFunctions, groupByContext.tableFunctions, context.windowFunctions);
}
Aggregations