This is an automated email from the ASF dual-hosted git repository.
yanlin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/calcite.git
The following commit(s) were added to refs/heads/master by this push:
new 2e9edae [CALCITE-4273] Support get expression lineage for Calc
2e9edae is described below
commit 2e9edae7fc57ab9c9c7c097008724ac99a1791a3
Author: yanlin-Lynn <[email protected]>
AuthorDate: Tue Sep 22 18:02:11 2020 +0800
[CALCITE-4273] Support get expression lineage for Calc
---
.../rel/metadata/RelMdExpressionLineage.java | 31 ++++++++++++++++++++++
.../org/apache/calcite/test/RelMetadataTest.java | 21 +++++++++++++++
2 files changed, 52 insertions(+)
diff --git
a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdExpressionLineage.java
b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdExpressionLineage.java
index 41189a0..f1c97cb 100644
---
a/core/src/main/java/org/apache/calcite/rel/metadata/RelMdExpressionLineage.java
+++
b/core/src/main/java/org/apache/calcite/rel/metadata/RelMdExpressionLineage.java
@@ -21,6 +21,7 @@ import org.apache.calcite.plan.hep.HepRelVertex;
import org.apache.calcite.plan.volcano.RelSubset;
import org.apache.calcite.rel.RelNode;
import org.apache.calcite.rel.core.Aggregate;
+import org.apache.calcite.rel.core.Calc;
import org.apache.calcite.rel.core.Exchange;
import org.apache.calcite.rel.core.Filter;
import org.apache.calcite.rel.core.Join;
@@ -42,6 +43,7 @@ import org.apache.calcite.rex.RexUtil;
import org.apache.calcite.sql.validate.SqlValidatorUtil;
import org.apache.calcite.util.BuiltInMethod;
import org.apache.calcite.util.ImmutableBitSet;
+import org.apache.calcite.util.Pair;
import org.apache.calcite.util.Util;
import com.google.common.collect.HashMultimap;
@@ -407,6 +409,35 @@ public class RelMdExpressionLineage
}
/**
+ * Expression lineage from Calc.
+ */
+ public Set<RexNode> getExpressionLineage(Calc calc,
+ RelMetadataQuery mq, RexNode outputExpression) {
+ final RelNode input = calc.getInput();
+ final RexBuilder rexBuilder = calc.getCluster().getRexBuilder();
+ // Extract input fields referenced by expression
+ final ImmutableBitSet inputFieldsUsed = extractInputRefs(outputExpression);
+
+ // Infer column origin expressions for given references
+ final Map<RexInputRef, Set<RexNode>> mapping = new LinkedHashMap<>();
+ Pair<ImmutableList<RexNode>, ImmutableList<RexNode>> calcProjectsAndFilter
=
+ calc.getProgram().split();
+ for (int idx : inputFieldsUsed) {
+ final RexNode inputExpr = calcProjectsAndFilter.getKey().get(idx);
+ final Set<RexNode> originalExprs = mq.getExpressionLineage(input,
inputExpr);
+ if (originalExprs == null) {
+ // Bail out
+ return null;
+ }
+ final RexInputRef ref = RexInputRef.of(idx,
calc.getRowType().getFieldList());
+ mapping.put(ref, originalExprs);
+ }
+
+ // Return result
+ return createAllPossibleExpressions(rexBuilder, outputExpression, mapping);
+ }
+
+ /**
* Given an expression, it will create all equivalent expressions resulting
* from replacing all possible combinations of references in the mapping by
* the corresponding expressions.
diff --git a/core/src/test/java/org/apache/calcite/test/RelMetadataTest.java
b/core/src/test/java/org/apache/calcite/test/RelMetadataTest.java
index bfda204..e181a0b 100644
--- a/core/src/test/java/org/apache/calcite/test/RelMetadataTest.java
+++ b/core/src/test/java/org/apache/calcite/test/RelMetadataTest.java
@@ -2507,6 +2507,27 @@ public class RelMetadataTest extends SqlToRelTestBase {
assertNull(r);
}
+ @Test void testExpressionLineageCalc() {
+ final RelNode rel = convertSql("select sal from (\n"
+ + " select deptno, empno, sal + 1 as sal, job from emp) "
+ + "where deptno = 10");
+ final HepProgramBuilder programBuilder = HepProgram.builder();
+ programBuilder.addRuleInstance(CoreRules.PROJECT_TO_CALC);
+ programBuilder.addRuleInstance(CoreRules.FILTER_TO_CALC);
+ programBuilder.addRuleInstance(CoreRules.CALC_MERGE);
+ final HepPlanner planner = new HepPlanner(programBuilder.build());
+ planner.setRoot(rel);
+ final RelNode optimizedRel = planner.findBestExp();
+ final RelMetadataQuery mq = optimizedRel.getCluster().getMetadataQuery();
+
+ final RexNode ref = RexInputRef.of(0,
optimizedRel.getRowType().getFieldList());
+ final Set<RexNode> r = mq.getExpressionLineage(optimizedRel, ref);
+
+ assertThat(r.size(), is(1));
+ final String resultString = r.iterator().next().toString();
+ assertThat(resultString, is("+([CATALOG, SALES, EMP].#0.$5, 1)"));
+ }
+
@Test void testAllPredicates() {
final Project rel = (Project) convertSql("select * from emp, dept");
final Join join = (Join) rel.getInput();