Search in sources :

Example 26 with QualifiedName

use of io.crate.sql.tree.QualifiedName in project crate by crate.

the class RelationSplitter method processWhere.

private void processWhere() {
    if (!querySpec.where().hasQuery()) {
        return;
    }
    Symbol query = querySpec.where().query();
    assert query != null : "query must not be null";
    QuerySplittingVisitor.Context context = QuerySplittingVisitor.INSTANCE.process(querySpec.where().query(), joinPairs);
    JoinConditionValidator.INSTANCE.process(context.query(), null);
    querySpec.where(new WhereClause(context.query()));
    for (Map.Entry<QualifiedName, Collection<Symbol>> entry : context.queries().asMap().entrySet()) {
        getSpec(entry.getKey()).where(new WhereClause(AndOperator.join(entry.getValue())));
    }
}
Also used : QualifiedName(io.crate.sql.tree.QualifiedName) WhereClause(io.crate.analyze.WhereClause)

Example 27 with QualifiedName

use of io.crate.sql.tree.QualifiedName in project crate by crate.

the class Rewriter method tryRewriteOuterToInnerJoin.

/**
     * Rewrite an Outer join to an inner join if possible.
     * <p>
     * Conditions on OUTER tables are not pushed down when a MultiSourceSelect is initially created because
     * the whereClause needs to be checked AFTER the join
     * (because if the join generates NULL rows the whereClause could become TRUE on those NULL rows)
     * <p>
     * See the following two examples where <code>t2</code> is the OUTER table:
     * <p>
     * <pre>
     *     select * from t1
     *          left join t2 on t1.t2_id = t2.id
     *     where
     *          coalesce(t2.x, 20) > 10   # becomes TRUE for null rows
     * </pre>
     * <p>
     * <p>
     * <p>
     * But if we know that the whereClause cannot possible become TRUE then we can push it down
     * (re-writing this into an inner join)
     * <p>
     * This is possible because all rows that are generated by the left-join would be removed again by the whereClause anyway.
     * <p>
     * <pre>
     *     select * from t1
     *          left join t2 on t1.t2_id = t2.id
     *     where
     *          t2.x > 10   # if t2.x is NULL this is always FALSE
     * </pre>
     */
public static void tryRewriteOuterToInnerJoin(EvaluatingNormalizer normalizer, JoinPair joinPair, List<Symbol> mssOutputSymbols, QuerySpec multiSourceQuerySpec, QualifiedName left, QualifiedName right, QuerySpec leftQuerySpec, QuerySpec rightQuerySpec) {
    assert left.equals(joinPair.left()) : "This JoinPair has a different left Qualified name: " + joinPair.left();
    assert right.equals(joinPair.right()) : "This JoinPair has a different left Qualified name: " + joinPair.right();
    JoinType joinType = joinPair.joinType();
    if (!joinType.isOuter()) {
        return;
    }
    WhereClause where = multiSourceQuerySpec.where();
    if (!where.hasQuery()) {
        return;
    }
    final Map<QualifiedName, QuerySpec> outerRelations = new HashMap<>(2);
    switch(joinType) {
        case LEFT:
            outerRelations.put(right, rightQuerySpec);
            break;
        case RIGHT:
            outerRelations.put(left, leftQuerySpec);
            break;
        case FULL:
            outerRelations.put(left, leftQuerySpec);
            outerRelations.put(right, rightQuerySpec);
            break;
    }
    Map<Set<QualifiedName>, Symbol> splitQueries = QuerySplitter.split(where.query());
    for (QualifiedName outerRelation : outerRelations.keySet()) {
        Symbol outerRelationQuery = splitQueries.remove(Sets.newHashSet(outerRelation));
        if (outerRelationQuery != null) {
            QuerySpec outerSpec = outerRelations.get(outerRelation);
            Symbol symbol = Symbols.replaceField(outerRelationQuery, new Function<Field, Symbol>() {

                @Nullable
                @Override
                public Symbol apply(@Nullable Field input) {
                    if (input != null && input.relation().getQualifiedName().equals(outerRelation)) {
                        return Literal.NULL;
                    }
                    return input;
                }
            });
            Symbol normalized = normalizer.normalize(symbol, null);
            if (WhereClause.canMatch(normalized)) {
                splitQueries.put(Sets.newHashSet(outerRelation), outerRelationQuery);
            } else {
                applyOuterJoinRewrite(joinPair, mssOutputSymbols, multiSourceQuerySpec, outerSpec, outerRelation, splitQueries, outerRelationQuery);
            }
        }
    }
}
Also used : QualifiedName(io.crate.sql.tree.QualifiedName) JoinType(io.crate.planner.node.dql.join.JoinType) Nullable(javax.annotation.Nullable)

