Re: psql's FETCH_COUNT (cursor) is not being respected for CTEs

From: Laurenz Albe <laurenz(dot)albe(at)cybertec(dot)at>
To: Daniel Verite <daniel(at)manitou-mail(dot)org>
Cc: PostgreSQL Hackers <pgsql-hackers(at)postgresql(dot)org>, Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>, Robert Haas <robertmhaas(at)gmail(dot)com>, Jakub Wartak <jakub(dot)wartak(at)enterprisedb(dot)com>
Subject: Re: psql's FETCH_COUNT (cursor) is not being respected for CTEs
Date: 2024-03-29 17:25:29
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-hackers

On Fri, 2024-03-29 at 14:07 +0100, Laurenz Albe wrote:
> I had a look at patch 0001 (0002 will follow).

Here is the code review for patch number 2:

> diff --git a/src/bin/psql/common.c b/src/bin/psql/common.c
+static bool
+SetupGOutput(PGresult *result, FILE **gfile_fout, bool *is_pipe)
+static void
+CloseGOutput(FILE *gfile_fout, bool is_pipe)

It makes sense to factor out this code.
But shouldn't these functions have a prototype at the beginning of the file?

> + /*
> + * If FETCH_COUNT is set and the context allows it, use the single row
> + * mode to fetch results and have no more than FETCH_COUNT rows in
> + * memory.
> + */

That comment talks about single-row mode, whey you are using chunked mode.
You probably forgot to modify the comment from a previous version of the patch.

> + if (fetch_count > 0 && !pset.crosstab_flag && !pset.gexec_flag && !is_watch
> + && !pset.gset_prefix && pset.show_all_results)
> + {
> + /*
> + * The row-by-chunks fetch is not enabled when SHOW_ALL_RESULTS is false,
> + * since we would need to accumulate all rows before knowing
> + * whether they need to be discarded or displayed, which contradicts
> + */
> + if (!PQsetChunkedRowsMode(pset.db, fetch_count))
> + {

I think that comment should be before the "if" statement, not inside it.

Here is a suggestion for a consolidated comment:

Fetch the result in chunks if FETCH_COUNT is set. We don't enable chunking
if SHOW_ALL_RESULTS is false, since that requires us to accumulate all rows
before we can tell what should be displayed, which would counter the idea
of FETCH_COUNT. Chunk fetching is also disabled if \gset, \crosstab,
\gexec and \watch are used.

> + if (fetch_count > 0 && result_status == PGRES_TUPLES_CHUNK)

Could it be that result_status == PGRES_TUPLES_CHUNK, but fetch_count is 0?
if not, perhaps there should be an Assert that verifies that, and the "if"
statement should only check for the latter condition.

> --- a/src/bin/psql/t/
> +++ b/src/bin/psql/t/
> @@ -184,10 +184,10 @@ like(
> "\\set FETCH_COUNT 1\nSELECT error;\n\\errverbose",
> on_error_stop => 0))[2],
> qr/\A^psql:<stdin>:2: ERROR: .*$
> -^LINE 2: SELECT error;$
> +^LINE 1: SELECT error;$
> ^ *^.*$
> ^psql:<stdin>:3: error: ERROR: [0-9A-Z]{5}: .*$
> -^LINE 2: SELECT error;$
> +^LINE 1: SELECT error;$

Why does the output change? Perhaps there is a good and harmless
explanation, but the naïve expectation would be that it doesn't.

The patch does not apply any more because of a conflict with the
non-blocking PQcancel patch.

After fixing the problem manually, it builds without warning.
The regression tests pass, and the feature works as expected.

Laurenz Albe

In response to


Browse pgsql-hackers by date

  From Date Subject
Next Message Christoph Berg 2024-03-29 18:07:31 Re: LLVM 18
Previous Message Amonson, Paul D 2024-03-29 17:25:14 RE: Popcount optimization using AVX512