PostgreSQL Source Code git master
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_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)
 

Variables

 PG_MODULE_MAGIC
 

Macro Definition Documentation

◆ ARRNELEMS

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

Definition at line 26 of file cube.c.

◆ ARRPTR

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

Definition at line 25 of file cube.c.

Function Documentation

◆ cube_a_f8()

Datum cube_a_f8 ( PG_FUNCTION_ARGS  )

Definition at line 207 of file cube.c.

208{
210 NDBOX *result;
211 int i;
212 int dim;
213 int size;
214 double *dur;
215
216 if (array_contains_nulls(ur))
218 (errcode(ERRCODE_ARRAY_ELEMENT_ERROR),
219 errmsg("cannot work with arrays containing NULLs")));
220
221 dim = ARRNELEMS(ur);
222 if (dim > CUBE_MAX_DIM)
224 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
225 errmsg("array is too long"),
226 errdetail("A cube cannot have more than %d dimensions.",
227 CUBE_MAX_DIM)));
228
229 dur = ARRPTR(ur);
230
231 size = POINT_SIZE(dim);
232 result = (NDBOX *) palloc0(size);
233 SET_VARSIZE(result, size);
234 SET_DIM(result, dim);
235 SET_POINT_BIT(result);
236
237 for (i = 0; i < dim; i++)
238 result->x[i] = dur[i];
239
240 PG_RETURN_NDBOX_P(result);
241}
#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:26
#define ARRPTR(x)
Definition: cube.c:25
#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:1203
int errcode(int sqlerrcode)
Definition: elog.c:853
int errmsg(const char *fmt,...)
Definition: elog.c:1070
#define ERROR
Definition: elog.h:39
#define ereport(elevel,...)
Definition: elog.h:149
int i
Definition: isn.c:72
void * palloc0(Size size)
Definition: mcxt.c:1347
static pg_noinline void Size size
Definition: slab.c:607
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, size, and NDBOX::x.

◆ cube_a_f8_f8()

Datum cube_a_f8_f8 ( PG_FUNCTION_ARGS  )

Definition at line 140 of file cube.c.

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

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, size, and NDBOX::x.

◆ cube_c_f8()

Datum cube_c_f8 ( PG_FUNCTION_ARGS  )

Definition at line 1819 of file cube.c.

1820{
1821 NDBOX *cube = PG_GETARG_NDBOX_P(0);
1822 double x = PG_GETARG_FLOAT8(1);
1823 NDBOX *result;
1824 int size;
1825 int i;
1826
1827 if (DIM(cube) + 1 > CUBE_MAX_DIM)
1828 ereport(ERROR,
1829 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
1830 errmsg("can't extend cube"),
1831 errdetail("A cube cannot have more than %d dimensions.",
1832 CUBE_MAX_DIM)));
1833
1834 if (IS_POINT(cube))
1835 {
1836 size = POINT_SIZE((DIM(cube) + 1));
1837 result = (NDBOX *) palloc0(size);
1838 SET_VARSIZE(result, size);
1839 SET_DIM(result, DIM(cube) + 1);
1840 SET_POINT_BIT(result);
1841 for (i = 0; i < DIM(cube); i++)
1842 result->x[i] = cube->x[i];
1843 result->x[DIM(result) - 1] = x;
1844 }
1845 else
1846 {
1847 size = CUBE_SIZE((DIM(cube) + 1));
1848 result = (NDBOX *) palloc0(size);
1849 SET_VARSIZE(result, size);
1850 SET_DIM(result, DIM(cube) + 1);
1851 for (i = 0; i < DIM(cube); i++)
1852 {
1853 result->x[i] = cube->x[i];
1854 result->x[DIM(result) + i] = cube->x[DIM(cube) + i];
1855 }
1856 result->x[DIM(result) - 1] = x;
1857 result->x[2 * DIM(result) - 1] = x;
1858 }
1859
1860 PG_FREE_IF_COPY(cube, 0);
1861 PG_RETURN_NDBOX_P(result);
1862}
#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:70

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, size, NDBOX::x, and x.

