Commit 53fb954d authored by Sergey Glukhov's avatar Sergey Glukhov

5.1 -> 5.5 merge

parents 8625a873 3468b55a
...@@ -7161,6 +7161,25 @@ init_connect ...@@ -7161,6 +7161,25 @@ init_connect
SET @@GLOBAL.init_connect= @old_init_connect; SET @@GLOBAL.init_connect= @old_init_connect;
DROP PROCEDURE p2; DROP PROCEDURE p2;
DROP PROCEDURE p5; DROP PROCEDURE p5;
#
# Bug#11766594 59736: SELECT DISTINCT.. INCORRECT RESULT WITH DETERMINISTIC FUNCTION IN WHERE C
#
CREATE TABLE t1 (a INT, b INT, KEY(b));
CREATE TABLE t2 (c INT, d INT, KEY(c));
INSERT INTO t1 VALUES (1,1),(1,1),(1,2);
INSERT INTO t2 VALUES (1,1),(1,2);
CREATE FUNCTION f1() RETURNS INT DETERMINISTIC
BEGIN
DECLARE a int;
-- SQL statement inside
SELECT 1 INTO a;
RETURN a;
END $
SELECT COUNT(DISTINCT d) FROM t1, t2 WHERE a = c AND b = f1();
COUNT(DISTINCT d)
2
DROP FUNCTION f1;
DROP TABLE t1, t2;
# ------------------------------------------------------------------ # ------------------------------------------------------------------
# -- End of 5.1 tests # -- End of 5.1 tests
# ------------------------------------------------------------------ # ------------------------------------------------------------------
......
...@@ -8376,6 +8376,33 @@ SET @@GLOBAL.init_connect= @old_init_connect; ...@@ -8376,6 +8376,33 @@ SET @@GLOBAL.init_connect= @old_init_connect;
DROP PROCEDURE p2; DROP PROCEDURE p2;
DROP PROCEDURE p5; DROP PROCEDURE p5;
--echo #
--echo # Bug#11766594 59736: SELECT DISTINCT.. INCORRECT RESULT WITH DETERMINISTIC FUNCTION IN WHERE C
--echo #
CREATE TABLE t1 (a INT, b INT, KEY(b));
CREATE TABLE t2 (c INT, d INT, KEY(c));
INSERT INTO t1 VALUES (1,1),(1,1),(1,2);
INSERT INTO t2 VALUES (1,1),(1,2);
DELIMITER $;
CREATE FUNCTION f1() RETURNS INT DETERMINISTIC
BEGIN
DECLARE a int;
-- SQL statement inside
SELECT 1 INTO a;
RETURN a;
END $
DELIMITER ;$
SELECT COUNT(DISTINCT d) FROM t1, t2 WHERE a = c AND b = f1();
DROP FUNCTION f1;
DROP TABLE t1, t2;
--echo # ------------------------------------------------------------------ --echo # ------------------------------------------------------------------
--echo # -- End of 5.1 tests --echo # -- End of 5.1 tests
--echo # ------------------------------------------------------------------ --echo # ------------------------------------------------------------------
......
...@@ -7888,7 +7888,7 @@ bool setup_fields(THD *thd, Item **ref_pointer_array, ...@@ -7888,7 +7888,7 @@ bool setup_fields(THD *thd, Item **ref_pointer_array,
if (item->with_sum_func && item->type() != Item::SUM_FUNC_ITEM && if (item->with_sum_func && item->type() != Item::SUM_FUNC_ITEM &&
sum_func_list) sum_func_list)
item->split_sum_func(thd, ref_pointer_array, *sum_func_list); item->split_sum_func(thd, ref_pointer_array, *sum_func_list);
thd->used_tables|= item->used_tables(); thd->lex->used_tables|= item->used_tables();
thd->lex->current_select->cur_pos_in_select_list++; thd->lex->current_select->cur_pos_in_select_list++;
} }
thd->lex->current_select->is_item_list_lookup= save_is_item_list_lookup; thd->lex->current_select->is_item_list_lookup= save_is_item_list_lookup;
...@@ -8235,7 +8235,7 @@ insert_fields(THD *thd, Name_resolution_context *context, const char *db_name, ...@@ -8235,7 +8235,7 @@ insert_fields(THD *thd, Name_resolution_context *context, const char *db_name,
views and natural joins this update is performed inside the loop below. views and natural joins this update is performed inside the loop below.
*/ */
if (table) if (table)
thd->used_tables|= table->map; thd->lex->used_tables|= table->map;
/* /*
Initialize a generic field iterator for the current table reference. Initialize a generic field iterator for the current table reference.
...@@ -8320,7 +8320,7 @@ insert_fields(THD *thd, Name_resolution_context *context, const char *db_name, ...@@ -8320,7 +8320,7 @@ insert_fields(THD *thd, Name_resolution_context *context, const char *db_name,
field_table= nj_col->table_ref->table; field_table= nj_col->table_ref->table;
if (field_table) if (field_table)
{ {
thd->used_tables|= field_table->map; thd->lex->used_tables|= field_table->map;
field_table->covering_keys.intersect(field->part_of_key); field_table->covering_keys.intersect(field->part_of_key);
field_table->merge_keys.merge(field->part_of_key); field_table->merge_keys.merge(field->part_of_key);
field_table->used_fields++; field_table->used_fields++;
...@@ -8328,7 +8328,7 @@ insert_fields(THD *thd, Name_resolution_context *context, const char *db_name, ...@@ -8328,7 +8328,7 @@ insert_fields(THD *thd, Name_resolution_context *context, const char *db_name,
} }
} }
else else
thd->used_tables|= item->used_tables(); thd->lex->used_tables|= item->used_tables();
thd->lex->current_select->cur_pos_in_select_list++; thd->lex->current_select->cur_pos_in_select_list++;
} }
/* /*
......
...@@ -795,7 +795,6 @@ THD::THD() ...@@ -795,7 +795,6 @@ THD::THD()
is_slave_error= thread_specific_used= FALSE; is_slave_error= thread_specific_used= FALSE;
my_hash_clear(&handler_tables_hash); my_hash_clear(&handler_tables_hash);
tmp_table=0; tmp_table=0;
used_tables=0;
cuted_fields= 0L; cuted_fields= 0L;
sent_row_count= 0L; sent_row_count= 0L;
limit_found_rows= 0; limit_found_rows= 0;
......
...@@ -1960,13 +1960,6 @@ public: ...@@ -1960,13 +1960,6 @@ public:
*/ */
ha_rows examined_row_count; ha_rows examined_row_count;
/*
The set of those tables whose fields are referenced in all subqueries
of the query.
TODO: possibly this it is incorrect to have used tables in THD because
with more than one subquery, it is not clear what does the field mean.
*/
table_map used_tables;
USER_CONN *user_connect; USER_CONN *user_connect;
CHARSET_INFO *db_charset; CHARSET_INFO *db_charset;
Warning_info *warning_info; Warning_info *warning_info;
......
...@@ -717,7 +717,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list, ...@@ -717,7 +717,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
lock_type= table_list->lock_type; lock_type= table_list->lock_type;
thd_proc_info(thd, "init"); thd_proc_info(thd, "init");
thd->used_tables=0; thd->lex->used_tables=0;
values= its++; values= its++;
value_count= values->elements; value_count= values->elements;
...@@ -872,7 +872,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list, ...@@ -872,7 +872,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
} }
else else
{ {
if (thd->used_tables) // Column used in values() if (thd->lex->used_tables) // Column used in values()
restore_record(table,s->default_values); // Get empty record restore_record(table,s->default_values); // Get empty record
else else
{ {
......
...@@ -434,6 +434,7 @@ void lex_start(THD *thd) ...@@ -434,6 +434,7 @@ void lex_start(THD *thd)
lex->server_options.port= -1; lex->server_options.port= -1;
lex->is_lex_started= TRUE; lex->is_lex_started= TRUE;
lex->used_tables= 0;
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
......
...@@ -2396,6 +2396,16 @@ struct LEX: public Query_tables_list ...@@ -2396,6 +2396,16 @@ struct LEX: public Query_tables_list
bool escape_used; bool escape_used;
bool is_lex_started; /* If lex_start() did run. For debugging. */ bool is_lex_started; /* If lex_start() did run. For debugging. */
/*
The set of those tables whose fields are referenced in all subqueries
of the query.
TODO: possibly this it is incorrect to have used tables in LEX because
with subquery, it is not clear what does the field mean. To fix this
we should aggregate used tables information for selected expressions
into the select_lex.
*/
table_map used_tables;
LEX(); LEX();
virtual ~LEX() virtual ~LEX()
......
...@@ -1474,7 +1474,7 @@ static int mysql_test_select(Prepared_statement *stmt, ...@@ -1474,7 +1474,7 @@ static int mysql_test_select(Prepared_statement *stmt,
if (open_normal_and_derived_tables(thd, tables, MYSQL_OPEN_FORCE_SHARED_MDL)) if (open_normal_and_derived_tables(thd, tables, MYSQL_OPEN_FORCE_SHARED_MDL))
goto error; goto error;
thd->used_tables= 0; // Updated by setup_fields thd->lex->used_tables= 0; // Updated by setup_fields
/* /*
JOIN::prepare calls JOIN::prepare calls
...@@ -1646,7 +1646,7 @@ static bool select_like_stmt_test(Prepared_statement *stmt, ...@@ -1646,7 +1646,7 @@ static bool select_like_stmt_test(Prepared_statement *stmt,
if (specific_prepare && (*specific_prepare)(thd)) if (specific_prepare && (*specific_prepare)(thd))
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
thd->used_tables= 0; // Updated by setup_fields thd->lex->used_tables= 0; // Updated by setup_fields
/* Calls JOIN::prepare */ /* Calls JOIN::prepare */
DBUG_RETURN(lex->unit.prepare(thd, 0, setup_tables_done_option)); DBUG_RETURN(lex->unit.prepare(thd, 0, setup_tables_done_option));
......
...@@ -435,7 +435,7 @@ fix_inner_refs(THD *thd, List<Item> &all_fields, SELECT_LEX *select, ...@@ -435,7 +435,7 @@ fix_inner_refs(THD *thd, List<Item> &all_fields, SELECT_LEX *select,
if (!ref->fixed && ref->fix_fields(thd, 0)) if (!ref->fixed && ref->fix_fields(thd, 0))
return TRUE; return TRUE;
thd->used_tables|= item->used_tables(); thd->lex->used_tables|= item->used_tables();
} }
return false; return false;
} }
...@@ -1675,7 +1675,7 @@ JOIN::optimize() ...@@ -1675,7 +1675,7 @@ JOIN::optimize()
if (exec_tmp_table1->distinct) if (exec_tmp_table1->distinct)
{ {
table_map used_tables= thd->used_tables; table_map used_tables= thd->lex->used_tables;
JOIN_TAB *last_join_tab= join_tab+tables-1; JOIN_TAB *last_join_tab= join_tab+tables-1;
do do
{ {
...@@ -2552,7 +2552,7 @@ mysql_select(THD *thd, Item ***rref_pointer_array, ...@@ -2552,7 +2552,7 @@ mysql_select(THD *thd, Item ***rref_pointer_array,
if (!(join= new JOIN(thd, fields, select_options, result))) if (!(join= new JOIN(thd, fields, select_options, result)))
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
thd_proc_info(thd, "init"); thd_proc_info(thd, "init");
thd->used_tables=0; // Updated by setup_fields thd->lex->used_tables=0; // Updated by setup_fields
err= join->prepare(rref_pointer_array, tables, wild_num, err= join->prepare(rref_pointer_array, tables, wild_num,
conds, og_num, order, group, having, proc_param, conds, og_num, order, group, having, proc_param,
select_lex, unit); select_lex, unit);
...@@ -17032,7 +17032,7 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order, ...@@ -17032,7 +17032,7 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
need_order=0; need_order=0;
extra.append(STRING_WITH_LEN("; Using filesort")); extra.append(STRING_WITH_LEN("; Using filesort"));
} }
if (distinct & test_all_bits(used_tables,thd->used_tables)) if (distinct & test_all_bits(used_tables, thd->lex->used_tables))
extra.append(STRING_WITH_LEN("; Distinct")); extra.append(STRING_WITH_LEN("; Distinct"));
for (uint part= 0; part < tab->ref.key_parts; part++) for (uint part= 0; part < tab->ref.key_parts; part++)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment