diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2019-08-21 15:23:45 +0300 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2019-08-21 15:23:45 +0300 |
commit | 32ec5fb979760ba2db52d8afc39e8e090cf80a9c (patch) | |
tree | 354038721b2f99c9834c31c4a6f3a5fa23c21341 /sql/sql_parse.cc | |
parent | e8de75db88acdf228237fbebad7f4c8f05e5cc1f (diff) | |
parent | 9de2e60d7491fcf3cd1f20a4be715ef0bedc316f (diff) | |
download | mariadb-git-32ec5fb979760ba2db52d8afc39e8e090cf80a9c.tar.gz |
Merge 10.2 into 10.3
Diffstat (limited to 'sql/sql_parse.cc')
-rw-r--r-- | sql/sql_parse.cc | 103 |
1 files changed, 75 insertions, 28 deletions
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 9bd2e6040f0..022c6519a8a 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -8248,10 +8248,6 @@ TABLE_LIST *st_select_lex::nest_last_join(THD *thd) TABLE_LIST *head= join_list->head(); if (head->nested_join && head->nested_join->nest_type & REBALANCED_NEST) { - List_iterator<TABLE_LIST> li(*join_list); - li++; - while (li++) - li.remove(); DBUG_RETURN(head); } if (unlikely(!(ptr= (TABLE_LIST*) thd->calloc(ALIGN_SIZE(sizeof(TABLE_LIST))+ @@ -8335,13 +8331,13 @@ void st_select_lex::add_joined_table(TABLE_LIST *table) context and right-associative in another context. In this query - SELECT * FROM t1 JOIN t2 LEFT JOIN t3 ON t2.a=t3.a (Q1) + SELECT * FROM t1 JOIN t2 LEFT JOIN t3 ON t2.a=t3.a (Q1) JOIN is left-associative and the query Q1 is interpreted as - SELECT * FROM (t1 JOIN t2) LEFT JOIN t3 ON t2.a=t3.a. + SELECT * FROM (t1 JOIN t2) LEFT JOIN t3 ON t2.a=t3.a. While in this query - SELECT * FROM t1 JOIN t2 LEFT JOIN t3 ON t2.a=t3.a ON t1.b=t2.b (Q2) + SELECT * FROM t1 JOIN t2 LEFT JOIN t3 ON t2.a=t3.a ON t1.b=t2.b (Q2) JOIN is right-associative and the query Q2 is interpreted as - SELECT * FROM t1 JOIN (t2 LEFT JOIN t3 ON t2.a=t3.a) ON t1.b=t2.b + SELECT * FROM t1 JOIN (t2 LEFT JOIN t3 ON t2.a=t3.a) ON t1.b=t2.b JOIN is right-associative if it is used with ON clause or with USING clause. Otherwise it is left-associative. @@ -8387,9 +8383,9 @@ void st_select_lex::add_joined_table(TABLE_LIST *table) J LJ - ON / \ / \ - t1 LJ - ON (TQ3*) => J t2 - / \ / \ - t3 t2 t1 t3 + t1 LJ - ON (TQ3*) => t3 J + / \ / \ + t3 t2 t1 t2 With several left associative JOINs SELECT * FROM t1 JOIN t2 JOIN t3 LEFT JOIN t4 ON t3.a=t4.a (Q4) @@ -8397,15 +8393,15 @@ void st_select_lex::add_joined_table(TABLE_LIST *table) J1 LJ - ON / \ / \ - t1 LJ - ON J2 t4 + t1 J2 J2 t4 / \ => / \ - J2 t4 J1 t3 - / \ / \ - t2 t3 t1 t2 + t2 LJ - ON J1 t3 + / \ / \ + t3 t4 t1 t2 - Here's another example: - SELECT * - FROM t1 JOIN t2 LEFT JOIN t3 JOIN t4 ON t3.a=t4.a ON t2.b=t3.b (Q5) + Here's another example: + SELECT * + FROM t1 JOIN t2 LEFT JOIN t3 JOIN t4 ON t3.a=t4.a ON t2.b=t3.b (Q5) J LJ - ON / \ / \ @@ -8415,15 +8411,58 @@ void st_select_lex::add_joined_table(TABLE_LIST *table) / \ t3 t4 - If the transformed nested join node node is a natural join node like in - the following query - SELECT * FROM t1 JOIN t2 LEFT JOIN t3 USING(a) (Q6) - the transformation additionally has to take care about setting proper - references in the field natural_join for both operands of the natural - join operation. - The function also has to change the name resolution context for ON - expressions used in the transformed join expression to take into - account the tables of the left_op node. + If the transformed nested join node node is a natural join node like in + the following query + SELECT * FROM t1 JOIN t2 LEFT JOIN t3 USING(a) (Q6) + the transformation additionally has to take care about setting proper + references in the field natural_join for both operands of the natural + join operation. + + The queries that combine comma syntax for join operation with + JOIN expression require a special care. Consider the query + SELECT * FROM t1, t2 JOIN t3 LEFT JOIN t4 ON t3.a=t4.a (Q7) + This query is equivalent to the query + SELECT * FROM (t1, t2) JOIN t3 LEFT JOIN t4 ON t3.a=t4.a + The latter is transformed in the same way as query Q1 + + J LJ - ON + / \ / \ + (t1,t2) LJ - ON => J t4 + / \ / \ + t3 t4 (t1,t2) t3 + + A transformation similar to the transformation for Q3 is done for + the following query with RIGHT JOIN + SELECT * FROM t1, t2 JOIN t3 RIGHT JOIN t4 ON t3.a=t4.a (Q8) + + J LJ - ON + / \ / \ + t3 LJ - ON => t4 J + / \ / \ + t4 (t1,t2) (t1,t2) t3 + + The function also has to change the name resolution context for ON + expressions used in the transformed join expression to take into + account the tables of the left_op node. + + TODO: + A more elegant solution would be to implement the transformation that + eliminates nests for cross join operations. For Q7 it would work like this: + + J LJ - ON + / \ / \ + (t1,t2) LJ - ON => (t1,t2,t3) t4 + / \ + t3 t4 + + For Q8 with RIGHT JOIN the transformation would work similarly: + + J LJ - ON + / \ / \ + t3 LJ - ON => t4 (t1,t2,t3) + / \ + t4 (t1,t2) + */ bool st_select_lex::add_cross_joined_table(TABLE_LIST *left_op, @@ -8446,7 +8485,11 @@ bool st_select_lex::add_cross_joined_table(TABLE_LIST *left_op, } TABLE_LIST *tbl; - List<TABLE_LIST> *jl= &right_op->nested_join->join_list; + List<TABLE_LIST> *right_op_jl= right_op->join_list; + TABLE_LIST *r_tbl= right_op_jl->pop(); + DBUG_ASSERT(right_op == r_tbl); + TABLE_LIST *l_tbl= right_op_jl->pop(); + DBUG_ASSERT(left_op == l_tbl); TABLE_LIST *cj_nest; /* @@ -8463,6 +8506,8 @@ bool st_select_lex::add_cross_joined_table(TABLE_LIST *left_op, List<TABLE_LIST> *cjl= &cj_nest->nested_join->join_list; cjl->empty(); + List<TABLE_LIST> *jl= &right_op->nested_join->join_list; + DBUG_ASSERT(jl->elements == 2); /* Look for the left most node tbl of the right_op tree */ for ( ; ; ) { @@ -8535,6 +8580,8 @@ bool st_select_lex::add_cross_joined_table(TABLE_LIST *left_op, create a new top level nested join node. */ right_op->nested_join->nest_type|= REBALANCED_NEST; + if (unlikely(right_op_jl->push_front(right_op))) + DBUG_RETURN(true); DBUG_RETURN(false); } |