From 5ac3c30fc1f9b7c265f33dae7999b56ea5c776e8 Mon Sep 17 00:00:00 2001
From: Michael Paquier <michael@paquier.xyz>
Date: Thu, 11 May 2023 14:39:22 +0900
Subject: [PATCH v1 2/2] Revert "Switch SQLValueFunction on "name" to use
 COERCE_SQL_SYNTAX"

This reverts commit fb32748e32e2b6b2fcb32220980b93d5436f855e.
---
 src/include/catalog/pg_proc.dat       |  9 -------
 src/include/nodes/primnodes.h         |  8 +++++-
 src/backend/executor/execExprInterp.c | 27 ++++++++++++++++++++
 src/backend/nodes/nodeFuncs.c         | 11 +++++---
 src/backend/parser/gram.y             | 30 +++++-----------------
 src/backend/parser/parse_expr.c       |  8 ++++++
 src/backend/parser/parse_target.c     | 18 ++++++++++++++
 src/backend/utils/adt/ruleutils.c     | 36 +++++++++++++--------------
 8 files changed, 92 insertions(+), 55 deletions(-)

diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat
index 0a0f749385..d7a60b39b5 100644
--- a/src/include/catalog/pg_proc.dat
+++ b/src/include/catalog/pg_proc.dat
@@ -1505,15 +1505,6 @@
 { oid => '745', descr => 'current user name',
   proname => 'current_user', provolatile => 's', prorettype => 'name',
   proargtypes => '', prosrc => 'current_user' },
-{ oid => '9695', descr => 'current role name',
-  proname => 'current_role', provolatile => 's', prorettype => 'name',
-  proargtypes => '', prosrc => 'current_user' },
-{ oid => '9696', descr => 'user name',
-  proname => 'user', provolatile => 's', prorettype => 'name',
-  proargtypes => '', prosrc => 'current_user' },
-{ oid => '9697', descr => 'name of the current database',
-  proname => 'current_catalog', provolatile => 's', prorettype => 'name',
-  proargtypes => '', prosrc => 'current_database' },
 { oid => '746', descr => 'session user name',
   proname => 'session_user', provolatile => 's', prorettype => 'name',
   proargtypes => '', prosrc => 'session_user' },
diff --git a/src/include/nodes/primnodes.h b/src/include/nodes/primnodes.h
index 7ade0d83f7..08e7dae73f 100644
--- a/src/include/nodes/primnodes.h
+++ b/src/include/nodes/primnodes.h
@@ -1466,7 +1466,13 @@ typedef enum SQLValueFunctionOp
 	SVFOP_LOCALTIME,
 	SVFOP_LOCALTIME_N,
 	SVFOP_LOCALTIMESTAMP,
-	SVFOP_LOCALTIMESTAMP_N
+	SVFOP_LOCALTIMESTAMP_N,
+	SVFOP_CURRENT_ROLE,
+	SVFOP_CURRENT_USER,
+	SVFOP_USER,
+	SVFOP_SESSION_USER,
+	SVFOP_CURRENT_CATALOG,
+	SVFOP_CURRENT_SCHEMA
 } SQLValueFunctionOp;
 
 typedef struct SQLValueFunction
diff --git a/src/backend/executor/execExprInterp.c b/src/backend/executor/execExprInterp.c
index d98710bfb3..7cc443ec52 100644
--- a/src/backend/executor/execExprInterp.c
+++ b/src/backend/executor/execExprInterp.c
@@ -2515,10 +2515,15 @@ ExecEvalParamExtern(ExprState *state, ExprEvalStep *op, ExprContext *econtext)
 void
 ExecEvalSQLValueFunction(ExprState *state, ExprEvalStep *op)
 {
+	LOCAL_FCINFO(fcinfo, 0);
 	SQLValueFunction *svf = op->d.sqlvaluefunction.svf;
 
 	*op->resnull = false;
 
+	/*
+	 * Note: current_schema() can return NULL.  current_user() etc currently
+	 * cannot, but might as well code those cases the same way for safety.
+	 */
 	switch (svf->op)
 	{
 		case SVFOP_CURRENT_DATE:
@@ -2540,6 +2545,28 @@ ExecEvalSQLValueFunction(ExprState *state, ExprEvalStep *op)
 		case SVFOP_LOCALTIMESTAMP_N:
 			*op->resvalue = TimestampGetDatum(GetSQLLocalTimestamp(svf->typmod));
 			break;
+		case SVFOP_CURRENT_ROLE:
+		case SVFOP_CURRENT_USER:
+		case SVFOP_USER:
+			InitFunctionCallInfoData(*fcinfo, NULL, 0, InvalidOid, NULL, NULL);
+			*op->resvalue = current_user(fcinfo);
+			*op->resnull = fcinfo->isnull;
+			break;
+		case SVFOP_SESSION_USER:
+			InitFunctionCallInfoData(*fcinfo, NULL, 0, InvalidOid, NULL, NULL);
+			*op->resvalue = session_user(fcinfo);
+			*op->resnull = fcinfo->isnull;
+			break;
+		case SVFOP_CURRENT_CATALOG:
+			InitFunctionCallInfoData(*fcinfo, NULL, 0, InvalidOid, NULL, NULL);
+			*op->resvalue = current_database(fcinfo);
+			*op->resnull = fcinfo->isnull;
+			break;
+		case SVFOP_CURRENT_SCHEMA:
+			InitFunctionCallInfoData(*fcinfo, NULL, 0, InvalidOid, NULL, NULL);
+			*op->resvalue = current_schema(fcinfo);
+			*op->resnull = fcinfo->isnull;
+			break;
 	}
 }
 
