Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit2549f06

Browse files
committed
Reject trailing junk after numeric literals
After this, the PostgreSQL lexers no longer accept numeric literalswith trailing non-digits, such as 123abc, which would be scanned astwo tokens: 123 and abc. This is undocumented and surprising, and itmight also interfere with some extended numeric literal syntax beingcontemplated for the future.Reviewed-by: John Naylor <john.naylor@enterprisedb.com>Discussion:https://www.postgresql.org/message-id/flat/b239564c-cad0-b23e-c57e-166d883cb97d@enterprisedb.com
1 parent70e8186 commit2549f06

File tree

5 files changed

+96
-86
lines changed

5 files changed

+96
-86
lines changed

‎src/backend/parser/scan.l

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -387,7 +387,7 @@ operator{op_chars}+
387387
*
388388
* {decimalfail} is used because we would like "1..10" to lex as 1, dot_dot, 10.
389389
*
390-
* {realfail1} and {realfail2} are added to prevent the need for scanner
390+
* {realfail} is added to prevent the need for scanner
391391
* backup when the {real} rule fails to match completely.
392392
*/
393393
digit[0-9]
@@ -396,10 +396,14 @@ integer{digit}+
396396
decimal(({digit}*\.{digit}+)|({digit}+\.{digit}*))
397397
decimalfail{digit}+\.\.
398398
real({integer}|{decimal})[Ee][-+]?{digit}+
399-
realfail1({integer}|{decimal})[Ee]
400-
realfail2({integer}|{decimal})[Ee][-+]
399+
realfail({integer}|{decimal})[Ee][-+]
400+
401+
integer_junk{integer}{ident_start}
402+
decimal_junk{decimal}{ident_start}
403+
real_junk{real}{ident_start}
401404

402405
param\${integer}
406+
param_junk\${integer}{ident_start}
403407

404408
other.
405409

@@ -974,6 +978,10 @@ other.
974978
yylval->ival =atol(yytext +1);
975979
return PARAM;
976980
}
981+
{param_junk}{
982+
SET_YYLLOC();
983+
yyerror("trailing junk after parameter");
984+
}
977985

