diff options
Diffstat (limited to 'src/backend/utils/cache/partcache.c')
-rw-r--r-- | src/backend/utils/cache/partcache.c | 48 |
1 files changed, 29 insertions, 19 deletions
diff --git a/src/backend/utils/cache/partcache.c b/src/backend/utils/cache/partcache.c index e35a43405eb..5757301d054 100644 --- a/src/backend/utils/cache/partcache.c +++ b/src/backend/utils/cache/partcache.c @@ -797,31 +797,38 @@ RelationGetPartitionQual(Relation rel) * get_partition_qual_relid * * Returns an expression tree describing the passed-in relation's partition - * constraint. If there is no partition constraint returns NULL; this can - * happen if the default partition is the only partition. + * constraint. + * + * If the relation is not found, or is not a partition, or there is no + * partition constraint, return NULL. We must guard against the first two + * cases because this supports a SQL function that could be passed any OID. + * The last case can happen even if relispartition is true, when a default + * partition is the only partition. */ Expr * get_partition_qual_relid(Oid relid) { - Relation rel = heap_open(relid, AccessShareLock); Expr *result = NULL; - List *and_args; - /* Do the work only if this relation is a partition. */ - if (rel->rd_rel->relispartition) + /* Do the work only if this relation exists and is a partition. */ + if (get_rel_relispartition(relid)) { + Relation rel = relation_open(relid, AccessShareLock); + List *and_args; + and_args = generate_partition_qual(rel); + /* Convert implicit-AND list format to boolean expression */ if (and_args == NIL) result = NULL; else if (list_length(and_args) > 1) result = makeBoolExpr(AND_EXPR, and_args, -1); else result = linitial(and_args); - } - /* Keep the lock. */ - heap_close(rel, NoLock); + /* Keep the lock, to allow safe deparsing against the rel by caller. */ + relation_close(rel, NoLock); + } return result; } @@ -845,7 +852,6 @@ generate_partition_qual(Relation rel) MemoryContext oldcxt; Datum boundDatum; bool isnull; - PartitionBoundSpec *bound; List *my_qual = NIL, *result = NIL; Relation parent; @@ -859,8 +865,8 @@ generate_partition_qual(Relation rel) return copyObject(rel->rd_partcheck); /* Grab at least an AccessShareLock on the parent table */ - parent = heap_open(get_partition_parent(RelationGetRelid(rel)), - AccessShareLock); + parent = relation_open(get_partition_parent(RelationGetRelid(rel)), + AccessShareLock); /* Get pg_class.relpartbound */ tuple = SearchSysCache1(RELOID, RelationGetRelid(rel)); @@ -871,13 +877,17 @@ generate_partition_qual(Relation rel) boundDatum = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_relpartbound, &isnull); - if (isnull) - elog(ERROR, "null relpartbound for relation %u", RelationGetRelid(rel)); - bound = castNode(PartitionBoundSpec, - stringToNode(TextDatumGetCString(boundDatum))); - ReleaseSysCache(tuple); + if (!isnull) + { + PartitionBoundSpec *bound; + + bound = castNode(PartitionBoundSpec, + stringToNode(TextDatumGetCString(boundDatum))); - my_qual = get_qual_from_partbound(rel, parent, bound); + my_qual = get_qual_from_partbound(rel, parent, bound); + } + + ReleaseSysCache(tuple); /* Add the parent's quals to the list (if any) */ if (parent->rd_rel->relispartition) @@ -903,7 +913,7 @@ generate_partition_qual(Relation rel) MemoryContextSwitchTo(oldcxt); /* Keep the parent locked until commit */ - heap_close(parent, NoLock); + relation_close(parent, NoLock); return result; } |