MySQL Lists are EOL. Please join:

List:Commits« Previous MessageNext Message »
From:marc.alff Date:December 2 2006 2:16am
Subject:bk commit into 5.1 tree (malff:1.2399) BUG#24736
View as plain text  
Below is the list of changes that have just been committed into a local
5.1 repository of marcsql. When marcsql does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html

ChangeSet@stripped, 2006-12-01 19:16:03-07:00, malff@weblab.(none) +9 -0
  Bug#24736: UDF functions parsed as Stored Functions
  
  Before this fix, a call to a User Defined Function (UDF) could,
  under some circumstances, be interpreted as a call to a Stored function
  instead. This occurred if a native function was invoked in the parameters
  for the UDF, as in "select my_udf(abs(x))".
  
  The root cause of this defect is the introduction, by the fix for Bug 21809,
  of st_select_lex::udf_list, and it's usage in the parser in sql_yacc.yy
  in the rule function_call_generic (in 5.1).
  
  While the fix itself for Bug 21809 is correct in 5.0, the code change
  merged into the 5.1 release created the issue, because the calls in 5.1 to :
  - lex->current_select->udf_list.push_front(udf)
  - lex->current_select->udf_list.pop()
  are not balanced in case of native functions, causing the udf_list,
  which is really a stack, to be out of sync with the internal stack
  maintained by the bison parser.
  
  Instead of moving the call to udf_list.pop(), which would have fixed the
  symptom, this patch goes further and removes the need for udf_list.
  
  This is motivated by two reasons:
  
  a) Maintaining a stack in the MySQL code in sync with the stack maintained
  internally in sql_yacc.cc (not .yy) is extremely dependent of the
  implementation of yacc/bison, and extremely difficult to maintain.
  It's also totally dependent of the structure of the grammar, and has a risk
  to break with regression defects each time the grammar itself is changed.
  
  b) The previous code did report construct like "foo(expr AS name)" as
  syntax errors (ER_PARSER_ERROR), which is incorrect, and misleading.
  The syntax is perfectly valid, as this expression is valid when "foo" is
  a UDF. Whether this syntax is legal or not depends of the semantic of "foo".
  
  With this change:
  
  a) There is only one stack (in bison), and no List<udf_func> to maintain.
  
  b) "foo(expr AS name)", when used incorrectly, is reported as semantic error:
  - ER_WRONG_PARAMETERS_TO_NATIVE_FCT (for native functions)
  - ER_WRONG_PARAMETERS_TO_STORED_FCT (for stored functions)
  This is achieved by the changes implemented in item_create.cc

  mysql-test/r/parser.result@stripped, 2006-12-01 19:11:51-07:00, malff@weblab.(none) +101 -0
    New tests

  mysql-test/r/udf.result@stripped, 2006-12-01 19:11:51-07:00, malff@weblab.(none) +24 -2
    New tests

  mysql-test/t/parser.test@stripped, 2006-12-01 19:11:51-07:00, malff@weblab.(none) +110 -0
    New tests

  mysql-test/t/udf.test@stripped, 2006-12-01 19:11:51-07:00, malff@weblab.(none) +18 -2
    New tests

  sql/item_create.cc@stripped, 2006-12-01 19:11:52-07:00, malff@weblab.(none) +200 -78
    Semantic checks for named parameters, as in "foo(expr AS name)".

  sql/share/errmsg.txt@stripped, 2006-12-01 19:11:52-07:00, malff@weblab.(none) +2 -0
    New error message

  sql/sql_lex.cc@stripped, 2006-12-01 19:11:52-07:00, malff@weblab.(none) +0 -2
    Remove usage of udf_list.

  sql/sql_lex.h@stripped, 2006-12-01 19:11:52-07:00, malff@weblab.(none) +0 -2
    Remove usage of udf_list.

  sql/sql_yacc.yy@stripped, 2006-12-01 19:11:52-07:00, malff@weblab.(none) +4 -15
    Remove usage of udf_list.

