]> granicus.if.org Git - postgresql/commitdiff
R-tree is dead ... long live GiST.
authorTom Lane <tgl@sss.pgh.pa.us>
Mon, 7 Nov 2005 17:36:47 +0000 (17:36 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Mon, 7 Nov 2005 17:36:47 +0000 (17:36 +0000)
46 files changed:
contrib/cube/cube.c
contrib/intarray/_int.h
contrib/ltree/_ltree_gist.c
contrib/ltree/ltree_gist.c
contrib/pg_trgm/trgm_gist.c
contrib/seg/seg.c
contrib/tsearch2/gistidx.c
contrib/tsearch2/query.c
contrib/tsearch2/rewrite.c
doc/src/sgml/backup.sgml
doc/src/sgml/geqo.sgml
doc/src/sgml/gist.sgml
doc/src/sgml/indices.sgml
doc/src/sgml/mvcc.sgml
doc/src/sgml/ref/create_index.sgml
doc/src/sgml/xindex.sgml
src/backend/access/Makefile
src/backend/access/gist/gistproc.c
src/backend/access/rtree/Makefile [deleted file]
src/backend/access/rtree/rtget.c [deleted file]
src/backend/access/rtree/rtproc.c [deleted file]
src/backend/access/rtree/rtree.c [deleted file]
src/backend/access/rtree/rtscan.c [deleted file]
src/backend/access/rtree/rtstrat.c [deleted file]
src/backend/access/transam/rmgr.c
src/backend/commands/indexcmds.c
src/backend/utils/adt/geo_selfuncs.c
src/backend/utils/adt/selfuncs.c
src/backend/utils/resowner/resowner.c
src/bin/psql/tab-complete.c
src/include/access/gist.h
src/include/access/rmgr.h
src/include/access/rtree.h [deleted file]
src/include/access/rtscan.h [deleted file]
src/include/catalog/catversion.h
src/include/catalog/pg_am.h
src/include/catalog/pg_amop.h
src/include/catalog/pg_amproc.h
src/include/catalog/pg_opclass.h
src/include/catalog/pg_proc.h
src/include/utils/geo_decls.h
src/include/utils/selfuncs.h
src/test/regress/expected/create_index.out
src/test/regress/expected/opr_sanity.out
src/test/regress/sql/create_index.sql
src/tools/backend/backend_dirs.html

index fca03f02d706028f279f5c2e202c2a7f73c5485c..0bc88ef6f1433268910897785721bf7b7c63987f 100644 (file)
@@ -10,7 +10,7 @@
 #include <math.h>
 
 #include "access/gist.h"
-#include "access/rtree.h"
+#include "access/skey.h"
 #include "lib/stringinfo.h"
 #include "utils/builtins.h"
 
index 2231bdb095bd8c06e796cac342e638ebb4591906..96f2b116a9f6b3cca80d0b2f5a36203283b848c3 100644 (file)
@@ -4,7 +4,7 @@
 
 #include "access/gist.h"
 #include "access/itup.h"
-#include "access/rtree.h"
+#include "access/skey.h"
 #include "catalog/pg_type.h"
 #include "utils/array.h"
 #include "utils/builtins.h"
index f68e9902b52c0d485cd48a0a2e1e8eac90624ef0..0344b6dc13493fcffc73bf269bfc7b68c96b172b 100644 (file)
@@ -5,8 +5,7 @@
 
 #include "ltree.h"
 #include "access/gist.h"
-#include "access/rtree.h"
-#include "access/nbtree.h"
+#include "access/skey.h"
 #include "utils/array.h"
 
 #include "crc32.h"
index 7e7ede02853d771915a9babd66c03484cfa81ca7..2be6449329c71bf0068c7998cb8c400b009bcbe2 100644 (file)
@@ -5,8 +5,8 @@
 
 #include "ltree.h"
 #include "access/gist.h"
-#include "access/rtree.h"
 #include "access/nbtree.h"
+#include "access/skey.h"
 #include "utils/array.h"
 #include "crc32.h"
 
index 33ed6d5e1f0e1c4aec4b5307e8063c8836497c09..9f1c20cf047034ca74ea2a4c0324a0726ac4b5ee 100644 (file)
@@ -2,13 +2,10 @@
 
 #include "access/gist.h"
 #include "access/itup.h"
-#include "access/rtree.h"
-#include "utils/elog.h"
-#include "utils/palloc.h"
+#include "access/tuptoaster.h"
+#include "storage/bufpage.h"
 #include "utils/array.h"
 #include "utils/builtins.h"
-#include "storage/bufpage.h"
-#include "access/tuptoaster.h"
 
 PG_FUNCTION_INFO_V1(gtrgm_in);
 Datum          gtrgm_in(PG_FUNCTION_ARGS);
index 52f65b062c8d85683a0ac499136798622b8e29ac..0a694a52ddfaf81da19dc94ba2ef44c00c14b4dd 100644 (file)
@@ -9,7 +9,7 @@
 #include <float.h>
 
 #include "access/gist.h"
-#include "access/rtree.h"
+#include "access/skey.h"
 #include "utils/builtins.h"
 
 #include "segdata.h"
@@ -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_contains_int(SEG * a, int *b);
index c0d15de691390341b19c371c5f2606c2201bf1d6..a01d06d65e73037a608e733e6461aba731ff067e 100644 (file)
@@ -4,11 +4,10 @@
 
 #include "access/gist.h"
 #include "access/itup.h"
-#include "access/rtree.h"
+#include "access/tuptoaster.h"
+#include "storage/bufpage.h"
 #include "utils/array.h"
 #include "utils/builtins.h"
-#include "storage/bufpage.h"
-#include "access/tuptoaster.h"
 
 #include "tsvector.h"
 #include "query.h"
index 013f0031965e40014e77c4a900a90435559096db..a260d459355ff13be63ff42f23e62d063c149c61 100644 (file)
 
 #include "access/gist.h"
 #include "access/itup.h"
-#include "access/rtree.h"
+#include "storage/bufpage.h"
 #include "utils/array.h"
 #include "utils/builtins.h"
-#include "storage/bufpage.h"
 
 #include "ts_cfg.h"
 #include "tsvector.h"
index e7b5045c9e912ddbfc460d3acd696a9d73b680d1..2e9b39f18db0e2e063e14a9c387a953afcea1ea0 100644 (file)
@@ -9,7 +9,6 @@
 
 #include "access/gist.h"
 #include "access/itup.h"
-#include "access/rtree.h"
 #include "storage/bufpage.h"
 #include "utils/array.h"
 #include "utils/builtins.h"
index 1cbe26f77abe99a0c653d14449099efbcc50db48..2341105a353c79dd8179402b038babaa5be71429 100644 (file)
@@ -1,5 +1,5 @@
 <!--
-$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">
  <title>Backup and Restore</title>
@@ -1129,8 +1129,8 @@ restore_command = 'copy /mnt/server/archivedir/%f "%p"'  # Windows
   <itemizedlist>
    <listitem>
     <para>
-     Operations on hash and R-tree indexes are
-     not presently WAL-logged, so replay will not update these index types.
+     Operations on hash indexes are
+     not presently WAL-logged, so replay will not update these indexes.
      The recommended workaround is to manually <command>REINDEX</> each
      such index after completing a recovery operation.
     </para>
index 9de43beeb7c0083c5a71991fc60f3f653255491f..35bb36f22af6ee85a32189686340b6c8ecd45a41 100644 (file)
@@ -1,5 +1,5 @@
 <!--
-$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
 -->
 
@@ -51,8 +51,8 @@ Genetic Optimizer
     caused by the support of a variety of <firstterm>join
     methods</firstterm> (e.g., nested loop, hash join, merge join in
     <productname>PostgreSQL</productname>) to process individual joins
-    and a diversity of <firstterm>indexes</firstterm> (e.g., R-tree,
-    B-tree, hash in <productname>PostgreSQL</productname>) as access
+    and a diversity of <firstterm>indexes</firstterm> (e.g.,
+    B-tree, hash, GiST in <productname>PostgreSQL</productname>) as access
     paths for relations.
    </para>
 
index ed4c689a728c3e5149eb0b5c8a0f0d382a9943d8..56e72f69beab938c0494f6307f6523112995dbfb 100644 (file)
@@ -1,25 +1,22 @@
 <!--
-$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">
 <title>GiST Indexes</title>
 
-<sect1 id="gist-intro">
- <title>Introduction</title>
-
- <para>
    <indexterm>
     <primary>index</primary>
     <secondary>GiST</secondary>
    </indexterm>
-   <indexterm>
-    <primary>GiST</primary>
-    <see>index</see>
-   </indexterm>
+
+<sect1 id="gist-intro">
+ <title>Introduction</title>
+
+ <para>
    <acronym>GiST</acronym> stands for Generalized Search Tree.  It is a
    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>.
  </para>
 
@@ -60,17 +57,17 @@ $PostgreSQL: pgsql/doc/src/sgml/gist.sgml,v 1.24 2005/11/04 23:14:00 petere Exp
  <para>
    This extensibility should not be confused with the extensibility of the
    other standard search trees in terms of the data they can handle.  For
-   example, <productname>PostgreSQL</productname> supports extensible B+-trees
-   and R-trees. That means that you can use
-   <productname>PostgreSQL</productname> to build a B+-tree or R-tree over any
-   data type you want. But B+-trees only support range predicates
+   example, <productname>PostgreSQL</productname> supports extensible B-trees
+   and hash indexes. That means that you can use
+   <productname>PostgreSQL</productname> to build a B-tree or hash over any
+   data type you want. But B-trees only support range predicates
    (<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>
    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
    than imagey</quote> and <quote>is imagex greater than imagey</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
    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
    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,
    <acronym>GiST</acronym> combines extensibility along with generality, code
    reuse, and a clean interface.
index d3bc74da92adc9edbe12b98451cfda9f5ea4bd6b..5fa1e79fefb0c5798f3a4599b7f282d5ae7acb20 100644 (file)
@@ -1,4 +1,4 @@
-<!-- $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">
  <title id="indexes-title">Indexes</title>
@@ -104,7 +104,7 @@ CREATE INDEX test1_id_index ON test1 (id);
 
   <para>
    <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.
    By default, the <command>CREATE INDEX</command> command will create a
    B-tree index, which fits the most common situations.
@@ -152,43 +152,6 @@ CREATE INDEX test1_id_index ON test1 (id);
    See <xref linkend="indexes-opclass"> below.
   </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>
    <indexterm>
     <primary>index</primary>
@@ -208,18 +171,6 @@ CREATE INDEX <replaceable>name</replaceable> ON <replaceable>table</replaceable>
 </synopsis>
   </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>
    <para>
     Testing has shown <productname>PostgreSQL</productname>'s hash
@@ -230,21 +181,47 @@ CREATE INDEX <replaceable>name</replaceable> ON <replaceable>table</replaceable>
     after a database crash.
     For these reasons, hash index use is presently discouraged.
    </para>
+  </note>  
 
-   <para>
-    Similarly, R-tree indexes do not seem to have any performance
-    advantages compared to the equivalent operations of GiST indexes.
-    Like hash indexes, they are not WAL-logged and may need
-    reindexing after a database crash.
-   </para>
+  <para>
+   <indexterm>
+    <primary>index</primary>
+    <secondary>GiST</secondary>
+   </indexterm>
+   <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>
-    While the problems with hash indexes may be fixed eventually,
-    it is likely that the R-tree index type will be retired in a future
-    release.  Users are encouraged to migrate applications that use R-tree
-    indexes to GiST indexes.
-   </para>
-  </note>  
+   <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.)
+   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>
 
 
index ea01104d937f4cb887523fa671cc844b2d30a462..9e2adc4e46f920aaaecd42cb693a2808cd2bc31e 100644 (file)
@@ -1,5 +1,5 @@
 <!--
-$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">
@@ -991,18 +991,6 @@ UPDATE accounts SET balance = balance - 100.00 WHERE acctnum = 22222;
        </para>
       </listitem>
      </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>
    </para>
 
@@ -1012,8 +1000,7 @@ UPDATE accounts SET balance = balance - 100.00 WHERE acctnum = 22222;
     indexes, they are the recommended index type for concurrent
     applications that need to index scalar data. When dealing with
     non-scalar data, B-trees are not useful, and GiST indexes should
-    be used instead.  R-tree indexes are deprecated and are likely
-    to disappear entirely in a future release.
+    be used instead.
    </para>
   </sect1>
  </chapter>
index 745a0a465e97ec6707fe5b4bbc63e132ca68d291..676fa8b4e6e605a483621fb5e282777d557e3112 100644 (file)
@@ -1,5 +1,5 @@
 <!--
-$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
 -->
 
@@ -34,7 +34,7 @@ CREATE [ UNIQUE ] INDEX <replaceable class="parameter">name</replaceable> ON <re
    <command>CREATE INDEX</command> constructs an index <replaceable
    class="parameter">index_name</replaceable> on the specified table.
    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>
@@ -55,11 +55,7 @@ CREATE [ UNIQUE ] INDEX <replaceable class="parameter">name</replaceable> ON <re
 
   <para>
    <productname>PostgreSQL</productname> provides the index methods
-   B-tree, R-tree, hash, and GiST. The B-tree index method is an
-   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
+   B-tree, hash, and GiST.  Users can also define their own index
    methods, but that is fairly complicated.
   </para>
 
@@ -137,9 +133,9 @@ CREATE [ UNIQUE ] INDEX <replaceable class="parameter">name</replaceable> ON <re
       <term><replaceable class="parameter">method</replaceable></term>
       <listitem>
        <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>rtree</literal>, and <literal>gist</literal>.  The
+        and <literal>gist</literal>.  The
         default method is <literal>btree</literal>.
        </para>
       </listitem>
@@ -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
    using an <literal>IS NULL</> predicate.
   </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>
@@ -270,13 +275,13 @@ CREATE INDEX code_idx ON films(code) TABLESPACE indexspace;
 Is this example correct?
 </comment>
   <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
    conversion function:
   </para>
   <programlisting>
 CREATE INDEX pointloc
-    ON points USING RTREE (point2box(location) box_ops);
+    ON points USING GIST (point2box(location) box_ops);
 SELECT * FROM points
     WHERE point2box(points.pointloc) = boxes.box;
   </programlisting>
index 6afcf7522055a8d729384864b3bc08db691db091..c63b1a148df8dd03cb793c6e36d119ede24bfb26 100644 (file)
@@ -1,5 +1,5 @@
 <!--
-$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">
@@ -170,8 +170,12 @@ $PostgreSQL: pgsql/doc/src/sgml/xindex.sgml,v 1.41 2005/07/19 01:27:59 neilc Exp
    </table>
 
   <para>
-   R-tree indexes express relationships in two-dimensional space.
-   They use twelve strategies, shown in
+   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.  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
    two-dimensional tests (overlaps, same, contains, contained by);
    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
   </para>
 
    <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">
      <thead>
       <row>
@@ -240,13 +244,6 @@ $PostgreSQL: pgsql/doc/src/sgml/xindex.sgml,v 1.41 2005/07/19 01:27:59 neilc Exp
     </tgroup>
    </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>
    Note that all strategy operators return Boolean values.  In
    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
    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
    is greater than, equal to, or less than the other.  Similarly, the
-   R-tree index method must be able to compute
-   intersections,  unions, and sizes of rectangles.  These
-   operations do not correspond to operators used in qualifications in
+   hash index method must be able to compute hash codes for key values.
+   These operations do not correspond to operators used in qualifications in
    SQL commands;  they are administrative routines used by
    the index methods, internally.
   </para>
@@ -339,37 +335,6 @@ $PostgreSQL: pgsql/doc/src/sgml/xindex.sgml,v 1.41 2005/07/19 01:27:59 neilc Exp
     </tgroup>
    </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>
    GiST indexes require seven support functions,
    shown in <xref linkend="xindex-gist-support-table">.
@@ -746,7 +711,7 @@ SELECT * FROM table WHERE integer_column &lt; 4;
 </programlisting>
    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
-   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</>
    condition that tests overlap between nonrectangular objects such as
    polygons.  Yet we could use the index to find objects whose bounding
index 769ed8eecb1061708af47e399b8916c7e8cfe713..82cd7a90ed5d802bf4e44df92bf1730f2a8cc60c 100644 (file)
@@ -1,14 +1,14 @@
 #
 # 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
 top_builddir = ../../..
 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)
 
 all: SUBSYS.o
