Re: BUG #8399: inconsistent input of multidimensional arrays

Поиск
Список
Период
Сортировка
От Bruce Momjian
Тема Re: BUG #8399: inconsistent input of multidimensional arrays
Дата
Msg-id 20140201011125.GG19957@momjian.us
обсуждение исходный текст
Ответ на BUG #8399: inconsistent input of multidimensional arrays  (borz_off@cs.msu.su)
Ответы Re: BUG #8399: inconsistent input of multidimensional arrays  (Joe Conway <mail@joeconway.com>)
Список pgsql-bugs
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. +

Вложения

В списке pgsql-bugs по дате отправления:

Предыдущее
От: Bruce Momjian
Дата:
Сообщение: Re: BUG #8398: to_json(''::hstore) gives invalid JSON
Следующее
От: Joe Conway
Дата:
Сообщение: Re: BUG #8399: inconsistent input of multidimensional arrays