diff --git a/contrib/cube/cube.c b/contrib/cube/cube.c
new file mode 100644
index b770271..d2d67d9
*** a/contrib/cube/cube.c
--- b/contrib/cube/cube.c
*************** g_cube_distance(PG_FUNCTION_ARGS)
*** 1337,1351 ****
  
  	if (strategy == CubeKNNDistanceCoord)
  	{
  		int			coord = PG_GETARG_INT32(1);
  
! 		if (DIM(cube) == 0)
! 			retval = 0.0;
! 		else if (IS_POINT(cube))
! 			retval = cube->x[(coord - 1) % DIM(cube)];
  		else
! 			retval = Min(cube->x[(coord - 1) % DIM(cube)],
! 						 cube->x[(coord - 1) % DIM(cube) + DIM(cube)]);
  	}
  	else
  	{
--- 1337,1402 ----
  
  	if (strategy == CubeKNNDistanceCoord)
  	{
+ 		/*
+ 		 * Handle ordering by ~> operator.  See comments of cube_coord_llur()
+ 		 * for details
+ 		 */
  		int			coord = PG_GETARG_INT32(1);
+ 		bool		isLeaf = GistPageIsLeaf(entry->page);
+ 		bool		inverse = false;
  
! 		/* Return inversed value for negative coordinate */
! 		if (coord < 0)
! 		{
! 			coord = -coord;
! 			inverse = true;
! 		}
! 
! 		if (coord <= 2 * DIM(cube))
! 		{
! 			/* dimension index */
! 			int		index = (coord - 1) / 2;
! 			/* whether this is upper bound (lower bound otherwise) */
! 			bool	upper = ((coord - 1) % 2 == 1);
! 
! 			if (IS_POINT(cube))
! 			{
! 				retval = cube->x[index];
! 			}
! 			else
! 			{
! 				if (isLeaf)
! 				{
! 					/* For leaf just return required upper/lower bound */
! 					if (upper)
! 						retval = Max(cube->x[index], cube->x[index + DIM(cube)]);
! 					else
! 						retval = Min(cube->x[index], cube->x[index + DIM(cube)]);
! 				}
! 				else
! 				{
! 					/*
! 					 * For non-leaf we should always return lower bound,
! 					 * because even upper bound of a child in the subtree can
! 					 * be as small as our lower bound.  For inversed case we
! 					 * return upper bound because it becomes lower bound for
! 					 * inversed value.
! 					 */
! 					if (!inverse)
! 						retval = Min(cube->x[index], cube->x[index + DIM(cube)]);
! 					else
! 						retval = Max(cube->x[index], cube->x[index + DIM(cube)]);
! 				}
! 			}
! 		}
  		else
! 		{
! 			retval = 0.0;
! 		}
! 
! 		/* Inverse return value if needed */
! 		if (inverse)
! 			retval = -retval;
  	}
  	else
  	{
*************** cube_coord(PG_FUNCTION_ARGS)
*** 1492,1534 ****
  }
  
  
! /*
!  * This function works like cube_coord(),
!  * but rearranges coordinates of corners to get cube representation
!  * in the form of (lower left, upper right).
!  * For historical reasons that extension allows us to create cubes in form
!  * ((2,1),(1,2)) and instead of normalizing such cube to ((1,1),(2,2)) it
!  * stores cube in original way. But to get cubes ordered by one of dimensions
!  * directly from the index without extra sort step we need some
!  * representation-independent coordinate getter. This function implements it.
   */
  Datum
  cube_coord_llur(PG_FUNCTION_ARGS)
  {
  	NDBOX	   *cube = PG_GETARG_NDBOX_P(0);
  	int			coord = PG_GETARG_INT32(1);
  
! 	if (coord <= 0 || coord > 2 * DIM(cube))
  		ereport(ERROR,
  				(errcode(ERRCODE_ARRAY_ELEMENT_ERROR),
! 				 errmsg("cube index %d is out of bounds", coord)));
  
! 	if (coord <= DIM(cube))
  	{
  		if (IS_POINT(cube))
! 			PG_RETURN_FLOAT8(cube->x[coord - 1]);
  		else
! 			PG_RETURN_FLOAT8(Min(cube->x[coord - 1],
! 								 cube->x[coord - 1 + DIM(cube)]));
  	}
  	else
  	{
! 		if (IS_POINT(cube))
! 			PG_RETURN_FLOAT8(cube->x[(coord - 1) % DIM(cube)]);
! 		else
! 			PG_RETURN_FLOAT8(Max(cube->x[coord - 1],
! 								 cube->x[coord - 1 - DIM(cube)]));
  	}
  }
  
  /* Increase or decrease box size by a radius in at least n dimensions. */
--- 1543,1625 ----
  }
  
  
! /*----
!  * This function works like cube_coord(), but rearranges coordinates in the
!  * way suitable to support coordinate ordering using KNN-GiST.  For historical
!  * reasons this extension allows us to create cubes in form ((2,1),(1,2)) and
!  * instead of normalizing such cube to ((1,1),(2,2)) it stores cube in original
!  * way.  But in order to get cubes ordered by one of dimensions from the index
!  * without explicit sort step we need this representation-independent coordinate
!  * getter.  Moreover, indexed dataset may contain cubes of different dimensions
!  * number.  Accordingly, this corrdinate getter should be able to return
!  * lower/upper bound for particular dimension independently on number of cube
!  * dimenstions.  Also, KNN-GiST supports only ascending sorting.  In order to
!  * support descinding sorting, this function returns inverse of value when
!  * negative coordinate is given.
!  *
!  * Long stoty short, this function uses following meaning of coordinates:
!  * # (2 * N - 1) -- lower bound of Nth dimension,
!  * # (2 * N) -- upper bound of Nth dimenstion,
!  * # - (2 * N - 1) -- negative of lower bound of Nth dimension,
!  * # - (2 * N) -- negative of upper bound of Nth dimenstion.
!  *
!  * When given coordinate exceeds number of cube dimensions, then 0 returned
!  * (reproducing logic of GiST indexing of variable-length cubes).
   */
  Datum
  cube_coord_llur(PG_FUNCTION_ARGS)
  {
  	NDBOX	   *cube = PG_GETARG_NDBOX_P(0);
  	int			coord = PG_GETARG_INT32(1);
+ 	bool		inverse = false;
+ 	float8		result;
  
! 	/* 0 is the only unsupported coordinate value */
! 	if (coord == 0)
  		ereport(ERROR,
  				(errcode(ERRCODE_ARRAY_ELEMENT_ERROR),
! 				 errmsg("zero cube index is not defined")));
  
! 	/* Return inversed value for negative coordinate */
! 	if (coord < 0)
  	{
+ 		coord = -coord;
+ 		inverse = true;
+ 	}
+ 
+ 	if (coord <= 2 * DIM(cube))
+ 	{
+ 		/* dimension index */
+ 		int		index = (coord - 1) / 2;
+ 		/* whether this is upper bound (lower bound otherwise) */
+ 		bool	upper = ((coord - 1) % 2 == 1);
+ 
  		if (IS_POINT(cube))
! 		{
! 			result = cube->x[index];
! 		}
  		else
! 		{
! 			if (upper)
! 				result = Max(cube->x[index], cube->x[index + DIM(cube)]);
! 			else
! 				result = Min(cube->x[index], cube->x[index + DIM(cube)]);
! 		}
  	}
  	else
  	{
! 		/*
! 		 * Return zero if coordinate is out of bound.  That reproduces logic of
! 		 * how cubes with low dimension number are expanded duing GiST indexing.
! 		 */
! 		result = 0.0;
  	}
+ 
+ 	/* Inverse value if needed */
+ 	if (inverse)
+ 		result = -result;
+ 
+ 	PG_RETURN_FLOAT8(result);
  }
  
  /* Increase or decrease box size by a radius in at least n dimensions. */
