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

Commit7ea5f1d

Browse files
committed
Here is a patch for the Table Function API. It fixes a bug found by Neil
Conway (BuildTupleFromCStrings sets NULL for pass-by-value types whenintended value is 0). It also implements some other improvementssuggested by Neil.Joe Conway
1 parenta5a8110 commit7ea5f1d

File tree

3 files changed

+72
-25
lines changed

3 files changed

+72
-25
lines changed

‎src/backend/executor/execTuples.c

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
*
1616
*
1717
* IDENTIFICATION
18-
* $Header: /cvsroot/pgsql/src/backend/executor/execTuples.c,v 1.53 2002/06/20 20:29:27 momjian Exp $
18+
* $Header: /cvsroot/pgsql/src/backend/executor/execTuples.c,v 1.54 2002/07/18 04:40:30 momjian Exp $
1919
*
2020
*-------------------------------------------------------------------------
2121
*/
@@ -759,6 +759,7 @@ BuildTupleFromCStrings(AttInMetadata *attinmeta, char **values)
759759
natts=tupdesc->natts;
760760

761761
dvalues= (Datum*)palloc(natts*sizeof(Datum));
762+
nulls= (char*)palloc(natts*sizeof(char));
762763

763764
/* Call the "in" function for each attribute */
764765
for (i=0;i<natts;i++)
@@ -772,22 +773,18 @@ BuildTupleFromCStrings(AttInMetadata *attinmeta, char **values)
772773
dvalues[i]=FunctionCall3(&attinfuncinfo,CStringGetDatum(values[i]),
773774
ObjectIdGetDatum(attelem),
774775
Int32GetDatum(atttypmod));
776+
nulls[i]=' ';
775777
}
776778
else
779+
{
777780
dvalues[i]=PointerGetDatum(NULL);
781+
nulls[i]='n';
782+
}
778783
}
779784

780785
/*
781786
* Form a tuple
782787
*/
783-
nulls= (char*)palloc(natts*sizeof(char));
784-
for (i=0;i<natts;i++)
785-
{
786-
if (DatumGetPointer(dvalues[i])!=NULL)
787-
nulls[i]=' ';
788-
else
789-
nulls[i]='n';
790-
}
791788
tuple=heap_formtuple(tupdesc,dvalues,nulls);
792789

793790
returntuple;

‎src/backend/utils/fmgr/funcapi.c

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ init_MultiFuncCall(PG_FUNCTION_ARGS)
5252
retval->call_cntr=0;
5353
retval->max_calls=0;
5454
retval->slot=NULL;
55-
retval->fctx=NULL;
55+
retval->user_fctx=NULL;
5656
retval->attinmeta=NULL;
5757
retval->fmctx=fcinfo->flinfo->fn_mcxt;
5858

@@ -75,6 +75,23 @@ init_MultiFuncCall(PG_FUNCTION_ARGS)
7575
returnretval;
7676
}
7777

