Skip to content

Commit cbd5e7e

Browse files
committed
add implementation document
1 parent 79af35d commit cbd5e7e

File tree

4 files changed

+148
-2
lines changed

4 files changed

+148
-2
lines changed

CN/modules/ROOT/nav.adoc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
**** xref:master/6.3.8.adoc[Force View]
3636
**** xref:master/6.3.9.adoc[大小写转换]
3737
**** xref:master/6.3.10.adoc[sys_guid 函数]
38-
*** xref:master/6.4.adoc[国标GB18030]
38+
**** xref:master/6.3.11.adoc[空字符串转null]
3939
*** 内置函数
4040
**** xref:master/6.4.1.adoc[sys_context]
4141
**** xref:master/6.4.2.adoc[userenv]
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
:sectnums:
2+
:sectnumlevels: 5
3+
4+
:imagesdir: ./_images
5+
6+
= 空字符串转NULL功能
7+
8+
== 目的
9+
10+
在Oracle数据库中,空字符串('')被视为NULL值,这是Oracle的一个重要特性。为了兼容Oracle的这一行为,IvorySQL提供了空字符串转NULL功能。当启用该功能后,SQL语句中的空字符串将自动转换为NULL值,从而保证Oracle应用程序在IvorySQL上的行为一致性。
11+
12+
== 实现说明
13+
14+
参数 `ivorysql.enable_emptystring_to_NULL` 对应的GUC变量为 `enable_emptystring_to_NULL`。
15+
16+
在文件 `ora_scan.l` 中可以看到对这个变量的使用:
17+
18+
[source,c]
19+
----
20+
case xe:
21+
yylval->str = litbufdup(yyscanner);
22+
if (strcmp(yylval->str, "") == 0 &&
23+
ORA_PARSER == compatible_db &&
24+
enable_emptystring_to_NULL)
25+
{
26+
return NULL_P;
27+
}
28+
return SCONST;
29+
----
30+
31+
其中 `xe` 代表被引号包围的字符串:
32+
33+
----
34+
<xe> extended quoted strings (support backslash escape sequences)
35+
----
36+
37+
上面代码的逻辑是,在词法分析时如果遇到空字符串,在空转NULL功能启用的情况下,返回 `NULL_P`,否则返回 `SCONST`。
38+
39+
在语法分析文件 `ora_gram.y` 里,对语句 `insert into abc values('');` 是这样解析的:
40+
41+
[source,c]
42+
----
43+
values_clause:
44+
VALUES '(' expr_list ')'
45+
{
46+
SelectStmt *n = makeNode(SelectStmt);
47+
48+
n->valuesLists = list_make1($3);
49+
$$ = (Node *) n;
50+
}
51+
52+
expr_list: a_expr
53+
{
54+
$$ = list_make1($1);
55+
}
56+
57+
a_expr: c_expr { $$ = $1; }
58+
59+
c_expr: AexprConst { $$ = $1; }
60+
61+
AexprConst: Iconst
62+
| Sconst
63+
{
64+
$$ = makeStringConst($1, @1);
65+
}
66+
| NULL_P
67+
{
68+
$$ = makeNullAConst(@1);
69+
}
70+
----
71+
72+
以上代码对词法分析时返回的 `NULL_P` 或者 `SCONST` 分别构建对应的节点进行处理。
73+

EN/modules/ROOT/nav.adoc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
*** xref:master/6.3.8.adoc[Force View]
3535
*** xref:master/6.3.9.adoc[Case Conversion]
3636
*** xref:master/6.3.10.adoc[sys_guid Function]
37-
** xref:master/6.4.adoc[GB18030 Character Set]
37+
*** xref:master/6.3.11.adoc[Empty String to NULL]
3838
** Built-in Functions
3939
*** xref:master/6.4.1.adoc[sys_context]
4040
*** xref:master/6.4.2.adoc[userenv]
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
:sectnums:
2+
:sectnumlevels: 5
3+
4+
:imagesdir: ./_images
5+
6+
= Empty String to NULL Conversion
7+
8+
== Purpose
9+
10+
In Oracle databases, empty strings ('') are treated as NULL values, which is an important Oracle feature. To maintain compatibility with this Oracle behavior, IvorySQL provides the empty string to NULL conversion functionality. When this feature is enabled, empty strings in SQL statements are automatically converted to NULL values, ensuring behavioral consistency for Oracle applications running on IvorySQL.
11+
12+
== Implementation
13+
14+
The parameter `ivorysql.enable_emptystring_to_NULL` corresponds to the GUC variable `enable_emptystring_to_NULL`.
15+
16+
In the file `ora_scan.l`, you can see how this variable is used:
17+
18+
[source,c]
19+
----
20+
case xe:
21+
yylval->str = litbufdup(yyscanner);
22+
if (strcmp(yylval->str, "") == 0 &&
23+
ORA_PARSER == compatible_db &&
24+
enable_emptystring_to_NULL)
25+
{
26+
return NULL_P;
27+
}
28+
return SCONST;
29+
----
30+
31+
Where `xe` represents strings enclosed in quotes:
32+
33+
----
34+
<xe> extended quoted strings (support backslash escape sequences)
35+
----
36+
37+
The logic of the above code is that during lexical analysis, if an empty string is encountered and the empty-to-NULL conversion feature is enabled, it returns `NULL_P`; otherwise, it returns `SCONST`.
38+
39+
In the grammar analysis file `ora_gram.y`, the statement `insert into abc values('');` is parsed as follows:
40+
41+
[source,c]
42+
----
43+
values_clause:
44+
VALUES '(' expr_list ')'
45+
{
46+
SelectStmt *n = makeNode(SelectStmt);
47+
48+
n->valuesLists = list_make1($3);
49+
$$ = (Node *) n;
50+
}
51+
52+
expr_list: a_expr
53+
{
54+
$$ = list_make1($1);
55+
}
56+
57+
a_expr: c_expr { $$ = $1; }
58+
59+
c_expr: AexprConst { $$ = $1; }
60+
61+
AexprConst: Iconst
62+
| Sconst
63+
{
64+
$$ = makeStringConst($1, @1);
65+
}
66+
| NULL_P
67+
{
68+
$$ = makeNullAConst(@1);
69+
}
70+
----
71+
72+
The above code constructs corresponding nodes to handle `NULL_P` or `SCONST` returned from the lexical analysis.
73+

0 commit comments

Comments
 (0)