From: | "Jonathan S(dot) Katz" <jkatz(at)postgresql(dot)org> |
---|---|
To: | vignesh C <vignesh21(at)gmail(dot)com>, PostgreSQL Hackers <pgsql-hackers(at)lists(dot)postgresql(dot)org> |
Subject: | Re: The output sql generated by pg_dump for a create function refers to a modified table name |
Date: | 2023-02-17 14:06:09 |
Message-ID: | 7aec721c-f75a-c769-55c3-2130e9159506@postgresql.org |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-hackers |
On 2/17/23 5:22 AM, vignesh C wrote:
> Hi,
>
> The output sql generated by pg_dump for the below function refers to a
> modified table name:
> create table t1 (c1 int);
> create table t2 (c1 int);
>
> CREATE OR REPLACE FUNCTION test_fun(c1 int)
> RETURNS void
> LANGUAGE SQL
> BEGIN ATOMIC
> WITH delete_t1 AS (
> DELETE FROM t1 WHERE c1 = $1
> )
> INSERT INTO t1 (c1) SELECT $1 FROM t2;
> END;
>
> The below sql output created by pg_dump refers to t1_1 which should
> have been t1:
> CREATE FUNCTION public.test_fun(c1 integer) RETURNS void
> LANGUAGE sql
> BEGIN ATOMIC
> WITH delete_t1 AS (
> DELETE FROM public.t1
> WHERE (t1_1.c1 = test_fun.c1)
> )
> INSERT INTO public.t1 (c1) SELECT test_fun.c1
> FROM public.t2;
> END;
>
> pg_get_function_sqlbody also returns similar result:
> select proname, pg_get_function_sqlbody(oid) from pg_proc where
> proname = 'test_fun';
> proname | pg_get_function_sqlbody
> ----------+-------------------------------------------
> test_fun | BEGIN ATOMIC +
> | WITH delete_t1 AS ( +
> | DELETE FROM t1 +
> | WHERE (t1_1.c1 = test_fun.c1) +
> | ) +
> | INSERT INTO t1 (c1) SELECT test_fun.c1+
> | FROM t2; +
> | END
> (1 row)
Thanks for reproducing and demonstrating that this was more generally
applicable. For context, this was initially discovered when testing the
DDL replication patch[1] under that context.
> I felt the problem here is with set_rtable_names function which
> changes the relation name t1 to t1_1 while parsing the statement:
> /*
> * If the selected name isn't unique, append digits to make it so, and
> * make a new hash entry for it once we've got a unique name. For a
> * very long input name, we might have to truncate to stay within
> * NAMEDATALEN.
> */
>
> During the query generation we will set the table names before
> generating each statement, in our case the table t1 would have been
> added already to the hash table during the first insert statement
> generation. Next time it will try to set the relation names again for
> the next statement, i.e delete statement, if the entry with same name
> already exists, it will change the name to t1_1 by appending a digit
> to keep the has entry unique.
Good catch. Do you have thoughts on how we can adjust the naming logic
to handle cases like this?
Jonathan
[1]
https://www.postgresql.org/message-id/e947fa21-24b2-f922-375a-d4f763ef3e4b%40postgresql.org
From | Date | Subject | |
---|---|---|---|
Next Message | Drouvot, Bertrand | 2023-02-17 14:13:17 | Re: Change xl_hash_vacuum_one_page.ntuples from int to uint16 |
Previous Message | Laurenz Albe | 2023-02-17 12:23:12 | Re: Move defaults toward ICU in 16? |