mirror of
https://github.com/MariaDB/server.git
synced 2026-05-06 15:15:34 +02:00
WL#1366: Use the schema (db) associated with an SP.
Phase 3: Made qualified names work for functions as well. mysql-test/r/sp-security.result: New testcases for functions with qualified names. mysql-test/t/sp-security.test: New testcases for functions with qualified names. sql/item_func.cc: Added error handling for stored function, if it doesn't exist. sql/item_func.h: Set null_value if execution of a stored function fails. sql/mysql_priv.h: Reverted previous change: No optional args for mysql_change_db(). (SPs use a specially tailored function instead.) sql/sp.cc: Copied mysql_change_db() from sql_db.cc and modified specially for SPs. sql/sp_head.cc: Fixed error handling for errors in functions during query/statement execution. sql/sql_db.cc: Reverted previous change: No optional args for mysql_change_db(). (SPs use a specially tailored function instead.) sql/sql_yacc.yy: Reworked the stored function/UDF invokation parsing and added qualified names for stored functions. UDFs now have precedence over stored functions (whith unqualified name). When using an unqualified name, only IDENT_sys is allowed (i.e. no unreserved keywords), since we get unresolvable reduce/reduce conflicts otherwise.
This commit is contained in:
parent
edf2003009
commit
d2ad3cff19
9 changed files with 286 additions and 143 deletions
106
sql/sp.cc
106
sql/sp.cc
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
|
||||
#include "mysql_priv.h"
|
||||
#include "sql_acl.h"
|
||||
#include "sp.h"
|
||||
#include "sp_head.h"
|
||||
#include "sp_cache.h"
|
||||
|
|
@ -960,19 +961,104 @@ sp_use_new_db(THD *thd, char *newdb, char *olddb, uint olddblen,
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Change database.
|
||||
|
||||
SYNOPSIS
|
||||
sp_change_db()
|
||||
thd Thread handler
|
||||
name Database name
|
||||
empty_is_ok True= it's ok with "" as name
|
||||
no_access_check True= don't do access check
|
||||
|
||||
DESCRIPTION
|
||||
This is the same as mysql_change_db(), but with some extra
|
||||
arguments for Stored Procedure usage; doing implicit "use"
|
||||
when executing an SP in a different database.
|
||||
We also use different error routines, since this might be
|
||||
invoked from a function when executing a query or statement.
|
||||
Note: We would have prefered to reuse mysql_change_db(), but
|
||||
the error handling in particular made that too awkward, so
|
||||
we (reluctantly) have a "copy" here.
|
||||
|
||||
RETURN VALUES
|
||||
0 ok
|
||||
1 error
|
||||
*/
|
||||
|
||||
int
|
||||
sp_change_db(THD *thd, char *db, bool no_access_check)
|
||||
sp_change_db(THD *thd, char *name, bool no_access_check)
|
||||
{
|
||||
int ret;
|
||||
ulong dbaccess= thd->db_access; /* mysql_change_db() changes this */
|
||||
my_bool nsok= thd->net.no_send_ok; /* mysql_change_db() does send_ok() */
|
||||
thd->net.no_send_ok= TRUE;
|
||||
int length, db_length;
|
||||
char *dbname=my_strdup((char*) name,MYF(MY_WME));
|
||||
char path[FN_REFLEN];
|
||||
ulong db_access;
|
||||
HA_CREATE_INFO create;
|
||||
DBUG_ENTER("sp_change_db");
|
||||
DBUG_PRINT("enter", ("db: %s, no_access_check: %d", db, no_access_check));
|
||||
DBUG_PRINT("enter", ("db: %s, no_access_check: %d", name, no_access_check));
|
||||
|
||||
ret= mysql_change_db(thd, db, 1, no_access_check);
|
||||
db_length= (!dbname ? 0 : strip_sp(dbname));
|
||||
if (dbname && db_length)
|
||||
{
|
||||
if ((db_length > NAME_LEN) || check_db_name(dbname))
|
||||
{
|
||||
my_printf_error(ER_WRONG_DB_NAME, ER(ER_WRONG_DB_NAME), MYF(0), dbname);
|
||||
x_free(dbname);
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
}
|
||||
|
||||
thd->net.no_send_ok= nsok;
|
||||
thd->db_access= dbaccess;
|
||||
DBUG_RETURN(ret);
|
||||
if (dbname && db_length)
|
||||
{
|
||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||
if (! no_access_check)
|
||||
{
|
||||
if (test_all_bits(thd->master_access,DB_ACLS))
|
||||
db_access=DB_ACLS;
|
||||
else
|
||||
db_access= (acl_get(thd->host,thd->ip, thd->priv_user,dbname,0) |
|
||||
thd->master_access);
|
||||
if (!(db_access & DB_ACLS) &&
|
||||
(!grant_option || check_grant_db(thd,dbname)))
|
||||
{
|
||||
my_printf_error(ER_DBACCESS_DENIED_ERROR, ER(ER_DBACCESS_DENIED_ERROR),
|
||||
MYF(0),
|
||||
thd->priv_user,
|
||||
thd->priv_host,
|
||||
dbname);
|
||||
mysql_log.write(thd,COM_INIT_DB,ER(ER_DBACCESS_DENIED_ERROR),
|
||||
thd->priv_user,
|
||||
thd->priv_host,
|
||||
dbname);
|
||||
my_free(dbname,MYF(0));
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
(void) sprintf(path,"%s/%s",mysql_data_home,dbname);
|
||||
length=unpack_dirname(path,path); // Convert if not unix
|
||||
if (length && path[length-1] == FN_LIBCHAR)
|
||||
path[length-1]=0; // remove ending '\'
|
||||
if (access(path,F_OK))
|
||||
{
|
||||
my_printf_error(ER_BAD_DB_ERROR, ER(ER_BAD_DB_ERROR), MYF(0), dbname);
|
||||
my_free(dbname,MYF(0));
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
}
|
||||
|
||||
x_free(thd->db);
|
||||
thd->db=dbname; // THD::~THD will free this
|
||||
thd->db_length=db_length;
|
||||
|
||||
if (dbname && db_length)
|
||||
{
|
||||
strmov(path+unpack_dirname(path,path), MY_DB_OPT_FILE);
|
||||
load_db_opt(thd, path, &create);
|
||||
thd->db_charset= create.default_table_charset ?
|
||||
create.default_table_charset :
|
||||
thd->variables.collation_server;
|
||||
thd->variables.collation_database= thd->db_charset;
|
||||
}
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue