pg.ddx.io  pgsql-sql@postgresql.org mailing list archive  
help / color / mirror / Atom feed
array_in: '{}}'::text[]
8+ messages / 3 participants
[nested] [flat]

* array_in: '{}}'::text[]
@ 2004-08-23 11:45  Markus Bertheau <twanger@bluetwanger.de>
  0 siblings, 2 replies; 8+ messages in thread

From: Markus Bertheau @ 2004-08-23 11:45 UTC (permalink / raw)
  To: pgsql-sql

Is there a reason the array_in parser accepts additional closing braces
at the end?

oocms=# SELECT '{}}'::text[];
 text
------
 {}
(1 запись)

Thanks

-- 
Markus Bertheau <twanger@bluetwanger.de>




^ permalink  raw  reply  [nested|flat] 8+ messages in thread

* Re: array_in: '{}}'::text[]
@ 2004-08-23 11:50  Markus Bertheau <twanger@bluetwanger.de>
  parent: Markus Bertheau <twanger@bluetwanger.de>
  1 sibling, 0 replies; 8+ messages in thread

From: Markus Bertheau @ 2004-08-23 11:50 UTC (permalink / raw)
  To: pgsql-sql

В Пнд, 23.08.2004, в 13:45, Markus Bertheau пишет:
> Is there a reason the array_in parser accepts additional closing braces
> at the end?

In fact it seems to accept everything after the closing brace matching
the first opening brace.

Thanks

-- 
Markus Bertheau <twanger@bluetwanger.de>




^ permalink  raw  reply  [nested|flat] 8+ messages in thread

* Re: array_in: '{}}'::text[]
@ 2004-08-23 18:32  Joe Conway <mail@joeconway.com>
  parent: Markus Bertheau <twanger@bluetwanger.de>
  1 sibling, 1 reply; 8+ messages in thread

From: Joe Conway @ 2004-08-23 18:32 UTC (permalink / raw)
  To: Markus Bertheau <twanger@bluetwanger.de>; +Cc: pgsql-sql

Markus Bertheau wrote:
> Is there a reason the array_in parser accepts additional closing braces
> at the end?
> 
> oocms=# SELECT '{}}'::text[];
>  text
> ------
>  {}
> (1 запись)

Hmmm, I was *about* to say that this is fixed in cvs (and indeed, the 
array_in parser is significantly tightened up compared to previous 
releases), but unfortunately, there is still work to be done :(

regression=# SELECT '{}}'::text[];
  text
------
  {}
(1 row)

regression=# select version();
                                                        version
---------------------------------------------------------------------------------------------------------------------
  PostgreSQL 8.0.0beta1 on x86_64-unknown-linux-gnu, compiled by GCC gcc 
(GCC) 3.3.3 20040412 (Red Hat Linux 3.3.3-7)
(1 row)

Look for a fix soon, at a cvs repository near you....

Joe



^ permalink  raw  reply  [nested|flat] 8+ messages in thread

* Re: [SQL] array_in: '{}}'::text[]
@ 2004-08-27 20:37  Joe Conway <mail@joeconway.com>
  parent: Joe Conway <mail@joeconway.com>
  0 siblings, 1 reply; 8+ messages in thread

From: Joe Conway @ 2004-08-27 20:37 UTC (permalink / raw)
  To: ; +Cc: Markus Bertheau <twanger@bluetwanger.de>; Patches (PostgreSQL) <pgsql-patches@postgresql.org>

Joe Conway wrote:
> Markus Bertheau wrote:
> 
>> Is there a reason the array_in parser accepts additional closing braces
>> at the end?
>>
>> oocms=# SELECT '{}}'::text[];
>>  text
>> ------
>>  {}
>> (1 запись)
> 
> 
> Hmmm, I was *about* to say that this is fixed in cvs (and indeed, the 
> array_in parser is significantly tightened up compared to previous 
> releases), but unfortunately, there is still work to be done :(

The attached patch takes care of the above issue:

regression=# SELECT '{}}'::text[];
ERROR:  malformed array literal: "{}}"

If there are no objections, I'll apply in about 24 hours.

Joe

Attachments:

current.80.diff (text/x-patch, 6.1K) download 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 27 Aug 2004 20:31:46 -0000 *************** *** 183,190 **** 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); /* --- 183,189 ---- typioparam = my_extra->typioparam; /* Make a modifiable copy of the input */ ! string_save = (char *) palloc0(strlen(string) + 1); strcpy(string_save, string); /* *************** *** 375,380 **** --- 374,380 ---- 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; --- 385,391 ---- } /* special case for an empty array */ ! if (strlen(str) == 2 && strncmp(str, "{}", 2) == 0) return 0; ptr = str; *************** *** 395,400 **** --- 395,404 ---- 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))); --- 485,492 ---- 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 **** --- 567,586 ---- 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 27 Aug 2004 20:31:46 -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 27 Aug 2004 20:31:46 -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
^ permalink raw reply [nested|flat] 8+ messages in thread

