diff options
Diffstat (limited to 'src/backend/parser')
-rw-r--r-- | src/backend/parser/gram.y | 89 | ||||
-rw-r--r-- | src/backend/parser/parse_expr.c | 60 | ||||
-rw-r--r-- | src/backend/parser/parse_target.c | 43 |
3 files changed, 132 insertions, 60 deletions
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index d6426f3b8e0..6f5aa8a3cbc 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -198,6 +198,8 @@ static Node *makeAndExpr(Node *lexpr, Node *rexpr, int location); static Node *makeOrExpr(Node *lexpr, Node *rexpr, int location); static Node *makeNotExpr(Node *expr, int location); static Node *makeAArrayExpr(List *elements, int location); +static Node *makeSQLValueFunction(SQLValueFunctionOp op, int32 typmod, + int location); static Node *makeXmlExpr(XmlExprOp op, char *name, List *named_args, List *args, int location); static List *mergeTableFuncParameters(List *func_args, List *columns); @@ -15288,87 +15290,51 @@ func_expr_common_subexpr: } | CURRENT_DATE { - $$ = (Node *) makeFuncCall(SystemFuncName("current_date"), - NIL, - COERCE_SQL_SYNTAX, - @1); + $$ = makeSQLValueFunction(SVFOP_CURRENT_DATE, -1, @1); } | CURRENT_TIME { - $$ = (Node *) makeFuncCall(SystemFuncName("current_time"), - NIL, - COERCE_SQL_SYNTAX, - @1); + $$ = makeSQLValueFunction(SVFOP_CURRENT_TIME, -1, @1); } | CURRENT_TIME '(' Iconst ')' { - $$ = (Node *) makeFuncCall(SystemFuncName("current_time"), - list_make1(makeIntConst($3, @3)), - COERCE_SQL_SYNTAX, - @1); + $$ = makeSQLValueFunction(SVFOP_CURRENT_TIME_N, $3, @1); } | CURRENT_TIMESTAMP { - $$ = (Node *) makeFuncCall(SystemFuncName("current_timestamp"), - NIL, - COERCE_SQL_SYNTAX, - @1); + $$ = makeSQLValueFunction(SVFOP_CURRENT_TIMESTAMP, -1, @1); } | CURRENT_TIMESTAMP '(' Iconst ')' { - $$ = (Node *) makeFuncCall(SystemFuncName("current_timestamp"), - list_make1(makeIntConst($3, @3)), - COERCE_SQL_SYNTAX, - @1); + $$ = makeSQLValueFunction(SVFOP_CURRENT_TIMESTAMP_N, $3, @1); } | LOCALTIME { - $$ = (Node *) makeFuncCall(SystemFuncName("localtime"), - NIL, - COERCE_SQL_SYNTAX, - @1); + $$ = makeSQLValueFunction(SVFOP_LOCALTIME, -1, @1); } | LOCALTIME '(' Iconst ')' { - $$ = (Node *) makeFuncCall(SystemFuncName("localtime"), - list_make1(makeIntConst($3, @3)), - COERCE_SQL_SYNTAX, - @1); + $$ = makeSQLValueFunction(SVFOP_LOCALTIME_N, $3, @1); } | LOCALTIMESTAMP { - $$ = (Node *) makeFuncCall(SystemFuncName("localtimestamp"), - NIL, - COERCE_SQL_SYNTAX, - @1); + $$ = makeSQLValueFunction(SVFOP_LOCALTIMESTAMP, -1, @1); } | LOCALTIMESTAMP '(' Iconst ')' { - $$ = (Node *) makeFuncCall(SystemFuncName("localtimestamp"), - list_make1(makeIntConst($3, @3)), - COERCE_SQL_SYNTAX, - @1); + $$ = makeSQLValueFunction(SVFOP_LOCALTIMESTAMP_N, $3, @1); } | CURRENT_ROLE { - $$ = (Node *) makeFuncCall(SystemFuncName("current_role"), - NIL, - COERCE_SQL_SYNTAX, - @1); + $$ = makeSQLValueFunction(SVFOP_CURRENT_ROLE, -1, @1); } | CURRENT_USER { - $$ = (Node *) makeFuncCall(SystemFuncName("current_user"), - NIL, - COERCE_SQL_SYNTAX, - @1); + $$ = makeSQLValueFunction(SVFOP_CURRENT_USER, -1, @1); } | SESSION_USER { - $$ = (Node *) makeFuncCall(SystemFuncName("session_user"), - NIL, - COERCE_SQL_SYNTAX, - @1); + $$ = makeSQLValueFunction(SVFOP_SESSION_USER, -1, @1); } | SYSTEM_USER { @@ -15379,24 +15345,15 @@ func_expr_common_subexpr: } | USER { - $$ = (Node *) makeFuncCall(SystemFuncName("user"), - NIL, - COERCE_SQL_SYNTAX, - @1); + $$ = makeSQLValueFunction(SVFOP_USER, -1, @1); } | CURRENT_CATALOG { - $$ = (Node *) makeFuncCall(SystemFuncName("current_catalog"), - NIL, - COERCE_SQL_SYNTAX, - @1); + $$ = makeSQLValueFunction(SVFOP_CURRENT_CATALOG, -1, @1); } | CURRENT_SCHEMA { - $$ = (Node *) makeFuncCall(SystemFuncName("current_schema"), - NIL, - COERCE_SQL_SYNTAX, - @1); + $$ = makeSQLValueFunction(SVFOP_CURRENT_SCHEMA, -1, @1); } | CAST '(' a_expr AS Typename ')' { $$ = makeTypeCast($3, $5, @1); } @@ -18520,6 +18477,18 @@ makeAArrayExpr(List *elements, int location) } static Node * +makeSQLValueFunction(SQLValueFunctionOp op, int32 typmod, int location) +{ + SQLValueFunction *svf = makeNode(SQLValueFunction); + + svf->op = op; + /* svf->type will be filled during parse analysis */ + svf->typmod = typmod; + svf->location = location; + return (Node *) svf; +} + +static Node * makeXmlExpr(XmlExprOp op, char *name, List *named_args, List *args, int location) { diff --git a/src/backend/parser/parse_expr.c b/src/backend/parser/parse_expr.c index 64356436ef7..0b3632735bf 100644 --- a/src/backend/parser/parse_expr.c +++ b/src/backend/parser/parse_expr.c @@ -64,6 +64,8 @@ static Node *transformArrayExpr(ParseState *pstate, A_ArrayExpr *a, static Node *transformRowExpr(ParseState *pstate, RowExpr *r, bool allowDefault); static Node *transformCoalesceExpr(ParseState *pstate, CoalesceExpr *c); static Node *transformMinMaxExpr(ParseState *pstate, MinMaxExpr *m); +static Node *transformSQLValueFunction(ParseState *pstate, + SQLValueFunction *svf); static Node *transformXmlExpr(ParseState *pstate, XmlExpr *x); static Node *transformXmlSerialize(ParseState *pstate, XmlSerialize *xs); static Node *transformBooleanTest(ParseState *pstate, BooleanTest *b); @@ -250,6 +252,11 @@ transformExprRecurse(ParseState *pstate, Node *expr) result = transformMinMaxExpr(pstate, (MinMaxExpr *) expr); break; + case T_SQLValueFunction: + result = transformSQLValueFunction(pstate, + (SQLValueFunction *) expr); + break; + case T_XmlExpr: result = transformXmlExpr(pstate, (XmlExpr *) expr); break; @@ -2221,6 +2228,59 @@ transformMinMaxExpr(ParseState *pstate, MinMaxExpr *m) } static Node * +transformSQLValueFunction(ParseState *pstate, SQLValueFunction *svf) +{ + /* + * All we need to do is insert the correct result type and (where needed) + * validate the typmod, so we just modify the node in-place. + */ + switch (svf->op) + { + case SVFOP_CURRENT_DATE: + svf->type = DATEOID; + break; + case SVFOP_CURRENT_TIME: + svf->type = TIMETZOID; + break; + case SVFOP_CURRENT_TIME_N: + svf->type = TIMETZOID; + svf->typmod = anytime_typmod_check(true, svf->typmod); + break; + case SVFOP_CURRENT_TIMESTAMP: + svf->type = TIMESTAMPTZOID; + break; + case SVFOP_CURRENT_TIMESTAMP_N: + svf->type = TIMESTAMPTZOID; + svf->typmod = anytimestamp_typmod_check(true, svf->typmod); + break; + case SVFOP_LOCALTIME: + svf->type = TIMEOID; + break; + case SVFOP_LOCALTIME_N: + svf->type = TIMEOID; + svf->typmod = anytime_typmod_check(false, svf->typmod); + break; + case SVFOP_LOCALTIMESTAMP: + svf->type = TIMESTAMPOID; + break; + case SVFOP_LOCALTIMESTAMP_N: + svf->type = TIMESTAMPOID; + svf->typmod = anytimestamp_typmod_check(false, svf->typmod); + break; + case SVFOP_CURRENT_ROLE: + case SVFOP_CURRENT_USER: + case SVFOP_USER: + case SVFOP_SESSION_USER: + case SVFOP_CURRENT_CATALOG: + case SVFOP_CURRENT_SCHEMA: + svf->type = NAMEOID; + break; + } + + return (Node *) svf; +} + +static Node * transformXmlExpr(ParseState *pstate, XmlExpr *x) { XmlExpr *newx; diff --git a/src/backend/parser/parse_target.c b/src/backend/parser/parse_target.c index e77b542fd76..4cca97ff9c1 100644 --- a/src/backend/parser/parse_target.c +++ b/src/backend/parser/parse_target.c @@ -1876,6 +1876,49 @@ FigureColnameInternal(Node *node, char **name) return 2; } break; + case T_SQLValueFunction: + /* make these act like a function or variable */ + switch (((SQLValueFunction *) node)->op) + { + case SVFOP_CURRENT_DATE: + *name = "current_date"; + return 2; + case SVFOP_CURRENT_TIME: + case SVFOP_CURRENT_TIME_N: + *name = "current_time"; + return 2; + case SVFOP_CURRENT_TIMESTAMP: + case SVFOP_CURRENT_TIMESTAMP_N: + *name = "current_timestamp"; + return 2; + case SVFOP_LOCALTIME: + case SVFOP_LOCALTIME_N: + *name = "localtime"; + return 2; + case SVFOP_LOCALTIMESTAMP: + case SVFOP_LOCALTIMESTAMP_N: + *name = "localtimestamp"; + return 2; + case SVFOP_CURRENT_ROLE: + *name = "current_role"; + return 2; + case SVFOP_CURRENT_USER: + *name = "current_user"; + return 2; + case SVFOP_USER: + *name = "user"; + return 2; + case SVFOP_SESSION_USER: + *name = "session_user"; + return 2; + case SVFOP_CURRENT_CATALOG: + *name = "current_catalog"; + return 2; + case SVFOP_CURRENT_SCHEMA: + *name = "current_schema"; + return 2; + } + break; case T_XmlExpr: /* make SQL/XML functions act like a regular function */ switch (((XmlExpr *) node)->op) |