From cd2624fd97b0c36b68da278abc5362647f69b07d Mon Sep 17 00:00:00 2001 From: Dean Rasheed Date: Tue, 4 Jun 2024 11:48:01 +0100 Subject: [PATCH] Fix PL/pgSQL's handling of integer ranges containing underscores. Commit faff8f8e47 allowed integer literals to contain underscores, but failed to update the lexer's "numericfail" rule. As a result, a decimal integer literal containing underscores would fail to parse, if used in an integer range with no whitespace after the first number, such as "1_001..1_003" in a PL/pgSQL FOR loop. Fix and backpatch to v16, where support for underscores in integer literals was added. Report and patch by Erik Wienhold. Discussion: https://postgr.es/m/808ce947-46ec-4628-85fa-3dd600b2c154%40ewie.name --- 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 | 11 +++++++++++ src/test/regress/sql/numerology.sql | 9 +++++++++ 5 files changed, 23 insertions(+), 3 deletions(-) diff --git a/src/backend/parser/scan.l b/src/backend/parser/scan.l index 9b33fb8d72..3248fb5108 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 c6d02439ab..ddc4658b92 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 d117cafce6..f9d68a96e7 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 c8196d2c85..8d4a3ba228 100644 --- a/src/test/regress/expected/numerology.out +++ b/src/test/regress/expected/numerology.out @@ -297,6 +297,17 @@ SELECT 1_000.5e0_1; 10005 (1 row) +DO $$ +DECLARE + i int; +BEGIN + FOR i IN 1_001..1_003 LOOP + RAISE NOTICE 'i = %', i; + END LOOP; +END $$; +NOTICE: i = 1001 +NOTICE: i = 1002 +NOTICE: i = 1003 -- 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 3f0ec34ecf..372e7bf9bc 100644 --- a/src/test/regress/sql/numerology.sql +++ b/src/test/regress/sql/numerology.sql @@ -77,6 +77,15 @@ SELECT 1_000.; SELECT .000_005; SELECT 1_000.5e0_1; +DO $$ +DECLARE + i int; +BEGIN + FOR i IN 1_001..1_003 LOOP + RAISE NOTICE 'i = %', i; + END LOOP; +END $$; + -- error cases SELECT _100; SELECT 100_;