Skip to content

Commit 865f14a

Browse files
committed
Allow named parameters to be specified using => in addition to :=
SQL has standardized on => as the use of to specify named parameters, and we've wanted for many years to support the same syntax ourselves, but this has been complicated by the possible use of => as an operator name. In PostgreSQL 9.0, we began emitting a warning when an operator named => was defined, and in PostgreSQL 9.2, we stopped shipping a =>(text, text) operator as part of hstore. By the time the next major version of PostgreSQL is released, => will have been deprecated for a full five years, so hopefully there won't be too many people still relying on it. We continue to support := for compatibility with previous PostgreSQL releases. Pavel Stehule, reviewed by Petr Jelinek, with a few documentation tweaks by me.
1 parent 4f3924d commit 865f14a

File tree

10 files changed

+124
-24
lines changed

10 files changed

+124
-24
lines changed

doc/src/sgml/func.sgml

+1-1
Original file line numberDiff line numberDiff line change
@@ -6785,7 +6785,7 @@ SELECT SUBSTRING('XY1234Z', 'Y*?([0-9]{1,3})');
67856785
Create interval from years, months, weeks, days, hours, minutes and
67866786
seconds fields
67876787
</entry>
6788-
<entry><literal>make_interval(days := 10)</literal></entry>
6788+
<entry><literal>make_interval(days => 10)</literal></entry>
67896789
<entry><literal>10 days</literal></entry>
67906790
</row>
67916791

doc/src/sgml/syntax.sgml

+16-5
Original file line numberDiff line numberDiff line change
@@ -2596,10 +2596,10 @@ SELECT concat_lower_or_upper('Hello', 'World');
25962596

25972597
<para>
25982598
In named notation, each argument's name is specified using
2599-
<literal>:=</literal> to separate it from the argument expression.
2599+
<literal>=></literal> to separate it from the argument expression.
26002600
For example:
26012601
<screen>
2602-
SELECT concat_lower_or_upper(a := 'Hello', b := 'World');
2602+
SELECT concat_lower_or_upper(a => 'Hello', b => 'World');
26032603
concat_lower_or_upper
26042604
-----------------------
26052605
hello world
@@ -2610,13 +2610,24 @@ SELECT concat_lower_or_upper(a := 'Hello', b := 'World');
26102610
using named notation is that the arguments may be specified in any
26112611
order, for example:
26122612
<screen>
2613-
SELECT concat_lower_or_upper(a := 'Hello', b := 'World', uppercase := true);
2613+
SELECT concat_lower_or_upper(a => 'Hello', b => 'World', uppercase => true);
26142614
concat_lower_or_upper
26152615
-----------------------
26162616
HELLO WORLD
26172617
(1 row)
26182618

2619-
SELECT concat_lower_or_upper(a := 'Hello', uppercase := true, b := 'World');
2619+
SELECT concat_lower_or_upper(a => 'Hello', uppercase => true, b => 'World');
2620+
concat_lower_or_upper
2621+
-----------------------
2622+
HELLO WORLD
2623+
(1 row)
2624+
</screen>
2625+
</para>
2626+
2627+
<para>
2628+
An older syntax based on ":=" is supported for backward compatibility:
2629+
<screen>
2630+
SELECT concat_lower_or_upper(a := 'Hello', uppercase := true, b := 'World');
26202631
concat_lower_or_upper
26212632
-----------------------
26222633
HELLO WORLD
@@ -2638,7 +2649,7 @@ SELECT concat_lower_or_upper(a := 'Hello', uppercase := true, b := 'World');
26382649
already mentioned, named arguments cannot precede positional arguments.
26392650
For example:
26402651
<screen>
2641-
SELECT concat_lower_or_upper('Hello', 'World', uppercase := true);
2652+
SELECT concat_lower_or_upper('Hello', 'World', uppercase => true);
26422653
concat_lower_or_upper
26432654
-----------------------
26442655
HELLO WORLD

doc/src/sgml/xfunc.sgml

+3-3
Original file line numberDiff line numberDiff line change
@@ -776,14 +776,14 @@ SELECT mleast(VARIADIC ARRAY[]::numeric[]);
776776
<literal>VARIADIC</>. For example, this will work:
777777

778778
<screen>
779-
SELECT mleast(VARIADIC arr := ARRAY[10, -1, 5, 4.4]);
779+
SELECT mleast(VARIADIC arr => ARRAY[10, -1, 5, 4.4]);
780780
</screen>
781781

782782
but not these:
783783

784784
<screen>
785-
SELECT mleast(arr := 10);
786-
SELECT mleast(arr := ARRAY[10, -1, 5, 4.4]);
785+
SELECT mleast(arr => 10);
786+
SELECT mleast(arr => ARRAY[10, -1, 5, 4.4]);
787787
</screen>
788788
</para>
789789
</sect2>

src/backend/commands/operatorcmds.c

-10
Original file line numberDiff line numberDiff line change
@@ -87,16 +87,6 @@ DefineOperator(List *names, List *parameters)
8787
/* Convert list of names to a name and namespace */
8888
oprNamespace = QualifiedNameGetCreationNamespace(names, &oprName);
8989

90-
/*
91-
* The SQL standard committee has decided that => should be used for named
92-
* parameters; therefore, a future release of PostgreSQL may disallow it
93-
* as the name of a user-defined operator.
94-
*/
95-
if (strcmp(oprName, "=>") == 0)
96-
ereport(WARNING,
97-
(errmsg("=> is deprecated as an operator name"),
98-
errdetail("This name may be disallowed altogether in future versions of PostgreSQL.")));
99-
10090
/* Check we have creation rights in target namespace */
10191
aclresult = pg_namespace_aclcheck(oprNamespace, GetUserId(), ACL_CREATE);
10292
if (aclresult != ACLCHECK_OK)

src/backend/parser/gram.y

+10-1
Original file line numberDiff line numberDiff line change
@@ -533,7 +533,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
533533
*/
534534
%token <str> IDENT FCONST SCONST BCONST XCONST Op
535535
%token <ival> ICONST PARAM
536-
%token TYPECAST DOT_DOT COLON_EQUALS
536+
%token TYPECAST DOT_DOT COLON_EQUALS EQUALS_GREATER
537537

538538
/*
539539
* If you want to make any keyword changes, update the keyword table in
@@ -12567,6 +12567,15 @@ func_arg_expr: a_expr
1256712567
na->location = @1;
1256812568
$$ = (Node *) na;
1256912569
}
12570+
| param_name EQUALS_GREATER a_expr
12571+
{
12572+
NamedArgExpr *na = makeNode(NamedArgExpr);
12573+
na->name = $1;
12574+
na->arg = (Expr *) $3;
12575+
na->argnumber = -1; /* until determined */
12576+
na->location = @1;
12577+
$$ = (Node *) na;
12578+
}
1257012579
;
1257112580

1257212581
type_list: Typename { $$ = list_make1($1); }

src/backend/parser/scan.l

+6
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,7 @@ identifier {ident_start}{ident_cont}*
334334
typecast "::"
335335
dot_dot \.\.
336336
colon_equals ":="
337+
equals_greater "=>"
337338

