summaryrefslogtreecommitdiff
path: root/sql/sql_yacc_ora.yy
diff options
context:
space:
mode:
authorIgor Babaev <igor@askmonty.org>2018-08-21 12:01:25 -0700
committerIgor Babaev <igor@askmonty.org>2018-08-21 12:27:29 -0700
commitc43d11b96e27f25d248f4740a2274f1bfb1d5845 (patch)
tree0b00e9753703b2588274650ff7f00bbdbcd01839 /sql/sql_yacc_ora.yy
parenta1fd25c22bc27e58b802dd83ee48428913351180 (diff)
downloadmariadb-git-c43d11b96e27f25d248f4740a2274f1bfb1d5845.tar.gz
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.
Diffstat (limited to 'sql/sql_yacc_ora.yy')
-rw-r--r--sql/sql_yacc_ora.yy42
1 files changed, 41 insertions, 1 deletions
diff --git a/sql/sql_yacc_ora.yy b/sql/sql_yacc_ora.yy
index d95e87c524a..a6446180fc0 100644
--- a/sql/sql_yacc_ora.yy
+++ b/sql/sql_yacc_ora.yy
@@ -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
@@ -13402,7 +13403,7 @@ insert_values:
values_list:
values_list ',' no_braces
- | no_braces
+ | no_braces_with_names
;
ident_eq_list:
@@ -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
{
@@ -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