Always use ReleaseTupleDesc after lookup_rowtype_tupdesc et al.

The API spec for lookup_rowtype_tupdesc previously said you could use
either ReleaseTupleDesc or DecrTupleDescRefCount.  However, the latter
choice means the caller must be certain that the returned tupdesc is
refcounted.  I don't recall right now whether that was always true
when this spec was written, but it's certainly not always true since
we introduced shared record typcaches for parallel workers.  That means
that callers using DecrTupleDescRefCount are dependent on typcache
behavior details that they probably shouldn't be.  Hence, change the API
spec to say that you must call ReleaseTupleDesc, and fix the half-dozen
callers that weren't.

AFAICT this is just future-proofing, there's no live bug here.
So no back-patch.

Per gripe from Chapman Flack.

Discussion: https://postgr.es/m/61B901A4.1050808@anastigmatix.net
This commit is contained in:
Tom Lane 2021-12-15 18:58:20 -05:00
parent 2a712066d0
commit bbc227e951
5 changed files with 10 additions and 7 deletions

View File

@ -15401,7 +15401,7 @@ ATExecAddOf(Relation rel, const TypeName *ofTypename, LOCKMODE lockmode)
errmsg("table \"%s\" has different type for column \"%s\"", errmsg("table \"%s\" has different type for column \"%s\"",
RelationGetRelationName(rel), type_attname))); RelationGetRelationName(rel), type_attname)));
} }
DecrTupleDescRefCount(typeTupleDesc); ReleaseTupleDesc(typeTupleDesc);
/* Any remaining columns at the end of the table had better be dropped. */ /* Any remaining columns at the end of the table had better be dropped. */
for (; table_attno <= tableTupleDesc->natts; table_attno++) for (; table_attno <= tableTupleDesc->natts; table_attno++)

View File

@ -1465,7 +1465,7 @@ ExecInitExprRec(Expr *node, ExprState *state,
/* find out the number of columns in the composite type */ /* find out the number of columns in the composite type */
tupDesc = lookup_rowtype_tupdesc(fstore->resulttype, -1); tupDesc = lookup_rowtype_tupdesc(fstore->resulttype, -1);
ncolumns = tupDesc->natts; ncolumns = tupDesc->natts;
DecrTupleDescRefCount(tupDesc); ReleaseTupleDesc(tupDesc);
/* create workspace for column values */ /* create workspace for column values */
values = (Datum *) palloc(sizeof(Datum) * ncolumns); values = (Datum *) palloc(sizeof(Datum) * ncolumns);

View File

@ -1484,7 +1484,7 @@ transformOfType(CreateStmtContext *cxt, TypeName *ofTypename)
n->location = -1; n->location = -1;
cxt->columns = lappend(cxt->columns, n); cxt->columns = lappend(cxt->columns, n);
} }
DecrTupleDescRefCount(tupdesc); ReleaseTupleDesc(tupdesc);
ReleaseSysCache(tuple); ReleaseSysCache(tuple);
} }

View File

@ -171,7 +171,7 @@ make_expanded_record_from_typeid(Oid type_id, int32 typmod,
/* If we called lookup_rowtype_tupdesc, release the pin it took */ /* If we called lookup_rowtype_tupdesc, release the pin it took */
if (type_id == RECORDOID) if (type_id == RECORDOID)
DecrTupleDescRefCount(tupdesc); ReleaseTupleDesc(tupdesc);
} }
else else
{ {
@ -854,7 +854,7 @@ expanded_record_fetch_tupdesc(ExpandedRecordHeader *erh)
tupdesc->tdrefcount++; tupdesc->tdrefcount++;
/* Release the pin lookup_rowtype_tupdesc acquired */ /* Release the pin lookup_rowtype_tupdesc acquired */
DecrTupleDescRefCount(tupdesc); ReleaseTupleDesc(tupdesc);
} }
else else
{ {

View File

@ -1820,8 +1820,11 @@ lookup_rowtype_tupdesc_internal(Oid type_id, int32 typmod, bool noError)
* for example from record_in().) * for example from record_in().)
* *
* Note: on success, we increment the refcount of the returned TupleDesc, * Note: on success, we increment the refcount of the returned TupleDesc,
* and log the reference in CurrentResourceOwner. Caller should call * and log the reference in CurrentResourceOwner. Caller must call
* ReleaseTupleDesc or DecrTupleDescRefCount when done using the tupdesc. * ReleaseTupleDesc when done using the tupdesc. (There are some
* cases in which the returned tupdesc is not refcounted, in which
* case PinTupleDesc/ReleaseTupleDesc are no-ops; but in these cases
* the tupdesc is guaranteed to live till process exit.)
*/ */
TupleDesc TupleDesc
lookup_rowtype_tupdesc(Oid type_id, int32 typmod) lookup_rowtype_tupdesc(Oid type_id, int32 typmod)