Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: postgresql-cfbot/postgresql
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: cbf53e2
Choose a base ref
...
head repository: postgresql-cfbot/postgresql
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 894ca76
Choose a head ref
  • 9 commits
  • 117 files changed
  • 3 contributors

Commits on May 20, 2025

  1. Enhancing catalog for support session variables and related support

    This patch introduces new system catalog table pg_variable. This table holds metadata about
    session variables created by command CREATE VARIABLE, and dropped by command DROP VARIABLE.
    Both commands are implemented by this patch. Possibility to change owner, schema or rename.
    
    Access to session variables can be controlled by SELECT or UPDATE rights. Both rights are
    introduced by this patch too.
    
    This patch enhancing pg_dump and psql to support session variables. The changes are related
    to system catalog.
    
    This patch is not short, but the code is simple.
    okbob@github.com authored and Commitfest Bot committed May 20, 2025
    Copy the full SHA
    a27ee09 View commit details
  2. Storage for session variables and SQL interface

    Session variables are stored in session memory in a dedicated hash table.
    They are set by the LET command and read by the SELECT command.
    The access rights should be checked.
    
    The identifiers of session variables should always be shadowed by possible
    column identifiers: we don't want to break an application by creating some
    badly named session variable.
    
    The limits of this patch (solved by other patches):
    
    - session variables block parallel execution
    - session variables blocks simple expression evaluation (in plpgsql)
    - SQL functions with session variables are not inlined
    - CALL statement is not supported (usage of direct access to express executor)
    - EXECUTE statement is not supported (usage of direct access to express executor)
    - memory used by dropped session variables is not released
    
    Implementations of EXPLAIN LET and PREPARE LET statements
    are in separate patches (for better readability)
    okbob@github.com authored and Commitfest Bot committed May 20, 2025
    Copy the full SHA
    3c6831f View commit details
  3. function pg_session_variables for cleaning tests

    This is a function designed for testing and debugging.  It returns the
    content of sessionvars as-is, and can therefore display entries about
    session variables that were dropped but for which this backend didn't
    process the shared invalidations yet.
    okbob@github.com authored and Commitfest Bot committed May 20, 2025
    Copy the full SHA
    27a8c2a View commit details
  4. DISCARD VARIABLES

    Implementation of DISCARD VARIABLES commands by removing hash table with session variables
    and resetting related memory context.
    okbob@github.com authored and Commitfest Bot committed May 20, 2025
    Copy the full SHA
    da3c2f0 View commit details
  5. memory cleaning after DROP VARIABLE

    Accepting a sinval message invalidates entries in the "sessionvars" hash table.
    These entries are validated before any read or write operations on session variables.
    When the entry cannot be validated, it is removed.  Removal will be delayed when
    the variable was dropped by the current transaction, which could still be rolled back.
    laurenz authored and Commitfest Bot committed May 20, 2025
    Copy the full SHA
    c75cbbe View commit details
  6. plpgsql tests

    laurenz authored and Commitfest Bot committed May 20, 2025
    Copy the full SHA
    193a31e View commit details
  7. GUC session_variables_ambiguity_warning

    Inside an query the session variables can be shadowed. This behaviour is by design,
    because this ensuring so new variables doesn't break existing queries. But this
    behaviour can be confusing, because shadowing is quiet.
    
    When new GUC session_variables_ambiguity_warning is on, then the warning
    is displayed, when some session variable can be used, but it is not used
    due shadowing. This feature should to help with investigation of unexpected
    behaviour.
    
    Note: PLpgSQL has an option that controls priority of identifier's spaces
    (SQL or PLpgSQL). Default behaviour doesn't allows collisions. I believe
    this default is the best. I cannot to implement similar very strict
    behaviour to session variables, because one unhappy named session variable
    can breaks an applications. The problems related to badly named PLpgSQL's
    varible is limitted just to only one routine.
    okbob@github.com authored and Commitfest Bot committed May 20, 2025
    Copy the full SHA
    4652e2b View commit details
  8. variable fence syntax support and variable fence usage guard support

    this patch introduces a concept of variable fence - syntax for variable
    reference `VARIABLE(varname)` that is not in collision with column reference.
    When variable fence usage guard warning is active, then usage variable
    without variable fence in the case, where there can be column references,
    the the warning is raised.
    
    initial implementation of variable fence
    okbob@github.com authored and Commitfest Bot committed May 20, 2025
    Copy the full SHA
    d5b7c3b View commit details
  9. [CF 1608] v20250515 - declarative session variables, LET command

    This branch was automatically generated by a robot using patches from an
    email thread registered at:
    
    https://commitfest.postgresql.org/patch/1608
    
    The branch will be overwritten each time a new patch version is posted to
    the thread, and also periodically to check for bitrot caused by changes
    on the master branch.
    
    Patch(es): https://www.postgresql.org/message-id/CAFj8pRCEjG005L=1vGbir-odYdcYxByOAeFVJ_K9eRcRF=MbNQ@mail.gmail.com
    Author(s): Pavel Stehule
    Commitfest Bot committed May 20, 2025
    Copy the full SHA
    894ca76 View commit details
