diff --git a/mysql-test/r/parser.result b/mysql-test/r/parser.result index afd78561898..5ba11d75a5a 100644 --- a/mysql-test/r/parser.result +++ b/mysql-test/r/parser.result @@ -386,3 +386,104 @@ select yearweek(); ERROR 42000: Incorrect parameter count in the call to native function 'yearweek' select yearweek(1, 2, 3); ERROR 42000: Incorrect parameter count in the call to native function 'yearweek' +select abs(3); +abs(3) +3 +select abs(3 AS three); +ERROR 42000: Incorrect parameters in the call to native function 'abs' +select abs(3 three); +ERROR 42000: Incorrect parameters in the call to native function 'abs' +select abs(3 AS "three"); +ERROR 42000: Incorrect parameters in the call to native function 'abs' +select abs(3 "three"); +ERROR 42000: Incorrect parameters in the call to native function 'abs' +set @bar="bar"; +set @foobar="foobar"; +select instr("foobar", "bar"); +instr("foobar", "bar") +4 +select instr("foobar" AS p1, "bar"); +ERROR 42000: Incorrect parameters in the call to native function 'instr' +select instr("foobar" p1, "bar"); +ERROR 42000: Incorrect parameters in the call to native function 'instr' +select instr("foobar" AS "p1", "bar"); +ERROR 42000: Incorrect parameters in the call to native function 'instr' +select instr("foobar" "p1", "bar"); +instr("foobar" "p1", "bar") +4 +select instr(@foobar "p1", "bar"); +ERROR 42000: Incorrect parameters in the call to native function 'instr' +select instr("foobar", "bar" AS p2); +ERROR 42000: Incorrect parameters in the call to native function 'instr' +select instr("foobar", "bar" p2); +ERROR 42000: Incorrect parameters in the call to native function 'instr' +select instr("foobar", "bar" AS "p2"); +ERROR 42000: Incorrect parameters in the call to native function 'instr' +select instr("foobar", "bar" "p2"); +instr("foobar", "bar" "p2") +0 +select instr("foobar", @bar "p2"); +ERROR 42000: Incorrect parameters in the call to native function 'instr' +select instr("foobar" AS p1, "bar" AS p2); +ERROR 42000: Incorrect parameters in the call to native function 'instr' +select conv(255, 10, 16); +conv(255, 10, 16) +FF +select conv(255 AS p1, 10, 16); +ERROR 42000: Incorrect parameters in the call to native function 'conv' +select conv(255 p1, 10, 16); +ERROR 42000: Incorrect parameters in the call to native function 'conv' +select conv(255 AS "p1", 10, 16); +ERROR 42000: Incorrect parameters in the call to native function 'conv' +select conv(255 "p1", 10, 16); +ERROR 42000: Incorrect parameters in the call to native function 'conv' +select conv(255, 10 AS p2, 16); +ERROR 42000: Incorrect parameters in the call to native function 'conv' +select conv(255, 10 p2, 16); +ERROR 42000: Incorrect parameters in the call to native function 'conv' +select conv(255, 10 AS "p2", 16); +ERROR 42000: Incorrect parameters in the call to native function 'conv' +select conv(255, 10 "p2", 16); +ERROR 42000: Incorrect parameters in the call to native function 'conv' +select conv(255, 10, 16 AS p3); +ERROR 42000: Incorrect parameters in the call to native function 'conv' +select conv(255, 10, 16 p3); +ERROR 42000: Incorrect parameters in the call to native function 'conv' +select conv(255, 10, 16 AS "p3"); +ERROR 42000: Incorrect parameters in the call to native function 'conv' +select conv(255, 10, 16 "p3"); +ERROR 42000: Incorrect parameters in the call to native function 'conv' +select conv(255 AS p1, 10 AS p2, 16 AS p3); +ERROR 42000: Incorrect parameters in the call to native function 'conv' +select atan(10); +atan(10) +1.4711276743037 +select atan(10 AS p1); +ERROR 42000: Incorrect parameters in the call to native function 'atan' +select atan(10 p1); +ERROR 42000: Incorrect parameters in the call to native function 'atan' +select atan(10 AS "p1"); +ERROR 42000: Incorrect parameters in the call to native function 'atan' +select atan(10 "p1"); +ERROR 42000: Incorrect parameters in the call to native function 'atan' +select atan(10, 20); +atan(10, 20) +0.46364760900081 +select atan(10 AS p1, 20); +ERROR 42000: Incorrect parameters in the call to native function 'atan' +select atan(10 p1, 20); +ERROR 42000: Incorrect parameters in the call to native function 'atan' +select atan(10 AS "p1", 20); +ERROR 42000: Incorrect parameters in the call to native function 'atan' +select atan(10 "p1", 20); +ERROR 42000: Incorrect parameters in the call to native function 'atan' +select atan(10, 20 AS p2); +ERROR 42000: Incorrect parameters in the call to native function 'atan' +select atan(10, 20 p2); +ERROR 42000: Incorrect parameters in the call to native function 'atan' +select atan(10, 20 AS "p2"); +ERROR 42000: Incorrect parameters in the call to native function 'atan' +select atan(10, 20 "p2"); +ERROR 42000: Incorrect parameters in the call to native function 'atan' +select atan(10 AS p1, 20 AS p2); +ERROR 42000: Incorrect parameters in the call to native function 'atan' diff --git a/mysql-test/r/udf.result b/mysql-test/r/udf.result index 69c860d8f85..52c59e6feb0 100644 --- a/mysql-test/r/udf.result +++ b/mysql-test/r/udf.result @@ -132,9 +132,9 @@ a c 1 1 2 2 SELECT a, fn(MIN(b) xx) as c FROM t1 GROUP BY a; -ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'xx) as c FROM t1 GROUP BY a' at line 1 +ERROR 42000: Incorrect parameters in the call to stored function 'fn' SELECT myfunc_int(fn(MIN(b) xx)) as c FROM t1 GROUP BY a; -ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'xx)) as c FROM t1 GROUP BY a' at line 1 +ERROR 42000: Incorrect parameters in the call to stored function 'fn' SELECT myfunc_int(test.fn(MIN(b) xx)) as c FROM t1 GROUP BY a; ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'xx)) as c FROM t1 GROUP BY a' at line 1 SELECT myfunc_int(fn(MIN(b)) xx) as c FROM t1 GROUP BY a; @@ -185,6 +185,28 @@ DROP VIEW v1; DROP TABLE t1; DROP FUNCTION fn; End of 5.0 tests. +select myfunc_double(3); +myfunc_double(3) +51.00 +select myfunc_double(3 AS three); +myfunc_double(3 AS three) +51.00 +select myfunc_double(abs(3)); +myfunc_double(abs(3)) +51.00 +select myfunc_double(abs(3) AS named_param); +myfunc_double(abs(3) AS named_param) +51.00 +select abs(myfunc_double(3)); +abs(myfunc_double(3)) +51.00 +select abs(myfunc_double(3 AS three)); +abs(myfunc_double(3 AS three)) +51.00 +select myfunc_double(abs(3 AS wrong)); +ERROR 42000: Incorrect parameters in the call to native function 'abs' +select abs(myfunc_double(3) AS wrong); +ERROR 42000: Incorrect parameters in the call to native function 'abs' DROP FUNCTION metaphon; DROP FUNCTION myfunc_double; DROP FUNCTION myfunc_nonexist; diff --git a/mysql-test/t/parser.test b/mysql-test/t/parser.test index 11af7c691d8..63e5137b3a3 100644 --- a/mysql-test/t/parser.test +++ b/mysql-test/t/parser.test @@ -508,3 +508,113 @@ select yearweek(); -- error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT select yearweek(1, 2, 3); +# +# Bug#24736: UDF functions parsed as Stored Functions +# + +# Verify that the syntax for calling UDF : foo(expr AS param, ...) +# can not be used when calling native functions + +# Native function with 1 argument + +select abs(3); +-- error ER_WRONG_PARAMETERS_TO_NATIVE_FCT +select abs(3 AS three); +-- error ER_WRONG_PARAMETERS_TO_NATIVE_FCT +select abs(3 three); +-- error ER_WRONG_PARAMETERS_TO_NATIVE_FCT +select abs(3 AS "three"); +-- error ER_WRONG_PARAMETERS_TO_NATIVE_FCT +select abs(3 "three"); + +# Native function with 2 arguments + +set @bar="bar"; +set @foobar="foobar"; + +select instr("foobar", "bar"); +-- error ER_WRONG_PARAMETERS_TO_NATIVE_FCT +select instr("foobar" AS p1, "bar"); +-- error ER_WRONG_PARAMETERS_TO_NATIVE_FCT +select instr("foobar" p1, "bar"); +-- error ER_WRONG_PARAMETERS_TO_NATIVE_FCT +select instr("foobar" AS "p1", "bar"); +## String concatenation, valid syntax +select instr("foobar" "p1", "bar"); +-- error ER_WRONG_PARAMETERS_TO_NATIVE_FCT +select instr(@foobar "p1", "bar"); +-- error ER_WRONG_PARAMETERS_TO_NATIVE_FCT +select instr("foobar", "bar" AS p2); +-- error ER_WRONG_PARAMETERS_TO_NATIVE_FCT +select instr("foobar", "bar" p2); +-- error ER_WRONG_PARAMETERS_TO_NATIVE_FCT +select instr("foobar", "bar" AS "p2"); +## String concatenation, valid syntax +select instr("foobar", "bar" "p2"); +-- error ER_WRONG_PARAMETERS_TO_NATIVE_FCT +select instr("foobar", @bar "p2"); +-- error ER_WRONG_PARAMETERS_TO_NATIVE_FCT +select instr("foobar" AS p1, "bar" AS p2); + +# Native function with 3 arguments + +select conv(255, 10, 16); +-- error ER_WRONG_PARAMETERS_TO_NATIVE_FCT +select conv(255 AS p1, 10, 16); +-- error ER_WRONG_PARAMETERS_TO_NATIVE_FCT +select conv(255 p1, 10, 16); +-- error ER_WRONG_PARAMETERS_TO_NATIVE_FCT +select conv(255 AS "p1", 10, 16); +-- error ER_WRONG_PARAMETERS_TO_NATIVE_FCT +select conv(255 "p1", 10, 16); +-- error ER_WRONG_PARAMETERS_TO_NATIVE_FCT +select conv(255, 10 AS p2, 16); +-- error ER_WRONG_PARAMETERS_TO_NATIVE_FCT +select conv(255, 10 p2, 16); +-- error ER_WRONG_PARAMETERS_TO_NATIVE_FCT +select conv(255, 10 AS "p2", 16); +-- error ER_WRONG_PARAMETERS_TO_NATIVE_FCT +select conv(255, 10 "p2", 16); +-- error ER_WRONG_PARAMETERS_TO_NATIVE_FCT +select conv(255, 10, 16 AS p3); +-- error ER_WRONG_PARAMETERS_TO_NATIVE_FCT +select conv(255, 10, 16 p3); +-- error ER_WRONG_PARAMETERS_TO_NATIVE_FCT +select conv(255, 10, 16 AS "p3"); +-- error ER_WRONG_PARAMETERS_TO_NATIVE_FCT +select conv(255, 10, 16 "p3"); +-- error ER_WRONG_PARAMETERS_TO_NATIVE_FCT +select conv(255 AS p1, 10 AS p2, 16 AS p3); + +# Native function with a variable number of arguments + +select atan(10); +-- error ER_WRONG_PARAMETERS_TO_NATIVE_FCT +select atan(10 AS p1); +-- error ER_WRONG_PARAMETERS_TO_NATIVE_FCT +select atan(10 p1); +-- error ER_WRONG_PARAMETERS_TO_NATIVE_FCT +select atan(10 AS "p1"); +-- error ER_WRONG_PARAMETERS_TO_NATIVE_FCT +select atan(10 "p1"); + +select atan(10, 20); +-- error ER_WRONG_PARAMETERS_TO_NATIVE_FCT +select atan(10 AS p1, 20); +-- error ER_WRONG_PARAMETERS_TO_NATIVE_FCT +select atan(10 p1, 20); +-- error ER_WRONG_PARAMETERS_TO_NATIVE_FCT +select atan(10 AS "p1", 20); +-- error ER_WRONG_PARAMETERS_TO_NATIVE_FCT +select atan(10 "p1", 20); +-- error ER_WRONG_PARAMETERS_TO_NATIVE_FCT +select atan(10, 20 AS p2); +-- error ER_WRONG_PARAMETERS_TO_NATIVE_FCT +select atan(10, 20 p2); +-- error ER_WRONG_PARAMETERS_TO_NATIVE_FCT +select atan(10, 20 AS "p2"); +-- error ER_WRONG_PARAMETERS_TO_NATIVE_FCT +select atan(10, 20 "p2"); +-- error ER_WRONG_PARAMETERS_TO_NATIVE_FCT +select atan(10 AS p1, 20 AS p2); + diff --git a/mysql-test/t/udf.test b/mysql-test/t/udf.test index 52ae424e423..24ddc1d44bc 100644 --- a/mysql-test/t/udf.test +++ b/mysql-test/t/udf.test @@ -149,9 +149,9 @@ EXPLAIN EXTENDED SELECT myfunc_int(a AS attr_name) FROM t1; EXPLAIN EXTENDED SELECT myfunc_int(a) FROM t1; SELECT a,c FROM v1; ---error ER_PARSE_ERROR +--error ER_WRONG_PARAMETERS_TO_STORED_FCT SELECT a, fn(MIN(b) xx) as c FROM t1 GROUP BY a; ---error ER_PARSE_ERROR +--error ER_WRONG_PARAMETERS_TO_STORED_FCT SELECT myfunc_int(fn(MIN(b) xx)) as c FROM t1 GROUP BY a; --error ER_PARSE_ERROR SELECT myfunc_int(test.fn(MIN(b) xx)) as c FROM t1 GROUP BY a; @@ -173,6 +173,22 @@ DROP FUNCTION fn; --echo End of 5.0 tests. +# +# Bug#24736: UDF functions parsed as Stored Functions +# + +select myfunc_double(3); +select myfunc_double(3 AS three); +select myfunc_double(abs(3)); +select myfunc_double(abs(3) AS named_param); +select abs(myfunc_double(3)); +select abs(myfunc_double(3 AS three)); + +-- error ER_WRONG_PARAMETERS_TO_NATIVE_FCT +select myfunc_double(abs(3 AS wrong)); +-- error ER_WRONG_PARAMETERS_TO_NATIVE_FCT +select abs(myfunc_double(3) AS wrong); + # # Drop the example functions from udf_example # diff --git a/sql/item_create.cc b/sql/item_create.cc index 7722ce28d4a..6f77cc0fa14 100644 --- a/sql/item_create.cc +++ b/sql/item_create.cc @@ -27,6 +27,37 @@ ============================================================================= */ +/** + Adapter for native functions with a variable number of arguments. + The main use of this class is to discard the following calls: + foo(expr1 AS name1, expr2 AS name2, ...) + which are syntactically correct (the syntax can refer to a UDF), + but semantically invalid for native functions. +*/ + +class Create_native_func : public Create_func +{ +public: + virtual Item* create(THD *thd, LEX_STRING name, List *item_list); + + /** + Builder method, with no arguments. + @param thd The current thread + @param name The native function name + @param item_list The function parameters, none of which are named + @return An item representing the function call + */ + virtual Item* create_native(THD *thd, LEX_STRING name, + List *item_list) = 0; + +protected: + /** Constructor. */ + Create_native_func() {} + /** Destructor. */ + virtual ~Create_native_func() {} +}; + + /** Adapter for functions that takes exactly zero arguments. */ @@ -302,10 +333,10 @@ protected: }; -class Create_func_atan : public Create_func +class Create_func_atan : public Create_native_func { public: - virtual Item* create(THD *thd, LEX_STRING name, List *item_list); + virtual Item* create_native(THD *thd, LEX_STRING name, List *item_list); static Create_func_atan s_singleton; @@ -434,10 +465,10 @@ protected: }; -class Create_func_concat : public Create_func +class Create_func_concat : public Create_native_func { public: - virtual Item* create(THD *thd, LEX_STRING name, List *item_list); + virtual Item* create_native(THD *thd, LEX_STRING name, List *item_list); static Create_func_concat s_singleton; @@ -447,10 +478,10 @@ protected: }; -class Create_func_concat_ws : public Create_func +class Create_func_concat_ws : public Create_native_func { public: - virtual Item* create(THD *thd, LEX_STRING name, List *item_list); + virtual Item* create_native(THD *thd, LEX_STRING name, List *item_list); static Create_func_concat_ws s_singleton; @@ -672,10 +703,10 @@ protected: }; -class Create_func_des_decrypt : public Create_func +class Create_func_des_decrypt : public Create_native_func { public: - virtual Item* create(THD *thd, LEX_STRING name, List *item_list); + virtual Item* create_native(THD *thd, LEX_STRING name, List *item_list); static Create_func_des_decrypt s_singleton; @@ -685,10 +716,10 @@ protected: }; -class Create_func_des_encrypt : public Create_func +class Create_func_des_encrypt : public Create_native_func { public: - virtual Item* create(THD *thd, LEX_STRING name, List *item_list); + virtual Item* create_native(THD *thd, LEX_STRING name, List *item_list); static Create_func_des_encrypt s_singleton; @@ -728,10 +759,10 @@ protected: #endif -class Create_func_elt : public Create_func +class Create_func_elt : public Create_native_func { public: - virtual Item* create(THD *thd, LEX_STRING name, List *item_list); + virtual Item* create_native(THD *thd, LEX_STRING name, List *item_list); static Create_func_elt s_singleton; @@ -754,10 +785,10 @@ protected: }; -class Create_func_encrypt : public Create_func +class Create_func_encrypt : public Create_native_func { public: - virtual Item* create(THD *thd, LEX_STRING name, List *item_list); + virtual Item* create_native(THD *thd, LEX_STRING name, List *item_list); static Create_func_encrypt s_singleton; @@ -825,10 +856,10 @@ protected: }; -class Create_func_export_set : public Create_func +class Create_func_export_set : public Create_native_func { public: - virtual Item* create(THD *thd, LEX_STRING name, List *item_list); + virtual Item* create_native(THD *thd, LEX_STRING name, List *item_list); static Create_func_export_set s_singleton; @@ -853,10 +884,10 @@ protected: #endif -class Create_func_field : public Create_func +class Create_func_field : public Create_native_func { public: - virtual Item* create(THD *thd, LEX_STRING name, List *item_list); + virtual Item* create_native(THD *thd, LEX_STRING name, List *item_list); static Create_func_field s_singleton; @@ -931,10 +962,10 @@ protected: }; -class Create_func_from_unixtime : public Create_func +class Create_func_from_unixtime : public Create_native_func { public: - virtual Item* create(THD *thd, LEX_STRING name, List *item_list); + virtual Item* create_native(THD *thd, LEX_STRING name, List *item_list); static Create_func_from_unixtime s_singleton; @@ -945,10 +976,10 @@ protected: #ifdef HAVE_SPATIAL -class Create_func_geometry_from_text : public Create_func +class Create_func_geometry_from_text : public Create_native_func { public: - virtual Item* create(THD *thd, LEX_STRING name, List *item_list); + virtual Item* create_native(THD *thd, LEX_STRING name, List *item_list); static Create_func_geometry_from_text s_singleton; @@ -960,10 +991,10 @@ protected: #ifdef HAVE_SPATIAL -class Create_func_geometry_from_wkb : public Create_func +class Create_func_geometry_from_wkb : public Create_native_func { public: - virtual Item* create(THD *thd, LEX_STRING name, List *item_list); + virtual Item* create_native(THD *thd, LEX_STRING name, List *item_list); static Create_func_geometry_from_wkb s_singleton; @@ -1032,10 +1063,10 @@ protected: #endif -class Create_func_greatest : public Create_func +class Create_func_greatest : public Create_native_func { public: - virtual Item* create(THD *thd, LEX_STRING name, List *item_list); + virtual Item* create_native(THD *thd, LEX_STRING name, List *item_list); static Create_func_greatest s_singleton; @@ -1237,10 +1268,10 @@ protected: }; -class Create_func_last_insert_id : public Create_func +class Create_func_last_insert_id : public Create_native_func { public: - virtual Item* create(THD *thd, LEX_STRING name, List *item_list); + virtual Item* create_native(THD *thd, LEX_STRING name, List *item_list); static Create_func_last_insert_id s_singleton; @@ -1263,10 +1294,10 @@ protected: }; -class Create_func_least : public Create_func +class Create_func_least : public Create_native_func { public: - virtual Item* create(THD *thd, LEX_STRING name, List *item_list); + virtual Item* create_native(THD *thd, LEX_STRING name, List *item_list); static Create_func_least s_singleton; @@ -1315,10 +1346,10 @@ protected: }; -class Create_func_locate : public Create_func +class Create_func_locate : public Create_native_func { public: - virtual Item* create(THD *thd, LEX_STRING name, List *item_list); + virtual Item* create_native(THD *thd, LEX_STRING name, List *item_list); static Create_func_locate s_singleton; @@ -1328,10 +1359,10 @@ protected: }; -class Create_func_log : public Create_func +class Create_func_log : public Create_native_func { public: - virtual Item* create(THD *thd, LEX_STRING name, List *item_list); + virtual Item* create_native(THD *thd, LEX_STRING name, List *item_list); static Create_func_log s_singleton; @@ -1419,10 +1450,10 @@ protected: }; -class Create_func_make_set : public Create_func +class Create_func_make_set : public Create_native_func { public: - virtual Item* create(THD *thd, LEX_STRING name, List *item_list); + virtual Item* create_native(THD *thd, LEX_STRING name, List *item_list); static Create_func_make_set s_singleton; @@ -1432,10 +1463,10 @@ protected: }; -class Create_func_master_pos_wait : public Create_func +class Create_func_master_pos_wait : public Create_native_func { public: - virtual Item* create(THD *thd, LEX_STRING name, List *item_list); + virtual Item* create_native(THD *thd, LEX_STRING name, List *item_list); static Create_func_master_pos_wait s_singleton; @@ -1676,10 +1707,10 @@ protected: }; -class Create_func_rand : public Create_func +class Create_func_rand : public Create_native_func { public: - virtual Item* create(THD *thd, LEX_STRING name, List *item_list); + virtual Item* create_native(THD *thd, LEX_STRING name, List *item_list); static Create_func_rand s_singleton; @@ -1715,10 +1746,10 @@ protected: }; -class Create_func_round : public Create_func +class Create_func_round : public Create_native_func { public: - virtual Item* create(THD *thd, LEX_STRING name, List *item_list); + virtual Item* create_native(THD *thd, LEX_STRING name, List *item_list); static Create_func_round s_singleton; @@ -2085,10 +2116,10 @@ protected: }; -class Create_func_unix_timestamp : public Create_func +class Create_func_unix_timestamp : public Create_native_func { public: - virtual Item* create(THD *thd, LEX_STRING name, List *item_list); + virtual Item* create_native(THD *thd, LEX_STRING name, List *item_list); static Create_func_unix_timestamp s_singleton; @@ -2221,10 +2252,10 @@ protected: #endif -class Create_func_year_week : public Create_func +class Create_func_year_week : public Create_native_func { public: - virtual Item* create(THD *thd, LEX_STRING name, List *item_list); + virtual Item* create_native(THD *thd, LEX_STRING name, List *item_list); static Create_func_year_week s_singleton; @@ -2240,6 +2271,29 @@ protected: ============================================================================= */ +/** + Checks if there are named parameters in a parameter list. + The syntax to name parameters in a function call is as follow: + foo(expr AS named, expr named, expr AS "named", expr "named") + @param params The parameter list, can be null + @return true if one or more parameter is named +*/ +static bool has_named_parameters(List *params) +{ + if (params) + { + Item *param; + List_iterator it(*params); + while ((param= it++)) + { + if (! param->is_autogenerated_name) + return true; + } + } + + return false; +} + #ifndef HAVE_SPATIAL Create_func_no_geom Create_func_no_geom::s_singleton; @@ -2387,11 +2441,27 @@ Create_sp_func::create(THD *thd, LEX_STRING db, LEX_STRING name, int arg_count= 0; Item *func= NULL; LEX *lex= thd->lex; - sp_name *qname= new (thd->mem_root) sp_name(db, name); + sp_name *qname; + + if (has_named_parameters(item_list)) + { + /* + The syntax "db.foo(expr AS p1, expr AS p2, ...) is invalid, + and has been rejected during syntactic parsing already, + because a stored function call may not have named parameters. + + The syntax "foo(expr AS p1, expr AS p2, ...)" is correct, + because it can refer to a User Defined Function call. + For a Stored Function however, this has no semantic. + */ + my_error(ER_WRONG_PARAMETERS_TO_STORED_FCT, MYF(0), name.str); + return NULL; + } if (item_list != NULL) arg_count= item_list->elements; + qname= new (thd->mem_root) sp_name(db, name); qname->init_qname(thd); sp_add_used_routine(lex, thd, qname, TYPE_ENUM_FUNCTION); @@ -2406,6 +2476,19 @@ Create_sp_func::create(THD *thd, LEX_STRING db, LEX_STRING name, } +Item* +Create_native_func::create(THD *thd, LEX_STRING name, List *item_list) +{ + if (has_named_parameters(item_list)) + { + my_error(ER_WRONG_PARAMETERS_TO_NATIVE_FCT, MYF(0), name.str); + return NULL; + } + + return create_native(thd, name, item_list); +} + + Item* Create_func_arg0::create(THD *thd, LEX_STRING name, List *item_list) { @@ -2439,6 +2522,13 @@ Create_func_arg1::create(THD *thd, LEX_STRING name, List *item_list) } Item *param_1= item_list->pop(); + + if (! param_1->is_autogenerated_name) + { + my_error(ER_WRONG_PARAMETERS_TO_NATIVE_FCT, MYF(0), name.str); + return NULL; + } + return create(thd, param_1); } @@ -2459,6 +2549,14 @@ Create_func_arg2::create(THD *thd, LEX_STRING name, List *item_list) Item *param_1= item_list->pop(); Item *param_2= item_list->pop(); + + if ( (! param_1->is_autogenerated_name) + || (! param_2->is_autogenerated_name)) + { + my_error(ER_WRONG_PARAMETERS_TO_NATIVE_FCT, MYF(0), name.str); + return NULL; + } + return create(thd, param_1, param_2); } @@ -2480,6 +2578,15 @@ Create_func_arg3::create(THD *thd, LEX_STRING name, List *item_list) Item *param_1= item_list->pop(); Item *param_2= item_list->pop(); Item *param_3= item_list->pop(); + + if ( (! param_1->is_autogenerated_name) + || (! param_2->is_autogenerated_name) + || (! param_3->is_autogenerated_name)) + { + my_error(ER_WRONG_PARAMETERS_TO_NATIVE_FCT, MYF(0), name.str); + return NULL; + } + return create(thd, param_1, param_2, param_3); } @@ -2574,7 +2681,8 @@ Create_func_asin::create(THD *thd, Item *arg1) Create_func_atan Create_func_atan::s_singleton; Item* -Create_func_atan::create(THD *thd, LEX_STRING name, List *item_list) +Create_func_atan::create_native(THD *thd, LEX_STRING name, + List *item_list) { Item* func= NULL; int arg_count= 0; @@ -2694,7 +2802,8 @@ Create_func_coercibility::create(THD *thd, Item *arg1) Create_func_concat Create_func_concat::s_singleton; Item* -Create_func_concat::create(THD *thd, LEX_STRING name, List *item_list) +Create_func_concat::create_native(THD *thd, LEX_STRING name, + List *item_list) { int arg_count= 0; @@ -2714,7 +2823,8 @@ Create_func_concat::create(THD *thd, LEX_STRING name, List *item_list) Create_func_concat_ws Create_func_concat_ws::s_singleton; Item* -Create_func_concat_ws::create(THD *thd, LEX_STRING name, List *item_list) +Create_func_concat_ws::create_native(THD *thd, LEX_STRING name, + List *item_list) { int arg_count= 0; @@ -2914,8 +3024,8 @@ Create_func_degrees::create(THD *thd, Item *arg1) Create_func_des_decrypt Create_func_des_decrypt::s_singleton; Item* -Create_func_des_decrypt::create(THD *thd, LEX_STRING name, - List *item_list) +Create_func_des_decrypt::create_native(THD *thd, LEX_STRING name, + List *item_list) { Item *func= NULL; int arg_count= 0; @@ -2951,8 +3061,8 @@ Create_func_des_decrypt::create(THD *thd, LEX_STRING name, Create_func_des_encrypt Create_func_des_encrypt::s_singleton; Item* -Create_func_des_encrypt::create(THD *thd, LEX_STRING name, - List *item_list) +Create_func_des_encrypt::create_native(THD *thd, LEX_STRING name, + List *item_list) { Item *func= NULL; int arg_count= 0; @@ -3011,7 +3121,8 @@ Create_func_disjoint::create(THD *thd, Item *arg1, Item *arg2) Create_func_elt Create_func_elt::s_singleton; Item* -Create_func_elt::create(THD *thd, LEX_STRING name, List *item_list) +Create_func_elt::create_native(THD *thd, LEX_STRING name, + List *item_list) { int arg_count= 0; @@ -3050,7 +3161,8 @@ Create_func_encode::create(THD *thd, Item *arg1, Item *arg2) Create_func_encrypt Create_func_encrypt::s_singleton; Item* -Create_func_encrypt::create(THD *thd, LEX_STRING name, List *item_list) +Create_func_encrypt::create_native(THD *thd, LEX_STRING name, + List *item_list) { Item *func= NULL; int arg_count= 0; @@ -3131,7 +3243,8 @@ Create_func_exp::create(THD *thd, Item *arg1) Create_func_export_set Create_func_export_set::s_singleton; Item* -Create_func_export_set::create(THD *thd, LEX_STRING name, List *item_list) +Create_func_export_set::create_native(THD *thd, LEX_STRING name, + List *item_list) { Item *func= NULL; int arg_count= 0; @@ -3195,7 +3308,8 @@ Create_func_exteriorring::create(THD *thd, Item *arg1) Create_func_field Create_func_field::s_singleton; Item* -Create_func_field::create(THD *thd, LEX_STRING name, List *item_list) +Create_func_field::create_native(THD *thd, LEX_STRING name, + List *item_list) { int arg_count= 0; @@ -3268,8 +3382,8 @@ Create_func_from_days::create(THD *thd, Item *arg1) Create_func_from_unixtime Create_func_from_unixtime::s_singleton; Item* -Create_func_from_unixtime::create(THD *thd, LEX_STRING name, - List *item_list) +Create_func_from_unixtime::create_native(THD *thd, LEX_STRING name, + List *item_list) { Item *func= NULL; int arg_count= 0; @@ -3307,8 +3421,8 @@ Create_func_from_unixtime::create(THD *thd, LEX_STRING name, Create_func_geometry_from_text Create_func_geometry_from_text::s_singleton; Item* -Create_func_geometry_from_text::create(THD *thd, LEX_STRING name, - List *item_list) +Create_func_geometry_from_text::create_native(THD *thd, LEX_STRING name, + List *item_list) { Item *func= NULL; int arg_count= 0; @@ -3347,8 +3461,8 @@ Create_func_geometry_from_text::create(THD *thd, LEX_STRING name, Create_func_geometry_from_wkb Create_func_geometry_from_wkb::s_singleton; Item* -Create_func_geometry_from_wkb::create(THD *thd, LEX_STRING name, - List *item_list) +Create_func_geometry_from_wkb::create_native(THD *thd, LEX_STRING name, + List *item_list) { Item *func= NULL; int arg_count= 0; @@ -3430,7 +3544,8 @@ Create_func_glength::create(THD *thd, Item *arg1) Create_func_greatest Create_func_greatest::s_singleton; Item* -Create_func_greatest::create(THD *thd, LEX_STRING name, List *item_list) +Create_func_greatest::create_native(THD *thd, LEX_STRING name, + List *item_list) { int arg_count= 0; @@ -3590,8 +3705,8 @@ Create_func_last_day::create(THD *thd, Item *arg1) Create_func_last_insert_id Create_func_last_insert_id::s_singleton; Item* -Create_func_last_insert_id::create(THD *thd, LEX_STRING name, - List *item_list) +Create_func_last_insert_id::create_native(THD *thd, LEX_STRING name, + List *item_list) { Item *func= NULL; int arg_count= 0; @@ -3636,7 +3751,8 @@ Create_func_lcase::create(THD *thd, Item *arg1) Create_func_least Create_func_least::s_singleton; Item* -Create_func_least::create(THD *thd, LEX_STRING name, List *item_list) +Create_func_least::create_native(THD *thd, LEX_STRING name, + List *item_list) { int arg_count= 0; @@ -3684,7 +3800,8 @@ Create_func_load_file::create(THD *thd, Item *arg1) Create_func_locate Create_func_locate::s_singleton; Item* -Create_func_locate::create(THD *thd, LEX_STRING name, List *item_list) +Create_func_locate::create_native(THD *thd, LEX_STRING name, + List *item_list) { Item *func= NULL; int arg_count= 0; @@ -3724,7 +3841,8 @@ Create_func_locate::create(THD *thd, LEX_STRING name, List *item_list) Create_func_log Create_func_log::s_singleton; Item* -Create_func_log::create(THD *thd, LEX_STRING name, List *item_list) +Create_func_log::create_native(THD *thd, LEX_STRING name, + List *item_list) { Item *func= NULL; int arg_count= 0; @@ -3814,7 +3932,8 @@ Create_func_maketime::create(THD *thd, Item *arg1, Item *arg2, Item *arg3) Create_func_make_set Create_func_make_set::s_singleton; Item* -Create_func_make_set::create(THD *thd, LEX_STRING name, List *item_list) +Create_func_make_set::create_native(THD *thd, LEX_STRING name, + List *item_list) { int arg_count= 0; @@ -3835,8 +3954,8 @@ Create_func_make_set::create(THD *thd, LEX_STRING name, List *item_list) Create_func_master_pos_wait Create_func_master_pos_wait::s_singleton; Item* -Create_func_master_pos_wait::create(THD *thd, LEX_STRING name, - List *item_list) +Create_func_master_pos_wait::create_native(THD *thd, LEX_STRING name, + List *item_list) { Item *func= NULL; int arg_count= 0; @@ -4044,7 +4163,8 @@ Create_func_radians::create(THD *thd, Item *arg1) Create_func_rand Create_func_rand::s_singleton; Item* -Create_func_rand::create(THD *thd, LEX_STRING name, List *item_list) +Create_func_rand::create_native(THD *thd, LEX_STRING name, + List *item_list) { Item *func= NULL; int arg_count= 0; @@ -4099,7 +4219,8 @@ Create_func_reverse::create(THD *thd, Item *arg1) Create_func_round Create_func_round::s_singleton; Item* -Create_func_round::create(THD *thd, LEX_STRING name, List *item_list) +Create_func_round::create_native(THD *thd, LEX_STRING name, + List *item_list) { Item *func= NULL; int arg_count= 0; @@ -4408,8 +4529,8 @@ Create_func_unhex::create(THD *thd, Item *arg1) Create_func_unix_timestamp Create_func_unix_timestamp::s_singleton; Item* -Create_func_unix_timestamp::create(THD *thd, LEX_STRING name, - List *item_list) +Create_func_unix_timestamp::create_native(THD *thd, LEX_STRING name, + List *item_list) { Item *func= NULL; int arg_count= 0; @@ -4540,7 +4661,8 @@ Create_func_y::create(THD *thd, Item *arg1) Create_func_year_week Create_func_year_week::s_singleton; Item* -Create_func_year_week::create(THD *thd, LEX_STRING name, List *item_list) +Create_func_year_week::create_native(THD *thd, LEX_STRING name, + List *item_list) { Item *func= NULL; int arg_count= 0; diff --git a/sql/share/errmsg.txt b/sql/share/errmsg.txt index 3022967eeeb..6d7e4075e2c 100644 --- a/sql/share/errmsg.txt +++ b/sql/share/errmsg.txt @@ -6010,4 +6010,6 @@ ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT 42000 eng "Incorrect parameter count in the call to native function '%-.64s'" ER_WRONG_PARAMETERS_TO_NATIVE_FCT 42000 eng "Incorrect parameters in the call to native function '%-.64s'" +ER_WRONG_PARAMETERS_TO_STORED_FCT 42000 + eng "Incorrect parameters in the call to stored function '%-.64s'" diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index ca40dc9013a..5c074cfc742 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -164,7 +164,6 @@ void lex_start(THD *thd, const uchar *buf, uint length) lex->select_lex.ftfunc_list= &lex->select_lex.ftfunc_list_alloc; lex->select_lex.group_list.empty(); lex->select_lex.order_list.empty(); - lex->select_lex.udf_list.empty(); lex->ignore_space=test(thd->variables.sql_mode & MODE_IGNORE_SPACE); lex->sql_command= SQLCOM_END; lex->duplicates= DUP_ERROR; @@ -1176,7 +1175,6 @@ void st_select_lex::init_select() braces= 0; when_list.empty(); expr_list.empty(); - udf_list.empty(); interval_list.empty(); use_index.empty(); ftfunc_list_alloc.empty(); diff --git a/sql/sql_lex.h b/sql/sql_lex.h index dd00018f5f8..21e1872d167 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -609,8 +609,6 @@ public: /* exclude this select from check of unique_table() */ bool exclude_from_table_unique_test; - List udf_list; /* udf function calls stack */ - void init_query(); void init_select(); st_select_lex_unit* master_unit(); diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index f5ad6f1e278..a6d9f5a15db 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -6375,7 +6375,7 @@ function_call_generic: } } /* Temporary placing the result of find_udf in $3 */ - lex->current_select->udf_list.push_front(udf); + $$= udf; #endif } udf_expr_list ')' @@ -6403,10 +6403,10 @@ function_call_generic: { #ifdef HAVE_DLOPEN /* Retrieving the result of find_udf */ - udf_func *udf; + udf_func *udf= $3; LEX *lex= Lex; - if (NULL != (udf= lex->current_select->udf_list.pop())) + if (udf) { if (udf->type == UDFTYPE_AGGREGATE) { @@ -6502,7 +6502,6 @@ udf_expr_list3: udf_expr: remember_name expr remember_end select_alias { - udf_func *udf= Select->udf_list.head(); /* Use Item::name as a storage for the attribute value of user defined function argument. It is safe to use Item::name @@ -6511,20 +6510,10 @@ udf_expr: */ if ($4.str) { - if (!udf) - { - /* - Disallow using AS to specify explicit names for the arguments - of stored routine calls - */ - yyerror(ER(ER_SYNTAX_ERROR)); - YYABORT; - } - $2->is_autogenerated_name= FALSE; $2->set_name($4.str, $4.length, system_charset_info); } - else if (udf) + else $2->set_name($1, (uint) ($3 - $1), YYTHD->charset()); $$= $2; }