Change array_push and array_cat so that they retain the lower bound of
authorTom Lane <tgl@sss.pgh.pa.us>
Sat, 19 Nov 2005 01:50:08 +0000 (01:50 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Sat, 19 Nov 2005 01:50:08 +0000 (01:50 +0000)
the array (for array_push) or higher-dimensional array (for array_cat)
rather than decrementing it as before.  This avoids generating lower
bounds other than one for any array operation within the SQL spec.  Per
recent discussion.
Interestingly, this seems to have been the original behavior, because
while updating the docs I noticed that a large fraction of relevant
examples were *wrong* for the old behavior and are now right.  Is it
worth correcting this in the back-branch docs?

doc/src/sgml/array.sgml
doc/src/sgml/func.sgml
src/backend/utils/adt/array_userfuncs.c
src/test/regress/expected/arrays.out

index c24646e43ca22d63db890e9765d63b229cdbf8ab..9255144999d6291afc93e192a06bce773e6b5f2a 100644 (file)
@@ -1,4 +1,4 @@
-<!-- $PostgreSQL: pgsql/doc/src/sgml/array.sgml,v 1.47 2005/11/17 22:14:50 tgl Exp $ -->
+<!-- $PostgreSQL: pgsql/doc/src/sgml/array.sgml,v 1.48 2005/11/19 01:50:08 tgl Exp $ -->
 
 <sect1 id="arrays">
  <title>Arrays</title>
@@ -391,13 +391,11 @@ SELECT ARRAY[5,6] || ARRAY[[1,2],[3,4]];
  </para>
 
  <para>
-  When a single element is pushed on to the beginning of a one-dimensional
-  array, the result is an array with a lower bound subscript equal to
-  the right-hand operand's lower bound subscript, minus one. When a single
-  element is pushed on to the end of a one-dimensional array, the result is
-  an array retaining the lower bound of the left-hand operand. For example:
+  When a single element is pushed on to either the beginning or end of a
+  one-dimensional array, the result is an array with the same lower bound
+  subscript as the array operand. For example:
 <programlisting>
-SELECT array_dims(1 || ARRAY[2,3]);
+SELECT array_dims(1 || '[0:1]={2,3}'::int[]);
  array_dims
 ------------
  [0:2]
@@ -441,7 +439,7 @@ SELECT array_dims(ARRAY[[1,2],[3,4]] || ARRAY[[5,6],[7,8],[9,0]]);
 SELECT array_dims(ARRAY[1,2] || ARRAY[[3,4],[5,6]]);
  array_dims
 ------------
- [0:2][1:2]
+ [1:3][1:2]
 (1 row)
 </programlisting>
  </para>
index 8bc963b02ff3a145564557e45fa9cc4e3b0b87c3..c0e364a30b87cca1c754d826b2e6cbc81ac68e47 100644 (file)
@@ -1,5 +1,5 @@
 <!--
-$PostgreSQL: pgsql/doc/src/sgml/func.sgml,v 1.293 2005/11/17 22:14:50 tgl Exp $
+$PostgreSQL: pgsql/doc/src/sgml/func.sgml,v 1.294 2005/11/19 01:50:08 tgl Exp $
 PostgreSQL documentation
 -->
 
@@ -7484,7 +7484,7 @@ SELECT NULLIF(value, '(none)') ...
     </entry>
         <entry><type>int</type></entry>
         <entry>returns lower bound of the requested array dimension</entry>
-        <entry><literal>array_lower(array_prepend(0, ARRAY[1,2,3]), 1)</literal></entry>
+        <entry><literal>array_lower('[0:2]={1,2,3}'::int[], 1)</literal></entry>
         <entry><literal>0</literal></entry>
        </row>
        <row>
index 468e444e139c4e5839e2008ea4a83d9de183f1c2..e1fc3f26db06be33033492fab772fd0851a8c823 100644 (file)
@@ -6,7 +6,7 @@
  * Copyright (c) 2003-2005, PostgreSQL Global Development Group
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/utils/adt/array_userfuncs.c,v 1.17 2005/11/17 22:14:52 tgl Exp $
+ *   $PostgreSQL: pgsql/src/backend/utils/adt/array_userfuncs.c,v 1.18 2005/11/19 01:50:08 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -152,6 +152,13 @@ array_push(PG_FUNCTION_ARGS)
    result = array_set(v, 1, &indx, newelem, isNull,
                       -1, typlen, typbyval, typalign);
 
+   /*
+    * Readjust result's LB to match the input's.  This does nothing in the
+    * append case, but it's the simplest way to implement the prepend case.
+    */
+   if (ARR_NDIM(v) == 1)
+       ARR_LBOUND(result)[0] = ARR_LBOUND(v)[0];
+
    PG_RETURN_ARRAYTYPE_P(result);
 }
 
