Подтвердить что ты не робот

Формат кортежа PostgreSQL

Есть ли какой-либо документ, описывающий формат кортежа, который придерживается сервер PostgreSQL? Официальная документация выглядит тайной об этом.

Один кортеж кажется достаточно простым, чтобы понять, но когда дело доходит до массивов кортежей, массивов составных кортежей и, наконец, вложенных массивов составных кортежей, невозможно быть уверенным в этом формате, просто взглянув на вывод.

Я прошу об этом после моей первоначальной попытки реализовать pg-tuple анализатор, который до сих пор отсутствует, чтобы иметь возможность анализировать кортежи PostgreSQL в Node. JS


<сильные > Примеры

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

Поскольку кажется, что вообще нет спецификации, Я начал работать над обращением его. Не уверен, что это можно сделать полностью, потому что из некоторых исходных примеров часто неясно, какие правила форматирования применяются.

4b9b3361

Ответ 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)

Если вы идете на более глубокое вложенное цитирование, посмотрите:

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 изменяет экранирование для \? Как мы можем тогда сказать разницу? (Согласно docs,

PostgreSQL также принимает "escape" строковые константы, которые являются расширение стандарта SQL. Указана константа escape-строки написав букву E (верхний или нижний регистр) непосредственно перед открытием одиночная кавычка

), так что это не текст в Юникоде, а способ, которым вы указываете postgres, что он должен интерпретировать escape файлы в тексте не как символы, а как escape-последовательности. Например, E'\'' будет интерпретироваться как ' и '\'' заставит его ждать закрытия ' для интерпретации. В вашем примере E'\\ text' текст представляет собой "\\ text" - мы добавляем backslsh для обратной косой черты и принимаем значение в двойных кавычках - все, как описано в онлайн-документах.

  • способ, которым экранируются {и}, не всегда ясен (я не мог ответить на этот вопрос, потому что он не был ясен сам)