diff options
author | Igor Babaev <igor@askmonty.org> | 2018-09-13 00:35:28 -0700 |
---|---|---|
committer | Igor Babaev <igor@askmonty.org> | 2018-09-14 18:13:16 -0700 |
commit | 3473e0452ed5edb567f49b26c9f506431e175ac4 (patch) | |
tree | dabdea5e4002d73a4ae29841973d9cad6ee8dd45 /sql/sql_prepare.cc | |
parent | 6b2da933592b54616467d08313fcb1d958fc67e4 (diff) | |
download | mariadb-git-3473e0452ed5edb567f49b26c9f506431e175ac4.tar.gz |
MDEV-17154 Multiple selects from parametrized CTE fails with syntax error
This patch fills a serious flaw in the implementation of common table
expressions. Before this patch an attempt to prepare a statement from
a query with a parameter marker in a CTE that was used more than once
in the query ended up with a bogus error message. Similarly if a statement
in a stored procedure contained a CTE whose specification used a
local variables and this CTE was referred to more than once in the
statement then the server failed to execute the stored procedure returning
a bogus error message on a non-existing field.
The problems appeared due to incorrect handling of parameter markers /
local variables in CTEs that were referred more than once.
This patch fixes the problems by differentiating between the original
occurrences of a parameter marker / local variable used in the
specification of a CTE and the corresponding occurrences used
in copies of this specification. These copies are substituted
instead of non-first references to the CTE.
The idea of the fix and even some code were taken from the MySQL
implementation of the common table expressions.
Diffstat (limited to 'sql/sql_prepare.cc')
-rw-r--r-- | sql/sql_prepare.cc | 12 |
1 files changed, 12 insertions, 0 deletions
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 0d7b0433bdd..51e9152220b 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -947,6 +947,7 @@ static bool insert_params(Prepared_statement *stmt, uchar *null_array, DBUG_RETURN(1); if (param->convert_str_value(stmt->thd)) DBUG_RETURN(1); /* out of memory */ + param->sync_clones(); } DBUG_RETURN(0); } @@ -995,6 +996,7 @@ static bool insert_bulk_params(Prepared_statement *stmt, } else DBUG_RETURN(1); // long is not supported here + param->sync_clones(); } DBUG_RETURN(0); } @@ -1023,6 +1025,7 @@ static bool set_conversion_functions(Prepared_statement *stmt, read_pos+= 2; (**it).unsigned_flag= MY_TEST(typecode & signed_bit); setup_one_conversion_function(thd, *it, (uchar) (typecode & 0xff)); + (*it)->sync_clones(); } *data= read_pos; DBUG_RETURN(0); @@ -1093,6 +1096,7 @@ static bool emb_insert_params(Prepared_statement *stmt, String *expanded_query) if (param->has_no_value()) DBUG_RETURN(1); } + param->sync_clones(); } if (param->convert_str_value(thd)) DBUG_RETURN(1); /* out of memory */ @@ -1135,6 +1139,7 @@ static bool emb_insert_params_with_log(Prepared_statement *stmt, String *query) if (param->convert_str_value(thd)) DBUG_RETURN(1); /* out of memory */ + param->sync_clones(); } if (acc.finalize()) DBUG_RETURN(1); @@ -1190,7 +1195,11 @@ swap_parameter_array(Item_param **param_array_dst, Item_param **end= param_array_dst + param_count; for (; dst < end; ++src, ++dst) + { (*dst)->set_param_type_and_swap_value(*src); + (*dst)->sync_clones(); + (*src)->sync_clones(); + } } @@ -1221,6 +1230,7 @@ insert_params_from_actual_params(Prepared_statement *stmt, if (ps_param->save_in_param(stmt->thd, param) || param->convert_str_value(stmt->thd)) DBUG_RETURN(1); + param->sync_clones(); } DBUG_RETURN(0); } @@ -1269,6 +1279,8 @@ insert_params_from_actual_params_with_log(Prepared_statement *stmt, if (param->convert_str_value(thd)) DBUG_RETURN(1); + + param->sync_clones(); } if (acc.finalize()) DBUG_RETURN(1); |