|
8 | 8 | *
|
9 | 9 | *
|
10 | 10 | * IDENTIFICATION
|
11 |
| - * $Header: /cvsroot/pgsql/src/backend/utils/adt/geo_ops.c,v 1.76 2003/05/09 21:19:49 tgl Exp $ |
| 11 | + * $Header: /cvsroot/pgsql/src/backend/utils/adt/geo_ops.c,v 1.77 2003/05/13 18:03:07 tgl Exp $ |
12 | 12 | *
|
13 | 13 | *-------------------------------------------------------------------------
|
14 | 14 | */
|
@@ -409,6 +409,58 @@ box_out(PG_FUNCTION_ARGS)
|
409 | 409 | PG_RETURN_CSTRING(path_encode(-1, 2, &(box->high)));
|
410 | 410 | }
|
411 | 411 |
|
| 412 | +/* |
| 413 | + * box_recv - converts external binary format to box |
| 414 | + */ |
| 415 | +Datum |
| 416 | +box_recv(PG_FUNCTION_ARGS) |
| 417 | +{ |
| 418 | + StringInfo buf = (StringInfo) PG_GETARG_POINTER(0); |
| 419 | + BOX *box; |
| 420 | + double x, |
| 421 | + y; |
| 422 | + |
| 423 | + box = (BOX *) palloc(sizeof(BOX)); |
| 424 | + |
| 425 | + box->high.x = pq_getmsgfloat8(buf); |
| 426 | + box->high.y = pq_getmsgfloat8(buf); |
| 427 | + box->low.x = pq_getmsgfloat8(buf); |
| 428 | + box->low.y = pq_getmsgfloat8(buf); |
| 429 | + |
| 430 | + /* reorder corners if necessary... */ |
| 431 | + if (box->high.x < box->low.x) |
| 432 | + { |
| 433 | + x = box->high.x; |
| 434 | + box->high.x = box->low.x; |
| 435 | + box->low.x = x; |
| 436 | + } |
| 437 | + if (box->high.y < box->low.y) |
| 438 | + { |
| 439 | + y = box->high.y; |
| 440 | + box->high.y = box->low.y; |
| 441 | + box->low.y = y; |
| 442 | + } |
| 443 | + |
| 444 | + PG_RETURN_BOX_P(box); |
| 445 | +} |
| 446 | + |
| 447 | +/* |
| 448 | + * box_send - converts box to binary format |
| 449 | + */ |
| 450 | +Datum |
| 451 | +box_send(PG_FUNCTION_ARGS) |
| 452 | +{ |
| 453 | + BOX *box = PG_GETARG_BOX_P(0); |
| 454 | + StringInfoData buf; |
| 455 | + |
| 456 | + pq_begintypsend(&buf); |
| 457 | + pq_sendfloat8(&buf, box->high.x); |
| 458 | + pq_sendfloat8(&buf, box->high.y); |
| 459 | + pq_sendfloat8(&buf, box->low.x); |
| 460 | + pq_sendfloat8(&buf, box->low.y); |
| 461 | + PG_RETURN_BYTEA_P(pq_endtypsend(&buf)); |
| 462 | +} |
| 463 | + |
412 | 464 |
|
413 | 465 | /* box_construct - fill in a new box.
|
414 | 466 | */
|
@@ -915,6 +967,26 @@ line_out(PG_FUNCTION_ARGS)
|
915 | 967 | PG_RETURN_CSTRING(result);
|
916 | 968 | }
|
917 | 969 |
|
| 970 | +/* |
| 971 | + * line_recv - converts external binary format to line |
| 972 | + */ |
| 973 | +Datum |
| 974 | +line_recv(PG_FUNCTION_ARGS) |
| 975 | +{ |
| 976 | + elog(ERROR, "line not yet implemented"); |
| 977 | + return 0; |
| 978 | +} |
| 979 | + |
| 980 | +/* |
| 981 | + * line_send - converts line to binary format |
| 982 | + */ |
| 983 | +Datum |
| 984 | +line_send(PG_FUNCTION_ARGS) |
| 985 | +{ |
| 986 | + elog(ERROR, "line not yet implemented"); |
| 987 | + return 0; |
| 988 | +} |
| 989 | + |
918 | 990 |
|
919 | 991 | /*----------------------------------------------------------
|
920 | 992 | * Conversion routines from one line formula to internal.
|
@@ -1271,6 +1343,64 @@ path_out(PG_FUNCTION_ARGS)
|
1271 | 1343 | PG_RETURN_CSTRING(path_encode(path->closed, path->npts, path->p));
|
1272 | 1344 | }
|
1273 | 1345 |
|
| 1346 | +/* |
| 1347 | + * path_recv - converts external binary format to path |
| 1348 | + * |
| 1349 | + * External representation is closed flag (a boolean byte), int32 number |
| 1350 | + * of points, and the points. |
| 1351 | + */ |
| 1352 | +Datum |
| 1353 | +path_recv(PG_FUNCTION_ARGS) |
| 1354 | +{ |
| 1355 | + StringInfo buf = (StringInfo) PG_GETARG_POINTER(0); |
| 1356 | + PATH *path; |
| 1357 | + int closed; |
| 1358 | + int32 npts; |
| 1359 | + int32 i; |
| 1360 | + int size; |
| 1361 | + |
| 1362 | + closed = pq_getmsgbyte(buf); |
| 1363 | + npts = pq_getmsgint(buf, sizeof(int32)); |
| 1364 | + if (npts < 0 || npts >= (int32) (INT_MAX / sizeof(Point))) |
| 1365 | + elog(ERROR, "Invalid number of points in external path"); |
| 1366 | + |
| 1367 | + size = offsetof(PATH, p[0]) +sizeof(path->p[0]) * npts; |
| 1368 | + path = (PATH *) palloc(size); |
| 1369 | + |
| 1370 | + path->size = size; |
| 1371 | + path->npts = npts; |
| 1372 | + path->closed = (closed ? 1 : 0); |
| 1373 | + |
| 1374 | + for (i = 0; i < npts; i++) |
| 1375 | + { |
| 1376 | + path->p[i].x = pq_getmsgfloat8(buf); |
| 1377 | + path->p[i].y = pq_getmsgfloat8(buf); |
| 1378 | + } |
| 1379 | + |
| 1380 | + PG_RETURN_PATH_P(path); |
| 1381 | +} |
| 1382 | + |
| 1383 | +/* |
| 1384 | + * path_send - converts path to binary format |
| 1385 | + */ |
| 1386 | +Datum |
| 1387 | +path_send(PG_FUNCTION_ARGS) |
| 1388 | +{ |
| 1389 | + PATH *path = PG_GETARG_PATH_P(0); |
| 1390 | + StringInfoData buf; |
| 1391 | + int32 i; |
| 1392 | + |
| 1393 | + pq_begintypsend(&buf); |
| 1394 | + pq_sendbyte(&buf, path->closed ? 1 : 0); |
| 1395 | + pq_sendint(&buf, path->npts, sizeof(int32)); |
| 1396 | + for (i = 0; i < path->npts; i++) |
| 1397 | + { |
| 1398 | + pq_sendfloat8(&buf, path->p[i].x); |
| 1399 | + pq_sendfloat8(&buf, path->p[i].y); |
| 1400 | + } |
| 1401 | + PG_RETURN_BYTEA_P(pq_endtypsend(&buf)); |
| 1402 | +} |
| 1403 | + |
1274 | 1404 |
|
1275 | 1405 | /*----------------------------------------------------------
|
1276 | 1406 | * Relational operators.
|
@@ -1815,6 +1945,46 @@ lseg_out(PG_FUNCTION_ARGS)
|
1815 | 1945 | PG_RETURN_CSTRING(path_encode(FALSE, 2, (Point *) &(ls->p[0])));
|
1816 | 1946 | }
|
1817 | 1947 |
|
| 1948 | +/* |
| 1949 | + * lseg_recv - converts external binary format to lseg |
| 1950 | + */ |
| 1951 | +Datum |
| 1952 | +lseg_recv(PG_FUNCTION_ARGS) |
| 1953 | +{ |
| 1954 | + StringInfo buf = (StringInfo) PG_GETARG_POINTER(0); |
| 1955 | + LSEG *lseg; |
| 1956 | + |
| 1957 | + lseg = (LSEG *) palloc(sizeof(LSEG)); |
| 1958 | + |
| 1959 | + lseg->p[0].x = pq_getmsgfloat8(buf); |
| 1960 | + lseg->p[0].y = pq_getmsgfloat8(buf); |
| 1961 | + lseg->p[1].x = pq_getmsgfloat8(buf); |
| 1962 | + lseg->p[1].y = pq_getmsgfloat8(buf); |
| 1963 | + |
| 1964 | +#ifdef NOT_USED |
| 1965 | + lseg->m = point_sl(&lseg->p[0], &lseg->p[1]); |
| 1966 | +#endif |
| 1967 | + |
| 1968 | + PG_RETURN_LSEG_P(lseg); |
| 1969 | +} |
| 1970 | + |
| 1971 | +/* |
| 1972 | + * lseg_send - converts lseg to binary format |
| 1973 | + */ |
| 1974 | +Datum |
| 1975 | +lseg_send(PG_FUNCTION_ARGS) |
| 1976 | +{ |
| 1977 | + LSEG *ls = PG_GETARG_LSEG_P(0); |
| 1978 | + StringInfoData buf; |
| 1979 | + |
| 1980 | + pq_begintypsend(&buf); |
| 1981 | + pq_sendfloat8(&buf, ls->p[0].x); |
| 1982 | + pq_sendfloat8(&buf, ls->p[0].y); |
| 1983 | + pq_sendfloat8(&buf, ls->p[1].x); |
| 1984 | + pq_sendfloat8(&buf, ls->p[1].y); |
| 1985 | + PG_RETURN_BYTEA_P(pq_endtypsend(&buf)); |
| 1986 | +} |
| 1987 | + |
1818 | 1988 |
|
1819 | 1989 | /* lseg_construct -
|
1820 | 1990 | * form a LSEG from two Points.
|
@@ -3186,6 +3356,64 @@ poly_out(PG_FUNCTION_ARGS)
|
3186 | 3356 | PG_RETURN_CSTRING(path_encode(TRUE, poly->npts, poly->p));
|
3187 | 3357 | }
|
3188 | 3358 |
|
| 3359 | +/* |
| 3360 | + * poly_recv - converts external binary format to polygon |
| 3361 | + * |
| 3362 | + * External representation is int32 number of points, and the points. |
| 3363 | + * We recompute the bounding box on read, instead of trusting it to |
| 3364 | + * be valid. (Checking it would take just as long, so may as well |
| 3365 | + * omit it from external representation.) |
| 3366 | + */ |
| 3367 | +Datum |
| 3368 | +poly_recv(PG_FUNCTION_ARGS) |
| 3369 | +{ |
| 3370 | + StringInfo buf = (StringInfo) PG_GETARG_POINTER(0); |
| 3371 | + POLYGON *poly; |
| 3372 | + int32 npts; |
| 3373 | + int32 i; |
| 3374 | + int size; |
| 3375 | + |
| 3376 | + npts = pq_getmsgint(buf, sizeof(int32)); |
| 3377 | + if (npts < 0 || npts >= (int32) ((INT_MAX - offsetof(POLYGON, p[0])) / sizeof(Point))) |
| 3378 | + elog(ERROR, "Invalid number of points in external polygon"); |
| 3379 | + |
| 3380 | + size = offsetof(POLYGON, p[0]) +sizeof(poly->p[0]) * npts; |
| 3381 | + poly = (POLYGON *) palloc0(size); /* zero any holes */ |
| 3382 | + |
| 3383 | + poly->size = size; |
| 3384 | + poly->npts = npts; |
| 3385 | + |
| 3386 | + for (i = 0; i < npts; i++) |
| 3387 | + { |
| 3388 | + poly->p[i].x = pq_getmsgfloat8(buf); |
| 3389 | + poly->p[i].y = pq_getmsgfloat8(buf); |
| 3390 | + } |
| 3391 | + |
| 3392 | + make_bound_box(poly); |
| 3393 | + |
| 3394 | + PG_RETURN_POLYGON_P(poly); |
| 3395 | +} |
| 3396 | + |
| 3397 | +/* |
| 3398 | + * poly_send - converts polygon to binary format |
| 3399 | + */ |
| 3400 | +Datum |
| 3401 | +poly_send(PG_FUNCTION_ARGS) |
| 3402 | +{ |
| 3403 | + POLYGON *poly = PG_GETARG_POLYGON_P(0); |
| 3404 | + StringInfoData buf; |
| 3405 | + int32 i; |
| 3406 | + |
| 3407 | + pq_begintypsend(&buf); |
| 3408 | + pq_sendint(&buf, poly->npts, sizeof(int32)); |
| 3409 | + for (i = 0; i < poly->npts; i++) |
| 3410 | + { |
| 3411 | + pq_sendfloat8(&buf, poly->p[i].x); |
| 3412 | + pq_sendfloat8(&buf, poly->p[i].y); |
| 3413 | + } |
| 3414 | + PG_RETURN_BYTEA_P(pq_endtypsend(&buf)); |
| 3415 | +} |
| 3416 | + |
3189 | 3417 |
|
3190 | 3418 | /*-------------------------------------------------------
|
3191 | 3419 | * Is polygon A strictly left of polygon B? i.e. is
|
@@ -4001,6 +4229,43 @@ circle_out(PG_FUNCTION_ARGS)
|
4001 | 4229 | PG_RETURN_CSTRING(result);
|
4002 | 4230 | }
|
4003 | 4231 |
|
| 4232 | +/* |
| 4233 | + * circle_recv - converts external binary format to circle |
| 4234 | + */ |
| 4235 | +Datum |
| 4236 | +circle_recv(PG_FUNCTION_ARGS) |
| 4237 | +{ |
| 4238 | + StringInfo buf = (StringInfo) PG_GETARG_POINTER(0); |
| 4239 | + CIRCLE *circle; |
| 4240 | + |
| 4241 | + circle = (CIRCLE *) palloc(sizeof(CIRCLE)); |
| 4242 | + |
| 4243 | + circle->center.x = pq_getmsgfloat8(buf); |
| 4244 | + circle->center.y = pq_getmsgfloat8(buf); |
| 4245 | + circle->radius = pq_getmsgfloat8(buf); |
| 4246 | + |
| 4247 | + if (circle->radius < 0) |
| 4248 | + elog(ERROR, "Invalid radius in external circle"); |
| 4249 | + |
| 4250 | + PG_RETURN_CIRCLE_P(circle); |
| 4251 | +} |
| 4252 | + |
| 4253 | +/* |
| 4254 | + * circle_send - converts circle to binary format |
| 4255 | + */ |
| 4256 | +Datum |
| 4257 | +circle_send(PG_FUNCTION_ARGS) |
| 4258 | +{ |
| 4259 | + CIRCLE *circle = PG_GETARG_CIRCLE_P(0); |
| 4260 | + StringInfoData buf; |
| 4261 | + |
| 4262 | + pq_begintypsend(&buf); |
| 4263 | + pq_sendfloat8(&buf, circle->center.x); |
| 4264 | + pq_sendfloat8(&buf, circle->center.y); |
| 4265 | + pq_sendfloat8(&buf, circle->radius); |
| 4266 | + PG_RETURN_BYTEA_P(pq_endtypsend(&buf)); |
| 4267 | +} |
| 4268 | + |
4004 | 4269 |
|
4005 | 4270 | /*----------------------------------------------------------
|
4006 | 4271 | * Relational operators for CIRCLEs.
|
|
0 commit comments