From 261c7d4b653bc3e44c31fd456d94f292caa50d8f Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Wed, 9 Oct 2013 01:09:18 -0400 Subject: [PATCH] Revive line type MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Change the input/output format to {A,B,C}, to match the internal representation. Complete the implementations of line_in, line_out, line_recv, line_send. Remove comments and error messages about the line type not being implemented. Add regression tests for existing line operators and functions. Reviewed-by: rui hua <365507506hua@gmail.com> Reviewed-by: Álvaro Herrera Reviewed-by: Jeevan Chalke --- doc/src/sgml/datatype.sgml | 42 +++- doc/src/sgml/func.sgml | 6 + src/backend/utils/adt/geo_ops.c | 224 ++++++++--------- src/include/catalog/pg_type.h | 3 +- src/include/utils/geo_decls.h | 7 - src/test/regress/expected/geometry.out | 3 - src/test/regress/expected/line.out | 271 +++++++++++++++++++++ src/test/regress/expected/sanity_check.out | 3 +- src/test/regress/output/misc.source | 3 +- src/test/regress/parallel_schedule | 2 +- src/test/regress/serial_schedule | 1 + src/test/regress/sql/geometry.sql | 4 - src/test/regress/sql/line.sql | 87 +++++++ 13 files changed, 503 insertions(+), 153 deletions(-) create mode 100644 src/test/regress/expected/line.out create mode 100644 src/test/regress/sql/line.sql diff --git a/doc/src/sgml/datatype.sgml b/doc/src/sgml/datatype.sgml index 87668ea0c1..07f0385d80 100644 --- a/doc/src/sgml/datatype.sgml +++ b/doc/src/sgml/datatype.sgml @@ -3051,9 +3051,7 @@ SELECT person.name, holidays.num_weeks FROM person, holidays Geometric data types represent two-dimensional spatial objects. shows the geometric - types available in PostgreSQL. The - most fundamental type, the point, forms the basis for all of the - other types. + types available in PostgreSQL. @@ -3063,8 +3061,8 @@ SELECT person.name, holidays.num_weeks FROM person, holidays Name Storage Size - Representation Description + Representation @@ -3077,8 +3075,8 @@ SELECT person.name, holidays.num_weeks FROM person, holidays line 32 bytes - Infinite line (not fully implemented) - ((x1,y1),(x2,y2)) + Infinite line + {A,B,C} lseg @@ -3152,6 +3150,38 @@ SELECT person.name, holidays.num_weeks FROM person, holidays + + Lines + + + line + + + + Lines (line) are represented by the linear equation Ax + By + + C = 0, where A and B are not both zero. Values of + type line is input and output in the following form: + +{ A, B, C } + + + Alternatively, any of the following forms can be used for input: + + +[ ( x1 , y1 ) , ( x2 , y2 ) ] +( ( x1 , y1 ) , ( x2 , y2 ) ) + ( x1 , y1 ) , ( x2 , y2 ) + x1 , y1 , x2 , y2 + + + where + (x1,y1) + and + (x2,y2) + are two (different) points on the line. + + + Line Segments diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml index c3090dd2b9..be7b00b1f3 100644 --- a/doc/src/sgml/func.sgml +++ b/doc/src/sgml/func.sgml @@ -8122,6 +8122,12 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple polygon to circle circle(polygon '((0,0),(1,1),(2,0))') + + line(point, point) + line + points to line + line(point '(-1,0)', point '(1,0)') + diff --git a/src/backend/utils/adt/geo_ops.c b/src/backend/utils/adt/geo_ops.c index 5d0b596106..b792d26977 100644 --- a/src/backend/utils/adt/geo_ops.c +++ b/src/backend/utils/adt/geo_ops.c @@ -926,42 +926,82 @@ box_diagonal(PG_FUNCTION_ARGS) /*********************************************************************** ** ** Routines for 2D lines. - ** Lines are not intended to be used as ADTs per se, - ** but their ops are useful tools for other ADT ops. Thus, - ** there are few relops. ** ***********************************************************************/ +static bool +line_decode(const char *str, LINE *line) +{ + char *tail; + + while (isspace((unsigned char) *str)) + str++; + if (*str++ != '{') + return false; + line->A = strtod(str, &tail); + if (tail <= str) + return false; + str = tail; + while (isspace((unsigned char) *str)) + str++; + if (*str++ != DELIM) + return false; + line->B = strtod(str, &tail); + if (tail <= str) + return false; + str = tail; + while (isspace((unsigned char) *str)) + str++; + if (*str++ != DELIM) + return false; + line->C = strtod(str, &tail); + if (tail <= str) + return false; + str = tail; + while (isspace((unsigned char) *str)) + str++; + if (*str++ != '}') + return false; + while (isspace((unsigned char) *str)) + str++; + if (*str) + return false; + + return true; +} + Datum line_in(PG_FUNCTION_ARGS) { -#ifdef ENABLE_LINE_TYPE char *str = PG_GETARG_CSTRING(0); -#endif LINE *line; - -#ifdef ENABLE_LINE_TYPE - /* when fixed, modify "not implemented", catalog/pg_type.h and SGML */ LSEG lseg; int isopen; char *s; - if ((!path_decode(TRUE, 2, str, &isopen, &s, &(lseg.p[0]))) - || (*s != '\0')) + line = (LINE *) palloc(sizeof(LINE)); + + if (path_decode(TRUE, 2, str, &isopen, &s, &(lseg.p[0])) && *s == '\0') + { + if (FPeq(lseg.p[0].x, lseg.p[1].x) && FPeq(lseg.p[0].y, lseg.p[1].y)) + ereport(ERROR, + (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), + errmsg("invalid line specification: must be two distinct points"))); + + line_construct_pts(line, &lseg.p[0], &lseg.p[1]); + } + else if (line_decode(str, line)) + { + if (FPzero(line->A) && FPzero(line->B)) + ereport(ERROR, + (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), + errmsg("invalid line specification: A and B cannot both be zero"))); + } + else ereport(ERROR, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), errmsg("invalid input syntax for type line: \"%s\"", str))); - line = (LINE *) palloc(sizeof(LINE)); - line_construct_pts(line, &lseg.p[0], &lseg.p[1]); -#else - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("type \"line\" not yet implemented"))); - - line = NULL; -#endif - PG_RETURN_LINE_P(line); } @@ -969,66 +1009,17 @@ line_in(PG_FUNCTION_ARGS) Datum line_out(PG_FUNCTION_ARGS) { -#ifdef ENABLE_LINE_TYPE LINE *line = PG_GETARG_LINE_P(0); -#endif - char *result; - -#ifdef ENABLE_LINE_TYPE - /* when fixed, modify "not implemented", catalog/pg_type.h and SGML */ - LSEG lseg; - - if (FPzero(line->B)) - { /* vertical */ - /* use "x = C" */ - result->A = -1; - result->B = 0; - result->C = pt1->x; -#ifdef GEODEBUG - printf("line_out- line is vertical\n"); -#endif -#ifdef NOT_USED - result->m = DBL_MAX; -#endif - - } - else if (FPzero(line->A)) - { /* horizontal */ - /* use "x = C" */ - result->A = 0; - result->B = -1; - result->C = pt1->y; -#ifdef GEODEBUG - printf("line_out- line is horizontal\n"); -#endif -#ifdef NOT_USED - result->m = 0.0; -#endif - - } - else - { - } + char *buf; + int ndig = DBL_DIG + extra_float_digits; - if (FPzero(line->A)) /* horizontal? */ - { - } - else if (FPzero(line->B)) /* vertical? */ - { - } - else - { - } + if (ndig < 1) + ndig = 1; - return path_encode(PATH_CLOSED, 2, (Point *) &(ls->p[0])); -#else - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("type \"line\" not yet implemented"))); - result = NULL; -#endif + buf = palloc(ndig * 3 + 5); + sprintf(buf, "{%.*g,%.*g,%.*g}", ndig, line->A, ndig, line->B, ndig, line->C); - PG_RETURN_CSTRING(result); + PG_RETURN_CSTRING(buf); } /* @@ -1037,10 +1028,16 @@ line_out(PG_FUNCTION_ARGS) Datum line_recv(PG_FUNCTION_ARGS) { - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("type \"line\" not yet implemented"))); - return 0; + StringInfo buf = (StringInfo) PG_GETARG_POINTER(0); + LINE *line; + + line = (LINE *) palloc(sizeof(LINE)); + + line->A = pq_getmsgfloat8(buf); + line->B = pq_getmsgfloat8(buf); + line->C = pq_getmsgfloat8(buf); + + PG_RETURN_LINE_P(line); } /* @@ -1049,10 +1046,14 @@ line_recv(PG_FUNCTION_ARGS) Datum line_send(PG_FUNCTION_ARGS) { - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("type \"line\" not yet implemented"))); - return 0; + LINE *line = PG_GETARG_LINE_P(0); + StringInfoData buf; + + pq_begintypsend(&buf); + pq_sendfloat8(&buf, line->A); + pq_sendfloat8(&buf, line->B); + pq_sendfloat8(&buf, line->C); + PG_RETURN_BYTEA_P(pq_endtypsend(&buf)); } @@ -1084,10 +1085,6 @@ line_construct_pm(Point *pt, double m) result->C = pt->y - m * pt->x; } -#ifdef NOT_USED - result->m = m; -#endif - return result; } @@ -1103,9 +1100,6 @@ line_construct_pts(LINE *line, Point *pt1, Point *pt2) line->A = -1; line->B = 0; line->C = pt1->x; -#ifdef NOT_USED - line->m = DBL_MAX; -#endif #ifdef GEODEBUG printf("line_construct_pts- line is vertical\n"); #endif @@ -1116,9 +1110,6 @@ line_construct_pts(LINE *line, Point *pt1, Point *pt2) line->A = 0; line->B = -1; line->C = pt1->y; -#ifdef NOT_USED - line->m = 0.0; -#endif #ifdef GEODEBUG printf("line_construct_pts- line is horizontal\n"); #endif @@ -1129,9 +1120,6 @@ line_construct_pts(LINE *line, Point *pt1, Point *pt2) line->A = (pt2->y - pt1->y) / (pt2->x - pt1->x); line->B = -1.0; line->C = pt1->y - line->A * pt1->x; -#ifdef NOT_USED - line->m = line->A; -#endif #ifdef GEODEBUG printf("line_construct_pts- line is neither vertical nor horizontal (diffs x=%.*g, y=%.*g\n", DBL_DIG, (pt2->x - pt1->x), DBL_DIG, (pt2->y - pt1->y)); @@ -1175,9 +1163,6 @@ line_parallel(PG_FUNCTION_ARGS) LINE *l1 = PG_GETARG_LINE_P(0); LINE *l2 = PG_GETARG_LINE_P(1); -#ifdef NOT_USED - PG_RETURN_BOOL(FPeq(l1->m, l2->m)); -#endif if (FPzero(l1->B)) PG_RETURN_BOOL(FPzero(l2->B)); @@ -1190,12 +1175,6 @@ line_perp(PG_FUNCTION_ARGS) LINE *l1 = PG_GETARG_LINE_P(0); LINE *l2 = PG_GETARG_LINE_P(1); -#ifdef NOT_USED - if (l1->m) - PG_RETURN_BOOL(FPeq(l2->m / l1->m, -1.0)); - else if (l2->m) - PG_RETURN_BOOL(FPeq(l1->m / l2->m, -1.0)); -#endif if (FPzero(l1->A)) PG_RETURN_BOOL(FPzero(l2->B)); else if (FPzero(l1->B)) @@ -1307,18 +1286,6 @@ line_interpt_internal(LINE *l1, LINE *l2) LinePGetDatum(l2)))) return NULL; -#ifdef NOT_USED - if (FPzero(l1->B)) /* l1 vertical? */ - result = point_construct(l2->m * l1->C + l2->C, l1->C); - else if (FPzero(l2->B)) /* l2 vertical? */ - result = point_construct(l1->m * l2->C + l1->C, l2->C); - else - { - x = (l1->C - l2->C) / (l2->A - l1->A); - result = point_construct(x, l1->m * x + l1->C); - } -#endif - if (FPzero(l1->B)) /* l1 vertical? */ { x = l1->C; @@ -2449,8 +2416,8 @@ dist_pl(PG_FUNCTION_ARGS) static double dist_pl_internal(Point *pt, LINE *line) { - return (line->A * pt->x + line->B * pt->y + line->C) / - HYPOT(line->A, line->B); + return fabs((line->A * pt->x + line->B * pt->y + line->C) / + HYPOT(line->A, line->B)); } Datum @@ -2771,11 +2738,6 @@ close_pl(PG_FUNCTION_ARGS) result = (Point *) palloc(sizeof(Point)); -#ifdef NOT_USED - if (FPeq(line->A, -1.0) && FPzero(line->B)) - { /* vertical */ - } -#endif if (FPzero(line->B)) /* vertical? */ { result->x = line->C; @@ -2789,9 +2751,7 @@ close_pl(PG_FUNCTION_ARGS) PG_RETURN_POINT_P(result); } /* drop a perpendicular and find the intersection point */ -#ifdef NOT_USED - invm = -1.0 / line->m; -#endif + /* invert and flip the sign on the slope to get a perpendicular */ invm = line->B / line->A; tmp = line_construct_pm(pt, invm); @@ -3038,6 +2998,7 @@ close_pb(PG_FUNCTION_ARGS) Datum close_sl(PG_FUNCTION_ARGS) { +#ifdef NOT_USED LSEG *lseg = PG_GETARG_LSEG_P(0); LINE *line = PG_GETARG_LINE_P(1); Point *result; @@ -3056,6 +3017,13 @@ close_sl(PG_FUNCTION_ARGS) result = point_copy(&lseg->p[1]); PG_RETURN_POINT_P(result); +#endif + + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("function \"close_sl\" not implemented"))); + + PG_RETURN_NULL(); } /* close_ls() diff --git a/src/include/catalog/pg_type.h b/src/include/catalog/pg_type.h index e3822faf66..20813125ab 100644 --- a/src/include/catalog/pg_type.h +++ b/src/include/catalog/pg_type.h @@ -393,10 +393,9 @@ DESCR("geometric polygon '(pt1,...)'"); #define POLYGONOID 604 DATA(insert OID = 628 ( line PGNSP PGUID 32 f b G f t \054 0 701 629 line_in line_out line_recv line_send - - - d p f 0 -1 0 0 _null_ _null_ _null_ )); -DESCR("geometric line (not implemented)"); +DESCR("geometric line"); #define LINEOID 628 DATA(insert OID = 629 ( _line PGNSP PGUID -1 f b A f t \054 0 628 0 array_in array_out array_recv array_send - - array_typanalyze d x f 0 -1 0 0 _null_ _null_ _null_ )); -DESCR(""); /* OIDS 700 - 799 */ diff --git a/src/include/utils/geo_decls.h b/src/include/utils/geo_decls.h index 5c83a71e7a..1e648c0bef 100644 --- a/src/include/utils/geo_decls.h +++ b/src/include/utils/geo_decls.h @@ -88,19 +88,12 @@ typedef struct /*--------------------------------------------------------------------- * LINE - Specified by its general equation (Ax+By+C=0). - * If there is a y-intercept, it is C, which - * incidentally gives a freebie point on the line - * (if B=0, then C is the x-intercept). - * Slope m is precalculated to save time; if - * the line is not vertical, m == A. *-------------------------------------------------------------------*/ typedef struct { double A, B, C; - - double m; } LINE; diff --git a/src/test/regress/expected/geometry.out b/src/test/regress/expected/geometry.out index 81237252eb..21ad555c79 100644 --- a/src/test/regress/expected/geometry.out +++ b/src/test/regress/expected/geometry.out @@ -145,9 +145,6 @@ SELECT '' AS thirty, p.f1, l.s, p.f1 ## l.s AS closest | (10,10) | [(11,22),(33,44)] | (11,22) (30 rows) --- --- Lines --- -- -- Boxes -- diff --git a/src/test/regress/expected/line.out b/src/test/regress/expected/line.out new file mode 100644 index 0000000000..7d222fc0c2 --- /dev/null +++ b/src/test/regress/expected/line.out @@ -0,0 +1,271 @@ +-- +-- LINE +-- Infinite lines +-- +--DROP TABLE LINE_TBL; +CREATE TABLE LINE_TBL (s line); +INSERT INTO LINE_TBL VALUES ('{1,-1,1}'); +INSERT INTO LINE_TBL VALUES ('(0,0),(6,6)'); +INSERT INTO LINE_TBL VALUES ('10,-10 ,-3,-4'); +INSERT INTO LINE_TBL VALUES ('[-1e6,2e2,3e5, -4e1]'); +INSERT INTO LINE_TBL VALUES ('(11,22,33,44)'); +INSERT INTO LINE_TBL VALUES ('[(1,0),(1,0)]'); +ERROR: invalid line specification: must be two distinct points +LINE 1: INSERT INTO LINE_TBL VALUES ('[(1,0),(1,0)]'); + ^ +-- horizontal +INSERT INTO LINE_TBL VALUES ('[(1,3),(2,3)]'); +-- vertical +INSERT INTO LINE_TBL VALUES ('[(3,1),(3,2)]'); +-- bad values for parser testing +INSERT INTO LINE_TBL VALUES ('{0,0,1}'); +ERROR: invalid line specification: A and B cannot both be zero +LINE 1: INSERT INTO LINE_TBL VALUES ('{0,0,1}'); + ^ +INSERT INTO LINE_TBL VALUES ('(3asdf,2 ,3,4r2)'); +ERROR: invalid input syntax for type line: "(3asdf,2 ,3,4r2)" +LINE 1: INSERT INTO LINE_TBL VALUES ('(3asdf,2 ,3,4r2)'); + ^ +INSERT INTO LINE_TBL VALUES ('[1,2,3, 4'); +ERROR: invalid input syntax for type line: "[1,2,3, 4" +LINE 1: INSERT INTO LINE_TBL VALUES ('[1,2,3, 4'); + ^ +INSERT INTO LINE_TBL VALUES ('[(,2),(3,4)]'); +ERROR: invalid input syntax for type line: "[(,2),(3,4)]" +LINE 1: INSERT INTO LINE_TBL VALUES ('[(,2),(3,4)]'); + ^ +INSERT INTO LINE_TBL VALUES ('[(1,2),(3,4)'); +ERROR: invalid input syntax for type line: "[(1,2),(3,4)" +LINE 1: INSERT INTO LINE_TBL VALUES ('[(1,2),(3,4)'); + ^ +select * from LINE_TBL; + s +--------------------------------------------- + {1,-1,1} + {1,-1,0} + {-0.461538461538462,-1,-5.38461538461538} + {-0.000184615384615385,-1,15.3846153846154} + {1,-1,11} + {0,-1,3} + {-1,0,3} +(7 rows) + +-- functions and operators +SELECT * FROM LINE_TBL WHERE (s <-> line '[(1,2),(3,4)]') < 10; + s +--------------------------------------------- + {1,-1,1} + {1,-1,0} + {-0.461538461538462,-1,-5.38461538461538} + {-0.000184615384615385,-1,15.3846153846154} + {1,-1,11} + {0,-1,3} + {-1,0,3} +(7 rows) + +SELECT * FROM LINE_TBL WHERE (point '(0.1,0.1)' <-> s) < 1; + s +---------- + {1,-1,1} + {1,-1,0} +(2 rows) + +SELECT * FROM LINE_TBL WHERE (lseg '[(0.1,0.1),(0.2,0.2)]' <-> s) < 1; + s +---------- + {1,-1,1} + {1,-1,0} +(2 rows) + +SELECT line '[(1,1),(2,1)]' <-> line '[(-1,-1),(-2,-1)]'; + ?column? +---------- + 2 +(1 row) + +SELECT lseg '[(1,1),(2,1)]' <-> line '[(-1,-1),(-2,-1)]'; + ?column? +---------- + 2 +(1 row) + +SELECT point '(-1,1)' <-> line '[(-3,0),(-4,0)]'; + ?column? +---------- + 1 +(1 row) + +SELECT lseg '[(1,1),(5,5)]' ?# line '[(2,0),(0,2)]'; -- true + ?column? +---------- + t +(1 row) + +SELECT lseg '[(1,1),(5,5)]' ?# line '[(0,0),(1,0)]'; -- false + ?column? +---------- + f +(1 row) + +SELECT line '[(0,0),(1,1)]' ?# box '(0,0,2,2)'; -- true + ?column? +---------- + t +(1 row) + +SELECT line '[(3,0),(4,1)]' ?# box '(0,0,2,2)'; -- false + ?column? +---------- + f +(1 row) + +SELECT point '(1,1)' <@ line '[(0,0),(2,2)]'; -- true + ?column? +---------- + t +(1 row) + +SELECT point '(1,1)' <@ line '[(0,0),(1,0)]'; -- false + ?column? +---------- + f +(1 row) + +SELECT point '(1,1)' @ line '[(0,0),(2,2)]'; -- true + ?column? +---------- + t +(1 row) + +SELECT point '(1,1)' @ line '[(0,0),(1,0)]'; -- false + ?column? +---------- + f +(1 row) + +SELECT lseg '[(1,1),(2,2)]' <@ line '[(0,0),(2,2)]'; -- true + ?column? +---------- + t +(1 row) + +SELECT lseg '[(1,1),(2,1)]' <@ line '[(0,0),(1,0)]'; -- false + ?column? +---------- + f +(1 row) + +SELECT lseg '[(1,1),(2,2)]' @ line '[(0,0),(2,2)]'; -- true + ?column? +---------- + t +(1 row) + +SELECT lseg '[(1,1),(2,1)]' @ line '[(0,0),(1,0)]'; -- false + ?column? +---------- + f +(1 row) + +SELECT point '(0,1)' ## line '[(0,0),(1,1)]'; + ?column? +----------- + (0.5,0.5) +(1 row) + +SELECT line '[(0,0),(1,1)]' ## lseg '[(1,0),(2,0)]'; + ?column? +---------- + (1,0) +(1 row) + +SELECT line '[(0,0),(1,1)]' ?# line '[(1,0),(2,1)]'; -- false + ?column? +---------- + f +(1 row) + +SELECT line '[(0,0),(1,1)]' ?# line '[(1,0),(1,1)]'; -- true + ?column? +---------- + t +(1 row) + +SELECT line '[(0,0),(1,1)]' # line '[(1,0),(2,1)]'; + ?column? +---------- + +(1 row) + +SELECT line '[(0,0),(1,1)]' # line '[(1,0),(1,1)]'; + ?column? +---------- + (1,1) +(1 row) + +SELECT line '[(0,0),(1,1)]' ?|| line '[(1,0),(2,1)]'; -- true + ?column? +---------- + t +(1 row) + +SELECT line '[(0,0),(1,1)]' ?|| line '[(1,0),(1,1)]'; -- false + ?column? +---------- + f +(1 row) + +SELECT line '[(0,0),(1,0)]' ?-| line '[(0,0),(0,1)]'; -- true + ?column? +---------- + t +(1 row) + +SELECT line '[(0,0),(1,1)]' ?-| line '[(1,0),(1,1)]'; -- false + ?column? +---------- + f +(1 row) + +SELECT ?- line '[(0,0),(1,0)]'; -- true + ?column? +---------- + t +(1 row) + +SELECT ?- line '[(0,0),(1,1)]'; -- false + ?column? +---------- + f +(1 row) + +SELECT ?| line '[(0,0),(0,1)]'; -- true + ?column? +---------- + t +(1 row) + +SELECT ?| line '[(0,0),(1,1)]'; -- false + ?column? +---------- + f +(1 row) + +SELECT line(point '(1,2)', point '(3,4)'); + line +---------- + {1,-1,1} +(1 row) + +SELECT line '[(1,2),(3,4)]' = line '[(3,4),(4,5)]'; -- true + ?column? +---------- + t +(1 row) + +SELECT line '[(1,2),(3,4)]' = line '[(3,4),(4,4)]'; -- false + ?column? +---------- + f +(1 row) + diff --git a/src/test/regress/expected/sanity_check.out b/src/test/regress/expected/sanity_check.out index 432d39a491..cee35aff3a 100644 --- a/src/test/regress/expected/sanity_check.out +++ b/src/test/regress/expected/sanity_check.out @@ -64,6 +64,7 @@ SELECT relname, relhasindex interval_tbl | f iportaltest | f kd_point_tbl | t + line_tbl | f log_table | f lseg_tbl | f main_table | f @@ -166,7 +167,7 @@ SELECT relname, relhasindex timetz_tbl | f tinterval_tbl | f varchar_tbl | f -(155 rows) +(156 rows) -- -- another sanity check: every system catalog that has OIDs should have diff --git a/src/test/regress/output/misc.source b/src/test/regress/output/misc.source index 29cbb22fb8..e194f7ed5c 100644 --- a/src/test/regress/output/misc.source +++ b/src/test/regress/output/misc.source @@ -638,6 +638,7 @@ SELECT user_relns() AS user_relns interval_tbl iportaltest kd_point_tbl + line_tbl log_table lseg_tbl main_table @@ -696,7 +697,7 @@ SELECT user_relns() AS user_relns tvvmv varchar_tbl xacttest -(118 rows) +(119 rows) SELECT name(equipment(hobby_construct(text 'skywalking', text 'mer'))); name diff --git a/src/test/regress/parallel_schedule b/src/test/regress/parallel_schedule index fd08e8ddf0..1c1491c3f3 100644 --- a/src/test/regress/parallel_schedule +++ b/src/test/regress/parallel_schedule @@ -23,7 +23,7 @@ test: numerology # ---------- # The second group of parallel tests # ---------- -test: point lseg box path polygon circle date time timetz timestamp timestamptz interval abstime reltime tinterval inet macaddr tstypes comments +test: point lseg line box path polygon circle date time timetz timestamp timestamptz interval abstime reltime tinterval inet macaddr tstypes comments # ---------- # Another group of parallel tests diff --git a/src/test/regress/serial_schedule b/src/test/regress/serial_schedule index 1ed059be6e..c4d451ab00 100644 --- a/src/test/regress/serial_schedule +++ b/src/test/regress/serial_schedule @@ -23,6 +23,7 @@ test: strings test: numerology test: point test: lseg +test: line test: box test: path test: polygon diff --git a/src/test/regress/sql/geometry.sql b/src/test/regress/sql/geometry.sql index 73f8032bb1..af7f8a51cc 100644 --- a/src/test/regress/sql/geometry.sql +++ b/src/test/regress/sql/geometry.sql @@ -58,10 +58,6 @@ SELECT '' AS count, p.f1, l.s, l.s # p.f1 AS intersection SELECT '' AS thirty, p.f1, l.s, p.f1 ## l.s AS closest FROM LSEG_TBL l, POINT_TBL p; --- --- Lines --- - -- -- Boxes -- diff --git a/src/test/regress/sql/line.sql b/src/test/regress/sql/line.sql new file mode 100644 index 0000000000..cd9280be47 --- /dev/null +++ b/src/test/regress/sql/line.sql @@ -0,0 +1,87 @@ +-- +-- LINE +-- Infinite lines +-- + +--DROP TABLE LINE_TBL; +CREATE TABLE LINE_TBL (s line); + +INSERT INTO LINE_TBL VALUES ('{1,-1,1}'); +INSERT INTO LINE_TBL VALUES ('(0,0),(6,6)'); +INSERT INTO LINE_TBL VALUES ('10,-10 ,-3,-4'); +INSERT INTO LINE_TBL VALUES ('[-1e6,2e2,3e5, -4e1]'); +INSERT INTO LINE_TBL VALUES ('(11,22,33,44)'); + +INSERT INTO LINE_TBL VALUES ('[(1,0),(1,0)]'); + +-- horizontal +INSERT INTO LINE_TBL VALUES ('[(1,3),(2,3)]'); +-- vertical +INSERT INTO LINE_TBL VALUES ('[(3,1),(3,2)]'); + +-- bad values for parser testing +INSERT INTO LINE_TBL VALUES ('{0,0,1}'); +INSERT INTO LINE_TBL VALUES ('(3asdf,2 ,3,4r2)'); +INSERT INTO LINE_TBL VALUES ('[1,2,3, 4'); +INSERT INTO LINE_TBL VALUES ('[(,2),(3,4)]'); +INSERT INTO LINE_TBL VALUES ('[(1,2),(3,4)'); + +select * from LINE_TBL; + + +-- functions and operators + +SELECT * FROM LINE_TBL WHERE (s <-> line '[(1,2),(3,4)]') < 10; + +SELECT * FROM LINE_TBL WHERE (point '(0.1,0.1)' <-> s) < 1; + +SELECT * FROM LINE_TBL WHERE (lseg '[(0.1,0.1),(0.2,0.2)]' <-> s) < 1; + +SELECT line '[(1,1),(2,1)]' <-> line '[(-1,-1),(-2,-1)]'; +SELECT lseg '[(1,1),(2,1)]' <-> line '[(-1,-1),(-2,-1)]'; +SELECT point '(-1,1)' <-> line '[(-3,0),(-4,0)]'; + +SELECT lseg '[(1,1),(5,5)]' ?# line '[(2,0),(0,2)]'; -- true +SELECT lseg '[(1,1),(5,5)]' ?# line '[(0,0),(1,0)]'; -- false + +SELECT line '[(0,0),(1,1)]' ?# box '(0,0,2,2)'; -- true +SELECT line '[(3,0),(4,1)]' ?# box '(0,0,2,2)'; -- false + +SELECT point '(1,1)' <@ line '[(0,0),(2,2)]'; -- true +SELECT point '(1,1)' <@ line '[(0,0),(1,0)]'; -- false + +SELECT point '(1,1)' @ line '[(0,0),(2,2)]'; -- true +SELECT point '(1,1)' @ line '[(0,0),(1,0)]'; -- false + +SELECT lseg '[(1,1),(2,2)]' <@ line '[(0,0),(2,2)]'; -- true +SELECT lseg '[(1,1),(2,1)]' <@ line '[(0,0),(1,0)]'; -- false + +SELECT lseg '[(1,1),(2,2)]' @ line '[(0,0),(2,2)]'; -- true +SELECT lseg '[(1,1),(2,1)]' @ line '[(0,0),(1,0)]'; -- false + +SELECT point '(0,1)' ## line '[(0,0),(1,1)]'; + +SELECT line '[(0,0),(1,1)]' ## lseg '[(1,0),(2,0)]'; + +SELECT line '[(0,0),(1,1)]' ?# line '[(1,0),(2,1)]'; -- false +SELECT line '[(0,0),(1,1)]' ?# line '[(1,0),(1,1)]'; -- true + +SELECT line '[(0,0),(1,1)]' # line '[(1,0),(2,1)]'; +SELECT line '[(0,0),(1,1)]' # line '[(1,0),(1,1)]'; + +SELECT line '[(0,0),(1,1)]' ?|| line '[(1,0),(2,1)]'; -- true +SELECT line '[(0,0),(1,1)]' ?|| line '[(1,0),(1,1)]'; -- false + +SELECT line '[(0,0),(1,0)]' ?-| line '[(0,0),(0,1)]'; -- true +SELECT line '[(0,0),(1,1)]' ?-| line '[(1,0),(1,1)]'; -- false + +SELECT ?- line '[(0,0),(1,0)]'; -- true +SELECT ?- line '[(0,0),(1,1)]'; -- false + +SELECT ?| line '[(0,0),(0,1)]'; -- true +SELECT ?| line '[(0,0),(1,1)]'; -- false + +SELECT line(point '(1,2)', point '(3,4)'); + +SELECT line '[(1,2),(3,4)]' = line '[(3,4),(4,5)]'; -- true +SELECT line '[(1,2),(3,4)]' = line '[(3,4),(4,4)]'; -- false -- 2.40.0