]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Fix longstanding error in contrib/intarray's int[] & int[] operator.
authorTom Lane <tgl@sss.pgh.pa.us>
Fri, 17 Feb 2012 01:00:34 +0000 (20:00 -0500)
committerTom Lane <tgl@sss.pgh.pa.us>
Fri, 17 Feb 2012 01:00:34 +0000 (20:00 -0500)
The array intersection code would give wrong results if the first entry of
the correct output array would be "1".  (I think only this value could be
at risk, since the previous word would always be a lower-bound entry with
that fixed value.)

Problem spotted by Julien Rouhaud, initial patch by Guillaume Lelarge,
cosmetic improvements by me.

contrib/intarray/_int_tool.c
contrib/intarray/expected/_int.out
contrib/intarray/sql/_int.sql

index fead4ff30dcea82195823fa2c7ded8ed5521a64f..1c6b7301a2b87859dfaf1f10dfa4a7bd4b8e5f74 100644 (file)
@@ -139,7 +139,8 @@ inner_int_inter(ArrayType *a, ArrayType *b)
                           *db,
                           *dr;
        int                     i,
-                               j;
+                               j,
+                               k;
 
        CHECKARRVALID(a);
        CHECKARRVALID(b);
@@ -154,27 +155,29 @@ inner_int_inter(ArrayType *a, ArrayType *b)
        r = new_intArrayType(Min(na, nb));
        dr = ARRPTR(r);
 
-       i = j = 0;
+       i = j = k = 0;
        while (i < na && j < nb)
+       {
                if (da[i] < db[j])
                        i++;
                else if (da[i] == db[j])
                {
-                       if (i + j == 0 || (i + j > 0 && *(dr - 1) != db[j]))
-                               *dr++ = db[j];
+                       if (k == 0 || dr[k - 1] != db[j])
+                               dr[k++] = db[j];
                        i++;
                        j++;
                }
                else
                        j++;
+       }
 
-       if ((dr - ARRPTR(r)) == 0)
+       if (k == 0)
        {
                pfree(r);
                return new_intArrayType(0);
        }
        else
-               return resize_intArrayType(r, dr - ARRPTR(r));
+               return resize_intArrayType(r, k);
 }
 
 void
index 596439d3149dca3687605ccd3ce4715bd93cd057..ab28ad33de128f72cb52aaef17962e30aa918bf6 100644 (file)
@@ -143,6 +143,12 @@ SELECT '{123,623,445}'::int[] & '{1623,623}';
  {623}
 (1 row)
 
+SELECT '{-1,3,1}'::int[] & '{1,2}';
+ ?column? 
+----------
+ {1}
+(1 row)
+
 --test query_int
 SELECT '1'::query_int;
  query_int 
index 1588e3b5145e2b65bd09ec34775c02dcbf6747b2..d020c5fa8e3411bcfdffcfcd920e66f100624144 100644 (file)
@@ -32,6 +32,7 @@ SELECT '{123,623,445}'::int[] | 623;
 SELECT '{123,623,445}'::int[] | 1623;
 SELECT '{123,623,445}'::int[] | '{1623,623}';
 SELECT '{123,623,445}'::int[] & '{1623,623}';
+SELECT '{-1,3,1}'::int[] & '{1,2}';
 
 
 --test query_int