2000-12-11 21:39:15 +01:00
|
|
|
/******************************************************************************
|
2010-09-20 22:08:53 +02:00
|
|
|
contrib/cube/cube.c
|
2006-03-11 05:38:42 +01:00
|
|
|
|
2000-12-11 21:39:15 +01:00
|
|
|
This file contains routines that can be bound to a Postgres backend and
|
|
|
|
called by the backend in the process of processing queries. The calling
|
|
|
|
format for these routines is dictated by Postgres architecture.
|
|
|
|
******************************************************************************/
|
|
|
|
|
|
|
|
#include "postgres.h"
|
|
|
|
|
2005-05-17 05:34:18 +02:00
|
|
|
#include <float.h>
|
2000-12-11 21:39:15 +01:00
|
|
|
#include <math.h>
|
|
|
|
|
|
|
|
#include "access/gist.h"
|
2015-05-15 22:03:16 +02:00
|
|
|
#include "access/stratnum.h"
|
2011-09-04 07:13:16 +02:00
|
|
|
#include "utils/array.h"
|
2000-12-11 21:39:15 +01:00
|
|
|
#include "utils/builtins.h"
|
|
|
|
|
|
|
|
#include "cubedata.h"
|
|
|
|
|
2006-05-31 00:12:16 +02:00
|
|
|
PG_MODULE_MAGIC;
|
|
|
|
|
2006-07-27 23:55:09 +02:00
|
|
|
/*
|
|
|
|
* Taken from the intarray contrib header
|
|
|
|
*/
|
|
|
|
#define ARRPTR(x) ( (double *) ARR_DATA_PTR(x) )
|
|
|
|
#define ARRNELEMS(x) ArrayGetNItems( ARR_NDIM(x), ARR_DIMS(x))
|
|
|
|
|
2000-12-11 21:39:15 +01:00
|
|
|
/*
|
|
|
|
** Input/Output routines
|
|
|
|
*/
|
2006-07-26 01:23:45 +02:00
|
|
|
PG_FUNCTION_INFO_V1(cube_in);
|
|
|
|
PG_FUNCTION_INFO_V1(cube_a_f8_f8);
|
|
|
|
PG_FUNCTION_INFO_V1(cube_a_f8);
|
|
|
|
PG_FUNCTION_INFO_V1(cube_out);
|
|
|
|
PG_FUNCTION_INFO_V1(cube_f8);
|
|
|
|
PG_FUNCTION_INFO_V1(cube_f8_f8);
|
|
|
|
PG_FUNCTION_INFO_V1(cube_c_f8);
|
|
|
|
PG_FUNCTION_INFO_V1(cube_c_f8_f8);
|
|
|
|
PG_FUNCTION_INFO_V1(cube_dim);
|
|
|
|
PG_FUNCTION_INFO_V1(cube_ll_coord);
|
|
|
|
PG_FUNCTION_INFO_V1(cube_ur_coord);
|
2015-12-18 12:38:27 +01:00
|
|
|
PG_FUNCTION_INFO_V1(cube_coord);
|
|
|
|
PG_FUNCTION_INFO_V1(cube_coord_llur);
|
2006-07-26 01:23:45 +02:00
|
|
|
PG_FUNCTION_INFO_V1(cube_subset);
|
|
|
|
|
2001-03-22 05:01:46 +01:00
|
|
|
/*
|
2000-12-11 21:39:15 +01:00
|
|
|
** GiST support methods
|
|
|
|
*/
|
2006-07-26 01:23:45 +02:00
|
|
|
|
|
|
|
PG_FUNCTION_INFO_V1(g_cube_consistent);
|
|
|
|
PG_FUNCTION_INFO_V1(g_cube_compress);
|
|
|
|
PG_FUNCTION_INFO_V1(g_cube_decompress);
|
|
|
|
PG_FUNCTION_INFO_V1(g_cube_penalty);
|
|
|
|
PG_FUNCTION_INFO_V1(g_cube_picksplit);
|
|
|
|
PG_FUNCTION_INFO_V1(g_cube_union);
|
|
|
|
PG_FUNCTION_INFO_V1(g_cube_same);
|
2015-12-18 12:38:27 +01:00
|
|
|
PG_FUNCTION_INFO_V1(g_cube_distance);
|
2006-07-26 01:23:45 +02:00
|
|
|
|
2003-09-14 03:52:25 +02:00
|
|
|
/*
|
|
|
|
** B-tree support functions
|
|
|
|
*/
|
2006-07-26 01:23:45 +02:00
|
|
|
PG_FUNCTION_INFO_V1(cube_eq);
|
|
|
|
PG_FUNCTION_INFO_V1(cube_ne);
|
|
|
|
PG_FUNCTION_INFO_V1(cube_lt);
|
|
|
|
PG_FUNCTION_INFO_V1(cube_gt);
|
|
|
|
PG_FUNCTION_INFO_V1(cube_le);
|
|
|
|
PG_FUNCTION_INFO_V1(cube_ge);
|
|
|
|
PG_FUNCTION_INFO_V1(cube_cmp);
|
|
|
|
|
2000-12-11 21:39:15 +01:00
|
|
|
/*
|
2001-05-31 20:16:55 +02:00
|
|
|
** R-tree support functions
|
2000-12-11 21:39:15 +01:00
|
|
|
*/
|
2006-07-26 01:23:45 +02:00
|
|
|
|
|
|
|
PG_FUNCTION_INFO_V1(cube_contains);
|
|
|
|
PG_FUNCTION_INFO_V1(cube_contained);
|
|
|
|
PG_FUNCTION_INFO_V1(cube_overlap);
|
|
|
|
PG_FUNCTION_INFO_V1(cube_union);
|
|
|
|
PG_FUNCTION_INFO_V1(cube_inter);
|
|
|
|
PG_FUNCTION_INFO_V1(cube_size);
|
|
|
|
|
2000-12-11 21:39:15 +01:00
|
|
|
/*
|
|
|
|
** miscellaneous
|
|
|
|
*/
|
2015-12-18 12:38:27 +01:00
|
|
|
PG_FUNCTION_INFO_V1(distance_taxicab);
|
2006-07-26 01:23:45 +02:00
|
|
|
PG_FUNCTION_INFO_V1(cube_distance);
|
2015-12-18 12:38:27 +01:00
|
|
|
PG_FUNCTION_INFO_V1(distance_chebyshev);
|
2006-07-26 01:23:45 +02:00
|
|
|
PG_FUNCTION_INFO_V1(cube_is_point);
|
|
|
|
PG_FUNCTION_INFO_V1(cube_enlarge);
|
|
|
|
|
|
|
|
/*
|
|
|
|
** For internal use only
|
|
|
|
*/
|
2009-06-11 16:49:15 +02:00
|
|
|
int32 cube_cmp_v0(NDBOX *a, NDBOX *b);
|
|
|
|
bool cube_contains_v0(NDBOX *a, NDBOX *b);
|
|
|
|
bool cube_overlap_v0(NDBOX *a, NDBOX *b);
|
|
|
|
NDBOX *cube_union_v0(NDBOX *a, NDBOX *b);
|
|
|
|
void rt_cube_size(NDBOX *a, double *sz);
|
|
|
|
NDBOX *g_cube_binary_union(NDBOX *r1, NDBOX *r2, int *sizep);
|
|
|
|
bool g_cube_leaf_consistent(NDBOX *key, NDBOX *query, StrategyNumber strategy);
|
|
|
|
bool g_cube_internal_consistent(NDBOX *key, NDBOX *query, StrategyNumber strategy);
|
2000-12-11 21:39:15 +01:00
|
|
|
|
2001-03-22 05:01:46 +01:00
|
|
|
/*
|
2000-12-11 21:39:15 +01:00
|
|
|
** Auxiliary funxtions
|
|
|
|
*/
|
2002-08-30 01:03:58 +02:00
|
|
|
static double distance_1D(double a1, double a2, double b1, double b2);
|
2014-05-06 18:12:18 +02:00
|
|
|
static bool cube_is_point_internal(NDBOX *cube);
|
2000-12-11 21:39:15 +01:00
|
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
* Input/Output functions
|
|
|
|
*****************************************************************************/
|
|
|
|
|
|
|
|
/* NdBox = [(lowerleft),(upperright)] */
|
|
|
|
/* [(xLL(1)...xLL(N)),(xUR(1)...xUR(n))] */
|
2006-07-26 01:23:45 +02:00
|
|
|
Datum
|
|
|
|
cube_in(PG_FUNCTION_ARGS)
|
2000-12-11 21:39:15 +01:00
|
|
|
{
|
2008-05-29 20:46:40 +02:00
|
|
|
char *str = PG_GETARG_CSTRING(0);
|
2013-07-29 16:42:37 +02:00
|
|
|
NDBOX *result;
|
2000-12-11 21:39:15 +01:00
|
|
|
|
2003-09-14 03:52:25 +02:00
|
|
|
cube_scanner_init(str);
|
2000-12-11 21:39:15 +01:00
|
|
|
|
2001-03-22 05:01:46 +01:00
|
|
|
if (cube_yyparse(&result) != 0)
|
Improve contrib/cube's handling of zero-D cubes, infinities, and NaNs.
It's always been possible to create a zero-dimensional cube by converting
from a zero-length float8 array, but cube_in failed to accept the '()'
representation that cube_out produced for that case, resulting in a
dump/reload hazard. Make it accept the case. Also fix a couple of
other places that didn't behave sanely for zero-dimensional cubes:
cube_size would produce 1.0 when surely the answer should be 0.0,
and g_cube_distance risked a divide-by-zero failure.
Likewise, it's always been possible to create cubes containing float8
infinity or NaN coordinate values, but cube_in couldn't parse such input,
and cube_out produced platform-dependent spellings of the values. Convert
them to use float8in_internal and float8out_internal so that the behavior
will be the same as for float8, as we recently did for the core geometric
types (cf commit 50861cd68). As in that commit, I don't pretend that this
patch fixes all insane corner-case behaviors that may exist for NaNs, but
it's a step forward.
(This change allows removal of the separate cube_1.out and cube_3.out
expected-files, as the platform dependency that previously required them
is now gone: an underflowing coordinate value will now produce an error
not plus or minus zero.)
Make errors from cube_in follow project conventions as to spelling
("invalid input syntax for cube" not "bad cube representation")
and errcode (INVALID_TEXT_REPRESENTATION not SYNTAX_ERROR).
Also a few marginal code cleanups and comment improvements.
Tom Lane, reviewed by Amul Sul
Discussion: <15085.1472494782@sss.pgh.pa.us>
2016-09-27 17:38:33 +02:00
|
|
|
cube_yyerror(&result, "cube parser failed");
|
2003-09-14 03:52:25 +02:00
|
|
|
|
|
|
|
cube_scanner_finish();
|
2000-12-11 21:39:15 +01:00
|
|
|
|
2017-09-18 21:21:23 +02:00
|
|
|
PG_RETURN_NDBOX_P(result);
|
2000-12-11 21:39:15 +01:00
|
|
|
}
|
|
|
|
|
2006-07-26 01:23:45 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
** Allows the construction of a cube from 2 float[]'s
|
|
|
|
*/
|
|
|
|
Datum
|
|
|
|
cube_a_f8_f8(PG_FUNCTION_ARGS)
|
|
|
|
{
|
2008-05-29 20:46:40 +02:00
|
|
|
ArrayType *ur = PG_GETARG_ARRAYTYPE_P(0);
|
|
|
|
ArrayType *ll = PG_GETARG_ARRAYTYPE_P(1);
|
|
|
|
NDBOX *result;
|
2006-10-04 02:30:14 +02:00
|
|
|
int i;
|
|
|
|
int dim;
|
|
|
|
int size;
|
Extend cube on-disk format to pack points more tightly.
If the lower left and upper right corners of a cube are the same, set a
flag in the cube header, and only store one copy of the coordinates. That
cuts the on-disk size into half for the common case that the cube datatype
is used to represent points rather than boxes.
The new format is backwards-compatible with the old one, so pg_upgrade
still works. However, to get the space savings, the data needs to be
rewritten. A simple VACUUM FULL or REINDEX is not enough, as the old
Datums will just be moved to the new heap/index as is. A pg_dump and
reload, or something similar like casting to text and back, will do the
trick.
This patch deliberately doesn't update all the alternative expected output
files, as I don't have access to machines that produce those outputs. I'm
not sure if they are still relevant, but if they are, the buildfarm will
tell us and produce the diff required to fix it. If none of the buildfarm
animals need them, they should be removed altogether.
Patch by Stas Kelvich.
2013-10-21 19:59:42 +02:00
|
|
|
bool point;
|
2006-10-04 02:30:14 +02:00
|
|
|
double *dur,
|
|
|
|
*dll;
|
2006-07-26 01:23:45 +02:00
|
|
|
|
2011-01-09 19:09:07 +01:00
|
|
|
if (array_contains_nulls(ur) || array_contains_nulls(ll))
|
2006-07-26 01:23:45 +02:00
|
|
|
ereport(ERROR,
|
2006-10-04 02:30:14 +02:00
|
|
|
(errcode(ERRCODE_ARRAY_ELEMENT_ERROR),
|
2008-05-29 20:46:40 +02:00
|
|
|
errmsg("cannot work with arrays containing NULLs")));
|
2006-07-26 01:23:45 +02:00
|
|
|
|
|
|
|
dim = ARRNELEMS(ur);
|
|
|
|
if (ARRNELEMS(ll) != dim)
|
|
|
|
ereport(ERROR,
|
2006-10-04 02:30:14 +02:00
|
|
|
(errcode(ERRCODE_ARRAY_ELEMENT_ERROR),
|
|
|
|
errmsg("UR and LL arrays must be of same length")));
|
2006-07-26 01:23:45 +02:00
|
|
|
|
|
|
|
dur = ARRPTR(ur);
|
|
|
|
dll = ARRPTR(ll);
|
|
|
|
|
Extend cube on-disk format to pack points more tightly.
If the lower left and upper right corners of a cube are the same, set a
flag in the cube header, and only store one copy of the coordinates. That
cuts the on-disk size into half for the common case that the cube datatype
is used to represent points rather than boxes.
The new format is backwards-compatible with the old one, so pg_upgrade
still works. However, to get the space savings, the data needs to be
rewritten. A simple VACUUM FULL or REINDEX is not enough, as the old
Datums will just be moved to the new heap/index as is. A pg_dump and
reload, or something similar like casting to text and back, will do the
trick.
This patch deliberately doesn't update all the alternative expected output
files, as I don't have access to machines that produce those outputs. I'm
not sure if they are still relevant, but if they are, the buildfarm will
tell us and produce the diff required to fix it. If none of the buildfarm
animals need them, they should be removed altogether.
Patch by Stas Kelvich.
2013-10-21 19:59:42 +02:00
|
|
|
/* Check if it's a point */
|
|
|
|
point = true;
|
|
|
|
for (i = 0; i < dim; i++)
|
|
|
|
{
|
|
|
|
if (dur[i] != dll[i])
|
|
|
|
{
|
|
|
|
point = false;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
size = point ? POINT_SIZE(dim) : CUBE_SIZE(dim);
|
2007-02-28 00:48:10 +01:00
|
|
|
result = (NDBOX *) palloc0(size);
|
|
|
|
SET_VARSIZE(result, size);
|
Extend cube on-disk format to pack points more tightly.
If the lower left and upper right corners of a cube are the same, set a
flag in the cube header, and only store one copy of the coordinates. That
cuts the on-disk size into half for the common case that the cube datatype
is used to represent points rather than boxes.
The new format is backwards-compatible with the old one, so pg_upgrade
still works. However, to get the space savings, the data needs to be
rewritten. A simple VACUUM FULL or REINDEX is not enough, as the old
Datums will just be moved to the new heap/index as is. A pg_dump and
reload, or something similar like casting to text and back, will do the
trick.
This patch deliberately doesn't update all the alternative expected output
files, as I don't have access to machines that produce those outputs. I'm
not sure if they are still relevant, but if they are, the buildfarm will
tell us and produce the diff required to fix it. If none of the buildfarm
animals need them, they should be removed altogether.
Patch by Stas Kelvich.
2013-10-21 19:59:42 +02:00
|
|
|
SET_DIM(result, dim);
|
2006-07-26 01:23:45 +02:00
|
|
|
|
2006-10-04 02:30:14 +02:00
|
|
|
for (i = 0; i < dim; i++)
|
2006-07-26 01:23:45 +02:00
|
|
|
result->x[i] = dur[i];
|
Extend cube on-disk format to pack points more tightly.
If the lower left and upper right corners of a cube are the same, set a
flag in the cube header, and only store one copy of the coordinates. That
cuts the on-disk size into half for the common case that the cube datatype
is used to represent points rather than boxes.
The new format is backwards-compatible with the old one, so pg_upgrade
still works. However, to get the space savings, the data needs to be
rewritten. A simple VACUUM FULL or REINDEX is not enough, as the old
Datums will just be moved to the new heap/index as is. A pg_dump and
reload, or something similar like casting to text and back, will do the
trick.
This patch deliberately doesn't update all the alternative expected output
files, as I don't have access to machines that produce those outputs. I'm
not sure if they are still relevant, but if they are, the buildfarm will
tell us and produce the diff required to fix it. If none of the buildfarm
animals need them, they should be removed altogether.
Patch by Stas Kelvich.
2013-10-21 19:59:42 +02:00
|
|
|
|
|
|
|
if (!point)
|
|
|
|
{
|
|
|
|
for (i = 0; i < dim; i++)
|
|
|
|
result->x[i + dim] = dll[i];
|
2006-07-26 01:23:45 +02:00
|
|
|
}
|
Extend cube on-disk format to pack points more tightly.
If the lower left and upper right corners of a cube are the same, set a
flag in the cube header, and only store one copy of the coordinates. That
cuts the on-disk size into half for the common case that the cube datatype
is used to represent points rather than boxes.
The new format is backwards-compatible with the old one, so pg_upgrade
still works. However, to get the space savings, the data needs to be
rewritten. A simple VACUUM FULL or REINDEX is not enough, as the old
Datums will just be moved to the new heap/index as is. A pg_dump and
reload, or something similar like casting to text and back, will do the
trick.
This patch deliberately doesn't update all the alternative expected output
files, as I don't have access to machines that produce those outputs. I'm
not sure if they are still relevant, but if they are, the buildfarm will
tell us and produce the diff required to fix it. If none of the buildfarm
animals need them, they should be removed altogether.
Patch by Stas Kelvich.
2013-10-21 19:59:42 +02:00
|
|
|
else
|
|
|
|
SET_POINT_BIT(result);
|
2006-07-26 01:23:45 +02:00
|
|
|
|
2017-09-18 21:21:23 +02:00
|
|
|
PG_RETURN_NDBOX_P(result);
|
2006-07-26 01:23:45 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
** Allows the construction of a zero-volume cube from a float[]
|
|
|
|
*/
|
|
|
|
Datum
|
|
|
|
cube_a_f8(PG_FUNCTION_ARGS)
|
2002-08-30 01:03:58 +02:00
|
|
|
{
|
2008-05-29 20:46:40 +02:00
|
|
|
ArrayType *ur = PG_GETARG_ARRAYTYPE_P(0);
|
|
|
|
NDBOX *result;
|
2006-10-04 02:30:14 +02:00
|
|
|
int i;
|
|
|
|
int dim;
|
|
|
|
int size;
|
|
|
|
double *dur;
|
2006-07-26 01:23:45 +02:00
|
|
|
|
2011-01-09 19:09:07 +01:00
|
|
|
if (array_contains_nulls(ur))
|
2006-07-26 01:23:45 +02:00
|
|
|
ereport(ERROR,
|
2006-10-04 02:30:14 +02:00
|
|
|
(errcode(ERRCODE_ARRAY_ELEMENT_ERROR),
|
2008-05-29 20:46:40 +02:00
|
|
|
errmsg("cannot work with arrays containing NULLs")));
|
2006-07-26 01:23:45 +02:00
|
|
|
|
|
|
|
dim = ARRNELEMS(ur);
|
|
|
|
|
|
|
|
dur = ARRPTR(ur);
|
|
|
|
|
Extend cube on-disk format to pack points more tightly.
If the lower left and upper right corners of a cube are the same, set a
flag in the cube header, and only store one copy of the coordinates. That
cuts the on-disk size into half for the common case that the cube datatype
is used to represent points rather than boxes.
The new format is backwards-compatible with the old one, so pg_upgrade
still works. However, to get the space savings, the data needs to be
rewritten. A simple VACUUM FULL or REINDEX is not enough, as the old
Datums will just be moved to the new heap/index as is. A pg_dump and
reload, or something similar like casting to text and back, will do the
trick.
This patch deliberately doesn't update all the alternative expected output
files, as I don't have access to machines that produce those outputs. I'm
not sure if they are still relevant, but if they are, the buildfarm will
tell us and produce the diff required to fix it. If none of the buildfarm
animals need them, they should be removed altogether.
Patch by Stas Kelvich.
2013-10-21 19:59:42 +02:00
|
|
|
size = POINT_SIZE(dim);
|
2007-02-28 00:48:10 +01:00
|
|
|
result = (NDBOX *) palloc0(size);
|
|
|
|
SET_VARSIZE(result, size);
|
Extend cube on-disk format to pack points more tightly.
If the lower left and upper right corners of a cube are the same, set a
flag in the cube header, and only store one copy of the coordinates. That
cuts the on-disk size into half for the common case that the cube datatype
is used to represent points rather than boxes.
The new format is backwards-compatible with the old one, so pg_upgrade
still works. However, to get the space savings, the data needs to be
rewritten. A simple VACUUM FULL or REINDEX is not enough, as the old
Datums will just be moved to the new heap/index as is. A pg_dump and
reload, or something similar like casting to text and back, will do the
trick.
This patch deliberately doesn't update all the alternative expected output
files, as I don't have access to machines that produce those outputs. I'm
not sure if they are still relevant, but if they are, the buildfarm will
tell us and produce the diff required to fix it. If none of the buildfarm
animals need them, they should be removed altogether.
Patch by Stas Kelvich.
2013-10-21 19:59:42 +02:00
|
|
|
SET_DIM(result, dim);
|
|
|
|
SET_POINT_BIT(result);
|
2006-07-26 01:23:45 +02:00
|
|
|
|
2006-10-04 02:30:14 +02:00
|
|
|
for (i = 0; i < dim; i++)
|
2006-07-26 01:23:45 +02:00
|
|
|
result->x[i] = dur[i];
|
|
|
|
|
2017-09-18 21:21:23 +02:00
|
|
|
PG_RETURN_NDBOX_P(result);
|
2002-08-30 01:03:58 +02:00
|
|
|
}
|
|
|
|
|
2006-07-26 01:23:45 +02:00
|
|
|
Datum
|
|
|
|
cube_subset(PG_FUNCTION_ARGS)
|
|
|
|
{
|
2017-09-18 21:21:23 +02:00
|
|
|
NDBOX *c = PG_GETARG_NDBOX_P(0);
|
2008-05-29 20:46:40 +02:00
|
|
|
ArrayType *idx = PG_GETARG_ARRAYTYPE_P(1);
|
|
|
|
NDBOX *result;
|
2006-10-04 02:30:14 +02:00
|
|
|
int size,
|
|
|
|
dim,
|
|
|
|
i;
|
|
|
|
int *dx;
|
2006-07-26 01:23:45 +02:00
|
|
|
|
2011-01-09 19:09:07 +01:00
|
|
|
if (array_contains_nulls(idx))
|
2006-07-26 01:23:45 +02:00
|
|
|
ereport(ERROR,
|
2006-10-04 02:30:14 +02:00
|
|
|
(errcode(ERRCODE_ARRAY_ELEMENT_ERROR),
|
2008-05-29 20:46:40 +02:00
|
|
|
errmsg("cannot work with arrays containing NULLs")));
|
2006-07-26 01:23:45 +02:00
|
|
|
|
2012-06-25 00:51:46 +02:00
|
|
|
dx = (int32 *) ARR_DATA_PTR(idx);
|
2006-07-26 01:23:45 +02:00
|
|
|
|
|
|
|
dim = ARRNELEMS(idx);
|
Extend cube on-disk format to pack points more tightly.
If the lower left and upper right corners of a cube are the same, set a
flag in the cube header, and only store one copy of the coordinates. That
cuts the on-disk size into half for the common case that the cube datatype
is used to represent points rather than boxes.
The new format is backwards-compatible with the old one, so pg_upgrade
still works. However, to get the space savings, the data needs to be
rewritten. A simple VACUUM FULL or REINDEX is not enough, as the old
Datums will just be moved to the new heap/index as is. A pg_dump and
reload, or something similar like casting to text and back, will do the
trick.
This patch deliberately doesn't update all the alternative expected output
files, as I don't have access to machines that produce those outputs. I'm
not sure if they are still relevant, but if they are, the buildfarm will
tell us and produce the diff required to fix it. If none of the buildfarm
animals need them, they should be removed altogether.
Patch by Stas Kelvich.
2013-10-21 19:59:42 +02:00
|
|
|
size = IS_POINT(c) ? POINT_SIZE(dim) : CUBE_SIZE(dim);
|
2007-02-28 00:48:10 +01:00
|
|
|
result = (NDBOX *) palloc0(size);
|
|
|
|
SET_VARSIZE(result, size);
|
Extend cube on-disk format to pack points more tightly.
If the lower left and upper right corners of a cube are the same, set a
flag in the cube header, and only store one copy of the coordinates. That
cuts the on-disk size into half for the common case that the cube datatype
is used to represent points rather than boxes.
The new format is backwards-compatible with the old one, so pg_upgrade
still works. However, to get the space savings, the data needs to be
rewritten. A simple VACUUM FULL or REINDEX is not enough, as the old
Datums will just be moved to the new heap/index as is. A pg_dump and
reload, or something similar like casting to text and back, will do the
trick.
This patch deliberately doesn't update all the alternative expected output
files, as I don't have access to machines that produce those outputs. I'm
not sure if they are still relevant, but if they are, the buildfarm will
tell us and produce the diff required to fix it. If none of the buildfarm
animals need them, they should be removed altogether.
Patch by Stas Kelvich.
2013-10-21 19:59:42 +02:00
|
|
|
SET_DIM(result, dim);
|
|
|
|
|
|
|
|
if (IS_POINT(c))
|
|
|
|
SET_POINT_BIT(result);
|
2006-07-26 01:23:45 +02:00
|
|
|
|
2006-10-04 02:30:14 +02:00
|
|
|
for (i = 0; i < dim; i++)
|
2006-07-26 01:23:45 +02:00
|
|
|
{
|
Extend cube on-disk format to pack points more tightly.
If the lower left and upper right corners of a cube are the same, set a
flag in the cube header, and only store one copy of the coordinates. That
cuts the on-disk size into half for the common case that the cube datatype
is used to represent points rather than boxes.
The new format is backwards-compatible with the old one, so pg_upgrade
still works. However, to get the space savings, the data needs to be
rewritten. A simple VACUUM FULL or REINDEX is not enough, as the old
Datums will just be moved to the new heap/index as is. A pg_dump and
reload, or something similar like casting to text and back, will do the
trick.
This patch deliberately doesn't update all the alternative expected output
files, as I don't have access to machines that produce those outputs. I'm
not sure if they are still relevant, but if they are, the buildfarm will
tell us and produce the diff required to fix it. If none of the buildfarm
animals need them, they should be removed altogether.
Patch by Stas Kelvich.
2013-10-21 19:59:42 +02:00
|
|
|
if ((dx[i] <= 0) || (dx[i] > DIM(c)))
|
2006-07-26 01:23:45 +02:00
|
|
|
ereport(ERROR,
|
2006-10-04 02:30:14 +02:00
|
|
|
(errcode(ERRCODE_ARRAY_ELEMENT_ERROR),
|
|
|
|
errmsg("Index out of bounds")));
|
|
|
|
result->x[i] = c->x[dx[i] - 1];
|
Extend cube on-disk format to pack points more tightly.
If the lower left and upper right corners of a cube are the same, set a
flag in the cube header, and only store one copy of the coordinates. That
cuts the on-disk size into half for the common case that the cube datatype
is used to represent points rather than boxes.
The new format is backwards-compatible with the old one, so pg_upgrade
still works. However, to get the space savings, the data needs to be
rewritten. A simple VACUUM FULL or REINDEX is not enough, as the old
Datums will just be moved to the new heap/index as is. A pg_dump and
reload, or something similar like casting to text and back, will do the
trick.
This patch deliberately doesn't update all the alternative expected output
files, as I don't have access to machines that produce those outputs. I'm
not sure if they are still relevant, but if they are, the buildfarm will
tell us and produce the diff required to fix it. If none of the buildfarm
animals need them, they should be removed altogether.
Patch by Stas Kelvich.
2013-10-21 19:59:42 +02:00
|
|
|
if (!IS_POINT(c))
|
|
|
|
result->x[i + dim] = c->x[dx[i] + DIM(c) - 1];
|
2006-07-26 01:23:45 +02:00
|
|
|
}
|
|
|
|
|
2007-11-15 22:14:46 +01:00
|
|
|
PG_FREE_IF_COPY(c, 0);
|
2017-09-18 21:21:23 +02:00
|
|
|
PG_RETURN_NDBOX_P(result);
|
2006-07-26 01:23:45 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
Datum
|
|
|
|
cube_out(PG_FUNCTION_ARGS)
|
2000-12-11 21:39:15 +01:00
|
|
|
{
|
2017-09-18 21:21:23 +02:00
|
|
|
NDBOX *cube = PG_GETARG_NDBOX_P(0);
|
2002-08-18 22:15:52 +02:00
|
|
|
StringInfoData buf;
|
Extend cube on-disk format to pack points more tightly.
If the lower left and upper right corners of a cube are the same, set a
flag in the cube header, and only store one copy of the coordinates. That
cuts the on-disk size into half for the common case that the cube datatype
is used to represent points rather than boxes.
The new format is backwards-compatible with the old one, so pg_upgrade
still works. However, to get the space savings, the data needs to be
rewritten. A simple VACUUM FULL or REINDEX is not enough, as the old
Datums will just be moved to the new heap/index as is. A pg_dump and
reload, or something similar like casting to text and back, will do the
trick.
This patch deliberately doesn't update all the alternative expected output
files, as I don't have access to machines that produce those outputs. I'm
not sure if they are still relevant, but if they are, the buildfarm will
tell us and produce the diff required to fix it. If none of the buildfarm
animals need them, they should be removed altogether.
Patch by Stas Kelvich.
2013-10-21 19:59:42 +02:00
|
|
|
int dim = DIM(cube);
|
2001-03-22 05:01:46 +01:00
|
|
|
int i;
|
|
|
|
|
2002-08-18 22:15:52 +02:00
|
|
|
initStringInfo(&buf);
|
2001-03-22 05:01:46 +01:00
|
|
|
|
2002-08-18 22:15:52 +02:00
|
|
|
appendStringInfoChar(&buf, '(');
|
2001-03-22 05:01:46 +01:00
|
|
|
for (i = 0; i < dim; i++)
|
|
|
|
{
|
2002-08-18 22:15:52 +02:00
|
|
|
if (i > 0)
|
2013-10-31 15:55:59 +01:00
|
|
|
appendStringInfoString(&buf, ", ");
|
Improve contrib/cube's handling of zero-D cubes, infinities, and NaNs.
It's always been possible to create a zero-dimensional cube by converting
from a zero-length float8 array, but cube_in failed to accept the '()'
representation that cube_out produced for that case, resulting in a
dump/reload hazard. Make it accept the case. Also fix a couple of
other places that didn't behave sanely for zero-dimensional cubes:
cube_size would produce 1.0 when surely the answer should be 0.0,
and g_cube_distance risked a divide-by-zero failure.
Likewise, it's always been possible to create cubes containing float8
infinity or NaN coordinate values, but cube_in couldn't parse such input,
and cube_out produced platform-dependent spellings of the values. Convert
them to use float8in_internal and float8out_internal so that the behavior
will be the same as for float8, as we recently did for the core geometric
types (cf commit 50861cd68). As in that commit, I don't pretend that this
patch fixes all insane corner-case behaviors that may exist for NaNs, but
it's a step forward.
(This change allows removal of the separate cube_1.out and cube_3.out
expected-files, as the platform dependency that previously required them
is now gone: an underflowing coordinate value will now produce an error
not plus or minus zero.)
Make errors from cube_in follow project conventions as to spelling
("invalid input syntax for cube" not "bad cube representation")
and errcode (INVALID_TEXT_REPRESENTATION not SYNTAX_ERROR).
Also a few marginal code cleanups and comment improvements.
Tom Lane, reviewed by Amul Sul
Discussion: <15085.1472494782@sss.pgh.pa.us>
2016-09-27 17:38:33 +02:00
|
|
|
appendStringInfoString(&buf, float8out_internal(LL_COORD(cube, i)));
|
2001-03-22 05:01:46 +01:00
|
|
|
}
|
2002-08-18 22:15:52 +02:00
|
|
|
appendStringInfoChar(&buf, ')');
|
2001-03-22 05:01:46 +01:00
|
|
|
|
Extend cube on-disk format to pack points more tightly.
If the lower left and upper right corners of a cube are the same, set a
flag in the cube header, and only store one copy of the coordinates. That
cuts the on-disk size into half for the common case that the cube datatype
is used to represent points rather than boxes.
The new format is backwards-compatible with the old one, so pg_upgrade
still works. However, to get the space savings, the data needs to be
rewritten. A simple VACUUM FULL or REINDEX is not enough, as the old
Datums will just be moved to the new heap/index as is. A pg_dump and
reload, or something similar like casting to text and back, will do the
trick.
This patch deliberately doesn't update all the alternative expected output
files, as I don't have access to machines that produce those outputs. I'm
not sure if they are still relevant, but if they are, the buildfarm will
tell us and produce the diff required to fix it. If none of the buildfarm
animals need them, they should be removed altogether.
Patch by Stas Kelvich.
2013-10-21 19:59:42 +02:00
|
|
|
if (!cube_is_point_internal(cube))
|
2001-03-22 05:01:46 +01:00
|
|
|
{
|
2013-10-31 15:55:59 +01:00
|
|
|
appendStringInfoString(&buf, ",(");
|
2002-08-18 22:15:52 +02:00
|
|
|
for (i = 0; i < dim; i++)
|
2001-03-22 05:01:46 +01:00
|
|
|
{
|
2002-08-18 22:15:52 +02:00
|
|
|
if (i > 0)
|
2013-10-31 15:55:59 +01:00
|
|
|
appendStringInfoString(&buf, ", ");
|
Improve contrib/cube's handling of zero-D cubes, infinities, and NaNs.
It's always been possible to create a zero-dimensional cube by converting
from a zero-length float8 array, but cube_in failed to accept the '()'
representation that cube_out produced for that case, resulting in a
dump/reload hazard. Make it accept the case. Also fix a couple of
other places that didn't behave sanely for zero-dimensional cubes:
cube_size would produce 1.0 when surely the answer should be 0.0,
and g_cube_distance risked a divide-by-zero failure.
Likewise, it's always been possible to create cubes containing float8
infinity or NaN coordinate values, but cube_in couldn't parse such input,
and cube_out produced platform-dependent spellings of the values. Convert
them to use float8in_internal and float8out_internal so that the behavior
will be the same as for float8, as we recently did for the core geometric
types (cf commit 50861cd68). As in that commit, I don't pretend that this
patch fixes all insane corner-case behaviors that may exist for NaNs, but
it's a step forward.
(This change allows removal of the separate cube_1.out and cube_3.out
expected-files, as the platform dependency that previously required them
is now gone: an underflowing coordinate value will now produce an error
not plus or minus zero.)
Make errors from cube_in follow project conventions as to spelling
("invalid input syntax for cube" not "bad cube representation")
and errcode (INVALID_TEXT_REPRESENTATION not SYNTAX_ERROR).
Also a few marginal code cleanups and comment improvements.
Tom Lane, reviewed by Amul Sul
Discussion: <15085.1472494782@sss.pgh.pa.us>
2016-09-27 17:38:33 +02:00
|
|
|
appendStringInfoString(&buf, float8out_internal(UR_COORD(cube, i)));
|
2001-03-22 05:01:46 +01:00
|
|
|
}
|
2002-08-18 22:15:52 +02:00
|
|
|
appendStringInfoChar(&buf, ')');
|
2001-03-22 05:01:46 +01:00
|
|
|
}
|
|
|
|
|
2007-11-15 22:14:46 +01:00
|
|
|
PG_FREE_IF_COPY(cube, 0);
|
2006-10-04 02:30:14 +02:00
|
|
|
PG_RETURN_CSTRING(buf.data);
|
2000-12-11 21:39:15 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************
|
2001-03-22 05:01:46 +01:00
|
|
|
* GiST functions
|
2000-12-11 21:39:15 +01:00
|
|
|
*****************************************************************************/
|
|
|
|
|
|
|
|
/*
|
|
|
|
** The GiST Consistent method for boxes
|
|
|
|
** Should return false if for all data items x below entry,
|
|
|
|
** the predicate x op query == FALSE, where op is the oper
|
|
|
|
** corresponding to strategy in the pg_amop table.
|
|
|
|
*/
|
2006-10-04 02:30:14 +02:00
|
|
|
Datum
|
2006-07-26 01:23:45 +02:00
|
|
|
g_cube_consistent(PG_FUNCTION_ARGS)
|
2000-12-11 21:39:15 +01:00
|
|
|
{
|
2006-10-04 02:30:14 +02:00
|
|
|
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
|
2017-09-18 21:21:23 +02:00
|
|
|
NDBOX *query = PG_GETARG_NDBOX_P(1);
|
2006-07-26 01:23:45 +02:00
|
|
|
StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
|
2009-06-11 16:49:15 +02:00
|
|
|
|
2008-04-14 19:05:34 +02:00
|
|
|
/* Oid subtype = PG_GETARG_OID(3); */
|
|
|
|
bool *recheck = (bool *) PG_GETARG_POINTER(4);
|
2007-11-15 22:14:46 +01:00
|
|
|
bool res;
|
2006-07-26 01:23:45 +02:00
|
|
|
|
2008-04-14 19:05:34 +02:00
|
|
|
/* All cases served by this function are exact */
|
|
|
|
*recheck = false;
|
|
|
|
|
2001-03-22 05:01:46 +01:00
|
|
|
/*
|
2001-05-31 20:16:55 +02:00
|
|
|
* if entry is not leaf, use g_cube_internal_consistent, else use
|
2001-03-22 05:01:46 +01:00
|
|
|
* g_cube_leaf_consistent
|
|
|
|
*/
|
|
|
|
if (GIST_LEAF(entry))
|
2017-09-18 21:21:23 +02:00
|
|
|
res = g_cube_leaf_consistent(DatumGetNDBOXP(entry->key),
|
2007-11-15 22:14:46 +01:00
|
|
|
query, strategy);
|
2001-03-22 05:01:46 +01:00
|
|
|
else
|
2017-09-18 21:21:23 +02:00
|
|
|
res = g_cube_internal_consistent(DatumGetNDBOXP(entry->key),
|
2007-11-15 22:14:46 +01:00
|
|
|
query, strategy);
|
2007-03-07 22:21:12 +01:00
|
|
|
|
2007-11-15 22:14:46 +01:00
|
|
|
PG_FREE_IF_COPY(query, 1);
|
2007-03-07 22:21:12 +01:00
|
|
|
PG_RETURN_BOOL(res);
|
2000-12-11 21:39:15 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
** The GiST Union method for boxes
|
|
|
|
** returns the minimal bounding box that encloses all the entries in entryvec
|
|
|
|
*/
|
2006-07-26 01:23:45 +02:00
|
|
|
Datum
|
|
|
|
g_cube_union(PG_FUNCTION_ARGS)
|
2000-12-11 21:39:15 +01:00
|
|
|
{
|
2008-05-29 20:46:40 +02:00
|
|
|
GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
|
|
|
|
int *sizep = (int *) PG_GETARG_POINTER(1);
|
2001-03-22 05:01:46 +01:00
|
|
|
NDBOX *out = (NDBOX *) NULL;
|
|
|
|
NDBOX *tmp;
|
2008-05-29 20:46:40 +02:00
|
|
|
int i;
|
2001-03-22 05:01:46 +01:00
|
|
|
|
2017-09-18 21:21:23 +02:00
|
|
|
tmp = DatumGetNDBOXP(entryvec->vector[0].key);
|
2001-03-22 05:01:46 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
* sizep = sizeof(NDBOX); -- NDBOX has variable size
|
|
|
|
*/
|
2007-02-28 00:48:10 +01:00
|
|
|
*sizep = VARSIZE(tmp);
|
2001-03-22 05:01:46 +01:00
|
|
|
|
2004-03-30 17:45:33 +02:00
|
|
|
for (i = 1; i < entryvec->n; i++)
|
2001-03-22 05:01:46 +01:00
|
|
|
{
|
2007-03-07 22:21:12 +01:00
|
|
|
out = g_cube_binary_union(tmp,
|
2017-09-18 21:21:23 +02:00
|
|
|
DatumGetNDBOXP(entryvec->vector[i].key),
|
2001-03-22 05:01:46 +01:00
|
|
|
sizep);
|
|
|
|
tmp = out;
|
|
|
|
}
|
|
|
|
|
2006-07-26 01:23:45 +02:00
|
|
|
PG_RETURN_POINTER(out);
|
2000-12-11 21:39:15 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
** GiST Compress and Decompress methods for boxes
|
|
|
|
** do not do anything.
|
|
|
|
*/
|
2006-07-26 01:23:45 +02:00
|
|
|
|
|
|
|
Datum
|
2006-10-04 02:30:14 +02:00
|
|
|
g_cube_compress(PG_FUNCTION_ARGS)
|
2000-12-11 21:39:15 +01:00
|
|
|
{
|
2006-10-04 02:30:14 +02:00
|
|
|
PG_RETURN_DATUM(PG_GETARG_DATUM(0));
|
2000-12-11 21:39:15 +01:00
|
|
|
}
|
|
|
|
|
2006-07-26 01:23:45 +02:00
|
|
|
Datum
|
2006-10-04 02:30:14 +02:00
|
|
|
g_cube_decompress(PG_FUNCTION_ARGS)
|
2000-12-11 21:39:15 +01:00
|
|
|
{
|
2007-03-07 22:21:12 +01:00
|
|
|
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
|
2017-09-18 21:21:23 +02:00
|
|
|
NDBOX *key = DatumGetNDBOXP(entry->key);
|
2007-03-07 22:21:12 +01:00
|
|
|
|
2017-09-18 21:21:23 +02:00
|
|
|
if (key != DatumGetNDBOXP(entry->key))
|
2007-03-07 22:21:12 +01:00
|
|
|
{
|
|
|
|
GISTENTRY *retval = (GISTENTRY *) palloc(sizeof(GISTENTRY));
|
2007-11-15 22:14:46 +01:00
|
|
|
|
2007-03-07 22:21:12 +01:00
|
|
|
gistentryinit(*retval, PointerGetDatum(key),
|
2007-11-15 22:14:46 +01:00
|
|
|
entry->rel, entry->page,
|
|
|
|
entry->offset, FALSE);
|
2007-03-07 22:21:12 +01:00
|
|
|
PG_RETURN_POINTER(retval);
|
|
|
|
}
|
|
|
|
PG_RETURN_POINTER(entry);
|
2000-12-11 21:39:15 +01:00
|
|
|
}
|
|
|
|
|
2006-07-26 01:23:45 +02:00
|
|
|
|
2000-12-11 21:39:15 +01:00
|
|
|
/*
|
|
|
|
** The GiST Penalty method for boxes
|
|
|
|
** As in the R-tree paper, we use change in area as our penalty metric
|
|
|
|
*/
|
2006-07-26 01:23:45 +02:00
|
|
|
Datum
|
2006-10-04 02:30:14 +02:00
|
|
|
g_cube_penalty(PG_FUNCTION_ARGS)
|
2000-12-11 21:39:15 +01:00
|
|
|
{
|
2006-10-04 02:30:14 +02:00
|
|
|
GISTENTRY *origentry = (GISTENTRY *) PG_GETARG_POINTER(0);
|
|
|
|
GISTENTRY *newentry = (GISTENTRY *) PG_GETARG_POINTER(1);
|
|
|
|
float *result = (float *) PG_GETARG_POINTER(2);
|
2001-05-31 20:16:55 +02:00
|
|
|
NDBOX *ud;
|
2002-08-30 01:03:58 +02:00
|
|
|
double tmp1,
|
2001-03-22 05:01:46 +01:00
|
|
|
tmp2;
|
|
|
|
|
2017-09-18 21:21:23 +02:00
|
|
|
ud = cube_union_v0(DatumGetNDBOXP(origentry->key),
|
|
|
|
DatumGetNDBOXP(newentry->key));
|
2001-05-31 20:16:55 +02:00
|
|
|
rt_cube_size(ud, &tmp1);
|
2017-09-18 21:21:23 +02:00
|
|
|
rt_cube_size(DatumGetNDBOXP(origentry->key), &tmp2);
|
2002-08-30 01:03:58 +02:00
|
|
|
*result = (float) (tmp1 - tmp2);
|
2001-03-22 05:01:46 +01:00
|
|
|
|
2006-10-04 02:30:14 +02:00
|
|
|
PG_RETURN_FLOAT8(*result);
|
2000-12-11 21:39:15 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
** The GiST PickSplit method for boxes
|
2001-03-22 05:01:46 +01:00
|
|
|
** We use Guttman's poly time split algorithm
|
2000-12-11 21:39:15 +01:00
|
|
|
*/
|
2006-07-26 01:23:45 +02:00
|
|
|
Datum
|
|
|
|
g_cube_picksplit(PG_FUNCTION_ARGS)
|
2000-12-11 21:39:15 +01:00
|
|
|
{
|
2008-05-29 20:46:40 +02:00
|
|
|
GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0);
|
|
|
|
GIST_SPLITVEC *v = (GIST_SPLITVEC *) PG_GETARG_POINTER(1);
|
2001-03-22 05:01:46 +01:00
|
|
|
OffsetNumber i,
|
|
|
|
j;
|
|
|
|
NDBOX *datum_alpha,
|
|
|
|
*datum_beta;
|
|
|
|
NDBOX *datum_l,
|
|
|
|
*datum_r;
|
|
|
|
NDBOX *union_d,
|
|
|
|
*union_dl,
|
|
|
|
*union_dr;
|
|
|
|
NDBOX *inter_d;
|
|
|
|
bool firsttime;
|
2002-08-30 01:03:58 +02:00
|
|
|
double size_alpha,
|
2001-03-22 05:01:46 +01:00
|
|
|
size_beta,
|
|
|
|
size_union,
|
|
|
|
size_inter;
|
2002-08-30 01:03:58 +02:00
|
|
|
double size_waste,
|
2001-03-22 05:01:46 +01:00
|
|
|
waste;
|
2002-08-30 01:03:58 +02:00
|
|
|
double size_l,
|
2001-03-22 05:01:46 +01:00
|
|
|
size_r;
|
|
|
|
int nbytes;
|
2006-06-28 14:00:14 +02:00
|
|
|
OffsetNumber seed_1 = 1,
|
|
|
|
seed_2 = 2;
|
2001-03-22 05:01:46 +01:00
|
|
|
OffsetNumber *left,
|
|
|
|
*right;
|
|
|
|
OffsetNumber maxoff;
|
|
|
|
|
2004-03-30 17:45:33 +02:00
|
|
|
maxoff = entryvec->n - 2;
|
2001-03-22 05:01:46 +01:00
|
|
|
nbytes = (maxoff + 2) * sizeof(OffsetNumber);
|
|
|
|
v->spl_left = (OffsetNumber *) palloc(nbytes);
|
|
|
|
v->spl_right = (OffsetNumber *) palloc(nbytes);
|
|
|
|
|
|
|
|
firsttime = true;
|
|
|
|
waste = 0.0;
|
|
|
|
|
|
|
|
for (i = FirstOffsetNumber; i < maxoff; i = OffsetNumberNext(i))
|
|
|
|
{
|
2017-09-18 21:21:23 +02:00
|
|
|
datum_alpha = DatumGetNDBOXP(entryvec->vector[i].key);
|
2001-03-22 05:01:46 +01:00
|
|
|
for (j = OffsetNumberNext(i); j <= maxoff; j = OffsetNumberNext(j))
|
|
|
|
{
|
2017-09-18 21:21:23 +02:00
|
|
|
datum_beta = DatumGetNDBOXP(entryvec->vector[j].key);
|
2001-03-22 05:01:46 +01:00
|
|
|
|
|
|
|
/* compute the wasted space by unioning these guys */
|
|
|
|
/* size_waste = size_union - size_inter; */
|
2006-07-26 01:23:45 +02:00
|
|
|
union_d = cube_union_v0(datum_alpha, datum_beta);
|
2001-03-22 05:01:46 +01:00
|
|
|
rt_cube_size(union_d, &size_union);
|
2017-09-18 21:21:23 +02:00
|
|
|
inter_d = DatumGetNDBOXP(DirectFunctionCall2(cube_inter,
|
|
|
|
entryvec->vector[i].key,
|
|
|
|
entryvec->vector[j].key));
|
2001-03-22 05:01:46 +01:00
|
|
|
rt_cube_size(inter_d, &size_inter);
|
|
|
|
size_waste = size_union - size_inter;
|
|
|
|
|
|
|
|
/*
|
2005-10-15 04:49:52 +02:00
|
|
|
* are these a more promising split than what we've already seen?
|
2001-03-22 05:01:46 +01:00
|
|
|
*/
|
|
|
|
|
|
|
|
if (size_waste > waste || firsttime)
|
|
|
|
{
|
|
|
|
waste = size_waste;
|
|
|
|
seed_1 = i;
|
|
|
|
seed_2 = j;
|
|
|
|
firsttime = false;
|
|
|
|
}
|
|
|
|
}
|
2000-12-11 21:39:15 +01:00
|
|
|
}
|
2001-03-22 05:01:46 +01:00
|
|
|
|
|
|
|
left = v->spl_left;
|
|
|
|
v->spl_nleft = 0;
|
|
|
|
right = v->spl_right;
|
|
|
|
v->spl_nright = 0;
|
|
|
|
|
2017-09-18 21:21:23 +02:00
|
|
|
datum_alpha = DatumGetNDBOXP(entryvec->vector[seed_1].key);
|
2006-07-26 01:23:45 +02:00
|
|
|
datum_l = cube_union_v0(datum_alpha, datum_alpha);
|
2001-05-31 20:16:55 +02:00
|
|
|
rt_cube_size(datum_l, &size_l);
|
2017-09-18 21:21:23 +02:00
|
|
|
datum_beta = DatumGetNDBOXP(entryvec->vector[seed_2].key);
|
2006-07-26 01:23:45 +02:00
|
|
|
datum_r = cube_union_v0(datum_beta, datum_beta);
|
2001-05-31 20:16:55 +02:00
|
|
|
rt_cube_size(datum_r, &size_r);
|
2001-03-22 05:01:46 +01:00
|
|
|
|
|
|
|
/*
|
2014-05-06 18:12:18 +02:00
|
|
|
* Now split up the regions between the two seeds. An important property
|
2005-10-15 04:49:52 +02:00
|
|
|
* of this split algorithm is that the split vector v has the indices of
|
|
|
|
* items to be split in order in its left and right vectors. We exploit
|
|
|
|
* this property by doing a merge in the code that actually splits the
|
|
|
|
* page.
|
2001-03-22 05:01:46 +01:00
|
|
|
*
|
2005-10-15 04:49:52 +02:00
|
|
|
* For efficiency, we also place the new index tuple in this loop. This is
|
|
|
|
* handled at the very end, when we have placed all the existing tuples
|
|
|
|
* and i == maxoff + 1.
|
2001-03-22 05:01:46 +01:00
|
|
|
*/
|
|
|
|
|
|
|
|
maxoff = OffsetNumberNext(maxoff);
|
|
|
|
for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i))
|
|
|
|
{
|
|
|
|
/*
|
2005-10-15 04:49:52 +02:00
|
|
|
* If we've already decided where to place this item, just put it on
|
2014-05-06 18:12:18 +02:00
|
|
|
* the right list. Otherwise, we need to figure out which page needs
|
2005-10-15 04:49:52 +02:00
|
|
|
* the least enlargement in order to store the item.
|
2001-03-22 05:01:46 +01:00
|
|
|
*/
|
|
|
|
|
|
|
|
if (i == seed_1)
|
|
|
|
{
|
|
|
|
*left++ = i;
|
|
|
|
v->spl_nleft++;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
else if (i == seed_2)
|
|
|
|
{
|
|
|
|
*right++ = i;
|
|
|
|
v->spl_nright++;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* okay, which page needs least enlargement? */
|
2017-09-18 21:21:23 +02:00
|
|
|
datum_alpha = DatumGetNDBOXP(entryvec->vector[i].key);
|
2006-07-26 01:23:45 +02:00
|
|
|
union_dl = cube_union_v0(datum_l, datum_alpha);
|
|
|
|
union_dr = cube_union_v0(datum_r, datum_alpha);
|
2001-05-31 20:16:55 +02:00
|
|
|
rt_cube_size(union_dl, &size_alpha);
|
|
|
|
rt_cube_size(union_dr, &size_beta);
|
2001-03-22 05:01:46 +01:00
|
|
|
|
|
|
|
/* pick which page to add it to */
|
|
|
|
if (size_alpha - size_l < size_beta - size_r)
|
|
|
|
{
|
|
|
|
datum_l = union_dl;
|
|
|
|
size_l = size_alpha;
|
|
|
|
*left++ = i;
|
|
|
|
v->spl_nleft++;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
datum_r = union_dr;
|
2010-11-15 03:27:34 +01:00
|
|
|
size_r = size_beta;
|
2001-03-22 05:01:46 +01:00
|
|
|
*right++ = i;
|
|
|
|
v->spl_nright++;
|
|
|
|
}
|
2000-12-11 21:39:15 +01:00
|
|
|
}
|
2001-03-22 05:01:46 +01:00
|
|
|
*left = *right = FirstOffsetNumber; /* sentinel value, see dosplit() */
|
2000-12-11 21:39:15 +01:00
|
|
|
|
2001-05-31 20:16:55 +02:00
|
|
|
v->spl_ldatum = PointerGetDatum(datum_l);
|
|
|
|
v->spl_rdatum = PointerGetDatum(datum_r);
|
2001-03-22 05:01:46 +01:00
|
|
|
|
2006-07-26 01:23:45 +02:00
|
|
|
PG_RETURN_POINTER(v);
|
2000-12-11 21:39:15 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
** Equality method
|
|
|
|
*/
|
2006-07-26 01:23:45 +02:00
|
|
|
Datum
|
|
|
|
g_cube_same(PG_FUNCTION_ARGS)
|
2000-12-11 21:39:15 +01:00
|
|
|
{
|
2017-09-18 21:21:23 +02:00
|
|
|
NDBOX *b1 = PG_GETARG_NDBOX_P(0);
|
|
|
|
NDBOX *b2 = PG_GETARG_NDBOX_P(1);
|
2008-05-29 20:46:40 +02:00
|
|
|
bool *result = (bool *) PG_GETARG_POINTER(2);
|
2006-07-26 01:23:45 +02:00
|
|
|
|
|
|
|
if (cube_cmp_v0(b1, b2) == 0)
|
2001-03-22 05:01:46 +01:00
|
|
|
*result = TRUE;
|
|
|
|
else
|
|
|
|
*result = FALSE;
|
|
|
|
|
2017-09-18 21:21:23 +02:00
|
|
|
PG_RETURN_NDBOX_P(result);
|
2000-12-11 21:39:15 +01:00
|
|
|
}
|
|
|
|
|
2001-03-22 05:01:46 +01:00
|
|
|
/*
|
2000-12-11 21:39:15 +01:00
|
|
|
** SUPPORT ROUTINES
|
|
|
|
*/
|
2001-03-22 05:01:46 +01:00
|
|
|
bool
|
2009-06-11 16:49:15 +02:00
|
|
|
g_cube_leaf_consistent(NDBOX *key,
|
|
|
|
NDBOX *query,
|
2001-03-22 05:01:46 +01:00
|
|
|
StrategyNumber strategy)
|
2000-12-11 21:39:15 +01:00
|
|
|
{
|
2001-03-22 05:01:46 +01:00
|
|
|
bool retval;
|
|
|
|
|
|
|
|
switch (strategy)
|
|
|
|
{
|
|
|
|
case RTOverlapStrategyNumber:
|
2017-08-17 18:39:20 +02:00
|
|
|
retval = cube_overlap_v0(key, query);
|
2001-03-22 05:01:46 +01:00
|
|
|
break;
|
|
|
|
case RTSameStrategyNumber:
|
2017-08-17 18:39:20 +02:00
|
|
|
retval = (cube_cmp_v0(key, query) == 0);
|
2001-03-22 05:01:46 +01:00
|
|
|
break;
|
|
|
|
case RTContainsStrategyNumber:
|
2006-09-10 19:36:52 +02:00
|
|
|
case RTOldContainsStrategyNumber:
|
2017-08-17 18:39:20 +02:00
|
|
|
retval = cube_contains_v0(key, query);
|
2001-03-22 05:01:46 +01:00
|
|
|
break;
|
|
|
|
case RTContainedByStrategyNumber:
|
2006-09-10 19:36:52 +02:00
|
|
|
case RTOldContainedByStrategyNumber:
|
2017-08-17 18:39:20 +02:00
|
|
|
retval = cube_contains_v0(query, key);
|
2001-03-22 05:01:46 +01:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
retval = FALSE;
|
|
|
|
}
|
2017-08-17 18:39:20 +02:00
|
|
|
return retval;
|
2000-12-11 21:39:15 +01:00
|
|
|
}
|
|
|
|
|
2001-03-22 05:01:46 +01:00
|
|
|
bool
|
2009-06-11 16:49:15 +02:00
|
|
|
g_cube_internal_consistent(NDBOX *key,
|
|
|
|
NDBOX *query,
|
2001-03-22 05:01:46 +01:00
|
|
|
StrategyNumber strategy)
|
2000-12-11 21:39:15 +01:00
|
|
|
{
|
2001-03-22 05:01:46 +01:00
|
|
|
bool retval;
|
|
|
|
|
|
|
|
switch (strategy)
|
|
|
|
{
|
|
|
|
case RTOverlapStrategyNumber:
|
2006-07-26 01:23:45 +02:00
|
|
|
retval = (bool) cube_overlap_v0(key, query);
|
2001-03-22 05:01:46 +01:00
|
|
|
break;
|
|
|
|
case RTSameStrategyNumber:
|
|
|
|
case RTContainsStrategyNumber:
|
2006-09-10 19:36:52 +02:00
|
|
|
case RTOldContainsStrategyNumber:
|
2006-07-26 01:23:45 +02:00
|
|
|
retval = (bool) cube_contains_v0(key, query);
|
2001-03-22 05:01:46 +01:00
|
|
|
break;
|
|
|
|
case RTContainedByStrategyNumber:
|
2006-09-10 19:36:52 +02:00
|
|
|
case RTOldContainedByStrategyNumber:
|
2006-07-26 01:23:45 +02:00
|
|
|
retval = (bool) cube_overlap_v0(key, query);
|
2001-03-22 05:01:46 +01:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
retval = FALSE;
|
|
|
|
}
|
2017-08-17 18:39:20 +02:00
|
|
|
return retval;
|
2000-12-11 21:39:15 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
NDBOX *
|
2009-06-11 16:49:15 +02:00
|
|
|
g_cube_binary_union(NDBOX *r1, NDBOX *r2, int *sizep)
|
2000-12-11 21:39:15 +01:00
|
|
|
{
|
2001-03-22 05:01:46 +01:00
|
|
|
NDBOX *retval;
|
2000-12-11 21:39:15 +01:00
|
|
|
|
2006-07-26 01:23:45 +02:00
|
|
|
retval = cube_union_v0(r1, r2);
|
2007-02-28 00:48:10 +01:00
|
|
|
*sizep = VARSIZE(retval);
|
2000-12-11 21:39:15 +01:00
|
|
|
|
2017-08-17 18:39:20 +02:00
|
|
|
return retval;
|
2000-12-11 21:39:15 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-07-26 01:23:45 +02:00
|
|
|
/* cube_union_v0 */
|
2001-03-22 05:01:46 +01:00
|
|
|
NDBOX *
|
2009-06-11 16:49:15 +02:00
|
|
|
cube_union_v0(NDBOX *a, NDBOX *b)
|
2000-12-11 21:39:15 +01:00
|
|
|
{
|
2001-03-22 05:01:46 +01:00
|
|
|
int i;
|
|
|
|
NDBOX *result;
|
Extend cube on-disk format to pack points more tightly.
If the lower left and upper right corners of a cube are the same, set a
flag in the cube header, and only store one copy of the coordinates. That
cuts the on-disk size into half for the common case that the cube datatype
is used to represent points rather than boxes.
The new format is backwards-compatible with the old one, so pg_upgrade
still works. However, to get the space savings, the data needs to be
rewritten. A simple VACUUM FULL or REINDEX is not enough, as the old
Datums will just be moved to the new heap/index as is. A pg_dump and
reload, or something similar like casting to text and back, will do the
trick.
This patch deliberately doesn't update all the alternative expected output
files, as I don't have access to machines that produce those outputs. I'm
not sure if they are still relevant, but if they are, the buildfarm will
tell us and produce the diff required to fix it. If none of the buildfarm
animals need them, they should be removed altogether.
Patch by Stas Kelvich.
2013-10-21 19:59:42 +02:00
|
|
|
int dim;
|
|
|
|
int size;
|
2001-03-22 05:01:46 +01:00
|
|
|
|
Extend cube on-disk format to pack points more tightly.
If the lower left and upper right corners of a cube are the same, set a
flag in the cube header, and only store one copy of the coordinates. That
cuts the on-disk size into half for the common case that the cube datatype
is used to represent points rather than boxes.
The new format is backwards-compatible with the old one, so pg_upgrade
still works. However, to get the space savings, the data needs to be
rewritten. A simple VACUUM FULL or REINDEX is not enough, as the old
Datums will just be moved to the new heap/index as is. A pg_dump and
reload, or something similar like casting to text and back, will do the
trick.
This patch deliberately doesn't update all the alternative expected output
files, as I don't have access to machines that produce those outputs. I'm
not sure if they are still relevant, but if they are, the buildfarm will
tell us and produce the diff required to fix it. If none of the buildfarm
animals need them, they should be removed altogether.
Patch by Stas Kelvich.
2013-10-21 19:59:42 +02:00
|
|
|
/* trivial case */
|
|
|
|
if (a == b)
|
|
|
|
return a;
|
2001-03-22 05:01:46 +01:00
|
|
|
|
Extend cube on-disk format to pack points more tightly.
If the lower left and upper right corners of a cube are the same, set a
flag in the cube header, and only store one copy of the coordinates. That
cuts the on-disk size into half for the common case that the cube datatype
is used to represent points rather than boxes.
The new format is backwards-compatible with the old one, so pg_upgrade
still works. However, to get the space savings, the data needs to be
rewritten. A simple VACUUM FULL or REINDEX is not enough, as the old
Datums will just be moved to the new heap/index as is. A pg_dump and
reload, or something similar like casting to text and back, will do the
trick.
This patch deliberately doesn't update all the alternative expected output
files, as I don't have access to machines that produce those outputs. I'm
not sure if they are still relevant, but if they are, the buildfarm will
tell us and produce the diff required to fix it. If none of the buildfarm
animals need them, they should be removed altogether.
Patch by Stas Kelvich.
2013-10-21 19:59:42 +02:00
|
|
|
/* swap the arguments if needed, so that 'a' is always larger than 'b' */
|
|
|
|
if (DIM(a) < DIM(b))
|
2001-03-22 05:01:46 +01:00
|
|
|
{
|
|
|
|
NDBOX *tmp = b;
|
|
|
|
|
|
|
|
b = a;
|
|
|
|
a = tmp;
|
|
|
|
}
|
Extend cube on-disk format to pack points more tightly.
If the lower left and upper right corners of a cube are the same, set a
flag in the cube header, and only store one copy of the coordinates. That
cuts the on-disk size into half for the common case that the cube datatype
is used to represent points rather than boxes.
The new format is backwards-compatible with the old one, so pg_upgrade
still works. However, to get the space savings, the data needs to be
rewritten. A simple VACUUM FULL or REINDEX is not enough, as the old
Datums will just be moved to the new heap/index as is. A pg_dump and
reload, or something similar like casting to text and back, will do the
trick.
This patch deliberately doesn't update all the alternative expected output
files, as I don't have access to machines that produce those outputs. I'm
not sure if they are still relevant, but if they are, the buildfarm will
tell us and produce the diff required to fix it. If none of the buildfarm
animals need them, they should be removed altogether.
Patch by Stas Kelvich.
2013-10-21 19:59:42 +02:00
|
|
|
dim = DIM(a);
|
2001-03-22 05:01:46 +01:00
|
|
|
|
Extend cube on-disk format to pack points more tightly.
If the lower left and upper right corners of a cube are the same, set a
flag in the cube header, and only store one copy of the coordinates. That
cuts the on-disk size into half for the common case that the cube datatype
is used to represent points rather than boxes.
The new format is backwards-compatible with the old one, so pg_upgrade
still works. However, to get the space savings, the data needs to be
rewritten. A simple VACUUM FULL or REINDEX is not enough, as the old
Datums will just be moved to the new heap/index as is. A pg_dump and
reload, or something similar like casting to text and back, will do the
trick.
This patch deliberately doesn't update all the alternative expected output
files, as I don't have access to machines that produce those outputs. I'm
not sure if they are still relevant, but if they are, the buildfarm will
tell us and produce the diff required to fix it. If none of the buildfarm
animals need them, they should be removed altogether.
Patch by Stas Kelvich.
2013-10-21 19:59:42 +02:00
|
|
|
size = CUBE_SIZE(dim);
|
|
|
|
result = palloc0(size);
|
|
|
|
SET_VARSIZE(result, size);
|
|
|
|
SET_DIM(result, dim);
|
|
|
|
|
2014-05-06 18:12:18 +02:00
|
|
|
/* First compute the union of the dimensions present in both args */
|
Extend cube on-disk format to pack points more tightly.
If the lower left and upper right corners of a cube are the same, set a
flag in the cube header, and only store one copy of the coordinates. That
cuts the on-disk size into half for the common case that the cube datatype
is used to represent points rather than boxes.
The new format is backwards-compatible with the old one, so pg_upgrade
still works. However, to get the space savings, the data needs to be
rewritten. A simple VACUUM FULL or REINDEX is not enough, as the old
Datums will just be moved to the new heap/index as is. A pg_dump and
reload, or something similar like casting to text and back, will do the
trick.
This patch deliberately doesn't update all the alternative expected output
files, as I don't have access to machines that produce those outputs. I'm
not sure if they are still relevant, but if they are, the buildfarm will
tell us and produce the diff required to fix it. If none of the buildfarm
animals need them, they should be removed altogether.
Patch by Stas Kelvich.
2013-10-21 19:59:42 +02:00
|
|
|
for (i = 0; i < DIM(b); i++)
|
2001-03-22 05:01:46 +01:00
|
|
|
{
|
Extend cube on-disk format to pack points more tightly.
If the lower left and upper right corners of a cube are the same, set a
flag in the cube header, and only store one copy of the coordinates. That
cuts the on-disk size into half for the common case that the cube datatype
is used to represent points rather than boxes.
The new format is backwards-compatible with the old one, so pg_upgrade
still works. However, to get the space savings, the data needs to be
rewritten. A simple VACUUM FULL or REINDEX is not enough, as the old
Datums will just be moved to the new heap/index as is. A pg_dump and
reload, or something similar like casting to text and back, will do the
trick.
This patch deliberately doesn't update all the alternative expected output
files, as I don't have access to machines that produce those outputs. I'm
not sure if they are still relevant, but if they are, the buildfarm will
tell us and produce the diff required to fix it. If none of the buildfarm
animals need them, they should be removed altogether.
Patch by Stas Kelvich.
2013-10-21 19:59:42 +02:00
|
|
|
result->x[i] = Min(
|
2014-05-06 18:12:18 +02:00
|
|
|
Min(LL_COORD(a, i), UR_COORD(a, i)),
|
|
|
|
Min(LL_COORD(b, i), UR_COORD(b, i))
|
|
|
|
);
|
Extend cube on-disk format to pack points more tightly.
If the lower left and upper right corners of a cube are the same, set a
flag in the cube header, and only store one copy of the coordinates. That
cuts the on-disk size into half for the common case that the cube datatype
is used to represent points rather than boxes.
The new format is backwards-compatible with the old one, so pg_upgrade
still works. However, to get the space savings, the data needs to be
rewritten. A simple VACUUM FULL or REINDEX is not enough, as the old
Datums will just be moved to the new heap/index as is. A pg_dump and
reload, or something similar like casting to text and back, will do the
trick.
This patch deliberately doesn't update all the alternative expected output
files, as I don't have access to machines that produce those outputs. I'm
not sure if they are still relevant, but if they are, the buildfarm will
tell us and produce the diff required to fix it. If none of the buildfarm
animals need them, they should be removed altogether.
Patch by Stas Kelvich.
2013-10-21 19:59:42 +02:00
|
|
|
result->x[i + DIM(a)] = Max(
|
2014-05-06 18:12:18 +02:00
|
|
|
Max(LL_COORD(a, i), UR_COORD(a, i)),
|
|
|
|
Max(LL_COORD(b, i), UR_COORD(b, i))
|
|
|
|
);
|
2001-03-22 05:01:46 +01:00
|
|
|
}
|
Extend cube on-disk format to pack points more tightly.
If the lower left and upper right corners of a cube are the same, set a
flag in the cube header, and only store one copy of the coordinates. That
cuts the on-disk size into half for the common case that the cube datatype
is used to represent points rather than boxes.
The new format is backwards-compatible with the old one, so pg_upgrade
still works. However, to get the space savings, the data needs to be
rewritten. A simple VACUUM FULL or REINDEX is not enough, as the old
Datums will just be moved to the new heap/index as is. A pg_dump and
reload, or something similar like casting to text and back, will do the
trick.
This patch deliberately doesn't update all the alternative expected output
files, as I don't have access to machines that produce those outputs. I'm
not sure if they are still relevant, but if they are, the buildfarm will
tell us and produce the diff required to fix it. If none of the buildfarm
animals need them, they should be removed altogether.
Patch by Stas Kelvich.
2013-10-21 19:59:42 +02:00
|
|
|
/* continue on the higher dimensions only present in 'a' */
|
|
|
|
for (; i < DIM(a); i++)
|
2001-03-22 05:01:46 +01:00
|
|
|
{
|
Extend cube on-disk format to pack points more tightly.
If the lower left and upper right corners of a cube are the same, set a
flag in the cube header, and only store one copy of the coordinates. That
cuts the on-disk size into half for the common case that the cube datatype
is used to represent points rather than boxes.
The new format is backwards-compatible with the old one, so pg_upgrade
still works. However, to get the space savings, the data needs to be
rewritten. A simple VACUUM FULL or REINDEX is not enough, as the old
Datums will just be moved to the new heap/index as is. A pg_dump and
reload, or something similar like casting to text and back, will do the
trick.
This patch deliberately doesn't update all the alternative expected output
files, as I don't have access to machines that produce those outputs. I'm
not sure if they are still relevant, but if they are, the buildfarm will
tell us and produce the diff required to fix it. If none of the buildfarm
animals need them, they should be removed altogether.
Patch by Stas Kelvich.
2013-10-21 19:59:42 +02:00
|
|
|
result->x[i] = Min(0,
|
2014-05-06 18:12:18 +02:00
|
|
|
Min(LL_COORD(a, i), UR_COORD(a, i))
|
|
|
|
);
|
Extend cube on-disk format to pack points more tightly.
If the lower left and upper right corners of a cube are the same, set a
flag in the cube header, and only store one copy of the coordinates. That
cuts the on-disk size into half for the common case that the cube datatype
is used to represent points rather than boxes.
The new format is backwards-compatible with the old one, so pg_upgrade
still works. However, to get the space savings, the data needs to be
rewritten. A simple VACUUM FULL or REINDEX is not enough, as the old
Datums will just be moved to the new heap/index as is. A pg_dump and
reload, or something similar like casting to text and back, will do the
trick.
This patch deliberately doesn't update all the alternative expected output
files, as I don't have access to machines that produce those outputs. I'm
not sure if they are still relevant, but if they are, the buildfarm will
tell us and produce the diff required to fix it. If none of the buildfarm
animals need them, they should be removed altogether.
Patch by Stas Kelvich.
2013-10-21 19:59:42 +02:00
|
|
|
result->x[i + dim] = Max(0,
|
2014-05-06 18:12:18 +02:00
|
|
|
Max(LL_COORD(a, i), UR_COORD(a, i))
|
|
|
|
);
|
2001-03-22 05:01:46 +01:00
|
|
|
}
|
|
|
|
|
Extend cube on-disk format to pack points more tightly.
If the lower left and upper right corners of a cube are the same, set a
flag in the cube header, and only store one copy of the coordinates. That
cuts the on-disk size into half for the common case that the cube datatype
is used to represent points rather than boxes.
The new format is backwards-compatible with the old one, so pg_upgrade
still works. However, to get the space savings, the data needs to be
rewritten. A simple VACUUM FULL or REINDEX is not enough, as the old
Datums will just be moved to the new heap/index as is. A pg_dump and
reload, or something similar like casting to text and back, will do the
trick.
This patch deliberately doesn't update all the alternative expected output
files, as I don't have access to machines that produce those outputs. I'm
not sure if they are still relevant, but if they are, the buildfarm will
tell us and produce the diff required to fix it. If none of the buildfarm
animals need them, they should be removed altogether.
Patch by Stas Kelvich.
2013-10-21 19:59:42 +02:00
|
|
|
/*
|
|
|
|
* Check if the result was in fact a point, and set the flag in the datum
|
|
|
|
* accordingly. (we don't bother to repalloc it smaller)
|
|
|
|
*/
|
|
|
|
if (cube_is_point_internal(result))
|
2002-09-04 22:31:48 +02:00
|
|
|
{
|
Extend cube on-disk format to pack points more tightly.
If the lower left and upper right corners of a cube are the same, set a
flag in the cube header, and only store one copy of the coordinates. That
cuts the on-disk size into half for the common case that the cube datatype
is used to represent points rather than boxes.
The new format is backwards-compatible with the old one, so pg_upgrade
still works. However, to get the space savings, the data needs to be
rewritten. A simple VACUUM FULL or REINDEX is not enough, as the old
Datums will just be moved to the new heap/index as is. A pg_dump and
reload, or something similar like casting to text and back, will do the
trick.
This patch deliberately doesn't update all the alternative expected output
files, as I don't have access to machines that produce those outputs. I'm
not sure if they are still relevant, but if they are, the buildfarm will
tell us and produce the diff required to fix it. If none of the buildfarm
animals need them, they should be removed altogether.
Patch by Stas Kelvich.
2013-10-21 19:59:42 +02:00
|
|
|
size = POINT_SIZE(dim);
|
|
|
|
SET_VARSIZE(result, size);
|
|
|
|
SET_POINT_BIT(result);
|
2002-09-04 22:31:48 +02:00
|
|
|
}
|
2001-03-22 05:01:46 +01:00
|
|
|
|
2017-08-17 18:39:20 +02:00
|
|
|
return result;
|
2000-12-11 21:39:15 +01:00
|
|
|
}
|
|
|
|
|
2006-07-26 01:23:45 +02:00
|
|
|
Datum
|
2006-10-04 02:30:14 +02:00
|
|
|
cube_union(PG_FUNCTION_ARGS)
|
2006-07-26 01:23:45 +02:00
|
|
|
{
|
2017-09-18 21:21:23 +02:00
|
|
|
NDBOX *a = PG_GETARG_NDBOX_P(0);
|
|
|
|
NDBOX *b = PG_GETARG_NDBOX_P(1);
|
2007-11-15 22:14:46 +01:00
|
|
|
NDBOX *res;
|
2006-07-26 01:23:45 +02:00
|
|
|
|
2007-03-07 22:21:12 +01:00
|
|
|
res = cube_union_v0(a, b);
|
2006-07-26 01:23:45 +02:00
|
|
|
|
2007-11-15 22:14:46 +01:00
|
|
|
PG_FREE_IF_COPY(a, 0);
|
|
|
|
PG_FREE_IF_COPY(b, 1);
|
2017-09-18 21:21:23 +02:00
|
|
|
PG_RETURN_NDBOX_P(res);
|
2006-07-26 01:23:45 +02:00
|
|
|
}
|
|
|
|
|
2000-12-11 21:39:15 +01:00
|
|
|
/* cube_inter */
|
2006-07-26 01:23:45 +02:00
|
|
|
Datum
|
|
|
|
cube_inter(PG_FUNCTION_ARGS)
|
2000-12-11 21:39:15 +01:00
|
|
|
{
|
2017-09-18 21:21:23 +02:00
|
|
|
NDBOX *a = PG_GETARG_NDBOX_P(0);
|
|
|
|
NDBOX *b = PG_GETARG_NDBOX_P(1);
|
2008-05-29 20:46:40 +02:00
|
|
|
NDBOX *result;
|
|
|
|
bool swapped = false;
|
2001-03-22 05:01:46 +01:00
|
|
|
int i;
|
Extend cube on-disk format to pack points more tightly.
If the lower left and upper right corners of a cube are the same, set a
flag in the cube header, and only store one copy of the coordinates. That
cuts the on-disk size into half for the common case that the cube datatype
is used to represent points rather than boxes.
The new format is backwards-compatible with the old one, so pg_upgrade
still works. However, to get the space savings, the data needs to be
rewritten. A simple VACUUM FULL or REINDEX is not enough, as the old
Datums will just be moved to the new heap/index as is. A pg_dump and
reload, or something similar like casting to text and back, will do the
trick.
This patch deliberately doesn't update all the alternative expected output
files, as I don't have access to machines that produce those outputs. I'm
not sure if they are still relevant, but if they are, the buildfarm will
tell us and produce the diff required to fix it. If none of the buildfarm
animals need them, they should be removed altogether.
Patch by Stas Kelvich.
2013-10-21 19:59:42 +02:00
|
|
|
int dim;
|
|
|
|
int size;
|
2001-03-22 05:01:46 +01:00
|
|
|
|
Extend cube on-disk format to pack points more tightly.
If the lower left and upper right corners of a cube are the same, set a
flag in the cube header, and only store one copy of the coordinates. That
cuts the on-disk size into half for the common case that the cube datatype
is used to represent points rather than boxes.
The new format is backwards-compatible with the old one, so pg_upgrade
still works. However, to get the space savings, the data needs to be
rewritten. A simple VACUUM FULL or REINDEX is not enough, as the old
Datums will just be moved to the new heap/index as is. A pg_dump and
reload, or something similar like casting to text and back, will do the
trick.
This patch deliberately doesn't update all the alternative expected output
files, as I don't have access to machines that produce those outputs. I'm
not sure if they are still relevant, but if they are, the buildfarm will
tell us and produce the diff required to fix it. If none of the buildfarm
animals need them, they should be removed altogether.
Patch by Stas Kelvich.
2013-10-21 19:59:42 +02:00
|
|
|
/* swap the arguments if needed, so that 'a' is always larger than 'b' */
|
|
|
|
if (DIM(a) < DIM(b))
|
2001-03-22 05:01:46 +01:00
|
|
|
{
|
|
|
|
NDBOX *tmp = b;
|
2014-05-06 18:12:18 +02:00
|
|
|
|
2001-03-22 05:01:46 +01:00
|
|
|
b = a;
|
|
|
|
a = tmp;
|
2008-05-29 20:46:40 +02:00
|
|
|
swapped = true;
|
2001-03-22 05:01:46 +01:00
|
|
|
}
|
Extend cube on-disk format to pack points more tightly.
If the lower left and upper right corners of a cube are the same, set a
flag in the cube header, and only store one copy of the coordinates. That
cuts the on-disk size into half for the common case that the cube datatype
is used to represent points rather than boxes.
The new format is backwards-compatible with the old one, so pg_upgrade
still works. However, to get the space savings, the data needs to be
rewritten. A simple VACUUM FULL or REINDEX is not enough, as the old
Datums will just be moved to the new heap/index as is. A pg_dump and
reload, or something similar like casting to text and back, will do the
trick.
This patch deliberately doesn't update all the alternative expected output
files, as I don't have access to machines that produce those outputs. I'm
not sure if they are still relevant, but if they are, the buildfarm will
tell us and produce the diff required to fix it. If none of the buildfarm
animals need them, they should be removed altogether.
Patch by Stas Kelvich.
2013-10-21 19:59:42 +02:00
|
|
|
dim = DIM(a);
|
2001-03-22 05:01:46 +01:00
|
|
|
|
Extend cube on-disk format to pack points more tightly.
If the lower left and upper right corners of a cube are the same, set a
flag in the cube header, and only store one copy of the coordinates. That
cuts the on-disk size into half for the common case that the cube datatype
is used to represent points rather than boxes.
The new format is backwards-compatible with the old one, so pg_upgrade
still works. However, to get the space savings, the data needs to be
rewritten. A simple VACUUM FULL or REINDEX is not enough, as the old
Datums will just be moved to the new heap/index as is. A pg_dump and
reload, or something similar like casting to text and back, will do the
trick.
This patch deliberately doesn't update all the alternative expected output
files, as I don't have access to machines that produce those outputs. I'm
not sure if they are still relevant, but if they are, the buildfarm will
tell us and produce the diff required to fix it. If none of the buildfarm
animals need them, they should be removed altogether.
Patch by Stas Kelvich.
2013-10-21 19:59:42 +02:00
|
|
|
size = CUBE_SIZE(dim);
|
|
|
|
result = (NDBOX *) palloc0(size);
|
|
|
|
SET_VARSIZE(result, size);
|
|
|
|
SET_DIM(result, dim);
|
|
|
|
|
2014-05-06 18:12:18 +02:00
|
|
|
/* First compute intersection of the dimensions present in both args */
|
Extend cube on-disk format to pack points more tightly.
If the lower left and upper right corners of a cube are the same, set a
flag in the cube header, and only store one copy of the coordinates. That
cuts the on-disk size into half for the common case that the cube datatype
is used to represent points rather than boxes.
The new format is backwards-compatible with the old one, so pg_upgrade
still works. However, to get the space savings, the data needs to be
rewritten. A simple VACUUM FULL or REINDEX is not enough, as the old
Datums will just be moved to the new heap/index as is. A pg_dump and
reload, or something similar like casting to text and back, will do the
trick.
This patch deliberately doesn't update all the alternative expected output
files, as I don't have access to machines that produce those outputs. I'm
not sure if they are still relevant, but if they are, the buildfarm will
tell us and produce the diff required to fix it. If none of the buildfarm
animals need them, they should be removed altogether.
Patch by Stas Kelvich.
2013-10-21 19:59:42 +02:00
|
|
|
for (i = 0; i < DIM(b); i++)
|
2001-03-22 05:01:46 +01:00
|
|
|
{
|
Extend cube on-disk format to pack points more tightly.
If the lower left and upper right corners of a cube are the same, set a
flag in the cube header, and only store one copy of the coordinates. That
cuts the on-disk size into half for the common case that the cube datatype
is used to represent points rather than boxes.
The new format is backwards-compatible with the old one, so pg_upgrade
still works. However, to get the space savings, the data needs to be
rewritten. A simple VACUUM FULL or REINDEX is not enough, as the old
Datums will just be moved to the new heap/index as is. A pg_dump and
reload, or something similar like casting to text and back, will do the
trick.
This patch deliberately doesn't update all the alternative expected output
files, as I don't have access to machines that produce those outputs. I'm
not sure if they are still relevant, but if they are, the buildfarm will
tell us and produce the diff required to fix it. If none of the buildfarm
animals need them, they should be removed altogether.
Patch by Stas Kelvich.
2013-10-21 19:59:42 +02:00
|
|
|
result->x[i] = Max(
|
2014-05-06 18:12:18 +02:00
|
|
|
Min(LL_COORD(a, i), UR_COORD(a, i)),
|
|
|
|
Min(LL_COORD(b, i), UR_COORD(b, i))
|
|
|
|
);
|
Extend cube on-disk format to pack points more tightly.
If the lower left and upper right corners of a cube are the same, set a
flag in the cube header, and only store one copy of the coordinates. That
cuts the on-disk size into half for the common case that the cube datatype
is used to represent points rather than boxes.
The new format is backwards-compatible with the old one, so pg_upgrade
still works. However, to get the space savings, the data needs to be
rewritten. A simple VACUUM FULL or REINDEX is not enough, as the old
Datums will just be moved to the new heap/index as is. A pg_dump and
reload, or something similar like casting to text and back, will do the
trick.
This patch deliberately doesn't update all the alternative expected output
files, as I don't have access to machines that produce those outputs. I'm
not sure if they are still relevant, but if they are, the buildfarm will
tell us and produce the diff required to fix it. If none of the buildfarm
animals need them, they should be removed altogether.
Patch by Stas Kelvich.
2013-10-21 19:59:42 +02:00
|
|
|
result->x[i + DIM(a)] = Min(
|
2014-05-06 18:12:18 +02:00
|
|
|
Max(LL_COORD(a, i), UR_COORD(a, i)),
|
|
|
|
Max(LL_COORD(b, i), UR_COORD(b, i))
|
|
|
|
);
|
2001-03-22 05:01:46 +01:00
|
|
|
}
|
2015-09-05 10:35:49 +02:00
|
|
|
/* continue on the higher dimensions only present in 'a' */
|
Extend cube on-disk format to pack points more tightly.
If the lower left and upper right corners of a cube are the same, set a
flag in the cube header, and only store one copy of the coordinates. That
cuts the on-disk size into half for the common case that the cube datatype
is used to represent points rather than boxes.
The new format is backwards-compatible with the old one, so pg_upgrade
still works. However, to get the space savings, the data needs to be
rewritten. A simple VACUUM FULL or REINDEX is not enough, as the old
Datums will just be moved to the new heap/index as is. A pg_dump and
reload, or something similar like casting to text and back, will do the
trick.
This patch deliberately doesn't update all the alternative expected output
files, as I don't have access to machines that produce those outputs. I'm
not sure if they are still relevant, but if they are, the buildfarm will
tell us and produce the diff required to fix it. If none of the buildfarm
animals need them, they should be removed altogether.
Patch by Stas Kelvich.
2013-10-21 19:59:42 +02:00
|
|
|
for (; i < DIM(a); i++)
|
2001-03-22 05:01:46 +01:00
|
|
|
{
|
Extend cube on-disk format to pack points more tightly.
If the lower left and upper right corners of a cube are the same, set a
flag in the cube header, and only store one copy of the coordinates. That
cuts the on-disk size into half for the common case that the cube datatype
is used to represent points rather than boxes.
The new format is backwards-compatible with the old one, so pg_upgrade
still works. However, to get the space savings, the data needs to be
rewritten. A simple VACUUM FULL or REINDEX is not enough, as the old
Datums will just be moved to the new heap/index as is. A pg_dump and
reload, or something similar like casting to text and back, will do the
trick.
This patch deliberately doesn't update all the alternative expected output
files, as I don't have access to machines that produce those outputs. I'm
not sure if they are still relevant, but if they are, the buildfarm will
tell us and produce the diff required to fix it. If none of the buildfarm
animals need them, they should be removed altogether.
Patch by Stas Kelvich.
2013-10-21 19:59:42 +02:00
|
|
|
result->x[i] = Max(0,
|
2014-05-06 18:12:18 +02:00
|
|
|
Min(LL_COORD(a, i), UR_COORD(a, i))
|
|
|
|
);
|
Extend cube on-disk format to pack points more tightly.
If the lower left and upper right corners of a cube are the same, set a
flag in the cube header, and only store one copy of the coordinates. That
cuts the on-disk size into half for the common case that the cube datatype
is used to represent points rather than boxes.
The new format is backwards-compatible with the old one, so pg_upgrade
still works. However, to get the space savings, the data needs to be
rewritten. A simple VACUUM FULL or REINDEX is not enough, as the old
Datums will just be moved to the new heap/index as is. A pg_dump and
reload, or something similar like casting to text and back, will do the
trick.
This patch deliberately doesn't update all the alternative expected output
files, as I don't have access to machines that produce those outputs. I'm
not sure if they are still relevant, but if they are, the buildfarm will
tell us and produce the diff required to fix it. If none of the buildfarm
animals need them, they should be removed altogether.
Patch by Stas Kelvich.
2013-10-21 19:59:42 +02:00
|
|
|
result->x[i + DIM(a)] = Min(0,
|
2014-05-06 18:12:18 +02:00
|
|
|
Max(LL_COORD(a, i), UR_COORD(a, i))
|
|
|
|
);
|
2001-03-22 05:01:46 +01:00
|
|
|
}
|
|
|
|
|
Extend cube on-disk format to pack points more tightly.
If the lower left and upper right corners of a cube are the same, set a
flag in the cube header, and only store one copy of the coordinates. That
cuts the on-disk size into half for the common case that the cube datatype
is used to represent points rather than boxes.
The new format is backwards-compatible with the old one, so pg_upgrade
still works. However, to get the space savings, the data needs to be
rewritten. A simple VACUUM FULL or REINDEX is not enough, as the old
Datums will just be moved to the new heap/index as is. A pg_dump and
reload, or something similar like casting to text and back, will do the
trick.
This patch deliberately doesn't update all the alternative expected output
files, as I don't have access to machines that produce those outputs. I'm
not sure if they are still relevant, but if they are, the buildfarm will
tell us and produce the diff required to fix it. If none of the buildfarm
animals need them, they should be removed altogether.
Patch by Stas Kelvich.
2013-10-21 19:59:42 +02:00
|
|
|
/*
|
|
|
|
* Check if the result was in fact a point, and set the flag in the datum
|
|
|
|
* accordingly. (we don't bother to repalloc it smaller)
|
|
|
|
*/
|
|
|
|
if (cube_is_point_internal(result))
|
2002-09-04 22:31:48 +02:00
|
|
|
{
|
Extend cube on-disk format to pack points more tightly.
If the lower left and upper right corners of a cube are the same, set a
flag in the cube header, and only store one copy of the coordinates. That
cuts the on-disk size into half for the common case that the cube datatype
is used to represent points rather than boxes.
The new format is backwards-compatible with the old one, so pg_upgrade
still works. However, to get the space savings, the data needs to be
rewritten. A simple VACUUM FULL or REINDEX is not enough, as the old
Datums will just be moved to the new heap/index as is. A pg_dump and
reload, or something similar like casting to text and back, will do the
trick.
This patch deliberately doesn't update all the alternative expected output
files, as I don't have access to machines that produce those outputs. I'm
not sure if they are still relevant, but if they are, the buildfarm will
tell us and produce the diff required to fix it. If none of the buildfarm
animals need them, they should be removed altogether.
Patch by Stas Kelvich.
2013-10-21 19:59:42 +02:00
|
|
|
size = POINT_SIZE(dim);
|
|
|
|
result = repalloc(result, size);
|
|
|
|
SET_VARSIZE(result, size);
|
|
|
|
SET_POINT_BIT(result);
|
2002-09-04 22:31:48 +02:00
|
|
|
}
|
2001-03-22 05:01:46 +01:00
|
|
|
|
2008-05-29 20:46:40 +02:00
|
|
|
if (swapped)
|
|
|
|
{
|
|
|
|
PG_FREE_IF_COPY(b, 0);
|
|
|
|
PG_FREE_IF_COPY(a, 1);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
PG_FREE_IF_COPY(a, 0);
|
|
|
|
PG_FREE_IF_COPY(b, 1);
|
|
|
|
}
|
2007-11-15 22:14:46 +01:00
|
|
|
|
2001-03-22 05:01:46 +01:00
|
|
|
/*
|
2005-10-15 04:49:52 +02:00
|
|
|
* Is it OK to return a non-null intersection for non-overlapping boxes?
|
2001-03-22 05:01:46 +01:00
|
|
|
*/
|
2017-09-18 21:21:23 +02:00
|
|
|
PG_RETURN_NDBOX_P(result);
|
2000-12-11 21:39:15 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* cube_size */
|
2006-07-26 01:23:45 +02:00
|
|
|
Datum
|
|
|
|
cube_size(PG_FUNCTION_ARGS)
|
2000-12-11 21:39:15 +01:00
|
|
|
{
|
2017-09-18 21:21:23 +02:00
|
|
|
NDBOX *a = PG_GETARG_NDBOX_P(0);
|
2008-05-29 20:46:40 +02:00
|
|
|
double result;
|
2001-03-22 05:01:46 +01:00
|
|
|
|
Improve contrib/cube's handling of zero-D cubes, infinities, and NaNs.
It's always been possible to create a zero-dimensional cube by converting
from a zero-length float8 array, but cube_in failed to accept the '()'
representation that cube_out produced for that case, resulting in a
dump/reload hazard. Make it accept the case. Also fix a couple of
other places that didn't behave sanely for zero-dimensional cubes:
cube_size would produce 1.0 when surely the answer should be 0.0,
and g_cube_distance risked a divide-by-zero failure.
Likewise, it's always been possible to create cubes containing float8
infinity or NaN coordinate values, but cube_in couldn't parse such input,
and cube_out produced platform-dependent spellings of the values. Convert
them to use float8in_internal and float8out_internal so that the behavior
will be the same as for float8, as we recently did for the core geometric
types (cf commit 50861cd68). As in that commit, I don't pretend that this
patch fixes all insane corner-case behaviors that may exist for NaNs, but
it's a step forward.
(This change allows removal of the separate cube_1.out and cube_3.out
expected-files, as the platform dependency that previously required them
is now gone: an underflowing coordinate value will now produce an error
not plus or minus zero.)
Make errors from cube_in follow project conventions as to spelling
("invalid input syntax for cube" not "bad cube representation")
and errcode (INVALID_TEXT_REPRESENTATION not SYNTAX_ERROR).
Also a few marginal code cleanups and comment improvements.
Tom Lane, reviewed by Amul Sul
Discussion: <15085.1472494782@sss.pgh.pa.us>
2016-09-27 17:38:33 +02:00
|
|
|
rt_cube_size(a, &result);
|
2007-11-15 22:14:46 +01:00
|
|
|
PG_FREE_IF_COPY(a, 0);
|
2006-10-04 02:30:14 +02:00
|
|
|
PG_RETURN_FLOAT8(result);
|
2000-12-11 21:39:15 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2009-06-11 16:49:15 +02:00
|
|
|
rt_cube_size(NDBOX *a, double *size)
|
2000-12-11 21:39:15 +01:00
|
|
|
{
|
Improve contrib/cube's handling of zero-D cubes, infinities, and NaNs.
It's always been possible to create a zero-dimensional cube by converting
from a zero-length float8 array, but cube_in failed to accept the '()'
representation that cube_out produced for that case, resulting in a
dump/reload hazard. Make it accept the case. Also fix a couple of
other places that didn't behave sanely for zero-dimensional cubes:
cube_size would produce 1.0 when surely the answer should be 0.0,
and g_cube_distance risked a divide-by-zero failure.
Likewise, it's always been possible to create cubes containing float8
infinity or NaN coordinate values, but cube_in couldn't parse such input,
and cube_out produced platform-dependent spellings of the values. Convert
them to use float8in_internal and float8out_internal so that the behavior
will be the same as for float8, as we recently did for the core geometric
types (cf commit 50861cd68). As in that commit, I don't pretend that this
patch fixes all insane corner-case behaviors that may exist for NaNs, but
it's a step forward.
(This change allows removal of the separate cube_1.out and cube_3.out
expected-files, as the platform dependency that previously required them
is now gone: an underflowing coordinate value will now produce an error
not plus or minus zero.)
Make errors from cube_in follow project conventions as to spelling
("invalid input syntax for cube" not "bad cube representation")
and errcode (INVALID_TEXT_REPRESENTATION not SYNTAX_ERROR).
Also a few marginal code cleanups and comment improvements.
Tom Lane, reviewed by Amul Sul
Discussion: <15085.1472494782@sss.pgh.pa.us>
2016-09-27 17:38:33 +02:00
|
|
|
double result;
|
Extend cube on-disk format to pack points more tightly.
If the lower left and upper right corners of a cube are the same, set a
flag in the cube header, and only store one copy of the coordinates. That
cuts the on-disk size into half for the common case that the cube datatype
is used to represent points rather than boxes.
The new format is backwards-compatible with the old one, so pg_upgrade
still works. However, to get the space savings, the data needs to be
rewritten. A simple VACUUM FULL or REINDEX is not enough, as the old
Datums will just be moved to the new heap/index as is. A pg_dump and
reload, or something similar like casting to text and back, will do the
trick.
This patch deliberately doesn't update all the alternative expected output
files, as I don't have access to machines that produce those outputs. I'm
not sure if they are still relevant, but if they are, the buildfarm will
tell us and produce the diff required to fix it. If none of the buildfarm
animals need them, they should be removed altogether.
Patch by Stas Kelvich.
2013-10-21 19:59:42 +02:00
|
|
|
int i;
|
2001-03-22 05:01:46 +01:00
|
|
|
|
|
|
|
if (a == (NDBOX *) NULL)
|
Improve contrib/cube's handling of zero-D cubes, infinities, and NaNs.
It's always been possible to create a zero-dimensional cube by converting
from a zero-length float8 array, but cube_in failed to accept the '()'
representation that cube_out produced for that case, resulting in a
dump/reload hazard. Make it accept the case. Also fix a couple of
other places that didn't behave sanely for zero-dimensional cubes:
cube_size would produce 1.0 when surely the answer should be 0.0,
and g_cube_distance risked a divide-by-zero failure.
Likewise, it's always been possible to create cubes containing float8
infinity or NaN coordinate values, but cube_in couldn't parse such input,
and cube_out produced platform-dependent spellings of the values. Convert
them to use float8in_internal and float8out_internal so that the behavior
will be the same as for float8, as we recently did for the core geometric
types (cf commit 50861cd68). As in that commit, I don't pretend that this
patch fixes all insane corner-case behaviors that may exist for NaNs, but
it's a step forward.
(This change allows removal of the separate cube_1.out and cube_3.out
expected-files, as the platform dependency that previously required them
is now gone: an underflowing coordinate value will now produce an error
not plus or minus zero.)
Make errors from cube_in follow project conventions as to spelling
("invalid input syntax for cube" not "bad cube representation")
and errcode (INVALID_TEXT_REPRESENTATION not SYNTAX_ERROR).
Also a few marginal code cleanups and comment improvements.
Tom Lane, reviewed by Amul Sul
Discussion: <15085.1472494782@sss.pgh.pa.us>
2016-09-27 17:38:33 +02:00
|
|
|
{
|
|
|
|
/* special case for GiST */
|
|
|
|
result = 0.0;
|
|
|
|
}
|
|
|
|
else if (IS_POINT(a) || DIM(a) == 0)
|
|
|
|
{
|
|
|
|
/* necessarily has zero size */
|
|
|
|
result = 0.0;
|
|
|
|
}
|
2001-03-22 05:01:46 +01:00
|
|
|
else
|
|
|
|
{
|
Improve contrib/cube's handling of zero-D cubes, infinities, and NaNs.
It's always been possible to create a zero-dimensional cube by converting
from a zero-length float8 array, but cube_in failed to accept the '()'
representation that cube_out produced for that case, resulting in a
dump/reload hazard. Make it accept the case. Also fix a couple of
other places that didn't behave sanely for zero-dimensional cubes:
cube_size would produce 1.0 when surely the answer should be 0.0,
and g_cube_distance risked a divide-by-zero failure.
Likewise, it's always been possible to create cubes containing float8
infinity or NaN coordinate values, but cube_in couldn't parse such input,
and cube_out produced platform-dependent spellings of the values. Convert
them to use float8in_internal and float8out_internal so that the behavior
will be the same as for float8, as we recently did for the core geometric
types (cf commit 50861cd68). As in that commit, I don't pretend that this
patch fixes all insane corner-case behaviors that may exist for NaNs, but
it's a step forward.
(This change allows removal of the separate cube_1.out and cube_3.out
expected-files, as the platform dependency that previously required them
is now gone: an underflowing coordinate value will now produce an error
not plus or minus zero.)
Make errors from cube_in follow project conventions as to spelling
("invalid input syntax for cube" not "bad cube representation")
and errcode (INVALID_TEXT_REPRESENTATION not SYNTAX_ERROR).
Also a few marginal code cleanups and comment improvements.
Tom Lane, reviewed by Amul Sul
Discussion: <15085.1472494782@sss.pgh.pa.us>
2016-09-27 17:38:33 +02:00
|
|
|
result = 1.0;
|
Extend cube on-disk format to pack points more tightly.
If the lower left and upper right corners of a cube are the same, set a
flag in the cube header, and only store one copy of the coordinates. That
cuts the on-disk size into half for the common case that the cube datatype
is used to represent points rather than boxes.
The new format is backwards-compatible with the old one, so pg_upgrade
still works. However, to get the space savings, the data needs to be
rewritten. A simple VACUUM FULL or REINDEX is not enough, as the old
Datums will just be moved to the new heap/index as is. A pg_dump and
reload, or something similar like casting to text and back, will do the
trick.
This patch deliberately doesn't update all the alternative expected output
files, as I don't have access to machines that produce those outputs. I'm
not sure if they are still relevant, but if they are, the buildfarm will
tell us and produce the diff required to fix it. If none of the buildfarm
animals need them, they should be removed altogether.
Patch by Stas Kelvich.
2013-10-21 19:59:42 +02:00
|
|
|
for (i = 0; i < DIM(a); i++)
|
Improve contrib/cube's handling of zero-D cubes, infinities, and NaNs.
It's always been possible to create a zero-dimensional cube by converting
from a zero-length float8 array, but cube_in failed to accept the '()'
representation that cube_out produced for that case, resulting in a
dump/reload hazard. Make it accept the case. Also fix a couple of
other places that didn't behave sanely for zero-dimensional cubes:
cube_size would produce 1.0 when surely the answer should be 0.0,
and g_cube_distance risked a divide-by-zero failure.
Likewise, it's always been possible to create cubes containing float8
infinity or NaN coordinate values, but cube_in couldn't parse such input,
and cube_out produced platform-dependent spellings of the values. Convert
them to use float8in_internal and float8out_internal so that the behavior
will be the same as for float8, as we recently did for the core geometric
types (cf commit 50861cd68). As in that commit, I don't pretend that this
patch fixes all insane corner-case behaviors that may exist for NaNs, but
it's a step forward.
(This change allows removal of the separate cube_1.out and cube_3.out
expected-files, as the platform dependency that previously required them
is now gone: an underflowing coordinate value will now produce an error
not plus or minus zero.)
Make errors from cube_in follow project conventions as to spelling
("invalid input syntax for cube" not "bad cube representation")
and errcode (INVALID_TEXT_REPRESENTATION not SYNTAX_ERROR).
Also a few marginal code cleanups and comment improvements.
Tom Lane, reviewed by Amul Sul
Discussion: <15085.1472494782@sss.pgh.pa.us>
2016-09-27 17:38:33 +02:00
|
|
|
result *= Abs(UR_COORD(a, i) - LL_COORD(a, i));
|
2001-03-22 05:01:46 +01:00
|
|
|
}
|
Improve contrib/cube's handling of zero-D cubes, infinities, and NaNs.
It's always been possible to create a zero-dimensional cube by converting
from a zero-length float8 array, but cube_in failed to accept the '()'
representation that cube_out produced for that case, resulting in a
dump/reload hazard. Make it accept the case. Also fix a couple of
other places that didn't behave sanely for zero-dimensional cubes:
cube_size would produce 1.0 when surely the answer should be 0.0,
and g_cube_distance risked a divide-by-zero failure.
Likewise, it's always been possible to create cubes containing float8
infinity or NaN coordinate values, but cube_in couldn't parse such input,
and cube_out produced platform-dependent spellings of the values. Convert
them to use float8in_internal and float8out_internal so that the behavior
will be the same as for float8, as we recently did for the core geometric
types (cf commit 50861cd68). As in that commit, I don't pretend that this
patch fixes all insane corner-case behaviors that may exist for NaNs, but
it's a step forward.
(This change allows removal of the separate cube_1.out and cube_3.out
expected-files, as the platform dependency that previously required them
is now gone: an underflowing coordinate value will now produce an error
not plus or minus zero.)
Make errors from cube_in follow project conventions as to spelling
("invalid input syntax for cube" not "bad cube representation")
and errcode (INVALID_TEXT_REPRESENTATION not SYNTAX_ERROR).
Also a few marginal code cleanups and comment improvements.
Tom Lane, reviewed by Amul Sul
Discussion: <15085.1472494782@sss.pgh.pa.us>
2016-09-27 17:38:33 +02:00
|
|
|
*size = result;
|
2000-12-11 21:39:15 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* make up a metric in which one box will be 'lower' than the other
|
2002-08-30 01:03:58 +02:00
|
|
|
-- this can be useful for sorting and to determine uniqueness */
|
2003-09-14 03:52:25 +02:00
|
|
|
int32
|
2009-06-11 16:49:15 +02:00
|
|
|
cube_cmp_v0(NDBOX *a, NDBOX *b)
|
2000-12-11 21:39:15 +01:00
|
|
|
{
|
2001-03-22 05:01:46 +01:00
|
|
|
int i;
|
|
|
|
int dim;
|
|
|
|
|
Extend cube on-disk format to pack points more tightly.
If the lower left and upper right corners of a cube are the same, set a
flag in the cube header, and only store one copy of the coordinates. That
cuts the on-disk size into half for the common case that the cube datatype
is used to represent points rather than boxes.
The new format is backwards-compatible with the old one, so pg_upgrade
still works. However, to get the space savings, the data needs to be
rewritten. A simple VACUUM FULL or REINDEX is not enough, as the old
Datums will just be moved to the new heap/index as is. A pg_dump and
reload, or something similar like casting to text and back, will do the
trick.
This patch deliberately doesn't update all the alternative expected output
files, as I don't have access to machines that produce those outputs. I'm
not sure if they are still relevant, but if they are, the buildfarm will
tell us and produce the diff required to fix it. If none of the buildfarm
animals need them, they should be removed altogether.
Patch by Stas Kelvich.
2013-10-21 19:59:42 +02:00
|
|
|
dim = Min(DIM(a), DIM(b));
|
2001-03-22 05:01:46 +01:00
|
|
|
|
|
|
|
/* compare the common dimensions */
|
|
|
|
for (i = 0; i < dim; i++)
|
|
|
|
{
|
Extend cube on-disk format to pack points more tightly.
If the lower left and upper right corners of a cube are the same, set a
flag in the cube header, and only store one copy of the coordinates. That
cuts the on-disk size into half for the common case that the cube datatype
is used to represent points rather than boxes.
The new format is backwards-compatible with the old one, so pg_upgrade
still works. However, to get the space savings, the data needs to be
rewritten. A simple VACUUM FULL or REINDEX is not enough, as the old
Datums will just be moved to the new heap/index as is. A pg_dump and
reload, or something similar like casting to text and back, will do the
trick.
This patch deliberately doesn't update all the alternative expected output
files, as I don't have access to machines that produce those outputs. I'm
not sure if they are still relevant, but if they are, the buildfarm will
tell us and produce the diff required to fix it. If none of the buildfarm
animals need them, they should be removed altogether.
Patch by Stas Kelvich.
2013-10-21 19:59:42 +02:00
|
|
|
if (Min(LL_COORD(a, i), UR_COORD(a, i)) >
|
|
|
|
Min(LL_COORD(b, i), UR_COORD(b, i)))
|
2003-09-14 03:52:25 +02:00
|
|
|
return 1;
|
Extend cube on-disk format to pack points more tightly.
If the lower left and upper right corners of a cube are the same, set a
flag in the cube header, and only store one copy of the coordinates. That
cuts the on-disk size into half for the common case that the cube datatype
is used to represent points rather than boxes.
The new format is backwards-compatible with the old one, so pg_upgrade
still works. However, to get the space savings, the data needs to be
rewritten. A simple VACUUM FULL or REINDEX is not enough, as the old
Datums will just be moved to the new heap/index as is. A pg_dump and
reload, or something similar like casting to text and back, will do the
trick.
This patch deliberately doesn't update all the alternative expected output
files, as I don't have access to machines that produce those outputs. I'm
not sure if they are still relevant, but if they are, the buildfarm will
tell us and produce the diff required to fix it. If none of the buildfarm
animals need them, they should be removed altogether.
Patch by Stas Kelvich.
2013-10-21 19:59:42 +02:00
|
|
|
if (Min(LL_COORD(a, i), UR_COORD(a, i)) <
|
|
|
|
Min(LL_COORD(b, i), UR_COORD(b, i)))
|
2003-09-14 03:52:25 +02:00
|
|
|
return -1;
|
2001-03-22 05:01:46 +01:00
|
|
|
}
|
|
|
|
for (i = 0; i < dim; i++)
|
|
|
|
{
|
Extend cube on-disk format to pack points more tightly.
If the lower left and upper right corners of a cube are the same, set a
flag in the cube header, and only store one copy of the coordinates. That
cuts the on-disk size into half for the common case that the cube datatype
is used to represent points rather than boxes.
The new format is backwards-compatible with the old one, so pg_upgrade
still works. However, to get the space savings, the data needs to be
rewritten. A simple VACUUM FULL or REINDEX is not enough, as the old
Datums will just be moved to the new heap/index as is. A pg_dump and
reload, or something similar like casting to text and back, will do the
trick.
This patch deliberately doesn't update all the alternative expected output
files, as I don't have access to machines that produce those outputs. I'm
not sure if they are still relevant, but if they are, the buildfarm will
tell us and produce the diff required to fix it. If none of the buildfarm
animals need them, they should be removed altogether.
Patch by Stas Kelvich.
2013-10-21 19:59:42 +02:00
|
|
|
if (Max(LL_COORD(a, i), UR_COORD(a, i)) >
|
|
|
|
Max(LL_COORD(b, i), UR_COORD(b, i)))
|
2003-09-14 03:52:25 +02:00
|
|
|
return 1;
|
Extend cube on-disk format to pack points more tightly.
If the lower left and upper right corners of a cube are the same, set a
flag in the cube header, and only store one copy of the coordinates. That
cuts the on-disk size into half for the common case that the cube datatype
is used to represent points rather than boxes.
The new format is backwards-compatible with the old one, so pg_upgrade
still works. However, to get the space savings, the data needs to be
rewritten. A simple VACUUM FULL or REINDEX is not enough, as the old
Datums will just be moved to the new heap/index as is. A pg_dump and
reload, or something similar like casting to text and back, will do the
trick.
This patch deliberately doesn't update all the alternative expected output
files, as I don't have access to machines that produce those outputs. I'm
not sure if they are still relevant, but if they are, the buildfarm will
tell us and produce the diff required to fix it. If none of the buildfarm
animals need them, they should be removed altogether.
Patch by Stas Kelvich.
2013-10-21 19:59:42 +02:00
|
|
|
if (Max(LL_COORD(a, i), UR_COORD(a, i)) <
|
|
|
|
Max(LL_COORD(b, i), UR_COORD(b, i)))
|
2003-09-14 03:52:25 +02:00
|
|
|
return -1;
|
2001-03-22 05:01:46 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* compare extra dimensions to zero */
|
Extend cube on-disk format to pack points more tightly.
If the lower left and upper right corners of a cube are the same, set a
flag in the cube header, and only store one copy of the coordinates. That
cuts the on-disk size into half for the common case that the cube datatype
is used to represent points rather than boxes.
The new format is backwards-compatible with the old one, so pg_upgrade
still works. However, to get the space savings, the data needs to be
rewritten. A simple VACUUM FULL or REINDEX is not enough, as the old
Datums will just be moved to the new heap/index as is. A pg_dump and
reload, or something similar like casting to text and back, will do the
trick.
This patch deliberately doesn't update all the alternative expected output
files, as I don't have access to machines that produce those outputs. I'm
not sure if they are still relevant, but if they are, the buildfarm will
tell us and produce the diff required to fix it. If none of the buildfarm
animals need them, they should be removed altogether.
Patch by Stas Kelvich.
2013-10-21 19:59:42 +02:00
|
|
|
if (DIM(a) > DIM(b))
|
2001-03-22 05:01:46 +01:00
|
|
|
{
|
Extend cube on-disk format to pack points more tightly.
If the lower left and upper right corners of a cube are the same, set a
flag in the cube header, and only store one copy of the coordinates. That
cuts the on-disk size into half for the common case that the cube datatype
is used to represent points rather than boxes.
The new format is backwards-compatible with the old one, so pg_upgrade
still works. However, to get the space savings, the data needs to be
rewritten. A simple VACUUM FULL or REINDEX is not enough, as the old
Datums will just be moved to the new heap/index as is. A pg_dump and
reload, or something similar like casting to text and back, will do the
trick.
This patch deliberately doesn't update all the alternative expected output
files, as I don't have access to machines that produce those outputs. I'm
not sure if they are still relevant, but if they are, the buildfarm will
tell us and produce the diff required to fix it. If none of the buildfarm
animals need them, they should be removed altogether.
Patch by Stas Kelvich.
2013-10-21 19:59:42 +02:00
|
|
|
for (i = dim; i < DIM(a); i++)
|
2001-03-22 05:01:46 +01:00
|
|
|
{
|
Extend cube on-disk format to pack points more tightly.
If the lower left and upper right corners of a cube are the same, set a
flag in the cube header, and only store one copy of the coordinates. That
cuts the on-disk size into half for the common case that the cube datatype
is used to represent points rather than boxes.
The new format is backwards-compatible with the old one, so pg_upgrade
still works. However, to get the space savings, the data needs to be
rewritten. A simple VACUUM FULL or REINDEX is not enough, as the old
Datums will just be moved to the new heap/index as is. A pg_dump and
reload, or something similar like casting to text and back, will do the
trick.
This patch deliberately doesn't update all the alternative expected output
files, as I don't have access to machines that produce those outputs. I'm
not sure if they are still relevant, but if they are, the buildfarm will
tell us and produce the diff required to fix it. If none of the buildfarm
animals need them, they should be removed altogether.
Patch by Stas Kelvich.
2013-10-21 19:59:42 +02:00
|
|
|
if (Min(LL_COORD(a, i), UR_COORD(a, i)) > 0)
|
2003-09-14 03:52:25 +02:00
|
|
|
return 1;
|
Extend cube on-disk format to pack points more tightly.
If the lower left and upper right corners of a cube are the same, set a
flag in the cube header, and only store one copy of the coordinates. That
cuts the on-disk size into half for the common case that the cube datatype
is used to represent points rather than boxes.
The new format is backwards-compatible with the old one, so pg_upgrade
still works. However, to get the space savings, the data needs to be
rewritten. A simple VACUUM FULL or REINDEX is not enough, as the old
Datums will just be moved to the new heap/index as is. A pg_dump and
reload, or something similar like casting to text and back, will do the
trick.
This patch deliberately doesn't update all the alternative expected output
files, as I don't have access to machines that produce those outputs. I'm
not sure if they are still relevant, but if they are, the buildfarm will
tell us and produce the diff required to fix it. If none of the buildfarm
animals need them, they should be removed altogether.
Patch by Stas Kelvich.
2013-10-21 19:59:42 +02:00
|
|
|
if (Min(LL_COORD(a, i), UR_COORD(a, i)) < 0)
|
2003-09-14 03:52:25 +02:00
|
|
|
return -1;
|
2001-03-22 05:01:46 +01:00
|
|
|
}
|
Extend cube on-disk format to pack points more tightly.
If the lower left and upper right corners of a cube are the same, set a
flag in the cube header, and only store one copy of the coordinates. That
cuts the on-disk size into half for the common case that the cube datatype
is used to represent points rather than boxes.
The new format is backwards-compatible with the old one, so pg_upgrade
still works. However, to get the space savings, the data needs to be
rewritten. A simple VACUUM FULL or REINDEX is not enough, as the old
Datums will just be moved to the new heap/index as is. A pg_dump and
reload, or something similar like casting to text and back, will do the
trick.
This patch deliberately doesn't update all the alternative expected output
files, as I don't have access to machines that produce those outputs. I'm
not sure if they are still relevant, but if they are, the buildfarm will
tell us and produce the diff required to fix it. If none of the buildfarm
animals need them, they should be removed altogether.
Patch by Stas Kelvich.
2013-10-21 19:59:42 +02:00
|
|
|
for (i = dim; i < DIM(a); i++)
|
2001-03-22 05:01:46 +01:00
|
|
|
{
|
Extend cube on-disk format to pack points more tightly.
If the lower left and upper right corners of a cube are the same, set a
flag in the cube header, and only store one copy of the coordinates. That
cuts the on-disk size into half for the common case that the cube datatype
is used to represent points rather than boxes.
The new format is backwards-compatible with the old one, so pg_upgrade
still works. However, to get the space savings, the data needs to be
rewritten. A simple VACUUM FULL or REINDEX is not enough, as the old
Datums will just be moved to the new heap/index as is. A pg_dump and
reload, or something similar like casting to text and back, will do the
trick.
This patch deliberately doesn't update all the alternative expected output
files, as I don't have access to machines that produce those outputs. I'm
not sure if they are still relevant, but if they are, the buildfarm will
tell us and produce the diff required to fix it. If none of the buildfarm
animals need them, they should be removed altogether.
Patch by Stas Kelvich.
2013-10-21 19:59:42 +02:00
|
|
|
if (Max(LL_COORD(a, i), UR_COORD(a, i)) > 0)
|
2003-09-14 03:52:25 +02:00
|
|
|
return 1;
|
Extend cube on-disk format to pack points more tightly.
If the lower left and upper right corners of a cube are the same, set a
flag in the cube header, and only store one copy of the coordinates. That
cuts the on-disk size into half for the common case that the cube datatype
is used to represent points rather than boxes.
The new format is backwards-compatible with the old one, so pg_upgrade
still works. However, to get the space savings, the data needs to be
rewritten. A simple VACUUM FULL or REINDEX is not enough, as the old
Datums will just be moved to the new heap/index as is. A pg_dump and
reload, or something similar like casting to text and back, will do the
trick.
This patch deliberately doesn't update all the alternative expected output
files, as I don't have access to machines that produce those outputs. I'm
not sure if they are still relevant, but if they are, the buildfarm will
tell us and produce the diff required to fix it. If none of the buildfarm
animals need them, they should be removed altogether.
Patch by Stas Kelvich.
2013-10-21 19:59:42 +02:00
|
|
|
if (Max(LL_COORD(a, i), UR_COORD(a, i)) < 0)
|
2003-09-14 03:52:25 +02:00
|
|
|
return -1;
|
2001-03-22 05:01:46 +01:00
|
|
|
}
|
2002-09-04 22:31:48 +02:00
|
|
|
|
|
|
|
/*
|
2005-10-15 04:49:52 +02:00
|
|
|
* if all common dimensions are equal, the cube with more dimensions
|
|
|
|
* wins
|
2002-09-04 22:31:48 +02:00
|
|
|
*/
|
2003-09-14 03:52:25 +02:00
|
|
|
return 1;
|
2001-03-22 05:01:46 +01:00
|
|
|
}
|
Extend cube on-disk format to pack points more tightly.
If the lower left and upper right corners of a cube are the same, set a
flag in the cube header, and only store one copy of the coordinates. That
cuts the on-disk size into half for the common case that the cube datatype
is used to represent points rather than boxes.
The new format is backwards-compatible with the old one, so pg_upgrade
still works. However, to get the space savings, the data needs to be
rewritten. A simple VACUUM FULL or REINDEX is not enough, as the old
Datums will just be moved to the new heap/index as is. A pg_dump and
reload, or something similar like casting to text and back, will do the
trick.
This patch deliberately doesn't update all the alternative expected output
files, as I don't have access to machines that produce those outputs. I'm
not sure if they are still relevant, but if they are, the buildfarm will
tell us and produce the diff required to fix it. If none of the buildfarm
animals need them, they should be removed altogether.
Patch by Stas Kelvich.
2013-10-21 19:59:42 +02:00
|
|
|
if (DIM(a) < DIM(b))
|
2001-03-22 05:01:46 +01:00
|
|
|
{
|
Extend cube on-disk format to pack points more tightly.
If the lower left and upper right corners of a cube are the same, set a
flag in the cube header, and only store one copy of the coordinates. That
cuts the on-disk size into half for the common case that the cube datatype
is used to represent points rather than boxes.
The new format is backwards-compatible with the old one, so pg_upgrade
still works. However, to get the space savings, the data needs to be
rewritten. A simple VACUUM FULL or REINDEX is not enough, as the old
Datums will just be moved to the new heap/index as is. A pg_dump and
reload, or something similar like casting to text and back, will do the
trick.
This patch deliberately doesn't update all the alternative expected output
files, as I don't have access to machines that produce those outputs. I'm
not sure if they are still relevant, but if they are, the buildfarm will
tell us and produce the diff required to fix it. If none of the buildfarm
animals need them, they should be removed altogether.
Patch by Stas Kelvich.
2013-10-21 19:59:42 +02:00
|
|
|
for (i = dim; i < DIM(b); i++)
|
2001-03-22 05:01:46 +01:00
|
|
|
{
|
Extend cube on-disk format to pack points more tightly.
If the lower left and upper right corners of a cube are the same, set a
flag in the cube header, and only store one copy of the coordinates. That
cuts the on-disk size into half for the common case that the cube datatype
is used to represent points rather than boxes.
The new format is backwards-compatible with the old one, so pg_upgrade
still works. However, to get the space savings, the data needs to be
rewritten. A simple VACUUM FULL or REINDEX is not enough, as the old
Datums will just be moved to the new heap/index as is. A pg_dump and
reload, or something similar like casting to text and back, will do the
trick.
This patch deliberately doesn't update all the alternative expected output
files, as I don't have access to machines that produce those outputs. I'm
not sure if they are still relevant, but if they are, the buildfarm will
tell us and produce the diff required to fix it. If none of the buildfarm
animals need them, they should be removed altogether.
Patch by Stas Kelvich.
2013-10-21 19:59:42 +02:00
|
|
|
if (Min(LL_COORD(b, i), UR_COORD(b, i)) > 0)
|
2003-09-14 03:52:25 +02:00
|
|
|
return -1;
|
Extend cube on-disk format to pack points more tightly.
If the lower left and upper right corners of a cube are the same, set a
flag in the cube header, and only store one copy of the coordinates. That
cuts the on-disk size into half for the common case that the cube datatype
is used to represent points rather than boxes.
The new format is backwards-compatible with the old one, so pg_upgrade
still works. However, to get the space savings, the data needs to be
rewritten. A simple VACUUM FULL or REINDEX is not enough, as the old
Datums will just be moved to the new heap/index as is. A pg_dump and
reload, or something similar like casting to text and back, will do the
trick.
This patch deliberately doesn't update all the alternative expected output
files, as I don't have access to machines that produce those outputs. I'm
not sure if they are still relevant, but if they are, the buildfarm will
tell us and produce the diff required to fix it. If none of the buildfarm
animals need them, they should be removed altogether.
Patch by Stas Kelvich.
2013-10-21 19:59:42 +02:00
|
|
|
if (Min(LL_COORD(b, i), UR_COORD(b, i)) < 0)
|
2003-09-14 03:52:25 +02:00
|
|
|
return 1;
|
2001-03-22 05:01:46 +01:00
|
|
|
}
|
Extend cube on-disk format to pack points more tightly.
If the lower left and upper right corners of a cube are the same, set a
flag in the cube header, and only store one copy of the coordinates. That
cuts the on-disk size into half for the common case that the cube datatype
is used to represent points rather than boxes.
The new format is backwards-compatible with the old one, so pg_upgrade
still works. However, to get the space savings, the data needs to be
rewritten. A simple VACUUM FULL or REINDEX is not enough, as the old
Datums will just be moved to the new heap/index as is. A pg_dump and
reload, or something similar like casting to text and back, will do the
trick.
This patch deliberately doesn't update all the alternative expected output
files, as I don't have access to machines that produce those outputs. I'm
not sure if they are still relevant, but if they are, the buildfarm will
tell us and produce the diff required to fix it. If none of the buildfarm
animals need them, they should be removed altogether.
Patch by Stas Kelvich.
2013-10-21 19:59:42 +02:00
|
|
|
for (i = dim; i < DIM(b); i++)
|
2001-03-22 05:01:46 +01:00
|
|
|
{
|
Extend cube on-disk format to pack points more tightly.
If the lower left and upper right corners of a cube are the same, set a
flag in the cube header, and only store one copy of the coordinates. That
cuts the on-disk size into half for the common case that the cube datatype
is used to represent points rather than boxes.
The new format is backwards-compatible with the old one, so pg_upgrade
still works. However, to get the space savings, the data needs to be
rewritten. A simple VACUUM FULL or REINDEX is not enough, as the old
Datums will just be moved to the new heap/index as is. A pg_dump and
reload, or something similar like casting to text and back, will do the
trick.
This patch deliberately doesn't update all the alternative expected output
files, as I don't have access to machines that produce those outputs. I'm
not sure if they are still relevant, but if they are, the buildfarm will
tell us and produce the diff required to fix it. If none of the buildfarm
animals need them, they should be removed altogether.
Patch by Stas Kelvich.
2013-10-21 19:59:42 +02:00
|
|
|
if (Max(LL_COORD(b, i), UR_COORD(b, i)) > 0)
|
2003-09-14 03:52:25 +02:00
|
|
|
return -1;
|
Extend cube on-disk format to pack points more tightly.
If the lower left and upper right corners of a cube are the same, set a
flag in the cube header, and only store one copy of the coordinates. That
cuts the on-disk size into half for the common case that the cube datatype
is used to represent points rather than boxes.
The new format is backwards-compatible with the old one, so pg_upgrade
still works. However, to get the space savings, the data needs to be
rewritten. A simple VACUUM FULL or REINDEX is not enough, as the old
Datums will just be moved to the new heap/index as is. A pg_dump and
reload, or something similar like casting to text and back, will do the
trick.
This patch deliberately doesn't update all the alternative expected output
files, as I don't have access to machines that produce those outputs. I'm
not sure if they are still relevant, but if they are, the buildfarm will
tell us and produce the diff required to fix it. If none of the buildfarm
animals need them, they should be removed altogether.
Patch by Stas Kelvich.
2013-10-21 19:59:42 +02:00
|
|
|
if (Max(LL_COORD(b, i), UR_COORD(b, i)) < 0)
|
2003-09-14 03:52:25 +02:00
|
|
|
return 1;
|
2001-03-22 05:01:46 +01:00
|
|
|
}
|
2002-09-04 22:31:48 +02:00
|
|
|
|
|
|
|
/*
|
2005-10-15 04:49:52 +02:00
|
|
|
* if all common dimensions are equal, the cube with more dimensions
|
|
|
|
* wins
|
2002-09-04 22:31:48 +02:00
|
|
|
*/
|
2003-09-14 03:52:25 +02:00
|
|
|
return -1;
|
2001-03-22 05:01:46 +01:00
|
|
|
}
|
|
|
|
|
2003-09-14 03:52:25 +02:00
|
|
|
/* They're really equal */
|
|
|
|
return 0;
|
2000-12-11 21:39:15 +01:00
|
|
|
}
|
|
|
|
|
2006-10-04 02:30:14 +02:00
|
|
|
Datum
|
2006-07-26 01:23:45 +02:00
|
|
|
cube_cmp(PG_FUNCTION_ARGS)
|
|
|
|
{
|
2017-09-18 21:21:23 +02:00
|
|
|
NDBOX *a = PG_GETARG_NDBOX_P(0),
|
|
|
|
*b = PG_GETARG_NDBOX_P(1);
|
2007-03-07 22:21:12 +01:00
|
|
|
int32 res;
|
2000-12-11 21:39:15 +01:00
|
|
|
|
2007-03-07 22:21:12 +01:00
|
|
|
res = cube_cmp_v0(a, b);
|
2006-07-26 01:23:45 +02:00
|
|
|
|
2007-11-15 22:14:46 +01:00
|
|
|
PG_FREE_IF_COPY(a, 0);
|
|
|
|
PG_FREE_IF_COPY(b, 1);
|
2007-03-07 22:21:12 +01:00
|
|
|
PG_RETURN_INT32(res);
|
2006-07-26 01:23:45 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Datum
|
|
|
|
cube_eq(PG_FUNCTION_ARGS)
|
2000-12-11 21:39:15 +01:00
|
|
|
{
|
2017-09-18 21:21:23 +02:00
|
|
|
NDBOX *a = PG_GETARG_NDBOX_P(0),
|
|
|
|
*b = PG_GETARG_NDBOX_P(1);
|
2007-03-07 22:21:12 +01:00
|
|
|
int32 res;
|
2006-07-26 01:23:45 +02:00
|
|
|
|
2007-03-07 22:21:12 +01:00
|
|
|
res = cube_cmp_v0(a, b);
|
2006-07-26 01:23:45 +02:00
|
|
|
|
2007-11-15 22:14:46 +01:00
|
|
|
PG_FREE_IF_COPY(a, 0);
|
|
|
|
PG_FREE_IF_COPY(b, 1);
|
2007-03-07 22:21:12 +01:00
|
|
|
PG_RETURN_BOOL(res == 0);
|
2000-12-11 21:39:15 +01:00
|
|
|
}
|
|
|
|
|
2006-07-26 01:23:45 +02:00
|
|
|
|
|
|
|
Datum
|
|
|
|
cube_ne(PG_FUNCTION_ARGS)
|
2000-12-11 21:39:15 +01:00
|
|
|
{
|
2017-09-18 21:21:23 +02:00
|
|
|
NDBOX *a = PG_GETARG_NDBOX_P(0),
|
|
|
|
*b = PG_GETARG_NDBOX_P(1);
|
2007-03-07 22:21:12 +01:00
|
|
|
int32 res;
|
2006-07-26 01:23:45 +02:00
|
|
|
|
2007-03-07 22:21:12 +01:00
|
|
|
res = cube_cmp_v0(a, b);
|
2006-07-26 01:23:45 +02:00
|
|
|
|
2007-11-15 22:14:46 +01:00
|
|
|
PG_FREE_IF_COPY(a, 0);
|
|
|
|
PG_FREE_IF_COPY(b, 1);
|
2007-03-07 22:21:12 +01:00
|
|
|
PG_RETURN_BOOL(res != 0);
|
2003-09-14 03:52:25 +02:00
|
|
|
}
|
2001-03-22 05:01:46 +01:00
|
|
|
|
2006-07-26 01:23:45 +02:00
|
|
|
|
|
|
|
Datum
|
|
|
|
cube_lt(PG_FUNCTION_ARGS)
|
2003-09-14 03:52:25 +02:00
|
|
|
{
|
2017-09-18 21:21:23 +02:00
|
|
|
NDBOX *a = PG_GETARG_NDBOX_P(0),
|
|
|
|
*b = PG_GETARG_NDBOX_P(1);
|
2007-03-07 22:21:12 +01:00
|
|
|
int32 res;
|
2006-07-26 01:23:45 +02:00
|
|
|
|
2007-03-07 22:21:12 +01:00
|
|
|
res = cube_cmp_v0(a, b);
|
2006-07-26 01:23:45 +02:00
|
|
|
|
2007-11-15 22:14:46 +01:00
|
|
|
PG_FREE_IF_COPY(a, 0);
|
|
|
|
PG_FREE_IF_COPY(b, 1);
|
2007-03-07 22:21:12 +01:00
|
|
|
PG_RETURN_BOOL(res < 0);
|
2003-09-14 03:52:25 +02:00
|
|
|
}
|
2001-03-22 05:01:46 +01:00
|
|
|
|
2006-07-26 01:23:45 +02:00
|
|
|
|
|
|
|
Datum
|
|
|
|
cube_gt(PG_FUNCTION_ARGS)
|
2003-09-14 03:52:25 +02:00
|
|
|
{
|
2017-09-18 21:21:23 +02:00
|
|
|
NDBOX *a = PG_GETARG_NDBOX_P(0),
|
|
|
|
*b = PG_GETARG_NDBOX_P(1);
|
2007-03-07 22:21:12 +01:00
|
|
|
int32 res;
|
2006-07-26 01:23:45 +02:00
|
|
|
|
2007-03-07 22:21:12 +01:00
|
|
|
res = cube_cmp_v0(a, b);
|
2006-07-26 01:23:45 +02:00
|
|
|
|
2007-11-15 22:14:46 +01:00
|
|
|
PG_FREE_IF_COPY(a, 0);
|
|
|
|
PG_FREE_IF_COPY(b, 1);
|
2007-03-07 22:21:12 +01:00
|
|
|
PG_RETURN_BOOL(res > 0);
|
2003-09-14 03:52:25 +02:00
|
|
|
}
|
2001-03-22 05:01:46 +01:00
|
|
|
|
2006-07-26 01:23:45 +02:00
|
|
|
|
|
|
|
Datum
|
|
|
|
cube_le(PG_FUNCTION_ARGS)
|
2003-09-14 03:52:25 +02:00
|
|
|
{
|
2017-09-18 21:21:23 +02:00
|
|
|
NDBOX *a = PG_GETARG_NDBOX_P(0),
|
|
|
|
*b = PG_GETARG_NDBOX_P(1);
|
2007-03-07 22:21:12 +01:00
|
|
|
int32 res;
|
2006-07-26 01:23:45 +02:00
|
|
|
|
2007-03-07 22:21:12 +01:00
|
|
|
res = cube_cmp_v0(a, b);
|
2006-07-26 01:23:45 +02:00
|
|
|
|
2007-11-15 22:14:46 +01:00
|
|
|
PG_FREE_IF_COPY(a, 0);
|
|
|
|
PG_FREE_IF_COPY(b, 1);
|
2007-03-07 22:21:12 +01:00
|
|
|
PG_RETURN_BOOL(res <= 0);
|
2000-12-11 21:39:15 +01:00
|
|
|
}
|
|
|
|
|
2006-07-26 01:23:45 +02:00
|
|
|
|
|
|
|
Datum
|
|
|
|
cube_ge(PG_FUNCTION_ARGS)
|
2000-12-11 21:39:15 +01:00
|
|
|
{
|
2017-09-18 21:21:23 +02:00
|
|
|
NDBOX *a = PG_GETARG_NDBOX_P(0),
|
|
|
|
*b = PG_GETARG_NDBOX_P(1);
|
2007-03-07 22:21:12 +01:00
|
|
|
int32 res;
|
2006-07-26 01:23:45 +02:00
|
|
|
|
2007-03-07 22:21:12 +01:00
|
|
|
res = cube_cmp_v0(a, b);
|
2006-07-26 01:23:45 +02:00
|
|
|
|
2007-11-15 22:14:46 +01:00
|
|
|
PG_FREE_IF_COPY(a, 0);
|
|
|
|
PG_FREE_IF_COPY(b, 1);
|
2007-03-07 22:21:12 +01:00
|
|
|
PG_RETURN_BOOL(res >= 0);
|
2000-12-11 21:39:15 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Contains */
|
|
|
|
/* Box(A) CONTAINS Box(B) IFF pt(A) < pt(B) */
|
2001-03-22 05:01:46 +01:00
|
|
|
bool
|
2009-06-11 16:49:15 +02:00
|
|
|
cube_contains_v0(NDBOX *a, NDBOX *b)
|
2000-12-11 21:39:15 +01:00
|
|
|
{
|
2001-03-22 05:01:46 +01:00
|
|
|
int i;
|
|
|
|
|
2002-08-30 01:03:58 +02:00
|
|
|
if ((a == NULL) || (b == NULL))
|
2017-08-17 18:39:20 +02:00
|
|
|
return FALSE;
|
2001-03-22 05:01:46 +01:00
|
|
|
|
Extend cube on-disk format to pack points more tightly.
If the lower left and upper right corners of a cube are the same, set a
flag in the cube header, and only store one copy of the coordinates. That
cuts the on-disk size into half for the common case that the cube datatype
is used to represent points rather than boxes.
The new format is backwards-compatible with the old one, so pg_upgrade
still works. However, to get the space savings, the data needs to be
rewritten. A simple VACUUM FULL or REINDEX is not enough, as the old
Datums will just be moved to the new heap/index as is. A pg_dump and
reload, or something similar like casting to text and back, will do the
trick.
This patch deliberately doesn't update all the alternative expected output
files, as I don't have access to machines that produce those outputs. I'm
not sure if they are still relevant, but if they are, the buildfarm will
tell us and produce the diff required to fix it. If none of the buildfarm
animals need them, they should be removed altogether.
Patch by Stas Kelvich.
2013-10-21 19:59:42 +02:00
|
|
|
if (DIM(a) < DIM(b))
|
2001-03-22 05:01:46 +01:00
|
|
|
{
|
|
|
|
/*
|
2005-10-15 04:49:52 +02:00
|
|
|
* 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.
|
2001-03-22 05:01:46 +01:00
|
|
|
*/
|
Extend cube on-disk format to pack points more tightly.
If the lower left and upper right corners of a cube are the same, set a
flag in the cube header, and only store one copy of the coordinates. That
cuts the on-disk size into half for the common case that the cube datatype
is used to represent points rather than boxes.
The new format is backwards-compatible with the old one, so pg_upgrade
still works. However, to get the space savings, the data needs to be
rewritten. A simple VACUUM FULL or REINDEX is not enough, as the old
Datums will just be moved to the new heap/index as is. A pg_dump and
reload, or something similar like casting to text and back, will do the
trick.
This patch deliberately doesn't update all the alternative expected output
files, as I don't have access to machines that produce those outputs. I'm
not sure if they are still relevant, but if they are, the buildfarm will
tell us and produce the diff required to fix it. If none of the buildfarm
animals need them, they should be removed altogether.
Patch by Stas Kelvich.
2013-10-21 19:59:42 +02:00
|
|
|
for (i = DIM(a); i < DIM(b); i++)
|
2001-03-22 05:01:46 +01:00
|
|
|
{
|
Extend cube on-disk format to pack points more tightly.
If the lower left and upper right corners of a cube are the same, set a
flag in the cube header, and only store one copy of the coordinates. That
cuts the on-disk size into half for the common case that the cube datatype
is used to represent points rather than boxes.
The new format is backwards-compatible with the old one, so pg_upgrade
still works. However, to get the space savings, the data needs to be
rewritten. A simple VACUUM FULL or REINDEX is not enough, as the old
Datums will just be moved to the new heap/index as is. A pg_dump and
reload, or something similar like casting to text and back, will do the
trick.
This patch deliberately doesn't update all the alternative expected output
files, as I don't have access to machines that produce those outputs. I'm
not sure if they are still relevant, but if they are, the buildfarm will
tell us and produce the diff required to fix it. If none of the buildfarm
animals need them, they should be removed altogether.
Patch by Stas Kelvich.
2013-10-21 19:59:42 +02:00
|
|
|
if (LL_COORD(b, i) != 0)
|
2017-08-17 18:39:20 +02:00
|
|
|
return FALSE;
|
Extend cube on-disk format to pack points more tightly.
If the lower left and upper right corners of a cube are the same, set a
flag in the cube header, and only store one copy of the coordinates. That
cuts the on-disk size into half for the common case that the cube datatype
is used to represent points rather than boxes.
The new format is backwards-compatible with the old one, so pg_upgrade
still works. However, to get the space savings, the data needs to be
rewritten. A simple VACUUM FULL or REINDEX is not enough, as the old
Datums will just be moved to the new heap/index as is. A pg_dump and
reload, or something similar like casting to text and back, will do the
trick.
This patch deliberately doesn't update all the alternative expected output
files, as I don't have access to machines that produce those outputs. I'm
not sure if they are still relevant, but if they are, the buildfarm will
tell us and produce the diff required to fix it. If none of the buildfarm
animals need them, they should be removed altogether.
Patch by Stas Kelvich.
2013-10-21 19:59:42 +02:00
|
|
|
if (UR_COORD(b, i) != 0)
|
2017-08-17 18:39:20 +02:00
|
|
|
return FALSE;
|
2001-03-22 05:01:46 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Can't care less about the excess dimensions of (a), if any */
|
Extend cube on-disk format to pack points more tightly.
If the lower left and upper right corners of a cube are the same, set a
flag in the cube header, and only store one copy of the coordinates. That
cuts the on-disk size into half for the common case that the cube datatype
is used to represent points rather than boxes.
The new format is backwards-compatible with the old one, so pg_upgrade
still works. However, to get the space savings, the data needs to be
rewritten. A simple VACUUM FULL or REINDEX is not enough, as the old
Datums will just be moved to the new heap/index as is. A pg_dump and
reload, or something similar like casting to text and back, will do the
trick.
This patch deliberately doesn't update all the alternative expected output
files, as I don't have access to machines that produce those outputs. I'm
not sure if they are still relevant, but if they are, the buildfarm will
tell us and produce the diff required to fix it. If none of the buildfarm
animals need them, they should be removed altogether.
Patch by Stas Kelvich.
2013-10-21 19:59:42 +02:00
|
|
|
for (i = 0; i < Min(DIM(a), DIM(b)); i++)
|
2001-03-22 05:01:46 +01:00
|
|
|
{
|
Extend cube on-disk format to pack points more tightly.
If the lower left and upper right corners of a cube are the same, set a
flag in the cube header, and only store one copy of the coordinates. That
cuts the on-disk size into half for the common case that the cube datatype
is used to represent points rather than boxes.
The new format is backwards-compatible with the old one, so pg_upgrade
still works. However, to get the space savings, the data needs to be
rewritten. A simple VACUUM FULL or REINDEX is not enough, as the old
Datums will just be moved to the new heap/index as is. A pg_dump and
reload, or something similar like casting to text and back, will do the
trick.
This patch deliberately doesn't update all the alternative expected output
files, as I don't have access to machines that produce those outputs. I'm
not sure if they are still relevant, but if they are, the buildfarm will
tell us and produce the diff required to fix it. If none of the buildfarm
animals need them, they should be removed altogether.
Patch by Stas Kelvich.
2013-10-21 19:59:42 +02:00
|
|
|
if (Min(LL_COORD(a, i), UR_COORD(a, i)) >
|
|
|
|
Min(LL_COORD(b, i), UR_COORD(b, i)))
|
2017-08-17 18:39:20 +02:00
|
|
|
return FALSE;
|
Extend cube on-disk format to pack points more tightly.
If the lower left and upper right corners of a cube are the same, set a
flag in the cube header, and only store one copy of the coordinates. That
cuts the on-disk size into half for the common case that the cube datatype
is used to represent points rather than boxes.
The new format is backwards-compatible with the old one, so pg_upgrade
still works. However, to get the space savings, the data needs to be
rewritten. A simple VACUUM FULL or REINDEX is not enough, as the old
Datums will just be moved to the new heap/index as is. A pg_dump and
reload, or something similar like casting to text and back, will do the
trick.
This patch deliberately doesn't update all the alternative expected output
files, as I don't have access to machines that produce those outputs. I'm
not sure if they are still relevant, but if they are, the buildfarm will
tell us and produce the diff required to fix it. If none of the buildfarm
animals need them, they should be removed altogether.
Patch by Stas Kelvich.
2013-10-21 19:59:42 +02:00
|
|
|
if (Max(LL_COORD(a, i), UR_COORD(a, i)) <
|
|
|
|
Max(LL_COORD(b, i), UR_COORD(b, i)))
|
2017-08-17 18:39:20 +02:00
|
|
|
return FALSE;
|
2001-03-22 05:01:46 +01:00
|
|
|
}
|
|
|
|
|
2017-08-17 18:39:20 +02:00
|
|
|
return TRUE;
|
2000-12-11 21:39:15 +01:00
|
|
|
}
|
|
|
|
|
2006-07-26 01:23:45 +02:00
|
|
|
Datum
|
|
|
|
cube_contains(PG_FUNCTION_ARGS)
|
|
|
|
{
|
2017-09-18 21:21:23 +02:00
|
|
|
NDBOX *a = PG_GETARG_NDBOX_P(0),
|
|
|
|
*b = PG_GETARG_NDBOX_P(1);
|
2007-03-07 22:21:12 +01:00
|
|
|
bool res;
|
2006-07-26 01:23:45 +02:00
|
|
|
|
2007-03-07 22:21:12 +01:00
|
|
|
res = cube_contains_v0(a, b);
|
2006-07-26 01:23:45 +02:00
|
|
|
|
2007-11-15 22:14:46 +01:00
|
|
|
PG_FREE_IF_COPY(a, 0);
|
|
|
|
PG_FREE_IF_COPY(b, 1);
|
2007-03-07 22:21:12 +01:00
|
|
|
PG_RETURN_BOOL(res);
|
2006-07-26 01:23:45 +02:00
|
|
|
}
|
|
|
|
|
2000-12-11 21:39:15 +01:00
|
|
|
/* Contained */
|
|
|
|
/* Box(A) Contained by Box(B) IFF Box(B) Contains Box(A) */
|
2006-07-26 01:23:45 +02:00
|
|
|
Datum
|
|
|
|
cube_contained(PG_FUNCTION_ARGS)
|
2000-12-11 21:39:15 +01:00
|
|
|
{
|
2017-09-18 21:21:23 +02:00
|
|
|
NDBOX *a = PG_GETARG_NDBOX_P(0),
|
|
|
|
*b = PG_GETARG_NDBOX_P(1);
|
2007-03-07 22:21:12 +01:00
|
|
|
bool res;
|
2006-07-26 01:23:45 +02:00
|
|
|
|
2007-03-07 22:21:12 +01:00
|
|
|
res = cube_contains_v0(b, a);
|
2006-07-26 01:23:45 +02:00
|
|
|
|
2007-11-15 22:14:46 +01:00
|
|
|
PG_FREE_IF_COPY(a, 0);
|
|
|
|
PG_FREE_IF_COPY(b, 1);
|
2007-03-07 22:21:12 +01:00
|
|
|
PG_RETURN_BOOL(res);
|
2000-12-11 21:39:15 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Overlap */
|
|
|
|
/* Box(A) Overlap Box(B) IFF (pt(a)LL < pt(B)UR) && (pt(b)LL < pt(a)UR) */
|
2001-03-22 05:01:46 +01:00
|
|
|
bool
|
2009-06-11 16:49:15 +02:00
|
|
|
cube_overlap_v0(NDBOX *a, NDBOX *b)
|
2000-12-11 21:39:15 +01:00
|
|
|
{
|
2001-03-22 05:01:46 +01:00
|
|
|
int i;
|
|
|
|
|
2002-08-30 01:03:58 +02:00
|
|
|
if ((a == NULL) || (b == NULL))
|
2017-08-17 18:39:20 +02:00
|
|
|
return FALSE;
|
2001-03-22 05:01:46 +01:00
|
|
|
|
|
|
|
/* swap the box pointers if needed */
|
Extend cube on-disk format to pack points more tightly.
If the lower left and upper right corners of a cube are the same, set a
flag in the cube header, and only store one copy of the coordinates. That
cuts the on-disk size into half for the common case that the cube datatype
is used to represent points rather than boxes.
The new format is backwards-compatible with the old one, so pg_upgrade
still works. However, to get the space savings, the data needs to be
rewritten. A simple VACUUM FULL or REINDEX is not enough, as the old
Datums will just be moved to the new heap/index as is. A pg_dump and
reload, or something similar like casting to text and back, will do the
trick.
This patch deliberately doesn't update all the alternative expected output
files, as I don't have access to machines that produce those outputs. I'm
not sure if they are still relevant, but if they are, the buildfarm will
tell us and produce the diff required to fix it. If none of the buildfarm
animals need them, they should be removed altogether.
Patch by Stas Kelvich.
2013-10-21 19:59:42 +02:00
|
|
|
if (DIM(a) < DIM(b))
|
2001-03-22 05:01:46 +01:00
|
|
|
{
|
|
|
|
NDBOX *tmp = b;
|
|
|
|
|
|
|
|
b = a;
|
|
|
|
a = tmp;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* compare within the dimensions of (b) */
|
Extend cube on-disk format to pack points more tightly.
If the lower left and upper right corners of a cube are the same, set a
flag in the cube header, and only store one copy of the coordinates. That
cuts the on-disk size into half for the common case that the cube datatype
is used to represent points rather than boxes.
The new format is backwards-compatible with the old one, so pg_upgrade
still works. However, to get the space savings, the data needs to be
rewritten. A simple VACUUM FULL or REINDEX is not enough, as the old
Datums will just be moved to the new heap/index as is. A pg_dump and
reload, or something similar like casting to text and back, will do the
trick.
This patch deliberately doesn't update all the alternative expected output
files, as I don't have access to machines that produce those outputs. I'm
not sure if they are still relevant, but if they are, the buildfarm will
tell us and produce the diff required to fix it. If none of the buildfarm
animals need them, they should be removed altogether.
Patch by Stas Kelvich.
2013-10-21 19:59:42 +02:00
|
|
|
for (i = 0; i < DIM(b); i++)
|
2001-03-22 05:01:46 +01:00
|
|
|
{
|
Extend cube on-disk format to pack points more tightly.
If the lower left and upper right corners of a cube are the same, set a
flag in the cube header, and only store one copy of the coordinates. That
cuts the on-disk size into half for the common case that the cube datatype
is used to represent points rather than boxes.
The new format is backwards-compatible with the old one, so pg_upgrade
still works. However, to get the space savings, the data needs to be
rewritten. A simple VACUUM FULL or REINDEX is not enough, as the old
Datums will just be moved to the new heap/index as is. A pg_dump and
reload, or something similar like casting to text and back, will do the
trick.
This patch deliberately doesn't update all the alternative expected output
files, as I don't have access to machines that produce those outputs. I'm
not sure if they are still relevant, but if they are, the buildfarm will
tell us and produce the diff required to fix it. If none of the buildfarm
animals need them, they should be removed altogether.
Patch by Stas Kelvich.
2013-10-21 19:59:42 +02:00
|
|
|
if (Min(LL_COORD(a, i), UR_COORD(a, i)) > Max(LL_COORD(b, i), UR_COORD(b, i)))
|
2017-08-17 18:39:20 +02:00
|
|
|
return FALSE;
|
Extend cube on-disk format to pack points more tightly.
If the lower left and upper right corners of a cube are the same, set a
flag in the cube header, and only store one copy of the coordinates. That
cuts the on-disk size into half for the common case that the cube datatype
is used to represent points rather than boxes.
The new format is backwards-compatible with the old one, so pg_upgrade
still works. However, to get the space savings, the data needs to be
rewritten. A simple VACUUM FULL or REINDEX is not enough, as the old
Datums will just be moved to the new heap/index as is. A pg_dump and
reload, or something similar like casting to text and back, will do the
trick.
This patch deliberately doesn't update all the alternative expected output
files, as I don't have access to machines that produce those outputs. I'm
not sure if they are still relevant, but if they are, the buildfarm will
tell us and produce the diff required to fix it. If none of the buildfarm
animals need them, they should be removed altogether.
Patch by Stas Kelvich.
2013-10-21 19:59:42 +02:00
|
|
|
if (Max(LL_COORD(a, i), UR_COORD(a, i)) < Min(LL_COORD(b, i), UR_COORD(b, i)))
|
2017-08-17 18:39:20 +02:00
|
|
|
return FALSE;
|
2001-03-22 05:01:46 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* compare to zero those dimensions in (a) absent in (b) */
|
Extend cube on-disk format to pack points more tightly.
If the lower left and upper right corners of a cube are the same, set a
flag in the cube header, and only store one copy of the coordinates. That
cuts the on-disk size into half for the common case that the cube datatype
is used to represent points rather than boxes.
The new format is backwards-compatible with the old one, so pg_upgrade
still works. However, to get the space savings, the data needs to be
rewritten. A simple VACUUM FULL or REINDEX is not enough, as the old
Datums will just be moved to the new heap/index as is. A pg_dump and
reload, or something similar like casting to text and back, will do the
trick.
This patch deliberately doesn't update all the alternative expected output
files, as I don't have access to machines that produce those outputs. I'm
not sure if they are still relevant, but if they are, the buildfarm will
tell us and produce the diff required to fix it. If none of the buildfarm
animals need them, they should be removed altogether.
Patch by Stas Kelvich.
2013-10-21 19:59:42 +02:00
|
|
|
for (i = DIM(b); i < DIM(a); i++)
|
2001-03-22 05:01:46 +01:00
|
|
|
{
|
Extend cube on-disk format to pack points more tightly.
If the lower left and upper right corners of a cube are the same, set a
flag in the cube header, and only store one copy of the coordinates. That
cuts the on-disk size into half for the common case that the cube datatype
is used to represent points rather than boxes.
The new format is backwards-compatible with the old one, so pg_upgrade
still works. However, to get the space savings, the data needs to be
rewritten. A simple VACUUM FULL or REINDEX is not enough, as the old
Datums will just be moved to the new heap/index as is. A pg_dump and
reload, or something similar like casting to text and back, will do the
trick.
This patch deliberately doesn't update all the alternative expected output
files, as I don't have access to machines that produce those outputs. I'm
not sure if they are still relevant, but if they are, the buildfarm will
tell us and produce the diff required to fix it. If none of the buildfarm
animals need them, they should be removed altogether.
Patch by Stas Kelvich.
2013-10-21 19:59:42 +02:00
|
|
|
if (Min(LL_COORD(a, i), UR_COORD(a, i)) > 0)
|
2017-08-17 18:39:20 +02:00
|
|
|
return FALSE;
|
Extend cube on-disk format to pack points more tightly.
If the lower left and upper right corners of a cube are the same, set a
flag in the cube header, and only store one copy of the coordinates. That
cuts the on-disk size into half for the common case that the cube datatype
is used to represent points rather than boxes.
The new format is backwards-compatible with the old one, so pg_upgrade
still works. However, to get the space savings, the data needs to be
rewritten. A simple VACUUM FULL or REINDEX is not enough, as the old
Datums will just be moved to the new heap/index as is. A pg_dump and
reload, or something similar like casting to text and back, will do the
trick.
This patch deliberately doesn't update all the alternative expected output
files, as I don't have access to machines that produce those outputs. I'm
not sure if they are still relevant, but if they are, the buildfarm will
tell us and produce the diff required to fix it. If none of the buildfarm
animals need them, they should be removed altogether.
Patch by Stas Kelvich.
2013-10-21 19:59:42 +02:00
|
|
|
if (Max(LL_COORD(a, i), UR_COORD(a, i)) < 0)
|
2017-08-17 18:39:20 +02:00
|
|
|
return FALSE;
|
2001-03-22 05:01:46 +01:00
|
|
|
}
|
|
|
|
|
2017-08-17 18:39:20 +02:00
|
|
|
return TRUE;
|
2000-12-11 21:39:15 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-07-26 01:23:45 +02:00
|
|
|
Datum
|
|
|
|
cube_overlap(PG_FUNCTION_ARGS)
|
|
|
|
{
|
2017-09-18 21:21:23 +02:00
|
|
|
NDBOX *a = PG_GETARG_NDBOX_P(0),
|
|
|
|
*b = PG_GETARG_NDBOX_P(1);
|
2007-03-07 22:21:12 +01:00
|
|
|
bool res;
|
2006-07-26 01:23:45 +02:00
|
|
|
|
2007-03-07 22:21:12 +01:00
|
|
|
res = cube_overlap_v0(a, b);
|
2006-07-26 01:23:45 +02:00
|
|
|
|
2007-11-15 22:14:46 +01:00
|
|
|
PG_FREE_IF_COPY(a, 0);
|
|
|
|
PG_FREE_IF_COPY(b, 1);
|
2007-03-07 22:21:12 +01:00
|
|
|
PG_RETURN_BOOL(res);
|
2006-07-26 01:23:45 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2000-12-11 21:39:15 +01:00
|
|
|
/* Distance */
|
|
|
|
/* The distance is computed as a per axis sum of the squared distances
|
2001-03-22 05:01:46 +01:00
|
|
|
between 1D projections of the boxes onto Cartesian axes. Assuming zero
|
|
|
|
distance between overlapping projections, this metric coincides with the
|
2000-12-11 21:39:15 +01:00
|
|
|
"common sense" geometric distance */
|
2006-07-26 01:23:45 +02:00
|
|
|
Datum
|
|
|
|
cube_distance(PG_FUNCTION_ARGS)
|
2000-12-11 21:39:15 +01:00
|
|
|
{
|
2017-09-18 21:21:23 +02:00
|
|
|
NDBOX *a = PG_GETARG_NDBOX_P(0),
|
|
|
|
*b = PG_GETARG_NDBOX_P(1);
|
2008-05-29 20:46:40 +02:00
|
|
|
bool swapped = false;
|
2001-03-22 05:01:46 +01:00
|
|
|
double d,
|
|
|
|
distance;
|
2008-05-29 20:46:40 +02:00
|
|
|
int i;
|
2001-03-22 05:01:46 +01:00
|
|
|
|
|
|
|
/* swap the box pointers if needed */
|
Extend cube on-disk format to pack points more tightly.
If the lower left and upper right corners of a cube are the same, set a
flag in the cube header, and only store one copy of the coordinates. That
cuts the on-disk size into half for the common case that the cube datatype
is used to represent points rather than boxes.
The new format is backwards-compatible with the old one, so pg_upgrade
still works. However, to get the space savings, the data needs to be
rewritten. A simple VACUUM FULL or REINDEX is not enough, as the old
Datums will just be moved to the new heap/index as is. A pg_dump and
reload, or something similar like casting to text and back, will do the
trick.
This patch deliberately doesn't update all the alternative expected output
files, as I don't have access to machines that produce those outputs. I'm
not sure if they are still relevant, but if they are, the buildfarm will
tell us and produce the diff required to fix it. If none of the buildfarm
animals need them, they should be removed altogether.
Patch by Stas Kelvich.
2013-10-21 19:59:42 +02:00
|
|
|
if (DIM(a) < DIM(b))
|
2001-03-22 05:01:46 +01:00
|
|
|
{
|
|
|
|
NDBOX *tmp = b;
|
|
|
|
|
|
|
|
b = a;
|
|
|
|
a = tmp;
|
2008-05-29 20:46:40 +02:00
|
|
|
swapped = true;
|
2001-03-22 05:01:46 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
distance = 0.0;
|
|
|
|
/* compute within the dimensions of (b) */
|
Extend cube on-disk format to pack points more tightly.
If the lower left and upper right corners of a cube are the same, set a
flag in the cube header, and only store one copy of the coordinates. That
cuts the on-disk size into half for the common case that the cube datatype
is used to represent points rather than boxes.
The new format is backwards-compatible with the old one, so pg_upgrade
still works. However, to get the space savings, the data needs to be
rewritten. A simple VACUUM FULL or REINDEX is not enough, as the old
Datums will just be moved to the new heap/index as is. A pg_dump and
reload, or something similar like casting to text and back, will do the
trick.
This patch deliberately doesn't update all the alternative expected output
files, as I don't have access to machines that produce those outputs. I'm
not sure if they are still relevant, but if they are, the buildfarm will
tell us and produce the diff required to fix it. If none of the buildfarm
animals need them, they should be removed altogether.
Patch by Stas Kelvich.
2013-10-21 19:59:42 +02:00
|
|
|
for (i = 0; i < DIM(b); i++)
|
2001-03-22 05:01:46 +01:00
|
|
|
{
|
2014-05-06 18:12:18 +02:00
|
|
|
d = distance_1D(LL_COORD(a, i), UR_COORD(a, i), LL_COORD(b, i), UR_COORD(b, i));
|
2001-03-22 05:01:46 +01:00
|
|
|
distance += d * d;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* compute distance to zero for those dimensions in (a) absent in (b) */
|
Extend cube on-disk format to pack points more tightly.
If the lower left and upper right corners of a cube are the same, set a
flag in the cube header, and only store one copy of the coordinates. That
cuts the on-disk size into half for the common case that the cube datatype
is used to represent points rather than boxes.
The new format is backwards-compatible with the old one, so pg_upgrade
still works. However, to get the space savings, the data needs to be
rewritten. A simple VACUUM FULL or REINDEX is not enough, as the old
Datums will just be moved to the new heap/index as is. A pg_dump and
reload, or something similar like casting to text and back, will do the
trick.
This patch deliberately doesn't update all the alternative expected output
files, as I don't have access to machines that produce those outputs. I'm
not sure if they are still relevant, but if they are, the buildfarm will
tell us and produce the diff required to fix it. If none of the buildfarm
animals need them, they should be removed altogether.
Patch by Stas Kelvich.
2013-10-21 19:59:42 +02:00
|
|
|
for (i = DIM(b); i < DIM(a); i++)
|
2001-03-22 05:01:46 +01:00
|
|
|
{
|
2014-05-06 18:12:18 +02:00
|
|
|
d = distance_1D(LL_COORD(a, i), UR_COORD(a, i), 0.0, 0.0);
|
2001-03-22 05:01:46 +01:00
|
|
|
distance += d * d;
|
|
|
|
}
|
|
|
|
|
2008-05-29 20:46:40 +02:00
|
|
|
if (swapped)
|
|
|
|
{
|
|
|
|
PG_FREE_IF_COPY(b, 0);
|
|
|
|
PG_FREE_IF_COPY(a, 1);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
PG_FREE_IF_COPY(a, 0);
|
|
|
|
PG_FREE_IF_COPY(b, 1);
|
|
|
|
}
|
|
|
|
|
2006-07-26 01:23:45 +02:00
|
|
|
PG_RETURN_FLOAT8(sqrt(distance));
|
2000-12-11 21:39:15 +01:00
|
|
|
}
|
|
|
|
|
2015-12-18 12:38:27 +01:00
|
|
|
Datum
|
|
|
|
distance_taxicab(PG_FUNCTION_ARGS)
|
|
|
|
{
|
2017-09-18 21:21:23 +02:00
|
|
|
NDBOX *a = PG_GETARG_NDBOX_P(0),
|
|
|
|
*b = PG_GETARG_NDBOX_P(1);
|
2015-12-18 12:38:27 +01:00
|
|
|
bool swapped = false;
|
|
|
|
double distance;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
/* swap the box pointers if needed */
|
|
|
|
if (DIM(a) < DIM(b))
|
|
|
|
{
|
|
|
|
NDBOX *tmp = b;
|
2015-12-28 20:39:09 +01:00
|
|
|
|
2015-12-18 12:38:27 +01:00
|
|
|
b = a;
|
|
|
|
a = tmp;
|
|
|
|
swapped = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
distance = 0.0;
|
|
|
|
/* compute within the dimensions of (b) */
|
|
|
|
for (i = 0; i < DIM(b); i++)
|
2015-12-28 20:39:09 +01:00
|
|
|
distance += fabs(distance_1D(LL_COORD(a, i), UR_COORD(a, i),
|
|
|
|
LL_COORD(b, i), UR_COORD(b, i)));
|
2015-12-18 12:38:27 +01:00
|
|
|
|
|
|
|
/* compute distance to zero for those dimensions in (a) absent in (b) */
|
|
|
|
for (i = DIM(b); i < DIM(a); i++)
|
2015-12-28 20:39:09 +01:00
|
|
|
distance += fabs(distance_1D(LL_COORD(a, i), UR_COORD(a, i),
|
|
|
|
0.0, 0.0));
|
2015-12-18 12:38:27 +01:00
|
|
|
|
|
|
|
if (swapped)
|
|
|
|
{
|
|
|
|
PG_FREE_IF_COPY(b, 0);
|
|
|
|
PG_FREE_IF_COPY(a, 1);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
PG_FREE_IF_COPY(a, 0);
|
|
|
|
PG_FREE_IF_COPY(b, 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
PG_RETURN_FLOAT8(distance);
|
|
|
|
}
|
|
|
|
|
|
|
|
Datum
|
|
|
|
distance_chebyshev(PG_FUNCTION_ARGS)
|
|
|
|
{
|
2017-09-18 21:21:23 +02:00
|
|
|
NDBOX *a = PG_GETARG_NDBOX_P(0),
|
|
|
|
*b = PG_GETARG_NDBOX_P(1);
|
2015-12-18 12:38:27 +01:00
|
|
|
bool swapped = false;
|
2015-12-28 20:39:09 +01:00
|
|
|
double d,
|
|
|
|
distance;
|
2015-12-18 12:38:27 +01:00
|
|
|
int i;
|
|
|
|
|
|
|
|
/* swap the box pointers if needed */
|
|
|
|
if (DIM(a) < DIM(b))
|
|
|
|
{
|
|
|
|
NDBOX *tmp = b;
|
2015-12-28 20:39:09 +01:00
|
|
|
|
2015-12-18 12:38:27 +01:00
|
|
|
b = a;
|
|
|
|
a = tmp;
|
|
|
|
swapped = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
distance = 0.0;
|
|
|
|
/* compute within the dimensions of (b) */
|
|
|
|
for (i = 0; i < DIM(b); i++)
|
|
|
|
{
|
2015-12-28 20:39:09 +01:00
|
|
|
d = fabs(distance_1D(LL_COORD(a, i), UR_COORD(a, i),
|
|
|
|
LL_COORD(b, i), UR_COORD(b, i)));
|
2015-12-18 12:38:27 +01:00
|
|
|
if (d > distance)
|
|
|
|
distance = d;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* compute distance to zero for those dimensions in (a) absent in (b) */
|
|
|
|
for (i = DIM(b); i < DIM(a); i++)
|
|
|
|
{
|
2015-12-28 20:39:09 +01:00
|
|
|
d = fabs(distance_1D(LL_COORD(a, i), UR_COORD(a, i), 0.0, 0.0));
|
2015-12-18 12:38:27 +01:00
|
|
|
if (d > distance)
|
|
|
|
distance = d;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (swapped)
|
|
|
|
{
|
|
|
|
PG_FREE_IF_COPY(b, 0);
|
|
|
|
PG_FREE_IF_COPY(a, 1);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
PG_FREE_IF_COPY(a, 0);
|
|
|
|
PG_FREE_IF_COPY(b, 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
PG_RETURN_FLOAT8(distance);
|
|
|
|
}
|
|
|
|
|
|
|
|
Datum
|
|
|
|
g_cube_distance(PG_FUNCTION_ARGS)
|
|
|
|
{
|
|
|
|
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
|
|
|
|
StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
|
2017-09-18 21:21:23 +02:00
|
|
|
NDBOX *cube = DatumGetNDBOXP(entry->key);
|
2015-12-28 20:39:09 +01:00
|
|
|
double retval;
|
2015-12-18 12:38:27 +01:00
|
|
|
|
|
|
|
if (strategy == CubeKNNDistanceCoord)
|
|
|
|
{
|
2015-12-28 20:39:09 +01:00
|
|
|
int coord = PG_GETARG_INT32(1);
|
2015-12-18 12:38:27 +01:00
|
|
|
|
Improve contrib/cube's handling of zero-D cubes, infinities, and NaNs.
It's always been possible to create a zero-dimensional cube by converting
from a zero-length float8 array, but cube_in failed to accept the '()'
representation that cube_out produced for that case, resulting in a
dump/reload hazard. Make it accept the case. Also fix a couple of
other places that didn't behave sanely for zero-dimensional cubes:
cube_size would produce 1.0 when surely the answer should be 0.0,
and g_cube_distance risked a divide-by-zero failure.
Likewise, it's always been possible to create cubes containing float8
infinity or NaN coordinate values, but cube_in couldn't parse such input,
and cube_out produced platform-dependent spellings of the values. Convert
them to use float8in_internal and float8out_internal so that the behavior
will be the same as for float8, as we recently did for the core geometric
types (cf commit 50861cd68). As in that commit, I don't pretend that this
patch fixes all insane corner-case behaviors that may exist for NaNs, but
it's a step forward.
(This change allows removal of the separate cube_1.out and cube_3.out
expected-files, as the platform dependency that previously required them
is now gone: an underflowing coordinate value will now produce an error
not plus or minus zero.)
Make errors from cube_in follow project conventions as to spelling
("invalid input syntax for cube" not "bad cube representation")
and errcode (INVALID_TEXT_REPRESENTATION not SYNTAX_ERROR).
Also a few marginal code cleanups and comment improvements.
Tom Lane, reviewed by Amul Sul
Discussion: <15085.1472494782@sss.pgh.pa.us>
2016-09-27 17:38:33 +02:00
|
|
|
if (DIM(cube) == 0)
|
|
|
|
retval = 0.0;
|
|
|
|
else if (IS_POINT(cube))
|
2015-12-28 20:39:09 +01:00
|
|
|
retval = cube->x[(coord - 1) % DIM(cube)];
|
2015-12-18 12:38:27 +01:00
|
|
|
else
|
2015-12-28 20:39:09 +01:00
|
|
|
retval = Min(cube->x[(coord - 1) % DIM(cube)],
|
|
|
|
cube->x[(coord - 1) % DIM(cube) + DIM(cube)]);
|
2015-12-18 12:38:27 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2017-09-18 21:21:23 +02:00
|
|
|
NDBOX *query = PG_GETARG_NDBOX_P(1);
|
2015-12-28 20:39:09 +01:00
|
|
|
|
|
|
|
switch (strategy)
|
2015-12-18 12:38:27 +01:00
|
|
|
{
|
2015-12-28 20:39:09 +01:00
|
|
|
case CubeKNNDistanceTaxicab:
|
|
|
|
retval = DatumGetFloat8(DirectFunctionCall2(distance_taxicab,
|
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
|
|
|
PointerGetDatum(cube), PointerGetDatum(query)));
|
2015-12-28 20:39:09 +01:00
|
|
|
break;
|
|
|
|
case CubeKNNDistanceEuclid:
|
|
|
|
retval = DatumGetFloat8(DirectFunctionCall2(cube_distance,
|
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
|
|
|
PointerGetDatum(cube), PointerGetDatum(query)));
|
2015-12-28 20:39:09 +01:00
|
|
|
break;
|
|
|
|
case CubeKNNDistanceChebyshev:
|
|
|
|
retval = DatumGetFloat8(DirectFunctionCall2(distance_chebyshev,
|
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
|
|
|
PointerGetDatum(cube), PointerGetDatum(query)));
|
2015-12-28 20:39:09 +01:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
elog(ERROR, "unrecognized cube strategy number: %d", strategy);
|
|
|
|
retval = 0; /* keep compiler quiet */
|
|
|
|
break;
|
2015-12-18 12:38:27 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
PG_RETURN_FLOAT8(retval);
|
|
|
|
}
|
|
|
|
|
2002-08-30 01:03:58 +02:00
|
|
|
static double
|
|
|
|
distance_1D(double a1, double a2, double b1, double b2)
|
2000-12-11 21:39:15 +01:00
|
|
|
{
|
2001-03-22 05:01:46 +01:00
|
|
|
/* interval (a) is entirely on the left of (b) */
|
|
|
|
if ((a1 <= b1) && (a2 <= b1) && (a1 <= b2) && (a2 <= b2))
|
2004-09-14 06:21:38 +02:00
|
|
|
return (Min(b1, b2) - Max(a1, a2));
|
2001-03-22 05:01:46 +01:00
|
|
|
|
|
|
|
/* interval (a) is entirely on the right of (b) */
|
|
|
|
if ((a1 > b1) && (a2 > b1) && (a1 > b2) && (a2 > b2))
|
2004-09-14 06:21:38 +02:00
|
|
|
return (Min(a1, a2) - Max(b1, b2));
|
2001-03-22 05:01:46 +01:00
|
|
|
|
|
|
|
/* the rest are all sorts of intersections */
|
2017-08-17 18:39:20 +02:00
|
|
|
return 0.0;
|
2000-12-11 21:39:15 +01:00
|
|
|
}
|
|
|
|
|
2002-08-30 01:03:58 +02:00
|
|
|
/* Test if a box is also a point */
|
2006-07-26 01:23:45 +02:00
|
|
|
Datum
|
|
|
|
cube_is_point(PG_FUNCTION_ARGS)
|
2000-12-11 21:39:15 +01:00
|
|
|
{
|
2017-09-18 21:21:23 +02:00
|
|
|
NDBOX *cube = PG_GETARG_NDBOX_P(0);
|
Extend cube on-disk format to pack points more tightly.
If the lower left and upper right corners of a cube are the same, set a
flag in the cube header, and only store one copy of the coordinates. That
cuts the on-disk size into half for the common case that the cube datatype
is used to represent points rather than boxes.
The new format is backwards-compatible with the old one, so pg_upgrade
still works. However, to get the space savings, the data needs to be
rewritten. A simple VACUUM FULL or REINDEX is not enough, as the old
Datums will just be moved to the new heap/index as is. A pg_dump and
reload, or something similar like casting to text and back, will do the
trick.
This patch deliberately doesn't update all the alternative expected output
files, as I don't have access to machines that produce those outputs. I'm
not sure if they are still relevant, but if they are, the buildfarm will
tell us and produce the diff required to fix it. If none of the buildfarm
animals need them, they should be removed altogether.
Patch by Stas Kelvich.
2013-10-21 19:59:42 +02:00
|
|
|
bool result;
|
|
|
|
|
|
|
|
result = cube_is_point_internal(cube);
|
|
|
|
PG_FREE_IF_COPY(cube, 0);
|
|
|
|
PG_RETURN_BOOL(result);
|
|
|
|
}
|
2002-09-04 22:31:48 +02:00
|
|
|
|
Extend cube on-disk format to pack points more tightly.
If the lower left and upper right corners of a cube are the same, set a
flag in the cube header, and only store one copy of the coordinates. That
cuts the on-disk size into half for the common case that the cube datatype
is used to represent points rather than boxes.
The new format is backwards-compatible with the old one, so pg_upgrade
still works. However, to get the space savings, the data needs to be
rewritten. A simple VACUUM FULL or REINDEX is not enough, as the old
Datums will just be moved to the new heap/index as is. A pg_dump and
reload, or something similar like casting to text and back, will do the
trick.
This patch deliberately doesn't update all the alternative expected output
files, as I don't have access to machines that produce those outputs. I'm
not sure if they are still relevant, but if they are, the buildfarm will
tell us and produce the diff required to fix it. If none of the buildfarm
animals need them, they should be removed altogether.
Patch by Stas Kelvich.
2013-10-21 19:59:42 +02:00
|
|
|
static bool
|
|
|
|
cube_is_point_internal(NDBOX *cube)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
if (IS_POINT(cube))
|
|
|
|
return true;
|
|
|
|
|
|
|
|
/*
|
2014-05-06 18:12:18 +02:00
|
|
|
* Even if the point-flag is not set, all the lower-left coordinates might
|
|
|
|
* match the upper-right coordinates, so that the value is in fact a
|
|
|
|
* point. Such values don't arise with current code - the point flag is
|
|
|
|
* always set if appropriate - but they might be present on-disk in
|
|
|
|
* clusters upgraded from pre-9.4 versions.
|
Extend cube on-disk format to pack points more tightly.
If the lower left and upper right corners of a cube are the same, set a
flag in the cube header, and only store one copy of the coordinates. That
cuts the on-disk size into half for the common case that the cube datatype
is used to represent points rather than boxes.
The new format is backwards-compatible with the old one, so pg_upgrade
still works. However, to get the space savings, the data needs to be
rewritten. A simple VACUUM FULL or REINDEX is not enough, as the old
Datums will just be moved to the new heap/index as is. A pg_dump and
reload, or something similar like casting to text and back, will do the
trick.
This patch deliberately doesn't update all the alternative expected output
files, as I don't have access to machines that produce those outputs. I'm
not sure if they are still relevant, but if they are, the buildfarm will
tell us and produce the diff required to fix it. If none of the buildfarm
animals need them, they should be removed altogether.
Patch by Stas Kelvich.
2013-10-21 19:59:42 +02:00
|
|
|
*/
|
|
|
|
for (i = 0; i < DIM(cube); i++)
|
2002-09-04 22:31:48 +02:00
|
|
|
{
|
Extend cube on-disk format to pack points more tightly.
If the lower left and upper right corners of a cube are the same, set a
flag in the cube header, and only store one copy of the coordinates. That
cuts the on-disk size into half for the common case that the cube datatype
is used to represent points rather than boxes.
The new format is backwards-compatible with the old one, so pg_upgrade
still works. However, to get the space savings, the data needs to be
rewritten. A simple VACUUM FULL or REINDEX is not enough, as the old
Datums will just be moved to the new heap/index as is. A pg_dump and
reload, or something similar like casting to text and back, will do the
trick.
This patch deliberately doesn't update all the alternative expected output
files, as I don't have access to machines that produce those outputs. I'm
not sure if they are still relevant, but if they are, the buildfarm will
tell us and produce the diff required to fix it. If none of the buildfarm
animals need them, they should be removed altogether.
Patch by Stas Kelvich.
2013-10-21 19:59:42 +02:00
|
|
|
if (LL_COORD(cube, i) != UR_COORD(cube, i))
|
|
|
|
return false;
|
2002-09-04 22:31:48 +02:00
|
|
|
}
|
Extend cube on-disk format to pack points more tightly.
If the lower left and upper right corners of a cube are the same, set a
flag in the cube header, and only store one copy of the coordinates. That
cuts the on-disk size into half for the common case that the cube datatype
is used to represent points rather than boxes.
The new format is backwards-compatible with the old one, so pg_upgrade
still works. However, to get the space savings, the data needs to be
rewritten. A simple VACUUM FULL or REINDEX is not enough, as the old
Datums will just be moved to the new heap/index as is. A pg_dump and
reload, or something similar like casting to text and back, will do the
trick.
This patch deliberately doesn't update all the alternative expected output
files, as I don't have access to machines that produce those outputs. I'm
not sure if they are still relevant, but if they are, the buildfarm will
tell us and produce the diff required to fix it. If none of the buildfarm
animals need them, they should be removed altogether.
Patch by Stas Kelvich.
2013-10-21 19:59:42 +02:00
|
|
|
return true;
|
2002-08-30 01:03:58 +02:00
|
|
|
}
|
2001-03-22 05:01:46 +01:00
|
|
|
|
2002-08-30 01:03:58 +02:00
|
|
|
/* Return dimensions in use in the data structure */
|
2006-07-26 01:23:45 +02:00
|
|
|
Datum
|
|
|
|
cube_dim(PG_FUNCTION_ARGS)
|
2002-08-30 01:03:58 +02:00
|
|
|
{
|
2017-09-18 21:21:23 +02:00
|
|
|
NDBOX *c = PG_GETARG_NDBOX_P(0);
|
Extend cube on-disk format to pack points more tightly.
If the lower left and upper right corners of a cube are the same, set a
flag in the cube header, and only store one copy of the coordinates. That
cuts the on-disk size into half for the common case that the cube datatype
is used to represent points rather than boxes.
The new format is backwards-compatible with the old one, so pg_upgrade
still works. However, to get the space savings, the data needs to be
rewritten. A simple VACUUM FULL or REINDEX is not enough, as the old
Datums will just be moved to the new heap/index as is. A pg_dump and
reload, or something similar like casting to text and back, will do the
trick.
This patch deliberately doesn't update all the alternative expected output
files, as I don't have access to machines that produce those outputs. I'm
not sure if they are still relevant, but if they are, the buildfarm will
tell us and produce the diff required to fix it. If none of the buildfarm
animals need them, they should be removed altogether.
Patch by Stas Kelvich.
2013-10-21 19:59:42 +02:00
|
|
|
int dim = DIM(c);
|
2014-05-06 18:12:18 +02:00
|
|
|
|
2007-11-15 22:14:46 +01:00
|
|
|
PG_FREE_IF_COPY(c, 0);
|
2008-05-29 20:46:40 +02:00
|
|
|
PG_RETURN_INT32(dim);
|
2002-08-30 01:03:58 +02:00
|
|
|
}
|
2001-03-22 05:01:46 +01:00
|
|
|
|
2002-08-30 01:03:58 +02:00
|
|
|
/* Return a specific normalized LL coordinate */
|
2006-07-26 01:23:45 +02:00
|
|
|
Datum
|
|
|
|
cube_ll_coord(PG_FUNCTION_ARGS)
|
2002-08-30 01:03:58 +02:00
|
|
|
{
|
2017-09-18 21:21:23 +02:00
|
|
|
NDBOX *c = PG_GETARG_NDBOX_P(0);
|
2015-12-28 20:39:09 +01:00
|
|
|
int n = PG_GETARG_INT32(1);
|
2006-07-26 01:23:45 +02:00
|
|
|
double result;
|
2002-09-04 22:31:48 +02:00
|
|
|
|
Extend cube on-disk format to pack points more tightly.
If the lower left and upper right corners of a cube are the same, set a
flag in the cube header, and only store one copy of the coordinates. That
cuts the on-disk size into half for the common case that the cube datatype
is used to represent points rather than boxes.
The new format is backwards-compatible with the old one, so pg_upgrade
still works. However, to get the space savings, the data needs to be
rewritten. A simple VACUUM FULL or REINDEX is not enough, as the old
Datums will just be moved to the new heap/index as is. A pg_dump and
reload, or something similar like casting to text and back, will do the
trick.
This patch deliberately doesn't update all the alternative expected output
files, as I don't have access to machines that produce those outputs. I'm
not sure if they are still relevant, but if they are, the buildfarm will
tell us and produce the diff required to fix it. If none of the buildfarm
animals need them, they should be removed altogether.
Patch by Stas Kelvich.
2013-10-21 19:59:42 +02:00
|
|
|
if (DIM(c) >= n && n > 0)
|
2014-05-06 18:12:18 +02:00
|
|
|
result = Min(LL_COORD(c, n - 1), UR_COORD(c, n - 1));
|
2008-05-29 20:46:40 +02:00
|
|
|
else
|
|
|
|
result = 0;
|
2006-07-26 01:23:45 +02:00
|
|
|
|
2007-11-15 22:14:46 +01:00
|
|
|
PG_FREE_IF_COPY(c, 0);
|
2006-07-26 01:23:45 +02:00
|
|
|
PG_RETURN_FLOAT8(result);
|
2002-08-30 01:03:58 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Return a specific normalized UR coordinate */
|
2006-07-26 01:23:45 +02:00
|
|
|
Datum
|
|
|
|
cube_ur_coord(PG_FUNCTION_ARGS)
|
2002-08-30 01:03:58 +02:00
|
|
|
{
|
2017-09-18 21:21:23 +02:00
|
|
|
NDBOX *c = PG_GETARG_NDBOX_P(0);
|
2015-12-28 20:39:09 +01:00
|
|
|
int n = PG_GETARG_INT32(1);
|
2006-07-26 01:23:45 +02:00
|
|
|
double result;
|
|
|
|
|
Extend cube on-disk format to pack points more tightly.
If the lower left and upper right corners of a cube are the same, set a
flag in the cube header, and only store one copy of the coordinates. That
cuts the on-disk size into half for the common case that the cube datatype
is used to represent points rather than boxes.
The new format is backwards-compatible with the old one, so pg_upgrade
still works. However, to get the space savings, the data needs to be
rewritten. A simple VACUUM FULL or REINDEX is not enough, as the old
Datums will just be moved to the new heap/index as is. A pg_dump and
reload, or something similar like casting to text and back, will do the
trick.
This patch deliberately doesn't update all the alternative expected output
files, as I don't have access to machines that produce those outputs. I'm
not sure if they are still relevant, but if they are, the buildfarm will
tell us and produce the diff required to fix it. If none of the buildfarm
animals need them, they should be removed altogether.
Patch by Stas Kelvich.
2013-10-21 19:59:42 +02:00
|
|
|
if (DIM(c) >= n && n > 0)
|
2014-05-06 18:12:18 +02:00
|
|
|
result = Max(LL_COORD(c, n - 1), UR_COORD(c, n - 1));
|
2008-05-29 20:46:40 +02:00
|
|
|
else
|
|
|
|
result = 0;
|
2006-07-26 01:23:45 +02:00
|
|
|
|
2007-11-15 22:14:46 +01:00
|
|
|
PG_FREE_IF_COPY(c, 0);
|
2006-07-26 01:23:45 +02:00
|
|
|
PG_RETURN_FLOAT8(result);
|
2002-08-30 01:03:58 +02:00
|
|
|
}
|
|
|
|
|
2015-12-18 12:38:27 +01:00
|
|
|
/*
|
|
|
|
* Function returns cube coordinate.
|
|
|
|
* Numbers from 1 to DIM denotes first corner coordinates.
|
|
|
|
* Numbers from DIM+1 to 2*DIM denotes second corner coordinates.
|
|
|
|
*/
|
|
|
|
Datum
|
|
|
|
cube_coord(PG_FUNCTION_ARGS)
|
|
|
|
{
|
2017-09-18 21:21:23 +02:00
|
|
|
NDBOX *cube = PG_GETARG_NDBOX_P(0);
|
2015-12-28 20:39:09 +01:00
|
|
|
int coord = PG_GETARG_INT32(1);
|
2015-12-18 12:38:27 +01:00
|
|
|
|
2015-12-28 20:39:09 +01:00
|
|
|
if (coord <= 0 || coord > 2 * DIM(cube))
|
2015-12-18 12:38:27 +01:00
|
|
|
ereport(ERROR,
|
2015-12-28 20:39:09 +01:00
|
|
|
(errcode(ERRCODE_ARRAY_ELEMENT_ERROR),
|
|
|
|
errmsg("cube index %d is out of bounds", coord)));
|
|
|
|
|
|
|
|
if (IS_POINT(cube))
|
|
|
|
PG_RETURN_FLOAT8(cube->x[(coord - 1) % DIM(cube)]);
|
|
|
|
else
|
|
|
|
PG_RETURN_FLOAT8(cube->x[coord - 1]);
|
2015-12-18 12:38:27 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* This function works like cube_coord(),
|
|
|
|
* but rearranges coordinates of corners to get cube representation
|
|
|
|
* in the form of (lower left, upper right).
|
|
|
|
* For historical reasons that extension allows us to create cubes in form
|
|
|
|
* ((2,1),(1,2)) and instead of normalizing such cube to ((1,1),(2,2)) it
|
|
|
|
* stores cube in original way. But to get cubes ordered by one of dimensions
|
|
|
|
* directly from the index without extra sort step we need some
|
|
|
|
* representation-independent coordinate getter. This function implements it.
|
|
|
|
*/
|
|
|
|
Datum
|
|
|
|
cube_coord_llur(PG_FUNCTION_ARGS)
|
|
|
|
{
|
2017-09-18 21:21:23 +02:00
|
|
|
NDBOX *cube = PG_GETARG_NDBOX_P(0);
|
2015-12-28 20:39:09 +01:00
|
|
|
int coord = PG_GETARG_INT32(1);
|
2015-12-18 12:38:27 +01:00
|
|
|
|
2015-12-28 20:39:09 +01:00
|
|
|
if (coord <= 0 || coord > 2 * DIM(cube))
|
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_ARRAY_ELEMENT_ERROR),
|
|
|
|
errmsg("cube index %d is out of bounds", coord)));
|
|
|
|
|
|
|
|
if (coord <= DIM(cube))
|
2015-12-18 12:38:27 +01:00
|
|
|
{
|
2015-12-28 20:39:09 +01:00
|
|
|
if (IS_POINT(cube))
|
|
|
|
PG_RETURN_FLOAT8(cube->x[coord - 1]);
|
2015-12-18 12:38:27 +01:00
|
|
|
else
|
2015-12-28 20:39:09 +01:00
|
|
|
PG_RETURN_FLOAT8(Min(cube->x[coord - 1],
|
|
|
|
cube->x[coord - 1 + DIM(cube)]));
|
2015-12-18 12:38:27 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2015-12-28 20:39:09 +01:00
|
|
|
if (IS_POINT(cube))
|
|
|
|
PG_RETURN_FLOAT8(cube->x[(coord - 1) % DIM(cube)]);
|
|
|
|
else
|
|
|
|
PG_RETURN_FLOAT8(Max(cube->x[coord - 1],
|
|
|
|
cube->x[coord - 1 - DIM(cube)]));
|
2015-12-18 12:38:27 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-08-30 01:03:58 +02:00
|
|
|
/* Increase or decrease box size by a radius in at least n dimensions. */
|
2006-07-26 01:23:45 +02:00
|
|
|
Datum
|
|
|
|
cube_enlarge(PG_FUNCTION_ARGS)
|
2002-08-30 01:03:58 +02:00
|
|
|
{
|
2017-09-18 21:21:23 +02:00
|
|
|
NDBOX *a = PG_GETARG_NDBOX_P(0);
|
2008-05-29 20:46:40 +02:00
|
|
|
double r = PG_GETARG_FLOAT8(1);
|
2012-06-25 00:51:46 +02:00
|
|
|
int32 n = PG_GETARG_INT32(2);
|
2002-09-04 22:31:48 +02:00
|
|
|
NDBOX *result;
|
|
|
|
int dim = 0;
|
|
|
|
int size;
|
|
|
|
int i,
|
Extend cube on-disk format to pack points more tightly.
If the lower left and upper right corners of a cube are the same, set a
flag in the cube header, and only store one copy of the coordinates. That
cuts the on-disk size into half for the common case that the cube datatype
is used to represent points rather than boxes.
The new format is backwards-compatible with the old one, so pg_upgrade
still works. However, to get the space savings, the data needs to be
rewritten. A simple VACUUM FULL or REINDEX is not enough, as the old
Datums will just be moved to the new heap/index as is. A pg_dump and
reload, or something similar like casting to text and back, will do the
trick.
This patch deliberately doesn't update all the alternative expected output
files, as I don't have access to machines that produce those outputs. I'm
not sure if they are still relevant, but if they are, the buildfarm will
tell us and produce the diff required to fix it. If none of the buildfarm
animals need them, they should be removed altogether.
Patch by Stas Kelvich.
2013-10-21 19:59:42 +02:00
|
|
|
j;
|
2002-09-04 22:31:48 +02:00
|
|
|
|
2003-08-04 02:43:34 +02:00
|
|
|
if (n > CUBE_MAX_DIM)
|
|
|
|
n = CUBE_MAX_DIM;
|
2007-03-07 22:21:12 +01:00
|
|
|
if (r > 0 && n > 0)
|
2002-09-04 22:31:48 +02:00
|
|
|
dim = n;
|
Extend cube on-disk format to pack points more tightly.
If the lower left and upper right corners of a cube are the same, set a
flag in the cube header, and only store one copy of the coordinates. That
cuts the on-disk size into half for the common case that the cube datatype
is used to represent points rather than boxes.
The new format is backwards-compatible with the old one, so pg_upgrade
still works. However, to get the space savings, the data needs to be
rewritten. A simple VACUUM FULL or REINDEX is not enough, as the old
Datums will just be moved to the new heap/index as is. A pg_dump and
reload, or something similar like casting to text and back, will do the
trick.
This patch deliberately doesn't update all the alternative expected output
files, as I don't have access to machines that produce those outputs. I'm
not sure if they are still relevant, but if they are, the buildfarm will
tell us and produce the diff required to fix it. If none of the buildfarm
animals need them, they should be removed altogether.
Patch by Stas Kelvich.
2013-10-21 19:59:42 +02:00
|
|
|
if (DIM(a) > dim)
|
|
|
|
dim = DIM(a);
|
|
|
|
|
|
|
|
size = CUBE_SIZE(dim);
|
2007-02-28 00:48:10 +01:00
|
|
|
result = (NDBOX *) palloc0(size);
|
|
|
|
SET_VARSIZE(result, size);
|
Extend cube on-disk format to pack points more tightly.
If the lower left and upper right corners of a cube are the same, set a
flag in the cube header, and only store one copy of the coordinates. That
cuts the on-disk size into half for the common case that the cube datatype
is used to represent points rather than boxes.
The new format is backwards-compatible with the old one, so pg_upgrade
still works. However, to get the space savings, the data needs to be
rewritten. A simple VACUUM FULL or REINDEX is not enough, as the old
Datums will just be moved to the new heap/index as is. A pg_dump and
reload, or something similar like casting to text and back, will do the
trick.
This patch deliberately doesn't update all the alternative expected output
files, as I don't have access to machines that produce those outputs. I'm
not sure if they are still relevant, but if they are, the buildfarm will
tell us and produce the diff required to fix it. If none of the buildfarm
animals need them, they should be removed altogether.
Patch by Stas Kelvich.
2013-10-21 19:59:42 +02:00
|
|
|
SET_DIM(result, dim);
|
|
|
|
|
|
|
|
for (i = 0, j = dim; i < DIM(a); i++, j++)
|
2002-09-04 22:31:48 +02:00
|
|
|
{
|
2014-05-06 18:12:18 +02:00
|
|
|
if (LL_COORD(a, i) >= UR_COORD(a, i))
|
2002-09-04 22:31:48 +02:00
|
|
|
{
|
2014-05-06 18:12:18 +02:00
|
|
|
result->x[i] = UR_COORD(a, i) - r;
|
|
|
|
result->x[j] = LL_COORD(a, i) + r;
|
2002-09-04 22:31:48 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2014-05-06 18:12:18 +02:00
|
|
|
result->x[i] = LL_COORD(a, i) - r;
|
|
|
|
result->x[j] = UR_COORD(a, i) + r;
|
2002-09-04 22:31:48 +02:00
|
|
|
}
|
|
|
|
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 */
|
2002-08-30 01:03:58 +02:00
|
|
|
for (; i < dim; i++, j++)
|
2002-09-04 22:31:48 +02:00
|
|
|
{
|
2007-03-07 22:21:12 +01:00
|
|
|
result->x[i] = -r;
|
|
|
|
result->x[j] = r;
|
2002-09-04 22:31:48 +02:00
|
|
|
}
|
2006-07-26 01:23:45 +02:00
|
|
|
|
Extend cube on-disk format to pack points more tightly.
If the lower left and upper right corners of a cube are the same, set a
flag in the cube header, and only store one copy of the coordinates. That
cuts the on-disk size into half for the common case that the cube datatype
is used to represent points rather than boxes.
The new format is backwards-compatible with the old one, so pg_upgrade
still works. However, to get the space savings, the data needs to be
rewritten. A simple VACUUM FULL or REINDEX is not enough, as the old
Datums will just be moved to the new heap/index as is. A pg_dump and
reload, or something similar like casting to text and back, will do the
trick.
This patch deliberately doesn't update all the alternative expected output
files, as I don't have access to machines that produce those outputs. I'm
not sure if they are still relevant, but if they are, the buildfarm will
tell us and produce the diff required to fix it. If none of the buildfarm
animals need them, they should be removed altogether.
Patch by Stas Kelvich.
2013-10-21 19:59:42 +02:00
|
|
|
/*
|
|
|
|
* Check if the result was in fact a point, and set the flag in the datum
|
|
|
|
* accordingly. (we don't bother to repalloc it smaller)
|
|
|
|
*/
|
|
|
|
if (cube_is_point_internal(result))
|
|
|
|
{
|
|
|
|
size = POINT_SIZE(dim);
|
|
|
|
SET_VARSIZE(result, size);
|
|
|
|
SET_POINT_BIT(result);
|
|
|
|
}
|
|
|
|
|
2007-11-15 22:14:46 +01:00
|
|
|
PG_FREE_IF_COPY(a, 0);
|
2017-09-18 21:21:23 +02:00
|
|
|
PG_RETURN_NDBOX_P(result);
|
2000-12-11 21:39:15 +01:00
|
|
|
}
|
2003-02-13 06:26:50 +01:00
|
|
|
|
|
|
|
/* Create a one dimensional box with identical upper and lower coordinates */
|
2006-07-26 01:23:45 +02:00
|
|
|
Datum
|
|
|
|
cube_f8(PG_FUNCTION_ARGS)
|
2003-02-13 06:26:50 +01:00
|
|
|
{
|
2008-05-29 20:46:40 +02:00
|
|
|
double x = PG_GETARG_FLOAT8(0);
|
2003-02-13 06:26:50 +01:00
|
|
|
NDBOX *result;
|
2003-08-04 02:43:34 +02:00
|
|
|
int size;
|
|
|
|
|
Extend cube on-disk format to pack points more tightly.
If the lower left and upper right corners of a cube are the same, set a
flag in the cube header, and only store one copy of the coordinates. That
cuts the on-disk size into half for the common case that the cube datatype
is used to represent points rather than boxes.
The new format is backwards-compatible with the old one, so pg_upgrade
still works. However, to get the space savings, the data needs to be
rewritten. A simple VACUUM FULL or REINDEX is not enough, as the old
Datums will just be moved to the new heap/index as is. A pg_dump and
reload, or something similar like casting to text and back, will do the
trick.
This patch deliberately doesn't update all the alternative expected output
files, as I don't have access to machines that produce those outputs. I'm
not sure if they are still relevant, but if they are, the buildfarm will
tell us and produce the diff required to fix it. If none of the buildfarm
animals need them, they should be removed altogether.
Patch by Stas Kelvich.
2013-10-21 19:59:42 +02:00
|
|
|
size = POINT_SIZE(1);
|
2007-02-28 00:48:10 +01:00
|
|
|
result = (NDBOX *) palloc0(size);
|
|
|
|
SET_VARSIZE(result, size);
|
Extend cube on-disk format to pack points more tightly.
If the lower left and upper right corners of a cube are the same, set a
flag in the cube header, and only store one copy of the coordinates. That
cuts the on-disk size into half for the common case that the cube datatype
is used to represent points rather than boxes.
The new format is backwards-compatible with the old one, so pg_upgrade
still works. However, to get the space savings, the data needs to be
rewritten. A simple VACUUM FULL or REINDEX is not enough, as the old
Datums will just be moved to the new heap/index as is. A pg_dump and
reload, or something similar like casting to text and back, will do the
trick.
This patch deliberately doesn't update all the alternative expected output
files, as I don't have access to machines that produce those outputs. I'm
not sure if they are still relevant, but if they are, the buildfarm will
tell us and produce the diff required to fix it. If none of the buildfarm
animals need them, they should be removed altogether.
Patch by Stas Kelvich.
2013-10-21 19:59:42 +02:00
|
|
|
SET_DIM(result, 1);
|
|
|
|
SET_POINT_BIT(result);
|
|
|
|
result->x[0] = x;
|
2006-10-04 02:30:14 +02:00
|
|
|
|
2017-09-18 21:21:23 +02:00
|
|
|
PG_RETURN_NDBOX_P(result);
|
2003-02-13 06:26:50 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Create a one dimensional box */
|
2006-07-26 01:23:45 +02:00
|
|
|
Datum
|
|
|
|
cube_f8_f8(PG_FUNCTION_ARGS)
|
2003-02-13 06:26:50 +01:00
|
|
|
{
|
2008-05-29 20:46:40 +02:00
|
|
|
double x0 = PG_GETARG_FLOAT8(0);
|
|
|
|
double x1 = PG_GETARG_FLOAT8(1);
|
2003-02-13 06:26:50 +01:00
|
|
|
NDBOX *result;
|
2003-08-04 02:43:34 +02:00
|
|
|
int size;
|
|
|
|
|
Extend cube on-disk format to pack points more tightly.
If the lower left and upper right corners of a cube are the same, set a
flag in the cube header, and only store one copy of the coordinates. That
cuts the on-disk size into half for the common case that the cube datatype
is used to represent points rather than boxes.
The new format is backwards-compatible with the old one, so pg_upgrade
still works. However, to get the space savings, the data needs to be
rewritten. A simple VACUUM FULL or REINDEX is not enough, as the old
Datums will just be moved to the new heap/index as is. A pg_dump and
reload, or something similar like casting to text and back, will do the
trick.
This patch deliberately doesn't update all the alternative expected output
files, as I don't have access to machines that produce those outputs. I'm
not sure if they are still relevant, but if they are, the buildfarm will
tell us and produce the diff required to fix it. If none of the buildfarm
animals need them, they should be removed altogether.
Patch by Stas Kelvich.
2013-10-21 19:59:42 +02:00
|
|
|
if (x0 == x1)
|
|
|
|
{
|
|
|
|
size = POINT_SIZE(1);
|
|
|
|
result = (NDBOX *) palloc0(size);
|
|
|
|
SET_VARSIZE(result, size);
|
|
|
|
SET_DIM(result, 1);
|
|
|
|
SET_POINT_BIT(result);
|
|
|
|
result->x[0] = x0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
size = CUBE_SIZE(1);
|
|
|
|
result = (NDBOX *) palloc0(size);
|
|
|
|
SET_VARSIZE(result, size);
|
|
|
|
SET_DIM(result, 1);
|
|
|
|
result->x[0] = x0;
|
|
|
|
result->x[1] = x1;
|
|
|
|
}
|
2006-07-26 01:23:45 +02:00
|
|
|
|
2017-09-18 21:21:23 +02:00
|
|
|
PG_RETURN_NDBOX_P(result);
|
2003-02-13 06:26:50 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Add a dimension to an existing cube with the same values for the new
|
|
|
|
coordinate */
|
2006-07-26 01:23:45 +02:00
|
|
|
Datum
|
|
|
|
cube_c_f8(PG_FUNCTION_ARGS)
|
2003-02-13 06:26:50 +01:00
|
|
|
{
|
2017-09-18 21:21:23 +02:00
|
|
|
NDBOX *cube = PG_GETARG_NDBOX_P(0);
|
2008-05-29 20:46:40 +02:00
|
|
|
double x = PG_GETARG_FLOAT8(1);
|
2003-02-13 06:26:50 +01:00
|
|
|
NDBOX *result;
|
2003-08-04 02:43:34 +02:00
|
|
|
int size;
|
|
|
|
int i;
|
|
|
|
|
Extend cube on-disk format to pack points more tightly.
If the lower left and upper right corners of a cube are the same, set a
flag in the cube header, and only store one copy of the coordinates. That
cuts the on-disk size into half for the common case that the cube datatype
is used to represent points rather than boxes.
The new format is backwards-compatible with the old one, so pg_upgrade
still works. However, to get the space savings, the data needs to be
rewritten. A simple VACUUM FULL or REINDEX is not enough, as the old
Datums will just be moved to the new heap/index as is. A pg_dump and
reload, or something similar like casting to text and back, will do the
trick.
This patch deliberately doesn't update all the alternative expected output
files, as I don't have access to machines that produce those outputs. I'm
not sure if they are still relevant, but if they are, the buildfarm will
tell us and produce the diff required to fix it. If none of the buildfarm
animals need them, they should be removed altogether.
Patch by Stas Kelvich.
2013-10-21 19:59:42 +02:00
|
|
|
if (IS_POINT(cube))
|
|
|
|
{
|
|
|
|
size = POINT_SIZE((DIM(cube) + 1));
|
|
|
|
result = (NDBOX *) palloc0(size);
|
|
|
|
SET_VARSIZE(result, size);
|
|
|
|
SET_DIM(result, DIM(cube) + 1);
|
|
|
|
SET_POINT_BIT(result);
|
|
|
|
for (i = 0; i < DIM(cube); i++)
|
|
|
|
result->x[i] = cube->x[i];
|
|
|
|
result->x[DIM(result) - 1] = x;
|
|
|
|
}
|
|
|
|
else
|
2003-08-04 02:43:34 +02:00
|
|
|
{
|
Extend cube on-disk format to pack points more tightly.
If the lower left and upper right corners of a cube are the same, set a
flag in the cube header, and only store one copy of the coordinates. That
cuts the on-disk size into half for the common case that the cube datatype
is used to represent points rather than boxes.
The new format is backwards-compatible with the old one, so pg_upgrade
still works. However, to get the space savings, the data needs to be
rewritten. A simple VACUUM FULL or REINDEX is not enough, as the old
Datums will just be moved to the new heap/index as is. A pg_dump and
reload, or something similar like casting to text and back, will do the
trick.
This patch deliberately doesn't update all the alternative expected output
files, as I don't have access to machines that produce those outputs. I'm
not sure if they are still relevant, but if they are, the buildfarm will
tell us and produce the diff required to fix it. If none of the buildfarm
animals need them, they should be removed altogether.
Patch by Stas Kelvich.
2013-10-21 19:59:42 +02:00
|
|
|
size = CUBE_SIZE((DIM(cube) + 1));
|
|
|
|
result = (NDBOX *) palloc0(size);
|
|
|
|
SET_VARSIZE(result, size);
|
|
|
|
SET_DIM(result, DIM(cube) + 1);
|
|
|
|
for (i = 0; i < DIM(cube); i++)
|
|
|
|
{
|
|
|
|
result->x[i] = cube->x[i];
|
|
|
|
result->x[DIM(result) + i] = cube->x[DIM(cube) + i];
|
|
|
|
}
|
|
|
|
result->x[DIM(result) - 1] = x;
|
2014-05-06 18:12:18 +02:00
|
|
|
result->x[2 * DIM(result) - 1] = x;
|
2003-08-04 02:43:34 +02:00
|
|
|
}
|
2006-07-26 01:23:45 +02:00
|
|
|
|
Extend cube on-disk format to pack points more tightly.
If the lower left and upper right corners of a cube are the same, set a
flag in the cube header, and only store one copy of the coordinates. That
cuts the on-disk size into half for the common case that the cube datatype
is used to represent points rather than boxes.
The new format is backwards-compatible with the old one, so pg_upgrade
still works. However, to get the space savings, the data needs to be
rewritten. A simple VACUUM FULL or REINDEX is not enough, as the old
Datums will just be moved to the new heap/index as is. A pg_dump and
reload, or something similar like casting to text and back, will do the
trick.
This patch deliberately doesn't update all the alternative expected output
files, as I don't have access to machines that produce those outputs. I'm
not sure if they are still relevant, but if they are, the buildfarm will
tell us and produce the diff required to fix it. If none of the buildfarm
animals need them, they should be removed altogether.
Patch by Stas Kelvich.
2013-10-21 19:59:42 +02:00
|
|
|
PG_FREE_IF_COPY(cube, 0);
|
2017-09-18 21:21:23 +02:00
|
|
|
PG_RETURN_NDBOX_P(result);
|
2003-02-13 06:26:50 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Add a dimension to an existing cube */
|
2006-07-26 01:23:45 +02:00
|
|
|
Datum
|
|
|
|
cube_c_f8_f8(PG_FUNCTION_ARGS)
|
2003-02-13 06:26:50 +01:00
|
|
|
{
|
2017-09-18 21:21:23 +02:00
|
|
|
NDBOX *cube = PG_GETARG_NDBOX_P(0);
|
2008-05-29 20:46:40 +02:00
|
|
|
double x1 = PG_GETARG_FLOAT8(1);
|
|
|
|
double x2 = PG_GETARG_FLOAT8(2);
|
2003-02-13 06:26:50 +01:00
|
|
|
NDBOX *result;
|
2003-08-04 02:43:34 +02:00
|
|
|
int size;
|
|
|
|
int i;
|
|
|
|
|
2014-05-06 18:12:18 +02:00
|
|
|
if (IS_POINT(cube) && (x1 == x2))
|
|
|
|
{
|
Extend cube on-disk format to pack points more tightly.
If the lower left and upper right corners of a cube are the same, set a
flag in the cube header, and only store one copy of the coordinates. That
cuts the on-disk size into half for the common case that the cube datatype
is used to represent points rather than boxes.
The new format is backwards-compatible with the old one, so pg_upgrade
still works. However, to get the space savings, the data needs to be
rewritten. A simple VACUUM FULL or REINDEX is not enough, as the old
Datums will just be moved to the new heap/index as is. A pg_dump and
reload, or something similar like casting to text and back, will do the
trick.
This patch deliberately doesn't update all the alternative expected output
files, as I don't have access to machines that produce those outputs. I'm
not sure if they are still relevant, but if they are, the buildfarm will
tell us and produce the diff required to fix it. If none of the buildfarm
animals need them, they should be removed altogether.
Patch by Stas Kelvich.
2013-10-21 19:59:42 +02:00
|
|
|
size = POINT_SIZE((DIM(cube) + 1));
|
|
|
|
result = (NDBOX *) palloc0(size);
|
|
|
|
SET_VARSIZE(result, size);
|
|
|
|
SET_DIM(result, DIM(cube) + 1);
|
|
|
|
SET_POINT_BIT(result);
|
|
|
|
for (i = 0; i < DIM(cube); i++)
|
|
|
|
result->x[i] = cube->x[i];
|
|
|
|
result->x[DIM(result) - 1] = x1;
|
|
|
|
}
|
|
|
|
else
|
2003-08-04 02:43:34 +02:00
|
|
|
{
|
Extend cube on-disk format to pack points more tightly.
If the lower left and upper right corners of a cube are the same, set a
flag in the cube header, and only store one copy of the coordinates. That
cuts the on-disk size into half for the common case that the cube datatype
is used to represent points rather than boxes.
The new format is backwards-compatible with the old one, so pg_upgrade
still works. However, to get the space savings, the data needs to be
rewritten. A simple VACUUM FULL or REINDEX is not enough, as the old
Datums will just be moved to the new heap/index as is. A pg_dump and
reload, or something similar like casting to text and back, will do the
trick.
This patch deliberately doesn't update all the alternative expected output
files, as I don't have access to machines that produce those outputs. I'm
not sure if they are still relevant, but if they are, the buildfarm will
tell us and produce the diff required to fix it. If none of the buildfarm
animals need them, they should be removed altogether.
Patch by Stas Kelvich.
2013-10-21 19:59:42 +02:00
|
|
|
size = CUBE_SIZE((DIM(cube) + 1));
|
|
|
|
result = (NDBOX *) palloc0(size);
|
|
|
|
SET_VARSIZE(result, size);
|
|
|
|
SET_DIM(result, DIM(cube) + 1);
|
|
|
|
for (i = 0; i < DIM(cube); i++)
|
|
|
|
{
|
|
|
|
result->x[i] = LL_COORD(cube, i);
|
|
|
|
result->x[DIM(result) + i] = UR_COORD(cube, i);
|
|
|
|
}
|
|
|
|
result->x[DIM(result) - 1] = x1;
|
|
|
|
result->x[2 * DIM(result) - 1] = x2;
|
2003-08-04 02:43:34 +02:00
|
|
|
}
|
2006-07-26 01:23:45 +02:00
|
|
|
|
Extend cube on-disk format to pack points more tightly.
If the lower left and upper right corners of a cube are the same, set a
flag in the cube header, and only store one copy of the coordinates. That
cuts the on-disk size into half for the common case that the cube datatype
is used to represent points rather than boxes.
The new format is backwards-compatible with the old one, so pg_upgrade
still works. However, to get the space savings, the data needs to be
rewritten. A simple VACUUM FULL or REINDEX is not enough, as the old
Datums will just be moved to the new heap/index as is. A pg_dump and
reload, or something similar like casting to text and back, will do the
trick.
This patch deliberately doesn't update all the alternative expected output
files, as I don't have access to machines that produce those outputs. I'm
not sure if they are still relevant, but if they are, the buildfarm will
tell us and produce the diff required to fix it. If none of the buildfarm
animals need them, they should be removed altogether.
Patch by Stas Kelvich.
2013-10-21 19:59:42 +02:00
|
|
|
PG_FREE_IF_COPY(cube, 0);
|
2017-09-18 21:21:23 +02:00
|
|
|
PG_RETURN_NDBOX_P(result);
|
2003-02-13 06:26:50 +01:00
|
|
|
}
|