mirror of
https://github.com/postgres/postgres.git
synced 2026-06-08 16:26:30 -04:00
Add all required calls to TupleDescFinalize()
As of this commit all TupleDescs must have TupleDescFinalize() called on them once the TupleDesc is set up and before BlessTupleDesc() is called. In this commit, TupleDescFinalize() does nothing. This change has only been separated out from the commit that properly implements this function to make the change more obvious. Any extension which makes its own TupleDesc will need to be modified to call the new function. The follow-up commit which properly implements TupleDescFinalize() will cause any code which forgets to do this to fail in assert-enabled builds in BlessTupleDesc(). It may still be worth mentioning this change in the release notes so that extension authors update their code. Author: David Rowley <dgrowleyml@gmail.com> Reviewed-by: Chao Li <li.evan.chao@gmail.com> Reviewed-by: Andres Freund <andres@anarazel.de> Reviewed-by: John Naylor <johncnaylorls@gmail.com> Reviewed-by: Amit Langote <amitlangote09@gmail.com> Reviewed-by: Zsolt Parragi <zsolt.parragi@percona.com> Reviewed-by: Álvaro Herrera <alvherre@kurilemu.de> Reviewed-by: Junwang Zhao <zhjwpku@gmail.com> Discussion: https://postgr.es/m/CAApHDvpoFjaj3%2Bw_jD5uPnGazaw41A71tVJokLDJg2zfcigpMQ%40mail.gmail.com
This commit is contained in:
parent
e5a77d876d
commit
503620311e
39 changed files with 100 additions and 1 deletions
|
|
@ -881,6 +881,7 @@ materializeResult(FunctionCallInfo fcinfo, PGconn *conn, PGresult *res)
|
|||
tupdesc = CreateTemplateTupleDesc(1);
|
||||
TupleDescInitEntry(tupdesc, (AttrNumber) 1, "status",
|
||||
TEXTOID, -1, 0);
|
||||
TupleDescFinalize(tupdesc);
|
||||
ntuples = 1;
|
||||
nfields = 1;
|
||||
}
|
||||
|
|
@ -1044,6 +1045,7 @@ materializeQueryResult(FunctionCallInfo fcinfo,
|
|||
tupdesc = CreateTemplateTupleDesc(1);
|
||||
TupleDescInitEntry(tupdesc, (AttrNumber) 1, "status",
|
||||
TEXTOID, -1, 0);
|
||||
TupleDescFinalize(tupdesc);
|
||||
attinmeta = TupleDescGetAttInMetadata(tupdesc);
|
||||
|
||||
oldcontext = MemoryContextSwitchTo(rsinfo->econtext->ecxt_per_query_memory);
|
||||
|
|
@ -1529,6 +1531,8 @@ dblink_get_pkey(PG_FUNCTION_ARGS)
|
|||
TupleDescInitEntry(tupdesc, (AttrNumber) 2, "colname",
|
||||
TEXTOID, -1, 0);
|
||||
|
||||
TupleDescFinalize(tupdesc);
|
||||
|
||||
/*
|
||||
* Generate attribute metadata needed later to produce tuples from raw
|
||||
* C strings
|
||||
|
|
|
|||
|
|
@ -174,6 +174,7 @@ pg_buffercache_pages(PG_FUNCTION_ARGS)
|
|||
TupleDescInitEntry(tupledesc, (AttrNumber) 9, "pinning_backends",
|
||||
INT4OID, -1, 0);
|
||||
|
||||
TupleDescFinalize(tupledesc);
|
||||
fctx->tupdesc = BlessTupleDesc(tupledesc);
|
||||
|
||||
/* Allocate NBuffers worth of BufferCachePagesRec records. */
|
||||
|
|
@ -442,6 +443,7 @@ pg_buffercache_os_pages_internal(FunctionCallInfo fcinfo, bool include_numa)
|
|||
TupleDescInitEntry(tupledesc, (AttrNumber) 3, "numa_node",
|
||||
INT4OID, -1, 0);
|
||||
|
||||
TupleDescFinalize(tupledesc);
|
||||
fctx->tupdesc = BlessTupleDesc(tupledesc);
|
||||
fctx->include_numa = include_numa;
|
||||
|
||||
|
|
|
|||
|
|
@ -469,6 +469,8 @@ pg_visibility_tupdesc(bool include_blkno, bool include_pd)
|
|||
TupleDescInitEntry(tupdesc, ++a, "pd_all_visible", BOOLOID, -1, 0);
|
||||
Assert(a == maxattr);
|
||||
|
||||
TupleDescFinalize(tupdesc);
|
||||
|
||||
return BlessTupleDesc(tupdesc);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -84,6 +84,7 @@ brtuple_disk_tupdesc(BrinDesc *brdesc)
|
|||
|
||||
MemoryContextSwitchTo(oldcxt);
|
||||
|
||||
TupleDescFinalize(tupdesc);
|
||||
brdesc->bd_disktdesc = tupdesc;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -221,6 +221,9 @@ CreateTupleDesc(int natts, Form_pg_attribute *attrs)
|
|||
memcpy(TupleDescAttr(desc, i), attrs[i], ATTRIBUTE_FIXED_PART_SIZE);
|
||||
populate_compact_attribute(desc, i);
|
||||
}
|
||||
|
||||
TupleDescFinalize(desc);
|
||||
|
||||
return desc;
|
||||
}
|
||||
|
||||
|
|
@ -265,6 +268,8 @@ CreateTupleDescCopy(TupleDesc tupdesc)
|
|||
desc->tdtypeid = tupdesc->tdtypeid;
|
||||
desc->tdtypmod = tupdesc->tdtypmod;
|
||||
|
||||
TupleDescFinalize(desc);
|
||||
|
||||
return desc;
|
||||
}
|
||||
|
||||
|
|
@ -311,6 +316,8 @@ CreateTupleDescTruncatedCopy(TupleDesc tupdesc, int natts)
|
|||
desc->tdtypeid = tupdesc->tdtypeid;
|
||||
desc->tdtypmod = tupdesc->tdtypmod;
|
||||
|
||||
TupleDescFinalize(desc);
|
||||
|
||||
return desc;
|
||||
}
|
||||
|
||||
|
|
@ -396,6 +403,8 @@ CreateTupleDescCopyConstr(TupleDesc tupdesc)
|
|||
desc->tdtypeid = tupdesc->tdtypeid;
|
||||
desc->tdtypmod = tupdesc->tdtypmod;
|
||||
|
||||
TupleDescFinalize(desc);
|
||||
|
||||
return desc;
|
||||
}
|
||||
|
||||
|
|
@ -438,6 +447,8 @@ TupleDescCopy(TupleDesc dst, TupleDesc src)
|
|||
* source's refcount would be wrong in any case.)
|
||||
*/
|
||||
dst->tdrefcount = -1;
|
||||
|
||||
TupleDescFinalize(dst);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -1065,6 +1076,8 @@ BuildDescFromLists(const List *names, const List *types, const List *typmods, co
|
|||
TupleDescInitEntryCollation(desc, attnum, attcollation);
|
||||
}
|
||||
|
||||
TupleDescFinalize(desc);
|
||||
|
||||
return desc;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -129,6 +129,7 @@ initGinState(GinState *state, Relation index)
|
|||
attr->attndims);
|
||||
TupleDescInitEntryCollation(state->tupdesc[i], (AttrNumber) 2,
|
||||
attr->attcollation);
|
||||
TupleDescFinalize(state->tupdesc[i]);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -201,6 +201,7 @@ gistrescan(IndexScanDesc scan, ScanKey key, int nkeys,
|
|||
attno - 1)->atttypid,
|
||||
-1, 0);
|
||||
}
|
||||
TupleDescFinalize(so->giststate->fetchTupdesc);
|
||||
scan->xs_hitupdesc = so->giststate->fetchTupdesc;
|
||||
|
||||
/* Also create a memory context that will hold the returned tuples */
|
||||
|
|
|
|||
|
|
@ -340,6 +340,7 @@ getSpGistTupleDesc(Relation index, SpGistTypeDesc *keyType)
|
|||
TupleDescCompactAttr(outTupDesc, i)->attcacheoff = -1;
|
||||
|
||||
populate_compact_attribute(outTupDesc, spgKeyColumn);
|
||||
TupleDescFinalize(outTupDesc);
|
||||
}
|
||||
return outTupDesc;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -745,6 +745,7 @@ pg_prepared_xact(PG_FUNCTION_ARGS)
|
|||
TupleDescInitEntry(tupdesc, (AttrNumber) 5, "dbid",
|
||||
OIDOID, -1, 0);
|
||||
|
||||
TupleDescFinalize(tupdesc);
|
||||
funcctx->tuple_desc = BlessTupleDesc(tupdesc);
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -430,6 +430,7 @@ pg_walfile_name_offset(PG_FUNCTION_ARGS)
|
|||
TupleDescInitEntry(resultTupleDesc, (AttrNumber) 2, "file_offset",
|
||||
INT4OID, -1, 0);
|
||||
|
||||
TupleDescFinalize(resultTupleDesc);
|
||||
resultTupleDesc = BlessTupleDesc(resultTupleDesc);
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -357,6 +357,8 @@ SendXlogRecPtrResult(XLogRecPtr ptr, TimeLineID tli)
|
|||
*/
|
||||
TupleDescInitBuiltinEntry(tupdesc, (AttrNumber) 2, "tli", INT8OID, -1, 0);
|
||||
|
||||
TupleDescFinalize(tupdesc);
|
||||
|
||||
/* send RowDescription */
|
||||
tstate = begin_tup_output_tupdesc(dest, tupdesc, &TTSOpsVirtual);
|
||||
|
||||
|
|
@ -388,6 +390,7 @@ SendTablespaceList(List *tablespaces)
|
|||
TupleDescInitBuiltinEntry(tupdesc, (AttrNumber) 1, "spcoid", OIDOID, -1, 0);
|
||||
TupleDescInitBuiltinEntry(tupdesc, (AttrNumber) 2, "spclocation", TEXTOID, -1, 0);
|
||||
TupleDescInitBuiltinEntry(tupdesc, (AttrNumber) 3, "size", INT8OID, -1, 0);
|
||||
TupleDescFinalize(tupdesc);
|
||||
|
||||
/* send RowDescription */
|
||||
tstate = begin_tup_output_tupdesc(dest, tupdesc, &TTSOpsVirtual);
|
||||
|
|
|
|||
|
|
@ -481,6 +481,8 @@ ConstructTupleDescriptor(Relation heapRelation,
|
|||
populate_compact_attribute(indexTupDesc, i);
|
||||
}
|
||||
|
||||
TupleDescFinalize(indexTupDesc);
|
||||
|
||||
return indexTupDesc;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1322,6 +1322,7 @@ pg_get_publication_tables(PG_FUNCTION_ARGS)
|
|||
TupleDescInitEntry(tupdesc, (AttrNumber) 4, "qual",
|
||||
PG_NODE_TREEOID, -1, 0);
|
||||
|
||||
TupleDescFinalize(tupdesc);
|
||||
funcctx->tuple_desc = BlessTupleDesc(tupdesc);
|
||||
funcctx->user_fctx = table_infos;
|
||||
|
||||
|
|
|
|||
|
|
@ -229,6 +229,12 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid,
|
|||
TupleDescAttr(tupdesc, 1)->attcompression = InvalidCompressionMethod;
|
||||
TupleDescAttr(tupdesc, 2)->attcompression = InvalidCompressionMethod;
|
||||
|
||||
populate_compact_attribute(tupdesc, 0);
|
||||
populate_compact_attribute(tupdesc, 1);
|
||||
populate_compact_attribute(tupdesc, 2);
|
||||
|
||||
TupleDescFinalize(tupdesc);
|
||||
|
||||
/*
|
||||
* Toast tables for regular relations go in pg_toast; those for temp
|
||||
* relations go into the per-backend temp-toast-table namespace.
|
||||
|
|
|
|||
|
|
@ -281,6 +281,7 @@ ExplainResultDesc(ExplainStmt *stmt)
|
|||
tupdesc = CreateTemplateTupleDesc(1);
|
||||
TupleDescInitEntry(tupdesc, (AttrNumber) 1, "QUERY PLAN",
|
||||
result_type, -1, 0);
|
||||
TupleDescFinalize(tupdesc);
|
||||
return tupdesc;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2424,6 +2424,7 @@ CallStmtResultDesc(CallStmt *stmt)
|
|||
-1,
|
||||
0);
|
||||
}
|
||||
TupleDescFinalize(tupdesc);
|
||||
}
|
||||
|
||||
return tupdesc;
|
||||
|
|
|
|||
|
|
@ -1808,6 +1808,7 @@ pg_get_sequence_data(PG_FUNCTION_ARGS)
|
|||
BOOLOID, -1, 0);
|
||||
TupleDescInitEntry(resultTupleDesc, (AttrNumber) 3, "page_lsn",
|
||||
LSNOID, -1, 0);
|
||||
TupleDescFinalize(resultTupleDesc);
|
||||
resultTupleDesc = BlessTupleDesc(resultTupleDesc);
|
||||
|
||||
seqrel = try_relation_open(relid, AccessShareLock);
|
||||
|
|
|
|||
|
|
@ -1038,6 +1038,8 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId,
|
|||
}
|
||||
}
|
||||
|
||||
TupleDescFinalize(descriptor);
|
||||
|
||||
/*
|
||||
* For relations with table AM and partitioned tables, select access
|
||||
* method to use: an explicitly indicated one, or (in the case of a
|
||||
|
|
@ -1466,6 +1468,8 @@ BuildDescForRelation(const List *columns)
|
|||
populate_compact_attribute(desc, attnum - 1);
|
||||
}
|
||||
|
||||
TupleDescFinalize(desc);
|
||||
|
||||
return desc;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -338,5 +338,6 @@ WaitStmtResultDesc(WaitStmt *stmt)
|
|||
tupdesc = CreateTemplateTupleDesc(1);
|
||||
TupleDescInitEntry(tupdesc, (AttrNumber) 1, "status",
|
||||
TEXTOID, -1, 0);
|
||||
TupleDescFinalize(tupdesc);
|
||||
return tupdesc;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -272,6 +272,7 @@ ExecMakeTableFunctionResult(SetExprState *setexpr,
|
|||
funcrettype,
|
||||
-1,
|
||||
0);
|
||||
TupleDescFinalize(tupdesc);
|
||||
rsinfo.setDesc = tupdesc;
|
||||
}
|
||||
MemoryContextSwitchTo(oldcontext);
|
||||
|
|
@ -776,6 +777,7 @@ init_sexpr(Oid foid, Oid input_collation, Expr *node,
|
|||
funcrettype,
|
||||
-1,
|
||||
0);
|
||||
TupleDescFinalize(tupdesc);
|
||||
sexpr->funcResultDesc = tupdesc;
|
||||
sexpr->funcReturnsTuple = false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2175,6 +2175,8 @@ ExecTypeFromTLInternal(List *targetList, bool skipjunk)
|
|||
cur_resno++;
|
||||
}
|
||||
|
||||
TupleDescFinalize(typeInfo);
|
||||
|
||||
return typeInfo;
|
||||
}
|
||||
|
||||
|
|
@ -2209,6 +2211,8 @@ ExecTypeFromExprList(List *exprList)
|
|||
cur_resno++;
|
||||
}
|
||||
|
||||
TupleDescFinalize(typeInfo);
|
||||
|
||||
return typeInfo;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -414,6 +414,7 @@ ExecInitFunctionScan(FunctionScan *node, EState *estate, int eflags)
|
|||
TupleDescInitEntryCollation(tupdesc,
|
||||
(AttrNumber) 1,
|
||||
exprCollation(funcexpr));
|
||||
TupleDescFinalize(tupdesc);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -485,6 +486,7 @@ ExecInitFunctionScan(FunctionScan *node, EState *estate, int eflags)
|
|||
0);
|
||||
}
|
||||
|
||||
TupleDescFinalize(scan_tupdesc);
|
||||
Assert(attno == natts);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1883,6 +1883,7 @@ addRangeTableEntryForFunction(ParseState *pstate,
|
|||
TupleDescInitEntryCollation(tupdesc,
|
||||
(AttrNumber) 1,
|
||||
exprCollation(funcexpr));
|
||||
TupleDescFinalize(tupdesc);
|
||||
}
|
||||
else if (functypclass == TYPEFUNC_RECORD)
|
||||
{
|
||||
|
|
@ -1940,6 +1941,7 @@ addRangeTableEntryForFunction(ParseState *pstate,
|
|||
|
||||
i++;
|
||||
}
|
||||
TupleDescFinalize(tupdesc);
|
||||
|
||||
/*
|
||||
* Ensure that the coldeflist defines a legal set of names (no
|
||||
|
|
@ -2008,7 +2010,7 @@ addRangeTableEntryForFunction(ParseState *pstate,
|
|||
0);
|
||||
/* no need to set collation */
|
||||
}
|
||||
|
||||
TupleDescFinalize(tupdesc);
|
||||
Assert(natts == totalatts);
|
||||
}
|
||||
else
|
||||
|
|
|
|||
|
|
@ -1572,6 +1572,8 @@ expandRecordVariable(ParseState *pstate, Var *var, int levelsup)
|
|||
}
|
||||
Assert(lname == NULL && lvar == NULL); /* lists same length? */
|
||||
|
||||
TupleDescFinalize(tupleDesc);
|
||||
|
||||
return tupleDesc;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1073,6 +1073,7 @@ libpqrcv_processTuples(PGresult *pgres, WalRcvExecResult *walres,
|
|||
for (coln = 0; coln < nRetTypes; coln++)
|
||||
TupleDescInitEntry(walres->tupledesc, (AttrNumber) coln + 1,
|
||||
PQfname(pgres, coln), retTypes[coln], -1, 0);
|
||||
TupleDescFinalize(walres->tupledesc);
|
||||
attinmeta = TupleDescGetAttInMetadata(walres->tupledesc);
|
||||
|
||||
/* No point in doing more here if there were no tuples returned. */
|
||||
|
|
|
|||
|
|
@ -452,6 +452,7 @@ IdentifySystem(void)
|
|||
TEXTOID, -1, 0);
|
||||
TupleDescInitBuiltinEntry(tupdesc, (AttrNumber) 4, "dbname",
|
||||
TEXTOID, -1, 0);
|
||||
TupleDescFinalize(tupdesc);
|
||||
|
||||
/* prepare for projection of tuples */
|
||||
tstate = begin_tup_output_tupdesc(dest, tupdesc, &TTSOpsVirtual);
|
||||
|
|
@ -497,6 +498,7 @@ ReadReplicationSlot(ReadReplicationSlotCmd *cmd)
|
|||
/* TimeLineID is unsigned, so int4 is not wide enough. */
|
||||
TupleDescInitBuiltinEntry(tupdesc, (AttrNumber) 3, "restart_tli",
|
||||
INT8OID, -1, 0);
|
||||
TupleDescFinalize(tupdesc);
|
||||
|
||||
memset(nulls, true, READ_REPLICATION_SLOT_COLS * sizeof(bool));
|
||||
|
||||
|
|
@ -599,6 +601,7 @@ SendTimeLineHistory(TimeLineHistoryCmd *cmd)
|
|||
tupdesc = CreateTemplateTupleDesc(2);
|
||||
TupleDescInitBuiltinEntry(tupdesc, (AttrNumber) 1, "filename", TEXTOID, -1, 0);
|
||||
TupleDescInitBuiltinEntry(tupdesc, (AttrNumber) 2, "content", TEXTOID, -1, 0);
|
||||
TupleDescFinalize(tupdesc);
|
||||
|
||||
TLHistoryFileName(histfname, cmd->timeline);
|
||||
TLHistoryFilePath(path, cmd->timeline);
|
||||
|
|
@ -1016,6 +1019,7 @@ StartReplication(StartReplicationCmd *cmd)
|
|||
INT8OID, -1, 0);
|
||||
TupleDescInitBuiltinEntry(tupdesc, (AttrNumber) 2, "next_tli_startpos",
|
||||
TEXTOID, -1, 0);
|
||||
TupleDescFinalize(tupdesc);
|
||||
|
||||
/* prepare for projection of tuple */
|
||||
tstate = begin_tup_output_tupdesc(dest, tupdesc, &TTSOpsVirtual);
|
||||
|
|
@ -1370,6 +1374,7 @@ CreateReplicationSlot(CreateReplicationSlotCmd *cmd)
|
|||
TEXTOID, -1, 0);
|
||||
TupleDescInitBuiltinEntry(tupdesc, (AttrNumber) 4, "output_plugin",
|
||||
TEXTOID, -1, 0);
|
||||
TupleDescFinalize(tupdesc);
|
||||
|
||||
/* prepare for projection of tuples */
|
||||
tstate = begin_tup_output_tupdesc(dest, tupdesc, &TTSOpsVirtual);
|
||||
|
|
|
|||
|
|
@ -1841,6 +1841,7 @@ aclexplode(PG_FUNCTION_ARGS)
|
|||
TupleDescInitEntry(tupdesc, (AttrNumber) 4, "is_grantable",
|
||||
BOOLOID, -1, 0);
|
||||
|
||||
TupleDescFinalize(tupdesc);
|
||||
funcctx->tuple_desc = BlessTupleDesc(tupdesc);
|
||||
|
||||
/* allocate memory for user context */
|
||||
|
|
|
|||
|
|
@ -454,6 +454,7 @@ pg_stat_file(PG_FUNCTION_ARGS)
|
|||
"creation", TIMESTAMPTZOID, -1, 0);
|
||||
TupleDescInitEntry(tupdesc, (AttrNumber) 6,
|
||||
"isdir", BOOLOID, -1, 0);
|
||||
TupleDescFinalize(tupdesc);
|
||||
BlessTupleDesc(tupdesc);
|
||||
|
||||
memset(isnull, false, sizeof(isnull));
|
||||
|
|
|
|||
|
|
@ -146,6 +146,7 @@ pg_lock_status(PG_FUNCTION_ARGS)
|
|||
TupleDescInitEntry(tupdesc, (AttrNumber) 16, "waitstart",
|
||||
TIMESTAMPTZOID, -1, 0);
|
||||
|
||||
TupleDescFinalize(tupdesc);
|
||||
funcctx->tuple_desc = BlessTupleDesc(tupdesc);
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -233,6 +233,7 @@ ordered_set_startup(FunctionCallInfo fcinfo, bool use_tuples)
|
|||
-1,
|
||||
0);
|
||||
|
||||
TupleDescFinalize(newdesc);
|
||||
FreeTupleDesc(qstate->tupdesc);
|
||||
qstate->tupdesc = newdesc;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -770,6 +770,7 @@ pg_stat_get_backend_subxact(PG_FUNCTION_ARGS)
|
|||
TupleDescInitEntry(tupdesc, (AttrNumber) 2, "subxact_overflow",
|
||||
BOOLOID, -1, 0);
|
||||
|
||||
TupleDescFinalize(tupdesc);
|
||||
BlessTupleDesc(tupdesc);
|
||||
|
||||
if ((local_beentry = pgstat_get_local_beentry_by_proc_number(procNumber)) != NULL)
|
||||
|
|
@ -1671,6 +1672,7 @@ pg_stat_wal_build_tuple(PgStat_WalCounters wal_counters,
|
|||
TupleDescInitEntry(tupdesc, (AttrNumber) 6, "stats_reset",
|
||||
TIMESTAMPTZOID, -1, 0);
|
||||
|
||||
TupleDescFinalize(tupdesc);
|
||||
BlessTupleDesc(tupdesc);
|
||||
|
||||
/* Fill values and NULLs */
|
||||
|
|
@ -2098,6 +2100,7 @@ pg_stat_get_archiver(PG_FUNCTION_ARGS)
|
|||
TupleDescInitEntry(tupdesc, (AttrNumber) 7, "stats_reset",
|
||||
TIMESTAMPTZOID, -1, 0);
|
||||
|
||||
TupleDescFinalize(tupdesc);
|
||||
BlessTupleDesc(tupdesc);
|
||||
|
||||
/* Get statistics about the archiver process */
|
||||
|
|
@ -2179,6 +2182,7 @@ pg_stat_get_replication_slot(PG_FUNCTION_ARGS)
|
|||
TIMESTAMPTZOID, -1, 0);
|
||||
TupleDescInitEntry(tupdesc, (AttrNumber) 13, "stats_reset",
|
||||
TIMESTAMPTZOID, -1, 0);
|
||||
TupleDescFinalize(tupdesc);
|
||||
BlessTupleDesc(tupdesc);
|
||||
|
||||
namestrcpy(&slotname, text_to_cstring(slotname_text));
|
||||
|
|
@ -2266,6 +2270,7 @@ pg_stat_get_subscription_stats(PG_FUNCTION_ARGS)
|
|||
INT8OID, -1, 0);
|
||||
TupleDescInitEntry(tupdesc, (AttrNumber) 13, "stats_reset",
|
||||
TIMESTAMPTZOID, -1, 0);
|
||||
TupleDescFinalize(tupdesc);
|
||||
BlessTupleDesc(tupdesc);
|
||||
|
||||
if (!subentry)
|
||||
|
|
|
|||
|
|
@ -651,6 +651,7 @@ tsvector_unnest(PG_FUNCTION_ARGS)
|
|||
TEXTARRAYOID, -1, 0);
|
||||
if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
|
||||
elog(ERROR, "return type must be a row type");
|
||||
TupleDescFinalize(tupdesc);
|
||||
funcctx->tuple_desc = tupdesc;
|
||||
|
||||
funcctx->user_fctx = PG_GETARG_TSVECTOR_COPY(0);
|
||||
|
|
|
|||
8
src/backend/utils/cache/relcache.c
vendored
8
src/backend/utils/cache/relcache.c
vendored
|
|
@ -729,6 +729,8 @@ RelationBuildTupleDesc(Relation relation)
|
|||
pfree(constr);
|
||||
relation->rd_att->constr = NULL;
|
||||
}
|
||||
|
||||
TupleDescFinalize(relation->rd_att);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -1985,6 +1987,7 @@ formrdesc(const char *relationName, Oid relationReltype,
|
|||
|
||||
/* initialize first attribute's attcacheoff, cf RelationBuildTupleDesc */
|
||||
TupleDescCompactAttr(relation->rd_att, 0)->attcacheoff = 0;
|
||||
TupleDescFinalize(relation->rd_att);
|
||||
|
||||
/* mark not-null status */
|
||||
if (has_not_null)
|
||||
|
|
@ -3688,6 +3691,8 @@ RelationBuildLocalRelation(const char *relname,
|
|||
for (i = 0; i < natts; i++)
|
||||
TupleDescAttr(rel->rd_att, i)->attrelid = relid;
|
||||
|
||||
TupleDescFinalize(rel->rd_att);
|
||||
|
||||
rel->rd_rel->reltablespace = reltablespace;
|
||||
|
||||
if (mapped_relation)
|
||||
|
|
@ -4443,6 +4448,7 @@ BuildHardcodedDescriptor(int natts, const FormData_pg_attribute *attrs)
|
|||
|
||||
/* initialize first attribute's attcacheoff, cf RelationBuildTupleDesc */
|
||||
TupleDescCompactAttr(result, 0)->attcacheoff = 0;
|
||||
TupleDescFinalize(result);
|
||||
|
||||
/* Note: we don't bother to set up a TupleConstr entry */
|
||||
|
||||
|
|
@ -6291,6 +6297,8 @@ load_relcache_init_file(bool shared)
|
|||
populate_compact_attribute(rel->rd_att, i);
|
||||
}
|
||||
|
||||
TupleDescFinalize(rel->rd_att);
|
||||
|
||||
/* next read the access method specific field */
|
||||
if (fread(&len, 1, sizeof(len), fp) != sizeof(len))
|
||||
goto read_failed;
|
||||
|
|
|
|||
|
|
@ -340,6 +340,8 @@ get_expr_result_type(Node *expr,
|
|||
exprCollation(col));
|
||||
i++;
|
||||
}
|
||||
TupleDescFinalize(tupdesc);
|
||||
|
||||
if (resultTypeId)
|
||||
*resultTypeId = rexpr->row_typeid;
|
||||
if (resultTupleDesc)
|
||||
|
|
@ -1044,6 +1046,7 @@ resolve_polymorphic_tupdesc(TupleDesc tupdesc, oidvector *declared_args,
|
|||
}
|
||||
}
|
||||
|
||||
TupleDescFinalize(tupdesc);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -1853,6 +1856,8 @@ build_function_result_tupdesc_d(char prokind,
|
|||
0);
|
||||
}
|
||||
|
||||
TupleDescFinalize(desc);
|
||||
|
||||
return desc;
|
||||
}
|
||||
|
||||
|
|
@ -1970,6 +1975,7 @@ TypeGetTupleDesc(Oid typeoid, List *colaliases)
|
|||
typeoid,
|
||||
-1,
|
||||
0);
|
||||
TupleDescFinalize(tupdesc);
|
||||
}
|
||||
else if (functypclass == TYPEFUNC_RECORD)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -444,6 +444,7 @@ GetPGVariableResultDesc(const char *name)
|
|||
TupleDescInitEntry(tupdesc, (AttrNumber) 1, varname,
|
||||
TEXTOID, -1, 0);
|
||||
}
|
||||
TupleDescFinalize(tupdesc);
|
||||
return tupdesc;
|
||||
}
|
||||
|
||||
|
|
@ -465,6 +466,7 @@ ShowGUCConfigOption(const char *name, DestReceiver *dest)
|
|||
tupdesc = CreateTemplateTupleDesc(1);
|
||||
TupleDescInitBuiltinEntry(tupdesc, (AttrNumber) 1, varname,
|
||||
TEXTOID, -1, 0);
|
||||
TupleDescFinalize(tupdesc);
|
||||
|
||||
/* prepare for projection of tuples */
|
||||
tstate = begin_tup_output_tupdesc(dest, tupdesc, &TTSOpsVirtual);
|
||||
|
|
@ -499,6 +501,7 @@ ShowAllGUCConfig(DestReceiver *dest)
|
|||
TEXTOID, -1, 0);
|
||||
TupleDescInitBuiltinEntry(tupdesc, (AttrNumber) 3, "description",
|
||||
TEXTOID, -1, 0);
|
||||
TupleDescFinalize(tupdesc);
|
||||
|
||||
/* prepare for projection of tuples */
|
||||
tstate = begin_tup_output_tupdesc(dest, tupdesc, &TTSOpsVirtual);
|
||||
|
|
@ -934,6 +937,8 @@ show_all_settings(PG_FUNCTION_ARGS)
|
|||
TupleDescInitEntry(tupdesc, (AttrNumber) 17, "pending_restart",
|
||||
BOOLOID, -1, 0);
|
||||
|
||||
TupleDescFinalize(tupdesc);
|
||||
|
||||
/*
|
||||
* Generate attribute metadata needed later to produce tuples from raw
|
||||
* C strings
|
||||
|
|
|
|||
|
|
@ -195,6 +195,7 @@ extern TupleDesc CreateTupleDescTruncatedCopy(TupleDesc tupdesc, int natts);
|
|||
|
||||
extern TupleDesc CreateTupleDescCopyConstr(TupleDesc tupdesc);
|
||||
|
||||
#define TupleDescFinalize(d) ((void) 0)
|
||||
#define TupleDescSize(src) \
|
||||
(offsetof(struct TupleDescData, compact_attrs) + \
|
||||
(src)->natts * sizeof(CompactAttribute) + \
|
||||
|
|
|
|||
|
|
@ -1912,6 +1912,8 @@ build_row_from_vars(PLpgSQL_variable **vars, int numvars)
|
|||
TupleDescInitEntryCollation(row->rowtupdesc, i + 1, typcoll);
|
||||
}
|
||||
|
||||
TupleDescFinalize(row->rowtupdesc);
|
||||
|
||||
return row;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -206,6 +206,7 @@ test_custom_stats_fixed_report(PG_FUNCTION_ARGS)
|
|||
INT8OID, -1, 0);
|
||||
TupleDescInitEntry(tupdesc, (AttrNumber) 2, "stats_reset",
|
||||
TIMESTAMPTZOID, -1, 0);
|
||||
TupleDescFinalize(tupdesc);
|
||||
BlessTupleDesc(tupdesc);
|
||||
|
||||
values[0] = Int64GetDatum(stats->numcalls);
|
||||
|
|
|
|||
|
|
@ -230,6 +230,7 @@ test_predtest(PG_FUNCTION_ARGS)
|
|||
"s_r_holds", BOOLOID, -1, 0);
|
||||
TupleDescInitEntry(tupdesc, (AttrNumber) 8,
|
||||
"w_r_holds", BOOLOID, -1, 0);
|
||||
TupleDescFinalize(tupdesc);
|
||||
tupdesc = BlessTupleDesc(tupdesc);
|
||||
|
||||
values[0] = BoolGetDatum(strong_implied_by);
|
||||
|
|
|
|||
Loading…
Reference in a new issue