提交 c2d0ebce 编写于 作者: T Tom Lane

Rewrite xindex.sgml for CREATE OPERATOR CLASS. catalogs.sgml finally

contains descriptions of every single system table.  Update 'complex'
tutorial example too.
上级 b6440a7e
<!--
Documentation of the system catalogs, directed toward PostgreSQL developers
$Header: /cvsroot/pgsql/doc/src/sgml/catalogs.sgml,v 2.48 2002/07/24 19:11:06 petere Exp $
$Header: /cvsroot/pgsql/doc/src/sgml/catalogs.sgml,v 2.49 2002/07/30 05:24:56 tgl Exp $
-->
<chapter id="catalogs">
......@@ -21,7 +21,7 @@
DATABASE</command> inserts a row into the
<structname>pg_database</structname> catalog -- and actually
creates the database on disk.) There are some exceptions for
esoteric operations, such as adding index access methods.
especially esoteric operations, such as adding index access methods.
</para>
<table>
......@@ -180,9 +180,7 @@
</table>
<para>
More detailed documentation of most catalogs follow below. The
catalogs that relate to index access methods are explained in the
<citetitle>Programmer's Guide</citetitle>.
More detailed documentation of each catalog follows below.
</para>
</sect1>
......@@ -267,6 +265,294 @@
</sect1>
<sect1 id="catalog-pg-am">
<title>pg_am</title>
<para>
<structname>pg_am</structname> stores information about index access
methods. There is one row for each index access method supported by
the system.
</para>
<table>
<title>pg_am Columns</title>
<tgroup cols=4>
<thead>
<row>
<entry>Name</entry>
<entry>Type</entry>
<entry>References</entry>
<entry>Description</entry>
</row>
</thead>
<tbody>
<row>
<entry>amname</entry>
<entry><type>name</type></entry>
<entry></entry>
<entry>name of the access method</entry>
</row>
<row>
<entry>amowner</entry>
<entry><type>int4</type></entry>
<entry>pg_shadow.usesysid</entry>
<entry>user ID of the owner (currently not used)</entry>
</row>
<row>
<entry>amstrategies</entry>
<entry><type>int2</type></entry>
<entry></entry>
<entry>number of operator strategies for this access method</entry>
</row>
<row>
<entry>amsupport</entry>
<entry><type>int2</type></entry>
<entry></entry>
<entry>number of support routines for this access method</entry>
</row>
<row>
<entry>amorderstrategy</entry>
<entry><type>int2</type></entry>
<entry></entry>
<entry>zero if the index offers no sort order, otherwise the strategy
number of the strategy operator that describes the sort order</entry>
</row>
<row>
<entry>amcanunique</entry>
<entry><type>bool</type></entry>
<entry></entry>
<entry>does AM support unique indexes?</entry>
</row>
<row>
<entry>amcanmulticol</entry>
<entry><type>bool</type></entry>
<entry></entry>
<entry>does AM support multicolumn indexes?</entry>
</row>
<row>
<entry>amindexnulls</entry>
<entry><type>bool</type></entry>
<entry></entry>
<entry>does AM support NULL index entries?</entry>
</row>
<row>
<entry>amconcurrent</entry>
<entry><type>bool</type></entry>
<entry></entry>
<entry>does AM support concurrent updates?</entry>
</row>
<row>
<entry>amgettuple</entry>
<entry><type>regproc</type></entry>
<entry>pg_proc.oid</entry>
<entry><quote>next valid tuple</quote> function</entry>
</row>
<row>
<entry>aminsert</entry>
<entry><type>regproc</type></entry>
<entry>pg_proc.oid</entry>
<entry><quote>insert this tuple</quote> function</entry>
</row>
<row>
<entry>ambeginscan</entry>
<entry><type>regproc</type></entry>
<entry>pg_proc.oid</entry>
<entry><quote>start new scan</quote> function</entry>
</row>
<row>
<entry>amrescan</entry>
<entry><type>regproc</type></entry>
<entry>pg_proc.oid</entry>
<entry><quote>restart this scan</quote> function</entry>
</row>
<row>
<entry>amendscan</entry>
<entry><type>regproc</type></entry>
<entry>pg_proc.oid</entry>
<entry><quote>end this scan</quote> function</entry>
</row>
<row>
<entry>ammarkpos</entry>
<entry><type>regproc</type></entry>
<entry>pg_proc.oid</entry>
<entry><quote>mark current scan position</quote> function</entry>
</row>
<row>
<entry>amrestrpos</entry>
<entry><type>regproc</type></entry>
<entry>pg_proc.oid</entry>
<entry><quote>restore marked scan position</quote> function</entry>
</row>
<row>
<entry>ambuild</entry>
<entry><type>regproc</type></entry>
<entry>pg_proc.oid</entry>
<entry><quote>build new index</quote> function</entry>
</row>
<row>
<entry>ambulkdelete</entry>
<entry><type>regproc</type></entry>
<entry>pg_proc.oid</entry>
<entry>bulk-delete function</entry>
</row>
<row>
<entry>amcostestimate</entry>
<entry><type>regproc</type></entry>
<entry>pg_proc.oid</entry>
<entry>estimate cost of an indexscan</entry>
</row>
</tbody>
</tgroup>
</table>
<para>
An index AM that supports multiple columns (has
<structfield>amcanmulticol</structfield> true) <emphasis>must</>
support indexing nulls in columns after the first, because the planner
will assume the index can be used for queries on just the first
column(s). For example, consider an index on (a,b) and a query
WHERE a = 4. The system will assume the index can be used to scan for
rows with a = 4, which is wrong if the index omits rows where b is null.
However it is okay to omit rows where the first indexed column is null.
(GiST currently does so.)
<structfield>amindexnulls</structfield> should be set true only if the
index AM indexes all rows, including arbitrary combinations of nulls.
</para>
</sect1>
<sect1 id="catalog-pg-amop">
<title>pg_amop</title>
<para>
<structname>pg_amop</structname> stores information about operators
associated with index access method operator classes. There is one
row for each operator that is a member of an operator class.
</para>
<table>
<title>pg_amop Columns</title>
<tgroup cols=4>
<thead>
<row>
<entry>Name</entry>
<entry>Type</entry>
<entry>References</entry>
<entry>Description</entry>
</row>
</thead>
<tbody>
<row>
<entry>amopclaid</entry>
<entry><type>oid</type></entry>
<entry>pg_opclass.oid</entry>
<entry>the index opclass this entry is for</entry>
</row>
<row>
<entry>amopstrategy</entry>
<entry><type>int2</type></entry>
<entry></entry>
<entry>operator strategy number</entry>
</row>
<row>
<entry>amopreqcheck</entry>
<entry><type>bool</type></entry>
<entry></entry>
<entry>index hit must be rechecked</entry>
</row>
<row>
<entry>amopopr</entry>
<entry><type>oid</type></entry>
<entry>pg_operator.oid</entry>
<entry>the operator's pg_operator OID</entry>
</row>
</tbody>
</tgroup>
</table>
</sect1>
<sect1 id="catalog-pg-amproc">
<title>pg_amproc</title>
<para>
<structname>pg_amproc</structname> stores information about support
procedures
associated with index access method operator classes. There is one
row for each support procedure belonging to an operator class.
</para>
<table>
<title>pg_amproc Columns</title>
<tgroup cols=4>
<thead>
<row>
<entry>Name</entry>
<entry>Type</entry>
<entry>References</entry>
<entry>Description</entry>
</row>
</thead>
<tbody>
<row>
<entry>amopclaid</entry>
<entry><type>oid</type></entry>
<entry>pg_opclass.oid</entry>
<entry>the index opclass this entry is for</entry>
</row>
<row>
<entry>amprocnum</entry>
<entry><type>int2</type></entry>
<entry></entry>
<entry>support procedure index</entry>
</row>
<row>
<entry>amproc</entry>
<entry><type>regproc</type></entry>
<entry>pg_proc.oid</entry>
<entry>OID of the proc</entry>
</row>
</tbody>
</tgroup>
</table>
</sect1>
<sect1 id="catalog-pg-attrdef">
<title>pg_attrdef</title>
......@@ -1923,6 +2209,104 @@
</sect1>
<sect1 id="catalog-pg-opclass">
<title>pg_opclass</title>
<para>
<structname>pg_opclass</structname> defines
index access method operator classes. Each operator class defines
semantics for index columns of a particular datatype and a particular
index access method. Note that there can be multiple operator classes
for a given datatype/access method combination, thus supporting multiple
behaviors.
</para>
<para>
Operator classes are described at length in the
<citetitle>Programmer's Guide</citetitle>.
</para>
<table>
<title>pg_opclass Columns</title>
<tgroup cols=4>
<thead>
<row>
<entry>Name</entry>
<entry>Type</entry>
<entry>References</entry>
<entry>Description</entry>
</row>
</thead>
<tbody>
<row>
<entry>opcamid</entry>
<entry><type>oid</type></entry>
<entry>pg_am.oid</entry>
<entry>index access method opclass is for</entry>
</row>
<row>
<entry>opcname</entry>
<entry><type>name</type></entry>
<entry></entry>
<entry>name of this opclass</entry>
</row>
<row>
<entry>opcnamespace</entry>
<entry><type>oid</type></entry>
<entry>pg_namespace.oid</entry>
<entry>namespace of this opclass</entry>
</row>
<row>
<entry>opcowner</entry>
<entry><type>int4</type></entry>
<entry>pg_shadow.usesysid</entry>
<entry>opclass owner</entry>
</row>
<row>
<entry>opcintype</entry>
<entry><type>oid</type></entry>
<entry>pg_type.oid</entry>
<entry>type of input data for opclass</entry>
</row>
<row>
<entry>opcdefault</entry>
<entry><type>bool</type></entry>
<entry></entry>
<entry>true if opclass is default for opcintype</entry>
</row>
<row>
<entry>opckeytype</entry>
<entry><type>oid</type></entry>
<entry>pg_type.oid</entry>
<entry>type of index data, or zero if same as opcintype</entry>
</row>
</tbody>
</tgroup>
</table>
<para>
The majority of the information defining an operator class is actually
not in its <structname>pg_opclass</structname> row, but in the associated
rows in <structname>pg_amop</structname> and
<structname>pg_amproc</structname>. Those rows are considered to be
part of the operator class definition --- this is not unlike the way
that a relation is defined by a single <structname>pg_class</structname>
row, plus associated rows in <structname>pg_attribute</structname> and
other tables.
</para>
</sect1>
<sect1 id="catalog-pg-operator">
<title>pg_operator</title>
......
此差异已折叠。
......@@ -5,9 +5,10 @@
-- use this new type.
--
--
-- Copyright (c) 1994, Regents of the University of California
-- Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
-- Portions Copyright (c) 1994, Regents of the University of California
--
-- $Id: complex.source,v 1.12 2002/04/17 20:57:57 tgl Exp $
-- $Header: /cvsroot/pgsql/src/tutorial/complex.source,v 1.13 2002/07/30 05:24:56 tgl Exp $
--
---------------------------------------------------------------------------
......@@ -46,13 +47,14 @@ CREATE FUNCTION complex_out(opaque)
CREATE TYPE complex (
internallength = 16,
input = complex_in,
output = complex_out
output = complex_out,
alignment = double
);
-----------------------------
-- Using the new type:
-- user-defined types can be use like ordinary built-in types.
-- user-defined types can be used like ordinary built-in types.
-----------------------------
-- eg. we can use it in a schema
......@@ -62,7 +64,7 @@ CREATE TABLE test_complex (
b complex
);
-- data for user-defined type are just strings in the proper textual
-- data for user-defined types are just strings in the proper textual
-- representation.
INSERT INTO test_complex VALUES ('(1.0, 2.5)', '(4.2, 3.55 )');
......@@ -74,7 +76,7 @@ SELECT * FROM test_complex;
-- Creating an operator for the new type:
-- Let's define an add operator for complex types. Since POSTGRES
-- supports function overloading, we'll use + as the add operator.
-- (Operators can be reused with different number and types of
-- (Operator names can be reused with different numbers and types of
-- arguments.)
-----------------------------
......@@ -121,20 +123,11 @@ CREATE AGGREGATE complex_sum (
SELECT complex_sum(a) FROM test_complex;
-------------------------------------------------------------------------------
-- ATTENTION! ATTENTION! ATTENTION! --
-- YOU MAY SKIP THE SECTION BELOW ON INTERFACING WITH INDICES. YOU DON'T --
-- NEED THE FOLLOWING IF YOU DON'T USE INDICES WITH NEW DATA TYPES. --
-------------------------------------------------------------------------------
SELECT 'READ ABOVE!' AS STOP;
-----------------------------
-- Interfacing New Types with Indices:
-- Interfacing New Types with Indexes:
-- We cannot define a secondary index (eg. a B-tree) over the new type
-- yet. We need to modify a few system catalogs to show POSTGRES how
-- to use the new type. Unfortunately, there is no simple command to
-- do this. Please bear with me.
-- yet. We need to create all the required operators and support
-- functions, then we can make the operator class.
-----------------------------
-- first, define the required operators
......@@ -170,81 +163,20 @@ CREATE OPERATOR > (
restrict = scalargtsel, join = scalargtjoinsel
);
INSERT INTO pg_opclass (opcamid, opcname, opcnamespace, opcowner, opcintype, opcdefault, opckeytype)
VALUES (
(SELECT oid FROM pg_am WHERE amname = 'btree'),
'complex_abs_ops',
(SELECT oid FROM pg_namespace WHERE nspname = 'pg_catalog'),
1, -- UID of superuser is hardwired to 1 as of PG 7.3
(SELECT oid FROM pg_type WHERE typname = 'complex'),
true,
0);
SELECT oid, *
FROM pg_opclass WHERE opcname = 'complex_abs_ops';
SELECT o.oid AS opoid, o.oprname
INTO TEMP 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';
-- make sure we have the right operators
SELECT * from complex_ops_tmp;
INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr)
SELECT opcl.oid, 1, false, c.opoid
FROM pg_opclass opcl, complex_ops_tmp c
WHERE
opcamid = (SELECT oid FROM pg_am WHERE amname = 'btree')
and opcname = 'complex_abs_ops'
and c.oprname = '<';
INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr)
SELECT opcl.oid, 2, false, c.opoid
FROM pg_opclass opcl, complex_ops_tmp c
WHERE
opcamid = (SELECT oid FROM pg_am WHERE amname = 'btree')
and opcname = 'complex_abs_ops'
and c.oprname = '<=';
INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr)
SELECT opcl.oid, 3, false, c.opoid
FROM pg_opclass opcl, complex_ops_tmp c
WHERE
opcamid = (SELECT oid FROM pg_am WHERE amname = 'btree')
and opcname = 'complex_abs_ops'
and c.oprname = '=';
INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr)
SELECT opcl.oid, 4, false, c.opoid
FROM pg_opclass opcl, complex_ops_tmp c
WHERE
opcamid = (SELECT oid FROM pg_am WHERE amname = 'btree')
and opcname = 'complex_abs_ops'
and c.oprname = '>=';
INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr)
SELECT opcl.oid, 5, false, c.opoid
FROM pg_opclass opcl, complex_ops_tmp c
WHERE
opcamid = (SELECT oid FROM pg_am WHERE amname = 'btree')
and opcname = 'complex_abs_ops'
and c.oprname = '>';
--
-- create the support function too
CREATE FUNCTION complex_abs_cmp(complex, complex) RETURNS int4
AS '_OBJWD_/complex' LANGUAGE 'c';
SELECT oid, proname FROM pg_proc WHERE proname = 'complex_abs_cmp';
-- now we can make the operator class
CREATE OPERATOR CLASS complex_abs_ops
DEFAULT FOR TYPE complex USING btree AS
OPERATOR 1 < ,
OPERATOR 2 <= ,
OPERATOR 3 = ,
OPERATOR 4 >= ,
OPERATOR 5 > ,
FUNCTION 1 complex_abs_cmp(complex, complex);
INSERT INTO pg_amproc (amopclaid, amprocnum, amproc)
SELECT opcl.oid, 1, pro.oid
FROM pg_opclass opcl, pg_proc pro
WHERE
opcamid = (SELECT oid FROM pg_am WHERE amname = 'btree')
and opcname = 'complex_abs_ops'
and proname = 'complex_abs_cmp';
-- now, we can define a btree index on complex types. First, let's populate
-- the table. Note that postgres needs many more tuples to start using the
......@@ -259,35 +191,8 @@ SELECT * from test_complex where a = '(56.0,-22.5)';
SELECT * from test_complex where a < '(56.0,-22.5)';
SELECT * from test_complex where a > '(56.0,-22.5)';
DELETE FROM pg_amop WHERE
amopclaid = (SELECT oid FROM pg_opclass WHERE
opcamid = (SELECT oid FROM pg_am WHERE amname = 'btree')
and opcname = 'complex_abs_ops');
DELETE FROM pg_amproc WHERE
amopclaid = (SELECT oid FROM pg_opclass WHERE
opcamid = (SELECT oid FROM pg_am WHERE amname = 'btree')
and opcname = 'complex_abs_ops');
DELETE FROM pg_opclass WHERE
opcamid = (SELECT oid FROM pg_am WHERE amname = 'btree')
and opcname = 'complex_abs_ops';
DROP FUNCTION complex_in(opaque);
-- clean up the example
DROP TABLE test_complex;
DROP TYPE complex CASCADE;
DROP FUNCTION complex_out(opaque);
DROP FUNCTION complex_add(complex, complex);
DROP FUNCTION complex_abs_lt(complex, complex);
DROP FUNCTION complex_abs_le(complex, complex);
DROP FUNCTION complex_abs_eq(complex, complex);
DROP FUNCTION complex_abs_ge(complex, complex);
DROP FUNCTION complex_abs_gt(complex, complex);
DROP FUNCTION complex_abs_cmp(complex, complex);
DROP OPERATOR + (complex, complex);
DROP OPERATOR < (complex, complex);
DROP OPERATOR <= (complex, complex);
DROP OPERATOR = (complex, complex);
DROP OPERATOR >= (complex, complex);
DROP OPERATOR > (complex, complex);
DROP AGGREGATE complex_sum (complex);
DROP TYPE complex;
DROP TABLE test_complex, complex_ops_tmp;
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册