agora inbox for [email protected]  
help / color / mirror / Atom feed
[PATCH 06/11] Add function formats
5+ messages / 4 participants
[nested] [flat]

* [PATCH 06/11] Add function formats
@ 2018-11-26 16:03 Nikita Glukhov <[email protected]>
  0 siblings, 0 replies; 5+ messages in thread

From: Nikita Glukhov @ 2018-11-26 16:03 UTC (permalink / raw)

---
 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


--------------0D18A6F3D5DF72C86FFB8E95
Content-Type: text/x-patch;
 name="0007-SQL-JSON-functions-v20.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
 filename="0007-SQL-JSON-functions-v20.patch"



^ permalink  raw  reply  [nested|flat] 5+ messages in thread

* [PATCH 08/13] Add function formats
@ 2018-12-03 23:05 Nikita Glukhov <[email protected]>
  0 siblings, 0 replies; 5+ messages in thread

From: Nikita Glukhov @ 2018-12-03 23:05 UTC (permalink / raw)

---
 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"



^ permalink  raw  reply  [nested|flat] 5+ messages in thread

* Re: Questions about the new subscription parameter: password_required
@ 2023-10-13 18:54 Jeff Davis <[email protected]>
  2023-10-15 22:47 ` Re: Questions about the new subscription parameter: password_required Peter Smith <[email protected]>
  0 siblings, 1 reply; 5+ messages in thread

From: Jeff Davis @ 2023-10-13 18:54 UTC (permalink / raw)
  To: Benoit Lobréau <[email protected]>; Robert Haas <[email protected]>; +Cc: pgsql-hackers

On Fri, 2023-10-13 at 11:18 +0200, Benoit Lobréau wrote:
> I tried adding a section in "Logical Replication > Subscription" with
> the text you suggested and links in the CREATE / ALTER SUBSRIPTION
> commands.
> 
> Is it better ?


Minor comments:

 * Use possessive "its" instead of the contraction, i.e. "before
transferring its ownership".
 * I like that docs cover the case where a password is specified, but
the remote server doesn't require one. But the warning is the wrong
place to explain that, it should be in the main behavioral description
in 31.2.2.
 * The warning feels like it has too many negatives and confused me at
first. I struggled myself a bit to come up with something less
confusing, but perhaps less is more: "Ensure that password_required is
properly set before transferring ownership of a subscription to a non-
superuser, otherwise the subscription may start to fail."
 * Missing space in the warning after "password_required = true"
 * Mention that a non-superuser-owned subscription with
password_required = false is partially locked down, e.g. the owner
can't change the connection string any more.
 * 31.2.2 could probably be in the CREATE SUBSCRIPTION docs instead,
and linked from the ALTER docs. That's fairly normal for other commands
and I'm not sure there needs to be a separate section in logical
replication. I don't have a strong opinion here.

I like the changes; this is a big improvement. I'll leave it to Robert
to commit it, so that he can ensure it matches how he expected the
feature to be used and sufficiently covers the behavioral aspects.

Regards,
	Jeff Davis







^ permalink  raw  reply  [nested|flat] 5+ messages in thread

* Re: Questions about the new subscription parameter: password_required
  2023-10-13 18:54 Re: Questions about the new subscription parameter: password_required Jeff Davis <[email protected]>
@ 2023-10-15 22:47 ` Peter Smith <[email protected]>
  0 siblings, 0 replies; 5+ messages in thread

From: Peter Smith @ 2023-10-15 22:47 UTC (permalink / raw)
  To: Jeff Davis <[email protected]>; +Cc: Benoit Lobréau <[email protected]>; Robert Haas <[email protected]>; pgsql-hackers

Hi, how about having links (instead of just
<literal>password_required=false</literal>) in alter_subscription.sgml
and logical-replication.sgml so the user can navigate easily back to
the CREATE SUBSCRIPTION parameters "password_required" part.

For example, alter_subscription.sgml does this already for "two_phase"
and "copy_data" but not for "password_required" (??)

======
Kind Regards,
Peter Smith
Fujitsu Australia

