*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/adt/arrayfuncs.c,v 1.107 2004/08/08 05:01:55 joe Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/adt/arrayfuncs.c,v 1.108 2004/08/28 19:31:28 joe Exp $
*
*-------------------------------------------------------------------------
*/
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);
+ string_save = pstrdup(string);
/*
* If the input string starts with dimension info, read and use that.
nelems_last[MAXDIM];
bool scanning_string = false;
bool eoArray = false;
+ bool empty_array = true;
char *ptr;
ArrayParseState parse_state = ARRAY_NO_LEVEL;
}
/* special case for an empty array */
- if (strncmp(str, "{}", 2) == 0)
+ if (strcmp(str, "{}") == 0)
return 0;
ptr = str;
while (!itemdone)
{
+ if (parse_state == ARRAY_ELEM_STARTED ||
+ parse_state == ARRAY_QUOTED_ELEM_STARTED)
+ empty_array = false;
+
switch (*ptr)
{
case '\0':
if (parse_state != ARRAY_ELEM_STARTED &&
parse_state != ARRAY_ELEM_COMPLETED &&
parse_state != ARRAY_QUOTED_ELEM_COMPLETED &&
- parse_state != ARRAY_LEVEL_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)));
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];
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
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