v4-0001-constant-folding-for-indexquals-in-bitmap-scan.patch

application/octet-stream

Filename: v4-0001-constant-folding-for-indexquals-in-bitmap-scan.patch
Type: application/octet-stream
Part: 0
Message: Re: BUG #17618: unnecessary filter column <> text even after adding index

Patch

Format: format-patch
Series: patch v4-0001
Subject: constant folding for indexquals in bitmap scan
File+
contrib/btree_gin/expected/bool.out 1 1
src/backend/optimizer/plan/createplan.c 45 2
From 17e63c3aaa5df849634a2770fdf18a0e88e56b08 Mon Sep 17 00:00:00 2001
From: Richard Guo <guofenglinux@gmail.com>
Date: Mon, 7 Nov 2022 15:56:46 +0800
Subject: [PATCH v4] constant folding for indexquals in bitmap scan

---
 contrib/btree_gin/expected/bool.out     |  2 +-
 src/backend/optimizer/plan/createplan.c | 47 +++++++++++++++++++++++--
 2 files changed, 46 insertions(+), 3 deletions(-)

diff --git a/contrib/btree_gin/expected/bool.out b/contrib/btree_gin/expected/bool.out
index 207a3f2328..51a70eb530 100644
--- a/contrib/btree_gin/expected/bool.out
+++ b/contrib/btree_gin/expected/bool.out
@@ -92,7 +92,7 @@ EXPLAIN (COSTS OFF) SELECT * FROM test_bool WHERE i=true ORDER BY i;
  Sort
    Sort Key: i
    ->  Bitmap Heap Scan on test_bool
-         Filter: i
+         Recheck Cond: i
          ->  Bitmap Index Scan on idx_bool
                Index Cond: (i = true)
 (6 rows)
diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c
index ac86ce9003..ef50cf8b18 100644
--- a/src/backend/optimizer/plan/createplan.c
+++ b/src/backend/optimizer/plan/createplan.c
@@ -20,6 +20,7 @@
 
 #include "access/sysattr.h"
 #include "catalog/pg_class.h"
+#include "catalog/pg_operator.h"
 #include "foreign/fdwapi.h"
 #include "miscadmin.h"
 #include "nodes/extensible.h"
@@ -3480,11 +3481,53 @@ create_bitmap_subplan(PlannerInfo *root, Path *bitmapqual,
 		{
 			IndexClause *iclause = (IndexClause *) lfirst(l);
 			RestrictInfo *rinfo = iclause->rinfo;
+			ListCell	 *l2;
 
 			Assert(!rinfo->pseudoconstant);
 			subquals = lappend(subquals, rinfo->clause);
-			subindexquals = list_concat(subindexquals,
-										get_actual_clauses(iclause->indexquals));
+
+			/*
+			 * The indexquals may have been transformed into form "indexkey =
+			 * true/false" in match_boolean_index_clause.  We need to
+			 * re-simplify them in order to compare them to scan_clauses in
+			 * create_bitmap_scan_plan.
+			 *
+			 * According to what match_boolean_index_clause does, the constant
+			 * input can be only on right, and it cannot be a constant-NULL.
+			 */
+			foreach(l2, iclause->indexquals)
+			{
+				RestrictInfo *restrictinfo = lfirst_node(RestrictInfo, l2);
+				Node		 *clause = (Node *) restrictinfo->clause;
+
+				Assert(!restrictinfo->pseudoconstant);
+
+				if (is_opclause(clause) &&
+					((OpExpr *) clause)->opno == BooleanEqualOperator)
+				{
+					Node	   *rightop;
+
+					Assert(list_length(((OpExpr *) clause)->args) == 2);
+					rightop = lsecond(((OpExpr *) clause)->args);
+
+					/*
+					 * The constant input can be only on right, and it cannot
+					 * be a constant-NULL.
+					 */
+					if (rightop && IsA(rightop, Const))
+					{
+						Node	*leftop = linitial(((OpExpr *) clause)->args);
+
+						Assert(!((Const *) rightop)->constisnull);
+						if (DatumGetBool(((Const *) rightop)->constvalue))
+							clause = leftop;	/* indexkey = true */
+						else
+							clause = negate_clause(leftop);	/* indexkey = false */
+					}
+				}
+
+				subindexquals = lappend(subindexquals, clause);
+			}
 			if (rinfo->parent_ec)
 				subindexECs = lappend(subindexECs, rinfo->parent_ec);
 		}
-- 
2.31.0