kei*_*rth 9 postgresql datatypes cast operator uuid
我有一个相当复杂的 Postgres 数据库,其中许多 UUID 字段被错误地存储为 VARCHAR。我想逐步迁移它们,但不幸的是,这样做打破了我的所有观点,因为 Postgres 没有内置的varchar = uuid
. 而是重写我的所有视图或尝试一次大规模迁移,我想临时创建一个 uuid = varchar 运算符,直到迁移完成。
我以前从未创建过自定义运算符,并且我在下面的尝试不起作用:
CREATE OR REPLACE FUNCTION uuid_equal_varchar (varchar, uuid)
RETURNS boolean AS 'SELECT $1::text = $2::text;' LANGUAGE sql IMMUTABLE;
CREATE OPERATOR = (
leftarg = character varying,
rightarg = uuid,
procedure = uuid_equal_varchar,
commutator = =
);
Run Code Online (Sandbox Code Playgroud)
然而,这个运营商打破了一切。包括一个简单的 varchar = varchar 比较(见下文):
SELECT * FROM test WHERE pk_test = '123';
ERROR: invalid input syntax for uuid: "123"
Run Code Online (Sandbox Code Playgroud)
有人可以向我解释我做错了什么吗?我是否试图尝试不可能的事情?
Eva*_*oll 10
你要做的CREATE CAST
不是运营商。这就是问题:
SELECT pg_typeof(uuid), uuid = uuid::varchar AS eq
FROM gen_random_uuid() AS t(uuid);
ERROR: operator does not exist: uuid = character varying
LINE 1: SELECT pg_typeof(uuid), uuid = uuid::varchar FROM gen_random...
^
HINT: No operator matches the given name and argument type(s). You might need to add explicit type casts.
Run Code Online (Sandbox Code Playgroud)
所以我们需要创建一个CAST
. 这会在需要时将 varchar 提升为 uuid。虽然如果你真的想要,你可以走另一条路。如果您这样做,您需要创建演员表(uuid AS 文本)。类型系统不知道 varchar:我们在 PostgreSQL 中不使用它;它本质text
上具有类型无关紧要的长度约束,因此速度较慢。
CREATE CAST (varchar AS uuid)
WITH INOUT
AS IMPLICIT;
Run Code Online (Sandbox Code Playgroud)
现在你可以再试一次。
pg_typeof | eq
-----------+----------
uuid | t
(1 row)
Run Code Online (Sandbox Code Playgroud)
以供参考,
IMPLICIT
表示可以在任何上下文中隐式调用强制转换。
INOUT
表示转换为 I/O 转换转换,通过调用源数据类型的输出函数,并将结果字符串传递给目标数据类型的输入函数来执行。
也就是说,当底层类型发生变化时,所有的视图都必须重新创建,
CREATE TABLE foo(uuid)
AS
VALUES (gen_random_uuid()::varchar);
CREATE VIEW bar AS TABLE foo;
Run Code Online (Sandbox Code Playgroud)
现在我们尝试改变类型 foo
ALTER TABLE foo
ALTER uuid
SET DATA TYPE uuid;
ERROR: cannot alter type of a column used by a view or rule
DETAIL: rule _RETURN on view bar depends on column "uuid"
Run Code Online (Sandbox Code Playgroud)
那失败了,所以我们放弃bar
更改类型并重新创建它,
BEGIN;
DROP VIEW bar;
ALTER TABLE foo ALTER uuid SET DATA TYPE uuid;
CREATE VIEW bar AS TABLE foo;
COMMIT;
Run Code Online (Sandbox Code Playgroud)
我们有快乐。
\d bar;
View "public.bar"
Column | Type | Modifiers
--------+------+-----------
uuid | uuid |
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
29464 次 |
最近记录: |