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.96) (envelope-from ) id 1vNbm9-008LCI-04 for pgsql-interfaces@arkaria.postgresql.org; Mon, 24 Nov 2025 18:59:01 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1vNbm7-003I0R-1o for pgsql-interfaces@arkaria.postgresql.org; Mon, 24 Nov 2025 18:58:59 +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.96) (envelope-from ) id 1vNbm7-003I0J-0e for pgsql-interfaces@lists.postgresql.org; Mon, 24 Nov 2025 18:58:59 +0000 Received: from mail-lf1-x12b.google.com ([2a00:1450:4864:20::12b]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.96) (envelope-from ) id 1vNbm4-001FeA-1W for pgsql-interfaces@lists.postgresql.org; Mon, 24 Nov 2025 18:58:58 +0000 Received: by mail-lf1-x12b.google.com with SMTP id 2adb3069b0e04-59578e38613so5385060e87.2 for ; Mon, 24 Nov 2025 10:58:57 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1764010735; x=1764615535; darn=lists.postgresql.org; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=Yk7nV0aglIG9z4Ec/K3qlqA31G+M91mC4rklKpltFpo=; b=d/lr7cf+09Nb+sJKZtDW6cqxHsc9TugdsujlsDXxsG7GnrXE5sS6twcWidh2qZ6MZu haZm4cjFTdOCXeHiMEllOW6wRrUHKAeZUle9+g4YGJHAxhny2GMEJm+OVC8AAhqWC8AB IX0j0jjjqJVP/8ZY0wazTU5Tmyrzd67ba/iEOxGwLFeyeCp88HVNINS1I0uBTv3u68Is KfwLMLYMclkhjttsZrw6wlREZ+W+ikdRNEvij4XRZigfDtqMBqCZy8vcmpMNrlalz9iM PGBU1NVVeCim7jJuWrUvd67mdZqsqx95uMq5Gd7DvWXQI7FvB0lMuHC5wrBdP3bO1kLu shWw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1764010735; x=1764615535; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=Yk7nV0aglIG9z4Ec/K3qlqA31G+M91mC4rklKpltFpo=; b=cMJe2fXG6/54bFgUBODHcdpjVGHwSFujJZLRXhdx2ncp+QUuezlYa1oNECnsw8umbI QQ62Df7zx7qSL3JBTGD76z1cU821Cj8mpdQ9JNk1gT5X/HFl9vybQY4dWEAqZn2cZOVG XFQ/UWhoKHBkG+1wlsws/LkTJTO4ubHOFMUy1dhKKI+OEJs0eF5C5SgYJ8sxTcjzNKhj XRBTjYCdKUucKN9MLpzgJHTOvcNeqIMXjiawbE2M1CeVrIsvZeR44YlSR2qKludec9jk 46SaqEuTHprclNUgn1h53JUCbXJNE+mmBYtn198ckNG1E+kKNJOOg3C36P4aipdUratJ d/qA== X-Gm-Message-State: AOJu0YxoMFEQyy1WYRhzcHUGdpmZIqD6Ah16/p+IMsMlRicBQpW3PgSV pnTFwT5/DjKr7bU4iRAdKhXFEN03pDvIh5+z0JCcWSpiu0lLTv1okhaL3cedu6Uqx99TqjbFuRE wiQza+a0tLkz5cBuMDfXoZjosOh/jaiia2Cjc X-Gm-Gg: ASbGncuxaDtLcIN9WQQZsCNZ/mYEuDiyBoZDc5Uk+OAGXjFskOvzUMnlnB/XPK1OROo RWX+Tykp2AIahN1U38es3ReKIYOGmBBPgOqcZRBxxEWg/7VBJ1dqM6IfC3Ooa5DlXLB60Ez9mHY 4MJMPYvWvowRQ9qaHIjzZjn2dq21DJdmcD2tPehnb0pI/L5eX8it4eQbEDstHe0Firp4IjVNLfs 4agmPasx/49jJZMWyxeSp7REJnirRWZPhrU28s+obmd3HClVuWOGFXA2jBaXoSAcQoUfI4UMDaM aL5ZnQ4Eh+A= X-Google-Smtp-Source: AGHT+IEu0lloyf4LdQq1YNmCzKI/fnNZDFiTEnqnIzYesDBOM9zlX1vCW5tVhBVOM1UPo9k9VrAYvMQc/X+19RUfymo= X-Received: by 2002:a05:6512:238c:b0:595:7e2d:986a with SMTP id 2adb3069b0e04-596b505c940mr48840e87.24.1764010735071; Mon, 24 Nov 2025 10:58:55 -0800 (PST) MIME-Version: 1.0 References: In-Reply-To: From: Tim Fors Date: Mon, 24 Nov 2025 13:58:43 -0500 X-Gm-Features: AWmQ_bnbYdtrC7nxivmmU658mah4QOfj3jTu1sbmS_hflBSLmEvkJ0ieaSfe3O4 Message-ID: Subject: Re: ECPG support for PQsetChunkedRowsMode() To: Daniel Verite Cc: pgsql-interfaces@lists.postgresql.org Content-Type: multipart/alternative; boundary="0000000000003e736106445bc1b3" List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --0000000000003e736106445bc1b3 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Thanks again for your replies Daniel. Let me provide a bit more background info: I work on a COBOL compiler on Linux x86 which now has support for PGSQL. We took the ECPG pre-processor and modified it to work with COBOL, and we integrated it into the compiler so that translation of SQL statements is done during the compilation of the COBOL program instead of requiring that that translation be done as a separate step prior to compilation. We refer to this as a *co*-processor as opposed to a pre-processor (which is what ECPG is). Because it is based on a modified version of ECPG, it leverages the ECPG library at runtime (i.e. when the COBOL program runs) to manage all communication between the client and the server. We have a business partner who is using our compiler and its PGSQL support. Their application had previously used Oracle as the DBMS, but now also supports PGSQL. When it comes to *single-row FETCH statements*, the business partner is reporting *considerably worse performance with PGSQL than with Oracle*. They expect comparable performance without having to change their SQL statements and COBOL code to do a fetch into a COBOL array and then iterate through that array, nor use an SQLDA. They have indicated that the difference in performance is because every FETCH statement has to go to the server to retrieve a row, whereas with Oracle they believe that a single-row FETCH actually retrieves multiple rows from the server under the covers, and there is logic on the client side to then perform the FETCH statements using the rows cached in the client rather than having to go to the server each time. I am going to verify this for myself, as well as examine how Db2 provides good performance for single-row FETCH statements. Further, they claim that the Oracle pre-processor is where that logic is being inserted into the COBOL program i.e. under the covers that generated code is handling the caching of rows on the client and supporting the required FETCH semantics using that cache. As a COBOL compiler developer, I'm very hesitant to try and modify our co-processor to implement this kind of client-side cursor management, caching rows on the client side while still providing all of the expected semantics associated with the FETCH statement. IMO cursor support is a crucial and non-trivial piece of the overall application support that a DBMS needs to provide, and it is not wise for a particular client to try and take these matters into their own hands. Row locking is just one concern that would need to be addressed - the FETCH statement would still be getting one row at a time but under the covers we'd be retrieving multiple rows, and it's not clear what kind of locking implications where might be, among a host of other possible "gotchas". But we seem to be between a rock and a hard place because PGSQL does not appear to have any support for single-row FETCH via cursors which would yield the same performance as Oracle. This is why I was hoping that there would be some way to influence PGSQL behaviour in this respect that I have overlooked. Hence my question re: "chunked rows" mode, which based on your reply does not do what I was looking for. Since you mentioned SQLDA, is that the official PGSQL approach that the business partner should be using? I know up front that they won't like that answer, because it means a variation in their application code for PGSQL vs Oracle, but if PGSQL provides no other way to improve single-row FETCH performance then I will mention it to them and see what they say. Please let me know if you have any more thoughts on this, or if more clarification from me would help. And of course, if there's a more appropriate mailing list for this issue let me know that too. Thanks, Tim On Mon, Nov 24, 2025 at 7:41=E2=80=AFAM Daniel Verite wrote: > Tim Fors wrote: > > > Note that ECPG supports using a C array as a host variable, and in > > that case there's a bulk transfer of rows from the client to the > > server, so performance is much better than getting the rows one at a > > time using a cursor. However, AFAIK this is not standard coding > > practice - one expects to be able to use the cursor to FETCH one > > row at a time, but still offer good performance. > > It's just a preprocessor. If the C code has EXEC SQL FETCH NEXT, it's > going to emit code sending a FETCH NEXT [1] SQL statement. > > But aside from the arrays you mention, it allows retrieving several > rows at a time through a cursor, so the client-side can still reduce > the round-trips to the server. See this example in [2]: > EXEC SQL FETCH 3 FROM mycursor INTO DESCRIPTOR mysqlda; > > [1]: https://www.postgresql.org/docs/current/sql-fetch.html > > [2]: https://www.postgresql.org/docs/current/ecpg-descriptors.html > > > Best regards, > -- > Daniel V=C3=A9rit=C3=A9 > https://postgresql.verite.pro/ > --0000000000003e736106445bc1b3 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
Thanks again for your replies Daniel.