index b9e0469b05b866d15c7d3e9267297add91396912..25531259124c5b7379179e564377e0753845adc1 100644 (file)
@@ -10,7 +10,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * 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 @@
 
 #include "access/gist.h"
 #include "access/itup.h"
-#include "access/rtree.h"
+#include "access/skey.h"
 #include "utils/geo_decls.h"
 
 
@@ -40,6 +40,47 @@ static bool rtree_internal_consistent(BOX *key, BOX *query,
  * 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
  *
@@ -493,8 +534,6 @@ size_box(Datum dbox)
  *
  * We can use the same function since all types use bounding boxes as the
  * internal-page representation.
- *
- * This implements the same logic as the rtree internal-page strategy map.
  */
 static bool
 rtree_internal_consistent(BOX *key, BOX *query, StrategyNumber strategy)
diff --git a/src/backend/access/rtree/Makefile b/src/backend/access/rtree/Makefile
deleted file mode 100644 (file)
index d53626c..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-#-------------------------------------------------------------------------
-#
-# 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
-
diff --git a/src/backend/access/rtree/rtget.c b/src/backend/access/rtree/rtget.c
deleted file mode 100644 (file)
index 010a493..0000000
+++ /dev/null
@@ -1,281 +0,0 @@
-/*-------------------------------------------------------------------------
- *
- * 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 */
-}
diff --git a/src/backend/access/rtree/rtproc.c b/src/backend/access/rtree/rtproc.c
deleted file mode 100644 (file)
index 292dac6..0000000
+++ /dev/null
@@ -1,175 +0,0 @@
-/*-------------------------------------------------------------------------
- *
- * 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();
-}
diff --git a/src/backend/access/rtree/rtree.c b/src/backend/access/rtree/rtree.c
deleted file mode 100644 (file)
index d684101..0000000
+++ /dev/null
@@ -1,1298 +0,0 @@
-/*-------------------------------------------------------------------------
- *
- * rtree.c
- *       interface routines for the postgres rtree indexed access method.
- *
- * 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/rtree.c,v 1.92 2005/10/15 02:49:09 momjian Exp $
- *
- *-------------------------------------------------------------------------
- */
-
-#include "postgres.h"
-
-#include "access/genam.h"
-#include "access/heapam.h"
-#include "access/rtree.h"
-#include "access/xlogutils.h"
-#include "catalog/index.h"
-#include "commands/vacuum.h"
-#include "executor/executor.h"
-#include "miscadmin.h"
-
-
-/*
- * XXX We assume that all datatypes indexable in rtrees are pass-by-reference.
- * To fix this, you'd need to improve the IndexTupleGetDatum() macro, and
- * do something with the various datum-pfreeing code.  However, it's not that
- * unreasonable an assumption in practice.
- */
-#define IndexTupleGetDatum(itup)  \
-       PointerGetDatum(((char *) (itup)) + sizeof(IndexTupleData))
-
-/*
- * Space-allocation macros.  Note we count the item's line pointer in its size.
- */
-#define RTPageAvailSpace  \
-       (BLCKSZ - (sizeof(PageHeaderData) - sizeof(ItemIdData)) \
-        - MAXALIGN(sizeof(RTreePageOpaqueData)))
-#define IndexTupleTotalSize(itup)  \
-       (MAXALIGN(IndexTupleSize(itup)) + sizeof(ItemIdData))
-#define IndexTupleAttSize(itup)  \
-       (IndexTupleSize(itup) - sizeof(IndexTupleData))
-
-/* results of rtpicksplit() */
-typedef struct SPLITVEC
-{
-       OffsetNumber *spl_left;
-       int                     spl_nleft;
-       Datum           spl_ldatum;
-       OffsetNumber *spl_right;
-       int                     spl_nright;
-       Datum           spl_rdatum;
-} SPLITVEC;
-
-/* for sorting tuples by cost, for picking split */
-typedef struct SPLITCOST
-{
-       OffsetNumber offset_number;
-       float           cost_differential;
-       bool            choose_left;
-} SPLITCOST;
-
-typedef struct RTSTATE
-{
-       FmgrInfo        unionFn;                /* union function */
-       FmgrInfo        sizeFn;                 /* size function */
-       FmgrInfo        interFn;                /* intersection function */
-} RTSTATE;
-
-/* Working state for rtbuild and its callback */
-typedef struct
-{
-       RTSTATE         rtState;
-       double          indtuples;
-} RTBuildState;
-
-/* non-export function prototypes */
-static void rtbuildCallback(Relation index,
-                               HeapTuple htup,
-                               Datum *values,
-                               bool *isnull,
-                               bool tupleIsAlive,
-                               void *state);
-static void rtdoinsert(Relation r, IndexTuple itup, RTSTATE *rtstate);
-static void rttighten(Relation r, RTSTACK *stk, Datum datum, int att_size,
-                 RTSTATE *rtstate);
-static void rtdosplit(Relation r, Buffer buffer, RTSTACK *stack,
-                 IndexTuple itup, RTSTATE *rtstate);
-static void rtintinsert(Relation r, RTSTACK *stk, IndexTuple ltup,
-                       IndexTuple rtup, RTSTATE *rtstate);
-static void rtnewroot(Relation r, IndexTuple lt, IndexTuple rt);
-static void rtpicksplit(Relation r, Page page, SPLITVEC *v, IndexTuple itup,
-                       RTSTATE *rtstate);
-static void RTInitBuffer(Buffer b, uint32 f);
-static OffsetNumber choose(Relation r, Page p, IndexTuple it,
-          RTSTATE *rtstate);
-static int     nospace(Page p, IndexTuple it);
-static void initRtstate(RTSTATE *rtstate, Relation index);
-static int     qsort_comp_splitcost(const void *a, const void *b);
-
-
-/*
- * routine to build an index.  Basically calls insert over and over
- */
-Datum
-rtbuild(PG_FUNCTION_ARGS)
-{
-       Relation        heap = (Relation) PG_GETARG_POINTER(0);
-       Relation        index = (Relation) PG_GETARG_POINTER(1);
-       IndexInfo  *indexInfo = (IndexInfo *) PG_GETARG_POINTER(2);
-       double          reltuples;
-       RTBuildState buildstate;
-       Buffer          buffer;
-
-       /* no locking is needed */
-
-       initRtstate(&buildstate.rtState, index);
-
-       /*
-        * We expect to be called exactly once for any index relation. If that's
-        * not the case, big trouble's what we have.
-        */
-       if (RelationGetNumberOfBlocks(index) != 0)
-               elog(ERROR, "index \"%s\" already contains data",
-                        RelationGetRelationName(index));
-
-       /* initialize the root page */
-       buffer = ReadBuffer(index, P_NEW);
-       RTInitBuffer(buffer, F_LEAF);
-       WriteBuffer(buffer);
-
-       /* build the index */
-       buildstate.indtuples = 0;
-
-       /* do the heap scan */
-       reltuples = IndexBuildHeapScan(heap, index, indexInfo,
-                                                                  rtbuildCallback, (void *) &buildstate);
-
-       /* okay, all heap tuples are indexed */
-
-       /* since we just counted the # of tuples, may as well update stats */
-       IndexCloseAndUpdateStats(heap, reltuples, index, buildstate.indtuples);
-
-       PG_RETURN_VOID();
-}
-
-/*
- * Per-tuple callback from IndexBuildHeapScan
- */
-static void
-rtbuildCallback(Relation index,
-                               HeapTuple htup,
-                               Datum *values,
-                               bool *isnull,
-                               bool tupleIsAlive,
-                               void *state)
-{
-       RTBuildState *buildstate = (RTBuildState *) state;
-       IndexTuple      itup;
-
-       /* form an index tuple and point it at the heap tuple */
-       itup = index_form_tuple(RelationGetDescr(index), values, isnull);
-       itup->t_tid = htup->t_self;
-
-       /* rtree indexes don't index nulls, see notes in rtinsert */
-       if (IndexTupleHasNulls(itup))
-       {
-               pfree(itup);
-               return;
-       }
-
-       /*
-        * Since we already have the index relation locked, we call rtdoinsert
-        * directly.  Normal access method calls dispatch through rtinsert, which
-        * locks the relation for write.  This is the right thing to do if you're
-        * inserting single tups, but not when you're initializing the whole index
-        * at once.
-        */
-       rtdoinsert(index, itup, &buildstate->rtState);
-
-       buildstate->indtuples += 1;
-
-       pfree(itup);
-}
-
-/*
- *     rtinsert -- wrapper for rtree tuple insertion.
- *
- *       This is the public interface routine for tuple insertion in rtrees.
- *       It doesn't do any work; just locks the relation and passes the buck.
- */
-Datum
-rtinsert(PG_FUNCTION_ARGS)
-{
-       Relation        r = (Relation) PG_GETARG_POINTER(0);
-       Datum      *values = (Datum *) PG_GETARG_POINTER(1);
-       bool       *isnull = (bool *) PG_GETARG_POINTER(2);
-       ItemPointer ht_ctid = (ItemPointer) PG_GETARG_POINTER(3);
-
-#ifdef NOT_USED
-       Relation        heapRel = (Relation) PG_GETARG_POINTER(4);
-       bool            checkUnique = PG_GETARG_BOOL(5);
-#endif
-       IndexTuple      itup;
-       RTSTATE         rtState;
-
-       /* generate an index tuple */
-       itup = index_form_tuple(RelationGetDescr(r), values, isnull);
-       itup->t_tid = *ht_ctid;
-
-       /*
-        * Currently, rtrees do not support indexing NULLs; considerable
-        * infrastructure work would have to be done to do anything reasonable
-        * with a NULL.
-        */
-       if (IndexTupleHasNulls(itup))
-       {
-               pfree(itup);
-               PG_RETURN_BOOL(false);
-       }
-
-       initRtstate(&rtState, r);
-
-       /*
-        * Since rtree is not marked "amconcurrent" in pg_am, caller should have
-        * acquired exclusive lock on index relation.  We need no locking here.
-        */
-       rtdoinsert(r, itup, &rtState);
-
-       PG_RETURN_BOOL(true);
-}
-
-static void
-rtdoinsert(Relation r, IndexTuple itup, RTSTATE *rtstate)
-{
-       Page            page;
-       Buffer          buffer;
-       BlockNumber blk;
-       IndexTuple      which;
-       OffsetNumber l;
-       RTSTACK    *stack;
-       RTreePageOpaque opaque;
-       Datum           datum;
-
-       blk = P_ROOT;
-       buffer = InvalidBuffer;
-       stack = NULL;
-
-       do
-       {
-               /* release the current buffer, read in the next one */
-               buffer = ReleaseAndReadBuffer(buffer, r, blk);
-               page = (Page) BufferGetPage(buffer);
-
-               opaque = (RTreePageOpaque) PageGetSpecialPointer(page);
-               if (!(opaque->flags & F_LEAF))
-               {
-                       RTSTACK    *n;
-                       ItemId          iid;
-
-                       n = (RTSTACK *) palloc(sizeof(RTSTACK));
-                       n->rts_parent = stack;
-                       n->rts_blk = blk;
-                       n->rts_child = choose(r, page, itup, rtstate);
-                       stack = n;
-
-                       iid = PageGetItemId(page, n->rts_child);
-                       which = (IndexTuple) PageGetItem(page, iid);
-                       blk = ItemPointerGetBlockNumber(&(which->t_tid));
-               }
-       } while (!(opaque->flags & F_LEAF));
-
-       if (nospace(page, itup))
-       {
-               /* need to do a split */
-               rtdosplit(r, buffer, stack, itup, rtstate);
-               freestack(stack);
-               WriteBuffer(buffer);    /* don't forget to release buffer! */
-               return;
-       }
-
-       /* add the item and write the buffer */
-       if (PageIsEmpty(page))
-       {
-               l = PageAddItem(page, (Item) itup, IndexTupleSize(itup),
-                                               FirstOffsetNumber,
-                                               LP_USED);
-       }
-       else
-       {
-               l = PageAddItem(page, (Item) itup, IndexTupleSize(itup),
-                                               OffsetNumberNext(PageGetMaxOffsetNumber(page)),
-                                               LP_USED);
-       }
-       if (l == InvalidOffsetNumber)
-               elog(ERROR, "failed to add index item to \"%s\"",
-                        RelationGetRelationName(r));
-
-       WriteBuffer(buffer);
-
-       datum = IndexTupleGetDatum(itup);
-
-       /* now expand the page boundary in the parent to include the new child */
-       rttighten(r, stack, datum, IndexTupleAttSize(itup), rtstate);
-       freestack(stack);
-}
-
-static void
-rttighten(Relation r,
-                 RTSTACK *stk,
-                 Datum datum,
-                 int att_size,
-                 RTSTATE *rtstate)
-{
-       Datum           oldud;
-       Datum           tdatum;
-       Page            p;
-       float           old_size,
-                               newd_size;
-       Buffer          b;
-
-       if (stk == NULL)
-               return;
-
-       b = ReadBuffer(r, stk->rts_blk);
-       p = BufferGetPage(b);
-
-       oldud = IndexTupleGetDatum(PageGetItem(p,
-                                                                                  PageGetItemId(p, stk->rts_child)));
-
-       FunctionCall2(&rtstate->sizeFn, oldud,
-                                 PointerGetDatum(&old_size));
-
-       datum = FunctionCall2(&rtstate->unionFn, oldud, datum);
-
-       FunctionCall2(&rtstate->sizeFn, datum,
-                                 PointerGetDatum(&newd_size));
-
-       /*
-        * If newd_size == 0 we have degenerate rectangles, so we don't know if
-        * there was any change, so we have to assume there was.
-        */
-       if ((newd_size == 0) || (newd_size != old_size))
-       {
-               TupleDesc       td = RelationGetDescr(r);
-
-               if (td->attrs[0]->attlen < 0)
-               {
-                       /*
-                        * This is an internal page, so 'oldud' had better be a union
-                        * (constant-length) key, too.  (See comment below.)
-                        */
-                       Assert(VARSIZE(DatumGetPointer(datum)) ==
-                                  VARSIZE(DatumGetPointer(oldud)));
-                       memmove(DatumGetPointer(oldud), DatumGetPointer(datum),
-                                       VARSIZE(DatumGetPointer(datum)));
-               }
-               else
-               {
-                       memmove(DatumGetPointer(oldud), DatumGetPointer(datum),
-                                       att_size);
-               }
-               WriteBuffer(b);
-
-               /*
-                * The user may be defining an index on variable-sized data (like
-                * polygons).  If so, we need to get a constant-sized datum for
-                * insertion on the internal page.      We do this by calling the union
-                * proc, which is required to return a rectangle.
-                */
-               tdatum = FunctionCall2(&rtstate->unionFn, datum, datum);
-
-               rttighten(r, stk->rts_parent, tdatum, att_size, rtstate);
-               pfree(DatumGetPointer(tdatum));
-       }
-       else
-               ReleaseBuffer(b);
-       pfree(DatumGetPointer(datum));
-}
-
-/*
- *     rtdosplit -- split a page in the tree.
- *
- *       rtpicksplit does the interesting work of choosing the split.
- *       This routine just does the bit-pushing.
- */
-static void
-rtdosplit(Relation r,
-                 Buffer buffer,
-                 RTSTACK *stack,
-                 IndexTuple itup,
-                 RTSTATE *rtstate)
-{
-       Page            p;
-       Buffer          leftbuf,
-                               rightbuf;
-       Page            left,
-                               right;
-       ItemId          itemid;
-       IndexTuple      item;
-       IndexTuple      ltup,
-                               rtup;
-       OffsetNumber maxoff;
-       OffsetNumber i;
-       OffsetNumber leftoff,
-                               rightoff;
-       BlockNumber lbknum,
-                               rbknum;
-       BlockNumber bufblock;
-       RTreePageOpaque opaque;
-       bool       *isnull;
-       SPLITVEC        v;
-       OffsetNumber *spl_left,
-                          *spl_right;
-       TupleDesc       tupDesc;
-       int                     n;
-       OffsetNumber newitemoff;
-
-       p = (Page) BufferGetPage(buffer);
-       opaque = (RTreePageOpaque) PageGetSpecialPointer(p);
-
-       rtpicksplit(r, p, &v, itup, rtstate);
-
-       /*
-        * The root of the tree is the first block in the relation.  If we're
-        * about to split the root, we need to do some hocus-pocus to enforce this
-        * guarantee.
-        */
-
-       if (BufferGetBlockNumber(buffer) == P_ROOT)
-       {
-               leftbuf = ReadBuffer(r, P_NEW);
-               RTInitBuffer(leftbuf, opaque->flags);
-               lbknum = BufferGetBlockNumber(leftbuf);
-               left = (Page) BufferGetPage(leftbuf);
-       }
-       else
-       {
-               leftbuf = buffer;
-               IncrBufferRefCount(buffer);
-               lbknum = BufferGetBlockNumber(buffer);
-               left = (Page) PageGetTempPage(p, sizeof(RTreePageOpaqueData));
-       }
-
-       rightbuf = ReadBuffer(r, P_NEW);
-       RTInitBuffer(rightbuf, opaque->flags);
-       rbknum = BufferGetBlockNumber(rightbuf);
-       right = (Page) BufferGetPage(rightbuf);
-
-       spl_left = v.spl_left;
-       spl_right = v.spl_right;
-       leftoff = rightoff = FirstOffsetNumber;
-       maxoff = PageGetMaxOffsetNumber(p);
-       newitemoff = OffsetNumberNext(maxoff);
-
-       /*
-        * spl_left contains a list of the offset numbers of the tuples that will
-        * go to the left page.  For each offset number, get the tuple item, then
-        * add the item to the left page.  Similarly for the right side.
-        */
-
-       /* fill left node */
-       for (n = 0; n < v.spl_nleft; n++)
-       {
-               i = *spl_left;
-               if (i == newitemoff)
-                       item = itup;
-               else
-               {
-                       itemid = PageGetItemId(p, i);
-                       item = (IndexTuple) PageGetItem(p, itemid);
-               }
-
-               if (PageAddItem(left, (Item) item, IndexTupleSize(item),
-                                               leftoff, LP_USED) == InvalidOffsetNumber)
-                       elog(ERROR, "failed to add index item to \"%s\"",
-                                RelationGetRelationName(r));
-               leftoff = OffsetNumberNext(leftoff);
-
-               spl_left++;                             /* advance in left split vector */
-       }
-
-       /* fill right node */
-       for (n = 0; n < v.spl_nright; n++)
-       {
-               i = *spl_right;
-               if (i == newitemoff)
-                       item = itup;
-               else
-               {
-                       itemid = PageGetItemId(p, i);
-                       item = (IndexTuple) PageGetItem(p, itemid);
-               }
-
-               if (PageAddItem(right, (Item) item, IndexTupleSize(item),
-                                               rightoff, LP_USED) == InvalidOffsetNumber)
-                       elog(ERROR, "failed to add index item to \"%s\"",
-                                RelationGetRelationName(r));
-               rightoff = OffsetNumberNext(rightoff);
-
-               spl_right++;                    /* advance in right split vector */
-       }
-
-       /* Make sure we consumed all of the split vectors, and release 'em */
-       Assert(*spl_left == InvalidOffsetNumber);
-       Assert(*spl_right == InvalidOffsetNumber);
-       pfree(v.spl_left);
-       pfree(v.spl_right);
-
-       if ((bufblock = BufferGetBlockNumber(buffer)) != P_ROOT)
-               PageRestoreTempPage(left, p);
-       WriteBuffer(leftbuf);
-       WriteBuffer(rightbuf);
-
-       /*
-        * Okay, the page is split.  We have three things left to do:
-        *
-        * 1)  Adjust any active scans on this index to cope with changes we
-        * introduced in its structure by splitting this page.
-        *
-        * 2)  "Tighten" the bounding box of the pointer to the left page in the
-        * parent node in the tree, if any.  Since we moved a bunch of stuff off
-        * the left page, we expect it to get smaller.  This happens in the
-        * internal insertion routine.
-        *
-        * 3)  Insert a pointer to the right page in the parent.  This may cause the
-        * parent to split.  If it does, we need to repeat steps one and two for
-        * each split node in the tree.
-        */
-
-       /* adjust active scans */
-       rtadjscans(r, RTOP_SPLIT, bufblock, FirstOffsetNumber);
-
-       tupDesc = r->rd_att;
-       isnull = (bool *) palloc(r->rd_rel->relnatts * sizeof(bool));
-       memset(isnull, false, r->rd_rel->relnatts * sizeof(bool));
-
-       ltup = index_form_tuple(tupDesc, &(v.spl_ldatum), isnull);
-       rtup = index_form_tuple(tupDesc, &(v.spl_rdatum), isnull);
-
-       pfree(isnull);
-       pfree(DatumGetPointer(v.spl_ldatum));
-       pfree(DatumGetPointer(v.spl_rdatum));
-
-       /* set pointers to new child pages in the internal index tuples */
-       ItemPointerSet(&(ltup->t_tid), lbknum, 1);
-       ItemPointerSet(&(rtup->t_tid), rbknum, 1);
-
-       rtintinsert(r, stack, ltup, rtup, rtstate);
-
-       pfree(ltup);
-       pfree(rtup);
-}
-
-static void
-rtintinsert(Relation r,
-                       RTSTACK *stk,
-                       IndexTuple ltup,
-                       IndexTuple rtup,
-                       RTSTATE *rtstate)
-{
-       IndexTuple      old;
-       Buffer          b;
-       Page            p;
-       Datum           ldatum,
-                               rdatum,
-                               newdatum;
-
-       if (stk == NULL)
-       {
-               rtnewroot(r, ltup, rtup);
-               return;
-       }
-
-       b = ReadBuffer(r, stk->rts_blk);
-       p = BufferGetPage(b);
-       old = (IndexTuple) PageGetItem(p, PageGetItemId(p, stk->rts_child));
-
-       /*
-        * This is a hack.      Right now, we force rtree internal keys to be constant
-        * size. To fix this, need delete the old key and add both left and right
-        * for the two new pages.  The insertion of left may force a split if the
-        * new left key is bigger than the old key.
-        */
-
-       if (IndexTupleSize(old) != IndexTupleSize(ltup))
-               ereport(ERROR,
-                               (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
-                                errmsg("variable-length rtree keys are not supported")));
-
-       /* install pointer to left child */
-       memmove(old, ltup, IndexTupleSize(ltup));
-
-       if (nospace(p, rtup))
-       {
-               newdatum = IndexTupleGetDatum(ltup);
-               rttighten(r, stk->rts_parent, newdatum,
-                                 IndexTupleAttSize(ltup), rtstate);
-               rtdosplit(r, b, stk->rts_parent, rtup, rtstate);
-               WriteBuffer(b);                 /* don't forget to release buffer!  - 01/31/94 */
-       }
-       else
-       {
-               if (PageAddItem(p, (Item) rtup, IndexTupleSize(rtup),
-                                               PageGetMaxOffsetNumber(p),
-                                               LP_USED) == InvalidOffsetNumber)
-                       elog(ERROR, "failed to add index item to \"%s\"",
-                                RelationGetRelationName(r));
-               WriteBuffer(b);
-               ldatum = IndexTupleGetDatum(ltup);
-               rdatum = IndexTupleGetDatum(rtup);
-               newdatum = FunctionCall2(&rtstate->unionFn, ldatum, rdatum);
-
-               rttighten(r, stk->rts_parent, newdatum,
-                                 IndexTupleAttSize(rtup), rtstate);
-
-               pfree(DatumGetPointer(newdatum));
-       }
-}
-
-static void
-rtnewroot(Relation r, IndexTuple lt, IndexTuple rt)
-{
-       Buffer          b;
-       Page            p;
-
-       b = ReadBuffer(r, P_ROOT);
-       RTInitBuffer(b, 0);
-       p = BufferGetPage(b);
-       if (PageAddItem(p, (Item) lt, IndexTupleSize(lt),
-                                       FirstOffsetNumber,
-                                       LP_USED) == InvalidOffsetNumber)
-               elog(ERROR, "failed to add index item to \"%s\"",
-                        RelationGetRelationName(r));
-       if (PageAddItem(p, (Item) rt, IndexTupleSize(rt),
-                                       OffsetNumberNext(FirstOffsetNumber),
-                                       LP_USED) == InvalidOffsetNumber)
-               elog(ERROR, "failed to add index item to \"%s\"",
-                        RelationGetRelationName(r));
-       WriteBuffer(b);
-}
-
-/*
- * Choose how to split an rtree page into two pages.
- *
- * We return two vectors of index item numbers, one for the items to be
- * put on the left page, one for the items to be put on the right page.
- * In addition, the item to be added (itup) is listed in the appropriate
- * vector.     It is represented by item number N+1 (N = # of items on page).
- *
- * Both vectors have a terminating sentinel value of InvalidOffsetNumber,
- * but the sentinal value is no longer used, because the SPLITVEC
- * vector also contains the length of each vector, and that information
- * is now used to iterate over them in rtdosplit(). --kbb, 21 Sept 2001
- *
- * The bounding-box datums for the two new pages are also returned in *v.
- *
- * This is the quadratic-cost split algorithm Guttman describes in
- * his paper.  The reason we chose it is that you can implement this
- * with less information about the data types on which you're operating.
- *
- * We must also deal with a consideration not found in Guttman's algorithm:
- * variable-length data.  In particular, the incoming item might be
- * large enough that not just any split will work.     In the worst case,
- * our "split" may have to be the new item on one page and all the existing
- * items on the other. Short of that, we have to take care that we do not
- * make a split that leaves both pages too full for the new item.
- */
-static void
-rtpicksplit(Relation r,
-                       Page page,
-                       SPLITVEC *v,
-                       IndexTuple itup,
-                       RTSTATE *rtstate)
-{
-       OffsetNumber maxoff,
-                               newitemoff;
-       OffsetNumber i,
-                               j;
-       IndexTuple      item_1,
-                               item_2;
-       Datum           datum_alpha,
-                               datum_beta;
-       Datum           datum_l,
-                               datum_r;
-       Datum           union_d,
-                               union_dl,
-                               union_dr;
-       Datum           inter_d;
-       bool            firsttime;
-       float           size_alpha,
-                               size_beta,
-                               size_union,
-                               size_inter;
-       float           size_waste,
-                               waste;
-       float           size_l,
-                               size_r;
-       int                     nbytes;
-       OffsetNumber seed_1 = 0,
-                               seed_2 = 0;
-       OffsetNumber *left,
-                          *right;
-       Size            newitemsz,
-                               item_1_sz,
-                               item_2_sz,
-                               left_avail_space,
-                               right_avail_space;
-       int                     total_num_tuples,
-                               num_tuples_without_seeds,
-                               max_after_split;        /* in Guttman's lingo, (M - m) */
-       float           diff;                   /* diff between cost of putting tuple left or
-                                                                * right */
-       SPLITCOST  *cost_vector;
-       int                     n;
-
-       /*
-        * First, make sure the new item is not so large that we can't possibly
-        * fit it on a page, even by itself.  (It's sufficient to make this test
-        * here, since any oversize tuple must lead to a page split attempt.)
-        */
-       newitemsz = IndexTupleTotalSize(itup);
-       if (newitemsz > RTPageAvailSpace)
-               ereport(ERROR,
-                               (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
-                                errmsg("index row size %lu exceeds rtree maximum, %lu",
-                                               (unsigned long) newitemsz,
-                                               (unsigned long) RTPageAvailSpace),
-                       errhint("Values larger than a buffer page cannot be indexed.")));
-
-       maxoff = PageGetMaxOffsetNumber(page);
-       newitemoff = OffsetNumberNext(maxoff);          /* phony index for new item */
-       total_num_tuples = newitemoff;
-       num_tuples_without_seeds = total_num_tuples - 2;
-       max_after_split = total_num_tuples / 2;         /* works for m = M/2 */
-
-       /* Make arrays big enough for worst case, including sentinel */
-       nbytes = (maxoff + 2) * sizeof(OffsetNumber);
-       v->spl_left = (OffsetNumber *) palloc(nbytes);
-       v->spl_right = (OffsetNumber *) palloc(nbytes);
-
-       firsttime = true;
-       waste = 0.0;
-
-       for (i = FirstOffsetNumber; i < maxoff; i = OffsetNumberNext(i))
-       {
-               item_1 = (IndexTuple) PageGetItem(page, PageGetItemId(page, i));
-               datum_alpha = IndexTupleGetDatum(item_1);
-               item_1_sz = IndexTupleTotalSize(item_1);
-
-               for (j = OffsetNumberNext(i); j <= maxoff; j = OffsetNumberNext(j))
-               {
-                       item_2 = (IndexTuple) PageGetItem(page, PageGetItemId(page, j));
-                       datum_beta = IndexTupleGetDatum(item_2);
-                       item_2_sz = IndexTupleTotalSize(item_2);
-
-                       /*
-                        * Ignore seed pairs that don't leave room for the new item on
-                        * either split page.
-                        */
-                       if (newitemsz + item_1_sz > RTPageAvailSpace &&
-                               newitemsz + item_2_sz > RTPageAvailSpace)
-                               continue;
-
-                       /* compute the wasted space by unioning these guys */
-                       union_d = FunctionCall2(&rtstate->unionFn,
-                                                                       datum_alpha, datum_beta);
-                       FunctionCall2(&rtstate->sizeFn, union_d,
-                                                 PointerGetDatum(&size_union));
-                       inter_d = FunctionCall2(&rtstate->interFn,
-                                                                       datum_alpha, datum_beta);
-
-                       /*
-                        * The interFn may return a NULL pointer (not an SQL null!) to
-                        * indicate no intersection.  sizeFn must cope with this.
-                        */
-                       FunctionCall2(&rtstate->sizeFn, inter_d,
-                                                 PointerGetDatum(&size_inter));
-                       size_waste = size_union - size_inter;
-
-                       if (DatumGetPointer(union_d) != NULL)
-                               pfree(DatumGetPointer(union_d));
-                       if (DatumGetPointer(inter_d) != NULL)
-                               pfree(DatumGetPointer(inter_d));
-
-                       /*
-                        * are these a more promising split that what we've already seen?
-                        */
-                       if (size_waste > waste || firsttime)
-                       {
-                               waste = size_waste;
-                               seed_1 = i;
-                               seed_2 = j;
-                               firsttime = false;
-                       }
-               }
-       }
-
-       if (firsttime)
-       {
-               /*
-                * There is no possible split except to put the new item on its own
-                * page.  Since we still have to compute the union rectangles, we play
-                * dumb and run through the split algorithm anyway, setting seed_1 =
-                * first item on page and seed_2 = new item.
-                */
-               seed_1 = FirstOffsetNumber;
-               seed_2 = newitemoff;
-       }
-
-       item_1 = (IndexTuple) PageGetItem(page, PageGetItemId(page, seed_1));
-       datum_alpha = IndexTupleGetDatum(item_1);
-       datum_l = FunctionCall2(&rtstate->unionFn, datum_alpha, datum_alpha);
-       FunctionCall2(&rtstate->sizeFn, datum_l, PointerGetDatum(&size_l));
-       left_avail_space = RTPageAvailSpace - IndexTupleTotalSize(item_1);
-
-       if (seed_2 == newitemoff)
-       {
-               item_2 = itup;
-               /* Needn't leave room for new item in calculations below */
-               newitemsz = 0;
-       }
-       else
-               item_2 = (IndexTuple) PageGetItem(page, PageGetItemId(page, seed_2));
-       datum_beta = IndexTupleGetDatum(item_2);
-       datum_r = FunctionCall2(&rtstate->unionFn, datum_beta, datum_beta);
-       FunctionCall2(&rtstate->sizeFn, datum_r, PointerGetDatum(&size_r));
-       right_avail_space = RTPageAvailSpace - IndexTupleTotalSize(item_2);
-
-       /*
-        * Now split up the regions between the two seeds.
-        *
-        * The cost_vector array will contain hints for determining where each tuple
-        * should go.  Each record in the array will contain a boolean,
-        * choose_left, that indicates which node the tuple prefers to be on, and
-        * the absolute difference in cost between putting the tuple in its
-        * favored node and in the other node.
-        *
-        * Later, we will sort the cost_vector in descending order by cost
-        * difference, and consider the tuples in that order for placement. That
-        * way, the tuples that *really* want to be in one node or the other get
-        * to choose first, and the tuples that don't really care choose last.
-        *
-        * First, build the cost_vector array.  The new index tuple will also be
-        * handled in this loop, and represented in the array, with i==newitemoff.
-        *
-        * In the case of variable size tuples it is possible that we only have the
-        * two seeds and no other tuples, in which case we don't do any of this
-        * cost_vector stuff.
-        */
-
-       /* to keep compiler quiet */
-       cost_vector = NULL;
-
-       if (num_tuples_without_seeds > 0)
-       {
-               cost_vector =
-                       (SPLITCOST *) palloc(num_tuples_without_seeds * sizeof(SPLITCOST));
-               n = 0;
-               for (i = FirstOffsetNumber; i <= newitemoff; i = OffsetNumberNext(i))
-               {
-                       /* Compute new union datums and sizes for both choices */
-
-                       if ((i == seed_1) || (i == seed_2))
-                               continue;
-                       else if (i == newitemoff)
-                               item_1 = itup;
-                       else
-                               item_1 = (IndexTuple) PageGetItem(page, PageGetItemId(page, i));
-
-                       datum_alpha = IndexTupleGetDatum(item_1);
-                       union_dl = FunctionCall2(&rtstate->unionFn, datum_l, datum_alpha);
-                       union_dr = FunctionCall2(&rtstate->unionFn, datum_r, datum_alpha);
-                       FunctionCall2(&rtstate->sizeFn, union_dl,
-                                                 PointerGetDatum(&size_alpha));
-                       FunctionCall2(&rtstate->sizeFn, union_dr,
-                                                 PointerGetDatum(&size_beta));
-                       pfree(DatumGetPointer(union_dl));
-                       pfree(DatumGetPointer(union_dr));
-
-                       diff = (size_alpha - size_l) - (size_beta - size_r);
-
-                       cost_vector[n].offset_number = i;
-                       cost_vector[n].cost_differential = fabs(diff);
-                       cost_vector[n].choose_left = (diff < 0);
-
-                       n++;
-               }
-
-               /*
-                * Sort the array.      The function qsort_comp_splitcost is set up
-                * "backwards", to provided descending order.
-                */
-               qsort(cost_vector, num_tuples_without_seeds, sizeof(SPLITCOST),
-                         &qsort_comp_splitcost);
-       }
-
-       /*
-        * Now make the final decisions about where each tuple will go, and build
-        * the vectors to return in the SPLITVEC record.
-        *
-        * The cost_vector array contains (descriptions of) all the tuples, in the
-        * order that we want to consider them, so we we just iterate through it
-        * and place each tuple in left or right nodes, according to the criteria
-        * described below.
-        */
-
-       left = v->spl_left;
-       v->spl_nleft = 0;
-       right = v->spl_right;
-       v->spl_nright = 0;
-
-       /*
-        * Place the seeds first. left avail space, left union, right avail space,
-        * and right union have already been adjusted for the seeds.
-        */
-
-       *left++ = seed_1;
-       v->spl_nleft++;
-
-       *right++ = seed_2;
-       v->spl_nright++;
-
-       for (n = 0; n < num_tuples_without_seeds; n++)
-       {
-               bool            left_feasible,
-                                       right_feasible,
-                                       choose_left;
-
-               /*
-                * We need to figure out which page needs the least enlargement in
-                * order to store the item.
-                */
-
-               i = cost_vector[n].offset_number;
-
-               /* Compute new union datums and sizes for both possible additions */
-               if (i == newitemoff)
-               {
-                       item_1 = itup;
-                       /* Needn't leave room for new item anymore */
-                       newitemsz = 0;
-               }
-               else
-                       item_1 = (IndexTuple) PageGetItem(page, PageGetItemId(page, i));
-               item_1_sz = IndexTupleTotalSize(item_1);
-
-               datum_alpha = IndexTupleGetDatum(item_1);
-               union_dl = FunctionCall2(&rtstate->unionFn, datum_l, datum_alpha);
-               union_dr = FunctionCall2(&rtstate->unionFn, datum_r, datum_alpha);
-               FunctionCall2(&rtstate->sizeFn, union_dl,
-                                         PointerGetDatum(&size_alpha));
-               FunctionCall2(&rtstate->sizeFn, union_dr,
-                                         PointerGetDatum(&size_beta));
-
-               /*
-                * We prefer the page that shows smaller enlargement of its union area
-                * (Guttman's algorithm), but we must take care that at least one page
-                * will still have room for the new item after this one is added.
-                *
-                * (We know that all the old items together can fit on one page, so we
-                * need not worry about any other problem than failing to fit the new
-                * item.)
-                *
-                * Guttman's algorithm actually has two factors to consider (in order):
-                * 1. if one node has so many tuples already assigned to it that the
-                * other needs all the rest in order to satisfy the condition that
-                * neither node has fewer than m tuples, then that is decisive; 2.
-                * otherwise, choose the page that shows the smaller enlargement of
-                * its union area.
-                *
-                * I have chosen m = M/2, where M is the maximum number of tuples on a
-                * page.  (Actually, this is only strictly true for fixed size tuples.
-                * For variable size tuples, there still might have to be only one
-                * tuple on a page, if it is really big.  But even with variable size
-                * tuples we still try to get m as close as possible to M/2.)
-                *
-                * The question of which page shows the smaller enlargement of its union
-                * area has already been answered, and the answer stored in the
-                * choose_left field of the SPLITCOST record.
-                */
-               left_feasible = (left_avail_space >= item_1_sz &&
-                                                ((left_avail_space - item_1_sz) >= newitemsz ||
-                                                 right_avail_space >= newitemsz));
-               right_feasible = (right_avail_space >= item_1_sz &&
-                                                 ((right_avail_space - item_1_sz) >= newitemsz ||
-                                                  left_avail_space >= newitemsz));
-               if (left_feasible && right_feasible)
-               {
-                       /*
-                        * Both feasible, use Guttman's algorithm. First check the m
-                        * condition described above, and if that doesn't apply, choose
-                        * the page with the smaller enlargement of its union area.
-                        */
-                       if (v->spl_nleft > max_after_split)
-                               choose_left = false;
-                       else if (v->spl_nright > max_after_split)
-                               choose_left = true;
-                       else
-                               choose_left = cost_vector[n].choose_left;
-               }
-               else if (left_feasible)
-                       choose_left = true;
-               else if (right_feasible)
-                       choose_left = false;
-               else
-               {
-                       elog(ERROR, "failed to find a workable rtree page split");
-                       choose_left = false;    /* keep compiler quiet */
-               }
-
-               if (choose_left)
-               {
-                       pfree(DatumGetPointer(datum_l));
-                       pfree(DatumGetPointer(union_dr));
-                       datum_l = union_dl;
-                       size_l = size_alpha;
-                       left_avail_space -= item_1_sz;
-                       *left++ = i;
-                       v->spl_nleft++;
-               }
-               else
-               {
-                       pfree(DatumGetPointer(datum_r));
-                       pfree(DatumGetPointer(union_dl));
-                       datum_r = union_dr;
-                       size_r = size_beta;
-                       right_avail_space -= item_1_sz;
-                       *right++ = i;
-                       v->spl_nright++;
-               }
-       }
-
-       if (num_tuples_without_seeds > 0)
-               pfree(cost_vector);
-
-       *left = *right = InvalidOffsetNumber;           /* add ending sentinels */
-
-       v->spl_ldatum = datum_l;
-       v->spl_rdatum = datum_r;
-}
-
-static void
-RTInitBuffer(Buffer b, uint32 f)
-{
-       RTreePageOpaque opaque;
-       Page            page;
-       Size            pageSize;
-
-       pageSize = BufferGetPageSize(b);
-
-       page = BufferGetPage(b);
-
-       PageInit(page, pageSize, sizeof(RTreePageOpaqueData));
-
-       opaque = (RTreePageOpaque) PageGetSpecialPointer(page);
-       opaque->flags = f;
-}
-
-static OffsetNumber
-choose(Relation r, Page p, IndexTuple it, RTSTATE *rtstate)
-{
-       OffsetNumber maxoff;
-       OffsetNumber i;
-       Datum           ud,
-                               id;
-       Datum           datum;
-       float           usize,
-                               dsize;
-       OffsetNumber which;
-       float           which_grow;
-
-       id = IndexTupleGetDatum(it);
-       maxoff = PageGetMaxOffsetNumber(p);
-       which_grow = -1.0;
-       which = -1;
-
-       for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i))
-       {
-               datum = IndexTupleGetDatum(PageGetItem(p, PageGetItemId(p, i)));
-               FunctionCall2(&rtstate->sizeFn, datum,
-                                         PointerGetDatum(&dsize));
-               ud = FunctionCall2(&rtstate->unionFn, datum, id);
-               FunctionCall2(&rtstate->sizeFn, ud,
-                                         PointerGetDatum(&usize));
-               pfree(DatumGetPointer(ud));
-               if (which_grow < 0 || usize - dsize < which_grow)
-               {
-                       which = i;
-                       which_grow = usize - dsize;
-                       if (which_grow == 0)
-                               break;
-               }
-       }
-
-       return which;
-}
-
-static int
-nospace(Page p, IndexTuple it)
-{
-       return PageGetFreeSpace(p) < IndexTupleSize(it);
-}
-
-void
-freestack(RTSTACK *s)
-{
-       RTSTACK    *p;
-
-       while (s != NULL)
-       {
-               p = s->rts_parent;
-               pfree(s);
-               s = p;
-       }
-}
-
-/*
- * Bulk deletion of all index entries pointing to a set of heap tuples.
- * The set of target tuples is specified via a callback routine that tells
- * whether any given heap tuple (identified by ItemPointer) is being deleted.
- *
- * Result: a palloc'd struct containing statistical info for VACUUM displays.
- */
-Datum
-rtbulkdelete(PG_FUNCTION_ARGS)
-{
-       Relation        rel = (Relation) PG_GETARG_POINTER(0);
-       IndexBulkDeleteCallback callback = (IndexBulkDeleteCallback) PG_GETARG_POINTER(1);
-       void       *callback_state = (void *) PG_GETARG_POINTER(2);
-       IndexBulkDeleteResult *result;
-       BlockNumber num_pages;
-       double          tuples_removed;
-       double          num_index_tuples;
-       IndexScanDesc iscan;
-
-       tuples_removed = 0;
-       num_index_tuples = 0;
-
-       /*
-        * Since rtree is not marked "amconcurrent" in pg_am, caller should have
-        * acquired exclusive lock on index relation.  We need no locking here.
-        */
-
-       /*
-        * XXX generic implementation --- should be improved!
-        */
-
-       /* walk through the entire index */
-       iscan = index_beginscan(NULL, rel, SnapshotAny, 0, NULL);
-       /* including killed tuples */
-       iscan->ignore_killed_tuples = false;
-
-       while (index_getnext_indexitem(iscan, ForwardScanDirection))
-       {
-               vacuum_delay_point();
-
-               if (callback(&iscan->xs_ctup.t_self, callback_state))
-               {
-                       ItemPointerData indextup = iscan->currentItemData;
-                       BlockNumber blkno;
-                       OffsetNumber offnum;
-                       Buffer          buf;
-                       Page            page;
-
-                       blkno = ItemPointerGetBlockNumber(&indextup);
-                       offnum = ItemPointerGetOffsetNumber(&indextup);
-
-                       /* adjust any scans that will be affected by this deletion */
-                       /* (namely, my own scan) */
-                       rtadjscans(rel, RTOP_DEL, blkno, offnum);
-
-                       /* delete the index tuple */
-                       buf = ReadBuffer(rel, blkno);
-                       page = BufferGetPage(buf);
-
-                       PageIndexTupleDelete(page, offnum);
-
-                       WriteBuffer(buf);
-
-                       tuples_removed += 1;
-               }
-               else
-                       num_index_tuples += 1;
-       }
-
-       index_endscan(iscan);
-
-       /* return statistics */
-       num_pages = RelationGetNumberOfBlocks(rel);
-
-       result = (IndexBulkDeleteResult *) palloc0(sizeof(IndexBulkDeleteResult));
-       result->num_pages = num_pages;
-       result->num_index_tuples = num_index_tuples;
-       result->tuples_removed = tuples_removed;
-
-       PG_RETURN_POINTER(result);
-}
-
-
-static void
-initRtstate(RTSTATE *rtstate, Relation index)
-{
-       fmgr_info_copy(&rtstate->unionFn,
-                                  index_getprocinfo(index, 1, RT_UNION_PROC),
-                                  CurrentMemoryContext);
-       fmgr_info_copy(&rtstate->sizeFn,
-                                  index_getprocinfo(index, 1, RT_SIZE_PROC),
-                                  CurrentMemoryContext);
-       fmgr_info_copy(&rtstate->interFn,
-                                  index_getprocinfo(index, 1, RT_INTER_PROC),
-                                  CurrentMemoryContext);
-}
-
-/* for sorting SPLITCOST records in descending order */
-static int
-qsort_comp_splitcost(const void *a, const void *b)
-{
-       float           diff =
-       ((SPLITCOST *) a)->cost_differential -
-       ((SPLITCOST *) b)->cost_differential;
-
-       if (diff < 0)
-               return 1;
-       else if (diff > 0)
-               return -1;
-       else
-               return 0;
-}
-
-#ifdef RTDEBUG
-
-void
-_rtdump(Relation r)
-{
-       Buffer          buf;
-       Page            page;
-       OffsetNumber offnum,
-                               maxoff;
-       BlockNumber blkno;
-       BlockNumber nblocks;
-       RTreePageOpaque po;
-       IndexTuple      itup;
-       BlockNumber itblkno;
-       OffsetNumber itoffno;
-       Datum           datum;
-       char       *itkey;
-
-       nblocks = RelationGetNumberOfBlocks(r);
-       for (blkno = 0; blkno < nblocks; blkno++)
-       {
-               buf = ReadBuffer(r, blkno);
-               page = BufferGetPage(buf);
-               po = (RTreePageOpaque) PageGetSpecialPointer(page);
-               maxoff = PageGetMaxOffsetNumber(page);
-               printf("Page %d maxoff %d <%s>\n", blkno, maxoff,
-                          (po->flags & F_LEAF ? "LEAF" : "INTERNAL"));
-
-               if (PageIsEmpty(page))
-               {
-                       ReleaseBuffer(buf);
-                       continue;
-               }
-
-               for (offnum = FirstOffsetNumber;
-                        offnum <= maxoff;
-                        offnum = OffsetNumberNext(offnum))
-               {
-                       itup = (IndexTuple) PageGetItem(page, PageGetItemId(page, offnum));
-                       itblkno = ItemPointerGetBlockNumber(&(itup->t_tid));
-                       itoffno = ItemPointerGetOffsetNumber(&(itup->t_tid));
-                       datum = IndexTupleGetDatum(itup);
-                       itkey = DatumGetCString(DirectFunctionCall1(box_out,
-                                                                                                               datum));
-                       printf("\t[%d] size %d heap <%d,%d> key:%s\n",
-                                  offnum, IndexTupleSize(itup), itblkno, itoffno, itkey);
-                       pfree(itkey);
-               }
-
-               ReleaseBuffer(buf);
-       }
-}
-#endif   /* defined RTDEBUG */
-
-void
-rtree_redo(XLogRecPtr lsn, XLogRecord *record)
-{
-       elog(PANIC, "rtree_redo: unimplemented");
-}
-
-void
-rtree_desc(char *buf, uint8 xl_info, char *rec)
-{
-}
diff --git a/src/backend/access/rtree/rtscan.c b/src/backend/access/rtree/rtscan.c
deleted file mode 100644 (file)
index 577c6a6..0000000
+++ /dev/null
@@ -1,493 +0,0 @@
-/*-------------------------------------------------------------------------
- *
- * rtscan.c
- *       routines to manage scans on index relations
- *
- * 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/rtscan.c,v 1.60 2005/10/15 02:49:09 momjian Exp $
- *
- *-------------------------------------------------------------------------
- */
-
-#include "postgres.h"
-
-#include "access/genam.h"
-#include "access/rtree.h"
-#include "utils/lsyscache.h"
-#include "utils/resowner.h"
-
-
-/* routines defined and used here */
-static void rtregscan(IndexScanDesc s);
-static void rtdropscan(IndexScanDesc s);
-static void rtadjone(IndexScanDesc s, int op, BlockNumber blkno,
-                OffsetNumber offnum);
-static void adjuststack(RTSTACK *stk, BlockNumber blkno);
-static void adjustiptr(IndexScanDesc s, ItemPointer iptr,
-                  int op, BlockNumber blkno, OffsetNumber offnum);
-
-/*
- *     Whenever we start an rtree scan in a backend, we register it in private
- *     space.  Then if the rtree index gets updated, we check all registered
- *     scans and adjust them if the tuple they point at got moved by the
- *     update.  We only need to do this in private space, because when we update
- *     an rtree we have a write lock on the tree, so no other process can have
- *     any locks at all on it.  A single transaction can have write and read
- *     locks on the same object, so that's why we need to handle this case.
- */
-
-typedef struct RTScanListData
-{
-       IndexScanDesc rtsl_scan;
-       ResourceOwner rtsl_owner;
-       struct RTScanListData *rtsl_next;
-} RTScanListData;
-
-typedef RTScanListData *RTScanList;
-
-/* pointer to list of local scans on rtrees */
-static RTScanList RTScans = NULL;
-
-Datum
-rtbeginscan(PG_FUNCTION_ARGS)
-{
-       Relation        r = (Relation) PG_GETARG_POINTER(0);
-       int                     nkeys = PG_GETARG_INT32(1);
-       ScanKey         key = (ScanKey) PG_GETARG_POINTER(2);
-       IndexScanDesc s;
-
-       s = RelationGetIndexScan(r, nkeys, key);
-
-       rtregscan(s);
-
-       PG_RETURN_POINTER(s);
-}
-
-Datum
-rtrescan(PG_FUNCTION_ARGS)
-{
-       IndexScanDesc s = (IndexScanDesc) PG_GETARG_POINTER(0);
-       ScanKey         key = (ScanKey) PG_GETARG_POINTER(1);
-       RTreeScanOpaque p;
-       int                     i;
-
-       /*
-        * Clear all the pointers.
-        */
-       ItemPointerSetInvalid(&s->currentItemData);
-       ItemPointerSetInvalid(&s->currentMarkData);
-
-       p = (RTreeScanOpaque) s->opaque;
-       if (p != NULL)
-       {
-               /* rescan an existing indexscan --- reset state */
-               freestack(p->s_stack);
-               freestack(p->s_markstk);
-               p->s_stack = p->s_markstk = NULL;
-               p->s_flags = 0x0;
-               /* drop pins on buffers -- no locks held */
-               if (BufferIsValid(p->curbuf))
-               {
-                       ReleaseBuffer(p->curbuf);
-                       p->curbuf = InvalidBuffer;
-               }
-               if (BufferIsValid(p->markbuf))
-               {
-                       ReleaseBuffer(p->markbuf);
-                       p->markbuf = InvalidBuffer;
-               }
-       }
-       else
-       {
-               /* initialize opaque data */
-               p = (RTreeScanOpaque) palloc(sizeof(RTreeScanOpaqueData));
-               p->s_stack = p->s_markstk = NULL;
-               p->curbuf = p->markbuf = InvalidBuffer;
-               p->s_internalNKey = s->numberOfKeys;
-               p->s_flags = 0x0;
-               s->opaque = p;
-               if (s->numberOfKeys > 0)
-                       p->s_internalKey = (ScanKey) palloc(sizeof(ScanKeyData) * s->numberOfKeys);
-       }
-
-       /* Update scan key, if a new one is given */
-       if (key && s->numberOfKeys > 0)
-       {
-               memmove(s->keyData,
-                               key,
-                               s->numberOfKeys * sizeof(ScanKeyData));
-
-               /*
-                * Scans on internal pages use different operators than they do on
-                * leaf pages.  For example, if the user wants all boxes that exactly
-                * match (x1,y1,x2,y2), then on internal pages we need to find all
-                * boxes that contain (x1,y1,x2,y2).  rtstrat.c knows how to pick the
-                * opclass member to use for internal pages. In some cases we need to
-                * negate the result of the opclass member.
-                */
-               for (i = 0; i < s->numberOfKeys; i++)
-               {
-                       AttrNumber      attno = s->keyData[i].sk_attno;
-                       Oid                     opclass;
-                       Oid                     subtype;
-                       StrategyNumber orig_strategy;
-                       StrategyNumber int_strategy;
-                       Oid                     int_oper;
-                       RegProcedure int_proc;
-                       int                     int_flags;
-
-                       opclass = s->indexRelation->rd_indclass->values[attno - 1];
-                       subtype = s->keyData[i].sk_subtype;
-                       orig_strategy = s->keyData[i].sk_strategy;
-                       int_strategy = RTMapToInternalOperator(orig_strategy);
-                       int_oper = get_opclass_member(opclass, subtype, int_strategy);
-                       Assert(OidIsValid(int_oper));
-                       int_proc = get_opcode(int_oper);
-                       int_flags = s->keyData[i].sk_flags;
-                       if (RTMapToInternalNegate(orig_strategy))
-                               int_flags |= SK_NEGATE;
-                       ScanKeyEntryInitialize(&(p->s_internalKey[i]),
-                                                                  int_flags,
-                                                                  attno,
-                                                                  int_strategy,
-                                                                  subtype,
-                                                                  int_proc,
-                                                                  s->keyData[i].sk_argument);
-               }
-       }
-
-       PG_RETURN_VOID();
-}
-
-Datum
-rtmarkpos(PG_FUNCTION_ARGS)
-{
-       IndexScanDesc s = (IndexScanDesc) PG_GETARG_POINTER(0);
-       RTreeScanOpaque p;
-       RTSTACK    *o,
-                          *n,
-                          *tmp;
-
-       s->currentMarkData = s->currentItemData;
-       p = (RTreeScanOpaque) s->opaque;
-       if (p->s_flags & RTS_CURBEFORE)
-               p->s_flags |= RTS_MRKBEFORE;
-       else
-               p->s_flags &= ~RTS_MRKBEFORE;
-
-       o = NULL;
-       n = p->s_stack;
-
-       /* copy the parent stack from the current item data */
-       while (n != NULL)
-       {
-               tmp = (RTSTACK *) palloc(sizeof(RTSTACK));
-               tmp->rts_child = n->rts_child;
-               tmp->rts_blk = n->rts_blk;
-               tmp->rts_parent = o;
-               o = tmp;
-               n = n->rts_parent;
-       }
-
-       freestack(p->s_markstk);
-       p->s_markstk = o;
-
-       /* Update markbuf: make sure to bump ref count on curbuf */
-       if (BufferIsValid(p->markbuf))
-       {
-               ReleaseBuffer(p->markbuf);
-               p->markbuf = InvalidBuffer;
-       }
-       if (BufferIsValid(p->curbuf))
-       {
-               IncrBufferRefCount(p->curbuf);
-               p->markbuf = p->curbuf;
-       }
-
-       PG_RETURN_VOID();
-}
-
-Datum
-rtrestrpos(PG_FUNCTION_ARGS)
-{
-       IndexScanDesc s = (IndexScanDesc) PG_GETARG_POINTER(0);
-       RTreeScanOpaque p;
-       RTSTACK    *o,
-                          *n,
-                          *tmp;
-
-       s->currentItemData = s->currentMarkData;
-       p = (RTreeScanOpaque) s->opaque;
-       if (p->s_flags & RTS_MRKBEFORE)
-               p->s_flags |= RTS_CURBEFORE;
-       else
-               p->s_flags &= ~RTS_CURBEFORE;
-
-       o = NULL;
-       n = p->s_markstk;
-
-       /* copy the parent stack from the current item data */
-       while (n != NULL)
-       {
-               tmp = (RTSTACK *) palloc(sizeof(RTSTACK));
-               tmp->rts_child = n->rts_child;
-               tmp->rts_blk = n->rts_blk;
-               tmp->rts_parent = o;
-               o = tmp;
-               n = n->rts_parent;
-       }
-
-       freestack(p->s_stack);
-       p->s_stack = o;
-
-       /* Update curbuf; be sure to bump ref count on markbuf */
-       if (BufferIsValid(p->curbuf))
-       {
-               ReleaseBuffer(p->curbuf);
-               p->curbuf = InvalidBuffer;
-       }
-       if (BufferIsValid(p->markbuf))
-       {
-               IncrBufferRefCount(p->markbuf);
-               p->curbuf = p->markbuf;
-       }
-
-       PG_RETURN_VOID();
-}
-
-Datum
-rtendscan(PG_FUNCTION_ARGS)
-{
-       IndexScanDesc s = (IndexScanDesc) PG_GETARG_POINTER(0);
-       RTreeScanOpaque p;
-
-       p = (RTreeScanOpaque) s->opaque;
-
-       if (p != NULL)
-       {
-               freestack(p->s_stack);
-               freestack(p->s_markstk);
-               if (BufferIsValid(p->curbuf))
-                       ReleaseBuffer(p->curbuf);
-               if (BufferIsValid(p->markbuf))
-                       ReleaseBuffer(p->markbuf);
-               pfree(s->opaque);
-       }
-
-       rtdropscan(s);
-
-       PG_RETURN_VOID();
-}
-
-static void
-rtregscan(IndexScanDesc s)
-{
-       RTScanList      l;
-
-       l = (RTScanList) palloc(sizeof(RTScanListData));
-       l->rtsl_scan = s;
-       l->rtsl_owner = CurrentResourceOwner;
-       l->rtsl_next = RTScans;
-       RTScans = l;
-}
-
-static void
-rtdropscan(IndexScanDesc s)
-{
-       RTScanList      l;
-       RTScanList      prev;
-
-       prev = NULL;
-
-       for (l = RTScans;
-                l != NULL && l->rtsl_scan != s;
-                l = l->rtsl_next)
-               prev = l;
-
-       if (l == NULL)
-               elog(ERROR, "rtree scan list corrupted -- could not find 0x%p",
-                        (void *) s);
-
-       if (prev == NULL)
-               RTScans = l->rtsl_next;
-       else
-               prev->rtsl_next = l->rtsl_next;
-
-       pfree(l);
-}
-
-/*
- * ReleaseResources_rtree() --- clean up rtree subsystem resources.
- *
- * This is here because it needs to touch this module's static var RTScans.
- */
-void
-ReleaseResources_rtree(void)
-{
-       RTScanList      l;
-       RTScanList      prev;
-       RTScanList      next;
-
-       /*
-        * Note: this should be a no-op during normal query shutdown. However, in
-        * an abort situation ExecutorEnd is not called and so there may be open
-        * index scans to clean up.
-        */
-       prev = NULL;
-
-       for (l = RTScans; l != NULL; l = next)
-       {
-               next = l->rtsl_next;
-               if (l->rtsl_owner == CurrentResourceOwner)
-               {
-                       if (prev == NULL)
-                               RTScans = next;
-                       else
-                               prev->rtsl_next = next;
-
-                       pfree(l);
-                       /* prev does not change */
-               }
-               else
-                       prev = l;
-       }
-}
-
-void
-rtadjscans(Relation r, int op, BlockNumber blkno, OffsetNumber offnum)
-{
-       RTScanList      l;
-       Oid                     relid;
-
-       relid = RelationGetRelid(r);
-       for (l = RTScans; l != NULL; l = l->rtsl_next)
-       {
-               if (RelationGetRelid(l->rtsl_scan->indexRelation) == relid)
-                       rtadjone(l->rtsl_scan, op, blkno, offnum);
-       }
-}
-
-/*
- *     rtadjone() -- adjust one scan for update.
- *
- *             By here, the scan passed in is on a modified relation.  Op tells
- *             us what the modification is, and blkno and offind tell us what
- *             block and offset index were affected.  This routine checks the
- *             current and marked positions, and the current and marked stacks,
- *             to see if any stored location needs to be changed because of the
- *             update.  If so, we make the change here.
- */
-static void
-rtadjone(IndexScanDesc s,
-                int op,
-                BlockNumber blkno,
-                OffsetNumber offnum)
-{
-       RTreeScanOpaque so;
-
-       adjustiptr(s, &(s->currentItemData), op, blkno, offnum);
-       adjustiptr(s, &(s->currentMarkData), op, blkno, offnum);
-
-       so = (RTreeScanOpaque) s->opaque;
-
-       if (op == RTOP_SPLIT)
-       {
-               adjuststack(so->s_stack, blkno);
-               adjuststack(so->s_markstk, blkno);
-       }
-}
-
-/*
- *     adjustiptr() -- adjust current and marked item pointers in the scan
- *
- *             Depending on the type of update and the place it happened, we
- *             need to do nothing, to back up one record, or to start over on
- *             the same page.
- */
-static void
-adjustiptr(IndexScanDesc s,
-                  ItemPointer iptr,
-                  int op,
-                  BlockNumber blkno,
-                  OffsetNumber offnum)
-{
-       OffsetNumber curoff;
-       RTreeScanOpaque so;
-
-       if (ItemPointerIsValid(iptr))
-       {
-               if (ItemPointerGetBlockNumber(iptr) == blkno)
-               {
-                       curoff = ItemPointerGetOffsetNumber(iptr);
-                       so = (RTreeScanOpaque) s->opaque;
-
-                       switch (op)
-                       {
-                               case RTOP_DEL:
-                                       /* back up one if we need to */
-                                       if (curoff >= offnum)
-                                       {
-
-                                               if (curoff > FirstOffsetNumber)
-                                               {
-                                                       /* just adjust the item pointer */
-                                                       ItemPointerSet(iptr, blkno, OffsetNumberPrev(curoff));
-                                               }
-                                               else
-                                               {
-                                                       /*
-                                                        * remember that we're before the current tuple
-                                                        */
-                                                       ItemPointerSet(iptr, blkno, FirstOffsetNumber);
-                                                       if (iptr == &(s->currentItemData))
-                                                               so->s_flags |= RTS_CURBEFORE;
-                                                       else
-                                                               so->s_flags |= RTS_MRKBEFORE;
-                                               }
-                                       }
-                                       break;
-
-                               case RTOP_SPLIT:
-                                       /* back to start of page on split */
-                                       ItemPointerSet(iptr, blkno, FirstOffsetNumber);
-                                       if (iptr == &(s->currentItemData))
-                                               so->s_flags &= ~RTS_CURBEFORE;
-                                       else
-                                               so->s_flags &= ~RTS_MRKBEFORE;
-                                       break;
-
-                               default:
-                                       elog(ERROR, "unrecognized operation in rtree scan adjust: %d", op);
-                       }
-               }
-       }
-}
-
-/*
- *     adjuststack() -- adjust the supplied stack for a split on a page in
- *                                      the index we're scanning.
- *
- *             If a page on our parent stack has split, we need to back up to the
- *             beginning of the page and rescan it.  The reason for this is that
- *             the split algorithm for rtrees doesn't order tuples in any useful
- *             way on a single page.  This means on that a split, we may wind up
- *             looking at some heap tuples more than once.  This is handled in the
- *             access method update code for heaps; if we've modified the tuple we
- *             are looking at already in this transaction, we ignore the update
- *             request.
- */
-static void
-adjuststack(RTSTACK *stk, BlockNumber blkno)
-{
-       while (stk != NULL)
-       {
-               if (stk->rts_blk == blkno)
-                       stk->rts_child = FirstOffsetNumber;
-
-               stk = stk->rts_parent;
-       }
-}
diff --git a/src/backend/access/rtree/rtstrat.c b/src/backend/access/rtree/rtstrat.c
deleted file mode 100644 (file)
index 1b72d98..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-/*-------------------------------------------------------------------------
- *
- * 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];
-}
index 3b8bcb131d0be70ea21c4cf290710ff7ff300c02..f7b48df1263025fa5a167b7e223cf2e0eec02591 100644 (file)
@@ -3,7 +3,7 @@
  *
  * 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"
 
@@ -13,7 +13,6 @@
 #include "access/heapam.h"
 #include "access/multixact.h"
 #include "access/nbtree.h"
-#include "access/rtree.h"
 #include "access/xact.h"
 #include "access/xlog_internal.h"
 #include "commands/dbcommands.h"
@@ -36,7 +35,7 @@ const RmgrData RmgrTable[RM_MAX_ID + 1] = {
        {"Heap", heap_redo, heap_desc, NULL, NULL},
        {"Btree", btree_redo, btree_desc, btree_xlog_startup, btree_xlog_cleanup},
        {"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},
        {"Sequence", seq_redo, seq_desc, NULL, NULL}
 };
index 07654e455ab4104fc4744062514964dfc3f79705..0a19168179f1b01b750d88f1bd9f0e52c30c7cde 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * 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,
                                                   PointerGetDatum(accessMethodName),
                                                   0, 0, 0);
        if (!HeapTupleIsValid(tuple))
-               ereport(ERROR,
-                               (errcode(ERRCODE_UNDEFINED_OBJECT),
-                                errmsg("access method \"%s\" does not exist",
-                                               accessMethodName)));
+       {
+               /*
+                * Hack to provide more-or-less-transparent updating of old RTREE
+                * 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);
        accessMethodForm = (Form_pg_am) GETSTRUCT(tuple);
 
index dddfaa3dbc4ed38fbf03836423f00d99c263d4f0..9aa33831379a810cbcfffb539437f3ecbaf7acc1 100644 (file)
@@ -9,7 +9,7 @@
  *
  *
  * 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
  *     something reasonable, someday.
 
 
 /*
- *     Selectivity functions for rtrees.  These are bogus -- unless we know
- *     the actual key distribution in the index, we can't make a good prediction
- *     of the selectivity of these operators.
+ *     Selectivity functions for geometric operators.  These are bogus -- unless
+ *     we know the actual key distribution in the index, we can't make a good
+ *     prediction of the selectivity of these operators.
  *
  *     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
- *     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.
  *
- *     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,
  *     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
  *     realistic numbers here, it hardly matters...
  */
