diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2021-01-04 11:52:00 -0500 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2021-01-04 11:52:00 -0500 |
commit | c9d5298485b78a37923a23f9af9aa0ade06762db (patch) | |
tree | 4e7e39d4035be1dcea11809ab2c43ed69bc4d8c7 /doc/src | |
parent | 844fe9f159a948377907a63d0ef3fb16dc51ce50 (diff) | |
download | postgresql-c9d5298485b78a37923a23f9af9aa0ade06762db.tar.gz postgresql-c9d5298485b78a37923a23f9af9aa0ade06762db.zip |
Re-implement pl/pgsql's expression and assignment parsing.
Invent new RawParseModes that allow the core grammar to handle
pl/pgsql expressions and assignments directly, and thereby get rid
of a lot of hackery in pl/pgsql's parser. This moves a good deal
of knowledge about pl/pgsql into the core code: notably, we have to
invent a CoercionContext that matches pl/pgsql's (rather dubious)
historical behavior for assignment coercions. That's getting away
from the original idea of pl/pgsql as an arm's-length extension of
the core, but really we crossed that bridge a long time ago.
The main advantage of doing this is that we can now use the core
parser to generate FieldStore and/or SubscriptingRef nodes to handle
assignments to pl/pgsql variables that are records or arrays. That
fixes a number of cases that had never been implemented in pl/pgsql
assignment, such as nested records and array slicing, and it allows
pl/pgsql assignment to support the datatype-specific subscripting
behaviors introduced in commit c7aba7c14.
There are cosmetic benefits too: when a syntax error occurs in a
pl/pgsql expression, the error report no longer includes the confusing
"SELECT" keyword that used to get prefixed to the expression text.
Also, there seem to be some small speed gains.
Discussion: https://postgr.es/m/4165684.1607707277@sss.pgh.pa.us
Diffstat (limited to 'doc/src')
-rw-r--r-- | doc/src/sgml/plpgsql.sgml | 21 |
1 files changed, 19 insertions, 2 deletions
diff --git a/doc/src/sgml/plpgsql.sgml b/doc/src/sgml/plpgsql.sgml index 11246aa6534..45d3e43ed14 100644 --- a/doc/src/sgml/plpgsql.sgml +++ b/doc/src/sgml/plpgsql.sgml @@ -946,8 +946,8 @@ PREPARE <replaceable>statement_name</replaceable>(integer, integer) AS SELECT $1 database engine. The expression must yield a single value (possibly a row value, if the variable is a row or record variable). The target variable can be a simple variable (optionally qualified with a block - name), a field of a row or record variable, or an element of an array - that is a simple variable or field. Equal (<literal>=</literal>) can be + name), a field of a row or record target, or an element or slice of + an array target. Equal (<literal>=</literal>) can be used instead of PL/SQL-compliant <literal>:=</literal>. </para> @@ -968,8 +968,25 @@ PREPARE <replaceable>statement_name</replaceable>(integer, integer) AS SELECT $1 <programlisting> tax := subtotal * 0.06; my_record.user_id := 20; +my_array[j] := 20; +my_array[1:3] := array[1,2,3]; +complex_array[n].realpart = 12.3; </programlisting> </para> + + <para> + It's useful to know that what follows the assignment operator is + essentially treated as a <literal>SELECT</literal> command; as long + as it returns a single row and column, it will work. Thus for example + one can write something like +<programlisting> +total_sales := sum(quantity) from sales; +</programlisting> + This provides an effect similar to the single-row <literal>SELECT + ... INTO</literal> syntax described in + <xref linkend="plpgsql-statements-sql-onerow"/>. However, that syntax + is more portable. + </para> </sect2> <sect2 id="plpgsql-statements-sql-noresult"> |