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

Lines changed: 52 additions & 1 deletion
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

Lines changed: 1 addition & 1 deletion
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

Lines changed: 17 additions & 73 deletions
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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy