Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1t9PaZ-009yPy-5R for pgsql-general@arkaria.postgresql.org; Fri, 08 Nov 2024 14:03:50 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.94.2) (envelope-from ) id 1t9PaV-009Ti8-Fn for pgsql-general@arkaria.postgresql.org; Fri, 08 Nov 2024 14:03:48 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1t9PaV-009Thz-38 for pgsql-general@lists.postgresql.org; Fri, 08 Nov 2024 14:03:47 +0000 Received: from mail-oo1-xc2a.google.com ([2607:f8b0:4864:20::c2a]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.94.2) (envelope-from ) id 1t9PaR-000rFD-20 for pgsql-general@lists.postgresql.org; Fri, 08 Nov 2024 14:03:46 +0000 Received: by mail-oo1-xc2a.google.com with SMTP id 006d021491bc7-5ee461f5dedso1289700eaf.0 for ; Fri, 08 Nov 2024 06:03:43 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1731074622; x=1731679422; darn=lists.postgresql.org; h=to:subject:message-id:date:from:in-reply-to:references:mime-version :from:to:cc:subject:date:message-id:reply-to; bh=X07QEM7Su5JDasoV+HNoIxj6aEaKQn0vVNDvngaSscs=; b=de33i7A33QgPvAdsMG837XdtjT96TQiCKJZWmIzKedd1JL1Kxc129RxvutlcVikDqm npt1wvCpR7yEVN4iVKrnDpse5xWrMJvJrp5ahQHsjh8VRePFnLO5Yi/6iJLSXYtPgTz/ knP5MTamXVpbW4Ft5zEuo7GIbsojdDPZh4ZdnEfGlfrehUG8SU3uoV9ZqSPoP1VX58p1 lOyjD6jFEzkwuAWNLNDLEFnME+nr/H8NWESgz/vUoMAQrwYZtlpHGMZNs2caAMgJqePa Ra9jtcIqkYtyeoajQ5fUNHyCKphVjYmGbiFy2AlLMYPn/MctZSeWaxQeUZD8QYdIMQFj Tfqg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1731074622; x=1731679422; h=to:subject:message-id:date:from:in-reply-to:references:mime-version :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=X07QEM7Su5JDasoV+HNoIxj6aEaKQn0vVNDvngaSscs=; b=Y9c8sMi89z5Vp6xbiiKymTF8jU3iWIVB4X2awFhsHHTIKLoj5X7OkMt8VPUnwvW0yn etPCMkKkHyGOt8htB1gxKlbBtzTJnGY9vxKaq6PjuH4p8rRiWM4yQ7YIHL7t8AJ9oMde GXbNOpttIhrPAF/eG7GgcnjqBTiI9KoNodSKq+M9IvxTaa3hbuwXuQOtM9EdK7YKMMLT dTfztIRjwnEm7RJmY56shKKGYoH3kXKwaFNoBha9RIUIsmNI1s03/85yNFyIO47+GZoo tx9JPQnuICxPMwc8ATeIJnZXuHVjFSb40XBTcasXdBovhPrAYiKtyjlNE6v1RVZhquqa bv/w== X-Gm-Message-State: AOJu0YyWErV38KYmBvXf7uV+8zVK3TWVFR8hEtfXz4X3wFTsLQR/pTMG 1MbHCN9mw5JEBjEPUfaZJ6HIwD+XeuX7SVAErm23H6FIXL5IrE/sPTYLSRh5/JW1kR8xSmMOdF3 jniCvrKUySQjHL9ih50BeEHhmxbYwwg== X-Google-Smtp-Source: AGHT+IGBybw+xD2sojWBrUnj22rTfpteFhPCrQ047xEeXnYg45Ft1rUqUYjLYE809LaUF0wzrj7YC4hts/jx8OKti+8= X-Received: by 2002:a05:6820:4b0a:b0:5eb:c6ba:796d with SMTP id 006d021491bc7-5ee57ba9b64mr2994810eaf.1.1731074621756; Fri, 08 Nov 2024 06:03:41 -0800 (PST) MIME-Version: 1.0 References: In-Reply-To: From: Ron Johnson Date: Fri, 8 Nov 2024 09:03:30 -0500 Message-ID: Subject: Re: Why plpython functions increase transaction counter much more then plpgsql functions? To: "pgsql-generallists.postgresql.org" Content-Type: multipart/alternative; boundary="000000000000e8ddaa062667378a" List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --000000000000e8ddaa062667378a Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Because the plpython function is executing dynamic SQL? On Fri, Nov 8, 2024 at 2:59=E2=80=AFAM Micha=C5=82 Albrycht wrote: > I'm trying to understand why plpython function has much bigger impact on > transaction counter in Postgres than plpgSQL function. Below is example > which uses 2 functions: > > Version with plpgSQL (each part done in separate transactions one after > another) > - check txid_current > - SQL query which calls the `f1_plpgsql` function which calls the > `insert_row_to_db` function 100 times > - check txid_current > > Then we compare txid_currnent values and difference is 2 which means tha= t > whole sql with 100 calls to `f1_plpgsql` and `insert_row_to_db` increased > transaction counter only by 1. > > Here is the code: > ``` > CREATE TABLE insert_rows_table( > i BIGINT > ); > > CREATE OR REPLACE FUNCTION insert_row_to_db(i BIGINT) > RETURNS VOID > AS $$ > BEGIN > INSERT INTO insert_rows_table SELECT i; > END > $$ LANGUAGE plpgsql SECURITY DEFINER VOLATILE PARALLEL UNSAFE; > > > CREATE OR REPLACE FUNCTION f1_plpgsql(i BIGINT) > RETURNS bigint > AS $$ > BEGIN > PERFORM insert_row_to_db(i); > RETURN i; > END > $$ LANGUAGE plpgsql SECURITY DEFINER VOLATILE PARALLEL UNSAFE; > > > SELECT txid_current(); > SELECT f1_plpgsql(i::BIGINT) FROM generate_series(1,100) as i; > SELECT txid_current(); > ``` > > Example output: > > txid_current > 500 > > f1_plpgsql > 1 > 2 > ... > 99 > 100 > > txid_current > 502 > > > Here is a code reproduction on db-fiddle: > https://www.db-fiddle.com/f/4jyoMCicNSZpjMt4jFYoz5/15135 > > Now let's replace `f1_plpgsql` with function written in plpython: > > ``` > CREATE OR REPLACE FUNCTION f1_plpython(i BIGINT) > RETURNS bigint > AS $$ > rows =3D plpy.execute("SELECT insert_row_to_db(" + str(i) + ")") > return i > $$ LANGUAGE plpython3u SECURITY DEFINER VOLATILE PARALLEL UNSAFE; > ``` > > I get: > > txid_current > 500 > > f1_plpgsql > 1 > 2 > ... > 99 > 100 > > txid_current > 602 > > > This proves that the plpython function affects the transaction counter > much more. Does anyone know why? Is there anything I can do about it? > > What's interesting it happens only if the function called by plpyhon make= s > changes to DB. When I replace `INSERT INTO insert_rows_table SELECT i;` > with `SELECT i` both plpython and plpgsql functions behave the same. > Regards, > > Micha=C5=82 Albrycht > > --=20 Death to , and butter sauce. Don't boil me, I'm still alive. lobster! --000000000000e8ddaa062667378a Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
Because the plpython function is executing dynamic SQ= L?

