Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CN/modules/ROOT/nav.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@
*** 内置函数
**** xref:master/oracle_builtin_functions/sys_context.adoc[sys_context]
**** xref:master/oracle_builtin_functions/userenv.adoc[userenv]
**** xref:master/oracle_builtin_functions/rawtohex.adoc[rawtohex]
*** xref:master/gb18030.adoc[国标GB18030]
* 参考指南
** xref:master/tools_reference.adoc[工具参考]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@

:sectnums:
:sectnumlevels: 5


= **功能概述**

IvorySQL提供兼容Oracle内置函数 ```RAWTOHEX('parameter')``` ,用于将RAW类型转换成十六进制字符串。

== 实现原理

PostgreSQL 提供的pg_catalog.encode(bytea, 'hex')函数,可直接完成二进制到十六进制的转换。
考虑到当前系统中已经存在的HEXTORAW函数通过封装pg_catalog.decode 的SQL方式实现,本次开发的
RAWTOHEX 函数将使用相同的方式来实现,即使用 SQL 函数包装 PostgreSQL 内置函数pg_catalog.encode,
而非编写 C 扩展。

raw、text、bytea以及varchar2这四种类型做为输入需要被支持。
sys.raw 是 bytea 的 domain 类型(typtype = 'd',typbasetype = bytea),PostgreSQL 支持 domain 到 base type 的隐式转换,RAWTOHEX(bytea) 可自动接受 sys.raw 输入。
sys.oravarcharchar(即 varchar2)到 pg_catalog.text 存在 IMPLICIT cast(datatype--1.0.sql),RAWTOHEX(text) 可自动接受 varchar2 输入。
因此,定义两个重载(而不是四个)。

```
sys.rawtohex(bytea) RETURNS varchar2
sys.rawtohex(text) RETURNS varchar2
```

具体功能则是在 `builtin_functions--1.0.sql` 中实现。
```sql
/* support rawtohex function for oracle compatibility */
CREATE OR REPLACE FUNCTION sys.rawtohex(bytea)
RETURNS varchar2
AS $$ SELECT CASE WHEN pg_catalog.octet_length($1) > 0 THEN upper(pg_catalog.encode($1, 'hex'))::varchar2 END; $$
LANGUAGE SQL
PARALLEL SAFE
STRICT
IMMUTABLE;

CREATE OR REPLACE FUNCTION sys.rawtohex(text)
RETURNS varchar2
AS $$ SELECT CASE WHEN pg_catalog.octet_length($1) > 0 THEN upper(pg_catalog.encode($1::bytea, 'hex'))::varchar2 END; $$
LANGUAGE SQL
PARALLEL SAFE
STRICT
IMMUTABLE;
```

== RAWTOHEX 典型用例
[cols="8,2"]
|====
|*用例语句*|*返回值*
|SELECT sys.rawtohex('\xDEADBEEF'::bytea); | DEADBEEF
|SELECT sys.rawtohex('\xFF'::raw); | FF
|SELECT sys.rawtohex('hello'::text); | 68656C6C6F
|SELECT sys.rawtohex('hello'::varchar2); | 68656C6C6F
|====
1 change: 1 addition & 0 deletions EN/modules/ROOT/nav.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@
** Built-in Functions
*** xref:master/oracle_builtin_functions/sys_context.adoc[sys_context]
*** xref:master/oracle_builtin_functions/userenv.adoc[userenv]
*** xref:master/oracle_builtin_functions/rawtohex.adoc[rawtohex]
** xref:master/gb18030.adoc[GB18030 Character Set]
* Reference
** xref:master/tools_reference.adoc[Tool Reference]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@

:sectnums:
:sectnumlevels: 5


= **Feature Overview**

IvorySQL provides compatibility with Oracle's built-in function ```RAWTOHEX('parameter')```, which is used to convert RAW to a character value containing its hexadecimal representation.

== Implementation Principle

The function pg_catalog.encode(bytea, 'hex') provided by PostgreSQL can directly convert binary data to hexadecimal.

Given that the existing HEXTORAW function in the current system is implemented by wrapping pg_catalog.decode using SQL, the RAWTOHEX function developed this time will be implemented in the same way. That is, it will be a SQL function wrapping the PostgreSQL built-in function pg_catalog.encode, rather than implementing it via a C extension.

The following four types need to be supported as input: raw, text, bytea, and varchar2.

sys.raw is a domain type of bytea (typtype = 'd', typbasetype = bytea). PostgreSQL supports implicit conversion from a domain type to its base type, so RAWTOHEX(bytea) can automatically accept sys.raw as input.

There is an IMPLICIT cast from sys.oravarcharchar (i.e., varchar2) to pg_catalog.text (defined in datatype--1.0.sql), so RAWTOHEX(text) can automatically accept varchar2 as input.

Therefore, two overloaded versions (rather than four) will be defined.

```
sys.rawtohex(bytea) RETURNS varchar2
sys.rawtohex(text) RETURNS varchar2
```

The specific functionality is implemented in builtin_functions—1.0.sql.
```sql
/* support rawtohex function for oracle compatibility */
CREATE OR REPLACE FUNCTION sys.rawtohex(bytea)
RETURNS varchar2
AS $$ SELECT CASE WHEN pg_catalog.octet_length($1) > 0 THEN upper(pg_catalog.encode($1, 'hex'))::varchar2 END; $$
LANGUAGE SQL
PARALLEL SAFE
STRICT
IMMUTABLE;

CREATE OR REPLACE FUNCTION sys.rawtohex(text)
RETURNS varchar2
AS $$ SELECT CASE WHEN pg_catalog.octet_length($1) > 0 THEN upper(pg_catalog.encode($1::bytea, 'hex'))::varchar2 END; $$
LANGUAGE SQL
PARALLEL SAFE
STRICT
IMMUTABLE;
```

== RAWTOHEX use cases
[cols="8,2"]
|====
|*SQL statement *|*return value*
|SELECT sys.rawtohex('\xDEADBEEF'::bytea); | DEADBEEF
|SELECT sys.rawtohex('\xFF'::raw); | FF
|SELECT sys.rawtohex('hello'::text); | 68656C6C6F
|SELECT sys.rawtohex('hello'::varchar2); | 68656C6C6F
|====
Loading