On Sat, Oct 14, 2023 at 5:57 AM Jeff Davis <[email protected]> wrote:
>
> On Fri, 2023-10-13 at 11:18 +0200, Benoit Lobréau wrote:
> > I tried adding a section in "Logical Replication > Subscription" with
> > the text you suggested and links in the CREATE / ALTER SUBSRIPTION
> > commands.
> >
> > Is it better ?
>
>
> Minor comments:
>
>  * Use possessive "its" instead of the contraction, i.e. "before
> transferring its ownership".
>  * I like that docs cover the case where a password is specified, but
> the remote server doesn't require one. But the warning is the wrong
> place to explain that, it should be in the main behavioral description
> in 31.2.2.
>  * The warning feels like it has too many negatives and confused me at
> first. I struggled myself a bit to come up with something less
> confusing, but perhaps less is more: "Ensure that password_required is
> properly set before transferring ownership of a subscription to a non-
> superuser, otherwise the subscription may start to fail."
>  * Missing space in the warning after "password_required = true"
>  * Mention that a non-superuser-owned subscription with
> password_required = false is partially locked down, e.g. the owner
> can't change the connection string any more.
>  * 31.2.2 could probably be in the CREATE SUBSCRIPTION docs instead,
> and linked from the ALTER docs. That's fairly normal for other commands
> and I'm not sure there needs to be a separate section in logical
> replication. I don't have a strong opinion here.
>
> I like the changes; this is a big improvement. I'll leave it to Robert
> to commit it, so that he can ensure it matches how he expected the
> feature to be used and sufficiently covers the behavioral aspects.
>
> Regards,
>         Jeff Davis
>
>
>






^ permalink  raw  reply  [nested|flat] 5+ messages in thread

* [PATCH v43 1/7] Refactor index_concurrently_create_copy() for use with REPACK (CONCURRENTLY).
@ 2026-03-11 13:15 Antonin Houska <[email protected]>
  0 siblings, 0 replies; 5+ messages in thread

From: Antonin Houska @ 2026-03-11 13:15 UTC (permalink / raw)

This patch moves the code to index_create_copy() and adds a "concurrently"
parameter so it can be used by REPACK (CONCURRENTLY).

With the CONCURRENTLY option, REPACK cannot simply swap the heap file and
rebuild its indexes. Instead, it needs to build a separate set of indexes
(including system catalog entries) *before* the actual swap, to reduce the
time AccessExclusiveLock needs to be held for.
---
 src/backend/catalog/index.c      | 54 +++++++++++++++++++++++---------
 src/backend/commands/indexcmds.c |  6 ++--
 src/backend/nodes/makefuncs.c    |  9 +++---
 src/include/catalog/index.h      |  3 ++
 src/include/nodes/makefuncs.h    |  4 ++-
 5 files changed, 54 insertions(+), 22 deletions(-)

diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index d8219b18c48..98d38dc5229 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1291,15 +1291,32 @@ index_create(Relation heapRelation,
 /*
  * index_concurrently_create_copy
  *
- * Create concurrently an index based on the definition of the one provided by
- * caller.  The index is inserted into catalogs and needs to be built later
- * on.  This is called during concurrent reindex processing.
- *
- * "tablespaceOid" is the tablespace to use for this index.
+ * Variant of index_create_copy(), called during concurrent reindex
+ * processing.
  */
 Oid
 index_concurrently_create_copy(Relation heapRelation, Oid oldIndexId,
 							   Oid tablespaceOid, const char *newName)
+{
+	return index_create_copy(heapRelation, oldIndexId, tablespaceOid, newName,
+							 true);
+}
+
+/*
+ * index_create_copy
+ *
+ * Create an index based on the definition of the one provided by caller.  The
+ * index is inserted into catalogs. If 'concurrently' is TRUE, it needs to be
+ * built later on, otherwise it's built immediately.
+ *
+ * "tablespaceOid" is the tablespace to use for this index.
+ *
+ * The actual implementation of index_concurrently_create_copy(), reusable for
+ * other purposes.
+ */
+Oid
+index_create_copy(Relation heapRelation, Oid oldIndexId, Oid tablespaceOid,
+				  const char *newName, bool concurrently)
 {
 	Relation	indexRelation;
 	IndexInfo  *oldInfo,
@@ -1318,6 +1335,7 @@ index_concurrently_create_copy(Relation heapRelation, Oid oldIndexId,
 	List	   *indexColNames = NIL;
 	List	   *indexExprs = NIL;
 	List	   *indexPreds = NIL;
+	int			flags = 0;
 
 	indexRelation = index_open(oldIndexId, RowExclusiveLock);
 
@@ -1328,7 +1346,7 @@ index_concurrently_create_copy(Relation heapRelation, Oid oldIndexId,
 	 * Concurrent build of an index with exclusion constraints is not
 	 * supported.
 	 */
-	if (oldInfo->ii_ExclusionOps != NULL)
+	if (oldInfo->ii_ExclusionOps != NULL && concurrently)
 		ereport(ERROR,
 				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
 				 errmsg("concurrent index creation for exclusion constraints is not supported")));
@@ -1384,9 +1402,7 @@ index_concurrently_create_copy(Relation heapRelation, Oid oldIndexId,
 	}
 
 	/*
-	 * Build the index information for the new index.  Note that rebuild of
-	 * indexes with exclusion constraints is not supported, hence there is no
-	 * need to fill all the ii_Exclusion* fields.
+	 * Build the index information for the new index.
 	 */
 	newInfo = makeIndexInfo(oldInfo->ii_NumIndexAttrs,
 							oldInfo->ii_NumIndexKeyAttrs,
@@ -1395,10 +1411,13 @@ index_concurrently_create_copy(Relation heapRelation, Oid oldIndexId,
 							indexPreds,
 							oldInfo->ii_Unique,
 							oldInfo->ii_NullsNotDistinct,
-							false,	/* not ready for inserts */
-							true,
+							!concurrently,	/* isready */
+							concurrently,	/* concurrent */
 							indexRelation->rd_indam->amsummarizing,
-							oldInfo->ii_WithoutOverlaps);
+							oldInfo->ii_WithoutOverlaps,
+							oldInfo->ii_ExclusionOps,
+							oldInfo->ii_ExclusionProcs,
+							oldInfo->ii_ExclusionStrats);
 
 	/*
 	 * Extract the list of column names and the column numbers for the new
@@ -1436,6 +1455,9 @@ index_concurrently_create_copy(Relation heapRelation, Oid oldIndexId,
 		stattargets[i].isnull = isnull;
 	}
 
+	if (concurrently)
+		flags = INDEX_CREATE_SKIP_BUILD | INDEX_CREATE_CONCURRENT;
+
 	/*
 	 * Now create the new index.
 	 *
@@ -1459,7 +1481,7 @@ index_concurrently_create_copy(Relation heapRelation, Oid oldIndexId,
 							  indcoloptions->values,
 							  stattargets,
 							  reloptionsDatum,
-							  INDEX_CREATE_SKIP_BUILD | INDEX_CREATE_CONCURRENT,
+							  flags,
 							  0,
 							  true, /* allow table to be a system catalog? */
 							  false,	/* is_internal? */
@@ -2453,7 +2475,8 @@ BuildIndexInfo(Relation index)
 					   indexStruct->indisready,
 					   false,
 					   index->rd_indam->amsummarizing,
-					   indexStruct->indisexclusion && indexStruct->indisunique);
+					   indexStruct->indisexclusion && indexStruct->indisunique,
+					   NULL, NULL, NULL);
 
 	/* fill in attribute numbers */
 	for (i = 0; i < numAtts; i++)
@@ -2513,7 +2536,8 @@ BuildDummyIndexInfo(Relation index)
 					   indexStruct->indisready,
 					   false,
 					   index->rd_indam->amsummarizing,
-					   indexStruct->indisexclusion && indexStruct->indisunique);
+					   indexStruct->indisexclusion && indexStruct->indisunique,
+					   NULL, NULL, NULL);
 
 	/* fill in attribute numbers */
 	for (i = 0; i < numAtts; i++)
diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c
index b89c6855364..836eedb8ed5 100644
--- a/src/backend/commands/indexcmds.c
+++ b/src/backend/commands/indexcmds.c
@@ -244,7 +244,8 @@ CheckIndexCompatible(Oid oldId,
 	 */
 	indexInfo = makeIndexInfo(numberOfAttributes, numberOfAttributes,
 							  accessMethodId, NIL, NIL, false, false,
-							  false, false, amsummarizing, isWithoutOverlaps);
+							  false, false, amsummarizing, isWithoutOverlaps,
+							  NULL, NULL, NULL);
 	typeIds = palloc_array(Oid, numberOfAttributes);
 	collationIds = palloc_array(Oid, numberOfAttributes);
 	opclassIds = palloc_array(Oid, numberOfAttributes);
