PostgreSQL元组格式

时间:2016-09-15 21:17:52

标签: postgresql tuples node-postgres compositetype

是否有任何描述PostgreSQL服务器所遵循的元组格式的文档?关于此,官方文件似乎很神秘。

单个元组似乎很容易理解,但是当涉及元组数组,复合元组数组,以及最后嵌套的复合元组数组时,仅通过查看输出就无法确定格式

我在初次尝试实现pg-tuple(一个今天仍然缺少的解析器)后能够解析Node.js中的PostgreSQL元组

实施例

(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)\"\"}\")"}我们可以获得

NullReferenceException

复合类型的多维数组变得更加复杂。

更新

因为感觉根本没有规范,I have started working on reversing it。不确定它是否可以完全完成,因为from some initial examples通常不清楚应用了哪些格式规则。

1 个答案:

答案 0 :(得分:2)

根据Nick发布了docs

  

如果字段类型是整数,则忽略空格,但不是   如果是文本。

  

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

  

字段值中嵌入的双引号和反斜杠将是   加倍。

现在引用尼克本人:

  

嵌套元素将转换为字符串,然后引用/转义   像任何其他字符串

我给出了下面的简短示例,与其嵌套值进行了比较:

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)

如您所见,输出再次遵循上述规则。

这样,对your questions的简短答案就是:

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

PostgreSQL也接受“转义”字符串常量,这是一个   SQL标准的扩展。指定了转义字符串常量   在开幕前写下字母E(大写或小写)   单引号

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

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