index 95980ca1e03659fc3649533e6d1aeea7269d410c..85c22ca6c4597870f39b815ef26638bd00315773 100644 (file)
@@ -15,7 +15,7 @@
  *
  *
  * 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)
        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
 hashcostestimate(PG_FUNCTION_ARGS)
 {
index 97933de820b4a1b1688fc6310afe632cc40249c1..dfdb9958f91784d4b5c8fc791e24f69aac96f66c 100644 (file)
@@ -14,7 +14,7 @@
  *
  *
  * 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 @@
 #include "utils/resowner.h"
 #include "access/gistscan.h"
 #include "access/hash.h"
-#include "access/rtree.h"
 #include "storage/bufmgr.h"
 #include "storage/proc.h"
 #include "utils/memutils.h"
@@ -280,7 +279,6 @@ ResourceOwnerReleaseInternal(ResourceOwner owner,
                /* Clean up index scans too */
                ReleaseResources_gist();
                ReleaseResources_hash();
-               ReleaseResources_rtree();
        }
 
        /* Let add-on modules get a chance too */
index 27d7469b9359aa8bbffbd66e95d0ba68e2be035e..d96a375f5df778894670aedc738cf7fa1201ba36 100644 (file)
@@ -3,7 +3,7 @@
  *
  * 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)
        else if (pg_strcasecmp(prev_wd, "USING") == 0)
        {
                static const char *const index_mth[] =
-               {"BTREE", "RTREE", "HASH", "GIST", NULL};
+               {"BTREE", "HASH", "GIST", NULL};
 
                COMPLETE_WITH_LIST(index_mth);
        }
