Re: Cleaning up array_in()

jian he <jian.universality@gmail.com>

From: jian he <jian.universality@gmail.com>
To: Heikki Linnakangas <hlinnaka@iki.fi>
Cc: Tom Lane <tgl@sss.pgh.pa.us>, Nikhil Benesch <nikhil.benesch@gmail.com>, Alexander Lakhin <exclusion@gmail.com>, Nathan Bossart <nathandbossart@gmail.com>, pgsql-hackers@lists.postgresql.org
Date: 2023-08-07T05:35:03Z
Lists: pgsql-hackers

Attachments

hi.
based on Heikki v3.
I made some changes:
array_in: dim[6] all initialize with -1, lBound[6] all initialize with 1.
if ReadArrayDimensions called, then corresponding dimension lBound
will replace the initialized default 1 value.
ReadArrayStr, since array_in main function initialized dim array,
dimensions_specified true or false, I don't need to initialize again,
so I deleted that part.

to solve corner cases like  '{{1,},{1},}'::text[]. in ReadArrayStr
main switch function, like other ArrayToken, first evaluate
expect_delim then assign expect_delim.
In ATOK_LEVEL_END. if non-empty array, closing bracket either precede
with an element or another closing element. In both cases, the
previous expect_delim should be true.

in
         * FIXME: Is this still required? I believe all the checks it
performs are
         * redundant with other checks in ReadArrayDimension() and
ReadArrayStr()
         */
I deleted
-       nitems_according_to_dims = ArrayGetNItemsSafe(ndim, dim, escontext);
-       if (nitems_according_to_dims < 0)
-               PG_RETURN_NULL();
-       if (nitems != nitems_according_to_dims)
-               elog(ERROR, "mismatch nitems, %d vs %d", nitems,
nitems_according_to_dims);
but I am not sure if the following is necessary.
      if (!ArrayCheckBoundsSafe(ndim, dim, lBound, escontext))
                PG_RETURN_NULL();

I added some corner case tests like select '{{1,},{1},}'::text[];

some changes broken:
select '{{1},{}}'::text[];
-DETAIL:  Multidimensional arrays must have sub-arrays with matching dimensions.
+DETAIL:  Unexpected "," character.
I added some error checks in ATOK_LEVEL_END. The first expect_delim
part check will first generate an error, the dimension error part will
not be reached.

Commits

  1. Don't specify number of dimensions in cases where we don't know it.

  2. Improve readability and error detection of array_in().

  3. Add trailing commas to enum definitions