Commit 08612f45 authored by Heikki Linnakangas's avatar Heikki Linnakangas

Extend cube on-disk format to pack points more tightly.

If the lower left and upper right corners of a cube are the same, set a
flag in the cube header, and only store one copy of the coordinates. That
cuts the on-disk size into half for the common case that the cube datatype
is used to represent points rather than boxes.

The new format is backwards-compatible with the old one, so pg_upgrade
still works. However, to get the space savings, the data needs to be
rewritten. A simple VACUUM FULL or REINDEX is not enough, as the old
Datums will just be moved to the new heap/index as is. A pg_dump and
reload, or something similar like casting to text and back, will do the
trick.

This patch deliberately doesn't update all the alternative expected output
files, as I don't have access to machines that produce those outputs. I'm
not sure if they are still relevant, but if they are, the buildfarm will
tell us and produce the diff required to fix it. If none of the buildfarm
animals need them, they should be removed altogether.

Patch by Stas Kelvich.
parent a5963efa
This diff is collapsed.
...@@ -4,11 +4,46 @@ ...@@ -4,11 +4,46 @@
typedef struct NDBOX typedef struct NDBOX
{ {
int32 vl_len_; /* varlena header (do not touch directly!) */ /* varlena header (do not touch directly!) */
unsigned int dim; int32 vl_len_;
/*----------
* Header contains info about NDBOX. For binary compatibility with old
* versions, it is defined as "unsigned int".
*
* Following information is stored:
*
* bits 0-7 : number of cube dimensions;
* bits 8-30 : unused, initialize to zero;
* bit 31 : point flag. If set, the upper right coordinates are not
* stored, and are implicitly the same as the lower left
* coordinates.
*----------
*/
unsigned int header;
/*
* Variable length array. The lower left coordinates for each dimension
* come first, followed by upper right coordinates unless the point flag
* is set.
*/
double x[1]; double x[1];
} NDBOX; } NDBOX;
#define POINT_BIT 0x80000000
#define DIM_MASK 0x7fffffff
#define IS_POINT(cube) ( ((cube)->header & POINT_BIT) != 0 )
#define SET_POINT_BIT(cube) ( (cube)->header |= POINT_BIT )
#define DIM(cube) ( (cube)->header & DIM_MASK )
#define SET_DIM(cube, _dim) ( (cube)->header = ((cube)->header & ~DIM_MASK) | (_dim) )
#define LL_COORD(cube, i) ( (cube)->x[i] )
#define UR_COORD(cube, i) ( IS_POINT(cube) ? (cube)->x[i] : (cube)->x[(i) + DIM(cube)] )
#define POINT_SIZE(_dim) (offsetof(NDBOX, x[0]) + sizeof(double)*(_dim))
#define CUBE_SIZE(_dim) (offsetof(NDBOX, x[0]) + sizeof(double)*(_dim)*2)
#define DatumGetNDBOX(x) ((NDBOX*)DatumGetPointer(x)) #define DatumGetNDBOX(x) ((NDBOX*)DatumGetPointer(x))
#define PG_GETARG_NDBOX(x) DatumGetNDBOX( PG_DETOAST_DATUM(PG_GETARG_DATUM(x)) ) #define PG_GETARG_NDBOX(x) DatumGetNDBOX( PG_DETOAST_DATUM(PG_GETARG_DATUM(x)) )
#define PG_RETURN_NDBOX(x) PG_RETURN_POINTER(x) #define PG_RETURN_NDBOX(x) PG_RETURN_POINTER(x)
...@@ -175,11 +175,12 @@ write_box(unsigned int dim, char *str1, char *str2) ...@@ -175,11 +175,12 @@ write_box(unsigned int dim, char *str1, char *str2)
NDBOX *bp; NDBOX *bp;
char *s; char *s;
int i; int i;
int size = offsetof(NDBOX, x[0]) + sizeof(double) * dim * 2; int size = CUBE_SIZE(dim);
bool point = true;
bp = palloc0(size); bp = palloc0(size);
SET_VARSIZE(bp, size); SET_VARSIZE(bp, size);
bp->dim = dim; SET_DIM(bp, dim);
s = str1; s = str1;
bp->x[i=0] = strtod(s, NULL); bp->x[i=0] = strtod(s, NULL);
...@@ -191,10 +192,28 @@ write_box(unsigned int dim, char *str1, char *str2) ...@@ -191,10 +192,28 @@ write_box(unsigned int dim, char *str1, char *str2)
s = str2; s = str2;
bp->x[i=dim] = strtod(s, NULL); bp->x[i=dim] = strtod(s, NULL);
if (bp->x[dim] != bp->x[0])
point = false;
while ((s = strchr(s, ',')) != NULL) while ((s = strchr(s, ',')) != NULL)
{ {
s++; i++; s++; i++;
bp->x[i] = strtod(s, NULL); bp->x[i] = strtod(s, NULL);
if (bp->x[i] != bp->x[i-dim])
point = false;
}
if (point)
{
/*
* The value turned out to be a point, ie. all the upper-right
* coordinates were equal to the lower-left coordinates. Resize the
* the cube we constructed. Note: we don't bother to repalloc() it
* smaller, it's unlikely that the tiny amount of memory free'd that
* way would be useful.
*/
size = POINT_SIZE(dim);
SET_VARSIZE(bp, size);
SET_POINT_BIT(bp);
} }
return(bp); return(bp);
...@@ -203,31 +222,29 @@ write_box(unsigned int dim, char *str1, char *str2) ...@@ -203,31 +222,29 @@ write_box(unsigned int dim, char *str1, char *str2)
static NDBOX * static NDBOX *
write_point_as_box(char *str, int dim) write_point_as_box(char *str, int dim)
{ {
NDBOX *bp; NDBOX *bp;
int i, int i,
size; size;
double x; double x;
char *s = str; char *s = str;
size = offsetof(NDBOX, x[0]) + sizeof(double) * dim * 2; size = POINT_SIZE(dim);
bp = palloc0(size);
bp = palloc0(size); SET_VARSIZE(bp, size);
SET_VARSIZE(bp, size); SET_DIM(bp, dim);
bp->dim = dim; SET_POINT_BIT(bp);
i = 0; i = 0;
x = strtod(s, NULL); x = strtod(s, NULL);
bp->x[0] = x; bp->x[0] = x;
bp->x[dim] = x; while ((s = strchr(s, ',')) != NULL)
while ((s = strchr(s, ',')) != NULL) {
{ s++; i++;
s++; i++; x = strtod(s, NULL);
x = strtod(s, NULL); bp->x[i] = x;
bp->x[i] = x; }
bp->x[i+dim] = x;
} return(bp);
return(bp);
} }
#include "cubescan.c" #include "cubescan.c"
...@@ -473,8 +473,85 @@ SELECT cube_subset(cube('(1,3,5),(6,7,8)'), ARRAY[3,2,1,1]); ...@@ -473,8 +473,85 @@ SELECT cube_subset(cube('(1,3,5),(6,7,8)'), ARRAY[3,2,1,1]);
(5, 3, 1, 1),(8, 7, 6, 6) (5, 3, 1, 1),(8, 7, 6, 6)
(1 row) (1 row)
SELECT cube_subset(cube('(1,3,5),(1,3,5)'), ARRAY[3,2,1,1]);
cube_subset
--------------
(5, 3, 1, 1)
(1 row)
SELECT cube_subset(cube('(1,3,5),(6,7,8)'), ARRAY[4,0]); SELECT cube_subset(cube('(1,3,5),(6,7,8)'), ARRAY[4,0]);
ERROR: Index out of bounds ERROR: Index out of bounds
SELECT cube_subset(cube('(6,7,8),(6,7,8)'), ARRAY[4,0]);
ERROR: Index out of bounds
--
-- Test point processing
--
SELECT cube('(1,2),(1,2)'); -- cube_in
cube
--------
(1, 2)
(1 row)
SELECT cube('{0,1,2}'::float[], '{0,1,2}'::float[]); -- cube_a_f8_f8
cube
-----------
(0, 1, 2)
(1 row)
SELECT cube('{5,6,7,8}'::float[]); -- cube_a_f8
cube
--------------
(5, 6, 7, 8)
(1 row)
SELECT cube(1.37); -- cube_f8
cube
--------
(1.37)
(1 row)
SELECT cube(1.37, 1.37); -- cube_f8_f8
cube
--------
(1.37)
(1 row)
SELECT cube(cube(1,1), 42); -- cube_c_f8
cube
---------
(1, 42)
(1 row)
SELECT cube(cube(1,2), 42); -- cube_c_f8
cube
-----------------
(1, 42),(2, 42)
(1 row)
SELECT cube(cube(1,1), 42, 42); -- cube_c_f8_f8
cube
---------
(1, 42)
(1 row)
SELECT cube(cube(1,1), 42, 24); -- cube_c_f8_f8
cube
-----------------
(1, 42),(1, 24)
(1 row)
SELECT cube(cube(1,2), 42, 42); -- cube_c_f8_f8
cube
-----------------
(1, 42),(2, 42)
(1 row)
SELECT cube(cube(1,2), 42, 24); -- cube_c_f8_f8
cube
-----------------
(1, 42),(2, 24)
(1 row)
-- --
-- Testing limit of CUBE_MAX_DIM dimensions check in cube_in. -- Testing limit of CUBE_MAX_DIM dimensions check in cube_in.
-- --
...@@ -878,6 +955,24 @@ SELECT cube_distance('(0)'::cube,'(.3,.4)'::cube); ...@@ -878,6 +955,24 @@ SELECT cube_distance('(0)'::cube,'(.3,.4)'::cube);
0.5 0.5
(1 row) (1 row)
SELECT cube_distance('(2,3,4)'::cube,'(2,3,4)'::cube);
cube_distance
---------------
0
(1 row)
SELECT cube_distance('(42,42,42,42)'::cube,'(137,137,137,137)'::cube);
cube_distance
---------------
190
(1 row)
SELECT cube_distance('(42,42,42)'::cube,'(137,137)'::cube);
cube_distance
------------------
140.762210837994
(1 row)
-- Test of cube function (text to cube) -- Test of cube function (text to cube)
-- --
SELECT cube('(1,1.2)'::text); SELECT cube('(1,1.2)'::text);
...@@ -912,6 +1007,18 @@ SELECT cube_dim('(0,0,0)'::cube); ...@@ -912,6 +1007,18 @@ SELECT cube_dim('(0,0,0)'::cube);
3 3
(1 row) (1 row)
SELECT cube_dim('(42,42,42),(42,42,42)'::cube);
cube_dim
----------
3
(1 row)
SELECT cube_dim('(4,8,15,16,23),(4,8,15,16,23)'::cube);
cube_dim
----------
5
(1 row)
-- Test of cube_ll_coord function (retrieves LL coodinate values) -- Test of cube_ll_coord function (retrieves LL coodinate values)
-- --
SELECT cube_ll_coord('(-1,1),(2,-2)'::cube, 1); SELECT cube_ll_coord('(-1,1),(2,-2)'::cube, 1);
...@@ -932,6 +1039,42 @@ SELECT cube_ll_coord('(-1,1),(2,-2)'::cube, 3); ...@@ -932,6 +1039,42 @@ SELECT cube_ll_coord('(-1,1),(2,-2)'::cube, 3);
0 0
(1 row) (1 row)
SELECT cube_ll_coord('(1,2),(1,2)'::cube, 1);
cube_ll_coord
---------------
1
(1 row)
SELECT cube_ll_coord('(1,2),(1,2)'::cube, 2);
cube_ll_coord
---------------
2
(1 row)
SELECT cube_ll_coord('(1,2),(1,2)'::cube, 3);
cube_ll_coord
---------------
0
(1 row)
SELECT cube_ll_coord('(42,137)'::cube, 1);
cube_ll_coord
---------------
42
(1 row)
SELECT cube_ll_coord('(42,137)'::cube, 2);
cube_ll_coord
---------------
137
(1 row)
SELECT cube_ll_coord('(42,137)'::cube, 3);
cube_ll_coord
---------------
0
(1 row)
-- Test of cube_ur_coord function (retrieves UR coodinate values) -- Test of cube_ur_coord function (retrieves UR coodinate values)
-- --
SELECT cube_ur_coord('(-1,1),(2,-2)'::cube, 1); SELECT cube_ur_coord('(-1,1),(2,-2)'::cube, 1);
...@@ -952,6 +1095,42 @@ SELECT cube_ur_coord('(-1,1),(2,-2)'::cube, 3); ...@@ -952,6 +1095,42 @@ SELECT cube_ur_coord('(-1,1),(2,-2)'::cube, 3);
0 0
(1 row) (1 row)
SELECT cube_ur_coord('(1,2),(1,2)'::cube, 1);
cube_ur_coord
---------------
1
(1 row)
SELECT cube_ur_coord('(1,2),(1,2)'::cube, 2);
cube_ur_coord
---------------
2
(1 row)
SELECT cube_ur_coord('(1,2),(1,2)'::cube, 3);
cube_ur_coord
---------------
0
(1 row)
SELECT cube_ur_coord('(42,137)'::cube, 1);
cube_ur_coord
---------------
42
(1 row)
SELECT cube_ur_coord('(42,137)'::cube, 2);
cube_ur_coord
---------------
137
(1 row)
SELECT cube_ur_coord('(42,137)'::cube, 3);
cube_ur_coord
---------------
0
(1 row)
-- Test of cube_is_point -- Test of cube_is_point
-- --
SELECT cube_is_point('(0)'::cube); SELECT cube_is_point('(0)'::cube);
...@@ -1100,6 +1279,108 @@ SELECT cube_enlarge('(2,-2),(-3,7)'::cube, -3, 2); ...@@ -1100,6 +1279,108 @@ SELECT cube_enlarge('(2,-2),(-3,7)'::cube, -3, 2);
(-0.5, 1),(-0.5, 4) (-0.5, 1),(-0.5, 4)
(1 row) (1 row)
SELECT cube_enlarge('(42,-23,-23),(42,23,23)'::cube, -23, 5);
cube_enlarge
--------------
(42, 0, 0)
(1 row)
SELECT cube_enlarge('(42,-23,-23),(42,23,23)'::cube, -24, 5);
cube_enlarge
--------------
(42, 0, 0)
(1 row)
-- Test of cube_union (MBR for two cubes)
--
SELECT cube_union('(1,2),(3,4)'::cube, '(5,6,7),(8,9,10)'::cube);
cube_union
----------------------
(1, 2, 0),(8, 9, 10)
(1 row)
SELECT cube_union('(1,2)'::cube, '(4,2,0,0)'::cube);
cube_union
---------------------------
(1, 2, 0, 0),(4, 2, 0, 0)
(1 row)
SELECT cube_union('(1,2),(1,2)'::cube, '(4,2),(4,2)'::cube);
cube_union
---------------
(1, 2),(4, 2)
(1 row)
SELECT cube_union('(1,2),(1,2)'::cube, '(1,2),(1,2)'::cube);
cube_union
------------
(1, 2)
(1 row)
SELECT cube_union('(1,2),(1,2)'::cube, '(1,2,0),(1,2,0)'::cube);
cube_union
------------
(1, 2, 0)
(1 row)
-- Test of cube_inter
--
SELECT cube_inter('(1,2),(10,11)'::cube, '(3,4), (16,15)'::cube); -- intersects
cube_inter
-----------------
(3, 4),(10, 11)
(1 row)
SELECT cube_inter('(1,2),(10,11)'::cube, '(3,4), (6,5)'::cube); -- includes
cube_inter
---------------
(3, 4),(6, 5)
(1 row)
SELECT cube_inter('(1,2),(10,11)'::cube, '(13,14), (16,15)'::cube); -- no intersection
cube_inter
-------------------
(13, 14),(10, 11)
(1 row)
SELECT cube_inter('(1,2),(10,11)'::cube, '(3,14), (16,15)'::cube); -- no intersection, but one dimension intersects
cube_inter
------------------
(3, 14),(10, 11)
(1 row)
SELECT cube_inter('(1,2),(10,11)'::cube, '(10,11), (16,15)'::cube); -- point intersection
cube_inter
------------
(10, 11)
(1 row)
SELECT cube_inter('(1,2,3)'::cube, '(1,2,3)'::cube); -- point args
cube_inter
------------
(1, 2, 3)
(1 row)
SELECT cube_inter('(1,2,3)'::cube, '(5,6,3)'::cube); -- point args
cube_inter
---------------------
(5, 6, 3),(1, 2, 3)
(1 row)
-- Test of cube_size
--
SELECT cube_size('(4,8),(15,16)'::cube);
cube_size
-----------
88
(1 row)
SELECT cube_size('(42,137)'::cube);
cube_size
-----------
0
(1 row)
-- Load some example data and build the index -- Load some example data and build the index
-- --
CREATE TABLE test_cube (c cube); CREATE TABLE test_cube (c cube);
......
...@@ -473,8 +473,85 @@ SELECT cube_subset(cube('(1,3,5),(6,7,8)'), ARRAY[3,2,1,1]); ...@@ -473,8 +473,85 @@ SELECT cube_subset(cube('(1,3,5),(6,7,8)'), ARRAY[3,2,1,1]);
(5, 3, 1, 1),(8, 7, 6, 6) (5, 3, 1, 1),(8, 7, 6, 6)
(1 row) (1 row)
SELECT cube_subset(cube('(1,3,5),(1,3,5)'), ARRAY[3,2,1,1]);
cube_subset
--------------
(5, 3, 1, 1)
(1 row)
SELECT cube_subset(cube('(1,3,5),(6,7,8)'), ARRAY[4,0]); SELECT cube_subset(cube('(1,3,5),(6,7,8)'), ARRAY[4,0]);
ERROR: Index out of bounds ERROR: Index out of bounds
SELECT cube_subset(cube('(6,7,8),(6,7,8)'), ARRAY[4,0]);
ERROR: Index out of bounds
--
-- Test point processing
--
SELECT cube('(1,2),(1,2)'); -- cube_in
cube
--------
(1, 2)
(1 row)
SELECT cube('{0,1,2}'::float[], '{0,1,2}'::float[]); -- cube_a_f8_f8
cube
-----------
(0, 1, 2)
(1 row)
SELECT cube('{5,6,7,8}'::float[]); -- cube_a_f8
cube
--------------
(5, 6, 7, 8)
(1 row)
SELECT cube(1.37); -- cube_f8
cube
--------
(1.37)
(1 row)
SELECT cube(1.37, 1.37); -- cube_f8_f8
cube
--------
(1.37)
(1 row)
SELECT cube(cube(1,1), 42); -- cube_c_f8
cube
---------
(1, 42)
(1 row)
SELECT cube(cube(1,2), 42); -- cube_c_f8
cube
-----------------
(1, 42),(2, 42)
(1 row)
SELECT cube(cube(1,1), 42, 42); -- cube_c_f8_f8
cube
---------
(1, 42)
(1 row)
SELECT cube(cube(1,1), 42, 24); -- cube_c_f8_f8
cube
-----------------
(1, 42),(1, 24)
(1 row)
SELECT cube(cube(1,2), 42, 42); -- cube_c_f8_f8
cube
-----------------
(1, 42),(2, 42)
(1 row)
SELECT cube(cube(1,2), 42, 24); -- cube_c_f8_f8
cube
-----------------
(1, 42),(2, 24)
(1 row)
-- --
-- Testing limit of CUBE_MAX_DIM dimensions check in cube_in. -- Testing limit of CUBE_MAX_DIM dimensions check in cube_in.
-- --
...@@ -878,6 +955,24 @@ SELECT cube_distance('(0)'::cube,'(.3,.4)'::cube); ...@@ -878,6 +955,24 @@ SELECT cube_distance('(0)'::cube,'(.3,.4)'::cube);
0.5 0.5
(1 row) (1 row)
SELECT cube_distance('(2,3,4)'::cube,'(2,3,4)'::cube);
cube_distance
---------------
0
(1 row)
SELECT cube_distance('(42,42,42,42)'::cube,'(137,137,137,137)'::cube);
cube_distance
---------------
190
(1 row)
SELECT cube_distance('(42,42,42)'::cube,'(137,137)'::cube);
cube_distance
------------------
140.762210837994
(1 row)
-- Test of cube function (text to cube) -- Test of cube function (text to cube)
-- --
SELECT cube('(1,1.2)'::text); SELECT cube('(1,1.2)'::text);
...@@ -912,6 +1007,18 @@ SELECT cube_dim('(0,0,0)'::cube); ...@@ -912,6 +1007,18 @@ SELECT cube_dim('(0,0,0)'::cube);
3 3
(1 row) (1 row)
SELECT cube_dim('(42,42,42),(42,42,42)'::cube);
cube_dim
----------
3
(1 row)
SELECT cube_dim('(4,8,15,16,23),(4,8,15,16,23)'::cube);
cube_dim
----------
5
(1 row)
-- Test of cube_ll_coord function (retrieves LL coodinate values) -- Test of cube_ll_coord function (retrieves LL coodinate values)
-- --
SELECT cube_ll_coord('(-1,1),(2,-2)'::cube, 1); SELECT cube_ll_coord('(-1,1),(2,-2)'::cube, 1);
...@@ -932,6 +1039,42 @@ SELECT cube_ll_coord('(-1,1),(2,-2)'::cube, 3); ...@@ -932,6 +1039,42 @@ SELECT cube_ll_coord('(-1,1),(2,-2)'::cube, 3);
0 0
(1 row) (1 row)
SELECT cube_ll_coord('(1,2),(1,2)'::cube, 1);
cube_ll_coord
---------------
1
(1 row)
SELECT cube_ll_coord('(1,2),(1,2)'::cube, 2);
cube_ll_coord
---------------
2
(1 row)
SELECT cube_ll_coord('(1,2),(1,2)'::cube, 3);
cube_ll_coord
---------------
0
(1 row)
SELECT cube_ll_coord('(42,137)'::cube, 1);
cube_ll_coord
---------------
42
(1 row)
SELECT cube_ll_coord('(42,137)'::cube, 2);
cube_ll_coord
---------------
137
(1 row)
SELECT cube_ll_coord('(42,137)'::cube, 3);
cube_ll_coord
---------------
0
(1 row)
-- Test of cube_ur_coord function (retrieves UR coodinate values) -- Test of cube_ur_coord function (retrieves UR coodinate values)
-- --
SELECT cube_ur_coord('(-1,1),(2,-2)'::cube, 1); SELECT cube_ur_coord('(-1,1),(2,-2)'::cube, 1);
...@@ -952,6 +1095,42 @@ SELECT cube_ur_coord('(-1,1),(2,-2)'::cube, 3); ...@@ -952,6 +1095,42 @@ SELECT cube_ur_coord('(-1,1),(2,-2)'::cube, 3);
0 0
(1 row) (1 row)
SELECT cube_ur_coord('(1,2),(1,2)'::cube, 1);
cube_ur_coord
---------------
1
(1 row)
SELECT cube_ur_coord('(1,2),(1,2)'::cube, 2);
cube_ur_coord
---------------
2
(1 row)
SELECT cube_ur_coord('(1,2),(1,2)'::cube, 3);
cube_ur_coord
---------------
0
(1 row)
SELECT cube_ur_coord('(42,137)'::cube, 1);
cube_ur_coord
---------------
42
(1 row)
SELECT cube_ur_coord('(42,137)'::cube, 2);
cube_ur_coord
---------------
137
(1 row)
SELECT cube_ur_coord('(42,137)'::cube, 3);
cube_ur_coord
---------------
0
(1 row)
-- Test of cube_is_point -- Test of cube_is_point
-- --
SELECT cube_is_point('(0)'::cube); SELECT cube_is_point('(0)'::cube);
...@@ -1100,6 +1279,108 @@ SELECT cube_enlarge('(2,-2),(-3,7)'::cube, -3, 2); ...@@ -1100,6 +1279,108 @@ SELECT cube_enlarge('(2,-2),(-3,7)'::cube, -3, 2);
(-0.5, 1),(-0.5, 4) (-0.5, 1),(-0.5, 4)
(1 row) (1 row)
SELECT cube_enlarge('(42,-23,-23),(42,23,23)'::cube, -23, 5);
cube_enlarge
--------------
(42, 0, 0)
(1 row)
SELECT cube_enlarge('(42,-23,-23),(42,23,23)'::cube, -24, 5);
cube_enlarge
--------------
(42, 0, 0)
(1 row)
-- Test of cube_union (MBR for two cubes)
--
SELECT cube_union('(1,2),(3,4)'::cube, '(5,6,7),(8,9,10)'::cube);
cube_union
----------------------
(1, 2, 0),(8, 9, 10)
(1 row)
SELECT cube_union('(1,2)'::cube, '(4,2,0,0)'::cube);
cube_union
---------------------------
(1, 2, 0, 0),(4, 2, 0, 0)
(1 row)
SELECT cube_union('(1,2),(1,2)'::cube, '(4,2),(4,2)'::cube);
cube_union
---------------
(1, 2),(4, 2)
(1 row)
SELECT cube_union('(1,2),(1,2)'::cube, '(1,2),(1,2)'::cube);
cube_union
------------
(1, 2)
(1 row)
SELECT cube_union('(1,2),(1,2)'::cube, '(1,2,0),(1,2,0)'::cube);
cube_union
------------
(1, 2, 0)
(1 row)
-- Test of cube_inter
--
SELECT cube_inter('(1,2),(10,11)'::cube, '(3,4), (16,15)'::cube); -- intersects
cube_inter
-----------------
(3, 4),(10, 11)
(1 row)
SELECT cube_inter('(1,2),(10,11)'::cube, '(3,4), (6,5)'::cube); -- includes
cube_inter
---------------
(3, 4),(6, 5)
(1 row)
SELECT cube_inter('(1,2),(10,11)'::cube, '(13,14), (16,15)'::cube); -- no intersection
cube_inter
-------------------
(13, 14),(10, 11)
(1 row)
SELECT cube_inter('(1,2),(10,11)'::cube, '(3,14), (16,15)'::cube); -- no intersection, but one dimension intersects
cube_inter
------------------
(3, 14),(10, 11)
(1 row)
SELECT cube_inter('(1,2),(10,11)'::cube, '(10,11), (16,15)'::cube); -- point intersection
cube_inter
------------
(10, 11)
(1 row)
SELECT cube_inter('(1,2,3)'::cube, '(1,2,3)'::cube); -- point args
cube_inter
------------
(1, 2, 3)
(1 row)
SELECT cube_inter('(1,2,3)'::cube, '(5,6,3)'::cube); -- point args
cube_inter
---------------------
(5, 6, 3),(1, 2, 3)
(1 row)
-- Test of cube_size
--
SELECT cube_size('(4,8),(15,16)'::cube);
cube_size
-----------
88
(1 row)
SELECT cube_size('(42,137)'::cube);
cube_size
-----------
0
(1 row)
-- Load some example data and build the index -- Load some example data and build the index
-- --
CREATE TABLE test_cube (c cube); CREATE TABLE test_cube (c cube);
......
...@@ -112,7 +112,24 @@ SELECT cube('{0,1,2}'::float[], '{3}'::float[]); ...@@ -112,7 +112,24 @@ SELECT cube('{0,1,2}'::float[], '{3}'::float[]);
SELECT cube(NULL::float[], '{3}'::float[]); SELECT cube(NULL::float[], '{3}'::float[]);
SELECT cube('{0,1,2}'::float[]); SELECT cube('{0,1,2}'::float[]);
SELECT cube_subset(cube('(1,3,5),(6,7,8)'), ARRAY[3,2,1,1]); SELECT cube_subset(cube('(1,3,5),(6,7,8)'), ARRAY[3,2,1,1]);
SELECT cube_subset(cube('(1,3,5),(1,3,5)'), ARRAY[3,2,1,1]);
SELECT cube_subset(cube('(1,3,5),(6,7,8)'), ARRAY[4,0]); SELECT cube_subset(cube('(1,3,5),(6,7,8)'), ARRAY[4,0]);
SELECT cube_subset(cube('(6,7,8),(6,7,8)'), ARRAY[4,0]);
--
-- Test point processing
--
SELECT cube('(1,2),(1,2)'); -- cube_in
SELECT cube('{0,1,2}'::float[], '{0,1,2}'::float[]); -- cube_a_f8_f8
SELECT cube('{5,6,7,8}'::float[]); -- cube_a_f8
SELECT cube(1.37); -- cube_f8
SELECT cube(1.37, 1.37); -- cube_f8_f8
SELECT cube(cube(1,1), 42); -- cube_c_f8
SELECT cube(cube(1,2), 42); -- cube_c_f8
SELECT cube(cube(1,1), 42, 42); -- cube_c_f8_f8
SELECT cube(cube(1,1), 42, 24); -- cube_c_f8_f8
SELECT cube(cube(1,2), 42, 42); -- cube_c_f8_f8
SELECT cube(cube(1,2), 42, 24); -- cube_c_f8_f8
-- --
-- Testing limit of CUBE_MAX_DIM dimensions check in cube_in. -- Testing limit of CUBE_MAX_DIM dimensions check in cube_in.
...@@ -212,6 +229,9 @@ SELECT '(-1,-1),(1,1)'::cube @> '(-2),(1)'::cube AS bool; ...@@ -212,6 +229,9 @@ SELECT '(-1,-1),(1,1)'::cube @> '(-2),(1)'::cube AS bool;
-- --
SELECT cube_distance('(0)'::cube,'(2,2,2,2)'::cube); SELECT cube_distance('(0)'::cube,'(2,2,2,2)'::cube);
SELECT cube_distance('(0)'::cube,'(.3,.4)'::cube); SELECT cube_distance('(0)'::cube,'(.3,.4)'::cube);
SELECT cube_distance('(2,3,4)'::cube,'(2,3,4)'::cube);
SELECT cube_distance('(42,42,42,42)'::cube,'(137,137,137,137)'::cube);
SELECT cube_distance('(42,42,42)'::cube,'(137,137)'::cube);
-- Test of cube function (text to cube) -- Test of cube function (text to cube)
-- --
...@@ -223,18 +243,32 @@ SELECT cube(NULL); ...@@ -223,18 +243,32 @@ SELECT cube(NULL);
SELECT cube_dim('(0)'::cube); SELECT cube_dim('(0)'::cube);
SELECT cube_dim('(0,0)'::cube); SELECT cube_dim('(0,0)'::cube);
SELECT cube_dim('(0,0,0)'::cube); SELECT cube_dim('(0,0,0)'::cube);
SELECT cube_dim('(42,42,42),(42,42,42)'::cube);
SELECT cube_dim('(4,8,15,16,23),(4,8,15,16,23)'::cube);
-- Test of cube_ll_coord function (retrieves LL coodinate values) -- Test of cube_ll_coord function (retrieves LL coodinate values)
-- --
SELECT cube_ll_coord('(-1,1),(2,-2)'::cube, 1); SELECT cube_ll_coord('(-1,1),(2,-2)'::cube, 1);
SELECT cube_ll_coord('(-1,1),(2,-2)'::cube, 2); SELECT cube_ll_coord('(-1,1),(2,-2)'::cube, 2);
SELECT cube_ll_coord('(-1,1),(2,-2)'::cube, 3); SELECT cube_ll_coord('(-1,1),(2,-2)'::cube, 3);
SELECT cube_ll_coord('(1,2),(1,2)'::cube, 1);
SELECT cube_ll_coord('(1,2),(1,2)'::cube, 2);
SELECT cube_ll_coord('(1,2),(1,2)'::cube, 3);
SELECT cube_ll_coord('(42,137)'::cube, 1);
SELECT cube_ll_coord('(42,137)'::cube, 2);
SELECT cube_ll_coord('(42,137)'::cube, 3);
-- Test of cube_ur_coord function (retrieves UR coodinate values) -- Test of cube_ur_coord function (retrieves UR coodinate values)
-- --
SELECT cube_ur_coord('(-1,1),(2,-2)'::cube, 1); SELECT cube_ur_coord('(-1,1),(2,-2)'::cube, 1);
SELECT cube_ur_coord('(-1,1),(2,-2)'::cube, 2); SELECT cube_ur_coord('(-1,1),(2,-2)'::cube, 2);
SELECT cube_ur_coord('(-1,1),(2,-2)'::cube, 3); SELECT cube_ur_coord('(-1,1),(2,-2)'::cube, 3);
SELECT cube_ur_coord('(1,2),(1,2)'::cube, 1);
SELECT cube_ur_coord('(1,2),(1,2)'::cube, 2);
SELECT cube_ur_coord('(1,2),(1,2)'::cube, 3);
SELECT cube_ur_coord('(42,137)'::cube, 1);
SELECT cube_ur_coord('(42,137)'::cube, 2);
SELECT cube_ur_coord('(42,137)'::cube, 3);
-- Test of cube_is_point -- Test of cube_is_point
-- --
...@@ -265,6 +299,31 @@ SELECT cube_enlarge('(2,-2),(-3,7)'::cube, 1, 2); ...@@ -265,6 +299,31 @@ SELECT cube_enlarge('(2,-2),(-3,7)'::cube, 1, 2);
SELECT cube_enlarge('(2,-2),(-3,7)'::cube, 3, 2); SELECT cube_enlarge('(2,-2),(-3,7)'::cube, 3, 2);
SELECT cube_enlarge('(2,-2),(-3,7)'::cube, -1, 2); SELECT cube_enlarge('(2,-2),(-3,7)'::cube, -1, 2);
SELECT cube_enlarge('(2,-2),(-3,7)'::cube, -3, 2); SELECT cube_enlarge('(2,-2),(-3,7)'::cube, -3, 2);
SELECT cube_enlarge('(42,-23,-23),(42,23,23)'::cube, -23, 5);
SELECT cube_enlarge('(42,-23,-23),(42,23,23)'::cube, -24, 5);
-- Test of cube_union (MBR for two cubes)
--
SELECT cube_union('(1,2),(3,4)'::cube, '(5,6,7),(8,9,10)'::cube);
SELECT cube_union('(1,2)'::cube, '(4,2,0,0)'::cube);
SELECT cube_union('(1,2),(1,2)'::cube, '(4,2),(4,2)'::cube);
SELECT cube_union('(1,2),(1,2)'::cube, '(1,2),(1,2)'::cube);
SELECT cube_union('(1,2),(1,2)'::cube, '(1,2,0),(1,2,0)'::cube);
-- Test of cube_inter
--
SELECT cube_inter('(1,2),(10,11)'::cube, '(3,4), (16,15)'::cube); -- intersects
SELECT cube_inter('(1,2),(10,11)'::cube, '(3,4), (6,5)'::cube); -- includes
SELECT cube_inter('(1,2),(10,11)'::cube, '(13,14), (16,15)'::cube); -- no intersection
SELECT cube_inter('(1,2),(10,11)'::cube, '(3,14), (16,15)'::cube); -- no intersection, but one dimension intersects
SELECT cube_inter('(1,2),(10,11)'::cube, '(10,11), (16,15)'::cube); -- point intersection
SELECT cube_inter('(1,2,3)'::cube, '(1,2,3)'::cube); -- point args
SELECT cube_inter('(1,2,3)'::cube, '(5,6,3)'::cube); -- point args
-- Test of cube_size
--
SELECT cube_size('(4,8),(15,16)'::cube);
SELECT cube_size('(42,137)'::cube);
-- Load some example data and build the index -- Load some example data and build the index
-- --
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment