aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/commands/functioncmds.c11
-rw-r--r--src/backend/nodes/copyfuncs.c3
-rw-r--r--src/backend/nodes/equalfuncs.c3
-rw-r--r--src/backend/parser/gram.y79
-rw-r--r--src/include/nodes/parsenodes.h17
5 files changed, 81 insertions, 32 deletions
diff --git a/src/backend/commands/functioncmds.c b/src/backend/commands/functioncmds.c
index 069adf46af5..c2c521bbfea 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.57 2005/03/29 00:16:57 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/functioncmds.c,v 1.58 2005/03/29 17:58:49 tgl Exp $
*
* DESCRIPTION
* These routines take the parse tree and pick out the
@@ -154,6 +154,15 @@ examine_parameter_list(List *parameter, Oid languageOid,
errmsg("functions cannot have more than %d arguments",
FUNC_MAX_ARGS)));
+ if (fp->mode == FUNC_PARAM_OUT)
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("CREATE FUNCTION / OUT parameters are not implemented")));
+ if (fp->mode == FUNC_PARAM_INOUT)
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("CREATE FUNCTION / INOUT parameters are not implemented")));
+
toid = LookupTypeName(t);
if (OidIsValid(toid))
{
diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c
index 92f7168ae9f..c2130e370d4 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.298 2005/03/14 00:19:36 neilc Exp $
+ * $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.299 2005/03/29 17:58:50 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -1888,6 +1888,7 @@ _copyFunctionParameter(FunctionParameter *from)
COPY_STRING_FIELD(name);
COPY_NODE_FIELD(argType);
+ COPY_SCALAR_FIELD(mode);
return newnode;
}
diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c
index cbd99dab720..bcf8c363937 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.237 2005/03/14 00:19:36 neilc Exp $
+ * $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.238 2005/03/29 17:58:50 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -949,6 +949,7 @@ _equalFunctionParameter(FunctionParameter *a, FunctionParameter *b)
{
COMPARE_STRING_FIELD(name);
COMPARE_NODE_FIELD(argType);
+ COMPARE_SCALAR_FIELD(mode);
return true;
}
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index a88262d4328..62497957263 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.484 2005/03/14 00:19:36 neilc Exp $
+ * $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.485 2005/03/29 17:58:50 tgl Exp $
*
* HISTORY
* AUTHOR DATE MAJOR EVENT
@@ -114,6 +114,8 @@ static void doNegateFloat(Value *v);
TypeName *typnam;
FunctionParameter *fun_param;
+ FunctionParameterMode fun_param_mode;
+ FuncWithArgs *funwithargs;
DefElem *defelt;
SortBy *sortby;
JoinExpr *jexpr;
@@ -206,7 +208,7 @@ static void doNegateFloat(Value *v);
%type <ival> privilege
%type <list> privileges privilege_list
%type <privtarget> privilege_target
-%type <node> function_with_argtypes
+%type <funwithargs> function_with_argtypes
%type <list> function_with_argtypes_list
%type <chr> TriggerOneEvent
@@ -233,9 +235,10 @@ static void doNegateFloat(Value *v);
%type <defelt> createfunc_opt_item common_func_opt_item
%type <fun_param> func_arg
+%type <fun_param_mode> arg_class
%type <typnam> func_return func_type aggr_argtype
-%type <boolean> arg_class TriggerForType OptTemp
+%type <boolean> TriggerForType OptTemp
%type <oncommit> OnCommitOption
%type <withoids> OptWithOids WithOidsAs
@@ -3177,7 +3180,7 @@ function_with_argtypes:
FuncWithArgs *n = makeNode(FuncWithArgs);
n->funcname = $1;
n->funcargs = extractArgTypes($2);
- $$ = (Node *)n;
+ $$ = n;
}
;
@@ -3295,7 +3298,13 @@ func_args_list:
| func_args_list ',' func_arg { $$ = lappend($1, $3); }
;
-/* We can catch over-specified arguments here if we want to,
+/*
+ * The style with arg_class first is SQL99 standard, but Oracle puts
+ * param_name first; accept both since it's likely people will try both
+ * anyway. Don't bother trying to save productions by letting arg_class
+ * have an empty alternative ... you'll get shift/reduce conflicts.
+ *
+ * We can catch over-specified arguments here if we want to,
* but for now better to silently swallow typmod, etc.
* - thomas 2000-03-22
*/
@@ -3305,33 +3314,48 @@ func_arg:
FunctionParameter *n = makeNode(FunctionParameter);
n->name = $2;
n->argType = $3;
+ n->mode = $1;
$$ = n;
}
- | arg_class func_type
+ | param_name arg_class func_type
{
FunctionParameter *n = makeNode(FunctionParameter);
- n->name = NULL;
+ n->name = $1;
+ n->argType = $3;
+ n->mode = $2;
+ $$ = n;
+ }
+ | param_name func_type
+ {
+ FunctionParameter *n = makeNode(FunctionParameter);
+ n->name = $1;
n->argType = $2;
+ n->mode = FUNC_PARAM_IN;
$$ = n;
}
- ;
-
-arg_class: IN_P { $$ = FALSE; }
- | OUT_P
+ | arg_class func_type
{
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("CREATE FUNCTION / OUT parameters are not implemented")));
- $$ = TRUE;
+ FunctionParameter *n = makeNode(FunctionParameter);
+ n->name = NULL;
+ n->argType = $2;
+ n->mode = $1;
+ $$ = n;
}
- | INOUT
+ | func_type
{
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("CREATE FUNCTION / INOUT parameters are not implemented")));
- $$ = FALSE;
+ FunctionParameter *n = makeNode(FunctionParameter);
+ n->name = NULL;
+ n->argType = $1;
+ n->mode = FUNC_PARAM_IN;
+ $$ = n;
}
- | /*EMPTY*/ { $$ = FALSE; }
+ ;
+
+/* INOUT is SQL99 standard, IN OUT is for Oracle compatibility */
+arg_class: IN_P { $$ = FUNC_PARAM_IN; }
+ | OUT_P { $$ = FUNC_PARAM_OUT; }
+ | INOUT { $$ = FUNC_PARAM_INOUT; }
+ | IN_P OUT_P { $$ = FUNC_PARAM_INOUT; }
;
/*
@@ -3458,7 +3482,7 @@ AlterFunctionStmt:
ALTER FUNCTION function_with_argtypes alterfunc_opt_list opt_restrict
{
AlterFunctionStmt *n = makeNode(AlterFunctionStmt);
- n->func = (FuncWithArgs *) $3;
+ n->func = $3;
n->actions = $4;
$$ = (Node *) n;
}
@@ -3561,7 +3585,7 @@ CreateCastStmt: CREATE CAST '(' Typename AS Typename ')'
CreateCastStmt *n = makeNode(CreateCastStmt);
n->sourcetype = $4;
n->targettype = $6;
- n->func = (FuncWithArgs *) $10;
+ n->func = $10;
n->context = (CoercionContext) $11;
$$ = (Node *)n;
}
@@ -8299,9 +8323,9 @@ check_func_name(List *names)
/* 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.
+ * argument types (TypeNames) for input parameters only. This is what
+ * is needed to look up an existing function, which is what is wanted by
+ * the productions that use this call.
*/
static List *
extractArgTypes(List *parameters)
@@ -8313,7 +8337,8 @@ extractArgTypes(List *parameters)
{
FunctionParameter *p = (FunctionParameter *) lfirst(i);
- result = lappend(result, p->argType);
+ if (p->mode != FUNC_PARAM_OUT) /* keep if IN or INOUT */
+ result = lappend(result, p->argType);
}
return result;
}
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
index 8cf274b14ce..a6a79e3a4fa 100644
--- a/src/include/nodes/parsenodes.h
+++ b/src/include/nodes/parsenodes.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.274 2005/03/14 00:19:37 neilc Exp $
+ * $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.275 2005/03/29 17:58:51 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -899,6 +899,11 @@ typedef struct PrivGrantee
char *groupname;
} PrivGrantee;
+/*
+ * Note: FuncWithArgs carries only the types of the input parameters of the
+ * function. So it is sufficient to identify an existing function, but it
+ * is not enough info to define a function nor to call it.
+ */
typedef struct FuncWithArgs
{
NodeTag type;
@@ -1389,12 +1394,20 @@ typedef struct CreateFunctionStmt
List *withClause; /* a list of DefElem */
} CreateFunctionStmt;
+typedef enum FunctionParameterMode
+{
+ /* the assigned enum values appear in pg_proc, don't change 'em! */
+ FUNC_PARAM_IN = 'i', /* input only */
+ FUNC_PARAM_OUT = 'o', /* output only */
+ FUNC_PARAM_INOUT = 'b' /* both */
+} FunctionParameterMode;
+
typedef struct FunctionParameter
{
NodeTag type;
char *name; /* parameter name, or NULL if not given */
TypeName *argType; /* TypeName for parameter type */
- /* someday add IN/OUT/INOUT indicator here */
+ FunctionParameterMode mode; /* IN/OUT/INOUT */
} FunctionParameter;
typedef struct AlterFunctionStmt