* Re: [SQL] array_in: '{}}'::text[]
@ 2004-08-28 03:05  Tom Lane <tgl@sss.pgh.pa.us>
  parent: Joe Conway <mail@joeconway.com>
  0 siblings, 1 reply; 8+ messages in thread

From: Tom Lane @ 2004-08-28 03:05 UTC (permalink / raw)
  To: Joe Conway <mail@joeconway.com>; +Cc: Markus Bertheau <twanger@bluetwanger.de>; Patches (PostgreSQL) <pgsql-patches@postgresql.org>

Joe Conway <mail@joeconway.com> writes:
>   	/* Make a modifiable copy of the input */
> ! 	string_save = (char *) palloc0(strlen(string) + 1);
>   	strcpy(string_save, string);

palloc0, instead of palloc, is clearly a waste of cycles here ...

actually, why isn't this just a pstrdup?

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

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

Looks reasonable otherwise.

			regards, tom lane



^ permalink  raw  reply  [nested|flat] 8+ messages in thread

* Re: [SQL] array_in: '{}}'::text[]
@ 2004-08-28 19:33  Joe Conway <mail@joeconway.com>
  parent: Tom Lane <tgl@sss.pgh.pa.us>
  0 siblings, 1 reply; 8+ messages in thread

From: Joe Conway @ 2004-08-28 19:33 UTC (permalink / raw)
  To: Tom Lane <tgl@sss.pgh.pa.us>; +Cc: Markus Bertheau <twanger@bluetwanger.de>; Patches (PostgreSQL) <pgsql-patches@postgresql.org>

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

Attachments:

current.80.diff (text/x-patch, 6.2K) download 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
^ permalink raw reply [nested|flat] 8+ messages in thread

* Re: [SQL] array_in: '{}}'::text[]
@ 2004-08-28 20:09  Markus Bertheau <twanger@bluetwanger.de>
  parent: Joe Conway <mail@joeconway.com>
  0 siblings, 1 reply; 8+ messages in thread

From: Markus Bertheau @ 2004-08-28 20:09 UTC (permalink / raw)
  To: Joe Conway <mail@joeconway.com>; +Cc: Tom Lane <tgl@sss.pgh.pa.us>; Patches (PostgreSQL) <pgsql-patches@postgresql.org>

В Сбт, 28.08.2004, в 21:33, Joe Conway пишет:

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

Without looking at the code in a whole, you accept '{} ' as an empty
array literal, so why is the special case for '{}' needed here? I should
be catched by the code that accepts additional whitespace after the last
closing brace, just that there is no white space:

> + 	/* 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;

Here's the second special case for empty arrays.

-- 
Markus Bertheau <twanger@bluetwanger.de>




^ permalink  raw  reply  [nested|flat] 8+ messages in thread

* Re: [SQL] array_in: '{}}'::text[]
@ 2004-08-28 22:41  Joe Conway <mail@joeconway.com>
  parent: Markus Bertheau <twanger@bluetwanger.de>
  0 siblings, 0 replies; 8+ messages in thread

From: Joe Conway @ 2004-08-28 22:41 UTC (permalink / raw)
  To: Markus Bertheau <twanger@bluetwanger.de>; +Cc: Tom Lane <tgl@sss.pgh.pa.us>; Patches (PostgreSQL) <pgsql-patches@postgresql.org>

Markus Bertheau wrote:
> 
> Without looking at the code in a whole, you accept '{} ' as an empty
> array literal, so why is the special case for '{}' needed here?

It's a fast path for a common special case. Why spend any cycles parsing 
if we can immediately recognize it? However, anything other than a 
simple '{}' does require parsing.

Joe



^ permalink  raw  reply  [nested|flat] 8+ messages in thread


end of thread, other threads:[~2004-08-28 22:41 UTC | newest]

Thread overview: 8+ messages (download: mbox mbox.gz follow: Atom feed)
-- links below jump to the message on this page --
2004-08-23 11:45 array_in: '{}}'::text[] Markus Bertheau <twanger@bluetwanger.de>
2004-08-23 11:50 ` Markus Bertheau <twanger@bluetwanger.de>
2004-08-23 18:32 ` Joe Conway <mail@joeconway.com>
2004-08-27 20:37   ` Joe Conway <mail@joeconway.com>
2004-08-28 03:05     ` Tom Lane <tgl@sss.pgh.pa.us>
2004-08-28 19:33       ` Joe Conway <mail@joeconway.com>
2004-08-28 20:09         ` Markus Bertheau <twanger@bluetwanger.de>
2004-08-28 22:41           ` Joe Conway <mail@joeconway.com>

This inbox is served by DDX for PostgreSQL; see mirroring instructions
for how to clone and mirror all data and code used for this inbox