]> granicus.if.org Git - postgresql/commitdiff
Allow assignment to array elements not contiguous with those already
authorTom Lane <tgl@sss.pgh.pa.us>
Fri, 29 Sep 2006 21:22:21 +0000 (21:22 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Fri, 29 Sep 2006 21:22:21 +0000 (21:22 +0000)
present; intervening positions are filled with nulls.  This behavior
is required by SQL99 but was not implementable before 8.2 due to lack
of support for nulls in arrays.  I have only made it work for the
one-dimensional case, which is all that SQL99 requires.  It seems quite
complex to get it right in higher dimensions, and since we never allowed
extension at all in higher dimensions, I think that must count as a
future feature addition not a bug fix.

doc/src/sgml/array.sgml
src/backend/utils/adt/arrayfuncs.c
src/test/regress/expected/arrays.out
src/test/regress/sql/arrays.sql

index 55e4085d0dddfd77226ae943270554e369cdbab2..3ed8ce9c04363f3fbea6e077bcbf815ca374f074 100644 (file)
@@ -1,4 +1,4 @@
-<!-- $PostgreSQL: pgsql/doc/src/sgml/array.sgml,v 1.51 2006/05/09 23:12:54 momjian Exp $ -->
+<!-- $PostgreSQL: pgsql/doc/src/sgml/array.sgml,v 1.52 2006/09/29 21:22:21 tgl Exp $ -->
 
 <sect1 id="arrays">
  <title>Arrays</title>
@@ -350,11 +350,12 @@ UPDATE sal_emp SET pay_by_quarter[1:2] = '{27000,27000}'
  </para>
 
  <para>
-  A stored array value can be enlarged by assigning to an element adjacent to
-  those already present, or by assigning to a slice that is adjacent
-  to or overlaps the data already present.  For example, if array
-  <literal>myarray</> currently has 4 elements, it will have five
-  elements after an update that assigns to <literal>myarray[5]</>.
+  A stored array value can be enlarged by assigning to element(s) not already
+  present.  Any positions between those previously present and the newly
+  assigned element(s) will be filled with nulls.  For example, if array
+  <literal>myarray</> currently has 4 elements, it will have six
+  elements after an update that assigns to <literal>myarray[6]</>,
+  and <literal>myarray[5]</> will contain a null.
   Currently, enlargement in this fashion is only allowed for one-dimensional
   arrays, not multidimensional arrays.
  </para>
index 8b0c11c163dd5029dcd011acaa739896a598c0c8..dd1f1649fad01ac3d4ac7b69f02d83266ba9f660 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/utils/adt/arrayfuncs.c,v 1.131 2006/09/10 20:14:20 tgl Exp $
+ *       $PostgreSQL: pgsql/src/backend/utils/adt/arrayfuncs.c,v 1.132 2006/09/29 21:22:21 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1925,8 +1925,9 @@ array_get_slice(ArrayType *array,
  *               modified entry.  The original array object is not changed.
  *
  * For one-dimensional arrays only, we allow the array to be extended
- * by assigning to the position one above or one below the existing range.
- * (XXX we could be more flexible: perhaps allow NULL fill?)
+ * by assigning to a position outside the existing subscript range; any
+ * positions between the existing elements and the new one are set to NULLs.
+ * (XXX TODO: allow a corresponding behavior for multidimensional arrays)
  *
  * NOTE: For assignments, we throw an error for invalid subscripts etc,
  * rather than returning a NULL as the fetch operations do.
@@ -1949,17 +1950,18 @@ array_set(ArrayType *array,
                                lb[MAXDIM],
                                offset;
        char       *elt_ptr;
-       bool            extendbefore = false;
-       bool            extendafter = false;
        bool            newhasnulls;
        bits8      *oldnullbitmap;
        int                     oldnitems,
+                               newnitems,
                                olddatasize,
                                newsize,
                                olditemlen,
                                newitemlen,
                                overheadlen,
                                oldoverheadlen,
+                               addedbefore,
+                               addedafter,
                                lenbefore,
                                lenafter;
 
@@ -1972,12 +1974,12 @@ array_set(ArrayType *array,
                if (nSubscripts != 1)
                        ereport(ERROR,
                                        (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
-                                        errmsg("invalid array subscripts")));
+                                        errmsg("wrong number of array subscripts")));
 
                if (indx[0] < 0 || indx[0] * elmlen >= arraytyplen)
                        ereport(ERROR,
                                        (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
-                                        errmsg("invalid array subscripts")));
+                                        errmsg("array subscript out of range")));
 
                if (isNull)
                        ereport(ERROR,
@@ -1994,7 +1996,7 @@ array_set(ArrayType *array,
        if (nSubscripts <= 0 || nSubscripts > MAXDIM)
                ereport(ERROR,
                                (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
-                                errmsg("invalid array subscripts")));
+                                errmsg("wrong number of array subscripts")));
 
        /* make sure item to be inserted is not toasted */
        if (elmlen == -1 && !isNull)
