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
相关产品推荐
相关产品推荐

