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 <1989yanlinw...@163.com>
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();

Reply via email to