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

Ruben Quesada Lopez updated CALCITE-3198:
-----------------------------------------
    Description: 
Currently, ReduceExpressionsRule.FILTER_INSTANCE can successfully reduce a 
query like this one (see RelOptRulesTest#testReduceConstantsDup):
{code}
// query:
select d.deptno from dept d where d.deptno=7 and d.deptno=8

// plan before:
LogicalProject(DEPTNO=[$0])
  LogicalFilter(condition=[AND(=($0, 7), =($0, 8))])
    LogicalTableScan(table=[[CATALOG, SALES, DEPT]])

// plan after:
LogicalProject(DEPTNO=[$0])
  LogicalValues(tuples=[[]])
{code}
As we can see, since the filter is 'always false', the 
LogicalTableScan+LogicalFilter are correctly replaced by an empty LogicalValues.

However, the same filter with a NOT expression, is not correctly simplified:
{code}
// query:
select d.deptno from dept d where not(d.deptno=7 and d.deptno=8)

// plan before:
LogicalProject(DEPTNO=[$0])
  LogicalFilter(condition=[NOT(AND(=($0, 7), =($0, 8)))])
    LogicalTableScan(table=[[CATALOG, SALES, DEPT]])

// plan after (actual, NOT distributivity for AND):
LogicalProject(DEPTNO=[$0])
  LogicalFilter(condition=[OR(<>($0, 7), <>($0, 8))])
    LogicalTableScan(table=[[CATALOG, SALES, DEPT]])

// plan after (expected, when $0's type is NOT nullable, filter removed):
LogicalProject(DEPTNO=[$0])
  LogicalTableScan(table=[[CATALOG, SALES, DEPT]])

// plan after (expected, when $0's type IS nullable, filter simplified as IS 
NOT NULL):
LogicalProject(DEPTNO=[$0])
  LogicalFilter(condition=[$0 IS NOT NULL])
    LogicalTableScan(table=[[CATALOG, SALES, DEPT]])
{code}

  was:
Currently, ReduceExpressionsRule.FILTER_INSTANCE can successfully reduce a 
query like this one (see RelOptRulesTest#testReduceConstantsDup):
{code}
// query:
select d.deptno from dept d where d.deptno=7 and d.deptno=8

// plan before:
LogicalProject(DEPTNO=[$0])
  LogicalFilter(condition=[AND(=($0, 7), =($0, 8))])
    LogicalTableScan(table=[[CATALOG, SALES, DEPT]])

// plan after:
LogicalProject(DEPTNO=[$0])
  LogicalValues(tuples=[[]])
{code}
As we can see, since the filter is 'always false', the 
LogicalTableScan+LogicalFilter are correctly replaced by an empty LogicalValues.

However, the same filter with a NOT expression, is not correctly simplified:
{code}
// query:
select d.deptno from dept d where not(d.deptno=7 and d.deptno=8)

// plan before:
LogicalProject(DEPTNO=[$0])
  LogicalFilter(condition=[NOT(AND(=($0, 7), =($0, 8)))])
    LogicalTableScan(table=[[CATALOG, SALES, DEPT]])

// plan after (actual, NOT distributivity for AND):
LogicalProject(DEPTNO=[$0])
  LogicalFilter(condition=[OR(<>($0, 7), <>($0, 8))])
    LogicalTableScan(table=[[CATALOG, SALES, DEPT]])

// plan after (expected, filter removed):
LogicalProject(DEPTNO=[$0])
  LogicalTableScan(table=[[CATALOG, SALES, DEPT]])
{code}
Since the filter is the negated of an 'always false filter' (the one used in 
the previous query), it is therefore an 'always true filter', so the expected 
behavior is that the LogicalFilter should be removed, and it is not.


> ReduceExpressionsRule.FILTER_INSTANCE does not reduce 'NOT(x=a AND x=b)'
> ------------------------------------------------------------------------
>
>                 Key: CALCITE-3198
>                 URL: https://issues.apache.org/jira/browse/CALCITE-3198
>             Project: Calcite
>          Issue Type: Bug
>    Affects Versions: 1.20.0
>            Reporter: Ruben Quesada Lopez
>            Assignee: Ruben Quesada Lopez
>            Priority: Minor
>              Labels: pull-request-available
>             Fix For: 1.21.0
>
>          Time Spent: 2h 40m
>  Remaining Estimate: 0h
>
> Currently, ReduceExpressionsRule.FILTER_INSTANCE can successfully reduce a 
> query like this one (see RelOptRulesTest#testReduceConstantsDup):
> {code}
> // query:
> select d.deptno from dept d where d.deptno=7 and d.deptno=8
> // plan before:
> LogicalProject(DEPTNO=[$0])
>   LogicalFilter(condition=[AND(=($0, 7), =($0, 8))])
>     LogicalTableScan(table=[[CATALOG, SALES, DEPT]])
> // plan after:
> LogicalProject(DEPTNO=[$0])
>   LogicalValues(tuples=[[]])
> {code}
> As we can see, since the filter is 'always false', the 
> LogicalTableScan+LogicalFilter are correctly replaced by an empty 
> LogicalValues.
> However, the same filter with a NOT expression, is not correctly simplified:
> {code}
> // query:
> select d.deptno from dept d where not(d.deptno=7 and d.deptno=8)
> // plan before:
> LogicalProject(DEPTNO=[$0])
>   LogicalFilter(condition=[NOT(AND(=($0, 7), =($0, 8)))])
>     LogicalTableScan(table=[[CATALOG, SALES, DEPT]])
> // plan after (actual, NOT distributivity for AND):
> LogicalProject(DEPTNO=[$0])
>   LogicalFilter(condition=[OR(<>($0, 7), <>($0, 8))])
>     LogicalTableScan(table=[[CATALOG, SALES, DEPT]])
> // plan after (expected, when $0's type is NOT nullable, filter removed):
> LogicalProject(DEPTNO=[$0])
>   LogicalTableScan(table=[[CATALOG, SALES, DEPT]])
> // plan after (expected, when $0's type IS nullable, filter simplified as IS 
> NOT NULL):
> LogicalProject(DEPTNO=[$0])
>   LogicalFilter(condition=[$0 IS NOT NULL])
>     LogicalTableScan(table=[[CATALOG, SALES, DEPT]])
> {code}



--
This message was sent by Atlassian JIRA
(v7.6.14#76016)

Reply via email to