summaryrefslogtreecommitdiff
path: root/sql/sql_select.cc
diff options
context:
space:
mode:
authorunknown <timour/timka@lamia.home>2006-09-01 15:07:04 +0300
committerunknown <timour/timka@lamia.home>2006-09-01 15:07:04 +0300
commitb017caefbd5f95fcdc81f1f545fdc944a454d168 (patch)
tree3e3f57b1259be8b80af868ee4f4c15dbf692b032 /sql/sql_select.cc
parentbfdbb780c26aae2705cf0d7e3048b5c0e40f59e1 (diff)
downloadmariadb-git-b017caefbd5f95fcdc81f1f545fdc944a454d168.tar.gz
Fix for BUG#21787: COUNT(*) + ORDER BY + LIMIT returns wrong result
The problem was due to a prior fix for BUG 9676, which limited the rows stored in a temporary table to the LIMIT clause. This optimization is not applicable to non-group queries with aggregate functions. The fix disables the optimization in this case. mysql-test/r/limit.result: Test case for BUG#21787 mysql-test/t/limit.test: Test case for BUG#21787 sql/sql_select.cc: If there is an aggregate function in a non-group query, materialize all rows in the temporary table no matter if there is a LIMIT clause. This is necessary, since the aggregate functions must be computed over all result rows, not just the first LIMIT rows.
Diffstat (limited to 'sql/sql_select.cc')
-rw-r--r--sql/sql_select.cc19
1 files changed, 14 insertions, 5 deletions
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 605ef49bb07..4c086f08af3 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -5612,11 +5612,6 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
keyinfo->key_length+= key_part_info->length;
}
}
- else
- {
- set_if_smaller(table->max_rows, rows_limit);
- param->end_write_records= rows_limit;
- }
if (distinct && field_count != param->hidden_field_count)
{
@@ -5679,6 +5674,20 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
0 : FIELDFLAG_BINARY;
}
}
+
+ /*
+ Push the LIMIT clause to the temporary table creation, so that we
+ materialize only up to 'rows_limit' records instead of all result records.
+ This optimization is not applicable when there is GROUP BY or there is
+ no GROUP BY, but there are aggregate functions, because both must be
+ computed for all result rows.
+ */
+ if (!group && !thd->lex->current_select->with_sum_func)
+ {
+ set_if_smaller(table->max_rows, rows_limit);
+ param->end_write_records= rows_limit;
+ }
+
if (thd->is_fatal_error) // If end of memory
goto err; /* purecov: inspected */
table->db_record_offset=1;