Commit 83001499 authored by unknown's avatar unknown

Merge rurik.mysql.com:/home/igor/dev/mysql-4.1-0

into  rurik.mysql.com:/home/igor/dev/mysql-5.0-0


mysql-test/t/having.test:
  Auto merged
mysql-test/r/having.result:
  Manual merge
sql/sql_lex.cc:
  Manual merge
sql/sql_lex.h:
  Manual merge
sql/sql_prepare.cc:
  Manual merge
sql/sql_select.cc:
  Manual merge
parents 6a2a94b5 67575038
...@@ -141,6 +141,40 @@ SUM(a) ...@@ -141,6 +141,40 @@ SUM(a)
6 6
4 4
DROP TABLE t1; DROP TABLE t1;
CREATE TABLE t1 (a int);
INSERT INTO t1 VALUES (1), (2), (1), (3), (2), (1);
SELECT a FROM t1 GROUP BY a HAVING a > 1;
a
2
3
SELECT a FROM t1 GROUP BY a HAVING 1 != 1 AND a > 1;
a
SELECT 0 AS x, a FROM t1 GROUP BY x,a HAVING x=1 AND a > 1;
x a
EXPLAIN SELECT a FROM t1 GROUP BY a HAVING 1 != 1 AND a > 1;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible HAVING
EXPLAIN SELECT 0 AS x, a FROM t1 GROUP BY x,a HAVING x=1 AND a > 1;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible HAVING
DROP table t1;
create table t1 (col1 int, col2 varchar(5), col_t1 int); create table t1 (col1 int, col2 varchar(5), col_t1 int);
create table t2 (col1 int, col2 varchar(5), col_t2 int); create table t2 (col1 int, col2 varchar(5), col_t2 int);
create table t3 (col1 int, col2 varchar(5), col_t3 int); create table t3 (col1 int, col2 varchar(5), col_t3 int);
......
...@@ -135,6 +135,22 @@ SELECT SUM(a) FROM t1 GROUP BY a HAVING SUM(a); ...@@ -135,6 +135,22 @@ SELECT SUM(a) FROM t1 GROUP BY a HAVING SUM(a);
DROP TABLE t1; DROP TABLE t1;
#
# Bug #14927: HAVING clause containing constant false conjunct
#
CREATE TABLE t1 (a int);
INSERT INTO t1 VALUES (1), (2), (1), (3), (2), (1);
SELECT a FROM t1 GROUP BY a HAVING a > 1;
SELECT a FROM t1 GROUP BY a HAVING 1 != 1 AND a > 1;
SELECT 0 AS x, a FROM t1 GROUP BY x,a HAVING x=1 AND a > 1;
EXPLAIN SELECT a FROM t1 GROUP BY a HAVING 1 != 1 AND a > 1;
EXPLAIN SELECT 0 AS x, a FROM t1 GROUP BY x,a HAVING x=1 AND a > 1;
DROP table t1;
# End of 4.1 tests # End of 4.1 tests
# #
......
...@@ -1122,7 +1122,7 @@ void st_select_lex::init_query() ...@@ -1122,7 +1122,7 @@ void st_select_lex::init_query()
embedding= leaf_tables= 0; embedding= leaf_tables= 0;
item_list.empty(); item_list.empty();
join= 0; join= 0;
having= where= prep_where= 0; having= prep_having= where= prep_where= 0;
olap= UNSPECIFIED_OLAP_TYPE; olap= UNSPECIFIED_OLAP_TYPE;
having_fix_field= 0; having_fix_field= 0;
context.select_lex= this; context.select_lex= this;
......
...@@ -474,6 +474,7 @@ public: ...@@ -474,6 +474,7 @@ public:
char *db; char *db;
Item *where, *having; /* WHERE & HAVING clauses */ Item *where, *having; /* WHERE & HAVING clauses */
Item *prep_where; /* saved WHERE clause for prepared statement processing */ Item *prep_where; /* saved WHERE clause for prepared statement processing */
Item *prep_having;/* saved HAVING clause for prepared statement processing */
/* point on lex in which it was created, used in view subquery detection */ /* point on lex in which it was created, used in view subquery detection */
st_lex *parent_lex; st_lex *parent_lex;
enum olap_type olap; enum olap_type olap;
......
...@@ -1862,6 +1862,96 @@ void mysql_stmt_prepare(THD *thd, const char *packet, uint packet_length) ...@@ -1862,6 +1862,96 @@ void mysql_stmt_prepare(THD *thd, const char *packet, uint packet_length)
{ {
/* Statement map deletes statement on erase */ /* Statement map deletes statement on erase */
thd->stmt_map.erase(stmt); thd->stmt_map.erase(stmt);
} }
else else
mysql_log.write(thd, COM_STMT_PREPARE, "[%lu] %s", stmt->id, packet); mysql_log.write(thd, COM_STMT_PREPARE, "[%lu] %s", stmt->id, packet);
...@@ -1955,11 +2045,14 @@ static const char *get_dynamic_sql_string(LEX *lex, uint *query_len) ...@@ -1955,11 +2045,14 @@ static const char *get_dynamic_sql_string(LEX *lex, uint *query_len)
} }
else else
{ {
query_str= lex->prepared_stmt_code.str; stmt->setup_set_params();
*query_len= lex->prepared_stmt_code.length; SELECT_LEX *sl= stmt->lex->all_selects_list;
} for (; sl; sl= sl->next_select_in_list())
end: {
return query_str; /*
during query optimisation.
*/
sl->prep_where= sl->where;
} }
...@@ -2066,13 +2159,18 @@ void reinit_stmt_before_use(THD *thd, LEX *lex) ...@@ -2066,13 +2159,18 @@ void reinit_stmt_before_use(THD *thd, LEX *lex)
sl->exclude_from_table_unique_test= FALSE; sl->exclude_from_table_unique_test= FALSE;
/* /*
Copy WHERE clause pointers to avoid damaging they by optimisation Copy WHERE, HAVING clause pointers to avoid damaging them by optimisation
*/ */
if (sl->prep_where) if (sl->prep_where)
{ {
sl->where= sl->prep_where->copy_andor_structure(thd); sl->where= sl->prep_where->copy_andor_structure(thd);
sl->where->cleanup(); sl->where->cleanup();
} }
if (sl->prep_having)
{
sl->having= sl->prep_having->copy_andor_structure(thd);
sl->having->cleanup();
}
DBUG_ASSERT(sl->join == 0); DBUG_ASSERT(sl->join == 0);
ORDER *order; ORDER *order;
/* Fix GROUP list */ /* Fix GROUP list */
......
...@@ -612,6 +612,7 @@ JOIN::optimize() ...@@ -612,6 +612,7 @@ JOIN::optimize()
build_bitmap_for_nested_joins(join_list, 0); build_bitmap_for_nested_joins(join_list, 0);
sel->prep_where= conds ? conds->copy_andor_structure(thd) : 0; sel->prep_where= conds ? conds->copy_andor_structure(thd) : 0;
sel->prep_having= having ? having->copy_andor_structure(thd) : 0;
if (arena) if (arena)
thd->restore_active_arena(arena, &backup); thd->restore_active_arena(arena, &backup);
...@@ -625,14 +626,27 @@ JOIN::optimize() ...@@ -625,14 +626,27 @@ JOIN::optimize()
DBUG_RETURN(1); DBUG_RETURN(1);
} }
if (cond_value == Item::COND_FALSE || {
Item::cond_result having_value;
having= optimize_cond(thd, having, &having_value);
if (thd->net.report_error)
{
error= 1;
DBUG_PRINT("error",("Error from optimize_cond"));
DBUG_RETURN(1);
}
if (cond_value == Item::COND_FALSE || having_value == Item::COND_FALSE ||
(!unit->select_limit_cnt && !(select_options & OPTION_FOUND_ROWS))) (!unit->select_limit_cnt && !(select_options & OPTION_FOUND_ROWS)))
{ /* Impossible cond */ { /* Impossible cond */
DBUG_PRINT("info", ("Impossible WHERE")); DBUG_PRINT("info", (having_value == Item::COND_FALSE ?
zero_result_cause= "Impossible WHERE"; "Impossible HAVING" : "Impossible WHERE"));
zero_result_cause= ?
"Impossible HAVING" : "Impossible WHERE";
error= 0; error= 0;
DBUG_RETURN(0); DBUG_RETURN(0);
} }
}
/* Optimize count(*), min() and max() */ /* Optimize count(*), min() and max() */
if (tables_list && tmp_table_param.sum_func_count && ! group_list) if (tables_list && tmp_table_param.sum_func_count && ! group_list)
......
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