Example 28 with QualifiedName

use of io.crate.sql.tree.QualifiedName in project crate by crate.

the class InternalCountOperationTest method testCount.

@Test
public void testCount() throws Exception {
    execute("create table t (name string) clustered into 1 shards with (number_of_replicas = 0)");
    ensureYellow();
    execute("insert into t (name) values ('Marvin'), ('Arthur'), ('Trillian')");
    execute("refresh table t");
    CountOperation countOperation = internalCluster().getDataNodeInstance(CountOperation.class);
    assertThat(countOperation.count("t", 0, WhereClause.MATCH_ALL), is(3L));
    Schemas schemas = internalCluster().getInstance(Schemas.class);
    TableInfo tableInfo = schemas.getTableInfo(new TableIdent(null, "t"));
    TableRelation tableRelation = new TableRelation(tableInfo);
    Map<QualifiedName, AnalyzedRelation> tableSources = ImmutableMap.<QualifiedName, AnalyzedRelation>of(new QualifiedName(tableInfo.ident().name()), tableRelation);
    SqlExpressions sqlExpressions = new SqlExpressions(tableSources, tableRelation);
    WhereClause whereClause = new WhereClause(sqlExpressions.normalize(sqlExpressions.asSymbol("name = 'Marvin'")));
    assertThat(countOperation.count("t", 0, whereClause), is(1L));
}
Also used : QualifiedName(io.crate.sql.tree.QualifiedName) WhereClause(io.crate.analyze.WhereClause) TableInfo(io.crate.metadata.table.TableInfo) TableIdent(io.crate.metadata.TableIdent) Schemas(io.crate.metadata.Schemas) AnalyzedRelation(io.crate.analyze.relations.AnalyzedRelation) SqlExpressions(io.crate.testing.SqlExpressions) TableRelation(io.crate.analyze.relations.TableRelation) Test(org.junit.Test) SQLTransportIntegrationTest(io.crate.integrationtests.SQLTransportIntegrationTest)

Aggregations

QualifiedName (io.crate.sql.tree.QualifiedName)28 Test (org.junit.Test)15 CrateUnitTest (io.crate.test.integration.CrateUnitTest)12 Field (io.crate.analyze.symbol.Field)8 SqlExpressions (io.crate.testing.SqlExpressions)7 DocTableInfo (io.crate.metadata.doc.DocTableInfo)6 DummyRelation (io.crate.testing.DummyRelation)6 AnalyzedRelation (io.crate.analyze.relations.AnalyzedRelation)5 TableRelation (io.crate.analyze.relations.TableRelation)5 WhereClause (io.crate.analyze.WhereClause)4 TableIdent (io.crate.metadata.TableIdent)4 Before (org.junit.Before)4 ArrayType (io.crate.types.ArrayType)3 DocTableRelation (io.crate.analyze.relations.DocTableRelation)2 JoinPair (io.crate.analyze.relations.JoinPair)2 Symbol (io.crate.analyze.symbol.Symbol)2 PartitionName (io.crate.metadata.PartitionName)2 TableInfo (io.crate.metadata.table.TableInfo)2 Set (java.util.Set)2 Nullable (javax.annotation.Nullable)2