Rodrigo Setti created CALCITE-7846:
--------------------------------------

             Summary: Set operations on one-column table functions can throw or 
return incorrect rows
                 Key: CALCITE-7846
                 URL: https://issues.apache.org/jira/browse/CALCITE-7846
             Project: Calcite
          Issue Type: Bug
          Components: core
    Affects Versions: 1.42.0
         Environment: Calcite core and {{linq4j}} 1.42.0; Enumerable 
convention; {{{}{{EnumerableRel.Prefer.ARRAY}}{}}}. Reproduced in a Java test 
on macOS.
            Reporter: Rodrigo Setti


A one-column user-defined table function and a one-column table can use 
different Enumerable row representations. Set operations between them can throw 
a {{ClassCastException}} or return incorrect rows.

Reproducer on Calcite 1.42.0:
 * Register {{numbers_fn()}} using {{{}TableFunctionImpl{}}}. It returns a 
{{ScannableTable}}
with one {{INTEGER}} column, n, and {{Object[]}} rows [1] and [2].
 * Register numbers_table as a {{ScannableTable}} with the same row type and
{{Object[]}} rows [2] and [3].
 * Compile and execute the following query with the Enumerable convention
and {{{}EnumerableRel.Prefer.ARRAY{}}}:

 
{code:java}
SELECT n FROM TABLE(numbers_fn())
EXCEPT
SELECT n FROM numbers_table{code}
 

Expected: one row, n = 1.

Actual: execution throws
{code:java}
java.lang.ClassCastException: java.lang.Integer cannot be cast to
[Ljava.lang.Object; at
org.apache.calcite.linq4j.function.Functions$ArrayEqualityComparer.hashCode.{code}
 

The same mixed table/function shape should also yield correct results when the 
operand order is reversed, and with {{UNION}} and {{{}INTERSECT{}}}.

Suspected cause: {{EnumerableTableFunctionScan.defaultTableFunctionImplement 
}}retains {{JavaRowFormat.ARRAY}} for this non-QueryableTable function, while a 
one-column {{EnumerableTableScan}} uses scalar rows. The set-operation comparer 
then receives incompatible representations.

This is related to CALCITE-1907, which fixed a prior one-column table function 
failure affecting downstream operators. The set-operation reproducer above 
still fails on 1.42.0. As a downstream workaround, placing an identity 
{{EnumerableCalc}} immediately above the one-column 
{{EnumerableTableFunctionScan}} makes the query return the expected row.

A regression test should cover {{EXCEPT}} in both directions, {{{}UNION{}}}, and
{{INTERSECT}} with the same one-column table and function.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to