summaryrefslogtreecommitdiff
path: root/contrib/intarray
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2012-02-16 20:00:23 -0500
committerTom Lane <tgl@sss.pgh.pa.us>2012-02-16 20:00:23 -0500
commitf559846a68df902715d05579c800f836b8f7226b (patch)
tree57fde0eb505cc752fe11e7873e9ab367b560959b /contrib/intarray
parentebc37d6924df785f3601f135c9c900fd7ec465c7 (diff)
Fix longstanding error in contrib/intarray's int[] & int[] operator.
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.
Diffstat (limited to 'contrib/intarray')
-rw-r--r--contrib/intarray/_int_tool.c15
-rw-r--r--contrib/intarray/expected/_int.out6
-rw-r--r--contrib/intarray/sql/_int.sql1
3 files changed, 16 insertions, 6 deletions
diff --git a/contrib/intarray/_int_tool.c b/contrib/intarray/_int_tool.c
index 8c0ec29c31b..780b28bc3f9 100644
--- a/contrib/intarray/_int_tool.c
+++ b/contrib/intarray/_int_tool.c
@@ -146,7 +146,8 @@ inner_int_inter(ArrayType *a, ArrayType *b)
*db,
*dr;
int i,
- j;
+ j,
+ k;
CHECKARRVALID(a);
CHECKARRVALID(b);
@@ -161,27 +162,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
diff --git a/contrib/intarray/expected/_int.out b/contrib/intarray/expected/_int.out
index 596439d3149..ab28ad33de1 100644
--- a/contrib/intarray/expected/_int.out
+++ b/contrib/intarray/expected/_int.out
@@ -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
diff --git a/contrib/intarray/sql/_int.sql b/contrib/intarray/sql/_int.sql
index 1588e3b5145..d020c5fa8e3 100644
--- a/contrib/intarray/sql/_int.sql
+++ b/contrib/intarray/sql/_int.sql
@@ -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