summaryrefslogtreecommitdiff
path: root/src/backend/parser/gram.y
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/parser/gram.y')
-rw-r--r--src/backend/parser/gram.y48
1 files changed, 43 insertions, 5 deletions
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index 703533891f..4a8bf5fd42 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.642 2008/12/04 11:42:24 heikki Exp $
+ * $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.643 2008/12/04 17:51:26 petere Exp $
*
* HISTORY
* AUTHOR DATE MAJOR EVENT
@@ -255,6 +255,7 @@ static TypeName *TableFuncTypeName(List *columns);
%type <list> stmtblock stmtmulti
OptTableElementList TableElementList OptInherit definition
OptWith opt_distinct opt_definition func_args func_args_list
+ func_args_with_defaults func_args_with_defaults_list
func_as createfunc_opt_list alterfunc_opt_list
aggr_args old_aggr_definition old_aggr_list
oper_argtypes RuleActionList RuleActionMulti
@@ -278,7 +279,7 @@ static TypeName *TableFuncTypeName(List *columns);
%type <into> into_clause create_as_target
%type <defelt> createfunc_opt_item common_func_opt_item
-%type <fun_param> func_arg table_func_column
+%type <fun_param> func_arg func_arg_with_default table_func_column
%type <fun_param_mode> arg_class
%type <typnam> func_return func_type
@@ -4170,7 +4171,7 @@ opt_nulls_order: NULLS_FIRST { $$ = SORTBY_NULLS_FIRST; }
*****************************************************************************/
CreateFunctionStmt:
- CREATE opt_or_replace FUNCTION func_name func_args
+ CREATE opt_or_replace FUNCTION func_name func_args_with_defaults
RETURNS func_return createfunc_opt_list opt_definition
{
CreateFunctionStmt *n = makeNode(CreateFunctionStmt);
@@ -4182,7 +4183,7 @@ CreateFunctionStmt:
n->withClause = $9;
$$ = (Node *)n;
}
- | CREATE opt_or_replace FUNCTION func_name func_args
+ | CREATE opt_or_replace FUNCTION func_name func_args_with_defaults
RETURNS TABLE '(' table_func_column_list ')' createfunc_opt_list opt_definition
{
CreateFunctionStmt *n = makeNode(CreateFunctionStmt);
@@ -4195,7 +4196,7 @@ CreateFunctionStmt:
n->withClause = $12;
$$ = (Node *)n;
}
- | CREATE opt_or_replace FUNCTION func_name func_args
+ | CREATE opt_or_replace FUNCTION func_name func_args_with_defaults
createfunc_opt_list opt_definition
{
CreateFunctionStmt *n = makeNode(CreateFunctionStmt);
@@ -4224,6 +4225,21 @@ func_args_list:
;
/*
+ * func_args_with_defaults is separate because we only want to accept
+ * defaults in CREATE FUNCTION, not in ALTER etc.
+ */
+func_args_with_defaults:
+ '(' func_args_with_defaults_list ')' { $$ = $2; }
+ | '(' ')' { $$ = NIL; }
+ ;
+
+func_args_with_defaults_list:
+ func_arg_with_default { $$ = list_make1( $1); }
+ | func_args_with_defaults_list ',' func_arg_with_default { $$ = lappend($1, $3); }
+ ;
+
+
+/*
* 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
@@ -4240,6 +4256,7 @@ func_arg:
n->name = $2;
n->argType = $3;
n->mode = $1;
+ n->defexpr = NULL;
$$ = n;
}
| param_name arg_class func_type
@@ -4248,6 +4265,7 @@ func_arg:
n->name = $1;
n->argType = $3;
n->mode = $2;
+ n->defexpr = NULL;
$$ = n;
}
| param_name func_type
@@ -4256,6 +4274,7 @@ func_arg:
n->name = $1;
n->argType = $2;
n->mode = FUNC_PARAM_IN;
+ n->defexpr = NULL;
$$ = n;
}
| arg_class func_type
@@ -4264,6 +4283,7 @@ func_arg:
n->name = NULL;
n->argType = $2;
n->mode = $1;
+ n->defexpr = NULL;
$$ = n;
}
| func_type
@@ -4272,6 +4292,7 @@ func_arg:
n->name = NULL;
n->argType = $1;
n->mode = FUNC_PARAM_IN;
+ n->defexpr = NULL;
$$ = n;
}
;
@@ -4322,6 +4343,23 @@ func_type: Typename { $$ = $1; }
}
;
+func_arg_with_default:
+ func_arg
+ {
+ $$ = $1;
+ }
+ | func_arg DEFAULT a_expr
+ {
+ $$ = $1;
+ $$->defexpr = $3;
+ }
+ | func_arg '=' a_expr
+ {
+ $$ = $1;
+ $$->defexpr = $3;
+ }
+ ;
+
createfunc_opt_list:
/* Must be at least one to prevent conflict */