PostgreSQL Source Code git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
cube.c File Reference
#include "postgres.h"
#include <math.h>
#include "access/gist.h"
#include "access/stratnum.h"
#include "cubedata.h"
#include "libpq/pqformat.h"
#include "utils/array.h"
#include "utils/float.h"
Include dependency graph for cube.c:

Go to the source code of this file.

Macros

#define ARRPTR(x)   ( (double *) ARR_DATA_PTR(x) )
 
#define ARRNELEMS(x)   ArrayGetNItems( ARR_NDIM(x), ARR_DIMS(x))
 

Functions

 PG_MODULE_MAGIC_EXT (.name="cube",.version=PG_VERSION)
 
 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_send)
 
 PG_FUNCTION_INFO_V1 (cube_recv)
 
 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)
 
 PG_FUNCTION_INFO_V1 (cube_coord)
 
 PG_FUNCTION_INFO_V1 (cube_coord_llur)
 
 PG_FUNCTION_INFO_V1 (cube_subset)
 
 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)
 
 PG_FUNCTION_INFO_V1 (g_cube_distance)
 
 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)
 
 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)
 
 PG_FUNCTION_INFO_V1 (distance_taxicab)
 
 PG_FUNCTION_INFO_V1 (cube_distance)
 
 PG_FUNCTION_INFO_V1 (distance_chebyshev)
 
 PG_FUNCTION_INFO_V1 (cube_is_point)
 
 PG_FUNCTION_INFO_V1 (cube_enlarge)
 
int32 cube_cmp_v0 (NDBOX *a, NDBOX *b)
 
bool cube_contains_v0 (NDBOX *a, NDBOX *b)
 
bool cube_overlap_v0 (NDBOX *a, NDBOX *b)
 
NDBOXcube_union_v0 (NDBOX *a, NDBOX *b)
 
void rt_cube_size (NDBOX *a, double *size)
 
NDBOXg_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)
 
static double distance_1D (double a1, double a2, double b1, double b2)
 
static bool cube_is_point_internal (NDBOX *cube)
 
Datum cube_in (PG_FUNCTION_ARGS)
 
Datum cube_a_f8_f8 (PG_FUNCTION_ARGS)
 
Datum cube_a_f8 (PG_FUNCTION_ARGS)
 
Datum cube_subset (PG_FUNCTION_ARGS)
 
Datum cube_out (PG_FUNCTION_ARGS)
 
Datum cube_send (PG_FUNCTION_ARGS)
 
Datum cube_recv (PG_FUNCTION_ARGS)
 
Datum g_cube_consistent (PG_FUNCTION_ARGS)
 
Datum g_cube_union (PG_FUNCTION_ARGS)
 
Datum g_cube_compress (PG_FUNCTION_ARGS)
 
Datum g_cube_decompress (PG_FUNCTION_ARGS)
 
Datum g_cube_penalty (PG_FUNCTION_ARGS)
 
Datum g_cube_picksplit (PG_FUNCTION_ARGS)
 
Datum g_cube_same (PG_FUNCTION_ARGS)
 
Datum cube_union (PG_FUNCTION_ARGS)
 
Datum cube_inter (PG_FUNCTION_ARGS)
 
Datum cube_size (PG_FUNCTION_ARGS)
 
Datum cube_cmp (PG_FUNCTION_ARGS)
 
Datum cube_eq (PG_FUNCTION_ARGS)
 
Datum cube_ne (PG_FUNCTION_ARGS)
 
Datum cube_lt (PG_FUNCTION_ARGS)
 
Datum cube_gt (PG_FUNCTION_ARGS)
 
Datum cube_le (PG_FUNCTION_ARGS)
 
Datum cube_ge (PG_FUNCTION_ARGS)
 
Datum cube_contains (PG_FUNCTION_ARGS)
 
Datum cube_contained (PG_FUNCTION_ARGS)
 
Datum cube_overlap (PG_FUNCTION_ARGS)
 
Datum cube_distance (PG_FUNCTION_ARGS)
 
Datum distance_taxicab (PG_FUNCTION_ARGS)
 
Datum distance_chebyshev (PG_FUNCTION_ARGS)
 
Datum g_cube_distance (PG_FUNCTION_ARGS)
 
Datum cube_is_point (PG_FUNCTION_ARGS)
 
Datum cube_dim (PG_FUNCTION_ARGS)
 
Datum cube_ll_coord (PG_FUNCTION_ARGS)
 
Datum cube_ur_coord (PG_FUNCTION_ARGS)
 
Datum cube_coord (PG_FUNCTION_ARGS)
 
Datum cube_coord_llur (PG_FUNCTION_ARGS)
 
Datum cube_enlarge (PG_FUNCTION_ARGS)
 
Datum cube_f8 (PG_FUNCTION_ARGS)
 
Datum cube_f8_f8 (PG_FUNCTION_ARGS)
 
Datum cube_c_f8 (PG_FUNCTION_ARGS)
 
Datum cube_c_f8_f8 (PG_FUNCTION_ARGS)
 

Macro Definition Documentation

◆ ARRNELEMS

#define ARRNELEMS (   x)    ArrayGetNItems( ARR_NDIM(x), ARR_DIMS(x))

Definition at line 29 of file cube.c.

◆ ARRPTR

#define ARRPTR (   x)    ( (double *) ARR_DATA_PTR(x) )

Definition at line 28 of file cube.c.

Function Documentation

◆ cube_a_f8()

Datum cube_a_f8 ( PG_FUNCTION_ARGS  )

Definition at line 210 of file cube.c.

211{
213 NDBOX *result;
214 int i;
215 int dim;
216 int size;
217 double *dur;
218
219 if (array_contains_nulls(ur))
221 (errcode(ERRCODE_ARRAY_ELEMENT_ERROR),
222 errmsg("cannot work with arrays containing NULLs")));
223
224 dim = ARRNELEMS(ur);
225 if (dim > CUBE_MAX_DIM)
227 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
228 errmsg("array is too long"),
229 errdetail("A cube cannot have more than %d dimensions.",
230 CUBE_MAX_DIM)));
231
232 dur = ARRPTR(ur);
233
234 size = POINT_SIZE(dim);
235 result = (NDBOX *) palloc0(size);
236 SET_VARSIZE(result, size);
237 SET_DIM(result, dim);
238 SET_POINT_BIT(result);
239
240 for (i = 0; i < dim; i++)
241 result->x[i] = dur[i];
242
243 PG_RETURN_NDBOX_P(result);
244}
#define PG_GETARG_ARRAYTYPE_P(n)
Definition: array.h:263
bool array_contains_nulls(ArrayType *array)
Definition: arrayfuncs.c:3767
#define ARRNELEMS(x)
Definition: cube.c:29
#define ARRPTR(x)
Definition: cube.c:28
#define SET_DIM(cube, _dim)
Definition: cubedata.h:43
#define POINT_SIZE(_dim)
Definition: cubedata.h:48
#define CUBE_MAX_DIM
Definition: cubedata.h:7
#define PG_RETURN_NDBOX_P(x)
Definition: cubedata.h:54
#define SET_POINT_BIT(cube)
Definition: cubedata.h:41
int errdetail(const char *fmt,...)
Definition: elog.c:1204
int errcode(int sqlerrcode)
Definition: elog.c:854
int errmsg(const char *fmt,...)
Definition: elog.c:1071
#define ERROR
Definition: elog.h:39
#define ereport(elevel,...)
Definition: elog.h:149
int i
Definition: isn.c:77
void * palloc0(Size size)
Definition: mcxt.c:1970
Definition: cubedata.h:10
double x[FLEXIBLE_ARRAY_MEMBER]
Definition: cubedata.h:33
#define SET_VARSIZE(PTR, len)
Definition: varatt.h:305

References array_contains_nulls(), ARRNELEMS, ARRPTR, CUBE_MAX_DIM, ereport, errcode(), errdetail(), errmsg(), ERROR, i, palloc0(), PG_GETARG_ARRAYTYPE_P, PG_RETURN_NDBOX_P, POINT_SIZE, SET_DIM, SET_POINT_BIT, SET_VARSIZE, and NDBOX::x.

◆ cube_a_f8_f8()

Datum cube_a_f8_f8 ( PG_FUNCTION_ARGS  )

Definition at line 143 of file cube.c.

144{
147 NDBOX *result;
148 int i;
149 int dim;
150 int size;
151 bool point;
152 double *dur,
153 *dll;
154
157 (errcode(ERRCODE_ARRAY_ELEMENT_ERROR),
158 errmsg("cannot work with arrays containing NULLs")));
159
160 dim = ARRNELEMS(ur);
161 if (dim > CUBE_MAX_DIM)
163 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
164 errmsg("can't extend cube"),
165 errdetail("A cube cannot have more than %d dimensions.",
166 CUBE_MAX_DIM)));
167
168 if (ARRNELEMS(ll) != dim)
170 (errcode(ERRCODE_ARRAY_ELEMENT_ERROR),
171 errmsg("UR and LL arrays must be of same length")));
172
173 dur = ARRPTR(ur);
174 dll = ARRPTR(ll);
175
176 /* Check if it's a point */
177 point = true;
178 for (i = 0; i < dim; i++)
179 {
180 if (dur[i] != dll[i])
181 {
182 point = false;
183 break;
184 }
185 }
186
187 size = point ? POINT_SIZE(dim) : CUBE_SIZE(dim);
188 result = (NDBOX *) palloc0(size);
189 SET_VARSIZE(result, size);
190 SET_DIM(result, dim);
191
192 for (i = 0; i < dim; i++)
193 result->x[i] = dur[i];
194
195 if (!point)
196 {
197 for (i = 0; i < dim; i++)
198 result->x[i + dim] = dll[i];
199 }
200 else
201 SET_POINT_BIT(result);
202
203 PG_RETURN_NDBOX_P(result);
204}
#define CUBE_SIZE(_dim)
Definition: cubedata.h:49
if(TABLE==NULL||TABLE_index==NULL)
Definition: isn.c:81

References array_contains_nulls(), ARRNELEMS, ARRPTR, CUBE_MAX_DIM, CUBE_SIZE, ereport, errcode(), errdetail(), errmsg(), ERROR, i, if(), palloc0(), PG_GETARG_ARRAYTYPE_P, PG_RETURN_NDBOX_P, POINT_SIZE, SET_DIM, SET_POINT_BIT, SET_VARSIZE, and NDBOX::x.

◆ cube_c_f8()

Datum cube_c_f8 ( PG_FUNCTION_ARGS  )

Definition at line 1822 of file cube.c.

