Commit fd3c6b18 authored by davi@virtua-cwbas201-21-158-74.ctb.virtua.com.br's avatar davi@virtua-cwbas201-21-158-74.ctb.virtua.com.br
Browse files

Bug#28318 CREATE FUNCTION (UDF) requires a schema

Bug#29816 Syntactically wrong query fails with misleading error message

The core problem is that an SQL-invoked function name can be a <schema
qualified routine name> that contains no <schema name>, but the mysql
parser insists that all stored procedures (function, procedures and
triggers) must have a <schema name>, which is not true for functions.
This problem is especially visible when trying to create a function
or when a query contains a syntax error after a function call (in the
same query), both will fail with a "No database selected" message if
the session is not attached to a particular schema, but the first
one should succeed and the second fail with a "syntax error" message.

Part of the fix is to revamp the sp name handling so that a schema
name may be omitted for functions -- this means that the internal
function name representation may not have a dot, which represents
that the function doesn't have a schema name. The other part is
to place schema checks after the type (function, trigger or procedure)
of the routine is known.
parent f4b671d8
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -1452,3 +1452,16 @@ end
until true end repeat retry;
end//
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;
+7 −0
Original line number Diff line number Diff line
@@ -296,4 +296,11 @@ Qcache_queries_in_cache 0
drop table t1;
drop function metaphon;
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.
+20 −0
Original line number Diff line number Diff line
@@ -2089,6 +2089,26 @@ end//

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
#
+14 −0
Original line number Diff line number Diff line
@@ -311,5 +311,19 @@ drop table t1;
drop function metaphon;
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.
+3 −10
Original line number Diff line number Diff line
@@ -1405,12 +1405,12 @@ static bool add_used_routine(LEX *lex, Query_arena *arena,
  {
    Sroutine_hash_entry *rn=
      (Sroutine_hash_entry *)arena->alloc(sizeof(Sroutine_hash_entry) +
                                          key->length);
                                          key->length + 1);
    if (!rn)              // OOM. Error will be reported using fatal_error().
      return FALSE;
    rn->key.length= key->length;
    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);
    lex->sroutines_list.link_in_list((byte *)rn, (byte **)&rn->next);
    rn->belong_to_view= belong_to_view;
@@ -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)
  {
    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];
    sp_head *sp;

@@ -1603,13 +1603,6 @@ sp_cache_routines_and_add_tables_aux(THD *thd, LEX *lex,
                              &thd->sp_func_cache : &thd->sp_proc_cache),
                              &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)))
      {
      case SP_OK:
Loading