Finish repairing 6.5's problems with r-tree indexes: create appropriate
authorTom Lane
Thu, 17 Feb 2000 03:40:02 +0000 (03:40 +0000)
committerTom Lane
Thu, 17 Feb 2000 03:40:02 +0000 (03:40 +0000)
selectivity functions and make the r-tree operators use them.  The
estimation functions themselves are just stubs, unfortunately, but
perhaps someday someone will make them compute realistic estimates.
Change pg_am so that the optimizer can reliably tell the difference
between ordered and unordered indexes --- before it would think that
an r-tree index can be scanned in '<<' order, which is not right AFAIK.
Repair broken negator links for network_sup and related ops.
Initdb forced.  This might be my last initdb force for 7.0 ... hope so
anyway ...

12 files changed:
doc/src/sgml/catalogs.sgml
doc/src/sgml/xindex.sgml
doc/src/sgml/xoper.sgml
src/backend/optimizer/util/plancat.c
src/backend/utils/adt/geo_selfuncs.c
src/include/catalog/catversion.h
src/include/catalog/pg_am.h
src/include/catalog/pg_operator.h
src/include/catalog/pg_proc.h
src/include/utils/geo_decls.h
src/test/regress/expected/create_index.out
src/test/regress/sql/create_index.sql

index f4dd09d88a34025aa58d77a8058b694674bfbfa7..e0009a17c2962f39b6a898199d681d6fb99b81c7 100644 (file)
@@ -1,6 +1,6 @@
 .\" This is -*-nroff-*-
 .\" XXX standard disclaimer belongs here....
-.\" $Header: /cvsroot/pgsql/doc/src/sgml/catalogs.sgml,v 2.4 2000/02/06 05:09:31 momjian Exp $
+.\" $Header: /cvsroot/pgsql/doc/src/sgml/catalogs.sgml,v 2.5 2000/02/17 03:39:39 tgl Exp $
 .TH "SYSTEM CATALOGS" INTRO 03/13/94 PostgreSQL PostgreSQL
 .SH "Section 7 - System Catalogs"
 .de LS
@@ -108,38 +108,37 @@ pg_aggregate
 .fi
 .nf M
 pg_am
-    NameData      amname       /* access method name */
-    oid         amowner    /* usesysid of creator */
-    char        amkind     /* - deprecated */
-               /* originally:
-                  h=hashed
-                  o=ordered
-                  s=special */
-    int2        amstrategies   /* total NUMBER of strategies by which
-                  we can traverse/search this AM */
-    int2        amsupport  /* total NUMBER of support functions
-                  that this AM uses */
-    regproc     amgettuple /* "next valid tuple" function */
-    regproc     aminsert   /* "insert this tuple" function */
-    regproc     amdelete   /* "delete this tuple" function */
-    regproc     amgetattr  /* - deprecated */
-    regproc     amsetlock  /* - deprecated */
-    regproc     amsettid   /* - deprecated */
-    regproc     amfreetuple    /* - deprecated */
-    regproc     ambeginscan    /* "start new scan" function */
-    regproc     amrescan   /* "restart this scan" function */
-    regproc     amendscan  /* "end this scan" function */
-    regproc     ammarkpos  /* "mark current scan position"
-                  function */
-    regproc     amrestrpos /* "restore marked scan position"
-                  function */
-    regproc     amopen     /* - deprecated */
-    regproc     amclose    /* - deprecated */
-    regproc     ambuild    /* "build new index" function */
-    regproc     amcreate   /* - deprecated */
-    regproc     amdestroy  /* - deprecated */
-    regproc     amcostestimate /* estimate cost of an indexscan */
-   
+    NameData    amname          /* access method name */
+    oid         amowner         /* usesysid of creator */
+    int2        amstrategies    /* total NUMBER of strategies by which
+                                   we can traverse/search this AM */
+    int2        amsupport       /* total NUMBER of support functions
+                                   that this AM uses */
+    int2        amorderstrategy /* if this AM has a sort order, the
+                                 * strategy number of the sort operator.
+                                 * Zero if AM is not ordered.
+                                 */
+    regproc     amgettuple      /* "next valid tuple" function */
+    regproc     aminsert        /* "insert this tuple" function */
+    regproc     amdelete        /* "delete this tuple" function */
+    regproc     amgetattr       /* - deprecated */
+    regproc     amsetlock       /* - deprecated */
+    regproc     amsettid        /* - deprecated */
+    regproc     amfreetuple     /* - deprecated */
+    regproc     ambeginscan     /* "start new scan" function */
+    regproc     amrescan        /* "restart this scan" function */
+    regproc     amendscan       /* "end this scan" function */
+    regproc     ammarkpos       /* "mark current scan position"
+                                   function */
+    regproc     amrestrpos      /* "restore marked scan position"
+                                   function */
+    regproc     amopen          /* - deprecated */
+    regproc     amclose         /* - deprecated */
+    regproc     ambuild         /* "build new index" function */
+    regproc     amcreate        /* - deprecated */
+    regproc     amdestroy       /* - deprecated */
+    regproc     amcostestimate  /* estimate cost of an indexscan */
+
 .fi
 .nf M
 pg_amop
index 608465dd1bc03c70b4e07df945f90721040f1638..9fcd9b99dacac381352105f9d968a6a77d7d6ff2 100644 (file)
@@ -1,5 +1,5 @@
 
 
@@ -51,10 +51,6 @@ Postgres documentation
        amowner
        object id of the owner's instance in pg_user
       
-      
-       amkind
-       not used at present, but set to 'o' as a place holder
-      
       
        amstrategies
        number of strategies for this access method (see below)
@@ -63,6 +59,11 @@ Postgres documentation
        amsupport
        number of support routines for this access method (see below)
       
+      
+       amorderstrategy
+       zero if the index offers no sort order, otherwise the strategy
+        number of the strategy operator that describes the sort order
+      
       
        amgettuple
       
@@ -217,6 +218,15 @@ SELECT oid FROM pg_am WHERE amname = 'btree';
    method.  The actual routines are listed elsewhere.
   
 
+  
+   By the way, the amorderstrategy entry tells whether
+   the access method supports ordered scan.  Zero means it doesn't; if it
+   does, amorderstrategy is the number of the strategy
+   routine that corresponds to the ordering operator.  For example, btree
+   has amorderstrategy = 1 which is its
+   "less than" strategy number.
+  
+
   
    The next class of interest is pg_opclass.  This class exists only to
    associate a name and default type with an oid.  In pg_amop, every
index 45d05b6c3b2bf8d53909aba6d846411f3342d66d..153e365e126eea8188a1bac6d0f3dfc4eb72f7f6 100644 (file)
@@ -265,6 +265,13 @@ SELECT (a + b) AS c FROM test_complex;
     yet.)  If you do not do this, things will still work, but the optimizer's
     estimates won't be as good as they could be.
    
+
+   
+    There are additional selectivity functions designed for geometric
+    operators in src/backend/utils/adt/geo_selfuncs.c: areasel, positionsel,
+    and contsel.  At this writing these are just stubs, but you may want
+    to use them (or even better, improve them) anyway.
+   
    
 
    
@@ -294,6 +301,9 @@ SELECT (a + b) AS c FROM test_complex;
    neqjoinsel  for <>
    scalarltjoinsel for < or <=
    scalargtjoinsel for > or >=
+   areajoinsel for 2D area-based comparisons
+   positionjoinsel for 2D position-based comparisons
+   contjoinsel for 2D containment-based comparisons
     
     
    
index 8663cdb0241de0d4aaa475cbfca59a20b9514ee1..e3a60c2c7f04be74e8f0949a0882514cd9ea2791 100644 (file)
@@ -9,7 +9,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/optimizer/util/plancat.c,v 1.47 2000/02/15 20:49:20 tgl Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/optimizer/util/plancat.c,v 1.48 2000/02/17 03:39:40 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -96,8 +96,8 @@ find_secondary_indexes(Query *root, Index relid)
        IndexOptInfo   *info = makeNode(IndexOptInfo);
        int             i;
        Relation        indexRelation;
-       uint16          amstrategy;
        Oid             relam;
+       uint16          amorderstrategy;
 
        /*
         * Need to make these arrays large enough to be sure there is a
@@ -129,37 +129,38 @@ find_secondary_indexes(Query *root, Index relid)
 
        /* Extract info from the relation descriptor for the index */
        indexRelation = index_open(index->indexrelid);
-#ifdef notdef
-       /* XXX should iterate through strategies -- but how?  use #1 for now */
-       amstrategy = indexRelation->rd_am->amstrategies;
-#endif  /* notdef */
-       amstrategy = 1;
        relam = indexRelation->rd_rel->relam;
        info->relam = relam;
        info->pages = indexRelation->rd_rel->relpages;
        info->tuples = indexRelation->rd_rel->reltuples;
        info->amcostestimate = index_cost_estimator(indexRelation);
+       amorderstrategy = indexRelation->rd_am->amorderstrategy;
        index_close(indexRelation);
 
        /*
-        * Fetch the ordering operators associated with the index.
-        *
-        * XXX what if it's a hash or other unordered index?
+        * Fetch the ordering operators associated with the index,
+        * if any.
         */
        MemSet(info->ordering, 0, sizeof(Oid) * (INDEX_MAX_KEYS+1));
