Bug #120288 Window function logic mismatch in indexed `NOT IN`
Submitted: 19 Apr 14:29 Modified: 20 Apr 8:04
Reporter: QiFan Liu Email Updates:
Status: Verified Impact on me:
None 
Category:MySQL Server: Optimizer Severity:S2 (Serious)
Version:8.0.45 OS:Linux (Observed on Linux via the `mysql:9.6` )
Assigned to: CPU Architecture:Any
Tags: cte, INDEX, window function, wrong-result

[19 Apr 14:29] QiFan Liu
Description:
MySQL returns inconsistent results for two logically equivalent forms of the same predicate when the only intended difference is index usage versus forced table scan. In the reproduced case, the indexed path returns `4` qualifying rows while the `IGNORE INDEX` path returns `0`.

How to repeat:
DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (
  c1 BIT,
  c2 BIT NOT NULL,
  UNIQUE KEY uq_c2_c1 (c2, c1)
);

INSERT INTO t1 (c1, c2) VALUES
  (NULL, b'0'),
  (NULL, b'1'),
  (b'0', b'0'),
  (b'0', b'1');

WITH wf_outer AS (
  SELECT
    base.c1,
    base.c2,
    ROW_NUMBER() OVER w_main AS wf_rn,
    LAG(base.c2, 1, NULL) OVER w_main AS prev_c2
  FROM t1 AS base
  WINDOW w_main AS (PARTITION BY base.c2 ORDER BY base.c1)
)
SELECT JSON_OBJECT(
  'with_index_count',
  (
    SELECT COUNT(*)
    FROM wf_outer AS o
    WHERE o.wf_rn >= 1
      AND INET_NTOA('2016-12-24 09:00:00') NOT IN (SELECT c2 FROM t1)
  ),
  'full_scan_count',
  (
    SELECT COUNT(*)
    FROM wf_outer AS o
    WHERE o.wf_rn >= 1
      AND INET_NTOA('2016-12-24 09:00:00') NOT IN (
        SELECT c2 FROM t1 IGNORE INDEX (uq_c2_c1)
      )
  )
) AS observation;
[20 Apr 8:04] Roy Lyseng
Thank you for the bug report.
Verified as described.