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

Commitfcc2817

Browse files
committed
Clean up and simplify code in a couple of set-returning functions
The following set-returning functions have their logic simplified, to bemore consistent with other in-core areas:- pg_prepared_statement()'s tuple descriptor is now created withget_call_result_type() instead of being created from scratch, savingfrom some duplication with pg_proc.dat.- show_all_file_settings(), similarly, now uses get_call_result_type()to build its tuple descriptor instead of creating it from scratch.- pg_options_to_table() made use of a static routine called only once.This commit removes this internal routine to make the function easier tofollow.- pg_config() was using a unique logic style, doing checks on the tupledescriptor passed down in expectedDesc, but it has no need to do so.This switches the function to use a tuplestore with a tuple descriptorretrieved from get_call_result_type(), instead.This simplifies an upcoming patch aimed at refactoring the waytuplestores are created and checked in set-returning functions, thischange making sense as its own independent cleanup by shaving somecode.Author: Melanie Plageman, Michael PaquierReviewed-by: Justin PryzbyDiscussion:https://postgr.es/m/CAAKRu_azyd1Z3W_r7Ou4sorTjRCs+PxeHw1CWJeXKofkE6TuZg@mail.gmail.com
1 parent04e706d commitfcc2817

File tree

5 files changed

+48
-128
lines changed

5 files changed

+48
-128
lines changed

‎src/backend/commands/prepare.c

Lines changed: 7 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include"catalog/pg_type.h"
2323
#include"commands/createas.h"
2424
#include"commands/prepare.h"
25+
#include"funcapi.h"
2526
#include"miscadmin.h"
2627
#include"nodes/nodeFuncs.h"
2728
#include"parser/analyze.h"
@@ -716,37 +717,23 @@ pg_prepared_statement(PG_FUNCTION_ARGS)
716717
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
717718
errmsg("materialize mode required, but it is not allowed in this context")));
718719

720+
if (get_call_result_type(fcinfo,NULL,&tupdesc)!=TYPEFUNC_COMPOSITE)
721+
elog(ERROR,"return type must be a row type");
722+
719723
/* need to build tuplestore in query context */
720724
per_query_ctx=rsinfo->econtext->ecxt_per_query_memory;
721725
oldcontext=MemoryContextSwitchTo(per_query_ctx);
722726

723-
/*
724-
* build tupdesc for result tuples. This must match the definition of the
725-
* pg_prepared_statements view in system_views.sql
726-
*/
727-
tupdesc=CreateTemplateTupleDesc(7);
728-
TupleDescInitEntry(tupdesc, (AttrNumber)1,"name",
729-
TEXTOID,-1,0);
730-
TupleDescInitEntry(tupdesc, (AttrNumber)2,"statement",
731-
TEXTOID,-1,0);
732-
TupleDescInitEntry(tupdesc, (AttrNumber)3,"prepare_time",
733-
TIMESTAMPTZOID,-1,0);
734-
TupleDescInitEntry(tupdesc, (AttrNumber)4,"parameter_types",
735-
REGTYPEARRAYOID,-1,0);
736-
TupleDescInitEntry(tupdesc, (AttrNumber)5,"from_sql",
737-
BOOLOID,-1,0);
738-
TupleDescInitEntry(tupdesc, (AttrNumber)6,"generic_plans",
739-
INT8OID,-1,0);
740-
TupleDescInitEntry(tupdesc, (AttrNumber)7,"custom_plans",
741-
INT8OID,-1,0);
742-
743727
/*
744728
* We put all the tuples into a tuplestore in one scan of the hashtable.
745729
* This avoids any issue of the hashtable possibly changing between calls.
746730
*/
747731
tupstore=
748732
tuplestore_begin_heap(rsinfo->allowedModes&SFRM_Materialize_Random,
749733
false,work_mem);
734+
rsinfo->returnMode=SFRM_Materialize;
735+
rsinfo->setResult=tupstore;
736+
rsinfo->setDesc=tupdesc;
750737

751738
/* generate junk in short-term context */
752739
MemoryContextSwitchTo(oldcontext);
@@ -778,10 +765,6 @@ pg_prepared_statement(PG_FUNCTION_ARGS)
778765
}
779766
}
780767

