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

Commita2a3192

Browse files
committed
Further cleanup around the edges of OPAQUE/pseudotype changes. Correct
the declarations of some index access method support functions. SupportSQL functions returning VOID.
1 parentcf7ee63 commita2a3192

File tree

7 files changed

+140
-113
lines changed

7 files changed

+140
-113
lines changed

‎doc/src/sgml/xfunc.sgml‎

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<!--
2-
$Header: /cvsroot/pgsql/doc/src/sgml/xfunc.sgml,v 1.55 2002/08/22 00:01:40 tgl Exp $
2+
$Header: /cvsroot/pgsql/doc/src/sgml/xfunc.sgml,v 1.56 2002/08/23 16:41:37 tgl Exp $
33
-->
44

55
<chapter id="xfunc">
@@ -170,22 +170,26 @@ CREATE FUNCTION tp1 (integer, numeric) RETURNS numeric AS '
170170
<command>DELETE</command>) as well
171171
as <command>SELECT</command> queries. However, the final command
172172
must be a <command>SELECT</command> that returns whatever is
173-
specified as the function's return type.
173+
specified as the function's return type. Alternatively, if you
174+
want to define a SQL function that performs actions but has no
175+
useful value to return, you can define it as returning <type>void</>.
176+
In that case it must not end with a <command>SELECT</command>.
177+
For example:
174178

175179
<programlisting>
176-
CREATE FUNCTION clean_EMP () RETURNSinteger AS '
180+
CREATE FUNCTION clean_EMP () RETURNSvoid AS '
177181
DELETE FROM EMP
178182
WHERE EMP.salary &lt;= 0;
179-
SELECT 1 AS ignore_this;
180183
' LANGUAGE SQL;
181184

182185
SELECT clean_EMP();
183186
</programlisting>
184187

185188
<screen>
186-
x
187-
---
188-
1
189+
clean_emp
190+
-----------
191+
192+
(1 row)
189193
</screen>
190194
</para>
191195

‎src/backend/catalog/pg_proc.c‎

