Search in sources :

Example 1 with IgniteFilter

use of org.apache.ignite.internal.processors.query.calcite.rel.IgniteFilter in project ignite by apache.

the class FilterSpoolMergeToSortedIndexSpoolRule method onMatch.

/**
 * {@inheritDoc}
 */
@Override
public void onMatch(RelOptRuleCall call) {
    final IgniteFilter filter = call.rel(0);
    final IgniteTableSpool spool = call.rel(1);
    RelOptCluster cluster = spool.getCluster();
    RelTraitSet trait = spool.getTraitSet();
    CorrelationTrait filterCorr = TraitUtils.correlation(filter);
    if (filterCorr.correlated())
        trait = trait.replace(filterCorr);
    RelNode input = spool.getInput();
    RelCollation inCollation = TraitUtils.collation(input);
    IndexConditions idxCond = RexUtils.buildSortedIndexConditions(cluster, inCollation, filter.getCondition(), spool.getRowType(), null);
    if (F.isEmpty(idxCond.lowerCondition()) && F.isEmpty(idxCond.upperCondition()))
        return;
    RelCollation traitCollation;
    RelCollation searchCollation;
    if (inCollation == null || inCollation.isDefault()) {
        // Create collation by index condition.
        List<RexNode> lowerBound = idxCond.lowerBound();
        List<RexNode> upperBound = idxCond.upperBound();
        assert lowerBound == null || upperBound == null || lowerBound.size() == upperBound.size();
        int cardinality = lowerBound != null ? lowerBound.size() : upperBound.size();
        List<Integer> equalsFields = new ArrayList<>(cardinality);
        List<Integer> otherFields = new ArrayList<>(cardinality);
        // First, add all equality filters to collation, then add other fields.
        for (int i = 0; i < cardinality; i++) {
            RexNode lowerNode = lowerBound != null ? lowerBound.get(i) : null;
            RexNode upperNode = upperBound != null ? upperBound.get(i) : null;
            if (RexUtils.isNotNull(lowerNode) || RexUtils.isNotNull(upperNode))
                (F.eq(lowerNode, upperNode) ? equalsFields : otherFields).add(i);
        }
        searchCollation = traitCollation = TraitUtils.createCollation(F.concat(true, equalsFields, otherFields));
    } else {
        // Create search collation as a prefix of input collation.
        traitCollation = inCollation;
        Set<Integer> searchKeys = idxCond.keys();
        List<RelFieldCollation> collationFields = inCollation.getFieldCollations().subList(0, searchKeys.size());
        assert searchKeys.containsAll(collationFields.stream().map(RelFieldCollation::getFieldIndex).collect(Collectors.toSet())) : "Search condition should be a prefix of collation [searchKeys=" + searchKeys + ", collation=" + inCollation + ']';
        searchCollation = RelCollations.of(collationFields);
    }
    RelNode res = new IgniteSortedIndexSpool(cluster, trait.replace(traitCollation), convert(input, input.getTraitSet().replace(traitCollation)), searchCollation, filter.getCondition(), idxCond);
    call.transformTo(res);
}
Also used : RelOptCluster(org.apache.calcite.plan.RelOptCluster) IgniteSortedIndexSpool(org.apache.ignite.internal.processors.query.calcite.rel.IgniteSortedIndexSpool) CorrelationTrait(org.apache.ignite.internal.processors.query.calcite.trait.CorrelationTrait) IndexConditions(org.apache.ignite.internal.processors.query.calcite.util.IndexConditions) ArrayList(java.util.ArrayList) RelTraitSet(org.apache.calcite.plan.RelTraitSet) RelCollation(org.apache.calcite.rel.RelCollation) RelNode(org.apache.calcite.rel.RelNode) IgniteFilter(org.apache.ignite.internal.processors.query.calcite.rel.IgniteFilter) IgniteTableSpool(org.apache.ignite.internal.processors.query.calcite.rel.IgniteTableSpool) RelFieldCollation(org.apache.calcite.rel.RelFieldCollation) RexNode(org.apache.calcite.rex.RexNode)

Example 2 with IgniteFilter

use of org.apache.ignite.internal.processors.query.calcite.rel.IgniteFilter in project ignite by apache.

the class FilterConverterRule method convert.

/**
 * {@inheritDoc}
 */
@Override
protected PhysicalNode convert(RelOptPlanner planner, RelMetadataQuery mq, LogicalFilter rel) {
    RelOptCluster cluster = rel.getCluster();
    RelTraitSet traits = cluster.traitSetOf(IgniteConvention.INSTANCE).replace(IgniteDistributions.single());
    Set<CorrelationId> corrIds = RexUtils.extractCorrelationIds(rel.getCondition());
    if (!corrIds.isEmpty()) {
        traits = traits.replace(CorrelationTrait.correlations(corrIds)).replace(RewindabilityTrait.REWINDABLE);
    }
    return new IgniteFilter(cluster, traits, convert(rel.getInput(), traits.replace(CorrelationTrait.UNCORRELATED)), rel.getCondition());
}
Also used : RelOptCluster(org.apache.calcite.plan.RelOptCluster) IgniteFilter(org.apache.ignite.internal.processors.query.calcite.rel.IgniteFilter) RelTraitSet(org.apache.calcite.plan.RelTraitSet) CorrelationId(org.apache.calcite.rel.core.CorrelationId)

