发生这种情况是因为 PostgreSQL 将接受任何类型的表达式(在 INSERT 语句中),其类型可以自动转换为该列的类型(更准确地说,这两种类型之间存在 ASSIGNMENT or IMPLICIT 转换:这就是为什么这些演员表首先存在)。前:
-- lets see what casts exists to boolean & text
-- "castcontext" is 'a' for ASSIGNMENT, 'i' for IMPLICIT and 'e' for EXPLICIT casts
select castsource::regtype::text,
casttarget::regtype::text,
castcontext
from pg_cast
where casttarget in ('boolean'::regtype, 'text'::regtype);
create table foo (
varchar_field varchar,
text_field text,
bool_field boolean
);
-- these are equivalents, because of some casts
insert into foo values ('false', 'false', 'false');
insert into foo values (false, false, false);
-- this will throw an error
insert into foo values (0, 0, 0);
好吧,我作弊了一点。有一种特殊情况。当你写一个 string 文字(如'false')时,它有一个unknown 类型。未知值总是传递给实际列类型的input function。真正的text 类型文字看起来有点不同:text 'false'。如果再次查看 PostgreSQL 提供的默认转换,您会发现从 text 到 boolean 没有转换。这就是最后一条语句失败的原因:
insert into foo values (text 'false', text 'false', text 'false');
SQLFiddle
编辑:所以,默认情况下,有一个从boolean 到text 的ASSIGNMENT 转换(character varying 也有一个)。这就是为什么您的表的 text_field 接受布尔输入。