index 22c897959f2036b740b1dcf18e7fd99a611709c6..b48c492f7f8b7c9f23d1b354c7c643e6702fbcf6 100644 (file)
@@ -9,18 +9,18 @@
  * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
  * 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
 #define GIST_H
 
+#include "access/xlog.h"
+#include "access/xlogdefs.h"
 #include "storage/bufpage.h"
 #include "storage/off.h"
 #include "utils/rel.h"
-#include "access/xlog.h"
-#include "access/xlogdefs.h"
 
 /*
  * amproc indexes for GiST indexes.
 #define GIST_EQUAL_PROC                                        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.
  */
index 17ef0d7866d4cc99e0a21b85b4e3c9d2a15ae173..da6bc6968359419d8ef8852cdbea9114d46fb380 100644 (file)
@@ -3,7 +3,7 @@
  *
  * 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
 #define RMGR_H
@@ -23,7 +23,6 @@ typedef uint8 RmgrId;
 #define RM_HEAP_ID                             10
 #define RM_BTREE_ID                            11
 #define RM_HASH_ID                             12
-#define RM_RTREE_ID                            13
 #define RM_GIST_ID                             14
 #define RM_SEQ_ID                              15
 #define RM_MAX_ID                              RM_SEQ_ID
diff --git a/src/include/access/rtree.h b/src/include/access/rtree.h
deleted file mode 100644 (file)
index d5aa103..0000000
+++ /dev/null
@@ -1,145 +0,0 @@
-/*-------------------------------------------------------------------------
- *
- * 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 */
diff --git a/src/include/access/rtscan.h b/src/include/access/rtscan.h
deleted file mode 100644 (file)
index 596ec28..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-/*-------------------------------------------------------------------------
- *
- * 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 */
index 3986f7a7fa128aa44238e8dfacce24e73a438499..94cadcd492e3fbb8e65fbbda2bc8dcd5c2022eeb 100644 (file)
@@ -37,7 +37,7 @@
  * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
  * 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 @@
  */
 
 /*                                                     yyyymmddN */
