diff options
author | Sergey Petrunya <psergey@askmonty.org> | 2015-01-25 16:16:25 +0100 |
---|---|---|
committer | Sergey Petrunya <psergey@askmonty.org> | 2015-01-25 16:16:25 +0100 |
commit | fb71449b10100e9a0f887b1585000fbfab294f3c (patch) | |
tree | 4af39c47d7a291b60721f6468648f49af0f5d85d | |
parent | d1c4ff2b2cd54886087b6b879a6ea23f66d6582f (diff) | |
download | mariadb-git-fb71449b10100e9a0f887b1585000fbfab294f3c.tar.gz |
MDEV-5719: Wrong result with GROUP BY and LEFT OUTER JOINmariadb-10.0.16
Merged revision 5224 from mysql-5.6 and added a test case.
..
revno: 5224
committer: Sergey Glukhov <sergey.glukhov@oracle.com>
branch nick: mysql-5.6
timestamp: Wed 2013-06-19 14:24:08 +0400
message:
Bug#16620047 INCORRECT QUERY RESULT (AFTER SERVER UPGRADE)
-rw-r--r-- | mysql-test/r/group_by_innodb.result | 23 | ||||
-rw-r--r-- | mysql-test/t/group_by_innodb.test | 19 | ||||
-rw-r--r-- | sql/field.h | 23 |
3 files changed, 57 insertions, 8 deletions
diff --git a/mysql-test/r/group_by_innodb.result b/mysql-test/r/group_by_innodb.result index 4b5d9990c51..1098579a82d 100644 --- a/mysql-test/r/group_by_innodb.result +++ b/mysql-test/r/group_by_innodb.result @@ -57,3 +57,26 @@ i GROUP_CONCAT( d1, d2 ORDER BY d1, d2 ) NULL 11.1,22.2 DROP TABLE t1; End of 5.5 tests +# +# MDEV-5719: Wrong result with GROUP BY and LEFT OUTER JOIN +# +CREATE TABLE t1 (oidGroup INT, oid INT PRIMARY KEY)ENGINE=INNODB; +INSERT INTO t1 VALUES (1,1),(1,2),(1,3),(1,4); +CREATE TABLE t2 (oid INT PRIMARY KEY)ENGINE=INNODB; +INSERT INTO t2 VALUES (3); +SELECT a.oidGroup, a.oid, b.oid FROM t1 a LEFT JOIN t2 b ON +a.oid=b.oid WHERE a.oidGroup=1; +oidGroup oid oid +1 1 NULL +1 2 NULL +1 3 3 +1 4 NULL +SELECT a.oidGroup, a.oid, b.oid FROM t1 a LEFT JOIN t2 b ON +a.oid=b.oid WHERE a.oidGroup=1 GROUP BY a.oid; +oidGroup oid oid +1 1 NULL +1 2 NULL +1 3 3 +1 4 NULL +DROP TABLE t1, t2; +# End of tests diff --git a/mysql-test/t/group_by_innodb.test b/mysql-test/t/group_by_innodb.test index df213cc189f..75ee3d0802a 100644 --- a/mysql-test/t/group_by_innodb.test +++ b/mysql-test/t/group_by_innodb.test @@ -67,3 +67,22 @@ DROP TABLE t1; --echo End of 5.5 tests +--echo # +--echo # MDEV-5719: Wrong result with GROUP BY and LEFT OUTER JOIN +--echo # +CREATE TABLE t1 (oidGroup INT, oid INT PRIMARY KEY)ENGINE=INNODB; +INSERT INTO t1 VALUES (1,1),(1,2),(1,3),(1,4); + +CREATE TABLE t2 (oid INT PRIMARY KEY)ENGINE=INNODB; +INSERT INTO t2 VALUES (3); + +# Returns a value +SELECT a.oidGroup, a.oid, b.oid FROM t1 a LEFT JOIN t2 b ON +a.oid=b.oid WHERE a.oidGroup=1; + +SELECT a.oidGroup, a.oid, b.oid FROM t1 a LEFT JOIN t2 b ON +a.oid=b.oid WHERE a.oidGroup=1 GROUP BY a.oid; + +DROP TABLE t1, t2; + +--echo # End of tests diff --git a/sql/field.h b/sql/field.h index dd603d41bf7..0390e95f954 100644 --- a/sql/field.h +++ b/sql/field.h @@ -656,21 +656,28 @@ public: inline bool is_null(my_ptrdiff_t row_offset= 0) const { /* + If the field is NULLable, it returns NULLity based + on null_ptr[row_offset] value. Otherwise it returns + NULL flag depending on TABLE::null_row value. + The table may have been marked as containing only NULL values for all fields if it is a NULL-complemented row of an OUTER JOIN or if the query is an implicitly grouped query (has aggregate functions but no GROUP BY clause) with no qualifying rows. If - this is the case (in which TABLE::null_row is true), the field - is considered to be NULL. + this is the case (in which TABLE::null_row is true) and the + field is not nullable, the field is considered to be NULL. + + Do not change the order of testing. Fields may be associated + with a TABLE object without being part of the current row. + For NULL value check to work for these fields, they must + have a valid null_ptr, and this pointer must be checked before + TABLE::null_row. + Note that if a table->null_row is set then also all null_bits are set for the row. - - Otherwise, if the field is NULLable, it has a valid null_ptr - pointer, and its NULLity is recorded in the "null_bit" bit of - null_ptr[row_offset]. */ - return (table->null_row ? TRUE : - null_ptr ? MY_TEST(null_ptr[row_offset] & null_bit) : 0); + return real_maybe_null() ? + MY_TEST(null_ptr[row_offset] & null_bit) : table->null_row; } inline bool is_real_null(my_ptrdiff_t row_offset= 0) const { return null_ptr ? (null_ptr[row_offset] & null_bit ? 1 : 0) : 0; } |