代码之家  ›  专栏  ›  技术社区  ›  Peter Krauss

是否可以使用子类型重载配置函数?

  •  2
  • Peter Krauss  · 技术社区  · 6 年前

    使用时 CREATE TABLE 可以申报 varchar(12) , varchar(34) varchar


    我认为忽视是一件好事 函数签名 function overloading ,而“子类型签名”将是一个混乱的东西来管理。。。但我在指南中没有看到(也没有看到) typeconv-func ),没有向导的警告,没有解释。

    所以,现在,2018年,在所有的PostgreSQL v10+增强之后。。。 我可以配置PostgreSQL接受子类型的函数重载吗?


    具体例子

    CREATE TABLE foo ( x  varchar(12), y varchar(34), z varchar );
    \d foo
    -- not ignored, as expected 
    
    CREATE OR REPLACE FUNCTION foo( p_x varchar ) RETURNS text AS 
    $f$ SELECT 'hello1' $f$ LANGUAGE SQL IMMUTABLE;
    CREATE OR REPLACE FUNCTION foo( p_x varchar(12) ) RETURNS text AS 
    $f$ SELECT 'hello10' $f$ LANGUAGE SQL IMMUTABLE;
    
    \df foo
                               List of functions
     Schema | Name | Result data type | Argument data types   |  Type  
    --------+------+------------------+-----------------------+--------
     public | foo  | text             | p_x character varying | normal
     (1 row)
    

    foo(x) 不一样的tham foo(z)

     SELECT pg_typeof(x),pg_typeof(y),pg_typeof(z) FROM foo;
     -- returns "character varying" for all
    

    当然,有时我们可以 pg_typeof()

    • s
    • geometry 可以检查子类型(例如点子类型)。它是一个 解决方法,但不是“真正的” 超载 ".

    注意 :已注释的 foo('abc') 将得到充分的解决” orthogonal

    CREATE FUNCTION foo( p_x text ) RETURNS text AS $f$ SELECT 'hello-text' 
    $f$ LANGUAGE SQL IMMUTABLE;
    

    “自动铸造” abc 发短信“解决问题” select foo('abc')

    1 回复  |  直到 6 年前
        1
  •  2
  •   Nick Barnes    6 年前

    类型修饰符

    当您在签名中使用typmods创建函数时,它们将被忽略。这个 function catalog 仅存储基类型ID(与 column catalog atttypmod 字段),所以不能单独用typmod来区分两个函数。

    据我所知,唯一的解决办法是创建一个 domain (内置typmod的用户定义类型别名)。这允许您的函数引用typmods,而实际上不必将它们存储在 pg_proc :

    CREATE DOMAIN varchar12 AS varchar(12);
    CREATE OR REPLACE FUNCTION foo( p_x varchar12 ) RETURNS text AS 
    $f$ SELECT 'hello10'::text $f$ LANGUAGE SQL IMMUTABLE;
    

    这样做的动机通常是为了保持长度限制;您的 varchar(12)

    但是,虽然域类型确实允许您重载函数,但您仍然需要将值转换为适当的域类型以解决重载问题。

    因此,它可能没有什么实际用途,除非您愿意将表列也转换为使用域。(不过,假设您选择的名称比其他名称更有意义,那么根据域定义模式也有其自身的好处 varchar12