diff --git a/contrib/cube/expected/cube.out b/contrib/cube/expected/cube.out
new file mode 100644
index 328b3b5..b6a694e
*** a/contrib/cube/expected/cube.out
--- b/contrib/cube/expected/cube.out
*************** SELECT cube(array[40,50,60], array[10,20
*** 1532,1568 ****
  SELECT cube(array[10,20,30], array[40,50,60])~>2;
   ?column? 
  ----------
!        20
  (1 row)
  
  SELECT cube(array[40,50,60], array[10,20,30])~>2;
   ?column? 
  ----------
!        20
  (1 row)
  
  SELECT cube(array[10,20,30], array[40,50,60])~>3;
   ?column? 
  ----------
!        30
  (1 row)
  
  SELECT cube(array[40,50,60], array[10,20,30])~>3;
   ?column? 
  ----------
!        30
  (1 row)
  
  SELECT cube(array[40,50,60], array[10,20,30])~>0;
! ERROR:  cube index 0 is out of bounds
  SELECT cube(array[40,50,60], array[10,20,30])~>4;
   ?column? 
  ----------
!        40
  (1 row)
  
  SELECT cube(array[40,50,60], array[10,20,30])~>(-1);
! ERROR:  cube index -1 is out of bounds
  -- Load some example data and build the index
  --
  CREATE TABLE test_cube (c cube);
--- 1532,1572 ----
  SELECT cube(array[10,20,30], array[40,50,60])~>2;
   ?column? 
  ----------
!        40
  (1 row)
  
  SELECT cube(array[40,50,60], array[10,20,30])~>2;
   ?column? 
  ----------
!        40
  (1 row)
  
  SELECT cube(array[10,20,30], array[40,50,60])~>3;
   ?column? 
  ----------
!        20
  (1 row)
  
  SELECT cube(array[40,50,60], array[10,20,30])~>3;
   ?column? 
  ----------
!        20
  (1 row)
  
  SELECT cube(array[40,50,60], array[10,20,30])~>0;
! ERROR:  zero cube index is not defined
  SELECT cube(array[40,50,60], array[10,20,30])~>4;
   ?column? 
  ----------
!        50
  (1 row)
  
  SELECT cube(array[40,50,60], array[10,20,30])~>(-1);
!  ?column? 
! ----------
!       -10
! (1 row)
! 
  -- Load some example data and build the index
  --
  CREATE TABLE test_cube (c cube);
*************** SELECT * FROM test_cube WHERE c && '(300
*** 1589,1747 ****
   (2424, 160),(2424, 81)
  (5 rows)
  
! -- kNN with index
  SELECT *, c <-> '(100, 100),(500, 500)'::cube as dist FROM test_cube ORDER BY c <-> '(100, 100),(500, 500)'::cube LIMIT 5;
              c            |       dist       
  -------------------------+------------------
   (337, 455),(240, 359)   |                0
   (759, 187),(662, 163)   |              162
   (948, 1201),(907, 1156) | 772.000647668122
   (1444, 403),(1346, 344) |              846
-  (369, 1457),(278, 1409) |              909
  (5 rows)
  
  SELECT *, c <=> '(100, 100),(500, 500)'::cube as dist FROM test_cube ORDER BY c <=> '(100, 100),(500, 500)'::cube LIMIT 5;
              c            | dist 
  -------------------------+------
   (337, 455),(240, 359)   |    0
   (759, 187),(662, 163)   |  162
   (948, 1201),(907, 1156) |  656
   (1444, 403),(1346, 344) |  846
   (369, 1457),(278, 1409) |  909
  (5 rows)
  
  SELECT *, c <#> '(100, 100),(500, 500)'::cube as dist FROM test_cube ORDER BY c <#> '(100, 100),(500, 500)'::cube LIMIT 5;
              c            | dist 
  -------------------------+------
   (337, 455),(240, 359)   |    0
   (759, 187),(662, 163)   |  162
   (1444, 403),(1346, 344) |  846
   (369, 1457),(278, 1409) |  909
-  (948, 1201),(907, 1156) | 1063
  (5 rows)
  
! -- kNN-based sorting
! SELECT * FROM test_cube ORDER BY c~>1 LIMIT 15; -- ascending by 1st coordinate of lower left corner
!              c             
! ---------------------------
!  (54, 38679),(3, 38602)
!  (83, 10271),(15, 10265)
!  (122, 46832),(64, 46762)
!  (167, 17214),(92, 17184)
!  (161, 24465),(107, 24374)
!  (162, 26040),(120, 25963)
!  (154, 4019),(138, 3990)
!  (259, 1850),(175, 1820)
!  (207, 40886),(179, 40879)
!  (288, 49588),(204, 49571)
!  (270, 32616),(226, 32607)
!  (318, 31489),(235, 31404)
!  (337, 455),(240, 359)
!  (270, 29508),(264, 29440)
!  (369, 1457),(278, 1409)
  (15 rows)
  
! SELECT * FROM test_cube ORDER BY c~>4 LIMIT 15; -- ascending by 2nd coordinate or upper right corner
!              c             
! ---------------------------
!  (30333, 50),(30273, 6)
!  (43301, 75),(43227, 43)
!  (19650, 142),(19630, 51)
!  (2424, 160),(2424, 81)
!  (3449, 171),(3354, 108)
!  (18037, 155),(17941, 109)
!  (28511, 208),(28479, 114)
!  (19946, 217),(19941, 118)
!  (16906, 191),(16816, 139)
!  (759, 187),(662, 163)
!  (22684, 266),(22656, 181)
!  (24423, 255),(24360, 213)
!  (45989, 249),(45910, 222)
!  (11399, 377),(11360, 294)
!  (12162, 389),(12103, 309)
  (15 rows)
  
! SELECT * FROM test_cube ORDER BY c~>1 DESC LIMIT 15; -- descending by 1st coordinate of lower left corner
!                c               
! -------------------------------
!  (50027, 49230),(49951, 49214)
!  (49980, 35004),(49937, 34963)
!  (49985, 6436),(49927, 6338)
!  (49999, 27218),(49908, 27176)
!  (49954, 1340),(49905, 1294)
!  (49944, 25163),(49902, 25153)
!  (49981, 34876),(49898, 34786)
!  (49957, 43390),(49897, 43384)
!  (49853, 18504),(49848, 18503)
!  (49902, 41752),(49818, 41746)
!  (49907, 30225),(49810, 30158)
!  (49843, 5175),(49808, 5145)
!  (49887, 24274),(49805, 24184)
!  (49847, 7128),(49798, 7067)
!  (49820, 7990),(49771, 7967)
  (15 rows)
  
! SELECT * FROM test_cube ORDER BY c~>4 DESC LIMIT 15; -- descending by 2nd coordinate or upper right corner
!                c               
! -------------------------------
!  (36311, 50073),(36258, 49987)
!  (30746, 50040),(30727, 49992)
!  (2168, 50012),(2108, 49914)
!  (21551, 49983),(21492, 49885)
!  (17954, 49975),(17865, 49915)
!  (3531, 49962),(3463, 49934)
!  (19128, 49932),(19112, 49849)
!  (31287, 49923),(31236, 49913)
!  (43925, 49912),(43888, 49878)
!  (29261, 49910),(29247, 49818)
!  (14913, 49873),(14849, 49836)
!  (20007, 49858),(19921, 49778)
!  (38266, 49852),(38233, 49844)
!  (37595, 49849),(37581, 49834)
!  (46151, 49848),(46058, 49830)
  (15 rows)
  
! -- same thing for index with points
! CREATE TABLE test_point(c cube);
! INSERT INTO test_point(SELECT cube(array[c->1,c->2,c->3,c->4]) FROM test_cube);
! CREATE INDEX ON test_point USING gist(c);
! SELECT * FROM test_point ORDER BY c~>1, c~>2 LIMIT 15; -- ascending by 1st then by 2nd coordinate
!             c             
! --------------------------
!  (54, 38679, 3, 38602)
!  (83, 10271, 15, 10265)
!  (122, 46832, 64, 46762)
!  (154, 4019, 138, 3990)
!  (161, 24465, 107, 24374)
!  (162, 26040, 120, 25963)
!  (167, 17214, 92, 17184)
!  (207, 40886, 179, 40879)
!  (259, 1850, 175, 1820)
!  (270, 29508, 264, 29440)
!  (270, 32616, 226, 32607)
!  (288, 49588, 204, 49571)
!  (318, 31489, 235, 31404)
!  (326, 18837, 285, 18817)
!  (337, 455, 240, 359)
  (15 rows)
  
! SELECT * FROM test_point ORDER BY c~>4 DESC LIMIT 15; -- descending by 1st coordinate
!               c               
! ------------------------------
!  (30746, 50040, 30727, 49992)
!  (36311, 50073, 36258, 49987)
!  (3531, 49962, 3463, 49934)
!  (17954, 49975, 17865, 49915)
!  (2168, 50012, 2108, 49914)
!  (31287, 49923, 31236, 49913)
!  (21551, 49983, 21492, 49885)
!  (43925, 49912, 43888, 49878)
!  (19128, 49932, 19112, 49849)
!  (38266, 49852, 38233, 49844)
!  (14913, 49873, 14849, 49836)
!  (37595, 49849, 37581, 49834)
!  (46151, 49848, 46058, 49830)
!  (29261, 49910, 29247, 49818)
!  (19233, 49824, 19185, 49794)
  (15 rows)
  
--- 1593,1984 ----
   (2424, 160),(2424, 81)
  (5 rows)
  
! -- Test kNN
! INSERT INTO test_cube VALUES ('(1,1)'), ('(100000)'), ('(0, 100000)'); -- Some corner cases
! SET enable_seqscan = OFF;
! SET enable_indexscan = ON;
! -- Test different metrics
  SELECT *, c <-> '(100, 100),(500, 500)'::cube as dist FROM test_cube ORDER BY c <-> '(100, 100),(500, 500)'::cube LIMIT 5;
              c            |       dist       
  -------------------------+------------------
   (337, 455),(240, 359)   |                0
+  (1, 1)                  | 140.007142674936
   (759, 187),(662, 163)   |              162
   (948, 1201),(907, 1156) | 772.000647668122
   (1444, 403),(1346, 344) |              846
  (5 rows)
  
  SELECT *, c <=> '(100, 100),(500, 500)'::cube as dist FROM test_cube ORDER BY c <=> '(100, 100),(500, 500)'::cube LIMIT 5;
              c            | dist 
  -------------------------+------
   (337, 455),(240, 359)   |    0
+  (1, 1)                  |   99
   (759, 187),(662, 163)   |  162
   (948, 1201),(907, 1156) |  656
   (1444, 403),(1346, 344) |  846
+ (5 rows)
+ 
+ SELECT *, c <#> '(100, 100),(500, 500)'::cube as dist FROM test_cube ORDER BY c <#> '(100, 100),(500, 500)'::cube LIMIT 5;
+             c            | dist 
+ -------------------------+------
+  (337, 455),(240, 359)   |    0
+  (759, 187),(662, 163)   |  162
+  (1, 1)                  |  198
+  (1444, 403),(1346, 344) |  846
   (369, 1457),(278, 1409) |  909
  (5 rows)
  
+ -- Test sorting by coordinates
+ SELECT c~>1, c FROM test_cube ORDER BY c~>1 LIMIT 15; -- ascending by left bound
+  ?column? |             c             
+ ----------+---------------------------
+         0 | (0, 100000)
+         1 | (1, 1)
+         3 | (54, 38679),(3, 38602)
+        15 | (83, 10271),(15, 10265)
+        64 | (122, 46832),(64, 46762)
+        92 | (167, 17214),(92, 17184)
+       107 | (161, 24465),(107, 24374)
+       120 | (162, 26040),(120, 25963)
+       138 | (154, 4019),(138, 3990)
+       175 | (259, 1850),(175, 1820)
+       179 | (207, 40886),(179, 40879)
+       204 | (288, 49588),(204, 49571)
+       226 | (270, 32616),(226, 32607)
+       235 | (318, 31489),(235, 31404)
+       240 | (337, 455),(240, 359)
+ (15 rows)
+ 
+ SELECT c~>2, c FROM test_cube ORDER BY c~>2 LIMIT 15; -- ascending by right bound
+  ?column? |             c             
+ ----------+---------------------------
+         0 | (0, 100000)
+         1 | (1, 1)
+        54 | (54, 38679),(3, 38602)
+        83 | (83, 10271),(15, 10265)
+       122 | (122, 46832),(64, 46762)
+       154 | (154, 4019),(138, 3990)
+       161 | (161, 24465),(107, 24374)
+       162 | (162, 26040),(120, 25963)
+       167 | (167, 17214),(92, 17184)
+       207 | (207, 40886),(179, 40879)
+       259 | (259, 1850),(175, 1820)
+       270 | (270, 29508),(264, 29440)
+       270 | (270, 32616),(226, 32607)
+       288 | (288, 49588),(204, 49571)
+       318 | (318, 31489),(235, 31404)
+ (15 rows)
+ 
+ SELECT c~>3, c FROM test_cube ORDER BY c~>3 LIMIT 15; -- ascending by lower bound
+  ?column? |             c             
+ ----------+---------------------------
+         0 | (100000)
+         1 | (1, 1)
+         6 | (30333, 50),(30273, 6)
+        43 | (43301, 75),(43227, 43)
+        51 | (19650, 142),(19630, 51)
+        81 | (2424, 160),(2424, 81)
+       108 | (3449, 171),(3354, 108)
+       109 | (18037, 155),(17941, 109)
+       114 | (28511, 208),(28479, 114)
+       118 | (19946, 217),(19941, 118)
+       139 | (16906, 191),(16816, 139)
+       163 | (759, 187),(662, 163)
+       181 | (22684, 266),(22656, 181)
+       213 | (24423, 255),(24360, 213)
+       222 | (45989, 249),(45910, 222)
+ (15 rows)
+ 
+ SELECT c~>4, c FROM test_cube ORDER BY c~>4 LIMIT 15; -- ascending by upper bound
+  ?column? |             c             
+ ----------+---------------------------
+         0 | (100000)
+         1 | (1, 1)
+        50 | (30333, 50),(30273, 6)
+        75 | (43301, 75),(43227, 43)
+       142 | (19650, 142),(19630, 51)
+       155 | (18037, 155),(17941, 109)
+       160 | (2424, 160),(2424, 81)
+       171 | (3449, 171),(3354, 108)
+       187 | (759, 187),(662, 163)
+       191 | (16906, 191),(16816, 139)
+       208 | (28511, 208),(28479, 114)
+       217 | (19946, 217),(19941, 118)
+       249 | (45989, 249),(45910, 222)
+       255 | (24423, 255),(24360, 213)
+       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)
+ SET enable_seqscan = ON;
+ SET enable_indexscan = OFF;
+ SELECT *, c <-> '(100, 100),(500, 500)'::cube as dist FROM test_cube ORDER BY c <-> '(100, 100),(500, 500)'::cube LIMIT 5;
+             c            |       dist       
+ -------------------------+------------------
+  (337, 455),(240, 359)   |                0
+  (1, 1)                  | 140.007142674936
+  (759, 187),(662, 163)   |              162
+  (948, 1201),(907, 1156) | 772.000647668122
+  (1444, 403),(1346, 344) |              846
+ (5 rows)
+ 
+ SELECT *, c <=> '(100, 100),(500, 500)'::cube as dist FROM test_cube ORDER BY c <=> '(100, 100),(500, 500)'::cube LIMIT 5;
+             c            | dist 
+ -------------------------+------
+  (337, 455),(240, 359)   |    0
+  (1, 1)                  |   99
+  (759, 187),(662, 163)   |  162
+  (948, 1201),(907, 1156) |  656
+  (1444, 403),(1346, 344) |  846
+ (5 rows)
+ 
  SELECT *, c <#> '(100, 100),(500, 500)'::cube as dist FROM test_cube ORDER BY c <#> '(100, 100),(500, 500)'::cube LIMIT 5;
              c            | dist 
  -------------------------+------
   (337, 455),(240, 359)   |    0
   (759, 187),(662, 163)   |  162
+  (1, 1)                  |  198
   (1444, 403),(1346, 344) |  846
   (369, 1457),(278, 1409) |  909
  (5 rows)
  
! SELECT c~>1, c FROM test_cube ORDER BY c~>1 LIMIT 15; -- ascending by left bound
!  ?column? |             c             
! ----------+---------------------------
!         0 | (0, 100000)
!         1 | (1, 1)
!         3 | (54, 38679),(3, 38602)
!        15 | (83, 10271),(15, 10265)
!        64 | (122, 46832),(64, 46762)
!        92 | (167, 17214),(92, 17184)
!       107 | (161, 24465),(107, 24374)
!       120 | (162, 26040),(120, 25963)
!       138 | (154, 4019),(138, 3990)
!       175 | (259, 1850),(175, 1820)
!       179 | (207, 40886),(179, 40879)
!       204 | (288, 49588),(204, 49571)
!       226 | (270, 32616),(226, 32607)
!       235 | (318, 31489),(235, 31404)
!       240 | (337, 455),(240, 359)
  (15 rows)
  
! SELECT c~>2, c FROM test_cube ORDER BY c~>2 LIMIT 15; -- ascending by right bound
!  ?column? |             c             
! ----------+---------------------------
!         0 | (0, 100000)
!         1 | (1, 1)
!        54 | (54, 38679),(3, 38602)
!        83 | (83, 10271),(15, 10265)
!       122 | (122, 46832),(64, 46762)
!       154 | (154, 4019),(138, 3990)
!       161 | (161, 24465),(107, 24374)
!       162 | (162, 26040),(120, 25963)
!       167 | (167, 17214),(92, 17184)
!       207 | (207, 40886),(179, 40879)
!       259 | (259, 1850),(175, 1820)
!       270 | (270, 29508),(264, 29440)
!       270 | (270, 32616),(226, 32607)
!       288 | (288, 49588),(204, 49571)
!       318 | (318, 31489),(235, 31404)
  (15 rows)
  
! SELECT c~>3, c FROM test_cube ORDER BY c~>3 LIMIT 15; -- ascending by lower bound
!  ?column? |             c             
! ----------+---------------------------
!         0 | (100000)
!         1 | (1, 1)
!         6 | (30333, 50),(30273, 6)
!        43 | (43301, 75),(43227, 43)
!        51 | (19650, 142),(19630, 51)
!        81 | (2424, 160),(2424, 81)
!       108 | (3449, 171),(3354, 108)
!       109 | (18037, 155),(17941, 109)
!       114 | (28511, 208),(28479, 114)
!       118 | (19946, 217),(19941, 118)
!       139 | (16906, 191),(16816, 139)
!       163 | (759, 187),(662, 163)
!       181 | (22684, 266),(22656, 181)
!       213 | (24423, 255),(24360, 213)
!       222 | (45989, 249),(45910, 222)
  (15 rows)
  
! SELECT c~>4, c FROM test_cube ORDER BY c~>4 LIMIT 15; -- ascending by upper bound
!  ?column? |             c             
! ----------+---------------------------
!         0 | (100000)
!         1 | (1, 1)
!        50 | (30333, 50),(30273, 6)
!        75 | (43301, 75),(43227, 43)
!       142 | (19650, 142),(19630, 51)
!       155 | (18037, 155),(17941, 109)
!       160 | (2424, 160),(2424, 81)
!       171 | (3449, 171),(3354, 108)
!       187 | (759, 187),(662, 163)
!       191 | (16906, 191),(16816, 139)
!       208 | (28511, 208),(28479, 114)
!       217 | (19946, 217),(19941, 118)
!       249 | (45989, 249),(45910, 222)
!       255 | (24423, 255),(24360, 213)
!       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)
  
diff --git a/contrib/cube/expected/cube_2.out b/contrib/cube/expected/cube_2.out
new file mode 100644
index 1aa5cf2..c6ce3a3
*** a/contrib/cube/expected/cube_2.out
--- b/contrib/cube/expected/cube_2.out
*************** SELECT * FROM test_cube WHERE c && '(300
*** 1589,1747 ****
   (2424, 160),(2424, 81)
  (5 rows)
  
! -- kNN with index
  SELECT *, c <-> '(100, 100),(500, 500)'::cube as dist FROM test_cube ORDER BY c <-> '(100, 100),(500, 500)'::cube LIMIT 5;
              c            |       dist       
  -------------------------+------------------
   (337, 455),(240, 359)   |                0
   (759, 187),(662, 163)   |              162
   (948, 1201),(907, 1156) | 772.000647668122
   (1444, 403),(1346, 344) |              846
-  (369, 1457),(278, 1409) |              909
  (5 rows)
  
  SELECT *, c <=> '(100, 100),(500, 500)'::cube as dist FROM test_cube ORDER BY c <=> '(100, 100),(500, 500)'::cube LIMIT 5;
              c            | dist 
  -------------------------+------
   (337, 455),(240, 359)   |    0
   (759, 187),(662, 163)   |  162
   (948, 1201),(907, 1156) |  656
   (1444, 403),(1346, 344) |  846
   (369, 1457),(278, 1409) |  909
  (5 rows)
  
  SELECT *, c <#> '(100, 100),(500, 500)'::cube as dist FROM test_cube ORDER BY c <#> '(100, 100),(500, 500)'::cube LIMIT 5;
              c            | dist 
  -------------------------+------
   (337, 455),(240, 359)   |    0
   (759, 187),(662, 163)   |  162
   (1444, 403),(1346, 344) |  846
   (369, 1457),(278, 1409) |  909
