I believe I have found a parser issue in PL/pgSQL involving the FOREACH ... SLICE syntax.
Thanks for the report!
CREATE FUNCTION test_slice_conflict() RETURNS text LANGUAGE plpgsql AS $$ DECLARE slice integer[]; arr integer[] := ARRAY[[1,2],[3,4]]; BEGIN FOREACH slice SLICE 1 IN ARRAY arr LOOP END LOOP; RETURN 'ok'; END; $$;
Observed behavior: The function fails to compile due to incorrect parsing of `slice` as the SLICE keyword.
Expected behavior: `slice` should be treated as a normal identifier (loop variable), and the function should compile and run successfully.
Confirmed on master.
Chat provided much more context for how/why this happened and why this seems like a good fix; prior art is my main argument though.
If a PL/pgSQL variable is named "slice", using it in a FOREACH ... SLICE loop produces a spurious syntax error:
DO $$ DECLARE slice integer[]; arr integer[] := ARRAY[[1,2],[3,4]]; BEGIN FOREACH slice SLICE 1 IN ARRAY arr LOOP END LOOP; END; $$; ERROR: syntax error at or near "SLICE"
The one-token lookahead in the for_variable grammar action runs under normal identifier lookup, so when "slice" is in scope the following SLICE keyword is consumed as a T_DATUM reference rather than K_SLICE, and foreach_slice fails.
The fix is to suppress variable lookup for that lookahead, using the same save/restore pattern already used in pl_gram.y::read_cursor_args():