mirror of
https://github.com/MariaDB/server.git
synced 2025-07-27 18:02:13 +03:00
MDEV-20265 Unknown column in field list
This patch corrects the fix of the patch for mdev-19421 that resolved the problem of parsing some embedded join expressions such as t1 join t2 left join t3 on t2.a=t3.a on t1.a=t2.a. Yet the patch contained a bug that prevented proper context analysis of the queries where such expressions were used together with comma separated table references in from clauses.
This commit is contained in:
103
sql/sql_parse.cc
103
sql/sql_parse.cc
@ -6435,10 +6435,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);
|
||||
}
|
||||
|
||||
@ -6522,13 +6518,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.
|
||||
@ -6574,9 +6570,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)
|
||||
@ -6584,15 +6580,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
|
||||
/ \ / \
|
||||
@ -6602,15 +6598,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,
|
||||
@ -6633,7 +6672,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;
|
||||
|
||||
/*
|
||||
@ -6650,6 +6693,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 ( ; ; )
|
||||
{
|
||||
@ -6721,6 +6766,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);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user