781-
rsinfo->returnMode=SFRM_Materialize;
782-
rsinfo->setResult=tupstore;
783-
rsinfo->setDesc=tupdesc;
784-
785768
return (Datum)0;
786769
}
787770

‎src/backend/foreign/foreign.c

Lines changed: 15 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -499,17 +499,19 @@ IsImportableForeignTable(const char *tablename,
499499

500500

501501
/*
502-
* deflist_to_tuplestore - Helper function to convert DefElem list to
503-
* tuplestore usable in SRF.
502+
* pg_options_to_table - Convert options array to name/value table
503+
*
504+
* This is useful to provide details for information_schema and pg_dump.
504505
*/
505-
staticvoid
506-
deflist_to_tuplestore(ReturnSetInfo*rsinfo,List*options)
506+
Datum
507+
pg_options_to_table(PG_FUNCTION_ARGS)
507508
{
509+
Datumarray=PG_GETARG_DATUM(0);
508510
ListCell*cell;
511+
List*options;
512+
ReturnSetInfo*rsinfo= (ReturnSetInfo*)fcinfo->resultinfo;
509513
TupleDesctupdesc;
510514
Tuplestorestate*tupstore;
511-
Datumvalues[2];
512-
boolnulls[2];
513515
MemoryContextper_query_ctx;
514516
MemoryContextoldcontext;
515517

@@ -524,6 +526,9 @@ deflist_to_tuplestore(ReturnSetInfo *rsinfo, List *options)
524526
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
525527
errmsg("materialize mode required, but it is not allowed in this context")));
526528

529+
options=untransformRelOptions(array);
530+
rsinfo= (ReturnSetInfo*)fcinfo->resultinfo;
531+
527532
per_query_ctx=rsinfo->econtext->ecxt_per_query_memory;
528533
oldcontext=MemoryContextSwitchTo(per_query_ctx);
529534

@@ -536,9 +541,13 @@ deflist_to_tuplestore(ReturnSetInfo *rsinfo, List *options)
536541
rsinfo->setResult=tupstore;
537542
rsinfo->setDesc=tupdesc;
538543

544+
MemoryContextSwitchTo(oldcontext);
545+
539546
foreach(cell,options)
540547
{
541548
DefElem*def=lfirst(cell);
549+
Datumvalues[2];
550+
boolnulls[2];
542551

543552
values[0]=CStringGetTextDatum(def->defname);
544553
nulls[0]= false;
@@ -555,22 +564,6 @@ deflist_to_tuplestore(ReturnSetInfo *rsinfo, List *options)
555564
tuplestore_putvalues(tupstore,tupdesc,values,nulls);
556565
}
557566

558-
MemoryContextSwitchTo(oldcontext);
559-
}
560-
561-
562-
/*
563-
* Convert options array to name/value table. Useful for information
564-
* schema and pg_dump.
565-
*/
566-
Datum
567-
pg_options_to_table(PG_FUNCTION_ARGS)
568-
{
569-
Datumarray=PG_GETARG_DATUM(0);
570-
571-
deflist_to_tuplestore((ReturnSetInfo*)fcinfo->resultinfo,
572-
untransformRelOptions(array));
573-
574567
return (Datum)0;
575568
}
576569

‎src/backend/utils/misc/guc.c

Lines changed: 3 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -10174,30 +10174,16 @@ show_all_file_settings(PG_FUNCTION_ARGS)
1017410174
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1017510175
errmsg("materialize mode required, but it is not allowed in this context")));
1017610176

10177+
if (get_call_result_type(fcinfo,NULL,&tupdesc)!=TYPEFUNC_COMPOSITE)
10178+
elog(ERROR,"return type must be a row type");
10179+
1017710180
/* Scan the config files using current context as workspace */
1017810181
conf=ProcessConfigFileInternal(PGC_SIGHUP, false,DEBUG3);
1017910182

1018010183
/* Switch into long-lived context to construct returned data structures */
1018110184
per_query_ctx=rsinfo->econtext->ecxt_per_query_memory;
1018210185
oldcontext=MemoryContextSwitchTo(per_query_ctx);
1018310186

