mirror of
https://github.com/postgres/postgres.git
synced 2025-04-20 00:42:27 +03:00
The changes I have made are described in CHANGES. This was based on
diffs to 7.3-devel and may not be applicable to 7.2. I have included a change covered by a previous bugfix patch I submitted (the problem with -.1 not being accepted by cube_in). It does not include a fix for the potential buffer overrun issue I reported for cube_yyerror in cubeparse.y. Bruno Wolff III
This commit is contained in:
parent
6d27cfdd89
commit
32784cddf1
@ -99,7 +99,7 @@ Tokens
|
|||||||
|
|
||||||
n [0-9]+
|
n [0-9]+
|
||||||
integer [+-]?{n}
|
integer [+-]?{n}
|
||||||
real [+-]?({n}\.{n}?)|(\.{n})
|
real [+-]?({n}\.{n}?|\.{n})
|
||||||
FLOAT ({integer}|{real})([eE]{integer})?
|
FLOAT ({integer}|{real})([eE]{integer})?
|
||||||
O_BRACKET \[
|
O_BRACKET \[
|
||||||
C_BRACKET \]
|
C_BRACKET \]
|
||||||
@ -182,8 +182,8 @@ t
|
|||||||
PRECISION
|
PRECISION
|
||||||
=========
|
=========
|
||||||
|
|
||||||
Values are stored internally as 32-bit floating point numbers. This means that
|
Values are stored internally as 64-bit floating point numbers. This means that
|
||||||
numbers with more than 7 significant digits will be truncated.
|
numbers with more than about 16 significant digits will be truncated.
|
||||||
|
|
||||||
|
|
||||||
USAGE
|
USAGE
|
||||||
@ -253,6 +253,44 @@ Other operators:
|
|||||||
reasonably good sorting in most cases, which is useful if
|
reasonably good sorting in most cases, which is useful if
|
||||||
you want to use ORDER BY with this type
|
you want to use ORDER BY with this type
|
||||||
|
|
||||||
|
The following functions are available:
|
||||||
|
|
||||||
|
cube_distance(cube, cube) returns double
|
||||||
|
cube_distance returns the distance between two cubes. If both cubes are
|
||||||
|
points, this is the normal distance function.
|
||||||
|
|
||||||
|
cube(text) returns cube
|
||||||
|
cube takes text input and returns a cube. This is useful for making cubes
|
||||||
|
from computed strings.
|
||||||
|
|
||||||
|
cube_dim(cube) returns int
|
||||||
|
cube_dim returns the number of dimensions stored in the the data structure
|
||||||
|
for a cube. This is useful for constraints on the dimensions of a cube.
|
||||||
|
|
||||||
|
cube_ll_coord(cube, int) returns double
|
||||||
|
cube_ll_coord returns the nth coordinate value for the lower left corner
|
||||||
|
of a cube. This is useful for doing coordinate transformations.
|
||||||
|
|
||||||
|
cube_ur_coord(cube, int) returns double
|
||||||
|
cube_ur_coord returns the nth coordinate value for the upper right corner
|
||||||
|
of a cube. This is useful for doing coordinate transformations.
|
||||||
|
|
||||||
|
cube_is_point(cube) returns bool
|
||||||
|
cube_is_point returns true if a cube is also a point. This is true when the
|
||||||
|
two defining corners are the same.
|
||||||
|
|
||||||
|
cube_enlarge(cube, double, int) returns cube
|
||||||
|
cube_enlarge increases the size of a cube by a specified radius in at least
|
||||||
|
n dimensions. If the radius is negative the box is shrunk instead. This
|
||||||
|
is useful for creating bounding boxes around a point for searching for
|
||||||
|
nearby points. All defined dimensions are changed by the radius. If n
|
||||||
|
is greater than the number of defined dimensions and the cube is being
|
||||||
|
increased (r >= 0) then 0 is used as the base for the extra coordinates.
|
||||||
|
LL coordinates are decreased by r and UR coordinates are increased by r. If
|
||||||
|
a LL coordinate is increased to larger than the corresponding UR coordinate
|
||||||
|
(this can only happen when r < 0) than both coordinates are set to their
|
||||||
|
average.
|
||||||
|
|
||||||
There are a few other potentially useful functions defined in cube.c
|
There are a few other potentially useful functions defined in cube.c
|
||||||
that vanished from the schema because I stopped using them. Some of
|
that vanished from the schema because I stopped using them. Some of
|
||||||
these were meant to support type casting. Let me know if I was wrong:
|
these were meant to support type casting. Let me know if I was wrong:
|
||||||
@ -287,3 +325,11 @@ Building 221
|
|||||||
Argonne, IL 60439-4844
|
Argonne, IL 60439-4844
|
||||||
|
|
||||||
selkovjr@mcs.anl.gov
|
selkovjr@mcs.anl.gov
|
||||||
|
|
||||||
|
------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Minor updates to this package were made by Bruno Wolff III <bruno@wolff.to>
|
||||||
|
in August of 2002.
|
||||||
|
|
||||||
|
These include changing the precision from single precision to double
|
||||||
|
precision and adding some new functions.
|
||||||
|
@ -28,6 +28,7 @@ extern int cube_yyparse();
|
|||||||
** Input/Output routines
|
** Input/Output routines
|
||||||
*/
|
*/
|
||||||
NDBOX *cube_in(char *str);
|
NDBOX *cube_in(char *str);
|
||||||
|
NDBOX *cube(text *str);
|
||||||
char *cube_out(NDBOX * cube);
|
char *cube_out(NDBOX * cube);
|
||||||
|
|
||||||
|
|
||||||
@ -55,8 +56,8 @@ bool cube_contained(NDBOX * a, NDBOX * b);
|
|||||||
bool cube_overlap(NDBOX * a, NDBOX * b);
|
bool cube_overlap(NDBOX * a, NDBOX * b);
|
||||||
NDBOX *cube_union(NDBOX * a, NDBOX * b);
|
NDBOX *cube_union(NDBOX * a, NDBOX * b);
|
||||||
NDBOX *cube_inter(NDBOX * a, NDBOX * b);
|
NDBOX *cube_inter(NDBOX * a, NDBOX * b);
|
||||||
float *cube_size(NDBOX * a);
|
double *cube_size(NDBOX * a);
|
||||||
void rt_cube_size(NDBOX * a, float *sz);
|
void rt_cube_size(NDBOX * a, double *sz);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** These make no sense for this type, but R-tree wants them
|
** These make no sense for this type, but R-tree wants them
|
||||||
@ -71,13 +72,18 @@ bool cube_right(NDBOX * a, NDBOX * b);
|
|||||||
*/
|
*/
|
||||||
bool cube_lt(NDBOX * a, NDBOX * b);
|
bool cube_lt(NDBOX * a, NDBOX * b);
|
||||||
bool cube_gt(NDBOX * a, NDBOX * b);
|
bool cube_gt(NDBOX * a, NDBOX * b);
|
||||||
float *cube_distance(NDBOX * a, NDBOX * b);
|
double *cube_distance(NDBOX * a, NDBOX * b);
|
||||||
|
int cube_dim(NDBOX *a);
|
||||||
|
double *cube_ll_coord(NDBOX * a, int n);
|
||||||
|
double *cube_ur_coord(NDBOX * a, int n);
|
||||||
|
bool cube_is_point(NDBOX * a);
|
||||||
|
NDBOX *cube_enlarge(NDBOX * a, double * r, int n);
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Auxiliary funxtions
|
** Auxiliary funxtions
|
||||||
*/
|
*/
|
||||||
static float distance_1D(float a1, float a2, float b1, float b2);
|
static double distance_1D(double a1, double a2, double b1, double b2);
|
||||||
static NDBOX *swap_corners(NDBOX * a);
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
@ -99,6 +105,15 @@ cube_in(char *str)
|
|||||||
return ((NDBOX *) result);
|
return ((NDBOX *) result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Allow conversion from text to cube to allow input of computed strings */
|
||||||
|
/* There may be issues with toasted data here. I don't know enough to be sure.*/
|
||||||
|
NDBOX *
|
||||||
|
cube(text *str)
|
||||||
|
{
|
||||||
|
return cube_in(DatumGetCString(DirectFunctionCall1(textout,
|
||||||
|
PointerGetDatum(str))));
|
||||||
|
}
|
||||||
|
|
||||||
char *
|
char *
|
||||||
cube_out(NDBOX *cube)
|
cube_out(NDBOX *cube)
|
||||||
{
|
{
|
||||||
@ -118,7 +133,7 @@ cube_out(NDBOX *cube)
|
|||||||
{
|
{
|
||||||
if (i > 0)
|
if (i > 0)
|
||||||
appendStringInfo(&buf, ", ");
|
appendStringInfo(&buf, ", ");
|
||||||
appendStringInfo(&buf, "%g", cube->x[i]);
|
appendStringInfo(&buf, "%.16g", cube->x[i]);
|
||||||
if (cube->x[i] != cube->x[i + dim])
|
if (cube->x[i] != cube->x[i + dim])
|
||||||
equal = false;
|
equal = false;
|
||||||
}
|
}
|
||||||
@ -131,7 +146,7 @@ cube_out(NDBOX *cube)
|
|||||||
{
|
{
|
||||||
if (i > 0)
|
if (i > 0)
|
||||||
appendStringInfo(&buf, ", ");
|
appendStringInfo(&buf, ", ");
|
||||||
appendStringInfo(&buf, "%g", cube->x[i + dim]);
|
appendStringInfo(&buf, "%.16g", cube->x[i + dim]);
|
||||||
}
|
}
|
||||||
appendStringInfoChar(&buf, ')');
|
appendStringInfoChar(&buf, ')');
|
||||||
}
|
}
|
||||||
@ -228,14 +243,14 @@ float *
|
|||||||
g_cube_penalty(GISTENTRY *origentry, GISTENTRY *newentry, float *result)
|
g_cube_penalty(GISTENTRY *origentry, GISTENTRY *newentry, float *result)
|
||||||
{
|
{
|
||||||
NDBOX *ud;
|
NDBOX *ud;
|
||||||
float tmp1,
|
double tmp1,
|
||||||
tmp2;
|
tmp2;
|
||||||
|
|
||||||
ud = cube_union((NDBOX *) DatumGetPointer(origentry->key),
|
ud = cube_union((NDBOX *) DatumGetPointer(origentry->key),
|
||||||
(NDBOX *) DatumGetPointer(newentry->key));
|
(NDBOX *) DatumGetPointer(newentry->key));
|
||||||
rt_cube_size(ud, &tmp1);
|
rt_cube_size(ud, &tmp1);
|
||||||
rt_cube_size((NDBOX *) DatumGetPointer(origentry->key), &tmp2);
|
rt_cube_size((NDBOX *) DatumGetPointer(origentry->key), &tmp2);
|
||||||
*result = tmp1 - tmp2;
|
*result = (float) (tmp1 - tmp2);
|
||||||
pfree(ud);
|
pfree(ud);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -265,13 +280,13 @@ g_cube_picksplit(bytea *entryvec,
|
|||||||
*union_dr;
|
*union_dr;
|
||||||
NDBOX *inter_d;
|
NDBOX *inter_d;
|
||||||
bool firsttime;
|
bool firsttime;
|
||||||
float size_alpha,
|
double size_alpha,
|
||||||
size_beta,
|
size_beta,
|
||||||
size_union,
|
size_union,
|
||||||
size_inter;
|
size_inter;
|
||||||
float size_waste,
|
double size_waste,
|
||||||
waste;
|
waste;
|
||||||
float size_l,
|
double size_l,
|
||||||
size_r;
|
size_r;
|
||||||
int nbytes;
|
int nbytes;
|
||||||
OffsetNumber seed_1 = 0,
|
OffsetNumber seed_1 = 0,
|
||||||
@ -519,22 +534,22 @@ g_cube_binary_union(NDBOX * r1, NDBOX * r2, int *sizep)
|
|||||||
|
|
||||||
/* cube_union */
|
/* cube_union */
|
||||||
NDBOX *
|
NDBOX *
|
||||||
cube_union(NDBOX * box_a, NDBOX * box_b)
|
cube_union(NDBOX * a, NDBOX * b)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
NDBOX *result;
|
NDBOX *result;
|
||||||
NDBOX *a = swap_corners(box_a);
|
|
||||||
NDBOX *b = swap_corners(box_b);
|
|
||||||
|
|
||||||
if (a->dim >= b->dim)
|
if (a->dim >= b->dim)
|
||||||
{
|
{
|
||||||
result = palloc(a->size);
|
result = palloc(a->size);
|
||||||
|
memset(result, 0, a->size);
|
||||||
result->size = a->size;
|
result->size = a->size;
|
||||||
result->dim = a->dim;
|
result->dim = a->dim;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
result = palloc(b->size);
|
result = palloc(b->size);
|
||||||
|
memset(result, 0, b->size);
|
||||||
result->size = b->size;
|
result->size = b->size;
|
||||||
result->dim = b->dim;
|
result->dim = b->dim;
|
||||||
}
|
}
|
||||||
@ -554,8 +569,8 @@ cube_union(NDBOX * box_a, NDBOX * box_b)
|
|||||||
*/
|
*/
|
||||||
for (i = 0; i < b->dim; i++)
|
for (i = 0; i < b->dim; i++)
|
||||||
{
|
{
|
||||||
result->x[i] = b->x[i];
|
result->x[i] = min(b->x[i], b->x[i + b->dim]);
|
||||||
result->x[i + a->dim] = b->x[i + b->dim];
|
result->x[i + a->dim] = max(b->x[i], b->x[i + b->dim]);
|
||||||
}
|
}
|
||||||
for (i = b->dim; i < a->dim; i++)
|
for (i = b->dim; i < a->dim; i++)
|
||||||
{
|
{
|
||||||
@ -565,34 +580,34 @@ cube_union(NDBOX * box_a, NDBOX * box_b)
|
|||||||
|
|
||||||
/* compute the union */
|
/* compute the union */
|
||||||
for (i = 0; i < a->dim; i++)
|
for (i = 0; i < a->dim; i++)
|
||||||
result->x[i] = min(a->x[i], result->x[i]);
|
{
|
||||||
for (i = a->dim; i < a->dim * 2; i++)
|
result->x[i] =
|
||||||
result->x[i] = max(a->x[i], result->x[i]);
|
min(min(a->x[i], a->x[i + a->dim]), result->x[i]);
|
||||||
|
result->x[i + a->dim] = max(max(a->x[i],
|
||||||
pfree(a);
|
a->x[i + a->dim]), result->x[i + a->dim]);
|
||||||
pfree(b);
|
}
|
||||||
|
|
||||||
return (result);
|
return (result);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* cube_inter */
|
/* cube_inter */
|
||||||
NDBOX *
|
NDBOX *
|
||||||
cube_inter(NDBOX * box_a, NDBOX * box_b)
|
cube_inter(NDBOX * a, NDBOX * b)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
NDBOX *result;
|
NDBOX *result;
|
||||||
NDBOX *a = swap_corners(box_a);
|
|
||||||
NDBOX *b = swap_corners(box_b);
|
|
||||||
|
|
||||||
if (a->dim >= b->dim)
|
if (a->dim >= b->dim)
|
||||||
{
|
{
|
||||||
result = palloc(a->size);
|
result = palloc(a->size);
|
||||||
|
memset(result, 0, a->size);
|
||||||
result->size = a->size;
|
result->size = a->size;
|
||||||
result->dim = a->dim;
|
result->dim = a->dim;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
result = palloc(b->size);
|
result = palloc(b->size);
|
||||||
|
memset(result, 0, b->size);
|
||||||
result->size = b->size;
|
result->size = b->size;
|
||||||
result->dim = b->dim;
|
result->dim = b->dim;
|
||||||
}
|
}
|
||||||
@ -612,8 +627,8 @@ cube_inter(NDBOX * box_a, NDBOX * box_b)
|
|||||||
*/
|
*/
|
||||||
for (i = 0; i < b->dim; i++)
|
for (i = 0; i < b->dim; i++)
|
||||||
{
|
{
|
||||||
result->x[i] = b->x[i];
|
result->x[i] = min(b->x[i], b->x[i + b->dim]);
|
||||||
result->x[i + a->dim] = b->x[i + b->dim];
|
result->x[i + a->dim] = max(b->x[i], b->x[i + b->dim]);
|
||||||
}
|
}
|
||||||
for (i = b->dim; i < a->dim; i++)
|
for (i = b->dim; i < a->dim; i++)
|
||||||
{
|
{
|
||||||
@ -623,12 +638,12 @@ cube_inter(NDBOX * box_a, NDBOX * box_b)
|
|||||||
|
|
||||||
/* compute the intersection */
|
/* compute the intersection */
|
||||||
for (i = 0; i < a->dim; i++)
|
for (i = 0; i < a->dim; i++)
|
||||||
result->x[i] = max(a->x[i], result->x[i]);
|
{
|
||||||
for (i = a->dim; i < a->dim * 2; i++)
|
result->x[i] =
|
||||||
result->x[i] = min(a->x[i], result->x[i]);
|
max(min(a->x[i], a->x[i + a->dim]), result->x[i]);
|
||||||
|
result->x[i + a->dim] = min(max(a->x[i],
|
||||||
pfree(a);
|
a->x[i + a->dim]), result->x[i + a->dim]);
|
||||||
pfree(b);
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Is it OK to return a non-null intersection for non-overlapping
|
* Is it OK to return a non-null intersection for non-overlapping
|
||||||
@ -638,14 +653,14 @@ cube_inter(NDBOX * box_a, NDBOX * box_b)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* cube_size */
|
/* cube_size */
|
||||||
float *
|
double *
|
||||||
cube_size(NDBOX * a)
|
cube_size(NDBOX * a)
|
||||||
{
|
{
|
||||||
int i,
|
int i,
|
||||||
j;
|
j;
|
||||||
float *result;
|
double *result;
|
||||||
|
|
||||||
result = (float *) palloc(sizeof(float));
|
result = (double *) palloc(sizeof(double));
|
||||||
|
|
||||||
*result = 1.0;
|
*result = 1.0;
|
||||||
for (i = 0, j = a->dim; i < a->dim; i++, j++)
|
for (i = 0, j = a->dim; i < a->dim; i++, j++)
|
||||||
@ -655,7 +670,7 @@ cube_size(NDBOX * a)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rt_cube_size(NDBOX * a, float *size)
|
rt_cube_size(NDBOX * a, double *size)
|
||||||
{
|
{
|
||||||
int i,
|
int i,
|
||||||
j;
|
j;
|
||||||
@ -679,114 +694,84 @@ rt_cube_size(NDBOX * a, float *size)
|
|||||||
/* is the right edge of (a) located to the left of
|
/* is the right edge of (a) located to the left of
|
||||||
the right edge of (b)? */
|
the right edge of (b)? */
|
||||||
bool
|
bool
|
||||||
cube_over_left(NDBOX * box_a, NDBOX * box_b)
|
cube_over_left(NDBOX * a, NDBOX * b)
|
||||||
{
|
{
|
||||||
NDBOX *a;
|
if ((a == NULL) || (b == NULL))
|
||||||
NDBOX *b;
|
|
||||||
|
|
||||||
if ((box_a == NULL) || (box_b == NULL))
|
|
||||||
return (FALSE);
|
return (FALSE);
|
||||||
|
|
||||||
a = swap_corners(box_a);
|
return (min(a->x[a->dim - 1], a->x[2 * a->dim - 1]) <=
|
||||||
b = swap_corners(box_b);
|
min(b->x[b->dim - 1], b->x[2 * b->dim - 1]) &&
|
||||||
|
!cube_left(a, b) && !cube_right(a, b));
|
||||||
return (a->x[a->dim - 1] <= b->x[b->dim - 1] && !cube_left(a, b) && !cube_right(a, b));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* is the left edge of (a) located to the right of
|
/* is the left edge of (a) located to the right of
|
||||||
the left edge of (b)? */
|
the left edge of (b)? */
|
||||||
bool
|
bool
|
||||||
cube_over_right(NDBOX * box_a, NDBOX * box_b)
|
cube_over_right(NDBOX * a, NDBOX * b)
|
||||||
{
|
{
|
||||||
NDBOX *a;
|
if ((a == NULL) || (b == NULL))
|
||||||
NDBOX *b;
|
|
||||||
|
|
||||||
if ((box_a == NULL) || (box_b == NULL))
|
|
||||||
return (FALSE);
|
return (FALSE);
|
||||||
|
|
||||||
a = swap_corners(box_a);
|
return (min(a->x[a->dim - 1], a->x[2 * a->dim - 1]) >=
|
||||||
b = swap_corners(box_b);
|
min(b->x[b->dim - 1], b->x[2 * b->dim - 1]) &&
|
||||||
|
!cube_left(a, b) && !cube_right(a, b));
|
||||||
return (a->x[a->dim - 1] >= b->x[b->dim - 1] && !cube_left(a, b) && !cube_right(a, b));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* return 'true' if the projection of 'a' is
|
/* return 'true' if the projection of 'a' is
|
||||||
entirely on the left of the projection of 'b' */
|
entirely on the left of the projection of 'b' */
|
||||||
bool
|
bool
|
||||||
cube_left(NDBOX * box_a, NDBOX * box_b)
|
cube_left(NDBOX * a, NDBOX * b)
|
||||||
{
|
{
|
||||||
NDBOX *a;
|
if ((a == NULL) || (b == NULL))
|
||||||
NDBOX *b;
|
|
||||||
|
|
||||||
if ((box_a == NULL) || (box_b == NULL))
|
|
||||||
return (FALSE);
|
return (FALSE);
|
||||||
|
|
||||||
a = swap_corners(box_a);
|
return (min(a->x[a->dim - 1], a->x[2 * a->dim - 1]) <
|
||||||
b = swap_corners(box_b);
|
min(b->x[0], b->x[b->dim]));
|
||||||
|
|
||||||
return (a->x[a->dim - 1] < b->x[0]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* return 'true' if the projection of 'a' is
|
/* return 'true' if the projection of 'a' is
|
||||||
entirely on the right of the projection of 'b' */
|
entirely on the right of the projection of 'b' */
|
||||||
bool
|
bool
|
||||||
cube_right(NDBOX * box_a, NDBOX * box_b)
|
cube_right(NDBOX * a, NDBOX * b)
|
||||||
{
|
{
|
||||||
NDBOX *a;
|
if ((a == NULL) || (b == NULL))
|
||||||
NDBOX *b;
|
|
||||||
|
|
||||||
if ((box_a == NULL) || (box_b == NULL))
|
|
||||||
return (FALSE);
|
return (FALSE);
|
||||||
|
|
||||||
a = swap_corners(box_a);
|
return (min(a->x[0], a->x[a->dim]) >
|
||||||
b = swap_corners(box_b);
|
min(b->x[b->dim - 1], b->x[2 * b->dim - 1]));
|
||||||
|
|
||||||
return (a->x[0] > b->x[b->dim - 1]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* make up a metric in which one box will be 'lower' than the other
|
/* make up a metric in which one box will be 'lower' than the other
|
||||||
-- this can be useful for srting and to determine uniqueness */
|
-- this can be useful for sorting and to determine uniqueness */
|
||||||
bool
|
bool
|
||||||
cube_lt(NDBOX * box_a, NDBOX * box_b)
|
cube_lt(NDBOX * a, NDBOX * b)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int dim;
|
int dim;
|
||||||
NDBOX *a;
|
|
||||||
NDBOX *b;
|
|
||||||
|
|
||||||
if ((box_a == NULL) || (box_b == NULL))
|
if ((a == NULL) || (b == NULL))
|
||||||
return (FALSE);
|
return (FALSE);
|
||||||
|
|
||||||
a = swap_corners(box_a);
|
|
||||||
b = swap_corners(box_b);
|
|
||||||
dim = min(a->dim, b->dim);
|
dim = min(a->dim, b->dim);
|
||||||
|
|
||||||
/*
|
|
||||||
* if all common dimensions are equal, the cube with more dimensions
|
|
||||||
* wins
|
|
||||||
*/
|
|
||||||
if (cube_same(a, b))
|
|
||||||
{
|
|
||||||
if (a->dim < b->dim)
|
|
||||||
return (TRUE);
|
|
||||||
else
|
|
||||||
return (FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* compare the common dimensions */
|
/* compare the common dimensions */
|
||||||
for (i = 0; i < dim; i++)
|
for (i = 0; i < dim; i++)
|
||||||
{
|
{
|
||||||
if (a->x[i] > b->x[i])
|
if (min(a->x[i], a->x[a->dim + i]) >
|
||||||
|
min(b->x[i], b->x[b->dim + i]))
|
||||||
return (FALSE);
|
return (FALSE);
|
||||||
if (a->x[i] < b->x[i])
|
if (min(a->x[i], a->x[a->dim + i]) <
|
||||||
|
min(b->x[i], b->x[b->dim + i]))
|
||||||
return (TRUE);
|
return (TRUE);
|
||||||
}
|
}
|
||||||
for (i = 0; i < dim; i++)
|
for (i = 0; i < dim; i++)
|
||||||
{
|
{
|
||||||
if (a->x[i + a->dim] > b->x[i + b->dim])
|
if (max(a->x[i], a->x[a->dim + i]) >
|
||||||
|
max(b->x[i], b->x[b->dim + i]))
|
||||||
return (FALSE);
|
return (FALSE);
|
||||||
if (a->x[i + a->dim] < b->x[i + b->dim])
|
if (max(a->x[i], a->x[a->dim + i]) <
|
||||||
|
max(b->x[i], b->x[b->dim + i]))
|
||||||
return (TRUE);
|
return (TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -795,35 +780,45 @@ cube_lt(NDBOX * box_a, NDBOX * box_b)
|
|||||||
{
|
{
|
||||||
for (i = dim; i < a->dim; i++)
|
for (i = dim; i < a->dim; i++)
|
||||||
{
|
{
|
||||||
if (a->x[i] > 0)
|
if (min(a->x[i], a->x[a->dim + i]) > 0)
|
||||||
return (FALSE);
|
return (FALSE);
|
||||||
if (a->x[i] < 0)
|
if (min(a->x[i], a->x[a->dim + i]) < 0)
|
||||||
return (TRUE);
|
return (TRUE);
|
||||||
}
|
}
|
||||||
for (i = 0; i < dim; i++)
|
for (i = dim; i < a->dim; i++)
|
||||||
{
|
{
|
||||||
if (a->x[i + a->dim] > 0)
|
if (max(a->x[i], a->x[a->dim + i]) > 0)
|
||||||
return (FALSE);
|
return (FALSE);
|
||||||
if (a->x[i + a->dim] < 0)
|
if (max(a->x[i], a->x[a->dim + i]) < 0)
|
||||||
return (TRUE);
|
return (TRUE);
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
* if all common dimensions are equal, the cube with more
|
||||||
|
* dimensions wins
|
||||||
|
*/
|
||||||
|
return (FALSE);
|
||||||
}
|
}
|
||||||
if (a->dim < b->dim)
|
if (a->dim < b->dim)
|
||||||
{
|
{
|
||||||
for (i = dim; i < b->dim; i++)
|
for (i = dim; i < b->dim; i++)
|
||||||
{
|
{
|
||||||
if (b->x[i] > 0)
|
if (min(b->x[i], b->x[b->dim + i]) > 0)
|
||||||
return (TRUE);
|
return (TRUE);
|
||||||
if (b->x[i] < 0)
|
if (min(b->x[i], b->x[b->dim + i]) < 0)
|
||||||
return (FALSE);
|
return (FALSE);
|
||||||
}
|
}
|
||||||
for (i = 0; i < dim; i++)
|
for (i = dim; i < b->dim; i++)
|
||||||
{
|
{
|
||||||
if (b->x[i + b->dim] > 0)
|
if (max(b->x[i], b->x[b->dim + i]) > 0)
|
||||||
return (TRUE);
|
return (TRUE);
|
||||||
if (b->x[i + b->dim] < 0)
|
if (max(b->x[i], b->x[b->dim + i]) < 0)
|
||||||
return (FALSE);
|
return (FALSE);
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
* if all common dimensions are equal, the cube with more
|
||||||
|
* dimensions wins
|
||||||
|
*/
|
||||||
|
return (TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (FALSE);
|
return (FALSE);
|
||||||
@ -831,45 +826,33 @@ cube_lt(NDBOX * box_a, NDBOX * box_b)
|
|||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
cube_gt(NDBOX * box_a, NDBOX * box_b)
|
cube_gt(NDBOX * a, NDBOX * b)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int dim;
|
int dim;
|
||||||
NDBOX *a;
|
|
||||||
NDBOX *b;
|
|
||||||
|
|
||||||
if ((box_a == NULL) || (box_b == NULL))
|
if ((a == NULL) || (b == NULL))
|
||||||
return (FALSE);
|
return (FALSE);
|
||||||
|
|
||||||
a = swap_corners(box_a);
|
|
||||||
b = swap_corners(box_b);
|
|
||||||
dim = min(a->dim, b->dim);
|
dim = min(a->dim, b->dim);
|
||||||
|
|
||||||
/*
|
|
||||||
* if all common dimensions are equal, the cube with more dimensions
|
|
||||||
* wins
|
|
||||||
*/
|
|
||||||
if (cube_same(a, b))
|
|
||||||
{
|
|
||||||
if (a->dim > b->dim)
|
|
||||||
return (TRUE);
|
|
||||||
else
|
|
||||||
return (FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* compare the common dimensions */
|
/* compare the common dimensions */
|
||||||
for (i = 0; i < dim; i++)
|
for (i = 0; i < dim; i++)
|
||||||
{
|
{
|
||||||
if (a->x[i] < b->x[i])
|
if (min(a->x[i], a->x[a->dim + i]) <
|
||||||
|
min(b->x[i], b->x[b->dim + i]))
|
||||||
return (FALSE);
|
return (FALSE);
|
||||||
if (a->x[i] > b->x[i])
|
if (min(a->x[i], a->x[a->dim + i]) >
|
||||||
|
min(b->x[i], b->x[b->dim + i]))
|
||||||
return (TRUE);
|
return (TRUE);
|
||||||
}
|
}
|
||||||
for (i = 0; i < dim; i++)
|
for (i = 0; i < dim; i++)
|
||||||
{
|
{
|
||||||
if (a->x[i + a->dim] < b->x[i + b->dim])
|
if (max(a->x[i], a->x[a->dim + i]) <
|
||||||
|
max(b->x[i], b->x[b->dim + i]))
|
||||||
return (FALSE);
|
return (FALSE);
|
||||||
if (a->x[i + a->dim] > b->x[i + b->dim])
|
if (max(a->x[i], a->x[a->dim + i]) >
|
||||||
|
max(b->x[i], b->x[b->dim + i]))
|
||||||
return (TRUE);
|
return (TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -879,35 +862,45 @@ cube_gt(NDBOX * box_a, NDBOX * box_b)
|
|||||||
{
|
{
|
||||||
for (i = dim; i < a->dim; i++)
|
for (i = dim; i < a->dim; i++)
|
||||||
{
|
{
|
||||||
if (a->x[i] < 0)
|
if (min(a->x[i], a->x[a->dim + i]) < 0)
|
||||||
return (FALSE);
|
return (FALSE);
|
||||||
if (a->x[i] > 0)
|
if (min(a->x[i], a->x[a->dim + i]) > 0)
|
||||||
return (TRUE);
|
return (TRUE);
|
||||||
}
|
}
|
||||||
for (i = 0; i < dim; i++)
|
for (i = dim; i < a->dim; i++)
|
||||||
{
|
{
|
||||||
if (a->x[i + a->dim] < 0)
|
if (max(a->x[i], a->x[a->dim + i]) < 0)
|
||||||
return (FALSE);
|
return (FALSE);
|
||||||
if (a->x[i + a->dim] > 0)
|
if (max(a->x[i], a->x[a->dim + i]) > 0)
|
||||||
return (TRUE);
|
return (TRUE);
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
* if all common dimensions are equal, the cube with more
|
||||||
|
* dimensions wins
|
||||||
|
*/
|
||||||
|
return (TRUE);
|
||||||
}
|
}
|
||||||
if (a->dim < b->dim)
|
if (a->dim < b->dim)
|
||||||
{
|
{
|
||||||
for (i = dim; i < b->dim; i++)
|
for (i = dim; i < b->dim; i++)
|
||||||
{
|
{
|
||||||
if (b->x[i] < 0)
|
if (min(b->x[i], b->x[b->dim + i]) < 0)
|
||||||
return (TRUE);
|
return (TRUE);
|
||||||
if (b->x[i] > 0)
|
if (min(b->x[i], b->x[b->dim + i]) > 0)
|
||||||
return (FALSE);
|
return (FALSE);
|
||||||
}
|
}
|
||||||
for (i = 0; i < dim; i++)
|
for (i = dim; i < b->dim; i++)
|
||||||
{
|
{
|
||||||
if (b->x[i + b->dim] < 0)
|
if (max(b->x[i], b->x[b->dim + i]) < 0)
|
||||||
return (TRUE);
|
return (TRUE);
|
||||||
if (b->x[i + b->dim] > 0)
|
if (max(b->x[i], b->x[b->dim + i]) > 0)
|
||||||
return (FALSE);
|
return (FALSE);
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
* if all common dimensions are equal, the cube with more
|
||||||
|
* dimensions wins
|
||||||
|
*/
|
||||||
|
return (FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (FALSE);
|
return (FALSE);
|
||||||
@ -916,18 +909,13 @@ cube_gt(NDBOX * box_a, NDBOX * box_b)
|
|||||||
|
|
||||||
/* Equal */
|
/* Equal */
|
||||||
bool
|
bool
|
||||||
cube_same(NDBOX * box_a, NDBOX * box_b)
|
cube_same(NDBOX * a, NDBOX * b)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
NDBOX *a;
|
|
||||||
NDBOX *b;
|
|
||||||
|
|
||||||
if ((box_a == NULL) || (box_b == NULL))
|
if ((a == NULL) || (b == NULL))
|
||||||
return (FALSE);
|
return (FALSE);
|
||||||
|
|
||||||
a = swap_corners(box_a);
|
|
||||||
b = swap_corners(box_b);
|
|
||||||
|
|
||||||
/* swap the box pointers if necessary */
|
/* swap the box pointers if necessary */
|
||||||
if (a->dim < b->dim)
|
if (a->dim < b->dim)
|
||||||
{
|
{
|
||||||
@ -939,15 +927,19 @@ cube_same(NDBOX * box_a, NDBOX * box_b)
|
|||||||
|
|
||||||
for (i = 0; i < b->dim; i++)
|
for (i = 0; i < b->dim; i++)
|
||||||
{
|
{
|
||||||
if (a->x[i] != b->x[i])
|
if (min(a->x[i], a->x[a->dim + i]) !=
|
||||||
|
min(b->x[i], b->x[b->dim + i]))
|
||||||
return (FALSE);
|
return (FALSE);
|
||||||
if (a->x[i + a->dim] != b->x[i + b->dim])
|
if (max(a->x[i], a->x[a->dim + i]) !=
|
||||||
|
max(b->x[i], b->x[b->dim + i]))
|
||||||
return (FALSE);
|
return (FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* all dimensions of (b) are compared to those of (a); instead of
|
* all dimensions of (b) are compared to those of (a); instead of
|
||||||
* those in (a) absent in (b), compare (a) to zero
|
* those in (a) absent in (b), compare (a) to zero
|
||||||
|
* Since both LL and UR coordinates are compared to zero, we can
|
||||||
|
* just check them all without worrying about which is which.
|
||||||
*/
|
*/
|
||||||
for (i = b->dim; i < a->dim; i++)
|
for (i = b->dim; i < a->dim; i++)
|
||||||
{
|
{
|
||||||
@ -957,40 +949,34 @@ cube_same(NDBOX * box_a, NDBOX * box_b)
|
|||||||
return (FALSE);
|
return (FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
pfree(a);
|
|
||||||
pfree(b);
|
|
||||||
|
|
||||||
return (TRUE);
|
return (TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Different */
|
/* Different */
|
||||||
bool
|
bool
|
||||||
cube_different(NDBOX * box_a, NDBOX * box_b)
|
cube_different(NDBOX * a, NDBOX * b)
|
||||||
{
|
{
|
||||||
return (!cube_same(box_a, box_b));
|
return (!cube_same(a, b));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Contains */
|
/* Contains */
|
||||||
/* Box(A) CONTAINS Box(B) IFF pt(A) < pt(B) */
|
/* Box(A) CONTAINS Box(B) IFF pt(A) < pt(B) */
|
||||||
bool
|
bool
|
||||||
cube_contains(NDBOX * box_a, NDBOX * box_b)
|
cube_contains(NDBOX * a, NDBOX * b)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
NDBOX *a;
|
|
||||||
NDBOX *b;
|
|
||||||
|
|
||||||
if ((box_a == NULL) || (box_b == NULL))
|
if ((a == NULL) || (b == NULL))
|
||||||
return (FALSE);
|
return (FALSE);
|
||||||
|
|
||||||
a = swap_corners(box_a);
|
|
||||||
b = swap_corners(box_b);
|
|
||||||
|
|
||||||
if (a->dim < b->dim)
|
if (a->dim < b->dim)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* the further comparisons will make sense if the excess
|
* the further comparisons will make sense if the excess
|
||||||
* dimensions of (b) were zeroes
|
* dimensions of (b) were zeroes
|
||||||
|
* Since both UL and UR coordinates must be zero, we can
|
||||||
|
* check them all without worrying about which is which.
|
||||||
*/
|
*/
|
||||||
for (i = a->dim; i < b->dim; i++)
|
for (i = a->dim; i < b->dim; i++)
|
||||||
{
|
{
|
||||||
@ -1004,15 +990,14 @@ cube_contains(NDBOX * box_a, NDBOX * box_b)
|
|||||||
/* Can't care less about the excess dimensions of (a), if any */
|
/* Can't care less about the excess dimensions of (a), if any */
|
||||||
for (i = 0; i < min(a->dim, b->dim); i++)
|
for (i = 0; i < min(a->dim, b->dim); i++)
|
||||||
{
|
{
|
||||||
if (a->x[i] > b->x[i])
|
if (min(a->x[i], a->x[a->dim + i]) >
|
||||||
|
min(b->x[i], b->x[b->dim + i]))
|
||||||
return (FALSE);
|
return (FALSE);
|
||||||
if (a->x[i + a->dim] < b->x[i + b->dim])
|
if (max(a->x[i], a->x[a->dim + i]) <
|
||||||
|
max(b->x[i], b->x[b->dim + i]))
|
||||||
return (FALSE);
|
return (FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
pfree(a);
|
|
||||||
pfree(b);
|
|
||||||
|
|
||||||
return (TRUE);
|
return (TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1030,22 +1015,17 @@ cube_contained(NDBOX * a, NDBOX * b)
|
|||||||
/* Overlap */
|
/* Overlap */
|
||||||
/* Box(A) Overlap Box(B) IFF (pt(a)LL < pt(B)UR) && (pt(b)LL < pt(a)UR) */
|
/* Box(A) Overlap Box(B) IFF (pt(a)LL < pt(B)UR) && (pt(b)LL < pt(a)UR) */
|
||||||
bool
|
bool
|
||||||
cube_overlap(NDBOX * box_a, NDBOX * box_b)
|
cube_overlap(NDBOX * a, NDBOX * b)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
NDBOX *a;
|
|
||||||
NDBOX *b;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This *very bad* error was found in the source: if ( (a==NULL) ||
|
* This *very bad* error was found in the source: if ( (a==NULL) ||
|
||||||
* (b=NULL) ) return(FALSE);
|
* (b=NULL) ) return(FALSE);
|
||||||
*/
|
*/
|
||||||
if ((box_a == NULL) || (box_b == NULL))
|
if ((a == NULL) || (b == NULL))
|
||||||
return (FALSE);
|
return (FALSE);
|
||||||
|
|
||||||
a = swap_corners(box_a);
|
|
||||||
b = swap_corners(box_b);
|
|
||||||
|
|
||||||
/* swap the box pointers if needed */
|
/* swap the box pointers if needed */
|
||||||
if (a->dim < b->dim)
|
if (a->dim < b->dim)
|
||||||
{
|
{
|
||||||
@ -1058,24 +1038,23 @@ cube_overlap(NDBOX * box_a, NDBOX * box_b)
|
|||||||
/* compare within the dimensions of (b) */
|
/* compare within the dimensions of (b) */
|
||||||
for (i = 0; i < b->dim; i++)
|
for (i = 0; i < b->dim; i++)
|
||||||
{
|
{
|
||||||
if (a->x[i] > b->x[i + b->dim])
|
if (min(a->x[i], a->x[a->dim + i]) >
|
||||||
|
max(b->x[i], b->x[b->dim + i]))
|
||||||
return (FALSE);
|
return (FALSE);
|
||||||
if (a->x[i + a->dim] < b->x[i])
|
if (max(a->x[i], a->x[a->dim + i]) <
|
||||||
|
min(b->x[i], b->x[b->dim + i]))
|
||||||
return (FALSE);
|
return (FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* compare to zero those dimensions in (a) absent in (b) */
|
/* compare to zero those dimensions in (a) absent in (b) */
|
||||||
for (i = b->dim; i < a->dim; i++)
|
for (i = b->dim; i < a->dim; i++)
|
||||||
{
|
{
|
||||||
if (a->x[i] > 0)
|
if (min(a->x[i], a->x[a->dim + i]) > 0)
|
||||||
return (FALSE);
|
return (FALSE);
|
||||||
if (a->x[i + a->dim] < 0)
|
if (max(a->x[i], a->x[a->dim + i]) < 0)
|
||||||
return (FALSE);
|
return (FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
pfree(a);
|
|
||||||
pfree(b);
|
|
||||||
|
|
||||||
return (TRUE);
|
return (TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1085,15 +1064,15 @@ cube_overlap(NDBOX * box_a, NDBOX * box_b)
|
|||||||
between 1D projections of the boxes onto Cartesian axes. Assuming zero
|
between 1D projections of the boxes onto Cartesian axes. Assuming zero
|
||||||
distance between overlapping projections, this metric coincides with the
|
distance between overlapping projections, this metric coincides with the
|
||||||
"common sense" geometric distance */
|
"common sense" geometric distance */
|
||||||
float *
|
double *
|
||||||
cube_distance(NDBOX * a, NDBOX * b)
|
cube_distance(NDBOX * a, NDBOX * b)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
double d,
|
double d,
|
||||||
distance;
|
distance;
|
||||||
float *result;
|
double *result;
|
||||||
|
|
||||||
result = (float *) palloc(sizeof(float));
|
result = (double *) palloc(sizeof(double));
|
||||||
|
|
||||||
/* swap the box pointers if needed */
|
/* swap the box pointers if needed */
|
||||||
if (a->dim < b->dim)
|
if (a->dim < b->dim)
|
||||||
@ -1119,13 +1098,13 @@ cube_distance(NDBOX * a, NDBOX * b)
|
|||||||
distance += d * d;
|
distance += d * d;
|
||||||
}
|
}
|
||||||
|
|
||||||
*result = (float) sqrt(distance);
|
*result = (double) sqrt(distance);
|
||||||
|
|
||||||
return (result);
|
return (result);
|
||||||
}
|
}
|
||||||
|
|
||||||
static float
|
static double
|
||||||
distance_1D(float a1, float a2, float b1, float b2)
|
distance_1D(double a1, double a2, double b1, double b2)
|
||||||
{
|
{
|
||||||
/* interval (a) is entirely on the left of (b) */
|
/* interval (a) is entirely on the left of (b) */
|
||||||
if ((a1 <= b1) && (a2 <= b1) && (a1 <= b2) && (a2 <= b2))
|
if ((a1 <= b1) && (a2 <= b1) && (a1 <= b2) && (a2 <= b2))
|
||||||
@ -1139,25 +1118,91 @@ distance_1D(float a1, float a2, float b1, float b2)
|
|||||||
return (0.0);
|
return (0.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* normalize the box's co-ordinates by placing min(xLL,xUR) to LL
|
/* Test if a box is also a point */
|
||||||
and max(xLL,xUR) to UR
|
bool
|
||||||
*/
|
cube_is_point(NDBOX * a)
|
||||||
static NDBOX *
|
|
||||||
swap_corners(NDBOX * a)
|
|
||||||
{
|
{
|
||||||
int i,
|
int i,
|
||||||
j;
|
j;
|
||||||
NDBOX *result;
|
|
||||||
|
|
||||||
result = palloc(a->size);
|
|
||||||
result->size = a->size;
|
|
||||||
result->dim = a->dim;
|
|
||||||
|
|
||||||
for (i = 0, j = a->dim; i < a->dim; i++, j++)
|
for (i = 0, j = a->dim; i < a->dim; i++, j++)
|
||||||
{
|
{
|
||||||
result->x[i] = min(a->x[i], a->x[j]);
|
if (a->x[i] != a->x[j]) return FALSE;
|
||||||
result->x[j] = max(a->x[i], a->x[j]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (result);
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return dimensions in use in the data structure */
|
||||||
|
int
|
||||||
|
cube_dim(NDBOX * a)
|
||||||
|
{
|
||||||
|
/* Other things will break before unsigned int doesn't fit. */
|
||||||
|
return a->dim;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return a specific normalized LL coordinate */
|
||||||
|
double *
|
||||||
|
cube_ll_coord(NDBOX * a, int n)
|
||||||
|
{
|
||||||
|
double *result;
|
||||||
|
result = (double *) palloc(sizeof(double));
|
||||||
|
*result = 0;
|
||||||
|
if (a->dim >= n && n > 0)
|
||||||
|
*result = min(a->x[n-1], a->x[a->dim + n-1]);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return a specific normalized UR coordinate */
|
||||||
|
double *
|
||||||
|
cube_ur_coord(NDBOX * a, int n)
|
||||||
|
{
|
||||||
|
double *result;
|
||||||
|
result = (double *) palloc(sizeof(double));
|
||||||
|
*result = 0;
|
||||||
|
if (a->dim >= n && n > 0)
|
||||||
|
*result = max(a->x[n-1], a->x[a->dim + n-1]);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Increase or decrease box size by a radius in at least n dimensions. */
|
||||||
|
NDBOX *
|
||||||
|
cube_enlarge(NDBOX * a, double * r, int n)
|
||||||
|
{
|
||||||
|
NDBOX *result;
|
||||||
|
int dim = 0;
|
||||||
|
int size;
|
||||||
|
int i,
|
||||||
|
j;
|
||||||
|
if (*r > 0 && n > 0) dim = n;
|
||||||
|
if (a->dim > dim) dim = a->dim;
|
||||||
|
size = offsetof(NDBOX, x[0]) + sizeof(double) * dim * 2;
|
||||||
|
result = (NDBOX *) palloc(size);
|
||||||
|
memset(result, 0, size);
|
||||||
|
result->size = size;
|
||||||
|
result->dim = dim;
|
||||||
|
for (i = 0, j = dim; i < a->dim; i++, j++)
|
||||||
|
{
|
||||||
|
if (a->x[i] >= a->x[j])
|
||||||
|
{
|
||||||
|
result->x[i] = a->x[j] - *r;
|
||||||
|
result->x[j] = a->x[i] + *r;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result->x[i] = a->x[i] - *r;
|
||||||
|
result->x[j] = a->x[j] + *r;
|
||||||
|
}
|
||||||
|
if (result->x[i] > result->x[j])
|
||||||
|
{
|
||||||
|
result->x[i] = (result->x[i] + result->x[j]) / 2;
|
||||||
|
result->x[j] = result->x[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* dim > a->dim only if r > 0 */
|
||||||
|
for (; i < dim; i++, j++)
|
||||||
|
{
|
||||||
|
result->x[i] = -*r;
|
||||||
|
result->x[j] = *r;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -8,12 +8,12 @@ SET search_path = public;
|
|||||||
CREATE FUNCTION cube_in(cstring)
|
CREATE FUNCTION cube_in(cstring)
|
||||||
RETURNS cube
|
RETURNS cube
|
||||||
AS 'MODULE_PATHNAME'
|
AS 'MODULE_PATHNAME'
|
||||||
LANGUAGE 'c' WITH (isStrict);
|
LANGUAGE 'c'IMMUTABLE STRICT;
|
||||||
|
|
||||||
CREATE FUNCTION cube_out(cube)
|
CREATE FUNCTION cube_out(cube)
|
||||||
RETURNS cstring
|
RETURNS cstring
|
||||||
AS 'MODULE_PATHNAME'
|
AS 'MODULE_PATHNAME'
|
||||||
LANGUAGE 'c' WITH (isStrict);
|
LANGUAGE 'c'IMMUTABLE STRICT;
|
||||||
|
|
||||||
CREATE TYPE cube (
|
CREATE TYPE cube (
|
||||||
internallength = variable,
|
internallength = variable,
|
||||||
@ -24,6 +24,16 @@ output = cube_out
|
|||||||
COMMENT ON TYPE cube IS
|
COMMENT ON TYPE cube IS
|
||||||
'multi-dimensional cube ''(FLOAT-1, FLOAT-2, ..., FLOAT-N), (FLOAT-1, FLOAT-2, ..., FLOAT-N)''';
|
'multi-dimensional cube ''(FLOAT-1, FLOAT-2, ..., FLOAT-N), (FLOAT-1, FLOAT-2, ..., FLOAT-N)''';
|
||||||
|
|
||||||
|
-- Convert from text to cube
|
||||||
|
|
||||||
|
CREATE FUNCTION cube(text)
|
||||||
|
RETURNS cube
|
||||||
|
AS 'MODULE_PATHNAME'
|
||||||
|
LANGUAGE 'c' IMMUTABLE STRICT;
|
||||||
|
|
||||||
|
COMMENT ON FUNCTION cube(text) IS
|
||||||
|
'convert text to cube';
|
||||||
|
|
||||||
--
|
--
|
||||||
-- External C-functions for R-tree methods
|
-- External C-functions for R-tree methods
|
||||||
--
|
--
|
||||||
@ -31,25 +41,25 @@ COMMENT ON TYPE cube IS
|
|||||||
-- Left/Right methods
|
-- Left/Right methods
|
||||||
|
|
||||||
CREATE FUNCTION cube_over_left(cube, cube) RETURNS bool
|
CREATE FUNCTION cube_over_left(cube, cube) RETURNS bool
|
||||||
AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict);
|
AS 'MODULE_PATHNAME' LANGUAGE 'c' IMMUTABLE STRICT;
|
||||||
|
|
||||||
COMMENT ON FUNCTION cube_over_left(cube, cube) IS
|
COMMENT ON FUNCTION cube_over_left(cube, cube) IS
|
||||||
'is over and left of (NOT IMPLEMENTED)';
|
'is over and left of (NOT IMPLEMENTED)';
|
||||||
|
|
||||||
CREATE FUNCTION cube_over_right(cube, cube) RETURNS bool
|
CREATE FUNCTION cube_over_right(cube, cube) RETURNS bool
|
||||||
AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict);
|
AS 'MODULE_PATHNAME' LANGUAGE 'c' IMMUTABLE STRICT;
|
||||||
|
|
||||||
COMMENT ON FUNCTION cube_over_right(cube, cube) IS
|
COMMENT ON FUNCTION cube_over_right(cube, cube) IS
|
||||||
'is over and right of (NOT IMPLEMENTED)';
|
'is over and right of (NOT IMPLEMENTED)';
|
||||||
|
|
||||||
CREATE FUNCTION cube_left(cube, cube) RETURNS bool
|
CREATE FUNCTION cube_left(cube, cube) RETURNS bool
|
||||||
AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict);
|
AS 'MODULE_PATHNAME' LANGUAGE 'c' IMMUTABLE STRICT;
|
||||||
|
|
||||||
COMMENT ON FUNCTION cube_left(cube, cube) IS
|
COMMENT ON FUNCTION cube_left(cube, cube) IS
|
||||||
'is left of (NOT IMPLEMENTED)';
|
'is left of (NOT IMPLEMENTED)';
|
||||||
|
|
||||||
CREATE FUNCTION cube_right(cube, cube) RETURNS bool
|
CREATE FUNCTION cube_right(cube, cube) RETURNS bool
|
||||||
AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict);
|
AS 'MODULE_PATHNAME' LANGUAGE 'c' IMMUTABLE STRICT;
|
||||||
|
|
||||||
COMMENT ON FUNCTION cube_right(cube, cube) IS
|
COMMENT ON FUNCTION cube_right(cube, cube) IS
|
||||||
'is right of (NOT IMPLEMENTED)';
|
'is right of (NOT IMPLEMENTED)';
|
||||||
@ -58,43 +68,43 @@ COMMENT ON FUNCTION cube_right(cube, cube) IS
|
|||||||
-- Comparison methods
|
-- Comparison methods
|
||||||
|
|
||||||
CREATE FUNCTION cube_lt(cube, cube) RETURNS bool
|
CREATE FUNCTION cube_lt(cube, cube) RETURNS bool
|
||||||
AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict);
|
AS 'MODULE_PATHNAME' LANGUAGE 'c' IMMUTABLE STRICT;
|
||||||
|
|
||||||
COMMENT ON FUNCTION cube_lt(cube, cube) IS
|
COMMENT ON FUNCTION cube_lt(cube, cube) IS
|
||||||
'lower than';
|
'lower than';
|
||||||
|
|
||||||
CREATE FUNCTION cube_gt(cube, cube) RETURNS bool
|
CREATE FUNCTION cube_gt(cube, cube) RETURNS bool
|
||||||
AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict);
|
AS 'MODULE_PATHNAME' LANGUAGE 'c' IMMUTABLE STRICT;
|
||||||
|
|
||||||
COMMENT ON FUNCTION cube_gt(cube, cube) IS
|
COMMENT ON FUNCTION cube_gt(cube, cube) IS
|
||||||
'greater than';
|
'greater than';
|
||||||
|
|
||||||
CREATE FUNCTION cube_contains(cube, cube) RETURNS bool
|
CREATE FUNCTION cube_contains(cube, cube) RETURNS bool
|
||||||
AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict);
|
AS 'MODULE_PATHNAME' LANGUAGE 'c' IMMUTABLE STRICT;
|
||||||
|
|
||||||
COMMENT ON FUNCTION cube_contains(cube, cube) IS
|
COMMENT ON FUNCTION cube_contains(cube, cube) IS
|
||||||
'contains';
|
'contains';
|
||||||
|
|
||||||
CREATE FUNCTION cube_contained(cube, cube) RETURNS bool
|
CREATE FUNCTION cube_contained(cube, cube) RETURNS bool
|
||||||
AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict);
|
AS 'MODULE_PATHNAME' LANGUAGE 'c' IMMUTABLE STRICT;
|
||||||
|
|
||||||
COMMENT ON FUNCTION cube_contained(cube, cube) IS
|
COMMENT ON FUNCTION cube_contained(cube, cube) IS
|
||||||
'contained in';
|
'contained in';
|
||||||
|
|
||||||
CREATE FUNCTION cube_overlap(cube, cube) RETURNS bool
|
CREATE FUNCTION cube_overlap(cube, cube) RETURNS bool
|
||||||
AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict);
|
AS 'MODULE_PATHNAME' LANGUAGE 'c' IMMUTABLE STRICT;
|
||||||
|
|
||||||
COMMENT ON FUNCTION cube_overlap(cube, cube) IS
|
COMMENT ON FUNCTION cube_overlap(cube, cube) IS
|
||||||
'overlaps';
|
'overlaps';
|
||||||
|
|
||||||
CREATE FUNCTION cube_same(cube, cube) RETURNS bool
|
CREATE FUNCTION cube_same(cube, cube) RETURNS bool
|
||||||
AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict);
|
AS 'MODULE_PATHNAME' LANGUAGE 'c' IMMUTABLE STRICT;
|
||||||
|
|
||||||
COMMENT ON FUNCTION cube_same(cube, cube) IS
|
COMMENT ON FUNCTION cube_same(cube, cube) IS
|
||||||
'same as';
|
'same as';
|
||||||
|
|
||||||
CREATE FUNCTION cube_different(cube, cube) RETURNS bool
|
CREATE FUNCTION cube_different(cube, cube) RETURNS bool
|
||||||
AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict);
|
AS 'MODULE_PATHNAME' LANGUAGE 'c' IMMUTABLE STRICT;
|
||||||
|
|
||||||
COMMENT ON FUNCTION cube_different(cube, cube) IS
|
COMMENT ON FUNCTION cube_different(cube, cube) IS
|
||||||
'different';
|
'different';
|
||||||
@ -102,22 +112,42 @@ COMMENT ON FUNCTION cube_different(cube, cube) IS
|
|||||||
-- support routines for indexing
|
-- support routines for indexing
|
||||||
|
|
||||||
CREATE FUNCTION cube_union(cube, cube) RETURNS cube
|
CREATE FUNCTION cube_union(cube, cube) RETURNS cube
|
||||||
AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict);
|
AS 'MODULE_PATHNAME' LANGUAGE 'c' IMMUTABLE STRICT;
|
||||||
|
|
||||||
CREATE FUNCTION cube_inter(cube, cube) RETURNS cube
|
CREATE FUNCTION cube_inter(cube, cube) RETURNS cube
|
||||||
AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict);
|
AS 'MODULE_PATHNAME' LANGUAGE 'c' IMMUTABLE STRICT;
|
||||||
|
|
||||||
CREATE FUNCTION cube_size(cube) RETURNS float4
|
CREATE FUNCTION cube_size(cube) RETURNS float8
|
||||||
AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict);
|
AS 'MODULE_PATHNAME' LANGUAGE 'c' IMMUTABLE STRICT;
|
||||||
|
|
||||||
|
|
||||||
-- Misc N-dimensional functions
|
-- Misc N-dimensional functions
|
||||||
|
|
||||||
-- proximity routines
|
-- proximity routines
|
||||||
|
|
||||||
CREATE FUNCTION cube_distance(cube, cube) RETURNS float4
|
CREATE FUNCTION cube_distance(cube, cube) RETURNS float8
|
||||||
AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict);
|
AS 'MODULE_PATHNAME' LANGUAGE 'c' IMMUTABLE STRICT;
|
||||||
|
|
||||||
|
-- Extracting elements functions
|
||||||
|
|
||||||
|
CREATE FUNCTION cube_dim(cube) RETURNS int4
|
||||||
|
AS 'MODULE_PATHNAME' LANGUAGE 'c' IMMUTABLE STRICT;
|
||||||
|
|
||||||
|
CREATE FUNCTION cube_ll_coord(cube, int4) RETURNS float8
|
||||||
|
AS 'MODULE_PATHNAME' LANGUAGE 'c' IMMUTABLE STRICT;
|
||||||
|
|
||||||
|
CREATE FUNCTION cube_ur_coord(cube, int4) RETURNS float8
|
||||||
|
AS 'MODULE_PATHNAME' LANGUAGE 'c' IMMUTABLE STRICT;
|
||||||
|
|
||||||
|
-- Test if cube is also a point
|
||||||
|
|
||||||
|
CREATE FUNCTION cube_is_point(cube) RETURNS bool
|
||||||
|
AS 'MODULE_PATHNAME' LANGUAGE 'c' IMMUTABLE STRICT;
|
||||||
|
|
||||||
|
-- Increasing the size of a cube by a radius in at least n dimensions
|
||||||
|
|
||||||
|
CREATE FUNCTION cube_enlarge(cube, float8, int4) RETURNS cube
|
||||||
|
AS 'MODULE_PATHNAME' LANGUAGE 'c' IMMUTABLE STRICT;
|
||||||
|
|
||||||
--
|
--
|
||||||
-- OPERATORS
|
-- OPERATORS
|
||||||
@ -202,7 +232,7 @@ CREATE FUNCTION g_cube_decompress(internal) RETURNS internal
|
|||||||
AS 'MODULE_PATHNAME' LANGUAGE 'c';
|
AS 'MODULE_PATHNAME' LANGUAGE 'c';
|
||||||
|
|
||||||
CREATE FUNCTION g_cube_penalty(internal,internal,internal) RETURNS internal
|
CREATE FUNCTION g_cube_penalty(internal,internal,internal) RETURNS internal
|
||||||
AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict);
|
AS 'MODULE_PATHNAME' LANGUAGE 'c' STRICT;
|
||||||
|
|
||||||
CREATE FUNCTION g_cube_picksplit(internal, internal) RETURNS internal
|
CREATE FUNCTION g_cube_picksplit(internal, internal) RETURNS internal
|
||||||
AS 'MODULE_PATHNAME' LANGUAGE 'c';
|
AS 'MODULE_PATHNAME' LANGUAGE 'c';
|
||||||
|
@ -2,5 +2,5 @@ typedef struct NDBOX
|
|||||||
{
|
{
|
||||||
unsigned int size; /* required to be a Postgres varlena type */
|
unsigned int size; /* required to be a Postgres varlena type */
|
||||||
unsigned int dim;
|
unsigned int dim;
|
||||||
float x[1];
|
double x[1];
|
||||||
} NDBOX;
|
} NDBOX;
|
||||||
|
@ -198,9 +198,10 @@ 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(float) * dim * 2;
|
int size = offsetof(NDBOX, x[0]) + sizeof(double) * dim * 2;
|
||||||
|
|
||||||
bp = palloc(size);
|
bp = palloc(size);
|
||||||
|
memset(bp, 0, size);
|
||||||
bp->size = size;
|
bp->size = size;
|
||||||
bp->dim = dim;
|
bp->dim = dim;
|
||||||
|
|
||||||
@ -230,9 +231,10 @@ static NDBOX * write_point_as_box(char *str)
|
|||||||
int dim = delim_count(str, ',') + 1;
|
int dim = delim_count(str, ',') + 1;
|
||||||
char * s = str;
|
char * s = str;
|
||||||
|
|
||||||
size = offsetof(NDBOX, x[0]) + sizeof(float) * dim * 2;
|
size = offsetof(NDBOX, x[0]) + sizeof(double) * dim * 2;
|
||||||
|
|
||||||
bp = palloc(size);
|
bp = palloc(size);
|
||||||
|
memset(bp, 0, size);
|
||||||
bp->size = size;
|
bp->size = size;
|
||||||
bp->dim = dim;
|
bp->dim = dim;
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ void cube_flush_scanner_buffer(void);
|
|||||||
|
|
||||||
n [0-9]+
|
n [0-9]+
|
||||||
integer [+-]?{n}
|
integer [+-]?{n}
|
||||||
real [+-]?({n}\.{n}?)|(\.{n})
|
real [+-]?({n}\.{n}?|\.{n})
|
||||||
float ({integer}|{real})([eE]{integer})?
|
float ({integer}|{real})([eE]{integer})?
|
||||||
|
|
||||||
%%
|
%%
|
||||||
|
@ -43,7 +43,10 @@ SELECT '.1'::cube AS cube;
|
|||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
SELECT '-.1'::cube AS cube;
|
SELECT '-.1'::cube AS cube;
|
||||||
ERROR: parse error, expecting `FLOAT' or `O_PAREN' or `O_BRACKET' at or before position 2, character ('.', \056), input: '-.1'
|
cube
|
||||||
|
--------
|
||||||
|
(-0.1)
|
||||||
|
(1 row)
|
||||||
|
|
||||||
SELECT '1.0'::cube AS cube;
|
SELECT '1.0'::cube AS cube;
|
||||||
cube
|
cube
|
||||||
@ -57,52 +60,52 @@ SELECT '-1.0'::cube AS cube;
|
|||||||
(-1)
|
(-1)
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
SELECT '1e7'::cube AS cube;
|
SELECT '1e27'::cube AS cube;
|
||||||
cube
|
cube
|
||||||
---------
|
---------
|
||||||
(1e+07)
|
(1e+27)
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
SELECT '-1e7'::cube AS cube;
|
SELECT '-1e27'::cube AS cube;
|
||||||
cube
|
cube
|
||||||
----------
|
----------
|
||||||
(-1e+07)
|
(-1e+27)
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
SELECT '1.0e7'::cube AS cube;
|
SELECT '1.0e27'::cube AS cube;
|
||||||
cube
|
cube
|
||||||
---------
|
---------
|
||||||
(1e+07)
|
(1e+27)
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
SELECT '-1.0e7'::cube AS cube;
|
SELECT '-1.0e27'::cube AS cube;
|
||||||
cube
|
cube
|
||||||
----------
|
----------
|
||||||
(-1e+07)
|
(-1e+27)
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
SELECT '1e+7'::cube AS cube;
|
SELECT '1e+27'::cube AS cube;
|
||||||
cube
|
cube
|
||||||
---------
|
---------
|
||||||
(1e+07)
|
(1e+27)
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
SELECT '-1e+7'::cube AS cube;
|
SELECT '-1e+27'::cube AS cube;
|
||||||
cube
|
cube
|
||||||
----------
|
----------
|
||||||
(-1e+07)
|
(-1e+27)
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
SELECT '1.0e+7'::cube AS cube;
|
SELECT '1.0e+27'::cube AS cube;
|
||||||
cube
|
cube
|
||||||
---------
|
---------
|
||||||
(1e+07)
|
(1e+27)
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
SELECT '-1.0e+7'::cube AS cube;
|
SELECT '-1.0e+27'::cube AS cube;
|
||||||
cube
|
cube
|
||||||
----------
|
----------
|
||||||
(-1e+07)
|
(-1e+27)
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
SELECT '1e-7'::cube AS cube;
|
SELECT '1e-7'::cube AS cube;
|
||||||
@ -141,6 +144,42 @@ SELECT '-1e-700'::cube AS cube;
|
|||||||
(0)
|
(0)
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
|
SELECT '1234567890123456'::cube AS cube;
|
||||||
|
cube
|
||||||
|
--------------------
|
||||||
|
(1234567890123456)
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT '+1234567890123456'::cube AS cube;
|
||||||
|
cube
|
||||||
|
--------------------
|
||||||
|
(1234567890123456)
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT '-1234567890123456'::cube AS cube;
|
||||||
|
cube
|
||||||
|
---------------------
|
||||||
|
(-1234567890123456)
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT '.1234567890123456'::cube AS cube;
|
||||||
|
cube
|
||||||
|
----------------------
|
||||||
|
(0.1234567890123456)
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT '+.1234567890123456'::cube AS cube;
|
||||||
|
cube
|
||||||
|
----------------------
|
||||||
|
(0.1234567890123456)
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT '-.1234567890123456'::cube AS cube;
|
||||||
|
cube
|
||||||
|
-----------------------
|
||||||
|
(-0.1234567890123456)
|
||||||
|
(1 row)
|
||||||
|
|
||||||
-- simple lists (points)
|
-- simple lists (points)
|
||||||
SELECT '1,2'::cube AS cube;
|
SELECT '1,2'::cube AS cube;
|
||||||
cube
|
cube
|
||||||
@ -924,6 +963,224 @@ SELECT '(-1,-1),(1,1)'::cube @ '(-2),(1)'::cube AS bool;
|
|||||||
f
|
f
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
|
-- Test of distance function
|
||||||
|
--
|
||||||
|
SELECT cube_distance('(0)'::cube,'(2,2,2,2)'::cube);
|
||||||
|
cube_distance
|
||||||
|
---------------
|
||||||
|
4
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT cube_distance('(0)'::cube,'(.3,.4)'::cube);
|
||||||
|
cube_distance
|
||||||
|
---------------
|
||||||
|
0.5
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- Test of cube function (text to cube)
|
||||||
|
--
|
||||||
|
SELECT cube('('||1||','||1.2||')');
|
||||||
|
cube
|
||||||
|
----------
|
||||||
|
(1, 1.2)
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT cube(NULL);
|
||||||
|
cube
|
||||||
|
------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- Test of cube_dim function (dimensions stored in cube)
|
||||||
|
--
|
||||||
|
SELECT cube_dim('(0)'::cube);
|
||||||
|
cube_dim
|
||||||
|
----------
|
||||||
|
1
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT cube_dim('(0,0)'::cube);
|
||||||
|
cube_dim
|
||||||
|
----------
|
||||||
|
2
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT cube_dim('(0,0,0)'::cube);
|
||||||
|
cube_dim
|
||||||
|
----------
|
||||||
|
3
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- Test of cube_ll_coord function (retrieves LL coodinate values)
|
||||||
|
--
|
||||||
|
SELECT cube_ll_coord('(-1,1),(2,-2)'::cube, 1);
|
||||||
|
cube_ll_coord
|
||||||
|
---------------
|
||||||
|
-1
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT cube_ll_coord('(-1,1),(2,-2)'::cube, 2);
|
||||||
|
cube_ll_coord
|
||||||
|
---------------
|
||||||
|
-2
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT cube_ll_coord('(-1,1),(2,-2)'::cube, 3);
|
||||||
|
cube_ll_coord
|
||||||
|
---------------
|
||||||
|
0
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- Test of cube_ur_coord function (retrieves UR coodinate values)
|
||||||
|
--
|
||||||
|
SELECT cube_ur_coord('(-1,1),(2,-2)'::cube, 1);
|
||||||
|
cube_ur_coord
|
||||||
|
---------------
|
||||||
|
2
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT cube_ur_coord('(-1,1),(2,-2)'::cube, 2);
|
||||||
|
cube_ur_coord
|
||||||
|
---------------
|
||||||
|
1
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT cube_ur_coord('(-1,1),(2,-2)'::cube, 3);
|
||||||
|
cube_ur_coord
|
||||||
|
---------------
|
||||||
|
0
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- Test of cube_is_point
|
||||||
|
--
|
||||||
|
SELECT cube_is_point('(0)'::cube);
|
||||||
|
cube_is_point
|
||||||
|
---------------
|
||||||
|
t
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT cube_is_point('(0,1,2)'::cube);
|
||||||
|
cube_is_point
|
||||||
|
---------------
|
||||||
|
t
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT cube_is_point('(0,1,2),(0,1,2)'::cube);
|
||||||
|
cube_is_point
|
||||||
|
---------------
|
||||||
|
t
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT cube_is_point('(0,1,2),(-1,1,2)'::cube);
|
||||||
|
cube_is_point
|
||||||
|
---------------
|
||||||
|
f
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT cube_is_point('(0,1,2),(0,-1,2)'::cube);
|
||||||
|
cube_is_point
|
||||||
|
---------------
|
||||||
|
f
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT cube_is_point('(0,1,2),(0,1,-2)'::cube);
|
||||||
|
cube_is_point
|
||||||
|
---------------
|
||||||
|
f
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
-- Test of cube_enlarge (enlarging and shrinking cubes)
|
||||||
|
--
|
||||||
|
SELECT cube_enlarge('(0)'::cube, 0, 0);
|
||||||
|
cube_enlarge
|
||||||
|
--------------
|
||||||
|
(0)
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT cube_enlarge('(0)'::cube, 0, 1);
|
||||||
|
cube_enlarge
|
||||||
|
--------------
|
||||||
|
(0)
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT cube_enlarge('(0)'::cube, 0, 2);
|
||||||
|
cube_enlarge
|
||||||
|
--------------
|
||||||
|
(0)
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT cube_enlarge('(0)'::cube, 1, 0);
|
||||||
|
cube_enlarge
|
||||||
|
--------------
|
||||||
|
(-1),(1)
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT cube_enlarge('(0)'::cube, 1, 1);
|
||||||
|
cube_enlarge
|
||||||
|
--------------
|
||||||
|
(-1),(1)
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT cube_enlarge('(0)'::cube, 1, 2);
|
||||||
|
cube_enlarge
|
||||||
|
-----------------
|
||||||
|
(-1, -1),(1, 1)
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT cube_enlarge('(0)'::cube, -1, 0);
|
||||||
|
cube_enlarge
|
||||||
|
--------------
|
||||||
|
(0)
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT cube_enlarge('(0)'::cube, -1, 1);
|
||||||
|
cube_enlarge
|
||||||
|
--------------
|
||||||
|
(0)
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT cube_enlarge('(0)'::cube, -1, 2);
|
||||||
|
cube_enlarge
|
||||||
|
--------------
|
||||||
|
(0)
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT cube_enlarge('(0,0,0)'::cube, 1, 0);
|
||||||
|
cube_enlarge
|
||||||
|
------------------------
|
||||||
|
(-1, -1, -1),(1, 1, 1)
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT cube_enlarge('(0,0,0)'::cube, 1, 2);
|
||||||
|
cube_enlarge
|
||||||
|
------------------------
|
||||||
|
(-1, -1, -1),(1, 1, 1)
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT cube_enlarge('(2,-2),(-3,7)'::cube, 1, 2);
|
||||||
|
cube_enlarge
|
||||||
|
-----------------
|
||||||
|
(-4, -3),(3, 8)
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT cube_enlarge('(2,-2),(-3,7)'::cube, 3, 2);
|
||||||
|
cube_enlarge
|
||||||
|
------------------
|
||||||
|
(-6, -5),(5, 10)
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT cube_enlarge('(2,-2),(-3,7)'::cube, -1, 2);
|
||||||
|
cube_enlarge
|
||||||
|
-----------------
|
||||||
|
(-2, -1),(1, 6)
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT cube_enlarge('(2,-2),(-3,7)'::cube, -3, 2);
|
||||||
|
cube_enlarge
|
||||||
|
---------------------
|
||||||
|
(-0.5, 1),(-0.5, 4)
|
||||||
|
(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);
|
||||||
|
@ -23,20 +23,26 @@ SELECT '.1'::cube AS cube;
|
|||||||
SELECT '-.1'::cube AS cube;
|
SELECT '-.1'::cube AS cube;
|
||||||
SELECT '1.0'::cube AS cube;
|
SELECT '1.0'::cube AS cube;
|
||||||
SELECT '-1.0'::cube AS cube;
|
SELECT '-1.0'::cube AS cube;
|
||||||
SELECT '1e7'::cube AS cube;
|
SELECT '1e27'::cube AS cube;
|
||||||
SELECT '-1e7'::cube AS cube;
|
SELECT '-1e27'::cube AS cube;
|
||||||
SELECT '1.0e7'::cube AS cube;
|
SELECT '1.0e27'::cube AS cube;
|
||||||
SELECT '-1.0e7'::cube AS cube;
|
SELECT '-1.0e27'::cube AS cube;
|
||||||
SELECT '1e+7'::cube AS cube;
|
SELECT '1e+27'::cube AS cube;
|
||||||
SELECT '-1e+7'::cube AS cube;
|
SELECT '-1e+27'::cube AS cube;
|
||||||
SELECT '1.0e+7'::cube AS cube;
|
SELECT '1.0e+27'::cube AS cube;
|
||||||
SELECT '-1.0e+7'::cube AS cube;
|
SELECT '-1.0e+27'::cube AS cube;
|
||||||
SELECT '1e-7'::cube AS cube;
|
SELECT '1e-7'::cube AS cube;
|
||||||
SELECT '-1e-7'::cube AS cube;
|
SELECT '-1e-7'::cube AS cube;
|
||||||
SELECT '1.0e-7'::cube AS cube;
|
SELECT '1.0e-7'::cube AS cube;
|
||||||
SELECT '-1.0e-7'::cube AS cube;
|
SELECT '-1.0e-7'::cube AS cube;
|
||||||
SELECT '1e-700'::cube AS cube;
|
SELECT '1e-700'::cube AS cube;
|
||||||
SELECT '-1e-700'::cube AS cube;
|
SELECT '-1e-700'::cube AS cube;
|
||||||
|
SELECT '1234567890123456'::cube AS cube;
|
||||||
|
SELECT '+1234567890123456'::cube AS cube;
|
||||||
|
SELECT '-1234567890123456'::cube AS cube;
|
||||||
|
SELECT '.1234567890123456'::cube AS cube;
|
||||||
|
SELECT '+.1234567890123456'::cube AS cube;
|
||||||
|
SELECT '-.1234567890123456'::cube AS cube;
|
||||||
|
|
||||||
-- simple lists (points)
|
-- simple lists (points)
|
||||||
SELECT '1,2'::cube AS cube;
|
SELECT '1,2'::cube AS cube;
|
||||||
@ -230,6 +236,60 @@ SELECT '(-1,-1),(1,1)'::cube @ '(-1),(1)'::cube AS bool;
|
|||||||
SELECT '(-1),(1)'::cube @ '(-2),(1)'::cube AS bool;
|
SELECT '(-1),(1)'::cube @ '(-2),(1)'::cube AS bool;
|
||||||
SELECT '(-1,-1),(1,1)'::cube @ '(-2),(1)'::cube AS bool;
|
SELECT '(-1,-1),(1,1)'::cube @ '(-2),(1)'::cube AS bool;
|
||||||
|
|
||||||
|
-- Test of distance function
|
||||||
|
--
|
||||||
|
SELECT cube_distance('(0)'::cube,'(2,2,2,2)'::cube);
|
||||||
|
SELECT cube_distance('(0)'::cube,'(.3,.4)'::cube);
|
||||||
|
|
||||||
|
-- Test of cube function (text to cube)
|
||||||
|
--
|
||||||
|
SELECT cube('('||1||','||1.2||')');
|
||||||
|
SELECT cube(NULL);
|
||||||
|
|
||||||
|
-- Test of cube_dim function (dimensions stored in cube)
|
||||||
|
--
|
||||||
|
SELECT cube_dim('(0)'::cube);
|
||||||
|
SELECT cube_dim('(0,0)'::cube);
|
||||||
|
SELECT cube_dim('(0,0,0)'::cube);
|
||||||
|
|
||||||
|
-- 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, 2);
|
||||||
|
SELECT cube_ll_coord('(-1,1),(2,-2)'::cube, 3);
|
||||||
|
|
||||||
|
-- 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, 2);
|
||||||
|
SELECT cube_ur_coord('(-1,1),(2,-2)'::cube, 3);
|
||||||
|
|
||||||
|
-- Test of cube_is_point
|
||||||
|
--
|
||||||
|
SELECT cube_is_point('(0)'::cube);
|
||||||
|
SELECT cube_is_point('(0,1,2)'::cube);
|
||||||
|
SELECT cube_is_point('(0,1,2),(0,1,2)'::cube);
|
||||||
|
SELECT cube_is_point('(0,1,2),(-1,1,2)'::cube);
|
||||||
|
SELECT cube_is_point('(0,1,2),(0,-1,2)'::cube);
|
||||||
|
SELECT cube_is_point('(0,1,2),(0,1,-2)'::cube);
|
||||||
|
|
||||||
|
-- Test of cube_enlarge (enlarging and shrinking cubes)
|
||||||
|
--
|
||||||
|
SELECT cube_enlarge('(0)'::cube, 0, 0);
|
||||||
|
SELECT cube_enlarge('(0)'::cube, 0, 1);
|
||||||
|
SELECT cube_enlarge('(0)'::cube, 0, 2);
|
||||||
|
SELECT cube_enlarge('(0)'::cube, 1, 0);
|
||||||
|
SELECT cube_enlarge('(0)'::cube, 1, 1);
|
||||||
|
SELECT cube_enlarge('(0)'::cube, 1, 2);
|
||||||
|
SELECT cube_enlarge('(0)'::cube, -1, 0);
|
||||||
|
SELECT cube_enlarge('(0)'::cube, -1, 1);
|
||||||
|
SELECT cube_enlarge('(0)'::cube, -1, 2);
|
||||||
|
SELECT cube_enlarge('(0,0,0)'::cube, 1, 0);
|
||||||
|
SELECT cube_enlarge('(0,0,0)'::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, -1, 2);
|
||||||
|
SELECT cube_enlarge('(2,-2),(-3,7)'::cube, -3, 2);
|
||||||
|
|
||||||
-- Load some example data and build the index
|
-- Load some example data and build the index
|
||||||
--
|
--
|
||||||
|
Loading…
x
Reference in New Issue
Block a user