Q1
This has finally been added to the official documentation with Postgres 9.4:
An assignment of a value to a PL/pgSQL variable is written as:
variable { := | = } expression;
[...] Equal (=
) can be used instead of PL/SQL-compliant :=
.
Q2
Are there any known consequences using =
instead of :=
?
Yes, I had a case with severe consequences: Function call with named parameters - which is related but not exactly the same thing.
Strictly speaking, the distinction in this case is made in SQL code. But that's an academic differentiation to the unsuspecting programmer.1
Consider the function:
CREATE FUNCTION f_oracle(is_true boolean = TRUE) -- correct use of "="
RETURNS text
LANGUAGE sql AS
$func$
SELECT CASE $1
WHEN TRUE THEN 'That''s true.'
WHEN FALSE THEN 'That''s false.'
ELSE 'How should I know?'
END
$func$;
Note the correct use of =
in the function definition. That's part of the CREATE FUNCTION
syntax - in the style of an SQL assignment.2
Function call with named notation:
SELECT * FROM f_oracle(is_true := TRUE);
Postgres identifies :=
as parameter assignment and all is well. However:
SELECT * FROM f_oracle(is_true = TRUE);
Since =
is the SQL equality operator, Postgres interprets is_true = TRUE
as SQL expression in the context of the calling statement and tries to evaluate it before passing the result as unnamed positional parameter. It looks for an identifier is_true
in the outer scope. If that can't be found:
ERROR: column "is_true" does not exist
That's the lucky case and, luckily, also the common one.
When is_true
can be found in the outer scope (and data types are compatible), is_true = TRUE
is a valid expression with a boolean
result that is accepted by the function. No error occurs. Clearly, this is the intention of the programmer using the SQL equality operator =
...
This db<>fiddle demonstrates the effect.
Old sqlfiddle
Very hard to debug if you're unaware of the distinction between =
and :=
.
Always use the the correct operator.
1 When using named notation in function calls, only :=
is the correct assignment operator. This applies to functions of all languages, not just PL/pgSQL, up to and including pg 9.4. See below.
2
One can use =
(or DEFAULT
) to define default values for function parameters. That's not related to the problem at hand in any way. It's just remarkably close to the incorrect use case.
Postgres 9.0 - 9.4: Transition from :=
to =>
The SQL standard for assignment to named function parameters is =>
(and Oracle's PL/SQL uses it. Postgres could not do the same, since the operator had previously been unreserved, so it's using PL/pgSQL's assignment operator :=
instead. With the release of Postgres 9.0 the use of =>
for other purposes has been deprecated. The release notes:
Deprecate use of => as an operator name (Robert Haas)
Future versions of PostgreSQL will probably reject this operator name
entirely, in order to support the SQL-standard notation for named
function parameters. For the moment, it is still allowed, but a
warning is emitted when such an operator is defined.
If you should be using =>
for something else, cease and desist. It will break in the future.
Postgres 9.5: use =>
now
Starting with this release, the SQL standard operator =>
is used. :=
is still supported for backward compatibility. But use the standard operator in new code that doesn't need to run on very old versions.
This applies to named parameter assignment in function calls (SQL scope), not to the assignment operator :=
in plpgsql code, which remains unchanged.
=
rather than:=
? Being "more modern" doesn't strike me as an advantage. – Flannelette=
instead of:=
. It was initially an accident (habbit from other languages), but I noticed PostgreSQL was willing to create the functions and that they ran fine, so I've stuck with it. – Platinous