SimonAlexs created CALCITE-6167:
-----------------------------------

             Summary: JoinConditionPushRule shouldn't push 'exists' with other 
table conditions down
                 Key: CALCITE-6167
                 URL: https://issues.apache.org/jira/browse/CALCITE-6167
             Project: Calcite
          Issue Type: Bug
          Components: core
    Affects Versions: 1.36.0
            Reporter: SimonAlexs


{code:java}
SELECT * 
from (select 1 a, 2 b) t
left join (select 2 a, 3 b) r on exists(select 1 from (select 1 a) s where 
s.a=t.a and s.a=r.a) {code}
In this sql, the RelNode tree is as below(pay attention to the position of 
exists):

 
{code:java}
// 1: with FilterJoinRule.JoinConditionPushRule
LogicalProject(a=[$0], b=[$1], a0=[$2], b0=[$3])
  LogicalJoin(condition=[true], joinType=[left])
    LogicalValues(tuples=[[{ 1, 2 }]])
    LogicalFilter(condition=[EXISTS({
                    LogicalFilter(condition=[AND(=($0, $cor0.a), =($0, 
$cor1.a0))])
                      LogicalValues(tuples=[[{ 1 }]])
                    })])
      LogicalValues(tuples=[[{ 2, 3 }]])

// 2: normal RelNode tree, without any rule
LogicalProject(a=[$0], b=[$1], a0=[$2], b0=[$3])
  LogicalJoin(condition=[EXISTS({
                LogicalFilter(condition=[AND(=($0, $cor0.a), =($0, $cor1.a0))])
                  LogicalValues(tuples=[[{ 1 }]])
                })], joinType=[left])
    LogicalValues(tuples=[[{ 1, 2 }]])
    LogicalValues(tuples=[[{ 2, 3 }]]){code}
With JoinConditionPushRule, 'exists' is pushed down to the filter of table 
'r'.But in 'exists', it has the condition 's.a=t.a' which uses the field of 
table 't'.This 'push down' results in that we cann't get values from table 't' 
easily.

I think this may be a bug.

 

Full test code is as below.(If the full code is unnecessary, please tell me, i 
will delete it)
{code:java}
String sql = "SELECT * from (select 1 a, 2 b) t " +
        "left join (select 2 a, 3 b) r on exists(select 1 from (select 1 a) s 
where s.a=t.a and s.a=r.a) ";
Properties properties = new Properties();
properties.put(CalciteConnectionProperty.MODEL.camelName(), "inline:{\n" +
        "  \"version\": \"1.0\",\n" +
        "  \"defaultSchema\": \"ps\",\n" +
        "  \"schemas\": [ ] }");
Statement calciteStatement = DriverManager.getConnection("jdbc:calcite:", 
properties).createStatement();
CalcitePrepare.Context prepareContext = 
calciteStatement.unwrap(CalciteServerStatement.class).createPrepareContext();
final FrameworkConfig config = Frameworks.newConfigBuilder()
        .parserConfig(SqlParser.config()
                .withLex(Lex.MYSQL)
                .withConformance(SqlConformanceEnum.MYSQL_5))
        .defaultSchema(prepareContext.getRootSchema().plus())
        .build();
Planner planner = Frameworks.getPlanner(config);
SqlNode parsedSql = planner.parse(sql);
SqlNode validatedSql = planner.validate(parsedSql);
RelNode originRel = planner.rel(validatedSql).rel;
// optimize
HepProgram program = HepProgram.builder()
        .addRuleInstance(CoreRules.JOIN_CONDITION_PUSH)
        .build();
HepPlanner hepPlanner = new HepPlanner(program);
hepPlanner.setRoot(originRel);
RelNode optimizedRel = hepPlanner.findBestExp();
System.out.println(RelOptUtil.toString(optimizedRel)); {code}
 



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

Reply via email to