├── docker-example ├── load-extension.sql ├── docker-compose.yml ├── README.md └── Dockerfile ├── .gitignore ├── roaringbitmap.control ├── roaringbitmap--0.2--0.3.sql ├── roaringbitmap--1.0--1.1.sql ├── roaringbitmap--1.1--1.2.sql ├── roaringbitmap--0.3--0.4.sql ├── Makefile ├── Makefile_native ├── .github └── workflows │ └── build-test.yml ├── benchmark ├── benchmark.sh ├── benchmark_rb64.sh ├── benchmark.sql └── benchmark_rb64.sql ├── roaringbitmap--0.4--0.5.sql ├── META.json ├── roaringbitmap.h ├── CHANGELOG.md ├── roaring64_buffer_reader.h ├── roaring_buffer_reader.h ├── LICENSE ├── roaringbitmap--0.2.sql ├── roaringbitmap--0.5--1.0.sql ├── roaring64_buffer_reader.c ├── sql ├── roaringbitmap.sql └── roaringbitmap64.sql └── roaringbitmap--1.2.sql /docker-example/load-extension.sql: -------------------------------------------------------------------------------- 1 | CREATE EXTENSION roaringbitmap; -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | *.a 3 | *.so 4 | *.pc 5 | *~ 6 | .*.sw? 7 | regression.diffs 8 | regression.out 9 | results/ -------------------------------------------------------------------------------- /roaringbitmap.control: -------------------------------------------------------------------------------- 1 | # roaringbitmap extension 2 | comment = 'support for Roaring Bitmaps' 3 | default_version = '1.2' 4 | module_pathname = '$libdir/roaringbitmap' 5 | relocatable = true 6 | -------------------------------------------------------------------------------- /roaringbitmap--0.2--0.3.sql: -------------------------------------------------------------------------------- 1 | /* roaringbitmap--0.2--0.3 */ 2 | 3 | 4 | CREATE OR REPLACE FUNCTION rb_iterate(roaringbitmap) 5 | RETURNS SETOF integer 6 | AS 'MODULE_PATHNAME', 'rb_iterate' 7 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 8 | -------------------------------------------------------------------------------- /roaringbitmap--1.0--1.1.sql: -------------------------------------------------------------------------------- 1 | CREATE OR REPLACE FUNCTION rb64_select(roaringbitmap64, bitset_limit bigint,bitset_offset bigint=0,reverse boolean=false,range_start bigint=0,range_end bigint=0) 2 | RETURNS roaringbitmap64 3 | AS 'MODULE_PATHNAME', 'rb64_select' 4 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 5 | -------------------------------------------------------------------------------- /docker-example/docker-compose.yml: -------------------------------------------------------------------------------- 1 | services: 2 | database: 3 | build: 4 | context: . 5 | dockerfile: ./Dockerfile 6 | environment: 7 | - POSTGRES_USER=admin 8 | - POSTGRES_PASSWORD=123456 9 | - POSTGRES_DB=test 10 | ports: 11 | - "5432:5432" 12 | -------------------------------------------------------------------------------- /roaringbitmap--1.1--1.2.sql: -------------------------------------------------------------------------------- 1 | CREATE OR REPLACE FUNCTION rb_runoptimize(roaringbitmap) 2 | RETURNS roaringbitmap 3 | AS 'MODULE_PATHNAME', 'rb_runoptimize' 4 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 5 | 6 | CREATE OR REPLACE FUNCTION rb64_runoptimize(roaringbitmap64) 7 | RETURNS roaringbitmap64 8 | AS 'MODULE_PATHNAME', 'rb64_runoptimize' 9 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 10 | -------------------------------------------------------------------------------- /roaringbitmap--0.3--0.4.sql: -------------------------------------------------------------------------------- 1 | /* roaringbitmap--0.3--0.4 */ 2 | 3 | -- type cast for bytea 4 | CREATE OR REPLACE FUNCTION roaringbitmap(bytea) 5 | RETURNS roaringbitmap 6 | AS 'MODULE_PATHNAME','rb_from_bytea' 7 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 8 | 9 | CREATE CAST (roaringbitmap AS bytea) WITHOUT FUNCTION; 10 | 11 | CREATE CAST (bytea AS roaringbitmap) WITH FUNCTION roaringbitmap(bytea); 12 | 13 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | EXTENSION = roaringbitmap 2 | TESTS = $(wildcard sql/*.sql) 3 | REGRESS = $(patsubst sql/%.sql,%,$(TESTS)) 4 | 5 | MODULE_big = roaringbitmap 6 | OBJS = roaring_buffer_reader.o roaringbitmap.o roaring64_buffer_reader.o roaringbitmap64.o 7 | 8 | $(OBJS): override CFLAGS += -std=c11 -Wno-error=maybe-uninitialized \ 9 | -Wno-declaration-after-statement -Wno-missing-prototypes 10 | 11 | PG_CONFIG = pg_config 12 | 13 | DATA = $(wildcard *--*.sql) 14 | PGXS := $(shell $(PG_CONFIG) --pgxs) 15 | include $(PGXS) 16 | -------------------------------------------------------------------------------- /docker-example/README.md: -------------------------------------------------------------------------------- 1 | # Building the extension with docker 2 | 3 | This directory contains an example showing you how to build and use the extension with the official postgres docker 4 | image. 5 | 6 | ## Usage 7 | 8 | ```shell 9 | docker compose up 10 | ``` 11 | 12 | After the container is started the extension is created automatically. 13 | 14 | ### Verify working extension 15 | 16 | To verify that the extension is working correctly you can execute the following statment 17 | 18 | ```sql 19 | SELECT roaringbitmap('{1,2,3}') 20 | ``` -------------------------------------------------------------------------------- /Makefile_native: -------------------------------------------------------------------------------- 1 | EXTENSION = roaringbitmap 2 | TESTS = $(wildcard sql/*.sql) 3 | REGRESS = $(patsubst sql/%.sql,%,$(TESTS)) 4 | 5 | MODULE_big = roaringbitmap 6 | OBJS = roaring_buffer_reader.o roaringbitmap.o roaring64_buffer_reader.o roaringbitmap64.o 7 | 8 | $(OBJS): override CFLAGS += -march=native -std=c11 -Wno-error=maybe-uninitialized \ 9 | -Wno-declaration-after-statement -Wno-missing-prototypes 10 | 11 | PG_CONFIG = pg_config 12 | 13 | DATA = $(wildcard *--*.sql) 14 | PGXS := $(shell $(PG_CONFIG) --pgxs) 15 | include $(PGXS) 16 | -------------------------------------------------------------------------------- /.github/workflows/build-test.yml: -------------------------------------------------------------------------------- 1 | name: Build and test 2 | on: 3 | push: # Run on any push 4 | pull_request: # Run on PRs 5 | jobs: 6 | test: 7 | runs-on: ubuntu-latest 8 | strategy: 9 | matrix: 10 | pg: [13, 14, 15, 16, 17, 18] 11 | container: 12 | image: pgxn/pgxn-tools 13 | steps: 14 | - name: Start PostgreSQL ${{ matrix.pg }} 15 | run: pg-start ${{ matrix.pg }} 16 | 17 | - name: Check out repo 18 | uses: actions/checkout@v4 19 | 20 | - name: Build & test extension 21 | run: pg-build-test 22 | -------------------------------------------------------------------------------- /benchmark/benchmark.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | psql -f benchmark.sql $*>benchmark.log 4 | rc=$? 5 | 6 | if [[ $rc -ne 0 ]]; then 7 | exit $rc 8 | fi 9 | 10 | dbinfo=`psql $* -c "select now() now, extversion roaringbitmap,(select setting pg_version from pg_settings where name='server_version') from pg_extension where extname='roaringbitmap'"` 11 | 12 | echo "$dbinfo" 13 | 14 | echo '| No | test | time(ms) |' 15 | echo '| -- | ---- | -------- |' 16 | 17 | count=0 18 | cat benchmark.log | while read line 19 | do 20 | if [[ $line =~ ^rb_ ]]; then 21 | let count++ 22 | echo -n "| $count | $line " 23 | elif [[ $line =~ 'Execution '[Tt]'ime: ' ]]; then 24 | array=($line) 25 | echo "| ${array[2]} |" 26 | fi 27 | done 28 | 29 | grep "Total time" benchmark.log 30 | 31 | -------------------------------------------------------------------------------- /benchmark/benchmark_rb64.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | psql -f benchmark_rb64.sql $*>benchmark_rb64.log 4 | rc=$? 5 | 6 | if [[ $rc -ne 0 ]]; then 7 | exit $rc 8 | fi 9 | 10 | dbinfo=`psql $* -c "select now() now, extversion roaringbitmap,(select setting pg_version from pg_settings where name='server_version') from pg_extension where extname='roaringbitmap'"` 11 | 12 | echo "$dbinfo" 13 | 14 | echo '| No | test | time(ms) |' 15 | echo '| -- | ---- | -------- |' 16 | 17 | count=0 18 | cat benchmark_rb64.log | while read line 19 | do 20 | if [[ $line =~ ^rb64_ ]]; then 21 | let count++ 22 | echo -n "| $count | $line " 23 | elif [[ $line =~ 'Execution '[Tt]'ime: ' ]]; then 24 | array=($line) 25 | echo "| ${array[2]} |" 26 | fi 27 | done 28 | 29 | grep "Total time" benchmark_rb64.log 30 | 31 | -------------------------------------------------------------------------------- /docker-example/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM postgres:16.0-bookworm AS builder 2 | ENV VERSION_TAG=1.1.0 3 | 4 | WORKDIR / 5 | RUN apt-get update && apt-get install -y curl unzip make gcc postgresql-server-dev-16 6 | RUN curl -LO "https://github.com/ChenHuajun/pg_roaringbitmap/archive/refs/tags/v$VERSION_TAG.zip" 7 | RUN unzip "v$VERSION_TAG.zip" 8 | WORKDIR "pg_roaringbitmap-$VERSION_TAG" 9 | RUN make -f Makefile_native && make install 10 | 11 | FROM postgres:16.0-bookworm 12 | COPY --from=builder /usr/share/postgresql/16/extension/roaringbitmap* /usr/share/postgresql/16/extension/ 13 | COPY --from=builder /usr/lib/postgresql/16/lib/roaringbitmap.so /usr/lib/postgresql/16/lib/ 14 | COPY --from=builder /usr/lib/postgresql/16/lib/bitcode/roaringbitmap /usr/lib/postgresql/16/lib/bitcode/roaringbitmap 15 | COPY --from=builder /usr/lib/postgresql/16/lib/bitcode/roaringbitmap.index.bc /usr/lib/postgresql/16/lib/bitcode/roaringbitmap.index.bc 16 | 17 | COPY load-extension.sql /docker-entrypoint-initdb.d 18 | -------------------------------------------------------------------------------- /roaringbitmap--0.4--0.5.sql: -------------------------------------------------------------------------------- 1 | /* roaringbitmap--0.4--0.5 */ 2 | 3 | -- Redefine rb_or_cardinality_agg/rb_and_cardinality_agg/rb_xor_cardinality_agg to support parallel aggregate 4 | 5 | DROP AGGREGATE rb_or_cardinality_agg(roaringbitmap); 6 | CREATE AGGREGATE rb_or_cardinality_agg(roaringbitmap)( 7 | SFUNC = rb_or_trans, 8 | STYPE = internal, 9 | FINALFUNC = rb_cardinality_final, 10 | COMBINEFUNC = rb_or_combine, 11 | SERIALFUNC = rb_serialize, 12 | DESERIALFUNC = rb_deserialize, 13 | PARALLEL = SAFE 14 | ); 15 | 16 | DROP AGGREGATE rb_and_cardinality_agg(roaringbitmap); 17 | CREATE AGGREGATE rb_and_cardinality_agg(roaringbitmap)( 18 | SFUNC = rb_and_trans, 19 | STYPE = internal, 20 | FINALFUNC = rb_cardinality_final, 21 | COMBINEFUNC = rb_and_combine, 22 | SERIALFUNC = rb_serialize, 23 | DESERIALFUNC = rb_deserialize, 24 | PARALLEL = SAFE 25 | ); 26 | 27 | DROP AGGREGATE rb_xor_cardinality_agg(roaringbitmap); 28 | CREATE AGGREGATE rb_xor_cardinality_agg(roaringbitmap)( 29 | SFUNC = rb_xor_trans, 30 | STYPE = internal, 31 | FINALFUNC = rb_cardinality_final, 32 | COMBINEFUNC = rb_xor_combine, 33 | SERIALFUNC = rb_serialize, 34 | DESERIALFUNC = rb_deserialize, 35 | PARALLEL = SAFE 36 | ); 37 | 38 | -------------------------------------------------------------------------------- /META.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "pg_roaringbitmap", 3 | "abstract": "A Roaring Bitmap data type", 4 | "description": "This library contains a single PostgreSQL extension, a Roaring Bitmap data type called 'roaringbitmap', along with some convenience operators and functions for constructing and handling Roaring Bitmaps.", 5 | "version": "1.1.0", 6 | "maintainer": [ 7 | "Chen Huajun " 8 | ], 9 | "license": "apache_2_0", 10 | "provides": { 11 | "pg_roaringbitmap": { 12 | "abstract": "A Roaring Bitmap data type", 13 | "file": "roaringbitmap--1.1.sql", 14 | "docfile": "README.md", 15 | "version": "1.1.0" 16 | } 17 | }, 18 | "resources": { 19 | "bugtracker": { 20 | "web": "http://github.com/ChenHuajun/pg_roaringbitmap/issues/" 21 | }, 22 | "repository": { 23 | "url": "git://github.com/ChenHuajun/pg_roaringbitmap.git", 24 | "web": "http://github.com/ChenHuajun/pg_roaringbitmap/", 25 | "type": "git" 26 | } 27 | }, 28 | "generated_by": "Chen Huajun", 29 | "meta-spec": { 30 | "version": "1.0.0", 31 | "url": "http://pgxn.org/meta/spec.txt" 32 | }, 33 | "tags": [ 34 | "Roaring Bitmap", 35 | "RoaringBitmap", 36 | "bitmap", 37 | "ordered set" 38 | ] 39 | } 40 | -------------------------------------------------------------------------------- /roaringbitmap.h: -------------------------------------------------------------------------------- 1 | #ifndef __ROARINGBITMAP_H__ 2 | #define __ROARINGBITMAP_H__ 3 | 4 | /* Created by ZEROMAX on 2017/3/20.*/ 5 | 6 | #include "postgres.h" 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #include "fmgr.h" 15 | #include "catalog/pg_type.h" 16 | #include "utils/builtins.h" 17 | #include "utils/array.h" 18 | #include "utils/bytea.h" 19 | #include "utils/memutils.h" 20 | #include "utils/guc.h" 21 | #include "lib/stringinfo.h" 22 | #include "funcapi.h" 23 | #include "libpq/pqformat.h" 24 | 25 | #include "roaring.h" 26 | #include "roaring_buffer_reader.h" 27 | #include "roaring64_buffer_reader.h" 28 | 29 | bool ArrayContainsNulls(ArrayType *array); 30 | 31 | /* useful macros for accessing int4 and int8 arrays */ 32 | #define ARRPTR(x) (ARR_DATA_PTR(x)) 33 | #define ARRNELEMS(x) ArrayGetNItems(ARR_NDIM(x), ARR_DIMS(x)) 34 | 35 | /* reject arrays we can't handle; to wit, those containing nulls */ 36 | #define CHECKARRVALID(x) \ 37 | do { \ 38 | if (ARR_HASNULL(x) && ArrayContainsNulls(x)) \ 39 | ereport(ERROR, \ 40 | (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED), \ 41 | errmsg("array must not contain nulls"))); \ 42 | } while(0) 43 | 44 | #define ARRISEMPTY(x) (ARRNELEMS(x) == 0) 45 | 46 | /* GUC variable for output format */ 47 | typedef enum 48 | { 49 | RBITMAP_OUTPUT_ARRAY, /* output as int array */ 50 | RBITMAP_OUTPUT_BYTEA /* output as bytea */ 51 | }RBITMAPOutputFormat; 52 | 53 | extern int rbitmap_output_format; /* output format */ 54 | 55 | #endif 56 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | 2 | # Change Log 3 | 4 | ### v1.1.0(2025-11-10) 5 | 1. made rangeend = 0 as unlimited(in rb64_fill,rb64_clear,rb64_flip,rb64_range,rb64_range_cardinality and rb64_select) 6 | 7 | ### v1.0.0(2025-11-09) 8 | 1. Support 64 bit roaring bitmap 9 | 2. Remove .travis.yml and roaringbitmap_gpdb6.out 10 | 11 | ### v0.5.5(2025-09-14) 12 | 1. Upgrade CRoaring to v4.3.11 13 | 2. Use CRoaring memory hooks to alloc memory by @xin-hedera 14 | 3. Validate user input from rb_from_bytea and roaringbitmap_in by @andreas(#41,#45,#50) 15 | 4. Add Github Actions workflow by @andreas 16 | 5. Add example demonstrating how to build and load the extension for the official postgres docker image by @Valefant 17 | 18 | ### v0.5.4(2022-06-29) 19 | - Fix incorrect result of rb_and which introduced by v0.5.2 (#22) 20 | Similar problems exist in rb_and,rb_and_cardinality,rb_andnot,rb_andnot_cardinality,rb_contains,rb_containedby and rb_intersect 21 | 22 | ### v0.5.3(2021-11-03) 23 | - Adjust test cases to adapt to PG13, PG14 24 | 25 | ### v0.5.2(2020-07-13) 26 | - Optimize performance of some functions through deferred serialization 27 | Optimized functions include rb_or_cardinality,rb_and,rb_and_cardinality,rb_andnot,rb_andnot_cardinality,rb_xor_cardinality,rb_cardinality,rb_is_empty,rb_exsit,rb_equals,rb_not_equals,rb_intersect,rb_contains,rb_containedby,rb_jaccard_dist,rb_min,rb_max,rb_rank,rb_index 28 | - Upgrade CRoaring to v0.2.66 29 | - add benchmark script 30 | - add travis CI support 31 | 32 | ### v0.5.1 (2020-04-30) 33 | - Remove `-march=native` from Makefile and add new Makefile_native to compile using native instructions (#8) 34 | - Fixes memory leak introduced by v0.4.1 which caused by call `PG_GETARG_BYTEA_P()` in aggctx (#9) 35 | 36 | ### v0.5.0 (2019-11-17) 37 | - Upgrade CRoaring to 0.2.65 38 | - Add support of PostgreSQL 12 39 | - Add support of Greenplum-db 6 40 | - Redefine rb_or_cardinality_agg/rb_and_cardinality_agg/rb_xor_cardinality_agg to support parallel aggregate 41 | - Fixes memory leak of v0.4.1 which caused by aligned malloc 42 | 43 | ### v0.4.1 (2019-11-04) 44 | - Use PostgreSQL MemoryContext instead of direct use of malloc 45 | - Fixes a bug that could cause crash when run windows aggregate (#5) 46 | - Fixes a bug that parallel aggregate may product wrong result (#6) 47 | 48 | ### v0.4.0 (2019-05-27) 49 | - Add type cast between roaringbitmp and bytea 50 | - Add support of PostgreSQL 11 51 | 52 | ### v0.3.0 (2018-08-23) 53 | - Add roaringbitmap.output_format parameter to control 'bytea' or 'array' output format 54 | - Change roaringbitmap default output format to 'bytea' in order to better support large cardinality bitmaps 55 | - Add `rb_iterate()` function and fix memory leak 56 | - Add `roaringbitmap.output_format` parameter 57 | 58 | ### v0.2.1 (2018-06-19) 59 | - Upgrade CRoaring to 0.2.49 60 | 61 | ### v0.2.0 (2018-06-09) 62 | - Adds support of input/output syntax similar to int array 63 | - Change range type from integer to bigint 64 | - Add boundary check of range 65 | - Adds `rb_index()`,`rb_fill()`,`rb_clear()`,`rb_range()`,`rb_range_cardinality()`,`rb_jaccard_dist()`,`rb_select()` functions 66 | - Adds Operators 67 | - Rename `rb_minimum()` to `rb_min()` 68 | - Rename `rb_maximum()` to `rb_max()` 69 | - Upgrade CRoaring to 0.2.42 70 | 71 | ### v0.1.0 (2018-04-07) 72 | - Adds initial regresion test set 73 | - Refactor roaringbitmap.c's code to clean compile warnnings 74 | - Adds `rb_to_array()` function 75 | - Removes `rb_iterate()` function to avoid memory leak 76 | - Fixes a bug that could cause memory leak 77 | - Adds support for parallel aggragation 78 | 79 | ### v0.0.3 (2018-03-31) 80 | 81 | - fork from https://github.com/zeromax007/gpdb-roaringbitmap and make roaringbitmap to be a PostgreSQL extension 82 | - update the CRoaring to v0.2.39. -------------------------------------------------------------------------------- /roaring64_buffer_reader.h: -------------------------------------------------------------------------------- 1 | #ifndef __ROARING64_BUFFER_READER_H__ 2 | #define __ROARING64_BUFFER_READER_H__ 3 | 4 | #include "roaring_buffer_reader.h" 5 | 6 | typedef struct roaring64_buffer_s { 7 | const char *buf; 8 | size_t buf_len; 9 | int32_t size; /* number of 64-bit buckets (each holds a 32-bit roaring bitmap) */ 10 | const uint32_t *keys; /* upper 32 bits per bucket */ 11 | const roaring_buffer_t **rb_readers; /* buffer reader for 32-bit roaring bitmaps */ 12 | } roaring64_buffer_t; 13 | 14 | 15 | /** 16 | * Creates a new 64-bit roaring buffer reader (from a portable serialized 64-bit roaringbitmap buffer). 17 | * The caller is responsible for freeing the result. 18 | * Returns NULL if error occurred. 19 | */ 20 | roaring64_buffer_t *roaring64_buffer_create(const char *buf, size_t buf_len); 21 | 22 | /** 23 | * free 64-bit roaring buffer reader 24 | */ 25 | void roaring64_buffer_free(const roaring64_buffer_t *rb); 26 | 27 | /** 28 | * Get the cardinality of the bitmap (number of elements). 29 | */ 30 | uint64_t roaring64_buffer_get_cardinality(const roaring64_buffer_t *rb); 31 | 32 | /** 33 | * Check if value x is present 34 | * Return false if error occurred. 35 | */ 36 | bool roaring64_buffer_contains(const roaring64_buffer_t *r, 37 | uint64_t val, 38 | bool *result); 39 | 40 | /** 41 | * Check if all the elements of ra1 are also in ra2. 42 | * Return false if error occurred. 43 | */ 44 | bool roaring64_buffer_is_subset(const roaring64_buffer_t *ra1, 45 | const roaring64_buffer_t *ra2, 46 | bool *result); 47 | 48 | /** 49 | * Computes the intersection between two bitmaps. 50 | * Return false if error occurred. 51 | */ 52 | bool roaring64_buffer_and_cardinality(const roaring64_buffer_t *x1, 53 | const roaring64_buffer_t *x2, 54 | uint64_t *result); 55 | 56 | /** 57 | * Computes the size of the union between two bitmaps. 58 | * Return false if error occurred. 59 | */ 60 | bool roaring64_buffer_or_cardinality(const roaring64_buffer_t *x1, 61 | const roaring64_buffer_t *x2, 62 | uint64_t *result); 63 | 64 | /** 65 | * Computes the size of the difference (andnot) between two bitmaps. 66 | * Return false if error occurred. 67 | */ 68 | bool roaring64_buffer_andnot_cardinality(const roaring64_buffer_t *x1, 69 | const roaring64_buffer_t *x2, 70 | uint64_t *result); 71 | 72 | /** 73 | * Computes the size of the symmetric difference between two bitmaps. 74 | * Return false if error occurred. 75 | */ 76 | bool roaring64_buffer_xor_cardinality(const roaring64_buffer_t *x1, 77 | const roaring64_buffer_t *x2, 78 | uint64_t *result); 79 | 80 | /** 81 | * Computes the Jaccard index between two bitmaps. 82 | * Return false if error occurred. 83 | */ 84 | bool roaring64_buffer_jaccard_index(const roaring64_buffer_t *x1, 85 | const roaring64_buffer_t *x2, 86 | double *result); 87 | 88 | /** 89 | * Check whether two bitmaps intersect. 90 | * Return false if error occurred. 91 | */ 92 | bool roaring64_buffer_intersect(const roaring64_buffer_t *x1, 93 | const roaring64_buffer_t *x2, 94 | bool *result); 95 | 96 | /** 97 | * Returns true if the bitmap is empty (cardinality is zero). 98 | */ 99 | bool roaring64_buffer_is_empty(const roaring64_buffer_t *rb); 100 | 101 | /** 102 | * Check if the two bitmaps contain the same elements. 103 | * Return false if error occurred. 104 | */ 105 | bool roaring64_buffer_equals(const roaring64_buffer_t *rb1, 106 | const roaring64_buffer_t *rb2, 107 | bool *result); 108 | 109 | /** 110 | * Count the number of integers that are smaller or equal to x. 111 | * Return false if error occurred. 112 | */ 113 | bool roaring64_buffer_rank(const roaring64_buffer_t *rb, 114 | uint64_t x, 115 | uint64_t *result); 116 | 117 | /** 118 | * Get the smallest value in the set, or UINT64_MAX if the set is empty. 119 | * Return false if error occurred. 120 | */ 121 | bool roaring64_buffer_minimum(const roaring64_buffer_t *rb, 122 | uint64_t *result); 123 | 124 | /** 125 | * Get the greatest value in the set, or 0 if the set is empty. 126 | * Return false if error occurred. 127 | */ 128 | bool roaring64_buffer_maximum(const roaring64_buffer_t *rb, 129 | uint64_t *result); 130 | 131 | #endif 132 | 133 | 134 | -------------------------------------------------------------------------------- /roaring_buffer_reader.h: -------------------------------------------------------------------------------- 1 | #ifndef __ROARING_BUFFER_READER_H__ 2 | #define __ROARING_BUFFER_READER_H__ 3 | 4 | #include "roaring.h" 5 | 6 | typedef struct roaring_buffer_s { 7 | const char *buf; 8 | size_t buf_len; 9 | int32_t size; /* number of containers */ 10 | const uint16_t *keyscards; 11 | const uint32_t *offsets; 12 | const char *bitmapOfRunContainers; 13 | bool hasrun; 14 | bool keyscards_need_free; 15 | bool offsets_need_free; 16 | } roaring_buffer_t; 17 | 18 | 19 | 20 | /** 21 | * Creates a new roaring buffer (from a partable serialized roaringbitmap buffer). 22 | * The caller is responsible for freeing the result. 23 | * Returns NULL if error occurred. 24 | */ 25 | roaring_buffer_t *roaring_buffer_create(const char *buf, size_t buf_len); 26 | 27 | /** 28 | * free roaring buffer 29 | */ 30 | void roaring_buffer_free(const roaring_buffer_t *rb); 31 | 32 | /** 33 | * Get the cardinality of the bitmap (number of elements). 34 | */ 35 | uint64_t roaring_buffer_get_cardinality(const roaring_buffer_t *ra); 36 | 37 | /** 38 | * Check if value x is present 39 | * Return false if error occurred. 40 | */ 41 | bool roaring_buffer_contains(const roaring_buffer_t *r, 42 | uint32_t val, 43 | bool *result); 44 | 45 | /** 46 | * Check if all the elements of ra1 are also in ra2. 47 | * Return false if error occurred. 48 | */ 49 | bool roaring_buffer_is_subset(const roaring_buffer_t *ra1, 50 | const roaring_buffer_t *ra2, 51 | bool *result); 52 | 53 | /** 54 | * Computes the intersection between two bitmaps and returns new bitmap. 55 | * The caller is responsible for freeing the result. 56 | * Return NULL if error occurred. 57 | */ 58 | roaring_bitmap_t *roaring_buffer_and(const roaring_buffer_t *ra1, 59 | const roaring_buffer_t *ra2); 60 | 61 | /** 62 | * Computes the size of the difference (andnot) between two bitmaps. 63 | * The caller is responsible for freeing the result. 64 | * Return NULL if error occurred. 65 | */ 66 | roaring_bitmap_t *roaring_buffer_andnot(const roaring_buffer_t *x1, 67 | const roaring_buffer_t *x2); 68 | 69 | /** 70 | * Computes the size of the intersection between two bitmaps. 71 | * Return false if error occurred. 72 | */ 73 | bool roaring_buffer_and_cardinality(const roaring_buffer_t *x1, 74 | const roaring_buffer_t *x2, 75 | uint64_t *result); 76 | 77 | /** 78 | * Computes the size of the union between two bitmaps. 79 | * Return false if error occurred. 80 | */ 81 | bool roaring_buffer_or_cardinality(const roaring_buffer_t *x1, 82 | const roaring_buffer_t *x2, 83 | uint64_t *result); 84 | 85 | /** 86 | * Computes the size of the difference (andnot) between two bitmaps. 87 | * Return false if error occurred. 88 | */ 89 | bool roaring_buffer_andnot_cardinality(const roaring_buffer_t *x1, 90 | const roaring_buffer_t *x2, 91 | uint64_t *result); 92 | 93 | /** 94 | * Computes the size of the difference (andnot) between two bitmaps. 95 | * Return false if error occurred. 96 | */ 97 | bool roaring_buffer_xor_cardinality(const roaring_buffer_t *x1, 98 | const roaring_buffer_t *x2, 99 | uint64_t *result); 100 | 101 | /** 102 | * Computes the Jaccard index between two bitmaps. (Also known as the Tanimoto 103 | * distance, or the Jaccard similarity coefficient) 104 | * 105 | * The Jaccard index is undefined if both bitmaps are empty. 106 | * Return false if error occurred. 107 | */ 108 | bool roaring_buffer_jaccard_index(const roaring_buffer_t *x1, 109 | const roaring_buffer_t *x2, 110 | double *result); 111 | 112 | /** 113 | * Check whether two bitmaps intersect. 114 | * Return false if error occurred. 115 | */ 116 | bool roaring_buffer_intersect(const roaring_buffer_t *x1, 117 | const roaring_buffer_t *x2, 118 | bool *result); 119 | 120 | /** 121 | * Returns true if the bitmap is empty (cardinality is zero). 122 | */ 123 | bool roaring_buffer_is_empty(const roaring_buffer_t *rb); 124 | 125 | 126 | /** 127 | * Check if the two bitmaps contain the same elements. 128 | * Return false if error occurred. 129 | */ 130 | bool roaring_buffer_equals(const roaring_buffer_t *rb1, 131 | const roaring_buffer_t *rb2, 132 | bool *result); 133 | 134 | /** 135 | * Count the number of integers that are smaller or equal to x. 136 | * Return false if error occurred. 137 | */ 138 | bool roaring_buffer_rank(const roaring_buffer_t *rb, 139 | uint32_t x, 140 | uint64_t *reuslt); 141 | 142 | /** 143 | * Get the smallest value in the set, or UINT32_MAX if the set is empty. 144 | * Return false if error occurred. 145 | */ 146 | bool roaring_buffer_minimum(const roaring_buffer_t *rb, 147 | uint32_t *result); 148 | 149 | /** 150 | * Get the greatest value in the set, or 0 if the set is empty. 151 | * Return false if error occurred. 152 | */ 153 | bool roaring_buffer_maximum(const roaring_buffer_t *rb, 154 | uint32_t *result); 155 | 156 | #endif 157 | -------------------------------------------------------------------------------- /benchmark/benchmark.sql: -------------------------------------------------------------------------------- 1 | set max_parallel_workers_per_gather=0; 2 | 3 | \timing 4 | \echo create test table tb_test_bitmaps 5 | create temp table tb_test_bitmaps as 6 | select id,rb_build_agg((random()*10000000)::int) bitmap 7 | from generate_series(1,100)id, generate_series(1,100000)b 8 | group by id; 9 | \timing 10 | 11 | select now() time_start \gset 12 | 13 | \echo rb_and_1 14 | explain analyze 15 | with t as( 16 | select (select bitmap from tb_test_bitmaps where id=1 limit 1) ra1,(select bitmap from tb_test_bitmaps where id=2 limit 1) ra2 17 | ) 18 | select rb_and(ra1,ra2) from t,generate_series(1,100) id; 19 | 20 | \echo rb_and_2 21 | explain analyze 22 | with t as( 23 | select (select bitmap from tb_test_bitmaps where id=1 limit 1) ra1,rb_fill('{}'::roaringbitmap,5000001,15000000) ra2 24 | ) 25 | select rb_and(ra1,ra2) from t,generate_series(1,1000) id; 26 | 27 | \echo rb_or_1 28 | explain analyze 29 | with t as( 30 | select (select bitmap from tb_test_bitmaps where id=1 limit 1) ra1,(select bitmap from tb_test_bitmaps where id=2 limit 1) ra2 31 | ) 32 | select rb_or(ra1,ra2) from t,generate_series(1,100) id; 33 | 34 | \echo rb_or_2 35 | explain analyze 36 | with t as( 37 | select (select bitmap from tb_test_bitmaps where id=1 limit 1) ra1,rb_fill('{}'::roaringbitmap,5000001,15000000) ra2 38 | ) 39 | select rb_or(ra1,ra2) from t,generate_series(1,1000) id; 40 | 41 | \echo rb_xor_1 42 | explain analyze 43 | with t as( 44 | select (select bitmap from tb_test_bitmaps where id=1 limit 1) ra1,(select bitmap from tb_test_bitmaps where id=2 limit 1) ra2 45 | ) 46 | select rb_xor(ra1,ra2) from t,generate_series(1,100) id; 47 | 48 | \echo rb_xor_2 49 | explain analyze 50 | with t as( 51 | select (select bitmap from tb_test_bitmaps where id=1 limit 1) ra1,rb_fill('{}'::roaringbitmap,5000001,15000000) ra2 52 | ) 53 | select rb_xor(ra1,ra2) from t,generate_series(1,1000) id; 54 | 55 | \echo rb_andnot_1 56 | explain analyze 57 | with t as( 58 | select (select bitmap from tb_test_bitmaps where id=1 limit 1) ra1,(select bitmap from tb_test_bitmaps where id=2 limit 1) ra2 59 | ) 60 | select rb_andnot(ra1,ra2) from t,generate_series(1,100) id; 61 | 62 | \echo rb_andnot_2 63 | explain analyze 64 | with t as( 65 | select (select bitmap from tb_test_bitmaps where id=1 limit 1) ra1,rb_fill('{}'::roaringbitmap,5000001,15000000) ra2 66 | ) 67 | select rb_andnot(ra1,ra2) from t,generate_series(1,1000) id; 68 | 69 | \echo rb_add 70 | explain analyze 71 | with t as( 72 | select (select bitmap from tb_test_bitmaps where id=1 limit 1) ra1 73 | ) 74 | select rb_add(ra1,id) from t,generate_series(1,1000)id; 75 | 76 | \echo rb_contains_1 77 | explain analyze 78 | with t as( 79 | select (select bitmap from tb_test_bitmaps where id=1 limit 1) ra1,(select bitmap from tb_test_bitmaps where id=2 limit 1) ra2 80 | ) 81 | select rb_contains(ra1,ra2) from t,generate_series(1,100); 82 | 83 | \echo rb_contains_2 84 | explain analyze 85 | with t as( 86 | select (select bitmap from tb_test_bitmaps where id=1 limit 1) ra1,rb_fill('{}'::roaringbitmap,5000001,15000000) ra2 87 | ) 88 | select rb_contains(ra1,ra2) from t,generate_series(1,1000); 89 | 90 | \echo rb_contains_3 91 | explain analyze 92 | with t as( 93 | select (select bitmap from tb_test_bitmaps where id=1 limit 1) ra1 94 | ) 95 | select rb_contains(ra1,id) from t,generate_series(1,1000)id; 96 | 97 | \echo rb_intersect_1 98 | explain analyze 99 | with t as( 100 | select (select bitmap from tb_test_bitmaps where id=1 limit 1) ra1,(select bitmap from tb_test_bitmaps where id=2 limit 1) ra2 101 | ) 102 | select rb_intersect(ra1,ra2) from t,generate_series(1,100) id; 103 | 104 | \echo rb_intersect_2 105 | explain analyze 106 | with t as( 107 | select (select bitmap from tb_test_bitmaps where id=1 limit 1) ra1,rb_fill('{}'::roaringbitmap,5000001,15000000) ra2 108 | ) 109 | select rb_intersect(ra1,ra2) from t,generate_series(1,1000) id; 110 | 111 | \echo rb_equals_1 112 | explain analyze 113 | with t as( 114 | select (select bitmap from tb_test_bitmaps where id=1 limit 1) ra1,(select bitmap from tb_test_bitmaps where id=2 limit 1) ra2 115 | ) 116 | select rb_equals(ra1,ra2) from t,generate_series(1,100) id; 117 | 118 | \echo rb_equals_2 119 | explain analyze 120 | with t as( 121 | select (select bitmap from tb_test_bitmaps where id=1 limit 1) ra1,rb_fill('{}'::roaringbitmap,5000001,15000000) ra2 122 | ) 123 | select rb_equals(ra1,ra2) from t,generate_series(1,1000) id; 124 | 125 | \echo rb_andnot_1 126 | explain analyze 127 | with t as( 128 | select (select bitmap from tb_test_bitmaps where id=1 limit 1) ra1,(select bitmap from tb_test_bitmaps where id=2 limit 1) ra2 129 | ) 130 | select rb_andnot(ra1,ra2) from t,generate_series(1,100) id; 131 | 132 | \echo rb_andnot_2 133 | explain analyze 134 | with t as( 135 | select (select bitmap from tb_test_bitmaps where id=1 limit 1) ra1,rb_fill('{}'::roaringbitmap,5000001,15000000) ra2 136 | ) 137 | select rb_andnot(ra1,ra2) from t,generate_series(1,1000) id; 138 | 139 | \echo rb_index_1 140 | explain analyze 141 | with t as( 142 | select (select bitmap from tb_test_bitmaps where id=1 limit 1) ra1 143 | ) 144 | select rb_index(ra1,id) from t,generate_series(1,1000)id; 145 | 146 | \echo rb_cardinality_1 147 | explain analyze 148 | with t as( 149 | select (select bitmap from tb_test_bitmaps where id=1 limit 1) ra1 150 | ) 151 | select rb_cardinality(ra1) from t,generate_series(1,1000); 152 | 153 | \echo rb_and_cardinality_1 154 | explain analyze 155 | with t as( 156 | select (select bitmap from tb_test_bitmaps where id=1 limit 1) ra1,(select bitmap from tb_test_bitmaps where id=2 limit 1) ra2 157 | ) 158 | select rb_and_cardinality(ra1,ra2) from t,generate_series(1,100); 159 | 160 | \echo rb_and_cardinality_2 161 | explain analyze 162 | with t as( 163 | select (select bitmap from tb_test_bitmaps where id=1 limit 1) ra1,rb_fill('{}'::roaringbitmap,5000001,15000000) ra2 164 | ) 165 | select rb_and_cardinality(ra1,ra2) from t,generate_series(1,1000); 166 | 167 | \echo rb_or_cardinality_1 168 | explain analyze 169 | with t as( 170 | select (select bitmap from tb_test_bitmaps where id=1 limit 1) ra1,(select bitmap from tb_test_bitmaps where id=2 limit 1) ra2 171 | ) 172 | select rb_or_cardinality(ra1,ra2) from t,generate_series(1,100); 173 | 174 | \echo rb_or_cardinality_2 175 | explain analyze 176 | with t as( 177 | select (select bitmap from tb_test_bitmaps where id=1 limit 1) ra1,rb_fill('{}'::roaringbitmap,5000001,15000000) ra2 178 | ) 179 | select rb_or_cardinality(ra1,ra2) from t,generate_series(1,1000); 180 | 181 | \echo rb_xor_cardinality_1 182 | explain analyze 183 | with t as( 184 | select (select bitmap from tb_test_bitmaps where id=1 limit 1) ra1,(select bitmap from tb_test_bitmaps where id=2 limit 1) ra2 185 | ) 186 | select rb_xor_cardinality(ra1,ra2) from t,generate_series(1,100); 187 | 188 | \echo rb_xor_cardinality_2 189 | explain analyze 190 | with t as( 191 | select (select bitmap from tb_test_bitmaps where id=1 limit 1) ra1,rb_fill('{}'::roaringbitmap,5000001,15000000) ra2 192 | ) 193 | select rb_xor_cardinality(ra1,ra2) from t,generate_series(1,1000); 194 | 195 | \echo rb_andnot_cardinality_1 196 | explain analyze 197 | with t as( 198 | select (select bitmap from tb_test_bitmaps where id=1 limit 1) ra1,(select bitmap from tb_test_bitmaps where id=2 limit 1) ra2 199 | ) 200 | select rb_andnot_cardinality(ra1,ra2) from t,generate_series(1,100); 201 | 202 | \echo rb_andnot_cardinality_2 203 | explain analyze 204 | with t as( 205 | select (select bitmap from tb_test_bitmaps where id=1 limit 1) ra1,rb_fill('{}'::roaringbitmap,5000001,15000000) ra2 206 | ) 207 | select rb_andnot_cardinality(ra1,ra2) from t,generate_series(1,1000); 208 | 209 | \echo rb_is_empty_1 210 | explain analyze 211 | with t as( 212 | select (select bitmap from tb_test_bitmaps where id=1 limit 1) ra1 213 | ) 214 | select rb_is_empty(ra1) from t,generate_series(1,1000); 215 | 216 | \echo rb_range_1 217 | explain analyze 218 | with t as( 219 | select (select bitmap from tb_test_bitmaps where id=1 limit 1) ra1 220 | ) 221 | select rb_range(ra1,id,2000000) from t,generate_series(1,100)id; 222 | 223 | \echo rb_range_cardinality_1 224 | explain analyze 225 | with t as( 226 | select (select bitmap from tb_test_bitmaps where id=1 limit 1) ra1 227 | ) 228 | select rb_range_cardinality(ra1,id,2000000) from t,generate_series(1,1000)id; 229 | 230 | \echo rb_min_1 231 | explain analyze 232 | with t as( 233 | select (select bitmap from tb_test_bitmaps where id=1 limit 1) ra1 234 | ) 235 | select rb_min(ra1) from t,generate_series(1,1000); 236 | 237 | \echo rb_max_1 238 | explain analyze 239 | with t as( 240 | select (select bitmap from tb_test_bitmaps where id=1 limit 1) ra1 241 | ) 242 | select rb_max(ra1) from t,generate_series(1,1000); 243 | 244 | \echo rb_rank_1 245 | explain analyze 246 | with t as( 247 | select (select bitmap from tb_test_bitmaps where id=1 limit 1) ra1 248 | ) 249 | select rb_rank(ra1,100000+id) from t,generate_series(1,1000)id; 250 | 251 | \echo rb_jaccard_dist_1 252 | explain analyze 253 | with t as( 254 | select (select bitmap from tb_test_bitmaps where id=1 limit 1) ra1,(select bitmap from tb_test_bitmaps where id=2 limit 1) ra2 255 | ) 256 | select rb_jaccard_dist(ra1,ra2) from t,generate_series(1,100); 257 | 258 | \echo rb_jaccard_dist_2 259 | explain analyze 260 | with t as( 261 | select (select bitmap from tb_test_bitmaps where id=1 limit 1) ra1,rb_fill('{}'::roaringbitmap,5000001,15000000) ra2 262 | ) 263 | select rb_jaccard_dist(ra1,ra2) from t,generate_series(1,1000); 264 | 265 | \echo rb_to_array_1 266 | explain analyze 267 | with t as( 268 | select (select bitmap from tb_test_bitmaps where id=1 limit 1) ra1 269 | ) 270 | select rb_to_array(ra1) from t,generate_series(1,100); 271 | 272 | \echo rb_iterate_1 273 | explain analyze 274 | with t as( 275 | select (select bitmap from tb_test_bitmaps where id=1 limit 1) ra1 276 | ) 277 | select rb_iterate(ra1) from t,generate_series(1,10); 278 | 279 | \echo rb_build_agg_1 280 | explain analyze 281 | select rb_build_agg(id) from generate_series(1,1000000) id; 282 | 283 | \echo rb_or_agg_1 284 | explain analyze 285 | select rb_or_agg(bitmap) from tb_test_bitmaps; 286 | 287 | \echo rb_and_agg_1 288 | explain analyze 289 | select rb_and_agg(bitmap) from tb_test_bitmaps; 290 | 291 | \echo rb_xor_agg_1 292 | explain analyze 293 | select rb_xor_agg(bitmap) from tb_test_bitmaps; 294 | 295 | \echo rb_or_cardinality_agg_1 296 | explain analyze 297 | select rb_or_cardinality_agg(bitmap) from tb_test_bitmaps; 298 | 299 | \echo rb_and_cardinality_agg_1 300 | explain analyze 301 | select rb_and_cardinality_agg(bitmap) from tb_test_bitmaps; 302 | 303 | \echo rb_xor_cardinality_agg_1 304 | explain analyze 305 | select rb_xor_cardinality_agg(bitmap) from tb_test_bitmaps; 306 | 307 | select now() - :'time_start'::timestamp as time_escape \gset 308 | 309 | \echo Total time: :time_escape 310 | 311 | -------------------------------------------------------------------------------- /benchmark/benchmark_rb64.sql: -------------------------------------------------------------------------------- 1 | set max_parallel_workers_per_gather=0; 2 | 3 | \timing 4 | \echo create test table tb_test_bitmaps 5 | create temp table tb_test_bitmaps as 6 | select id,rb64_build_agg((random()*10000000)::int) bitmap 7 | from generate_series(1,100)id, generate_series(1,100000)b 8 | group by id; 9 | \timing 10 | 11 | select now() time_start \gset 12 | 13 | \echo rb64_and_1 14 | explain analyze 15 | with t as( 16 | select (select bitmap from tb_test_bitmaps where id=1 limit 1) ra1,(select bitmap from tb_test_bitmaps where id=2 limit 1) ra2 17 | ) 18 | select rb64_and(ra1,ra2) from t,generate_series(1,100) id; 19 | 20 | \echo rb64_and_2 21 | explain analyze 22 | with t as( 23 | select (select bitmap from tb_test_bitmaps where id=1 limit 1) ra1,rb64_fill('{}'::roaringbitmap64,5000001,15000000) ra2 24 | ) 25 | select rb64_and(ra1,ra2) from t,generate_series(1,1000) id; 26 | 27 | \echo rb64_or_1 28 | explain analyze 29 | with t as( 30 | select (select bitmap from tb_test_bitmaps where id=1 limit 1) ra1,(select bitmap from tb_test_bitmaps where id=2 limit 1) ra2 31 | ) 32 | select rb64_or(ra1,ra2) from t,generate_series(1,100) id; 33 | 34 | \echo rb64_or_2 35 | explain analyze 36 | with t as( 37 | select (select bitmap from tb_test_bitmaps where id=1 limit 1) ra1,rb64_fill('{}'::roaringbitmap64,5000001,15000000) ra2 38 | ) 39 | select rb64_or(ra1,ra2) from t,generate_series(1,1000) id; 40 | 41 | \echo rb64_xor_1 42 | explain analyze 43 | with t as( 44 | select (select bitmap from tb_test_bitmaps where id=1 limit 1) ra1,(select bitmap from tb_test_bitmaps where id=2 limit 1) ra2 45 | ) 46 | select rb64_xor(ra1,ra2) from t,generate_series(1,100) id; 47 | 48 | \echo rb64_xor_2 49 | explain analyze 50 | with t as( 51 | select (select bitmap from tb_test_bitmaps where id=1 limit 1) ra1,rb64_fill('{}'::roaringbitmap64,5000001,15000000) ra2 52 | ) 53 | select rb64_xor(ra1,ra2) from t,generate_series(1,1000) id; 54 | 55 | \echo rb64_andnot_1 56 | explain analyze 57 | with t as( 58 | select (select bitmap from tb_test_bitmaps where id=1 limit 1) ra1,(select bitmap from tb_test_bitmaps where id=2 limit 1) ra2 59 | ) 60 | select rb64_andnot(ra1,ra2) from t,generate_series(1,100) id; 61 | 62 | \echo rb64_andnot_2 63 | explain analyze 64 | with t as( 65 | select (select bitmap from tb_test_bitmaps where id=1 limit 1) ra1,rb64_fill('{}'::roaringbitmap64,5000001,15000000) ra2 66 | ) 67 | select rb64_andnot(ra1,ra2) from t,generate_series(1,1000) id; 68 | 69 | \echo rb64_add 70 | explain analyze 71 | with t as( 72 | select (select bitmap from tb_test_bitmaps where id=1 limit 1) ra1 73 | ) 74 | select rb64_add(ra1,id) from t,generate_series(1,1000)id; 75 | 76 | \echo rb64_contains_1 77 | explain analyze 78 | with t as( 79 | select (select bitmap from tb_test_bitmaps where id=1 limit 1) ra1,(select bitmap from tb_test_bitmaps where id=2 limit 1) ra2 80 | ) 81 | select rb64_contains(ra1,ra2) from t,generate_series(1,100); 82 | 83 | \echo rb64_contains_2 84 | explain analyze 85 | with t as( 86 | select (select bitmap from tb_test_bitmaps where id=1 limit 1) ra1,rb64_fill('{}'::roaringbitmap64,5000001,15000000) ra2 87 | ) 88 | select rb64_contains(ra1,ra2) from t,generate_series(1,1000); 89 | 90 | \echo rb64_contains_3 91 | explain analyze 92 | with t as( 93 | select (select bitmap from tb_test_bitmaps where id=1 limit 1) ra1 94 | ) 95 | select rb64_contains(ra1,id) from t,generate_series(1,1000)id; 96 | 97 | \echo rb64_intersect_1 98 | explain analyze 99 | with t as( 100 | select (select bitmap from tb_test_bitmaps where id=1 limit 1) ra1,(select bitmap from tb_test_bitmaps where id=2 limit 1) ra2 101 | ) 102 | select rb64_intersect(ra1,ra2) from t,generate_series(1,100) id; 103 | 104 | \echo rb64_intersect_2 105 | explain analyze 106 | with t as( 107 | select (select bitmap from tb_test_bitmaps where id=1 limit 1) ra1,rb64_fill('{}'::roaringbitmap64,5000001,15000000) ra2 108 | ) 109 | select rb64_intersect(ra1,ra2) from t,generate_series(1,1000) id; 110 | 111 | \echo rb64_equals_1 112 | explain analyze 113 | with t as( 114 | select (select bitmap from tb_test_bitmaps where id=1 limit 1) ra1,(select bitmap from tb_test_bitmaps where id=2 limit 1) ra2 115 | ) 116 | select rb64_equals(ra1,ra2) from t,generate_series(1,100) id; 117 | 118 | \echo rb64_equals_2 119 | explain analyze 120 | with t as( 121 | select (select bitmap from tb_test_bitmaps where id=1 limit 1) ra1,rb64_fill('{}'::roaringbitmap64,5000001,15000000) ra2 122 | ) 123 | select rb64_equals(ra1,ra2) from t,generate_series(1,1000) id; 124 | 125 | \echo rb64_andnot_1 126 | explain analyze 127 | with t as( 128 | select (select bitmap from tb_test_bitmaps where id=1 limit 1) ra1,(select bitmap from tb_test_bitmaps where id=2 limit 1) ra2 129 | ) 130 | select rb64_andnot(ra1,ra2) from t,generate_series(1,100) id; 131 | 132 | \echo rb64_andnot_2 133 | explain analyze 134 | with t as( 135 | select (select bitmap from tb_test_bitmaps where id=1 limit 1) ra1,rb64_fill('{}'::roaringbitmap64,5000001,15000000) ra2 136 | ) 137 | select rb64_andnot(ra1,ra2) from t,generate_series(1,1000) id; 138 | 139 | \echo rb64_index_1 140 | explain analyze 141 | with t as( 142 | select (select bitmap from tb_test_bitmaps where id=1 limit 1) ra1 143 | ) 144 | select rb64_index(ra1,id) from t,generate_series(1,1000)id; 145 | 146 | \echo rb64_cardinality_1 147 | explain analyze 148 | with t as( 149 | select (select bitmap from tb_test_bitmaps where id=1 limit 1) ra1 150 | ) 151 | select rb64_cardinality(ra1) from t,generate_series(1,1000); 152 | 153 | \echo rb64_and_cardinality_1 154 | explain analyze 155 | with t as( 156 | select (select bitmap from tb_test_bitmaps where id=1 limit 1) ra1,(select bitmap from tb_test_bitmaps where id=2 limit 1) ra2 157 | ) 158 | select rb64_and_cardinality(ra1,ra2) from t,generate_series(1,100); 159 | 160 | \echo rb64_and_cardinality_2 161 | explain analyze 162 | with t as( 163 | select (select bitmap from tb_test_bitmaps where id=1 limit 1) ra1,rb64_fill('{}'::roaringbitmap64,5000001,15000000) ra2 164 | ) 165 | select rb64_and_cardinality(ra1,ra2) from t,generate_series(1,1000); 166 | 167 | \echo rb64_or_cardinality_1 168 | explain analyze 169 | with t as( 170 | select (select bitmap from tb_test_bitmaps where id=1 limit 1) ra1,(select bitmap from tb_test_bitmaps where id=2 limit 1) ra2 171 | ) 172 | select rb64_or_cardinality(ra1,ra2) from t,generate_series(1,100); 173 | 174 | \echo rb64_or_cardinality_2 175 | explain analyze 176 | with t as( 177 | select (select bitmap from tb_test_bitmaps where id=1 limit 1) ra1,rb64_fill('{}'::roaringbitmap64,5000001,15000000) ra2 178 | ) 179 | select rb64_or_cardinality(ra1,ra2) from t,generate_series(1,1000); 180 | 181 | \echo rb64_xor_cardinality_1 182 | explain analyze 183 | with t as( 184 | select (select bitmap from tb_test_bitmaps where id=1 limit 1) ra1,(select bitmap from tb_test_bitmaps where id=2 limit 1) ra2 185 | ) 186 | select rb64_xor_cardinality(ra1,ra2) from t,generate_series(1,100); 187 | 188 | \echo rb64_xor_cardinality_2 189 | explain analyze 190 | with t as( 191 | select (select bitmap from tb_test_bitmaps where id=1 limit 1) ra1,rb64_fill('{}'::roaringbitmap64,5000001,15000000) ra2 192 | ) 193 | select rb64_xor_cardinality(ra1,ra2) from t,generate_series(1,1000); 194 | 195 | \echo rb64_andnot_cardinality_1 196 | explain analyze 197 | with t as( 198 | select (select bitmap from tb_test_bitmaps where id=1 limit 1) ra1,(select bitmap from tb_test_bitmaps where id=2 limit 1) ra2 199 | ) 200 | select rb64_andnot_cardinality(ra1,ra2) from t,generate_series(1,100); 201 | 202 | \echo rb64_andnot_cardinality_2 203 | explain analyze 204 | with t as( 205 | select (select bitmap from tb_test_bitmaps where id=1 limit 1) ra1,rb64_fill('{}'::roaringbitmap64,5000001,15000000) ra2 206 | ) 207 | select rb64_andnot_cardinality(ra1,ra2) from t,generate_series(1,1000); 208 | 209 | \echo rb64_is_empty_1 210 | explain analyze 211 | with t as( 212 | select (select bitmap from tb_test_bitmaps where id=1 limit 1) ra1 213 | ) 214 | select rb64_is_empty(ra1) from t,generate_series(1,1000); 215 | 216 | \echo rb64_range_1 217 | explain analyze 218 | with t as( 219 | select (select bitmap from tb_test_bitmaps where id=1 limit 1) ra1 220 | ) 221 | select rb64_range(ra1,id,2000000) from t,generate_series(1,100)id; 222 | 223 | \echo rb64_range_cardinality_1 224 | explain analyze 225 | with t as( 226 | select (select bitmap from tb_test_bitmaps where id=1 limit 1) ra1 227 | ) 228 | select rb64_range_cardinality(ra1,id,2000000) from t,generate_series(1,1000)id; 229 | 230 | \echo rb64_min_1 231 | explain analyze 232 | with t as( 233 | select (select bitmap from tb_test_bitmaps where id=1 limit 1) ra1 234 | ) 235 | select rb64_min(ra1) from t,generate_series(1,1000); 236 | 237 | \echo rb64_max_1 238 | explain analyze 239 | with t as( 240 | select (select bitmap from tb_test_bitmaps where id=1 limit 1) ra1 241 | ) 242 | select rb64_max(ra1) from t,generate_series(1,1000); 243 | 244 | \echo rb64_rank_1 245 | explain analyze 246 | with t as( 247 | select (select bitmap from tb_test_bitmaps where id=1 limit 1) ra1 248 | ) 249 | select rb64_rank(ra1,100000+id) from t,generate_series(1,1000)id; 250 | 251 | \echo rb64_jaccard_dist_1 252 | explain analyze 253 | with t as( 254 | select (select bitmap from tb_test_bitmaps where id=1 limit 1) ra1,(select bitmap from tb_test_bitmaps where id=2 limit 1) ra2 255 | ) 256 | select rb64_jaccard_dist(ra1,ra2) from t,generate_series(1,100); 257 | 258 | \echo rb64_jaccard_dist_2 259 | explain analyze 260 | with t as( 261 | select (select bitmap from tb_test_bitmaps where id=1 limit 1) ra1,rb64_fill('{}'::roaringbitmap64,5000001,15000000) ra2 262 | ) 263 | select rb64_jaccard_dist(ra1,ra2) from t,generate_series(1,1000); 264 | 265 | \echo rb64_to_array_1 266 | explain analyze 267 | with t as( 268 | select (select bitmap from tb_test_bitmaps where id=1 limit 1) ra1 269 | ) 270 | select rb64_to_array(ra1) from t,generate_series(1,100); 271 | 272 | \echo rb64_iterate_1 273 | explain analyze 274 | with t as( 275 | select (select bitmap from tb_test_bitmaps where id=1 limit 1) ra1 276 | ) 277 | select rb64_iterate(ra1) from t,generate_series(1,10); 278 | 279 | \echo rb64_build_agg_1 280 | explain analyze 281 | select rb64_build_agg(id) from generate_series(1,1000000) id; 282 | 283 | \echo rb64_or_agg_1 284 | explain analyze 285 | select rb64_or_agg(bitmap) from tb_test_bitmaps; 286 | 287 | \echo rb64_and_agg_1 288 | explain analyze 289 | select rb64_and_agg(bitmap) from tb_test_bitmaps; 290 | 291 | \echo rb64_xor_agg_1 292 | explain analyze 293 | select rb64_xor_agg(bitmap) from tb_test_bitmaps; 294 | 295 | \echo rb64_or_cardinality_agg_1 296 | explain analyze 297 | select rb64_or_cardinality_agg(bitmap) from tb_test_bitmaps; 298 | 299 | \echo rb64_and_cardinality_agg_1 300 | explain analyze 301 | select rb64_and_cardinality_agg(bitmap) from tb_test_bitmaps; 302 | 303 | \echo rb64_xor_cardinality_agg_1 304 | explain analyze 305 | select rb64_xor_cardinality_agg(bitmap) from tb_test_bitmaps; 306 | 307 | select now() - :'time_start'::timestamp as time_escape \gset 308 | 309 | \echo Total time: :time_escape 310 | 311 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /roaringbitmap--0.2.sql: -------------------------------------------------------------------------------- 1 | 2 | -- complain if script is sourced in psql, rather than via CREATE EXTENSION 3 | \echo Use "CREATE EXTENSION roaringbitmap" to load this file. \quit 4 | 5 | -- 6 | -- Type definition for Roaring Bitmaps 7 | -- 8 | 9 | CREATE TYPE roaringbitmap; 10 | 11 | CREATE OR REPLACE FUNCTION roaringbitmap_in(cstring) 12 | RETURNS roaringbitmap 13 | AS 'MODULE_PATHNAME','roaringbitmap_in' 14 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 15 | 16 | CREATE OR REPLACE FUNCTION roaringbitmap_out(roaringbitmap) 17 | RETURNS cstring 18 | AS 'MODULE_PATHNAME','roaringbitmap_out' 19 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 20 | 21 | CREATE OR REPLACE FUNCTION roaringbitmap_recv(internal) 22 | RETURNS roaringbitmap 23 | AS 'MODULE_PATHNAME','roaringbitmap_recv' 24 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 25 | 26 | CREATE OR REPLACE FUNCTION roaringbitmap_send(roaringbitmap) 27 | RETURNS bytea 28 | AS 'MODULE_PATHNAME','roaringbitmap_send' 29 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 30 | 31 | CREATE TYPE roaringbitmap ( 32 | INTERNALLENGTH = VARIABLE, 33 | INPUT = roaringbitmap_in, 34 | OUTPUT = roaringbitmap_out, 35 | receive = roaringbitmap_recv, 36 | send = roaringbitmap_send, 37 | STORAGE = external 38 | ); 39 | 40 | -- 41 | -- Operator Functions 42 | -- 43 | CREATE OR REPLACE FUNCTION rb_and(roaringbitmap, roaringbitmap) 44 | RETURNS roaringbitmap 45 | AS 'MODULE_PATHNAME', 'rb_and' 46 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 47 | 48 | CREATE OR REPLACE FUNCTION rb_or(roaringbitmap, roaringbitmap) 49 | RETURNS roaringbitmap 50 | AS 'MODULE_PATHNAME', 'rb_or' 51 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 52 | 53 | CREATE OR REPLACE FUNCTION rb_xor(roaringbitmap, roaringbitmap) 54 | RETURNS roaringbitmap 55 | AS 'MODULE_PATHNAME', 'rb_xor' 56 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 57 | 58 | CREATE OR REPLACE FUNCTION rb_andnot(roaringbitmap, roaringbitmap) 59 | RETURNS roaringbitmap 60 | AS 'MODULE_PATHNAME', 'rb_andnot' 61 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 62 | 63 | CREATE OR REPLACE FUNCTION rb_add(roaringbitmap, integer) 64 | RETURNS roaringbitmap 65 | AS 'MODULE_PATHNAME', 'rb_add' 66 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 67 | 68 | CREATE OR REPLACE FUNCTION rb_add(integer, roaringbitmap) 69 | RETURNS roaringbitmap 70 | AS 'SELECT rb_add($2, $1);' 71 | LANGUAGE SQL STRICT IMMUTABLE PARALLEL SAFE; 72 | 73 | CREATE OR REPLACE FUNCTION rb_remove(roaringbitmap, integer) 74 | RETURNS roaringbitmap 75 | AS 'MODULE_PATHNAME', 'rb_remove' 76 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 77 | 78 | CREATE OR REPLACE FUNCTION rb_shiftright(roaringbitmap, bigint) 79 | RETURNS roaringbitmap 80 | AS 'MODULE_PATHNAME', 'rb_shiftright' 81 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 82 | 83 | CREATE OR REPLACE FUNCTION rb_shiftleft(roaringbitmap, bigint) 84 | RETURNS roaringbitmap 85 | AS 'SELECT rb_shiftright($1, -$2);' 86 | LANGUAGE SQL STRICT IMMUTABLE PARALLEL SAFE; 87 | 88 | CREATE OR REPLACE FUNCTION rb_contains(roaringbitmap, roaringbitmap) 89 | RETURNS bool 90 | AS 'MODULE_PATHNAME', 'rb_contains' 91 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 92 | 93 | CREATE OR REPLACE FUNCTION rb_contains(roaringbitmap, integer) 94 | RETURNS bool 95 | AS 'MODULE_PATHNAME', 'rb_exsit' 96 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 97 | 98 | CREATE OR REPLACE FUNCTION rb_containedby(roaringbitmap, roaringbitmap) 99 | RETURNS bool 100 | AS 'MODULE_PATHNAME', 'rb_containedby' 101 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 102 | 103 | CREATE OR REPLACE FUNCTION rb_containedby(integer, roaringbitmap) 104 | RETURNS bool 105 | AS 'SELECT rb_contains($2, $1);' 106 | LANGUAGE SQL STRICT IMMUTABLE PARALLEL SAFE; 107 | 108 | CREATE OR REPLACE FUNCTION rb_intersect(roaringbitmap, roaringbitmap) 109 | RETURNS bool 110 | AS 'MODULE_PATHNAME', 'rb_intersect' 111 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 112 | 113 | CREATE OR REPLACE FUNCTION rb_equals(roaringbitmap, roaringbitmap) 114 | RETURNS bool 115 | AS 'MODULE_PATHNAME', 'rb_equals' 116 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 117 | 118 | CREATE OR REPLACE FUNCTION rb_not_equals(roaringbitmap, roaringbitmap) 119 | RETURNS bool 120 | AS 'MODULE_PATHNAME', 'rb_not_equals' 121 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 122 | 123 | -- 124 | -- Functions 125 | -- 126 | 127 | CREATE OR REPLACE FUNCTION rb_build(integer[]) 128 | RETURNS roaringbitmap 129 | AS 'MODULE_PATHNAME', 'rb_build' 130 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 131 | 132 | CREATE OR REPLACE FUNCTION rb_index(roaringbitmap, integer) 133 | RETURNS bigint 134 | AS 'MODULE_PATHNAME', 'rb_index' 135 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 136 | 137 | CREATE OR REPLACE FUNCTION rb_cardinality(roaringbitmap) 138 | RETURNS bigint 139 | AS 'MODULE_PATHNAME', 'rb_cardinality' 140 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 141 | 142 | CREATE OR REPLACE FUNCTION rb_and_cardinality(roaringbitmap, roaringbitmap) 143 | RETURNS bigint 144 | AS 'MODULE_PATHNAME', 'rb_and_cardinality' 145 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 146 | 147 | CREATE OR REPLACE FUNCTION rb_or_cardinality(roaringbitmap, roaringbitmap) 148 | RETURNS bigint 149 | AS 'MODULE_PATHNAME', 'rb_or_cardinality' 150 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 151 | 152 | CREATE OR REPLACE FUNCTION rb_xor_cardinality(roaringbitmap, roaringbitmap) 153 | RETURNS bigint 154 | AS 'MODULE_PATHNAME', 'rb_xor_cardinality' 155 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 156 | 157 | CREATE OR REPLACE FUNCTION rb_andnot_cardinality(roaringbitmap, roaringbitmap) 158 | RETURNS bigint 159 | AS 'MODULE_PATHNAME', 'rb_andnot_cardinality' 160 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 161 | 162 | CREATE OR REPLACE FUNCTION rb_is_empty(roaringbitmap) 163 | RETURNS bool 164 | AS 'MODULE_PATHNAME', 'rb_is_empty' 165 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 166 | 167 | CREATE OR REPLACE FUNCTION rb_fill(roaringbitmap, range_start bigint, range_end bigint) 168 | RETURNS roaringbitmap 169 | AS 'MODULE_PATHNAME', 'rb_fill' 170 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 171 | 172 | CREATE OR REPLACE FUNCTION rb_clear(roaringbitmap, range_start bigint, range_end bigint) 173 | RETURNS roaringbitmap 174 | AS 'MODULE_PATHNAME', 'rb_clear' 175 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 176 | 177 | CREATE OR REPLACE FUNCTION rb_flip(roaringbitmap, range_start bigint, range_end bigint) 178 | RETURNS roaringbitmap 179 | AS 'MODULE_PATHNAME', 'rb_flip' 180 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 181 | 182 | CREATE OR REPLACE FUNCTION rb_range(roaringbitmap, range_start bigint, range_end bigint) 183 | RETURNS roaringbitmap 184 | AS 'MODULE_PATHNAME', 'rb_range' 185 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 186 | 187 | CREATE OR REPLACE FUNCTION rb_range_cardinality(roaringbitmap, range_start bigint, range_end bigint) 188 | RETURNS bigint 189 | AS 'MODULE_PATHNAME', 'rb_range_cardinality' 190 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 191 | 192 | CREATE OR REPLACE FUNCTION rb_min(roaringbitmap) 193 | RETURNS integer 194 | AS 'MODULE_PATHNAME', 'rb_min' 195 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 196 | 197 | CREATE OR REPLACE FUNCTION rb_max(roaringbitmap) 198 | RETURNS integer 199 | AS 'MODULE_PATHNAME', 'rb_max' 200 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 201 | 202 | CREATE OR REPLACE FUNCTION rb_rank(roaringbitmap, integer) 203 | RETURNS bigint 204 | AS 'MODULE_PATHNAME', 'rb_rank' 205 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 206 | 207 | CREATE OR REPLACE FUNCTION rb_jaccard_dist(roaringbitmap, roaringbitmap) 208 | RETURNS float8 209 | AS 'MODULE_PATHNAME', 'rb_jaccard_dist' 210 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 211 | 212 | CREATE OR REPLACE FUNCTION rb_select(roaringbitmap, bitset_limit bigint,bitset_offset bigint=0,reverse boolean=false,range_start bigint=0,range_end bigint=4294967296) 213 | RETURNS roaringbitmap 214 | AS 'MODULE_PATHNAME', 'rb_select' 215 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 216 | 217 | CREATE OR REPLACE FUNCTION rb_to_array(roaringbitmap) 218 | RETURNS integer[] 219 | AS 'MODULE_PATHNAME', 'rb_to_array' 220 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 221 | 222 | -- 223 | -- Operators 224 | -- 225 | 226 | CREATE OPERATOR & ( 227 | LEFTARG = roaringbitmap, 228 | RIGHTARG = roaringbitmap, 229 | PROCEDURE = rb_and 230 | ); 231 | 232 | CREATE OPERATOR | ( 233 | LEFTARG = roaringbitmap, 234 | RIGHTARG = roaringbitmap, 235 | PROCEDURE = rb_or 236 | ); 237 | 238 | CREATE OPERATOR | ( 239 | LEFTARG = roaringbitmap, 240 | RIGHTARG = int4, 241 | PROCEDURE = rb_add 242 | ); 243 | 244 | CREATE OPERATOR | ( 245 | LEFTARG = int4, 246 | RIGHTARG = roaringbitmap, 247 | PROCEDURE = rb_add 248 | ); 249 | 250 | CREATE OPERATOR # ( 251 | LEFTARG = roaringbitmap, 252 | RIGHTARG = roaringbitmap, 253 | PROCEDURE = rb_xor 254 | ); 255 | 256 | CREATE OPERATOR << ( 257 | LEFTARG = roaringbitmap, 258 | RIGHTARG = bigint, 259 | PROCEDURE = rb_shiftleft 260 | ); 261 | 262 | CREATE OPERATOR >> ( 263 | LEFTARG = roaringbitmap, 264 | RIGHTARG = bigint, 265 | PROCEDURE = rb_shiftright 266 | ); 267 | 268 | CREATE OPERATOR - ( 269 | LEFTARG = roaringbitmap, 270 | RIGHTARG = roaringbitmap, 271 | PROCEDURE = rb_andnot 272 | ); 273 | 274 | CREATE OPERATOR - ( 275 | LEFTARG = roaringbitmap, 276 | RIGHTARG = int4, 277 | PROCEDURE = rb_remove 278 | ); 279 | 280 | CREATE OPERATOR @> ( 281 | LEFTARG = roaringbitmap, 282 | RIGHTARG = roaringbitmap, 283 | PROCEDURE = rb_contains, 284 | COMMUTATOR = '<@', 285 | RESTRICT = contsel, 286 | JOIN = contjoinsel 287 | ); 288 | 289 | CREATE OPERATOR @> ( 290 | LEFTARG = roaringbitmap, 291 | RIGHTARG = int4, 292 | PROCEDURE = rb_contains, 293 | COMMUTATOR = '<@', 294 | RESTRICT = contsel, 295 | JOIN = contjoinsel 296 | ); 297 | 298 | CREATE OPERATOR <@ ( 299 | LEFTARG = roaringbitmap, 300 | RIGHTARG = roaringbitmap, 301 | PROCEDURE = rb_containedby, 302 | COMMUTATOR = '@>', 303 | RESTRICT = contsel, 304 | JOIN = contjoinsel 305 | ); 306 | 307 | CREATE OPERATOR <@ ( 308 | LEFTARG = int4, 309 | RIGHTARG = roaringbitmap, 310 | PROCEDURE = rb_containedby, 311 | COMMUTATOR = '@>', 312 | RESTRICT = contsel, 313 | JOIN = contjoinsel 314 | ); 315 | 316 | CREATE OPERATOR && ( 317 | LEFTARG = roaringbitmap, 318 | RIGHTARG = roaringbitmap, 319 | PROCEDURE = rb_intersect, 320 | COMMUTATOR = '&&', 321 | RESTRICT = contsel, 322 | JOIN = contjoinsel 323 | ); 324 | 325 | CREATE OPERATOR = ( 326 | LEFTARG = roaringbitmap, 327 | RIGHTARG = roaringbitmap, 328 | PROCEDURE = rb_equals, 329 | COMMUTATOR = '=', 330 | NEGATOR = '<>', 331 | RESTRICT = eqsel, 332 | JOIN = eqjoinsel 333 | ); 334 | 335 | CREATE OPERATOR <> ( 336 | LEFTARG = roaringbitmap, 337 | RIGHTARG = roaringbitmap, 338 | PROCEDURE = rb_not_equals, 339 | COMMUTATOR = '<>', 340 | NEGATOR = '=', 341 | RESTRICT = neqsel, 342 | JOIN = neqjoinsel 343 | ); 344 | 345 | -- 346 | -- Aggragations 347 | -- 348 | 349 | CREATE OR REPLACE FUNCTION rb_final(internal) 350 | RETURNS roaringbitmap 351 | AS 'MODULE_PATHNAME', 'rb_serialize' 352 | LANGUAGE C IMMUTABLE PARALLEL SAFE; 353 | 354 | CREATE OR REPLACE FUNCTION rb_serialize(internal) 355 | RETURNS bytea 356 | AS 'MODULE_PATHNAME', 'rb_serialize' 357 | LANGUAGE C IMMUTABLE PARALLEL SAFE; 358 | 359 | CREATE OR REPLACE FUNCTION rb_deserialize(bytea,internal) 360 | RETURNS internal 361 | AS 'MODULE_PATHNAME', 'rb_deserialize' 362 | LANGUAGE C IMMUTABLE PARALLEL SAFE; 363 | 364 | CREATE OR REPLACE FUNCTION rb_cardinality_final(internal) 365 | RETURNS bigint 366 | AS 'MODULE_PATHNAME', 'rb_cardinality_final' 367 | LANGUAGE C IMMUTABLE PARALLEL SAFE; 368 | 369 | 370 | CREATE OR REPLACE FUNCTION rb_or_trans(internal, roaringbitmap) 371 | RETURNS internal 372 | AS 'MODULE_PATHNAME', 'rb_or_trans' 373 | LANGUAGE C IMMUTABLE PARALLEL SAFE; 374 | 375 | CREATE OR REPLACE FUNCTION rb_or_combine(internal, internal) 376 | RETURNS internal 377 | AS 'MODULE_PATHNAME', 'rb_or_combine' 378 | LANGUAGE C IMMUTABLE PARALLEL SAFE; 379 | 380 | CREATE AGGREGATE rb_or_agg(roaringbitmap)( 381 | SFUNC = rb_or_trans, 382 | STYPE = internal, 383 | FINALFUNC = rb_final, 384 | COMBINEFUNC = rb_or_combine, 385 | SERIALFUNC = rb_serialize, 386 | DESERIALFUNC = rb_deserialize, 387 | PARALLEL = SAFE 388 | ); 389 | 390 | CREATE AGGREGATE rb_or_cardinality_agg(roaringbitmap)( 391 | SFUNC = rb_or_trans, 392 | STYPE = internal, 393 | FINALFUNC = rb_cardinality_final, 394 | PARALLEL = SAFE 395 | ); 396 | 397 | 398 | CREATE OR REPLACE FUNCTION rb_and_trans(internal, roaringbitmap) 399 | RETURNS internal 400 | AS 'MODULE_PATHNAME', 'rb_and_trans' 401 | LANGUAGE C IMMUTABLE PARALLEL SAFE; 402 | 403 | CREATE OR REPLACE FUNCTION rb_and_combine(internal, internal) 404 | RETURNS internal 405 | AS 'MODULE_PATHNAME', 'rb_and_combine' 406 | LANGUAGE C IMMUTABLE PARALLEL SAFE; 407 | 408 | CREATE AGGREGATE rb_and_agg(roaringbitmap)( 409 | SFUNC = rb_and_trans, 410 | STYPE = internal, 411 | FINALFUNC = rb_final, 412 | COMBINEFUNC = rb_and_combine, 413 | SERIALFUNC = rb_serialize, 414 | DESERIALFUNC = rb_deserialize, 415 | PARALLEL = SAFE 416 | ); 417 | 418 | 419 | CREATE AGGREGATE rb_and_cardinality_agg(roaringbitmap)( 420 | SFUNC = rb_and_trans, 421 | STYPE = internal, 422 | FINALFUNC = rb_cardinality_final, 423 | PARALLEL = SAFE 424 | ); 425 | 426 | 427 | CREATE OR REPLACE FUNCTION rb_xor_trans(internal, roaringbitmap) 428 | RETURNS internal 429 | AS 'MODULE_PATHNAME', 'rb_xor_trans' 430 | LANGUAGE C IMMUTABLE PARALLEL SAFE; 431 | 432 | CREATE OR REPLACE FUNCTION rb_xor_combine(internal, internal) 433 | RETURNS internal 434 | AS 'MODULE_PATHNAME', 'rb_xor_combine' 435 | LANGUAGE C IMMUTABLE PARALLEL SAFE; 436 | 437 | CREATE AGGREGATE rb_xor_agg(roaringbitmap)( 438 | SFUNC = rb_xor_trans, 439 | STYPE = internal, 440 | FINALFUNC = rb_final, 441 | COMBINEFUNC = rb_xor_combine, 442 | SERIALFUNC = rb_serialize, 443 | DESERIALFUNC = rb_deserialize, 444 | PARALLEL = SAFE 445 | ); 446 | 447 | 448 | CREATE AGGREGATE rb_xor_cardinality_agg(roaringbitmap)( 449 | SFUNC = rb_xor_trans, 450 | STYPE = internal, 451 | FINALFUNC = rb_cardinality_final, 452 | PARALLEL = SAFE 453 | ); 454 | 455 | CREATE OR REPLACE FUNCTION rb_build_trans(internal, integer) 456 | RETURNS internal 457 | AS 'MODULE_PATHNAME', 'rb_build_trans' 458 | LANGUAGE C IMMUTABLE PARALLEL SAFE; 459 | 460 | CREATE AGGREGATE rb_build_agg(integer)( 461 | SFUNC = rb_build_trans, 462 | STYPE = internal, 463 | FINALFUNC = rb_final, 464 | COMBINEFUNC = rb_or_combine, 465 | SERIALFUNC = rb_serialize, 466 | DESERIALFUNC = rb_deserialize, 467 | PARALLEL = SAFE 468 | ); 469 | -------------------------------------------------------------------------------- /roaringbitmap--0.5--1.0.sql: -------------------------------------------------------------------------------- 1 | 2 | -- complain if script is sourced in psql, rather than via CREATE EXTENSION 3 | \echo Use "CREATE EXTENSION roaringbitmap" to load this file. \quit 4 | 5 | CREATE OR REPLACE FUNCTION rb_contains(roaringbitmap, integer) 6 | RETURNS bool 7 | AS 'MODULE_PATHNAME', 'rb_exists' 8 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 9 | 10 | -- 11 | -- Type definition for 64 bit Roaring Bitmaps 12 | -- 13 | 14 | CREATE TYPE roaringbitmap64; 15 | 16 | CREATE OR REPLACE FUNCTION roaringbitmap64_in(cstring) 17 | RETURNS roaringbitmap64 18 | AS 'MODULE_PATHNAME','roaringbitmap64_in' 19 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 20 | 21 | CREATE OR REPLACE FUNCTION roaringbitmap64_out(roaringbitmap64) 22 | RETURNS cstring 23 | AS 'MODULE_PATHNAME','roaringbitmap64_out' 24 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 25 | 26 | CREATE OR REPLACE FUNCTION roaringbitmap64_recv(internal) 27 | RETURNS roaringbitmap64 28 | AS 'MODULE_PATHNAME','roaringbitmap64_recv' 29 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 30 | 31 | CREATE OR REPLACE FUNCTION roaringbitmap64_send(roaringbitmap64) 32 | RETURNS bytea 33 | AS 'MODULE_PATHNAME','roaringbitmap64_send' 34 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 35 | 36 | CREATE TYPE roaringbitmap64 ( 37 | INTERNALLENGTH = VARIABLE, 38 | INPUT = roaringbitmap64_in, 39 | OUTPUT = roaringbitmap64_out, 40 | receive = roaringbitmap64_recv, 41 | send = roaringbitmap64_send, 42 | STORAGE = external 43 | ); 44 | 45 | -- 46 | -- type cast for bytea 47 | -- 48 | CREATE OR REPLACE FUNCTION roaringbitmap64(bytea) 49 | RETURNS roaringbitmap64 50 | AS 'MODULE_PATHNAME','rb64_from_bytea' 51 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 52 | 53 | CREATE CAST (roaringbitmap64 AS bytea) WITHOUT FUNCTION; 54 | 55 | CREATE CAST (bytea AS roaringbitmap64) WITH FUNCTION roaringbitmap64(bytea); 56 | 57 | -- 58 | -- type cast for roaringbitmap 59 | -- 60 | CREATE OR REPLACE FUNCTION rb64_to_roaringbitmap(roaringbitmap64) 61 | RETURNS roaringbitmap 62 | AS 'MODULE_PATHNAME', 'rb64_to_roaringbitmap' 63 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 64 | 65 | CREATE OR REPLACE FUNCTION rb64_from_roaringbitmap(roaringbitmap) 66 | RETURNS roaringbitmap64 67 | AS 'MODULE_PATHNAME', 'rb64_from_roaringbitmap' 68 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 69 | 70 | CREATE CAST (roaringbitmap64 AS roaringbitmap) WITH FUNCTION rb64_to_roaringbitmap(roaringbitmap64); 71 | CREATE CAST (roaringbitmap AS roaringbitmap64) WITH FUNCTION rb64_from_roaringbitmap(roaringbitmap); 72 | 73 | -- 74 | -- Operator Functions 75 | -- 76 | CREATE OR REPLACE FUNCTION rb64_and(roaringbitmap64, roaringbitmap64) 77 | RETURNS roaringbitmap64 78 | AS 'MODULE_PATHNAME', 'rb64_and' 79 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 80 | 81 | CREATE OR REPLACE FUNCTION rb64_or(roaringbitmap64, roaringbitmap64) 82 | RETURNS roaringbitmap64 83 | AS 'MODULE_PATHNAME', 'rb64_or' 84 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 85 | 86 | CREATE OR REPLACE FUNCTION rb64_xor(roaringbitmap64, roaringbitmap64) 87 | RETURNS roaringbitmap64 88 | AS 'MODULE_PATHNAME', 'rb64_xor' 89 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 90 | 91 | CREATE OR REPLACE FUNCTION rb64_andnot(roaringbitmap64, roaringbitmap64) 92 | RETURNS roaringbitmap64 93 | AS 'MODULE_PATHNAME', 'rb64_andnot' 94 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 95 | 96 | CREATE OR REPLACE FUNCTION rb64_add(roaringbitmap64, bigint) 97 | RETURNS roaringbitmap64 98 | AS 'MODULE_PATHNAME', 'rb64_add' 99 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 100 | 101 | CREATE OR REPLACE FUNCTION rb64_add(bigint, roaringbitmap64) 102 | RETURNS roaringbitmap64 103 | AS 'SELECT rb64_add($2, $1);' 104 | LANGUAGE SQL STRICT IMMUTABLE PARALLEL SAFE; 105 | 106 | CREATE OR REPLACE FUNCTION rb64_remove(roaringbitmap64, bigint) 107 | RETURNS roaringbitmap64 108 | AS 'MODULE_PATHNAME', 'rb64_remove' 109 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 110 | 111 | CREATE OR REPLACE FUNCTION rb64_shiftright(roaringbitmap64, bigint) 112 | RETURNS roaringbitmap64 113 | AS 'MODULE_PATHNAME', 'rb64_shiftright' 114 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 115 | 116 | CREATE OR REPLACE FUNCTION rb64_shiftleft(roaringbitmap64, bigint) 117 | RETURNS roaringbitmap64 118 | AS 'SELECT rb64_shiftright($1, -$2);' 119 | LANGUAGE SQL STRICT IMMUTABLE PARALLEL SAFE; 120 | 121 | CREATE OR REPLACE FUNCTION rb64_contains(roaringbitmap64, roaringbitmap64) 122 | RETURNS bool 123 | AS 'MODULE_PATHNAME', 'rb64_contains' 124 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 125 | 126 | CREATE OR REPLACE FUNCTION rb64_contains(roaringbitmap64, bigint) 127 | RETURNS bool 128 | AS 'MODULE_PATHNAME', 'rb64_exists' 129 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 130 | 131 | CREATE OR REPLACE FUNCTION rb64_containedby(roaringbitmap64, roaringbitmap64) 132 | RETURNS bool 133 | AS 'MODULE_PATHNAME', 'rb64_containedby' 134 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 135 | 136 | CREATE OR REPLACE FUNCTION rb64_containedby(bigint, roaringbitmap64) 137 | RETURNS bool 138 | AS 'SELECT rb64_contains($2, $1);' 139 | LANGUAGE SQL STRICT IMMUTABLE PARALLEL SAFE; 140 | 141 | CREATE OR REPLACE FUNCTION rb64_intersect(roaringbitmap64, roaringbitmap64) 142 | RETURNS bool 143 | AS 'MODULE_PATHNAME', 'rb64_intersect' 144 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 145 | 146 | CREATE OR REPLACE FUNCTION rb64_equals(roaringbitmap64, roaringbitmap64) 147 | RETURNS bool 148 | AS 'MODULE_PATHNAME', 'rb64_equals' 149 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 150 | 151 | CREATE OR REPLACE FUNCTION rb64_not_equals(roaringbitmap64, roaringbitmap64) 152 | RETURNS bool 153 | AS 'MODULE_PATHNAME', 'rb64_not_equals' 154 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 155 | 156 | -- 157 | -- Functions 158 | -- 159 | 160 | CREATE OR REPLACE FUNCTION rb64_build(bigint[]) 161 | RETURNS roaringbitmap64 162 | AS 'MODULE_PATHNAME', 'rb64_build' 163 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 164 | 165 | CREATE OR REPLACE FUNCTION rb64_index(roaringbitmap64, bigint) 166 | RETURNS bigint 167 | AS 'MODULE_PATHNAME', 'rb64_index' 168 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 169 | 170 | CREATE OR REPLACE FUNCTION rb64_cardinality(roaringbitmap64) 171 | RETURNS bigint 172 | AS 'MODULE_PATHNAME', 'rb64_cardinality' 173 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 174 | 175 | CREATE OR REPLACE FUNCTION rb64_and_cardinality(roaringbitmap64, roaringbitmap64) 176 | RETURNS bigint 177 | AS 'MODULE_PATHNAME', 'rb64_and_cardinality' 178 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 179 | 180 | CREATE OR REPLACE FUNCTION rb64_or_cardinality(roaringbitmap64, roaringbitmap64) 181 | RETURNS bigint 182 | AS 'MODULE_PATHNAME', 'rb64_or_cardinality' 183 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 184 | 185 | CREATE OR REPLACE FUNCTION rb64_xor_cardinality(roaringbitmap64, roaringbitmap64) 186 | RETURNS bigint 187 | AS 'MODULE_PATHNAME', 'rb64_xor_cardinality' 188 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 189 | 190 | CREATE OR REPLACE FUNCTION rb64_andnot_cardinality(roaringbitmap64, roaringbitmap64) 191 | RETURNS bigint 192 | AS 'MODULE_PATHNAME', 'rb64_andnot_cardinality' 193 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 194 | 195 | CREATE OR REPLACE FUNCTION rb64_is_empty(roaringbitmap64) 196 | RETURNS bool 197 | AS 'MODULE_PATHNAME', 'rb64_is_empty' 198 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 199 | 200 | CREATE OR REPLACE FUNCTION rb64_fill(roaringbitmap64, range_start bigint, range_end bigint) 201 | RETURNS roaringbitmap64 202 | AS 'MODULE_PATHNAME', 'rb64_fill' 203 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 204 | 205 | CREATE OR REPLACE FUNCTION rb64_clear(roaringbitmap64, range_start bigint, range_end bigint) 206 | RETURNS roaringbitmap64 207 | AS 'MODULE_PATHNAME', 'rb64_clear' 208 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 209 | 210 | CREATE OR REPLACE FUNCTION rb64_flip(roaringbitmap64, range_start bigint, range_end bigint) 211 | RETURNS roaringbitmap64 212 | AS 'MODULE_PATHNAME', 'rb64_flip' 213 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 214 | 215 | CREATE OR REPLACE FUNCTION rb64_range(roaringbitmap64, range_start bigint, range_end bigint) 216 | RETURNS roaringbitmap64 217 | AS 'MODULE_PATHNAME', 'rb64_range' 218 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 219 | 220 | CREATE OR REPLACE FUNCTION rb64_range_cardinality(roaringbitmap64, range_start bigint, range_end bigint) 221 | RETURNS bigint 222 | AS 'MODULE_PATHNAME', 'rb64_range_cardinality' 223 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 224 | 225 | CREATE OR REPLACE FUNCTION rb64_min(roaringbitmap64) 226 | RETURNS bigint 227 | AS 'MODULE_PATHNAME', 'rb64_min' 228 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 229 | 230 | CREATE OR REPLACE FUNCTION rb64_max(roaringbitmap64) 231 | RETURNS bigint 232 | AS 'MODULE_PATHNAME', 'rb64_max' 233 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 234 | 235 | CREATE OR REPLACE FUNCTION rb64_rank(roaringbitmap64, bigint) 236 | RETURNS bigint 237 | AS 'MODULE_PATHNAME', 'rb64_rank' 238 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 239 | 240 | CREATE OR REPLACE FUNCTION rb64_jaccard_dist(roaringbitmap64, roaringbitmap64) 241 | RETURNS float8 242 | AS 'MODULE_PATHNAME', 'rb64_jaccard_dist' 243 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 244 | 245 | CREATE OR REPLACE FUNCTION rb64_select(roaringbitmap64, bitset_limit bigint,bitset_offset bigint=0,reverse boolean=false,range_start bigint=0,range_end bigint=-1) 246 | RETURNS roaringbitmap64 247 | AS 'MODULE_PATHNAME', 'rb64_select' 248 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 249 | 250 | CREATE OR REPLACE FUNCTION rb64_to_array(roaringbitmap64) 251 | RETURNS bigint[] 252 | AS 'MODULE_PATHNAME', 'rb64_to_array' 253 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 254 | 255 | CREATE OR REPLACE FUNCTION rb64_iterate(roaringbitmap64) 256 | RETURNS SETOF bigint 257 | AS 'MODULE_PATHNAME', 'rb64_iterate' 258 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 259 | 260 | -- 261 | -- Operators 262 | -- 263 | 264 | CREATE OPERATOR & ( 265 | LEFTARG = roaringbitmap64, 266 | RIGHTARG = roaringbitmap64, 267 | PROCEDURE = rb64_and 268 | ); 269 | 270 | CREATE OPERATOR | ( 271 | LEFTARG = roaringbitmap64, 272 | RIGHTARG = roaringbitmap64, 273 | PROCEDURE = rb64_or 274 | ); 275 | 276 | CREATE OPERATOR | ( 277 | LEFTARG = roaringbitmap64, 278 | RIGHTARG = bigint, 279 | PROCEDURE = rb64_add 280 | ); 281 | 282 | CREATE OPERATOR | ( 283 | LEFTARG = bigint, 284 | RIGHTARG = roaringbitmap64, 285 | PROCEDURE = rb64_add 286 | ); 287 | 288 | CREATE OPERATOR # ( 289 | LEFTARG = roaringbitmap64, 290 | RIGHTARG = roaringbitmap64, 291 | PROCEDURE = rb64_xor 292 | ); 293 | 294 | CREATE OPERATOR << ( 295 | LEFTARG = roaringbitmap64, 296 | RIGHTARG = bigint, 297 | PROCEDURE = rb64_shiftleft 298 | ); 299 | 300 | CREATE OPERATOR >> ( 301 | LEFTARG = roaringbitmap64, 302 | RIGHTARG = bigint, 303 | PROCEDURE = rb64_shiftright 304 | ); 305 | 306 | CREATE OPERATOR - ( 307 | LEFTARG = roaringbitmap64, 308 | RIGHTARG = roaringbitmap64, 309 | PROCEDURE = rb64_andnot 310 | ); 311 | 312 | CREATE OPERATOR - ( 313 | LEFTARG = roaringbitmap64, 314 | RIGHTARG = bigint, 315 | PROCEDURE = rb64_remove 316 | ); 317 | 318 | CREATE OPERATOR @> ( 319 | LEFTARG = roaringbitmap64, 320 | RIGHTARG = roaringbitmap64, 321 | PROCEDURE = rb64_contains, 322 | COMMUTATOR = '<@', 323 | RESTRICT = contsel, 324 | JOIN = contjoinsel 325 | ); 326 | 327 | CREATE OPERATOR @> ( 328 | LEFTARG = roaringbitmap64, 329 | RIGHTARG = bigint, 330 | PROCEDURE = rb64_contains, 331 | COMMUTATOR = '<@', 332 | RESTRICT = contsel, 333 | JOIN = contjoinsel 334 | ); 335 | 336 | CREATE OPERATOR <@ ( 337 | LEFTARG = roaringbitmap64, 338 | RIGHTARG = roaringbitmap64, 339 | PROCEDURE = rb64_containedby, 340 | COMMUTATOR = '@>', 341 | RESTRICT = contsel, 342 | JOIN = contjoinsel 343 | ); 344 | 345 | CREATE OPERATOR <@ ( 346 | LEFTARG = bigint, 347 | RIGHTARG = roaringbitmap64, 348 | PROCEDURE = rb64_containedby, 349 | COMMUTATOR = '@>', 350 | RESTRICT = contsel, 351 | JOIN = contjoinsel 352 | ); 353 | 354 | CREATE OPERATOR && ( 355 | LEFTARG = roaringbitmap64, 356 | RIGHTARG = roaringbitmap64, 357 | PROCEDURE = rb64_intersect, 358 | COMMUTATOR = '&&', 359 | RESTRICT = contsel, 360 | JOIN = contjoinsel 361 | ); 362 | 363 | CREATE OPERATOR = ( 364 | LEFTARG = roaringbitmap64, 365 | RIGHTARG = roaringbitmap64, 366 | PROCEDURE = rb64_equals, 367 | COMMUTATOR = '=', 368 | NEGATOR = '<>', 369 | RESTRICT = eqsel, 370 | JOIN = eqjoinsel 371 | ); 372 | 373 | CREATE OPERATOR <> ( 374 | LEFTARG = roaringbitmap64, 375 | RIGHTARG = roaringbitmap64, 376 | PROCEDURE = rb64_not_equals, 377 | COMMUTATOR = '<>', 378 | NEGATOR = '=', 379 | RESTRICT = neqsel, 380 | JOIN = neqjoinsel 381 | ); 382 | 383 | -- 384 | -- Aggragations 385 | -- 386 | 387 | CREATE OR REPLACE FUNCTION rb64_final(internal) 388 | RETURNS roaringbitmap64 389 | AS 'MODULE_PATHNAME', 'rb64_serialize' 390 | LANGUAGE C IMMUTABLE PARALLEL SAFE; 391 | 392 | CREATE OR REPLACE FUNCTION rb64_serialize(internal) 393 | RETURNS bytea 394 | AS 'MODULE_PATHNAME', 'rb64_serialize' 395 | LANGUAGE C IMMUTABLE PARALLEL SAFE; 396 | 397 | CREATE OR REPLACE FUNCTION rb64_deserialize(bytea,internal) 398 | RETURNS internal 399 | AS 'MODULE_PATHNAME', 'rb64_deserialize' 400 | LANGUAGE C IMMUTABLE PARALLEL SAFE; 401 | 402 | CREATE OR REPLACE FUNCTION rb64_cardinality_final(internal) 403 | RETURNS bigint 404 | AS 'MODULE_PATHNAME', 'rb64_cardinality_final' 405 | LANGUAGE C IMMUTABLE PARALLEL SAFE; 406 | 407 | 408 | CREATE OR REPLACE FUNCTION rb64_or_trans(internal, roaringbitmap64) 409 | RETURNS internal 410 | AS 'MODULE_PATHNAME', 'rb64_or_trans' 411 | LANGUAGE C IMMUTABLE PARALLEL SAFE; 412 | 413 | CREATE OR REPLACE FUNCTION rb64_or_combine(internal, internal) 414 | RETURNS internal 415 | AS 'MODULE_PATHNAME', 'rb64_or_combine' 416 | LANGUAGE C IMMUTABLE PARALLEL SAFE; 417 | 418 | CREATE AGGREGATE rb64_or_agg(roaringbitmap64)( 419 | SFUNC = rb64_or_trans, 420 | STYPE = internal, 421 | FINALFUNC = rb64_final, 422 | COMBINEFUNC = rb64_or_combine, 423 | SERIALFUNC = rb64_serialize, 424 | DESERIALFUNC = rb64_deserialize, 425 | PARALLEL = SAFE 426 | ); 427 | 428 | CREATE AGGREGATE rb64_or_cardinality_agg(roaringbitmap64)( 429 | SFUNC = rb64_or_trans, 430 | STYPE = internal, 431 | FINALFUNC = rb64_cardinality_final, 432 | COMBINEFUNC = rb64_or_combine, 433 | SERIALFUNC = rb64_serialize, 434 | DESERIALFUNC = rb64_deserialize, 435 | PARALLEL = SAFE 436 | ); 437 | 438 | 439 | CREATE OR REPLACE FUNCTION rb64_and_trans(internal, roaringbitmap64) 440 | RETURNS internal 441 | AS 'MODULE_PATHNAME', 'rb64_and_trans' 442 | LANGUAGE C IMMUTABLE PARALLEL SAFE; 443 | 444 | CREATE OR REPLACE FUNCTION rb64_and_combine(internal, internal) 445 | RETURNS internal 446 | AS 'MODULE_PATHNAME', 'rb64_and_combine' 447 | LANGUAGE C IMMUTABLE PARALLEL SAFE; 448 | 449 | CREATE AGGREGATE rb64_and_agg(roaringbitmap64)( 450 | SFUNC = rb64_and_trans, 451 | STYPE = internal, 452 | FINALFUNC = rb64_final, 453 | COMBINEFUNC = rb64_and_combine, 454 | SERIALFUNC = rb64_serialize, 455 | DESERIALFUNC = rb64_deserialize, 456 | PARALLEL = SAFE 457 | ); 458 | 459 | 460 | CREATE AGGREGATE rb64_and_cardinality_agg(roaringbitmap64)( 461 | SFUNC = rb64_and_trans, 462 | STYPE = internal, 463 | FINALFUNC = rb64_cardinality_final, 464 | COMBINEFUNC = rb64_and_combine, 465 | SERIALFUNC = rb64_serialize, 466 | DESERIALFUNC = rb64_deserialize, 467 | PARALLEL = SAFE 468 | ); 469 | 470 | 471 | CREATE OR REPLACE FUNCTION rb64_xor_trans(internal, roaringbitmap64) 472 | RETURNS internal 473 | AS 'MODULE_PATHNAME', 'rb64_xor_trans' 474 | LANGUAGE C IMMUTABLE PARALLEL SAFE; 475 | 476 | CREATE OR REPLACE FUNCTION rb64_xor_combine(internal, internal) 477 | RETURNS internal 478 | AS 'MODULE_PATHNAME', 'rb64_xor_combine' 479 | LANGUAGE C IMMUTABLE PARALLEL SAFE; 480 | 481 | CREATE AGGREGATE rb64_xor_agg(roaringbitmap64)( 482 | SFUNC = rb64_xor_trans, 483 | STYPE = internal, 484 | FINALFUNC = rb64_final, 485 | COMBINEFUNC = rb64_xor_combine, 486 | SERIALFUNC = rb64_serialize, 487 | DESERIALFUNC = rb64_deserialize, 488 | PARALLEL = SAFE 489 | ); 490 | 491 | 492 | CREATE AGGREGATE rb64_xor_cardinality_agg(roaringbitmap64)( 493 | SFUNC = rb64_xor_trans, 494 | STYPE = internal, 495 | FINALFUNC = rb64_cardinality_final, 496 | COMBINEFUNC = rb64_xor_combine, 497 | SERIALFUNC = rb64_serialize, 498 | DESERIALFUNC = rb64_deserialize, 499 | PARALLEL = SAFE 500 | ); 501 | 502 | CREATE OR REPLACE FUNCTION rb64_build_trans(internal, bigint) 503 | RETURNS internal 504 | AS 'MODULE_PATHNAME', 'rb64_build_trans' 505 | LANGUAGE C IMMUTABLE PARALLEL SAFE; 506 | 507 | CREATE AGGREGATE rb64_build_agg(bigint)( 508 | SFUNC = rb64_build_trans, 509 | STYPE = internal, 510 | FINALFUNC = rb64_final, 511 | COMBINEFUNC = rb64_or_combine, 512 | SERIALFUNC = rb64_serialize, 513 | DESERIALFUNC = rb64_deserialize, 514 | PARALLEL = SAFE 515 | ); 516 | -------------------------------------------------------------------------------- /roaring64_buffer_reader.c: -------------------------------------------------------------------------------- 1 | /** 2 | * 64-bit roaring buffer reader, leveraging 32-bit roaring buffer reader for leaf bitmaps. 3 | */ 4 | 5 | #include "roaring64_buffer_reader.h" 6 | 7 | 8 | static inline uint32_t rb64_get_key_at_index(const roaring64_buffer_t *rb, uint32_t i) { 9 | return rb->keys[i]; 10 | } 11 | 12 | static inline const roaring_buffer_t *rb64_get_reader_at_index(const roaring64_buffer_t *rb, uint32_t i) { 13 | return rb->rb_readers[i]; 14 | } 15 | 16 | /** 17 | * Good old binary search. 18 | * Assumes that array is sorted, has logarithmic complexity. 19 | * if the result is x, then: 20 | * if ( x>0 ) you have array[x] = ikey 21 | * if ( x<0 ) then inserting ikey at position -x-1 in array (insuring that array[-x-1]=ikey) 22 | * keeps the array sorted. 23 | */ 24 | static inline int32_t rb64_keys_binary_search(const uint32_t *array, int32_t size, uint32_t key) { 25 | int32_t low = 0; 26 | int32_t high = size - 1; 27 | while (low <= high) { 28 | int32_t middleIndex = (low + high) >> 1; 29 | uint32_t middleValue = array[middleIndex]; 30 | if (middleValue < key) { 31 | low = middleIndex + 1; 32 | } else if (middleValue > key) { 33 | high = middleIndex - 1; 34 | } else { 35 | return middleIndex; 36 | } 37 | } 38 | return -(low + 1); 39 | } 40 | 41 | /** 42 | * Galloping search 43 | * Assumes that array is sorted, has logarithmic complexity. 44 | * if the result is x, then if x = length, you have that all values in array between pos and length 45 | * are smaller than min. 46 | * otherwise returns the first index x such that array[x] >= min. 47 | */ 48 | static inline int32_t rb64_keys_advance_until(const uint32_t *array, int32_t pos, int32_t length, uint32_t min) { 49 | int32_t lower = pos + 1; 50 | if ((lower >= length) || (array[lower] >= min)) { 51 | return lower; 52 | } 53 | int32_t spansize = 1; 54 | while ((lower + spansize < length) && (array[lower + spansize] < min)) { 55 | spansize <<= 1; 56 | } 57 | int32_t upper = (lower + spansize < length) ? lower + spansize : length - 1; 58 | if (array[upper] == min) { 59 | return upper; 60 | } 61 | if (array[upper] < min) { 62 | return length; 63 | } 64 | lower += (spansize >> 1); 65 | int32_t mid = 0; 66 | while (lower + 1 != upper) { 67 | mid = (lower + upper) >> 1; 68 | if (array[mid] == min) { 69 | return mid; 70 | } else if (array[mid] < min) { 71 | lower = mid; 72 | } else { 73 | upper = mid; 74 | } 75 | } 76 | return upper; 77 | } 78 | 79 | /** 80 | * Creates a new 64-bit roaring buffer reader (from a portable serialized 64-bit roaringbitmap buffer). 81 | * The caller is responsible for freeing the result. 82 | * Returns NULL if error occurred. 83 | */ 84 | roaring64_buffer_t *roaring64_buffer_create(const char *buf, size_t buf_len){ 85 | // https://github.com/RoaringBitmap/RoaringFormatSpec#extension-for-64-bit-implementations 86 | if (buf == NULL) { 87 | return NULL; 88 | } 89 | size_t read_bytes = 0; 90 | const char *cur = buf; 91 | 92 | // Read as uint64 the distinct number of "buckets", where a bucket is 93 | // defined as the most significant 32 bits of an element. 94 | uint64_t num_buckets; 95 | if (read_bytes + sizeof(num_buckets) > buf_len) { 96 | return NULL; 97 | } 98 | memcpy(&num_buckets, cur, sizeof(num_buckets)); 99 | cur += sizeof(num_buckets); 100 | read_bytes += sizeof(num_buckets); 101 | 102 | // Buckets should be 32 bits with 4 bits of zero padding. 103 | if (num_buckets > UINT32_MAX) { 104 | return NULL; 105 | } 106 | 107 | if(num_buckets == 0) { 108 | roaring64_buffer_t *ans = (roaring64_buffer_t *)roaring_malloc(sizeof(roaring64_buffer_t)); 109 | if(ans == NULL) 110 | return NULL; 111 | ans->buf = buf; 112 | ans->buf_len = read_bytes; 113 | ans->size = 0; 114 | ans->keys = NULL; 115 | ans->rb_readers = NULL; 116 | return ans; 117 | } 118 | 119 | uint32_t *keys = (uint32_t *)roaring_malloc(sizeof(uint32_t) * num_buckets); 120 | const roaring_buffer_t **rb_readers = (const roaring_buffer_t **)roaring_malloc(sizeof(roaring_buffer_t *) * num_buckets); 121 | if(keys == NULL || rb_readers == NULL){ 122 | if(keys) roaring_free(keys); 123 | if(rb_readers) roaring_free((void *)rb_readers); 124 | return NULL; 125 | } 126 | 127 | // Iterate through buckets ordered by increasing keys. 128 | int64_t previous_key = -1; 129 | for(uint64_t i = 0; i < num_buckets; ++i){ 130 | // Read as uint32 the most significant 32 bits of the bucket. 131 | if(read_bytes + sizeof(uint32_t) > buf_len){ 132 | roaring_free(keys); 133 | roaring_free((void *)rb_readers); 134 | return NULL; 135 | } 136 | uint32_t key; 137 | memcpy(&key, cur, sizeof(uint32_t)); 138 | cur += sizeof(uint32_t); 139 | read_bytes += sizeof(uint32_t); 140 | 141 | // High 32 bits must be strictly increasing. 142 | if (key <= previous_key) { 143 | roaring_free(keys); 144 | roaring_free((void *)rb_readers); 145 | return NULL; 146 | } 147 | previous_key = key; 148 | 149 | // Read the 32-bit Roaring bitmaps representing the least 150 | // significant bits of a set of elements. 151 | size_t remain = (size_t)(buf_len - read_bytes); 152 | roaring_buffer_t *rb_reader = roaring_buffer_create(cur, remain); 153 | if(rb_reader == NULL){ 154 | // Free previously created rb_readers before returning 155 | for(uint64_t j = 0; j < i; ++j){ 156 | if(rb_readers[j]) roaring_buffer_free(rb_readers[j]); 157 | } 158 | roaring_free(keys); 159 | roaring_free((void *)rb_readers); 160 | return NULL; 161 | } 162 | size_t rb_size = rb_reader->buf_len; 163 | // Check if the buffer size is valid 164 | if(rb_size > remain){ 165 | roaring_buffer_free(rb_reader); 166 | // Free previously created rb_readers before returning 167 | for(uint64_t j = 0; j < i; ++j){ 168 | if(rb_readers[j]) roaring_buffer_free(rb_readers[j]); 169 | } 170 | roaring_free(keys); 171 | roaring_free((void *)rb_readers); 172 | return NULL; 173 | } 174 | cur += rb_size; 175 | read_bytes += rb_size; 176 | 177 | keys[i] = key; 178 | rb_readers[i] = rb_reader; 179 | 180 | } 181 | 182 | roaring64_buffer_t *ans = (roaring64_buffer_t *)roaring_malloc(sizeof(roaring64_buffer_t)); 183 | if(ans == NULL){ 184 | // Free all created rb_readers before returning 185 | for(uint64_t i = 0; i < num_buckets; ++i){ 186 | if(rb_readers[i]) roaring_buffer_free(rb_readers[i]); 187 | } 188 | roaring_free(keys); 189 | roaring_free((void *)rb_readers); 190 | return NULL; 191 | } 192 | ans->buf = buf; 193 | ans->buf_len = read_bytes; 194 | ans->size = num_buckets; 195 | ans->keys = keys; 196 | ans->rb_readers = rb_readers; 197 | return ans; 198 | } 199 | 200 | /** 201 | * free 64-bit roaring buffer reader 202 | */ 203 | void roaring64_buffer_free(const roaring64_buffer_t *rb) { 204 | if(!rb) return; 205 | if(rb->rb_readers){ 206 | for(int i = 0; i < rb->size; ++i){ 207 | if(rb->rb_readers[i]) roaring_buffer_free(rb->rb_readers[i]); 208 | } 209 | roaring_free((void *)rb->rb_readers); 210 | } 211 | if(rb->keys) roaring_free((void *)rb->keys); 212 | roaring_free((void *)rb); 213 | } 214 | 215 | /** 216 | * Get the cardinality of the bitmap (number of elements). 217 | */ 218 | uint64_t roaring64_buffer_get_cardinality(const roaring64_buffer_t *rb) { 219 | uint64_t total = 0; 220 | for (int i = 0; i < rb->size; ++i) { 221 | total += roaring_buffer_get_cardinality(rb->rb_readers[i]); 222 | } 223 | return total; 224 | } 225 | 226 | /** 227 | * Check if value x is present 228 | * Return false if error occurred. 229 | */ 230 | bool roaring64_buffer_contains(const roaring64_buffer_t *rb, 231 | uint64_t val, 232 | bool *result) { 233 | uint32_t high = (uint32_t)(val >> 32); 234 | int32_t idx = rb64_keys_binary_search(rb->keys, rb->size, high); 235 | if(idx < 0){ 236 | *result = false; 237 | return true; 238 | } 239 | bool ans = false; 240 | bool ok = roaring_buffer_contains(rb64_get_reader_at_index(rb, idx), (uint32_t)(val & 0xFFFFFFFFu), &ans); 241 | if(!ok) 242 | return false; 243 | *result = ans; 244 | return true; 245 | } 246 | 247 | /** 248 | * Check if all the elements of ra1 are also in ra2. 249 | * Return false if error occurred. 250 | */ 251 | bool roaring64_buffer_is_subset(const roaring64_buffer_t *ra1, 252 | const roaring64_buffer_t *ra2, 253 | bool *result) { 254 | const int length1 = ra1->size, 255 | length2 = ra2->size; 256 | int pos1 = 0, pos2 = 0; 257 | while (pos1 < length1 && pos2 < length2) { 258 | const uint32_t s1 = rb64_get_key_at_index(ra1, pos1); 259 | const uint32_t s2 = rb64_get_key_at_index(ra2, pos2); 260 | if (s1 == s2) { 261 | const roaring_buffer_t *c1 = rb64_get_reader_at_index(ra1, pos1); 262 | if(c1 == NULL) 263 | return false; 264 | const roaring_buffer_t *c2 = rb64_get_reader_at_index(ra2, pos2); 265 | if(c2 == NULL) 266 | return false; 267 | bool subset = false; 268 | bool ok = roaring_buffer_is_subset(c1, c2, &subset); 269 | if(!ok) 270 | return false; 271 | if(!subset){ 272 | *result = false; 273 | return true; 274 | } 275 | ++pos1; ++pos2; 276 | } else if (s1 < s2) { 277 | *result = false; 278 | return true; 279 | } else { 280 | pos2 = rb64_keys_advance_until(ra2->keys, pos2, length2, s1); 281 | } 282 | } 283 | *result = (pos1 == length1); 284 | return true; 285 | } 286 | 287 | /** 288 | * Computes the intersection between two bitmaps. 289 | * Return false if error occurred. 290 | */ 291 | bool roaring64_buffer_and_cardinality(const roaring64_buffer_t *x1, 292 | const roaring64_buffer_t *x2, 293 | uint64_t *result) { 294 | const int length1 = x1->size, 295 | length2 = x2->size; 296 | uint64_t cardinality = 0; 297 | int pos1 = 0, pos2 = 0; 298 | while (pos1 < length1 && pos2 < length2) { 299 | const uint32_t s1 = rb64_get_key_at_index(x1, pos1); 300 | const uint32_t s2 = rb64_get_key_at_index(x2, pos2); 301 | if (s1 == s2) { 302 | const roaring_buffer_t *c1 = rb64_get_reader_at_index(x1, pos1); 303 | if(c1 == NULL) 304 | return false; 305 | const roaring_buffer_t *c2 = rb64_get_reader_at_index(x2, pos2); 306 | if(c2 == NULL) 307 | return false; 308 | uint64_t card = 0; 309 | bool ok = roaring_buffer_and_cardinality(c1, c2, &card); 310 | if(!ok) 311 | return false; 312 | cardinality += card; 313 | ++pos1; ++pos2; 314 | } else if (s1 < s2) { 315 | pos1 = rb64_keys_advance_until(x1->keys, pos1, length1, s2); 316 | } else { 317 | pos2 = rb64_keys_advance_until(x2->keys, pos2, length2, s1); 318 | } 319 | } 320 | *result = cardinality; 321 | return true; 322 | } 323 | 324 | /** 325 | * Computes the size of the union between two bitmaps. 326 | * Return false if error occurred. 327 | */ 328 | bool roaring64_buffer_or_cardinality(const roaring64_buffer_t *x1, 329 | const roaring64_buffer_t *x2, 330 | uint64_t *result) { 331 | bool ok; 332 | uint64_t inter; 333 | const uint64_t c1 = roaring64_buffer_get_cardinality(x1); 334 | const uint64_t c2 = roaring64_buffer_get_cardinality(x2); 335 | ok = roaring64_buffer_and_cardinality(x1, x2, &inter); 336 | if(!ok) 337 | return false; 338 | *result = c1 + c2 - inter; 339 | return true; 340 | } 341 | 342 | /** 343 | * Computes the size of the difference (andnot) between two bitmaps. 344 | * Return false if error occurred. 345 | */ 346 | bool roaring64_buffer_andnot_cardinality(const roaring64_buffer_t *x1, 347 | const roaring64_buffer_t *x2, 348 | uint64_t *result) { 349 | bool ok; 350 | uint64_t inter; 351 | const uint64_t c1 = roaring64_buffer_get_cardinality(x1); 352 | ok = roaring64_buffer_and_cardinality(x1, x2, &inter); 353 | if(!ok) 354 | return false; 355 | *result = c1 - inter; 356 | return true; 357 | } 358 | 359 | /** 360 | * Computes the size of the symmetric difference between two bitmaps. 361 | * Return false if error occurred. 362 | */ 363 | bool roaring64_buffer_xor_cardinality(const roaring64_buffer_t *x1, 364 | const roaring64_buffer_t *x2, 365 | uint64_t *result) { 366 | bool ok; 367 | uint64_t inter; 368 | const uint64_t c1 = roaring64_buffer_get_cardinality(x1); 369 | const uint64_t c2 = roaring64_buffer_get_cardinality(x2); 370 | ok = roaring64_buffer_and_cardinality(x1, x2, &inter); 371 | if(!ok) 372 | return false; 373 | *result = c1 + c2 - 2 * inter; 374 | return true; 375 | } 376 | 377 | /** 378 | * Computes the Jaccard index between two bitmaps. 379 | * Return false if error occurred. 380 | */ 381 | bool roaring64_buffer_jaccard_index(const roaring64_buffer_t *x1, 382 | const roaring64_buffer_t *x2, 383 | double *result) { 384 | bool ok; 385 | uint64_t inter; 386 | const uint64_t c1 = roaring64_buffer_get_cardinality(x1); 387 | const uint64_t c2 = roaring64_buffer_get_cardinality(x2); 388 | ok = roaring64_buffer_and_cardinality(x1, x2, &inter); 389 | if(!ok) 390 | return false; 391 | *result = (double)inter / (double)(c1 + c2 - inter); 392 | return true; 393 | } 394 | 395 | /** 396 | * Check whether two bitmaps intersect. 397 | * Return false if error occurred. 398 | */ 399 | bool roaring64_buffer_intersect(const roaring64_buffer_t *x1, 400 | const roaring64_buffer_t *x2, 401 | bool *result) { 402 | const int length1 = x1->size, 403 | length2 = x2->size; 404 | int pos1 = 0, pos2 = 0; 405 | while (pos1 < length1 && pos2 < length2) { 406 | const uint32_t s1 = rb64_get_key_at_index(x1, pos1); 407 | const uint32_t s2 = rb64_get_key_at_index(x2, pos2); 408 | if (s1 == s2) { 409 | const roaring_buffer_t *c1 = rb64_get_reader_at_index(x1, pos1); 410 | if(c1 == NULL) 411 | return false; 412 | const roaring_buffer_t *c2 = rb64_get_reader_at_index(x2, pos2); 413 | if(c2 == NULL) 414 | return false; 415 | bool intersect = false; 416 | bool ok = roaring_buffer_intersect(c1, c2, &intersect); 417 | if(!ok) 418 | return false; 419 | if(intersect){ 420 | *result = true; 421 | return true; 422 | } 423 | ++pos1; ++pos2; 424 | } else if (s1 < s2) { 425 | pos1 = rb64_keys_advance_until(x1->keys, pos1, length1, s2); 426 | } else { 427 | pos2 = rb64_keys_advance_until(x2->keys, pos2, length2, s1); 428 | } 429 | } 430 | *result = false; 431 | return true; 432 | } 433 | 434 | /** 435 | * Returns true if the bitmap is empty (cardinality is zero). 436 | */ 437 | bool roaring64_buffer_is_empty(const roaring64_buffer_t *rb) { 438 | return rb->size == 0; 439 | } 440 | 441 | /** 442 | * Check if the two bitmaps contain the same elements. 443 | * Return false if error occurred. 444 | */ 445 | bool roaring64_buffer_equals(const roaring64_buffer_t *rb1, 446 | const roaring64_buffer_t *rb2, 447 | bool *result) { 448 | if (rb1->size != rb2->size) { *result = false; return true; } 449 | for (int i = 0; i < rb1->size; ++i) { 450 | if (rb64_get_key_at_index(rb1, i) != rb64_get_key_at_index(rb2, i)) { 451 | *result = false; 452 | return true; 453 | } 454 | } 455 | for (int i = 0; i < rb1->size; ++i) { 456 | const roaring_buffer_t *c1 = rb64_get_reader_at_index(rb1, i); 457 | if(c1 == NULL) 458 | return false; 459 | const roaring_buffer_t *c2 = rb64_get_reader_at_index(rb2, i); 460 | if(c2 == NULL) 461 | return false; 462 | bool areequal = false; 463 | bool ok = roaring_buffer_equals(c1, c2, &areequal); 464 | if(!ok) 465 | return false; 466 | if (!areequal) { 467 | *result = false; 468 | return true; 469 | } 470 | } 471 | *result = true; 472 | return true; 473 | } 474 | 475 | /** 476 | * Count the number of integers that are smaller or equal to x. 477 | * Return false if error occurred. 478 | */ 479 | bool roaring64_buffer_rank(const roaring64_buffer_t *rb, 480 | uint64_t x, 481 | uint64_t *result) { 482 | uint32_t xhigh = (uint32_t)(x >> 32); 483 | *result = 0; 484 | for (int i = 0; i < rb->size; i++) { 485 | uint32_t key = rb64_get_key_at_index(rb, i); 486 | if (xhigh < key) 487 | return true; 488 | const roaring_buffer_t *c = rb64_get_reader_at_index(rb, (uint32_t)i); 489 | if(c == NULL) 490 | return false; 491 | if (xhigh == key) { 492 | uint64_t r = 0; 493 | bool ok = roaring_buffer_rank(c, (uint32_t)(x & 0xFFFFFFFFu), &r); 494 | if(!ok) 495 | return false; 496 | *result += r; 497 | return true; 498 | } else { 499 | *result += roaring_buffer_get_cardinality(c); 500 | } 501 | } 502 | return true; 503 | } 504 | 505 | /** 506 | * Get the smallest value in the set, or UINT64_MAX if the set is empty. 507 | * Return false if error occurred. 508 | */ 509 | bool roaring64_buffer_minimum(const roaring64_buffer_t *rb, 510 | uint64_t *result) { 511 | if (rb->size > 0) { 512 | const roaring_buffer_t *c = rb64_get_reader_at_index(rb, 0); 513 | if(c == NULL) 514 | return false; 515 | uint32_t low = 0; 516 | bool ok = roaring_buffer_minimum(c, &low); 517 | if(!ok) 518 | return false; 519 | *result = (((uint64_t)rb64_get_key_at_index(rb, 0)) << 32) | (uint64_t)low; 520 | } else { 521 | *result = UINT64_MAX; 522 | } 523 | return true; 524 | } 525 | 526 | /** 527 | * Get the greatest value in the set, or 0 if the set is empty. 528 | * Return false if error occurred. 529 | */ 530 | bool roaring64_buffer_maximum(const roaring64_buffer_t *rb, 531 | uint64_t *result) { 532 | if (rb->size > 0) { 533 | int i = rb->size - 1; 534 | const roaring_buffer_t *c = rb64_get_reader_at_index(rb, (uint32_t)i); 535 | if(c == NULL) 536 | return false; 537 | uint32_t low = 0; 538 | bool ok = roaring_buffer_maximum(c, &low); 539 | if(!ok) 540 | return false; 541 | *result = (((uint64_t)rb64_get_key_at_index(rb, i)) << 32) | (uint64_t)low; 542 | } else { 543 | *result = 0; 544 | } 545 | return true; 546 | } 547 | 548 | 549 | -------------------------------------------------------------------------------- /sql/roaringbitmap.sql: -------------------------------------------------------------------------------- 1 | -- 2 | -- Test roaringbitmap extension 3 | -- 4 | 5 | set client_min_messages = 'warning'; 6 | CREATE EXTENSION if not exists roaringbitmap; 7 | 8 | -- Test input and output 9 | 10 | set roaringbitmap.output_format='array'; 11 | set extra_float_digits = 0; 12 | 13 | select '{}'::roaringbitmap; 14 | select ' { } '::roaringbitmap; 15 | select '{ 1 }'::roaringbitmap; 16 | select '{-1,2,555555,-4}'::roaringbitmap; 17 | select '{ -1 , 2 , 555555 , -4 }'::roaringbitmap; 18 | select '{ 1 , -2 , 555555 , -4 }'::roaringbitmap; 19 | select '{ 1 , -2 , 555555 , -4 ,2147483647,-2147483648}'::roaringbitmap; 20 | select roaringbitmap('{ 1 , -2 , 555555 , -4 }'); 21 | 22 | set roaringbitmap.output_format='bytea'; 23 | select '{}'::roaringbitmap; 24 | select '{ -1 , 2 , 555555 , -4 }'::roaringbitmap; 25 | 26 | set roaringbitmap.output_format='array'; 27 | select '{}'::roaringbitmap; 28 | select '\x3a30000000000000'::roaringbitmap; 29 | select '\x3a300000030000000000000008000000ffff01002000000022000000240000000200237afcffffff'::roaringbitmap; 30 | 31 | -- Exception 32 | select ''::roaringbitmap; 33 | select '{'::roaringbitmap; 34 | select '{1'::roaringbitmap; 35 | select '{1} x'::roaringbitmap; 36 | select '{1x}'::roaringbitmap; 37 | select '{-x}'::roaringbitmap; 38 | select '{,}'::roaringbitmap; 39 | select '{1,}'::roaringbitmap; 40 | select '{1,xxx}'::roaringbitmap; 41 | select '{1,3'::roaringbitmap; 42 | select '{1,1'::roaringbitmap; 43 | select '{1,-2147483649}'::roaringbitmap; 44 | select '{2147483648}'::roaringbitmap; 45 | 46 | -- Test Type cast 47 | select '{}'::roaringbitmap::bytea; 48 | select '{1}'::roaringbitmap::bytea; 49 | select '{1,9999}'::roaringbitmap::bytea; 50 | select '{}'::roaringbitmap::bytea::roaringbitmap; 51 | select '{1}'::roaringbitmap::bytea::roaringbitmap; 52 | select '{1,9999,-88888}'::roaringbitmap::bytea::roaringbitmap; 53 | select roaringbitmap('{1,9999,-88888}'::roaringbitmap::bytea); 54 | 55 | -- Exception 56 | select roaringbitmap('\x11'::bytea); 57 | select '\x11'::bytea::roaringbitmap; 58 | 59 | -- Test Operator 60 | 61 | select roaringbitmap('{}') & roaringbitmap('{}'); 62 | select roaringbitmap('{}') & roaringbitmap('{3,4,5}'); 63 | select roaringbitmap('{1,2,3}') & roaringbitmap('{}'); 64 | select roaringbitmap('{1,2,3}') & roaringbitmap('{3,4,5}'); 65 | select roaringbitmap('{1,-2,-3}') & roaringbitmap('{-3,-4,5}'); 66 | 67 | select roaringbitmap('{}') | roaringbitmap('{}'); 68 | select roaringbitmap('{}') | roaringbitmap('{3,4,5}'); 69 | select roaringbitmap('{1,2,3}') | roaringbitmap('{}'); 70 | select roaringbitmap('{1,2,3}') | roaringbitmap('{3,4,5}'); 71 | select roaringbitmap('{1,-2,-3}') | roaringbitmap('{-3,-4,5}'); 72 | 73 | select roaringbitmap('{}') | 6; 74 | select roaringbitmap('{1,2,3}') | 6; 75 | select roaringbitmap('{1,2,3}') | 1; 76 | select roaringbitmap('{1,2,3}') | -1; 77 | select roaringbitmap('{-1,-2,3}') | -1; 78 | 79 | select 6 | roaringbitmap('{}'); 80 | select 6 | roaringbitmap('{1,2,3}'); 81 | select 1 | roaringbitmap('{1,2,3}'); 82 | select -1 | roaringbitmap('{1,2,3}'); 83 | select -1 | roaringbitmap('{-1,-2,3}'); 84 | 85 | select roaringbitmap('{}') # roaringbitmap('{}'); 86 | select roaringbitmap('{}') # roaringbitmap('{3,4,5}'); 87 | select roaringbitmap('{1,2,3}') # roaringbitmap('{}'); 88 | select roaringbitmap('{1,2,3}') # roaringbitmap('{3,4,5}'); 89 | select roaringbitmap('{1,-2,-3}') # roaringbitmap('{-3,-4,5}'); 90 | 91 | select roaringbitmap('{}') - roaringbitmap('{}'); 92 | select roaringbitmap('{}') - roaringbitmap('{3,4,5}'); 93 | select roaringbitmap('{1,2,3}') - roaringbitmap('{}'); 94 | select roaringbitmap('{1,2,3}') - roaringbitmap('{3,4,5}'); 95 | select roaringbitmap('{1,-2,-3}') - roaringbitmap('{-3,-4,5}'); 96 | 97 | select roaringbitmap('{}') - 3; 98 | select roaringbitmap('{1,2,3}') - 3; 99 | select roaringbitmap('{1,2,3}') - 1; 100 | select roaringbitmap('{1,2,3}') - -1; 101 | select roaringbitmap('{-1,-2,3}') - -1; 102 | 103 | select roaringbitmap('{}') << 2; 104 | select roaringbitmap('{-2,-1,0,1,2,3,2147483647,-2147483648}') << 2; 105 | select roaringbitmap('{-2,-1,0,1,2,3,2147483647,-2147483648}') << 1; 106 | select roaringbitmap('{-2,-1,0,1,2,3,2147483647,-2147483648}') << 0; 107 | select roaringbitmap('{-2,-1,0,1,2,3,2147483647,-2147483648}') << -1; 108 | select roaringbitmap('{-2,-1,0,1,2,3,2147483647,-2147483648}') << -2; 109 | select roaringbitmap('{-2,-1,0,1,2,3,2147483647,-2147483648}') << 4294967295; 110 | select roaringbitmap('{-2,-1,0,1,2,3,2147483647,-2147483648}') << 4294967296; 111 | select roaringbitmap('{-2,-1,0,1,2,3,2147483647,-2147483648}') << -4294967295; 112 | select roaringbitmap('{-2,-1,0,1,2,3,2147483647,-2147483648}') << -4294967296; 113 | 114 | select roaringbitmap('{}') >> 2; 115 | select roaringbitmap('{-2,-1,0,1,2,3,2147483647,-2147483648}') >> 2; 116 | select roaringbitmap('{-2,-1,0,1,2,3,2147483647,-2147483648}') >> 1; 117 | select roaringbitmap('{-2,-1,0,1,2,3,2147483647,-2147483648}') >> 0; 118 | select roaringbitmap('{-2,-1,0,1,2,3,2147483647,-2147483648}') >> -1; 119 | select roaringbitmap('{-2,-1,0,1,2,3,2147483647,-2147483648}') >> -2; 120 | select roaringbitmap('{-2,-1,0,1,2,3,2147483647,-2147483648}') >> 4294967295; 121 | select roaringbitmap('{-2,-1,0,1,2,3,2147483647,-2147483648}') >> 4294967296; 122 | select roaringbitmap('{-2,-1,0,1,2,3,2147483647,-2147483648}') >> -4294967295; 123 | select roaringbitmap('{-2,-1,0,1,2,3,2147483647,-2147483648}') >> -4294967296; 124 | 125 | select roaringbitmap('{}') @> roaringbitmap('{}'); 126 | select roaringbitmap('{}') @> roaringbitmap('{3,4,5}'); 127 | select roaringbitmap('{1,2,3}') @> roaringbitmap('{}'); 128 | select roaringbitmap('{1,2,3}') @> roaringbitmap('{3,4,5}'); 129 | select roaringbitmap('{1,2,3}') @> roaringbitmap('{3,2}'); 130 | select roaringbitmap('{1,-2,-3}') @> roaringbitmap('{-3,1}'); 131 | 132 | select roaringbitmap('{}') @> 2; 133 | select roaringbitmap('{1,2,3}') @> 20; 134 | select roaringbitmap('{1,2,3}') @> 1; 135 | select roaringbitmap('{1,2,3}') @> -1; 136 | select roaringbitmap('{-1,-2,3}') @> -1; 137 | 138 | select roaringbitmap('{}') <@ roaringbitmap('{}'); 139 | select roaringbitmap('{}') <@ roaringbitmap('{3,4,5}'); 140 | select roaringbitmap('{1,2,3}') <@ roaringbitmap('{}'); 141 | select roaringbitmap('{1,2,3}') <@ roaringbitmap('{3,4,5}'); 142 | select roaringbitmap('{2,3}') <@ roaringbitmap('{1,3,2}'); 143 | select roaringbitmap('{1,-3}') <@ roaringbitmap('{-3,1,1000}'); 144 | 145 | select 6 <@ roaringbitmap('{}'); 146 | select 3 <@ roaringbitmap('{1,2,3}'); 147 | select 1 <@ roaringbitmap('{1,2,3}'); 148 | select -1 <@ roaringbitmap('{1,2,3}'); 149 | select -1 <@ roaringbitmap('{-1,-2,3}'); 150 | 151 | select roaringbitmap('{}') && roaringbitmap('{}'); 152 | select roaringbitmap('{}') && roaringbitmap('{3,4,5}'); 153 | select roaringbitmap('{1,2,3}') && roaringbitmap('{}'); 154 | select roaringbitmap('{1,2,3}') && roaringbitmap('{3,4,5}'); 155 | select roaringbitmap('{1,-2,-3}') && roaringbitmap('{-3,-4,5}'); 156 | 157 | select roaringbitmap('{}') = roaringbitmap('{}'); 158 | select roaringbitmap('{}') = roaringbitmap('{3,4,5}'); 159 | select roaringbitmap('{1,2,3}') = roaringbitmap('{}'); 160 | select roaringbitmap('{1,2,3}') = roaringbitmap('{3,1,2}'); 161 | select roaringbitmap('{1,-2,-3}') = roaringbitmap('{-3,-4,5}'); 162 | 163 | select roaringbitmap('{}') <> roaringbitmap('{}'); 164 | select roaringbitmap('{}') <> roaringbitmap('{3,4,5}'); 165 | select roaringbitmap('{1,2,3}') <> roaringbitmap('{}'); 166 | select roaringbitmap('{1,2,3}') <> roaringbitmap('{3,1,2}'); 167 | select roaringbitmap('{1,-2,-3}') <> roaringbitmap('{-3,-4,5}'); 168 | 169 | -- Test the functions with one bitmap variable 170 | 171 | select rb_build(NULL); 172 | select rb_build('{}'::int[]); 173 | select rb_build('{1}'::int[]); 174 | select rb_build('{-1,2,555555,-4}'::int[]); 175 | select rb_build('{1,-2,555555,-4,2147483647,-2147483648}'::int[]); 176 | 177 | select rb_to_array(NULL); 178 | select rb_to_array('{}'::roaringbitmap); 179 | select rb_to_array('{1}'::roaringbitmap); 180 | select rb_to_array('{-1,2,555555,-4}'::roaringbitmap); 181 | select rb_to_array('{1,-2,555555,-4,2147483647,-2147483648}'::roaringbitmap); 182 | 183 | select rb_is_empty(NULL); 184 | select rb_is_empty('{}'); 185 | select rb_is_empty('{1}'); 186 | select rb_is_empty('{1,10,100}'); 187 | 188 | select rb_cardinality(NULL); 189 | select rb_cardinality('{}'); 190 | select rb_cardinality('{1}'); 191 | select rb_cardinality('{1,10,100}'); 192 | 193 | select rb_max(NULL); 194 | select rb_max('{}'); 195 | select rb_max('{1}'); 196 | select rb_max('{1,10,100}'); 197 | select rb_max('{1,10,100,2147483647,-2147483648,-1}'); 198 | 199 | select rb_min(NULL); 200 | select rb_min('{}'); 201 | select rb_min('{1}'); 202 | select rb_min('{1,10,100}'); 203 | select rb_min('{1,10,100,2147483647,-2147483648,-1}'); 204 | 205 | select rb_iterate(NULL); 206 | select rb_iterate('{}'); 207 | select rb_iterate('{1}'); 208 | select rb_iterate('{1,10,100}'); 209 | select rb_iterate('{1,10,100,2147483647,-2147483648,-1}'); 210 | 211 | select rb_runoptimize(NULL); 212 | select rb_runoptimize('{}'); 213 | select rb_runoptimize('{1}'); 214 | select rb_runoptimize('{1,10,100}'); 215 | select rb_runoptimize('{1,10,100,2147483647,-2147483648,-1}'); 216 | 217 | -- Test the functions with two bitmap variables 218 | 219 | select rb_and(NULL,'{1,10,100}'); 220 | select rb_and('{1,10,100}',NULL); 221 | select rb_and('{}','{1,10,100}'); 222 | select rb_and('{1,10,100}','{}'); 223 | select rb_and('{2}','{1,10,100}'); 224 | select rb_and('{1,2,10}','{1,10,100}'); 225 | select rb_and('{1,10}','{1,10,100}'); 226 | 227 | select rb_and_cardinality(NULL,'{1,10,100}'); 228 | select rb_and_cardinality('{1,10,100}',NULL); 229 | select rb_and_cardinality('{}','{1,10,100}'); 230 | select rb_and_cardinality('{1,10,100}','{}'); 231 | select rb_and_cardinality('{2}','{1,10,100}'); 232 | select rb_and_cardinality('{1,2,10}','{1,10,100}'); 233 | select rb_and_cardinality('{1,10}','{1,10,100}'); 234 | 235 | select rb_or(NULL,'{1,10,100}'); 236 | select rb_or('{1,10,100}',NULL); 237 | select rb_or('{}','{1,10,100}'); 238 | select rb_or('{1,10,100}','{}'); 239 | select rb_or('{2}','{1,10,100}'); 240 | select rb_or('{1,2,10}','{1,10,100}'); 241 | select rb_or('{1,10}','{1,10,100}'); 242 | 243 | select rb_or_cardinality(NULL,'{1,10,100}'); 244 | select rb_or_cardinality('{1,10,100}',NULL); 245 | select rb_or_cardinality('{}','{1,10,100}'); 246 | select rb_or_cardinality('{1,10,100}','{}'); 247 | select rb_or_cardinality('{2}','{1,10,100}'); 248 | select rb_or_cardinality('{1,2,10}','{1,10,100}'); 249 | select rb_or_cardinality('{1,10}','{1,10,100}'); 250 | 251 | select rb_xor(NULL,'{1,10,100}'); 252 | select rb_xor('{1,10,100}',NULL); 253 | select rb_xor('{}','{1,10,100}'); 254 | select rb_xor('{1,10,100}','{}'); 255 | select rb_xor('{2}','{1,10,100}'); 256 | select rb_xor('{1,2,10}','{1,10,100}'); 257 | select rb_xor('{1,10}','{1,10,100}'); 258 | 259 | select rb_xor_cardinality(NULL,'{1,10,100}'); 260 | select rb_xor_cardinality('{1,10,100}',NULL); 261 | select rb_xor_cardinality('{}','{1,10,100}'); 262 | select rb_xor_cardinality('{1,10,100}','{}'); 263 | select rb_xor_cardinality('{2}','{1,10,100}'); 264 | select rb_xor_cardinality('{1,2,10}','{1,10,100}'); 265 | select rb_xor_cardinality('{1,10}','{1,10,100}'); 266 | 267 | select rb_equals(NULL,'{1,10,100}'); 268 | select rb_equals('{1,10,100}',NULL); 269 | select rb_equals('{}','{1,10,100}'); 270 | select rb_equals('{1,10,100}','{}'); 271 | select rb_equals('{2}','{1,10,100}'); 272 | select rb_equals('{1,2,10}','{1,10,100}'); 273 | select rb_equals('{1,10}','{1,10,100}'); 274 | select rb_equals('{1,10,100}','{1,10,100}'); 275 | select rb_equals('{1,10,100,10}','{1,100,10}'); 276 | 277 | select rb_intersect(NULL,'{1,10,100}'); 278 | select rb_intersect('{1,10,100}',NULL); 279 | select rb_intersect('{}','{1,10,100}'); 280 | select rb_intersect('{1,10,100}','{}'); 281 | select rb_intersect('{2}','{1,10,100}'); 282 | select rb_intersect('{1,2,10}','{1,10,100}'); 283 | select rb_intersect('{1,10}','{1,10,100}'); 284 | select rb_intersect('{1,10,100}','{1,10,100}'); 285 | select rb_intersect('{1,10,100,10}','{1,100,10}'); 286 | 287 | select rb_andnot(NULL,'{1,10,100}'); 288 | select rb_andnot('{1,10,100}',NULL); 289 | select rb_andnot('{}','{1,10,100}'); 290 | select rb_andnot('{1,10,100}','{}'); 291 | select rb_andnot('{2}','{1,10,100}'); 292 | select rb_andnot('{1,2,10}','{1,10,100}'); 293 | select rb_andnot('{1,10}','{1,10,100}'); 294 | select rb_andnot('{1,10,100}','{1,10,100}'); 295 | select rb_andnot('{1,10,100,10}','{1,100,10}'); 296 | 297 | select rb_andnot_cardinality(NULL,'{1,10,100}'); 298 | select rb_andnot_cardinality('{1,10,100}',NULL); 299 | select rb_andnot_cardinality('{}','{1,10,100}'); 300 | select rb_andnot_cardinality('{1,10,100}','{}'); 301 | select rb_andnot_cardinality('{2}','{1,10,100}'); 302 | select rb_andnot_cardinality('{1,2,10}','{1,10,100}'); 303 | select rb_andnot_cardinality('{1,10}','{1,10,100}'); 304 | select rb_andnot_cardinality('{1,10,100}','{1,10,100}'); 305 | select rb_andnot_cardinality('{1,10,100,10}','{1,100,10}'); 306 | 307 | select rb_jaccard_dist(NULL,'{1,10,100}'); 308 | select rb_jaccard_dist('{1,10,100}',NULL); 309 | select rb_jaccard_dist('{}','{1,10,100}'); 310 | select rb_jaccard_dist('{1,10,100}','{}'); 311 | select rb_jaccard_dist('{2}','{1,10,100}'); 312 | select rb_jaccard_dist('{1,2,10}','{1,10,100}'); 313 | select rb_jaccard_dist('{1,10,11,12}','{1,10,100}'); 314 | select rb_jaccard_dist('{1,10,100}','{1,10,11,12}'); 315 | select rb_jaccard_dist('{1,10,100}','{1,10,100}'); 316 | select rb_jaccard_dist('{1,10,-100}','{1,10,-100}'); 317 | select rb_jaccard_dist('{1,10,100}','{1,10,-100}'); 318 | 319 | -- Test other functions 320 | 321 | select rb_rank(NULL,0); 322 | select rb_rank('{}',0); 323 | select rb_rank('{1,10,100}',0); 324 | select rb_rank('{1,10,100}',1); 325 | select rb_rank('{1,10,100}',99); 326 | select rb_rank('{1,10,100}',100); 327 | select rb_rank('{1,10,100}',101); 328 | select rb_rank('{1,10,100,-3,-1}',-2); 329 | 330 | select rb_remove(NULL,0); 331 | select rb_remove('{}',0); 332 | select rb_remove('{1}',1); 333 | select rb_remove('{1,10,100}',0); 334 | select rb_remove('{1,10,100}',1); 335 | select rb_remove('{1,10,100}',99); 336 | 337 | select rb_fill(NULL,0,0); 338 | select rb_fill('{}',0,0); 339 | select rb_fill('{}',0,1); 340 | select rb_fill('{}',0,2); 341 | select rb_fill('{1,10,100}',10,10); 342 | select rb_fill('{1,10,100}',10,11); 343 | select rb_fill('{1,10,100}',10,12); 344 | select rb_fill('{1,10,100}',10,13); 345 | select rb_fill('{1,10,100}',10,20); 346 | select rb_fill('{1,10,100}',0,-1); 347 | select rb_cardinality(rb_fill('{1,10,100}',2,1000000000)); 348 | select rb_cardinality(rb_fill('{1,10,100}',-1,5000000000)); 349 | 350 | select rb_index(NULL,3); 351 | select rb_index('{1,2,3}',NULL); 352 | select rb_index('{}',3); 353 | select rb_index('{1}',3); 354 | select rb_index('{1}',1); 355 | select rb_index('{1,10,100}',10); 356 | select rb_index('{1,10,100}',99); 357 | select rb_index('{1,10,-100}',-100); 358 | 359 | select rb_clear(NULL,0,10); 360 | select rb_clear('{}',0,10); 361 | select rb_clear('{1,10,100}',0,10); 362 | select rb_clear('{1,10,100}',3,3); 363 | select rb_clear('{1,10,100}',-3,3); 364 | select rb_clear('{1,10,100}',0,-1); 365 | select rb_clear('{1,10,100}',9,9); 366 | select rb_clear('{1,10,100}',2,1000000000); 367 | select rb_clear('{0,1,10,100,-2,-1}',1,4294967295); 368 | select rb_clear('{0,1,10,100,-2,-1}',0,4294967296); 369 | 370 | select rb_flip(NULL,0,10); 371 | select rb_flip('{}',0,10); 372 | select rb_flip('{1,10,100}',9,100); 373 | select rb_flip('{1,10,100}',10,101); 374 | select rb_flip('{1,10,100}',-3,3); 375 | select rb_flip('{1,10,100}',0,-1); 376 | select rb_flip('{1,10,100}',9,9); 377 | select rb_cardinality(rb_flip('{1,10,100}',2,1000000000)); 378 | select rb_cardinality(rb_flip('{1,10,100}',-1,5000000000)); 379 | 380 | select rb_range(NULL,0,10); 381 | select rb_range('{}',0,10); 382 | select rb_range('{1,10,100}',0,10); 383 | select rb_range('{1,10,100}',3,3); 384 | select rb_range('{1,10,100}',-3,3); 385 | select rb_range('{1,10,100}',0,-1); 386 | select rb_range('{1,10,100}',9,9); 387 | select rb_range('{1,10,100}',2,1000000000); 388 | select rb_range('{0,1,10,100,-2,-1}',1,4294967295); 389 | select rb_range('{0,1,10,100,-2,-1}',0,4294967296); 390 | 391 | select rb_range_cardinality(NULL,0,10); 392 | select rb_range_cardinality('{}',0,10); 393 | select rb_range_cardinality('{1,10,100}',0,10); 394 | select rb_range_cardinality('{1,10,100}',3,3); 395 | select rb_range_cardinality('{1,10,100}',-3,3); 396 | select rb_range_cardinality('{1,10,100}',0,-1); 397 | select rb_range_cardinality('{1,10,100}',9,9); 398 | select rb_range_cardinality('{1,10,100}',2,1000000000); 399 | select rb_range_cardinality('{0,1,10,100,-2,-1}',1,4294967295); 400 | select rb_range_cardinality('{0,1,10,100,-2,-1}',0,4294967296); 401 | 402 | select rb_select(NULL,10); 403 | select rb_select('{}',10); 404 | select rb_select('{0,1,2,10,100,1000,2147483647,-2147483648,-2,-1}',0); 405 | select rb_select('{0,1,2,10,100,1000,2147483647,-2147483648,-2,-1}',1); 406 | select rb_select('{0,1,2,10,100,1000,2147483647,-2147483648,-2,-1}',2); 407 | select rb_select('{0,1,2,10,100,1000,2147483647,-2147483648,-2,-1}',2,0); 408 | select rb_select('{0,1,2,10,100,1000,2147483647,-2147483648,-2,-1}',2,1); 409 | select rb_select('{0,1,2,10,100,1000,2147483647,-2147483648,-2,-1}',2,1,true); 410 | select rb_select('{0,1,2,10,100,1000,2147483647,-2147483648,-2,-1}',2,1,true,9); 411 | select rb_select('{0,1,2,10,100,1000,2147483647,-2147483648,-2,-1}',2,1,true,9,4294967295); 412 | select rb_select('{0,1,2,10,100,1000,2147483647,-2147483648,-2,-1}',2,1,false); 413 | select rb_select('{0,1,2,10,100,1000,2147483647,-2147483648,-2,-1}',2,1,false,9); 414 | select rb_select('{0,1,2,10,100,1000,2147483647,-2147483648,-2,-1}',2,1,false,10); 415 | select rb_select('{0,1,2,10,100,1000,2147483647,-2147483648,-2,-1}',2,1,false,10,10); 416 | select rb_select('{0,1,2,10,100,1000,2147483647,-2147483648,-2,-1}',2,1,false,-10,100); 417 | select rb_select('{0,1,2,10,100,1000,2147483647,-2147483648,-2,-1}',2,1,false,-10,-10); 418 | select rb_select('{0,1,2,10,100,1000,2147483647,-2147483648,-2,-1}',2,1,false,10,10001); 419 | select rb_select('{0,1,2,10,100,1000,2147483647,-2147483648,-2,-1}',2,1,true,10,10001); 420 | 421 | 422 | -- Test aggregate 423 | 424 | select rb_and_agg(id) from (values (NULL::roaringbitmap)) t(id); 425 | select rb_and_agg(id) from (values (roaringbitmap('{}'))) t(id); 426 | select rb_and_agg(id) from (values (roaringbitmap('{1}'))) t(id); 427 | select rb_and_agg(id) from (values (roaringbitmap('{1,10,100}'))) t(id); 428 | select rb_and_agg(id) from (values (roaringbitmap('{1,10,100}')),(roaringbitmap('{2,10}'))) t(id); 429 | select rb_and_agg(id) from (values (roaringbitmap('{1,10,100}')),(roaringbitmap('{1,10,100}'))) t(id); 430 | select rb_and_agg(id) from (values (NULL),(roaringbitmap('{1,10,100}')),(roaringbitmap('{}'))) t(id); 431 | select rb_and_agg(id) from (values (NULL),(roaringbitmap('{1,10,100}')),(roaringbitmap('{1}'))) t(id); 432 | select rb_and_agg(id) from (values (NULL),(roaringbitmap('{1,10,100}')),(roaringbitmap('{2}'))) t(id); 433 | select rb_and_agg(id) from (values (roaringbitmap('{1,10,100}')),(NULL),(roaringbitmap('{2,10}'))) t(id); 434 | select rb_and_agg(id) from (values (NULL),(roaringbitmap('{1,10,100}')),(NULL),(roaringbitmap('{1,10,100,101}')),(NULL)) t(id); 435 | 436 | select rb_and_cardinality_agg(id) from (values (NULL::roaringbitmap)) t(id); 437 | select rb_and_cardinality_agg(id) from (values (roaringbitmap('{}'))) t(id); 438 | select rb_and_cardinality_agg(id) from (values (roaringbitmap('{1}'))) t(id); 439 | select rb_and_cardinality_agg(id) from (values (roaringbitmap('{1,10,100}'))) t(id); 440 | select rb_and_cardinality_agg(id) from (values (roaringbitmap('{1,10,100}')),(roaringbitmap('{2,10}'))) t(id); 441 | select rb_and_cardinality_agg(id) from (values (roaringbitmap('{1,10,100}')),(roaringbitmap('{1,10,100}'))) t(id); 442 | select rb_and_cardinality_agg(id) from (values (NULL),(roaringbitmap('{1,10,100}')),(roaringbitmap('{}'))) t(id); 443 | select rb_and_cardinality_agg(id) from (values (NULL),(roaringbitmap('{1,10,100}')),(roaringbitmap('{1}'))) t(id); 444 | select rb_and_cardinality_agg(id) from (values (NULL),(roaringbitmap('{1,10,100}')),(roaringbitmap('{2}'))) t(id); 445 | select rb_and_cardinality_agg(id) from (values (roaringbitmap('{1,10,100}')),(NULL),(roaringbitmap('{2,10}'))) t(id); 446 | select rb_and_cardinality_agg(id) from (values (NULL),(roaringbitmap('{1,10,100}')),(NULL),(roaringbitmap('{1,10,100,101}')),(NULL)) t(id); 447 | 448 | select rb_or_agg(id) from (values (NULL::roaringbitmap)) t(id); 449 | select rb_or_agg(id) from (values (roaringbitmap('{}'))) t(id); 450 | select rb_or_agg(id) from (values (roaringbitmap('{1}'))) t(id); 451 | select rb_or_agg(id) from (values (roaringbitmap('{1,10,100}'))) t(id); 452 | select rb_or_agg(id) from (values (roaringbitmap('{1,10,100}')),(roaringbitmap('{2,10}'))) t(id); 453 | select rb_or_agg(id) from (values (roaringbitmap('{1,10,100}')),(roaringbitmap('{1,10,100}'))) t(id); 454 | select rb_or_agg(id) from (values (NULL),(roaringbitmap('{1,10,100}')),(roaringbitmap('{}'))) t(id); 455 | select rb_or_agg(id) from (values (NULL),(roaringbitmap('{1,10,100}')),(roaringbitmap('{1}'))) t(id); 456 | select rb_or_agg(id) from (values (NULL),(roaringbitmap('{1,10,100}')),(roaringbitmap('{2}'))) t(id); 457 | select rb_or_agg(id) from (values (roaringbitmap('{1,10,100}')),(NULL),(roaringbitmap('{2,10}'))) t(id); 458 | select rb_or_agg(id) from (values (NULL),(roaringbitmap('{1,10,100}')),(NULL),(roaringbitmap('{1,10,100,101}')),(NULL)) t(id); 459 | 460 | select rb_or_cardinality_agg(id) from (values (NULL::roaringbitmap)) t(id); 461 | select rb_or_cardinality_agg(id) from (values (roaringbitmap('{}'))) t(id); 462 | select rb_or_cardinality_agg(id) from (values (roaringbitmap('{1}'))) t(id); 463 | select rb_or_cardinality_agg(id) from (values (roaringbitmap('{1,10,100}'))) t(id); 464 | select rb_or_cardinality_agg(id) from (values (roaringbitmap('{1,10,100}')),(roaringbitmap('{2,10}'))) t(id); 465 | select rb_or_cardinality_agg(id) from (values (roaringbitmap('{1,10,100}')),(roaringbitmap('{1,10,100}'))) t(id); 466 | select rb_or_cardinality_agg(id) from (values (NULL),(roaringbitmap('{1,10,100}')),(roaringbitmap('{}'))) t(id); 467 | select rb_or_cardinality_agg(id) from (values (NULL),(roaringbitmap('{1,10,100}')),(roaringbitmap('{1}'))) t(id); 468 | select rb_or_cardinality_agg(id) from (values (NULL),(roaringbitmap('{1,10,100}')),(roaringbitmap('{2}'))) t(id); 469 | select rb_or_cardinality_agg(id) from (values (roaringbitmap('{1,10,100}')),(NULL),(roaringbitmap('{2,10}'))) t(id); 470 | select rb_or_cardinality_agg(id) from (values (NULL),(roaringbitmap('{1,10,100}')),(NULL),(roaringbitmap('{1,10,100,101}')),(NULL)) t(id); 471 | 472 | select rb_xor_agg(id) from (values (NULL::roaringbitmap)) t(id); 473 | select rb_xor_agg(id) from (values (roaringbitmap('{}'))) t(id); 474 | select rb_xor_agg(id) from (values (roaringbitmap('{1}'))) t(id); 475 | select rb_xor_agg(id) from (values (roaringbitmap('{1,10,100}'))) t(id); 476 | select rb_xor_agg(id) from (values (roaringbitmap('{1,10,100}')),(roaringbitmap('{2,10}'))) t(id); 477 | select rb_xor_agg(id) from (values (roaringbitmap('{1,10,100}')),(roaringbitmap('{1,10,100}'))) t(id); 478 | select rb_xor_agg(id) from (values (NULL),(roaringbitmap('{1,10,100}')),(roaringbitmap('{}'))) t(id); 479 | select rb_xor_agg(id) from (values (NULL),(roaringbitmap('{1,10,100}')),(roaringbitmap('{1}'))) t(id); 480 | select rb_xor_agg(id) from (values (NULL),(roaringbitmap('{1,10,100}')),(roaringbitmap('{2}'))) t(id); 481 | select rb_xor_agg(id) from (values (NULL),(roaringbitmap('{1,10,100}')),(roaringbitmap('{2,10}'))) t(id); 482 | select rb_xor_agg(id) from (values (roaringbitmap('{1,10,100}')),(NULL),(roaringbitmap('{1,10,100,101}'))) t(id); 483 | select rb_xor_agg(id) from (values (NULL),(roaringbitmap('{1,10,100}')),(NULL),(roaringbitmap('{1,10,101}')),(roaringbitmap('{1,100,102}')),(NULL)) t(id); 484 | 485 | select rb_xor_cardinality_agg(id) from (values (NULL::roaringbitmap)) t(id); 486 | select rb_xor_cardinality_agg(id) from (values (roaringbitmap('{}'))) t(id); 487 | select rb_xor_cardinality_agg(id) from (values (roaringbitmap('{1}'))) t(id); 488 | select rb_xor_cardinality_agg(id) from (values (roaringbitmap('{1,10,100}'))) t(id); 489 | select rb_xor_cardinality_agg(id) from (values (roaringbitmap('{1,10,100}')),(roaringbitmap('{2,10}'))) t(id); 490 | select rb_xor_cardinality_agg(id) from (values (roaringbitmap('{1,10,100}')),(roaringbitmap('{1,10,100}'))) t(id); 491 | select rb_xor_cardinality_agg(id) from (values (NULL),(roaringbitmap('{1,10,100}')),(roaringbitmap('{}'))) t(id); 492 | select rb_xor_cardinality_agg(id) from (values (NULL),(roaringbitmap('{1,10,100}')),(roaringbitmap('{1}'))) t(id); 493 | select rb_xor_cardinality_agg(id) from (values (NULL),(roaringbitmap('{1,10,100}')),(roaringbitmap('{2}'))) t(id); 494 | select rb_xor_cardinality_agg(id) from (values (NULL),(roaringbitmap('{1,10,100}')),(roaringbitmap('{2,10}'))) t(id); 495 | select rb_xor_cardinality_agg(id) from (values (roaringbitmap('{1,10,100}')),(NULL),(roaringbitmap('{1,10,100,101}'))) t(id); 496 | select rb_xor_cardinality_agg(id) from (values (NULL),(roaringbitmap('{1,10,100}')),(NULL),(roaringbitmap('{1,10,101}')),(roaringbitmap('{1,100,102}')),(NULL)) t(id); 497 | 498 | select rb_build_agg(id) from (values (NULL::int)) t(id); 499 | select rb_build_agg(id) from (values (1)) t(id); 500 | select rb_build_agg(id) from (values (1),(10)) t(id); 501 | select rb_build_agg(id) from (values (1),(10),(10),(100),(1)) t(id); 502 | 503 | 504 | -- Test Windows aggregate 505 | 506 | with t(id,bitmap) as( 507 | values(0,NULL),(1,roaringbitmap('{1,10}')),(2,NULL),(3,roaringbitmap('{2,10}')),(4,roaringbitmap('{10,100}')) 508 | ) 509 | select id,bitmap,rb_and_agg(bitmap) over(order by id),rb_and_cardinality_agg(bitmap) over(order by id) from t; 510 | 511 | with t(id,bitmap) as( 512 | values(0,NULL),(1,roaringbitmap('{1,10}')),(2,NULL),(3,roaringbitmap('{2,10}')),(4,roaringbitmap('{10,100}')) 513 | ) 514 | select id,bitmap,rb_or_agg(bitmap) over(order by id),rb_or_cardinality_agg(bitmap) over(order by id) from t; 515 | 516 | with t(id,bitmap) as( 517 | values(0,NULL),(1,roaringbitmap('{1,10}')),(2,NULL),(3,roaringbitmap('{2,10}')),(4,roaringbitmap('{10,100}')) 518 | ) 519 | select id,bitmap,rb_xor_agg(bitmap) over(order by id),rb_xor_cardinality_agg(bitmap) over(order by id) from t; 520 | 521 | with t(id) as( 522 | values(0),(1),(2),(NULL),(4),(NULL) 523 | ) 524 | select id,rb_build_agg(id) over(order by id) from t; 525 | 526 | 527 | -- Test parallel aggregate 528 | 529 | set max_parallel_workers=8; 530 | set max_parallel_workers_per_gather=2; 531 | set parallel_setup_cost=0; 532 | set parallel_tuple_cost=0; 533 | set min_parallel_table_scan_size=0; 534 | 535 | CREATE OR REPLACE FUNCTION get_json_plan(sql text) RETURNS SETOF json AS 536 | $BODY$ 537 | BEGIN 538 | RETURN QUERY EXECUTE 'EXPLAIN (COSTS OFF,FORMAT JSON) ' || sql; 539 | 540 | RETURN; 541 | END 542 | $BODY$ 543 | LANGUAGE plpgsql; 544 | 545 | 546 | create table if not exists bitmap_test_tb1(id int, bitmap roaringbitmap); 547 | truncate bitmap_test_tb1; 548 | insert into bitmap_test_tb1 values (NULL,NULL); 549 | insert into bitmap_test_tb1 select id,rb_build(ARRAY[id]) from generate_series(1,10000)id; 550 | insert into bitmap_test_tb1 values (NULL,NULL); 551 | insert into bitmap_test_tb1 values (10001,rb_build(ARRAY[10,100,1000,10000,10001])); 552 | 553 | select position('"Parallel Aware": true' in get_json_plan(' 554 | select rb_cardinality(bitmap),rb_min(bitmap),rb_max(bitmap) 555 | from (select rb_build_agg(id) bitmap from bitmap_test_tb1)a 556 | ')::text) > 0 is_parallel_plan; 557 | 558 | select rb_cardinality(bitmap),rb_min(bitmap),rb_max(bitmap) 559 | from (select rb_build_agg(id) bitmap from bitmap_test_tb1)a; 560 | 561 | select position('"Parallel Aware": true' in get_json_plan(' 562 | select rb_cardinality(bitmap),rb_min(bitmap),rb_max(bitmap) 563 | from (select rb_and_agg(bitmap) bitmap from bitmap_test_tb1)a 564 | ')::text) > 0 is_parallel_plan; 565 | 566 | select rb_cardinality(bitmap),rb_min(bitmap),rb_max(bitmap) 567 | from (select rb_and_agg(bitmap) bitmap from bitmap_test_tb1)a; 568 | 569 | select position('"Parallel Aware": true' in get_json_plan(' 570 | select rb_cardinality(bitmap),rb_min(bitmap),rb_max(bitmap) 571 | from (select rb_or_agg(bitmap) bitmap from bitmap_test_tb1)a 572 | ')::text) > 0 is_parallel_plan; 573 | 574 | select rb_cardinality(bitmap),rb_min(bitmap),rb_max(bitmap) 575 | from (select rb_or_agg(bitmap) bitmap from bitmap_test_tb1)a; 576 | 577 | select position('"Parallel Aware": true' in get_json_plan(' 578 | select rb_cardinality(bitmap),rb_min(bitmap),rb_max(bitmap) 579 | from (select rb_xor_agg(bitmap) bitmap from bitmap_test_tb1)a 580 | ')::text) > 0 is_parallel_plan; 581 | 582 | select rb_cardinality(bitmap),rb_min(bitmap),rb_max(bitmap) 583 | from (select rb_xor_agg(bitmap) bitmap from bitmap_test_tb1)a; 584 | 585 | select position('"Parallel Aware": true' in get_json_plan(' 586 | select rb_and_cardinality_agg(bitmap),rb_or_cardinality_agg(bitmap),rb_xor_cardinality_agg(bitmap) from bitmap_test_tb1 587 | ')::text) > 0 is_parallel_plan; 588 | 589 | select rb_and_cardinality_agg(bitmap),rb_or_cardinality_agg(bitmap),rb_xor_cardinality_agg(bitmap) from bitmap_test_tb1; 590 | 591 | --rb_iterate() not support parallel on PG10 while run on parallel in PG11+ 592 | --explain(costs off) 593 | --select count(*) from (select rb_iterate(bitmap) from bitmap_test_tb1)a; 594 | 595 | select count(*) from (select rb_iterate(bitmap) from bitmap_test_tb1)a; 596 | 597 | select position('"Parallel Aware": true' in get_json_plan(' 598 | select id,bitmap, 599 | rb_build_agg(id) over(w), 600 | rb_or_agg(bitmap) over(w), 601 | rb_and_agg(bitmap) over(w), 602 | rb_xor_agg(bitmap) over(w) 603 | from bitmap_test_tb1 604 | window w as (order by id) 605 | order by id limit 10 606 | ')::text) > 0 is_parallel_plan; 607 | 608 | select id,bitmap, 609 | rb_build_agg(id) over(w), 610 | rb_or_agg(bitmap) over(w), 611 | rb_and_agg(bitmap) over(w), 612 | rb_xor_agg(bitmap) over(w) 613 | from bitmap_test_tb1 614 | window w as (order by id) 615 | order by id limit 10; 616 | 617 | -- bugfix #22 618 | SELECT '{100373,1829130,1861002,1975442,2353213,2456403}'::roaringbitmap & '{2353213}'::roaringbitmap; 619 | SELECT rb_and_cardinality('{100373,1829130,1861002,1975442,2353213,2456403}','{2353213}'); 620 | 621 | -- bugfix #45: rb_to_array and rb_min exhibits inconsistent results in a malformed serialize input 622 | select rb_to_array('\x3a300000010000000000000000000000000000000000000000000000000000000000000000000000000000000008'::roaringbitmap), 623 | rb_min('\x3a300000010000000000000000000000000000000000000000000000000000000000000000000000000000000008'::roaringbitmap); 624 | 625 | 626 | -------------------------------------------------------------------------------- /roaringbitmap--1.2.sql: -------------------------------------------------------------------------------- 1 | 2 | -- complain if script is sourced in psql, rather than via CREATE EXTENSION 3 | \echo Use "CREATE EXTENSION roaringbitmap" to load this file. \quit 4 | 5 | -- 6 | -- Type definition for Roaring Bitmaps 7 | -- 8 | 9 | CREATE TYPE roaringbitmap; 10 | 11 | CREATE OR REPLACE FUNCTION roaringbitmap_in(cstring) 12 | RETURNS roaringbitmap 13 | AS 'MODULE_PATHNAME','roaringbitmap_in' 14 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 15 | 16 | CREATE OR REPLACE FUNCTION roaringbitmap_out(roaringbitmap) 17 | RETURNS cstring 18 | AS 'MODULE_PATHNAME','roaringbitmap_out' 19 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 20 | 21 | CREATE OR REPLACE FUNCTION roaringbitmap_recv(internal) 22 | RETURNS roaringbitmap 23 | AS 'MODULE_PATHNAME','roaringbitmap_recv' 24 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 25 | 26 | CREATE OR REPLACE FUNCTION roaringbitmap_send(roaringbitmap) 27 | RETURNS bytea 28 | AS 'MODULE_PATHNAME','roaringbitmap_send' 29 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 30 | 31 | CREATE TYPE roaringbitmap ( 32 | INTERNALLENGTH = VARIABLE, 33 | INPUT = roaringbitmap_in, 34 | OUTPUT = roaringbitmap_out, 35 | receive = roaringbitmap_recv, 36 | send = roaringbitmap_send, 37 | STORAGE = external 38 | ); 39 | 40 | -- 41 | -- type cast for bytea 42 | -- 43 | CREATE OR REPLACE FUNCTION roaringbitmap(bytea) 44 | RETURNS roaringbitmap 45 | AS 'MODULE_PATHNAME','rb_from_bytea' 46 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 47 | 48 | CREATE CAST (roaringbitmap AS bytea) WITHOUT FUNCTION; 49 | CREATE CAST (bytea AS roaringbitmap) WITH FUNCTION roaringbitmap(bytea); 50 | 51 | -- 52 | -- Operator Functions 53 | -- 54 | CREATE OR REPLACE FUNCTION rb_and(roaringbitmap, roaringbitmap) 55 | RETURNS roaringbitmap 56 | AS 'MODULE_PATHNAME', 'rb_and' 57 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 58 | 59 | CREATE OR REPLACE FUNCTION rb_or(roaringbitmap, roaringbitmap) 60 | RETURNS roaringbitmap 61 | AS 'MODULE_PATHNAME', 'rb_or' 62 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 63 | 64 | CREATE OR REPLACE FUNCTION rb_xor(roaringbitmap, roaringbitmap) 65 | RETURNS roaringbitmap 66 | AS 'MODULE_PATHNAME', 'rb_xor' 67 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 68 | 69 | CREATE OR REPLACE FUNCTION rb_andnot(roaringbitmap, roaringbitmap) 70 | RETURNS roaringbitmap 71 | AS 'MODULE_PATHNAME', 'rb_andnot' 72 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 73 | 74 | CREATE OR REPLACE FUNCTION rb_add(roaringbitmap, integer) 75 | RETURNS roaringbitmap 76 | AS 'MODULE_PATHNAME', 'rb_add' 77 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 78 | 79 | CREATE OR REPLACE FUNCTION rb_add(integer, roaringbitmap) 80 | RETURNS roaringbitmap 81 | AS 'SELECT rb_add($2, $1);' 82 | LANGUAGE SQL STRICT IMMUTABLE PARALLEL SAFE; 83 | 84 | CREATE OR REPLACE FUNCTION rb_remove(roaringbitmap, integer) 85 | RETURNS roaringbitmap 86 | AS 'MODULE_PATHNAME', 'rb_remove' 87 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 88 | 89 | CREATE OR REPLACE FUNCTION rb_shiftright(roaringbitmap, bigint) 90 | RETURNS roaringbitmap 91 | AS 'MODULE_PATHNAME', 'rb_shiftright' 92 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 93 | 94 | CREATE OR REPLACE FUNCTION rb_shiftleft(roaringbitmap, bigint) 95 | RETURNS roaringbitmap 96 | AS 'SELECT rb_shiftright($1, -$2);' 97 | LANGUAGE SQL STRICT IMMUTABLE PARALLEL SAFE; 98 | 99 | CREATE OR REPLACE FUNCTION rb_contains(roaringbitmap, roaringbitmap) 100 | RETURNS bool 101 | AS 'MODULE_PATHNAME', 'rb_contains' 102 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 103 | 104 | CREATE OR REPLACE FUNCTION rb_contains(roaringbitmap, integer) 105 | RETURNS bool 106 | AS 'MODULE_PATHNAME', 'rb_exists' 107 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 108 | 109 | CREATE OR REPLACE FUNCTION rb_containedby(roaringbitmap, roaringbitmap) 110 | RETURNS bool 111 | AS 'MODULE_PATHNAME', 'rb_containedby' 112 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 113 | 114 | CREATE OR REPLACE FUNCTION rb_containedby(integer, roaringbitmap) 115 | RETURNS bool 116 | AS 'SELECT rb_contains($2, $1);' 117 | LANGUAGE SQL STRICT IMMUTABLE PARALLEL SAFE; 118 | 119 | CREATE OR REPLACE FUNCTION rb_intersect(roaringbitmap, roaringbitmap) 120 | RETURNS bool 121 | AS 'MODULE_PATHNAME', 'rb_intersect' 122 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 123 | 124 | CREATE OR REPLACE FUNCTION rb_equals(roaringbitmap, roaringbitmap) 125 | RETURNS bool 126 | AS 'MODULE_PATHNAME', 'rb_equals' 127 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 128 | 129 | CREATE OR REPLACE FUNCTION rb_not_equals(roaringbitmap, roaringbitmap) 130 | RETURNS bool 131 | AS 'MODULE_PATHNAME', 'rb_not_equals' 132 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 133 | 134 | -- 135 | -- Functions 136 | -- 137 | 138 | CREATE OR REPLACE FUNCTION rb_build(integer[]) 139 | RETURNS roaringbitmap 140 | AS 'MODULE_PATHNAME', 'rb_build' 141 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 142 | 143 | CREATE OR REPLACE FUNCTION rb_index(roaringbitmap, integer) 144 | RETURNS bigint 145 | AS 'MODULE_PATHNAME', 'rb_index' 146 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 147 | 148 | CREATE OR REPLACE FUNCTION rb_cardinality(roaringbitmap) 149 | RETURNS bigint 150 | AS 'MODULE_PATHNAME', 'rb_cardinality' 151 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 152 | 153 | CREATE OR REPLACE FUNCTION rb_and_cardinality(roaringbitmap, roaringbitmap) 154 | RETURNS bigint 155 | AS 'MODULE_PATHNAME', 'rb_and_cardinality' 156 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 157 | 158 | CREATE OR REPLACE FUNCTION rb_or_cardinality(roaringbitmap, roaringbitmap) 159 | RETURNS bigint 160 | AS 'MODULE_PATHNAME', 'rb_or_cardinality' 161 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 162 | 163 | CREATE OR REPLACE FUNCTION rb_xor_cardinality(roaringbitmap, roaringbitmap) 164 | RETURNS bigint 165 | AS 'MODULE_PATHNAME', 'rb_xor_cardinality' 166 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 167 | 168 | CREATE OR REPLACE FUNCTION rb_andnot_cardinality(roaringbitmap, roaringbitmap) 169 | RETURNS bigint 170 | AS 'MODULE_PATHNAME', 'rb_andnot_cardinality' 171 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 172 | 173 | CREATE OR REPLACE FUNCTION rb_is_empty(roaringbitmap) 174 | RETURNS bool 175 | AS 'MODULE_PATHNAME', 'rb_is_empty' 176 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 177 | 178 | CREATE OR REPLACE FUNCTION rb_fill(roaringbitmap, range_start bigint, range_end bigint) 179 | RETURNS roaringbitmap 180 | AS 'MODULE_PATHNAME', 'rb_fill' 181 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 182 | 183 | CREATE OR REPLACE FUNCTION rb_clear(roaringbitmap, range_start bigint, range_end bigint) 184 | RETURNS roaringbitmap 185 | AS 'MODULE_PATHNAME', 'rb_clear' 186 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 187 | 188 | CREATE OR REPLACE FUNCTION rb_flip(roaringbitmap, range_start bigint, range_end bigint) 189 | RETURNS roaringbitmap 190 | AS 'MODULE_PATHNAME', 'rb_flip' 191 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 192 | 193 | CREATE OR REPLACE FUNCTION rb_range(roaringbitmap, range_start bigint, range_end bigint) 194 | RETURNS roaringbitmap 195 | AS 'MODULE_PATHNAME', 'rb_range' 196 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 197 | 198 | CREATE OR REPLACE FUNCTION rb_range_cardinality(roaringbitmap, range_start bigint, range_end bigint) 199 | RETURNS bigint 200 | AS 'MODULE_PATHNAME', 'rb_range_cardinality' 201 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 202 | 203 | CREATE OR REPLACE FUNCTION rb_min(roaringbitmap) 204 | RETURNS integer 205 | AS 'MODULE_PATHNAME', 'rb_min' 206 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 207 | 208 | CREATE OR REPLACE FUNCTION rb_max(roaringbitmap) 209 | RETURNS integer 210 | AS 'MODULE_PATHNAME', 'rb_max' 211 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 212 | 213 | CREATE OR REPLACE FUNCTION rb_rank(roaringbitmap, integer) 214 | RETURNS bigint 215 | AS 'MODULE_PATHNAME', 'rb_rank' 216 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 217 | 218 | CREATE OR REPLACE FUNCTION rb_jaccard_dist(roaringbitmap, roaringbitmap) 219 | RETURNS float8 220 | AS 'MODULE_PATHNAME', 'rb_jaccard_dist' 221 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 222 | 223 | CREATE OR REPLACE FUNCTION rb_select(roaringbitmap, bitset_limit bigint,bitset_offset bigint=0,reverse boolean=false,range_start bigint=0,range_end bigint=4294967296) 224 | RETURNS roaringbitmap 225 | AS 'MODULE_PATHNAME', 'rb_select' 226 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 227 | 228 | CREATE OR REPLACE FUNCTION rb_to_array(roaringbitmap) 229 | RETURNS integer[] 230 | AS 'MODULE_PATHNAME', 'rb_to_array' 231 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 232 | 233 | CREATE OR REPLACE FUNCTION rb_iterate(roaringbitmap) 234 | RETURNS SETOF integer 235 | AS 'MODULE_PATHNAME', 'rb_iterate' 236 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 237 | 238 | CREATE OR REPLACE FUNCTION rb_runoptimize(roaringbitmap) 239 | RETURNS roaringbitmap 240 | AS 'MODULE_PATHNAME', 'rb_runoptimize' 241 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 242 | 243 | -- 244 | -- Operators 245 | -- 246 | 247 | CREATE OPERATOR & ( 248 | LEFTARG = roaringbitmap, 249 | RIGHTARG = roaringbitmap, 250 | PROCEDURE = rb_and 251 | ); 252 | 253 | CREATE OPERATOR | ( 254 | LEFTARG = roaringbitmap, 255 | RIGHTARG = roaringbitmap, 256 | PROCEDURE = rb_or 257 | ); 258 | 259 | CREATE OPERATOR | ( 260 | LEFTARG = roaringbitmap, 261 | RIGHTARG = int4, 262 | PROCEDURE = rb_add 263 | ); 264 | 265 | CREATE OPERATOR | ( 266 | LEFTARG = int4, 267 | RIGHTARG = roaringbitmap, 268 | PROCEDURE = rb_add 269 | ); 270 | 271 | CREATE OPERATOR # ( 272 | LEFTARG = roaringbitmap, 273 | RIGHTARG = roaringbitmap, 274 | PROCEDURE = rb_xor 275 | ); 276 | 277 | CREATE OPERATOR << ( 278 | LEFTARG = roaringbitmap, 279 | RIGHTARG = bigint, 280 | PROCEDURE = rb_shiftleft 281 | ); 282 | 283 | CREATE OPERATOR >> ( 284 | LEFTARG = roaringbitmap, 285 | RIGHTARG = bigint, 286 | PROCEDURE = rb_shiftright 287 | ); 288 | 289 | CREATE OPERATOR - ( 290 | LEFTARG = roaringbitmap, 291 | RIGHTARG = roaringbitmap, 292 | PROCEDURE = rb_andnot 293 | ); 294 | 295 | CREATE OPERATOR - ( 296 | LEFTARG = roaringbitmap, 297 | RIGHTARG = int4, 298 | PROCEDURE = rb_remove 299 | ); 300 | 301 | CREATE OPERATOR @> ( 302 | LEFTARG = roaringbitmap, 303 | RIGHTARG = roaringbitmap, 304 | PROCEDURE = rb_contains, 305 | COMMUTATOR = '<@', 306 | RESTRICT = contsel, 307 | JOIN = contjoinsel 308 | ); 309 | 310 | CREATE OPERATOR @> ( 311 | LEFTARG = roaringbitmap, 312 | RIGHTARG = int4, 313 | PROCEDURE = rb_contains, 314 | COMMUTATOR = '<@', 315 | RESTRICT = contsel, 316 | JOIN = contjoinsel 317 | ); 318 | 319 | CREATE OPERATOR <@ ( 320 | LEFTARG = roaringbitmap, 321 | RIGHTARG = roaringbitmap, 322 | PROCEDURE = rb_containedby, 323 | COMMUTATOR = '@>', 324 | RESTRICT = contsel, 325 | JOIN = contjoinsel 326 | ); 327 | 328 | CREATE OPERATOR <@ ( 329 | LEFTARG = int4, 330 | RIGHTARG = roaringbitmap, 331 | PROCEDURE = rb_containedby, 332 | COMMUTATOR = '@>', 333 | RESTRICT = contsel, 334 | JOIN = contjoinsel 335 | ); 336 | 337 | CREATE OPERATOR && ( 338 | LEFTARG = roaringbitmap, 339 | RIGHTARG = roaringbitmap, 340 | PROCEDURE = rb_intersect, 341 | COMMUTATOR = '&&', 342 | RESTRICT = contsel, 343 | JOIN = contjoinsel 344 | ); 345 | 346 | CREATE OPERATOR = ( 347 | LEFTARG = roaringbitmap, 348 | RIGHTARG = roaringbitmap, 349 | PROCEDURE = rb_equals, 350 | COMMUTATOR = '=', 351 | NEGATOR = '<>', 352 | RESTRICT = eqsel, 353 | JOIN = eqjoinsel 354 | ); 355 | 356 | CREATE OPERATOR <> ( 357 | LEFTARG = roaringbitmap, 358 | RIGHTARG = roaringbitmap, 359 | PROCEDURE = rb_not_equals, 360 | COMMUTATOR = '<>', 361 | NEGATOR = '=', 362 | RESTRICT = neqsel, 363 | JOIN = neqjoinsel 364 | ); 365 | 366 | -- 367 | -- Aggregations 368 | -- 369 | 370 | CREATE OR REPLACE FUNCTION rb_final(internal) 371 | RETURNS roaringbitmap 372 | AS 'MODULE_PATHNAME', 'rb_serialize' 373 | LANGUAGE C IMMUTABLE PARALLEL SAFE; 374 | 375 | CREATE OR REPLACE FUNCTION rb_serialize(internal) 376 | RETURNS bytea 377 | AS 'MODULE_PATHNAME', 'rb_serialize' 378 | LANGUAGE C IMMUTABLE PARALLEL SAFE; 379 | 380 | CREATE OR REPLACE FUNCTION rb_deserialize(bytea,internal) 381 | RETURNS internal 382 | AS 'MODULE_PATHNAME', 'rb_deserialize' 383 | LANGUAGE C IMMUTABLE PARALLEL SAFE; 384 | 385 | CREATE OR REPLACE FUNCTION rb_cardinality_final(internal) 386 | RETURNS bigint 387 | AS 'MODULE_PATHNAME', 'rb_cardinality_final' 388 | LANGUAGE C IMMUTABLE PARALLEL SAFE; 389 | 390 | 391 | CREATE OR REPLACE FUNCTION rb_or_trans(internal, roaringbitmap) 392 | RETURNS internal 393 | AS 'MODULE_PATHNAME', 'rb_or_trans' 394 | LANGUAGE C IMMUTABLE PARALLEL SAFE; 395 | 396 | CREATE OR REPLACE FUNCTION rb_or_combine(internal, internal) 397 | RETURNS internal 398 | AS 'MODULE_PATHNAME', 'rb_or_combine' 399 | LANGUAGE C IMMUTABLE PARALLEL SAFE; 400 | 401 | CREATE AGGREGATE rb_or_agg(roaringbitmap)( 402 | SFUNC = rb_or_trans, 403 | STYPE = internal, 404 | FINALFUNC = rb_final, 405 | COMBINEFUNC = rb_or_combine, 406 | SERIALFUNC = rb_serialize, 407 | DESERIALFUNC = rb_deserialize, 408 | PARALLEL = SAFE 409 | ); 410 | 411 | CREATE AGGREGATE rb_or_cardinality_agg(roaringbitmap)( 412 | SFUNC = rb_or_trans, 413 | STYPE = internal, 414 | FINALFUNC = rb_cardinality_final, 415 | COMBINEFUNC = rb_or_combine, 416 | SERIALFUNC = rb_serialize, 417 | DESERIALFUNC = rb_deserialize, 418 | PARALLEL = SAFE 419 | ); 420 | 421 | 422 | CREATE OR REPLACE FUNCTION rb_and_trans(internal, roaringbitmap) 423 | RETURNS internal 424 | AS 'MODULE_PATHNAME', 'rb_and_trans' 425 | LANGUAGE C IMMUTABLE PARALLEL SAFE; 426 | 427 | CREATE OR REPLACE FUNCTION rb_and_combine(internal, internal) 428 | RETURNS internal 429 | AS 'MODULE_PATHNAME', 'rb_and_combine' 430 | LANGUAGE C IMMUTABLE PARALLEL SAFE; 431 | 432 | CREATE AGGREGATE rb_and_agg(roaringbitmap)( 433 | SFUNC = rb_and_trans, 434 | STYPE = internal, 435 | FINALFUNC = rb_final, 436 | COMBINEFUNC = rb_and_combine, 437 | SERIALFUNC = rb_serialize, 438 | DESERIALFUNC = rb_deserialize, 439 | PARALLEL = SAFE 440 | ); 441 | 442 | 443 | CREATE AGGREGATE rb_and_cardinality_agg(roaringbitmap)( 444 | SFUNC = rb_and_trans, 445 | STYPE = internal, 446 | FINALFUNC = rb_cardinality_final, 447 | COMBINEFUNC = rb_and_combine, 448 | SERIALFUNC = rb_serialize, 449 | DESERIALFUNC = rb_deserialize, 450 | PARALLEL = SAFE 451 | ); 452 | 453 | 454 | CREATE OR REPLACE FUNCTION rb_xor_trans(internal, roaringbitmap) 455 | RETURNS internal 456 | AS 'MODULE_PATHNAME', 'rb_xor_trans' 457 | LANGUAGE C IMMUTABLE PARALLEL SAFE; 458 | 459 | CREATE OR REPLACE FUNCTION rb_xor_combine(internal, internal) 460 | RETURNS internal 461 | AS 'MODULE_PATHNAME', 'rb_xor_combine' 462 | LANGUAGE C IMMUTABLE PARALLEL SAFE; 463 | 464 | CREATE AGGREGATE rb_xor_agg(roaringbitmap)( 465 | SFUNC = rb_xor_trans, 466 | STYPE = internal, 467 | FINALFUNC = rb_final, 468 | COMBINEFUNC = rb_xor_combine, 469 | SERIALFUNC = rb_serialize, 470 | DESERIALFUNC = rb_deserialize, 471 | PARALLEL = SAFE 472 | ); 473 | 474 | 475 | CREATE AGGREGATE rb_xor_cardinality_agg(roaringbitmap)( 476 | SFUNC = rb_xor_trans, 477 | STYPE = internal, 478 | FINALFUNC = rb_cardinality_final, 479 | COMBINEFUNC = rb_xor_combine, 480 | SERIALFUNC = rb_serialize, 481 | DESERIALFUNC = rb_deserialize, 482 | PARALLEL = SAFE 483 | ); 484 | 485 | CREATE OR REPLACE FUNCTION rb_build_trans(internal, integer) 486 | RETURNS internal 487 | AS 'MODULE_PATHNAME', 'rb_build_trans' 488 | LANGUAGE C IMMUTABLE PARALLEL SAFE; 489 | 490 | CREATE AGGREGATE rb_build_agg(integer)( 491 | SFUNC = rb_build_trans, 492 | STYPE = internal, 493 | FINALFUNC = rb_final, 494 | COMBINEFUNC = rb_or_combine, 495 | SERIALFUNC = rb_serialize, 496 | DESERIALFUNC = rb_deserialize, 497 | PARALLEL = SAFE 498 | ); 499 | 500 | -- 501 | -- Type definition for 64 bit Roaring Bitmaps 502 | -- 503 | 504 | CREATE TYPE roaringbitmap64; 505 | 506 | CREATE OR REPLACE FUNCTION roaringbitmap64_in(cstring) 507 | RETURNS roaringbitmap64 508 | AS 'MODULE_PATHNAME','roaringbitmap64_in' 509 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 510 | 511 | CREATE OR REPLACE FUNCTION roaringbitmap64_out(roaringbitmap64) 512 | RETURNS cstring 513 | AS 'MODULE_PATHNAME','roaringbitmap64_out' 514 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 515 | 516 | CREATE OR REPLACE FUNCTION roaringbitmap64_recv(internal) 517 | RETURNS roaringbitmap64 518 | AS 'MODULE_PATHNAME','roaringbitmap64_recv' 519 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 520 | 521 | CREATE OR REPLACE FUNCTION roaringbitmap64_send(roaringbitmap64) 522 | RETURNS bytea 523 | AS 'MODULE_PATHNAME','roaringbitmap64_send' 524 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 525 | 526 | CREATE TYPE roaringbitmap64 ( 527 | INTERNALLENGTH = VARIABLE, 528 | INPUT = roaringbitmap64_in, 529 | OUTPUT = roaringbitmap64_out, 530 | receive = roaringbitmap64_recv, 531 | send = roaringbitmap64_send, 532 | STORAGE = external 533 | ); 534 | 535 | -- 536 | -- type cast for bytea 537 | -- 538 | CREATE OR REPLACE FUNCTION roaringbitmap64(bytea) 539 | RETURNS roaringbitmap64 540 | AS 'MODULE_PATHNAME','rb64_from_bytea' 541 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 542 | 543 | CREATE CAST (roaringbitmap64 AS bytea) WITHOUT FUNCTION; 544 | CREATE CAST (bytea AS roaringbitmap64) WITH FUNCTION roaringbitmap64(bytea); 545 | 546 | -- 547 | -- type cast for roaringbitmap 548 | -- 549 | CREATE OR REPLACE FUNCTION rb64_to_roaringbitmap(roaringbitmap64) 550 | RETURNS roaringbitmap 551 | AS 'MODULE_PATHNAME', 'rb64_to_roaringbitmap' 552 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 553 | 554 | CREATE OR REPLACE FUNCTION rb64_from_roaringbitmap(roaringbitmap) 555 | RETURNS roaringbitmap64 556 | AS 'MODULE_PATHNAME', 'rb64_from_roaringbitmap' 557 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 558 | 559 | CREATE CAST (roaringbitmap64 AS roaringbitmap) WITH FUNCTION rb64_to_roaringbitmap(roaringbitmap64); 560 | CREATE CAST (roaringbitmap AS roaringbitmap64) WITH FUNCTION rb64_from_roaringbitmap(roaringbitmap); 561 | 562 | -- 563 | -- Operator Functions 564 | -- 565 | CREATE OR REPLACE FUNCTION rb64_and(roaringbitmap64, roaringbitmap64) 566 | RETURNS roaringbitmap64 567 | AS 'MODULE_PATHNAME', 'rb64_and' 568 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 569 | 570 | CREATE OR REPLACE FUNCTION rb64_or(roaringbitmap64, roaringbitmap64) 571 | RETURNS roaringbitmap64 572 | AS 'MODULE_PATHNAME', 'rb64_or' 573 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 574 | 575 | CREATE OR REPLACE FUNCTION rb64_xor(roaringbitmap64, roaringbitmap64) 576 | RETURNS roaringbitmap64 577 | AS 'MODULE_PATHNAME', 'rb64_xor' 578 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 579 | 580 | CREATE OR REPLACE FUNCTION rb64_andnot(roaringbitmap64, roaringbitmap64) 581 | RETURNS roaringbitmap64 582 | AS 'MODULE_PATHNAME', 'rb64_andnot' 583 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 584 | 585 | CREATE OR REPLACE FUNCTION rb64_add(roaringbitmap64, bigint) 586 | RETURNS roaringbitmap64 587 | AS 'MODULE_PATHNAME', 'rb64_add' 588 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 589 | 590 | CREATE OR REPLACE FUNCTION rb64_add(bigint, roaringbitmap64) 591 | RETURNS roaringbitmap64 592 | AS 'SELECT rb64_add($2, $1);' 593 | LANGUAGE SQL STRICT IMMUTABLE PARALLEL SAFE; 594 | 595 | CREATE OR REPLACE FUNCTION rb64_remove(roaringbitmap64, bigint) 596 | RETURNS roaringbitmap64 597 | AS 'MODULE_PATHNAME', 'rb64_remove' 598 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 599 | 600 | CREATE OR REPLACE FUNCTION rb64_shiftright(roaringbitmap64, bigint) 601 | RETURNS roaringbitmap64 602 | AS 'MODULE_PATHNAME', 'rb64_shiftright' 603 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 604 | 605 | CREATE OR REPLACE FUNCTION rb64_shiftleft(roaringbitmap64, bigint) 606 | RETURNS roaringbitmap64 607 | AS 'SELECT rb64_shiftright($1, -$2);' 608 | LANGUAGE SQL STRICT IMMUTABLE PARALLEL SAFE; 609 | 610 | CREATE OR REPLACE FUNCTION rb64_contains(roaringbitmap64, roaringbitmap64) 611 | RETURNS bool 612 | AS 'MODULE_PATHNAME', 'rb64_contains' 613 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 614 | 615 | CREATE OR REPLACE FUNCTION rb64_contains(roaringbitmap64, bigint) 616 | RETURNS bool 617 | AS 'MODULE_PATHNAME', 'rb64_exists' 618 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 619 | 620 | CREATE OR REPLACE FUNCTION rb64_containedby(roaringbitmap64, roaringbitmap64) 621 | RETURNS bool 622 | AS 'MODULE_PATHNAME', 'rb64_containedby' 623 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 624 | 625 | CREATE OR REPLACE FUNCTION rb64_containedby(bigint, roaringbitmap64) 626 | RETURNS bool 627 | AS 'SELECT rb64_contains($2, $1);' 628 | LANGUAGE SQL STRICT IMMUTABLE PARALLEL SAFE; 629 | 630 | CREATE OR REPLACE FUNCTION rb64_intersect(roaringbitmap64, roaringbitmap64) 631 | RETURNS bool 632 | AS 'MODULE_PATHNAME', 'rb64_intersect' 633 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 634 | 635 | CREATE OR REPLACE FUNCTION rb64_equals(roaringbitmap64, roaringbitmap64) 636 | RETURNS bool 637 | AS 'MODULE_PATHNAME', 'rb64_equals' 638 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 639 | 640 | CREATE OR REPLACE FUNCTION rb64_not_equals(roaringbitmap64, roaringbitmap64) 641 | RETURNS bool 642 | AS 'MODULE_PATHNAME', 'rb64_not_equals' 643 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 644 | 645 | -- 646 | -- Functions 647 | -- 648 | 649 | CREATE OR REPLACE FUNCTION rb64_build(bigint[]) 650 | RETURNS roaringbitmap64 651 | AS 'MODULE_PATHNAME', 'rb64_build' 652 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 653 | 654 | CREATE OR REPLACE FUNCTION rb64_index(roaringbitmap64, bigint) 655 | RETURNS bigint 656 | AS 'MODULE_PATHNAME', 'rb64_index' 657 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 658 | 659 | CREATE OR REPLACE FUNCTION rb64_cardinality(roaringbitmap64) 660 | RETURNS bigint 661 | AS 'MODULE_PATHNAME', 'rb64_cardinality' 662 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 663 | 664 | CREATE OR REPLACE FUNCTION rb64_and_cardinality(roaringbitmap64, roaringbitmap64) 665 | RETURNS bigint 666 | AS 'MODULE_PATHNAME', 'rb64_and_cardinality' 667 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 668 | 669 | CREATE OR REPLACE FUNCTION rb64_or_cardinality(roaringbitmap64, roaringbitmap64) 670 | RETURNS bigint 671 | AS 'MODULE_PATHNAME', 'rb64_or_cardinality' 672 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 673 | 674 | CREATE OR REPLACE FUNCTION rb64_xor_cardinality(roaringbitmap64, roaringbitmap64) 675 | RETURNS bigint 676 | AS 'MODULE_PATHNAME', 'rb64_xor_cardinality' 677 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 678 | 679 | CREATE OR REPLACE FUNCTION rb64_andnot_cardinality(roaringbitmap64, roaringbitmap64) 680 | RETURNS bigint 681 | AS 'MODULE_PATHNAME', 'rb64_andnot_cardinality' 682 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 683 | 684 | CREATE OR REPLACE FUNCTION rb64_is_empty(roaringbitmap64) 685 | RETURNS bool 686 | AS 'MODULE_PATHNAME', 'rb64_is_empty' 687 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 688 | 689 | CREATE OR REPLACE FUNCTION rb64_fill(roaringbitmap64, range_start bigint, range_end bigint) 690 | RETURNS roaringbitmap64 691 | AS 'MODULE_PATHNAME', 'rb64_fill' 692 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 693 | 694 | CREATE OR REPLACE FUNCTION rb64_clear(roaringbitmap64, range_start bigint, range_end bigint) 695 | RETURNS roaringbitmap64 696 | AS 'MODULE_PATHNAME', 'rb64_clear' 697 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 698 | 699 | CREATE OR REPLACE FUNCTION rb64_flip(roaringbitmap64, range_start bigint, range_end bigint) 700 | RETURNS roaringbitmap64 701 | AS 'MODULE_PATHNAME', 'rb64_flip' 702 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 703 | 704 | CREATE OR REPLACE FUNCTION rb64_range(roaringbitmap64, range_start bigint, range_end bigint) 705 | RETURNS roaringbitmap64 706 | AS 'MODULE_PATHNAME', 'rb64_range' 707 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 708 | 709 | CREATE OR REPLACE FUNCTION rb64_range_cardinality(roaringbitmap64, range_start bigint, range_end bigint) 710 | RETURNS bigint 711 | AS 'MODULE_PATHNAME', 'rb64_range_cardinality' 712 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 713 | 714 | CREATE OR REPLACE FUNCTION rb64_min(roaringbitmap64) 715 | RETURNS bigint 716 | AS 'MODULE_PATHNAME', 'rb64_min' 717 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 718 | 719 | CREATE OR REPLACE FUNCTION rb64_max(roaringbitmap64) 720 | RETURNS bigint 721 | AS 'MODULE_PATHNAME', 'rb64_max' 722 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 723 | 724 | CREATE OR REPLACE FUNCTION rb64_rank(roaringbitmap64, bigint) 725 | RETURNS bigint 726 | AS 'MODULE_PATHNAME', 'rb64_rank' 727 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 728 | 729 | CREATE OR REPLACE FUNCTION rb64_jaccard_dist(roaringbitmap64, roaringbitmap64) 730 | RETURNS float8 731 | AS 'MODULE_PATHNAME', 'rb64_jaccard_dist' 732 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 733 | 734 | CREATE OR REPLACE FUNCTION rb64_select(roaringbitmap64, bitset_limit bigint,bitset_offset bigint=0,reverse boolean=false,range_start bigint=0,range_end bigint=0) 735 | RETURNS roaringbitmap64 736 | AS 'MODULE_PATHNAME', 'rb64_select' 737 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 738 | 739 | CREATE OR REPLACE FUNCTION rb64_to_array(roaringbitmap64) 740 | RETURNS bigint[] 741 | AS 'MODULE_PATHNAME', 'rb64_to_array' 742 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 743 | 744 | CREATE OR REPLACE FUNCTION rb64_iterate(roaringbitmap64) 745 | RETURNS SETOF bigint 746 | AS 'MODULE_PATHNAME', 'rb64_iterate' 747 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 748 | 749 | CREATE OR REPLACE FUNCTION rb64_runoptimize(roaringbitmap64) 750 | RETURNS roaringbitmap64 751 | AS 'MODULE_PATHNAME', 'rb64_runoptimize' 752 | LANGUAGE C STRICT IMMUTABLE PARALLEL SAFE; 753 | 754 | -- 755 | -- Operators 756 | -- 757 | 758 | CREATE OPERATOR & ( 759 | LEFTARG = roaringbitmap64, 760 | RIGHTARG = roaringbitmap64, 761 | PROCEDURE = rb64_and 762 | ); 763 | 764 | CREATE OPERATOR | ( 765 | LEFTARG = roaringbitmap64, 766 | RIGHTARG = roaringbitmap64, 767 | PROCEDURE = rb64_or 768 | ); 769 | 770 | CREATE OPERATOR | ( 771 | LEFTARG = roaringbitmap64, 772 | RIGHTARG = bigint, 773 | PROCEDURE = rb64_add 774 | ); 775 | 776 | CREATE OPERATOR | ( 777 | LEFTARG = bigint, 778 | RIGHTARG = roaringbitmap64, 779 | PROCEDURE = rb64_add 780 | ); 781 | 782 | CREATE OPERATOR # ( 783 | LEFTARG = roaringbitmap64, 784 | RIGHTARG = roaringbitmap64, 785 | PROCEDURE = rb64_xor 786 | ); 787 | 788 | CREATE OPERATOR << ( 789 | LEFTARG = roaringbitmap64, 790 | RIGHTARG = bigint, 791 | PROCEDURE = rb64_shiftleft 792 | ); 793 | 794 | CREATE OPERATOR >> ( 795 | LEFTARG = roaringbitmap64, 796 | RIGHTARG = bigint, 797 | PROCEDURE = rb64_shiftright 798 | ); 799 | 800 | CREATE OPERATOR - ( 801 | LEFTARG = roaringbitmap64, 802 | RIGHTARG = roaringbitmap64, 803 | PROCEDURE = rb64_andnot 804 | ); 805 | 806 | CREATE OPERATOR - ( 807 | LEFTARG = roaringbitmap64, 808 | RIGHTARG = bigint, 809 | PROCEDURE = rb64_remove 810 | ); 811 | 812 | CREATE OPERATOR @> ( 813 | LEFTARG = roaringbitmap64, 814 | RIGHTARG = roaringbitmap64, 815 | PROCEDURE = rb64_contains, 816 | COMMUTATOR = '<@', 817 | RESTRICT = contsel, 818 | JOIN = contjoinsel 819 | ); 820 | 821 | CREATE OPERATOR @> ( 822 | LEFTARG = roaringbitmap64, 823 | RIGHTARG = bigint, 824 | PROCEDURE = rb64_contains, 825 | COMMUTATOR = '<@', 826 | RESTRICT = contsel, 827 | JOIN = contjoinsel 828 | ); 829 | 830 | CREATE OPERATOR <@ ( 831 | LEFTARG = roaringbitmap64, 832 | RIGHTARG = roaringbitmap64, 833 | PROCEDURE = rb64_containedby, 834 | COMMUTATOR = '@>', 835 | RESTRICT = contsel, 836 | JOIN = contjoinsel 837 | ); 838 | 839 | CREATE OPERATOR <@ ( 840 | LEFTARG = bigint, 841 | RIGHTARG = roaringbitmap64, 842 | PROCEDURE = rb64_containedby, 843 | COMMUTATOR = '@>', 844 | RESTRICT = contsel, 845 | JOIN = contjoinsel 846 | ); 847 | 848 | CREATE OPERATOR && ( 849 | LEFTARG = roaringbitmap64, 850 | RIGHTARG = roaringbitmap64, 851 | PROCEDURE = rb64_intersect, 852 | COMMUTATOR = '&&', 853 | RESTRICT = contsel, 854 | JOIN = contjoinsel 855 | ); 856 | 857 | CREATE OPERATOR = ( 858 | LEFTARG = roaringbitmap64, 859 | RIGHTARG = roaringbitmap64, 860 | PROCEDURE = rb64_equals, 861 | COMMUTATOR = '=', 862 | NEGATOR = '<>', 863 | RESTRICT = eqsel, 864 | JOIN = eqjoinsel 865 | ); 866 | 867 | CREATE OPERATOR <> ( 868 | LEFTARG = roaringbitmap64, 869 | RIGHTARG = roaringbitmap64, 870 | PROCEDURE = rb64_not_equals, 871 | COMMUTATOR = '<>', 872 | NEGATOR = '=', 873 | RESTRICT = neqsel, 874 | JOIN = neqjoinsel 875 | ); 876 | 877 | -- 878 | -- Aggregations 879 | -- 880 | 881 | CREATE OR REPLACE FUNCTION rb64_final(internal) 882 | RETURNS roaringbitmap64 883 | AS 'MODULE_PATHNAME', 'rb64_serialize' 884 | LANGUAGE C IMMUTABLE PARALLEL SAFE; 885 | 886 | CREATE OR REPLACE FUNCTION rb64_serialize(internal) 887 | RETURNS bytea 888 | AS 'MODULE_PATHNAME', 'rb64_serialize' 889 | LANGUAGE C IMMUTABLE PARALLEL SAFE; 890 | 891 | CREATE OR REPLACE FUNCTION rb64_deserialize(bytea,internal) 892 | RETURNS internal 893 | AS 'MODULE_PATHNAME', 'rb64_deserialize' 894 | LANGUAGE C IMMUTABLE PARALLEL SAFE; 895 | 896 | CREATE OR REPLACE FUNCTION rb64_cardinality_final(internal) 897 | RETURNS bigint 898 | AS 'MODULE_PATHNAME', 'rb64_cardinality_final' 899 | LANGUAGE C IMMUTABLE PARALLEL SAFE; 900 | 901 | 902 | CREATE OR REPLACE FUNCTION rb64_or_trans(internal, roaringbitmap64) 903 | RETURNS internal 904 | AS 'MODULE_PATHNAME', 'rb64_or_trans' 905 | LANGUAGE C IMMUTABLE PARALLEL SAFE; 906 | 907 | CREATE OR REPLACE FUNCTION rb64_or_combine(internal, internal) 908 | RETURNS internal 909 | AS 'MODULE_PATHNAME', 'rb64_or_combine' 910 | LANGUAGE C IMMUTABLE PARALLEL SAFE; 911 | 912 | CREATE AGGREGATE rb64_or_agg(roaringbitmap64)( 913 | SFUNC = rb64_or_trans, 914 | STYPE = internal, 915 | FINALFUNC = rb64_final, 916 | COMBINEFUNC = rb64_or_combine, 917 | SERIALFUNC = rb64_serialize, 918 | DESERIALFUNC = rb64_deserialize, 919 | PARALLEL = SAFE 920 | ); 921 | 922 | CREATE AGGREGATE rb64_or_cardinality_agg(roaringbitmap64)( 923 | SFUNC = rb64_or_trans, 924 | STYPE = internal, 925 | FINALFUNC = rb64_cardinality_final, 926 | COMBINEFUNC = rb64_or_combine, 927 | SERIALFUNC = rb64_serialize, 928 | DESERIALFUNC = rb64_deserialize, 929 | PARALLEL = SAFE 930 | ); 931 | 932 | 933 | CREATE OR REPLACE FUNCTION rb64_and_trans(internal, roaringbitmap64) 934 | RETURNS internal 935 | AS 'MODULE_PATHNAME', 'rb64_and_trans' 936 | LANGUAGE C IMMUTABLE PARALLEL SAFE; 937 | 938 | CREATE OR REPLACE FUNCTION rb64_and_combine(internal, internal) 939 | RETURNS internal 940 | AS 'MODULE_PATHNAME', 'rb64_and_combine' 941 | LANGUAGE C IMMUTABLE PARALLEL SAFE; 942 | 943 | CREATE AGGREGATE rb64_and_agg(roaringbitmap64)( 944 | SFUNC = rb64_and_trans, 945 | STYPE = internal, 946 | FINALFUNC = rb64_final, 947 | COMBINEFUNC = rb64_and_combine, 948 | SERIALFUNC = rb64_serialize, 949 | DESERIALFUNC = rb64_deserialize, 950 | PARALLEL = SAFE 951 | ); 952 | 953 | 954 | CREATE AGGREGATE rb64_and_cardinality_agg(roaringbitmap64)( 955 | SFUNC = rb64_and_trans, 956 | STYPE = internal, 957 | FINALFUNC = rb64_cardinality_final, 958 | COMBINEFUNC = rb64_and_combine, 959 | SERIALFUNC = rb64_serialize, 960 | DESERIALFUNC = rb64_deserialize, 961 | PARALLEL = SAFE 962 | ); 963 | 964 | 965 | CREATE OR REPLACE FUNCTION rb64_xor_trans(internal, roaringbitmap64) 966 | RETURNS internal 967 | AS 'MODULE_PATHNAME', 'rb64_xor_trans' 968 | LANGUAGE C IMMUTABLE PARALLEL SAFE; 969 | 970 | CREATE OR REPLACE FUNCTION rb64_xor_combine(internal, internal) 971 | RETURNS internal 972 | AS 'MODULE_PATHNAME', 'rb64_xor_combine' 973 | LANGUAGE C IMMUTABLE PARALLEL SAFE; 974 | 975 | CREATE AGGREGATE rb64_xor_agg(roaringbitmap64)( 976 | SFUNC = rb64_xor_trans, 977 | STYPE = internal, 978 | FINALFUNC = rb64_final, 979 | COMBINEFUNC = rb64_xor_combine, 980 | SERIALFUNC = rb64_serialize, 981 | DESERIALFUNC = rb64_deserialize, 982 | PARALLEL = SAFE 983 | ); 984 | 985 | 986 | CREATE AGGREGATE rb64_xor_cardinality_agg(roaringbitmap64)( 987 | SFUNC = rb64_xor_trans, 988 | STYPE = internal, 989 | FINALFUNC = rb64_cardinality_final, 990 | COMBINEFUNC = rb64_xor_combine, 991 | SERIALFUNC = rb64_serialize, 992 | DESERIALFUNC = rb64_deserialize, 993 | PARALLEL = SAFE 994 | ); 995 | 996 | CREATE OR REPLACE FUNCTION rb64_build_trans(internal, bigint) 997 | RETURNS internal 998 | AS 'MODULE_PATHNAME', 'rb64_build_trans' 999 | LANGUAGE C IMMUTABLE PARALLEL SAFE; 1000 | 1001 | CREATE AGGREGATE rb64_build_agg(bigint)( 1002 | SFUNC = rb64_build_trans, 1003 | STYPE = internal, 1004 | FINALFUNC = rb64_final, 1005 | COMBINEFUNC = rb64_or_combine, 1006 | SERIALFUNC = rb64_serialize, 1007 | DESERIALFUNC = rb64_deserialize, 1008 | PARALLEL = SAFE 1009 | ); 1010 | -------------------------------------------------------------------------------- /sql/roaringbitmap64.sql: -------------------------------------------------------------------------------- 1 | -- 2 | -- Test roaringbitmap64 data type 3 | -- 4 | 5 | set client_min_messages = 'warning'; 6 | CREATE EXTENSION if not exists roaringbitmap; 7 | 8 | -- Test input and output 9 | 10 | set roaringbitmap.output_format='array'; 11 | set extra_float_digits = 0; 12 | 13 | select '{}'::roaringbitmap64; 14 | select ' { } '::roaringbitmap64; 15 | select '{ 1 }'::roaringbitmap64; 16 | select '{-1,2,555555,-4}'::roaringbitmap64; 17 | select '{ -1 , 2 , 555555 , -4 }'::roaringbitmap64; 18 | select '{ 1 , -2 , 555555 , -4 }'::roaringbitmap64; 19 | select '{ 1 , -2 , 555555 , -4 ,9223372036854775807,-9223372036854775808}'::roaringbitmap64; 20 | select roaringbitmap64('{ 1 , -2 , 555555 , -4 }'); 21 | 22 | set roaringbitmap.output_format='bytea'; 23 | select '{}'::roaringbitmap64; 24 | select '{ -1 , 2 , 555555 , -4 }'::roaringbitmap64; 25 | 26 | set roaringbitmap.output_format='array'; 27 | select '{}'::roaringbitmap64; 28 | select '\x0000000000000000'::roaringbitmap64; 29 | select '\x0200000000000000000000003a300000020000000000000008000000180000001a0000000200237affffffff3a30000001000000ffff010010000000fcffffff'::roaringbitmap64; 30 | 31 | -- Exception 32 | select ''::roaringbitmap64; 33 | select '{'::roaringbitmap64; 34 | select '{1'::roaringbitmap64; 35 | select '{1} x'::roaringbitmap64; 36 | select '{1x}'::roaringbitmap64; 37 | select '{-x}'::roaringbitmap64; 38 | select '{,}'::roaringbitmap64; 39 | select '{1,}'::roaringbitmap64; 40 | select '{1,xxx}'::roaringbitmap64; 41 | select '{1,3'::roaringbitmap64; 42 | select '{1,1'::roaringbitmap64; 43 | select '{1,-9223372036854775809}'::roaringbitmap64; 44 | select '{9223372036854775808}'::roaringbitmap64; 45 | 46 | -- Test Type cast 47 | select '{}'::roaringbitmap64::bytea; 48 | select '{1}'::roaringbitmap64::bytea; 49 | select '{1,9999}'::roaringbitmap64::bytea; 50 | select '{}'::roaringbitmap64::bytea::roaringbitmap64; 51 | select '{1}'::roaringbitmap64::bytea::roaringbitmap64; 52 | select '{1,9999,-88888}'::roaringbitmap64::bytea::roaringbitmap64; 53 | select roaringbitmap64('{1,9999,-88888}'::roaringbitmap64::bytea); 54 | 55 | select roaringbitmap('{}')::roaringbitmap64; 56 | select roaringbitmap('{0,1,9999,2147483647,-2147483648,-2,-1}')::roaringbitmap64; 57 | select roaringbitmap64('{}')::roaringbitmap; 58 | select roaringbitmap64('{0,1,9999,2147483647,-2147483648,-2,-1}')::roaringbitmap; 59 | 60 | -- Exception 61 | select roaringbitmap64('\x11'::bytea); 62 | select '\x11'::bytea::roaringbitmap64; 63 | select roaringbitmap64('{0,1,9999,2147483648,-2147483648,-2,-1}')::roaringbitmap; 64 | select roaringbitmap64('{0,1,9999,2147483647,-2147483649,-2,-1}')::roaringbitmap; 65 | 66 | -- Test Operator 67 | 68 | select roaringbitmap64('{}') & roaringbitmap64('{}'); 69 | select roaringbitmap64('{}') & roaringbitmap64('{3,4,5}'); 70 | select roaringbitmap64('{1,2,3}') & roaringbitmap64('{}'); 71 | select roaringbitmap64('{1,2,3}') & roaringbitmap64('{3,4,5}'); 72 | select roaringbitmap64('{1,-2,-3}') & roaringbitmap64('{-3,-4,5}'); 73 | 74 | select roaringbitmap64('{}') | roaringbitmap64('{}'); 75 | select roaringbitmap64('{}') | roaringbitmap64('{3,4,5}'); 76 | select roaringbitmap64('{1,2,3}') | roaringbitmap64('{}'); 77 | select roaringbitmap64('{1,2,3}') | roaringbitmap64('{3,4,5}'); 78 | select roaringbitmap64('{1,-2,-3}') | roaringbitmap64('{-3,-4,5}'); 79 | 80 | select roaringbitmap64('{}') | 6; 81 | select roaringbitmap64('{1,2,3}') | 6; 82 | select roaringbitmap64('{1,2,3}') | 1; 83 | select roaringbitmap64('{1,2,3}') | -1; 84 | select roaringbitmap64('{-1,-2,3}') | -1; 85 | 86 | select 6 | roaringbitmap64('{}'); 87 | select 6 | roaringbitmap64('{1,2,3}'); 88 | select 1 | roaringbitmap64('{1,2,3}'); 89 | select -1 | roaringbitmap64('{1,2,3}'); 90 | select -1 | roaringbitmap64('{-1,-2,3}'); 91 | 92 | select roaringbitmap64('{}') # roaringbitmap64('{}'); 93 | select roaringbitmap64('{}') # roaringbitmap64('{3,4,5}'); 94 | select roaringbitmap64('{1,2,3}') # roaringbitmap64('{}'); 95 | select roaringbitmap64('{1,2,3}') # roaringbitmap64('{3,4,5}'); 96 | select roaringbitmap64('{1,-2,-3}') # roaringbitmap64('{-3,-4,5}'); 97 | 98 | select roaringbitmap64('{}') - roaringbitmap64('{}'); 99 | select roaringbitmap64('{}') - roaringbitmap64('{3,4,5}'); 100 | select roaringbitmap64('{1,2,3}') - roaringbitmap64('{}'); 101 | select roaringbitmap64('{1,2,3}') - roaringbitmap64('{3,4,5}'); 102 | select roaringbitmap64('{1,-2,-3}') - roaringbitmap64('{-3,-4,5}'); 103 | 104 | select roaringbitmap64('{}') - 3; 105 | select roaringbitmap64('{1,2,3}') - 3; 106 | select roaringbitmap64('{1,2,3}') - 1; 107 | select roaringbitmap64('{1,2,3}') - -1; 108 | select roaringbitmap64('{-1,-2,3}') - -1; 109 | 110 | select roaringbitmap64('{}') << 2; 111 | select roaringbitmap64('{-2,-1,0,1,2,3,9223372036854775807,-9223372036854775808}') << 2; 112 | select roaringbitmap64('{-2,-1,0,1,2,3,9223372036854775807,-9223372036854775808}') << 1; 113 | select roaringbitmap64('{-2,-1,0,1,2,3,9223372036854775807,-9223372036854775808}') << 0; 114 | select roaringbitmap64('{-2,-1,0,1,2,3,9223372036854775807,-9223372036854775808}') << -1; 115 | select roaringbitmap64('{-2,-1,0,1,2,3,9223372036854775807,-9223372036854775808}') << -2; 116 | select roaringbitmap64('{-2,-1,0,1,2,3,9223372036854775807,-9223372036854775808}') << 4294967295; 117 | select roaringbitmap64('{-2,-1,0,1,2,3,9223372036854775807,-9223372036854775808}') << 9223372036854775807; 118 | select roaringbitmap64('{-2,-1,0,1,2,3,9223372036854775807,-9223372036854775808}') << -4294967295; 119 | select roaringbitmap64('{-2,-1,0,1,2,3,9223372036854775807,-9223372036854775808}') << -9223372036854775807; 120 | 121 | select roaringbitmap64('{}') >> 2; 122 | select roaringbitmap64('{-2,-1,0,1,2,3,9223372036854775807,-9223372036854775808}') >> 2; 123 | select roaringbitmap64('{-2,-1,0,1,2,3,9223372036854775807,-9223372036854775808}') >> 1; 124 | select roaringbitmap64('{-2,-1,0,1,2,3,9223372036854775807,-9223372036854775808}') >> 0; 125 | select roaringbitmap64('{-2,-1,0,1,2,3,9223372036854775807,-9223372036854775808}') >> -1; 126 | select roaringbitmap64('{-2,-1,0,1,2,3,9223372036854775807,-9223372036854775808}') >> -2; 127 | select roaringbitmap64('{-2,-1,0,1,2,3,9223372036854775807,-9223372036854775808}') >> 4294967295; 128 | select roaringbitmap64('{-2,-1,0,1,2,3,9223372036854775807,-9223372036854775808}') >> 9223372036854775807; 129 | select roaringbitmap64('{-2,-1,0,1,2,3,9223372036854775807,-9223372036854775808}') >> -4294967295; 130 | select roaringbitmap64('{-2,-1,0,1,2,3,9223372036854775807,-9223372036854775808}') >> -9223372036854775807; 131 | 132 | select roaringbitmap64('{}') @> roaringbitmap64('{}'); 133 | select roaringbitmap64('{}') @> roaringbitmap64('{3,4,5}'); 134 | select roaringbitmap64('{1,2,3}') @> roaringbitmap64('{}'); 135 | select roaringbitmap64('{1,2,3}') @> roaringbitmap64('{3,4,5}'); 136 | select roaringbitmap64('{1,2,3}') @> roaringbitmap64('{3,2}'); 137 | select roaringbitmap64('{1,-2,-3}') @> roaringbitmap64('{-3,1}'); 138 | 139 | select roaringbitmap64('{}') @> 2; 140 | select roaringbitmap64('{1,2,3}') @> 20; 141 | select roaringbitmap64('{1,2,3}') @> 1; 142 | select roaringbitmap64('{1,2,3}') @> -1; 143 | select roaringbitmap64('{-1,-2,3}') @> -1; 144 | 145 | select roaringbitmap64('{}') <@ roaringbitmap64('{}'); 146 | select roaringbitmap64('{}') <@ roaringbitmap64('{3,4,5}'); 147 | select roaringbitmap64('{1,2,3}') <@ roaringbitmap64('{}'); 148 | select roaringbitmap64('{1,2,3}') <@ roaringbitmap64('{3,4,5}'); 149 | select roaringbitmap64('{2,3}') <@ roaringbitmap64('{1,3,2}'); 150 | select roaringbitmap64('{1,-3}') <@ roaringbitmap64('{-3,1,1000}'); 151 | 152 | select 6 <@ roaringbitmap64('{}'); 153 | select 3 <@ roaringbitmap64('{1,2,3}'); 154 | select 1 <@ roaringbitmap64('{1,2,3}'); 155 | select -1 <@ roaringbitmap64('{1,2,3}'); 156 | select -1 <@ roaringbitmap64('{-1,-2,3}'); 157 | 158 | select roaringbitmap64('{}') && roaringbitmap64('{}'); 159 | select roaringbitmap64('{}') && roaringbitmap64('{3,4,5}'); 160 | select roaringbitmap64('{1,2,3}') && roaringbitmap64('{}'); 161 | select roaringbitmap64('{1,2,3}') && roaringbitmap64('{3,4,5}'); 162 | select roaringbitmap64('{1,-2,-3}') && roaringbitmap64('{-3,-4,5}'); 163 | 164 | select roaringbitmap64('{}') = roaringbitmap64('{}'); 165 | select roaringbitmap64('{}') = roaringbitmap64('{3,4,5}'); 166 | select roaringbitmap64('{1,2,3}') = roaringbitmap64('{}'); 167 | select roaringbitmap64('{1,2,3}') = roaringbitmap64('{3,1,2}'); 168 | select roaringbitmap64('{1,-2,-3}') = roaringbitmap64('{-3,-4,5}'); 169 | 170 | select roaringbitmap64('{}') <> roaringbitmap64('{}'); 171 | select roaringbitmap64('{}') <> roaringbitmap64('{3,4,5}'); 172 | select roaringbitmap64('{1,2,3}') <> roaringbitmap64('{}'); 173 | select roaringbitmap64('{1,2,3}') <> roaringbitmap64('{3,1,2}'); 174 | select roaringbitmap64('{1,-2,-3}') <> roaringbitmap64('{-3,-4,5}'); 175 | 176 | -- Test the functions with one bitmap variable 177 | 178 | select rb64_build(NULL); 179 | select rb64_build('{}'::int[]); 180 | select rb64_build('{1}'::int[]); 181 | select rb64_build('{-1,2,555555,-4}'::int[]); 182 | select rb64_build('{1,-2,555555,-4,9223372036854775807,-9223372036854775808}'::bigint[]); 183 | 184 | select rb64_to_array(NULL); 185 | select rb64_to_array('{}'::roaringbitmap64); 186 | select rb64_to_array('{1}'::roaringbitmap64); 187 | select rb64_to_array('{-1,2,555555,-4}'::roaringbitmap64); 188 | select rb64_to_array('{1,-2,555555,-4,9223372036854775807,-9223372036854775808}'::roaringbitmap64); 189 | 190 | select rb64_is_empty(NULL); 191 | select rb64_is_empty('{}'); 192 | select rb64_is_empty('{1}'); 193 | select rb64_is_empty('{1,10,100}'); 194 | select rb64_is_empty('{1,10,100,-4,9223372036854775807,-9223372036854775808}'); 195 | 196 | select rb64_cardinality(NULL); 197 | select rb64_cardinality('{}'); 198 | select rb64_cardinality('{1}'); 199 | select rb64_cardinality('{1,10,100}'); 200 | select rb64_cardinality('{1,10,100,-4,9223372036854775807,-9223372036854775808}'); 201 | 202 | select rb64_max(NULL); 203 | select rb64_max('{}'); 204 | select rb64_max('{1}'); 205 | select rb64_max('{1,10,100}'); 206 | select rb64_max('{1,10,100,9223372036854775807,-9223372036854775808,-1}'); 207 | 208 | select rb64_min(NULL); 209 | select rb64_min('{}'); 210 | select rb64_min('{1}'); 211 | select rb64_min('{1,10,100}'); 212 | select rb64_min('{1,10,100,9223372036854775807,-9223372036854775808,-1}'); 213 | 214 | select rb64_iterate(NULL); 215 | select rb64_iterate('{}'); 216 | select rb64_iterate('{1}'); 217 | select rb64_iterate('{1,10,100}'); 218 | select rb64_iterate('{1,10,100,9223372036854775807,-9223372036854775808,-1}'); 219 | 220 | select rb64_runoptimize(NULL); 221 | select rb64_runoptimize('{}'); 222 | select rb64_runoptimize('{1}'); 223 | select rb64_runoptimize('{1,10,100}'); 224 | select rb64_runoptimize('{1,10,100,9223372036854775807,-9223372036854775808,-1}'); 225 | 226 | -- Test the functions with two bitmap variables 227 | 228 | select rb64_and(NULL,'{1,10,100}'); 229 | select rb64_and('{1,10,100}',NULL); 230 | select rb64_and('{}','{1,10,100}'); 231 | select rb64_and('{1,10,100}','{}'); 232 | select rb64_and('{2}','{1,10,100}'); 233 | select rb64_and('{1,2,10}','{1,10,100}'); 234 | select rb64_and('{1,10}','{1,10,100}'); 235 | select rb64_and('{1,10,9223372036854775807,-9223372036854775808,-1}','{1,10,100,-9223372036854775808,-1}'); 236 | 237 | select rb64_and_cardinality(NULL,'{1,10,100}'); 238 | select rb64_and_cardinality('{1,10,100}',NULL); 239 | select rb64_and_cardinality('{}','{1,10,100}'); 240 | select rb64_and_cardinality('{1,10,100}','{}'); 241 | select rb64_and_cardinality('{2}','{1,10,100}'); 242 | select rb64_and_cardinality('{1,2,10}','{1,10,100}'); 243 | select rb64_and_cardinality('{1,10}','{1,10,100}'); 244 | select rb64_and_cardinality('{1,10,9223372036854775807,-9223372036854775808,-1}','{1,10,100,-9223372036854775808,-1}'); 245 | 246 | select rb64_or(NULL,'{1,10,100}'); 247 | select rb64_or('{1,10,100}',NULL); 248 | select rb64_or('{}','{1,10,100}'); 249 | select rb64_or('{1,10,100}','{}'); 250 | select rb64_or('{2}','{1,10,100}'); 251 | select rb64_or('{1,2,10}','{1,10,100}'); 252 | select rb64_or('{1,10}','{1,10,100}'); 253 | select rb64_or('{1,10,9223372036854775807,-9223372036854775808,-1}','{1,10,100,-9223372036854775808,-1}'); 254 | 255 | select rb64_or_cardinality(NULL,'{1,10,100}'); 256 | select rb64_or_cardinality('{1,10,100}',NULL); 257 | select rb64_or_cardinality('{}','{1,10,100}'); 258 | select rb64_or_cardinality('{1,10,100}','{}'); 259 | select rb64_or_cardinality('{2}','{1,10,100}'); 260 | select rb64_or_cardinality('{1,2,10}','{1,10,100}'); 261 | select rb64_or_cardinality('{1,10}','{1,10,100}'); 262 | select rb64_or_cardinality('{1,10,9223372036854775807,-9223372036854775808,-1}','{1,10,100,-9223372036854775808,-1}'); 263 | 264 | select rb64_xor(NULL,'{1,10,100}'); 265 | select rb64_xor('{1,10,100}',NULL); 266 | select rb64_xor('{}','{1,10,100}'); 267 | select rb64_xor('{1,10,100}','{}'); 268 | select rb64_xor('{2}','{1,10,100}'); 269 | select rb64_xor('{1,2,10}','{1,10,100}'); 270 | select rb64_xor('{1,10}','{1,10,100}'); 271 | select rb64_xor('{1,10,9223372036854775807,-9223372036854775808,-1}','{1,10,100,-9223372036854775808,-1}'); 272 | 273 | select rb64_xor_cardinality(NULL,'{1,10,100}'); 274 | select rb64_xor_cardinality('{1,10,100}',NULL); 275 | select rb64_xor_cardinality('{}','{1,10,100}'); 276 | select rb64_xor_cardinality('{1,10,100}','{}'); 277 | select rb64_xor_cardinality('{2}','{1,10,100}'); 278 | select rb64_xor_cardinality('{1,2,10}','{1,10,100}'); 279 | select rb64_xor_cardinality('{1,10}','{1,10,100}'); 280 | select rb64_xor_cardinality('{1,10,9223372036854775807,-9223372036854775808,-1}','{1,10,100,-9223372036854775808,-1}'); 281 | 282 | select rb64_equals(NULL,'{1,10,100}'); 283 | select rb64_equals('{1,10,100}',NULL); 284 | select rb64_equals('{}','{1,10,100}'); 285 | select rb64_equals('{1,10,100}','{}'); 286 | select rb64_equals('{2}','{1,10,100}'); 287 | select rb64_equals('{1,2,10}','{1,10,100}'); 288 | select rb64_equals('{1,10}','{1,10,100}'); 289 | select rb64_equals('{1,10,100}','{1,10,100}'); 290 | select rb64_equals('{1,10,100,10}','{1,100,10}'); 291 | select rb64_equals('{1,10,9223372036854775807,-9223372036854775808,-1}','{1,10,100,-9223372036854775808,-1}'); 292 | select rb64_equals('{1,10,9223372036854775807,-9223372036854775808,-1}','{1,10,9223372036854775807,-9223372036854775808,-1}'); 293 | 294 | select rb64_intersect(NULL,'{1,10,100}'); 295 | select rb64_intersect('{1,10,100}',NULL); 296 | select rb64_intersect('{}','{1,10,100}'); 297 | select rb64_intersect('{1,10,100}','{}'); 298 | select rb64_intersect('{2}','{1,10,100}'); 299 | select rb64_intersect('{1,2,10}','{1,10,100}'); 300 | select rb64_intersect('{1,10}','{1,10,100}'); 301 | select rb64_intersect('{1,10,100}','{1,10,100}'); 302 | select rb64_intersect('{1,10,100,10}','{1,100,10}'); 303 | select rb64_intersect('{1,10,9223372036854775807,-9223372036854775808,-1}','{1,10,100,-9223372036854775808,-1}'); 304 | 305 | select rb64_andnot(NULL,'{1,10,100}'); 306 | select rb64_andnot('{1,10,100}',NULL); 307 | select rb64_andnot('{}','{1,10,100}'); 308 | select rb64_andnot('{1,10,100}','{}'); 309 | select rb64_andnot('{2}','{1,10,100}'); 310 | select rb64_andnot('{1,2,10}','{1,10,100}'); 311 | select rb64_andnot('{1,10}','{1,10,100}'); 312 | select rb64_andnot('{1,10,100}','{1,10,100}'); 313 | select rb64_andnot('{1,10,100,10}','{1,100,10}'); 314 | select rb64_andnot('{1,10,9223372036854775807,-9223372036854775808,-1}','{1,10,100,-9223372036854775808,-1}'); 315 | 316 | select rb64_andnot_cardinality(NULL,'{1,10,100}'); 317 | select rb64_andnot_cardinality('{1,10,100}',NULL); 318 | select rb64_andnot_cardinality('{}','{1,10,100}'); 319 | select rb64_andnot_cardinality('{1,10,100}','{}'); 320 | select rb64_andnot_cardinality('{2}','{1,10,100}'); 321 | select rb64_andnot_cardinality('{1,2,10}','{1,10,100}'); 322 | select rb64_andnot_cardinality('{1,10}','{1,10,100}'); 323 | select rb64_andnot_cardinality('{1,10,100}','{1,10,100}'); 324 | select rb64_andnot_cardinality('{1,10,100,10}','{1,100,10}'); 325 | select rb64_andnot_cardinality('{1,10,9223372036854775807,-9223372036854775808,-1}','{1,10,100,-9223372036854775808,-1}'); 326 | 327 | select rb64_jaccard_dist(NULL,'{1,10,100}'); 328 | select rb64_jaccard_dist('{1,10,100}',NULL); 329 | select rb64_jaccard_dist('{}','{1,10,100}'); 330 | select rb64_jaccard_dist('{1,10,100}','{}'); 331 | select rb64_jaccard_dist('{2}','{1,10,100}'); 332 | select rb64_jaccard_dist('{1,2,10}','{1,10,100}'); 333 | select rb64_jaccard_dist('{1,10,11,12}','{1,10,100}'); 334 | select rb64_jaccard_dist('{1,10,100}','{1,10,11,12}'); 335 | select rb64_jaccard_dist('{1,10,100}','{1,10,100}'); 336 | select rb64_jaccard_dist('{1,10,-100}','{1,10,-100}'); 337 | select rb64_jaccard_dist('{1,10,100}','{1,10,-100}'); 338 | select rb64_jaccard_dist('{1,10,9223372036854775807,-9223372036854775808,-1}','{1,10,100,-9223372036854775808,-1}'); 339 | 340 | -- Test other functions 341 | 342 | select rb64_rank(NULL,0); 343 | select rb64_rank('{}',0); 344 | select rb64_rank('{1,10,100}',0); 345 | select rb64_rank('{1,10,100}',1); 346 | select rb64_rank('{1,10,100}',99); 347 | select rb64_rank('{1,10,100}',100); 348 | select rb64_rank('{1,10,100}',101); 349 | select rb64_rank('{1,10,100,-3,-1}',-2); 350 | 351 | select rb64_remove(NULL,0); 352 | select rb64_remove('{}',0); 353 | select rb64_remove('{1}',1); 354 | select rb64_remove('{1,10,100}',0); 355 | select rb64_remove('{1,10,100}',1); 356 | select rb64_remove('{1,10,100}',99); 357 | select rb64_remove('{1,10,100,9223372036854775807,-9223372036854775808,-1}',-9223372036854775808); 358 | 359 | select rb64_fill(NULL,-1,-1); 360 | select rb64_fill('{}',-1,-1); 361 | select rb64_fill('{}',0,1); 362 | select rb64_fill('{}',0,2); 363 | select rb64_fill('{1,10,100}',10,10); 364 | select rb64_fill('{1,10,100}',10,11); 365 | select rb64_fill('{1,10,100}',10,12); 366 | select rb64_fill('{1,10,100}',10,13); 367 | select rb64_fill('{1,10,100}',10,20); 368 | select rb64_fill('{1,10,100}',-1,-1); 369 | select rb64_fill('{1,10,100,9223372036854775807,-9223372036854775808,-1}',9223372036854775800,9223372036854775807); 370 | select rb64_cardinality(rb64_fill('{1,10,100}',2,1000000000)); 371 | select rb64_cardinality(rb64_fill('{1,10,100}',0,5000000000)); 372 | select rb64_cardinality(rb64_fill('{1,10,100,9223372036854775807,-9223372036854775808,-1}',9223372036854775800,9223372036854775807)); 373 | 374 | select rb64_index(NULL,3); 375 | select rb64_index('{1,2,3}',NULL); 376 | select rb64_index('{}',3); 377 | select rb64_index('{1}',3); 378 | select rb64_index('{1}',1); 379 | select rb64_index('{1,10,100}',10); 380 | select rb64_index('{1,10,100}',99); 381 | select rb64_index('{1,10,-100}',-100); 382 | 383 | select rb64_clear(NULL,0,10); 384 | select rb64_clear('{}',0,10); 385 | select rb64_clear('{1,10,100}',0,10); 386 | select rb64_clear('{1,10,100}',3,3); 387 | select rb64_clear('{1,10,100}',-3,3); 388 | select rb64_clear('{1,10,100}',0,-1); 389 | select rb64_clear('{1,10,100}',9,9); 390 | select rb64_clear('{1,10,100}',2,1000000000); 391 | select rb64_clear('{0,1,10,100,-2,-1}',1,4294967295); 392 | select rb64_clear('{0,1,10,100,-2,-1}',0,4294967296); 393 | select rb64_clear('{0,1,10,100,-2,-1}',1,-1); 394 | select rb64_clear('{0,1,10,100,-2,-1}',0,9223372036854775800); 395 | 396 | select rb64_flip(NULL,0,10); 397 | select rb64_flip('{}',0,10); 398 | select rb64_flip('{1,10,100}',9,100); 399 | select rb64_flip('{1,10,100}',10,101); 400 | select rb64_flip('{1,10,100}',-3,3); 401 | select rb64_flip('{1,10,100}',-1,-1); 402 | select rb64_flip('{1,10,100}',9,9); 403 | select rb64_flip('{1,10,100,9223372036854775807,-9223372036854775808,-1}',9223372036854775800,9223372036854775807); 404 | select rb64_cardinality(rb64_flip('{1,10,100}',2,1000000000)); 405 | select rb64_cardinality(rb64_flip('{1,10,100}',-1,5000000000)); 406 | select rb64_cardinality(rb64_flip('{1,10,100,9223372036854775807,-9223372036854775808,-1}',9223372036854775800,9223372036854775807)); 407 | 408 | 409 | select rb64_range(NULL,0,10); 410 | select rb64_range('{}',0,10); 411 | select rb64_range('{1,10,100}',0,10); 412 | select rb64_range('{1,10,100}',3,3); 413 | select rb64_range('{1,10,100}',-3,3); 414 | select rb64_range('{1,10,100}',0,-1); 415 | select rb64_range('{1,10,100}',9,9); 416 | select rb64_range('{1,10,100}',2,1000000000); 417 | select rb64_range('{0,1,10,100,-2,-1}',1,4294967295); 418 | select rb64_range('{0,1,10,100,-2,-1}',0,4294967296); 419 | select rb64_range('{0,1,10,100,-2,-1}',9223372036854775800,9223372036854775807); 420 | select rb64_range('{0,1,10,100,-2,-1}',1,9223372036854775807); 421 | select rb64_range('{0,1,10,100,-2,-1}',1,0); 422 | 423 | select rb64_range_cardinality(NULL,0,10); 424 | select rb64_range_cardinality('{}',0,10); 425 | select rb64_range_cardinality('{1,10,100}',0,10); 426 | select rb64_range_cardinality('{1,10,100}',3,3); 427 | select rb64_range_cardinality('{1,10,100}',-3,3); 428 | select rb64_range_cardinality('{1,10,100}',0,-1); 429 | select rb64_range_cardinality('{1,10,100}',9,9); 430 | select rb64_range_cardinality('{1,10,100}',2,1000000000); 431 | select rb64_range_cardinality('{0,1,10,100,-2,-1}',1,4294967295); 432 | select rb64_range_cardinality('{0,1,10,100,-2,-1}',0,4294967296); 433 | select rb64_range_cardinality('{0,1,10,100,-2,-1}',9223372036854775800,9223372036854775807); 434 | select rb64_range_cardinality('{0,1,10,100,-2,-1}',1,9223372036854775807); 435 | select rb64_range_cardinality('{0,1,10,100,-2,-1}',1,0); 436 | 437 | select rb64_select(NULL,10); 438 | select rb64_select('{}',10); 439 | select rb64_select('{0,1,2,10,100,1000,9223372036854775807,-9223372036854775808,-2,-1}',0); 440 | select rb64_select('{0,1,2,10,100,1000,9223372036854775807,-9223372036854775808,-2,-1}',1); 441 | select rb64_select('{0,1,2,10,100,1000,9223372036854775807,-9223372036854775808,-2,-1}',2); 442 | select rb64_select('{0,1,2,10,100,1000,9223372036854775807,-9223372036854775808,-2,-1}',2,0); 443 | select rb64_select('{0,1,2,10,100,1000,9223372036854775807,-9223372036854775808,-2,-1}',2,1); 444 | select rb64_select('{0,1,2,10,100,1000,9223372036854775807,-9223372036854775808,-2,-1}',2,1,true); 445 | select rb64_select('{0,1,2,10,100,1000,9223372036854775807,-9223372036854775808,-2,-1}',2,1,true,9); 446 | select rb64_select('{0,1,2,10,100,1000,9223372036854775807,-9223372036854775808,-2,-1}',2,1,true,9,4294967295); 447 | select rb64_select('{0,1,2,10,100,1000,9223372036854775807,-9223372036854775808,-2,-1}',2,1,false); 448 | select rb64_select('{0,1,2,10,100,1000,9223372036854775807,-9223372036854775808,-2,-1}',2,1,false,9); 449 | select rb64_select('{0,1,2,10,100,1000,9223372036854775807,-9223372036854775808,-2,-1}',2,1,false,10); 450 | select rb64_select('{0,1,2,10,100,1000,9223372036854775807,-9223372036854775808,-2,-1}',2,1,false,10,10); 451 | select rb64_select('{0,1,2,10,100,1000,9223372036854775807,-9223372036854775808,-2,-1}',2,1,false,-10,100); 452 | select rb64_select('{0,1,2,10,100,1000,9223372036854775807,-9223372036854775808,-2,-1}',2,1,false,-10,-10); 453 | select rb64_select('{0,1,2,10,100,1000,9223372036854775807,-9223372036854775808,-2,-1}',2,1,false,10,10001); 454 | select rb64_select('{0,1,2,10,100,1000,9223372036854775807,-9223372036854775808,-2,-1}',2,1,true,10,10001); 455 | 456 | 457 | -- Test aggregate 458 | 459 | select rb64_and_agg(id) from (values (NULL::roaringbitmap64)) t(id); 460 | select rb64_and_agg(id) from (values (roaringbitmap64('{}'))) t(id); 461 | select rb64_and_agg(id) from (values (roaringbitmap64('{1}'))) t(id); 462 | select rb64_and_agg(id) from (values (roaringbitmap64('{1,10,100}'))) t(id); 463 | select rb64_and_agg(id) from (values (roaringbitmap64('{1,10,100}')),(roaringbitmap64('{2,10}'))) t(id); 464 | select rb64_and_agg(id) from (values (roaringbitmap64('{1,10,100}')),(roaringbitmap64('{1,10,100}'))) t(id); 465 | select rb64_and_agg(id) from (values (NULL),(roaringbitmap64('{1,10,100}')),(roaringbitmap64('{}'))) t(id); 466 | select rb64_and_agg(id) from (values (NULL),(roaringbitmap64('{1,10,100}')),(roaringbitmap64('{1}'))) t(id); 467 | select rb64_and_agg(id) from (values (NULL),(roaringbitmap64('{1,10,100}')),(roaringbitmap64('{2}'))) t(id); 468 | select rb64_and_agg(id) from (values (roaringbitmap64('{1,10,100}')),(NULL),(roaringbitmap64('{2,10}'))) t(id); 469 | select rb64_and_agg(id) from (values (NULL),(roaringbitmap64('{1,10,100}')),(NULL),(roaringbitmap64('{1,10,100,101}')),(NULL)) t(id); 470 | select rb64_and_agg(id) from (values (NULL),(roaringbitmap64('{1,10,100,9223372036854775807}')),(NULL),(roaringbitmap64('{1,10,100,101,9223372036854775807,-9223372036854775808,-2}')),(NULL)) t(id); 471 | 472 | select rb64_and_cardinality_agg(id) from (values (NULL::roaringbitmap64)) t(id); 473 | select rb64_and_cardinality_agg(id) from (values (roaringbitmap64('{}'))) t(id); 474 | select rb64_and_cardinality_agg(id) from (values (roaringbitmap64('{1}'))) t(id); 475 | select rb64_and_cardinality_agg(id) from (values (roaringbitmap64('{1,10,100}'))) t(id); 476 | select rb64_and_cardinality_agg(id) from (values (roaringbitmap64('{1,10,100}')),(roaringbitmap64('{2,10}'))) t(id); 477 | select rb64_and_cardinality_agg(id) from (values (roaringbitmap64('{1,10,100}')),(roaringbitmap64('{1,10,100}'))) t(id); 478 | select rb64_and_cardinality_agg(id) from (values (NULL),(roaringbitmap64('{1,10,100}')),(roaringbitmap64('{}'))) t(id); 479 | select rb64_and_cardinality_agg(id) from (values (NULL),(roaringbitmap64('{1,10,100}')),(roaringbitmap64('{1}'))) t(id); 480 | select rb64_and_cardinality_agg(id) from (values (NULL),(roaringbitmap64('{1,10,100}')),(roaringbitmap64('{2}'))) t(id); 481 | select rb64_and_cardinality_agg(id) from (values (roaringbitmap64('{1,10,100}')),(NULL),(roaringbitmap64('{2,10}'))) t(id); 482 | select rb64_and_cardinality_agg(id) from (values (NULL),(roaringbitmap64('{1,10,100}')),(NULL),(roaringbitmap64('{1,10,100,101}')),(NULL)) t(id); 483 | select rb64_and_cardinality_agg(id) from (values (NULL),(roaringbitmap64('{1,10,100,9223372036854775807}')),(NULL),(roaringbitmap64('{1,10,100,101,9223372036854775807,-9223372036854775808,-2}')),(NULL)) t(id); 484 | 485 | 486 | select rb64_or_agg(id) from (values (NULL::roaringbitmap64)) t(id); 487 | select rb64_or_agg(id) from (values (roaringbitmap64('{}'))) t(id); 488 | select rb64_or_agg(id) from (values (roaringbitmap64('{1}'))) t(id); 489 | select rb64_or_agg(id) from (values (roaringbitmap64('{1,10,100}'))) t(id); 490 | select rb64_or_agg(id) from (values (roaringbitmap64('{1,10,100}')),(roaringbitmap64('{2,10}'))) t(id); 491 | select rb64_or_agg(id) from (values (roaringbitmap64('{1,10,100}')),(roaringbitmap64('{1,10,100}'))) t(id); 492 | select rb64_or_agg(id) from (values (NULL),(roaringbitmap64('{1,10,100}')),(roaringbitmap64('{}'))) t(id); 493 | select rb64_or_agg(id) from (values (NULL),(roaringbitmap64('{1,10,100}')),(roaringbitmap64('{1}'))) t(id); 494 | select rb64_or_agg(id) from (values (NULL),(roaringbitmap64('{1,10,100}')),(roaringbitmap64('{2}'))) t(id); 495 | select rb64_or_agg(id) from (values (roaringbitmap64('{1,10,100}')),(NULL),(roaringbitmap64('{2,10}'))) t(id); 496 | select rb64_or_agg(id) from (values (NULL),(roaringbitmap64('{1,10,100}')),(NULL),(roaringbitmap64('{1,10,100,101}')),(NULL)) t(id); 497 | select rb64_or_agg(id) from (values (NULL),(roaringbitmap64('{1,10,100,9223372036854775807}')),(NULL),(roaringbitmap64('{1,10,100,101,9223372036854775807,-9223372036854775808,-2}')),(NULL)) t(id); 498 | 499 | select rb64_or_cardinality_agg(id) from (values (NULL::roaringbitmap64)) t(id); 500 | select rb64_or_cardinality_agg(id) from (values (roaringbitmap64('{}'))) t(id); 501 | select rb64_or_cardinality_agg(id) from (values (roaringbitmap64('{1}'))) t(id); 502 | select rb64_or_cardinality_agg(id) from (values (roaringbitmap64('{1,10,100}'))) t(id); 503 | select rb64_or_cardinality_agg(id) from (values (roaringbitmap64('{1,10,100}')),(roaringbitmap64('{2,10}'))) t(id); 504 | select rb64_or_cardinality_agg(id) from (values (roaringbitmap64('{1,10,100}')),(roaringbitmap64('{1,10,100}'))) t(id); 505 | select rb64_or_cardinality_agg(id) from (values (NULL),(roaringbitmap64('{1,10,100}')),(roaringbitmap64('{}'))) t(id); 506 | select rb64_or_cardinality_agg(id) from (values (NULL),(roaringbitmap64('{1,10,100}')),(roaringbitmap64('{1}'))) t(id); 507 | select rb64_or_cardinality_agg(id) from (values (NULL),(roaringbitmap64('{1,10,100}')),(roaringbitmap64('{2}'))) t(id); 508 | select rb64_or_cardinality_agg(id) from (values (roaringbitmap64('{1,10,100}')),(NULL),(roaringbitmap64('{2,10}'))) t(id); 509 | select rb64_or_cardinality_agg(id) from (values (NULL),(roaringbitmap64('{1,10,100}')),(NULL),(roaringbitmap64('{1,10,100,101}')),(NULL)) t(id); 510 | select rb64_or_cardinality_agg(id) from (values (NULL),(roaringbitmap64('{1,10,100,9223372036854775807}')),(NULL),(roaringbitmap64('{1,10,100,101,9223372036854775807,-9223372036854775808,-2}')),(NULL)) t(id); 511 | 512 | select rb64_xor_agg(id) from (values (NULL::roaringbitmap64)) t(id); 513 | select rb64_xor_agg(id) from (values (roaringbitmap64('{}'))) t(id); 514 | select rb64_xor_agg(id) from (values (roaringbitmap64('{1}'))) t(id); 515 | select rb64_xor_agg(id) from (values (roaringbitmap64('{1,10,100}'))) t(id); 516 | select rb64_xor_agg(id) from (values (roaringbitmap64('{1,10,100}')),(roaringbitmap64('{2,10}'))) t(id); 517 | select rb64_xor_agg(id) from (values (roaringbitmap64('{1,10,100}')),(roaringbitmap64('{1,10,100}'))) t(id); 518 | select rb64_xor_agg(id) from (values (NULL),(roaringbitmap64('{1,10,100}')),(roaringbitmap64('{}'))) t(id); 519 | select rb64_xor_agg(id) from (values (NULL),(roaringbitmap64('{1,10,100}')),(roaringbitmap64('{1}'))) t(id); 520 | select rb64_xor_agg(id) from (values (NULL),(roaringbitmap64('{1,10,100}')),(roaringbitmap64('{2}'))) t(id); 521 | select rb64_xor_agg(id) from (values (NULL),(roaringbitmap64('{1,10,100}')),(roaringbitmap64('{2,10}'))) t(id); 522 | select rb64_xor_agg(id) from (values (roaringbitmap64('{1,10,100}')),(NULL),(roaringbitmap64('{1,10,100,101}'))) t(id); 523 | select rb64_xor_agg(id) from (values (NULL),(roaringbitmap64('{1,10,100}')),(NULL),(roaringbitmap64('{1,10,101}')),(roaringbitmap64('{1,100,102}')),(NULL)) t(id); 524 | select rb64_xor_agg(id) from (values (NULL),(roaringbitmap64('{1,10,100,9223372036854775807}')),(NULL),(roaringbitmap64('{1,10,100,101,9223372036854775807,-9223372036854775808,-2}')),(NULL)) t(id); 525 | 526 | select rb64_xor_cardinality_agg(id) from (values (NULL::roaringbitmap64)) t(id); 527 | select rb64_xor_cardinality_agg(id) from (values (roaringbitmap64('{}'))) t(id); 528 | select rb64_xor_cardinality_agg(id) from (values (roaringbitmap64('{1}'))) t(id); 529 | select rb64_xor_cardinality_agg(id) from (values (roaringbitmap64('{1,10,100}'))) t(id); 530 | select rb64_xor_cardinality_agg(id) from (values (roaringbitmap64('{1,10,100}')),(roaringbitmap64('{2,10}'))) t(id); 531 | select rb64_xor_cardinality_agg(id) from (values (roaringbitmap64('{1,10,100}')),(roaringbitmap64('{1,10,100}'))) t(id); 532 | select rb64_xor_cardinality_agg(id) from (values (NULL),(roaringbitmap64('{1,10,100}')),(roaringbitmap64('{}'))) t(id); 533 | select rb64_xor_cardinality_agg(id) from (values (NULL),(roaringbitmap64('{1,10,100}')),(roaringbitmap64('{1}'))) t(id); 534 | select rb64_xor_cardinality_agg(id) from (values (NULL),(roaringbitmap64('{1,10,100}')),(roaringbitmap64('{2}'))) t(id); 535 | select rb64_xor_cardinality_agg(id) from (values (NULL),(roaringbitmap64('{1,10,100}')),(roaringbitmap64('{2,10}'))) t(id); 536 | select rb64_xor_cardinality_agg(id) from (values (roaringbitmap64('{1,10,100}')),(NULL),(roaringbitmap64('{1,10,100,101}'))) t(id); 537 | select rb64_xor_cardinality_agg(id) from (values (NULL),(roaringbitmap64('{1,10,100}')),(NULL),(roaringbitmap64('{1,10,101}')),(roaringbitmap64('{1,100,102}')),(NULL)) t(id); 538 | select rb64_xor_cardinality_agg(id) from (values (NULL),(roaringbitmap64('{1,10,100,9223372036854775807}')),(NULL),(roaringbitmap64('{1,10,100,101,9223372036854775807,-9223372036854775808,-2}')),(NULL)) t(id); 539 | 540 | select rb64_build_agg(id) from (values (NULL::int)) t(id); 541 | select rb64_build_agg(id) from (values (1)) t(id); 542 | select rb64_build_agg(id) from (values (1),(10)) t(id); 543 | select rb64_build_agg(id) from (values (1),(10),(10),(100),(1)) t(id); 544 | select rb64_build_agg(id) from (values (1),(10),(10),(100),(1),(-2),(9223372036854775807),(-9223372036854775808)) t(id); 545 | 546 | -- Test Windows aggregate 547 | 548 | with t(id,bitmap) as( 549 | values(0,NULL),(1,roaringbitmap64('{1,10}')),(2,NULL),(3,roaringbitmap64('{2,10}')),(4,roaringbitmap64('{10,100}')) 550 | ) 551 | select id,bitmap,rb64_and_agg(bitmap) over(order by id),rb64_and_cardinality_agg(bitmap) over(order by id) from t; 552 | 553 | with t(id,bitmap) as( 554 | values(0,NULL),(1,roaringbitmap64('{1,10}')),(2,NULL),(3,roaringbitmap64('{2,10}')),(4,roaringbitmap64('{10,100}')) 555 | ) 556 | select id,bitmap,rb64_or_agg(bitmap) over(order by id),rb64_or_cardinality_agg(bitmap) over(order by id) from t; 557 | 558 | with t(id,bitmap) as( 559 | values(0,NULL),(1,roaringbitmap64('{1,10}')),(2,NULL),(3,roaringbitmap64('{2,10}')),(4,roaringbitmap64('{10,100}')) 560 | ) 561 | select id,bitmap,rb64_xor_agg(bitmap) over(order by id),rb64_xor_cardinality_agg(bitmap) over(order by id) from t; 562 | 563 | with t(id) as( 564 | values(0),(1),(2),(NULL),(4),(NULL) 565 | ) 566 | select id,rb64_build_agg(id) over(order by id) from t; 567 | 568 | with t(id,bitmap) as( 569 | values(0,NULL),(1,roaringbitmap64('{1,10}')),(2,NULL),(3,roaringbitmap64('{2,10}')),(4,roaringbitmap64('{10,100}')),(5,roaringbitmap64('{10,100,9223372036854775807,-9223372036854775808,-2}')) 570 | ) 571 | select id,bitmap,rb64_xor_agg(bitmap) over(order by id),rb64_xor_cardinality_agg(bitmap) over(order by id) from t; 572 | 573 | 574 | 575 | -- Test parallel aggregate 576 | 577 | set max_parallel_workers=8; 578 | set max_parallel_workers_per_gather=2; 579 | set parallel_setup_cost=0; 580 | set parallel_tuple_cost=0; 581 | set min_parallel_table_scan_size=0; 582 | 583 | CREATE OR REPLACE FUNCTION get_json_plan(sql text) RETURNS SETOF json AS 584 | $BODY$ 585 | BEGIN 586 | RETURN QUERY EXECUTE 'EXPLAIN (COSTS OFF,FORMAT JSON) ' || sql; 587 | 588 | RETURN; 589 | END 590 | $BODY$ 591 | LANGUAGE plpgsql; 592 | 593 | create table if not exists bitmap64_test_tb1(id int, bitmap roaringbitmap64); 594 | truncate bitmap64_test_tb1; 595 | insert into bitmap64_test_tb1 values (NULL,NULL); 596 | insert into bitmap64_test_tb1 select id,rb64_build(ARRAY[id]) from generate_series(1,10000)id; 597 | insert into bitmap64_test_tb1 values (NULL,NULL); 598 | insert into bitmap64_test_tb1 values (10001,rb64_build(ARRAY[10,100,1000,10000,10001,9223372036854775807,-9223372036854775808,-2])); 599 | 600 | select position('"Parallel Aware": true' in get_json_plan(' 601 | select rb64_cardinality(bitmap),rb64_min(bitmap),rb64_max(bitmap) 602 | from (select rb64_build_agg(id) bitmap from bitmap64_test_tb1)a 603 | ')::text) > 0 is_parallel_plan; 604 | 605 | select rb64_cardinality(bitmap),rb64_min(bitmap),rb64_max(bitmap) 606 | from (select rb64_build_agg(id) bitmap from bitmap64_test_tb1)a; 607 | 608 | select position('"Parallel Aware": true' in get_json_plan(' 609 | select rb64_cardinality(bitmap),rb64_min(bitmap),rb64_max(bitmap) 610 | from (select rb64_and_agg(bitmap) bitmap from bitmap64_test_tb1)a 611 | ')::text) > 0 is_parallel_plan; 612 | 613 | select rb64_cardinality(bitmap),rb64_min(bitmap),rb64_max(bitmap) 614 | from (select rb64_and_agg(bitmap) bitmap from bitmap64_test_tb1)a; 615 | 616 | select position('"Parallel Aware": true' in get_json_plan(' 617 | select rb64_cardinality(bitmap),rb64_min(bitmap),rb64_max(bitmap) 618 | from (select rb64_or_agg(bitmap) bitmap from bitmap64_test_tb1)a 619 | ')::text) > 0 is_parallel_plan; 620 | 621 | select rb64_cardinality(bitmap),rb64_min(bitmap),rb64_max(bitmap) 622 | from (select rb64_or_agg(bitmap) bitmap from bitmap64_test_tb1)a; 623 | 624 | select position('"Parallel Aware": true' in get_json_plan(' 625 | select rb64_cardinality(bitmap),rb64_min(bitmap),rb64_max(bitmap) 626 | from (select rb64_xor_agg(bitmap) bitmap from bitmap64_test_tb1)a 627 | ')::text) > 0 is_parallel_plan; 628 | 629 | select rb64_cardinality(bitmap),rb64_min(bitmap),rb64_max(bitmap) 630 | from (select rb64_xor_agg(bitmap) bitmap from bitmap64_test_tb1)a; 631 | 632 | select position('"Parallel Aware": true' in get_json_plan(' 633 | select rb64_and_cardinality_agg(bitmap),rb64_or_cardinality_agg(bitmap),rb64_xor_cardinality_agg(bitmap) from bitmap64_test_tb1 634 | ')::text) > 0 is_parallel_plan; 635 | 636 | select rb64_and_cardinality_agg(bitmap),rb64_or_cardinality_agg(bitmap),rb64_xor_cardinality_agg(bitmap) from bitmap64_test_tb1; 637 | 638 | --rb64_iterate() not support parallel on PG10 while run on parallel in PG11+ 639 | --explain(costs off) 640 | --select count(*) from (select rb64_iterate(bitmap) from bitmap64_test_tb1)a; 641 | 642 | select count(*) from (select rb64_iterate(bitmap) from bitmap64_test_tb1)a; 643 | 644 | select position('"Parallel Aware": true' in get_json_plan(' 645 | select id,bitmap, 646 | rb64_build_agg(id) over(w), 647 | rb64_or_agg(bitmap) over(w), 648 | rb64_and_agg(bitmap) over(w), 649 | rb64_xor_agg(bitmap) over(w) 650 | from bitmap64_test_tb1 651 | window w as (order by id) 652 | order by id limit 10 653 | ')::text) > 0 is_parallel_plan; 654 | 655 | select id,bitmap, 656 | rb64_build_agg(id) over(w), 657 | rb64_or_agg(bitmap) over(w), 658 | rb64_and_agg(bitmap) over(w), 659 | rb64_xor_agg(bitmap) over(w) 660 | from bitmap64_test_tb1 661 | window w as (order by id) 662 | order by id limit 10; 663 | 664 | -- bugfix #22 665 | SELECT '{100373,1829130,1861002,1975442,2353213,2456403}'::roaringbitmap64 & '{2353213}'::roaringbitmap64; 666 | SELECT rb64_and_cardinality('{100373,1829130,1861002,1975442,2353213,2456403}','{2353213}'); 667 | 668 | -- bugfix #45: rb64_to_array and rb64_min exhibits inconsistent results in a malformed serialize input 669 | select rb64_to_array('\x0100000000000000000000003a300000010000000000000000000000000000000000000000000000000000000000000000000000000000000008'::roaringbitmap64), 670 | rb64_min('\x0100000000000000000000003a300000010000000000000000000000000000000000000000000000000000000000000000000000000000000008'::roaringbitmap64); 671 | 672 | 673 | 674 | --------------------------------------------------------------------------------