338339
/*
339340
* "self" is the set of chars that should be returned as single-character
@@ -808,6 +809,11 @@ other .
808809
return COLON_EQUALS;
809810
}
810811

812+
{equals_greater} {
813+
SET_YYLLOC();
814+
return EQUALS_GREATER;
815+
}
816+
811817
{self} {
812818
SET_YYLLOC();
813819
return yytext[0];

src/test/regress/expected/create_operator.out

+4-3
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,14 @@ CREATE OPERATOR #%# (
2929
-- Test comments
3030
COMMENT ON OPERATOR ###### (int4, NONE) IS 'bad right unary';
3131
ERROR: operator does not exist: integer ######
32-
-- Show deprecated message. => is deprecated now
32+
-- => is disallowed now
3333
CREATE OPERATOR => (
3434
leftarg = int8, -- right unary
3535
procedure = numeric_fac
3636
);
37-
WARNING: => is deprecated as an operator name
38-
DETAIL: This name may be disallowed altogether in future versions of PostgreSQL.
37+
ERROR: syntax error at or near "=>"
38+
LINE 1: CREATE OPERATOR => (
39+
^
3940
-- Should fail. CREATE OPERATOR requires USAGE on SCHEMA
4041
BEGIN TRANSACTION;
4142
CREATE ROLE regress_rol_op1;

src/test/regress/expected/polymorphism.out

+67
Original file line numberDiff line numberDiff line change
@@ -1356,6 +1356,73 @@ select dfunc('a'::text, 'b', flag := true); -- mixed notation
13561356
a
13571357
(1 row)
13581358

1359+
-- ansi/sql syntax
1360+
select dfunc(a => 1, b => 2);
1361+
dfunc
1362+
-------
1363+
1
1364+
(1 row)
1365+
1366+
select dfunc(a => 'a'::text, b => 'b');
1367+
dfunc
1368+
-------
1369+
a
1370+
(1 row)
1371+
1372+
select dfunc(a => 'a'::text, b => 'b', flag => false); -- named notation
1373+
dfunc
1374+
-------
1375+
b
1376+
(1 row)
1377+
1378+
select dfunc(b => 'b'::text, a => 'a'); -- named notation with default
1379+
dfunc
1380+
-------
1381+
a
1382+
(1 row)
1383+
1384+
select dfunc(a => 'a'::text, flag => true); -- named notation with default
1385+
dfunc
1386+
-------
1387+
a
1388+
(1 row)
1389+
1390+
select dfunc(a => 'a'::text, flag => false); -- named notation with default
1391+
dfunc
1392+
-------
1393+
1394+
(1 row)
1395+
1396+
select dfunc(b => 'b'::text, a => 'a', flag => true); -- named notation
1397+
dfunc
1398+
-------
1399+
a
1400+
(1 row)
1401+
1402+
select dfunc('a'::text, 'b', false); -- full positional notation
1403+
dfunc
1404+
-------
1405+
b
1406+
(1 row)
1407+
1408+
select dfunc('a'::text, 'b', flag => false); -- mixed notation
1409+
dfunc
1410+
-------
1411+
b
1412+
(1 row)
1413+
1414+
select dfunc('a'::text, 'b', true); -- full positional notation
1415+
dfunc
1416+
-------
1417+
a
1418+
(1 row)
1419+
1420+
select dfunc('a'::text, 'b', flag => true); -- mixed notation
1421+
dfunc
1422+
-------
1423+
a
1424+
(1 row)
1425+
13591426
-- check reverse-listing of named-arg calls
13601427
CREATE VIEW dfview AS
13611428
SELECT q1, q2,

src/test/regress/sql/create_operator.sql

+1-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ CREATE OPERATOR #%# (
3535
-- Test comments
3636
COMMENT ON OPERATOR ###### (int4, NONE) IS 'bad right unary';
3737

38-
-- Show deprecated message. => is deprecated now
38+
-- => is disallowed now
3939
CREATE OPERATOR => (
4040
leftarg = int8, -- right unary
4141
procedure = numeric_fac

src/test/regress/sql/polymorphism.sql

+16
Original file line numberDiff line numberDiff line change
@@ -748,6 +748,22 @@ select dfunc('a'::text, 'b', flag := false); -- mixed notation
748748
select dfunc('a'::text, 'b', true); -- full positional notation
749749
select dfunc('a'::text, 'b', flag := true); -- mixed notation
750750

751+
-- ansi/sql syntax
752+
select dfunc(a => 1, b => 2);
753+
select dfunc(a => 'a'::text, b => 'b');
754+
select dfunc(a => 'a'::text, b => 'b', flag => false); -- named notation
755+
756+
select dfunc(b => 'b'::text, a => 'a'); -- named notation with default
757+
select dfunc(a => 'a'::text, flag => true); -- named notation with default
758+
select dfunc(a => 'a'::text, flag => false); -- named notation with default
759+
select dfunc(b => 'b'::text, a => 'a', flag => true); -- named notation
760+
761+
select dfunc('a'::text, 'b', false); -- full positional notation
762+
select dfunc('a'::text, 'b', flag => false); -- mixed notation
763+
select dfunc('a'::text, 'b', true); -- full positional notation
764+
select dfunc('a'::text, 'b', flag => true); -- mixed notation
765+
766+
751767
-- check reverse-listing of named-arg calls
752768
CREATE VIEW dfview AS
753769
SELECT q1, q2,

0 commit comments

Comments
 (0)