Weiqing Yang created FLINK-41449:
------------------------------------

             Summary: Two functions with the same name from different databases 
return the same result in one query
                 Key: FLINK-41449
                 URL: https://issues.apache.org/jira/browse/FLINK-41449
             Project: Flink
          Issue Type: Bug
          Components: Table SQL / Planner
    Affects Versions: 2.4.0
            Reporter: Weiqing Yang


*What happens*

When a query calls two different catalog functions that share a simple name, 
for example {{db1.f}} and {{db2.f}}, on the same arguments, both columns return 
the result of whichever function comes first.

*How to reproduce* (SQL Client, batch or streaming)

Two scalar functions:
{code:java}
public class Upper extends ScalarFunction {
    public String eval(String s) { return s == null ? null : s.toUpperCase(); }
}
public class Lower extends ScalarFunction {
    public String eval(String s) { return s == null ? null : s.toLowerCase(); }
}
{code}
{code:sql}
CREATE DATABASE db1;
CREATE DATABASE db2;
CREATE FUNCTION db1.f AS 'repro.Upper';
CREATE FUNCTION db2.f AS 'repro.Lower';
SELECT s, db1.f(s) AS upper_s, db2.f(s) AS lower_s FROM (VALUES ('Flink'), 
('Table')) AS t(s);
{code}
Actual:
{noformat}
|     s | upper_s | lower_s |
| Flink |   FLINK |   FLINK |
| Table |   TABLE |   TABLE |
{noformat}
Expected {{lower_s}} to be {{flink}} and {{table}}.

* Swapping the two columns makes both columns lower-case.
* {{db2.f(s)}} on its own returns the right value.
* The same classes registered as {{db1.g}} and {{db2.h}} return the right 
values.
* Batch and streaming mode give the same wrong result.
* {{EXPLAIN}} prints both calls as {{f(s)}}:
{noformat}
Calc(select=[s, f(s) AS EXPR$1, f(s) AS EXPR$2])
{noformat}

*Likely cause*

{{BridgingSqlFunction}} does not override {{equals}} or {{hashCode}}, so it 
inherits Calcite's {{SqlOperator#equals}}, which compares only the operator 
name and kind. The name is the function's simple name 
({{BridgingUtils#createName}}), so {{db1.f}} and {{db2.f}} are equal operators, 
{{db1.f(s)}} and {{db2.f(s)}} become equal expressions, and the planner 
evaluates one of them for both columns. Which planner step merges them is not 
yet confirmed.

Reproduced on release-2.4. {{BridgingSqlFunction}} has had this shape for 
several releases, so older versions are likely affected too.




--
This message was sent by Atlassian Jira
(v10.3.26#10030026)

Reply via email to