Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit5b81703

Browse files
committed
Simplify SRFs using materialize mode in contrib/ modules
9e98583 introduced a helper to centralize building their needed state(tuplestore, tuple descriptors, etc.), checking for any errors. Thiscommit updates all places of contrib/ that can be switched to useSetSingleFuncCall() as a drop-in replacement, resulting in the removalof a lot of boilerplate code in all the modules updated by this commit.Per analysis, some places remain as they are:- pg_logdir_ls() in adminpack/ uses historically TYPEFUNC_RECORD asreturn type, and I suspect that changing it may cause issues at run-timewith some of its past versions, down to 1.0.- dblink/ uses a wrapper function doing exactly the work ofSetSingleFuncCall(). Here the switch should be possible, but ratherinvasive so it does not seem the extra backpatch maintenance cost.- tablefunc/, similarly, uses multiple helper functions with portions ofSetSingleFuncCall() spread across the code paths of this module.Author: Melanie PlagemanDiscussion:https://postgr.es/m/CAAKRu_bvDPJoL9mH6eYwvBpPtTGQwbDzfJbCM-OjkSZDu5yTPg@mail.gmail.com
1 parentd5ed9da commit5b81703

File tree

8 files changed

+32
-301
lines changed

8 files changed

+32
-301
lines changed

‎contrib/amcheck/verify_heapam.c

