Re: POC: PLpgSQL FOREACH IN JSON ARRAY - Mailing list pgsql-hackers
| From | Chao Li |
|---|---|
| Subject | Re: POC: PLpgSQL FOREACH IN JSON ARRAY |
| Date | |
| Msg-id | EC293375-3C09-4A6F-9B76-E5FF8A9E7165@gmail.com Whole thread Raw |
| In response to | Re: POC: PLpgSQL FOREACH IN JSON ARRAY (Pavel Stehule <pavel.stehule@gmail.com>) |
| List | pgsql-hackers |
> On Mar 5, 2026, at 02:50, Pavel Stehule <pavel.stehule@gmail.com> wrote:
>
> Hi
>
> st 4. 3. 2026 v 12:35 odesílatel Jim Jones <jim.jones@uni-muenster.de> napsal:
> I reviewed the code I have nothing to add at this point. LGTM!
>
> The tests touch a lot of different scenarios, but for the sake of
> completeness I'd like to suggest adding these three cases:
>
> -- EXIT and CONTINUE can be triggered by LOOP_RC_PROCESSING
> DO $$
> DECLARE x int;
> BEGIN
> FOREACH x IN JSON ARRAY '[1,2,3,4,5]'
> LOOP
> EXIT WHEN x = 3;
> RAISE NOTICE '%', x;
> END LOOP;
> END;
> $$;
>
> DO $$
> DECLARE x int;
> BEGIN
> FOREACH x IN JSON ARRAY '[1,2,3,4,5]'
> LOOP
> CONTINUE WHEN x % 2 = 0;
> RAISE NOTICE '%', x;
> END LOOP;
> END;
> $$;
>
>
> -- Variable instead of string
> DO $$
> DECLARE x int; arr jsonb;
> BEGIN
> SELECT jsonb_agg(i) INTO arr
> FROM generate_series(1,3) i;
>
> FOREACH x IN JSON ARRAY arr
> LOOP
> RAISE NOTICE '%', x;
> END LOOP;
> END;
> $$;
>
>
> I merged these examples to tests
>
> Thank you for review
>
> Regards
>
> Pavel
>
> Thanks!
>
> Best, Jim
> <v20260304-5-0001-FOREACH-scalar-IN-JSON-ARRAY.patch>
I just reviewed and tested the patch. Here comes my comments:
1 - pl_gram.y
```
+ ereport(ERROR,
+ (errcode(ERRCODE_SYNTAX_ERROR),
+ errmsg("not zero slice is allowed only for arrays"),
+ parser_errposition(@4)));
```
* () around errcode and errmsg are no longer needed. This comment is general, and I saw other ereport() also use () in
thispatch.
* parser_errposition should have the same indention as errmsg.
2 - pl_exec.c
```
+ errdetail("Cannot iterate over a object value.")));
```
Typo: a -> an
3 - pl_exec.c
```
+ tmp_cxt = AllocSetContextCreate(CurrentMemoryContext,
+ "FOREACH IN JSON ARRAY temporary cxt",
+ ALLOCSET_DEFAULT_SIZES);
```
Do we need to destroy tmp_cxt after the loop?
4 Looks like record type of loop var is not supported:
```
evantest=# do $$
declare
r record;
begin
foreach r in json array '[{"x":1,"y":"hi"},{"x":2,"y":"hello"}]’
loop
raise notice 'x: %, y: %', r.x, r.y;
end loop;
end;
$$;
ERROR: record type has not been registered
CONTEXT: PL/pgSQL function inline_code_block line 5 at FOREACH over json array
```
So, I want to check if you intentionally don’t want to support that or just missed that? If it’s not supported, then
maybedocument that.
5 I tried that composite type of loop var is supported, maybe add a test case for that. What I tested:
```
create type t_foreach_json_row as (
x int,
y text,
z numeric
);
do $$
declare
r t_foreach_json_row;
begin
foreach r in json array
'[{"x":1,"y":"one","z":1.5},
{"x":2,"y":"two"},
{"y":"three","z":3.14},
{}]'
loop
raise notice 'x=%, y=%, z=%', r.x, r.y, r.z;
end loop;
end;
$$;
drop type t_foreach_json_row;
```
Best regards,
--
Chao Li (Evan)
HighGo Software Co., Ltd.
https://www.highgo.com/
pgsql-hackers by date: