summaryrefslogtreecommitdiff
path: root/src/include
diff options
context:
space:
mode:
authorHeikki Linnakangas <heikki.linnakangas@iki.fi>2015-05-15 14:26:51 +0300
committerHeikki Linnakangas <heikki.linnakangas@iki.fi>2015-05-15 14:26:51 +0300
commit35fcb1b3d038a501f3f4c87c05630095abaaadab (patch)
treed67f36684fb18b8523e78f13c0a358b376f50d4b /src/include
parentecd222e770d352121590363ffdf981147a43e976 (diff)
downloadpostgresql-35fcb1b3d038a501f3f4c87c05630095abaaadab.tar.gz
Allow GiST distance function to return merely a lower-bound.
The distance function can now set *recheck = false, like index quals. The executor will then re-check the ORDER BY expressions, and use a queue to reorder the results on the fly. This makes it possible to do kNN-searches on polygons and circles, which don't store the exact value in the index, but just a bounding box. Alexander Korotkov and me
Diffstat (limited to 'src/include')
-rw-r--r--src/include/access/genam.h3
-rw-r--r--src/include/access/relscan.h9
-rw-r--r--src/include/catalog/catversion.h2
-rw-r--r--src/include/catalog/pg_amop.h2
-rw-r--r--src/include/catalog/pg_amproc.h2
-rw-r--r--src/include/catalog/pg_operator.h8
-rw-r--r--src/include/catalog/pg_proc.h4
-rw-r--r--src/include/nodes/execnodes.h20
-rw-r--r--src/include/nodes/plannodes.h10
-rw-r--r--src/include/utils/geo_decls.h3
10 files changed, 58 insertions, 5 deletions
diff --git a/src/include/access/genam.h b/src/include/access/genam.h
index d86590ac11..f129c4b58f 100644
--- a/src/include/access/genam.h
+++ b/src/include/access/genam.h
@@ -147,7 +147,10 @@ extern void index_restrpos(IndexScanDesc scan);
extern ItemPointer index_getnext_tid(IndexScanDesc scan,
ScanDirection direction);
extern HeapTuple index_fetch_heap(IndexScanDesc scan);
+extern bool index_get_heap_values(IndexScanDesc scan, ItemPointer heapPtr,
+ Datum values[INDEX_MAX_KEYS], bool isnull[INDEX_MAX_KEYS]);
extern HeapTuple index_getnext(IndexScanDesc scan, ScanDirection direction);
+
extern int64 index_getbitmap(IndexScanDesc scan, TIDBitmap *bitmap);
extern IndexBulkDeleteResult *index_bulk_delete(IndexVacuumInfo *info,
diff --git a/src/include/access/relscan.h b/src/include/access/relscan.h
index 9bb63622fe..865d36403a 100644
--- a/src/include/access/relscan.h
+++ b/src/include/access/relscan.h
@@ -91,6 +91,15 @@ typedef struct IndexScanDescData
/* NB: if xs_cbuf is not InvalidBuffer, we hold a pin on that buffer */
bool xs_recheck; /* T means scan keys must be rechecked */
+ /*
+ * When fetching with an ordering operator, the values of the ORDER BY
+ * expressions of the last returned tuple, according to the index. If
+ * xs_recheck is true, these need to be rechecked just like the scan keys,
+ * and the values returned here are a lower-bound on the actual values.
+ */
+ Datum *xs_orderbyvals;
+ bool *xs_orderbynulls;
+
/* state data for traversing HOT chains in index_getnext */
bool xs_continue_hot; /* T if must keep walking HOT chain */
} IndexScanDescData;
diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h
index 09fdc364e0..b6a6da9a10 100644
--- a/src/include/catalog/catversion.h
+++ b/src/include/catalog/catversion.h
@@ -53,6 +53,6 @@
*/
/* yyyymmddN */
-#define CATALOG_VERSION_NO 201505141
+#define CATALOG_VERSION_NO 201505151
#endif
diff --git a/src/include/catalog/pg_amop.h b/src/include/catalog/pg_amop.h
index 5aab896786..9b8294fd94 100644
--- a/src/include/catalog/pg_amop.h
+++ b/src/include/catalog/pg_amop.h
@@ -650,6 +650,7 @@ DATA(insert ( 2594 604 604 11 s 2577 783 0 ));
DATA(insert ( 2594 604 604 12 s 2576 783 0 ));
DATA(insert ( 2594 604 604 13 s 2861 783 0 ));
DATA(insert ( 2594 604 604 14 s 2860 783 0 ));
+DATA(insert ( 2594 604 600 15 o 3289 783 1970 ));
/*
* gist circle_ops
@@ -669,6 +670,7 @@ DATA(insert ( 2595 718 718 11 s 1514 783 0 ));
DATA(insert ( 2595 718 718 12 s 2590 783 0 ));
DATA(insert ( 2595 718 718 13 s 2865 783 0 ));
DATA(insert ( 2595 718 718 14 s 2864 783 0 ));
+DATA(insert ( 2595 718 600 15 o 3291 783 1970 ));
/*
* gin array_ops (these anyarray operators are used with all the opclasses
diff --git a/src/include/catalog/pg_amproc.h b/src/include/catalog/pg_amproc.h
index e3de3b57e7..3111d6f4ad 100644
--- a/src/include/catalog/pg_amproc.h
+++ b/src/include/catalog/pg_amproc.h
@@ -208,6 +208,7 @@ DATA(insert ( 2594 604 604 4 2580 ));
DATA(insert ( 2594 604 604 5 2581 ));
DATA(insert ( 2594 604 604 6 2582 ));
DATA(insert ( 2594 604 604 7 2584 ));
+DATA(insert ( 2594 604 604 8 3288 ));
DATA(insert ( 2595 718 718 1 2591 ));
DATA(insert ( 2595 718 718 2 2583 ));
DATA(insert ( 2595 718 718 3 2592 ));
@@ -215,6 +216,7 @@ DATA(insert ( 2595 718 718 4 2580 ));
DATA(insert ( 2595 718 718 5 2581 ));
DATA(insert ( 2595 718 718 6 2582 ));
DATA(insert ( 2595 718 718 7 2584 ));
+DATA(insert ( 2595 718 718 8 3288 ));
DATA(insert ( 3655 3614 3614 1 3654 ));
DATA(insert ( 3655 3614 3614 2 3651 ));
DATA(insert ( 3655 3614 3614 3 3648 ));
diff --git a/src/include/catalog/pg_operator.h b/src/include/catalog/pg_operator.h
index 34ebb50ea5..6e260cb304 100644
--- a/src/include/catalog/pg_operator.h
+++ b/src/include/catalog/pg_operator.h
@@ -1015,9 +1015,13 @@ DATA(insert OID = 1520 ( "<->" PGNSP PGUID b f f 718 718 701 1520 0 ci
DESCR("distance between");
DATA(insert OID = 1521 ( "#" PGNSP PGUID l f f 0 604 23 0 0 poly_npoints - - ));
DESCR("number of points");
-DATA(insert OID = 1522 ( "<->" PGNSP PGUID b f f 600 718 701 0 0 dist_pc - - ));
+DATA(insert OID = 1522 ( "<->" PGNSP PGUID b f f 600 718 701 3291 0 dist_pc - - ));
DESCR("distance between");
-DATA(insert OID = 3276 ( "<->" PGNSP PGUID b f f 600 604 701 0 0 dist_ppoly - - ));
+DATA(insert OID = 3291 ( "<->" PGNSP PGUID b f f 718 600 701 1522 0 dist_cpoint - - ));
+DESCR("distance between");
+DATA(insert OID = 3276 ( "<->" PGNSP PGUID b f f 600 604 701 3289 0 dist_ppoly - - ));
+DESCR("distance between");
+DATA(insert OID = 3289 ( "<->" PGNSP PGUID b f f 604 600 701 3276 0 dist_polyp - - ));
DESCR("distance between");
DATA(insert OID = 1523 ( "<->" PGNSP PGUID b f f 718 604 701 0 0 dist_cpoly - - ));
DESCR("distance between");
diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h
index d4bc60b7d6..1c9edbc3b3 100644
--- a/src/include/catalog/pg_proc.h
+++ b/src/include/catalog/pg_proc.h
@@ -856,6 +856,8 @@ DATA(insert OID = 727 ( dist_sl PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 70
DATA(insert OID = 728 ( dist_cpoly PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 701 "718 604" _null_ _null_ _null_ _null_ _null_ dist_cpoly _null_ _null_ _null_ ));
DATA(insert OID = 729 ( poly_distance PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 701 "604 604" _null_ _null_ _null_ _null_ _null_ poly_distance _null_ _null_ _null_ ));
DATA(insert OID = 3275 ( dist_ppoly PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 701 "600 604" _null_ _null_ _null_ _null_ _null_ dist_ppoly _null_ _null_ _null_ ));
+DATA(insert OID = 3292 ( dist_polyp PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 701 "604 600" _null_ _null_ _null_ _null_ _null_ dist_polyp _null_ _null_ _null_ ));
+DATA(insert OID = 3290 ( dist_cpoint PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 701 "718 600" _null_ _null_ _null_ _null_ _null_ dist_cpoint _null_ _null_ _null_ ));
DATA(insert OID = 740 ( text_lt PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "25 25" _null_ _null_ _null_ _null_ _null_ text_lt _null_ _null_ _null_ ));
DATA(insert OID = 741 ( text_le PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 16 "25 25" _null_ _null_ _null_ _null_ _null_ text_le _null_ _null_ _null_ ));
@@ -4165,6 +4167,8 @@ DATA(insert OID = 2179 ( gist_point_consistent PGNSP PGUID 12 1 0 0 0 f f f f t
DESCR("GiST support");
DATA(insert OID = 3064 ( gist_point_distance PGNSP PGUID 12 1 0 0 0 f f f f t f i 4 0 701 "2281 600 23 26" _null_ _null_ _null_ _null_ _null_ gist_point_distance _null_ _null_ _null_ ));
DESCR("GiST support");
+DATA(insert OID = 3288 ( gist_bbox_distance PGNSP PGUID 12 1 0 0 0 f f f f t f i 4 0 701 "2281 600 23 26" _null_ _null_ _null_ _null_ _null_ gist_bbox_distance _null_ _null_ _null_ ));
+DESCR("GiST support");
/* GIN */
DATA(insert OID = 2731 ( gingetbitmap PGNSP PGUID 12 1 0 0 0 f f f f t f v 2 0 20 "2281 2281" _null_ _null_ _null_ _null_ _null_ gingetbitmap _null_ _null_ _null_ ));
diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h
index 5ad2cc2358..fcfe1107f9 100644
--- a/src/include/nodes/execnodes.h
+++ b/src/include/nodes/execnodes.h
@@ -17,6 +17,7 @@
#include "access/genam.h"
#include "access/heapam.h"
#include "executor/instrument.h"
+#include "lib/pairingheap.h"
#include "nodes/params.h"
#include "nodes/plannodes.h"
#include "utils/reltrigger.h"
@@ -1262,6 +1263,7 @@ typedef struct
* IndexScanState information
*
* indexqualorig execution state for indexqualorig expressions
+ * indexorderbyorig execution state for indexorderbyorig expressions
* ScanKeys Skey structures for index quals
* NumScanKeys number of ScanKeys
* OrderByKeys Skey structures for index ordering operators
@@ -1272,12 +1274,21 @@ typedef struct
* RuntimeContext expr context for evaling runtime Skeys
* RelationDesc index relation descriptor
* ScanDesc index scan descriptor
+ *
+ * ReorderQueue tuples that need reordering due to re-check
+ * ReachedEnd have we fetched all tuples from index already?
+ * OrderByValues values of ORDER BY exprs of last fetched tuple
+ * OrderByNulls null flags for OrderByValues
+ * SortSupport for reordering ORDER BY exprs
+ * OrderByTypByVals is the datatype of order by expression pass-by-value?
+ * OrderByTypLens typlens of the datatypes of order by expressions
* ----------------
*/
typedef struct IndexScanState
{
ScanState ss; /* its first field is NodeTag */
List *indexqualorig;
+ List *indexorderbyorig;
ScanKey iss_ScanKeys;
int iss_NumScanKeys;
ScanKey iss_OrderByKeys;
@@ -1288,6 +1299,15 @@ typedef struct IndexScanState
ExprContext *iss_RuntimeContext;
Relation iss_RelationDesc;
IndexScanDesc iss_ScanDesc;
+
+ /* These are needed for re-checking ORDER BY expr ordering */
+ pairingheap *iss_ReorderQueue;
+ bool iss_ReachedEnd;
+ Datum *iss_OrderByValues;
+ bool *iss_OrderByNulls;
+ SortSupport iss_SortSupport;
+ bool *iss_OrderByTypByVals;
+ int16 *iss_OrderByTypLens;
} IndexScanState;
/* ----------------
diff --git a/src/include/nodes/plannodes.h b/src/include/nodes/plannodes.h
index 1494b336c2..65f71d8170 100644
--- a/src/include/nodes/plannodes.h
+++ b/src/include/nodes/plannodes.h
@@ -311,8 +311,13 @@ typedef Scan SeqScan;
* index column order. Only the expressions are provided, not the auxiliary
* sort-order information from the ORDER BY SortGroupClauses; it's assumed
* that the sort ordering is fully determinable from the top-level operators.
- * indexorderbyorig is unused at run time, but is needed for EXPLAIN.
- * (Note these fields are used for amcanorderbyop cases, not amcanorder cases.)
+ * indexorderbyorig is used at runtime to recheck the ordering, if the index
+ * cannot calculate an accurate ordering. It is also needed for EXPLAIN.
+ *
+ * indexorderbyops is an array of operators used to sort the ORDER BY
+ * expressions, used together with indexorderbyorig to recheck ordering at run
+ * time. (Note these fields are used for amcanorderbyop cases, not amcanorder
+ * cases.)
*
* indexorderdir specifies the scan ordering, for indexscans on amcanorder
* indexes (for other indexes it should be "don't care").
@@ -326,6 +331,7 @@ typedef struct IndexScan
List *indexqualorig; /* the same in original form */
List *indexorderby; /* list of index ORDER BY exprs */
List *indexorderbyorig; /* the same in original form */
+ Oid *indexorderbyops; /* operators to sort ORDER BY exprs */
ScanDirection indexorderdir; /* forward or backward or don't care */
} IndexScan;
diff --git a/src/include/utils/geo_decls.h b/src/include/utils/geo_decls.h
index 4377baa645..2311d35dd7 100644
--- a/src/include/utils/geo_decls.h
+++ b/src/include/utils/geo_decls.h
@@ -394,8 +394,10 @@ extern Datum circle_diameter(PG_FUNCTION_ARGS);
extern Datum circle_radius(PG_FUNCTION_ARGS);
extern Datum circle_distance(PG_FUNCTION_ARGS);
extern Datum dist_pc(PG_FUNCTION_ARGS);
+extern Datum dist_cpoint(PG_FUNCTION_ARGS);
extern Datum dist_cpoly(PG_FUNCTION_ARGS);
extern Datum dist_ppoly(PG_FUNCTION_ARGS);
+extern Datum dist_polyp(PG_FUNCTION_ARGS);
extern Datum circle_center(PG_FUNCTION_ARGS);
extern Datum cr_circle(PG_FUNCTION_ARGS);
extern Datum box_circle(PG_FUNCTION_ARGS);
@@ -420,6 +422,7 @@ extern Datum gist_circle_consistent(PG_FUNCTION_ARGS);
extern Datum gist_point_compress(PG_FUNCTION_ARGS);
extern Datum gist_point_consistent(PG_FUNCTION_ARGS);
extern Datum gist_point_distance(PG_FUNCTION_ARGS);
+extern Datum gist_bbox_distance(PG_FUNCTION_ARGS);
extern Datum gist_point_fetch(PG_FUNCTION_ARGS);