mirror of
https://github.com/postgres/postgres.git
synced 2025-07-28 23:42:10 +03:00
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 to support OUT parameters, so better to have it in the main backend. Also, fix plpgsql validator to detect bogus OUT parameters even when check_function_bodies is off.
This commit is contained in:
@ -7,7 +7,7 @@
|
||||
* Copyright (c) 2002-2005, PostgreSQL Global Development Group
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/utils/fmgr/funcapi.c,v 1.27 2005/11/17 22:14:53 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/fmgr/funcapi.c,v 1.28 2005/12/28 18:11:25 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -628,6 +628,109 @@ get_type_func_class(Oid typid)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* get_func_arg_info
|
||||
*
|
||||
* Fetch info about the argument types, names, and IN/OUT modes from the
|
||||
* pg_proc tuple. Return value is the total number of arguments.
|
||||
* Other results are palloc'd. *p_argtypes is always filled in, but
|
||||
* *p_argnames and *p_argmodes will be set NULL in the default cases
|
||||
* (no names, and all IN arguments, respectively).
|
||||
*
|
||||
* Note that this function simply fetches what is in the pg_proc tuple;
|
||||
* it doesn't do any interpretation of polymorphic types.
|
||||
*/
|
||||
int
|
||||
get_func_arg_info(HeapTuple procTup,
|
||||
Oid **p_argtypes, char ***p_argnames, char **p_argmodes)
|
||||
{
|
||||
Form_pg_proc procStruct = (Form_pg_proc) GETSTRUCT(procTup);
|
||||
Datum proallargtypes;
|
||||
Datum proargmodes;
|
||||
Datum proargnames;
|
||||
bool isNull;
|
||||
ArrayType *arr;
|
||||
int numargs;
|
||||
Datum *elems;
|
||||
int nelems;
|
||||
int i;
|
||||
|
||||
/* First discover the total number of parameters and get their types */
|
||||
proallargtypes = SysCacheGetAttr(PROCOID, procTup,
|
||||
Anum_pg_proc_proallargtypes,
|
||||
&isNull);
|
||||
if (!isNull)
|
||||
{
|
||||
/*
|
||||
* We expect the arrays to be 1-D arrays of the right types; verify
|
||||
* that. For the OID and char arrays, we don't need to use
|
||||
* deconstruct_array() since the array data is just going to look like
|
||||
* a C array of values.
|
||||
*/
|
||||
arr = DatumGetArrayTypeP(proallargtypes); /* ensure not toasted */
|
||||
numargs = ARR_DIMS(arr)[0];
|
||||
if (ARR_NDIM(arr) != 1 ||
|
||||
numargs < 0 ||
|
||||
ARR_HASNULL(arr) ||
|
||||
ARR_ELEMTYPE(arr) != OIDOID)
|
||||
elog(ERROR, "proallargtypes is not a 1-D Oid array");
|
||||
Assert(numargs >= procStruct->pronargs);
|
||||
*p_argtypes = (Oid *) palloc(numargs * sizeof(Oid));
|
||||
memcpy(*p_argtypes, ARR_DATA_PTR(arr),
|
||||
numargs * sizeof(Oid));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* If no proallargtypes, use proargtypes */
|
||||
numargs = procStruct->proargtypes.dim1;
|
||||
Assert(numargs == procStruct->pronargs);
|
||||
*p_argtypes = (Oid *) palloc(numargs * sizeof(Oid));
|
||||
memcpy(*p_argtypes, procStruct->proargtypes.values,
|
||||
numargs * sizeof(Oid));
|
||||
}
|
||||
|
||||
/* Get argument names, if available */
|
||||
proargnames = SysCacheGetAttr(PROCOID, procTup,
|
||||
Anum_pg_proc_proargnames,
|
||||
&isNull);
|
||||
if (isNull)
|
||||
*p_argnames = NULL;
|
||||
else
|
||||
{
|
||||
deconstruct_array(DatumGetArrayTypeP(proargnames),
|
||||
TEXTOID, -1, false, 'i',
|
||||
&elems, NULL, &nelems);
|
||||
if (nelems != numargs) /* should not happen */
|
||||
elog(ERROR, "proargnames must have the same number of elements as the function has arguments");
|
||||
*p_argnames = (char **) palloc(sizeof(char *) * numargs);
|
||||
for (i = 0; i < numargs; i++)
|
||||
(*p_argnames)[i] = DatumGetCString(DirectFunctionCall1(textout,
|
||||
elems[i]));
|
||||
}
|
||||
|
||||
/* Get argument modes, if available */
|
||||
proargmodes = SysCacheGetAttr(PROCOID, procTup,
|
||||
Anum_pg_proc_proargmodes,
|
||||
&isNull);
|
||||
if (isNull)
|
||||
*p_argmodes = NULL;
|
||||
else
|
||||
{
|
||||
arr = DatumGetArrayTypeP(proargmodes); /* ensure not toasted */
|
||||
if (ARR_NDIM(arr) != 1 ||
|
||||
ARR_DIMS(arr)[0] != numargs ||
|
||||
ARR_HASNULL(arr) ||
|
||||
ARR_ELEMTYPE(arr) != CHAROID)
|
||||
elog(ERROR, "proargmodes is not a 1-D char array");
|
||||
*p_argmodes = (char *) palloc(numargs * sizeof(char));
|
||||
memcpy(*p_argmodes, ARR_DATA_PTR(arr),
|
||||
numargs * sizeof(char));
|
||||
}
|
||||
|
||||
return numargs;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* get_func_result_name
|
||||
*
|
||||
|
Reference in New Issue
Block a user