Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
MDEV-16930 Crash when VALUES in derived table contains expressions
This patch always provides columns of the temporary table used for
materialization of a table value constructor with some names.
Before this patch these names were always borrowed from the items
of the first row of the table value constructor. When this row
contained expressions and expressions were not named then it could cause
different kinds of problems. In particular if the TVC is used as the
specification of a derived table this could cause a crash.
The names given to the expressions used in a TVC are the same as those
given to the columns of the result set from the corresponding SELECT.
  • Loading branch information
igorbabaev committed Aug 21, 2018
1 parent a1fd25c commit c43d11b
Show file tree
Hide file tree
Showing 4 changed files with 138 additions and 2 deletions.
35 changes: 35 additions & 0 deletions mysql-test/main/table_value_constr.result
Expand Up @@ -2154,3 +2154,38 @@ id select_type table type possible_keys key key_len ref rows Extra
3 UNION t1 ALL NULL NULL NULL NULL 3
NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL
drop table t1;
#
# MDEV-16930: expression in the first row of TVC specifying derived table
#
SELECT 1 + 1, 2, "abc";
1 + 1 2 abc
2 2 abc
SELECT * FROM (SELECT 1 + 1, 2, "abc") t;
1 + 1 2 abc
2 2 abc
WITH cte AS (SELECT 1 + 1, 2, "abc") SELECT * FROM cte;
1 + 1 2 abc
2 2 abc
SELECT 1 + 1, 2, "abc" UNION SELECT 3+4, 3, "abc";
1 + 1 2 abc
2 2 abc
7 3 abc
CREATE VIEW v1 AS SELECT 1 + 1, 2, "abc";
SELECT * FROM v1;
1 + 1 2 abc
2 2 abc
DROP VIEW v1;
VALUES(1 + 1,2,"abc");
1 + 1 2 abc
2 2 abc
SELECT * FROM (VALUES(1 + 1,2,"abc")) t;
1 + 1 2 abc
2 2 abc
PREPARE stmt FROM "SELECT * FROM (VALUES(1 + 1,2,'abc')) t";
EXECUTE stmt;
1 + 1 2 abc
2 2 abc
EXECUTE stmt;
1 + 1 2 abc
2 2 abc
DEALLOCATE PREPARE stmt;
21 changes: 21 additions & 0 deletions mysql-test/main/table_value_constr.test
Expand Up @@ -1104,3 +1104,24 @@ eval $q4;
eval explain $q4;

drop table t1;

--echo #
--echo # MDEV-16930: expression in the first row of TVC specifying derived table
--echo #

SELECT 1 + 1, 2, "abc";
SELECT * FROM (SELECT 1 + 1, 2, "abc") t;
WITH cte AS (SELECT 1 + 1, 2, "abc") SELECT * FROM cte;
SELECT 1 + 1, 2, "abc" UNION SELECT 3+4, 3, "abc";
CREATE VIEW v1 AS SELECT 1 + 1, 2, "abc";
SELECT * FROM v1;
DROP VIEW v1;

VALUES(1 + 1,2,"abc");
SELECT * FROM (VALUES(1 + 1,2,"abc")) t;
PREPARE stmt FROM "SELECT * FROM (VALUES(1 + 1,2,'abc')) t";
EXECUTE stmt;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;


42 changes: 41 additions & 1 deletion sql/sql_yacc.yy
Expand Up @@ -2044,6 +2044,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
preload_list preload_list_or_parts preload_keys preload_keys_parts
select_item_list select_item values_list no_braces
opt_limit_clause delete_limit_clause fields opt_values values
no_braces_with_names opt_values_with_names values_with_names
procedure_list procedure_list2 procedure_item
field_def handler opt_generated_always
opt_ignore opt_column opt_restrict
Expand Down Expand Up @@ -13247,7 +13248,7 @@ insert_values:

values_list:
values_list ',' no_braces
| no_braces
| no_braces_with_names
;

ident_eq_list:
Expand Down Expand Up @@ -13300,11 +13301,31 @@ no_braces:
}
;

no_braces_with_names:
'('
{
if (unlikely(!(Lex->insert_list= new (thd->mem_root) List_item)))
MYSQL_YYABORT;
}
opt_values_with_names ')'
{
LEX *lex=Lex;
if (unlikely(lex->many_values.push_back(lex->insert_list,
thd->mem_root)))
MYSQL_YYABORT;
}
;

opt_values:
/* empty */ {}
| values
;

opt_values_with_names:
/* empty */ {}
| values_with_names
;

values:
values ',' expr_or_default
{
Expand All @@ -13318,6 +13339,25 @@ values:
}
;

values_with_names:
values_with_names ',' remember_name expr_or_default remember_end
{
if (unlikely(Lex->insert_list->push_back($4, thd->mem_root)))
MYSQL_YYABORT;
// give some name in case of using in table value constuctor (TVC)
if (!$4->name.str)
$4->set_name(thd, $3, (uint) ($5 - $3), thd->charset());
}
| remember_name expr_or_default remember_end
{
if (unlikely(Lex->insert_list->push_back($2, thd->mem_root)))
MYSQL_YYABORT;
// give some name in case of using in table value constuctor (TVC)
if (!$2->name.str)
$2->set_name(thd, $1, (uint) ($3 - $1), thd->charset());
}
;

expr_or_default:
expr { $$= $1;}
| DEFAULT
Expand Down
42 changes: 41 additions & 1 deletion sql/sql_yacc_ora.yy
Expand Up @@ -1450,6 +1450,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
assign_to_keycache_parts
preload_list preload_list_or_parts preload_keys preload_keys_parts
select_item_list select_item values_list no_braces
no_braces_with_names opt_values_with_names values_with_names
opt_limit_clause delete_limit_clause fields opt_values values
procedure_list procedure_list2 procedure_item
field_def handler opt_generated_always
Expand Down Expand Up @@ -13402,7 +13403,7 @@ insert_values:

values_list:
values_list ',' no_braces
| no_braces
| no_braces_with_names
;

ident_eq_list:
Expand Down Expand Up @@ -13455,11 +13456,31 @@ no_braces:
}
;

no_braces_with_names:
'('
{
if (unlikely(!(Lex->insert_list= new (thd->mem_root) List_item)))
MYSQL_YYABORT;
}
opt_values_with_names ')'
{
LEX *lex=Lex;
if (unlikely(lex->many_values.push_back(lex->insert_list,
thd->mem_root)))
MYSQL_YYABORT;
}
;

opt_values:
/* empty */ {}
| values
;

opt_values_with_names:
/* empty */ {}
| values_with_names
;

values:
values ',' expr_or_default
{
Expand All @@ -13473,6 +13494,25 @@ values:
}
;

values_with_names:
values_with_names ',' remember_name expr_or_default remember_end
{
if (unlikely(Lex->insert_list->push_back($4, thd->mem_root)))
MYSQL_YYABORT;
// give some name in case of using in table value constuctor (TVC)
if (!$4->name.str)
$4->set_name(thd, $3, (uint) ($5 - $3), thd->charset());
}
| remember_name expr_or_default remember_end
{
if (unlikely(Lex->insert_list->push_back($2, thd->mem_root)))
MYSQL_YYABORT;
// give some name in case of using in table value constuctor (TVC)
if (!$2->name.str)
$2->set_name(thd, $1, (uint) ($3 - $1), thd->charset());
}
;

expr_or_default:
expr { $$= $1;}
| DEFAULT
Expand Down

0 comments on commit c43d11b

Please sign in to comment.