You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

pg_typeof是否返回数据类型别名?类型枚举校验需兼容别名吗?

解答:不需要考虑类型别名,pg_typeof返回标准类型名称

好问题!答案是不需要额外包含类型别名,因为pg_typeof()返回的始终是PostgreSQL中类型的官方标准名称,而不是别名。

核心原理

PostgreSQL中的类型别名(比如int4对应integer、timestamp对应timestamp without time zone)只是语法层面的简写,当数据库解析表达式时,会自动将别名映射到对应的标准类型。pg_typeof()获取的是最终解析后的类型名称,所以:

  • 即使你用1::int4,pg_typeof()返回的是'integer'
  • 即使你用current_timestamp::timestamp,pg_typeof()返回的是'timestamp without time zone'

你可以直接验证这个行为:

SELECT pg_typeof(1::int4); -- 输出 'integer'
SELECT pg_typeof(current_timestamp::timestamp); -- 输出 'timestamp without time zone'
SELECT pg_typeof('2024-01-01'::date); -- 输出 'date'(不会返回别名比如'date8')

适配你的函数实现

基于这个特性,你只需要在枚举中定义标准类型名称即可,不需要添加任何别名。比如你的枚举可以保持:

CREATE TYPE supported_types AS enum ('integer', 'timestamp without time zone');

然后在函数中直接用这个枚举来做合法性检查,优化后的函数示例:

CREATE OR REPLACE FUNCTION fun(expressions text[]) RETURNS void AS $$
DECLARE
  expression_type text;
BEGIN
  FOR i IN 1..array_length(expressions, 1) LOOP
    -- 用where false确保不会返回实际数据,只获取类型
    EXECUTE format('select pg_typeof((select %s from some_table where false))', expressions[i]) INTO expression_type;
    
    -- 检查类型是否在允许的集合中
    IF expression_type NOT IN (SELECT unnest(enum_range(NULL::supported_types))::text) THEN
      RAISE EXCEPTION 'Unsupported data type: %. Allowed types are: %', 
        expression_type, array_to_string(enum_range(NULL::supported_types), ', ');
    END IF;
  END LOOP;
  
  -- 这里添加存储表达式的逻辑(示例)
  -- INSERT INTO your_expression_table(expression_text) VALUES (unnest(expressions));
END;
$$ LANGUAGE plpgsql;

额外提示

如果需要确认某个类型的标准名称,可以用pg_type系统表查询:

SELECT typname, typalias FROM pg_type WHERE typname IN ('int4', 'integer', 'timestamp', 'timestamptz');

这个查询会显示别名和对应标准类型的关联关系,帮助你确认所有需要的标准名称。

内容的提问来源于stack exchange,提问作者binoternary

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 03:24:04