Lines changed: 20 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_proc.c,v 1.89 2002/08/22 00:01:41 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_proc.c,v 1.90 2002/08/23 16:41:37 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -266,24 +266,18 @@ ProcedureCreate(const char *procedureName,
266266
recordDependencyOn(&myself,&referenced,DEPENDENCY_NORMAL);
267267

268268
/* dependency on return type */
269-
if (OidIsValid(returnType))
270-
{
271-
referenced.classId=RelOid_pg_type;
272-
referenced.objectId=returnType;
273-
referenced.objectSubId=0;
274-
recordDependencyOn(&myself,&referenced,DEPENDENCY_NORMAL);
275-
}
269+
referenced.classId=RelOid_pg_type;
270+
referenced.objectId=returnType;
271+
referenced.objectSubId=0;
272+
recordDependencyOn(&myself,&referenced,DEPENDENCY_NORMAL);
276273

277274
/* dependency on input types */
278275
for (i=0;i<parameterCount;i++)
279276
{
280-
if (OidIsValid(typev[i]))
281-
{
282-
referenced.classId=RelOid_pg_type;
283-
referenced.objectId=typev[i];
284-
referenced.objectSubId=0;
285-
recordDependencyOn(&myself,&referenced,DEPENDENCY_NORMAL);
286-
}
277+
referenced.classId=RelOid_pg_type;
278+
referenced.objectId=typev[i];
279+
referenced.objectSubId=0;
280+
recordDependencyOn(&myself,&referenced,DEPENDENCY_NORMAL);
287281
}
288282

289283
heap_freetuple(tup);
@@ -324,10 +318,10 @@ checkretval(Oid rettype, char fn_typtype, List *queryTreeList)
324318
intrellogcols;/* # of nondeleted columns in rel */
325319
intcolindex;/* physical column index */
326320

327-
/* guard against empty function body; OK only ifno return type */
321+
/* guard against empty function body; OK only ifvoid return type */
328322
if (queryTreeList==NIL)
329323
{
330-
if (rettype!=InvalidOid)
324+
if (rettype!=VOIDOID)
331325
elog(ERROR,"function declared to return %s, but no SELECT provided",
332326
format_type_be(rettype));
333327
return;
@@ -340,13 +334,12 @@ checkretval(Oid rettype, char fn_typtype, List *queryTreeList)
340334
tlist=parse->targetList;
341335

342336
/*
343-
* The last query must be a SELECT if and only if there is a return
344-
* type.
337+
* The last query must be a SELECT if and only if return type isn't VOID.
345338
*/
346-
if (rettype==InvalidOid)
339+
if (rettype==VOIDOID)
347340
{
348341
if (cmd==CMD_SELECT)
349-
elog(ERROR,"function declaredwith noreturntype, but final statement is a SELECT");
342+
elog(ERROR,"function declaredtoreturnvoid, but final statement is a SELECT");
350343
return;
351344
}
352345

@@ -573,13 +566,15 @@ fmgr_sql_validator(PG_FUNCTION_ARGS)
573566
tuple=SearchSysCache(PROCOID,funcoid,0,0,0);
574567
if (!HeapTupleIsValid(tuple))
575568
elog(ERROR,"cache lookup of function %u failed",funcoid);
576-
577569
proc= (Form_pg_proc)GETSTRUCT(tuple);
578570

571+
functyptype=get_typtype(proc->prorettype);
572+
579573
/* Disallow pseudotypes in arguments and result */
580-
/* except that return type can be RECORD */
581-
if (get_typtype(proc->prorettype)=='p'&&
582-
proc->prorettype!=RECORDOID)
574+
/* except that return type can be RECORD or VOID */
575+
if (functyptype=='p'&&
576+
proc->prorettype!=RECORDOID&&
577+
proc->prorettype!=VOIDOID)
583578
elog(ERROR,"SQL functions cannot return type %s",
584579
format_type_be(proc->prorettype));
585580

@@ -596,9 +591,6 @@ fmgr_sql_validator(PG_FUNCTION_ARGS)
596591

597592
prosrc=DatumGetCString(DirectFunctionCall1(textout,tmp));
598593

599-
/* check typtype to see if we have a predetermined return type */
600-
functyptype=get_typtype(proc->prorettype);
601-
602594
querytree_list=pg_parse_and_rewrite(prosrc,proc->proargtypes,proc->pronargs);
603595
checkretval(proc->prorettype,functyptype,querytree_list);
604596

‎src/backend/commands/typecmds.c‎

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/commands/typecmds.c,v 1.10 2002/08/22 00:01:42 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/commands/typecmds.c,v 1.11 2002/08/23 16:41:37 tgl Exp $
1212
*
1313
* DESCRIPTION
1414
* The "DefineFoo" routines take the parse tree and pick out the
@@ -203,19 +203,27 @@ DefineType(List *names, List *parameters)
203203
outputOid=findTypeIOFunction(outputName,typoid, true);
204204

205205
/*
206-
* Verify that I/O procs return the expected thing. OPAQUE is an allowed
207-
*(but deprecated) alternative to the fully type-safe choices.
206+
* Verify that I/O procs return the expected thing. OPAQUE is an allowed,
207+
* but deprecated, alternative to the fully type-safe choices.
208208
*/
209209
resulttype=get_func_rettype(inputOid);
210-
if (!((OidIsValid(typoid)&&resulttype==typoid)||
211-
resulttype==OPAQUEOID))
212-
elog(ERROR,"Type input function %s must return %s or OPAQUE",
213-
NameListToString(inputName),typeName);
210+
if (!(OidIsValid(typoid)&&resulttype==typoid))
211+
{
212+
if (resulttype==OPAQUEOID)
213+
elog(NOTICE,"DefineType: OPAQUE is deprecated, instead declare I/O functions using their true datatypes");
214+
else
215+
elog(ERROR,"Type input function %s must return %s",
216+
NameListToString(inputName),typeName);
217+
}
214218
resulttype=get_func_rettype(outputOid);
215-
if (!(resulttype==CSTRINGOID||
216-
resulttype==OPAQUEOID))
217-
elog(ERROR,"Type output function %s must return CSTRING or OPAQUE",
218-
NameListToString(outputName));
219+
if (resulttype!=CSTRINGOID)
220+
{
221+
if (resulttype==OPAQUEOID)
222+
elog(NOTICE,"DefineType: OPAQUE is deprecated, instead declare I/O functions using their true datatypes");
223+
else
224+
elog(ERROR,"Type output function %s must return cstring",
225+
NameListToString(outputName));
226+
}
219227

220228
/*
221229
* now have TypeCreate do all the real work.
@@ -671,6 +679,10 @@ findTypeIOFunction(List *procname, Oid typeOid, bool isOutput)
671679
* or two arguments (data value, element OID). The signature
672680
* may use OPAQUE in place of the actual type name; this is the
673681
* only possibility if the type doesn't yet exist as a shell.
682+
*
683+
* Note: although we could throw a NOTICE in this routine if OPAQUE
684+
* is used, we do not because of the probability that it'd be
685+
* duplicate with a notice issued in DefineType.
674686
*/
675687
if (OidIsValid(typeOid))
676688
{

‎src/backend/executor/functions.c‎

Lines changed: 20 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/executor/functions.c,v 1.54 2002/08/05 02:30:50 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/executor/functions.c,v 1.55 2002/08/23 16:41:37 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -86,36 +86,35 @@ static void ShutdownSQLFunction(Datum arg);
8686
staticexecution_state*
8787
init_execution_state(char*src,Oid*argOidVect,intnargs)
8888
{
89-
execution_state*newes;
90-
execution_state*nextes;
89+
execution_state*firstes;
9190
execution_state*preves;
9291
List*queryTree_list,
9392
*qtl_item;
9493

95-
newes= (execution_state*)palloc(sizeof(execution_state));
96-
nextes=newes;
97-
preves= (execution_state*)NULL;
98-
9994
queryTree_list=pg_parse_and_rewrite(src,argOidVect,nargs);
10095

96+
firstes=NULL;
97+
preves=NULL;
98+
10199
foreach(qtl_item,queryTree_list)
102100
{
103101
Query*queryTree=lfirst(qtl_item);
104102
Plan*planTree;
103+
execution_state*newes;
105104
EState*estate;
106105

107106
planTree=pg_plan_query(queryTree);
108107

109-
if (!nextes)
110-
nextes= (execution_state*)palloc(sizeof(execution_state));
108+
newes= (execution_state*)palloc(sizeof(execution_state));
111109
if (preves)
112-
preves->next=nextes;
113-
114-
nextes->next=NULL;
115-
nextes->status=F_EXEC_START;
110+
preves->next=newes;
111+
else
112+
firstes=newes;
116113

117-
nextes->qd=CreateQueryDesc(queryTree,planTree,None,NULL);
118-
estate=CreateExecutorState();
114+
newes->next=NULL;
115+
newes->status=F_EXEC_START;
116+
newes->qd=CreateQueryDesc(queryTree,planTree,None,NULL);
117+
newes->estate=estate=CreateExecutorState();
119118

120119
if (nargs>0)
121120
{
@@ -124,7 +123,7 @@ init_execution_state(char *src, Oid *argOidVect, int nargs)
124123

125124
paramLI= (ParamListInfo)palloc((nargs+1)*sizeof(ParamListInfoData));
126125

127-
MemSet(paramLI,0,nargs*sizeof(ParamListInfoData));
126+
MemSet(paramLI,0,(nargs+1)*sizeof(ParamListInfoData));
128127

129128
estate->es_param_list_info=paramLI;
130129

@@ -139,12 +138,11 @@ init_execution_state(char *src, Oid *argOidVect, int nargs)
139138
}
140139
else
141140
estate->es_param_list_info= (ParamListInfo)NULL;
142-
nextes->estate=estate;
143-
preves=nextes;
144-
nextes= (execution_state*)NULL;
141+
142+
preves=newes;
145143
}
146144

147-
returnnewes;
145+
returnfirstes;
148146
}
149147

150148

@@ -195,7 +193,7 @@ init_sql_fcache(FmgrInfo *finfo)
195193
*/
196194
fcache->typlen=typeStruct->typlen;
197195

198-
if (typeStruct->typtype=='b'||typeStruct->typtype=='d')
196+
if (typeStruct->typtype!='c')
199197
{
200198
/* The return type is not a relation, so just use byval */
201199
fcache->typbyval=typeStruct->typbyval;
@@ -484,22 +482,19 @@ fmgr_sql(PG_FUNCTION_ARGS)
484482
fcache= (SQLFunctionCachePtr)fcinfo->flinfo->fn_extra;
485483
}
486484
es=fcache->func_state;
487-
Assert(es);
488485

489486
/*
490487
* Find first unfinished query in function.
491488
*/
492489
while (es&&es->status==F_EXEC_DONE)
493490
es=es->next;
494491

495-
Assert(es);
496-
497492
/*
498493
* Execute each command in the function one after another until we're
499494
* executing the final command and get a result or we run out of
500495
* commands.
501496
*/
502-
while (es!= (execution_state*)NULL)
497+
while (es)
503498
{
504499
result=postquel_execute(es,fcinfo,fcache);
505500
if (es->status!=F_EXEC_DONE)

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp