Skip to content

Commit 22e3b55

Browse files
committed
Switch some system functions to use get_call_result_type()
This shaves some code by replacing the combinations of CreateTemplateTupleDesc()/TupleDescInitEntry() hardcoding a mapping of the attributes listed in pg_proc.dat by get_call_result_type() to build the TupleDesc needed for the rows generated. get_call_result_type() is more expensive than the former style, but this removes some duplication with the lists of OUT parameters (pg_proc.dat and the attributes hardcoded in these code paths). This is applied to functions that are not considered as critical (aka that could be called repeatedly for monitoring purposes). Author: Bharath Rupireddy Reviewed-by: Robert Haas, Álvaro Herrera, Tom Lane, Michael Paquier Discussion: https://postgr.es/m/CALj2ACV23HW5HP5hFjd89FNS-z5X8r2jNXdMXcpN2BgTtKd87w@mail.gmail.com
1 parent f03bd57 commit 22e3b55

File tree

12 files changed

+62
-286
lines changed

12 files changed

+62
-286
lines changed

contrib/old_snapshot/time_mapping.c

Lines changed: 4 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ PG_MODULE_MAGIC;
3838
PG_FUNCTION_INFO_V1(pg_old_snapshot_time_mapping);
3939

4040
static OldSnapshotTimeMapping *GetOldSnapshotTimeMapping(void);
41-
static TupleDesc MakeOldSnapshotTimeMappingTupleDesc(void);
4241
static HeapTuple MakeOldSnapshotTimeMappingTuple(TupleDesc tupdesc,
4342
OldSnapshotTimeMapping *mapping);
4443

@@ -54,12 +53,15 @@ pg_old_snapshot_time_mapping(PG_FUNCTION_ARGS)
5453
if (SRF_IS_FIRSTCALL())
5554
{
5655
MemoryContext oldcontext;
56+
TupleDesc tupdesc;
5757

5858
funcctx = SRF_FIRSTCALL_INIT();
5959
oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
6060
mapping = GetOldSnapshotTimeMapping();
6161
funcctx->user_fctx = mapping;
62-
funcctx->tuple_desc = MakeOldSnapshotTimeMappingTupleDesc();
62+
if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
63+
elog(ERROR, "return type must be a row type");
64+
funcctx->tuple_desc = tupdesc;
6365
MemoryContextSwitchTo(oldcontext);
6466
}
6567

@@ -101,26 +103,6 @@ GetOldSnapshotTimeMapping(void)
101103
return mapping;
102104
}
103105

104-
/*
105-
* Build a tuple descriptor for the pg_old_snapshot_time_mapping() SRF.
106-
*/
107-
static TupleDesc
108-
MakeOldSnapshotTimeMappingTupleDesc(void)
109-
{
110-
TupleDesc tupdesc;
111-
112-
tupdesc = CreateTemplateTupleDesc(NUM_TIME_MAPPING_COLUMNS);
113-
114-
TupleDescInitEntry(tupdesc, (AttrNumber) 1, "array_offset",
115-
INT4OID, -1, 0);
116-
TupleDescInitEntry(tupdesc, (AttrNumber) 2, "end_timestamp",
117-
TIMESTAMPTZOID, -1, 0);
118-
TupleDescInitEntry(tupdesc, (AttrNumber) 3, "newest_xmin",
119-
XIDOID, -1, 0);
120-
121-
return BlessTupleDesc(tupdesc);
122-
}
123-
124106
/*
125107
* Convert one entry from the old snapshot time mapping to a HeapTuple.
126108
*/

contrib/pg_visibility/pg_visibility.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -291,10 +291,8 @@ pg_visibility_map_summary(PG_FUNCTION_ARGS)
291291
ReleaseBuffer(vmbuffer);
292292
relation_close(rel, AccessShareLock);
293293

294-
tupdesc = CreateTemplateTupleDesc(2);
295-
TupleDescInitEntry(tupdesc, (AttrNumber) 1, "all_visible", INT8OID, -1, 0);
296-
TupleDescInitEntry(tupdesc, (AttrNumber) 2, "all_frozen", INT8OID, -1, 0);
297-
tupdesc = BlessTupleDesc(tupdesc);
294+
if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
295+
elog(ERROR, "return type must be a row type");
298296

299297
values[0] = Int64GetDatum(all_visible);
300298
values[1] = Int64GetDatum(all_frozen);

src/backend/access/transam/commit_ts.c

Lines changed: 4 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -422,18 +422,8 @@ pg_last_committed_xact(PG_FUNCTION_ARGS)
422422
/* and construct a tuple with our data */
423423
xid = GetLatestCommitTsData(&ts, &nodeid);
424424

425-
/*
426-
* Construct a tuple descriptor for the result row. This must match this
427-
* function's pg_proc entry!
428-
*/
429-
tupdesc = CreateTemplateTupleDesc(3);
430-
TupleDescInitEntry(tupdesc, (AttrNumber) 1, "xid",
431-
XIDOID, -1, 0);
432-
TupleDescInitEntry(tupdesc, (AttrNumber) 2, "timestamp",
433-
TIMESTAMPTZOID, -1, 0);
434-
TupleDescInitEntry(tupdesc, (AttrNumber) 3, "roident",
435-
OIDOID, -1, 0);
436-
tupdesc = BlessTupleDesc(tupdesc);
425+
if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
426+
elog(ERROR, "return type must be a row type");
437427

438428
if (!TransactionIdIsNormal(xid))
439429
{
@@ -476,16 +466,8 @@ pg_xact_commit_timestamp_origin(PG_FUNCTION_ARGS)
476466

477467
found = TransactionIdGetCommitTsData(xid, &ts, &nodeid);
478468

479-
/*
480-
* Construct a tuple descriptor for the result row. This must match this
481-
* function's pg_proc entry!
482-
*/
483-
tupdesc = CreateTemplateTupleDesc(2);
484-
TupleDescInitEntry(tupdesc, (AttrNumber) 1, "timestamp",
485-
TIMESTAMPTZOID, -1, 0);
486-
TupleDescInitEntry(tupdesc, (AttrNumber) 2, "roident",
487-
OIDOID, -1, 0);
488-
tupdesc = BlessTupleDesc(tupdesc);
469+
if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
470+
elog(ERROR, "return type must be a row type");
489471

490472
if (!found)
491473
{

src/backend/access/transam/multixact.c

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3373,12 +3373,9 @@ pg_get_multixact_members(PG_FUNCTION_ARGS)
33733373
false);
33743374
multi->iter = 0;
33753375

3376-
tupdesc = CreateTemplateTupleDesc(2);
3377-
TupleDescInitEntry(tupdesc, (AttrNumber) 1, "xid",
3378-
XIDOID, -1, 0);
3379-
TupleDescInitEntry(tupdesc, (AttrNumber) 2, "mode",
3380-
TEXTOID, -1, 0);
3381-
3376+
if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
3377+
elog(ERROR, "return type must be a row type");
3378+
funccxt->tuple_desc = tupdesc;
33823379
funccxt->attinmeta = TupleDescGetAttInMetadata(tupdesc);
33833380
funccxt->user_fctx = multi;
33843381

src/backend/catalog/objectaddress.c

Lines changed: 6 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -2397,14 +2397,8 @@ pg_get_object_address(PG_FUNCTION_ARGS)
23972397
if (relation)
23982398
relation_close(relation, AccessShareLock);
23992399

2400-
tupdesc = CreateTemplateTupleDesc(3);
2401-
TupleDescInitEntry(tupdesc, (AttrNumber) 1, "classid",
2402-
OIDOID, -1, 0);
2403-
TupleDescInitEntry(tupdesc, (AttrNumber) 2, "objid",
2404-
OIDOID, -1, 0);
2405-
TupleDescInitEntry(tupdesc, (AttrNumber) 3, "objsubid",
2406-
INT4OID, -1, 0);
2407-
tupdesc = BlessTupleDesc(tupdesc);
2400+
if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
2401+
elog(ERROR, "return type must be a row type");
24082402

24092403
values[0] = ObjectIdGetDatum(addr.classId);
24102404
values[1] = ObjectIdGetDatum(addr.objectId);
@@ -4244,21 +4238,8 @@ pg_identify_object(PG_FUNCTION_ARGS)
42444238
address.objectId = objid;
42454239
address.objectSubId = objsubid;
42464240

4247-
/*
4248-
* Construct a tuple descriptor for the result row. This must match this
4249-
* function's pg_proc entry!
4250-
*/
4251-
tupdesc = CreateTemplateTupleDesc(4);
4252-
TupleDescInitEntry(tupdesc, (AttrNumber) 1, "type",
4253-
TEXTOID, -1, 0);
4254-
TupleDescInitEntry(tupdesc, (AttrNumber) 2, "schema",
4255-
TEXTOID, -1, 0);
4256-
TupleDescInitEntry(tupdesc, (AttrNumber) 3, "name",
4257-
TEXTOID, -1, 0);
4258-
TupleDescInitEntry(tupdesc, (AttrNumber) 4, "identity",
4259-
TEXTOID, -1, 0);
4260-
4261-
tupdesc = BlessTupleDesc(tupdesc);
4241+
if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
4242+
elog(ERROR, "return type must be a row type");
42624243

42634244
if (is_objectclass_supported(address.classId))
42644245
{
@@ -4374,19 +4355,8 @@ pg_identify_object_as_address(PG_FUNCTION_ARGS)
43744355
address.objectId = objid;
43754356
address.objectSubId = objsubid;
43764357

4377-
/*
4378-
* Construct a tuple descriptor for the result row. This must match this
4379-
* function's pg_proc entry!
4380-
*/
4381-
tupdesc = CreateTemplateTupleDesc(3);
4382-
TupleDescInitEntry(tupdesc, (AttrNumber) 1, "type",
4383-
TEXTOID, -1, 0);
4384-
TupleDescInitEntry(tupdesc, (AttrNumber) 2, "object_names",
4385-
TEXTARRAYOID, -1, 0);
4386-
TupleDescInitEntry(tupdesc, (AttrNumber) 3, "object_args",
4387-
TEXTARRAYOID, -1, 0);
4388-
4389-
tupdesc = BlessTupleDesc(tupdesc);
4358+
if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
4359+
elog(ERROR, "return type must be a row type");
43904360

43914361
/* object type, which can never be NULL */
43924362
values[0] = CStringGetTextDatum(getObjectTypeDescription(&address, true));

src/backend/commands/sequence.c

Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1762,23 +1762,8 @@ pg_sequence_parameters(PG_FUNCTION_ARGS)
17621762
errmsg("permission denied for sequence %s",
17631763
get_rel_name(relid))));
17641764

