我最近通过将更复杂的数据类型转换为更简单的数据类型来优化我们的一些Postgres表。在目前为止除了一个案例之外的每一个案例中,这都是相当简单的,例如:
ALTER TABLE products ALTER COLUMN price TYPE integer USING price::integer;
为了将文本转换为自定义枚举数据类型,这也很简单。我刚刚编写了一个PLPGSQL函数,它将文本转换为枚举,然后像这样转换列:
ALTER TABLE products ALTER COLUMN color TYPE color_enum USING text_to_color_enum(color);
在我必须将整数转换为布尔值的情况下,此语法失败。这些都失败了:
ALTER TABLE products ALTER return_policy TYPE boolean USING return_policy > 0;
ALTER TABLE products ALTER return_policy TYPE boolean USING bool(return_policy);
ALTER TABLE products ALTER COLUMN return_policy TYPE boolean USING bool(return_policy);
ALTER TABLE products ALTER COLUMN return_policy TYPE boolean USING CASE WHEN return_policy <> 0 THEN TRUE ELSE FALSE END;
错误消息始终相同:
ERROR: operator does not exist: boolean = integer
HINT: No operator matches the given name and argument type(s). You might need to add explicit type casts.
该列中没有空值。所有值均为零或正数。 SELECT pg_typeof(return_policy) FROM products LIMIT 1;
返回integer
。从整数到布尔值创建自定义强制转换失败,因为显然已存在一个。在Postgres 9.4和9.5中也发生了同样的事情。我在这里做错了什么?
答案 0 :(得分:3)
验证列是否为约束,如果是,则需要在更改类型之前删除约束。
ALTER TABLE products ALTER COLUMN price DROP DEFAULT;
ALTER TABLE products ALTER price TYPE bool USING CASE WHEN price = 0 THEN FALSE ELSE TRUE END;
ALTER TABLE products ALTER COLUMN price SET DEFAULT FALSE;
答案 1 :(得分:1)
我的一个部分索引的条件为Hashes
。 (这个数字应该是退货政策的天数,但由于我们要求所有的一切都没有退货政策或30天的退货政策,因此它不是一个有意义的int。删除索引允许我的原始SQL代码正确运行。