Search in sources :

Example 1 with Spool

use of org.apache.calcite.rel.core.Spool in project ignite-3 by apache.

the class TableDmlPlannerTest method insertCachesIndexScan.

/**
 * InsertCachesIndexScan.
 * TODO Documentation https://issues.apache.org/jira/browse/IGNITE-15859
 *
 * @throws Exception If failed.
 */
@Test
public void insertCachesIndexScan() throws Exception {
    TestTable tbl = createTable("TEST", IgniteDistributions.random(), "VAL", Integer.class);
    tbl.addIndex(new IgniteIndex(RelCollations.of(0), "IDX", tbl));
    IgniteSchema schema = createSchema(tbl);
    String sql = "insert into test select 2 * val from test";
    RelNode phys = physicalPlan(sql, schema, "LogicalTableScanConverterRule");
    assertNotNull(phys);
    String invalidPlanMsg = "Invalid plan:\n" + RelOptUtil.toString(phys);
    IgniteTableModify modifyNode = findFirstNode(phys, byClass(IgniteTableModify.class));
    assertThat(invalidPlanMsg, modifyNode, notNullValue());
    assertThat(invalidPlanMsg, modifyNode.getInput(), instanceOf(Spool.class));
    Spool spool = (Spool) modifyNode.getInput();
    assertThat(invalidPlanMsg, spool.readType, equalTo(Spool.Type.EAGER));
    assertThat(invalidPlanMsg, findFirstNode(phys, byClass(IgniteIndexScan.class)), notNullValue());
}
Also used : IgniteIndex(org.apache.ignite.internal.sql.engine.schema.IgniteIndex) RelNode(org.apache.calcite.rel.RelNode) IgniteTableModify(org.apache.ignite.internal.sql.engine.rel.IgniteTableModify) Spool(org.apache.calcite.rel.core.Spool) IgniteSchema(org.apache.ignite.internal.sql.engine.schema.IgniteSchema) Test(org.junit.jupiter.api.Test)

Example 2 with Spool

use of org.apache.calcite.rel.core.Spool in project calcite by apache.

the class RelSet method mergeWith.

/**
 * Merges <code>otherSet</code> into this RelSet.
 *
 * <p>One generally calls this method after discovering that two relational
 * expressions are equivalent, and hence the <code>RelSet</code>s they
 * belong to are equivalent also.
 *
 * <p>After this method completes, <code>otherSet</code> is obsolete, its
 * {@link #equivalentSet} member points to this RelSet, and this RelSet is
 * still alive.
 *
 * @param planner  Planner
 * @param otherSet RelSet which is equivalent to this one
 */
void mergeWith(VolcanoPlanner planner, RelSet otherSet) {
    assert this != otherSet;
    assert this.equivalentSet == null;
    assert otherSet.equivalentSet == null;
    LOGGER.trace("Merge set#{} into set#{}", otherSet.id, id);
    otherSet.equivalentSet = this;
    RelOptCluster cluster = castNonNull(rel).getCluster();
    // remove from table
    boolean existed = planner.allSets.remove(otherSet);
    assert existed : "merging with a dead otherSet";
    Set<RelNode> changedRels = new HashSet<>();
    // merge subsets
    for (RelSubset otherSubset : otherSet.subsets) {
        RelSubset subset = null;
        RelTraitSet otherTraits = otherSubset.getTraitSet();
        // If it is logical or delivered physical traitSet
        if (otherSubset.isDelivered() || !otherSubset.isRequired()) {
            subset = getOrCreateSubset(cluster, otherTraits, false);
        }
        // in which case, register again.
        if (otherSubset.isRequired()) {
            subset = getOrCreateSubset(cluster, otherTraits, true);
        }
        assert subset != null;
        if (subset.passThroughCache == null) {
            subset.passThroughCache = otherSubset.passThroughCache;
        } else if (otherSubset.passThroughCache != null) {
            subset.passThroughCache.addAll(otherSubset.passThroughCache);
        }
        // collect RelSubset instances, whose best should be changed
        if (otherSubset.bestCost.isLt(subset.bestCost) && otherSubset.best != null) {
            changedRels.add(otherSubset.best);
        }
    }
    Set<RelNode> parentRels = new HashSet<>(parents);
    for (RelNode otherRel : otherSet.rels) {
        if (!(otherRel instanceof Spool) && !otherRel.isEnforcer() && parentRels.contains(otherRel)) {
            // case it is not marked as an enforcer.
            if (otherRel.getInputs().size() != 1 || otherRel.getInput(0).getTraitSet().satisfies(otherRel.getTraitSet())) {
                planner.prune(otherRel);
            }
        }
        planner.reregister(this, otherRel);
    }
    // Has another set merged with this?
    assert equivalentSet == null;
    // propagate the new best information from changed relNodes.
    for (RelNode rel : changedRels) {
        planner.propagateCostImprovements(rel);
    }
    // Update all rels which have a child in the other set, to reflect the
    // fact that the child has been renamed.
    // 
    // Copy array to prevent ConcurrentModificationException.
    final List<RelNode> previousParents = ImmutableList.copyOf(otherSet.getParentRels());
    for (RelNode parentRel : previousParents) {
        planner.rename(parentRel);
    }
    // of this set - indeed, it could be dangerous.
    if (equivalentSet != null) {
        return;
    }
    // Make sure the cost changes as a result of merging are propagated.
    for (RelNode parentRel : getParentRels()) {
        planner.propagateCostImprovements(parentRel);
    }
    assert equivalentSet == null;
    // once to fire again.)
    for (RelNode rel : rels) {
        assert planner.getSet(rel) == this;
        planner.fireRules(rel);
    }
    // Fire rule match on subsets as well
    for (RelSubset subset : subsets) {
        planner.fireRules(subset);
    }
}
Also used : RelOptCluster(org.apache.calcite.plan.RelOptCluster) RelNode(org.apache.calcite.rel.RelNode) Spool(org.apache.calcite.rel.core.Spool) RelTraitSet(org.apache.calcite.plan.RelTraitSet) HashSet(java.util.HashSet)

