diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index eb24195..ce8e221 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -478,7 +478,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); %type fetch_args select_limit_value offset_clause select_offset_value - select_fetch_first_value I_or_F_const + select_fetch_first_value I_or_F_const I_or_BIGI_const %type row_or_rows first_or_next %type OptSeqOptList SeqOptList OptParenthesizedSeqOptList @@ -623,9 +623,9 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); * DOT_DOT is unused in the core SQL grammar, and so will always provoke * parse errors. It is needed by PL/pgSQL. */ -%token IDENT UIDENT FCONST SCONST USCONST BCONST XCONST Op +%token IDENT UIDENT FCONST SCONST USCONST BCONST XCONST Op BIGICONST %token ICONST PARAM -%token TYPECAST DOT_DOT COLON_EQUALS EQUALS_GREATER +%token TYPECAST SQRT DOT_DOT COLON_EQUALS EQUALS_GREATER %token LESS_EQUALS GREATER_EQUALS NOT_EQUALS /* @@ -804,6 +804,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); %left '[' ']' %left '(' ')' %left TYPECAST +%left SQRT %left '.' /* * These might seem to be low-precedence, but actually they are not part @@ -4452,12 +4453,19 @@ opt_by: BY NumericOnly: FCONST { $$ = makeFloat($1); } + | BIGICONST { $$ = makeFloat($1); } | '+' FCONST { $$ = makeFloat($2); } + | '+' BIGICONST { $$ = makeFloat($2); } | '-' FCONST { $$ = makeFloat($2); doNegateFloat($$); } + | '-' BIGICONST + { + $$ = makeFloat($2); + doNegateFloat($$); + } | SignedIconst { $$ = makeInteger($1); } ; @@ -5530,6 +5538,7 @@ TriggerFuncArg: $$ = makeString(psprintf("%d", $1)); } | FCONST { $$ = makeString($1); } + | BIGICONST { $$ = makeString($1); } | Sconst { $$ = makeString($1); } | ColLabel { $$ = makeString($1); } ; @@ -11894,6 +11903,11 @@ I_or_F_const: | FCONST { $$ = makeFloatConst($1,@1); } ; +I_or_BIGI_const: + Iconst { $$ = makeIntConst($1,@1); } + | BIGICONST { $$ = makeFloatConst($1,@1); } + ; + /* noise words */ row_or_rows: ROW { $$ = 0; } | ROWS { $$ = 0; } @@ -13274,6 +13288,13 @@ a_expr: c_expr { $$ = $1; } { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "+", NULL, $2, @1); } | '-' a_expr %prec UMINUS { $$ = doNegate($2, @1); } + | SQRT I_or_BIGI_const %prec SQRT + { + $$ = (Node *) makeFuncCall(SystemFuncName("sqrt"), + list_make1($2), + COERCE_SQL_SYNTAX, + @2); + } | a_expr '+' a_expr { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "+", $1, $3, @2); } | a_expr '-' a_expr @@ -13703,6 +13724,13 @@ b_expr: c_expr { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "+", NULL, $2, @1); } | '-' b_expr %prec UMINUS { $$ = doNegate($2, @1); } + | SQRT I_or_BIGI_const %prec SQRT + { + $$ = (Node *) makeFuncCall(SystemFuncName("sqrt"), + list_make1($2), + COERCE_SQL_SYNTAX, + @2); + } | b_expr '+' b_expr { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "+", $1, $3, @2); } | b_expr '-' b_expr @@ -15149,6 +15177,10 @@ AexprConst: Iconst { $$ = makeFloatConst($1, @1); } + | BIGICONST + { + $$ = makeFloatConst($1, @1); + } | Sconst { $$ = makeStringConst($1, @1); diff --git a/src/backend/parser/scan.l b/src/backend/parser/scan.l index 9f9d8a1..a597985 100644 --- a/src/backend/parser/scan.l +++ b/src/backend/parser/scan.l @@ -124,6 +124,7 @@ static void addlitchar(unsigned char ychar, core_yyscan_t yyscanner); static char *litbufdup(core_yyscan_t yyscanner); static unsigned char unescape_single_char(unsigned char c, core_yyscan_t yyscanner); static int process_integer_literal(const char *token, YYSTYPE *lval); +static int process_integer_bigint_literal(const char *token, YYSTYPE *lval); static void addunicode(pg_wchar c, yyscan_t yyscanner); #define yyerror(msg) scanner_yyerror(msg, yyscanner) @@ -348,6 +349,7 @@ identifier {ident_start}{ident_cont}* /* Assorted special-case operators and operator-like tokens */ typecast "::" +sqrt "√" dot_dot \.\. colon_equals ":=" @@ -816,6 +818,11 @@ other . return TYPECAST; } +{sqrt} { + SET_YYLLOC(); + return SQRT; + } + {dot_dot} { SET_YYLLOC(); return DOT_DOT; @@ -974,8 +981,9 @@ other . {integer} { SET_YYLLOC(); - return process_integer_literal(yytext, yylval); + return process_integer_bigint_literal(yytext, yylval); } + {decimal} { SET_YYLLOC(); yylval->str = pstrdup(yytext); @@ -1319,6 +1327,24 @@ process_integer_literal(const char *token, YYSTYPE *lval) return ICONST; } +static int +process_integer_bigint_literal(const char *token, YYSTYPE *lval) +{ + int val; + char *endptr; + + errno = 0; + val = strtoint(token, &endptr, 10); + if (*endptr != '\0' || errno == ERANGE) + { + /* integer too large (or contains decimal pt), treat it as a float */ + lval->str = pstrdup(token); + return BIGICONST; + } + lval->ival = val; + return ICONST; +} + static void addunicode(pg_wchar c, core_yyscan_t yyscanner) {