◆ cube_c_f8_f8()

Datum cube_c_f8_f8 ( PG_FUNCTION_ARGS  )

Definition at line 1866 of file cube.c.

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

◆ cube_cmp()

Datum cube_cmp ( PG_FUNCTION_ARGS  )

Definition at line 1018 of file cube.c.

1019{
1021 *b = PG_GETARG_NDBOX_P(1);
1022 int32 res;
1023
1024 res = cube_cmp_v0(a, b);
1025
1026 PG_FREE_IF_COPY(a, 0);
1027 PG_FREE_IF_COPY(b, 1);
1029}
int32_t int32
Definition: c.h:484
int32 cube_cmp_v0(NDBOX *a, NDBOX *b)
Definition: cube.c:938
#define PG_RETURN_INT32(x)
Definition: fmgr.h:354
int b
Definition: isn.c:69
int a
Definition: isn.c:68

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

◆ cube_cmp_v0()

int32 cube_cmp_v0 ( NDBOX a,
NDBOX b 
)

Definition at line 938 of file cube.c.

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

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 1179 of file cube.c.

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

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

◆ cube_contains()

Datum cube_contains ( PG_FUNCTION_ARGS  )

Definition at line 1163 of file cube.c.

1164{
1166 *b = PG_GETARG_NDBOX_P(1);
1167 bool res;
1168
1169 res = cube_contains_v0(a, b);
1170
1171 PG_FREE_IF_COPY(a, 0);
1172 PG_FREE_IF_COPY(b, 1);
1174}

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

◆ cube_contains_v0()

bool cube_contains_v0 ( NDBOX a,
NDBOX b 
)

Definition at line 1125 of file cube.c.

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

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 1604 of file cube.c.

1605{
1606 NDBOX *cube = PG_GETARG_NDBOX_P(0);
1607 int coord = PG_GETARG_INT32(1);
1608
1609 if (coord <= 0 || coord > 2 * DIM(cube))
1610 ereport(ERROR,
1611 (errcode(ERRCODE_ARRAY_ELEMENT_ERROR),
1612 errmsg("cube index %d is out of bounds", coord)));
1613
1614 if (IS_POINT(cube))
1615 PG_RETURN_FLOAT8(cube->x[(coord - 1) % DIM(cube)]);
1616 else
1617 PG_RETURN_FLOAT8(cube->x[coord - 1]);
1618}
#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 1645 of file cube.c.

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

1556{
1558 int dim = DIM(c);
1559
1560 PG_FREE_IF_COPY(c, 0);
1561 PG_RETURN_INT32(dim);
1562}
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 1254 of file cube.c.

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

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 1704 of file cube.c.

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

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, size, UR_COORD, and NDBOX::x.

◆ cube_eq()

Datum cube_eq ( PG_FUNCTION_ARGS  )

Definition at line 1033 of file cube.c.

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

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

◆ cube_f8()

Datum cube_f8 ( PG_FUNCTION_ARGS  )

Definition at line 1769 of file cube.c.

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

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

◆ cube_f8_f8()

Datum cube_f8_f8 ( PG_FUNCTION_ARGS  )

Definition at line 1787 of file cube.c.

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

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

◆ cube_ge()

Datum cube_ge ( PG_FUNCTION_ARGS  )

Definition at line 1108 of file cube.c.

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

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

◆ cube_gt()

Datum cube_gt ( PG_FUNCTION_ARGS  )

Definition at line 1078 of file cube.c.

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

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

◆ cube_in()

Datum cube_in ( PG_FUNCTION_ARGS  )

Definition at line 118 of file cube.c.

