Re: [PATCH] Revive line type - Mailing list pgsql-hackers
From | Peter Eisentraut |
---|---|
Subject | Re: [PATCH] Revive line type |
Date | |
Msg-id | 1379219721.10763.1.camel@vanquo.pezone.net Whole thread Raw |
In response to | Re: [PATCH] Revive line type (Peter Eisentraut <peter_e@gmx.net>) |
Responses |
Re: [PATCH] Revive line type
|
List | pgsql-hackers |
Here is a new patch for the line type, with a new input/output format {A,B,C}, as discussed in this thread. >From 837fcf5d9b1ee8e589ef4b19f7d6e575229ca758 Mon Sep 17 00:00:00 2001 From: Peter Eisentraut <peter_e@gmx.net> Date: Sun, 15 Sep 2013 00:02:06 -0400 Subject: [PATCH] Revive line type 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> --- doc/src/sgml/datatype.sgml | 42 ++++- doc/src/sgml/func.sgml | 6 + src/backend/utils/adt/geo_ops.c | 219 ++++++++++------------- 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(+), 148 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 87668ea..07f0385 100644 --- a/doc/src/sgml/datatype.sgml +++ b/doc/src/sgml/datatype.sgml @@ -3051,9 +3051,7 @@ <title>Geometric Types</title> <para> Geometric data types represent two-dimensional spatial objects. <xref linkend="datatype-geo-table"> shows the geometric - types available in <productname>PostgreSQL</productname>. The - most fundamental type, the point, forms the basis for all of the - other types. + types available in <productname>PostgreSQL</productname>. </para> <table id="datatype-geo-table"> @@ -3063,8 +3061,8 @@ <title>Geometric Types</title> <row> <entry>Name</entry> <entry>Storage Size</entry> - <entry>Representation</entry> <entry>Description</entry> + <entry>Representation</entry> </row> </thead> <tbody> @@ -3077,8 +3075,8 @@ <title>Geometric Types</title> <row> <entry><type>line</type></entry> <entry>32 bytes</entry> - <entry>Infinite line (not fully implemented)</entry> - <entry>((x1,y1),(x2,y2))</entry> + <entry>Infinite line</entry> + <entry>{A,B,C}</entry> </row> <row> <entry><type>lseg</type></entry> @@ -3153,6 +3151,38 @@ <title>Points</title> </sect2> <sect2> + <title>Lines</title> + + <indexterm> + <primary>line</primary> + </indexterm> + + <para> + Lines (<type>line</type>) are represented by the linear equation Ax + By + + C = 0, where A and B are not both zero. Values of + type <type>line</type> is input and output in the following form: +<synopsis> +{ <replaceable>A</replaceable>, <replaceable>B</replaceable>, <replaceable>C</replaceable> } +</synopsis> + + Alternatively, any of the following forms can be used for input: + +<synopsis> +[ ( <replaceable>x1</replaceable> , <replaceable>y1</replaceable> ) , ( <replaceable>x2</replaceable> , <replaceable>y2</replaceable>) ] +( ( <replaceable>x1</replaceable> , <replaceable>y1</replaceable> ) , ( <replaceable>x2</replaceable> , <replaceable>y2</replaceable>) ) + ( <replaceable>x1</replaceable> , <replaceable>y1</replaceable> ) , ( <replaceable>x2</replaceable> , <replaceable>y2</replaceable>) + <replaceable>x1</replaceable> , <replaceable>y1</replaceable> , <replaceable>x2</replaceable> , <replaceable>y2</replaceable> +</synopsis> + + where + <literal>(<replaceable>x1</replaceable>,<replaceable>y1</replaceable>)</literal> + and + <literal>(<replaceable>x2</replaceable>,<replaceable>y2</replaceable>)</literal> + are two (different) points on the line. + </para> + </sect2> + + <sect2> <title>Line Segments</title> <indexterm> diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml index ee1c957..8f60c56 100644 --- a/doc/src/sgml/func.sgml +++ b/doc/src/sgml/func.sgml @@ -8123,6 +8123,12 @@ <title>Geometric Type Conversion Functions</title> <entry><literal>circle(polygon '((0,0),(1,1),(2,0))')</literal></entry> </row> <row> + <entry><literal><function>line(<type>point</type>, <type>point</type>)</function></literal></entry> + <entry><type>line</type></entry> + <entry>points to line</entry> + <entry><literal>line(point '(-1,0)', point '(1,0)')</literal></entry> + </row> + <row> <entry> <indexterm> <primary>lseg</primary> diff --git a/src/backend/utils/adt/geo_ops.c b/src/backend/utils/adt/geo_ops.c index 5d0b596..6bfe6d7 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 @@ -2789,9 +2756,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 +3003,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 +3022,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 e3822fa..2081312 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 - - - dp 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 5c83a71..1e648c0 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 8123725..21ad555 100644 --- a/src/test/regress/expected/geometry.out +++ b/src/test/regress/expected/geometry.out @@ -146,9 +146,6 @@ SELECT '' AS thirty, p.f1, l.s, p.f1 ## l.s AS closest (30 rows) -- --- Lines --- --- -- Boxes -- SELECT '' as six, box(f1) AS box FROM CIRCLE_TBL; diff --git a/src/test/regress/expected/line.out b/src/test/regress/expected/line.out new file mode 100644 index 0000000..7d222fc --- /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 432d39a..cee35af 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 29cbb22..e194f7e 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 fd08e8d..1c1491c 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 inetmacaddr tstypes comments +test: point lseg line box path polygon circle date time timetz timestamp timestamptz interval abstime reltime tintervalinet macaddr tstypes comments # ---------- # Another group of parallel tests diff --git a/src/test/regress/serial_schedule b/src/test/regress/serial_schedule index 1ed059b..c4d451a 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 73f8032..af7f8a5 100644 --- a/src/test/regress/sql/geometry.sql +++ b/src/test/regress/sql/geometry.sql @@ -59,10 +59,6 @@ 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 0000000..cd9280b --- /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 -- 1.8.4.rc3
pgsql-hackers by date: