Search in sources :

Example 16 with IgniteSchema

use of org.apache.ignite.internal.sql.engine.schema.IgniteSchema in project ignite-3 by apache.

the class LimitOffsetPlannerTest method testOrderOfRels.

@Test
public void testOrderOfRels() throws Exception {
    IgniteSchema publicSchema = createSchemaWithTable(IgniteDistributions.random());
    // Simple case, Limit can't be pushed down under Exchange or Sort. Sort before Exchange is more preferable.
    assertPlan("SELECT * FROM TEST ORDER BY ID LIMIT 10 OFFSET 10", publicSchema, isInstanceOf(IgniteLimit.class).and(input(isInstanceOf(IgniteExchange.class).and(input(isInstanceOf(IgniteSort.class))))));
    // Simple case without ordering.
    assertPlan("SELECT * FROM TEST OFFSET 10 ROWS FETCH FIRST 10 ROWS ONLY", publicSchema, isInstanceOf(IgniteLimit.class).and(input(isInstanceOf(IgniteExchange.class))).and(hasChildThat(isInstanceOf(IgniteSort.class)).negate()));
    // Check that Sort node is not eliminated by aggregation and Exchange node is not eliminated by distribution
    // required by parent nodes.
    assertPlan("SELECT * FROM TEST UNION (SELECT * FROM TEST ORDER BY ID LIMIT 10)", publicSchema, nodeOrAnyChild(isInstanceOf(IgniteUnionAll.class).and(hasChildThat(isInstanceOf(IgniteLimit.class).and(input(isInstanceOf(IgniteExchange.class).and(input(isInstanceOf(IgniteSort.class)))))))));
    // Check that internal Sort node is not eliminated by external Sort node with different collation.
    assertPlan("SELECT * FROM (SELECT * FROM TEST ORDER BY ID LIMIT 10) ORDER BY VAL", publicSchema, nodeOrAnyChild(isInstanceOf(IgniteSort.class).and(hasChildThat(isInstanceOf(IgniteLimit.class).and(input(isInstanceOf(IgniteExchange.class).and(input(isInstanceOf(IgniteSort.class)))))))));
    // Check that extended collation is passed through the Limit node if it satisfies the Limit collation.
    assertPlan("SELECT * FROM (SELECT * FROM TEST ORDER BY ID LIMIT 10) ORDER BY ID, VAL", publicSchema, isInstanceOf(IgniteLimit.class).and(input(isInstanceOf(IgniteExchange.class).and(input(isInstanceOf(IgniteSort.class).and(s -> s.collation().getKeys().equals(ImmutableIntList.of(0, 1))))))));
    // Check that external Sort node is not required if external collation is subset of internal collation.
    assertPlan("SELECT * FROM (SELECT * FROM TEST ORDER BY ID, VAL LIMIT 10) ORDER BY ID", publicSchema, isInstanceOf(IgniteLimit.class).and(input(isInstanceOf(IgniteExchange.class).and(input(isInstanceOf(IgniteSort.class))))));
    // Check double limit when external collation is a subset of internal collation.
    assertPlan("SELECT * FROM (SELECT * FROM TEST ORDER BY ID, VAL LIMIT 10) ORDER BY ID LIMIT 5 OFFSET 3", publicSchema, isInstanceOf(IgniteLimit.class).and(input(isInstanceOf(IgniteLimit.class).and(input(isInstanceOf(IgniteExchange.class).and(input(isInstanceOf(IgniteSort.class))))))));
    // Check limit/exchange/sort rel order in subquery.
    assertPlan("SELECT NULLIF((SELECT id FROM test ORDER BY id LIMIT 1 OFFSET 1), id) FROM test", publicSchema, hasChildThat(isInstanceOf(IgniteLimit.class).and(input(isInstanceOf(IgniteExchange.class).and(e -> e.distribution() == IgniteDistributions.single()).and(input(isInstanceOf(IgniteSort.class)))))));
    publicSchema = createSchemaWithTable(IgniteDistributions.random(), 0);
    // Sort node is not required, since collation of the Limit node equals to the index collation.
    assertPlan("SELECT * FROM TEST ORDER BY ID LIMIT 10 OFFSET 10", publicSchema, isInstanceOf(IgniteLimit.class).and(input(isInstanceOf(IgniteExchange.class).and(input(isInstanceOf(IgniteIndexScan.class))))).and(hasChildThat(isInstanceOf(IgniteSort.class)).negate()));
    publicSchema = createSchemaWithTable(IgniteDistributions.random(), 0, 1);
    // Sort node is not required, since collation of the Limit node satisfies the index collation.
    assertPlan("SELECT * FROM TEST ORDER BY ID LIMIT 10 OFFSET 10", publicSchema, isInstanceOf(IgniteLimit.class).and(input(isInstanceOf(IgniteExchange.class).and(input(isInstanceOf(IgniteIndexScan.class))))).and(hasChildThat(isInstanceOf(IgniteSort.class)).negate()));
    publicSchema = createSchemaWithTable(IgniteDistributions.single());
    // Exchange node is not required, since distribution of the table is already "single".
    assertPlan("SELECT * FROM TEST ORDER BY ID LIMIT 10 OFFSET 10", publicSchema, isInstanceOf(IgniteLimit.class).and(input(isInstanceOf(IgniteSort.class))).and(hasChildThat(isInstanceOf(IgniteExchange.class)).negate()));
}
Also used : IgniteUnionAll(org.apache.ignite.internal.sql.engine.rel.IgniteUnionAll) RelCollations(org.apache.calcite.rel.RelCollations) IgniteDistributions(org.apache.ignite.internal.sql.engine.trait.IgniteDistributions) RelDataType(org.apache.calcite.rel.type.RelDataType) RelDataTypeFactory(org.apache.calcite.rel.type.RelDataTypeFactory) Arrays(java.util.Arrays) IgniteSchema(org.apache.ignite.internal.sql.engine.schema.IgniteSchema) ImmutableIntList(org.apache.calcite.util.ImmutableIntList) IgniteLimit(org.apache.ignite.internal.sql.engine.rel.IgniteLimit) IgniteExchange(org.apache.ignite.internal.sql.engine.rel.IgniteExchange) IgniteSort(org.apache.ignite.internal.sql.engine.rel.IgniteSort) ArrayUtils(org.apache.ignite.internal.util.ArrayUtils) RelFieldCollation(org.apache.calcite.rel.RelFieldCollation) IgniteIndexScan(org.apache.ignite.internal.sql.engine.rel.IgniteIndexScan) Test(org.junit.jupiter.api.Test) Collectors.toList(java.util.stream.Collectors.toList) IgniteTypeSystem(org.apache.ignite.internal.sql.engine.type.IgniteTypeSystem) IgniteDistribution(org.apache.ignite.internal.sql.engine.trait.IgniteDistribution) IgniteTypeFactory(org.apache.ignite.internal.sql.engine.type.IgniteTypeFactory) IgniteUnionAll(org.apache.ignite.internal.sql.engine.rel.IgniteUnionAll) IgniteLimit(org.apache.ignite.internal.sql.engine.rel.IgniteLimit) IgniteSort(org.apache.ignite.internal.sql.engine.rel.IgniteSort) IgniteSchema(org.apache.ignite.internal.sql.engine.schema.IgniteSchema) IgniteExchange(org.apache.ignite.internal.sql.engine.rel.IgniteExchange) Test(org.junit.jupiter.api.Test)

