Skip to content

Commit a972d80

Browse files
committed
test3
1 parent f19d22f commit a972d80

4 files changed

Lines changed: 101 additions & 224 deletions

File tree

.coderabbit.yaml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
# yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json
22
# Minimal configuration for getting started
3-
language: "zh-CN"
4-
# language: "en-US"
3+
# language: "zh-CN"
4+
language: "en-US"
55
reviews:
66
profile: "chill"
77
high_level_summary: true
88
auto_review:
99
enabled: true
1010
drafts: false
11-
base_branches: ["master", "IVORY_REL_5_STABLE", "auto_review"]
11+
base_branches: ["master", "v4.6", "v4.5","v1.17", "auto_review"]

.github/workflows/pr-preview.yml

Lines changed: 0 additions & 166 deletions
This file was deleted.

CN/modules/ROOT/pages/master/6.3.5.adoc

Lines changed: 97 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
IvorySQL提供了兼容Oracle的NLS参数功能,包含如下参数。
99

10-
[cols="2,8"]
10+
[cols="3,7"]
1111
|====
1212
|*参数名称*|*功能描述*
1313
|ivorysql.datetime_ignore_nls_mask | 表示日期格式是否忽略NLS参数影响,默认为0。
@@ -20,77 +20,120 @@ IvorySQL提供了兼容Oracle的NLS参数功能,包含如下参数。
2020
|nls_currency | 兼容Oracle的同名参数,指定显示本地货币的符号,对应数字字符串格式中占位符L。
2121
|====
2222

23-
24-
2523
== 实现原理
2624

2725
=== nls_length_semantics参数
2826

29-
对于pliSQL函数,在创建函数时,系统表pg_proc中存储函数参数为全部参数个数(包括OUT参数个数)及对应的参数数据类型。
30-
31-
在处理函数参数的interpret_function_parameter_list()函数中,根据参数模式,判断如果是IN OUT,则参数不能有默认值。
32-
33-
在make_return_stmt函数中,去掉如果发现有out参数报错的处理。
34-
35-
通过修改FuncnameGetCandidates函数,在函数查找时匹配包括out参数在内的所有参数。
36-
37-
函数编译时,构造一个row变量来容纳OUT参数变量和返回值变量。修改编译好的函数返回类型(function->fn_rettype)为RECORDOID。
38-
39-
函数执行时,在ExecInitFunc函数中调用新函数ExecInitFuncOutParams, 构造OUT参数计算节点,通过计算函数plisql_out_param将函数返回值和OUT参数值从tuple中分离,并且为OUT参数向外赋值。
40-
41-
=== 匿名块支持out参数
42-
43-
为了支持冒号占位符形式的绑定变量,修改ora_scan.l文件,添加语法,遇到冒号占位符返回ORAPARAM。在ora_gram.y文件中,在c_expr和赋值plassign_target的语法中,添加对ORAPARAM添加处理,构造一个OraParamRef节点。
44-
45-
新增 DO + USING 语法:
27+
IvorySQL中的数据类型存在一个属性修饰符typmod,是对类型的补充说明,比如在VARCHAR(n)类型中,n就是类型修饰符。在创建或修改表的列时可以指定长度类型,例如:
4628
```
47-
DO [ LANGUAGE lang_name ] code [USING IN | OUT | IN OUT, ...]
29+
ivorysql=# create table t1(name varchar2(2 byte));
4830
```
49-
修改ora_gram.y文件,增加DO+USING语法支持。DoStmt结构体中增加 paramsmode 用于存储匿名块中的绑定变量模式等信息的列表。
50-
51-
对PBE过程的修改包括:exec_parse_message函数中,根据应用接口传过来的参数类型oid,识别出实参的模式;在exec_bind_message函数中,对于匿名块DO+USING,识别出USING后面参数的模式,向执行器传递参数信息。
5231

53-
含OUT参数匿名块的执行
32+
对于列类型为CHAR、VARCHAR和VARCHAR2字符型的列,当没有显式指定列的长度类型时,IvorySQL使用nls_length_semantics参数的值来决定长度类型,有byte和char两种值,默认为byte。需要特别注意的是,nls_length_semantics参数的值仅影响新创建的列,对已经存在的列不会产生任何影响。
5433