-#define CATALOG_VERSION_NO     200510211
+#define CATALOG_VERSION_NO     200511071
 
 #endif
index 4f21202fa9b164a68c95decb2e6ff608cb34c688..2ef62c24944d201de2353d2d71dfbb8e93d0c581 100644 (file)
@@ -8,7 +8,7 @@
  * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
  * 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
  *             the genbki.sh script reads this file and generates .bki
@@ -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 ));
 DESCR("b-tree index access method");
 #define BTREE_AM_OID 403
index 09ea2d9856ac168d411493a4752be01e2206d213..55b289212d9e6644b6cdc6a9e2593caef1678a7a 100644 (file)
@@ -23,7 +23,7 @@
  * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
  * 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
  *      the genbki.sh script reads this file and generates .bki
@@ -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
  */
index 38c4f257837bff6e46bf67c0c6d1191f3fb6b3f8..c4d494dea0931ba1b1ec23d6a6e6a410e6fd345d 100644 (file)
@@ -19,7 +19,7 @@
  * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
  * 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
  *       the genbki.sh script reads this file and generates .bki
@@ -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 */
 DATA(insert (   397    0 1 382 ));
 DATA(insert (   421    0 1 357 ));
index 24b4059a83193e2527d126d3a3f38b297c77e671..aa2f86d9e2c23f8a7189a5c298522058a7312108 100644 (file)
@@ -27,7 +27,7 @@
  * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
  * 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
  *       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 ));
 DATA(insert OID =  423 (       403             bit_ops                 PGNSP PGUID 1560 t 0 ));
 DATA(insert OID =  424 (       403             bool_ops                PGNSP PGUID   16 t 0 ));
 #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 ));
 #define BPCHAR_BTREE_OPS_OID 426
 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 ));
 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 = 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 ));
 #define TEXT_BTREE_OPS_OID 1994
 DATA(insert OID = 1995 (       405             text_ops                PGNSP PGUID   25 t 0 ));
