当前位置:早雪网网络学院编程文档数据库技术Postgresql → PostgreSQL7.0手册-程序员手册 -43. 扩展索引接口

PostgreSQL7.0手册-程序员手册 -43. 扩展索引接口

减小字体 增大字体 作者:不详  来源:supcode.com收集整理  发布时间:2005-7-23 12:21:52
省索引.如果不是这样,只需要向 opcdeftype 插入零,而不是插入该数据类型的 oid: 

INSERT INTO pg_opclass (opcname, opcdeftype) VALUES ('complex_abs_ops', 0);
因此,现在我们有了一个访问方式和一个操作符表.我们还需要一套操作符;用于定义操作符的过程已经在这份手册的早先部分讨论过了.对这个用于 Btrees 的 complex_abs_ops 操作符表,我们需要的操作符是: 
        absolute value less-than
        absolute value less-than-or-equal
        absolute value equal
        absolute value greater-than-or-equal
        absolute value greater-than
假设实现函数册代码放在文件 PGROOT/src/tutorial/complex.c 里 
有一部分代码看起来象:(注意我们在余下的例子中将只展示等号操作符.其他四种操作符都非常相似,请参考 complex.c 或 complex.sql 获取详细信息.) 

#define Mag(c) ((c)->x*(c)->x + (c)->y*(c)->y)

         bool
         complex_abs_eq(Complex *a, Complex *b)
         {
             double amag = Mag(a), bmag = Mag(b);
             return (amag==bmag);
         }
我们用下面语句让 Postgres 这样识别这个函数: 
CREATE FUNCTION complex_abs_eq(complex, complex)
              RETURNS bool
              AS 'PGROOT/tutorial/obj/complex.so'
              LANGUAGE 'c';
有几个很重要的问题要在这里指出. 
首先,请注意定义了用于 complex 的小于,小于或等于,等于,大于或等于和大于操作符.我们可以只有一个命名了的操作符名,(比如 =)并把类型 complex 做为其两个操作数.这种情况下我们没有其它用于 complex 的 = 操作符,但是如果我们要制作一个实用的数据类型,我们可能需要 = 做为用于复数的通用等于操作的操作符.这种情况,我们可能需要使用一些其他操作符名称来命名 complex_abs_eq. 

第二,尽管 Postgres 可以处理同名操作符,只要它们的输入数据类型不同.C 只能处理一个具有给出名称的全局过程.因此我们不能把 C 函数命名为象 abs_eq 这样简单的名字.通常在 C 函数名里面包含数据类型名称是一个好习惯,这样就不会和用于其它数据类型的函数冲突. 

第三,我们可以制作函数 abs_eq 的 Postgres 名称,依靠 Postgres 通过输入数据类型来与任何其他同名 Postgres 函数区分开.为了令例子简单,我们做的函数在 C 层次和 Postgres 层次都有相同的名称, 

最后,请注意这些操作符函数返回布尔值.访问模式依靠这个特性.(令一方面,支持函数返回特定的访问模式的希望值--在这种情况下是一个符号整数.)文件里最终的过程是我们在讨论表 pg_am 里amsupport 字段时提到过的"支持过程".我们稍后将用到这个东西.目前我们暂时忽略它. 

现在定义使用它们的操作符: 

CREATE OPERATOR = (
     leftarg = complex, rightarg = complex,
     procedure = complex_abs_eq,
     restrict = eqsel, join = eqjoinsel
         )
这里的重要问题是过程名称(就是上面定义的 C 函数)和这个关系和联合选择性函数.你应该只使用例子里(参阅 complex.source)的选择性函数.请注意还要有这样的用于小于,等于和大于情况的函数.必须提供这些(函数),否则优化器将无法有效地使用该索引. 
下一步是为这些操作符向 pg_amop 关系里面增加条目.要做这些,我们将需要我们刚定义的这些操作符的 oid.我们将从所有操作符中找出接受两个复数的操作符名称,并把它们选出来: 

    SELECT o.oid AS opoid, o.oprname
     INTO TABLE complex_ops_tmp
     FROM pg_operator o, pg_type t
     WHERE o.oprleft = t.oid and o.oprright = t.oid
      and t.typname = 'complex';

 opoid  | oprname
--------+---------
 277963 | +
 277970 | <
 277971 | <=
 277972 | =
 277973 | >=
 277974 | >
(6 rows)
(同样,一些你的 oid (对象标识)将可以肯定是不同的.)我们感兴趣的操作符是那些 oid(对象标识)在 277970 到 277974 之间的.你得到的值将可能不同,你应该用你得到的值代替上面的数值.我们通过一条 select 语句实现这个目的。 
现在我们已经准备好用我们新的操作符表更新 pg_amop 表.在整个讨论中最重要的是在 pg_amop 里操作符是顺序排列的,从小于等于到大于等于.我们用下面方法增加我们需要的实例: 

    INSERT INTO pg_amop (amopid, amopclaid, amopopr, amopstrategy)
        SELECT am.oid, opcl.oid, c.opoid, 1
        FROM pg_am am, pg_opclass opcl, complex_ops_tmp c
        WHERE amname = 'btree' AND
            opcname = 'complex_abs_ops' AND
            c.oprname = '<';
然后添加其他操作符,相应地替换上面第三行的 "1" 和最后一行的 "<"。注意顺序:"小于" 是 1,"小于或等于" 是 2,"等于" 是 3,"大于或等于" 是 4,而 "大于" 是 5。 
下一步是注册我们前面在讨论 pg_am 时描述过的"支持过程".支持过程的 oid(对象标识)存放在表 pg_amproc 里,用访问模式的 oid(对象标识)和操作符表 oid(对象标识)做关键字.首先,我们需要在 Postgres 注册函数(还记得我们把实现这个过程的C 代码放在了我们实现操作符过程的文件的底部吗?): 

    CREATE FUNCTION complex_abs_cmp(complex, complex)
     RETURNS int4
     AS 'PGROOT/tutorial/obj/complex.so'
     LANGUAGE 'c';

    SELECT oid, proname FROM pg_proc
     WHERE proname = 'complex_abs_cmp';

  oid   |     proname
--------+---

上一页  [1] [2] [3]  下一页

[数据载入中...] [返回上一页] [打 印]