Динамическая передача типа строки в jsonb_populate_recordset - PullRequest
0 голосов
/ 18 октября 2019

Я работаю над кодом для раскрутки данных, упакованных в JSONB с обычным форматом для передачи в другую систему.

- Postgres 11.4.
- Формат JSON известен заранее, он указан в записи.
- У меня есть определенный тип для формата JSON.

Вот урезанная промежуточная таблица:

CREATE TABLE IF NOT EXISTS data.domo_passthrough (
    id           uuid NOT NULL DEFAULT extensions.gen_random_uuid (),
    type_name    text NOT NULL DEFAULT NULL, 
    report_data  jsonb NOT NULL DEFAULT '{}',

CONSTRAINT domo_passthrough_id_pkey
    PRIMARY KEY (id)
);

Поле report_data содержит упакованные данные, поле type_name включает название формата, например, это:

create type data.table_stats_type as (
    table_name text, 
    record_count integer,
    table_number integer)

Этот код работает правильно, чтобы распаковать данные в три столбца, определенных в типе:

select expanded_data.*
  from domo_passthrough,
       jsonb_populate_recordset(null::table_stats_type, report_data) as expanded_data;

Что я хотел бы сделать, если это возможно, это передать имя-типав качестве аргумента jsonb_populate_recordset:

select expanded_data.*
  from domo_passthrough,
       jsonb_populate_recordset(null::type_name, report_data) as expanded_data;

Это не работает, а null::type_name возвращает ошибку:

ERROR:  type "type_name" does not exist
LINE 3:        jsonb_populate_recordset(null::type_name, report_data..

Справедливо. Тип_имя - это текст, а не литерал. Я надеюсь, что есть хороший способ сделать то, что я после. (Я понимаю, что в данный момент мне нужно не испортить присвоения имен типов в данных.) Возможности:

- какая-то операция ::casting, но я не могу понять, какой типЯ бы использовал от null:: до type_name. Я нашел функцию pg_typeof, но не вижу способа применить ее для построения кода.

- Динамический SQL в функции. Кажется, это возможно, но я надеюсь на что-то более простое.

- Некоторые другие функции или опции, о которых я не знаю.

ВОЗВРАТ НАСТРОЙКИ Функция?

Спасибо за комментарий, я подумал, что попробую написать функцию ... и я был озадачен. Всегда сложно получить динамические результаты из SQL. Я не жалуюсь на это ... но это один раз, когда я хотел бы иметь обобщенный инструмент. Это звучит так, как будто RETURN SETOF RECORD должно работать, но у меня ничего не получилось. Я просмотрел несколько тем и документов, но я все еще в тупике. Вот функция PG / pgSQL, так как я не смог заставить работать версию на чистом SQL:

DROP FUNCTION IF EXISTS api.domo_passthrough_expand (text, jsonb);
CREATE FUNCTION api.domo_passthrough_expand(type_name text, packed_data jsonb) 
    RETURNS SETOF record AS
$BODY$
BEGIN

    RETURN QUERY EXECUTE FORMAT
   'select *
      from jsonb_populate_recordset(null::%1$I, %2$I) as expanded_data;',
           type_name,
           packed_data;
END;
$BODY$
LANGUAGE plpgsql;

ALTER FUNCTION api.domo_passthrough_expand(text, jsonb) OWNER TO user_bender;

select expanded.* 

  from domo_passthrough,
        domo_passthrough_expand(domo_passthrough.type_name,domo_passthrough.report_data)

ERROR:  a column definition list is required for functions returning "record"
LINE 4:      domo_passthrough_expand(domo_passthrough.type_name,domo...

Есть ли способ сделать мое расширение в общем случае с помощью функции? Если нет, я могу подходить к чему-то другому, но я бы предпочел, чтобы все было на стороне Postgres.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...