summaryrefslogtreecommitdiff
path: root/sql/sql_prepare.cc
diff options
context:
space:
mode:
authorunknown <igor@rurik.mysql.com>2006-05-06 23:48:13 -0700
committerunknown <igor@rurik.mysql.com>2006-05-06 23:48:13 -0700
commit375749b8afd8b7f47a0b717d0546ad1b2a8f05eb (patch)
treec0395e36606a03a1a826b85cd00bc0c1484e9314 /sql/sql_prepare.cc
parent427bcfb440d76124539222f70b4787e8737e2100 (diff)
downloadmariadb-git-375749b8afd8b7f47a0b717d0546ad1b2a8f05eb.tar.gz
Fixed bug #14927.
A query with a group by and having clauses could return a wrong result set if the having condition contained a constant conjunct evaluated to FALSE. It happened because the pushdown condition for table with grouping columns lost its constant conjuncts. Pushdown conditions are always built by the function make_cond_for_table that ignores constant conjuncts. This is apparently not correct when constant false conjuncts are present. mysql-test/r/having.result: Added a test case for bug #14927. mysql-test/t/having.test: Added a test case for bug #14927. sql/sql_lex.cc: Fixed bug #14927. Initialized fields for having conditions in st_select_lex::init_query(). sql/sql_lex.h: Fixed bug #14927. Added a field to restore having condititions for execution in SP and PS. sql/sql_prepare.cc: Fixed bug #14927. Added code to restore havinf conditions for execution in SP and PS. sql/sql_select.cc: Fixed bug #14927. Performed evaluation of constant expressions in having clauses. If the having condition contains a constant conjunct that is always false an empty result set is returned after the optimization phase. In this case the corresponding EXPLAIN command now returns "Impossible HAVING" in the last column.
Diffstat (limited to 'sql/sql_prepare.cc')
-rw-r--r--sql/sql_prepare.cc10
1 files changed, 8 insertions, 2 deletions
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc
index 741d84eab44..2d9e80df63c 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -1667,10 +1667,11 @@ int mysql_stmt_prepare(THD *thd, char *packet, uint packet_length,
for (; sl; sl= sl->next_select_in_list())
{
/*
- Save WHERE clause pointers, because they may be changed
+ Save WHERE, HAVING clause pointers, because they may be changed
during query optimisation.
*/
sl->prep_where= sl->where;
+ sl->prep_having= sl->having;
/*
Switch off a temporary flag that prevents evaluation of
subqueries in statement prepare.
@@ -1696,13 +1697,18 @@ static void reset_stmt_for_execute(Prepared_statement *stmt)
/* remove option which was put by mysql_explain_union() */
sl->options&= ~SELECT_DESCRIBE;
/*
- Copy WHERE clause pointers to avoid damaging they by optimisation
+ Copy WHERE, HAVING clause pointers to avoid damaging they by optimisation
*/
if (sl->prep_where)
{
sl->where= sl->prep_where->copy_andor_structure(thd);
sl->where->cleanup();
}
+ if (sl->prep_having)
+ {
+ sl->having= sl->prep_having->copy_andor_structure(thd);
+ sl->having->cleanup();
+ }
DBUG_ASSERT(sl->join == 0);
ORDER *order;
/* Fix GROUP list */