Re: [PATCH] Revive line type - Mailing list pgsql-hackers
| From | Peter Eisentraut |
|---|---|
| Subject | Re: [PATCH] Revive line type |
| Date | |
| Msg-id | 1372296877.5915.5.camel@vanquo.pezone.net Whole thread Raw |
| In response to | [PATCH] Revive line type (rui hua <365507506hua@gmail.com>) |
| Responses |
Re: [PATCH] Revive line type
Re: [PATCH] Revive line type |
| List | pgsql-hackers |
On Sun, 2013-06-23 at 12:24 +0800, rui hua wrote:
> Regression tests are all succeed, but several problems have be found while
> ding some simple test. The updated document said that the points used in
> the output are not necessarily the points used on input. I understand that
> as long as they are marked on the same line. But when the input data
> represents a horizontal or vertical line, the output is not exactly the
> same line. It is another line parallel to it.
> postgres=# select line('1,3,2,3');
> line
> -----------------
> [(0,-3),(1,-3)]
> (1 row)
This was just using the wrong sign. Fixed.
> In addition, when a straight line coincides with coordinate axis, output
> appears -0, I do not know whether it is appropriate.
This is a matter of the floating-point operations. I don't think it's
on scope to worry about that. With the above fix, the cases you pointed
out go away anyway.
> Negative value appeared when use <-> to calculate the distance between two
> parallel lines.
Fixed with fabs().
New patch included. Still wondering whether to use a A,B,C-based output
format per Tom's comment.
>From d765f8a515a6f3de0e68e68962e5109945260b8c Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <peter_e@gmx.net>
Date: Fri, 14 Jun 2013 20:23:15 -0400
Subject: [PATCH] Revive line type
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 | 34 +++-
doc/src/sgml/func.sgml | 6 +
src/backend/utils/adt/geo_ops.c | 112 +++++-------
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 | 267 ++++++++++++++++++++++++++++
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 | 86 +++++++++
13 files changed, 443 insertions(+), 88 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 f73e6b2..ecbbdd8 100644
--- a/doc/src/sgml/datatype.sgml
+++ b/doc/src/sgml/datatype.sgml
@@ -3066,7 +3066,7 @@ <title>Geometric Types</title>
<row>
<entry><type>line</type></entry>
<entry>32 bytes</entry>
- <entry>Infinite line (not fully implemented)</entry>
+ <entry>Infinite line</entry>
<entry>((x1,y1),(x2,y2))</entry>
</row>
<row>
@@ -3142,6 +3142,38 @@ <title>Points</title>
</sect2>
<sect2>
+ <title>Lines</title>
+
+ <indexterm>
+ <primary>line</primary>
+ </indexterm>
+
+ <para>
+ Lines (<type>line</type>) are specified by pairs of points.
+ Values of type <type>line</type> are specified using any of the following
+ syntaxes:
+
+<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>
+
+ <para>
+ Lines are output using the first syntax. The points used in the output
+ are not necessarily the points used on input.
+ </para>
+ </sect2>
+
+ <sect2>
<title>Line Segments</title>
<indexterm>
diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml
index 8cf5385..fd0e4a3 100644
--- a/doc/src/sgml/func.sgml
+++ b/doc/src/sgml/func.sgml
@@ -8070,6 +8070,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>lseg(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 ad18cf0..e668a21 100644
--- a/src/backend/utils/adt/geo_ops.c
+++ b/src/backend/utils/adt/geo_ops.c
@@ -933,13 +933,8 @@
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;
@@ -950,15 +945,13 @@
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
errmsg("invalid input syntax for type line: \"%s\"", str)));
+ 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 = (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);
}
@@ -967,66 +960,31 @@
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
-
+ lseg.p[0].x = lseg.p[1].x = - line->C/line->A;
+ lseg.p[0].y = 0;
+ lseg.p[1].y = 1;
}
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
-
+ lseg.p[0].x = 0;
+ lseg.p[1].x = 1;
+ lseg.p[0].y = lseg.p[1].y = - line->C/line->B;
}
else
{
+ lseg.p[0].x = 0;
+ lseg.p[0].y = - line->C/line->B;
+ lseg.p[1].x = 1;
+ lseg.p[1].y = (-line->C - line->A)/line->B;
}
- if (FPzero(line->A)) /* horizontal? */
- {
- }
- else if (FPzero(line->B)) /* vertical? */
- {
- }
- else
- {
- }
-
- return path_encode(TRUE, 2, (Point *) &(ls->p[0]));
-#else
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("type \"line\" not yet implemented")));
- result = NULL;
-#endif
-
- PG_RETURN_CSTRING(result);
+ PG_RETURN_CSTRING(path_encode(FALSE, 2, (Point *) &(lseg.p[0])));
}
/*
@@ -1035,10 +993,16 @@
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);
}
/*
@@ -1047,10 +1011,14 @@
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));
}
@@ -2447,8 +2415,8 @@
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
@@ -3036,6 +3004,7 @@
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;
@@ -3054,6 +3023,13 @@
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..0ef992d
--- /dev/null
+++ b/src/test/regress/expected/line.out
@@ -0,0 +1,267 @@
+--
+-- LINE
+-- Infinite lines
+--
+--DROP TABLE LINE_TBL;
+CREATE TABLE LINE_TBL (s line);
+INSERT INTO LINE_TBL VALUES ('[(1,2),(3,4)]');
+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 ('(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
+-----------------------------------------------
+ [(0,1),(1,2)]
+ [(0,0),(1,1)]
+ [(0,-5.38461538461538),(1,-5.84615384615385)]
+ [(0,15.3846153846154),(1,15.3844307692308)]
+ [(0,11),(1,12)]
+ [(0,3),(1,3)]
+ [(3,0),(3,1)]
+(7 rows)
+
+-- functions and operators
+SELECT * FROM LINE_TBL WHERE (s <-> line '[(1,2),(3,4)]') < 10;
+ s
+-----------------------------------------------
+ [(0,1),(1,2)]
+ [(0,0),(1,1)]
+ [(0,-5.38461538461538),(1,-5.84615384615385)]
+ [(0,15.3846153846154),(1,15.3844307692308)]
+ [(0,11),(1,12)]
+ [(0,3),(1,3)]
+ [(3,0),(3,1)]
+(7 rows)
+
+SELECT * FROM LINE_TBL WHERE (point '(0.1,0.1)' <-> s) < 1;
+ s
+---------------
+ [(0,1),(1,2)]
+ [(0,0),(1,1)]
+(2 rows)
+
+SELECT * FROM LINE_TBL WHERE (lseg '[(0.1,0.1),(0.2,0.2)]' <-> s) < 1;
+ s
+---------------
+ [(0,1),(1,2)]
+ [(0,0),(1,1)]
+(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
+---------------
+ [(0,1),(1,2)]
+(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 2af28b1..cbedeb5 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 d6eaa7a..5b86ede 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..b24f730
--- /dev/null
+++ b/src/test/regress/sql/line.sql
@@ -0,0 +1,86 @@
+--
+-- LINE
+-- Infinite lines
+--
+
+--DROP TABLE LINE_TBL;
+CREATE TABLE LINE_TBL (s line);
+
+INSERT INTO LINE_TBL VALUES ('[(1,2),(3,4)]');
+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 ('(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.7.10.4
pgsql-hackers by date: