Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
MariaDB
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nexedi
MariaDB
Commits
6ac3d751
Commit
6ac3d751
authored
Aug 15, 2017
by
Alexander Barkov
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'origin/bb-10.2-ext' into 10.3
parents
1743883d
b5098f3d
Changes
13
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
177 additions
and
120 deletions
+177
-120
mysql-test/r/lowercase_fs_off.result
mysql-test/r/lowercase_fs_off.result
+1
-1
sql/item_func.cc
sql/item_func.cc
+13
-12
sql/item_func.h
sql/item_func.h
+1
-1
sql/sp_head.cc
sql/sp_head.cc
+11
-10
sql/sp_head.h
sql/sp_head.h
+3
-1
sql/sql_class.cc
sql/sql_class.cc
+11
-0
sql/sql_class.h
sql/sql_class.h
+4
-2
sql/sql_cmd.h
sql/sql_cmd.h
+29
-0
sql/sql_lex.cc
sql/sql_lex.cc
+29
-1
sql/sql_lex.h
sql/sql_lex.h
+2
-0
sql/sql_parse.cc
sql/sql_parse.cc
+64
-54
sql/sql_yacc.yy
sql/sql_yacc.yy
+5
-18
sql/sql_yacc_ora.yy
sql/sql_yacc_ora.yy
+4
-20
No files found.
mysql-test/r/lowercase_fs_off.result
View file @
6ac3d751
...
...
@@ -61,7 +61,7 @@ connect con2,localhost,USER_1,,db1;
call p1();
ERROR 42000: execute command denied to user 'USER_1'@'localhost' for routine 'db1.p1'
call P1();
ERROR 42000: execute command denied to user 'USER_1'@'localhost' for routine 'db1.
P
1'
ERROR 42000: execute command denied to user 'USER_1'@'localhost' for routine 'db1.
p
1'
select f1(1);
ERROR 42000: execute command denied to user 'USER_1'@'localhost' for routine 'db1.f1'
connection default;
...
...
sql/item_func.cc
View file @
6ac3d751
...
...
@@ -6257,7 +6257,7 @@ void my_missing_function_error(const LEX_CSTRING &token, const char *func_name)
*/
bool
Item_func_sp
::
init_result_field
(
THD
*
thd
)
Item_func_sp
::
init_result_field
(
THD
*
thd
,
sp_head
*
sp
)
{
TABLE_SHARE
*
share
;
DBUG_ENTER
(
"Item_func_sp::init_result_field"
);
...
...
@@ -6265,7 +6265,7 @@ Item_func_sp::init_result_field(THD *thd)
DBUG_ASSERT
(
m_sp
==
NULL
);
DBUG_ASSERT
(
sp_result_field
==
NULL
);
if
(
!
(
m_sp
=
sp
_handler_function
.
sp_find_routine
(
thd
,
m_name
,
true
)
))
if
(
!
(
m_sp
=
sp
))
{
my_missing_function_error
(
m_name
->
m_name
,
ErrConvDQName
(
m_name
).
ptr
());
context
->
process_error
(
thd
);
...
...
@@ -6513,12 +6513,7 @@ Item_func_sp::sp_check_access(THD *thd)
{
DBUG_ENTER
(
"Item_func_sp::sp_check_access"
);
DBUG_ASSERT
(
m_sp
);
if
(
check_routine_access
(
thd
,
EXECUTE_ACL
,
m_sp
->
m_db
.
str
,
m_sp
->
m_name
.
str
,
&
sp_handler_function
,
false
))
DBUG_RETURN
(
TRUE
);
DBUG_RETURN
(
FALSE
);
DBUG_RETURN
(
m_sp
->
check_execute_access
(
thd
));
}
...
...
@@ -6528,6 +6523,7 @@ Item_func_sp::fix_fields(THD *thd, Item **ref)
bool
res
;
DBUG_ENTER
(
"Item_func_sp::fix_fields"
);
DBUG_ASSERT
(
fixed
==
0
);
sp_head
*
sp
=
sp_handler_function
.
sp_find_routine
(
thd
,
m_name
,
true
);
/*
Checking privileges to execute the function while creating view and
...
...
@@ -6540,9 +6536,14 @@ Item_func_sp::fix_fields(THD *thd, Item **ref)
if
(
context
->
security_ctx
)
thd
->
security_ctx
=
context
->
security_ctx
;
res
=
check_routine_access
(
thd
,
EXECUTE_ACL
,
m_name
->
m_db
.
str
,
m_name
->
m_name
.
str
,
&
sp_handler_function
,
false
);
/*
If the routine is not found, let's still check EXECUTE_ACL to decide
whether to return "Access denied" or "Routine does not exist".
*/
res
=
sp
?
sp
->
check_execute_access
(
thd
)
:
check_routine_access
(
thd
,
EXECUTE_ACL
,
m_name
->
m_db
.
str
,
m_name
->
m_name
.
str
,
&
sp_handler_function
,
false
);
thd
->
security_ctx
=
save_security_ctx
;
if
(
res
)
...
...
@@ -6557,7 +6558,7 @@ Item_func_sp::fix_fields(THD *thd, Item **ref)
to make m_sp and result_field members available to fix_length_and_dec(),
which is called from Item_func::fix_fields().
*/
res
=
init_result_field
(
thd
);
res
=
init_result_field
(
thd
,
sp
);
if
(
res
)
DBUG_RETURN
(
res
);
...
...
sql/item_func.h
View file @
6ac3d751
...
...
@@ -2679,7 +2679,7 @@ class Item_func_sp :public Item_func
bool
execute
();
bool
execute_impl
(
THD
*
thd
);
bool
init_result_field
(
THD
*
thd
);
bool
init_result_field
(
THD
*
thd
,
sp_head
*
sp
);
protected:
bool
is_expensive_processor
(
void
*
arg
)
...
...
sql/sp_head.cc
View file @
6ac3d751
...
...
@@ -610,7 +610,7 @@ sp_head::init(LEX *lex)
void
sp_head
::
init_sp_name
(
THD
*
thd
,
const
sp_name
*
spname
)
sp_head
::
init_sp_name
(
const
sp_name
*
spname
)
{
DBUG_ENTER
(
"sp_head::init_sp_name"
);
...
...
@@ -619,17 +619,10 @@ sp_head::init_sp_name(THD *thd, const sp_name *spname)
DBUG_ASSERT
(
spname
&&
spname
->
m_db
.
str
&&
spname
->
m_db
.
length
);
/* We have to copy strings to get them into the right memroot. */
m_db
.
length
=
spname
->
m_db
.
length
;
m_db
.
str
=
strmake_root
(
thd
->
mem_root
,
spname
->
m_db
.
str
,
spname
->
m_db
.
length
);
m_name
.
length
=
spname
->
m_name
.
length
;
m_name
.
str
=
strmake_root
(
thd
->
mem_root
,
spname
->
m_name
.
str
,
spname
->
m_name
.
length
);
Database_qualified_name
::
copy
(
&
main_mem_root
,
spname
->
m_db
,
spname
->
m_name
);
m_explicit_name
=
spname
->
m_explicit_name
;
spname
->
make_qname
(
thd
,
&
m_qname
);
spname
->
make_qname
(
&
main_mem_root
,
&
m_qname
);
DBUG_VOID_RETURN
;
}
...
...
@@ -1424,6 +1417,14 @@ set_routine_security_ctx(THD *thd, sp_head *sp, Security_context **save_ctx)
#endif // ! NO_EMBEDDED_ACCESS_CHECKS
bool
sp_head
::
check_execute_access
(
THD
*
thd
)
const
{
return
check_routine_access
(
thd
,
EXECUTE_ACL
,
m_db
.
str
,
m_name
.
str
,
m_handler
,
false
);
}
/**
Create rcontext using the routine security.
This is important for sql_mode=ORACLE to make sure that the invoker has
...
...
sql/sp_head.h
View file @
6ac3d751
...
...
@@ -320,7 +320,7 @@ class sp_head :private Query_arena,
/** Copy sp name from parser. */
void
init_sp_name
(
THD
*
thd
,
const
sp_name
*
spname
);
init_sp_name
(
const
sp_name
*
spname
);
/** Set the body-definition start position. */
void
...
...
@@ -791,6 +791,8 @@ class sp_head :private Query_arena,
sp_pcontext
*
get_parse_context
()
{
return
m_pcont
;
}
bool
check_execute_access
(
THD
*
thd
)
const
;
private:
MEM_ROOT
*
m_thd_root
;
///< Temp. store for thd's mem_root
...
...
sql/sql_class.cc
View file @
6ac3d751
...
...
@@ -7505,4 +7505,15 @@ void AUTHID::parse(const char *str, size_t length)
}
void
Database_qualified_name
::
copy
(
MEM_ROOT
*
mem_root
,
const
LEX_CSTRING
&
db
,
const
LEX_CSTRING
&
name
)
{
m_db
.
length
=
db
.
length
;
m_db
.
str
=
strmake_root
(
mem_root
,
db
.
str
,
db
.
length
);
m_name
.
length
=
name
.
length
;
m_name
.
str
=
strmake_root
(
mem_root
,
name
.
str
,
name
.
length
);
}
#endif
/* !defined(MYSQL_CLIENT) */
sql/sql_class.h
View file @
6ac3d751
...
...
@@ -6001,6 +6001,8 @@ class Database_qualified_name
(
const
uchar
*
)
m_name
.
str
,
m_name
.
length
,
(
const
uchar
*
)
other
->
m_name
.
str
,
other
->
m_name
.
length
);
}
void
copy
(
MEM_ROOT
*
mem_root
,
const
LEX_CSTRING
&
db
,
const
LEX_CSTRING
&
name
);
// Export db and name as a qualified name string: 'db.name'
size_t
make_qname
(
char
*
dst
,
size_t
dstlen
)
const
{
...
...
@@ -6009,13 +6011,13 @@ class Database_qualified_name
(
int
)
m_name
.
length
,
m_name
.
str
);
}
// Export db and name as a qualified name string, allocate on mem_root.
bool
make_qname
(
THD
*
thd
,
LEX_CSTRING
*
dst
)
const
bool
make_qname
(
MEM_ROOT
*
mem_root
,
LEX_CSTRING
*
dst
)
const
{
const
uint
dot
=
!!
m_db
.
length
;
char
*
tmp
;
/* format: [database + dot] + name + '\0' */
dst
->
length
=
m_db
.
length
+
dot
+
m_name
.
length
;
if
(
!
(
dst
->
str
=
tmp
=
(
char
*
)
thd
->
alloc
(
dst
->
length
+
1
)))
if
(
!
(
dst
->
str
=
tmp
=
(
char
*
)
alloc_root
(
mem_root
,
dst
->
length
+
1
)))
return
true
;
sprintf
(
tmp
,
"%.*s%.*s%.*s"
,
(
int
)
m_db
.
length
,
(
m_db
.
length
?
m_db
.
str
:
""
),
...
...
sql/sql_cmd.h
View file @
6ac3d751
...
...
@@ -167,4 +167,33 @@ class Sql_cmd : public Sql_alloc
}
};
/**
Sql_cmd_call represents the CALL statement.
*/
class
Sql_cmd_call
:
public
Sql_cmd
{
public:
class
sp_name
*
m_name
;
Sql_cmd_call
(
class
sp_name
*
name
)
:
m_name
(
name
)
{}
virtual
~
Sql_cmd_call
()
{}
/**
Execute a CALL statement at runtime.
@param thd the current thread.
@return false on success.
*/
bool
execute
(
THD
*
thd
);
virtual
enum_sql_command
sql_command_code
()
const
{
return
SQLCOM_CALL
;
}
};
#endif // SQL_CMD_INCLUDED
sql/sql_lex.cc
View file @
6ac3d751
...
...
@@ -5845,7 +5845,7 @@ sp_head *LEX::make_sp_head(THD *thd, const sp_name *name,
sp
->
reset_thd_mem_root
(
thd
);
sp
->
init
(
this
);
if
(
name
)
sp
->
init_sp_name
(
thd
,
name
);
sp
->
init_sp_name
(
name
);
sphead
=
sp
;
}
sp_chistics
.
init
();
...
...
@@ -5853,6 +5853,32 @@ sp_head *LEX::make_sp_head(THD *thd, const sp_name *name,
}
bool
LEX
::
sp_body_finalize_procedure
(
THD
*
thd
)
{
if
(
sphead
->
check_unresolved_goto
())
return
true
;
sphead
->
set_stmt_end
(
thd
);
sphead
->
restore_thd_mem_root
(
thd
);
return
false
;
}
bool
LEX
::
sp_body_finalize_function
(
THD
*
thd
)
{
if
(
sphead
->
is_not_allowed_in_function
(
"function"
))
return
true
;
if
(
!
(
sphead
->
m_flags
&
sp_head
::
HAS_RETURN
))
{
my_error
(
ER_SP_NORETURN
,
MYF
(
0
),
ErrConvDQName
(
sphead
).
ptr
());
return
true
;
}
if
(
sp_body_finalize_procedure
(
thd
))
return
true
;
(
void
)
is_native_function_with_warn
(
thd
,
&
sphead
->
m_name
);
return
false
;
}
bool
LEX
::
sp_block_with_exceptions_finalize_declarations
(
THD
*
thd
)
{
/*
...
...
@@ -7160,6 +7186,8 @@ bool LEX::call_statement_start(THD *thd, sp_name *name)
sql_command
=
SQLCOM_CALL
;
spname
=
name
;
value_list
.
empty
();
if
(
!
(
m_sql_cmd
=
new
(
thd
->
mem_root
)
Sql_cmd_call
(
name
)))
return
true
;
sp_handler_procedure
.
add_used_routine
(
this
,
thd
,
name
);
return
false
;
}
...
...
sql/sql_lex.h
View file @
6ac3d751
...
...
@@ -3176,6 +3176,8 @@ struct LEX: public Query_tables_list
return
NULL
;
return
make_sp_head_no_recursive
(
thd
,
name
,
sph
);
}
bool
sp_body_finalize_function
(
THD
*
);
bool
sp_body_finalize_procedure
(
THD
*
);
bool
call_statement_start
(
THD
*
thd
,
sp_name
*
name
);
bool
call_statement_start
(
THD
*
thd
,
const
LEX_CSTRING
*
name
);
bool
call_statement_start
(
THD
*
thd
,
const
LEX_CSTRING
*
name1
,
...
...
sql/sql_parse.cc
View file @
6ac3d751
...
...
@@ -3074,6 +3074,69 @@ static bool prepare_db_action(THD *thd, ulong want_access, LEX_CSTRING *dbname)
return
check_access
(
thd
,
want_access
,
dbname
->
str
,
NULL
,
NULL
,
1
,
0
);
}
bool
Sql_cmd_call
::
execute
(
THD
*
thd
)
{
TABLE_LIST
*
all_tables
=
thd
->
lex
->
query_tables
;
sp_head
*
sp
;
/*
This will cache all SP and SF and open and lock all tables
required for execution.
*/
if
(
check_table_access
(
thd
,
SELECT_ACL
,
all_tables
,
FALSE
,
UINT_MAX
,
FALSE
)
||
open_and_lock_tables
(
thd
,
all_tables
,
TRUE
,
0
))
return
true
;
/*
By this moment all needed SPs should be in cache so no need to look
into DB.
*/
if
(
!
(
sp
=
sp_handler_procedure
.
sp_find_routine
(
thd
,
m_name
,
true
)))
{
/*
If the routine is not found, let's still check EXECUTE_ACL to decide
whether to return "Access denied" or "Routine does not exist".
*/
if
(
check_routine_access
(
thd
,
EXECUTE_ACL
,
m_name
->
m_db
.
str
,
m_name
->
m_name
.
str
,
&
sp_handler_procedure
,
false
))
return
true
;
/*
sp_find_routine can have issued an ER_SP_RECURSION_LIMIT error.
Send message ER_SP_DOES_NOT_EXIST only if procedure is not found in
cache.
*/
if
(
!
sp_cache_lookup
(
&
thd
->
sp_proc_cache
,
m_name
))
my_error
(
ER_SP_DOES_NOT_EXIST
,
MYF
(
0
),
"PROCEDURE"
,
ErrConvDQName
(
m_name
).
ptr
());
return
true
;
}
else
{
if
(
sp
->
check_execute_access
(
thd
))
return
true
;
/*
Check that the stored procedure doesn't contain Dynamic SQL
and doesn't return result sets: such stored procedures can't
be called from a function or trigger.
*/
if
(
thd
->
in_sub_stmt
)
{
const
char
*
where
=
(
thd
->
in_sub_stmt
&
SUB_STMT_TRIGGER
?
"trigger"
:
"function"
);
if
(
sp
->
is_not_allowed_in_function
(
where
))
return
true
;
}
if
(
do_execute_sp
(
thd
,
sp
))
return
true
;
}
return
false
;
}
/**
Execute command saved in thd and lex->sql_command.
...
...
@@ -5748,60 +5811,6 @@ mysql_execute_command(THD *thd)
my_ok
(
thd
);
break
;
/* break super switch */
}
/* end case group bracket */
case
SQLCOM_CALL
:
{
sp_head
*
sp
;
/*
This will cache all SP and SF and open and lock all tables
required for execution.
*/
if
(
check_table_access
(
thd
,
SELECT_ACL
,
all_tables
,
FALSE
,
UINT_MAX
,
FALSE
)
||
open_and_lock_tables
(
thd
,
all_tables
,
TRUE
,
0
))
goto
error
;
if
(
check_routine_access
(
thd
,
EXECUTE_ACL
,
lex
->
spname
->
m_db
.
str
,
lex
->
spname
->
m_name
.
str
,
&
sp_handler_procedure
,
false
))
goto
error
;
/*
By this moment all needed SPs should be in cache so no need to look
into DB.
*/
if
(
!
(
sp
=
sp_handler_procedure
.
sp_find_routine
(
thd
,
lex
->
spname
,
true
)))
{
/*
sp_find_routine can have issued an ER_SP_RECURSION_LIMIT error.
Send message ER_SP_DOES_NOT_EXIST only if procedure is not found in
cache.
*/
if
(
!
sp_cache_lookup
(
&
thd
->
sp_proc_cache
,
lex
->
spname
))
my_error
(
ER_SP_DOES_NOT_EXIST
,
MYF
(
0
),
"PROCEDURE"
,
ErrConvDQName
(
lex
->
spname
).
ptr
());
goto
error
;
}
else
{
/*
Check that the stored procedure doesn't contain Dynamic SQL
and doesn't return result sets: such stored procedures can't
be called from a function or trigger.
*/
if
(
thd
->
in_sub_stmt
)
{
const
char
*
where
=
(
thd
->
in_sub_stmt
&
SUB_STMT_TRIGGER
?
"trigger"
:
"function"
);
if
(
sp
->
is_not_allowed_in_function
(
where
))
goto
error
;
}
if
(
do_execute_sp
(
thd
,
sp
))
goto
error
;
}
break
;
}
case
SQLCOM_COMPOUND
:
DBUG_ASSERT
(
all_tables
==
0
);
DBUG_ASSERT
(
thd
->
in_sub_stmt
==
0
);
...
...
@@ -6196,6 +6205,7 @@ mysql_execute_command(THD *thd)
case
SQLCOM_SIGNAL
:
case
SQLCOM_RESIGNAL
:
case
SQLCOM_GET_DIAGNOSTICS
:
case
SQLCOM_CALL
:
DBUG_ASSERT
(
lex
->
m_sql_cmd
!=
NULL
);
res
=
lex
->
m_sql_cmd
->
execute
(
thd
);
break
;
...
...
sql/sql_yacc.yy
View file @
6ac3d751
...
...
@@ -16634,6 +16634,7 @@ sf_tail:
opt_if_not_exists
sp_name
{
Lex->sql_command= SQLCOM_CREATE_SPFUNCTION;
if (!Lex->make_sp_head_no_recursive(thd, $1, $2,
&sp_handler_function))
MYSQL_YYABORT;
...
...
@@ -16650,25 +16651,15 @@ sf_tail:
}
sp_proc_stmt_in_returns_clause
{
LEX *lex= thd->lex;
sp_head *sp= lex->sphead;
if (sp->is_not_allowed_in_function("function"))
if (Lex->sp_body_finalize_function(thd))
MYSQL_YYABORT;
lex->sql_command= SQLCOM_CREATE_SPFUNCTION;
sp->set_stmt_end(thd);
if (!(sp->m_flags & sp_head::HAS_RETURN))
my_yyabort_error((ER_SP_NORETURN, MYF(0),
ErrConvDQName(sp).ptr()));
(void) is_native_function_with_warn(thd, &sp->m_name);
sp->restore_thd_mem_root(thd);
}
;
sp_tail:
opt_if_not_exists sp_name
{
Lex->sql_command= SQLCOM_CREATE_PROCEDURE;
if (!Lex->make_sp_head_no_recursive(thd, $1, $2,
&sp_handler_procedure))
MYSQL_YYABORT;
...
...
@@ -16681,12 +16672,8 @@ sp_tail:
}
sp_proc_stmt
{
LEX *lex= Lex;
sp_head *sp= lex->sphead;
sp->set_stmt_end(thd);
lex->sql_command= SQLCOM_CREATE_PROCEDURE;
sp->restore_thd_mem_root(thd);
if (Lex->sp_body_finalize_procedure(thd))
MYSQL_YYABORT;
}
;
...
...
sql/sql_yacc_ora.yy
View file @
6ac3d751
...
...
@@ -16856,6 +16856,7 @@ sf_tail:
opt_if_not_exists
sp_name
{
Lex->sql_command= SQLCOM_CREATE_SPFUNCTION;
if (!Lex->make_sp_head_no_recursive(thd, $1, $2,
&sp_handler_function))
MYSQL_YYABORT;
...
...
@@ -16873,27 +16874,15 @@ sf_tail:
sp_tail_is
sp_body
{
LEX *lex= thd->lex;
sp_head *sp= lex->sphead;
if (sp->check_unresolved_goto())
if (Lex->sp_body_finalize_function(thd))
MYSQL_YYABORT;
if (sp->is_not_allowed_in_function("function"))
MYSQL_YYABORT;
lex->sql_command= SQLCOM_CREATE_SPFUNCTION;
sp->set_stmt_end(thd);
if (!(sp->m_flags & sp_head::HAS_RETURN))
my_yyabort_error((ER_SP_NORETURN, MYF(0),
ErrConvDQName(sp).ptr()));
(void) is_native_function_with_warn(thd, &sp->m_name);
sp->restore_thd_mem_root(thd);
}
;
sp_tail:
opt_if_not_exists sp_name
{
Lex->sql_command= SQLCOM_CREATE_PROCEDURE;
if (!Lex->make_sp_head_no_recursive(thd, $1, $2,
&sp_handler_procedure))
MYSQL_YYABORT;
...
...
@@ -16907,13 +16896,8 @@ sp_tail:
sp_tail_is
sp_body
{
LEX *lex= Lex;
sp_head *sp= lex->sphead;
if (sp->check_unresolved_goto())
if (Lex->sp_body_finalize_procedure(thd))
MYSQL_YYABORT;
sp->set_stmt_end(thd);
lex->sql_command= SQLCOM_CREATE_PROCEDURE;
sp->restore_thd_mem_root(thd);
}
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment