use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.plan.RelOptCluster in project calcite by apache.
the class ReduceExpressionsRule method reduceExpressions.
/**
* Reduces a list of expressions.
*
* <p>The {@code matchNullability} flag comes into play when reducing a
* expression whose type is nullable. Suppose we are reducing an expression
* {@code CASE WHEN 'a' = 'a' THEN 1 ELSE NULL END}. Before reduction the
* type is {@code INTEGER} (nullable), but after reduction the literal 1 has
* type {@code INTEGER NOT NULL}.
*
* <p>In some situations it is more important to preserve types; in this
* case you should use {@code matchNullability = true} (which used to be
* the default behavior of this method), and it will cast the literal to
* {@code INTEGER} (nullable).
*
* <p>In other situations, you would rather propagate the new stronger type,
* because it may allow further optimizations later; pass
* {@code matchNullability = false} and no cast will be added, but you may
* need to adjust types elsewhere in the expression tree.
*
* @param rel Relational expression
* @param expList List of expressions, modified in place
* @param predicates Constraints known to hold on input expressions
* @param unknownAsFalse Whether UNKNOWN will be treated as FALSE
* @param matchNullability Whether Calcite should add a CAST to a literal
* resulting from simplification and expression if the
* expression had nullable type and the literal is
* NOT NULL
*
* @return whether reduction found something to change, and succeeded
*/
protected static boolean reduceExpressions(RelNode rel, List<RexNode> expList, RelOptPredicateList predicates, boolean unknownAsFalse, boolean matchNullability) {
final RelOptCluster cluster = rel.getCluster();
final RexBuilder rexBuilder = cluster.getRexBuilder();
final RexExecutor executor = Util.first(cluster.getPlanner().getExecutor(), RexUtil.EXECUTOR);
final RexSimplify simplify = new RexSimplify(rexBuilder, predicates, unknownAsFalse, executor);
// Simplify predicates in place
boolean reduced = reduceExpressionsInternal(rel, simplify, expList, predicates);
final ExprSimplifier simplifier = new ExprSimplifier(simplify, matchNullability);
boolean simplified = false;
for (int i = 0; i < expList.size(); i++) {
RexNode expr2 = simplifier.apply(expList.get(i));
if (!expr2.toString().equals(expList.get(i).toString())) {
expList.remove(i);
expList.add(i, expr2);
simplified = true;
}
}
return reduced || simplified;
}
use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.plan.RelOptCluster in project calcite by apache.
the class FilterTableFunctionTransposeRule method onMatch.
// ~ Methods ----------------------------------------------------------------
// implement RelOptRule
public void onMatch(RelOptRuleCall call) {
LogicalFilter filter = call.rel(0);
LogicalTableFunctionScan funcRel = call.rel(1);
Set<RelColumnMapping> columnMappings = funcRel.getColumnMappings();
if (columnMappings == null || columnMappings.isEmpty()) {
// possible.
return;
}
List<RelNode> funcInputs = funcRel.getInputs();
if (funcInputs.size() != 1) {
// offsetting field indices, similar to join
return;
}
// TODO: support mappings other than 1-to-1
if (funcRel.getRowType().getFieldCount() != funcInputs.get(0).getRowType().getFieldCount()) {
return;
}
for (RelColumnMapping mapping : columnMappings) {
if (mapping.iInputColumn != mapping.iOutputColumn) {
return;
}
if (mapping.derived) {
return;
}
}
final List<RelNode> newFuncInputs = new ArrayList<RelNode>();
final RelOptCluster cluster = funcRel.getCluster();
final RexNode condition = filter.getCondition();
// create filters on top of each func input, modifying the filter
// condition to reference the child instead
RexBuilder rexBuilder = filter.getCluster().getRexBuilder();
List<RelDataTypeField> origFields = funcRel.getRowType().getFieldList();
// TODO: these need to be non-zero once we
// support arbitrary mappings
int[] adjustments = new int[origFields.size()];
for (RelNode funcInput : funcInputs) {
RexNode newCondition = condition.accept(new RelOptUtil.RexInputConverter(rexBuilder, origFields, funcInput.getRowType().getFieldList(), adjustments));
newFuncInputs.add(LogicalFilter.create(funcInput, newCondition));
}
// create a new UDX whose children are the filters created above
LogicalTableFunctionScan newFuncRel = LogicalTableFunctionScan.create(cluster, newFuncInputs, funcRel.getCall(), funcRel.getElementType(), funcRel.getRowType(), columnMappings);
call.transformTo(newFuncRel);
}
use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.plan.RelOptCluster in project calcite by apache.
the class RelOptTestBase method checkPlanning.
/**
* Checks the plan for a SQL statement before/after executing a given rule,
* with a pre-program to prepare the tree.
*
* @param tester Tester
* @param preProgram Program to execute before comparing before state
* @param planner Planner
* @param sql SQL query
* @param unchanged Whether the rule is to have no effect
*/
protected void checkPlanning(Tester tester, HepProgram preProgram, RelOptPlanner planner, String sql, boolean unchanged) {
final DiffRepository diffRepos = getDiffRepos();
String sql2 = diffRepos.expand("sql", sql);
final RelRoot root = tester.convertSqlToRel(sql2);
final RelNode relInitial = root.rel;
assertTrue(relInitial != null);
List<RelMetadataProvider> list = Lists.newArrayList();
list.add(DefaultRelMetadataProvider.INSTANCE);
planner.registerMetadataProviders(list);
RelMetadataProvider plannerChain = ChainedRelMetadataProvider.of(list);
final RelOptCluster cluster = relInitial.getCluster();
cluster.setMetadataProvider(plannerChain);
RelNode relBefore;
if (preProgram == null) {
relBefore = relInitial;
} else {
HepPlanner prePlanner = new HepPlanner(preProgram);
prePlanner.setRoot(relInitial);
relBefore = prePlanner.findBestExp();
}
assertThat(relBefore, notNullValue());
final String planBefore = NL + RelOptUtil.toString(relBefore);
diffRepos.assertEquals("planBefore", "${planBefore}", planBefore);
SqlToRelTestBase.assertValid(relBefore);
planner.setRoot(relBefore);
RelNode r = planner.findBestExp();
if (tester.isLateDecorrelate()) {
final String planMid = NL + RelOptUtil.toString(r);
diffRepos.assertEquals("planMid", "${planMid}", planMid);
SqlToRelTestBase.assertValid(r);
final RelBuilder relBuilder = RelFactories.LOGICAL_BUILDER.create(cluster, null);
r = RelDecorrelator.decorrelateQuery(r, relBuilder);
}
final String planAfter = NL + RelOptUtil.toString(r);
if (unchanged) {
assertThat(planAfter, is(planBefore));
} else {
diffRepos.assertEquals("planAfter", "${planAfter}", planAfter);
if (planBefore.equals(planAfter)) {
throw new AssertionError("Expected plan before and after is the same.\n" + "You must use unchanged=true or call checkPlanUnchanged");
}
}
SqlToRelTestBase.assertValid(r);
}
use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.plan.RelOptCluster in project calcite by apache.
the class SqlToRelConverterExtendedTest method foo.
public static void foo(RelNode rel) {
// Convert rel tree to JSON.
final RelJsonWriter writer = new RelJsonWriter();
rel.explain(writer);
final String json = writer.asString();
// Find the schema. If there are no tables in the plan, we won't need one.
final RelOptSchema[] schemas = { null };
rel.accept(new RelShuttleImpl() {
@Override
public RelNode visit(TableScan scan) {
schemas[0] = scan.getTable().getRelOptSchema();
return super.visit(scan);
}
});
// Convert JSON back to rel tree.
Frameworks.withPlanner(new Frameworks.PlannerAction<Object>() {
public Object apply(RelOptCluster cluster, RelOptSchema relOptSchema, SchemaPlus rootSchema) {
final RelJsonReader reader = new RelJsonReader(cluster, schemas[0], rootSchema);
try {
RelNode x = reader.read(json);
} catch (IOException e) {
throw new RuntimeException(e);
}
return null;
}
});
}
use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.plan.RelOptCluster in project calcite by apache.
the class CollationConversionTest method testCollationConversion.
@Test
public void testCollationConversion() {
final VolcanoPlanner planner = new VolcanoPlanner();
planner.addRelTraitDef(ConventionTraitDef.INSTANCE);
planner.addRelTraitDef(COLLATION_TRAIT_DEF);
planner.addRule(new SingleNodeRule());
planner.addRule(new LeafTraitRule());
planner.addRule(ExpandConversionRule.INSTANCE);
final RelOptCluster cluster = newCluster(planner);
final NoneLeafRel leafRel = new NoneLeafRel(cluster, "a");
final NoneSingleRel singleRel = new NoneSingleRel(cluster, leafRel);
final RelNode convertedRel = planner.changeTraits(singleRel, cluster.traitSetOf(PHYS_CALLING_CONVENTION).plus(ROOT_COLLATION));
planner.setRoot(convertedRel);
RelNode result = planner.chooseDelegate().findBestExp();
assertTrue(result instanceof RootSingleRel);
assertTrue(result.getTraitSet().contains(ROOT_COLLATION));
assertTrue(result.getTraitSet().contains(PHYS_CALLING_CONVENTION));
final RelNode input = result.getInput(0);
assertTrue(input instanceof PhysicalSort);
assertTrue(result.getTraitSet().contains(ROOT_COLLATION));
assertTrue(input.getTraitSet().contains(PHYS_CALLING_CONVENTION));
final RelNode input2 = input.getInput(0);
assertTrue(input2 instanceof LeafRel);
assertTrue(input2.getTraitSet().contains(LEAF_COLLATION));
assertTrue(input.getTraitSet().contains(PHYS_CALLING_CONVENTION));
}
Aggregations