From: Nikita Glukhov Date: Tue, 4 Dec 2018 02:05:11 +0300 Subject: [PATCH 08/13] Add function formats --- contrib/pg_stat_statements/pg_stat_statements.c | 6 ++++ src/backend/nodes/copyfuncs.c | 6 ++++ src/backend/nodes/equalfuncs.c | 6 ++++ src/backend/nodes/outfuncs.c | 6 ++++ src/backend/nodes/readfuncs.c | 6 ++++ src/backend/optimizer/util/clauses.c | 4 +++ src/backend/utils/adt/ruleutils.c | 37 +++++++++++++++++++++---- src/include/nodes/primnodes.h | 11 ++++++++ 8 files changed, 76 insertions(+), 6 deletions(-) diff --git a/contrib/pg_stat_statements/pg_stat_statements.c b/contrib/pg_stat_statements/pg_stat_statements.c index 33f9a79..7f770d2 100644 --- a/contrib/pg_stat_statements/pg_stat_statements.c +++ b/contrib/pg_stat_statements/pg_stat_statements.c @@ -2481,11 +2481,13 @@ JumbleExpr(pgssJumbleState *jstate, Node *node) Aggref *expr = (Aggref *) node; APP_JUMB(expr->aggfnoid); + APP_JUMB(expr->aggformat); JumbleExpr(jstate, (Node *) expr->aggdirectargs); JumbleExpr(jstate, (Node *) expr->args); JumbleExpr(jstate, (Node *) expr->aggorder); JumbleExpr(jstate, (Node *) expr->aggdistinct); JumbleExpr(jstate, (Node *) expr->aggfilter); + JumbleExpr(jstate, (Node *) expr->aggformatopts); } break; case T_GroupingFunc: @@ -2501,8 +2503,10 @@ JumbleExpr(pgssJumbleState *jstate, Node *node) APP_JUMB(expr->winfnoid); APP_JUMB(expr->winref); + APP_JUMB(expr->winformat); JumbleExpr(jstate, (Node *) expr->args); JumbleExpr(jstate, (Node *) expr->aggfilter); + JumbleExpr(jstate, (Node *) expr->winformatopts); } break; case T_ArrayRef: @@ -2520,7 +2524,9 @@ JumbleExpr(pgssJumbleState *jstate, Node *node) FuncExpr *expr = (FuncExpr *) node; APP_JUMB(expr->funcid); + APP_JUMB(expr->funcformat2); JumbleExpr(jstate, (Node *) expr->args); + JumbleExpr(jstate, (Node *) expr->funcformatopts); } break; case T_NamedArgExpr: diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c index db49968..30c234e 100644 --- a/src/backend/nodes/copyfuncs.c +++ b/src/backend/nodes/copyfuncs.c @@ -1441,6 +1441,8 @@ _copyAggref(const Aggref *from) COPY_SCALAR_FIELD(aggkind); COPY_SCALAR_FIELD(agglevelsup); COPY_SCALAR_FIELD(aggsplit); + COPY_SCALAR_FIELD(aggformat); + COPY_NODE_FIELD(aggformatopts); COPY_LOCATION_FIELD(location); return newnode; @@ -1480,6 +1482,8 @@ _copyWindowFunc(const WindowFunc *from) COPY_SCALAR_FIELD(winref); COPY_SCALAR_FIELD(winstar); COPY_SCALAR_FIELD(winagg); + COPY_SCALAR_FIELD(winformat); + COPY_NODE_FIELD(winformatopts); COPY_LOCATION_FIELD(location); return newnode; @@ -1521,6 +1525,8 @@ _copyFuncExpr(const FuncExpr *from) COPY_SCALAR_FIELD(funccollid); COPY_SCALAR_FIELD(inputcollid); COPY_NODE_FIELD(args); + COPY_SCALAR_FIELD(funcformat2); + COPY_NODE_FIELD(funcformatopts); COPY_LOCATION_FIELD(location); return newnode; diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c index 3a084b4..edfcb78 100644 --- a/src/backend/nodes/equalfuncs.c +++ b/src/backend/nodes/equalfuncs.c @@ -226,6 +226,8 @@ _equalAggref(const Aggref *a, const Aggref *b) COMPARE_SCALAR_FIELD(aggkind); COMPARE_SCALAR_FIELD(agglevelsup); COMPARE_SCALAR_FIELD(aggsplit); + COMPARE_SCALAR_FIELD(aggformat); + COMPARE_NODE_FIELD(aggformatopts); COMPARE_LOCATION_FIELD(location); return true; @@ -258,6 +260,8 @@ _equalWindowFunc(const WindowFunc *a, const WindowFunc *b) COMPARE_SCALAR_FIELD(winref); COMPARE_SCALAR_FIELD(winstar); COMPARE_SCALAR_FIELD(winagg); + COMPARE_SCALAR_FIELD(winformat); + COMPARE_NODE_FIELD(winformatopts); COMPARE_LOCATION_FIELD(location); return true; @@ -289,6 +293,8 @@ _equalFuncExpr(const FuncExpr *a, const FuncExpr *b) COMPARE_SCALAR_FIELD(funccollid); COMPARE_SCALAR_FIELD(inputcollid); COMPARE_NODE_FIELD(args); + COMPARE_SCALAR_FIELD(funcformat2); + COMPARE_NODE_FIELD(funcformatopts); COMPARE_LOCATION_FIELD(location); return true; diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c index f0c3965..b884bb8 100644 --- a/src/backend/nodes/outfuncs.c +++ b/src/backend/nodes/outfuncs.c @@ -1219,6 +1219,8 @@ _outAggref(StringInfo str, const Aggref *node) WRITE_CHAR_FIELD(aggkind); WRITE_UINT_FIELD(agglevelsup); WRITE_ENUM_FIELD(aggsplit, AggSplit); + WRITE_ENUM_FIELD(aggformat, FuncFormat); + WRITE_NODE_FIELD(aggformatopts); WRITE_LOCATION_FIELD(location); } @@ -1248,6 +1250,8 @@ _outWindowFunc(StringInfo str, const WindowFunc *node) WRITE_UINT_FIELD(winref); WRITE_BOOL_FIELD(winstar); WRITE_BOOL_FIELD(winagg); + WRITE_ENUM_FIELD(winformat, FuncFormat); + WRITE_NODE_FIELD(winformatopts); WRITE_LOCATION_FIELD(location); } @@ -1279,6 +1283,8 @@ _outFuncExpr(StringInfo str, const FuncExpr *node) WRITE_OID_FIELD(funccollid); WRITE_OID_FIELD(inputcollid); WRITE_NODE_FIELD(args); + WRITE_ENUM_FIELD(funcformat2, FuncFormat); + WRITE_NODE_FIELD(funcformatopts); WRITE_LOCATION_FIELD(location); } diff --git a/src/backend/nodes/readfuncs.c b/src/backend/nodes/readfuncs.c index e117867..cc55517 100644 --- a/src/backend/nodes/readfuncs.c +++ b/src/backend/nodes/readfuncs.c @@ -611,6 +611,8 @@ _readAggref(void) READ_CHAR_FIELD(aggkind); READ_UINT_FIELD(agglevelsup); READ_ENUM_FIELD(aggsplit, AggSplit); + READ_ENUM_FIELD(aggformat, FuncFormat); + READ_NODE_FIELD(aggformatopts); READ_LOCATION_FIELD(location); READ_DONE(); @@ -650,6 +652,8 @@ _readWindowFunc(void) READ_UINT_FIELD(winref); READ_BOOL_FIELD(winstar); READ_BOOL_FIELD(winagg); + READ_ENUM_FIELD(winformat, FuncFormat); + READ_NODE_FIELD(winformatopts); READ_LOCATION_FIELD(location); READ_DONE(); @@ -691,6 +695,8 @@ _readFuncExpr(void) READ_OID_FIELD(funccollid); READ_OID_FIELD(inputcollid); READ_NODE_FIELD(args); + READ_ENUM_FIELD(funcformat2, FuncFormat); + READ_NODE_FIELD(funcformatopts); READ_LOCATION_FIELD(location); READ_DONE(); diff --git a/src/backend/optimizer/util/clauses.c b/src/backend/optimizer/util/clauses.c index 8df3693..4413d03 100644 --- a/src/backend/optimizer/util/clauses.c +++ b/src/backend/optimizer/util/clauses.c @@ -2692,6 +2692,8 @@ eval_const_expressions_mutator(Node *node, newexpr->winref = expr->winref; newexpr->winstar = expr->winstar; newexpr->winagg = expr->winagg; + newexpr->winformat = expr->winformat; + newexpr->winformatopts = copyObject(expr->winformatopts); newexpr->location = expr->location; return (Node *) newexpr; @@ -2738,6 +2740,8 @@ eval_const_expressions_mutator(Node *node, newexpr->funccollid = expr->funccollid; newexpr->inputcollid = expr->inputcollid; newexpr->args = args; + newexpr->funcformat2 = expr->funcformat2; + newexpr->funcformatopts = copyObject(expr->funcformatopts); newexpr->location = expr->location; return (Node *) newexpr; } diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 3c84f91..46ddc35 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -9045,6 +9045,16 @@ get_oper_expr(OpExpr *expr, deparse_context *context) appendStringInfoChar(buf, ')'); } +static void +get_func_opts(FuncFormat aggformat, Node *aggformatopts, deparse_context *context) +{ + switch (aggformat) + { + default: + break; + } +} + /* * get_func_expr - Parse back a FuncExpr node */ @@ -9059,6 +9069,7 @@ get_func_expr(FuncExpr *expr, deparse_context *context, List *argnames; bool use_variadic; ListCell *l; + const char *funcname; /* * If the function call came from an implicit coercion, then just show the @@ -9113,12 +9124,19 @@ get_func_expr(FuncExpr *expr, deparse_context *context, nargs++; } - appendStringInfo(buf, "%s(", - generate_function_name(funcoid, nargs, - argnames, argtypes, - expr->funcvariadic, - &use_variadic, - context->special_exprkind)); + switch (expr->funcformat2) + { + default: + funcname = generate_function_name(funcoid, nargs, + argnames, argtypes, + expr->funcvariadic, + &use_variadic, + context->special_exprkind); + break; + } + + appendStringInfo(buf, "%s(", funcname); + nargs = 0; foreach(l, expr->args) { @@ -9128,6 +9146,9 @@ get_func_expr(FuncExpr *expr, deparse_context *context, appendStringInfoString(buf, "VARIADIC "); get_rule_expr((Node *) lfirst(l), context, true); } + + get_func_opts(expr->funcformat2, expr->funcformatopts, context); + appendStringInfoChar(buf, ')'); } @@ -9226,6 +9247,8 @@ get_agg_expr(Aggref *aggref, deparse_context *context, } } + get_func_opts(aggref->aggformat, aggref->aggformatopts, context); + if (aggref->aggfilter != NULL) { appendStringInfoString(buf, ") FILTER (WHERE "); @@ -9292,6 +9315,8 @@ get_windowfunc_expr(WindowFunc *wfunc, deparse_context *context) else get_rule_expr((Node *) wfunc->args, context, true); + get_func_opts(wfunc->winformat, wfunc->winformatopts, context); + if (wfunc->aggfilter != NULL) { appendStringInfoString(buf, ") FILTER (WHERE "); diff --git a/src/include/nodes/primnodes.h b/src/include/nodes/primnodes.h index 67533d4..ecf6ff6 100644 --- a/src/include/nodes/primnodes.h +++ b/src/include/nodes/primnodes.h @@ -252,6 +252,11 @@ typedef struct Param int location; /* token location, or -1 if unknown */ } Param; +typedef enum FuncFormat +{ + FUNCFMT_REGULAR = 0, +} FuncFormat; + /* * Aggref * @@ -311,6 +316,8 @@ typedef struct Aggref char aggkind; /* aggregate kind (see pg_aggregate.h) */ Index agglevelsup; /* > 0 if agg belongs to outer query */ AggSplit aggsplit; /* expected agg-splitting mode of parent Agg */ + FuncFormat aggformat; /* how to display this aggregate */ + Node *aggformatopts; /* display options, if any */ int location; /* token location, or -1 if unknown */ } Aggref; @@ -364,6 +371,8 @@ typedef struct WindowFunc Index winref; /* index of associated WindowClause */ bool winstar; /* true if argument list was really '*' */ bool winagg; /* is function a simple aggregate? */ + FuncFormat winformat; /* how to display this window function */ + Node *winformatopts; /* display options, if any */ int location; /* token location, or -1 if unknown */ } WindowFunc; @@ -459,6 +468,8 @@ typedef struct FuncExpr Oid funccollid; /* OID of collation of result */ Oid inputcollid; /* OID of collation that function should use */ List *args; /* arguments to the function */ + FuncFormat funcformat2; /* how to display this function call */ + Node *funcformatopts; /* display options, if any */ int location; /* token location, or -1 if unknown */ } FuncExpr; -- 2.7.4 --------------2248398DA0749267D43F99DB Content-Type: text/x-patch; name="0009-SQL-JSON-functions-v21.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="0009-SQL-JSON-functions-v21.patch"