[MDEV-31023] The phenomenon of inconsistent query results caused by null data values Created: 2023-04-07  Updated: 2023-07-28  Resolved: 2023-07-28

Status: Closed
Project: MariaDB Server
Component/s: None
Affects Version/s: 10.9.4
Fix Version/s: N/A

Type: Bug Priority: Major
Reporter: Chenglin Tian Assignee: Unassigned
Resolution: Incomplete Votes: 0
Labels: None
Environment:

Ubuntu 18.04.6 LTS (GNU/Linux 5.4.0-144-generic x86_64)



 Description   

Here is our table creation statement:

CREATE TABLE IF NOT EXISTS t0(c0 LONGTEXT) ;
CREATE TABLE IF NOT EXISTS t1 LIKE t0;
CREATE TABLE IF NOT EXISTS t2(c0 DECIMAL) ;
REPLACE INTO t0(c0) VALUES('j_{(~PAZ)');
INSERT INTO t0(c0) VALUES(NULL);
REPLACE INTO t0(c0) VALUES(NULL);
INSERT IGNORE INTO t0(c0) VALUES('');
REPLACE INTO t0(c0) VALUES(1373444939);
DELETE LOW_PRIORITY IGNORE FROM t0 WHERE t0.c0;
INSERT INTO t1(c0) VALUES(1257022825), (365137223), (NULL);
REPLACE LOW_PRIORITY INTO t1(c0) VALUES(-1836894879);
REPLACE INTO t0(c0) VALUES(NULL);
REPLACE INTO t1(c0) VALUES(NULL);
REPLACE INTO t2(c0) VALUES(960364164);
REPLACE LOW_PRIORITY INTO t1(c0) VALUES("");
INSERT IGNORE INTO t0(c0) VALUES(1318946640);
DELETE QUICK IGNORE FROM t0;
REPLACE LOW_PRIORITY INTO t1(c0) VALUES(NULL);
INSERT IGNORE INTO t0(c0) VALUES(NULL);
INSERT LOW_PRIORITY IGNORE INTO t0(c0) VALUES(2066070913);

This is the statement where we found inconsistencies:

SELECT ALL t2.c0 AS ref0 FROM t1, t2 RIGHT OUTER JOIN t0 ON EXISTS (SELECT 1 wHERE FALSE) WHERE ((t2.c0 IS FALSE) NOT IN (BIT_COUNT(t1.c0)));
 --expected:[null,null,null,null,null,null]
 --actual:empty set

Because the values of t2.c0 are all null, we replace t2.c0 with null in the inconsistent statement. Theoretically, the semantics are the same, but this statement can return a data list containing six nulls;

SELECT ALL t2.c0 AS ref0 FROM t1, t2 RIGHT OUTER JOIN t0 ON EXISTS (SELECT 1 wHERE FALSE) WHERE ((NULL IS FALSE) NOT IN (BIT_COUNT(t1.c0)));
--expected:[null,null,null,null,null,null]
 --actual:[null,null,null,null,null,null]

Subsequently, we used SQLancer's TLP method for validation and found that the two queries that were supposed to be equivalent had inconsistent results:

--SELECT ALL t2.c0 AS ref0 FROM t1, t2 RIGHT OUTER JOIN t0 ON EXISTS (SELECT 1 wHERE FALSE);
 --actual:[null,null,null,null,null,null,null,null,null,null,null,null,null,null]
 
SELECT ALL t2.c0 AS ref0 FROM t1, t2 RIGHT OUTER JOIN t0 ON EXISTS (SELECT 1 wHERE FALSE) WHERE ((t2.c0 IS FALSE) NOT IN (BIT_COUNT(t1.c0))) UNION ALL SELECT ALL t2.c0 AS ref0 FROM t1, t2 RIGHT OUTER JOIN t0 ON EXISTS(SELECT 1 wHERE FALSE) WHERE (NOT ((t2.c0 IS FALSE) NOT IN (BIT_COUNT(t1.c0)))) UNION ALL SELECT ALL t2.c0 AS ref0 FROM t1, t2 RIGHT OUTER JOIN t0 ON EXISTS(SELECT 1 wHERE FALSE) WHERE ((t2.c0 IS FALSE) NOT IN (BIT_COUNT(t1.c0))) is null;
 --actual:[null,null,null,null,null,null]

The results of the above two queries should be the same. The second query is that we added a condition to the first query and performed a UNION ALL operation on the true, false, and null results of this condition.



 Comments   
Comment by Sergei Golubchik [ 2023-06-27 ]

why do you think that "values of t2.c0 are all null" ?

select * from t2;
c0
960364164

Generated at Thu Feb 08 10:20:42 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.