Как установить массив составного типа, содержащий элементы JSONB с литеральным значением? - PullRequest
0 голосов
/ 27 февраля 2019

У меня есть этот тип:

CREATE TYPE public.user_type AS (
    text_1 VARCHAR(512),
    text_2 VARCHAR(1000),
    jsonb_1 JSONB,
    jsonb_2 JSONB
);

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

SQL Error [22P02]: ERROR: malformed array literal: "{{"(text 1,text 2,{"key_1":"value_1"},{"key_2":"value_2"})"}"
  Detail: Unexpected array element.
  Where: PL/pgSQL function inline_code_block line 4 during statement block local variable initialization

с этим фрагментом:

DO $$
DECLARE
    user_type public.user_type[] = '{{"(text 1,text 2,{"key_1":"value_1"},{"key_2":"value_2"})"}';
BEGIN
END $$;

Как сформировать буквенную строку, чтобы установить этот составнойтип?

Для других модульных тестов я могу объявить составные типы без элементов JSONB и установить их с литеральными значениями.Например, это работает:

Для этого типа:

CREATE TYPE public.user_type_2 AS (
    text_1 VARCHAR(512),
    text_2 VARCHAR(1000)
);

Этот фрагмент будет возвращать несколько строк:

DO $$
DECLARE
    user_type_2 public.user_type_2[] = '{{"(string_1a,string_1b)"},{"(string_2a,string_2b)"}}';
BEGIN
     DROP TABLE IF EXISTS _results;
     CREATE TEMPORARY TABLE _results AS  
     SELECT * FROM UNNEST(user_type_2) x (text_1, text_2);
END $$;

SELECT * FROM _results;

, как и следовало ожидать

+-----------+-----------+
|  text_1   |  text_2   |
+-----------+-----------+
| string_1a | string_1b |
| string_2a | string_2b |
+-----------+-----------+

1 Ответ

0 голосов
/ 27 февраля 2019

Для этого необходимо использовать несколько уровней экранирования:

  • Элемент массива должен быть окружен ", поскольку он содержит ,, { и }.

  • Каждый из " внутри элемента массива должен быть экранирован до \".

  • Элементы JSON всоставной тип должен быть окружен " (теперь \"), потому что он содержит ,.

  • . " для строк JSON необходимо удвоить, чтобы избежать" из предыдущего пункта, поэтому они в конечном итоге станут \"\".

Ваше задание может выглядеть следующим образом:

user_type public.user_type[] := '{"(text 1,text 2,\"{\"\"key_1\"\": \"\"value_1\"\"}\",\"{\"\"key_2\"\": \"\"value_2\"\"}\")"}';

Фу.

...