diff --git a/src/backend/nodes/nodeFuncs.c b/src/backend/nodes/nodeFuncs.c
index 5252efdf21..0ed8712a63 100644
--- a/src/backend/nodes/nodeFuncs.c
+++ b/src/backend/nodes/nodeFuncs.c
@@ -936,8 +936,11 @@ exprCollation(const Node *expr)
 			coll = ((const MinMaxExpr *) expr)->minmaxcollid;
 			break;
 		case T_SQLValueFunction:
-			/* Returns a non-collatable type */
-			coll = InvalidOid;
+			/* Returns either NAME or a non-collatable type */
+			if (((const SQLValueFunction *) expr)->type == NAMEOID)
+				coll = C_COLLATION_OID;
+			else
+				coll = InvalidOid;
 			break;
 		case T_XmlExpr:
 
@@ -1177,7 +1180,9 @@ exprSetCollation(Node *expr, Oid collation)
 			((MinMaxExpr *) expr)->minmaxcollid = collation;
 			break;
 		case T_SQLValueFunction:
-			Assert(collation == InvalidOid);
+			Assert((((SQLValueFunction *) expr)->type == NAMEOID) ?
+				   (collation == C_COLLATION_OID) :
+				   (collation == InvalidOid));
 			break;
 		case T_XmlExpr:
 			Assert((((XmlExpr *) expr)->op == IS_XMLSERIALIZE) ?
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index 62f521cf10..6f5aa8a3cb 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -15326,24 +15326,15 @@ func_expr_common_subexpr:
 				}
 			| 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
 				{
@@ -15354,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); }
diff --git a/src/backend/parser/parse_expr.c b/src/backend/parser/parse_expr.c
index f0369eee41..0b3632735b 100644
--- a/src/backend/parser/parse_expr.c
+++ b/src/backend/parser/parse_expr.c
@@ -2267,6 +2267,14 @@ transformSQLValueFunction(ParseState *pstate, SQLValueFunction *svf)
 			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;
diff --git a/src/backend/parser/parse_target.c b/src/backend/parser/parse_target.c
index 4702f5f79e..4cca97ff9c 100644
--- a/src/backend/parser/parse_target.c
+++ b/src/backend/parser/parse_target.c
@@ -1899,6 +1899,24 @@ FigureColnameInternal(Node *node, char **name)
 				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:
diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c
index b815a9441d..e93d66a7ec 100644
--- a/src/backend/utils/adt/ruleutils.c
+++ b/src/backend/utils/adt/ruleutils.c
@@ -9282,6 +9282,24 @@ get_rule_expr(Node *node, deparse_context *context,
 						appendStringInfo(buf, "LOCALTIMESTAMP(%d)",
 										 svf->typmod);
 						break;
+					case SVFOP_CURRENT_ROLE:
+						appendStringInfoString(buf, "CURRENT_ROLE");
+						break;
+					case SVFOP_CURRENT_USER:
+						appendStringInfoString(buf, "CURRENT_USER");
+						break;
+					case SVFOP_USER:
+						appendStringInfoString(buf, "USER");
+						break;
+					case SVFOP_SESSION_USER:
+						appendStringInfoString(buf, "SESSION_USER");
+						break;
+					case SVFOP_CURRENT_CATALOG:
+						appendStringInfoString(buf, "CURRENT_CATALOG");
+						break;
+					case SVFOP_CURRENT_SCHEMA:
+						appendStringInfoString(buf, "CURRENT_SCHEMA");
+						break;
 				}
 			}
 			break;
@@ -10488,24 +10506,6 @@ get_func_sql_syntax(FuncExpr *expr, deparse_context *context)
 			appendStringInfoChar(buf, ')');
 			return true;
 
-		case F_CURRENT_CATALOG:
-			appendStringInfoString(buf, "CURRENT_CATALOG");
-			return true;
-		case F_CURRENT_ROLE:
-			appendStringInfoString(buf, "CURRENT_ROLE");
-			return true;
-		case F_CURRENT_SCHEMA:
-			appendStringInfoString(buf, "CURRENT_SCHEMA");
-			return true;
-		case F_CURRENT_USER:
-			appendStringInfoString(buf, "CURRENT_USER");
-			return true;
-		case F_USER:
-			appendStringInfoString(buf, "USER");
-			return true;
-		case F_SESSION_USER:
-			appendStringInfoString(buf, "SESSION_USER");
-			return true;
 		case F_SYSTEM_USER:
 			appendStringInfoString(buf, "SYSTEM_USER");
 			return true;
-- 
2.40.1