On Fri, Nov 8, 2024 at 2:59=E2=80=AFAM Micha=C5=82 Albrycht <michalalbrycht@gmail.com> wrote= :
I'm trying to understand why plpython function has much bigger impac= t on transaction counter in Postgres than plpgSQL function. Below is exampl= e which uses 2 functions:

Version with plpgSQL (each part done in se= parate transactions one after another)
=C2=A0- check txid_current
=C2= =A0- SQL query which calls the `f1_plpgsql` function =C2=A0which calls the = `insert_row_to_db` function 100 times
=C2=A0- check txid_current
=C2= =A0
=C2=A0Then we compare txid_currnent values and difference is 2 which= means that whole sql with 100 calls to `f1_plpgsql` and `insert_row_to_db`= increased transaction counter only by 1.
=C2=A0
Here is the code:```
CREATE TABLE insert_rows_table(
=C2=A0 =C2=A0 i BIGINT
);
=
CREATE OR REPLACE FUNCTION insert_row_to_db(i BIGINT)
RETURNS VOIDAS $$
BEGIN
=C2=A0 =C2=A0 INSERT INTO insert_rows_table SELECT i;END
$$ LANGUAGE plpgsql SECURITY DEFINER VOLATILE PARALLEL UNSAFE;
=

CREATE OR REPLACE FUNCTION f1_plpgsql(i BIGINT)
=C2=A0 RETURNS b= igint
AS $$
BEGIN
=C2=A0 =C2=A0 PERFORM insert_row_to_db(i);
= =C2=A0 =C2=A0 RETURN i;
END
$$ LANGUAGE plpgsql SECURITY DEFINER VOLA= TILE PARALLEL UNSAFE;


SELECT txid_current();
SELECT f1_plpgsq= l(i::BIGINT) FROM generate_series(1,100) as i;
SELECT txid_current();```

Example output:

txid_current
500

f1_plpgsql1
2
...
99
100

txid_current
502


Here is a= code reproduction on db-fiddle: https://www.db-fiddle.com/f/4j= yoMCicNSZpjMt4jFYoz5/15135

Now let's replace `f1_plpgsql` wi= th function written in plpython:

```
CREATE OR REPLACE FUNCTION f= 1_plpython(i BIGINT)
=C2=A0 RETURNS bigint
AS $$
=C2=A0 =C2=A0 row= s =3D plpy.execute("SELECT insert_row_to_db(" + str(i) + ")&= quot;)
=C2=A0 =C2=A0 return i
$$ LANGUAGE plpython3u SECURITY DEFINER= VOLATILE PARALLEL UNSAFE;
```

I get:

txid_current
500<= br>
f1_plpgsql
1
2
...
99
100

txid_current
602<= br>

This proves that the plpython function affects the transaction c= ounter much more. Does anyone know why? Is there anything I can do about it= ?

What's interesting it happens only if the function called by p= lpyhon makes changes to DB. When I replace `INSERT INTO insert_rows_table S= ELECT i;` with `SELECT i` both plpython and plpgsql functions behave the sa= me.
=C2=A0Regards,

Micha=C5=82 Albrycht
=C2= =A0


--
Death to <Redacted>, and butter sauce.Don't boil me, I'm still alive.
<Redacted> lobs= ter!
--000000000000e8ddaa062667378a--