What I changed is covered in the CHANGES file.
Note that this includes a bug fix I already subimtted.
These changes are versus 7.3 CVS and may not be backwards compatible with 7.2.
They do not include a bug fix for a problem I reported with cube_yyerror.
A context diff is attached.
diff -c -r -N --exclude=CVS cube/CHANGES newcube/CHANGES
*** cube/CHANGES Wed Dec 31 18:00:00 1969
--- newcube/CHANGES Wed Aug 28 09:47:20 2002
***************
*** 0 ****
--- 1,95 ----
+ Changes that were made in August 2002.
+
+ Note that this was based on a 7.3 development version and changes may not
+ directly work with earlier versions.
+
+ I fixed a bug in cubescan.pl that prevented signed numbers with no digits
+ before a decimal point from being accepted. This was submitted as a separate
+ patch and may already be applied.
+
+ I reported but did not fix a potential buffer overrun problem in cube_yyerror
+ in cubeparse.y.
+
+ cube_inter should really return NULL if the two cubes don't overlap. However
+ this requires changing to the new calling sequence and I don't know enough
+ about how to do it to make the change.
+
+ I changed all floats to doubles except for g_cube_penalty which I don't
+ think can be changed to return double. This might cause the penalty to
+ overflow sooner than one might expect, but overflow could have happened
+ even with floats.
+
+ I changed the output format (in cube_out) to use %.16g instead of %g, since the
+ default is only 6 digits of precision.
+
+ I changed all of the functions declared with (isstrict) to use the current
+ method of declaring this.
+
+ I changed all of the externally visible functions to be immutable which
+ they are. I don't think this matters for the gist functions and didn't
+ try to declare them immutable in case there was something tricky about them
+ that I don't understand.
+
+ I changed the regression tests to use some larger exponents to test output
+ in exponential form. 1e7 was too small for this.
+
+ I added some regression tests to check for 16 digits of precision. This
+ may or may not be a good idea.
+
+ I got rid of the swap_corners function. It created scratch boxes that
+ were iterated through and deleted. This is slower than just getting the
+ larger or smaller coordinate as needed, since swap_corners was doing the
+ same thing with the overhead of a function call and memory allocation.
+
+ I added memset calls to zero out newly allocated NDBOXes as the documentation
+ on functions indicates should be done.
+
+ I got rid of a call to cube_same in cube_lt and cube_gt since the test
+ was redundant with other checks being made. The call to cube_same would
+ only be faster if most of the time you were comparing equivalent cubes.
+
+ In cube_lt and cube_gt, the second (UR) for loop for comparing
+ extra coordinates to 0 had the wrong range.
+
+ Note that the cube_distance function wasn't mentioned in the README.cube file.
+
+ I added regression tests for the cube_distance function.
+
+ I added the following new functions:
+ cube
+ cube_dim
+ cube_ll_coord
+ cube_ur_coord
+ cube_is_point
+ cube_enlarge
+
+ cube takes text input and returns a cube. This is useful for making cubes
+ from computed strings.
+
+ 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 returns the nth coordinate value for the lower left corner
+ of a cube. This is useful for doing coordinate transformations.
+
+ 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 returns true if a cube is also a point. This is true when the
+ two defining corners are the same.
+
+ 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.
+
+ I added regression tests for the new functions.
+
+ I added documentation for cube_distance and the new functions to README.cube
+ as well as making a few other minor changes.
diff -c -r -N --exclude=CVS cube/README.cube newcube/README.cube
*** cube/README.cube Mon Dec 11 14:39:14 2000
--- newcube/README.cube Wed Aug 28 08:55:47 2002
***************
*** 99,105 ****
n [0-9]+
integer [+-]?{n}
! real [+-]?({n}\.{n}?)|(\.{n})
FLOAT ({integer}|{real})([eE]{integer})?
O_BRACKET \[
C_BRACKET \]
--- 99,105 ----
n [0-9]+
integer [+-]?{n}
! real [+-]?({n}\.{n}?|\.{n})
FLOAT ({integer}|{real})([eE]{integer})?
O_BRACKET \[
C_BRACKET \]
***************
*** 182,189 ****
PRECISION
=========
! Values are stored internally as 32-bit floating point numbers. This means that
! numbers with more than 7 significant digits will be truncated.
USAGE
--- 182,189 ----
PRECISION
=========
! Values are stored internally as 64-bit floating point numbers. This means that
! numbers with more than about 16 significant digits will be truncated.
USAGE
***************
*** 253,258 ****
--- 253,296 ----
reasonably good sorting in most cases, which is useful if
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
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:
***************
*** 287,289 ****
--- 325,335 ----
Argonne, IL 60439-4844
[EMAIL PROTECTED]
+
+ ------------------------------------------------------------------------
+
+ Minor updates to this package were made by Bruno Wolff III <[EMAIL PROTECTED]>
+ in August of 2002.
+
+ These include changing the precision from single precision to double
+ precision and adding some new functions.
diff -c -r -N --exclude=CVS cube/cube.c newcube/cube.c
*** cube/cube.c Fri Aug 23 16:01:50 2002
--- newcube/cube.c Wed Aug 28 08:06:53 2002
***************
*** 28,33 ****
--- 28,34 ----
** Input/Output routines
*/
NDBOX *cube_in(char *str);
+ NDBOX *cube(text *str);
char *cube_out(NDBOX * cube);
***************
*** 55,62 ****
bool cube_overlap(NDBOX * a, NDBOX * b);
NDBOX *cube_union(NDBOX * a, NDBOX * b);
NDBOX *cube_inter(NDBOX * a, NDBOX * b);
! float *cube_size(NDBOX * a);
! void rt_cube_size(NDBOX * a, float *sz);
/*
** These make no sense for this type, but R-tree wants them
--- 56,63 ----
bool cube_overlap(NDBOX * a, NDBOX * b);
NDBOX *cube_union(NDBOX * a, NDBOX * b);
NDBOX *cube_inter(NDBOX * a, NDBOX * b);
! double *cube_size(NDBOX * a);
! void rt_cube_size(NDBOX * a, double *sz);
/*
** These make no sense for this type, but R-tree wants them
***************
*** 71,83 ****
*/
bool cube_lt(NDBOX * a, NDBOX * b);
bool cube_gt(NDBOX * a, NDBOX * b);
! float *cube_distance(NDBOX * a, NDBOX * b);
/*
** Auxiliary funxtions
*/
! static float distance_1D(float a1, float a2, float b1, float b2);
! static NDBOX *swap_corners(NDBOX * a);
/*****************************************************************************
--- 72,89 ----
*/
bool cube_lt(NDBOX * a, NDBOX * b);
bool cube_gt(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
*/
! static double distance_1D(double a1, double a2, double b1, double b2);
/*****************************************************************************
***************
*** 99,104 ****
--- 105,119 ----
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 *
cube_out(NDBOX *cube)
{
***************
*** 118,124 ****
{
if (i > 0)
appendStringInfo(&buf, ", ");
! appendStringInfo(&buf, "%g", cube->x[i]);
if (cube->x[i] != cube->x[i + dim])
equal = false;
}
--- 133,139 ----
{
if (i > 0)
appendStringInfo(&buf, ", ");
! appendStringInfo(&buf, "%.16g", cube->x[i]);
if (cube->x[i] != cube->x[i + dim])
equal = false;
}
***************
*** 131,137 ****
{
if (i > 0)
appendStringInfo(&buf, ", ");
! appendStringInfo(&buf, "%g", cube->x[i + dim]);
}
appendStringInfoChar(&buf, ')');
}
--- 146,152 ----
{
if (i > 0)
appendStringInfo(&buf, ", ");
! appendStringInfo(&buf, "%.16g", cube->x[i + dim]);
}
appendStringInfoChar(&buf, ')');
}
***************
*** 228,241 ****
g_cube_penalty(GISTENTRY *origentry, GISTENTRY *newentry, float *result)
{
NDBOX *ud;
! float tmp1,
tmp2;
ud = cube_union((NDBOX *) DatumGetPointer(origentry->key),
(NDBOX *) DatumGetPointer(newentry->key));
rt_cube_size(ud, &tmp1);
rt_cube_size((NDBOX *) DatumGetPointer(origentry->key), &tmp2);
! *result = tmp1 - tmp2;
pfree(ud);
/*
--- 243,256 ----
g_cube_penalty(GISTENTRY *origentry, GISTENTRY *newentry, float *result)
{
NDBOX *ud;
! double tmp1,
tmp2;
ud = cube_union((NDBOX *) DatumGetPointer(origentry->key),
(NDBOX *) DatumGetPointer(newentry->key));
rt_cube_size(ud, &tmp1);
rt_cube_size((NDBOX *) DatumGetPointer(origentry->key), &tmp2);
! *result = (float) (tmp1 - tmp2);
pfree(ud);
/*
***************
*** 265,277 ****
*union_dr;
NDBOX *inter_d;
bool firsttime;
! float size_alpha,
size_beta,
size_union,
size_inter;
! float size_waste,
waste;
! float size_l,
size_r;
int nbytes;
OffsetNumber seed_1 = 0,
--- 280,292 ----
*union_dr;
NDBOX *inter_d;
bool firsttime;
! double size_alpha,
size_beta,
size_union,
size_inter;
! double size_waste,
waste;
! double size_l,
size_r;
int nbytes;
OffsetNumber seed_1 = 0,
***************
*** 519,540 ****
/* cube_union */
NDBOX *
! cube_union(NDBOX * box_a, NDBOX * box_b)
{
int i;
NDBOX *result;
- NDBOX *a = swap_corners(box_a);
- NDBOX *b = swap_corners(box_b);
if (a->dim >= b->dim)
{
result = palloc(a->size);
result->size = a->size;
result->dim = a->dim;
}
else
{
result = palloc(b->size);
result->size = b->size;
result->dim = b->dim;
}
--- 534,555 ----
/* cube_union */
NDBOX *
! cube_union(NDBOX * a, NDBOX * b)
{
int i;
NDBOX *result;
if (a->dim >= b->dim)
{
result = palloc(a->size);
+ memset(result, 0, a->size);
result->size = a->size;
result->dim = a->dim;
}
else
{
result = palloc(b->size);
+ memset(result, 0, b->size);
result->size = b->size;
result->dim = b->dim;
}
***************
*** 554,561 ****
*/
for (i = 0; i < b->dim; i++)
{
! result->x[i] = b->x[i];
! result->x[i + a->dim] = b->x[i + b->dim];
}
for (i = b->dim; i < a->dim; i++)
{
--- 569,576 ----
*/
for (i = 0; i < b->dim; i++)
{
! result->x[i] = min(b->x[i], 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++)
{
***************
*** 565,598 ****
/* compute the union */
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] = max(a->x[i], result->x[i]);
!
! pfree(a);
! pfree(b);
return (result);
}
/* cube_inter */
NDBOX *
! cube_inter(NDBOX * box_a, NDBOX * box_b)
{
int i;
NDBOX *result;
- NDBOX *a = swap_corners(box_a);
- NDBOX *b = swap_corners(box_b);
if (a->dim >= b->dim)
{
result = palloc(a->size);
result->size = a->size;
result->dim = a->dim;
}
else
{
result = palloc(b->size);
result->size = b->size;
result->dim = b->dim;
}
--- 580,613 ----
/* compute the union */
for (i = 0; i < a->dim; 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],
! a->x[i + a->dim]), result->x[i + a->dim]);
! }
return (result);
}
/* cube_inter */
NDBOX *
! cube_inter(NDBOX * a, NDBOX * b)
{
int i;
NDBOX *result;
if (a->dim >= b->dim)
{
result = palloc(a->size);
+ memset(result, 0, a->size);
result->size = a->size;
result->dim = a->dim;
}
else
{
result = palloc(b->size);
+ memset(result, 0, b->size);
result->size = b->size;
result->dim = b->dim;
}
***************
*** 612,619 ****
*/
for (i = 0; i < b->dim; i++)
{
! result->x[i] = b->x[i];
! result->x[i + a->dim] = b->x[i + b->dim];
}
for (i = b->dim; i < a->dim; i++)
{
--- 627,634 ----
*/
for (i = 0; i < b->dim; i++)
{
! result->x[i] = min(b->x[i], 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++)
{
***************
*** 623,634 ****
/* compute the intersection */
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] = min(a->x[i], result->x[i]);
!
! pfree(a);
! pfree(b);
/*
* Is it OK to return a non-null intersection for non-overlapping
--- 638,649 ----
/* compute the intersection */
for (i = 0; i < a->dim; 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],
! a->x[i + a->dim]), result->x[i + a->dim]);
! }
/*
* Is it OK to return a non-null intersection for non-overlapping
***************
*** 638,651 ****
}
/* cube_size */
! float *
cube_size(NDBOX * a)
{
int i,
j;
! float *result;
! result = (float *) palloc(sizeof(float));
*result = 1.0;
for (i = 0, j = a->dim; i < a->dim; i++, j++)
--- 653,666 ----
}
/* cube_size */
! double *
cube_size(NDBOX * a)
{
int i,
j;
! double *result;
! result = (double *) palloc(sizeof(double));
*result = 1.0;
for (i = 0, j = a->dim; i < a->dim; i++, j++)
***************
*** 655,661 ****
}
void
! rt_cube_size(NDBOX * a, float *size)
{
int i,
j;
--- 670,676 ----
}
void
! rt_cube_size(NDBOX * a, double *size)
{
int i,
j;
***************
*** 679,792 ****
/* is the right edge of (a) located to the left of
the right edge of (b)? */
bool
! cube_over_left(NDBOX * box_a, NDBOX * box_b)
{
! NDBOX *a;
! NDBOX *b;
!
! if ((box_a == NULL) || (box_b == NULL))
return (FALSE);
! a = swap_corners(box_a);
! b = swap_corners(box_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
the left edge of (b)? */
bool
! cube_over_right(NDBOX * box_a, NDBOX * box_b)
{
! NDBOX *a;
! NDBOX *b;
!
! if ((box_a == NULL) || (box_b == NULL))
return (FALSE);
! a = swap_corners(box_a);
! b = swap_corners(box_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
entirely on the left of the projection of 'b' */
bool
! cube_left(NDBOX * box_a, NDBOX * box_b)
{
! NDBOX *a;
! NDBOX *b;
!
! if ((box_a == NULL) || (box_b == NULL))
return (FALSE);
! a = swap_corners(box_a);
! b = swap_corners(box_b);
!
! return (a->x[a->dim - 1] < b->x[0]);
}
/* return 'true' if the projection of 'a' is
entirely on the right of the projection of 'b' */
bool
! cube_right(NDBOX * box_a, NDBOX * box_b)
{
! NDBOX *a;
! NDBOX *b;
!
! if ((box_a == NULL) || (box_b == NULL))
return (FALSE);
! a = swap_corners(box_a);
! b = swap_corners(box_b);
!
! return (a->x[0] > b->x[b->dim - 1]);
}
/* make up a metric in which one box will be 'lower' than the other
! -- this can be useful for srting and to determine uniqueness */
bool
! cube_lt(NDBOX * box_a, NDBOX * box_b)
{
int i;
int dim;
- NDBOX *a;
- NDBOX *b;
! if ((box_a == NULL) || (box_b == NULL))
return (FALSE);
- a = swap_corners(box_a);
- b = swap_corners(box_b);
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 */
for (i = 0; i < dim; i++)
{
! if (a->x[i] > b->x[i])
return (FALSE);
! if (a->x[i] < b->x[i])
return (TRUE);
}
for (i = 0; i < dim; i++)
{
! if (a->x[i + a->dim] > b->x[i + b->dim])
return (FALSE);
! if (a->x[i + a->dim] < b->x[i + b->dim])
return (TRUE);
}
--- 694,777 ----
/* is the right edge of (a) located to the left of
the right edge of (b)? */
bool
! cube_over_left(NDBOX * a, NDBOX * b)
{
! if ((a == NULL) || (b == NULL))
return (FALSE);
! return (min(a->x[a->dim - 1], a->x[2 * a->dim - 1]) <=
! min(b->x[b->dim - 1], b->x[2 * b->dim - 1]) &&
! !cube_left(a, b) && !cube_right(a, b));
}
/* is the left edge of (a) located to the right of
the left edge of (b)? */
bool
! cube_over_right(NDBOX * a, NDBOX * b)
{
! if ((a == NULL) || (b == NULL))
return (FALSE);
! return (min(a->x[a->dim - 1], a->x[2 * a->dim - 1]) >=
! min(b->x[b->dim - 1], b->x[2 * b->dim - 1]) &&
! !cube_left(a, b) && !cube_right(a, b));
}
/* return 'true' if the projection of 'a' is
entirely on the left of the projection of 'b' */
bool
! cube_left(NDBOX * a, NDBOX * b)
{
! if ((a == NULL) || (b == NULL))
return (FALSE);
! return (min(a->x[a->dim - 1], a->x[2 * a->dim - 1]) <
! min(b->x[0], b->x[b->dim]));
}
/* return 'true' if the projection of 'a' is
entirely on the right of the projection of 'b' */
bool
! cube_right(NDBOX * a, NDBOX * b)
{
! if ((a == NULL) || (b == NULL))
return (FALSE);
! return (min(a->x[0], a->x[a->dim]) >
! min(b->x[b->dim - 1], b->x[2 * b->dim - 1]));
}
/* make up a metric in which one box will be 'lower' than the other
! -- this can be useful for sorting and to determine uniqueness */
bool
! cube_lt(NDBOX * a, NDBOX * b)
{
int i;
int dim;
! if ((a == NULL) || (b == NULL))
return (FALSE);
dim = min(a->dim, b->dim);
/* compare the common dimensions */
for (i = 0; i < dim; i++)
{
! if (min(a->x[i], a->x[a->dim + i]) >
! min(b->x[i], b->x[b->dim + i]))
return (FALSE);
! if (min(a->x[i], a->x[a->dim + i]) <
! min(b->x[i], b->x[b->dim + i]))
return (TRUE);
}
for (i = 0; i < dim; i++)
{
! if (max(a->x[i], a->x[a->dim + i]) >
! max(b->x[i], b->x[b->dim + i]))
return (FALSE);
! if (max(a->x[i], a->x[a->dim + i]) <
! max(b->x[i], b->x[b->dim + i]))
return (TRUE);
}
***************
*** 795,829 ****
{
for (i = dim; i < a->dim; i++)
{
! if (a->x[i] > 0)
return (FALSE);
! if (a->x[i] < 0)
return (TRUE);
}
! for (i = 0; i < dim; i++)
{
! if (a->x[i + a->dim] > 0)
return (FALSE);
! if (a->x[i + a->dim] < 0)
return (TRUE);
}
}
if (a->dim < b->dim)
{
for (i = dim; i < b->dim; i++)
{
! if (b->x[i] > 0)
return (TRUE);
! if (b->x[i] < 0)
return (FALSE);
}
! for (i = 0; i < dim; i++)
{
! if (b->x[i + b->dim] > 0)
return (TRUE);
! if (b->x[i + b->dim] < 0)
return (FALSE);
}
}
return (FALSE);
--- 780,824 ----
{
for (i = dim; i < a->dim; i++)
{
! if (min(a->x[i], a->x[a->dim + i]) > 0)
return (FALSE);
! if (min(a->x[i], a->x[a->dim + i]) < 0)
return (TRUE);
}
! for (i = dim; i < a->dim; i++)
{
! if (max(a->x[i], a->x[a->dim + i]) > 0)
return (FALSE);
! if (max(a->x[i], a->x[a->dim + i]) < 0)
return (TRUE);
}
+ /*
+ * if all common dimensions are equal, the cube with more
+ * dimensions wins
+ */
+ return (FALSE);
}
if (a->dim < b->dim)
{
for (i = dim; i < b->dim; i++)
{
! if (min(b->x[i], b->x[b->dim + i]) > 0)
return (TRUE);
! if (min(b->x[i], b->x[b->dim + i]) < 0)
return (FALSE);
}
! for (i = dim; i < b->dim; i++)
{
! if (max(b->x[i], b->x[b->dim + i]) > 0)
return (TRUE);
! if (max(b->x[i], b->x[b->dim + i]) < 0)
return (FALSE);
}
+ /*
+ * if all common dimensions are equal, the cube with more
+ * dimensions wins
+ */
+ return (TRUE);
}
return (FALSE);
***************
*** 831,875 ****
bool
! cube_gt(NDBOX * box_a, NDBOX * box_b)
{
int i;
int dim;
- NDBOX *a;
- NDBOX *b;
! if ((box_a == NULL) || (box_b == NULL))
return (FALSE);
- a = swap_corners(box_a);
- b = swap_corners(box_b);
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 */
for (i = 0; i < dim; i++)
{
! if (a->x[i] < b->x[i])
return (FALSE);
! if (a->x[i] > b->x[i])
return (TRUE);
}
for (i = 0; i < dim; i++)
{
! if (a->x[i + a->dim] < b->x[i + b->dim])
return (FALSE);
! if (a->x[i + a->dim] > b->x[i + b->dim])
return (TRUE);
}
--- 826,858 ----
bool
! cube_gt(NDBOX * a, NDBOX * b)
{
int i;
int dim;
! if ((a == NULL) || (b == NULL))
return (FALSE);
dim = min(a->dim, b->dim);
/* compare the common dimensions */
for (i = 0; i < dim; i++)
{
! if (min(a->x[i], a->x[a->dim + i]) <
! min(b->x[i], b->x[b->dim + i]))
return (FALSE);
! if (min(a->x[i], a->x[a->dim + i]) >
! min(b->x[i], b->x[b->dim + i]))
return (TRUE);
}
for (i = 0; i < dim; i++)
{
! if (max(a->x[i], a->x[a->dim + i]) <
! max(b->x[i], b->x[b->dim + i]))
return (FALSE);
! if (max(a->x[i], a->x[a->dim + i]) >
! max(b->x[i], b->x[b->dim + i]))
return (TRUE);
}
***************
*** 879,913 ****
{
for (i = dim; i < a->dim; i++)
{
! if (a->x[i] < 0)
return (FALSE);
! if (a->x[i] > 0)
return (TRUE);
}
! for (i = 0; i < dim; i++)
{
! if (a->x[i + a->dim] < 0)
return (FALSE);
! if (a->x[i + a->dim] > 0)
return (TRUE);
}
}
if (a->dim < b->dim)
{
for (i = dim; i < b->dim; i++)
{
! if (b->x[i] < 0)
return (TRUE);
! if (b->x[i] > 0)
return (FALSE);
}
! for (i = 0; i < dim; i++)
{
! if (b->x[i + b->dim] < 0)
return (TRUE);
! if (b->x[i + b->dim] > 0)
return (FALSE);
}
}
return (FALSE);
--- 862,906 ----
{
for (i = dim; i < a->dim; i++)
{
! if (min(a->x[i], a->x[a->dim + i]) < 0)
return (FALSE);
! if (min(a->x[i], a->x[a->dim + i]) > 0)
return (TRUE);
}
! for (i = dim; i < a->dim; i++)
{
! if (max(a->x[i], a->x[a->dim + i]) < 0)
return (FALSE);
! if (max(a->x[i], a->x[a->dim + i]) > 0)
return (TRUE);
}
+ /*
+ * if all common dimensions are equal, the cube with more
+ * dimensions wins
+ */
+ return (TRUE);
}
if (a->dim < b->dim)
{
for (i = dim; i < b->dim; i++)
{
! if (min(b->x[i], b->x[b->dim + i]) < 0)
return (TRUE);
! if (min(b->x[i], b->x[b->dim + i]) > 0)
return (FALSE);
}
! for (i = dim; i < b->dim; i++)
{
! if (max(b->x[i], b->x[b->dim + i]) < 0)
return (TRUE);
! if (max(b->x[i], b->x[b->dim + i]) > 0)
return (FALSE);
}
+ /*
+ * if all common dimensions are equal, the cube with more
+ * dimensions wins
+ */
+ return (FALSE);
}
return (FALSE);
***************
*** 916,933 ****
/* Equal */
bool
! cube_same(NDBOX * box_a, NDBOX * box_b)
{
int i;
- NDBOX *a;
- NDBOX *b;
! if ((box_a == NULL) || (box_b == NULL))
return (FALSE);
- a = swap_corners(box_a);
- b = swap_corners(box_b);
-
/* swap the box pointers if necessary */
if (a->dim < b->dim)
{
--- 909,921 ----
/* Equal */
bool
! cube_same(NDBOX * a, NDBOX * b)
{
int i;
! if ((a == NULL) || (b == NULL))
return (FALSE);
/* swap the box pointers if necessary */
if (a->dim < b->dim)
{
***************
*** 939,953 ****
for (i = 0; i < b->dim; i++)
{
! if (a->x[i] != b->x[i])
return (FALSE);
! if (a->x[i + a->dim] != b->x[i + b->dim])
return (FALSE);
}
/*
* all dimensions of (b) are compared to those of (a); instead of
* those in (a) absent in (b), compare (a) to zero
*/
for (i = b->dim; i < a->dim; i++)
{
--- 927,945 ----
for (i = 0; i < b->dim; i++)
{
! if (min(a->x[i], a->x[a->dim + i]) !=
! min(b->x[i], b->x[b->dim + i]))
return (FALSE);
! if (max(a->x[i], a->x[a->dim + i]) !=
! max(b->x[i], b->x[b->dim + i]))
return (FALSE);
}
/*
* all dimensions of (b) are compared to those of (a); instead of
* 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++)
{
***************
*** 957,996 ****
return (FALSE);
}
- pfree(a);
- pfree(b);
-
return (TRUE);
}
/* Different */
bool
! cube_different(NDBOX * box_a, NDBOX * box_b)
{
! return (!cube_same(box_a, box_b));
}
/* Contains */
/* Box(A) CONTAINS Box(B) IFF pt(A) < pt(B) */
bool
! cube_contains(NDBOX * box_a, NDBOX * box_b)
{
int i;
- NDBOX *a;
- NDBOX *b;
! if ((box_a == NULL) || (box_b == NULL))
return (FALSE);
- a = swap_corners(box_a);
- b = swap_corners(box_b);
-
if (a->dim < b->dim)
{
/*
* the further comparisons will make sense if the excess
* dimensions of (b) were zeroes
*/
for (i = a->dim; i < b->dim; i++)
{
--- 949,982 ----
return (FALSE);
}
return (TRUE);
}
/* Different */
bool
! cube_different(NDBOX * a, NDBOX * b)
{
! return (!cube_same(a, b));
}
/* Contains */
/* Box(A) CONTAINS Box(B) IFF pt(A) < pt(B) */
bool
! cube_contains(NDBOX * a, NDBOX * b)
{
int i;
! if ((a == NULL) || (b == NULL))
return (FALSE);
if (a->dim < b->dim)
{
/*
* the further comparisons will make sense if the excess
* 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++)
{
***************
*** 1004,1018 ****
/* Can't care less about the excess dimensions of (a), if any */
for (i = 0; i < min(a->dim, b->dim); i++)
{
! if (a->x[i] > b->x[i])
return (FALSE);
! if (a->x[i + a->dim] < b->x[i + b->dim])
return (FALSE);
}
- pfree(a);
- pfree(b);
-
return (TRUE);
}
--- 990,1003 ----
/* Can't care less about the excess dimensions of (a), if any */
for (i = 0; i < min(a->dim, b->dim); i++)
{
! if (min(a->x[i], a->x[a->dim + i]) >
! min(b->x[i], b->x[b->dim + i]))
return (FALSE);
! if (max(a->x[i], a->x[a->dim + i]) <
! max(b->x[i], b->x[b->dim + i]))
return (FALSE);
}
return (TRUE);
}
***************
*** 1030,1051 ****
/* Overlap */
/* Box(A) Overlap Box(B) IFF (pt(a)LL < pt(B)UR) && (pt(b)LL < pt(a)UR) */
bool
! cube_overlap(NDBOX * box_a, NDBOX * box_b)
{
int i;
- NDBOX *a;
- NDBOX *b;
/*
* This *very bad* error was found in the source: if ( (a==NULL) ||
* (b=NULL) ) return(FALSE);
*/
! if ((box_a == NULL) || (box_b == NULL))
return (FALSE);
- a = swap_corners(box_a);
- b = swap_corners(box_b);
-
/* swap the box pointers if needed */
if (a->dim < b->dim)
{
--- 1015,1031 ----
/* Overlap */
/* Box(A) Overlap Box(B) IFF (pt(a)LL < pt(B)UR) && (pt(b)LL < pt(a)UR) */
bool
! cube_overlap(NDBOX * a, NDBOX * b)
{
int i;
/*
* This *very bad* error was found in the source: if ( (a==NULL) ||
* (b=NULL) ) return(FALSE);
*/
! if ((a == NULL) || (b == NULL))
return (FALSE);
/* swap the box pointers if needed */
if (a->dim < b->dim)
{
***************
*** 1058,1081 ****
/* compare within the dimensions of (b) */
for (i = 0; i < b->dim; i++)
{
! if (a->x[i] > b->x[i + b->dim])
return (FALSE);
! if (a->x[i + a->dim] < b->x[i])
return (FALSE);
}
/* compare to zero those dimensions in (a) absent in (b) */
for (i = b->dim; i < a->dim; i++)
{
! if (a->x[i] > 0)
return (FALSE);
! if (a->x[i + a->dim] < 0)
return (FALSE);
}
- pfree(a);
- pfree(b);
-
return (TRUE);
}
--- 1038,1060 ----
/* compare within the dimensions of (b) */
for (i = 0; i < b->dim; i++)
{
! if (min(a->x[i], a->x[a->dim + i]) >
! max(b->x[i], b->x[b->dim + i]))
return (FALSE);
! if (max(a->x[i], a->x[a->dim + i]) <
! min(b->x[i], b->x[b->dim + i]))
return (FALSE);
}
/* compare to zero those dimensions in (a) absent in (b) */
for (i = b->dim; i < a->dim; i++)
{
! if (min(a->x[i], a->x[a->dim + i]) > 0)
return (FALSE);
! if (max(a->x[i], a->x[a->dim + i]) < 0)
return (FALSE);
}
return (TRUE);
}
***************
*** 1085,1099 ****
between 1D projections of the boxes onto Cartesian axes. Assuming zero
distance between overlapping projections, this metric coincides with the
"common sense" geometric distance */
! float *
cube_distance(NDBOX * a, NDBOX * b)
{
int i;
double d,
distance;
! float *result;
! result = (float *) palloc(sizeof(float));
/* swap the box pointers if needed */
if (a->dim < b->dim)
--- 1064,1078 ----
between 1D projections of the boxes onto Cartesian axes. Assuming zero
distance between overlapping projections, this metric coincides with the
"common sense" geometric distance */
! double *
cube_distance(NDBOX * a, NDBOX * b)
{
int i;
double d,
distance;
! double *result;
! result = (double *) palloc(sizeof(double));
/* swap the box pointers if needed */
if (a->dim < b->dim)
***************
*** 1119,1131 ****
distance += d * d;
}
! *result = (float) sqrt(distance);
return (result);
}
! static float
! distance_1D(float a1, float a2, float b1, float b2)
{
/* interval (a) is entirely on the left of (b) */
if ((a1 <= b1) && (a2 <= b1) && (a1 <= b2) && (a2 <= b2))
--- 1098,1110 ----
distance += d * d;
}
! *result = (double) sqrt(distance);
return (result);
}
! static double
! distance_1D(double a1, double a2, double b1, double b2)
{
/* interval (a) is entirely on the left of (b) */
if ((a1 <= b1) && (a2 <= b1) && (a1 <= b2) && (a2 <= b2))
***************
*** 1139,1163 ****
return (0.0);
}
! /* normalize the box's co-ordinates by placing min(xLL,xUR) to LL
! and max(xLL,xUR) to UR
! */
! static NDBOX *
! swap_corners(NDBOX * a)
{
! int i,
! 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++)
! {
! result->x[i] = min(a->x[i], a->x[j]);
! result->x[j] = max(a->x[i], a->x[j]);
! }
! return (result);
}
--- 1118,1208 ----
return (0.0);
}
! /* Test if a box is also a point */
! bool
! cube_is_point(NDBOX * a)
{
! int i,
! j;
! for (i = 0, j = a->dim; i < a->dim; i++, j++)
! {
! if (a->x[i] != a->x[j]) return FALSE;
! }
! 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;
}
diff -c -r -N --exclude=CVS cube/cube.sql.in newcube/cube.sql.in
*** cube/cube.sql.in Fri Aug 23 16:01:50 2002
--- newcube/cube.sql.in Wed Aug 28 08:10:24 2002
***************
*** 8,19 ****
CREATE FUNCTION cube_in(cstring)
RETURNS cube
AS 'MODULE_PATHNAME'
! LANGUAGE 'c' WITH (isStrict);
CREATE FUNCTION cube_out(cube)
RETURNS cstring
AS 'MODULE_PATHNAME'
! LANGUAGE 'c' WITH (isStrict);
CREATE TYPE cube (
internallength = variable,
--- 8,19 ----
CREATE FUNCTION cube_in(cstring)
RETURNS cube
AS 'MODULE_PATHNAME'
! LANGUAGE 'c'IMMUTABLE STRICT;
CREATE FUNCTION cube_out(cube)
RETURNS cstring
AS 'MODULE_PATHNAME'
! LANGUAGE 'c'IMMUTABLE STRICT;
CREATE TYPE cube (
internallength = variable,
***************
*** 24,29 ****
--- 24,39 ----
COMMENT ON TYPE cube IS
'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
--
***************
*** 31,55 ****
-- Left/Right methods
CREATE FUNCTION cube_over_left(cube, cube) RETURNS bool
! AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict);
COMMENT ON FUNCTION cube_over_left(cube, cube) IS
'is over and left of (NOT IMPLEMENTED)';
CREATE FUNCTION cube_over_right(cube, cube) RETURNS bool
! AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict);
COMMENT ON FUNCTION cube_over_right(cube, cube) IS
'is over and right of (NOT IMPLEMENTED)';
CREATE FUNCTION cube_left(cube, cube) RETURNS bool
! AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict);
COMMENT ON FUNCTION cube_left(cube, cube) IS
'is left of (NOT IMPLEMENTED)';
CREATE FUNCTION cube_right(cube, cube) RETURNS bool
! AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict);
COMMENT ON FUNCTION cube_right(cube, cube) IS
'is right of (NOT IMPLEMENTED)';
--- 41,65 ----
-- Left/Right methods
CREATE FUNCTION cube_over_left(cube, cube) RETURNS bool
! AS 'MODULE_PATHNAME' LANGUAGE 'c' IMMUTABLE STRICT;
COMMENT ON FUNCTION cube_over_left(cube, cube) IS
'is over and left of (NOT IMPLEMENTED)';
CREATE FUNCTION cube_over_right(cube, cube) RETURNS bool
! AS 'MODULE_PATHNAME' LANGUAGE 'c' IMMUTABLE STRICT;
COMMENT ON FUNCTION cube_over_right(cube, cube) IS
'is over and right of (NOT IMPLEMENTED)';
CREATE FUNCTION cube_left(cube, cube) RETURNS bool
! AS 'MODULE_PATHNAME' LANGUAGE 'c' IMMUTABLE STRICT;
COMMENT ON FUNCTION cube_left(cube, cube) IS
'is left of (NOT IMPLEMENTED)';
CREATE FUNCTION cube_right(cube, cube) RETURNS bool
! AS 'MODULE_PATHNAME' LANGUAGE 'c' IMMUTABLE STRICT;
COMMENT ON FUNCTION cube_right(cube, cube) IS
'is right of (NOT IMPLEMENTED)';
***************
*** 58,100 ****
-- Comparison methods
CREATE FUNCTION cube_lt(cube, cube) RETURNS bool
! AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict);
COMMENT ON FUNCTION cube_lt(cube, cube) IS
'lower than';
CREATE FUNCTION cube_gt(cube, cube) RETURNS bool
! AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict);
COMMENT ON FUNCTION cube_gt(cube, cube) IS
'greater than';
CREATE FUNCTION cube_contains(cube, cube) RETURNS bool
! AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict);
COMMENT ON FUNCTION cube_contains(cube, cube) IS
'contains';
CREATE FUNCTION cube_contained(cube, cube) RETURNS bool
! AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict);
COMMENT ON FUNCTION cube_contained(cube, cube) IS
'contained in';
CREATE FUNCTION cube_overlap(cube, cube) RETURNS bool
! AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict);
COMMENT ON FUNCTION cube_overlap(cube, cube) IS
'overlaps';
CREATE FUNCTION cube_same(cube, cube) RETURNS bool
! AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict);
COMMENT ON FUNCTION cube_same(cube, cube) IS
'same as';
CREATE FUNCTION cube_different(cube, cube) RETURNS bool
! AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict);
COMMENT ON FUNCTION cube_different(cube, cube) IS
'different';
--- 68,110 ----
-- Comparison methods
CREATE FUNCTION cube_lt(cube, cube) RETURNS bool
! AS 'MODULE_PATHNAME' LANGUAGE 'c' IMMUTABLE STRICT;
COMMENT ON FUNCTION cube_lt(cube, cube) IS
'lower than';
CREATE FUNCTION cube_gt(cube, cube) RETURNS bool
! AS 'MODULE_PATHNAME' LANGUAGE 'c' IMMUTABLE STRICT;
COMMENT ON FUNCTION cube_gt(cube, cube) IS
'greater than';
CREATE FUNCTION cube_contains(cube, cube) RETURNS bool
! AS 'MODULE_PATHNAME' LANGUAGE 'c' IMMUTABLE STRICT;
COMMENT ON FUNCTION cube_contains(cube, cube) IS
'contains';
CREATE FUNCTION cube_contained(cube, cube) RETURNS bool
! AS 'MODULE_PATHNAME' LANGUAGE 'c' IMMUTABLE STRICT;
COMMENT ON FUNCTION cube_contained(cube, cube) IS
'contained in';
CREATE FUNCTION cube_overlap(cube, cube) RETURNS bool
! AS 'MODULE_PATHNAME' LANGUAGE 'c' IMMUTABLE STRICT;
COMMENT ON FUNCTION cube_overlap(cube, cube) IS
'overlaps';
CREATE FUNCTION cube_same(cube, cube) RETURNS bool
! AS 'MODULE_PATHNAME' LANGUAGE 'c' IMMUTABLE STRICT;
COMMENT ON FUNCTION cube_same(cube, cube) IS
'same as';
CREATE FUNCTION cube_different(cube, cube) RETURNS bool
! AS 'MODULE_PATHNAME' LANGUAGE 'c' IMMUTABLE STRICT;
COMMENT ON FUNCTION cube_different(cube, cube) IS
'different';
***************
*** 102,123 ****
-- support routines for indexing
CREATE FUNCTION cube_union(cube, cube) RETURNS cube
! AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict);
CREATE FUNCTION cube_inter(cube, cube) RETURNS cube
! AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict);
! CREATE FUNCTION cube_size(cube) RETURNS float4
! AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict);
-- Misc N-dimensional functions
-- proximity routines
! CREATE FUNCTION cube_distance(cube, cube) RETURNS float4
! AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict);
--
-- OPERATORS
--- 112,153 ----
-- support routines for indexing
CREATE FUNCTION cube_union(cube, cube) RETURNS cube
! AS 'MODULE_PATHNAME' LANGUAGE 'c' IMMUTABLE STRICT;
CREATE FUNCTION cube_inter(cube, cube) RETURNS cube
! AS 'MODULE_PATHNAME' LANGUAGE 'c' IMMUTABLE STRICT;
! CREATE FUNCTION cube_size(cube) RETURNS float8
! AS 'MODULE_PATHNAME' LANGUAGE 'c' IMMUTABLE STRICT;
-- Misc N-dimensional functions
-- proximity routines
! CREATE FUNCTION cube_distance(cube, cube) RETURNS float8
! 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
***************
*** 202,208 ****
AS 'MODULE_PATHNAME' LANGUAGE 'c';
CREATE FUNCTION g_cube_penalty(internal,internal,internal) RETURNS internal
! AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict);
CREATE FUNCTION g_cube_picksplit(internal, internal) RETURNS internal
AS 'MODULE_PATHNAME' LANGUAGE 'c';
--- 232,238 ----
AS 'MODULE_PATHNAME' LANGUAGE 'c';
CREATE FUNCTION g_cube_penalty(internal,internal,internal) RETURNS internal
! AS 'MODULE_PATHNAME' LANGUAGE 'c' STRICT;
CREATE FUNCTION g_cube_picksplit(internal, internal) RETURNS internal
AS 'MODULE_PATHNAME' LANGUAGE 'c';
diff -c -r -N --exclude=CVS cube/cubedata.h newcube/cubedata.h
*** cube/cubedata.h Mon Nov 5 11:46:22 2001
--- newcube/cubedata.h Tue Aug 27 19:13:19 2002
***************
*** 2,6 ****
{
unsigned int size; /* required to be a Postgres varlena
type */
unsigned int dim;
! float x[1];
} NDBOX;
--- 2,6 ----
{
unsigned int size; /* required to be a Postgres varlena
type */
unsigned int dim;
! double x[1];
} NDBOX;
diff -c -r -N --exclude=CVS cube/cubeparse.y newcube/cubeparse.y
*** cube/cubeparse.y Mon Dec 11 14:39:14 2000
--- newcube/cubeparse.y Tue Aug 27 21:35:11 2002
***************
*** 198,206 ****
NDBOX * bp;
char * s;
int i;
! int size = offsetof(NDBOX, x[0]) + sizeof(float) * dim * 2;
bp = palloc(size);
bp->size = size;
bp->dim = dim;
--- 198,207 ----
NDBOX * bp;
char * s;
int i;
! int size = offsetof(NDBOX, x[0]) + sizeof(double) * dim * 2;
bp = palloc(size);
+ memset(bp, 0, size);
bp->size = size;
bp->dim = dim;
***************
*** 217,223 ****
s++; i++;
bp->x[i] = strtod(s, NULL);
}
!
return(bp);
}
--- 218,224 ----
s++; i++;
bp->x[i] = strtod(s, NULL);
}
!
return(bp);
}
***************
*** 230,238 ****
int dim = delim_count(str, ',') + 1;
char * s = str;
! size = offsetof(NDBOX, x[0]) + sizeof(float) * dim * 2;
bp = palloc(size);
bp->size = size;
bp->dim = dim;
--- 231,240 ----
int dim = delim_count(str, ',') + 1;
char * s = str;
! size = offsetof(NDBOX, x[0]) + sizeof(double) * dim * 2;
bp = palloc(size);
+ memset(bp, 0, size);
bp->size = size;
bp->dim = dim;
diff -c -r -N --exclude=CVS cube/cubescan.l newcube/cubescan.l
*** cube/cubescan.l Tue Jul 30 11:33:08 2002
--- newcube/cubescan.l Tue Aug 27 09:04:16 2002
***************
*** 34,40 ****
n [0-9]+
integer [+-]?{n}
! real [+-]?({n}\.{n}?)|(\.{n})
float ({integer}|{real})([eE]{integer})?
%%
--- 34,40 ----
n [0-9]+
integer [+-]?{n}
! real [+-]?({n}\.{n}?|\.{n})
float ({integer}|{real})([eE]{integer})?
%%
diff -c -r -N --exclude=CVS cube/expected/cube.out newcube/expected/cube.out
*** cube/expected/cube.out Fri Aug 23 16:01:50 2002
--- newcube/expected/cube.out Wed Aug 28 09:32:44 2002
***************
*** 43,49 ****
(1 row)
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'
SELECT '1.0'::cube AS cube;
cube
--- 43,52 ----
(1 row)
SELECT '-.1'::cube AS cube;
! cube
! --------
! (-0.1)
! (1 row)
SELECT '1.0'::cube AS cube;
cube
***************
*** 57,108 ****
(-1)
(1 row)
! SELECT '1e7'::cube AS cube;
cube
---------
! (1e+07)
(1 row)
! SELECT '-1e7'::cube AS cube;
cube
----------
! (-1e+07)
(1 row)
! SELECT '1.0e7'::cube AS cube;
cube
---------
! (1e+07)
(1 row)
! SELECT '-1.0e7'::cube AS cube;
cube
----------
! (-1e+07)
(1 row)
! SELECT '1e+7'::cube AS cube;
cube
---------
! (1e+07)
(1 row)
! SELECT '-1e+7'::cube AS cube;
cube
----------
! (-1e+07)
(1 row)
! SELECT '1.0e+7'::cube AS cube;
cube
---------
! (1e+07)
(1 row)
! SELECT '-1.0e+7'::cube AS cube;
cube
----------
! (-1e+07)
(1 row)
SELECT '1e-7'::cube AS cube;
--- 60,111 ----
(-1)
(1 row)
! SELECT '1e27'::cube AS cube;
cube
---------
! (1e+27)
(1 row)
! SELECT '-1e27'::cube AS cube;
cube
----------
! (-1e+27)
(1 row)
! SELECT '1.0e27'::cube AS cube;
cube
---------
! (1e+27)
(1 row)
! SELECT '-1.0e27'::cube AS cube;
cube
----------
! (-1e+27)
(1 row)
! SELECT '1e+27'::cube AS cube;
cube
---------
! (1e+27)
(1 row)
! SELECT '-1e+27'::cube AS cube;
cube
----------
! (-1e+27)
(1 row)
! SELECT '1.0e+27'::cube AS cube;
cube
---------
! (1e+27)
(1 row)
! SELECT '-1.0e+27'::cube AS cube;
cube
----------
! (-1e+27)
(1 row)
SELECT '1e-7'::cube AS cube;
***************
*** 141,146 ****
--- 144,185 ----
(0)
(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)
SELECT '1,2'::cube AS cube;
cube
***************
*** 922,927 ****
--- 961,1184 ----
bool
------
f
+ (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
diff -c -r -N --exclude=CVS cube/sql/cube.sql newcube/sql/cube.sql
*** cube/sql/cube.sql Thu Aug 23 10:10:17 2001
--- newcube/sql/cube.sql Wed Aug 28 09:32:13 2002
***************
*** 23,42 ****
SELECT '-.1'::cube AS cube;
SELECT '1.0'::cube AS cube;
SELECT '-1.0'::cube AS cube;
! SELECT '1e7'::cube AS cube;
! SELECT '-1e7'::cube AS cube;
! SELECT '1.0e7'::cube AS cube;
! SELECT '-1.0e7'::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 '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 '1e-700'::cube AS cube;
SELECT '-1e-700'::cube AS cube;
-- simple lists (points)
SELECT '1,2'::cube AS cube;
--- 23,48 ----
SELECT '-.1'::cube AS cube;
SELECT '1.0'::cube AS cube;
SELECT '-1.0'::cube AS cube;
! SELECT '1e27'::cube AS cube;
! SELECT '-1e27'::cube AS cube;
! SELECT '1.0e27'::cube AS cube;
! SELECT '-1.0e27'::cube AS cube;
! SELECT '1e+27'::cube AS cube;
! SELECT '-1e+27'::cube AS cube;
! SELECT '1.0e+27'::cube AS cube;
! SELECT '-1.0e+27'::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 '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)
SELECT '1,2'::cube AS cube;
***************
*** 230,235 ****
--- 236,295 ----
SELECT '(-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
--
---------------------------(end of broadcast)---------------------------
TIP 2: you can get off all lists at once with the unregister command
(send "unregister YourEmailAddressHere" to [EMAIL PROTECTED])