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

Commit15093bf

Browse files
committed
Move plpgsql's fetchArgInfo() into funcapi.c, and rename to
get_func_arg_info() for consistency with other names there.This code will probably be useful to other PLs when they start tosupport OUT parameters, so better to have it in the main backend.Also, fix plpgsql validator to detect bogus OUT parameters even whencheck_function_bodies is off.
1 parent776d63f commit15093bf

File tree

4 files changed

+131
-121
lines changed

4 files changed

+131
-121
lines changed

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

Lines changed: 104 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Copyright (c) 2002-2005, PostgreSQL Global Development Group
88
*
99
* IDENTIFICATION
10-
* $PostgreSQL: pgsql/src/backend/utils/fmgr/funcapi.c,v 1.27 2005/11/17 22:14:53 tgl Exp $
10+
* $PostgreSQL: pgsql/src/backend/utils/fmgr/funcapi.c,v 1.28 2005/12/28 18:11:25 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -628,6 +628,109 @@ get_type_func_class(Oid typid)
628628
}
629629

630630

631+
/*
632+
* get_func_arg_info
633+
*
634+
* Fetch info about the argument types, names, and IN/OUT modes from the
635+
* pg_proc tuple. Return value is the total number of arguments.
636+
* Other results are palloc'd. *p_argtypes is always filled in, but
637+
* *p_argnames and *p_argmodes will be set NULL in the default cases
638+
* (no names, and all IN arguments, respectively).
639+
*
640+
* Note that this function simply fetches what is in the pg_proc tuple;
641+
* it doesn't do any interpretation of polymorphic types.
642+
*/
643+
int
644+
get_func_arg_info(HeapTupleprocTup,
645+
Oid**p_argtypes,char***p_argnames,char**p_argmodes)
646+
{
647+
Form_pg_procprocStruct= (Form_pg_proc)GETSTRUCT(procTup);
648+
Datumproallargtypes;
649+
Datumproargmodes;
650+
Datumproargnames;
651+
boolisNull;
652+
ArrayType*arr;
653+
intnumargs;
654+
Datum*elems;
655+
intnelems;
656+
inti;
657+
658+
/* First discover the total number of parameters and get their types */
659+
proallargtypes=SysCacheGetAttr(PROCOID,procTup,
660+
Anum_pg_proc_proallargtypes,
661+
&isNull);
662+
if (!isNull)
663+
{
664+
/*
665+
* We expect the arrays to be 1-D arrays of the right types; verify
666+
* that. For the OID and char arrays, we don't need to use
667+
* deconstruct_array() since the array data is just going to look like
668+
* a C array of values.
669+
*/
670+
arr=DatumGetArrayTypeP(proallargtypes);/* ensure not toasted */
671+
numargs=ARR_DIMS(arr)[0];
672+
if (ARR_NDIM(arr)!=1||
673+
numargs<0||
674+
ARR_HASNULL(arr)||
675+
ARR_ELEMTYPE(arr)!=OIDOID)
676+
elog(ERROR,"proallargtypes is not a 1-D Oid array");
677+
Assert(numargs >=procStruct->pronargs);
678+
*p_argtypes= (Oid*)palloc(numargs*sizeof(Oid));
679+
memcpy(*p_argtypes,ARR_DATA_PTR(arr),
680+
numargs*sizeof(Oid));
681+
}
682+
else
683+
{
684+
/* If no proallargtypes, use proargtypes */
685+
numargs=procStruct->proargtypes.dim1;
686+
Assert(numargs==procStruct->pronargs);
687+
*p_argtypes= (Oid*)palloc(numargs*sizeof(Oid));
688+
memcpy(*p_argtypes,procStruct->proargtypes.values,
689+
numargs*sizeof(Oid));
690+
}
691+
692+
/* Get argument names, if available */
693+
proargnames=SysCacheGetAttr(PROCOID,procTup,
694+
Anum_pg_proc_proargnames,
695+
&isNull);
696+
if (isNull)
697+
*p_argnames=NULL;
698+
else
699+
{
700+
deconstruct_array(DatumGetArrayTypeP(proargnames),
701+
TEXTOID,-1, false,'i',
702+
&elems,NULL,&nelems);
703+
if (nelems!=numargs)/* should not happen */
704+
elog(ERROR,"proargnames must have the same number of elements as the function has arguments");
705+
*p_argnames= (char**)palloc(sizeof(char*)*numargs);
706+
for (i=0;i<numargs;i++)
707+
(*p_argnames)[i]=DatumGetCString(DirectFunctionCall1(textout,
708+
elems[i]));
709+
}
710+
711+
/* Get argument modes, if available */
712+
proargmodes=SysCacheGetAttr(PROCOID,procTup,
713+
Anum_pg_proc_proargmodes,
714+
&isNull);
715+
if (isNull)
716+
*p_argmodes=NULL;
717+
else
718+
{
719+
arr=DatumGetArrayTypeP(proargmodes);/* ensure not toasted */
720+
if (ARR_NDIM(arr)!=1||
721+
ARR_DIMS(arr)[0]!=numargs||
722+
ARR_HASNULL(arr)||
723+
ARR_ELEMTYPE(arr)!=CHAROID)
724+
elog(ERROR,"proargmodes is not a 1-D char array");
725+
*p_argmodes= (char*)palloc(numargs*sizeof(char));
726+
memcpy(*p_argmodes,ARR_DATA_PTR(arr),
727+
numargs*sizeof(char));
728+
}
729+
730+
returnnumargs;
731+
}
732+
733+
631734
/*
632735
* get_func_result_name
633736
*

‎src/include/funcapi.h

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
*
1010
* Copyright (c) 2002-2005, PostgreSQL Global Development Group
1111
*
12-
* $PostgreSQL: pgsql/src/include/funcapi.h,v 1.21 2005/11/22 18:17:29 momjian Exp $
12+
* $PostgreSQL: pgsql/src/include/funcapi.h,v 1.22 2005/12/28 18:11:25 tgl Exp $
1313
*
1414
*-------------------------------------------------------------------------
1515
*/
@@ -165,12 +165,16 @@ extern TypeFuncClass get_func_result_type(Oid functionId,
165165
Oid*resultTypeId,
166166
TupleDesc*resultTupleDesc);
167167