-  (948, 1201),(907, 1156) | 1063
  (5 rows)
  
! -- kNN-based sorting
! SELECT * FROM test_cube ORDER BY c~>1 LIMIT 15; -- ascending by 1st coordinate of lower left corner
!              c             
! ---------------------------
!  (54, 38679),(3, 38602)
!  (83, 10271),(15, 10265)
!  (122, 46832),(64, 46762)
!  (167, 17214),(92, 17184)
!  (161, 24465),(107, 24374)
!  (162, 26040),(120, 25963)
!  (154, 4019),(138, 3990)
!  (259, 1850),(175, 1820)
!  (207, 40886),(179, 40879)
!  (288, 49588),(204, 49571)
!  (270, 32616),(226, 32607)
!  (318, 31489),(235, 31404)
!  (337, 455),(240, 359)
!  (270, 29508),(264, 29440)
!  (369, 1457),(278, 1409)
  (15 rows)
  
! SELECT * FROM test_cube ORDER BY c~>4 LIMIT 15; -- ascending by 2nd coordinate or upper right corner
!              c             
! ---------------------------
!  (30333, 50),(30273, 6)
!  (43301, 75),(43227, 43)
!  (19650, 142),(19630, 51)
!  (2424, 160),(2424, 81)
!  (3449, 171),(3354, 108)
!  (18037, 155),(17941, 109)
!  (28511, 208),(28479, 114)
!  (19946, 217),(19941, 118)
!  (16906, 191),(16816, 139)
!  (759, 187),(662, 163)
!  (22684, 266),(22656, 181)
!  (24423, 255),(24360, 213)
!  (45989, 249),(45910, 222)
!  (11399, 377),(11360, 294)
!  (12162, 389),(12103, 309)
  (15 rows)
  
