Search in sources :

Example 1 with WhereClause

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.");
}
Also used : Symbol(io.crate.analyze.symbol.Symbol) WhereClause(io.crate.analyze.WhereClause) SymbolToTrueVisitor(io.crate.analyze.SymbolToTrueVisitor) Literal(io.crate.analyze.symbol.Literal) ImmutableList(com.google.common.collect.ImmutableList) Tuple(org.elasticsearch.common.collect.Tuple)

Example 2 with WhereClause

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;
    }
}
Also used : EvaluatingNormalizer(io.crate.analyze.EvaluatingNormalizer) Symbol(io.crate.analyze.symbol.Symbol) WhereClause(io.crate.analyze.WhereClause) PartitionExpression(io.crate.operation.reference.partitioned.PartitionExpression) Literal(io.crate.analyze.symbol.Literal) ImmutableList(com.google.common.collect.ImmutableList)

Example 3 with WhereClause

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));
    }
}
Also used : DocTableInfo(io.crate.metadata.doc.DocTableInfo) TermsQuery(org.apache.lucene.queries.TermsQuery) CrateRegexQuery(io.crate.lucene.match.CrateRegexQuery) IntersectsPrefixTreeQuery(org.apache.lucene.spatial.prefix.IntersectsPrefixTreeQuery) WithinPrefixTreeQuery(org.apache.lucene.spatial.prefix.WithinPrefixTreeQuery) QualifiedName(io.crate.sql.tree.QualifiedName) WhereClause(io.crate.analyze.WhereClause) DataType(io.crate.types.DataType) TableIdent(io.crate.metadata.TableIdent) AnalyzedRelation(io.crate.analyze.relations.AnalyzedRelation) SqlExpressions(io.crate.testing.SqlExpressions) TableRelation(io.crate.analyze.relations.TableRelation) Test(org.junit.Test) CrateUnitTest(io.crate.test.integration.CrateUnitTest)

Example 4 with WhereClause

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;
}
Also used : DiscoveryNode(org.elasticsearch.cluster.node.DiscoveryNode) SysNodesTableInfo(io.crate.metadata.sys.SysNodesTableInfo) QualifiedName(io.crate.sql.tree.QualifiedName) WhereClause(io.crate.analyze.WhereClause) AnalyzedRelation(io.crate.analyze.relations.AnalyzedRelation) TableRelation(io.crate.analyze.relations.TableRelation) SqlExpressions(io.crate.testing.SqlExpressions)

Example 5 with WhereClause

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));
}
Also used : WhereClause(io.crate.analyze.WhereClause) Test(org.junit.Test) CrateUnitTest(io.crate.test.integration.CrateUnitTest)

Aggregations

WhereClause (io.crate.analyze.WhereClause)76 Test (org.junit.Test)52 CrateUnitTest (io.crate.test.integration.CrateUnitTest)30 CrateDummyClusterServiceUnitTest (io.crate.test.integration.CrateDummyClusterServiceUnitTest)17 Symbol (io.crate.analyze.symbol.Symbol)10 PartitionName (io.crate.metadata.PartitionName)8 RelationName (io.crate.metadata.RelationName)7 TableInfo (io.crate.metadata.table.TableInfo)7 Reference (io.crate.metadata.Reference)6 DocTableRelation (io.crate.analyze.relations.DocTableRelation)5 Symbol (io.crate.expression.symbol.Symbol)5 DocTableInfo (io.crate.metadata.doc.DocTableInfo)5 SqlExpressions (io.crate.testing.SqlExpressions)5 AnalyzedRelation (io.crate.analyze.relations.AnalyzedRelation)4 Routing (io.crate.metadata.Routing)4 QualifiedName (io.crate.sql.tree.QualifiedName)4 ImmutableList (com.google.common.collect.ImmutableList)3 OrderBy (io.crate.analyze.OrderBy)3 Function (io.crate.analyze.symbol.Function)3 Bucket (io.crate.data.Bucket)3