use of io.crate.analyze.WhereClause 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.WhereClause 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.WhereClause in project crate by crate.
the class LuceneQueryBuilderTest method testWhereRefEqNullWithDifferentTypes.
@Test
public void testWhereRefEqNullWithDifferentTypes() throws Exception {
for (DataType type : DataTypes.PRIMITIVE_TYPES) {
DocTableInfo tableInfo = TestingTableInfo.builder(new TableIdent(null, "test_primitive"), null).add("x", type).build();
TableRelation tableRelation = new TableRelation(tableInfo);
Map<QualifiedName, AnalyzedRelation> tableSources = ImmutableMap.of(new QualifiedName(tableInfo.ident().name()), tableRelation);
SqlExpressions sqlExpressions = new SqlExpressions(tableSources, tableRelation, new Object[] { null }, SessionContext.SYSTEM_SESSION);
Query query = convert(new WhereClause(sqlExpressions.normalize(sqlExpressions.asSymbol("x = ?"))));
// must always become a MatchNoDocsQuery (empty BooleanQuery)
// string: term query with null would cause NPE
// int/numeric: rangeQuery from null to null would match all
// bool: term would match false too because of the condition in the eq query builder
assertThat(query, instanceOf(BooleanQuery.class));
assertThat(((BooleanQuery) query).clauses().size(), is(0));
}
}
use of io.crate.analyze.WhereClause in project crate by crate.
the class NodeStatsCollectSourceTest method filterNodes.
private List<DiscoveryNode> filterNodes(String where) throws NoSuchFieldException, IllegalAccessException {
// build where clause with id = ?
SysNodesTableInfo tableInfo = mock(SysNodesTableInfo.class);
when(tableInfo.ident()).thenReturn(new TableIdent("sys", "nodes"));
when(tableInfo.getReference(new ColumnIdent("id"))).thenReturn(new Reference(new ReferenceIdent(new TableIdent("sys", "nodes"), "id"), RowGranularity.DOC, DataTypes.STRING));
when(tableInfo.getReference(SysNodesTableInfo.Columns.NAME)).thenReturn(new Reference(new ReferenceIdent(SysNodesTableInfo.IDENT, SysNodesTableInfo.Columns.NAME), RowGranularity.DOC, DataTypes.STRING));
when(tableInfo.getReference(SysNodesTableInfo.Columns.HOSTNAME)).thenReturn(new Reference(new ReferenceIdent(SysNodesTableInfo.IDENT, SysNodesTableInfo.Columns.HOSTNAME), RowGranularity.DOC, DataTypes.STRING));
TableRelation tableRelation = new TableRelation(tableInfo);
Map<QualifiedName, AnalyzedRelation> tableSources = ImmutableMap.<QualifiedName, AnalyzedRelation>of(new QualifiedName("sys.nodes"), tableRelation);
SqlExpressions sqlExpressions = new SqlExpressions(tableSources, tableRelation);
WhereClause whereClause = new WhereClause(sqlExpressions.normalize(sqlExpressions.asSymbol(where)));
List<DiscoveryNode> nodes = Lists.newArrayList(NodeStatsCollectSource.nodeIds(whereClause, discoveryNodes, getFunctions()));
Collections.sort(nodes, new Comparator<DiscoveryNode>() {
@Override
public int compare(DiscoveryNode o1, DiscoveryNode o2) {
return o1.getId().compareTo(o2.getId());
}
});
return nodes;
}
use of io.crate.analyze.WhereClause in project crate by crate.
the class WhereClauseAnalyzerTest method testPrimaryKeyAndVersion.
@Test
public void testPrimaryKeyAndVersion() throws Exception {
WhereClause whereClause = analyzeSelectWhere("select name from users where id = 2 and \"_version\" = 1");
assertThat(whereClause.docKeys().get().getOnlyKey(), isDocKey("2", 1L));
}
Aggregations