1
0
mirror of https://github.com/MariaDB/server.git synced 2026-01-06 05:22:24 +03:00

Bug fix for lp:732124 union + limit returns wrong result

mysql-test/r/union.result:
  Added test for lp:732124
mysql-test/t/union.test:
  Added test for lp:732124
sql/sp_rcontext.cc:
  Updated function definition for ::send_data()
sql/sp_rcontext.h:
  Updated function definition for ::send_data()
sql/sql_analyse.cc:
  Test if send_data() returned an error
sql/sql_class.cc:
  Updated function definition for ::send_data()
sql/sql_class.h:
  Changed select_result::send_data(List<Item> &items) to return -1 in case of duplicate row that should not be counted as part of LIMIT
sql/sql_cursor.cc:
  Check if send_data returned error
sql/sql_delete.cc:
  Updated function definition for ::send_data()
sql/sql_insert.cc:
  Updated function definition for ::send_data()
sql/sql_select.cc:
  Don't count rows which send_data() tells you to ignore
sql/sql_union.cc:
  Inform caller that the row should be ignored. This is the real bug fix for lp:732124
sql/sql_update.cc:
  Updated function definition for ::send_data()
This commit is contained in:
Michael Widenius
2011-03-09 19:45:48 +02:00
parent 251a5fa975
commit e6b0be38f9
14 changed files with 95 additions and 43 deletions

View File

@@ -2514,7 +2514,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;
@@ -2572,7 +2576,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();
@@ -2643,7 +2647,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);
};
@@ -2660,7 +2664,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);
};
@@ -2681,7 +2685,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);
@@ -2836,7 +2840,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();
@@ -2852,7 +2856,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; };
};
@@ -2863,7 +2867,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 */
@@ -2877,7 +2881,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();
@@ -2890,7 +2894,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 */
@@ -3055,7 +3059,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();
@@ -3099,7 +3103,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();
@@ -3143,7 +3147,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();