Fix circle_in to accept "(x,y),r" as it's advertised to do.
authorTom Lane
Wed, 8 Apr 2020 00:50:02 +0000 (20:50 -0400)
committerTom Lane
Wed, 8 Apr 2020 00:50:02 +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 f8e74a007624bb2d9a730f9658c93b56c011f7f7..cb8f723e66be76e955b20ea9823d7e68a9315fd4 100644 (file)
@@ -4488,8 +4488,8 @@ poly_path(PG_FUNCTION_ARGS)
 /*     circle_in       -       convert a string to internal form.
  *
  *     External format: (center and radius of circle)
- *             "((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)
@@ -4503,16 +4503,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 > ');