Lines changed: 4 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,6 @@ static bool check_tuple_visibility(HeapCheckContext *ctx);
165165
staticvoidreport_corruption(HeapCheckContext*ctx,char*msg);
166166
staticvoidreport_toast_corruption(HeapCheckContext*ctx,
167167
ToastedAttribute*ta,char*msg);
168-
staticTupleDescverify_heapam_tupdesc(void);
169168
staticFullTransactionIdFullTransactionIdFromXidAndCtx(TransactionIdxid,
170169
constHeapCheckContext*ctx);
171170
staticvoidupdate_cached_xid_range(HeapCheckContext*ctx);
@@ -214,8 +213,6 @@ Datum
214213
verify_heapam(PG_FUNCTION_ARGS)
215214
{
216215
ReturnSetInfo*rsinfo= (ReturnSetInfo*)fcinfo->resultinfo;
217-
MemoryContextold_context;
218-
boolrandom_access;
219216
HeapCheckContextctx;
220217
Buffervmbuffer=InvalidBuffer;
221218
Oidrelid;
@@ -227,16 +224,6 @@ verify_heapam(PG_FUNCTION_ARGS)
227224
BlockNumbernblocks;
228225
constchar*skip;
229226

230-
/* Check to see if caller supports us returning a tuplestore */
231-
if (rsinfo==NULL|| !IsA(rsinfo,ReturnSetInfo))
232-
ereport(ERROR,
233-
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
234-
errmsg("set-valued function called in context that cannot accept a set")));
235-
if (!(rsinfo->allowedModes&SFRM_Materialize))
236-
ereport(ERROR,
237-
(errcode(ERRCODE_SYNTAX_ERROR),
238-
errmsg("materialize mode required, but it is not allowed in this context")));
239-
240227
/* Check supplied arguments */
241228
if (PG_ARGISNULL(0))
242229
ereport(ERROR,
@@ -290,15 +277,10 @@ verify_heapam(PG_FUNCTION_ARGS)
290277
*/
291278
ctx.attnum=-1;
292279

293-
/* The tupdesc and tuplestore must be created in ecxt_per_query_memory */
294-
old_context=MemoryContextSwitchTo(rsinfo->econtext->ecxt_per_query_memory);
295-
random_access= (rsinfo->allowedModes&SFRM_Materialize_Random)!=0;
296-
ctx.tupdesc=verify_heapam_tupdesc();
297-
ctx.tupstore=tuplestore_begin_heap(random_access, false,work_mem);
298-
rsinfo->returnMode=SFRM_Materialize;
299-
rsinfo->setResult=ctx.tupstore;
300-
rsinfo->setDesc=ctx.tupdesc;
301-
MemoryContextSwitchTo(old_context);
280+
/* Construct the tuplestore and tuple descriptor */
281+
SetSingleFuncCall(fcinfo,0);
282+
ctx.tupdesc=rsinfo->setDesc;
283+
ctx.tupstore=rsinfo->setResult;
302284

303285
/* Open relation, check relkind and access method */
304286
ctx.rel=relation_open(relid,AccessShareLock);
@@ -630,26 +612,6 @@ report_toast_corruption(HeapCheckContext *ctx, ToastedAttribute *ta,
630612
ctx->is_corrupt= true;
631613
}
632614

633-
/*
634-
* Construct the TupleDesc used to report messages about corruptions found
635-
* while scanning the heap.
636-
*/
637-
staticTupleDesc
638-
verify_heapam_tupdesc(void)
639-
{
640-
TupleDesctupdesc;
641-
AttrNumbera=0;
642-
643-
tupdesc=CreateTemplateTupleDesc(HEAPCHECK_RELATION_COLS);
644-
TupleDescInitEntry(tupdesc,++a,"blkno",INT8OID,-1,0);
645-
TupleDescInitEntry(tupdesc,++a,"offnum",INT4OID,-1,0);
646-
TupleDescInitEntry(tupdesc,++a,"attnum",INT4OID,-1,0);
647-
TupleDescInitEntry(tupdesc,++a,"msg",TEXTOID,-1,0);
648-
Assert(a==HEAPCHECK_RELATION_COLS);
649-
650-
returnBlessTupleDesc(tupdesc);
651-
}
652-
653615
/*
654616
* Check for tuple header corruption.
655617
*

‎contrib/dblink/dblink.c

Lines changed: 2 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1928,36 +1928,14 @@ dblink_get_notify(PG_FUNCTION_ARGS)
19281928
PGconn*conn;
19291929
PGnotify*notify;
19301930
ReturnSetInfo*rsinfo= (ReturnSetInfo*)fcinfo->resultinfo;
1931-
TupleDesctupdesc;
1932-
Tuplestorestate*tupstore;
1933-
MemoryContextper_query_ctx;
1934-
MemoryContextoldcontext;
1935-
1936-
prepTuplestoreResult(fcinfo);
19371931

19381932
dblink_init();
19391933
if (PG_NARGS()==1)
19401934
conn=dblink_get_named_conn(text_to_cstring(PG_GETARG_TEXT_PP(0)));
19411935
else
19421936
conn=pconn->conn;
19431937

1944-
/* create the tuplestore in per-query memory */
1945-
per_query_ctx=rsinfo->econtext->ecxt_per_query_memory;
1946-
oldcontext=MemoryContextSwitchTo(per_query_ctx);
1947-
1948-
tupdesc=CreateTemplateTupleDesc(DBLINK_NOTIFY_COLS);
1949-
TupleDescInitEntry(tupdesc, (AttrNumber)1,"notify_name",
1950-
TEXTOID,-1,0);
1951-
TupleDescInitEntry(tupdesc, (AttrNumber)2,"be_pid",
1952-
INT4OID,-1,0);
1953-
TupleDescInitEntry(tupdesc, (AttrNumber)3,"extra",
1954-
TEXTOID,-1,0);
1955-
1956-
tupstore=tuplestore_begin_heap(true, false,work_mem);
1957-
rsinfo->setResult=tupstore;
1958-
rsinfo->setDesc=tupdesc;
1959-
1960-
MemoryContextSwitchTo(oldcontext);
1938+
SetSingleFuncCall(fcinfo,0);
19611939

19621940
PQconsumeInput(conn);
19631941
while ((notify=PQnotifies(conn))!=NULL)
@@ -1980,7 +1958,7 @@ dblink_get_notify(PG_FUNCTION_ARGS)
19801958
else
19811959
nulls[2]= true;
19821960

1983-
tuplestore_putvalues(tupstore,tupdesc,values,nulls);
1961+
tuplestore_putvalues(rsinfo->setResult,rsinfo->setDesc,values,nulls);
19841962

19851963
PQfreemem(notify);
19861964
PQconsumeInput(conn);

‎contrib/pageinspect/brinfuncs.c

Lines changed: 3 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -126,9 +126,6 @@ brin_page_items(PG_FUNCTION_ARGS)
126126
bytea*raw_page=PG_GETARG_BYTEA_P(0);
127127
OidindexRelid=PG_GETARG_OID(1);
128128
ReturnSetInfo*rsinfo= (ReturnSetInfo*)fcinfo->resultinfo;
129-
TupleDesctupdesc;
130-
MemoryContextoldcontext;
131-
Tuplestorestate*tupstore;
132129
RelationindexRel;
133130
brin_column_state**columns;
134131
BrinDesc*bdesc;
@@ -143,29 +140,7 @@ brin_page_items(PG_FUNCTION_ARGS)
143140
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
144141
errmsg("must be superuser to use raw page functions")));
145142

