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
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
mariadb
Commits
fa612924
Commit
fa612924
authored
Nov 26, 2009
by
Martin Hansson
Browse files
Options
Browse Files
Download
Plain Diff
Merge of fix for Bug#48459
parents
185e24d5
8e53e7e4
Changes
8
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
324 additions
and
90 deletions
+324
-90
client/mysql.cc
client/mysql.cc
+2
-2
mysql-test/r/bug47671.result
mysql-test/r/bug47671.result
+13
-0
mysql-test/r/sp.result
mysql-test/r/sp.result
+58
-0
mysql-test/t/bug47671-master.opt
mysql-test/t/bug47671-master.opt
+1
-0
mysql-test/t/bug47671.test
mysql-test/t/bug47671.test
+6
-0
mysql-test/t/sp.test
mysql-test/t/sp.test
+67
-0
sql/item_cmpfunc.cc
sql/item_cmpfunc.cc
+13
-0
sql/sql_yacc.yy
sql/sql_yacc.yy
+164
-88
No files found.
client/mysql.cc
View file @
fa612924
...
...
@@ -4335,7 +4335,7 @@ com_status(String *buffer __attribute__((unused)),
Don't remove "limit 1",
it is protection againts SQL_SELECT_LIMIT=0
*/
if
(
mysql_store_result_for_lazy
(
&
result
))
if
(
!
mysql_store_result_for_lazy
(
&
result
))
{
MYSQL_ROW
cur
=
mysql_fetch_row
(
result
);
if
(
cur
)
...
...
@@ -4379,7 +4379,7 @@ com_status(String *buffer __attribute__((unused)),
if
(
mysql_errno
(
&
mysql
)
==
CR_SERVER_GONE_ERROR
)
return
0
;
}
if
(
mysql_store_result_for_lazy
(
&
result
))
if
(
!
mysql_store_result_for_lazy
(
&
result
))
{
MYSQL_ROW
cur
=
mysql_fetch_row
(
result
);
if
(
cur
)
...
...
mysql-test/r/bug47671.result
0 → 100644
View file @
fa612924
#
# Bug#47671 - wrong character-set after upgrade from 5.1.34 to 5.1.39
#
# Extract only charset information from 'status' command output using regex
--------------
Server characterset: utf8
Db characterset: utf8
Client characterset: utf8
Conn. characterset: utf8
--------------
mysql-test/r/sp.result
View file @
fa612924
...
...
@@ -6979,6 +6979,64 @@ CALL p1;
ERROR 42S22: Unknown column 'A.b' in 'IN/ALL/ANY subquery'
DROP PROCEDURE p1;
DROP TABLE t1, t2;
#
# Bug#47627: SET @@{global.session}.local_variable in stored routine causes crash
# Bug#48626: Crash or lost connection using SET for declared variables with @@
#
DROP PROCEDURE IF EXISTS p1;
DROP PROCEDURE IF EXISTS p2;
DROP PROCEDURE IF EXISTS p3;
CREATE PROCEDURE p1()
BEGIN
DECLARE v INT DEFAULT 0;
SET @@SESSION.v= 10;
END//
ERROR HY000: Unknown system variable 'v'
CREATE PROCEDURE p2()
BEGIN
DECLARE v INT DEFAULT 0;
SET v= 10;
END//
call p2()//
CREATE PROCEDURE p3()
BEGIN
DECLARE v INT DEFAULT 0;
SELECT @@SESSION.v;
END//
ERROR HY000: Unknown system variable 'v'
CREATE PROCEDURE p4()
BEGIN
DECLARE v INT DEFAULT 0;
SET @@GLOBAL.v= 10;
END//
ERROR HY000: Unknown system variable 'v'
CREATE PROCEDURE p5()
BEGIN
DECLARE init_connect INT DEFAULT 0;
SET init_connect= 10;
SET @@GLOBAL.init_connect= 'SELECT 1';
SET @@SESSION.IDENTITY= 1;
SELECT @@SESSION.IDENTITY;
SELECT @@GLOBAL.init_connect;
SELECT init_connect;
END//
CREATE PROCEDURE p6()
BEGIN
DECLARE v INT DEFAULT 0;
SET @@v= 0;
END//
ERROR HY000: Unknown system variable 'v'
SET @old_init_connect= @@GLOBAL.init_connect;
CALL p5();
@@SESSION.IDENTITY
1
@@GLOBAL.init_connect
SELECT 1
init_connect
10
SET @@GLOBAL.init_connect= @old_init_connect;
DROP PROCEDURE p2;
DROP PROCEDURE p5;
# ------------------------------------------------------------------
# -- End of 5.1 tests
# ------------------------------------------------------------------
mysql-test/t/bug47671-master.opt
0 → 100644
View file @
fa612924
--default-character-set=utf8 --skip-character-set-client-handshake
mysql-test/t/bug47671.test
0 → 100644
View file @
fa612924
--
echo
#
--
echo
# Bug#47671 - wrong character-set after upgrade from 5.1.34 to 5.1.39
--
echo
#
--
echo
# Extract only charset information from 'status' command output using regex
--
replace_regex
/.*
mysql
.*//
/
Connection
.*//
/
Current
.*//
/
SSL
.*//
/
Using
.*//
/
Server
version
.*//
/
Protocol
.*//
/
UNIX
.*//
/
Uptime
.*//
/
Threads
.*//
--
exec
$MYSQL
-
u
root
test
-
e
"status"
;
mysql-test/t/sp.test
View file @
fa612924
...
...
@@ -8263,6 +8263,73 @@ CALL p1;
DROP PROCEDURE p1;
DROP TABLE t1, t2;
--echo #
--echo # Bug#47627: SET @@{global.session}.local_variable in stored routine causes crash
--echo # Bug#48626: Crash or lost connection using SET for declared variables with @@
--echo #
--disable_warnings
DROP PROCEDURE IF EXISTS p1;
DROP PROCEDURE IF EXISTS p2;
DROP PROCEDURE IF EXISTS p3;
--enable_warnings
delimiter //;
--error ER_UNKNOWN_SYSTEM_VARIABLE
CREATE PROCEDURE p1()
BEGIN
DECLARE v INT DEFAULT 0;
SET @@SESSION.v= 10;
END//
CREATE PROCEDURE p2()
BEGIN
DECLARE v INT DEFAULT 0;
SET v= 10;
END//
call p2()//
--error ER_UNKNOWN_SYSTEM_VARIABLE
CREATE PROCEDURE p3()
BEGIN
DECLARE v INT DEFAULT 0;
SELECT @@SESSION.v;
END//
--error ER_UNKNOWN_SYSTEM_VARIABLE
CREATE PROCEDURE p4()
BEGIN
DECLARE v INT DEFAULT 0;
SET @@GLOBAL.v= 10;
END//
CREATE PROCEDURE p5()
BEGIN
DECLARE init_connect INT DEFAULT 0;
SET init_connect= 10;
SET @@GLOBAL.init_connect= '
SELECT
1
'
;
SET
@@
SESSION
.
IDENTITY
=
1
;
SELECT
@@
SESSION
.
IDENTITY
;
SELECT
@@
GLOBAL
.
init_connect
;
SELECT
init_connect
;
END
//
--
error
ER_UNKNOWN_SYSTEM_VARIABLE
CREATE
PROCEDURE
p6
()
BEGIN
DECLARE
v
INT
DEFAULT
0
;
SET
@@
v
=
0
;
END
//
delimiter
;
//
SET
@
old_init_connect
=
@@
GLOBAL
.
init_connect
;
CALL
p5
();
SET
@@
GLOBAL
.
init_connect
=
@
old_init_connect
;
DROP
PROCEDURE
p2
;
DROP
PROCEDURE
p5
;
--
echo
# ------------------------------------------------------------------
--
echo
# -- End of 5.1 tests
...
...
sql/item_cmpfunc.cc
View file @
fa612924
...
...
@@ -960,12 +960,23 @@ int Arg_comparator::set_cmp_func(Item_result_field *owner_arg,
(
*
b
)
->
field_type
()
==
MYSQL_TYPE_YEAR
))
{
is_nulls_eq
=
is_owner_equal_func
();
year_as_datetime
=
FALSE
;
if
((
*
a
)
->
is_datetime
())
{
year_as_datetime
=
TRUE
;
get_value_a_func
=
&
get_datetime_value
;
}
else
if
((
*
a
)
->
field_type
()
==
MYSQL_TYPE_YEAR
)
get_value_a_func
=
&
get_year_value
;
else
{
/*
Because convert_constant_item is called only for EXECUTE in PS mode
the value of get_value_x_func set in PREPARE might be not
valid for EXECUTE.
*/
get_value_a_func
=
NULL
;
}
if
((
*
b
)
->
is_datetime
())
{
...
...
@@ -973,6 +984,8 @@ int Arg_comparator::set_cmp_func(Item_result_field *owner_arg,
get_value_b_func
=
&
get_datetime_value
;
}
else
if
((
*
b
)
->
field_type
()
==
MYSQL_TYPE_YEAR
)
get_value_b_func
=
&
get_year_value
;
else
get_value_b_func
=
NULL
;
func
=
&
Arg_comparator
::
compare_year
;
return
0
;
...
...
sql/sql_yacc.yy
View file @
fa612924
...
...
@@ -389,6 +389,138 @@ void case_stmt_action_end_case(LEX *lex, bool simple)
lex->sphead->do_cont_backpatch();
}
static bool
find_sys_var_null_base(THD *thd, struct sys_var_with_base *tmp)
{
tmp->var= find_sys_var(thd, tmp->base_name.str, tmp->base_name.length);
if (tmp->var == NULL)
my_error(ER_UNKNOWN_SYSTEM_VARIABLE, MYF(0), tmp->base_name.str);
else
tmp->base_name= null_lex_str;
return thd->is_error();
}
/**
Helper action for a SET statement.
Used to push a system variable into the assignment list.
@param thd the current thread
@param tmp the system variable with base name
@param var_type the scope of the variable
@param val the value being assigned to the variable
@return TRUE if error, FALSE otherwise.
*/
static bool
set_system_variable(THD *thd, struct sys_var_with_base *tmp,
enum enum_var_type var_type, Item *val)
{
set_var *var;
LEX *lex= thd->lex;
/* No AUTOCOMMIT from a stored function or trigger. */
if (lex->spcont && tmp->var == &sys_autocommit)
lex->sphead->m_flags|= sp_head::HAS_SET_AUTOCOMMIT_STMT;
if (! (var= new set_var(var_type, tmp->var, &tmp->base_name, val)))
return TRUE;
return lex->var_list.push_back(var);
}
/**
Helper action for a SET statement.
Used to push a SP local variable into the assignment list.
@param thd the current thread
@param var_type the SP local variable
@param val the value being assigned to the variable
@return TRUE if error, FALSE otherwise.
*/
static bool
set_local_variable(THD *thd, sp_variable_t *spv, Item *val)
{
Item *it;
LEX *lex= thd->lex;
sp_instr_set *sp_set;
if (val)
it= val;
else if (spv->dflt)
it= spv->dflt;
else
{
it= new (thd->mem_root) Item_null();
if (it == NULL)
return TRUE;
}
sp_set= new sp_instr_set(lex->sphead->instructions(), lex->spcont,
spv->offset, it, spv->type, lex, TRUE);
return (sp_set == NULL || lex->sphead->add_instr(sp_set));
}
/**
Helper action for a SET statement.
Used to SET a field of NEW row.
@param thd the current thread
@param name the field name
@param val the value being assigned to the row
@return TRUE if error, FALSE otherwise.
*/
static bool
set_trigger_new_row(THD *thd, LEX_STRING *name, Item *val)
{
LEX *lex= thd->lex;
Item_trigger_field *trg_fld;
sp_instr_set_trigger_field *sp_fld;
/* QQ: Shouldn't this be field's default value ? */
if (! val)
val= new Item_null();
DBUG_ASSERT(lex->trg_chistics.action_time == TRG_ACTION_BEFORE &&
(lex->trg_chistics.event == TRG_EVENT_INSERT ||
lex->trg_chistics.event == TRG_EVENT_UPDATE));
trg_fld= new (thd->mem_root)
Item_trigger_field(lex->current_context(),
Item_trigger_field::NEW_ROW,
name->str, UPDATE_ACL, FALSE);
if (trg_fld == NULL)
return TRUE;
sp_fld= new sp_instr_set_trigger_field(lex->sphead->instructions(),
lex->spcont, trg_fld, val, lex);
if (sp_fld == NULL)
return TRUE;
/*
Let us add this item to list of all Item_trigger_field
objects in trigger.
*/
lex->trg_table_fields.link_in_list((uchar *) trg_fld,
(uchar **) &trg_fld->next_trg_field);
return lex->sphead->add_instr(sp_fld);
}
/**
Helper to resolve the SQL:2003 Syntax exception 1) in <in predicate>.
See SQL:2003, Part 2, section 8.4 <in predicate>, Note 184, page 383.
...
...
@@ -11830,98 +11962,42 @@ sys_option_value:
option_type internal_variable_name equal set_expr_or_default
{
THD *thd= YYTHD;
LEX *lex=Lex;
LEX *lex= Lex;
LEX_STRING *name= &$2.base_name;
if ($2.var == trg_new_row_fake_var)
{
/* We are in trigger and assigning value to field of new row */
Item *it;
Item_trigger_field *trg_fld;
sp_instr_set_trigger_field *sp_fld;
LINT_INIT(sp_fld);
if ($1)
{
my_parse_error(ER(ER_SYNTAX_ERROR));
MYSQL_YYABORT;
}
if ($4)
it= $4;
else
{
/* QQ: Shouldn't this be field's default value ? */
it= new Item_null();
}
DBUG_ASSERT(lex->trg_chistics.action_time == TRG_ACTION_BEFORE &&
(lex->trg_chistics.event == TRG_EVENT_INSERT ||
lex->trg_chistics.event == TRG_EVENT_UPDATE));
trg_fld= new (thd->mem_root)
Item_trigger_field(Lex->current_context(),
Item_trigger_field::NEW_ROW,
$2.base_name.str,
UPDATE_ACL, FALSE);
if (trg_fld == NULL)
MYSQL_YYABORT;
sp_fld= new sp_instr_set_trigger_field(lex->sphead->
instructions(),
lex->spcont,
trg_fld,
it, lex);
if (sp_fld == NULL)
MYSQL_YYABORT;
/*
Let us add this item to list of all Item_trigger_field
objects in trigger.
*/
lex->trg_table_fields.link_in_list((uchar *)trg_fld,
(uchar **) &trg_fld->
next_trg_field);
if (lex->sphead->add_instr(sp_fld))
if (set_trigger_new_row(YYTHD, name, $4))
MYSQL_YYABORT;
}
else if ($2.var)
{
/* System variable */
{
if ($1)
lex->option_type= $1;
set_var *var= new set_var(lex->option_type, $2.var,
&$2.base_name, $4);
if (
var == NULL
)
/* It is a system variable. */
if (
set_system_variable(thd, &$2, lex->option_type, $4)
)
MYSQL_YYABORT;
lex->var_list.push_back(var);
}
else
{
/* An SP local variable */
sp_pcontext *ctx= lex->spcont;
sp_variable_t *spv;
sp_instr_set *sp_set;
Item *it;
sp_pcontext *spc= lex->spcont;
sp_variable_t *spv= spc->find_variable(name);
if ($1)
{
my_parse_error(ER(ER_SYNTAX_ERROR));
MYSQL_YYABORT;
}
spv= ctx->find_variable(&$2.base_name);
if ($4)
it= $4;
else if (spv->dflt)
it= spv->dflt;
else
{
it= new (thd->mem_root) Item_null();
if (it == NULL)
MYSQL_YYABORT;
}
sp_set= new sp_instr_set(lex->sphead->instructions(), ctx,
spv->offset, it, spv->type, lex, TRUE);
if (sp_set == NULL ||
lex->sphead->add_instr(sp_set))
/* It is a local variable. */
if (set_local_variable(thd, spv, $4))
MYSQL_YYABORT;
}
}
...
...
@@ -11957,11 +12033,16 @@ option_value:
}
| '@' '@' opt_var_ident_type internal_variable_name equal set_expr_or_default
{
LEX *lex=Lex;
set_var *var= new set_var($3, $4.var, &$4.base_name, $6);
if (var == NULL)
THD *thd= YYTHD;
struct sys_var_with_base tmp= $4;
/* Lookup if necessary: must be a system variable. */
if (tmp.var == NULL)
{
if (find_sys_var_null_base(thd, &tmp))
MYSQL_YYABORT;
}
if (set_system_variable(thd, &tmp, $3, $6))
MYSQL_YYABORT;
lex->var_list.push_back(var);
}
| charset old_or_new_charset_name_or_default
{
...
...
@@ -12054,31 +12135,26 @@ internal_variable_name:
ident
{
THD *thd= YYTHD;
LEX *lex= thd->lex;
sp_pcontext *spc= lex->spcont;
sp_pcontext *spc= thd->lex->spcont;
sp_variable_t *spv;
/*
We have to lookup here since local vars can shadow sysvars
*/
/*
Best effort lookup for system variable.
*/
if (!spc || !(spv = spc->find_variable(&$1)))
{
struct sys_var_with_base tmp= {NULL, $1};
/* Not an SP local variable */
sys_var *tmp=find_sys_var(thd, $1.str, $1.length);
if (!tmp)
if (find_sys_var_null_base(thd, &tmp))
MYSQL_YYABORT;
$$.var= tmp;
$$.base_name= null_lex_str;
if (spc && tmp == &sys_autocommit)
{
/*
We don't allow setting AUTOCOMMIT from a stored function
or trigger.
*/
lex->sphead->m_flags|= sp_head::HAS_SET_AUTOCOMMIT_STMT;
}
$$= tmp;
}
else
{
/* An SP local variable */
/*
Possibly an SP local variable (or a shadowed sysvar).
Will depend on the context of the SET statement.
*/
$$.var= NULL;
$$.base_name= $1;
}
...
...
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