diff options
-rw-r--r-- | client/mysqltest.cc | 45 | ||||
-rw-r--r-- | mysql-test/r/fulltext.result | 2 | ||||
-rw-r--r-- | mysql-test/r/func_group_innodb.result | 13 | ||||
-rw-r--r-- | mysql-test/r/group_by.result | 82 | ||||
-rw-r--r-- | mysql-test/r/join_outer.result | 24 | ||||
-rw-r--r-- | mysql-test/r/join_outer_jcl6.result | 24 | ||||
-rw-r--r-- | mysql-test/r/log_state.result | 28 | ||||
-rw-r--r-- | mysql-test/t/func_group_innodb.test | 14 | ||||
-rw-r--r-- | mysql-test/t/group_by.test | 75 | ||||
-rw-r--r-- | mysql-test/t/join_outer.test | 19 | ||||
-rw-r--r-- | mysql-test/t/log_state.test | 14 | ||||
-rw-r--r-- | sql/item_cmpfunc.h | 2 | ||||
-rw-r--r-- | sql/opt_range.cc | 2 | ||||
-rw-r--r-- | sql/opt_sum.cc | 4 | ||||
-rw-r--r-- | sql/sql_select.cc | 27 |
15 files changed, 342 insertions, 33 deletions
diff --git a/client/mysqltest.cc b/client/mysqltest.cc index 77fbbb1757e..612a4885303 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -743,6 +743,9 @@ void handle_error(struct st_command*, const char *err_sqlstate, DYNAMIC_STRING *ds); void handle_no_error(struct st_command*); +static void handle_no_active_connection(struct st_command* command, + struct st_connection *cn, DYNAMIC_STRING *ds); + #ifdef EMBEDDED_LIBRARY /* workaround for MySQL BUG#57491 */ @@ -2291,6 +2294,19 @@ void var_query_set(VAR *var, const char *query, const char** query_end) DBUG_ENTER("var_query_set"); LINT_INIT(res); + if (!mysql) + { + struct st_command command; + memset(&command, 0, sizeof(command)); + command.query= (char*)query; + command.first_word_len= (*query_end - query); + command.first_argument= command.query + command.first_word_len; + command.end= (char*)*query_end; + command.abort_on_error= 1; /* avoid uninitialized variables */ + handle_no_active_connection(&command, cur_con, &ds_res); + DBUG_VOID_RETURN; + } + /* Only white space or ) allowed past ending ` */ while (end > query && *end != '`') { @@ -2396,6 +2412,12 @@ void var_set_query_get_value(struct st_command *command, VAR *var) DBUG_ENTER("var_set_query_get_value"); LINT_INIT(res); + if (!mysql) + { + handle_no_active_connection(command, cur_con, &ds_res); + DBUG_VOID_RETURN; + } + strip_parentheses(command); DBUG_PRINT("info", ("query: %s", command->query)); check_command_args(command, command->first_argument, query_get_value_args, @@ -2554,6 +2576,7 @@ void eval_expr(VAR *v, const char *p, const char **p_end, bool do_eval) command.first_word_len= len; command.first_argument= command.query + len; command.end= (char*)*p_end; + command.abort_on_error= 1; /* avoid uninitialized variables */ var_set_query_get_value(&command, v); DBUG_VOID_RETURN; } @@ -6950,6 +6973,22 @@ int append_warnings(DYNAMIC_STRING *ds, MYSQL* mysql) /* + Handle situation where query is sent but there is no active connection + (e.g directly after disconnect). + + We emulate MySQL-compatible behaviour of sending something on a closed + connection. +*/ +static void handle_no_active_connection(struct st_command *command, + struct st_connection *cn, DYNAMIC_STRING *ds) +{ + handle_error(command, 2006, "MySQL server has gone away", "000000", ds); + cn->pending= FALSE; + var_set_errno(2006); +} + + +/* Run query using MySQL C API SYNOPSIS @@ -6975,11 +7014,7 @@ void run_query_normal(struct st_connection *cn, struct st_command *command, if (!mysql) { - /* Emulate old behaviour of sending something on a closed connection */ - handle_error(command, 2006, "MySQL server has gone away", - "000000", ds); - cn->pending= FALSE; - var_set_errno(2006); + handle_no_active_connection(command, cn, ds); DBUG_VOID_RETURN; } diff --git a/mysql-test/r/fulltext.result b/mysql-test/r/fulltext.result index 5374d856343..33ec3d1f39c 100644 --- a/mysql-test/r/fulltext.result +++ b/mysql-test/r/fulltext.result @@ -684,8 +684,10 @@ PREPARE stmt FROM WHERE t1.f1 GROUP BY t1.f1))'; EXECUTE stmt; 1 +1 EXECUTE stmt; 1 +1 DEALLOCATE PREPARE stmt; DROP TABLE t1; End of 5.1 tests diff --git a/mysql-test/r/func_group_innodb.result b/mysql-test/r/func_group_innodb.result index 11d8e390f1d..c69bbe58953 100644 --- a/mysql-test/r/func_group_innodb.result +++ b/mysql-test/r/func_group_innodb.result @@ -145,3 +145,16 @@ select count(*), min(7), max(7) from t2m, t1i; count(*) min(7) max(7) 0 NULL NULL drop table t1m, t1i, t2m, t2i; +# +# Bug#13723054 CRASH WITH MIN/MAX AFTER QUICK_GROUP_MIN_MAX_SELECT::NEXT_MIN +# +CREATE TABLE t1(a BLOB, b VARCHAR(255) CHARSET LATIN1, c INT, +KEY(b, c, a(765))) ENGINE=INNODB; +INSERT INTO t1(a, b, c) VALUES ('', 'a', 0), ('', 'a', null), ('', 'a', 0); +SELECT MIN(c) FROM t1 GROUP BY b; +MIN(c) +0 +EXPLAIN SELECT MIN(c) FROM t1 GROUP BY b; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range NULL b 263 NULL 4 Using index for group-by +DROP TABLE t1; diff --git a/mysql-test/r/group_by.result b/mysql-test/r/group_by.result index b98c19c3857..68ddcd39e92 100644 --- a/mysql-test/r/group_by.result +++ b/mysql-test/r/group_by.result @@ -2013,8 +2013,88 @@ zzz 3 4 8 -#TODO: in merge with 5.3 add original test suite +SET @save_optimizer_switch967242=@@optimizer_switch; +SET optimizer_switch = 'in_to_exists=on'; +SELECT t2_1.b +FROM t1 JOIN t2 AS t2_1 JOIN t2 AS t2_2 +ON (t2_2.b = t2_1.b ) AND (t2_2.c = t2_1.c ) +WHERE +( SELECT COUNT(*) FROM t2 ) IS NOT NULL +OR a = t2_1.c +GROUP BY t2_1.b; +b +0 +3 +4 +8 +SET optimizer_switch=@save_optimizer_switch967242; drop table t1, t2; +# +# Bug#12578908: SELECT SQL_BUFFER_RESULT OUTPUTS TOO MANY +# ROWS WHEN GROUP IS OPTIMIZED AWAY +# +CREATE TABLE t1 (col1 int, col2 int) ; +INSERT INTO t1 VALUES (10,1),(11,7); +CREATE TABLE t2 (col1 int, col2 int) ; +INSERT INTO t2 VALUES (10,8); + +EXPLAIN SELECT SQL_BUFFER_RESULT t2.col2 FROM t2 JOIN t1 ON t1.col1 GROUP BY t2.col2; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 system NULL NULL NULL NULL 1 Using temporary +1 SIMPLE t1 ALL NULL NULL NULL NULL 2 Using where +SELECT SQL_BUFFER_RESULT t2.col2 FROM t2 JOIN t1 ON t1.col1 GROUP BY t2.col2; +col2 +8 + +EXPLAIN SELECT t2.col2 FROM t2 JOIN t1 ON t1.col1 GROUP BY t2.col2; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 system NULL NULL NULL NULL 1 +1 SIMPLE t1 ALL NULL NULL NULL NULL 2 Using where +SELECT t2.col2 FROM t2 JOIN t1 ON t1.col1 GROUP BY t2.col2; +col2 +8 + +DROP TABLE t1,t2; +# +# BUG#12640437: USING SQL_BUFFER_RESULT RESULTS IN A +# DIFFERENT QUERY OUTPUT +# +CREATE TABLE t1 ( +a int, +b varchar(1), +KEY (b,a) +); +INSERT INTO t1 VALUES (1,NULL),(0,'a'); + +EXPLAIN SELECT SQL_BUFFER_RESULT MIN(a), b FROM t1 WHERE t1.b = 'a' GROUP BY b; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range b b 9 NULL 2 Using where; Using index for group-by; Using temporary + +SELECT SQL_BUFFER_RESULT MIN(a), b FROM t1 WHERE t1.b = 'a' GROUP BY b; +MIN(a) b +0 a + +EXPLAIN SELECT MIN(a), b FROM t1 WHERE t1.b = 'a' GROUP BY b; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range b b 9 NULL 2 Using where; Using index for group-by + +SELECT MIN(a), b FROM t1 WHERE t1.b = 'a' GROUP BY b; +MIN(a) b +0 a + +DROP TABLE t1; +# +# LP bug#993726 Wrong result from a query with ALL subquery predicate in WHERE +# +CREATE TABLE t1(a INT); +INSERT INTO t1 VALUES (0); +SELECT 1 FROM t1 WHERE 1 > ALL(SELECT 1 FROM t1 WHERE a!=0); +1 +1 +SELECT max(1) FROM t1 WHERE a!=0; +max(1) +NULL +drop table t1; # End of 5.2 tests # # BUG#872702: Crash in add_ref_to_table_cond() when grouping by a PK diff --git a/mysql-test/r/join_outer.result b/mysql-test/r/join_outer.result index 163a3cb2656..45aaa0b7a8e 100644 --- a/mysql-test/r/join_outer.result +++ b/mysql-test/r/join_outer.result @@ -1606,6 +1606,30 @@ f DROP TABLE t1; End of 5.1 tests # +# LP BUG#994392: Wrong result with RIGHT/LEFT JOIN and ALL subquery +# predicate in WHERE condition. +# +CREATE TABLE t1(a INT); +INSERT INTO t1 VALUES(9); +CREATE TABLE t2(b INT); +INSERT INTO t2 VALUES(8); +CREATE TABLE t3(c INT); +INSERT INTO t3 VALUES(3); +SELECT * FROM t2 RIGHT JOIN t3 ON(c = b) WHERE b < ALL(SELECT a FROM t1 WHERE a <= 7); +b c +NULL 3 +SELECT * FROM t3 LEFT JOIN t2 ON(c = b) WHERE b < ALL(SELECT a FROM t1 WHERE a <= 7); +c b +3 NULL +SELECT * FROM t2 RIGHT JOIN t3 ON(c = b) WHERE b not in (SELECT a FROM t1 WHERE a <= 7); +b c +NULL 3 +SELECT * FROM t3 LEFT JOIN t2 ON(c = b) WHERE b not in (SELECT a FROM t1 WHERE a <= 7); +c b +3 NULL +drop table t1,t2,t3; +End of 5.2 tests +# # LP bug #813447: LEFT JOIN with single-row inner table and # a subquery in ON expression # diff --git a/mysql-test/r/join_outer_jcl6.result b/mysql-test/r/join_outer_jcl6.result index de58c9eb790..441e8dd574f 100644 --- a/mysql-test/r/join_outer_jcl6.result +++ b/mysql-test/r/join_outer_jcl6.result @@ -1617,6 +1617,30 @@ f DROP TABLE t1; End of 5.1 tests # +# LP BUG#994392: Wrong result with RIGHT/LEFT JOIN and ALL subquery +# predicate in WHERE condition. +# +CREATE TABLE t1(a INT); +INSERT INTO t1 VALUES(9); +CREATE TABLE t2(b INT); +INSERT INTO t2 VALUES(8); +CREATE TABLE t3(c INT); +INSERT INTO t3 VALUES(3); +SELECT * FROM t2 RIGHT JOIN t3 ON(c = b) WHERE b < ALL(SELECT a FROM t1 WHERE a <= 7); +b c +NULL 3 +SELECT * FROM t3 LEFT JOIN t2 ON(c = b) WHERE b < ALL(SELECT a FROM t1 WHERE a <= 7); +c b +3 NULL +SELECT * FROM t2 RIGHT JOIN t3 ON(c = b) WHERE b not in (SELECT a FROM t1 WHERE a <= 7); +b c +NULL 3 +SELECT * FROM t3 LEFT JOIN t2 ON(c = b) WHERE b not in (SELECT a FROM t1 WHERE a <= 7); +c b +3 NULL +drop table t1,t2,t3; +End of 5.2 tests +# # LP bug #813447: LEFT JOIN with single-row inner table and # a subquery in ON expression # diff --git a/mysql-test/r/log_state.result b/mysql-test/r/log_state.result index 6987ab94d74..597840c780e 100644 --- a/mysql-test/r/log_state.result +++ b/mysql-test/r/log_state.result @@ -320,22 +320,22 @@ TRUNCATE TABLE mysql.slow_log; CREATE TABLE t1 (a INT); CREATE TABLE t2 (b INT, PRIMARY KEY (b)); INSERT INTO t2 VALUES (3),(4); -INSERT INTO t1 VALUES (1+sleep(.01)),(2); -INSERT INTO t1 SELECT b+sleep(.01) from t2; -UPDATE t1 SET a=a+sleep(.01) WHERE a>2; -UPDATE t1 SET a=a+sleep(.01) ORDER BY a DESC; -UPDATE t2 set b=b+sleep(.01) limit 1; -UPDATE t1 SET a=a+sleep(.01) WHERE a in (SELECT b from t2); -DELETE FROM t1 WHERE a=a+sleep(.01) ORDER BY a LIMIT 2; +INSERT INTO t1 VALUES (1+sleep(.02)),(2); +INSERT INTO t1 SELECT b+sleep(.02) from t2; +UPDATE t1 SET a=a+sleep(.02) WHERE a>2; +UPDATE t1 SET a=a+sleep(.02) ORDER BY a DESC; +UPDATE t2 set b=b+sleep(.02) limit 1; +UPDATE t1 SET a=a+sleep(.02) WHERE a in (SELECT b from t2); +DELETE FROM t1 WHERE a=a+sleep(.02) ORDER BY a LIMIT 2; SELECT rows_examined,sql_text FROM mysql.slow_log; rows_examined sql_text -0 INSERT INTO t1 VALUES (1+sleep(.01)),(2) -2 INSERT INTO t1 SELECT b+sleep(.01) from t2 -4 UPDATE t1 SET a=a+sleep(.01) WHERE a>2 -8 UPDATE t1 SET a=a+sleep(.01) ORDER BY a DESC -2 UPDATE t2 set b=b+sleep(.01) limit 1 -4 UPDATE t1 SET a=a+sleep(.01) WHERE a in (SELECT b from t2) -6 DELETE FROM t1 WHERE a=a+sleep(.01) ORDER BY a LIMIT 2 +0 INSERT INTO t1 VALUES (1+sleep(.02)),(2) +2 INSERT INTO t1 SELECT b+sleep(.02) from t2 +4 UPDATE t1 SET a=a+sleep(.02) WHERE a>2 +8 UPDATE t1 SET a=a+sleep(.02) ORDER BY a DESC +2 UPDATE t2 set b=b+sleep(.02) limit 1 +4 UPDATE t1 SET a=a+sleep(.02) WHERE a in (SELECT b from t2) +6 DELETE FROM t1 WHERE a=a+sleep(.02) ORDER BY a LIMIT 2 DROP TABLE t1,t2; TRUNCATE TABLE mysql.slow_log; # end of bug#49756 diff --git a/mysql-test/t/func_group_innodb.test b/mysql-test/t/func_group_innodb.test index 1bdfd8f54bb..9e88894de58 100644 --- a/mysql-test/t/func_group_innodb.test +++ b/mysql-test/t/func_group_innodb.test @@ -83,3 +83,17 @@ explain select count(*), min(7), max(7) from t2m, t1i; select count(*), min(7), max(7) from t2m, t1i; drop table t1m, t1i, t2m, t2i; + + +--echo # +--echo # Bug#13723054 CRASH WITH MIN/MAX AFTER QUICK_GROUP_MIN_MAX_SELECT::NEXT_MIN +--echo # + +CREATE TABLE t1(a BLOB, b VARCHAR(255) CHARSET LATIN1, c INT, + KEY(b, c, a(765))) ENGINE=INNODB; +INSERT INTO t1(a, b, c) VALUES ('', 'a', 0), ('', 'a', null), ('', 'a', 0); + +SELECT MIN(c) FROM t1 GROUP BY b; +EXPLAIN SELECT MIN(c) FROM t1 GROUP BY b; + +DROP TABLE t1; diff --git a/mysql-test/t/group_by.test b/mysql-test/t/group_by.test index f9e8e671063..d4214442709 100644 --- a/mysql-test/t/group_by.test +++ b/mysql-test/t/group_by.test @@ -1377,10 +1377,82 @@ t2_1.b + 1 > 0 OR a = t2_1.c GROUP BY zzz; ---echo #TODO: in merge with 5.3 add original test suite +SET @save_optimizer_switch967242=@@optimizer_switch; +SET optimizer_switch = 'in_to_exists=on'; + +SELECT t2_1.b +FROM t1 JOIN t2 AS t2_1 JOIN t2 AS t2_2 + ON (t2_2.b = t2_1.b ) AND (t2_2.c = t2_1.c ) +WHERE + ( SELECT COUNT(*) FROM t2 ) IS NOT NULL + OR a = t2_1.c +GROUP BY t2_1.b; +SET optimizer_switch=@save_optimizer_switch967242; drop table t1, t2; +--echo # +--echo # Bug#12578908: SELECT SQL_BUFFER_RESULT OUTPUTS TOO MANY +--echo # ROWS WHEN GROUP IS OPTIMIZED AWAY +--echo # + +CREATE TABLE t1 (col1 int, col2 int) ; +INSERT INTO t1 VALUES (10,1),(11,7); + +CREATE TABLE t2 (col1 int, col2 int) ; +INSERT INTO t2 VALUES (10,8); + +let $q_body=t2.col2 FROM t2 JOIN t1 ON t1.col1 GROUP BY t2.col2; + +--echo +--eval EXPLAIN SELECT SQL_BUFFER_RESULT $q_body +--eval SELECT SQL_BUFFER_RESULT $q_body +--echo +--eval EXPLAIN SELECT $q_body +--eval SELECT $q_body + +--echo +DROP TABLE t1,t2; + +--echo # +--echo # BUG#12640437: USING SQL_BUFFER_RESULT RESULTS IN A +--echo # DIFFERENT QUERY OUTPUT +--echo # + +CREATE TABLE t1 ( + a int, + b varchar(1), + KEY (b,a) +); + +INSERT INTO t1 VALUES (1,NULL),(0,'a'); + +let $query= + SELECT SQL_BUFFER_RESULT MIN(a), b FROM t1 WHERE t1.b = 'a' GROUP BY b; + +--echo +--eval EXPLAIN $query +--echo +--eval $query + +let $query= SELECT MIN(a), b FROM t1 WHERE t1.b = 'a' GROUP BY b; +--echo +--eval EXPLAIN $query +--echo +--eval $query + +--echo +DROP TABLE t1; + +--echo # +--echo # LP bug#993726 Wrong result from a query with ALL subquery predicate in WHERE +--echo # +CREATE TABLE t1(a INT); +INSERT INTO t1 VALUES (0); +SELECT 1 FROM t1 WHERE 1 > ALL(SELECT 1 FROM t1 WHERE a!=0); +SELECT max(1) FROM t1 WHERE a!=0; +drop table t1; + --echo # End of 5.2 tests --echo # @@ -1401,4 +1473,3 @@ GROUP BY 1; DROP TABLE t1, t2; --echo # End of 5.3 tests - diff --git a/mysql-test/t/join_outer.test b/mysql-test/t/join_outer.test index 3b2ab662dd8..69c08cd54bd 100644 --- a/mysql-test/t/join_outer.test +++ b/mysql-test/t/join_outer.test @@ -1179,6 +1179,25 @@ DROP TABLE t1; --echo End of 5.1 tests --echo # +--echo # LP BUG#994392: Wrong result with RIGHT/LEFT JOIN and ALL subquery +--echo # predicate in WHERE condition. +--echo # + +CREATE TABLE t1(a INT); +INSERT INTO t1 VALUES(9); +CREATE TABLE t2(b INT); +INSERT INTO t2 VALUES(8); +CREATE TABLE t3(c INT); +INSERT INTO t3 VALUES(3); +SELECT * FROM t2 RIGHT JOIN t3 ON(c = b) WHERE b < ALL(SELECT a FROM t1 WHERE a <= 7); +SELECT * FROM t3 LEFT JOIN t2 ON(c = b) WHERE b < ALL(SELECT a FROM t1 WHERE a <= 7); +SELECT * FROM t2 RIGHT JOIN t3 ON(c = b) WHERE b not in (SELECT a FROM t1 WHERE a <= 7); +SELECT * FROM t3 LEFT JOIN t2 ON(c = b) WHERE b not in (SELECT a FROM t1 WHERE a <= 7); +drop table t1,t2,t3; + +--echo End of 5.2 tests + +--echo # --echo # LP bug #813447: LEFT JOIN with single-row inner table and --echo # a subquery in ON expression --echo # diff --git a/mysql-test/t/log_state.test b/mysql-test/t/log_state.test index 05e17dc9fa7..032c46e83b6 100644 --- a/mysql-test/t/log_state.test +++ b/mysql-test/t/log_state.test @@ -381,13 +381,13 @@ CREATE TABLE t2 (b INT, PRIMARY KEY (b)); INSERT INTO t2 VALUES (3),(4); connect (con2,localhost,root,,); -INSERT INTO t1 VALUES (1+sleep(.01)),(2); -INSERT INTO t1 SELECT b+sleep(.01) from t2; -UPDATE t1 SET a=a+sleep(.01) WHERE a>2; -UPDATE t1 SET a=a+sleep(.01) ORDER BY a DESC; -UPDATE t2 set b=b+sleep(.01) limit 1; -UPDATE t1 SET a=a+sleep(.01) WHERE a in (SELECT b from t2); -DELETE FROM t1 WHERE a=a+sleep(.01) ORDER BY a LIMIT 2; +INSERT INTO t1 VALUES (1+sleep(.02)),(2); +INSERT INTO t1 SELECT b+sleep(.02) from t2; +UPDATE t1 SET a=a+sleep(.02) WHERE a>2; +UPDATE t1 SET a=a+sleep(.02) ORDER BY a DESC; +UPDATE t2 set b=b+sleep(.02) limit 1; +UPDATE t1 SET a=a+sleep(.02) WHERE a in (SELECT b from t2); +DELETE FROM t1 WHERE a=a+sleep(.02) ORDER BY a LIMIT 2; SELECT rows_examined,sql_text FROM mysql.slow_log; disconnect con2; diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index 189b83b7efc..45a0976fae1 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -247,6 +247,7 @@ public: {} bool fix_fields(THD *, Item **); bool fix_left(THD *thd, Item **ref); + table_map not_null_tables() const { return 0; } bool is_null(); longlong val_int(); void cleanup(); @@ -498,6 +499,7 @@ public: {} virtual void top_level_item() { abort_on_null= 1; } bool is_top_level_item() { return abort_on_null; } + table_map not_null_tables() const { return 0; } longlong val_int(); enum Functype functype() const { return NOT_ALL_FUNC; } const char *func_name() const { return "<not>"; } diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 4b973b8500e..4ffe184ca03 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -13121,7 +13121,7 @@ int QUICK_GROUP_MIN_MAX_SELECT::next_min() if (min_max_arg_part && min_max_arg_part->field->is_null()) { /* Find the first subsequent record without NULL in the MIN/MAX field. */ - key_copy(tmp_record, record, index_info, 0); + key_copy(tmp_record, record, index_info, max_used_key_length); result= file->ha_index_read_map(record, tmp_record, make_keypart_map(real_key_parts), HA_READ_AFTER_KEY); diff --git a/sql/opt_sum.cc b/sql/opt_sum.cc index 9e097af1e6e..b6aca56f047 100644 --- a/sql/opt_sum.cc +++ b/sql/opt_sum.cc @@ -416,7 +416,7 @@ int opt_sum_query(THD *thd, } removed_tables|= table->map; } - else if (!expr->const_item() || !is_exact_count) + else if (!expr->const_item() || !is_exact_count || conds) { /* The optimization is not applicable in both cases: @@ -426,6 +426,8 @@ int opt_sum_query(THD *thd, NULL if the query does not return any rows. Thus, if we are not able to determine if the query returns any rows, we can't apply the optimization and replace MIN/MAX with a constant. + (c) there is a WHERE clause. The WHERE conditions may result in + an empty result, but the clause cannot be taken into account here. */ const_result= 0; break; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index fccd94ec3cd..50d1ffbb19c 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -1487,7 +1487,6 @@ JOIN::optimize() simple_order=1; select_distinct= 0; // No need in distinct for 1 row group_optimized_away= 1; - implicit_grouping= TRUE; } calc_group_buffer(this, group_list); @@ -7880,7 +7879,31 @@ JOIN::make_simple_join(JOIN *parent, TABLE *temp_table) tmp_table_param.copy_field= tmp_table_param.copy_field_end=0; first_record= sort_and_group=0; send_records= (ha_rows) 0; - group= 0; + + if (group_optimized_away && !tmp_table_param.precomputed_group_by) + { + /* + If grouping has been optimized away, a temporary table is + normally not needed unless we're explicitly requested to create + one (e.g. due to a SQL_BUFFER_RESULT hint or INSERT ... SELECT). + + In this case (grouping was optimized away), temp_table was + created without a grouping expression and JOIN::exec() will not + perform the necessary grouping (by the use of end_send_group() + or end_write_group()) if JOIN::group is set to false. + + There is one exception: if the loose index scan access method is + used to read into the temporary table, grouping and aggregate + functions are handled. + */ + // the temporary table was explicitly requested + DBUG_ASSERT(test(select_options & OPTION_BUFFER_RESULT)); + // the temporary table does not have a grouping expression + DBUG_ASSERT(!temp_table->group); + } + else + group= false; + row_limit= unit->select_limit_cnt; do_send_rows= row_limit ? 1 : 0; |