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 {

522 result->high.x = pt1->x;

523 result->low.x = pt2->x;

524 }

525 else

526 {

527 result->high.x = pt2->x;

528 result->low.x = pt1->x;

529 }

531 {

532 result->high.y = pt1->y;

533 result->low.y = pt2->y;

534 }

535 else

536 {

537 result->high.y = pt2->y;

538 result->low.y = pt1->y;

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 (box\_ov(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 (path\_decode(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;

1090 result->C = pt->x;

1091 }

1092 else if (m == 0)

1093 {

1094

1095 result->A = 0.0;

1096 result->B = -1.0;

1097 result->C = pt->y;

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 (FPzero(l2->B))

1214 else if (FPzero(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 (FPzero(l1->A) && !isnan(l1->A) && FPzero(l2->A) && !isnan(l2->A))

1272 else if (FPzero(l1->B) && !isnan(l1->B) && FPzero(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 (FPzero(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 (path\_decode(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 (box\_ov(&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{

1886 result->x = x;

1887 result->y = y;

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 (path\_decode(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{

2144 lseg->p[0].x = pt1->x;

2145 lseg->p[0].y = pt1->y;

2146 lseg->p[1].x = pt2->x;

2147 lseg->p[1].y = pt2->y;

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

2895 point.x = box->low.x;

2896 point.y = box->high.y;

2899

2903 {

2904 dist = d;

2905 if (result != NULL)

2906 *result = closept;

2907 }

2908

2909 point.x = box->high.x;

2910 point.y = box->low.y;

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

3025 point.x = box->low.x;

3026 point.y = box->high.y;

3029

3033 {

3034 dist = d;

3035 if (result != NULL)

3036 *result = closept;

3037 }

3038

3039 point.x = box->high.x;

3040 point.y = box->low.y;

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;

3180 for (i = 0; i < n; i++)

3181 {

3185 a = b;

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 (box\_ov(&lbox, box))

3276 return false;

3277

3278 if (result != NULL)

3279 {

3280 box_cn(&point, box);

3282 }

3283

3284

3287 return true;

3288

3289

3290 point.x = box->low.x;

3291 point.y = box->high.y;

3294 return true;

3295

3298 return true;

3299

3300 point.x = box->high.x;

3301 point.y = box->low.y;

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

3337 p1.x = box->low.x;

3338 p1.y = box->low.y;

3339 p2.x = box->low.x;

3350 p2.y = box->low.y;

3354 p1.x = box->low.x;

3355 p1.y = box->low.y;

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

3386 x1 = x2 = poly->p[0].x;

3387 y2 = y1 = poly->p[0].y;

3388 for (i = 1; i < poly->npts; i++)

3389 {

3391 x1 = poly->p[i].x;

3393 x2 = poly->p[i].x;

3395 y1 = poly->p[i].y;

3397 y2 = poly->p[i].y;

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 (path\_decode(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

3772 sa.p[1] = polya->p[ia];

3773

3774

3775 sb.p[0] = polyb->p[polyb->npts - 1];

3776

3777 for (ib = 0; ib < polyb->npts && !result; ib++)

3778 {

3779 sb.p[1] = polyb->p[ib];

3781 sb.p[0] = sb.p[1];

3782 }

3783

3784

3785

3786

3787 sa.p[0] = sa.p[1];

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

3835 t.p[0] = *a;

3836 t.p[1] = *b;

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

3877 t.p[0] = *a;

3878 t.p[1] = *b;

3879 s.p[0] = poly->p[(start == 0) ? (poly->npts - 1) : (start - 1)];

3880

3882 {

3884

3886

3887 s.p[1] = poly->p[i];

3888

3890 {

3892 return true;

3893

3894

3896 }

3898 {

3899

3901 }

3903 {

3904

3905

3906

3907

3908 intersection = true;

3910 if (res)

3912 }

3913

3914 s.p[0] = s.p[1];

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;

3959 s.p[0] = s.p[1];

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

4309 box->high.x = pt->x;

4310 box->low.x = pt->x;

4311 box->high.y = pt->y;

4312 box->low.y = pt->y;

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 {

5404 if (FPzero(x))

5406 else if (FPgt(x, 0))

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

5532 x = fabs(x);

5533 y = fabs(y);

5534

5535

5536 if (x < y)

5537 {

5539

5540 x = y;

5541 y = temp;

5542 }

5543

5544

5545

5546

5547

5548

5549 if (y == 0.0)

5550 return x;

5551

5552

5553 yx = y / x;

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)