L= et me provide a bit more background info: I work on a COBOL compiler on Lin= ux x86 which now has support for PGSQL.=C2=A0

We t= ook the ECPG pre-processor and modified it to work with COBOL, and we integ= rated it into the compiler so that translation of SQL statements is done du= ring the compilation of the COBOL program instead of requiring that that tr= anslation be done as a separate step prior to compilation. We refer to this= as a co-processor as opposed to a pre-processor (which is what ECPG= is). Because it is based on a modified version of ECPG, it leverages the E= CPG library at runtime (i.e. when the COBOL program runs) to manage all com= munication between the client and the server.

We h= ave a business partner who is using our compiler and its PGSQL support. The= ir application had previously used Oracle as the DBMS, but now also support= s=C2=A0PGSQL.=C2=A0

When it comes to single-row= FETCH statements, the business partner is reporting considerably wo= rse performance with PGSQL than with Oracle. They expect comparable per= formance without having to change their SQL statements and COBOL code to do= a fetch into a COBOL array and then iterate through that array, nor use an= SQLDA.

They have indicated that the difference in= performance is because every FETCH statement has to go to the server to re= trieve a row, whereas with Oracle they believe that a single-row FETCH actu= ally retrieves multiple rows from the server under the covers, and there is= logic on the client side to then perform the FETCH statements using the ro= ws cached in the client rather than having to go to the server each time. I= am going to verify this for myself, as well as examine how Db2 provides go= od performance for single-row FETCH statements.

Fu= rther, they claim that the Oracle pre-processor is where that logic is bein= g inserted into the COBOL program i.e. under the covers that generated code= is handling the caching of rows on the client and supporting the required = FETCH semantics using that cache.=C2=A0

As a COBOL= compiler developer, I'm very hesitant to try and modify our co-process= or to implement this kind of client-side cursor management,=C2=A0caching ro= ws on the client side while still providing all of the expected semantics a= ssociated with the FETCH statement. IMO cursor support is a crucial and non= -trivial piece of the overall application support that a DBMS needs to prov= ide, and it is not wise for a particular client to try and take these matte= rs into their own hands. Row locking is just one concern that would need to= be addressed - the FETCH statement would still be getting one row at a tim= e but under the covers we'd be retrieving multiple rows, and it's n= ot clear what kind of locking implications where might be, among a host of = other possible "gotchas".

But we seem to= be between a rock and a hard place because PGSQL does not appear to have a= ny support for single-row FETCH via cursors which would yield the same perf= ormance as Oracle. This is why I was hoping that there would be some way to= influence PGSQL behaviour in this respect that I have overlooked. Hence my= question re: "chunked rows" mode, which based on your reply does= not do what I was looking for.=C2=A0

Since you me= ntioned SQLDA, is that the official PGSQL approach that the business partne= r should be using? I know up front that they won't like that answer, be= cause it means a variation in their application code for PGSQL vs Oracle, b= ut if PGSQL provides no other way to improve single-row FETCH performance t= hen I will mention it to them and see what they say.

Please let me know if you have any more thoughts on this, or if more cla= rification from me would help. And of course, if there's a more appropr= iate mailing list for this issue let me know that too.

=
Thanks,

Tim

On Mon= , Nov 24, 2025 at 7:41=E2=80=AFAM Daniel Verite <daniel@manitou-mail.org> wrote:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 Tim = Fors wrote:

> Note that ECPG supports using a C array as a host variable, and in
> that case there's a bulk transfer of rows from the client to the > server, so performance is much better than getting the rows one at a > time using a cursor. However, AFAIK this is not standard coding
> practice - one expects to be able to use the cursor to FETCH one
> row at a time, but still offer good performance.

It's just a preprocessor. If the C code has EXEC SQL FETCH NEXT, it'= ;s
going to emit code sending a FETCH NEXT [1] SQL statement.

But aside from the arrays you mention, it allows retrieving several
rows at a time through a cursor, so the client-side can still reduce
the round-trips to the server. See this example in [2]:
=C2=A0EXEC SQL FETCH 3 FROM mycursor INTO DESCRIPTOR mysqlda;

[1]: https://www.postgresql.org/docs/current/s= ql-fetch.html

[2]: https://www.postgresql.org/docs/cu= rrent/ecpg-descriptors.html


Best regards,
--
Daniel V=C3=A9rit=C3=A9
https://postgresql.verite.pro/
--0000000000003e736106445bc1b3--