postgres在bigint bug上分区表外键

时间:2015-04-16 09:27:56

标签: postgresql foreign-keys partitioning

我有一个按日期分区的表格,带有一个bigint主键,并有另一个表引用这个主键,但当我尝试插入一个我知道的值在分区表中时,约束会出现:

ERROR: insert or update on table "partition_test_2" violates foreign key constraint "partition_test_2_record_id_fkey"
SQL state: 23503
Detail: Key (record_id)=(2315648946516) is not present in table "partition_test".

以下是复制问题的脚本:

--DROP TRIGGER insert_partition_test_trigger ON temp.partition_test;
DROP TABLE IF EXISTS temp.partition_test_y2015m1;
DROP TABLE IF EXISTS temp.partition_test_y2015m2;
DROP TABLE IF EXISTS temp.partition_test_y2015m3;
DROP TABLE IF EXISTS temp.partition_test_y2015m4;
DROP TABLE IF EXISTS temp.partition_test_2;
DROP TABLE IF EXISTS temp.partition_test;

CREATE TABLE temp.partition_test
(
    record_id bigint PRIMARY KEY,
    date date,
    units integer
);

CREATE TABLE temp.partition_test_y2015m1 (CHECK(date >= '2015-01-01' AND date < '2015-02-01')) INHERITS (temp.partition_test);
CREATE TABLE temp.partition_test_y2015m2 (CHECK(date >= '2015-02-01' AND date < '2015-03-01')) INHERITS (temp.partition_test);
CREATE TABLE temp.partition_test_y2015m3 (CHECK(date >= '2015-03-01' AND date < '2015-04-01')) INHERITS (temp.partition_test);
CREATE TABLE temp.partition_test_y2015m4 (CHECK(date >= '2015-04-01' AND date < '2015-05-01')) INHERITS (temp.partition_test);

CREATE INDEX partition_test_y2015m1_date ON temp.partition_test_y2015m1(date);
CREATE INDEX partition_test_y2015m2_date ON temp.partition_test_y2015m2(date);
CREATE INDEX partition_test_y2015m3_date ON temp.partition_test_y2015m3(date);
CREATE INDEX partition_test_y2015m4_date ON temp.partition_test_y2015m4(date);

CREATE OR REPLACE FUNCTION partition_test_insert_trigger()
RETURNS TRIGGER AS $$
BEGIN
    IF new.date >= '2015-01-01' AND new.date < '2015-02-01' THEN
        INSERT INTO temp.partition_test_y2015m1 VALUES (NEW.*);
    ELSIF new.date >= '2015-02-01' AND new.date < '2015-03-01' THEN
        INSERT INTO temp.partition_test_y2015m2 VALUES (NEW.*);
    ELSIF new.date >= '2015-03-01' AND new.date < '2015-04-01' THEN
        INSERT INTO temp.partition_test_y2015m3 VALUES (NEW.*);
    ELSIF new.date >= '2015-04-01' AND new.date < '2015-05-01' THEN
        INSERT INTO temp.partition_test_y2015m4 VALUES (NEW.*);
    ELSE
        RAISE EXCEPTION 'Date out of range. Fix the partition_test_insert_trigger() function!';
    END IF;
    RETURN NULL;
END;
$$
LANGUAGE plpgsql;

CREATE TRIGGER insert_partition_test_trigger
    BEFORE INSERT ON temp.partition_test
    FOR EACH ROW EXECUTE PROCEDURE partition_test_insert_trigger();

INSERT INTO temp.partition_test (record_id, date, units) VALUES
(2315648946516,'2015-01-15', 12),
(5684621651651,'2015-02-04',54),
(5665655115778,'2015-03-19',2),
(6532322558877,'2015-04-25',68);

CREATE TABLE temp.partition_test_2
(
    record_id bigint REFERENCES temp.partition_test(record_id),
    price_type_id smallint,
    price numeric,
    PRIMARY KEY (record_id, price_type_id)
);
INSERT INTO temp.partition_test_2(record_id, price_type_id, price) VALUES 
(2315648946516, 1, 100.25),
(2315648946516, 2, 100.25),
(5684621651651, 1, 100.25),
(5684621651651, 2, 100.25),
(5665655115778, 1, 100.25),
(5665655115778, 2, 100.25),
(6532322558877, 1, 100.25),
(6532322558877, 2, 100.25);

-- SELECT * FROM temp.partition_test WHERE record_id = 2315648946516;

这是Postgres中的一个错误,是不是可以做到?或者我做错了什么?

1 个答案:

答案 0 :(得分:0)

正如上面的评论所说:

“继承功能的一个严重限制是索引(包括唯一约束)和外键约束仅适用于单个表,而不适用于它们的继承子”

非常感谢,我觉得这应该是以后版本中实现的功能。