aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/parser/scan.l18
-rw-r--r--src/fe_utils/psqlscan.l7
-rw-r--r--src/interfaces/ecpg/preproc/pgc.l18
3 files changed, 21 insertions, 22 deletions
diff --git a/src/backend/parser/scan.l b/src/backend/parser/scan.l
index 6c6a6e320f0..74e34df71fa 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 ae5418e7da0..02d95498e41 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 5ccda8da6b1..5e90e35bd2b 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);
}
} /* <C,SQL> */
@@ -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;
}