Commit e2433cbc authored by unknown's avatar unknown

Bug #30715: Assertion failed: item_field->field->real_maybe_null(),

  file .\opt_sum.cc, line
The optimizer pre-calculates the MIN/MAX values for queries like
 SELECT MIN(kp_k) WHERE kp_1 = const AND ... AND kp_k-1 = const
when there is a key over kp_1...kp_k
In doing so it was not checking correctly nullability and 
there was a superfluous assert(). 
Fixed by making sure that the field can be null before checking and
taking out the wrong assert().
.
Introduced a correct check for nullability 
The MIN(field) can return NULL when all the row values in the group
are NULL-able or if there were no rows.
Fixed the assertion to reflect the case when there are no rows.


mysql-test/r/func_group.result:
  Bug #30715: test case
mysql-test/t/func_group.test:
  Bug #30715: test case
sql/opt_sum.cc:
  Bug #30715: correct nullability check for MIN/MAX pre-calculation over index.
parent 62a7e160
...@@ -1387,4 +1387,9 @@ SELECT 1 FROM t1 GROUP BY (SELECT SLEEP(0) FROM t1 ORDER BY AVG(DISTINCT a) ); ...@@ -1387,4 +1387,9 @@ SELECT 1 FROM t1 GROUP BY (SELECT SLEEP(0) FROM t1 ORDER BY AVG(DISTINCT a) );
1 1
1 1
DROP TABLE t1; DROP TABLE t1;
CREATE TABLE t1 (a int, b date NOT NULL, KEY k1 (a,b));
SELECT MIN(b) FROM t1 WHERE a=1 AND b>'2007-08-01';
MIN(b)
NULL
DROP TABLE t1;
End of 5.0 tests End of 5.0 tests
...@@ -873,5 +873,14 @@ SELECT 1 FROM t1 GROUP BY (SELECT SLEEP(0) FROM t1 ORDER BY AVG(DISTINCT a) ); ...@@ -873,5 +873,14 @@ SELECT 1 FROM t1 GROUP BY (SELECT SLEEP(0) FROM t1 ORDER BY AVG(DISTINCT a) );
DROP TABLE t1; DROP TABLE t1;
#
# Bug #30715: Assertion failed: item_field->field->real_maybe_null(), file
# .\opt_sum.cc, line
#
CREATE TABLE t1 (a int, b date NOT NULL, KEY k1 (a,b));
SELECT MIN(b) FROM t1 WHERE a=1 AND b>'2007-08-01';
DROP TABLE t1;
### ###
--echo End of 5.0 tests --echo End of 5.0 tests
...@@ -249,20 +249,20 @@ int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds) ...@@ -249,20 +249,20 @@ int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds)
Check if case 1 from above holds. If it does, we should read Check if case 1 from above holds. If it does, we should read
the skipped tuple. the skipped tuple.
*/ */
if (ref.key_buff[prefix_len] == 1 && if (item_field->field->real_maybe_null() &&
/* ref.key_buff[prefix_len] == 1 &&
/*
Last keypart (i.e. the argument to MIN) is set to NULL by Last keypart (i.e. the argument to MIN) is set to NULL by
find_key_for_maxmin only if all other keyparts are bound find_key_for_maxmin only if all other keyparts are bound
to constants in a conjunction of equalities. Hence, we to constants in a conjunction of equalities. Hence, we
can detect this by checking only if the last keypart is can detect this by checking only if the last keypart is
NULL. NULL.
*/ */
(error == HA_ERR_KEY_NOT_FOUND || (error == HA_ERR_KEY_NOT_FOUND ||
key_cmp_if_same(table, ref.key_buff, ref.key, prefix_len))) key_cmp_if_same(table, ref.key_buff, ref.key, prefix_len)))
{ {
DBUG_ASSERT(item_field->field->real_maybe_null());
error= table->file->index_read(table->record[0], ref.key_buff, error= table->file->index_read(table->record[0], ref.key_buff,
ref.key_length, ref.key_length,
HA_READ_KEY_EXACT); HA_READ_KEY_EXACT);
} }
} }
......
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