Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit b0b7be6

Browse files
committed
Add BRIN infrastructure for "inclusion" opclasses
This lets BRIN be used with R-Tree-like indexing strategies. Also provided are operator classes for range types, box and inet/cidr. The infrastructure provided here should be sufficient to create operator classes for similar datatypes; for instance, opclasses for PostGIS geometries should be doable, though we didn't try to implement one. (A box/point opclass was also submitted, but we ripped it out before commit because the handling of floating point comparisons in existing code is inconsistent and would generate corrupt indexes.) Author: Emre Hasegeli. Cosmetic changes by me Review: Andreas Karlsson
1 parent 199f597 commit b0b7be6

File tree

18 files changed

+928
-105
lines changed

18 files changed

+928
-105
lines changed

doc/src/sgml/brin.sgml

+52-1
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,9 @@
7272
<para>
7373
The <firstterm>minmax</>
7474
operator classes store the minimum and the maximum values appearing
75-
in the indexed column within the range.
75+
in the indexed column within the range. The <firstterm>inclusion</>
76+
operator classes store a value which includes the values in the indexed
77+
column within the range.
7678
</para>
7779

7880
<table id="brin-builtin-opclasses-table">
@@ -251,6 +253,18 @@
251253
<literal>&gt;</literal>
252254
</entry>
253255
</row>
256+
<row>
257+
<entry><literal>inet_inclusion_ops</literal></entry>
258+
<entry><type>inet</type></entry>
259+
<entry>
260+
<literal>&amp;&amp;</>
261+
<literal>&gt;&gt;</>
262+
<literal>&gt;&gt;=</>
263+
<literal>&lt;&lt;</literal>
264+
<literal>&lt;&lt;=</literal>
265+
<literal>=</literal>
266+
</entry>
267+
</row>
254268
<row>
255269
<entry><literal>bpchar_minmax_ops</literal></entry>
256270
<entry><type>character</type></entry>
@@ -372,6 +386,25 @@
372386
<literal>&gt;</literal>
373387
</entry>
374388
</row>
389+
<row>
390+
<entry><literal>range_inclusion_ops</></entry>
391+
<entry><type>any range type</type></entry>
392+
<entry>
393+
<literal>&amp;&amp;</>
394+
<literal>&amp;&gt;</>
395+
<literal>&amp;&lt;</>
396+
<literal>&gt;&gt;</>
397+
<literal>&lt;&lt;</>
398+
<literal>&lt;@</>
399+
<literal>=</>
400+
<literal>@&gt;</>
401+
<literal>&lt;</literal>
402+
<literal>&lt;=</literal>
403+
<literal>=</literal>
404+
<literal>&gt;=</literal>
405+
<literal>&gt;</literal>
406+
</entry>
407+
</row>
375408
<row>
376409
<entry><literal>pg_lsn_minmax_ops</literal></entry>
377410
<entry><type>pg_lsn</type></entry>
@@ -383,6 +416,24 @@
383416
<literal>&gt;</literal>
384417
</entry>
385418
</row>
419+
<row>
420+
<entry><literal>box_inclusion_ops</></entry>
421+
<entry><type>box</type></entry>
422+
<entry>
423+
<literal>&amp;&amp;</>
424+
<literal>&amp;&gt;</>
425+
<literal>&amp;&lt;</>
426+
<literal>&gt;&gt;</>
427+
<literal>&lt;&lt;</>
428+
<literal>&lt;@</>
429+
<literal>~=</>
430+
<literal>@&gt;</>
431+
<literal>&amp;&gt;|</>
432+
<literal>|&amp;&lt;</>
433+
<literal>&gt;&gt;|</>
434+
<literal>|&lt;&lt;</literal>
435+
</entry>
436+
</row>
386437
</tbody>
387438
</tgroup>
388439
</table>

src/backend/access/brin/Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,6 @@ top_builddir = ../../../..
1313
include $(top_builddir)/src/Makefile.global
1414

1515
OBJS = brin.o brin_pageops.o brin_revmap.o brin_tuple.o brin_xlog.o \
16-
brin_minmax.o
16+
brin_minmax.o brin_inclusion.o
1717

1818
include $(top_srcdir)/src/backend/common.mk

src/backend/access/brin/brin.c

+17-73
Original file line numberDiff line numberDiff line change
@@ -105,11 +105,6 @@ brininsert(PG_FUNCTION_ARGS)
105105
BrinMemTuple *dtup;
106106
BlockNumber heapBlk;
107107
int keyno;
108-
#ifdef USE_ASSERT_CHECKING
109-
BrinTuple *tmptup;
110-
BrinMemTuple *tmpdtup;
111-
Size tmpsiz;
112-
#endif
113108

114109
CHECK_FOR_INTERRUPTS();
115110

@@ -137,45 +132,6 @@ brininsert(PG_FUNCTION_ARGS)
137132

138133
dtup = brin_deform_tuple(bdesc, brtup);
139134