10184-
/* Build a tuple descriptor for our result type */
10185-
tupdesc=CreateTemplateTupleDesc(NUM_PG_FILE_SETTINGS_ATTS);
10186-
TupleDescInitEntry(tupdesc, (AttrNumber)1,"sourcefile",
10187-
TEXTOID,-1,0);
10188-
TupleDescInitEntry(tupdesc, (AttrNumber)2,"sourceline",
10189-
INT4OID,-1,0);
10190-
TupleDescInitEntry(tupdesc, (AttrNumber)3,"seqno",
10191-
INT4OID,-1,0);
10192-
TupleDescInitEntry(tupdesc, (AttrNumber)4,"name",
10193-
TEXTOID,-1,0);
10194-
TupleDescInitEntry(tupdesc, (AttrNumber)5,"setting",
10195-
TEXTOID,-1,0);
10196-
TupleDescInitEntry(tupdesc, (AttrNumber)6,"applied",
10197-
BOOLOID,-1,0);
10198-
TupleDescInitEntry(tupdesc, (AttrNumber)7,"error",
10199-
TEXTOID,-1,0);
10200-
1020110187
/* Build a tuplestore to return our results in */
1020210188
tupstore=tuplestore_begin_heap(true, false,work_mem);
1020310189
rsinfo->returnMode=SFRM_Materialize;

‎src/backend/utils/misc/pg_config.c

Lines changed: 17 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -26,80 +26,49 @@ pg_config(PG_FUNCTION_ARGS)
2626
{
2727
ReturnSetInfo*rsinfo= (ReturnSetInfo*)fcinfo->resultinfo;
2828
Tuplestorestate*tupstore;
29-
HeapTupletuple;
3029
TupleDesctupdesc;
31-
AttInMetadata*attinmeta;
32-
MemoryContextper_query_ctx;
3330
MemoryContextoldcontext;
3431
ConfigData*configdata;
3532
size_tconfigdata_len;
36-
char*values[2];
3733
inti=0;
3834

3935
/* check to see if caller supports us returning a tuplestore */
4036
if (rsinfo==NULL|| !IsA(rsinfo,ReturnSetInfo))
4137
ereport(ERROR,
4238
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4339
errmsg("set-valued function called in context that cannot accept a set")));
44-
if (!(rsinfo->allowedModes&SFRM_Materialize)||
45-
rsinfo->expectedDesc==NULL)
40+
if (!(rsinfo->allowedModes&SFRM_Materialize))
4641
ereport(ERROR,
4742
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
4843
errmsg("materialize mode required, but it is not allowed in this context")));
4944

50-
per_query_ctx=rsinfo->econtext->ecxt_per_query_memory;
51-
oldcontext=MemoryContextSwitchTo(per_query_ctx);
45+
if (get_call_result_type(fcinfo,NULL,&tupdesc)!=TYPEFUNC_COMPOSITE)
46+
elog(ERROR,"return type must be a row type");
5247

53-
/*get the requested return tuple description */
54-
tupdesc=CreateTupleDescCopy(rsinfo->expectedDesc);
48+
/*Build tuplestore to hold the result rows */
49+
oldcontext=MemoryContextSwitchTo(rsinfo->econtext->ecxt_per_query_memory);
5550

56-
/*
57-
* Check to make sure we have a reasonable tuple descriptor
58-
*/
59-
if (tupdesc->natts!=2||
60-
TupleDescAttr(tupdesc,0)->atttypid!=TEXTOID||
61-
TupleDescAttr(tupdesc,1)->atttypid!=TEXTOID)
62-
ereport(ERROR,
63-
(errcode(ERRCODE_SYNTAX_ERROR),
64-
errmsg("query-specified return tuple and "
65-
"function return type are not compatible")));
66-
67-
/* OK to use it */
68-
attinmeta=TupleDescGetAttInMetadata(tupdesc);
69-
70-
/* let the caller know we're sending back a tuplestore */
51+
tupstore=tuplestore_begin_heap(true, false,work_mem);
7152
rsinfo->returnMode=SFRM_Materialize;
53+
rsinfo->setResult=tupstore;
54+
rsinfo->setDesc=tupdesc;
7255