Showing with 9,966 additions and 64 deletions.
  1. +134 −0 doc/src/sgml/catalogs.sgml
  2. +125 −0 doc/src/sgml/config.sgml
  3. +125 −2 doc/src/sgml/ddl.sgml
  4. +34 −2 doc/src/sgml/func.sgml
  5. +16 −0 doc/src/sgml/glossary.sgml
  6. +6 −0 doc/src/sgml/parallel.sgml
  7. +14 −0 doc/src/sgml/plpgsql.sgml
  8. +4 −0 doc/src/sgml/ref/allfiles.sgml
  9. +21 −8 doc/src/sgml/ref/alter_default_privileges.sgml
  10. +179 −0 doc/src/sgml/ref/alter_variable.sgml
  11. +1 −0 doc/src/sgml/ref/comment.sgml
  12. +9 −3 doc/src/sgml/ref/create_schema.sgml
  13. +152 −0 doc/src/sgml/ref/create_variable.sgml
  14. +12 −1 doc/src/sgml/ref/discard.sgml
  15. +118 −0 doc/src/sgml/ref/drop_variable.sgml
  16. +13 −7 doc/src/sgml/ref/grant.sgml
  17. +96 −0 doc/src/sgml/ref/let.sgml
  18. +13 −0 doc/src/sgml/ref/psql-ref.sgml
  19. +8 −0 doc/src/sgml/ref/revoke.sgml
  20. +4 −0 doc/src/sgml/reference.sgml
  21. +1 −0 src/backend/catalog/Makefile
  22. +76 −0 src/backend/catalog/aclchk.c
  23. +11 −0 src/backend/catalog/dependency.c
  24. +1 −0 src/backend/catalog/meson.build
  25. +510 −0 src/backend/catalog/namespace.c
  26. +119 −2 src/backend/catalog/objectaddress.c
  27. +2 −0 src/backend/catalog/pg_shdepend.c
  28. +258 −0 src/backend/catalog/pg_variable.c
  29. +1 −0 src/backend/commands/Makefile
  30. +9 −0 src/backend/commands/alter.c
  31. +6 −0 src/backend/commands/discard.c
  32. +4 −0 src/backend/commands/dropcmds.c
  33. +4 −0 src/backend/commands/event_trigger.c
  34. +1 −0 src/backend/commands/meson.build
  35. +10 −0 src/backend/commands/prepare.c
  36. +1 −0 src/backend/commands/seclabel.c
  37. +792 −0 src/backend/commands/session_variable.c
  38. +41 −0 src/backend/commands/tablecmds.c
  39. +15 −0 src/backend/commands/typecmds.c
  40. +1 −0 src/backend/executor/Makefile
  41. +32 −0 src/backend/executor/execExpr.c
  42. +66 −0 src/backend/executor/execMain.c
  43. +1 −0 src/backend/executor/meson.build
  44. +172 −0 src/backend/executor/svariableReceiver.c
  45. +16 −0 src/backend/nodes/nodeFuncs.c
  46. +36 −0 src/backend/optimizer/plan/planner.c
  47. +149 −7 src/backend/optimizer/plan/setrefs.c
  48. +3 −0 src/backend/optimizer/prep/prepjointree.c
  49. +32 −1 src/backend/optimizer/util/clauses.c
  50. +271 −1 src/backend/parser/analyze.c
  51. +170 −8 src/backend/parser/gram.y
  52. +9 −0 src/backend/parser/parse_agg.c
  53. +331 −1 src/backend/parser/parse_expr.c
  54. +2 −0 src/backend/parser/parse_func.c
  55. +1 −0 src/backend/parser/parse_merge.c
  56. +7 −0 src/backend/parser/parse_target.c
  57. +12 −0 src/backend/parser/parse_utilcmd.c
  58. +7 −0 src/backend/tcop/dest.c
  59. +39 −0 src/backend/tcop/utility.c
  60. +221 −0 src/backend/utils/adt/acl.c
  61. +54 −0 src/backend/utils/adt/ruleutils.c
  62. +113 −0 src/backend/utils/cache/lsyscache.c
  63. +37 −4 src/backend/utils/cache/plancache.c
  64. +7 −3 src/backend/utils/fmgr/fmgr.c
  65. +18 −0 src/backend/utils/misc/guc_tables.c
  66. +2 −0 src/backend/utils/misc/postgresql.conf.sample
  67. +3 −0 src/bin/pg_dump/common.c
  68. +6 −0 src/bin/pg_dump/dumputils.c
  69. +2 −0 src/bin/pg_dump/pg_backup.h
  70. +9 −0 src/bin/pg_dump/pg_backup_archiver.c
  71. +190 −0 src/bin/pg_dump/pg_dump.c
  72. +15 −0 src/bin/pg_dump/pg_dump.h
  73. +7 −0 src/bin/pg_dump/pg_dump_sort.c
  74. +64 −0 src/bin/pg_dump/t/002_pg_dump.pl
  75. +3 −0 src/bin/psql/command.c
  76. +99 −1 src/bin/psql/describe.c
  77. +3 −0 src/bin/psql/describe.h
  78. +1 −0 src/bin/psql/help.c
  79. +50 −9 src/bin/psql/tab-complete.in.c
  80. +2 −1 src/include/catalog/Makefile
  81. +1 −0 src/include/catalog/meson.build
  82. +7 −0 src/include/catalog/namespace.h
  83. +1 −0 src/include/catalog/pg_default_acl.h
  84. +31 −0 src/include/catalog/pg_proc.dat
  85. +90 −0 src/include/catalog/pg_variable.h
  86. +34 −0 src/include/commands/session_variable.h
  87. +22 −0 src/include/executor/svariableReceiver.h
  88. +14 −0 src/include/nodes/execnodes.h
  89. +44 −0 src/include/nodes/parsenodes.h
  90. +14 −0 src/include/nodes/pathnodes.h
  91. +9 −0 src/include/nodes/plannodes.h
  92. +16 −0 src/include/nodes/primnodes.h
  93. +2 −0 src/include/optimizer/planmain.h
  94. +3 −0 src/include/parser/kwlist.h
  95. +2 −0 src/include/parser/parse_expr.h
  96. +3 −0 src/include/parser/parse_node.h
  97. +5 −0 src/include/tcop/cmdtaglist.h
  98. +1 −0 src/include/tcop/dest.h
  99. +1 −0 src/include/utils/acl.h
  100. +9 −0 src/include/utils/lsyscache.h
  101. +2 −1 src/pl/plpgsql/src/Makefile
  102. +415 −0 src/pl/plpgsql/src/expected/plpgsql_session_variable.out
  103. +1 −0 src/pl/plpgsql/src/meson.build
  104. +2 −1 src/pl/plpgsql/src/pl_exec.c
  105. +318 −0 src/pl/plpgsql/src/sql/plpgsql_session_variable.sql
  106. +110 −0 src/test/isolation/expected/session-variable.out
  107. +1 −0 src/test/isolation/isolation_schedule
  108. +50 −0 src/test/isolation/specs/session-variable.spec
  109. +17 −0 src/test/regress/expected/dependency.out
  110. +4 −0 src/test/regress/expected/oidjoins.out
  111. +50 −0 src/test/regress/expected/psql.out
  112. +2,030 −0 src/test/regress/expected/session_variables.out
  113. +1 −1 src/test/regress/parallel_schedule
  114. +14 −0 src/test/regress/sql/dependency.sql
  115. +21 −0 src/test/regress/sql/psql.sql
  116. +1,403 −0 src/test/regress/sql/session_variables.sql
  117. +9 −0 src/tools/pgindent/typedefs.list
134 changes: 134 additions & 0 deletions doc/src/sgml/catalogs.sgml
Original file line number Diff line number Diff line change
@@ -369,6 +369,11 @@
<entry><link linkend="catalog-pg-user-mapping"><structname>pg_user_mapping</structname></link></entry>
<entry>mappings of users to foreign servers</entry>
</row>

<row>
<entry><link linkend="catalog-pg-variable"><structname>pg_variable</structname></link></entry>
<entry>session variables</entry>
</row>
</tbody>
</tgroup>
</table>
@@ -3362,6 +3367,7 @@ SCRAM-SHA-256$<replaceable>&lt;iteration count&gt;</replaceable>:<replaceable>&l
<literal>T</literal> = type,
<literal>n</literal> = schema,
<literal>L</literal> = large object
<literal>V</literal> = session variable
</para></entry>
</row>

@@ -9779,4 +9785,132 @@ SCRAM-SHA-256$<replaceable>&lt;iteration count&gt;</replaceable>:<replaceable>&l
</table>
</sect1>

<sect1 id="catalog-pg-variable">
<title><structname>pg_variable</structname></title>

<indexterm zone="catalog-pg-variable">
<primary>pg_variable</primary>
</indexterm>

<para>
The catalog <structname>pg_variable</structname> stores information about
session variables.
</para>