index b63b2d4a8b04528fee840ea541a152a253e3e8a7..5b0af25c1c09194d983e0a9502ab26212470c531 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
  * 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
  *       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" _
 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_ ));
 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 */
 
@@ -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_ ));
 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_ ));
 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_ ));
index 1795a9f14a00f72e06c389c12f5817e5b3ea53ee..7e27150ea2dacf36fda724be7d2f8dd729de0388 100644 (file)
@@ -6,7 +6,7 @@
  * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
  * 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
  *       These routines do *not* use the float types from adt/.
@@ -406,14 +406,6 @@ extern Datum poly_circle(PG_FUNCTION_ARGS);
 extern Datum circle_poly(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) */
 extern Datum gist_box_compress(PG_FUNCTION_ARGS);
 extern Datum gist_box_decompress(PG_FUNCTION_ARGS);
index ba91b0b40228213fc190ffe761d16ef7105c3dcd..7ba2dde1d90c45b0ea4202d3d1f326b534c097c6 100644 (file)
@@ -8,7 +8,7 @@
  * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
  * 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,
                                                 double nbuckets);
 
 extern Datum btcostestimate(PG_FUNCTION_ARGS);
-extern Datum rtcostestimate(PG_FUNCTION_ARGS);
 extern Datum hashcostestimate(PG_FUNCTION_ARGS);
 extern Datum gistcostestimate(PG_FUNCTION_ARGS);
 
