]> granicus.if.org Git - postgresql/commitdiff
Fix grammar for IN/OUT/INOUT parameters. This commit doesn't actually
authorTom Lane <tgl@sss.pgh.pa.us>
Tue, 29 Mar 2005 17:58:51 +0000 (17:58 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Tue, 29 Mar 2005 17:58:51 +0000 (17:58 +0000)
implement any new feature, it just pushes the 'not implemented' error
message deeper into the backend.  I also tweaked the grammar to accept
Oracle-ish parameter syntax (parameter name first), as well as the
SQL99 standard syntax (parameter mode first), since it was easy and
people will doubtless try to use both anyway.

src/backend/commands/functioncmds.c
src/backend/nodes/copyfuncs.c
src/backend/nodes/equalfuncs.c
src/backend/parser/gram.y
src/include/nodes/parsenodes.h

index 069adf46af5acaf4085b02e8ec6cca0a2ee18ff9..c2c521bbfeab77ddc2e1ffbbbcc9bc240763c4e1 100644 (file)
@@ -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))
                {
index 92f7168ae9fbf4d3337636c41a5b5b056f71cfdb..c2130e370d4b8b8277725d131c617d1e11f9e40b 100644 (file)
@@ -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;
 }
index cbd99dab7207787f992efcaa810722296cee2d36..bcf8c36393725505e5a7ee600b577dd47d061326 100644 (file)
@@ -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;
 }
index a88262d432816afb3755be874688a8bbb01dc225..62497957263e6c709d52bc1e83cd68894bedbffe 100644 (file)
@@ -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;
 }
index 8cf274b14ce1374a5151895b56d5f860247fcf48..a6a79e3a4fa5fc041bcdd3b9f9f8bb19915454cd 100644 (file)
@@ -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