Re: [SQL] array_in: '{}}'::text[] - Mailing list pgsql-patches

From Joe Conway
Subject Re: [SQL] array_in: '{}}'::text[]
Date
Msg-id 4130DE0F.7030207@joeconway.com
Whole thread Raw
In response to Re: [SQL] array_in: '{}}'::text[]  (Tom Lane <tgl@sss.pgh.pa.us>)
Responses Re: [SQL] array_in: '{}}'::text[]
List pgsql-patches
Tom Lane wrote:
>
> actually, why isn't this just a pstrdup?

> Why not just if (strcmp(str, "{}") == 0)
>

Good points. Changes made, and attached committed.

Joe
Index: src/backend/utils/adt/arrayfuncs.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/backend/utils/adt/arrayfuncs.c,v
retrieving revision 1.107
diff -c -r1.107 arrayfuncs.c
*** src/backend/utils/adt/arrayfuncs.c    8 Aug 2004 05:01:55 -0000    1.107
--- src/backend/utils/adt/arrayfuncs.c    28 Aug 2004 19:19:22 -0000
***************
*** 183,191 ****
      typioparam = my_extra->typioparam;

      /* Make a modifiable copy of the input */
!     /* XXX why are we allocating an extra 2 bytes here? */
!     string_save = (char *) palloc(strlen(string) + 3);
!     strcpy(string_save, string);

      /*
       * If the input string starts with dimension info, read and use that.
--- 183,189 ----
      typioparam = my_extra->typioparam;

      /* Make a modifiable copy of the input */
!     string_save = pstrdup(string);

      /*
       * If the input string starts with dimension info, read and use that.
***************
*** 375,380 ****
--- 373,379 ----
                      nelems_last[MAXDIM];
      bool            scanning_string = false;
      bool            eoArray = false;
+     bool            empty_array = true;
      char           *ptr;
      ArrayParseState    parse_state = ARRAY_NO_LEVEL;

***************
*** 385,391 ****
      }

      /* special case for an empty array */
!     if (strncmp(str, "{}", 2) == 0)
          return 0;

      ptr = str;
--- 384,390 ----
      }

      /* special case for an empty array */
!     if (strcmp(str, "{}") == 0)
          return 0;

      ptr = str;
***************
*** 395,400 ****
--- 394,403 ----

          while (!itemdone)
          {
+             if (parse_state == ARRAY_ELEM_STARTED ||
+                 parse_state == ARRAY_QUOTED_ELEM_STARTED)
+                 empty_array = false;
+
              switch (*ptr)
              {
                  case '\0':
***************
*** 481,487 ****
                          if (parse_state != ARRAY_ELEM_STARTED &&
                              parse_state != ARRAY_ELEM_COMPLETED &&
                              parse_state != ARRAY_QUOTED_ELEM_COMPLETED &&
!                             parse_state != ARRAY_LEVEL_COMPLETED)
                              ereport(ERROR,
                                  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
                                  errmsg("malformed array literal: \"%s\"", str)));
--- 484,491 ----
                          if (parse_state != ARRAY_ELEM_STARTED &&
                              parse_state != ARRAY_ELEM_COMPLETED &&
                              parse_state != ARRAY_QUOTED_ELEM_COMPLETED &&
!                             parse_state != ARRAY_LEVEL_COMPLETED &&
!                             !(nest_level == 1 &&  parse_state == ARRAY_LEVEL_STARTED))
                              ereport(ERROR,
                                  (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
                                  errmsg("malformed array literal: \"%s\"", str)));
***************
*** 562,567 ****
--- 566,585 ----
          temp[ndim - 1]++;
          ptr++;
      }
+
+     /* only whitespace is allowed after the closing brace */
+     while (*ptr)
+     {
+         if (!isspace(*ptr++))
+             ereport(ERROR,
+                 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
+                 errmsg("malformed array literal: \"%s\"", str)));
+     }
+
+     /* special case for an empty array */
+     if (empty_array)
+         return 0;
+
      for (i = 0; i < ndim; ++i)
          dim[i] = temp[i];

