diff --git a/src/backend/parser/scan.l b/src/backend/parser/scan.l index 6c6a6e320f..74e34df71f 100644 --- a/src/backend/parser/scan.l +++ b/src/backend/parser/scan.l @@ -1005,22 +1005,18 @@ other . } {realfail1} { /* - * throw back the [Ee], and treat as {decimal}. Note - * that it is possible the input is actually {integer}, - * but since this case will almost certainly lead to a - * syntax error anyway, we don't bother to distinguish. + * throw back the [Ee], and figure out whether what + * remains is an {integer} or {decimal}. */ yyless(yyleng - 1); SET_YYLLOC(); - yylval->str = pstrdup(yytext); - return FCONST; + return process_integer_literal(yytext, yylval); } {realfail2} { /* throw back the [Ee][+-], and proceed as above */ yyless(yyleng - 2); SET_YYLLOC(); - yylval->str = pstrdup(yytext); - return FCONST; + return process_integer_literal(yytext, yylval); } @@ -1255,6 +1251,10 @@ litbufdup(core_yyscan_t yyscanner) return new; } +/* + * Process {integer}. Note this will also do the right thing with {decimal}, + * ie digits and a decimal point. + */ static int process_integer_literal(const char *token, YYSTYPE *lval) { @@ -1265,7 +1265,7 @@ process_integer_literal(const char *token, YYSTYPE *lval) val = strtoint(token, &endptr, 10); if (*endptr != '\0' || errno == ERANGE) { - /* integer too large, treat it as a float */ + /* integer too large (or contains decimal pt), treat it as a float */ lval->str = pstrdup(token); return FCONST; } diff --git a/src/fe_utils/psqlscan.l b/src/fe_utils/psqlscan.l index ae5418e7da..02d95498e4 100644 --- a/src/fe_utils/psqlscan.l +++ b/src/fe_utils/psqlscan.l @@ -887,10 +887,9 @@ other . } {realfail1} { /* - * throw back the [Ee], and treat as {decimal}. Note - * that it is possible the input is actually {integer}, - * but since this case will almost certainly lead to a - * syntax error anyway, we don't bother to distinguish. + * throw back the [Ee], and figure out whether what + * remains is an {integer} or {decimal}. + * (in psql, we don't actually care...) */ yyless(yyleng - 1); ECHO; diff --git a/src/interfaces/ecpg/preproc/pgc.l b/src/interfaces/ecpg/preproc/pgc.l index 5ccda8da6b..5e90e35bd2 100644 --- a/src/interfaces/ecpg/preproc/pgc.l +++ b/src/interfaces/ecpg/preproc/pgc.l @@ -900,20 +900,16 @@ cppline {space}*#([^i][A-Za-z]*|{if}|{ifdef}|{ifndef}|{import})((\/\*[^*/]*\*+ } {realfail1} { /* - * throw back the [Ee], and treat as {decimal}. Note - * that it is possible the input is actually {integer}, - * but since this case will almost certainly lead to a - * syntax error anyway, we don't bother to distinguish. + * throw back the [Ee], and figure out whether what + * remains is an {integer} or {decimal}. */ yyless(yyleng - 1); - base_yylval.str = mm_strdup(yytext); - return FCONST; + return process_integer_literal(yytext, &base_yylval); } {realfail2} { /* throw back the [Ee][+-], and proceed as above */ yyless(yyleng - 2); - base_yylval.str = mm_strdup(yytext); - return FCONST; + return process_integer_literal(yytext, &base_yylval); } } /* */ @@ -1473,6 +1469,10 @@ addlitchar(unsigned char ychar) literalbuf[literallen] = '\0'; } +/* + * Process {integer}. Note this will also do the right thing with {decimal}, + * ie digits and a decimal point. + */ static int process_integer_literal(const char *token, YYSTYPE *lval) { @@ -1483,7 +1483,7 @@ process_integer_literal(const char *token, YYSTYPE *lval) val = strtoint(token, &endptr, 10); if (*endptr != '\0' || errno == ERANGE) { - /* integer too large, treat it as a float */ + /* integer too large (or contains decimal pt), treat it as a float */ lval->str = mm_strdup(token); return FCONST; }