Commit 0576b10d authored by unknown's avatar unknown

Merge Mariadb 5.1->5.2

parents 0b74feae 4ad5de2c
...@@ -414,7 +414,7 @@ a ...@@ -414,7 +414,7 @@ a
5 5
select found_rows(); select found_rows();
found_rows() found_rows()
6 5
SELECT SQL_CALC_FOUND_ROWS * FROM t1 LIMIT 100 UNION SELECT * FROM t2; SELECT SQL_CALC_FOUND_ROWS * FROM t1 LIMIT 100 UNION SELECT * FROM t2;
a a
1 1
...@@ -447,7 +447,7 @@ a ...@@ -447,7 +447,7 @@ a
4 4
select found_rows(); select found_rows();
found_rows() found_rows()
6 5
SELECT SQL_CALC_FOUND_ROWS * FROM t1 limit 2,2 UNION SELECT * FROM t2; SELECT SQL_CALC_FOUND_ROWS * FROM t1 limit 2,2 UNION SELECT * FROM t2;
a a
3 3
...@@ -1208,9 +1208,12 @@ a b ...@@ -1208,9 +1208,12 @@ a b
select * from ((select * from t1 limit 1) union (select * from t1 limit 1)) a; select * from ((select * from t1 limit 1) union (select * from t1 limit 1)) a;
a b a b
1 a 1 a
2 b
select * from ((select * from t1 limit 1) union (select * from t1 limit 1) union (select * from t1 limit 1)) a; select * from ((select * from t1 limit 1) union (select * from t1 limit 1) union (select * from t1 limit 1)) a;
a b a b
1 a 1 a
2 b
3 c
select * from ((((select * from t1))) union (select * from t1) union (select * from t1)) a; select * from ((((select * from t1))) union (select * from t1) union (select * from t1)) a;
a b a b
1 a 1 a
...@@ -1647,4 +1650,17 @@ b ...@@ -1647,4 +1650,17 @@ b
1 1
2 2
DROP TABLE t1,t2; 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 End of 5.1 tests
...@@ -362,7 +362,7 @@ a ...@@ -362,7 +362,7 @@ a
2 2
select found_rows(); select found_rows();
found_rows() found_rows()
6 5
SELECT SQL_CALC_FOUND_ROWS * FROM t1 UNION SELECT * FROM t2 LIMIT 100; SELECT SQL_CALC_FOUND_ROWS * FROM t1 UNION SELECT * FROM t2 LIMIT 100;
a a
1 1
...@@ -372,7 +372,7 @@ a ...@@ -372,7 +372,7 @@ a
5 5
select found_rows(); select found_rows();
found_rows() found_rows()
6 5
SELECT SQL_CALC_FOUND_ROWS * FROM t1 LIMIT 100 UNION SELECT * FROM t2; SELECT SQL_CALC_FOUND_ROWS * FROM t1 LIMIT 100 UNION SELECT * FROM t2;
a a
1 1
...@@ -405,7 +405,7 @@ a ...@@ -405,7 +405,7 @@ a
4 4
select found_rows(); select found_rows();
found_rows() found_rows()
6 5
SELECT SQL_CALC_FOUND_ROWS * FROM t1 limit 2,2 UNION SELECT * FROM t2; SELECT SQL_CALC_FOUND_ROWS * FROM t1 limit 2,2 UNION SELECT * FROM t2;
a a
3 3
...@@ -1166,9 +1166,12 @@ a b ...@@ -1166,9 +1166,12 @@ a b
select * from ((select * from t1 limit 1) union (select * from t1 limit 1)) a; select * from ((select * from t1 limit 1) union (select * from t1 limit 1)) a;
a b a b
1 a 1 a
2 b
select * from ((select * from t1 limit 1) union (select * from t1 limit 1) union (select * from t1 limit 1)) a; select * from ((select * from t1 limit 1) union (select * from t1 limit 1) union (select * from t1 limit 1)) a;
a b a b
1 a 1 a
2 b
3 c
select * from ((((select * from t1))) union (select * from t1) union (select * from t1)) a; select * from ((((select * from t1))) union (select * from t1) union (select * from t1)) a;
a b a b
1 a 1 a
...@@ -1426,4 +1429,17 @@ select _utf8'12' union select _latin1'12345'; ...@@ -1426,4 +1429,17 @@ select _utf8'12' union select _latin1'12345';
12 12
12 12
12345 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 End of 5.0 tests
...@@ -904,6 +904,15 @@ drop table t1, t2; ...@@ -904,6 +904,15 @@ drop table t1, t2;
# #
select _utf8'12' union select _latin1'12345'; 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 --disable_query_log
drop database pbxt; drop database pbxt;
......
...@@ -1155,5 +1155,13 @@ SELECT * FROM t2 UNION SELECT * FROM t2 ...@@ -1155,5 +1155,13 @@ SELECT * FROM t2 UNION SELECT * FROM t2
DROP TABLE t1,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 --echo End of 5.1 tests
...@@ -651,7 +651,7 @@ int Select_fetch_into_spvars::prepare(List<Item> &fields, SELECT_LEX_UNIT *u) ...@@ -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<struct sp_variable> spvar_iter(*spvar_list);
List_iterator_fast<Item> item_iter(items); List_iterator_fast<Item> item_iter(items);
...@@ -668,7 +668,7 @@ bool Select_fetch_into_spvars::send_data(List<Item> &items) ...@@ -668,7 +668,7 @@ bool Select_fetch_into_spvars::send_data(List<Item> &items)
for (; spvar= spvar_iter++, item= item_iter++; ) for (; spvar= spvar_iter++, item= item_iter++; )
{ {
if (thd->spcont->set_variable(thd, spvar->offset, &item)) if (thd->spcont->set_variable(thd, spvar->offset, &item))
return TRUE; return 1;
} }
return FALSE; return 0;
} }
...@@ -254,7 +254,7 @@ class Select_fetch_into_spvars: public select_result_interceptor ...@@ -254,7 +254,7 @@ class Select_fetch_into_spvars: public select_result_interceptor
void set_spvar_list(List<struct sp_variable> *vars) { spvar_list= vars; } void set_spvar_list(List<struct sp_variable> *vars) { spvar_list= vars; }
virtual bool send_eof() { return FALSE; } 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); virtual int prepare(List<Item> &list, SELECT_LEX_UNIT *u);
}; };
......
...@@ -753,7 +753,7 @@ int analyse::end_of_records() ...@@ -753,7 +753,7 @@ int analyse::end_of_records()
tmp_str.append(STRING_WITH_LEN(" NOT NULL")); tmp_str.append(STRING_WITH_LEN(" NOT NULL"));
output_str_length = tmp_str.length(); output_str_length = tmp_str.length();
func_items[9]->set(tmp_str.ptr(), tmp_str.length(), tmp_str.charset()); 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; return -1;
continue; continue;
} }
...@@ -798,7 +798,7 @@ int analyse::end_of_records() ...@@ -798,7 +798,7 @@ int analyse::end_of_records()
if (!(*f)->nulls) if (!(*f)->nulls)
ans.append(STRING_WITH_LEN(" NOT NULL")); ans.append(STRING_WITH_LEN(" NOT NULL"));
func_items[9]->set(ans.ptr(), ans.length(), ans.charset()); 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 -1;
} }
return 0; return 0;
......
...@@ -1883,7 +1883,7 @@ void select_send::cleanup() ...@@ -1883,7 +1883,7 @@ void select_send::cleanup()
/* Send data to client. Returns 0 if ok */ /* 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) if (unit->offset_limit_cnt)
{ // using limit offset,count { // using limit offset,count
...@@ -2192,7 +2192,7 @@ select_export::prepare(List<Item> &list, SELECT_LEX_UNIT *u) ...@@ -2192,7 +2192,7 @@ select_export::prepare(List<Item> &list, SELECT_LEX_UNIT *u)
(int) (uchar) (x) == line_sep_char || \ (int) (uchar) (x) == line_sep_char || \
!(x)) !(x))
bool select_export::send_data(List<Item> &items) int select_export::send_data(List<Item> &items)
{ {
DBUG_ENTER("select_export::send_data"); DBUG_ENTER("select_export::send_data");
...@@ -2450,7 +2450,7 @@ select_dump::prepare(List<Item> &list __attribute__((unused)), ...@@ -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); List_iterator_fast<Item> li(items);
char buff[MAX_FIELD_WIDTH]; char buff[MAX_FIELD_WIDTH];
...@@ -2495,7 +2495,7 @@ select_subselect::select_subselect(Item_subselect *item_arg) ...@@ -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"); DBUG_ENTER("select_singlerow_subselect::send_data");
Item_singlerow_subselect *it= (Item_singlerow_subselect *)item; Item_singlerow_subselect *it= (Item_singlerow_subselect *)item;
...@@ -2526,7 +2526,7 @@ void select_max_min_finder_subselect::cleanup() ...@@ -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"); DBUG_ENTER("select_max_min_finder_subselect::send_data");
Item_maxmin_subselect *it= (Item_maxmin_subselect *)item; Item_maxmin_subselect *it= (Item_maxmin_subselect *)item;
...@@ -2630,7 +2630,7 @@ bool select_max_min_finder_subselect::cmp_str() ...@@ -2630,7 +2630,7 @@ bool select_max_min_finder_subselect::cmp_str()
sortcmp(val1, val2, cache->collation.collation) < 0); 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"); DBUG_ENTER("select_exists_subselect::send_data");
Item_exists_subselect *it= (Item_exists_subselect *)item; Item_exists_subselect *it= (Item_exists_subselect *)item;
...@@ -2982,7 +2982,7 @@ Statement_map::~Statement_map() ...@@ -2982,7 +2982,7 @@ Statement_map::~Statement_map()
hash_free(&st_hash); 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_fast<my_var> var_li(var_list);
List_iterator<Item> it(items); List_iterator<Item> it(items);
......
...@@ -2567,7 +2567,11 @@ class select_result :public Sql_alloc { ...@@ -2567,7 +2567,11 @@ class select_result :public Sql_alloc {
virtual uint field_count(List<Item> &fields) const virtual uint field_count(List<Item> &fields) const
{ return fields.elements; } { return fields.elements; }
virtual bool send_fields(List<Item> &list, uint flags)=0; 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 bool initialize_tables (JOIN *join=0) { return 0; }
virtual void send_error(uint errcode,const char *err); virtual void send_error(uint errcode,const char *err);
virtual bool send_eof()=0; virtual bool send_eof()=0;
...@@ -2625,7 +2629,7 @@ class select_send :public select_result { ...@@ -2625,7 +2629,7 @@ class select_send :public select_result {
public: public:
select_send() :is_result_set_started(FALSE) {} select_send() :is_result_set_started(FALSE) {}
bool send_fields(List<Item> &list, uint flags); bool send_fields(List<Item> &list, uint flags);
bool send_data(List<Item> &items); int send_data(List<Item> &items);
bool send_eof(); bool send_eof();
virtual bool check_simple_select() const { return FALSE; } virtual bool check_simple_select() const { return FALSE; }
void abort(); void abort();
...@@ -2696,7 +2700,7 @@ class select_export :public select_to_file { ...@@ -2696,7 +2700,7 @@ class select_export :public select_to_file {
} }
~select_export(); ~select_export();
int prepare(List<Item> &list, SELECT_LEX_UNIT *u); 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 @@ class select_dump :public select_to_file { ...@@ -2713,7 +2717,7 @@ class select_dump :public select_to_file {
nest_level= nest_level_arg; nest_level= nest_level_arg;
} }
int prepare(List<Item> &list, SELECT_LEX_UNIT *u); 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 @@ class select_insert :public select_result_interceptor { ...@@ -2734,7 +2738,7 @@ class select_insert :public select_result_interceptor {
~select_insert(); ~select_insert();
int prepare(List<Item> &list, SELECT_LEX_UNIT *u); int prepare(List<Item> &list, SELECT_LEX_UNIT *u);
virtual int prepare2(void); 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 void store_values(List<Item> &values);
virtual bool can_rollback_data() { return 0; } virtual bool can_rollback_data() { return 0; }
void send_error(uint errcode,const char *err); void send_error(uint errcode,const char *err);
...@@ -2889,7 +2893,7 @@ class select_union :public select_result_interceptor ...@@ -2889,7 +2893,7 @@ class select_union :public select_result_interceptor
select_union() :table(0) {} select_union() :table(0) {}
int prepare(List<Item> &list, SELECT_LEX_UNIT *u); 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 send_eof();
bool flush(); bool flush();
...@@ -2905,7 +2909,7 @@ class select_subselect :public select_result_interceptor ...@@ -2905,7 +2909,7 @@ class select_subselect :public select_result_interceptor
Item_subselect *item; Item_subselect *item;
public: public:
select_subselect(Item_subselect *item); select_subselect(Item_subselect *item);
bool send_data(List<Item> &items)=0; int send_data(List<Item> &items)=0;
bool send_eof() { return 0; }; bool send_eof() { return 0; };
}; };
...@@ -2916,7 +2920,7 @@ class select_singlerow_subselect :public select_subselect ...@@ -2916,7 +2920,7 @@ class select_singlerow_subselect :public select_subselect
select_singlerow_subselect(Item_subselect *item_arg) select_singlerow_subselect(Item_subselect *item_arg)
:select_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 */ /* used in independent ALL/ANY optimisation */
...@@ -2930,7 +2934,7 @@ class select_max_min_finder_subselect :public select_subselect ...@@ -2930,7 +2934,7 @@ class select_max_min_finder_subselect :public select_subselect
:select_subselect(item_arg), cache(0), fmax(mx) :select_subselect(item_arg), cache(0), fmax(mx)
{} {}
void cleanup(); void cleanup();
bool send_data(List<Item> &items); int send_data(List<Item> &items);
bool cmp_real(); bool cmp_real();
bool cmp_int(); bool cmp_int();
bool cmp_decimal(); bool cmp_decimal();
...@@ -2943,7 +2947,7 @@ class select_exists_subselect :public select_subselect ...@@ -2943,7 +2947,7 @@ class select_exists_subselect :public select_subselect
public: public:
select_exists_subselect(Item_subselect *item_arg) select_exists_subselect(Item_subselect *item_arg)
:select_subselect(item_arg){} :select_subselect(item_arg){}
bool send_data(List<Item> &items); int send_data(List<Item> &items);
}; };
/* Structs used when sorting */ /* Structs used when sorting */
...@@ -3108,7 +3112,7 @@ class multi_delete :public select_result_interceptor ...@@ -3108,7 +3112,7 @@ class multi_delete :public select_result_interceptor
multi_delete(TABLE_LIST *dt, uint num_of_tables); multi_delete(TABLE_LIST *dt, uint num_of_tables);
~multi_delete(); ~multi_delete();
int prepare(List<Item> &list, SELECT_LEX_UNIT *u); 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); bool initialize_tables (JOIN *join);
void send_error(uint errcode,const char *err); void send_error(uint errcode,const char *err);
int do_deletes(); int do_deletes();
...@@ -3152,7 +3156,7 @@ class multi_update :public select_result_interceptor ...@@ -3152,7 +3156,7 @@ class multi_update :public select_result_interceptor
enum_duplicates handle_duplicates, bool ignore); enum_duplicates handle_duplicates, bool ignore);
~multi_update(); ~multi_update();
int prepare(List<Item> &list, SELECT_LEX_UNIT *u); 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); bool initialize_tables (JOIN *join);
void send_error(uint errcode,const char *err); void send_error(uint errcode,const char *err);
int do_updates(); int do_updates();
...@@ -3196,7 +3200,7 @@ class select_dumpvar :public select_result_interceptor { ...@@ -3196,7 +3200,7 @@ class select_dumpvar :public select_result_interceptor {
} }
~select_dumpvar() {} ~select_dumpvar() {}
int prepare(List<Item> &list, SELECT_LEX_UNIT *u); 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 send_eof();
virtual bool check_simple_select() const; virtual bool check_simple_select() const;
void cleanup(); void cleanup();
......
...@@ -662,7 +662,7 @@ void Materialized_cursor::fetch(ulong num_rows) ...@@ -662,7 +662,7 @@ void Materialized_cursor::fetch(ulong num_rows)
If network write failed (i.e. due to a closed socked), If network write failed (i.e. due to a closed socked),
the error has already been set. Just return. the error has already been set. Just return.
*/ */
if (result->send_data(item_list)) if (result->send_data(item_list) > 0)
return; return;
} }
......
...@@ -757,7 +757,7 @@ multi_delete::~multi_delete() ...@@ -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; int secure_counter= delete_while_scanning ? -1 : 0;
TABLE_LIST *del_table; TABLE_LIST *del_table;
......
...@@ -3191,7 +3191,7 @@ select_insert::~select_insert() ...@@ -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"); DBUG_ENTER("select_insert::send_data");
bool error=0; bool error=0;
......
...@@ -106,7 +106,7 @@ class Select_fetch_protocol_binary: public select_send ...@@ -106,7 +106,7 @@ class Select_fetch_protocol_binary: public select_send
public: public:
Select_fetch_protocol_binary(THD *thd); Select_fetch_protocol_binary(THD *thd);
virtual bool send_fields(List<Item> &list, uint flags); 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(); virtual bool send_eof();
#ifdef EMBEDDED_LIBRARY #ifdef EMBEDDED_LIBRARY
void begin_dataset() void begin_dataset()
...@@ -2840,11 +2840,11 @@ bool Select_fetch_protocol_binary::send_eof() ...@@ -2840,11 +2840,11 @@ bool Select_fetch_protocol_binary::send_eof()
} }
bool int
Select_fetch_protocol_binary::send_data(List<Item> &fields) Select_fetch_protocol_binary::send_data(List<Item> &fields)
{ {
Protocol *save_protocol= thd->protocol; Protocol *save_protocol= thd->protocol;
bool rc; int rc;
thd->protocol= &protocol; thd->protocol= &protocol;
rc= select_send::send_data(fields); rc= select_send::send_data(fields);
......
...@@ -1811,7 +1811,7 @@ JOIN::exec() ...@@ -1811,7 +1811,7 @@ JOIN::exec()
{ {
if (do_send_rows && if (do_send_rows &&
(procedure ? (procedure->send_row(procedure_fields_list) || (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; error= 1;
else else
{ {
...@@ -7423,7 +7423,7 @@ return_zero_rows(JOIN *join, select_result *result,TABLE_LIST *tables, ...@@ -7423,7 +7423,7 @@ return_zero_rows(JOIN *join, select_result *result,TABLE_LIST *tables,
Item *item; Item *item;
while ((item= it++)) while ((item= it++))
item->no_rows_in_result(); item->no_rows_in_result();
send_error= result->send_data(fields); send_error= result->send_data(fields) > 0;
} }
if (!send_error) if (!send_error)
result->send_eof(); // Should be safe result->send_eof(); // Should be safe
...@@ -11466,7 +11466,7 @@ do_select(JOIN *join,List<Item> *fields,TABLE *table,Procedure *procedure) ...@@ -11466,7 +11466,7 @@ do_select(JOIN *join,List<Item> *fields,TABLE *table,Procedure *procedure)
{ {
List<Item> *columns_list= (procedure ? &join->procedure_fields_list : List<Item> *columns_list= (procedure ? &join->procedure_fields_list :
fields); fields);
rc= join->result->send_data(*columns_list); rc= join->result->send_data(*columns_list) > 0;
} }
} }
else else
...@@ -12687,7 +12687,13 @@ end_send(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), ...@@ -12687,7 +12687,13 @@ end_send(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
if (join->procedure) if (join->procedure)
error=join->procedure->send_row(join->procedure_fields_list); error=join->procedure->send_row(join->procedure_fields_list);
else if (join->do_send_rows) 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) if (error)
DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */ DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */
if (++join->send_records >= join->unit->select_limit_cnt && if (++join->send_records >= join->unit->select_limit_cnt &&
...@@ -12799,7 +12805,15 @@ end_send_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), ...@@ -12799,7 +12805,15 @@ end_send_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
else else
{ {
if (join->do_send_rows) 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++; join->send_records++;
} }
if (join->rollup.state != ROLLUP::STATE_NONE && error <= 0) if (join->rollup.state != ROLLUP::STATE_NONE && error <= 0)
...@@ -16678,6 +16692,7 @@ int JOIN::rollup_send_data(uint idx) ...@@ -16678,6 +16692,7 @@ int JOIN::rollup_send_data(uint idx)
uint i; uint i;
for (i= send_group_parts ; i-- > idx ; ) for (i= send_group_parts ; i-- > idx ; )
{ {
int res= 0;
/* Get reference pointers to sum functions in place */ /* Get reference pointers to sum functions in place */
memcpy((char*) ref_pointer_array, memcpy((char*) ref_pointer_array,
(char*) rollup.ref_pointer_arrays[i], (char*) rollup.ref_pointer_arrays[i],
...@@ -16685,8 +16700,9 @@ int JOIN::rollup_send_data(uint idx) ...@@ -16685,8 +16700,9 @@ int JOIN::rollup_send_data(uint idx)
if ((!having || having->val_int())) if ((!having || having->val_int()))
{ {
if (send_records < unit->select_limit_cnt && do_send_rows && 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; return 1;
if (!res)
send_records++; send_records++;
} }
} }
......
...@@ -49,7 +49,7 @@ int select_union::prepare(List<Item> &list, SELECT_LEX_UNIT *u) ...@@ -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; int error= 0;
if (unit->offset_limit_cnt) if (unit->offset_limit_cnt)
...@@ -63,6 +63,14 @@ bool select_union::send_data(List<Item> &values) ...@@ -63,6 +63,14 @@ bool select_union::send_data(List<Item> &values)
if ((error= table->file->ha_write_row(table->record[0]))) 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 */ /* create_internal_tmp_table_from_heap will generate error if needed */
if (table->file->is_fatal_error(error, HA_CHECK_DUP) && if (table->file->is_fatal_error(error, HA_CHECK_DUP) &&
create_internal_tmp_table_from_heap(thd, table, &tmp_table_param, error, 1)) create_internal_tmp_table_from_heap(thd, table, &tmp_table_param, error, 1))
......
...@@ -1689,7 +1689,7 @@ multi_update::~multi_update() ...@@ -1689,7 +1689,7 @@ multi_update::~multi_update()
} }
bool multi_update::send_data(List<Item> &not_used_values) int multi_update::send_data(List<Item> &not_used_values)
{ {
TABLE_LIST *cur_table; TABLE_LIST *cur_table;
DBUG_ENTER("multi_update::send_data"); DBUG_ENTER("multi_update::send_data");
......
...@@ -1424,6 +1424,7 @@ xtPublic void xt_spinxslock_init(struct XTThread *XT_UNUSED(self), XTSpinXSLockP ...@@ -1424,6 +1424,7 @@ xtPublic void xt_spinxslock_init(struct XTThread *XT_UNUSED(self), XTSpinXSLockP
#endif #endif
{ {
sxs->sxs_xlocked = 0; sxs->sxs_xlocked = 0;
sxs->sxs_xwaiter = 0;
sxs->sxs_rlock_count = 0; sxs->sxs_rlock_count = 0;
sxs->sxs_wait_count = 0; sxs->sxs_wait_count = 0;
#ifdef DEBUG #ifdef DEBUG
......
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