PostgreSQL Source Code: contrib/cube/cube.c Source File (original) (raw)
1
2
3
4
5
6
7
8
10
11#include <math.h>
12
19
21 .name = "cube",
22 .version = PG_VERSION
23);
24
25
26
27
28#define ARRPTR(x) ( (double *) ARR_DATA_PTR(x) )
29#define ARRNELEMS(x) ArrayGetNItems( ARR_NDIM(x), ARR_DIMS(x))
30
31
32
33
50
51
52
53
54
63
64
65
66
74
75
76
77
78
85
86
87
88
94
95
96
97
106
107
108
109
110static double distance_1D(double a1, double a2, double b1, double b2);
112
113
114
115
116
117
118
119
122{
125 Size scanbuflen;
127
129
130 cube_yyparse(&result, scanbuflen, fcinfo->context, scanner);
131
132
134
136}
137
138
139
140
141
144{
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
163 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
164 errmsg("can't extend cube"),
165 errdetail("A cube cannot have more than %d dimensions.",
167
170 (errcode(ERRCODE_ARRAY_ELEMENT_ERROR),
171 errmsg("UR and LL arrays must be of same length")));
172
175
176
177 point = true;
179 {
181 {
182 point = false;
183 break;
184 }
185 }
186
191
194
195 if (!point)
196 {
198 result->x[i + dim] = dll[i];
199 }
200 else
202
204}
205
206
207
208
211{
214 int i;
215 int dim;
216 int size;
217 double *dur;
218
221 (errcode(ERRCODE_ARRAY_ELEMENT_ERROR),
222 errmsg("cannot work with arrays containing NULLs")));
223
227 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
228 errmsg("array is too long"),
229 errdetail("A cube cannot have more than %d dimensions.",
231
233
239
242
244}
245
248{
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
263
267 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
268 errmsg("array is too long"),
269 errdetail("A cube cannot have more than %d dimensions.",
271
276
279
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];
288 result->x[i + dim] = c->x[dx[i] + DIM(c) - 1];
289 }
290
293}
294
297{
300 int dim = DIM(cube);
301 int i;
302
304
307 {
308 if (i > 0)
311 }
313
315 {
318 {
319 if (i > 0)
322 }
324 }
325
328}
329
330
331
332
335{
340
345
348
350}
351
352
353
354
357{
363
368 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
369 errmsg("cube dimension is too large"),
370 errdetail("A cube cannot have more than %d dimensions.",
376 cube->header = header;
379
381}
382
383
384
385
386
387
388
389
390
391
392
393
396{
400
401
403 bool res;
404
405
406 *recheck = false;
407
408
409
410
411
414 query, strategy);
415 else
417 query, strategy);
418
421}
422
423
424
425
426
427
430{
435 int i;
436
438
439
440
441
443
444 for (i = 1; i < entryvec->n; i++)
445 {
448 sizep);
449 tmp = out;
450 }
451
453}
454
455
456
457
458
459
462{
464}
465
468{
471
473 {
475
478 entry->offset, false);
480 }
482}
483
484
485
486
487
488
491{
496 double tmp1,
497 tmp2;
498
503 *result = (float) (tmp1 - tmp2);
504
506}
507
508
509
510
511
512
513
516{
520 j;
521 NDBOX *datum_alpha,
522 *datum_beta;
524 *datum_r;
526 *union_dl,
527 *union_dr;
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;
540 seed_2 = 2;
542 *right;
544
545 maxoff = entryvec->n - 2;
546 nbytes = (maxoff + 2) * sizeof(OffsetNumber);
549
550 firsttime = true;
551 waste = 0.0;
552
554 {
557 {
559
560
561
562 union_d = cube_union_v0(datum_alpha, datum_beta);
568 size_waste = size_union - size_inter;
569
570
571
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
588
590 datum_l = cube_union_v0(datum_alpha, datum_alpha);
595
596
597
598
599
600
601
602
603
604
605
606
607
610 {
611
612
613
614
615
616
617 if (i == seed_1)
618 {
619 *left++ = i;
621 continue;
622 }
623 else if (i == seed_2)
624 {
625 *right++ = i;
627 continue;
628 }
629
630
636
637
638 if (size_alpha - size_l < size_beta - size_r)
639 {
640 datum_l = union_dl;
641 size_l = size_alpha;
642 *left++ = i;
644 }
645 else
646 {
647 datum_r = union_dr;
648 size_r = size_beta;
649 *right++ = i;
651 }
652 }
654
657
659}
660
661
662
663
666{
670
672 *result = true;
673 else
674 *result = false;
675
677}
678
679
680
681
682bool
686{
687 bool retval;
688
689 switch (strategy)
690 {
693 break;
696 break;
700 break;
704 break;
705 default:
706 retval = false;
707 }
708 return retval;
709}
710
711bool
715{
716 bool retval;
717
718 switch (strategy)
719 {
722 break;
727 break;
731 break;
732 default:
733 retval = false;
734 }
735 return retval;
736}
737
740{
742
744 *sizep = VARSIZE(retval);
745
746 return retval;
747}
748
749
750
753{
754 int i;
756 int dim;
757 int size;
758
759
761 return a;
762
763
765 {
767
769 a = tmp;
770 }
772
777
778
779 for (i = 0; i < DIM(b); i++)
780 {
785 }
786
788 {
791 );
792 result->x[i + dim] = Max(0,
794 );
795 }
796
797
798
799
800
802 {
806 }
807
808 return result;
809}
810
813{
817
819
823}
824
825
828{
832 bool swapped = false;
833 int i;
834 int dim;
835 int size;
836
837
839 {
841
843 a = tmp;
844 swapped = true;
845 }
847
852
853
854 for (i = 0; i < DIM(b); i++)
855 {
860 }
861
863 {
866 );
869 );
870 }
871
872
873
874
875
877 {
879 result = repalloc(result, size);
882 }
883
884 if (swapped)
885 {
888 }
889 else
890 {
893 }
894
895
896
897
899}
900
901
904{
906 double result;
907
911}
912
913void
915{
916 double result;
917 int i;
918
920 {
921
922 result = 0.0;
923 }
925 {
926
927 result = 0.0;
928 }
929 else
930 {
931 result = 1.0;
932 for (i = 0; i < DIM(a); i++)
934 }
935 *size = result;
936}
937
938
939
942{
943 int i;
944 int dim;
945
947
948
950 {
953 return 1;
956 return -1;
957 }
959 {
962 return 1;
965 return -1;
966 }
967
968
970 {
971 for (i = dim; i < DIM(a); i++)
972 {
974 return 1;
976 return -1;
977 }
978 for (i = dim; i < DIM(a); i++)
979 {
981 return 1;
983 return -1;
984 }
985
986
987
988
989
990 return 1;
991 }
993 {
994 for (i = dim; i < DIM(b); i++)
995 {
997 return -1;
999 return 1;
1000 }
1001 for (i = dim; i < DIM(b); i++)
1002 {
1004 return -1;
1006 return 1;
1007 }
1008
1009
1010
1011
1012
1013 return -1;
1014 }
1015
1016
1017 return 0;
1018}
1019
1022{
1026
1028
1032}
1033
1034
1037{
1041
1043
1047}
1048
1049
1052{
1056
1058
1062}
1063
1064
1067{
1071
1073
1077}
1078
1079
1082{
1086
1088
1092}
1093
1094
1097{
1101
1103
1107}
1108
1109
1112{
1116
1118
1122}
1123
1124
1125
1126
1127bool
1129{
1130 int i;
1131
1132 if ((a == NULL) || (b == NULL))
1133 return false;
1134
1136 {
1137
1138
1139
1140
1141
1143 {
1145 return false;
1147 return false;
1148 }
1149 }
1150
1151
1153 {
1156 return false;
1159 return false;
1160 }
1161
1162 return true;
1163}
1164
1167{
1170 bool res;
1171
1173
1177}
1178
1179
1180
1183{
1186 bool res;
1187
1189
1193}
1194
1195
1196
1197bool
1199{
1200 int i;
1201
1202 if ((a == NULL) || (b == NULL))
1203 return false;
1204
1205
1207 {
1209
1211 a = tmp;
1212 }
1213
1214
1215 for (i = 0; i < DIM(b); i++)
1216 {
1218 return false;
1220 return false;
1221 }
1222
1223
1225 {
1227 return false;
1229 return false;
1230 }
1231
1232 return true;
1233}
1234
1235
1238{
1241 bool res;
1242
1244
1248}
1249
1250
1251
1252
1253
1254
1255
1258{
1261 bool swapped = false;
1262 double d,
1263 distance;
1264 int i;
1265
1266
1268 {
1270
1272 a = tmp;
1273 swapped = true;
1274 }
1275
1276 distance = 0.0;
1277
1278 for (i = 0; i < DIM(b); i++)
1279 {
1281 distance += d * d;
1282 }
1283
1284
1286 {
1288 distance += d * d;
1289 }
1290
1291 if (swapped)
1292 {
1295 }
1296 else
1297 {
1300 }
1301
1303}
1304
1307{
1310 bool swapped = false;
1311 double distance;
1312 int i;
1313
1314
1316 {
1318
1320 a = tmp;
1321 swapped = true;
1322 }
1323
1324 distance = 0.0;
1325
1326 for (i = 0; i < DIM(b); i++)
1329
1330
1333 0.0, 0.0));
1334
1335 if (swapped)
1336 {
1339 }
1340 else
1341 {
1344 }
1345
1347}
1348
1351{
1354 bool swapped = false;
1355 double d,
1356 distance;
1357 int i;
1358
1359
1361 {
1363
1365 a = tmp;
1366 swapped = true;
1367 }
1368
1369 distance = 0.0;
1370
1371 for (i = 0; i < DIM(b); i++)
1372 {
1375 if (d > distance)
1376 distance = d;
1377 }
1378
1379
1381 {
1383 if (d > distance)
1384 distance = d;
1385 }
1386
1387 if (swapped)
1388 {
1391 }
1392 else
1393 {
1396 }
1397
1399}
1400
1403{
1407 double retval;
1408
1410 {
1411
1412
1413
1414
1417 bool inverse = false;
1418
1419
1420 if (coord == 0)
1422 (errcode(ERRCODE_ARRAY_ELEMENT_ERROR),
1423 errmsg("zero cube index is not defined")));
1424
1425
1426 if (coord < 0)
1427 {
1428 coord = -coord;
1429 inverse = true;
1430 }
1431
1432 if (coord <= 2 * DIM(cube))
1433 {
1434
1435 int index = (coord - 1) / 2;
1436
1437
1438 bool upper = ((coord - 1) % 2 == 1);
1439
1441 {
1443 }
1444 else
1445 {
1446 if (isLeaf)
1447 {
1448
1451 else
1453 }
1454 else
1455 {
1456
1457
1458
1459
1460
1461
1462
1463 if (!inverse)
1465 else
1467 }
1468 }
1469 }
1470 else
1471 {
1472 retval = 0.0;
1473 }
1474
1475
1476 if (inverse)
1477 retval = -retval;
1478 }
1479 else
1480 {
1482
1483 switch (strategy)
1484 {
1488 break;
1492 break;
1496 break;
1497 default:
1498 elog(ERROR, "unrecognized cube strategy number: %d", strategy);
1499 retval = 0;
1500 break;
1501 }
1502 }
1504}
1505
1506static double
1508{
1509
1510 if ((a1 <= b1) && (a2 <= b1) && (a1 <= b2) && (a2 <= b2))
1512
1513
1514 if ((a1 > b1) && (a2 > b1) && (a1 > b2) && (a2 > b2))
1516
1517
1518 return 0.0;
1519}
1520
1521
1524{
1526 bool result;
1527
1531}
1532
1533static bool
1535{
1536 int i;
1537
1539 return true;
1540
1541
1542
1543
1544
1545
1546
1547
1548 for (i = 0; i < DIM(cube); i++)
1549 {
1551 return false;
1552 }
1553 return true;
1554}
1555
1556
1559{
1562
1565}
1566
1567
1570{
1573 double result;
1574
1575 if (DIM(c) >= n && n > 0)
1577 else
1578 result = 0;
1579
1582}
1583
1584
1587{
1590 double result;
1591
1592 if (DIM(c) >= n && n > 0)
1594 else
1595 result = 0;
1596
1599}
1600
1601
1602
1603
1604
1605
1608{
1611
1612 if (coord <= 0 || coord > 2 * DIM(cube))
1614 (errcode(ERRCODE_ARRAY_ELEMENT_ERROR),
1615 errmsg("cube index %d is out of bounds", coord)));
1616
1619 else
1621}
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1649{
1652 bool inverse = false;
1654
1655
1656 if (coord == 0)
1658 (errcode(ERRCODE_ARRAY_ELEMENT_ERROR),
1659 errmsg("zero cube index is not defined")));
1660
1661
1662 if (coord < 0)
1663 {
1664 coord = -coord;
1665 inverse = true;
1666 }
1667
1668 if (coord <= 2 * DIM(cube))
1669 {
1670
1671 int index = (coord - 1) / 2;
1672
1673
1674 bool upper = ((coord - 1) % 2 == 1);
1675
1677 {
1679 }
1680 else
1681 {
1684 else
1686 }
1687 }
1688 else
1689 {
1690
1691
1692
1693
1694
1695 result = 0.0;
1696 }
1697
1698
1699 if (inverse)
1700 result = -result;
1701
1703}
1704
1705
1708{
1713 int dim = 0;
1714 int size;
1715 int i,
1716 j;
1717
1720 if (r > 0 && n > 0)
1721 dim = n;
1724
1729
1730 for (i = 0, j = dim; i < DIM(a); i++, j++)
1731 {
1733 {
1736 }
1737 else
1738 {
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
1749 for (; i < dim; i++, j++)
1750 {
1753 }
1754
1755
1756
1757
1758
1760 {
1764 }
1765
1768}
1769
1770
1773{
1776 int size;
1777
1784
1786}
1787
1788
1791{
1795 int size;
1796
1797 if (x0 == x1)
1798 {
1804 result->x[0] = x0;
1805 }
1806 else
1807 {
1812 result->x[0] = x0;
1813 result->x[1] = x1;
1814 }
1815
1817}
1818
1819
1820
1823{
1827 int size;
1828 int i;
1829
1832 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
1833 errmsg("can't extend cube"),
1834 errdetail("A cube cannot have more than %d dimensions.",
1836
1838 {
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 {
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
1865}
1866
1867
1870{
1875 int size;
1876 int i;
1877
1880 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
1881 errmsg("can't extend cube"),
1882 errdetail("A cube cannot have more than %d dimensions.",
1884
1885 if (IS_POINT(cube) && (x1 == x2))
1886 {
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 {
1902 for (i = 0; i < DIM(cube); i++)
1903 {
1906 }
1907 result->x[DIM(result) - 1] = x1;
1908 result->x[2 * DIM(result) - 1] = x2;
1909 }
1910
1913}
Datum idx(PG_FUNCTION_ARGS)
#define PG_GETARG_ARRAYTYPE_P(n)
bool array_contains_nulls(ArrayType *array)
Datum cube_gt(PG_FUNCTION_ARGS)
Datum cube_eq(PG_FUNCTION_ARGS)
Datum cube_le(PG_FUNCTION_ARGS)
Datum cube_coord(PG_FUNCTION_ARGS)
Datum distance_taxicab(PG_FUNCTION_ARGS)
Datum cube_ll_coord(PG_FUNCTION_ARGS)
Datum cube_subset(PG_FUNCTION_ARGS)
Datum cube_distance(PG_FUNCTION_ARGS)
static bool cube_is_point_internal(NDBOX *cube)
bool cube_overlap_v0(NDBOX *a, NDBOX *b)
bool g_cube_leaf_consistent(NDBOX *key, NDBOX *query, StrategyNumber strategy)
bool cube_contains_v0(NDBOX *a, NDBOX *b)
Datum distance_chebyshev(PG_FUNCTION_ARGS)
Datum g_cube_picksplit(PG_FUNCTION_ARGS)
int32 cube_cmp_v0(NDBOX *a, NDBOX *b)
Datum cube_dim(PG_FUNCTION_ARGS)
Datum g_cube_union(PG_FUNCTION_ARGS)
Datum cube_in(PG_FUNCTION_ARGS)
Datum cube_enlarge(PG_FUNCTION_ARGS)
Datum cube_c_f8(PG_FUNCTION_ARGS)
Datum g_cube_same(PG_FUNCTION_ARGS)
Datum cube_ur_coord(PG_FUNCTION_ARGS)
Datum g_cube_distance(PG_FUNCTION_ARGS)
Datum cube_contained(PG_FUNCTION_ARGS)
Datum cube_cmp(PG_FUNCTION_ARGS)
Datum cube_a_f8_f8(PG_FUNCTION_ARGS)
PG_MODULE_MAGIC_EXT(.name="cube",.version=PG_VERSION)
Datum g_cube_consistent(PG_FUNCTION_ARGS)
NDBOX * cube_union_v0(NDBOX *a, NDBOX *b)
static double distance_1D(double a1, double a2, double b1, double b2)
Datum cube_size(PG_FUNCTION_ARGS)
Datum cube_recv(PG_FUNCTION_ARGS)
void rt_cube_size(NDBOX *a, double *size)
Datum cube_lt(PG_FUNCTION_ARGS)
Datum cube_contains(PG_FUNCTION_ARGS)
Datum cube_union(PG_FUNCTION_ARGS)
Datum cube_f8_f8(PG_FUNCTION_ARGS)
Datum g_cube_decompress(PG_FUNCTION_ARGS)
Datum cube_f8(PG_FUNCTION_ARGS)
Datum cube_a_f8(PG_FUNCTION_ARGS)
Datum cube_c_f8_f8(PG_FUNCTION_ARGS)
Datum cube_coord_llur(PG_FUNCTION_ARGS)
Datum cube_inter(PG_FUNCTION_ARGS)
Datum g_cube_compress(PG_FUNCTION_ARGS)
PG_FUNCTION_INFO_V1(cube_in)
Datum cube_is_point(PG_FUNCTION_ARGS)
bool g_cube_internal_consistent(NDBOX *key, NDBOX *query, StrategyNumber strategy)
NDBOX * g_cube_binary_union(NDBOX *r1, NDBOX *r2, int *sizep)
Datum cube_send(PG_FUNCTION_ARGS)
Datum cube_overlap(PG_FUNCTION_ARGS)
Datum cube_ge(PG_FUNCTION_ARGS)
Datum cube_out(PG_FUNCTION_ARGS)
Datum g_cube_penalty(PG_FUNCTION_ARGS)
Datum cube_ne(PG_FUNCTION_ARGS)
int cube_yyparse(NDBOX **result, Size scanbuflen, struct Node *escontext, yyscan_t yyscanner)
#define SET_DIM(cube, _dim)
void cube_scanner_init(const char *str, Size *scanbuflen, yyscan_t *yyscannerp)
#define DatumGetNDBOXP(x)
#define LL_COORD(cube, i)
#define CubeKNNDistanceCoord
void cube_scanner_finish(yyscan_t yyscanner)
#define CubeKNNDistanceEuclid
#define PG_RETURN_NDBOX_P(x)
#define CubeKNNDistanceTaxicab
#define SET_POINT_BIT(cube)
#define CubeKNNDistanceChebyshev
#define PG_GETARG_NDBOX_P(x)
#define UR_COORD(cube, i)
int errdetail(const char *fmt,...)
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
char * float8out_internal(double num)
#define PG_FREE_IF_COPY(ptr, n)
#define PG_RETURN_BYTEA_P(x)
#define DirectFunctionCall2(func, arg1, arg2)
#define PG_GETARG_FLOAT8(n)
#define PG_RETURN_FLOAT8(x)
#define PG_GETARG_POINTER(n)
#define PG_RETURN_CSTRING(x)
#define PG_GETARG_DATUM(n)
#define PG_GETARG_CSTRING(n)
#define PG_GETARG_UINT16(n)
#define PG_RETURN_INT32(x)
#define PG_GETARG_INT32(n)
#define PG_RETURN_DATUM(x)
#define PG_RETURN_POINTER(x)
#define PG_RETURN_BOOL(x)
#define GistPageIsLeaf(page)
#define gistentryinit(e, k, r, pg, o, l)
static const FormData_pg_attribute a1
static const FormData_pg_attribute a2
if(TABLE==NULL||TABLE_index==NULL)
void * repalloc(void *pointer, Size size)
void * palloc0(Size size)
#define OffsetNumberNext(offsetNumber)
#define FirstOffsetNumber
Datum upper(PG_FUNCTION_ARGS)
static Datum PointerGetDatum(const void *X)
static float8 DatumGetFloat8(Datum X)
unsigned int pq_getmsgint(StringInfo msg, int b)
float8 pq_getmsgfloat8(StringInfo msg)
void pq_begintypsend(StringInfo buf)
bytea * pq_endtypsend(StringInfo buf)
void pq_sendfloat8(StringInfo buf, float8 f)
static void pq_sendint32(StringInfo buf, uint32 i)
#define RTOldContainsStrategyNumber
#define RTOverlapStrategyNumber
#define RTSameStrategyNumber
#define RTContainsStrategyNumber
#define RTOldContainedByStrategyNumber
#define RTContainedByStrategyNumber
void appendStringInfoString(StringInfo str, const char *s)
void appendStringInfoChar(StringInfo str, char ch)
void initStringInfo(StringInfo str)
StringInfoData * StringInfo
GISTENTRY vector[FLEXIBLE_ARRAY_MEMBER]
double x[FLEXIBLE_ARRAY_MEMBER]
#define SET_VARSIZE(PTR, len)