1765-
tupdesc = CreateTemplateTupleDesc(7);
1766-
TupleDescInitEntry(tupdesc, (AttrNumber) 1, "start_value",
1767-
INT8OID, -1, 0);
1768-
TupleDescInitEntry(tupdesc, (AttrNumber) 2, "minimum_value",
1769-
INT8OID, -1, 0);
1770-
TupleDescInitEntry(tupdesc, (AttrNumber) 3, "maximum_value",
1771-
INT8OID, -1, 0);
1772-
TupleDescInitEntry(tupdesc, (AttrNumber) 4, "increment",
1773-
INT8OID, -1, 0);
1774-
TupleDescInitEntry(tupdesc, (AttrNumber) 5, "cycle_option",
1775-
BOOLOID, -1, 0);
1776-
TupleDescInitEntry(tupdesc, (AttrNumber) 6, "cache_size",
1777-
INT8OID, -1, 0);
1778-
TupleDescInitEntry(tupdesc, (AttrNumber) 7, "data_type",
1779-
OIDOID, -1, 0);
1780-
1781-
BlessTupleDesc(tupdesc);
1765+
if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
1766+
elog(ERROR, "return type must be a row type");
17821767

17831768
memset(isnull, 0, sizeof(isnull));
17841769

src/backend/tsearch/wparser.c

Lines changed: 15 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,8 @@ typedef struct HeadlineJsonState
4646
static text *headline_json_value(void *_state, char *elem_value, int elem_len);
4747

4848
static void
49-
tt_setup_firstcall(FuncCallContext *funcctx, Oid prsid)
49+
tt_setup_firstcall(FuncCallContext *funcctx, FunctionCallInfo fcinfo,
50+
Oid prsid)
5051
{
5152
TupleDesc tupdesc;
5253
MemoryContext oldcontext;
@@ -66,15 +67,11 @@ tt_setup_firstcall(FuncCallContext *funcctx, Oid prsid)
6667
(Datum) 0));
6768
funcctx->user_fctx = (void *) st;
6869

