summaryrefslogtreecommitdiff
path: root/sql/sql_select.cc
diff options
context:
space:
mode:
authorMichael Widenius <monty@askmonty.org>2011-03-09 19:45:48 +0200
committerMichael Widenius <monty@askmonty.org>2011-03-09 19:45:48 +0200
commite6b0be38f9ea03b4f657b210755f6891ce2a30f0 (patch)
treeb939c86916f6ab3745286dd9e19928e0c4041f13 /sql/sql_select.cc
parent251a5fa97598c8f0e7e0759880503d0932ca2918 (diff)
downloadmariadb-git-e6b0be38f9ea03b4f657b210755f6891ce2a30f0.tar.gz
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()
Diffstat (limited to 'sql/sql_select.cc')
-rw-r--r--sql/sql_select.cc30
1 files changed, 23 insertions, 7 deletions
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index f367315c258..6ce4ddcf2ea 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
{
@@ -7422,7 +7422,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
@@ -11456,7 +11456,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
@@ -12667,7 +12667,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 &&
@@ -12779,7 +12785,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)
@@ -16653,6 +16667,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],
@@ -16660,9 +16675,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 */