PostgreSQL元组格式



是否有文档描述PostgreSQL服务器坚持的元组格式?官方文档对此似乎很晦涩。

单个元组似乎很简单,可以弄清楚,但是当涉及到元组的数组、复合元组的数组以及复合元组的嵌套数组时,仅通过查看输出就不可能确定格式。

我问这个是在我最初尝试实现pg-tuple之后,一个解析器,今天仍然缺失,能够解析Node.js中的PostgreSQL元组


create type type_A as (
   a int,
   b text
);
    (1,hello)
  • 复合文本:(1,"hello world!")

create type type_B as (
   c type_A,
   d type_A[]
);
  • 简单值数组:{"(2,two)","(3,three)"}

  • 对于type_B[]我们可以得到:

{"("(7,inner)","{""(88,eight-1)"",""(99,nine-2)""}")","("(77,inner)","{""(888,eight-3)"",""(999,nine-4)""}")"}

对于复合类型的多维数组则更加复杂。


因为感觉根本没有规范,我已经开始扭转它。不确定是否可以完全完成,因为从一些最初的例子中,通常不清楚应用了什么格式规则。

正如Nick所说,根据docs:

如果字段类型是整数,则忽略

空白,但不是如果是文本

复合输出例程将在field周围加上双引号值,如果它们是空字符串或包含括号、逗号、双引号、反斜杠或空格

在字段值中嵌入双引号和反斜杠翻了一倍。

现在引用Nick自己的话:

嵌套元素被转换为字符串,然后加引号/转义像其他字符串

一样

我在下面给出一个简短的例子,与它的嵌套值进行比较:

a=# create table playground (t text, ta text[],f float,fa float[]);
CREATE TABLE
a=# insert into playground select 'space here',array['','bs'],8.0,array[null,8.1];
INSERT 0 1
a=# insert into playground select 'no_space',array[null,'nospace'],9.0,array[9.1,8.0];
INSERT 0 1
a=# select playground,* from playground;
                    playground                     |     t      |       ta       | f |     fa
---------------------------------------------------+------------+----------------+---+------------
 ("space here","{"""",""bs\\""}",8,"{NULL,8.1}") | space here | {"","bs\"}    | 8 | {NULL,8.1}
 (no_space,"{NULL,nospace}",9,"{9.1,8}")           | no_space   | {NULL,nospace} | 9 | {9.1,8}
(2 rows)

如果你需要更深层次的嵌套引号,请看:

a=# select nested,* from (select playground,* from playground) nested;
                                                         nested                                                          |                    playground                     |     t      |       ta       | f |     fa
-------------------------------------------------------------------------------------------------------------------------+---------------------------------------------------+------------+----------------+---+------------
 ("(""space here"",""{"""""""",""""bs\\\\""""}"",8,""{NULL,8.1}"")","space here","{"""",""bs\\""}",8,"{NULL,8.1}") | ("space here","{"""",""bs\\""}",8,"{NULL,8.1}") | space here | {"","bs\"}    | 8 | {NULL,8.1}
 ("(no_space,""{NULL,nospace}"",9,""{9.1,8}"")",no_space,"{NULL,nospace}",9,"{9.1,8}")                                   | (no_space,"{NULL,nospace}",9,"{9.1,8}")           | no_space   | {NULL,nospace} | 9 | {9.1,8}
(2 rows)
如您所见,输出再次遵循上述规则。

对你的问题的简短回答是:

  • 为什么数组通常在双引号内呈现,而一个空数组突然成为一个开放值?(空数组的文本表示不包含逗号或空格等)
  • 为什么一个"突然被呈现为"?('one two'的文本表示,根据上面的规则是"one\ two",最后的文本表示是""one\\two"",这就是你得到的)
  • 为什么unicode格式的文本会改变的转义?那我们怎么分辨呢?(根据文件,

PostgreSQL也接受"转义"字符串常量SQL标准的扩展。指定转义字符串常量在开头写上字母E(大写或小写)单引号

),所以它不是unicode文本,而是您告诉postgres应该将文本中的转义解释为转义而不是符号的方式。例如,E'''将被解释为', '''将使其等待关闭'进行解释。在您的示例E'\ text'中,它的文本表示将是"\ text" -我们为反斜杠添加反斜杠并在双引号中接受值-所有这些都在在线文档中描述。

  • {和}转义的方式并不总是清楚(我无法回答这个问题,因为它本身不清楚)

最新更新