功能概述
IvorySQL提供兼容Oracle内置函数 ,用于返回当前会话的相关信息。
这是一个遗留函数,建议使用 USERENV('parameter')SYS_CONTEXT 函数及其内置的 USERENV 命名空间来获取当前功能。
1. 实现原理
USERENV 通过Bison规则解析函数调用,检查参数合法性并映射到对应的具体SQL函数。
解析规则在 ora_gram.y 中实现,逻辑如下:
USERENV '(' Sconst ')'
{
char *normalized_param = downcase_identifier($3, strlen($3), true, true);
#define CHECK_AND_CALL(param, func_name) \
if (strcmp(normalized_param, param) == 0) \
$$ = (Node *) makeFuncCall(OracleSystemFuncName(func_name), NIL, COERCE_EXPLICIT_CALL, @1);
CHECK_AND_CALL("client_info", "get_client_info")
else CHECK_AND_CALL("entryid", "get_entryid")
else CHECK_AND_CALL("terminal", "get_terminal")
else CHECK_AND_CALL("isdba", "get_isdba")
else CHECK_AND_CALL("lang", "get_lang")
else CHECK_AND_CALL("language", "get_language")
else CHECK_AND_CALL("sessionid", "get_sessionid")
else CHECK_AND_CALL("sid", "get_sid")
else
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("invalid USERENV parameter: \"%s\".", $3)));
#undef CHECK_AND_CALL
}
具体功能则是在 builtin_functions—1.0.sql 中实现。例如:
CREATE OR REPLACE FUNCTION sys.get_language()
RETURNS varchar2
AS $$
SELECT (regexp_split_to_array(current_setting('lc_monetary'), '\.'))[1]||'.'||pg_client_encoding();
$$ LANGUAGE sql STRICT;