1. PostgreSQL 数据类型直接有3种转换,隐式转换,赋值转换,
显式转换;对应的转换类型存在系统表 pg_cast中
三种方式分别对应 i(Implicit),a(Assignment),e(Explicit)
下面的语句可以查看所有转换:
select castsource::regtype,casttarget::regtype,castcontext from pg_cast where castsource='text'::regtype;
2. 三者的转换关系为 i < a < e;意思是可以隐式转换的一定可以赋值转换和
显式转换;可以赋值转换的一定可以
显式转换
可以
显式转换的不能隐式转换和赋值转换
3. 注意,在pg_cast中能查到的类型之间一定可以转换,但是查不到的未必不可以转换!
比如 bigint -> text
select castsource::regtype,casttarget::regtype,castcontext from pg_cast where castsource='bigint'::regtype;
并未找到 bigint->text的转换
其实,除了 pg_cast 中的转换关系外,pg_type 系统表中还有一个列 :typcategory,表示该类型所属的大类,如,char,varchar,text等属于字符串,那么该列为 S,int,numeric,double 等为数值类型,那么该字段为 N(Numeric)
PG在判断是否可以转换的函数中(find_coercion_pathway),有如下代码片段:
-
if (ccontext >= COERCION_ASSIGNMENT &&
-
TypeCategory(targetTypeId) == TYPCATEGORY_STRING)
-
result = COERCION_PATH_COERCEVIAIO;
-
else if (ccontext >= COERCION_EXPLICIT &&
-
TypeCategory(sourceTypeId) == TYPCATEGORY_STRING)
-
result = COERCION_PATH_COERCEVIAIO
解释:
规则1)对赋值转换和显式转换,如果目标类型是字符型(上文提到的 S),那么可以转换
规则2)对
显式转换,如果待转换的对象是字符型(S),那么可以转换
当然,实际转换时还要看格式是否正确,比如 把 '123'::text 可以转换为int,但 'abc'::text不能转换为 int
-
postgres=# select 123::int::text; --满足规则1:其他(int)->text(S)
-
text
-
------
-
123
-
(1 row)
-
-
-
postgres=# select '123'::text::int;--满足规则2:text(S) -> 其他(int)
-
int4
-
------
-
123
-
(1 row)
-
postgres=# select 'abc'::text::int;--
ERROR: invalid input syntax for integer: "abc"
postgres=#
阅读(8549) | 评论(0) | 转发(0) |