Обсуждение: line type

Поиск
Список
Период
Сортировка

line type

От
Peter Eisentraut
Дата:
What's the deal with the line type?

It's installed in the catalogs and listed in the documentation,
varyingly as not implemented or not fully implemented, but all the
support functions throw an error.  Is there any known list of things
that would need to be done to make it fully implemented?  Or should we
just get rid of it?




Re: line type

От
Tom Lane
Дата:
Peter Eisentraut <peter_e@gmx.net> writes:
> What's the deal with the line type?
> It's installed in the catalogs and listed in the documentation,
> varyingly as not implemented or not fully implemented, but all the
> support functions throw an error.  Is there any known list of things
> that would need to be done to make it fully implemented?  Or should we
> just get rid of it?

Tom Lockhart seems to have lobotomized line_in and line_out in commit
402b47cffafcbbc66af8ee6b6340b4db09f00a7b.  A look in the archives
suggests it was because of my complaint the day before:
http://archives.postgresql.org/pgsql-hackers/1998-08/msg00346.php

I'm not sure there's anything wrong with line_in, but line_out is still
obviously broken.  However, there are a couple dozen other functions
taking/returning "line", and in general those don't look significantly
more bogus than any other part of geo_ops.c.

I do notice this comment above line_in:
**                Lines are not intended to be used as ADTs per se,**                but their ops are useful tools for
otherADT ops.  Thus,**                there are few relops.
 

but that argument seems specious from here.  Even if it's mostly a
support type, being able to get at it would be useful for
testing/debugging the other operations, I think.

I'd vote for fixing the I/O functions and adding some docs and
regression tests ... but on the other hand, I'm not volunteering
to do the work.
        regards, tom lane



[PATCH] Revive line type

От
Peter Eisentraut
Дата:
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.
---
This just revives existing functionality, doesn't add anything new.
One thing that the original code did not settle was how to convert a
line in form Ax+By+C=0 to the two-points output form.  Obviously, you
can just pick to random points on the line, but I wonder whether there
is a more standard solution.
doc/src/sgml/datatype.sgml                 |   34 +++-doc/src/sgml/func.sgml                     |    6
+src/backend/utils/adt/geo_ops.c           |  108 +++++--------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        |  243
++++++++++++++++++++++++++++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              |   77 +++++++++13 files
changed,408 insertions(+), 86 deletions(-)create mode 100644 src/test/regress/expected/line.outcreate 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>32bytes</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 4c5af4b..835a189 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..61a1900 100644
--- a/src/backend/utils/adt/geo_ops.c
+++ b/src/backend/utils/adt/geo_ops.c
@@ -933,13 +933,8 @@Datumline_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
inputsyntax 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 @@Datumline_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 @@Datumline_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 @@Datumline_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));}

@@ -3036,6 +3004,7 @@Datumclose_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        604DATA(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            628DATA(insert OID = 629 (  _line       PGNSP PGUID    -1 f b A f t
\0540 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 -
Specifiedby 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.
*-------------------------------------------------------------------*/typedefstruct{    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..39b912a
--- /dev/null
+++ b/src/test/regress/expected/line.out
@@ -0,0 +1,243 @@
+--
+-- 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)]');
+                                     ^
+-- 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)]
+(5 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)]
+(5 rows)
+
+SELECT * FROM LINE_TBL WHERE (point '(0.1,0.1)' <-> s) < 1;
+                       s                       
+-----------------------------------------------
+ [(0,1),(1,2)]
+ [(0,0),(1,1)]
+ [(0,-5.38461538461538),(1,-5.84615384615385)]
+(3 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)]
+ [(0,-5.38461538461538),(1,-5.84615384615385)]
+(3 rows)
+
+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: stringstest: numerologytest: pointtest: lseg
+test: linetest: boxtest: pathtest: 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..25e680d
--- /dev/null
+++ b/src/test/regress/sql/line.sql
@@ -0,0 +1,77 @@
+--
+-- 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)]');
+
+-- 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 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





Re: [PATCH] Revive line type

От
Tom Lane
Дата:
Peter Eisentraut <peter_e@gmx.net> writes:
> 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.
> ---
> This just revives existing functionality, doesn't add anything new.
> One thing that the original code did not settle was how to convert a
> line in form Ax+By+C=0 to the two-points output form.  Obviously, you
> can just pick to random points on the line, but I wonder whether there
> is a more standard solution.

ISTM printing a line as two points is an unfortunate representational
choice altogether.  If the internal form is Ax+By+C=0, shouldn't the
text form expose A,B,C directly?  What you've got here necessarily
suffers a lot of roundoff error during I/O conversions, and so it seems
pretty likely to fail dump-and-reload tests.
        regards, tom lane