55-
1. 在PortalStart函数中对匿名块语句,调用CreateTupleDescFromParams函数,增加参数构造描述信息。
34+
在语法解析文件 ora_gram.y中,存在如下代码来根据nls_length_semantics 把原本的char/varchar/varchar2类型改成oracharchar或者oracharbyte:
35+
```
36+
CharacterWithLength: character '(' Iconst ')'
37+
{
38+
if (ORA_PARSER == compatible_db)
39+
{
40+
if (strcmp($1, "bpchar"))
41+
{
42+
if (nls_length_semantics == NLS_LENGTH_CHAR)
43+
$1 = "oravarcharchar";
44+
else
45+
$1 = "oravarcharbyte";
46+
}
47+
else
48+
{
49+
if (nls_length_semantics == NLS_LENGTH_CHAR)
50+
$1 = "oracharchar";
51+
else
52+
$1 = "oracharbyte";
53+
}
54+
55+
$$ = OracleSystemTypeName($1);
56+
$$->typmods = list_make1(makeIntConst($3, @3));
57+
$$->location = @1;
58+
}
59+
else
60+
{
61+
...
62+
}
63+
}
64+
;
5665

57-
2. PLiSQL_function成员fn_prokind增加新值PROKIND_ANONYMOUS_BLOCK用来表示匿名块。
66+
```
5867

59-
3. 在plisql_exec_function函数中,对有out参数的匿名块做判断,调用plisql_anonymous_return_out_parameter函数完成对OUT参数构造PLiSQL_row类型的变量,最后将row类型的变量求值当作匿名块函数的返回值。
68+
IvorySQL 中数据类型oracharchar和oracharbyte的修饰符输入输出函数包括:
69+
oravarcharchartypmodout() / oravarcharbytetypmodout() / oracharbytetypmodout() / oracharchartypmodout()
6070

61-
=== libpq中调用含out参数的函数
71+
上面这些函数调用C语言实现的函数 anychar_typmodout() ,后者根据 nls_length_semantics 的值来调整输出的内容是否包含 byte/char 的说明。
6272

63-
修改Libpq以支持按位置和按参数名字绑定,涉及SQL端,PLiSQL端,libpq接口端。
73+
nls_length_semantics 另一个作用是限制表中的列长度:
74+
根据上述代码在语法解析文件 ora_gram.y中,如果原本的varchar类型被转换成了oracharchar类型,则函数oravarcharchar()会被调用,而pg_mbcharcliplen()函数计算字符长度,而不是字节长度。
75+
```
76+
Datum
77+
oravarcharchar(PG_FUNCTION_ARGS)
78+
{
79+
VarChar *source = PG_GETARG_VARCHAR_PP(0);
80+
int32 typmod = PG_GETARG_INT32(1);
81+
bool isExplicit = PG_GETARG_BOOL(2);
82+
int32 len,
83+
maxlen;
84+
size_t maxmblen;
85+
char *s_data;
86+
87+
len = VARSIZE_ANY_EXHDR(source);
88+
s_data = VARDATA_ANY(source);
89+
maxlen = typmod - VARHDRSZ;
90+
91+
/* No work if typmod is invalid or supplied data fits it already */
92+
if (maxlen < 0 || len <= maxlen)
93+
PG_RETURN_VARCHAR_P(source);
94+
95+
maxmblen = pg_mbcharcliplen(s_data, len, maxlen);
96+
97+
...
98+
}
99+
```
64100

65-
1. SQL端:在服务器端实现系统函数 get_parameter_description,该函数根据SQL语句,返回变量名字与位置的关系。这个函数被用在libpq接口函数中。
66-
返回的第一行name显示SQL类型,后面行依次显示占位符名字、位置信息。
101+
=== GUC参数datetime_ignore_nls_mask
67102