Example 17 with IgniteSchema

use of org.apache.ignite.internal.sql.engine.schema.IgniteSchema in project ignite-3 by apache.

the class LimitOffsetPlannerTest method createSchemaWithTable.

/**
 * Creates PUBLIC schema with one TEST table.
 */
private IgniteSchema createSchemaWithTable(IgniteDistribution distr, int... indexedColumns) {
    IgniteTypeFactory f = new IgniteTypeFactory(IgniteTypeSystem.INSTANCE);
    RelDataType type = new RelDataTypeFactory.Builder(f).add("ID", f.createJavaType(Integer.class)).add("VAL", f.createJavaType(String.class)).build();
    TestTable table = new TestTable("TEST", type, ROW_CNT) {

        @Override
        public IgniteDistribution distribution() {
            return distr;
        }
    };
    if (!ArrayUtils.nullOrEmpty(indexedColumns)) {
        table.addIndex(RelCollations.of(Arrays.stream(indexedColumns).mapToObj(idx -> new RelFieldCollation(idx, RelFieldCollation.Direction.ASCENDING, RelFieldCollation.NullDirection.FIRST)).collect(toList())), "test_idx");
    }
    return createSchema(table);
}
Also used : RelCollations(org.apache.calcite.rel.RelCollations) IgniteDistributions(org.apache.ignite.internal.sql.engine.trait.IgniteDistributions) RelDataType(org.apache.calcite.rel.type.RelDataType) RelDataTypeFactory(org.apache.calcite.rel.type.RelDataTypeFactory) Arrays(java.util.Arrays) IgniteSchema(org.apache.ignite.internal.sql.engine.schema.IgniteSchema) ImmutableIntList(org.apache.calcite.util.ImmutableIntList) IgniteLimit(org.apache.ignite.internal.sql.engine.rel.IgniteLimit) IgniteExchange(org.apache.ignite.internal.sql.engine.rel.IgniteExchange) IgniteSort(org.apache.ignite.internal.sql.engine.rel.IgniteSort) ArrayUtils(org.apache.ignite.internal.util.ArrayUtils) RelFieldCollation(org.apache.calcite.rel.RelFieldCollation) IgniteIndexScan(org.apache.ignite.internal.sql.engine.rel.IgniteIndexScan) Test(org.junit.jupiter.api.Test) Collectors.toList(java.util.stream.Collectors.toList) IgniteTypeSystem(org.apache.ignite.internal.sql.engine.type.IgniteTypeSystem) IgniteDistribution(org.apache.ignite.internal.sql.engine.trait.IgniteDistribution) IgniteTypeFactory(org.apache.ignite.internal.sql.engine.type.IgniteTypeFactory) IgniteUnionAll(org.apache.ignite.internal.sql.engine.rel.IgniteUnionAll) IgniteTypeFactory(org.apache.ignite.internal.sql.engine.type.IgniteTypeFactory) RelDataTypeFactory(org.apache.calcite.rel.type.RelDataTypeFactory) RelFieldCollation(org.apache.calcite.rel.RelFieldCollation) RelDataType(org.apache.calcite.rel.type.RelDataType)

