PostgreSQL транзакционный DDL и to_regclass

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

Ожидается ли такое поведение? Или это ошибка?

подробность

Вот краткий пример, где это идет не так:

begin;
create schema test;
create table test.test ( id serial, category integer );

create or replace function test.test_insert () returns trigger as $$
declare
    child_table_name text;
    table_id     text;
begin
    child_table_name = concat('test.test_', text(new.category));
    table_id = to_regclass(child_table_name::cstring);
    if table_id is null then
        execute format('create table %I ( primary key (id), check ( category = %L ) ) inherits (test.test)', child_table_name, new.category);
    end if;
    execute format ('insert into %I values ($1.*)', child_table_name) using new;
    return null;
end;
$$ language plpgsql;

create trigger test_insert before insert on test.test for each row execute procedure test.test_insert();

insert into test.test (category) values (1);
insert into test.test (category) values (1);
insert into test.test (category) values (1);
commit;

1 ответ

Решение

Вы используете %I неверный спецификатор формата.

Если ваша категория 1тогда вы в итоге звоните to_regclass('test.test_1')то есть проверка таблицы test_1 в схеме test,

Тем не мение, format('create table %I', 'test.test_1') будет обрабатывать аргумент формата как один идентификатор и указывать его соответствующим образом, вычисляя 'create table "test.test_1"', Это создаст таблицу с именем "test.test_1" в вашей схеме по умолчанию (вероятно, public).

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

child_table_name = format('test.%I', 'test_' || new.category);

... и при построении строк SQL, просто замените это значение напрямую (т.е. %s скорее, чем %I).

Другие вопросы по тегам