Switch SQLValueFunction on "name" to use COERCE_SQL_SYNTAX

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
This commit is contained in:
Michael Paquier 2022-11-20 10:58:28 +09:00
parent ed1d3132d2
commit fb32748e32
9 changed files with 56 additions and 93 deletions

View 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;
}
}

View 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) ?

View 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); }

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

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

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

View File

@ -57,6 +57,6 @@
*/
/* yyyymmddN */
#define CATALOG_VERSION_NO 202211181
#define CATALOG_VERSION_NO 202211201
#endif

View File

@ -1505,6 +1505,15 @@
{ 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' },

View 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