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#21809 | kgeorge | 24 Oct |