mirror of
https://github.com/postgres/postgres.git
synced 2025-06-14 18:42:34 +03:00
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.
This commit is contained in:
@ -6785,7 +6785,7 @@ SELECT SUBSTRING('XY1234Z', 'Y*?([0-9]{1,3})');
|
|||||||
Create interval from years, months, weeks, days, hours, minutes and
|
Create interval from years, months, weeks, days, hours, minutes and
|
||||||
seconds fields
|
seconds fields
|
||||||
</entry>
|
</entry>
|
||||||
<entry><literal>make_interval(days := 10)</literal></entry>
|
<entry><literal>make_interval(days => 10)</literal></entry>
|
||||||
<entry><literal>10 days</literal></entry>
|
<entry><literal>10 days</literal></entry>
|
||||||
</row>
|
</row>
|
||||||
|
|
||||||
|
@ -2596,10 +2596,10 @@ SELECT concat_lower_or_upper('Hello', 'World');
|
|||||||
|
|
||||||
<para>
|
<para>
|
||||||
In named notation, each argument's name is specified using
|
In named notation, each argument's name is specified using
|
||||||
<literal>:=</literal> to separate it from the argument expression.
|
<literal>=></literal> to separate it from the argument expression.
|
||||||
For example:
|
For example:
|
||||||
<screen>
|
<screen>
|
||||||
SELECT concat_lower_or_upper(a := 'Hello', b := 'World');
|
SELECT concat_lower_or_upper(a => 'Hello', b => 'World');
|
||||||
concat_lower_or_upper
|
concat_lower_or_upper
|
||||||
-----------------------
|
-----------------------
|
||||||
hello world
|
hello world
|
||||||
@ -2610,13 +2610,24 @@ SELECT concat_lower_or_upper(a := 'Hello', b := 'World');
|
|||||||
using named notation is that the arguments may be specified in any
|
using named notation is that the arguments may be specified in any
|
||||||
order, for example:
|
order, for example:
|
||||||
<screen>
|
<screen>
|
||||||
SELECT concat_lower_or_upper(a := 'Hello', b := 'World', uppercase := true);
|
SELECT concat_lower_or_upper(a => 'Hello', b => 'World', uppercase => true);
|
||||||
concat_lower_or_upper
|
concat_lower_or_upper
|
||||||
-----------------------
|
-----------------------
|
||||||
HELLO WORLD
|
HELLO WORLD
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
SELECT concat_lower_or_upper(a := 'Hello', uppercase := true, b := 'World');
|
SELECT concat_lower_or_upper(a => 'Hello', uppercase => true, b => 'World');
|
||||||
|
concat_lower_or_upper
|
||||||
|
-----------------------
|
||||||
|
HELLO WORLD
|
||||||
|
(1 row)
|
||||||
|
</screen>
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
An older syntax based on ":=" is supported for backward compatibility:
|
||||||
|
<screen>
|
||||||
|
SELECT concat_lower_or_upper(a := 'Hello', uppercase := true, b := 'World');
|
||||||
concat_lower_or_upper
|
concat_lower_or_upper
|
||||||
-----------------------
|
-----------------------
|
||||||
HELLO WORLD
|
HELLO WORLD
|
||||||
@ -2638,7 +2649,7 @@ SELECT concat_lower_or_upper(a := 'Hello', uppercase := true, b := 'World');
|
|||||||
already mentioned, named arguments cannot precede positional arguments.
|
already mentioned, named arguments cannot precede positional arguments.
|
||||||
For example:
|
For example:
|
||||||
<screen>
|
<screen>
|
||||||
SELECT concat_lower_or_upper('Hello', 'World', uppercase := true);
|
SELECT concat_lower_or_upper('Hello', 'World', uppercase => true);
|
||||||
concat_lower_or_upper
|
concat_lower_or_upper
|
||||||
-----------------------
|
-----------------------
|
||||||
HELLO WORLD
|
HELLO WORLD
|
||||||
|
@ -776,14 +776,14 @@ SELECT mleast(VARIADIC ARRAY[]::numeric[]);
|
|||||||
<literal>VARIADIC</>. For example, this will work:
|
<literal>VARIADIC</>. For example, this will work:
|
||||||
|
|
||||||
<screen>
|
<screen>
|
||||||
SELECT mleast(VARIADIC arr := ARRAY[10, -1, 5, 4.4]);
|
SELECT mleast(VARIADIC arr => ARRAY[10, -1, 5, 4.4]);
|
||||||
</screen>
|
</screen>
|
||||||
|
|
||||||
but not these:
|
but not these:
|
||||||
|
|
||||||
<screen>
|
<screen>
|
||||||
SELECT mleast(arr := 10);
|
SELECT mleast(arr => 10);
|
||||||
SELECT mleast(arr := ARRAY[10, -1, 5, 4.4]);
|
SELECT mleast(arr => ARRAY[10, -1, 5, 4.4]);
|
||||||
</screen>
|
</screen>
|
||||||
</para>
|
</para>
|
||||||
</sect2>
|
</sect2>
|
||||||
|
@ -87,16 +87,6 @@ DefineOperator(List *names, List *parameters)
|
|||||||
/* Convert list of names to a name and namespace */
|
/* Convert list of names to a name and namespace */
|
||||||
oprNamespace = QualifiedNameGetCreationNamespace(names, &oprName);
|
oprNamespace = QualifiedNameGetCreationNamespace(names, &oprName);
|
||||||
|
|
||||||
/*
|
|
||||||
* The SQL standard committee has decided that => should be used for named
|
|
||||||
* parameters; therefore, a future release of PostgreSQL may disallow it
|
|
||||||
* as the name of a user-defined operator.
|
|
||||||
*/
|
|
||||||
if (strcmp(oprName, "=>") == 0)
|
|
||||||
ereport(WARNING,
|
|
||||||
(errmsg("=> is deprecated as an operator name"),
|
|
||||||
errdetail("This name may be disallowed altogether in future versions of PostgreSQL.")));
|
|
||||||
|
|
||||||
/* Check we have creation rights in target namespace */
|
/* Check we have creation rights in target namespace */
|
||||||
aclresult = pg_namespace_aclcheck(oprNamespace, GetUserId(), ACL_CREATE);
|
aclresult = pg_namespace_aclcheck(oprNamespace, GetUserId(), ACL_CREATE);
|
||||||
if (aclresult != ACLCHECK_OK)
|
if (aclresult != ACLCHECK_OK)
|
||||||
|
@ -533,7 +533,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
|
|||||||
*/
|
*/
|
||||||
%token <str> IDENT FCONST SCONST BCONST XCONST Op
|
%token <str> IDENT FCONST SCONST BCONST XCONST Op
|
||||||
%token <ival> ICONST PARAM
|
%token <ival> ICONST PARAM
|
||||||
%token TYPECAST DOT_DOT COLON_EQUALS
|
%token TYPECAST DOT_DOT COLON_EQUALS EQUALS_GREATER
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If you want to make any keyword changes, update the keyword table in
|
* If you want to make any keyword changes, update the keyword table in
|
||||||
@ -12567,6 +12567,15 @@ func_arg_expr: a_expr
|
|||||||
na->location = @1;
|
na->location = @1;
|
||||||
$$ = (Node *) na;
|
$$ = (Node *) na;
|
||||||
}
|
}
|
||||||
|
| param_name EQUALS_GREATER 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); }
|
type_list: Typename { $$ = list_make1($1); }
|
||||||
|
@ -334,6 +334,7 @@ identifier {ident_start}{ident_cont}*
|
|||||||
typecast "::"
|
typecast "::"
|
||||||
dot_dot \.\.
|
dot_dot \.\.
|
||||||
colon_equals ":="
|
colon_equals ":="
|
||||||
|
equals_greater "=>"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* "self" is the set of chars that should be returned as single-character
|
* "self" is the set of chars that should be returned as single-character
|
||||||
@ -808,6 +809,11 @@ other .
|
|||||||
return COLON_EQUALS;
|
return COLON_EQUALS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{equals_greater} {
|
||||||
|
SET_YYLLOC();
|
||||||
|
return EQUALS_GREATER;
|
||||||
|
}
|
||||||
|
|
||||||
{self} {
|
{self} {
|
||||||
SET_YYLLOC();
|
SET_YYLLOC();
|
||||||
return yytext[0];
|
return yytext[0];
|
||||||
|
@ -29,13 +29,14 @@ CREATE OPERATOR #%# (
|
|||||||
-- Test comments
|
-- Test comments
|
||||||
COMMENT ON OPERATOR ###### (int4, NONE) IS 'bad right unary';
|
COMMENT ON OPERATOR ###### (int4, NONE) IS 'bad right unary';
|
||||||
ERROR: operator does not exist: integer ######
|
ERROR: operator does not exist: integer ######
|
||||||
-- Show deprecated message. => is deprecated now
|
-- => is disallowed now
|
||||||
CREATE OPERATOR => (
|
CREATE OPERATOR => (
|
||||||
leftarg = int8, -- right unary
|
leftarg = int8, -- right unary
|
||||||
procedure = numeric_fac
|
procedure = numeric_fac
|
||||||
);
|
);
|
||||||
WARNING: => is deprecated as an operator name
|
ERROR: syntax error at or near "=>"
|
||||||
DETAIL: This name may be disallowed altogether in future versions of PostgreSQL.
|
LINE 1: CREATE OPERATOR => (
|
||||||
|
^
|
||||||
-- Should fail. CREATE OPERATOR requires USAGE on SCHEMA
|
-- Should fail. CREATE OPERATOR requires USAGE on SCHEMA
|
||||||
BEGIN TRANSACTION;
|
BEGIN TRANSACTION;
|
||||||
CREATE ROLE regress_rol_op1;
|
CREATE ROLE regress_rol_op1;
|
||||||
|
@ -1356,6 +1356,73 @@ select dfunc('a'::text, 'b', flag := true); -- mixed notation
|
|||||||
a
|
a
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
|
-- ansi/sql syntax
|
||||||
|
select dfunc(a => 1, b => 2);
|
||||||
|
dfunc
|
||||||
|
-------
|
||||||
|
1
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
select dfunc(a => 'a'::text, b => 'b');
|
||||||
|
dfunc
|
||||||
|
-------
|
||||||
|
a
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
select dfunc(a => 'a'::text, b => 'b', flag => false); -- named notation
|
||||||
|
dfunc
|
||||||
|
-------
|
||||||
|
b
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
select dfunc(b => 'b'::text, a => 'a'); -- named notation with default
|
||||||
|
dfunc
|
||||||
|
-------
|
||||||
|
a
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
select dfunc(a => 'a'::text, flag => true); -- named notation with default
|
||||||
|
dfunc
|
||||||
|
-------
|
||||||
|
a
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
select dfunc(a => 'a'::text, flag => false); -- named notation with default
|
||||||
|
dfunc
|
||||||
|
-------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
select dfunc(b => 'b'::text, a => 'a', flag => true); -- named notation
|
||||||
|
dfunc
|
||||||
|
-------
|
||||||
|
a
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
select dfunc('a'::text, 'b', false); -- full positional notation
|
||||||
|
dfunc
|
||||||
|
-------
|
||||||
|
b
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
select dfunc('a'::text, 'b', flag => false); -- mixed notation
|
||||||
|
dfunc
|
||||||
|
-------
|
||||||
|
b
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
select dfunc('a'::text, 'b', true); -- full positional notation
|
||||||
|
dfunc
|
||||||
|
-------
|
||||||
|
a
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
select dfunc('a'::text, 'b', flag => true); -- mixed notation
|
||||||
|
dfunc
|
||||||
|
-------
|
||||||
|
a
|
||||||
|
(1 row)
|
||||||
|
|
||||||
-- check reverse-listing of named-arg calls
|
-- check reverse-listing of named-arg calls
|
||||||
CREATE VIEW dfview AS
|
CREATE VIEW dfview AS
|
||||||
SELECT q1, q2,
|
SELECT q1, q2,
|
||||||
|
@ -35,7 +35,7 @@ CREATE OPERATOR #%# (
|
|||||||
-- Test comments
|
-- Test comments
|
||||||
COMMENT ON OPERATOR ###### (int4, NONE) IS 'bad right unary';
|
COMMENT ON OPERATOR ###### (int4, NONE) IS 'bad right unary';
|
||||||
|
|
||||||
-- Show deprecated message. => is deprecated now
|
-- => is disallowed now
|
||||||
CREATE OPERATOR => (
|
CREATE OPERATOR => (
|
||||||
leftarg = int8, -- right unary
|
leftarg = int8, -- right unary
|
||||||
procedure = numeric_fac
|
procedure = numeric_fac
|
||||||
|
@ -748,6 +748,22 @@ select dfunc('a'::text, 'b', flag := false); -- mixed notation
|
|||||||
select dfunc('a'::text, 'b', true); -- full positional notation
|
select dfunc('a'::text, 'b', true); -- full positional notation
|
||||||
select dfunc('a'::text, 'b', flag := true); -- mixed notation
|
select dfunc('a'::text, 'b', flag := true); -- mixed notation
|
||||||
|
|
||||||
|
-- ansi/sql syntax
|
||||||
|
select dfunc(a => 1, b => 2);
|
||||||
|
select dfunc(a => 'a'::text, b => 'b');
|
||||||
|
select dfunc(a => 'a'::text, b => 'b', flag => false); -- named notation
|
||||||
|
|
||||||
|
select dfunc(b => 'b'::text, a => 'a'); -- named notation with default
|
||||||
|
select dfunc(a => 'a'::text, flag => true); -- named notation with default
|
||||||
|
select dfunc(a => 'a'::text, flag => false); -- named notation with default
|
||||||
|
select dfunc(b => 'b'::text, a => 'a', flag => true); -- named notation
|
||||||
|
|
||||||
|
select dfunc('a'::text, 'b', false); -- full positional notation
|
||||||
|
select dfunc('a'::text, 'b', flag => false); -- mixed notation
|
||||||
|
select dfunc('a'::text, 'b', true); -- full positional notation
|
||||||
|
select dfunc('a'::text, 'b', flag => true); -- mixed notation
|
||||||
|
|
||||||
|
|
||||||
-- check reverse-listing of named-arg calls
|
-- check reverse-listing of named-arg calls
|
||||||
CREATE VIEW dfview AS
|
CREATE VIEW dfview AS
|
||||||
SELECT q1, q2,
|
SELECT q1, q2,
|
||||||
|
Reference in New Issue
Block a user