@@ -305,7 +312,7 @@ array_cat(PG_FUNCTION_ARGS)
    {
        /*
         * resulting array has the second argument as the outer array, with
-        * the first argument appended to the front of the outer dimension
+        * the first argument inserted at the front of the outer dimension
         */
        ndims = ndims2;
        dims = (int *) palloc(ndims * sizeof(int));
@@ -316,9 +323,6 @@ array_cat(PG_FUNCTION_ARGS)
        /* increment number of elements in outer array */
        dims[0] += 1;
 
-       /* decrement outer array lower bound */
-       lbs[0] -= 1;
-
        /* make sure the added element matches our existing elements */
        for (i = 0; i < ndims1; i++)
        {
index da218f0047c7f0e1438d93fb9e0ed7580b52699e..11b83ea993618f80c30b77c8871ac3368af6d5d0 100644 (file)
@@ -224,9 +224,9 @@ SELECT array_append(array[42], 6) AS "{42,6}";
 (1 row)
 
 SELECT array_prepend(6, array[42]) AS "{6,42}";
-    {6,42}    
---------------
[0:1]={6,42}
+ {6,42} 
+--------
+ {6,42}
 (1 row)
 
 SELECT array_cat(ARRAY[1,2], ARRAY[3,4]) AS "{1,2,3,4}";
@@ -236,9 +236,9 @@ SELECT array_cat(ARRAY[1,2], ARRAY[3,4]) AS "{1,2,3,4}";
 (1 row)
 
 SELECT array_cat(ARRAY[1,2], ARRAY[[3,4],[5,6]]) AS "{{1,2},{3,4},{5,6}}";
-      {{1,2},{3,4},{5,6}}       
---------------------------------
[0:2][1:2]={{1,2},{3,4},{5,6}}
+ {{1,2},{3,4},{5,6}} 
+---------------------
+ {{1,2},{3,4},{5,6}}
 (1 row)
 
 SELECT array_cat(ARRAY[[3,4],[5,6]], ARRAY[1,2]) AS "{{3,4},{5,6},{1,2}}";
@@ -267,9 +267,9 @@ SELECT ARRAY[1,2] || 3 AS "{1,2,3}";
 (1 row)
 
 SELECT 0 || ARRAY[1,2] AS "{0,1,2}";
-    {0,1,2}    
----------------
[0:2]={0,1,2}
+ {0,1,2} 
+---------
+ {0,1,2}
 (1 row)
 
 SELECT ARRAY[1,2] || ARRAY[3,4] AS "{1,2,3,4}";
@@ -297,9 +297,9 @@ SELECT ARRAY[0,0] || ARRAY[1,1] || ARRAY[2,2] AS "{0,0,1,1,2,2}";
 (1 row)
 
 SELECT 0 || ARRAY[1,2] || 3 AS "{0,1,2,3}";
-    {0,1,2,3}    
------------------
[0:3]={0,1,2,3}
+ {0,1,2,3} 
+-----------
+ {0,1,2,3}
 (1 row)
 
 -- array casts