@@ -2028,70 +2030,72 @@ array_set(ArrayType *array,
        if (ndim != nSubscripts)
                ereport(ERROR,
                                (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
-                                errmsg("invalid array subscripts")));
+                                errmsg("wrong number of array subscripts")));
 
        /* copy dim/lb since we may modify them */
        memcpy(dim, ARR_DIMS(array), ndim * sizeof(int));
        memcpy(lb, ARR_LBOUND(array), ndim * sizeof(int));
 
+       newhasnulls = (ARR_HASNULL(array) || isNull);
+       addedbefore = addedafter = 0;
+
        /*
         * Check subscripts
         */
-       for (i = 0; i < ndim; i++)
+       if (ndim == 1)
        {
-               if (indx[i] < lb[i])
+               if (indx[0] < lb[0])
                {
-                       if (ndim == 1 && indx[i] == lb[i] - 1)
-                       {
-                               dim[i]++;
-                               lb[i]--;
-                               extendbefore = true;
-                       }
-                       else
-                               ereport(ERROR,
-                                               (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
-                                                errmsg("invalid array subscripts")));
+                       addedbefore = lb[0] - indx[0];
+                       dim[0] += addedbefore;
+                       lb[0] = indx[0];
+                       if (addedbefore > 1)
+                               newhasnulls = true;                             /* will insert nulls */
                }
-               if (indx[i] >= (dim[i] + lb[i]))
+               if (indx[0] >= (dim[0] + lb[0]))
                {
-                       if (ndim == 1 && indx[i] == (dim[i] + lb[i]))
-                       {
-                               dim[i]++;
-                               extendafter = true;
-                       }
-                       else
+                       addedafter = indx[0] - (dim[0] + lb[0]) + 1;
+                       dim[0] += addedafter;
+                       if (addedafter > 1)
+                               newhasnulls = true;                             /* will insert nulls */
+               }
+       }
+       else
+       {
+               /*
+                * XXX currently we do not support extending multi-dimensional
+                * arrays during assignment
+                */
+               for (i = 0; i < ndim; i++)
+               {
+                       if (indx[i] < lb[i] ||
+                               indx[i] >= (dim[i] + lb[i]))
                                ereport(ERROR,
                                                (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
-                                                errmsg("invalid array subscripts")));
+                                                errmsg("array subscript out of range")));
                }
        }
 
        /*
         * Compute sizes of items and areas to copy
         */
-       if (ARR_HASNULL(array) || isNull)
-       {
-               newhasnulls = true;
-               overheadlen = ARR_OVERHEAD_WITHNULLS(ndim,
-                                                                                        ArrayGetNItems(ndim, dim));
-       }
+       newnitems = ArrayGetNItems(ndim, dim);
+       if (newhasnulls)
+               overheadlen = ARR_OVERHEAD_WITHNULLS(ndim, newnitems);
        else