168-
externchar*get_func_result_name(OidfunctionId);
169-
170168
externboolresolve_polymorphic_argtypes(intnumargs,Oid*argtypes,
171169
char*argmodes,
172170
Node*call_expr);
173171

172+
externintget_func_arg_info(HeapTupleprocTup,
173+
Oid**p_argtypes,char***p_argnames,
174+
char**p_argmodes);
175+
176+
externchar*get_func_result_name(OidfunctionId);
177+
174178
externTupleDescbuild_function_result_tupdesc_d(Datumproallargtypes,
175179
Datumproargmodes,
176180
Datumproargnames);

‎src/pl/plpgsql/src/pl_comp.c

Lines changed: 3 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* procedural language
44
*
55
* IDENTIFICATION
6-
* $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_comp.c,v 1.97 2005/12/09 17:08:49 tgl Exp $
6+
* $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_comp.c,v 1.98 2005/12/28 18:11:25 tgl Exp $
77
*
88
* This software is copyrighted by Jan Wieck - Hamburg.
99
*
@@ -123,9 +123,6 @@ static PLpgSQL_function *do_compile(FunctionCallInfo fcinfo,
123123
HeapTupleprocTup,
124124
PLpgSQL_func_hashkey*hashkey,
125125
boolforValidator);
126-
staticintfetchArgInfo(HeapTupleprocTup,
127-
Oid**p_argtypes,char***p_argnames,
128-
char**p_argmodes);
129126
staticPLpgSQL_row*build_row_from_class(OidclassOid);
130127
staticPLpgSQL_row*build_row_from_vars(PLpgSQL_variable**vars,intnumvars);
131128
staticPLpgSQL_type*build_datatype(HeapTupletypeTup,int32typmod);
@@ -358,7 +355,8 @@ do_compile(FunctionCallInfo fcinfo,
358355
*/
359356
MemoryContextSwitchTo(compile_tmp_cxt);
360357

361-
numargs=fetchArgInfo(procTup,&argtypes,&argnames,&argmodes);
358+
numargs=get_func_arg_info(procTup,
359+
&argtypes,&argnames,&argmodes);
362360

363361
plpgsql_resolve_polymorphic_argtypes(numargs,argtypes,argmodes,
364362
fcinfo->flinfo->fn_expr,
@@ -751,102 +749,6 @@ plpgsql_compile_error_callback(void *arg)
751749
}
752750

753751

754-
/*
755-
* Fetch info about the argument types, names, and IN/OUT modes from the
756-
* pg_proc tuple. Return value is the number of arguments.
757-
* Other results are palloc'd.
758-
*/
759-
staticint
760-
fetchArgInfo(HeapTupleprocTup,Oid**p_argtypes,char***p_argnames,
761-
char**p_argmodes)
762-
{
763-
Form_pg_procprocStruct= (Form_pg_proc)GETSTRUCT(procTup);
764-
Datumproallargtypes;
765-
Datumproargmodes;
766-
Datumproargnames;
767-
boolisNull;
768-
ArrayType*arr;
769-
intnumargs;
770-
Datum*elems;
771-
intnelems;
772-
inti;
773-
774-
/* First discover the total number of parameters and get their types */
775-
proallargtypes=SysCacheGetAttr(PROCOID,procTup,
776-
Anum_pg_proc_proallargtypes,
777-
&isNull);
778-
if (!isNull)
779-
{
780-
/*
781-
* We expect the arrays to be 1-D arrays of the right types; verify
782-
* that. For the OID and char arrays, we don't need to use
783-
* deconstruct_array() since the array data is just going to look like
784-
* a C array of values.
785-
*/
786-
arr=DatumGetArrayTypeP(proallargtypes);/* ensure not toasted */
787-
numargs=ARR_DIMS(arr)[0];
788-
if (ARR_NDIM(arr)!=1||
789-
numargs<0||
790-
ARR_HASNULL(arr)||
791-
ARR_ELEMTYPE(arr)!=OIDOID)
792-
elog(ERROR,"proallargtypes is not a 1-D Oid array");
793-
Assert(numargs >=procStruct->pronargs);
794-
*p_argtypes= (Oid*)palloc(numargs*sizeof(Oid));
795-
memcpy(*p_argtypes,ARR_DATA_PTR(arr),
796-
numargs*sizeof(Oid));
797-
}
798-
else
799-
{
800-
/* If no proallargtypes, use proargtypes */
801-
numargs=procStruct->proargtypes.dim1;
802-
Assert(numargs==procStruct->pronargs);
803-
*p_argtypes= (Oid*)palloc(numargs*sizeof(Oid));
804-
memcpy(*p_argtypes,procStruct->proargtypes.values,
805-
numargs*sizeof(Oid));
806-
}
807-
808-
/* Get argument names, if available */
809-
proargnames=SysCacheGetAttr(PROCOID,procTup,
810-
Anum_pg_proc_proargnames,
811-
&isNull);
812-
if (isNull)
813-
*p_argnames=NULL;
814-
else
815-
{
816-
deconstruct_array(DatumGetArrayTypeP(proargnames),
817-
TEXTOID,-1, false,'i',
818-
&elems,NULL,&nelems);
819-
if (nelems!=numargs)/* should not happen */
820-
elog(ERROR,"proargnames must have the same number of elements as the function has arguments");
821-
*p_argnames= (char**)palloc(sizeof(char*)*numargs);
822-
for (i=0;i<numargs;i++)
823-
(*p_argnames)[i]=DatumGetCString(DirectFunctionCall1(textout,
824-
elems[i]));
825-
}
826-
827-
/* Get argument modes, if available */
828-
proargmodes=SysCacheGetAttr(PROCOID,procTup,
829-
Anum_pg_proc_proargmodes,
830-
&isNull);
831-
if (isNull)
832-
*p_argmodes=NULL;
833-
else
834-
{
835-
arr=DatumGetArrayTypeP(proargmodes);/* ensure not toasted */
836-
if (ARR_NDIM(arr)!=1||
837-
ARR_DIMS(arr)[0]!=numargs||
838-
ARR_HASNULL(arr)||
839-
ARR_ELEMTYPE(arr)!=CHAROID)
840-
elog(ERROR,"proargmodes is not a 1-D char array");
841-
*p_argmodes= (char*)palloc(numargs*sizeof(char));
842-
memcpy(*p_argmodes,ARR_DATA_PTR(arr),
843-
numargs*sizeof(char));
844-
}
845-
846-
returnnumargs;
847-
}
848-
849-
850752
/* ----------
851753
* plpgsql_parse_wordThe scanner calls this to postparse
852754
*any single word not found by a

‎src/pl/plpgsql/src/pl_handler.c

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* procedural language
44
*
55
* IDENTIFICATION
6-
* $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_handler.c,v 1.26 2005/10/15 02:49:50 momjian Exp $
6+
* $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_handler.c,v 1.27 2005/12/28 18:11:25 tgl Exp $
77
*
88
* This software is copyrighted by Jan Wieck - Hamburg.
99
*
@@ -41,6 +41,7 @@
4141
#include"access/heapam.h"
4242
#include"catalog/pg_proc.h"
4343
#include"catalog/pg_type.h"
44+
#include"funcapi.h"
4445
#include"utils/builtins.h"
4546
#include"utils/lsyscache.h"
4647
#include"utils/syscache.h"
@@ -147,9 +148,11 @@ plpgsql_validator(PG_FUNCTION_ARGS)
147148
HeapTupletuple;
148149
Form_pg_procproc;
149150
charfunctyptype;
151+
intnumargs;
152+
Oid*argtypes;
153+
char**argnames;
154+
char*argmodes;
150155
boolistrigger= false;
151-
boolhaspolyresult;
152-
boolhaspolyarg;
153156
inti;
154157

155158
/* perform initialization */
@@ -173,32 +176,30 @@ plpgsql_validator(PG_FUNCTION_ARGS)
173176
if (proc->prorettype==TRIGGEROID||
174177
(proc->prorettype==OPAQUEOID&&proc->pronargs==0))
175178
istrigger= true;
176-
elseif (proc->prorettype==ANYARRAYOID||
177-
proc->prorettype==ANYELEMENTOID)
178-
haspolyresult= true;
179179
elseif (proc->prorettype!=RECORDOID&&
180-
proc->prorettype!=VOIDOID)
180+
proc->prorettype!=VOIDOID&&
181+
proc->prorettype!=ANYARRAYOID&&
182+
proc->prorettype!=ANYELEMENTOID)
181183
ereport(ERROR,
182184
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
183185
errmsg("plpgsql functions cannot return type %s",
184186
format_type_be(proc->prorettype))));
185187
}
186188

187-
/* Disallow pseudotypes in arguments */
189+
/* Disallow pseudotypes in arguments(either IN or OUT)*/
188190
/* except for ANYARRAY or ANYELEMENT */
189-
haspolyarg= false;
190-
for (i=0;i<proc->pronargs;i++)
191+
numargs=get_func_arg_info(tuple,
192+
&argtypes,&argnames,&argmodes);
193+
for (i=0;i<numargs;i++)
191194
{
192-
if (get_typtype(proc->proargtypes.values[i])=='p')
195+
if (get_typtype(argtypes[i])=='p')
193196
{
194-
if (proc->proargtypes.values[i]==ANYARRAYOID||
195-
proc->proargtypes.values[i]==ANYELEMENTOID)
196-
haspolyarg= true;
197-
else
197+
if (argtypes[i]!=ANYARRAYOID&&
198+
argtypes[i]!=ANYELEMENTOID)
198199
ereport(ERROR,
199200
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
200201
errmsg("plpgsql functions cannot take type %s",
201-
format_type_be(proc->proargtypes.values[i]))));
202+
format_type_be(argtypes[i]))));
202203
}
203204
}
204205

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp