Ruben Q L created CALCITE-7140: ---------------------------------- Summary: Improve constant reduction of expressions containing SqlRowOperator Key: CALCITE-7140 URL: https://issues.apache.org/jira/browse/CALCITE-7140 Project: Calcite Issue Type: Improvement Components: core Reporter: Ruben Q L
Currently, if we have a query like this (e.g. to be included in RelOptRulesTest): {code:java} @Test void testCardinality() { final String sql = "SELECT CARDINALITY(ARRAY[1, 2])"; sql(sql).withRule(CoreRules.PROJECT_REDUCE_EXPRESSIONS).check(); } {code} It is correctly reduced as "2" by the ReduceExpressionsRule: {code:xml} <TestCase name="testCardinality"> <Resource name="sql"> <![CDATA[SELECT CARDINALITY(ARRAY[1, 2])]]> </Resource> <Resource name="planBefore"> <![CDATA[ LogicalProject(EXPR$0=[CARDINALITY(ARRAY(1, 2))]) LogicalValues(tuples=[[{ 0 }]]) ]]> </Resource> <Resource name="planAfter"> <![CDATA[ LogicalProject(EXPR$0=[2]) LogicalValues(tuples=[[{ 0 }]]) ]]> </Resource> </TestCase> {code} However, a similar query containing constant structs: {code:java} @Test void testCardinalityWithRow() { final String sql = "SELECT CARDINALITY(ARRAY[ROW(1,'a'), ROW(2,'b')])"; sql(sql).withRule(CoreRules.PROJECT_REDUCE_EXPRESSIONS).check(); } {code} Is not reduced and remains unchanged: {code:xml} <TestCase name="testCardinalityWithRow"> <Resource name="sql"> <![CDATA[SELECT CARDINALITY(ARRAY[ROW(1,'a'), ROW(2,'b')])]]> </Resource> <Resource name="planBefore"> <![CDATA[ LogicalProject(EXPR$0=[CARDINALITY(ARRAY(ROW(1, 'a'), ROW(2, 'b')))]) LogicalValues(tuples=[[{ 0 }]]) ]]> </Resource> <Resource name="planAfter"> <![CDATA[ LogicalProject(EXPR$0=[2]) LogicalValues(tuples=[[{ 0 }]]) ]]> </Resource> </TestCase> => org.opentest4j.AssertionFailedError: planAfter ==> expected: < LogicalProject(EXPR$0=[2]) LogicalValues(tuples=[[{ 0 }]]) > but was: < LogicalProject(EXPR$0=[CARDINALITY(ARRAY(ROW(1, 'a'), ROW(2, 'b')))]) LogicalValues(tuples=[[{ 0 }]]) {code} The reason is that [ReduceExpressionsRule#ReducibleExprLocator a RexCall with SqlRowOperator is considered non-constant|https://github.com/apache/calcite/blob/3ceb364c158e80c59a89137c85637ad53f4c0fab/core/src/main/java/org/apache/calcite/rel/rules/ReduceExpressionsRule.java#L1150], since the "Row operator itself can't be reduced to a literal"; however, in cases like this one, a RexCall (e.g. cardinality) containing a SqlRowOperator can be potentially reduced. -- This message was sent by Atlassian Jira (v8.20.10#820010)