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()));
}
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);
}
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));
}
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)));
}
}
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)));
}
}
Aggregations