140-
#ifdef USE_ASSERT_CHECKING
141-
{
142-
/*
143-
* When assertions are enabled, we use this as an opportunity to
144-
* test the "union" method, which would otherwise be used very
145-
* rarely: first create a placeholder tuple, and addValue the
146-
* value we just got into it. Then union the existing index tuple
147-
* with the updated placeholder tuple. The tuple resulting from
148-
* that union should be identical to the one resulting from the
149-
* regular operation (straight addValue) below.
150-
*
151-
* Here we create the tuple to compare with; the actual comparison
152-
* is below.
153-
*/
154-
tmptup = brin_form_placeholder_tuple(bdesc, heapBlk, &tmpsiz);
155-
tmpdtup = brin_deform_tuple(bdesc, tmptup);
156-
for (keyno = 0; keyno < bdesc->bd_tupdesc->natts; keyno++)
157-
{
158-
BrinValues *bval;
159-
FmgrInfo *addValue;
160-
161-
bval = &tmpdtup->bt_columns[keyno];
162-
addValue = index_getprocinfo(idxRel, keyno + 1,
163-
BRIN_PROCNUM_ADDVALUE);
164-
FunctionCall4Coll(addValue,
165-
idxRel->rd_indcollation[keyno],
166-
PointerGetDatum(bdesc),
167-
PointerGetDatum(bval),
168-
values[keyno],
169-
nulls[keyno]);
170-
}
171-
172-
union_tuples(bdesc, tmpdtup, brtup);
173-
174-
tmpdtup->bt_placeholder = dtup->bt_placeholder;
175-
tmptup = brin_form_tuple(bdesc, heapBlk, tmpdtup, &tmpsiz);
176-
}
177-
#endif
178-
179135
/*
180136
* Compare the key values of the new tuple to the stored index values;
181137
* our deformed tuple will get updated if the new tuple doesn't fit
@@ -202,20 +158,6 @@ brininsert(PG_FUNCTION_ARGS)
202158
need_insert |= DatumGetBool(result);
203159
}
204160

205-
#ifdef USE_ASSERT_CHECKING
206-
{
207-
/*
208-
* Now we can compare the tuple produced by the union function
209-
* with the one from plain addValue.
210-
*/
211-
BrinTuple *cmptup;
212-
Size cmpsz;
213-
214-
cmptup = brin_form_tuple(bdesc, heapBlk, dtup, &cmpsz);
215-
Assert(brin_tuples_equal(tmptup, tmpsiz, cmptup, cmpsz));
216-
}
217-
#endif
218-
219161
if (!need_insert)
220162
{
221163
/*
@@ -323,8 +265,6 @@ brinbeginscan(PG_FUNCTION_ARGS)
323265
* If a TID from the revmap is read as InvalidTID, we know that range is
324266
* unsummarized. Pages in those ranges need to be returned regardless of scan
325267
* keys.
326-
*
327-
* XXX see _bt_first on what to do about sk_subtype.
328268
*/
329269
Datum
330270
bringetbitmap(PG_FUNCTION_ARGS)
@@ -340,7 +280,6 @@ bringetbitmap(PG_FUNCTION_ARGS)
340280
BlockNumber nblocks;
341281
BlockNumber heapBlk;
342282
int totalpages = 0;
343-
int keyno;
344283
FmgrInfo *consistentFn;
345284
MemoryContext oldcxt;
346285
MemoryContext perRangeCxt;
@@ -359,18 +298,11 @@ bringetbitmap(PG_FUNCTION_ARGS)
359298
heap_close(heapRel, AccessShareLock);
360299

361300
/*
362-
* Obtain consistent functions for all indexed column. Maybe it'd be
363-
* possible to do this lazily only the first time we see a scan key that
364-
* involves each particular attribute.
301+
* Make room for the consistent support procedures of indexed columns. We
302+
* don't look them up here; we do that lazily the first time we see a scan
303+
* key reference each of them. We rely on zeroing fn_oid to InvalidOid.
365304
*/
366-
consistentFn = palloc(sizeof(FmgrInfo) * bdesc->bd_tupdesc->natts);
367-
for (keyno = 0; keyno < bdesc->bd_tupdesc->natts; keyno++)
368-
{
369-
FmgrInfo *tmp;
370-
371-
tmp = index_getprocinfo(idxRel, keyno + 1, BRIN_PROCNUM_CONSISTENT);
372-
fmgr_info_copy(&consistentFn[keyno], tmp, CurrentMemoryContext);
373-
}
305+
consistentFn = palloc0(sizeof(FmgrInfo) * bdesc->bd_tupdesc->natts);
374306

375307
/*
376308
* Setup and use a per-range memory context, which is reset every time we
@@ -418,7 +350,6 @@ bringetbitmap(PG_FUNCTION_ARGS)
418350
else
419351
{
420352
BrinMemTuple *dtup;
421-
int keyno;
422353

423354
dtup = brin_deform_tuple(bdesc, tup);
424355
if (dtup->bt_placeholder)
@@ -431,6 +362,8 @@ bringetbitmap(PG_FUNCTION_ARGS)
431362
}
432363
else
433364
{
365+
int keyno;
366+
434367
/*
435368
* Compare scan keys with summary values stored for the range.
436369
* If scan keys are matched, the page range must be added to
@@ -456,6 +389,17 @@ bringetbitmap(PG_FUNCTION_ARGS)
456389
(key->sk_collation ==
457390
bdesc->bd_tupdesc->attrs[keyattno - 1]->attcollation));
458391

392+
/* First time this column? look up consistent function */
393+
if (consistentFn[keyattno - 1].fn_oid == InvalidOid)
394+
{
395+
FmgrInfo *tmp;
396+
397+
tmp = index_getprocinfo(idxRel, keyattno,
398+
BRIN_PROCNUM_CONSISTENT);
399+
fmgr_info_copy(&consistentFn[keyattno - 1], tmp,
400+
CurrentMemoryContext);
401+
}
402+
459403
/*
460404
* Check whether the scan key is consistent with the page
461405
* range values; if so, have the pages in the range added

0 commit comments

Comments
 (0)