From bfe88b7499589247c452e9f87d686183e5b96828 Mon Sep 17 00:00:00 2001 From: Jim Vanns Date: Sun, 1 Mar 2026 10:44:12 +0000 Subject: [PATCH 2/3] [PATCH 2/3] Extend existing BitmapOps test for SAOP This patch adds the test for planners choice of partial indexes for SAOP as part of the WHERE clause. - Minimal schema plus required partial indexes - Generates some fake data - Adds explicit values that are in the partial indexes - Runs 4x queries all functionally equivalent but semantically different Note the 4th run tests specifically the best index is chosen via the costings. diff --git a/src/test/regress/sql/bitmapops.sql b/src/test/regress/sql/bitmapops.sql index 1b175f6ff96..aec5fb5a625 100644 --- a/src/test/regress/sql/bitmapops.sql +++ b/src/test/regress/sql/bitmapops.sql @@ -45,3 +45,65 @@ SELECT count(*) FROM bmscantest WHERE a = 1 OR b = 1; -- clean up DROP TABLE bmscantest; + + +-- Test ScalarArrayOpExpr (SAOP) for partial indexes + +-- Generate enough data that we can test the use of an index +CREATE TABLE ipairs( + key INT, + value INT +) +WITH (autovacuum_enabled = false); +-- Install the partial index on these values +CREATE INDEX ipairs_key_idx1 ON ipairs(key) WHERE key = 507; +CREATE INDEX ipairs_key_idx2 ON ipairs(key) WHERE key = 508; +CREATE INDEX ipairs_key_idx3 ON ipairs(key) WHERE key = 509; +CREATE INDEX ipairs_key_idx4 ON ipairs(key) WHERE key <= 508; -- Give planner a choice + +-- Dummy data to surround ours +INSERT INTO ipairs(key, value) +SELECT n, -n +FROM generate_series(1, 1000) AS tmp(n); + +-- Update statistics +VACUUM (ANALYZE) ipairs; + +-- Our specific test data to force the partial index +EXPLAIN (ANALYZE, COSTS OFF, BUFFERS OFF, SUMMARY OFF, TIMING OFF) +UPDATE ipairs +SET value = 0 +WHERE key IN (507,508,509); + +-- We want ensure that an index use is always attempted - just for the test +SET enable_seqscan=false; + +-- Variant 1 (works without the SAOP optimiser patch) +EXPLAIN (COSTS OFF) +SELECT value = 0 +FROM ipairs +WHERE + key = 507 OR + key = 508 OR + key = 509; + +-- Variant 2 (works only with the SAOP optimiser patch) +EXPLAIN (COSTS OFF) +SELECT value = 0 +FROM ipairs +WHERE key IN (507, 508, 509); + +-- Variant 3 (as above) +EXPLAIN (COSTS OFF) +SELECT value = 0 +FROM ipairs +WHERE key = ANY('{507,508,509}'::INT[]); + +-- Variant 5 (should use only ipairs_key_idx4) +EXPLAIN (COSTS OFF) +SELECT value = 0 +FROM ipairs +WHERE key < ANY('{508}'::INT[]); + +-- Clean up +DROP TABLE ipairs; -- 2.43.0