69-
tupdesc = CreateTemplateTupleDesc(3);
70-
TupleDescInitEntry(tupdesc, (AttrNumber) 1, "tokid",
71-
INT4OID, -1, 0);
72-
TupleDescInitEntry(tupdesc, (AttrNumber) 2, "alias",
73-
TEXTOID, -1, 0);
74-
TupleDescInitEntry(tupdesc, (AttrNumber) 3, "description",
75-
TEXTOID, -1, 0);
76-
70+
if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
71+
elog(ERROR, "return type must be a row type");
72+
funcctx->tuple_desc = tupdesc;
7773
funcctx->attinmeta = TupleDescGetAttInMetadata(tupdesc);
74+
7875
MemoryContextSwitchTo(oldcontext);
7976
}
8077

@@ -116,7 +113,7 @@ ts_token_type_byid(PG_FUNCTION_ARGS)
116113
if (SRF_IS_FIRSTCALL())
117114
{
118115
funcctx = SRF_FIRSTCALL_INIT();
119-
tt_setup_firstcall(funcctx, PG_GETARG_OID(0));
116+
tt_setup_firstcall(funcctx, fcinfo, PG_GETARG_OID(0));
120117
}
121118

122119
funcctx = SRF_PERCALL_SETUP();
@@ -139,7 +136,7 @@ ts_token_type_byname(PG_FUNCTION_ARGS)
139136

140137
funcctx = SRF_FIRSTCALL_INIT();
141138
prsId = get_ts_parser_oid(textToQualifiedNameList(prsname), false);
142-
tt_setup_firstcall(funcctx, prsId);
139+
tt_setup_firstcall(funcctx, fcinfo, prsId);
143140
}
144141

145142
funcctx = SRF_PERCALL_SETUP();
@@ -164,7 +161,8 @@ typedef struct
164161

165162

166163
static void
167-
prs_setup_firstcall(FuncCallContext *funcctx, Oid prsid, text *txt)
164+
prs_setup_firstcall(FuncCallContext *funcctx, FunctionCallInfo fcinfo,
165+
Oid prsid, text *txt)
168166
{
169167
TupleDesc tupdesc;
170168
MemoryContext oldcontext;
@@ -209,12 +207,9 @@ prs_setup_firstcall(FuncCallContext *funcctx, Oid prsid, text *txt)
209207
st->cur = 0;
210208

211209
funcctx->user_fctx = (void *) st;
212-
tupdesc = CreateTemplateTupleDesc(2);
213-
TupleDescInitEntry(tupdesc, (AttrNumber) 1, "tokid",
214-
INT4OID, -1, 0);
215-
TupleDescInitEntry(tupdesc, (AttrNumber) 2, "token",
216-
TEXTOID, -1, 0);
217-
210+
if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
211+
elog(ERROR, "return type must be a row type");
212+
funcctx->tuple_desc = tupdesc;
218213
funcctx->attinmeta = TupleDescGetAttInMetadata(tupdesc);
219214
MemoryContextSwitchTo(oldcontext);
220215
}
@@ -256,7 +251,7 @@ ts_parse_byid(PG_FUNCTION_ARGS)
256251
text *txt = PG_GETARG_TEXT_PP(1);
257252

258253
funcctx = SRF_FIRSTCALL_INIT();
259-
prs_setup_firstcall(funcctx, PG_GETARG_OID(0), txt);
254+
prs_setup_firstcall(funcctx, fcinfo, PG_GETARG_OID(0), txt);
260255
PG_FREE_IF_COPY(txt, 1);
261256
}
262257

@@ -281,7 +276,7 @@ ts_parse_byname(PG_FUNCTION_ARGS)
281276

282277
funcctx = SRF_FIRSTCALL_INIT();
283278
prsId = get_ts_parser_oid(textToQualifiedNameList(prsname), false);
284-
prs_setup_firstcall(funcctx, prsId, txt);
279+
prs_setup_firstcall(funcctx, fcinfo, prsId, txt);
285280
}
286281

287282
funcctx = SRF_PERCALL_SETUP();

src/backend/utils/adt/datetime.c

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4983,19 +4983,10 @@ pg_timezone_abbrevs(PG_FUNCTION_ARGS)
49834983
*pindex = 0;
49844984
funcctx->user_fctx = (void *) pindex;
49854985

