Postgres定制运营商优先于内置?

时间:2016-09-26 06:33:42

标签: postgresql jsonb

我最近写了一篇关于为PostgreSQL的JSONB类型创建自定义减号运算符的blog post

基本上,运算符是这样创建的:

CREATE OPERATOR - (
    PROCEDURE = jsonb_minus,
    LEFTARG   = jsonb,
    RIGHTARG  = jsonb )

但是,正如评论者正确指出的那样,在创建此运算符之后,默认的JSONB - TEXT不再起作用。此查询会导致错误:

SELECT '{"a":1, "b":{"c":123, "d":"test"}}'::jsonb - 'a'

结果为invalid input syntax for type json。您必须将第二个参数显式地转换为TEXT才能使其正常工作。

删除自定义运算符后,将恢复正常行为,上面的查询会显示所需的结果:{"b": {"c": 123, "d": "test"}}

为什么Postgres会在未指定显式类型时尝试通过默认TEXT转换为JSONB?我可以避免这个吗?

1 个答案:

答案 0 :(得分:4)

由于文档中描述的operator type resolution rules而定义运算符时会出现问题。

在您给出的示例中,-运算符的参数具有类型jsonb(左参数)和unknown(右参数)。 PostgreSQL的类型unknown是分配给string literals的类型。

现在,如果定义了自定义运算符,则运算符类型解析在步骤2.a。中选择运算符:

  
      
  1. 检查操作员是否完全接受输入参数类型。如果存在(在所考虑的运算符集中只能有一个完全匹配),请使用它。

         

    一个。如果二元运算符调用的一个参数是unknown类型,则假设它与此检查的另一个参数类型相同。涉及两个unknown输入或带有unknown输入的一元运算符的调用在此步骤中永远不会找到匹配项。

  2.   

因此,unknown参数'a'将转换为jsonb,这会导致您发现错误。