68-
```
69-
ivorysql=# select * from get_parameter_description('insert into t values(:x, :y);');
70-
name | position
71-
-------+----------
72-
false | 0
73-
:x | 1
74-
:y | 2
75-
(3 rows)
76-
```
77-
对于匿名块语句,尚不支持。
103+
这个参数被定义为一个int值,低四位分别表示是否在相应的日期时间格式上忽略NLS参数的影响,掩码定义如下:
104+
```
105+
#define ORADATE_MASK 0x01
106+
#define ORATIMESTAMP_MASK 0x02
107+
#define ORATIMESTAMPTZ_MASK 0x04
108+
#define ORATIMESTAMPLTZ_MASK 0x08
109+
```
78110

79-
2. PLiSQL端:主要是PL/iSQL块根据参数位置或参数名称调整参数内部标识。
111+
在源代码中,这个GUC参数被用于下面这些函数:
112+
oradate_in()、oratimestamp_in()、oratimestampltz_in()以及oratimestamptz_in()。
80113

81-
执行函数需要从绑定句柄中获取参数的值与类型的信息;
114+
如果相应的掩码被设置,则调用原生PG的处理函数,否则调用兼容代码并忽略NLS格式。
82115

83-
对out参数的返回列名称做一个特殊处理。如果是out参数,那么其列名称为_column_xxx,其中xxx是out参数的位置,从而根据绑定位置与返回的位置从结果集中给out参数赋值;
116+
=== GUC参数 nls_date_format/nls_timestamp_format/nls_timestamp_tz_format
84117

85-
在PLiSQL执行端,根据参数名字出现的位置,调整名字转换成内部标识的变量,如$number。在返回到客户端的时候,发送描述信息给libpq, 从而达到返回的列名是由参数名字构造,LIBPQ端根据列名来给out参数赋值。
118+
这三个GUC参数,在函数 ora_do_to_timestamp() 中做为格式字符串,对输入的字符串进行格式检查与模式识别。
119+
下面是其默认值,可以通过设置其值为"pg"使其失效。"pg"表示禁用NLS特定行为,恢复为PostgreSQL的默认行为。
120+
```
121+
char *nls_date_format = "YYYY-MM-DD";
122+
char *nls_timestamp_format = "YYYY-MM-DD HH24:MI:SS.FF6";
123+
char *nls_timestamp_tz_format = "YYYY-MM-DD HH24:MI:SS.FF6 TZH:TZM";
124+
```
86125

87-
3. libpq接口端:提供准备、绑定、执行函数, 这些函数与OCI接口相应函数类似, 在说什么。
126+
=== GUC参数 nls_currency/nls_iso_currency/nls_territory
88127

89-
一般调用流程如下:
90-
使用IvyHandleAlloc分配语句句柄和错误句柄。
91-
调用IvyStmtPrepare准备语句。
92-
调用IvyBindByPos或IvyBindByName 绑定参数。
93-
调用IvyStmtExecute 执行,可重复执行。
94-
调用IvyFreeHandle 释放语句句柄和错误句柄。
128+
目前nls_territory和nls_iso_currency支持CHINA与AMERICA两个值
95129

96-
另外还实现了Ivyconnectdb,Ivystatus,Ivyexec,IvyresultStatus,IvyCreatePreparedStatement,IvybindOutParameterByPos,IvyexecPreparedStatement,IvyexecPreparedStatement2,Ivynfields,Ivyntuples,Ivyclear等一系列接口函数。
130+
```
131+
char *nls_territory = "AMERICA";
132+
char *nls_currency = "$";
133+
char *nls_iso_currency = "AMERICA";
134+
```
135+
这三个参数将在oracle兼容函数to_number()中被使用。
136+
[NOTE]
137+
====
138+
`to_number()`函数尚未实现。傻大姐撒低级啊实打实
139+
====

EN/modules/ROOT/pages/master/welcome.adoc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,4 @@ It is Apache licensed Open Source and always free to use. Any comments please co
1717
== Docs Download
1818
https://docs.ivorysql.org/en/ivorysql-doc/v4.5/ivorysql.pdf[IvorySQL v4.5 pdf documentation]
1919

20-
testtttttttttttttt
20+
testtttttttttttttt 大大苏打实打实

0 commit comments

Comments
 (0)