List:Commits« Previous MessageNext Message »
From:kgeorge Date:October 24 2006 2:27pm
Subject:bk commit into 5.0 tree (gkodinov:1.2302) BUG#21809
View as plain text  
Below is the list of changes that have just been committed into a local
5.0 repository of kgeorge. When kgeorge 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-10-24 15:26:41+03:00, gkodinov@stripped +8 -0
  Bug #21809: Error 1356 while selecting from view with grouping though underlying
              select OK.
  The SQL parser was using Item::name to transfer user defined function attributes
  to the user defined function (udf). It was not distinguishing between user defined 
  function call arguments and stored procedure call arguments. Setting Item::name 
  was causing Item_ref::print() method to print the argument as quoted identifiers 
  and caused views that reference aggregate functions as udf call arguments (and 
  rely on Item::print() for the text of the view to store) to throw an undefined 
  identifier error.
  Overloaded Item_ref::print to print aggregate functions as such when printing
  the references to aggregate functions taken out of context by split_sum_func2()
  Fixed the parser to properly detect using AS clause in stored procedure arguments
  as an error.
  Fixed printing the arguments of udf call to print properly the udf attribute.

  mysql-test/r/udf.result@stripped, 2006-10-24 15:26:29+03:00, gkodinov@stripped +79 -0
    Bug #21809: Error 1356 while selecting from view with grouping though underlying
                select OK.
     - test cases

  mysql-test/t/udf.test@stripped, 2006-10-24 15:26:30+03:00, gkodinov@stripped +44 -0
    Bug #21809: Error 1356 while selecting from view with grouping though underlying
                select OK.
     - test cases

  sql/item.cc@stripped, 2006-10-24 15:26:31+03:00, gkodinov@stripped +24 -2
    Bug #21809: Error 1356 while selecting from view with grouping though underlying
                select OK.
     - Don't print the refs to SUM functions as refs.

  sql/item_func.cc@stripped, 2006-10-24 15:26:32+03:00, gkodinov@stripped +14 -0
    Bug #21809: Error 1356 while selecting from view with grouping though underlying
                select OK.
     - print the aliases in the udf calls

  sql/item_func.h@stripped, 2006-10-24 15:26:33+03:00, gkodinov@stripped +1 -0
    Bug #21809: Error 1356 while selecting from view with grouping though underlying
                select OK.
     - print the aliases in the udf calls

  sql/sql_lex.cc@stripped, 2006-10-24 15:26:33+03:00, gkodinov@stripped +2 -0
    Bug #21809: Error 1356 while selecting from view with grouping though underlying
                select OK.
     - disable aliases for arguments in stored routine calls

  sql/sql_lex.h@stripped, 2006-10-24 15:26:34+03:00, gkodinov@stripped +2 -0
    Bug #21809: Error 1356 while selecting from view with grouping though underlying
                select OK.
     - disable aliases for arguments in stored routine calls

  sql/sql_yacc.yy@stripped, 2006-10-24 15:26:35+03:00, gkodinov@stripped +30 -11
    Bug #21809: Error 1356 while selecting from view with grouping though underlying
                select OK.
     - disable aliases for arguments in stored routine calls
     - fix bison duplicate symbol warnings

# 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:	gkodinov
# Host:	macbook.gmz
# Root:	/Users/kgeorge/mysql/work/B21809-5.0-opt