119{
120 char *str = PG_GETARG_CSTRING(0);
121 NDBOX *result;
122 Size scanbuflen;
123 yyscan_t scanner;
124
125 cube_scanner_init(str, &scanbuflen, &scanner);
126
127 cube_yyparse(&result, scanbuflen, fcinfo->context, scanner);
128
129 /* We might as well run this even on failure. */
130 cube_scanner_finish(scanner);
131
132 PG_RETURN_NDBOX_P(result);
133}
size_t Size
Definition: c.h:562
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 824 of file cube.c.

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

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, size, UR_COORD, and NDBOX::x.

Referenced by g_cube_picksplit().

◆ cube_is_point()

Datum cube_is_point ( PG_FUNCTION_ARGS  )

Definition at line 1520 of file cube.c.

1521{
1522 NDBOX *cube = PG_GETARG_NDBOX_P(0);
1523 bool result;
1524
1525 result = cube_is_point_internal(cube);
1526 PG_FREE_IF_COPY(cube, 0);
1527 PG_RETURN_BOOL(result);
1528}

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 1531 of file cube.c.

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

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 1093 of file cube.c.

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

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

◆ cube_ll_coord()

Datum cube_ll_coord ( PG_FUNCTION_ARGS  )

Definition at line 1566 of file cube.c.

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

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 1063 of file cube.c.

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

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

◆ cube_ne()

Datum cube_ne ( PG_FUNCTION_ARGS  )

Definition at line 1048 of file cube.c.

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

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

◆ cube_out()

Datum cube_out ( PG_FUNCTION_ARGS  )

Definition at line 293 of file cube.c.

294{
295 NDBOX *cube = PG_GETARG_NDBOX_P(0);
297 int dim = DIM(cube);
298 int i;
299
301
303 for (i = 0; i < dim; i++)
304 {
305 if (i > 0)
308 }
310
311 if (!cube_is_point_internal(cube))
312 {
314 for (i = 0; i < dim; i++)
315 {
316 if (i > 0)
319 }
321 }
322
323 PG_FREE_IF_COPY(cube, 0);
325}
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 1234 of file cube.c.

1235{
1237 *b = PG_GETARG_NDBOX_P(1);
1238 bool res;
1239
1240 res = cube_overlap_v0(a, b);
1241
1242 PG_FREE_IF_COPY(a, 0);
1243 PG_FREE_IF_COPY(b, 1);
1245}
bool cube_overlap_v0(NDBOX *a, NDBOX *b)
Definition: cube.c:1195

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

◆ cube_overlap_v0()

bool cube_overlap_v0 ( NDBOX a,
NDBOX b 
)

Definition at line 1195 of file cube.c.

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

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 353 of file cube.c.

354{
356 int32 header;
357 int32 i,
358 nitems;
359 NDBOX *cube;
360
361 header = pq_getmsgint(buf, sizeof(int32));
362 nitems = (header & DIM_MASK);
363 if (nitems > CUBE_MAX_DIM)
365 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
366 errmsg("cube dimension is too large"),
367 errdetail("A cube cannot have more than %d dimensions.",
368 CUBE_MAX_DIM)));
369 if ((header & POINT_BIT) == 0)
370 nitems += nitems;
371 cube = palloc(offsetof(NDBOX, x) + sizeof(double) * nitems);
372 SET_VARSIZE(cube, offsetof(NDBOX, x) + sizeof(double) * nitems);
373 cube->header = header;
374 for (i = 0; i < nitems; i++)
375 cube->x[i] = pq_getmsgfloat8(buf);
376
377 PG_RETURN_NDBOX_P(cube);
378}
#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:1317
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 331 of file cube.c.

332{
333 NDBOX *cube = PG_GETARG_NDBOX_P(0);
335 int32 i,
336 nitems = DIM(cube);
337
339 pq_sendint32(&buf, cube->header);
340 if (!IS_POINT(cube))
341 nitems += nitems;
342 /* for symmetry with cube_recv, we don't use LL_COORD/UR_COORD here */
343 for (i = 0; i < nitems; i++)
344 pq_sendfloat8(&buf, cube->x[i]);
345
347}
#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 900 of file cube.c.

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

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 244 of file cube.c.

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

