Построение литерала массива в качестве ввода для функции PL / pg SQL - PullRequest
1 голос
/ 13 марта 2020

Как массив с элементами составного типа должен быть включен в вызов функции?

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

Тип

CREATE TYPE jobs_v0.insertable_program AS (
       handle text,
       zip bytea
);

Таблицы

CREATE TABLE jobs_v0.jobs (
       id bigserial PRIMARY KEY NOT NULL,
       manifest_cid text NOT NULL,
       created_at timestamp NOT NULL DEFAULT now()
);

CREATE TABLE jobs_v0.programs (
       id bigserial PRIMARY KEY NOT NULL,
       job bigserial REFERENCES jobs_v0.jobs(id) NOT NULL,
       handle text NOT NULL,
       package bytea NOT NULL
);

Функция:

CREATE OR REPLACE FUNCTION jobs_v0.insert_job(
       manifest_cid text,
       programs jobs_v0.insertable_program[]
) RETURNS void AS
$$
DECLARE
       job_id jobs_v0.jobs.id%TYPE;
       program jobs_v0.insertable_program;
       inserted_programs jobs_v0.programs[];
BEGIN
       -- Insert job
       INSERT INTO jobs_v0.jobs(manifest_cid) VALUES (manifest_cid)
       RETURNING id INTO job_id;

       -- Insert programs
       INSERT INTO jobs_v0.programs(job, handle, package)
       SELECT job_id, * FROM unnest(programs)
       RETURNING * INTO inserted_programs;
END;
$$ LANGUAGE plpgsql;

Попытки выполнения и ошибки:

select jobs_v0.insert_job('QmTXzATwNfgGVukV1fX2T6xw9f6LAYRVWpsdXyRWzUR2H9', '{"(main, 0xdeadbeef)"}'::jobs_v0.insertable_program[]);
ERROR:  malformed array literal: "12"
DETAIL:  Array value must start with "{" or dimension information.
CONTEXT:  PL/pgSQL function jobs_v0.insert_job(text,jobs_v0.insertable_program[]) line 12 at SQL statement

---

select jobs_v0.insert_job('QmTXzATwNfgGVukV1fX2T6xw9f6LAYRVWpsdXyRWzUR2H9', array[row('main', E'\\xdeadbeef')]::jobs_v0.insertable_program[]);
ERROR:  malformed array literal: "13"
DETAIL:  Array value must start with "{" or dimension information.


1 Ответ

2 голосов
/ 13 марта 2020

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

select jobs_v0.insert_job(
          'QmTXzATwNfgGVukV1fX2T6xw9f6LAYRVWpsdXyRWzUR2H9',
          '{"(main,\"\\\\xdeadbeef\")"}'
       );

Но ошибка заключается в коде функции:

INSERT INTO jobs_v0.programs(job, handle, package)
SELECT job_id, * FROM unnest(programs)
RETURNING * INTO inserted_programs;

* в RETRUNING * относится ко всем столбцы jobs_v0.programs, не для всех столбцов jobs_v0.insertable_program, как вы, вероятно, ожидаете.

Кроме того, inserted_programs не может иметь тип массива, это должно быть типа jobs_v0.insertable_program и может содержать только один результат. Если INSERT вставит несколько строк, будет возвращена только первая.

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