mirror of
https://github.com/postgres/postgres.git
synced 2025-07-17 06:41:09 +03:00
Allow underscores in integer and numeric constants.
This allows underscores to be used in integer and numeric literals, and their corresponding type input functions, for visual grouping. For example: 1_500_000_000 3.14159_26535_89793 0xffff_ffff 0b_1001_0001 A single underscore is allowed between any 2 digits, or immediately after the base prefix indicator of non-decimal integers, per SQL:202x draft. Peter Eisentraut and Dean Rasheed Discussion: https://postgr.es/m/84aae844-dc55-a4be-86d9-4f0fa405cc97%40enterprisedb.com
This commit is contained in:
@ -19,6 +19,7 @@
|
||||
#include "catalog/pg_type.h"
|
||||
#include "mb/pg_wchar.h"
|
||||
#include "nodes/makefuncs.h"
|
||||
#include "nodes/miscnodes.h"
|
||||
#include "nodes/nodeFuncs.h"
|
||||
#include "nodes/subscripting.h"
|
||||
#include "parser/parse_coerce.h"
|
||||
@ -385,47 +386,11 @@ make_const(ParseState *pstate, A_Const *aconst)
|
||||
{
|
||||
/* could be an oversize integer as well as a float ... */
|
||||
|
||||
int base = 10;
|
||||
char *startptr;
|
||||
int sign;
|
||||
char *testvalue;
|
||||
ErrorSaveContext escontext = {T_ErrorSaveContext};
|
||||
int64 val64;
|
||||
char *endptr;
|
||||
|
||||
startptr = aconst->val.fval.fval;
|
||||
if (startptr[0] == '-')
|
||||
{
|
||||
sign = -1;
|
||||
startptr++;
|
||||
}
|
||||
else
|
||||
sign = +1;
|
||||
if (startptr[0] == '0')
|
||||
{
|
||||
if (startptr[1] == 'b' || startptr[1] == 'B')
|
||||
{
|
||||
base = 2;
|
||||
startptr += 2;
|
||||
}
|
||||
else if (startptr[1] == 'o' || startptr[1] == 'O')
|
||||
{
|
||||
base = 8;
|
||||
startptr += 2;
|
||||
}
|
||||
else if (startptr[1] == 'x' || startptr[1] == 'X')
|
||||
{
|
||||
base = 16;
|
||||
startptr += 2;
|
||||
}
|
||||
}
|
||||
|
||||
if (sign == +1)
|
||||
testvalue = startptr;
|
||||
else
|
||||
testvalue = psprintf("-%s", startptr);
|
||||
errno = 0;
|
||||
val64 = strtoi64(testvalue, &endptr, base);
|
||||
if (errno == 0 && *endptr == '\0')
|
||||
val64 = pg_strtoint64_safe(aconst->val.fval.fval, (Node *) &escontext);
|
||||
if (!escontext.error_occurred)
|
||||
{
|
||||
/*
|
||||
* It might actually fit in int32. Probably only INT_MIN
|
||||
|
@ -37,10 +37,12 @@
|
||||
|
||||
#include "common/string.h"
|
||||
#include "gramparse.h"
|
||||
#include "nodes/miscnodes.h"
|
||||
#include "parser/parser.h" /* only needed for GUC variables */
|
||||
#include "parser/scansup.h"
|
||||
#include "port/pg_bitutils.h"
|
||||
#include "mb/pg_wchar.h"
|
||||
#include "utils/builtins.h"
|
||||
}
|
||||
|
||||
%{
|
||||
@ -395,19 +397,19 @@ hexdigit [0-9A-Fa-f]
|
||||
octdigit [0-7]
|
||||
bindigit [0-1]
|
||||
|
||||
decinteger {decdigit}+
|
||||
hexinteger 0[xX]{hexdigit}+
|
||||
octinteger 0[oO]{octdigit}+
|
||||
bininteger 0[bB]{bindigit}+
|
||||
decinteger {decdigit}(_?{decdigit})*
|
||||
hexinteger 0[xX](_?{hexdigit})+
|
||||
octinteger 0[oO](_?{octdigit})+
|
||||
bininteger 0[bB](_?{bindigit})+
|
||||
|
||||
hexfail 0[xX]
|
||||
octfail 0[oO]
|
||||
binfail 0[bB]
|
||||
hexfail 0[xX]_?
|
||||
octfail 0[oO]_?
|
||||
binfail 0[bB]_?
|
||||
|
||||
numeric (({decinteger}\.{decinteger}?)|(\.{decinteger}))
|
||||
numericfail {decdigit}+\.\.
|
||||
|
||||
real ({decinteger}|{numeric})[Ee][-+]?{decdigit}+
|
||||
real ({decinteger}|{numeric})[Ee][-+]?{decinteger}
|
||||
realfail ({decinteger}|{numeric})[Ee][-+]
|
||||
|
||||
decinteger_junk {decinteger}{ident_start}
|
||||
@ -1364,12 +1366,11 @@ litbufdup(core_yyscan_t yyscanner)
|
||||
static int
|
||||
process_integer_literal(const char *token, YYSTYPE *lval, int base)
|
||||
{
|
||||
int val;
|
||||
char *endptr;
|
||||
ErrorSaveContext escontext = {T_ErrorSaveContext};
|
||||
int32 val;
|
||||
|
||||
errno = 0;
|
||||
val = strtoint(base == 10 ? token : token + 2, &endptr, base);
|
||||
if (*endptr != '\0' || errno == ERANGE)
|
||||
val = pg_strtoint32_safe(token, (Node *) &escontext);
|
||||
if (escontext.error_occurred)
|
||||
{
|
||||
/* integer too large (or contains decimal pt), treat it as a float */
|
||||
lval->str = pstrdup(token);
|
||||
|
Reference in New Issue
Block a user