Example 3 with IgniteFilter

use of org.apache.ignite.internal.processors.query.calcite.rel.IgniteFilter in project ignite by apache.

the class PlannerTest method testMergeFilters.

/**
 * @throws Exception If failed.
 */
@Test
public void testMergeFilters() throws Exception {
    IgniteTypeFactory f = new IgniteTypeFactory(IgniteTypeSystem.INSTANCE);
    TestTable testTbl = new TestTable(new RelDataTypeFactory.Builder(f).add("ID", f.createJavaType(Integer.class)).add("VAL", f.createJavaType(String.class)).build()) {

        @Override
        public IgniteDistribution distribution() {
            return IgniteDistributions.single();
        }
    };
    IgniteSchema publicSchema = new IgniteSchema("PUBLIC");
    publicSchema.addTable("TEST", testTbl);
    String sql = "" + "SELECT val from (\n" + "   SELECT * \n" + "   FROM TEST \n" + "   WHERE VAL = 10) \n" + "WHERE VAL = 10";
    RelNode phys = physicalPlan(sql, publicSchema);
    assertNotNull(phys);
    AtomicInteger filterCnt = new AtomicInteger();
    // Counts filters af the plan.
    phys.childrenAccept(new RelVisitor() {

        @Override
        public void visit(RelNode node, int ordinal, RelNode parent) {
            if (node instanceof IgniteFilter)
                filterCnt.incrementAndGet();
            super.visit(node, ordinal, parent);
        }
    });
    // Checks that two filter merged into one filter.
    // Expected plan:
    // IgniteProject(VAL=[$1])
    // IgniteProject(ID=[$0], VAL=[$1])
    // IgniteFilter(condition=[=(CAST($1):INTEGER, 10)])
    // IgniteTableScan(table=[[PUBLIC, TEST]])
    assertEquals(0, filterCnt.get());
}
Also used : RelNode(org.apache.calcite.rel.RelNode) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) IgniteFilter(org.apache.ignite.internal.processors.query.calcite.rel.IgniteFilter) IgniteTypeFactory(org.apache.ignite.internal.processors.query.calcite.type.IgniteTypeFactory) Frameworks.newConfigBuilder(org.apache.calcite.tools.Frameworks.newConfigBuilder) RelVisitor(org.apache.calcite.rel.RelVisitor) IgniteSchema(org.apache.ignite.internal.processors.query.calcite.schema.IgniteSchema) Test(org.junit.Test)

Example 4 with IgniteFilter

use of org.apache.ignite.internal.processors.query.calcite.rel.IgniteFilter in project ignite by apache.

the class CorrelatedSubqueryPlannerTest method test.

/**
 * Test verifies the row type is consistent for correlation variable and
 * node that actually puts this variable into a context.
 *
 * In this particular test the row type of the left input of CNLJ node should
 * match the row type correlated variable in the filter was created with.
 *
 * @throws Exception In case of any unexpected error.
 */
@Test
public void test() throws Exception {
    IgniteSchema schema = createSchema(createTable("T1", IgniteDistributions.single(), "A", Integer.class, "B", Integer.class, "C", Integer.class, "D", Integer.class, "E", Integer.class));
    String sql = "" + "SELECT (SELECT count(*) FROM t1 AS x WHERE x.b<t1.b)\n" + "  FROM t1\n" + " WHERE (a>e-2 AND a<e+2)\n" + "    OR c>d\n" + " ORDER BY 1;";
    IgniteRel rel = physicalPlan(sql, schema, "FilterTableScanMergeRule");
    IgniteFilter filter = findFirstNode(rel, byClass(IgniteFilter.class).and(f -> RexUtils.hasCorrelation(((Filter) f).getCondition())));
    RexFieldAccess fieldAccess = findFirst(filter.getCondition(), RexFieldAccess.class);
    assertNotNull(fieldAccess);
    assertEquals(RexCorrelVariable.class, fieldAccess.getReferenceExpr().getClass());
    IgniteCorrelatedNestedLoopJoin join = findFirstNode(rel, byClass(IgniteCorrelatedNestedLoopJoin.class));
    assertEquals(fieldAccess.getReferenceExpr().getType(), join.getLeft().getRowType());
}
Also used : Project(org.apache.calcite.rel.core.Project) RexFieldAccess(org.apache.calcite.rex.RexFieldAccess) IgnitePlanner(org.apache.ignite.internal.processors.query.calcite.prepare.IgnitePlanner) LogicalProject(org.apache.calcite.rel.logical.LogicalProject) LogicalFilter(org.apache.calcite.rel.logical.LogicalFilter) PlannerPhase(org.apache.ignite.internal.processors.query.calcite.prepare.PlannerPhase) PlanningContext(org.apache.ignite.internal.processors.query.calcite.prepare.PlanningContext) Test(org.junit.Test) RelNode(org.apache.calcite.rel.RelNode) Filter(org.apache.calcite.rel.core.Filter) IgniteSchema(org.apache.ignite.internal.processors.query.calcite.schema.IgniteSchema) IgniteCorrelatedNestedLoopJoin(org.apache.ignite.internal.processors.query.calcite.rel.IgniteCorrelatedNestedLoopJoin) IgniteFilter(org.apache.ignite.internal.processors.query.calcite.rel.IgniteFilter) List(java.util.List) SqlNode(org.apache.calcite.sql.SqlNode) IgniteRel(org.apache.ignite.internal.processors.query.calcite.rel.IgniteRel) RexNode(org.apache.calcite.rex.RexNode) RexCorrelVariable(org.apache.calcite.rex.RexCorrelVariable) LogicalCorrelate(org.apache.calcite.rel.logical.LogicalCorrelate) Collections(java.util.Collections) RexUtils(org.apache.ignite.internal.processors.query.calcite.util.RexUtils) IgniteDistributions(org.apache.ignite.internal.processors.query.calcite.trait.IgniteDistributions) RexCall(org.apache.calcite.rex.RexCall) IgniteFilter(org.apache.ignite.internal.processors.query.calcite.rel.IgniteFilter) IgniteRel(org.apache.ignite.internal.processors.query.calcite.rel.IgniteRel) IgniteSchema(org.apache.ignite.internal.processors.query.calcite.schema.IgniteSchema) IgniteCorrelatedNestedLoopJoin(org.apache.ignite.internal.processors.query.calcite.rel.IgniteCorrelatedNestedLoopJoin) RexFieldAccess(org.apache.calcite.rex.RexFieldAccess) Test(org.junit.Test)

Example 5 with IgniteFilter

use of org.apache.ignite.internal.processors.query.calcite.rel.IgniteFilter in project ignite by apache.

the class FilterSpoolMergeToHashIndexSpoolRule method onMatch.

/**
 * {@inheritDoc}
 */
@Override
public void onMatch(RelOptRuleCall call) {
    final IgniteFilter filter = call.rel(0);
    final IgniteTableSpool spool = call.rel(1);
    RelOptCluster cluster = spool.getCluster();
    RelTraitSet trait = spool.getTraitSet();
    CorrelationTrait filterCorr = TraitUtils.correlation(filter);
    if (filterCorr.correlated())
        trait = trait.replace(filterCorr);
    RelNode input = spool.getInput();
    List<RexNode> searchRow = RexUtils.buildHashSearchRow(cluster, filter.getCondition(), spool.getRowType(), null, false);
    if (F.isEmpty(searchRow))
        return;
    RelNode res = new IgniteHashIndexSpool(cluster, trait.replace(RelCollations.EMPTY), input, searchRow, filter.getCondition());
    call.transformTo(res);
}
Also used : RelOptCluster(org.apache.calcite.plan.RelOptCluster) CorrelationTrait(org.apache.ignite.internal.processors.query.calcite.trait.CorrelationTrait) RelNode(org.apache.calcite.rel.RelNode) IgniteFilter(org.apache.ignite.internal.processors.query.calcite.rel.IgniteFilter) IgniteTableSpool(org.apache.ignite.internal.processors.query.calcite.rel.IgniteTableSpool) IgniteHashIndexSpool(org.apache.ignite.internal.processors.query.calcite.rel.IgniteHashIndexSpool) RelTraitSet(org.apache.calcite.plan.RelTraitSet) RexNode(org.apache.calcite.rex.RexNode)

Aggregations

IgniteFilter (org.apache.ignite.internal.processors.query.calcite.rel.IgniteFilter)5 RelNode (org.apache.calcite.rel.RelNode)4 RelOptCluster (org.apache.calcite.plan.RelOptCluster)3 RelTraitSet (org.apache.calcite.plan.RelTraitSet)3 RexNode (org.apache.calcite.rex.RexNode)3 IgniteTableSpool (org.apache.ignite.internal.processors.query.calcite.rel.IgniteTableSpool)2 IgniteSchema (org.apache.ignite.internal.processors.query.calcite.schema.IgniteSchema)2 CorrelationTrait (org.apache.ignite.internal.processors.query.calcite.trait.CorrelationTrait)2 Test (org.junit.Test)2 ArrayList (java.util.ArrayList)1 Collections (java.util.Collections)1 List (java.util.List)1 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)1 RelCollation (org.apache.calcite.rel.RelCollation)1 RelFieldCollation (org.apache.calcite.rel.RelFieldCollation)1 RelVisitor (org.apache.calcite.rel.RelVisitor)1 CorrelationId (org.apache.calcite.rel.core.CorrelationId)1 Filter (org.apache.calcite.rel.core.Filter)1 Project (org.apache.calcite.rel.core.Project)1 LogicalCorrelate (org.apache.calcite.rel.logical.LogicalCorrelate)1