1823{
1824 NDBOX *cube = PG_GETARG_NDBOX_P(0);
1825 double x = PG_GETARG_FLOAT8(1);
1826 NDBOX *result;
1827 int size;
1828 int i;
1829
1830 if (DIM(cube) + 1 > CUBE_MAX_DIM)
1831 ereport(ERROR,
1832 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
1833 errmsg("can't extend cube"),
1834 errdetail("A cube cannot have more than %d dimensions.",
1835 CUBE_MAX_DIM)));
1836
1837 if (IS_POINT(cube))
1838 {
1839 size = POINT_SIZE((DIM(cube) + 1));
1840 result = (NDBOX *) palloc0(size);
1841 SET_VARSIZE(result, size);
1842 SET_DIM(result, DIM(cube) + 1);
1843 SET_POINT_BIT(result);
1844 for (i = 0; i < DIM(cube); i++)
1845 result->x[i] = cube->x[i];
1846 result->x[DIM(result) - 1] = x;
1847 }
1848 else
1849 {
1850 size = CUBE_SIZE((DIM(cube) + 1));
1851 result = (NDBOX *) palloc0(size);
1852 SET_VARSIZE(result, size);
1853 SET_DIM(result, DIM(cube) + 1);
1854 for (i = 0; i < DIM(cube); i++)
1855 {
1856 result->x[i] = cube->x[i];
1857 result->x[DIM(result) + i] = cube->x[DIM(cube) + i];
1858 }
1859 result->x[DIM(result) - 1] = x;
1860 result->x[2 * DIM(result) - 1] = x;
1861 }
1862
1863 PG_FREE_IF_COPY(cube, 0);
1864 PG_RETURN_NDBOX_P(result);
1865}
#define IS_POINT(cube)
Definition: cubedata.h:40
#define DIM(cube)
Definition: cubedata.h:42
#define PG_GETARG_NDBOX_P(x)
Definition: cubedata.h:53
#define PG_FREE_IF_COPY(ptr, n)
Definition: fmgr.h:260
#define PG_GETARG_FLOAT8(n)
Definition: fmgr.h:282
int x
Definition: isn.c:75

References CUBE_MAX_DIM, CUBE_SIZE, DIM, ereport, errcode(), errdetail(), errmsg(), ERROR, i, IS_POINT, palloc0(), PG_FREE_IF_COPY, PG_GETARG_FLOAT8, PG_GETARG_NDBOX_P, PG_RETURN_NDBOX_P, POINT_SIZE, SET_DIM, SET_POINT_BIT, SET_VARSIZE, NDBOX::x, and x.

◆ cube_c_f8_f8()

Datum cube_c_f8_f8 ( PG_FUNCTION_ARGS  )

Definition at line 1869 of file cube.c.

1870{
1871 NDBOX *cube = PG_GETARG_NDBOX_P(0);
1872 double x1 = PG_GETARG_FLOAT8(1);
1873 double x2 = PG_GETARG_FLOAT8(2);
1874 NDBOX *result;
1875 int size;
1876 int i;
1877
1878 if (DIM(cube) + 1 > CUBE_MAX_DIM)
1879 ereport(ERROR,
1880 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
1881 errmsg("can't extend cube"),
1882 errdetail("A cube cannot have more than %d dimensions.",
1883 CUBE_MAX_DIM)));
1884
1885 if (IS_POINT(cube) && (x1 == x2))
1886 {
1887 size = POINT_SIZE((DIM(cube) + 1));
1888 result = (NDBOX *) palloc0(size);
1889 SET_VARSIZE(result, size);
1890 SET_DIM(result, DIM(cube) + 1);
1891 SET_POINT_BIT(result);
1892 for (i = 0; i < DIM(cube); i++)
1893 result->x[i] = cube->x[i];
1894 result->x[DIM(result) - 1] = x1;
1895 }
1896 else
1897 {
1898 size = CUBE_SIZE((DIM(cube) + 1));
1899 result = (NDBOX *) palloc0(size);
1900 SET_VARSIZE(result, size);
1901 SET_DIM(result, DIM(cube) + 1);
1902 for (i = 0; i < DIM(cube); i++)
1903 {
1904 result->x[i] = LL_COORD(cube, i);
1905 result->x[DIM(result) + i] = UR_COORD(cube, i);
1906 }
1907 result->x[DIM(result) - 1] = x1;
1908 result->x[2 * DIM(result) - 1] = x2;
1909 }
1910
1911 PG_FREE_IF_COPY(cube, 0);
1912 PG_RETURN_NDBOX_P(result);
1913}
#define LL_COORD(cube, i)
Definition: cubedata.h:45
#define UR_COORD(cube, i)
Definition: cubedata.h:46

References CUBE_MAX_DIM, CUBE_SIZE, DIM, ereport, errcode(), errdetail(), errmsg(), ERROR, i, IS_POINT, LL_COORD, palloc0(), PG_FREE_IF_COPY, PG_GETARG_FLOAT8, PG_GETARG_NDBOX_P, PG_RETURN_NDBOX_P, POINT_SIZE, SET_DIM, SET_POINT_BIT, SET_VARSIZE, UR_COORD, and NDBOX::x.

◆ cube_cmp()

Datum cube_cmp ( PG_FUNCTION_ARGS  )

Definition at line 1021 of file cube.c.

1022{
1024 *b = PG_GETARG_NDBOX_P(1);
1025 int32 res;
1026
1027 res = cube_cmp_v0(a, b);
1028
1029 PG_FREE_IF_COPY(a, 0);
1030 PG_FREE_IF_COPY(b, 1);
1031 PG_RETURN_INT32(res);
1032}
int32_t int32
Definition: c.h:498
int32 cube_cmp_v0(NDBOX *a, NDBOX *b)
Definition: cube.c:941
#define PG_RETURN_INT32(x)
Definition: fmgr.h:354
int b
Definition: isn.c:74
int a
Definition: isn.c:73

References a, b, cube_cmp_v0(), PG_FREE_IF_COPY, PG_GETARG_NDBOX_P, and PG_RETURN_INT32.

◆ cube_cmp_v0()

int32 cube_cmp_v0 ( NDBOX a,
NDBOX b 
)

Definition at line 941 of file cube.c.

942{
943 int i;
944 int dim;
945
946 dim = Min(DIM(a), DIM(b));
947
948 /* compare the common dimensions */
949 for (i = 0; i < dim; i++)
950 {
951 if (Min(LL_COORD(a, i), UR_COORD(a, i)) >
952 Min(LL_COORD(b, i), UR_COORD(b, i)))
953 return 1;
954 if (Min(LL_COORD(a, i), UR_COORD(a, i)) <
955 Min(LL_COORD(b, i), UR_COORD(b, i)))
956 return -1;
957 }
958 for (i = 0; i < dim; i++)
959 {
960 if (Max(LL_COORD(a, i), UR_COORD(a, i)) >
961 Max(LL_COORD(b, i), UR_COORD(b, i)))
962 return 1;
963 if (Max(LL_COORD(a, i), UR_COORD(a, i)) <
964 Max(LL_COORD(b, i), UR_COORD(b, i)))
965 return -1;
966 }
967
968 /* compare extra dimensions to zero */
969 if (DIM(a) > DIM(b))
970 {
971 for (i = dim; i < DIM(a); i++)
972 {
973 if (Min(LL_COORD(a, i), UR_COORD(a, i)) > 0)
974 return 1;
975 if (Min(LL_COORD(a, i), UR_COORD(a, i)) < 0)
976 return -1;
977 }
978 for (i = dim; i < DIM(a); i++)
979 {
980 if (Max(LL_COORD(a, i), UR_COORD(a, i)) > 0)
981 return 1;
982 if (Max(LL_COORD(a, i), UR_COORD(a, i)) < 0)
983 return -1;
984 }
985
986 /*
987 * if all common dimensions are equal, the cube with more dimensions
988 * wins
989 */
990 return 1;
991 }
992 if (DIM(a) < DIM(b))
993 {
994 for (i = dim; i < DIM(b); i++)
995 {
996 if (Min(LL_COORD(b, i), UR_COORD(b, i)) > 0)
997 return -1;
998 if (Min(LL_COORD(b, i), UR_COORD(b, i)) < 0)
999 return 1;
1000 }
1001 for (i = dim; i < DIM(b); i++)
1002 {
1003 if (Max(LL_COORD(b, i), UR_COORD(b, i)) > 0)
1004 return -1;
1005 if (Max(LL_COORD(b, i), UR_COORD(b, i)) < 0)
1006 return 1;
1007 }
1008
1009 /*
1010 * if all common dimensions are equal, the cube with more dimensions
1011 * wins
1012 */
1013 return -1;
1014 }
1015
1016 /* They're really equal */
1017 return 0;
1018}
#define Min(x, y)
Definition: c.h:975
#define Max(x, y)
Definition: c.h:969

References a, b, DIM, i, LL_COORD, Max, Min, and UR_COORD.

Referenced by cube_cmp(), cube_eq(), cube_ge(), cube_gt(), cube_le(), cube_lt(), cube_ne(), g_cube_leaf_consistent(), and g_cube_same().

◆ cube_contained()

Datum cube_contained ( PG_FUNCTION_ARGS  )

Definition at line 1182 of file cube.c.

1183{
1185 *b = PG_GETARG_NDBOX_P(1);
1186 bool res;
1187
1188 res = cube_contains_v0(b, a);
1189
1190 PG_FREE_IF_COPY(a, 0);
1191 PG_FREE_IF_COPY(b, 1);
1192 PG_RETURN_BOOL(res);
1193}
bool cube_contains_v0(NDBOX *a, NDBOX *b)
Definition: cube.c:1128
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359

References a, b, cube_contains_v0(), PG_FREE_IF_COPY, PG_GETARG_NDBOX_P, and PG_RETURN_BOOL.

◆ cube_contains()

Datum cube_contains ( PG_FUNCTION_ARGS  )

Definition at line 1166 of file cube.c.

1167{
1169 *b = PG_GETARG_NDBOX_P(1);
1170 bool res;
1171
1172 res = cube_contains_v0(a, b);
1173
1174 PG_FREE_IF_COPY(a, 0);
1175 PG_FREE_IF_COPY(b, 1);
1176 PG_RETURN_BOOL(res);
1177}

References a, b, cube_contains_v0(), PG_FREE_IF_COPY, PG_GETARG_NDBOX_P, and PG_RETURN_BOOL.

◆ cube_contains_v0()

bool cube_contains_v0 ( NDBOX a,
NDBOX b 
)

Definition at line 1128 of file cube.c.

