2016-09-15 45 views
12

是否有描述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)\"\"}\")"}

對於複合類型的多維數組,它變得更加複雜。


UPDATE

由於感覺沒有規範可言,I have started working on reversing it。不知道它是否可以完全完成,因爲from some initial examples通常不清楚應用了什麼格式規則。

+1

問出於好奇 - 你這樣做是因爲需要還是僅僅爲了科學? Postgres中有json和hstore之類的東西。 –

+1

@KamilG。這源於開發人員的實際需求。我也是[pg-promise](https://github.com/vitaly-t/pg-promise)的作者。所以不,這不是學術性的。 –

+1

我不太喜歡。你想知道元組是如何存儲在磁盤上的?或者當輸出爲字符串時,元組的外觀如何?還有別的嗎? –

回答

1

由於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) 

如果你去f或更深的嵌套報價,看看:

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

的Postgres QL也接受「轉義」字符串常量,這是SQL標準的一個 擴展。轉義字符串常量通過寫字母E剛剛開幕 單引號

)之前(大寫或小寫)指定 ,所以它不是Unicode文本,但你告訴Postgres的,它應該的方式將文本中的轉義解釋爲符號,而不是轉義。例如E'\''將被解釋爲''\''將使其等待關閉'進行解釋。在你的例子E'\\ text'中,文本代表的是"\\ text"--我們添加backslsh作爲反斜槓,並用雙引號取值 - 所有這些在聯機文檔中都有描述。

  • 即{和}被轉義的方式並不總是很清楚(我不能ANWER這個問題,因爲它是不明確本身)