Fix PL/pgSQL's handling of integer ranges containing underscores.
authorDean Rasheed <dean.a.rasheed@gmail.com>
Tue, 4 Jun 2024 10:48:01 +0000 (11:48 +0100)
committerDean Rasheed <dean.a.rasheed@gmail.com>
Tue, 4 Jun 2024 10:48:01 +0000 (11:48 +0100)
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
src/fe_utils/psqlscan.l
src/interfaces/ecpg/preproc/pgc.l
src/test/regress/expected/numerology.out
src/test/regress/sql/numerology.sql

index 9b33fb8d722d770ae5cf2d2a9f972bce6df9880e..3248fb5108058f6282632d41a2b9cfff82c61b35 100644 (file)
@@ -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][-+]
index c6d02439ab2cdb7dd05dde3cbc00464ce43026ec..ddc4658b9256c71dfdd7e5530354f5b6f1a58355 100644 (file)
@@ -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][-+]
index d117cafce65d3504aab19f0a9246c747a7615f6d..f9d68a96e79d9af22f05155cae94553104ec6970 100644 (file)
@@ -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][-+]
index c8196d2c85a3056a46cfdaa53c49c1755137bd39..8d4a3ba228a1c3b79632cd55ce6e57bd689d0b8f 100644 (file)
@@ -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
index 3f0ec34ecfa6d53c29df4c5767cbc5cb90e43fc4..372e7bf9bc87e372ecb579609b68cd47d98cf0d1 100644 (file)
@@ -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_;