146-
/* check to see if caller supports us returning a tuplestore */
147-
if (rsinfo==NULL|| !IsA(rsinfo,ReturnSetInfo))
148-
ereport(ERROR,
149-
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
150-
errmsg("set-valued function called in context that cannot accept a set")));
151-
if (!(rsinfo->allowedModes&SFRM_Materialize))
152-
ereport(ERROR,
153-
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
154-
errmsg("materialize mode required, but it is not allowed in this context")));
155-
156-
/* Build a tuple descriptor for our result type */
157-
if (get_call_result_type(fcinfo,NULL,&tupdesc)!=TYPEFUNC_COMPOSITE)
158-
elog(ERROR,"return type must be a row type");
159-
160-
/* Build tuplestore to hold the result rows */
161-
oldcontext=MemoryContextSwitchTo(rsinfo->econtext->ecxt_per_query_memory);
162-
163-
tupstore=tuplestore_begin_heap(true, false,work_mem);
164-
rsinfo->returnMode=SFRM_Materialize;
165-
rsinfo->setResult=tupstore;
166-
rsinfo->setDesc=tupdesc;
167-
168-
MemoryContextSwitchTo(oldcontext);
143+
SetSingleFuncCall(fcinfo,0);
169144

170145
indexRel=index_open(indexRelid,AccessShareLock);
171146
bdesc=brin_build_desc(indexRel);
@@ -251,7 +226,7 @@ brin_page_items(PG_FUNCTION_ARGS)
251226
intatt=attno-1;
252227

253228
values[0]=UInt16GetDatum(offset);
254-
switch (TupleDescAttr(tupdesc,1)->atttypid)
229+
switch (TupleDescAttr(rsinfo->setDesc,1)->atttypid)
255230
{
256231
caseINT8OID:
257232
values[1]=Int64GetDatum((int64)dtup->bt_blkno);
@@ -301,7 +276,7 @@ brin_page_items(PG_FUNCTION_ARGS)
301276
}
302277
}
303278

304-
tuplestore_putvalues(tupstore,tupdesc,values,nulls);
279+
tuplestore_putvalues(rsinfo->setResult,rsinfo->setDesc,values,nulls);
305280