index 7bd4e0c522668875b9fabed92187bf21a4f63867..13aca04270bf5888067b33d410f139e1a1da9680 100644 (file)
@@ -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)
        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)
 --
 CREATE INDEX grect2ind ON fast_emp4000 USING gist (home_base);
index 2904585883f83e910d275e85e08d366bf0f448fd..aad7a10ed0a0ff1ddd3a8e946a19d248b8f24fcf 100644 (file)
@@ -798,18 +798,6 @@ FROM pg_amop p1 LEFT JOIN pg_opclass p2 ON amopclaid = p2.oid
 ORDER BY 1, 2, 3;
  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 |            2 | <=
@@ -834,7 +822,7 @@ ORDER BY 1, 2, 3;
      783 |           10 | <<|
      783 |           11 | |>>
      783 |           12 | |&>
-(36 rows)
+(24 rows)
 
 -- Check that all operators linked to by opclass entries have selectivity
 -- estimators.  This is not absolutely required, but it seems a reasonable
index 07f40f5c775c17ddcbcec6d8d686a4971a841ab6..aa70bdd46f5fa88100882cbea7d935e7209e8417 100644 (file)
@@ -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)
        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)
 --
index 30898c446ce13c6ef182d589bfcb1ac9d00befa1..9ce2bedfcb65c8a9bddb0bc19a341f6a55c78554 100644 (file)
@@ -212,9 +212,6 @@ index types<br />
  <a id="access_nbtree" name="access_nbtree"></a> <a
 href="../../backend/access/nbtree">access/nbtree</a> - Lehman and
 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
 href="../../backend/access/transam">access/transam</a> -
 transaction manager (BEGIN/ABORT/COMMIT)<br />