BUG #8399: inconsistent input of multidimensional arrays

Started by Alexey Borzovover 12 years ago5 messagesbugs
Jump to latest
#1Alexey Borzov
borz_off@rdw.ru

The following bug has been logged on the website:

Bug reference: 8399
Logged by: Alexey Borzov
Email address: borz_off@cs.msu.su
PostgreSQL version: 9.3rc1
Operating system: irrelevant
Description:

PostgreSQL documentation states:

"Multidimensional arrays must have matching extents for each dimension. A
mismatch causes an error..."

This is not completely true:
postgres=# select cast('{{1,2}, {3}}' as integer[]);
ERROR: multidimensional arrays must have array expressions with matching
dimensions
LINE 1: select cast('{{1,2}, {3}}' as integer[]);
^
postgres=# select cast('{{1}, {2,3}}' as integer[]);
int4
------------------
{{1,NULL},{2,3}}
(1 row)

Trying to use an array constructor yields an expected error in both cases.

Confirmed on 9.3rc1 and 9.0.13

--
Sent via pgsql-bugs mailing list (pgsql-bugs@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-bugs

#2Bruce Momjian
bruce@momjian.us
In reply to: Alexey Borzov (#1)
Re: BUG #8399: inconsistent input of multidimensional arrays

On Tue, Aug 27, 2013 at 08:18:10AM +0000, borz_off@cs.msu.su wrote:

PostgreSQL documentation states:

"Multidimensional arrays must have matching extents for each dimension. A
mismatch causes an error..."

This is not completely true:
postgres=# select cast('{{1,2}, {3}}' as integer[]);
ERROR: multidimensional arrays must have array expressions with matching
dimensions
LINE 1: select cast('{{1,2}, {3}}' as integer[]);
^
postgres=# select cast('{{1}, {2,3}}' as integer[]);
int4
------------------
{{1,NULL},{2,3}}
(1 row)

Trying to use an array constructor yields an expected error in both cases.

Confirmed on 9.3rc1 and 9.0.13

This is a very interesting report. The behavior you are seeing is based
on this 2004 commit:

commit 0e13d627bebad769498696b5fd0ac821bde5140d
Author: Joe Conway <mail@joeconway.com>
Date: Thu Aug 5 03:30:44 2004 +0000

Require that array literals produce "rectangular" arrays, i.e. all the
subarrays of a given dimension have the same number of elements/subarrays.

Also repair a longstanding undocumented (as far as I can see) ability to
explicitly set array bounds in the array literal syntax. It now can
deal properly with negative array indicies. Modify array_out so that
arrays with non-standard lower bounds (i.e. not 1) are output with
the expicit dimension syntax. This fixes a longstanding issue whereby
arrays with non-default lower bounds had them changed to default
after a dump/reload cycle.

Modify regression tests and docs to suit, and add some minimal
documentation regarding the explicit dimension syntax.

Particularly, this block of code:

if ((nelems_last[nest_level] != 1) &&
(nelems[nest_level] != nelems_last[nest_level]))
ereport(ERROR,
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
errmsg("multidimensional arrays must have "
"array expressions with matching "
"dimensions")));

The nelems_last array is initialized to '1', so when an array comes in
that is one element, no check is made. I doubt this was intended.

What I have done is to change the initalization and test to -1, which
seems to fix the problem.

test=> select cast('{{1}, {2, 3}}' as integer[]);
ERROR: multidimensional arrays must have array expressions with matching dimensions
LINE 1: select cast('{{1}, {2, 3}}' as integer[]);

I was a little worried that this might break existing values stored in
the database, and hence dump/reload, but it seems the arrays are
extended with NULLs so it loads just fine:

CREATE TABLE test(x int[]);
INSERT INTO test SELECT cast('{{1}, {2, 3, 4, 5}}' AS integer[]);
COPY test TO stdout;
{{1,NULL,NULL,NULL},{2,3,4,5}}

Patch attached. The patch controls what strings are accepted as arrays
and will be an incompatibility for 9.4.

Joe, does this sound right?

--
Bruce Momjian <bruce@momjian.us> http://momjian.us
EnterpriseDB http://enterprisedb.com

+ Everyone has their own god. +

Attachments:

array.difftext/x-diff; charset=us-asciiDownload+11-11
#3Joe Conway
mail@joeconway.com
In reply to: Bruce Momjian (#2)
Re: BUG #8399: inconsistent input of multidimensional arrays

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 01/31/2014 05:11 PM, Bruce Momjian wrote:

On Tue, Aug 27, 2013 at 08:18:10AM +0000, borz_off@cs.msu.su
wrote:

PostgreSQL documentation states:

"Multidimensional arrays must have matching extents for each
dimension. A mismatch causes an error..."

This is not completely true: postgres=# select cast('{{1,2},
{3}}' as integer[]); ERROR: multidimensional arrays must have
array expressions with matching dimensions LINE 1: select
cast('{{1,2}, {3}}' as integer[]); ^ postgres=# select
cast('{{1}, {2,3}}' as integer[]); int4 ------------------
{{1,NULL},{2,3}} (1 row)

Trying to use an array constructor yields an expected error in
both cases.

Joe, does this sound right?

I believe back when that 2004 commit was made, arrays did not allow
NULL elements at all. So I guess this is an unintended side effect of,
or a latent bug exposed by, that change.

Let me take a closer look...

Joe

- --
Joe Conway
credativ LLC: http://www.credativ.us
Linux, PostgreSQL, and general Open Source
Training, Service, Consulting, & 24x7 Support
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.14 (GNU/Linux)
Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/

iQIcBAEBAgAGBQJS7FH1AAoJEDfy90M199hlMzUP/1e6h0UioXC7HkEgW4DLrI4v
V1lVWu3BB9rmQ6RBJMTA6/wJXm28X5etGrDAt0prQPMsvffNcSxZt5gStmMbvCDo
9+90ZrIYdjNJ8GKzojXYsPj7YDzXgkroyYIYW7fUyzjsJqDt8pfR8da5qDJeWyS8
44teI7hWd4RDRK2kBZlpr6gk/J8CSawBR9Noh5PdG1M39oeep2DcdjLbj+XNZB33
by4KiGi+Al8gLLpmyCZCVCukK92MrmOrauz9gyOto6wdcMjyb+rzdLnyAPUG5B/m
Kk+1UZhWSKKVi4DlujHOwzvAOlLpVMSYyPb5nwACkc2dDo42Huy3hyP83lSfaCiQ
Qkfvu4XglLvio0T/Ym1+dHYAEOdxn3ZdJDK2/UUuPTZwDjQbbI1+hHdIL3cJg7eH
imBSQz3aiaoOL98/CBtwOromNEeKlLzqLqVZO9qiJgWJlLgbXtJEGRjp/BKYZwYy
EFwxGPL0kEyS8LcGZbGVrRWrXgYerzhYahKuVgtV26HlNeml2c7bd0g7ldM5Tzzc
K8g6/sH1/Kx0DUsRsx2EiCitC9DE3mXn5ZYsWxMTYduFPR6T6qcCkNML6ZlSWhHS
Oi/bcQs3sNLOyCmkcXbxPHHTfPtrX7Zenj8JPSh8tkDmup9YqmtD1QHsqySxKpK1
eDWexdJBD/Ds5waDGitk
=9ygd
-----END PGP SIGNATURE-----

--
Sent via pgsql-bugs mailing list (pgsql-bugs@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-bugs

#4Joe Conway
mail@joeconway.com
In reply to: Joe Conway (#3)
Re: BUG #8399: inconsistent input of multidimensional arrays

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 01/31/2014 05:46 PM, Joe Conway wrote:

On 01/31/2014 05:11 PM, Bruce Momjian wrote:

Joe, does this sound right?

Let me take a closer look...

I had forgotten how convoluted the array code is ;-)

Yes, it looks correct to me, although I think I would initialize
nelems_last[i] to 0 rather than -1.

Joe

- --
Joe Conway
credativ LLC: http://www.credativ.us
Linux, PostgreSQL, and general Open Source
Training, Service, Consulting, & 24x7 Support
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.14 (GNU/Linux)
Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/

iQIcBAEBAgAGBQJS7IsEAAoJEDfy90M199hlH4YP/1ERkU0XEnZc2FWVANg8NLKk
kW3rIa+Q8UUHPVPuhD1GXSXsxBBs5XwJz9rWaTB05iO678eft1FvT2IHciCMKX2m
83FFkXQEEVLr26py+zBnuOVbnmpQ2ubmbr4ZL2fG7KYRzJkPGw4YNmXVWXgyOmOQ
gltB3G1q2bNvovIz8OAXkFxkDOjdxfWdbRpoT6pYTGt/wIa5AfWLYxU5v30WZXSC
rr0b5rJtn6y4+L2ZsU8HptMVOklbZOkD7+Oee7h5UMB2MazBFMKksaCuBuPGXqJj
2MKtb47xccWWY1mNVF9gdPUSIXtYDDtNjlsBnbP5bWO09UOEuSmoBZd4qG4XKI4b
3dLRskgHZfT5gZVEDaF+vS/7OHI0nGPKhgfT1kNGJZpSpbo5M7lRdcX+lCO4mTkz
7JPZoWmsUqAc8n0eEX/UuwTJL/mzFzowJ0YxaVnqRooIhXwDnQjYCydSuA8mtpTP
+qY4IV/4u6yK7c5tM8cOX9ZDkriXvF6yypeIvqKLzHwnu4/6D0RHIusY0fFC+GGY
1jBWHjLYywl59ThauRqWhONiqN1F0roOK0nbdwxe3mw8n+hu/wwmCpyWlPDxUaEa
CFXEN5b6uLXDM3Dy0RzvyFn2o0/c9dlleZWp7L8cV+WcU7iULo0LNMli90I+FK9z
Cho3QAatYJ6QovloFps/
=XbLY
-----END PGP SIGNATURE-----

--
Sent via pgsql-bugs mailing list (pgsql-bugs@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-bugs

#5Bruce Momjian
bruce@momjian.us
In reply to: Joe Conway (#4)
Re: BUG #8399: inconsistent input of multidimensional arrays

On Fri, Jan 31, 2014 at 09:49:56PM -0800, Joe Conway wrote:

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 01/31/2014 05:46 PM, Joe Conway wrote:

On 01/31/2014 05:11 PM, Bruce Momjian wrote:

Joe, does this sound right?

Let me take a closer look...

I had forgotten how convoluted the array code is ;-)

Yes, it looks correct to me, although I think I would initialize
nelems_last[i] to 0 rather than -1.

Thanks for the review. I went with zero as you suggested. Applied
patch attached.

--
Bruce Momjian <bruce@momjian.us> http://momjian.us
EnterpriseDB http://enterprisedb.com

+ Everyone has their own god. +

Attachments:

array.difftext/x-diff; charset=us-asciiDownload+12-12