postgres:重载/向域添加比较运算符

发布于 2024-10-11 10:23:02 字数 708 浏览 2 评论 0原文

我有一列应该有 3 个可能的值(例如“A”、“B”、“C”)。 通常使用枚举来处理此类事情,但由于我的数据库中的许多表都会有这样的列,所以我想为类型定义一个默认值(“C”),代表这个枚举。

(AFAIK没有任何额外的定义,我需要写这样的东西:

%COLUMN% %ENUM_TYPE% NOT NULL DEFAULT enum_first(null::%ENUM_TYPE%),

每次我需要这样的枚举)

CREATE TYPE ... 语句不允许定义默认值,但 CREATE DOMAIN ... 可以。

我尝试了一个小技巧:CREATE TYPE zzz_enum AS ENUM (...); CREATE DOMAIN zzz AS zzz_enum DEFAULT 'A';,但比较 %zzz column% = 'A' 进行查询会导致错误:

...operator %zzz% = undefined ...

如何“手动”为域定义比较运算符或创建自定义类型,这将:

  • 拥有一个可能值的列表,我可以通过查询获得
  • 这些值 将其中一个值作为默认值
  • 是一个标识符,我可以像表定义中的任何常规 SQL 类型一样使用它,

提前致谢!

I have a column which should have 3 possible values (for example 'A', 'B', 'C').
It is conventional to use enum for such kind of things, but since many tables in my DB will have such column, I would like to define a default value ('C') for type, representing this enum.

(AFAIK without any additional definitions, I need to write something like this:

%COLUMN% %ENUM_TYPE% NOT NULL DEFAULT enum_first(null::%ENUM_TYPE%),

every time i need such enum)

CREATE TYPE ... statement does not allow to define default value, but CREATE DOMAIN ... does.

I tried a little trick: CREATE TYPE zzz_enum AS ENUM (...); CREATE DOMAIN zzz AS zzz_enum DEFAULT 'A';, but query with comparison of %zzz column% = 'A' results in error:

... operator %zzz% = undefined ...

How can I define comparison operator for domain 'by-hand' or create a custom type, which will:

  • Have a list of possible values, which I could get through query
  • Have one of those values as a default value
  • Be a identifier, which I could use like any regular SQL type in table definition

Thanks in advance!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

总攻大人 2024-10-18 10:23:02

这应该有效,但事实并非如此。我认为这是一个错误。

请关注此处的讨论: http://archives.postgresql.org/pgsql-错误/2011-01/msg00082.php

This ought to work, but it doesn't. I think it's a bug.

Follow the discussion here: http://archives.postgresql.org/pgsql-bugs/2011-01/msg00082.php

踏雪无痕 2024-10-18 10:23:02
CREATE FUNCTION zzz_like (a zzz_enum, b TEXT) RETURNS BOOLEAN
AS
$
        SELECT  $1::TEXT LIKE $2;
$
LANGUAGE 'sql'

CREATE OPERATOR ~~ (LEFTARG=zzz_enum, RIGHTARG=TEXT, PROCEDURE=zzz_like)

SELECT  *
FROM    zzz_test
WHERE   zzz_column LIKE '%A%'

您可以直接在查询中将表达式转换为 TEXT

SELECT  *
FROM    zzz_test
WHERE   zzz_column::TEXT LIKE '%A%'

更新:

抱歉,问题出错了。

正如@Peter提到的,这确实是一个错误,因为像 arrayenum 这样的复杂类型上的域不会隐式转换为 anyarray相应的相等运算符需要anyenum

CREATE FUNCTION zzz_like (a zzz_enum, b TEXT) RETURNS BOOLEAN
AS
$
        SELECT  $1::TEXT LIKE $2;
$
LANGUAGE 'sql'

CREATE OPERATOR ~~ (LEFTARG=zzz_enum, RIGHTARG=TEXT, PROCEDURE=zzz_like)

SELECT  *
FROM    zzz_test
WHERE   zzz_column LIKE '%A%'

You may just cast the expression to TEXT right in your query:

SELECT  *
FROM    zzz_test
WHERE   zzz_column::TEXT LIKE '%A%'

Update:

Sorry, got the problem wrong.

As @Peter mentioned, it's a bug indeed, since domains over complex types like array and enum are not implicitly cast into anyarray and anyenum required for the corresponding equality operators.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文