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 selkovjr@mcs.anl.gov + + ------------------------------------------------------------------------ + + Minor updates to this package were made by Bruno Wolff III + 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 --