◆ cube_union()

Datum cube_union ( PG_FUNCTION_ARGS  )

Definition at line 809 of file cube.c.

810{
813 NDBOX *res;
814
815 res = cube_union_v0(a, b);
816
817 PG_FREE_IF_COPY(a, 0);
818 PG_FREE_IF_COPY(b, 1);
820}
NDBOX * cube_union_v0(NDBOX *a, NDBOX *b)
Definition: cube.c:749

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

◆ cube_union_v0()

NDBOX * cube_union_v0 ( NDBOX a,
NDBOX b 
)

Definition at line 749 of file cube.c.

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

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, size, 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 1583 of file cube.c.

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

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 1504 of file cube.c.

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

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 1347 of file cube.c.

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

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 1303 of file cube.c.

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

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 736 of file cube.c.

737{
738 NDBOX *retval;
739
740 retval = cube_union_v0(r1, r2);
741 *sizep = VARSIZE(retval);
742
743 return retval;
744}
#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 458 of file cube.c.

459{
461}
#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 392 of file cube.c.

393{
394 GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
395 NDBOX *query = PG_GETARG_NDBOX_P(1);
397
398 /* Oid subtype = PG_GETARG_OID(3); */
399 bool *recheck = (bool *) PG_GETARG_POINTER(4);
400 bool res;
401
402 /* All cases served by this function are exact */
403 *recheck = false;
404
405 /*
406 * if entry is not leaf, use g_cube_internal_consistent, else use
407 * g_cube_leaf_consistent
408 */
409 if (GIST_LEAF(entry))
411 query, strategy);
412 else
414 query, strategy);
415
416 PG_FREE_IF_COPY(query, 1);
418}
bool g_cube_leaf_consistent(NDBOX *key, NDBOX *query, StrategyNumber strategy)
Definition: cube.c:680
bool g_cube_internal_consistent(NDBOX *key, NDBOX *query, StrategyNumber strategy)
Definition: cube.c:709
#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, PG_RETURN_BOOL, and res.

◆ g_cube_decompress()

Datum g_cube_decompress ( PG_FUNCTION_ARGS  )

Definition at line 464 of file cube.c.

465{
466 GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
467 NDBOX *key = DatumGetNDBOXP(entry->key);
468
469 if (key != DatumGetNDBOXP(entry->key))
470 {
471 GISTENTRY *retval = (GISTENTRY *) palloc(sizeof(GISTENTRY));
472
474 entry->rel, entry->page,
475 entry->offset, false);
476 PG_RETURN_POINTER(retval);
477 }
478 PG_RETURN_POINTER(entry);
479}
#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 1399 of file cube.c.

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

712{
713 bool retval;
714
715 switch (strategy)
716 {
718 retval = (bool) cube_overlap_v0(key, query);
719 break;
723 retval = (bool) cube_contains_v0(key, query);
724 break;
727 retval = (bool) cube_overlap_v0(key, query);
728 break;
729 default:
730 retval = false;
731 }
732 return retval;
733}
#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 680 of file cube.c.

683{
684 bool retval;
685
686 switch (strategy)
687 {
689 retval = cube_overlap_v0(key, query);
690 break;
692 retval = (cube_cmp_v0(key, query) == 0);
693 break;
696 retval = cube_contains_v0(key, query);
697 break;
700 retval = cube_contains_v0(query, key);
701 break;
702 default:
703 retval = false;
704 }
705 return retval;
706}

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 487 of file cube.c.

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

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 512 of file cube.c.

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

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

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 426 of file cube.c.

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

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  )

◆ rt_cube_size()

void rt_cube_size ( NDBOX a,
double *  size 
)

Definition at line 911 of file cube.c.

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

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

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

Variable Documentation

◆ PG_MODULE_MAGIC

PG_MODULE_MAGIC

Definition at line 20 of file cube.c.