Index: src/test/regress/expected/arrays.out
===================================================================
RCS file: /cvsroot/pgsql-server/src/test/regress/expected/arrays.out,v
retrieving revision 1.22
diff -c -r1.22 arrays.out
*** src/test/regress/expected/arrays.out    5 Aug 2004 03:30:03 -0000    1.22
--- src/test/regress/expected/arrays.out    28 Aug 2004 19:19:22 -0000
***************
*** 425,427 ****
--- 425,485 ----
   t
  (1 row)

+ --
+ -- General array parser tests
+ --
+ -- none of the following should be accepted
+ select '{{1,{2}},{2,3}}'::text[];
+ ERROR:  malformed array literal: "{{1,{2}},{2,3}}"
+ select '{{},{}}'::text[];
+ ERROR:  malformed array literal: "{{},{}}"
+ select '{{1,2},\\{2,3}}'::text[];
+ ERROR:  malformed array literal: "{{1,2},\{2,3}}"
+ select '{{"1 2" x},{3}}'::text[];
+ ERROR:  malformed array literal: "{{"1 2" x},{3}}"
+ select '{}}'::text[];
+ ERROR:  malformed array literal: "{}}"
+ select '{ }}'::text[];
+ ERROR:  malformed array literal: "{ }}"
+ -- none of the above should be accepted
+ -- all of the following should be accepted
+ select '{}'::text[];
+  text
+ ------
+  {}
+ (1 row)
+
+ select '{{{1,2,3,4},{2,3,4,5}},{{3,4,5,6},{4,5,6,7}}}'::text[];
+                      text
+ -----------------------------------------------
+  {{{1,2,3,4},{2,3,4,5}},{{3,4,5,6},{4,5,6,7}}}
+ (1 row)
+
+ select '{0 second  ,0 second}'::interval[];
+    interval
+ ---------------
+  {"@ 0","@ 0"}
+ (1 row)
+
+ select '{ { "," } , { 3 } }'::text[];
+     text
+ -------------
+  {{","},{3}}
+ (1 row)
+
+ select '  {   {  "  0 second  "   ,  0 second  }   }'::text[];
+              text
+ -------------------------------
+  {{"  0 second  ","0 second"}}
+ (1 row)
+
+ select '{
+            0 second,
+            @ 1 hour @ 42 minutes @ 20 seconds
+          }'::interval[];
+               interval
+ ------------------------------------
+  {"@ 0","@ 1 hour 42 mins 20 secs"}
+ (1 row)
+
+ -- all of the above should be accepted
Index: src/test/regress/sql/arrays.sql
===================================================================
RCS file: /cvsroot/pgsql-server/src/test/regress/sql/arrays.sql,v
retrieving revision 1.17
diff -c -r1.17 arrays.sql
*** src/test/regress/sql/arrays.sql    9 Jun 2004 19:08:20 -0000    1.17
--- src/test/regress/sql/arrays.sql    28 Aug 2004 19:19:22 -0000
***************
*** 192,194 ****
--- 192,219 ----
  select 'foo' not like all (array['%a', '%o']); -- f
  select 'foo' ilike any (array['%A', '%O']); -- t
  select 'foo' ilike all (array['F%', '%O']); -- t
+
+ --
+ -- General array parser tests
+ --
+
+ -- none of the following should be accepted
+ select '{{1,{2}},{2,3}}'::text[];
+ select '{{},{}}'::text[];
+ select '{{1,2},\\{2,3}}'::text[];
+ select '{{"1 2" x},{3}}'::text[];
+ select '{}}'::text[];
+ select '{ }}'::text[];
+ -- none of the above should be accepted
+
+ -- all of the following should be accepted
+ select '{}'::text[];
+ select '{{{1,2,3,4},{2,3,4,5}},{{3,4,5,6},{4,5,6,7}}}'::text[];
+ select '{0 second  ,0 second}'::interval[];
+ select '{ { "," } , { 3 } }'::text[];
+ select '  {   {  "  0 second  "   ,  0 second  }   }'::text[];
+ select '{
+            0 second,
+            @ 1 hour @ 42 minutes @ 20 seconds
+          }'::interval[];
+ -- all of the above should be accepted

pgsql-patches by date:

Previous
From: Tom Lane
Date:
Subject: Re: log_filename_prefix --> log_filename + strftime()
Next
From: Markus Bertheau
Date:
Subject: Re: [SQL] array_in: '{}}'::text[]