diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/backend/optimizer/path/indxpath.c | 18 | ||||
-rw-r--r-- | src/backend/optimizer/path/pathkeys.c | 9 | ||||
-rw-r--r-- | src/backend/partitioning/partprune.c | 6 | ||||
-rw-r--r-- | src/include/catalog/pg_opfamily.h | 3 |
4 files changed, 32 insertions, 4 deletions
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 */ |