Commit e746f451 authored by Igor Babaev's avatar Igor Babaev

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.
parent ec1f195e
......@@ -2921,5 +2921,331 @@ NULL NULL NULL 9
NULL NULL NULL 5
drop table t1,t2,t3,t4,s1,s2;
#
# MDEV-20265: Mix of comma joins with JOIN expressions
# (correction of the fix for MDEV-19421)
# MDEV-20330: duplicate
#
create table t1 (a int);
insert into t1 values (7), (5), (3);
create table t2 (a int);
insert into t2 values (5), (1), (7);
create table t3 (a int);
insert into t3 values (2), (7), (3);
create table t4 (a int);
insert into t4 values (4), (7), (9), (5);
create table t5 (a int);
insert into t5 values (3), (7), (9), (2);
explain extended select t1.a as t1_a, t2.a as t2_a, t3.a as t3_a, t4.a as t4_a
from t1, t2 join t3 left join t4 on t3.a=t4.a;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00
1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 Using join buffer (flat, BNL join)
1 SIMPLE t3 ALL NULL NULL NULL NULL 3 100.00 Using join buffer (incremental, BNL join)
1 SIMPLE t4 ALL NULL NULL NULL NULL 4 100.00 Using where; Using join buffer (incremental, BNL join)
Warnings:
Note 1003 select `test`.`t1`.`a` AS `t1_a`,`test`.`t2`.`a` AS `t2_a`,`test`.`t3`.`a` AS `t3_a`,`test`.`t4`.`a` AS `t4_a` from `test`.`t1` join `test`.`t2` join `test`.`t3` left join `test`.`t4` on((`test`.`t4`.`a` = `test`.`t3`.`a`)) where 1
select t1.a as t1_a, t2.a as t2_a, t3.a as t3_a, t4.a as t4_a
from t1, t2 join t3 left join t4 on t3.a=t4.a;
t1_a t2_a t3_a t4_a
7 5 7 7
5 5 7 7
3 5 7 7
7 1 7 7
5 1 7 7
3 1 7 7
7 7 7 7
5 7 7 7
3 7 7 7
7 5 2 NULL
5 5 2 NULL
3 5 2 NULL
7 1 2 NULL
5 1 2 NULL
3 1 2 NULL
7 7 2 NULL
5 7 2 NULL
3 7 2 NULL
7 5 3 NULL
5 5 3 NULL
3 5 3 NULL
7 1 3 NULL
5 1 3 NULL
3 1 3 NULL
7 7 3 NULL
5 7 3 NULL
3 7 3 NULL
explain extended select t1.a as t1_a, t2.a as t2_a, t3.a as t3_a, t4.a as t4_a
from t1, t2 join t3 right join t4 on t3.a=t4.a;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00
1 SIMPLE t4 ALL NULL NULL NULL NULL 4 100.00 Using join buffer (flat, BNL join)
1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 Using join buffer (incremental, BNL join)
1 SIMPLE t3 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (incremental, BNL join)
Warnings:
Note 1003 select `test`.`t1`.`a` AS `t1_a`,`test`.`t2`.`a` AS `t2_a`,`test`.`t3`.`a` AS `t3_a`,`test`.`t4`.`a` AS `t4_a` from `test`.`t1` join `test`.`t4` left join (`test`.`t2` join `test`.`t3`) on((`test`.`t3`.`a` = `test`.`t4`.`a`)) where 1
select t1.a as t1_a, t2.a as t2_a, t3.a as t3_a, t4.a as t4_a
from t1, t2 join t3 right join t4 on t3.a=t4.a;
t1_a t2_a t3_a t4_a
7 5 7 7
5 5 7 7
3 5 7 7
7 1 7 7
5 1 7 7
3 1 7 7
7 7 7 7
5 7 7 7
3 7 7 7
7 NULL NULL 4
5 NULL NULL 4
3 NULL NULL 4
7 NULL NULL 9
5 NULL NULL 9
3 NULL NULL 9
7 NULL NULL 5
5 NULL NULL 5
3 NULL NULL 5
explain extended select t1.a as t1_a, t2.a as t2_a, t3.a as t3_a, t4.a as t4_a, t5.a as t5_a
from t1, t2 join t3 join t4 left join t5 on t4.a=t5.a;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00
1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 Using join buffer (flat, BNL join)
1 SIMPLE t3 ALL NULL NULL NULL NULL 3 100.00 Using join buffer (incremental, BNL join)
1 SIMPLE t4 ALL NULL NULL NULL NULL 4 100.00 Using join buffer (incremental, BNL join)
1 SIMPLE t5 ALL NULL NULL NULL NULL 4 100.00 Using where; Using join buffer (incremental, BNL join)
Warnings:
Note 1003 select `test`.`t1`.`a` AS `t1_a`,`test`.`t2`.`a` AS `t2_a`,`test`.`t3`.`a` AS `t3_a`,`test`.`t4`.`a` AS `t4_a`,`test`.`t5`.`a` AS `t5_a` from `test`.`t1` join `test`.`t2` join `test`.`t3` join `test`.`t4` left join `test`.`t5` on((`test`.`t5`.`a` = `test`.`t4`.`a`)) where 1
select t1.a as t1_a, t2.a as t2_a, t3.a as t3_a, t4.a as t4_a, t5.a as t5_a
from t1, t2 join t3 join t4 left join t5 on t4.a=t5.a;
t1_a t2_a t3_a t4_a t5_a
7 5 2 7 7
5 5 2 7 7
3 5 2 7 7
7 1 2 7 7
5 1 2 7 7
3 1 2 7 7
7 7 2 7 7
5 7 2 7 7
3 7 2 7 7
7 5 7 7 7
5 5 7 7 7
3 5 7 7 7
7 1 7 7 7
5 1 7 7 7
3 1 7 7 7
7 7 7 7 7
5 7 7 7 7
3 7 7 7 7
7 5 3 7 7
5 5 3 7 7
3 5 3 7 7
7 1 3 7 7
5 1 3 7 7
3 1 3 7 7
7 7 3 7 7
5 7 3 7 7
3 7 3 7 7
7 5 2 9 9
5 5 2 9 9
3 5 2 9 9
7 1 2 9 9
5 1 2 9 9
3 1 2 9 9
7 7 2 9 9
5 7 2 9 9
3 7 2 9 9
7 5 7 9 9
5 5 7 9 9
3 5 7 9 9
7 1 7 9 9
5 1 7 9 9
3 1 7 9 9
7 7 7 9 9
5 7 7 9 9
3 7 7 9 9
7 5 3 9 9
5 5 3 9 9
3 5 3 9 9
7 1 3 9 9
5 1 3 9 9
3 1 3 9 9
7 7 3 9 9
5 7 3 9 9
3 7 3 9 9
7 5 2 4 NULL
5 5 2 4 NULL
3 5 2 4 NULL
7 1 2 4 NULL
5 1 2 4 NULL
3 1 2 4 NULL
7 7 2 4 NULL
5 7 2 4 NULL
3 7 2 4 NULL
7 5 7 4 NULL
5 5 7 4 NULL
3 5 7 4 NULL
7 1 7 4 NULL
5 1 7 4 NULL
3 1 7 4 NULL
7 7 7 4 NULL
5 7 7 4 NULL
3 7 7 4 NULL
7 5 3 4 NULL
5 5 3 4 NULL
3 5 3 4 NULL
7 1 3 4 NULL
5 1 3 4 NULL
3 1 3 4 NULL
7 7 3 4 NULL
5 7 3 4 NULL
3 7 3 4 NULL
7 5 2 5 NULL
5 5 2 5 NULL
3 5 2 5 NULL
7 1 2 5 NULL
5 1 2 5 NULL
3 1 2 5 NULL
7 7 2 5 NULL
5 7 2 5 NULL
3 7 2 5 NULL
7 5 7 5 NULL
5 5 7 5 NULL
3 5 7 5 NULL
7 1 7 5 NULL
5 1 7 5 NULL
3 1 7 5 NULL
7 7 7 5 NULL
5 7 7 5 NULL
3 7 7 5 NULL
7 5 3 5 NULL
5 5 3 5 NULL
3 5 3 5 NULL
7 1 3 5 NULL
5 1 3 5 NULL
3 1 3 5 NULL
7 7 3 5 NULL
5 7 3 5 NULL
3 7 3 5 NULL
explain extended select t1.a as t1_a, t2.a as t2_a, t3.a as t3_a, t4.a as t4_a, t5.a as t5_a
from t1, t2 join t3 join t4 right join t5 on t4.a=t5.a;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00
1 SIMPLE t5 ALL NULL NULL NULL NULL 4 100.00 Using join buffer (flat, BNL join)
1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 Using join buffer (incremental, BNL join)
1 SIMPLE t3 ALL NULL NULL NULL NULL 3 100.00 Using join buffer (incremental, BNL join)
1 SIMPLE t4 ALL NULL NULL NULL NULL 4 100.00 Using where; Using join buffer (incremental, BNL join)
Warnings:
Note 1003 select `test`.`t1`.`a` AS `t1_a`,`test`.`t2`.`a` AS `t2_a`,`test`.`t3`.`a` AS `t3_a`,`test`.`t4`.`a` AS `t4_a`,`test`.`t5`.`a` AS `t5_a` from `test`.`t1` join `test`.`t5` left join (`test`.`t2` join `test`.`t3` join `test`.`t4`) on((`test`.`t4`.`a` = `test`.`t5`.`a`)) where 1
select t1.a as t1_a, t2.a as t2_a, t3.a as t3_a, t4.a as t4_a, t5.a as t5_a
from t1, t2 join t3 join t4 right join t5 on t4.a=t5.a;
t1_a t2_a t3_a t4_a t5_a
7 5 2 7 7
5 5 2 7 7
3 5 2 7 7
7 1 2 7 7
5 1 2 7 7
3 1 2 7 7
7 7 2 7 7
5 7 2 7 7
3 7 2 7 7
7 5 7 7 7
5 5 7 7 7
3 5 7 7 7
7 1 7 7 7
5 1 7 7 7
3 1 7 7 7
7 7 7 7 7
5 7 7 7 7
3 7 7 7 7
7 5 3 7 7
5 5 3 7 7
3 5 3 7 7
7 1 3 7 7
5 1 3 7 7
3 1 3 7 7
7 7 3 7 7
5 7 3 7 7
3 7 3 7 7
7 5 2 9 9
5 5 2 9 9
3 5 2 9 9
7 1 2 9 9
5 1 2 9 9
3 1 2 9 9
7 7 2 9 9
5 7 2 9 9
3 7 2 9 9
7 5 7 9 9
5 5 7 9 9
3 5 7 9 9
7 1 7 9 9
5 1 7 9 9
3 1 7 9 9
7 7 7 9 9
5 7 7 9 9
3 7 7 9 9
7 5 3 9 9
5 5 3 9 9
3 5 3 9 9
7 1 3 9 9
5 1 3 9 9
3 1 3 9 9
7 7 3 9 9
5 7 3 9 9
3 7 3 9 9
7 NULL NULL NULL 3
5 NULL NULL NULL 3
3 NULL NULL NULL 3
7 NULL NULL NULL 2
5 NULL NULL NULL 2
3 NULL NULL NULL 2
explain extended select t1.a as t1_a, t2.a as t2_a, t3.a as t3_a, t4.a as t4_a, t5.a as t5_a
from t1 left join t2 on t1.a=t2.a, t3 join t4 right join t5 on t4.a=t5.a;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00
1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t5 ALL NULL NULL NULL NULL 4 100.00 Using join buffer (incremental, BNL join)
1 SIMPLE t3 ALL NULL NULL NULL NULL 3 100.00 Using join buffer (incremental, BNL join)
1 SIMPLE t4 ALL NULL NULL NULL NULL 4 100.00 Using where; Using join buffer (incremental, BNL join)
Warnings:
Note 1003 select `test`.`t1`.`a` AS `t1_a`,`test`.`t2`.`a` AS `t2_a`,`test`.`t3`.`a` AS `t3_a`,`test`.`t4`.`a` AS `t4_a`,`test`.`t5`.`a` AS `t5_a` from `test`.`t1` left join `test`.`t2` on((`test`.`t2`.`a` = `test`.`t1`.`a`)) join `test`.`t5` left join (`test`.`t3` join `test`.`t4`) on((`test`.`t4`.`a` = `test`.`t5`.`a`)) where 1
select t1.a as t1_a, t2.a as t2_a, t3.a as t3_a, t4.a as t4_a, t5.a as t5_a
from t1 left join t2 on t1.a=t2.a, t3 join t4 right join t5 on t4.a=t5.a;
t1_a t2_a t3_a t4_a t5_a
5 5 2 7 7
7 7 2 7 7
3 NULL 2 7 7
5 5 7 7 7
7 7 7 7 7
3 NULL 7 7 7
5 5 3 7 7
7 7 3 7 7
3 NULL 3 7 7
5 5 2 9 9
7 7 2 9 9
3 NULL 2 9 9
5 5 7 9 9
7 7 7 9 9
3 NULL 7 9 9
5 5 3 9 9
7 7 3 9 9
3 NULL 3 9 9
5 5 NULL NULL 3
7 7 NULL NULL 3
3 NULL NULL NULL 3
5 5 NULL NULL 2
7 7 NULL NULL 2
3 NULL NULL NULL 2
drop table t1,t2,t3,t4,t5;
select a.a
from (select 1 as a) a,
(select 2 as b) b
cross join
(select 3 as c) c
left join
(select 4 as d) d
on 1;
a
1
#
# End of MariaDB 5.5 tests
#
......@@ -1613,6 +1613,65 @@ eval $q;
drop table t1,t2,t3,t4,s1,s2;
--echo #
--echo # MDEV-20265: Mix of comma joins with JOIN expressions
--echo # (correction of the fix for MDEV-19421)
--echo # MDEV-20330: duplicate
--echo #
create table t1 (a int);
insert into t1 values (7), (5), (3);
create table t2 (a int);
insert into t2 values (5), (1), (7);
create table t3 (a int);
insert into t3 values (2), (7), (3);
create table t4 (a int);
insert into t4 values (4), (7), (9), (5);
create table t5 (a int);
insert into t5 values (3), (7), (9), (2);
let $q=
select t1.a as t1_a, t2.a as t2_a, t3.a as t3_a, t4.a as t4_a
from t1, t2 join t3 left join t4 on t3.a=t4.a;
eval explain extended $q;
eval $q;
let $q=
select t1.a as t1_a, t2.a as t2_a, t3.a as t3_a, t4.a as t4_a
from t1, t2 join t3 right join t4 on t3.a=t4.a;
eval explain extended $q;
eval $q;
let $q=
select t1.a as t1_a, t2.a as t2_a, t3.a as t3_a, t4.a as t4_a, t5.a as t5_a
from t1, t2 join t3 join t4 left join t5 on t4.a=t5.a;
eval explain extended $q;
eval $q;
let $q=
select t1.a as t1_a, t2.a as t2_a, t3.a as t3_a, t4.a as t4_a, t5.a as t5_a
from t1, t2 join t3 join t4 right join t5 on t4.a=t5.a;
eval explain extended $q;
eval $q;
let $q=
select t1.a as t1_a, t2.a as t2_a, t3.a as t3_a, t4.a as t4_a, t5.a as t5_a
from t1 left join t2 on t1.a=t2.a, t3 join t4 right join t5 on t4.a=t5.a;
eval explain extended $q;
eval $q;
drop table t1,t2,t3,t4,t5;
select a.a
from (select 1 as a) a,
(select 2 as b) b
cross join
(select 3 as c) c
left join
(select 4 as d) d
on 1;
--echo #
--echo # End of MariaDB 5.5 tests
--echo #
......@@ -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);
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment