Switch SQLValueFunction on "name" to use COERCE_SQL_SYNTAX
authorMichael Paquier <michael@paquier.xyz>
Sun, 20 Nov 2022 01:58:28 +0000 (10:58 +0900)
committerMichael Paquier <michael@paquier.xyz>
Sun, 20 Nov 2022 01:58:28 +0000 (10:58 +0900)
This commit changes six SQL keywords to use COERCE_SQL_SYNTAX rather
than relying on SQLValueFunction:
- CURRENT_ROLE
- CURRENT_USER
- USER
- SESSION_USER
- CURRENT_CATALOG
- CURRENT_SCHEMA

Among the six, "user", "current_role" and "current_catalog" require
specific SQL functions to allow ruleutils.c to map them to the SQL
keywords these require when using COERCE_SQL_SYNTAX.  Having
pg_proc.proname match with the keyword ensures that the compatibility
remains the same when projecting any of these keywords in a FROM clause
to an attribute name when an alias is not specified.  This is covered by
the tests added in 2e0d80c, making sure that a correct mapping happens
with each SQL keyword.  The three others (current_schema, session_user
and current_user) already have pg_proc entries for this job, so this
brings more consistency between the way such keywords are treated in the
parser, the executor and ruleutils.c.

SQLValueFunction is reduced to half its contents after this change,
simplifying its logic a bit as there is no need to enforce a C collation
anymore for the entries returning a name as a result.  I have made a few
performance tests, with a million-ish calls to these keywords without
seeing a difference in run-time or in perf profiles
(ExecEvalSQLValueFunction() is removed from the profiles).  The
remaining SQLValueFunctions are now related to timestamps and dates.

Bump catalog version.

Reviewed-by: Corey Huinker
Discussion: https://postgr.es/m/YzaG3MoryCguUOym@paquier.xyz

src/backend/executor/execExprInterp.c
src/backend/nodes/nodeFuncs.c
src/backend/parser/gram.y
src/backend/parser/parse_expr.c
src/backend/parser/parse_target.c
src/backend/utils/adt/ruleutils.c
src/include/catalog/catversion.h
src/include/catalog/pg_proc.dat
src/include/nodes/primnodes.h

index 9b9bbf00a9727250ee510d4ff07e57e01ac9ef30..6ebf5c287ea455c7b148888652b07312270543f2 100644 (file)
@@ -2495,15 +2495,10 @@ 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:
@@ -2525,28 +2520,6 @@ 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;
    }
 }
 
index 0a7b22f97e7bb94565e6c1a93aadbd32c8d292e9..2585a3175c958a298fc8ceb90aeac6850814c81c 100644 (file)
@@ -917,11 +917,8 @@ exprCollation(const Node *expr)
            coll = ((const MinMaxExpr *) expr)->minmaxcollid;
            break;
        case T_SQLValueFunction:
-           /* Returns either NAME or a non-collatable type */
-           if (((const SQLValueFunction *) expr)->type == NAMEOID)
-               coll = C_COLLATION_OID;
-           else
-               coll = InvalidOid;
+           /* Returns a non-collatable type */
+           coll = InvalidOid;
            break;
        case T_XmlExpr:
 
@@ -1144,9 +1141,7 @@ exprSetCollation(Node *expr, Oid collation)
            ((MinMaxExpr *) expr)->minmaxcollid = collation;
            break;
        case T_SQLValueFunction:
-           Assert((((SQLValueFunction *) expr)->type == NAMEOID) ?
-                  (collation == C_COLLATION_OID) :
-                  (collation == InvalidOid));
+           Assert(collation == InvalidOid);
            break;
        case T_XmlExpr:
            Assert((((XmlExpr *) expr)->op == IS_XMLSERIALIZE) ?
index 2a910ded15e5c6f3b7b9235dae5802f92e1d4b81..9054742427c5c1c10f132a39328d1e3901a58daf 100644 (file)
@@ -15231,15 +15231,24 @@ func_expr_common_subexpr:
                }
            | CURRENT_ROLE
                {
-                   $$ = makeSQLValueFunction(SVFOP_CURRENT_ROLE, -1, @1);
+                   $$ = (Node *) makeFuncCall(SystemFuncName("current_role"),
+                                              NIL,
+                                              COERCE_SQL_SYNTAX,
+                                              @1);
                }
            | CURRENT_USER
                {
-                   $$ = makeSQLValueFunction(SVFOP_CURRENT_USER, -1, @1);
+                   $$ = (Node *) makeFuncCall(SystemFuncName("current_user"),
+                                              NIL,
+                                              COERCE_SQL_SYNTAX,
+                                              @1);
                }
            | SESSION_USER
                {
-                   $$ = makeSQLValueFunction(SVFOP_SESSION_USER, -1, @1);
+                   $$ = (Node *) makeFuncCall(SystemFuncName("session_user"),
+                                              NIL,
+                                              COERCE_SQL_SYNTAX,
+                                              @1);
                }
            | SYSTEM_USER
                {
@@ -15250,15 +15259,24 @@ func_expr_common_subexpr:
                }
            | USER
                {
-                   $$ = makeSQLValueFunction(SVFOP_USER, -1, @1);
+                   $$ = (Node *) makeFuncCall(SystemFuncName("user"),
+                                              NIL,
+                                              COERCE_SQL_SYNTAX,
+                                              @1);
                }
            | CURRENT_CATALOG
                {
-                   $$ = makeSQLValueFunction(SVFOP_CURRENT_CATALOG, -1, @1);
+                   $$ = (Node *) makeFuncCall(SystemFuncName("current_catalog"),
+                                              NIL,
+                                              COERCE_SQL_SYNTAX,
+                                              @1);
                }
            | CURRENT_SCHEMA
                {
-                   $$ = makeSQLValueFunction(SVFOP_CURRENT_SCHEMA, -1, @1);
+                   $$ = (Node *) makeFuncCall(SystemFuncName("current_schema"),
+                                              NIL,
+                                              COERCE_SQL_SYNTAX,
+                                              @1);
                }
            | CAST '(' a_expr AS Typename ')'
                { $$ = makeTypeCast($3, $5, @1); }
index e5fc708c8a59f2e4fdb972382c5dc056e07a79f9..0fdbf82f3a9d056d700779e36c1675b492fd87aa 100644 (file)
@@ -2231,14 +2231,6 @@ 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;
index bd8057bc3e747d52cb213b8c7bc6a3cd6cef43a2..f54591a9874f90574688c39dc422e83641552436 100644 (file)
@@ -1895,24 +1895,6 @@ 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:
index b4c040758874190eb6ea5419ce81716a4199aec2..129f3333fb921df7beeb5bd5ad7fbc2572ed92e5 100644 (file)
@@ -9169,24 +9169,6 @@ 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;
@@ -10288,6 +10270,24 @@ 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;
index 775e3a5db5f4a4d9b91015b2bafc0ee2eb80a797..ac2043f6cc04d730c34d5d4dda76ed0c62623626 100644 (file)
@@ -57,6 +57,6 @@
  */
 
 /*                         yyyymmddN */
-#define CATALOG_VERSION_NO 202211181
+#define CATALOG_VERSION_NO 202211201
 
 #endif
index 9dbe9ec8017bd9399448c6638e4c41de496a98dc..fd2559442e55cb7f5633813e4287d35cfee80095 100644 (file)
 { 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' },
index f71f551782fc3017e520d3e0ecb9697960eb7414..f6dd27edcc13788fc63897a9833520a48495e509 100644 (file)
@@ -1313,13 +1313,7 @@ typedef enum SQLValueFunctionOp
    SVFOP_LOCALTIME,
    SVFOP_LOCALTIME_N,
    SVFOP_LOCALTIMESTAMP,
-   SVFOP_LOCALTIMESTAMP_N,
-   SVFOP_CURRENT_ROLE,
-   SVFOP_CURRENT_USER,
-   SVFOP_USER,
-   SVFOP_SESSION_USER,
-   SVFOP_CURRENT_CATALOG,
-   SVFOP_CURRENT_SCHEMA
+   SVFOP_LOCALTIMESTAMP_N
 } SQLValueFunctionOp;
 
 typedef struct SQLValueFunction