aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2016-05-17 17:01:18 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2016-05-17 17:01:18 -0400
commite13ac5586c49c77f301329b79bd7e8f489d0e66f (patch)
tree8bf0f11cba4dac8362a1f63c118d0b975d5dd233
parent7c979c95a3700d0bd34c2831f49a9260d505b0f9 (diff)
downloadpostgresql-e13ac5586c49c77f301329b79bd7e8f489d0e66f.tar.gz
postgresql-e13ac5586c49c77f301329b79bd7e8f489d0e66f.zip
Avoid possible crash in contrib/bloom's blendscan().
It's possible to begin and end an indexscan without ever calling amrescan. contrib/bloom, unlike every other index AM, allocated its "scan->opaque" storage at amrescan time, and thus would crash in amendscan if amrescan hadn't been called. We could fix this by putting in a null-pointer check in blendscan, but I see no very good reason why contrib/bloom should march to its own drummer in this respect. Let's move that initialization to blbeginscan instead. Per report from Jeff Janes.
-rw-r--r--contrib/bloom/blscan.c26
1 files changed, 10 insertions, 16 deletions
diff --git a/contrib/bloom/blscan.c b/contrib/bloom/blscan.c
index fc82f543738..aebf32a8d2f 100644
--- a/contrib/bloom/blscan.c
+++ b/contrib/bloom/blscan.c
@@ -29,9 +29,16 @@ IndexScanDesc
blbeginscan(Relation r, int nkeys, int norderbys)
{
IndexScanDesc scan;
+ BloomScanOpaque so;
scan = RelationGetIndexScan(r, nkeys, norderbys);
+ so = (BloomScanOpaque) palloc(sizeof(BloomScanOpaqueData));
+ initBloomState(&so->state, scan->indexRelation);
+ so->sign = NULL;
+
+ scan->opaque = so;
+
return scan;
}
@@ -42,23 +49,10 @@ void
blrescan(IndexScanDesc scan, ScanKey scankey, int nscankeys,
ScanKey orderbys, int norderbys)
{
- BloomScanOpaque so;
-
- so = (BloomScanOpaque) scan->opaque;
-
- if (so == NULL)
- {
- /* if called from blbeginscan */
- so = (BloomScanOpaque) palloc(sizeof(BloomScanOpaqueData));
- initBloomState(&so->state, scan->indexRelation);
- scan->opaque = so;
+ BloomScanOpaque so = (BloomScanOpaque) scan->opaque;
- }
- else
- {
- if (so->sign)
- pfree(so->sign);
- }
+ if (so->sign)
+ pfree(so->sign);
so->sign = NULL;
if (scankey && scan->numberOfKeys > 0)