use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rel.logical.LogicalProject in project calcite by apache.
the class ProjectWindowTransposeRule method onMatch.
@Override
public void onMatch(RelOptRuleCall call) {
final LogicalProject project = call.rel(0);
final LogicalWindow window = call.rel(1);
final RelOptCluster cluster = window.getCluster();
final List<RelDataTypeField> rowTypeWindowInput = window.getInput().getRowType().getFieldList();
final int windowInputColumn = rowTypeWindowInput.size();
// Record the window input columns which are actually referred
// either in the LogicalProject above LogicalWindow or LogicalWindow itself
// (Note that the constants used in LogicalWindow are not considered here)
final ImmutableBitSet beReferred = findReference(project, window);
// it is impossible to trim anyone of them out
if (beReferred.cardinality() == windowInputColumn) {
return;
}
// Put a DrillProjectRel below LogicalWindow
final List<RexNode> exps = new ArrayList<>();
final RelDataTypeFactory.Builder builder = cluster.getTypeFactory().builder();
// Keep only the fields which are referred
for (int index : BitSets.toIter(beReferred)) {
final RelDataTypeField relDataTypeField = rowTypeWindowInput.get(index);
exps.add(new RexInputRef(index, relDataTypeField.getType()));
builder.add(relDataTypeField);
}
final LogicalProject projectBelowWindow = new LogicalProject(cluster, window.getTraitSet(), window.getInput(), exps, builder.build());
// Create a new LogicalWindow with necessary inputs only
final List<Window.Group> groups = new ArrayList<>();
// As the un-referred columns are trimmed by the LogicalProject,
// the indices specified in LogicalWindow would need to be adjusted
final RexShuttle indexAdjustment = new RexShuttle() {
@Override
public RexNode visitInputRef(RexInputRef inputRef) {
final int newIndex = getAdjustedIndex(inputRef.getIndex(), beReferred, windowInputColumn);
return new RexInputRef(newIndex, inputRef.getType());
}
@Override
public RexNode visitCall(final RexCall call) {
if (call instanceof Window.RexWinAggCall) {
boolean[] update = { false };
final List<RexNode> clonedOperands = visitList(call.operands, update);
if (update[0]) {
return new Window.RexWinAggCall((SqlAggFunction) call.getOperator(), call.getType(), clonedOperands, ((Window.RexWinAggCall) call).ordinal, ((Window.RexWinAggCall) call).distinct);
} else {
return call;
}
} else {
return super.visitCall(call);
}
}
};
int aggCallIndex = windowInputColumn;
final RelDataTypeFactory.Builder outputBuilder = cluster.getTypeFactory().builder();
outputBuilder.addAll(projectBelowWindow.getRowType().getFieldList());
for (Window.Group group : window.groups) {
final ImmutableBitSet.Builder keys = ImmutableBitSet.builder();
final List<RelFieldCollation> orderKeys = new ArrayList<>();
final List<Window.RexWinAggCall> aggCalls = new ArrayList<>();
// Adjust keys
for (int index : group.keys) {
keys.set(getAdjustedIndex(index, beReferred, windowInputColumn));
}
// Adjust orderKeys
for (RelFieldCollation relFieldCollation : group.orderKeys.getFieldCollations()) {
final int index = relFieldCollation.getFieldIndex();
orderKeys.add(relFieldCollation.copy(getAdjustedIndex(index, beReferred, windowInputColumn)));
}
// Adjust Window Functions
for (Window.RexWinAggCall rexWinAggCall : group.aggCalls) {
aggCalls.add((Window.RexWinAggCall) rexWinAggCall.accept(indexAdjustment));
final RelDataTypeField relDataTypeField = window.getRowType().getFieldList().get(aggCallIndex);
outputBuilder.add(relDataTypeField);
++aggCallIndex;
}
groups.add(new Window.Group(keys.build(), group.isRows, group.lowerBound, group.upperBound, RelCollations.of(orderKeys), aggCalls));
}
final LogicalWindow newLogicalWindow = LogicalWindow.create(window.getTraitSet(), projectBelowWindow, window.constants, outputBuilder.build(), groups);
// Modify the top LogicalProject
final List<RexNode> topProjExps = new ArrayList<>();
for (RexNode rexNode : project.getChildExps()) {
topProjExps.add(rexNode.accept(indexAdjustment));
}
final LogicalProject newTopProj = project.copy(newLogicalWindow.getTraitSet(), newLogicalWindow, topProjExps, project.getRowType());
if (ProjectRemoveRule.isTrivial(newTopProj)) {
call.transformTo(newLogicalWindow);
} else {
call.transformTo(newTopProj);
}
}
use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rel.logical.LogicalProject in project calcite by apache.
the class SemiJoinProjectTransposeRule method onMatch.
// ~ Methods ----------------------------------------------------------------
public void onMatch(RelOptRuleCall call) {
SemiJoin semiJoin = call.rel(0);
LogicalProject project = call.rel(1);
// Convert the LHS semi-join keys to reference the child projection
// expression; all projection expressions must be RexInputRefs,
// otherwise, we wouldn't have created this semi-join.
final List<Integer> newLeftKeys = new ArrayList<>();
final List<Integer> leftKeys = semiJoin.getLeftKeys();
final List<RexNode> projExprs = project.getProjects();
for (int leftKey : leftKeys) {
RexInputRef inputRef = (RexInputRef) projExprs.get(leftKey);
newLeftKeys.add(inputRef.getIndex());
}
// convert the semijoin condition to reflect the LHS with the project
// pulled up
RexNode newCondition = adjustCondition(project, semiJoin);
SemiJoin newSemiJoin = SemiJoin.create(project.getInput(), semiJoin.getRight(), newCondition, ImmutableIntList.copyOf(newLeftKeys), semiJoin.getRightKeys());
// Create the new projection. Note that the projection expressions
// are the same as the original because they only reference the LHS
// of the semijoin and the semijoin only projects out the LHS
final RelBuilder relBuilder = call.builder();
relBuilder.push(newSemiJoin);
relBuilder.project(projExprs, project.getRowType().getFieldNames());
call.transformTo(relBuilder.build());
}
use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rel.logical.LogicalProject in project calcite by apache.
the class RelOptPlanReaderTest method testTypeToClass.
@Test
public void testTypeToClass() {
RelJson relJson = new RelJson(null);
// in org.apache.calcite.rel package
assertThat(relJson.classToTypeName(LogicalProject.class), is("LogicalProject"));
assertThat(relJson.typeNameToClass("LogicalProject"), sameInstance((Class) LogicalProject.class));
// in org.apache.calcite.adapter.jdbc.JdbcRules outer class
assertThat(relJson.classToTypeName(JdbcRules.JdbcProject.class), is("JdbcProject"));
assertThat(relJson.typeNameToClass("JdbcProject"), equalTo((Class) JdbcRules.JdbcProject.class));
try {
Class clazz = relJson.typeNameToClass("NonExistentRel");
fail("expected exception, got " + clazz);
} catch (RuntimeException e) {
assertThat(e.getMessage(), is("unknown type NonExistentRel"));
}
try {
Class clazz = relJson.typeNameToClass("org.apache.calcite.rel.NonExistentRel");
fail("expected exception, got " + clazz);
} catch (RuntimeException e) {
assertThat(e.getMessage(), is("unknown type org.apache.calcite.rel.NonExistentRel"));
}
// In this class; no special treatment. Note: '$MyRel' not '.MyRel'.
assertThat(relJson.classToTypeName(MyRel.class), is("org.apache.calcite.plan.RelOptPlanReaderTest$MyRel"));
assertThat(relJson.typeNameToClass(MyRel.class.getName()), equalTo((Class) MyRel.class));
// Using canonical name (with '$'), not found
try {
Class clazz = relJson.typeNameToClass(MyRel.class.getCanonicalName());
fail("expected exception, got " + clazz);
} catch (RuntimeException e) {
assertThat(e.getMessage(), is("unknown type org.apache.calcite.plan.RelOptPlanReaderTest.MyRel"));
}
}
use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rel.logical.LogicalProject in project drill by apache.
the class DrillUnnestRule method onMatch.
@Override
public void onMatch(RelOptRuleCall call) {
final Uncollect uncollect = call.rel(0);
final LogicalProject project = call.rel(1);
RexNode projectedNode = project.getProjects().iterator().next();
if (projectedNode.getKind() != SqlKind.FIELD_ACCESS) {
return;
}
final RelTraitSet traits = uncollect.getTraitSet().plus(DrillRel.DRILL_LOGICAL);
DrillUnnestRel unnest = new DrillUnnestRel(uncollect.getCluster(), traits, uncollect.getRowType(), projectedNode);
call.transformTo(unnest);
}
use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rel.logical.LogicalProject in project samza by apache.
the class TestQueryPlanner method testRemoteJoinWithUdfAndFilterHelper.
void testRemoteJoinWithUdfAndFilterHelper(boolean enableOptimizer) throws SamzaSqlValidatorException {
Map<String, String> staticConfigs = SamzaSqlTestConfig.fetchStaticConfigsWithFactories(1);
String sql = "Insert into testavro.enrichedPageViewTopic " + "select pv.pageKey as __key__, pv.pageKey as pageKey, coalesce(null, 'N/A') as companyName," + " p.name as profileName, p.address as profileAddress " + "from testRemoteStore.Profile.`$table` as p " + "join testavro.PAGEVIEW as pv " + " on p.__key__ = BuildOutputRecord('id', pv.profileId)" + " where p.name = 'Mike' and pv.profileId = 1 and p.name = pv.pageKey";
staticConfigs.put(SamzaSqlApplicationConfig.CFG_SQL_STMT, sql);
staticConfigs.put(SamzaSqlApplicationConfig.CFG_SQL_ENABLE_PLAN_OPTIMIZER, Boolean.toString(enableOptimizer));
Config samzaConfig = new MapConfig(staticConfigs);
DslConverter dslConverter = new SamzaSqlDslConverterFactory().create(samzaConfig);
Collection<RelRoot> relRoots = dslConverter.convertDsl(sql);
/*
Query plan without optimization:
LogicalProject(__key__=[$9], pageKey=[$9], companyName=['N/A'], profileName=[$2], profileAddress=[$4])
LogicalFilter(condition=[AND(=($2, 'Mike'), =($10, 1), =($2, $9))]) ==> Only the second condition could be pushed down.
LogicalProject(__key__=[$0], id=[$1], name=[$2], companyId=[$3], address=[$4], selfEmployed=[$5],
phoneNumbers=[$6], mapValues=[$7], __key__0=[$8], pageKey=[$9], profileId=[$10])
==> ProjectMergeRule removes this redundant node.
LogicalJoin(condition=[=($0, $11)], joinType=[inner])
LogicalTableScan(table=[[testRemoteStore, Profile, $table]])
LogicalProject(__key__=[$0], pageKey=[$1], profileId=[$2], $f3=[BuildOutputRecord('id', $2)]) ==> Filter is pushed above project.
LogicalTableScan(table=[[testavro, PAGEVIEW]])
Query plan with optimization:
LogicalProject(__key__=[$9], pageKey=[$9], companyName=['N/A'], profileName=[$2], profileAddress=[$4])
LogicalFilter(condition=[AND(=($2, 'Mike'), =($2, $9))])
LogicalJoin(condition=[=($0, $11)], joinType=[inner])
LogicalTableScan(table=[[testRemoteStore, Profile, $table]])
LogicalFilter(condition=[=($2, 1)])
LogicalProject(__key__=[$0], pageKey=[$1], profileId=[$2], $f3=[BuildOutputRecord('id', $2)])
LogicalTableScan(table=[[testavro, PAGEVIEW]])
*/
assertEquals(1, relRoots.size());
RelRoot relRoot = relRoots.iterator().next();
RelNode relNode = relRoot.rel;
assertTrue(relNode instanceof LogicalProject);
relNode = relNode.getInput(0);
assertTrue(relNode instanceof LogicalFilter);
if (enableOptimizer) {
assertEquals("AND(=($2, $9), =($2, 'Mike'))", ((LogicalFilter) relNode).getCondition().toString());
} else {
assertEquals("AND(=($2, $9), =(1, $10), =($2, 'Mike'))", ((LogicalFilter) relNode).getCondition().toString());
}
relNode = relNode.getInput(0);
if (enableOptimizer) {
assertTrue(relNode instanceof LogicalJoin);
assertEquals(2, relNode.getInputs().size());
} else {
assertTrue(relNode instanceof LogicalProject);
relNode = relNode.getInput(0);
}
LogicalJoin join = (LogicalJoin) relNode;
RelNode left = join.getLeft();
RelNode right = join.getRight();
assertTrue(left instanceof LogicalTableScan);
if (enableOptimizer) {
assertTrue(right instanceof LogicalFilter);
assertEquals("=(1, $2)", ((LogicalFilter) right).getCondition().toString());
relNode = right.getInput(0);
} else {
relNode = right;
}
assertTrue(relNode instanceof LogicalProject);
relNode = relNode.getInput(0);
assertTrue(relNode instanceof LogicalTableScan);
}
Aggregations