Fix circle_in to accept "(x,y),r" as it's advertised to do.
authorTom Lane <tgl@sss.pgh.pa.us>
Wed, 8 Apr 2020 00:50:02 +0000 (20:50 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Wed, 8 Apr 2020 00:50:28 +0000 (20:50 -0400)
Our documentation describes four allowed input syntaxes for circles,
but the regression tests tried only three ... with predictable
consequences.  Remarkably, this has been wrong since the circle
datatype was added in 1997, but nobody noticed till now.

David Zhang, with some help from me

Discussion: https://postgr.es/m/332c47fa-d951-7574-b5cc-a8f7f7201202@highgo.ca

src/backend/utils/adt/geo_ops.c
src/test/regress/expected/circle.out
src/test/regress/sql/circle.sql

index 71ee7f8f08e8bf6387024da92447c0748fc3d01e..a7db7839588817175231c3b8e62703bc94e37457 100644 (file)
@@ -4604,8 +4604,8 @@ poly_path(PG_FUNCTION_ARGS)
 /*     circle_in       -       convert a string to internal form.
  *
  *     External format: (center and radius of circle)
- *             "((f8,f8)<f8>)"
- *             also supports quick entry style "(f8,f8,f8)"
+ *             "<(f8,f8),f8>"
+ *             also supports quick entry style "f8,f8,f8"
  */
 Datum
 circle_in(PG_FUNCTION_ARGS)
@@ -4619,16 +4619,19 @@ circle_in(PG_FUNCTION_ARGS)
    s = str;
    while (isspace((unsigned char) *s))
        s++;
-   if ((*s == LDELIM_C) || (*s == LDELIM))
+   if (*s == LDELIM_C)
+       depth++, s++;
+   else if (*s == LDELIM)
    {
-       depth++;
+       /* If there are two left parens, consume the first one */
        cp = (s + 1);
        while (isspace((unsigned char) *cp))
            cp++;
        if (*cp == LDELIM)
-           s = cp;
+           depth++, s = cp;
    }
 
+   /* pair_decode will consume parens around the pair, if any */
    pair_decode(s, &circle->center.x, &circle->center.y, &s, "circle", str);
 
    if (*s == DELIM)
index 218300f12637dd64a8cf9cf9ad1942cc2e308955..eb497a23843e49b0c9d730ab7f759d6229d8bfda 100644 (file)
@@ -6,10 +6,10 @@
 SET extra_float_digits = -1;
 CREATE TABLE CIRCLE_TBL (f1 circle);
 INSERT INTO CIRCLE_TBL VALUES ('<(5,1),3>');
-INSERT INTO CIRCLE_TBL VALUES ('<(1,2),100>');
-INSERT INTO CIRCLE_TBL VALUES ('1,3,5');
-INSERT INTO CIRCLE_TBL VALUES ('((1,2),3)');
-INSERT INTO CIRCLE_TBL VALUES ('<(100,200),10>');
+INSERT INTO CIRCLE_TBL VALUES ('((1,2),100)');
+INSERT INTO CIRCLE_TBL VALUES (' 1 , 3 , 5 ');
+INSERT INTO CIRCLE_TBL VALUES (' ( ( 1 , 2 ) , 3 ) ');
+INSERT INTO CIRCLE_TBL VALUES (' ( 100 , 200 ) , 10 ');
 INSERT INTO CIRCLE_TBL VALUES (' < ( 100 , 1 ) , 115 > ');
 INSERT INTO CIRCLE_TBL VALUES ('<(3,5),0>');   -- Zero radius
 INSERT INTO CIRCLE_TBL VALUES ('<(3,5),NaN>'); -- NaN radius
index 7e582c6c29d78a78cfb5f75c1a3355d707128bfc..170d6bee97755cedc686706a7aaa2f9a7f319a15 100644 (file)
@@ -10,13 +10,13 @@ CREATE TABLE CIRCLE_TBL (f1 circle);
 
 INSERT INTO CIRCLE_TBL VALUES ('<(5,1),3>');
 
-INSERT INTO CIRCLE_TBL VALUES ('<(1,2),100>');
+INSERT INTO CIRCLE_TBL VALUES ('((1,2),100)');
 
-INSERT INTO CIRCLE_TBL VALUES ('1,3,5');
+INSERT INTO CIRCLE_TBL VALUES (' 1 , 3 , 5 ');
 
-INSERT INTO CIRCLE_TBL VALUES ('((1,2),3)');
+INSERT INTO CIRCLE_TBL VALUES (' ( ( 1 , 2 ) , 3 ) ');
 
-INSERT INTO CIRCLE_TBL VALUES ('<(100,200),10>');
+INSERT INTO CIRCLE_TBL VALUES (' ( 100 , 200 ) , 10 ');
 
 INSERT INTO CIRCLE_TBL VALUES (' < ( 100 , 1 ) , 115 > ');