Merge virtua-cwbas201-21-158-74.ctb.virtua.com.br:/Users/davi/mysql/push/bugs/28318-5.0

into  virtua-cwbas201-21-158-74.ctb.virtua.com.br:/Users/davi/mysql/push/mysql-5.0-runtime
parents c3d06676 fd3c6b18
...@@ -1452,3 +1452,16 @@ end ...@@ -1452,3 +1452,16 @@ end
until true end repeat retry; until true end repeat retry;
end// end//
ERROR 42000: LEAVE with no matching label: retry ERROR 42000: LEAVE with no matching label: retry
DROP DATABASE IF EXISTS mysqltest;
CREATE DATABASE mysqltest;
USE mysqltest;
DROP DATABASE mysqltest;
SELECT inexistent(), 1 + ,;
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 '' at line 1
SELECT inexistent();
ERROR 42000: FUNCTION inexistent does not exist
SELECT .inexistent();
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 '()' at line 1
SELECT ..inexistent();
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 '.inexistent()' at line 1
USE test;
...@@ -296,4 +296,11 @@ Qcache_queries_in_cache 0 ...@@ -296,4 +296,11 @@ Qcache_queries_in_cache 0
drop table t1; drop table t1;
drop function metaphon; drop function metaphon;
set GLOBAL query_cache_size=default; set GLOBAL query_cache_size=default;
DROP DATABASE IF EXISTS mysqltest;
CREATE DATABASE mysqltest;
USE mysqltest;
DROP DATABASE mysqltest;
CREATE FUNCTION metaphon RETURNS STRING SONAME "UDF_EXAMPLE_LIB";
DROP FUNCTION metaphon;
USE test;
End of 5.0 tests. End of 5.0 tests.
...@@ -2089,6 +2089,26 @@ end// ...@@ -2089,6 +2089,26 @@ end//
delimiter ;// delimiter ;//
#
# Bug#29816 Syntactically wrong query fails with misleading error message
#
--disable_warnings
DROP DATABASE IF EXISTS mysqltest;
--enable_warnings
CREATE DATABASE mysqltest;
USE mysqltest;
DROP DATABASE mysqltest;
--error ER_PARSE_ERROR
SELECT inexistent(), 1 + ,;
--error ER_SP_DOES_NOT_EXIST
SELECT inexistent();
--error ER_PARSE_ERROR
SELECT .inexistent();
--error ER_PARSE_ERROR
SELECT ..inexistent();
USE test;
# #
# BUG#NNNN: New bug synopsis # BUG#NNNN: New bug synopsis
# #
......
...@@ -311,5 +311,19 @@ drop table t1; ...@@ -311,5 +311,19 @@ drop table t1;
drop function metaphon; drop function metaphon;
set GLOBAL query_cache_size=default; set GLOBAL query_cache_size=default;
#
# Bug#28318 CREATE FUNCTION (UDF) requires a schema
#
--disable_warnings
DROP DATABASE IF EXISTS mysqltest;
--enable_warnings
CREATE DATABASE mysqltest;
USE mysqltest;
DROP DATABASE mysqltest;
--replace_result $UDF_EXAMPLE_LIB UDF_EXAMPLE_LIB
eval CREATE FUNCTION metaphon RETURNS STRING SONAME "$UDF_EXAMPLE_LIB";
DROP FUNCTION metaphon;
USE test;
--echo End of 5.0 tests. --echo End of 5.0 tests.
...@@ -1405,12 +1405,12 @@ static bool add_used_routine(LEX *lex, Query_arena *arena, ...@@ -1405,12 +1405,12 @@ static bool add_used_routine(LEX *lex, Query_arena *arena,
{ {
Sroutine_hash_entry *rn= Sroutine_hash_entry *rn=
(Sroutine_hash_entry *)arena->alloc(sizeof(Sroutine_hash_entry) + (Sroutine_hash_entry *)arena->alloc(sizeof(Sroutine_hash_entry) +
key->length); key->length + 1);
if (!rn) // OOM. Error will be reported using fatal_error(). if (!rn) // OOM. Error will be reported using fatal_error().
return FALSE; return FALSE;
rn->key.length= key->length; rn->key.length= key->length;
rn->key.str= (char *)rn + sizeof(Sroutine_hash_entry); rn->key.str= (char *)rn + sizeof(Sroutine_hash_entry);
memcpy(rn->key.str, key->str, key->length); memcpy(rn->key.str, key->str, key->length + 1);
my_hash_insert(&lex->sroutines, (byte *)rn); my_hash_insert(&lex->sroutines, (byte *)rn);
lex->sroutines_list.link_in_list((byte *)rn, (byte **)&rn->next); lex->sroutines_list.link_in_list((byte *)rn, (byte **)&rn->next);
rn->belong_to_view= belong_to_view; rn->belong_to_view= belong_to_view;
...@@ -1595,7 +1595,7 @@ sp_cache_routines_and_add_tables_aux(THD *thd, LEX *lex, ...@@ -1595,7 +1595,7 @@ sp_cache_routines_and_add_tables_aux(THD *thd, LEX *lex,
for (Sroutine_hash_entry *rt= start; rt; rt= rt->next) for (Sroutine_hash_entry *rt= start; rt; rt= rt->next)
{ {
sp_name name(rt->key.str, rt->key.length); sp_name name(thd, rt->key.str, rt->key.length);
int type= rt->key.str[0]; int type= rt->key.str[0];
sp_head *sp; sp_head *sp;
...@@ -1603,13 +1603,6 @@ sp_cache_routines_and_add_tables_aux(THD *thd, LEX *lex, ...@@ -1603,13 +1603,6 @@ sp_cache_routines_and_add_tables_aux(THD *thd, LEX *lex,
&thd->sp_func_cache : &thd->sp_proc_cache), &thd->sp_func_cache : &thd->sp_proc_cache),
&name))) &name)))
{ {
name.m_name.str= strchr(name.m_qname.str, '.');
name.m_db.length= name.m_name.str - name.m_qname.str;
name.m_db.str= strmake_root(thd->mem_root, name.m_qname.str,
name.m_db.length);
name.m_name.str+= 1;
name.m_name.length= name.m_qname.length - name.m_db.length - 1;
switch ((ret= db_find_routine(thd, type, &name, &sp))) switch ((ret= db_find_routine(thd, type, &name, &sp)))
{ {
case SP_OK: case SP_OK:
......
...@@ -369,17 +369,42 @@ sp_eval_expr(THD *thd, Field *result_field, Item **expr_item_ptr) ...@@ -369,17 +369,42 @@ sp_eval_expr(THD *thd, Field *result_field, Item **expr_item_ptr)
* *
*/ */
sp_name::sp_name(THD *thd, char *key, uint key_len)
{
m_sroutines_key.str= key;
m_sroutines_key.length= key_len;
m_qname.str= ++key;
m_qname.length= key_len - 1;
if ((m_name.str= strchr(m_qname.str, '.')))
{
m_db.length= m_name.str - key;
m_db.str= strmake_root(thd->mem_root, key, m_db.length);
m_name.str++;
m_name.length= m_qname.length - m_db.length - 1;
}
else
{
m_name.str= m_qname.str;
m_name.length= m_qname.length;
m_db.str= 0;
m_db.length= 0;
}
m_explicit_name= false;
}
void void
sp_name::init_qname(THD *thd) sp_name::init_qname(THD *thd)
{ {
m_sroutines_key.length= m_db.length + m_name.length + 2; const uint dot= !!m_db.length;
/* m_sroutines format: m_type + [database + dot] + name + nul */
m_sroutines_key.length= 1 + m_db.length + dot + m_name.length;
if (!(m_sroutines_key.str= thd->alloc(m_sroutines_key.length + 1))) if (!(m_sroutines_key.str= thd->alloc(m_sroutines_key.length + 1)))
return; return;
m_qname.length= m_sroutines_key.length - 1; m_qname.length= m_sroutines_key.length - 1;
m_qname.str= m_sroutines_key.str + 1; m_qname.str= m_sroutines_key.str + 1;
sprintf(m_qname.str, "%.*s.%.*s", sprintf(m_qname.str, "%.*s%.*s%.*s",
m_db.length, (m_db.length ? m_db.str : ""), m_db.length, (m_db.length ? m_db.str : ""),
m_name.length, m_name.str); dot, ".", m_name.length, m_name.str);
} }
......
...@@ -72,16 +72,7 @@ class sp_name : public Sql_alloc ...@@ -72,16 +72,7 @@ class sp_name : public Sql_alloc
Creates temporary sp_name object from key, used mainly Creates temporary sp_name object from key, used mainly
for SP-cache lookups. for SP-cache lookups.
*/ */
sp_name(char *key, uint key_len) sp_name(THD *thd, char *key, uint key_len);
{
m_sroutines_key.str= key;
m_sroutines_key.length= key_len;
m_name.str= m_qname.str= key + 1;
m_name.length= m_qname.length= key_len - 1;
m_db.str= 0;
m_db.length= 0;
m_explicit_name= false;
}
// Init. the qualified name from the db and name. // Init. the qualified name from the db and name.
void init_qname(THD *thd); // thd for memroot allocation void init_qname(THD *thd); // thd for memroot allocation
......
...@@ -1570,13 +1570,15 @@ sp_name: ...@@ -1570,13 +1570,15 @@ sp_name:
| ident | ident
{ {
LEX *lex= Lex; LEX *lex= Lex;
LEX_STRING db; LEX_STRING db= {0,0};
THD *thd= YYTHD;
if (check_routine_name($1)) if (check_routine_name($1))
{ {
my_error(ER_SP_WRONG_NAME, MYF(0), $1.str); my_error(ER_SP_WRONG_NAME, MYF(0), $1.str);
MYSQL_YYABORT; MYSQL_YYABORT;
} }
if (lex->copy_db_to(&db.str, &db.length)) if (thd->db && thd->copy_db_to(&db.str, &db.length))
MYSQL_YYABORT; MYSQL_YYABORT;
$$= new sp_name(db, $1, false); $$= new sp_name(db, $1, false);
if ($$) if ($$)
...@@ -1626,6 +1628,13 @@ create_function_tail: ...@@ -1626,6 +1628,13 @@ create_function_tail:
my_error(ER_SP_NO_RECURSIVE_CREATE, MYF(0), "FUNCTION"); my_error(ER_SP_NO_RECURSIVE_CREATE, MYF(0), "FUNCTION");
MYSQL_YYABORT; MYSQL_YYABORT;
} }
if (!lex->spname->m_db.length)
{
my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
MYSQL_YYABORT;
}
/* Order is important here: new - reset - init */ /* Order is important here: new - reset - init */
sp= new sp_head(); sp= new sp_head();
sp->reset_thd_mem_root(thd); sp->reset_thd_mem_root(thd);
...@@ -5195,8 +5204,8 @@ simple_expr: ...@@ -5195,8 +5204,8 @@ simple_expr:
#endif /* HAVE_DLOPEN */ #endif /* HAVE_DLOPEN */
{ {
THD *thd= lex->thd; THD *thd= lex->thd;
LEX_STRING db; LEX_STRING db= {0,0};
if (lex->copy_db_to(&db.str, &db.length)) if (thd->db && thd->copy_db_to(&db.str, &db.length))
MYSQL_YYABORT; MYSQL_YYABORT;
sp_name *name= new sp_name(db, $1, false); sp_name *name= new sp_name(db, $1, false);
if (name) if (name)
...@@ -9746,6 +9755,12 @@ trigger_tail: ...@@ -9746,6 +9755,12 @@ trigger_tail:
MYSQL_YYABORT; MYSQL_YYABORT;
} }
if (!$3->m_db.length)
{
my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
MYSQL_YYABORT;
}
if (!(sp= new sp_head())) if (!(sp= new sp_head()))
MYSQL_YYABORT; MYSQL_YYABORT;
sp->reset_thd_mem_root(thd); sp->reset_thd_mem_root(thd);
...@@ -9828,6 +9843,12 @@ sp_tail: ...@@ -9828,6 +9843,12 @@ sp_tail:
MYSQL_YYABORT; MYSQL_YYABORT;
} }
if (!$3->m_db.length)
{
my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
MYSQL_YYABORT;
}
lex->stmt_definition_begin= $2; lex->stmt_definition_begin= $2;
/* Order is important here: new - reset - init */ /* Order is important here: new - reset - init */
......
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