1129{
1130 int i;
1131
1132 if ((a == NULL) || (b == NULL))
1133 return false;
1134
1135 if (DIM(a) < DIM(b))
1136 {
1137 /*
1138 * the further comparisons will make sense if the excess dimensions of
1139 * (b) were zeroes Since both UL and UR coordinates must be zero, we
1140 * can check them all without worrying about which is which.
1141 */
1142 for (i = DIM(a); i < DIM(b); i++)
1143 {
1144 if (LL_COORD(b, i) != 0)
1145 return false;
1146 if (UR_COORD(b, i) != 0)
1147 return false;
1148 }
1149 }
1150
1151 /* Can't care less about the excess dimensions of (a), if any */
1152 for (i = 0; i < Min(DIM(a), DIM(b)); i++)
1153 {
1154 if (Min(LL_COORD(a, i), UR_COORD(a, i)) >
1155 Min(LL_COORD(b, i), UR_COORD(b, i)))
1156 return false;
1157 if (Max(LL_COORD(a, i), UR_COORD(a, i)) <
1158 Max(LL_COORD(b, i), UR_COORD(b, i)))
1159 return false;
1160 }
1161
1162 return true;
1163}

References a, b, DIM, i, LL_COORD, Max, Min, and UR_COORD.

Referenced by cube_contained(), cube_contains(), g_cube_internal_consistent(), and g_cube_leaf_consistent().

◆ cube_coord()

Datum cube_coord ( PG_FUNCTION_ARGS  )

Definition at line 1607 of file cube.c.

1608{
1609 NDBOX *cube = PG_GETARG_NDBOX_P(0);
1610 int coord = PG_GETARG_INT32(1);
1611
1612 if (coord <= 0 || coord > 2 * DIM(cube))
1613 ereport(ERROR,
1614 (errcode(ERRCODE_ARRAY_ELEMENT_ERROR),
1615 errmsg("cube index %d is out of bounds", coord)));
1616
1617 if (IS_POINT(cube))
1618 PG_RETURN_FLOAT8(cube->x[(coord - 1) % DIM(cube)]);
1619 else
1620 PG_RETURN_FLOAT8(cube->x[coord - 1]);
1621}
#define PG_RETURN_FLOAT8(x)
Definition: fmgr.h:367
#define PG_GETARG_INT32(n)
Definition: fmgr.h:269

References DIM, ereport, errcode(), errmsg(), ERROR, IS_POINT, PG_GETARG_INT32, PG_GETARG_NDBOX_P, PG_RETURN_FLOAT8, and NDBOX::x.

◆ cube_coord_llur()

Datum cube_coord_llur ( PG_FUNCTION_ARGS  )

Definition at line 1648 of file cube.c.

1649{
1650 NDBOX *cube = PG_GETARG_NDBOX_P(0);
1651 int coord = PG_GETARG_INT32(1);
1652 bool inverse = false;
1653 float8 result;
1654
1655 /* 0 is the only unsupported coordinate value */
1656 if (coord == 0)
1657 ereport(ERROR,
1658 (errcode(ERRCODE_ARRAY_ELEMENT_ERROR),
1659 errmsg("zero cube index is not defined")));
1660
1661 /* Return inversed value for negative coordinate */
1662 if (coord < 0)
1663 {
1664 coord = -coord;
1665 inverse = true;
1666 }
1667
1668 if (coord <= 2 * DIM(cube))
1669 {
1670 /* dimension index */
1671 int index = (coord - 1) / 2;
1672
1673 /* whether this is upper bound (lower bound otherwise) */
1674 bool upper = ((coord - 1) % 2 == 1);
1675
1676 if (IS_POINT(cube))
1677 {
1678 result = cube->x[index];
1679 }
1680 else
1681 {
1682 if (upper)
1683 result = Max(cube->x[index], cube->x[index + DIM(cube)]);
1684 else
1685 result = Min(cube->x[index], cube->x[index + DIM(cube)]);
1686 }
1687 }
1688 else
1689 {
1690 /*
1691 * Return zero if coordinate is out of bound. That reproduces logic
1692 * of how cubes with low dimension number are expanded during GiST
1693 * indexing.
1694 */
1695 result = 0.0;
1696 }
1697
1698 /* Inverse value if needed */
1699 if (inverse)
1700 result = -result;
1701
1702 PG_RETURN_FLOAT8(result);
1703}
double float8
Definition: c.h:601
Datum upper(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:80
Definition: type.h:96

References DIM, ereport, errcode(), errmsg(), ERROR, IS_POINT, Max, Min, PG_GETARG_INT32, PG_GETARG_NDBOX_P, PG_RETURN_FLOAT8, upper(), and NDBOX::x.

◆ cube_dim()

Datum cube_dim ( PG_FUNCTION_ARGS  )

Definition at line 1558 of file cube.c.

1559{
1561 int dim = DIM(c);
1562
1563 PG_FREE_IF_COPY(c, 0);
1564 PG_RETURN_INT32(dim);
1565}
char * c

References DIM, PG_FREE_IF_COPY, PG_GETARG_NDBOX_P, and PG_RETURN_INT32.

◆ cube_distance()

Datum cube_distance ( PG_FUNCTION_ARGS  )

Definition at line 1257 of file cube.c.

1258{
1260 *b = PG_GETARG_NDBOX_P(1);
1261 bool swapped = false;
1262 double d,
1263 distance;
1264 int i;
1265
1266 /* swap the box pointers if needed */
1267 if (DIM(a) < DIM(b))
1268 {
1269 NDBOX *tmp = b;
1270
1271 b = a;
1272 a = tmp;
1273 swapped = true;
1274 }
1275
1276 distance = 0.0;
1277 /* compute within the dimensions of (b) */
1278 for (i = 0; i < DIM(b); i++)
1279 {
1280 d = distance_1D(LL_COORD(a, i), UR_COORD(a, i), LL_COORD(b, i), UR_COORD(b, i));
1281 distance += d * d;
1282 }
1283
1284 /* compute distance to zero for those dimensions in (a) absent in (b) */
1285 for (i = DIM(b); i < DIM(a); i++)
1286 {
1287 d = distance_1D(LL_COORD(a, i), UR_COORD(a, i), 0.0, 0.0);
1288 distance += d * d;
1289 }
1290
1291 if (swapped)
1292 {
1293 PG_FREE_IF_COPY(b, 0);
1294 PG_FREE_IF_COPY(a, 1);
1295 }
1296 else
1297 {
1298 PG_FREE_IF_COPY(a, 0);
1299 PG_FREE_IF_COPY(b, 1);
1300 }
1301
1302 PG_RETURN_FLOAT8(sqrt(distance));
1303}
static double distance_1D(double a1, double a2, double b1, double b2)
Definition: cube.c:1507

References a, b, DIM, distance_1D(), i, LL_COORD, PG_FREE_IF_COPY, PG_GETARG_NDBOX_P, PG_RETURN_FLOAT8, and UR_COORD.

Referenced by g_cube_distance().

◆ cube_enlarge()

Datum cube_enlarge ( PG_FUNCTION_ARGS  )

Definition at line 1707 of file cube.c.

1708{
1710 double r = PG_GETARG_FLOAT8(1);
1711 int32 n = PG_GETARG_INT32(2);
1712 NDBOX *result;
1713 int dim = 0;
1714 int size;
1715 int i,
1716 j;
1717
1718 if (n > CUBE_MAX_DIM)
1719 n = CUBE_MAX_DIM;
1720 if (r > 0 && n > 0)
1721 dim = n;
1722 if (DIM(a) > dim)
1723 dim = DIM(a);
1724
1725 size = CUBE_SIZE(dim);
1726 result = (NDBOX *) palloc0(size);
1727 SET_VARSIZE(result, size);
1728 SET_DIM(result, dim);
1729
1730 for (i = 0, j = dim; i < DIM(a); i++, j++)
1731 {
1732 if (LL_COORD(a, i) >= UR_COORD(a, i))
1733 {
1734 result->x[i] = UR_COORD(a, i) - r;
1735 result->x[j] = LL_COORD(a, i) + r;
1736 }
1737 else
1738 {
1739 result->x[i] = LL_COORD(a, i) - r;
1740 result->x[j] = UR_COORD(a, i) + r;
1741 }
1742 if (result->x[i] > result->x[j])
1743 {
1744 result->x[i] = (result->x[i] + result->x[j]) / 2;
1745 result->x[j] = result->x[i];
1746 }
1747 }
1748 /* dim > a->dim only if r > 0 */
1749 for (; i < dim; i++, j++)
1750 {
1751 result->x[i] = -r;
1752 result->x[j] = r;
1753 }
1754
1755 /*
1756 * Check if the result was in fact a point, and set the flag in the datum
1757 * accordingly. (we don't bother to repalloc it smaller)
1758 */
1759 if (cube_is_point_internal(result))
1760 {
1761 size = POINT_SIZE(dim);
1762 SET_VARSIZE(result, size);
1763 SET_POINT_BIT(result);
1764 }
1765
1766 PG_FREE_IF_COPY(a, 0);
1767 PG_RETURN_NDBOX_P(result);
1768}
static bool cube_is_point_internal(NDBOX *cube)
Definition: cube.c:1534
int j
Definition: isn.c:78

References a, cube_is_point_internal(), CUBE_MAX_DIM, CUBE_SIZE, DIM, i, j, LL_COORD, palloc0(), PG_FREE_IF_COPY, PG_GETARG_FLOAT8, PG_GETARG_INT32, PG_GETARG_NDBOX_P, PG_RETURN_NDBOX_P, POINT_SIZE, SET_DIM, SET_POINT_BIT, SET_VARSIZE, UR_COORD, and NDBOX::x.

◆ cube_eq()

Datum cube_eq ( PG_FUNCTION_ARGS  )

Definition at line 1036 of file cube.c.

1037{
1039 *b = PG_GETARG_NDBOX_P(1);
1040 int32 res;
1041
1042 res = cube_cmp_v0(a, b);
1043
1044 PG_FREE_IF_COPY(a, 0);
1045 PG_FREE_IF_COPY(b, 1);
1046 PG_RETURN_BOOL(res == 0);
1047}

References a, b, cube_cmp_v0(), PG_FREE_IF_COPY, PG_GETARG_NDBOX_P, and PG_RETURN_BOOL.

◆ cube_f8()

Datum cube_f8 ( PG_FUNCTION_ARGS  )

Definition at line 1772 of file cube.c.

1773{
1774 double x = PG_GETARG_FLOAT8(0);
1775 NDBOX *result;
1776 int size;
1777
1778 size = POINT_SIZE(1);
1779 result = (NDBOX *) palloc0(size);
1780 SET_VARSIZE(result, size);
1781 SET_DIM(result, 1);
1782 SET_POINT_BIT(result);
1783 result->x[0] = x;
1784
1785 PG_RETURN_NDBOX_P(result);
1786}

References palloc0(), PG_GETARG_FLOAT8, PG_RETURN_NDBOX_P, POINT_SIZE, SET_DIM, SET_POINT_BIT, SET_VARSIZE, NDBOX::x, and x.

◆ cube_f8_f8()

Datum cube_f8_f8 ( PG_FUNCTION_ARGS  )

Definition at line 1790 of file cube.c.

1791{
1792 double x0 = PG_GETARG_FLOAT8(0);
1793 double x1 = PG_GETARG_FLOAT8(1);
1794 NDBOX *result;
1795 int size;
1796
1797 if (x0 == x1)
1798 {
1799 size = POINT_SIZE(1);
1800 result = (NDBOX *) palloc0(size);
1801 SET_VARSIZE(result, size);
1802 SET_DIM(result, 1);
1803 SET_POINT_BIT(result);
1804 result->x[0] = x0;
1805 }
1806 else
1807 {
1808 size = CUBE_SIZE(1);
1809 result = (NDBOX *) palloc0(size);
1810 SET_VARSIZE(result, size);
1811 SET_DIM(result, 1);
1812 result->x[0] = x0;
1813 result->x[1] = x1;
1814 }
1815
1816 PG_RETURN_NDBOX_P(result);
1817}

References CUBE_SIZE, palloc0(), PG_GETARG_FLOAT8, PG_RETURN_NDBOX_P, POINT_SIZE, SET_DIM, SET_POINT_BIT, SET_VARSIZE, and NDBOX::x.

◆ cube_ge()

Datum cube_ge ( PG_FUNCTION_ARGS  )

Definition at line 1111 of file cube.c.

1112{
1114 *b = PG_GETARG_NDBOX_P(1);
1115 int32 res;
1116
1117 res = cube_cmp_v0(a, b);
1118
1119 PG_FREE_IF_COPY(a, 0);
1120 PG_FREE_IF_COPY(b, 1);
1121 PG_RETURN_BOOL(res >= 0);
1122}

References a, b, cube_cmp_v0(), PG_FREE_IF_COPY, PG_GETARG_NDBOX_P, and PG_RETURN_BOOL.

◆ cube_gt()

Datum cube_gt ( PG_FUNCTION_ARGS  )

Definition at line 1081 of file cube.c.

1082{
1084 *b = PG_GETARG_NDBOX_P(1);
1085 int32 res;
1086
1087 res = cube_cmp_v0(a, b);
1088
1089 PG_FREE_IF_COPY(a, 0);
1090 PG_FREE_IF_COPY(b, 1);
1091 PG_RETURN_BOOL(res > 0);
1092}

References a, b, cube_cmp_v0(), PG_FREE_IF_COPY, PG_GETARG_NDBOX_P, and PG_RETURN_BOOL.

◆ cube_in()

Datum cube_in ( PG_FUNCTION_ARGS  )

Definition at line 121 of file cube.c.

122{
123 char *str = PG_GETARG_CSTRING(0);
124 NDBOX *result;
125 Size scanbuflen;
126 yyscan_t scanner;
127
128 cube_scanner_init(str, &scanbuflen, &scanner);
129
130 cube_yyparse(&result, scanbuflen, fcinfo->context, scanner);
131
132 /* We might as well run this even on failure. */
133 cube_scanner_finish(scanner);
134
135 PG_RETURN_NDBOX_P(result);
136}
size_t Size
Definition: c.h:576
int cube_yyparse(NDBOX **result, Size scanbuflen, struct Node *escontext, yyscan_t yyscanner)
void cube_scanner_init(const char *str, Size *scanbuflen, yyscan_t *yyscannerp)
Definition: cubescan.l:102
void * yyscan_t
Definition: cubedata.h:67
void cube_scanner_finish(yyscan_t yyscanner)
Definition: cubescan.l:121
#define PG_GETARG_CSTRING(n)
Definition: fmgr.h:277
const char * str

References cube_scanner_finish(), cube_scanner_init(), cube_yyparse(), PG_GETARG_CSTRING, PG_RETURN_NDBOX_P, and str.

◆ cube_inter()

Datum cube_inter ( PG_FUNCTION_ARGS  )

Definition at line 827 of file cube.c.

828{
831 NDBOX *result;
832 bool swapped = false;
833 int i;
834 int dim;
835 int size;
836
837 /* swap the arguments if needed, so that 'a' is always larger than 'b' */
838 if (DIM(a) < DIM(b))
839 {
840 NDBOX *tmp = b;
841
842 b = a;
843 a = tmp;
844 swapped = true;
845 }
846 dim = DIM(a);
847
848 size = CUBE_SIZE(dim);
849 result = (NDBOX *) palloc0(size);
850 SET_VARSIZE(result, size);
851 SET_DIM(result, dim);
852
853 /* First compute intersection of the dimensions present in both args */
854 for (i = 0; i < DIM(b); i++)
855 {
856 result->x[i] = Max(Min(LL_COORD(a, i), UR_COORD(a, i)),
857 Min(LL_COORD(b, i), UR_COORD(b, i)));
858 result->x[i + DIM(a)] = Min(Max(LL_COORD(a, i), UR_COORD(a, i)),
859 Max(LL_COORD(b, i), UR_COORD(b, i)));
860 }
861 /* continue on the higher dimensions only present in 'a' */
862 for (; i < DIM(a); i++)
863 {
864 result->x[i] = Max(0,
865 Min(LL_COORD(a, i), UR_COORD(a, i))
866 );
867 result->x[i + DIM(a)] = Min(0,
868 Max(LL_COORD(a, i), UR_COORD(a, i))
869 );
870 }
871
872 /*
873 * Check if the result was in fact a point, and set the flag in the datum
874 * accordingly. (we don't bother to repalloc it smaller)
875 */
876 if (cube_is_point_internal(result))
877 {
878 size = POINT_SIZE(dim);
879 result = repalloc(result, size);
880 SET_VARSIZE(result, size);
881 SET_POINT_BIT(result);
882 }
883
884 if (swapped)
885 {
886 PG_FREE_IF_COPY(b, 0);
887 PG_FREE_IF_COPY(a, 1);
888 }
889 else
890 {
891 PG_FREE_IF_COPY(a, 0);
892 PG_FREE_IF_COPY(b, 1);
893 }
894
895 /*
896 * Is it OK to return a non-null intersection for non-overlapping boxes?
897 */
898 PG_RETURN_NDBOX_P(result);
899}
void * repalloc(void *pointer, Size size)
Definition: mcxt.c:2167

References a, b, cube_is_point_internal(), CUBE_SIZE, DIM, i, LL_COORD, Max, Min, palloc0(), PG_FREE_IF_COPY, PG_GETARG_NDBOX_P, PG_RETURN_NDBOX_P, POINT_SIZE, repalloc(), SET_DIM, SET_POINT_BIT, SET_VARSIZE, UR_COORD, and NDBOX::x.

Referenced by g_cube_picksplit().

◆ cube_is_point()

Datum cube_is_point ( PG_FUNCTION_ARGS  )

Definition at line 1523 of file cube.c.

1524{
1525 NDBOX *cube = PG_GETARG_NDBOX_P(0);
1526 bool result;
1527
1528 result = cube_is_point_internal(cube);
1529 PG_FREE_IF_COPY(cube, 0);
1530 PG_RETURN_BOOL(result);
1531}

References cube_is_point_internal(), PG_FREE_IF_COPY, PG_GETARG_NDBOX_P, and PG_RETURN_BOOL.

◆ cube_is_point_internal()

static bool cube_is_point_internal ( NDBOX cube)
static

Definition at line 1534 of file cube.c.

1535{
1536 int i;
1537
1538 if (IS_POINT(cube))
1539 return true;
1540
1541 /*
1542 * Even if the point-flag is not set, all the lower-left coordinates might
1543 * match the upper-right coordinates, so that the value is in fact a
1544 * point. Such values don't arise with current code - the point flag is
1545 * always set if appropriate - but they might be present on-disk in
1546 * clusters upgraded from pre-9.4 versions.
1547 */
1548 for (i = 0; i < DIM(cube); i++)
1549 {
1550 if (LL_COORD(cube, i) != UR_COORD(cube, i))
1551 return false;
1552 }
1553 return true;
1554}

References DIM, i, IS_POINT, LL_COORD, and UR_COORD.

Referenced by cube_enlarge(), cube_inter(), cube_is_point(), cube_out(), and cube_union_v0().

◆ cube_le()

Datum cube_le ( PG_FUNCTION_ARGS  )

Definition at line 1096 of file cube.c.

1097{
1099 *b = PG_GETARG_NDBOX_P(1);
1100 int32 res;
1101
1102 res = cube_cmp_v0(a, b);
1103
1104 PG_FREE_IF_COPY(a, 0);
1105 PG_FREE_IF_COPY(b, 1);
1106 PG_RETURN_BOOL(res <= 0);
1107}

References a, b, cube_cmp_v0(), PG_FREE_IF_COPY, PG_GETARG_NDBOX_P, and PG_RETURN_BOOL.

◆ cube_ll_coord()

Datum cube_ll_coord ( PG_FUNCTION_ARGS  )

Definition at line 1569 of file cube.c.

1570{
1572 int n = PG_GETARG_INT32(1);
1573 double result;
1574
1575 if (DIM(c) >= n && n > 0)
1576 result = Min(LL_COORD(c, n - 1), UR_COORD(c, n - 1));
1577 else
1578 result = 0;
1579
1580 PG_FREE_IF_COPY(c, 0);
1581 PG_RETURN_FLOAT8(result);
1582}

References DIM, LL_COORD, Min, PG_FREE_IF_COPY, PG_GETARG_INT32, PG_GETARG_NDBOX_P, PG_RETURN_FLOAT8, and UR_COORD.

◆ cube_lt()

Datum cube_lt ( PG_FUNCTION_ARGS  )

Definition at line 1066 of file cube.c.

1067{
1069 *b = PG_GETARG_NDBOX_P(1);
1070 int32 res;
1071
1072 res = cube_cmp_v0(a, b);
1073
1074 PG_FREE_IF_COPY(a, 0);
1075 PG_FREE_IF_COPY(b, 1);
1076 PG_RETURN_BOOL(res < 0);
1077}

References a, b, cube_cmp_v0(), PG_FREE_IF_COPY, PG_GETARG_NDBOX_P, and PG_RETURN_BOOL.

◆ cube_ne()

Datum cube_ne ( PG_FUNCTION_ARGS  )

Definition at line 1051 of file cube.c.

1052{
1054 *b = PG_GETARG_NDBOX_P(1);
1055 int32 res;
1056
1057 res = cube_cmp_v0(a, b);
1058
1059 PG_FREE_IF_COPY(a, 0);
1060 PG_FREE_IF_COPY(b, 1);
1061 PG_RETURN_BOOL(res != 0);
1062}

References a, b, cube_cmp_v0(), PG_FREE_IF_COPY, PG_GETARG_NDBOX_P, and PG_RETURN_BOOL.

◆ cube_out()

Datum cube_out ( PG_FUNCTION_ARGS  )

Definition at line 296 of file cube.c.

297{
298 NDBOX *cube = PG_GETARG_NDBOX_P(0);
300 int dim = DIM(cube);
301 int i;
302
304
306 for (i = 0; i < dim; i++)
307 {
308 if (i > 0)
311 }
313
314 if (!cube_is_point_internal(cube))
315 {
317 for (i = 0; i < dim; i++)
318 {
319 if (i > 0)
322 }
324 }
325
326 PG_FREE_IF_COPY(cube, 0);
328}
char * float8out_internal(double num)
Definition: float.c:537
#define PG_RETURN_CSTRING(x)
Definition: fmgr.h:362
static char * buf
Definition: pg_test_fsync.c:72
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:230
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:242
void initStringInfo(StringInfo str)
Definition: stringinfo.c:97

References appendStringInfoChar(), appendStringInfoString(), buf, cube_is_point_internal(), DIM, float8out_internal(), i, initStringInfo(), LL_COORD, PG_FREE_IF_COPY, PG_GETARG_NDBOX_P, PG_RETURN_CSTRING, and UR_COORD.

◆ cube_overlap()

Datum cube_overlap ( PG_FUNCTION_ARGS  )

Definition at line 1237 of file cube.c.

1238{
1240 *b = PG_GETARG_NDBOX_P(1);
1241 bool res;
1242
1243 res = cube_overlap_v0(a, b);
1244
1245 PG_FREE_IF_COPY(a, 0);
1246 PG_FREE_IF_COPY(b, 1);
1247 PG_RETURN_BOOL(res);
1248}
bool cube_overlap_v0(NDBOX *a, NDBOX *b)
Definition: cube.c:1198

References a, b, cube_overlap_v0(), PG_FREE_IF_COPY, PG_GETARG_NDBOX_P, and PG_RETURN_BOOL.

◆ cube_overlap_v0()

bool cube_overlap_v0 ( NDBOX a,
NDBOX b 
)

Definition at line 1198 of file cube.c.

1199{
1200 int i;
1201
1202 if ((a == NULL) || (b == NULL))
1203 return false;
1204
1205 /* swap the box pointers if needed */
1206 if (DIM(a) < DIM(b))
1207 {
1208 NDBOX *tmp = b;
1209
1210 b = a;
1211 a = tmp;
1212 }
1213
1214 /* compare within the dimensions of (b) */
1215 for (i = 0; i < DIM(b); i++)
1216 {
1217 if (Min(LL_COORD(a, i), UR_COORD(a, i)) > Max(LL_COORD(b, i), UR_COORD(b, i)))
1218 return false;
1219 if (Max(LL_COORD(a, i), UR_COORD(a, i)) < Min(LL_COORD(b, i), UR_COORD(b, i)))
1220 return false;
1221 }
1222
1223 /* compare to zero those dimensions in (a) absent in (b) */
1224 for (i = DIM(b); i < DIM(a); i++)
1225 {
1226 if (Min(LL_COORD(a, i), UR_COORD(a, i)) > 0)
1227 return false;
1228 if (Max(LL_COORD(a, i), UR_COORD(a, i)) < 0)
1229 return false;
1230 }
1231
1232 return true;
1233}

References a, b, DIM, i, LL_COORD, Max, Min, and UR_COORD.

Referenced by cube_overlap(), g_cube_internal_consistent(), and g_cube_leaf_consistent().

◆ cube_recv()

Datum cube_recv ( PG_FUNCTION_ARGS  )

Definition at line 356 of file cube.c.

357{
359 int32 header;
360 int32 i,
361 nitems;
362 NDBOX *cube;
363
364 header = pq_getmsgint(buf, sizeof(int32));
365 nitems = (header & DIM_MASK);
366 if (nitems > CUBE_MAX_DIM)
368 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
369 errmsg("cube dimension is too large"),
370 errdetail("A cube cannot have more than %d dimensions.",
371 CUBE_MAX_DIM)));
372 if ((header & POINT_BIT) == 0)
373 nitems += nitems;
374 cube = palloc(offsetof(NDBOX, x) + sizeof(double) * nitems);
375 SET_VARSIZE(cube, offsetof(NDBOX, x) + sizeof(double) * nitems);
376 cube->header = header;
377 for (i = 0; i < nitems; i++)
378 cube->x[i] = pq_getmsgfloat8(buf);
379
380 PG_RETURN_NDBOX_P(cube);
381}
#define DIM_MASK
Definition: cubedata.h:38
#define POINT_BIT
Definition: cubedata.h:37
#define PG_GETARG_POINTER(n)
Definition: fmgr.h:276
#define nitems(x)
Definition: indent.h:31
void * palloc(Size size)
Definition: mcxt.c:1940
unsigned int pq_getmsgint(StringInfo msg, int b)
Definition: pqformat.c:415
float8 pq_getmsgfloat8(StringInfo msg)
Definition: pqformat.c:488
StringInfoData * StringInfo
Definition: stringinfo.h:54
unsigned int header
Definition: cubedata.h:27