4986-
/*
4987-
* build tupdesc for result tuples. This must match this function's
4988-
* pg_proc entry!
4989-
*/
4990-
tupdesc = CreateTemplateTupleDesc(3);
4991-
TupleDescInitEntry(tupdesc, (AttrNumber) 1, "abbrev",
4992-
TEXTOID, -1, 0);
4993-
TupleDescInitEntry(tupdesc, (AttrNumber) 2, "utc_offset",
4994-
INTERVALOID, -1, 0);
4995-
TupleDescInitEntry(tupdesc, (AttrNumber) 3, "is_dst",
4996-
BOOLOID, -1, 0);
4997-
4998-
funcctx->tuple_desc = BlessTupleDesc(tupdesc);
4986+
if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
4987+
elog(ERROR, "return type must be a row type");
4988+
funcctx->tuple_desc = tupdesc;
4989+
49994990
MemoryContextSwitchTo(oldcontext);
50004991
}
50014992

src/backend/utils/adt/misc.c

Lines changed: 5 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -427,18 +427,9 @@ pg_get_keywords(PG_FUNCTION_ARGS)
427427
funcctx = SRF_FIRSTCALL_INIT();
428428
oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
429429

430-
tupdesc = CreateTemplateTupleDesc(5);
431-
TupleDescInitEntry(tupdesc, (AttrNumber) 1, "word",
432-
TEXTOID, -1, 0);
433-
TupleDescInitEntry(tupdesc, (AttrNumber) 2, "catcode",
434-
CHAROID, -1, 0);
435-
TupleDescInitEntry(tupdesc, (AttrNumber) 3, "barelabel",
436-
BOOLOID, -1, 0);
437-
TupleDescInitEntry(tupdesc, (AttrNumber) 4, "catdesc",
438-
TEXTOID, -1, 0);
439-
TupleDescInitEntry(tupdesc, (AttrNumber) 5, "baredesc",
440-
TEXTOID, -1, 0);
441-
430+
if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
431+
elog(ERROR, "return type must be a row type");
432+
funcctx->tuple_desc = tupdesc;
442433
funcctx->attinmeta = TupleDescGetAttInMetadata(tupdesc);
443434

444435
MemoryContextSwitchTo(oldcontext);
@@ -515,20 +506,8 @@ pg_get_catalog_foreign_keys(PG_FUNCTION_ARGS)
515506
funcctx = SRF_FIRSTCALL_INIT();
516507
oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
517508

518-
tupdesc = CreateTemplateTupleDesc(6);
519-
TupleDescInitEntry(tupdesc, (AttrNumber) 1, "fktable",
520-
REGCLASSOID, -1, 0);
521-
TupleDescInitEntry(tupdesc, (AttrNumber) 2, "fkcols",
522-
TEXTARRAYOID, -1, 0);
523-
TupleDescInitEntry(tupdesc, (AttrNumber) 3, "pktable",
524-
REGCLASSOID, -1, 0);
525-
TupleDescInitEntry(tupdesc, (AttrNumber) 4, "pkcols",
526-
TEXTARRAYOID, -1, 0);
527-
TupleDescInitEntry(tupdesc, (AttrNumber) 5, "is_array",
528-
BOOLOID, -1, 0);
529-
TupleDescInitEntry(tupdesc, (AttrNumber) 6, "is_opt",
530-
BOOLOID, -1, 0);
531-
509+
if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
510+
elog(ERROR, "return type must be a row type");
532511
funcctx->tuple_desc = BlessTupleDesc(tupdesc);
533512

534513
/*

src/backend/utils/adt/partitionfuncs.c

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -88,17 +88,9 @@ pg_partition_tree(PG_FUNCTION_ARGS)
8888
*/
8989
partitions = find_all_inheritors(rootrelid, AccessShareLock, NULL);
9090

91-
tupdesc = CreateTemplateTupleDesc(PG_PARTITION_TREE_COLS);
92-
TupleDescInitEntry(tupdesc, (AttrNumber) 1, "relid",
93-
REGCLASSOID, -1, 0);
94-
TupleDescInitEntry(tupdesc, (AttrNumber) 2, "parentid",
95-
REGCLASSOID, -1, 0);
96-
TupleDescInitEntry(tupdesc, (AttrNumber) 3, "isleaf",
97-
BOOLOID, -1, 0);
98-
TupleDescInitEntry(tupdesc, (AttrNumber) 4, "level",
99-
INT4OID, -1, 0);
100-
101-
funcctx->tuple_desc = BlessTupleDesc(tupdesc);
91+
if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
92+
elog(ERROR, "return type must be a row type");
93+
funcctx->tuple_desc = tupdesc;
10294

10395
/* The only state we need is the partition list */
10496
funcctx->user_fctx = (void *) partitions;

0 commit comments

Comments
 (0)