<table>
<title><structname>pg_variable</structname> Columns</title>
<tgroup cols="1">
<thead>
<row>
<entry role="catalog_table_entry"><para role="column_definition">
Column Type
</para>
<para>
Description
</para></entry>
</row>
</thead>

<tbody>
<row>
<entry role="catalog_table_entry"><para role="column_definition">
<structfield>oid</structfield> <type>oid</type>
</para>
<para>
Row identifier
</para></entry>
</row>

<row>
<entry role="catalog_table_entry"><para role="column_definition">
<structfield>vartype</structfield> <type>oid</type>
(references <link linkend="catalog-pg-type"><structname>pg_type</structname></link>.<structfield>oid</structfield>)
</para>
<para>
The OID of the variable's data type
</para></entry>
</row>

<row>
<entry role="catalog_table_entry"><para role="column_definition">
<structfield>varcreate_lsn</structfield> <type>pg_lsn</type>
</para>
<para>
LSN of the transaction where the variable was created.
<structfield>varcreate_lsn</structfield> and
<structfield>oid</structfield> together form the all-time unique
identifier (<structfield>oid</structfield> alone is not enough, since
object identifiers can get reused).
</para></entry>
</row>

<row>
<entry role="catalog_table_entry"><para role="column_definition">
<structfield>varname</structfield> <type>name</type>
</para>
<para>
Name of the session variable
</para></entry>
</row>

<row>
<entry role="catalog_table_entry"><para role="column_definition">
<structfield>varnamespace</structfield> <type>oid</type>
(references <link linkend="catalog-pg-namespace"><structname>pg_namespace</structname></link>.<structfield>oid</structfield>)
</para>
<para>
The OID of the namespace that contains this variable
</para></entry>
</row>

<row>
<entry role="catalog_table_entry"><para role="column_definition">
<structfield>varowner</structfield> <type>oid</type>
(references <link linkend="catalog-pg-authid"><structname>pg_authid</structname></link>.<structfield>oid</structfield>)
</para>
<para>
Owner of the variable
</para></entry>
</row>

<row>
<entry role="catalog_table_entry"><para role="column_definition">
<structfield>vartypmod</structfield> <type>int4</type>
</para>
<para>
<structfield>vartypmod</structfield> records type-specific data
supplied at variable creation time (for example, the maximum
length of a <type>varchar</type> column). It is passed to
type-specific input functions and length coercion functions.
The value will generally be -1 for types that do not need <structfield>vartypmod</structfield>.
</para></entry>
</row>

<row>
<entry role="catalog_table_entry"><para role="column_definition">
<structfield>varcollation</structfield> <type>oid</type>
(references <link linkend="catalog-pg-collation"><structname>pg_collation</structname></link>.<structfield>oid</structfield>)
</para>
<para>
The defined collation of the variable, or zero if the variable is
not of a collatable data type.
</para></entry>
</row>

