0011-add-function-formats-v13.patch
text/x-patch
Filename: 0011-add-function-formats-v13.patch
Type: text/x-patch
Part: 1
Message:
Re: SQL/JSON: functions
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: unified
Series: patch v13-0011
| File | + | − |
|---|---|---|
| contrib/pg_stat_statements/pg_stat_statements.c | 6 | 0 |
| src/backend/nodes/copyfuncs.c | 6 | 0 |
| src/backend/nodes/equalfuncs.c | 6 | 0 |
| src/backend/nodes/outfuncs.c | 6 | 0 |
| src/backend/nodes/readfuncs.c | 6 | 0 |
| src/backend/optimizer/util/clauses.c | 4 | 0 |
| src/backend/utils/adt/ruleutils.c | 31 | 6 |
| src/include/nodes/primnodes.h | 11 | 0 |
diff --git a/contrib/pg_stat_statements/pg_stat_statements.c b/contrib/pg_stat_statements/pg_stat_statements.c
index 9286734..afc56a1 100644
--- a/contrib/pg_stat_statements/pg_stat_statements.c
+++ b/contrib/pg_stat_statements/pg_stat_statements.c
@@ -2480,11 +2480,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:
@@ -2500,8 +2502,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:
@@ -2519,7 +2523,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 f84da80..f215f3a 100644
--- a/src/backend/nodes/copyfuncs.c
+++ b/src/backend/nodes/copyfuncs.c
@@ -1378,6 +1378,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;
@@ -1417,6 +1419,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;
@@ -1458,6 +1462,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 ee8d925..7c28151 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 fd80891..52fdcbb 100644
--- a/src/backend/nodes/outfuncs.c
+++ b/src/backend/nodes/outfuncs.c
@@ -1153,6 +1153,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);
}
@@ -1182,6 +1184,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);
}
@@ -1213,6 +1217,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 068db35..745d3f3 100644
--- a/src/backend/nodes/readfuncs.c
+++ b/src/backend/nodes/readfuncs.c
@@ -600,6 +600,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();
@@ -639,6 +641,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();
@@ -680,6 +684,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 a9a09af..bee71b7 100644
--- a/src/backend/optimizer/util/clauses.c
+++ b/src/backend/optimizer/util/clauses.c
@@ -2655,6 +2655,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;
@@ -2701,6 +2703,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 096aa82..be46c00 100644
--- a/src/backend/utils/adt/ruleutils.c
+++ b/src/backend/utils/adt/ruleutils.c
@@ -8937,6 +8937,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
*/
@@ -8951,6 +8961,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
@@ -9005,12 +9016,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)
{
@@ -9020,6 +9038,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, ')');
}
@@ -9118,6 +9139,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 ");
@@ -9184,6 +9207,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 41330b2..641500e 100644
--- a/src/include/nodes/primnodes.h
+++ b/src/include/nodes/primnodes.h
@@ -249,6 +249,11 @@ typedef struct Param
int location; /* token location, or -1 if unknown */
} Param;
+typedef enum FuncFormat
+{
+ FUNCFMT_REGULAR = 0,
+} FuncFormat;
+
/*
* Aggref
*
@@ -308,6 +313,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;
@@ -361,6 +368,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;
@@ -456,6 +465,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;