Example 18 with IgniteSchema

use of org.apache.ignite.internal.sql.engine.schema.IgniteSchema in project ignite-3 by apache.

the class AggregatePlannerTest method distribution.

/**
 * Test that aggregate has single distribution output even if parent node accept random distibution inputs.
 *
 * @throws Exception If failed.
 */
@ParameterizedTest
@EnumSource
public void distribution(AggregateAlgorithm algo) throws Exception {
    TestTable tbl = createAffinityTable().addIndex(RelCollations.of(ImmutableIntList.of(3)), "grp0");
    IgniteSchema publicSchema = new IgniteSchema("PUBLIC");
    publicSchema.addTable("TEST", tbl);
    String sql = "SELECT AVG(val0), grp0 FROM TEST GROUP BY grp0 UNION ALL SELECT val0, grp0 FROM test";
    IgniteRel phys = physicalPlan(sql, publicSchema, concat(algo.rulesToDisable, "SortMapReduceAggregateConverterRule", "HashMapReduceAggregateConverterRule"));
    IgniteSingleAggregateBase singleAgg = findFirstNode(phys, byClass(algo.single));
    assertEquals(IgniteDistributions.single(), TraitUtils.distribution(singleAgg));
    phys = physicalPlan(sql, publicSchema, concat(algo.rulesToDisable, "SortSingleAggregateConverterRule", "HashSingleAggregateConverterRule"));
    IgniteReduceAggregateBase rdcAgg = findFirstNode(phys, byClass(algo.reduce));
    assertEquals(IgniteDistributions.single(), TraitUtils.distribution(rdcAgg));
}
Also used : IgniteReduceAggregateBase(org.apache.ignite.internal.sql.engine.rel.agg.IgniteReduceAggregateBase) IgniteRel(org.apache.ignite.internal.sql.engine.rel.IgniteRel) IgniteSingleAggregateBase(org.apache.ignite.internal.sql.engine.rel.agg.IgniteSingleAggregateBase) IgniteSchema(org.apache.ignite.internal.sql.engine.schema.IgniteSchema) EnumSource(org.junit.jupiter.params.provider.EnumSource) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest)

Example 19 with IgniteSchema

use of org.apache.ignite.internal.sql.engine.schema.IgniteSchema in project ignite-3 by apache.

the class AggregatePlannerTest method singleWithIndex.

/**
 * SingleWithIndex.
 * TODO Documentation https://issues.apache.org/jira/browse/IGNITE-15859
 *
 * @throws Exception If failed.
 */
@ParameterizedTest
@EnumSource
public void singleWithIndex(AggregateAlgorithm algo) throws Exception {
    TestTable tbl = createBroadcastTable().addIndex(RelCollations.of(ImmutableIntList.of(3, 4)), "grp0_grp1");
    IgniteSchema publicSchema = new IgniteSchema("PUBLIC");
    publicSchema.addTable("TEST", tbl);
    String sql = "SELECT AVG(val0) FILTER(WHERE val1 > 10) FROM test GROUP BY grp0";
    IgniteRel phys = physicalPlan(sql, publicSchema, algo.rulesToDisable);
    IgniteSingleAggregateBase agg = findFirstNode(phys, byClass(algo.single));
    assertNotNull(agg, "Invalid plan\n" + RelOptUtil.toString(phys));
    assertThat("Invalid plan\n" + RelOptUtil.toString(phys), first(agg.getAggCallList()).getAggregation(), IsInstanceOf.instanceOf(SqlAvgAggFunction.class));
    if (algo == AggregateAlgorithm.SORT) {
        assertNotNull(findFirstNode(phys, byClass(IgniteIndexScan.class)));
    }
}
Also used : SqlAvgAggFunction(org.apache.calcite.sql.fun.SqlAvgAggFunction) IgniteRel(org.apache.ignite.internal.sql.engine.rel.IgniteRel) IgniteSingleAggregateBase(org.apache.ignite.internal.sql.engine.rel.agg.IgniteSingleAggregateBase) IgniteSchema(org.apache.ignite.internal.sql.engine.schema.IgniteSchema) EnumSource(org.junit.jupiter.params.provider.EnumSource) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest)

