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 1t9Jta-009CMY-UZ for pgsql-general@arkaria.postgresql.org; Fri, 08 Nov 2024 07:59:06 +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 1t9JtX-0070ZM-14 for pgsql-general@arkaria.postgresql.org; Fri, 08 Nov 2024 07:59:03 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1t9JtW-0070ZE-La for pgsql-general@lists.postgresql.org; Fri, 08 Nov 2024 07:59:03 +0000 Received: from mail-pj1-x1035.google.com ([2607:f8b0:4864:20::1035]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.94.2) (envelope-from ) id 1t9JtU-000lsV-0Y for pgsql-general@lists.postgresql.org; Fri, 08 Nov 2024 07:59:02 +0000 Received: by mail-pj1-x1035.google.com with SMTP id 98e67ed59e1d1-2e2e23f2931so1496574a91.0 for ; Thu, 07 Nov 2024 23:58:59 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1731052738; x=1731657538; darn=lists.postgresql.org; h=to:subject:message-id:date:from:mime-version:from:to:cc:subject :date:message-id:reply-to; bh=CGplJTndf1P2rXdozcB858B8CKamVECTQwka4e/F7bE=; b=EpP0QScgcAVuVZUazO+jbydzug9qqVzjNZU35OPIfLg6J3xvvAi0wjJVSmNUSph2hn gziPISnSZcchbZS0+bLMN2kG3JPrezV3wlU+92oc3c7f2HGp8a+J759Y8kR39MFAVnAO GZ0Po48G+zE69oLQRf5R6t8JgxcTkNsxmYAWV/M5dds57a+hvf0sHpFvrk45F0MHRcg9 F6yfoVVgWshvFcs6sPTe9NODcKaFQzUTHs6SfPO5xx+tn46rB1sb77KyS/ZRlt9SFyZD Xx0p8CPm9RSdy7WHkzxop0zeGB4fS1qMlkhaIvD3cND+UwVTzk1grAxvc6l6hIWpNs35 QmHA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1731052738; x=1731657538; h=to:subject:message-id:date:from:mime-version:x-gm-message-state :from:to:cc:subject:date:message-id:reply-to; bh=CGplJTndf1P2rXdozcB858B8CKamVECTQwka4e/F7bE=; b=X9van49BvrpMmV8CM3YuLxY3wuRjmsytQZqDOwSENkqcfppYXxdiPYDEW1F6u94aFk CMPDaqvS6Smhj0F2scfFtlkJS005TuKg9YbOQz3KtLO+VvMvVf4w6OoACvb83Tqm48VW gLcimYLnxg+9x6TQB2WrFXRLZZJB1dPBFAWu9x/qoqrkmxx1M83FDyBuE/OkqNOG1/72 ioCYtTkmHnQOOckzfNzuguunvvExOqNnanmAnFGLlRnMofRNNH8IWp0wrjxzjvaEGMaz +/g8B/RlHNbC2r5xSXfi6IQMyzOabp0NCY5hPE+7p2/RApy0IrLh5KdVN0RX3DypYKXR NgJQ== X-Gm-Message-State: AOJu0YzIXPsV43of06rR9Wgp2VGzJzFWHquFX3a8spFrJiB3FIvs6VWq oe9ImpcnCKhMN36LVANyaFKhl+q5iWJ07fEnKpk/TsYP7S5OBvwyjlPnxV1sLAgexANZL+gjWQe dU9n6I3B5S/zxc6C0QIp+DzqsK5ysuqO+ X-Google-Smtp-Source: AGHT+IFx6y7isnAeLrKYbu1Fw+L8SU9PcDkEHYkHi7Io2bjkGjK2UOh4Gjs0Ygam9nHTVRAT4hAZkbLTijG42CSQD2Y= X-Received: by 2002:a17:90b:1844:b0:2e2:cd6b:c6ca with SMTP id 98e67ed59e1d1-2e9b17760aamr2647818a91.25.1731052738031; Thu, 07 Nov 2024 23:58:58 -0800 (PST) MIME-Version: 1.0 From: =?UTF-8?Q?Micha=C5=82_Albrycht?= Date: Fri, 8 Nov 2024 08:58:47 +0100 Message-ID: Subject: Why plpython functions increase transaction counter much more then plpgsql functions? To: pgsql-general@lists.postgresql.org Content-Type: multipart/alternative; boundary="00000000000089bc3e0626621ffe" List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --00000000000089bc3e0626621ffe Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable 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 that 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 makes 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 --00000000000089bc3e0626621ffe Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
I'm trying to understand why plpython function has muc= h bigger impact on transaction counter in Postgres than plpgSQL function. B= elow is example which uses 2 functions:

Version with plpgSQL (each p= art done in separate transactions one after another)
=C2=A0- check txid_= current
=C2=A0- SQL query which calls the `f1_plpgsql` function =C2=A0wh= ich calls the `insert_row_to_db` function 100 times
=C2=A0- check txid_c= urrent
=C2=A0
=C2=A0Then we compare txid_currnent values and differe= nce is 2 which means that whole sql with 100 calls to `f1_plpgsql` and `ins= ert_row_to_db` increased transaction counter only by 1.
=C2=A0
Here i= s the code:
```
CREATE TABLE insert_rows_table(
=C2=A0 =C2=A0 i BI= GINT
);

CREATE OR REPLACE FUNCTION insert_row_to_db(i BIGINT)
= RETURNS VOID
AS $$
BEGIN
=C2=A0 =C2=A0 INSERT INTO insert_rows_tab= le SELECT i;
END
$$ LANGUAGE plpgsql SECURITY DEFINER VOLATILE PARALL= EL UNSAFE;


CREATE OR REPLACE FUNCTION f1_plpgsql(i BIGINT)
= =C2=A0 RETURNS bigint
AS $$
BEGIN
=C2=A0 =C2=A0 PERFORM insert_row= _to_db(i);
=C2=A0 =C2=A0 RETURN i;
END
$$ LANGUAGE plpgsql SECURIT= Y DEFINER VOLATILE PARALLEL UNSAFE;


SELECT txid_current();
SE= LECT 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/4jyoMC= icNSZpjMt4jFYoz5/15135

Now let's replace `f1_plpgsql` with f= unction written in plpython:

```
CREATE OR REPLACE FUNCTION f1_pl= python(i BIGINT)
=C2=A0 RETURNS bigint
AS $$
=C2=A0 =C2=A0 rows = =3D plpy.execute("SELECT insert_row_to_db(" + str(i) + ")&qu= ot;)
=C2=A0 =C2=A0 return i
$$ LANGUAGE plpython3u SECURITY DEFINER V= OLATILE 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 cou= nter much more. Does anyone know why? Is there anything I can do about it?<= br>
What's interesting it happens only if the function called by plp= yhon makes changes to DB. When I replace `INSERT INTO insert_rows_table SEL= ECT i;` with `SELECT i` both plpython and plpgsql functions behave the same= .
=C2=A0Regards,

Micha=C5=82 Albrycht
=C2=A0<= /div>
--00000000000089bc3e0626621ffe--