PostgreSQL Source Code: src/backend/utils/adt/geo_ops.c Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
26
27#include <math.h>
28#include <limits.h>
30#include <ctype.h>
31
36#include "utils/fmgrprotos.h"
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
74{
77
78
88
89
96
97
108
109
122
123
125
126
133
134
136 const char *type_name, const char *orig_string,
137 Node *escontext);
140 const char *type_name, const char *orig_string,
141 Node *escontext);
143static int pair_count(char *s, char delim);
145 bool *isopen, char **endptr_p,
146 const char *type_name, const char *orig_string,
147 Node *escontext);
149
150
151
152
153
154
155
156
157#define LDELIM '('
158#define RDELIM ')'
159#define DELIM ','
160#define LDELIM_EP '['
161#define RDELIM_EP ']'
162#define LDELIM_C '<'
163#define RDELIM_C '>'
164#define LDELIM_L '{'
165#define RDELIM_L '}'
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193static bool
195 const char *type_name, const char *orig_string,
196 Node *escontext)
197{
198 *x = float8in_internal(num, endptr_p, type_name, orig_string, escontext);
200}
201
202static void
204{
206
209}
210
211static bool
213 const char *type_name, const char *orig_string,
214 Node *escontext)
215{
216 bool has_delim;
217
218 while (isspace((unsigned char) *str))
220 if ((has_delim = (*str == LDELIM)))
222
224 return false;
225
227 goto fail;
228
230 return false;
231
232 if (has_delim)
233 {
235 goto fail;
236 while (isspace((unsigned char) *str))
238 }
239
240
241 if (endptr_p)
242 *endptr_p = str;
243 else if (*str != '\0')
244 goto fail;
245 return true;
246
247fail:
248 ereturn(escontext, false,
249 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
250 errmsg("invalid input syntax for type %s: \"%s\"",
251 type_name, orig_string)));
252}
253
254static void
256{
259
263}
264
265static bool
267 bool *isopen, char **endptr_p,
268 const char *type_name, const char *orig_string,
269 Node *escontext)
270{
271 int depth = 0;
272 char *cp;
273 int i;
274
275 while (isspace((unsigned char) *str))
278 {
279
280 if (!opentype)
281 goto fail;
282 depth++;
284 }
286 {
287 cp = (str + 1);
288 while (isspace((unsigned char) *cp))
289 cp++;
291 {
292 depth++;
293 str = cp;
294 }
296 {
297 depth++;
298 str = cp;
299 }
300 }
301
302 for (i = 0; i < npts; i++)
303 {
305 escontext))
306 return false;
309 p++;
310 }
311
312 while (depth > 0)
313 {
315 {
316 depth--;
318 while (isspace((unsigned char) *str))
320 }
321 else
322 goto fail;
323 }
324
325
326 if (endptr_p)
327 *endptr_p = str;
328 else if (*str != '\0')
329 goto fail;
330 return true;
331
332fail:
333 ereturn(escontext, false,
334 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
335 errmsg("invalid input syntax for type %s: \"%s\"",
336 type_name, orig_string)));
337}
338
339static char *
341{
343 int i;
344
346
348 {
351 break;
354 break;
356 break;
357 }
358
359 for (i = 0; i < npts; i++)
360 {
361 if (i > 0)
366 pt++;
367 }
368
370 {
373 break;
376 break;
378 break;
379 }
380
381 return str.data;
382}
383
384
385
386
387
388
389
390
391static int
393{
394 int ndelim = 0;
395
396 while ((s = strchr(s, delim)) != NULL)
397 {
398 ndelim++;
399 s++;
400 }
401 return (ndelim % 2) ? ((ndelim + 1) / 2) : -1;
402}
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
423{
425 Node *escontext = fcinfo->context;
427 bool isopen;
429 y;
430
432 escontext))
434
435
437 {
441 }
443 {
447 }
448
450}
451
452
453
456{
458
460}
461
462
463
464
467{
469 BOX *box;
471 y;
472
474
479
480
482 {
486 }
488 {
492 }
493
495}
496
497
498
499
502{
505
512}
513
514
515
516
517static inline void
519{
521 {
524 }
525 else
526 {
529 }
531 {
534 }
535 else
536 {
539 }
540}
541
542
543
544
545
546
547
548
549
552{
555
558}
559
560
561
564{
567
569}
570
571static bool
573{
578}
579
580
581
584{
587
589}
590
591
592
593
594
595
596
599{
602
604}
605
606
607
610{
613
615}
616
617
618
619
620
621
622
625{
628
630}
631
632
633
636{
639
641}
642
643
644
645
648{
651
653}
654
655
656
659{
662
664}
665
666
667
668
671{
674
676}
677
678
679
682{
685
687}
688
689
690
693{
696
698}
699
700
701
702
703static bool
705{
706 return FPge(contains_box->high.x, contained_box->high.x) &&
707 FPle(contains_box->low.x, contained_box->low.x) &&
709 FPle(contains_box->low.y, contained_box->low.y);
710}
711
712
713
714
715
716
717
718
719
720
723{
726
728}
729
732{
735
737}
738
739
740
741
742
745{
748
750}
751
754{
757
759}
760
763{
766
768}
769
772{
775
777}
778
781{
784
786}
787
788
789
790
791
792
793
794
797{
799
801}
802
803
804
805
806
809{
811
813}
814
815
816
817
818
821{
823
825}
826
827
828
829
830
833{
837 b;
838
841
843}
844
845
846
847
850{
853
855
857}
858
859
860
861
864{
866}
867
868
869
870
871static void
873{
876}
877
878
879
880
881
884{
886}
887
888
889
890
891
894{
896}
897
898
899
900
901
902
903
904
905
906
909{
912 BOX *result;
913
914 if ((box1, box2))
916
918
923
925}
926
927
928
929
930
931
934{
937
939
941}
942
943
944
945
946
947
948
949static bool
951{
952
954 return false;
955 if (*s++ != DELIM)
956 goto fail;
958 return false;
959 if (*s++ != DELIM)
960 goto fail;
962 return false;
964 goto fail;
965 while (isspace((unsigned char) *s))
966 s++;
967 if (*s != '\0')
968 goto fail;
969 return true;
970
971fail:
972 ereturn(escontext, false,
973 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
974 errmsg("invalid input syntax for type %s: \"%s\"",
975 "line", str)));
976}
977
980{
982 Node *escontext = fcinfo->context;
985 bool isopen;
986 char *s;
987
989 while (isspace((unsigned char) *s))
990 s++;
992 {
997 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
998 errmsg("invalid line specification: A and B cannot both be zero")));
999 }
1000 else
1001 {
1002 if ((s, true, 2, &lseg.p[0], &isopen, NULL, "line", str,
1003 escontext))
1007 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
1008 errmsg("invalid line specification: must be two distinct points")));
1009
1010
1011
1012
1013
1014
1016 }
1017
1019}
1020
1021
1024{
1029
1032}
1033
1034
1035
1036
1039{
1042
1044
1048
1051 (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
1052 errmsg("invalid line specification: A and B cannot both be zero")));
1053
1055}
1056
1057
1058
1059
1062{
1065
1071}
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082static inline void
1084{
1085 if (isinf(m))
1086 {
1087
1088 result->A = -1.0;
1089 result->B = 0.0;
1091 }
1092 else if (m == 0)
1093 {
1094
1095 result->A = 0.0;
1096 result->B = -1.0;
1098 }
1099 else
1100 {
1101
1102 result->A = m;
1103 result->B = -1.0;
1105
1106 if (result->C == 0.0)
1107 result->C = 0.0;
1108 }
1109}
1110
1111
1112
1113
1116{
1120
1123 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1124 errmsg("invalid line specification: must be two distinct points")));
1125
1127
1129}
1130
1131
1132
1133
1134
1135
1138{
1141
1143}
1144
1147{
1150
1152}
1153
1156{
1159
1168
1171}
1172
1175{
1177
1179}
1180
1183{
1185
1187}
1188
1189
1190
1191
1192
1195{
1199
1200
1201 if (unlikely(isnan(l1->A) || isnan(l1->B) || isnan(l1->C) ||
1202 isnan(l2->A) || isnan(l2->B) || isnan(l2->C)))
1203 {
1207 }
1208
1209
1212 else if ((l2->B))
1214 else if ((l2->C))
1216 else
1217 ratio = 1.0;
1218
1222}
1223
1224
1225
1226
1227
1228
1229
1230
1231
1234{
1236 return 0.0;
1240}
1241
1242
1243
1244
1245
1248{
1252 return 0.0;
1254}
1255
1256
1257
1258
1259
1262{
1266
1269
1270 if ((l1->A) && !isnan(l1->A) &&
(l2->A) && !isnan(l2->A))
1272 else if ((l1->B) && !isnan(l1->B) &&
(l2->B) && !isnan(l2->B))
1274 else
1275 ratio = 1.0;
1276
1280}
1281
1282
1283
1284
1287{
1291
1293
1297}
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313static bool
1315{
1317 y;
1318
1320 {
1322 return false;
1323
1329 }
1330 else if ((l2->B))
1331 {
1333 return false;
1334
1340 }
1341 else
1342 return false;
1343
1344
1345 if (x == 0.0)
1346 x = 0.0;
1347 if (y == 0.0)
1348 y = 0.0;
1349
1350 if (result != NULL)
1352
1353 return true;
1354}
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1381{
1384 int i,
1385 j;
1386
1389
1390 for (i = 0; i < path->npts; i++)
1391 {
1392 j = (i + 1) % path->npts;
1395 }
1396
1398}
1399
1400
1403{
1405 Node *escontext = fcinfo->context;
1407 bool isopen;
1408 char *s;
1409 int npts;
1410 int size;
1411 int base_size;
1412 int depth = 0;
1413
1416 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
1417 errmsg("invalid input syntax for type %s: \"%s\"",
1418 "path", str)));
1419
1420 s = str;
1421 while (isspace((unsigned char) *s))
1422 s++;
1423
1424
1425 if ((*s == LDELIM) && (strrchr(s, LDELIM) == s))
1426 {
1427 s++;
1428 depth++;
1429 }
1430
1431 base_size = sizeof(path->p[0]) * npts;
1432 size = offsetof(PATH, p) + base_size;
1433
1434
1435 if (base_size / npts != sizeof(path->p[0]) || size <= base_size)
1437 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
1438 errmsg("too many points requested")));
1439
1441
1443 path->npts = npts;
1444
1445 if ((s, true, npts, &(path->p[0]), &isopen, &s, "path", str,
1446 escontext))
1448
1449 if (depth >= 1)
1450 {
1453 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
1454 errmsg("invalid input syntax for type %s: \"%s\"",
1455 "path", str)));
1456 while (isspace((unsigned char) *s))
1457 s++;
1458 }
1459 if (*s != '\0')
1461 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
1462 errmsg("invalid input syntax for type %s: \"%s\"",
1463 "path", str)));
1464
1465 path->closed = (!isopen);
1466
1467 path->dummy = 0;
1468
1470}
1471
1472
1475{
1477
1479}
1480
1481
1482
1483
1484
1485
1486
1489{
1492 int closed;
1495 int size;
1496
1499 if (npts <= 0 || npts >= (int32) ((INT_MAX - offsetof(PATH, p)) / sizeof(Point)))
1501 (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
1502 errmsg("invalid number of points in external \"path\" value")));
1503
1504 size = offsetof(PATH, p) + sizeof(path->p[0]) * npts;
1506
1508 path->npts = npts;
1509 path->closed = (closed ? 1 : 0);
1510
1511 path->dummy = 0;
1512
1513 for (i = 0; i < npts; i++)
1514 {
1517 }
1518
1520}
1521
1522
1523
1524
1527{
1531
1535 for (i = 0; i < path->npts; i++)
1536 {
1539 }
1541}
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1554{
1557
1559}
1560
1563{
1566
1568}
1569
1572{
1575
1577}
1578
1581{
1584
1586}
1587
1590{
1593
1595}
1596
1597
1598
1599
1600
1603{
1605
1607}
1608
1611{
1613
1615}
1616
1619{
1621
1623}
1624
1625
1628{
1630
1631 path->closed = true;
1632
1634}
1635
1638{
1640
1641 path->closed = false;
1642
1644}
1645
1646
1647
1648
1649
1650
1651
1654{
1658 b2;
1659 int i,
1660 j;
1662 seg2;
1663
1665
1668 for (i = 1; i < p1->npts; i++)
1669 {
1674 }
1677 for (i = 1; i < p2->npts; i++)
1678 {
1683 }
1684 if ((&b1, &b2))
1686
1687
1688 for (i = 0; i < p1->npts; i++)
1689 {
1690 int iprev;
1691
1692 if (i > 0)
1693 iprev = i - 1;
1694 else
1695 {
1697 continue;
1698 iprev = p1->npts - 1;
1699 }
1700
1701 for (j = 0; j < p2->npts; j++)
1702 {
1703 int jprev;
1704
1705 if (j > 0)
1706 jprev = j - 1;
1707 else
1708 {
1710 continue;
1711 jprev = p2->npts - 1;
1712 }
1713
1718 }
1719 }
1720
1721
1723}
1724
1725
1726
1727
1728
1731{
1734 float8 min = 0.0;
1735 bool have_min = false;
1737 int i,
1738 j;
1740 seg2;
1741
1742 for (i = 0; i < p1->npts; i++)
1743 {
1744 int iprev;
1745
1746 if (i > 0)
1747 iprev = i - 1;
1748 else
1749 {
1751 continue;
1752 iprev = p1->npts - 1;
1753 }
1754
1755 for (j = 0; j < p2->npts; j++)
1756 {
1757 int jprev;
1758
1759 if (j > 0)
1760 jprev = j - 1;
1761 else
1762 {
1764 continue;
1765 jprev = p2->npts - 1;
1766 }
1767
1770
1772 if (!have_min || float8_lt(tmp, min))
1773 {
1774 min = tmp;
1775 have_min = true;
1776 }
1777 }
1778 }
1779
1780 if (!have_min)
1782
1784}
1785
1786
1787
1788
1789
1790
1793{
1795 float8 result = 0.0;
1796 int i;
1797
1798 for (i = 0; i < path->npts; i++)
1799 {
1800 int iprev;
1801
1802 if (i > 0)
1803 iprev = i - 1;
1804 else
1805 {
1807 continue;
1808 iprev = path->npts - 1;
1809 }
1810
1812 }
1813
1815}
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1832{
1835
1836
1837 pair_decode(str, &point->x, &point->y, NULL, "point", str, fcinfo->context);
1839}
1840
1843{
1845
1847}
1848
1849
1850
1851
1854{
1857
1862}
1863
1864
1865
1866
1869{
1872
1877}
1878
1879
1880
1881
1882
1883static inline void
1885{
1888}
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1902{
1905
1907}
1908
1911{
1914
1916}
1917
1920{
1923
1925}
1926
1929{
1932
1934}
1935
1938{
1941
1943}
1944
1947{
1950
1952}
1953
1956{
1959
1961}
1962
1965{
1968
1970}
1971
1972
1973
1974
1975
1976static inline bool
1978{
1979
1980 if (unlikely(isnan(pt1->x) || isnan(pt1->y) ||
1981 isnan(pt2->x) || isnan(pt2->y)))
1983
1984 return (FPeq(pt1->x, pt2->x) && FPeq(pt1->y, pt2->y));
1985}
1986
1987
1988
1989
1990
1991
1994{
1997
1999}
2000
2003{
2005}
2006
2009{
2012
2014}
2015
2016
2017
2018
2019
2020
2021
2024{
2025 if (FPeq(pt1->x, pt2->x))
2027 if (FPeq(pt1->y, pt2->y))
2028 return 0.0;
2030}
2031
2032
2033
2034
2035
2036
2037
2040{
2041 if (FPeq(pt1->x, pt2->x))
2042 return 0.0;
2043 if (FPeq(pt1->y, pt2->y))
2046}
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2066{
2068 Node *escontext = fcinfo->context;
2070 bool isopen;
2071
2072 if ((str, true, 2, &lseg->p[0], &isopen, NULL, "lseg", str,
2073 escontext))
2075
2077}
2078
2079
2082{
2084
2086}
2087
2088
2089
2090
2093{
2096
2098
2103
2105}
2106
2107
2108
2109
2112{
2115
2122}
2123
2124
2125
2126
2127
2130{
2134
2136
2138}
2139
2140
2141static inline void
2143{
2148}
2149
2150
2151
2152
2153
2156{
2157 return point_sl(&lseg->p[0], &lseg->p[1]);
2158}
2159
2160
2161
2162
2163
2166{
2168}
2169
2170
2173{
2175
2177}
2178
2179
2180
2181
2182
2183
2184
2185
2186
2189{
2192
2194}
2195
2196
2199{
2202
2204}
2205
2206
2207
2208
2211{
2214
2216}
2217
2220{
2222
2224}
2225
2228{
2230
2232}
2233
2234
2237{
2240
2243}
2244
2247{
2250
2253}
2254
2257{
2260
2263}
2264
2267{
2270
2273}
2274
2277{
2280
2283}
2284
2287{
2290
2293}
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2307{
2310
2312}
2313
2314
2317{
2320
2322
2325
2327}
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337static bool
2339{
2342
2345 return false;
2346
2347
2348
2349
2350
2352 return false;
2353
2354 if (result != NULL)
2355 *result = interpt;
2356
2357 return true;
2358}
2359
2362{
2366
2368
2372}
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2391{
2394
2396}
2397
2398
2399
2400
2403{
2406
2408}
2409
2410
2411
2412
2415{
2418
2420}
2421
2422
2423
2424
2427{
2430
2432}
2433
2436{
2437 float8 result = 0.0;
2438 bool have_min = false;
2440 int i;
2442
2444
2445
2446
2447
2448
2449 for (i = 0; i < path->npts; i++)
2450 {
2451 int iprev;
2452
2453 if (i > 0)
2454 iprev = i - 1;
2455 else
2456 {
2458 continue;
2459 iprev = path->npts - 1;
2460 }
2461
2464 if (!have_min || float8_lt(tmp, result))
2465 {
2466 result = tmp;
2467 have_min = true;
2468 }
2469 }
2470
2471 return result;
2472}
2473
2474
2475
2476
2479{
2482
2484}
2485
2486
2487
2488
2491{
2494
2496}
2497
2498
2499
2500
2503{
2506
2508}
2509
2510
2511
2512
2515{
2518
2520}
2521
2522
2523
2524
2527{
2530
2532}
2533
2534
2535
2536
2539{
2542
2544}
2545
2546
2547
2548
2551{
2554
2556}
2557
2558
2559
2560
2563{
2566
2568}
2569
2572{
2574
2575
2578 if (result < 0.0)
2579 result = 0.0;
2580
2581 return result;
2582}
2583
2584
2585
2586
2589{
2592
2594}
2595
2596
2597
2598
2601{
2604
2606}
2607
2608
2609
2610
2613{
2616
2618}
2619
2622{
2625
2627}
2628
2631{
2634 int i;
2636
2638 return 0.0;
2639
2640
2641 seg.p[0].x = poly->p[0].x;
2642 seg.p[0].y = poly->p[0].y;
2643 seg.p[1].x = poly->p[poly->npts - 1].x;
2644 seg.p[1].y = poly->p[poly->npts - 1].y;
2646
2647
2648 for (i = 0; i < poly->npts - 1; i++)
2649 {
2650 seg.p[0].x = poly->p[i].x;
2651 seg.p[0].y = poly->p[i].y;
2652 seg.p[1].x = poly->p[i + 1].x;
2653 seg.p[1].y = poly->p[i + 1].y;
2656 result = d;
2657 }
2658
2659 return result;
2660}
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674static bool
2676{
2679
2680
2681
2682
2683
2684
2687 return false;
2688
2689
2690
2691
2692
2694 return false;
2695 if (result != NULL)
2696 {
2697
2698
2699
2700
2701
2703 *result = lseg->p[0];
2705 *result = lseg->p[1];
2706 else
2707 *result = interpt;
2708 }
2709
2710 return true;
2711}
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2725{
2728
2729
2730
2731
2732
2733
2736 {
2737 if (result != NULL)
2738 *result = *point;
2739
2741 }
2742
2743 if (result != NULL)
2744 *result = closept;
2745
2746 return point_dt(&closept, point);
2747}
2748
2751{
2755
2757
2760
2762}
2763
2764
2765
2766
2767
2768
2769
2770
2773{
2776
2777
2778
2779
2780
2783
2784 if (result != NULL)
2785 *result = closept;
2786
2787 return point_dt(&closept, pt);
2788}
2789
2792{
2796
2798
2801
2803}
2804
2805
2806
2807
2808
2811{
2814 d;
2815
2816
2818 return 0.0;
2819
2820
2821
2822
2823
2827 {
2828 dist = d;
2829 if (result != NULL)
2830 *result = point;
2831 }
2832
2833
2836 {
2837 dist = d;
2838 if (result != NULL)
2839 *result = on_lseg->p[0];
2840 }
2843 {
2844 dist = d;
2845 if (result != NULL)
2846 *result = on_lseg->p[1];
2847 }
2848
2849 return dist;
2850}
2851
2854{
2858
2861
2863
2866
2868}
2869
2870
2871
2872
2873
2874
2875
2876
2879{
2881 d;
2883 closept;
2885
2887 {
2888 if (result != NULL)
2889 *result = *pt;
2890
2891 return 0.0;
2892 }
2893
2894
2899
2903 {
2904 dist = d;
2905 if (result != NULL)
2906 *result = closept;
2907 }
2908
2914 {
2915 dist = d;
2916 if (result != NULL)
2917 *result = closept;
2918 }
2919
2923 {
2924 dist = d;
2925 if (result != NULL)
2926 *result = closept;
2927 }
2928
2929 return dist;
2930}
2931
2934{
2938
2940
2943
2945}
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2961{
2963 dist2;
2964
2966 return 0.0;
2967
2970
2971 if (dist1 < dist2)
2972 {
2973 if (result != NULL)
2974 *result = lseg->p[0];
2975
2976 return dist1;
2977 }
2978 else
2979 {
2980 if (result != NULL)
2981 *result = lseg->p[1];
2982
2983 return dist2;
2984 }
2985}
2986
2989{
2993
2996
2998
3001
3003}
3004
3005
3006
3007
3008
3009
3010
3011
3014{
3016 d;
3018 closept;
3020
3022 return 0.0;
3023
3024
3029
3033 {
3034 dist = d;
3035 if (result != NULL)
3036 *result = closept;
3037 }
3038
3044 {
3045 dist = d;
3046 if (result != NULL)
3047 *result = closept;
3048 }
3049
3053 {
3054 dist = d;
3055 if (result != NULL)
3056 *result = closept;
3057 }
3058
3059 return dist;
3060}
3061
3064{
3068
3070
3073
3075}
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086static bool
3088{
3091 line->C));
3092}
3093
3096{
3099
3101}
3102
3103
3104
3105
3106
3107
3108static bool
3110{
3113 point_dt(&lseg->p[0], &lseg->p[1]));
3114}
3115
3118{
3121
3123}
3124
3125
3126
3127
3128
3129static bool
3131{
3132 return box->high.x >= point->x && box->low.x <= point->x &&
3133 box->high.y >= point->y && box->low.y <= point->y;
3134}
3135
3138{
3141
3143}
3144
3147{
3150
3152}
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3167{
3170 int i,
3171 n;
3173 b;
3174
3175
3177 {
3178 n = path->npts - 1;
3181 {
3186 }
3188 }
3189
3190
3192}
3193
3194
3195
3196
3197
3198
3199
3202{
3205
3208}
3209
3210
3211
3212
3213
3214
3215
3216static bool
3218{
3221}
3222
3225{
3228
3230}
3231
3232
3233
3234
3235
3236
3239{
3242
3244}
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262static bool
3264{
3265 BOX lbox;
3268
3273
3274
3275 if ((&lbox, box))
3276 return false;
3277
3278 if (result != NULL)
3279 {
3280 box_cn(&point, box);
3282 }
3283
3284
3287 return true;
3288
3289
3294 return true;
3295
3298 return true;
3299
3304 return true;
3305
3308 return true;
3309
3310
3311 return false;
3312}
3313
3316{
3319
3321}
3322
3323
3324
3325
3326
3329{
3334 p2;
3335
3336
3359
3360
3362}
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375static void
3377{
3378 int i;
3380 y1,
3381 x2,
3382 y2;
3383
3385
3388 for (i = 1; i < poly->npts; i++)
3389 {
3398 }
3399
3404}
3405
3406
3407
3408
3409
3410
3411
3412
3413
3416{
3418 Node *escontext = fcinfo->context;
3420 int npts;
3421 int size;
3422 int base_size;
3423 bool isopen;
3424
3427 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
3428 errmsg("invalid input syntax for type %s: \"%s\"",
3429 "polygon", str)));
3430
3431 base_size = sizeof(poly->p[0]) * npts;
3432 size = offsetof(POLYGON, p) + base_size;
3433
3434
3435 if (base_size / npts != sizeof(poly->p[0]) || size <= base_size)
3437 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
3438 errmsg("too many points requested")));
3439
3440 poly = (POLYGON *) palloc0(size);
3441
3443 poly->npts = npts;
3444
3445 if ((str, false, npts, &(poly->p[0]), &isopen, NULL, "polygon",
3446 str, escontext))
3448
3450
3452}
3453
3454
3455
3456
3457
3460{
3462
3464}
3465
3466
3467
3468
3469
3470
3471
3472
3473
3476{
3481 int size;
3482
3484 if (npts <= 0 || npts >= (int32) ((INT_MAX - offsetof(POLYGON, p)) / sizeof(Point)))
3486 (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
3487 errmsg("invalid number of points in external \"polygon\" value")));
3488
3489 size = offsetof(POLYGON, p) + sizeof(poly->p[0]) * npts;
3490 poly = (POLYGON *) palloc0(size);
3491
3493 poly->npts = npts;
3494
3495 for (i = 0; i < npts; i++)
3496 {
3499 }
3500
3502
3504}
3505
3506
3507
3508
3511{
3515
3518 for (i = 0; i < poly->npts; i++)
3519 {
3522 }
3524}
3525
3526
3527
3528
3529
3530
3531
3534{
3537 bool result;
3538
3540
3541
3542
3543
3546
3548}
3549
3550
3551
3552
3553
3554
3557{
3560 bool result;
3561
3563
3564
3565
3566
3569
3571}
3572
3573
3574
3575
3576
3577
3580{
3583 bool result;
3584
3586
3587
3588
3589
3592
3594}
3595
3596
3597
3598
3599
3600
3603{
3606 bool result;
3607
3609
3610
3611
3612
3615
3617}
3618
3619
3620
3621
3622
3623
3626{
3629 bool result;
3630
3632
3633
3634
3635
3638
3640}
3641
3642
3643
3644
3645
3646
3649{
3652 bool result;
3653
3655
3656
3657
3658
3661
3663}
3664
3665
3666
3667
3668
3669
3672{
3675 bool result;
3676
3678
3679
3680
3681
3684
3686}
3687
3688
3689
3690
3691
3692
3695{
3698 bool result;
3699
3701
3702
3703
3704
3707
3709}
3710
3711
3712
3713
3714
3715
3716
3717
3718
3721{
3724 bool result;
3725
3726 if (polya->npts != polyb->npts)
3727 result = false;
3728 else
3730
3731
3732
3733
3736
3738}
3739
3740
3741
3742
3743static bool
3745{
3746 bool result;
3747
3749
3750
3752
3753
3754
3755
3756
3757
3758 if (result)
3759 {
3760 int ia,
3761 ib;
3763 sb;
3764
3765
3766 sa.p[0] = polya->p[polya->npts - 1];
3767 result = false;
3768
3769 for (ia = 0; ia < polya->npts && !result; ia++)
3770 {
3771
3773
3774
3775 sb.p[0] = polyb->p[polyb->npts - 1];
3776
3777 for (ib = 0; ib < polyb->npts && !result; ib++)
3778 {
3782 }
3783
3784
3785
3786
3788 }
3789
3790 if (!result)
3791 {
3794 }
3795 }
3796
3797 return result;
3798}
3799
3802{
3805 bool result;
3806
3808
3809
3810
3811
3814
3816}
3817
3818
3819
3820
3821
3822
3823
3824
3825
3826
3827
3828
3829static bool
3831{
3832
3834
3837
3839 {
3842 }
3844 {
3847 }
3849 {
3851 }
3853 {
3855 }
3856
3857 return true;
3858}
3859
3860
3861
3862
3863
3864
3865static bool
3867{
3869 t;
3870 int i;
3871 bool res = true,
3872 intersection = false;
3873
3874
3876
3879 s.p[0] = poly->p[(start == 0) ? (poly->npts - 1) : (start - 1)];
3880
3882 {
3884
3886
3888
3890 {
3892 return true;
3893
3894
3896 }
3898 {
3899
3901 }
3903 {
3904
3905
3906
3907
3908 intersection = true;
3910 if (res)
3912 }
3913
3915 }
3916
3917 if (res && !intersection)
3918 {
3920
3921
3922
3923
3924
3927
3929 }
3930
3931 return res;
3932}
3933
3934
3935
3936
3937static bool
3939{
3940 int i;
3942
3943 Assert(contains_poly->npts > 0 && contained_poly->npts > 0);
3944
3945
3946
3947
3948
3950 return false;
3951
3952 s.p[0] = contained_poly->p[contained_poly->npts - 1];
3953
3954 for (i = 0; i < contained_poly->npts; i++)
3955 {
3956 s.p[1] = contained_poly->p[i];
3958 return false;
3960 }
3961
3962 return true;
3963}
3964
3967{
3970 bool result;
3971
3973
3974
3975
3976
3979
3981}
3982
3983
3984
3985
3986
3989{
3992 bool result;
3993
3994
3996
3997
3998
3999
4002
4004}
4005
4006
4009{
4012
4014}
4015
4018{
4021
4023}
4024
4025
4028{
4031 float8 min = 0.0;
4032 bool have_min = false;
4034 int i,
4035 j;
4037 seg2;
4038
4039
4040
4041
4042
4043
4046
4047
4048
4049
4050
4051
4052 for (i = 0; i < polya->npts; i++)
4053 {
4054 int iprev;
4055
4056 if (i > 0)
4057 iprev = i - 1;
4058 else
4059 iprev = polya->npts - 1;
4060
4061 for (j = 0; j < polyb->npts; j++)
4062 {
4063 int jprev;
4064
4065 if (j > 0)
4066 jprev = j - 1;
4067 else
4068 jprev = polyb->npts - 1;
4069
4072
4074 if (!have_min || float8_lt(tmp, min))
4075 {
4076 min = tmp;
4077 have_min = true;
4078 }
4079 }
4080 }
4081
4082 if (!have_min)
4084
4086}
4087
4088
4089
4090
4091
4092
4093
4094
4097{
4101
4103
4105
4107}
4108
4109
4110static inline void
4112{
4116}
4117
4120{
4124
4126
4128
4130}
4131
4132
4133static inline void
4135{
4139}
4140
4143{
4147
4149
4151
4153}
4154
4155
4156static inline void
4158{
4164}
4165
4168{
4172
4174
4176
4178}
4179
4180
4181static inline void
4183{
4185
4187
4193}
4194
4197{
4201
4203
4205
4207}
4208
4209
4210
4211
4212
4213
4214
4215
4218{
4221 BOX *result;
4222
4224
4226
4228}
4229
4232{
4235 BOX *result;
4236
4238
4241
4243}
4244
4247{
4250 BOX *result;
4251
4253
4256
4258}
4259
4262{
4265 BOX *result;
4267 low;
4268
4270
4273
4275
4277}
4278
4281{
4284 BOX *result;
4286 low;
4287
4289
4292
4294
4296}
4297
4298
4299
4300
4303{
4305 BOX *box;
4306
4308
4313
4315}
4316
4317
4318
4319
4322{
4325 *container;
4326
4328
4329 container->high.x = float8_max(box1->high.x, box2->high.x);
4330 container->low.x = float8_min(box1->low.x, box2->low.x);
4331 container->high.y = float8_max(box1->high.y, box2->high.y);
4332 container->low.y = float8_min(box1->low.y, box2->low.y);
4333
4335}
4336
4337
4338
4339
4340
4341
4342
4343
4344
4345
4346
4349{
4352 PATH *result;
4353 int size,
4354 base_size;
4355 int i;
4356
4359
4360 base_size = sizeof(p1->p[0]) * (p1->npts + p2->npts);
4361 size = offsetof(PATH, p) + base_size;
4362
4363
4364 if (base_size / sizeof(p1->p[0]) != (p1->npts + p2->npts) ||
4365 size <= base_size)
4367 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
4368 errmsg("too many points requested")));
4369
4371
4375
4376 result->dummy = 0;
4377
4378 for (i = 0; i < p1->npts; i++)
4379 {
4380 result->p[i].x = p1->p[i].x;
4381 result->p[i].y = p1->p[i].y;
4382 }
4383 for (i = 0; i < p2->npts; i++)
4384 {
4385 result->p[i + p1->npts].x = p2->p[i].x;
4386 result->p[i + p1->npts].y = p2->p[i].y;
4387 }
4388
4390}
4391
4392
4393
4394
4397{
4400 int i;
4401
4402 for (i = 0; i < path->npts; i++)
4404
4406}
4407
4410{
4413 int i;
4414
4415 for (i = 0; i < path->npts; i++)
4417
4419}
4420
4421
4422
4423
4426{
4429 int i;
4430
4431 for (i = 0; i < path->npts; i++)
4433
4435}
4436
4439{
4442 int i;
4443
4444 for (i = 0; i < path->npts; i++)
4446
4448}
4449
4450
4453{
4456 int size;
4457 int i;
4458
4459
4462 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4463 errmsg("open path cannot be converted to polygon")));
4464
4465
4466
4467
4468
4469 size = offsetof(POLYGON, p) + sizeof(poly->p[0]) * path->npts;
4471
4474
4475 for (i = 0; i < path->npts; i++)
4476 {
4477 poly->p[i].x = path->p[i].x;
4478 poly->p[i].y = path->p[i].y;
4479 }
4480
4482
4484}
4485
4486
4487
4488
4489
4490
4491
4492
4495{
4497
4499}
4500
4501
4504{
4508
4510
4512 *result = circle.center;
4513
4515}
4516
4517
4520{
4522 BOX *box;
4523
4526
4528}
4529
4530
4531
4532
4533
4536{
4539 int size;
4540
4541
4542 size = offsetof(POLYGON, p) + sizeof(poly->p[0]) * 4;
4544
4546 poly->npts = 4;
4547
4548 poly->p[0].x = box->low.x;
4549 poly->p[0].y = box->low.y;
4550 poly->p[1].x = box->low.x;
4551 poly->p[1].y = box->high.y;
4552 poly->p[2].x = box->high.x;
4553 poly->p[2].y = box->high.y;
4554 poly->p[3].x = box->high.x;
4555 poly->p[3].y = box->low.y;
4556
4558
4560}
4561
4562
4565{
4568 int size;
4569 int i;
4570
4571
4572
4573
4574
4575 size = offsetof(PATH, p) + sizeof(path->p[0]) * poly->npts;
4577
4580 path->closed = true;
4581
4582 path->dummy = 0;
4583
4584 for (i = 0; i < poly->npts; i++)
4585 {
4586 path->p[i].x = poly->p[i].x;
4587 path->p[i].y = poly->p[i].y;
4588 }
4589
4591}
4592
4593
4594
4595
4596
4597
4598
4599
4600
4601
4602
4603
4604
4605
4606
4607
4608
4609
4612{
4614 Node *escontext = fcinfo->context;
4616 char *s,
4617 *cp;
4618 int depth = 0;
4619
4620 s = str;
4621 while (isspace((unsigned char) *s))
4622 s++;
4624 depth++, s++;
4625 else if (*s == LDELIM)
4626 {
4627
4628 cp = (s + 1);
4629 while (isspace((unsigned char) *cp))
4630 cp++;
4632 depth++, s = cp;
4633 }
4634
4635
4637 escontext))
4639
4640 if (*s == DELIM)
4641 s++;
4642
4645
4646
4647 if (circle->radius < 0.0)
4649 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
4650 errmsg("invalid input syntax for type %s: \"%s\"",
4651 "circle", str)));
4652
4653 while (depth > 0)
4654 {
4655 if ((*s == RDELIM) || ((*s == RDELIM_C) && (depth == 1)))
4656 {
4657 depth--;
4658 s++;
4659 while (isspace((unsigned char) *s))
4660 s++;
4661 }
4662 else
4664 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
4665 errmsg("invalid input syntax for type %s: \"%s\"",
4666 "circle", str)));
4667 }
4668
4669 if (*s != '\0')
4671 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
4672 errmsg("invalid input syntax for type %s: \"%s\"",
4673 "circle", str)));
4674
4676}
4677
4678
4679
4682{
4685
4687
4695
4697}
4698
4699
4700
4701
4704{
4707
4709
4713
4714
4715 if (circle->radius < 0.0)
4717 (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
4718 errmsg("invalid radius in external \"circle\" value")));
4719
4721}
4722
4723
4724
4725
4728{
4731
4737}
4738
4739
4740
4741
4742
4743
4744
4745
4746
4747
4748
4749
4752{
4755
4759}
4760
4761
4762
4765{
4768
4771}
4772
4773
4774
4775
4778{
4781
4784}
4785
4786
4787
4790{
4793
4796}
4797
4798
4799
4802{
4805
4808}
4809
4810
4811
4812
4815{
4818
4821}
4822
4823
4824
4827{
4830
4833}
4834
4835
4836
4839{
4842
4845}
4846
4847
4848
4849
4852{
4855
4858}
4859
4860
4861
4864{
4867
4870}
4871
4872
4873
4874
4877{
4880
4883}
4884
4885
4886
4887
4890{
4893
4896}
4897
4898
4899
4900
4901
4904{
4907
4909}
4910
4913{
4916
4918}
4919
4922{
4925
4927}
4928
4931{
4934
4936}
4937
4940{
4943
4945}
4946
4949{
4952
4954}
4955
4956
4957
4958
4959
4960
4961
4962
4963
4966{
4970
4972
4975
4977}
4978
4981{
4985
4987
4990
4992}
4993
4994
4995
4996
4997
5000{
5004
5006
5009
5011}
5012
5015{
5019
5021
5024
5026}
5027
5028
5029
5030
5033{
5035
5037}
5038
5039
5040
5041
5044{
5046
5048}
5049
5050
5051
5052
5055{
5057
5059}
5060
5061
5062
5063
5064
5067{
5071
5074 if (result < 0.0)
5075 result = 0.0;
5076
5078}
5079
5080
5083{
5087
5090}
5091
5092
5095{
5099
5102}
5103
5104
5105
5106
5107
5110{
5114
5117 if (result < 0.0)
5118 result = 0.0;
5119
5121}
5122
5123
5124
5125
5128{
5132
5134 if (result < 0.0)
5135 result = 0.0;
5136
5138}
5139
5140
5141
5144{
5147
5149 result->x = circle->center.x;
5150 result->y = circle->center.y;
5151
5153}
5154
5155
5156
5157
5160{
5162}
5163
5164
5165
5166
5167
5168
5171{
5175
5177
5178 result->center.x = center->x;
5179 result->center.y = center->y;
5180 result->radius = radius;
5181
5183}
5184
5187{
5189 BOX *box;
5191
5193
5195
5200
5202}
5203
5204
5205
5206
5209{
5212
5214
5217
5219
5221}
5222
5223
5226{
5230 int base_size,
5231 size;
5232 int i;
5235
5238 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
5239 errmsg("cannot convert circle with radius zero to polygon")));
5240
5241 if (npts < 2)
5243 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
5244 errmsg("must request at least 2 points")));
5245
5246 base_size = sizeof(poly->p[0]) * npts;
5247 size = offsetof(POLYGON, p) + base_size;
5248
5249
5250 if (base_size / npts != sizeof(poly->p[0]) || size <= base_size)
5252 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
5253 errmsg("too many points requested")));
5254
5255 poly = (POLYGON *) palloc0(size);
5257 poly->npts = npts;
5258
5260
5261 for (i = 0; i < npts; i++)
5262 {
5264
5269 }
5270
5272
5274}
5275
5276
5277
5278
5279
5280
5281
5282
5283
5284static void
5286{
5287 int i;
5288
5290
5294
5295 for (i = 0; i < poly->npts; i++)
5299
5300 for (i = 0; i < poly->npts; i++)
5304}
5305
5308{
5311
5313
5315
5317}
5318
5319
5320
5321
5322
5323
5324
5325
5326
5327
5328
5329
5330
5331
5332
5333
5334
5335
5336
5337#define POINT_ON_POLYGON INT_MAX
5338
5339static int
5341{
5343 y0;
5345 prev_y;
5346 int i = 0;
5348 y;
5349 int cross,
5350 total_cross = 0;
5351
5353
5354
5357
5358 prev_x = x0;
5359 prev_y = y0;
5360
5361 for (i = 1; i < npts; i++)
5362 {
5363
5366
5367
5369 return 2;
5370 total_cross += cross;
5371
5372 prev_x = x;
5373 prev_y = y;
5374 }
5375
5376
5378 return 2;
5379 total_cross += cross;
5380
5381 if (total_cross != 0)
5382 return 1;
5383 return 0;
5384}
5385
5386
5387
5388
5389
5390
5391
5392
5393
5394
5395
5396static int
5398{
5400 int y_sign;
5401
5403 {
5407 {
5408 if (FPzero(prev_y))
5409
5411 return FPlt(prev_y, 0.0) ? 1 : -1;
5412 }
5413 else
5414 {
5416
5418 return 0;
5419 }
5420 }
5421 else
5422 {
5423
5424 y_sign = FPgt(y, 0.0) ? 1 : -1;
5425
5427
5428 return FPlt(prev_x, 0.0) ? 0 : y_sign;
5429 else if ((y_sign < 0 && FPlt(prev_y, 0.0)) ||
5430 (y_sign > 0 && FPgt(prev_y, 0.0)))
5431
5432 return 0;
5433 else
5434 {
5435 if (FPge(x, 0.0) && FPgt(prev_x, 0.0))
5436
5437 return 2 * y_sign;
5438 if (FPlt(x, 0.0) && FPle(prev_x, 0.0))
5439
5440 return 0;
5441
5442
5447 if ((y_sign < 0 && FPlt(z, 0.0)) ||
5448 (y_sign > 0 && FPgt(z, 0.0)))
5449 return 0;
5450 return 2 * y_sign;
5451 }
5452 }
5453}
5454
5455
5456static bool
5458{
5459 int i,
5460 ii,
5461 j;
5462
5463
5464 for (i = 0; i < npts; i++)
5465 {
5467 {
5468
5469
5470 for (ii = 1, j = i + 1; ii < npts; ii++, j++)
5471 {
5472 if (j >= npts)
5473 j = 0;
5475 break;
5476 }
5477 if (ii == npts)
5478 return true;
5479
5480
5481 for (ii = 1, j = i - 1; ii < npts; ii++, j--)
5482 {
5483 if (j < 0)
5484 j = (npts - 1);
5486 break;
5487 }
5488 if (ii == npts)
5489 return true;
5490 }
5491 }
5492
5493 return false;
5494}
5495
5496
5497
5498
5499
5500
5501
5502
5503
5504
5505
5506
5507
5508
5509
5510
5511
5512
5513
5514
5515
5516
5517
5520{
5522 result;
5523
5524
5525 if (isinf(x) || isinf(y))
5527
5528 if (isnan(x) || isnan(y))
5530
5531
5534
5535
5537 {
5539
5541 y = temp;
5542 }
5543
5544
5545
5546
5547
5548
5549 if (y == 0.0)
5550 return x;
5551
5552
5554 result = x * sqrt(1.0 + (yx * yx));
5555
5556 if (unlikely(isinf(result)))
5558 if (unlikely(result == 0.0))
5560
5561 return result;
5562}
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
#define ereturn(context, dummy_value,...)
#define ereport(elevel,...)
float8 float8in_internal(char *num, char **endptr_p, const char *type_name, const char *orig_string, struct Node *escontext)
pg_noinline void float_overflow_error(void)
pg_noinline void float_underflow_error(void)
char * float8out_internal(double num)
static float8 float8_min(const float8 val1, const float8 val2)
static float8 float8_mul(const float8 val1, const float8 val2)
static float8 float8_pl(const float8 val1, const float8 val2)
static float8 float8_mi(const float8 val1, const float8 val2)
static float8 get_float8_infinity(void)
static float8 float8_max(const float8 val1, const float8 val2)
static bool float8_eq(const float8 val1, const float8 val2)
static float8 get_float8_nan(void)
static float8 float8_div(const float8 val1, const float8 val2)
static bool float8_lt(const float8 val1, const float8 val2)
static bool float8_gt(const float8 val1, const float8 val2)
#define PG_FREE_IF_COPY(ptr, n)
#define PG_RETURN_BYTEA_P(x)
#define PG_GETARG_FLOAT8(n)
#define PG_RETURN_FLOAT8(x)
#define PG_GETARG_POINTER(n)
#define PG_RETURN_CSTRING(x)
#define PG_GETARG_CSTRING(n)
#define PG_RETURN_INT32(x)
#define PG_GETARG_INT32(n)
#define PG_RETURN_BOOL(x)
static bool FPlt(double A, double B)
#define PG_GETARG_POINT_P(n)
#define PG_RETURN_CIRCLE_P(x)
static bool FPge(double A, double B)
#define PG_RETURN_BOX_P(x)
#define PG_RETURN_LSEG_P(x)
#define PG_RETURN_POINT_P(x)
#define PG_GETARG_LINE_P(n)
static bool FPne(double A, double B)
#define PG_RETURN_POLYGON_P(x)
#define PG_GETARG_BOX_P(n)
#define PG_GETARG_POLYGON_P(n)
#define PG_GETARG_PATH_P_COPY(n)
#define PG_GETARG_CIRCLE_P(n)
static bool FPgt(double A, double B)
static bool FPle(double A, double B)
#define PG_GETARG_LSEG_P(n)
#define PG_RETURN_LINE_P(x)
#define PG_GETARG_PATH_P(n)
static bool FPeq(double A, double B)
#define PG_RETURN_PATH_P(x)
static void poly_to_circle(CIRCLE *result, POLYGON *poly)
Datum circle_div_pt(PG_FUNCTION_ARGS)
static bool pair_decode(char *str, float8 *x, float8 *y, char **endptr_p, const char *type_name, const char *orig_string, Node *escontext)
Datum circle_contained(PG_FUNCTION_ARGS)
Datum close_ls(PG_FUNCTION_ARGS)
static bool box_ov(BOX *box1, BOX *box2)
static float8 box_closept_point(Point *result, BOX *box, Point *pt)
Datum box_width(PG_FUNCTION_ARGS)
Datum path_n_le(PG_FUNCTION_ARGS)
Datum lseg_center(PG_FUNCTION_ARGS)
Datum path_close(PG_FUNCTION_ARGS)
Datum circle_in(PG_FUNCTION_ARGS)
Datum point_distance(PG_FUNCTION_ARGS)
static int lseg_crossing(float8 x, float8 y, float8 prev_x, float8 prev_y)
Datum circle_eq(PG_FUNCTION_ARGS)
Datum path_distance(PG_FUNCTION_ARGS)
static bool box_interpt_lseg(Point *result, BOX *box, LSEG *lseg)
static bool lseg_inside_poly(Point *a, Point *b, POLYGON *poly, int start)
static bool lseg_contain_point(LSEG *lseg, Point *pt)
Datum lseg_send(PG_FUNCTION_ARGS)
Datum box_left(PG_FUNCTION_ARGS)
static bool single_decode(char *num, float8 *x, char **endptr_p, const char *type_name, const char *orig_string, Node *escontext)
Datum point_ne(PG_FUNCTION_ARGS)
Datum path_n_eq(PG_FUNCTION_ARGS)
Datum point_out(PG_FUNCTION_ARGS)
Datum circle_overright(PG_FUNCTION_ARGS)
Datum circle_radius(PG_FUNCTION_ARGS)
Datum cr_circle(PG_FUNCTION_ARGS)
static char * path_encode(enum path_delim path_delim, int npts, Point *pt)
Datum point_send(PG_FUNCTION_ARGS)
Datum circle_distance(PG_FUNCTION_ARGS)
Datum circle_center(PG_FUNCTION_ARGS)
Datum box_gt(PG_FUNCTION_ARGS)
Datum circle_right(PG_FUNCTION_ARGS)
Datum circle_overleft(PG_FUNCTION_ARGS)
Datum path_mul_pt(PG_FUNCTION_ARGS)
Datum box_right(PG_FUNCTION_ARGS)
static float8 box_ht(BOX *box)
Datum dist_pathp(PG_FUNCTION_ARGS)
Datum circle_diameter(PG_FUNCTION_ARGS)
static bool poly_contain_poly(POLYGON *contains_poly, POLYGON *contained_poly)
Datum lseg_out(PG_FUNCTION_ARGS)
Datum path_n_ge(PG_FUNCTION_ARGS)
Datum box_ge(PG_FUNCTION_ARGS)
Datum poly_in(PG_FUNCTION_ARGS)
Datum dist_pc(PG_FUNCTION_ARGS)
Datum point_sub(PG_FUNCTION_ARGS)
Datum poly_npoints(PG_FUNCTION_ARGS)
Datum dist_ps(PG_FUNCTION_ARGS)
Datum poly_overabove(PG_FUNCTION_ARGS)
static void statlseg_construct(LSEG *lseg, Point *pt1, Point *pt2)
Datum on_pl(PG_FUNCTION_ARGS)
Datum path_isopen(PG_FUNCTION_ARGS)
Datum path_sub_pt(PG_FUNCTION_ARGS)
Datum circle_same(PG_FUNCTION_ARGS)
Datum point_div(PG_FUNCTION_ARGS)
Datum line_vertical(PG_FUNCTION_ARGS)
Datum box_same(PG_FUNCTION_ARGS)
Datum line_in(PG_FUNCTION_ARGS)
Datum circle_box(PG_FUNCTION_ARGS)
static void point_construct(Point *result, float8 x, float8 y)
Datum circle_ge(PG_FUNCTION_ARGS)
Datum poly_contain_pt(PG_FUNCTION_ARGS)
Datum dist_ppoly(PG_FUNCTION_ARGS)
Datum poly_out(PG_FUNCTION_ARGS)
Datum poly_distance(PG_FUNCTION_ARGS)
Datum line_distance(PG_FUNCTION_ARGS)
Datum circle_mul_pt(PG_FUNCTION_ARGS)
Datum point_eq(PG_FUNCTION_ARGS)
static bool box_contain_box(BOX *contains_box, BOX *contained_box)
Datum dist_ppath(PG_FUNCTION_ARGS)
Datum point_box(PG_FUNCTION_ARGS)
static void line_construct(LINE *result, Point *pt, float8 m)
Datum box_sub(PG_FUNCTION_ARGS)
Datum circle_overabove(PG_FUNCTION_ARGS)
Datum poly_overright(PG_FUNCTION_ARGS)
Datum point_above(PG_FUNCTION_ARGS)
Datum dist_cpoly(PG_FUNCTION_ARGS)
Datum line_perp(PG_FUNCTION_ARGS)
Datum path_in(PG_FUNCTION_ARGS)
Datum dist_pl(PG_FUNCTION_ARGS)
static void point_add_point(Point *result, Point *pt1, Point *pt2)
Datum lseg_eq(PG_FUNCTION_ARGS)
Datum poly_contained(PG_FUNCTION_ARGS)
Datum poly_circle(PG_FUNCTION_ARGS)
Datum box_distance(PG_FUNCTION_ARGS)
Datum close_lseg(PG_FUNCTION_ARGS)
Datum path_area(PG_FUNCTION_ARGS)
Datum points_box(PG_FUNCTION_ARGS)
Datum box_below(PG_FUNCTION_ARGS)
static void make_bound_box(POLYGON *poly)
Datum poly_overleft(PG_FUNCTION_ARGS)
static bool line_decode(char *s, const char *str, LINE *line, Node *escontext)
Datum poly_path(PG_FUNCTION_ARGS)
static float8 box_closept_lseg(Point *result, BOX *box, LSEG *lseg)
static void point_mul_point(Point *result, Point *pt1, Point *pt2)
Datum circle_above(PG_FUNCTION_ARGS)
Datum dist_sp(PG_FUNCTION_ARGS)
Datum poly_overlap(PG_FUNCTION_ARGS)
Datum lseg_ge(PG_FUNCTION_ARGS)
Datum poly_left(PG_FUNCTION_ARGS)
Datum line_construct_pp(PG_FUNCTION_ARGS)
static bool poly_overlap_internal(POLYGON *polya, POLYGON *polyb)
static float8 circle_ar(CIRCLE *circle)
Datum path_open(PG_FUNCTION_ARGS)
Datum box_add(PG_FUNCTION_ARGS)
Datum box_diagonal(PG_FUNCTION_ARGS)
Datum line_eq(PG_FUNCTION_ARGS)
Datum box_below_eq(PG_FUNCTION_ARGS)
static void box_cn(Point *center, BOX *box)
Datum path_send(PG_FUNCTION_ARGS)
Datum poly_contain(PG_FUNCTION_ARGS)
Datum circle_add_pt(PG_FUNCTION_ARGS)
static void point_div_point(Point *result, Point *pt1, Point *pt2)
static float8 box_ar(BOX *box)
Datum poly_recv(PG_FUNCTION_ARGS)
Datum inter_lb(PG_FUNCTION_ARGS)
Datum box_area(PG_FUNCTION_ARGS)
Datum path_length(PG_FUNCTION_ARGS)
Datum boxes_bound_box(PG_FUNCTION_ARGS)
Datum box_out(PG_FUNCTION_ARGS)
Datum circle_below(PG_FUNCTION_ARGS)
Datum lseg_gt(PG_FUNCTION_ARGS)
static float8 lseg_closept_point(Point *result, LSEG *lseg, Point *pt)
Datum path_out(PG_FUNCTION_ARGS)
Datum box_in(PG_FUNCTION_ARGS)
Datum box_recv(PG_FUNCTION_ARGS)
static float8 lseg_closept_line(Point *result, LSEG *lseg, LINE *line)
Datum on_ppath(PG_FUNCTION_ARGS)
Datum pt_contained_circle(PG_FUNCTION_ARGS)
Datum lseg_recv(PG_FUNCTION_ARGS)
Datum line_send(PG_FUNCTION_ARGS)
Datum lseg_horizontal(PG_FUNCTION_ARGS)
Datum close_pl(PG_FUNCTION_ARGS)
static float8 line_closept_point(Point *result, LINE *line, Point *point)
Datum box_above_eq(PG_FUNCTION_ARGS)
Datum on_ps(PG_FUNCTION_ARGS)
Datum box_contain_pt(PG_FUNCTION_ARGS)
Datum dist_sl(PG_FUNCTION_ARGS)
Datum path_poly(PG_FUNCTION_ARGS)
Datum point_below(PG_FUNCTION_ARGS)
Datum box_le(PG_FUNCTION_ARGS)
Datum line_parallel(PG_FUNCTION_ARGS)
Datum lseg_length(PG_FUNCTION_ARGS)
float8 pg_hypot(float8 x, float8 y)
Datum line_out(PG_FUNCTION_ARGS)
Datum line_interpt(PG_FUNCTION_ARGS)
Datum close_sb(PG_FUNCTION_ARGS)
Datum lseg_le(PG_FUNCTION_ARGS)
Datum on_pb(PG_FUNCTION_ARGS)
static int point_inside(Point *p, int npts, Point *plist)
Datum lseg_ne(PG_FUNCTION_ARGS)
Datum path_inter(PG_FUNCTION_ARGS)
Datum dist_lp(PG_FUNCTION_ARGS)
Datum box_poly(PG_FUNCTION_ARGS)
Datum inter_sb(PG_FUNCTION_ARGS)
Datum poly_below(PG_FUNCTION_ARGS)
Datum poly_overbelow(PG_FUNCTION_ARGS)
Datum pt_contained_poly(PG_FUNCTION_ARGS)
Datum circle_contain(PG_FUNCTION_ARGS)
static bool line_interpt_line(Point *result, LINE *l1, LINE *l2)
static void box_construct(BOX *result, Point *pt1, Point *pt2)
Datum lseg_lt(PG_FUNCTION_ARGS)
Datum circle_send(PG_FUNCTION_ARGS)
static bool box_contain_lseg(BOX *box, LSEG *lseg)
Datum circle_lt(PG_FUNCTION_ARGS)
Datum lseg_vertical(PG_FUNCTION_ARGS)
Datum lseg_construct(PG_FUNCTION_ARGS)
Datum lseg_intersect(PG_FUNCTION_ARGS)
Datum dist_bp(PG_FUNCTION_ARGS)
Datum box_div(PG_FUNCTION_ARGS)
Datum path_n_lt(PG_FUNCTION_ARGS)
Datum box_overright(PG_FUNCTION_ARGS)
Datum path_npoints(PG_FUNCTION_ARGS)
static float8 point_dt(Point *pt1, Point *pt2)
Datum on_sl(PG_FUNCTION_ARGS)
Datum point_horiz(PG_FUNCTION_ARGS)
Datum circle_out(PG_FUNCTION_ARGS)
Datum inter_sl(PG_FUNCTION_ARGS)
static bool path_decode(char *str, bool opentype, int npts, Point *p, bool *isopen, char **endptr_p, const char *type_name, const char *orig_string, Node *escontext)
Datum lseg_parallel(PG_FUNCTION_ARGS)
static bool plist_same(int npts, Point *p1, Point *p2)
static bool touched_lseg_inside_poly(Point *a, Point *b, LSEG *s, POLYGON *poly, int start)
Datum box_overabove(PG_FUNCTION_ARGS)
Datum poly_above(PG_FUNCTION_ARGS)
Datum line_recv(PG_FUNCTION_ARGS)
Datum lseg_interpt(PG_FUNCTION_ARGS)
Datum point_recv(PG_FUNCTION_ARGS)
Datum box_circle(PG_FUNCTION_ARGS)
Datum path_isclosed(PG_FUNCTION_ARGS)
Datum circle_sub_pt(PG_FUNCTION_ARGS)
Datum line_horizontal(PG_FUNCTION_ARGS)
Datum box_mul(PG_FUNCTION_ARGS)
Datum box_overlap(PG_FUNCTION_ARGS)
Datum box_center(PG_FUNCTION_ARGS)
Datum circle_overbelow(PG_FUNCTION_ARGS)
static float8 dist_ppoly_internal(Point *pt, POLYGON *poly)
Datum box_contain(PG_FUNCTION_ARGS)
Datum box_height(PG_FUNCTION_ARGS)
Datum circle_contain_pt(PG_FUNCTION_ARGS)
Datum dist_bs(PG_FUNCTION_ARGS)
Datum path_add_pt(PG_FUNCTION_ARGS)
static float8 box_wd(BOX *box)
static bool box_contain_point(BOX *box, Point *point)
Datum circle_ne(PG_FUNCTION_ARGS)
Datum circle_le(PG_FUNCTION_ARGS)
Datum box_intersect(PG_FUNCTION_ARGS)
Datum close_pb(PG_FUNCTION_ARGS)
Datum circle_left(PG_FUNCTION_ARGS)
static float8 point_sl(Point *pt1, Point *pt2)
static float8 lseg_invsl(LSEG *lseg)
Datum point_left(PG_FUNCTION_ARGS)
Datum path_add(PG_FUNCTION_ARGS)
static bool line_contain_point(LINE *line, Point *point)
Datum circle_overlap(PG_FUNCTION_ARGS)
Datum lseg_in(PG_FUNCTION_ARGS)
Datum circle_area(PG_FUNCTION_ARGS)
Datum on_sb(PG_FUNCTION_ARGS)
Datum dist_pb(PG_FUNCTION_ARGS)
Datum point_add(PG_FUNCTION_ARGS)
static float8 lseg_sl(LSEG *lseg)
Datum circle_recv(PG_FUNCTION_ARGS)
Datum poly_right(PG_FUNCTION_ARGS)
Datum box_lt(PG_FUNCTION_ARGS)
Datum path_recv(PG_FUNCTION_ARGS)
static float8 dist_cpoly_internal(CIRCLE *circle, POLYGON *poly)
static float8 line_sl(LINE *line)
Datum line_intersect(PG_FUNCTION_ARGS)
Datum box_eq(PG_FUNCTION_ARGS)
Datum path_n_gt(PG_FUNCTION_ARGS)
Datum poly_box(PG_FUNCTION_ARGS)
Datum point_slope(PG_FUNCTION_ARGS)
Datum circle_poly(PG_FUNCTION_ARGS)
static int pair_count(char *s, char delim)
static bool lseg_interpt_lseg(Point *result, LSEG *l1, LSEG *l2)
Datum point_right(PG_FUNCTION_ARGS)
Datum box_send(PG_FUNCTION_ARGS)
static float8 point_invsl(Point *pt1, Point *pt2)
Datum point_mul(PG_FUNCTION_ARGS)
static float8 dist_ppath_internal(Point *pt, PATH *path)
static void pair_encode(float8 x, float8 y, StringInfo str)
Datum dist_polyc(PG_FUNCTION_ARGS)
Datum dist_sb(PG_FUNCTION_ARGS)
static float8 line_invsl(LINE *line)
static void point_sub_point(Point *result, Point *pt1, Point *pt2)
Datum circle_gt(PG_FUNCTION_ARGS)
Datum box_overbelow(PG_FUNCTION_ARGS)
static float8 lseg_closept_lseg(Point *result, LSEG *on_lseg, LSEG *to_lseg)
Datum dist_cpoint(PG_FUNCTION_ARGS)
Datum lseg_distance(PG_FUNCTION_ARGS)
Datum dist_ls(PG_FUNCTION_ARGS)
Datum construct_point(PG_FUNCTION_ARGS)
Datum poly_center(PG_FUNCTION_ARGS)
Datum lseg_perp(PG_FUNCTION_ARGS)
Datum box_contained(PG_FUNCTION_ARGS)
Datum path_div_pt(PG_FUNCTION_ARGS)
static bool lseg_interpt_line(Point *result, LSEG *lseg, LINE *line)
Datum point_in(PG_FUNCTION_ARGS)
Datum box_overleft(PG_FUNCTION_ARGS)
static bool point_eq_point(Point *pt1, Point *pt2)
Datum close_ps(PG_FUNCTION_ARGS)
Datum dist_polyp(PG_FUNCTION_ARGS)
Datum box_above(PG_FUNCTION_ARGS)
Datum poly_same(PG_FUNCTION_ARGS)
static void single_encode(float8 x, StringInfo str)
Datum point_vert(PG_FUNCTION_ARGS)
Datum poly_send(PG_FUNCTION_ARGS)
Assert(PointerIsAligned(start, uint64))
void pfree(void *pointer)
void * palloc0(Size size)
#define CHECK_FOR_INTERRUPTS()
#define SOFT_ERROR_OCCURRED(escontext)
unsigned int pq_getmsgint(StringInfo msg, int b)
float8 pq_getmsgfloat8(StringInfo msg)
void pq_begintypsend(StringInfo buf)
int pq_getmsgbyte(StringInfo msg)
bytea * pq_endtypsend(StringInfo buf)
void pq_sendfloat8(StringInfo buf, float8 f)
static void pq_sendint32(StringInfo buf, uint32 i)
static void pq_sendbyte(StringInfo buf, uint8 byt)
char * psprintf(const char *fmt,...)
void check_stack_depth(void)
void appendStringInfo(StringInfo str, const char *fmt,...)
void appendStringInfoString(StringInfo str, const char *s)
void appendStringInfoChar(StringInfo str, char ch)
void initStringInfo(StringInfo str)
StringInfoData * StringInfo
Point p[FLEXIBLE_ARRAY_MEMBER]
Point p[FLEXIBLE_ARRAY_MEMBER]
#define SET_VARSIZE(PTR, len)