--- 1.235/sql/item.cc	2006-10-24 15:26:59 +03:00
+++ 1.236/sql/item.cc	2006-10-24 15:26:59 +03:00
@@ -1148,6 +1148,28 @@ void Item_name_const::print(String *str)
 
 
 /*
+ need a special class to adjust printing : references to aggregate functions 
+ must not be printed as refs because the aggregate functions that are added to
+ the front of select list are not printed as well.
+*/
+class Item_aggregate_ref : public Item_ref
+{
+public:
+  Item_aggregate_ref(Name_resolution_context *context_arg, Item **item,
+                  const char *table_name_arg, const char *field_name_arg)
+    :Item_ref(context_arg, item, table_name_arg, field_name_arg) {}
+
+  void print (String *str)
+  {
+    if (ref)
+      (*ref)->print(str);
+    else
+      Item_ident::print(str);
+  }
+};
+
+
+/*
   Move SUM items out from item tree and replace with reference
 
   SYNOPSIS
@@ -1200,8 +1222,8 @@ void Item::split_sum_func2(THD *thd, Ite
     Item *new_item, *real_itm= real_item();
 
     ref_pointer_array[el]= real_itm;
-    if (!(new_item= new Item_ref(&thd->lex->current_select->context,
-                                 ref_pointer_array + el, 0, name)))
+    if (!(new_item= new
Item_aggregate_ref(&thd->lex->current_select->context,
+                                           ref_pointer_array + el, 0, name)))
       return;                                   // fatal_error is set
     fields.push_front(real_itm);
     thd->change_item_tree(ref, new_item);

--- 1.304/sql/item_func.cc	2006-10-24 15:26:59 +03:00
+++ 1.305/sql/item_func.cc	2006-10-24 15:26:59 +03:00
@@ -2869,6 +2869,20 @@ void Item_udf_func::cleanup()
 }
 
 
+void Item_udf_func::print(String *str)
+{
+  str->append(func_name());
+  str->append('(');
+  for (uint i=0 ; i < arg_count ; i++)
+  {
+    if (i != 0)
+      str->append(',');
+    args[i]->print_item_w_name(str);
+  }
+  str->append(')');
+}
+
+
 double Item_func_udf_float::val_real()
 {
   DBUG_ASSERT(fixed == 1);

--- 1.153/sql/item_func.h	2006-10-24 15:26:59 +03:00
+++ 1.154/sql/item_func.h	2006-10-24 15:26:59 +03:00
@@ -951,6 +951,7 @@ public:
   Item_result result_type () const { return udf.result_type(); }
   table_map not_null_tables() const { return 0; }
   bool is_expensive() { return 1; }
+  void print(String *str);
 };
 
 

--- 1.201/sql/sql_lex.cc	2006-10-24 15:27:00 +03:00
+++ 1.202/sql/sql_lex.cc	2006-10-24 15:27:00 +03:00
@@ -163,6 +163,7 @@ void lex_start(THD *thd, uchar *buf,uint
   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->current_select= &lex->select_lex;
   lex->yacc_yyss=lex->yacc_yyvs=0;
   lex->ignore_space=test(thd->variables.sql_mode & MODE_IGNORE_SPACE);
@@ -1166,6 +1167,7 @@ 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.228/sql/sql_lex.h	2006-10-24 15:27:00 +03:00
+++ 1.229/sql/sql_lex.h	2006-10-24 15:27:00 +03:00
@@ -580,6 +580,8 @@ 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.491/sql/sql_yacc.yy	2006-10-24 15:27:00 +03:00
+++ 1.492/sql/sql_yacc.yy	2006-10-24 15:27:00 +03:00
@@ -650,11 +650,8 @@ bool my_yyoverflow(short **a, YYSTYPE **
 %token  UNIX_TIMESTAMP
 %token  UNKNOWN_SYM
 %token  UNLOCK_SYM
-%token  UNLOCK_SYM
 %token  UNSIGNED
 %token  UNTIL_SYM
-%token  UNTIL_SYM
-%token  UPDATE_SYM
 %token  UPDATE_SYM
 %token  UPGRADE_SYM
 %token  USAGE
@@ -764,7 +761,7 @@ bool my_yyoverflow(short **a, YYSTYPE **
 
 %type <item_list>
 	expr_list udf_expr_list udf_expr_list2 when_list
-	ident_list ident_list_arg
+	ident_list ident_list_arg opt_expr_list
 
 %type <var_type>
         option_type opt_var_type opt_var_ident_type
@@ -4724,7 +4721,7 @@ simple_expr:
 	  { $$= new Item_func_trim($5,$3); }
 	| TRUNCATE_SYM '(' expr ',' expr ')'
 	  { $$= new Item_func_round($3,$5,1); }
-	| ident '.' ident '(' udf_expr_list ')'
+	| ident '.' ident '(' opt_expr_list ')'
 	  {
 	    LEX *lex= Lex;
 	    sp_name *name= new sp_name($1, $3);
@@ -4741,27 +4738,27 @@ simple_expr:
           {
 #ifdef HAVE_DLOPEN
             udf_func *udf= 0;
+            LEX *lex= Lex;
             if (using_udf_functions &&
                 (udf= find_udf($1.str, $1.length)) &&
                 udf->type == UDFTYPE_AGGREGATE)
             {
-              LEX *lex= Lex;
               if (lex->current_select->inc_in_sum_expr())
               {
                 yyerror(ER(ER_SYNTAX_ERROR));
                 YYABORT;
               }
             }
-            $<udf>$= udf;
+            lex->current_select->udf_list.push_front(udf);
 #endif
           }
           udf_expr_list ')'
           {
 #ifdef HAVE_DLOPEN
-            udf_func *udf= $<udf>3;
-            SELECT_LEX *sel= Select;
+            udf_func *udf;
+            LEX *lex= Lex;
 
-            if (udf)
+            if (NULL != (udf= lex->current_select->udf_list.pop()))
             {
               if (udf->type == UDFTYPE_AGGREGATE)
                 Select->in_sum_expr--;
@@ -4988,12 +4985,29 @@ 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
+           because the syntax will not allow having an explicit name here.
+           See WL#1017 re. udf attributes.
+          */
 	  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
+	  else if (udf)
 	    $2->set_name($1, (uint) ($3 - $1), YYTHD->charset());
 	  $$= $2;
 	}
@@ -5112,6 +5126,11 @@ cast_type:
         | TIME_SYM		{ $$=ITEM_CAST_TIME; Lex->charset= NULL;
Lex->dec=Lex->length= (char*)0; }
         | DATETIME		{ $$=ITEM_CAST_DATETIME; Lex->charset= NULL;
Lex->dec=Lex->length= (char*)0; }
         | DECIMAL_SYM float_options { $$=ITEM_CAST_DECIMAL; Lex->charset= NULL; }
+	;
+
+opt_expr_list:
+	/* empty */ { $$= NULL; }
+	| expr_list { $$= $1;}
 	;
 
 expr_list:

--- 1.7/mysql-test/r/udf.result	2006-10-24 15:27:00 +03:00
+++ 1.8/mysql-test/r/udf.result	2006-10-24 15:27:00 +03:00
@@ -105,6 +105,85 @@ explain select myfunc_int(f1) from t1 or
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	SIMPLE	t1	ALL	NULL	NULL	NULL	NULL	2	Using temporary; Using filesort
 drop table t1;
+CREATE TABLE t1(a INT, b INT);
+INSERT INTO t1 values (1,1),(2,2);
+CREATE FUNCTION fn(a int) RETURNS int DETERMINISTIC
+BEGIN
+RETURN a;
+END
+||
+CREATE VIEW v1 AS SELECT a, fn(MIN(b)) as c FROM t1 GROUP BY a;
+SELECT myfunc_int(a AS attr_name) FROM t1;
+myfunc_int(a AS attr_name)
+1
+2
+EXPLAIN EXTENDED SELECT myfunc_int(a AS attr_name) FROM t1;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	ALL	NULL	NULL	NULL	NULL	2	
+Warnings:
+Note	1003	select myfunc_int(`test`.`t1`.`a` AS `attr_name`) AS `myfunc_int(a AS
attr_name)` from `test`.`t1`
+EXPLAIN EXTENDED SELECT myfunc_int(a) FROM t1;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	ALL	NULL	NULL	NULL	NULL	2	
+Warnings:
+Note	1003	select myfunc_int(`test`.`t1`.`a` AS `a`) AS `myfunc_int(a)` from `test`.`t1`
+SELECT a,c FROM v1;
+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
+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
+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;
+c
+1
+2
+SELECT myfunc_int(test.fn(MIN(b)) xx) as c FROM t1 GROUP BY a;
+c
+1
+2
+EXPLAIN EXTENDED SELECT myfunc_int(MIN(b) xx) as c FROM t1 GROUP BY a;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	ALL	NULL	NULL	NULL	NULL	2	Using temporary; Using filesort
+Warnings:
+Note	1003	select myfunc_int(min(`test`.`t1`.`b`) AS `xx`) AS `c` from `test`.`t1` group
by `test`.`t1`.`a`
+EXPLAIN EXTENDED SELECT test.fn(MIN(b)) as c FROM t1 GROUP BY a;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	ALL	NULL	NULL	NULL	NULL	2	Using temporary; Using filesort
+Warnings:
+Note	1003	select `test`.`fn`(min(`test`.`t1`.`b`)) AS `c` from `test`.`t1` group by
`test`.`t1`.`a`
+EXPLAIN EXTENDED SELECT myfunc_int(fn(MIN(b))) as c FROM t1 GROUP BY a;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	ALL	NULL	NULL	NULL	NULL	2	Using temporary; Using filesort
+Warnings:
+Note	1003	select myfunc_int(`test`.`fn`(min(`test`.`t1`.`b`)) AS `fn(MIN(b))`) AS `c`
from `test`.`t1` group by `test`.`t1`.`a`
+EXPLAIN EXTENDED SELECT myfunc_int(test.fn(MIN(b))) as c FROM t1 GROUP BY a;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	ALL	NULL	NULL	NULL	NULL	2	Using temporary; Using filesort
+Warnings:
+Note	1003	select myfunc_int(`test`.`fn`(min(`test`.`t1`.`b`)) AS `test.fn(MIN(b))`) AS
`c` from `test`.`t1` group by `test`.`t1`.`a`
+SELECT myfunc_int(MIN(b) xx) as c FROM t1 GROUP BY a;
+c
+1
+2
+SELECT test.fn(MIN(b)) as c FROM t1 GROUP BY a;
+c
+1
+2
+SELECT myfunc_int(fn(MIN(b))) as c FROM t1 GROUP BY a;
+c
+1
+2
+SELECT myfunc_int(test.fn(MIN(b))) as c FROM t1 GROUP BY a;
+c
+1
+2
+DROP VIEW v1;
+DROP TABLE t1;
+DROP FUNCTION fn;
 End of 5.0 tests.
 DROP FUNCTION metaphon;
 DROP FUNCTION myfunc_double;

--- 1.8/mysql-test/t/udf.test	2006-10-24 15:27:00 +03:00
+++ 1.9/mysql-test/t/udf.test	2006-10-24 15:27:00 +03:00
@@ -127,6 +127,50 @@ create table t1(f1 int);
 insert into t1 values(1),(2);
 explain select myfunc_int(f1) from t1 order by 1;
 drop table t1;
+
+# 
+# Bug #21809: Error 1356 while selecting from view with grouping though 
+#              underlying select OK.
+#
+CREATE TABLE t1(a INT, b INT); INSERT INTO t1 values (1,1),(2,2);
+
+DELIMITER ||;
+CREATE FUNCTION fn(a int) RETURNS int DETERMINISTIC
+BEGIN
+    RETURN a;
+END
+||
+DELIMITER ;||
+
+CREATE VIEW v1 AS SELECT a, fn(MIN(b)) as c FROM t1 GROUP BY a;
+
+SELECT myfunc_int(a AS attr_name) FROM t1;
+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
+SELECT a, fn(MIN(b) xx) as c FROM t1 GROUP BY a;
+--error ER_PARSE_ERROR
+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;
+
+SELECT myfunc_int(fn(MIN(b)) xx) as c FROM t1 GROUP BY a;
+SELECT myfunc_int(test.fn(MIN(b)) xx) as c FROM t1 GROUP BY a;
+
+EXPLAIN EXTENDED SELECT myfunc_int(MIN(b) xx) as c FROM t1 GROUP BY a;
+EXPLAIN EXTENDED SELECT test.fn(MIN(b)) as c FROM t1 GROUP BY a;
+EXPLAIN EXTENDED SELECT myfunc_int(fn(MIN(b))) as c FROM t1 GROUP BY a;
+EXPLAIN EXTENDED SELECT myfunc_int(test.fn(MIN(b))) as c FROM t1 GROUP BY a;
+SELECT myfunc_int(MIN(b) xx) as c FROM t1 GROUP BY a;
+SELECT test.fn(MIN(b)) as c FROM t1 GROUP BY a;
+SELECT myfunc_int(fn(MIN(b))) as c FROM t1 GROUP BY a;
+SELECT myfunc_int(test.fn(MIN(b))) as c FROM t1 GROUP BY a;
+DROP VIEW v1;
+DROP TABLE t1;
+DROP FUNCTION fn;
+
 --echo End of 5.0 tests.
 
 #
Thread
bk commit into 5.0 tree (gkodinov:1.2302) BUG#21809kgeorge24 Oct