summaryrefslogtreecommitdiff
path: root/sql/sql_yacc.yy
diff options
context:
space:
mode:
authorunknown <davi@virtua-cwbas201-21-158-74.ctb.virtua.com.br>2007-10-09 20:46:33 -0300
committerunknown <davi@virtua-cwbas201-21-158-74.ctb.virtua.com.br>2007-10-09 20:46:33 -0300
commitad104d5bfd455f245bd3e9602fd01e60b6e9f783 (patch)
treef3f7438416dcb6b9a5fca1af52cd41c113252566 /sql/sql_yacc.yy
parent5c836d24f64eb99aba3cb94da3ee90bcca209500 (diff)
downloadmariadb-git-ad104d5bfd455f245bd3e9602fd01e60b6e9f783.tar.gz
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. mysql-test/r/sp-error.result: Add test case result for Bug#29816 mysql-test/r/udf.result: Add test case result for Bug#28318 mysql-test/t/sp-error.test: Add test case for Bug#29816 mysql-test/t/udf.test: Add test case for Bug#28318 sql/sp.cc: Copy the (last) nul byte of the stored routine key and move name parsing code to the sp_name class constructor. sql/sp_head.cc: Revamp routine name parsing for when no schema is specified and omit dot from the qualified name if the routine is not associated with a scheme name. sql/sp_head.h: Name parsing got bigger, uninline by moving to a single unit -- the sp_head.cc file. sql/sql_yacc.yy: Only copy the schema name if one is actually set and check for schema name presence only where it's necessary.
Diffstat (limited to 'sql/sql_yacc.yy')
-rw-r--r--sql/sql_yacc.yy31
1 files changed, 26 insertions, 5 deletions
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index e0b9ab28594..7e3c11b5122 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -1569,13 +1569,15 @@ sp_name:
| ident
{
LEX *lex= Lex;
- LEX_STRING db;
+ LEX_STRING db= {0,0};
+ THD *thd= YYTHD;
+
if (check_routine_name($1))
{
my_error(ER_SP_WRONG_NAME, MYF(0), $1.str);
MYSQL_YYABORT;
}
- if (lex->copy_db_to(&db.str, &db.length))
+ if (thd->db && thd->copy_db_to(&db.str, &db.length))
MYSQL_YYABORT;
$$= new sp_name(db, $1, false);
if ($$)
@@ -1625,6 +1627,13 @@ create_function_tail:
my_error(ER_SP_NO_RECURSIVE_CREATE, MYF(0), "FUNCTION");
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 */
sp= new sp_head();
sp->reset_thd_mem_root(thd);
@@ -5194,8 +5203,8 @@ simple_expr:
#endif /* HAVE_DLOPEN */
{
THD *thd= lex->thd;
- LEX_STRING db;
- if (lex->copy_db_to(&db.str, &db.length))
+ LEX_STRING db= {0,0};
+ if (thd->db && thd->copy_db_to(&db.str, &db.length))
MYSQL_YYABORT;
sp_name *name= new sp_name(db, $1, false);
if (name)
@@ -9730,7 +9739,13 @@ trigger_tail:
my_error(ER_SP_NO_RECURSIVE_CREATE, MYF(0), "TRIGGER");
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()))
MYSQL_YYABORT;
sp->reset_thd_mem_root(thd);
@@ -9813,6 +9828,12 @@ sp_tail:
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;
/* Order is important here: new - reset - init */