<row>
<entry role="catalog_table_entry"><para role="column_definition">
<structfield>varacl</structfield> <type>aclitem[]</type>
</para>
<para>
Access privileges; see
<xref linkend="sql-grant"/> and
<xref linkend="sql-revoke"/>
for details
</para></entry>
</row>

</tbody>
</tgroup>
</table>
</sect1>
</chapter>
125 changes: 125 additions & 0 deletions doc/src/sgml/config.sgml
Original file line number Diff line number Diff line change
@@ -11374,6 +11374,131 @@ dynamic_library_path = '/usr/local/lib/postgresql:$libdir'
</listitem>
</varlistentry>

<varlistentry id="guc-session-variables-ambiguity-warning" xreflabel="session_variables_ambiguity_warning">
<term><varname>session_variables_ambiguity_warning</varname> (<type>boolean</type>)
<indexterm>
<primary><varname>session_variables_ambiguity_warning</varname> configuration parameter</primary>
</indexterm>
</term>
<listitem>
<para>
When on, a warning is raised when any identifier in a query could be
used as both a column identifier, routine variable or a session
variable identifier. The default is <literal>off</literal>.
</para>
<para>
Session variables can be shadowed by column references in a query, this
is an expected behavior. Previously working queries shouldn't error out
by creating any session variable, so session variables are always shadowed
if an identifier is ambiguous. Variables should be referenced using
anunambiguous identifier without any possibility for a collision with
identifier of other database objects (column names or record fields names).
The warning messages emitted when enabling <varname>session_variables_ambiguity_warning</varname>
can help finding such identifier collision.
<programlisting>
CREATE TABLE foo(a int);
INSERT INTO foo VALUES(10);
CREATE VARIABLE a int;
LET a = 100;
SELECT a FROM foo;
</programlisting>

<screen>
a
----
10
(1 row)
</screen>

<programlisting>
SET session_variables_ambiguity_warning TO on;
SELECT a FROM foo;
</programlisting>

<screen>
WARNING: session variable "a" is shadowed
LINE 1: SELECT a FROM foo;
^
DETAIL: Session variables can be shadowed by columns, routine's variables and routine's arguments with the same name.
a
----
10
(1 row)
</screen>
</para>
<para>
This feature can significantly increase log size, so it's disabled by
default. For testing or development environments it's recommended to
enable it if you use session variables.
</para>
</listitem>
</varlistentry>

<varlistentry id="guc-session-variables-use-fence-warning-guard" xreflabel="session_variables_use_fence_warning_guard">
<term><varname>session_variables_use_fence_warning_guard</varname> (<type>boolean</type>)
<indexterm>
<primary><varname>session_variables_use_fence_warning_guard</varname> configuration parameter</primary>
</indexterm>
</term>
<listitem>
<para>
When on, a warning is raised when a session variable identifier is used
inside a query without variable fence. The default is <literal>off</literal>.
The warning is raised only when variable is used in places, where an
collisions with column names is possible.
<programlisting>
CREATE TABLE foo(a int);
INSERT INTO foo VALUES(10);
CREATE VARIABLE b int;
LET b = 100;
SELECT a, b FROM foo;
</programlisting>

<screen>
a | b
----+-----
10 | 100
(1 row)
</screen>

<programlisting>
SET session_variables_use_fence_warning_guard TO on;
SELECT a, b FROM foo;
</programlisting>

<screen>
WARNING: session variable "b" is not used inside variable fence
LINE 1: SELECT a, b FROM foo;
^
DETAIL: The collision of session variable' names and column names is possible.
a | b
----+-----
10 | 100
(1 row)
</screen>

<programlisting>
SELECT a, VARIABLE(b) FROM foo;
</programlisting>

<screen>
a | b
----+-----
10 | 100
(1 row)
</screen>
</para>

<para>
This feature can significantly increase log size, so it's disabled by
default. Unless another collision resolution technique is used
(dedicated schema or using prefixes like <literal>_</literal>),
the use of variable fence syntax is strongly recommended, and this
warning should be enabled.
</para>
</listitem>
</varlistentry>

<varlistentry id="guc-standard-conforming-strings" xreflabel="standard_conforming_strings">
<term><varname>standard_conforming_strings</varname> (<type>boolean</type>)
<indexterm><primary>strings</primary><secondary>standard conforming</secondary></indexterm>
Loading