Example 20 with IgniteSchema

use of org.apache.ignite.internal.sql.engine.schema.IgniteSchema in project ignite-3 by apache.

the class AggregatePlannerTest method mapReduceGroupBy.

/**
 * MapReduceGroupBy.
 * TODO Documentation https://issues.apache.org/jira/browse/IGNITE-15859
 *
 * @throws Exception If failed.
 */
@ParameterizedTest
@EnumSource
public void mapReduceGroupBy(AggregateAlgorithm algo) throws Exception {
    TestTable tbl = createAffinityTable();
    IgniteSchema publicSchema = new IgniteSchema("PUBLIC");
    publicSchema.addTable("TEST", tbl);
    String sql = "SELECT AVG(val0) FILTER (WHERE val1 > 10) FROM test GROUP BY grp1, grp0";
    IgniteRel phys = physicalPlan(sql, publicSchema, algo.rulesToDisable);
    IgniteMapAggregateBase mapAgg = findFirstNode(phys, byClass(algo.map));
    IgniteReduceAggregateBase rdcAgg = findFirstNode(phys, byClass(algo.reduce));
    assertNotNull(rdcAgg, "Invalid plan\n" + RelOptUtil.toString(phys, SqlExplainLevel.ALL_ATTRIBUTES));
    assertNotNull(mapAgg, "Invalid plan\n" + RelOptUtil.toString(phys));
    assertThat("Invalid plan\n" + RelOptUtil.toString(phys), first(rdcAgg.getAggregateCalls()).getAggregation(), IsInstanceOf.instanceOf(SqlAvgAggFunction.class));
    assertThat("Invalid plan\n" + RelOptUtil.toString(phys), first(mapAgg.getAggCallList()).getAggregation(), IsInstanceOf.instanceOf(SqlAvgAggFunction.class));
    if (algo == AggregateAlgorithm.SORT) {
        assertNotNull(findFirstNode(phys, byClass(IgniteSort.class)));
    }
}
Also used : SqlAvgAggFunction(org.apache.calcite.sql.fun.SqlAvgAggFunction) IgniteReduceAggregateBase(org.apache.ignite.internal.sql.engine.rel.agg.IgniteReduceAggregateBase) IgniteRel(org.apache.ignite.internal.sql.engine.rel.IgniteRel) IgniteSchema(org.apache.ignite.internal.sql.engine.schema.IgniteSchema) IgniteMapAggregateBase(org.apache.ignite.internal.sql.engine.rel.agg.IgniteMapAggregateBase) EnumSource(org.junit.jupiter.params.provider.EnumSource) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest)

Aggregations

IgniteSchema (org.apache.ignite.internal.sql.engine.schema.IgniteSchema)115 Test (org.junit.jupiter.api.Test)105 IgniteRel (org.apache.ignite.internal.sql.engine.rel.IgniteRel)93 RelFieldCollation (org.apache.calcite.rel.RelFieldCollation)66 IgniteSort (org.apache.ignite.internal.sql.engine.rel.IgniteSort)42 RelCollation (org.apache.calcite.rel.RelCollation)33 IgniteTypeFactory (org.apache.ignite.internal.sql.engine.type.IgniteTypeFactory)28 RelDataTypeFactory (org.apache.calcite.rel.type.RelDataTypeFactory)20 RelNode (org.apache.calcite.rel.RelNode)12 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)11 IgniteIndex (org.apache.ignite.internal.sql.engine.schema.IgniteIndex)9 IgniteDistribution (org.apache.ignite.internal.sql.engine.trait.IgniteDistribution)9 SchemaPlus (org.apache.calcite.schema.SchemaPlus)8 RexFieldAccess (org.apache.calcite.rex.RexFieldAccess)7 PlanningContext (org.apache.ignite.internal.sql.engine.prepare.PlanningContext)7 IgniteIndexScan (org.apache.ignite.internal.sql.engine.rel.IgniteIndexScan)7 RexNode (org.apache.calcite.rex.RexNode)6 MappingQueryContext (org.apache.ignite.internal.sql.engine.prepare.MappingQueryContext)6 MultiStepPlan (org.apache.ignite.internal.sql.engine.prepare.MultiStepPlan)6 MultiStepQueryPlan (org.apache.ignite.internal.sql.engine.prepare.MultiStepQueryPlan)6