X-Original-To: pgsql-patches-postgresql.org@localhost.postgresql.org Received: from localhost (unknown [200.46.204.144]) by svr1.postgresql.org (Postfix) with ESMTP id AD0195E46E1 for ; Sat, 28 Aug 2004 16:33:44 -0300 (ADT) Received: from svr1.postgresql.org ([200.46.204.71]) by localhost (av.hub.org [200.46.204.144]) (amavisd-new, port 10024) with ESMTP id 53124-05 for ; Sat, 28 Aug 2004 19:33:35 +0000 (GMT) Received: from joeconway.com (66-146-172-86.skyriver.net [66.146.172.86]) by svr1.postgresql.org (Postfix) with ESMTP id 909E75E46D4 for ; Sat, 28 Aug 2004 16:33:34 -0300 (ADT) Received: from [192.168.4.3] (account jconway [192.168.4.3] verified) by joeconway.com (CommuniGate Pro SMTP 4.1.8) with ESMTP-TLS id 2150597; Sat, 28 Aug 2004 12:25:40 -0700 Message-ID: <4130DE0F.7030207@joeconway.com> Date: Sat, 28 Aug 2004 12:33:35 -0700 From: Joe Conway User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.7.2) Gecko/20040803 X-Accept-Language: en-us, en MIME-Version: 1.0 To: Tom Lane Cc: Markus Bertheau , "Patches (PostgreSQL)" Subject: Re: [SQL] array_in: '{}}'::text[] References: <1093261555.2647.6.camel@dicaprio.akademie1.de> <412A384C.5000907@joeconway.com> <412F9BA5.8070009@joeconway.com> <14978.1093662341@sss.pgh.pa.us> In-Reply-To: <14978.1093662341@sss.pgh.pa.us> Content-Type: multipart/mixed; boundary="------------000400010602080505040301" X-Virus-Scanned: by amavisd-new at hub.org X-Spam-Status: No, hits=0.0 tagged_above=0.0 required=5.0 tests= X-Spam-Level: X-Archive-Number: 200408/523 X-Sequence-Number: 12812 This is a multi-part message in MIME format. --------------000400010602080505040301 Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit 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 --------------000400010602080505040301 Content-Type: text/x-patch; name="current.80.diff" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="current.80.diff" 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 --------------000400010602080505040301--