1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-27 12:41:57 +03:00

llow negative coordinate for ~> (cube, int) operator

~> (cube, int) operator was especially designed for knn-gist search.
However, knn-gist supports only ascending ordering of results. Nevertheless
it would be useful to support descending ordering by ~> (cube, int) operator.
We provide workaround for that: negative coordinate give us inversed value
of corresponding cube bound. Therefore, knn search using negative coordinate
gives us an effect of descending ordering by cube bound.

Author: Alexander Korotkov
Reviewed by: Tomas Vondra, Andrey Borodin
Discussion: https://www.postgresql.org/message-id/flat/a9657f6a-b497-36ff-e56-482a2c7e3292@2ndquadrant.com
This commit is contained in:
Teodor Sigaev
2018-01-11 14:49:36 +03:00
parent 563a053bdd
commit f50c80dbb1
5 changed files with 379 additions and 14 deletions

View File

@ -1554,7 +1554,7 @@ SELECT cube(array[40,50,60], array[10,20,30])~>3;
(1 row)
SELECT cube(array[40,50,60], array[10,20,30])~>0;
ERROR: cube index 0 is out of bounds
ERROR: zero cube index is not defined
SELECT cube(array[40,50,60], array[10,20,30])~>4;
?column?
----------
@ -1562,7 +1562,11 @@ SELECT cube(array[40,50,60], array[10,20,30])~>4;
(1 row)
SELECT cube(array[40,50,60], array[10,20,30])~>(-1);
ERROR: cube index -1 is out of bounds
?column?
----------
-10
(1 row)
-- Load some example data and build the index
--
CREATE TABLE test_cube (c cube);
@ -1726,6 +1730,86 @@ SELECT c~>4, c FROM test_cube ORDER BY c~>4 LIMIT 15; -- ascending by upper boun
266 | (22684, 266),(22656, 181)
(15 rows)
SELECT c~>(-1), c FROM test_cube ORDER BY c~>(-1) LIMIT 15; -- descending by left bound
?column? | c
----------+-------------------------------
-100000 | (100000)
-49951 | (50027, 49230),(49951, 49214)
-49937 | (49980, 35004),(49937, 34963)
-49927 | (49985, 6436),(49927, 6338)
-49908 | (49999, 27218),(49908, 27176)
-49905 | (49954, 1340),(49905, 1294)
-49902 | (49944, 25163),(49902, 25153)
-49898 | (49981, 34876),(49898, 34786)
-49897 | (49957, 43390),(49897, 43384)
-49848 | (49853, 18504),(49848, 18503)
-49818 | (49902, 41752),(49818, 41746)
-49810 | (49907, 30225),(49810, 30158)
-49808 | (49843, 5175),(49808, 5145)
-49805 | (49887, 24274),(49805, 24184)
-49798 | (49847, 7128),(49798, 7067)
(15 rows)
SELECT c~>(-2), c FROM test_cube ORDER BY c~>(-2) LIMIT 15; -- descending by right bound
?column? | c
----------+-------------------------------
-100000 | (100000)
-50027 | (50027, 49230),(49951, 49214)
-49999 | (49999, 27218),(49908, 27176)
-49985 | (49985, 6436),(49927, 6338)
-49981 | (49981, 34876),(49898, 34786)
-49980 | (49980, 35004),(49937, 34963)
-49957 | (49957, 43390),(49897, 43384)
-49954 | (49954, 1340),(49905, 1294)
-49944 | (49944, 25163),(49902, 25153)
-49907 | (49907, 30225),(49810, 30158)
-49902 | (49902, 41752),(49818, 41746)
-49887 | (49887, 24274),(49805, 24184)
-49853 | (49853, 18504),(49848, 18503)
-49847 | (49847, 7128),(49798, 7067)
-49843 | (49843, 5175),(49808, 5145)
(15 rows)
SELECT c~>(-3), c FROM test_cube ORDER BY c~>(-3) LIMIT 15; -- descending by lower bound
?column? | c
----------+-------------------------------
-100000 | (0, 100000)
-49992 | (30746, 50040),(30727, 49992)
-49987 | (36311, 50073),(36258, 49987)
-49934 | (3531, 49962),(3463, 49934)
-49915 | (17954, 49975),(17865, 49915)
-49914 | (2168, 50012),(2108, 49914)
-49913 | (31287, 49923),(31236, 49913)
-49885 | (21551, 49983),(21492, 49885)
-49878 | (43925, 49912),(43888, 49878)
-49849 | (19128, 49932),(19112, 49849)
-49844 | (38266, 49852),(38233, 49844)
-49836 | (14913, 49873),(14849, 49836)
-49834 | (37595, 49849),(37581, 49834)
-49830 | (46151, 49848),(46058, 49830)
-49818 | (29261, 49910),(29247, 49818)
(15 rows)
SELECT c~>(-4), c FROM test_cube ORDER BY c~>(-4) LIMIT 15; -- descending by upper bound
?column? | c
----------+-------------------------------
-100000 | (0, 100000)
-50073 | (36311, 50073),(36258, 49987)
-50040 | (30746, 50040),(30727, 49992)
-50012 | (2168, 50012),(2108, 49914)
-49983 | (21551, 49983),(21492, 49885)
-49975 | (17954, 49975),(17865, 49915)
-49962 | (3531, 49962),(3463, 49934)
-49932 | (19128, 49932),(19112, 49849)
-49923 | (31287, 49923),(31236, 49913)
-49912 | (43925, 49912),(43888, 49878)
-49910 | (29261, 49910),(29247, 49818)
-49873 | (14913, 49873),(14849, 49836)
-49858 | (20007, 49858),(19921, 49778)
-49852 | (38266, 49852),(38233, 49844)
-49849 | (37595, 49849),(37581, 49834)
(15 rows)
-- Same queries with sequential scan (should give the same results as above)
RESET enable_seqscan;
SET enable_indexscan = OFF;
@ -1839,4 +1923,84 @@ SELECT c~>4, c FROM test_cube ORDER BY c~>4 LIMIT 15; -- ascending by upper boun
266 | (22684, 266),(22656, 181)
(15 rows)
SELECT c~>(-1), c FROM test_cube ORDER BY c~>(-1) LIMIT 15; -- descending by left bound
?column? | c
----------+-------------------------------
-100000 | (100000)
-49951 | (50027, 49230),(49951, 49214)
-49937 | (49980, 35004),(49937, 34963)
-49927 | (49985, 6436),(49927, 6338)
-49908 | (49999, 27218),(49908, 27176)
-49905 | (49954, 1340),(49905, 1294)
-49902 | (49944, 25163),(49902, 25153)
-49898 | (49981, 34876),(49898, 34786)
-49897 | (49957, 43390),(49897, 43384)
-49848 | (49853, 18504),(49848, 18503)
-49818 | (49902, 41752),(49818, 41746)
-49810 | (49907, 30225),(49810, 30158)
-49808 | (49843, 5175),(49808, 5145)
-49805 | (49887, 24274),(49805, 24184)
-49798 | (49847, 7128),(49798, 7067)
(15 rows)
SELECT c~>(-2), c FROM test_cube ORDER BY c~>(-2) LIMIT 15; -- descending by right bound
?column? | c
----------+-------------------------------
-100000 | (100000)
-50027 | (50027, 49230),(49951, 49214)
-49999 | (49999, 27218),(49908, 27176)
-49985 | (49985, 6436),(49927, 6338)
-49981 | (49981, 34876),(49898, 34786)
-49980 | (49980, 35004),(49937, 34963)
-49957 | (49957, 43390),(49897, 43384)
-49954 | (49954, 1340),(49905, 1294)
-49944 | (49944, 25163),(49902, 25153)
-49907 | (49907, 30225),(49810, 30158)
-49902 | (49902, 41752),(49818, 41746)
-49887 | (49887, 24274),(49805, 24184)
-49853 | (49853, 18504),(49848, 18503)
-49847 | (49847, 7128),(49798, 7067)
-49843 | (49843, 5175),(49808, 5145)
(15 rows)
SELECT c~>(-3), c FROM test_cube ORDER BY c~>(-3) LIMIT 15; -- descending by lower bound
?column? | c
----------+-------------------------------
-100000 | (0, 100000)
-49992 | (30746, 50040),(30727, 49992)
-49987 | (36311, 50073),(36258, 49987)
-49934 | (3531, 49962),(3463, 49934)
-49915 | (17954, 49975),(17865, 49915)
-49914 | (2168, 50012),(2108, 49914)
-49913 | (31287, 49923),(31236, 49913)
-49885 | (21551, 49983),(21492, 49885)
-49878 | (43925, 49912),(43888, 49878)
-49849 | (19128, 49932),(19112, 49849)
-49844 | (38266, 49852),(38233, 49844)
-49836 | (14913, 49873),(14849, 49836)
-49834 | (37595, 49849),(37581, 49834)
-49830 | (46151, 49848),(46058, 49830)
-49818 | (29261, 49910),(29247, 49818)
(15 rows)
SELECT c~>(-4), c FROM test_cube ORDER BY c~>(-4) LIMIT 15; -- descending by upper bound
?column? | c
----------+-------------------------------
-100000 | (0, 100000)
-50073 | (36311, 50073),(36258, 49987)
-50040 | (30746, 50040),(30727, 49992)
-50012 | (2168, 50012),(2108, 49914)
-49983 | (21551, 49983),(21492, 49885)
-49975 | (17954, 49975),(17865, 49915)
-49962 | (3531, 49962),(3463, 49934)
-49932 | (19128, 49932),(19112, 49849)
-49923 | (31287, 49923),(31236, 49913)
-49912 | (43925, 49912),(43888, 49878)
-49910 | (29261, 49910),(29247, 49818)
-49873 | (14913, 49873),(14849, 49836)
-49858 | (20007, 49858),(19921, 49778)
-49852 | (38266, 49852),(38233, 49844)
-49849 | (37595, 49849),(37581, 49834)
(15 rows)
RESET enable_indexscan;