References buf, CUBE_MAX_DIM, DIM_MASK, ereport, errcode(), errdetail(), errmsg(), ERROR, NDBOX::header, i, nitems, palloc(), PG_GETARG_POINTER, PG_RETURN_NDBOX_P, POINT_BIT, pq_getmsgfloat8(), pq_getmsgint(), SET_VARSIZE, NDBOX::x, and x.

◆ cube_send()

Datum cube_send ( PG_FUNCTION_ARGS  )

Definition at line 334 of file cube.c.

335{
336 NDBOX *cube = PG_GETARG_NDBOX_P(0);
338 int32 i,
339 nitems = DIM(cube);
340
342 pq_sendint32(&buf, cube->header);
343 if (!IS_POINT(cube))
344 nitems += nitems;
345 /* for symmetry with cube_recv, we don't use LL_COORD/UR_COORD here */
346 for (i = 0; i < nitems; i++)
347 pq_sendfloat8(&buf, cube->x[i]);
348
350}
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:371
void pq_begintypsend(StringInfo buf)
Definition: pqformat.c:326
bytea * pq_endtypsend(StringInfo buf)
Definition: pqformat.c:346
void pq_sendfloat8(StringInfo buf, float8 f)
Definition: pqformat.c:276
static void pq_sendint32(StringInfo buf, uint32 i)
Definition: pqformat.h:144

References buf, DIM, NDBOX::header, i, IS_POINT, nitems, PG_GETARG_NDBOX_P, PG_RETURN_BYTEA_P, pq_begintypsend(), pq_endtypsend(), pq_sendfloat8(), pq_sendint32(), and NDBOX::x.

◆ cube_size()

Datum cube_size ( PG_FUNCTION_ARGS  )

Definition at line 903 of file cube.c.

904{
906 double result;
907
908 rt_cube_size(a, &result);
909 PG_FREE_IF_COPY(a, 0);
910 PG_RETURN_FLOAT8(result);
911}
void rt_cube_size(NDBOX *a, double *size)
Definition: cube.c:914

References a, PG_FREE_IF_COPY, PG_GETARG_NDBOX_P, PG_RETURN_FLOAT8, and rt_cube_size().

◆ cube_subset()

Datum cube_subset ( PG_FUNCTION_ARGS  )

Definition at line 247 of file cube.c.

248{
251 NDBOX *result;
252 int size,
253 dim,
254 i;
255 int *dx;
256
259 (errcode(ERRCODE_ARRAY_ELEMENT_ERROR),
260 errmsg("cannot work with arrays containing NULLs")));
261
262 dx = (int32 *) ARR_DATA_PTR(idx);
263
264 dim = ARRNELEMS(idx);
265 if (dim > CUBE_MAX_DIM)
267 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
268 errmsg("array is too long"),
269 errdetail("A cube cannot have more than %d dimensions.",
270 CUBE_MAX_DIM)));
271
272 size = IS_POINT(c) ? POINT_SIZE(dim) : CUBE_SIZE(dim);
273 result = (NDBOX *) palloc0(size);
274 SET_VARSIZE(result, size);
275 SET_DIM(result, dim);
276
277 if (IS_POINT(c))
278 SET_POINT_BIT(result);
279
280 for (i = 0; i < dim; i++)
281 {
282 if ((dx[i] <= 0) || (dx[i] > DIM(c)))
284 (errcode(ERRCODE_ARRAY_ELEMENT_ERROR),
285 errmsg("Index out of bounds")));
286 result->x[i] = c->x[dx[i] - 1];
287 if (!IS_POINT(c))
288 result->x[i + dim] = c->x[dx[i] + DIM(c) - 1];
289 }
290
291 PG_FREE_IF_COPY(c, 0);
292 PG_RETURN_NDBOX_P(result);
293}
Datum idx(PG_FUNCTION_ARGS)
Definition: _int_op.c:262
#define ARR_DATA_PTR(a)
Definition: array.h:322

References ARR_DATA_PTR, array_contains_nulls(), ARRNELEMS, CUBE_MAX_DIM, CUBE_SIZE, DIM, ereport, errcode(), errdetail(), errmsg(), ERROR, i, idx(), IS_POINT, palloc0(), PG_FREE_IF_COPY, PG_GETARG_ARRAYTYPE_P, PG_GETARG_NDBOX_P, PG_RETURN_NDBOX_P, POINT_SIZE, SET_DIM, SET_POINT_BIT, SET_VARSIZE, and NDBOX::x.

◆ cube_union()

Datum cube_union ( PG_FUNCTION_ARGS  )

Definition at line 812 of file cube.c.

813{
816 NDBOX *res;
817
818 res = cube_union_v0(a, b);
819
820 PG_FREE_IF_COPY(a, 0);
821 PG_FREE_IF_COPY(b, 1);
823}
NDBOX * cube_union_v0(NDBOX *a, NDBOX *b)
Definition: cube.c:752

References a, b, cube_union_v0(), PG_FREE_IF_COPY, PG_GETARG_NDBOX_P, and PG_RETURN_NDBOX_P.

◆ cube_union_v0()

NDBOX * cube_union_v0 ( NDBOX a,
NDBOX b 
)

Definition at line 752 of file cube.c.

753{
754 int i;
755 NDBOX *result;
756 int dim;
757 int size;
758
759 /* trivial case */
760 if (a == b)
761 return a;
762
763 /* swap the arguments if needed, so that 'a' is always larger than 'b' */
764 if (DIM(a) < DIM(b))
765 {
766 NDBOX *tmp = b;
767
768 b = a;
769 a = tmp;
770 }
771 dim = DIM(a);
772
773 size = CUBE_SIZE(dim);
774 result = palloc0(size);
775 SET_VARSIZE(result, size);
776 SET_DIM(result, dim);
777
778 /* First compute the union of the dimensions present in both args */
779 for (i = 0; i < DIM(b); i++)
780 {
781 result->x[i] = Min(Min(LL_COORD(a, i), UR_COORD(a, i)),
782 Min(LL_COORD(b, i), UR_COORD(b, i)));
783 result->x[i + DIM(a)] = Max(Max(LL_COORD(a, i), UR_COORD(a, i)),
784 Max(LL_COORD(b, i), UR_COORD(b, i)));
785 }
786 /* continue on the higher dimensions only present in 'a' */
787 for (; i < DIM(a); i++)
788 {
789 result->x[i] = Min(0,
790 Min(LL_COORD(a, i), UR_COORD(a, i))
791 );
792 result->x[i + dim] = Max(0,
793 Max(LL_COORD(a, i), UR_COORD(a, i))
794 );
795 }
796
797 /*
798 * Check if the result was in fact a point, and set the flag in the datum
799 * accordingly. (we don't bother to repalloc it smaller)
800 */
801 if (cube_is_point_internal(result))
802 {
803 size = POINT_SIZE(dim);
804 SET_VARSIZE(result, size);
805 SET_POINT_BIT(result);
806 }
807
808 return result;
809}

