summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/main/table_value_constr.result35
-rw-r--r--mysql-test/main/table_value_constr.test21
-rw-r--r--sql/sql_yacc.yy42
-rw-r--r--sql/sql_yacc_ora.yy42
4 files changed, 138 insertions, 2 deletions
diff --git a/mysql-test/main/table_value_constr.result b/mysql-test/main/table_value_constr.result
index b0b0fa81664..1d485af4a4d 100644
--- a/mysql-test/main/table_value_constr.result
+++ b/mysql-test/main/table_value_constr.result
@@ -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;
diff --git a/mysql-test/main/table_value_constr.test b/mysql-test/main/table_value_constr.test
index eb30f00fa91..5df40d1047c 100644
--- a/mysql-test/main/table_value_constr.test
+++ b/mysql-test/main/table_value_constr.test
@@ -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;
+
+
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index f915895a260..1ec731781a5 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -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
@@ -13247,7 +13248,7 @@ insert_values:
values_list:
values_list ',' no_braces
- | no_braces
+ | no_braces_with_names
;
ident_eq_list:
@@ -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
{
@@ -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
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