aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--contrib/btree_gin/expected/bool.out10
-rw-r--r--contrib/btree_gist/expected/bool.out4
-rw-r--r--src/backend/optimizer/path/indxpath.c18
-rw-r--r--src/backend/optimizer/path/pathkeys.c9
-rw-r--r--src/backend/partitioning/partprune.c6
-rw-r--r--src/include/catalog/pg_opfamily.h3
6 files changed, 40 insertions, 10 deletions
diff --git a/contrib/btree_gin/expected/bool.out b/contrib/btree_gin/expected/bool.out
index efb3e1e327c..207a3f23281 100644
--- a/contrib/btree_gin/expected/bool.out
+++ b/contrib/btree_gin/expected/bool.out
@@ -87,13 +87,15 @@ EXPLAIN (COSTS OFF) SELECT * FROM test_bool WHERE i<=true ORDER BY i;
(6 rows)
EXPLAIN (COSTS OFF) SELECT * FROM test_bool WHERE i=true ORDER BY i;
- QUERY PLAN
------------------------------
+ QUERY PLAN
+-------------------------------------------
Sort
Sort Key: i
- -> Seq Scan on test_bool
+ -> Bitmap Heap Scan on test_bool
Filter: i
-(4 rows)
+ -> Bitmap Index Scan on idx_bool
+ Index Cond: (i = true)
+(6 rows)
EXPLAIN (COSTS OFF) SELECT * FROM test_bool WHERE i>=true ORDER BY i;
QUERY PLAN
diff --git a/contrib/btree_gist/expected/bool.out b/contrib/btree_gist/expected/bool.out
index c67a9685d52..29390f079c0 100644
--- a/contrib/btree_gist/expected/bool.out
+++ b/contrib/btree_gist/expected/bool.out
@@ -71,7 +71,7 @@ SELECT * FROM booltmp WHERE a;
QUERY PLAN
------------------------------------------
Index Only Scan using boolidx on booltmp
- Filter: a
+ Index Cond: (a = true)
(2 rows)
SELECT * FROM booltmp WHERE a;
@@ -85,7 +85,7 @@ SELECT * FROM booltmp WHERE NOT a;
QUERY PLAN
------------------------------------------
Index Only Scan using boolidx on booltmp
- Filter: (NOT a)
+ Index Cond: (a = false)
(2 rows)
SELECT * FROM booltmp WHERE NOT a;
diff --git a/src/backend/optimizer/path/indxpath.c b/src/backend/optimizer/path/indxpath.c
index 045ff2e487e..63a8eef45cd 100644
--- a/src/backend/optimizer/path/indxpath.c
+++ b/src/backend/optimizer/path/indxpath.c
@@ -153,6 +153,7 @@ static IndexClause *match_clause_to_indexcol(PlannerInfo *root,
RestrictInfo *rinfo,
int indexcol,
IndexOptInfo *index);
+static bool IsBooleanOpfamily(Oid opfamily);
static IndexClause *match_boolean_index_clause(PlannerInfo *root,
RestrictInfo *rinfo,
int indexcol, IndexOptInfo *index);
@@ -2343,6 +2344,23 @@ match_clause_to_indexcol(PlannerInfo *root,
}
/*
+ * IsBooleanOpfamily
+ * Detect whether an opfamily supports boolean equality as an operator.
+ *
+ * If the opfamily OID is in the range of built-in objects, we can rely
+ * on hard-wired knowledge of which built-in opfamilies support this.
+ * For extension opfamilies, there's no choice but to do a catcache lookup.
+ */
+static bool
+IsBooleanOpfamily(Oid opfamily)
+{
+ if (opfamily < FirstNormalObjectId)
+ return IsBuiltinBooleanOpfamily(opfamily);
+ else
+ return op_in_opfamily(BooleanEqualOperator, opfamily);
+}
+
+/*
* match_boolean_index_clause
* Recognize restriction clauses that can be matched to a boolean index.
*
diff --git a/src/backend/optimizer/path/pathkeys.c b/src/backend/optimizer/path/pathkeys.c
index 1fa7fc99b51..18f88700981 100644
--- a/src/backend/optimizer/path/pathkeys.c
+++ b/src/backend/optimizer/path/pathkeys.c
@@ -1191,8 +1191,13 @@ partkey_is_bool_constant_for_query(RelOptInfo *partrel, int partkeycol)
PartitionScheme partscheme = partrel->part_scheme;
ListCell *lc;
- /* If the partkey isn't boolean, we can't possibly get a match */
- if (!IsBooleanOpfamily(partscheme->partopfamily[partkeycol]))
+ /*
+ * If the partkey isn't boolean, we can't possibly get a match.
+ *
+ * Partitioning currently can only use built-in AMs, so checking for
+ * built-in boolean opfamilies is good enough.
+ */
+ if (!IsBuiltinBooleanOpfamily(partscheme->partopfamily[partkeycol]))
return false;
/* Check each restriction clause for the partitioned rel */
diff --git a/src/backend/partitioning/partprune.c b/src/backend/partitioning/partprune.c
index bf9fe5b7aaf..5ab46123671 100644
--- a/src/backend/partitioning/partprune.c
+++ b/src/backend/partitioning/partprune.c
@@ -3596,7 +3596,11 @@ match_boolean_partition_clause(Oid partopfamily, Expr *clause, Expr *partkey,
*outconst = NULL;
- if (!IsBooleanOpfamily(partopfamily))
+ /*
+ * Partitioning currently can only use built-in AMs, so checking for
+ * built-in boolean opfamilies is good enough.
+ */
+ if (!IsBuiltinBooleanOpfamily(partopfamily))
return PARTCLAUSE_UNSUPPORTED;
if (IsA(clause, BooleanTest))
diff --git a/src/include/catalog/pg_opfamily.h b/src/include/catalog/pg_opfamily.h
index 8dc9ce01bb9..67ad01ce07c 100644
--- a/src/include/catalog/pg_opfamily.h
+++ b/src/include/catalog/pg_opfamily.h
@@ -55,7 +55,8 @@ DECLARE_UNIQUE_INDEX_PKEY(pg_opfamily_oid_index, 2755, OpfamilyOidIndexId, on pg
#ifdef EXPOSE_TO_CLIENT_CODE
-#define IsBooleanOpfamily(opfamily) \
+/* This does not account for non-core opfamilies that might accept boolean */
+#define IsBuiltinBooleanOpfamily(opfamily) \
((opfamily) == BOOL_BTREE_FAM_OID || (opfamily) == BOOL_HASH_FAM_OID)
#endif /* EXPOSE_TO_CLIENT_CODE */