PLpgSQL_func_hashkey *hashkey,
                   bool forValidator);
 static void plpgsql_compile_error_callback(void *arg);
+static void add_parameter_name(int itemtype, int itemno, const char *name);
 static void add_dummy_return(PLpgSQL_function *function);
 static Node *plpgsql_pre_column_ref(ParseState *pstate, ColumnRef *cref);
 static Node *plpgsql_post_column_ref(ParseState *pstate, ColumnRef *cref, Node *var);
                                        out_arg_variables[num_out_args++] = argvariable;
 
                                /* Add to namespace under the $n name */
-                               plpgsql_ns_additem(argitemtype, argvariable->dno, buf);
+                               add_parameter_name(argitemtype, argvariable->dno, buf);
 
                                /* If there's a name for the argument, make an alias */
                                if (argnames && argnames[i][0] != '\0')
-                                       plpgsql_ns_additem(argitemtype, argvariable->dno,
+                                       add_parameter_name(argitemtype, argvariable->dno,
                                                                           argnames[i]);
                        }
 
 }
 
 
+/*
+ * Add a name for a function parameter to the function's namespace
+ */
+static void
+add_parameter_name(int itemtype, int itemno, const char *name)
+{
+       /*
+        * Before adding the name, check for duplicates.  We need this even though
+        * functioncmds.c has a similar check, because that code explicitly
+        * doesn't complain about conflicting IN and OUT parameter names.  In
+        * plpgsql, such names are in the same namespace, so there is no way to
+        * disambiguate.
+        */
+       if (plpgsql_ns_lookup(plpgsql_ns_top(), true,
+                                                 name, NULL, NULL,
+                                                 NULL) != NULL)
+               ereport(ERROR,
+                               (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
+                                errmsg("parameter name \"%s\" used more than once",
+                                               name)));
+
+       /* OK, add the name */
+       plpgsql_ns_additem(itemtype, itemno, name);
+}
+
 /*
  * Add a dummy RETURN statement to the given function's body
  */