Skip to content
Merged
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
2 changes: 2 additions & 0 deletions CN/modules/ROOT/nav.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
**** xref:master/6.3.6.adoc[函数与存储过程]
**** xref:master/6.3.7.adoc[嵌套子函数]
**** xref:master/6.3.8.adoc[Force View]
**** xref:master/6.3.9.adoc[大小写转换]
*** xref:master/6.4.adoc[国标GB18030]
*** 内置函数
**** xref:master/6.4.1.adoc[sys_context]
**** xref:master/6.4.2.adoc[userenv]
Expand Down
2 changes: 1 addition & 1 deletion CN/modules/ROOT/pages/master/5.2.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export PG_CONFIG=/usr/local/ivorysql/ivorysql-4/bin/pg_config

** 拉取pg_vector源码
```
git clone --branch v0.6.2 https://github.com/pgvector/pgvector.git
git clone --branch v0.8.1 https://github.com/pgvector/pgvector.git
```

** 安装 pgvector
Expand Down
47 changes: 47 additions & 0 deletions CN/modules/ROOT/pages/master/6.3.9.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
:sectnums:
:sectnumlevels: 5

:imagesdir: ./_images

= 引用标识符大小写转换

== 目的

为了满足Oracle的引用标识符大小写兼容,ivorysql设计了三种引用标识符的大小写转换模式。

== 实现说明

如果在数据库初始化时附加了参数 `-C`,值可以为 `normal/interchange/lowercase`,则代码中 `Intidb.c->main()` 函数会处理该参数,根据参数值设置全局变量 `caseswitchmode`。然后 `initdb` 命令会以 `-boot` 模式启动一个 `psotgres` 进程用于设置 `template1` 模板数据库,同时赋予参数 `-C ivorysql.identifier_case_switch=caseswitchmode` 给新进程。

这个新启动的后端进程会通过下面的代码将 `identifier_case_switch` 信息写入 `pg_control` 文件:

```
BootstrapModeMain() -> BootStrapXLOG();
/* save database compatible level value */
ControlFile->dbmode = bootstrap_database_mode;
ControlFile->casemode = identifier_case_switch;

/* some additional ControlFile fields are set in WriteControlFile() */
WriteControlFile();
```

当用户使用 `pg_ctl` 命令启动数据库时,`postmaster` 进程会读取 `pg_control` 文件的内容,代码调用路径为:

```
PostmasterMain()-->SetCaseGucOption()-->GetCaseSwitchModeFromControl()
```

读取到参数值后调用 `SetConfigOption()` 函数进行赋值。

在每个新的后端进程开始的时候,由于是从 `postmaster` 进程 `fork` 而来,会自动拥有相同的 `ivorysql.identifier_case_switch` 参数值。首先处理 `startup` 包,其中如果包含 `database` 或者 `user` 这两个参数,则根据 `identifier_case_switch` 对参数值做相应的处理。

源代码为:

```
BackendMain()->BackendInitialize()-->ProcessStartupPacket()
```

另外,在处理用户的 SQL 语句时,如果包含标识符,也会进行同样的处理,代码分布在:
SplitIdentifierString(),quoteOneName() 和 SplitGUCList() 这几个函数中。


2 changes: 2 additions & 0 deletions EN/modules/ROOT/nav.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
*** xref:master/6.3.6.adoc[Function and stored procedure]
*** xref:master/6.3.7.adoc[Nested Subfunctions]
*** xref:master/6.3.8.adoc[Force View]
*** xref:master/6.3.9.adoc[Case Conversion]
** xref:master/6.4.adoc[GB18030 Character Set]
** Built-in Functions
*** xref:master/6.4.1.adoc[sys_context]
*** xref:master/6.4.2.adoc[userenv]
Expand Down
48 changes: 48 additions & 0 deletions EN/modules/ROOT/pages/master/6.3.9.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
:sectnums:
:sectnumlevels: 5

:imagesdir: ./_images

= Quoted Identifier Case Conversion

== Purpose

To meet Oracle's quoted identifier case compatibility requirements, IvorySQL has designed three case conversion modes for quoted identifiers.

== Implementation Details

If the parameter `-C` is appended during database initialization, with values of `normal/interchange/lowercase`, the `Intidb.c->main()` function in the code will process this parameter and set the global variable `caseswitchmode` according to the parameter value. Then the `initdb` command will start a `postgres` process in `-boot` mode to set up the `template1` template database, while passing the parameter `-C ivorysql.identifier_case_switch=caseswitchmode` to the new process.

This newly started backend process will write the `identifier_case_switch` information to the `pg_control` file through the following code:

```
BootstrapModeMain() -> BootStrapXLOG();
/* save database compatible level value */
ControlFile->dbmode = bootstrap_database_mode;
ControlFile->casemode = identifier_case_switch;

/* some additional ControlFile fields are set in WriteControlFile() */
WriteControlFile();
```

When a user starts the database using the `pg_ctl` command, the `postmaster` process will read the contents of the `pg_control` file. The code call path is:

```
PostmasterMain()-->SetCaseGucOption()-->GetCaseSwitchModeFromControl()
```

After reading the parameter value, the `SetConfigOption()` function is called to assign the value.

When each new backend process starts, since it is forked from the `postmaster` process, it automatically has the same `ivorysql.identifier_case_switch` parameter value. First, it processes the `startup` packet, and if it contains `database` or `user` parameters, the parameter values are processed accordingly based on `identifier_case_switch`.

The source code is:

```
BackendMain()->BackendInitialize()-->ProcessStartupPacket()
```

Additionally, when processing user SQL statements, if they contain identifiers, the same processing is performed. The code is distributed in:
SplitIdentifierString(), quoteOneName() and SplitGUCList() functions.