Example 3 with Spool

use of org.apache.calcite.rel.core.Spool in project ignite-3 by apache.

the class TableDmlPlannerTest method insertCachesTableScan.

/**
 * InsertCachesTableScan.
 * TODO Documentation https://issues.apache.org/jira/browse/IGNITE-15859
 *
 * @throws Exception If failed.
 */
@Test
public void insertCachesTableScan() throws Exception {
    IgniteSchema schema = createSchema(createTable("TEST", IgniteDistributions.random(), "VAL", Integer.class));
    String sql = "insert into test select 2 * val from test";
    RelNode phys = physicalPlan(sql, schema, "LogicalIndexScanConverterRule");
    assertNotNull(phys);
    String invalidPlanMsg = "Invalid plan:\n" + RelOptUtil.toString(phys);
    IgniteTableModify modifyNode = findFirstNode(phys, byClass(IgniteTableModify.class));
    assertThat(invalidPlanMsg, modifyNode, notNullValue());
    assertThat(invalidPlanMsg, modifyNode.getInput(), instanceOf(Spool.class));
    Spool spool = (Spool) modifyNode.getInput();
    assertThat(invalidPlanMsg, spool.readType, equalTo(Spool.Type.EAGER));
    assertThat(invalidPlanMsg, findFirstNode(phys, byClass(IgniteTableScan.class)), notNullValue());
}
Also used : RelNode(org.apache.calcite.rel.RelNode) IgniteTableModify(org.apache.ignite.internal.sql.engine.rel.IgniteTableModify) Spool(org.apache.calcite.rel.core.Spool) IgniteSchema(org.apache.ignite.internal.sql.engine.schema.IgniteSchema) Test(org.junit.jupiter.api.Test)

Example 4 with Spool

use of org.apache.calcite.rel.core.Spool in project ignite-3 by apache.

the class TableDmlPlannerTest method updateCachesDependentIndexScan.

/**
 * UpdateCachesDependentIndexScan.
 * TODO Documentation https://issues.apache.org/jira/browse/IGNITE-15859
 *
 * @throws Exception If failed.
 */
@Test
public void updateCachesDependentIndexScan() throws Exception {
    TestTable tbl = createTable("TEST", IgniteDistributions.random(), "VAL", Integer.class);
    tbl.addIndex(new IgniteIndex(RelCollations.of(0), "IDX", tbl));
    IgniteSchema schema = createSchema(tbl);
    String sql = "update test set val = 2 * val where val between 2 and 10";
    RelNode phys = physicalPlan(sql, schema, "LogicalTableScanConverterRule");
    assertNotNull(phys);
    String invalidPlanMsg = "Invalid plan:\n" + RelOptUtil.toString(phys);
    IgniteTableModify modifyNode = findFirstNode(phys, byClass(IgniteTableModify.class));
    assertThat(invalidPlanMsg, modifyNode, notNullValue());
    assertThat(invalidPlanMsg, modifyNode.getInput(), instanceOf(Spool.class));
    Spool spool = (Spool) modifyNode.getInput();
    assertThat(invalidPlanMsg, spool.readType, equalTo(Spool.Type.EAGER));
    assertThat(invalidPlanMsg, findFirstNode(phys, byClass(IgniteIndexScan.class)), notNullValue());
}
Also used : IgniteIndex(org.apache.ignite.internal.sql.engine.schema.IgniteIndex) RelNode(org.apache.calcite.rel.RelNode) IgniteTableModify(org.apache.ignite.internal.sql.engine.rel.IgniteTableModify) Spool(org.apache.calcite.rel.core.Spool) IgniteSchema(org.apache.ignite.internal.sql.engine.schema.IgniteSchema) Test(org.junit.jupiter.api.Test)

Aggregations

RelNode (org.apache.calcite.rel.RelNode)4 Spool (org.apache.calcite.rel.core.Spool)4 IgniteTableModify (org.apache.ignite.internal.sql.engine.rel.IgniteTableModify)3 IgniteSchema (org.apache.ignite.internal.sql.engine.schema.IgniteSchema)3 Test (org.junit.jupiter.api.Test)3 IgniteIndex (org.apache.ignite.internal.sql.engine.schema.IgniteIndex)2 HashSet (java.util.HashSet)1 RelOptCluster (org.apache.calcite.plan.RelOptCluster)1 RelTraitSet (org.apache.calcite.plan.RelTraitSet)1