aboutsummaryrefslogtreecommitdiff
path: root/src/backend
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend')
-rw-r--r--src/backend/bootstrap/bootstrap.c15
-rw-r--r--src/backend/catalog/pg_aggregate.c5
-rw-r--r--src/backend/catalog/pg_proc.c52
-rw-r--r--src/backend/commands/functioncmds.c29
-rw-r--r--src/backend/nodes/copyfuncs.c18
-rw-r--r--src/backend/nodes/equalfuncs.c16
-rw-r--r--src/backend/parser/gram.y87
-rw-r--r--src/backend/utils/adt/sets.c7
-rw-r--r--src/backend/utils/fmgr/fmgr.c10
9 files changed, 192 insertions, 47 deletions
diff --git a/src/backend/bootstrap/bootstrap.c b/src/backend/bootstrap/bootstrap.c
index b21f4cc8065..c1105f3b11e 100644
--- a/src/backend/bootstrap/bootstrap.c
+++ b/src/backend/bootstrap/bootstrap.c
@@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/bootstrap/bootstrap.c,v 1.173 2004/01/06 23:15:22 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/bootstrap/bootstrap.c,v 1.174 2004/01/06 23:55:18 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -130,6 +130,7 @@ static struct typinfo Procid[] = {
{"oidvector", OIDVECTOROID, 0, INDEX_MAX_KEYS * 4, F_OIDVECTORIN, F_OIDVECTOROUT},
{"smgr", 210, 0, 2, F_SMGRIN, F_SMGROUT},
{"_int4", 1007, INT4OID, -1, F_ARRAY_IN, F_ARRAY_OUT},
+ {"_text", 1009, TEXTOID, -1, F_ARRAY_IN, F_ARRAY_OUT},
{"_aclitem", 1034, 1033, -1, F_ARRAY_IN, F_ARRAY_OUT}
};
@@ -690,6 +691,11 @@ DefineAttr(char *name, char *type, int attnum)
attrtypes[attnum]->attbyval = Ap->am_typ.typbyval;
attrtypes[attnum]->attstorage = Ap->am_typ.typstorage;
attrtypes[attnum]->attalign = Ap->am_typ.typalign;
+ /* if an array type, assume 1-dimensional attribute */
+ if (Ap->am_typ.typelem != InvalidOid && Ap->am_typ.typlen < 0)
+ attrtypes[attnum]->attndims = 1;
+ else
+ attrtypes[attnum]->attndims = 0;
}
else
{
@@ -729,7 +735,14 @@ DefineAttr(char *name, char *type, int attnum)
attrtypes[attnum]->attalign = 'i';
break;
}
+ /* if an array type, assume 1-dimensional attribute */
+ if (Procid[typeoid].elem != InvalidOid && attlen < 0)
+ attrtypes[attnum]->attndims = 1;
+ else
+ attrtypes[attnum]->attndims = 0;
}
+
+ attrtypes[attnum]->attstattarget = -1;
attrtypes[attnum]->attcacheoff = -1;
attrtypes[attnum]->atttypmod = -1;
attrtypes[attnum]->attislocal = true;
diff --git a/src/backend/catalog/pg_aggregate.c b/src/backend/catalog/pg_aggregate.c
index 8ed1aecdfe9..d21ecef3606 100644
--- a/src/backend/catalog/pg_aggregate.c
+++ b/src/backend/catalog/pg_aggregate.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/catalog/pg_aggregate.c,v 1.65 2003/11/29 19:51:45 pgsql Exp $
+ * $PostgreSQL: pgsql/src/backend/catalog/pg_aggregate.c,v 1.66 2004/01/06 23:55:18 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -190,7 +190,8 @@ AggregateCreate(const char *aggName,
PROVOLATILE_IMMUTABLE, /* volatility (not
* needed for agg) */
1, /* parameterCount */
- fnArgs); /* parameterTypes */
+ fnArgs, /* parameterTypes */
+ NULL); /* parameterNames */
/*
* Okay to create the pg_aggregate entry.
diff --git a/src/backend/catalog/pg_proc.c b/src/backend/catalog/pg_proc.c
index bca442ab8c4..b9628734701 100644
--- a/src/backend/catalog/pg_proc.c
+++ b/src/backend/catalog/pg_proc.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/catalog/pg_proc.c,v 1.110 2003/11/29 19:51:46 pgsql Exp $
+ * $PostgreSQL: pgsql/src/backend/catalog/pg_proc.c,v 1.111 2004/01/06 23:55:18 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -42,6 +42,9 @@ Datum fmgr_internal_validator(PG_FUNCTION_ARGS);
Datum fmgr_c_validator(PG_FUNCTION_ARGS);
Datum fmgr_sql_validator(PG_FUNCTION_ARGS);
+static Datum create_parameternames_array(int parameterCount,
+ const char *parameterNames[]);
+
/* ----------------------------------------------------------------
* ProcedureCreate
@@ -62,7 +65,8 @@ ProcedureCreate(const char *procedureName,
bool isStrict,
char volatility,
int parameterCount,
- const Oid *parameterTypes)
+ const Oid *parameterTypes,
+ const char *parameterNames[])
{
int i;
Relation rel;
@@ -72,6 +76,7 @@ ProcedureCreate(const char *procedureName,
Datum values[Natts_pg_proc];
char replaces[Natts_pg_proc];
Oid typev[FUNC_MAX_ARGS];
+ Datum namesarray;
Oid relid;
NameData procname;
TupleDesc tupDesc;
@@ -122,6 +127,9 @@ ProcedureCreate(const char *procedureName,
if (parameterCount > 0)
memcpy(typev, parameterTypes, parameterCount * sizeof(Oid));
+ /* Process param names, if given */
+ namesarray = create_parameternames_array(parameterCount, parameterNames);
+
if (languageObjectId == SQLlanguageId)
{
/*
@@ -197,6 +205,9 @@ ProcedureCreate(const char *procedureName,
values[i++] = UInt16GetDatum(parameterCount); /* pronargs */
values[i++] = ObjectIdGetDatum(returnType); /* prorettype */
values[i++] = PointerGetDatum(typev); /* proargtypes */
+ values[i++] = namesarray; /* proargnames */
+ if (namesarray == PointerGetDatum(NULL))
+ nulls[Anum_pg_proc_proargnames - 1] = 'n';
values[i++] = DirectFunctionCall1(textin, /* prosrc */
CStringGetDatum(prosrc));
values[i++] = DirectFunctionCall1(textin, /* probin */
@@ -334,6 +345,43 @@ ProcedureCreate(const char *procedureName,
return retval;
}
+
+/*
+ * create_parameternames_array - build proargnames value from an array
+ * of C strings. Returns a NULL pointer if no names provided.
+ */
+static Datum
+create_parameternames_array(int parameterCount, const char *parameterNames[])
+{
+ Datum elems[FUNC_MAX_ARGS];
+ bool found = false;
+ ArrayType *names;
+ int i;
+
+ if (!parameterNames)
+ return PointerGetDatum(NULL);
+
+ for (i=0; i<parameterCount; i++)
+ {
+ const char *s = parameterNames[i];
+
+ if (s && *s)
+ found = true;
+ else
+ s = "";
+
+ elems[i] = DirectFunctionCall1(textin, CStringGetDatum(s));
+ }
+
+ if (!found)
+ return PointerGetDatum(NULL);
+
+ names = construct_array(elems, parameterCount, TEXTOID, -1, false, 'i');
+
+ return PointerGetDatum(names);
+}
+
+
/*
* check_sql_fn_retval() -- check return value of a list of sql parse trees.
*
diff --git a/src/backend/commands/functioncmds.c b/src/backend/commands/functioncmds.c
index 05bc52d9de5..2eb4c100a2b 100644
--- a/src/backend/commands/functioncmds.c
+++ b/src/backend/commands/functioncmds.c
@@ -10,7 +10,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/functioncmds.c,v 1.42 2003/11/29 19:51:47 pgsql Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/functioncmds.c,v 1.43 2004/01/06 23:55:18 tgl Exp $
*
* DESCRIPTION
* These routines take the parse tree and pick out the
@@ -130,19 +130,22 @@ compute_return_type(TypeName *returnType, Oid languageOid,
}
/*
- * Interpret the argument-types list of the CREATE FUNCTION statement.
+ * Interpret the parameter list of the CREATE FUNCTION statement.
*/
static int
-compute_parameter_types(List *argTypes, Oid languageOid,
- Oid *parameterTypes)
+examine_parameter_list(List *parameter, Oid languageOid,
+ Oid *parameterTypes, const char *parameterNames[])
{
int parameterCount = 0;
List *x;
MemSet(parameterTypes, 0, FUNC_MAX_ARGS * sizeof(Oid));
- foreach(x, argTypes)
+ MemSet(parameterNames, 0, FUNC_MAX_ARGS * sizeof(char *));
+
+ foreach(x, parameter)
{
- TypeName *t = (TypeName *) lfirst(x);
+ FunctionParameter *fp = (FunctionParameter *) lfirst(x);
+ TypeName *t = fp->argType;
Oid toid;
if (parameterCount >= FUNC_MAX_ARGS)
@@ -182,7 +185,11 @@ compute_parameter_types(List *argTypes, Oid languageOid,
(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
errmsg("functions cannot accept set arguments")));
- parameterTypes[parameterCount++] = toid;
+ parameterTypes[parameterCount] = toid;
+
+ parameterNames[parameterCount] = fp->name;
+
+ parameterCount++;
}
return parameterCount;
@@ -402,6 +409,7 @@ CreateFunction(CreateFunctionStmt *stmt)
AclResult aclresult;
int parameterCount;
Oid parameterTypes[FUNC_MAX_ARGS];
+ const char *parameterNames[FUNC_MAX_ARGS];
bool isStrict,
security;
char volatility;
@@ -480,8 +488,8 @@ CreateFunction(CreateFunctionStmt *stmt)
compute_return_type(stmt->returnType, languageOid,
&prorettype, &returnsSet);
- parameterCount = compute_parameter_types(stmt->argTypes, languageOid,
- parameterTypes);
+ parameterCount = examine_parameter_list(stmt->parameters, languageOid,
+ parameterTypes, parameterNames);
compute_attributes_with_style(stmt->withClause, &isStrict, &volatility);
@@ -527,7 +535,8 @@ CreateFunction(CreateFunctionStmt *stmt)
isStrict,
volatility,
parameterCount,
- parameterTypes);
+ parameterTypes,
+ parameterNames);
}
diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c
index 18a8a369e69..b47c51e4621 100644
--- a/src/backend/nodes/copyfuncs.c
+++ b/src/backend/nodes/copyfuncs.c
@@ -15,7 +15,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.274 2004/01/06 04:31:01 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.275 2004/01/06 23:55:18 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -1878,7 +1878,7 @@ _copyCreateFunctionStmt(CreateFunctionStmt *from)
COPY_SCALAR_FIELD(replace);
COPY_NODE_FIELD(funcname);
- COPY_NODE_FIELD(argTypes);
+ COPY_NODE_FIELD(parameters);
COPY_NODE_FIELD(returnType);
COPY_NODE_FIELD(options);
COPY_NODE_FIELD(withClause);
@@ -1886,6 +1886,17 @@ _copyCreateFunctionStmt(CreateFunctionStmt *from)
return newnode;
}
+static FunctionParameter *
+_copyFunctionParameter(FunctionParameter *from)
+{
+ FunctionParameter *newnode = makeNode(FunctionParameter);
+
+ COPY_STRING_FIELD(name);
+ COPY_NODE_FIELD(argType);
+
+ return newnode;
+}
+
static RemoveAggrStmt *
_copyRemoveAggrStmt(RemoveAggrStmt *from)
{
@@ -2788,6 +2799,9 @@ copyObject(void *from)
case T_CreateFunctionStmt:
retval = _copyCreateFunctionStmt(from);
break;
+ case T_FunctionParameter:
+ retval = _copyFunctionParameter(from);
+ break;
case T_RemoveAggrStmt:
retval = _copyRemoveAggrStmt(from);
break;
diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c
index 41b292a47cc..61e04b1fbda 100644
--- a/src/backend/nodes/equalfuncs.c
+++ b/src/backend/nodes/equalfuncs.c
@@ -18,7 +18,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.212 2004/01/05 05:07:35 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.213 2004/01/06 23:55:18 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -884,7 +884,7 @@ _equalCreateFunctionStmt(CreateFunctionStmt *a, CreateFunctionStmt *b)
{
COMPARE_SCALAR_FIELD(replace);
COMPARE_NODE_FIELD(funcname);
- COMPARE_NODE_FIELD(argTypes);
+ COMPARE_NODE_FIELD(parameters);
COMPARE_NODE_FIELD(returnType);
COMPARE_NODE_FIELD(options);
COMPARE_NODE_FIELD(withClause);
@@ -893,6 +893,15 @@ _equalCreateFunctionStmt(CreateFunctionStmt *a, CreateFunctionStmt *b)
}
static bool
+_equalFunctionParameter(FunctionParameter *a, FunctionParameter *b)
+{
+ COMPARE_STRING_FIELD(name);
+ COMPARE_NODE_FIELD(argType);
+
+ return true;
+}
+
+static bool
_equalRemoveAggrStmt(RemoveAggrStmt *a, RemoveAggrStmt *b)
{
COMPARE_NODE_FIELD(aggname);
@@ -1868,6 +1877,9 @@ equal(void *a, void *b)
case T_CreateFunctionStmt:
retval = _equalCreateFunctionStmt(a, b);
break;
+ case T_FunctionParameter:
+ retval = _equalFunctionParameter(a, b);
+ break;
case T_RemoveAggrStmt:
retval = _equalRemoveAggrStmt(a, b);
break;
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index 8866200444f..a578e5d3116 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -11,7 +11,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.441 2003/12/01 22:07:58 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.442 2004/01/06 23:55:18 tgl Exp $
*
* HISTORY
* AUTHOR DATE MAJOR EVENT
@@ -87,6 +87,7 @@ static Node *makeRowNullTest(NullTestType test, List *args);
static DefElem *makeDefElem(char *name, Node *arg);
static A_Const *makeBoolConst(bool state);
static FuncCall *makeOverlaps(List *largs, List *rargs);
+static List *extractArgTypes(List *parameters);
static SelectStmt *findLeftmostSelect(SelectStmt *node);
static void insertSelectOptions(SelectStmt *stmt,
List *sortClause, List *forUpdate,
@@ -116,6 +117,7 @@ static void doNegateFloat(Value *v);
ObjectType objtype;
TypeName *typnam;
+ FunctionParameter *fun_param;
DefElem *defelt;
SortBy *sortby;
JoinExpr *jexpr;
@@ -230,9 +232,10 @@ static void doNegateFloat(Value *v);
%type <range> into_clause OptTempTableName
%type <defelt> createfunc_opt_item
-%type <typnam> func_arg func_return func_type aggr_argtype
+%type <fun_param> func_arg
+%type <typnam> func_return func_type aggr_argtype
-%type <boolean> opt_arg TriggerForType OptTemp OptWithOids
+%type <boolean> arg_class TriggerForType OptTemp OptWithOids
%type <oncommit> OnCommitOption
%type <list> for_update_clause opt_for_update_clause update_list
@@ -303,7 +306,7 @@ static void doNegateFloat(Value *v);
%type <str> Sconst comment_text
%type <str> UserId opt_boolean ColId_or_Sconst
%type <list> var_list var_list_or_default
-%type <str> ColId ColLabel type_name
+%type <str> ColId ColLabel type_name param_name
%type <node> var_value zone_value
%type <keyword> unreserved_keyword func_name_keyword
@@ -2433,7 +2436,7 @@ opclass_item:
CreateOpClassItem *n = makeNode(CreateOpClassItem);
n->itemtype = OPCLASS_ITEM_FUNCTION;
n->name = $3;
- n->args = $4;
+ n->args = extractArgTypes($4);
n->number = $2;
$$ = (Node *) n;
}
@@ -2562,7 +2565,7 @@ CommentStmt:
CommentStmt *n = makeNode(CommentStmt);
n->objtype = OBJECT_FUNCTION;
n->objname = $4;
- n->objargs = $5;
+ n->objargs = extractArgTypes($5);
n->comment = $7;
$$ = (Node *) n;
}
@@ -2994,7 +2997,7 @@ function_with_argtypes:
{
FuncWithArgs *n = makeNode(FuncWithArgs);
n->funcname = $1;
- n->funcargs = $2;
+ n->funcargs = extractArgTypes($2);
$$ = (Node *)n;
}
;
@@ -3094,7 +3097,7 @@ CreateFunctionStmt:
CreateFunctionStmt *n = makeNode(CreateFunctionStmt);
n->replace = $2;
n->funcname = $4;
- n->argTypes = $5;
+ n->parameters = $5;
n->returnType = $7;
n->options = $8;
n->withClause = $9;
@@ -3116,18 +3119,28 @@ func_args_list:
| func_args_list ',' func_arg { $$ = lappend($1, $3); }
;
-func_arg: opt_arg func_type
+/* We can catch over-specified arguments here if we want to,
+ * but for now better to silently swallow typmod, etc.
+ * - thomas 2000-03-22
+ */
+func_arg:
+ arg_class param_name func_type
{
- /* We can catch over-specified arguments here if we want to,
- * but for now better to silently swallow typmod, etc.
- * - thomas 2000-03-22
- */
- $$ = $2;
+ FunctionParameter *n = makeNode(FunctionParameter);
+ n->name = $2;
+ n->argType = $3;
+ $$ = n;
+ }
+ | arg_class func_type
+ {
+ FunctionParameter *n = makeNode(FunctionParameter);
+ n->name = NULL;
+ n->argType = $2;
+ $$ = n;
}
- | func_type { $$ = $1; }
;
-opt_arg: IN_P { $$ = FALSE; }
+arg_class: IN_P { $$ = FALSE; }
| OUT_P
{
ereport(ERROR,
@@ -3142,6 +3155,13 @@ opt_arg: IN_P { $$ = FALSE; }
errmsg("CREATE FUNCTION / INOUT parameters are not implemented")));
$$ = FALSE;
}
+ | /*EMPTY*/ { $$ = FALSE; }
+ ;
+
+/*
+ * Ideally param_name should be ColId, but that causes too many conflicts.
+ */
+param_name: function_name
;
func_return:
@@ -3255,7 +3275,7 @@ RemoveFuncStmt:
{
RemoveFuncStmt *n = makeNode(RemoveFuncStmt);
n->funcname = $3;
- n->args = $4;
+ n->args = extractArgTypes($4);
n->behavior = $5;
$$ = (Node *)n;
}
@@ -3433,7 +3453,7 @@ RenameStmt: ALTER AGGREGATE func_name '(' aggr_argtype ')' RENAME TO name
RenameStmt *n = makeNode(RenameStmt);
n->renameType = OBJECT_FUNCTION;
n->object = $3;
- n->objarg = $4;
+ n->objarg = extractArgTypes($4);
n->newname = $7;
$$ = (Node *)n;
}
@@ -7402,7 +7422,6 @@ unreserved_keyword:
| INCREMENT
| INDEX
| INHERITS
- | INOUT
| INPUT_P
| INSENSITIVE
| INSERT
@@ -7428,7 +7447,6 @@ unreserved_keyword:
| MONTH_P
| MOVE
| NAMES
- | NATIONAL
| NEXT
| NO
| NOCREATEDB
@@ -7440,13 +7458,11 @@ unreserved_keyword:
| OIDS
| OPERATOR
| OPTION
- | OUT_P
| OWNER
| PARTIAL
| PASSWORD
| PATH_P
| PENDANT
- | PRECISION
| PREPARE
| PRESERVE
| PRIOR
@@ -7543,15 +7559,19 @@ col_name_keyword:
| EXISTS
| EXTRACT
| FLOAT_P
+ | INOUT
| INT_P
| INTEGER
| INTERVAL
+ | NATIONAL
| NCHAR
| NONE
| NULLIF
| NUMERIC
+ | OUT_P
| OVERLAY
| POSITION
+ | PRECISION
| REAL
| ROW
| SETOF
@@ -7582,7 +7602,6 @@ func_name_keyword:
| FREEZE
| FULL
| ILIKE
- | IN_P
| INNER_P
| IS
| ISNULL
@@ -7640,6 +7659,7 @@ reserved_keyword:
| GRANT
| GROUP_P
| HAVING
+ | IN_P
| INITIALLY
| INTERSECT
| INTO
@@ -7942,6 +7962,27 @@ makeOverlaps(List *largs, List *rargs)
return n;
}
+/* extractArgTypes()
+ * Given a list of FunctionParameter nodes, extract a list of just the
+ * argument types (TypeNames). Most of the productions using func_args
+ * don't currently want the full FunctionParameter data, so we use this
+ * rather than having two sets of productions.
+ */
+static List *
+extractArgTypes(List *parameters)
+{
+ List *result = NIL;
+ List *i;
+
+ foreach(i, parameters)
+ {
+ FunctionParameter *p = (FunctionParameter *) lfirst(i);
+
+ result = lappend(result, p->argType);
+ }
+ return result;
+}
+
/* findLeftmostSelect()
* Find the leftmost component SelectStmt in a set-operation parsetree.
*/
diff --git a/src/backend/utils/adt/sets.c b/src/backend/utils/adt/sets.c
index 45a8b9d5080..33f1ed1a4a8 100644
--- a/src/backend/utils/adt/sets.c
+++ b/src/backend/utils/adt/sets.c
@@ -10,7 +10,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/adt/sets.c,v 1.61 2003/11/29 19:51:59 pgsql Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/adt/sets.c,v 1.62 2004/01/06 23:55:18 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -65,8 +65,9 @@ SetDefine(char *querystr, Oid elemType)
false, /* security invoker */
false, /* isStrict (irrelevant, no args) */
PROVOLATILE_VOLATILE, /* assume unsafe */
- 0, /* parameterCount */
- NULL); /* parameterTypes */
+ 0, /* parameterCount */
+ NULL, /* parameterTypes */
+ NULL); /* parameterNames */
/*
* Since we're still inside this command of the transaction, we can't
diff --git a/src/backend/utils/fmgr/fmgr.c b/src/backend/utils/fmgr/fmgr.c
index a6d5246a4aa..c42dfba32b5 100644
--- a/src/backend/utils/fmgr/fmgr.c
+++ b/src/backend/utils/fmgr/fmgr.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/fmgr/fmgr.c,v 1.77 2003/11/29 19:52:01 pgsql Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/fmgr/fmgr.c,v 1.78 2004/01/06 23:55:19 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -155,6 +155,8 @@ fmgr_info_cxt_security(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt,
const FmgrBuiltin *fbp;
HeapTuple procedureTuple;
Form_pg_proc procedureStruct;
+ Datum prosrcdatum;
+ bool isnull;
char *prosrc;
/*
@@ -214,8 +216,12 @@ fmgr_info_cxt_security(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt,
* name of the internal function is stored in prosrc (it
* doesn't have to be the same as the name of the alias!)
*/
+ prosrcdatum = SysCacheGetAttr(PROCOID, procedureTuple,
+ Anum_pg_proc_prosrc, &isnull);
+ if (isnull)
+ elog(ERROR, "null prosrc");
prosrc = DatumGetCString(DirectFunctionCall1(textout,
- PointerGetDatum(&procedureStruct->prosrc)));
+ prosrcdatum));
fbp = fmgr_lookupByName(prosrc);
if (fbp == NULL)
ereport(ERROR,