Commit 2afbcdf4 authored by malff/marcsql@weblab.(none)'s avatar malff/marcsql@weblab.(none)

Merge malff@bk-internal.mysql.com:/home/bk/mysql-5.1-runtime

into  weblab.(none):/home/marcsql/TREE/mysql-5.1-18239
parents 9bfc5f57 6e29099d
...@@ -2178,6 +2178,7 @@ set @stamped_time=in_time; ...@@ -2178,6 +2178,7 @@ set @stamped_time=in_time;
set x=2; set x=2;
end if; end if;
end| end|
set time_zone='+03:00';
call bug3426(1000, @i)| call bug3426(1000, @i)|
select @i, from_unixtime(@stamped_time, '%d-%m-%Y %h:%i:%s') as time| select @i, from_unixtime(@stamped_time, '%d-%m-%Y %h:%i:%s') as time|
@i time @i time
...@@ -5627,4 +5628,119 @@ Called B ...@@ -5627,4 +5628,119 @@ Called B
drop procedure proc_21462_a| drop procedure proc_21462_a|
drop procedure proc_21462_b| drop procedure proc_21462_b|
End of 5.0 tests End of 5.0 tests
Begin of 5.1 tests
drop function if exists pi;
create function pi() returns varchar(50)
return "pie, my favorite desert.";
Warnings:
Note 1578 This function 'pi' has the same name as a native function.
SET @save_sql_mode=@@sql_mode;
SET SQL_MODE='IGNORE_SPACE';
select pi(), pi ();
pi() pi ()
3.141593 3.141593
select test.pi(), test.pi ();
test.pi() test.pi ()
pie, my favorite desert. pie, my favorite desert.
Warnings:
Note 1578 This function 'pi' has the same name as a native function.
SET SQL_MODE='';
select pi(), pi ();
pi() pi ()
3.141593 3.141593
select test.pi(), test.pi ();
test.pi() test.pi ()
pie, my favorite desert. pie, my favorite desert.
SET @@sql_mode=@save_sql_mode;
drop function pi;
drop function if exists test.database;
drop function if exists test.current_user;
drop function if exists test.md5;
create database nowhere;
use nowhere;
drop database nowhere;
SET @save_sql_mode=@@sql_mode;
SET SQL_MODE='IGNORE_SPACE';
select database(), database ();
database() database ()
NULL NULL
select current_user(), current_user ();
current_user() current_user ()
root@localhost root@localhost
select md5("aaa"), md5 ("aaa");
md5("aaa") md5 ("aaa")
47bce5c74f589f4867dbd57e9ca9f808 47bce5c74f589f4867dbd57e9ca9f808
SET SQL_MODE='';
select database(), database ();
database() database ()
NULL NULL
select current_user(), current_user ();
current_user() current_user ()
root@localhost root@localhost
select md5("aaa"), md5 ("aaa");
md5("aaa") md5 ("aaa")
47bce5c74f589f4867dbd57e9ca9f808 47bce5c74f589f4867dbd57e9ca9f808
use test;
create function `database`() returns varchar(50)
return "Stored function database";
Warnings:
Note 1578 This function 'database' has the same name as a native function.
create function `current_user`() returns varchar(50)
return "Stored function current_user";
Warnings:
Note 1578 This function 'current_user' has the same name as a native function.
create function md5(x varchar(50)) returns varchar(50)
return "Stored function md5";
Warnings:
Note 1578 This function 'md5' has the same name as a native function.
SET SQL_MODE='IGNORE_SPACE';
select database(), database ();
database() database ()
test test
select current_user(), current_user ();
current_user() current_user ()
root@localhost root@localhost
select md5("aaa"), md5 ("aaa");
md5("aaa") md5 ("aaa")
47bce5c74f589f4867dbd57e9ca9f808 47bce5c74f589f4867dbd57e9ca9f808
select test.database(), test.database ();
test.database() test.database ()
Stored function database Stored function database
Warnings:
Note 1578 This function 'database' has the same name as a native function.
select test.current_user(), test.current_user ();
test.current_user() test.current_user ()
Stored function current_user Stored function current_user
Warnings:
Note 1578 This function 'current_user' has the same name as a native function.
select test.md5("aaa"), test.md5 ("aaa");
test.md5("aaa") test.md5 ("aaa")
Stored function md5 Stored function md5
Warnings:
Note 1578 This function 'md5' has the same name as a native function.
SET SQL_MODE='';
select database(), database ();
database() database ()
test test
select current_user(), current_user ();
current_user() current_user ()
root@localhost root@localhost
select md5("aaa"), md5 ("aaa");
md5("aaa") md5 ("aaa")
47bce5c74f589f4867dbd57e9ca9f808 47bce5c74f589f4867dbd57e9ca9f808
select test.database(), test.database ();
test.database() test.database ()
Stored function database Stored function database
select test.current_user(), test.current_user ();
test.current_user() test.current_user ()
Stored function current_user Stored function current_user
select test.md5("aaa"), test.md5 ("aaa");
test.md5("aaa") test.md5 ("aaa")
Stored function md5 Stored function md5
SET @@sql_mode=@save_sql_mode;
drop function test.database;
drop function test.current_user;
drop function md5;
use test;
End of 5.1 tests
drop table t1,t2; drop table t1,t2;
use test;
drop function if exists a;
drop function if exists x;
drop function if exists y;
create function a() returns int
return 1;
create function x() returns int
return 2;
Warnings:
Note 1578 This function 'x' has the same name as a native function.
create function y() returns int
return 3;
Warnings:
Note 1578 This function 'y' has the same name as a native function.
select a();
a()
1
select x();
ERROR 42000: Incorrect parameter count in the call to native function 'x'
select y();
ERROR 42000: Incorrect parameter count in the call to native function 'y'
select x(PointFromText("POINT(10 20)")), y(PointFromText("POINT(10 20)"));
x(PointFromText("POINT(10 20)")) y(PointFromText("POINT(10 20)"))
10 20
select test.a(), test.x(), test.y();
test.a() test.x() test.y()
1 2 3
Warnings:
Note 1578 This function 'x' has the same name as a native function.
Note 1578 This function 'y' has the same name as a native function.
drop function a;
drop function x;
drop function y;
...@@ -106,6 +106,22 @@ id select_type table type possible_keys key key_len ref rows Extra ...@@ -106,6 +106,22 @@ 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 1 SIMPLE t1 ALL NULL NULL NULL NULL 2 Using temporary; Using filesort
drop table t1; drop table t1;
End of 5.0 tests. End of 5.0 tests.
drop function if exists pi;
CREATE FUNCTION pi RETURNS STRING SONAME "should_not_parse.so";
ERROR HY000: This function 'pi' has the same name as a native function.
DROP FUNCTION IF EXISTS metaphon;
CREATE FUNCTION metaphon(a int) RETURNS int
return 0;
CREATE FUNCTION metaphon RETURNS STRING SONAME "UDF_EXAMPLE_LIB";
ERROR HY000: Function 'metaphon' already exists
DROP FUNCTION metaphon;
CREATE FUNCTION metaphon RETURNS STRING SONAME "UDF_EXAMPLE_LIB";
CREATE FUNCTION metaphon(a int) RETURNS int
return 0;
ERROR HY000: Function 'metaphon' already exists
CREATE FUNCTION test.metaphon(a int) RETURNS int
return 0;
ERROR HY000: Function 'metaphon' already exists
DROP FUNCTION metaphon; DROP FUNCTION metaphon;
DROP FUNCTION myfunc_double; DROP FUNCTION myfunc_double;
DROP FUNCTION myfunc_nonexist; DROP FUNCTION myfunc_nonexist;
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
# Tests that uses 'goto' to into sp-goto.test (currently disabled) # Tests that uses 'goto' to into sp-goto.test (currently disabled)
# Tests that destroys system tables (e.g. mysql.proc) for error testing # Tests that destroys system tables (e.g. mysql.proc) for error testing
# go to sp-destruct. # go to sp-destruct.
# Tests that require --with-geometry go into sp_gis.test
use test; use test;
...@@ -2584,6 +2585,9 @@ begin ...@@ -2584,6 +2585,9 @@ begin
end if; end if;
end| end|
# so that from_unixtime() has a deterministic result
set time_zone='+03:00';
call bug3426(1000, @i)| call bug3426(1000, @i)|
select @i, from_unixtime(@stamped_time, '%d-%m-%Y %h:%i:%s') as time| select @i, from_unixtime(@stamped_time, '%d-%m-%Y %h:%i:%s') as time|
call bug3426(NULL, @i)| call bug3426(NULL, @i)|
...@@ -6585,6 +6589,108 @@ drop procedure proc_21462_b| ...@@ -6585,6 +6589,108 @@ drop procedure proc_21462_b|
--echo End of 5.0 tests --echo End of 5.0 tests
--echo Begin of 5.1 tests
#
# BUG#18239: Possible to overload internal functions with stored functions
#
delimiter ;|
--disable_warnings
drop function if exists pi;
--enable_warnings
create function pi() returns varchar(50)
return "pie, my favorite desert.";
SET @save_sql_mode=@@sql_mode;
SET SQL_MODE='IGNORE_SPACE';
select pi(), pi ();
select test.pi(), test.pi ();
SET SQL_MODE='';
select pi(), pi ();
select test.pi(), test.pi ();
SET @@sql_mode=@save_sql_mode;
drop function pi;
# End of BUG#18239
#
# BUG#22619: Spaces considered harmful
#
--disable_warnings
drop function if exists test.database;
drop function if exists test.current_user;
drop function if exists test.md5;
--enable_warnings
create database nowhere;
use nowhere;
drop database nowhere;
SET @save_sql_mode=@@sql_mode;
SET SQL_MODE='IGNORE_SPACE';
select database(), database ();
select current_user(), current_user ();
select md5("aaa"), md5 ("aaa");
SET SQL_MODE='';
select database(), database ();
select current_user(), current_user ();
select md5("aaa"), md5 ("aaa");
use test;
create function `database`() returns varchar(50)
return "Stored function database";
create function `current_user`() returns varchar(50)
return "Stored function current_user";
create function md5(x varchar(50)) returns varchar(50)
return "Stored function md5";
SET SQL_MODE='IGNORE_SPACE';
select database(), database ();
select current_user(), current_user ();
select md5("aaa"), md5 ("aaa");
select test.database(), test.database ();
select test.current_user(), test.current_user ();
select test.md5("aaa"), test.md5 ("aaa");
SET SQL_MODE='';
select database(), database ();
select current_user(), current_user ();
select md5("aaa"), md5 ("aaa");
select test.database(), test.database ();
select test.current_user(), test.current_user ();
select test.md5("aaa"), test.md5 ("aaa");
SET @@sql_mode=@save_sql_mode;
drop function test.database;
drop function test.current_user;
drop function md5;
use test;
delimiter |;
# End of BUG#22619
--echo End of 5.1 tests
# #
# BUG#NNNN: New bug synopsis # BUG#NNNN: New bug synopsis
......
-- source include/have_geometry.inc
use test;
#
# BUG#21025: misleading error message when creating functions named 'x', or 'y'
#
--disable_warnings
drop function if exists a;
drop function if exists x;
drop function if exists y;
--enable_warnings
create function a() returns int
return 1;
create function x() returns int
return 2;
create function y() returns int
return 3;
select a();
--error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT
select x();
--error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT
select y();
select x(PointFromText("POINT(10 20)")), y(PointFromText("POINT(10 20)"));
select test.a(), test.x(), test.y();
drop function a;
drop function x;
drop function y;
...@@ -129,6 +129,42 @@ explain select myfunc_int(f1) from t1 order by 1; ...@@ -129,6 +129,42 @@ explain select myfunc_int(f1) from t1 order by 1;
drop table t1; drop table t1;
--echo End of 5.0 tests. --echo End of 5.0 tests.
#
# BUG#18239: Possible to overload internal functions with stored functions
#
--disable_warnings
drop function if exists pi;
--enable_warnings
--error ER_NATIVE_FCT_NAME_COLLISION
CREATE FUNCTION pi RETURNS STRING SONAME "should_not_parse.so";
# Verify that Stored Functions and UDF are mutually exclusive
DROP FUNCTION IF EXISTS metaphon;
CREATE FUNCTION metaphon(a int) RETURNS int
return 0;
--replace_result $UDF_EXAMPLE_LIB UDF_EXAMPLE_LIB
--error ER_UDF_EXISTS
eval CREATE FUNCTION metaphon RETURNS STRING SONAME "$UDF_EXAMPLE_LIB";
DROP FUNCTION metaphon;
--replace_result $UDF_EXAMPLE_LIB UDF_EXAMPLE_LIB
eval CREATE FUNCTION metaphon RETURNS STRING SONAME "$UDF_EXAMPLE_LIB";
--error ER_UDF_EXISTS
CREATE FUNCTION metaphon(a int) RETURNS int
return 0;
--error ER_UDF_EXISTS
CREATE FUNCTION test.metaphon(a int) RETURNS int
return 0;
# End of Bug#18239
# #
# Drop the example functions from udf_example # Drop the example functions from udf_example
# #
......
...@@ -6010,4 +6010,6 @@ ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT 42000 ...@@ -6010,4 +6010,6 @@ ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT 42000
eng "Incorrect parameter count in the call to native function '%-.64s'" eng "Incorrect parameter count in the call to native function '%-.64s'"
ER_WRONG_PARAMETERS_TO_NATIVE_FCT 42000 ER_WRONG_PARAMETERS_TO_NATIVE_FCT 42000
eng "Incorrect parameters in the call to native function '%-.64s'" eng "Incorrect parameters in the call to native function '%-.64s'"
ER_NATIVE_FCT_NAME_COLLISION
eng "This function '%-.64s' has the same name as a native function."
...@@ -242,6 +242,12 @@ bool is_keyword(const char *name, uint len) ...@@ -242,6 +242,12 @@ bool is_keyword(const char *name, uint len)
return get_hash_symbol(name,len,0)!=0; return get_hash_symbol(name,len,0)!=0;
} }
bool is_lex_native_function(const LEX_STRING *name)
{
DBUG_ASSERT(name != NULL);
return (get_hash_symbol(name->str, name->length, 1) != 0);
}
/* make a copy of token before ptr and set yytoklen */ /* make a copy of token before ptr and set yytoklen */
static LEX_STRING get_token(LEX *lex,uint length) static LEX_STRING get_token(LEX *lex,uint length)
......
...@@ -1230,4 +1230,6 @@ extern void lex_end(LEX *lex); ...@@ -1230,4 +1230,6 @@ extern void lex_end(LEX *lex);
extern int MYSQLlex(void *arg, void *yythd); extern int MYSQLlex(void *arg, void *yythd);
extern const uchar *skip_rear_comments(const uchar *ubegin, const uchar *uend); extern const uchar *skip_rear_comments(const uchar *ubegin, const uchar *uend);
extern bool is_lex_native_function(const LEX_STRING *name);
#endif /* MYSQL_SERVER */ #endif /* MYSQL_SERVER */
...@@ -97,6 +97,17 @@ void turn_parser_debug_on() ...@@ -97,6 +97,17 @@ void turn_parser_debug_on()
} }
#endif #endif
static bool is_native_function(THD *thd, const LEX_STRING *name)
{
if (find_native_function_builder(thd, *name))
return true;
if (is_lex_native_function(name))
return true;
return false;
}
%} %}
%union { %union {
int num; int num;
...@@ -1537,6 +1548,7 @@ sp_name: ...@@ -1537,6 +1548,7 @@ sp_name:
create_function_tail: create_function_tail:
RETURNS_SYM udf_type SONAME_SYM TEXT_STRING_sys RETURNS_SYM udf_type SONAME_SYM TEXT_STRING_sys
{ {
THD *thd= YYTHD;
LEX *lex=Lex; LEX *lex=Lex;
if (lex->definer != NULL) if (lex->definer != NULL)
{ {
...@@ -1549,6 +1561,12 @@ create_function_tail: ...@@ -1549,6 +1561,12 @@ create_function_tail:
my_error(ER_WRONG_USAGE, MYF(0), "SONAME", "DEFINER"); my_error(ER_WRONG_USAGE, MYF(0), "SONAME", "DEFINER");
YYABORT; YYABORT;
} }
if (is_native_function(thd, & lex->spname->m_name))
{
my_error(ER_NATIVE_FCT_NAME_COLLISION, MYF(0),
lex->spname->m_name.str);
YYABORT;
}
lex->sql_command = SQLCOM_CREATE_FUNCTION; lex->sql_command = SQLCOM_CREATE_FUNCTION;
lex->udf.name = lex->spname->m_name; lex->udf.name = lex->spname->m_name;
lex->udf.returns=(Item_result) $2; lex->udf.returns=(Item_result) $2;
...@@ -1637,6 +1655,7 @@ create_function_tail: ...@@ -1637,6 +1655,7 @@ create_function_tail:
} }
sp_proc_stmt sp_proc_stmt
{ {
THD *thd= YYTHD;
LEX *lex= Lex; LEX *lex= Lex;
sp_head *sp= lex->sphead; sp_head *sp= lex->sphead;
...@@ -1644,15 +1663,50 @@ create_function_tail: ...@@ -1644,15 +1663,50 @@ create_function_tail:
YYABORT; YYABORT;
lex->sql_command= SQLCOM_CREATE_SPFUNCTION; lex->sql_command= SQLCOM_CREATE_SPFUNCTION;
sp->init_strings(YYTHD, lex); sp->init_strings(thd, lex);
if (!(sp->m_flags & sp_head::HAS_RETURN)) if (!(sp->m_flags & sp_head::HAS_RETURN))
{ {
my_error(ER_SP_NORETURN, MYF(0), sp->m_qname.str); my_error(ER_SP_NORETURN, MYF(0), sp->m_qname.str);
YYABORT; YYABORT;
} }
if (is_native_function(thd, & sp->m_name))
{
/*
This warning will be printed when
[1] A client query is parsed,
[2] A stored function is loaded by db_load_routine.
Printing the warning for [2] is intentional, to cover the
following scenario:
- A user define a SF 'foo' using MySQL 5.N
- An application uses select foo(), and works.
- MySQL 5.{N+1} defines a new native function 'foo', as
part of a new feature.
- MySQL 5.{N+1} documentation is updated, and should mention
that there is a potential incompatible change in case of
existing stored function named 'foo'.
- The user deploys 5.{N+1}. At this point, 'select foo()'
means something different, and the user code is most likely
broken (it's only safe if the code is 'select db.foo()').
With a warning printed when the SF is loaded (which has to occur
before the call), the warning will provide a hint explaining
the root cause of a later failure of 'select foo()'.
With no warning printed, the user code will fail with no
apparent reason.
Printing a warning each time db_load_routine is executed for
an ambiguous function is annoying, since that can happen a lot,
but in practice should not happen unless there *are* name
collisions.
If a collision exists, it should not be silenced but fixed.
*/
push_warning_printf(thd,
MYSQL_ERROR::WARN_LEVEL_NOTE,
ER_NATIVE_FCT_NAME_COLLISION,
ER(ER_NATIVE_FCT_NAME_COLLISION),
sp->m_name.str);
}
/* Restore flag if it was cleared above */ /* Restore flag if it was cleared above */
YYTHD->client_capabilities |= $<ulong_num>2; thd->client_capabilities |= $<ulong_num>2;
sp->restore_thd_mem_root(YYTHD); sp->restore_thd_mem_root(thd);
} }
; ;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment