This is an automated email from the ASF dual-hosted git repository.

zabetak 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 0cb51c6  [CALCITE-2822] Allow MultiJoin rules with any project/filter 
(Siddharth Teotia)
0cb51c6 is described below

commit 0cb51c64715dd45f8bbcd533cc9096b4bb7b70af
Author: siddharth <siddha...@dremio.com>
AuthorDate: Tue Feb 5 11:01:37 2019 -0800

    [CALCITE-2822] Allow MultiJoin rules with any project/filter (Siddharth 
Teotia)
    
    Close apache/calcite#1030
---
 .../java/org/apache/calcite/plan/RelOptUtil.java   |   6 +-
 .../rel/rules/FilterMultiJoinMergeRule.java        |  27 +++-
 .../rel/rules/MultiJoinProjectTransposeRule.java   |   5 +-
 .../rel/rules/ProjectMultiJoinMergeRule.java       |  22 ++-
 .../apache/calcite/sql2rel/SqlToRelConverter.java  |   4 +-
 .../org/apache/calcite/test/RelOptRulesTest.java   | 170 ++++++++++++++++++++-
 .../org/apache/calcite/test/RelOptRulesTest.xml    |  21 +++
 7 files changed, 234 insertions(+), 21 deletions(-)

diff --git a/core/src/main/java/org/apache/calcite/plan/RelOptUtil.java 
b/core/src/main/java/org/apache/calcite/plan/RelOptUtil.java
index fc76890..452f528 100644
--- a/core/src/main/java/org/apache/calcite/plan/RelOptUtil.java
+++ b/core/src/main/java/org/apache/calcite/plan/RelOptUtil.java
@@ -2770,16 +2770,16 @@ public abstract class RelOptUtil {
   /**
    * Creates a new {@link org.apache.calcite.rel.rules.MultiJoin} to reflect
    * projection references from a
-   * {@link org.apache.calcite.rel.logical.LogicalProject} that is on top of 
the
+   * {@link Project} that is on top of the
    * {@link org.apache.calcite.rel.rules.MultiJoin}.
    *
    * @param multiJoin the original MultiJoin
-   * @param project   the LogicalProject on top of the MultiJoin
+   * @param project   the Project on top of the MultiJoin
    * @return the new MultiJoin
    */
   public static MultiJoin projectMultiJoin(
       MultiJoin multiJoin,
-      LogicalProject project) {
+      Project project) {
     // Locate all input references in the projection expressions as well
     // the post-join filter.  Since the filter effectively sits in
     // between the LogicalProject and the MultiJoin, the projection needs
diff --git 
a/core/src/main/java/org/apache/calcite/rel/rules/FilterMultiJoinMergeRule.java 
b/core/src/main/java/org/apache/calcite/rel/rules/FilterMultiJoinMergeRule.java
index ee96b90..553c4ac 100644
--- 
a/core/src/main/java/org/apache/calcite/rel/rules/FilterMultiJoinMergeRule.java
+++ 
b/core/src/main/java/org/apache/calcite/rel/rules/FilterMultiJoinMergeRule.java
@@ -18,6 +18,7 @@ package org.apache.calcite.rel.rules;
 
 import org.apache.calcite.plan.RelOptRule;
 import org.apache.calcite.plan.RelOptRuleCall;
+import org.apache.calcite.rel.core.Filter;
 import org.apache.calcite.rel.core.RelFactories;
 import org.apache.calcite.rel.logical.LogicalFilter;
 import org.apache.calcite.rex.RexBuilder;
@@ -30,8 +31,7 @@ import java.util.List;
 
 /**
  * Planner rule that merges a
- * {@link org.apache.calcite.rel.logical.LogicalFilter}
- * into a {@link MultiJoin},
+ * {@link Filter} into a {@link MultiJoin},
  * creating a richer {@code MultiJoin}.
  *
  * @see org.apache.calcite.rel.rules.ProjectMultiJoinMergeRule
@@ -43,19 +43,32 @@ public class FilterMultiJoinMergeRule extends RelOptRule {
   //~ Constructors -----------------------------------------------------------
 
   /**
-   * Creates a FilterMultiJoinMergeRule.
+   * Creates a FilterMultiJoinMergeRule that uses {@link Filter}
+   * of type {@link LogicalFilter}
+   * @param relBuilderFactory builder factory for relational expressions
    */
   public FilterMultiJoinMergeRule(RelBuilderFactory relBuilderFactory) {
+    this(LogicalFilter.class, relBuilderFactory);
+  }
+
+  /**
+   * Creates a FilterMultiJoinMergeRule that uses a generic
+   * {@link Filter}
+   * @param filterClass filter class
+   * @param relBuilderFactory builder factory for relational expressions
+   */
+  public FilterMultiJoinMergeRule(Class<? extends Filter> filterClass,
+      RelBuilderFactory relBuilderFactory) {
     super(
-        operand(LogicalFilter.class,
-            operand(MultiJoin.class, any())),
-        relBuilderFactory, null);
+      operand(filterClass,
+        operand(MultiJoin.class, any())),
+      relBuilderFactory, null);
   }
 
   //~ Methods ----------------------------------------------------------------
 
   public void onMatch(RelOptRuleCall call) {
-    LogicalFilter filter = call.rel(0);
+    Filter filter = call.rel(0);
     MultiJoin multiJoin = call.rel(1);
 
     // Create a new post-join filter condition
diff --git 
a/core/src/main/java/org/apache/calcite/rel/rules/MultiJoinProjectTransposeRule.java
 
b/core/src/main/java/org/apache/calcite/rel/rules/MultiJoinProjectTransposeRule.java
index 8579816..d87a600 100644
--- 
a/core/src/main/java/org/apache/calcite/rel/rules/MultiJoinProjectTransposeRule.java
+++ 
b/core/src/main/java/org/apache/calcite/rel/rules/MultiJoinProjectTransposeRule.java
@@ -20,6 +20,7 @@ import org.apache.calcite.plan.RelOptRuleCall;
 import org.apache.calcite.plan.RelOptRuleOperand;
 import org.apache.calcite.plan.RelOptUtil;
 import org.apache.calcite.rel.RelNode;
+import org.apache.calcite.rel.core.Project;
 import org.apache.calcite.rel.core.RelFactories;
 import org.apache.calcite.rel.logical.LogicalJoin;
 import org.apache.calcite.rel.logical.LogicalProject;
@@ -117,7 +118,7 @@ public class MultiJoinProjectTransposeRule extends 
JoinProjectTransposeRule {
   }
 
   // override JoinProjectTransposeRule
-  protected LogicalProject getRightChild(RelOptRuleCall call) {
+  protected Project getRightChild(RelOptRuleCall call) {
     if (call.rels.length == 4) {
       return call.rel(2);
     } else {
@@ -128,7 +129,7 @@ public class MultiJoinProjectTransposeRule extends 
JoinProjectTransposeRule {
   // override JoinProjectTransposeRule
   protected RelNode getProjectChild(
       RelOptRuleCall call,
-      LogicalProject project,
+      Project project,
       boolean leftChild) {
     // locate the appropriate MultiJoin based on which rule was fired
     // and which projection we're dealing with
diff --git 
a/core/src/main/java/org/apache/calcite/rel/rules/ProjectMultiJoinMergeRule.java
 
b/core/src/main/java/org/apache/calcite/rel/rules/ProjectMultiJoinMergeRule.java
index 95a568f..a36c1f6 100644
--- 
a/core/src/main/java/org/apache/calcite/rel/rules/ProjectMultiJoinMergeRule.java
+++ 
b/core/src/main/java/org/apache/calcite/rel/rules/ProjectMultiJoinMergeRule.java
@@ -19,6 +19,7 @@ package org.apache.calcite.rel.rules;
 import org.apache.calcite.plan.RelOptRule;
 import org.apache.calcite.plan.RelOptRuleCall;
 import org.apache.calcite.plan.RelOptUtil;
+import org.apache.calcite.rel.core.Project;
 import org.apache.calcite.rel.core.RelFactories;
 import org.apache.calcite.rel.logical.LogicalProject;
 import org.apache.calcite.tools.RelBuilder;
@@ -38,17 +39,34 @@ public class ProjectMultiJoinMergeRule extends RelOptRule {
 
   //~ Constructors -----------------------------------------------------------
 
-  /** Creates a ProjectMultiJoinMergeRule. */
+  /**
+   * Creates a ProjectMultiJoinMergeRule that uses {@link Project}
+   * of type {@link LogicalProject}
+   * @param relBuilderFactory builder factory for relational expressions
+   */
   public ProjectMultiJoinMergeRule(RelBuilderFactory relBuilderFactory) {
     super(
         operand(LogicalProject.class,
             operand(MultiJoin.class, any())), relBuilderFactory, null);
   }
 
+  /**
+   * Creates a ProjectMultiJoinMergeRule that uses a generic
+   * {@link Project}
+   * @param projectClass project class
+   * @param relBuilderFactory builder factory for relational expressions
+   */
+  public ProjectMultiJoinMergeRule(Class<? extends Project> projectClass,
+      RelBuilderFactory relBuilderFactory) {
+    super(
+      operand(projectClass,
+        operand(MultiJoin.class, any())), relBuilderFactory, null);
+  }
+
   //~ Methods ----------------------------------------------------------------
 
   public void onMatch(RelOptRuleCall call) {
-    LogicalProject project = call.rel(0);
+    Project project = call.rel(0);
     MultiJoin multiJoin = call.rel(1);
 
     // if all inputs have their projFields set, then projection information
diff --git 
a/core/src/main/java/org/apache/calcite/sql2rel/SqlToRelConverter.java 
b/core/src/main/java/org/apache/calcite/sql2rel/SqlToRelConverter.java
index 6e1db91..7668ee8 100644
--- a/core/src/main/java/org/apache/calcite/sql2rel/SqlToRelConverter.java
+++ b/core/src/main/java/org/apache/calcite/sql2rel/SqlToRelConverter.java
@@ -987,9 +987,9 @@ public class SqlToRelConverter {
       return;
     }
 
-    final RelFactories.FilterFactory factory =
+    final RelFactories.FilterFactory filterFactory =
         RelFactories.DEFAULT_FILTER_FACTORY;
-    final RelNode filter = factory.createFilter(bb.root, convertedWhere2);
+    final RelNode filter = filterFactory.createFilter(bb.root, 
convertedWhere2);
     final RelNode r;
     final CorrelationUse p = getCorrelationUse(bb, filter);
     if (p != null) {
diff --git a/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java 
b/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java
index 38719ce..1882ef6 100644
--- a/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java
+++ b/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java
@@ -21,10 +21,12 @@ import 
org.apache.calcite.adapter.enumerable.EnumerableRules;
 import org.apache.calcite.config.CalciteConnectionConfigImpl;
 import org.apache.calcite.plan.Context;
 import org.apache.calcite.plan.Contexts;
+import org.apache.calcite.plan.Convention;
 import org.apache.calcite.plan.ConventionTraitDef;
 import org.apache.calcite.plan.RelOptCluster;
 import org.apache.calcite.plan.RelOptPlanner;
 import org.apache.calcite.plan.RelOptRule;
+import org.apache.calcite.plan.RelOptRuleCall;
 import org.apache.calcite.plan.RelOptUtil;
 import org.apache.calcite.plan.RelTraitDef;
 import org.apache.calcite.plan.RelTraitSet;
@@ -37,6 +39,7 @@ import org.apache.calcite.prepare.Prepare;
 import org.apache.calcite.rel.RelCollation;
 import org.apache.calcite.rel.RelCollationTraitDef;
 import org.apache.calcite.rel.RelCollations;
+import org.apache.calcite.rel.RelDistributionTraitDef;
 import org.apache.calcite.rel.RelDistributions;
 import org.apache.calcite.rel.RelFieldCollation;
 import org.apache.calcite.rel.RelNode;
@@ -52,13 +55,17 @@ import org.apache.calcite.rel.core.RelFactories;
 import org.apache.calcite.rel.core.Union;
 import org.apache.calcite.rel.logical.LogicalAggregate;
 import org.apache.calcite.rel.logical.LogicalCorrelate;
+import org.apache.calcite.rel.logical.LogicalFilter;
 import org.apache.calcite.rel.logical.LogicalProject;
 import org.apache.calcite.rel.logical.LogicalTableModify;
 import org.apache.calcite.rel.logical.LogicalTableScan;
 import org.apache.calcite.rel.metadata.CachingRelMetadataProvider;
 import org.apache.calcite.rel.metadata.ChainedRelMetadataProvider;
 import org.apache.calcite.rel.metadata.DefaultRelMetadataProvider;
+import org.apache.calcite.rel.metadata.RelMdCollation;
+import org.apache.calcite.rel.metadata.RelMdDistribution;
 import org.apache.calcite.rel.metadata.RelMetadataProvider;
+import org.apache.calcite.rel.metadata.RelMetadataQuery;
 import org.apache.calcite.rel.rules.AggregateExpandDistinctAggregatesRule;
 import org.apache.calcite.rel.rules.AggregateExtractProjectRule;
 import org.apache.calcite.rel.rules.AggregateFilterTransposeRule;
@@ -128,6 +135,7 @@ import org.apache.calcite.rel.type.RelDataType;
 import org.apache.calcite.rel.type.RelDataTypeFactory;
 import org.apache.calcite.rex.RexCall;
 import org.apache.calcite.rex.RexNode;
+import org.apache.calcite.rex.RexUtil;
 import org.apache.calcite.runtime.Hook;
 import org.apache.calcite.sql.SqlKind;
 import org.apache.calcite.sql.SqlNode;
@@ -136,12 +144,15 @@ import org.apache.calcite.sql.SqlSpecialOperator;
 import org.apache.calcite.sql.fun.SqlStdOperatorTable;
 import org.apache.calcite.sql.type.ReturnTypes;
 import org.apache.calcite.sql.type.SqlTypeName;
+import org.apache.calcite.sql.validate.SqlConformanceEnum;
 import org.apache.calcite.sql.validate.SqlValidator;
+import org.apache.calcite.sql.validate.SqlValidatorUtil;
 import org.apache.calcite.sql2rel.SqlToRelConverter;
 import org.apache.calcite.test.catalog.MockCatalogReader;
 import org.apache.calcite.tools.Program;
 import org.apache.calcite.tools.Programs;
 import org.apache.calcite.tools.RelBuilder;
+import org.apache.calcite.tools.RelBuilderFactory;
 import org.apache.calcite.tools.RuleSet;
 import org.apache.calcite.tools.RuleSets;
 import org.apache.calcite.util.ImmutableBitSet;
@@ -1907,11 +1918,11 @@ public class RelOptRulesTest extends RelOptTestBase {
         .addMatchOrder(HepMatchOrder.BOTTOM_UP)
         .addRuleInstance(JoinToMultiJoinRule.INSTANCE)
         .addRuleCollection(
-            Arrays.asList(FilterMultiJoinMergeRule.INSTANCE, 
ProjectMultiJoinMergeRule.INSTANCE))
+        Arrays.asList(FilterMultiJoinMergeRule.INSTANCE, 
ProjectMultiJoinMergeRule.INSTANCE))
         .build();
     checkPlanning(program,
         "select * from (select * from emp e1 left outer join dept d on 
e1.deptno = d.deptno "
-            + "where d.deptno > 3) where ename LIKE 'bar'");
+          + "where d.deptno > 3) where ename LIKE 'bar'");
   }
 
   @Test public void testReduceConstants() throws Exception {
@@ -5404,12 +5415,12 @@ public class RelOptRulesTest extends RelOptTestBase {
     RelNode root = builder
         .scan("EMP")
         .filter(
-            builder.call(SqlStdOperatorTable.EQUALS,
-                builder.field("EMPNO"), builder.literal(10)))
+        builder.call(SqlStdOperatorTable.EQUALS,
+          builder.field("EMPNO"), builder.literal(10)))
         .exchange(RelDistributions.hash(ImmutableList.of(0)))
         .project(builder.field(0), builder.field(1))
         .sortExchange(RelDistributions.hash(ImmutableList.of(0, 1)),
-            RelCollations.of(new RelFieldCollation(0), new 
RelFieldCollation(1)))
+        RelCollations.of(new RelFieldCollation(0), new RelFieldCollation(1)))
         .build();
 
     HepProgram preProgram = new HepProgramBuilder().build();
@@ -5553,6 +5564,155 @@ public class RelOptRulesTest extends RelOptTestBase {
     String planAfter = NL + RelOptUtil.toString(relAfter);
     getDiffRepos().assertEquals("planAfter", "${planAfter}", planAfter);
   }
+
+  @Test public void testFilterAndProjectWithMultiJoin() throws Exception {
+    final Tester tester = new TesterImpl(getDiffRepos(),
+        false, false, true, false,
+        null, null, SqlToRelConverter.Config.DEFAULT,
+        SqlConformanceEnum.DEFAULT, Contexts.empty());
+
+    final HepProgram preProgram = new HepProgramBuilder()
+        .addMatchOrder(HepMatchOrder.BOTTOM_UP)
+        .addRuleCollection(Arrays.asList(MyFilterRule.INSTANCE, 
MyProjectRule.INSTANCE))
+        .build();
+
+    final FilterMultiJoinMergeRule filterMultiJoinMergeRule =
+        new FilterMultiJoinMergeRule(MyFilter.class, 
RelFactories.LOGICAL_BUILDER);
+
+    final ProjectMultiJoinMergeRule projectMultiJoinMergeRule =
+        new ProjectMultiJoinMergeRule(MyProject.class, 
RelFactories.LOGICAL_BUILDER);
+
+    HepProgram program = new HepProgramBuilder()
+        .addMatchOrder(HepMatchOrder.BOTTOM_UP)
+        .addRuleInstance(JoinToMultiJoinRule.INSTANCE)
+        .addRuleCollection(Arrays.asList(filterMultiJoinMergeRule, 
projectMultiJoinMergeRule))
+        .build();
+
+    checkPlanning(tester, preProgram, new HepPlanner(program),
+        "select * from (select * from emp e1 left outer join dept d on 
e1.deptno = d.deptno "
+            + "where d.deptno > 3)", false);
+  }
+}
+
+/**
+ * Custom implementation of {@link Filter} for use
+ * in test case to verify that {@link FilterMultiJoinMergeRule}
+ * can be created with any {@link Filter} and not limited to
+ * {@link org.apache.calcite.rel.logical.LogicalFilter}
+ */
+class MyFilter extends Filter {
+
+  MyFilter(
+      RelOptCluster cluster,
+      RelTraitSet traitSet,
+      RelNode child,
+      RexNode condition) {
+    super(cluster, traitSet, child, condition);
+  }
+
+  public MyFilter copy(RelTraitSet traitSet, RelNode input,
+      RexNode condition) {
+    return new MyFilter(getCluster(), traitSet, input, condition);
+  }
+
+  /** Creates a MyFilter. */
+  public static MyFilter create(final RelNode input, RexNode condition) {
+    final RelOptCluster cluster = input.getCluster();
+    final RelMetadataQuery mq = cluster.getMetadataQuery();
+    final RelTraitSet traitSet = cluster.traitSetOf(Convention.NONE)
+        .replaceIfs(RelCollationTraitDef.INSTANCE,
+          () -> RelMdCollation.filter(mq, input))
+        .replaceIf(RelDistributionTraitDef.INSTANCE,
+          () -> RelMdDistribution.filter(mq, input));
+    return new MyFilter(cluster, traitSet, input, condition);
+  }
+}
+
+/**
+ * Rule to transform {@link LogicalFilter} into
+ * custom MyFilter
+ */
+class MyFilterRule extends RelOptRule {
+  static final MyFilterRule INSTANCE =
+      new MyFilterRule(LogicalFilter.class, RelFactories.LOGICAL_BUILDER);
+
+  private MyFilterRule(Class<? extends Filter> clazz,
+      RelBuilderFactory relBuilderFactory) {
+    super(RelOptRule.operand(clazz, RelOptRule.any()), relBuilderFactory, 
null);
+  }
+
+  @Override public void onMatch(RelOptRuleCall call) {
+    final LogicalFilter logicalFilter = call.rel(0);
+    final MyFilter myFilter = MyFilter.create(logicalFilter.getInput(),
+        logicalFilter.getCondition());
+    call.transformTo(myFilter);
+  }
+}
+
+/**
+ * Custom implementation of {@link Project} for use
+ * in test case to verify that {@link ProjectMultiJoinMergeRule}
+ * can be created with any {@link Project} and not limited to
+ * {@link org.apache.calcite.rel.logical.LogicalProject}
+ */
+class MyProject extends Project {
+  MyProject(
+      RelOptCluster cluster,
+      RelTraitSet traitSet,
+      RelNode input,
+      List<? extends RexNode> projects,
+      RelDataType rowType) {
+    super(cluster, traitSet, input, projects, rowType);
+  }
+
+  public MyProject copy(RelTraitSet traitSet, RelNode input,
+      List<RexNode> projects, RelDataType rowType) {
+    return new MyProject(getCluster(), traitSet, input, projects, rowType);
+  }
+
+  /** Creates a MyProject. */
+  public static MyProject create(final RelNode input,
+      final List<? extends RexNode> projects, List<String> fieldNames) {
+    final RelOptCluster cluster = input.getCluster();
+    final RelDataType rowType =
+        RexUtil.createStructType(cluster.getTypeFactory(), projects,
+          fieldNames, SqlValidatorUtil.F_SUGGESTER);
+    return create(input, projects, rowType);
+  }
+
+  /** Creates a MyProject. */
+  public static MyProject create(final RelNode input,
+      final List<? extends RexNode> projects, RelDataType rowType) {
+    final RelOptCluster cluster = input.getCluster();
+    final RelMetadataQuery mq = cluster.getMetadataQuery();
+    final RelTraitSet traitSet =
+        cluster.traitSet().replace(Convention.NONE)
+          .replaceIfs(RelCollationTraitDef.INSTANCE,
+            () -> RelMdCollation.project(mq, input, projects));
+    return new MyProject(cluster, traitSet, input, projects, rowType);
+  }
+}
+
+/**
+ * Rule to transform {@link LogicalProject} into custom
+ * MyProject
+ */
+class MyProjectRule extends RelOptRule {
+  static final MyProjectRule INSTANCE =
+      new MyProjectRule(LogicalProject.class, RelFactories.LOGICAL_BUILDER);
+
+  private MyProjectRule(Class<? extends Project> clazz,
+      RelBuilderFactory relBuilderFactory) {
+    super(RelOptRule.operand(clazz, RelOptRule.any()), relBuilderFactory, 
null);
+  }
+
+  @Override public void onMatch(RelOptRuleCall call) {
+    final LogicalProject logicalProject = call.rel(0);
+    final MyProject myProject = MyProject.create(logicalProject.getInput(),
+        logicalProject.getChildExps(), logicalProject.getRowType());
+    call.transformTo(myProject);
+  }
 }
 
+
 // End RelOptRulesTest.java
diff --git 
a/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml 
b/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml
index 21f99d2..97ee0b9 100644
--- a/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml
+++ b/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml
@@ -10976,4 +10976,25 @@ EnumerableUnion(all=[true])
 ]]>
         </Resource>
     </TestCase>
+    <TestCase name="testFilterAndProjectWithMultiJoin">
+        <Resource name="sql">
+            <![CDATA[select * from (select * from emp e1 left outer join dept 
d on e1.deptno = d.deptno where d.deptno > 3) where ename LIKE 'bar']]>
+        </Resource>
+        <Resource name="planBefore">
+            <![CDATA[
+MyProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], SAL=[$5], 
COMM=[$6], DEPTNO=[$7], SLACKER=[$8], DEPTNO0=[$9], NAME=[$10])
+  MyFilter(condition=[>($9, 3)])
+    LogicalJoin(condition=[=($7, $9)], joinType=[left])
+      LogicalTableScan(table=[[CATALOG, SALES, EMP]])
+      LogicalTableScan(table=[[CATALOG, SALES, DEPT]])
+]]>
+        </Resource>
+        <Resource name="planAfter">
+            <![CDATA[
+MultiJoin(joinFilter=[true], isFullOuterJoin=[false], joinTypes=[[INNER, 
LEFT]], outerJoinConditions=[[NULL, =($7, $9)]], projFields=[[{0, 1, 2, 3, 4, 
5, 6, 7, 8}, {0, 1}]], postJoinFilter=[>($9, 3)])
+  LogicalTableScan(table=[[CATALOG, SALES, EMP]])
+  LogicalTableScan(table=[[CATALOG, SALES, DEPT]])
+]]>
+        </Resource>
+    </TestCase>
 </Root>

Reply via email to