Проблемы с разделением postgresql-11 и автоинкрементом первичного ключа - PullRequest
0 голосов
/ 23 октября 2019

Первичный ключ в многораздельных таблицах увеличивается на n (n> 1), а не на 1.

Попытка переписать plpgsql различными способами безуспешно. Должно быть что-то, чего я не понимаю.

CREATE SCHEMA IF NOT EXISTS some_record_pool;

CREATE SEQUENCE some_record_pkey_seq;

create table some_record
(
    id BIGINT not null DEFAULT nextval('some_record_pkey_seq'::regclass),
    device_id bigint,
    device_type bigint,
    record_time timestamp,
    module_serial_number bigint,
    module_id bigint,
    message_type bigint,
    event_code bigint,
    device_status bytea,
    sequence_number bigint,
    data_bytes bigint,
    device_data bytea,
    active boolean,
    deleted boolean,
    created_time timestamp default now() not null,
    created_on timestamp with time zone default now() not null,
    updated_on timestamp with time zone default now() not null
);


CREATE INDEX idx_device_id
    ON public.some_record USING brin
    (device_id)
    TABLESPACE pg_default;

CREATE INDEX idx_module_id
    ON public.some_record USING brin
    (module_id)
    TABLESPACE pg_default;

CREATE INDEX idx_er_created_time
    ON public.some_record (cast(created_time as DATE));

----- CREATE TRIGGER ----------
CREATE OR REPLACE FUNCTION some_record_insert_function()
    RETURNS TRIGGER AS
$$
DECLARE
    partition_date    TEXT;
    partition_name    TEXT;
    start_of_month    TEXT;
    end_of_next_month TEXT;
BEGIN
    partition_date := to_char(NEW.created_time, 'YYYY_MM');
    partition_name := 'some_record_' || partition_date;
    start_of_month := to_char((NEW.created_time), 'YYYY-MM') || '-01';
    end_of_next_month := to_char((NEW.created_time + interval '1 month'), 'YYYY-MM') || '-01';
    IF NOT EXISTS
        (SELECT 1
         FROM information_schema.tables
         WHERE table_name = partition_name)
    THEN
        RAISE NOTICE 'A partition has been created %', partition_name;
        EXECUTE format(
                E'CREATE TABLE some_record_pool.%I ' ||
                E'(CHECK ( date_trunc(\'day\', created_time) >= ''%s'' ' ||
                E'AND date_trunc(\'day\', created_time) < ''%s'')) INHERITS (public.some_record)',
                partition_name, start_of_month, end_of_next_month);
        -- EXECUTE format('GRANT SELECT ON TABLE %I TO readonly',
        -- partition_name); -- use this if you use role based permission
    ELSE
        RAISE NOTICE 'A partition DOES NOT EXIST %', partition_name;
    END IF;
    EXECUTE format(
            'INSERT INTO some_record_pool.%I (device_id, device_type, ' ||
            'record_time, module_serial_number, module_id, message_type, ' ||
            'event_code, device_status, sequence_number, data_bytes, device_data,' ||
            ' active, deleted) VALUES($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13)',
            partition_name) using NEW.device_id, NEW.device_type,
        NEW.record_time, NEW.module_serial_number, NEW.module_id, NEW.message_type,
        NEW.event_code, NEW.device_status, NEW.sequence_number, NEW.data_bytes,
                NEW.device_data, NEW.active, NEW.deleted;
    RETURN NEW;
END
$$
    LANGUAGE plpgsql;


CREATE TRIGGER insert_some_record_trigger
    BEFORE INSERT ON public.some_record
    FOR EACH ROW EXECUTE PROCEDURE public.some_record_insert_function();

--- INSERTING DATA FOR TESTING

INSERT INTO some_record (
    event_record_id, timestamp, event_description_id, event_source_label, event_source_track, event_source_direction, 
    measurement_description, measurement_value, hw_address_module_id, hw_address_rlc_address, sub_system_source, 
    event_type, device_id, active, deleted) VALUES(1, 2, to_timestamp('1953-10-21 14:30:46.555337', 'YYYY-MM-DD HH:MI:SS.US'), 1, 1, 1, 1, NULL, 1, 9, E'9 B
00000000  92 FF 3C 00 7F 00 00 03 E8                         .ÿ<.....è
', TRUE, FALSE, to_timestamp('2019-10-21 14:30:46.555337', 'YYYY-MM-DD HH:MI:SS.US'), to_timestamp('2019-10-21 14:30:46.555337', 'YYYY-MM-DD HH:MI:SS.US'));

Смысл кода в том, чтобы автоматически создавать разделы и вставлять данные, если раздел существует.

Первичный ключ должен быть увеличен на единицу, но этоне ведет себя так, как ожидаемый результат только за один прогон является id: 1

...