SQL-standard function body

Enterprise / PostgreSQL - Peter Eisentraut [eisentraut.org] - 7 April 2021 19:47 UTC

This adds support for writing CREATE FUNCTION and CREATE PROCEDURE statements for language SQL with a function body that conforms to the SQL standard and is portable to other implementations.

Instead of the PostgreSQL-specific AS $$ string literal $$ syntax, this allows writing out the SQL statements making up the body unquoted, either as a single statement:

CREATE FUNCTION add(a integer, b integer) RETURNS integer LANGUAGE SQL RETURN a + b;

or as a block

CREATE PROCEDURE insert_data(a integer, b integer) LANGUAGE SQL BEGIN ATOMIC INSERT INTO tbl VALUES (a); INSERT INTO tbl VALUES (b); END;

The function body is parsed at function definition time and stored as expression nodes in a new pg_proc column prosqlbody. So at run time, no further parsing is required.

However, this form does not support polymorphic arguments, because there is no more parse analysis done at call time.

Dependencies between the function and the objects it uses are fully tracked.

A new RETURN statement is introduced. This can only be used inside function bodies. Internally, it is treated much like a SELECT statement.

psql needs some new intelligence to keep track of function body boundaries so that it doesn't send off statements when it sees semicolons that are inside a function body.

e717a9a18b SQL-standard function body
doc/src/sgml/catalogs.sgml | 10 +
doc/src/sgml/ref/create_function.sgml | 125 ++++++++++--
doc/src/sgml/ref/create_procedure.sgml | 61 +++++-
src/backend/catalog/pg_aggregate.c | 1 +
src/backend/catalog/pg_proc.c | 116 +++++++----
src/backend/commands/aggregatecmds.c | 2 +
src/backend/commands/functioncmds.c | 145 ++++++++++---
src/backend/commands/typecmds.c | 4 +
src/backend/executor/functions.c | 79 +++++---
src/backend/nodes/copyfuncs.c | 15 ++
src/backend/nodes/equalfuncs.c | 13 ++
src/backend/nodes/outfuncs.c | 12 ++
src/backend/nodes/readfuncs.c | 1 +
src/backend/optimizer/util/clauses.c | 126 ++++++++----
src/backend/parser/analyze.c | 35 ++++
src/backend/parser/gram.y | 129 +++++++++---
src/backend/tcop/postgres.c | 3 +-
src/backend/utils/adt/ruleutils.c | 139 ++++++++++++-
src/bin/pg_dump/pg_dump.c | 45 ++++-
src/bin/psql/describe.c | 15 +-
src/fe_utils/psqlscan.l | 24 ++-
src/include/catalog/catversion.h | 2 +-
src/include/catalog/pg_proc.dat | 4 +
src/include/catalog/pg_proc.h | 6 +-
src/include/commands/defrem.h | 2 +
src/include/executor/functions.h | 15 ++
src/include/fe_utils/psqlscan_int.h | 2 +
src/include/nodes/nodes.h | 1 +
src/include/nodes/parsenodes.h | 13 ++
src/include/parser/kwlist.h | 2 +
src/include/tcop/tcopprot.h | 1 +
src/interfaces/ecpg/preproc/ecpg.addons | 6 +
src/interfaces/ecpg/preproc/ecpg.trailer | 4 +-
src/test/regress/expected/create_function_3.out | 257 +++++++++++++++++++++++-
src/test/regress/expected/create_procedure.out | 65 ++++++
src/test/regress/sql/create_function_3.sql | 110 +++++++++-
src/test/regress/sql/create_procedure.sql | 33 +++
37 files changed, 1411 insertions(+), 212 deletions(-)

Upstream: git.postgresql.org


  • Share