View File

@ -1554,7 +1554,7 @@ SELECT cube(array[40,50,60], array[10,20,30])~>3;
(1 row)
SELECT cube(array[40,50,60], array[10,20,30])~>0;
ERROR: cube index 0 is out of bounds
ERROR: zero cube index is not defined
SELECT cube(array[40,50,60], array[10,20,30])~>4;
?column?
----------
@ -1562,7 +1562,11 @@ SELECT cube(array[40,50,60], array[10,20,30])~>4;
(1 row)
SELECT cube(array[40,50,60], array[10,20,30])~>(-1);
ERROR: cube index -1 is out of bounds
?column?
----------
-10
(1 row)
-- Load some example data and build the index
--
CREATE TABLE test_cube (c cube);
@ -1726,6 +1730,86 @@ SELECT c~>4, c FROM test_cube ORDER BY c~>4 LIMIT 15; -- ascending by upper boun
266 | (22684, 266),(22656, 181)
(15 rows)
SELECT c~>(-1), c FROM test_cube ORDER BY c~>(-1) LIMIT 15; -- descending by left bound
?column? | c
----------+-------------------------------
-100000 | (100000)
-49951 | (50027, 49230),(49951, 49214)
-49937 | (49980, 35004),(49937, 34963)
-49927 | (49985, 6436),(49927, 6338)
-49908 | (49999, 27218),(49908, 27176)
-49905 | (49954, 1340),(49905, 1294)
-49902 | (49944, 25163),(49902, 25153)
-49898 | (49981, 34876),(49898, 34786)
-49897 | (49957, 43390),(49897, 43384)
-49848 | (49853, 18504),(49848, 18503)
-49818 | (49902, 41752),(49818, 41746)
-49810 | (49907, 30225),(49810, 30158)
-49808 | (49843, 5175),(49808, 5145)
-49805 | (49887, 24274),(49805, 24184)
-49798 | (49847, 7128),(49798, 7067)
(15 rows)
SELECT c~>(-2), c FROM test_cube ORDER BY c~>(-2) LIMIT 15; -- descending by right bound
?column? | c
----------+-------------------------------
-100000 | (100000)
-50027 | (50027, 49230),(49951, 49214)
-49999 | (49999, 27218),(49908, 27176)
-49985 | (49985, 6436),(49927, 6338)
-49981 | (49981, 34876),(49898, 34786)
-49980 | (49980, 35004),(49937, 34963)
-49957 | (49957, 43390),(49897, 43384)
-49954 | (49954, 1340),(49905, 1294)
-49944 | (49944, 25163),(49902, 25153)
-49907 | (49907, 30225),(49810, 30158)
-49902 | (49902, 41752),(49818, 41746)
-49887 | (49887, 24274),(49805, 24184)
-49853 | (49853, 18504),(49848, 18503)
-49847 | (49847, 7128),(49798, 7067)
-49843 | (49843, 5175),(49808, 5145)
(15 rows)
SELECT c~>(-3), c FROM test_cube ORDER BY c~>(-3) LIMIT 15; -- descending by lower bound
?column? | c
----------+-------------------------------
-100000 | (0, 100000)
-49992 | (30746, 50040),(30727, 49992)
-49987 | (36311, 50073),(36258, 49987)
-49934 | (3531, 49962),(3463, 49934)
-49915 | (17954, 49975),(17865, 49915)
-49914 | (2168, 50012),(2108, 49914)
-49913 | (31287, 49923),(31236, 49913)
-49885 | (21551, 49983),(21492, 49885)
-49878 | (43925, 49912),(43888, 49878)
-49849 | (19128, 49932),(19112, 49849)
-49844 | (38266, 49852),(38233, 49844)
-49836 | (14913, 49873),(14849, 49836)
-49834 | (37595, 49849),(37581, 49834)
-49830 | (46151, 49848),(46058, 49830)
-49818 | (29261, 49910),(29247, 49818)
(15 rows)
SELECT c~>(-4), c FROM test_cube ORDER BY c~>(-4) LIMIT 15; -- descending by upper bound
?column? | c
----------+-------------------------------
-100000 | (0, 100000)
-50073 | (36311, 50073),(36258, 49987)
-50040 | (30746, 50040),(30727, 49992)
-50012 | (2168, 50012),(2108, 49914)
-49983 | (21551, 49983),(21492, 49885)
-49975 | (17954, 49975),(17865, 49915)
-49962 | (3531, 49962),(3463, 49934)
-49932 | (19128, 49932),(19112, 49849)
-49923 | (31287, 49923),(31236, 49913)
-49912 | (43925, 49912),(43888, 49878)
-49910 | (29261, 49910),(29247, 49818)
-49873 | (14913, 49873),(14849, 49836)
-49858 | (20007, 49858),(19921, 49778)
-49852 | (38266, 49852),(38233, 49844)
-49849 | (37595, 49849),(37581, 49834)
(15 rows)
-- Same queries with sequential scan (should give the same results as above)
RESET enable_seqscan;
SET enable_indexscan = OFF;
@ -1839,4 +1923,84 @@ SELECT c~>4, c FROM test_cube ORDER BY c~>4 LIMIT 15; -- ascending by upper boun
266 | (22684, 266),(22656, 181)
(15 rows)
SELECT c~>(-1), c FROM test_cube ORDER BY c~>(-1) LIMIT 15; -- descending by left bound
?column? | c
----------+-------------------------------
-100000 | (100000)
-49951 | (50027, 49230),(49951, 49214)
-49937 | (49980, 35004),(49937, 34963)
-49927 | (49985, 6436),(49927, 6338)
-49908 | (49999, 27218),(49908, 27176)
-49905 | (49954, 1340),(49905, 1294)
-49902 | (49944, 25163),(49902, 25153)
-49898 | (49981, 34876),(49898, 34786)
-49897 | (49957, 43390),(49897, 43384)
-49848 | (49853, 18504),(49848, 18503)
-49818 | (49902, 41752),(49818, 41746)
-49810 | (49907, 30225),(49810, 30158)
-49808 | (49843, 5175),(49808, 5145)
-49805 | (49887, 24274),(49805, 24184)
-49798 | (49847, 7128),(49798, 7067)
(15 rows)
SELECT c~>(-2), c FROM test_cube ORDER BY c~>(-2) LIMIT 15; -- descending by right bound
?column? | c
----------+-------------------------------
-100000 | (100000)
-50027 | (50027, 49230),(49951, 49214)
-49999 | (49999, 27218),(49908, 27176)
-49985 | (49985, 6436),(49927, 6338)
-49981 | (49981, 34876),(49898, 34786)
-49980 | (49980, 35004),(49937, 34963)
-49957 | (49957, 43390),(49897, 43384)
-49954 | (49954, 1340),(49905, 1294)
-49944 | (49944, 25163),(49902, 25153)
-49907 | (49907, 30225),(49810, 30158)
-49902 | (49902, 41752),(49818, 41746)
-49887 | (49887, 24274),(49805, 24184)
-49853 | (49853, 18504),(49848, 18503)
-49847 | (49847, 7128),(49798, 7067)
-49843 | (49843, 5175),(49808, 5145)
(15 rows)
SELECT c~>(-3), c FROM test_cube ORDER BY c~>(-3) LIMIT 15; -- descending by lower bound
?column? | c
----------+-------------------------------
-100000 | (0, 100000)
-49992 | (30746, 50040),(30727, 49992)
-49987 | (36311, 50073),(36258, 49987)
-49934 | (3531, 49962),(3463, 49934)
-49915 | (17954, 49975),(17865, 49915)
-49914 | (2168, 50012),(2108, 49914)
-49913 | (31287, 49923),(31236, 49913)
-49885 | (21551, 49983),(21492, 49885)
-49878 | (43925, 49912),(43888, 49878)
-49849 | (19128, 49932),(19112, 49849)
-49844 | (38266, 49852),(38233, 49844)
-49836 | (14913, 49873),(14849, 49836)
-49834 | (37595, 49849),(37581, 49834)
-49830 | (46151, 49848),(46058, 49830)
-49818 | (29261, 49910),(29247, 49818)
(15 rows)
SELECT c~>(-4), c FROM test_cube ORDER BY c~>(-4) LIMIT 15; -- descending by upper bound
?column? | c
----------+-------------------------------
-100000 | (0, 100000)
-50073 | (36311, 50073),(36258, 49987)
-50040 | (30746, 50040),(30727, 49992)
-50012 | (2168, 50012),(2108, 49914)
-49983 | (21551, 49983),(21492, 49885)
-49975 | (17954, 49975),(17865, 49915)
-49962 | (3531, 49962),(3463, 49934)
-49932 | (19128, 49932),(19112, 49849)
-49923 | (31287, 49923),(31236, 49913)
-49912 | (43925, 49912),(43888, 49878)
-49910 | (29261, 49910),(29247, 49818)
-49873 | (14913, 49873),(14849, 49836)
-49858 | (20007, 49858),(19921, 49778)
-49852 | (38266, 49852),(38233, 49844)
-49849 | (37595, 49849),(37581, 49834)
(15 rows)
RESET enable_indexscan;