References a, b, cube_is_point_internal(), CUBE_SIZE, DIM, i, LL_COORD, Max, Min, palloc0(), POINT_SIZE, SET_DIM, SET_POINT_BIT, SET_VARSIZE, UR_COORD, and NDBOX::x.

Referenced by cube_union(), g_cube_binary_union(), g_cube_penalty(), and g_cube_picksplit().

◆ cube_ur_coord()

Datum cube_ur_coord ( PG_FUNCTION_ARGS  )

Definition at line 1586 of file cube.c.

1587{
1589 int n = PG_GETARG_INT32(1);
1590 double result;
1591
1592 if (DIM(c) >= n && n > 0)
1593 result = Max(LL_COORD(c, n - 1), UR_COORD(c, n - 1));
1594 else
1595 result = 0;
1596
1597 PG_FREE_IF_COPY(c, 0);
1598 PG_RETURN_FLOAT8(result);
1599}

References DIM, LL_COORD, Max, PG_FREE_IF_COPY, PG_GETARG_INT32, PG_GETARG_NDBOX_P, PG_RETURN_FLOAT8, and UR_COORD.

◆ distance_1D()

static double distance_1D ( double  a1,
double  a2,
double  b1,
double  b2 
)
static

Definition at line 1507 of file cube.c.

1508{
1509 /* interval (a) is entirely on the left of (b) */
1510 if ((a1 <= b1) && (a2 <= b1) && (a1 <= b2) && (a2 <= b2))
1511 return (Min(b1, b2) - Max(a1, a2));
1512
1513 /* interval (a) is entirely on the right of (b) */
1514 if ((a1 > b1) && (a2 > b1) && (a1 > b2) && (a2 > b2))
1515 return (Min(a1, a2) - Max(b1, b2));
1516
1517 /* the rest are all sorts of intersections */
1518 return 0.0;
1519}
static const FormData_pg_attribute a1
Definition: heap.c:144
static const FormData_pg_attribute a2
Definition: heap.c:157

References a1, a2, Max, and Min.

Referenced by cube_distance(), distance_chebyshev(), and distance_taxicab().

◆ distance_chebyshev()

Datum distance_chebyshev ( PG_FUNCTION_ARGS  )

Definition at line 1350 of file cube.c.

1351{
1353 *b = PG_GETARG_NDBOX_P(1);
1354 bool swapped = false;
1355 double d,
1356 distance;
1357 int i;
1358
1359 /* swap the box pointers if needed */
1360 if (DIM(a) < DIM(b))
1361 {
1362 NDBOX *tmp = b;
1363
1364 b = a;
1365 a = tmp;
1366 swapped = true;
1367 }
1368
1369 distance = 0.0;
1370 /* compute within the dimensions of (b) */
1371 for (i = 0; i < DIM(b); i++)
1372 {
1373 d = fabs(distance_1D(LL_COORD(a, i), UR_COORD(a, i),
1374 LL_COORD(b, i), UR_COORD(b, i)));
1375 if (d > distance)
1376 distance = d;
1377 }
1378
1379 /* compute distance to zero for those dimensions in (a) absent in (b) */
1380 for (i = DIM(b); i < DIM(a); i++)
1381 {
1382 d = fabs(distance_1D(LL_COORD(a, i), UR_COORD(a, i), 0.0, 0.0));
1383 if (d > distance)
1384 distance = d;
1385 }
1386
1387 if (swapped)
1388 {
1389 PG_FREE_IF_COPY(b, 0);
1390 PG_FREE_IF_COPY(a, 1);
1391 }
1392 else
1393 {
1394 PG_FREE_IF_COPY(a, 0);
1395 PG_FREE_IF_COPY(b, 1);
1396 }
1397
1398 PG_RETURN_FLOAT8(distance);
1399}

References a, b, DIM, distance_1D(), i, LL_COORD, PG_FREE_IF_COPY, PG_GETARG_NDBOX_P, PG_RETURN_FLOAT8, and UR_COORD.

Referenced by g_cube_distance().

◆ distance_taxicab()

Datum distance_taxicab ( PG_FUNCTION_ARGS  )

Definition at line 1306 of file cube.c.

1307{
1309 *b = PG_GETARG_NDBOX_P(1);
1310 bool swapped = false;
1311 double distance;
1312 int i;
1313
1314 /* swap the box pointers if needed */
1315 if (DIM(a) < DIM(b))
1316 {
1317 NDBOX *tmp = b;
1318
1319 b = a;
1320 a = tmp;
1321 swapped = true;
1322 }
1323
1324 distance = 0.0;
1325 /* compute within the dimensions of (b) */
1326 for (i = 0; i < DIM(b); i++)
1327 distance += fabs(distance_1D(LL_COORD(a, i), UR_COORD(a, i),
1328 LL_COORD(b, i), UR_COORD(b, i)));
1329
1330 /* compute distance to zero for those dimensions in (a) absent in (b) */
1331 for (i = DIM(b); i < DIM(a); i++)
1332 distance += fabs(distance_1D(LL_COORD(a, i), UR_COORD(a, i),
1333 0.0, 0.0));
1334
1335 if (swapped)
1336 {
1337 PG_FREE_IF_COPY(b, 0);
1338 PG_FREE_IF_COPY(a, 1);
1339 }
1340 else
1341 {
1342 PG_FREE_IF_COPY(a, 0);
1343 PG_FREE_IF_COPY(b, 1);
1344 }
1345
1346 PG_RETURN_FLOAT8(distance);
1347}

References a, b, DIM, distance_1D(), i, LL_COORD, PG_FREE_IF_COPY, PG_GETARG_NDBOX_P, PG_RETURN_FLOAT8, and UR_COORD.

Referenced by g_cube_distance().

◆ g_cube_binary_union()

NDBOX * g_cube_binary_union ( NDBOX r1,
NDBOX r2,
int *  sizep 
)

Definition at line 739 of file cube.c.

740{
741 NDBOX *retval;
742
743 retval = cube_union_v0(r1, r2);
744 *sizep = VARSIZE(retval);
745
746 return retval;
747}
#define VARSIZE(PTR)
Definition: varatt.h:279

References cube_union_v0(), and VARSIZE.

Referenced by g_cube_union().

◆ g_cube_compress()

Datum g_cube_compress ( PG_FUNCTION_ARGS  )

Definition at line 461 of file cube.c.

462{
464}
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:268
#define PG_RETURN_DATUM(x)
Definition: fmgr.h:353

References PG_GETARG_DATUM, and PG_RETURN_DATUM.

◆ g_cube_consistent()

Datum g_cube_consistent ( PG_FUNCTION_ARGS  )

Definition at line 395 of file cube.c.

396{
397 GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
398 NDBOX *query = PG_GETARG_NDBOX_P(1);
400
401 /* Oid subtype = PG_GETARG_OID(3); */
402 bool *recheck = (bool *) PG_GETARG_POINTER(4);
403 bool res;
404
405 /* All cases served by this function are exact */
406 *recheck = false;
407
408 /*
409 * if entry is not leaf, use g_cube_internal_consistent, else use
410 * g_cube_leaf_consistent
411 */
412 if (GIST_LEAF(entry))
414 query, strategy);
415 else
417 query, strategy);
418
419 PG_FREE_IF_COPY(query, 1);
420 PG_RETURN_BOOL(res);
421}
bool g_cube_leaf_consistent(NDBOX *key, NDBOX *query, StrategyNumber strategy)
Definition: cube.c:683
bool g_cube_internal_consistent(NDBOX *key, NDBOX *query, StrategyNumber strategy)
Definition: cube.c:712
#define DatumGetNDBOXP(x)
Definition: cubedata.h:52
#define PG_GETARG_UINT16(n)
Definition: fmgr.h:272
#define GIST_LEAF(entry)
Definition: gist.h:171
uint16 StrategyNumber
Definition: stratnum.h:22
Datum key
Definition: gist.h:161

References DatumGetNDBOXP, g_cube_internal_consistent(), g_cube_leaf_consistent(), GIST_LEAF, GISTENTRY::key, PG_FREE_IF_COPY, PG_GETARG_NDBOX_P, PG_GETARG_POINTER, PG_GETARG_UINT16, and PG_RETURN_BOOL.

◆ g_cube_decompress()

Datum g_cube_decompress ( PG_FUNCTION_ARGS  )

Definition at line 467 of file cube.c.

468{
469 GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
470 NDBOX *key = DatumGetNDBOXP(entry->key);
471
472 if (key != DatumGetNDBOXP(entry->key))
473 {
474 GISTENTRY *retval = (GISTENTRY *) palloc(sizeof(GISTENTRY));
475
477 entry->rel, entry->page,
478 entry->offset, false);
479 PG_RETURN_POINTER(retval);
480 }
481 PG_RETURN_POINTER(entry);
482}
#define PG_RETURN_POINTER(x)
Definition: fmgr.h:361
#define gistentryinit(e, k, r, pg, o, l)
Definition: gist.h:245
static Datum PointerGetDatum(const void *X)
Definition: postgres.h:327
OffsetNumber offset
Definition: gist.h:164
Page page
Definition: gist.h:163
Relation rel
Definition: gist.h:162

References DatumGetNDBOXP, gistentryinit, GISTENTRY::key, sort-test::key, GISTENTRY::offset, GISTENTRY::page, palloc(), PG_GETARG_POINTER, PG_RETURN_POINTER, PointerGetDatum(), and GISTENTRY::rel.

◆ g_cube_distance()

Datum g_cube_distance ( PG_FUNCTION_ARGS  )

Definition at line 1402 of file cube.c.

1403{
1404 GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
1406 NDBOX *cube = DatumGetNDBOXP(entry->key);
1407 double retval;
1408
1409 if (strategy == CubeKNNDistanceCoord)
1410 {
1411 /*
1412 * Handle ordering by ~> operator. See comments of cube_coord_llur()
1413 * for details
1414 */
1415 int coord = PG_GETARG_INT32(1);
1416 bool isLeaf = GistPageIsLeaf(entry->page);
1417 bool inverse = false;
1418
1419 /* 0 is the only unsupported coordinate value */
1420 if (coord == 0)
1421 ereport(ERROR,
1422 (errcode(ERRCODE_ARRAY_ELEMENT_ERROR),
1423 errmsg("zero cube index is not defined")));
1424
1425 /* Return inversed value for negative coordinate */
1426 if (coord < 0)
1427 {
1428 coord = -coord;
1429 inverse = true;
1430 }
1431
1432 if (coord <= 2 * DIM(cube))
1433 {
1434 /* dimension index */
1435 int index = (coord - 1) / 2;
1436
1437 /* whether this is upper bound (lower bound otherwise) */
1438 bool upper = ((coord - 1) % 2 == 1);
1439
1440 if (IS_POINT(cube))
1441 {
1442 retval = cube->x[index];
1443 }
1444 else
1445 {
1446 if (isLeaf)
1447 {
1448 /* For leaf just return required upper/lower bound */
1449 if (upper)
1450 retval = Max(cube->x[index], cube->x[index + DIM(cube)]);
1451 else
1452 retval = Min(cube->x[index], cube->x[index + DIM(cube)]);
1453 }
1454 else
1455 {
1456 /*
1457 * For non-leaf we should always return lower bound,
1458 * because even upper bound of a child in the subtree can
1459 * be as small as our lower bound. For inversed case we
1460 * return upper bound because it becomes lower bound for
1461 * inversed value.
1462 */
1463 if (!inverse)
1464 retval = Min(cube->x[index], cube->x[index + DIM(cube)]);
1465 else
1466 retval = Max(cube->x[index], cube->x[index + DIM(cube)]);
1467 }
1468 }
1469 }
1470 else
1471 {
1472 retval = 0.0;
1473 }
1474
1475 /* Inverse return value if needed */
1476 if (inverse)
1477 retval = -retval;
1478 }
1479 else
1480 {
1481 NDBOX *query = PG_GETARG_NDBOX_P(1);
1482
1483 switch (strategy)
1484 {
1487 PointerGetDatum(cube), PointerGetDatum(query)));
1488 break;
1491 PointerGetDatum(cube), PointerGetDatum(query)));
1492 break;
1495 PointerGetDatum(cube), PointerGetDatum(query)));
1496 break;
1497 default:
1498 elog(ERROR, "unrecognized cube strategy number: %d", strategy);
1499 retval = 0; /* keep compiler quiet */
1500 break;
1501 }
1502 }
1503 PG_RETURN_FLOAT8(retval);
1504}
Datum distance_taxicab(PG_FUNCTION_ARGS)
Definition: cube.c:1306
Datum cube_distance(PG_FUNCTION_ARGS)
Definition: cube.c:1257
Datum distance_chebyshev(PG_FUNCTION_ARGS)
Definition: cube.c:1350
#define CubeKNNDistanceCoord
Definition: cubedata.h:57
#define CubeKNNDistanceEuclid
Definition: cubedata.h:59
#define CubeKNNDistanceTaxicab
Definition: cubedata.h:58
#define CubeKNNDistanceChebyshev
Definition: cubedata.h:60
#define elog(elevel,...)
Definition: elog.h:226
#define DirectFunctionCall2(func, arg1, arg2)
Definition: fmgr.h:684
#define GistPageIsLeaf(page)
Definition: gist.h:170
static float8 DatumGetFloat8(Datum X)
Definition: postgres.h:499

References cube_distance(), CubeKNNDistanceChebyshev, CubeKNNDistanceCoord, CubeKNNDistanceEuclid, CubeKNNDistanceTaxicab, DatumGetFloat8(), DatumGetNDBOXP, DIM, DirectFunctionCall2, distance_chebyshev(), distance_taxicab(), elog, ereport, errcode(), errmsg(), ERROR, GistPageIsLeaf, IS_POINT, GISTENTRY::key, Max, Min, GISTENTRY::page, PG_GETARG_INT32, PG_GETARG_NDBOX_P, PG_GETARG_POINTER, PG_GETARG_UINT16, PG_RETURN_FLOAT8, PointerGetDatum(), upper(), and NDBOX::x.

◆ g_cube_internal_consistent()

bool g_cube_internal_consistent ( NDBOX key,
NDBOX query,
StrategyNumber  strategy 
)

Definition at line 712 of file cube.c.

715{
716 bool retval;
717
718 switch (strategy)
719 {
721 retval = (bool) cube_overlap_v0(key, query);
722 break;
726 retval = (bool) cube_contains_v0(key, query);
727 break;
730 retval = (bool) cube_overlap_v0(key, query);
731 break;
732 default:
733 retval = false;
734 }
735 return retval;
736}
#define RTOldContainsStrategyNumber
Definition: stratnum.h:63
#define RTOverlapStrategyNumber
Definition: stratnum.h:53
#define RTSameStrategyNumber
Definition: stratnum.h:56
#define RTContainsStrategyNumber
Definition: stratnum.h:57
#define RTOldContainedByStrategyNumber
Definition: stratnum.h:64
#define RTContainedByStrategyNumber
Definition: stratnum.h:58

References cube_contains_v0(), cube_overlap_v0(), sort-test::key, RTContainedByStrategyNumber, RTContainsStrategyNumber, RTOldContainedByStrategyNumber, RTOldContainsStrategyNumber, RTOverlapStrategyNumber, and RTSameStrategyNumber.

Referenced by g_cube_consistent().

◆ g_cube_leaf_consistent()

bool g_cube_leaf_consistent ( NDBOX key,
NDBOX query,
StrategyNumber  strategy 
)

Definition at line 683 of file cube.c.

686{
687 bool retval;
688
689 switch (strategy)
690 {
692 retval = cube_overlap_v0(key, query);
693 break;
695 retval = (cube_cmp_v0(key, query) == 0);
696 break;
699 retval = cube_contains_v0(key, query);
700 break;
703 retval = cube_contains_v0(query, key);
704 break;
705 default:
706 retval = false;
707 }
708 return retval;
709}

References cube_cmp_v0(), cube_contains_v0(), cube_overlap_v0(), sort-test::key, RTContainedByStrategyNumber, RTContainsStrategyNumber, RTOldContainedByStrategyNumber, RTOldContainsStrategyNumber, RTOverlapStrategyNumber, and RTSameStrategyNumber.

Referenced by g_cube_consistent().

◆ g_cube_penalty()

Datum g_cube_penalty ( PG_FUNCTION_ARGS  )

Definition at line 490 of file cube.c.

491{
492 GISTENTRY *origentry = (GISTENTRY *) PG_GETARG_POINTER(0);
493 GISTENTRY *newentry = (GISTENTRY *) PG_GETARG_POINTER(1);
494 float *result = (float *) PG_GETARG_POINTER(2);
495 NDBOX *ud;
496 double tmp1,
497 tmp2;
498
499 ud = cube_union_v0(DatumGetNDBOXP(origentry->key),
500 DatumGetNDBOXP(newentry->key));
501 rt_cube_size(ud, &tmp1);
502 rt_cube_size(DatumGetNDBOXP(origentry->key), &tmp2);
503 *result = (float) (tmp1 - tmp2);
504
505 PG_RETURN_FLOAT8(*result);
506}

References cube_union_v0(), DatumGetNDBOXP, GISTENTRY::key, PG_GETARG_POINTER, PG_RETURN_FLOAT8, and rt_cube_size().

◆ g_cube_picksplit()

Datum g_cube_picksplit ( PG_FUNCTION_ARGS  )

Definition at line 515 of file cube.c.

516{
520 j;
521 NDBOX *datum_alpha,
522 *datum_beta;
523 NDBOX *datum_l,
524 *datum_r;
525 NDBOX *union_d,
526 *union_dl,
527 *union_dr;
528 NDBOX *inter_d;
529 bool firsttime;
530 double size_alpha,
531 size_beta,
532 size_union,
533 size_inter;
534 double size_waste,
535 waste;
536 double size_l,
537 size_r;
538 int nbytes;
539 OffsetNumber seed_1 = 1,
540 seed_2 = 2;
541 OffsetNumber *left,
542 *right;
543 OffsetNumber maxoff;
544
545 maxoff = entryvec->n - 2;
546 nbytes = (maxoff + 2) * sizeof(OffsetNumber);
547 v->spl_left = (OffsetNumber *) palloc(nbytes);
548 v->spl_right = (OffsetNumber *) palloc(nbytes);
549
550 firsttime = true;
551 waste = 0.0;
552
553 for (i = FirstOffsetNumber; i < maxoff; i = OffsetNumberNext(i))
554 {
555 datum_alpha = DatumGetNDBOXP(entryvec->vector[i].key);
556 for (j = OffsetNumberNext(i); j <= maxoff; j = OffsetNumberNext(j))
557 {
558 datum_beta = DatumGetNDBOXP(entryvec->vector[j].key);
559
560 /* compute the wasted space by unioning these guys */
561 /* size_waste = size_union - size_inter; */
562 union_d = cube_union_v0(datum_alpha, datum_beta);
563 rt_cube_size(union_d, &size_union);
565 entryvec->vector[i].key,
566 entryvec->vector[j].key));
567 rt_cube_size(inter_d, &size_inter);
568 size_waste = size_union - size_inter;
569
570 /*
571 * are these a more promising split than what we've already seen?
572 */
573
574 if (size_waste > waste || firsttime)
575 {
576 waste = size_waste;
577 seed_1 = i;
578 seed_2 = j;
579 firsttime = false;
580 }
581 }
582 }
583
584 left = v->spl_left;
585 v->spl_nleft = 0;
586 right = v->spl_right;
587 v->spl_nright = 0;
588
589 datum_alpha = DatumGetNDBOXP(entryvec->vector[seed_1].key);
590 datum_l = cube_union_v0(datum_alpha, datum_alpha);
591 rt_cube_size(datum_l, &size_l);
592 datum_beta = DatumGetNDBOXP(entryvec->vector[seed_2].key);
593 datum_r = cube_union_v0(datum_beta, datum_beta);
594 rt_cube_size(datum_r, &size_r);
595
596 /*
597 * Now split up the regions between the two seeds. An important property
598 * of this split algorithm is that the split vector v has the indices of
599 * items to be split in order in its left and right vectors. We exploit
600 * this property by doing a merge in the code that actually splits the
601 * page.
602 *
603 * For efficiency, we also place the new index tuple in this loop. This is
604 * handled at the very end, when we have placed all the existing tuples
605 * and i == maxoff + 1.
606 */
607
608 maxoff = OffsetNumberNext(maxoff);
609 for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i))
610 {
611 /*
612 * If we've already decided where to place this item, just put it on
613 * the right list. Otherwise, we need to figure out which page needs
614 * the least enlargement in order to store the item.
615 */
616
617 if (i == seed_1)
618 {
619 *left++ = i;
620 v->spl_nleft++;
621 continue;
622 }
623 else if (i == seed_2)
624 {
625 *right++ = i;
626 v->spl_nright++;
627 continue;
628 }
629
630 /* okay, which page needs least enlargement? */
631 datum_alpha = DatumGetNDBOXP(entryvec->vector[i].key);
632 union_dl = cube_union_v0(datum_l, datum_alpha);
633 union_dr = cube_union_v0(datum_r, datum_alpha);
634 rt_cube_size(union_dl, &size_alpha);
635 rt_cube_size(union_dr, &size_beta);
636
637 /* pick which page to add it to */
638 if (size_alpha - size_l < size_beta - size_r)
639 {
640 datum_l = union_dl;
641 size_l = size_alpha;
642 *left++ = i;
643 v->spl_nleft++;
644 }
645 else
646 {
647 datum_r = union_dr;
648 size_r = size_beta;
649 *right++ = i;
650 v->spl_nright++;
651 }
652 }
653 *left = *right = FirstOffsetNumber; /* sentinel value */
654
655 v->spl_ldatum = PointerGetDatum(datum_l);
656 v->spl_rdatum = PointerGetDatum(datum_r);
657
659}
Datum cube_inter(PG_FUNCTION_ARGS)
Definition: cube.c:827
#define OffsetNumberNext(offsetNumber)
Definition: off.h:52
uint16 OffsetNumber
Definition: off.h:24
#define FirstOffsetNumber
Definition: off.h:27
int spl_nleft
Definition: gist.h:144
OffsetNumber * spl_right
Definition: gist.h:148
Datum spl_ldatum
Definition: gist.h:145
Datum spl_rdatum
Definition: gist.h:150
int spl_nright
Definition: gist.h:149
OffsetNumber * spl_left
Definition: gist.h:143
GISTENTRY vector[FLEXIBLE_ARRAY_MEMBER]
Definition: gist.h:237
int32 n
Definition: gist.h:236

References cube_inter(), cube_union_v0(), DatumGetNDBOXP, DirectFunctionCall2, FirstOffsetNumber, i, j, GISTENTRY::key, GistEntryVector::n, OffsetNumberNext, palloc(), PG_GETARG_POINTER, PG_RETURN_POINTER, PointerGetDatum(), rt_cube_size(), GIST_SPLITVEC::spl_ldatum, GIST_SPLITVEC::spl_left, GIST_SPLITVEC::spl_nleft, GIST_SPLITVEC::spl_nright, GIST_SPLITVEC::spl_rdatum, GIST_SPLITVEC::spl_right, and GistEntryVector::vector.

◆ g_cube_same()

Datum g_cube_same ( PG_FUNCTION_ARGS  )

Definition at line 665 of file cube.c.

666{
667 NDBOX *b1 = PG_GETARG_NDBOX_P(0);
668 NDBOX *b2 = PG_GETARG_NDBOX_P(1);
669 bool *result = (bool *) PG_GETARG_POINTER(2);
670
671 if (cube_cmp_v0(b1, b2) == 0)
672 *result = true;
673 else
674 *result = false;
675
676 PG_RETURN_NDBOX_P(result);
677}

References cube_cmp_v0(), PG_GETARG_NDBOX_P, PG_GETARG_POINTER, and PG_RETURN_NDBOX_P.

◆ g_cube_union()

Datum g_cube_union ( PG_FUNCTION_ARGS  )

Definition at line 429 of file cube.c.

430{
432 int *sizep = (int *) PG_GETARG_POINTER(1);
433 NDBOX *out = (NDBOX *) NULL;
434 NDBOX *tmp;
435 int i;
436
437 tmp = DatumGetNDBOXP(entryvec->vector[0].key);
438
439 /*
440 * sizep = sizeof(NDBOX); -- NDBOX has variable size
441 */
442 *sizep = VARSIZE(tmp);
443
444 for (i = 1; i < entryvec->n; i++)
445 {
446 out = g_cube_binary_union(tmp,
447 DatumGetNDBOXP(entryvec->vector[i].key),
448 sizep);
449 tmp = out;
450 }
451
453}
NDBOX * g_cube_binary_union(NDBOX *r1, NDBOX *r2, int *sizep)
Definition: cube.c:739

References DatumGetNDBOXP, g_cube_binary_union(), i, GISTENTRY::key, GistEntryVector::n, PG_GETARG_POINTER, PG_RETURN_POINTER, VARSIZE, and GistEntryVector::vector.

◆ PG_FUNCTION_INFO_V1() [1/42]

PG_FUNCTION_INFO_V1 ( cube_a_f8  )

◆ PG_FUNCTION_INFO_V1() [2/42]

PG_FUNCTION_INFO_V1 ( cube_a_f8_f8  )

◆ PG_FUNCTION_INFO_V1() [3/42]

PG_FUNCTION_INFO_V1 ( cube_c_f8  )

◆ PG_FUNCTION_INFO_V1() [4/42]

PG_FUNCTION_INFO_V1 ( cube_c_f8_f8  )

◆ PG_FUNCTION_INFO_V1() [5/42]

PG_FUNCTION_INFO_V1 ( cube_cmp  )

◆ PG_FUNCTION_INFO_V1() [6/42]

PG_FUNCTION_INFO_V1 ( cube_contained  )

◆ PG_FUNCTION_INFO_V1() [7/42]

PG_FUNCTION_INFO_V1 ( cube_contains  )

◆ PG_FUNCTION_INFO_V1() [8/42]

PG_FUNCTION_INFO_V1 ( cube_coord  )

◆ PG_FUNCTION_INFO_V1() [9/42]

PG_FUNCTION_INFO_V1 ( cube_coord_llur  )

◆ PG_FUNCTION_INFO_V1() [10/42]

PG_FUNCTION_INFO_V1 ( cube_dim  )

◆ PG_FUNCTION_INFO_V1() [11/42]

PG_FUNCTION_INFO_V1 ( cube_distance  )

◆ PG_FUNCTION_INFO_V1() [12/42]

PG_FUNCTION_INFO_V1 ( cube_enlarge  )

◆ PG_FUNCTION_INFO_V1() [13/42]

PG_FUNCTION_INFO_V1 ( cube_eq  )

◆ PG_FUNCTION_INFO_V1() [14/42]

PG_FUNCTION_INFO_V1 ( cube_f8  )

◆ PG_FUNCTION_INFO_V1() [15/42]

PG_FUNCTION_INFO_V1 ( cube_f8_f8  )

◆ PG_FUNCTION_INFO_V1() [16/42]

PG_FUNCTION_INFO_V1 ( cube_ge  )

◆ PG_FUNCTION_INFO_V1() [17/42]

PG_FUNCTION_INFO_V1 ( cube_gt  )

◆ PG_FUNCTION_INFO_V1() [18/42]

PG_FUNCTION_INFO_V1 ( cube_in  )

◆ PG_FUNCTION_INFO_V1() [19/42]

PG_FUNCTION_INFO_V1 ( cube_inter  )

◆ PG_FUNCTION_INFO_V1() [20/42]

PG_FUNCTION_INFO_V1 ( cube_is_point  )

◆ PG_FUNCTION_INFO_V1() [21/42]

PG_FUNCTION_INFO_V1 ( cube_le  )

◆ PG_FUNCTION_INFO_V1() [22/42]

PG_FUNCTION_INFO_V1 ( cube_ll_coord  )

◆ PG_FUNCTION_INFO_V1() [23/42]

PG_FUNCTION_INFO_V1 ( cube_lt  )

◆ PG_FUNCTION_INFO_V1() [24/42]

PG_FUNCTION_INFO_V1 ( cube_ne  )

◆ PG_FUNCTION_INFO_V1() [25/42]

PG_FUNCTION_INFO_V1 ( cube_out  )

◆ PG_FUNCTION_INFO_V1() [26/42]

PG_FUNCTION_INFO_V1 ( cube_overlap  )

◆ PG_FUNCTION_INFO_V1() [27/42]

PG_FUNCTION_INFO_V1 ( cube_recv  )

◆ PG_FUNCTION_INFO_V1() [28/42]

PG_FUNCTION_INFO_V1 ( cube_send  )

◆ PG_FUNCTION_INFO_V1() [29/42]

PG_FUNCTION_INFO_V1 ( cube_size  )

◆ PG_FUNCTION_INFO_V1() [30/42]

PG_FUNCTION_INFO_V1 ( cube_subset  )

◆ PG_FUNCTION_INFO_V1() [31/42]

PG_FUNCTION_INFO_V1 ( cube_union  )

◆ PG_FUNCTION_INFO_V1() [32/42]

PG_FUNCTION_INFO_V1 ( cube_ur_coord  )

◆ PG_FUNCTION_INFO_V1() [33/42]

PG_FUNCTION_INFO_V1 ( distance_chebyshev  )

◆ PG_FUNCTION_INFO_V1() [34/42]

PG_FUNCTION_INFO_V1 ( distance_taxicab  )

◆ PG_FUNCTION_INFO_V1() [35/42]

PG_FUNCTION_INFO_V1 ( g_cube_compress  )

◆ PG_FUNCTION_INFO_V1() [36/42]

PG_FUNCTION_INFO_V1 ( g_cube_consistent  )

◆ PG_FUNCTION_INFO_V1() [37/42]

PG_FUNCTION_INFO_V1 ( g_cube_decompress  )

◆ PG_FUNCTION_INFO_V1() [38/42]

PG_FUNCTION_INFO_V1 ( g_cube_distance  )

◆ PG_FUNCTION_INFO_V1() [39/42]

PG_FUNCTION_INFO_V1 ( g_cube_penalty  )

◆ PG_FUNCTION_INFO_V1() [40/42]

PG_FUNCTION_INFO_V1 ( g_cube_picksplit  )

◆ PG_FUNCTION_INFO_V1() [41/42]

PG_FUNCTION_INFO_V1 ( g_cube_same  )

◆ PG_FUNCTION_INFO_V1() [42/42]

PG_FUNCTION_INFO_V1 ( g_cube_union  )

◆ PG_MODULE_MAGIC_EXT()

PG_MODULE_MAGIC_EXT ( name = "cube",
version = PG_VERSION 
)

◆ rt_cube_size()

void rt_cube_size ( NDBOX a,
double *  size 
)

Definition at line 914 of file cube.c.

915{
916 double result;
917 int i;
918
919 if (a == (NDBOX *) NULL)
920 {
921 /* special case for GiST */
922 result = 0.0;
923 }
924 else if (IS_POINT(a) || DIM(a) == 0)
925 {
926 /* necessarily has zero size */
927 result = 0.0;
928 }
929 else
930 {
931 result = 1.0;
932 for (i = 0; i < DIM(a); i++)
933 result *= fabs(UR_COORD(a, i) - LL_COORD(a, i));
934 }
935 *size = result;
936}

References a, DIM, i, IS_POINT, LL_COORD, and UR_COORD.

Referenced by cube_size(), g_cube_penalty(), and g_cube_picksplit().