78+
/*
79+
* per_MultiFuncCall
80+
*
81+
* Do Multi-function per-call setup
82+
*/
83+
FuncCallContext*
84+
per_MultiFuncCall(PG_FUNCTION_ARGS)
85+
{
86+
FuncCallContext*retval= (FuncCallContext*)fcinfo->flinfo->fn_extra;
87+
88+
/* make sure we start with a fresh slot */
89+
if(retval->slot!=NULL)
90+
ExecClearTuple(retval->slot);
91+
92+
returnretval;
93+
}
94+
7895
/*
7996
* end_MultiFuncCall
8097
* Clean up after init_MultiFuncCall

‎src/include/funcapi.h

Lines changed: 48 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -65,22 +65,57 @@ typedef struct
6565
*/
6666
typedefstruct
6767
{
68-
/* Number of times we've been called before */
68+
/*
69+
* Number of times we've been called before.
70+
*
71+
* call_cntr is initialized to 0 for you by SRF_FIRSTCALL_INIT(), and
72+
* incremented for you every time SRF_RETURN_NEXT() is called.
73+
*/
6974
uint32call_cntr;
7075

71-
/* Maximum number of calls */
76+
/*
77+
* OPTIONAL maximum number of calls
78+
*
79+
* max_calls is here for convenience ONLY and setting it is OPTIONAL.
80+
* If not set, you must provide alternative means to know when the
81+
* function is done.
82+
*/
7283
uint32max_calls;
7384

74-
/* pointer to result slot */
85+
/*
86+
* OPTIONAL pointer to result slot
87+
*
88+
* slot is for use when returning tuples (i.e. composite data types)
89+
* and is not needed when returning base (i.e. scalar) data types.
90+
*/
7591
TupleTableSlot*slot;
7692

77-
/* pointer to misc context info */
78-
void*fctx;
79-
80-
/* pointer to struct containing arrays of attribute type input metainfo */
93+
/*
94+
* OPTIONAL pointer to misc user provided context info
95+
*
96+
* user_fctx is for use as a pointer to your own struct to retain
97+
* arbitrary context information between calls for your function.
98+
*/
99+
void*user_fctx;
100+
101+
/*
102+
* OPTIONAL pointer to struct containing arrays of attribute type input
103+
* metainfo
104+
*
105+
* attinmeta is for use when returning tuples (i.e. composite data types)
106+
* and is not needed when returning base (i.e. scalar) data types. It
107+
* is ONLY needed if you intend to use BuildTupleFromCStrings() to create
108+
* the return tuple.
109+
*/
81110
AttInMetadata*attinmeta;
82111

83-
/* memory context used to initialize structure */
112+
/*
113+
* memory context used to initialize structure
114+
*
115+
* fmctx is set by SRF_FIRSTCALL_INIT() for you, and used by
116+
* SRF_RETURN_DONE() for cleanup. It is primarily for internal use
117+
* by the API.
118+
*/
84119
MemoryContextfmctx;
85120

86121
}FuncCallContext;
@@ -137,7 +172,7 @@ extern void get_type_metadata(Oid typeid, Oid *attinfuncid, Oid *attelem);
137172
* Datumresult;
138173
* <user defined declarations>
139174
*
140-
* if(SRF_IS_FIRSTPASS())
175+
* if(SRF_IS_FIRSTCALL())
141176
* {
142177
* <user defined code>
143178
* funcctx = SRF_FIRSTCALL_INIT();
@@ -148,7 +183,7 @@ extern void get_type_metadata(Oid typeid, Oid *attinfuncid, Oid *attelem);
148183
* <user defined code>
149184
* }
150185
* <user defined code>
151-
* funcctx = SRF_PERCALL_SETUP(funcctx);
186+
* funcctx = SRF_PERCALL_SETUP();
152187
* <user defined code>
153188
*
154189
* if (funcctx->call_cntr < funcctx->max_calls)
@@ -167,14 +202,12 @@ extern void get_type_metadata(Oid typeid, Oid *attinfuncid, Oid *attelem);
167202

168203
/* from funcapi.c */
169204
externFuncCallContext*init_MultiFuncCall(PG_FUNCTION_ARGS);
205+
externFuncCallContext*per_MultiFuncCall(PG_FUNCTION_ARGS);
170206
externvoidend_MultiFuncCall(PG_FUNCTION_ARGS,FuncCallContext*funcctx);
171207

172-
#defineSRF_IS_FIRSTPASS() (fcinfo->flinfo->fn_extra == NULL)
208+
#defineSRF_IS_FIRSTCALL() (fcinfo->flinfo->fn_extra == NULL)
173209
#defineSRF_FIRSTCALL_INIT() init_MultiFuncCall(fcinfo)
174-
#defineSRF_PERCALL_SETUP(_funcctx) \
175-
fcinfo->flinfo->fn_extra; \
176-
if(_funcctx->slot != NULL) \
177-
ExecClearTuple(_funcctx->slot)
210+
#defineSRF_PERCALL_SETUP() per_MultiFuncCall(fcinfo)
178211
#defineSRF_RETURN_NEXT(_funcctx,_result) \
179212
do { \
180213
ReturnSetInfo *rsi; \

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp