plpgsql fails to parse 1_000..1_000 as 1000..1000 in FOR loops: DO $$ DECLARE i int; BEGIN FOR i IN 1_000..1_000 LOOP END LOOP; END $$;
ERROR: syntax error at or near "1_000." LINE 5: FOR i IN 1_000..1_000 LOOP The scan.l defines rule "numericfail" to handle this ambiguity without requiring extra whitespace or parenthesis around the integer literals. But the rule only accepts digits 0-9. Again, an oversight in faff8f8e47. Fixed in the attached patch. -- Erik
>From 7e51d9ea7ef2ffc2a2b8c831533a382a5493575b Mon Sep 17 00:00:00 2001 From: Erik Wienhold <e...@ewie.name> Date: Wed, 15 May 2024 02:43:12 +0200 Subject: [PATCH] plpgsql: fix parsing of integer range with underscores Fix lexer rule "numericfail" that ensures that we parse 1_000..1_000 as 1000..1000 instead of failing with 'syntax error at or near "1_000."' or requiring extra whitespace/parenthesis to resolve the ambiguity. Oversight in faff8f8e47 which added underscores to numeric literals. --- src/backend/parser/scan.l | 2 +- src/fe_utils/psqlscan.l | 2 +- src/interfaces/ecpg/preproc/pgc.l | 2 +- src/test/regress/expected/numerology.out | 7 +++++++ src/test/regress/sql/numerology.sql | 8 ++++++++ 5 files changed, 18 insertions(+), 3 deletions(-) diff --git a/src/backend/parser/scan.l b/src/backend/parser/scan.l index 5eaadf53b2..a8e504ad09 100644 --- a/src/backend/parser/scan.l +++ b/src/backend/parser/scan.l @@ -407,7 +407,7 @@ octfail 0[oO]_? binfail 0[bB]_? numeric (({decinteger}\.{decinteger}?)|(\.{decinteger})) -numericfail {decdigit}+\.\. +numericfail {decinteger}\.\. real ({decinteger}|{numeric})[Ee][-+]?{decinteger} realfail ({decinteger}|{numeric})[Ee][-+] diff --git a/src/fe_utils/psqlscan.l b/src/fe_utils/psqlscan.l index c9df0594fd..7780151434 100644 --- a/src/fe_utils/psqlscan.l +++ b/src/fe_utils/psqlscan.l @@ -343,7 +343,7 @@ octfail 0[oO]_? binfail 0[bB]_? numeric (({decinteger}\.{decinteger}?)|(\.{decinteger})) -numericfail {decdigit}+\.\. +numericfail {decinteger}\.\. real ({decinteger}|{numeric})[Ee][-+]?{decinteger} realfail ({decinteger}|{numeric})[Ee][-+] diff --git a/src/interfaces/ecpg/preproc/pgc.l b/src/interfaces/ecpg/preproc/pgc.l index bcfbd0978b..7744d2facf 100644 --- a/src/interfaces/ecpg/preproc/pgc.l +++ b/src/interfaces/ecpg/preproc/pgc.l @@ -376,7 +376,7 @@ octfail 0[oO]_? binfail 0[bB]_? numeric (({decinteger}\.{decinteger}?)|(\.{decinteger})) -numericfail {decdigit}+\.\. +numericfail {decinteger}\.\. real ({decinteger}|{numeric})[Ee][-+]?{decinteger} realfail ({decinteger}|{numeric})[Ee][-+] diff --git a/src/test/regress/expected/numerology.out b/src/test/regress/expected/numerology.out index f662a5050a..86caccbbc5 100644 --- a/src/test/regress/expected/numerology.out +++ b/src/test/regress/expected/numerology.out @@ -297,6 +297,13 @@ SELECT 1_000.5e0_1; 10005 (1 row) +DO $$ +DECLARE + i int; +BEGIN + FOR i IN 1_000..1_000 LOOP + END LOOP; +END $$; -- error cases SELECT _100; ERROR: column "_100" does not exist diff --git a/src/test/regress/sql/numerology.sql b/src/test/regress/sql/numerology.sql index 1941c58e68..eb8d4e48d7 100644 --- a/src/test/regress/sql/numerology.sql +++ b/src/test/regress/sql/numerology.sql @@ -77,6 +77,14 @@ SELECT 1_000.; SELECT .000_005; SELECT 1_000.5e0_1; +DO $$ +DECLARE + i int; +BEGIN + FOR i IN 1_000..1_000 LOOP + END LOOP; +END $$; + -- error cases SELECT _100; SELECT 100_; -- 2.45.1