978986
{integer}{
979987
SET_YYLLOC();
@@ -995,20 +1003,21 @@ other.
9951003
yylval->str =pstrdup(yytext);
9961004
return FCONST;
9971005
}
998-
{realfail1}{
999-
/*
1000-
* throw back the [Ee], and figure out whether what
1001-
* remains is an {integer} or {decimal}.
1002-
*/
1003-
yyless(yyleng -1);
1006+
{realfail}{
10041007
SET_YYLLOC();
1005-
returnprocess_integer_literal(yytext, yylval);
1008+
yyerror("trailing junk after numeric literal");
10061009
}
1007-
{realfail2}{
1008-
/* throw back the [Ee][+-], and proceed as above */
1009-
yyless(yyleng -2);
1010+
{integer_junk}{
10101011
SET_YYLLOC();
1011-
returnprocess_integer_literal(yytext, yylval);
1012+
yyerror("trailing junk after numeric literal");
1013+
}
1014+
{decimal_junk}{
1015+
SET_YYLLOC();
1016+
yyerror("trailing junk after numeric literal");
1017+
}
1018+
{real_junk}{
1019+
SET_YYLLOC();
1020+
yyerror("trailing junk after numeric literal");
10121021
}
10131022

10141023

‎src/fe_utils/psqlscan.l

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -325,7 +325,7 @@ operator{op_chars}+
325325
*
326326
* {decimalfail} is used because we would like "1..10" to lex as 1, dot_dot, 10.
327327
*
328-
* {realfail1} and {realfail2} are added to prevent the need for scanner
328+
* {realfail} is added to prevent the need for scanner
329329
* backup when the {real} rule fails to match completely.
330330
*/
331331
digit[0-9]
@@ -334,10 +334,14 @@ integer{digit}+
334334
decimal(({digit}*\.{digit}+)|({digit}+\.{digit}*))
335335
decimalfail{digit}+\.\.
336336
real({integer}|{decimal})[Ee][-+]?{digit}+
337-
realfail1({integer}|{decimal})[Ee]
338-
realfail2({integer}|{decimal})[Ee][-+]
337+
realfail({integer}|{decimal})[Ee][-+]
338+
339+
integer_junk{integer}{ident_start}
340+
decimal_junk{decimal}{ident_start}
341+
real_junk{real}{ident_start}
339342

340343
param\${integer}
344+
param_junk\${integer}{ident_start}
341345

342346
/* psql-specific: characters allowed in variable names */
343347
variable_char[A-Za-z\200-\377_0-9]
@@ -839,6 +843,9 @@ other.
839843
{param}{
840844
ECHO;
841845
}
846+
{param_junk}{
847+
ECHO;
848+
}
842849

843850
{integer}{
844851
ECHO;
@@ -854,18 +861,16 @@ other.
854861
{real}{
855862
ECHO;
856863
}
857-
{realfail1}{
858-
/*
859-
* throw back the [Ee], and figure out whether what
860-
* remains is an {integer} or {decimal}.
861-
* (in psql, we don't actually care...)
862-
*/
863-
yyless(yyleng -1);
864+
{realfail}{
864865
ECHO;
865866
}
866-
{realfail2}{
867-
/* throw back the [Ee][+-], and proceed as above */
868-
yyless(yyleng -2);
867+
{integer_junk}{
868+
ECHO;
869+
}
870+
{decimal_junk}{
871+
ECHO;
872+
}
873+
{real_junk}{
869874
ECHO;
870875
}
871876

‎src/interfaces/ecpg/preproc/pgc.l

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -353,7 +353,7 @@ operator{op_chars}+
353353
*
354354
* {decimalfail} is used because we would like "1..10" to lex as 1, dot_dot, 10.
355355
*
356-
* {realfail1} and {realfail2} are added to prevent the need for scanner
356+
* {realfail} is added to prevent the need for scanner
357357
* backup when the {real} rule fails to match completely.
358358
*/
359359
digit[0-9]
@@ -362,10 +362,14 @@ integer{digit}+
362362
decimal(({digit}*\.{digit}+)|({digit}+\.{digit}*))
363363
decimalfail{digit}+\.\.
364364
real({integer}|{decimal})[Ee][-+]?{digit}+
365-
realfail1({integer}|{decimal})[Ee]
366-
realfail2({integer}|{decimal})[Ee][-+]
365+
realfail({integer}|{decimal})[Ee][-+]
366+
367+
integer_junk{integer}{ident_start}
368+
decimal_junk{decimal}{ident_start}
369+
real_junk{real}{ident_start}
367370

368371
param\${integer}
372+
param_junk\${integer}{ident_start}
369373

370374
/* special characters for other dbms */
371375
/* we have to react differently in compat mode */
@@ -917,6 +921,9 @@ cppline{space}*#([^i][A-Za-z]*|{if}|{ifdef}|{ifndef}|{import})((\/\*[^*/]*\*+
917921
base_yylval.ival =atol(yytext+1);
918922
return PARAM;
919923
}
924+
{param_junk}{
925+
mmfatal(PARSE_ERROR,"trailing junk after parameter");
926+
}
920927

921928
{ip}{
922929
base_yylval.str =mm_strdup(yytext);
@@ -941,22 +948,31 @@ cppline{space}*#([^i][A-Za-z]*|{if}|{ifdef}|{ifndef}|{import})((\/\*[^*/]*\*+
941948
base_yylval.str =mm_strdup(yytext);
942949
return FCONST;
943950
}
944-
{realfail1}{
951+
{realfail}{
945952
/*
946-
* throw back the [Ee], and figure out whether what
953+
* throw back the [Ee][+-], and figure out whether what
947954
* remains is an {integer} or {decimal}.
948955
*/
949-
yyless(yyleng -1);
950-
returnprocess_integer_literal(yytext, &base_yylval);
951-
}
952-
{realfail2}{
953-
/* throw back the [Ee][+-], and proceed as above */
954956
yyless(yyleng -2);
955957
returnprocess_integer_literal(yytext, &base_yylval);
956958
}
957959
}/* <C,SQL> */
958960

959961
<SQL>{
962+
/*
963+
* Note that some trailing junk is valid in C (such as 100LL), so we
964+
* contain this to SQL mode.
965+
*/
966+
{integer_junk}{
967+
mmfatal(PARSE_ERROR,"trailing junk after numeric literal");
968+
}
969+
{decimal_junk}{
970+
mmfatal(PARSE_ERROR,"trailing junk after numeric literal");
971+
}
972+
{real_junk}{
973+
mmfatal(PARSE_ERROR,"trailing junk after numeric literal");
974+
}
975+
960976
:{identifier}((("->"|\.){identifier})|(\[{array}\]))*{
961977
base_yylval.str =mm_strdup(yytext+1);
962978
return CVARIABLE;

‎src/test/regress/expected/numerology.out

Lines changed: 29 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -6,64 +6,45 @@
66
-- Trailing junk in numeric literals
77
--
88
SELECT 123abc;
9-
abc
10-
-----
11-
123
12-
(1 row)
13-
9+
ERROR: trailing junk after numeric literal at or near "123a"
10+
LINE 1: SELECT 123abc;
11+
^
1412
SELECT 0x0o;
15-
x0o
16-
-----
17-
0
18-
(1 row)
19-
13+
ERROR: trailing junk after numeric literal at or near "0x"
14+
LINE 1: SELECT 0x0o;
15+
^
2016
SELECT 1_2_3;
21-
_2_3
22-
------
23-
1
24-
(1 row)
25-
17+
ERROR: trailing junk after numeric literal at or near "1_"
18+
LINE 1: SELECT 1_2_3;
19+
^
2620
SELECT 0.a;
27-
a
28-
---
29-
0
30-
(1 row)
31-
21+
ERROR: trailing junk after numeric literal at or near "0.a"
22+
LINE 1: SELECT 0.a;
23+
^
3224
SELECT 0.0a;
33-
a
34-
-----
35-
0.0
36-
(1 row)
37-
25+
ERROR: trailing junk after numeric literal at or near "0.0a"
26+
LINE 1: SELECT 0.0a;
27+
^
3828
SELECT .0a;
39-
a
40-
-----
41-
0.0
42-
(1 row)
43-
29+
ERROR: trailing junk after numeric literal at or near ".0a"
30+
LINE 1: SELECT .0a;
31+
^
4432
SELECT 0.0e1a;
45-
a
46-
---
47-
0
48-
(1 row)
49-
33+
ERROR: trailing junk after numeric literal at or near "0.0e1a"
34+
LINE 1: SELECT 0.0e1a;
35+
^
5036
SELECT 0.0e;
51-
e
52-
-----
53-
0.0
54-
(1 row)
55-
37+
ERROR: trailing junk after numeric literal at or near "0.0e"
38+
LINE 1: SELECT 0.0e;
39+
^
5640
SELECT 0.0e+a;
57-
ERROR:syntax errorat or near "+"
41+
ERROR:trailing junk after numeric literalat or near "0.0e+"
5842
LINE 1: SELECT 0.0e+a;
59-
^
43+
^
6044
PREPARE p1 AS SELECT $1a;
61-
EXECUTE p1(1);
62-
a
63-
---
64-
1
65-
(1 row)
66-
45+
ERROR: trailing junk after parameter at or near "$1a"
46+
LINE 1: PREPARE p1 AS SELECT $1a;
47+
^
6748
--
6849
-- Test implicit type conversions
6950
-- This fails for Postgres v6.1 (and earlier?)

‎src/test/regress/sql/numerology.sql

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ SELECT 0.0e1a;
1717
SELECT0.0e;
1818
SELECT0.0e+a;
1919
PREPARE p1ASSELECT $1a;
20-
EXECUTE p1(1);
2120

2221
--
2322
-- Test implicit type conversions

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp