pgbitmap
Postgres extension providing a bitmap type
|
This extension creates a space-optimised, non-sparse, bitmap type for postgres.
A bitmap is an array of bits, indexed by an integer. Bitmaps provide an efficient means to implement sets and pgbitmap
provides operations for:
This is a beta release. The plan is to give it real-life usage before releasing a production version if all looks well.
There are no known bugs or deficiencies. If you find any problems or want enhancements, contact me and I will do what I can to respond quickly.
0.2 (alpha) Initial release
0.3 (alpha) Fix for bitmap corruption when adding bit to empty bitmap.
0.5 (alpha) Change name of extension to pgbitmap from bitmap.
0.6 (alpha) Minor fixes to Makefiles find_pg_config and docs
0.9 (beta) Minor updates to documentation and to allow distribution through pgxn. Updated to Beta status as it all seems stable enough.
0.9.1 (beta) Updated to convince pgxn to fully index the extension.
0.9.2 (beta) Fix for bitmap union bug on unions of empty bitmaps.
0.9.3 (beta) No-change update for release to PGXN
0.9.4 (beta) Utility functions made available to other extensions.
0.9.5 (beta) Fix to (unused by pgbitmap) definition of DatumGetBitmap
pgbitmap
is documented internally using Doxygen, with this page acting as the start page. The current docs can be found here.
The standard Postgres bit type is limited in a number of ways. In particular, each bit string starts at bit zero so a bitstring for bit 1,000,000 would contain the overhead of 1,000,000 zero bits. It also, currently, does not have all of the functionality that this bitmap type provides.
Pgbitmap was developed as a means of implementing sets of integers. It is particularly suited for managing sets of privileges for Virtual Private Database implementations.
Functions:
Set Returning Functions:
Operators:
Aggregates:
The bitmap type has a compact textual representation that is not intended to be human-readable. This textual representation enables bitmaps to be used in hstore, and in text-based backups.
In addition to the functions described above, casts, ::text
, ::bitmap
, can also be used.
An empty bitmap can be created using bitmap()
. A bitmap with a single element included (ie a single bit set to 1) can also be created using bitmap(n)
. Bitmaps are more usually created from arrays or queries. The following queries return identical bitmaps:
Elements can be added to a bitmap using the bitmap_setbit()
function or the +
operator. They can be removed using bitmap_clearbit()
or the -
operator, and can be tested using the bitmap_testbit()
function or the ?
operator. The setbit and clearbit functions are rarely directly used in SQL, as array or aggregation operations are usually faster.
This is how you might test for a privilege, in a round-about sort of way:
Bitmaps are stored as ranges of bits. There are a number of functions for checking and manipulating bitmap ranges.
is_empty()
returns true if the bitmap contains no elements.
bitmin()
returns the lowest value element in the bitmap (ie the lowest bit that is set). If the bitmap is empty, it returns null.
bitmax()
returns the highest element in the bitmap, or null if the bitmap is empty.
bitmap_setmin()
and bitmap_setmax()
can be used to efficiently clear large sections of a bitmap. The result of:
would be a bitmap with elements 200 to 205.
Bitmaps may be compared. This is primarily for the purpose of sorting and indexing. Testing for equality or inequality is probably the only useful comparison from an API perspective.
These functions and operators act on a pair of bitmaps to yield a result.
bitmap_union()
, the +
operator, returns a bitmap containing all elements from both arguments. The following queries return identical results:
bitmap_intersect()
, the *
operator, yields the set of common elements from its arguments. The following queries return identical results:
bitmap_minus()
, the -
operator, yields a bitmap containing all elements from the first argument that do not appear in the second. These queries return identical results:
These functions return the elements of a bitmap, either as an array, or as a set. Use the set returning function like this:
The to_array()
function can also be invoked as a cast, eg:
These functions aggregate a collection of bitmaps using the union or intersect operations. Eg to identify all privileges of all members of a group of offices, we could use something like this:
If you're using the pgxn client all you need to do is this:
Pgbitmap can be built using the standard Postgres PGXS build mechanism as described here [https://www.postgresql.org/docs/12/extend-pgxs.html].
The build will need to be able to find the pg_config executable that matches your Postgres version. It will attempt to find this using find_pg_config
(in the top-level pgbitmap directory). If it cannot find pg_config the build will fail.
You can manually define the location in the PG_CONFIG
file:
From the pgbitmap directory (the root directory of the extension), use the following commands:
To build the extension, followed by:
To install it. You may then need to stop and restart your database service to have postgres recognise the extension.
To test the installation use:
To create html documentation (in docs/html/index.html) use:
You will need to have doxygen and dot installed.