[ 
https://issues.apache.org/jira/browse/CALCITE-7661?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Darpan Lunagariya (e6data computing) updated CALCITE-7661:
----------------------------------------------------------
    Description: 
h2. Problem

When both inputs of an inner join reference the same outer correlated field, 
{{RelDecorrelator}} can lose the relationship between those inputs.

For example:

{code:sql}
left.deptno = outer.deptno
right.deptno = outer.deptno
{code}

After decorrelation, both inputs carry a copy of {{outer.deptno}}. Those copies 
must remain equal. Currently, the inner join can lose that equality, allowing 
rows associated with different outer values to be joined.

h2. Reproducer

Using the SCOTT schema:

{code:sql}
SELECT d.deptno
FROM dept d
WHERE EXISTS (
  SELECT *
  FROM (
    SELECT *
    FROM emp e
    WHERE e.deptno = d.deptno
  ) l
  JOIN (
    SELECT *
    FROM dept d2
    WHERE d2.deptno = d.deptno
  ) r
  ON TRUE
)
{code}

h2. Incorrect plan

{code}
LogicalProject(DEPTNO=[$0])
  LogicalJoin(condition=[=($0, $3)], joinType=[inner])
    LogicalTableScan(table=[[scott, DEPT]])
    LogicalProject(DEPTNO3=[$0], $f1=[true])
      LogicalAggregate(group=[{0}])
        LogicalProject(DEPTNO3=[$12])
          LogicalJoin(condition=[true], joinType=[inner])
            LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], 
HIREDATE=[$4], SAL=[$5], COMM=[$6], DEPTNO=[$7], DEPTNO8=[$7])
              LogicalFilter(condition=[IS NOT NULL($7)])
                LogicalTableScan(table=[[scott, EMP]])
            LogicalProject(DEPTNO=[$0], DNAME=[$1], LOC=[$2], DEPTNO3=[$0])
              LogicalTableScan(table=[[scott, DEPT]])
{code}

The inner join between EMP and DEPT has {{condition=[true]}}. Only the 
DEPT-side carrier, {{$12}}, is subsequently matched with the outer 
{{d.deptno}}. The EMP-side carrier, {{$8}}, is unconstrained, so this query 
will return the department for which there are no employees, which is wrong.

The inner join should instead retain equality between the two correlation 
carriers:

{code}
LogicalJoin(
  condition=[IS NOT DISTINCT FROM($8, $12)],
  joinType=[inner])
{code}

  was:
h2. Problem

When both inputs of an inner join reference the same outer correlated field, 
{{RelDecorrelator}} can lose the relationship between those inputs.

For example:

{code:sql}
left.deptno = outer.deptno
right.deptno = outer.deptno
{code}

After decorrelation, both inputs carry a copy of {{outer.deptno}}. Those copies 
must remain equal. Currently, the inner join can lose that equality, allowing 
rows associated with different outer values to be joined.

h2. Reproducer

Using the SCOTT schema:

{code:sql}
SELECT d.deptno
FROM dept d
WHERE EXISTS (
  SELECT *
  FROM (
    SELECT *
    FROM emp e
    WHERE e.deptno = d.deptno
  ) l
  JOIN (
    SELECT *
    FROM dept d2
    WHERE d2.deptno = d.deptno
  ) r
  ON TRUE
)
{code}

Department 40 has no employees, so the original correlated query must not 
return it.

h2. Incorrect plan

{code}
LogicalProject(DEPTNO=[$0])
  LogicalJoin(condition=[=($0, $3)], joinType=[inner])
    LogicalTableScan(table=[[scott, DEPT]])
    LogicalProject(DEPTNO3=[$0], $f1=[true])
      LogicalAggregate(group=[{0}])
        LogicalProject(DEPTNO3=[$12])
          LogicalJoin(condition=[true], joinType=[inner])
            LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], 
HIREDATE=[$4], SAL=[$5], COMM=[$6], DEPTNO=[$7], DEPTNO8=[$7])
              LogicalFilter(condition=[IS NOT NULL($7)])
                LogicalTableScan(table=[[scott, EMP]])
            LogicalProject(DEPTNO=[$0], DNAME=[$1], LOC=[$2], DEPTNO3=[$0])
              LogicalTableScan(table=[[scott, DEPT]])
{code}

The inner join between EMP and DEPT has {{condition=[true]}}. Only the 
DEPT-side carrier, {{$12}}, is subsequently matched with the outer 
{{d.deptno}}. The EMP-side carrier, {{$8}}, is unconstrained, so an employee 
from another department can be joined with department 40.

The inner join should instead retain equality between the two correlation 
carriers:

{code}
LogicalJoin(
  condition=[IS NOT DISTINCT FROM($8, $12)],
  joinType=[inner])
{code}


> RelDecorrelator loses shared correlation constraint across inner join inputs
> ----------------------------------------------------------------------------
>
>                 Key: CALCITE-7661
>                 URL: https://issues.apache.org/jira/browse/CALCITE-7661
>             Project: Calcite
>          Issue Type: Bug
>          Components: core
>            Reporter: Darpan Lunagariya (e6data computing)
>            Assignee: Darpan Lunagariya (e6data computing)
>            Priority: Major
>
> h2. Problem
> When both inputs of an inner join reference the same outer correlated field, 
> {{RelDecorrelator}} can lose the relationship between those inputs.
> For example:
> {code:sql}
> left.deptno = outer.deptno
> right.deptno = outer.deptno
> {code}
> After decorrelation, both inputs carry a copy of {{outer.deptno}}. Those 
> copies must remain equal. Currently, the inner join can lose that equality, 
> allowing rows associated with different outer values to be joined.
> h2. Reproducer
> Using the SCOTT schema:
> {code:sql}
> SELECT d.deptno
> FROM dept d
> WHERE EXISTS (
>   SELECT *
>   FROM (
>     SELECT *
>     FROM emp e
>     WHERE e.deptno = d.deptno
>   ) l
>   JOIN (
>     SELECT *
>     FROM dept d2
>     WHERE d2.deptno = d.deptno
>   ) r
>   ON TRUE
> )
> {code}
> h2. Incorrect plan
> {code}
> LogicalProject(DEPTNO=[$0])
>   LogicalJoin(condition=[=($0, $3)], joinType=[inner])
>     LogicalTableScan(table=[[scott, DEPT]])
>     LogicalProject(DEPTNO3=[$0], $f1=[true])
>       LogicalAggregate(group=[{0}])
>         LogicalProject(DEPTNO3=[$12])
>           LogicalJoin(condition=[true], joinType=[inner])
>             LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], 
> HIREDATE=[$4], SAL=[$5], COMM=[$6], DEPTNO=[$7], DEPTNO8=[$7])
>               LogicalFilter(condition=[IS NOT NULL($7)])
>                 LogicalTableScan(table=[[scott, EMP]])
>             LogicalProject(DEPTNO=[$0], DNAME=[$1], LOC=[$2], DEPTNO3=[$0])
>               LogicalTableScan(table=[[scott, DEPT]])
> {code}
> The inner join between EMP and DEPT has {{condition=[true]}}. Only the 
> DEPT-side carrier, {{$12}}, is subsequently matched with the outer 
> {{d.deptno}}. The EMP-side carrier, {{$8}}, is unconstrained, so this query 
> will return the department for which there are no employees, which is wrong.
> The inner join should instead retain equality between the two correlation 
> carriers:
> {code}
> LogicalJoin(
>   condition=[IS NOT DISTINCT FROM($8, $12)],
>   joinType=[inner])
> {code}



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

Reply via email to