zabetak commented on a change in pull request #2613:
URL: https://github.com/apache/calcite/pull/2613#discussion_r764397014
##########
File path: core/src/test/java/org/apache/calcite/test/RelMetadataTest.java
##########
@@ -2482,6 +2483,115 @@ private void checkPredicates(RelOptCluster cluster,
RelOptTable empTable,
assertThat(inputRef1.getIdentifier(), is(inputRef2.getIdentifier()));
}
+ @Test void testExpressionLineageComplexExpression() {
+ // empno is column 0 in catalog.sales.emp
+ // ename is column 1 in catalog.sales.emp
+ // deptno is column 7 in catalog.sales.emp
+ final RelNode rel = convertSql("select (empno = 1 or ename = 'abc') and
deptno > 1 from emp");
+ final RelMetadataQuery mq = rel.getCluster().getMetadataQuery();
+
+ final RexNode ref = RexInputRef.of(0, rel.getRowType().getFieldList());
+ final Set<RexNode> r = mq.getExpressionLineage(rel, ref);
+
+ // check '(empno = 1 or ename = 'abc') and deptno > 1'
+ assertThat(r.size(), is(1));
+ final RexNode result = r.iterator().next();
+ assertThat(result.getKind(), is(SqlKind.AND));
+ final RexCall and = (RexCall) result;
+
+ // check '(empno = 1 or ename = 'abc')'
+ assertThat(and.getOperands().size(), is(2));
+ final RexCall or = (RexCall) and.getOperands().get(0);
+ assertThat(or.getKind(), is(SqlKind.OR));
+ assertThat(or.getOperands().size(), is(2));
+
+ // check 'empno = 1'
+ final RexCall eq1 = (RexCall) or.getOperands().get(0);
+ assertThat(eq1.getKind(), is(SqlKind.EQUALS));
+ final RexTableInputRef inputRef1 = (RexTableInputRef)
eq1.getOperands().get(0);
+ assertThat(inputRef1.getQualifiedName(), is(EMP_QNAME));
+ assertThat(inputRef1.getIndex(), is(0));
+ final RexLiteral literal1 = (RexLiteral) eq1.getOperands().get(1);
+ assertThat(literal1.getValueAs(Integer.class), is(1));
+
+ // check 'ename = 'abc''
+ final RexCall eq2 = (RexCall) or.getOperands().get(1);
+ assertThat(eq2.getKind(), is(SqlKind.EQUALS));
+ final RexTableInputRef inputRef2 = (RexTableInputRef)
eq2.getOperands().get(0);
+ assertThat(inputRef2.getQualifiedName(), is(EMP_QNAME));
+ assertThat(inputRef2.getIndex(), is(1));
+ final RexLiteral literal2 = (RexLiteral) eq2.getOperands().get(1);
+ assertThat(literal2.getValueAs(String.class), is("abc"));
+
+ // check 'deptno > 1'
+ final RexCall gt = (RexCall) and.getOperands().get(1);
+ assertThat(gt.getKind(), is(SqlKind.GREATER_THAN));
+ final RexTableInputRef inputRef3 = (RexTableInputRef)
gt.getOperands().get(0);
+ assertThat(inputRef3.getQualifiedName(), is(EMP_QNAME));
+ assertThat(inputRef3.getIndex(), is(7));
+ final RexLiteral literal3 = (RexLiteral) gt.getOperands().get(1);
+ assertThat(literal3.getValueAs(Integer.class), is(1));
Review comment:
I know that you are following the style of previous tests in this class
and that is good but I find a bit verbose for what we really need. Instead of
having 17 `assertThat` can't we just have only one based on the string
representation of the expression?
Something like the following:
```
String actualExp = r.iterator().next().toString();
assertEquals("AND([CATALOG, SALES, EMP].#0.$0...", actualExp);
```
What do you think?
##########
File path:
core/src/main/java/org/apache/calcite/rel/metadata/RelMdExpressionLineage.java
##########
@@ -493,9 +493,8 @@ private static void createExpressions(RexBuilder rexBuilder,
Map<RexInputRef, RexNode> singleMapping, Set<RexNode> result) {
if (mapping.isEmpty()) {
final RexReplacer replacer = new RexReplacer(singleMapping);
- final List<RexNode> updatedPreds = new ArrayList<>(
- RelOptUtil.conjunctions(
- rexBuilder.copy(expr)));
+ final List<RexNode> updatedPreds = new ArrayList<>();
+ updatedPreds.add(rexBuilder.copy(expr));
Review comment:
Micro optim, probably insignificant but since the list is always gonna
have one element so let's keep it like that:
```suggestion
final List<RexNode> updatedPreds = new ArrayList<>(1);
updatedPreds.add(rexBuilder.copy(expr));
```
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]