zoukankan      html  css  js  c++  java
  • [转]greenplum(postgresql)之数据字典

    greenplum是基于postgresql开发的分布式数据库,里面大部分的数据字典是一样的。我们在维护gp的时候对gp的数据字典比较熟悉,特此分享给大家。在这里不会详细介绍每个字典的内容,只会介绍常见的应用以及一些已经封装好了的函数。具体的介绍大家可以去看postgresql的中文文档(附件),里面有详细的解释。

        1.postgresql中,所有数据库的对象都是用oid连接在一起的。

            这样子会造成我们在理解数据字典的时候有一些不知所云。下面介绍几个函数,可以简化很多的操作。

    名字

    引用

    描述

    regproc

    pg_proc

    函数名字

    regprocedure

    pg_proc

    带参数类型的函数

    regoper

    pg_operator

    操作符名

    regoperator

    pg_operator

    带参数类型的操作符

    regclass

    pg_class

    关系名

          最常用的是regclass,关联数据字典的oid,使用方法如下:

    [sql] view plain copy
     
    1. aligputf8=# select 1259::regclass;  
    2.  regclass   
    3. ----------  
    4.  pg_class  
    5. (1 row)  
    6. aligputf8=# select oid,relname from pg_class where oid='pg_class'::regclass;  
    7.  oid  | relname    
    8. ------+----------  
    9.  1259 | pg_class  
    10. (1 row)  


             这样子就可以通过regclass寻找一个表的信息,就不用去关联 pg_class跟pg_namespace(记录schema信息)了。比较方便。

            同样的,其他几个类型也是一样的用法,如regproc(regprocedure)是跟pg_proc(保存普通函数的命令)关联的。regoper(regoperator)是跟pg_operator(操作符)的oid关联的。

    Eg:

    [sql] view plain copy
     
    1. aligputf8=# select oid::regoper,oid::regoperator,oid,oprname from pg_operator limit 1;  
    2.      oid      |        oid        | oid | oprname   
    3. --------------+-------------------+-----+---------  
    4.  pg_catalog.= | =(integer,bigint) |  15 | =  
    5. (1 row)  
    6.   
    7. aligputf8=# select oid::regproc,oid::regprocedure,oid,proname from pg_proc limit 1;  
    8.   oid   |       oid       | oid  | proname   
    9. --------+-----------------+------+---------  
    10.  boolin | boolin(cstring) | 1242 | boolin  
    11. (1 row)  

            下面给给出如何使用regclass的例子。

      2.获取表的字段信息。

             表名是放在pg_class,schema名是放在pg_namespace里面的,字段信息是放在pg_attribute里面的。一般是关联这三张表:

             eg:        

    [sql] view plain copy
     
    1. SELECT a.attname,pg_catalog.format_type(a.atttypid, a.atttypmod) AS data_type   
    2.  FROM    pg_catalog.pg_attribute a,  
    3.         (  
    4.          SELECT  c.oid   
    5.            FROM    pg_catalog.pg_class c    
    6.            LEFT JOIN pg_catalog.pg_namespace n      
    7.              ON n.oid = c.relnamespace    
    8.           WHERE c.relname = 'pg_class'  
    9.             AND n.nspname = 'pg_catalog'   
    10.          )b   
    11.  WHERE a.attrelid = b.oid   
    12.  AND a.attnum > 0   
    13.  AND NOT a.attisdropped ORDER BY a.attnum;  
    14.   
    15.   
    16.    

              如果使用regclass就会简化很多:                                  

    [sql] view plain copy
     
    1. SELECT a.attname,pg_catalog.format_type(a.atttypid, a.atttypmod) AS data_type   
    2.  FROM    pg_catalog.pg_attribute a  
    3. WHERE a.attrelid ='pg_catalog.pg_class'::regclass  
    4.  AND a.attnum > 0   
    5.  AND NOT a.attisdropped ORDER BY a.attnum;  

              其实regclass就是一个类型,oid或text到regclass有一个类型转换,跟多表关联不一样,多数据字典表关联的话,如果表不存在,会返回空记录,不会报错,而如果采用regclass则会报错,所以在不确定表是否存在的情况下,慎用regclass。

    3.获取表的分布键:

    gp_distribution_policy记录这表的数据字典,localoid跟pg_class的oid关联。attrnums是一个数组,记录字段的attnum,跟pg_attribute里面的attnum关联的。

    [sql] view plain copy
     
    1. aligputf8=# create table cxfa2 ( a int ,b int ,c int ,d int ) distributed by (c,a);   
    2.   
    3.   
    4.   
    5. ligputf8=# select * from gp_distribution_policy where localoid='cxfa2'::regclass     ;  
    6. localoid | attrnums   
    7. ---------+----------  
    8.   334868 | {3,1}  
    9. 1 row)  
    10.   
    11.  select a.attrnums[i.i],b.attname,a.localoid::regclass   
    12.    from gp_distribution_policy a,  
    13.         (select generate_series(1,10))i(i),  
    14.         pg_attribute b   
    15.   where a.attrnums[i.i] is not null   
    16.     and a.localoid=b.attrelid   
    17.     and a.attrnums[i.i]=b.attnum   
    18.     and a.localoid='public.cxfa2'::regclass   
    19.       order by i.i;  


     

    结果如下:

    [sql] view plain copy
     
    1.  attrnums | attname | localoid   
    2. ----------+---------+----------  
    3.         3 | c       | cxfa2  
    4.         1 | a       | cxfa2  
    5. (2 rows)  


     

    4.获取一个视图的定义。

    [sql] view plain copy
     
    1. aligputf8=# df pg_get_viewdef  
    2.                           List of functions  
    3.    Schema   |      Name      | Result data type | Argument data types   
    4. ------------+----------------+------------------+---------------------  
    5.  pg_catalog | pg_get_viewdef | text             | oid  
    6.  pg_catalog | pg_get_viewdef | text             | oid, boolean  
    7.  pg_catalog | pg_get_viewdef | text             | text  
    8.  pg_catalog | pg_get_viewdef | text             | text, boolean  
    9. (4 rows)  

    使用这个系统函数可以获取视图的定义,可以传入oid或者是表名,第二个参数表示是否格式化输出,默认不格式化输出。

    [sql] view plain copy
     
    1. aligputf8=# create table cxfa( a int) distributed by (a);  
    2. CREATE TABLE  
    3. aligputf8=# create view v_cxfa as select * from cxfa;  
    4. CREATE VIEW  
    5. aligputf8=# select pg_get_viewdef('v_cxfa',true);  
    6.  pg_get_viewdef   
    7. ----------------  
    8.   SELECT cxfa.a  
    9.     FROM cxfa;  
    10. (1 row)  


     

    其实这个函数是去获取数据字典pg_rewrite(存储为表和视图定义的重写规则),将规则重新算出sql展现给我们。可以通过下面sql去查询数据库保存的重写规则。

    aligputf8=# select ev_action from pg_rewrite where ev_class='v_cxfa'::regclass;

                                                                                                   ev_action                                                                                                                             

    ------------------------------------------------------------------------------------------------------------------------------------------------------------

     ({QUERY :commandType 1 :querySource 0 :canSetTag true :utilityStmt <> :resultRelation 0 :into <> :intoOptions <> :intoOnCommit 0 :intoTableSpaceName <> :hasAggs false :hasWindFuncs false :hasSubLinks false :rtable ({RTE :alias {ALIAS :aliasname *OLD* :colnames <>} :eref {ALIAS :aliasname *OLD* :colnames ("a")} :rtekind 0 :relid 334939 :inh false :inFromCl false :requiredPerms 0 :checkAsUser 0 :forceDistRandom false :pseudocols <>} {RTE :alias {ALIAS :aliasname *NEW* :colnames <>} :eref {ALIAS :aliasname *NEW* :colnames ("a")} :rtekind 0 :relid 334939 :inh false :inFromCl false :requiredPerms 0 :checkAsUser 0 :forceDistRandom false :pseudocols <>} {RTE :alias <> :eref {ALIAS :aliasname cxfa :colnames ("a")} :rtekind 0 :relid 334930 :inh true :inFromCl true :requiredPerms 2 :checkAsUser 0 :forceDistRandom false :pseudocols <>}) :jointree {FROMEXPR :fromlist ({RANGETBLREF :rtindex 3}) :quals <>} :targetList ({TARGETENTRY :expr {VAR :varno 3 :varattno 1 :vartype 23 :vartypmod -1 :varlevelsup 0 :varnoold 3 :varoattno 1} :resno 1 :resname a :ressortgroupref 0 :resorigtbl 334930 :resorigcol 1 :resjunk false}) :returningList <> :groupClause <> :havingQual <> :windowClause <> :distinctClause <> :sortClause <> :limitOffset <> :limitCount <> :rowMarks <> :setOperations <> :resultRelations <> :result_partitions <> :result_aosegnos <> :returningLists <> :intoOidInfo.relOid 0 :intoOidInfo.comptypeOid 0 :intoOidInfo.toastOid 0 :intoOidInfo.toastIndexOid 0 :intoOidInfo.toastComptypeOid 0 :intoOidInfo.aosegOid 0 :intoOidInfo.aosegIndexOid 0 :intoOidInfo.aosegComptypeOid 0})

    (1 row)

    与pg_get_viewdef类似的函数还有如下,其原理都是差不多的,将数据字典的重写规则翻译为sql:

    [sql] view plain copy
     
    1. aligputf8=# df pg_get_*def  
    2.                                  List of functions  
    3.    Schema   |           Name            | Result data type |  Argument data types   
    4. ------------+---------------------------+------------------+-----------------------  
    5.  pg_catalog | pg_get_constraintdef      | text             | oid  
    6.  pg_catalog | pg_get_constraintdef      | text             | oid, boolean  
    7.  pg_catalog | pg_get_indexdef           | text             | oid  
    8.  pg_catalog | pg_get_indexdef           | text             | oid, integer, boolean  
    9.  pg_catalog | pg_get_partition_def      | text             | oid  
    10.  pg_catalog | pg_get_partition_def      | text             | oid, boolean  
    11.  pg_catalog | pg_get_partition_rule_def | text             | oid  
    12.  pg_catalog | pg_get_partition_rule_def | text             | oid, boolean  
    13.  pg_catalog | pg_get_ruledef            | text             | oid  
    14.  pg_catalog | pg_get_ruledef            | text             | oid, boolean  
    15.  pg_catalog | pg_get_triggerdef         | text             | oid  

    注:触发器在greenplum里面是不支持的。 

    5.分区表相关操作

    d一个表是看不出一个表是否是分区表的,所以必须查询数据字典才能知道。查分区表可以通过pg_partitions跟pg_partition_columns这两个视图来查询,但是这两个视图的结构非常复杂,在线上gp上数据字典都非常大,没有充分利用到索引,这个查询起来效率太低了。我们直接通过数据字典的实体表来查询的话,会快很多。

    首先创建一个分区表:

    [sql] view plain copy
     
    1. create table public.cxfa3(  
    2.       id               integer                  
    3.      ,name             character varying(20)    
    4.      ,birth            date                     
    5. )Distributed by (id)  
    6. PARTITION BY range(birth)  
    7. (  
    8.     PARTITION p19860801 START ('1986-08-01'::date) END ('1986-08-02'::date) EVERY ('1 day'::interval),  
    9.     PARTITION p19860802 START ('1986-08-02'::date) END ('1986-08-03'::date) EVERY ('1 day'::interval)  
    10. );  

        5.1 查询一个表是否是分区表

    表pg_partition:每一个分区表的父表有一行记录。

    parkind:    表示分区类型(range 或者 list)。

    parnatts:  分区建个数。

    paratts:       分区键,跟pg_attribute关联,是一个列表。

     表pg_partition_rule:保存分区表每一个子分区的分区名以及分区规则等。

    [sql] view plain copy
     
    1. aligputf8=# select count(*) from pg_partition where parrelid='public.cxfa3'::regclass;  
    2.  count   
    3. -------  
    4.      1  
    5. (1 row)  

    只要count的结果是=1的,表示该表是分区表,否则该表不是分区表。每个分区表在里面只有一行记录。

         5.2 查询一个表的分区键

    [sql] view plain copy
     
    1. aligputf8=# select attname as columnname   
    2. aligputf8-#   from pg_attribute a,pg_partition b   
    3. aligputf8-#  where a.attnum = b.paratts[0]   
    4. aligputf8-#    and b.parrelid = a.attrelid   
    5. aligputf8-#    and a.attrelid='public.cxfa3'::regclass;  
    6.  columnname   
    7. ------------  
    8.  birth  
    9. (1 row)  

    由于现在gp上面的分区键都是一个的,所以为了效率,我们也只是获取第一个分区键

          5.3 查询分区表每个分区的具体信息

    [sql] view plain copy
     
    1. aligputf8=# SELECT pp.parrelid::regclass,pr1.parchildrelid::regclass,pr1.parname,  
    2. aligputf8-#          CASE  
    3. aligputf8-#              WHEN pp.parkind = 'h'::"char" THEN 'hash'::text  
    4. aligputf8-#              WHEN pp.parkind = 'r'::"char" THEN 'range'::text  
    5. aligputf8-#              WHEN pp.parkind = 'l'::"char" THEN 'list'::text  
    6. aligputf8-#              ELSE NULL::text  
    7. aligputf8-#          END AS partitiontype,  
    8. aligputf8-#          pg_get_partition_rule_def(pr1.oid, true) AS partitionboundary  
    9. aligputf8-# FROM  pg_partition pp, pg_partition_rule pr1    
    10. aligputf8-# WHERE pp.paristemplate = false AND pp.parrelid = 'cxfa3'::regclass AND pr1.paroid = pp.oid  
    11. aligputf8-# order by pr1.parname;  
    12.         parrelid |     parchildrelid     |  parname  | partitiontype |                                         partitionboundary                                          
    13. ----------+-----------------------+-----------+---------------+---------------------------------------------------------------------------------------------------  
    14.  cxfa3    | cxfa3_1_prt_p19860801 | p19860801 | range         | PARTITION p19860801 START ('1986-08-01'::date) END ('1986-08-02'::date) EVERY ('1 day'::interval)  
    15.  cxfa3    | cxfa3_1_prt_p19860802 | p19860802 | range         | PARTITION p19860802 START ('1986-08-02'::date) END ('1986-08-03'::date) EVERY ('1 day'::interval)  
    16. (2 rows)  

    6.查询comment(备注信息)

    comment信息是放在表pg_description中的。

    名字

    类型

    引用

    描述

    objoid

    oid

    任意 oid 属性

    这条描述所描述的对象的 OID

    classoid

    oid

    pg_class.oid

    这个对象出现的系统表的 OID

    objsubid

    int4

    对于一个表字段的注释,它是字段号(objoid 和 classoid 指向表自身)。对于其它对象类型,它是零。

    description

    text

    作为对该对象的描述的任意文本

         查询在表上的comment信息:

    [sql] view plain copy
     
    1. aligputf8=# select  COALESCE(description,'') as comment from pg_description where objoid='cxfa'::regclass and objsubid=0;  
    2.                comment                  
    3. --------------------------------------  
    4.  a table created by scutshuxue.chenxf  
    5. (1 row)  

        查询表中字段的comment信息:

    [sql] view plain copy
     
    1. aligputf8=# select b.attname as columnname, COALESCE(a.description,'')  as comment  
    2. aligputf8-#   from pg_catalog.pg_description a,pg_catalog.pg_attribute b   
    3. aligputf8-#  where objoid='cxfa'::regclass   
    4. aligputf8-#    and a.objoid=b.attrelid   
    5. aligputf8-#    and a.objsubid=b.attnum;  
    6.  columnname |        comment           
    7. ------------+------------------------  
    8.  a          | column a of table cxfa  
    9. (1 row)  

    7.查询权限信息

    对于表、视图来说,在pg_class里面有一个字段relacl,保存了权限信息,如下:

    [sql] view plain copy
     
    1. aligputf8=# select relacl from pg_class where relname='cxfa3';  
    2.                          relacl                           
    3. --------------------------------------------------------  
    4.  {gpadmin1=arwdxt/gpadmin1,role_aquery=arwdxt/gpadmin1}  
    5. (1 row)  

    具体解释如下:

                  =xxxx -- 赋予 PUBLIC 的权限
             uname=xxxx -- 赋予一个用户的权限
       group gname=xxxx -- 赋予一个组的权限

    r -- SELECT ("读")
                      w -- UPDATE ("写")
                      a -- INSERT ("追加")
                      d -- DELETE
                      x -- REFERENCES
                      t -- TRIGGER
                      X -- EXECUTE
                      U -- USAGE
                      C -- CREATE
                      c -- CONNECT
                      T -- TEMPORARY
                 arwdxt -- ALL PRIVILEGES (用于表)
                      * -- 给前面权限的授权选项

    /yyyy -- 授出这个权限的用户

    对于函数,在pg_proc里面也有一个对应的字段proacl。对于schema,pg_namespace里面也有对应的字段nspacl。

    但是查这些字段有点不是很方便,在数据库里面有很多函数可以方便一些查询。如下:

    [sql] view plain copy
     
    1. aligputf8=# df *privilege*  
    2.                                List of functions  
    3.    Schema   |           Name           | Result data type | Argument data types  
    4. ------------+--------------------------+------------------+---------------------  
    5.  pg_catalog | has_database_privilege   | boolean          | name, oid, text  
    6.  pg_catalog | has_database_privilege   | boolean          | name, text, text  
    7.  pg_catalog | has_database_privilege   | boolean          | oid, oid, text  
    8.  pg_catalog | has_database_privilege   | boolean          | oid, text  
    9.  pg_catalog | has_database_privilege   | boolean          | oid, text, text  
    10.  pg_catalog | has_database_privilege   | boolean          | text, text  
    11.  pg_catalog | has_function_privilege   | boolean          | name, oid, text  
    12.  pg_catalog | has_function_privilege   | boolean          | name, text, text  
    13.  pg_catalog | has_function_privilege   | boolean          | oid, oid, text  
    14.  pg_catalog | has_function_privilege   | boolean          | oid, text  
    15.  pg_catalog | has_function_privilege   | boolean          | oid, text, text  
    16.  pg_catalog | has_function_privilege   | boolean          | text, text  
    17.  pg_catalog | has_language_privilege   | boolean          | name, oid, text  
    18.  pg_catalog | has_language_privilege   | boolean          | name, text, text  
    19.  pg_catalog | has_language_privilege   | boolean          | oid, oid, text  
    20.  pg_catalog | has_language_privilege   | boolean          | oid, text  
    21.  pg_catalog | has_language_privilege   | boolean          | oid, text, text  
    22.  pg_catalog | has_language_privilege   | boolean          | text, text  
    23.  pg_catalog | has_schema_privilege     | boolean          | name, oid, text  
    24.  pg_catalog | has_schema_privilege     | boolean          | name, text, text  
    25.  pg_catalog | has_schema_privilege     | boolean          | oid, oid, text  
    26.  pg_catalog | has_schema_privilege     | boolean          | oid, text  
    27.  pg_catalog | has_schema_privilege     | boolean          | oid, text, text  
    28.  pg_catalog | has_schema_privilege     | boolean          | text, text  
    29.  pg_catalog | has_table_privilege      | boolean          | name, oid, text  
    30.  pg_catalog | has_table_privilege      | boolean          | name, text, text  
    31.  pg_catalog | has_table_privilege      | boolean          | oid, oid, text  
    32.  pg_catalog | has_table_privilege      | boolean          | oid, text  
    33.  pg_catalog | has_table_privilege      | boolean          | oid, text, text  
    34.  pg_catalog | has_table_privilege      | boolean          | text, text  
    35.  pg_catalog | has_tablespace_privilege | boolean          | name, oid, text  
    36.  pg_catalog | has_tablespace_privilege | boolean          | name, text, text  
    37.  pg_catalog | has_tablespace_privilege | boolean          | oid, oid, text  
    38.  pg_catalog | has_tablespace_privilege | boolean          | oid, text  
    39.  pg_catalog | has_tablespace_privilege | boolean          | oid, text, text  
    40.  pg_catalog | has_tablespace_privilege | boolean          | text, text  
    41. (36 rows)  

    示例:

    查询role_aquery用户是否有访问public.cxfa3这个表的select权限。如果结果为't'则表示有这个权限,如果为'f'则没有权限。

    [sql] view plain copy
     
    1. aligputf8=# select has_table_privilege('role_aquery','public.cxfa3','select');  
    2.  has_table_privilege   
    3. ---------------------  
    4.  t  
    5. (1 row)  
    6. aligputf8=# select has_table_privilege('role_dhw','public.cxfa3','select');  
    7.  has_table_privilege   
    8. ---------------------  
    9.  f  
    10. (1 row)  

    8.查询表的依赖关系

              我们在drop一个表的时候,经常被提醒上面有视图,不能drop。例如:

    [sql] view plain copy
     
    1. aligputf8=# drop table cxfa;  
    2. NOTICE:  rule _RETURN on view v_cxfa depends on table cxfa  
    3. NOTICE:  view v_cxfa depends on rule _RETURN on view v_cxfa  
    4. ERROR:  cannot drop table cxfa because other objects depend on it  
    5. HINT:  Use DROP ... CASCADE to drop the dependent objects too.  

             那么数据库里面是怎么保存这些依赖关系的呢?答案就在pg_depend数据字典。下面就以视图

                      create  view v_cxfa as select * from cxfa;

             为例,介绍依赖关系是如何工作的。

             pg_depend的官方文档:http://www.pgsqldb.org/pgsqldoc-8.1c/catalog-pg-depend.html#AEN56970

    [sql] view plain copy
     
    1. aligputf8=# select * from pg_depend where refobjid='cxfa'::regclass;  
    2.  classid | objid  | objsubid | refclassid | refobjid | refobjsubid | deptype   
    3. ---------+--------+----------+------------+----------+-------------+---------  
    4.     1247 | 334931 |        0 |       1259 |   334930 |           0 | i  
    5.     2618 | 334941 |        0 |       1259 |   334930 |           1 | n  
    6. (2 rows)  
    7.    
    8. aligputf8=# select relname from pg_class where oid in (1247,2618);  
    9.   relname     
    10. ------------  
    11.  pg_type  
    12.  pg_rewrite  
    13. (2 rows)  
    14.    
    15. aligputf8=# select typname from pg_type where oid=334931;  
    16.  typname   
    17. ---------  
    18.  cxfa  
    19. (1 row)  
    20.    
    21. aligputf8=# select rulename,ev_class::regclass,ev_class from pg_rewrite where oid=334941;  
    22.  rulename | ev_class | ev_class   
    23. ----------+----------+----------  
    24.  _RETURN  | v_cxfa   |   334939  
    25. (1 row)  

    上面说明了复合类型(每创建一个表,都会在pg_type里面创建一个复合类型,drop表的时候会默认drop掉的)cxfa是依赖于表cxfa的,还有pg_rewrite这个表里面oid=334941的记录是依赖于表cxfa的,这个记录是表示视图v_cxfa的重写规则的,所以我们可以通过这个找到依赖于表cxfa的视图。

    我们可以下面的sql来查询依赖于表上面的视图,过滤掉复合类型及其他函数等。

    由于pg_depend是没有记录数据字典的依赖关系的,所以我们如果要查询数据字典上面的视图,我们可以这么做:

    [sql] view plain copy
     
    1. aligputf8=# select ev_class::regclass from pg_rewrite where oid in (  
    2. aligputf8(#    select b.objid   
    3. aligputf8(#      from pg_depend a,pg_depend b   
    4. aligputf8(#     where a.refclassid=1259         
    5. aligputf8(#       and b.deptype='i'   
    6. aligputf8(#       and a.classid=2618  
    7. aligputf8(#       and a.objid=b.objid   
    8. aligputf8(#       and a.classid=b.classid   
    9. aligputf8(#       and a.refclassid=b.refclassid   
    10. aligputf8(#       and a.refobjid<>b.refobjid  
    11. aligputf8(#       and a.refobjid='cxfa'::regclass   
    12. aligputf8(#    );  
    13.  ev_class   
    14. ----------  
    15.  v_cxfa  
    16. (1 row)  


     

    查出pg_attribute的oid:

    [sql] view plain copy
     
    1. aligputf8=# select oid from pg_class where relname='pg_attribute';  
    2.  oid    
    3. ------  
    4.  1249  
    5. (1 row)  

    加入一个视图,验证能否找到新加入的表:

    aligputf8=# create view v_cxf_attribute as select * from pg_attribute;

    CREATE VIEW

    然后用下面的sql查找出视图:

    [sql] view plain copy
     
    1. aligputf8=# SELECT ev_class::regclass FROM pg_catalog.pg_rewrite WHERE ev_action like '%relid 1249%';  
    2.                   ev_class                    
    3. --------------------------------------------  
    4.  pg_stats  
    5.  pg_partition_columns  
    6.  information_schema.attributes  
    7.  information_schema.check_constraints  
    8.  information_schema.column_domain_usage  
    9.  information_schema.column_privileges  
    10.  information_schema.column_udt_usage  
    11.  information_schema.columns  
    12.  information_schema.constraint_column_usage  
    13.  information_schema.key_column_usage  
    14.  information_schema.role_column_grants  
    15.  information_schema.table_constraints  
    16.  information_schema.view_column_usage  
    17.  information_schema.element_types  
    18.  v_cxf_attribute  
    19. (15 rows)  

    9.类型转换

            在gp中,我们经常使用 cast函数,或者是::type进行类型转换,究竟哪两种类型之间是可以转换的,哪两种类型之间不能转换,转换的规则是什么。其实这些都在pg_cast里面中定义了。

    名字

    类型

    引用

    描述

    castsource

    oid

    pg_type.oid

    源数据类型的 OID

    casttarget

    oid

    pg_type.oid

    目标数据类型的 OID

    castfunc

    oid

    pg_proc.oid

    用于执行这个转换的函数的 OID 。如果该数据类型是二进制兼容的,那么为零(也就是说,不需要运行时的操作来执行转换)。

    castcontext

    char

    标识这个转换可以在什么环境里调用。e 表示只能进行明确的转换(使用 CAST 或 :: 语法)。a 表示在赋值给目标字段的时候隐含调用,也可以明确调用。i 表示在表达式中隐含,当然也包括其它情况。

            我们想知道,text类型到date类型的转换是用了那个函数可以这么查:

    [sql] view plain copy
     
    1. aligputf8=# select castfunc::regprocedure from pg_cast where castsource='text'::regtype and casttarget='date'::regtype;  
    2.   castfunc    
    3. ------------  
    4.  date(text)  
    5. (1 row)  
    6.   
    7. aligputf8=# select '20110302'::date;  
    8.     date      
    9. ------------  
    10.  2011-03-02  
    11. (1 row)  
    12.   
    13. aligputf8=# select date('20110302');  
    14.     date      
    15. ------------  
    16.  2011-03-02  
    17. (1 row)  

    可以看出,cast('20110302' as date)跟'20110302'::date其实都是调用了date('20110302')函数进行类型转换了。

    我们是否可以自定义类型转换呢?答案是肯定的。

    比方说,上面的regclass类型是没有到text类型的转换的:

    [sql] view plain copy
     
    1. aligputf8=# select 1259::regclass::text;  
    2. ERROR:  cannot cast type regclass to text  
    3. LINE 1: select 1259::regclass::text;  

               我们先创建一个类型转换函数:

    [sql] view plain copy
     
    1. CREATE or replace FUNCTION regclass2text(a regclass)  
    2.   RETURNS text  
    3. AS $    
    4.   return a;  
    5. $ LANGUAGE plpythonu;  

              然后定义一个cast类型转换规则。

    [sql] view plain copy
     
    1. aligputf8=# create cast(regclass as text) with function regclass2text(a regclass);  
    2. CREATE CAST  

             这样子我们就定义好了一个类型转换,验证:

    [sql] view plain copy
     
      1. aligputf8=# select 1259::regclass::text;  
      2.    text     
      3. ----------  
      4.  pg_class  
      5. (1 row)  
      6. aligputf8=# select cast(1259::regclass as text);  
      7.    text     
      8. ----------  
      9.  pg_class  
      10. (1 row)  

    (原文地址: http://blog.csdn.net/prettyshuang/article/details/49638641)

  • 相关阅读:
    lightoj1140_数位dp
    lightoj1057_状压dp
    lightoj1068_数位dp
    lightoj1018_状压dp
    lightoj1217_简单dp
    lightoj1119_简单状压dp
    lightoj1037_状压dp
    lightoj1110_LCS并输出
    图论算法----最短路
    poj1182 食物链
  • 原文地址:https://www.cnblogs.com/jianyungsun/p/7168222.html
Copyright © 2011-2022 走看看