PostgreSQL双表结构工作不正常

PostgreSQL双表结构工作不正常,postgresql,check-constraints,Postgresql,Check Constraints,我运行以下代码: -- Table describing messages CREATE TABLE messages ( id serial PRIMARY KEY NOT NULL, text TEXT -- Message can have or not have text ); -- Table describing media attached to messages CREATE TABLE messages_attachments ( message_id integer

我运行以下代码:

-- Table describing messages
CREATE TABLE messages
(
 id serial PRIMARY KEY NOT NULL,
 text TEXT  -- Message can have or not have text
);

-- Table describing media attached to messages
CREATE TABLE messages_attachments
(
 message_id integer NOT NULL REFERENCES messages,
 -- Messages can have any number of attachments, including 0
 attachment_id TEXT NOT NULL
);

-- Messages must have either text or at least one attachment
CREATE FUNCTION message_has_text_or_attachments(integer) RETURNS bool STABLE
AS
$$
 SELECT
  EXISTS(SELECT 1 FROM messages_attachments WHERE message_id = $1)
 OR
  (SELECT text IS NOT NULL FROM messages WHERE id = $1);
$$ LANGUAGE SQL;

ALTER TABLE messages ADD CONSTRAINT nonempty_message CHECK ( message_has_text_or_attachments(id) );

-- Insert a message with no text and no attachments. Should fail, but it does not
INSERT INTO messages(text) VALUES (NULL);

SELECT *, message_has_text_or_attachments(id) FROM messages;
我希望它在
INSERT
行失败,因为插入的行违反了检查约束(我们正在插入一条文本为
NULL
且该消息没有附件的消息),但它成功运行,下一个查询返回(
1
NULL
false
)(这是一个略加修改的函数定义(由于数据库版本的原因,用撇号代替美元符号)

更有趣的是,如果在添加
约束之前更改命令的顺序并
插入
行,则PostgreSQL无法
更改
表,因为某些行违反了“
检查约束”非空消息”

为什么PostgreSQL允许插入违反约束的行?我在函数定义中的某个地方弄错了吗?在如何应用约束以及它们可以依赖哪些表方面是否存在一些限制?这是PostgreSQL错误吗?

来自:

PostgreSQL不支持引用被检查的新行或更新行以外的表数据的检查约束。尽管违反此规则的检查约束可能在简单测试中有效,但它不能保证数据库不会达到约束条件为false的状态(由于涉及的其他行的后续更改)