agora inbox for [email protected]help / color / mirror / Atom feed
[PATCH v29 11/11] Add documentations about Incremental View Maintenance 166+ messages / 3 participants [nested] [flat]
* [PATCH v29 11/11] Add documentations about Incremental View Maintenance @ 2019-12-20 01:25 Yugo Nagata <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Yugo Nagata @ 2019-12-20 01:25 UTC (permalink / raw) --- doc/src/sgml/catalogs.sgml | 9 + .../sgml/ref/create_materialized_view.sgml | 124 ++++- .../sgml/ref/refresh_materialized_view.sgml | 8 +- doc/src/sgml/rules.sgml | 437 ++++++++++++++++++ doc/src/sgml/system-views.sgml | 9 + 5 files changed, 583 insertions(+), 4 deletions(-) diff --git a/doc/src/sgml/catalogs.sgml b/doc/src/sgml/catalogs.sgml index d17ff51e28..3de3303cac 100644 --- a/doc/src/sgml/catalogs.sgml +++ b/doc/src/sgml/catalogs.sgml @@ -2224,6 +2224,15 @@ SCRAM-SHA-256$<replaceable><iteration count></replaceable>:<replaceable>&l </para></entry> </row> + <row> + <entry role="catalog_table_entry"><para role="column_definition"> + <structfield>relisivm</structfield> <type>bool</type> + </para> + <para> + True if relation is incrementally maintainable materialized view + </para></entry> + </row> + <row> <entry role="catalog_table_entry"><para role="column_definition"> <structfield>relrewrite</structfield> <type>oid</type> diff --git a/doc/src/sgml/ref/create_materialized_view.sgml b/doc/src/sgml/ref/create_materialized_view.sgml index 0d2fea2b97..8c574062db 100644 --- a/doc/src/sgml/ref/create_materialized_view.sgml +++ b/doc/src/sgml/ref/create_materialized_view.sgml @@ -21,7 +21,7 @@ PostgreSQL documentation <refsynopsisdiv> <synopsis> -CREATE MATERIALIZED VIEW [ IF NOT EXISTS ] <replaceable>table_name</replaceable> +CREATE [ INCREMENTAL ] MATERIALIZED VIEW [ IF NOT EXISTS ] <replaceable>table_name</replaceable> [ (<replaceable>column_name</replaceable> [, ...] ) ] [ USING <replaceable class="parameter">method</replaceable> ] [ WITH ( <replaceable class="parameter">storage_parameter</replaceable> [= <replaceable class="parameter">value</replaceable>] [, ... ] ) ] @@ -60,6 +60,125 @@ CREATE MATERIALIZED VIEW [ IF NOT EXISTS ] <replaceable>table_name</replaceable> <title>Parameters</title> <variablelist> + <varlistentry> + <term><literal>INCREMENTAL</literal></term> + <listitem> + <para> + If specified, some triggers are automatically created so that the rows + of the materialized view are immediately updated when base tables of the + materialized view are updated. In general, this allows faster update of + the materialized view at a price of slower update of the base tables + because the triggers will be invoked. We call this form of materialized + view as "Incrementally Maintainable Materialized View" (IMMV). + </para> + <para> + When <acronym>IMMV</acronym> is defined without using <command>WITH NO DATA</command>, + a unique index is created on the view automatically if possible. If the view + definition query has a GROUP BY clause, a unique index is created on the columns + of GROUP BY expressions. Also, if the view has DISTINCT clause, a unique index + is created on all columns in the target list. Otherwise, if the view contains all + primary key attritubes of its base tables in the target list, a unique index is + created on these attritubes. In other cases, no index is created. + </para> + <para> + There are restrictions of query definitions allowed to use this + option. The following are supported in query definitions for IMMV: + <itemizedlist> + + <listitem> + <para> + Inner joins (including self-joins). + </para> + </listitem> + + <listitem> + <para> + Some built-in aggregate functions (count, sum, avg, min, max) without a HAVING + clause. + </para> + </listitem> + </itemizedlist> + + Unsupported queries with this option include the following: + + <itemizedlist> + <listitem> + <para> + Outer joins. + </para> + </listitem> + + <listitem> + <para> + Sub-queries. + </para> + </listitem> + + <listitem> + <para> + Aggregate functions other than built-in count, sum, avg, min and max. + </para> + </listitem> + <listitem> + <para> + Aggregate functions with a HAVING clause. + </para> + </listitem> + <listitem> + <para> + DISTINCT ON, WINDOW, VALUES, LIMIT and OFFSET clause. + </para> + </listitem> + </itemizedlist> + + Other restrictions include: + <itemizedlist> + + <listitem> + <para> + IMMVs must be based on simple base tables. It's not supported to + create them on top of views or materialized views. + </para> + </listitem> + + <listitem> + <para> + It is not supported to include system columns in an IMMV. + <programlisting> +CREATE INCREMENTAL MATERIALIZED VIEW mv_ivm02 AS SELECT i,j FROM mv_base_a WHERE xmin = '610'; +ERROR: system column is not supported with IVM + </programlisting> + </para> + </listitem> + + <listitem> + <para> + Non-immutable functions are not supported. + <programlisting> +CREATE INCREMENTAL MATERIALIZED VIEW mv_ivm12 AS SELECT i,j FROM mv_base_a WHERE i = random()::int; +ERROR: functions in IMMV must be marked IMMUTABLE + </programlisting> + </para> + </listitem> + + <listitem> + <para> + IMMVs do not support expressions that contains aggregates + </para> + </listitem> + + <listitem> + <para> + Logical replication does not support IMMVs. + </para> + </listitem> + + </itemizedlist> + + </para> + </listitem> + </varlistentry> + <varlistentry> <term><literal>IF NOT EXISTS</literal></term> <listitem> @@ -155,7 +274,8 @@ CREATE MATERIALIZED VIEW [ IF NOT EXISTS ] <replaceable>table_name</replaceable> This clause specifies whether or not the materialized view should be populated at creation time. If not, the materialized view will be flagged as unscannable and cannot be queried until <command>REFRESH - MATERIALIZED VIEW</command> is used. + MATERIALIZED VIEW</command> is used. Also, if the view is IMMV, + triggers for maintaining the view are not created. </para> </listitem> </varlistentry> diff --git a/doc/src/sgml/ref/refresh_materialized_view.sgml b/doc/src/sgml/ref/refresh_materialized_view.sgml index 675d6090f3..c29cfc19b6 100644 --- a/doc/src/sgml/ref/refresh_materialized_view.sgml +++ b/doc/src/sgml/ref/refresh_materialized_view.sgml @@ -35,9 +35,13 @@ REFRESH MATERIALIZED VIEW [ CONCURRENTLY ] <replaceable class="parameter">name</ owner of the materialized view. The old contents are discarded. If <literal>WITH DATA</literal> is specified (or defaults) the backing query is executed to provide the new data, and the materialized view is left in a - scannable state. If <literal>WITH NO DATA</literal> is specified no new + scannable state. If the view is an incrementally maintainable materialized + view (IMMV) and was unpopulated, triggers for maintaining the view are + created. Also, a unique index is created for IMMV if it is possible and the + view doesn't have that yet. + If <literal>WITH NO DATA</literal> is specified no new data is generated and the materialized view is left in an unscannable - state. + state. If the view is IMMV, the triggers are dropped. </para> <para> <literal>CONCURRENTLY</literal> and <literal>WITH NO DATA</literal> may not diff --git a/doc/src/sgml/rules.sgml b/doc/src/sgml/rules.sgml index d229b94d39..22e4cad103 100644 --- a/doc/src/sgml/rules.sgml +++ b/doc/src/sgml/rules.sgml @@ -1096,6 +1096,443 @@ SELECT word FROM words ORDER BY word <-> 'caterpiler' LIMIT 10; </sect1> +<sect1 id="rules-ivm"> +<title>Incremental View Maintenance</title> + +<indexterm zone="rules-ivm"> + <primary>incremental view maintenance</primary> +</indexterm> + +<indexterm zone="rules-ivm"> + <primary>materialized view</primary> + <secondary>incremental view maintenance</secondary> +</indexterm> + +<indexterm zone="rules-ivm"> + <primary>view</primary> + <secondary>incremental view maintenance</secondary> +</indexterm> + +<sect2 id="rules-ivm-overview"> +<title>Overview</title> + +<para> + Incremental View Maintenance (<acronym>IVM</acronym>) is a way to make + materialized views up-to-date in which only incremental changes are computed + and applied on views rather than recomputing the contents from scratch as + <command>REFRESH MATERIALIZED VIEW</command> does. <acronym>IVM</acronym> + can update materialized views more efficiently than recomputation when only + small parts of the view are changed. +</para> + +<para> + There are two approaches with regard to timing of view maintenance: + immediate and deferred. In immediate maintenance, views are updated in the + same transaction that its base table is modified. In deferred maintenance, + views are updated after the transaction is committed, for example, when the + view is accessed, as a response to user command like <command>REFRESH + MATERIALIZED VIEW</command>, or periodically in background, and so on. + <productname>PostgreSQL</productname> currently implements only a kind of + immediate maintenance, in which materialized views are updated immediately + in AFTER triggers when a base table is modified. +</para> + +<para> + To create materialized views supporting <acronym>IVM</acronym>, use the + <command>CREATE INCREMENTAL MATERIALIZED VIEW</command>, for example: +<programlisting> +CREATE <emphasis>INCREMENTAL</emphasis> MATERIALIZED VIEW mymatview AS SELECT * FROM mytab; +</programlisting> + When a materialized view is created with the <literal>INCREMENTAL</literal> + keyword, some triggers are automatically created so that the view's contents are + immediately updated when its base tables are modified. We call this form + of materialized view an Incrementally Maintainable Materialized View + (<acronym>IMMV</acronym>). +<programlisting> +postgres=# CREATE INCREMENTAL MATERIALIZED VIEW m AS SELECT * FROM t0; +NOTICE: could not create an index on materialized view "m" automatically +HINT: Create an index on the materialized view for effcient incremental maintenance. +SELECT 3 +postgres=# SELECT * FROM m; + i +--- + 1 + 2 + 3 +(3 rows) + +postgres=# INSERT INTO t0 VALUES (4); +INSERT 0 1 +postgres=# SELECT * FROM m; -- automatically updated + i +--- + 1 + 2 + 3 + 4 +(4 rows) +</programlisting> +</para> + +<para> + Some <acronym>IMMV</acronym>s have hidden columns which are added + automatically when a materialized view is created. Their name starts + with <literal>__ivm_</literal> and they contain information required + for maintaining the <acronym>IMMV</acronym>. Such columns are not visible + when the <acronym>IMMV</acronym> is accessed by <literal>SELECT *</literal> + but are visible if the column name is explicitly specified in the target + list. We can also see the hidden columns in <literal>\d</literal> + meta-commands of <command>psql</command> commands. +</para> + +<para> + In general, <acronym>IMMV</acronym>s allow faster updates of materialized + views at the price of slower updates to their base tables. Updates of + <acronym>IMMV</acronym> is slower because triggers will be invoked and the + view is updated in triggers per modification statement. +</para> + +<para> + For example, suppose a normal materialized view defined as below: + +<programlisting> +test=# CREATE INCREMENTAL MATERIALIZED VIEW mv_ivm AS + SELECT a.aid, b.bid, a.abalance, b.bbalance + FROM pgbench_accounts a JOIN pgbench_branches b USING(bid); +SELECT 10000000 + +</programlisting> + + Updating a tuple in a base table of this materialized view is rapid but the + <command>REFRESH MATERIALIZED VIEW</command> command on this view takes a long time: + +<programlisting> +test=# UPDATE pgbench_accounts SET abalance = 1000 WHERE aid = 1; +UPDATE 1 +Time: 0.990 ms + +test=# REFRESH MATERIALIZED VIEW mv_normal ; +REFRESH MATERIALIZED VIEW +Time: 33533.952 ms (00:33.534) +</programlisting> +</para> + +<para> + On the other hand, after creating <acronym>IMMV</acronym> with the same view + definition as below: + +<programlisting> +test=# CREATE INCREMENTAL MATERIALIZED VIEW mv_ivm AS + SELECT a.aid, b.bid, a.abalance, b.bbalance + FROM pgbench_accounts a JOIN pgbench_branches b USING(bid); +test=# UPDATE pgbench_accounts SET abalance = 1000 WHERE aid = 1; +NOTICE: created index "mv_ivm_index" on materialized view "mv_ivm" +</programlisting> + + updating a tuple in a base table takes more than the normal view, + but its content is updated automatically and this is faster than the + <command>REFRESH MATERIALIZED VIEW</command> command. + +<programlisting> +test=# UPDATE pgbench_accounts SET abalance = 1000 WHERE aid = 1; +UPDATE 1 +Time: 13.068 ms +</programlisting> + +</para> + +<para> + Appropriate indexes on <acronym>IMMV</acronym>s are necessary for + efficient <acronym>IVM</acronym> because it looks for tuples to be + updated in <acronym>IMMV</acronym>. If there are no indexes, it + will take a long time. +</para> + +<para> + Therefore, when <acronym>IMMV</acronym> is defined, a unique index is created on the view + automatically if possible. If the view definition query has a GROUP BY clause, a unique + index is created on the columns of GROUP BY expressions. Also, if the view has DISTINCT + clause, a unique index is created on all columns in the target list. Otherwise, if the + view contains all primary key attritubes of its base tables in the target list, a unique + index is created on these attritubes. In other cases, no index is created. +</para> + +<para> + In the previous example, a unique index "mv_ivm_index" is created on aid and bid + columns of materialized view "mv_ivm", and this enables the rapid update of the view. + Dropping this index make updating the view take a loger time. +<programlisting> +test=# DROP INDEX mv_ivm_index; +DROP INDEX +Time: 67.081 ms + +test=# UPDATE pgbench_accounts SET abalance = 1000 WHERE aid = 1; +UPDATE 1 +Time: 16386.245 ms (00:16.386) +</programlisting> + +</para> + +<para> + <acronym>IVM</acronym> is effective when we want to keep a materialized + view up-to-date and small fraction of a base table is modified + infrequently. Due to the overhead of immediate maintenance, <acronym>IVM</acronym> + is not effective when a base table is modified frequently. Also, when a + large part of a base table is modified or large data is inserted into a + base table, <acronym>IVM</acronym> is not effective and the cost of + maintenance can be larger than the <command>REFRESH MATERIALIZED VIEW</command> + command. In such situation, we can use <command>REFRESH MATERIALIZED VIEW</command> + and specify <literal>WITH NO DATA</literal> to disable immediate + maintenance before modifying a base table. After a base table modification, + execute the <command>REFRESH MATERIALIZED VIEW</command> (with <literal>WITH DATA</literal>) + command to refresh the view data and enable immediate maintenance. +</para> + +</sect2> + +<sect2 id="rules-ivm-support"> +<title>Supported View Definitions and Restrictions</title> + +<para> + Currently, we can create <acronym>IMMV</acronym>s using inner joins, and some + aggregates. However, several restrictions apply to the definition of IMMV. +</para> + +<sect3 id="rules-ivm-support-joins"> +<title>Joins</title> +<para> + Inner joins including self-join are supported. Outer joins are not supported. +</para> +</sect3> + +<sect3 id="rules-ivm-support-aggregates"> +<title>Aggregates</title> +<para> + Supported aggregate functions are <function>count</function>, <function>sum</function>, + <function>avg</function>, <function>min</function>, and <function>max</function>. + Currently, only built-in aggregate functions are supported and user defined + aggregates cannot be used. When a base table is modified, the new aggregated + values are incrementally calculated using the old aggregated values and values + of related hidden columns stored in <acronym>IMMV</acronym>. +</para> + +<para> + Note that for <function>min</function> or <function>max</function>, the new values + could be re-calculated from base tables with regard to the affected groups when a + tuple containing the current minimal or maximal values are deleted from a base table. + Therefore, it can takes a long time to update an <acronym>IMMV</acronym> containing + these functions. +</para> + +<para> + Also note that using <function>sum</function> or <function>avg</function> on + <type>real</type> (<type>float4</type>) type or <type>double precision</type> + (<type>float8</type>) type in <acronym>IMMV</acronym> is unsafe. This is + because aggregated values in <acronym>IMMV</acronym> can become different from + results calculated from base tables due to the limited precision of these types. + To avoid this problem, use the <type>numeric</type> type instead. +</para> + + <sect4 id="rules-ivm-restrictions-aggregates"> + <title>Restrictions on Aggregates</title> + <para> + There are the following restrictions: + <itemizedlist> + <listitem> + <para> + If we have a <literal>GROUP BY</literal> clause, expressions specified in + <literal>GROUP BY</literal> must appear in the target list. This is + how tuples to be updated in the <acronym>IMMV</acronym> are identified. + These attributes are used as scan keys for searching tuples in the + <acronym>IMMV</acronym>, so indexes on them are required for efficient + <acronym>IVM</acronym>. + </para> + </listitem> + + <listitem> + <para> + <literal>HAVING</literal> clause cannot be used. + </para> + </listitem> + </itemizedlist> + </para> + </sect4> +</sect3> + +<sect3 id="rules-ivm-general-restricitons"> +<title>Other General Restrictions</title> +<para> + There are other restrictions which generally apply to <acronym>IMMV</acronym>: + <itemizedlist> + <listitem> + <para> + Sub-queries cannot be used. + </para> + </listitem> + + <listitem> + <para> + CTEs cannot be used. + </para> + </listitem> + + <listitem> + <para> + Window functions cannot be used. + </para> + </listitem> + + <listitem> + <para> + <acronym>IMMV</acronym>s must be based on simple base tables. It's not + supported to create them on top of views, materialized views, foreign tables, inhe. + </para> + </listitem> + + <listitem> + <para> + LIMIT and OFFSET clauses cannot be used. + </para> + </listitem> + + <listitem> + <para> + <acronym>IMMV</acronym>s cannot contain system columns. + </para> + </listitem> + + <listitem> + <para> + <acronym>IMMV</acronym>s cannot contain non-immutable functions. + </para> + </listitem> + + <listitem> + <para> + UNION/INTERSECT/EXCEPT clauses cannnot be used. + </para> + </listitem> + + <listitem> + <para> + DISTINCT ON clauses cannot be used. + </para> + </listitem> + + <listitem> + <para> + TABLESAMPLE parameter cannot be used. + </para> + </listitem> + + <listitem> + <para> + inheritance parent tables cannnot be used. + </para> + </listitem> + + <listitem> + <para> + VALUES clause cannnot be used. + </para> + </listitem> + + <listitem> + <para> + <literal>GROUPING SETS</literal> and <literal>FILTER</literal> clauses cannot be used. + </para> + </listitem> + + <listitem> + <para> + FOR UPDATE/SHARE cannot be used. + </para> + </listitem> + + <listitem> + <para> + targetlist cannot contain columns whose name start with <literal>__ivm_</literal>. + </para> + </listitem> + + <listitem> + <para> + targetlist cannot contain expressions which contain an aggregate in it. + </para> + </listitem> + + <listitem> + <para> + Logical replication is not supported, that is, even when a base table + at a publisher node is modified, <acronym>IMMV</acronym>s at subscriber + nodes are not updated. + </para> + </listitem> + + </itemizedlist> +</para> +</sect3> + +</sect2> + +<sect2 id="rules-ivm-distinct"> +<title><literal>DISTINCT</literal></title> + +<para> + <productname>PostgreSQL</productname> supports <acronym>IMMV</acronym> with + <literal>DISTINCT</literal>. For example, suppose a <acronym>IMMV</acronym> + defined with <literal>DISTINCT</literal> on a base table containing duplicate + tuples. When tuples are deleted from the base table, a tuple in the view is + deleted if and only if the multiplicity of the tuple becomes zero. Moreover, + when tuples are inserted into the base table, a tuple is inserted into the + view only if the same tuple doesn't already exist in it. +</para> + +<para> + Physically, an <acronym>IMMV</acronym> defined with <literal>DISTINCT</literal> + contains tuples after eliminating duplicates, and the multiplicity of each tuple + is stored in a hidden column named <literal>__ivm_count__</literal>. +</para> +</sect2> + +<sect2 id="rules-ivm-concurrent-transactions"> +<title>Concurrent Transactions</title> +<para> + Suppose an <acronym>IMMV</acronym> is defined on two base tables and each + table was modified in different a concurrent transaction simultaneously. + In the transaction which was committed first, <acronym>IMMV</acronym> can + be updated considering only the change which happened in this transaction. + On the other hand, in order to update the view correctly in the transaction + which was committed later, we need to know the changes occurred in + both transactions. For this reason, <literal>ExclusiveLock</literal> + is held on an <acronym>IMMV</acronym> immediately after a base table is + modified in <literal>READ COMMITTED</literal> mode to make sure that + the <acronym>IMMV</acronym> is updated in the latter transaction after + the former transaction is committed. In <literal>REPEATABLE READ</literal> + or <literal>SERIALIZABLE</literal> mode, an error is raised immediately + if lock acquisition fails because any changes which occurred in + other transactions are not be visible in these modes and + <acronym>IMMV</acronym> cannot be updated correctly in such situations. + However, as an exception if the view has only one base table and + <command>INSERT</command> is performed on the table, + the lock held on thew view is <literal>RowExclusiveLock</literal>. +</para> +</sect2> + +<sect2 id="rules-ivm-rls"> +<title>Row Level Security</title> +<para> + If some base tables have row level security policy, rows that are not visible + to the materialized view's owner are excluded from the result. In addition, such + rows are excluded as well when views are incrementally maintained. However, if a + new policy is defined or policies are changed after the materialized view was created, + the new policy will not be applied to the view contents. To apply the new policy, + you need to refresh materialized views. +</para> +</sect2> + +</sect1> + <sect1 id="rules-update"> <title>Rules on <command>INSERT</command>, <command>UPDATE</command>, and <command>DELETE</command></title> diff --git a/doc/src/sgml/system-views.sgml b/doc/src/sgml/system-views.sgml index 2b35c2f91b..5366f707eb 100644 --- a/doc/src/sgml/system-views.sgml +++ b/doc/src/sgml/system-views.sgml @@ -1787,6 +1787,15 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx </para></entry> </row> + <row> + <entry role="catalog_table_entry"><para role="column_definition"> + <structfield>isimmv</structfield> <type>bool</type> + </para> + <para> + True if materialized view is incrementally maintainable + </para></entry> + </row> + <row> <entry role="catalog_table_entry"><para role="column_definition"> <structfield>definition</structfield> <type>text</type> -- 2.25.1 --Multipart=_Mon__28_Aug_2023_16_05_30_+0900_b1OvQD_3A3ZMTGvj-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH 09/11] regress tests for session variables @ 2022-04-04 18:54 [email protected] <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: [email protected] @ 2022-04-04 18:54 UTC (permalink / raw) Checks of basic functionality, check of usage session variables in subtransactions and from PLpgSQL --- .../isolation/expected/session-variable.out | 86 ++ src/test/isolation/isolation_schedule | 1 + .../isolation/specs/session-variable.spec | 34 + .../regress/expected/session_variables.out | 1287 +++++++++++++++++ src/test/regress/parallel_schedule | 2 +- src/test/regress/sql/session_variables.sql | 959 ++++++++++++ 6 files changed, 2368 insertions(+), 1 deletion(-) create mode 100644 src/test/isolation/expected/session-variable.out create mode 100644 src/test/isolation/specs/session-variable.spec create mode 100644 src/test/regress/expected/session_variables.out create mode 100644 src/test/regress/sql/session_variables.sql diff --git a/src/test/isolation/expected/session-variable.out b/src/test/isolation/expected/session-variable.out new file mode 100644 index 0000000000..b0059910a1 --- /dev/null +++ b/src/test/isolation/expected/session-variable.out @@ -0,0 +1,86 @@ +Parsed test spec with 2 sessions + +starting permutation: let val drop val +step let: LET myvar = 'test'; +step val: SELECT myvar; +myvar +----- +test +(1 row) + +step drop: DROP VARIABLE myvar; +step val: SELECT myvar; +ERROR: column or variable "myvar" does not exist + +starting permutation: let val s1 drop val sr1 +step let: LET myvar = 'test'; +step val: SELECT myvar; +myvar +----- +test +(1 row) + +step s1: BEGIN; +step drop: DROP VARIABLE myvar; +step val: SELECT myvar; +ERROR: column or variable "myvar" does not exist +step sr1: ROLLBACK; + +starting permutation: let val dbg drop create dbg val +step let: LET myvar = 'test'; +step val: SELECT myvar; +myvar +----- +test +(1 row) + +step dbg: SELECT schema, name, removed FROM pg_debug_show_used_session_variables(); +schema|name |removed +------+-----+------- +public|myvar|f +(1 row) + +step drop: DROP VARIABLE myvar; +step create: CREATE VARIABLE myvar AS text +step dbg: SELECT schema, name, removed FROM pg_debug_show_used_session_variables(); +schema|name|removed +------+----+------- +(0 rows) + +step val: SELECT myvar; +myvar +----- + +(1 row) + + +starting permutation: let val s1 dbg drop create dbg val sr1 +step let: LET myvar = 'test'; +step val: SELECT myvar; +myvar +----- +test +(1 row) + +step s1: BEGIN; +step dbg: SELECT schema, name, removed FROM pg_debug_show_used_session_variables(); +schema|name |removed +------+-----+------- +public|myvar|f +(1 row) + +step drop: DROP VARIABLE myvar; +step create: CREATE VARIABLE myvar AS text +step dbg: SELECT schema, name, removed FROM pg_debug_show_used_session_variables(); +schema|name |removed +------+-----+------- +public|myvar|f +(1 row) + +step val: SELECT myvar; +myvar +----- + +(1 row) + +step sr1: ROLLBACK; diff --git a/src/test/isolation/isolation_schedule b/src/test/isolation/isolation_schedule index 529a4cbd4d..96ecf93e32 100644 --- a/src/test/isolation/isolation_schedule +++ b/src/test/isolation/isolation_schedule @@ -107,3 +107,4 @@ test: cluster-conflict-partition test: truncate-conflict test: serializable-parallel test: serializable-parallel-2 +test: session-variable diff --git a/src/test/isolation/specs/session-variable.spec b/src/test/isolation/specs/session-variable.spec new file mode 100644 index 0000000000..fe47339110 --- /dev/null +++ b/src/test/isolation/specs/session-variable.spec @@ -0,0 +1,34 @@ +# Test session variables memory cleanup for sinval + +setup +{ + CREATE VARIABLE myvar AS text; +} + +teardown +{ + DROP VARIABLE IF EXISTS myvar; +} + +session s1 +step s1 { BEGIN; } +step let { LET myvar = 'test'; } +step val { SELECT myvar; } +step dbg { SELECT schema, name, removed FROM pg_debug_show_used_session_variables(); } +step sr1 { ROLLBACK; } + + +session s2 +step drop { DROP VARIABLE myvar; } +step create { CREATE VARIABLE myvar AS text } + +# Concurrent drop of a known variable should lead to an error +permutation let val drop val +# Same, but with an explicit transaction +permutation let val s1 drop val sr1 +# Concurrent drop/create of a known variable should lead to empty variable +permutation let val dbg drop create dbg val +# Concurrent drop/create of a known variable should lead to empty variable +# We need a transaction to make sure that we won't accept invalidation when +# calling the dbg step after the concurrent drop +permutation let val s1 dbg drop create dbg val sr1 diff --git a/src/test/regress/expected/session_variables.out b/src/test/regress/expected/session_variables.out new file mode 100644 index 0000000000..d411f0440d --- /dev/null +++ b/src/test/regress/expected/session_variables.out @@ -0,0 +1,1287 @@ +CREATE SCHEMA svartest; +SET search_path = svartest; +CREATE VARIABLE var1 AS integer; +CREATE TEMP VARIABLE var2 AS text; +DROP VARIABLE var1, var2; +-- functional interface +CREATE VARIABLE var1 AS numeric; +CREATE ROLE var_test_role; +GRANT USAGE ON SCHEMA svartest TO var_test_role; +SET ROLE TO var_test_role; +-- should fail +SELECT var1; +ERROR: permission denied for session variable var1 +SET ROLE TO DEFAULT; +GRANT SELECT ON VARIABLE var1 TO var_test_role; +SET ROLE TO var_test_role; +-- should fail +LET var1 = 10; +ERROR: permission denied for session variable var1 +-- should work +SELECT var1; + var1 +------ + +(1 row) + +SET ROLE TO DEFAULT; +GRANT UPDATE ON VARIABLE var1 TO var_test_role; +SET ROLE TO var_test_role; +-- should work +LET var1 = 333; +SET ROLE TO DEFAULT; +REVOKE ALL ON VARIABLE var1 FROM var_test_role; +CREATE OR REPLACE FUNCTION secure_var() +RETURNS int AS $$ + SELECT svartest.var1::int; +$$ LANGUAGE sql SECURITY DEFINER; +SELECT secure_var(); + secure_var +------------ + 333 +(1 row) + +SET ROLE TO var_test_role; +-- should fail +SELECT svartest.var1; +ERROR: permission denied for session variable var1 +-- should work; +SELECT secure_var(); + secure_var +------------ + 333 +(1 row) + +SET ROLE TO DEFAULT; +EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM generate_series(1,100) g(v) WHERE v = var1; + QUERY PLAN +----------------------------------------------- + Function Scan on pg_catalog.generate_series g + Output: v + Function Call: generate_series(1, 100) + Filter: ((g.v)::numeric = var1) +(4 rows) + +CREATE VIEW schema_var_view AS SELECT var1; +SELECT * FROM schema_var_view; + var1 +------ + 333 +(1 row) + +\c - +SET search_path = svartest; +-- should work still, but var will be empty +SELECT * FROM schema_var_view; + var1 +------ + +(1 row) + +LET var1 = pi(); +SELECT var1; + var1 +------------------ + 3.14159265358979 +(1 row) + +-- we can see execution plan of LET statement +EXPLAIN (VERBOSE, COSTS OFF) LET var1 = pi(); + QUERY PLAN +---------------------------- + SET SESSION VARIABLE + Result + Output: 3.14159265358979 +(3 rows) + +SELECT var1; + var1 +------------------ + 3.14159265358979 +(1 row) + +CREATE VARIABLE var3 AS int; +CREATE OR REPLACE FUNCTION inc(int) +RETURNS int AS $$ +BEGIN + LET svartest.var3 = COALESCE(svartest.var3 + $1, $1); + RETURN var3; +END; +$$ LANGUAGE plpgsql; +SELECT inc(1); + inc +----- + 1 +(1 row) + +SELECT inc(1); + inc +----- + 2 +(1 row) + +SELECT inc(1); + inc +----- + 3 +(1 row) + +SELECT inc(1) FROM generate_series(1,10); + inc +----- + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 +(10 rows) + +SET ROLE TO var_test_role; +-- should fail +LET var3 = 0; +ERROR: permission denied for session variable var3 +SET ROLE TO DEFAULT; +DROP VIEW schema_var_view; +DROP VARIABLE var1 CASCADE; +DROP VARIABLE var3 CASCADE; +-- composite variables +CREATE TYPE sv_xyz AS (x int, y int, z numeric(10,2)); +CREATE VARIABLE v1 AS sv_xyz; +CREATE VARIABLE v2 AS sv_xyz; +\d v1 +\d v2 +LET v1 = (1,2,3.14); +LET v2 = (10,20,3.14*10); +-- should work too - there are prepared casts +LET v1 = (1,2,3.14); +SELECT v1; + v1 +------------ + (1,2,3.14) +(1 row) + +SELECT v2; + v2 +--------------- + (10,20,31.40) +(1 row) + +SELECT (v1).*; + x | y | z +---+---+------ + 1 | 2 | 3.14 +(1 row) + +SELECT (v2).*; + x | y | z +----+----+------- + 10 | 20 | 31.40 +(1 row) + +SELECT v1.x + v1.z; + ?column? +---------- + 4.14 +(1 row) + +SELECT v2.x + v2.z; + ?column? +---------- + 41.40 +(1 row) + +-- access to composite fields should be safe too +-- should fail +SET ROLE TO var_test_role; +SELECT v2.x; +ERROR: permission denied for session variable v2 +SET ROLE TO DEFAULT; +DROP VARIABLE v1; +DROP VARIABLE v2; +REVOKE USAGE ON SCHEMA svartest FROM var_test_role; +DROP ROLE var_test_role; +-- scalar variables should not be in conflict with qualified column +CREATE VARIABLE varx AS text; +SELECT varx.relname FROM pg_class varx WHERE varx.relname = 'pg_class'; + relname +---------- + pg_class +(1 row) + +-- should fail +SELECT varx.xxx; +ERROR: type text is not composite +-- variables can be updated under RO transaction +BEGIN; +SET TRANSACTION READ ONLY; +LET varx = 'hello'; +COMMIT; +SELECT varx; + varx +------- + hello +(1 row) + +DROP VARIABLE varx; +CREATE TYPE t1 AS (a int, b numeric, c text); +CREATE VARIABLE v1 AS t1; +LET v1 = (1, pi(), 'hello'); +SELECT v1; + v1 +---------------------------- + (1,3.14159265358979,hello) +(1 row) + +LET v1.b = 10.2222; +SELECT v1; + v1 +------------------- + (1,10.2222,hello) +(1 row) + +-- should fail +LET v1.x = 10; +ERROR: cannot assign to field "x" of column "v1" because there is no such column in data type t1 +LINE 1: LET v1.x = 10; + ^ +DROP VARIABLE v1; +DROP TYPE t1; +-- arrays are supported +CREATE VARIABLE va1 AS numeric[]; +LET va1 = ARRAY[1.1,2.1]; +LET va1[1] = 10.1; +SELECT va1; + va1 +------------ + {10.1,2.1} +(1 row) + +CREATE TYPE ta2 AS (a numeric, b numeric[]); +CREATE VARIABLE va2 AS ta2; +LET va2 = (10.1, ARRAY[0.0, 0.0]); +LET va2.a = 10.2; +SELECT va2; + va2 +-------------------- + (10.2,"{0.0,0.0}") +(1 row) + +LET va2.b[1] = 10.3; +SELECT va2; + va2 +--------------------- + (10.2,"{10.3,0.0}") +(1 row) + +DROP VARIABLE va1; +DROP VARIABLE va2; +DROP TYPE ta2; +-- default values +CREATE VARIABLE v1 AS numeric DEFAULT pi(); +LET v1 = v1 * 2; +SELECT v1; + v1 +------------------ + 6.28318530717958 +(1 row) + +CREATE TYPE t2 AS (a numeric, b text); +CREATE VARIABLE v2 AS t2 DEFAULT (NULL, 'Hello'); +LET svartest.v2.a = pi(); +SELECT v2; + v2 +-------------------------- + (3.14159265358979,Hello) +(1 row) + +-- should fail due dependency +DROP TYPE t2; +ERROR: cannot drop type t2 because other objects depend on it +DETAIL: session variable v2 depends on type t2 +HINT: Use DROP ... CASCADE to drop the dependent objects too. +-- should be ok +DROP VARIABLE v1; +DROP VARIABLE v2; +-- tests of alters +CREATE SCHEMA var_schema1; +CREATE SCHEMA var_schema2; +CREATE VARIABLE var_schema1.var1 AS integer; +LET var_schema1.var1 = 1000; +SELECT var_schema1.var1; + var1 +------ + 1000 +(1 row) + +ALTER VARIABLE var_schema1.var1 SET SCHEMA var_schema2; +SELECT var_schema2.var1; + var1 +------ + 1000 +(1 row) + +CREATE ROLE var_test_role; +ALTER VARIABLE var_schema2.var1 OWNER TO var_test_role; +SET ROLE TO var_test_role; +-- should fail, no access to schema var_schema2.var +SELECT var_schema2.var1; +ERROR: permission denied for schema var_schema2 +DROP VARIABLE var_schema2.var1; +ERROR: permission denied for schema var_schema2 +SET ROLE TO DEFAULT; +ALTER VARIABLE var_schema2.var1 SET SCHEMA public; +SET ROLE TO var_test_role; +SELECT public.var1; + var1 +------ + 1000 +(1 row) + +ALTER VARIABLE public.var1 RENAME TO var1_renamed; +SELECT public.var1_renamed; + var1_renamed +-------------- + 1000 +(1 row) + +DROP VARIABLE public.var1_renamed; +SET ROLE TO DEFAULt; +-- default rights test +ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON VARIABLES TO var_test_role; +CREATE VARIABLE public.var2 AS int; +SET ROLE TO var_test_role; +-- should be ok +LET public.var2 = 100; +SELECT public.var2; + var2 +------ + 100 +(1 row) + +SET ROLE TO DEFAULt; +DROP VARIABLE public.var2; +DROP OWNED BY var_test_role; +DROP ROLE var_test_role; +CREATE VARIABLE xx AS text DEFAULT 'hello'; +SELECT xx, upper(xx); + xx | upper +-------+------- + hello | HELLO +(1 row) + +LET xx = 'Hi'; +SELECT xx; + xx +---- + Hi +(1 row) + +DROP VARIABLE xx; +-- ON TRANSACTION END RESET tests +CREATE VARIABLE t1 AS int DEFAULT -1 ON TRANSACTION END RESET; +BEGIN; + SELECT t1; + t1 +---- + -1 +(1 row) + + LET t1 = 100; + SELECT t1; + t1 +----- + 100 +(1 row) + +COMMIT; +SELECT t1; + t1 +---- + -1 +(1 row) + +BEGIN; + SELECT t1; + t1 +---- + -1 +(1 row) + + LET t1 = 100; + SELECT t1; + t1 +----- + 100 +(1 row) + +ROLLBACK; +SELECT t1; + t1 +---- + -1 +(1 row) + +DROP VARIABLE t1; +CREATE VARIABLE v1 AS int DEFAULT 0; +CREATE VARIABLE v2 AS text DEFAULT 'none'; +LET v1 = 100; +LET v2 = 'Hello'; +SELECT v1, v2; + v1 | v2 +-----+------- + 100 | Hello +(1 row) + +LET v1 = DEFAULT; +LET v2 = DEFAULT; +SELECT v1, v2; + v1 | v2 +----+------ + 0 | none +(1 row) + +DROP VARIABLE v1; +DROP VARIABLE v2; +-- ON COMMIT DROP tests +-- should be 0 always +SELECT count(*) FROM pg_variable; + count +------- + 0 +(1 row) + +CREATE TEMP VARIABLE g AS int ON COMMIT DROP; +SELECT count(*) FROM pg_variable; + count +------- + 0 +(1 row) + +BEGIN; + CREATE TEMP VARIABLE g AS int ON COMMIT DROP; +COMMIT; +SELECT count(*) FROM pg_variable; + count +------- + 0 +(1 row) + +BEGIN; + CREATE TEMP VARIABLE g AS int ON COMMIT DROP; +ROLLBACK; +SELECT count(*) FROM pg_variable; + count +------- + 0 +(1 row) + +-- Encourage use of parallel plans +SET parallel_setup_cost = 0; +SET parallel_tuple_cost = 0; +SET min_parallel_table_scan_size = 0; +SET max_parallel_workers_per_gather = 2; +-- test on query with workers +CREATE TABLE svar_test(a int); +INSERT INTO svar_test SELECT * FROM generate_series(1,1000); +ANALYZE svar_test; +CREATE VARIABLE zero int; +LET zero = 0; +-- parallel workers should be used +EXPLAIN (costs off) SELECT count(*) FROM svar_test WHERE a%10 = zero; + QUERY PLAN +-------------------------------------------- + Aggregate + -> Gather + Workers Planned: 2 + -> Parallel Seq Scan on svar_test + Filter: ((a % 10) = zero) +(5 rows) + +-- result should be 100 +SELECT count(*) FROM svar_test WHERE a%10 = zero; + count +------- + 100 +(1 row) + +LET zero = (SELECT count(*) FROM svar_test); +-- result should be 1000 +SELECT zero; + zero +------ + 1000 +(1 row) + +-- parallel workers should be used +EXPLAIN (costs off) LET zero = (SELECT count(*) FROM svar_test); + QUERY PLAN +---------------------------------------------------------- + SET SESSION VARIABLE + Result + InitPlan 1 (returns $1) + -> Finalize Aggregate + -> Gather + Workers Planned: 2 + -> Partial Aggregate + -> Parallel Seq Scan on svar_test +(8 rows) + +-- test for dependency on relation +CREATE VARIABLE v_table AS svar_test; +ALTER TABLE svar_test ALTER COLUMN a TYPE text; +ERROR: cannot alter table "svar_test" because session variable "svartest.v_table" uses it +DROP VARIABLE v_table; +DROP TABLE svar_test; +DROP VARIABLE zero; +RESET parallel_setup_cost; +RESET parallel_tuple_cost; +RESET min_parallel_table_scan_size; +RESET max_parallel_workers_per_gather; +-- use variables in prepared statements +CREATE VARIABLE v AS numeric; +LET v = 3.14; +-- use variables in views +CREATE VIEW vv AS SELECT COALESCE(v, 0) + 1000 AS result; +SELECT * FROM vv; + result +--------- + 1003.14 +(1 row) + +-- start a new session +\c +SET search_path to svartest; +SELECT * FROM vv; + result +-------- + 1000 +(1 row) + +LET v = 3.14; +SELECT * FROM vv; + result +--------- + 1003.14 +(1 row) + +-- should fail, dependency +DROP VARIABLE v; +ERROR: cannot drop session variable v because other objects depend on it +DETAIL: view vv depends on session variable v +HINT: Use DROP ... CASCADE to drop the dependent objects too. +-- should be ok +DROP VARIABLE v CASCADE; +NOTICE: drop cascades to view vv +-- other features +CREATE VARIABLE dt AS integer DEFAULT 0; +LET dt = 100; +SELECT dt; + dt +----- + 100 +(1 row) + +DISCARD VARIABLES; +SELECT dt; + dt +---- + 0 +(1 row) + +DROP VARIABLE dt; +-- NOT NULL +CREATE VARIABLE v1 AS int NOT NULL; +CREATE VARIABLE v2 AS int NOT NULL DEFAULT NULL; +-- should fail +SELECT v1; +ERROR: null value is not allowed for NOT NULL session variable "svartest.v1" +DETAIL: The session variable was not initialized yet. +SELECT v2; +ERROR: null value is not allowed for NOT NULL session variable "svartest.v2" +LET v1 = NULL; +ERROR: null value is not allowed for NOT NULL session variable "svartest.v1" +LET v2 = NULL; +ERROR: null value is not allowed for NOT NULL session variable "svartest.v2" +LET v1 = DEFAULT; +ERROR: null value is not allowed for NOT NULL session variable "svartest.v1" +LET v2 = DEFAULT; +ERROR: null value is not allowed for NOT NULL session variable "svartest.v2" +-- should be ok +LET v1 = 100; +LET v2 = 1000; +SELECT v1, v2; + v1 | v2 +-----+------ + 100 | 1000 +(1 row) + +DROP VARIABLE v1; +DROP VARIABLE v2; +CREATE VARIABLE tv AS int; +CREATE VARIABLE IF NOT EXISTS tv AS int; +NOTICE: session variable "tv" already exists, skipping +DROP VARIABLE tv; +CREATE IMMUTABLE VARIABLE iv AS int DEFAULT 100; +SELECT iv; + iv +----- + 100 +(1 row) + +-- should fail; +LET iv = 10000; +ERROR: session variable "svartest.iv" is declared IMMUTABLE +DROP VARIABLE iv; +-- different order +CREATE IMMUTABLE VARIABLE iv AS int DEFAULT 100; +-- should to fail +LET iv = 10000; +ERROR: session variable "svartest.iv" is declared IMMUTABLE +-- should be ok +SELECT iv; + iv +----- + 100 +(1 row) + +DROP VARIABLE iv; +CREATE IMMUTABLE VARIABLE iv AS int; +-- should be ok +LET iv = NULL; +-- should fail +LET iv = NULL; +ERROR: session variable "svartest.iv" is declared IMMUTABLE +DROP VARIABLE iv; +-- create variable inside plpgsql block +DO $$ +BEGIN + CREATE VARIABLE do_test_svar AS date DEFAULT '2000-01-01'; +END; +$$; +SELECT do_test_svar; + do_test_svar +-------------- + 01-01-2000 +(1 row) + +DROP VARIABLE do_test_svar; +-- should fail +CREATE IMMUTABLE VARIABLE xx AS int NOT NULL; +ERROR: IMMUTABLE NOT NULL variable requires default expression +-- REASSIGN OWNED test +CREATE ROLE var_test_role1; +CREATE ROLE var_test_role2; +CREATE VARIABLE xxx_var AS int; +ALTER VARIABLE xxx_var OWNER TO var_test_role1; +REASSIGN OWNED BY var_test_role1 to var_test_role2; +SELECT varowner::regrole FROM pg_variable WHERE varname = 'xxx_var'; + varowner +---------------- + var_test_role2 +(1 row) + +DROP OWNED BY var_test_role1; +DROP ROLE var_test_role1; +SELECT count(*) FROM pg_variable WHERE varname = 'xxx_var'; + count +------- + 1 +(1 row) + +DROP OWNED BY var_test_role2; +DROP ROLE var_test_role2; +SELECT count(*) FROM pg_variable WHERE varname = 'xxx_var'; + count +------- + 0 +(1 row) + +-- creating, dropping temporary variable +BEGIN; +CREATE TEMP VARIABLE tempvar AS INT ON COMMIT DROP; +LET tempvar = 100; +SAVEPOINT s1; +DROP VARIABLE tempvar; +ROLLBACK TO s1; +SELECT tempvar; + tempvar +--------- + 100 +(1 row) + +COMMIT; +-- should to fail +LET tempvar = 100; +ERROR: session variable "tempvar" doesn't exist +LINE 1: LET tempvar = 100; + ^ +BEGIN; +SAVEPOINT s1; +CREATE TEMP VARIABLE tempvar AS INT ON COMMIT DROP; +LET tempvar = 100; +ROLLBACK TO s1; +COMMIT; +-- should to fail +LET tempvar = 100; +ERROR: session variable "tempvar" doesn't exist +LINE 1: LET tempvar = 100; + ^ +CREATE VARIABLE var1 AS int; +LET var1 = 100; +BEGIN; +DROP VARIABLE var1; +ROLLBACK; +SELECT var1; + var1 +------ + 100 +(1 row) + +DROP VARIABLE var1; +CREATE VARIABLE var1 AS int DEFAULT 100; +COMMENT ON VARIABLE var1 IS 'some variable comment'; +SELECT pg_catalog.obj_description(oid, 'pg_variable') FROM pg_variable WHERE varname = 'var1'; + obj_description +----------------------- + some variable comment +(1 row) + +DROP VARIABLE var1; +CREATE TABLE xxtab(avar int); +CREATE TYPE xxtype AS (avar int); +CREATE VARIABLE xxtab AS xxtype; +INSERT INTO xxtab VALUES(10); +-- it is ambiguous, but columns are preferred +-- variable is shadowed +SELECT xxtab.avar FROM xxtab; + avar +------ + 10 +(1 row) + +SET session_variables_ambiguity_warning TO on; +SELECT xxtab.avar FROM xxtab; +WARNING: session variable "xxtab.avar" is shadowed +LINE 1: SELECT xxtab.avar FROM xxtab; + ^ +DETAIL: Session variables can be shadowed by columns, routine's variables and routine's arguments with the same name. + avar +------ + 10 +(1 row) + +SET search_path = svartest; +CREATE VARIABLE testvar as int; +-- plpgsql variables are preferred against session variables +DO $$ +<<myblock>> +DECLARE testvar int; +BEGIN + -- should be ok without warning + LET testvar = 100; + -- should be ok without warning + testvar := 1000; + -- should be ok without warning + RAISE NOTICE 'session variable is %', svartest.testvar; + -- should be ok without warning + RAISE NOTICE 'plpgsql variable is %', myblock.testvar; + -- should to print plpgsql variable with warning + RAISE NOTICE 'variable is %', testvar; +END; +$$; +WARNING: session variable "testvar" is shadowed +LINE 1: testvar := 1000 + ^ +DETAIL: Session variables can be shadowed by columns, routine's variables and routine's arguments with the same name. +QUERY: testvar := 1000 +NOTICE: session variable is 100 +NOTICE: plpgsql variable is 1000 +WARNING: session variable "testvar" is shadowed +LINE 1: testvar + ^ +DETAIL: Session variables can be shadowed by columns, routine's variables and routine's arguments with the same name. +QUERY: testvar +NOTICE: variable is 1000 +DROP VARIABLE testvar; +SET session_variables_ambiguity_warning TO default; +-- should be ok +SELECT avar FROM xxtab; + avar +------ + 10 +(1 row) + +CREATE VARIABLE public.avar AS int; +-- should be ok, see the table +SELECT avar FROM xxtab; + avar +------ + 10 +(1 row) + +-- should be ok +SELECT public.avar FROM xxtab; + avar +------ + +(1 row) + +DROP VARIABLE xxtab; +SELECT xxtab.avar FROM xxtab; + avar +------ + 10 +(1 row) + +DROP VARIABLE public.avar; +DROP TYPE xxtype; +DROP TABLE xxtab; +-- test of plan cache invalidation +CREATE VARIABLE xx AS int; +SET plan_cache_mode = force_generic_plan; +PREPARE pp AS SELECT xx; +EXECUTE pp; + xx +---- + +(1 row) + +DROP VARIABLE xx; +CREATE VARIABLE xx AS int; +-- should to work +EXECUTE pp; + xx +---- + +(1 row) + +DROP VARIABLE xx; +DEALLOCATE pp; +SET plan_cache_mode = DEFAULT; +CREATE ROLE var_test_role; +CREATE SCHEMA vartest; +GRANT USAGE ON SCHEMA vartest TO var_test_role; +CREATE VARIABLE vartest.x AS int; +CREATE VARIABLE vartest.y AS int; +LET vartest.x = 100; +LET vartest.y = 101; +GRANT SELECT ON ALL VARIABLES IN SCHEMA vartest TO var_test_role; +SET ROLE TO var_test_role; +SELECT vartest.x, vartest.y; + x | y +-----+----- + 100 | 101 +(1 row) + +SET ROLE TO DEFAULT; +REVOKE SELECT ON ALL VARIABLES IN SCHEMA vartest FROM var_test_role; +SET ROLE TO var_test_role; +-- should to fail +SELECT vartest.x; +ERROR: permission denied for session variable x +SELECT vartest.y; +ERROR: permission denied for session variable y +SET ROLE TO DEFAULT; +DROP VARIABLE vartest.x, vartest.y; +DROP SCHEMA vartest; +DROP ROLE var_test_role; +-- test cached plan +CREATE VARIABLE v1 AS text; +CREATE VARIABLE v2 AS int; +CREATE VARIABLE v3 AS int; +LET v1 = 'test'; +LET v2 = 10; +LET v3 = 5; +PREPARE q1 AS SELECT v1 || i FROM generate_series(1, v2) g(i) WHERE i IN (v2, v3); +SET plan_cache_mode to force_generic_plan; +EXECUTE q1; + ?column? +---------- + test5 + test10 +(2 rows) + +EXPLAIN EXECUTE q1; + QUERY PLAN +----------------------------------------------------------------------- + Function Scan on generate_series g (cost=0.00..0.14 rows=2 width=32) + Filter: (i = ANY (ARRAY[v2, v3])) +(2 rows) + +-- dependecy check +DROP VARIABLE v3; +-- recreate v3 again +CREATE VARIABLE v3 AS int DEFAULT 6; +-- should to work, the plan should be recreated +EXECUTE q1; + ?column? +---------- + test6 + test10 +(2 rows) + +DEALLOCATE q1; +-- fill v1 by long text +LET v1 = repeat(' ', 10000); +PREPARE q1 AS SELECT length(v1); +EXECUTE q1; + length +-------- + 10000 +(1 row) + +LET v1 = repeat(' ', 5000); +EXECUTE q1; + length +-------- + 5000 +(1 row) + +DEALLOCATE q1; +SET plan_cache_mode to default; +DROP VARIABLE v1, v2, v3; +CREATE ROLE var_test_role; +CREATE VARIABLE public.v1 AS int DEFAULT 0; +-- check acl when variable is acessed by simple eval expr method +CREATE OR REPLACE FUNCTION public.fx_var(int) +RETURNS int AS $$ +DECLARE xx int; +BEGIN + xx := public.v1 + $1; + RETURN xx; +END; +$$ LANGUAGE plpgsql; +-- should be ok +SELECT public.fx_var(0); + fx_var +-------- + 0 +(1 row) + +SET ROLE TO var_test_role; +-- should to fail +SELECT public.fx_var(0); +ERROR: permission denied for session variable v1 +CONTEXT: PL/pgSQL function public.fx_var(integer) line 4 at assignment +SET ROLE TO default; +GRANT SELECT ON VARIABLE public.v1 TO var_test_role; +SET ROLE TO var_test_role; +-- should be ok +SELECT public.fx_var(0); + fx_var +-------- + 0 +(1 row) + +SET ROLE TO default; +REVOKE SELECT ON VARIABLE public.v1 FROM var_test_role; +SET ROLE TO var_test_role; +-- should be fail +SELECT public.fx_var(0); +ERROR: permission denied for session variable v1 +CONTEXT: PL/pgSQL function public.fx_var(integer) line 4 at assignment +SET ROLE TO DEFAULT; +DROP FUNCTION public.fx_var(int); +DROP VARIABLE public.v1; +DROP ROLE var_test_role; +CREATE TYPE public.svar_test_type AS (a int, b int, c numeric); +CREATE VARIABLE public.svar AS public.svar_test_type; +LET public.svar = ROW(10,20,30); +SELECT public.svar; + svar +------------ + (10,20,30) +(1 row) + +ALTER TYPE public.svar_test_type DROP ATTRIBUTE c; +-- should be ok +SELECT public.svar; + svar +--------- + (10,20) +(1 row) + +ALTER TYPE public.svar_test_type ADD ATTRIBUTE c int; +-- should be ok +SELECT public.svar; + svar +---------- + (10,20,) +(1 row) + +LET public.svar = ROW(10,20,30); +-- should be ok again for new value +SELECT public.svar; + svar +------------ + (10,20,30) +(1 row) + +DROP VARIABLE public.svar; +DROP TYPE public.svar_test_type; +CREATE VARIABLE public.svar AS int; +select oid as varid from pg_variable where varname = 'svar' and varnamespace = 'public'::regnamespace \gset +SELECT schema, name, removed FROM pg_debug_show_used_session_variables(); + schema | name | removed +--------+------+--------- +(0 rows) + +LET public.svar = 100; +SELECT schema, name, removed FROM pg_debug_show_used_session_variables(); + schema | name | removed +--------+------+--------- + public | svar | f +(1 row) + +BEGIN; +DROP VARIABLE public.svar; +-- value should be in memory +SELECT schema, name, removed FROM pg_debug_show_used_session_variables(); + schema | name | removed +--------+------+--------- + | | t +(1 row) + +ROLLBACK; +-- value should be in memory +SELECT schema, name, removed FROM pg_debug_show_used_session_variables() f WHERE f.varid = :varid; + schema | name | removed +--------+------+--------- + public | svar | f +(1 row) + +SELECT public.svar; + svar +------ + 100 +(1 row) + +BEGIN; +DROP VARIABLE public.svar; +-- value should be in memory +SELECT schema, name, removed FROM pg_debug_show_used_session_variables() f WHERE f.varid = :varid;; + schema | name | removed +--------+------+--------- + | | t +(1 row) + +COMMIT; +-- the memory should be clean; +SELECT schema, name, removed FROM pg_debug_show_used_session_variables() WHERE f.varid = :varid; +ERROR: missing FROM-clause entry for table "f" +LINE 1: ...FROM pg_debug_show_used_session_variables() WHERE f.varid = ... + ^ +BEGIN; +CREATE VARIABLE public.svar AS int; +select oid as varid from pg_variable where varname = 'svar' and varnamespace = 'public'::regnamespace \gset +LET public.svar = 100; +ROLLBACK; +-- the memory should be clean; +SELECT schema, name, removed FROM pg_debug_show_used_session_variables() f WHERE f.varid = :varid; + schema | name | removed +--------+------+--------- +(0 rows) + +\unset varid +CREATE VARIABLE public.svar AS int; +LET public.svar = 100; +-- repeated aborted transaction +BEGIN; DROP VARIABLE public.svar; ROLLBACK; +BEGIN; DROP VARIABLE public.svar; ROLLBACK; +BEGIN; DROP VARIABLE public.svar; ROLLBACK; +-- the value should be still available +SELECT public.svar; + svar +------ + 100 +(1 row) + +DROP VARIABLE public.svar; +CREATE TYPE public.svar_test_type AS (a int, b int); +CREATE VARIABLE public.svar AS public.svar_test_type; +SELECT public.svar; + svar +------ + +(1 row) + +ALTER TYPE public.svar_test_type ADD ATTRIBUTE c int; +SELECT public.svar; + svar +------ + +(1 row) + +ALTER TYPE public.svar_test_type DROP ATTRIBUTE b; +SELECT public.svar; + svar +------ + +(1 row) + +DROP VARIABLE public.svar; +DROP TYPE public.svar_test_type; +CREATE TYPE public.svar_test_type AS (a int, b int); +CREATE VARIABLE public.svar AS public.svar_test_type; +CREATE VARIABLE public.svar2 AS public.svar_test_type; +LET public.svar = (10, 20); +ALTER TYPE public.svar_test_type ADD ATTRIBUTE c int; +SELECT public.svar; + svar +---------- + (10,20,) +(1 row) + +LET public.svar2 = (10, 20, 30); +ALTER TYPE public.svar_test_type DROP ATTRIBUTE b; +SELECT public.svar; + svar +------- + (10,) +(1 row) + +SELECT public.svar2; + svar2 +--------- + (10,30) +(1 row) + +DROP VARIABLE public.svar; +DROP VARIABLE public.svar2; +DROP TYPE public.svar_test_type; +-- The composite type cannot be changed when it is used +CREATE TYPE public.svar_type AS (a int, b int); +CREATE VARIABLE public.svar AS public.svar_type; +-- should to fail +ALTER TYPE public.svar_type ALTER ATTRIBUTE b TYPE numeric; +ERROR: cannot alter type "svar_type" because session variable "public.svar" uses it +DROP VARIABLE public.svar; +CREATE TYPE public.svar_type2 AS (a int, b int, c public.svar_type); +CREATE VARIABLE public.svar AS public.svar_type2; +-- should to fail +ALTER TYPE public.svar_type ALTER ATTRIBUTE b TYPE numeric; +ERROR: cannot alter type "svar_type" because session variable "public.svar" uses it +DROP VARIABLE public.svar; +DROP TYPE public.svar_type2; +DROP TYPE public.svar_type; +-- The variable can be shadowed by table or by alias +CREATE TYPE public.svar_type AS (a int, b int, c int); +CREATE VARIABLE public.svar AS public.svar_type; +CREATE TABLE public.svar (a int, b int); +INSERT INTO public.svar VALUES(10, 20); +LET public.svar = (100, 200, 300); +-- should be ok +-- show table +SELECT * FROM public.svar; + a | b +----+---- + 10 | 20 +(1 row) + +SELECT svar.a FROM public.svar; + a +---- + 10 +(1 row) + +SELECT svar.* FROM public.svar; + a | b +----+---- + 10 | 20 +(1 row) + +-- show variable +SELECT public.svar; + svar +--------------- + (100,200,300) +(1 row) + +SELECT public.svar.c; + c +----- + 300 +(1 row) + +SELECT (public.svar).*; + a | b | c +-----+-----+----- + 100 | 200 | 300 +(1 row) + +-- the variable is shadowed, raise error +SELECT public.svar.c FROM public.svar; +ERROR: column svar.c does not exist +LINE 1: SELECT public.svar.c FROM public.svar; + ^ +-- can be fixed by alias +SELECT public.svar.c FROM public.svar x; + c +----- + 300 +(1 row) + +-- again with warnings +SET session_variables_ambiguity_warning TO on; +SELECT * FROM public.svar; + a | b +----+---- + 10 | 20 +(1 row) + +SELECT svar.a FROM public.svar; + a +---- + 10 +(1 row) + +SELECT svar.* FROM public.svar; + a | b +----+---- + 10 | 20 +(1 row) + +-- show variable +SELECT public.svar; + svar +--------------- + (100,200,300) +(1 row) + +SELECT public.svar.c; + c +----- + 300 +(1 row) + +SELECT (public.svar).*; + a | b | c +-----+-----+----- + 100 | 200 | 300 +(1 row) + +-- the variable is shadowed, raise error +SELECT public.svar.c FROM public.svar; +WARNING: session variable "public.svar" is shadowed +LINE 1: SELECT public.svar.c FROM public.svar; + ^ +DETAIL: Session variables can be shadowed by tables or table's aliases with the same name. +ERROR: column svar.c does not exist +LINE 1: SELECT public.svar.c FROM public.svar; + ^ +-- can be fixed by alias +SELECT public.svar.c FROM public.svar x; + c +----- + 300 +(1 row) + +SET session_variables_ambiguity_warning TO DEFAULT; +DROP VARIABLE public.svar; +DROP TABLE public.svar; +DROP TYPE public.svar_type; diff --git a/src/test/regress/parallel_schedule b/src/test/regress/parallel_schedule index 9f644a0c1b..7426b39ab3 100644 --- a/src/test/regress/parallel_schedule +++ b/src/test/regress/parallel_schedule @@ -119,7 +119,7 @@ test: json jsonb json_encoding jsonpath jsonpath_encoding jsonb_jsonpath # NB: temp.sql does a reconnect which transiently uses 2 connections, # so keep this parallel group to at most 19 tests # ---------- -test: plancache limit plpgsql copy2 temp domain rangefuncs prepare conversion truncate alter_table sequence polymorphism rowtypes returning largeobject with xml +test: plancache limit plpgsql copy2 temp domain rangefuncs prepare conversion truncate alter_table sequence polymorphism rowtypes returning largeobject with xml session_variables # ---------- # Another group of parallel tests diff --git a/src/test/regress/sql/session_variables.sql b/src/test/regress/sql/session_variables.sql new file mode 100644 index 0000000000..d32bb5b042 --- /dev/null +++ b/src/test/regress/sql/session_variables.sql @@ -0,0 +1,959 @@ +CREATE SCHEMA svartest; + +SET search_path = svartest; + +CREATE VARIABLE var1 AS integer; +CREATE TEMP VARIABLE var2 AS text; + +DROP VARIABLE var1, var2; + +-- functional interface +CREATE VARIABLE var1 AS numeric; + +CREATE ROLE var_test_role; +GRANT USAGE ON SCHEMA svartest TO var_test_role; + +SET ROLE TO var_test_role; + +-- should fail +SELECT var1; + +SET ROLE TO DEFAULT; + +GRANT SELECT ON VARIABLE var1 TO var_test_role; + +SET ROLE TO var_test_role; +-- should fail +LET var1 = 10; +-- should work +SELECT var1; + +SET ROLE TO DEFAULT; + +GRANT UPDATE ON VARIABLE var1 TO var_test_role; + +SET ROLE TO var_test_role; + +-- should work +LET var1 = 333; + +SET ROLE TO DEFAULT; + +REVOKE ALL ON VARIABLE var1 FROM var_test_role; + +CREATE OR REPLACE FUNCTION secure_var() +RETURNS int AS $$ + SELECT svartest.var1::int; +$$ LANGUAGE sql SECURITY DEFINER; + +SELECT secure_var(); + +SET ROLE TO var_test_role; + +-- should fail +SELECT svartest.var1; + +-- should work; +SELECT secure_var(); + +SET ROLE TO DEFAULT; + +EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM generate_series(1,100) g(v) WHERE v = var1; + +CREATE VIEW schema_var_view AS SELECT var1; + +SELECT * FROM schema_var_view; + +\c - + +SET search_path = svartest; + +-- should work still, but var will be empty +SELECT * FROM schema_var_view; + +LET var1 = pi(); + +SELECT var1; + +-- we can see execution plan of LET statement +EXPLAIN (VERBOSE, COSTS OFF) LET var1 = pi(); + +SELECT var1; + +CREATE VARIABLE var3 AS int; + +CREATE OR REPLACE FUNCTION inc(int) +RETURNS int AS $$ +BEGIN + LET svartest.var3 = COALESCE(svartest.var3 + $1, $1); + RETURN var3; +END; +$$ LANGUAGE plpgsql; + +SELECT inc(1); +SELECT inc(1); +SELECT inc(1); + +SELECT inc(1) FROM generate_series(1,10); + +SET ROLE TO var_test_role; + +-- should fail +LET var3 = 0; + +SET ROLE TO DEFAULT; + +DROP VIEW schema_var_view; + +DROP VARIABLE var1 CASCADE; +DROP VARIABLE var3 CASCADE; + +-- composite variables + +CREATE TYPE sv_xyz AS (x int, y int, z numeric(10,2)); + +CREATE VARIABLE v1 AS sv_xyz; +CREATE VARIABLE v2 AS sv_xyz; + +\d v1 +\d v2 + +LET v1 = (1,2,3.14); +LET v2 = (10,20,3.14*10); + +-- should work too - there are prepared casts +LET v1 = (1,2,3.14); + +SELECT v1; +SELECT v2; +SELECT (v1).*; +SELECT (v2).*; + +SELECT v1.x + v1.z; +SELECT v2.x + v2.z; + +-- access to composite fields should be safe too +-- should fail +SET ROLE TO var_test_role; + +SELECT v2.x; + +SET ROLE TO DEFAULT; + +DROP VARIABLE v1; +DROP VARIABLE v2; + +REVOKE USAGE ON SCHEMA svartest FROM var_test_role; +DROP ROLE var_test_role; + +-- scalar variables should not be in conflict with qualified column +CREATE VARIABLE varx AS text; +SELECT varx.relname FROM pg_class varx WHERE varx.relname = 'pg_class'; + +-- should fail +SELECT varx.xxx; + +-- variables can be updated under RO transaction + +BEGIN; +SET TRANSACTION READ ONLY; +LET varx = 'hello'; +COMMIT; + +SELECT varx; + +DROP VARIABLE varx; + +CREATE TYPE t1 AS (a int, b numeric, c text); + +CREATE VARIABLE v1 AS t1; +LET v1 = (1, pi(), 'hello'); +SELECT v1; +LET v1.b = 10.2222; +SELECT v1; + +-- should fail +LET v1.x = 10; + +DROP VARIABLE v1; +DROP TYPE t1; + +-- arrays are supported +CREATE VARIABLE va1 AS numeric[]; +LET va1 = ARRAY[1.1,2.1]; +LET va1[1] = 10.1; +SELECT va1; + +CREATE TYPE ta2 AS (a numeric, b numeric[]); +CREATE VARIABLE va2 AS ta2; +LET va2 = (10.1, ARRAY[0.0, 0.0]); +LET va2.a = 10.2; +SELECT va2; +LET va2.b[1] = 10.3; +SELECT va2; + +DROP VARIABLE va1; +DROP VARIABLE va2; +DROP TYPE ta2; + +-- default values +CREATE VARIABLE v1 AS numeric DEFAULT pi(); +LET v1 = v1 * 2; +SELECT v1; + +CREATE TYPE t2 AS (a numeric, b text); +CREATE VARIABLE v2 AS t2 DEFAULT (NULL, 'Hello'); +LET svartest.v2.a = pi(); +SELECT v2; + +-- should fail due dependency +DROP TYPE t2; + +-- should be ok +DROP VARIABLE v1; +DROP VARIABLE v2; + +-- tests of alters +CREATE SCHEMA var_schema1; +CREATE SCHEMA var_schema2; + +CREATE VARIABLE var_schema1.var1 AS integer; +LET var_schema1.var1 = 1000; +SELECT var_schema1.var1; +ALTER VARIABLE var_schema1.var1 SET SCHEMA var_schema2; +SELECT var_schema2.var1; + +CREATE ROLE var_test_role; + +ALTER VARIABLE var_schema2.var1 OWNER TO var_test_role; +SET ROLE TO var_test_role; + +-- should fail, no access to schema var_schema2.var +SELECT var_schema2.var1; +DROP VARIABLE var_schema2.var1; + +SET ROLE TO DEFAULT; + +ALTER VARIABLE var_schema2.var1 SET SCHEMA public; + +SET ROLE TO var_test_role; +SELECT public.var1; + +ALTER VARIABLE public.var1 RENAME TO var1_renamed; + +SELECT public.var1_renamed; + +DROP VARIABLE public.var1_renamed; + +SET ROLE TO DEFAULt; + +-- default rights test +ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON VARIABLES TO var_test_role; + +CREATE VARIABLE public.var2 AS int; + +SET ROLE TO var_test_role; + +-- should be ok +LET public.var2 = 100; +SELECT public.var2; + +SET ROLE TO DEFAULt; + +DROP VARIABLE public.var2; +DROP OWNED BY var_test_role; + +DROP ROLE var_test_role; + +CREATE VARIABLE xx AS text DEFAULT 'hello'; + +SELECT xx, upper(xx); + +LET xx = 'Hi'; + +SELECT xx; + +DROP VARIABLE xx; + +-- ON TRANSACTION END RESET tests +CREATE VARIABLE t1 AS int DEFAULT -1 ON TRANSACTION END RESET; + +BEGIN; + SELECT t1; + LET t1 = 100; + SELECT t1; +COMMIT; + +SELECT t1; + +BEGIN; + SELECT t1; + LET t1 = 100; + SELECT t1; +ROLLBACK; + +SELECT t1; + +DROP VARIABLE t1; + +CREATE VARIABLE v1 AS int DEFAULT 0; +CREATE VARIABLE v2 AS text DEFAULT 'none'; + +LET v1 = 100; +LET v2 = 'Hello'; +SELECT v1, v2; +LET v1 = DEFAULT; +LET v2 = DEFAULT; +SELECT v1, v2; + +DROP VARIABLE v1; +DROP VARIABLE v2; + +-- ON COMMIT DROP tests +-- should be 0 always +SELECT count(*) FROM pg_variable; + +CREATE TEMP VARIABLE g AS int ON COMMIT DROP; + +SELECT count(*) FROM pg_variable; + +BEGIN; + CREATE TEMP VARIABLE g AS int ON COMMIT DROP; +COMMIT; + +SELECT count(*) FROM pg_variable; + +BEGIN; + CREATE TEMP VARIABLE g AS int ON COMMIT DROP; +ROLLBACK; + +SELECT count(*) FROM pg_variable; + +-- Encourage use of parallel plans +SET parallel_setup_cost = 0; +SET parallel_tuple_cost = 0; +SET min_parallel_table_scan_size = 0; +SET max_parallel_workers_per_gather = 2; + +-- test on query with workers +CREATE TABLE svar_test(a int); +INSERT INTO svar_test SELECT * FROM generate_series(1,1000); +ANALYZE svar_test; +CREATE VARIABLE zero int; +LET zero = 0; + +-- parallel workers should be used +EXPLAIN (costs off) SELECT count(*) FROM svar_test WHERE a%10 = zero; + +-- result should be 100 +SELECT count(*) FROM svar_test WHERE a%10 = zero; + +LET zero = (SELECT count(*) FROM svar_test); + +-- result should be 1000 +SELECT zero; + +-- parallel workers should be used +EXPLAIN (costs off) LET zero = (SELECT count(*) FROM svar_test); + +-- test for dependency on relation +CREATE VARIABLE v_table AS svar_test; + +ALTER TABLE svar_test ALTER COLUMN a TYPE text; + +DROP VARIABLE v_table; +DROP TABLE svar_test; +DROP VARIABLE zero; + +RESET parallel_setup_cost; +RESET parallel_tuple_cost; +RESET min_parallel_table_scan_size; +RESET max_parallel_workers_per_gather; + +-- use variables in prepared statements +CREATE VARIABLE v AS numeric; +LET v = 3.14; + +-- use variables in views +CREATE VIEW vv AS SELECT COALESCE(v, 0) + 1000 AS result; +SELECT * FROM vv; + +-- start a new session +\c + +SET search_path to svartest; + +SELECT * FROM vv; +LET v = 3.14; +SELECT * FROM vv; + +-- should fail, dependency +DROP VARIABLE v; + +-- should be ok +DROP VARIABLE v CASCADE; + +-- other features +CREATE VARIABLE dt AS integer DEFAULT 0; + +LET dt = 100; +SELECT dt; + +DISCARD VARIABLES; + +SELECT dt; + +DROP VARIABLE dt; + +-- NOT NULL +CREATE VARIABLE v1 AS int NOT NULL; +CREATE VARIABLE v2 AS int NOT NULL DEFAULT NULL; + +-- should fail +SELECT v1; +SELECT v2; +LET v1 = NULL; +LET v2 = NULL; +LET v1 = DEFAULT; +LET v2 = DEFAULT; + +-- should be ok +LET v1 = 100; +LET v2 = 1000; +SELECT v1, v2; + +DROP VARIABLE v1; +DROP VARIABLE v2; + +CREATE VARIABLE tv AS int; +CREATE VARIABLE IF NOT EXISTS tv AS int; +DROP VARIABLE tv; + +CREATE IMMUTABLE VARIABLE iv AS int DEFAULT 100; +SELECT iv; + +-- should fail; +LET iv = 10000; + +DROP VARIABLE iv; + +-- different order +CREATE IMMUTABLE VARIABLE iv AS int DEFAULT 100; +-- should to fail +LET iv = 10000; +-- should be ok +SELECT iv; + +DROP VARIABLE iv; + +CREATE IMMUTABLE VARIABLE iv AS int; + +-- should be ok +LET iv = NULL; + +-- should fail +LET iv = NULL; + +DROP VARIABLE iv; + +-- create variable inside plpgsql block +DO $$ +BEGIN + CREATE VARIABLE do_test_svar AS date DEFAULT '2000-01-01'; +END; +$$; + +SELECT do_test_svar; + +DROP VARIABLE do_test_svar; + +-- should fail +CREATE IMMUTABLE VARIABLE xx AS int NOT NULL; + + + +-- REASSIGN OWNED test +CREATE ROLE var_test_role1; +CREATE ROLE var_test_role2; + +CREATE VARIABLE xxx_var AS int; + +ALTER VARIABLE xxx_var OWNER TO var_test_role1; +REASSIGN OWNED BY var_test_role1 to var_test_role2; + +SELECT varowner::regrole FROM pg_variable WHERE varname = 'xxx_var'; + +DROP OWNED BY var_test_role1; +DROP ROLE var_test_role1; +SELECT count(*) FROM pg_variable WHERE varname = 'xxx_var'; + +DROP OWNED BY var_test_role2; +DROP ROLE var_test_role2; +SELECT count(*) FROM pg_variable WHERE varname = 'xxx_var'; + +-- creating, dropping temporary variable +BEGIN; + +CREATE TEMP VARIABLE tempvar AS INT ON COMMIT DROP; + +LET tempvar = 100; + +SAVEPOINT s1; + +DROP VARIABLE tempvar; + +ROLLBACK TO s1; + +SELECT tempvar; + +COMMIT; + +-- should to fail +LET tempvar = 100; + +BEGIN; + +SAVEPOINT s1; + +CREATE TEMP VARIABLE tempvar AS INT ON COMMIT DROP; + +LET tempvar = 100; + +ROLLBACK TO s1; + +COMMIT; + +-- should to fail +LET tempvar = 100; + +CREATE VARIABLE var1 AS int; +LET var1 = 100; +BEGIN; +DROP VARIABLE var1; +ROLLBACK; +SELECT var1; + +DROP VARIABLE var1; + +CREATE VARIABLE var1 AS int DEFAULT 100; +COMMENT ON VARIABLE var1 IS 'some variable comment'; + +SELECT pg_catalog.obj_description(oid, 'pg_variable') FROM pg_variable WHERE varname = 'var1'; + +DROP VARIABLE var1; + +CREATE TABLE xxtab(avar int); + +CREATE TYPE xxtype AS (avar int); + +CREATE VARIABLE xxtab AS xxtype; + +INSERT INTO xxtab VALUES(10); + +-- it is ambiguous, but columns are preferred +-- variable is shadowed +SELECT xxtab.avar FROM xxtab; + +SET session_variables_ambiguity_warning TO on; + +SELECT xxtab.avar FROM xxtab; + +SET search_path = svartest; + +CREATE VARIABLE testvar as int; + +-- plpgsql variables are preferred against session variables +DO $$ +<<myblock>> +DECLARE testvar int; +BEGIN + -- should be ok without warning + LET testvar = 100; + -- should be ok without warning + testvar := 1000; + -- should be ok without warning + RAISE NOTICE 'session variable is %', svartest.testvar; + -- should be ok without warning + RAISE NOTICE 'plpgsql variable is %', myblock.testvar; + -- should to print plpgsql variable with warning + RAISE NOTICE 'variable is %', testvar; +END; +$$; + +DROP VARIABLE testvar; + +SET session_variables_ambiguity_warning TO default; + +-- should be ok +SELECT avar FROM xxtab; + +CREATE VARIABLE public.avar AS int; + +-- should be ok, see the table +SELECT avar FROM xxtab; + +-- should be ok +SELECT public.avar FROM xxtab; + +DROP VARIABLE xxtab; + +SELECT xxtab.avar FROM xxtab; + +DROP VARIABLE public.avar; + +DROP TYPE xxtype; + +DROP TABLE xxtab; + +-- test of plan cache invalidation +CREATE VARIABLE xx AS int; + +SET plan_cache_mode = force_generic_plan; + +PREPARE pp AS SELECT xx; + +EXECUTE pp; + +DROP VARIABLE xx; + +CREATE VARIABLE xx AS int; + +-- should to work +EXECUTE pp; + +DROP VARIABLE xx; + +DEALLOCATE pp; + +SET plan_cache_mode = DEFAULT; + +CREATE ROLE var_test_role; + +CREATE SCHEMA vartest; + +GRANT USAGE ON SCHEMA vartest TO var_test_role; + +CREATE VARIABLE vartest.x AS int; +CREATE VARIABLE vartest.y AS int; + +LET vartest.x = 100; +LET vartest.y = 101; + +GRANT SELECT ON ALL VARIABLES IN SCHEMA vartest TO var_test_role; + +SET ROLE TO var_test_role; + +SELECT vartest.x, vartest.y; + +SET ROLE TO DEFAULT; + +REVOKE SELECT ON ALL VARIABLES IN SCHEMA vartest FROM var_test_role; + +SET ROLE TO var_test_role; + +-- should to fail +SELECT vartest.x; +SELECT vartest.y; + +SET ROLE TO DEFAULT; + +DROP VARIABLE vartest.x, vartest.y; + +DROP SCHEMA vartest; + +DROP ROLE var_test_role; + +-- test cached plan +CREATE VARIABLE v1 AS text; +CREATE VARIABLE v2 AS int; +CREATE VARIABLE v3 AS int; + +LET v1 = 'test'; +LET v2 = 10; +LET v3 = 5; + +PREPARE q1 AS SELECT v1 || i FROM generate_series(1, v2) g(i) WHERE i IN (v2, v3); + +SET plan_cache_mode to force_generic_plan; + +EXECUTE q1; + +EXPLAIN EXECUTE q1; + +-- dependecy check +DROP VARIABLE v3; + +-- recreate v3 again +CREATE VARIABLE v3 AS int DEFAULT 6; + +-- should to work, the plan should be recreated +EXECUTE q1; + +DEALLOCATE q1; + +-- fill v1 by long text +LET v1 = repeat(' ', 10000); + +PREPARE q1 AS SELECT length(v1); + +EXECUTE q1; + +LET v1 = repeat(' ', 5000); + +EXECUTE q1; + +DEALLOCATE q1; + +SET plan_cache_mode to default; + +DROP VARIABLE v1, v2, v3; + +CREATE ROLE var_test_role; + +CREATE VARIABLE public.v1 AS int DEFAULT 0; + +-- check acl when variable is acessed by simple eval expr method +CREATE OR REPLACE FUNCTION public.fx_var(int) +RETURNS int AS $$ +DECLARE xx int; +BEGIN + xx := public.v1 + $1; + RETURN xx; +END; +$$ LANGUAGE plpgsql; + +-- should be ok +SELECT public.fx_var(0); + +SET ROLE TO var_test_role; + +-- should to fail +SELECT public.fx_var(0); + +SET ROLE TO default; + +GRANT SELECT ON VARIABLE public.v1 TO var_test_role; + +SET ROLE TO var_test_role; + +-- should be ok +SELECT public.fx_var(0); + +SET ROLE TO default; + +REVOKE SELECT ON VARIABLE public.v1 FROM var_test_role; + +SET ROLE TO var_test_role; + +-- should be fail +SELECT public.fx_var(0); + +SET ROLE TO DEFAULT; + +DROP FUNCTION public.fx_var(int); + +DROP VARIABLE public.v1; + +DROP ROLE var_test_role; + +CREATE TYPE public.svar_test_type AS (a int, b int, c numeric); + +CREATE VARIABLE public.svar AS public.svar_test_type; + +LET public.svar = ROW(10,20,30); + +SELECT public.svar; + +ALTER TYPE public.svar_test_type DROP ATTRIBUTE c; + +-- should be ok +SELECT public.svar; + +ALTER TYPE public.svar_test_type ADD ATTRIBUTE c int; + +-- should be ok +SELECT public.svar; + +LET public.svar = ROW(10,20,30); + +-- should be ok again for new value +SELECT public.svar; + +DROP VARIABLE public.svar; + +DROP TYPE public.svar_test_type; + +CREATE VARIABLE public.svar AS int; +select oid as varid from pg_variable where varname = 'svar' and varnamespace = 'public'::regnamespace \gset + +SELECT schema, name, removed FROM pg_debug_show_used_session_variables(); + +LET public.svar = 100; + +SELECT schema, name, removed FROM pg_debug_show_used_session_variables(); + +BEGIN; + +DROP VARIABLE public.svar; + +-- value should be in memory +SELECT schema, name, removed FROM pg_debug_show_used_session_variables(); + +ROLLBACK; + +-- value should be in memory +SELECT schema, name, removed FROM pg_debug_show_used_session_variables() f WHERE f.varid = :varid; + +SELECT public.svar; + +BEGIN; + +DROP VARIABLE public.svar; + +-- value should be in memory +SELECT schema, name, removed FROM pg_debug_show_used_session_variables() f WHERE f.varid = :varid;; + +COMMIT; + +-- the memory should be clean; +SELECT schema, name, removed FROM pg_debug_show_used_session_variables() WHERE f.varid = :varid; + +BEGIN; + +CREATE VARIABLE public.svar AS int; +select oid as varid from pg_variable where varname = 'svar' and varnamespace = 'public'::regnamespace \gset + + +LET public.svar = 100; + +ROLLBACK; + +-- the memory should be clean; +SELECT schema, name, removed FROM pg_debug_show_used_session_variables() f WHERE f.varid = :varid; + +\unset varid + +CREATE VARIABLE public.svar AS int; + +LET public.svar = 100; + +-- repeated aborted transaction +BEGIN; DROP VARIABLE public.svar; ROLLBACK; +BEGIN; DROP VARIABLE public.svar; ROLLBACK; +BEGIN; DROP VARIABLE public.svar; ROLLBACK; + +-- the value should be still available +SELECT public.svar; + +DROP VARIABLE public.svar; + +CREATE TYPE public.svar_test_type AS (a int, b int); + +CREATE VARIABLE public.svar AS public.svar_test_type; + +SELECT public.svar; + +ALTER TYPE public.svar_test_type ADD ATTRIBUTE c int; + +SELECT public.svar; + +ALTER TYPE public.svar_test_type DROP ATTRIBUTE b; + +SELECT public.svar; + +DROP VARIABLE public.svar; +DROP TYPE public.svar_test_type; + +CREATE TYPE public.svar_test_type AS (a int, b int); + +CREATE VARIABLE public.svar AS public.svar_test_type; +CREATE VARIABLE public.svar2 AS public.svar_test_type; + +LET public.svar = (10, 20); + +ALTER TYPE public.svar_test_type ADD ATTRIBUTE c int; + +SELECT public.svar; + +LET public.svar2 = (10, 20, 30); + +ALTER TYPE public.svar_test_type DROP ATTRIBUTE b; + +SELECT public.svar; +SELECT public.svar2; + +DROP VARIABLE public.svar; +DROP VARIABLE public.svar2; +DROP TYPE public.svar_test_type; + +-- The composite type cannot be changed when it is used +CREATE TYPE public.svar_type AS (a int, b int); + +CREATE VARIABLE public.svar AS public.svar_type; + +-- should to fail +ALTER TYPE public.svar_type ALTER ATTRIBUTE b TYPE numeric; + +DROP VARIABLE public.svar; + +CREATE TYPE public.svar_type2 AS (a int, b int, c public.svar_type); + +CREATE VARIABLE public.svar AS public.svar_type2; + +-- should to fail +ALTER TYPE public.svar_type ALTER ATTRIBUTE b TYPE numeric; + +DROP VARIABLE public.svar; +DROP TYPE public.svar_type2; +DROP TYPE public.svar_type; + +-- The variable can be shadowed by table or by alias +CREATE TYPE public.svar_type AS (a int, b int, c int); +CREATE VARIABLE public.svar AS public.svar_type; + +CREATE TABLE public.svar (a int, b int); + +INSERT INTO public.svar VALUES(10, 20); + +LET public.svar = (100, 200, 300); + +-- should be ok +-- show table +SELECT * FROM public.svar; +SELECT svar.a FROM public.svar; +SELECT svar.* FROM public.svar; + +-- show variable +SELECT public.svar; +SELECT public.svar.c; +SELECT (public.svar).*; + +-- the variable is shadowed, raise error +SELECT public.svar.c FROM public.svar; + +-- can be fixed by alias +SELECT public.svar.c FROM public.svar x; + +-- again with warnings +SET session_variables_ambiguity_warning TO on; + +SELECT * FROM public.svar; +SELECT svar.a FROM public.svar; +SELECT svar.* FROM public.svar; + +-- show variable +SELECT public.svar; +SELECT public.svar.c; +SELECT (public.svar).*; + +-- the variable is shadowed, raise error +SELECT public.svar.c FROM public.svar; + +-- can be fixed by alias +SELECT public.svar.c FROM public.svar x; + +SET session_variables_ambiguity_warning TO DEFAULT; + +DROP VARIABLE public.svar; +DROP TABLE public.svar; +DROP TYPE public.svar_type; -- 2.37.2 --gcms4zhgklsgym3k Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename*0=v20220906-1-0010-this-patch-changes-error-message-column-does; filename*1="n-t-exis.patch" ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH 09/11] regress tests for session variables @ 2022-04-04 18:54 [email protected] <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: [email protected] @ 2022-04-04 18:54 UTC (permalink / raw) Checks of basic functionality, check of usage session variables in subtransactions and from PLpgSQL --- .../isolation/expected/session-variable.out | 86 ++ src/test/isolation/isolation_schedule | 1 + .../isolation/specs/session-variable.spec | 34 + .../regress/expected/session_variables.out | 1287 +++++++++++++++++ src/test/regress/parallel_schedule | 2 +- src/test/regress/sql/session_variables.sql | 959 ++++++++++++ 6 files changed, 2368 insertions(+), 1 deletion(-) create mode 100644 src/test/isolation/expected/session-variable.out create mode 100644 src/test/isolation/specs/session-variable.spec create mode 100644 src/test/regress/expected/session_variables.out create mode 100644 src/test/regress/sql/session_variables.sql diff --git a/src/test/isolation/expected/session-variable.out b/src/test/isolation/expected/session-variable.out new file mode 100644 index 0000000000..b0059910a1 --- /dev/null +++ b/src/test/isolation/expected/session-variable.out @@ -0,0 +1,86 @@ +Parsed test spec with 2 sessions + +starting permutation: let val drop val +step let: LET myvar = 'test'; +step val: SELECT myvar; +myvar +----- +test +(1 row) + +step drop: DROP VARIABLE myvar; +step val: SELECT myvar; +ERROR: column or variable "myvar" does not exist + +starting permutation: let val s1 drop val sr1 +step let: LET myvar = 'test'; +step val: SELECT myvar; +myvar +----- +test +(1 row) + +step s1: BEGIN; +step drop: DROP VARIABLE myvar; +step val: SELECT myvar; +ERROR: column or variable "myvar" does not exist +step sr1: ROLLBACK; + +starting permutation: let val dbg drop create dbg val +step let: LET myvar = 'test'; +step val: SELECT myvar; +myvar +----- +test +(1 row) + +step dbg: SELECT schema, name, removed FROM pg_debug_show_used_session_variables(); +schema|name |removed +------+-----+------- +public|myvar|f +(1 row) + +step drop: DROP VARIABLE myvar; +step create: CREATE VARIABLE myvar AS text +step dbg: SELECT schema, name, removed FROM pg_debug_show_used_session_variables(); +schema|name|removed +------+----+------- +(0 rows) + +step val: SELECT myvar; +myvar +----- + +(1 row) + + +starting permutation: let val s1 dbg drop create dbg val sr1 +step let: LET myvar = 'test'; +step val: SELECT myvar; +myvar +----- +test +(1 row) + +step s1: BEGIN; +step dbg: SELECT schema, name, removed FROM pg_debug_show_used_session_variables(); +schema|name |removed +------+-----+------- +public|myvar|f +(1 row) + +step drop: DROP VARIABLE myvar; +step create: CREATE VARIABLE myvar AS text +step dbg: SELECT schema, name, removed FROM pg_debug_show_used_session_variables(); +schema|name |removed +------+-----+------- +public|myvar|f +(1 row) + +step val: SELECT myvar; +myvar +----- + +(1 row) + +step sr1: ROLLBACK; diff --git a/src/test/isolation/isolation_schedule b/src/test/isolation/isolation_schedule index 529a4cbd4d..96ecf93e32 100644 --- a/src/test/isolation/isolation_schedule +++ b/src/test/isolation/isolation_schedule @@ -107,3 +107,4 @@ test: cluster-conflict-partition test: truncate-conflict test: serializable-parallel test: serializable-parallel-2 +test: session-variable diff --git a/src/test/isolation/specs/session-variable.spec b/src/test/isolation/specs/session-variable.spec new file mode 100644 index 0000000000..fe47339110 --- /dev/null +++ b/src/test/isolation/specs/session-variable.spec @@ -0,0 +1,34 @@ +# Test session variables memory cleanup for sinval + +setup +{ + CREATE VARIABLE myvar AS text; +} + +teardown +{ + DROP VARIABLE IF EXISTS myvar; +} + +session s1 +step s1 { BEGIN; } +step let { LET myvar = 'test'; } +step val { SELECT myvar; } +step dbg { SELECT schema, name, removed FROM pg_debug_show_used_session_variables(); } +step sr1 { ROLLBACK; } + + +session s2 +step drop { DROP VARIABLE myvar; } +step create { CREATE VARIABLE myvar AS text } + +# Concurrent drop of a known variable should lead to an error +permutation let val drop val +# Same, but with an explicit transaction +permutation let val s1 drop val sr1 +# Concurrent drop/create of a known variable should lead to empty variable +permutation let val dbg drop create dbg val +# Concurrent drop/create of a known variable should lead to empty variable +# We need a transaction to make sure that we won't accept invalidation when +# calling the dbg step after the concurrent drop +permutation let val s1 dbg drop create dbg val sr1 diff --git a/src/test/regress/expected/session_variables.out b/src/test/regress/expected/session_variables.out new file mode 100644 index 0000000000..d411f0440d --- /dev/null +++ b/src/test/regress/expected/session_variables.out @@ -0,0 +1,1287 @@ +CREATE SCHEMA svartest; +SET search_path = svartest; +CREATE VARIABLE var1 AS integer; +CREATE TEMP VARIABLE var2 AS text; +DROP VARIABLE var1, var2; +-- functional interface +CREATE VARIABLE var1 AS numeric; +CREATE ROLE var_test_role; +GRANT USAGE ON SCHEMA svartest TO var_test_role; +SET ROLE TO var_test_role; +-- should fail +SELECT var1; +ERROR: permission denied for session variable var1 +SET ROLE TO DEFAULT; +GRANT SELECT ON VARIABLE var1 TO var_test_role; +SET ROLE TO var_test_role; +-- should fail +LET var1 = 10; +ERROR: permission denied for session variable var1 +-- should work +SELECT var1; + var1 +------ + +(1 row) + +SET ROLE TO DEFAULT; +GRANT UPDATE ON VARIABLE var1 TO var_test_role; +SET ROLE TO var_test_role; +-- should work +LET var1 = 333; +SET ROLE TO DEFAULT; +REVOKE ALL ON VARIABLE var1 FROM var_test_role; +CREATE OR REPLACE FUNCTION secure_var() +RETURNS int AS $$ + SELECT svartest.var1::int; +$$ LANGUAGE sql SECURITY DEFINER; +SELECT secure_var(); + secure_var +------------ + 333 +(1 row) + +SET ROLE TO var_test_role; +-- should fail +SELECT svartest.var1; +ERROR: permission denied for session variable var1 +-- should work; +SELECT secure_var(); + secure_var +------------ + 333 +(1 row) + +SET ROLE TO DEFAULT; +EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM generate_series(1,100) g(v) WHERE v = var1; + QUERY PLAN +----------------------------------------------- + Function Scan on pg_catalog.generate_series g + Output: v + Function Call: generate_series(1, 100) + Filter: ((g.v)::numeric = var1) +(4 rows) + +CREATE VIEW schema_var_view AS SELECT var1; +SELECT * FROM schema_var_view; + var1 +------ + 333 +(1 row) + +\c - +SET search_path = svartest; +-- should work still, but var will be empty +SELECT * FROM schema_var_view; + var1 +------ + +(1 row) + +LET var1 = pi(); +SELECT var1; + var1 +------------------ + 3.14159265358979 +(1 row) + +-- we can see execution plan of LET statement +EXPLAIN (VERBOSE, COSTS OFF) LET var1 = pi(); + QUERY PLAN +---------------------------- + SET SESSION VARIABLE + Result + Output: 3.14159265358979 +(3 rows) + +SELECT var1; + var1 +------------------ + 3.14159265358979 +(1 row) + +CREATE VARIABLE var3 AS int; +CREATE OR REPLACE FUNCTION inc(int) +RETURNS int AS $$ +BEGIN + LET svartest.var3 = COALESCE(svartest.var3 + $1, $1); + RETURN var3; +END; +$$ LANGUAGE plpgsql; +SELECT inc(1); + inc +----- + 1 +(1 row) + +SELECT inc(1); + inc +----- + 2 +(1 row) + +SELECT inc(1); + inc +----- + 3 +(1 row) + +SELECT inc(1) FROM generate_series(1,10); + inc +----- + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 +(10 rows) + +SET ROLE TO var_test_role; +-- should fail +LET var3 = 0; +ERROR: permission denied for session variable var3 +SET ROLE TO DEFAULT; +DROP VIEW schema_var_view; +DROP VARIABLE var1 CASCADE; +DROP VARIABLE var3 CASCADE; +-- composite variables +CREATE TYPE sv_xyz AS (x int, y int, z numeric(10,2)); +CREATE VARIABLE v1 AS sv_xyz; +CREATE VARIABLE v2 AS sv_xyz; +\d v1 +\d v2 +LET v1 = (1,2,3.14); +LET v2 = (10,20,3.14*10); +-- should work too - there are prepared casts +LET v1 = (1,2,3.14); +SELECT v1; + v1 +------------ + (1,2,3.14) +(1 row) + +SELECT v2; + v2 +--------------- + (10,20,31.40) +(1 row) + +SELECT (v1).*; + x | y | z +---+---+------ + 1 | 2 | 3.14 +(1 row) + +SELECT (v2).*; + x | y | z +----+----+------- + 10 | 20 | 31.40 +(1 row) + +SELECT v1.x + v1.z; + ?column? +---------- + 4.14 +(1 row) + +SELECT v2.x + v2.z; + ?column? +---------- + 41.40 +(1 row) + +-- access to composite fields should be safe too +-- should fail +SET ROLE TO var_test_role; +SELECT v2.x; +ERROR: permission denied for session variable v2 +SET ROLE TO DEFAULT; +DROP VARIABLE v1; +DROP VARIABLE v2; +REVOKE USAGE ON SCHEMA svartest FROM var_test_role; +DROP ROLE var_test_role; +-- scalar variables should not be in conflict with qualified column +CREATE VARIABLE varx AS text; +SELECT varx.relname FROM pg_class varx WHERE varx.relname = 'pg_class'; + relname +---------- + pg_class +(1 row) + +-- should fail +SELECT varx.xxx; +ERROR: type text is not composite +-- variables can be updated under RO transaction +BEGIN; +SET TRANSACTION READ ONLY; +LET varx = 'hello'; +COMMIT; +SELECT varx; + varx +------- + hello +(1 row) + +DROP VARIABLE varx; +CREATE TYPE t1 AS (a int, b numeric, c text); +CREATE VARIABLE v1 AS t1; +LET v1 = (1, pi(), 'hello'); +SELECT v1; + v1 +---------------------------- + (1,3.14159265358979,hello) +(1 row) + +LET v1.b = 10.2222; +SELECT v1; + v1 +------------------- + (1,10.2222,hello) +(1 row) + +-- should fail +LET v1.x = 10; +ERROR: cannot assign to field "x" of column "v1" because there is no such column in data type t1 +LINE 1: LET v1.x = 10; + ^ +DROP VARIABLE v1; +DROP TYPE t1; +-- arrays are supported +CREATE VARIABLE va1 AS numeric[]; +LET va1 = ARRAY[1.1,2.1]; +LET va1[1] = 10.1; +SELECT va1; + va1 +------------ + {10.1,2.1} +(1 row) + +CREATE TYPE ta2 AS (a numeric, b numeric[]); +CREATE VARIABLE va2 AS ta2; +LET va2 = (10.1, ARRAY[0.0, 0.0]); +LET va2.a = 10.2; +SELECT va2; + va2 +-------------------- + (10.2,"{0.0,0.0}") +(1 row) + +LET va2.b[1] = 10.3; +SELECT va2; + va2 +--------------------- + (10.2,"{10.3,0.0}") +(1 row) + +DROP VARIABLE va1; +DROP VARIABLE va2; +DROP TYPE ta2; +-- default values +CREATE VARIABLE v1 AS numeric DEFAULT pi(); +LET v1 = v1 * 2; +SELECT v1; + v1 +------------------ + 6.28318530717958 +(1 row) + +CREATE TYPE t2 AS (a numeric, b text); +CREATE VARIABLE v2 AS t2 DEFAULT (NULL, 'Hello'); +LET svartest.v2.a = pi(); +SELECT v2; + v2 +-------------------------- + (3.14159265358979,Hello) +(1 row) + +-- should fail due dependency +DROP TYPE t2; +ERROR: cannot drop type t2 because other objects depend on it +DETAIL: session variable v2 depends on type t2 +HINT: Use DROP ... CASCADE to drop the dependent objects too. +-- should be ok +DROP VARIABLE v1; +DROP VARIABLE v2; +-- tests of alters +CREATE SCHEMA var_schema1; +CREATE SCHEMA var_schema2; +CREATE VARIABLE var_schema1.var1 AS integer; +LET var_schema1.var1 = 1000; +SELECT var_schema1.var1; + var1 +------ + 1000 +(1 row) + +ALTER VARIABLE var_schema1.var1 SET SCHEMA var_schema2; +SELECT var_schema2.var1; + var1 +------ + 1000 +(1 row) + +CREATE ROLE var_test_role; +ALTER VARIABLE var_schema2.var1 OWNER TO var_test_role; +SET ROLE TO var_test_role; +-- should fail, no access to schema var_schema2.var +SELECT var_schema2.var1; +ERROR: permission denied for schema var_schema2 +DROP VARIABLE var_schema2.var1; +ERROR: permission denied for schema var_schema2 +SET ROLE TO DEFAULT; +ALTER VARIABLE var_schema2.var1 SET SCHEMA public; +SET ROLE TO var_test_role; +SELECT public.var1; + var1 +------ + 1000 +(1 row) + +ALTER VARIABLE public.var1 RENAME TO var1_renamed; +SELECT public.var1_renamed; + var1_renamed +-------------- + 1000 +(1 row) + +DROP VARIABLE public.var1_renamed; +SET ROLE TO DEFAULt; +-- default rights test +ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON VARIABLES TO var_test_role; +CREATE VARIABLE public.var2 AS int; +SET ROLE TO var_test_role; +-- should be ok +LET public.var2 = 100; +SELECT public.var2; + var2 +------ + 100 +(1 row) + +SET ROLE TO DEFAULt; +DROP VARIABLE public.var2; +DROP OWNED BY var_test_role; +DROP ROLE var_test_role; +CREATE VARIABLE xx AS text DEFAULT 'hello'; +SELECT xx, upper(xx); + xx | upper +-------+------- + hello | HELLO +(1 row) + +LET xx = 'Hi'; +SELECT xx; + xx +---- + Hi +(1 row) + +DROP VARIABLE xx; +-- ON TRANSACTION END RESET tests +CREATE VARIABLE t1 AS int DEFAULT -1 ON TRANSACTION END RESET; +BEGIN; + SELECT t1; + t1 +---- + -1 +(1 row) + + LET t1 = 100; + SELECT t1; + t1 +----- + 100 +(1 row) + +COMMIT; +SELECT t1; + t1 +---- + -1 +(1 row) + +BEGIN; + SELECT t1; + t1 +---- + -1 +(1 row) + + LET t1 = 100; + SELECT t1; + t1 +----- + 100 +(1 row) + +ROLLBACK; +SELECT t1; + t1 +---- + -1 +(1 row) + +DROP VARIABLE t1; +CREATE VARIABLE v1 AS int DEFAULT 0; +CREATE VARIABLE v2 AS text DEFAULT 'none'; +LET v1 = 100; +LET v2 = 'Hello'; +SELECT v1, v2; + v1 | v2 +-----+------- + 100 | Hello +(1 row) + +LET v1 = DEFAULT; +LET v2 = DEFAULT; +SELECT v1, v2; + v1 | v2 +----+------ + 0 | none +(1 row) + +DROP VARIABLE v1; +DROP VARIABLE v2; +-- ON COMMIT DROP tests +-- should be 0 always +SELECT count(*) FROM pg_variable; + count +------- + 0 +(1 row) + +CREATE TEMP VARIABLE g AS int ON COMMIT DROP; +SELECT count(*) FROM pg_variable; + count +------- + 0 +(1 row) + +BEGIN; + CREATE TEMP VARIABLE g AS int ON COMMIT DROP; +COMMIT; +SELECT count(*) FROM pg_variable; + count +------- + 0 +(1 row) + +BEGIN; + CREATE TEMP VARIABLE g AS int ON COMMIT DROP; +ROLLBACK; +SELECT count(*) FROM pg_variable; + count +------- + 0 +(1 row) + +-- Encourage use of parallel plans +SET parallel_setup_cost = 0; +SET parallel_tuple_cost = 0; +SET min_parallel_table_scan_size = 0; +SET max_parallel_workers_per_gather = 2; +-- test on query with workers +CREATE TABLE svar_test(a int); +INSERT INTO svar_test SELECT * FROM generate_series(1,1000); +ANALYZE svar_test; +CREATE VARIABLE zero int; +LET zero = 0; +-- parallel workers should be used +EXPLAIN (costs off) SELECT count(*) FROM svar_test WHERE a%10 = zero; + QUERY PLAN +-------------------------------------------- + Aggregate + -> Gather + Workers Planned: 2 + -> Parallel Seq Scan on svar_test + Filter: ((a % 10) = zero) +(5 rows) + +-- result should be 100 +SELECT count(*) FROM svar_test WHERE a%10 = zero; + count +------- + 100 +(1 row) + +LET zero = (SELECT count(*) FROM svar_test); +-- result should be 1000 +SELECT zero; + zero +------ + 1000 +(1 row) + +-- parallel workers should be used +EXPLAIN (costs off) LET zero = (SELECT count(*) FROM svar_test); + QUERY PLAN +---------------------------------------------------------- + SET SESSION VARIABLE + Result + InitPlan 1 (returns $1) + -> Finalize Aggregate + -> Gather + Workers Planned: 2 + -> Partial Aggregate + -> Parallel Seq Scan on svar_test +(8 rows) + +-- test for dependency on relation +CREATE VARIABLE v_table AS svar_test; +ALTER TABLE svar_test ALTER COLUMN a TYPE text; +ERROR: cannot alter table "svar_test" because session variable "svartest.v_table" uses it +DROP VARIABLE v_table; +DROP TABLE svar_test; +DROP VARIABLE zero; +RESET parallel_setup_cost; +RESET parallel_tuple_cost; +RESET min_parallel_table_scan_size; +RESET max_parallel_workers_per_gather; +-- use variables in prepared statements +CREATE VARIABLE v AS numeric; +LET v = 3.14; +-- use variables in views +CREATE VIEW vv AS SELECT COALESCE(v, 0) + 1000 AS result; +SELECT * FROM vv; + result +--------- + 1003.14 +(1 row) + +-- start a new session +\c +SET search_path to svartest; +SELECT * FROM vv; + result +-------- + 1000 +(1 row) + +LET v = 3.14; +SELECT * FROM vv; + result +--------- + 1003.14 +(1 row) + +-- should fail, dependency +DROP VARIABLE v; +ERROR: cannot drop session variable v because other objects depend on it +DETAIL: view vv depends on session variable v +HINT: Use DROP ... CASCADE to drop the dependent objects too. +-- should be ok +DROP VARIABLE v CASCADE; +NOTICE: drop cascades to view vv +-- other features +CREATE VARIABLE dt AS integer DEFAULT 0; +LET dt = 100; +SELECT dt; + dt +----- + 100 +(1 row) + +DISCARD VARIABLES; +SELECT dt; + dt +---- + 0 +(1 row) + +DROP VARIABLE dt; +-- NOT NULL +CREATE VARIABLE v1 AS int NOT NULL; +CREATE VARIABLE v2 AS int NOT NULL DEFAULT NULL; +-- should fail +SELECT v1; +ERROR: null value is not allowed for NOT NULL session variable "svartest.v1" +DETAIL: The session variable was not initialized yet. +SELECT v2; +ERROR: null value is not allowed for NOT NULL session variable "svartest.v2" +LET v1 = NULL; +ERROR: null value is not allowed for NOT NULL session variable "svartest.v1" +LET v2 = NULL; +ERROR: null value is not allowed for NOT NULL session variable "svartest.v2" +LET v1 = DEFAULT; +ERROR: null value is not allowed for NOT NULL session variable "svartest.v1" +LET v2 = DEFAULT; +ERROR: null value is not allowed for NOT NULL session variable "svartest.v2" +-- should be ok +LET v1 = 100; +LET v2 = 1000; +SELECT v1, v2; + v1 | v2 +-----+------ + 100 | 1000 +(1 row) + +DROP VARIABLE v1; +DROP VARIABLE v2; +CREATE VARIABLE tv AS int; +CREATE VARIABLE IF NOT EXISTS tv AS int; +NOTICE: session variable "tv" already exists, skipping +DROP VARIABLE tv; +CREATE IMMUTABLE VARIABLE iv AS int DEFAULT 100; +SELECT iv; + iv +----- + 100 +(1 row) + +-- should fail; +LET iv = 10000; +ERROR: session variable "svartest.iv" is declared IMMUTABLE +DROP VARIABLE iv; +-- different order +CREATE IMMUTABLE VARIABLE iv AS int DEFAULT 100; +-- should to fail +LET iv = 10000; +ERROR: session variable "svartest.iv" is declared IMMUTABLE +-- should be ok +SELECT iv; + iv +----- + 100 +(1 row) + +DROP VARIABLE iv; +CREATE IMMUTABLE VARIABLE iv AS int; +-- should be ok +LET iv = NULL; +-- should fail +LET iv = NULL; +ERROR: session variable "svartest.iv" is declared IMMUTABLE +DROP VARIABLE iv; +-- create variable inside plpgsql block +DO $$ +BEGIN + CREATE VARIABLE do_test_svar AS date DEFAULT '2000-01-01'; +END; +$$; +SELECT do_test_svar; + do_test_svar +-------------- + 01-01-2000 +(1 row) + +DROP VARIABLE do_test_svar; +-- should fail +CREATE IMMUTABLE VARIABLE xx AS int NOT NULL; +ERROR: IMMUTABLE NOT NULL variable requires default expression +-- REASSIGN OWNED test +CREATE ROLE var_test_role1; +CREATE ROLE var_test_role2; +CREATE VARIABLE xxx_var AS int; +ALTER VARIABLE xxx_var OWNER TO var_test_role1; +REASSIGN OWNED BY var_test_role1 to var_test_role2; +SELECT varowner::regrole FROM pg_variable WHERE varname = 'xxx_var'; + varowner +---------------- + var_test_role2 +(1 row) + +DROP OWNED BY var_test_role1; +DROP ROLE var_test_role1; +SELECT count(*) FROM pg_variable WHERE varname = 'xxx_var'; + count +------- + 1 +(1 row) + +DROP OWNED BY var_test_role2; +DROP ROLE var_test_role2; +SELECT count(*) FROM pg_variable WHERE varname = 'xxx_var'; + count +------- + 0 +(1 row) + +-- creating, dropping temporary variable +BEGIN; +CREATE TEMP VARIABLE tempvar AS INT ON COMMIT DROP; +LET tempvar = 100; +SAVEPOINT s1; +DROP VARIABLE tempvar; +ROLLBACK TO s1; +SELECT tempvar; + tempvar +--------- + 100 +(1 row) + +COMMIT; +-- should to fail +LET tempvar = 100; +ERROR: session variable "tempvar" doesn't exist +LINE 1: LET tempvar = 100; + ^ +BEGIN; +SAVEPOINT s1; +CREATE TEMP VARIABLE tempvar AS INT ON COMMIT DROP; +LET tempvar = 100; +ROLLBACK TO s1; +COMMIT; +-- should to fail +LET tempvar = 100; +ERROR: session variable "tempvar" doesn't exist +LINE 1: LET tempvar = 100; + ^ +CREATE VARIABLE var1 AS int; +LET var1 = 100; +BEGIN; +DROP VARIABLE var1; +ROLLBACK; +SELECT var1; + var1 +------ + 100 +(1 row) + +DROP VARIABLE var1; +CREATE VARIABLE var1 AS int DEFAULT 100; +COMMENT ON VARIABLE var1 IS 'some variable comment'; +SELECT pg_catalog.obj_description(oid, 'pg_variable') FROM pg_variable WHERE varname = 'var1'; + obj_description +----------------------- + some variable comment +(1 row) + +DROP VARIABLE var1; +CREATE TABLE xxtab(avar int); +CREATE TYPE xxtype AS (avar int); +CREATE VARIABLE xxtab AS xxtype; +INSERT INTO xxtab VALUES(10); +-- it is ambiguous, but columns are preferred +-- variable is shadowed +SELECT xxtab.avar FROM xxtab; + avar +------ + 10 +(1 row) + +SET session_variables_ambiguity_warning TO on; +SELECT xxtab.avar FROM xxtab; +WARNING: session variable "xxtab.avar" is shadowed +LINE 1: SELECT xxtab.avar FROM xxtab; + ^ +DETAIL: Session variables can be shadowed by columns, routine's variables and routine's arguments with the same name. + avar +------ + 10 +(1 row) + +SET search_path = svartest; +CREATE VARIABLE testvar as int; +-- plpgsql variables are preferred against session variables +DO $$ +<<myblock>> +DECLARE testvar int; +BEGIN + -- should be ok without warning + LET testvar = 100; + -- should be ok without warning + testvar := 1000; + -- should be ok without warning + RAISE NOTICE 'session variable is %', svartest.testvar; + -- should be ok without warning + RAISE NOTICE 'plpgsql variable is %', myblock.testvar; + -- should to print plpgsql variable with warning + RAISE NOTICE 'variable is %', testvar; +END; +$$; +WARNING: session variable "testvar" is shadowed +LINE 1: testvar := 1000 + ^ +DETAIL: Session variables can be shadowed by columns, routine's variables and routine's arguments with the same name. +QUERY: testvar := 1000 +NOTICE: session variable is 100 +NOTICE: plpgsql variable is 1000 +WARNING: session variable "testvar" is shadowed +LINE 1: testvar + ^ +DETAIL: Session variables can be shadowed by columns, routine's variables and routine's arguments with the same name. +QUERY: testvar +NOTICE: variable is 1000 +DROP VARIABLE testvar; +SET session_variables_ambiguity_warning TO default; +-- should be ok +SELECT avar FROM xxtab; + avar +------ + 10 +(1 row) + +CREATE VARIABLE public.avar AS int; +-- should be ok, see the table +SELECT avar FROM xxtab; + avar +------ + 10 +(1 row) + +-- should be ok +SELECT public.avar FROM xxtab; + avar +------ + +(1 row) + +DROP VARIABLE xxtab; +SELECT xxtab.avar FROM xxtab; + avar +------ + 10 +(1 row) + +DROP VARIABLE public.avar; +DROP TYPE xxtype; +DROP TABLE xxtab; +-- test of plan cache invalidation +CREATE VARIABLE xx AS int; +SET plan_cache_mode = force_generic_plan; +PREPARE pp AS SELECT xx; +EXECUTE pp; + xx +---- + +(1 row) + +DROP VARIABLE xx; +CREATE VARIABLE xx AS int; +-- should to work +EXECUTE pp; + xx +---- + +(1 row) + +DROP VARIABLE xx; +DEALLOCATE pp; +SET plan_cache_mode = DEFAULT; +CREATE ROLE var_test_role; +CREATE SCHEMA vartest; +GRANT USAGE ON SCHEMA vartest TO var_test_role; +CREATE VARIABLE vartest.x AS int; +CREATE VARIABLE vartest.y AS int; +LET vartest.x = 100; +LET vartest.y = 101; +GRANT SELECT ON ALL VARIABLES IN SCHEMA vartest TO var_test_role; +SET ROLE TO var_test_role; +SELECT vartest.x, vartest.y; + x | y +-----+----- + 100 | 101 +(1 row) + +SET ROLE TO DEFAULT; +REVOKE SELECT ON ALL VARIABLES IN SCHEMA vartest FROM var_test_role; +SET ROLE TO var_test_role; +-- should to fail +SELECT vartest.x; +ERROR: permission denied for session variable x +SELECT vartest.y; +ERROR: permission denied for session variable y +SET ROLE TO DEFAULT; +DROP VARIABLE vartest.x, vartest.y; +DROP SCHEMA vartest; +DROP ROLE var_test_role; +-- test cached plan +CREATE VARIABLE v1 AS text; +CREATE VARIABLE v2 AS int; +CREATE VARIABLE v3 AS int; +LET v1 = 'test'; +LET v2 = 10; +LET v3 = 5; +PREPARE q1 AS SELECT v1 || i FROM generate_series(1, v2) g(i) WHERE i IN (v2, v3); +SET plan_cache_mode to force_generic_plan; +EXECUTE q1; + ?column? +---------- + test5 + test10 +(2 rows) + +EXPLAIN EXECUTE q1; + QUERY PLAN +----------------------------------------------------------------------- + Function Scan on generate_series g (cost=0.00..0.14 rows=2 width=32) + Filter: (i = ANY (ARRAY[v2, v3])) +(2 rows) + +-- dependecy check +DROP VARIABLE v3; +-- recreate v3 again +CREATE VARIABLE v3 AS int DEFAULT 6; +-- should to work, the plan should be recreated +EXECUTE q1; + ?column? +---------- + test6 + test10 +(2 rows) + +DEALLOCATE q1; +-- fill v1 by long text +LET v1 = repeat(' ', 10000); +PREPARE q1 AS SELECT length(v1); +EXECUTE q1; + length +-------- + 10000 +(1 row) + +LET v1 = repeat(' ', 5000); +EXECUTE q1; + length +-------- + 5000 +(1 row) + +DEALLOCATE q1; +SET plan_cache_mode to default; +DROP VARIABLE v1, v2, v3; +CREATE ROLE var_test_role; +CREATE VARIABLE public.v1 AS int DEFAULT 0; +-- check acl when variable is acessed by simple eval expr method +CREATE OR REPLACE FUNCTION public.fx_var(int) +RETURNS int AS $$ +DECLARE xx int; +BEGIN + xx := public.v1 + $1; + RETURN xx; +END; +$$ LANGUAGE plpgsql; +-- should be ok +SELECT public.fx_var(0); + fx_var +-------- + 0 +(1 row) + +SET ROLE TO var_test_role; +-- should to fail +SELECT public.fx_var(0); +ERROR: permission denied for session variable v1 +CONTEXT: PL/pgSQL function public.fx_var(integer) line 4 at assignment +SET ROLE TO default; +GRANT SELECT ON VARIABLE public.v1 TO var_test_role; +SET ROLE TO var_test_role; +-- should be ok +SELECT public.fx_var(0); + fx_var +-------- + 0 +(1 row) + +SET ROLE TO default; +REVOKE SELECT ON VARIABLE public.v1 FROM var_test_role; +SET ROLE TO var_test_role; +-- should be fail +SELECT public.fx_var(0); +ERROR: permission denied for session variable v1 +CONTEXT: PL/pgSQL function public.fx_var(integer) line 4 at assignment +SET ROLE TO DEFAULT; +DROP FUNCTION public.fx_var(int); +DROP VARIABLE public.v1; +DROP ROLE var_test_role; +CREATE TYPE public.svar_test_type AS (a int, b int, c numeric); +CREATE VARIABLE public.svar AS public.svar_test_type; +LET public.svar = ROW(10,20,30); +SELECT public.svar; + svar +------------ + (10,20,30) +(1 row) + +ALTER TYPE public.svar_test_type DROP ATTRIBUTE c; +-- should be ok +SELECT public.svar; + svar +--------- + (10,20) +(1 row) + +ALTER TYPE public.svar_test_type ADD ATTRIBUTE c int; +-- should be ok +SELECT public.svar; + svar +---------- + (10,20,) +(1 row) + +LET public.svar = ROW(10,20,30); +-- should be ok again for new value +SELECT public.svar; + svar +------------ + (10,20,30) +(1 row) + +DROP VARIABLE public.svar; +DROP TYPE public.svar_test_type; +CREATE VARIABLE public.svar AS int; +select oid as varid from pg_variable where varname = 'svar' and varnamespace = 'public'::regnamespace \gset +SELECT schema, name, removed FROM pg_debug_show_used_session_variables(); + schema | name | removed +--------+------+--------- +(0 rows) + +LET public.svar = 100; +SELECT schema, name, removed FROM pg_debug_show_used_session_variables(); + schema | name | removed +--------+------+--------- + public | svar | f +(1 row) + +BEGIN; +DROP VARIABLE public.svar; +-- value should be in memory +SELECT schema, name, removed FROM pg_debug_show_used_session_variables(); + schema | name | removed +--------+------+--------- + | | t +(1 row) + +ROLLBACK; +-- value should be in memory +SELECT schema, name, removed FROM pg_debug_show_used_session_variables() f WHERE f.varid = :varid; + schema | name | removed +--------+------+--------- + public | svar | f +(1 row) + +SELECT public.svar; + svar +------ + 100 +(1 row) + +BEGIN; +DROP VARIABLE public.svar; +-- value should be in memory +SELECT schema, name, removed FROM pg_debug_show_used_session_variables() f WHERE f.varid = :varid;; + schema | name | removed +--------+------+--------- + | | t +(1 row) + +COMMIT; +-- the memory should be clean; +SELECT schema, name, removed FROM pg_debug_show_used_session_variables() WHERE f.varid = :varid; +ERROR: missing FROM-clause entry for table "f" +LINE 1: ...FROM pg_debug_show_used_session_variables() WHERE f.varid = ... + ^ +BEGIN; +CREATE VARIABLE public.svar AS int; +select oid as varid from pg_variable where varname = 'svar' and varnamespace = 'public'::regnamespace \gset +LET public.svar = 100; +ROLLBACK; +-- the memory should be clean; +SELECT schema, name, removed FROM pg_debug_show_used_session_variables() f WHERE f.varid = :varid; + schema | name | removed +--------+------+--------- +(0 rows) + +\unset varid +CREATE VARIABLE public.svar AS int; +LET public.svar = 100; +-- repeated aborted transaction +BEGIN; DROP VARIABLE public.svar; ROLLBACK; +BEGIN; DROP VARIABLE public.svar; ROLLBACK; +BEGIN; DROP VARIABLE public.svar; ROLLBACK; +-- the value should be still available +SELECT public.svar; + svar +------ + 100 +(1 row) + +DROP VARIABLE public.svar; +CREATE TYPE public.svar_test_type AS (a int, b int); +CREATE VARIABLE public.svar AS public.svar_test_type; +SELECT public.svar; + svar +------ + +(1 row) + +ALTER TYPE public.svar_test_type ADD ATTRIBUTE c int; +SELECT public.svar; + svar +------ + +(1 row) + +ALTER TYPE public.svar_test_type DROP ATTRIBUTE b; +SELECT public.svar; + svar +------ + +(1 row) + +DROP VARIABLE public.svar; +DROP TYPE public.svar_test_type; +CREATE TYPE public.svar_test_type AS (a int, b int); +CREATE VARIABLE public.svar AS public.svar_test_type; +CREATE VARIABLE public.svar2 AS public.svar_test_type; +LET public.svar = (10, 20); +ALTER TYPE public.svar_test_type ADD ATTRIBUTE c int; +SELECT public.svar; + svar +---------- + (10,20,) +(1 row) + +LET public.svar2 = (10, 20, 30); +ALTER TYPE public.svar_test_type DROP ATTRIBUTE b; +SELECT public.svar; + svar +------- + (10,) +(1 row) + +SELECT public.svar2; + svar2 +--------- + (10,30) +(1 row) + +DROP VARIABLE public.svar; +DROP VARIABLE public.svar2; +DROP TYPE public.svar_test_type; +-- The composite type cannot be changed when it is used +CREATE TYPE public.svar_type AS (a int, b int); +CREATE VARIABLE public.svar AS public.svar_type; +-- should to fail +ALTER TYPE public.svar_type ALTER ATTRIBUTE b TYPE numeric; +ERROR: cannot alter type "svar_type" because session variable "public.svar" uses it +DROP VARIABLE public.svar; +CREATE TYPE public.svar_type2 AS (a int, b int, c public.svar_type); +CREATE VARIABLE public.svar AS public.svar_type2; +-- should to fail +ALTER TYPE public.svar_type ALTER ATTRIBUTE b TYPE numeric; +ERROR: cannot alter type "svar_type" because session variable "public.svar" uses it +DROP VARIABLE public.svar; +DROP TYPE public.svar_type2; +DROP TYPE public.svar_type; +-- The variable can be shadowed by table or by alias +CREATE TYPE public.svar_type AS (a int, b int, c int); +CREATE VARIABLE public.svar AS public.svar_type; +CREATE TABLE public.svar (a int, b int); +INSERT INTO public.svar VALUES(10, 20); +LET public.svar = (100, 200, 300); +-- should be ok +-- show table +SELECT * FROM public.svar; + a | b +----+---- + 10 | 20 +(1 row) + +SELECT svar.a FROM public.svar; + a +---- + 10 +(1 row) + +SELECT svar.* FROM public.svar; + a | b +----+---- + 10 | 20 +(1 row) + +-- show variable +SELECT public.svar; + svar +--------------- + (100,200,300) +(1 row) + +SELECT public.svar.c; + c +----- + 300 +(1 row) + +SELECT (public.svar).*; + a | b | c +-----+-----+----- + 100 | 200 | 300 +(1 row) + +-- the variable is shadowed, raise error +SELECT public.svar.c FROM public.svar; +ERROR: column svar.c does not exist +LINE 1: SELECT public.svar.c FROM public.svar; + ^ +-- can be fixed by alias +SELECT public.svar.c FROM public.svar x; + c +----- + 300 +(1 row) + +-- again with warnings +SET session_variables_ambiguity_warning TO on; +SELECT * FROM public.svar; + a | b +----+---- + 10 | 20 +(1 row) + +SELECT svar.a FROM public.svar; + a +---- + 10 +(1 row) + +SELECT svar.* FROM public.svar; + a | b +----+---- + 10 | 20 +(1 row) + +-- show variable +SELECT public.svar; + svar +--------------- + (100,200,300) +(1 row) + +SELECT public.svar.c; + c +----- + 300 +(1 row) + +SELECT (public.svar).*; + a | b | c +-----+-----+----- + 100 | 200 | 300 +(1 row) + +-- the variable is shadowed, raise error +SELECT public.svar.c FROM public.svar; +WARNING: session variable "public.svar" is shadowed +LINE 1: SELECT public.svar.c FROM public.svar; + ^ +DETAIL: Session variables can be shadowed by tables or table's aliases with the same name. +ERROR: column svar.c does not exist +LINE 1: SELECT public.svar.c FROM public.svar; + ^ +-- can be fixed by alias +SELECT public.svar.c FROM public.svar x; + c +----- + 300 +(1 row) + +SET session_variables_ambiguity_warning TO DEFAULT; +DROP VARIABLE public.svar; +DROP TABLE public.svar; +DROP TYPE public.svar_type; diff --git a/src/test/regress/parallel_schedule b/src/test/regress/parallel_schedule index 9f644a0c1b..7426b39ab3 100644 --- a/src/test/regress/parallel_schedule +++ b/src/test/regress/parallel_schedule @@ -119,7 +119,7 @@ test: json jsonb json_encoding jsonpath jsonpath_encoding jsonb_jsonpath # NB: temp.sql does a reconnect which transiently uses 2 connections, # so keep this parallel group to at most 19 tests # ---------- -test: plancache limit plpgsql copy2 temp domain rangefuncs prepare conversion truncate alter_table sequence polymorphism rowtypes returning largeobject with xml +test: plancache limit plpgsql copy2 temp domain rangefuncs prepare conversion truncate alter_table sequence polymorphism rowtypes returning largeobject with xml session_variables # ---------- # Another group of parallel tests diff --git a/src/test/regress/sql/session_variables.sql b/src/test/regress/sql/session_variables.sql new file mode 100644 index 0000000000..d32bb5b042 --- /dev/null +++ b/src/test/regress/sql/session_variables.sql @@ -0,0 +1,959 @@ +CREATE SCHEMA svartest; + +SET search_path = svartest; + +CREATE VARIABLE var1 AS integer; +CREATE TEMP VARIABLE var2 AS text; + +DROP VARIABLE var1, var2; + +-- functional interface +CREATE VARIABLE var1 AS numeric; + +CREATE ROLE var_test_role; +GRANT USAGE ON SCHEMA svartest TO var_test_role; + +SET ROLE TO var_test_role; + +-- should fail +SELECT var1; + +SET ROLE TO DEFAULT; + +GRANT SELECT ON VARIABLE var1 TO var_test_role; + +SET ROLE TO var_test_role; +-- should fail +LET var1 = 10; +-- should work +SELECT var1; + +SET ROLE TO DEFAULT; + +GRANT UPDATE ON VARIABLE var1 TO var_test_role; + +SET ROLE TO var_test_role; + +-- should work +LET var1 = 333; + +SET ROLE TO DEFAULT; + +REVOKE ALL ON VARIABLE var1 FROM var_test_role; + +CREATE OR REPLACE FUNCTION secure_var() +RETURNS int AS $$ + SELECT svartest.var1::int; +$$ LANGUAGE sql SECURITY DEFINER; + +SELECT secure_var(); + +SET ROLE TO var_test_role; + +-- should fail +SELECT svartest.var1; + +-- should work; +SELECT secure_var(); + +SET ROLE TO DEFAULT; + +EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM generate_series(1,100) g(v) WHERE v = var1; + +CREATE VIEW schema_var_view AS SELECT var1; + +SELECT * FROM schema_var_view; + +\c - + +SET search_path = svartest; + +-- should work still, but var will be empty +SELECT * FROM schema_var_view; + +LET var1 = pi(); + +SELECT var1; + +-- we can see execution plan of LET statement +EXPLAIN (VERBOSE, COSTS OFF) LET var1 = pi(); + +SELECT var1; + +CREATE VARIABLE var3 AS int; + +CREATE OR REPLACE FUNCTION inc(int) +RETURNS int AS $$ +BEGIN + LET svartest.var3 = COALESCE(svartest.var3 + $1, $1); + RETURN var3; +END; +$$ LANGUAGE plpgsql; + +SELECT inc(1); +SELECT inc(1); +SELECT inc(1); + +SELECT inc(1) FROM generate_series(1,10); + +SET ROLE TO var_test_role; + +-- should fail +LET var3 = 0; + +SET ROLE TO DEFAULT; + +DROP VIEW schema_var_view; + +DROP VARIABLE var1 CASCADE; +DROP VARIABLE var3 CASCADE; + +-- composite variables + +CREATE TYPE sv_xyz AS (x int, y int, z numeric(10,2)); + +CREATE VARIABLE v1 AS sv_xyz; +CREATE VARIABLE v2 AS sv_xyz; + +\d v1 +\d v2 + +LET v1 = (1,2,3.14); +LET v2 = (10,20,3.14*10); + +-- should work too - there are prepared casts +LET v1 = (1,2,3.14); + +SELECT v1; +SELECT v2; +SELECT (v1).*; +SELECT (v2).*; + +SELECT v1.x + v1.z; +SELECT v2.x + v2.z; + +-- access to composite fields should be safe too +-- should fail +SET ROLE TO var_test_role; + +SELECT v2.x; + +SET ROLE TO DEFAULT; + +DROP VARIABLE v1; +DROP VARIABLE v2; + +REVOKE USAGE ON SCHEMA svartest FROM var_test_role; +DROP ROLE var_test_role; + +-- scalar variables should not be in conflict with qualified column +CREATE VARIABLE varx AS text; +SELECT varx.relname FROM pg_class varx WHERE varx.relname = 'pg_class'; + +-- should fail +SELECT varx.xxx; + +-- variables can be updated under RO transaction + +BEGIN; +SET TRANSACTION READ ONLY; +LET varx = 'hello'; +COMMIT; + +SELECT varx; + +DROP VARIABLE varx; + +CREATE TYPE t1 AS (a int, b numeric, c text); + +CREATE VARIABLE v1 AS t1; +LET v1 = (1, pi(), 'hello'); +SELECT v1; +LET v1.b = 10.2222; +SELECT v1; + +-- should fail +LET v1.x = 10; + +DROP VARIABLE v1; +DROP TYPE t1; + +-- arrays are supported +CREATE VARIABLE va1 AS numeric[]; +LET va1 = ARRAY[1.1,2.1]; +LET va1[1] = 10.1; +SELECT va1; + +CREATE TYPE ta2 AS (a numeric, b numeric[]); +CREATE VARIABLE va2 AS ta2; +LET va2 = (10.1, ARRAY[0.0, 0.0]); +LET va2.a = 10.2; +SELECT va2; +LET va2.b[1] = 10.3; +SELECT va2; + +DROP VARIABLE va1; +DROP VARIABLE va2; +DROP TYPE ta2; + +-- default values +CREATE VARIABLE v1 AS numeric DEFAULT pi(); +LET v1 = v1 * 2; +SELECT v1; + +CREATE TYPE t2 AS (a numeric, b text); +CREATE VARIABLE v2 AS t2 DEFAULT (NULL, 'Hello'); +LET svartest.v2.a = pi(); +SELECT v2; + +-- should fail due dependency +DROP TYPE t2; + +-- should be ok +DROP VARIABLE v1; +DROP VARIABLE v2; + +-- tests of alters +CREATE SCHEMA var_schema1; +CREATE SCHEMA var_schema2; + +CREATE VARIABLE var_schema1.var1 AS integer; +LET var_schema1.var1 = 1000; +SELECT var_schema1.var1; +ALTER VARIABLE var_schema1.var1 SET SCHEMA var_schema2; +SELECT var_schema2.var1; + +CREATE ROLE var_test_role; + +ALTER VARIABLE var_schema2.var1 OWNER TO var_test_role; +SET ROLE TO var_test_role; + +-- should fail, no access to schema var_schema2.var +SELECT var_schema2.var1; +DROP VARIABLE var_schema2.var1; + +SET ROLE TO DEFAULT; + +ALTER VARIABLE var_schema2.var1 SET SCHEMA public; + +SET ROLE TO var_test_role; +SELECT public.var1; + +ALTER VARIABLE public.var1 RENAME TO var1_renamed; + +SELECT public.var1_renamed; + +DROP VARIABLE public.var1_renamed; + +SET ROLE TO DEFAULt; + +-- default rights test +ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON VARIABLES TO var_test_role; + +CREATE VARIABLE public.var2 AS int; + +SET ROLE TO var_test_role; + +-- should be ok +LET public.var2 = 100; +SELECT public.var2; + +SET ROLE TO DEFAULt; + +DROP VARIABLE public.var2; +DROP OWNED BY var_test_role; + +DROP ROLE var_test_role; + +CREATE VARIABLE xx AS text DEFAULT 'hello'; + +SELECT xx, upper(xx); + +LET xx = 'Hi'; + +SELECT xx; + +DROP VARIABLE xx; + +-- ON TRANSACTION END RESET tests +CREATE VARIABLE t1 AS int DEFAULT -1 ON TRANSACTION END RESET; + +BEGIN; + SELECT t1; + LET t1 = 100; + SELECT t1; +COMMIT; + +SELECT t1; + +BEGIN; + SELECT t1; + LET t1 = 100; + SELECT t1; +ROLLBACK; + +SELECT t1; + +DROP VARIABLE t1; + +CREATE VARIABLE v1 AS int DEFAULT 0; +CREATE VARIABLE v2 AS text DEFAULT 'none'; + +LET v1 = 100; +LET v2 = 'Hello'; +SELECT v1, v2; +LET v1 = DEFAULT; +LET v2 = DEFAULT; +SELECT v1, v2; + +DROP VARIABLE v1; +DROP VARIABLE v2; + +-- ON COMMIT DROP tests +-- should be 0 always +SELECT count(*) FROM pg_variable; + +CREATE TEMP VARIABLE g AS int ON COMMIT DROP; + +SELECT count(*) FROM pg_variable; + +BEGIN; + CREATE TEMP VARIABLE g AS int ON COMMIT DROP; +COMMIT; + +SELECT count(*) FROM pg_variable; + +BEGIN; + CREATE TEMP VARIABLE g AS int ON COMMIT DROP; +ROLLBACK; + +SELECT count(*) FROM pg_variable; + +-- Encourage use of parallel plans +SET parallel_setup_cost = 0; +SET parallel_tuple_cost = 0; +SET min_parallel_table_scan_size = 0; +SET max_parallel_workers_per_gather = 2; + +-- test on query with workers +CREATE TABLE svar_test(a int); +INSERT INTO svar_test SELECT * FROM generate_series(1,1000); +ANALYZE svar_test; +CREATE VARIABLE zero int; +LET zero = 0; + +-- parallel workers should be used +EXPLAIN (costs off) SELECT count(*) FROM svar_test WHERE a%10 = zero; + +-- result should be 100 +SELECT count(*) FROM svar_test WHERE a%10 = zero; + +LET zero = (SELECT count(*) FROM svar_test); + +-- result should be 1000 +SELECT zero; + +-- parallel workers should be used +EXPLAIN (costs off) LET zero = (SELECT count(*) FROM svar_test); + +-- test for dependency on relation +CREATE VARIABLE v_table AS svar_test; + +ALTER TABLE svar_test ALTER COLUMN a TYPE text; + +DROP VARIABLE v_table; +DROP TABLE svar_test; +DROP VARIABLE zero; + +RESET parallel_setup_cost; +RESET parallel_tuple_cost; +RESET min_parallel_table_scan_size; +RESET max_parallel_workers_per_gather; + +-- use variables in prepared statements +CREATE VARIABLE v AS numeric; +LET v = 3.14; + +-- use variables in views +CREATE VIEW vv AS SELECT COALESCE(v, 0) + 1000 AS result; +SELECT * FROM vv; + +-- start a new session +\c + +SET search_path to svartest; + +SELECT * FROM vv; +LET v = 3.14; +SELECT * FROM vv; + +-- should fail, dependency +DROP VARIABLE v; + +-- should be ok +DROP VARIABLE v CASCADE; + +-- other features +CREATE VARIABLE dt AS integer DEFAULT 0; + +LET dt = 100; +SELECT dt; + +DISCARD VARIABLES; + +SELECT dt; + +DROP VARIABLE dt; + +-- NOT NULL +CREATE VARIABLE v1 AS int NOT NULL; +CREATE VARIABLE v2 AS int NOT NULL DEFAULT NULL; + +-- should fail +SELECT v1; +SELECT v2; +LET v1 = NULL; +LET v2 = NULL; +LET v1 = DEFAULT; +LET v2 = DEFAULT; + +-- should be ok +LET v1 = 100; +LET v2 = 1000; +SELECT v1, v2; + +DROP VARIABLE v1; +DROP VARIABLE v2; + +CREATE VARIABLE tv AS int; +CREATE VARIABLE IF NOT EXISTS tv AS int; +DROP VARIABLE tv; + +CREATE IMMUTABLE VARIABLE iv AS int DEFAULT 100; +SELECT iv; + +-- should fail; +LET iv = 10000; + +DROP VARIABLE iv; + +-- different order +CREATE IMMUTABLE VARIABLE iv AS int DEFAULT 100; +-- should to fail +LET iv = 10000; +-- should be ok +SELECT iv; + +DROP VARIABLE iv; + +CREATE IMMUTABLE VARIABLE iv AS int; + +-- should be ok +LET iv = NULL; + +-- should fail +LET iv = NULL; + +DROP VARIABLE iv; + +-- create variable inside plpgsql block +DO $$ +BEGIN + CREATE VARIABLE do_test_svar AS date DEFAULT '2000-01-01'; +END; +$$; + +SELECT do_test_svar; + +DROP VARIABLE do_test_svar; + +-- should fail +CREATE IMMUTABLE VARIABLE xx AS int NOT NULL; + + + +-- REASSIGN OWNED test +CREATE ROLE var_test_role1; +CREATE ROLE var_test_role2; + +CREATE VARIABLE xxx_var AS int; + +ALTER VARIABLE xxx_var OWNER TO var_test_role1; +REASSIGN OWNED BY var_test_role1 to var_test_role2; + +SELECT varowner::regrole FROM pg_variable WHERE varname = 'xxx_var'; + +DROP OWNED BY var_test_role1; +DROP ROLE var_test_role1; +SELECT count(*) FROM pg_variable WHERE varname = 'xxx_var'; + +DROP OWNED BY var_test_role2; +DROP ROLE var_test_role2; +SELECT count(*) FROM pg_variable WHERE varname = 'xxx_var'; + +-- creating, dropping temporary variable +BEGIN; + +CREATE TEMP VARIABLE tempvar AS INT ON COMMIT DROP; + +LET tempvar = 100; + +SAVEPOINT s1; + +DROP VARIABLE tempvar; + +ROLLBACK TO s1; + +SELECT tempvar; + +COMMIT; + +-- should to fail +LET tempvar = 100; + +BEGIN; + +SAVEPOINT s1; + +CREATE TEMP VARIABLE tempvar AS INT ON COMMIT DROP; + +LET tempvar = 100; + +ROLLBACK TO s1; + +COMMIT; + +-- should to fail +LET tempvar = 100; + +CREATE VARIABLE var1 AS int; +LET var1 = 100; +BEGIN; +DROP VARIABLE var1; +ROLLBACK; +SELECT var1; + +DROP VARIABLE var1; + +CREATE VARIABLE var1 AS int DEFAULT 100; +COMMENT ON VARIABLE var1 IS 'some variable comment'; + +SELECT pg_catalog.obj_description(oid, 'pg_variable') FROM pg_variable WHERE varname = 'var1'; + +DROP VARIABLE var1; + +CREATE TABLE xxtab(avar int); + +CREATE TYPE xxtype AS (avar int); + +CREATE VARIABLE xxtab AS xxtype; + +INSERT INTO xxtab VALUES(10); + +-- it is ambiguous, but columns are preferred +-- variable is shadowed +SELECT xxtab.avar FROM xxtab; + +SET session_variables_ambiguity_warning TO on; + +SELECT xxtab.avar FROM xxtab; + +SET search_path = svartest; + +CREATE VARIABLE testvar as int; + +-- plpgsql variables are preferred against session variables +DO $$ +<<myblock>> +DECLARE testvar int; +BEGIN + -- should be ok without warning + LET testvar = 100; + -- should be ok without warning + testvar := 1000; + -- should be ok without warning + RAISE NOTICE 'session variable is %', svartest.testvar; + -- should be ok without warning + RAISE NOTICE 'plpgsql variable is %', myblock.testvar; + -- should to print plpgsql variable with warning + RAISE NOTICE 'variable is %', testvar; +END; +$$; + +DROP VARIABLE testvar; + +SET session_variables_ambiguity_warning TO default; + +-- should be ok +SELECT avar FROM xxtab; + +CREATE VARIABLE public.avar AS int; + +-- should be ok, see the table +SELECT avar FROM xxtab; + +-- should be ok +SELECT public.avar FROM xxtab; + +DROP VARIABLE xxtab; + +SELECT xxtab.avar FROM xxtab; + +DROP VARIABLE public.avar; + +DROP TYPE xxtype; + +DROP TABLE xxtab; + +-- test of plan cache invalidation +CREATE VARIABLE xx AS int; + +SET plan_cache_mode = force_generic_plan; + +PREPARE pp AS SELECT xx; + +EXECUTE pp; + +DROP VARIABLE xx; + +CREATE VARIABLE xx AS int; + +-- should to work +EXECUTE pp; + +DROP VARIABLE xx; + +DEALLOCATE pp; + +SET plan_cache_mode = DEFAULT; + +CREATE ROLE var_test_role; + +CREATE SCHEMA vartest; + +GRANT USAGE ON SCHEMA vartest TO var_test_role; + +CREATE VARIABLE vartest.x AS int; +CREATE VARIABLE vartest.y AS int; + +LET vartest.x = 100; +LET vartest.y = 101; + +GRANT SELECT ON ALL VARIABLES IN SCHEMA vartest TO var_test_role; + +SET ROLE TO var_test_role; + +SELECT vartest.x, vartest.y; + +SET ROLE TO DEFAULT; + +REVOKE SELECT ON ALL VARIABLES IN SCHEMA vartest FROM var_test_role; + +SET ROLE TO var_test_role; + +-- should to fail +SELECT vartest.x; +SELECT vartest.y; + +SET ROLE TO DEFAULT; + +DROP VARIABLE vartest.x, vartest.y; + +DROP SCHEMA vartest; + +DROP ROLE var_test_role; + +-- test cached plan +CREATE VARIABLE v1 AS text; +CREATE VARIABLE v2 AS int; +CREATE VARIABLE v3 AS int; + +LET v1 = 'test'; +LET v2 = 10; +LET v3 = 5; + +PREPARE q1 AS SELECT v1 || i FROM generate_series(1, v2) g(i) WHERE i IN (v2, v3); + +SET plan_cache_mode to force_generic_plan; + +EXECUTE q1; + +EXPLAIN EXECUTE q1; + +-- dependecy check +DROP VARIABLE v3; + +-- recreate v3 again +CREATE VARIABLE v3 AS int DEFAULT 6; + +-- should to work, the plan should be recreated +EXECUTE q1; + +DEALLOCATE q1; + +-- fill v1 by long text +LET v1 = repeat(' ', 10000); + +PREPARE q1 AS SELECT length(v1); + +EXECUTE q1; + +LET v1 = repeat(' ', 5000); + +EXECUTE q1; + +DEALLOCATE q1; + +SET plan_cache_mode to default; + +DROP VARIABLE v1, v2, v3; + +CREATE ROLE var_test_role; + +CREATE VARIABLE public.v1 AS int DEFAULT 0; + +-- check acl when variable is acessed by simple eval expr method +CREATE OR REPLACE FUNCTION public.fx_var(int) +RETURNS int AS $$ +DECLARE xx int; +BEGIN + xx := public.v1 + $1; + RETURN xx; +END; +$$ LANGUAGE plpgsql; + +-- should be ok +SELECT public.fx_var(0); + +SET ROLE TO var_test_role; + +-- should to fail +SELECT public.fx_var(0); + +SET ROLE TO default; + +GRANT SELECT ON VARIABLE public.v1 TO var_test_role; + +SET ROLE TO var_test_role; + +-- should be ok +SELECT public.fx_var(0); + +SET ROLE TO default; + +REVOKE SELECT ON VARIABLE public.v1 FROM var_test_role; + +SET ROLE TO var_test_role; + +-- should be fail +SELECT public.fx_var(0); + +SET ROLE TO DEFAULT; + +DROP FUNCTION public.fx_var(int); + +DROP VARIABLE public.v1; + +DROP ROLE var_test_role; + +CREATE TYPE public.svar_test_type AS (a int, b int, c numeric); + +CREATE VARIABLE public.svar AS public.svar_test_type; + +LET public.svar = ROW(10,20,30); + +SELECT public.svar; + +ALTER TYPE public.svar_test_type DROP ATTRIBUTE c; + +-- should be ok +SELECT public.svar; + +ALTER TYPE public.svar_test_type ADD ATTRIBUTE c int; + +-- should be ok +SELECT public.svar; + +LET public.svar = ROW(10,20,30); + +-- should be ok again for new value +SELECT public.svar; + +DROP VARIABLE public.svar; + +DROP TYPE public.svar_test_type; + +CREATE VARIABLE public.svar AS int; +select oid as varid from pg_variable where varname = 'svar' and varnamespace = 'public'::regnamespace \gset + +SELECT schema, name, removed FROM pg_debug_show_used_session_variables(); + +LET public.svar = 100; + +SELECT schema, name, removed FROM pg_debug_show_used_session_variables(); + +BEGIN; + +DROP VARIABLE public.svar; + +-- value should be in memory +SELECT schema, name, removed FROM pg_debug_show_used_session_variables(); + +ROLLBACK; + +-- value should be in memory +SELECT schema, name, removed FROM pg_debug_show_used_session_variables() f WHERE f.varid = :varid; + +SELECT public.svar; + +BEGIN; + +DROP VARIABLE public.svar; + +-- value should be in memory +SELECT schema, name, removed FROM pg_debug_show_used_session_variables() f WHERE f.varid = :varid;; + +COMMIT; + +-- the memory should be clean; +SELECT schema, name, removed FROM pg_debug_show_used_session_variables() WHERE f.varid = :varid; + +BEGIN; + +CREATE VARIABLE public.svar AS int; +select oid as varid from pg_variable where varname = 'svar' and varnamespace = 'public'::regnamespace \gset + + +LET public.svar = 100; + +ROLLBACK; + +-- the memory should be clean; +SELECT schema, name, removed FROM pg_debug_show_used_session_variables() f WHERE f.varid = :varid; + +\unset varid + +CREATE VARIABLE public.svar AS int; + +LET public.svar = 100; + +-- repeated aborted transaction +BEGIN; DROP VARIABLE public.svar; ROLLBACK; +BEGIN; DROP VARIABLE public.svar; ROLLBACK; +BEGIN; DROP VARIABLE public.svar; ROLLBACK; + +-- the value should be still available +SELECT public.svar; + +DROP VARIABLE public.svar; + +CREATE TYPE public.svar_test_type AS (a int, b int); + +CREATE VARIABLE public.svar AS public.svar_test_type; + +SELECT public.svar; + +ALTER TYPE public.svar_test_type ADD ATTRIBUTE c int; + +SELECT public.svar; + +ALTER TYPE public.svar_test_type DROP ATTRIBUTE b; + +SELECT public.svar; + +DROP VARIABLE public.svar; +DROP TYPE public.svar_test_type; + +CREATE TYPE public.svar_test_type AS (a int, b int); + +CREATE VARIABLE public.svar AS public.svar_test_type; +CREATE VARIABLE public.svar2 AS public.svar_test_type; + +LET public.svar = (10, 20); + +ALTER TYPE public.svar_test_type ADD ATTRIBUTE c int; + +SELECT public.svar; + +LET public.svar2 = (10, 20, 30); + +ALTER TYPE public.svar_test_type DROP ATTRIBUTE b; + +SELECT public.svar; +SELECT public.svar2; + +DROP VARIABLE public.svar; +DROP VARIABLE public.svar2; +DROP TYPE public.svar_test_type; + +-- The composite type cannot be changed when it is used +CREATE TYPE public.svar_type AS (a int, b int); + +CREATE VARIABLE public.svar AS public.svar_type; + +-- should to fail +ALTER TYPE public.svar_type ALTER ATTRIBUTE b TYPE numeric; + +DROP VARIABLE public.svar; + +CREATE TYPE public.svar_type2 AS (a int, b int, c public.svar_type); + +CREATE VARIABLE public.svar AS public.svar_type2; + +-- should to fail +ALTER TYPE public.svar_type ALTER ATTRIBUTE b TYPE numeric; + +DROP VARIABLE public.svar; +DROP TYPE public.svar_type2; +DROP TYPE public.svar_type; + +-- The variable can be shadowed by table or by alias +CREATE TYPE public.svar_type AS (a int, b int, c int); +CREATE VARIABLE public.svar AS public.svar_type; + +CREATE TABLE public.svar (a int, b int); + +INSERT INTO public.svar VALUES(10, 20); + +LET public.svar = (100, 200, 300); + +-- should be ok +-- show table +SELECT * FROM public.svar; +SELECT svar.a FROM public.svar; +SELECT svar.* FROM public.svar; + +-- show variable +SELECT public.svar; +SELECT public.svar.c; +SELECT (public.svar).*; + +-- the variable is shadowed, raise error +SELECT public.svar.c FROM public.svar; + +-- can be fixed by alias +SELECT public.svar.c FROM public.svar x; + +-- again with warnings +SET session_variables_ambiguity_warning TO on; + +SELECT * FROM public.svar; +SELECT svar.a FROM public.svar; +SELECT svar.* FROM public.svar; + +-- show variable +SELECT public.svar; +SELECT public.svar.c; +SELECT (public.svar).*; + +-- the variable is shadowed, raise error +SELECT public.svar.c FROM public.svar; + +-- can be fixed by alias +SELECT public.svar.c FROM public.svar x; + +SET session_variables_ambiguity_warning TO DEFAULT; + +DROP VARIABLE public.svar; +DROP TABLE public.svar; +DROP TYPE public.svar_type; -- 2.37.2 --gcms4zhgklsgym3k Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename*0=v20220906-1-0010-this-patch-changes-error-message-column-does; filename*1="n-t-exis.patch" ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v20220922 10/13] regress tests for session variables @ 2022-04-04 18:54 [email protected] <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: [email protected] @ 2022-04-04 18:54 UTC (permalink / raw) Checks of basic functionality, check of usage session variables in subtransactions and from PLpgSQL --- .../isolation/expected/session-variable.out | 86 ++ src/test/isolation/isolation_schedule | 1 + .../isolation/specs/session-variable.spec | 34 + .../regress/expected/session_variables.out | 1287 +++++++++++++++++ src/test/regress/parallel_schedule | 2 +- src/test/regress/sql/session_variables.sql | 959 ++++++++++++ 6 files changed, 2368 insertions(+), 1 deletion(-) create mode 100644 src/test/isolation/expected/session-variable.out create mode 100644 src/test/isolation/specs/session-variable.spec create mode 100644 src/test/regress/expected/session_variables.out create mode 100644 src/test/regress/sql/session_variables.sql diff --git a/src/test/isolation/expected/session-variable.out b/src/test/isolation/expected/session-variable.out new file mode 100644 index 0000000000..b0059910a1 --- /dev/null +++ b/src/test/isolation/expected/session-variable.out @@ -0,0 +1,86 @@ +Parsed test spec with 2 sessions + +starting permutation: let val drop val +step let: LET myvar = 'test'; +step val: SELECT myvar; +myvar +----- +test +(1 row) + +step drop: DROP VARIABLE myvar; +step val: SELECT myvar; +ERROR: column or variable "myvar" does not exist + +starting permutation: let val s1 drop val sr1 +step let: LET myvar = 'test'; +step val: SELECT myvar; +myvar +----- +test +(1 row) + +step s1: BEGIN; +step drop: DROP VARIABLE myvar; +step val: SELECT myvar; +ERROR: column or variable "myvar" does not exist +step sr1: ROLLBACK; + +starting permutation: let val dbg drop create dbg val +step let: LET myvar = 'test'; +step val: SELECT myvar; +myvar +----- +test +(1 row) + +step dbg: SELECT schema, name, removed FROM pg_debug_show_used_session_variables(); +schema|name |removed +------+-----+------- +public|myvar|f +(1 row) + +step drop: DROP VARIABLE myvar; +step create: CREATE VARIABLE myvar AS text +step dbg: SELECT schema, name, removed FROM pg_debug_show_used_session_variables(); +schema|name|removed +------+----+------- +(0 rows) + +step val: SELECT myvar; +myvar +----- + +(1 row) + + +starting permutation: let val s1 dbg drop create dbg val sr1 +step let: LET myvar = 'test'; +step val: SELECT myvar; +myvar +----- +test +(1 row) + +step s1: BEGIN; +step dbg: SELECT schema, name, removed FROM pg_debug_show_used_session_variables(); +schema|name |removed +------+-----+------- +public|myvar|f +(1 row) + +step drop: DROP VARIABLE myvar; +step create: CREATE VARIABLE myvar AS text +step dbg: SELECT schema, name, removed FROM pg_debug_show_used_session_variables(); +schema|name |removed +------+-----+------- +public|myvar|f +(1 row) + +step val: SELECT myvar; +myvar +----- + +(1 row) + +step sr1: ROLLBACK; diff --git a/src/test/isolation/isolation_schedule b/src/test/isolation/isolation_schedule index 5413a59a80..67837ef00f 100644 --- a/src/test/isolation/isolation_schedule +++ b/src/test/isolation/isolation_schedule @@ -108,3 +108,4 @@ test: cluster-conflict-partition test: truncate-conflict test: serializable-parallel test: serializable-parallel-2 +test: session-variable diff --git a/src/test/isolation/specs/session-variable.spec b/src/test/isolation/specs/session-variable.spec new file mode 100644 index 0000000000..fe47339110 --- /dev/null +++ b/src/test/isolation/specs/session-variable.spec @@ -0,0 +1,34 @@ +# Test session variables memory cleanup for sinval + +setup +{ + CREATE VARIABLE myvar AS text; +} + +teardown +{ + DROP VARIABLE IF EXISTS myvar; +} + +session s1 +step s1 { BEGIN; } +step let { LET myvar = 'test'; } +step val { SELECT myvar; } +step dbg { SELECT schema, name, removed FROM pg_debug_show_used_session_variables(); } +step sr1 { ROLLBACK; } + + +session s2 +step drop { DROP VARIABLE myvar; } +step create { CREATE VARIABLE myvar AS text } + +# Concurrent drop of a known variable should lead to an error +permutation let val drop val +# Same, but with an explicit transaction +permutation let val s1 drop val sr1 +# Concurrent drop/create of a known variable should lead to empty variable +permutation let val dbg drop create dbg val +# Concurrent drop/create of a known variable should lead to empty variable +# We need a transaction to make sure that we won't accept invalidation when +# calling the dbg step after the concurrent drop +permutation let val s1 dbg drop create dbg val sr1 diff --git a/src/test/regress/expected/session_variables.out b/src/test/regress/expected/session_variables.out new file mode 100644 index 0000000000..d411f0440d --- /dev/null +++ b/src/test/regress/expected/session_variables.out @@ -0,0 +1,1287 @@ +CREATE SCHEMA svartest; +SET search_path = svartest; +CREATE VARIABLE var1 AS integer; +CREATE TEMP VARIABLE var2 AS text; +DROP VARIABLE var1, var2; +-- functional interface +CREATE VARIABLE var1 AS numeric; +CREATE ROLE var_test_role; +GRANT USAGE ON SCHEMA svartest TO var_test_role; +SET ROLE TO var_test_role; +-- should fail +SELECT var1; +ERROR: permission denied for session variable var1 +SET ROLE TO DEFAULT; +GRANT SELECT ON VARIABLE var1 TO var_test_role; +SET ROLE TO var_test_role; +-- should fail +LET var1 = 10; +ERROR: permission denied for session variable var1 +-- should work +SELECT var1; + var1 +------ + +(1 row) + +SET ROLE TO DEFAULT; +GRANT UPDATE ON VARIABLE var1 TO var_test_role; +SET ROLE TO var_test_role; +-- should work +LET var1 = 333; +SET ROLE TO DEFAULT; +REVOKE ALL ON VARIABLE var1 FROM var_test_role; +CREATE OR REPLACE FUNCTION secure_var() +RETURNS int AS $$ + SELECT svartest.var1::int; +$$ LANGUAGE sql SECURITY DEFINER; +SELECT secure_var(); + secure_var +------------ + 333 +(1 row) + +SET ROLE TO var_test_role; +-- should fail +SELECT svartest.var1; +ERROR: permission denied for session variable var1 +-- should work; +SELECT secure_var(); + secure_var +------------ + 333 +(1 row) + +SET ROLE TO DEFAULT; +EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM generate_series(1,100) g(v) WHERE v = var1; + QUERY PLAN +----------------------------------------------- + Function Scan on pg_catalog.generate_series g + Output: v + Function Call: generate_series(1, 100) + Filter: ((g.v)::numeric = var1) +(4 rows) + +CREATE VIEW schema_var_view AS SELECT var1; +SELECT * FROM schema_var_view; + var1 +------ + 333 +(1 row) + +\c - +SET search_path = svartest; +-- should work still, but var will be empty +SELECT * FROM schema_var_view; + var1 +------ + +(1 row) + +LET var1 = pi(); +SELECT var1; + var1 +------------------ + 3.14159265358979 +(1 row) + +-- we can see execution plan of LET statement +EXPLAIN (VERBOSE, COSTS OFF) LET var1 = pi(); + QUERY PLAN +---------------------------- + SET SESSION VARIABLE + Result + Output: 3.14159265358979 +(3 rows) + +SELECT var1; + var1 +------------------ + 3.14159265358979 +(1 row) + +CREATE VARIABLE var3 AS int; +CREATE OR REPLACE FUNCTION inc(int) +RETURNS int AS $$ +BEGIN + LET svartest.var3 = COALESCE(svartest.var3 + $1, $1); + RETURN var3; +END; +$$ LANGUAGE plpgsql; +SELECT inc(1); + inc +----- + 1 +(1 row) + +SELECT inc(1); + inc +----- + 2 +(1 row) + +SELECT inc(1); + inc +----- + 3 +(1 row) + +SELECT inc(1) FROM generate_series(1,10); + inc +----- + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 +(10 rows) + +SET ROLE TO var_test_role; +-- should fail +LET var3 = 0; +ERROR: permission denied for session variable var3 +SET ROLE TO DEFAULT; +DROP VIEW schema_var_view; +DROP VARIABLE var1 CASCADE; +DROP VARIABLE var3 CASCADE; +-- composite variables +CREATE TYPE sv_xyz AS (x int, y int, z numeric(10,2)); +CREATE VARIABLE v1 AS sv_xyz; +CREATE VARIABLE v2 AS sv_xyz; +\d v1 +\d v2 +LET v1 = (1,2,3.14); +LET v2 = (10,20,3.14*10); +-- should work too - there are prepared casts +LET v1 = (1,2,3.14); +SELECT v1; + v1 +------------ + (1,2,3.14) +(1 row) + +SELECT v2; + v2 +--------------- + (10,20,31.40) +(1 row) + +SELECT (v1).*; + x | y | z +---+---+------ + 1 | 2 | 3.14 +(1 row) + +SELECT (v2).*; + x | y | z +----+----+------- + 10 | 20 | 31.40 +(1 row) + +SELECT v1.x + v1.z; + ?column? +---------- + 4.14 +(1 row) + +SELECT v2.x + v2.z; + ?column? +---------- + 41.40 +(1 row) + +-- access to composite fields should be safe too +-- should fail +SET ROLE TO var_test_role; +SELECT v2.x; +ERROR: permission denied for session variable v2 +SET ROLE TO DEFAULT; +DROP VARIABLE v1; +DROP VARIABLE v2; +REVOKE USAGE ON SCHEMA svartest FROM var_test_role; +DROP ROLE var_test_role; +-- scalar variables should not be in conflict with qualified column +CREATE VARIABLE varx AS text; +SELECT varx.relname FROM pg_class varx WHERE varx.relname = 'pg_class'; + relname +---------- + pg_class +(1 row) + +-- should fail +SELECT varx.xxx; +ERROR: type text is not composite +-- variables can be updated under RO transaction +BEGIN; +SET TRANSACTION READ ONLY; +LET varx = 'hello'; +COMMIT; +SELECT varx; + varx +------- + hello +(1 row) + +DROP VARIABLE varx; +CREATE TYPE t1 AS (a int, b numeric, c text); +CREATE VARIABLE v1 AS t1; +LET v1 = (1, pi(), 'hello'); +SELECT v1; + v1 +---------------------------- + (1,3.14159265358979,hello) +(1 row) + +LET v1.b = 10.2222; +SELECT v1; + v1 +------------------- + (1,10.2222,hello) +(1 row) + +-- should fail +LET v1.x = 10; +ERROR: cannot assign to field "x" of column "v1" because there is no such column in data type t1 +LINE 1: LET v1.x = 10; + ^ +DROP VARIABLE v1; +DROP TYPE t1; +-- arrays are supported +CREATE VARIABLE va1 AS numeric[]; +LET va1 = ARRAY[1.1,2.1]; +LET va1[1] = 10.1; +SELECT va1; + va1 +------------ + {10.1,2.1} +(1 row) + +CREATE TYPE ta2 AS (a numeric, b numeric[]); +CREATE VARIABLE va2 AS ta2; +LET va2 = (10.1, ARRAY[0.0, 0.0]); +LET va2.a = 10.2; +SELECT va2; + va2 +-------------------- + (10.2,"{0.0,0.0}") +(1 row) + +LET va2.b[1] = 10.3; +SELECT va2; + va2 +--------------------- + (10.2,"{10.3,0.0}") +(1 row) + +DROP VARIABLE va1; +DROP VARIABLE va2; +DROP TYPE ta2; +-- default values +CREATE VARIABLE v1 AS numeric DEFAULT pi(); +LET v1 = v1 * 2; +SELECT v1; + v1 +------------------ + 6.28318530717958 +(1 row) + +CREATE TYPE t2 AS (a numeric, b text); +CREATE VARIABLE v2 AS t2 DEFAULT (NULL, 'Hello'); +LET svartest.v2.a = pi(); +SELECT v2; + v2 +-------------------------- + (3.14159265358979,Hello) +(1 row) + +-- should fail due dependency +DROP TYPE t2; +ERROR: cannot drop type t2 because other objects depend on it +DETAIL: session variable v2 depends on type t2 +HINT: Use DROP ... CASCADE to drop the dependent objects too. +-- should be ok +DROP VARIABLE v1; +DROP VARIABLE v2; +-- tests of alters +CREATE SCHEMA var_schema1; +CREATE SCHEMA var_schema2; +CREATE VARIABLE var_schema1.var1 AS integer; +LET var_schema1.var1 = 1000; +SELECT var_schema1.var1; + var1 +------ + 1000 +(1 row) + +ALTER VARIABLE var_schema1.var1 SET SCHEMA var_schema2; +SELECT var_schema2.var1; + var1 +------ + 1000 +(1 row) + +CREATE ROLE var_test_role; +ALTER VARIABLE var_schema2.var1 OWNER TO var_test_role; +SET ROLE TO var_test_role; +-- should fail, no access to schema var_schema2.var +SELECT var_schema2.var1; +ERROR: permission denied for schema var_schema2 +DROP VARIABLE var_schema2.var1; +ERROR: permission denied for schema var_schema2 +SET ROLE TO DEFAULT; +ALTER VARIABLE var_schema2.var1 SET SCHEMA public; +SET ROLE TO var_test_role; +SELECT public.var1; + var1 +------ + 1000 +(1 row) + +ALTER VARIABLE public.var1 RENAME TO var1_renamed; +SELECT public.var1_renamed; + var1_renamed +-------------- + 1000 +(1 row) + +DROP VARIABLE public.var1_renamed; +SET ROLE TO DEFAULt; +-- default rights test +ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON VARIABLES TO var_test_role; +CREATE VARIABLE public.var2 AS int; +SET ROLE TO var_test_role; +-- should be ok +LET public.var2 = 100; +SELECT public.var2; + var2 +------ + 100 +(1 row) + +SET ROLE TO DEFAULt; +DROP VARIABLE public.var2; +DROP OWNED BY var_test_role; +DROP ROLE var_test_role; +CREATE VARIABLE xx AS text DEFAULT 'hello'; +SELECT xx, upper(xx); + xx | upper +-------+------- + hello | HELLO +(1 row) + +LET xx = 'Hi'; +SELECT xx; + xx +---- + Hi +(1 row) + +DROP VARIABLE xx; +-- ON TRANSACTION END RESET tests +CREATE VARIABLE t1 AS int DEFAULT -1 ON TRANSACTION END RESET; +BEGIN; + SELECT t1; + t1 +---- + -1 +(1 row) + + LET t1 = 100; + SELECT t1; + t1 +----- + 100 +(1 row) + +COMMIT; +SELECT t1; + t1 +---- + -1 +(1 row) + +BEGIN; + SELECT t1; + t1 +---- + -1 +(1 row) + + LET t1 = 100; + SELECT t1; + t1 +----- + 100 +(1 row) + +ROLLBACK; +SELECT t1; + t1 +---- + -1 +(1 row) + +DROP VARIABLE t1; +CREATE VARIABLE v1 AS int DEFAULT 0; +CREATE VARIABLE v2 AS text DEFAULT 'none'; +LET v1 = 100; +LET v2 = 'Hello'; +SELECT v1, v2; + v1 | v2 +-----+------- + 100 | Hello +(1 row) + +LET v1 = DEFAULT; +LET v2 = DEFAULT; +SELECT v1, v2; + v1 | v2 +----+------ + 0 | none +(1 row) + +DROP VARIABLE v1; +DROP VARIABLE v2; +-- ON COMMIT DROP tests +-- should be 0 always +SELECT count(*) FROM pg_variable; + count +------- + 0 +(1 row) + +CREATE TEMP VARIABLE g AS int ON COMMIT DROP; +SELECT count(*) FROM pg_variable; + count +------- + 0 +(1 row) + +BEGIN; + CREATE TEMP VARIABLE g AS int ON COMMIT DROP; +COMMIT; +SELECT count(*) FROM pg_variable; + count +------- + 0 +(1 row) + +BEGIN; + CREATE TEMP VARIABLE g AS int ON COMMIT DROP; +ROLLBACK; +SELECT count(*) FROM pg_variable; + count +------- + 0 +(1 row) + +-- Encourage use of parallel plans +SET parallel_setup_cost = 0; +SET parallel_tuple_cost = 0; +SET min_parallel_table_scan_size = 0; +SET max_parallel_workers_per_gather = 2; +-- test on query with workers +CREATE TABLE svar_test(a int); +INSERT INTO svar_test SELECT * FROM generate_series(1,1000); +ANALYZE svar_test; +CREATE VARIABLE zero int; +LET zero = 0; +-- parallel workers should be used +EXPLAIN (costs off) SELECT count(*) FROM svar_test WHERE a%10 = zero; + QUERY PLAN +-------------------------------------------- + Aggregate + -> Gather + Workers Planned: 2 + -> Parallel Seq Scan on svar_test + Filter: ((a % 10) = zero) +(5 rows) + +-- result should be 100 +SELECT count(*) FROM svar_test WHERE a%10 = zero; + count +------- + 100 +(1 row) + +LET zero = (SELECT count(*) FROM svar_test); +-- result should be 1000 +SELECT zero; + zero +------ + 1000 +(1 row) + +-- parallel workers should be used +EXPLAIN (costs off) LET zero = (SELECT count(*) FROM svar_test); + QUERY PLAN +---------------------------------------------------------- + SET SESSION VARIABLE + Result + InitPlan 1 (returns $1) + -> Finalize Aggregate + -> Gather + Workers Planned: 2 + -> Partial Aggregate + -> Parallel Seq Scan on svar_test +(8 rows) + +-- test for dependency on relation +CREATE VARIABLE v_table AS svar_test; +ALTER TABLE svar_test ALTER COLUMN a TYPE text; +ERROR: cannot alter table "svar_test" because session variable "svartest.v_table" uses it +DROP VARIABLE v_table; +DROP TABLE svar_test; +DROP VARIABLE zero; +RESET parallel_setup_cost; +RESET parallel_tuple_cost; +RESET min_parallel_table_scan_size; +RESET max_parallel_workers_per_gather; +-- use variables in prepared statements +CREATE VARIABLE v AS numeric; +LET v = 3.14; +-- use variables in views +CREATE VIEW vv AS SELECT COALESCE(v, 0) + 1000 AS result; +SELECT * FROM vv; + result +--------- + 1003.14 +(1 row) + +-- start a new session +\c +SET search_path to svartest; +SELECT * FROM vv; + result +-------- + 1000 +(1 row) + +LET v = 3.14; +SELECT * FROM vv; + result +--------- + 1003.14 +(1 row) + +-- should fail, dependency +DROP VARIABLE v; +ERROR: cannot drop session variable v because other objects depend on it +DETAIL: view vv depends on session variable v +HINT: Use DROP ... CASCADE to drop the dependent objects too. +-- should be ok +DROP VARIABLE v CASCADE; +NOTICE: drop cascades to view vv +-- other features +CREATE VARIABLE dt AS integer DEFAULT 0; +LET dt = 100; +SELECT dt; + dt +----- + 100 +(1 row) + +DISCARD VARIABLES; +SELECT dt; + dt +---- + 0 +(1 row) + +DROP VARIABLE dt; +-- NOT NULL +CREATE VARIABLE v1 AS int NOT NULL; +CREATE VARIABLE v2 AS int NOT NULL DEFAULT NULL; +-- should fail +SELECT v1; +ERROR: null value is not allowed for NOT NULL session variable "svartest.v1" +DETAIL: The session variable was not initialized yet. +SELECT v2; +ERROR: null value is not allowed for NOT NULL session variable "svartest.v2" +LET v1 = NULL; +ERROR: null value is not allowed for NOT NULL session variable "svartest.v1" +LET v2 = NULL; +ERROR: null value is not allowed for NOT NULL session variable "svartest.v2" +LET v1 = DEFAULT; +ERROR: null value is not allowed for NOT NULL session variable "svartest.v1" +LET v2 = DEFAULT; +ERROR: null value is not allowed for NOT NULL session variable "svartest.v2" +-- should be ok +LET v1 = 100; +LET v2 = 1000; +SELECT v1, v2; + v1 | v2 +-----+------ + 100 | 1000 +(1 row) + +DROP VARIABLE v1; +DROP VARIABLE v2; +CREATE VARIABLE tv AS int; +CREATE VARIABLE IF NOT EXISTS tv AS int; +NOTICE: session variable "tv" already exists, skipping +DROP VARIABLE tv; +CREATE IMMUTABLE VARIABLE iv AS int DEFAULT 100; +SELECT iv; + iv +----- + 100 +(1 row) + +-- should fail; +LET iv = 10000; +ERROR: session variable "svartest.iv" is declared IMMUTABLE +DROP VARIABLE iv; +-- different order +CREATE IMMUTABLE VARIABLE iv AS int DEFAULT 100; +-- should to fail +LET iv = 10000; +ERROR: session variable "svartest.iv" is declared IMMUTABLE +-- should be ok +SELECT iv; + iv +----- + 100 +(1 row) + +DROP VARIABLE iv; +CREATE IMMUTABLE VARIABLE iv AS int; +-- should be ok +LET iv = NULL; +-- should fail +LET iv = NULL; +ERROR: session variable "svartest.iv" is declared IMMUTABLE +DROP VARIABLE iv; +-- create variable inside plpgsql block +DO $$ +BEGIN + CREATE VARIABLE do_test_svar AS date DEFAULT '2000-01-01'; +END; +$$; +SELECT do_test_svar; + do_test_svar +-------------- + 01-01-2000 +(1 row) + +DROP VARIABLE do_test_svar; +-- should fail +CREATE IMMUTABLE VARIABLE xx AS int NOT NULL; +ERROR: IMMUTABLE NOT NULL variable requires default expression +-- REASSIGN OWNED test +CREATE ROLE var_test_role1; +CREATE ROLE var_test_role2; +CREATE VARIABLE xxx_var AS int; +ALTER VARIABLE xxx_var OWNER TO var_test_role1; +REASSIGN OWNED BY var_test_role1 to var_test_role2; +SELECT varowner::regrole FROM pg_variable WHERE varname = 'xxx_var'; + varowner +---------------- + var_test_role2 +(1 row) + +DROP OWNED BY var_test_role1; +DROP ROLE var_test_role1; +SELECT count(*) FROM pg_variable WHERE varname = 'xxx_var'; + count +------- + 1 +(1 row) + +DROP OWNED BY var_test_role2; +DROP ROLE var_test_role2; +SELECT count(*) FROM pg_variable WHERE varname = 'xxx_var'; + count +------- + 0 +(1 row) + +-- creating, dropping temporary variable +BEGIN; +CREATE TEMP VARIABLE tempvar AS INT ON COMMIT DROP; +LET tempvar = 100; +SAVEPOINT s1; +DROP VARIABLE tempvar; +ROLLBACK TO s1; +SELECT tempvar; + tempvar +--------- + 100 +(1 row) + +COMMIT; +-- should to fail +LET tempvar = 100; +ERROR: session variable "tempvar" doesn't exist +LINE 1: LET tempvar = 100; + ^ +BEGIN; +SAVEPOINT s1; +CREATE TEMP VARIABLE tempvar AS INT ON COMMIT DROP; +LET tempvar = 100; +ROLLBACK TO s1; +COMMIT; +-- should to fail +LET tempvar = 100; +ERROR: session variable "tempvar" doesn't exist +LINE 1: LET tempvar = 100; + ^ +CREATE VARIABLE var1 AS int; +LET var1 = 100; +BEGIN; +DROP VARIABLE var1; +ROLLBACK; +SELECT var1; + var1 +------ + 100 +(1 row) + +DROP VARIABLE var1; +CREATE VARIABLE var1 AS int DEFAULT 100; +COMMENT ON VARIABLE var1 IS 'some variable comment'; +SELECT pg_catalog.obj_description(oid, 'pg_variable') FROM pg_variable WHERE varname = 'var1'; + obj_description +----------------------- + some variable comment +(1 row) + +DROP VARIABLE var1; +CREATE TABLE xxtab(avar int); +CREATE TYPE xxtype AS (avar int); +CREATE VARIABLE xxtab AS xxtype; +INSERT INTO xxtab VALUES(10); +-- it is ambiguous, but columns are preferred +-- variable is shadowed +SELECT xxtab.avar FROM xxtab; + avar +------ + 10 +(1 row) + +SET session_variables_ambiguity_warning TO on; +SELECT xxtab.avar FROM xxtab; +WARNING: session variable "xxtab.avar" is shadowed +LINE 1: SELECT xxtab.avar FROM xxtab; + ^ +DETAIL: Session variables can be shadowed by columns, routine's variables and routine's arguments with the same name. + avar +------ + 10 +(1 row) + +SET search_path = svartest; +CREATE VARIABLE testvar as int; +-- plpgsql variables are preferred against session variables +DO $$ +<<myblock>> +DECLARE testvar int; +BEGIN + -- should be ok without warning + LET testvar = 100; + -- should be ok without warning + testvar := 1000; + -- should be ok without warning + RAISE NOTICE 'session variable is %', svartest.testvar; + -- should be ok without warning + RAISE NOTICE 'plpgsql variable is %', myblock.testvar; + -- should to print plpgsql variable with warning + RAISE NOTICE 'variable is %', testvar; +END; +$$; +WARNING: session variable "testvar" is shadowed +LINE 1: testvar := 1000 + ^ +DETAIL: Session variables can be shadowed by columns, routine's variables and routine's arguments with the same name. +QUERY: testvar := 1000 +NOTICE: session variable is 100 +NOTICE: plpgsql variable is 1000 +WARNING: session variable "testvar" is shadowed +LINE 1: testvar + ^ +DETAIL: Session variables can be shadowed by columns, routine's variables and routine's arguments with the same name. +QUERY: testvar +NOTICE: variable is 1000 +DROP VARIABLE testvar; +SET session_variables_ambiguity_warning TO default; +-- should be ok +SELECT avar FROM xxtab; + avar +------ + 10 +(1 row) + +CREATE VARIABLE public.avar AS int; +-- should be ok, see the table +SELECT avar FROM xxtab; + avar +------ + 10 +(1 row) + +-- should be ok +SELECT public.avar FROM xxtab; + avar +------ + +(1 row) + +DROP VARIABLE xxtab; +SELECT xxtab.avar FROM xxtab; + avar +------ + 10 +(1 row) + +DROP VARIABLE public.avar; +DROP TYPE xxtype; +DROP TABLE xxtab; +-- test of plan cache invalidation +CREATE VARIABLE xx AS int; +SET plan_cache_mode = force_generic_plan; +PREPARE pp AS SELECT xx; +EXECUTE pp; + xx +---- + +(1 row) + +DROP VARIABLE xx; +CREATE VARIABLE xx AS int; +-- should to work +EXECUTE pp; + xx +---- + +(1 row) + +DROP VARIABLE xx; +DEALLOCATE pp; +SET plan_cache_mode = DEFAULT; +CREATE ROLE var_test_role; +CREATE SCHEMA vartest; +GRANT USAGE ON SCHEMA vartest TO var_test_role; +CREATE VARIABLE vartest.x AS int; +CREATE VARIABLE vartest.y AS int; +LET vartest.x = 100; +LET vartest.y = 101; +GRANT SELECT ON ALL VARIABLES IN SCHEMA vartest TO var_test_role; +SET ROLE TO var_test_role; +SELECT vartest.x, vartest.y; + x | y +-----+----- + 100 | 101 +(1 row) + +SET ROLE TO DEFAULT; +REVOKE SELECT ON ALL VARIABLES IN SCHEMA vartest FROM var_test_role; +SET ROLE TO var_test_role; +-- should to fail +SELECT vartest.x; +ERROR: permission denied for session variable x +SELECT vartest.y; +ERROR: permission denied for session variable y +SET ROLE TO DEFAULT; +DROP VARIABLE vartest.x, vartest.y; +DROP SCHEMA vartest; +DROP ROLE var_test_role; +-- test cached plan +CREATE VARIABLE v1 AS text; +CREATE VARIABLE v2 AS int; +CREATE VARIABLE v3 AS int; +LET v1 = 'test'; +LET v2 = 10; +LET v3 = 5; +PREPARE q1 AS SELECT v1 || i FROM generate_series(1, v2) g(i) WHERE i IN (v2, v3); +SET plan_cache_mode to force_generic_plan; +EXECUTE q1; + ?column? +---------- + test5 + test10 +(2 rows) + +EXPLAIN EXECUTE q1; + QUERY PLAN +----------------------------------------------------------------------- + Function Scan on generate_series g (cost=0.00..0.14 rows=2 width=32) + Filter: (i = ANY (ARRAY[v2, v3])) +(2 rows) + +-- dependecy check +DROP VARIABLE v3; +-- recreate v3 again +CREATE VARIABLE v3 AS int DEFAULT 6; +-- should to work, the plan should be recreated +EXECUTE q1; + ?column? +---------- + test6 + test10 +(2 rows) + +DEALLOCATE q1; +-- fill v1 by long text +LET v1 = repeat(' ', 10000); +PREPARE q1 AS SELECT length(v1); +EXECUTE q1; + length +-------- + 10000 +(1 row) + +LET v1 = repeat(' ', 5000); +EXECUTE q1; + length +-------- + 5000 +(1 row) + +DEALLOCATE q1; +SET plan_cache_mode to default; +DROP VARIABLE v1, v2, v3; +CREATE ROLE var_test_role; +CREATE VARIABLE public.v1 AS int DEFAULT 0; +-- check acl when variable is acessed by simple eval expr method +CREATE OR REPLACE FUNCTION public.fx_var(int) +RETURNS int AS $$ +DECLARE xx int; +BEGIN + xx := public.v1 + $1; + RETURN xx; +END; +$$ LANGUAGE plpgsql; +-- should be ok +SELECT public.fx_var(0); + fx_var +-------- + 0 +(1 row) + +SET ROLE TO var_test_role; +-- should to fail +SELECT public.fx_var(0); +ERROR: permission denied for session variable v1 +CONTEXT: PL/pgSQL function public.fx_var(integer) line 4 at assignment +SET ROLE TO default; +GRANT SELECT ON VARIABLE public.v1 TO var_test_role; +SET ROLE TO var_test_role; +-- should be ok +SELECT public.fx_var(0); + fx_var +-------- + 0 +(1 row) + +SET ROLE TO default; +REVOKE SELECT ON VARIABLE public.v1 FROM var_test_role; +SET ROLE TO var_test_role; +-- should be fail +SELECT public.fx_var(0); +ERROR: permission denied for session variable v1 +CONTEXT: PL/pgSQL function public.fx_var(integer) line 4 at assignment +SET ROLE TO DEFAULT; +DROP FUNCTION public.fx_var(int); +DROP VARIABLE public.v1; +DROP ROLE var_test_role; +CREATE TYPE public.svar_test_type AS (a int, b int, c numeric); +CREATE VARIABLE public.svar AS public.svar_test_type; +LET public.svar = ROW(10,20,30); +SELECT public.svar; + svar +------------ + (10,20,30) +(1 row) + +ALTER TYPE public.svar_test_type DROP ATTRIBUTE c; +-- should be ok +SELECT public.svar; + svar +--------- + (10,20) +(1 row) + +ALTER TYPE public.svar_test_type ADD ATTRIBUTE c int; +-- should be ok +SELECT public.svar; + svar +---------- + (10,20,) +(1 row) + +LET public.svar = ROW(10,20,30); +-- should be ok again for new value +SELECT public.svar; + svar +------------ + (10,20,30) +(1 row) + +DROP VARIABLE public.svar; +DROP TYPE public.svar_test_type; +CREATE VARIABLE public.svar AS int; +select oid as varid from pg_variable where varname = 'svar' and varnamespace = 'public'::regnamespace \gset +SELECT schema, name, removed FROM pg_debug_show_used_session_variables(); + schema | name | removed +--------+------+--------- +(0 rows) + +LET public.svar = 100; +SELECT schema, name, removed FROM pg_debug_show_used_session_variables(); + schema | name | removed +--------+------+--------- + public | svar | f +(1 row) + +BEGIN; +DROP VARIABLE public.svar; +-- value should be in memory +SELECT schema, name, removed FROM pg_debug_show_used_session_variables(); + schema | name | removed +--------+------+--------- + | | t +(1 row) + +ROLLBACK; +-- value should be in memory +SELECT schema, name, removed FROM pg_debug_show_used_session_variables() f WHERE f.varid = :varid; + schema | name | removed +--------+------+--------- + public | svar | f +(1 row) + +SELECT public.svar; + svar +------ + 100 +(1 row) + +BEGIN; +DROP VARIABLE public.svar; +-- value should be in memory +SELECT schema, name, removed FROM pg_debug_show_used_session_variables() f WHERE f.varid = :varid;; + schema | name | removed +--------+------+--------- + | | t +(1 row) + +COMMIT; +-- the memory should be clean; +SELECT schema, name, removed FROM pg_debug_show_used_session_variables() WHERE f.varid = :varid; +ERROR: missing FROM-clause entry for table "f" +LINE 1: ...FROM pg_debug_show_used_session_variables() WHERE f.varid = ... + ^ +BEGIN; +CREATE VARIABLE public.svar AS int; +select oid as varid from pg_variable where varname = 'svar' and varnamespace = 'public'::regnamespace \gset +LET public.svar = 100; +ROLLBACK; +-- the memory should be clean; +SELECT schema, name, removed FROM pg_debug_show_used_session_variables() f WHERE f.varid = :varid; + schema | name | removed +--------+------+--------- +(0 rows) + +\unset varid +CREATE VARIABLE public.svar AS int; +LET public.svar = 100; +-- repeated aborted transaction +BEGIN; DROP VARIABLE public.svar; ROLLBACK; +BEGIN; DROP VARIABLE public.svar; ROLLBACK; +BEGIN; DROP VARIABLE public.svar; ROLLBACK; +-- the value should be still available +SELECT public.svar; + svar +------ + 100 +(1 row) + +DROP VARIABLE public.svar; +CREATE TYPE public.svar_test_type AS (a int, b int); +CREATE VARIABLE public.svar AS public.svar_test_type; +SELECT public.svar; + svar +------ + +(1 row) + +ALTER TYPE public.svar_test_type ADD ATTRIBUTE c int; +SELECT public.svar; + svar +------ + +(1 row) + +ALTER TYPE public.svar_test_type DROP ATTRIBUTE b; +SELECT public.svar; + svar +------ + +(1 row) + +DROP VARIABLE public.svar; +DROP TYPE public.svar_test_type; +CREATE TYPE public.svar_test_type AS (a int, b int); +CREATE VARIABLE public.svar AS public.svar_test_type; +CREATE VARIABLE public.svar2 AS public.svar_test_type; +LET public.svar = (10, 20); +ALTER TYPE public.svar_test_type ADD ATTRIBUTE c int; +SELECT public.svar; + svar +---------- + (10,20,) +(1 row) + +LET public.svar2 = (10, 20, 30); +ALTER TYPE public.svar_test_type DROP ATTRIBUTE b; +SELECT public.svar; + svar +------- + (10,) +(1 row) + +SELECT public.svar2; + svar2 +--------- + (10,30) +(1 row) + +DROP VARIABLE public.svar; +DROP VARIABLE public.svar2; +DROP TYPE public.svar_test_type; +-- The composite type cannot be changed when it is used +CREATE TYPE public.svar_type AS (a int, b int); +CREATE VARIABLE public.svar AS public.svar_type; +-- should to fail +ALTER TYPE public.svar_type ALTER ATTRIBUTE b TYPE numeric; +ERROR: cannot alter type "svar_type" because session variable "public.svar" uses it +DROP VARIABLE public.svar; +CREATE TYPE public.svar_type2 AS (a int, b int, c public.svar_type); +CREATE VARIABLE public.svar AS public.svar_type2; +-- should to fail +ALTER TYPE public.svar_type ALTER ATTRIBUTE b TYPE numeric; +ERROR: cannot alter type "svar_type" because session variable "public.svar" uses it +DROP VARIABLE public.svar; +DROP TYPE public.svar_type2; +DROP TYPE public.svar_type; +-- The variable can be shadowed by table or by alias +CREATE TYPE public.svar_type AS (a int, b int, c int); +CREATE VARIABLE public.svar AS public.svar_type; +CREATE TABLE public.svar (a int, b int); +INSERT INTO public.svar VALUES(10, 20); +LET public.svar = (100, 200, 300); +-- should be ok +-- show table +SELECT * FROM public.svar; + a | b +----+---- + 10 | 20 +(1 row) + +SELECT svar.a FROM public.svar; + a +---- + 10 +(1 row) + +SELECT svar.* FROM public.svar; + a | b +----+---- + 10 | 20 +(1 row) + +-- show variable +SELECT public.svar; + svar +--------------- + (100,200,300) +(1 row) + +SELECT public.svar.c; + c +----- + 300 +(1 row) + +SELECT (public.svar).*; + a | b | c +-----+-----+----- + 100 | 200 | 300 +(1 row) + +-- the variable is shadowed, raise error +SELECT public.svar.c FROM public.svar; +ERROR: column svar.c does not exist +LINE 1: SELECT public.svar.c FROM public.svar; + ^ +-- can be fixed by alias +SELECT public.svar.c FROM public.svar x; + c +----- + 300 +(1 row) + +-- again with warnings +SET session_variables_ambiguity_warning TO on; +SELECT * FROM public.svar; + a | b +----+---- + 10 | 20 +(1 row) + +SELECT svar.a FROM public.svar; + a +---- + 10 +(1 row) + +SELECT svar.* FROM public.svar; + a | b +----+---- + 10 | 20 +(1 row) + +-- show variable +SELECT public.svar; + svar +--------------- + (100,200,300) +(1 row) + +SELECT public.svar.c; + c +----- + 300 +(1 row) + +SELECT (public.svar).*; + a | b | c +-----+-----+----- + 100 | 200 | 300 +(1 row) + +-- the variable is shadowed, raise error +SELECT public.svar.c FROM public.svar; +WARNING: session variable "public.svar" is shadowed +LINE 1: SELECT public.svar.c FROM public.svar; + ^ +DETAIL: Session variables can be shadowed by tables or table's aliases with the same name. +ERROR: column svar.c does not exist +LINE 1: SELECT public.svar.c FROM public.svar; + ^ +-- can be fixed by alias +SELECT public.svar.c FROM public.svar x; + c +----- + 300 +(1 row) + +SET session_variables_ambiguity_warning TO DEFAULT; +DROP VARIABLE public.svar; +DROP TABLE public.svar; +DROP TYPE public.svar_type; diff --git a/src/test/regress/parallel_schedule b/src/test/regress/parallel_schedule index 9f644a0c1b..7426b39ab3 100644 --- a/src/test/regress/parallel_schedule +++ b/src/test/regress/parallel_schedule @@ -119,7 +119,7 @@ test: json jsonb json_encoding jsonpath jsonpath_encoding jsonb_jsonpath # NB: temp.sql does a reconnect which transiently uses 2 connections, # so keep this parallel group to at most 19 tests # ---------- -test: plancache limit plpgsql copy2 temp domain rangefuncs prepare conversion truncate alter_table sequence polymorphism rowtypes returning largeobject with xml +test: plancache limit plpgsql copy2 temp domain rangefuncs prepare conversion truncate alter_table sequence polymorphism rowtypes returning largeobject with xml session_variables # ---------- # Another group of parallel tests diff --git a/src/test/regress/sql/session_variables.sql b/src/test/regress/sql/session_variables.sql new file mode 100644 index 0000000000..d32bb5b042 --- /dev/null +++ b/src/test/regress/sql/session_variables.sql @@ -0,0 +1,959 @@ +CREATE SCHEMA svartest; + +SET search_path = svartest; + +CREATE VARIABLE var1 AS integer; +CREATE TEMP VARIABLE var2 AS text; + +DROP VARIABLE var1, var2; + +-- functional interface +CREATE VARIABLE var1 AS numeric; + +CREATE ROLE var_test_role; +GRANT USAGE ON SCHEMA svartest TO var_test_role; + +SET ROLE TO var_test_role; + +-- should fail +SELECT var1; + +SET ROLE TO DEFAULT; + +GRANT SELECT ON VARIABLE var1 TO var_test_role; + +SET ROLE TO var_test_role; +-- should fail +LET var1 = 10; +-- should work +SELECT var1; + +SET ROLE TO DEFAULT; + +GRANT UPDATE ON VARIABLE var1 TO var_test_role; + +SET ROLE TO var_test_role; + +-- should work +LET var1 = 333; + +SET ROLE TO DEFAULT; + +REVOKE ALL ON VARIABLE var1 FROM var_test_role; + +CREATE OR REPLACE FUNCTION secure_var() +RETURNS int AS $$ + SELECT svartest.var1::int; +$$ LANGUAGE sql SECURITY DEFINER; + +SELECT secure_var(); + +SET ROLE TO var_test_role; + +-- should fail +SELECT svartest.var1; + +-- should work; +SELECT secure_var(); + +SET ROLE TO DEFAULT; + +EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM generate_series(1,100) g(v) WHERE v = var1; + +CREATE VIEW schema_var_view AS SELECT var1; + +SELECT * FROM schema_var_view; + +\c - + +SET search_path = svartest; + +-- should work still, but var will be empty +SELECT * FROM schema_var_view; + +LET var1 = pi(); + +SELECT var1; + +-- we can see execution plan of LET statement +EXPLAIN (VERBOSE, COSTS OFF) LET var1 = pi(); + +SELECT var1; + +CREATE VARIABLE var3 AS int; + +CREATE OR REPLACE FUNCTION inc(int) +RETURNS int AS $$ +BEGIN + LET svartest.var3 = COALESCE(svartest.var3 + $1, $1); + RETURN var3; +END; +$$ LANGUAGE plpgsql; + +SELECT inc(1); +SELECT inc(1); +SELECT inc(1); + +SELECT inc(1) FROM generate_series(1,10); + +SET ROLE TO var_test_role; + +-- should fail +LET var3 = 0; + +SET ROLE TO DEFAULT; + +DROP VIEW schema_var_view; + +DROP VARIABLE var1 CASCADE; +DROP VARIABLE var3 CASCADE; + +-- composite variables + +CREATE TYPE sv_xyz AS (x int, y int, z numeric(10,2)); + +CREATE VARIABLE v1 AS sv_xyz; +CREATE VARIABLE v2 AS sv_xyz; + +\d v1 +\d v2 + +LET v1 = (1,2,3.14); +LET v2 = (10,20,3.14*10); + +-- should work too - there are prepared casts +LET v1 = (1,2,3.14); + +SELECT v1; +SELECT v2; +SELECT (v1).*; +SELECT (v2).*; + +SELECT v1.x + v1.z; +SELECT v2.x + v2.z; + +-- access to composite fields should be safe too +-- should fail +SET ROLE TO var_test_role; + +SELECT v2.x; + +SET ROLE TO DEFAULT; + +DROP VARIABLE v1; +DROP VARIABLE v2; + +REVOKE USAGE ON SCHEMA svartest FROM var_test_role; +DROP ROLE var_test_role; + +-- scalar variables should not be in conflict with qualified column +CREATE VARIABLE varx AS text; +SELECT varx.relname FROM pg_class varx WHERE varx.relname = 'pg_class'; + +-- should fail +SELECT varx.xxx; + +-- variables can be updated under RO transaction + +BEGIN; +SET TRANSACTION READ ONLY; +LET varx = 'hello'; +COMMIT; + +SELECT varx; + +DROP VARIABLE varx; + +CREATE TYPE t1 AS (a int, b numeric, c text); + +CREATE VARIABLE v1 AS t1; +LET v1 = (1, pi(), 'hello'); +SELECT v1; +LET v1.b = 10.2222; +SELECT v1; + +-- should fail +LET v1.x = 10; + +DROP VARIABLE v1; +DROP TYPE t1; + +-- arrays are supported +CREATE VARIABLE va1 AS numeric[]; +LET va1 = ARRAY[1.1,2.1]; +LET va1[1] = 10.1; +SELECT va1; + +CREATE TYPE ta2 AS (a numeric, b numeric[]); +CREATE VARIABLE va2 AS ta2; +LET va2 = (10.1, ARRAY[0.0, 0.0]); +LET va2.a = 10.2; +SELECT va2; +LET va2.b[1] = 10.3; +SELECT va2; + +DROP VARIABLE va1; +DROP VARIABLE va2; +DROP TYPE ta2; + +-- default values +CREATE VARIABLE v1 AS numeric DEFAULT pi(); +LET v1 = v1 * 2; +SELECT v1; + +CREATE TYPE t2 AS (a numeric, b text); +CREATE VARIABLE v2 AS t2 DEFAULT (NULL, 'Hello'); +LET svartest.v2.a = pi(); +SELECT v2; + +-- should fail due dependency +DROP TYPE t2; + +-- should be ok +DROP VARIABLE v1; +DROP VARIABLE v2; + +-- tests of alters +CREATE SCHEMA var_schema1; +CREATE SCHEMA var_schema2; + +CREATE VARIABLE var_schema1.var1 AS integer; +LET var_schema1.var1 = 1000; +SELECT var_schema1.var1; +ALTER VARIABLE var_schema1.var1 SET SCHEMA var_schema2; +SELECT var_schema2.var1; + +CREATE ROLE var_test_role; + +ALTER VARIABLE var_schema2.var1 OWNER TO var_test_role; +SET ROLE TO var_test_role; + +-- should fail, no access to schema var_schema2.var +SELECT var_schema2.var1; +DROP VARIABLE var_schema2.var1; + +SET ROLE TO DEFAULT; + +ALTER VARIABLE var_schema2.var1 SET SCHEMA public; + +SET ROLE TO var_test_role; +SELECT public.var1; + +ALTER VARIABLE public.var1 RENAME TO var1_renamed; + +SELECT public.var1_renamed; + +DROP VARIABLE public.var1_renamed; + +SET ROLE TO DEFAULt; + +-- default rights test +ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON VARIABLES TO var_test_role; + +CREATE VARIABLE public.var2 AS int; + +SET ROLE TO var_test_role; + +-- should be ok +LET public.var2 = 100; +SELECT public.var2; + +SET ROLE TO DEFAULt; + +DROP VARIABLE public.var2; +DROP OWNED BY var_test_role; + +DROP ROLE var_test_role; + +CREATE VARIABLE xx AS text DEFAULT 'hello'; + +SELECT xx, upper(xx); + +LET xx = 'Hi'; + +SELECT xx; + +DROP VARIABLE xx; + +-- ON TRANSACTION END RESET tests +CREATE VARIABLE t1 AS int DEFAULT -1 ON TRANSACTION END RESET; + +BEGIN; + SELECT t1; + LET t1 = 100; + SELECT t1; +COMMIT; + +SELECT t1; + +BEGIN; + SELECT t1; + LET t1 = 100; + SELECT t1; +ROLLBACK; + +SELECT t1; + +DROP VARIABLE t1; + +CREATE VARIABLE v1 AS int DEFAULT 0; +CREATE VARIABLE v2 AS text DEFAULT 'none'; + +LET v1 = 100; +LET v2 = 'Hello'; +SELECT v1, v2; +LET v1 = DEFAULT; +LET v2 = DEFAULT; +SELECT v1, v2; + +DROP VARIABLE v1; +DROP VARIABLE v2; + +-- ON COMMIT DROP tests +-- should be 0 always +SELECT count(*) FROM pg_variable; + +CREATE TEMP VARIABLE g AS int ON COMMIT DROP; + +SELECT count(*) FROM pg_variable; + +BEGIN; + CREATE TEMP VARIABLE g AS int ON COMMIT DROP; +COMMIT; + +SELECT count(*) FROM pg_variable; + +BEGIN; + CREATE TEMP VARIABLE g AS int ON COMMIT DROP; +ROLLBACK; + +SELECT count(*) FROM pg_variable; + +-- Encourage use of parallel plans +SET parallel_setup_cost = 0; +SET parallel_tuple_cost = 0; +SET min_parallel_table_scan_size = 0; +SET max_parallel_workers_per_gather = 2; + +-- test on query with workers +CREATE TABLE svar_test(a int); +INSERT INTO svar_test SELECT * FROM generate_series(1,1000); +ANALYZE svar_test; +CREATE VARIABLE zero int; +LET zero = 0; + +-- parallel workers should be used +EXPLAIN (costs off) SELECT count(*) FROM svar_test WHERE a%10 = zero; + +-- result should be 100 +SELECT count(*) FROM svar_test WHERE a%10 = zero; + +LET zero = (SELECT count(*) FROM svar_test); + +-- result should be 1000 +SELECT zero; + +-- parallel workers should be used +EXPLAIN (costs off) LET zero = (SELECT count(*) FROM svar_test); + +-- test for dependency on relation +CREATE VARIABLE v_table AS svar_test; + +ALTER TABLE svar_test ALTER COLUMN a TYPE text; + +DROP VARIABLE v_table; +DROP TABLE svar_test; +DROP VARIABLE zero; + +RESET parallel_setup_cost; +RESET parallel_tuple_cost; +RESET min_parallel_table_scan_size; +RESET max_parallel_workers_per_gather; + +-- use variables in prepared statements +CREATE VARIABLE v AS numeric; +LET v = 3.14; + +-- use variables in views +CREATE VIEW vv AS SELECT COALESCE(v, 0) + 1000 AS result; +SELECT * FROM vv; + +-- start a new session +\c + +SET search_path to svartest; + +SELECT * FROM vv; +LET v = 3.14; +SELECT * FROM vv; + +-- should fail, dependency +DROP VARIABLE v; + +-- should be ok +DROP VARIABLE v CASCADE; + +-- other features +CREATE VARIABLE dt AS integer DEFAULT 0; + +LET dt = 100; +SELECT dt; + +DISCARD VARIABLES; + +SELECT dt; + +DROP VARIABLE dt; + +-- NOT NULL +CREATE VARIABLE v1 AS int NOT NULL; +CREATE VARIABLE v2 AS int NOT NULL DEFAULT NULL; + +-- should fail +SELECT v1; +SELECT v2; +LET v1 = NULL; +LET v2 = NULL; +LET v1 = DEFAULT; +LET v2 = DEFAULT; + +-- should be ok +LET v1 = 100; +LET v2 = 1000; +SELECT v1, v2; + +DROP VARIABLE v1; +DROP VARIABLE v2; + +CREATE VARIABLE tv AS int; +CREATE VARIABLE IF NOT EXISTS tv AS int; +DROP VARIABLE tv; + +CREATE IMMUTABLE VARIABLE iv AS int DEFAULT 100; +SELECT iv; + +-- should fail; +LET iv = 10000; + +DROP VARIABLE iv; + +-- different order +CREATE IMMUTABLE VARIABLE iv AS int DEFAULT 100; +-- should to fail +LET iv = 10000; +-- should be ok +SELECT iv; + +DROP VARIABLE iv; + +CREATE IMMUTABLE VARIABLE iv AS int; + +-- should be ok +LET iv = NULL; + +-- should fail +LET iv = NULL; + +DROP VARIABLE iv; + +-- create variable inside plpgsql block +DO $$ +BEGIN + CREATE VARIABLE do_test_svar AS date DEFAULT '2000-01-01'; +END; +$$; + +SELECT do_test_svar; + +DROP VARIABLE do_test_svar; + +-- should fail +CREATE IMMUTABLE VARIABLE xx AS int NOT NULL; + + + +-- REASSIGN OWNED test +CREATE ROLE var_test_role1; +CREATE ROLE var_test_role2; + +CREATE VARIABLE xxx_var AS int; + +ALTER VARIABLE xxx_var OWNER TO var_test_role1; +REASSIGN OWNED BY var_test_role1 to var_test_role2; + +SELECT varowner::regrole FROM pg_variable WHERE varname = 'xxx_var'; + +DROP OWNED BY var_test_role1; +DROP ROLE var_test_role1; +SELECT count(*) FROM pg_variable WHERE varname = 'xxx_var'; + +DROP OWNED BY var_test_role2; +DROP ROLE var_test_role2; +SELECT count(*) FROM pg_variable WHERE varname = 'xxx_var'; + +-- creating, dropping temporary variable +BEGIN; + +CREATE TEMP VARIABLE tempvar AS INT ON COMMIT DROP; + +LET tempvar = 100; + +SAVEPOINT s1; + +DROP VARIABLE tempvar; + +ROLLBACK TO s1; + +SELECT tempvar; + +COMMIT; + +-- should to fail +LET tempvar = 100; + +BEGIN; + +SAVEPOINT s1; + +CREATE TEMP VARIABLE tempvar AS INT ON COMMIT DROP; + +LET tempvar = 100; + +ROLLBACK TO s1; + +COMMIT; + +-- should to fail +LET tempvar = 100; + +CREATE VARIABLE var1 AS int; +LET var1 = 100; +BEGIN; +DROP VARIABLE var1; +ROLLBACK; +SELECT var1; + +DROP VARIABLE var1; + +CREATE VARIABLE var1 AS int DEFAULT 100; +COMMENT ON VARIABLE var1 IS 'some variable comment'; + +SELECT pg_catalog.obj_description(oid, 'pg_variable') FROM pg_variable WHERE varname = 'var1'; + +DROP VARIABLE var1; + +CREATE TABLE xxtab(avar int); + +CREATE TYPE xxtype AS (avar int); + +CREATE VARIABLE xxtab AS xxtype; + +INSERT INTO xxtab VALUES(10); + +-- it is ambiguous, but columns are preferred +-- variable is shadowed +SELECT xxtab.avar FROM xxtab; + +SET session_variables_ambiguity_warning TO on; + +SELECT xxtab.avar FROM xxtab; + +SET search_path = svartest; + +CREATE VARIABLE testvar as int; + +-- plpgsql variables are preferred against session variables +DO $$ +<<myblock>> +DECLARE testvar int; +BEGIN + -- should be ok without warning + LET testvar = 100; + -- should be ok without warning + testvar := 1000; + -- should be ok without warning + RAISE NOTICE 'session variable is %', svartest.testvar; + -- should be ok without warning + RAISE NOTICE 'plpgsql variable is %', myblock.testvar; + -- should to print plpgsql variable with warning + RAISE NOTICE 'variable is %', testvar; +END; +$$; + +DROP VARIABLE testvar; + +SET session_variables_ambiguity_warning TO default; + +-- should be ok +SELECT avar FROM xxtab; + +CREATE VARIABLE public.avar AS int; + +-- should be ok, see the table +SELECT avar FROM xxtab; + +-- should be ok +SELECT public.avar FROM xxtab; + +DROP VARIABLE xxtab; + +SELECT xxtab.avar FROM xxtab; + +DROP VARIABLE public.avar; + +DROP TYPE xxtype; + +DROP TABLE xxtab; + +-- test of plan cache invalidation +CREATE VARIABLE xx AS int; + +SET plan_cache_mode = force_generic_plan; + +PREPARE pp AS SELECT xx; + +EXECUTE pp; + +DROP VARIABLE xx; + +CREATE VARIABLE xx AS int; + +-- should to work +EXECUTE pp; + +DROP VARIABLE xx; + +DEALLOCATE pp; + +SET plan_cache_mode = DEFAULT; + +CREATE ROLE var_test_role; + +CREATE SCHEMA vartest; + +GRANT USAGE ON SCHEMA vartest TO var_test_role; + +CREATE VARIABLE vartest.x AS int; +CREATE VARIABLE vartest.y AS int; + +LET vartest.x = 100; +LET vartest.y = 101; + +GRANT SELECT ON ALL VARIABLES IN SCHEMA vartest TO var_test_role; + +SET ROLE TO var_test_role; + +SELECT vartest.x, vartest.y; + +SET ROLE TO DEFAULT; + +REVOKE SELECT ON ALL VARIABLES IN SCHEMA vartest FROM var_test_role; + +SET ROLE TO var_test_role; + +-- should to fail +SELECT vartest.x; +SELECT vartest.y; + +SET ROLE TO DEFAULT; + +DROP VARIABLE vartest.x, vartest.y; + +DROP SCHEMA vartest; + +DROP ROLE var_test_role; + +-- test cached plan +CREATE VARIABLE v1 AS text; +CREATE VARIABLE v2 AS int; +CREATE VARIABLE v3 AS int; + +LET v1 = 'test'; +LET v2 = 10; +LET v3 = 5; + +PREPARE q1 AS SELECT v1 || i FROM generate_series(1, v2) g(i) WHERE i IN (v2, v3); + +SET plan_cache_mode to force_generic_plan; + +EXECUTE q1; + +EXPLAIN EXECUTE q1; + +-- dependecy check +DROP VARIABLE v3; + +-- recreate v3 again +CREATE VARIABLE v3 AS int DEFAULT 6; + +-- should to work, the plan should be recreated +EXECUTE q1; + +DEALLOCATE q1; + +-- fill v1 by long text +LET v1 = repeat(' ', 10000); + +PREPARE q1 AS SELECT length(v1); + +EXECUTE q1; + +LET v1 = repeat(' ', 5000); + +EXECUTE q1; + +DEALLOCATE q1; + +SET plan_cache_mode to default; + +DROP VARIABLE v1, v2, v3; + +CREATE ROLE var_test_role; + +CREATE VARIABLE public.v1 AS int DEFAULT 0; + +-- check acl when variable is acessed by simple eval expr method +CREATE OR REPLACE FUNCTION public.fx_var(int) +RETURNS int AS $$ +DECLARE xx int; +BEGIN + xx := public.v1 + $1; + RETURN xx; +END; +$$ LANGUAGE plpgsql; + +-- should be ok +SELECT public.fx_var(0); + +SET ROLE TO var_test_role; + +-- should to fail +SELECT public.fx_var(0); + +SET ROLE TO default; + +GRANT SELECT ON VARIABLE public.v1 TO var_test_role; + +SET ROLE TO var_test_role; + +-- should be ok +SELECT public.fx_var(0); + +SET ROLE TO default; + +REVOKE SELECT ON VARIABLE public.v1 FROM var_test_role; + +SET ROLE TO var_test_role; + +-- should be fail +SELECT public.fx_var(0); + +SET ROLE TO DEFAULT; + +DROP FUNCTION public.fx_var(int); + +DROP VARIABLE public.v1; + +DROP ROLE var_test_role; + +CREATE TYPE public.svar_test_type AS (a int, b int, c numeric); + +CREATE VARIABLE public.svar AS public.svar_test_type; + +LET public.svar = ROW(10,20,30); + +SELECT public.svar; + +ALTER TYPE public.svar_test_type DROP ATTRIBUTE c; + +-- should be ok +SELECT public.svar; + +ALTER TYPE public.svar_test_type ADD ATTRIBUTE c int; + +-- should be ok +SELECT public.svar; + +LET public.svar = ROW(10,20,30); + +-- should be ok again for new value +SELECT public.svar; + +DROP VARIABLE public.svar; + +DROP TYPE public.svar_test_type; + +CREATE VARIABLE public.svar AS int; +select oid as varid from pg_variable where varname = 'svar' and varnamespace = 'public'::regnamespace \gset + +SELECT schema, name, removed FROM pg_debug_show_used_session_variables(); + +LET public.svar = 100; + +SELECT schema, name, removed FROM pg_debug_show_used_session_variables(); + +BEGIN; + +DROP VARIABLE public.svar; + +-- value should be in memory +SELECT schema, name, removed FROM pg_debug_show_used_session_variables(); + +ROLLBACK; + +-- value should be in memory +SELECT schema, name, removed FROM pg_debug_show_used_session_variables() f WHERE f.varid = :varid; + +SELECT public.svar; + +BEGIN; + +DROP VARIABLE public.svar; + +-- value should be in memory +SELECT schema, name, removed FROM pg_debug_show_used_session_variables() f WHERE f.varid = :varid;; + +COMMIT; + +-- the memory should be clean; +SELECT schema, name, removed FROM pg_debug_show_used_session_variables() WHERE f.varid = :varid; + +BEGIN; + +CREATE VARIABLE public.svar AS int; +select oid as varid from pg_variable where varname = 'svar' and varnamespace = 'public'::regnamespace \gset + + +LET public.svar = 100; + +ROLLBACK; + +-- the memory should be clean; +SELECT schema, name, removed FROM pg_debug_show_used_session_variables() f WHERE f.varid = :varid; + +\unset varid + +CREATE VARIABLE public.svar AS int; + +LET public.svar = 100; + +-- repeated aborted transaction +BEGIN; DROP VARIABLE public.svar; ROLLBACK; +BEGIN; DROP VARIABLE public.svar; ROLLBACK; +BEGIN; DROP VARIABLE public.svar; ROLLBACK; + +-- the value should be still available +SELECT public.svar; + +DROP VARIABLE public.svar; + +CREATE TYPE public.svar_test_type AS (a int, b int); + +CREATE VARIABLE public.svar AS public.svar_test_type; + +SELECT public.svar; + +ALTER TYPE public.svar_test_type ADD ATTRIBUTE c int; + +SELECT public.svar; + +ALTER TYPE public.svar_test_type DROP ATTRIBUTE b; + +SELECT public.svar; + +DROP VARIABLE public.svar; +DROP TYPE public.svar_test_type; + +CREATE TYPE public.svar_test_type AS (a int, b int); + +CREATE VARIABLE public.svar AS public.svar_test_type; +CREATE VARIABLE public.svar2 AS public.svar_test_type; + +LET public.svar = (10, 20); + +ALTER TYPE public.svar_test_type ADD ATTRIBUTE c int; + +SELECT public.svar; + +LET public.svar2 = (10, 20, 30); + +ALTER TYPE public.svar_test_type DROP ATTRIBUTE b; + +SELECT public.svar; +SELECT public.svar2; + +DROP VARIABLE public.svar; +DROP VARIABLE public.svar2; +DROP TYPE public.svar_test_type; + +-- The composite type cannot be changed when it is used +CREATE TYPE public.svar_type AS (a int, b int); + +CREATE VARIABLE public.svar AS public.svar_type; + +-- should to fail +ALTER TYPE public.svar_type ALTER ATTRIBUTE b TYPE numeric; + +DROP VARIABLE public.svar; + +CREATE TYPE public.svar_type2 AS (a int, b int, c public.svar_type); + +CREATE VARIABLE public.svar AS public.svar_type2; + +-- should to fail +ALTER TYPE public.svar_type ALTER ATTRIBUTE b TYPE numeric; + +DROP VARIABLE public.svar; +DROP TYPE public.svar_type2; +DROP TYPE public.svar_type; + +-- The variable can be shadowed by table or by alias +CREATE TYPE public.svar_type AS (a int, b int, c int); +CREATE VARIABLE public.svar AS public.svar_type; + +CREATE TABLE public.svar (a int, b int); + +INSERT INTO public.svar VALUES(10, 20); + +LET public.svar = (100, 200, 300); + +-- should be ok +-- show table +SELECT * FROM public.svar; +SELECT svar.a FROM public.svar; +SELECT svar.* FROM public.svar; + +-- show variable +SELECT public.svar; +SELECT public.svar.c; +SELECT (public.svar).*; + +-- the variable is shadowed, raise error +SELECT public.svar.c FROM public.svar; + +-- can be fixed by alias +SELECT public.svar.c FROM public.svar x; + +-- again with warnings +SET session_variables_ambiguity_warning TO on; + +SELECT * FROM public.svar; +SELECT svar.a FROM public.svar; +SELECT svar.* FROM public.svar; + +-- show variable +SELECT public.svar; +SELECT public.svar.c; +SELECT (public.svar).*; + +-- the variable is shadowed, raise error +SELECT public.svar.c FROM public.svar; + +-- can be fixed by alias +SELECT public.svar.c FROM public.svar x; + +SET session_variables_ambiguity_warning TO DEFAULT; + +DROP VARIABLE public.svar; +DROP TABLE public.svar; +DROP TYPE public.svar_type; -- 2.37.0 --z3ntqfnlkpftg4xg Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="v20220922-0011-FIXUP-regress-tests-for-session-variables.patch" ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v20220916 10/13] regress tests for session variables @ 2022-04-04 18:54 [email protected] <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: [email protected] @ 2022-04-04 18:54 UTC (permalink / raw) Checks of basic functionality, check of usage session variables in subtransactions and from PLpgSQL --- .../isolation/expected/session-variable.out | 86 ++ src/test/isolation/isolation_schedule | 1 + .../isolation/specs/session-variable.spec | 34 + .../regress/expected/session_variables.out | 1287 +++++++++++++++++ src/test/regress/parallel_schedule | 2 +- src/test/regress/sql/session_variables.sql | 959 ++++++++++++ 6 files changed, 2368 insertions(+), 1 deletion(-) create mode 100644 src/test/isolation/expected/session-variable.out create mode 100644 src/test/isolation/specs/session-variable.spec create mode 100644 src/test/regress/expected/session_variables.out create mode 100644 src/test/regress/sql/session_variables.sql diff --git a/src/test/isolation/expected/session-variable.out b/src/test/isolation/expected/session-variable.out new file mode 100644 index 0000000000..b0059910a1 --- /dev/null +++ b/src/test/isolation/expected/session-variable.out @@ -0,0 +1,86 @@ +Parsed test spec with 2 sessions + +starting permutation: let val drop val +step let: LET myvar = 'test'; +step val: SELECT myvar; +myvar +----- +test +(1 row) + +step drop: DROP VARIABLE myvar; +step val: SELECT myvar; +ERROR: column or variable "myvar" does not exist + +starting permutation: let val s1 drop val sr1 +step let: LET myvar = 'test'; +step val: SELECT myvar; +myvar +----- +test +(1 row) + +step s1: BEGIN; +step drop: DROP VARIABLE myvar; +step val: SELECT myvar; +ERROR: column or variable "myvar" does not exist +step sr1: ROLLBACK; + +starting permutation: let val dbg drop create dbg val +step let: LET myvar = 'test'; +step val: SELECT myvar; +myvar +----- +test +(1 row) + +step dbg: SELECT schema, name, removed FROM pg_debug_show_used_session_variables(); +schema|name |removed +------+-----+------- +public|myvar|f +(1 row) + +step drop: DROP VARIABLE myvar; +step create: CREATE VARIABLE myvar AS text +step dbg: SELECT schema, name, removed FROM pg_debug_show_used_session_variables(); +schema|name|removed +------+----+------- +(0 rows) + +step val: SELECT myvar; +myvar +----- + +(1 row) + + +starting permutation: let val s1 dbg drop create dbg val sr1 +step let: LET myvar = 'test'; +step val: SELECT myvar; +myvar +----- +test +(1 row) + +step s1: BEGIN; +step dbg: SELECT schema, name, removed FROM pg_debug_show_used_session_variables(); +schema|name |removed +------+-----+------- +public|myvar|f +(1 row) + +step drop: DROP VARIABLE myvar; +step create: CREATE VARIABLE myvar AS text +step dbg: SELECT schema, name, removed FROM pg_debug_show_used_session_variables(); +schema|name |removed +------+-----+------- +public|myvar|f +(1 row) + +step val: SELECT myvar; +myvar +----- + +(1 row) + +step sr1: ROLLBACK; diff --git a/src/test/isolation/isolation_schedule b/src/test/isolation/isolation_schedule index 5413a59a80..67837ef00f 100644 --- a/src/test/isolation/isolation_schedule +++ b/src/test/isolation/isolation_schedule @@ -108,3 +108,4 @@ test: cluster-conflict-partition test: truncate-conflict test: serializable-parallel test: serializable-parallel-2 +test: session-variable diff --git a/src/test/isolation/specs/session-variable.spec b/src/test/isolation/specs/session-variable.spec new file mode 100644 index 0000000000..fe47339110 --- /dev/null +++ b/src/test/isolation/specs/session-variable.spec @@ -0,0 +1,34 @@ +# Test session variables memory cleanup for sinval + +setup +{ + CREATE VARIABLE myvar AS text; +} + +teardown +{ + DROP VARIABLE IF EXISTS myvar; +} + +session s1 +step s1 { BEGIN; } +step let { LET myvar = 'test'; } +step val { SELECT myvar; } +step dbg { SELECT schema, name, removed FROM pg_debug_show_used_session_variables(); } +step sr1 { ROLLBACK; } + + +session s2 +step drop { DROP VARIABLE myvar; } +step create { CREATE VARIABLE myvar AS text } + +# Concurrent drop of a known variable should lead to an error +permutation let val drop val +# Same, but with an explicit transaction +permutation let val s1 drop val sr1 +# Concurrent drop/create of a known variable should lead to empty variable +permutation let val dbg drop create dbg val +# Concurrent drop/create of a known variable should lead to empty variable +# We need a transaction to make sure that we won't accept invalidation when +# calling the dbg step after the concurrent drop +permutation let val s1 dbg drop create dbg val sr1 diff --git a/src/test/regress/expected/session_variables.out b/src/test/regress/expected/session_variables.out new file mode 100644 index 0000000000..d411f0440d --- /dev/null +++ b/src/test/regress/expected/session_variables.out @@ -0,0 +1,1287 @@ +CREATE SCHEMA svartest; +SET search_path = svartest; +CREATE VARIABLE var1 AS integer; +CREATE TEMP VARIABLE var2 AS text; +DROP VARIABLE var1, var2; +-- functional interface +CREATE VARIABLE var1 AS numeric; +CREATE ROLE var_test_role; +GRANT USAGE ON SCHEMA svartest TO var_test_role; +SET ROLE TO var_test_role; +-- should fail +SELECT var1; +ERROR: permission denied for session variable var1 +SET ROLE TO DEFAULT; +GRANT SELECT ON VARIABLE var1 TO var_test_role; +SET ROLE TO var_test_role; +-- should fail +LET var1 = 10; +ERROR: permission denied for session variable var1 +-- should work +SELECT var1; + var1 +------ + +(1 row) + +SET ROLE TO DEFAULT; +GRANT UPDATE ON VARIABLE var1 TO var_test_role; +SET ROLE TO var_test_role; +-- should work +LET var1 = 333; +SET ROLE TO DEFAULT; +REVOKE ALL ON VARIABLE var1 FROM var_test_role; +CREATE OR REPLACE FUNCTION secure_var() +RETURNS int AS $$ + SELECT svartest.var1::int; +$$ LANGUAGE sql SECURITY DEFINER; +SELECT secure_var(); + secure_var +------------ + 333 +(1 row) + +SET ROLE TO var_test_role; +-- should fail +SELECT svartest.var1; +ERROR: permission denied for session variable var1 +-- should work; +SELECT secure_var(); + secure_var +------------ + 333 +(1 row) + +SET ROLE TO DEFAULT; +EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM generate_series(1,100) g(v) WHERE v = var1; + QUERY PLAN +----------------------------------------------- + Function Scan on pg_catalog.generate_series g + Output: v + Function Call: generate_series(1, 100) + Filter: ((g.v)::numeric = var1) +(4 rows) + +CREATE VIEW schema_var_view AS SELECT var1; +SELECT * FROM schema_var_view; + var1 +------ + 333 +(1 row) + +\c - +SET search_path = svartest; +-- should work still, but var will be empty +SELECT * FROM schema_var_view; + var1 +------ + +(1 row) + +LET var1 = pi(); +SELECT var1; + var1 +------------------ + 3.14159265358979 +(1 row) + +-- we can see execution plan of LET statement +EXPLAIN (VERBOSE, COSTS OFF) LET var1 = pi(); + QUERY PLAN +---------------------------- + SET SESSION VARIABLE + Result + Output: 3.14159265358979 +(3 rows) + +SELECT var1; + var1 +------------------ + 3.14159265358979 +(1 row) + +CREATE VARIABLE var3 AS int; +CREATE OR REPLACE FUNCTION inc(int) +RETURNS int AS $$ +BEGIN + LET svartest.var3 = COALESCE(svartest.var3 + $1, $1); + RETURN var3; +END; +$$ LANGUAGE plpgsql; +SELECT inc(1); + inc +----- + 1 +(1 row) + +SELECT inc(1); + inc +----- + 2 +(1 row) + +SELECT inc(1); + inc +----- + 3 +(1 row) + +SELECT inc(1) FROM generate_series(1,10); + inc +----- + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 +(10 rows) + +SET ROLE TO var_test_role; +-- should fail +LET var3 = 0; +ERROR: permission denied for session variable var3 +SET ROLE TO DEFAULT; +DROP VIEW schema_var_view; +DROP VARIABLE var1 CASCADE; +DROP VARIABLE var3 CASCADE; +-- composite variables +CREATE TYPE sv_xyz AS (x int, y int, z numeric(10,2)); +CREATE VARIABLE v1 AS sv_xyz; +CREATE VARIABLE v2 AS sv_xyz; +\d v1 +\d v2 +LET v1 = (1,2,3.14); +LET v2 = (10,20,3.14*10); +-- should work too - there are prepared casts +LET v1 = (1,2,3.14); +SELECT v1; + v1 +------------ + (1,2,3.14) +(1 row) + +SELECT v2; + v2 +--------------- + (10,20,31.40) +(1 row) + +SELECT (v1).*; + x | y | z +---+---+------ + 1 | 2 | 3.14 +(1 row) + +SELECT (v2).*; + x | y | z +----+----+------- + 10 | 20 | 31.40 +(1 row) + +SELECT v1.x + v1.z; + ?column? +---------- + 4.14 +(1 row) + +SELECT v2.x + v2.z; + ?column? +---------- + 41.40 +(1 row) + +-- access to composite fields should be safe too +-- should fail +SET ROLE TO var_test_role; +SELECT v2.x; +ERROR: permission denied for session variable v2 +SET ROLE TO DEFAULT; +DROP VARIABLE v1; +DROP VARIABLE v2; +REVOKE USAGE ON SCHEMA svartest FROM var_test_role; +DROP ROLE var_test_role; +-- scalar variables should not be in conflict with qualified column +CREATE VARIABLE varx AS text; +SELECT varx.relname FROM pg_class varx WHERE varx.relname = 'pg_class'; + relname +---------- + pg_class +(1 row) + +-- should fail +SELECT varx.xxx; +ERROR: type text is not composite +-- variables can be updated under RO transaction +BEGIN; +SET TRANSACTION READ ONLY; +LET varx = 'hello'; +COMMIT; +SELECT varx; + varx +------- + hello +(1 row) + +DROP VARIABLE varx; +CREATE TYPE t1 AS (a int, b numeric, c text); +CREATE VARIABLE v1 AS t1; +LET v1 = (1, pi(), 'hello'); +SELECT v1; + v1 +---------------------------- + (1,3.14159265358979,hello) +(1 row) + +LET v1.b = 10.2222; +SELECT v1; + v1 +------------------- + (1,10.2222,hello) +(1 row) + +-- should fail +LET v1.x = 10; +ERROR: cannot assign to field "x" of column "v1" because there is no such column in data type t1 +LINE 1: LET v1.x = 10; + ^ +DROP VARIABLE v1; +DROP TYPE t1; +-- arrays are supported +CREATE VARIABLE va1 AS numeric[]; +LET va1 = ARRAY[1.1,2.1]; +LET va1[1] = 10.1; +SELECT va1; + va1 +------------ + {10.1,2.1} +(1 row) + +CREATE TYPE ta2 AS (a numeric, b numeric[]); +CREATE VARIABLE va2 AS ta2; +LET va2 = (10.1, ARRAY[0.0, 0.0]); +LET va2.a = 10.2; +SELECT va2; + va2 +-------------------- + (10.2,"{0.0,0.0}") +(1 row) + +LET va2.b[1] = 10.3; +SELECT va2; + va2 +--------------------- + (10.2,"{10.3,0.0}") +(1 row) + +DROP VARIABLE va1; +DROP VARIABLE va2; +DROP TYPE ta2; +-- default values +CREATE VARIABLE v1 AS numeric DEFAULT pi(); +LET v1 = v1 * 2; +SELECT v1; + v1 +------------------ + 6.28318530717958 +(1 row) + +CREATE TYPE t2 AS (a numeric, b text); +CREATE VARIABLE v2 AS t2 DEFAULT (NULL, 'Hello'); +LET svartest.v2.a = pi(); +SELECT v2; + v2 +-------------------------- + (3.14159265358979,Hello) +(1 row) + +-- should fail due dependency +DROP TYPE t2; +ERROR: cannot drop type t2 because other objects depend on it +DETAIL: session variable v2 depends on type t2 +HINT: Use DROP ... CASCADE to drop the dependent objects too. +-- should be ok +DROP VARIABLE v1; +DROP VARIABLE v2; +-- tests of alters +CREATE SCHEMA var_schema1; +CREATE SCHEMA var_schema2; +CREATE VARIABLE var_schema1.var1 AS integer; +LET var_schema1.var1 = 1000; +SELECT var_schema1.var1; + var1 +------ + 1000 +(1 row) + +ALTER VARIABLE var_schema1.var1 SET SCHEMA var_schema2; +SELECT var_schema2.var1; + var1 +------ + 1000 +(1 row) + +CREATE ROLE var_test_role; +ALTER VARIABLE var_schema2.var1 OWNER TO var_test_role; +SET ROLE TO var_test_role; +-- should fail, no access to schema var_schema2.var +SELECT var_schema2.var1; +ERROR: permission denied for schema var_schema2 +DROP VARIABLE var_schema2.var1; +ERROR: permission denied for schema var_schema2 +SET ROLE TO DEFAULT; +ALTER VARIABLE var_schema2.var1 SET SCHEMA public; +SET ROLE TO var_test_role; +SELECT public.var1; + var1 +------ + 1000 +(1 row) + +ALTER VARIABLE public.var1 RENAME TO var1_renamed; +SELECT public.var1_renamed; + var1_renamed +-------------- + 1000 +(1 row) + +DROP VARIABLE public.var1_renamed; +SET ROLE TO DEFAULt; +-- default rights test +ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON VARIABLES TO var_test_role; +CREATE VARIABLE public.var2 AS int; +SET ROLE TO var_test_role; +-- should be ok +LET public.var2 = 100; +SELECT public.var2; + var2 +------ + 100 +(1 row) + +SET ROLE TO DEFAULt; +DROP VARIABLE public.var2; +DROP OWNED BY var_test_role; +DROP ROLE var_test_role; +CREATE VARIABLE xx AS text DEFAULT 'hello'; +SELECT xx, upper(xx); + xx | upper +-------+------- + hello | HELLO +(1 row) + +LET xx = 'Hi'; +SELECT xx; + xx +---- + Hi +(1 row) + +DROP VARIABLE xx; +-- ON TRANSACTION END RESET tests +CREATE VARIABLE t1 AS int DEFAULT -1 ON TRANSACTION END RESET; +BEGIN; + SELECT t1; + t1 +---- + -1 +(1 row) + + LET t1 = 100; + SELECT t1; + t1 +----- + 100 +(1 row) + +COMMIT; +SELECT t1; + t1 +---- + -1 +(1 row) + +BEGIN; + SELECT t1; + t1 +---- + -1 +(1 row) + + LET t1 = 100; + SELECT t1; + t1 +----- + 100 +(1 row) + +ROLLBACK; +SELECT t1; + t1 +---- + -1 +(1 row) + +DROP VARIABLE t1; +CREATE VARIABLE v1 AS int DEFAULT 0; +CREATE VARIABLE v2 AS text DEFAULT 'none'; +LET v1 = 100; +LET v2 = 'Hello'; +SELECT v1, v2; + v1 | v2 +-----+------- + 100 | Hello +(1 row) + +LET v1 = DEFAULT; +LET v2 = DEFAULT; +SELECT v1, v2; + v1 | v2 +----+------ + 0 | none +(1 row) + +DROP VARIABLE v1; +DROP VARIABLE v2; +-- ON COMMIT DROP tests +-- should be 0 always +SELECT count(*) FROM pg_variable; + count +------- + 0 +(1 row) + +CREATE TEMP VARIABLE g AS int ON COMMIT DROP; +SELECT count(*) FROM pg_variable; + count +------- + 0 +(1 row) + +BEGIN; + CREATE TEMP VARIABLE g AS int ON COMMIT DROP; +COMMIT; +SELECT count(*) FROM pg_variable; + count +------- + 0 +(1 row) + +BEGIN; + CREATE TEMP VARIABLE g AS int ON COMMIT DROP; +ROLLBACK; +SELECT count(*) FROM pg_variable; + count +------- + 0 +(1 row) + +-- Encourage use of parallel plans +SET parallel_setup_cost = 0; +SET parallel_tuple_cost = 0; +SET min_parallel_table_scan_size = 0; +SET max_parallel_workers_per_gather = 2; +-- test on query with workers +CREATE TABLE svar_test(a int); +INSERT INTO svar_test SELECT * FROM generate_series(1,1000); +ANALYZE svar_test; +CREATE VARIABLE zero int; +LET zero = 0; +-- parallel workers should be used +EXPLAIN (costs off) SELECT count(*) FROM svar_test WHERE a%10 = zero; + QUERY PLAN +-------------------------------------------- + Aggregate + -> Gather + Workers Planned: 2 + -> Parallel Seq Scan on svar_test + Filter: ((a % 10) = zero) +(5 rows) + +-- result should be 100 +SELECT count(*) FROM svar_test WHERE a%10 = zero; + count +------- + 100 +(1 row) + +LET zero = (SELECT count(*) FROM svar_test); +-- result should be 1000 +SELECT zero; + zero +------ + 1000 +(1 row) + +-- parallel workers should be used +EXPLAIN (costs off) LET zero = (SELECT count(*) FROM svar_test); + QUERY PLAN +---------------------------------------------------------- + SET SESSION VARIABLE + Result + InitPlan 1 (returns $1) + -> Finalize Aggregate + -> Gather + Workers Planned: 2 + -> Partial Aggregate + -> Parallel Seq Scan on svar_test +(8 rows) + +-- test for dependency on relation +CREATE VARIABLE v_table AS svar_test; +ALTER TABLE svar_test ALTER COLUMN a TYPE text; +ERROR: cannot alter table "svar_test" because session variable "svartest.v_table" uses it +DROP VARIABLE v_table; +DROP TABLE svar_test; +DROP VARIABLE zero; +RESET parallel_setup_cost; +RESET parallel_tuple_cost; +RESET min_parallel_table_scan_size; +RESET max_parallel_workers_per_gather; +-- use variables in prepared statements +CREATE VARIABLE v AS numeric; +LET v = 3.14; +-- use variables in views +CREATE VIEW vv AS SELECT COALESCE(v, 0) + 1000 AS result; +SELECT * FROM vv; + result +--------- + 1003.14 +(1 row) + +-- start a new session +\c +SET search_path to svartest; +SELECT * FROM vv; + result +-------- + 1000 +(1 row) + +LET v = 3.14; +SELECT * FROM vv; + result +--------- + 1003.14 +(1 row) + +-- should fail, dependency +DROP VARIABLE v; +ERROR: cannot drop session variable v because other objects depend on it +DETAIL: view vv depends on session variable v +HINT: Use DROP ... CASCADE to drop the dependent objects too. +-- should be ok +DROP VARIABLE v CASCADE; +NOTICE: drop cascades to view vv +-- other features +CREATE VARIABLE dt AS integer DEFAULT 0; +LET dt = 100; +SELECT dt; + dt +----- + 100 +(1 row) + +DISCARD VARIABLES; +SELECT dt; + dt +---- + 0 +(1 row) + +DROP VARIABLE dt; +-- NOT NULL +CREATE VARIABLE v1 AS int NOT NULL; +CREATE VARIABLE v2 AS int NOT NULL DEFAULT NULL; +-- should fail +SELECT v1; +ERROR: null value is not allowed for NOT NULL session variable "svartest.v1" +DETAIL: The session variable was not initialized yet. +SELECT v2; +ERROR: null value is not allowed for NOT NULL session variable "svartest.v2" +LET v1 = NULL; +ERROR: null value is not allowed for NOT NULL session variable "svartest.v1" +LET v2 = NULL; +ERROR: null value is not allowed for NOT NULL session variable "svartest.v2" +LET v1 = DEFAULT; +ERROR: null value is not allowed for NOT NULL session variable "svartest.v1" +LET v2 = DEFAULT; +ERROR: null value is not allowed for NOT NULL session variable "svartest.v2" +-- should be ok +LET v1 = 100; +LET v2 = 1000; +SELECT v1, v2; + v1 | v2 +-----+------ + 100 | 1000 +(1 row) + +DROP VARIABLE v1; +DROP VARIABLE v2; +CREATE VARIABLE tv AS int; +CREATE VARIABLE IF NOT EXISTS tv AS int; +NOTICE: session variable "tv" already exists, skipping +DROP VARIABLE tv; +CREATE IMMUTABLE VARIABLE iv AS int DEFAULT 100; +SELECT iv; + iv +----- + 100 +(1 row) + +-- should fail; +LET iv = 10000; +ERROR: session variable "svartest.iv" is declared IMMUTABLE +DROP VARIABLE iv; +-- different order +CREATE IMMUTABLE VARIABLE iv AS int DEFAULT 100; +-- should to fail +LET iv = 10000; +ERROR: session variable "svartest.iv" is declared IMMUTABLE +-- should be ok +SELECT iv; + iv +----- + 100 +(1 row) + +DROP VARIABLE iv; +CREATE IMMUTABLE VARIABLE iv AS int; +-- should be ok +LET iv = NULL; +-- should fail +LET iv = NULL; +ERROR: session variable "svartest.iv" is declared IMMUTABLE +DROP VARIABLE iv; +-- create variable inside plpgsql block +DO $$ +BEGIN + CREATE VARIABLE do_test_svar AS date DEFAULT '2000-01-01'; +END; +$$; +SELECT do_test_svar; + do_test_svar +-------------- + 01-01-2000 +(1 row) + +DROP VARIABLE do_test_svar; +-- should fail +CREATE IMMUTABLE VARIABLE xx AS int NOT NULL; +ERROR: IMMUTABLE NOT NULL variable requires default expression +-- REASSIGN OWNED test +CREATE ROLE var_test_role1; +CREATE ROLE var_test_role2; +CREATE VARIABLE xxx_var AS int; +ALTER VARIABLE xxx_var OWNER TO var_test_role1; +REASSIGN OWNED BY var_test_role1 to var_test_role2; +SELECT varowner::regrole FROM pg_variable WHERE varname = 'xxx_var'; + varowner +---------------- + var_test_role2 +(1 row) + +DROP OWNED BY var_test_role1; +DROP ROLE var_test_role1; +SELECT count(*) FROM pg_variable WHERE varname = 'xxx_var'; + count +------- + 1 +(1 row) + +DROP OWNED BY var_test_role2; +DROP ROLE var_test_role2; +SELECT count(*) FROM pg_variable WHERE varname = 'xxx_var'; + count +------- + 0 +(1 row) + +-- creating, dropping temporary variable +BEGIN; +CREATE TEMP VARIABLE tempvar AS INT ON COMMIT DROP; +LET tempvar = 100; +SAVEPOINT s1; +DROP VARIABLE tempvar; +ROLLBACK TO s1; +SELECT tempvar; + tempvar +--------- + 100 +(1 row) + +COMMIT; +-- should to fail +LET tempvar = 100; +ERROR: session variable "tempvar" doesn't exist +LINE 1: LET tempvar = 100; + ^ +BEGIN; +SAVEPOINT s1; +CREATE TEMP VARIABLE tempvar AS INT ON COMMIT DROP; +LET tempvar = 100; +ROLLBACK TO s1; +COMMIT; +-- should to fail +LET tempvar = 100; +ERROR: session variable "tempvar" doesn't exist +LINE 1: LET tempvar = 100; + ^ +CREATE VARIABLE var1 AS int; +LET var1 = 100; +BEGIN; +DROP VARIABLE var1; +ROLLBACK; +SELECT var1; + var1 +------ + 100 +(1 row) + +DROP VARIABLE var1; +CREATE VARIABLE var1 AS int DEFAULT 100; +COMMENT ON VARIABLE var1 IS 'some variable comment'; +SELECT pg_catalog.obj_description(oid, 'pg_variable') FROM pg_variable WHERE varname = 'var1'; + obj_description +----------------------- + some variable comment +(1 row) + +DROP VARIABLE var1; +CREATE TABLE xxtab(avar int); +CREATE TYPE xxtype AS (avar int); +CREATE VARIABLE xxtab AS xxtype; +INSERT INTO xxtab VALUES(10); +-- it is ambiguous, but columns are preferred +-- variable is shadowed +SELECT xxtab.avar FROM xxtab; + avar +------ + 10 +(1 row) + +SET session_variables_ambiguity_warning TO on; +SELECT xxtab.avar FROM xxtab; +WARNING: session variable "xxtab.avar" is shadowed +LINE 1: SELECT xxtab.avar FROM xxtab; + ^ +DETAIL: Session variables can be shadowed by columns, routine's variables and routine's arguments with the same name. + avar +------ + 10 +(1 row) + +SET search_path = svartest; +CREATE VARIABLE testvar as int; +-- plpgsql variables are preferred against session variables +DO $$ +<<myblock>> +DECLARE testvar int; +BEGIN + -- should be ok without warning + LET testvar = 100; + -- should be ok without warning + testvar := 1000; + -- should be ok without warning + RAISE NOTICE 'session variable is %', svartest.testvar; + -- should be ok without warning + RAISE NOTICE 'plpgsql variable is %', myblock.testvar; + -- should to print plpgsql variable with warning + RAISE NOTICE 'variable is %', testvar; +END; +$$; +WARNING: session variable "testvar" is shadowed +LINE 1: testvar := 1000 + ^ +DETAIL: Session variables can be shadowed by columns, routine's variables and routine's arguments with the same name. +QUERY: testvar := 1000 +NOTICE: session variable is 100 +NOTICE: plpgsql variable is 1000 +WARNING: session variable "testvar" is shadowed +LINE 1: testvar + ^ +DETAIL: Session variables can be shadowed by columns, routine's variables and routine's arguments with the same name. +QUERY: testvar +NOTICE: variable is 1000 +DROP VARIABLE testvar; +SET session_variables_ambiguity_warning TO default; +-- should be ok +SELECT avar FROM xxtab; + avar +------ + 10 +(1 row) + +CREATE VARIABLE public.avar AS int; +-- should be ok, see the table +SELECT avar FROM xxtab; + avar +------ + 10 +(1 row) + +-- should be ok +SELECT public.avar FROM xxtab; + avar +------ + +(1 row) + +DROP VARIABLE xxtab; +SELECT xxtab.avar FROM xxtab; + avar +------ + 10 +(1 row) + +DROP VARIABLE public.avar; +DROP TYPE xxtype; +DROP TABLE xxtab; +-- test of plan cache invalidation +CREATE VARIABLE xx AS int; +SET plan_cache_mode = force_generic_plan; +PREPARE pp AS SELECT xx; +EXECUTE pp; + xx +---- + +(1 row) + +DROP VARIABLE xx; +CREATE VARIABLE xx AS int; +-- should to work +EXECUTE pp; + xx +---- + +(1 row) + +DROP VARIABLE xx; +DEALLOCATE pp; +SET plan_cache_mode = DEFAULT; +CREATE ROLE var_test_role; +CREATE SCHEMA vartest; +GRANT USAGE ON SCHEMA vartest TO var_test_role; +CREATE VARIABLE vartest.x AS int; +CREATE VARIABLE vartest.y AS int; +LET vartest.x = 100; +LET vartest.y = 101; +GRANT SELECT ON ALL VARIABLES IN SCHEMA vartest TO var_test_role; +SET ROLE TO var_test_role; +SELECT vartest.x, vartest.y; + x | y +-----+----- + 100 | 101 +(1 row) + +SET ROLE TO DEFAULT; +REVOKE SELECT ON ALL VARIABLES IN SCHEMA vartest FROM var_test_role; +SET ROLE TO var_test_role; +-- should to fail +SELECT vartest.x; +ERROR: permission denied for session variable x +SELECT vartest.y; +ERROR: permission denied for session variable y +SET ROLE TO DEFAULT; +DROP VARIABLE vartest.x, vartest.y; +DROP SCHEMA vartest; +DROP ROLE var_test_role; +-- test cached plan +CREATE VARIABLE v1 AS text; +CREATE VARIABLE v2 AS int; +CREATE VARIABLE v3 AS int; +LET v1 = 'test'; +LET v2 = 10; +LET v3 = 5; +PREPARE q1 AS SELECT v1 || i FROM generate_series(1, v2) g(i) WHERE i IN (v2, v3); +SET plan_cache_mode to force_generic_plan; +EXECUTE q1; + ?column? +---------- + test5 + test10 +(2 rows) + +EXPLAIN EXECUTE q1; + QUERY PLAN +----------------------------------------------------------------------- + Function Scan on generate_series g (cost=0.00..0.14 rows=2 width=32) + Filter: (i = ANY (ARRAY[v2, v3])) +(2 rows) + +-- dependecy check +DROP VARIABLE v3; +-- recreate v3 again +CREATE VARIABLE v3 AS int DEFAULT 6; +-- should to work, the plan should be recreated +EXECUTE q1; + ?column? +---------- + test6 + test10 +(2 rows) + +DEALLOCATE q1; +-- fill v1 by long text +LET v1 = repeat(' ', 10000); +PREPARE q1 AS SELECT length(v1); +EXECUTE q1; + length +-------- + 10000 +(1 row) + +LET v1 = repeat(' ', 5000); +EXECUTE q1; + length +-------- + 5000 +(1 row) + +DEALLOCATE q1; +SET plan_cache_mode to default; +DROP VARIABLE v1, v2, v3; +CREATE ROLE var_test_role; +CREATE VARIABLE public.v1 AS int DEFAULT 0; +-- check acl when variable is acessed by simple eval expr method +CREATE OR REPLACE FUNCTION public.fx_var(int) +RETURNS int AS $$ +DECLARE xx int; +BEGIN + xx := public.v1 + $1; + RETURN xx; +END; +$$ LANGUAGE plpgsql; +-- should be ok +SELECT public.fx_var(0); + fx_var +-------- + 0 +(1 row) + +SET ROLE TO var_test_role; +-- should to fail +SELECT public.fx_var(0); +ERROR: permission denied for session variable v1 +CONTEXT: PL/pgSQL function public.fx_var(integer) line 4 at assignment +SET ROLE TO default; +GRANT SELECT ON VARIABLE public.v1 TO var_test_role; +SET ROLE TO var_test_role; +-- should be ok +SELECT public.fx_var(0); + fx_var +-------- + 0 +(1 row) + +SET ROLE TO default; +REVOKE SELECT ON VARIABLE public.v1 FROM var_test_role; +SET ROLE TO var_test_role; +-- should be fail +SELECT public.fx_var(0); +ERROR: permission denied for session variable v1 +CONTEXT: PL/pgSQL function public.fx_var(integer) line 4 at assignment +SET ROLE TO DEFAULT; +DROP FUNCTION public.fx_var(int); +DROP VARIABLE public.v1; +DROP ROLE var_test_role; +CREATE TYPE public.svar_test_type AS (a int, b int, c numeric); +CREATE VARIABLE public.svar AS public.svar_test_type; +LET public.svar = ROW(10,20,30); +SELECT public.svar; + svar +------------ + (10,20,30) +(1 row) + +ALTER TYPE public.svar_test_type DROP ATTRIBUTE c; +-- should be ok +SELECT public.svar; + svar +--------- + (10,20) +(1 row) + +ALTER TYPE public.svar_test_type ADD ATTRIBUTE c int; +-- should be ok +SELECT public.svar; + svar +---------- + (10,20,) +(1 row) + +LET public.svar = ROW(10,20,30); +-- should be ok again for new value +SELECT public.svar; + svar +------------ + (10,20,30) +(1 row) + +DROP VARIABLE public.svar; +DROP TYPE public.svar_test_type; +CREATE VARIABLE public.svar AS int; +select oid as varid from pg_variable where varname = 'svar' and varnamespace = 'public'::regnamespace \gset +SELECT schema, name, removed FROM pg_debug_show_used_session_variables(); + schema | name | removed +--------+------+--------- +(0 rows) + +LET public.svar = 100; +SELECT schema, name, removed FROM pg_debug_show_used_session_variables(); + schema | name | removed +--------+------+--------- + public | svar | f +(1 row) + +BEGIN; +DROP VARIABLE public.svar; +-- value should be in memory +SELECT schema, name, removed FROM pg_debug_show_used_session_variables(); + schema | name | removed +--------+------+--------- + | | t +(1 row) + +ROLLBACK; +-- value should be in memory +SELECT schema, name, removed FROM pg_debug_show_used_session_variables() f WHERE f.varid = :varid; + schema | name | removed +--------+------+--------- + public | svar | f +(1 row) + +SELECT public.svar; + svar +------ + 100 +(1 row) + +BEGIN; +DROP VARIABLE public.svar; +-- value should be in memory +SELECT schema, name, removed FROM pg_debug_show_used_session_variables() f WHERE f.varid = :varid;; + schema | name | removed +--------+------+--------- + | | t +(1 row) + +COMMIT; +-- the memory should be clean; +SELECT schema, name, removed FROM pg_debug_show_used_session_variables() WHERE f.varid = :varid; +ERROR: missing FROM-clause entry for table "f" +LINE 1: ...FROM pg_debug_show_used_session_variables() WHERE f.varid = ... + ^ +BEGIN; +CREATE VARIABLE public.svar AS int; +select oid as varid from pg_variable where varname = 'svar' and varnamespace = 'public'::regnamespace \gset +LET public.svar = 100; +ROLLBACK; +-- the memory should be clean; +SELECT schema, name, removed FROM pg_debug_show_used_session_variables() f WHERE f.varid = :varid; + schema | name | removed +--------+------+--------- +(0 rows) + +\unset varid +CREATE VARIABLE public.svar AS int; +LET public.svar = 100; +-- repeated aborted transaction +BEGIN; DROP VARIABLE public.svar; ROLLBACK; +BEGIN; DROP VARIABLE public.svar; ROLLBACK; +BEGIN; DROP VARIABLE public.svar; ROLLBACK; +-- the value should be still available +SELECT public.svar; + svar +------ + 100 +(1 row) + +DROP VARIABLE public.svar; +CREATE TYPE public.svar_test_type AS (a int, b int); +CREATE VARIABLE public.svar AS public.svar_test_type; +SELECT public.svar; + svar +------ + +(1 row) + +ALTER TYPE public.svar_test_type ADD ATTRIBUTE c int; +SELECT public.svar; + svar +------ + +(1 row) + +ALTER TYPE public.svar_test_type DROP ATTRIBUTE b; +SELECT public.svar; + svar +------ + +(1 row) + +DROP VARIABLE public.svar; +DROP TYPE public.svar_test_type; +CREATE TYPE public.svar_test_type AS (a int, b int); +CREATE VARIABLE public.svar AS public.svar_test_type; +CREATE VARIABLE public.svar2 AS public.svar_test_type; +LET public.svar = (10, 20); +ALTER TYPE public.svar_test_type ADD ATTRIBUTE c int; +SELECT public.svar; + svar +---------- + (10,20,) +(1 row) + +LET public.svar2 = (10, 20, 30); +ALTER TYPE public.svar_test_type DROP ATTRIBUTE b; +SELECT public.svar; + svar +------- + (10,) +(1 row) + +SELECT public.svar2; + svar2 +--------- + (10,30) +(1 row) + +DROP VARIABLE public.svar; +DROP VARIABLE public.svar2; +DROP TYPE public.svar_test_type; +-- The composite type cannot be changed when it is used +CREATE TYPE public.svar_type AS (a int, b int); +CREATE VARIABLE public.svar AS public.svar_type; +-- should to fail +ALTER TYPE public.svar_type ALTER ATTRIBUTE b TYPE numeric; +ERROR: cannot alter type "svar_type" because session variable "public.svar" uses it +DROP VARIABLE public.svar; +CREATE TYPE public.svar_type2 AS (a int, b int, c public.svar_type); +CREATE VARIABLE public.svar AS public.svar_type2; +-- should to fail +ALTER TYPE public.svar_type ALTER ATTRIBUTE b TYPE numeric; +ERROR: cannot alter type "svar_type" because session variable "public.svar" uses it +DROP VARIABLE public.svar; +DROP TYPE public.svar_type2; +DROP TYPE public.svar_type; +-- The variable can be shadowed by table or by alias +CREATE TYPE public.svar_type AS (a int, b int, c int); +CREATE VARIABLE public.svar AS public.svar_type; +CREATE TABLE public.svar (a int, b int); +INSERT INTO public.svar VALUES(10, 20); +LET public.svar = (100, 200, 300); +-- should be ok +-- show table +SELECT * FROM public.svar; + a | b +----+---- + 10 | 20 +(1 row) + +SELECT svar.a FROM public.svar; + a +---- + 10 +(1 row) + +SELECT svar.* FROM public.svar; + a | b +----+---- + 10 | 20 +(1 row) + +-- show variable +SELECT public.svar; + svar +--------------- + (100,200,300) +(1 row) + +SELECT public.svar.c; + c +----- + 300 +(1 row) + +SELECT (public.svar).*; + a | b | c +-----+-----+----- + 100 | 200 | 300 +(1 row) + +-- the variable is shadowed, raise error +SELECT public.svar.c FROM public.svar; +ERROR: column svar.c does not exist +LINE 1: SELECT public.svar.c FROM public.svar; + ^ +-- can be fixed by alias +SELECT public.svar.c FROM public.svar x; + c +----- + 300 +(1 row) + +-- again with warnings +SET session_variables_ambiguity_warning TO on; +SELECT * FROM public.svar; + a | b +----+---- + 10 | 20 +(1 row) + +SELECT svar.a FROM public.svar; + a +---- + 10 +(1 row) + +SELECT svar.* FROM public.svar; + a | b +----+---- + 10 | 20 +(1 row) + +-- show variable +SELECT public.svar; + svar +--------------- + (100,200,300) +(1 row) + +SELECT public.svar.c; + c +----- + 300 +(1 row) + +SELECT (public.svar).*; + a | b | c +-----+-----+----- + 100 | 200 | 300 +(1 row) + +-- the variable is shadowed, raise error +SELECT public.svar.c FROM public.svar; +WARNING: session variable "public.svar" is shadowed +LINE 1: SELECT public.svar.c FROM public.svar; + ^ +DETAIL: Session variables can be shadowed by tables or table's aliases with the same name. +ERROR: column svar.c does not exist +LINE 1: SELECT public.svar.c FROM public.svar; + ^ +-- can be fixed by alias +SELECT public.svar.c FROM public.svar x; + c +----- + 300 +(1 row) + +SET session_variables_ambiguity_warning TO DEFAULT; +DROP VARIABLE public.svar; +DROP TABLE public.svar; +DROP TYPE public.svar_type; diff --git a/src/test/regress/parallel_schedule b/src/test/regress/parallel_schedule index 9f644a0c1b..7426b39ab3 100644 --- a/src/test/regress/parallel_schedule +++ b/src/test/regress/parallel_schedule @@ -119,7 +119,7 @@ test: json jsonb json_encoding jsonpath jsonpath_encoding jsonb_jsonpath # NB: temp.sql does a reconnect which transiently uses 2 connections, # so keep this parallel group to at most 19 tests # ---------- -test: plancache limit plpgsql copy2 temp domain rangefuncs prepare conversion truncate alter_table sequence polymorphism rowtypes returning largeobject with xml +test: plancache limit plpgsql copy2 temp domain rangefuncs prepare conversion truncate alter_table sequence polymorphism rowtypes returning largeobject with xml session_variables # ---------- # Another group of parallel tests diff --git a/src/test/regress/sql/session_variables.sql b/src/test/regress/sql/session_variables.sql new file mode 100644 index 0000000000..d32bb5b042 --- /dev/null +++ b/src/test/regress/sql/session_variables.sql @@ -0,0 +1,959 @@ +CREATE SCHEMA svartest; + +SET search_path = svartest; + +CREATE VARIABLE var1 AS integer; +CREATE TEMP VARIABLE var2 AS text; + +DROP VARIABLE var1, var2; + +-- functional interface +CREATE VARIABLE var1 AS numeric; + +CREATE ROLE var_test_role; +GRANT USAGE ON SCHEMA svartest TO var_test_role; + +SET ROLE TO var_test_role; + +-- should fail +SELECT var1; + +SET ROLE TO DEFAULT; + +GRANT SELECT ON VARIABLE var1 TO var_test_role; + +SET ROLE TO var_test_role; +-- should fail +LET var1 = 10; +-- should work +SELECT var1; + +SET ROLE TO DEFAULT; + +GRANT UPDATE ON VARIABLE var1 TO var_test_role; + +SET ROLE TO var_test_role; + +-- should work +LET var1 = 333; + +SET ROLE TO DEFAULT; + +REVOKE ALL ON VARIABLE var1 FROM var_test_role; + +CREATE OR REPLACE FUNCTION secure_var() +RETURNS int AS $$ + SELECT svartest.var1::int; +$$ LANGUAGE sql SECURITY DEFINER; + +SELECT secure_var(); + +SET ROLE TO var_test_role; + +-- should fail +SELECT svartest.var1; + +-- should work; +SELECT secure_var(); + +SET ROLE TO DEFAULT; + +EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM generate_series(1,100) g(v) WHERE v = var1; + +CREATE VIEW schema_var_view AS SELECT var1; + +SELECT * FROM schema_var_view; + +\c - + +SET search_path = svartest; + +-- should work still, but var will be empty +SELECT * FROM schema_var_view; + +LET var1 = pi(); + +SELECT var1; + +-- we can see execution plan of LET statement +EXPLAIN (VERBOSE, COSTS OFF) LET var1 = pi(); + +SELECT var1; + +CREATE VARIABLE var3 AS int; + +CREATE OR REPLACE FUNCTION inc(int) +RETURNS int AS $$ +BEGIN + LET svartest.var3 = COALESCE(svartest.var3 + $1, $1); + RETURN var3; +END; +$$ LANGUAGE plpgsql; + +SELECT inc(1); +SELECT inc(1); +SELECT inc(1); + +SELECT inc(1) FROM generate_series(1,10); + +SET ROLE TO var_test_role; + +-- should fail +LET var3 = 0; + +SET ROLE TO DEFAULT; + +DROP VIEW schema_var_view; + +DROP VARIABLE var1 CASCADE; +DROP VARIABLE var3 CASCADE; + +-- composite variables + +CREATE TYPE sv_xyz AS (x int, y int, z numeric(10,2)); + +CREATE VARIABLE v1 AS sv_xyz; +CREATE VARIABLE v2 AS sv_xyz; + +\d v1 +\d v2 + +LET v1 = (1,2,3.14); +LET v2 = (10,20,3.14*10); + +-- should work too - there are prepared casts +LET v1 = (1,2,3.14); + +SELECT v1; +SELECT v2; +SELECT (v1).*; +SELECT (v2).*; + +SELECT v1.x + v1.z; +SELECT v2.x + v2.z; + +-- access to composite fields should be safe too +-- should fail +SET ROLE TO var_test_role; + +SELECT v2.x; + +SET ROLE TO DEFAULT; + +DROP VARIABLE v1; +DROP VARIABLE v2; + +REVOKE USAGE ON SCHEMA svartest FROM var_test_role; +DROP ROLE var_test_role; + +-- scalar variables should not be in conflict with qualified column +CREATE VARIABLE varx AS text; +SELECT varx.relname FROM pg_class varx WHERE varx.relname = 'pg_class'; + +-- should fail +SELECT varx.xxx; + +-- variables can be updated under RO transaction + +BEGIN; +SET TRANSACTION READ ONLY; +LET varx = 'hello'; +COMMIT; + +SELECT varx; + +DROP VARIABLE varx; + +CREATE TYPE t1 AS (a int, b numeric, c text); + +CREATE VARIABLE v1 AS t1; +LET v1 = (1, pi(), 'hello'); +SELECT v1; +LET v1.b = 10.2222; +SELECT v1; + +-- should fail +LET v1.x = 10; + +DROP VARIABLE v1; +DROP TYPE t1; + +-- arrays are supported +CREATE VARIABLE va1 AS numeric[]; +LET va1 = ARRAY[1.1,2.1]; +LET va1[1] = 10.1; +SELECT va1; + +CREATE TYPE ta2 AS (a numeric, b numeric[]); +CREATE VARIABLE va2 AS ta2; +LET va2 = (10.1, ARRAY[0.0, 0.0]); +LET va2.a = 10.2; +SELECT va2; +LET va2.b[1] = 10.3; +SELECT va2; + +DROP VARIABLE va1; +DROP VARIABLE va2; +DROP TYPE ta2; + +-- default values +CREATE VARIABLE v1 AS numeric DEFAULT pi(); +LET v1 = v1 * 2; +SELECT v1; + +CREATE TYPE t2 AS (a numeric, b text); +CREATE VARIABLE v2 AS t2 DEFAULT (NULL, 'Hello'); +LET svartest.v2.a = pi(); +SELECT v2; + +-- should fail due dependency +DROP TYPE t2; + +-- should be ok +DROP VARIABLE v1; +DROP VARIABLE v2; + +-- tests of alters +CREATE SCHEMA var_schema1; +CREATE SCHEMA var_schema2; + +CREATE VARIABLE var_schema1.var1 AS integer; +LET var_schema1.var1 = 1000; +SELECT var_schema1.var1; +ALTER VARIABLE var_schema1.var1 SET SCHEMA var_schema2; +SELECT var_schema2.var1; + +CREATE ROLE var_test_role; + +ALTER VARIABLE var_schema2.var1 OWNER TO var_test_role; +SET ROLE TO var_test_role; + +-- should fail, no access to schema var_schema2.var +SELECT var_schema2.var1; +DROP VARIABLE var_schema2.var1; + +SET ROLE TO DEFAULT; + +ALTER VARIABLE var_schema2.var1 SET SCHEMA public; + +SET ROLE TO var_test_role; +SELECT public.var1; + +ALTER VARIABLE public.var1 RENAME TO var1_renamed; + +SELECT public.var1_renamed; + +DROP VARIABLE public.var1_renamed; + +SET ROLE TO DEFAULt; + +-- default rights test +ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON VARIABLES TO var_test_role; + +CREATE VARIABLE public.var2 AS int; + +SET ROLE TO var_test_role; + +-- should be ok +LET public.var2 = 100; +SELECT public.var2; + +SET ROLE TO DEFAULt; + +DROP VARIABLE public.var2; +DROP OWNED BY var_test_role; + +DROP ROLE var_test_role; + +CREATE VARIABLE xx AS text DEFAULT 'hello'; + +SELECT xx, upper(xx); + +LET xx = 'Hi'; + +SELECT xx; + +DROP VARIABLE xx; + +-- ON TRANSACTION END RESET tests +CREATE VARIABLE t1 AS int DEFAULT -1 ON TRANSACTION END RESET; + +BEGIN; + SELECT t1; + LET t1 = 100; + SELECT t1; +COMMIT; + +SELECT t1; + +BEGIN; + SELECT t1; + LET t1 = 100; + SELECT t1; +ROLLBACK; + +SELECT t1; + +DROP VARIABLE t1; + +CREATE VARIABLE v1 AS int DEFAULT 0; +CREATE VARIABLE v2 AS text DEFAULT 'none'; + +LET v1 = 100; +LET v2 = 'Hello'; +SELECT v1, v2; +LET v1 = DEFAULT; +LET v2 = DEFAULT; +SELECT v1, v2; + +DROP VARIABLE v1; +DROP VARIABLE v2; + +-- ON COMMIT DROP tests +-- should be 0 always +SELECT count(*) FROM pg_variable; + +CREATE TEMP VARIABLE g AS int ON COMMIT DROP; + +SELECT count(*) FROM pg_variable; + +BEGIN; + CREATE TEMP VARIABLE g AS int ON COMMIT DROP; +COMMIT; + +SELECT count(*) FROM pg_variable; + +BEGIN; + CREATE TEMP VARIABLE g AS int ON COMMIT DROP; +ROLLBACK; + +SELECT count(*) FROM pg_variable; + +-- Encourage use of parallel plans +SET parallel_setup_cost = 0; +SET parallel_tuple_cost = 0; +SET min_parallel_table_scan_size = 0; +SET max_parallel_workers_per_gather = 2; + +-- test on query with workers +CREATE TABLE svar_test(a int); +INSERT INTO svar_test SELECT * FROM generate_series(1,1000); +ANALYZE svar_test; +CREATE VARIABLE zero int; +LET zero = 0; + +-- parallel workers should be used +EXPLAIN (costs off) SELECT count(*) FROM svar_test WHERE a%10 = zero; + +-- result should be 100 +SELECT count(*) FROM svar_test WHERE a%10 = zero; + +LET zero = (SELECT count(*) FROM svar_test); + +-- result should be 1000 +SELECT zero; + +-- parallel workers should be used +EXPLAIN (costs off) LET zero = (SELECT count(*) FROM svar_test); + +-- test for dependency on relation +CREATE VARIABLE v_table AS svar_test; + +ALTER TABLE svar_test ALTER COLUMN a TYPE text; + +DROP VARIABLE v_table; +DROP TABLE svar_test; +DROP VARIABLE zero; + +RESET parallel_setup_cost; +RESET parallel_tuple_cost; +RESET min_parallel_table_scan_size; +RESET max_parallel_workers_per_gather; + +-- use variables in prepared statements +CREATE VARIABLE v AS numeric; +LET v = 3.14; + +-- use variables in views +CREATE VIEW vv AS SELECT COALESCE(v, 0) + 1000 AS result; +SELECT * FROM vv; + +-- start a new session +\c + +SET search_path to svartest; + +SELECT * FROM vv; +LET v = 3.14; +SELECT * FROM vv; + +-- should fail, dependency +DROP VARIABLE v; + +-- should be ok +DROP VARIABLE v CASCADE; + +-- other features +CREATE VARIABLE dt AS integer DEFAULT 0; + +LET dt = 100; +SELECT dt; + +DISCARD VARIABLES; + +SELECT dt; + +DROP VARIABLE dt; + +-- NOT NULL +CREATE VARIABLE v1 AS int NOT NULL; +CREATE VARIABLE v2 AS int NOT NULL DEFAULT NULL; + +-- should fail +SELECT v1; +SELECT v2; +LET v1 = NULL; +LET v2 = NULL; +LET v1 = DEFAULT; +LET v2 = DEFAULT; + +-- should be ok +LET v1 = 100; +LET v2 = 1000; +SELECT v1, v2; + +DROP VARIABLE v1; +DROP VARIABLE v2; + +CREATE VARIABLE tv AS int; +CREATE VARIABLE IF NOT EXISTS tv AS int; +DROP VARIABLE tv; + +CREATE IMMUTABLE VARIABLE iv AS int DEFAULT 100; +SELECT iv; + +-- should fail; +LET iv = 10000; + +DROP VARIABLE iv; + +-- different order +CREATE IMMUTABLE VARIABLE iv AS int DEFAULT 100; +-- should to fail +LET iv = 10000; +-- should be ok +SELECT iv; + +DROP VARIABLE iv; + +CREATE IMMUTABLE VARIABLE iv AS int; + +-- should be ok +LET iv = NULL; + +-- should fail +LET iv = NULL; + +DROP VARIABLE iv; + +-- create variable inside plpgsql block +DO $$ +BEGIN + CREATE VARIABLE do_test_svar AS date DEFAULT '2000-01-01'; +END; +$$; + +SELECT do_test_svar; + +DROP VARIABLE do_test_svar; + +-- should fail +CREATE IMMUTABLE VARIABLE xx AS int NOT NULL; + + + +-- REASSIGN OWNED test +CREATE ROLE var_test_role1; +CREATE ROLE var_test_role2; + +CREATE VARIABLE xxx_var AS int; + +ALTER VARIABLE xxx_var OWNER TO var_test_role1; +REASSIGN OWNED BY var_test_role1 to var_test_role2; + +SELECT varowner::regrole FROM pg_variable WHERE varname = 'xxx_var'; + +DROP OWNED BY var_test_role1; +DROP ROLE var_test_role1; +SELECT count(*) FROM pg_variable WHERE varname = 'xxx_var'; + +DROP OWNED BY var_test_role2; +DROP ROLE var_test_role2; +SELECT count(*) FROM pg_variable WHERE varname = 'xxx_var'; + +-- creating, dropping temporary variable +BEGIN; + +CREATE TEMP VARIABLE tempvar AS INT ON COMMIT DROP; + +LET tempvar = 100; + +SAVEPOINT s1; + +DROP VARIABLE tempvar; + +ROLLBACK TO s1; + +SELECT tempvar; + +COMMIT; + +-- should to fail +LET tempvar = 100; + +BEGIN; + +SAVEPOINT s1; + +CREATE TEMP VARIABLE tempvar AS INT ON COMMIT DROP; + +LET tempvar = 100; + +ROLLBACK TO s1; + +COMMIT; + +-- should to fail +LET tempvar = 100; + +CREATE VARIABLE var1 AS int; +LET var1 = 100; +BEGIN; +DROP VARIABLE var1; +ROLLBACK; +SELECT var1; + +DROP VARIABLE var1; + +CREATE VARIABLE var1 AS int DEFAULT 100; +COMMENT ON VARIABLE var1 IS 'some variable comment'; + +SELECT pg_catalog.obj_description(oid, 'pg_variable') FROM pg_variable WHERE varname = 'var1'; + +DROP VARIABLE var1; + +CREATE TABLE xxtab(avar int); + +CREATE TYPE xxtype AS (avar int); + +CREATE VARIABLE xxtab AS xxtype; + +INSERT INTO xxtab VALUES(10); + +-- it is ambiguous, but columns are preferred +-- variable is shadowed +SELECT xxtab.avar FROM xxtab; + +SET session_variables_ambiguity_warning TO on; + +SELECT xxtab.avar FROM xxtab; + +SET search_path = svartest; + +CREATE VARIABLE testvar as int; + +-- plpgsql variables are preferred against session variables +DO $$ +<<myblock>> +DECLARE testvar int; +BEGIN + -- should be ok without warning + LET testvar = 100; + -- should be ok without warning + testvar := 1000; + -- should be ok without warning + RAISE NOTICE 'session variable is %', svartest.testvar; + -- should be ok without warning + RAISE NOTICE 'plpgsql variable is %', myblock.testvar; + -- should to print plpgsql variable with warning + RAISE NOTICE 'variable is %', testvar; +END; +$$; + +DROP VARIABLE testvar; + +SET session_variables_ambiguity_warning TO default; + +-- should be ok +SELECT avar FROM xxtab; + +CREATE VARIABLE public.avar AS int; + +-- should be ok, see the table +SELECT avar FROM xxtab; + +-- should be ok +SELECT public.avar FROM xxtab; + +DROP VARIABLE xxtab; + +SELECT xxtab.avar FROM xxtab; + +DROP VARIABLE public.avar; + +DROP TYPE xxtype; + +DROP TABLE xxtab; + +-- test of plan cache invalidation +CREATE VARIABLE xx AS int; + +SET plan_cache_mode = force_generic_plan; + +PREPARE pp AS SELECT xx; + +EXECUTE pp; + +DROP VARIABLE xx; + +CREATE VARIABLE xx AS int; + +-- should to work +EXECUTE pp; + +DROP VARIABLE xx; + +DEALLOCATE pp; + +SET plan_cache_mode = DEFAULT; + +CREATE ROLE var_test_role; + +CREATE SCHEMA vartest; + +GRANT USAGE ON SCHEMA vartest TO var_test_role; + +CREATE VARIABLE vartest.x AS int; +CREATE VARIABLE vartest.y AS int; + +LET vartest.x = 100; +LET vartest.y = 101; + +GRANT SELECT ON ALL VARIABLES IN SCHEMA vartest TO var_test_role; + +SET ROLE TO var_test_role; + +SELECT vartest.x, vartest.y; + +SET ROLE TO DEFAULT; + +REVOKE SELECT ON ALL VARIABLES IN SCHEMA vartest FROM var_test_role; + +SET ROLE TO var_test_role; + +-- should to fail +SELECT vartest.x; +SELECT vartest.y; + +SET ROLE TO DEFAULT; + +DROP VARIABLE vartest.x, vartest.y; + +DROP SCHEMA vartest; + +DROP ROLE var_test_role; + +-- test cached plan +CREATE VARIABLE v1 AS text; +CREATE VARIABLE v2 AS int; +CREATE VARIABLE v3 AS int; + +LET v1 = 'test'; +LET v2 = 10; +LET v3 = 5; + +PREPARE q1 AS SELECT v1 || i FROM generate_series(1, v2) g(i) WHERE i IN (v2, v3); + +SET plan_cache_mode to force_generic_plan; + +EXECUTE q1; + +EXPLAIN EXECUTE q1; + +-- dependecy check +DROP VARIABLE v3; + +-- recreate v3 again +CREATE VARIABLE v3 AS int DEFAULT 6; + +-- should to work, the plan should be recreated +EXECUTE q1; + +DEALLOCATE q1; + +-- fill v1 by long text +LET v1 = repeat(' ', 10000); + +PREPARE q1 AS SELECT length(v1); + +EXECUTE q1; + +LET v1 = repeat(' ', 5000); + +EXECUTE q1; + +DEALLOCATE q1; + +SET plan_cache_mode to default; + +DROP VARIABLE v1, v2, v3; + +CREATE ROLE var_test_role; + +CREATE VARIABLE public.v1 AS int DEFAULT 0; + +-- check acl when variable is acessed by simple eval expr method +CREATE OR REPLACE FUNCTION public.fx_var(int) +RETURNS int AS $$ +DECLARE xx int; +BEGIN + xx := public.v1 + $1; + RETURN xx; +END; +$$ LANGUAGE plpgsql; + +-- should be ok +SELECT public.fx_var(0); + +SET ROLE TO var_test_role; + +-- should to fail +SELECT public.fx_var(0); + +SET ROLE TO default; + +GRANT SELECT ON VARIABLE public.v1 TO var_test_role; + +SET ROLE TO var_test_role; + +-- should be ok +SELECT public.fx_var(0); + +SET ROLE TO default; + +REVOKE SELECT ON VARIABLE public.v1 FROM var_test_role; + +SET ROLE TO var_test_role; + +-- should be fail +SELECT public.fx_var(0); + +SET ROLE TO DEFAULT; + +DROP FUNCTION public.fx_var(int); + +DROP VARIABLE public.v1; + +DROP ROLE var_test_role; + +CREATE TYPE public.svar_test_type AS (a int, b int, c numeric); + +CREATE VARIABLE public.svar AS public.svar_test_type; + +LET public.svar = ROW(10,20,30); + +SELECT public.svar; + +ALTER TYPE public.svar_test_type DROP ATTRIBUTE c; + +-- should be ok +SELECT public.svar; + +ALTER TYPE public.svar_test_type ADD ATTRIBUTE c int; + +-- should be ok +SELECT public.svar; + +LET public.svar = ROW(10,20,30); + +-- should be ok again for new value +SELECT public.svar; + +DROP VARIABLE public.svar; + +DROP TYPE public.svar_test_type; + +CREATE VARIABLE public.svar AS int; +select oid as varid from pg_variable where varname = 'svar' and varnamespace = 'public'::regnamespace \gset + +SELECT schema, name, removed FROM pg_debug_show_used_session_variables(); + +LET public.svar = 100; + +SELECT schema, name, removed FROM pg_debug_show_used_session_variables(); + +BEGIN; + +DROP VARIABLE public.svar; + +-- value should be in memory +SELECT schema, name, removed FROM pg_debug_show_used_session_variables(); + +ROLLBACK; + +-- value should be in memory +SELECT schema, name, removed FROM pg_debug_show_used_session_variables() f WHERE f.varid = :varid; + +SELECT public.svar; + +BEGIN; + +DROP VARIABLE public.svar; + +-- value should be in memory +SELECT schema, name, removed FROM pg_debug_show_used_session_variables() f WHERE f.varid = :varid;; + +COMMIT; + +-- the memory should be clean; +SELECT schema, name, removed FROM pg_debug_show_used_session_variables() WHERE f.varid = :varid; + +BEGIN; + +CREATE VARIABLE public.svar AS int; +select oid as varid from pg_variable where varname = 'svar' and varnamespace = 'public'::regnamespace \gset + + +LET public.svar = 100; + +ROLLBACK; + +-- the memory should be clean; +SELECT schema, name, removed FROM pg_debug_show_used_session_variables() f WHERE f.varid = :varid; + +\unset varid + +CREATE VARIABLE public.svar AS int; + +LET public.svar = 100; + +-- repeated aborted transaction +BEGIN; DROP VARIABLE public.svar; ROLLBACK; +BEGIN; DROP VARIABLE public.svar; ROLLBACK; +BEGIN; DROP VARIABLE public.svar; ROLLBACK; + +-- the value should be still available +SELECT public.svar; + +DROP VARIABLE public.svar; + +CREATE TYPE public.svar_test_type AS (a int, b int); + +CREATE VARIABLE public.svar AS public.svar_test_type; + +SELECT public.svar; + +ALTER TYPE public.svar_test_type ADD ATTRIBUTE c int; + +SELECT public.svar; + +ALTER TYPE public.svar_test_type DROP ATTRIBUTE b; + +SELECT public.svar; + +DROP VARIABLE public.svar; +DROP TYPE public.svar_test_type; + +CREATE TYPE public.svar_test_type AS (a int, b int); + +CREATE VARIABLE public.svar AS public.svar_test_type; +CREATE VARIABLE public.svar2 AS public.svar_test_type; + +LET public.svar = (10, 20); + +ALTER TYPE public.svar_test_type ADD ATTRIBUTE c int; + +SELECT public.svar; + +LET public.svar2 = (10, 20, 30); + +ALTER TYPE public.svar_test_type DROP ATTRIBUTE b; + +SELECT public.svar; +SELECT public.svar2; + +DROP VARIABLE public.svar; +DROP VARIABLE public.svar2; +DROP TYPE public.svar_test_type; + +-- The composite type cannot be changed when it is used +CREATE TYPE public.svar_type AS (a int, b int); + +CREATE VARIABLE public.svar AS public.svar_type; + +-- should to fail +ALTER TYPE public.svar_type ALTER ATTRIBUTE b TYPE numeric; + +DROP VARIABLE public.svar; + +CREATE TYPE public.svar_type2 AS (a int, b int, c public.svar_type); + +CREATE VARIABLE public.svar AS public.svar_type2; + +-- should to fail +ALTER TYPE public.svar_type ALTER ATTRIBUTE b TYPE numeric; + +DROP VARIABLE public.svar; +DROP TYPE public.svar_type2; +DROP TYPE public.svar_type; + +-- The variable can be shadowed by table or by alias +CREATE TYPE public.svar_type AS (a int, b int, c int); +CREATE VARIABLE public.svar AS public.svar_type; + +CREATE TABLE public.svar (a int, b int); + +INSERT INTO public.svar VALUES(10, 20); + +LET public.svar = (100, 200, 300); + +-- should be ok +-- show table +SELECT * FROM public.svar; +SELECT svar.a FROM public.svar; +SELECT svar.* FROM public.svar; + +-- show variable +SELECT public.svar; +SELECT public.svar.c; +SELECT (public.svar).*; + +-- the variable is shadowed, raise error +SELECT public.svar.c FROM public.svar; + +-- can be fixed by alias +SELECT public.svar.c FROM public.svar x; + +-- again with warnings +SET session_variables_ambiguity_warning TO on; + +SELECT * FROM public.svar; +SELECT svar.a FROM public.svar; +SELECT svar.* FROM public.svar; + +-- show variable +SELECT public.svar; +SELECT public.svar.c; +SELECT (public.svar).*; + +-- the variable is shadowed, raise error +SELECT public.svar.c FROM public.svar; + +-- can be fixed by alias +SELECT public.svar.c FROM public.svar x; + +SET session_variables_ambiguity_warning TO DEFAULT; + +DROP VARIABLE public.svar; +DROP TABLE public.svar; +DROP TYPE public.svar_type; -- 2.37.0 --w2in66fnadvggvsb Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="v20220916-0011-FIXUP-regress-tests-for-session-variables.patch" ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v20220916 10/13] regress tests for session variables @ 2022-04-04 18:54 [email protected] <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: [email protected] @ 2022-04-04 18:54 UTC (permalink / raw) Checks of basic functionality, check of usage session variables in subtransactions and from PLpgSQL --- .../isolation/expected/session-variable.out | 86 ++ src/test/isolation/isolation_schedule | 1 + .../isolation/specs/session-variable.spec | 34 + .../regress/expected/session_variables.out | 1287 +++++++++++++++++ src/test/regress/parallel_schedule | 2 +- src/test/regress/sql/session_variables.sql | 959 ++++++++++++ 6 files changed, 2368 insertions(+), 1 deletion(-) create mode 100644 src/test/isolation/expected/session-variable.out create mode 100644 src/test/isolation/specs/session-variable.spec create mode 100644 src/test/regress/expected/session_variables.out create mode 100644 src/test/regress/sql/session_variables.sql diff --git a/src/test/isolation/expected/session-variable.out b/src/test/isolation/expected/session-variable.out new file mode 100644 index 0000000000..b0059910a1 --- /dev/null +++ b/src/test/isolation/expected/session-variable.out @@ -0,0 +1,86 @@ +Parsed test spec with 2 sessions + +starting permutation: let val drop val +step let: LET myvar = 'test'; +step val: SELECT myvar; +myvar +----- +test +(1 row) + +step drop: DROP VARIABLE myvar; +step val: SELECT myvar; +ERROR: column or variable "myvar" does not exist + +starting permutation: let val s1 drop val sr1 +step let: LET myvar = 'test'; +step val: SELECT myvar; +myvar +----- +test +(1 row) + +step s1: BEGIN; +step drop: DROP VARIABLE myvar; +step val: SELECT myvar; +ERROR: column or variable "myvar" does not exist +step sr1: ROLLBACK; + +starting permutation: let val dbg drop create dbg val +step let: LET myvar = 'test'; +step val: SELECT myvar; +myvar +----- +test +(1 row) + +step dbg: SELECT schema, name, removed FROM pg_debug_show_used_session_variables(); +schema|name |removed +------+-----+------- +public|myvar|f +(1 row) + +step drop: DROP VARIABLE myvar; +step create: CREATE VARIABLE myvar AS text +step dbg: SELECT schema, name, removed FROM pg_debug_show_used_session_variables(); +schema|name|removed +------+----+------- +(0 rows) + +step val: SELECT myvar; +myvar +----- + +(1 row) + + +starting permutation: let val s1 dbg drop create dbg val sr1 +step let: LET myvar = 'test'; +step val: SELECT myvar; +myvar +----- +test +(1 row) + +step s1: BEGIN; +step dbg: SELECT schema, name, removed FROM pg_debug_show_used_session_variables(); +schema|name |removed +------+-----+------- +public|myvar|f +(1 row) + +step drop: DROP VARIABLE myvar; +step create: CREATE VARIABLE myvar AS text +step dbg: SELECT schema, name, removed FROM pg_debug_show_used_session_variables(); +schema|name |removed +------+-----+------- +public|myvar|f +(1 row) + +step val: SELECT myvar; +myvar +----- + +(1 row) + +step sr1: ROLLBACK; diff --git a/src/test/isolation/isolation_schedule b/src/test/isolation/isolation_schedule index 5413a59a80..67837ef00f 100644 --- a/src/test/isolation/isolation_schedule +++ b/src/test/isolation/isolation_schedule @@ -108,3 +108,4 @@ test: cluster-conflict-partition test: truncate-conflict test: serializable-parallel test: serializable-parallel-2 +test: session-variable diff --git a/src/test/isolation/specs/session-variable.spec b/src/test/isolation/specs/session-variable.spec new file mode 100644 index 0000000000..fe47339110 --- /dev/null +++ b/src/test/isolation/specs/session-variable.spec @@ -0,0 +1,34 @@ +# Test session variables memory cleanup for sinval + +setup +{ + CREATE VARIABLE myvar AS text; +} + +teardown +{ + DROP VARIABLE IF EXISTS myvar; +} + +session s1 +step s1 { BEGIN; } +step let { LET myvar = 'test'; } +step val { SELECT myvar; } +step dbg { SELECT schema, name, removed FROM pg_debug_show_used_session_variables(); } +step sr1 { ROLLBACK; } + + +session s2 +step drop { DROP VARIABLE myvar; } +step create { CREATE VARIABLE myvar AS text } + +# Concurrent drop of a known variable should lead to an error +permutation let val drop val +# Same, but with an explicit transaction +permutation let val s1 drop val sr1 +# Concurrent drop/create of a known variable should lead to empty variable +permutation let val dbg drop create dbg val +# Concurrent drop/create of a known variable should lead to empty variable +# We need a transaction to make sure that we won't accept invalidation when +# calling the dbg step after the concurrent drop +permutation let val s1 dbg drop create dbg val sr1 diff --git a/src/test/regress/expected/session_variables.out b/src/test/regress/expected/session_variables.out new file mode 100644 index 0000000000..d411f0440d --- /dev/null +++ b/src/test/regress/expected/session_variables.out @@ -0,0 +1,1287 @@ +CREATE SCHEMA svartest; +SET search_path = svartest; +CREATE VARIABLE var1 AS integer; +CREATE TEMP VARIABLE var2 AS text; +DROP VARIABLE var1, var2; +-- functional interface +CREATE VARIABLE var1 AS numeric; +CREATE ROLE var_test_role; +GRANT USAGE ON SCHEMA svartest TO var_test_role; +SET ROLE TO var_test_role; +-- should fail +SELECT var1; +ERROR: permission denied for session variable var1 +SET ROLE TO DEFAULT; +GRANT SELECT ON VARIABLE var1 TO var_test_role; +SET ROLE TO var_test_role; +-- should fail +LET var1 = 10; +ERROR: permission denied for session variable var1 +-- should work +SELECT var1; + var1 +------ + +(1 row) + +SET ROLE TO DEFAULT; +GRANT UPDATE ON VARIABLE var1 TO var_test_role; +SET ROLE TO var_test_role; +-- should work +LET var1 = 333; +SET ROLE TO DEFAULT; +REVOKE ALL ON VARIABLE var1 FROM var_test_role; +CREATE OR REPLACE FUNCTION secure_var() +RETURNS int AS $$ + SELECT svartest.var1::int; +$$ LANGUAGE sql SECURITY DEFINER; +SELECT secure_var(); + secure_var +------------ + 333 +(1 row) + +SET ROLE TO var_test_role; +-- should fail +SELECT svartest.var1; +ERROR: permission denied for session variable var1 +-- should work; +SELECT secure_var(); + secure_var +------------ + 333 +(1 row) + +SET ROLE TO DEFAULT; +EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM generate_series(1,100) g(v) WHERE v = var1; + QUERY PLAN +----------------------------------------------- + Function Scan on pg_catalog.generate_series g + Output: v + Function Call: generate_series(1, 100) + Filter: ((g.v)::numeric = var1) +(4 rows) + +CREATE VIEW schema_var_view AS SELECT var1; +SELECT * FROM schema_var_view; + var1 +------ + 333 +(1 row) + +\c - +SET search_path = svartest; +-- should work still, but var will be empty +SELECT * FROM schema_var_view; + var1 +------ + +(1 row) + +LET var1 = pi(); +SELECT var1; + var1 +------------------ + 3.14159265358979 +(1 row) + +-- we can see execution plan of LET statement +EXPLAIN (VERBOSE, COSTS OFF) LET var1 = pi(); + QUERY PLAN +---------------------------- + SET SESSION VARIABLE + Result + Output: 3.14159265358979 +(3 rows) + +SELECT var1; + var1 +------------------ + 3.14159265358979 +(1 row) + +CREATE VARIABLE var3 AS int; +CREATE OR REPLACE FUNCTION inc(int) +RETURNS int AS $$ +BEGIN + LET svartest.var3 = COALESCE(svartest.var3 + $1, $1); + RETURN var3; +END; +$$ LANGUAGE plpgsql; +SELECT inc(1); + inc +----- + 1 +(1 row) + +SELECT inc(1); + inc +----- + 2 +(1 row) + +SELECT inc(1); + inc +----- + 3 +(1 row) + +SELECT inc(1) FROM generate_series(1,10); + inc +----- + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 +(10 rows) + +SET ROLE TO var_test_role; +-- should fail +LET var3 = 0; +ERROR: permission denied for session variable var3 +SET ROLE TO DEFAULT; +DROP VIEW schema_var_view; +DROP VARIABLE var1 CASCADE; +DROP VARIABLE var3 CASCADE; +-- composite variables +CREATE TYPE sv_xyz AS (x int, y int, z numeric(10,2)); +CREATE VARIABLE v1 AS sv_xyz; +CREATE VARIABLE v2 AS sv_xyz; +\d v1 +\d v2 +LET v1 = (1,2,3.14); +LET v2 = (10,20,3.14*10); +-- should work too - there are prepared casts +LET v1 = (1,2,3.14); +SELECT v1; + v1 +------------ + (1,2,3.14) +(1 row) + +SELECT v2; + v2 +--------------- + (10,20,31.40) +(1 row) + +SELECT (v1).*; + x | y | z +---+---+------ + 1 | 2 | 3.14 +(1 row) + +SELECT (v2).*; + x | y | z +----+----+------- + 10 | 20 | 31.40 +(1 row) + +SELECT v1.x + v1.z; + ?column? +---------- + 4.14 +(1 row) + +SELECT v2.x + v2.z; + ?column? +---------- + 41.40 +(1 row) + +-- access to composite fields should be safe too +-- should fail +SET ROLE TO var_test_role; +SELECT v2.x; +ERROR: permission denied for session variable v2 +SET ROLE TO DEFAULT; +DROP VARIABLE v1; +DROP VARIABLE v2; +REVOKE USAGE ON SCHEMA svartest FROM var_test_role; +DROP ROLE var_test_role; +-- scalar variables should not be in conflict with qualified column +CREATE VARIABLE varx AS text; +SELECT varx.relname FROM pg_class varx WHERE varx.relname = 'pg_class'; + relname +---------- + pg_class +(1 row) + +-- should fail +SELECT varx.xxx; +ERROR: type text is not composite +-- variables can be updated under RO transaction +BEGIN; +SET TRANSACTION READ ONLY; +LET varx = 'hello'; +COMMIT; +SELECT varx; + varx +------- + hello +(1 row) + +DROP VARIABLE varx; +CREATE TYPE t1 AS (a int, b numeric, c text); +CREATE VARIABLE v1 AS t1; +LET v1 = (1, pi(), 'hello'); +SELECT v1; + v1 +---------------------------- + (1,3.14159265358979,hello) +(1 row) + +LET v1.b = 10.2222; +SELECT v1; + v1 +------------------- + (1,10.2222,hello) +(1 row) + +-- should fail +LET v1.x = 10; +ERROR: cannot assign to field "x" of column "v1" because there is no such column in data type t1 +LINE 1: LET v1.x = 10; + ^ +DROP VARIABLE v1; +DROP TYPE t1; +-- arrays are supported +CREATE VARIABLE va1 AS numeric[]; +LET va1 = ARRAY[1.1,2.1]; +LET va1[1] = 10.1; +SELECT va1; + va1 +------------ + {10.1,2.1} +(1 row) + +CREATE TYPE ta2 AS (a numeric, b numeric[]); +CREATE VARIABLE va2 AS ta2; +LET va2 = (10.1, ARRAY[0.0, 0.0]); +LET va2.a = 10.2; +SELECT va2; + va2 +-------------------- + (10.2,"{0.0,0.0}") +(1 row) + +LET va2.b[1] = 10.3; +SELECT va2; + va2 +--------------------- + (10.2,"{10.3,0.0}") +(1 row) + +DROP VARIABLE va1; +DROP VARIABLE va2; +DROP TYPE ta2; +-- default values +CREATE VARIABLE v1 AS numeric DEFAULT pi(); +LET v1 = v1 * 2; +SELECT v1; + v1 +------------------ + 6.28318530717958 +(1 row) + +CREATE TYPE t2 AS (a numeric, b text); +CREATE VARIABLE v2 AS t2 DEFAULT (NULL, 'Hello'); +LET svartest.v2.a = pi(); +SELECT v2; + v2 +-------------------------- + (3.14159265358979,Hello) +(1 row) + +-- should fail due dependency +DROP TYPE t2; +ERROR: cannot drop type t2 because other objects depend on it +DETAIL: session variable v2 depends on type t2 +HINT: Use DROP ... CASCADE to drop the dependent objects too. +-- should be ok +DROP VARIABLE v1; +DROP VARIABLE v2; +-- tests of alters +CREATE SCHEMA var_schema1; +CREATE SCHEMA var_schema2; +CREATE VARIABLE var_schema1.var1 AS integer; +LET var_schema1.var1 = 1000; +SELECT var_schema1.var1; + var1 +------ + 1000 +(1 row) + +ALTER VARIABLE var_schema1.var1 SET SCHEMA var_schema2; +SELECT var_schema2.var1; + var1 +------ + 1000 +(1 row) + +CREATE ROLE var_test_role; +ALTER VARIABLE var_schema2.var1 OWNER TO var_test_role; +SET ROLE TO var_test_role; +-- should fail, no access to schema var_schema2.var +SELECT var_schema2.var1; +ERROR: permission denied for schema var_schema2 +DROP VARIABLE var_schema2.var1; +ERROR: permission denied for schema var_schema2 +SET ROLE TO DEFAULT; +ALTER VARIABLE var_schema2.var1 SET SCHEMA public; +SET ROLE TO var_test_role; +SELECT public.var1; + var1 +------ + 1000 +(1 row) + +ALTER VARIABLE public.var1 RENAME TO var1_renamed; +SELECT public.var1_renamed; + var1_renamed +-------------- + 1000 +(1 row) + +DROP VARIABLE public.var1_renamed; +SET ROLE TO DEFAULt; +-- default rights test +ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON VARIABLES TO var_test_role; +CREATE VARIABLE public.var2 AS int; +SET ROLE TO var_test_role; +-- should be ok +LET public.var2 = 100; +SELECT public.var2; + var2 +------ + 100 +(1 row) + +SET ROLE TO DEFAULt; +DROP VARIABLE public.var2; +DROP OWNED BY var_test_role; +DROP ROLE var_test_role; +CREATE VARIABLE xx AS text DEFAULT 'hello'; +SELECT xx, upper(xx); + xx | upper +-------+------- + hello | HELLO +(1 row) + +LET xx = 'Hi'; +SELECT xx; + xx +---- + Hi +(1 row) + +DROP VARIABLE xx; +-- ON TRANSACTION END RESET tests +CREATE VARIABLE t1 AS int DEFAULT -1 ON TRANSACTION END RESET; +BEGIN; + SELECT t1; + t1 +---- + -1 +(1 row) + + LET t1 = 100; + SELECT t1; + t1 +----- + 100 +(1 row) + +COMMIT; +SELECT t1; + t1 +---- + -1 +(1 row) + +BEGIN; + SELECT t1; + t1 +---- + -1 +(1 row) + + LET t1 = 100; + SELECT t1; + t1 +----- + 100 +(1 row) + +ROLLBACK; +SELECT t1; + t1 +---- + -1 +(1 row) + +DROP VARIABLE t1; +CREATE VARIABLE v1 AS int DEFAULT 0; +CREATE VARIABLE v2 AS text DEFAULT 'none'; +LET v1 = 100; +LET v2 = 'Hello'; +SELECT v1, v2; + v1 | v2 +-----+------- + 100 | Hello +(1 row) + +LET v1 = DEFAULT; +LET v2 = DEFAULT; +SELECT v1, v2; + v1 | v2 +----+------ + 0 | none +(1 row) + +DROP VARIABLE v1; +DROP VARIABLE v2; +-- ON COMMIT DROP tests +-- should be 0 always +SELECT count(*) FROM pg_variable; + count +------- + 0 +(1 row) + +CREATE TEMP VARIABLE g AS int ON COMMIT DROP; +SELECT count(*) FROM pg_variable; + count +------- + 0 +(1 row) + +BEGIN; + CREATE TEMP VARIABLE g AS int ON COMMIT DROP; +COMMIT; +SELECT count(*) FROM pg_variable; + count +------- + 0 +(1 row) + +BEGIN; + CREATE TEMP VARIABLE g AS int ON COMMIT DROP; +ROLLBACK; +SELECT count(*) FROM pg_variable; + count +------- + 0 +(1 row) + +-- Encourage use of parallel plans +SET parallel_setup_cost = 0; +SET parallel_tuple_cost = 0; +SET min_parallel_table_scan_size = 0; +SET max_parallel_workers_per_gather = 2; +-- test on query with workers +CREATE TABLE svar_test(a int); +INSERT INTO svar_test SELECT * FROM generate_series(1,1000); +ANALYZE svar_test; +CREATE VARIABLE zero int; +LET zero = 0; +-- parallel workers should be used +EXPLAIN (costs off) SELECT count(*) FROM svar_test WHERE a%10 = zero; + QUERY PLAN +-------------------------------------------- + Aggregate + -> Gather + Workers Planned: 2 + -> Parallel Seq Scan on svar_test + Filter: ((a % 10) = zero) +(5 rows) + +-- result should be 100 +SELECT count(*) FROM svar_test WHERE a%10 = zero; + count +------- + 100 +(1 row) + +LET zero = (SELECT count(*) FROM svar_test); +-- result should be 1000 +SELECT zero; + zero +------ + 1000 +(1 row) + +-- parallel workers should be used +EXPLAIN (costs off) LET zero = (SELECT count(*) FROM svar_test); + QUERY PLAN +---------------------------------------------------------- + SET SESSION VARIABLE + Result + InitPlan 1 (returns $1) + -> Finalize Aggregate + -> Gather + Workers Planned: 2 + -> Partial Aggregate + -> Parallel Seq Scan on svar_test +(8 rows) + +-- test for dependency on relation +CREATE VARIABLE v_table AS svar_test; +ALTER TABLE svar_test ALTER COLUMN a TYPE text; +ERROR: cannot alter table "svar_test" because session variable "svartest.v_table" uses it +DROP VARIABLE v_table; +DROP TABLE svar_test; +DROP VARIABLE zero; +RESET parallel_setup_cost; +RESET parallel_tuple_cost; +RESET min_parallel_table_scan_size; +RESET max_parallel_workers_per_gather; +-- use variables in prepared statements +CREATE VARIABLE v AS numeric; +LET v = 3.14; +-- use variables in views +CREATE VIEW vv AS SELECT COALESCE(v, 0) + 1000 AS result; +SELECT * FROM vv; + result +--------- + 1003.14 +(1 row) + +-- start a new session +\c +SET search_path to svartest; +SELECT * FROM vv; + result +-------- + 1000 +(1 row) + +LET v = 3.14; +SELECT * FROM vv; + result +--------- + 1003.14 +(1 row) + +-- should fail, dependency +DROP VARIABLE v; +ERROR: cannot drop session variable v because other objects depend on it +DETAIL: view vv depends on session variable v +HINT: Use DROP ... CASCADE to drop the dependent objects too. +-- should be ok +DROP VARIABLE v CASCADE; +NOTICE: drop cascades to view vv +-- other features +CREATE VARIABLE dt AS integer DEFAULT 0; +LET dt = 100; +SELECT dt; + dt +----- + 100 +(1 row) + +DISCARD VARIABLES; +SELECT dt; + dt +---- + 0 +(1 row) + +DROP VARIABLE dt; +-- NOT NULL +CREATE VARIABLE v1 AS int NOT NULL; +CREATE VARIABLE v2 AS int NOT NULL DEFAULT NULL; +-- should fail +SELECT v1; +ERROR: null value is not allowed for NOT NULL session variable "svartest.v1" +DETAIL: The session variable was not initialized yet. +SELECT v2; +ERROR: null value is not allowed for NOT NULL session variable "svartest.v2" +LET v1 = NULL; +ERROR: null value is not allowed for NOT NULL session variable "svartest.v1" +LET v2 = NULL; +ERROR: null value is not allowed for NOT NULL session variable "svartest.v2" +LET v1 = DEFAULT; +ERROR: null value is not allowed for NOT NULL session variable "svartest.v1" +LET v2 = DEFAULT; +ERROR: null value is not allowed for NOT NULL session variable "svartest.v2" +-- should be ok +LET v1 = 100; +LET v2 = 1000; +SELECT v1, v2; + v1 | v2 +-----+------ + 100 | 1000 +(1 row) + +DROP VARIABLE v1; +DROP VARIABLE v2; +CREATE VARIABLE tv AS int; +CREATE VARIABLE IF NOT EXISTS tv AS int; +NOTICE: session variable "tv" already exists, skipping +DROP VARIABLE tv; +CREATE IMMUTABLE VARIABLE iv AS int DEFAULT 100; +SELECT iv; + iv +----- + 100 +(1 row) + +-- should fail; +LET iv = 10000; +ERROR: session variable "svartest.iv" is declared IMMUTABLE +DROP VARIABLE iv; +-- different order +CREATE IMMUTABLE VARIABLE iv AS int DEFAULT 100; +-- should to fail +LET iv = 10000; +ERROR: session variable "svartest.iv" is declared IMMUTABLE +-- should be ok +SELECT iv; + iv +----- + 100 +(1 row) + +DROP VARIABLE iv; +CREATE IMMUTABLE VARIABLE iv AS int; +-- should be ok +LET iv = NULL; +-- should fail +LET iv = NULL; +ERROR: session variable "svartest.iv" is declared IMMUTABLE +DROP VARIABLE iv; +-- create variable inside plpgsql block +DO $$ +BEGIN + CREATE VARIABLE do_test_svar AS date DEFAULT '2000-01-01'; +END; +$$; +SELECT do_test_svar; + do_test_svar +-------------- + 01-01-2000 +(1 row) + +DROP VARIABLE do_test_svar; +-- should fail +CREATE IMMUTABLE VARIABLE xx AS int NOT NULL; +ERROR: IMMUTABLE NOT NULL variable requires default expression +-- REASSIGN OWNED test +CREATE ROLE var_test_role1; +CREATE ROLE var_test_role2; +CREATE VARIABLE xxx_var AS int; +ALTER VARIABLE xxx_var OWNER TO var_test_role1; +REASSIGN OWNED BY var_test_role1 to var_test_role2; +SELECT varowner::regrole FROM pg_variable WHERE varname = 'xxx_var'; + varowner +---------------- + var_test_role2 +(1 row) + +DROP OWNED BY var_test_role1; +DROP ROLE var_test_role1; +SELECT count(*) FROM pg_variable WHERE varname = 'xxx_var'; + count +------- + 1 +(1 row) + +DROP OWNED BY var_test_role2; +DROP ROLE var_test_role2; +SELECT count(*) FROM pg_variable WHERE varname = 'xxx_var'; + count +------- + 0 +(1 row) + +-- creating, dropping temporary variable +BEGIN; +CREATE TEMP VARIABLE tempvar AS INT ON COMMIT DROP; +LET tempvar = 100; +SAVEPOINT s1; +DROP VARIABLE tempvar; +ROLLBACK TO s1; +SELECT tempvar; + tempvar +--------- + 100 +(1 row) + +COMMIT; +-- should to fail +LET tempvar = 100; +ERROR: session variable "tempvar" doesn't exist +LINE 1: LET tempvar = 100; + ^ +BEGIN; +SAVEPOINT s1; +CREATE TEMP VARIABLE tempvar AS INT ON COMMIT DROP; +LET tempvar = 100; +ROLLBACK TO s1; +COMMIT; +-- should to fail +LET tempvar = 100; +ERROR: session variable "tempvar" doesn't exist +LINE 1: LET tempvar = 100; + ^ +CREATE VARIABLE var1 AS int; +LET var1 = 100; +BEGIN; +DROP VARIABLE var1; +ROLLBACK; +SELECT var1; + var1 +------ + 100 +(1 row) + +DROP VARIABLE var1; +CREATE VARIABLE var1 AS int DEFAULT 100; +COMMENT ON VARIABLE var1 IS 'some variable comment'; +SELECT pg_catalog.obj_description(oid, 'pg_variable') FROM pg_variable WHERE varname = 'var1'; + obj_description +----------------------- + some variable comment +(1 row) + +DROP VARIABLE var1; +CREATE TABLE xxtab(avar int); +CREATE TYPE xxtype AS (avar int); +CREATE VARIABLE xxtab AS xxtype; +INSERT INTO xxtab VALUES(10); +-- it is ambiguous, but columns are preferred +-- variable is shadowed +SELECT xxtab.avar FROM xxtab; + avar +------ + 10 +(1 row) + +SET session_variables_ambiguity_warning TO on; +SELECT xxtab.avar FROM xxtab; +WARNING: session variable "xxtab.avar" is shadowed +LINE 1: SELECT xxtab.avar FROM xxtab; + ^ +DETAIL: Session variables can be shadowed by columns, routine's variables and routine's arguments with the same name. + avar +------ + 10 +(1 row) + +SET search_path = svartest; +CREATE VARIABLE testvar as int; +-- plpgsql variables are preferred against session variables +DO $$ +<<myblock>> +DECLARE testvar int; +BEGIN + -- should be ok without warning + LET testvar = 100; + -- should be ok without warning + testvar := 1000; + -- should be ok without warning + RAISE NOTICE 'session variable is %', svartest.testvar; + -- should be ok without warning + RAISE NOTICE 'plpgsql variable is %', myblock.testvar; + -- should to print plpgsql variable with warning + RAISE NOTICE 'variable is %', testvar; +END; +$$; +WARNING: session variable "testvar" is shadowed +LINE 1: testvar := 1000 + ^ +DETAIL: Session variables can be shadowed by columns, routine's variables and routine's arguments with the same name. +QUERY: testvar := 1000 +NOTICE: session variable is 100 +NOTICE: plpgsql variable is 1000 +WARNING: session variable "testvar" is shadowed +LINE 1: testvar + ^ +DETAIL: Session variables can be shadowed by columns, routine's variables and routine's arguments with the same name. +QUERY: testvar +NOTICE: variable is 1000 +DROP VARIABLE testvar; +SET session_variables_ambiguity_warning TO default; +-- should be ok +SELECT avar FROM xxtab; + avar +------ + 10 +(1 row) + +CREATE VARIABLE public.avar AS int; +-- should be ok, see the table +SELECT avar FROM xxtab; + avar +------ + 10 +(1 row) + +-- should be ok +SELECT public.avar FROM xxtab; + avar +------ + +(1 row) + +DROP VARIABLE xxtab; +SELECT xxtab.avar FROM xxtab; + avar +------ + 10 +(1 row) + +DROP VARIABLE public.avar; +DROP TYPE xxtype; +DROP TABLE xxtab; +-- test of plan cache invalidation +CREATE VARIABLE xx AS int; +SET plan_cache_mode = force_generic_plan; +PREPARE pp AS SELECT xx; +EXECUTE pp; + xx +---- + +(1 row) + +DROP VARIABLE xx; +CREATE VARIABLE xx AS int; +-- should to work +EXECUTE pp; + xx +---- + +(1 row) + +DROP VARIABLE xx; +DEALLOCATE pp; +SET plan_cache_mode = DEFAULT; +CREATE ROLE var_test_role; +CREATE SCHEMA vartest; +GRANT USAGE ON SCHEMA vartest TO var_test_role; +CREATE VARIABLE vartest.x AS int; +CREATE VARIABLE vartest.y AS int; +LET vartest.x = 100; +LET vartest.y = 101; +GRANT SELECT ON ALL VARIABLES IN SCHEMA vartest TO var_test_role; +SET ROLE TO var_test_role; +SELECT vartest.x, vartest.y; + x | y +-----+----- + 100 | 101 +(1 row) + +SET ROLE TO DEFAULT; +REVOKE SELECT ON ALL VARIABLES IN SCHEMA vartest FROM var_test_role; +SET ROLE TO var_test_role; +-- should to fail +SELECT vartest.x; +ERROR: permission denied for session variable x +SELECT vartest.y; +ERROR: permission denied for session variable y +SET ROLE TO DEFAULT; +DROP VARIABLE vartest.x, vartest.y; +DROP SCHEMA vartest; +DROP ROLE var_test_role; +-- test cached plan +CREATE VARIABLE v1 AS text; +CREATE VARIABLE v2 AS int; +CREATE VARIABLE v3 AS int; +LET v1 = 'test'; +LET v2 = 10; +LET v3 = 5; +PREPARE q1 AS SELECT v1 || i FROM generate_series(1, v2) g(i) WHERE i IN (v2, v3); +SET plan_cache_mode to force_generic_plan; +EXECUTE q1; + ?column? +---------- + test5 + test10 +(2 rows) + +EXPLAIN EXECUTE q1; + QUERY PLAN +----------------------------------------------------------------------- + Function Scan on generate_series g (cost=0.00..0.14 rows=2 width=32) + Filter: (i = ANY (ARRAY[v2, v3])) +(2 rows) + +-- dependecy check +DROP VARIABLE v3; +-- recreate v3 again +CREATE VARIABLE v3 AS int DEFAULT 6; +-- should to work, the plan should be recreated +EXECUTE q1; + ?column? +---------- + test6 + test10 +(2 rows) + +DEALLOCATE q1; +-- fill v1 by long text +LET v1 = repeat(' ', 10000); +PREPARE q1 AS SELECT length(v1); +EXECUTE q1; + length +-------- + 10000 +(1 row) + +LET v1 = repeat(' ', 5000); +EXECUTE q1; + length +-------- + 5000 +(1 row) + +DEALLOCATE q1; +SET plan_cache_mode to default; +DROP VARIABLE v1, v2, v3; +CREATE ROLE var_test_role; +CREATE VARIABLE public.v1 AS int DEFAULT 0; +-- check acl when variable is acessed by simple eval expr method +CREATE OR REPLACE FUNCTION public.fx_var(int) +RETURNS int AS $$ +DECLARE xx int; +BEGIN + xx := public.v1 + $1; + RETURN xx; +END; +$$ LANGUAGE plpgsql; +-- should be ok +SELECT public.fx_var(0); + fx_var +-------- + 0 +(1 row) + +SET ROLE TO var_test_role; +-- should to fail +SELECT public.fx_var(0); +ERROR: permission denied for session variable v1 +CONTEXT: PL/pgSQL function public.fx_var(integer) line 4 at assignment +SET ROLE TO default; +GRANT SELECT ON VARIABLE public.v1 TO var_test_role; +SET ROLE TO var_test_role; +-- should be ok +SELECT public.fx_var(0); + fx_var +-------- + 0 +(1 row) + +SET ROLE TO default; +REVOKE SELECT ON VARIABLE public.v1 FROM var_test_role; +SET ROLE TO var_test_role; +-- should be fail +SELECT public.fx_var(0); +ERROR: permission denied for session variable v1 +CONTEXT: PL/pgSQL function public.fx_var(integer) line 4 at assignment +SET ROLE TO DEFAULT; +DROP FUNCTION public.fx_var(int); +DROP VARIABLE public.v1; +DROP ROLE var_test_role; +CREATE TYPE public.svar_test_type AS (a int, b int, c numeric); +CREATE VARIABLE public.svar AS public.svar_test_type; +LET public.svar = ROW(10,20,30); +SELECT public.svar; + svar +------------ + (10,20,30) +(1 row) + +ALTER TYPE public.svar_test_type DROP ATTRIBUTE c; +-- should be ok +SELECT public.svar; + svar +--------- + (10,20) +(1 row) + +ALTER TYPE public.svar_test_type ADD ATTRIBUTE c int; +-- should be ok +SELECT public.svar; + svar +---------- + (10,20,) +(1 row) + +LET public.svar = ROW(10,20,30); +-- should be ok again for new value +SELECT public.svar; + svar +------------ + (10,20,30) +(1 row) + +DROP VARIABLE public.svar; +DROP TYPE public.svar_test_type; +CREATE VARIABLE public.svar AS int; +select oid as varid from pg_variable where varname = 'svar' and varnamespace = 'public'::regnamespace \gset +SELECT schema, name, removed FROM pg_debug_show_used_session_variables(); + schema | name | removed +--------+------+--------- +(0 rows) + +LET public.svar = 100; +SELECT schema, name, removed FROM pg_debug_show_used_session_variables(); + schema | name | removed +--------+------+--------- + public | svar | f +(1 row) + +BEGIN; +DROP VARIABLE public.svar; +-- value should be in memory +SELECT schema, name, removed FROM pg_debug_show_used_session_variables(); + schema | name | removed +--------+------+--------- + | | t +(1 row) + +ROLLBACK; +-- value should be in memory +SELECT schema, name, removed FROM pg_debug_show_used_session_variables() f WHERE f.varid = :varid; + schema | name | removed +--------+------+--------- + public | svar | f +(1 row) + +SELECT public.svar; + svar +------ + 100 +(1 row) + +BEGIN; +DROP VARIABLE public.svar; +-- value should be in memory +SELECT schema, name, removed FROM pg_debug_show_used_session_variables() f WHERE f.varid = :varid;; + schema | name | removed +--------+------+--------- + | | t +(1 row) + +COMMIT; +-- the memory should be clean; +SELECT schema, name, removed FROM pg_debug_show_used_session_variables() WHERE f.varid = :varid; +ERROR: missing FROM-clause entry for table "f" +LINE 1: ...FROM pg_debug_show_used_session_variables() WHERE f.varid = ... + ^ +BEGIN; +CREATE VARIABLE public.svar AS int; +select oid as varid from pg_variable where varname = 'svar' and varnamespace = 'public'::regnamespace \gset +LET public.svar = 100; +ROLLBACK; +-- the memory should be clean; +SELECT schema, name, removed FROM pg_debug_show_used_session_variables() f WHERE f.varid = :varid; + schema | name | removed +--------+------+--------- +(0 rows) + +\unset varid +CREATE VARIABLE public.svar AS int; +LET public.svar = 100; +-- repeated aborted transaction +BEGIN; DROP VARIABLE public.svar; ROLLBACK; +BEGIN; DROP VARIABLE public.svar; ROLLBACK; +BEGIN; DROP VARIABLE public.svar; ROLLBACK; +-- the value should be still available +SELECT public.svar; + svar +------ + 100 +(1 row) + +DROP VARIABLE public.svar; +CREATE TYPE public.svar_test_type AS (a int, b int); +CREATE VARIABLE public.svar AS public.svar_test_type; +SELECT public.svar; + svar +------ + +(1 row) + +ALTER TYPE public.svar_test_type ADD ATTRIBUTE c int; +SELECT public.svar; + svar +------ + +(1 row) + +ALTER TYPE public.svar_test_type DROP ATTRIBUTE b; +SELECT public.svar; + svar +------ + +(1 row) + +DROP VARIABLE public.svar; +DROP TYPE public.svar_test_type; +CREATE TYPE public.svar_test_type AS (a int, b int); +CREATE VARIABLE public.svar AS public.svar_test_type; +CREATE VARIABLE public.svar2 AS public.svar_test_type; +LET public.svar = (10, 20); +ALTER TYPE public.svar_test_type ADD ATTRIBUTE c int; +SELECT public.svar; + svar +---------- + (10,20,) +(1 row) + +LET public.svar2 = (10, 20, 30); +ALTER TYPE public.svar_test_type DROP ATTRIBUTE b; +SELECT public.svar; + svar +------- + (10,) +(1 row) + +SELECT public.svar2; + svar2 +--------- + (10,30) +(1 row) + +DROP VARIABLE public.svar; +DROP VARIABLE public.svar2; +DROP TYPE public.svar_test_type; +-- The composite type cannot be changed when it is used +CREATE TYPE public.svar_type AS (a int, b int); +CREATE VARIABLE public.svar AS public.svar_type; +-- should to fail +ALTER TYPE public.svar_type ALTER ATTRIBUTE b TYPE numeric; +ERROR: cannot alter type "svar_type" because session variable "public.svar" uses it +DROP VARIABLE public.svar; +CREATE TYPE public.svar_type2 AS (a int, b int, c public.svar_type); +CREATE VARIABLE public.svar AS public.svar_type2; +-- should to fail +ALTER TYPE public.svar_type ALTER ATTRIBUTE b TYPE numeric; +ERROR: cannot alter type "svar_type" because session variable "public.svar" uses it +DROP VARIABLE public.svar; +DROP TYPE public.svar_type2; +DROP TYPE public.svar_type; +-- The variable can be shadowed by table or by alias +CREATE TYPE public.svar_type AS (a int, b int, c int); +CREATE VARIABLE public.svar AS public.svar_type; +CREATE TABLE public.svar (a int, b int); +INSERT INTO public.svar VALUES(10, 20); +LET public.svar = (100, 200, 300); +-- should be ok +-- show table +SELECT * FROM public.svar; + a | b +----+---- + 10 | 20 +(1 row) + +SELECT svar.a FROM public.svar; + a +---- + 10 +(1 row) + +SELECT svar.* FROM public.svar; + a | b +----+---- + 10 | 20 +(1 row) + +-- show variable +SELECT public.svar; + svar +--------------- + (100,200,300) +(1 row) + +SELECT public.svar.c; + c +----- + 300 +(1 row) + +SELECT (public.svar).*; + a | b | c +-----+-----+----- + 100 | 200 | 300 +(1 row) + +-- the variable is shadowed, raise error +SELECT public.svar.c FROM public.svar; +ERROR: column svar.c does not exist +LINE 1: SELECT public.svar.c FROM public.svar; + ^ +-- can be fixed by alias +SELECT public.svar.c FROM public.svar x; + c +----- + 300 +(1 row) + +-- again with warnings +SET session_variables_ambiguity_warning TO on; +SELECT * FROM public.svar; + a | b +----+---- + 10 | 20 +(1 row) + +SELECT svar.a FROM public.svar; + a +---- + 10 +(1 row) + +SELECT svar.* FROM public.svar; + a | b +----+---- + 10 | 20 +(1 row) + +-- show variable +SELECT public.svar; + svar +--------------- + (100,200,300) +(1 row) + +SELECT public.svar.c; + c +----- + 300 +(1 row) + +SELECT (public.svar).*; + a | b | c +-----+-----+----- + 100 | 200 | 300 +(1 row) + +-- the variable is shadowed, raise error +SELECT public.svar.c FROM public.svar; +WARNING: session variable "public.svar" is shadowed +LINE 1: SELECT public.svar.c FROM public.svar; + ^ +DETAIL: Session variables can be shadowed by tables or table's aliases with the same name. +ERROR: column svar.c does not exist +LINE 1: SELECT public.svar.c FROM public.svar; + ^ +-- can be fixed by alias +SELECT public.svar.c FROM public.svar x; + c +----- + 300 +(1 row) + +SET session_variables_ambiguity_warning TO DEFAULT; +DROP VARIABLE public.svar; +DROP TABLE public.svar; +DROP TYPE public.svar_type; diff --git a/src/test/regress/parallel_schedule b/src/test/regress/parallel_schedule index 9f644a0c1b..7426b39ab3 100644 --- a/src/test/regress/parallel_schedule +++ b/src/test/regress/parallel_schedule @@ -119,7 +119,7 @@ test: json jsonb json_encoding jsonpath jsonpath_encoding jsonb_jsonpath # NB: temp.sql does a reconnect which transiently uses 2 connections, # so keep this parallel group to at most 19 tests # ---------- -test: plancache limit plpgsql copy2 temp domain rangefuncs prepare conversion truncate alter_table sequence polymorphism rowtypes returning largeobject with xml +test: plancache limit plpgsql copy2 temp domain rangefuncs prepare conversion truncate alter_table sequence polymorphism rowtypes returning largeobject with xml session_variables # ---------- # Another group of parallel tests diff --git a/src/test/regress/sql/session_variables.sql b/src/test/regress/sql/session_variables.sql new file mode 100644 index 0000000000..d32bb5b042 --- /dev/null +++ b/src/test/regress/sql/session_variables.sql @@ -0,0 +1,959 @@ +CREATE SCHEMA svartest; + +SET search_path = svartest; + +CREATE VARIABLE var1 AS integer; +CREATE TEMP VARIABLE var2 AS text; + +DROP VARIABLE var1, var2; + +-- functional interface +CREATE VARIABLE var1 AS numeric; + +CREATE ROLE var_test_role; +GRANT USAGE ON SCHEMA svartest TO var_test_role; + +SET ROLE TO var_test_role; + +-- should fail +SELECT var1; + +SET ROLE TO DEFAULT; + +GRANT SELECT ON VARIABLE var1 TO var_test_role; + +SET ROLE TO var_test_role; +-- should fail +LET var1 = 10; +-- should work +SELECT var1; + +SET ROLE TO DEFAULT; + +GRANT UPDATE ON VARIABLE var1 TO var_test_role; + +SET ROLE TO var_test_role; + +-- should work +LET var1 = 333; + +SET ROLE TO DEFAULT; + +REVOKE ALL ON VARIABLE var1 FROM var_test_role; + +CREATE OR REPLACE FUNCTION secure_var() +RETURNS int AS $$ + SELECT svartest.var1::int; +$$ LANGUAGE sql SECURITY DEFINER; + +SELECT secure_var(); + +SET ROLE TO var_test_role; + +-- should fail +SELECT svartest.var1; + +-- should work; +SELECT secure_var(); + +SET ROLE TO DEFAULT; + +EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM generate_series(1,100) g(v) WHERE v = var1; + +CREATE VIEW schema_var_view AS SELECT var1; + +SELECT * FROM schema_var_view; + +\c - + +SET search_path = svartest; + +-- should work still, but var will be empty +SELECT * FROM schema_var_view; + +LET var1 = pi(); + +SELECT var1; + +-- we can see execution plan of LET statement +EXPLAIN (VERBOSE, COSTS OFF) LET var1 = pi(); + +SELECT var1; + +CREATE VARIABLE var3 AS int; + +CREATE OR REPLACE FUNCTION inc(int) +RETURNS int AS $$ +BEGIN + LET svartest.var3 = COALESCE(svartest.var3 + $1, $1); + RETURN var3; +END; +$$ LANGUAGE plpgsql; + +SELECT inc(1); +SELECT inc(1); +SELECT inc(1); + +SELECT inc(1) FROM generate_series(1,10); + +SET ROLE TO var_test_role; + +-- should fail +LET var3 = 0; + +SET ROLE TO DEFAULT; + +DROP VIEW schema_var_view; + +DROP VARIABLE var1 CASCADE; +DROP VARIABLE var3 CASCADE; + +-- composite variables + +CREATE TYPE sv_xyz AS (x int, y int, z numeric(10,2)); + +CREATE VARIABLE v1 AS sv_xyz; +CREATE VARIABLE v2 AS sv_xyz; + +\d v1 +\d v2 + +LET v1 = (1,2,3.14); +LET v2 = (10,20,3.14*10); + +-- should work too - there are prepared casts +LET v1 = (1,2,3.14); + +SELECT v1; +SELECT v2; +SELECT (v1).*; +SELECT (v2).*; + +SELECT v1.x + v1.z; +SELECT v2.x + v2.z; + +-- access to composite fields should be safe too +-- should fail +SET ROLE TO var_test_role; + +SELECT v2.x; + +SET ROLE TO DEFAULT; + +DROP VARIABLE v1; +DROP VARIABLE v2; + +REVOKE USAGE ON SCHEMA svartest FROM var_test_role; +DROP ROLE var_test_role; + +-- scalar variables should not be in conflict with qualified column +CREATE VARIABLE varx AS text; +SELECT varx.relname FROM pg_class varx WHERE varx.relname = 'pg_class'; + +-- should fail +SELECT varx.xxx; + +-- variables can be updated under RO transaction + +BEGIN; +SET TRANSACTION READ ONLY; +LET varx = 'hello'; +COMMIT; + +SELECT varx; + +DROP VARIABLE varx; + +CREATE TYPE t1 AS (a int, b numeric, c text); + +CREATE VARIABLE v1 AS t1; +LET v1 = (1, pi(), 'hello'); +SELECT v1; +LET v1.b = 10.2222; +SELECT v1; + +-- should fail +LET v1.x = 10; + +DROP VARIABLE v1; +DROP TYPE t1; + +-- arrays are supported +CREATE VARIABLE va1 AS numeric[]; +LET va1 = ARRAY[1.1,2.1]; +LET va1[1] = 10.1; +SELECT va1; + +CREATE TYPE ta2 AS (a numeric, b numeric[]); +CREATE VARIABLE va2 AS ta2; +LET va2 = (10.1, ARRAY[0.0, 0.0]); +LET va2.a = 10.2; +SELECT va2; +LET va2.b[1] = 10.3; +SELECT va2; + +DROP VARIABLE va1; +DROP VARIABLE va2; +DROP TYPE ta2; + +-- default values +CREATE VARIABLE v1 AS numeric DEFAULT pi(); +LET v1 = v1 * 2; +SELECT v1; + +CREATE TYPE t2 AS (a numeric, b text); +CREATE VARIABLE v2 AS t2 DEFAULT (NULL, 'Hello'); +LET svartest.v2.a = pi(); +SELECT v2; + +-- should fail due dependency +DROP TYPE t2; + +-- should be ok +DROP VARIABLE v1; +DROP VARIABLE v2; + +-- tests of alters +CREATE SCHEMA var_schema1; +CREATE SCHEMA var_schema2; + +CREATE VARIABLE var_schema1.var1 AS integer; +LET var_schema1.var1 = 1000; +SELECT var_schema1.var1; +ALTER VARIABLE var_schema1.var1 SET SCHEMA var_schema2; +SELECT var_schema2.var1; + +CREATE ROLE var_test_role; + +ALTER VARIABLE var_schema2.var1 OWNER TO var_test_role; +SET ROLE TO var_test_role; + +-- should fail, no access to schema var_schema2.var +SELECT var_schema2.var1; +DROP VARIABLE var_schema2.var1; + +SET ROLE TO DEFAULT; + +ALTER VARIABLE var_schema2.var1 SET SCHEMA public; + +SET ROLE TO var_test_role; +SELECT public.var1; + +ALTER VARIABLE public.var1 RENAME TO var1_renamed; + +SELECT public.var1_renamed; + +DROP VARIABLE public.var1_renamed; + +SET ROLE TO DEFAULt; + +-- default rights test +ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON VARIABLES TO var_test_role; + +CREATE VARIABLE public.var2 AS int; + +SET ROLE TO var_test_role; + +-- should be ok +LET public.var2 = 100; +SELECT public.var2; + +SET ROLE TO DEFAULt; + +DROP VARIABLE public.var2; +DROP OWNED BY var_test_role; + +DROP ROLE var_test_role; + +CREATE VARIABLE xx AS text DEFAULT 'hello'; + +SELECT xx, upper(xx); + +LET xx = 'Hi'; + +SELECT xx; + +DROP VARIABLE xx; + +-- ON TRANSACTION END RESET tests +CREATE VARIABLE t1 AS int DEFAULT -1 ON TRANSACTION END RESET; + +BEGIN; + SELECT t1; + LET t1 = 100; + SELECT t1; +COMMIT; + +SELECT t1; + +BEGIN; + SELECT t1; + LET t1 = 100; + SELECT t1; +ROLLBACK; + +SELECT t1; + +DROP VARIABLE t1; + +CREATE VARIABLE v1 AS int DEFAULT 0; +CREATE VARIABLE v2 AS text DEFAULT 'none'; + +LET v1 = 100; +LET v2 = 'Hello'; +SELECT v1, v2; +LET v1 = DEFAULT; +LET v2 = DEFAULT; +SELECT v1, v2; + +DROP VARIABLE v1; +DROP VARIABLE v2; + +-- ON COMMIT DROP tests +-- should be 0 always +SELECT count(*) FROM pg_variable; + +CREATE TEMP VARIABLE g AS int ON COMMIT DROP; + +SELECT count(*) FROM pg_variable; + +BEGIN; + CREATE TEMP VARIABLE g AS int ON COMMIT DROP; +COMMIT; + +SELECT count(*) FROM pg_variable; + +BEGIN; + CREATE TEMP VARIABLE g AS int ON COMMIT DROP; +ROLLBACK; + +SELECT count(*) FROM pg_variable; + +-- Encourage use of parallel plans +SET parallel_setup_cost = 0; +SET parallel_tuple_cost = 0; +SET min_parallel_table_scan_size = 0; +SET max_parallel_workers_per_gather = 2; + +-- test on query with workers +CREATE TABLE svar_test(a int); +INSERT INTO svar_test SELECT * FROM generate_series(1,1000); +ANALYZE svar_test; +CREATE VARIABLE zero int; +LET zero = 0; + +-- parallel workers should be used +EXPLAIN (costs off) SELECT count(*) FROM svar_test WHERE a%10 = zero; + +-- result should be 100 +SELECT count(*) FROM svar_test WHERE a%10 = zero; + +LET zero = (SELECT count(*) FROM svar_test); + +-- result should be 1000 +SELECT zero; + +-- parallel workers should be used +EXPLAIN (costs off) LET zero = (SELECT count(*) FROM svar_test); + +-- test for dependency on relation +CREATE VARIABLE v_table AS svar_test; + +ALTER TABLE svar_test ALTER COLUMN a TYPE text; + +DROP VARIABLE v_table; +DROP TABLE svar_test; +DROP VARIABLE zero; + +RESET parallel_setup_cost; +RESET parallel_tuple_cost; +RESET min_parallel_table_scan_size; +RESET max_parallel_workers_per_gather; + +-- use variables in prepared statements +CREATE VARIABLE v AS numeric; +LET v = 3.14; + +-- use variables in views +CREATE VIEW vv AS SELECT COALESCE(v, 0) + 1000 AS result; +SELECT * FROM vv; + +-- start a new session +\c + +SET search_path to svartest; + +SELECT * FROM vv; +LET v = 3.14; +SELECT * FROM vv; + +-- should fail, dependency +DROP VARIABLE v; + +-- should be ok +DROP VARIABLE v CASCADE; + +-- other features +CREATE VARIABLE dt AS integer DEFAULT 0; + +LET dt = 100; +SELECT dt; + +DISCARD VARIABLES; + +SELECT dt; + +DROP VARIABLE dt; + +-- NOT NULL +CREATE VARIABLE v1 AS int NOT NULL; +CREATE VARIABLE v2 AS int NOT NULL DEFAULT NULL; + +-- should fail +SELECT v1; +SELECT v2; +LET v1 = NULL; +LET v2 = NULL; +LET v1 = DEFAULT; +LET v2 = DEFAULT; + +-- should be ok +LET v1 = 100; +LET v2 = 1000; +SELECT v1, v2; + +DROP VARIABLE v1; +DROP VARIABLE v2; + +CREATE VARIABLE tv AS int; +CREATE VARIABLE IF NOT EXISTS tv AS int; +DROP VARIABLE tv; + +CREATE IMMUTABLE VARIABLE iv AS int DEFAULT 100; +SELECT iv; + +-- should fail; +LET iv = 10000; + +DROP VARIABLE iv; + +-- different order +CREATE IMMUTABLE VARIABLE iv AS int DEFAULT 100; +-- should to fail +LET iv = 10000; +-- should be ok +SELECT iv; + +DROP VARIABLE iv; + +CREATE IMMUTABLE VARIABLE iv AS int; + +-- should be ok +LET iv = NULL; + +-- should fail +LET iv = NULL; + +DROP VARIABLE iv; + +-- create variable inside plpgsql block +DO $$ +BEGIN + CREATE VARIABLE do_test_svar AS date DEFAULT '2000-01-01'; +END; +$$; + +SELECT do_test_svar; + +DROP VARIABLE do_test_svar; + +-- should fail +CREATE IMMUTABLE VARIABLE xx AS int NOT NULL; + + + +-- REASSIGN OWNED test +CREATE ROLE var_test_role1; +CREATE ROLE var_test_role2; + +CREATE VARIABLE xxx_var AS int; + +ALTER VARIABLE xxx_var OWNER TO var_test_role1; +REASSIGN OWNED BY var_test_role1 to var_test_role2; + +SELECT varowner::regrole FROM pg_variable WHERE varname = 'xxx_var'; + +DROP OWNED BY var_test_role1; +DROP ROLE var_test_role1; +SELECT count(*) FROM pg_variable WHERE varname = 'xxx_var'; + +DROP OWNED BY var_test_role2; +DROP ROLE var_test_role2; +SELECT count(*) FROM pg_variable WHERE varname = 'xxx_var'; + +-- creating, dropping temporary variable +BEGIN; + +CREATE TEMP VARIABLE tempvar AS INT ON COMMIT DROP; + +LET tempvar = 100; + +SAVEPOINT s1; + +DROP VARIABLE tempvar; + +ROLLBACK TO s1; + +SELECT tempvar; + +COMMIT; + +-- should to fail +LET tempvar = 100; + +BEGIN; + +SAVEPOINT s1; + +CREATE TEMP VARIABLE tempvar AS INT ON COMMIT DROP; + +LET tempvar = 100; + +ROLLBACK TO s1; + +COMMIT; + +-- should to fail +LET tempvar = 100; + +CREATE VARIABLE var1 AS int; +LET var1 = 100; +BEGIN; +DROP VARIABLE var1; +ROLLBACK; +SELECT var1; + +DROP VARIABLE var1; + +CREATE VARIABLE var1 AS int DEFAULT 100; +COMMENT ON VARIABLE var1 IS 'some variable comment'; + +SELECT pg_catalog.obj_description(oid, 'pg_variable') FROM pg_variable WHERE varname = 'var1'; + +DROP VARIABLE var1; + +CREATE TABLE xxtab(avar int); + +CREATE TYPE xxtype AS (avar int); + +CREATE VARIABLE xxtab AS xxtype; + +INSERT INTO xxtab VALUES(10); + +-- it is ambiguous, but columns are preferred +-- variable is shadowed +SELECT xxtab.avar FROM xxtab; + +SET session_variables_ambiguity_warning TO on; + +SELECT xxtab.avar FROM xxtab; + +SET search_path = svartest; + +CREATE VARIABLE testvar as int; + +-- plpgsql variables are preferred against session variables +DO $$ +<<myblock>> +DECLARE testvar int; +BEGIN + -- should be ok without warning + LET testvar = 100; + -- should be ok without warning + testvar := 1000; + -- should be ok without warning + RAISE NOTICE 'session variable is %', svartest.testvar; + -- should be ok without warning + RAISE NOTICE 'plpgsql variable is %', myblock.testvar; + -- should to print plpgsql variable with warning + RAISE NOTICE 'variable is %', testvar; +END; +$$; + +DROP VARIABLE testvar; + +SET session_variables_ambiguity_warning TO default; + +-- should be ok +SELECT avar FROM xxtab; + +CREATE VARIABLE public.avar AS int; + +-- should be ok, see the table +SELECT avar FROM xxtab; + +-- should be ok +SELECT public.avar FROM xxtab; + +DROP VARIABLE xxtab; + +SELECT xxtab.avar FROM xxtab; + +DROP VARIABLE public.avar; + +DROP TYPE xxtype; + +DROP TABLE xxtab; + +-- test of plan cache invalidation +CREATE VARIABLE xx AS int; + +SET plan_cache_mode = force_generic_plan; + +PREPARE pp AS SELECT xx; + +EXECUTE pp; + +DROP VARIABLE xx; + +CREATE VARIABLE xx AS int; + +-- should to work +EXECUTE pp; + +DROP VARIABLE xx; + +DEALLOCATE pp; + +SET plan_cache_mode = DEFAULT; + +CREATE ROLE var_test_role; + +CREATE SCHEMA vartest; + +GRANT USAGE ON SCHEMA vartest TO var_test_role; + +CREATE VARIABLE vartest.x AS int; +CREATE VARIABLE vartest.y AS int; + +LET vartest.x = 100; +LET vartest.y = 101; + +GRANT SELECT ON ALL VARIABLES IN SCHEMA vartest TO var_test_role; + +SET ROLE TO var_test_role; + +SELECT vartest.x, vartest.y; + +SET ROLE TO DEFAULT; + +REVOKE SELECT ON ALL VARIABLES IN SCHEMA vartest FROM var_test_role; + +SET ROLE TO var_test_role; + +-- should to fail +SELECT vartest.x; +SELECT vartest.y; + +SET ROLE TO DEFAULT; + +DROP VARIABLE vartest.x, vartest.y; + +DROP SCHEMA vartest; + +DROP ROLE var_test_role; + +-- test cached plan +CREATE VARIABLE v1 AS text; +CREATE VARIABLE v2 AS int; +CREATE VARIABLE v3 AS int; + +LET v1 = 'test'; +LET v2 = 10; +LET v3 = 5; + +PREPARE q1 AS SELECT v1 || i FROM generate_series(1, v2) g(i) WHERE i IN (v2, v3); + +SET plan_cache_mode to force_generic_plan; + +EXECUTE q1; + +EXPLAIN EXECUTE q1; + +-- dependecy check +DROP VARIABLE v3; + +-- recreate v3 again +CREATE VARIABLE v3 AS int DEFAULT 6; + +-- should to work, the plan should be recreated +EXECUTE q1; + +DEALLOCATE q1; + +-- fill v1 by long text +LET v1 = repeat(' ', 10000); + +PREPARE q1 AS SELECT length(v1); + +EXECUTE q1; + +LET v1 = repeat(' ', 5000); + +EXECUTE q1; + +DEALLOCATE q1; + +SET plan_cache_mode to default; + +DROP VARIABLE v1, v2, v3; + +CREATE ROLE var_test_role; + +CREATE VARIABLE public.v1 AS int DEFAULT 0; + +-- check acl when variable is acessed by simple eval expr method +CREATE OR REPLACE FUNCTION public.fx_var(int) +RETURNS int AS $$ +DECLARE xx int; +BEGIN + xx := public.v1 + $1; + RETURN xx; +END; +$$ LANGUAGE plpgsql; + +-- should be ok +SELECT public.fx_var(0); + +SET ROLE TO var_test_role; + +-- should to fail +SELECT public.fx_var(0); + +SET ROLE TO default; + +GRANT SELECT ON VARIABLE public.v1 TO var_test_role; + +SET ROLE TO var_test_role; + +-- should be ok +SELECT public.fx_var(0); + +SET ROLE TO default; + +REVOKE SELECT ON VARIABLE public.v1 FROM var_test_role; + +SET ROLE TO var_test_role; + +-- should be fail +SELECT public.fx_var(0); + +SET ROLE TO DEFAULT; + +DROP FUNCTION public.fx_var(int); + +DROP VARIABLE public.v1; + +DROP ROLE var_test_role; + +CREATE TYPE public.svar_test_type AS (a int, b int, c numeric); + +CREATE VARIABLE public.svar AS public.svar_test_type; + +LET public.svar = ROW(10,20,30); + +SELECT public.svar; + +ALTER TYPE public.svar_test_type DROP ATTRIBUTE c; + +-- should be ok +SELECT public.svar; + +ALTER TYPE public.svar_test_type ADD ATTRIBUTE c int; + +-- should be ok +SELECT public.svar; + +LET public.svar = ROW(10,20,30); + +-- should be ok again for new value +SELECT public.svar; + +DROP VARIABLE public.svar; + +DROP TYPE public.svar_test_type; + +CREATE VARIABLE public.svar AS int; +select oid as varid from pg_variable where varname = 'svar' and varnamespace = 'public'::regnamespace \gset + +SELECT schema, name, removed FROM pg_debug_show_used_session_variables(); + +LET public.svar = 100; + +SELECT schema, name, removed FROM pg_debug_show_used_session_variables(); + +BEGIN; + +DROP VARIABLE public.svar; + +-- value should be in memory +SELECT schema, name, removed FROM pg_debug_show_used_session_variables(); + +ROLLBACK; + +-- value should be in memory +SELECT schema, name, removed FROM pg_debug_show_used_session_variables() f WHERE f.varid = :varid; + +SELECT public.svar; + +BEGIN; + +DROP VARIABLE public.svar; + +-- value should be in memory +SELECT schema, name, removed FROM pg_debug_show_used_session_variables() f WHERE f.varid = :varid;; + +COMMIT; + +-- the memory should be clean; +SELECT schema, name, removed FROM pg_debug_show_used_session_variables() WHERE f.varid = :varid; + +BEGIN; + +CREATE VARIABLE public.svar AS int; +select oid as varid from pg_variable where varname = 'svar' and varnamespace = 'public'::regnamespace \gset + + +LET public.svar = 100; + +ROLLBACK; + +-- the memory should be clean; +SELECT schema, name, removed FROM pg_debug_show_used_session_variables() f WHERE f.varid = :varid; + +\unset varid + +CREATE VARIABLE public.svar AS int; + +LET public.svar = 100; + +-- repeated aborted transaction +BEGIN; DROP VARIABLE public.svar; ROLLBACK; +BEGIN; DROP VARIABLE public.svar; ROLLBACK; +BEGIN; DROP VARIABLE public.svar; ROLLBACK; + +-- the value should be still available +SELECT public.svar; + +DROP VARIABLE public.svar; + +CREATE TYPE public.svar_test_type AS (a int, b int); + +CREATE VARIABLE public.svar AS public.svar_test_type; + +SELECT public.svar; + +ALTER TYPE public.svar_test_type ADD ATTRIBUTE c int; + +SELECT public.svar; + +ALTER TYPE public.svar_test_type DROP ATTRIBUTE b; + +SELECT public.svar; + +DROP VARIABLE public.svar; +DROP TYPE public.svar_test_type; + +CREATE TYPE public.svar_test_type AS (a int, b int); + +CREATE VARIABLE public.svar AS public.svar_test_type; +CREATE VARIABLE public.svar2 AS public.svar_test_type; + +LET public.svar = (10, 20); + +ALTER TYPE public.svar_test_type ADD ATTRIBUTE c int; + +SELECT public.svar; + +LET public.svar2 = (10, 20, 30); + +ALTER TYPE public.svar_test_type DROP ATTRIBUTE b; + +SELECT public.svar; +SELECT public.svar2; + +DROP VARIABLE public.svar; +DROP VARIABLE public.svar2; +DROP TYPE public.svar_test_type; + +-- The composite type cannot be changed when it is used +CREATE TYPE public.svar_type AS (a int, b int); + +CREATE VARIABLE public.svar AS public.svar_type; + +-- should to fail +ALTER TYPE public.svar_type ALTER ATTRIBUTE b TYPE numeric; + +DROP VARIABLE public.svar; + +CREATE TYPE public.svar_type2 AS (a int, b int, c public.svar_type); + +CREATE VARIABLE public.svar AS public.svar_type2; + +-- should to fail +ALTER TYPE public.svar_type ALTER ATTRIBUTE b TYPE numeric; + +DROP VARIABLE public.svar; +DROP TYPE public.svar_type2; +DROP TYPE public.svar_type; + +-- The variable can be shadowed by table or by alias +CREATE TYPE public.svar_type AS (a int, b int, c int); +CREATE VARIABLE public.svar AS public.svar_type; + +CREATE TABLE public.svar (a int, b int); + +INSERT INTO public.svar VALUES(10, 20); + +LET public.svar = (100, 200, 300); + +-- should be ok +-- show table +SELECT * FROM public.svar; +SELECT svar.a FROM public.svar; +SELECT svar.* FROM public.svar; + +-- show variable +SELECT public.svar; +SELECT public.svar.c; +SELECT (public.svar).*; + +-- the variable is shadowed, raise error +SELECT public.svar.c FROM public.svar; + +-- can be fixed by alias +SELECT public.svar.c FROM public.svar x; + +-- again with warnings +SET session_variables_ambiguity_warning TO on; + +SELECT * FROM public.svar; +SELECT svar.a FROM public.svar; +SELECT svar.* FROM public.svar; + +-- show variable +SELECT public.svar; +SELECT public.svar.c; +SELECT (public.svar).*; + +-- the variable is shadowed, raise error +SELECT public.svar.c FROM public.svar; + +-- can be fixed by alias +SELECT public.svar.c FROM public.svar x; + +SET session_variables_ambiguity_warning TO DEFAULT; + +DROP VARIABLE public.svar; +DROP TABLE public.svar; +DROP TYPE public.svar_type; -- 2.37.0 --w2in66fnadvggvsb Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="v20220916-0011-FIXUP-regress-tests-for-session-variables.patch" ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v4 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use proargdefaults to handle the optional pretty argument. --- src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 6 ++---- 2 files changed, 2 insertions(+), 18 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index a70807e84ca..27be4501e12 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -808,20 +808,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 69c1e5bb264..b43cbb62b82 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -3984,9 +3984,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8566,7 +8563,8 @@ prosrc => 'pg_timezone_names' }, { oid => '2730', descr => 'trigger description with pretty-print option', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', proargnames => '{trigger,pretty}', + proargdefaults => '{false}', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.43.0 --eEEy3EHc57lA8spa-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v1 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use CREATE OR REPLACE FUNCTION to handle the optional pretty argument. --- src/backend/catalog/system_functions.sql | 7 +++++++ src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 5 +---- 3 files changed, 8 insertions(+), 18 deletions(-) diff --git a/src/backend/catalog/system_functions.sql b/src/backend/catalog/system_functions.sql index 81d210a9c45..c9c011ea5c1 100644 --- a/src/backend/catalog/system_functions.sql +++ b/src/backend/catalog/system_functions.sql @@ -699,6 +699,13 @@ LANGUAGE INTERNAL PARALLEL SAFE AS 'pg_get_expr'; +CREATE OR REPLACE FUNCTION + pg_get_triggerdef(trigger oid, pretty bool DEFAULT false) +RETURNS TEXT +LANGUAGE INTERNAL +PARALLEL SAFE +AS 'pg_get_triggerdef'; + -- -- The default permissions for functions mean that anyone can execute them. -- A number of functions shouldn't be executable by just anyone, but rather diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 9effa02fa2e..45a35f823e8 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -807,20 +807,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 10c5286bd7d..146963c254b 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -3974,9 +3974,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8535,7 +8532,7 @@ prosrc => 'pg_timezone_names' }, { oid => '2730', descr => 'trigger description with pretty-print option', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.51.2 --IRGsBYp1UN8d6WrT-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v2 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use CREATE OR REPLACE FUNCTION to handle the optional pretty argument. --- src/backend/catalog/system_functions.sql | 7 +++++++ src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 5 +---- 3 files changed, 8 insertions(+), 18 deletions(-) diff --git a/src/backend/catalog/system_functions.sql b/src/backend/catalog/system_functions.sql index a6f7cdf3a36..08b9b68d0cd 100644 --- a/src/backend/catalog/system_functions.sql +++ b/src/backend/catalog/system_functions.sql @@ -699,6 +699,13 @@ LANGUAGE INTERNAL PARALLEL SAFE AS 'pg_get_expr'; +CREATE OR REPLACE FUNCTION + pg_get_triggerdef(trigger oid, pretty bool DEFAULT false) +RETURNS TEXT +LANGUAGE INTERNAL +PARALLEL SAFE +AS 'pg_get_triggerdef'; + -- -- The default permissions for functions mean that anyone can execute them. -- A number of functions shouldn't be executable by just anyone, but rather diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 305e3e80c41..188d367b113 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -807,20 +807,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 3a0be2d4b2a..d644a391e0e 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -3983,9 +3983,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8551,7 +8548,7 @@ prosrc => 'pg_timezone_names' }, { oid => '2730', descr => 'trigger description with pretty-print option', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.43.0 --3/nz5wg6+DYwHsLU-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v8.1 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use proargdefaults to handle the optional pretty argument. --- src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 8 +++----- 2 files changed, 3 insertions(+), 19 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index e60478677e0..bfa5ef7910b 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -818,20 +818,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index df43469be3d..7cccfe6d7a7 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -4003,9 +4003,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8640,9 +8637,10 @@ proallargtypes => '{text,text,interval,bool}', proargmodes => '{o,o,o,o}', proargnames => '{name,abbrev,utc_offset,is_dst}', prosrc => 'pg_timezone_names' }, -{ oid => '2730', descr => 'trigger description with pretty-print option', +{ oid => '2730', descr => 'trigger description', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', proargnames => '{trigger,pretty}', + proargdefaults => '{false}', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.53.0 --AcCatzXgbvyipyEy-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v8.1 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use proargdefaults to handle the optional pretty argument. --- src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 8 +++----- 2 files changed, 3 insertions(+), 19 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index e60478677e0..bfa5ef7910b 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -818,20 +818,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index df43469be3d..7cccfe6d7a7 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -4003,9 +4003,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8640,9 +8637,10 @@ proallargtypes => '{text,text,interval,bool}', proargmodes => '{o,o,o,o}', proargnames => '{name,abbrev,utc_offset,is_dst}', prosrc => 'pg_timezone_names' }, -{ oid => '2730', descr => 'trigger description with pretty-print option', +{ oid => '2730', descr => 'trigger description', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', proargnames => '{trigger,pretty}', + proargdefaults => '{false}', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.53.0 --AcCatzXgbvyipyEy-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v5 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use proargdefaults to handle the optional pretty argument. --- src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 6 ++---- 2 files changed, 2 insertions(+), 18 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 972f89eafbc..bd0ca6891c3 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -818,20 +818,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index f36f4625e50..43844bb6862 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -3997,9 +3997,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8630,7 +8627,8 @@ prosrc => 'pg_timezone_names' }, { oid => '2730', descr => 'trigger description with pretty-print option', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', proargnames => '{trigger,pretty}', + proargdefaults => '{false}', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.52.0 --m23X5uHFNxthGTU3-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v8 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use proargdefaults to handle the optional pretty argument. --- src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 8 +++----- 2 files changed, 3 insertions(+), 19 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index e60478677e0..bfa5ef7910b 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -818,20 +818,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 71bd2aaf3d9..d7a6493dd19 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -4003,9 +4003,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8640,9 +8637,10 @@ proallargtypes => '{text,text,interval,bool}', proargmodes => '{o,o,o,o}', proargnames => '{name,abbrev,utc_offset,is_dst}', prosrc => 'pg_timezone_names' }, -{ oid => '2730', descr => 'trigger description with pretty-print option', +{ oid => '2730', descr => 'trigger description', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', proargnames => '{trigger,pretty}', + proargdefaults => '{false}', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.53.0 --iWwo79nqhOvOs5kf-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v4 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use proargdefaults to handle the optional pretty argument. --- src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 6 ++---- 2 files changed, 2 insertions(+), 18 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index a70807e84ca..27be4501e12 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -808,20 +808,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 69c1e5bb264..b43cbb62b82 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -3984,9 +3984,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8566,7 +8563,8 @@ prosrc => 'pg_timezone_names' }, { oid => '2730', descr => 'trigger description with pretty-print option', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', proargnames => '{trigger,pretty}', + proargdefaults => '{false}', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.43.0 --eEEy3EHc57lA8spa-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v7 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use proargdefaults to handle the optional pretty argument. --- src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 8 +++----- 2 files changed, 3 insertions(+), 19 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 707f83d4310..249f4518f62 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -818,20 +818,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 855529509de..f4df55370e7 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -4003,9 +4003,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8673,9 +8670,10 @@ proallargtypes => '{text,text,interval,bool}', proargmodes => '{o,o,o,o}', proargnames => '{name,abbrev,utc_offset,is_dst}', prosrc => 'pg_timezone_names' }, -{ oid => '2730', descr => 'trigger description with pretty-print option', +{ oid => '2730', descr => 'trigger description', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', proargnames => '{trigger,pretty}', + proargdefaults => '{false}', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.52.0 --GzYugJnip6WHHvTk-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v1 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use CREATE OR REPLACE FUNCTION to handle the optional pretty argument. --- src/backend/catalog/system_functions.sql | 7 +++++++ src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 5 +---- 3 files changed, 8 insertions(+), 18 deletions(-) diff --git a/src/backend/catalog/system_functions.sql b/src/backend/catalog/system_functions.sql index 81d210a9c45..c9c011ea5c1 100644 --- a/src/backend/catalog/system_functions.sql +++ b/src/backend/catalog/system_functions.sql @@ -699,6 +699,13 @@ LANGUAGE INTERNAL PARALLEL SAFE AS 'pg_get_expr'; +CREATE OR REPLACE FUNCTION + pg_get_triggerdef(trigger oid, pretty bool DEFAULT false) +RETURNS TEXT +LANGUAGE INTERNAL +PARALLEL SAFE +AS 'pg_get_triggerdef'; + -- -- The default permissions for functions mean that anyone can execute them. -- A number of functions shouldn't be executable by just anyone, but rather diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 9effa02fa2e..45a35f823e8 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -807,20 +807,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 10c5286bd7d..146963c254b 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -3974,9 +3974,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8535,7 +8532,7 @@ prosrc => 'pg_timezone_names' }, { oid => '2730', descr => 'trigger description with pretty-print option', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.51.2 --IRGsBYp1UN8d6WrT-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v5 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use proargdefaults to handle the optional pretty argument. --- src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 6 ++---- 2 files changed, 2 insertions(+), 18 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 972f89eafbc..bd0ca6891c3 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -818,20 +818,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index f36f4625e50..43844bb6862 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -3997,9 +3997,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8630,7 +8627,8 @@ prosrc => 'pg_timezone_names' }, { oid => '2730', descr => 'trigger description with pretty-print option', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', proargnames => '{trigger,pretty}', + proargdefaults => '{false}', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.52.0 --m23X5uHFNxthGTU3-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v7 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use proargdefaults to handle the optional pretty argument. --- src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 8 +++----- 2 files changed, 3 insertions(+), 19 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 707f83d4310..249f4518f62 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -818,20 +818,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 855529509de..f4df55370e7 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -4003,9 +4003,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8673,9 +8670,10 @@ proallargtypes => '{text,text,interval,bool}', proargmodes => '{o,o,o,o}', proargnames => '{name,abbrev,utc_offset,is_dst}', prosrc => 'pg_timezone_names' }, -{ oid => '2730', descr => 'trigger description with pretty-print option', +{ oid => '2730', descr => 'trigger description', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', proargnames => '{trigger,pretty}', + proargdefaults => '{false}', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.52.0 --GzYugJnip6WHHvTk-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v3 7/7] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use CREATE OR REPLACE FUNCTION to handle the optional pretty argument. --- src/backend/catalog/system_functions.sql | 7 +++++++ src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 5 +---- src/include/catalog/pg_retired.dat | 1 + 4 files changed, 9 insertions(+), 18 deletions(-) diff --git a/src/backend/catalog/system_functions.sql b/src/backend/catalog/system_functions.sql index a6f7cdf3a36..08b9b68d0cd 100644 --- a/src/backend/catalog/system_functions.sql +++ b/src/backend/catalog/system_functions.sql @@ -699,6 +699,13 @@ LANGUAGE INTERNAL PARALLEL SAFE AS 'pg_get_expr'; +CREATE OR REPLACE FUNCTION + pg_get_triggerdef(trigger oid, pretty bool DEFAULT false) +RETURNS TEXT +LANGUAGE INTERNAL +PARALLEL SAFE +AS 'pg_get_triggerdef'; + -- -- The default permissions for functions mean that anyone can execute them. -- A number of functions shouldn't be executable by just anyone, but rather diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index d87b361a093..598c916ddb6 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -807,20 +807,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 4304ab220ba..bf00983b3ff 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -3983,9 +3983,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8551,7 +8548,7 @@ prosrc => 'pg_timezone_names' }, { oid => '2730', descr => 'trigger description with pretty-print option', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', diff --git a/src/include/catalog/pg_retired.dat b/src/include/catalog/pg_retired.dat index 8b5f58850f6..46764648040 100644 --- a/src/include/catalog/pg_retired.dat +++ b/src/include/catalog/pg_retired.dat @@ -22,6 +22,7 @@ { oid => '1640', proname => 'pg_get_viewdef' }, { oid => '1641', proname => 'pg_get_viewdef' }, { oid => '1643', proname => 'pg_get_indexdef' }, +{ oid => '1662', proname => 'pg_get_triggerdef' }, { oid => '1716', proname => 'pg_get_expr' } ] -- 2.43.0 --zd8Z8rlPOcTi77n/-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v1 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use CREATE OR REPLACE FUNCTION to handle the optional pretty argument. --- src/backend/catalog/system_functions.sql | 7 +++++++ src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 5 +---- 3 files changed, 8 insertions(+), 18 deletions(-) diff --git a/src/backend/catalog/system_functions.sql b/src/backend/catalog/system_functions.sql index 81d210a9c45..c9c011ea5c1 100644 --- a/src/backend/catalog/system_functions.sql +++ b/src/backend/catalog/system_functions.sql @@ -699,6 +699,13 @@ LANGUAGE INTERNAL PARALLEL SAFE AS 'pg_get_expr'; +CREATE OR REPLACE FUNCTION + pg_get_triggerdef(trigger oid, pretty bool DEFAULT false) +RETURNS TEXT +LANGUAGE INTERNAL +PARALLEL SAFE +AS 'pg_get_triggerdef'; + -- -- The default permissions for functions mean that anyone can execute them. -- A number of functions shouldn't be executable by just anyone, but rather diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 9effa02fa2e..45a35f823e8 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -807,20 +807,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 10c5286bd7d..146963c254b 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -3974,9 +3974,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8535,7 +8532,7 @@ prosrc => 'pg_timezone_names' }, { oid => '2730', descr => 'trigger description with pretty-print option', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.51.2 --IRGsBYp1UN8d6WrT-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v1 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use CREATE OR REPLACE FUNCTION to handle the optional pretty argument. --- src/backend/catalog/system_functions.sql | 7 +++++++ src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 5 +---- 3 files changed, 8 insertions(+), 18 deletions(-) diff --git a/src/backend/catalog/system_functions.sql b/src/backend/catalog/system_functions.sql index 81d210a9c45..c9c011ea5c1 100644 --- a/src/backend/catalog/system_functions.sql +++ b/src/backend/catalog/system_functions.sql @@ -699,6 +699,13 @@ LANGUAGE INTERNAL PARALLEL SAFE AS 'pg_get_expr'; +CREATE OR REPLACE FUNCTION + pg_get_triggerdef(trigger oid, pretty bool DEFAULT false) +RETURNS TEXT +LANGUAGE INTERNAL +PARALLEL SAFE +AS 'pg_get_triggerdef'; + -- -- The default permissions for functions mean that anyone can execute them. -- A number of functions shouldn't be executable by just anyone, but rather diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 9effa02fa2e..45a35f823e8 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -807,20 +807,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 10c5286bd7d..146963c254b 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -3974,9 +3974,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8535,7 +8532,7 @@ prosrc => 'pg_timezone_names' }, { oid => '2730', descr => 'trigger description with pretty-print option', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.51.2 --IRGsBYp1UN8d6WrT-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v2 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use CREATE OR REPLACE FUNCTION to handle the optional pretty argument. --- src/backend/catalog/system_functions.sql | 7 +++++++ src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 5 +---- 3 files changed, 8 insertions(+), 18 deletions(-) diff --git a/src/backend/catalog/system_functions.sql b/src/backend/catalog/system_functions.sql index a6f7cdf3a36..08b9b68d0cd 100644 --- a/src/backend/catalog/system_functions.sql +++ b/src/backend/catalog/system_functions.sql @@ -699,6 +699,13 @@ LANGUAGE INTERNAL PARALLEL SAFE AS 'pg_get_expr'; +CREATE OR REPLACE FUNCTION + pg_get_triggerdef(trigger oid, pretty bool DEFAULT false) +RETURNS TEXT +LANGUAGE INTERNAL +PARALLEL SAFE +AS 'pg_get_triggerdef'; + -- -- The default permissions for functions mean that anyone can execute them. -- A number of functions shouldn't be executable by just anyone, but rather diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 305e3e80c41..188d367b113 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -807,20 +807,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 3a0be2d4b2a..d644a391e0e 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -3983,9 +3983,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8551,7 +8548,7 @@ prosrc => 'pg_timezone_names' }, { oid => '2730', descr => 'trigger description with pretty-print option', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.43.0 --3/nz5wg6+DYwHsLU-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v5 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use proargdefaults to handle the optional pretty argument. --- src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 6 ++---- 2 files changed, 2 insertions(+), 18 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 972f89eafbc..bd0ca6891c3 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -818,20 +818,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index f36f4625e50..43844bb6862 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -3997,9 +3997,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8630,7 +8627,8 @@ prosrc => 'pg_timezone_names' }, { oid => '2730', descr => 'trigger description with pretty-print option', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', proargnames => '{trigger,pretty}', + proargdefaults => '{false}', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.52.0 --m23X5uHFNxthGTU3-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v1 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use CREATE OR REPLACE FUNCTION to handle the optional pretty argument. --- src/backend/catalog/system_functions.sql | 7 +++++++ src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 5 +---- 3 files changed, 8 insertions(+), 18 deletions(-) diff --git a/src/backend/catalog/system_functions.sql b/src/backend/catalog/system_functions.sql index 81d210a9c45..c9c011ea5c1 100644 --- a/src/backend/catalog/system_functions.sql +++ b/src/backend/catalog/system_functions.sql @@ -699,6 +699,13 @@ LANGUAGE INTERNAL PARALLEL SAFE AS 'pg_get_expr'; +CREATE OR REPLACE FUNCTION + pg_get_triggerdef(trigger oid, pretty bool DEFAULT false) +RETURNS TEXT +LANGUAGE INTERNAL +PARALLEL SAFE +AS 'pg_get_triggerdef'; + -- -- The default permissions for functions mean that anyone can execute them. -- A number of functions shouldn't be executable by just anyone, but rather diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 9effa02fa2e..45a35f823e8 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -807,20 +807,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 10c5286bd7d..146963c254b 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -3974,9 +3974,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8535,7 +8532,7 @@ prosrc => 'pg_timezone_names' }, { oid => '2730', descr => 'trigger description with pretty-print option', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.51.2 --IRGsBYp1UN8d6WrT-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v4 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use proargdefaults to handle the optional pretty argument. --- src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 6 ++---- 2 files changed, 2 insertions(+), 18 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index a70807e84ca..27be4501e12 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -808,20 +808,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 69c1e5bb264..b43cbb62b82 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -3984,9 +3984,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8566,7 +8563,8 @@ prosrc => 'pg_timezone_names' }, { oid => '2730', descr => 'trigger description with pretty-print option', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', proargnames => '{trigger,pretty}', + proargdefaults => '{false}', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.43.0 --eEEy3EHc57lA8spa-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v4 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use proargdefaults to handle the optional pretty argument. --- src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 6 ++---- 2 files changed, 2 insertions(+), 18 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index a70807e84ca..27be4501e12 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -808,20 +808,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 69c1e5bb264..b43cbb62b82 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -3984,9 +3984,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8566,7 +8563,8 @@ prosrc => 'pg_timezone_names' }, { oid => '2730', descr => 'trigger description with pretty-print option', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', proargnames => '{trigger,pretty}', + proargdefaults => '{false}', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.43.0 --eEEy3EHc57lA8spa-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v5 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use proargdefaults to handle the optional pretty argument. --- src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 6 ++---- 2 files changed, 2 insertions(+), 18 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 972f89eafbc..bd0ca6891c3 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -818,20 +818,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index f36f4625e50..43844bb6862 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -3997,9 +3997,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8630,7 +8627,8 @@ prosrc => 'pg_timezone_names' }, { oid => '2730', descr => 'trigger description with pretty-print option', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', proargnames => '{trigger,pretty}', + proargdefaults => '{false}', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.52.0 --m23X5uHFNxthGTU3-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v4 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use proargdefaults to handle the optional pretty argument. --- src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 6 ++---- 2 files changed, 2 insertions(+), 18 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index a70807e84ca..27be4501e12 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -808,20 +808,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 69c1e5bb264..b43cbb62b82 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -3984,9 +3984,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8566,7 +8563,8 @@ prosrc => 'pg_timezone_names' }, { oid => '2730', descr => 'trigger description with pretty-print option', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', proargnames => '{trigger,pretty}', + proargdefaults => '{false}', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.43.0 --eEEy3EHc57lA8spa-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v8.1 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use proargdefaults to handle the optional pretty argument. --- src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 8 +++----- 2 files changed, 3 insertions(+), 19 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index e60478677e0..bfa5ef7910b 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -818,20 +818,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index df43469be3d..7cccfe6d7a7 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -4003,9 +4003,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8640,9 +8637,10 @@ proallargtypes => '{text,text,interval,bool}', proargmodes => '{o,o,o,o}', proargnames => '{name,abbrev,utc_offset,is_dst}', prosrc => 'pg_timezone_names' }, -{ oid => '2730', descr => 'trigger description with pretty-print option', +{ oid => '2730', descr => 'trigger description', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', proargnames => '{trigger,pretty}', + proargdefaults => '{false}', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.53.0 --AcCatzXgbvyipyEy-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v2 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use CREATE OR REPLACE FUNCTION to handle the optional pretty argument. --- src/backend/catalog/system_functions.sql | 7 +++++++ src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 5 +---- 3 files changed, 8 insertions(+), 18 deletions(-) diff --git a/src/backend/catalog/system_functions.sql b/src/backend/catalog/system_functions.sql index a6f7cdf3a36..08b9b68d0cd 100644 --- a/src/backend/catalog/system_functions.sql +++ b/src/backend/catalog/system_functions.sql @@ -699,6 +699,13 @@ LANGUAGE INTERNAL PARALLEL SAFE AS 'pg_get_expr'; +CREATE OR REPLACE FUNCTION + pg_get_triggerdef(trigger oid, pretty bool DEFAULT false) +RETURNS TEXT +LANGUAGE INTERNAL +PARALLEL SAFE +AS 'pg_get_triggerdef'; + -- -- The default permissions for functions mean that anyone can execute them. -- A number of functions shouldn't be executable by just anyone, but rather diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 305e3e80c41..188d367b113 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -807,20 +807,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 3a0be2d4b2a..d644a391e0e 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -3983,9 +3983,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8551,7 +8548,7 @@ prosrc => 'pg_timezone_names' }, { oid => '2730', descr => 'trigger description with pretty-print option', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.43.0 --3/nz5wg6+DYwHsLU-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v8.1 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use proargdefaults to handle the optional pretty argument. --- src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 8 +++----- 2 files changed, 3 insertions(+), 19 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index e60478677e0..bfa5ef7910b 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -818,20 +818,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index df43469be3d..7cccfe6d7a7 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -4003,9 +4003,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8640,9 +8637,10 @@ proallargtypes => '{text,text,interval,bool}', proargmodes => '{o,o,o,o}', proargnames => '{name,abbrev,utc_offset,is_dst}', prosrc => 'pg_timezone_names' }, -{ oid => '2730', descr => 'trigger description with pretty-print option', +{ oid => '2730', descr => 'trigger description', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', proargnames => '{trigger,pretty}', + proargdefaults => '{false}', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.53.0 --AcCatzXgbvyipyEy-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v8 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use proargdefaults to handle the optional pretty argument. --- src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 8 +++----- 2 files changed, 3 insertions(+), 19 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index e60478677e0..bfa5ef7910b 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -818,20 +818,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 71bd2aaf3d9..d7a6493dd19 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -4003,9 +4003,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8640,9 +8637,10 @@ proallargtypes => '{text,text,interval,bool}', proargmodes => '{o,o,o,o}', proargnames => '{name,abbrev,utc_offset,is_dst}', prosrc => 'pg_timezone_names' }, -{ oid => '2730', descr => 'trigger description with pretty-print option', +{ oid => '2730', descr => 'trigger description', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', proargnames => '{trigger,pretty}', + proargdefaults => '{false}', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.53.0 --iWwo79nqhOvOs5kf-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v4 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use proargdefaults to handle the optional pretty argument. --- src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 6 ++---- 2 files changed, 2 insertions(+), 18 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index a70807e84ca..27be4501e12 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -808,20 +808,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 69c1e5bb264..b43cbb62b82 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -3984,9 +3984,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8566,7 +8563,8 @@ prosrc => 'pg_timezone_names' }, { oid => '2730', descr => 'trigger description with pretty-print option', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', proargnames => '{trigger,pretty}', + proargdefaults => '{false}', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.43.0 --eEEy3EHc57lA8spa-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v3 7/7] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use CREATE OR REPLACE FUNCTION to handle the optional pretty argument. --- src/backend/catalog/system_functions.sql | 7 +++++++ src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 5 +---- src/include/catalog/pg_retired.dat | 1 + 4 files changed, 9 insertions(+), 18 deletions(-) diff --git a/src/backend/catalog/system_functions.sql b/src/backend/catalog/system_functions.sql index a6f7cdf3a36..08b9b68d0cd 100644 --- a/src/backend/catalog/system_functions.sql +++ b/src/backend/catalog/system_functions.sql @@ -699,6 +699,13 @@ LANGUAGE INTERNAL PARALLEL SAFE AS 'pg_get_expr'; +CREATE OR REPLACE FUNCTION + pg_get_triggerdef(trigger oid, pretty bool DEFAULT false) +RETURNS TEXT +LANGUAGE INTERNAL +PARALLEL SAFE +AS 'pg_get_triggerdef'; + -- -- The default permissions for functions mean that anyone can execute them. -- A number of functions shouldn't be executable by just anyone, but rather diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index d87b361a093..598c916ddb6 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -807,20 +807,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 4304ab220ba..bf00983b3ff 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -3983,9 +3983,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8551,7 +8548,7 @@ prosrc => 'pg_timezone_names' }, { oid => '2730', descr => 'trigger description with pretty-print option', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', diff --git a/src/include/catalog/pg_retired.dat b/src/include/catalog/pg_retired.dat index 8b5f58850f6..46764648040 100644 --- a/src/include/catalog/pg_retired.dat +++ b/src/include/catalog/pg_retired.dat @@ -22,6 +22,7 @@ { oid => '1640', proname => 'pg_get_viewdef' }, { oid => '1641', proname => 'pg_get_viewdef' }, { oid => '1643', proname => 'pg_get_indexdef' }, +{ oid => '1662', proname => 'pg_get_triggerdef' }, { oid => '1716', proname => 'pg_get_expr' } ] -- 2.43.0 --zd8Z8rlPOcTi77n/-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v3 7/7] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use CREATE OR REPLACE FUNCTION to handle the optional pretty argument. --- src/backend/catalog/system_functions.sql | 7 +++++++ src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 5 +---- src/include/catalog/pg_retired.dat | 1 + 4 files changed, 9 insertions(+), 18 deletions(-) diff --git a/src/backend/catalog/system_functions.sql b/src/backend/catalog/system_functions.sql index a6f7cdf3a36..08b9b68d0cd 100644 --- a/src/backend/catalog/system_functions.sql +++ b/src/backend/catalog/system_functions.sql @@ -699,6 +699,13 @@ LANGUAGE INTERNAL PARALLEL SAFE AS 'pg_get_expr'; +CREATE OR REPLACE FUNCTION + pg_get_triggerdef(trigger oid, pretty bool DEFAULT false) +RETURNS TEXT +LANGUAGE INTERNAL +PARALLEL SAFE +AS 'pg_get_triggerdef'; + -- -- The default permissions for functions mean that anyone can execute them. -- A number of functions shouldn't be executable by just anyone, but rather diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index d87b361a093..598c916ddb6 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -807,20 +807,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 4304ab220ba..bf00983b3ff 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -3983,9 +3983,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8551,7 +8548,7 @@ prosrc => 'pg_timezone_names' }, { oid => '2730', descr => 'trigger description with pretty-print option', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', diff --git a/src/include/catalog/pg_retired.dat b/src/include/catalog/pg_retired.dat index 8b5f58850f6..46764648040 100644 --- a/src/include/catalog/pg_retired.dat +++ b/src/include/catalog/pg_retired.dat @@ -22,6 +22,7 @@ { oid => '1640', proname => 'pg_get_viewdef' }, { oid => '1641', proname => 'pg_get_viewdef' }, { oid => '1643', proname => 'pg_get_indexdef' }, +{ oid => '1662', proname => 'pg_get_triggerdef' }, { oid => '1716', proname => 'pg_get_expr' } ] -- 2.43.0 --zd8Z8rlPOcTi77n/-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v8.1 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use proargdefaults to handle the optional pretty argument. --- src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 8 +++----- 2 files changed, 3 insertions(+), 19 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index e60478677e0..bfa5ef7910b 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -818,20 +818,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index df43469be3d..7cccfe6d7a7 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -4003,9 +4003,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8640,9 +8637,10 @@ proallargtypes => '{text,text,interval,bool}', proargmodes => '{o,o,o,o}', proargnames => '{name,abbrev,utc_offset,is_dst}', prosrc => 'pg_timezone_names' }, -{ oid => '2730', descr => 'trigger description with pretty-print option', +{ oid => '2730', descr => 'trigger description', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', proargnames => '{trigger,pretty}', + proargdefaults => '{false}', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.53.0 --AcCatzXgbvyipyEy-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v8 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use proargdefaults to handle the optional pretty argument. --- src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 8 +++----- 2 files changed, 3 insertions(+), 19 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index e60478677e0..bfa5ef7910b 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -818,20 +818,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 71bd2aaf3d9..d7a6493dd19 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -4003,9 +4003,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8640,9 +8637,10 @@ proallargtypes => '{text,text,interval,bool}', proargmodes => '{o,o,o,o}', proargnames => '{name,abbrev,utc_offset,is_dst}', prosrc => 'pg_timezone_names' }, -{ oid => '2730', descr => 'trigger description with pretty-print option', +{ oid => '2730', descr => 'trigger description', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', proargnames => '{trigger,pretty}', + proargdefaults => '{false}', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.53.0 --iWwo79nqhOvOs5kf-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v3 7/7] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use CREATE OR REPLACE FUNCTION to handle the optional pretty argument. --- src/backend/catalog/system_functions.sql | 7 +++++++ src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 5 +---- src/include/catalog/pg_retired.dat | 1 + 4 files changed, 9 insertions(+), 18 deletions(-) diff --git a/src/backend/catalog/system_functions.sql b/src/backend/catalog/system_functions.sql index a6f7cdf3a36..08b9b68d0cd 100644 --- a/src/backend/catalog/system_functions.sql +++ b/src/backend/catalog/system_functions.sql @@ -699,6 +699,13 @@ LANGUAGE INTERNAL PARALLEL SAFE AS 'pg_get_expr'; +CREATE OR REPLACE FUNCTION + pg_get_triggerdef(trigger oid, pretty bool DEFAULT false) +RETURNS TEXT +LANGUAGE INTERNAL +PARALLEL SAFE +AS 'pg_get_triggerdef'; + -- -- The default permissions for functions mean that anyone can execute them. -- A number of functions shouldn't be executable by just anyone, but rather diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index d87b361a093..598c916ddb6 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -807,20 +807,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 4304ab220ba..bf00983b3ff 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -3983,9 +3983,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8551,7 +8548,7 @@ prosrc => 'pg_timezone_names' }, { oid => '2730', descr => 'trigger description with pretty-print option', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', diff --git a/src/include/catalog/pg_retired.dat b/src/include/catalog/pg_retired.dat index 8b5f58850f6..46764648040 100644 --- a/src/include/catalog/pg_retired.dat +++ b/src/include/catalog/pg_retired.dat @@ -22,6 +22,7 @@ { oid => '1640', proname => 'pg_get_viewdef' }, { oid => '1641', proname => 'pg_get_viewdef' }, { oid => '1643', proname => 'pg_get_indexdef' }, +{ oid => '1662', proname => 'pg_get_triggerdef' }, { oid => '1716', proname => 'pg_get_expr' } ] -- 2.43.0 --zd8Z8rlPOcTi77n/-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v7 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use proargdefaults to handle the optional pretty argument. --- src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 8 +++----- 2 files changed, 3 insertions(+), 19 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 707f83d4310..249f4518f62 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -818,20 +818,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 855529509de..f4df55370e7 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -4003,9 +4003,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8673,9 +8670,10 @@ proallargtypes => '{text,text,interval,bool}', proargmodes => '{o,o,o,o}', proargnames => '{name,abbrev,utc_offset,is_dst}', prosrc => 'pg_timezone_names' }, -{ oid => '2730', descr => 'trigger description with pretty-print option', +{ oid => '2730', descr => 'trigger description', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', proargnames => '{trigger,pretty}', + proargdefaults => '{false}', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.52.0 --GzYugJnip6WHHvTk-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v8.1 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use proargdefaults to handle the optional pretty argument. --- src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 8 +++----- 2 files changed, 3 insertions(+), 19 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index e60478677e0..bfa5ef7910b 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -818,20 +818,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index df43469be3d..7cccfe6d7a7 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -4003,9 +4003,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8640,9 +8637,10 @@ proallargtypes => '{text,text,interval,bool}', proargmodes => '{o,o,o,o}', proargnames => '{name,abbrev,utc_offset,is_dst}', prosrc => 'pg_timezone_names' }, -{ oid => '2730', descr => 'trigger description with pretty-print option', +{ oid => '2730', descr => 'trigger description', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', proargnames => '{trigger,pretty}', + proargdefaults => '{false}', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.53.0 --AcCatzXgbvyipyEy-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v5 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use proargdefaults to handle the optional pretty argument. --- src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 6 ++---- 2 files changed, 2 insertions(+), 18 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 972f89eafbc..bd0ca6891c3 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -818,20 +818,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index f36f4625e50..43844bb6862 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -3997,9 +3997,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8630,7 +8627,8 @@ prosrc => 'pg_timezone_names' }, { oid => '2730', descr => 'trigger description with pretty-print option', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', proargnames => '{trigger,pretty}', + proargdefaults => '{false}', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.52.0 --m23X5uHFNxthGTU3-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v5 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use proargdefaults to handle the optional pretty argument. --- src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 6 ++---- 2 files changed, 2 insertions(+), 18 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 972f89eafbc..bd0ca6891c3 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -818,20 +818,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index f36f4625e50..43844bb6862 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -3997,9 +3997,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8630,7 +8627,8 @@ prosrc => 'pg_timezone_names' }, { oid => '2730', descr => 'trigger description with pretty-print option', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', proargnames => '{trigger,pretty}', + proargdefaults => '{false}', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.52.0 --m23X5uHFNxthGTU3-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v2 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use CREATE OR REPLACE FUNCTION to handle the optional pretty argument. --- src/backend/catalog/system_functions.sql | 7 +++++++ src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 5 +---- 3 files changed, 8 insertions(+), 18 deletions(-) diff --git a/src/backend/catalog/system_functions.sql b/src/backend/catalog/system_functions.sql index a6f7cdf3a36..08b9b68d0cd 100644 --- a/src/backend/catalog/system_functions.sql +++ b/src/backend/catalog/system_functions.sql @@ -699,6 +699,13 @@ LANGUAGE INTERNAL PARALLEL SAFE AS 'pg_get_expr'; +CREATE OR REPLACE FUNCTION + pg_get_triggerdef(trigger oid, pretty bool DEFAULT false) +RETURNS TEXT +LANGUAGE INTERNAL +PARALLEL SAFE +AS 'pg_get_triggerdef'; + -- -- The default permissions for functions mean that anyone can execute them. -- A number of functions shouldn't be executable by just anyone, but rather diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 305e3e80c41..188d367b113 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -807,20 +807,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 3a0be2d4b2a..d644a391e0e 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -3983,9 +3983,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8551,7 +8548,7 @@ prosrc => 'pg_timezone_names' }, { oid => '2730', descr => 'trigger description with pretty-print option', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.43.0 --3/nz5wg6+DYwHsLU-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v7 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use proargdefaults to handle the optional pretty argument. --- src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 8 +++----- 2 files changed, 3 insertions(+), 19 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 707f83d4310..249f4518f62 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -818,20 +818,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 855529509de..f4df55370e7 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -4003,9 +4003,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8673,9 +8670,10 @@ proallargtypes => '{text,text,interval,bool}', proargmodes => '{o,o,o,o}', proargnames => '{name,abbrev,utc_offset,is_dst}', prosrc => 'pg_timezone_names' }, -{ oid => '2730', descr => 'trigger description with pretty-print option', +{ oid => '2730', descr => 'trigger description', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', proargnames => '{trigger,pretty}', + proargdefaults => '{false}', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.52.0 --GzYugJnip6WHHvTk-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v8.1 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use proargdefaults to handle the optional pretty argument. --- src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 8 +++----- 2 files changed, 3 insertions(+), 19 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index e60478677e0..bfa5ef7910b 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -818,20 +818,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index df43469be3d..7cccfe6d7a7 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -4003,9 +4003,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8640,9 +8637,10 @@ proallargtypes => '{text,text,interval,bool}', proargmodes => '{o,o,o,o}', proargnames => '{name,abbrev,utc_offset,is_dst}', prosrc => 'pg_timezone_names' }, -{ oid => '2730', descr => 'trigger description with pretty-print option', +{ oid => '2730', descr => 'trigger description', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', proargnames => '{trigger,pretty}', + proargdefaults => '{false}', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.53.0 --AcCatzXgbvyipyEy-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v8 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use proargdefaults to handle the optional pretty argument. --- src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 8 +++----- 2 files changed, 3 insertions(+), 19 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index e60478677e0..bfa5ef7910b 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -818,20 +818,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 71bd2aaf3d9..d7a6493dd19 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -4003,9 +4003,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8640,9 +8637,10 @@ proallargtypes => '{text,text,interval,bool}', proargmodes => '{o,o,o,o}', proargnames => '{name,abbrev,utc_offset,is_dst}', prosrc => 'pg_timezone_names' }, -{ oid => '2730', descr => 'trigger description with pretty-print option', +{ oid => '2730', descr => 'trigger description', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', proargnames => '{trigger,pretty}', + proargdefaults => '{false}', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.53.0 --iWwo79nqhOvOs5kf-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v1 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use CREATE OR REPLACE FUNCTION to handle the optional pretty argument. --- src/backend/catalog/system_functions.sql | 7 +++++++ src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 5 +---- 3 files changed, 8 insertions(+), 18 deletions(-) diff --git a/src/backend/catalog/system_functions.sql b/src/backend/catalog/system_functions.sql index 81d210a9c45..c9c011ea5c1 100644 --- a/src/backend/catalog/system_functions.sql +++ b/src/backend/catalog/system_functions.sql @@ -699,6 +699,13 @@ LANGUAGE INTERNAL PARALLEL SAFE AS 'pg_get_expr'; +CREATE OR REPLACE FUNCTION + pg_get_triggerdef(trigger oid, pretty bool DEFAULT false) +RETURNS TEXT +LANGUAGE INTERNAL +PARALLEL SAFE +AS 'pg_get_triggerdef'; + -- -- The default permissions for functions mean that anyone can execute them. -- A number of functions shouldn't be executable by just anyone, but rather diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 9effa02fa2e..45a35f823e8 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -807,20 +807,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 10c5286bd7d..146963c254b 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -3974,9 +3974,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8535,7 +8532,7 @@ prosrc => 'pg_timezone_names' }, { oid => '2730', descr => 'trigger description with pretty-print option', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.51.2 --IRGsBYp1UN8d6WrT-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v1 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use CREATE OR REPLACE FUNCTION to handle the optional pretty argument. --- src/backend/catalog/system_functions.sql | 7 +++++++ src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 5 +---- 3 files changed, 8 insertions(+), 18 deletions(-) diff --git a/src/backend/catalog/system_functions.sql b/src/backend/catalog/system_functions.sql index 81d210a9c45..c9c011ea5c1 100644 --- a/src/backend/catalog/system_functions.sql +++ b/src/backend/catalog/system_functions.sql @@ -699,6 +699,13 @@ LANGUAGE INTERNAL PARALLEL SAFE AS 'pg_get_expr'; +CREATE OR REPLACE FUNCTION + pg_get_triggerdef(trigger oid, pretty bool DEFAULT false) +RETURNS TEXT +LANGUAGE INTERNAL +PARALLEL SAFE +AS 'pg_get_triggerdef'; + -- -- The default permissions for functions mean that anyone can execute them. -- A number of functions shouldn't be executable by just anyone, but rather diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 9effa02fa2e..45a35f823e8 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -807,20 +807,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 10c5286bd7d..146963c254b 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -3974,9 +3974,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8535,7 +8532,7 @@ prosrc => 'pg_timezone_names' }, { oid => '2730', descr => 'trigger description with pretty-print option', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.51.2 --IRGsBYp1UN8d6WrT-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v2 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use CREATE OR REPLACE FUNCTION to handle the optional pretty argument. --- src/backend/catalog/system_functions.sql | 7 +++++++ src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 5 +---- 3 files changed, 8 insertions(+), 18 deletions(-) diff --git a/src/backend/catalog/system_functions.sql b/src/backend/catalog/system_functions.sql index a6f7cdf3a36..08b9b68d0cd 100644 --- a/src/backend/catalog/system_functions.sql +++ b/src/backend/catalog/system_functions.sql @@ -699,6 +699,13 @@ LANGUAGE INTERNAL PARALLEL SAFE AS 'pg_get_expr'; +CREATE OR REPLACE FUNCTION + pg_get_triggerdef(trigger oid, pretty bool DEFAULT false) +RETURNS TEXT +LANGUAGE INTERNAL +PARALLEL SAFE +AS 'pg_get_triggerdef'; + -- -- The default permissions for functions mean that anyone can execute them. -- A number of functions shouldn't be executable by just anyone, but rather diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 305e3e80c41..188d367b113 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -807,20 +807,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 3a0be2d4b2a..d644a391e0e 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -3983,9 +3983,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8551,7 +8548,7 @@ prosrc => 'pg_timezone_names' }, { oid => '2730', descr => 'trigger description with pretty-print option', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.43.0 --3/nz5wg6+DYwHsLU-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v8.1 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use proargdefaults to handle the optional pretty argument. --- src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 8 +++----- 2 files changed, 3 insertions(+), 19 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index e60478677e0..bfa5ef7910b 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -818,20 +818,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index df43469be3d..7cccfe6d7a7 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -4003,9 +4003,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8640,9 +8637,10 @@ proallargtypes => '{text,text,interval,bool}', proargmodes => '{o,o,o,o}', proargnames => '{name,abbrev,utc_offset,is_dst}', prosrc => 'pg_timezone_names' }, -{ oid => '2730', descr => 'trigger description with pretty-print option', +{ oid => '2730', descr => 'trigger description', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', proargnames => '{trigger,pretty}', + proargdefaults => '{false}', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.53.0 --AcCatzXgbvyipyEy-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v3 7/7] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use CREATE OR REPLACE FUNCTION to handle the optional pretty argument. --- src/backend/catalog/system_functions.sql | 7 +++++++ src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 5 +---- src/include/catalog/pg_retired.dat | 1 + 4 files changed, 9 insertions(+), 18 deletions(-) diff --git a/src/backend/catalog/system_functions.sql b/src/backend/catalog/system_functions.sql index a6f7cdf3a36..08b9b68d0cd 100644 --- a/src/backend/catalog/system_functions.sql +++ b/src/backend/catalog/system_functions.sql @@ -699,6 +699,13 @@ LANGUAGE INTERNAL PARALLEL SAFE AS 'pg_get_expr'; +CREATE OR REPLACE FUNCTION + pg_get_triggerdef(trigger oid, pretty bool DEFAULT false) +RETURNS TEXT +LANGUAGE INTERNAL +PARALLEL SAFE +AS 'pg_get_triggerdef'; + -- -- The default permissions for functions mean that anyone can execute them. -- A number of functions shouldn't be executable by just anyone, but rather diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index d87b361a093..598c916ddb6 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -807,20 +807,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 4304ab220ba..bf00983b3ff 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -3983,9 +3983,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8551,7 +8548,7 @@ prosrc => 'pg_timezone_names' }, { oid => '2730', descr => 'trigger description with pretty-print option', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', diff --git a/src/include/catalog/pg_retired.dat b/src/include/catalog/pg_retired.dat index 8b5f58850f6..46764648040 100644 --- a/src/include/catalog/pg_retired.dat +++ b/src/include/catalog/pg_retired.dat @@ -22,6 +22,7 @@ { oid => '1640', proname => 'pg_get_viewdef' }, { oid => '1641', proname => 'pg_get_viewdef' }, { oid => '1643', proname => 'pg_get_indexdef' }, +{ oid => '1662', proname => 'pg_get_triggerdef' }, { oid => '1716', proname => 'pg_get_expr' } ] -- 2.43.0 --zd8Z8rlPOcTi77n/-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v1 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use CREATE OR REPLACE FUNCTION to handle the optional pretty argument. --- src/backend/catalog/system_functions.sql | 7 +++++++ src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 5 +---- 3 files changed, 8 insertions(+), 18 deletions(-) diff --git a/src/backend/catalog/system_functions.sql b/src/backend/catalog/system_functions.sql index 81d210a9c45..c9c011ea5c1 100644 --- a/src/backend/catalog/system_functions.sql +++ b/src/backend/catalog/system_functions.sql @@ -699,6 +699,13 @@ LANGUAGE INTERNAL PARALLEL SAFE AS 'pg_get_expr'; +CREATE OR REPLACE FUNCTION + pg_get_triggerdef(trigger oid, pretty bool DEFAULT false) +RETURNS TEXT +LANGUAGE INTERNAL +PARALLEL SAFE +AS 'pg_get_triggerdef'; + -- -- The default permissions for functions mean that anyone can execute them. -- A number of functions shouldn't be executable by just anyone, but rather diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 9effa02fa2e..45a35f823e8 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -807,20 +807,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 10c5286bd7d..146963c254b 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -3974,9 +3974,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8535,7 +8532,7 @@ prosrc => 'pg_timezone_names' }, { oid => '2730', descr => 'trigger description with pretty-print option', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.51.2 --IRGsBYp1UN8d6WrT-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v8 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use proargdefaults to handle the optional pretty argument. --- src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 8 +++----- 2 files changed, 3 insertions(+), 19 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index e60478677e0..bfa5ef7910b 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -818,20 +818,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 71bd2aaf3d9..d7a6493dd19 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -4003,9 +4003,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8640,9 +8637,10 @@ proallargtypes => '{text,text,interval,bool}', proargmodes => '{o,o,o,o}', proargnames => '{name,abbrev,utc_offset,is_dst}', prosrc => 'pg_timezone_names' }, -{ oid => '2730', descr => 'trigger description with pretty-print option', +{ oid => '2730', descr => 'trigger description', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', proargnames => '{trigger,pretty}', + proargdefaults => '{false}', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.53.0 --iWwo79nqhOvOs5kf-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v2 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use CREATE OR REPLACE FUNCTION to handle the optional pretty argument. --- src/backend/catalog/system_functions.sql | 7 +++++++ src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 5 +---- 3 files changed, 8 insertions(+), 18 deletions(-) diff --git a/src/backend/catalog/system_functions.sql b/src/backend/catalog/system_functions.sql index a6f7cdf3a36..08b9b68d0cd 100644 --- a/src/backend/catalog/system_functions.sql +++ b/src/backend/catalog/system_functions.sql @@ -699,6 +699,13 @@ LANGUAGE INTERNAL PARALLEL SAFE AS 'pg_get_expr'; +CREATE OR REPLACE FUNCTION + pg_get_triggerdef(trigger oid, pretty bool DEFAULT false) +RETURNS TEXT +LANGUAGE INTERNAL +PARALLEL SAFE +AS 'pg_get_triggerdef'; + -- -- The default permissions for functions mean that anyone can execute them. -- A number of functions shouldn't be executable by just anyone, but rather diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 305e3e80c41..188d367b113 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -807,20 +807,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 3a0be2d4b2a..d644a391e0e 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -3983,9 +3983,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8551,7 +8548,7 @@ prosrc => 'pg_timezone_names' }, { oid => '2730', descr => 'trigger description with pretty-print option', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.43.0 --3/nz5wg6+DYwHsLU-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v4 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use proargdefaults to handle the optional pretty argument. --- src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 6 ++---- 2 files changed, 2 insertions(+), 18 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index a70807e84ca..27be4501e12 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -808,20 +808,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 69c1e5bb264..b43cbb62b82 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -3984,9 +3984,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8566,7 +8563,8 @@ prosrc => 'pg_timezone_names' }, { oid => '2730', descr => 'trigger description with pretty-print option', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', proargnames => '{trigger,pretty}', + proargdefaults => '{false}', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.43.0 --eEEy3EHc57lA8spa-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v4 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use proargdefaults to handle the optional pretty argument. --- src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 6 ++---- 2 files changed, 2 insertions(+), 18 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index a70807e84ca..27be4501e12 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -808,20 +808,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 69c1e5bb264..b43cbb62b82 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -3984,9 +3984,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8566,7 +8563,8 @@ prosrc => 'pg_timezone_names' }, { oid => '2730', descr => 'trigger description with pretty-print option', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', proargnames => '{trigger,pretty}', + proargdefaults => '{false}', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.43.0 --eEEy3EHc57lA8spa-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v4 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use proargdefaults to handle the optional pretty argument. --- src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 6 ++---- 2 files changed, 2 insertions(+), 18 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index a70807e84ca..27be4501e12 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -808,20 +808,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 69c1e5bb264..b43cbb62b82 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -3984,9 +3984,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8566,7 +8563,8 @@ prosrc => 'pg_timezone_names' }, { oid => '2730', descr => 'trigger description with pretty-print option', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', proargnames => '{trigger,pretty}', + proargdefaults => '{false}', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.43.0 --eEEy3EHc57lA8spa-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v2 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use CREATE OR REPLACE FUNCTION to handle the optional pretty argument. --- src/backend/catalog/system_functions.sql | 7 +++++++ src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 5 +---- 3 files changed, 8 insertions(+), 18 deletions(-) diff --git a/src/backend/catalog/system_functions.sql b/src/backend/catalog/system_functions.sql index a6f7cdf3a36..08b9b68d0cd 100644 --- a/src/backend/catalog/system_functions.sql +++ b/src/backend/catalog/system_functions.sql @@ -699,6 +699,13 @@ LANGUAGE INTERNAL PARALLEL SAFE AS 'pg_get_expr'; +CREATE OR REPLACE FUNCTION + pg_get_triggerdef(trigger oid, pretty bool DEFAULT false) +RETURNS TEXT +LANGUAGE INTERNAL +PARALLEL SAFE +AS 'pg_get_triggerdef'; + -- -- The default permissions for functions mean that anyone can execute them. -- A number of functions shouldn't be executable by just anyone, but rather diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 305e3e80c41..188d367b113 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -807,20 +807,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 3a0be2d4b2a..d644a391e0e 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -3983,9 +3983,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8551,7 +8548,7 @@ prosrc => 'pg_timezone_names' }, { oid => '2730', descr => 'trigger description with pretty-print option', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.43.0 --3/nz5wg6+DYwHsLU-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v8.1 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use proargdefaults to handle the optional pretty argument. --- src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 8 +++----- 2 files changed, 3 insertions(+), 19 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index e60478677e0..bfa5ef7910b 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -818,20 +818,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index df43469be3d..7cccfe6d7a7 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -4003,9 +4003,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8640,9 +8637,10 @@ proallargtypes => '{text,text,interval,bool}', proargmodes => '{o,o,o,o}', proargnames => '{name,abbrev,utc_offset,is_dst}', prosrc => 'pg_timezone_names' }, -{ oid => '2730', descr => 'trigger description with pretty-print option', +{ oid => '2730', descr => 'trigger description', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', proargnames => '{trigger,pretty}', + proargdefaults => '{false}', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.53.0 --AcCatzXgbvyipyEy-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v8 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use proargdefaults to handle the optional pretty argument. --- src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 8 +++----- 2 files changed, 3 insertions(+), 19 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index e60478677e0..bfa5ef7910b 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -818,20 +818,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 71bd2aaf3d9..d7a6493dd19 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -4003,9 +4003,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8640,9 +8637,10 @@ proallargtypes => '{text,text,interval,bool}', proargmodes => '{o,o,o,o}', proargnames => '{name,abbrev,utc_offset,is_dst}', prosrc => 'pg_timezone_names' }, -{ oid => '2730', descr => 'trigger description with pretty-print option', +{ oid => '2730', descr => 'trigger description', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', proargnames => '{trigger,pretty}', + proargdefaults => '{false}', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.53.0 --iWwo79nqhOvOs5kf-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v7 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use proargdefaults to handle the optional pretty argument. --- src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 8 +++----- 2 files changed, 3 insertions(+), 19 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 707f83d4310..249f4518f62 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -818,20 +818,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 855529509de..f4df55370e7 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -4003,9 +4003,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8673,9 +8670,10 @@ proallargtypes => '{text,text,interval,bool}', proargmodes => '{o,o,o,o}', proargnames => '{name,abbrev,utc_offset,is_dst}', prosrc => 'pg_timezone_names' }, -{ oid => '2730', descr => 'trigger description with pretty-print option', +{ oid => '2730', descr => 'trigger description', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', proargnames => '{trigger,pretty}', + proargdefaults => '{false}', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.52.0 --GzYugJnip6WHHvTk-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v7 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use proargdefaults to handle the optional pretty argument. --- src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 8 +++----- 2 files changed, 3 insertions(+), 19 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 707f83d4310..249f4518f62 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -818,20 +818,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 855529509de..f4df55370e7 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -4003,9 +4003,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8673,9 +8670,10 @@ proallargtypes => '{text,text,interval,bool}', proargmodes => '{o,o,o,o}', proargnames => '{name,abbrev,utc_offset,is_dst}', prosrc => 'pg_timezone_names' }, -{ oid => '2730', descr => 'trigger description with pretty-print option', +{ oid => '2730', descr => 'trigger description', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', proargnames => '{trigger,pretty}', + proargdefaults => '{false}', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.52.0 --GzYugJnip6WHHvTk-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v8.1 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use proargdefaults to handle the optional pretty argument. --- src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 8 +++----- 2 files changed, 3 insertions(+), 19 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index e60478677e0..bfa5ef7910b 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -818,20 +818,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index df43469be3d..7cccfe6d7a7 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -4003,9 +4003,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8640,9 +8637,10 @@ proallargtypes => '{text,text,interval,bool}', proargmodes => '{o,o,o,o}', proargnames => '{name,abbrev,utc_offset,is_dst}', prosrc => 'pg_timezone_names' }, -{ oid => '2730', descr => 'trigger description with pretty-print option', +{ oid => '2730', descr => 'trigger description', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', proargnames => '{trigger,pretty}', + proargdefaults => '{false}', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.53.0 --AcCatzXgbvyipyEy-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v7 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use proargdefaults to handle the optional pretty argument. --- src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 8 +++----- 2 files changed, 3 insertions(+), 19 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 707f83d4310..249f4518f62 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -818,20 +818,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 855529509de..f4df55370e7 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -4003,9 +4003,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8673,9 +8670,10 @@ proallargtypes => '{text,text,interval,bool}', proargmodes => '{o,o,o,o}', proargnames => '{name,abbrev,utc_offset,is_dst}', prosrc => 'pg_timezone_names' }, -{ oid => '2730', descr => 'trigger description with pretty-print option', +{ oid => '2730', descr => 'trigger description', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', proargnames => '{trigger,pretty}', + proargdefaults => '{false}', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.52.0 --GzYugJnip6WHHvTk-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v2 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use CREATE OR REPLACE FUNCTION to handle the optional pretty argument. --- src/backend/catalog/system_functions.sql | 7 +++++++ src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 5 +---- 3 files changed, 8 insertions(+), 18 deletions(-) diff --git a/src/backend/catalog/system_functions.sql b/src/backend/catalog/system_functions.sql index a6f7cdf3a36..08b9b68d0cd 100644 --- a/src/backend/catalog/system_functions.sql +++ b/src/backend/catalog/system_functions.sql @@ -699,6 +699,13 @@ LANGUAGE INTERNAL PARALLEL SAFE AS 'pg_get_expr'; +CREATE OR REPLACE FUNCTION + pg_get_triggerdef(trigger oid, pretty bool DEFAULT false) +RETURNS TEXT +LANGUAGE INTERNAL +PARALLEL SAFE +AS 'pg_get_triggerdef'; + -- -- The default permissions for functions mean that anyone can execute them. -- A number of functions shouldn't be executable by just anyone, but rather diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 305e3e80c41..188d367b113 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -807,20 +807,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 3a0be2d4b2a..d644a391e0e 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -3983,9 +3983,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8551,7 +8548,7 @@ prosrc => 'pg_timezone_names' }, { oid => '2730', descr => 'trigger description with pretty-print option', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.43.0 --3/nz5wg6+DYwHsLU-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v4 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use proargdefaults to handle the optional pretty argument. --- src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 6 ++---- 2 files changed, 2 insertions(+), 18 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index a70807e84ca..27be4501e12 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -808,20 +808,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 69c1e5bb264..b43cbb62b82 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -3984,9 +3984,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8566,7 +8563,8 @@ prosrc => 'pg_timezone_names' }, { oid => '2730', descr => 'trigger description with pretty-print option', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', proargnames => '{trigger,pretty}', + proargdefaults => '{false}', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.43.0 --eEEy3EHc57lA8spa-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v4 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use proargdefaults to handle the optional pretty argument. --- src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 6 ++---- 2 files changed, 2 insertions(+), 18 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index a70807e84ca..27be4501e12 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -808,20 +808,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 69c1e5bb264..b43cbb62b82 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -3984,9 +3984,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8566,7 +8563,8 @@ prosrc => 'pg_timezone_names' }, { oid => '2730', descr => 'trigger description with pretty-print option', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', proargnames => '{trigger,pretty}', + proargdefaults => '{false}', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.43.0 --eEEy3EHc57lA8spa-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v8 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use proargdefaults to handle the optional pretty argument. --- src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 8 +++----- 2 files changed, 3 insertions(+), 19 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index e60478677e0..bfa5ef7910b 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -818,20 +818,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 71bd2aaf3d9..d7a6493dd19 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -4003,9 +4003,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8640,9 +8637,10 @@ proallargtypes => '{text,text,interval,bool}', proargmodes => '{o,o,o,o}', proargnames => '{name,abbrev,utc_offset,is_dst}', prosrc => 'pg_timezone_names' }, -{ oid => '2730', descr => 'trigger description with pretty-print option', +{ oid => '2730', descr => 'trigger description', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', proargnames => '{trigger,pretty}', + proargdefaults => '{false}', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.53.0 --iWwo79nqhOvOs5kf-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v5 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use proargdefaults to handle the optional pretty argument. --- src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 6 ++---- 2 files changed, 2 insertions(+), 18 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 972f89eafbc..bd0ca6891c3 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -818,20 +818,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index f36f4625e50..43844bb6862 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -3997,9 +3997,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8630,7 +8627,8 @@ prosrc => 'pg_timezone_names' }, { oid => '2730', descr => 'trigger description with pretty-print option', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', proargnames => '{trigger,pretty}', + proargdefaults => '{false}', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.52.0 --m23X5uHFNxthGTU3-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v7 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use proargdefaults to handle the optional pretty argument. --- src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 8 +++----- 2 files changed, 3 insertions(+), 19 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 707f83d4310..249f4518f62 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -818,20 +818,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 855529509de..f4df55370e7 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -4003,9 +4003,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8673,9 +8670,10 @@ proallargtypes => '{text,text,interval,bool}', proargmodes => '{o,o,o,o}', proargnames => '{name,abbrev,utc_offset,is_dst}', prosrc => 'pg_timezone_names' }, -{ oid => '2730', descr => 'trigger description with pretty-print option', +{ oid => '2730', descr => 'trigger description', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', proargnames => '{trigger,pretty}', + proargdefaults => '{false}', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.52.0 --GzYugJnip6WHHvTk-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v2 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use CREATE OR REPLACE FUNCTION to handle the optional pretty argument. --- src/backend/catalog/system_functions.sql | 7 +++++++ src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 5 +---- 3 files changed, 8 insertions(+), 18 deletions(-) diff --git a/src/backend/catalog/system_functions.sql b/src/backend/catalog/system_functions.sql index a6f7cdf3a36..08b9b68d0cd 100644 --- a/src/backend/catalog/system_functions.sql +++ b/src/backend/catalog/system_functions.sql @@ -699,6 +699,13 @@ LANGUAGE INTERNAL PARALLEL SAFE AS 'pg_get_expr'; +CREATE OR REPLACE FUNCTION + pg_get_triggerdef(trigger oid, pretty bool DEFAULT false) +RETURNS TEXT +LANGUAGE INTERNAL +PARALLEL SAFE +AS 'pg_get_triggerdef'; + -- -- The default permissions for functions mean that anyone can execute them. -- A number of functions shouldn't be executable by just anyone, but rather diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 305e3e80c41..188d367b113 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -807,20 +807,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 3a0be2d4b2a..d644a391e0e 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -3983,9 +3983,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8551,7 +8548,7 @@ prosrc => 'pg_timezone_names' }, { oid => '2730', descr => 'trigger description with pretty-print option', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.43.0 --3/nz5wg6+DYwHsLU-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v2 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use CREATE OR REPLACE FUNCTION to handle the optional pretty argument. --- src/backend/catalog/system_functions.sql | 7 +++++++ src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 5 +---- 3 files changed, 8 insertions(+), 18 deletions(-) diff --git a/src/backend/catalog/system_functions.sql b/src/backend/catalog/system_functions.sql index a6f7cdf3a36..08b9b68d0cd 100644 --- a/src/backend/catalog/system_functions.sql +++ b/src/backend/catalog/system_functions.sql @@ -699,6 +699,13 @@ LANGUAGE INTERNAL PARALLEL SAFE AS 'pg_get_expr'; +CREATE OR REPLACE FUNCTION + pg_get_triggerdef(trigger oid, pretty bool DEFAULT false) +RETURNS TEXT +LANGUAGE INTERNAL +PARALLEL SAFE +AS 'pg_get_triggerdef'; + -- -- The default permissions for functions mean that anyone can execute them. -- A number of functions shouldn't be executable by just anyone, but rather diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 305e3e80c41..188d367b113 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -807,20 +807,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 3a0be2d4b2a..d644a391e0e 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -3983,9 +3983,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8551,7 +8548,7 @@ prosrc => 'pg_timezone_names' }, { oid => '2730', descr => 'trigger description with pretty-print option', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.43.0 --3/nz5wg6+DYwHsLU-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v2 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use CREATE OR REPLACE FUNCTION to handle the optional pretty argument. --- src/backend/catalog/system_functions.sql | 7 +++++++ src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 5 +---- 3 files changed, 8 insertions(+), 18 deletions(-) diff --git a/src/backend/catalog/system_functions.sql b/src/backend/catalog/system_functions.sql index a6f7cdf3a36..08b9b68d0cd 100644 --- a/src/backend/catalog/system_functions.sql +++ b/src/backend/catalog/system_functions.sql @@ -699,6 +699,13 @@ LANGUAGE INTERNAL PARALLEL SAFE AS 'pg_get_expr'; +CREATE OR REPLACE FUNCTION + pg_get_triggerdef(trigger oid, pretty bool DEFAULT false) +RETURNS TEXT +LANGUAGE INTERNAL +PARALLEL SAFE +AS 'pg_get_triggerdef'; + -- -- The default permissions for functions mean that anyone can execute them. -- A number of functions shouldn't be executable by just anyone, but rather diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 305e3e80c41..188d367b113 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -807,20 +807,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 3a0be2d4b2a..d644a391e0e 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -3983,9 +3983,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8551,7 +8548,7 @@ prosrc => 'pg_timezone_names' }, { oid => '2730', descr => 'trigger description with pretty-print option', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.43.0 --3/nz5wg6+DYwHsLU-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v8 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use proargdefaults to handle the optional pretty argument. --- src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 8 +++----- 2 files changed, 3 insertions(+), 19 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index e60478677e0..bfa5ef7910b 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -818,20 +818,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 71bd2aaf3d9..d7a6493dd19 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -4003,9 +4003,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8640,9 +8637,10 @@ proallargtypes => '{text,text,interval,bool}', proargmodes => '{o,o,o,o}', proargnames => '{name,abbrev,utc_offset,is_dst}', prosrc => 'pg_timezone_names' }, -{ oid => '2730', descr => 'trigger description with pretty-print option', +{ oid => '2730', descr => 'trigger description', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', proargnames => '{trigger,pretty}', + proargdefaults => '{false}', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.53.0 --iWwo79nqhOvOs5kf-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v4 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use proargdefaults to handle the optional pretty argument. --- src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 6 ++---- 2 files changed, 2 insertions(+), 18 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index a70807e84ca..27be4501e12 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -808,20 +808,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 69c1e5bb264..b43cbb62b82 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -3984,9 +3984,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8566,7 +8563,8 @@ prosrc => 'pg_timezone_names' }, { oid => '2730', descr => 'trigger description with pretty-print option', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', proargnames => '{trigger,pretty}', + proargdefaults => '{false}', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.43.0 --eEEy3EHc57lA8spa-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v7 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use proargdefaults to handle the optional pretty argument. --- src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 8 +++----- 2 files changed, 3 insertions(+), 19 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 707f83d4310..249f4518f62 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -818,20 +818,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 855529509de..f4df55370e7 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -4003,9 +4003,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8673,9 +8670,10 @@ proallargtypes => '{text,text,interval,bool}', proargmodes => '{o,o,o,o}', proargnames => '{name,abbrev,utc_offset,is_dst}', prosrc => 'pg_timezone_names' }, -{ oid => '2730', descr => 'trigger description with pretty-print option', +{ oid => '2730', descr => 'trigger description', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', proargnames => '{trigger,pretty}', + proargdefaults => '{false}', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.52.0 --GzYugJnip6WHHvTk-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v3 7/7] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use CREATE OR REPLACE FUNCTION to handle the optional pretty argument. --- src/backend/catalog/system_functions.sql | 7 +++++++ src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 5 +---- src/include/catalog/pg_retired.dat | 1 + 4 files changed, 9 insertions(+), 18 deletions(-) diff --git a/src/backend/catalog/system_functions.sql b/src/backend/catalog/system_functions.sql index a6f7cdf3a36..08b9b68d0cd 100644 --- a/src/backend/catalog/system_functions.sql +++ b/src/backend/catalog/system_functions.sql @@ -699,6 +699,13 @@ LANGUAGE INTERNAL PARALLEL SAFE AS 'pg_get_expr'; +CREATE OR REPLACE FUNCTION + pg_get_triggerdef(trigger oid, pretty bool DEFAULT false) +RETURNS TEXT +LANGUAGE INTERNAL +PARALLEL SAFE +AS 'pg_get_triggerdef'; + -- -- The default permissions for functions mean that anyone can execute them. -- A number of functions shouldn't be executable by just anyone, but rather diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index d87b361a093..598c916ddb6 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -807,20 +807,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 4304ab220ba..bf00983b3ff 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -3983,9 +3983,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8551,7 +8548,7 @@ prosrc => 'pg_timezone_names' }, { oid => '2730', descr => 'trigger description with pretty-print option', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', diff --git a/src/include/catalog/pg_retired.dat b/src/include/catalog/pg_retired.dat index 8b5f58850f6..46764648040 100644 --- a/src/include/catalog/pg_retired.dat +++ b/src/include/catalog/pg_retired.dat @@ -22,6 +22,7 @@ { oid => '1640', proname => 'pg_get_viewdef' }, { oid => '1641', proname => 'pg_get_viewdef' }, { oid => '1643', proname => 'pg_get_indexdef' }, +{ oid => '1662', proname => 'pg_get_triggerdef' }, { oid => '1716', proname => 'pg_get_expr' } ] -- 2.43.0 --zd8Z8rlPOcTi77n/-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v7 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use proargdefaults to handle the optional pretty argument. --- src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 8 +++----- 2 files changed, 3 insertions(+), 19 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 707f83d4310..249f4518f62 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -818,20 +818,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 855529509de..f4df55370e7 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -4003,9 +4003,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8673,9 +8670,10 @@ proallargtypes => '{text,text,interval,bool}', proargmodes => '{o,o,o,o}', proargnames => '{name,abbrev,utc_offset,is_dst}', prosrc => 'pg_timezone_names' }, -{ oid => '2730', descr => 'trigger description with pretty-print option', +{ oid => '2730', descr => 'trigger description', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', proargnames => '{trigger,pretty}', + proargdefaults => '{false}', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.52.0 --GzYugJnip6WHHvTk-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v8 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use proargdefaults to handle the optional pretty argument. --- src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 8 +++----- 2 files changed, 3 insertions(+), 19 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index e60478677e0..bfa5ef7910b 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -818,20 +818,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 71bd2aaf3d9..d7a6493dd19 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -4003,9 +4003,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8640,9 +8637,10 @@ proallargtypes => '{text,text,interval,bool}', proargmodes => '{o,o,o,o}', proargnames => '{name,abbrev,utc_offset,is_dst}', prosrc => 'pg_timezone_names' }, -{ oid => '2730', descr => 'trigger description with pretty-print option', +{ oid => '2730', descr => 'trigger description', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', proargnames => '{trigger,pretty}', + proargdefaults => '{false}', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.53.0 --iWwo79nqhOvOs5kf-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v2 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use CREATE OR REPLACE FUNCTION to handle the optional pretty argument. --- src/backend/catalog/system_functions.sql | 7 +++++++ src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 5 +---- 3 files changed, 8 insertions(+), 18 deletions(-) diff --git a/src/backend/catalog/system_functions.sql b/src/backend/catalog/system_functions.sql index a6f7cdf3a36..08b9b68d0cd 100644 --- a/src/backend/catalog/system_functions.sql +++ b/src/backend/catalog/system_functions.sql @@ -699,6 +699,13 @@ LANGUAGE INTERNAL PARALLEL SAFE AS 'pg_get_expr'; +CREATE OR REPLACE FUNCTION + pg_get_triggerdef(trigger oid, pretty bool DEFAULT false) +RETURNS TEXT +LANGUAGE INTERNAL +PARALLEL SAFE +AS 'pg_get_triggerdef'; + -- -- The default permissions for functions mean that anyone can execute them. -- A number of functions shouldn't be executable by just anyone, but rather diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 305e3e80c41..188d367b113 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -807,20 +807,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 3a0be2d4b2a..d644a391e0e 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -3983,9 +3983,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8551,7 +8548,7 @@ prosrc => 'pg_timezone_names' }, { oid => '2730', descr => 'trigger description with pretty-print option', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.43.0 --3/nz5wg6+DYwHsLU-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v5 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use proargdefaults to handle the optional pretty argument. --- src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 6 ++---- 2 files changed, 2 insertions(+), 18 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 972f89eafbc..bd0ca6891c3 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -818,20 +818,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index f36f4625e50..43844bb6862 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -3997,9 +3997,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8630,7 +8627,8 @@ prosrc => 'pg_timezone_names' }, { oid => '2730', descr => 'trigger description with pretty-print option', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', proargnames => '{trigger,pretty}', + proargdefaults => '{false}', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.52.0 --m23X5uHFNxthGTU3-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v2 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use CREATE OR REPLACE FUNCTION to handle the optional pretty argument. --- src/backend/catalog/system_functions.sql | 7 +++++++ src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 5 +---- 3 files changed, 8 insertions(+), 18 deletions(-) diff --git a/src/backend/catalog/system_functions.sql b/src/backend/catalog/system_functions.sql index a6f7cdf3a36..08b9b68d0cd 100644 --- a/src/backend/catalog/system_functions.sql +++ b/src/backend/catalog/system_functions.sql @@ -699,6 +699,13 @@ LANGUAGE INTERNAL PARALLEL SAFE AS 'pg_get_expr'; +CREATE OR REPLACE FUNCTION + pg_get_triggerdef(trigger oid, pretty bool DEFAULT false) +RETURNS TEXT +LANGUAGE INTERNAL +PARALLEL SAFE +AS 'pg_get_triggerdef'; + -- -- The default permissions for functions mean that anyone can execute them. -- A number of functions shouldn't be executable by just anyone, but rather diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 305e3e80c41..188d367b113 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -807,20 +807,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 3a0be2d4b2a..d644a391e0e 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -3983,9 +3983,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8551,7 +8548,7 @@ prosrc => 'pg_timezone_names' }, { oid => '2730', descr => 'trigger description with pretty-print option', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.43.0 --3/nz5wg6+DYwHsLU-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v5 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use proargdefaults to handle the optional pretty argument. --- src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 6 ++---- 2 files changed, 2 insertions(+), 18 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 972f89eafbc..bd0ca6891c3 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -818,20 +818,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index f36f4625e50..43844bb6862 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -3997,9 +3997,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8630,7 +8627,8 @@ prosrc => 'pg_timezone_names' }, { oid => '2730', descr => 'trigger description with pretty-print option', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', proargnames => '{trigger,pretty}', + proargdefaults => '{false}', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.52.0 --m23X5uHFNxthGTU3-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v8 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use proargdefaults to handle the optional pretty argument. --- src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 8 +++----- 2 files changed, 3 insertions(+), 19 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index e60478677e0..bfa5ef7910b 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -818,20 +818,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 71bd2aaf3d9..d7a6493dd19 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -4003,9 +4003,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8640,9 +8637,10 @@ proallargtypes => '{text,text,interval,bool}', proargmodes => '{o,o,o,o}', proargnames => '{name,abbrev,utc_offset,is_dst}', prosrc => 'pg_timezone_names' }, -{ oid => '2730', descr => 'trigger description with pretty-print option', +{ oid => '2730', descr => 'trigger description', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', proargnames => '{trigger,pretty}', + proargdefaults => '{false}', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.53.0 --iWwo79nqhOvOs5kf-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v5 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use proargdefaults to handle the optional pretty argument. --- src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 6 ++---- 2 files changed, 2 insertions(+), 18 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 972f89eafbc..bd0ca6891c3 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -818,20 +818,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index f36f4625e50..43844bb6862 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -3997,9 +3997,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8630,7 +8627,8 @@ prosrc => 'pg_timezone_names' }, { oid => '2730', descr => 'trigger description with pretty-print option', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', proargnames => '{trigger,pretty}', + proargdefaults => '{false}', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.52.0 --m23X5uHFNxthGTU3-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v8 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use proargdefaults to handle the optional pretty argument. --- src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 8 +++----- 2 files changed, 3 insertions(+), 19 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index e60478677e0..bfa5ef7910b 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -818,20 +818,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 71bd2aaf3d9..d7a6493dd19 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -4003,9 +4003,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8640,9 +8637,10 @@ proallargtypes => '{text,text,interval,bool}', proargmodes => '{o,o,o,o}', proargnames => '{name,abbrev,utc_offset,is_dst}', prosrc => 'pg_timezone_names' }, -{ oid => '2730', descr => 'trigger description with pretty-print option', +{ oid => '2730', descr => 'trigger description', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', proargnames => '{trigger,pretty}', + proargdefaults => '{false}', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.53.0 --iWwo79nqhOvOs5kf-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v2 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use CREATE OR REPLACE FUNCTION to handle the optional pretty argument. --- src/backend/catalog/system_functions.sql | 7 +++++++ src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 5 +---- 3 files changed, 8 insertions(+), 18 deletions(-) diff --git a/src/backend/catalog/system_functions.sql b/src/backend/catalog/system_functions.sql index a6f7cdf3a36..08b9b68d0cd 100644 --- a/src/backend/catalog/system_functions.sql +++ b/src/backend/catalog/system_functions.sql @@ -699,6 +699,13 @@ LANGUAGE INTERNAL PARALLEL SAFE AS 'pg_get_expr'; +CREATE OR REPLACE FUNCTION + pg_get_triggerdef(trigger oid, pretty bool DEFAULT false) +RETURNS TEXT +LANGUAGE INTERNAL +PARALLEL SAFE +AS 'pg_get_triggerdef'; + -- -- The default permissions for functions mean that anyone can execute them. -- A number of functions shouldn't be executable by just anyone, but rather diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 305e3e80c41..188d367b113 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -807,20 +807,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 3a0be2d4b2a..d644a391e0e 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -3983,9 +3983,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8551,7 +8548,7 @@ prosrc => 'pg_timezone_names' }, { oid => '2730', descr => 'trigger description with pretty-print option', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.43.0 --3/nz5wg6+DYwHsLU-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v4 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use proargdefaults to handle the optional pretty argument. --- src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 6 ++---- 2 files changed, 2 insertions(+), 18 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index a70807e84ca..27be4501e12 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -808,20 +808,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 69c1e5bb264..b43cbb62b82 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -3984,9 +3984,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8566,7 +8563,8 @@ prosrc => 'pg_timezone_names' }, { oid => '2730', descr => 'trigger description with pretty-print option', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', proargnames => '{trigger,pretty}', + proargdefaults => '{false}', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.43.0 --eEEy3EHc57lA8spa-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v8 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use proargdefaults to handle the optional pretty argument. --- src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 8 +++----- 2 files changed, 3 insertions(+), 19 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index e60478677e0..bfa5ef7910b 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -818,20 +818,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 71bd2aaf3d9..d7a6493dd19 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -4003,9 +4003,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8640,9 +8637,10 @@ proallargtypes => '{text,text,interval,bool}', proargmodes => '{o,o,o,o}', proargnames => '{name,abbrev,utc_offset,is_dst}', prosrc => 'pg_timezone_names' }, -{ oid => '2730', descr => 'trigger description with pretty-print option', +{ oid => '2730', descr => 'trigger description', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', proargnames => '{trigger,pretty}', + proargdefaults => '{false}', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.53.0 --iWwo79nqhOvOs5kf-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v8.1 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use proargdefaults to handle the optional pretty argument. --- src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 8 +++----- 2 files changed, 3 insertions(+), 19 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index e60478677e0..bfa5ef7910b 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -818,20 +818,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index df43469be3d..7cccfe6d7a7 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -4003,9 +4003,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8640,9 +8637,10 @@ proallargtypes => '{text,text,interval,bool}', proargmodes => '{o,o,o,o}', proargnames => '{name,abbrev,utc_offset,is_dst}', prosrc => 'pg_timezone_names' }, -{ oid => '2730', descr => 'trigger description with pretty-print option', +{ oid => '2730', descr => 'trigger description', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', proargnames => '{trigger,pretty}', + proargdefaults => '{false}', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.53.0 --AcCatzXgbvyipyEy-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v2 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use CREATE OR REPLACE FUNCTION to handle the optional pretty argument. --- src/backend/catalog/system_functions.sql | 7 +++++++ src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 5 +---- 3 files changed, 8 insertions(+), 18 deletions(-) diff --git a/src/backend/catalog/system_functions.sql b/src/backend/catalog/system_functions.sql index a6f7cdf3a36..08b9b68d0cd 100644 --- a/src/backend/catalog/system_functions.sql +++ b/src/backend/catalog/system_functions.sql @@ -699,6 +699,13 @@ LANGUAGE INTERNAL PARALLEL SAFE AS 'pg_get_expr'; +CREATE OR REPLACE FUNCTION + pg_get_triggerdef(trigger oid, pretty bool DEFAULT false) +RETURNS TEXT +LANGUAGE INTERNAL +PARALLEL SAFE +AS 'pg_get_triggerdef'; + -- -- The default permissions for functions mean that anyone can execute them. -- A number of functions shouldn't be executable by just anyone, but rather diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 305e3e80c41..188d367b113 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -807,20 +807,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 3a0be2d4b2a..d644a391e0e 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -3983,9 +3983,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8551,7 +8548,7 @@ prosrc => 'pg_timezone_names' }, { oid => '2730', descr => 'trigger description with pretty-print option', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.43.0 --3/nz5wg6+DYwHsLU-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v7 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use proargdefaults to handle the optional pretty argument. --- src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 8 +++----- 2 files changed, 3 insertions(+), 19 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 707f83d4310..249f4518f62 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -818,20 +818,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 855529509de..f4df55370e7 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -4003,9 +4003,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8673,9 +8670,10 @@ proallargtypes => '{text,text,interval,bool}', proargmodes => '{o,o,o,o}', proargnames => '{name,abbrev,utc_offset,is_dst}', prosrc => 'pg_timezone_names' }, -{ oid => '2730', descr => 'trigger description with pretty-print option', +{ oid => '2730', descr => 'trigger description', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', proargnames => '{trigger,pretty}', + proargdefaults => '{false}', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.52.0 --GzYugJnip6WHHvTk-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v5 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use proargdefaults to handle the optional pretty argument. --- src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 6 ++---- 2 files changed, 2 insertions(+), 18 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 972f89eafbc..bd0ca6891c3 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -818,20 +818,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index f36f4625e50..43844bb6862 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -3997,9 +3997,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8630,7 +8627,8 @@ prosrc => 'pg_timezone_names' }, { oid => '2730', descr => 'trigger description with pretty-print option', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', proargnames => '{trigger,pretty}', + proargdefaults => '{false}', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.52.0 --m23X5uHFNxthGTU3-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v1 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use CREATE OR REPLACE FUNCTION to handle the optional pretty argument. --- src/backend/catalog/system_functions.sql | 7 +++++++ src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 5 +---- 3 files changed, 8 insertions(+), 18 deletions(-) diff --git a/src/backend/catalog/system_functions.sql b/src/backend/catalog/system_functions.sql index 81d210a9c45..c9c011ea5c1 100644 --- a/src/backend/catalog/system_functions.sql +++ b/src/backend/catalog/system_functions.sql @@ -699,6 +699,13 @@ LANGUAGE INTERNAL PARALLEL SAFE AS 'pg_get_expr'; +CREATE OR REPLACE FUNCTION + pg_get_triggerdef(trigger oid, pretty bool DEFAULT false) +RETURNS TEXT +LANGUAGE INTERNAL +PARALLEL SAFE +AS 'pg_get_triggerdef'; + -- -- The default permissions for functions mean that anyone can execute them. -- A number of functions shouldn't be executable by just anyone, but rather diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 9effa02fa2e..45a35f823e8 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -807,20 +807,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 10c5286bd7d..146963c254b 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -3974,9 +3974,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8535,7 +8532,7 @@ prosrc => 'pg_timezone_names' }, { oid => '2730', descr => 'trigger description with pretty-print option', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.51.2 --IRGsBYp1UN8d6WrT-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v4 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use proargdefaults to handle the optional pretty argument. --- src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 6 ++---- 2 files changed, 2 insertions(+), 18 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index a70807e84ca..27be4501e12 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -808,20 +808,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 69c1e5bb264..b43cbb62b82 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -3984,9 +3984,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8566,7 +8563,8 @@ prosrc => 'pg_timezone_names' }, { oid => '2730', descr => 'trigger description with pretty-print option', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', proargnames => '{trigger,pretty}', + proargdefaults => '{false}', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.43.0 --eEEy3EHc57lA8spa-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v3 7/7] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use CREATE OR REPLACE FUNCTION to handle the optional pretty argument. --- src/backend/catalog/system_functions.sql | 7 +++++++ src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 5 +---- src/include/catalog/pg_retired.dat | 1 + 4 files changed, 9 insertions(+), 18 deletions(-) diff --git a/src/backend/catalog/system_functions.sql b/src/backend/catalog/system_functions.sql index a6f7cdf3a36..08b9b68d0cd 100644 --- a/src/backend/catalog/system_functions.sql +++ b/src/backend/catalog/system_functions.sql @@ -699,6 +699,13 @@ LANGUAGE INTERNAL PARALLEL SAFE AS 'pg_get_expr'; +CREATE OR REPLACE FUNCTION + pg_get_triggerdef(trigger oid, pretty bool DEFAULT false) +RETURNS TEXT +LANGUAGE INTERNAL +PARALLEL SAFE +AS 'pg_get_triggerdef'; + -- -- The default permissions for functions mean that anyone can execute them. -- A number of functions shouldn't be executable by just anyone, but rather diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index d87b361a093..598c916ddb6 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -807,20 +807,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 4304ab220ba..bf00983b3ff 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -3983,9 +3983,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8551,7 +8548,7 @@ prosrc => 'pg_timezone_names' }, { oid => '2730', descr => 'trigger description with pretty-print option', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', diff --git a/src/include/catalog/pg_retired.dat b/src/include/catalog/pg_retired.dat index 8b5f58850f6..46764648040 100644 --- a/src/include/catalog/pg_retired.dat +++ b/src/include/catalog/pg_retired.dat @@ -22,6 +22,7 @@ { oid => '1640', proname => 'pg_get_viewdef' }, { oid => '1641', proname => 'pg_get_viewdef' }, { oid => '1643', proname => 'pg_get_indexdef' }, +{ oid => '1662', proname => 'pg_get_triggerdef' }, { oid => '1716', proname => 'pg_get_expr' } ] -- 2.43.0 --zd8Z8rlPOcTi77n/-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v3 7/7] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use CREATE OR REPLACE FUNCTION to handle the optional pretty argument. --- src/backend/catalog/system_functions.sql | 7 +++++++ src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 5 +---- src/include/catalog/pg_retired.dat | 1 + 4 files changed, 9 insertions(+), 18 deletions(-) diff --git a/src/backend/catalog/system_functions.sql b/src/backend/catalog/system_functions.sql index a6f7cdf3a36..08b9b68d0cd 100644 --- a/src/backend/catalog/system_functions.sql +++ b/src/backend/catalog/system_functions.sql @@ -699,6 +699,13 @@ LANGUAGE INTERNAL PARALLEL SAFE AS 'pg_get_expr'; +CREATE OR REPLACE FUNCTION + pg_get_triggerdef(trigger oid, pretty bool DEFAULT false) +RETURNS TEXT +LANGUAGE INTERNAL +PARALLEL SAFE +AS 'pg_get_triggerdef'; + -- -- The default permissions for functions mean that anyone can execute them. -- A number of functions shouldn't be executable by just anyone, but rather diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index d87b361a093..598c916ddb6 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -807,20 +807,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 4304ab220ba..bf00983b3ff 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -3983,9 +3983,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8551,7 +8548,7 @@ prosrc => 'pg_timezone_names' }, { oid => '2730', descr => 'trigger description with pretty-print option', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', diff --git a/src/include/catalog/pg_retired.dat b/src/include/catalog/pg_retired.dat index 8b5f58850f6..46764648040 100644 --- a/src/include/catalog/pg_retired.dat +++ b/src/include/catalog/pg_retired.dat @@ -22,6 +22,7 @@ { oid => '1640', proname => 'pg_get_viewdef' }, { oid => '1641', proname => 'pg_get_viewdef' }, { oid => '1643', proname => 'pg_get_indexdef' }, +{ oid => '1662', proname => 'pg_get_triggerdef' }, { oid => '1716', proname => 'pg_get_expr' } ] -- 2.43.0 --zd8Z8rlPOcTi77n/-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v8.1 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use proargdefaults to handle the optional pretty argument. --- src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 8 +++----- 2 files changed, 3 insertions(+), 19 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index e60478677e0..bfa5ef7910b 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -818,20 +818,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index df43469be3d..7cccfe6d7a7 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -4003,9 +4003,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8640,9 +8637,10 @@ proallargtypes => '{text,text,interval,bool}', proargmodes => '{o,o,o,o}', proargnames => '{name,abbrev,utc_offset,is_dst}', prosrc => 'pg_timezone_names' }, -{ oid => '2730', descr => 'trigger description with pretty-print option', +{ oid => '2730', descr => 'trigger description', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', proargnames => '{trigger,pretty}', + proargdefaults => '{false}', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.53.0 --AcCatzXgbvyipyEy-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v1 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use CREATE OR REPLACE FUNCTION to handle the optional pretty argument. --- src/backend/catalog/system_functions.sql | 7 +++++++ src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 5 +---- 3 files changed, 8 insertions(+), 18 deletions(-) diff --git a/src/backend/catalog/system_functions.sql b/src/backend/catalog/system_functions.sql index 81d210a9c45..c9c011ea5c1 100644 --- a/src/backend/catalog/system_functions.sql +++ b/src/backend/catalog/system_functions.sql @@ -699,6 +699,13 @@ LANGUAGE INTERNAL PARALLEL SAFE AS 'pg_get_expr'; +CREATE OR REPLACE FUNCTION + pg_get_triggerdef(trigger oid, pretty bool DEFAULT false) +RETURNS TEXT +LANGUAGE INTERNAL +PARALLEL SAFE +AS 'pg_get_triggerdef'; + -- -- The default permissions for functions mean that anyone can execute them. -- A number of functions shouldn't be executable by just anyone, but rather diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 9effa02fa2e..45a35f823e8 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -807,20 +807,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 10c5286bd7d..146963c254b 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -3974,9 +3974,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8535,7 +8532,7 @@ prosrc => 'pg_timezone_names' }, { oid => '2730', descr => 'trigger description with pretty-print option', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.51.2 --IRGsBYp1UN8d6WrT-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v5 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use proargdefaults to handle the optional pretty argument. --- src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 6 ++---- 2 files changed, 2 insertions(+), 18 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 972f89eafbc..bd0ca6891c3 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -818,20 +818,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index f36f4625e50..43844bb6862 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -3997,9 +3997,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8630,7 +8627,8 @@ prosrc => 'pg_timezone_names' }, { oid => '2730', descr => 'trigger description with pretty-print option', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', proargnames => '{trigger,pretty}', + proargdefaults => '{false}', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.52.0 --m23X5uHFNxthGTU3-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v2 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use CREATE OR REPLACE FUNCTION to handle the optional pretty argument. --- src/backend/catalog/system_functions.sql | 7 +++++++ src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 5 +---- 3 files changed, 8 insertions(+), 18 deletions(-) diff --git a/src/backend/catalog/system_functions.sql b/src/backend/catalog/system_functions.sql index a6f7cdf3a36..08b9b68d0cd 100644 --- a/src/backend/catalog/system_functions.sql +++ b/src/backend/catalog/system_functions.sql @@ -699,6 +699,13 @@ LANGUAGE INTERNAL PARALLEL SAFE AS 'pg_get_expr'; +CREATE OR REPLACE FUNCTION + pg_get_triggerdef(trigger oid, pretty bool DEFAULT false) +RETURNS TEXT +LANGUAGE INTERNAL +PARALLEL SAFE +AS 'pg_get_triggerdef'; + -- -- The default permissions for functions mean that anyone can execute them. -- A number of functions shouldn't be executable by just anyone, but rather diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 305e3e80c41..188d367b113 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -807,20 +807,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 3a0be2d4b2a..d644a391e0e 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -3983,9 +3983,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8551,7 +8548,7 @@ prosrc => 'pg_timezone_names' }, { oid => '2730', descr => 'trigger description with pretty-print option', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.43.0 --3/nz5wg6+DYwHsLU-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v5 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use proargdefaults to handle the optional pretty argument. --- src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 6 ++---- 2 files changed, 2 insertions(+), 18 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 972f89eafbc..bd0ca6891c3 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -818,20 +818,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index f36f4625e50..43844bb6862 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -3997,9 +3997,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8630,7 +8627,8 @@ prosrc => 'pg_timezone_names' }, { oid => '2730', descr => 'trigger description with pretty-print option', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', proargnames => '{trigger,pretty}', + proargdefaults => '{false}', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.52.0 --m23X5uHFNxthGTU3-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v5 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use proargdefaults to handle the optional pretty argument. --- src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 6 ++---- 2 files changed, 2 insertions(+), 18 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 972f89eafbc..bd0ca6891c3 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -818,20 +818,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index f36f4625e50..43844bb6862 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -3997,9 +3997,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8630,7 +8627,8 @@ prosrc => 'pg_timezone_names' }, { oid => '2730', descr => 'trigger description with pretty-print option', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', proargnames => '{trigger,pretty}', + proargdefaults => '{false}', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.52.0 --m23X5uHFNxthGTU3-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v4 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use proargdefaults to handle the optional pretty argument. --- src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 6 ++---- 2 files changed, 2 insertions(+), 18 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index a70807e84ca..27be4501e12 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -808,20 +808,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 69c1e5bb264..b43cbb62b82 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -3984,9 +3984,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8566,7 +8563,8 @@ prosrc => 'pg_timezone_names' }, { oid => '2730', descr => 'trigger description with pretty-print option', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', proargnames => '{trigger,pretty}', + proargdefaults => '{false}', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.43.0 --eEEy3EHc57lA8spa-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v5 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use proargdefaults to handle the optional pretty argument. --- src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 6 ++---- 2 files changed, 2 insertions(+), 18 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 972f89eafbc..bd0ca6891c3 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -818,20 +818,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index f36f4625e50..43844bb6862 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -3997,9 +3997,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8630,7 +8627,8 @@ prosrc => 'pg_timezone_names' }, { oid => '2730', descr => 'trigger description with pretty-print option', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', proargnames => '{trigger,pretty}', + proargdefaults => '{false}', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.52.0 --m23X5uHFNxthGTU3-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v5 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use proargdefaults to handle the optional pretty argument. --- src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 6 ++---- 2 files changed, 2 insertions(+), 18 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 972f89eafbc..bd0ca6891c3 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -818,20 +818,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index f36f4625e50..43844bb6862 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -3997,9 +3997,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8630,7 +8627,8 @@ prosrc => 'pg_timezone_names' }, { oid => '2730', descr => 'trigger description with pretty-print option', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', proargnames => '{trigger,pretty}', + proargdefaults => '{false}', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.52.0 --m23X5uHFNxthGTU3-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v7 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use proargdefaults to handle the optional pretty argument. --- src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 8 +++----- 2 files changed, 3 insertions(+), 19 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 707f83d4310..249f4518f62 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -818,20 +818,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 855529509de..f4df55370e7 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -4003,9 +4003,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8673,9 +8670,10 @@ proallargtypes => '{text,text,interval,bool}', proargmodes => '{o,o,o,o}', proargnames => '{name,abbrev,utc_offset,is_dst}', prosrc => 'pg_timezone_names' }, -{ oid => '2730', descr => 'trigger description with pretty-print option', +{ oid => '2730', descr => 'trigger description', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', proargnames => '{trigger,pretty}', + proargdefaults => '{false}', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.52.0 --GzYugJnip6WHHvTk-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v2 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use CREATE OR REPLACE FUNCTION to handle the optional pretty argument. --- src/backend/catalog/system_functions.sql | 7 +++++++ src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 5 +---- 3 files changed, 8 insertions(+), 18 deletions(-) diff --git a/src/backend/catalog/system_functions.sql b/src/backend/catalog/system_functions.sql index a6f7cdf3a36..08b9b68d0cd 100644 --- a/src/backend/catalog/system_functions.sql +++ b/src/backend/catalog/system_functions.sql @@ -699,6 +699,13 @@ LANGUAGE INTERNAL PARALLEL SAFE AS 'pg_get_expr'; +CREATE OR REPLACE FUNCTION + pg_get_triggerdef(trigger oid, pretty bool DEFAULT false) +RETURNS TEXT +LANGUAGE INTERNAL +PARALLEL SAFE +AS 'pg_get_triggerdef'; + -- -- The default permissions for functions mean that anyone can execute them. -- A number of functions shouldn't be executable by just anyone, but rather diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 305e3e80c41..188d367b113 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -807,20 +807,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 3a0be2d4b2a..d644a391e0e 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -3983,9 +3983,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8551,7 +8548,7 @@ prosrc => 'pg_timezone_names' }, { oid => '2730', descr => 'trigger description with pretty-print option', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.43.0 --3/nz5wg6+DYwHsLU-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v1 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use CREATE OR REPLACE FUNCTION to handle the optional pretty argument. --- src/backend/catalog/system_functions.sql | 7 +++++++ src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 5 +---- 3 files changed, 8 insertions(+), 18 deletions(-) diff --git a/src/backend/catalog/system_functions.sql b/src/backend/catalog/system_functions.sql index 81d210a9c45..c9c011ea5c1 100644 --- a/src/backend/catalog/system_functions.sql +++ b/src/backend/catalog/system_functions.sql @@ -699,6 +699,13 @@ LANGUAGE INTERNAL PARALLEL SAFE AS 'pg_get_expr'; +CREATE OR REPLACE FUNCTION + pg_get_triggerdef(trigger oid, pretty bool DEFAULT false) +RETURNS TEXT +LANGUAGE INTERNAL +PARALLEL SAFE +AS 'pg_get_triggerdef'; + -- -- The default permissions for functions mean that anyone can execute them. -- A number of functions shouldn't be executable by just anyone, but rather diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 9effa02fa2e..45a35f823e8 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -807,20 +807,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 10c5286bd7d..146963c254b 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -3974,9 +3974,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8535,7 +8532,7 @@ prosrc => 'pg_timezone_names' }, { oid => '2730', descr => 'trigger description with pretty-print option', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.51.2 --IRGsBYp1UN8d6WrT-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v8 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use proargdefaults to handle the optional pretty argument. --- src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 8 +++----- 2 files changed, 3 insertions(+), 19 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index e60478677e0..bfa5ef7910b 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -818,20 +818,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 71bd2aaf3d9..d7a6493dd19 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -4003,9 +4003,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8640,9 +8637,10 @@ proallargtypes => '{text,text,interval,bool}', proargmodes => '{o,o,o,o}', proargnames => '{name,abbrev,utc_offset,is_dst}', prosrc => 'pg_timezone_names' }, -{ oid => '2730', descr => 'trigger description with pretty-print option', +{ oid => '2730', descr => 'trigger description', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', proargnames => '{trigger,pretty}', + proargdefaults => '{false}', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.53.0 --iWwo79nqhOvOs5kf-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v8.1 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use proargdefaults to handle the optional pretty argument. --- src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 8 +++----- 2 files changed, 3 insertions(+), 19 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index e60478677e0..bfa5ef7910b 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -818,20 +818,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index df43469be3d..7cccfe6d7a7 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -4003,9 +4003,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8640,9 +8637,10 @@ proallargtypes => '{text,text,interval,bool}', proargmodes => '{o,o,o,o}', proargnames => '{name,abbrev,utc_offset,is_dst}', prosrc => 'pg_timezone_names' }, -{ oid => '2730', descr => 'trigger description with pretty-print option', +{ oid => '2730', descr => 'trigger description', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', proargnames => '{trigger,pretty}', + proargdefaults => '{false}', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.53.0 --AcCatzXgbvyipyEy-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v1 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use CREATE OR REPLACE FUNCTION to handle the optional pretty argument. --- src/backend/catalog/system_functions.sql | 7 +++++++ src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 5 +---- 3 files changed, 8 insertions(+), 18 deletions(-) diff --git a/src/backend/catalog/system_functions.sql b/src/backend/catalog/system_functions.sql index 81d210a9c45..c9c011ea5c1 100644 --- a/src/backend/catalog/system_functions.sql +++ b/src/backend/catalog/system_functions.sql @@ -699,6 +699,13 @@ LANGUAGE INTERNAL PARALLEL SAFE AS 'pg_get_expr'; +CREATE OR REPLACE FUNCTION + pg_get_triggerdef(trigger oid, pretty bool DEFAULT false) +RETURNS TEXT +LANGUAGE INTERNAL +PARALLEL SAFE +AS 'pg_get_triggerdef'; + -- -- The default permissions for functions mean that anyone can execute them. -- A number of functions shouldn't be executable by just anyone, but rather diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 9effa02fa2e..45a35f823e8 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -807,20 +807,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 10c5286bd7d..146963c254b 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -3974,9 +3974,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8535,7 +8532,7 @@ prosrc => 'pg_timezone_names' }, { oid => '2730', descr => 'trigger description with pretty-print option', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.51.2 --IRGsBYp1UN8d6WrT-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v8 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use proargdefaults to handle the optional pretty argument. --- src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 8 +++----- 2 files changed, 3 insertions(+), 19 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index e60478677e0..bfa5ef7910b 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -818,20 +818,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 71bd2aaf3d9..d7a6493dd19 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -4003,9 +4003,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8640,9 +8637,10 @@ proallargtypes => '{text,text,interval,bool}', proargmodes => '{o,o,o,o}', proargnames => '{name,abbrev,utc_offset,is_dst}', prosrc => 'pg_timezone_names' }, -{ oid => '2730', descr => 'trigger description with pretty-print option', +{ oid => '2730', descr => 'trigger description', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', proargnames => '{trigger,pretty}', + proargdefaults => '{false}', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.53.0 --iWwo79nqhOvOs5kf-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v4 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use proargdefaults to handle the optional pretty argument. --- src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 6 ++---- 2 files changed, 2 insertions(+), 18 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index a70807e84ca..27be4501e12 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -808,20 +808,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 69c1e5bb264..b43cbb62b82 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -3984,9 +3984,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8566,7 +8563,8 @@ prosrc => 'pg_timezone_names' }, { oid => '2730', descr => 'trigger description with pretty-print option', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', proargnames => '{trigger,pretty}', + proargdefaults => '{false}', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.43.0 --eEEy3EHc57lA8spa-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v8.1 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use proargdefaults to handle the optional pretty argument. --- src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 8 +++----- 2 files changed, 3 insertions(+), 19 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index e60478677e0..bfa5ef7910b 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -818,20 +818,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index df43469be3d..7cccfe6d7a7 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -4003,9 +4003,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8640,9 +8637,10 @@ proallargtypes => '{text,text,interval,bool}', proargmodes => '{o,o,o,o}', proargnames => '{name,abbrev,utc_offset,is_dst}', prosrc => 'pg_timezone_names' }, -{ oid => '2730', descr => 'trigger description with pretty-print option', +{ oid => '2730', descr => 'trigger description', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', proargnames => '{trigger,pretty}', + proargdefaults => '{false}', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.53.0 --AcCatzXgbvyipyEy-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v3 7/7] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use CREATE OR REPLACE FUNCTION to handle the optional pretty argument. --- src/backend/catalog/system_functions.sql | 7 +++++++ src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 5 +---- src/include/catalog/pg_retired.dat | 1 + 4 files changed, 9 insertions(+), 18 deletions(-) diff --git a/src/backend/catalog/system_functions.sql b/src/backend/catalog/system_functions.sql index a6f7cdf3a36..08b9b68d0cd 100644 --- a/src/backend/catalog/system_functions.sql +++ b/src/backend/catalog/system_functions.sql @@ -699,6 +699,13 @@ LANGUAGE INTERNAL PARALLEL SAFE AS 'pg_get_expr'; +CREATE OR REPLACE FUNCTION + pg_get_triggerdef(trigger oid, pretty bool DEFAULT false) +RETURNS TEXT +LANGUAGE INTERNAL +PARALLEL SAFE +AS 'pg_get_triggerdef'; + -- -- The default permissions for functions mean that anyone can execute them. -- A number of functions shouldn't be executable by just anyone, but rather diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index d87b361a093..598c916ddb6 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -807,20 +807,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 4304ab220ba..bf00983b3ff 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -3983,9 +3983,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8551,7 +8548,7 @@ prosrc => 'pg_timezone_names' }, { oid => '2730', descr => 'trigger description with pretty-print option', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', diff --git a/src/include/catalog/pg_retired.dat b/src/include/catalog/pg_retired.dat index 8b5f58850f6..46764648040 100644 --- a/src/include/catalog/pg_retired.dat +++ b/src/include/catalog/pg_retired.dat @@ -22,6 +22,7 @@ { oid => '1640', proname => 'pg_get_viewdef' }, { oid => '1641', proname => 'pg_get_viewdef' }, { oid => '1643', proname => 'pg_get_indexdef' }, +{ oid => '1662', proname => 'pg_get_triggerdef' }, { oid => '1716', proname => 'pg_get_expr' } ] -- 2.43.0 --zd8Z8rlPOcTi77n/-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v1 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use CREATE OR REPLACE FUNCTION to handle the optional pretty argument. --- src/backend/catalog/system_functions.sql | 7 +++++++ src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 5 +---- 3 files changed, 8 insertions(+), 18 deletions(-) diff --git a/src/backend/catalog/system_functions.sql b/src/backend/catalog/system_functions.sql index 81d210a9c45..c9c011ea5c1 100644 --- a/src/backend/catalog/system_functions.sql +++ b/src/backend/catalog/system_functions.sql @@ -699,6 +699,13 @@ LANGUAGE INTERNAL PARALLEL SAFE AS 'pg_get_expr'; +CREATE OR REPLACE FUNCTION + pg_get_triggerdef(trigger oid, pretty bool DEFAULT false) +RETURNS TEXT +LANGUAGE INTERNAL +PARALLEL SAFE +AS 'pg_get_triggerdef'; + -- -- The default permissions for functions mean that anyone can execute them. -- A number of functions shouldn't be executable by just anyone, but rather diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 9effa02fa2e..45a35f823e8 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -807,20 +807,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 10c5286bd7d..146963c254b 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -3974,9 +3974,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8535,7 +8532,7 @@ prosrc => 'pg_timezone_names' }, { oid => '2730', descr => 'trigger description with pretty-print option', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.51.2 --IRGsBYp1UN8d6WrT-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v1 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use CREATE OR REPLACE FUNCTION to handle the optional pretty argument. --- src/backend/catalog/system_functions.sql | 7 +++++++ src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 5 +---- 3 files changed, 8 insertions(+), 18 deletions(-) diff --git a/src/backend/catalog/system_functions.sql b/src/backend/catalog/system_functions.sql index 81d210a9c45..c9c011ea5c1 100644 --- a/src/backend/catalog/system_functions.sql +++ b/src/backend/catalog/system_functions.sql @@ -699,6 +699,13 @@ LANGUAGE INTERNAL PARALLEL SAFE AS 'pg_get_expr'; +CREATE OR REPLACE FUNCTION + pg_get_triggerdef(trigger oid, pretty bool DEFAULT false) +RETURNS TEXT +LANGUAGE INTERNAL +PARALLEL SAFE +AS 'pg_get_triggerdef'; + -- -- The default permissions for functions mean that anyone can execute them. -- A number of functions shouldn't be executable by just anyone, but rather diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 9effa02fa2e..45a35f823e8 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -807,20 +807,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 10c5286bd7d..146963c254b 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -3974,9 +3974,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8535,7 +8532,7 @@ prosrc => 'pg_timezone_names' }, { oid => '2730', descr => 'trigger description with pretty-print option', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.51.2 --IRGsBYp1UN8d6WrT-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v3 7/7] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use CREATE OR REPLACE FUNCTION to handle the optional pretty argument. --- src/backend/catalog/system_functions.sql | 7 +++++++ src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 5 +---- src/include/catalog/pg_retired.dat | 1 + 4 files changed, 9 insertions(+), 18 deletions(-) diff --git a/src/backend/catalog/system_functions.sql b/src/backend/catalog/system_functions.sql index a6f7cdf3a36..08b9b68d0cd 100644 --- a/src/backend/catalog/system_functions.sql +++ b/src/backend/catalog/system_functions.sql @@ -699,6 +699,13 @@ LANGUAGE INTERNAL PARALLEL SAFE AS 'pg_get_expr'; +CREATE OR REPLACE FUNCTION + pg_get_triggerdef(trigger oid, pretty bool DEFAULT false) +RETURNS TEXT +LANGUAGE INTERNAL +PARALLEL SAFE +AS 'pg_get_triggerdef'; + -- -- The default permissions for functions mean that anyone can execute them. -- A number of functions shouldn't be executable by just anyone, but rather diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index d87b361a093..598c916ddb6 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -807,20 +807,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 4304ab220ba..bf00983b3ff 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -3983,9 +3983,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8551,7 +8548,7 @@ prosrc => 'pg_timezone_names' }, { oid => '2730', descr => 'trigger description with pretty-print option', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', diff --git a/src/include/catalog/pg_retired.dat b/src/include/catalog/pg_retired.dat index 8b5f58850f6..46764648040 100644 --- a/src/include/catalog/pg_retired.dat +++ b/src/include/catalog/pg_retired.dat @@ -22,6 +22,7 @@ { oid => '1640', proname => 'pg_get_viewdef' }, { oid => '1641', proname => 'pg_get_viewdef' }, { oid => '1643', proname => 'pg_get_indexdef' }, +{ oid => '1662', proname => 'pg_get_triggerdef' }, { oid => '1716', proname => 'pg_get_expr' } ] -- 2.43.0 --zd8Z8rlPOcTi77n/-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v3 7/7] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use CREATE OR REPLACE FUNCTION to handle the optional pretty argument. --- src/backend/catalog/system_functions.sql | 7 +++++++ src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 5 +---- src/include/catalog/pg_retired.dat | 1 + 4 files changed, 9 insertions(+), 18 deletions(-) diff --git a/src/backend/catalog/system_functions.sql b/src/backend/catalog/system_functions.sql index a6f7cdf3a36..08b9b68d0cd 100644 --- a/src/backend/catalog/system_functions.sql +++ b/src/backend/catalog/system_functions.sql @@ -699,6 +699,13 @@ LANGUAGE INTERNAL PARALLEL SAFE AS 'pg_get_expr'; +CREATE OR REPLACE FUNCTION + pg_get_triggerdef(trigger oid, pretty bool DEFAULT false) +RETURNS TEXT +LANGUAGE INTERNAL +PARALLEL SAFE +AS 'pg_get_triggerdef'; + -- -- The default permissions for functions mean that anyone can execute them. -- A number of functions shouldn't be executable by just anyone, but rather diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index d87b361a093..598c916ddb6 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -807,20 +807,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 4304ab220ba..bf00983b3ff 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -3983,9 +3983,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8551,7 +8548,7 @@ prosrc => 'pg_timezone_names' }, { oid => '2730', descr => 'trigger description with pretty-print option', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', diff --git a/src/include/catalog/pg_retired.dat b/src/include/catalog/pg_retired.dat index 8b5f58850f6..46764648040 100644 --- a/src/include/catalog/pg_retired.dat +++ b/src/include/catalog/pg_retired.dat @@ -22,6 +22,7 @@ { oid => '1640', proname => 'pg_get_viewdef' }, { oid => '1641', proname => 'pg_get_viewdef' }, { oid => '1643', proname => 'pg_get_indexdef' }, +{ oid => '1662', proname => 'pg_get_triggerdef' }, { oid => '1716', proname => 'pg_get_expr' } ] -- 2.43.0 --zd8Z8rlPOcTi77n/-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v8 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use proargdefaults to handle the optional pretty argument. --- src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 8 +++----- 2 files changed, 3 insertions(+), 19 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index e60478677e0..bfa5ef7910b 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -818,20 +818,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 71bd2aaf3d9..d7a6493dd19 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -4003,9 +4003,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8640,9 +8637,10 @@ proallargtypes => '{text,text,interval,bool}', proargmodes => '{o,o,o,o}', proargnames => '{name,abbrev,utc_offset,is_dst}', prosrc => 'pg_timezone_names' }, -{ oid => '2730', descr => 'trigger description with pretty-print option', +{ oid => '2730', descr => 'trigger description', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', proargnames => '{trigger,pretty}', + proargdefaults => '{false}', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.53.0 --iWwo79nqhOvOs5kf-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v5 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use proargdefaults to handle the optional pretty argument. --- src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 6 ++---- 2 files changed, 2 insertions(+), 18 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 972f89eafbc..bd0ca6891c3 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -818,20 +818,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index f36f4625e50..43844bb6862 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -3997,9 +3997,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8630,7 +8627,8 @@ prosrc => 'pg_timezone_names' }, { oid => '2730', descr => 'trigger description with pretty-print option', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', proargnames => '{trigger,pretty}', + proargdefaults => '{false}', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.52.0 --m23X5uHFNxthGTU3-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v1 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use CREATE OR REPLACE FUNCTION to handle the optional pretty argument. --- src/backend/catalog/system_functions.sql | 7 +++++++ src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 5 +---- 3 files changed, 8 insertions(+), 18 deletions(-) diff --git a/src/backend/catalog/system_functions.sql b/src/backend/catalog/system_functions.sql index 81d210a9c45..c9c011ea5c1 100644 --- a/src/backend/catalog/system_functions.sql +++ b/src/backend/catalog/system_functions.sql @@ -699,6 +699,13 @@ LANGUAGE INTERNAL PARALLEL SAFE AS 'pg_get_expr'; +CREATE OR REPLACE FUNCTION + pg_get_triggerdef(trigger oid, pretty bool DEFAULT false) +RETURNS TEXT +LANGUAGE INTERNAL +PARALLEL SAFE +AS 'pg_get_triggerdef'; + -- -- The default permissions for functions mean that anyone can execute them. -- A number of functions shouldn't be executable by just anyone, but rather diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 9effa02fa2e..45a35f823e8 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -807,20 +807,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 10c5286bd7d..146963c254b 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -3974,9 +3974,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8535,7 +8532,7 @@ prosrc => 'pg_timezone_names' }, { oid => '2730', descr => 'trigger description with pretty-print option', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.51.2 --IRGsBYp1UN8d6WrT-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v1 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use CREATE OR REPLACE FUNCTION to handle the optional pretty argument. --- src/backend/catalog/system_functions.sql | 7 +++++++ src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 5 +---- 3 files changed, 8 insertions(+), 18 deletions(-) diff --git a/src/backend/catalog/system_functions.sql b/src/backend/catalog/system_functions.sql index 81d210a9c45..c9c011ea5c1 100644 --- a/src/backend/catalog/system_functions.sql +++ b/src/backend/catalog/system_functions.sql @@ -699,6 +699,13 @@ LANGUAGE INTERNAL PARALLEL SAFE AS 'pg_get_expr'; +CREATE OR REPLACE FUNCTION + pg_get_triggerdef(trigger oid, pretty bool DEFAULT false) +RETURNS TEXT +LANGUAGE INTERNAL +PARALLEL SAFE +AS 'pg_get_triggerdef'; + -- -- The default permissions for functions mean that anyone can execute them. -- A number of functions shouldn't be executable by just anyone, but rather diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 9effa02fa2e..45a35f823e8 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -807,20 +807,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 10c5286bd7d..146963c254b 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -3974,9 +3974,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8535,7 +8532,7 @@ prosrc => 'pg_timezone_names' }, { oid => '2730', descr => 'trigger description with pretty-print option', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.51.2 --IRGsBYp1UN8d6WrT-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v5 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use proargdefaults to handle the optional pretty argument. --- src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 6 ++---- 2 files changed, 2 insertions(+), 18 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 972f89eafbc..bd0ca6891c3 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -818,20 +818,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index f36f4625e50..43844bb6862 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -3997,9 +3997,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8630,7 +8627,8 @@ prosrc => 'pg_timezone_names' }, { oid => '2730', descr => 'trigger description with pretty-print option', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', proargnames => '{trigger,pretty}', + proargdefaults => '{false}', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.52.0 --m23X5uHFNxthGTU3-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v8.1 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use proargdefaults to handle the optional pretty argument. --- src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 8 +++----- 2 files changed, 3 insertions(+), 19 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index e60478677e0..bfa5ef7910b 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -818,20 +818,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index df43469be3d..7cccfe6d7a7 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -4003,9 +4003,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8640,9 +8637,10 @@ proallargtypes => '{text,text,interval,bool}', proargmodes => '{o,o,o,o}', proargnames => '{name,abbrev,utc_offset,is_dst}', prosrc => 'pg_timezone_names' }, -{ oid => '2730', descr => 'trigger description with pretty-print option', +{ oid => '2730', descr => 'trigger description', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', proargnames => '{trigger,pretty}', + proargdefaults => '{false}', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.53.0 --AcCatzXgbvyipyEy-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v7 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use proargdefaults to handle the optional pretty argument. --- src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 8 +++----- 2 files changed, 3 insertions(+), 19 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 707f83d4310..249f4518f62 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -818,20 +818,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 855529509de..f4df55370e7 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -4003,9 +4003,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8673,9 +8670,10 @@ proallargtypes => '{text,text,interval,bool}', proargmodes => '{o,o,o,o}', proargnames => '{name,abbrev,utc_offset,is_dst}', prosrc => 'pg_timezone_names' }, -{ oid => '2730', descr => 'trigger description with pretty-print option', +{ oid => '2730', descr => 'trigger description', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', proargnames => '{trigger,pretty}', + proargdefaults => '{false}', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.52.0 --GzYugJnip6WHHvTk-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v8 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use proargdefaults to handle the optional pretty argument. --- src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 8 +++----- 2 files changed, 3 insertions(+), 19 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index e60478677e0..bfa5ef7910b 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -818,20 +818,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 71bd2aaf3d9..d7a6493dd19 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -4003,9 +4003,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8640,9 +8637,10 @@ proallargtypes => '{text,text,interval,bool}', proargmodes => '{o,o,o,o}', proargnames => '{name,abbrev,utc_offset,is_dst}', prosrc => 'pg_timezone_names' }, -{ oid => '2730', descr => 'trigger description with pretty-print option', +{ oid => '2730', descr => 'trigger description', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', proargnames => '{trigger,pretty}', + proargdefaults => '{false}', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.53.0 --iWwo79nqhOvOs5kf-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v8.1 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use proargdefaults to handle the optional pretty argument. --- src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 8 +++----- 2 files changed, 3 insertions(+), 19 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index e60478677e0..bfa5ef7910b 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -818,20 +818,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index df43469be3d..7cccfe6d7a7 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -4003,9 +4003,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8640,9 +8637,10 @@ proallargtypes => '{text,text,interval,bool}', proargmodes => '{o,o,o,o}', proargnames => '{name,abbrev,utc_offset,is_dst}', prosrc => 'pg_timezone_names' }, -{ oid => '2730', descr => 'trigger description with pretty-print option', +{ oid => '2730', descr => 'trigger description', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', proargnames => '{trigger,pretty}', + proargdefaults => '{false}', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.53.0 --AcCatzXgbvyipyEy-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v8 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use proargdefaults to handle the optional pretty argument. --- src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 8 +++----- 2 files changed, 3 insertions(+), 19 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index e60478677e0..bfa5ef7910b 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -818,20 +818,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 71bd2aaf3d9..d7a6493dd19 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -4003,9 +4003,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8640,9 +8637,10 @@ proallargtypes => '{text,text,interval,bool}', proargmodes => '{o,o,o,o}', proargnames => '{name,abbrev,utc_offset,is_dst}', prosrc => 'pg_timezone_names' }, -{ oid => '2730', descr => 'trigger description with pretty-print option', +{ oid => '2730', descr => 'trigger description', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', proargnames => '{trigger,pretty}', + proargdefaults => '{false}', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.53.0 --iWwo79nqhOvOs5kf-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v4 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use proargdefaults to handle the optional pretty argument. --- src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 6 ++---- 2 files changed, 2 insertions(+), 18 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index a70807e84ca..27be4501e12 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -808,20 +808,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 69c1e5bb264..b43cbb62b82 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -3984,9 +3984,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8566,7 +8563,8 @@ prosrc => 'pg_timezone_names' }, { oid => '2730', descr => 'trigger description with pretty-print option', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', proargnames => '{trigger,pretty}', + proargdefaults => '{false}', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.43.0 --eEEy3EHc57lA8spa-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v2 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use CREATE OR REPLACE FUNCTION to handle the optional pretty argument. --- src/backend/catalog/system_functions.sql | 7 +++++++ src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 5 +---- 3 files changed, 8 insertions(+), 18 deletions(-) diff --git a/src/backend/catalog/system_functions.sql b/src/backend/catalog/system_functions.sql index a6f7cdf3a36..08b9b68d0cd 100644 --- a/src/backend/catalog/system_functions.sql +++ b/src/backend/catalog/system_functions.sql @@ -699,6 +699,13 @@ LANGUAGE INTERNAL PARALLEL SAFE AS 'pg_get_expr'; +CREATE OR REPLACE FUNCTION + pg_get_triggerdef(trigger oid, pretty bool DEFAULT false) +RETURNS TEXT +LANGUAGE INTERNAL +PARALLEL SAFE +AS 'pg_get_triggerdef'; + -- -- The default permissions for functions mean that anyone can execute them. -- A number of functions shouldn't be executable by just anyone, but rather diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 305e3e80c41..188d367b113 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -807,20 +807,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 3a0be2d4b2a..d644a391e0e 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -3983,9 +3983,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8551,7 +8548,7 @@ prosrc => 'pg_timezone_names' }, { oid => '2730', descr => 'trigger description with pretty-print option', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.43.0 --3/nz5wg6+DYwHsLU-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v1 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use CREATE OR REPLACE FUNCTION to handle the optional pretty argument. --- src/backend/catalog/system_functions.sql | 7 +++++++ src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 5 +---- 3 files changed, 8 insertions(+), 18 deletions(-) diff --git a/src/backend/catalog/system_functions.sql b/src/backend/catalog/system_functions.sql index 81d210a9c45..c9c011ea5c1 100644 --- a/src/backend/catalog/system_functions.sql +++ b/src/backend/catalog/system_functions.sql @@ -699,6 +699,13 @@ LANGUAGE INTERNAL PARALLEL SAFE AS 'pg_get_expr'; +CREATE OR REPLACE FUNCTION + pg_get_triggerdef(trigger oid, pretty bool DEFAULT false) +RETURNS TEXT +LANGUAGE INTERNAL +PARALLEL SAFE +AS 'pg_get_triggerdef'; + -- -- The default permissions for functions mean that anyone can execute them. -- A number of functions shouldn't be executable by just anyone, but rather diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 9effa02fa2e..45a35f823e8 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -807,20 +807,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 10c5286bd7d..146963c254b 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -3974,9 +3974,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8535,7 +8532,7 @@ prosrc => 'pg_timezone_names' }, { oid => '2730', descr => 'trigger description with pretty-print option', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.51.2 --IRGsBYp1UN8d6WrT-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v8.1 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use proargdefaults to handle the optional pretty argument. --- src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 8 +++----- 2 files changed, 3 insertions(+), 19 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index e60478677e0..bfa5ef7910b 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -818,20 +818,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index df43469be3d..7cccfe6d7a7 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -4003,9 +4003,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8640,9 +8637,10 @@ proallargtypes => '{text,text,interval,bool}', proargmodes => '{o,o,o,o}', proargnames => '{name,abbrev,utc_offset,is_dst}', prosrc => 'pg_timezone_names' }, -{ oid => '2730', descr => 'trigger description with pretty-print option', +{ oid => '2730', descr => 'trigger description', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', proargnames => '{trigger,pretty}', + proargdefaults => '{false}', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.53.0 --AcCatzXgbvyipyEy-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v8.1 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use proargdefaults to handle the optional pretty argument. --- src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 8 +++----- 2 files changed, 3 insertions(+), 19 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index e60478677e0..bfa5ef7910b 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -818,20 +818,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index df43469be3d..7cccfe6d7a7 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -4003,9 +4003,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8640,9 +8637,10 @@ proallargtypes => '{text,text,interval,bool}', proargmodes => '{o,o,o,o}', proargnames => '{name,abbrev,utc_offset,is_dst}', prosrc => 'pg_timezone_names' }, -{ oid => '2730', descr => 'trigger description with pretty-print option', +{ oid => '2730', descr => 'trigger description', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', proargnames => '{trigger,pretty}', + proargdefaults => '{false}', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.53.0 --AcCatzXgbvyipyEy-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v8 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use proargdefaults to handle the optional pretty argument. --- src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 8 +++----- 2 files changed, 3 insertions(+), 19 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index e60478677e0..bfa5ef7910b 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -818,20 +818,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 71bd2aaf3d9..d7a6493dd19 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -4003,9 +4003,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8640,9 +8637,10 @@ proallargtypes => '{text,text,interval,bool}', proargmodes => '{o,o,o,o}', proargnames => '{name,abbrev,utc_offset,is_dst}', prosrc => 'pg_timezone_names' }, -{ oid => '2730', descr => 'trigger description with pretty-print option', +{ oid => '2730', descr => 'trigger description', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', proargnames => '{trigger,pretty}', + proargdefaults => '{false}', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.53.0 --iWwo79nqhOvOs5kf-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v5 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use proargdefaults to handle the optional pretty argument. --- src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 6 ++---- 2 files changed, 2 insertions(+), 18 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 972f89eafbc..bd0ca6891c3 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -818,20 +818,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index f36f4625e50..43844bb6862 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -3997,9 +3997,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8630,7 +8627,8 @@ prosrc => 'pg_timezone_names' }, { oid => '2730', descr => 'trigger description with pretty-print option', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', proargnames => '{trigger,pretty}', + proargdefaults => '{false}', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.52.0 --m23X5uHFNxthGTU3-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v8.1 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use proargdefaults to handle the optional pretty argument. --- src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 8 +++----- 2 files changed, 3 insertions(+), 19 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index e60478677e0..bfa5ef7910b 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -818,20 +818,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index df43469be3d..7cccfe6d7a7 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -4003,9 +4003,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8640,9 +8637,10 @@ proallargtypes => '{text,text,interval,bool}', proargmodes => '{o,o,o,o}', proargnames => '{name,abbrev,utc_offset,is_dst}', prosrc => 'pg_timezone_names' }, -{ oid => '2730', descr => 'trigger description with pretty-print option', +{ oid => '2730', descr => 'trigger description', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', proargnames => '{trigger,pretty}', + proargdefaults => '{false}', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.53.0 --AcCatzXgbvyipyEy-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v7 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use proargdefaults to handle the optional pretty argument. --- src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 8 +++----- 2 files changed, 3 insertions(+), 19 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 707f83d4310..249f4518f62 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -818,20 +818,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 855529509de..f4df55370e7 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -4003,9 +4003,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8673,9 +8670,10 @@ proallargtypes => '{text,text,interval,bool}', proargmodes => '{o,o,o,o}', proargnames => '{name,abbrev,utc_offset,is_dst}', prosrc => 'pg_timezone_names' }, -{ oid => '2730', descr => 'trigger description with pretty-print option', +{ oid => '2730', descr => 'trigger description', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', proargnames => '{trigger,pretty}', + proargdefaults => '{false}', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.52.0 --GzYugJnip6WHHvTk-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v5 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use proargdefaults to handle the optional pretty argument. --- src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 6 ++---- 2 files changed, 2 insertions(+), 18 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 972f89eafbc..bd0ca6891c3 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -818,20 +818,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index f36f4625e50..43844bb6862 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -3997,9 +3997,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8630,7 +8627,8 @@ prosrc => 'pg_timezone_names' }, { oid => '2730', descr => 'trigger description with pretty-print option', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', proargnames => '{trigger,pretty}', + proargdefaults => '{false}', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.52.0 --m23X5uHFNxthGTU3-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v7 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use proargdefaults to handle the optional pretty argument. --- src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 8 +++----- 2 files changed, 3 insertions(+), 19 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 707f83d4310..249f4518f62 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -818,20 +818,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 855529509de..f4df55370e7 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -4003,9 +4003,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8673,9 +8670,10 @@ proallargtypes => '{text,text,interval,bool}', proargmodes => '{o,o,o,o}', proargnames => '{name,abbrev,utc_offset,is_dst}', prosrc => 'pg_timezone_names' }, -{ oid => '2730', descr => 'trigger description with pretty-print option', +{ oid => '2730', descr => 'trigger description', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', proargnames => '{trigger,pretty}', + proargdefaults => '{false}', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.52.0 --GzYugJnip6WHHvTk-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v8 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use proargdefaults to handle the optional pretty argument. --- src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 8 +++----- 2 files changed, 3 insertions(+), 19 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index e60478677e0..bfa5ef7910b 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -818,20 +818,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 71bd2aaf3d9..d7a6493dd19 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -4003,9 +4003,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8640,9 +8637,10 @@ proallargtypes => '{text,text,interval,bool}', proargmodes => '{o,o,o,o}', proargnames => '{name,abbrev,utc_offset,is_dst}', prosrc => 'pg_timezone_names' }, -{ oid => '2730', descr => 'trigger description with pretty-print option', +{ oid => '2730', descr => 'trigger description', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', proargnames => '{trigger,pretty}', + proargdefaults => '{false}', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.53.0 --iWwo79nqhOvOs5kf-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v3 7/7] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use CREATE OR REPLACE FUNCTION to handle the optional pretty argument. --- src/backend/catalog/system_functions.sql | 7 +++++++ src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 5 +---- src/include/catalog/pg_retired.dat | 1 + 4 files changed, 9 insertions(+), 18 deletions(-) diff --git a/src/backend/catalog/system_functions.sql b/src/backend/catalog/system_functions.sql index a6f7cdf3a36..08b9b68d0cd 100644 --- a/src/backend/catalog/system_functions.sql +++ b/src/backend/catalog/system_functions.sql @@ -699,6 +699,13 @@ LANGUAGE INTERNAL PARALLEL SAFE AS 'pg_get_expr'; +CREATE OR REPLACE FUNCTION + pg_get_triggerdef(trigger oid, pretty bool DEFAULT false) +RETURNS TEXT +LANGUAGE INTERNAL +PARALLEL SAFE +AS 'pg_get_triggerdef'; + -- -- The default permissions for functions mean that anyone can execute them. -- A number of functions shouldn't be executable by just anyone, but rather diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index d87b361a093..598c916ddb6 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -807,20 +807,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 4304ab220ba..bf00983b3ff 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -3983,9 +3983,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8551,7 +8548,7 @@ prosrc => 'pg_timezone_names' }, { oid => '2730', descr => 'trigger description with pretty-print option', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', diff --git a/src/include/catalog/pg_retired.dat b/src/include/catalog/pg_retired.dat index 8b5f58850f6..46764648040 100644 --- a/src/include/catalog/pg_retired.dat +++ b/src/include/catalog/pg_retired.dat @@ -22,6 +22,7 @@ { oid => '1640', proname => 'pg_get_viewdef' }, { oid => '1641', proname => 'pg_get_viewdef' }, { oid => '1643', proname => 'pg_get_indexdef' }, +{ oid => '1662', proname => 'pg_get_triggerdef' }, { oid => '1716', proname => 'pg_get_expr' } ] -- 2.43.0 --zd8Z8rlPOcTi77n/-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v1 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use CREATE OR REPLACE FUNCTION to handle the optional pretty argument. --- src/backend/catalog/system_functions.sql | 7 +++++++ src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 5 +---- 3 files changed, 8 insertions(+), 18 deletions(-) diff --git a/src/backend/catalog/system_functions.sql b/src/backend/catalog/system_functions.sql index 81d210a9c45..c9c011ea5c1 100644 --- a/src/backend/catalog/system_functions.sql +++ b/src/backend/catalog/system_functions.sql @@ -699,6 +699,13 @@ LANGUAGE INTERNAL PARALLEL SAFE AS 'pg_get_expr'; +CREATE OR REPLACE FUNCTION + pg_get_triggerdef(trigger oid, pretty bool DEFAULT false) +RETURNS TEXT +LANGUAGE INTERNAL +PARALLEL SAFE +AS 'pg_get_triggerdef'; + -- -- The default permissions for functions mean that anyone can execute them. -- A number of functions shouldn't be executable by just anyone, but rather diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 9effa02fa2e..45a35f823e8 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -807,20 +807,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 10c5286bd7d..146963c254b 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -3974,9 +3974,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8535,7 +8532,7 @@ prosrc => 'pg_timezone_names' }, { oid => '2730', descr => 'trigger description with pretty-print option', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.51.2 --IRGsBYp1UN8d6WrT-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v1 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use CREATE OR REPLACE FUNCTION to handle the optional pretty argument. --- src/backend/catalog/system_functions.sql | 7 +++++++ src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 5 +---- 3 files changed, 8 insertions(+), 18 deletions(-) diff --git a/src/backend/catalog/system_functions.sql b/src/backend/catalog/system_functions.sql index 81d210a9c45..c9c011ea5c1 100644 --- a/src/backend/catalog/system_functions.sql +++ b/src/backend/catalog/system_functions.sql @@ -699,6 +699,13 @@ LANGUAGE INTERNAL PARALLEL SAFE AS 'pg_get_expr'; +CREATE OR REPLACE FUNCTION + pg_get_triggerdef(trigger oid, pretty bool DEFAULT false) +RETURNS TEXT +LANGUAGE INTERNAL +PARALLEL SAFE +AS 'pg_get_triggerdef'; + -- -- The default permissions for functions mean that anyone can execute them. -- A number of functions shouldn't be executable by just anyone, but rather diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 9effa02fa2e..45a35f823e8 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -807,20 +807,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 10c5286bd7d..146963c254b 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -3974,9 +3974,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8535,7 +8532,7 @@ prosrc => 'pg_timezone_names' }, { oid => '2730', descr => 'trigger description with pretty-print option', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.51.2 --IRGsBYp1UN8d6WrT-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v2 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use CREATE OR REPLACE FUNCTION to handle the optional pretty argument. --- src/backend/catalog/system_functions.sql | 7 +++++++ src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 5 +---- 3 files changed, 8 insertions(+), 18 deletions(-) diff --git a/src/backend/catalog/system_functions.sql b/src/backend/catalog/system_functions.sql index a6f7cdf3a36..08b9b68d0cd 100644 --- a/src/backend/catalog/system_functions.sql +++ b/src/backend/catalog/system_functions.sql @@ -699,6 +699,13 @@ LANGUAGE INTERNAL PARALLEL SAFE AS 'pg_get_expr'; +CREATE OR REPLACE FUNCTION + pg_get_triggerdef(trigger oid, pretty bool DEFAULT false) +RETURNS TEXT +LANGUAGE INTERNAL +PARALLEL SAFE +AS 'pg_get_triggerdef'; + -- -- The default permissions for functions mean that anyone can execute them. -- A number of functions shouldn't be executable by just anyone, but rather diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 305e3e80c41..188d367b113 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -807,20 +807,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 3a0be2d4b2a..d644a391e0e 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -3983,9 +3983,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8551,7 +8548,7 @@ prosrc => 'pg_timezone_names' }, { oid => '2730', descr => 'trigger description with pretty-print option', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.43.0 --3/nz5wg6+DYwHsLU-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v7 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use proargdefaults to handle the optional pretty argument. --- src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 8 +++----- 2 files changed, 3 insertions(+), 19 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 707f83d4310..249f4518f62 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -818,20 +818,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 855529509de..f4df55370e7 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -4003,9 +4003,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8673,9 +8670,10 @@ proallargtypes => '{text,text,interval,bool}', proargmodes => '{o,o,o,o}', proargnames => '{name,abbrev,utc_offset,is_dst}', prosrc => 'pg_timezone_names' }, -{ oid => '2730', descr => 'trigger description with pretty-print option', +{ oid => '2730', descr => 'trigger description', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', proargnames => '{trigger,pretty}', + proargdefaults => '{false}', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.52.0 --GzYugJnip6WHHvTk-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v8 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use proargdefaults to handle the optional pretty argument. --- src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 8 +++----- 2 files changed, 3 insertions(+), 19 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index e60478677e0..bfa5ef7910b 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -818,20 +818,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 71bd2aaf3d9..d7a6493dd19 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -4003,9 +4003,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8640,9 +8637,10 @@ proallargtypes => '{text,text,interval,bool}', proargmodes => '{o,o,o,o}', proargnames => '{name,abbrev,utc_offset,is_dst}', prosrc => 'pg_timezone_names' }, -{ oid => '2730', descr => 'trigger description with pretty-print option', +{ oid => '2730', descr => 'trigger description', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', proargnames => '{trigger,pretty}', + proargdefaults => '{false}', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.53.0 --iWwo79nqhOvOs5kf-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v3 7/7] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use CREATE OR REPLACE FUNCTION to handle the optional pretty argument. --- src/backend/catalog/system_functions.sql | 7 +++++++ src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 5 +---- src/include/catalog/pg_retired.dat | 1 + 4 files changed, 9 insertions(+), 18 deletions(-) diff --git a/src/backend/catalog/system_functions.sql b/src/backend/catalog/system_functions.sql index a6f7cdf3a36..08b9b68d0cd 100644 --- a/src/backend/catalog/system_functions.sql +++ b/src/backend/catalog/system_functions.sql @@ -699,6 +699,13 @@ LANGUAGE INTERNAL PARALLEL SAFE AS 'pg_get_expr'; +CREATE OR REPLACE FUNCTION + pg_get_triggerdef(trigger oid, pretty bool DEFAULT false) +RETURNS TEXT +LANGUAGE INTERNAL +PARALLEL SAFE +AS 'pg_get_triggerdef'; + -- -- The default permissions for functions mean that anyone can execute them. -- A number of functions shouldn't be executable by just anyone, but rather diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index d87b361a093..598c916ddb6 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -807,20 +807,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 4304ab220ba..bf00983b3ff 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -3983,9 +3983,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8551,7 +8548,7 @@ prosrc => 'pg_timezone_names' }, { oid => '2730', descr => 'trigger description with pretty-print option', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', diff --git a/src/include/catalog/pg_retired.dat b/src/include/catalog/pg_retired.dat index 8b5f58850f6..46764648040 100644 --- a/src/include/catalog/pg_retired.dat +++ b/src/include/catalog/pg_retired.dat @@ -22,6 +22,7 @@ { oid => '1640', proname => 'pg_get_viewdef' }, { oid => '1641', proname => 'pg_get_viewdef' }, { oid => '1643', proname => 'pg_get_indexdef' }, +{ oid => '1662', proname => 'pg_get_triggerdef' }, { oid => '1716', proname => 'pg_get_expr' } ] -- 2.43.0 --zd8Z8rlPOcTi77n/-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v1 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use CREATE OR REPLACE FUNCTION to handle the optional pretty argument. --- src/backend/catalog/system_functions.sql | 7 +++++++ src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 5 +---- 3 files changed, 8 insertions(+), 18 deletions(-) diff --git a/src/backend/catalog/system_functions.sql b/src/backend/catalog/system_functions.sql index 81d210a9c45..c9c011ea5c1 100644 --- a/src/backend/catalog/system_functions.sql +++ b/src/backend/catalog/system_functions.sql @@ -699,6 +699,13 @@ LANGUAGE INTERNAL PARALLEL SAFE AS 'pg_get_expr'; +CREATE OR REPLACE FUNCTION + pg_get_triggerdef(trigger oid, pretty bool DEFAULT false) +RETURNS TEXT +LANGUAGE INTERNAL +PARALLEL SAFE +AS 'pg_get_triggerdef'; + -- -- The default permissions for functions mean that anyone can execute them. -- A number of functions shouldn't be executable by just anyone, but rather diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 9effa02fa2e..45a35f823e8 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -807,20 +807,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 10c5286bd7d..146963c254b 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -3974,9 +3974,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8535,7 +8532,7 @@ prosrc => 'pg_timezone_names' }, { oid => '2730', descr => 'trigger description with pretty-print option', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.51.2 --IRGsBYp1UN8d6WrT-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v4 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use proargdefaults to handle the optional pretty argument. --- src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 6 ++---- 2 files changed, 2 insertions(+), 18 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index a70807e84ca..27be4501e12 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -808,20 +808,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 69c1e5bb264..b43cbb62b82 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -3984,9 +3984,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8566,7 +8563,8 @@ prosrc => 'pg_timezone_names' }, { oid => '2730', descr => 'trigger description with pretty-print option', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', proargnames => '{trigger,pretty}', + proargdefaults => '{false}', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.43.0 --eEEy3EHc57lA8spa-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v3 7/7] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use CREATE OR REPLACE FUNCTION to handle the optional pretty argument. --- src/backend/catalog/system_functions.sql | 7 +++++++ src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 5 +---- src/include/catalog/pg_retired.dat | 1 + 4 files changed, 9 insertions(+), 18 deletions(-) diff --git a/src/backend/catalog/system_functions.sql b/src/backend/catalog/system_functions.sql index a6f7cdf3a36..08b9b68d0cd 100644 --- a/src/backend/catalog/system_functions.sql +++ b/src/backend/catalog/system_functions.sql @@ -699,6 +699,13 @@ LANGUAGE INTERNAL PARALLEL SAFE AS 'pg_get_expr'; +CREATE OR REPLACE FUNCTION + pg_get_triggerdef(trigger oid, pretty bool DEFAULT false) +RETURNS TEXT +LANGUAGE INTERNAL +PARALLEL SAFE +AS 'pg_get_triggerdef'; + -- -- The default permissions for functions mean that anyone can execute them. -- A number of functions shouldn't be executable by just anyone, but rather diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index d87b361a093..598c916ddb6 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -807,20 +807,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 4304ab220ba..bf00983b3ff 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -3983,9 +3983,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8551,7 +8548,7 @@ prosrc => 'pg_timezone_names' }, { oid => '2730', descr => 'trigger description with pretty-print option', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', diff --git a/src/include/catalog/pg_retired.dat b/src/include/catalog/pg_retired.dat index 8b5f58850f6..46764648040 100644 --- a/src/include/catalog/pg_retired.dat +++ b/src/include/catalog/pg_retired.dat @@ -22,6 +22,7 @@ { oid => '1640', proname => 'pg_get_viewdef' }, { oid => '1641', proname => 'pg_get_viewdef' }, { oid => '1643', proname => 'pg_get_indexdef' }, +{ oid => '1662', proname => 'pg_get_triggerdef' }, { oid => '1716', proname => 'pg_get_expr' } ] -- 2.43.0 --zd8Z8rlPOcTi77n/-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v4 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use proargdefaults to handle the optional pretty argument. --- src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 6 ++---- 2 files changed, 2 insertions(+), 18 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index a70807e84ca..27be4501e12 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -808,20 +808,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 69c1e5bb264..b43cbb62b82 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -3984,9 +3984,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8566,7 +8563,8 @@ prosrc => 'pg_timezone_names' }, { oid => '2730', descr => 'trigger description with pretty-print option', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', proargnames => '{trigger,pretty}', + proargdefaults => '{false}', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.43.0 --eEEy3EHc57lA8spa-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v8.1 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use proargdefaults to handle the optional pretty argument. --- src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 8 +++----- 2 files changed, 3 insertions(+), 19 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index e60478677e0..bfa5ef7910b 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -818,20 +818,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index df43469be3d..7cccfe6d7a7 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -4003,9 +4003,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8640,9 +8637,10 @@ proallargtypes => '{text,text,interval,bool}', proargmodes => '{o,o,o,o}', proargnames => '{name,abbrev,utc_offset,is_dst}', prosrc => 'pg_timezone_names' }, -{ oid => '2730', descr => 'trigger description with pretty-print option', +{ oid => '2730', descr => 'trigger description', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', proargnames => '{trigger,pretty}', + proargdefaults => '{false}', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.53.0 --AcCatzXgbvyipyEy-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v2 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use CREATE OR REPLACE FUNCTION to handle the optional pretty argument. --- src/backend/catalog/system_functions.sql | 7 +++++++ src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 5 +---- 3 files changed, 8 insertions(+), 18 deletions(-) diff --git a/src/backend/catalog/system_functions.sql b/src/backend/catalog/system_functions.sql index a6f7cdf3a36..08b9b68d0cd 100644 --- a/src/backend/catalog/system_functions.sql +++ b/src/backend/catalog/system_functions.sql @@ -699,6 +699,13 @@ LANGUAGE INTERNAL PARALLEL SAFE AS 'pg_get_expr'; +CREATE OR REPLACE FUNCTION + pg_get_triggerdef(trigger oid, pretty bool DEFAULT false) +RETURNS TEXT +LANGUAGE INTERNAL +PARALLEL SAFE +AS 'pg_get_triggerdef'; + -- -- The default permissions for functions mean that anyone can execute them. -- A number of functions shouldn't be executable by just anyone, but rather diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 305e3e80c41..188d367b113 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -807,20 +807,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 3a0be2d4b2a..d644a391e0e 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -3983,9 +3983,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8551,7 +8548,7 @@ prosrc => 'pg_timezone_names' }, { oid => '2730', descr => 'trigger description with pretty-print option', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.43.0 --3/nz5wg6+DYwHsLU-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v3 7/7] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use CREATE OR REPLACE FUNCTION to handle the optional pretty argument. --- src/backend/catalog/system_functions.sql | 7 +++++++ src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 5 +---- src/include/catalog/pg_retired.dat | 1 + 4 files changed, 9 insertions(+), 18 deletions(-) diff --git a/src/backend/catalog/system_functions.sql b/src/backend/catalog/system_functions.sql index a6f7cdf3a36..08b9b68d0cd 100644 --- a/src/backend/catalog/system_functions.sql +++ b/src/backend/catalog/system_functions.sql @@ -699,6 +699,13 @@ LANGUAGE INTERNAL PARALLEL SAFE AS 'pg_get_expr'; +CREATE OR REPLACE FUNCTION + pg_get_triggerdef(trigger oid, pretty bool DEFAULT false) +RETURNS TEXT +LANGUAGE INTERNAL +PARALLEL SAFE +AS 'pg_get_triggerdef'; + -- -- The default permissions for functions mean that anyone can execute them. -- A number of functions shouldn't be executable by just anyone, but rather diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index d87b361a093..598c916ddb6 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -807,20 +807,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 4304ab220ba..bf00983b3ff 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -3983,9 +3983,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8551,7 +8548,7 @@ prosrc => 'pg_timezone_names' }, { oid => '2730', descr => 'trigger description with pretty-print option', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', diff --git a/src/include/catalog/pg_retired.dat b/src/include/catalog/pg_retired.dat index 8b5f58850f6..46764648040 100644 --- a/src/include/catalog/pg_retired.dat +++ b/src/include/catalog/pg_retired.dat @@ -22,6 +22,7 @@ { oid => '1640', proname => 'pg_get_viewdef' }, { oid => '1641', proname => 'pg_get_viewdef' }, { oid => '1643', proname => 'pg_get_indexdef' }, +{ oid => '1662', proname => 'pg_get_triggerdef' }, { oid => '1716', proname => 'pg_get_expr' } ] -- 2.43.0 --zd8Z8rlPOcTi77n/-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v3 7/7] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use CREATE OR REPLACE FUNCTION to handle the optional pretty argument. --- src/backend/catalog/system_functions.sql | 7 +++++++ src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 5 +---- src/include/catalog/pg_retired.dat | 1 + 4 files changed, 9 insertions(+), 18 deletions(-) diff --git a/src/backend/catalog/system_functions.sql b/src/backend/catalog/system_functions.sql index a6f7cdf3a36..08b9b68d0cd 100644 --- a/src/backend/catalog/system_functions.sql +++ b/src/backend/catalog/system_functions.sql @@ -699,6 +699,13 @@ LANGUAGE INTERNAL PARALLEL SAFE AS 'pg_get_expr'; +CREATE OR REPLACE FUNCTION + pg_get_triggerdef(trigger oid, pretty bool DEFAULT false) +RETURNS TEXT +LANGUAGE INTERNAL +PARALLEL SAFE +AS 'pg_get_triggerdef'; + -- -- The default permissions for functions mean that anyone can execute them. -- A number of functions shouldn't be executable by just anyone, but rather diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index d87b361a093..598c916ddb6 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -807,20 +807,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 4304ab220ba..bf00983b3ff 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -3983,9 +3983,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8551,7 +8548,7 @@ prosrc => 'pg_timezone_names' }, { oid => '2730', descr => 'trigger description with pretty-print option', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', diff --git a/src/include/catalog/pg_retired.dat b/src/include/catalog/pg_retired.dat index 8b5f58850f6..46764648040 100644 --- a/src/include/catalog/pg_retired.dat +++ b/src/include/catalog/pg_retired.dat @@ -22,6 +22,7 @@ { oid => '1640', proname => 'pg_get_viewdef' }, { oid => '1641', proname => 'pg_get_viewdef' }, { oid => '1643', proname => 'pg_get_indexdef' }, +{ oid => '1662', proname => 'pg_get_triggerdef' }, { oid => '1716', proname => 'pg_get_expr' } ] -- 2.43.0 --zd8Z8rlPOcTi77n/-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v3 7/7] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use CREATE OR REPLACE FUNCTION to handle the optional pretty argument. --- src/backend/catalog/system_functions.sql | 7 +++++++ src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 5 +---- src/include/catalog/pg_retired.dat | 1 + 4 files changed, 9 insertions(+), 18 deletions(-) diff --git a/src/backend/catalog/system_functions.sql b/src/backend/catalog/system_functions.sql index a6f7cdf3a36..08b9b68d0cd 100644 --- a/src/backend/catalog/system_functions.sql +++ b/src/backend/catalog/system_functions.sql @@ -699,6 +699,13 @@ LANGUAGE INTERNAL PARALLEL SAFE AS 'pg_get_expr'; +CREATE OR REPLACE FUNCTION + pg_get_triggerdef(trigger oid, pretty bool DEFAULT false) +RETURNS TEXT +LANGUAGE INTERNAL +PARALLEL SAFE +AS 'pg_get_triggerdef'; + -- -- The default permissions for functions mean that anyone can execute them. -- A number of functions shouldn't be executable by just anyone, but rather diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index d87b361a093..598c916ddb6 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -807,20 +807,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 4304ab220ba..bf00983b3ff 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -3983,9 +3983,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8551,7 +8548,7 @@ prosrc => 'pg_timezone_names' }, { oid => '2730', descr => 'trigger description with pretty-print option', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', diff --git a/src/include/catalog/pg_retired.dat b/src/include/catalog/pg_retired.dat index 8b5f58850f6..46764648040 100644 --- a/src/include/catalog/pg_retired.dat +++ b/src/include/catalog/pg_retired.dat @@ -22,6 +22,7 @@ { oid => '1640', proname => 'pg_get_viewdef' }, { oid => '1641', proname => 'pg_get_viewdef' }, { oid => '1643', proname => 'pg_get_indexdef' }, +{ oid => '1662', proname => 'pg_get_triggerdef' }, { oid => '1716', proname => 'pg_get_expr' } ] -- 2.43.0 --zd8Z8rlPOcTi77n/-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v7 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use proargdefaults to handle the optional pretty argument. --- src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 8 +++----- 2 files changed, 3 insertions(+), 19 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 707f83d4310..249f4518f62 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -818,20 +818,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 855529509de..f4df55370e7 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -4003,9 +4003,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8673,9 +8670,10 @@ proallargtypes => '{text,text,interval,bool}', proargmodes => '{o,o,o,o}', proargnames => '{name,abbrev,utc_offset,is_dst}', prosrc => 'pg_timezone_names' }, -{ oid => '2730', descr => 'trigger description with pretty-print option', +{ oid => '2730', descr => 'trigger description', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', proargnames => '{trigger,pretty}', + proargdefaults => '{false}', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.52.0 --GzYugJnip6WHHvTk-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v3 7/7] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use CREATE OR REPLACE FUNCTION to handle the optional pretty argument. --- src/backend/catalog/system_functions.sql | 7 +++++++ src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 5 +---- src/include/catalog/pg_retired.dat | 1 + 4 files changed, 9 insertions(+), 18 deletions(-) diff --git a/src/backend/catalog/system_functions.sql b/src/backend/catalog/system_functions.sql index a6f7cdf3a36..08b9b68d0cd 100644 --- a/src/backend/catalog/system_functions.sql +++ b/src/backend/catalog/system_functions.sql @@ -699,6 +699,13 @@ LANGUAGE INTERNAL PARALLEL SAFE AS 'pg_get_expr'; +CREATE OR REPLACE FUNCTION + pg_get_triggerdef(trigger oid, pretty bool DEFAULT false) +RETURNS TEXT +LANGUAGE INTERNAL +PARALLEL SAFE +AS 'pg_get_triggerdef'; + -- -- The default permissions for functions mean that anyone can execute them. -- A number of functions shouldn't be executable by just anyone, but rather diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index d87b361a093..598c916ddb6 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -807,20 +807,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 4304ab220ba..bf00983b3ff 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -3983,9 +3983,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8551,7 +8548,7 @@ prosrc => 'pg_timezone_names' }, { oid => '2730', descr => 'trigger description with pretty-print option', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', diff --git a/src/include/catalog/pg_retired.dat b/src/include/catalog/pg_retired.dat index 8b5f58850f6..46764648040 100644 --- a/src/include/catalog/pg_retired.dat +++ b/src/include/catalog/pg_retired.dat @@ -22,6 +22,7 @@ { oid => '1640', proname => 'pg_get_viewdef' }, { oid => '1641', proname => 'pg_get_viewdef' }, { oid => '1643', proname => 'pg_get_indexdef' }, +{ oid => '1662', proname => 'pg_get_triggerdef' }, { oid => '1716', proname => 'pg_get_expr' } ] -- 2.43.0 --zd8Z8rlPOcTi77n/-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v3 7/7] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use CREATE OR REPLACE FUNCTION to handle the optional pretty argument. --- src/backend/catalog/system_functions.sql | 7 +++++++ src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 5 +---- src/include/catalog/pg_retired.dat | 1 + 4 files changed, 9 insertions(+), 18 deletions(-) diff --git a/src/backend/catalog/system_functions.sql b/src/backend/catalog/system_functions.sql index a6f7cdf3a36..08b9b68d0cd 100644 --- a/src/backend/catalog/system_functions.sql +++ b/src/backend/catalog/system_functions.sql @@ -699,6 +699,13 @@ LANGUAGE INTERNAL PARALLEL SAFE AS 'pg_get_expr'; +CREATE OR REPLACE FUNCTION + pg_get_triggerdef(trigger oid, pretty bool DEFAULT false) +RETURNS TEXT +LANGUAGE INTERNAL +PARALLEL SAFE +AS 'pg_get_triggerdef'; + -- -- The default permissions for functions mean that anyone can execute them. -- A number of functions shouldn't be executable by just anyone, but rather diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index d87b361a093..598c916ddb6 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -807,20 +807,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 4304ab220ba..bf00983b3ff 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -3983,9 +3983,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8551,7 +8548,7 @@ prosrc => 'pg_timezone_names' }, { oid => '2730', descr => 'trigger description with pretty-print option', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', diff --git a/src/include/catalog/pg_retired.dat b/src/include/catalog/pg_retired.dat index 8b5f58850f6..46764648040 100644 --- a/src/include/catalog/pg_retired.dat +++ b/src/include/catalog/pg_retired.dat @@ -22,6 +22,7 @@ { oid => '1640', proname => 'pg_get_viewdef' }, { oid => '1641', proname => 'pg_get_viewdef' }, { oid => '1643', proname => 'pg_get_indexdef' }, +{ oid => '1662', proname => 'pg_get_triggerdef' }, { oid => '1716', proname => 'pg_get_expr' } ] -- 2.43.0 --zd8Z8rlPOcTi77n/-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v4 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use proargdefaults to handle the optional pretty argument. --- src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 6 ++---- 2 files changed, 2 insertions(+), 18 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index a70807e84ca..27be4501e12 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -808,20 +808,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 69c1e5bb264..b43cbb62b82 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -3984,9 +3984,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8566,7 +8563,8 @@ prosrc => 'pg_timezone_names' }, { oid => '2730', descr => 'trigger description with pretty-print option', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', proargnames => '{trigger,pretty}', + proargdefaults => '{false}', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.43.0 --eEEy3EHc57lA8spa-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v7 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use proargdefaults to handle the optional pretty argument. --- src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 8 +++----- 2 files changed, 3 insertions(+), 19 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 707f83d4310..249f4518f62 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -818,20 +818,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 855529509de..f4df55370e7 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -4003,9 +4003,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8673,9 +8670,10 @@ proallargtypes => '{text,text,interval,bool}', proargmodes => '{o,o,o,o}', proargnames => '{name,abbrev,utc_offset,is_dst}', prosrc => 'pg_timezone_names' }, -{ oid => '2730', descr => 'trigger description with pretty-print option', +{ oid => '2730', descr => 'trigger description', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', proargnames => '{trigger,pretty}', + proargdefaults => '{false}', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.52.0 --GzYugJnip6WHHvTk-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v7 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use proargdefaults to handle the optional pretty argument. --- src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 8 +++----- 2 files changed, 3 insertions(+), 19 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 707f83d4310..249f4518f62 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -818,20 +818,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 855529509de..f4df55370e7 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -4003,9 +4003,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8673,9 +8670,10 @@ proallargtypes => '{text,text,interval,bool}', proargmodes => '{o,o,o,o}', proargnames => '{name,abbrev,utc_offset,is_dst}', prosrc => 'pg_timezone_names' }, -{ oid => '2730', descr => 'trigger description with pretty-print option', +{ oid => '2730', descr => 'trigger description', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', proargnames => '{trigger,pretty}', + proargdefaults => '{false}', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.52.0 --GzYugJnip6WHHvTk-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v7 6/6] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use proargdefaults to handle the optional pretty argument. --- src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 8 +++----- 2 files changed, 3 insertions(+), 19 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 707f83d4310..249f4518f62 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -818,20 +818,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 855529509de..f4df55370e7 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -4003,9 +4003,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8673,9 +8670,10 @@ proallargtypes => '{text,text,interval,bool}', proargmodes => '{o,o,o,o}', proargnames => '{name,abbrev,utc_offset,is_dst}', prosrc => 'pg_timezone_names' }, -{ oid => '2730', descr => 'trigger description with pretty-print option', +{ oid => '2730', descr => 'trigger description', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', proargnames => '{trigger,pretty}', + proargdefaults => '{false}', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', -- 2.52.0 --GzYugJnip6WHHvTk-- ^ permalink raw reply [nested|flat] 166+ messages in thread
* [PATCH v3 7/7] Handle pg_get_triggerdef default args in system_functions.sql @ 2025-12-09 19:51 Mark Wong <[email protected]> 0 siblings, 0 replies; 166+ messages in thread From: Mark Wong @ 2025-12-09 19:51 UTC (permalink / raw) Modernize pg_get_triggerdef to use CREATE OR REPLACE FUNCTION to handle the optional pretty argument. --- src/backend/catalog/system_functions.sql | 7 +++++++ src/backend/utils/adt/ruleutils.c | 14 -------------- src/include/catalog/pg_proc.dat | 5 +---- src/include/catalog/pg_retired.dat | 1 + 4 files changed, 9 insertions(+), 18 deletions(-) diff --git a/src/backend/catalog/system_functions.sql b/src/backend/catalog/system_functions.sql index a6f7cdf3a36..08b9b68d0cd 100644 --- a/src/backend/catalog/system_functions.sql +++ b/src/backend/catalog/system_functions.sql @@ -699,6 +699,13 @@ LANGUAGE INTERNAL PARALLEL SAFE AS 'pg_get_expr'; +CREATE OR REPLACE FUNCTION + pg_get_triggerdef(trigger oid, pretty bool DEFAULT false) +RETURNS TEXT +LANGUAGE INTERNAL +PARALLEL SAFE +AS 'pg_get_triggerdef'; + -- -- The default permissions for functions mean that anyone can execute them. -- A number of functions shouldn't be executable by just anyone, but rather diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index d87b361a093..598c916ddb6 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -807,20 +807,6 @@ pg_get_viewdef_worker(Oid viewoid, int prettyFlags, int wrapColumn) */ Datum pg_get_triggerdef(PG_FUNCTION_ARGS) -{ - Oid trigid = PG_GETARG_OID(0); - char *res; - - res = pg_get_triggerdef_worker(trigid, false); - - if (res == NULL) - PG_RETURN_NULL(); - - PG_RETURN_TEXT_P(string_to_text(res)); -} - -Datum -pg_get_triggerdef_ext(PG_FUNCTION_ARGS) { Oid trigid = PG_GETARG_OID(0); bool pretty = PG_GETARG_BOOL(1); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 4304ab220ba..bf00983b3ff 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -3983,9 +3983,6 @@ proname => 'pg_get_partition_constraintdef', provolatile => 's', prorettype => 'text', proargtypes => 'oid', prosrc => 'pg_get_partition_constraintdef' }, -{ oid => '1662', descr => 'trigger description', - proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid', prosrc => 'pg_get_triggerdef' }, { oid => '1665', descr => 'name of sequence for a serial column', proname => 'pg_get_serial_sequence', provolatile => 's', prorettype => 'text', proargtypes => 'text text', prosrc => 'pg_get_serial_sequence' }, @@ -8551,7 +8548,7 @@ prosrc => 'pg_timezone_names' }, { oid => '2730', descr => 'trigger description with pretty-print option', proname => 'pg_get_triggerdef', provolatile => 's', prorettype => 'text', - proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef_ext' }, + proargtypes => 'oid bool', prosrc => 'pg_get_triggerdef' }, # asynchronous notifications { oid => '3035', diff --git a/src/include/catalog/pg_retired.dat b/src/include/catalog/pg_retired.dat index 8b5f58850f6..46764648040 100644 --- a/src/include/catalog/pg_retired.dat +++ b/src/include/catalog/pg_retired.dat @@ -22,6 +22,7 @@ { oid => '1640', proname => 'pg_get_viewdef' }, { oid => '1641', proname => 'pg_get_viewdef' }, { oid => '1643', proname => 'pg_get_indexdef' }, +{ oid => '1662', proname => 'pg_get_triggerdef' }, { oid => '1716', proname => 'pg_get_expr' } ] -- 2.43.0 --zd8Z8rlPOcTi77n/-- ^ permalink raw reply [nested|flat] 166+ messages in thread
end of thread, other threads:[~2025-12-09 19:51 UTC | newest] Thread overview: 166+ messages (download: mbox mbox.gz follow: Atom feed) -- links below jump to the message on this page -- 2019-12-20 01:25 [PATCH v29 11/11] Add documentations about Incremental View Maintenance Yugo Nagata <[email protected]> 2022-04-04 18:54 [PATCH 09/11] regress tests for session variables [email protected] <[email protected]> 2022-04-04 18:54 [PATCH 09/11] regress tests for session variables [email protected] <[email protected]> 2022-04-04 18:54 [PATCH v20220922 10/13] regress tests for session variables [email protected] <[email protected]> 2022-04-04 18:54 [PATCH v20220916 10/13] regress tests for session variables [email protected] <[email protected]> 2022-04-04 18:54 [PATCH v20220916 10/13] regress tests for session variables [email protected] <[email protected]> 2025-12-09 19:51 [PATCH v4 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v1 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v2 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v8.1 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v8.1 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v5 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v8 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v4 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v7 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v1 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v5 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v7 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v3 7/7] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v1 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v1 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v2 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v5 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v1 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v4 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v4 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v5 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v4 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v8.1 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v2 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v8.1 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v8 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v4 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v3 7/7] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v3 7/7] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v8.1 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v8 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v3 7/7] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v7 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v8.1 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v5 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v5 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v2 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v7 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v8.1 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v8 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v1 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v1 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v2 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v8.1 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v3 7/7] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v1 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v8 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v2 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v4 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v4 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v4 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v2 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v8.1 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v8 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v7 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v7 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v8.1 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v7 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v2 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v4 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v4 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v8 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v5 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v7 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v2 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v2 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v2 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v8 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v4 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v7 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v3 7/7] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v7 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v8 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v2 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v5 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v2 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v5 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v8 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v5 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v8 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v2 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v4 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v8 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v8.1 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v2 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v7 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v5 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v1 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v4 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v3 7/7] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v3 7/7] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v8.1 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v1 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v5 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v2 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v5 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v5 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v4 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v5 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v5 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v7 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v2 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v1 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v8 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v8.1 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v1 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v8 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v4 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v8.1 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v3 7/7] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v1 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v1 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v3 7/7] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v3 7/7] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v8 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v5 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v1 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v1 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v5 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v8.1 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v7 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v8 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v8.1 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v8 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v4 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v2 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v1 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v8.1 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v8.1 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v8 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v5 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v8.1 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v7 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v5 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v7 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v8 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v3 7/7] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v1 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v1 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v2 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v7 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v8 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v3 7/7] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v1 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v4 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v3 7/7] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v4 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v8.1 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v2 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v3 7/7] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v3 7/7] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v3 7/7] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v7 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v3 7/7] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v3 7/7] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v4 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v7 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v7 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v7 6/6] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]> 2025-12-09 19:51 [PATCH v3 7/7] Handle pg_get_triggerdef default args in system_functions.sql Mark Wong <[email protected]>
This inbox is served by agora; see mirroring instructions for how to clone and mirror all data and code used for this inbox