73-
/* initialize our tuplestore */
74-
tupstore=tuplestore_begin_heap(true, false,work_mem);
56+
MemoryContextSwitchTo(oldcontext);
7557

7658
configdata=get_configdata(my_exec_path,&configdata_len);
7759
for (i=0;i<configdata_len;i++)
7860
{
79-
values[0]=configdata[i].name;
80-
values[1]=configdata[i].setting;
81-
82-
tuple=BuildTupleFromCStrings(attinmeta,values);
83-
tuplestore_puttuple(tupstore,tuple);
84-
}
61+
Datumvalues[2];
62+
boolnulls[2];
8563

86-
/*
87-
* no longer need the tuple descriptor reference created by
88-
* TupleDescGetAttInMetadata()
89-
*/
90-
ReleaseTupleDesc(tupdesc);
64+
memset(values,0,sizeof(values));
65+
memset(nulls,0,sizeof(nulls));
9166

92-
rsinfo->setResult=tupstore;
67+
values[0]=CStringGetTextDatum(configdata[i].name);
68+
values[1]=CStringGetTextDatum(configdata[i].setting);
9369

94-
/*
95-
* SFRM_Materialize mode expects us to return a NULL Datum. The actual
96-
* tuples are in our tuplestore and passed back through rsinfo->setResult.
97-
* rsinfo->setDesc is set to the tuple description that we actually used
98-
* to build our tuples with, so the caller can verify we did what it was
99-
* expecting.
100-
*/
101-
rsinfo->setDesc=tupdesc;
102-
MemoryContextSwitchTo(oldcontext);
70+
tuplestore_putvalues(tupstore,tupdesc,values,nulls);
71+
}
10372

10473
return (Datum)0;
10574
}

‎src/backend/utils/mmgr/portalmem.c

Lines changed: 6 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include"access/xact.h"
2222
#include"catalog/pg_type.h"
2323
#include"commands/portalcmds.h"
24+
#include"funcapi.h"
2425
#include"miscadmin.h"
2526
#include"storage/ipc.h"
2627
#include"utils/builtins.h"
@@ -1152,23 +1153,8 @@ pg_cursor(PG_FUNCTION_ARGS)
11521153
per_query_ctx=rsinfo->econtext->ecxt_per_query_memory;
11531154
oldcontext=MemoryContextSwitchTo(per_query_ctx);
11541155

1155-
/*
1156-
* build tupdesc for result tuples. This must match the definition of the
1157-
* pg_cursors view in system_views.sql
1158-
*/
1159-
tupdesc=CreateTemplateTupleDesc(6);
1160-
TupleDescInitEntry(tupdesc, (AttrNumber)1,"name",
1161-
TEXTOID,-1,0);
1162-
TupleDescInitEntry(tupdesc, (AttrNumber)2,"statement",
1163-
TEXTOID,-1,0);
1164-
TupleDescInitEntry(tupdesc, (AttrNumber)3,"is_holdable",
1165-
BOOLOID,-1,0);
1166-
TupleDescInitEntry(tupdesc, (AttrNumber)4,"is_binary",
1167-
BOOLOID,-1,0);
1168-
TupleDescInitEntry(tupdesc, (AttrNumber)5,"is_scrollable",
1169-
BOOLOID,-1,0);
1170-
TupleDescInitEntry(tupdesc, (AttrNumber)6,"creation_time",
1171-
TIMESTAMPTZOID,-1,0);
1156+
if (get_call_result_type(fcinfo,NULL,&tupdesc)!=TYPEFUNC_COMPOSITE)
1157+
elog(ERROR,"return type must be a row type");
11721158

11731159
/*
11741160
* We put all the tuples into a tuplestore in one scan of the hashtable.
@@ -1177,6 +1163,9 @@ pg_cursor(PG_FUNCTION_ARGS)
11771163
tupstore=
11781164
tuplestore_begin_heap(rsinfo->allowedModes&SFRM_Materialize_Random,
11791165
false,work_mem);
1166+
rsinfo->returnMode=SFRM_Materialize;
1167+
rsinfo->setResult=tupstore;
1168+
rsinfo->setDesc=tupdesc;
11801169

11811170
/* generate junk in short-term context */
11821171
MemoryContextSwitchTo(oldcontext);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp