Reverting patch for BUG #14009 (use of abs() on null value causes problems with filesort
Fix for bug #14536: SELECT @a,@a:=... fails with prepared statements
This commit is contained in:
parent
f3502cd983
commit
e5f48e13bf
@ -180,8 +180,8 @@ Field Type Null Key Default Extra
|
|||||||
f1 date NO 0000-00-00
|
f1 date NO 0000-00-00
|
||||||
f2 datetime YES NULL
|
f2 datetime YES NULL
|
||||||
f3 time YES NULL
|
f3 time YES NULL
|
||||||
f4 time NO 00:00:00
|
f4 time YES NULL
|
||||||
f5 time NO 00:00:00
|
f5 time YES NULL
|
||||||
f6 time NO 00:00:00
|
f6 time NO 00:00:00
|
||||||
f7 datetime YES NULL
|
f7 datetime YES NULL
|
||||||
f8 date YES NULL
|
f8 date YES NULL
|
||||||
|
@ -176,7 +176,7 @@ Table Create Table
|
|||||||
t1 CREATE TABLE `t1` (
|
t1 CREATE TABLE `t1` (
|
||||||
`round(15.4,-1)` decimal(3,0) unsigned NOT NULL default '0',
|
`round(15.4,-1)` decimal(3,0) unsigned NOT NULL default '0',
|
||||||
`truncate(-5678.123451,-3)` decimal(4,0) NOT NULL default '0',
|
`truncate(-5678.123451,-3)` decimal(4,0) NOT NULL default '0',
|
||||||
`abs(-1.1)` decimal(2,1) default NULL,
|
`abs(-1.1)` decimal(2,1) NOT NULL default '0.0',
|
||||||
`-(-1.1)` decimal(2,1) NOT NULL default '0.0'
|
`-(-1.1)` decimal(2,1) NOT NULL default '0.0'
|
||||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
@ -123,6 +123,17 @@ select @a+0, @a:=@a+0+count(*), count(*), @a+0 from t1 group by i;
|
|||||||
0 1 1 0
|
0 1 1 0
|
||||||
1 3 2 0
|
1 3 2 0
|
||||||
3 6 3 0
|
3 6 3 0
|
||||||
|
set @a=0;
|
||||||
|
select @a,@a:="hello",@a,@a:=3,@a,@a:="hello again" from t1 group by i;
|
||||||
|
@a @a:="hello" @a @a:=3 @a @a:="hello again"
|
||||||
|
0 hello 0 3 0 hello again
|
||||||
|
0 hello 0 3 0 hello again
|
||||||
|
0 hello 0 3 0 hello again
|
||||||
|
select @a,@a:="hello",@a,@a:=3,@a,@a:="hello again" from t1 group by i;
|
||||||
|
@a @a:="hello" @a @a:=3 @a @a:="hello again"
|
||||||
|
hello again hello hello again 3 hello again hello again
|
||||||
|
hello again hello hello again 3 hello again hello again
|
||||||
|
hello again hello hello again 3 hello again hello again
|
||||||
drop table t1;
|
drop table t1;
|
||||||
set @a=_latin2'test';
|
set @a=_latin2'test';
|
||||||
select charset(@a),collation(@a),coercibility(@a);
|
select charset(@a),collation(@a),coercibility(@a);
|
||||||
|
@ -16,4 +16,3 @@ rpl_until : Unstable test case, bug#12429
|
|||||||
rpl_deadlock : Unstable test case, bug#12429
|
rpl_deadlock : Unstable test case, bug#12429
|
||||||
kill : Unstable test case, bug#9712
|
kill : Unstable test case, bug#9712
|
||||||
archive_gis : The test fails on 32bit Linux
|
archive_gis : The test fails on 32bit Linux
|
||||||
user_var : Ramil should fix this soon
|
|
||||||
|
@ -70,6 +70,10 @@ create table t1 (i int not null);
|
|||||||
insert t1 values (1),(2),(2),(3),(3),(3);
|
insert t1 values (1),(2),(2),(3),(3),(3);
|
||||||
select @a:=0; select @a, @a:=@a+count(*), count(*), @a from t1 group by i;
|
select @a:=0; select @a, @a:=@a+count(*), count(*), @a from t1 group by i;
|
||||||
select @a:=0; select @a+0, @a:=@a+0+count(*), count(*), @a+0 from t1 group by i;
|
select @a:=0; select @a+0, @a:=@a+0+count(*), count(*), @a+0 from t1 group by i;
|
||||||
|
|
||||||
|
set @a=0;
|
||||||
|
select @a,@a:="hello",@a,@a:=3,@a,@a:="hello again" from t1 group by i;
|
||||||
|
select @a,@a:="hello",@a,@a:=3,@a,@a:="hello again" from t1 group by i;
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
|
||||||
#
|
#
|
||||||
|
12
sql/item.cc
12
sql/item.cc
@ -5082,14 +5082,16 @@ bool Item_insert_value::fix_fields(THD *thd, Item **items)
|
|||||||
{
|
{
|
||||||
DBUG_ASSERT(fixed == 0);
|
DBUG_ASSERT(fixed == 0);
|
||||||
/* We should only check that arg is in first table */
|
/* We should only check that arg is in first table */
|
||||||
st_table_list *orig_next_table= context->last_name_resolution_table;
|
if (!arg->fixed)
|
||||||
context->last_name_resolution_table= context->first_name_resolution_table;
|
|
||||||
if (!arg->fixed && arg->fix_fields(thd, &arg))
|
|
||||||
{
|
{
|
||||||
|
bool res;
|
||||||
|
st_table_list *orig_next_table= context->last_name_resolution_table;
|
||||||
|
context->last_name_resolution_table= context->first_name_resolution_table;
|
||||||
|
res= arg->fix_fields(thd, &arg);
|
||||||
context->last_name_resolution_table= orig_next_table;
|
context->last_name_resolution_table= orig_next_table;
|
||||||
return TRUE;
|
if (res)
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
context->last_name_resolution_table= orig_next_table;
|
|
||||||
|
|
||||||
if (arg->type() == REF_ITEM)
|
if (arg->type() == REF_ITEM)
|
||||||
{
|
{
|
||||||
|
@ -636,7 +636,6 @@ void Item_func_num1::fix_num_length_and_dec()
|
|||||||
{
|
{
|
||||||
decimals= args[0]->decimals;
|
decimals= args[0]->decimals;
|
||||||
max_length= args[0]->max_length;
|
max_length= args[0]->max_length;
|
||||||
maybe_null= 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -845,6 +845,7 @@ public:
|
|||||||
{
|
{
|
||||||
decimals=0;
|
decimals=0;
|
||||||
max_length=MAX_TIME_WIDTH*MY_CHARSET_BIN_MB_MAXLEN;
|
max_length=MAX_TIME_WIDTH*MY_CHARSET_BIN_MB_MAXLEN;
|
||||||
|
maybe_null= 1;
|
||||||
}
|
}
|
||||||
Field *tmp_table_field(TABLE *t_arg)
|
Field *tmp_table_field(TABLE *t_arg)
|
||||||
{
|
{
|
||||||
|
@ -37,11 +37,11 @@ static int open_unireg_entry(THD *thd, TABLE *entry, const char *db,
|
|||||||
TABLE_LIST *table_list, MEM_ROOT *mem_root);
|
TABLE_LIST *table_list, MEM_ROOT *mem_root);
|
||||||
static void free_cache_entry(TABLE *entry);
|
static void free_cache_entry(TABLE *entry);
|
||||||
static void mysql_rm_tmp_tables(void);
|
static void mysql_rm_tmp_tables(void);
|
||||||
static my_bool open_new_frm(const char *path, const char *alias,
|
static bool open_new_frm(THD *thd, const char *path, const char *alias,
|
||||||
const char *db, const char *table_name,
|
const char *db, const char *table_name,
|
||||||
uint db_stat, uint prgflag,
|
uint db_stat, uint prgflag,
|
||||||
uint ha_open_flags, TABLE *outparam,
|
uint ha_open_flags, TABLE *outparam,
|
||||||
TABLE_LIST *table_desc, MEM_ROOT *mem_root);
|
TABLE_LIST *table_desc, MEM_ROOT *mem_root);
|
||||||
|
|
||||||
extern "C" byte *table_cache_key(const byte *record,uint *length,
|
extern "C" byte *table_cache_key(const byte *record,uint *length,
|
||||||
my_bool not_used __attribute__((unused)))
|
my_bool not_used __attribute__((unused)))
|
||||||
@ -1755,7 +1755,7 @@ static int open_unireg_entry(THD *thd, TABLE *entry, const char *db,
|
|||||||
thd->open_options, entry)) &&
|
thd->open_options, entry)) &&
|
||||||
(error != 5 ||
|
(error != 5 ||
|
||||||
(fn_format(path, path, 0, reg_ext, MY_UNPACK_FILENAME),
|
(fn_format(path, path, 0, reg_ext, MY_UNPACK_FILENAME),
|
||||||
open_new_frm(path, alias, db, name,
|
open_new_frm(thd, path, alias, db, name,
|
||||||
(uint) (HA_OPEN_KEYFILE | HA_OPEN_RNDFILE |
|
(uint) (HA_OPEN_KEYFILE | HA_OPEN_RNDFILE |
|
||||||
HA_GET_INDEX | HA_TRY_READ_ONLY),
|
HA_GET_INDEX | HA_TRY_READ_ONLY),
|
||||||
READ_KEYINFO | COMPUTE_TYPES | EXTRA_RECORD,
|
READ_KEYINFO | COMPUTE_TYPES | EXTRA_RECORD,
|
||||||
@ -5260,6 +5260,7 @@ int init_ftfuncs(THD *thd, SELECT_LEX *select_lex, bool no_order)
|
|||||||
|
|
||||||
SYNOPSIS
|
SYNOPSIS
|
||||||
open_new_frm()
|
open_new_frm()
|
||||||
|
THD thread handler
|
||||||
path path to .frm
|
path path to .frm
|
||||||
alias alias for table
|
alias alias for table
|
||||||
db database
|
db database
|
||||||
@ -5273,8 +5274,8 @@ int init_ftfuncs(THD *thd, SELECT_LEX *select_lex, bool no_order)
|
|||||||
mem_root temporary MEM_ROOT for parsing
|
mem_root temporary MEM_ROOT for parsing
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static my_bool
|
static bool
|
||||||
open_new_frm(const char *path, const char *alias,
|
open_new_frm(THD *thd, const char *path, const char *alias,
|
||||||
const char *db, const char *table_name,
|
const char *db, const char *table_name,
|
||||||
uint db_stat, uint prgflag,
|
uint db_stat, uint prgflag,
|
||||||
uint ha_open_flags, TABLE *outparam, TABLE_LIST *table_desc,
|
uint ha_open_flags, TABLE *outparam, TABLE_LIST *table_desc,
|
||||||
@ -5296,7 +5297,7 @@ open_new_frm(const char *path, const char *alias,
|
|||||||
my_error(ER_WRONG_OBJECT, MYF(0), db, table_name, "BASE TABLE");
|
my_error(ER_WRONG_OBJECT, MYF(0), db, table_name, "BASE TABLE");
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
if (mysql_make_view(parser, table_desc))
|
if (mysql_make_view(thd, parser, table_desc))
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -361,8 +361,8 @@ public:
|
|||||||
|
|
||||||
friend class st_select_lex_unit;
|
friend class st_select_lex_unit;
|
||||||
friend bool mysql_new_select(struct st_lex *lex, bool move_down);
|
friend bool mysql_new_select(struct st_lex *lex, bool move_down);
|
||||||
friend my_bool mysql_make_view (File_parser *parser,
|
friend bool mysql_make_view(THD *thd, File_parser *parser,
|
||||||
TABLE_LIST *table);
|
TABLE_LIST *table);
|
||||||
private:
|
private:
|
||||||
void fast_exclude();
|
void fast_exclude();
|
||||||
};
|
};
|
||||||
|
@ -1237,7 +1237,8 @@ JOIN::exec()
|
|||||||
|
|
||||||
if (zero_result_cause)
|
if (zero_result_cause)
|
||||||
{
|
{
|
||||||
(void) return_zero_rows(this, result, select_lex->leaf_tables, *columns_list,
|
(void) return_zero_rows(this, result, select_lex->leaf_tables,
|
||||||
|
*columns_list,
|
||||||
send_row_on_empty_set(),
|
send_row_on_empty_set(),
|
||||||
select_options,
|
select_options,
|
||||||
zero_result_cause,
|
zero_result_cause,
|
||||||
@ -1671,7 +1672,8 @@ JOIN::exec()
|
|||||||
{
|
{
|
||||||
thd->proc_info="Sending data";
|
thd->proc_info="Sending data";
|
||||||
DBUG_PRINT("info", ("%s", thd->proc_info));
|
DBUG_PRINT("info", ("%s", thd->proc_info));
|
||||||
result->send_fields(*columns_list,
|
result->send_fields((procedure ? curr_join->procedure_fields_list :
|
||||||
|
*curr_fields_list),
|
||||||
Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF);
|
Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF);
|
||||||
error= do_select(curr_join, curr_fields_list, NULL, procedure);
|
error= do_select(curr_join, curr_fields_list, NULL, procedure);
|
||||||
thd->limit_found_rows= curr_join->send_records;
|
thd->limit_found_rows= curr_join->send_records;
|
||||||
@ -9023,7 +9025,6 @@ do_select(JOIN *join,List<Item> *fields,TABLE *table,Procedure *procedure)
|
|||||||
int rc= 0;
|
int rc= 0;
|
||||||
enum_nested_loop_state error= NESTED_LOOP_OK;
|
enum_nested_loop_state error= NESTED_LOOP_OK;
|
||||||
JOIN_TAB *join_tab;
|
JOIN_TAB *join_tab;
|
||||||
List<Item> *columns_list= procedure? &join->procedure_fields_list : fields;
|
|
||||||
DBUG_ENTER("do_select");
|
DBUG_ENTER("do_select");
|
||||||
|
|
||||||
join->procedure=procedure;
|
join->procedure=procedure;
|
||||||
@ -9057,7 +9058,11 @@ do_select(JOIN *join,List<Item> *fields,TABLE *table,Procedure *procedure)
|
|||||||
error= (*end_select)(join,join_tab,1);
|
error= (*end_select)(join,join_tab,1);
|
||||||
}
|
}
|
||||||
else if (join->send_row_on_empty_set())
|
else if (join->send_row_on_empty_set())
|
||||||
|
{
|
||||||
|
List<Item> *columns_list= (procedure ? &join->procedure_fields_list :
|
||||||
|
fields);
|
||||||
rc= join->result->send_data(*columns_list);
|
rc= join->result->send_data(*columns_list);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -728,20 +728,24 @@ loop_out:
|
|||||||
|
|
||||||
SYNOPSIS
|
SYNOPSIS
|
||||||
mysql_make_view()
|
mysql_make_view()
|
||||||
parser - parser object;
|
thd Thread handler
|
||||||
table - TABLE_LIST structure for filling
|
parser parser object
|
||||||
|
table TABLE_LIST structure for filling
|
||||||
|
|
||||||
RETURN
|
RETURN
|
||||||
0 ok
|
0 ok
|
||||||
1 error
|
1 error
|
||||||
*/
|
*/
|
||||||
|
|
||||||
my_bool
|
bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table)
|
||||||
mysql_make_view(File_parser *parser, TABLE_LIST *table)
|
|
||||||
{
|
{
|
||||||
THD *thd= current_thd;
|
SELECT_LEX *end, *view_select;
|
||||||
|
LEX *old_lex, *lex;
|
||||||
|
Query_arena *arena, backup;
|
||||||
|
int res;
|
||||||
|
bool result;
|
||||||
DBUG_ENTER("mysql_make_view");
|
DBUG_ENTER("mysql_make_view");
|
||||||
DBUG_PRINT("info", ("table=%p (%s)", table, table->table_name));
|
DBUG_PRINT("info", ("table: 0x%lx (%s)", (ulong) table, table->table_name));
|
||||||
|
|
||||||
if (table->view)
|
if (table->view)
|
||||||
{
|
{
|
||||||
@ -765,16 +769,12 @@ mysql_make_view(File_parser *parser, TABLE_LIST *table)
|
|||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
SELECT_LEX *end;
|
|
||||||
LEX *old_lex= thd->lex, *lex;
|
|
||||||
SELECT_LEX *view_select;
|
|
||||||
int res= 0;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
For now we assume that tables will not be changed during PS life (it
|
For now we assume that tables will not be changed during PS life (it
|
||||||
will be TRUE as far as we make new table cache).
|
will be TRUE as far as we make new table cache).
|
||||||
*/
|
*/
|
||||||
Query_arena *arena= thd->stmt_arena, backup;
|
old_lex= thd->lex;
|
||||||
|
arena= thd->stmt_arena;
|
||||||
if (arena->is_conventional())
|
if (arena->is_conventional())
|
||||||
arena= 0;
|
arena= 0;
|
||||||
else
|
else
|
||||||
@ -1133,23 +1133,21 @@ ok:
|
|||||||
(st_select_lex_node**)&old_lex->all_selects_list;
|
(st_select_lex_node**)&old_lex->all_selects_list;
|
||||||
|
|
||||||
ok2:
|
ok2:
|
||||||
if (arena)
|
|
||||||
thd->restore_active_arena(arena, &backup);
|
|
||||||
if (!old_lex->time_zone_tables_used && thd->lex->time_zone_tables_used)
|
if (!old_lex->time_zone_tables_used && thd->lex->time_zone_tables_used)
|
||||||
old_lex->time_zone_tables_used= thd->lex->time_zone_tables_used;
|
old_lex->time_zone_tables_used= thd->lex->time_zone_tables_used;
|
||||||
thd->lex= old_lex;
|
result= !table->prelocking_placeholder && table->prepare_security(thd);
|
||||||
if (!table->prelocking_placeholder && table->prepare_security(thd))
|
|
||||||
DBUG_RETURN(1);
|
|
||||||
|
|
||||||
DBUG_RETURN(0);
|
end:
|
||||||
|
|
||||||
err:
|
|
||||||
if (arena)
|
if (arena)
|
||||||
thd->restore_active_arena(arena, &backup);
|
thd->restore_active_arena(arena, &backup);
|
||||||
|
thd->lex= old_lex;
|
||||||
|
DBUG_RETURN(result);
|
||||||
|
|
||||||
|
err:
|
||||||
delete table->view;
|
delete table->view;
|
||||||
table->view= 0; // now it is not VIEW placeholder
|
table->view= 0; // now it is not VIEW placeholder
|
||||||
thd->lex= old_lex;
|
result= 1;
|
||||||
DBUG_RETURN(1);
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
bool mysql_create_view(THD *thd,
|
bool mysql_create_view(THD *thd,
|
||||||
enum_view_create_mode mode);
|
enum_view_create_mode mode);
|
||||||
|
|
||||||
my_bool mysql_make_view(File_parser *parser, TABLE_LIST *table);
|
bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table);
|
||||||
|
|
||||||
bool mysql_drop_view(THD *thd, TABLE_LIST *view, enum_drop_mode drop_mode);
|
bool mysql_drop_view(THD *thd, TABLE_LIST *view, enum_drop_mode drop_mode);
|
||||||
|
|
||||||
|
@ -2654,7 +2654,7 @@ Natural_join_column::check_grants(THD *thd, const char *name, uint length)
|
|||||||
GRANT_INFO *grant;
|
GRANT_INFO *grant;
|
||||||
const char *db_name;
|
const char *db_name;
|
||||||
const char *table_name;
|
const char *table_name;
|
||||||
Security_context *save_security_ctx= 0;
|
Security_context *save_security_ctx;
|
||||||
Security_context *new_sctx= table_ref->security_ctx;
|
Security_context *new_sctx= table_ref->security_ctx;
|
||||||
bool res;
|
bool res;
|
||||||
|
|
||||||
@ -2673,14 +2673,11 @@ Natural_join_column::check_grants(THD *thd, const char *name, uint length)
|
|||||||
table_name= table_ref->table->s->table_name;
|
table_name= table_ref->table->s->table_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
save_security_ctx= thd->security_ctx;
|
||||||
if (new_sctx)
|
if (new_sctx)
|
||||||
{
|
|
||||||
save_security_ctx= thd->security_ctx;
|
|
||||||
thd->security_ctx= new_sctx;
|
thd->security_ctx= new_sctx;
|
||||||
}
|
|
||||||
res= check_grant_column(thd, grant, db_name, table_name, name, length);
|
res= check_grant_column(thd, grant, db_name, table_name, name, length);
|
||||||
if (save_security_ctx)
|
thd->security_ctx= save_security_ctx;
|
||||||
thd->security_ctx= save_security_ctx;
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user