2016-09-15 2 views
12

Gibt es ein Dokument, das das Tupelformat beschreibt, dem der PostgreSQL-Server folgt? Die offizielle Dokumentation scheint dazu geheimnisvoll. Ein einzelnes Tupel scheint einfach genug zu sein, um es herauszufinden, aber wenn es um Tupelarrays, Arrays aus zusammengesetzten Tupeln und schließlich verschachtelte Arrays aus zusammengesetzten Tupeln geht, ist es unmöglich, sich über das Format zu vergewissern, indem man einfach auf das Symbol guckt Ausgabe.PostgreSQL-Tupelformat

ich diese bei der Umsetzung pg-tuple nach meinem ersten Versuch bin zu fragen, ein Parser, der heute noch fehlt ist, in der Lage sein PostgreSQL Tupel innerhalb Node.js


Beispiele

create type type_A as (
    a int, 
    b text 
); 
zu analysieren
  • mit einem einfachen Text: (1,hello)
  • mit einem komplexen Text: (1,"hello world!")

create type type_B as (
    c type_A, 
    d type_A[] 
); 
  • simple-Wert-Array: {"(2,two)","(3,three)"}

  • für type_B[] können wir erhalten:

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

Es wird noch komplexer für mehrdimensionale Arrays von Composite-Typen.


UPDATE

Da fühlt es sich wie keine Angabe überhaupt gibt, I have started working on reversing it. Nicht sicher, ob es vollständig durchgeführt werden kann, denn from some initial examples ist oft unklar, welche Formatierungsregeln angewendet werden.

+1

aus Vorstellung Neugier - werden Sie es tun, weil von der Notwendigkeit oder nur für die Wissenschaft? Es gibt Dinge wie json und hstore in Postgres. –

+1

@KamilG. Dies ergibt sich aus den praktischen Bedürfnissen der Entwicklergemeinschaft. Ich bin auch der Autor von [pg-promise] (https://github.com/vitaly-t/pg-promise). Also nein, es ist nicht akademisch. –

+1

Ich verstehe das nicht ganz. Möchten Sie wissen, wie Tupel auf der Festplatte gespeichert sind? Oder wie sieht ein Tupel bei der Ausgabe als String aus? Etwas anderes? –

Antwort

1

Wie Nick geschrieben, nach docs:

das Leerzeichen, wenn das Feld Typ integer ignoriert werden, aber nicht wenn es Text ist.

und

Die zusammengesetzte Ausgaberoutine wird doppelte Anführungszeichen um Feld Werte setzen, wenn sie leere Strings sind oder enthalten Klammern, Kommas, doppelte Anführungszeichen, Schrägstriche oder weißen Raum.

und

doppelte Anführungszeichen und Schrägstriche in Feldwerte eingebettet werden verdoppelt.

und jetzt zitierte Nick selbst:

verschachtelte Elemente in Strings umgewandelt und dann zitierten/ wie jede andere Zeichenfolge entkam

I kurzgeschlossen Beispiel geben unten, bequem verglichen seine verschachtelten Wert:

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) 

Wenn Sie gehen f oder tiefer verschachtelten zitieren, schauen:

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) 

Wie Sie sehen können, wieder die Ausgabe folgt die oben genannten Regeln.

diese Weise in kurzen Antworten auf your questions wäre:

  • warum Array normalerweise in Anführungszeichen dargestellt wird, während ein leeres Array plötzlich ein offener Wert ist? (Textdarstellung Leer-Anordnung enthält nicht Komma oder Leerzeichen oder usw.)
  • warum eine einzelne "? (Textdarstellung 'one\ two'„plötzlich, wie \ präsentiert wird“, oben nach Regeln ist "one\\ two" und Textdarstellung der letzte ist ""one\\\\two"" und es ist genau das, was Sie erhalten)
  • warum Unicode-formatierten Text für \ das entweichende verändert? Wie können wir den Unterschied dann sagen? (nach docs,

PostgreS QL akzeptiert auch "Escape" -String-Konstanten, die eine Erweiterung zum SQL-Standard sind. Eine Escape-String-Konstante ist angegeben durch den Buchstaben E (Groß- oder Kleinschreibung) Schreiben kurz vor der Eröffnung Apostroph

), so ist es nicht Unicode-Text, aber die so, wie Sie Postgres sagen, dass es sein sollte interpretieren entgeht im Text nicht als Symbole, sondern als Fluchten. ZB E'\'' wird als ' interpretiert und '\'' wird warten, bis der Abschluss ' interpretiert wird. In Ihrem Beispiel E'\\ text' der Text davon wird "\\ text" sein - wir fügen Backslsh für Backslash und nehmen Wert in Anführungszeichen - alle wie in Online-Dokumenten beschrieben.

  • die Art und Weise, dass {und} entkommen sind, ist nicht immer klar (ich diese Frage nicht anwer konnte, weil nicht klar selbst war)