! SELECT * FROM test_cube ORDER BY c~>1 DESC LIMIT 15; -- descending by 1st coordinate of lower left corner
!                c               
! -------------------------------
!  (50027, 49230),(49951, 49214)
!  (49980, 35004),(49937, 34963)
!  (49985, 6436),(49927, 6338)
!  (49999, 27218),(49908, 27176)
!  (49954, 1340),(49905, 1294)
!  (49944, 25163),(49902, 25153)
!  (49981, 34876),(49898, 34786)
!  (49957, 43390),(49897, 43384)
!  (49853, 18504),(49848, 18503)
!  (49902, 41752),(49818, 41746)
!  (49907, 30225),(49810, 30158)
!  (49843, 5175),(49808, 5145)
!  (49887, 24274),(49805, 24184)
!  (49847, 7128),(49798, 7067)
!  (49820, 7990),(49771, 7967)
  (15 rows)
  
! SELECT * FROM test_cube ORDER BY c~>4 DESC LIMIT 15; -- descending by 2nd coordinate or upper right corner
!                c               
! -------------------------------
!  (36311, 50073),(36258, 49987)
!  (30746, 50040),(30727, 49992)
!  (2168, 50012),(2108, 49914)
!  (21551, 49983),(21492, 49885)
!  (17954, 49975),(17865, 49915)
!  (3531, 49962),(3463, 49934)
!  (19128, 49932),(19112, 49849)
!  (31287, 49923),(31236, 49913)
!  (43925, 49912),(43888, 49878)
!  (29261, 49910),(29247, 49818)
!  (14913, 49873),(14849, 49836)
!  (20007, 49858),(19921, 49778)
!  (38266, 49852),(38233, 49844)
!  (37595, 49849),(37581, 49834)
!  (46151, 49848),(46058, 49830)
  (15 rows)
  
! -- same thing for index with points
! CREATE TABLE test_point(c cube);
! INSERT INTO test_point(SELECT cube(array[c->1,c->2,c->3,c->4]) FROM test_cube);
! CREATE INDEX ON test_point USING gist(c);
! SELECT * FROM test_point ORDER BY c~>1, c~>2 LIMIT 15; -- ascending by 1st then by 2nd coordinate
!             c             
! --------------------------
!  (54, 38679, 3, 38602)
!  (83, 10271, 15, 10265)
!  (122, 46832, 64, 46762)
!  (154, 4019, 138, 3990)
!  (161, 24465, 107, 24374)
!  (162, 26040, 120, 25963)
!  (167, 17214, 92, 17184)
!  (207, 40886, 179, 40879)
!  (259, 1850, 175, 1820)
!  (270, 29508, 264, 29440)
!  (270, 32616, 226, 32607)
!  (288, 49588, 204, 49571)
!  (318, 31489, 235, 31404)
!  (326, 18837, 285, 18817)
!  (337, 455, 240, 359)
  (15 rows)
  
! SELECT * FROM test_point ORDER BY c~>4 DESC LIMIT 15; -- descending by 1st coordinate
!               c               
! ------------------------------
!  (30746, 50040, 30727, 49992)
!  (36311, 50073, 36258, 49987)
!  (3531, 49962, 3463, 49934)
!  (17954, 49975, 17865, 49915)
!  (2168, 50012, 2108, 49914)
!  (31287, 49923, 31236, 49913)
!  (21551, 49983, 21492, 49885)
!  (43925, 49912, 43888, 49878)
!  (19128, 49932, 19112, 49849)
!  (38266, 49852, 38233, 49844)
!  (14913, 49873, 14849, 49836)
!  (37595, 49849, 37581, 49834)
!  (46151, 49848, 46058, 49830)
!  (29261, 49910, 29247, 49818)
!  (19233, 49824, 19185, 49794)
  (15 rows)
  
--- 1589,1980 ----
   (2424, 160),(2424, 81)
  (5 rows)
  
! -- Test kNN
! INSERT INTO test_cube VALUES ('(1,1)'), ('(100000)'), ('(0, 100000)'); -- Some corner cases
! SET enable_seqscan = OFF;
! SET enable_indexscan = ON;
! -- Test different metrics
  SELECT *, c <-> '(100, 100),(500, 500)'::cube as dist FROM test_cube ORDER BY c <-> '(100, 100),(500, 500)'::cube LIMIT 5;
              c            |       dist       
  -------------------------+------------------
   (337, 455),(240, 359)   |                0
+  (1, 1)                  | 140.007142674936
   (759, 187),(662, 163)   |              162
   (948, 1201),(907, 1156) | 772.000647668122
   (1444, 403),(1346, 344) |              846
  (5 rows)
  
  SELECT *, c <=> '(100, 100),(500, 500)'::cube as dist FROM test_cube ORDER BY c <=> '(100, 100),(500, 500)'::cube LIMIT 5;
              c            | dist 
  -------------------------+------
   (337, 455),(240, 359)   |    0
+  (1, 1)                  |   99
   (759, 187),(662, 163)   |  162
   (948, 1201),(907, 1156) |  656
   (1444, 403),(1346, 344) |  846
+ (5 rows)
+ 
+ SELECT *, c <#> '(100, 100),(500, 500)'::cube as dist FROM test_cube ORDER BY c <#> '(100, 100),(500, 500)'::cube LIMIT 5;
+             c            | dist 
+ -------------------------+------
+  (337, 455),(240, 359)   |    0
+  (759, 187),(662, 163)   |  162
+  (1, 1)                  |  198
+  (1444, 403),(1346, 344) |  846
   (369, 1457),(278, 1409) |  909
  (5 rows)
  
+ -- Test sorting by coordinates
+ SELECT c~>1, c FROM test_cube ORDER BY c~>1 LIMIT 15; -- ascending by left bound
+  ?column? |             c             
+ ----------+---------------------------
+         0 | (0, 100000)
+         1 | (1, 1)
+         3 | (54, 38679),(3, 38602)
+        15 | (83, 10271),(15, 10265)
+        64 | (122, 46832),(64, 46762)
+        92 | (167, 17214),(92, 17184)
+       107 | (161, 24465),(107, 24374)
+       120 | (162, 26040),(120, 25963)
+       138 | (154, 4019),(138, 3990)
+       175 | (259, 1850),(175, 1820)
+       179 | (207, 40886),(179, 40879)
+       204 | (288, 49588),(204, 49571)
+       226 | (270, 32616),(226, 32607)
+       235 | (318, 31489),(235, 31404)
+       240 | (337, 455),(240, 359)
+ (15 rows)
+ 
+ SELECT c~>2, c FROM test_cube ORDER BY c~>2 LIMIT 15; -- ascending by right bound
+  ?column? |             c             
+ ----------+---------------------------
+         0 | (0, 100000)
+         1 | (1, 1)
+        54 | (54, 38679),(3, 38602)
+        83 | (83, 10271),(15, 10265)
+       122 | (122, 46832),(64, 46762)
+       154 | (154, 4019),(138, 3990)
+       161 | (161, 24465),(107, 24374)
+       162 | (162, 26040),(120, 25963)
+       167 | (167, 17214),(92, 17184)
+       207 | (207, 40886),(179, 40879)
+       259 | (259, 1850),(175, 1820)
+       270 | (270, 29508),(264, 29440)
+       270 | (270, 32616),(226, 32607)
+       288 | (288, 49588),(204, 49571)
+       318 | (318, 31489),(235, 31404)
+ (15 rows)
+ 
+ SELECT c~>3, c FROM test_cube ORDER BY c~>3 LIMIT 15; -- ascending by lower bound
+  ?column? |             c             
+ ----------+---------------------------
+         0 | (100000)
+         1 | (1, 1)
+         6 | (30333, 50),(30273, 6)
+        43 | (43301, 75),(43227, 43)
+        51 | (19650, 142),(19630, 51)
+        81 | (2424, 160),(2424, 81)
+       108 | (3449, 171),(3354, 108)
+       109 | (18037, 155),(17941, 109)
+       114 | (28511, 208),(28479, 114)
+       118 | (19946, 217),(19941, 118)
+       139 | (16906, 191),(16816, 139)
+       163 | (759, 187),(662, 163)
+       181 | (22684, 266),(22656, 181)
+       213 | (24423, 255),(24360, 213)
+       222 | (45989, 249),(45910, 222)
+ (15 rows)
+ 
+ SELECT c~>4, c FROM test_cube ORDER BY c~>4 LIMIT 15; -- ascending by upper bound
+  ?column? |             c             
+ ----------+---------------------------
+         0 | (100000)
+         1 | (1, 1)
+        50 | (30333, 50),(30273, 6)
+        75 | (43301, 75),(43227, 43)
+       142 | (19650, 142),(19630, 51)
+       155 | (18037, 155),(17941, 109)
+       160 | (2424, 160),(2424, 81)
+       171 | (3449, 171),(3354, 108)
+       187 | (759, 187),(662, 163)
+       191 | (16906, 191),(16816, 139)
+       208 | (28511, 208),(28479, 114)
+       217 | (19946, 217),(19941, 118)
+       249 | (45989, 249),(45910, 222)
+       255 | (24423, 255),(24360, 213)
+       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)
+ SET enable_seqscan = ON;
+ SET enable_indexscan = OFF;
+ SELECT *, c <-> '(100, 100),(500, 500)'::cube as dist FROM test_cube ORDER BY c <-> '(100, 100),(500, 500)'::cube LIMIT 5;
+             c            |       dist       
+ -------------------------+------------------
+  (337, 455),(240, 359)   |                0
+  (1, 1)                  | 140.007142674936
+  (759, 187),(662, 163)   |              162
+  (948, 1201),(907, 1156) | 772.000647668122
+  (1444, 403),(1346, 344) |              846
+ (5 rows)
+ 
+ SELECT *, c <=> '(100, 100),(500, 500)'::cube as dist FROM test_cube ORDER BY c <=> '(100, 100),(500, 500)'::cube LIMIT 5;
+             c            | dist 
+ -------------------------+------
+  (337, 455),(240, 359)   |    0
+  (1, 1)                  |   99
+  (759, 187),(662, 163)   |  162
+  (948, 1201),(907, 1156) |  656
+  (1444, 403),(1346, 344) |  846
+ (5 rows)
+ 
  SELECT *, c <#> '(100, 100),(500, 500)'::cube as dist FROM test_cube ORDER BY c <#> '(100, 100),(500, 500)'::cube LIMIT 5;
              c            | dist 
  -------------------------+------
   (337, 455),(240, 359)   |    0
   (759, 187),(662, 163)   |  162
+  (1, 1)                  |  198
   (1444, 403),(1346, 344) |  846
   (369, 1457),(278, 1409) |  909
  (5 rows)
  
! SELECT c~>1, c FROM test_cube ORDER BY c~>1 LIMIT 15; -- ascending by left bound
!  ?column? |             c             
! ----------+---------------------------
!         0 | (0, 100000)
!         1 | (1, 1)
!         3 | (54, 38679),(3, 38602)
!        15 | (83, 10271),(15, 10265)
!        64 | (122, 46832),(64, 46762)
!        92 | (167, 17214),(92, 17184)
!       107 | (161, 24465),(107, 24374)
!       120 | (162, 26040),(120, 25963)
!       138 | (154, 4019),(138, 3990)
!       175 | (259, 1850),(175, 1820)
!       179 | (207, 40886),(179, 40879)
!       204 | (288, 49588),(204, 49571)
!       226 | (270, 32616),(226, 32607)
!       235 | (318, 31489),(235, 31404)
!       240 | (337, 455),(240, 359)
  (15 rows)
  
! SELECT c~>2, c FROM test_cube ORDER BY c~>2 LIMIT 15; -- ascending by right bound
!  ?column? |             c             
! ----------+---------------------------
!         0 | (0, 100000)
!         1 | (1, 1)
!        54 | (54, 38679),(3, 38602)
!        83 | (83, 10271),(15, 10265)
!       122 | (122, 46832),(64, 46762)
!       154 | (154, 4019),(138, 3990)
!       161 | (161, 24465),(107, 24374)
!       162 | (162, 26040),(120, 25963)
!       167 | (167, 17214),(92, 17184)
!       207 | (207, 40886),(179, 40879)
!       259 | (259, 1850),(175, 1820)
!       270 | (270, 29508),(264, 29440)
!       270 | (270, 32616),(226, 32607)
!       288 | (288, 49588),(204, 49571)
!       318 | (318, 31489),(235, 31404)
  (15 rows)
  
! SELECT c~>3, c FROM test_cube ORDER BY c~>3 LIMIT 15; -- ascending by lower bound
!  ?column? |             c             
! ----------+---------------------------
!         0 | (100000)
!         1 | (1, 1)
!         6 | (30333, 50),(30273, 6)
!        43 | (43301, 75),(43227, 43)
!        51 | (19650, 142),(19630, 51)
!        81 | (2424, 160),(2424, 81)
!       108 | (3449, 171),(3354, 108)
!       109 | (18037, 155),(17941, 109)
!       114 | (28511, 208),(28479, 114)
!       118 | (19946, 217),(19941, 118)
!       139 | (16906, 191),(16816, 139)
!       163 | (759, 187),(662, 163)
!       181 | (22684, 266),(22656, 181)
!       213 | (24423, 255),(24360, 213)
!       222 | (45989, 249),(45910, 222)
  (15 rows)
  
! SELECT c~>4, c FROM test_cube ORDER BY c~>4 LIMIT 15; -- ascending by upper bound
!  ?column? |             c             
! ----------+---------------------------
!         0 | (100000)
!         1 | (1, 1)
!        50 | (30333, 50),(30273, 6)
!        75 | (43301, 75),(43227, 43)
!       142 | (19650, 142),(19630, 51)
!       155 | (18037, 155),(17941, 109)
!       160 | (2424, 160),(2424, 81)
!       171 | (3449, 171),(3354, 108)
!       187 | (759, 187),(662, 163)
!       191 | (16906, 191),(16816, 139)
!       208 | (28511, 208),(28479, 114)
!       217 | (19946, 217),(19941, 118)
!       249 | (45989, 249),(45910, 222)
!       255 | (24423, 255),(24360, 213)
!       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)
  
diff --git a/contrib/cube/sql/cube.sql b/contrib/cube/sql/cube.sql
new file mode 100644
index 58ea3ad..510d5a7
*** a/contrib/cube/sql/cube.sql
--- b/contrib/cube/sql/cube.sql
*************** SELECT * FROM test_cube WHERE c && '(300
*** 382,401 ****
  -- Test sorting
  SELECT * FROM test_cube WHERE c && '(3000,1000),(0,0)' GROUP BY c ORDER BY c;
  
