Re: POC: PLpgSQL FOREACH IN JSON ARRAY

From: Jim Jones <jim(dot)jones(at)uni-muenster(dot)de>
To: Pavel Stehule <pavel(dot)stehule(at)gmail(dot)com>, PostgreSQL Hackers <pgsql-hackers(at)lists(dot)postgresql(dot)org>
Subject: Re: POC: PLpgSQL FOREACH IN JSON ARRAY
Date: 2026-03-03 07:42:59
Message-ID: d6ac54b9-79f4-485b-a540-96c56cd0b991@uni-muenster.de
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Hi Pavel,

I quickly tested the patch, and I also could observe a ~3x performance
improvement!

A few first impressions:

## in exec_stmt_foreach_json_a the boolean variable found is declared as
false, bit its value is never set to true until exec_set_found() is called:

/*
* Set the FOUND variable to indicate the result of executing the loop
* (namely, whether we looped one or more times). This must be set here so
* that it does not interfere with the value of the FOUND variable inside
* the loop processing itself.
*/
exec_set_found(estate, found);

Test:

DO $$
DECLARE
x int;
BEGIN
FOREACH x IN JSON ARRAY '[1,2,3]'
LOOP
RAISE NOTICE 'x: %', x;
END LOOP;

IF FOUND THEN
RAISE NOTICE 'FOUND is true';
ELSE
RAISE NOTICE 'FOUND is false';
END IF;
END;
$$;
NOTICE: x: 1
NOTICE: x: 2
NOTICE: x: 3
NOTICE: FOUND is false

## Suggestion in the plpgsql.sgml

The <literal>FOREACH</literal> loop is much like a
<literal>FOREACH</literal> loop,

to

"much like a regular <literal>FOREACH</literal> loop over arrays"

## Typo in comment

/*
* We cannot to use fieldnames for tupdescentry, because
* these names can be suffixed by name of row variable.
...

We cannot to use > We cannot use

## Nit pick

These error messages are not wrong, but IMO a errhint/errdetail could
add some value here:

ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("cannot extract elements from a scalar")));

ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("cannot extract elements from an object")));

Something like this perhaps?

ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("cannot extract elements from a scalar"),
errhint("FOREACH IN JSON ARRAY requires an array value.")));

ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("FOREACH expression must evaluate to a JSON array"),
errdetail("Cannot iterate over a scalar value.")));

Thanks for the patch!

Best, Jim

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Alexander Lakhin 2026-03-03 08:00:00 Re: BUG: Former primary node might stuck when started as a standby
Previous Message Zhijie Hou (Fujitsu) 2026-03-03 07:42:31 RE: Fix slotsync worker busy loop causing repeated log messages