-       {
-               newhasnulls = false;
                overheadlen = ARR_OVERHEAD_NONULLS(ndim);
-       }
        oldnitems = ArrayGetNItems(ndim, ARR_DIMS(array));
        oldnullbitmap = ARR_NULLBITMAP(array);
        oldoverheadlen = ARR_DATA_OFFSET(array);
        olddatasize = ARR_SIZE(array) - oldoverheadlen;
-       if (extendbefore)
+       if (addedbefore)
        {
                offset = 0;
                lenbefore = 0;
                olditemlen = 0;
                lenafter = olddatasize;
        }
-       else if (extendafter)
+       else if (addedafter)
        {
                offset = oldnitems;
                lenbefore = olddatasize;
@@ -2158,9 +2162,16 @@ array_set(ArrayType *array,
        {
                bits8      *newnullbitmap = ARR_NULLBITMAP(newarray);
 
-               array_set_isnull(newnullbitmap, offset, isNull);
-               if (extendbefore)
-                       array_bitmap_copy(newnullbitmap, 1,
+               /* Zero the bitmap to take care of marking inserted positions null */
+               MemSet(newnullbitmap, 0, (newnitems + 7) / 8);
+               /* Fix the inserted value */
+               if (addedafter)
+                       array_set_isnull(newnullbitmap, newnitems - 1, isNull);
+               else
+                       array_set_isnull(newnullbitmap, offset, isNull);
+               /* Fix the copied range(s) */
+               if (addedbefore)
+                       array_bitmap_copy(newnullbitmap, addedbefore,
                                                          oldnullbitmap, 0,
                                                          oldnitems);
                else
@@ -2168,7 +2179,7 @@ array_set(ArrayType *array,
                        array_bitmap_copy(newnullbitmap, 0,
                                                          oldnullbitmap, 0,
                                                          offset);
-                       if (!extendafter)
+                       if (addedafter == 0)
                                array_bitmap_copy(newnullbitmap, offset + 1,
                                                                  oldnullbitmap, offset + 1,
                                                                  oldnitems - offset - 1);
@@ -2202,6 +2213,11 @@ array_set(ArrayType *array,
  *               A new array is returned, just like the old except for the
  *               modified range.  The original array object is not changed.
  *
+ * For one-dimensional arrays only, we allow the array to be extended
+ * by assigning to positions outside the existing subscript range; any
+ * positions between the existing elements and the new ones are set to NULLs.
+ * (XXX TODO: allow a corresponding behavior for multidimensional arrays)
+ *
  * NOTE: we assume it is OK to scribble on the provided index arrays
  * lowerIndx[] and upperIndx[].  These are generally just temporaries.
  *
@@ -2235,6 +2251,8 @@ array_set_slice(ArrayType *array,
                                newitemsize,
                                overheadlen,
                                oldoverheadlen,
+                               addedbefore,
+                               addedafter,
                                lenbefore,
                                lenafter,
                                itemsbefore,
@@ -2298,55 +2316,70 @@ array_set_slice(ArrayType *array,
        if (ndim < nSubscripts || ndim <= 0 || ndim > MAXDIM)
                ereport(ERROR,
                                (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
-                                errmsg("invalid array subscripts")));
+                                errmsg("wrong number of array subscripts")));
 
        /* copy dim/lb since we may modify them */
        memcpy(dim, ARR_DIMS(array), ndim * sizeof(int));
        memcpy(lb, ARR_LBOUND(array), ndim * sizeof(int));
 
+       newhasnulls = (ARR_HASNULL(array) || ARR_HASNULL(srcArray));
+       addedbefore = addedafter = 0;
+
        /*
-        * Check provided subscripts.  A slice exceeding the current array limits
-        * throws an error, *except* in the 1-D case where we will extend the
-        * array as long as no hole is created. An empty slice is an error, too.
+        * Check subscripts
         */
-       for (i = 0; i < nSubscripts; i++)
+       if (ndim == 1)
        {
-               if (lowerIndx[i] > upperIndx[i])
+               Assert(nSubscripts == 1);
+               if (lowerIndx[0] > upperIndx[0])
                        ereport(ERROR,
                                        (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
-                                        errmsg("invalid array subscripts")));
-               if (lowerIndx[i] < lb[i])
+                                        errmsg("upper bound cannot be less than lower bound")));
+               if (lowerIndx[0] < lb[0])
                {
-                       if (ndim == 1 && upperIndx[i] >= lb[i] - 1)
-                       {
-                               dim[i] += lb[i] - lowerIndx[i];
-                               lb[i] = lowerIndx[i];
-                       }
-                       else
+                       if (upperIndx[0] < lb[0] - 1)
+                               newhasnulls = true;                             /* will insert nulls */
+                       addedbefore = lb[0] - lowerIndx[0];
+                       dim[0] += addedbefore;
+                       lb[0] = lowerIndx[0];
+               }
+               if (upperIndx[0] >= (dim[0] + lb[0]))
+               {
+                       if (lowerIndx[0] > (dim[0] + lb[0]))
+                               newhasnulls = true;                             /* will insert nulls */
+                       addedafter = upperIndx[0] - (dim[0] + lb[0]) + 1;
+                       dim[0] += addedafter;
+               }
+       }
+       else
+       {
+               /*
+                * XXX currently we do not support extending multi-dimensional
+                * arrays during assignment
+                */
+               for (i = 0; i < nSubscripts; i++)
+               {
+                       if (lowerIndx[i] > upperIndx[i])
+                               ereport(ERROR,
+                                               (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
+                                                errmsg("upper bound cannot be less than lower bound")));
+                       if (lowerIndx[i] < lb[i] ||
+                               upperIndx[i] >= (dim[i] + lb[i]))
                                ereport(ERROR,
                                                (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
-                                                errmsg("invalid array subscripts")));
+                                                errmsg("array subscript out of range")));
                }
-               if (upperIndx[i] >= (dim[i] + lb[i]))
+               /* fill any missing subscript positions with full array range */
+               for (; i < ndim; i++)
                {
-                       if (ndim == 1 && lowerIndx[i] <= (dim[i] + lb[i]))
-                               dim[i] = upperIndx[i] - lb[i] + 1;
-                       else
+                       lowerIndx[i] = lb[i];
+                       upperIndx[i] = dim[i] + lb[i] - 1;
+                       if (lowerIndx[i] > upperIndx[i])
                                ereport(ERROR,
                                                (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
-                                                errmsg("invalid array subscripts")));
+                                                errmsg("upper bound cannot be less than lower bound")));
                }
        }
-       /* fill any missing subscript positions with full array range */
-       for (; i < ndim; i++)
-       {
-               lowerIndx[i] = lb[i];
-               upperIndx[i] = dim[i] + lb[i] - 1;
-               if (lowerIndx[i] > upperIndx[i])
-                       ereport(ERROR,
-                                       (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
-                                        errmsg("invalid array subscripts")));
-       }
 
        /* Do this mainly to check for overflow */
        nitems = ArrayGetNItems(ndim, dim);
@@ -2366,16 +2399,10 @@ array_set_slice(ArrayType *array,
         * Compute space occupied by new entries, space occupied by replaced
         * entries, and required space for new array.
         */
-       if (ARR_HASNULL(array) || ARR_HASNULL(srcArray))
-       {
-               newhasnulls = true;
+       if (newhasnulls)
                overheadlen = ARR_OVERHEAD_WITHNULLS(ndim, nitems);
-       }
        else
-       {
-               newhasnulls = false;
                overheadlen = ARR_OVERHEAD_NONULLS(ndim);
-       }
        newitemsize = array_nelems_size(ARR_DATA_PTR(srcArray), 0,
                                                                        ARR_NULLBITMAP(srcArray), nsrcitems,
                                                                        elmlen, elmbyval, elmalign);
@@ -2407,7 +2434,7 @@ array_set_slice(ArrayType *array,
                char       *oldarraydata = ARR_DATA_PTR(array);
                bits8      *oldarraybitmap = ARR_NULLBITMAP(array);
 
-               itemsbefore = slicelb - oldlb;
+               itemsbefore = Min(slicelb, oldub + 1) - oldlb;
                lenbefore = array_nelems_size(oldarraydata, 0, oldarraybitmap,
                                                                          itemsbefore,
                                                                          elmlen, elmbyval, elmalign);
@@ -2467,13 +2494,15 @@ array_set_slice(ArrayType *array,
                        bits8      *newnullbitmap = ARR_NULLBITMAP(newarray);
                        bits8      *oldnullbitmap = ARR_NULLBITMAP(array);
 
-                       array_bitmap_copy(newnullbitmap, 0,
+                       /* Zero the bitmap to handle marking inserted positions null */
+                       MemSet(newnullbitmap, 0, (nitems + 7) / 8);
+                       array_bitmap_copy(newnullbitmap, addedbefore,
                                                          oldnullbitmap, 0,
                                                          itemsbefore);
-                       array_bitmap_copy(newnullbitmap, itemsbefore,
+                       array_bitmap_copy(newnullbitmap, lowerIndx[0] - lb[0],
                                                          ARR_NULLBITMAP(srcArray), 0,
                                                          nsrcitems);
-                       array_bitmap_copy(newnullbitmap, itemsbefore + nsrcitems,
+                       array_bitmap_copy(newnullbitmap, addedbefore + itemsbefore + nolditems,
                                                          oldnullbitmap, itemsbefore + nolditems,
                                                          itemsafter);
                }
index b0f9f69a57f0e908f07e7ed07c901c8707b8ce7c..643ae7f39bdfa638355c8aef2bd2d87ca9876775 100644 (file)
@@ -143,6 +143,116 @@ SELECT a,b,c FROM arrtest;
  [4:4]={NULL}  | {3,4}                 | {foo,new_word}
 (3 rows)
 
+--
+-- test array extension
+--
+CREATE TEMP TABLE arrtest1 (i int[], t text[]);
+insert into arrtest1 values(array[1,2,null,4], array['one','two',null,'four']);
+select * from arrtest1;
+      i       |          t          
+--------------+---------------------
+ {1,2,NULL,4} | {one,two,NULL,four}
+(1 row)
+
+update arrtest1 set i[2] = 22, t[2] = 'twenty-two';
+select * from arrtest1;
+       i       |             t              
+---------------+----------------------------
+ {1,22,NULL,4} | {one,twenty-two,NULL,four}
+(1 row)
+
+update arrtest1 set i[5] = 5, t[5] = 'five';
+select * from arrtest1;
+        i        |                t                
+-----------------+---------------------------------
+ {1,22,NULL,4,5} | {one,twenty-two,NULL,four,five}
+(1 row)
+
+update arrtest1 set i[8] = 8, t[8] = 'eight';
+select * from arrtest1;
+              i              |                        t                        
+-----------------------------+-------------------------------------------------
+ {1,22,NULL,4,5,NULL,NULL,8} | {one,twenty-two,NULL,four,five,NULL,NULL,eight}
+(1 row)
+
+update arrtest1 set i[0] = 0, t[0] = 'zero';
+select * from arrtest1;
+                  i                  |                             t                              
+-------------------------------------+------------------------------------------------------------
+ [0:8]={0,1,22,NULL,4,5,NULL,NULL,8} | [0:8]={zero,one,twenty-two,NULL,four,five,NULL,NULL,eight}
+(1 row)
+
+update arrtest1 set i[-3] = -3, t[-3] = 'minus-three';
+select * from arrtest1;
+                         i                         |                                         t                                         
+---------------------------------------------------+-----------------------------------------------------------------------------------
+ [-3:8]={-3,NULL,NULL,0,1,22,NULL,4,5,NULL,NULL,8} | [-3:8]={minus-three,NULL,NULL,zero,one,twenty-two,NULL,four,five,NULL,NULL,eight}
+(1 row)
+
+update arrtest1 set i[0:2] = array[10,11,12], t[0:2] = array['ten','eleven','twelve'];
+select * from arrtest1;
+                          i                          |                                        t                                        
+-----------------------------------------------------+---------------------------------------------------------------------------------
+ [-3:8]={-3,NULL,NULL,10,11,12,NULL,4,5,NULL,NULL,8} | [-3:8]={minus-three,NULL,NULL,ten,eleven,twelve,NULL,four,five,NULL,NULL,eight}
+(1 row)
+
+update arrtest1 set i[8:10] = array[18,null,20], t[8:10] = array['p18',null,'p20'];
+select * from arrtest1;
+                               i                               |                                            t                                            
+---------------------------------------------------------------+-----------------------------------------------------------------------------------------
+ [-3:10]={-3,NULL,NULL,10,11,12,NULL,4,5,NULL,NULL,18,NULL,20} | [-3:10]={minus-three,NULL,NULL,ten,eleven,twelve,NULL,four,five,NULL,NULL,p18,NULL,p20}
+(1 row)
+
+update arrtest1 set i[11:12] = array[null,22], t[11:12] = array[null,'p22'];
+select * from arrtest1;
+                                   i                                   |                                                t                                                 
+-----------------------------------------------------------------------+--------------------------------------------------------------------------------------------------
+ [-3:12]={-3,NULL,NULL,10,11,12,NULL,4,5,NULL,NULL,18,NULL,20,NULL,22} | [-3:12]={minus-three,NULL,NULL,ten,eleven,twelve,NULL,four,five,NULL,NULL,p18,NULL,p20,NULL,p22}
+(1 row)
+
+update arrtest1 set i[15:16] = array[null,26], t[15:16] = array[null,'p26'];
+select * from arrtest1;
+                                            i                                            |                                                          t                                                          
+-----------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------
+ [-3:16]={-3,NULL,NULL,10,11,12,NULL,4,5,NULL,NULL,18,NULL,20,NULL,22,NULL,NULL,NULL,26} | [-3:16]={minus-three,NULL,NULL,ten,eleven,twelve,NULL,four,five,NULL,NULL,p18,NULL,p20,NULL,p22,NULL,NULL,NULL,p26}
+(1 row)
+
+update arrtest1 set i[-5:-3] = array[-15,-14,-13], t[-5:-3] = array['m15','m14','m13'];
+select * from arrtest1;
+                                                i                                                 |                                                          t                                                          
+--------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------
+ [-5:16]={-15,-14,-13,NULL,NULL,10,11,12,NULL,4,5,NULL,NULL,18,NULL,20,NULL,22,NULL,NULL,NULL,26} | [-5:16]={m15,m14,m13,NULL,NULL,ten,eleven,twelve,NULL,four,five,NULL,NULL,p18,NULL,p20,NULL,p22,NULL,NULL,NULL,p26}
+(1 row)
+
+update arrtest1 set i[-7:-6] = array[-17,null], t[-7:-6] = array['m17',null];
+select * from arrtest1;
+                                                     i                                                     |                                                              t                                                               
+-----------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------
+ [-7:16]={-17,NULL,-15,-14,-13,NULL,NULL,10,11,12,NULL,4,5,NULL,NULL,18,NULL,20,NULL,22,NULL,NULL,NULL,26} | [-7:16]={m17,NULL,m15,m14,m13,NULL,NULL,ten,eleven,twelve,NULL,four,five,NULL,NULL,p18,NULL,p20,NULL,p22,NULL,NULL,NULL,p26}
+(1 row)
+
+update arrtest1 set i[-12:-10] = array[-22,null,-20], t[-12:-10] = array['m22',null,'m20'];
+select * from arrtest1;
+                                                                 i                                                                 |                                                                          t                                                                           
+-----------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------
+ [-12:16]={-22,NULL,-20,NULL,NULL,-17,NULL,-15,-14,-13,NULL,NULL,10,11,12,NULL,4,5,NULL,NULL,18,NULL,20,NULL,22,NULL,NULL,NULL,26} | [-12:16]={m22,NULL,m20,NULL,NULL,m17,NULL,m15,m14,m13,NULL,NULL,ten,eleven,twelve,NULL,four,five,NULL,NULL,p18,NULL,p20,NULL,p22,NULL,NULL,NULL,p26}
+(1 row)
+
+delete from arrtest1;
+insert into arrtest1 values(array[1,2,null,4], array['one','two',null,'four']);
+select * from arrtest1;
+      i       |          t          
+--------------+---------------------
+ {1,2,NULL,4} | {one,two,NULL,four}
+(1 row)
+
+update arrtest1 set i[0:5] = array[0,1,2,null,4,5], t[0:5] = array['z','p1','p2',null,'p4','p5'];
+select * from arrtest1;
+           i            |             t              
+------------------------+----------------------------
+ [0:5]={0,1,2,NULL,4,5} | [0:5]={z,p1,p2,NULL,p4,p5}
+(1 row)
+
 --
 -- array expressions and operators
 --
index ad5f455cf490e546d3d2b4fb765181ae7979daf5..1f574a018487711ea897aafd7fbd02a5b5769d36 100644 (file)
@@ -90,6 +90,42 @@ SELECT a FROM arrtest WHERE a[2] IS NULL;
 DELETE FROM arrtest WHERE a[2] IS NULL AND b IS NULL;
 SELECT a,b,c FROM arrtest;
 
+--
+-- test array extension
+--
+CREATE TEMP TABLE arrtest1 (i int[], t text[]);
+insert into arrtest1 values(array[1,2,null,4], array['one','two',null,'four']);
+select * from arrtest1;
+update arrtest1 set i[2] = 22, t[2] = 'twenty-two';
+select * from arrtest1;
+update arrtest1 set i[5] = 5, t[5] = 'five';
+select * from arrtest1;
+update arrtest1 set i[8] = 8, t[8] = 'eight';
+select * from arrtest1;
+update arrtest1 set i[0] = 0, t[0] = 'zero';
+select * from arrtest1;
+update arrtest1 set i[-3] = -3, t[-3] = 'minus-three';
+select * from arrtest1;
+update arrtest1 set i[0:2] = array[10,11,12], t[0:2] = array['ten','eleven','twelve'];
+select * from arrtest1;
+update arrtest1 set i[8:10] = array[18,null,20], t[8:10] = array['p18',null,'p20'];
+select * from arrtest1;
+update arrtest1 set i[11:12] = array[null,22], t[11:12] = array[null,'p22'];
+select * from arrtest1;
+update arrtest1 set i[15:16] = array[null,26], t[15:16] = array[null,'p26'];
+select * from arrtest1;
+update arrtest1 set i[-5:-3] = array[-15,-14,-13], t[-5:-3] = array['m15','m14','m13'];
+select * from arrtest1;
+update arrtest1 set i[-7:-6] = array[-17,null], t[-7:-6] = array['m17',null];
+select * from arrtest1;
+update arrtest1 set i[-12:-10] = array[-22,null,-20], t[-12:-10] = array['m22',null,'m20'];
+select * from arrtest1;
+delete from arrtest1;
+insert into arrtest1 values(array[1,2,null,4], array['one','two',null,'four']);
+select * from arrtest1;
+update arrtest1 set i[0:5] = array[0,1,2,null,4,5], t[0:5] = array['z','p1','p2',null,'p4','p5'];
+select * from arrtest1;
+
 --
 -- array expressions and operators
 --