From 9a19c93947559140ec21b3bf96666e2fc84ab434 Mon Sep 17 00:00:00 2001 From: Oreo Yang <2167young@163.com> Date: Wed, 22 Oct 2025 15:59:56 +0800 Subject: [PATCH 1/2] add adocs for sys_context function --- CN/modules/ROOT/nav.adoc | 4 +- CN/modules/ROOT/pages/master/6.4.1.adoc | 88 ++++++++++ .../ROOT/pages/master/{6.4.adoc => 6.5.adoc} | 0 CN/modules/ROOT/pages/master/7.8.adoc | 149 +++++++++++------ EN/modules/ROOT/nav.adoc | 4 +- EN/modules/ROOT/pages/master/6.4.1.adoc | 91 +++++++++++ .../ROOT/pages/master/{6.4.adoc => 6.5.adoc} | 0 EN/modules/ROOT/pages/master/7.8.adoc | 153 ++++++++++++------ 8 files changed, 393 insertions(+), 96 deletions(-) create mode 100644 CN/modules/ROOT/pages/master/6.4.1.adoc rename CN/modules/ROOT/pages/master/{6.4.adoc => 6.5.adoc} (100%) create mode 100644 EN/modules/ROOT/pages/master/6.4.1.adoc rename EN/modules/ROOT/pages/master/{6.4.adoc => 6.5.adoc} (100%) diff --git a/CN/modules/ROOT/nav.adoc b/CN/modules/ROOT/nav.adoc index e3c8c3c6..f3762582 100644 --- a/CN/modules/ROOT/nav.adoc +++ b/CN/modules/ROOT/nav.adoc @@ -26,7 +26,9 @@ **** xref:master/6.3.2.adoc[OUT 参数] **** xref:master/6.3.4.adoc[%TYPE、%ROWTYPE] **** xref:master/6.3.5.adoc[NLS 参数] -*** xref:master/6.4.adoc[国标GB18030] +*** 内置函数 +**** xref:master/6.4.1.adoc[sys_context] +*** xref:master/6.5.adoc[国标GB18030] ** Oracle兼容功能列表 *** xref:master/7.1.adoc[1、框架设计] *** xref:master/7.2.adoc[2、GUC框架] diff --git a/CN/modules/ROOT/pages/master/6.4.1.adoc b/CN/modules/ROOT/pages/master/6.4.1.adoc new file mode 100644 index 00000000..196904ce --- /dev/null +++ b/CN/modules/ROOT/pages/master/6.4.1.adoc @@ -0,0 +1,88 @@ + +:sectnums: +:sectnumlevels: 5 + + += **功能概述** + +IvorySQL提供兼容Oracle内置函数`SYS_CONTEXT('namespace', 'parameter' [, length ])`, +返回当前时刻与给定上下文关联参数的值,可以在SQL和PLSQL语言中使用。 + +== 实现原理 + +SYS_CONTEXT的实现原理是通过动态查询系统表与postgres的内置函数,确保结果的实时性, +使用 SECURITY INVOKER 确保函数以调用者的权限执行,避免权限提升问题。 +该方法的实现逻辑如下: +```sql +CREATE OR REPLACE FUNCTION sys.sys_context(a varchar2, b varchar2) +RETURNS varchar2 AS $$ +DECLARE + res varchar2; +BEGIN + IF upper(a) = 'USERENV' THEN + CASE upper(b) + WHEN 'CURRENT_SCHEMA' THEN + SELECT current_schema() INTO res; + WHEN 'LANG' THEN + SELECT sys.get_lang() INTO res; + ... + ELSE + RAISE EXCEPTION 'invalid USERENV parameter: %', b; + END CASE; + ELSIF upper(a) = 'SYS_SESSION_ROLES' THEN + CASE upper(b) + WHEN 'LOGIN' THEN + SELECT CASE WHEN rolcanlogin = 't' THEN 'TRUE' ELSE 'FALSE' END INTO res FROM pg_roles WHERE oid = current_user::regrole::oid; +... + ELSE + RAISE EXCEPTION 'invalid SYS_SESSION_ROLES parameter: %', b; + END CASE; + ELSE + SELECT current_setting(a||'.'||b, true) INTO res; + END IF; + RETURN res; +END; +$$ LANGUAGE plisql SECURITY INVOKER; +``` +== USERENV支持的参数 +[cols="2,8"] +|==== +|*参数名称*|*返回值* +|CURRENT_SCHEMA | 当前活动默认模式的名称。在会话期间,可以通过 ALTER SESSION SET CURRENT_SCHEMA 语句更改该值。该值也可能在会话期间发生变化,以反映任何活动定义者权限对象的所有者。如果直接在视图定义的正文中使用,那么将返回在执行使用视图的游标时使用的默认模式。 +|CURRENT_SCHEMAID | 当前活动的默认模式的标识符。 +|SESSION_USER | 当前session的用户 +会话用户(登录用户)的名称。在数据库会话期间,随着 Real Application Security 会话的附加或分离,该名称可能会发生变化。对于企业用户,返回模式。对于其他用户,返回数据库用户名。如果数据库会话当前附加了 Real Application Security 会话,则返回用户 XS$NULL。 +|SESSION_USERID | 当前session的用户ID。 +|PROXY_USER | 代表 SESSION_USER 打开当前会话的数据库用户名称。 +|PROXY_USERID | 代表 SESSION_USER 打开当前会话的数据库用户的标识符。 +|CURRENT_USER | 当前会话中执行操作的用户。 +|CURRENT_USERID | 当前会话中执行操作的用户标识符。 +|CURRENT_EDITION_NAME | 当前版本的名字。 +|CLIENT_PROGRAM_NAME | 客户端程序的名称。 +|==== +[cols="2,8"] +|==== +|*参数名称*|*返回值* +|IP_ADDRESS | 客户端的IP地址。 +|HOST | 客户端主机的名称。 +|ISDBA | 如果当前用户是数据库管理员,则返回TRUE。 +|LANG | 语言的缩写名称,比现有的 “LANGUAGE ”参数更简短。 +|LANGUAGE | 当前会话的使用的语言和地区,以及数据库字符集,格式为:language_territory.characterset。 +|NLS_DATE_FORMAT | 当前session的日期格式。 +|PLATFORM_SLASH | 在用户的平台上用作文件路径分隔符的斜线字符(Unix或Linux是’/’,Windows是’\’)。 +|DB_NAME | 当前连接的CDB的名称。 +|SID | 当前会话的系统标识符。 +|SESSIONID | 审计会话标识符。不能在分布式 SQL 语句中使用此属性。 +|CLIENT_INFO | 返回最多 64 字节的用户会话信息,应用程序可使用 DBMS_APPLICATION_INFO 包存储这些信息。 +|ENTRYID | 当前审计条目编号。审计条目编号序列在细粒度审计记录和常规审计记录之间共享。不能在分布式 SQL 语句中使用此属性。只有通过标准或细粒度审计的审计处理程序才能看到正确的审计条目标识符。 +|TERMINAL | 当前会话客户端的操作系统标识符。在分布式 SQL 语句中,该属性返回本地会话的标识符。在分布式环境中,仅支持远程 SELECT 语句,不支持远程 INSERT、UPDATE 或 DELETE 操作。(此参数的返回长度可能因操作系统而异)。 +|==== +== SYS_SESSION_ROLES支持的参数 +[cols="2,8"] +|==== +|*参数名称*|*返回值* +|DBA | 如果当前用户是数据库管理员,则返回TRUE。 +|LOGIN | 如果当前用户是登录角色,则返回TRUE。 +|CREATEROLE | 如果当前session的用户具有创建角色的权限,则返回TRUE。 +|CREATEDB | 如果当前session的用户具有创建数据库的权限,则返回TRUE。 +|==== \ No newline at end of file diff --git a/CN/modules/ROOT/pages/master/6.4.adoc b/CN/modules/ROOT/pages/master/6.5.adoc similarity index 100% rename from CN/modules/ROOT/pages/master/6.4.adoc rename to CN/modules/ROOT/pages/master/6.5.adoc diff --git a/CN/modules/ROOT/pages/master/7.8.adoc b/CN/modules/ROOT/pages/master/7.8.adoc index e094f5fb..824357fd 100644 --- a/CN/modules/ROOT/pages/master/7.8.adoc +++ b/CN/modules/ROOT/pages/master/7.8.adoc @@ -74,11 +74,13 @@ |to_single_byte |compose |decompose +|sys_context |==== == 内置函数说明 -1、兼容sysdate函数,功能:查看对应的日期与时间,测试用例如下: +=== `sysdate` 函数 +功能:查看对应的日期与时间,测试用例如下: 查询当前系统的日期: ``` @@ -99,7 +101,8 @@ select sysdate()-1 from dual; (1 row) ``` -2、兼容systimestamp函数,功能:返回本机数据库上当前系统日期和时间(包括微秒和时区),测试用例如下: +=== `systimestamp` 函数 +功能:返回本机数据库上当前系统日期和时间(包括微秒和时区),测试用例如下: 查询当前日期的日期和时间: ``` @@ -110,7 +113,8 @@ select systimestamp() from dual; (1 row) ``` -3、兼容add_months函数,功能:函数将一个月数(n)添加一个日期,并返回相隔n月的同一天,支持参数:date, number;测试用例如下: +=== `add_months` 函数 +功能:函数将一个月数(n)添加一个日期,并返回相隔n月的同一天,支持参数:date, number;测试用例如下: 查询当前日期(七月六日)的下个月的同一天: ``` @@ -131,7 +135,8 @@ select add_months(sysdate(),-1) from dual; (1 row) ``` -4、兼容last_day函数,功能:返回指定日期所在月份的最后一天,支持参数:date,测试用例如下: +=== `last_day` 函数 +功能:返回指定日期所在月份的最后一天,支持参数:date,测试用例如下: 查询当天所在月份的最后一天: ``` @@ -152,7 +157,8 @@ select last_day(to_date('2019-09-01'))from dual; (1 row) ``` -5、兼容next_day函数,功能:返回指定日期的下一个日期。支持参数:date, integer /date ,text, 说明:当函数中第二个参数传的星期数比现有星期数小时,会返回下一个星期的日期;当函数中第二个参数所传的日期比现有星期数大,会返回本周相应星期日期。测试用例如下: +=== `next_day` 函数 +功能:返回指定日期的下一个日期。支持参数:date, integer /date ,text, 说明:当函数中第二个参数传的星期数比现有星期数小时,会返回下一个星期的日期;当函数中第二个参数所传的日期比现有星期数大,会返回本周相应星期日期。测试用例如下: 查询当前日期的下一天: ``` @@ -173,7 +179,8 @@ select next_day(sysdate(),'FRIDAY') from dual; (1 row) ``` -6、兼容months_between函数,功能:返回日期类型的date1和date2之间相差的月份,支持参数:date,date,说明:如果date1晚于date2,返回正数;如果date1早于date2返回负数;如果date1和date2是某月里的同一天,返回结果为整数;如果不是同一天,会在每月31天的基础上返回带有小数部分的结果。测试用例如下: +=== `months_between` 函数 +功能:返回日期类型的date1和date2之间相差的月份,支持参数:date,date,说明:如果date1晚于date2,返回正数;如果date1早于date2返回负数;如果date1和date2是某月里的同一天,返回结果为整数;如果不是同一天,会在每月31天的基础上返回带有小数部分的结果。测试用例如下: 查询不同月份同一天之间相差的月份: ``` @@ -194,7 +201,8 @@ select months_between(to_date('2023-07-06'),to_date('2023-08-05')) from dual; (1 row) ``` -7、兼容current_date函数,功能:返回当前时区的当前日期,测试用例如下: +=== `current_date` 函数 +功能:返回当前时区的当前日期,测试用例如下: 查询当前时区的当前日期: ``` @@ -205,7 +213,8 @@ select current_date from dual; (1 row) ``` -8、兼容current_timestamp函数,功能:返回当前时区的当前日期与当前时间,包含当前时区信息。支持参数:integer, 说明:返回的时间可调整精度。测试用例如下: +=== `current_timestamp` 函数 +功能:返回当前时区的当前日期与当前时间,包含当前时区信息。支持参数:integer, 说明:返回的时间可调整精度。测试用例如下: 查询当前时区的当前日期与时间: ``` @@ -226,7 +235,8 @@ select current_timestamp(3) from dual; (1 row) ``` -9、兼容new_time函数,功能:返回某个时间在某时区所对应的在另一个时区的日期,支持参数:date, text, text ,测试用例如下: +=== `new_time` 函数 +功能:返回某个时间在某时区所对应的在另一个时区的日期,支持参数:date, text, text ,测试用例如下: 返回当前日期在另一个时区对应的日期: ``` @@ -237,7 +247,8 @@ select sysdate() bj_time,new_time(sysdate(),'PDT','GMT')los_angles from dual; (1 row) ``` -10、兼容tz_offset函数,功能:返回给定时区与标准时区的偏移量,支持参数:text,测试用例如下: +=== `tz_offset` 函数 +功能:返回给定时区与标准时区的偏移量,支持参数:text,测试用例如下: 返回给定时区与标准时区偏移量: ``` @@ -248,7 +259,8 @@ select tz_offset('US/Eastern') from dual; (1 row) ``` -11、兼容trunc函数,功能:可以截取日期,得到想要的数值,如年,月,日,时,分,支持参数:date/date,text,测试用例如下: +=== `trunc` 函数 +功能:可以截取日期,得到想要的数值,如年,月,日,时,分,支持参数:date/date,text,测试用例如下: 截取当前日期: ``` @@ -279,7 +291,8 @@ select trunc(sysdate(),'mm') from dual; (1 row) ``` -12、兼容instr函数,功能:字符串查找函数,用于判断源字符串中是否包含目标字符串,并返回匹配位置。支持参数形式如下: +=== `instr` 函数 +功能:字符串查找函数,用于判断源字符串中是否包含目标字符串,并返回匹配位置。支持参数形式如下: * `instr(string, str)` * `instr(string, str, start_position, nth_appearance)` @@ -340,7 +353,8 @@ select * from tableName where instr(name,'helloworld')>0; * 根据 `position` 的正负确定正向或反向搜索,并设置循环的起止位置和步长。 * 在循环中逐字节移动并比较,与模式字符串匹配成功即返回相应位置。 -13、兼容instrb函数,功能:字符串查找函数,返回字符串的位置,支持参数: varchar2, text, number DEFAULT 1, number DEFAULT 1,以下为测试用例: +=== `instrb` 函数 +功能:字符串查找函数,返回字符串的位置,支持参数: varchar2, text, number DEFAULT 1, number DEFAULT 1,以下为测试用例: 返回CORPORATE FLOOR中默认第一次出现OR时字符串的位置: ``` @@ -361,7 +375,8 @@ SELECT INSTRB('CORPORATE FLOOR','OR',5,2) "Instring in bytes" FROM DUAL; (1 row) ``` -14、兼容substr函数,功能:截取字符串函数,以字符为单位截取,支持参数:text, integer, 测试用例如下: +=== `substr` 函数 +功能:截取字符串函数,以字符为单位截取,支持参数:text, integer, 测试用例如下: 截取’今天天气很好’中从第五个字符开始,往后的字符串: ``` @@ -373,7 +388,8 @@ SELECT SUBSTR('今天天气很好',5) "Substring with bytes" FROM DUAL; (1 row) ``` -15、兼容substrb函数,功能:截取字符串函数,以字节为单位截取,支持参数:varchar2, number/varchar2, number,number,测试用例如下: +=== `substrb` 函数 +功能:截取字符串函数,以字节为单位截取,支持参数:varchar2, number/varchar2, number,number,测试用例如下: 截取’今天天气很好’中从第五个字节开始,往后的字符串: ``` @@ -394,7 +410,8 @@ SELECT SUBSTRB('今天天气很好',5,8) "Substring with bytes" FROM DUAL; (1 row) ``` -16、兼容trim函数,功能:去除指定字符串的左右空格或对应数据,支持参数:varchar2 /varchar2,varchar2,测试用例如下: +=== `trim` 函数 +功能:去除指定字符串的左右空格或对应数据,支持参数:varchar2 /varchar2,varchar2,测试用例如下: 去除' aaa bbb ccc '的左右空格: ``` @@ -415,7 +432,8 @@ select trim('aaa bbb ccc','aaa')trim from dual; (1 row) ``` -17、兼容ltrim函数,功能:去除指定字符串的左侧空格或对应数据,支持参数:varchar2 /varchar2,varchar2,测试用例如下: +=== `ltrim` 函数 +功能:去除指定字符串的左侧空格或对应数据,支持参数:varchar2 /varchar2,varchar2,测试用例如下: 去除' abcdefg '的左侧空格: ``` @@ -436,7 +454,8 @@ select ltrim('abcdefg','fegab')ltrim from dual; (1 row) ``` -18、兼容rtrim函数,功能:去除指定字符串的右侧空格,测试用例如下: +=== `rtrim` 函数 +功能:去除指定字符串的右侧空格,测试用例如下: 去除' abcdefg '的右侧空格: ``` @@ -457,7 +476,8 @@ select rtrim('abcdefg','fegab')rtrim from dual; (1 row) ``` -19、兼容length函数,功能:求取指定字符串字符的长度,支持参数:char/integer/varchar2测试用例如下: +=== `length` 函数 +功能:求取指定字符串字符的长度,支持参数:char/integer/varchar2测试用例如下: 查询223的字符长度: ``` @@ -488,7 +508,8 @@ select length('ivorysql数据库') from dual; (1 row) ``` -20、兼容lengthb功能:求取指定字符串字节的长度,支持参数:char/bytea/varchar2测试用例如下: +=== `lengthb` 函数 +功能:求取指定字符串字节的长度,支持参数:char/bytea/varchar2测试用例如下: 查询'ivorysql'的字节长度: ``` @@ -519,7 +540,8 @@ select lengthb('ivorysql数据库'::varchar2) from dual; (1 row) ``` -21、兼容replace函数,功能:替换指定字符串中的字符或删除字符,支持参数:text, text, text/varchar2, varchar2, varchar2 DEFAULT NULL::varchar2, 测试用例如下: +=== `replace` 函数 +功能:替换指定字符串中的字符或删除字符,支持参数:text, text, text/varchar2, varchar2, varchar2 DEFAULT NULL::varchar2, 测试用例如下: 替换'jack and jue'中的'j'为'bl': ``` @@ -540,7 +562,8 @@ select replace('jack and jue','j') from dual; (1 row) ``` -22、兼容regexp_replace函数,此函数为replace函数的扩展。功能:用于通过正则表达式来进行匹配替换。支持参数:text, text, text /text, text, text, integer/varchar2, varchar2/varchar2, varchar2 varchar2, 测试用例如下: +=== `regexp_replace` 函数 +此函数为`replace` 函数的扩展。功能:用于通过正则表达式来进行匹配替换。支持参数:text, text, text /text, text, text, integer/varchar2, varchar2/varchar2, varchar2 varchar2, 测试用例如下: 将匹配到的数字替换为*#: ``` @@ -580,7 +603,8 @@ select regexp_replace('01234abcd56789','012','xxx')from dual; (1 row) ``` -23、兼容regexp_substr函数,功能:拾取合符正则表达式描述的字符子串,支持参数:text, text,integer /text, text, integer, integer/ text, text, integer, integer, text /varchar2 ,varchar2,测试用例如下: +=== `regexp_substr` 函数 +功能:拾取合符正则表达式描述的字符子串,支持参数:text, text,integer /text, text, integer, integer/ text, text, integer, integer, text /varchar2 ,varchar2,测试用例如下: 查询'012ab34'中从第一个数开始的012字串: ``` @@ -630,7 +654,8 @@ select regexp_substr('数据库', '数据') from dual; (1 row) ``` -24、兼容regexp_instr函数,功能:用于标定符合正则表达式的字符子串的开始位置,支持参数:text, text,integer /text, text, integer, integer/ text, text, integer, integer, text/text, text, integer, integer, text, integer/ varchar2, varchar2,测试用例如下: +=== `regexp_instr` 函数 +功能:用于标定符合正则表达式的字符子串的开始位置,支持参数:text, text,integer /text, text, integer, integer/ text, text, integer, integer, text/text, text, integer, integer, text, integer/ varchar2, varchar2,测试用例如下: 查询'abcaBcabc'中从第一个字符开始,出现abc子串的位置: ``` @@ -681,7 +706,8 @@ SELECT regexp_instr('数据库', '库'); (1 row) ``` -25、兼容regexp_like函数,功能:与like类似,用于模糊查询。支持参数:varchar2, varchar2 /varchar2, varchar2 varchar2, +=== `regexp_like` 函数 +功能:与like类似,用于模糊查询。支持参数:varchar2, varchar2 /varchar2, varchar2 varchar2, 首先创建一个regexp_like表用于测试用例查询: ``` @@ -731,7 +757,8 @@ select * from t_regexp_like where regexp_like(value,'ABC','i'); ``` -26、兼容to_number函数,功能:是将一些处理过的按一定格式编排过的字符串变回数值型的格式,支持参数:text/text,text测试用例如下: +=== `to_number` 函数 +功能:是将一些处理过的按一定格式编排过的字符串变回数值型的格式,支持参数:text/text,text测试用例如下: 将字符串'-34,338,492'转换为数值型格式: ``` @@ -753,7 +780,8 @@ SELECT to_number('5.01-', '9.99S'); (1 row) ``` -27、兼容to_char函数,功能:将数字或日期转换为字符类型,支持参数:date/date,text/timestamp/timestamp,text测试用例如下: +=== `to_char` 函数 +功能:将数字或日期转换为字符类型,支持参数:date/date,text/timestamp/timestamp,text测试用例如下: 将当前系统日期转换为字符格式: ``` @@ -793,7 +821,8 @@ SELECT to_char(sysdate()::timestamp,'MM-YYYY-DD'); (1 row) ``` -28、兼容to_date函数,功能:将字符类型转换为日期类型,支持参数:text/text,text测试用例如下: +=== `to_date` 函数 +功能:将字符类型转换为日期类型,支持参数:text/text,text测试用例如下: 将'2023/07/06'转换为日期类型: ``` @@ -814,7 +843,8 @@ SELECT to_date('-44,0201','YYYY-MM-DD'); (1 row) ``` -29、兼容to_timestamp函数,功能:可以存储年、月、日、小时、分钟、秒,同时还可以存储秒的小数部分。支持参数:text/text,text测试用例如下: +=== `to_timestamp` 函数 +功能:可以存储年、月、日、小时、分钟、秒,同时还可以存储秒的小数部分。支持参数:text/text,text测试用例如下: 查询'2018-11-02 12:34:56.025'以日期形式输出: ``` @@ -835,7 +865,8 @@ SELECT to_timestamp('2011,12,18 11:38 ', 'YYYY-MM-DD HH24:MI:SS'); (1 row) ``` -30、兼容to_timestamp_tz函数,功能:根据时间查询,时间字符串有T,Z并有毫秒,时区。测试用例如下: +=== `to_timestamp_tz` 函数 +功能:根据时间查询,时间字符串有T,Z并有毫秒,时区。测试用例如下: 查询'2016-10-9 14:10:10.123000'以日期形式输出: ``` @@ -856,7 +887,8 @@ SELECT to_timestamp('2011,12,18 11:38 ', 'YYYY-MM-DD HH24:MI:SS'); (1 row) ``` -31、兼容to_yminterval函数,功能:将一个字符串类型转化为年和月的时间差类型,支持参数:text, 测试用例如下: +=== `to_yminterval` 函数 +功能:将一个字符串类型转化为年和月的时间差类型,支持参数:text, 测试用例如下: 查询'20110101'以后两个年零八个月后的日期: ``` @@ -867,7 +899,8 @@ select to_date('20110101','yyyymmdd')+to_yminterval('02-08') from dual; (1 row) ``` -32、兼容to_dsinterval函数,功能:将一个日期加上一定的小时或者天数变成另外一个日期,支持参数:text,测试用例如下: +=== `to_dsinterval` 函数 +功能:将一个日期加上一定的小时或者天数变成另外一个日期,支持参数:text,测试用例如下: 查询当前系统时间加上9个半小时后的日期(当前为2023-07-06,18:00): ``` @@ -878,7 +911,8 @@ select sysdate()+to_dsinterval('0 09:30:00')as newdate from dual; (1 row) ``` -33、兼容numtodsinterval函数,功能:将数字转换成时间间隔类型的数据。支持参数:double precision, text测试用例如下: +=== `numtodsinterval` 函数 +功能:将数字转换成时间间隔类型的数据。支持参数:double precision, text测试用例如下: 转换100.00个小时为时间间隔类型数据: ``` @@ -899,7 +933,8 @@ SELECT NUMTODSINTERVAL(100, 'minute'); (1 row) ``` -34、兼容numtoyminterval函数,功能:将数字转换成日期间隔类型的数据。 +=== `numtoyminterval` 函数 +功能:将数字转换成日期间隔类型的数据。 支持参数:double precision,text,测试用例如下: 转换1.00,year为日期间隔: @@ -921,7 +956,8 @@ SELECT NUMTOYMINTERVAL(1,'month'); (1 row) ``` -35、兼容localtimestamp函数,功能:返回会话中的日期和时间,支持参数:integer, 函数中增加参数为精度,测试用例如下: +=== `localtimestamp` 函数 +功能:返回会话中的日期和时间,支持参数:integer, 函数中增加参数为精度,测试用例如下: 返回当前会话中的日期和时间: ``` @@ -942,7 +978,8 @@ select localtimestamp(1) from dual; (1 row) ``` -36、兼容from_tz函数,功能:将时间从一个时区转换为另一个时区,支持参数;timestamp, text ,测试用例如下: +=== `from_tz` 函数 +功能:将时间从一个时区转换为另一个时区,支持参数;timestamp, text ,测试用例如下: 将'2000-03-28 08:00:00', '3:00'转换为当前时区: ``` @@ -953,7 +990,8 @@ SELECT FROM_TZ(TIMESTAMP '2000-03-28 08:00:00', '3:00') FROM DUAL; (1 row) ``` -37、兼容sys_extract_utc函数,功能:将一个timestamptz转换为UTC时区时间。支持参数:timestamp with time zone 测试用例如下: +=== `sys_extract_utc` 函数 +功能:将一个timestamptz转换为UTC时区时间。支持参数:timestamp with time zone 测试用例如下: 查询转换timestamp '2000-03-28 11:30:00.00 -8:00'为UTC时区后的时间: ``` @@ -964,7 +1002,8 @@ select sys_extract_utc(timestamp '2000-03-28 11:30:00.00 -8:00') from dual; (1 row) ``` -38、兼容sessiontimezone函数,功能:查看时区详细信息,测试用例如下: +=== `sessiontimezone` 函数 +功能:查看时区详细信息,测试用例如下: 查看当前时区的详细信息: ``` @@ -987,7 +1026,8 @@ select sessiontimezone() from dual; (1 row) ``` -39、兼容hextoraw函数,功能:将字符串表示的二进制数值转换为一个raw数值。支持参数:text,测试用例如下: +=== `hextoraw` 函数 +功能:将字符串表示的二进制数值转换为一个raw数值。支持参数:text,测试用例如下: 将字符串'abcdef'转换为raw数值: ``` @@ -998,7 +1038,8 @@ select hextoraw('abcdef')from dual; (1 row) ``` -40、兼容uid函数,功能:获取数据库的实例名。测试用例如下: +=== `uid` 函数 +功能:获取数据库的实例名。测试用例如下: 获取当前数据库的实例名: ``` @@ -1009,7 +1050,8 @@ select uid() from dual; (1 row) ``` -41、兼容USERENV函数,功能:返回当前用户环境的信息,测试用例如下: +=== `USERENV` 函数 +功能:返回当前用户环境的信息,测试用例如下: 查看当前用户是否是dba,如果是返回ture: ``` @@ -1030,7 +1072,8 @@ select userenv('sessionid')from dual; (1 row) ``` -42、兼容ASCIISTR函数,功能:传入字符串,返回对应的ASCII字符,测试用例如下: +=== `ASCIISTR` 函数 +功能:传入字符串,返回对应的ASCII字符,测试用例如下: 只有ASCII字符: ``` select asciistr('Hello, World!') from dual; @@ -1057,7 +1100,8 @@ select userenv('sessionid')from dual; (1 row) ``` -43、兼容TO_MULTI_BYTE函数, 功能:将字符串中的半角字符转换为全角字符: +=== `TO_MULTI_BYTE` 函数 +功能:将字符串中的半角字符转换为全角字符: 输入半角字符,转换为全角字符: ``` select to_multi_byte('1.2'::text) ; @@ -1066,7 +1110,8 @@ select to_multi_byte('1.2'::text) ; 1.2 ``` -44、兼容TO_SINGLE_BYTE函数, 功能:将字符串中的半角字符转换为全角字符 +=== `TO_SINGLE_BYTE` 函数 +功能:将字符串中的半角字符转换为全角字符 输入全角字符,转换为半角字符: ``` select to_single_byte('1.2'); @@ -1075,7 +1120,8 @@ select to_single_byte('1.2'); 1.2 ``` -45、兼容COMPOSE函数,功能:将基本字符和组合标记组合一个复合Unicode字符: +=== `COMPOSE` 函数 +功能:将基本字符和组合标记组合一个复合Unicode字符: 输入基本字符a和组合标记768, 返回法语à ``` select compose('a'||chr(768)) from dual; @@ -1086,11 +1132,22 @@ select compose('a'||chr(768)) from dual; ``` -46、兼容DECOMPOSE函数,功能:将复合Unicode字符(如带有重音或特殊符号的字符)分解为其基本字符和组合标记 +=== `DECOMPOSE` 函数 +功能:将复合Unicode字符(如带有重音或特殊符号的字符)分解为其基本字符和组合标记 输入法语é,返回基本字符e和组合标记301: ``` select asciistr(decompose('é')) from dual; asciistr ---------- e\0301 +``` +=== `SYS_CONTEXT` 函数 +功能:返回当前时刻与给定上下文关联的参数的值,可以在SQL和PLSQL语言中使用。 +``` +ivorysql=# select sys_context('USERENV','DB_NAME'); + sys_context +------------- + ivorysql +(1 row) + ``` \ No newline at end of file diff --git a/EN/modules/ROOT/nav.adoc b/EN/modules/ROOT/nav.adoc index 3d42ed18..d12d4930 100644 --- a/EN/modules/ROOT/nav.adoc +++ b/EN/modules/ROOT/nav.adoc @@ -25,7 +25,9 @@ *** xref:master/6.3.2.adoc[OUT Parameter] *** xref:master/6.3.4.adoc[%Type & %Rowtype] *** xref:master/6.3.5.adoc[NLS Parameters] -** xref:master/6.4.adoc[GB18030 Character Set] +** Built-in Functions +*** xref:master/6.4.1.adoc[sys_context] +** xref:master/6.5.adoc[GB18030 Character Set] * List of Oracle compatible features ** xref:master/7.1.adoc[1、Ivorysql frame design] ** xref:master/7.2.adoc[2、GUC Framework] diff --git a/EN/modules/ROOT/pages/master/6.4.1.adoc b/EN/modules/ROOT/pages/master/6.4.1.adoc new file mode 100644 index 00000000..43269f97 --- /dev/null +++ b/EN/modules/ROOT/pages/master/6.4.1.adoc @@ -0,0 +1,91 @@ +:sectnums: +:sectnumlevels: 5 + += **Feature Overview** + +IvorySQL provides compatibility with the Oracle built-in function `SYS_CONTEXT('namespace', 'parameter' [, length ])`, +which returns the value of the parameter associated with the given context at the current moment. It can be used in both SQL and PL/SQL languages. + +== Implementation Principle + +The implementation principle of `SYS_CONTEXT` involves dynamically querying system tables and PostgreSQL's built-in functions to ensure real-time results. +It uses `SECURITY INVOKER` to ensure the function executes with the caller's permissions, avoiding privilege escalation issues. +The implementation logic is as follows: + +```sql +CREATE OR REPLACE FUNCTION sys.sys_context(a varchar2, b varchar2) +RETURNS varchar2 AS $$ +DECLARE + res varchar2; +BEGIN + IF upper(a) = 'USERENV' THEN + CASE upper(b) + WHEN 'CURRENT_SCHEMA' THEN + SELECT current_schema() INTO res; + WHEN 'LANG' THEN + SELECT sys.get_lang() INTO res; + ... + ELSE + RAISE EXCEPTION 'invalid USERENV parameter: %', b; + END CASE; + ELSIF upper(a) = 'SYS_SESSION_ROLES' THEN + CASE upper(b) + WHEN 'LOGIN' THEN + SELECT CASE WHEN rolcanlogin = 't' THEN 'TRUE' ELSE 'FALSE' END INTO res FROM pg_roles WHERE oid = current_user::regrole::oid; +... + ELSE + RAISE EXCEPTION 'invalid SYS_SESSION_ROLES parameter: %', b; + END CASE; + ELSE + SELECT current_setting(a||'.'||b, true) INTO res; + END IF; + RETURN res; +END; +$$ LANGUAGE plisql SECURITY INVOKER; +``` +== Parameters Supported by USERENV + +[cols="3,7"] +|==== +|Parameter Name|Return Value +|CURRENT_SCHEMA | The name of the currently active default schema. This value may change during the duration of a session through use of an ALTER SESSION SET CURRENT_SCHEMA statement. This may also change during the duration of a session to reflect the owner of any active definer's rights object. When used directly in the body of a view definition, this returns the default schema used when executing the cursor that is using the view; it does not respect views used in the cursor as being definer's rights. +|CURRENT_SCHEMAID | Identifier of the currently active default schema. +|SESSION_USER | The name of the session user (the user who logged on). This may change during the duration of a database session as Real Application Security sessions are attached or detached. For enterprise users, returns the schema. For other users, returns the database user name. If a Real Application Security session is currently attached to the database session, returns user XS$NULL. +|SESSION_USERID | The identifier of the session user (the user who logged on). +|PROXY_USER | Name of the database user who opened the current session on behalf of SESSION_USER. +|PROXY_USERID | Identifier of the database user who opened the current session on behalf of SESSION_USER. +|CURRENT_USER | The name of the database user whose privileges are currently active. This may change during the duration of a database session as Real Application Security sessions are attached or detached, or to reflect the owner of any active definer's rights object. When no definer's rights object is active, CURRENT_USER returns the same value as SESSION_USER. When used directly in the body of a view definition, this returns the user that is executing the cursor that is using the view; it does not respect views used in the cursor as being definer's rights. For enterprise users, returns schema. If a Real Application Security user is currently active, returns user XS$NULL. +|CURRENT_USERID | The identifier of the database user whose privileges are currently active. +|CURRENT_EDITION_NAME | The name of the current edition. +|CLIENT_PROGRAM_NAME | The name of the program used for the database session. +|==== + +[cols="3,7"] +|==== +|Parameter Name|Return Value +|IP_ADDRESS | The IP address of the client. +|HOST | Name of the host machine from which the client has connected. +|ISDBA | Returns TRUE if the user has been authenticated as having DBA privileges either through the operating system or through a password file. +|LANG | The abbreviated name for the language, a shorter form than the existing 'LANGUAGE' parameter. +|LANGUAGE | The language and territory currently used by your session, along with the database character set, in this form:language_territory.characterset +|NLS_DATE_FORMAT | The date format for the session. +|PLATFORM_SLASH | The slash character that is used as the file path delimiter for your platform. +|DB_NAME | Name of the database as specified in the DB_NAME initialization parameter. +|SID | +The session ID. +|SESSIONID | The auditing session identifier. You cannot use this attribute in distributed SQL statements. +|CLIENT_INFO | Returns up to 64 bytes of user session information that can be stored by an application using the DBMS_APPLICATION_INFO package. +|ENTRYID | The current audit entry number. The audit entryid sequence is shared between fine-grained audit records and regular audit records. You cannot use this attribute in distributed SQL statements. The correct auditing entry identifier can be seen only through an audit handler for standard or fine-grained audit. +|TERMINAL | The operating system identifier for the client of the current session. In distributed SQL statements, this attribute returns the identifier for your local session. In a distributed environment, this is supported only for remote SELECT statements, not for remote INSERT, UPDATE, or DELETE operations. (The return length of this parameter may vary by operating system.) +|==== + +== Parameters Supported by SYS_SESSION_ROLES + +[cols="3,7"] +|==== +|Parameter Name|Return Value +|DBA | Returns TRUE if the current user is a database administrator. +|LOGIN | Returns TRUE if the current user is a login role. +|CREATEROLE | Returns TRUE if the current session's user has the privilege to create roles. +|CREATEDB | Returns TRUE if the current session's user has the privilege to create databases. +|==== diff --git a/EN/modules/ROOT/pages/master/6.4.adoc b/EN/modules/ROOT/pages/master/6.5.adoc similarity index 100% rename from EN/modules/ROOT/pages/master/6.4.adoc rename to EN/modules/ROOT/pages/master/6.5.adoc diff --git a/EN/modules/ROOT/pages/master/7.8.adoc b/EN/modules/ROOT/pages/master/7.8.adoc index d80eee4a..d4f2f6ac 100644 --- a/EN/modules/ROOT/pages/master/7.8.adoc +++ b/EN/modules/ROOT/pages/master/7.8.adoc @@ -74,11 +74,13 @@ |to_single_byte |compose |decompose +|sys_context |==== == Built-in function descriptions -1、Compatible with sysdate function, function: view the corresponding date and time, the test cases are as follows: +=== `sysdate` function +function: view the corresponding date and time, the test cases are as follows: Query the date of the current system: ``` @@ -99,7 +101,8 @@ select sysdate()-1 from dual; (1 row) ``` -2、Compatible with the systimestamp function, function: return the current system date and time (including microseconds and time zone) on the local database, the test cases are as follows: +=== `systimestamp` function +function: return the current system date and time (including microseconds and time zone) on the local database, the test cases are as follows: Date and time to query the current date: ``` @@ -110,7 +113,8 @@ select systimestamp() from dual; (1 row) ``` -3、Compatible with add_months functions, function: the function adds a date to the number of months (n), and returns the same day that is n months apart, supporting parameters: date, number; The test cases are as follows: +=== `add_months` function +function: the function adds a date to the number of months (n), and returns the same day that is n months apart, supporting parameters: date, number; The test cases are as follows: Check the same day of the following month on the current date (July 6): ``` @@ -131,7 +135,8 @@ select add_months(sysdate(),-1) from dual; (1 row) ``` -4、Compatible with last_day functions, function: return the last day of the month where the specified date is located, support parameters: date, the test cases are as follows: +=== `last_day` function +function: return the last day of the month where the specified date is located, support parameters: date, the test cases are as follows: Check the last day of the month in which the day is located: ``` @@ -152,7 +157,8 @@ select last_day(to_date('2019-09-01'))from dual; (1 row) ``` -5、 Compatible with next_day functions, function: return the next date of the specified date. Supported parameters: date, integer /date, text, Note: When the second parameter in the function passes the number of weeks more hours than the existing week, the date of the next week will be returned; When the date passed by the second parameter in the function is greater than the existing number of weeks, the corresponding day of the week of the week is returned. The test cases are as follows: +=== `next_day` function +function: return the next date of the specified date. Supported parameters: date, integer /date, text, Note: When the second parameter in the function passes the number of weeks more hours than the existing week, the date of the next week will be returned; When the date passed by the second parameter in the function is greater than the existing number of weeks, the corresponding day of the week of the week is returned. The test cases are as follows: Query the next day of the current date: ``` @@ -173,7 +179,8 @@ select next_day(sysdate(),'FRIDAY') from dual; (1 row) ``` -6、Compatible with months_between functions, function: return the month of difference between date1 and date2 of date type, support parameters: date, date, description: if date1 is later than date2, return a positive number; If date1 is earlier than date2, a negative number is returned; If date1 and date2 are the same day of a month, the return result is an integer; If not the same day, results with decimal parts are returned on a monthly basis of 31 days. The test cases are as follows: +=== `months_between` function +function: return the month of difference between date1 and date2 of date type, support parameters: date, date, description: if date1 is later than date2, return a positive number; If date1 is earlier than date2, a negative number is returned; If date1 and date2 are the same day of a month, the return result is an integer; If not the same day, results with decimal parts are returned on a monthly basis of 31 days. The test cases are as follows: To find the month that differs between the same day in different months: ``` @@ -194,7 +201,8 @@ select months_between(to_date('2023-07-06'),to_date('2023-08-05')) from dual; (1 row) ``` -7、Compatible with current_date functions, functions: return the current date of the current time zone, the test cases are as follows: +=== `current_date` function +function: return the current date of the current time zone, the test cases are as follows: To query the current date in the current time zone: ``` @@ -205,7 +213,8 @@ select current_date from dual; (1 row) ``` -8、Compatible with current_timestamp functions, function: return the current date and current time of the current time zone, including the current time zone information. Support parameters: integer, Note: The returned time can be adjusted with precision. The test cases are as follows: +=== `current_timestamp` function +function: return the current date and current time of the current time zone, including the current time zone information. Support parameters: integer, Note: The returned time can be adjusted with precision. The test cases are as follows: To query the current date and time in the current time zone: ``` @@ -226,7 +235,8 @@ select current_timestamp(3) from dual; (1 row) ``` -9、Compatible with new_time functions, function: return the date in another time zone corresponding to a certain time zone, support parameters: date, text, text, the test case is as follows: +=== `new_time` function +function: return the date in another time zone corresponding to a certain time zone, support parameters: date, text, text, the test case is as follows: Returns the date for the current date in another time zone: ``` @@ -237,7 +247,8 @@ select sysdate() bj_time,new_time(sysdate(),'PDT','GMT')los_angles from dual; (1 row) ``` -10、Compatible with tz_offset functions, function: return the offset of the given time zone and the standard time zone, support parameters: text, the test case is as follows: +=== `tz_offset` function +function: return the offset of the given time zone and the standard time zone, support parameters: text, the test case is as follows: Returns the offset of a given time zone from the standard time zone: ``` @@ -248,7 +259,8 @@ select tz_offset('US/Eastern') from dual; (1 row) ``` -11、Compatible with trunc function, function: you can intercept the date to get the desired value, such as year, month, day, hour, minute, support parameters: date/date, text, the test case is as follows: +=== `trunc` function +function: you can intercept the date to get the desired value, such as year, month, day, hour, minute, support parameters: date/date, text, the test case is as follows: Intercept the current date: ``` @@ -279,7 +291,8 @@ select trunc(sysdate(),'mm') from dual; (1 row) ``` -12、Compatible with instr function, function: string search that checks whether the source string contains the target string and returns the match position. Supported parameter forms are as follows: +=== `instr` function +function: string search that checks whether the source string contains the target string and returns the match position. Supported parameter forms are as follows: * `instr(string, str)` * `instr(string, str, start_position, nth_appearance)` @@ -340,7 +353,8 @@ Implementation notes: * The sign of `position` decides forward or backward search and sets loop bounds and step. * Iterates byte by byte through the source string, comparing with the pattern until a match is found. -13、Compatible with instrb function, function: string lookup function, return the position of the string, support parameters: varchar2, text, number DEFAULT 1, number DEFAULT 1, the following are test cases: +=== `instrb` function +function: string lookup function, return the position of the string, support parameters: varchar2, text, number DEFAULT 1, number DEFAULT 1, the following are test cases: RETURNS THE POSITION OF THE STRING IN CORPORATE FLOOR WHEN THE FIRST OR OCCURS BY DEFAULT: ``` @@ -361,7 +375,8 @@ SELECT INSTRB('CORPORATE FLOOR','OR',5,2) "Instring in bytes" FROM DUAL; (1 row) ``` -14、Compatible with substr function, function: intercept string function, truncated in characters, support parameters: text, integer, test cases are as follows: +=== `substr` function +function: intercept string function, truncated in characters, support parameters: text, integer, test cases are as follows: Intercept the string from the fifth character in 'It is nice today', followed by: ``` @@ -373,7 +388,8 @@ SELECT SUBSTR('It is nice today',5) "Substring with bytes" FROM DUAL; (1 row) ``` -15、Compatible with substrb function, function: intercept string function, intercept in bytes, support parameters: varchar2, number/varchar2, number, number, the test cases are as follows: +=== `substrb` function +function: intercept string function, intercept in bytes, support parameters: varchar2, number/varchar2, number, number, the test cases are as follows: Intercept the string starting with the fifth byte in 'It's nice today' and then onwards: ``` @@ -395,7 +411,8 @@ SELECT SUBSTRB('It is nice today',5,8) "Substring with bytes" FROM DUAL; (1 row) ``` -16、Compatible with trim function, function: remove the left and right spaces or corresponding data of the specified string, support parameters: varchar2 / varchar2, varchar2, the test cases are as follows: +=== `trim` function +function: remove the left and right spaces or corresponding data of the specified string, support parameters: varchar2 / varchar2, varchar2, the test cases are as follows: Remove the left and right spaces of ' aaa bbb ccc ': ``` select trim(' aaa bbb ccc ')trim from dual; @@ -415,7 +432,8 @@ select trim('aaa bbb ccc','aaa')trim from dual; (1 row) ``` -17、Compatible with ltrim function, function: remove the left space or corresponding data of the specified string, support parameters: varchar2 / varchar2, varchar2, the test cases are as follows: +=== `ltrim` function +function: remove the left space or corresponding data of the specified string, support parameters: varchar2 / varchar2, varchar2, the test cases are as follows: Remove the space to the left of ' abcdefg ': ``` @@ -436,7 +454,8 @@ select ltrim('abcdefg','fegab')ltrim from dual; (1 row) ``` -18、Compatible with rtrim function, function: remove the space on the right side of the specified string, the test case is as follows: +=== `rtrim` function +function: remove the space on the right side of the specified string, the test case is as follows: Remove the space to the right of ' abcdefg ': ``` @@ -457,7 +476,8 @@ select rtrim('abcdefg','fegab')rtrim from dual; (1 row) ``` -19、Compatible with the length function, function: find the length of the specified string character, support parameters: char/integer/varchar2 The test cases are as follows: +=== `length` function +function: find the length of the specified string character, support parameters: char/integer/varchar2 The test cases are as follows: Query the character length of 223: ``` @@ -488,7 +508,8 @@ select length('ivorysql database') from dual; (1 row) ``` -20、Compatible with lengthb function: find the length of the specified string byte, support parameters: char/bytea/varchar2 test cases are as follows: +=== `lengthb` function +function: find the length of the specified string byte, support parameters: char/bytea/varchar2 test cases are as follows: Query the byte lengthb of 'ivorysql': @@ -520,7 +541,8 @@ select lengthb('ivorysql database') from dual; (1 row) ``` -21、compatible with replace function, function: replace the character in the specified string or delete the character, support parameters: text, text, text/varchar2, varchar2, varchar2 DEFAULT NULL::varchar2, test for example: +=== `replace` function +function: replace the character in the specified string or delete the character, support parameters: text, text, text/varchar2, varchar2, varchar2 DEFAULT NULL::varchar2, test for example: Replace 'j' in 'jack and jue' with 'bl' : ``` @@ -541,7 +563,8 @@ select replace('jack and jue','j') from dual; (1 row) ``` -22、compatible with the regexp_replace function, which is an extension of the replace function. Function: Used to perform matching and replacement through regular expressions. Supported parameters: text, text, text /text, text, text, integer/varchar2, varchar2/varchar2, varchar2 varchar2, varchar2 varchar2, for example: +=== `regexp_replace` function +which is an extension of the replace function. Function: Used to perform matching and replacement through regular expressions. Supported parameters: text, text, text /text, text, text, integer/varchar2, varchar2/varchar2, varchar2 varchar2, varchar2 varchar2, for example: Replace the matched number with *#: ``` @@ -581,7 +604,8 @@ select regexp_replace('01234abcd56789','012','xxx')from dual; (1 row) ``` -23、Compatible with regexp_substr functions, function: pick up the character substring described by the regular expression, support parameters: text, text, integer /text, text, integer, integer / text, text, integer, integer, text /varchar2, varchar2, the test cases are as follows: +=== `regexp_substr` function +function: pick up the character substring described by the regular expression, support parameters: text, text, integer /text, text, integer, integer / text, text, integer, integer, text /varchar2, varchar2, the test cases are as follows: Query the 012 string starting with the first number in '012ab34': ``` @@ -631,7 +655,8 @@ select regexp_substr('Database' , 'Data') from dual; (1 row)s ``` -24、Compatible with regexp_instr functions, function: used to calibrate the start position of the character substring that conforms to the regular expression, support parameters: text, text, integer /text, text, integer, integer / text, text, integer, integer, text, integer / varchar2, varchar2, the test case is as follows: +=== `regexp_instr` function +function: used to calibrate the start position of the character substring that conforms to the regular expression, support parameters: text, text, integer /text, text, integer, integer / text, text, integer, integer, text, integer / varchar2, varchar2, the test case is as follows: Query 'abcaBcabc' for the position of the abc substring starting from the first character: ``` @@ -682,7 +707,8 @@ SELECT regexp_instr('Database', 'Data'); (1 row) ``` -25、Compatible with regexp_like functions, function: similar to like, used for fuzzy queries. Supported parameters: varchar2, varchar2 /varchar2, varchar2 varchar2, +=== `regexp_like` function +function: similar to like, used for fuzzy queries. Supported parameters: varchar2, varchar2 /varchar2, varchar2 varchar2, First create a regexp_like table for the test case query: ``` @@ -732,7 +758,8 @@ select * from t_regexp_like where regexp_like(value,'ABC','i'); ``` -26、Compatible with to_number functions, function: is to change some processed strings arranged in a certain format back to a numeric format, support parameters: text/text, text test cases are as follows: +=== `to_number` function +function: is to change some processed strings arranged in a certain format back to a numeric format, support parameters: text/text, text test cases are as follows: Convert the string '-34,338,492' to numeric format: ``` @@ -754,7 +781,8 @@ SELECT to_number('5.01-', '9.99S'); (1 row) ``` -27、Compatible with to_char functions, functions: convert numbers or dates to character types, support parameters: date/date, text/timestamp/timestamp, text test cases are as follows: +=== `to_char` function +function: convert numbers or dates to character types, support parameters: date/date, text/timestamp/timestamp, text test cases are as follows: To convert the current system date to character format: ``` @@ -794,7 +822,8 @@ SELECT to_char(sysdate()::timestamp,'MM-YYYY-DD'); (1 row) ``` -28、Compatible with to_date functions, function: convert character type to date type, support parameters: text/text, text test cases are as follows: +=== `to_date` function +function: convert character type to date type, support parameters: text/text, text test cases are as follows: Convert '2023/07/06' to date type: ``` @@ -815,7 +844,8 @@ SELECT to_date('-44,0201','YYYY-MM-DD'); (1 row) ``` -29、Compatible with to_timestamp functions, functions: can store year, month, day, hour, minute, second, and can also store fractional parts of seconds. Supported parameters: text/text, text test cases are as follows: +=== `to_timestamp` function +function: can store year, month, day, hour, minute, second, and can also store fractional parts of seconds. Supported parameters: text/text, text test cases are as follows: Query '2018-11-02 12:34:56.025' output as a date: ``` SELECT to_timestamp('20181102.12.34.56.025'); @@ -835,7 +865,8 @@ SELECT to_timestamp('2011,12,18 11:38 ', 'YYYY-MM-DD HH24:MI:SS'); (1 row) ``` -30、Compatible with to_timestamp_tz functions, functions: according to the time query, the time string has T, Z and milliseconds, time zone. The test cases are as follows: +=== `to_timestamp_tz` function +function: according to the time query, the time string has T, Z and milliseconds, time zone. The test cases are as follows: Query '2016-10-9 14:10:10.123000' output as a date: @@ -857,7 +888,8 @@ Query '10-9-2016 14:10:10.123000 +8:30' output as a date: (1 row) ``` -31、Compatible with to_yminterval functions, function: convert a string type to a year and month time difference type, support parameters: text, The test cases are as follows: +=== `to_yminterval` function +function: convert a string type to a year and month time difference type, support parameters: text, The test cases are as follows: Query the date after two years and eight months after '20110101': ``` select to_date('20110101','yyyymmdd')+to_yminterval('02-08') from dual; @@ -867,7 +899,8 @@ select to_date('20110101','yyyymmdd')+to_yminterval('02-08') from dual; (1 row) ``` -32、Compatible with to_dsinterval functions, function: add a date plus a certain hour or number of days into another date, support parameters: text, test cases are as follows: +=== `to_dsinterval` function +function: add a date plus a certain hour or number of days into another date, support parameters: text, test cases are as follows: Query the current system time plus the date in 9 and a half hours (currently 2023-07-06, 18:00): ``` @@ -878,7 +911,8 @@ select sysdate()+to_dsinterval('0 09:30:00')as newdate from dual; (1 row) ``` -33、compatible with numtodsinterval function, function: convert numbers into time interval type data. The supporting parameters: double precision, text test cases are as follows: +=== `numtodsinterval` function +function: convert numbers into time interval type data. The supporting parameters: double precision, text test cases are as follows: Convert 100.00 hours to interval type data: ``` SELECT NUMTODSINTERVAL(100.00, 'hour'); @@ -898,7 +932,8 @@ SELECT NUMTODSINTERVAL(100, 'minute'); (1 row) ``` -34、Compatible with the numtoyminterval function, function: convert numbers into date interval type data. +=== `numtoyminterval` function +function: convert numbers into date interval type data. Convert 1, year to date interval: double precision, text, the test case is as follows: ``` @@ -919,7 +954,8 @@ SELECT NUMTOYMINTERVAL(1,'month'); (1 row) ``` -35、Compatible with the localtimestamp function, function: return the date and time in the session, support parameters: integer, add parameters to the function as precision, the test cases are as follows: +=== `localtimestamp` function +function: return the date and time in the session, support parameters: integer, add parameters to the function as precision, the test cases are as follows: To return the date and time in the current session: ``` @@ -940,7 +976,8 @@ select localtimestamp(1) from dual; (1 row) ``` -36、Compatible with from_tz functions, functions: convert time from one time zone to another, support parameters; timestamp, text, the test case is as follows: +=== `from_tz` function +function: convert time from one time zone to another, support parameters; timestamp, text, the test case is as follows: Convert '2000-03-28 08:00:00', '3:00' to the current time zone: ``` @@ -951,7 +988,8 @@ SELECT FROM_TZ(TIMESTAMP '2000-03-28 08:00:00', '3:00') FROM DUAL; (1 row) ``` -37、Compatible with sys_extract_utc functions, function: convert a timestamptz to UTC time zone time. Supported parameters: timestamp with time zone The test cases are as follows: +=== `sys_extract_utc` function +function: convert a timestamptz to UTC time zone time. Supported parameters: timestamp with time zone The test cases are as follows: Query conversion timestamp '2000-03-28 11:30:00.00 -8:00' to the time after UTC time zone: ``` @@ -962,7 +1000,8 @@ select sys_extract_utc(timestamp '2000-03-28 11:30:00.00 -8:00') from dual; (1 row) ``` -38、Compatible with sessiontimezone function, function: view time zone details, test cases are as follows: +=== `sessiontimezone` function +function: view time zone details, test cases are as follows: To view the details of the current time zone: ``` select sessiontimezone() from dual; @@ -984,7 +1023,8 @@ select sessiontimezone() from dual; (1 row) ``` -39、compatible with hextoraw function, function: convert the binary value represented by the string into a RAW value. Support parameters: text, the test cases are as follows: +=== `hextoraw` function +function: convert the binary value represented by the string into a RAW value. Support parameters: text, the test cases are as follows: Convert the string 'abcdef' to a raw value: @@ -996,7 +1036,8 @@ select hextoraw('abcdef')from dual; (1 row) ``` -40、Compatible with uid function, function: get the instance name of the database. The test cases are as follows: +=== `uid` function +function: get the instance name of the database. The test cases are as follows: Get the instance name of the current database: ``` @@ -1007,7 +1048,8 @@ select uid() from dual; (1 row) ``` -41、Compatible with USERENV function, function: return the information of the current user environment, the test cases are as follows: +=== `USERENV` function +function: return the information of the current user environment, the test cases are as follows: Check whether the current user is DBA, and if so, return ture: ``` @@ -1028,7 +1070,8 @@ select userenv('sessionid')from dual; (1 row) ``` -42、Compatible with ASCIISTR function, function: input string, return ASCII characters, the test cases are as follows: +=== `ASCIISTR` function +function: input string, return ASCII characters, the test cases are as follows: string with only ascii chars: ``` select asciistr('Hello, World!') from dual; @@ -1055,7 +1098,8 @@ string with mixed ascii and non-ascii: (1 row) ``` -43、Compatible with TO_MULTI_BYTE function, function: Convert half-width characters in a string to full-width characters: +=== `TO_MULTI_BYTE` function +function: Convert half-width characters in a string to full-width characters: input half-width characters, Convert to full-width characters: ``` select to_multi_byte('1.2'::text) ; @@ -1064,8 +1108,9 @@ select to_multi_byte('1.2'::text) ; 1.2 ``` -44、Compatible with TO_SINGLE_BYTE function, function: Convert full-width characters in a string to half-width characters: -input full-width characters, Convert to half-width characters: 输入全角字符,转换为半角字符: +=== `TO_SINGLE_BYTE` function +function: Convert full-width characters in a string to half-width characters: +input full-width characters, Convert to half-width characters: ``` select to_single_byte('1.2'); to_single_byte @@ -1073,7 +1118,8 @@ select to_single_byte('1.2'); 1.2 ``` -45、Compatible with COMPOSE function,function: Combine base characters and combining marks into a composite Unicode character: +=== `COMPOSE` function +function: Combine base characters and combining marks into a composite Unicode character: input base character 'a' with a combining mark '768', return à: ``` select compose('a'||chr(768)) from dual; @@ -1084,11 +1130,22 @@ select compose('a'||chr(768)) from dual; ``` -46、ompatible with DECOMPOSE function, function: Decompose composite Unicode characters (like those with accents or special symbols) into their base characters and combining marks. -input é, return a base character 'e' with a combining mark '301': +=== `DECOMPOSE` function +function: Decompose composite Unicode characters (like those with accents or special symbols) into their base characters and combining marks. +input é, return a base character 'e' with a combining mark '301': ``` select asciistr(decompose('é')) from dual; asciistr ---------- e\0301 ``` +=== `SYS_CONTEXT` function +which returns the value of the parameter associated with the given context at the current moment. It can be used in both SQL and PL/SQL languages. +``` +ivorysql=# select sys_context('USERENV','DB_NAME'); + sys_context +------------- + ivorysql +(1 row) + +``` From 164860bf667c2554ee296e15f964bea300960504 Mon Sep 17 00:00:00 2001 From: Oreo Yang <2167young@163.com> Date: Mon, 27 Oct 2025 15:58:42 +0800 Subject: [PATCH 2/2] add userenv .adoc --- CN/modules/ROOT/nav.adoc | 1 + CN/modules/ROOT/pages/master/6.4.2.adoc | 57 +++++++++++++++++++++++++ EN/modules/ROOT/nav.adoc | 1 + EN/modules/ROOT/pages/master/6.4.2.adoc | 57 +++++++++++++++++++++++++ 4 files changed, 116 insertions(+) create mode 100644 CN/modules/ROOT/pages/master/6.4.2.adoc create mode 100644 EN/modules/ROOT/pages/master/6.4.2.adoc diff --git a/CN/modules/ROOT/nav.adoc b/CN/modules/ROOT/nav.adoc index f3762582..d0470346 100644 --- a/CN/modules/ROOT/nav.adoc +++ b/CN/modules/ROOT/nav.adoc @@ -28,6 +28,7 @@ **** xref:master/6.3.5.adoc[NLS 参数] *** 内置函数 **** xref:master/6.4.1.adoc[sys_context] +**** xref:master/6.4.2.adoc[userenv] *** xref:master/6.5.adoc[国标GB18030] ** Oracle兼容功能列表 *** xref:master/7.1.adoc[1、框架设计] diff --git a/CN/modules/ROOT/pages/master/6.4.2.adoc b/CN/modules/ROOT/pages/master/6.4.2.adoc new file mode 100644 index 00000000..ad1ec29b --- /dev/null +++ b/CN/modules/ROOT/pages/master/6.4.2.adoc @@ -0,0 +1,57 @@ + +:sectnums: +:sectnumlevels: 5 + + += **功能概述** + +IvorySQL提供兼容Oracle内置函数`USERENV('parameter')`,用于返回当前会话的相关信息。 +这是一个遗留函数,建议使用 SYS_CONTEXT 函数及其内置的 USERENV 命名空间来获取当前功能。 + +== 实现原理 + +`USERENV` 通过Bison规则解析函数调用,检查参数合法性并映射到对应的具体SQL函数。 +解析规则在 `ora_gram.y` 中实现,逻辑如下: +```c +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` 中实现。例如: +```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; +``` + +== USERENV支持的参数 +[cols="2,8"] +|==== +|*参数名称*|*返回值* +|sid | 当前session的用户ID。 +|sessionid | 返回审计会话标识符。 +|language | 返回数据库当前会话的语言、地域和字符集。 +|lang | 返回ISO缩写语言名称。 +|isdba | 如果用户已经被认证为管理员;或者是通过操作系统或口令文件具有管理员特权的,返回“TRUE",否则返回"FALSE"。 +|==== diff --git a/EN/modules/ROOT/nav.adoc b/EN/modules/ROOT/nav.adoc index d12d4930..ee4fef24 100644 --- a/EN/modules/ROOT/nav.adoc +++ b/EN/modules/ROOT/nav.adoc @@ -27,6 +27,7 @@ *** xref:master/6.3.5.adoc[NLS Parameters] ** Built-in Functions *** xref:master/6.4.1.adoc[sys_context] +*** xref:master/6.4.2.adoc[userenv] ** xref:master/6.5.adoc[GB18030 Character Set] * List of Oracle compatible features ** xref:master/7.1.adoc[1、Ivorysql frame design] diff --git a/EN/modules/ROOT/pages/master/6.4.2.adoc b/EN/modules/ROOT/pages/master/6.4.2.adoc new file mode 100644 index 00000000..6a723305 --- /dev/null +++ b/EN/modules/ROOT/pages/master/6.4.2.adoc @@ -0,0 +1,57 @@ +:sectnums: +:sectnumlevels: 5 + += **Feature Overview** + +IvorySQL provides compatibility with Oracle's built-in function `USERENV('parameter')`, which is used to return information about the current session. +This is a legacy function, and IvorySQL recommends taht you can use the `SYS_CONTEXT` function with its built-in `USERENV` namespace for current functionality. + +== Implementation Principle + +`USERENV` parses function calls through Bison rules, checks parameter validity, and maps them to corresponding SQL functions. +The parsing rules are implemented in `ora_gram.y`, with the following logic: + +```c +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 + } +``` +The specific functionality is implemented in `builtin_functions--1.0.sql`. For example: +```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; +``` + +== Supported Parameters for USERENV + +[cols="3,7"] +|==== +|Parameter Name|Return Value +|sid | The user ID of the current session. +|sessionid | Returns the audit session identifier. +|language | Returns the language, territory, and character set of the current database session. +|lang | Returns the ISO abbreviation of the language name. +|isdba | Returns "TRUE" if the user has been authenticated as an administrator or has administrator privileges through the operating system or password file; otherwise, returns "FALSE". +|====