diff options
author | unknown <knielsen@knielsen-hq.org> | 2011-04-12 14:26:06 +0200 |
---|---|---|
committer | unknown <knielsen@knielsen-hq.org> | 2011-04-12 14:26:06 +0200 |
commit | ce55d37929fc91b476541d3a77336a44b20317ac (patch) | |
tree | 867bf056f51f0338af221431380445d7784b2c0e | |
parent | fcd29b78456a47b00763fe249bbee9456bfbf6bb (diff) | |
parent | 3a3a91ff051abe859589e33fab4b5588e325d55b (diff) | |
download | mariadb-git-ce55d37929fc91b476541d3a77336a44b20317ac.tar.gz |
Merge Mariadb 5.1->5.2
-rw-r--r-- | mysql-test/r/union.result | 20 | ||||
-rw-r--r-- | mysql-test/suite/pbxt/r/union.result | 22 | ||||
-rw-r--r-- | mysql-test/suite/pbxt/t/union.test | 9 | ||||
-rw-r--r-- | mysql-test/t/union.test | 8 | ||||
-rw-r--r-- | sql/sp_rcontext.cc | 6 | ||||
-rw-r--r-- | sql/sp_rcontext.h | 2 | ||||
-rw-r--r-- | sql/sql_analyse.cc | 4 | ||||
-rw-r--r-- | sql/sql_class.cc | 14 | ||||
-rw-r--r-- | sql/sql_class.h | 30 | ||||
-rw-r--r-- | sql/sql_cursor.cc | 2 | ||||
-rw-r--r-- | sql/sql_delete.cc | 2 | ||||
-rw-r--r-- | sql/sql_insert.cc | 2 | ||||
-rw-r--r-- | sql/sql_prepare.cc | 6 | ||||
-rw-r--r-- | sql/sql_select.cc | 30 | ||||
-rw-r--r-- | sql/sql_union.cc | 10 | ||||
-rw-r--r-- | sql/sql_update.cc | 2 | ||||
-rw-r--r-- | storage/pbxt/src/lock_xt.cc | 1 |
17 files changed, 124 insertions, 46 deletions
diff --git a/mysql-test/r/union.result b/mysql-test/r/union.result index 054f416bfd4..d66db1ad211 100644 --- a/mysql-test/r/union.result +++ b/mysql-test/r/union.result @@ -414,7 +414,7 @@ a 5 select found_rows(); found_rows() -6 +5 SELECT SQL_CALC_FOUND_ROWS * FROM t1 LIMIT 100 UNION SELECT * FROM t2; a 1 @@ -447,7 +447,7 @@ a 4 select found_rows(); found_rows() -6 +5 SELECT SQL_CALC_FOUND_ROWS * FROM t1 limit 2,2 UNION SELECT * FROM t2; a 3 @@ -1208,9 +1208,12 @@ a b select * from ((select * from t1 limit 1) union (select * from t1 limit 1)) a; a b 1 a +2 b select * from ((select * from t1 limit 1) union (select * from t1 limit 1) union (select * from t1 limit 1)) a; a b 1 a +2 b +3 c select * from ((((select * from t1))) union (select * from t1) union (select * from t1)) a; a b 1 a @@ -1647,4 +1650,17 @@ b 1 2 DROP TABLE t1,t2; +create table t1 (a int); +insert into t1 values (10),(10),(10),(2),(3),(4),(5),(6),(7),(8),(9),(1),(10); +select a from t1 where false UNION select a from t1 limit 8; +a +10 +2 +3 +4 +5 +6 +7 +8 +drop table t1; End of 5.1 tests diff --git a/mysql-test/suite/pbxt/r/union.result b/mysql-test/suite/pbxt/r/union.result index cfcd17cf0d9..5d9dfb07965 100644 --- a/mysql-test/suite/pbxt/r/union.result +++ b/mysql-test/suite/pbxt/r/union.result @@ -362,7 +362,7 @@ a 2 select found_rows(); found_rows() -6 +5 SELECT SQL_CALC_FOUND_ROWS * FROM t1 UNION SELECT * FROM t2 LIMIT 100; a 1 @@ -372,7 +372,7 @@ a 5 select found_rows(); found_rows() -6 +5 SELECT SQL_CALC_FOUND_ROWS * FROM t1 LIMIT 100 UNION SELECT * FROM t2; a 1 @@ -405,7 +405,7 @@ a 4 select found_rows(); found_rows() -6 +5 SELECT SQL_CALC_FOUND_ROWS * FROM t1 limit 2,2 UNION SELECT * FROM t2; a 3 @@ -1166,9 +1166,12 @@ a b select * from ((select * from t1 limit 1) union (select * from t1 limit 1)) a; a b 1 a +2 b select * from ((select * from t1 limit 1) union (select * from t1 limit 1) union (select * from t1 limit 1)) a; a b 1 a +2 b +3 c select * from ((((select * from t1))) union (select * from t1) union (select * from t1)) a; a b 1 a @@ -1426,4 +1429,17 @@ select _utf8'12' union select _latin1'12345'; 12 12 12345 +create table t1 (a int); +insert into t1 values (10),(10),(10),(2),(3),(4),(5),(6),(7),(8),(9),(1),(10); +select a from t1 where false UNION select a from t1 limit 8; +a +10 +2 +3 +4 +5 +6 +7 +8 +drop table t1; End of 5.0 tests diff --git a/mysql-test/suite/pbxt/t/union.test b/mysql-test/suite/pbxt/t/union.test index 02c73d4bb57..c216b3caceb 100644 --- a/mysql-test/suite/pbxt/t/union.test +++ b/mysql-test/suite/pbxt/t/union.test @@ -904,6 +904,15 @@ drop table t1, t2; # select _utf8'12' union select _latin1'12345'; +# +# lp:732124 union + limit returns wrong result +# +create table t1 (a int); +insert into t1 values (10),(10),(10),(2),(3),(4),(5),(6),(7),(8),(9),(1),(10); +--sorted_result +select a from t1 where false UNION select a from t1 limit 8; +drop table t1; + --disable_query_log drop database pbxt; diff --git a/mysql-test/t/union.test b/mysql-test/t/union.test index c8d5ea0f8e5..34bb4afc41c 100644 --- a/mysql-test/t/union.test +++ b/mysql-test/t/union.test @@ -1155,5 +1155,13 @@ SELECT * FROM t2 UNION SELECT * FROM t2 DROP TABLE t1,t2; +# +# lp:732124 union + limit returns wrong result +# +create table t1 (a int); +insert into t1 values (10),(10),(10),(2),(3),(4),(5),(6),(7),(8),(9),(1),(10); +--sorted_result +select a from t1 where false UNION select a from t1 limit 8; +drop table t1; --echo End of 5.1 tests diff --git a/sql/sp_rcontext.cc b/sql/sp_rcontext.cc index 686e1a1346f..18c80b2b054 100644 --- a/sql/sp_rcontext.cc +++ b/sql/sp_rcontext.cc @@ -651,7 +651,7 @@ int Select_fetch_into_spvars::prepare(List<Item> &fields, SELECT_LEX_UNIT *u) } -bool Select_fetch_into_spvars::send_data(List<Item> &items) +int Select_fetch_into_spvars::send_data(List<Item> &items) { List_iterator_fast<struct sp_variable> spvar_iter(*spvar_list); List_iterator_fast<Item> item_iter(items); @@ -668,7 +668,7 @@ bool Select_fetch_into_spvars::send_data(List<Item> &items) for (; spvar= spvar_iter++, item= item_iter++; ) { if (thd->spcont->set_variable(thd, spvar->offset, &item)) - return TRUE; + return 1; } - return FALSE; + return 0; } diff --git a/sql/sp_rcontext.h b/sql/sp_rcontext.h index ecd11453e49..15815e496dd 100644 --- a/sql/sp_rcontext.h +++ b/sql/sp_rcontext.h @@ -254,7 +254,7 @@ public: void set_spvar_list(List<struct sp_variable> *vars) { spvar_list= vars; } virtual bool send_eof() { return FALSE; } - virtual bool send_data(List<Item> &items); + virtual int send_data(List<Item> &items); virtual int prepare(List<Item> &list, SELECT_LEX_UNIT *u); }; diff --git a/sql/sql_analyse.cc b/sql/sql_analyse.cc index 2c6937d29b7..a57bd41c7e6 100644 --- a/sql/sql_analyse.cc +++ b/sql/sql_analyse.cc @@ -753,7 +753,7 @@ int analyse::end_of_records() tmp_str.append(STRING_WITH_LEN(" NOT NULL")); output_str_length = tmp_str.length(); func_items[9]->set(tmp_str.ptr(), tmp_str.length(), tmp_str.charset()); - if (result->send_data(result_fields)) + if (result->send_data(result_fields) > 0) return -1; continue; } @@ -798,7 +798,7 @@ int analyse::end_of_records() if (!(*f)->nulls) ans.append(STRING_WITH_LEN(" NOT NULL")); func_items[9]->set(ans.ptr(), ans.length(), ans.charset()); - if (result->send_data(result_fields)) + if (result->send_data(result_fields) > 0) return -1; } return 0; diff --git a/sql/sql_class.cc b/sql/sql_class.cc index a02ab2bba9e..ba7e0654331 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -1883,7 +1883,7 @@ void select_send::cleanup() /* Send data to client. Returns 0 if ok */ -bool select_send::send_data(List<Item> &items) +int select_send::send_data(List<Item> &items) { if (unit->offset_limit_cnt) { // using limit offset,count @@ -2192,7 +2192,7 @@ select_export::prepare(List<Item> &list, SELECT_LEX_UNIT *u) (int) (uchar) (x) == line_sep_char || \ !(x)) -bool select_export::send_data(List<Item> &items) +int select_export::send_data(List<Item> &items) { DBUG_ENTER("select_export::send_data"); @@ -2450,7 +2450,7 @@ select_dump::prepare(List<Item> &list __attribute__((unused)), } -bool select_dump::send_data(List<Item> &items) +int select_dump::send_data(List<Item> &items) { List_iterator_fast<Item> li(items); char buff[MAX_FIELD_WIDTH]; @@ -2495,7 +2495,7 @@ select_subselect::select_subselect(Item_subselect *item_arg) } -bool select_singlerow_subselect::send_data(List<Item> &items) +int select_singlerow_subselect::send_data(List<Item> &items) { DBUG_ENTER("select_singlerow_subselect::send_data"); Item_singlerow_subselect *it= (Item_singlerow_subselect *)item; @@ -2526,7 +2526,7 @@ void select_max_min_finder_subselect::cleanup() } -bool select_max_min_finder_subselect::send_data(List<Item> &items) +int select_max_min_finder_subselect::send_data(List<Item> &items) { DBUG_ENTER("select_max_min_finder_subselect::send_data"); Item_maxmin_subselect *it= (Item_maxmin_subselect *)item; @@ -2630,7 +2630,7 @@ bool select_max_min_finder_subselect::cmp_str() sortcmp(val1, val2, cache->collation.collation) < 0); } -bool select_exists_subselect::send_data(List<Item> &items) +int select_exists_subselect::send_data(List<Item> &items) { DBUG_ENTER("select_exists_subselect::send_data"); Item_exists_subselect *it= (Item_exists_subselect *)item; @@ -2982,7 +2982,7 @@ Statement_map::~Statement_map() hash_free(&st_hash); } -bool select_dumpvar::send_data(List<Item> &items) +int select_dumpvar::send_data(List<Item> &items) { List_iterator_fast<my_var> var_li(var_list); List_iterator<Item> it(items); diff --git a/sql/sql_class.h b/sql/sql_class.h index 8a5cc6da741..90fe2bb49c1 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -2567,7 +2567,11 @@ public: virtual uint field_count(List<Item> &fields) const { return fields.elements; } virtual bool send_fields(List<Item> &list, uint flags)=0; - virtual bool send_data(List<Item> &items)=0; + /* + send_data returns 0 on ok, 1 on error and -1 if data was ignored, for + example for a duplicate row entry written to a temp table. + */ + virtual int send_data(List<Item> &items)=0; virtual bool initialize_tables (JOIN *join=0) { return 0; } virtual void send_error(uint errcode,const char *err); virtual bool send_eof()=0; @@ -2625,7 +2629,7 @@ class select_send :public select_result { public: select_send() :is_result_set_started(FALSE) {} bool send_fields(List<Item> &list, uint flags); - bool send_data(List<Item> &items); + int send_data(List<Item> &items); bool send_eof(); virtual bool check_simple_select() const { return FALSE; } void abort(); @@ -2696,7 +2700,7 @@ public: } ~select_export(); int prepare(List<Item> &list, SELECT_LEX_UNIT *u); - bool send_data(List<Item> &items); + int send_data(List<Item> &items); }; @@ -2713,7 +2717,7 @@ public: nest_level= nest_level_arg; } int prepare(List<Item> &list, SELECT_LEX_UNIT *u); - bool send_data(List<Item> &items); + int send_data(List<Item> &items); }; @@ -2734,7 +2738,7 @@ public: ~select_insert(); int prepare(List<Item> &list, SELECT_LEX_UNIT *u); virtual int prepare2(void); - bool send_data(List<Item> &items); + virtual int send_data(List<Item> &items); virtual void store_values(List<Item> &values); virtual bool can_rollback_data() { return 0; } void send_error(uint errcode,const char *err); @@ -2889,7 +2893,7 @@ public: select_union() :table(0) {} int prepare(List<Item> &list, SELECT_LEX_UNIT *u); - bool send_data(List<Item> &items); + int send_data(List<Item> &items); bool send_eof(); bool flush(); @@ -2905,7 +2909,7 @@ protected: Item_subselect *item; public: select_subselect(Item_subselect *item); - bool send_data(List<Item> &items)=0; + int send_data(List<Item> &items)=0; bool send_eof() { return 0; }; }; @@ -2916,7 +2920,7 @@ public: select_singlerow_subselect(Item_subselect *item_arg) :select_subselect(item_arg) {} - bool send_data(List<Item> &items); + int send_data(List<Item> &items); }; /* used in independent ALL/ANY optimisation */ @@ -2930,7 +2934,7 @@ public: :select_subselect(item_arg), cache(0), fmax(mx) {} void cleanup(); - bool send_data(List<Item> &items); + int send_data(List<Item> &items); bool cmp_real(); bool cmp_int(); bool cmp_decimal(); @@ -2943,7 +2947,7 @@ class select_exists_subselect :public select_subselect public: select_exists_subselect(Item_subselect *item_arg) :select_subselect(item_arg){} - bool send_data(List<Item> &items); + int send_data(List<Item> &items); }; /* Structs used when sorting */ @@ -3108,7 +3112,7 @@ public: multi_delete(TABLE_LIST *dt, uint num_of_tables); ~multi_delete(); int prepare(List<Item> &list, SELECT_LEX_UNIT *u); - bool send_data(List<Item> &items); + int send_data(List<Item> &items); bool initialize_tables (JOIN *join); void send_error(uint errcode,const char *err); int do_deletes(); @@ -3152,7 +3156,7 @@ public: enum_duplicates handle_duplicates, bool ignore); ~multi_update(); int prepare(List<Item> &list, SELECT_LEX_UNIT *u); - bool send_data(List<Item> &items); + int send_data(List<Item> &items); bool initialize_tables (JOIN *join); void send_error(uint errcode,const char *err); int do_updates(); @@ -3196,7 +3200,7 @@ public: } ~select_dumpvar() {} int prepare(List<Item> &list, SELECT_LEX_UNIT *u); - bool send_data(List<Item> &items); + int send_data(List<Item> &items); bool send_eof(); virtual bool check_simple_select() const; void cleanup(); diff --git a/sql/sql_cursor.cc b/sql/sql_cursor.cc index 77be6eaff34..2b01e43e406 100644 --- a/sql/sql_cursor.cc +++ b/sql/sql_cursor.cc @@ -662,7 +662,7 @@ void Materialized_cursor::fetch(ulong num_rows) If network write failed (i.e. due to a closed socked), the error has already been set. Just return. */ - if (result->send_data(item_list)) + if (result->send_data(item_list) > 0) return; } diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index 5564d628594..6729c34afd3 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -757,7 +757,7 @@ multi_delete::~multi_delete() } -bool multi_delete::send_data(List<Item> &values) +int multi_delete::send_data(List<Item> &values) { int secure_counter= delete_while_scanning ? -1 : 0; TABLE_LIST *del_table; diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 81f658b6a77..901db600d0d 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -3191,7 +3191,7 @@ select_insert::~select_insert() } -bool select_insert::send_data(List<Item> &values) +int select_insert::send_data(List<Item> &values) { DBUG_ENTER("select_insert::send_data"); bool error=0; diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index c7109982f93..1a3c4f4f8ae 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -106,7 +106,7 @@ class Select_fetch_protocol_binary: public select_send public: Select_fetch_protocol_binary(THD *thd); virtual bool send_fields(List<Item> &list, uint flags); - virtual bool send_data(List<Item> &items); + virtual int send_data(List<Item> &items); virtual bool send_eof(); #ifdef EMBEDDED_LIBRARY void begin_dataset() @@ -2840,11 +2840,11 @@ bool Select_fetch_protocol_binary::send_eof() } -bool +int Select_fetch_protocol_binary::send_data(List<Item> &fields) { Protocol *save_protocol= thd->protocol; - bool rc; + int rc; thd->protocol= &protocol; rc= select_send::send_data(fields); diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 052c01725de..8c5b881f41e 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -1811,7 +1811,7 @@ JOIN::exec() { if (do_send_rows && (procedure ? (procedure->send_row(procedure_fields_list) || - procedure->end_of_records()) : result->send_data(fields_list))) + procedure->end_of_records()) : result->send_data(fields_list)> 0)) error= 1; else { @@ -7423,7 +7423,7 @@ return_zero_rows(JOIN *join, select_result *result,TABLE_LIST *tables, Item *item; while ((item= it++)) item->no_rows_in_result(); - send_error= result->send_data(fields); + send_error= result->send_data(fields) > 0; } if (!send_error) result->send_eof(); // Should be safe @@ -11466,7 +11466,7 @@ do_select(JOIN *join,List<Item> *fields,TABLE *table,Procedure *procedure) { List<Item> *columns_list= (procedure ? &join->procedure_fields_list : fields); - rc= join->result->send_data(*columns_list); + rc= join->result->send_data(*columns_list) > 0; } } else @@ -12687,7 +12687,13 @@ end_send(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), if (join->procedure) error=join->procedure->send_row(join->procedure_fields_list); else if (join->do_send_rows) - error=join->result->send_data(*join->fields); + { + if ((error= join->result->send_data(*join->fields)) < 0) + { + /* row was not accepted. Don't count it */ + DBUG_RETURN(NESTED_LOOP_OK); + } + } if (error) DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */ if (++join->send_records >= join->unit->select_limit_cnt && @@ -12799,7 +12805,15 @@ end_send_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), else { if (join->do_send_rows) - error=join->result->send_data(*join->fields) ? 1 : 0; + { + error= join->result->send_data(*join->fields); + if (error < 0) + { + /* Duplicate row, don't count */ + join->send_records--; + error= 0; + } + } join->send_records++; } if (join->rollup.state != ROLLUP::STATE_NONE && error <= 0) @@ -16678,6 +16692,7 @@ int JOIN::rollup_send_data(uint idx) uint i; for (i= send_group_parts ; i-- > idx ; ) { + int res= 0; /* Get reference pointers to sum functions in place */ memcpy((char*) ref_pointer_array, (char*) rollup.ref_pointer_arrays[i], @@ -16685,9 +16700,10 @@ int JOIN::rollup_send_data(uint idx) if ((!having || having->val_int())) { if (send_records < unit->select_limit_cnt && do_send_rows && - result->send_data(rollup.fields[i])) + (res= result->send_data(rollup.fields[i])) > 0) return 1; - send_records++; + if (!res) + send_records++; } } /* Restore ref_pointer_array */ diff --git a/sql/sql_union.cc b/sql/sql_union.cc index 2cedce497b6..d173c761311 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -49,7 +49,7 @@ int select_union::prepare(List<Item> &list, SELECT_LEX_UNIT *u) } -bool select_union::send_data(List<Item> &values) +int select_union::send_data(List<Item> &values) { int error= 0; if (unit->offset_limit_cnt) @@ -63,6 +63,14 @@ bool select_union::send_data(List<Item> &values) if ((error= table->file->ha_write_row(table->record[0]))) { + if (error == HA_ERR_FOUND_DUPP_KEY) + { + /* + Inform upper level that we found a duplicate key, that should not + be counted as part of limit + */ + return -1; + } /* create_internal_tmp_table_from_heap will generate error if needed */ if (table->file->is_fatal_error(error, HA_CHECK_DUP) && create_internal_tmp_table_from_heap(thd, table, &tmp_table_param, error, 1)) diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 41ff4e998e2..70572b406e5 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -1689,7 +1689,7 @@ multi_update::~multi_update() } -bool multi_update::send_data(List<Item> ¬_used_values) +int multi_update::send_data(List<Item> ¬_used_values) { TABLE_LIST *cur_table; DBUG_ENTER("multi_update::send_data"); diff --git a/storage/pbxt/src/lock_xt.cc b/storage/pbxt/src/lock_xt.cc index 946adfecccc..5dbba9db83a 100644 --- a/storage/pbxt/src/lock_xt.cc +++ b/storage/pbxt/src/lock_xt.cc @@ -1424,6 +1424,7 @@ xtPublic void xt_spinxslock_init(struct XTThread *XT_UNUSED(self), XTSpinXSLockP #endif { sxs->sxs_xlocked = 0; + sxs->sxs_xwaiter = 0; sxs->sxs_rlock_count = 0; sxs->sxs_wait_count = 0; #ifdef DEBUG |