@@ -931,7 +932,8 @@ DefineIndex(ParseState *pstate,
 							  !concurrent,
 							  concurrent,
 							  amissummarizing,
-							  stmt->iswithoutoverlaps);
+							  stmt->iswithoutoverlaps,
+							  NULL, NULL, NULL);
 
 	typeIds = palloc_array(Oid, numberOfAttributes);
 	collationIds = palloc_array(Oid, numberOfAttributes);
diff --git a/src/backend/nodes/makefuncs.c b/src/backend/nodes/makefuncs.c
index 3cd35c5c457..8d23aa917e5 100644
--- a/src/backend/nodes/makefuncs.c
+++ b/src/backend/nodes/makefuncs.c
@@ -834,7 +834,8 @@ IndexInfo *
 makeIndexInfo(int numattrs, int numkeyattrs, Oid amoid, List *expressions,
 			  List *predicates, bool unique, bool nulls_not_distinct,
 			  bool isready, bool concurrent, bool summarizing,
-			  bool withoutoverlaps)
+			  bool withoutoverlaps, Oid *exclusion_ops, Oid *exclusion_procs,
+			  uint16 *exclusion_strats)
 {
 	IndexInfo  *n = makeNode(IndexInfo);
 
@@ -863,9 +864,9 @@ makeIndexInfo(int numattrs, int numkeyattrs, Oid amoid, List *expressions,
 	n->ii_PredicateState = NULL;
 
 	/* exclusion constraints */
-	n->ii_ExclusionOps = NULL;
-	n->ii_ExclusionProcs = NULL;
-	n->ii_ExclusionStrats = NULL;
+	n->ii_ExclusionOps = exclusion_ops;
+	n->ii_ExclusionProcs = exclusion_procs;
+	n->ii_ExclusionStrats = exclusion_strats;
 
 	/* speculative inserts */
 	n->ii_UniqueOps = NULL;
diff --git a/src/include/catalog/index.h b/src/include/catalog/index.h
index 36b70689254..144e241ebd3 100644
--- a/src/include/catalog/index.h
+++ b/src/include/catalog/index.h
@@ -105,6 +105,9 @@ extern Oid	index_concurrently_create_copy(Relation heapRelation,
 										   Oid oldIndexId,
 										   Oid tablespaceOid,
 										   const char *newName);
+extern Oid	index_create_copy(Relation heapRelation, Oid oldIndexId,
+							  Oid tablespaceOid, const char *newName,
+							  bool concurrently);
 
 extern void index_concurrently_build(Oid heapRelationId,
 									 Oid indexRelationId);
diff --git a/src/include/nodes/makefuncs.h b/src/include/nodes/makefuncs.h
index bf54d39feb0..40ec249a7a1 100644
--- a/src/include/nodes/makefuncs.h
+++ b/src/include/nodes/makefuncs.h
@@ -99,7 +99,9 @@ extern IndexInfo *makeIndexInfo(int numattrs, int numkeyattrs, Oid amoid,
 								List *expressions, List *predicates,
 								bool unique, bool nulls_not_distinct,
 								bool isready, bool concurrent,
-								bool summarizing, bool withoutoverlaps);
+								bool summarizing, bool withoutoverlaps,
+								Oid *exclusion_ops, Oid *exclusion_procs,
+								uint16 *exclusion_strats);
 
 extern Node *makeStringConst(char *str, int location);
 extern DefElem *makeDefElem(char *name, Node *arg, int location);
-- 
2.47.3


--nzintiedl6o4kcyp
Content-Type: text/x-diff; charset=utf-8
Content-Disposition: attachment;
	filename="v43-0002-Do-not-dereference-varattrib_4b-in-VARSIZE_4B.patch"



^ permalink  raw  reply  [nested|flat] 5+ messages in thread


end of thread, other threads:[~2026-03-11 13:15 UTC | newest]

Thread overview: 5+ messages (download: mbox mbox.gz follow: Atom feed)
-- links below jump to the message on this page --
2018-11-26 16:03 [PATCH 06/11] Add function formats Nikita Glukhov <[email protected]>
2018-12-03 23:05 [PATCH 08/13] Add function formats Nikita Glukhov <[email protected]>
2023-10-13 18:54 Re: Questions about the new subscription parameter: password_required Jeff Davis <[email protected]>
2023-10-15 22:47 ` Re: Questions about the new subscription parameter: password_required Peter Smith <[email protected]>
2026-03-11 13:15 [PATCH v43 1/7] Refactor index_concurrently_create_copy() for use with REPACK (CONCURRENTLY). Antonin Houska <[email protected]>

This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox