Commit 2a8d3d83 authored by Tom Lane's avatar Tom Lane

R-tree is dead ... long live GiST.

parent 645adf5d
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
#include <math.h> #include <math.h>
#include "access/gist.h" #include "access/gist.h"
#include "access/rtree.h" #include "access/skey.h"
#include "lib/stringinfo.h" #include "lib/stringinfo.h"
#include "utils/builtins.h" #include "utils/builtins.h"
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
#include "access/gist.h" #include "access/gist.h"
#include "access/itup.h" #include "access/itup.h"
#include "access/rtree.h" #include "access/skey.h"
#include "catalog/pg_type.h" #include "catalog/pg_type.h"
#include "utils/array.h" #include "utils/array.h"
#include "utils/builtins.h" #include "utils/builtins.h"
......
...@@ -5,8 +5,7 @@ ...@@ -5,8 +5,7 @@
#include "ltree.h" #include "ltree.h"
#include "access/gist.h" #include "access/gist.h"
#include "access/rtree.h" #include "access/skey.h"
#include "access/nbtree.h"
#include "utils/array.h" #include "utils/array.h"
#include "crc32.h" #include "crc32.h"
......
...@@ -5,8 +5,8 @@ ...@@ -5,8 +5,8 @@
#include "ltree.h" #include "ltree.h"
#include "access/gist.h" #include "access/gist.h"
#include "access/rtree.h"
#include "access/nbtree.h" #include "access/nbtree.h"
#include "access/skey.h"
#include "utils/array.h" #include "utils/array.h"
#include "crc32.h" #include "crc32.h"
......
...@@ -2,13 +2,10 @@ ...@@ -2,13 +2,10 @@
#include "access/gist.h" #include "access/gist.h"
#include "access/itup.h" #include "access/itup.h"
#include "access/rtree.h" #include "access/tuptoaster.h"
#include "utils/elog.h" #include "storage/bufpage.h"
#include "utils/palloc.h"
#include "utils/array.h" #include "utils/array.h"
#include "utils/builtins.h" #include "utils/builtins.h"
#include "storage/bufpage.h"
#include "access/tuptoaster.h"
PG_FUNCTION_INFO_V1(gtrgm_in); PG_FUNCTION_INFO_V1(gtrgm_in);
Datum gtrgm_in(PG_FUNCTION_ARGS); Datum gtrgm_in(PG_FUNCTION_ARGS);
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
#include <float.h> #include <float.h>
#include "access/gist.h" #include "access/gist.h"
#include "access/rtree.h" #include "access/skey.h"
#include "utils/builtins.h" #include "utils/builtins.h"
#include "segdata.h" #include "segdata.h"
...@@ -53,7 +53,7 @@ bool *gseg_same(SEG * b1, SEG * b2, bool *result); ...@@ -53,7 +53,7 @@ bool *gseg_same(SEG * b1, SEG * b2, bool *result);
/* /*
** R-tree suport functions ** R-tree support functions
*/ */
bool seg_same(SEG * a, SEG * b); bool seg_same(SEG * a, SEG * b);
bool seg_contains_int(SEG * a, int *b); bool seg_contains_int(SEG * a, int *b);
......
...@@ -4,11 +4,10 @@ ...@@ -4,11 +4,10 @@
#include "access/gist.h" #include "access/gist.h"
#include "access/itup.h" #include "access/itup.h"
#include "access/rtree.h" #include "access/tuptoaster.h"
#include "storage/bufpage.h"
#include "utils/array.h" #include "utils/array.h"
#include "utils/builtins.h" #include "utils/builtins.h"
#include "storage/bufpage.h"
#include "access/tuptoaster.h"
#include "tsvector.h" #include "tsvector.h"
#include "query.h" #include "query.h"
......
...@@ -15,10 +15,9 @@ ...@@ -15,10 +15,9 @@
#include "access/gist.h" #include "access/gist.h"
#include "access/itup.h" #include "access/itup.h"
#include "access/rtree.h" #include "storage/bufpage.h"
#include "utils/array.h" #include "utils/array.h"
#include "utils/builtins.h" #include "utils/builtins.h"
#include "storage/bufpage.h"
#include "ts_cfg.h" #include "ts_cfg.h"
#include "tsvector.h" #include "tsvector.h"
......
...@@ -9,7 +9,6 @@ ...@@ -9,7 +9,6 @@
#include "access/gist.h" #include "access/gist.h"
#include "access/itup.h" #include "access/itup.h"
#include "access/rtree.h"
#include "storage/bufpage.h" #include "storage/bufpage.h"
#include "utils/array.h" #include "utils/array.h"
#include "utils/builtins.h" #include "utils/builtins.h"
......
<!-- <!--
$PostgreSQL: pgsql/doc/src/sgml/backup.sgml,v 2.75 2005/11/04 23:13:59 petere Exp $ $PostgreSQL: pgsql/doc/src/sgml/backup.sgml,v 2.76 2005/11/07 17:36:44 tgl Exp $
--> -->
<chapter id="backup"> <chapter id="backup">
<title>Backup and Restore</title> <title>Backup and Restore</title>
...@@ -1129,8 +1129,8 @@ restore_command = 'copy /mnt/server/archivedir/%f "%p"' # Windows ...@@ -1129,8 +1129,8 @@ restore_command = 'copy /mnt/server/archivedir/%f "%p"' # Windows
<itemizedlist> <itemizedlist>
<listitem> <listitem>
<para> <para>
Operations on hash and R-tree indexes are Operations on hash indexes are
not presently WAL-logged, so replay will not update these index types. not presently WAL-logged, so replay will not update these indexes.
The recommended workaround is to manually <command>REINDEX</> each The recommended workaround is to manually <command>REINDEX</> each
such index after completing a recovery operation. such index after completing a recovery operation.
</para> </para>
......
<!-- <!--
$PostgreSQL: pgsql/doc/src/sgml/geqo.sgml,v 1.33 2005/10/25 13:38:09 momjian Exp $ $PostgreSQL: pgsql/doc/src/sgml/geqo.sgml,v 1.34 2005/11/07 17:36:44 tgl Exp $
Genetic Optimizer Genetic Optimizer
--> -->
...@@ -51,8 +51,8 @@ Genetic Optimizer ...@@ -51,8 +51,8 @@ Genetic Optimizer
caused by the support of a variety of <firstterm>join caused by the support of a variety of <firstterm>join
methods</firstterm> (e.g., nested loop, hash join, merge join in methods</firstterm> (e.g., nested loop, hash join, merge join in
<productname>PostgreSQL</productname>) to process individual joins <productname>PostgreSQL</productname>) to process individual joins
and a diversity of <firstterm>indexes</firstterm> (e.g., R-tree, and a diversity of <firstterm>indexes</firstterm> (e.g.,
B-tree, hash in <productname>PostgreSQL</productname>) as access B-tree, hash, GiST in <productname>PostgreSQL</productname>) as access
paths for relations. paths for relations.
</para> </para>
......
<!-- <!--
$PostgreSQL: pgsql/doc/src/sgml/gist.sgml,v 1.24 2005/11/04 23:14:00 petere Exp $ $PostgreSQL: pgsql/doc/src/sgml/gist.sgml,v 1.25 2005/11/07 17:36:44 tgl Exp $
--> -->
<chapter id="GiST"> <chapter id="GiST">
<title>GiST Indexes</title> <title>GiST Indexes</title>
<sect1 id="gist-intro">
<title>Introduction</title>
<para>
<indexterm> <indexterm>
<primary>index</primary> <primary>index</primary>
<secondary>GiST</secondary> <secondary>GiST</secondary>
</indexterm> </indexterm>
<indexterm>
<primary>GiST</primary> <sect1 id="gist-intro">
<see>index</see> <title>Introduction</title>
</indexterm>
<para>
<acronym>GiST</acronym> stands for Generalized Search Tree. It is a <acronym>GiST</acronym> stands for Generalized Search Tree. It is a
balanced, tree-structured access method, that acts as a base template in balanced, tree-structured access method, that acts as a base template in
which to implement arbitrary indexing schemes. B+-trees, R-trees and many which to implement arbitrary indexing schemes. B-trees, R-trees and many
other indexing schemes can be implemented in <acronym>GiST</acronym>. other indexing schemes can be implemented in <acronym>GiST</acronym>.
</para> </para>
...@@ -60,17 +57,17 @@ $PostgreSQL: pgsql/doc/src/sgml/gist.sgml,v 1.24 2005/11/04 23:14:00 petere Exp ...@@ -60,17 +57,17 @@ $PostgreSQL: pgsql/doc/src/sgml/gist.sgml,v 1.24 2005/11/04 23:14:00 petere Exp
<para> <para>
This extensibility should not be confused with the extensibility of the This extensibility should not be confused with the extensibility of the
other standard search trees in terms of the data they can handle. For other standard search trees in terms of the data they can handle. For
example, <productname>PostgreSQL</productname> supports extensible B+-trees example, <productname>PostgreSQL</productname> supports extensible B-trees
and R-trees. That means that you can use and hash indexes. That means that you can use
<productname>PostgreSQL</productname> to build a B+-tree or R-tree over any <productname>PostgreSQL</productname> to build a B-tree or hash over any
data type you want. But B+-trees only support range predicates data type you want. But B-trees only support range predicates
(<literal>&lt;</literal>, <literal>=</literal>, <literal>&gt;</literal>), (<literal>&lt;</literal>, <literal>=</literal>, <literal>&gt;</literal>),
and R-trees only support n-D range queries (contains, contained, equals). and hash indexes only support equality queries.
</para> </para>
<para> <para>
So if you index, say, an image collection with a So if you index, say, an image collection with a
<productname>PostgreSQL</productname> B+-tree, you can only issue queries <productname>PostgreSQL</productname> B-tree, you can only issue queries
such as <quote>is imagex equal to imagey</quote>, <quote>is imagex less such as <quote>is imagex equal to imagey</quote>, <quote>is imagex less
than imagey</quote> and <quote>is imagex greater than imagey</quote>? than imagey</quote> and <quote>is imagex greater than imagey</quote>?
Depending on how you define <quote>equals</quote>, <quote>less than</quote> Depending on how you define <quote>equals</quote>, <quote>less than</quote>
...@@ -84,7 +81,7 @@ $PostgreSQL: pgsql/doc/src/sgml/gist.sgml,v 1.24 2005/11/04 23:14:00 petere Exp ...@@ -84,7 +81,7 @@ $PostgreSQL: pgsql/doc/src/sgml/gist.sgml,v 1.24 2005/11/04 23:14:00 petere Exp
All it takes to get a <acronym>GiST</acronym> access method up and running All it takes to get a <acronym>GiST</acronym> access method up and running
is to implement seven user-defined methods, which define the behavior of is to implement seven user-defined methods, which define the behavior of
keys in the tree. Of course these methods have to be pretty fancy to keys in the tree. Of course these methods have to be pretty fancy to
support fancy queries, but for all the standard queries (B+-trees, support fancy queries, but for all the standard queries (B-trees,
R-trees, etc.) they're relatively straightforward. In short, R-trees, etc.) they're relatively straightforward. In short,
<acronym>GiST</acronym> combines extensibility along with generality, code <acronym>GiST</acronym> combines extensibility along with generality, code
reuse, and a clean interface. reuse, and a clean interface.
......
<!-- $PostgreSQL: pgsql/doc/src/sgml/indices.sgml,v 1.54 2005/11/04 23:14:00 petere Exp $ --> <!-- $PostgreSQL: pgsql/doc/src/sgml/indices.sgml,v 1.55 2005/11/07 17:36:44 tgl Exp $ -->
<chapter id="indexes"> <chapter id="indexes">
<title id="indexes-title">Indexes</title> <title id="indexes-title">Indexes</title>
...@@ -104,7 +104,7 @@ CREATE INDEX test1_id_index ON test1 (id); ...@@ -104,7 +104,7 @@ CREATE INDEX test1_id_index ON test1 (id);
<para> <para>
<productname>PostgreSQL</productname> provides several index types: <productname>PostgreSQL</productname> provides several index types:
B-tree, R-tree, Hash, and GiST. Each index type uses a different B-tree, Hash, and GiST. Each index type uses a different
algorithm that is best suited to different types of queries. algorithm that is best suited to different types of queries.
By default, the <command>CREATE INDEX</command> command will create a By default, the <command>CREATE INDEX</command> command will create a
B-tree index, which fits the most common situations. B-tree index, which fits the most common situations.
...@@ -152,43 +152,6 @@ CREATE INDEX test1_id_index ON test1 (id); ...@@ -152,43 +152,6 @@ CREATE INDEX test1_id_index ON test1 (id);
See <xref linkend="indexes-opclass"> below. See <xref linkend="indexes-opclass"> below.
</para> </para>
<para>
<indexterm>
<primary>index</primary>
<secondary>R-tree</secondary>
</indexterm>
<indexterm>
<primary>R-tree</primary>
<see>index</see>
</indexterm>
R-tree indexes are suited for queries on two-dimensional spatial data.
To create an R-tree index, use a command of the form
<synopsis>
CREATE INDEX <replaceable>name</replaceable> ON <replaceable>table</replaceable> USING rtree (<replaceable>column</replaceable>);
</synopsis>
The <productname>PostgreSQL</productname> query planner will
consider using an R-tree index whenever an indexed column is
involved in a comparison using one of these operators:
<simplelist>
<member><literal>&lt;&lt;</literal></member>
<member><literal>&amp;&lt;</literal></member>
<member><literal>&amp;&gt;</literal></member>
<member><literal>&gt;&gt;</literal></member>
<member><literal>&lt;&lt;|</literal></member>
<member><literal>&amp;&lt;|</literal></member>
<member><literal>|&amp;&gt;</literal></member>
<member><literal>|&gt;&gt;</literal></member>
<member><literal>~</literal></member>
<member><literal>@</literal></member>
<member><literal>~=</literal></member>
<member><literal>&amp;&amp;</literal></member>
</simplelist>
(See <xref linkend="functions-geometry"> for the meaning of
these operators.)
</para>
<para> <para>
<indexterm> <indexterm>
<primary>index</primary> <primary>index</primary>
...@@ -208,18 +171,6 @@ CREATE INDEX <replaceable>name</replaceable> ON <replaceable>table</replaceable> ...@@ -208,18 +171,6 @@ CREATE INDEX <replaceable>name</replaceable> ON <replaceable>table</replaceable>
</synopsis> </synopsis>
</para> </para>
<para>
GiST indexes are not a single kind of index, but rather an infrastructure
within which many different indexing strategies can be implemented.
Accordingly, the particular operators with which a GiST index can be
used vary depending on the indexing strategy (the <firstterm>operator
class</>). The standard distribution of
<productname>PostgreSQL</productname> includes GiST operator classes
equivalent to the R-tree operator classes, and many other GiST operator
classes are available in the <literal>contrib</> collection or as separate
projects. For more information see <xref linkend="GiST">.
</para>
<note> <note>
<para> <para>
Testing has shown <productname>PostgreSQL</productname>'s hash Testing has shown <productname>PostgreSQL</productname>'s hash
...@@ -230,21 +181,47 @@ CREATE INDEX <replaceable>name</replaceable> ON <replaceable>table</replaceable> ...@@ -230,21 +181,47 @@ CREATE INDEX <replaceable>name</replaceable> ON <replaceable>table</replaceable>
after a database crash. after a database crash.
For these reasons, hash index use is presently discouraged. For these reasons, hash index use is presently discouraged.
</para> </para>
</note>
<para> <para>
Similarly, R-tree indexes do not seem to have any performance <indexterm>
advantages compared to the equivalent operations of GiST indexes. <primary>index</primary>
Like hash indexes, they are not WAL-logged and may need <secondary>GiST</secondary>
reindexing after a database crash. </indexterm>
</para> <indexterm>
<primary>GiST</primary>
<see>index</see>
</indexterm>
GiST indexes are not a single kind of index, but rather an infrastructure
within which many different indexing strategies can be implemented.
Accordingly, the particular operators with which a GiST index can be
used vary depending on the indexing strategy (the <firstterm>operator
class</>). As an example, the standard distribution of
<productname>PostgreSQL</productname> includes GiST operator classes
for several two-dimensional geometric data types, which support indexed
queries using these operators:
<para> <simplelist>
While the problems with hash indexes may be fixed eventually, <member><literal>&lt;&lt;</literal></member>
it is likely that the R-tree index type will be retired in a future <member><literal>&amp;&lt;</literal></member>
release. Users are encouraged to migrate applications that use R-tree <member><literal>&amp;&gt;</literal></member>
indexes to GiST indexes. <member><literal>&gt;&gt;</literal></member>
</para> <member><literal>&lt;&lt;|</literal></member>
</note> <member><literal>&amp;&lt;|</literal></member>
<member><literal>|&amp;&gt;</literal></member>
<member><literal>|&gt;&gt;</literal></member>
<member><literal>~</literal></member>
<member><literal>@</literal></member>
<member><literal>~=</literal></member>
<member><literal>&amp;&amp;</literal></member>
</simplelist>
(See <xref linkend="functions-geometry"> for the meaning of
these operators.)
Many other GiST operator
classes are available in the <literal>contrib</> collection or as separate
projects. For more information see <xref linkend="GiST">.
</para>
</sect1> </sect1>
......
<!-- <!--
$PostgreSQL: pgsql/doc/src/sgml/mvcc.sgml,v 2.52 2005/10/21 01:41:28 tgl Exp $ $PostgreSQL: pgsql/doc/src/sgml/mvcc.sgml,v 2.53 2005/11/07 17:36:44 tgl Exp $
--> -->
<chapter id="mvcc"> <chapter id="mvcc">
...@@ -991,18 +991,6 @@ UPDATE accounts SET balance = balance - 100.00 WHERE acctnum = 22222; ...@@ -991,18 +991,6 @@ UPDATE accounts SET balance = balance - 100.00 WHERE acctnum = 22222;
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term>
R-tree indexes
</term>
<listitem>
<para>
Share/exclusive index-level locks are used for read/write access.
Locks are released after the entire command is done.
</para>
</listitem>
</varlistentry>
</variablelist> </variablelist>
</para> </para>
...@@ -1012,8 +1000,7 @@ UPDATE accounts SET balance = balance - 100.00 WHERE acctnum = 22222; ...@@ -1012,8 +1000,7 @@ UPDATE accounts SET balance = balance - 100.00 WHERE acctnum = 22222;
indexes, they are the recommended index type for concurrent indexes, they are the recommended index type for concurrent
applications that need to index scalar data. When dealing with applications that need to index scalar data. When dealing with
non-scalar data, B-trees are not useful, and GiST indexes should non-scalar data, B-trees are not useful, and GiST indexes should
be used instead. R-tree indexes are deprecated and are likely be used instead.
to disappear entirely in a future release.
</para> </para>
</sect1> </sect1>
</chapter> </chapter>
......
<!-- <!--
$PostgreSQL: pgsql/doc/src/sgml/ref/create_index.sgml,v 1.51 2005/01/04 00:39:53 tgl Exp $ $PostgreSQL: pgsql/doc/src/sgml/ref/create_index.sgml,v 1.52 2005/11/07 17:36:44 tgl Exp $
PostgreSQL documentation PostgreSQL documentation
--> -->
...@@ -34,7 +34,7 @@ CREATE [ UNIQUE ] INDEX <replaceable class="parameter">name</replaceable> ON <re ...@@ -34,7 +34,7 @@ CREATE [ UNIQUE ] INDEX <replaceable class="parameter">name</replaceable> ON <re
<command>CREATE INDEX</command> constructs an index <replaceable <command>CREATE INDEX</command> constructs an index <replaceable
class="parameter">index_name</replaceable> on the specified table. class="parameter">index_name</replaceable> on the specified table.
Indexes are primarily used to enhance database performance (though Indexes are primarily used to enhance database performance (though
inappropriate use will result in slower performance). inappropriate use can result in slower performance).
</para> </para>
<para> <para>
...@@ -55,11 +55,7 @@ CREATE [ UNIQUE ] INDEX <replaceable class="parameter">name</replaceable> ON <re ...@@ -55,11 +55,7 @@ CREATE [ UNIQUE ] INDEX <replaceable class="parameter">name</replaceable> ON <re
<para> <para>
<productname>PostgreSQL</productname> provides the index methods <productname>PostgreSQL</productname> provides the index methods
B-tree, R-tree, hash, and GiST. The B-tree index method is an B-tree, hash, and GiST. Users can also define their own index
implementation of Lehman-Yao high-concurrency B-trees. The R-tree
index method implements standard R-trees using Guttman's quadratic
split algorithm. The hash index method is an implementation of
Litwin's linear hashing. Users can also define their own index
methods, but that is fairly complicated. methods, but that is fairly complicated.
</para> </para>
...@@ -137,9 +133,9 @@ CREATE [ UNIQUE ] INDEX <replaceable class="parameter">name</replaceable> ON <re ...@@ -137,9 +133,9 @@ CREATE [ UNIQUE ] INDEX <replaceable class="parameter">name</replaceable> ON <re
<term><replaceable class="parameter">method</replaceable></term> <term><replaceable class="parameter">method</replaceable></term>
<listitem> <listitem>
<para> <para>
The name of the method to be used for the index. Choices are The name of the index method to be used. Choices are
<literal>btree</literal>, <literal>hash</literal>, <literal>btree</literal>, <literal>hash</literal>,
<literal>rtree</literal>, and <literal>gist</literal>. The and <literal>gist</literal>. The
default method is <literal>btree</literal>. default method is <literal>btree</literal>.
</para> </para>
</listitem> </listitem>
...@@ -243,6 +239,15 @@ CREATE [ UNIQUE ] INDEX <replaceable class="parameter">name</replaceable> ON <re ...@@ -243,6 +239,15 @@ CREATE [ UNIQUE ] INDEX <replaceable class="parameter">name</replaceable> ON <re
The best way to use indexes in such cases is to create a partial index The best way to use indexes in such cases is to create a partial index
using an <literal>IS NULL</> predicate. using an <literal>IS NULL</> predicate.
</para> </para>
<para>
Prior releases of <productname>PostgreSQL</productname> also had an
R-tree index method. This method has been removed because
it had no significant advantages over the GiST method.
If <literal>USING rtree</> is specified, <command>CREATE INDEX</>
will interpret it as <literal>USING gist</>, to simplify conversion
of old databases to GiST.
</para>
</refsect1> </refsect1>
<refsect1> <refsect1>
...@@ -270,13 +275,13 @@ CREATE INDEX code_idx ON films(code) TABLESPACE indexspace; ...@@ -270,13 +275,13 @@ CREATE INDEX code_idx ON films(code) TABLESPACE indexspace;
Is this example correct? Is this example correct?
</comment> </comment>
<para> <para>
To create a R-tree index on a point attribute so that we To create a GiST index on a point attribute so that we
can efficiently use box operators on the result of the can efficiently use box operators on the result of the
conversion function: conversion function:
</para> </para>
<programlisting> <programlisting>
CREATE INDEX pointloc CREATE INDEX pointloc
ON points USING RTREE (point2box(location) box_ops); ON points USING GIST (point2box(location) box_ops);
SELECT * FROM points SELECT * FROM points
WHERE point2box(points.pointloc) = boxes.box; WHERE point2box(points.pointloc) = boxes.box;
</programlisting> </programlisting>
......
<!-- <!--
$PostgreSQL: pgsql/doc/src/sgml/xindex.sgml,v 1.41 2005/07/19 01:27:59 neilc Exp $ $PostgreSQL: pgsql/doc/src/sgml/xindex.sgml,v 1.42 2005/11/07 17:36:44 tgl Exp $
--> -->
<sect1 id="xindex"> <sect1 id="xindex">
...@@ -170,8 +170,12 @@ $PostgreSQL: pgsql/doc/src/sgml/xindex.sgml,v 1.41 2005/07/19 01:27:59 neilc Exp ...@@ -170,8 +170,12 @@ $PostgreSQL: pgsql/doc/src/sgml/xindex.sgml,v 1.41 2005/07/19 01:27:59 neilc Exp
</table> </table>
<para> <para>
R-tree indexes express relationships in two-dimensional space. GiST indexes are even more flexible: they do not have a fixed set of
They use twelve strategies, shown in strategies at all. Instead, the <quote>consistency</> support routine
of each particular GiST operator class interprets the strategy numbers
however it likes. As an example, several of the built-in GiST index
operator classes index two-dimensional geometric objects, providing
the <quote>R-tree</> strategies shown in
<xref linkend="xindex-rtree-strat-table">. Four of these are true <xref linkend="xindex-rtree-strat-table">. Four of these are true
two-dimensional tests (overlaps, same, contains, contained by); two-dimensional tests (overlaps, same, contains, contained by);
four of them consider only the X direction; and the other four four of them consider only the X direction; and the other four
...@@ -179,7 +183,7 @@ $PostgreSQL: pgsql/doc/src/sgml/xindex.sgml,v 1.41 2005/07/19 01:27:59 neilc Exp ...@@ -179,7 +183,7 @@ $PostgreSQL: pgsql/doc/src/sgml/xindex.sgml,v 1.41 2005/07/19 01:27:59 neilc Exp
</para> </para>
<table tocentry="1" id="xindex-rtree-strat-table"> <table tocentry="1" id="xindex-rtree-strat-table">
<title>R-tree Strategies</title> <title>GiST Two-Dimensional <quote>R-tree</> Strategies</title>
<tgroup cols="2"> <tgroup cols="2">
<thead> <thead>
<row> <row>
...@@ -240,13 +244,6 @@ $PostgreSQL: pgsql/doc/src/sgml/xindex.sgml,v 1.41 2005/07/19 01:27:59 neilc Exp ...@@ -240,13 +244,6 @@ $PostgreSQL: pgsql/doc/src/sgml/xindex.sgml,v 1.41 2005/07/19 01:27:59 neilc Exp
</tgroup> </tgroup>
</table> </table>
<para>
GiST indexes are even more flexible: they do not have a fixed set of
strategies at all. Instead, the <quote>consistency</> support routine
of each particular GiST operator class interprets the strategy numbers
however it likes.
</para>
<para> <para>
Note that all strategy operators return Boolean values. In Note that all strategy operators return Boolean values. In
practice, all operators defined as index method strategies must practice, all operators defined as index method strategies must
...@@ -274,9 +271,8 @@ $PostgreSQL: pgsql/doc/src/sgml/xindex.sgml,v 1.41 2005/07/19 01:27:59 neilc Exp ...@@ -274,9 +271,8 @@ $PostgreSQL: pgsql/doc/src/sgml/xindex.sgml,v 1.41 2005/07/19 01:27:59 neilc Exp
additional support routines in order to work. For example, the B-tree additional support routines in order to work. For example, the B-tree
index method must be able to compare two keys and determine whether one index method must be able to compare two keys and determine whether one
is greater than, equal to, or less than the other. Similarly, the is greater than, equal to, or less than the other. Similarly, the
R-tree index method must be able to compute hash index method must be able to compute hash codes for key values.
intersections, unions, and sizes of rectangles. These These operations do not correspond to operators used in qualifications in
operations do not correspond to operators used in qualifications in
SQL commands; they are administrative routines used by SQL commands; they are administrative routines used by
the index methods, internally. the index methods, internally.
</para> </para>
...@@ -339,37 +335,6 @@ $PostgreSQL: pgsql/doc/src/sgml/xindex.sgml,v 1.41 2005/07/19 01:27:59 neilc Exp ...@@ -339,37 +335,6 @@ $PostgreSQL: pgsql/doc/src/sgml/xindex.sgml,v 1.41 2005/07/19 01:27:59 neilc Exp
</tgroup> </tgroup>
</table> </table>
<para>
R-tree indexes require three support functions,
shown in <xref linkend="xindex-rtree-support-table">.
</para>
<table tocentry="1" id="xindex-rtree-support-table">
<title>R-tree Support Functions</title>
<tgroup cols="2">
<thead>
<row>
<entry>Function</entry>
<entry>Support Number</entry>
</row>
</thead>
<tbody>
<row>
<entry>union</entry>
<entry>1</entry>
</row>
<row>
<entry>intersection</entry>
<entry>2</entry>
</row>
<row>
<entry>size</entry>
<entry>3</entry>
</row>
</tbody>
</tgroup>
</table>
<para> <para>
GiST indexes require seven support functions, GiST indexes require seven support functions,
shown in <xref linkend="xindex-gist-support-table">. shown in <xref linkend="xindex-gist-support-table">.
...@@ -746,7 +711,7 @@ SELECT * FROM table WHERE integer_column &lt; 4; ...@@ -746,7 +711,7 @@ SELECT * FROM table WHERE integer_column &lt; 4;
</programlisting> </programlisting>
can be satisfied exactly by a B-tree index on the integer column. can be satisfied exactly by a B-tree index on the integer column.
But there are cases where an index is useful as an inexact guide to But there are cases where an index is useful as an inexact guide to
the matching rows. For example, if an R-tree index stores only the matching rows. For example, if a GiST index stores only
bounding boxes for objects, then it cannot exactly satisfy a <literal>WHERE</> bounding boxes for objects, then it cannot exactly satisfy a <literal>WHERE</>
condition that tests overlap between nonrectangular objects such as condition that tests overlap between nonrectangular objects such as
polygons. Yet we could use the index to find objects whose bounding polygons. Yet we could use the index to find objects whose bounding
......
# #
# Makefile for the access methods module # Makefile for the access methods module
# #
# $PostgreSQL: pgsql/src/backend/access/Makefile,v 1.9 2003/11/29 19:51:39 pgsql Exp $ # $PostgreSQL: pgsql/src/backend/access/Makefile,v 1.10 2005/11/07 17:36:44 tgl Exp $
# #
subdir = src/backend/access subdir = src/backend/access
top_builddir = ../../.. top_builddir = ../../..
include $(top_builddir)/src/Makefile.global include $(top_builddir)/src/Makefile.global
SUBDIRS := common gist hash heap index nbtree rtree transam SUBDIRS := common gist hash heap index nbtree transam
SUBDIROBJS := $(SUBDIRS:%=%/SUBSYS.o) SUBDIROBJS := $(SUBDIRS:%=%/SUBSYS.o)
all: SUBSYS.o all: SUBSYS.o
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/access/gist/gistproc.c,v 1.3 2005/10/15 02:49:08 momjian Exp $ * $PostgreSQL: pgsql/src/backend/access/gist/gistproc.c,v 1.4 2005/11/07 17:36:44 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
#include "access/gist.h" #include "access/gist.h"
#include "access/itup.h" #include "access/itup.h"
#include "access/rtree.h" #include "access/skey.h"
#include "utils/geo_decls.h" #include "utils/geo_decls.h"
...@@ -40,6 +40,47 @@ static bool rtree_internal_consistent(BOX *key, BOX *query, ...@@ -40,6 +40,47 @@ static bool rtree_internal_consistent(BOX *key, BOX *query,
* Box ops * Box ops
**************************************************/ **************************************************/
static Datum
rt_box_union(PG_FUNCTION_ARGS)
{
BOX *a = PG_GETARG_BOX_P(0);
BOX *b = PG_GETARG_BOX_P(1);
BOX *n;
n = (BOX *) palloc(sizeof(BOX));
n->high.x = Max(a->high.x, b->high.x);
n->high.y = Max(a->high.y, b->high.y);
n->low.x = Min(a->low.x, b->low.x);
n->low.y = Min(a->low.y, b->low.y);
PG_RETURN_BOX_P(n);
}
static Datum
rt_box_inter(PG_FUNCTION_ARGS)
{
BOX *a = PG_GETARG_BOX_P(0);
BOX *b = PG_GETARG_BOX_P(1);
BOX *n;
n = (BOX *) palloc(sizeof(BOX));
n->high.x = Min(a->high.x, b->high.x);
n->high.y = Min(a->high.y, b->high.y);
n->low.x = Max(a->low.x, b->low.x);
n->low.y = Max(a->low.y, b->low.y);
if (n->high.x < n->low.x || n->high.y < n->low.y)
{
pfree(n);
/* Indicate "no intersection" by returning NULL pointer */
n = NULL;
}
PG_RETURN_BOX_P(n);
}
/* /*
* The GiST Consistent method for boxes * The GiST Consistent method for boxes
* *
...@@ -493,8 +534,6 @@ size_box(Datum dbox) ...@@ -493,8 +534,6 @@ size_box(Datum dbox)
* *
* We can use the same function since all types use bounding boxes as the * We can use the same function since all types use bounding boxes as the
* internal-page representation. * internal-page representation.
*
* This implements the same logic as the rtree internal-page strategy map.
*/ */
static bool static bool
rtree_internal_consistent(BOX *key, BOX *query, StrategyNumber strategy) rtree_internal_consistent(BOX *key, BOX *query, StrategyNumber strategy)
......
#-------------------------------------------------------------------------
#
# Makefile--
# Makefile for access/rtree
#
# IDENTIFICATION
# $PostgreSQL: pgsql/src/backend/access/rtree/Makefile,v 1.11 2003/11/29 19:51:40 pgsql Exp $
#
#-------------------------------------------------------------------------
subdir = src/backend/access/rtree
top_builddir = ../../../..
include $(top_builddir)/src/Makefile.global
OBJS = rtget.o rtproc.o rtree.o rtscan.o rtstrat.o
all: SUBSYS.o
SUBSYS.o: $(OBJS)
$(LD) $(LDREL) $(LDOUT) SUBSYS.o $(OBJS)
depend dep:
$(CC) -MM $(CFLAGS) *.c >depend
clean:
rm -f SUBSYS.o $(OBJS)
ifeq (depend,$(wildcard depend))
include depend
endif
/*-------------------------------------------------------------------------
*
* rtget.c
* fetch tuples from an rtree scan.
*
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/access/rtree/rtget.c,v 1.37 2005/10/15 02:49:09 momjian Exp $
*
*-------------------------------------------------------------------------
*/
#include "postgres.h"
#include "access/iqual.h"
#include "access/relscan.h"
#include "access/rtree.h"
#include "pgstat.h"
static OffsetNumber findnext(IndexScanDesc s, OffsetNumber n,
ScanDirection dir);
static bool rtnext(IndexScanDesc s, ScanDirection dir);
Datum
rtgettuple(PG_FUNCTION_ARGS)
{
IndexScanDesc s = (IndexScanDesc) PG_GETARG_POINTER(0);
ScanDirection dir = (ScanDirection) PG_GETARG_INT32(1);
RTreeScanOpaque so = (RTreeScanOpaque) s->opaque;
Page page;
OffsetNumber offnum;
/*
* If we've already produced a tuple and the executor has informed us that
* it should be marked "killed", do so now.
*/
if (s->kill_prior_tuple && ItemPointerIsValid(&(s->currentItemData)))
{
offnum = ItemPointerGetOffsetNumber(&(s->currentItemData));
page = BufferGetPage(so->curbuf);
PageGetItemId(page, offnum)->lp_flags |= LP_DELETE;
SetBufferCommitInfoNeedsSave(so->curbuf);
}
/*
* Get the next tuple that matches the search key; if asked to skip killed
* tuples, find the first non-killed tuple that matches. Return as soon as
* we've run out of matches or we've found an acceptable match.
*/
for (;;)
{
bool res = rtnext(s, dir);
if (res && s->ignore_killed_tuples)
{
offnum = ItemPointerGetOffsetNumber(&(s->currentItemData));
page = BufferGetPage(so->curbuf);
if (ItemIdDeleted(PageGetItemId(page, offnum)))
continue;
}
PG_RETURN_BOOL(res);
}
}
Datum
rtgetmulti(PG_FUNCTION_ARGS)
{
IndexScanDesc s = (IndexScanDesc) PG_GETARG_POINTER(0);
ItemPointer tids = (ItemPointer) PG_GETARG_POINTER(1);
int32 max_tids = PG_GETARG_INT32(2);
int32 *returned_tids = (int32 *) PG_GETARG_POINTER(3);
RTreeScanOpaque so = (RTreeScanOpaque) s->opaque;
bool res = true;
int32 ntids = 0;
/* XXX generic implementation: loop around guts of rtgettuple */
while (ntids < max_tids)
{
res = rtnext(s, ForwardScanDirection);
if (res && s->ignore_killed_tuples)
{
Page page;
OffsetNumber offnum;
offnum = ItemPointerGetOffsetNumber(&(s->currentItemData));
page = BufferGetPage(so->curbuf);
if (ItemIdDeleted(PageGetItemId(page, offnum)))
continue;
}
if (!res)
break;
tids[ntids] = s->xs_ctup.t_self;
ntids++;
}
*returned_tids = ntids;
PG_RETURN_BOOL(res);
}
static bool
rtnext(IndexScanDesc s, ScanDirection dir)
{
Page p;
OffsetNumber n;
RTreePageOpaque po;
RTreeScanOpaque so;
so = (RTreeScanOpaque) s->opaque;
if (!ItemPointerIsValid(&(s->currentItemData)))
{
/* first call: start at the root */
Assert(BufferIsValid(so->curbuf) == false);
so->curbuf = ReadBuffer(s->indexRelation, P_ROOT);
pgstat_count_index_scan(&s->xs_pgstat_info);
}
p = BufferGetPage(so->curbuf);
po = (RTreePageOpaque) PageGetSpecialPointer(p);
if (!ItemPointerIsValid(&(s->currentItemData)))
{
/* first call: start at first/last offset */
if (ScanDirectionIsForward(dir))
n = FirstOffsetNumber;
else
n = PageGetMaxOffsetNumber(p);
}
else
{
/* go on to the next offset */
n = ItemPointerGetOffsetNumber(&(s->currentItemData));
if (ScanDirectionIsForward(dir))
n = OffsetNumberNext(n);
else
n = OffsetNumberPrev(n);
}
for (;;)
{
IndexTuple it;
RTSTACK *stk;
n = findnext(s, n, dir);
/* no match on this page, so read in the next stack entry */
if (n == InvalidOffsetNumber)
{
/* if out of stack entries, we're done */
if (so->s_stack == NULL)
{
ReleaseBuffer(so->curbuf);
so->curbuf = InvalidBuffer;
return false;
}
stk = so->s_stack;
so->curbuf = ReleaseAndReadBuffer(so->curbuf, s->indexRelation,
stk->rts_blk);
p = BufferGetPage(so->curbuf);
po = (RTreePageOpaque) PageGetSpecialPointer(p);
if (ScanDirectionIsBackward(dir))
n = OffsetNumberPrev(stk->rts_child);
else
n = OffsetNumberNext(stk->rts_child);
so->s_stack = stk->rts_parent;
pfree(stk);
continue;
}
if (po->flags & F_LEAF)
{
ItemPointerSet(&(s->currentItemData),
BufferGetBlockNumber(so->curbuf),
n);
it = (IndexTuple) PageGetItem(p, PageGetItemId(p, n));
s->xs_ctup.t_self = it->t_tid;
return true;
}
else
{
BlockNumber blk;
stk = (RTSTACK *) palloc(sizeof(RTSTACK));
stk->rts_child = n;
stk->rts_blk = BufferGetBlockNumber(so->curbuf);
stk->rts_parent = so->s_stack;
so->s_stack = stk;
it = (IndexTuple) PageGetItem(p, PageGetItemId(p, n));
blk = ItemPointerGetBlockNumber(&(it->t_tid));
/*
* Note that we release the pin on the page as we descend down the
* tree, even though there's a good chance we'll eventually need
* to re-read the buffer later in this scan. This may or may not
* be optimal, but it doesn't seem likely to make a huge
* performance difference either way.
*/
so->curbuf = ReleaseAndReadBuffer(so->curbuf, s->indexRelation, blk);
p = BufferGetPage(so->curbuf);
po = (RTreePageOpaque) PageGetSpecialPointer(p);
if (ScanDirectionIsBackward(dir))
n = PageGetMaxOffsetNumber(p);
else
n = FirstOffsetNumber;
}
}
}
/*
* Return the offset of the next matching index entry. We begin the
* search at offset "n" and search for matches in the direction
* "dir". If no more matching entries are found on the page,
* InvalidOffsetNumber is returned.
*/
static OffsetNumber
findnext(IndexScanDesc s, OffsetNumber n, ScanDirection dir)
{
OffsetNumber maxoff;
IndexTuple it;
RTreePageOpaque po;
RTreeScanOpaque so;
Page p;
so = (RTreeScanOpaque) s->opaque;
p = BufferGetPage(so->curbuf);
maxoff = PageGetMaxOffsetNumber(p);
po = (RTreePageOpaque) PageGetSpecialPointer(p);
/*
* If we modified the index during the scan, we may have a pointer to a
* ghost tuple, before the scan. If this is the case, back up one.
*/
if (so->s_flags & RTS_CURBEFORE)
{
so->s_flags &= ~RTS_CURBEFORE;
n = OffsetNumberPrev(n);
}
while (n >= FirstOffsetNumber && n <= maxoff)
{
it = (IndexTuple) PageGetItem(p, PageGetItemId(p, n));
if (po->flags & F_LEAF)
{
if (index_keytest(it,
RelationGetDescr(s->indexRelation),
s->numberOfKeys, s->keyData))
break;
}
else
{
if (index_keytest(it,
RelationGetDescr(s->indexRelation),
so->s_internalNKey, so->s_internalKey))
break;
}
if (ScanDirectionIsBackward(dir))
n = OffsetNumberPrev(n);
else
n = OffsetNumberNext(n);
}
if (n >= FirstOffsetNumber && n <= maxoff)
return n; /* found a match on this page */
else
return InvalidOffsetNumber; /* no match, go to next page */
}
/*-------------------------------------------------------------------------
*
* rtproc.c
* pg_amproc entries for rtrees.
*
* NOTE: for largely-historical reasons, the intersection functions should
* return a NULL pointer (*not* an SQL null value) to indicate "no
* intersection". The size functions must be prepared to accept such
* a pointer and return 0. This convention means that only pass-by-reference
* data types can be used as the output of the union and intersection
* routines, but that's not a big problem.
*
*
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/access/rtree/rtproc.c,v 1.43 2005/10/15 02:49:09 momjian Exp $
*
*-------------------------------------------------------------------------
*/
#include "postgres.h"
#include "utils/geo_decls.h"
Datum
rt_box_union(PG_FUNCTION_ARGS)
{
BOX *a = PG_GETARG_BOX_P(0);
BOX *b = PG_GETARG_BOX_P(1);
BOX *n;
n = (BOX *) palloc(sizeof(BOX));
n->high.x = Max(a->high.x, b->high.x);
n->high.y = Max(a->high.y, b->high.y);
n->low.x = Min(a->low.x, b->low.x);
n->low.y = Min(a->low.y, b->low.y);
PG_RETURN_BOX_P(n);
}
Datum
rt_box_inter(PG_FUNCTION_ARGS)
{
BOX *a = PG_GETARG_BOX_P(0);
BOX *b = PG_GETARG_BOX_P(1);
BOX *n;
n = (BOX *) palloc(sizeof(BOX));
n->high.x = Min(a->high.x, b->high.x);
n->high.y = Min(a->high.y, b->high.y);
n->low.x = Max(a->low.x, b->low.x);
n->low.y = Max(a->low.y, b->low.y);
if (n->high.x < n->low.x || n->high.y < n->low.y)
{
pfree(n);
/* Indicate "no intersection" by returning NULL pointer */
n = NULL;
}
PG_RETURN_BOX_P(n);
}
Datum
rt_box_size(PG_FUNCTION_ARGS)
{
BOX *a = PG_GETARG_BOX_P(0);
/* NB: size is an output argument */
float *size = (float *) PG_GETARG_POINTER(1);
if (a == NULL || a->high.x <= a->low.x || a->high.y <= a->low.y)
*size = 0.0;
else
*size = (float) ((a->high.x - a->low.x) * (a->high.y - a->low.y));
PG_RETURN_VOID();
}
Datum
rt_poly_union(PG_FUNCTION_ARGS)
{
POLYGON *a = PG_GETARG_POLYGON_P(0);
POLYGON *b = PG_GETARG_POLYGON_P(1);
POLYGON *p;
p = (POLYGON *) palloc0(sizeof(POLYGON)); /* zero any holes */
p->size = sizeof(POLYGON);
p->npts = 0;
p->boundbox.high.x = Max(a->boundbox.high.x, b->boundbox.high.x);
p->boundbox.high.y = Max(a->boundbox.high.y, b->boundbox.high.y);
p->boundbox.low.x = Min(a->boundbox.low.x, b->boundbox.low.x);
p->boundbox.low.y = Min(a->boundbox.low.y, b->boundbox.low.y);
/* Avoid leaking memory when handed toasted input. */
PG_FREE_IF_COPY(a, 0);
PG_FREE_IF_COPY(b, 1);
PG_RETURN_POLYGON_P(p);
}
Datum
rt_poly_inter(PG_FUNCTION_ARGS)
{
POLYGON *a = PG_GETARG_POLYGON_P(0);
POLYGON *b = PG_GETARG_POLYGON_P(1);
POLYGON *p;
p = (POLYGON *) palloc0(sizeof(POLYGON)); /* zero any holes */
p->size = sizeof(POLYGON);
p->npts = 0;
p->boundbox.high.x = Min(a->boundbox.high.x, b->boundbox.high.x);
p->boundbox.high.y = Min(a->boundbox.high.y, b->boundbox.high.y);
p->boundbox.low.x = Max(a->boundbox.low.x, b->boundbox.low.x);
p->boundbox.low.y = Max(a->boundbox.low.y, b->boundbox.low.y);
if (p->boundbox.high.x < p->boundbox.low.x ||
p->boundbox.high.y < p->boundbox.low.y)
{
pfree(p);
/* Indicate "no intersection" by returning NULL pointer */
p = NULL;
}
/* Avoid leaking memory when handed toasted input. */
PG_FREE_IF_COPY(a, 0);
PG_FREE_IF_COPY(b, 1);
PG_RETURN_POLYGON_P(p);
}
Datum
rt_poly_size(PG_FUNCTION_ARGS)
{
Pointer aptr = PG_GETARG_POINTER(0);
/* NB: size is an output argument */
float *size = (float *) PG_GETARG_POINTER(1);
POLYGON *a;
double xdim,
ydim;
/*
* Can't just use GETARG because of possibility that input is NULL; since
* POLYGON is toastable, GETARG will try to inspect its value
*/
if (aptr == NULL)
{
*size = 0.0;
PG_RETURN_VOID();
}
/* Now safe to apply GETARG */
a = PG_GETARG_POLYGON_P(0);
if (a->boundbox.high.x <= a->boundbox.low.x ||
a->boundbox.high.y <= a->boundbox.low.y)
*size = 0.0;
else
{
xdim = (a->boundbox.high.x - a->boundbox.low.x);
ydim = (a->boundbox.high.y - a->boundbox.low.y);
*size = (float) (xdim * ydim);
}
/* Avoid leaking memory when handed toasted input. */
PG_FREE_IF_COPY(a, 0);
PG_RETURN_VOID();
}
This diff is collapsed.
This diff is collapsed.
/*-------------------------------------------------------------------------
*
* rtstrat.c
* strategy map data for rtrees.
*
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/access/rtree/rtstrat.c,v 1.27 2005/06/24 20:53:30 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#include "postgres.h"
#include "access/rtree.h"
/*
* Here's something peculiar to rtrees that doesn't apply to most other
* indexing structures: When we're searching a tree for a given value, we
* can't do the same sorts of comparisons on internal node entries as we
* do at leaves. The reason is that if we're looking for (say) all boxes
* that are the same as (0,0,10,10), then we need to find all leaf pages
* that overlap that region. So internally we search for overlap, and at
* the leaf we search for equality.
*
* This array maps leaf search operators to the internal search operators.
*/
static const StrategyNumber RTOperMap[RTNStrategies] = {
RTOverRightStrategyNumber, /* left */
RTRightStrategyNumber, /* overleft */
RTOverlapStrategyNumber, /* overlap */
RTLeftStrategyNumber, /* overright */
RTOverLeftStrategyNumber, /* right */
RTContainsStrategyNumber, /* same */
RTContainsStrategyNumber, /* contains */
RTOverlapStrategyNumber, /* contained-by */
RTAboveStrategyNumber, /* overbelow */
RTOverAboveStrategyNumber, /* below */
RTOverBelowStrategyNumber, /* above */
RTBelowStrategyNumber /* overabove */
};
/*
* We may need to negate the result of the selected operator. (This could
* be avoided by expanding the set of operators required for an opclass.)
*/
static const bool RTNegateMap[RTNStrategies] = {
true, /* left */
true, /* overleft */
false, /* overlap */
true, /* overright */
true, /* right */
false, /* same */
false, /* contains */
false, /* contained-by */
true, /* overbelow */
true, /* below */
true, /* above */
true /* overabove */
};
StrategyNumber
RTMapToInternalOperator(StrategyNumber strat)
{
Assert(strat > 0 && strat <= RTNStrategies);
return RTOperMap[strat - 1];
}
bool
RTMapToInternalNegate(StrategyNumber strat)
{
Assert(strat > 0 && strat <= RTNStrategies);
return RTNegateMap[strat - 1];
}
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* *
* Resource managers definition * Resource managers definition
* *
* $PostgreSQL: pgsql/src/backend/access/transam/rmgr.c,v 1.20 2005/06/14 11:45:14 teodor Exp $ * $PostgreSQL: pgsql/src/backend/access/transam/rmgr.c,v 1.21 2005/11/07 17:36:45 tgl Exp $
*/ */
#include "postgres.h" #include "postgres.h"
...@@ -13,7 +13,6 @@ ...@@ -13,7 +13,6 @@
#include "access/heapam.h" #include "access/heapam.h"
#include "access/multixact.h" #include "access/multixact.h"
#include "access/nbtree.h" #include "access/nbtree.h"
#include "access/rtree.h"
#include "access/xact.h" #include "access/xact.h"
#include "access/xlog_internal.h" #include "access/xlog_internal.h"
#include "commands/dbcommands.h" #include "commands/dbcommands.h"
...@@ -36,7 +35,7 @@ const RmgrData RmgrTable[RM_MAX_ID + 1] = { ...@@ -36,7 +35,7 @@ const RmgrData RmgrTable[RM_MAX_ID + 1] = {
{"Heap", heap_redo, heap_desc, NULL, NULL}, {"Heap", heap_redo, heap_desc, NULL, NULL},
{"Btree", btree_redo, btree_desc, btree_xlog_startup, btree_xlog_cleanup}, {"Btree", btree_redo, btree_desc, btree_xlog_startup, btree_xlog_cleanup},
{"Hash", hash_redo, hash_desc, NULL, NULL}, {"Hash", hash_redo, hash_desc, NULL, NULL},
{"Rtree", rtree_redo, rtree_desc, NULL, NULL}, {"Reserved 13", NULL, NULL, NULL, NULL},
{"Gist", gist_redo, gist_desc, gist_xlog_startup, gist_xlog_cleanup}, {"Gist", gist_redo, gist_desc, gist_xlog_startup, gist_xlog_cleanup},
{"Sequence", seq_redo, seq_desc, NULL, NULL} {"Sequence", seq_redo, seq_desc, NULL, NULL}
}; };
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/commands/indexcmds.c,v 1.134 2005/10/15 02:49:15 momjian Exp $ * $PostgreSQL: pgsql/src/backend/commands/indexcmds.c,v 1.135 2005/11/07 17:36:45 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -226,10 +226,27 @@ DefineIndex(RangeVar *heapRelation, ...@@ -226,10 +226,27 @@ DefineIndex(RangeVar *heapRelation,
PointerGetDatum(accessMethodName), PointerGetDatum(accessMethodName),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(tuple)) if (!HeapTupleIsValid(tuple))
ereport(ERROR, {
(errcode(ERRCODE_UNDEFINED_OBJECT), /*
errmsg("access method \"%s\" does not exist", * Hack to provide more-or-less-transparent updating of old RTREE
accessMethodName))); * indexes to GIST: if RTREE is requested and not found, use GIST.
*/
if (strcmp(accessMethodName, "rtree") == 0)
{
ereport(NOTICE,
(errmsg("substituting access method \"gist\" for obsolete method \"rtree\"")));
accessMethodName = "gist";
tuple = SearchSysCache(AMNAME,
PointerGetDatum(accessMethodName),
0, 0, 0);
}
if (!HeapTupleIsValid(tuple))
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("access method \"%s\" does not exist",
accessMethodName)));
}
accessMethodId = HeapTupleGetOid(tuple); accessMethodId = HeapTupleGetOid(tuple);
accessMethodForm = (Form_pg_am) GETSTRUCT(tuple); accessMethodForm = (Form_pg_am) GETSTRUCT(tuple);
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/adt/geo_selfuncs.c,v 1.24 2004/12/31 22:01:22 pgsql Exp $ * $PostgreSQL: pgsql/src/backend/utils/adt/geo_selfuncs.c,v 1.25 2005/11/07 17:36:45 tgl Exp $
* *
* XXX These are totally bogus. Perhaps someone will make them do * XXX These are totally bogus. Perhaps someone will make them do
* something reasonable, someday. * something reasonable, someday.
...@@ -22,19 +22,19 @@ ...@@ -22,19 +22,19 @@
/* /*
* Selectivity functions for rtrees. These are bogus -- unless we know * Selectivity functions for geometric operators. These are bogus -- unless
* the actual key distribution in the index, we can't make a good prediction * we know the actual key distribution in the index, we can't make a good
* of the selectivity of these operators. * prediction of the selectivity of these operators.
* *
* Note: the values used here may look unreasonably small. Perhaps they * Note: the values used here may look unreasonably small. Perhaps they
* are. For now, we want to make sure that the optimizer will make use * are. For now, we want to make sure that the optimizer will make use
* of an r-tree index if one is available, so the selectivity had better * of a geometric index if one is available, so the selectivity had better
* be fairly small. * be fairly small.
* *
* In general, rtrees need to search multiple subtrees in order to guarantee * In general, GiST needs to search multiple subtrees in order to guarantee
* that all occurrences of the same key have been found. Because of this, * that all occurrences of the same key have been found. Because of this,
* the estimated cost for scanning the index ought to be higher than the * the estimated cost for scanning the index ought to be higher than the
* output selectivity would indicate. rtcostestimate(), over in selfuncs.c, * output selectivity would indicate. gistcostestimate(), over in selfuncs.c,
* ought to be adjusted accordingly --- but until we can generate somewhat * ought to be adjusted accordingly --- but until we can generate somewhat
* realistic numbers here, it hardly matters... * realistic numbers here, it hardly matters...
*/ */
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/adt/selfuncs.c,v 1.191 2005/10/15 02:49:29 momjian Exp $ * $PostgreSQL: pgsql/src/backend/utils/adt/selfuncs.c,v 1.192 2005/11/07 17:36:45 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -4470,24 +4470,6 @@ btcostestimate(PG_FUNCTION_ARGS) ...@@ -4470,24 +4470,6 @@ btcostestimate(PG_FUNCTION_ARGS)
PG_RETURN_VOID(); PG_RETURN_VOID();
} }
Datum
rtcostestimate(PG_FUNCTION_ARGS)
{
PlannerInfo *root = (PlannerInfo *) PG_GETARG_POINTER(0);
IndexOptInfo *index = (IndexOptInfo *) PG_GETARG_POINTER(1);
List *indexQuals = (List *) PG_GETARG_POINTER(2);
Cost *indexStartupCost = (Cost *) PG_GETARG_POINTER(3);
Cost *indexTotalCost = (Cost *) PG_GETARG_POINTER(4);
Selectivity *indexSelectivity = (Selectivity *) PG_GETARG_POINTER(5);
double *indexCorrelation = (double *) PG_GETARG_POINTER(6);
genericcostestimate(root, index, indexQuals, 0.0,
indexStartupCost, indexTotalCost,
indexSelectivity, indexCorrelation);
PG_RETURN_VOID();
}
Datum Datum
hashcostestimate(PG_FUNCTION_ARGS) hashcostestimate(PG_FUNCTION_ARGS)
{ {
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/resowner/resowner.c,v 1.14 2005/10/15 02:49:36 momjian Exp $ * $PostgreSQL: pgsql/src/backend/utils/resowner/resowner.c,v 1.15 2005/11/07 17:36:45 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -23,7 +23,6 @@ ...@@ -23,7 +23,6 @@
#include "utils/resowner.h" #include "utils/resowner.h"
#include "access/gistscan.h" #include "access/gistscan.h"
#include "access/hash.h" #include "access/hash.h"
#include "access/rtree.h"
#include "storage/bufmgr.h" #include "storage/bufmgr.h"
#include "storage/proc.h" #include "storage/proc.h"
#include "utils/memutils.h" #include "utils/memutils.h"
...@@ -280,7 +279,6 @@ ResourceOwnerReleaseInternal(ResourceOwner owner, ...@@ -280,7 +279,6 @@ ResourceOwnerReleaseInternal(ResourceOwner owner,
/* Clean up index scans too */ /* Clean up index scans too */
ReleaseResources_gist(); ReleaseResources_gist();
ReleaseResources_hash(); ReleaseResources_hash();
ReleaseResources_rtree();
} }
/* Let add-on modules get a chance too */ /* Let add-on modules get a chance too */
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* *
* Copyright (c) 2000-2005, PostgreSQL Global Development Group * Copyright (c) 2000-2005, PostgreSQL Global Development Group
* *
* $PostgreSQL: pgsql/src/bin/psql/tab-complete.c,v 1.138 2005/10/15 02:49:40 momjian Exp $ * $PostgreSQL: pgsql/src/bin/psql/tab-complete.c,v 1.139 2005/11/07 17:36:45 tgl Exp $
*/ */
/*---------------------------------------------------------------------- /*----------------------------------------------------------------------
...@@ -1025,7 +1025,7 @@ psql_completion(char *text, int start, int end) ...@@ -1025,7 +1025,7 @@ psql_completion(char *text, int start, int end)
else if (pg_strcasecmp(prev_wd, "USING") == 0) else if (pg_strcasecmp(prev_wd, "USING") == 0)
{ {
static const char *const index_mth[] = static const char *const index_mth[] =
{"BTREE", "RTREE", "HASH", "GIST", NULL}; {"BTREE", "HASH", "GIST", NULL};
COMPLETE_WITH_LIST(index_mth); COMPLETE_WITH_LIST(index_mth);
} }
......
...@@ -9,18 +9,18 @@ ...@@ -9,18 +9,18 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/access/gist.h,v 1.50 2005/10/15 02:49:42 momjian Exp $ * $PostgreSQL: pgsql/src/include/access/gist.h,v 1.51 2005/11/07 17:36:46 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
#ifndef GIST_H #ifndef GIST_H
#define GIST_H #define GIST_H
#include "access/xlog.h"
#include "access/xlogdefs.h"
#include "storage/bufpage.h" #include "storage/bufpage.h"
#include "storage/off.h" #include "storage/off.h"
#include "utils/rel.h" #include "utils/rel.h"
#include "access/xlog.h"
#include "access/xlogdefs.h"
/* /*
* amproc indexes for GiST indexes. * amproc indexes for GiST indexes.
...@@ -34,6 +34,23 @@ ...@@ -34,6 +34,23 @@
#define GIST_EQUAL_PROC 7 #define GIST_EQUAL_PROC 7
#define GISTNProcs 7 #define GISTNProcs 7
/*
* strategy numbers for GiST opclasses that want to implement the old
* RTREE behavior.
*/
#define RTLeftStrategyNumber 1
#define RTOverLeftStrategyNumber 2
#define RTOverlapStrategyNumber 3
#define RTOverRightStrategyNumber 4
#define RTRightStrategyNumber 5
#define RTSameStrategyNumber 6
#define RTContainsStrategyNumber 7
#define RTContainedByStrategyNumber 8
#define RTOverBelowStrategyNumber 9
#define RTBelowStrategyNumber 10
#define RTAboveStrategyNumber 11
#define RTOverAboveStrategyNumber 12
/* /*
* Page opaque data in a GiST index page. * Page opaque data in a GiST index page.
*/ */
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* *
* Resource managers definition * Resource managers definition
* *
* $PostgreSQL: pgsql/src/include/access/rmgr.h,v 1.14 2005/06/06 17:01:24 tgl Exp $ * $PostgreSQL: pgsql/src/include/access/rmgr.h,v 1.15 2005/11/07 17:36:46 tgl Exp $
*/ */
#ifndef RMGR_H #ifndef RMGR_H
#define RMGR_H #define RMGR_H
...@@ -23,7 +23,6 @@ typedef uint8 RmgrId; ...@@ -23,7 +23,6 @@ typedef uint8 RmgrId;
#define RM_HEAP_ID 10 #define RM_HEAP_ID 10
#define RM_BTREE_ID 11 #define RM_BTREE_ID 11
#define RM_HASH_ID 12 #define RM_HASH_ID 12
#define RM_RTREE_ID 13
#define RM_GIST_ID 14 #define RM_GIST_ID 14
#define RM_SEQ_ID 15 #define RM_SEQ_ID 15
#define RM_MAX_ID RM_SEQ_ID #define RM_MAX_ID RM_SEQ_ID
......
/*-------------------------------------------------------------------------
*
* rtree.h
* common declarations for the rtree access method code.
*
*
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/access/rtree.h,v 1.41 2005/06/24 20:53:31 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#ifndef RTREE_H
#define RTREE_H
#include "access/itup.h"
#include "access/sdir.h"
#include "access/skey.h"
#include "access/xlog.h"
#include "utils/rel.h"
/* see rtstrat.c for what all this is about */
#define RTNStrategies 12
#define RTLeftStrategyNumber 1
#define RTOverLeftStrategyNumber 2
#define RTOverlapStrategyNumber 3
#define RTOverRightStrategyNumber 4
#define RTRightStrategyNumber 5
#define RTSameStrategyNumber 6
#define RTContainsStrategyNumber 7
#define RTContainedByStrategyNumber 8
#define RTOverBelowStrategyNumber 9
#define RTBelowStrategyNumber 10
#define RTAboveStrategyNumber 11
#define RTOverAboveStrategyNumber 12
#define RTNProcs 3
#define RT_UNION_PROC 1
#define RT_INTER_PROC 2
#define RT_SIZE_PROC 3
#define F_LEAF (1 << 0)
typedef struct RTreePageOpaqueData
{
uint32 flags;
} RTreePageOpaqueData;
typedef RTreePageOpaqueData *RTreePageOpaque;
/*
* When we descend a tree, we keep a stack of parent pointers.
*/
typedef struct RTSTACK
{
struct RTSTACK *rts_parent;
OffsetNumber rts_child;
BlockNumber rts_blk;
} RTSTACK;
/*
* When we're doing a scan, we need to keep track of the parent stack
* for the marked and current items. Also, rtrees have the following
* property: if you're looking for the box (1,1,2,2), on the internal
* nodes you have to search for all boxes that *contain* (1,1,2,2),
* and not the ones that match it. We have a private scan key for
* internal nodes in the opaque structure for rtrees for this reason.
* See access/index-rtree/rtscan.c and rtstrat.c for how it gets
* initialized. We also keep pins on the scan's current buffer and
* marked buffer, if any: this avoids the need to invoke ReadBuffer()
* for each tuple produced by the index scan.
*/
typedef struct RTreeScanOpaqueData
{
struct RTSTACK *s_stack;
struct RTSTACK *s_markstk;
uint16 s_flags;
int s_internalNKey;
ScanKey s_internalKey;
Buffer curbuf;
Buffer markbuf;
} RTreeScanOpaqueData;
typedef RTreeScanOpaqueData *RTreeScanOpaque;
/*
* When we're doing a scan and updating a tree at the same time, the
* updates may affect the scan. We use the flags entry of the scan's
* opaque space to record our actual position in response to updates
* that we can't handle simply by adjusting pointers.
*/
#define RTS_CURBEFORE ((uint16) (1 << 0))
#define RTS_MRKBEFORE ((uint16) (1 << 1))
/* root page of an rtree */
#define P_ROOT 0
/*
* When we update a relation on which we're doing a scan, we need to
* check the scan and fix it if the update affected any of the pages it
* touches. Otherwise, we can miss records that we should see. The only
* times we need to do this are for deletions and splits. See the code in
* rtscan.c for how the scan is fixed. These two contants tell us what sort
* of operation changed the index.
*/
#define RTOP_DEL 0
#define RTOP_SPLIT 1
/* defined in rtree.c */
extern void freestack(RTSTACK *s);
/*
* RTree code.
* Defined in access/rtree/
*/
extern Datum rtinsert(PG_FUNCTION_ARGS);
extern Datum rtbulkdelete(PG_FUNCTION_ARGS);
extern Datum rtbeginscan(PG_FUNCTION_ARGS);
extern Datum rtgettuple(PG_FUNCTION_ARGS);
extern Datum rtgetmulti(PG_FUNCTION_ARGS);
extern Datum rtendscan(PG_FUNCTION_ARGS);
extern Datum rtmarkpos(PG_FUNCTION_ARGS);
extern Datum rtrestrpos(PG_FUNCTION_ARGS);
extern Datum rtrescan(PG_FUNCTION_ARGS);
extern Datum rtbuild(PG_FUNCTION_ARGS);
extern void _rtdump(Relation r);
extern void rtree_redo(XLogRecPtr lsn, XLogRecord *record);
extern void rtree_desc(char *buf, uint8 xl_info, char *rec);
/* rtscan.c */
extern void rtadjscans(Relation r, int op, BlockNumber blkno,
OffsetNumber offnum);
extern void ReleaseResources_rtree(void);
/* rtstrat.c */
extern StrategyNumber RTMapToInternalOperator(StrategyNumber strat);
extern bool RTMapToInternalNegate(StrategyNumber strat);
#endif /* RTREE_H */
/*-------------------------------------------------------------------------
*
* rtscan.h
* routines defined in access/rtree/rtscan.c
*
*
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/access/rtscan.h,v 1.18 2004/12/31 22:03:21 pgsql Exp $
*
*-------------------------------------------------------------------------
*/
#ifndef RTSCAN_H
#define RTSCAN_H
#include "storage/block.h"
#include "storage/off.h"
#include "utils/rel.h"
void rtadjscans(Relation r, int op, BlockNumber blkno, OffsetNumber offnum);
#endif /* RTSCAN_H */
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.305 2005/10/21 15:45:06 tgl Exp $ * $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.306 2005/11/07 17:36:46 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -53,6 +53,6 @@ ...@@ -53,6 +53,6 @@
*/ */
/* yyyymmddN */ /* yyyymmddN */
#define CATALOG_VERSION_NO 200510211 #define CATALOG_VERSION_NO 200511071
#endif #endif
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/catalog/pg_am.h,v 1.38 2005/10/15 02:49:42 momjian Exp $ * $PostgreSQL: pgsql/src/include/catalog/pg_am.h,v 1.39 2005/11/07 17:36:46 tgl Exp $
* *
* NOTES * NOTES
* the genbki.sh script reads this file and generates .bki * the genbki.sh script reads this file and generates .bki
...@@ -104,8 +104,6 @@ typedef FormData_pg_am *Form_pg_am; ...@@ -104,8 +104,6 @@ typedef FormData_pg_am *Form_pg_am;
* ---------------- * ----------------
*/ */
DATA(insert OID = 402 ( rtree 12 3 0 f f f f f rtinsert rtbeginscan rtgettuple rtgetmulti rtrescan rtendscan rtmarkpos rtrestrpos rtbuild rtbulkdelete - rtcostestimate ));
DESCR("r-tree index access method");
DATA(insert OID = 403 ( btree 5 1 1 t t t t t btinsert btbeginscan btgettuple btgetmulti btrescan btendscan btmarkpos btrestrpos btbuild btbulkdelete btvacuumcleanup btcostestimate )); DATA(insert OID = 403 ( btree 5 1 1 t t t t t btinsert btbeginscan btgettuple btgetmulti btrescan btendscan btmarkpos btrestrpos btbuild btbulkdelete btvacuumcleanup btcostestimate ));
DESCR("b-tree index access method"); DESCR("b-tree index access method");
#define BTREE_AM_OID 403 #define BTREE_AM_OID 403
......
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/catalog/pg_amop.h,v 1.66 2005/10/15 02:49:42 momjian Exp $ * $PostgreSQL: pgsql/src/include/catalog/pg_amop.h,v 1.67 2005/11/07 17:36:46 tgl Exp $
* *
* NOTES * NOTES
* the genbki.sh script reads this file and generates .bki * the genbki.sh script reads this file and generates .bki
...@@ -80,40 +80,6 @@ typedef FormData_pg_amop *Form_pg_amop; ...@@ -80,40 +80,6 @@ typedef FormData_pg_amop *Form_pg_amop;
* ---------------- * ----------------
*/ */
/*
* rtree box_ops
*/
DATA(insert ( 425 0 1 f 493 ));
DATA(insert ( 425 0 2 f 494 ));
DATA(insert ( 425 0 3 f 500 ));
DATA(insert ( 425 0 4 f 495 ));
DATA(insert ( 425 0 5 f 496 ));
DATA(insert ( 425 0 6 f 499 ));
DATA(insert ( 425 0 7 f 498 ));
DATA(insert ( 425 0 8 f 497 ));
DATA(insert ( 425 0 9 f 2571 ));
DATA(insert ( 425 0 10 f 2570 ));
DATA(insert ( 425 0 11 f 2573 ));
DATA(insert ( 425 0 12 f 2572 ));
/*
* rtree poly_ops (supports polygons)
*/
DATA(insert ( 1993 0 1 f 485 ));
DATA(insert ( 1993 0 2 f 486 ));
DATA(insert ( 1993 0 3 f 492 ));
DATA(insert ( 1993 0 4 f 487 ));
DATA(insert ( 1993 0 5 f 488 ));
DATA(insert ( 1993 0 6 f 491 ));
DATA(insert ( 1993 0 7 f 490 ));
DATA(insert ( 1993 0 8 f 489 ));
DATA(insert ( 1993 0 9 f 2575 ));
DATA(insert ( 1993 0 10 f 2574 ));
DATA(insert ( 1993 0 11 f 2577 ));
DATA(insert ( 1993 0 12 f 2576 ));
/* /*
* btree int2_ops * btree int2_ops
*/ */
......
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/catalog/pg_amproc.h,v 1.54 2005/07/01 19:19:03 tgl Exp $ * $PostgreSQL: pgsql/src/include/catalog/pg_amproc.h,v 1.55 2005/11/07 17:36:46 tgl Exp $
* *
* NOTES * NOTES
* the genbki.sh script reads this file and generates .bki * the genbki.sh script reads this file and generates .bki
...@@ -74,15 +74,6 @@ typedef FormData_pg_amproc *Form_pg_amproc; ...@@ -74,15 +74,6 @@ typedef FormData_pg_amproc *Form_pg_amproc;
* ---------------- * ----------------
*/ */
/* rtree */
DATA(insert ( 425 0 1 193 ));
DATA(insert ( 425 0 2 194 ));
DATA(insert ( 425 0 3 195 ));
DATA(insert ( 1993 0 1 197 ));
DATA(insert ( 1993 0 2 198 ));
DATA(insert ( 1993 0 3 199 ));
/* btree */ /* btree */
DATA(insert ( 397 0 1 382 )); DATA(insert ( 397 0 1 382 ));
DATA(insert ( 421 0 1 357 )); DATA(insert ( 421 0 1 357 ));
......
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/catalog/pg_opclass.h,v 1.66 2005/07/01 19:19:03 tgl Exp $ * $PostgreSQL: pgsql/src/include/catalog/pg_opclass.h,v 1.67 2005/11/07 17:36:46 tgl Exp $
* *
* NOTES * NOTES
* the genbki.sh script reads this file and generates .bki * the genbki.sh script reads this file and generates .bki
...@@ -94,7 +94,6 @@ DATA(insert OID = 397 ( 403 array_ops PGNSP PGUID 2277 t 0 )); ...@@ -94,7 +94,6 @@ DATA(insert OID = 397 ( 403 array_ops PGNSP PGUID 2277 t 0 ));
DATA(insert OID = 423 ( 403 bit_ops PGNSP PGUID 1560 t 0 )); DATA(insert OID = 423 ( 403 bit_ops PGNSP PGUID 1560 t 0 ));
DATA(insert OID = 424 ( 403 bool_ops PGNSP PGUID 16 t 0 )); DATA(insert OID = 424 ( 403 bool_ops PGNSP PGUID 16 t 0 ));
#define BOOL_BTREE_OPS_OID 424 #define BOOL_BTREE_OPS_OID 424
DATA(insert OID = 425 ( 402 box_ops PGNSP PGUID 603 t 0 ));
DATA(insert OID = 426 ( 403 bpchar_ops PGNSP PGUID 1042 t 0 )); DATA(insert OID = 426 ( 403 bpchar_ops PGNSP PGUID 1042 t 0 ));
#define BPCHAR_BTREE_OPS_OID 426 #define BPCHAR_BTREE_OPS_OID 426
DATA(insert OID = 427 ( 405 bpchar_ops PGNSP PGUID 1042 t 0 )); DATA(insert OID = 427 ( 405 bpchar_ops PGNSP PGUID 1042 t 0 ));
...@@ -135,7 +134,6 @@ DATA(insert OID = 1989 ( 403 oid_ops PGNSP PGUID 26 t 0 )); ...@@ -135,7 +134,6 @@ DATA(insert OID = 1989 ( 403 oid_ops PGNSP PGUID 26 t 0 ));
DATA(insert OID = 1990 ( 405 oid_ops PGNSP PGUID 26 t 0 )); DATA(insert OID = 1990 ( 405 oid_ops PGNSP PGUID 26 t 0 ));
DATA(insert OID = 1991 ( 403 oidvector_ops PGNSP PGUID 30 t 0 )); DATA(insert OID = 1991 ( 403 oidvector_ops PGNSP PGUID 30 t 0 ));
DATA(insert OID = 1992 ( 405 oidvector_ops PGNSP PGUID 30 t 0 )); DATA(insert OID = 1992 ( 405 oidvector_ops PGNSP PGUID 30 t 0 ));
DATA(insert OID = 1993 ( 402 poly_ops PGNSP PGUID 604 t 0 ));
DATA(insert OID = 1994 ( 403 text_ops PGNSP PGUID 25 t 0 )); DATA(insert OID = 1994 ( 403 text_ops PGNSP PGUID 25 t 0 ));
#define TEXT_BTREE_OPS_OID 1994 #define TEXT_BTREE_OPS_OID 1994
DATA(insert OID = 1995 ( 405 text_ops PGNSP PGUID 25 t 0 )); DATA(insert OID = 1995 ( 405 text_ops PGNSP PGUID 25 t 0 ));
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.387 2005/10/15 02:49:42 momjian Exp $ * $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.388 2005/11/07 17:36:46 tgl Exp $
* *
* NOTES * NOTES
* The script catalog/genbki.sh reads this file and generates .bki * The script catalog/genbki.sh reads this file and generates .bki
...@@ -394,18 +394,6 @@ DATA(insert OID = 191 ( box_right PGNSP PGUID 12 f f t f i 2 16 "603 603" _ ...@@ -394,18 +394,6 @@ DATA(insert OID = 191 ( box_right PGNSP PGUID 12 f f t f i 2 16 "603 603" _
DESCR("is right of"); DESCR("is right of");
DATA(insert OID = 192 ( box_contained PGNSP PGUID 12 f f t f i 2 16 "603 603" _null_ _null_ _null_ box_contained - _null_ )); DATA(insert OID = 192 ( box_contained PGNSP PGUID 12 f f t f i 2 16 "603 603" _null_ _null_ _null_ box_contained - _null_ ));
DESCR("contained in?"); DESCR("contained in?");
DATA(insert OID = 193 ( rt_box_union PGNSP PGUID 12 f f t f i 2 603 "603 603" _null_ _null_ _null_ rt_box_union - _null_ ));
DESCR("r-tree");
DATA(insert OID = 194 ( rt_box_inter PGNSP PGUID 12 f f t f i 2 2278 "603 603" _null_ _null_ _null_ rt_box_inter - _null_ ));
DESCR("r-tree");
DATA(insert OID = 195 ( rt_box_size PGNSP PGUID 12 f f t f i 2 2278 "603 2281" _null_ _null_ _null_ rt_box_size - _null_ ));
DESCR("r-tree");
DATA(insert OID = 197 ( rt_poly_union PGNSP PGUID 12 f f t f i 2 604 "604 604" _null_ _null_ _null_ rt_poly_union - _null_ ));
DESCR("r-tree");
DATA(insert OID = 198 ( rt_poly_inter PGNSP PGUID 12 f f t f i 2 2278 "604 604" _null_ _null_ _null_ rt_poly_inter - _null_ ));
DESCR("r-tree");
DATA(insert OID = 199 ( rt_poly_size PGNSP PGUID 12 f f t f i 2 2278 "604 2281" _null_ _null_ _null_ rt_poly_size - _null_ ));
DESCR("r-tree");
/* OIDS 200 - 299 */ /* OIDS 200 - 299 */
...@@ -668,29 +656,6 @@ DESCR("convert int4 to float4"); ...@@ -668,29 +656,6 @@ DESCR("convert int4 to float4");
DATA(insert OID = 319 ( int4 PGNSP PGUID 12 f f t f i 1 23 "700" _null_ _null_ _null_ ftoi4 - _null_ )); DATA(insert OID = 319 ( int4 PGNSP PGUID 12 f f t f i 1 23 "700" _null_ _null_ _null_ ftoi4 - _null_ ));
DESCR("convert float4 to int4"); DESCR("convert float4 to int4");
DATA(insert OID = 320 ( rtinsert PGNSP PGUID 12 f f t f v 6 16 "2281 2281 2281 2281 2281 2281" _null_ _null_ _null_ rtinsert - _null_ ));
DESCR("r-tree(internal)");
DATA(insert OID = 322 ( rtgettuple PGNSP PGUID 12 f f t f v 2 16 "2281 2281" _null_ _null_ _null_ rtgettuple - _null_ ));
DESCR("r-tree(internal)");
DATA(insert OID = 635 ( rtgetmulti PGNSP PGUID 12 f f t f v 4 16 "2281 2281 2281 2281" _null_ _null_ _null_ rtgetmulti - _null_ ));
DESCR("r-tree(internal)");
DATA(insert OID = 323 ( rtbuild PGNSP PGUID 12 f f t f v 3 2278 "2281 2281 2281" _null_ _null_ _null_ rtbuild - _null_ ));
DESCR("r-tree(internal)");
DATA(insert OID = 324 ( rtbeginscan PGNSP PGUID 12 f f t f v 3 2281 "2281 2281 2281" _null_ _null_ _null_ rtbeginscan - _null_ ));
DESCR("r-tree(internal)");
DATA(insert OID = 325 ( rtendscan PGNSP PGUID 12 f f t f v 1 2278 "2281" _null_ _null_ _null_ rtendscan - _null_ ));
DESCR("r-tree(internal)");
DATA(insert OID = 326 ( rtmarkpos PGNSP PGUID 12 f f t f v 1 2278 "2281" _null_ _null_ _null_ rtmarkpos - _null_ ));
DESCR("r-tree(internal)");
DATA(insert OID = 327 ( rtrestrpos PGNSP PGUID 12 f f t f v 1 2278 "2281" _null_ _null_ _null_ rtrestrpos - _null_ ));
DESCR("r-tree(internal)");
DATA(insert OID = 328 ( rtrescan PGNSP PGUID 12 f f t f v 2 2278 "2281 2281" _null_ _null_ _null_ rtrescan - _null_ ));
DESCR("r-tree(internal)");
DATA(insert OID = 321 ( rtbulkdelete PGNSP PGUID 12 f f t f v 3 2281 "2281 2281 2281" _null_ _null_ _null_ rtbulkdelete - _null_ ));
DESCR("r-tree(internal)");
DATA(insert OID = 1265 ( rtcostestimate PGNSP PGUID 12 f f t f v 7 2278 "2281 2281 2281 2281 2281 2281 2281" _null_ _null_ _null_ rtcostestimate - _null_ ));
DESCR("r-tree(internal)");
DATA(insert OID = 330 ( btgettuple PGNSP PGUID 12 f f t f v 2 16 "2281 2281" _null_ _null_ _null_ btgettuple - _null_ )); DATA(insert OID = 330 ( btgettuple PGNSP PGUID 12 f f t f v 2 16 "2281 2281" _null_ _null_ _null_ btgettuple - _null_ ));
DESCR("btree(internal)"); DESCR("btree(internal)");
DATA(insert OID = 636 ( btgetmulti PGNSP PGUID 12 f f t f v 4 16 "2281 2281 2281 2281" _null_ _null_ _null_ btgetmulti - _null_ )); DATA(insert OID = 636 ( btgetmulti PGNSP PGUID 12 f f t f v 4 16 "2281 2281 2281 2281" _null_ _null_ _null_ btgetmulti - _null_ ));
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/utils/geo_decls.h,v 1.48 2005/07/01 19:19:04 tgl Exp $ * $PostgreSQL: pgsql/src/include/utils/geo_decls.h,v 1.49 2005/11/07 17:36:47 tgl Exp $
* *
* NOTE * NOTE
* These routines do *not* use the float types from adt/. * These routines do *not* use the float types from adt/.
...@@ -406,14 +406,6 @@ extern Datum poly_circle(PG_FUNCTION_ARGS); ...@@ -406,14 +406,6 @@ extern Datum poly_circle(PG_FUNCTION_ARGS);
extern Datum circle_poly(PG_FUNCTION_ARGS); extern Datum circle_poly(PG_FUNCTION_ARGS);
extern Datum circle_area(PG_FUNCTION_ARGS); extern Datum circle_area(PG_FUNCTION_ARGS);
/* support routines for the rtree access method (access/rtree/rtproc.c) */
extern Datum rt_box_union(PG_FUNCTION_ARGS);
extern Datum rt_box_inter(PG_FUNCTION_ARGS);
extern Datum rt_box_size(PG_FUNCTION_ARGS);
extern Datum rt_poly_size(PG_FUNCTION_ARGS);
extern Datum rt_poly_union(PG_FUNCTION_ARGS);
extern Datum rt_poly_inter(PG_FUNCTION_ARGS);
/* support routines for the GiST access method (access/gist/gistproc.c) */ /* support routines for the GiST access method (access/gist/gistproc.c) */
extern Datum gist_box_compress(PG_FUNCTION_ARGS); extern Datum gist_box_compress(PG_FUNCTION_ARGS);
extern Datum gist_box_decompress(PG_FUNCTION_ARGS); extern Datum gist_box_decompress(PG_FUNCTION_ARGS);
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/utils/selfuncs.h,v 1.24 2005/10/15 02:49:46 momjian Exp $ * $PostgreSQL: pgsql/src/include/utils/selfuncs.h,v 1.25 2005/11/07 17:36:47 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -124,7 +124,6 @@ extern Selectivity estimate_hash_bucketsize(PlannerInfo *root, Node *hashkey, ...@@ -124,7 +124,6 @@ extern Selectivity estimate_hash_bucketsize(PlannerInfo *root, Node *hashkey,
double nbuckets); double nbuckets);
extern Datum btcostestimate(PG_FUNCTION_ARGS); extern Datum btcostestimate(PG_FUNCTION_ARGS);
extern Datum rtcostestimate(PG_FUNCTION_ARGS);
extern Datum hashcostestimate(PG_FUNCTION_ARGS); extern Datum hashcostestimate(PG_FUNCTION_ARGS);
extern Datum gistcostestimate(PG_FUNCTION_ARGS); extern Datum gistcostestimate(PG_FUNCTION_ARGS);
......
...@@ -46,55 +46,6 @@ CREATE INDEX onek2_u2_prtl ON onek2 USING btree(unique2 int4_ops) ...@@ -46,55 +46,6 @@ CREATE INDEX onek2_u2_prtl ON onek2 USING btree(unique2 int4_ops)
CREATE INDEX onek2_stu1_prtl ON onek2 USING btree(stringu1 name_ops) CREATE INDEX onek2_stu1_prtl ON onek2 USING btree(stringu1 name_ops)
where onek2.stringu1 >= 'J' and onek2.stringu1 < 'K'; where onek2.stringu1 >= 'J' and onek2.stringu1 < 'K';
-- --
-- RTREE
--
-- rtrees use a quadratic page-splitting algorithm that takes a
-- really, really long time. we don't test all rtree opclasses
-- in the regression test (we check them using the sequoia 2000
-- benchmark).
--
CREATE INDEX rect2ind ON fast_emp4000 USING rtree (home_base);
SET enable_seqscan = ON;
SET enable_indexscan = OFF;
SET enable_bitmapscan = OFF;
SELECT * FROM fast_emp4000
WHERE home_base @ '(200,200),(2000,1000)'::box
ORDER BY home_base USING <;
home_base
-----------------------
(1444,403),(1346,344)
(337,455),(240,359)
(2 rows)
SELECT count(*) FROM fast_emp4000 WHERE home_base && '(1000,1000,0,0)'::box;
count
-------
2
(1 row)
SET enable_seqscan = OFF;
SET enable_indexscan = ON;
SET enable_bitmapscan = ON;
-- there's no easy way to check that these commands actually use
-- the index, unfortunately. (EXPLAIN would work, but its output
-- changes too often for me to want to put an EXPLAIN in the test...)
SELECT * FROM fast_emp4000
WHERE home_base @ '(200,200),(2000,1000)'::box
ORDER BY home_base USING <;
home_base
-----------------------
(1444,403),(1346,344)
(337,455),(240,359)
(2 rows)
SELECT count(*) FROM fast_emp4000 WHERE home_base && '(1000,1000,0,0)'::box;
count
-------
2
(1 row)
DROP INDEX rect2ind;
--
-- GiST (rtree-equivalent opclasses only) -- GiST (rtree-equivalent opclasses only)
-- --
CREATE INDEX grect2ind ON fast_emp4000 USING gist (home_base); CREATE INDEX grect2ind ON fast_emp4000 USING gist (home_base);
......
...@@ -798,18 +798,6 @@ FROM pg_amop p1 LEFT JOIN pg_opclass p2 ON amopclaid = p2.oid ...@@ -798,18 +798,6 @@ FROM pg_amop p1 LEFT JOIN pg_opclass p2 ON amopclaid = p2.oid
ORDER BY 1, 2, 3; ORDER BY 1, 2, 3;
opcamid | amopstrategy | oprname opcamid | amopstrategy | oprname
---------+--------------+--------- ---------+--------------+---------
402 | 1 | <<
402 | 2 | &<
402 | 3 | &&
402 | 4 | &>
402 | 5 | >>
402 | 6 | ~=
402 | 7 | ~
402 | 8 | @
402 | 9 | &<|
402 | 10 | <<|
402 | 11 | |>>
402 | 12 | |&>
403 | 1 | < 403 | 1 | <
403 | 1 | ~<~ 403 | 1 | ~<~
403 | 2 | <= 403 | 2 | <=
...@@ -834,7 +822,7 @@ ORDER BY 1, 2, 3; ...@@ -834,7 +822,7 @@ ORDER BY 1, 2, 3;
783 | 10 | <<| 783 | 10 | <<|
783 | 11 | |>> 783 | 11 | |>>
783 | 12 | |&> 783 | 12 | |&>
(36 rows) (24 rows)
-- Check that all operators linked to by opclass entries have selectivity -- Check that all operators linked to by opclass entries have selectivity
-- estimators. This is not absolutely required, but it seems a reasonable -- estimators. This is not absolutely required, but it seems a reasonable
......
...@@ -67,42 +67,6 @@ CREATE INDEX onek2_u2_prtl ON onek2 USING btree(unique2 int4_ops) ...@@ -67,42 +67,6 @@ CREATE INDEX onek2_u2_prtl ON onek2 USING btree(unique2 int4_ops)
CREATE INDEX onek2_stu1_prtl ON onek2 USING btree(stringu1 name_ops) CREATE INDEX onek2_stu1_prtl ON onek2 USING btree(stringu1 name_ops)
where onek2.stringu1 >= 'J' and onek2.stringu1 < 'K'; where onek2.stringu1 >= 'J' and onek2.stringu1 < 'K';
--
-- RTREE
--
-- rtrees use a quadratic page-splitting algorithm that takes a
-- really, really long time. we don't test all rtree opclasses
-- in the regression test (we check them using the sequoia 2000
-- benchmark).
--
CREATE INDEX rect2ind ON fast_emp4000 USING rtree (home_base);
SET enable_seqscan = ON;
SET enable_indexscan = OFF;
SET enable_bitmapscan = OFF;
SELECT * FROM fast_emp4000
WHERE home_base @ '(200,200),(2000,1000)'::box
ORDER BY home_base USING <;
SELECT count(*) FROM fast_emp4000 WHERE home_base && '(1000,1000,0,0)'::box;
SET enable_seqscan = OFF;
SET enable_indexscan = ON;
SET enable_bitmapscan = ON;
-- there's no easy way to check that these commands actually use
-- the index, unfortunately. (EXPLAIN would work, but its output
-- changes too often for me to want to put an EXPLAIN in the test...)
SELECT * FROM fast_emp4000
WHERE home_base @ '(200,200),(2000,1000)'::box
ORDER BY home_base USING <;
SELECT count(*) FROM fast_emp4000 WHERE home_base && '(1000,1000,0,0)'::box;
DROP INDEX rect2ind;
-- --
-- GiST (rtree-equivalent opclasses only) -- GiST (rtree-equivalent opclasses only)
-- --
......
...@@ -212,9 +212,6 @@ index types<br /> ...@@ -212,9 +212,6 @@ index types<br />
<a id="access_nbtree" name="access_nbtree"></a> <a <a id="access_nbtree" name="access_nbtree"></a> <a
href="../../backend/access/nbtree">access/nbtree</a> - Lehman and href="../../backend/access/nbtree">access/nbtree</a> - Lehman and
Yao's btree management algorithm<br /> Yao's btree management algorithm<br />
<a id="access_rtree" name="access_rtree"></a> <a
href="../../backend/access/rtree">access/rtree</a> - used for
indexing of 2-dimensional data<br />
<a id="access_transam" name="access_transam"></a> <a <a id="access_transam" name="access_transam"></a> <a
href="../../backend/access/transam">access/transam</a> - href="../../backend/access/transam">access/transam</a> -
transaction manager (BEGIN/ABORT/COMMIT)<br /> transaction manager (BEGIN/ABORT/COMMIT)<br />
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment