summaryrefslogtreecommitdiff
path: root/contrib/intarray
diff options
context:
space:
mode:
authorTom Lane2012-02-17 01:00:11 +0000
committerTom Lane2012-02-17 01:00:11 +0000
commit06d9afa6f93ec08a45da4de7afd97bbf16738739 (patch)
tree2c9776a5c070be13f4a3a0c4c61c0c935c620449 /contrib/intarray
parent4767bc8ff2edc1258cf4d8a83155d4cedd724231 (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.c13
-rw-r--r--contrib/intarray/expected/_int.out6
-rw-r--r--contrib/intarray/sql/_int.sql1
3 files changed, 14 insertions, 6 deletions
diff --git a/contrib/intarray/_int_tool.c b/contrib/intarray/_int_tool.c
index 79f018d333b..132d1531605 100644
--- a/contrib/intarray/_int_tool.c
+++ b/contrib/intarray/_int_tool.c
@@ -140,7 +140,8 @@ inner_int_inter(ArrayType *a, ArrayType *b)
*db,
*dr;
int i,
- j;
+ j,
+ k;
if (ARRISEMPTY(a) || ARRISEMPTY(b))
return new_intArrayType(0);
@@ -152,15 +153,15 @@ 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++;
}
@@ -168,13 +169,13 @@ inner_int_inter(ArrayType *a, ArrayType *b)
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 6ed3cc6ced0..4080b9633fe 100644
--- a/contrib/intarray/expected/_int.out
+++ b/contrib/intarray/expected/_int.out
@@ -137,6 +137,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 b60e936dc52..216c5c58d61 100644
--- a/contrib/intarray/sql/_int.sql
+++ b/contrib/intarray/sql/_int.sql
@@ -24,6 +24,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