! -- kNN with index
  SELECT *, c <-> '(100, 100),(500, 500)'::cube as dist FROM test_cube ORDER BY c <-> '(100, 100),(500, 500)'::cube LIMIT 5;
  SELECT *, c <=> '(100, 100),(500, 500)'::cube as dist FROM test_cube ORDER BY c <=> '(100, 100),(500, 500)'::cube LIMIT 5;
  SELECT *, c <#> '(100, 100),(500, 500)'::cube as dist FROM test_cube ORDER BY c <#> '(100, 100),(500, 500)'::cube LIMIT 5;
  
! -- kNN-based sorting
! SELECT * FROM test_cube ORDER BY c~>1 LIMIT 15; -- ascending by 1st coordinate of lower left corner
! SELECT * FROM test_cube ORDER BY c~>4 LIMIT 15; -- ascending by 2nd coordinate or upper right corner
! SELECT * FROM test_cube ORDER BY c~>1 DESC LIMIT 15; -- descending by 1st coordinate of lower left corner
! SELECT * FROM test_cube ORDER BY c~>4 DESC LIMIT 15; -- descending by 2nd coordinate or upper right corner
  
! -- same thing for index with points
! CREATE TABLE test_point(c cube);
! INSERT INTO test_point(SELECT cube(array[c->1,c->2,c->3,c->4]) FROM test_cube);
! CREATE INDEX ON test_point USING gist(c);
! SELECT * FROM test_point ORDER BY c~>1, c~>2 LIMIT 15; -- ascending by 1st then by 2nd coordinate
! SELECT * FROM test_point ORDER BY c~>4 DESC LIMIT 15; -- descending by 1st coordinate
--- 382,420 ----
  -- Test sorting
  SELECT * FROM test_cube WHERE c && '(3000,1000),(0,0)' GROUP BY c ORDER BY c;
  
! -- Test kNN
! INSERT INTO test_cube VALUES ('(1,1)'), ('(100000)'), ('(0, 100000)'); -- Some corner cases
! SET enable_seqscan = OFF;
! SET enable_indexscan = ON;
! 
! -- Test different metrics
  SELECT *, c <-> '(100, 100),(500, 500)'::cube as dist FROM test_cube ORDER BY c <-> '(100, 100),(500, 500)'::cube LIMIT 5;
  SELECT *, c <=> '(100, 100),(500, 500)'::cube as dist FROM test_cube ORDER BY c <=> '(100, 100),(500, 500)'::cube LIMIT 5;
  SELECT *, c <#> '(100, 100),(500, 500)'::cube as dist FROM test_cube ORDER BY c <#> '(100, 100),(500, 500)'::cube LIMIT 5;
  
! -- Test sorting by coordinates
! SELECT c~>1, c FROM test_cube ORDER BY c~>1 LIMIT 15; -- ascending by left bound
! SELECT c~>2, c FROM test_cube ORDER BY c~>2 LIMIT 15; -- ascending by right bound
! SELECT c~>3, c FROM test_cube ORDER BY c~>3 LIMIT 15; -- ascending by lower bound
! SELECT c~>4, c FROM test_cube ORDER BY c~>4 LIMIT 15; -- ascending by upper bound
! SELECT c~>(-1), c FROM test_cube ORDER BY c~>(-1) LIMIT 15; -- descending by left bound
! SELECT c~>(-2), c FROM test_cube ORDER BY c~>(-2) LIMIT 15; -- descending by right bound
! SELECT c~>(-3), c FROM test_cube ORDER BY c~>(-3) LIMIT 15; -- descending by lower bound
! SELECT c~>(-4), c FROM test_cube ORDER BY c~>(-4) LIMIT 15; -- descending by upper bound
  
! -- Same queries with sequential scan (should give the same results as above)
! SET enable_seqscan = ON;
! SET enable_indexscan = OFF;
! 
! SELECT *, c <-> '(100, 100),(500, 500)'::cube as dist FROM test_cube ORDER BY c <-> '(100, 100),(500, 500)'::cube LIMIT 5;
! SELECT *, c <=> '(100, 100),(500, 500)'::cube as dist FROM test_cube ORDER BY c <=> '(100, 100),(500, 500)'::cube LIMIT 5;
! SELECT *, c <#> '(100, 100),(500, 500)'::cube as dist FROM test_cube ORDER BY c <#> '(100, 100),(500, 500)'::cube LIMIT 5;
! 
! SELECT c~>1, c FROM test_cube ORDER BY c~>1 LIMIT 15; -- ascending by left bound
! SELECT c~>2, c FROM test_cube ORDER BY c~>2 LIMIT 15; -- ascending by right bound
! SELECT c~>3, c FROM test_cube ORDER BY c~>3 LIMIT 15; -- ascending by lower bound
! SELECT c~>4, c FROM test_cube ORDER BY c~>4 LIMIT 15; -- ascending by upper bound
! SELECT c~>(-1), c FROM test_cube ORDER BY c~>(-1) LIMIT 15; -- descending by left bound
! SELECT c~>(-2), c FROM test_cube ORDER BY c~>(-2) LIMIT 15; -- descending by right bound
! SELECT c~>(-3), c FROM test_cube ORDER BY c~>(-3) LIMIT 15; -- descending by lower bound
! SELECT c~>(-4), c FROM test_cube ORDER BY c~>(-4) LIMIT 15; -- descending by upper bound
diff --git a/doc/src/sgml/cube.sgml b/doc/src/sgml/cube.sgml
new file mode 100644
index 46d8e4e..65887b1
*** a/doc/src/sgml/cube.sgml
--- b/doc/src/sgml/cube.sgml
***************
*** 186,195 ****
        <entry><literal>a ~&gt; n</literal></entry>
        <entry><type>float8</type></entry>
        <entry>
!         Get <replaceable>n</replaceable>-th coordinate in <quote>normalized</quote> cube
!         representation, in which the coordinates have been rearranged into
!         the form <quote>lower left &mdash; upper right</quote>; that is, the
!         smaller endpoint along each dimension appears first.
        </entry>
       </row>
  
--- 186,197 ----
        <entry><literal>a ~&gt; n</literal></entry>
        <entry><type>float8</type></entry>
        <entry>
!         Get <replaceable>n</replaceable>-th coordinate of cube in following way:
!         n = 2 * k - 1 means lower bound of <replaceable>k</replaceable>-th
!         dimension, n = 2 * k means upper bound of
!         <replaceable>k</replaceable>-th dimension.  Negative
!         <replaceable>n</replaceable> denotes inversed value of corresponding
!         positive coordinate.  This operator is designed for KNN-GiST support.
        </entry>
       </row>
  
