Commit 4a8d3771 authored by Igor Babaev's avatar Igor Babaev

Fixed bug mdev-10058.

This was a bug in the parser. As a result it could accept queries
with invalid derived tables if they used With clauses.
parent b7994495
......@@ -759,3 +759,20 @@ a
30
drop view v1;
drop table t1;
#
# Bug mdev-10058: Invalid derived table with WITH clause
#
CREATE TABLE t1 (a INT);
CREATE TABLE t2 (a INT);
CREATE TABLE t3 (a INT);
INSERT INTO t1 VALUES (1),(2),(3);
INSERT INTO t2 VALUES (1),(2),(3);
INSERT INTO t3 VALUES (1),(2),(3);
SELECT * FROM (WITH a AS (SELECT * FROM t1) (t2 NATURAL JOIN t3));
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 't2 NATURAL JOIN t3))' at line 1
SELECT * FROM (WITH a AS (SELECT * FROM t1) SELECT * FROM t2 NATURAL JOIN t3) AS d1;
a
1
2
3
DROP TABLE t1,t2,t3;
......@@ -448,3 +448,22 @@ with t1 as (select * from v1) select * from t1;
drop view v1;
drop table t1;
--echo #
--echo # Bug mdev-10058: Invalid derived table with WITH clause
--echo #
CREATE TABLE t1 (a INT);
CREATE TABLE t2 (a INT);
CREATE TABLE t3 (a INT);
INSERT INTO t1 VALUES (1),(2),(3);
INSERT INTO t2 VALUES (1),(2),(3);
INSERT INTO t3 VALUES (1),(2),(3);
--ERROR ER_PARSE_ERROR
SELECT * FROM (WITH a AS (SELECT * FROM t1) (t2 NATURAL JOIN t3));
SELECT * FROM (WITH a AS (SELECT * FROM t1) SELECT * FROM t2 NATURAL JOIN t3) AS d1;
DROP TABLE t1,t2,t3;
......@@ -11018,20 +11018,20 @@ table_factor:
and our parser. Possibly this rule could be replaced by our
query_expression_body.
*/
| '('opt_with_clause get_select_lex select_derived_union ')' opt_table_alias
| '(' get_select_lex select_derived_union ')' opt_table_alias
{
/* Use $3 instead of Lex->current_select as derived table will
/* Use $2 instead of Lex->current_select as derived table will
alter value of Lex->current_select. */
if (!($4 || $6) && $3->embedding &&
!$3->embedding->nested_join->join_list.elements)
if (!($3 || $5) && $2->embedding &&
!$2->embedding->nested_join->join_list.elements)
{
/* we have a derived table ($4 == NULL) but no alias,
/* we have a derived table ($3 == NULL) but no alias,
Since we are nested in further parentheses so we
can pass NULL to the outer level parentheses
Permits parsing of "((((select ...))) as xyz)" */
$$= 0;
}
else if (!$4)
else if (!$3)
{
/* Handle case of derived table, alias may be NULL if there
are no outer parentheses, add_table_to_list() will throw
......@@ -11039,13 +11039,12 @@ table_factor:
LEX *lex=Lex;
SELECT_LEX *sel= lex->current_select;
SELECT_LEX_UNIT *unit= sel->master_unit();
unit->set_with_clause($2);
lex->current_select= sel= unit->outer_select();
Table_ident *ti= new (thd->mem_root) Table_ident(unit);
if (ti == NULL)
MYSQL_YYABORT;
if (!($$= sel->add_table_to_list(lex->thd,
ti, $6, 0,
ti, $5, 0,
TL_READ, MDL_SHARED_READ)))
MYSQL_YYABORT;
......@@ -11053,11 +11052,11 @@ table_factor:
lex->pop_context();
lex->nest_level--;
}
/*else if (($4->select_lex &&
$4->select_lex->master_unit()->is_union() &&
($4->select_lex->master_unit()->first_select() ==
$4->select_lex || !$4->lifted)) || $6)*/
else if ($6 != NULL)
/*else if (($3->select_lex &&
$3->select_lex->master_unit()->is_union() &&
($3->select_lex->master_unit()->first_select() ==
$3->select_lex || !$3->lifted)) || $5)*/
else if ($5 != NULL)
{
/*
Tables with or without joins within parentheses cannot
......@@ -11070,7 +11069,7 @@ table_factor:
{
/* nested join: FROM (t1 JOIN t2 ...),
nest_level is the same as in the outer query */
$$= $4;
$$= $3;
}
/*
Fields in derived table can be used in upper select in
......@@ -11082,6 +11081,26 @@ table_factor:
!$$->derived->first_select()->next_select())
$$->select_lex->add_where_field($$->derived->first_select());
}
/* Represents derived table with WITH clause */
| '(' get_select_lex subselect_start
with_clause query_expression_body
subselect_end ')' opt_table_alias
{
LEX *lex=Lex;
SELECT_LEX *sel= $2;
SELECT_LEX_UNIT *unit= $5->master_unit();
Table_ident *ti= new (thd->mem_root) Table_ident(unit);
if (ti == NULL)
MYSQL_YYABORT;
$5->set_with_clause($4);
lex->current_select= sel;
if (!($$= sel->add_table_to_list(lex->thd,
ti, $8, 0,
TL_READ, MDL_SHARED_READ)))
MYSQL_YYABORT;
sel->add_joined_table($$);
}
;
/*
......@@ -14014,7 +14033,6 @@ opt_with_clause:
| with_clause
{
$$= $1;
Lex->derived_tables|= DERIVED_WITH;
}
;
......@@ -14026,6 +14044,7 @@ with_clause:
new With_clause($2, Lex->curr_with_clause);
if (with_clause == NULL)
MYSQL_YYABORT;
Lex->derived_tables|= DERIVED_WITH;
Lex->curr_with_clause= with_clause;
with_clause->add_to_list(Lex->with_clauses_list_last_next);
}
......
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