306281
/*
307282
* If the item was unused, jump straight to the next one; otherwise,

‎contrib/pageinspect/gistfuncs.c

Lines changed: 4 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -97,10 +97,6 @@ gist_page_items_bytea(PG_FUNCTION_ARGS)
9797
{
9898
bytea*raw_page=PG_GETARG_BYTEA_P(0);
9999
ReturnSetInfo*rsinfo= (ReturnSetInfo*)fcinfo->resultinfo;
100-
boolrandomAccess;
101-
TupleDesctupdesc;
102-
Tuplestorestate*tupstore;
103-
MemoryContextoldcontext;
104100
Pagepage;
105101
OffsetNumberoffset;
106102
OffsetNumbermaxoff=InvalidOffsetNumber;
@@ -110,29 +106,7 @@ gist_page_items_bytea(PG_FUNCTION_ARGS)
110106
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
111107
errmsg("must be superuser to use raw page functions")));
112108

113-
/* check to see if caller supports us returning a tuplestore */
114-
if (rsinfo==NULL|| !IsA(rsinfo,ReturnSetInfo))
115-
ereport(ERROR,
116-
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
117-
errmsg("set-valued function called in context that cannot accept a set")));
118-
if (!(rsinfo->allowedModes&SFRM_Materialize))
119-
ereport(ERROR,
120-
(errcode(ERRCODE_SYNTAX_ERROR),
121-
errmsg("materialize mode required, but it is not allowed in this context")));
122-
123-
/* The tupdesc and tuplestore must be created in ecxt_per_query_memory */
124-
oldcontext=MemoryContextSwitchTo(rsinfo->econtext->ecxt_per_query_memory);
125-
126-
if (get_call_result_type(fcinfo,NULL,&tupdesc)!=TYPEFUNC_COMPOSITE)
127-
elog(ERROR,"return type must be a row type");
128-
129-
randomAccess= (rsinfo->allowedModes&SFRM_Materialize_Random)!=0;
130-
tupstore=tuplestore_begin_heap(randomAccess, false,work_mem);
131-
rsinfo->returnMode=SFRM_Materialize;
132-
rsinfo->setResult=tupstore;
133-
rsinfo->setDesc=tupdesc;
134-
135-
MemoryContextSwitchTo(oldcontext);
109+
SetSingleFuncCall(fcinfo,0);
136110

137111
page=get_page_from_raw(raw_page);
138112

@@ -173,7 +147,7 @@ gist_page_items_bytea(PG_FUNCTION_ARGS)
173147
values[3]=BoolGetDatum(ItemIdIsDead(id));
174148
values[4]=PointerGetDatum(tuple_bytea);
175149

176-
tuplestore_putvalues(tupstore,tupdesc,values,nulls);
150+
tuplestore_putvalues(rsinfo->setResult,rsinfo->setDesc,values,nulls);
177151
}
178152

179153
return (Datum)0;
@@ -185,11 +159,7 @@ gist_page_items(PG_FUNCTION_ARGS)
185159
bytea*raw_page=PG_GETARG_BYTEA_P(0);
186160
OidindexRelid=PG_GETARG_OID(1);
187161
ReturnSetInfo*rsinfo= (ReturnSetInfo*)fcinfo->resultinfo;
188-
boolrandomAccess;
189162
RelationindexRel;
190-
TupleDesctupdesc;
191-
Tuplestorestate*tupstore;
192-
MemoryContextoldcontext;
193163
Pagepage;
194164
OffsetNumberoffset;
195165
OffsetNumbermaxoff=InvalidOffsetNumber;
@@ -199,29 +169,7 @@ gist_page_items(PG_FUNCTION_ARGS)
199169
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
200170
errmsg("must be superuser to use raw page functions")));
201171

202-
/* check to see if caller supports us returning a tuplestore */
203-
if (rsinfo==NULL|| !IsA(rsinfo,ReturnSetInfo))
204-
ereport(ERROR,
205-
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
206-
errmsg("set-valued function called in context that cannot accept a set")));
207-
if (!(rsinfo->allowedModes&SFRM_Materialize))
208-
ereport(ERROR,
209-
(errcode(ERRCODE_SYNTAX_ERROR),
210-
errmsg("materialize mode required, but it is not allowed in this context")));
211-
212-
/* The tupdesc and tuplestore must be created in ecxt_per_query_memory */
213-
oldcontext=MemoryContextSwitchTo(rsinfo->econtext->ecxt_per_query_memory);
214-
215-
if (get_call_result_type(fcinfo,NULL,&tupdesc)!=TYPEFUNC_COMPOSITE)
216-
elog(ERROR,"return type must be a row type");
217-
218-
randomAccess= (rsinfo->allowedModes&SFRM_Materialize_Random)!=0;
219-
tupstore=tuplestore_begin_heap(randomAccess, false,work_mem);
220-
rsinfo->returnMode=SFRM_Materialize;
221-
rsinfo->setResult=tupstore;
222-
rsinfo->setDesc=tupdesc;
223-
224-
MemoryContextSwitchTo(oldcontext);
172+
SetSingleFuncCall(fcinfo,0);
225173

226174
/* Open the relation */
227175
indexRel=index_open(indexRelid,AccessShareLock);
@@ -272,7 +220,7 @@ gist_page_items(PG_FUNCTION_ARGS)
272220
nulls[4]= true;
273221
}
274222

275-
tuplestore_putvalues(tupstore,tupdesc,values,nulls);
223+
tuplestore_putvalues(rsinfo->setResult,rsinfo->setDesc,values,nulls);
276224
}
277225

278226
relation_close(indexRel,AccessShareLock);

‎contrib/pg_stat_statements/pg_stat_statements.c

Lines changed: 3 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1494,10 +1494,6 @@ pg_stat_statements_internal(FunctionCallInfo fcinfo,
14941494
boolshowtext)
14951495
{
14961496
ReturnSetInfo*rsinfo= (ReturnSetInfo*)fcinfo->resultinfo;
1497-
TupleDesctupdesc;
1498-
Tuplestorestate*tupstore;
1499-
MemoryContextper_query_ctx;
1500-
MemoryContextoldcontext;
15011497
Oiduserid=GetUserId();
15021498
boolis_allowed_role= false;
15031499
char*qbuffer=NULL;
@@ -1516,30 +1512,14 @@ pg_stat_statements_internal(FunctionCallInfo fcinfo,
15161512
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
15171513
errmsg("pg_stat_statements must be loaded via shared_preload_libraries")));
15181514

1519-
/* check to see if caller supports us returning a tuplestore */
1520-
if (rsinfo==NULL|| !IsA(rsinfo,ReturnSetInfo))
1521-
ereport(ERROR,
1522-
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1523-
errmsg("set-valued function called in context that cannot accept a set")));
1524-
if (!(rsinfo->allowedModes&SFRM_Materialize))
1525-
ereport(ERROR,
1526-
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1527-
errmsg("materialize mode required, but it is not allowed in this context")));
1528-
1529-
/* Switch into long-lived context to construct returned data structures */
1530-
per_query_ctx=rsinfo->econtext->ecxt_per_query_memory;
1531-
oldcontext=MemoryContextSwitchTo(per_query_ctx);
1532-
1533-
/* Build a tuple descriptor for our result type */
1534-
if (get_call_result_type(fcinfo,NULL,&tupdesc)!=TYPEFUNC_COMPOSITE)
1535-
elog(ERROR,"return type must be a row type");
1515+
SetSingleFuncCall(fcinfo,0);
15361516

15371517
/*
15381518
* Check we have the expected number of output arguments. Aside from
15391519
* being a good safety check, we need a kluge here to detect API version
15401520
* 1.1, which was wedged into the code in an ill-considered way.
15411521
*/
1542-
switch (tupdesc->natts)
1522+
switch (rsinfo->setDesc->natts)
15431523
{
15441524
casePG_STAT_STATEMENTS_COLS_V1_0:
15451525
if (api_version!=PGSS_V1_0)
@@ -1571,13 +1551,6 @@ pg_stat_statements_internal(FunctionCallInfo fcinfo,
15711551
elog(ERROR,"incorrect number of output arguments");
15721552
}
15731553

1574-
tupstore=tuplestore_begin_heap(true, false,work_mem);
1575-
rsinfo->returnMode=SFRM_Materialize;
1576-
rsinfo->setResult=tupstore;
1577-
rsinfo->setDesc=tupdesc;
1578-
1579-
MemoryContextSwitchTo(oldcontext);
1580-
15811554
/*
15821555
* We'd like to load the query text file (if needed) while not holding any
15831556
* lock on pgss->lock. In the worst case we'll have to do this again
@@ -1800,7 +1773,7 @@ pg_stat_statements_internal(FunctionCallInfo fcinfo,
18001773
api_version==PGSS_V1_9 ?PG_STAT_STATEMENTS_COLS_V1_9 :
18011774
-1/* fail if you forget to update this assert */ ));
18021775

1803-
tuplestore_putvalues(tupstore,tupdesc,values,nulls);
1776+
tuplestore_putvalues(rsinfo->setResult,rsinfo->setDesc,values,nulls);
18041777
}
18051778

18061779
LWLockRelease(pgss->lock);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp