*** a/doc/src/sgml/syntax.sgml
--- b/doc/src/sgml/syntax.sgml
***************
*** 2447,2456 **** SELECT concat_lower_or_upper('Hello', 'World');
  
      <para>
       In named notation, each argument's name is specified using
!      <literal>:=</literal> to separate it from the argument expression.
       For example:
  <screen>
! SELECT concat_lower_or_upper(a := 'Hello', b := 'World');
   concat_lower_or_upper 
  -----------------------
   hello world
--- 2447,2457 ----
  
      <para>
       In named notation, each argument's name is specified using
!      <literal>:=</literal> or <literal>=&gt;</literal> to separate it from the
!      argument expression. <literal>=&gt;</literal> is preferred.
       For example:
  <screen>
! SELECT concat_lower_or_upper(a =&gt; 'Hello', b =&gt; 'World');
   concat_lower_or_upper 
  -----------------------
   hello world
***************
*** 2461,2473 **** SELECT concat_lower_or_upper(a := 'Hello', b := 'World');
       using named notation is that the arguments may be specified in any
       order, for example:
  <screen>
! SELECT concat_lower_or_upper(a := 'Hello', b := 'World', uppercase := true);
   concat_lower_or_upper 
  -----------------------
   HELLO WORLD
  (1 row)
  
! SELECT concat_lower_or_upper(a := 'Hello', uppercase := true, b := 'World');
   concat_lower_or_upper 
  -----------------------
   HELLO WORLD
--- 2462,2474 ----
       using named notation is that the arguments may be specified in any
       order, for example:
  <screen>
! SELECT concat_lower_or_upper(a =&gt; 'Hello', b &gt; 'World', uppercase &gt; true);
   concat_lower_or_upper 
  -----------------------
   HELLO WORLD
  (1 row)
  
! SELECT concat_lower_or_upper(a &gt; 'Hello', uppercase &gt; true, b &gt; 'World');
   concat_lower_or_upper 
  -----------------------
   HELLO WORLD
***************
*** 2489,2495 **** SELECT concat_lower_or_upper(a := 'Hello', uppercase := true, b := 'World');
      already mentioned, named arguments cannot precede positional arguments.
      For example:
  <screen>
! SELECT concat_lower_or_upper('Hello', 'World', uppercase := true);
   concat_lower_or_upper 
  -----------------------
   HELLO WORLD
--- 2490,2496 ----
      already mentioned, named arguments cannot precede positional arguments.
      For example:
  <screen>
! SELECT concat_lower_or_upper('Hello', 'World', uppercase &gt; true);
   concat_lower_or_upper 
  -----------------------
   HELLO WORLD
*** a/src/backend/parser/gram.y
--- b/src/backend/parser/gram.y
***************
*** 501,507 **** static void processCASbits(int cas_bits, int location, const char *constrType,
   */
  %token <str>	IDENT FCONST SCONST BCONST XCONST Op
  %token <ival>	ICONST PARAM
! %token			TYPECAST DOT_DOT COLON_EQUALS
  
  /*
   * If you want to make any keyword changes, update the keyword table in
--- 501,507 ----
   */
  %token <str>	IDENT FCONST SCONST BCONST XCONST Op
  %token <ival>	ICONST PARAM
! %token			TYPECAST DOT_DOT COLON_EQUALS EQUALS_GREATHER
  
  /*
   * If you want to make any keyword changes, update the keyword table in
***************
*** 11856,11861 **** func_arg_expr:  a_expr
--- 11856,11870 ----
  					na->location = @1;
  					$$ = (Node *) na;
  				}
+ 			| param_name EQUALS_GREATHER a_expr
+ 				{
+ 					NamedArgExpr *na = makeNode(NamedArgExpr);
+ 					na->name = $1;
+ 					na->arg = (Expr *) $3;
+ 					na->argnumber = -1;		/* until determined */
+ 					na->location = @1;
+ 					$$ = (Node *) na;
+ 				}
  		;
  
  type_list:	Typename								{ $$ = list_make1($1); }
*** a/src/backend/parser/scan.l
--- b/src/backend/parser/scan.l
***************
*** 320,325 **** identifier		{ident_start}{ident_cont}*
--- 320,326 ----
  typecast		"::"
  dot_dot			\.\.
  colon_equals	":="
+ equals_greather		"=>"
  
  /*
   * "self" is the set of chars that should be returned as single-character
***************
*** 757,762 **** other			.
--- 758,768 ----
  					return COLON_EQUALS;
  				}
  
+ {equals_greather}	{
+ 					SET_YYLLOC();
+ 					return EQUALS_GREATHER;
+ 				}
+ 
  {self}			{
  					SET_YYLLOC();
  					return yytext[0];
*** a/src/test/regress/expected/polymorphism.out
--- b/src/test/regress/expected/polymorphism.out
***************
*** 1179,1184 **** ERROR:  function dfunc(unknown, c := integer, b := date) does not exist
--- 1179,1202 ----
  LINE 1: select * from dfunc('Hello World', c := 20, b := '2009-07-25...
                        ^
  HINT:  No function matches the given name and argument types. You might need to add explicit type casts.
+ select * from dfunc(c => '2009-07-25'::date, a => 'Hello World', b => 20);
+       a      | b  |     c      
+ -------------+----+------------
+  Hello World | 20 | 07-25-2009
+ (1 row)
+ 
+ select * from dfunc('Hello World', b => 20, c => '2009-07-25'::date);
+       a      | b  |     c      
+ -------------+----+------------
+  Hello World | 20 | 07-25-2009
+ (1 row)
+ 
+ select * from dfunc('Hello World', c => '2009-07-25'::date, b => 20);
+       a      | b  |     c      
+ -------------+----+------------
+  Hello World | 20 | 07-25-2009
+ (1 row)
+ 
  drop function dfunc(varchar, numeric, date);
  -- test out parameters with named params
  create function dfunc(a varchar = 'def a', out _a varchar, c numeric = NULL, out _c numeric)
*** a/src/test/regress/sql/polymorphism.sql
--- b/src/test/regress/sql/polymorphism.sql
***************
*** 681,686 **** select * from dfunc('Hello World', b := 20, c := '2009-07-25'::date);
--- 681,690 ----
  select * from dfunc('Hello World', c := '2009-07-25'::date, b := 20);
  select * from dfunc('Hello World', c := 20, b := '2009-07-25'::date);  -- fail
  
+ select * from dfunc(c => '2009-07-25'::date, a => 'Hello World', b => 20);
+ select * from dfunc('Hello World', b => 20, c => '2009-07-25'::date);
+ select * from dfunc('Hello World', c => '2009-07-25'::date, b => 20);
+ 
  drop function dfunc(varchar, numeric, date);
  
  -- test out parameters with named params
