aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/cache/partcache.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/utils/cache/partcache.c')
-rw-r--r--src/backend/utils/cache/partcache.c48
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;
}