【问题标题】:Postgres describe of aggregate function returning type modification value of -1 for user defined typePostgres 描述聚合函数返回类型修改值为 -1 的用户定义类型
【发布时间】:2016-12-12 18:24:14
【问题描述】:

我创建了一个聚合函数,包含以下内容:

CREATE FUNCTION rtrim(mychar) RETURNS mychar
            AS '$libdir/libmy_pgmod', 'mycharrtrim'
            LANGUAGE C IMMUTABLE STRICT;
CREATE OR REPLACE FUNCTION mychar_max( mychar, mychar ) RETURNS mychar
            AS '$libdir/libmy_pgmod', 'mychar_max'
            LANGUAGE C IMMUTABLE STRICT;
CREATE OR REPLACE FUNCTION mychar_min( mychar, mychar ) RETURNS mychar
            AS '$libdir/libmy_pgmod', 'mychar_min'
            LANGUAGE C IMMUTABLE STRICT;
CREATE AGGREGATE MAX( lzchar ) ( 
    SFUNC  = mychar_max,
    STYPE  = mychar,
    SORTOP = > 
);
CREATE AGGREGATE MIN( mychar ) ( 
    SFUNC  = mychar_min,
    STYPE  = mychar,
    SORTOP = < 
);

mychar 是一种使用 2 个类型修饰符定义的类型。第一个类型修饰符是字符串的长度,第二个是字符串的 CCSID,因为我们要模拟 zOS 字符串。然后我在表中创建如下:

create table t1 (c1 mychar(20, 1208), c2 char(20));

在我的 C 代码中,我尝试对以下语句进行描述:

select c1, max(c1), max(c2) from t1 group by c1;

但是,当我尝试使用以下代码从描述中检索数据时,描述返回正常:

char *colName = PQfname( result, hvNum );
int   colTmod = PQfmod( result, hvNum );
int   colSize = PQfsize( result, hvNum );
Oid   oid     = PQftype( result, hvNum );
Oid   tblOid  = PQftable( result, hvNum );

对于第一列,我得到了预期值(colName、colTmod、oid 和 tblOid)。对于第二列 (max(c1)),它返回 ma​​x 作为 colName(我预期的),它还正确返回正确的 oid。但是,对于 colTmod,它返回 -1。在这种情况下,我需要做些什么来获得正确的 colTmod 值吗?对于作为本机字符的 max(c2) 列,它按预期正确返回所有内容,包括 colTmod 作为 24。一定是我做错了什么,导致我的 char 或聚合函数的实现没有正确返回类型修改值。

【问题讨论】:

    标签: postgresql


    【解决方案1】:

    我不是 100% 确定,但我很确定聚合函数的结果没有类型修饰符。

    我用定义为numeric(7,2) 的列尝试了你的实验,和你一样,当我查询最大值时,PQfmod 得到了-1。

    numericmax聚合是使用numeric_larger定义的,其定义为:

    Datum
    numeric_larger(PG_FUNCTION_ARGS)
    {
        Numeric     num1 = PG_GETARG_NUMERIC(0);
        Numeric     num2 = PG_GETARG_NUMERIC(1);
    
        /*
         * Use cmp_numerics so that this will agree with the comparison operators,
         * particularly as regards comparisons involving NaN.
         */
        if (cmp_numerics(num1, num2) > 0)
            PG_RETURN_NUMERIC(num1);
        else
            PG_RETURN_NUMERIC(num2);
    }
    

    所以它尽可能简单地获取并返回输入值之一。

    如果类型修饰符没有保留在那里,我猜它们永远不会保留在聚合中。

    【讨论】:

    • 感谢 Laurenz 的回复。我必须在周末验证这一点。我认为我之前看到的是 typmod 或 size 至少对于 (var)char 类型是正确的。我将不得不再次检查并查看 numeric 会发生什么。
    猜你喜欢
    • 2021-06-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多