use of io.crate.analyze.symbol.Literal in project crate by crate.
the class WhereClauseAnalyzer method tieBreakPartitionQueries.
private static WhereClause tieBreakPartitionQueries(EvaluatingNormalizer normalizer, Map<Symbol, List<Literal>> queryPartitionMap, WhereClause whereClause, TransactionContext transactionContext) 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<>();
SymbolToTrueVisitor symbolToTrueVisitor = new SymbolToTrueVisitor();
for (Map.Entry<Symbol, List<Literal>> entry : queryPartitionMap.entrySet()) {
Symbol query = entry.getKey();
List<Literal> partitions = entry.getValue();
Symbol symbol = symbolToTrueVisitor.process(query, null);
Symbol normalized = normalizer.normalize(symbol, transactionContext);
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);
WhereClause where = new WhereClause(symbolListTuple.v1(), whereClause.docKeys().orElse(null), new ArrayList<String>(symbolListTuple.v2().size()));
where.partitions(symbolListTuple.v2());
return where;
}
throw new UnsupportedOperationException("logical conjunction of the conditions in the WHERE clause which " + "involve partitioned columns led to a query that can't be executed.");
}
use of io.crate.analyze.symbol.Literal in project crate by crate.
the class WhereClauseAnalyzer method resolvePartitions.
private static WhereClause resolvePartitions(WhereClause whereClause, DocTableInfo tableInfo, Functions functions, TransactionContext transactionContext) {
assert tableInfo.isPartitioned() : "table must be partitioned in order to resolve partitions";
assert whereClause.partitions().isEmpty() : "partitions must not be analyzed twice";
if (tableInfo.partitions().isEmpty()) {
// table is partitioned but has no data / no partitions
return WhereClause.NO_MATCH;
}
PartitionReferenceResolver partitionReferenceResolver = preparePartitionResolver(tableInfo.partitionedByColumns());
EvaluatingNormalizer normalizer = new EvaluatingNormalizer(functions, RowGranularity.PARTITION, ReplaceMode.COPY, partitionReferenceResolver, null);
Symbol normalized;
Map<Symbol, List<Literal>> queryPartitionMap = new HashMap<>();
for (PartitionName partitionName : tableInfo.partitions()) {
for (PartitionExpression partitionExpression : partitionReferenceResolver.expressions()) {
partitionExpression.setNextRow(partitionName);
}
normalized = normalizer.normalize(whereClause.query(), transactionContext);
assert normalized != null : "normalizing a query must not return null";
if (normalized.equals(whereClause.query())) {
// no partition columns inside the where clause
return whereClause;
}
boolean canMatch = WhereClause.canMatch(normalized);
if (canMatch) {
List<Literal> partitions = queryPartitionMap.get(normalized);
if (partitions == null) {
partitions = new ArrayList<>();
queryPartitionMap.put(normalized, partitions);
}
partitions.add(Literal.of(partitionName.asIndexName()));
}
}
if (queryPartitionMap.size() == 1) {
Map.Entry<Symbol, List<Literal>> entry = Iterables.getOnlyElement(queryPartitionMap.entrySet());
whereClause = new WhereClause(entry.getKey(), whereClause.docKeys().orElse(null), new ArrayList<String>(entry.getValue().size()));
whereClause.partitions(entry.getValue());
return whereClause;
} else if (queryPartitionMap.size() > 0) {
return tieBreakPartitionQueries(normalizer, queryPartitionMap, whereClause, transactionContext);
} else {
return WhereClause.NO_MATCH;
}
}
use of io.crate.analyze.symbol.Literal in project crate by crate.
the class RelationAnalyzer method symbolFromSelectOutputReferenceOrExpression.
/**
* <h2>resolve expression by also taking alias and ordinal-reference into account</h2>
* <p>
* <p>
* in group by or order by clauses it is possible to reference anything in the
* select list by using a number or alias
* </p>
* <p>
* These are allowed:
* <pre>
* select name as n ... order by n
* select name ... order by 1
* select name ... order by other_column
* </pre>
*/
private Symbol symbolFromSelectOutputReferenceOrExpression(Expression expression, SelectAnalysis selectAnalysis, String clause, ExpressionAnalyzer expressionAnalyzer, ExpressionAnalysisContext expressionAnalysisContext) {
Symbol symbol;
if (expression instanceof QualifiedNameReference) {
List<String> parts = ((QualifiedNameReference) expression).getName().getParts();
if (parts.size() == 1) {
symbol = getOneOrAmbiguous(selectAnalysis.outputMultiMap(), Iterables.getOnlyElement(parts));
if (symbol != null) {
return symbol;
}
}
}
symbol = expressionAnalyzer.convert(expression, expressionAnalysisContext);
if (symbol.symbolType().isValueSymbol()) {
Literal longLiteral;
try {
longLiteral = io.crate.analyze.symbol.Literal.convert(symbol, DataTypes.LONG);
} catch (ClassCastException | IllegalArgumentException e) {
throw new UnsupportedOperationException(String.format(Locale.ENGLISH, "Cannot use %s in %s clause", SymbolPrinter.INSTANCE.printSimple(symbol), clause));
}
symbol = ordinalOutputReference(selectAnalysis.outputSymbols(), longLiteral, clause);
}
return symbol;
}
use of io.crate.analyze.symbol.Literal in project crate by crate.
the class AnyLikeOperatorTest method anyLike.
private Boolean anyLike(String pattern, String... expressions) {
Literal patternLiteral = Literal.of(pattern);
Object[] value = new Object[expressions.length];
for (int i = 0; i < expressions.length; i++) {
value[i] = expressions[i] == null ? null : new BytesRef(expressions[i]);
}
Literal valuesLiteral = Literal.of(new ArrayType(DataTypes.STRING), value);
AnyLikeOperator impl = (AnyLikeOperator) new AnyLikeOperator.AnyLikeResolver().getForTypes(Arrays.asList(DataTypes.STRING, valuesLiteral.valueType()));
return impl.evaluate(patternLiteral, valuesLiteral);
}
use of io.crate.analyze.symbol.Literal in project crate by crate.
the class AnyLikeOperatorTest method testNegateLike.
@Test
public void testNegateLike() throws Exception {
Literal patternLiteral = Literal.of("A");
Literal valuesLiteral = Literal.of(new ArrayType(DataTypes.STRING), new Object[] { new BytesRef("A"), new BytesRef("B") });
FunctionImplementation impl = new AnyLikeOperator.AnyLikeResolver().getForTypes(Arrays.asList(DataTypes.STRING, valuesLiteral.valueType()));
Function anyLikeFunction = new Function(impl.info(), Arrays.<Symbol>asList(patternLiteral, valuesLiteral));
Input<Boolean> normalized = (Input<Boolean>) impl.normalizeSymbol(anyLikeFunction, new TransactionContext(SessionContext.SYSTEM_SESSION));
assertThat(normalized.value(), is(true));
assertThat(new NotPredicate().evaluate(normalized), is(false));
}
Aggregations