-       for (i = 0; i < INDEX_MAX_KEYS && index->indclass[i]; i++)
+       if (amorderstrategy != 0)
        {
-           HeapTuple       amopTuple;
+           for (i = 0; i < INDEX_MAX_KEYS && index->indclass[i]; i++)
+           {
+               HeapTuple       amopTuple;
+               Form_pg_amop    amop;
 
-           amopTuple = SearchSysCacheTuple(AMOPSTRATEGY,
+               amopTuple =
+                   SearchSysCacheTuple(AMOPSTRATEGY,
                                        ObjectIdGetDatum(relam),
                                        ObjectIdGetDatum(index->indclass[i]),
-                                       UInt16GetDatum(amstrategy),
+                                       UInt16GetDatum(amorderstrategy),
                                        0);
-           if (!HeapTupleIsValid(amopTuple))
-               elog(ERROR, "find_secondary_indexes: no amop %u %u %d",
-                    relam, index->indclass[i], amstrategy);
-           info->ordering[i] = ((Form_pg_amop) GETSTRUCT(amopTuple))->amopopr;
+               if (!HeapTupleIsValid(amopTuple))
+                   elog(ERROR, "find_secondary_indexes: no amop %u %u %d",
+                        relam, index->indclass[i], (int) amorderstrategy);
+               amop = (Form_pg_amop) GETSTRUCT(amopTuple);
+               info->ordering[i] = amop->amopopr;
+           }
        }
 
        indexes = lcons(info, indexes);
index 9dd0de0e424557ab40cdb8f39c2436c9e3688742..95e594ea0ef90fa1d1f1df5df2402f8d363a6cc0 100644 (file)
@@ -1,6 +1,6 @@
 /*-------------------------------------------------------------------------
  *
- * geo-selfuncs.c
+ * geo_selfuncs.c
  *   Selectivity routines registered in the operator catalog in the
  *   "oprrest" and "oprjoin" attributes.
  *
@@ -9,9 +9,10 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/utils/adt/geo_selfuncs.c,v 1.12 2000/01/26 05:57:14 momjian Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/utils/adt/geo_selfuncs.c,v 1.13 2000/02/17 03:39:42 tgl Exp $
  *
- *     XXX These are totally bogus.
+ * XXX These are totally bogus.  Perhaps someone will make them do
+ * something reasonable, someday.
  *
  *-------------------------------------------------------------------------
  */
 
 #include "utils/builtins.h"
 
+
+/*
+ * 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.
+ *
+ * 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
+ * be fairly small.
+ *
+ * In general, rtrees need 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,
+ * ought to be adjusted accordingly --- but until we can generate somewhat
+ * realistic numbers here, it hardly matters...
+ */
+
+
+/*
+ * Selectivity for operators that depend on area, such as "overlap".
+ */
+
 float64
 areasel(Oid opid,
        Oid relid,
        AttrNumber attno,
-       char *value,
+       Datum value,
        int32 flag)
 {
    float64     result;
 
    result = (float64) palloc(sizeof(float64data));
-   *result = 1.0 / 4.0;
+   *result = 0.05;
    return result;
 }
 
@@ -43,81 +68,66 @@ areajoinsel(Oid opid,
    float64     result;
 
    result = (float64) palloc(sizeof(float64data));
-   *result = 1.0 / 4.0;
+   *result = 0.05;
    return result;
 }
 
 /*
- * 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.
+ * positionsel
  *
- * In general, rtrees need to search multiple subtrees in order to guarantee
- * that all occurrences of the same key have been found.  Because of this,
- * the heuristic selectivity functions we return are higher than they would
- * otherwise be.
- */
-
-/*
- * left_sel -- How likely is a box to be strictly left of (right of, above,
- *             below) a given box?
+ * How likely is a box to be strictly left of (right of, above, below)
+ * a given box?
  */
 
-#ifdef NOT_USED
 float64
-leftsel(Oid opid,
-       Oid relid,
-       AttrNumber attno,
-       char *value,
-       int32 flag)
+positionsel(Oid opid,
+           Oid relid,
+           AttrNumber attno,
+           Datum value,
+           int32 flag)
 {
    float64     result;
 
    result = (float64) palloc(sizeof(float64data));
-   *result = 1.0 / 6.0;
+   *result = 0.1;
    return result;
 }
 
-#endif
-
-#ifdef NOT_USED
 float64
-leftjoinsel(Oid opid,
-           Oid relid1,
-           AttrNumber attno1,
-           Oid relid2,
-           AttrNumber attno2)
+positionjoinsel(Oid opid,
+               Oid relid1,
+               AttrNumber attno1,
+               Oid relid2,
+               AttrNumber attno2)
 {
    float64     result;
 
    result = (float64) palloc(sizeof(float64data));
-   *result = 1.0 / 6.0;
+   *result = 0.1;
    return result;
 }
 
-#endif
-
 /*
  * contsel -- How likely is a box to contain (be contained by) a given box?
+ *
+ * This is a tighter constraint than "overlap", so produce a smaller
+ * estimate than areasel does.
  */
-#ifdef NOT_USED
+
 float64
 contsel(Oid opid,
        Oid relid,
        AttrNumber attno,
-       char *value,
+       Datum value,
        int32 flag)
 {
    float64     result;
 
    result = (float64) palloc(sizeof(float64data));
-   *result = 1.0 / 10.0;
+   *result = 0.01;
    return result;
 }
 
-#endif
-
-#ifdef NOT_USED
 float64
 contjoinsel(Oid opid,
            Oid relid1,
@@ -128,8 +138,6 @@ contjoinsel(Oid opid,
    float64     result;
 
    result = (float64) palloc(sizeof(float64data));
-   *result = 1.0 / 10.0;
+   *result = 0.01;
    return result;
 }
-
-#endif
index 482b299c55d6c4843e1620775b21b5b39fda1a80..b64d62be2bc6b492ce8085c2db5927dd398c78e9 100644 (file)
@@ -37,7 +37,7 @@
  * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: catversion.h,v 1.15 2000/02/16 17:26:06 thomas Exp $
+ * $Id: catversion.h,v 1.16 2000/02/17 03:39:45 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -53,6 +53,6 @@
  */
 
 /*                          yyyymmddN */
-#define CATALOG_VERSION_NO  200002161
+#define CATALOG_VERSION_NO  200002162
 
 #endif
index a1e55784b0fcd2b5739247ac2fffb46d64532938..dfebc0e8c8f46b6f3c3c949d4add0fb0bd77deee 100644 (file)
@@ -8,7 +8,7 @@
  * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: pg_am.h,v 1.13 2000/01/26 05:57:56 momjian Exp $
+ * $Id: pg_am.h,v 1.14 2000/02/17 03:39:47 tgl Exp $
  *
  * NOTES
  *     the genbki.sh script reads this file and generates .bki
  */
 CATALOG(pg_am)
 {
-   NameData    amname;
-   int4        amowner;
-   char        amkind;
-   int2        amstrategies;
-   int2        amsupport;
-   regproc     amgettuple;
-   regproc     aminsert;
-   regproc     amdelete;
-   regproc     amgetattr;
-   regproc     amsetlock;
-   regproc     amsettid;
-   regproc     amfreetuple;
-   regproc     ambeginscan;
-   regproc     amrescan;
-   regproc     amendscan;
-   regproc     ammarkpos;
-   regproc     amrestrpos;
-   regproc     amopen;
-   regproc     amclose;
-   regproc     ambuild;
-   regproc     amcreate;
-   regproc     amdestroy;
-   regproc     amcostestimate;
+   NameData    amname;         /* access method name */
+   int4        amowner;        /* usesysid of creator */
+   int2        amstrategies;   /* total NUMBER of strategies by which
+                                * we can traverse/search this AM */
+   int2        amsupport;      /* total NUMBER of support functions
+                                * that this AM uses */
+   int2        amorderstrategy; /* if this AM has a sort order, the
+                                 * strategy number of the sort operator.
+                                 * Zero if AM is not ordered. */
+   regproc     amgettuple;     /* "next valid tuple" function */
+   regproc     aminsert;       /* "insert this tuple" function */
+   regproc     amdelete;       /* "delete this tuple" function */
+   regproc     amgetattr;      /* - deprecated */
+   regproc     amsetlock;      /* - deprecated */
+   regproc     amsettid;       /* - deprecated */
+   regproc     amfreetuple;    /* - deprecated */
+   regproc     ambeginscan;    /* "start new scan" function */
+   regproc     amrescan;       /* "restart this scan" function */
+   regproc     amendscan;      /* "end this scan" function */
+   regproc     ammarkpos;      /* "mark current scan position" function */
+   regproc     amrestrpos;     /* "restore marked scan position" function */
+   regproc     amopen;         /* - deprecated */
+   regproc     amclose;        /* - deprecated */
+   regproc     ambuild;        /* "build new index" function */
+   regproc     amcreate;       /* - deprecated */
+   regproc     amdestroy;      /* - deprecated */
+   regproc     amcostestimate; /* estimate cost of an indexscan */
 } FormData_pg_am;
 
 /* ----------------
@@ -75,9 +79,9 @@ typedef FormData_pg_am *Form_pg_am;
 #define Natts_pg_am                        23
 #define Anum_pg_am_amname              1
 #define Anum_pg_am_amowner             2
-#define Anum_pg_am_amkind              3
-#define Anum_pg_am_amstrategies            4
-#define Anum_pg_am_amsupport           5
+#define Anum_pg_am_amstrategies            3
+#define Anum_pg_am_amsupport           4
+#define Anum_pg_am_amorderstrategy     5
 #define Anum_pg_am_amgettuple          6
 #define Anum_pg_am_aminsert                7
 #define Anum_pg_am_amdelete                8
@@ -102,15 +106,15 @@ typedef FormData_pg_am *Form_pg_am;
  * ----------------
  */
 
-DATA(insert OID = 402 (  rtree PGUID "o" 8 3 rtgettuple rtinsert rtdelete - - - - rtbeginscan rtrescan rtendscan rtmarkpos rtrestrpos - - rtbuild - - rtcostestimate ));
+DATA(insert OID = 402 (  rtree PGUID 8 3 0 rtgettuple rtinsert rtdelete - - - - rtbeginscan rtrescan rtendscan rtmarkpos rtrestrpos - - rtbuild - - rtcostestimate ));
 DESCR("");
-DATA(insert OID = 403 (  btree PGUID "o" 5 1 btgettuple btinsert btdelete - - - - btbeginscan btrescan btendscan btmarkpos btrestrpos - - btbuild - - btcostestimate ));
+DATA(insert OID = 403 (  btree PGUID 5 1 1 btgettuple btinsert btdelete - - - - btbeginscan btrescan btendscan btmarkpos btrestrpos - - btbuild - - btcostestimate ));
 DESCR("");
 #define BTREE_AM_OID 403
-DATA(insert OID = 405 (  hash PGUID "o"  1 1 hashgettuple hashinsert hashdelete - - - - hashbeginscan hashrescan hashendscan hashmarkpos hashrestrpos - - hashbuild - - hashcostestimate ));
+DATA(insert OID = 405 (  hash PGUID 1 1 0 hashgettuple hashinsert hashdelete - - - - hashbeginscan hashrescan hashendscan hashmarkpos hashrestrpos - - hashbuild - - hashcostestimate ));
 DESCR("");
 #define HASH_AM_OID 405
-DATA(insert OID = 783 (  gist PGUID "o" 100 7 gistgettuple gistinsert gistdelete - - - - gistbeginscan gistrescan gistendscan gistmarkpos gistrestrpos - - gistbuild - - gistcostestimate ));
+DATA(insert OID = 783 (  gist PGUID 100 7 0 gistgettuple gistinsert gistdelete - - - - gistbeginscan gistrescan gistendscan gistmarkpos gistrestrpos - - gistbuild - - gistcostestimate ));
 DESCR("");
 
 #endif  /* PG_AM_H */
index e510c621d02e2a649a32809b68294c00708d937e..965c7860e45d9ab2140820b85d2ad71cacac6e98 100644 (file)
@@ -8,7 +8,7 @@
  * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: pg_operator.h,v 1.68 2000/02/16 17:26:07 thomas Exp $
+ * $Id: pg_operator.h,v 1.69 2000/02/17 03:39:48 tgl Exp $
  *
  * NOTES
  *   the genbki.sh script reads this file and generates .bki
@@ -157,31 +157,31 @@ DATA(insert OID = 420 ( "<="     PGUID 0 b t f  20  23  16  82 419 0 0 int84le sc
 DATA(insert OID = 430 ( ">="      PGUID 0 b t f  20  23  16  80 418 0 0 int84ge scalargtsel scalargtjoinsel ));
 
 DATA(insert OID = 484 (  "-"      PGUID 0 l t f   0  20  20   0   0   0   0 int8um - - ));
-DATA(insert OID = 485 (  "<<"     PGUID 0 b t f 604 604  16   0   0   0   0 poly_left - - ));
-DATA(insert OID = 486 (  "&<"     PGUID 0 b t f 604 604  16   0   0   0   0 poly_overleft - - ));
-DATA(insert OID = 487 (  "&>"     PGUID 0 b t f 604 604  16   0   0   0   0 poly_overright - - ));
-DATA(insert OID = 488 (  ">>"     PGUID 0 b t f 604 604  16   0   0   0   0 poly_right - - ));
-DATA(insert OID = 489 (  "@"      PGUID 0 b t f 604 604  16 490   0   0   0 poly_contained - - ));
-DATA(insert OID = 490 (  "~"      PGUID 0 b t f 604 604  16 489   0   0   0 poly_contain - - ));
+DATA(insert OID = 485 (  "<<"     PGUID 0 b t f 604 604  16   0   0   0   0 poly_left positionsel positionjoinsel ));
+DATA(insert OID = 486 (  "&<"     PGUID 0 b t f 604 604  16   0   0   0   0 poly_overleft positionsel positionjoinsel ));
+DATA(insert OID = 487 (  "&>"     PGUID 0 b t f 604 604  16   0   0   0   0 poly_overright positionsel positionjoinsel ));
+DATA(insert OID = 488 (  ">>"     PGUID 0 b t f 604 604  16   0   0   0   0 poly_right positionsel positionjoinsel ));
+DATA(insert OID = 489 (  "@"      PGUID 0 b t f 604 604  16 490   0   0   0 poly_contained contsel contjoinsel ));
+DATA(insert OID = 490 (  "~"      PGUID 0 b t f 604 604  16 489   0   0   0 poly_contain contsel contjoinsel ));
 DATA(insert OID = 491 (  "~="     PGUID 0 b t f 604 604  16 491   0   0   0 poly_same eqsel eqjoinsel ));
-DATA(insert OID = 492 (  "&&"     PGUID 0 b t f 604 604  16   0   0   0   0 poly_overlap - - ));
-DATA(insert OID = 493 (  "<<"     PGUID 0 b t f 603 603  16   0   0   0   0 box_left - - ));
-DATA(insert OID = 494 (  "&<"     PGUID 0 b t f 603 603  16   0   0   0   0 box_overleft - - ));
-DATA(insert OID = 495 (  "&>"     PGUID 0 b t f 603 603  16   0   0   0   0 box_overright - - ));
-DATA(insert OID = 496 (  ">>"     PGUID 0 b t f 603 603  16   0   0   0   0 box_right - - ));
-DATA(insert OID = 497 (  "@"      PGUID 0 b t f 603 603  16 498   0   0   0 box_contained - - ));
-DATA(insert OID = 498 (  "~"      PGUID 0 b t f 603 603  16 497   0   0   0 box_contain - - ));
+DATA(insert OID = 492 (  "&&"     PGUID 0 b t f 604 604  16   0   0   0   0 poly_overlap areasel areajoinsel ));
+DATA(insert OID = 493 (  "<<"     PGUID 0 b t f 603 603  16   0   0   0   0 box_left positionsel positionjoinsel ));
+DATA(insert OID = 494 (  "&<"     PGUID 0 b t f 603 603  16   0   0   0   0 box_overleft positionsel positionjoinsel ));
+DATA(insert OID = 495 (  "&>"     PGUID 0 b t f 603 603  16   0   0   0   0 box_overright positionsel positionjoinsel ));
+DATA(insert OID = 496 (  ">>"     PGUID 0 b t f 603 603  16   0   0   0   0 box_right positionsel positionjoinsel ));
+DATA(insert OID = 497 (  "@"      PGUID 0 b t f 603 603  16 498   0   0   0 box_contained contsel contjoinsel ));
+DATA(insert OID = 498 (  "~"      PGUID 0 b t f 603 603  16 497   0   0   0 box_contain contsel contjoinsel ));
 DATA(insert OID = 499 (  "~="     PGUID 0 b t f 603 603  16 499   0   0   0 box_same eqsel eqjoinsel ));
-DATA(insert OID = 500 (  "&&"     PGUID 0 b t f 603 603  16   0   0   0   0 box_overlap - - ));
+DATA(insert OID = 500 (  "&&"     PGUID 0 b t f 603 603  16   0   0   0   0 box_overlap areasel areajoinsel ));
 DATA(insert OID = 501 (  ">="     PGUID 0 b t f 603 603  16 505 504   0   0 box_ge areasel areajoinsel ));
 DATA(insert OID = 502 (  ">"      PGUID 0 b t f 603 603  16 504 505   0   0 box_gt areasel areajoinsel ));
 DATA(insert OID = 503 (  "="      PGUID 0 b t f 603 603  16 503   0 504 504 box_eq eqsel eqjoinsel ));
 DATA(insert OID = 504 (  "<"      PGUID 0 b t f 603 603  16 502 501   0   0 box_lt areasel areajoinsel ));
 DATA(insert OID = 505 (  "<="     PGUID 0 b t f 603 603  16 501 502   0   0 box_le areasel areajoinsel ));
-DATA(insert OID = 506 (  ">^"     PGUID 0 b t f 600 600  16   0   0   0   0 point_above - - ));
-DATA(insert OID = 507 (  "<<"     PGUID 0 b t f 600 600  16   0   0   0   0 point_left - - ));
-DATA(insert OID = 508 (  ">>"     PGUID 0 b t f 600 600  16   0   0   0   0 point_right - - ));
-DATA(insert OID = 509 (  "<^"     PGUID 0 b t f 600 600  16   0   0   0   0 point_below - - ));
+DATA(insert OID = 506 (  ">^"     PGUID 0 b t f 600 600  16   0   0   0   0 point_above positionsel positionjoinsel ));
+DATA(insert OID = 507 (  "<<"     PGUID 0 b t f 600 600  16   0   0   0   0 point_left positionsel positionjoinsel ));
+DATA(insert OID = 508 (  ">>"     PGUID 0 b t f 600 600  16   0   0   0   0 point_right positionsel positionjoinsel ));
+DATA(insert OID = 509 (  "<^"     PGUID 0 b t f 600 600  16   0   0   0   0 point_below positionsel positionjoinsel ));
 DATA(insert OID = 510 (  "~="     PGUID 0 b t f 600 600  16 510   0   0   0 point_eq eqsel eqjoinsel ));
 DATA(insert OID = 511 (  "@"      PGUID 0 b t f 600 603  16   0   0   0   0 on_pb - - ));
 DATA(insert OID = 512 (  "@"      PGUID 0 b t f 600 602  16 755   0   0   0 on_ppath - - ));
@@ -388,9 +388,9 @@ DATA(insert OID =  796 (  ">="     PGUID 0 b t f  602  602   16  795  0 0 0 path_n
 DATA(insert OID =  797 (  "#"     PGUID 0 l t f    0  602   23    0  0 0 0 path_npoints - - ));
 DATA(insert OID =  798 (  "?#"    PGUID 0 b t f  602  602   16    0  0 0 0 path_inter - - ));
 DATA(insert OID =  799 (  "@-@"    PGUID 0 l t f   0  602  701    0  0 0 0 path_length - - ));
-DATA(insert OID =  800 (  ">^"    PGUID 0 b t f  603  603   16    0  0 0 0 box_above - - ));
-DATA(insert OID =  801 (  "<^"    PGUID 0 b t f  603  603   16    0  0 0 0 box_below - - ));
-DATA(insert OID =  802 (  "?#"    PGUID 0 b t f  603  603   16    0  0 0 0 box_overlap - - ));
+DATA(insert OID =  800 (  ">^"    PGUID 0 b t f  603  603   16    0  0 0 0 box_above positionsel positionjoinsel ));
+DATA(insert OID =  801 (  "<^"    PGUID 0 b t f  603  603   16    0  0 0 0 box_below positionsel positionjoinsel ));
+DATA(insert OID =  802 (  "?#"    PGUID 0 b t f  603  603   16    0  0 0 0 box_overlap areasel areajoinsel ));
 DATA(insert OID =  803 (  "#"     PGUID 0 b t f  603  603  603    0  0 0 0 box_intersect - - ));
 DATA(insert OID =  804 (  "+"     PGUID 0 b t f  603  600  603    0  0 0 0 box_add - - ));
 DATA(insert OID =  805 (  "-"     PGUID 0 b t f  603  600  603    0  0 0 0 box_sub - - ));
@@ -570,16 +570,16 @@ DATA(insert OID = 1503 (  ">"   PGUID 0 b t f  718  718   16 1502 1504    0    0 circle
 DATA(insert OID = 1504 (  "<="   PGUID 0 b t f  718  718   16 1505 1503    0    0 circle_le areasel areajoinsel ));
 DATA(insert OID = 1505 (  ">="   PGUID 0 b t f  718  718   16 1504 1502    0    0 circle_ge areasel areajoinsel ));
 
-DATA(insert OID = 1506 (  "<<"   PGUID 0 b t f  718  718   16    0    0    0    0 circle_left - - ));
-DATA(insert OID = 1507 (  "&<"   PGUID 0 b t f  718  718   16    0    0    0    0 circle_overleft - - ));
-DATA(insert OID = 1508 (  "&>"   PGUID 0 b t f  718  718   16    0    0    0    0 circle_overright - - ));
-DATA(insert OID = 1509 (  ">>"   PGUID 0 b t f  718  718   16    0    0    0    0 circle_right - - ));
-DATA(insert OID = 1510 (  "@"    PGUID 0 b t f  718  718   16 1511    0    0    0 circle_contained - - ));
-DATA(insert OID = 1511 (  "~"    PGUID 0 b t f  718  718   16 1510    0    0    0 circle_contain - - ));
+DATA(insert OID = 1506 (  "<<"   PGUID 0 b t f  718  718   16    0    0    0    0 circle_left positionsel positionjoinsel ));
+DATA(insert OID = 1507 (  "&<"   PGUID 0 b t f  718  718   16    0    0    0    0 circle_overleft positionsel positionjoinsel ));
+DATA(insert OID = 1508 (  "&>"   PGUID 0 b t f  718  718   16    0    0    0    0 circle_overright positionsel positionjoinsel ));
+DATA(insert OID = 1509 (  ">>"   PGUID 0 b t f  718  718   16    0    0    0    0 circle_right positionsel positionjoinsel ));
+DATA(insert OID = 1510 (  "@"    PGUID 0 b t f  718  718   16 1511    0    0    0 circle_contained contsel contjoinsel ));
+DATA(insert OID = 1511 (  "~"    PGUID 0 b t f  718  718   16 1510    0    0    0 circle_contain contsel contjoinsel ));
 DATA(insert OID = 1512 (  "~="   PGUID 0 b t f  718  718   16 1512    0    0    0 circle_same eqsel eqjoinsel ));
-DATA(insert OID = 1513 (  "&&"   PGUID 0 b t f  718  718   16    0    0    0    0 circle_overlap - - ));
-DATA(insert OID = 1514 (  ">^"   PGUID 0 b t f  718  718   16    0    0    0    0 circle_above - - ));
-DATA(insert OID = 1515 (  "<^"   PGUID 0 b t f  718  718   16    0    0    0    0 circle_below - - ));
+DATA(insert OID = 1513 (  "&&"   PGUID 0 b t f  718  718   16    0    0    0    0 circle_overlap areasel areajoinsel ));
+DATA(insert OID = 1514 (  ">^"   PGUID 0 b t f  718  718   16    0    0    0    0 circle_above positionsel positionjoinsel ));
+DATA(insert OID = 1515 (  "<^"   PGUID 0 b t f  718  718   16    0    0    0    0 circle_below positionsel positionjoinsel ));
 
 DATA(insert OID = 1516 (  "+"    PGUID 0 b t f  718  600  718    0    0    0    0 circle_add_pt - - ));
 DATA(insert OID = 1517 (  "-"    PGUID 0 b t f  718  600  718    0    0    0    0 circle_sub_pt - - ));
@@ -652,10 +652,10 @@ DATA(insert OID = 1203 (  "<"    PGUID 0 b t f 869 869     16 1205 1206 0 0 network
 DATA(insert OID = 1204 (  "<="    PGUID 0 b t f 869 869     16 1206 1205 0 0 network_le scalarltsel scalarltjoinsel ));
 DATA(insert OID = 1205 (  ">"     PGUID 0 b t f 869 869     16 1203 1204 0 0 network_gt scalargtsel scalargtjoinsel ));
 DATA(insert OID = 1206 (  ">="    PGUID 0 b t f 869 869     16 1204 1203 0 0 network_ge scalargtsel scalargtjoinsel ));
-DATA(insert OID = 931  (  "<<"    PGUID 0 b t f 869 869     16 933  934  0 0 network_sub - - ));
-DATA(insert OID = 932  (  "<<="    PGUID 0 b t f 869 869    16 934  933  0 0 network_subeq - - ));
-DATA(insert OID = 933  (  ">>"    PGUID 0 b t f 869 869     16 931  932  0 0 network_sup - - ));
-DATA(insert OID = 934  (  ">>="    PGUID 0 b t f 869 869    16 932  931  0 0 network_supeq - - ));
+DATA(insert OID = 931  (  "<<"    PGUID 0 b t f 869 869     16 933     0 0 0 network_sub - - ));
+DATA(insert OID = 932  (  "<<="    PGUID 0 b t f 869 869    16 934     0 0 0 network_subeq - - ));
+DATA(insert OID = 933  (  ">>"    PGUID 0 b t f 869 869     16 931     0 0 0 network_sup - - ));
+DATA(insert OID = 934  (  ">>="    PGUID 0 b t f 869 869    16 932     0 0 0 network_supeq - - ));
 
 /* CIDR type */
 DATA(insert OID = 820 (  "="      PGUID 0 b t f 650 650     16 820 821 0 0 network_eq eqsel eqjoinsel ));
@@ -664,10 +664,10 @@ DATA(insert OID = 822 (  "<"     PGUID 0 b t f 650 650     16 824 825 0 0 network_lt
 DATA(insert OID = 823 (  "<="     PGUID 0 b t f 650 650     16 825 824 0 0 network_le scalarltsel scalarltjoinsel ));
 DATA(insert OID = 824 (  ">"      PGUID 0 b t f 650 650     16 822 823 0 0 network_gt scalargtsel scalargtjoinsel ));
 DATA(insert OID = 825 (  ">="     PGUID 0 b t f 650 650     16 823 822 0 0 network_ge scalargtsel scalargtjoinsel ));
-DATA(insert OID = 826 (  "<<"     PGUID 0 b t f 650 650     16 828 1004  0 0 network_sub - - ));
-DATA(insert OID = 827 (  "<<="    PGUID 0 b t f 650 650     16 1004 828  0 0 network_subeq - - ));
-DATA(insert OID = 828 (  ">>"     PGUID 0 b t f 650 650     16 826  827  0 0 network_sup - - ));
-DATA(insert OID = 1004 ( ">>="    PGUID 0 b t f 650 650     16 827  826  0 0 network_supeq - - ));
+DATA(insert OID = 826 (  "<<"     PGUID 0 b t f 650 650     16 828   0 0 0 network_sub - - ));
+DATA(insert OID = 827 (  "<<="    PGUID 0 b t f 650 650     16 1004  0 0 0 network_subeq - - ));
+DATA(insert OID = 828 (  ">>"     PGUID 0 b t f 650 650     16 826   0 0 0 network_sup - - ));
+DATA(insert OID = 1004 ( ">>="    PGUID 0 b t f 650 650     16 827   0 0 0 network_supeq - - ));
 
 /* NUMERIC type - OID's 1700-1799 */
 DATA(insert OID = 1752 (  "="     PGUID 0 b t f 1700 1700   16 1752 1753 1754 1754 numeric_eq eqsel eqjoinsel ));
index 64c015fbff25058a8c2b5f1e37d36d911f666b11..4fdbaaaf9ddeac0ad68d89bd9a44f7fa68de3112 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: pg_proc.h,v 1.122 2000/02/16 17:26:07 thomas Exp $
+ * $Id: pg_proc.h,v 1.123 2000/02/17 03:39:48 tgl Exp $
  *
  * NOTES
  *   The script catalog/genbki.sh reads this file and generates .bki
@@ -293,9 +293,9 @@ DESCR("contained in");
 DATA(insert OID = 138 (  box_center           PGUID 11 f t t 1 f 600 "603" 100 1 0 100  box_center - ));
 DESCR("center of");
 DATA(insert OID = 139 (  areasel          PGUID 11 f t f 5 f 701 "26 26 21 0 23" 100 0 0 100  areasel - ));
-DESCR("restriction selectivity for operators on areas");
+DESCR("restriction selectivity for area-comparison operators");
 DATA(insert OID = 140 (  areajoinsel      PGUID 11 f t f 5 f 701 "26 26 21 26 21" 100 0 0 100  areajoinsel - ));
-DESCR("join selectivity for operators on areas");
+DESCR("join selectivity for area-comparison operators");
 DATA(insert OID = 141 (  int4mul          PGUID 11 f t t 2 f 23 "23 23" 100 0 0 100  int4mul - ));
 DESCR("multiply");
 DATA(insert OID = 142 (  int4fac          PGUID 11 f t t 1 f 23 "23" 100 0 0 100  int4fac - ));
@@ -1565,6 +1565,15 @@ DESCR("current transaction time");
 
 /* OIDS 1300 - 1399 */
 
+DATA(insert OID = 1300 (  positionsel         PGUID 11 f t f 5 f 701 "26 26 21 0 23" 100 0 0 100  positionsel - ));
+DESCR("restriction selectivity for position-comparison operators");
+DATA(insert OID = 1301 (  positionjoinsel     PGUID 11 f t f 5 f 701 "26 26 21 26 21" 100 0 0 100  positionjoinsel - ));
+DESCR("join selectivity for position-comparison operators");
+DATA(insert OID = 1302 (  contsel         PGUID 11 f t f 5 f 701 "26 26 21 0 23" 100 0 0 100  contsel - ));
+DESCR("restriction selectivity for containment comparison operators");
+DATA(insert OID = 1303 (  contjoinsel     PGUID 11 f t f 5 f 701 "26 26 21 26 21" 100 0 0 100  contjoinsel - ));
+DESCR("join selectivity for containment comparison operators");
+
 DATA(insert OID = 1314 (  timestamp_cmp         PGUID 11 f t f 2 f   23 "1184 1184" 100 0 0 100  timestamp_cmp - ));
 DESCR("less-equal-greater");
 DATA(insert OID = 1315 (  interval_cmp      PGUID 11 f t f 2 f   23 "1186 1186" 100 0 0 100  interval_cmp - ));
index 24a791dbecfe9fc9c551858fa9d214f53aa2dcc5..50745f9008be932010800d20a0fa7b174744b7a1 100644 (file)
@@ -6,12 +6,13 @@
  * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: geo_decls.h,v 1.24 2000/01/26 05:58:38 momjian Exp $
+ * $Id: geo_decls.h,v 1.25 2000/02/17 03:39:51 tgl Exp $
  *
  * NOTE
  *   These routines do *not* use the float types from adt/.
  *
  *   XXX These routines were not written by a numerical analyst.
+ *
  *   XXX I have made some attempt to flesh out the operators
  *     and data types. There are still some more to do. - tgl 97/04/19
  *
@@ -362,8 +363,16 @@ extern double circle_dt(CIRCLE *circle1, CIRCLE *circle2);
 
 /* geo_selfuncs.c */
 extern float64 areasel(Oid opid, Oid relid, AttrNumber attno,
-       char *value, int32 flag);
+                      Datum value, int32 flag);
 extern float64 areajoinsel(Oid opid, Oid relid1, AttrNumber attno1,
-           Oid relid2, AttrNumber attno2);
+                          Oid relid2, AttrNumber attno2);
+extern float64 positionsel(Oid opid, Oid relid, AttrNumber attno,
+                          Datum value, int32 flag);
+extern float64 positionjoinsel(Oid opid, Oid relid1, AttrNumber attno1,
+                              Oid relid2, AttrNumber attno2);
+extern float64 contsel(Oid opid, Oid relid, AttrNumber attno,
+                      Datum value, int32 flag);
+extern float64 contjoinsel(Oid opid, Oid relid1, AttrNumber attno1,
+                          Oid relid2, AttrNumber attno2);
 
 #endif  /* GEO_DECLS_H */
index 3b070452e4dea4bc3be80dc8a6adaea3256ce884..3e727517741142dc5d0cf7e7d9425638b33460d4 100644 (file)
@@ -47,10 +47,22 @@ CREATE INDEX bt_f8_index ON bt_f8_heap USING btree (seqno float8_ops);
 -- 
 -- 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
+-- in the regression test (we check them using the sequoia 2000
 -- benchmark).
 --
 CREATE INDEX rect2ind ON fast_emp4000 USING rtree (home_base bigbox_ops);
+-- there's no easy way to check that this command actually is using
+-- 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       
+-----------------------
+ (337,455),(240,359)
+ (1444,403),(1346,344)
+(2 rows)
+
 --
 -- HASH
 --
index 00281765a3025dbdd8ec195784bb76a8cecba65c..2ebc7ef3c3a08585406b5d1170b8ec0ac73b19b9 100644 (file)
@@ -70,11 +70,17 @@ CREATE INDEX bt_f8_index ON bt_f8_heap USING btree (seqno float8_ops);
 -- 
 -- 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
+-- in the regression test (we check them using the sequoia 2000
 -- benchmark).
 --
 CREATE INDEX rect2ind ON fast_emp4000 USING rtree (home_base bigbox_ops);
 
+-- there's no easy way to check that this command actually is using
+-- 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 <<;
 
 --
 -- HASH