# This is a BitKeeper patch.  What follows are the unified diffs for the
# set of deltas contained in the patch.  The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User:	malff
# Host:	weblab.(none)
# Root:	/home/marcsql/TREE/mysql-5.1-maint-24736

--- 1.67/sql/item_create.cc	2006-12-01 19:16:09 -07:00
+++ 1.68/sql/item_create.cc	2006-12-01 19:16:09 -07:00
@@ -28,6 +28,37 @@
 */
 
 /**
+  Adapter for native functions with a variable number of arguments.
+  The main use of this class is to discard the following calls:
+  <code>foo(expr1 AS name1, expr2 AS name2, ...)</code>
+  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> *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> *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> *item_list);
+  virtual Item* create_native(THD *thd, LEX_STRING name, List<Item> *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> *item_list);
+  virtual Item* create_native(THD *thd, LEX_STRING name, List<Item> *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> *item_list);
+  virtual Item* create_native(THD *thd, LEX_STRING name, List<Item> *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> *item_list);
+  virtual Item* create_native(THD *thd, LEX_STRING name, List<Item> *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> *item_list);
+  virtual Item* create_native(THD *thd, LEX_STRING name, List<Item> *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> *item_list);
+  virtual Item* create_native(THD *thd, LEX_STRING name, List<Item> *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> *item_list);
+  virtual Item* create_native(THD *thd, LEX_STRING name, List<Item> *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> *item_list);
+  virtual Item* create_native(THD *thd, LEX_STRING name, List<Item> *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> *item_list);
+  virtual Item* create_native(THD *thd, LEX_STRING name, List<Item> *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> *item_list);
+  virtual Item* create_native(THD *thd, LEX_STRING name, List<Item> *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> *item_list);
+  virtual Item* create_native(THD *thd, LEX_STRING name, List<Item> *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> *item_list);
+  virtual Item* create_native(THD *thd, LEX_STRING name, List<Item> *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> *item_list);
+  virtual Item* create_native(THD *thd, LEX_STRING name, List<Item> *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> *item_list);
+  virtual Item* create_native(THD *thd, LEX_STRING name, List<Item> *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> *item_list);
+  virtual Item* create_native(THD *thd, LEX_STRING name, List<Item> *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> *item_list);
+  virtual Item* create_native(THD *thd, LEX_STRING name, List<Item> *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> *item_list);
+  virtual Item* create_native(THD *thd, LEX_STRING name, List<Item> *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> *item_list);
+  virtual Item* create_native(THD *thd, LEX_STRING name, List<Item> *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> *item_list);
+  virtual Item* create_native(THD *thd, LEX_STRING name, List<Item> *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> *item_list);
+  virtual Item* create_native(THD *thd, LEX_STRING name, List<Item> *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> *item_list);
+  virtual Item* create_native(THD *thd, LEX_STRING name, List<Item> *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> *item_list);
+  virtual Item* create_native(THD *thd, LEX_STRING name, List<Item> *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> *item_list);
+  virtual Item* create_native(THD *thd, LEX_STRING name, List<Item> *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:
+  <code>foo(expr AS named, expr named, expr AS "named", expr "named")</code>
+  @param params The parameter list, can be null
+  @return true if one or more parameter is named
+*/
+static bool has_named_parameters(List<Item> *params)
+{
+  if (params)
+  {
+    Item *param;
+    List_iterator<Item> 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_STR
   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);
 
@@ -2407,6 +2477,19 @@ Create_sp_func::create(THD *thd, LEX_STR
 
 
 Item*
+Create_native_func::create(THD *thd, LEX_STRING name, List<Item> *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> *item_list)
 {
   int arg_count= 0;
@@ -2439,6 +2522,13 @@ Create_func_arg1::create(THD *thd, LEX_S
   }
 
   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_S
 
   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_S
   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 
 Create_func_atan Create_func_atan::s_singleton;
 
 Item*
-Create_func_atan::create(THD *thd, LEX_STRING name, List<Item> *item_list)
+Create_func_atan::create_native(THD *thd, LEX_STRING name,
+                                List<Item> *item_list)
 {
   Item* func= NULL;
   int arg_count= 0;
@@ -2694,7 +2802,8 @@ Create_func_coercibility::create(THD *th
 Create_func_concat Create_func_concat::s_singleton;
 
 Item*
-Create_func_concat::create(THD *thd, LEX_STRING name, List<Item> *item_list)
+Create_func_concat::create_native(THD *thd, LEX_STRING name,
+                                  List<Item> *item_list)
 {
   int arg_count= 0;
 
@@ -2714,7 +2823,8 @@ Create_func_concat::create(THD *thd, LEX
 Create_func_concat_ws Create_func_concat_ws::s_singleton;
 
 Item*
-Create_func_concat_ws::create(THD *thd, LEX_STRING name, List<Item> *item_list)
+Create_func_concat_ws::create_native(THD *thd, LEX_STRING name,
+                                     List<Item> *item_list)
 {
   int arg_count= 0;
 
@@ -2914,8 +3024,8 @@ Create_func_degrees::create(THD *thd, It
 Create_func_des_decrypt Create_func_des_decrypt::s_singleton;
 
 Item*
-Create_func_des_decrypt::create(THD *thd, LEX_STRING name,
-                                List<Item> *item_list)
+Create_func_des_decrypt::create_native(THD *thd, LEX_STRING name,
+                                       List<Item> *item_list)
 {
   Item *func= NULL;
   int arg_count= 0;
@@ -2951,8 +3061,8 @@ Create_func_des_decrypt::create(THD *thd
 Create_func_des_encrypt Create_func_des_encrypt::s_singleton;
 
 Item*
-Create_func_des_encrypt::create(THD *thd, LEX_STRING name,
-                                List<Item> *item_list)
+Create_func_des_encrypt::create_native(THD *thd, LEX_STRING name,
+                                       List<Item> *item_list)
 {
   Item *func= NULL;
   int arg_count= 0;
@@ -3011,7 +3121,8 @@ Create_func_disjoint::create(THD *thd, I
 Create_func_elt Create_func_elt::s_singleton;
 
 Item*
-Create_func_elt::create(THD *thd, LEX_STRING name, List<Item> *item_list)
+Create_func_elt::create_native(THD *thd, LEX_STRING name,
+                               List<Item> *item_list)
 {
   int arg_count= 0;
 
@@ -3050,7 +3161,8 @@ Create_func_encode::create(THD *thd, Ite
 Create_func_encrypt Create_func_encrypt::s_singleton;
 
 Item*
-Create_func_encrypt::create(THD *thd, LEX_STRING name, List<Item> *item_list)
+Create_func_encrypt::create_native(THD *thd, LEX_STRING name,
+                                   List<Item> *item_list)
 {
   Item *func= NULL;
   int arg_count= 0;
@@ -3131,7 +3243,8 @@ Create_func_exp::create(THD *thd, Item *
 Create_func_export_set Create_func_export_set::s_singleton;
 
 Item*
-Create_func_export_set::create(THD *thd, LEX_STRING name, List<Item> *item_list)
+Create_func_export_set::create_native(THD *thd, LEX_STRING name,
+                                      List<Item> *item_list)
 {
   Item *func= NULL;
   int arg_count= 0;
@@ -3195,7 +3308,8 @@ Create_func_exteriorring::create(THD *th
 Create_func_field Create_func_field::s_singleton;
 
 Item*
-Create_func_field::create(THD *thd, LEX_STRING name, List<Item> *item_list)
+Create_func_field::create_native(THD *thd, LEX_STRING name,
+                                 List<Item> *item_list)
 {
   int arg_count= 0;
 
@@ -3268,8 +3382,8 @@ Create_func_from_days::create(THD *thd, 
 Create_func_from_unixtime Create_func_from_unixtime::s_singleton;
 
 Item*
-Create_func_from_unixtime::create(THD *thd, LEX_STRING name,
-                                  List<Item> *item_list)
+Create_func_from_unixtime::create_native(THD *thd, LEX_STRING name,
+                                         List<Item> *item_list)
 {
   Item *func= NULL;
   int arg_count= 0;
@@ -3307,8 +3421,8 @@ Create_func_from_unixtime::create(THD *t
 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> *item_list)
+Create_func_geometry_from_text::create_native(THD *thd, LEX_STRING name,
+                                              List<Item> *item_list)
 {
   Item *func= NULL;
   int arg_count= 0;
@@ -3347,8 +3461,8 @@ Create_func_geometry_from_text::create(T
 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> *item_list)
+Create_func_geometry_from_wkb::create_native(THD *thd, LEX_STRING name,
+                                             List<Item> *item_list)
 {
   Item *func= NULL;
   int arg_count= 0;
@@ -3430,7 +3544,8 @@ Create_func_glength::create(THD *thd, It
 Create_func_greatest Create_func_greatest::s_singleton;
 
 Item*
-Create_func_greatest::create(THD *thd, LEX_STRING name, List<Item> *item_list)
+Create_func_greatest::create_native(THD *thd, LEX_STRING name,
+                                    List<Item> *item_list)
 {
   int arg_count= 0;
 
@@ -3590,8 +3705,8 @@ Create_func_last_day::create(THD *thd, I
 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> *item_list)
+Create_func_last_insert_id::create_native(THD *thd, LEX_STRING name,
+                                          List<Item> *item_list)
 {
   Item *func= NULL;
   int arg_count= 0;
@@ -3636,7 +3751,8 @@ Create_func_lcase::create(THD *thd, Item
 Create_func_least Create_func_least::s_singleton;
 
 Item*
-Create_func_least::create(THD *thd, LEX_STRING name, List<Item> *item_list)
+Create_func_least::create_native(THD *thd, LEX_STRING name,
+                                 List<Item> *item_list)
 {
   int arg_count= 0;
 
@@ -3684,7 +3800,8 @@ Create_func_load_file::create(THD *thd, 
 Create_func_locate Create_func_locate::s_singleton;
 
 Item*
-Create_func_locate::create(THD *thd, LEX_STRING name, List<Item> *item_list)
+Create_func_locate::create_native(THD *thd, LEX_STRING name,
+                                  List<Item> *item_list)
 {
   Item *func= NULL;
   int arg_count= 0;
@@ -3724,7 +3841,8 @@ Create_func_locate::create(THD *thd, LEX
 Create_func_log Create_func_log::s_singleton;
 
 Item*
-Create_func_log::create(THD *thd, LEX_STRING name, List<Item> *item_list)
+Create_func_log::create_native(THD *thd, LEX_STRING name,
+                               List<Item> *item_list)
 {
   Item *func= NULL;
   int arg_count= 0;
@@ -3814,7 +3932,8 @@ Create_func_maketime::create(THD *thd, I
 Create_func_make_set Create_func_make_set::s_singleton;
 
 Item*
-Create_func_make_set::create(THD *thd, LEX_STRING name, List<Item> *item_list)
+Create_func_make_set::create_native(THD *thd, LEX_STRING name,
+                                    List<Item> *item_list)
 {
   int arg_count= 0;
 
@@ -3835,8 +3954,8 @@ Create_func_make_set::create(THD *thd, L
 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> *item_list)
+Create_func_master_pos_wait::create_native(THD *thd, LEX_STRING name,
+                                           List<Item> *item_list)
 {
   Item *func= NULL;
   int arg_count= 0;
@@ -4044,7 +4163,8 @@ Create_func_radians::create(THD *thd, It
 Create_func_rand Create_func_rand::s_singleton;
 
 Item*
-Create_func_rand::create(THD *thd, LEX_STRING name, List<Item> *item_list)
+Create_func_rand::create_native(THD *thd, LEX_STRING name,
+                                List<Item> *item_list)
 {
   Item *func= NULL;
   int arg_count= 0;
@@ -4099,7 +4219,8 @@ Create_func_reverse::create(THD *thd, It
 Create_func_round Create_func_round::s_singleton;
 
 Item*
-Create_func_round::create(THD *thd, LEX_STRING name, List<Item> *item_list)
+Create_func_round::create_native(THD *thd, LEX_STRING name,
+                                 List<Item> *item_list)
 {
   Item *func= NULL;
   int arg_count= 0;
@@ -4408,8 +4529,8 @@ Create_func_unhex::create(THD *thd, Item
 Create_func_unix_timestamp Create_func_unix_timestamp::s_singleton;
 
 Item*
-Create_func_unix_timestamp::create(THD *thd, LEX_STRING name,
-                                   List<Item> *item_list)
+Create_func_unix_timestamp::create_native(THD *thd, LEX_STRING name,
+                                          List<Item> *item_list)
 {
   Item *func= NULL;
   int arg_count= 0;
@@ -4540,7 +4661,8 @@ Create_func_y::create(THD *thd, Item *ar
 Create_func_year_week Create_func_year_week::s_singleton;
 
 Item*
-Create_func_year_week::create(THD *thd, LEX_STRING name, List<Item> *item_list)
+Create_func_year_week::create_native(THD *thd, LEX_STRING name,
+                                     List<Item> *item_list)
 {
   Item *func= NULL;
   int arg_count= 0;

--- 1.210/sql/sql_lex.cc	2006-12-01 19:16:09 -07:00
+++ 1.211/sql/sql_lex.cc	2006-12-01 19:16:09 -07:00
@@ -164,7 +164,6 @@ void lex_start(THD *thd, const uchar *bu
   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();

--- 1.248/sql/sql_lex.h	2006-12-01 19:16:09 -07:00
+++ 1.249/sql/sql_lex.h	2006-12-01 19:16:09 -07:00
@@ -609,8 +609,6 @@ public:
   /* exclude this select from check of unique_table() */
   bool exclude_from_table_unique_test;
 
-  List<udf_func>     udf_list;                  /* udf function calls stack */
-
   void init_query();
   void init_select();
   st_select_lex_unit* master_unit();

--- 1.516/sql/sql_yacc.yy	2006-12-01 19:16:09 -07:00
+++ 1.517/sql/sql_yacc.yy	2006-12-01 19:16:09 -07:00
@@ -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>$= 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= $<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;
 	}

--- 1.133/sql/share/errmsg.txt	2006-12-01 19:16:09 -07:00
+++ 1.134/sql/share/errmsg.txt	2006-12-01 19:16:09 -07:00
@@ -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'"
 

--- 1.1/mysql-test/r/parser.result	2006-12-01 19:16:09 -07:00
+++ 1.2/mysql-test/r/parser.result	2006-12-01 19:16:09 -07:00
@@ -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'

--- 1.1/mysql-test/t/parser.test	2006-12-01 19:16:09 -07:00
+++ 1.2/mysql-test/t/parser.test	2006-12-01 19:16:09 -07:00
@@ -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);
+

--- 1.12/mysql-test/r/udf.result	2006-12-01 19:16:09 -07:00
+++ 1.13/mysql-test/r/udf.result	2006-12-01 19:16:09 -07:00
@@ -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;

--- 1.12/mysql-test/t/udf.test	2006-12-01 19:16:09 -07:00
+++ 1.13/mysql-test/t/udf.test	2006-12-01 19:16:09 -07:00
@@ -149,9 +149,9 @@ EXPLAIN EXTENDED SELECT myfunc_int(a AS 
 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;
@@ -172,6 +172,22 @@ DROP TABLE t1;
 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
Thread
bk commit into 5.1 tree (malff:1.2399) BUG#24736marc.alff2 Dec