├── .github └── workflows │ └── main.yml ├── .gitignore ├── CODEOWNERS ├── LICENSE ├── META.json ├── Makefile ├── README.md ├── bench ├── acc.sql ├── add.sql ├── addi.sql ├── div.sql ├── init.sql ├── mul.sql ├── muli.sql ├── serialize.sql ├── sub.sql ├── sum.sql └── sum_up.sql ├── istore--0.1.0--0.1.1.sql ├── istore--0.1.0.sql ├── istore--0.1.1--0.1.0.sql ├── istore--0.1.1--0.1.2.sql ├── istore--0.1.1.sql ├── istore--0.1.10--0.1.11.sql ├── istore--0.1.10--0.1.9.sql ├── istore--0.1.10.sql ├── istore--0.1.11--0.1.10.sql ├── istore--0.1.11--0.1.12.sql ├── istore--0.1.11.sql ├── istore--0.1.12--0.1.11.sql ├── istore--0.1.12.sql ├── istore--0.1.2--0.1.1.sql ├── istore--0.1.2--0.1.3.sql ├── istore--0.1.2.sql ├── istore--0.1.3--0.1.2.sql ├── istore--0.1.3--0.1.4.sql ├── istore--0.1.3.sql ├── istore--0.1.4--0.1.3.sql ├── istore--0.1.4--0.1.5.sql ├── istore--0.1.4.sql ├── istore--0.1.5--0.1.4.sql ├── istore--0.1.5--0.1.6.sql ├── istore--0.1.5.sql ├── istore--0.1.6--0.1.5.sql ├── istore--0.1.6--0.1.7.sql ├── istore--0.1.6.sql ├── istore--0.1.7--0.1.6.sql ├── istore--0.1.7--0.1.8.sql ├── istore--0.1.7.sql ├── istore--0.1.8--0.1.7.sql ├── istore--0.1.8--0.1.9.sql ├── istore--0.1.8.sql ├── istore--0.1.9--0.1.10.sql ├── istore--0.1.9--0.1.8.sql ├── istore--0.1.9.sql ├── istore.control ├── sql ├── bigistore.sql ├── casts.sql ├── istore.sql ├── types.sql └── x-parallel.sql ├── src ├── avl.c ├── avl.h ├── bigistore.c ├── depcode.c ├── is_parser.c ├── is_parser.h ├── istore.c ├── istore.h ├── istore_agg.c ├── istore_cast.c ├── istore_io.c ├── istore_key_gin.c └── pairs.c └── test ├── expected ├── aggregates_test.out ├── binary_copy_test.out ├── cast_test.out ├── functions_plain_test.out ├── functions_test.out ├── istore_io_test.out ├── istore_key_gin_test.out ├── migration_test.out ├── operator_test.out ├── parallel_test.out ├── parallel_test_1.out └── parallel_test_2.out └── sql ├── aggregates_test.sql ├── binary_copy_test.sql ├── cast_test.sql ├── functions_plain_test.sql ├── functions_test.sql ├── istore_io_test.sql ├── istore_key_gin_test.sql ├── migration_test.sql ├── operator_test.sql └── parallel_test.sql /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | - main 8 | pull_request: 9 | 10 | jobs: 11 | test: 12 | strategy: 13 | matrix: 14 | pg: [16, 15, 14, 13, 12, 11, 10] 15 | name: 🐘 PostgreSQL ${{ matrix.pg }} 16 | runs-on: ubuntu-latest 17 | container: pgxn/pgxn-tools 18 | steps: 19 | - run: pg-start ${{ matrix.pg }} 20 | - uses: actions/checkout@v2 21 | - run: pg-build-test 22 | 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Object files 2 | *.o 3 | *.ko 4 | *.obj 5 | *.elf 6 | 7 | # Libraries 8 | *.lib 9 | *.a 10 | 11 | # Shared objects (inc. Windows DLLs) 12 | *.dll 13 | *.so 14 | *.so.* 15 | *.dylib 16 | 17 | # Executables 18 | *.exe 19 | *.app 20 | *.i*86 21 | *.x86_64 22 | *.hex 23 | *.swp 24 | temp 25 | results 26 | bench/benchmarks* 27 | vendor 28 | regression.diffs 29 | regression.out 30 | .deps 31 | -------------------------------------------------------------------------------- /CODEOWNERS: -------------------------------------------------------------------------------- 1 | # Lines starting with '#' are comments. 2 | # Each line is a file pattern followed by one or more owners. 3 | 4 | # More details are here: https://help.github.com/articles/about-codeowners/ 5 | 6 | # The '*' pattern is global owners. 7 | 8 | # Order is important. The last matching pattern has the most precedence. 9 | # The folders are ordered as follows: 10 | 11 | # In each subsection folders are ordered first by depth, then alphabetically. 12 | # This should make it easy to add new rules without breaking existing ones. 13 | 14 | # Global rule: 15 | * @adjust/kpis-team 16 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 adjust 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /META.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "istore", 3 | "abstract": "An integer -> integer key/value store for analytic workloads", 4 | "version": "0.1.12", 5 | "maintainer" : [ 6 | "adjustgmbh" 7 | ], 8 | "license": { 9 | "PostgreSQL": "http://www.postgresql.org/about/licence" 10 | }, 11 | "provides": { 12 | "istore": { 13 | "file": "sql/istore.sql", 14 | "version": "0.1.12", 15 | "abstract": "An integer -> integer key/value store for analytic workloads" 16 | } 17 | }, 18 | "meta-spec": { 19 | "version": "1.0.0", 20 | "url": "http://pgxn.org/meta/spec.txt" 21 | }, 22 | "description": "istore provides a key/valyue store of ints to ints. This is useful for analytic workloads where istore can efficiently store sparse integer arrays.", 23 | "prereqs": { 24 | "runtime": { 25 | "requires": { 26 | "PostgreSQL": "10.0.0" 27 | } 28 | } 29 | }, 30 | "resources": { 31 | "bugtracker": { 32 | "web": "http://github.com/adjust/istore/issues" 33 | }, 34 | "repository": { 35 | "url": "git://github.com/adjust/istore.git", 36 | "web": "http://github.com/adjust/istore", 37 | "type": "git" 38 | } 39 | } 40 | } 41 | 42 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | #http://blog.pgxn.org/post/4783001135/extension-makefiles pg makefiles 2 | EXTENSION = istore 3 | PG_CONFIG ?= pg_config 4 | DATA = $(wildcard *--*.sql) 5 | PGXS := $(shell $(PG_CONFIG) --pgxs) 6 | MODULE_big = istore 7 | OBJS = $(patsubst %.c,%.o,$(wildcard src/*.c)) 8 | TESTS = $(sort $(wildcard test/sql/*.sql)) 9 | REGRESS ?= $(patsubst test/sql/%.sql,%,$(TESTS)) 10 | REGRESS_OPTS = --inputdir=test \ 11 | --load-extension=$(EXTENSION) 12 | PG_CPPFLAGS = --std=c99 13 | include $(PGXS) 14 | 15 | ifeq ($(shell test $(VERSION_NUM) -lt 90600; echo $$?),0) 16 | REGRESS := $(filter-out parallel_test, $(REGRESS)) 17 | endif 18 | -------------------------------------------------------------------------------- /bench/acc.sql: -------------------------------------------------------------------------------- 1 | SELECT accumulate(a) IS NULL as acc FROM is_bench; -------------------------------------------------------------------------------- /bench/add.sql: -------------------------------------------------------------------------------- 1 | SELECT a + b IS NULL as add FROM is_bench; -------------------------------------------------------------------------------- /bench/addi.sql: -------------------------------------------------------------------------------- 1 | SELECT a + c IS NULL as addi FROM is_bench; -------------------------------------------------------------------------------- /bench/div.sql: -------------------------------------------------------------------------------- 1 | SELECT a / b IS NULL as div FROM is_bench; -------------------------------------------------------------------------------- /bench/init.sql: -------------------------------------------------------------------------------- 1 | CREATE EXTENSION istore; 2 | CREATE TABLE is_bench AS 3 | SELECT 4 | string_agg((random()*:keys)::int::text || '=>'|| (random()*10000)::int::text, ',')::istore AS a, 5 | string_agg((random()*:keys)::int::text || '=>'|| (random()*10000+1)::int::text, ',')::istore AS b, 6 | (random()*1000)::int as c 7 | FROM 8 | generate_series(0, 10000 * :scale) AS i, 9 | generate_series(i, i + (i % :size)) AS j 10 | GROUP BY i; 11 | 12 | 13 | -------------------------------------------------------------------------------- /bench/mul.sql: -------------------------------------------------------------------------------- 1 | SELECT a * b IS NULL as mul FROM is_bench; -------------------------------------------------------------------------------- /bench/muli.sql: -------------------------------------------------------------------------------- 1 | SELECT a * c IS NULL as muli FROM is_bench; -------------------------------------------------------------------------------- /bench/serialize.sql: -------------------------------------------------------------------------------- 1 | SELECT a FROM is_bench; -------------------------------------------------------------------------------- /bench/sub.sql: -------------------------------------------------------------------------------- 1 | SELECT a - b IS NULL as sub FROM is_bench; -------------------------------------------------------------------------------- /bench/sum.sql: -------------------------------------------------------------------------------- 1 | SELECT SUM(a) IS NULL as sum FROM is_bench; -------------------------------------------------------------------------------- /bench/sum_up.sql: -------------------------------------------------------------------------------- 1 | SELECT sum_up(a) IS NULL as sum_up FROM is_bench; -------------------------------------------------------------------------------- /istore--0.1.0--0.1.1.sql: -------------------------------------------------------------------------------- 1 | ----functions---- 2 | CREATE OR REPLACE FUNCTION sum_up(istore, integer) 3 | RETURNS bigint 4 | LANGUAGE c 5 | IMMUTABLE STRICT 6 | AS 'istore', $function$istore_sum_up$function$; 7 | ---- 8 | CREATE OR REPLACE FUNCTION sum_up(bigistore, integer) 9 | RETURNS bigint 10 | LANGUAGE c 11 | IMMUTABLE STRICT 12 | AS 'istore', $function$bigistore_sum_up$function$; 13 | -------------------------------------------------------------------------------- /istore--0.1.0.sql: -------------------------------------------------------------------------------- 1 | -- complain if script is sourced in psql, rather than via CREATE EXTENSION 2 | \echo Use "CREATE EXTENSION istore" to load this file. \quit 3 | --source file sql/types.sql 4 | CREATE FUNCTION istore_in(cstring) 5 | RETURNS istore 6 | AS 'istore' 7 | LANGUAGE C IMMUTABLE STRICT; 8 | 9 | CREATE FUNCTION istore_out(istore) 10 | RETURNS cstring 11 | AS 'istore' 12 | LANGUAGE C IMMUTABLE STRICT; 13 | 14 | CREATE FUNCTION istore_send(istore) 15 | RETURNS bytea 16 | AS 'istore' 17 | LANGUAGE C IMMUTABLE STRICT; 18 | 19 | CREATE FUNCTION istore_recv(internal) 20 | RETURNS istore 21 | AS 'istore' 22 | LANGUAGE C IMMUTABLE STRICT; 23 | 24 | CREATE TYPE istore ( 25 | INPUT = istore_in, 26 | OUTPUT = istore_out, 27 | RECEIVE = istore_recv, 28 | SEND = istore_send, 29 | STORAGE = EXTENDED 30 | ); 31 | 32 | CREATE FUNCTION bigistore_in(cstring) 33 | RETURNS bigistore 34 | AS 'istore' 35 | LANGUAGE C IMMUTABLE STRICT; 36 | 37 | CREATE FUNCTION bigistore_out(bigistore) 38 | RETURNS cstring 39 | AS 'istore' 40 | LANGUAGE C IMMUTABLE STRICT; 41 | 42 | CREATE FUNCTION bigistore_send(bigistore) 43 | RETURNS bytea 44 | AS 'istore' 45 | LANGUAGE C IMMUTABLE STRICT; 46 | 47 | CREATE FUNCTION bigistore_recv(internal) 48 | RETURNS bigistore 49 | AS 'istore' 50 | LANGUAGE C IMMUTABLE STRICT; 51 | 52 | CREATE TYPE bigistore ( 53 | INPUT = bigistore_in, 54 | OUTPUT = bigistore_out, 55 | RECEIVE = bigistore_recv, 56 | SEND = bigistore_send, 57 | STORAGE = EXTENDED 58 | ); 59 | 60 | --source file sql/istore.sql 61 | 62 | CREATE FUNCTION exist(istore, integer) 63 | RETURNS boolean 64 | AS 'istore', 'istore_exist' 65 | LANGUAGE C IMMUTABLE STRICT; 66 | 67 | CREATE FUNCTION fetchval(istore, integer) 68 | RETURNS integer 69 | AS 'istore', 'istore_fetchval' 70 | LANGUAGE C IMMUTABLE STRICT; 71 | 72 | CREATE FUNCTION each(IN is istore, 73 | OUT key integer, 74 | OUT value integer) 75 | RETURNS SETOF record 76 | AS 'istore','istore_each' 77 | LANGUAGE C STRICT IMMUTABLE; 78 | 79 | CREATE FUNCTION compact(istore) 80 | RETURNS istore 81 | AS 'istore', 'istore_compact' 82 | LANGUAGE C IMMUTABLE STRICT; 83 | 84 | CREATE FUNCTION add(istore, istore) 85 | RETURNS istore 86 | AS 'istore', 'istore_add' 87 | LANGUAGE C IMMUTABLE STRICT; 88 | 89 | CREATE FUNCTION add(istore, integer) 90 | RETURNS istore 91 | AS 'istore', 'istore_add_integer' 92 | LANGUAGE C IMMUTABLE STRICT; 93 | 94 | CREATE FUNCTION subtract(istore, istore) 95 | RETURNS istore 96 | AS 'istore', 'istore_subtract' 97 | LANGUAGE C IMMUTABLE STRICT; 98 | 99 | CREATE FUNCTION subtract(istore, integer) 100 | RETURNS istore 101 | AS 'istore', 'istore_subtract_integer' 102 | LANGUAGE C IMMUTABLE STRICT; 103 | 104 | CREATE FUNCTION multiply(istore, istore) 105 | RETURNS istore 106 | AS 'istore', 'istore_multiply' 107 | LANGUAGE C IMMUTABLE STRICT; 108 | 109 | CREATE FUNCTION multiply(istore, integer) 110 | RETURNS istore 111 | AS 'istore', 'istore_multiply_integer' 112 | LANGUAGE C IMMUTABLE STRICT; 113 | 114 | CREATE FUNCTION divide(istore, istore) 115 | RETURNS istore 116 | AS 'istore', 'istore_divide' 117 | LANGUAGE C IMMUTABLE STRICT; 118 | 119 | CREATE FUNCTION divide(istore, integer) 120 | RETURNS istore 121 | AS 'istore', 'istore_divide_integer' 122 | LANGUAGE C IMMUTABLE STRICT; 123 | 124 | CREATE FUNCTION istore(integer[]) 125 | RETURNS istore 126 | AS 'istore', 'istore_from_intarray' 127 | LANGUAGE C IMMUTABLE STRICT; 128 | 129 | CREATE FUNCTION istore_agg_finalfn(internal) 130 | RETURNS bigistore 131 | AS 'istore' 132 | LANGUAGE C IMMUTABLE STRICT; 133 | 134 | CREATE FUNCTION sum_up(istore) 135 | RETURNS bigint 136 | AS 'istore', 'istore_sum_up' 137 | LANGUAGE C IMMUTABLE STRICT; 138 | 139 | CREATE FUNCTION istore(integer[], integer[]) 140 | RETURNS istore 141 | AS 'istore', 'istore_array_add' 142 | LANGUAGE C IMMUTABLE STRICT; 143 | 144 | CREATE FUNCTION fill_gaps(istore, integer, integer DEFAULT 0) 145 | RETURNS istore 146 | AS 'istore', 'istore_fill_gaps' 147 | LANGUAGE C IMMUTABLE STRICT; 148 | 149 | CREATE FUNCTION accumulate(istore) 150 | RETURNS istore 151 | AS 'istore', 'istore_accumulate' 152 | LANGUAGE C IMMUTABLE STRICT; 153 | 154 | CREATE FUNCTION accumulate(istore, integer) 155 | RETURNS istore 156 | AS 'istore', 'istore_accumulate' 157 | LANGUAGE C IMMUTABLE STRICT; 158 | 159 | CREATE FUNCTION istore_seed(integer, integer, integer) 160 | RETURNS istore 161 | AS 'istore' 162 | LANGUAGE C IMMUTABLE STRICT; 163 | 164 | CREATE FUNCTION istore_val_larger(istore, istore) 165 | RETURNS istore 166 | AS 'istore' 167 | LANGUAGE C IMMUTABLE STRICT; 168 | 169 | CREATE FUNCTION istore_val_smaller(istore, istore) 170 | RETURNS istore 171 | AS 'istore' 172 | LANGUAGE C IMMUTABLE STRICT; 173 | 174 | CREATE FUNCTION akeys(istore) 175 | RETURNS integer[] 176 | AS 'istore' ,'istore_akeys' 177 | LANGUAGE C IMMUTABLE STRICT; 178 | 179 | CREATE FUNCTION avals(istore) 180 | RETURNS integer[] 181 | AS 'istore' ,'istore_avals' 182 | LANGUAGE C IMMUTABLE STRICT; 183 | 184 | CREATE FUNCTION skeys(istore) 185 | RETURNS setof int 186 | AS 'istore' ,'istore_skeys' 187 | LANGUAGE C IMMUTABLE STRICT; 188 | 189 | CREATE FUNCTION svals(istore) 190 | RETURNS setof int 191 | AS 'istore' ,'istore_svals' 192 | LANGUAGE C IMMUTABLE STRICT; 193 | 194 | CREATE FUNCTION istore_to_json(istore) 195 | RETURNS json 196 | AS 'istore', 'istore_to_json' 197 | LANGUAGE C IMMUTABLE STRICT; 198 | 199 | CREATE AGGREGATE SUM ( 200 | sfunc = array_agg_transfn, 201 | basetype = istore, 202 | stype = internal, 203 | finalfunc = istore_agg_finalfn 204 | ); 205 | 206 | CREATE AGGREGATE MIN(istore) ( 207 | sfunc = istore_val_smaller, 208 | stype = istore 209 | ); 210 | 211 | CREATE AGGREGATE MAX(istore) ( 212 | sfunc = istore_val_larger, 213 | stype = istore 214 | ); 215 | 216 | CREATE OPERATOR -> ( 217 | leftarg = istore, 218 | rightarg = integer, 219 | procedure = fetchval 220 | ); 221 | 222 | CREATE OPERATOR ? ( 223 | leftarg = istore, 224 | rightarg = integer, 225 | procedure = exist 226 | ); 227 | 228 | CREATE OPERATOR + ( 229 | leftarg = istore, 230 | rightarg = istore, 231 | procedure = add 232 | ); 233 | 234 | CREATE OPERATOR + ( 235 | leftarg = istore, 236 | rightarg = integer, 237 | procedure = add 238 | ); 239 | 240 | CREATE OPERATOR - ( 241 | leftarg = istore, 242 | rightarg = istore, 243 | procedure = subtract 244 | ); 245 | 246 | CREATE OPERATOR - ( 247 | leftarg = istore, 248 | rightarg = integer, 249 | procedure = subtract 250 | ); 251 | 252 | CREATE OPERATOR * ( 253 | leftarg = istore, 254 | rightarg = istore, 255 | procedure = multiply 256 | ); 257 | 258 | CREATE OPERATOR * ( 259 | leftarg = istore, 260 | rightarg = integer, 261 | procedure = multiply 262 | ); 263 | 264 | CREATE OPERATOR / ( 265 | leftarg = istore, 266 | rightarg = istore, 267 | procedure = divide 268 | ); 269 | 270 | CREATE OPERATOR / ( 271 | leftarg = istore, 272 | rightarg = integer, 273 | procedure = divide 274 | ); 275 | 276 | 277 | CREATE FUNCTION gin_extract_istore_key(internal, internal) 278 | RETURNS internal 279 | AS 'istore' 280 | LANGUAGE C IMMUTABLE STRICT; 281 | 282 | CREATE FUNCTION gin_extract_istore_key_query(internal, internal, int2, internal, internal) 283 | RETURNS internal 284 | AS 'istore' 285 | LANGUAGE C IMMUTABLE STRICT; 286 | 287 | CREATE FUNCTION gin_consistent_istore_key(internal, int2, internal, int4, internal, internal) 288 | RETURNS bool 289 | AS 'istore' 290 | LANGUAGE C IMMUTABLE STRICT; 291 | 292 | CREATE OPERATOR CLASS istore_key_ops 293 | DEFAULT FOR TYPE istore USING gin 294 | AS 295 | OPERATOR 9 ?(istore, integer), 296 | FUNCTION 1 btint4cmp(integer, integer), 297 | FUNCTION 2 gin_extract_istore_key(internal, internal), 298 | FUNCTION 3 gin_extract_istore_key_query(internal, internal, int2, internal, internal), 299 | FUNCTION 4 gin_consistent_istore_key(internal, int2, internal, int4, internal, internal), 300 | STORAGE integer; 301 | 302 | --source file sql/casts.sql 303 | 304 | CREATE FUNCTION istore(bigistore) 305 | RETURNS istore 306 | AS 'istore', 'bigistore_to_istore' 307 | LANGUAGE C IMMUTABLE STRICT; 308 | 309 | CREATE FUNCTION bigistore(istore) 310 | RETURNS bigistore 311 | AS 'istore', 'istore_to_big_istore' 312 | LANGUAGE C IMMUTABLE STRICT; 313 | 314 | CREATE CAST (istore as bigistore) WITH FUNCTION bigistore(istore) AS IMPLICIT; 315 | CREATE CAST (bigistore as istore) WITH FUNCTION istore(bigistore) AS ASSIGNMENT; 316 | 317 | --source file sql/bigistore.sql 318 | 319 | CREATE FUNCTION exist(bigistore, integer) 320 | RETURNS boolean 321 | AS 'istore', 'bigistore_exist' 322 | LANGUAGE C IMMUTABLE STRICT; 323 | 324 | CREATE FUNCTION fetchval(bigistore, integer) 325 | RETURNS integer 326 | AS 'istore', 'bigistore_fetchval' 327 | LANGUAGE C IMMUTABLE STRICT; 328 | 329 | CREATE FUNCTION each(IN is bigistore, 330 | OUT key integer, 331 | OUT value bigint) 332 | RETURNS SETOF record 333 | AS 'istore','bigistore_each' 334 | LANGUAGE C STRICT IMMUTABLE; 335 | 336 | CREATE FUNCTION compact(bigistore) 337 | RETURNS bigistore 338 | AS 'istore', 'bigistore_compact' 339 | LANGUAGE C IMMUTABLE STRICT; 340 | 341 | CREATE FUNCTION add(bigistore, bigistore) 342 | RETURNS bigistore 343 | AS 'istore', 'bigistore_add' 344 | LANGUAGE C IMMUTABLE STRICT; 345 | 346 | CREATE FUNCTION add(bigistore, bigint) 347 | RETURNS bigistore 348 | AS 'istore', 'bigistore_add_integer' 349 | LANGUAGE C IMMUTABLE STRICT; 350 | 351 | CREATE FUNCTION subtract(bigistore, bigistore) 352 | RETURNS bigistore 353 | AS 'istore', 'bigistore_subtract' 354 | LANGUAGE C IMMUTABLE STRICT; 355 | 356 | CREATE FUNCTION subtract(bigistore, bigint) 357 | RETURNS bigistore 358 | AS 'istore', 'bigistore_subtract_integer' 359 | LANGUAGE C IMMUTABLE STRICT; 360 | 361 | CREATE FUNCTION multiply(bigistore, bigistore) 362 | RETURNS bigistore 363 | AS 'istore', 'bigistore_multiply' 364 | LANGUAGE C IMMUTABLE STRICT; 365 | 366 | CREATE FUNCTION multiply(bigistore, bigint) 367 | RETURNS bigistore 368 | AS 'istore', 'bigistore_multiply_integer' 369 | LANGUAGE C IMMUTABLE STRICT; 370 | 371 | CREATE FUNCTION divide(bigistore, bigistore) 372 | RETURNS bigistore 373 | AS 'istore', 'bigistore_divide' 374 | LANGUAGE C IMMUTABLE STRICT; 375 | 376 | CREATE FUNCTION divide(bigistore, bigint) 377 | RETURNS bigistore 378 | AS 'istore', 'bigistore_divide_integer' 379 | LANGUAGE C IMMUTABLE STRICT; 380 | 381 | CREATE FUNCTION bigistore(integer[]) 382 | RETURNS bigistore 383 | AS 'istore', 'bigistore_from_intarray' 384 | LANGUAGE C IMMUTABLE STRICT; 385 | 386 | CREATE FUNCTION bigistore_agg_finalfn(internal) 387 | RETURNS bigistore 388 | AS 'istore' 389 | LANGUAGE C IMMUTABLE STRICT; 390 | 391 | CREATE FUNCTION sum_up(bigistore) 392 | RETURNS bigint 393 | AS 'istore', 'bigistore_sum_up' 394 | LANGUAGE C IMMUTABLE STRICT; 395 | 396 | CREATE FUNCTION bigistore(integer[], integer[]) 397 | RETURNS bigistore 398 | AS 'istore', 'bigistore_array_add' 399 | LANGUAGE C IMMUTABLE STRICT; 400 | 401 | CREATE FUNCTION bigistore(integer[], bigint[]) 402 | RETURNS bigistore 403 | AS 'istore', 'bigistore_array_add' 404 | LANGUAGE C IMMUTABLE STRICT; 405 | 406 | CREATE FUNCTION istore(integer[], bigint[]) 407 | RETURNS bigistore 408 | AS 'istore', 'bigistore_array_add' 409 | LANGUAGE C IMMUTABLE STRICT; 410 | 411 | CREATE FUNCTION fill_gaps(bigistore, integer, bigint DEFAULT 0) 412 | RETURNS bigistore 413 | AS 'istore', 'bigistore_fill_gaps' 414 | LANGUAGE C IMMUTABLE STRICT; 415 | 416 | CREATE FUNCTION accumulate(bigistore) 417 | RETURNS bigistore 418 | AS 'istore', 'bigistore_accumulate' 419 | LANGUAGE C IMMUTABLE STRICT; 420 | 421 | CREATE FUNCTION accumulate(bigistore, integer) 422 | RETURNS bigistore 423 | AS 'istore', 'bigistore_accumulate' 424 | LANGUAGE C IMMUTABLE STRICT; 425 | 426 | CREATE FUNCTION istore_seed(integer, integer, bigint) 427 | RETURNS bigistore 428 | AS 'istore', 'bigistore_seed' 429 | LANGUAGE C IMMUTABLE STRICT; 430 | 431 | CREATE FUNCTION istore_val_larger(bigistore, bigistore) 432 | RETURNS bigistore 433 | AS 'istore', 'bigistore_val_larger' 434 | LANGUAGE C IMMUTABLE STRICT; 435 | 436 | CREATE FUNCTION istore_val_smaller(bigistore, bigistore) 437 | RETURNS bigistore 438 | AS 'istore', 'bigistore_val_smaller' 439 | LANGUAGE C IMMUTABLE STRICT; 440 | 441 | CREATE FUNCTION akeys(bigistore) 442 | RETURNS integer[] 443 | AS 'istore' ,'bigistore_akeys' 444 | LANGUAGE C IMMUTABLE STRICT; 445 | 446 | CREATE FUNCTION avals(bigistore) 447 | RETURNS bigint[] 448 | AS 'istore' ,'bigistore_avals' 449 | LANGUAGE C IMMUTABLE STRICT; 450 | 451 | CREATE FUNCTION skeys(bigistore) 452 | RETURNS setof integer 453 | AS 'istore' ,'bigistore_skeys' 454 | LANGUAGE C IMMUTABLE STRICT; 455 | 456 | CREATE FUNCTION svals(bigistore) 457 | RETURNS setof bigint 458 | AS 'istore' ,'bigistore_svals' 459 | LANGUAGE C IMMUTABLE STRICT; 460 | 461 | CREATE FUNCTION istore_to_json(bigistore) 462 | RETURNS json 463 | AS 'istore', 'bigistore_to_json' 464 | LANGUAGE C IMMUTABLE STRICT; 465 | 466 | 467 | CREATE AGGREGATE SUM ( 468 | sfunc = array_agg_transfn, 469 | basetype = bigistore, 470 | stype = internal, 471 | finalfunc = bigistore_agg_finalfn 472 | ); 473 | 474 | CREATE AGGREGATE MIN(bigistore) ( 475 | sfunc = istore_val_smaller, 476 | stype = bigistore 477 | ); 478 | 479 | CREATE AGGREGATE MAX(bigistore) ( 480 | sfunc = istore_val_larger, 481 | stype = bigistore 482 | ); 483 | 484 | CREATE OPERATOR -> ( 485 | leftarg = bigistore, 486 | rightarg = integer, 487 | procedure = fetchval 488 | ); 489 | 490 | CREATE OPERATOR ? ( 491 | leftarg = bigistore, 492 | rightarg = integer, 493 | procedure = exist 494 | ); 495 | 496 | CREATE OPERATOR + ( 497 | leftarg = bigistore, 498 | rightarg = bigistore, 499 | procedure = add 500 | ); 501 | 502 | CREATE OPERATOR + ( 503 | leftarg = bigistore, 504 | rightarg = bigint, 505 | procedure = add 506 | ); 507 | 508 | CREATE OPERATOR - ( 509 | leftarg = bigistore, 510 | rightarg = bigistore, 511 | procedure = subtract 512 | ); 513 | 514 | CREATE OPERATOR - ( 515 | leftarg = bigistore, 516 | rightarg = bigint, 517 | procedure = subtract 518 | ); 519 | 520 | CREATE OPERATOR * ( 521 | leftarg = bigistore, 522 | rightarg = bigistore, 523 | procedure = multiply 524 | ); 525 | 526 | CREATE OPERATOR * ( 527 | leftarg = bigistore, 528 | rightarg = bigint, 529 | procedure = multiply 530 | ); 531 | 532 | CREATE OPERATOR / ( 533 | leftarg = bigistore, 534 | rightarg = bigistore, 535 | procedure = divide 536 | ); 537 | 538 | CREATE OPERATOR / ( 539 | leftarg = bigistore, 540 | rightarg = bigint, 541 | procedure = divide 542 | ); 543 | 544 | CREATE FUNCTION gin_extract_bigistore_key(internal, internal) 545 | RETURNS internal 546 | AS 'istore' 547 | LANGUAGE C IMMUTABLE STRICT; 548 | 549 | CREATE OPERATOR CLASS bigistore_key_ops 550 | DEFAULT FOR TYPE bigistore USING gin 551 | AS 552 | OPERATOR 9 ?(bigistore, integer), 553 | FUNCTION 1 btint4cmp(integer, integer), 554 | FUNCTION 2 gin_extract_bigistore_key(internal, internal), 555 | FUNCTION 3 gin_extract_istore_key_query(internal, internal, int2, internal, internal), 556 | FUNCTION 4 gin_consistent_istore_key(internal, int2, internal, int4, internal, internal), 557 | STORAGE integer; 558 | 559 | -------------------------------------------------------------------------------- /istore--0.1.1--0.1.0.sql: -------------------------------------------------------------------------------- 1 | ----functions---- 2 | DROP FUNCTION IF EXISTS sum_up(istore, integer); 3 | ---- 4 | DROP FUNCTION IF EXISTS sum_up(bigistore, integer); 5 | -------------------------------------------------------------------------------- /istore--0.1.1--0.1.2.sql: -------------------------------------------------------------------------------- 1 | -- We can't replace the fetchval function without dropping -> operator 2 | DROP OPERATOR -> (bigistore, integer); 3 | DROP FUNCTION IF EXISTS fetchval(bigistore, integer); 4 | CREATE OR REPLACE FUNCTION fetchval(bigistore, integer) 5 | RETURNS bigint 6 | LANGUAGE c 7 | IMMUTABLE STRICT 8 | AS 'istore', $function$bigistore_fetchval$function$; 9 | CREATE OPERATOR -> ( 10 | leftarg = bigistore, 11 | rightarg = integer, 12 | procedure = fetchval 13 | ); 14 | -------------------------------------------------------------------------------- /istore--0.1.1.sql: -------------------------------------------------------------------------------- 1 | -- complain if script is sourced in psql, rather than via CREATE EXTENSION 2 | \echo Use "CREATE EXTENSION istore" to load this file. \quit 3 | --source file sql/types.sql 4 | CREATE FUNCTION istore_in(cstring) 5 | RETURNS istore 6 | AS 'istore' 7 | LANGUAGE C IMMUTABLE STRICT; 8 | 9 | CREATE FUNCTION istore_out(istore) 10 | RETURNS cstring 11 | AS 'istore' 12 | LANGUAGE C IMMUTABLE STRICT; 13 | 14 | CREATE FUNCTION istore_send(istore) 15 | RETURNS bytea 16 | AS 'istore' 17 | LANGUAGE C IMMUTABLE STRICT; 18 | 19 | CREATE FUNCTION istore_recv(internal) 20 | RETURNS istore 21 | AS 'istore' 22 | LANGUAGE C IMMUTABLE STRICT; 23 | 24 | CREATE TYPE istore ( 25 | INPUT = istore_in, 26 | OUTPUT = istore_out, 27 | RECEIVE = istore_recv, 28 | SEND = istore_send, 29 | STORAGE = EXTENDED 30 | ); 31 | 32 | CREATE FUNCTION bigistore_in(cstring) 33 | RETURNS bigistore 34 | AS 'istore' 35 | LANGUAGE C IMMUTABLE STRICT; 36 | 37 | CREATE FUNCTION bigistore_out(bigistore) 38 | RETURNS cstring 39 | AS 'istore' 40 | LANGUAGE C IMMUTABLE STRICT; 41 | 42 | CREATE FUNCTION bigistore_send(bigistore) 43 | RETURNS bytea 44 | AS 'istore' 45 | LANGUAGE C IMMUTABLE STRICT; 46 | 47 | CREATE FUNCTION bigistore_recv(internal) 48 | RETURNS bigistore 49 | AS 'istore' 50 | LANGUAGE C IMMUTABLE STRICT; 51 | 52 | CREATE TYPE bigistore ( 53 | INPUT = bigistore_in, 54 | OUTPUT = bigistore_out, 55 | RECEIVE = bigistore_recv, 56 | SEND = bigistore_send, 57 | STORAGE = EXTENDED 58 | ); 59 | 60 | --source file sql/istore.sql 61 | 62 | CREATE FUNCTION exist(istore, integer) 63 | RETURNS boolean 64 | AS 'istore', 'istore_exist' 65 | LANGUAGE C IMMUTABLE STRICT; 66 | 67 | CREATE FUNCTION fetchval(istore, integer) 68 | RETURNS integer 69 | AS 'istore', 'istore_fetchval' 70 | LANGUAGE C IMMUTABLE STRICT; 71 | 72 | CREATE FUNCTION each(IN is istore, 73 | OUT key integer, 74 | OUT value integer) 75 | RETURNS SETOF record 76 | AS 'istore','istore_each' 77 | LANGUAGE C STRICT IMMUTABLE; 78 | 79 | CREATE FUNCTION compact(istore) 80 | RETURNS istore 81 | AS 'istore', 'istore_compact' 82 | LANGUAGE C IMMUTABLE STRICT; 83 | 84 | CREATE FUNCTION add(istore, istore) 85 | RETURNS istore 86 | AS 'istore', 'istore_add' 87 | LANGUAGE C IMMUTABLE STRICT; 88 | 89 | CREATE FUNCTION add(istore, integer) 90 | RETURNS istore 91 | AS 'istore', 'istore_add_integer' 92 | LANGUAGE C IMMUTABLE STRICT; 93 | 94 | CREATE FUNCTION subtract(istore, istore) 95 | RETURNS istore 96 | AS 'istore', 'istore_subtract' 97 | LANGUAGE C IMMUTABLE STRICT; 98 | 99 | CREATE FUNCTION subtract(istore, integer) 100 | RETURNS istore 101 | AS 'istore', 'istore_subtract_integer' 102 | LANGUAGE C IMMUTABLE STRICT; 103 | 104 | CREATE FUNCTION multiply(istore, istore) 105 | RETURNS istore 106 | AS 'istore', 'istore_multiply' 107 | LANGUAGE C IMMUTABLE STRICT; 108 | 109 | CREATE FUNCTION multiply(istore, integer) 110 | RETURNS istore 111 | AS 'istore', 'istore_multiply_integer' 112 | LANGUAGE C IMMUTABLE STRICT; 113 | 114 | CREATE FUNCTION divide(istore, istore) 115 | RETURNS istore 116 | AS 'istore', 'istore_divide' 117 | LANGUAGE C IMMUTABLE STRICT; 118 | 119 | CREATE FUNCTION divide(istore, integer) 120 | RETURNS istore 121 | AS 'istore', 'istore_divide_integer' 122 | LANGUAGE C IMMUTABLE STRICT; 123 | 124 | CREATE FUNCTION istore(integer[]) 125 | RETURNS istore 126 | AS 'istore', 'istore_from_intarray' 127 | LANGUAGE C IMMUTABLE STRICT; 128 | 129 | CREATE FUNCTION istore_agg_finalfn(internal) 130 | RETURNS bigistore 131 | AS 'istore' 132 | LANGUAGE C IMMUTABLE STRICT; 133 | 134 | CREATE FUNCTION sum_up(istore) 135 | RETURNS bigint 136 | AS 'istore', 'istore_sum_up' 137 | LANGUAGE C IMMUTABLE STRICT; 138 | 139 | CREATE FUNCTION sum_up(istore, integer) 140 | RETURNS bigint 141 | AS 'istore', 'istore_sum_up' 142 | LANGUAGE C IMMUTABLE STRICT; 143 | 144 | CREATE FUNCTION istore(integer[], integer[]) 145 | RETURNS istore 146 | AS 'istore', 'istore_array_add' 147 | LANGUAGE C IMMUTABLE STRICT; 148 | 149 | CREATE FUNCTION fill_gaps(istore, integer, integer DEFAULT 0) 150 | RETURNS istore 151 | AS 'istore', 'istore_fill_gaps' 152 | LANGUAGE C IMMUTABLE STRICT; 153 | 154 | CREATE FUNCTION accumulate(istore) 155 | RETURNS istore 156 | AS 'istore', 'istore_accumulate' 157 | LANGUAGE C IMMUTABLE STRICT; 158 | 159 | CREATE FUNCTION accumulate(istore, integer) 160 | RETURNS istore 161 | AS 'istore', 'istore_accumulate' 162 | LANGUAGE C IMMUTABLE STRICT; 163 | 164 | CREATE FUNCTION istore_seed(integer, integer, integer) 165 | RETURNS istore 166 | AS 'istore' 167 | LANGUAGE C IMMUTABLE STRICT; 168 | 169 | CREATE FUNCTION istore_val_larger(istore, istore) 170 | RETURNS istore 171 | AS 'istore' 172 | LANGUAGE C IMMUTABLE STRICT; 173 | 174 | CREATE FUNCTION istore_val_smaller(istore, istore) 175 | RETURNS istore 176 | AS 'istore' 177 | LANGUAGE C IMMUTABLE STRICT; 178 | 179 | CREATE FUNCTION akeys(istore) 180 | RETURNS integer[] 181 | AS 'istore' ,'istore_akeys' 182 | LANGUAGE C IMMUTABLE STRICT; 183 | 184 | CREATE FUNCTION avals(istore) 185 | RETURNS integer[] 186 | AS 'istore' ,'istore_avals' 187 | LANGUAGE C IMMUTABLE STRICT; 188 | 189 | CREATE FUNCTION skeys(istore) 190 | RETURNS setof int 191 | AS 'istore' ,'istore_skeys' 192 | LANGUAGE C IMMUTABLE STRICT; 193 | 194 | CREATE FUNCTION svals(istore) 195 | RETURNS setof int 196 | AS 'istore' ,'istore_svals' 197 | LANGUAGE C IMMUTABLE STRICT; 198 | 199 | CREATE FUNCTION istore_to_json(istore) 200 | RETURNS json 201 | AS 'istore', 'istore_to_json' 202 | LANGUAGE C IMMUTABLE STRICT; 203 | 204 | CREATE AGGREGATE SUM ( 205 | sfunc = array_agg_transfn, 206 | basetype = istore, 207 | stype = internal, 208 | finalfunc = istore_agg_finalfn 209 | ); 210 | 211 | CREATE AGGREGATE MIN(istore) ( 212 | sfunc = istore_val_smaller, 213 | stype = istore 214 | ); 215 | 216 | CREATE AGGREGATE MAX(istore) ( 217 | sfunc = istore_val_larger, 218 | stype = istore 219 | ); 220 | 221 | CREATE OPERATOR -> ( 222 | leftarg = istore, 223 | rightarg = integer, 224 | procedure = fetchval 225 | ); 226 | 227 | CREATE OPERATOR ? ( 228 | leftarg = istore, 229 | rightarg = integer, 230 | procedure = exist 231 | ); 232 | 233 | CREATE OPERATOR + ( 234 | leftarg = istore, 235 | rightarg = istore, 236 | procedure = add 237 | ); 238 | 239 | CREATE OPERATOR + ( 240 | leftarg = istore, 241 | rightarg = integer, 242 | procedure = add 243 | ); 244 | 245 | CREATE OPERATOR - ( 246 | leftarg = istore, 247 | rightarg = istore, 248 | procedure = subtract 249 | ); 250 | 251 | CREATE OPERATOR - ( 252 | leftarg = istore, 253 | rightarg = integer, 254 | procedure = subtract 255 | ); 256 | 257 | CREATE OPERATOR * ( 258 | leftarg = istore, 259 | rightarg = istore, 260 | procedure = multiply 261 | ); 262 | 263 | CREATE OPERATOR * ( 264 | leftarg = istore, 265 | rightarg = integer, 266 | procedure = multiply 267 | ); 268 | 269 | CREATE OPERATOR / ( 270 | leftarg = istore, 271 | rightarg = istore, 272 | procedure = divide 273 | ); 274 | 275 | CREATE OPERATOR / ( 276 | leftarg = istore, 277 | rightarg = integer, 278 | procedure = divide 279 | ); 280 | 281 | 282 | CREATE FUNCTION gin_extract_istore_key(internal, internal) 283 | RETURNS internal 284 | AS 'istore' 285 | LANGUAGE C IMMUTABLE STRICT; 286 | 287 | CREATE FUNCTION gin_extract_istore_key_query(internal, internal, int2, internal, internal) 288 | RETURNS internal 289 | AS 'istore' 290 | LANGUAGE C IMMUTABLE STRICT; 291 | 292 | CREATE FUNCTION gin_consistent_istore_key(internal, int2, internal, int4, internal, internal) 293 | RETURNS bool 294 | AS 'istore' 295 | LANGUAGE C IMMUTABLE STRICT; 296 | 297 | CREATE OPERATOR CLASS istore_key_ops 298 | DEFAULT FOR TYPE istore USING gin 299 | AS 300 | OPERATOR 9 ?(istore, integer), 301 | FUNCTION 1 btint4cmp(integer, integer), 302 | FUNCTION 2 gin_extract_istore_key(internal, internal), 303 | FUNCTION 3 gin_extract_istore_key_query(internal, internal, int2, internal, internal), 304 | FUNCTION 4 gin_consistent_istore_key(internal, int2, internal, int4, internal, internal), 305 | STORAGE integer; 306 | 307 | --source file sql/casts.sql 308 | 309 | CREATE FUNCTION istore(bigistore) 310 | RETURNS istore 311 | AS 'istore', 'bigistore_to_istore' 312 | LANGUAGE C IMMUTABLE STRICT; 313 | 314 | CREATE FUNCTION bigistore(istore) 315 | RETURNS bigistore 316 | AS 'istore', 'istore_to_big_istore' 317 | LANGUAGE C IMMUTABLE STRICT; 318 | 319 | CREATE CAST (istore as bigistore) WITH FUNCTION bigistore(istore) AS IMPLICIT; 320 | CREATE CAST (bigistore as istore) WITH FUNCTION istore(bigistore) AS ASSIGNMENT; 321 | 322 | --source file sql/bigistore.sql 323 | 324 | CREATE FUNCTION exist(bigistore, integer) 325 | RETURNS boolean 326 | AS 'istore', 'bigistore_exist' 327 | LANGUAGE C IMMUTABLE STRICT; 328 | 329 | CREATE FUNCTION fetchval(bigistore, integer) 330 | RETURNS integer 331 | AS 'istore', 'bigistore_fetchval' 332 | LANGUAGE C IMMUTABLE STRICT; 333 | 334 | CREATE FUNCTION each(IN is bigistore, 335 | OUT key integer, 336 | OUT value bigint) 337 | RETURNS SETOF record 338 | AS 'istore','bigistore_each' 339 | LANGUAGE C STRICT IMMUTABLE; 340 | 341 | CREATE FUNCTION compact(bigistore) 342 | RETURNS bigistore 343 | AS 'istore', 'bigistore_compact' 344 | LANGUAGE C IMMUTABLE STRICT; 345 | 346 | CREATE FUNCTION add(bigistore, bigistore) 347 | RETURNS bigistore 348 | AS 'istore', 'bigistore_add' 349 | LANGUAGE C IMMUTABLE STRICT; 350 | 351 | CREATE FUNCTION add(bigistore, bigint) 352 | RETURNS bigistore 353 | AS 'istore', 'bigistore_add_integer' 354 | LANGUAGE C IMMUTABLE STRICT; 355 | 356 | CREATE FUNCTION subtract(bigistore, bigistore) 357 | RETURNS bigistore 358 | AS 'istore', 'bigistore_subtract' 359 | LANGUAGE C IMMUTABLE STRICT; 360 | 361 | CREATE FUNCTION subtract(bigistore, bigint) 362 | RETURNS bigistore 363 | AS 'istore', 'bigistore_subtract_integer' 364 | LANGUAGE C IMMUTABLE STRICT; 365 | 366 | CREATE FUNCTION multiply(bigistore, bigistore) 367 | RETURNS bigistore 368 | AS 'istore', 'bigistore_multiply' 369 | LANGUAGE C IMMUTABLE STRICT; 370 | 371 | CREATE FUNCTION multiply(bigistore, bigint) 372 | RETURNS bigistore 373 | AS 'istore', 'bigistore_multiply_integer' 374 | LANGUAGE C IMMUTABLE STRICT; 375 | 376 | CREATE FUNCTION divide(bigistore, bigistore) 377 | RETURNS bigistore 378 | AS 'istore', 'bigistore_divide' 379 | LANGUAGE C IMMUTABLE STRICT; 380 | 381 | CREATE FUNCTION divide(bigistore, bigint) 382 | RETURNS bigistore 383 | AS 'istore', 'bigistore_divide_integer' 384 | LANGUAGE C IMMUTABLE STRICT; 385 | 386 | CREATE FUNCTION bigistore(integer[]) 387 | RETURNS bigistore 388 | AS 'istore', 'bigistore_from_intarray' 389 | LANGUAGE C IMMUTABLE STRICT; 390 | 391 | CREATE FUNCTION bigistore_agg_finalfn(internal) 392 | RETURNS bigistore 393 | AS 'istore' 394 | LANGUAGE C IMMUTABLE STRICT; 395 | 396 | CREATE FUNCTION sum_up(bigistore) 397 | RETURNS bigint 398 | AS 'istore', 'bigistore_sum_up' 399 | LANGUAGE C IMMUTABLE STRICT; 400 | 401 | CREATE FUNCTION sum_up(bigistore, integer) 402 | RETURNS bigint 403 | AS 'istore', 'bigistore_sum_up' 404 | LANGUAGE C IMMUTABLE STRICT; 405 | 406 | CREATE FUNCTION bigistore(integer[], integer[]) 407 | RETURNS bigistore 408 | AS 'istore', 'bigistore_array_add' 409 | LANGUAGE C IMMUTABLE STRICT; 410 | 411 | CREATE FUNCTION bigistore(integer[], bigint[]) 412 | RETURNS bigistore 413 | AS 'istore', 'bigistore_array_add' 414 | LANGUAGE C IMMUTABLE STRICT; 415 | 416 | CREATE FUNCTION istore(integer[], bigint[]) 417 | RETURNS bigistore 418 | AS 'istore', 'bigistore_array_add' 419 | LANGUAGE C IMMUTABLE STRICT; 420 | 421 | CREATE FUNCTION fill_gaps(bigistore, integer, bigint DEFAULT 0) 422 | RETURNS bigistore 423 | AS 'istore', 'bigistore_fill_gaps' 424 | LANGUAGE C IMMUTABLE STRICT; 425 | 426 | CREATE FUNCTION accumulate(bigistore) 427 | RETURNS bigistore 428 | AS 'istore', 'bigistore_accumulate' 429 | LANGUAGE C IMMUTABLE STRICT; 430 | 431 | CREATE FUNCTION accumulate(bigistore, integer) 432 | RETURNS bigistore 433 | AS 'istore', 'bigistore_accumulate' 434 | LANGUAGE C IMMUTABLE STRICT; 435 | 436 | CREATE FUNCTION istore_seed(integer, integer, bigint) 437 | RETURNS bigistore 438 | AS 'istore', 'bigistore_seed' 439 | LANGUAGE C IMMUTABLE STRICT; 440 | 441 | CREATE FUNCTION istore_val_larger(bigistore, bigistore) 442 | RETURNS bigistore 443 | AS 'istore', 'bigistore_val_larger' 444 | LANGUAGE C IMMUTABLE STRICT; 445 | 446 | CREATE FUNCTION istore_val_smaller(bigistore, bigistore) 447 | RETURNS bigistore 448 | AS 'istore', 'bigistore_val_smaller' 449 | LANGUAGE C IMMUTABLE STRICT; 450 | 451 | CREATE FUNCTION akeys(bigistore) 452 | RETURNS integer[] 453 | AS 'istore' ,'bigistore_akeys' 454 | LANGUAGE C IMMUTABLE STRICT; 455 | 456 | CREATE FUNCTION avals(bigistore) 457 | RETURNS bigint[] 458 | AS 'istore' ,'bigistore_avals' 459 | LANGUAGE C IMMUTABLE STRICT; 460 | 461 | CREATE FUNCTION skeys(bigistore) 462 | RETURNS setof integer 463 | AS 'istore' ,'bigistore_skeys' 464 | LANGUAGE C IMMUTABLE STRICT; 465 | 466 | CREATE FUNCTION svals(bigistore) 467 | RETURNS setof bigint 468 | AS 'istore' ,'bigistore_svals' 469 | LANGUAGE C IMMUTABLE STRICT; 470 | 471 | CREATE FUNCTION istore_to_json(bigistore) 472 | RETURNS json 473 | AS 'istore', 'bigistore_to_json' 474 | LANGUAGE C IMMUTABLE STRICT; 475 | 476 | 477 | CREATE AGGREGATE SUM ( 478 | sfunc = array_agg_transfn, 479 | basetype = bigistore, 480 | stype = internal, 481 | finalfunc = bigistore_agg_finalfn 482 | ); 483 | 484 | CREATE AGGREGATE MIN(bigistore) ( 485 | sfunc = istore_val_smaller, 486 | stype = bigistore 487 | ); 488 | 489 | CREATE AGGREGATE MAX(bigistore) ( 490 | sfunc = istore_val_larger, 491 | stype = bigistore 492 | ); 493 | 494 | CREATE OPERATOR -> ( 495 | leftarg = bigistore, 496 | rightarg = integer, 497 | procedure = fetchval 498 | ); 499 | 500 | CREATE OPERATOR ? ( 501 | leftarg = bigistore, 502 | rightarg = integer, 503 | procedure = exist 504 | ); 505 | 506 | CREATE OPERATOR + ( 507 | leftarg = bigistore, 508 | rightarg = bigistore, 509 | procedure = add 510 | ); 511 | 512 | CREATE OPERATOR + ( 513 | leftarg = bigistore, 514 | rightarg = bigint, 515 | procedure = add 516 | ); 517 | 518 | CREATE OPERATOR - ( 519 | leftarg = bigistore, 520 | rightarg = bigistore, 521 | procedure = subtract 522 | ); 523 | 524 | CREATE OPERATOR - ( 525 | leftarg = bigistore, 526 | rightarg = bigint, 527 | procedure = subtract 528 | ); 529 | 530 | CREATE OPERATOR * ( 531 | leftarg = bigistore, 532 | rightarg = bigistore, 533 | procedure = multiply 534 | ); 535 | 536 | CREATE OPERATOR * ( 537 | leftarg = bigistore, 538 | rightarg = bigint, 539 | procedure = multiply 540 | ); 541 | 542 | CREATE OPERATOR / ( 543 | leftarg = bigistore, 544 | rightarg = bigistore, 545 | procedure = divide 546 | ); 547 | 548 | CREATE OPERATOR / ( 549 | leftarg = bigistore, 550 | rightarg = bigint, 551 | procedure = divide 552 | ); 553 | 554 | CREATE FUNCTION gin_extract_bigistore_key(internal, internal) 555 | RETURNS internal 556 | AS 'istore' 557 | LANGUAGE C IMMUTABLE STRICT; 558 | 559 | CREATE OPERATOR CLASS bigistore_key_ops 560 | DEFAULT FOR TYPE bigistore USING gin 561 | AS 562 | OPERATOR 9 ?(bigistore, integer), 563 | FUNCTION 1 btint4cmp(integer, integer), 564 | FUNCTION 2 gin_extract_bigistore_key(internal, internal), 565 | FUNCTION 3 gin_extract_istore_key_query(internal, internal, int2, internal, internal), 566 | FUNCTION 4 gin_consistent_istore_key(internal, int2, internal, int4, internal, internal), 567 | STORAGE integer; 568 | 569 | -------------------------------------------------------------------------------- /istore--0.1.10--0.1.11.sql: -------------------------------------------------------------------------------- 1 | CREATE FUNCTION row_to_istore(record) 2 | RETURNS istore 3 | AS 'istore', 'row_to_istore' 4 | LANGUAGE C IMMUTABLE STRICT; 5 | 6 | CREATE FUNCTION row_to_bigistore(record) 7 | RETURNS bigistore 8 | AS 'istore', 'row_to_bigistore' 9 | LANGUAGE C IMMUTABLE STRICT; 10 | -------------------------------------------------------------------------------- /istore--0.1.10--0.1.9.sql: -------------------------------------------------------------------------------- 1 | DROP FUNCTION slice(istore, min integer, max integer); 2 | DROP FUNCTION slice(bigistore, min integer, max integer); -------------------------------------------------------------------------------- /istore--0.1.11--0.1.10.sql: -------------------------------------------------------------------------------- 1 | DROP FUNCTION row_to_istore(record); 2 | DROP FUNCTION row_to_bigistore(record); 3 | -------------------------------------------------------------------------------- /istore--0.1.11--0.1.12.sql: -------------------------------------------------------------------------------- 1 | CREATE FUNCTION max_value(istore) 2 | RETURNS integer 3 | AS 'istore', 'istore_max_value' 4 | LANGUAGE C IMMUTABLE STRICT; 5 | 6 | CREATE FUNCTION max_value(bigistore) 7 | RETURNS bigint 8 | AS 'istore', 'bigistore_max_value' 9 | LANGUAGE C IMMUTABLE STRICT; 10 | -------------------------------------------------------------------------------- /istore--0.1.12--0.1.11.sql: -------------------------------------------------------------------------------- 1 | DROP FUNCTION max_value(istore); 2 | DROP FUNCTION max_value(bigistore); 3 | -------------------------------------------------------------------------------- /istore--0.1.2--0.1.1.sql: -------------------------------------------------------------------------------- 1 | -- We can't replace the fetchval function without dropping -> operator 2 | DROP OPERATOR -> (bigistore, integer); 3 | DROP FUNCTION IF EXISTS fetchval(bigistore, integer); 4 | CREATE OR REPLACE FUNCTION fetchval(bigistore, integer) 5 | RETURNS integer 6 | LANGUAGE c 7 | IMMUTABLE STRICT 8 | AS 'istore', $function$bigistore_fetchval$function$; 9 | CREATE OPERATOR -> ( 10 | leftarg = bigistore, 11 | rightarg = integer, 12 | procedure = fetchval 13 | ); 14 | -------------------------------------------------------------------------------- /istore--0.1.2--0.1.3.sql: -------------------------------------------------------------------------------- 1 | ---- 2 | CREATE OR REPLACE FUNCTION bigistore_agg_finalfn(internal) 3 | RETURNS bigistore 4 | LANGUAGE c 5 | IMMUTABLE STRICT 6 | AS 'istore', $function$bigistore_agg_finalfn_pairs$function$; 7 | ---- 8 | CREATE OR REPLACE FUNCTION istore_max_transfn(internal, bigistore) 9 | RETURNS internal 10 | LANGUAGE c 11 | IMMUTABLE 12 | AS 'istore', $function$bigistore_max_transfn$function$; 13 | ---- 14 | CREATE OR REPLACE FUNCTION istore_min_transfn(internal, bigistore) 15 | RETURNS internal 16 | LANGUAGE c 17 | IMMUTABLE 18 | AS 'istore', $function$bigistore_min_transfn$function$; 19 | ---- 20 | CREATE OR REPLACE FUNCTION istore_sum_transfn(internal, bigistore) 21 | RETURNS internal 22 | LANGUAGE c 23 | IMMUTABLE 24 | AS 'istore', $function$bigistore_sum_transfn$function$; 25 | ---- 26 | CREATE OR REPLACE FUNCTION istore_agg_finalfn_pairs(internal) 27 | RETURNS istore 28 | LANGUAGE c 29 | IMMUTABLE STRICT 30 | AS 'istore', $function$istore_agg_finalfn_pairs$function$; 31 | ---- 32 | CREATE OR REPLACE FUNCTION istore_max_transfn(internal, istore) 33 | RETURNS internal 34 | LANGUAGE c 35 | IMMUTABLE 36 | AS 'istore', $function$istore_max_transfn$function$; 37 | ---- 38 | CREATE OR REPLACE FUNCTION istore_min_transfn(internal, istore) 39 | RETURNS internal 40 | LANGUAGE c 41 | IMMUTABLE 42 | AS 'istore', $function$istore_min_transfn$function$; 43 | ---- 44 | CREATE OR REPLACE FUNCTION istore_sum_transfn(internal, istore) 45 | RETURNS internal 46 | LANGUAGE c 47 | IMMUTABLE 48 | AS 'istore', $function$istore_sum_transfn$function$; 49 | ----aggregates---- 50 | DROP AGGREGATE IF EXISTS max (bigistore); 51 | CREATE AGGREGATE max(bigistore) ( 52 | SFUNC = public.istore_max_transfn, 53 | STYPE = internal, 54 | FINALFUNC = bigistore_agg_finalfn 55 | ); 56 | 57 | 58 | ---- 59 | DROP AGGREGATE IF EXISTS min (bigistore); 60 | CREATE AGGREGATE min(bigistore) ( 61 | SFUNC = public.istore_min_transfn, 62 | STYPE = internal, 63 | FINALFUNC = bigistore_agg_finalfn 64 | ); 65 | 66 | 67 | ---- 68 | DROP AGGREGATE IF EXISTS sum (bigistore); 69 | CREATE AGGREGATE sum(bigistore) ( 70 | SFUNC = public.istore_sum_transfn, 71 | STYPE = internal, 72 | FINALFUNC = bigistore_agg_finalfn 73 | ); 74 | 75 | 76 | ---- 77 | DROP AGGREGATE IF EXISTS max (istore); 78 | CREATE AGGREGATE max(istore) ( 79 | SFUNC = public.istore_max_transfn, 80 | STYPE = internal, 81 | FINALFUNC = istore_agg_finalfn_pairs 82 | ); 83 | 84 | 85 | ---- 86 | DROP AGGREGATE IF EXISTS min (istore); 87 | CREATE AGGREGATE min(istore) ( 88 | SFUNC = public.istore_min_transfn, 89 | STYPE = internal, 90 | FINALFUNC = istore_agg_finalfn_pairs 91 | ); 92 | 93 | 94 | ---- 95 | DROP AGGREGATE IF EXISTS sum (istore); 96 | CREATE AGGREGATE sum(istore) ( 97 | SFUNC = public.istore_sum_transfn, 98 | STYPE = internal, 99 | FINALFUNC = bigistore_agg_finalfn 100 | ); 101 | 102 | ----functions---- 103 | DROP FUNCTION IF EXISTS istore_agg_finalfn(internal); 104 | -------------------------------------------------------------------------------- /istore--0.1.2.sql: -------------------------------------------------------------------------------- 1 | -- complain if script is sourced in psql, rather than via CREATE EXTENSION 2 | \echo Use "CREATE EXTENSION istore" to load this file. \quit 3 | --source file sql/types.sql 4 | CREATE FUNCTION istore_in(cstring) 5 | RETURNS istore 6 | AS 'istore' 7 | LANGUAGE C IMMUTABLE STRICT; 8 | 9 | CREATE FUNCTION istore_out(istore) 10 | RETURNS cstring 11 | AS 'istore' 12 | LANGUAGE C IMMUTABLE STRICT; 13 | 14 | CREATE FUNCTION istore_send(istore) 15 | RETURNS bytea 16 | AS 'istore' 17 | LANGUAGE C IMMUTABLE STRICT; 18 | 19 | CREATE FUNCTION istore_recv(internal) 20 | RETURNS istore 21 | AS 'istore' 22 | LANGUAGE C IMMUTABLE STRICT; 23 | 24 | CREATE TYPE istore ( 25 | INPUT = istore_in, 26 | OUTPUT = istore_out, 27 | RECEIVE = istore_recv, 28 | SEND = istore_send, 29 | STORAGE = EXTENDED 30 | ); 31 | 32 | CREATE FUNCTION bigistore_in(cstring) 33 | RETURNS bigistore 34 | AS 'istore' 35 | LANGUAGE C IMMUTABLE STRICT; 36 | 37 | CREATE FUNCTION bigistore_out(bigistore) 38 | RETURNS cstring 39 | AS 'istore' 40 | LANGUAGE C IMMUTABLE STRICT; 41 | 42 | CREATE FUNCTION bigistore_send(bigistore) 43 | RETURNS bytea 44 | AS 'istore' 45 | LANGUAGE C IMMUTABLE STRICT; 46 | 47 | CREATE FUNCTION bigistore_recv(internal) 48 | RETURNS bigistore 49 | AS 'istore' 50 | LANGUAGE C IMMUTABLE STRICT; 51 | 52 | CREATE TYPE bigistore ( 53 | INPUT = bigistore_in, 54 | OUTPUT = bigistore_out, 55 | RECEIVE = bigistore_recv, 56 | SEND = bigistore_send, 57 | STORAGE = EXTENDED 58 | ); 59 | 60 | --source file sql/istore.sql 61 | 62 | CREATE FUNCTION exist(istore, integer) 63 | RETURNS boolean 64 | AS 'istore', 'istore_exist' 65 | LANGUAGE C IMMUTABLE STRICT; 66 | 67 | CREATE FUNCTION fetchval(istore, integer) 68 | RETURNS integer 69 | AS 'istore', 'istore_fetchval' 70 | LANGUAGE C IMMUTABLE STRICT; 71 | 72 | CREATE FUNCTION each(IN is istore, 73 | OUT key integer, 74 | OUT value integer) 75 | RETURNS SETOF record 76 | AS 'istore','istore_each' 77 | LANGUAGE C STRICT IMMUTABLE; 78 | 79 | CREATE FUNCTION compact(istore) 80 | RETURNS istore 81 | AS 'istore', 'istore_compact' 82 | LANGUAGE C IMMUTABLE STRICT; 83 | 84 | CREATE FUNCTION add(istore, istore) 85 | RETURNS istore 86 | AS 'istore', 'istore_add' 87 | LANGUAGE C IMMUTABLE STRICT; 88 | 89 | CREATE FUNCTION add(istore, integer) 90 | RETURNS istore 91 | AS 'istore', 'istore_add_integer' 92 | LANGUAGE C IMMUTABLE STRICT; 93 | 94 | CREATE FUNCTION subtract(istore, istore) 95 | RETURNS istore 96 | AS 'istore', 'istore_subtract' 97 | LANGUAGE C IMMUTABLE STRICT; 98 | 99 | CREATE FUNCTION subtract(istore, integer) 100 | RETURNS istore 101 | AS 'istore', 'istore_subtract_integer' 102 | LANGUAGE C IMMUTABLE STRICT; 103 | 104 | CREATE FUNCTION multiply(istore, istore) 105 | RETURNS istore 106 | AS 'istore', 'istore_multiply' 107 | LANGUAGE C IMMUTABLE STRICT; 108 | 109 | CREATE FUNCTION multiply(istore, integer) 110 | RETURNS istore 111 | AS 'istore', 'istore_multiply_integer' 112 | LANGUAGE C IMMUTABLE STRICT; 113 | 114 | CREATE FUNCTION divide(istore, istore) 115 | RETURNS istore 116 | AS 'istore', 'istore_divide' 117 | LANGUAGE C IMMUTABLE STRICT; 118 | 119 | CREATE FUNCTION divide(istore, integer) 120 | RETURNS istore 121 | AS 'istore', 'istore_divide_integer' 122 | LANGUAGE C IMMUTABLE STRICT; 123 | 124 | CREATE FUNCTION istore(integer[]) 125 | RETURNS istore 126 | AS 'istore', 'istore_from_intarray' 127 | LANGUAGE C IMMUTABLE STRICT; 128 | 129 | CREATE FUNCTION istore_agg_finalfn(internal) 130 | RETURNS bigistore 131 | AS 'istore' 132 | LANGUAGE C IMMUTABLE STRICT; 133 | 134 | CREATE FUNCTION sum_up(istore) 135 | RETURNS bigint 136 | AS 'istore', 'istore_sum_up' 137 | LANGUAGE C IMMUTABLE STRICT; 138 | 139 | CREATE FUNCTION sum_up(istore, integer) 140 | RETURNS bigint 141 | AS 'istore', 'istore_sum_up' 142 | LANGUAGE C IMMUTABLE STRICT; 143 | 144 | CREATE FUNCTION istore(integer[], integer[]) 145 | RETURNS istore 146 | AS 'istore', 'istore_array_add' 147 | LANGUAGE C IMMUTABLE STRICT; 148 | 149 | CREATE FUNCTION fill_gaps(istore, integer, integer DEFAULT 0) 150 | RETURNS istore 151 | AS 'istore', 'istore_fill_gaps' 152 | LANGUAGE C IMMUTABLE STRICT; 153 | 154 | CREATE FUNCTION accumulate(istore) 155 | RETURNS istore 156 | AS 'istore', 'istore_accumulate' 157 | LANGUAGE C IMMUTABLE STRICT; 158 | 159 | CREATE FUNCTION accumulate(istore, integer) 160 | RETURNS istore 161 | AS 'istore', 'istore_accumulate' 162 | LANGUAGE C IMMUTABLE STRICT; 163 | 164 | CREATE FUNCTION istore_seed(integer, integer, integer) 165 | RETURNS istore 166 | AS 'istore' 167 | LANGUAGE C IMMUTABLE STRICT; 168 | 169 | CREATE FUNCTION istore_val_larger(istore, istore) 170 | RETURNS istore 171 | AS 'istore' 172 | LANGUAGE C IMMUTABLE STRICT; 173 | 174 | CREATE FUNCTION istore_val_smaller(istore, istore) 175 | RETURNS istore 176 | AS 'istore' 177 | LANGUAGE C IMMUTABLE STRICT; 178 | 179 | CREATE FUNCTION akeys(istore) 180 | RETURNS integer[] 181 | AS 'istore' ,'istore_akeys' 182 | LANGUAGE C IMMUTABLE STRICT; 183 | 184 | CREATE FUNCTION avals(istore) 185 | RETURNS integer[] 186 | AS 'istore' ,'istore_avals' 187 | LANGUAGE C IMMUTABLE STRICT; 188 | 189 | CREATE FUNCTION skeys(istore) 190 | RETURNS setof int 191 | AS 'istore' ,'istore_skeys' 192 | LANGUAGE C IMMUTABLE STRICT; 193 | 194 | CREATE FUNCTION svals(istore) 195 | RETURNS setof int 196 | AS 'istore' ,'istore_svals' 197 | LANGUAGE C IMMUTABLE STRICT; 198 | 199 | CREATE FUNCTION istore_to_json(istore) 200 | RETURNS json 201 | AS 'istore', 'istore_to_json' 202 | LANGUAGE C IMMUTABLE STRICT; 203 | 204 | CREATE AGGREGATE SUM ( 205 | sfunc = array_agg_transfn, 206 | basetype = istore, 207 | stype = internal, 208 | finalfunc = istore_agg_finalfn 209 | ); 210 | 211 | CREATE AGGREGATE MIN(istore) ( 212 | sfunc = istore_val_smaller, 213 | stype = istore 214 | ); 215 | 216 | CREATE AGGREGATE MAX(istore) ( 217 | sfunc = istore_val_larger, 218 | stype = istore 219 | ); 220 | 221 | CREATE OPERATOR -> ( 222 | leftarg = istore, 223 | rightarg = integer, 224 | procedure = fetchval 225 | ); 226 | 227 | CREATE OPERATOR ? ( 228 | leftarg = istore, 229 | rightarg = integer, 230 | procedure = exist 231 | ); 232 | 233 | CREATE OPERATOR + ( 234 | leftarg = istore, 235 | rightarg = istore, 236 | procedure = add 237 | ); 238 | 239 | CREATE OPERATOR + ( 240 | leftarg = istore, 241 | rightarg = integer, 242 | procedure = add 243 | ); 244 | 245 | CREATE OPERATOR - ( 246 | leftarg = istore, 247 | rightarg = istore, 248 | procedure = subtract 249 | ); 250 | 251 | CREATE OPERATOR - ( 252 | leftarg = istore, 253 | rightarg = integer, 254 | procedure = subtract 255 | ); 256 | 257 | CREATE OPERATOR * ( 258 | leftarg = istore, 259 | rightarg = istore, 260 | procedure = multiply 261 | ); 262 | 263 | CREATE OPERATOR * ( 264 | leftarg = istore, 265 | rightarg = integer, 266 | procedure = multiply 267 | ); 268 | 269 | CREATE OPERATOR / ( 270 | leftarg = istore, 271 | rightarg = istore, 272 | procedure = divide 273 | ); 274 | 275 | CREATE OPERATOR / ( 276 | leftarg = istore, 277 | rightarg = integer, 278 | procedure = divide 279 | ); 280 | 281 | 282 | CREATE FUNCTION gin_extract_istore_key(internal, internal) 283 | RETURNS internal 284 | AS 'istore' 285 | LANGUAGE C IMMUTABLE STRICT; 286 | 287 | CREATE FUNCTION gin_extract_istore_key_query(internal, internal, int2, internal, internal) 288 | RETURNS internal 289 | AS 'istore' 290 | LANGUAGE C IMMUTABLE STRICT; 291 | 292 | CREATE FUNCTION gin_consistent_istore_key(internal, int2, internal, int4, internal, internal) 293 | RETURNS bool 294 | AS 'istore' 295 | LANGUAGE C IMMUTABLE STRICT; 296 | 297 | CREATE OPERATOR CLASS istore_key_ops 298 | DEFAULT FOR TYPE istore USING gin 299 | AS 300 | OPERATOR 9 ?(istore, integer), 301 | FUNCTION 1 btint4cmp(integer, integer), 302 | FUNCTION 2 gin_extract_istore_key(internal, internal), 303 | FUNCTION 3 gin_extract_istore_key_query(internal, internal, int2, internal, internal), 304 | FUNCTION 4 gin_consistent_istore_key(internal, int2, internal, int4, internal, internal), 305 | STORAGE integer; 306 | 307 | --source file sql/casts.sql 308 | 309 | CREATE FUNCTION istore(bigistore) 310 | RETURNS istore 311 | AS 'istore', 'bigistore_to_istore' 312 | LANGUAGE C IMMUTABLE STRICT; 313 | 314 | CREATE FUNCTION bigistore(istore) 315 | RETURNS bigistore 316 | AS 'istore', 'istore_to_big_istore' 317 | LANGUAGE C IMMUTABLE STRICT; 318 | 319 | CREATE CAST (istore as bigistore) WITH FUNCTION bigistore(istore) AS IMPLICIT; 320 | CREATE CAST (bigistore as istore) WITH FUNCTION istore(bigistore) AS ASSIGNMENT; 321 | 322 | --source file sql/bigistore.sql 323 | 324 | CREATE FUNCTION exist(bigistore, integer) 325 | RETURNS boolean 326 | AS 'istore', 'bigistore_exist' 327 | LANGUAGE C IMMUTABLE STRICT; 328 | 329 | CREATE FUNCTION fetchval(bigistore, integer) 330 | RETURNS bigint 331 | AS 'istore', 'bigistore_fetchval' 332 | LANGUAGE C IMMUTABLE STRICT; 333 | 334 | CREATE FUNCTION each(IN is bigistore, 335 | OUT key integer, 336 | OUT value bigint) 337 | RETURNS SETOF record 338 | AS 'istore','bigistore_each' 339 | LANGUAGE C STRICT IMMUTABLE; 340 | 341 | CREATE FUNCTION compact(bigistore) 342 | RETURNS bigistore 343 | AS 'istore', 'bigistore_compact' 344 | LANGUAGE C IMMUTABLE STRICT; 345 | 346 | CREATE FUNCTION add(bigistore, bigistore) 347 | RETURNS bigistore 348 | AS 'istore', 'bigistore_add' 349 | LANGUAGE C IMMUTABLE STRICT; 350 | 351 | CREATE FUNCTION add(bigistore, bigint) 352 | RETURNS bigistore 353 | AS 'istore', 'bigistore_add_integer' 354 | LANGUAGE C IMMUTABLE STRICT; 355 | 356 | CREATE FUNCTION subtract(bigistore, bigistore) 357 | RETURNS bigistore 358 | AS 'istore', 'bigistore_subtract' 359 | LANGUAGE C IMMUTABLE STRICT; 360 | 361 | CREATE FUNCTION subtract(bigistore, bigint) 362 | RETURNS bigistore 363 | AS 'istore', 'bigistore_subtract_integer' 364 | LANGUAGE C IMMUTABLE STRICT; 365 | 366 | CREATE FUNCTION multiply(bigistore, bigistore) 367 | RETURNS bigistore 368 | AS 'istore', 'bigistore_multiply' 369 | LANGUAGE C IMMUTABLE STRICT; 370 | 371 | CREATE FUNCTION multiply(bigistore, bigint) 372 | RETURNS bigistore 373 | AS 'istore', 'bigistore_multiply_integer' 374 | LANGUAGE C IMMUTABLE STRICT; 375 | 376 | CREATE FUNCTION divide(bigistore, bigistore) 377 | RETURNS bigistore 378 | AS 'istore', 'bigistore_divide' 379 | LANGUAGE C IMMUTABLE STRICT; 380 | 381 | CREATE FUNCTION divide(bigistore, bigint) 382 | RETURNS bigistore 383 | AS 'istore', 'bigistore_divide_integer' 384 | LANGUAGE C IMMUTABLE STRICT; 385 | 386 | CREATE FUNCTION bigistore(integer[]) 387 | RETURNS bigistore 388 | AS 'istore', 'bigistore_from_intarray' 389 | LANGUAGE C IMMUTABLE STRICT; 390 | 391 | CREATE FUNCTION bigistore_agg_finalfn(internal) 392 | RETURNS bigistore 393 | AS 'istore' 394 | LANGUAGE C IMMUTABLE STRICT; 395 | 396 | CREATE FUNCTION sum_up(bigistore) 397 | RETURNS bigint 398 | AS 'istore', 'bigistore_sum_up' 399 | LANGUAGE C IMMUTABLE STRICT; 400 | 401 | CREATE FUNCTION sum_up(bigistore, integer) 402 | RETURNS bigint 403 | AS 'istore', 'bigistore_sum_up' 404 | LANGUAGE C IMMUTABLE STRICT; 405 | 406 | CREATE FUNCTION bigistore(integer[], integer[]) 407 | RETURNS bigistore 408 | AS 'istore', 'bigistore_array_add' 409 | LANGUAGE C IMMUTABLE STRICT; 410 | 411 | CREATE FUNCTION bigistore(integer[], bigint[]) 412 | RETURNS bigistore 413 | AS 'istore', 'bigistore_array_add' 414 | LANGUAGE C IMMUTABLE STRICT; 415 | 416 | CREATE FUNCTION istore(integer[], bigint[]) 417 | RETURNS bigistore 418 | AS 'istore', 'bigistore_array_add' 419 | LANGUAGE C IMMUTABLE STRICT; 420 | 421 | CREATE FUNCTION fill_gaps(bigistore, integer, bigint DEFAULT 0) 422 | RETURNS bigistore 423 | AS 'istore', 'bigistore_fill_gaps' 424 | LANGUAGE C IMMUTABLE STRICT; 425 | 426 | CREATE FUNCTION accumulate(bigistore) 427 | RETURNS bigistore 428 | AS 'istore', 'bigistore_accumulate' 429 | LANGUAGE C IMMUTABLE STRICT; 430 | 431 | CREATE FUNCTION accumulate(bigistore, integer) 432 | RETURNS bigistore 433 | AS 'istore', 'bigistore_accumulate' 434 | LANGUAGE C IMMUTABLE STRICT; 435 | 436 | CREATE FUNCTION istore_seed(integer, integer, bigint) 437 | RETURNS bigistore 438 | AS 'istore', 'bigistore_seed' 439 | LANGUAGE C IMMUTABLE STRICT; 440 | 441 | CREATE FUNCTION istore_val_larger(bigistore, bigistore) 442 | RETURNS bigistore 443 | AS 'istore', 'bigistore_val_larger' 444 | LANGUAGE C IMMUTABLE STRICT; 445 | 446 | CREATE FUNCTION istore_val_smaller(bigistore, bigistore) 447 | RETURNS bigistore 448 | AS 'istore', 'bigistore_val_smaller' 449 | LANGUAGE C IMMUTABLE STRICT; 450 | 451 | CREATE FUNCTION akeys(bigistore) 452 | RETURNS integer[] 453 | AS 'istore' ,'bigistore_akeys' 454 | LANGUAGE C IMMUTABLE STRICT; 455 | 456 | CREATE FUNCTION avals(bigistore) 457 | RETURNS bigint[] 458 | AS 'istore' ,'bigistore_avals' 459 | LANGUAGE C IMMUTABLE STRICT; 460 | 461 | CREATE FUNCTION skeys(bigistore) 462 | RETURNS setof integer 463 | AS 'istore' ,'bigistore_skeys' 464 | LANGUAGE C IMMUTABLE STRICT; 465 | 466 | CREATE FUNCTION svals(bigistore) 467 | RETURNS setof bigint 468 | AS 'istore' ,'bigistore_svals' 469 | LANGUAGE C IMMUTABLE STRICT; 470 | 471 | CREATE FUNCTION istore_to_json(bigistore) 472 | RETURNS json 473 | AS 'istore', 'bigistore_to_json' 474 | LANGUAGE C IMMUTABLE STRICT; 475 | 476 | 477 | CREATE AGGREGATE SUM ( 478 | sfunc = array_agg_transfn, 479 | basetype = bigistore, 480 | stype = internal, 481 | finalfunc = bigistore_agg_finalfn 482 | ); 483 | 484 | CREATE AGGREGATE MIN(bigistore) ( 485 | sfunc = istore_val_smaller, 486 | stype = bigistore 487 | ); 488 | 489 | CREATE AGGREGATE MAX(bigistore) ( 490 | sfunc = istore_val_larger, 491 | stype = bigistore 492 | ); 493 | 494 | CREATE OPERATOR -> ( 495 | leftarg = bigistore, 496 | rightarg = integer, 497 | procedure = fetchval 498 | ); 499 | 500 | CREATE OPERATOR ? ( 501 | leftarg = bigistore, 502 | rightarg = integer, 503 | procedure = exist 504 | ); 505 | 506 | CREATE OPERATOR + ( 507 | leftarg = bigistore, 508 | rightarg = bigistore, 509 | procedure = add 510 | ); 511 | 512 | CREATE OPERATOR + ( 513 | leftarg = bigistore, 514 | rightarg = bigint, 515 | procedure = add 516 | ); 517 | 518 | CREATE OPERATOR - ( 519 | leftarg = bigistore, 520 | rightarg = bigistore, 521 | procedure = subtract 522 | ); 523 | 524 | CREATE OPERATOR - ( 525 | leftarg = bigistore, 526 | rightarg = bigint, 527 | procedure = subtract 528 | ); 529 | 530 | CREATE OPERATOR * ( 531 | leftarg = bigistore, 532 | rightarg = bigistore, 533 | procedure = multiply 534 | ); 535 | 536 | CREATE OPERATOR * ( 537 | leftarg = bigistore, 538 | rightarg = bigint, 539 | procedure = multiply 540 | ); 541 | 542 | CREATE OPERATOR / ( 543 | leftarg = bigistore, 544 | rightarg = bigistore, 545 | procedure = divide 546 | ); 547 | 548 | CREATE OPERATOR / ( 549 | leftarg = bigistore, 550 | rightarg = bigint, 551 | procedure = divide 552 | ); 553 | 554 | CREATE FUNCTION gin_extract_bigistore_key(internal, internal) 555 | RETURNS internal 556 | AS 'istore' 557 | LANGUAGE C IMMUTABLE STRICT; 558 | 559 | CREATE OPERATOR CLASS bigistore_key_ops 560 | DEFAULT FOR TYPE bigistore USING gin 561 | AS 562 | OPERATOR 9 ?(bigistore, integer), 563 | FUNCTION 1 btint4cmp(integer, integer), 564 | FUNCTION 2 gin_extract_bigistore_key(internal, internal), 565 | FUNCTION 3 gin_extract_istore_key_query(internal, internal, int2, internal, internal), 566 | FUNCTION 4 gin_consistent_istore_key(internal, int2, internal, int4, internal, internal), 567 | STORAGE integer; 568 | 569 | -------------------------------------------------------------------------------- /istore--0.1.3--0.1.2.sql: -------------------------------------------------------------------------------- 1 | ----functions---- 2 | CREATE OR REPLACE FUNCTION istore_agg_finalfn(internal) 3 | RETURNS bigistore 4 | LANGUAGE c 5 | IMMUTABLE STRICT 6 | AS 'istore', $function$istore_agg_finalfn$function$; 7 | ---- 8 | CREATE OR REPLACE FUNCTION bigistore_agg_finalfn(internal) 9 | RETURNS bigistore 10 | LANGUAGE c 11 | IMMUTABLE STRICT 12 | AS 'istore', $function$bigistore_agg_finalfn$function$; 13 | 14 | ----aggregates---- 15 | DROP AGGREGATE IF EXISTS max (bigistore); 16 | CREATE AGGREGATE max(bigistore) ( 17 | SFUNC = public.istore_val_larger, 18 | STYPE = bigistore 19 | ); 20 | 21 | 22 | ---- 23 | DROP AGGREGATE IF EXISTS min (bigistore); 24 | CREATE AGGREGATE min(bigistore) ( 25 | SFUNC = public.istore_val_smaller, 26 | STYPE = bigistore 27 | ); 28 | 29 | ---- 30 | DROP AGGREGATE IF EXISTS sum (bigistore); 31 | CREATE AGGREGATE sum(bigistore) ( 32 | SFUNC = array_agg_transfn, 33 | STYPE = internal, 34 | FINALFUNC = bigistore_agg_finalfn 35 | ); 36 | 37 | ---- 38 | DROP AGGREGATE IF EXISTS max (istore); 39 | CREATE AGGREGATE max(istore) ( 40 | SFUNC = public.istore_val_larger, 41 | STYPE = istore 42 | ); 43 | 44 | 45 | ---- 46 | DROP AGGREGATE IF EXISTS min (istore); 47 | CREATE AGGREGATE min(istore) ( 48 | SFUNC = public.istore_val_smaller, 49 | STYPE = istore 50 | ); 51 | 52 | 53 | ---- 54 | DROP AGGREGATE IF EXISTS sum (istore); 55 | CREATE AGGREGATE sum(istore) ( 56 | SFUNC = array_agg_transfn, 57 | STYPE = internal, 58 | FINALFUNC = istore_agg_finalfn 59 | ); 60 | 61 | ---- 62 | DROP FUNCTION IF EXISTS istore_max_transfn(internal, bigistore); 63 | ---- 64 | DROP FUNCTION IF EXISTS istore_min_transfn(internal, bigistore); 65 | ---- 66 | DROP FUNCTION IF EXISTS istore_sum_transfn(internal, bigistore); 67 | ---- 68 | DROP FUNCTION IF EXISTS istore_agg_finalfn_pairs(internal); 69 | ---- 70 | DROP FUNCTION IF EXISTS istore_max_transfn(internal, istore); 71 | ---- 72 | DROP FUNCTION IF EXISTS istore_min_transfn(internal, istore); 73 | ---- 74 | DROP FUNCTION IF EXISTS istore_sum_transfn(internal, istore); 75 | -------------------------------------------------------------------------------- /istore--0.1.3--0.1.4.sql: -------------------------------------------------------------------------------- 1 | ----functions---- 2 | CREATE OR REPLACE FUNCTION bigistore_avl_finalfn(internal) 3 | RETURNS bigistore 4 | LANGUAGE c 5 | IMMUTABLE 6 | AS 'istore', $function$bigistore_avl_finalfn$function$; 7 | ---- 8 | CREATE OR REPLACE FUNCTION bigistore_avl_transfn(internal, integer, bigint) 9 | RETURNS internal 10 | LANGUAGE c 11 | IMMUTABLE 12 | AS 'istore', $function$bigistore_avl_transfn$function$; 13 | ---- 14 | CREATE OR REPLACE FUNCTION istore_avl_finalfn(internal) 15 | RETURNS istore 16 | LANGUAGE c 17 | IMMUTABLE 18 | AS 'istore', $function$istore_avl_finalfn$function$; 19 | ---- 20 | CREATE OR REPLACE FUNCTION istore_avl_transfn(internal, integer, integer) 21 | RETURNS internal 22 | LANGUAGE c 23 | IMMUTABLE 24 | AS 'istore', $function$istore_avl_transfn$function$; 25 | ----aggregates---- 26 | CREATE AGGREGATE isagg(integer, bigint) ( 27 | SFUNC = bigistore_avl_transfn, 28 | STYPE = internal, 29 | FINALFUNC = bigistore_avl_finalfn 30 | ); 31 | 32 | ---- 33 | CREATE AGGREGATE isagg(integer, integer) ( 34 | SFUNC = istore_avl_transfn, 35 | STYPE = internal, 36 | FINALFUNC = istore_avl_finalfn 37 | ); 38 | -------------------------------------------------------------------------------- /istore--0.1.4--0.1.3.sql: -------------------------------------------------------------------------------- 1 | ----aggregates---- 2 | DROP AGGREGATE IF EXISTS isagg (integer, bigint); 3 | ---- 4 | DROP AGGREGATE IF EXISTS isagg (integer, integer); 5 | ----functions---- 6 | DROP FUNCTION IF EXISTS bigistore_avl_finalfn(internal); 7 | ---- 8 | DROP FUNCTION IF EXISTS bigistore_avl_transfn(internal, integer, bigint); 9 | ---- 10 | DROP FUNCTION IF EXISTS istore_avl_finalfn(internal); 11 | ---- 12 | DROP FUNCTION IF EXISTS istore_avl_transfn(internal, integer, integer); 13 | -------------------------------------------------------------------------------- /istore--0.1.4--0.1.5.sql: -------------------------------------------------------------------------------- 1 | ----functions---- 2 | CREATE OR REPLACE FUNCTION istore_length(bigistore) 3 | RETURNS integer 4 | LANGUAGE c 5 | IMMUTABLE STRICT 6 | AS 'istore', $function$bigistore_length$function$; 7 | ---- 8 | CREATE OR REPLACE FUNCTION istore_length(istore) 9 | RETURNS integer 10 | LANGUAGE c 11 | IMMUTABLE STRICT 12 | AS 'istore', $function$istore_length$function$; 13 | -------------------------------------------------------------------------------- /istore--0.1.5--0.1.4.sql: -------------------------------------------------------------------------------- 1 | ----functions---- 2 | DROP FUNCTION IF EXISTS istore_length(bigistore); 3 | ---- 4 | DROP FUNCTION IF EXISTS istore_length(istore); 5 | -------------------------------------------------------------------------------- /istore--0.1.5--0.1.6.sql: -------------------------------------------------------------------------------- 1 | ----functions---- 2 | CREATE OR REPLACE FUNCTION concat(istore, istore) 3 | RETURNS istore 4 | LANGUAGE c 5 | IMMUTABLE STRICT 6 | AS 'istore', $function$istore_concat$function$; 7 | ---- 8 | CREATE OR REPLACE FUNCTION max_key(istore) 9 | RETURNS integer 10 | LANGUAGE c 11 | IMMUTABLE STRICT 12 | AS 'istore', $function$istore_max_key$function$; 13 | ---- 14 | CREATE OR REPLACE FUNCTION min_key(istore) 15 | RETURNS integer 16 | LANGUAGE c 17 | IMMUTABLE STRICT 18 | AS 'istore', $function$istore_min_key$function$; 19 | ---- 20 | CREATE OR REPLACE FUNCTION delete(bigistore, bigistore) 21 | RETURNS bigistore 22 | LANGUAGE c 23 | IMMUTABLE STRICT 24 | AS 'istore', $function$bigistore_delete_istore$function$; 25 | ---- 26 | CREATE OR REPLACE FUNCTION exists_any(bigistore, integer[]) 27 | RETURNS boolean 28 | LANGUAGE c 29 | IMMUTABLE STRICT 30 | AS 'istore', $function$bigistore_exists_any$function$; 31 | ---- 32 | CREATE OR REPLACE FUNCTION exists_all(bigistore, integer[]) 33 | RETURNS boolean 34 | LANGUAGE c 35 | IMMUTABLE STRICT 36 | AS 'istore', $function$bigistore_exists_all$function$; 37 | ---- 38 | CREATE OR REPLACE FUNCTION delete(bigistore, integer[]) 39 | RETURNS bigistore 40 | LANGUAGE c 41 | IMMUTABLE STRICT 42 | AS 'istore', $function$bigistore_delete_array$function$; 43 | ---- 44 | CREATE OR REPLACE FUNCTION delete(bigistore, integer) 45 | RETURNS bigistore 46 | LANGUAGE c 47 | IMMUTABLE STRICT 48 | AS 'istore', $function$bigistore_delete$function$; 49 | ---- 50 | CREATE OR REPLACE FUNCTION slice_array(bigistore, integer[]) 51 | RETURNS integer[] 52 | LANGUAGE c 53 | IMMUTABLE STRICT 54 | AS 'istore', $function$bigistore_slice_to_array$function$; 55 | ---- 56 | CREATE OR REPLACE FUNCTION slice(bigistore, integer[]) 57 | RETURNS bigistore 58 | LANGUAGE c 59 | IMMUTABLE STRICT 60 | AS 'istore', $function$bigistore_slice$function$; 61 | ---- 62 | CREATE OR REPLACE FUNCTION istore_to_matrix(bigistore) 63 | RETURNS integer[] 64 | LANGUAGE c 65 | IMMUTABLE STRICT 66 | AS 'istore', $function$bigistore_to_matrix$function$; 67 | ---- 68 | CREATE OR REPLACE FUNCTION istore_to_array(bigistore) 69 | RETURNS integer[] 70 | LANGUAGE c 71 | IMMUTABLE STRICT 72 | AS 'istore', $function$bigistore_to_array$function$; 73 | ---- 74 | CREATE OR REPLACE FUNCTION concat(bigistore, bigistore) 75 | RETURNS bigistore 76 | LANGUAGE c 77 | IMMUTABLE STRICT 78 | AS 'istore', $function$bigistore_concat$function$; 79 | ---- 80 | CREATE OR REPLACE FUNCTION max_key(bigistore) 81 | RETURNS integer 82 | LANGUAGE c 83 | IMMUTABLE STRICT 84 | AS 'istore', $function$bigistore_max_key$function$; 85 | ---- 86 | CREATE OR REPLACE FUNCTION min_key(bigistore) 87 | RETURNS integer 88 | LANGUAGE c 89 | IMMUTABLE STRICT 90 | AS 'istore', $function$bigistore_min_key$function$; 91 | ---- 92 | CREATE OR REPLACE FUNCTION delete(istore, istore) 93 | RETURNS istore 94 | LANGUAGE c 95 | IMMUTABLE STRICT 96 | AS 'istore', $function$istore_delete_istore$function$; 97 | ---- 98 | CREATE OR REPLACE FUNCTION exists_any(istore, integer[]) 99 | RETURNS boolean 100 | LANGUAGE c 101 | IMMUTABLE STRICT 102 | AS 'istore', $function$istore_exists_any$function$; 103 | ---- 104 | CREATE OR REPLACE FUNCTION exists_all(istore, integer[]) 105 | RETURNS boolean 106 | LANGUAGE c 107 | IMMUTABLE STRICT 108 | AS 'istore', $function$istore_exists_all$function$; 109 | ---- 110 | CREATE OR REPLACE FUNCTION delete(istore, integer[]) 111 | RETURNS istore 112 | LANGUAGE c 113 | IMMUTABLE STRICT 114 | AS 'istore', $function$istore_delete_array$function$; 115 | ---- 116 | CREATE OR REPLACE FUNCTION delete(istore, integer) 117 | RETURNS istore 118 | LANGUAGE c 119 | IMMUTABLE STRICT 120 | AS 'istore', $function$istore_delete$function$; 121 | ---- 122 | CREATE OR REPLACE FUNCTION slice_array(istore, integer[]) 123 | RETURNS integer[] 124 | LANGUAGE c 125 | IMMUTABLE STRICT 126 | AS 'istore', $function$istore_slice_to_array$function$; 127 | ---- 128 | CREATE OR REPLACE FUNCTION slice(istore, integer[]) 129 | RETURNS istore 130 | LANGUAGE c 131 | IMMUTABLE STRICT 132 | AS 'istore', $function$istore_slice$function$; 133 | ---- 134 | CREATE OR REPLACE FUNCTION istore_to_matrix(istore) 135 | RETURNS integer[] 136 | LANGUAGE c 137 | IMMUTABLE STRICT 138 | AS 'istore', $function$istore_to_matrix$function$; 139 | ---- 140 | CREATE OR REPLACE FUNCTION istore_to_array(istore) 141 | RETURNS integer[] 142 | LANGUAGE c 143 | IMMUTABLE STRICT 144 | AS 'istore', $function$istore_to_array$function$; 145 | ----operators---- 146 | CREATE OPERATOR ?& ( 147 | PROCEDURE = exists_all, 148 | LEFTARG = bigistore, 149 | RIGHTARG = _int4 150 | ); 151 | 152 | ---- 153 | CREATE OPERATOR %# ( 154 | PROCEDURE = istore_to_matrix, 155 | RIGHTARG = bigistore 156 | ); 157 | 158 | ---- 159 | CREATE OPERATOR %% ( 160 | PROCEDURE = istore_to_array, 161 | RIGHTARG = bigistore 162 | ); 163 | 164 | ---- 165 | CREATE OPERATOR -> ( 166 | PROCEDURE = slice_array, 167 | LEFTARG = bigistore, 168 | RIGHTARG = _int4 169 | ); 170 | 171 | ---- 172 | CREATE OPERATOR -> ( 173 | PROCEDURE = slice_array, 174 | LEFTARG = istore, 175 | RIGHTARG = _int4 176 | ); 177 | 178 | ---- 179 | CREATE OPERATOR || ( 180 | PROCEDURE = concat, 181 | LEFTARG = bigistore, 182 | RIGHTARG = bigistore 183 | ); 184 | 185 | ---- 186 | CREATE OPERATOR ?| ( 187 | PROCEDURE = exists_any, 188 | LEFTARG = bigistore, 189 | RIGHTARG = _int4 190 | ); 191 | 192 | ---- 193 | CREATE OPERATOR %# ( 194 | PROCEDURE = istore_to_matrix, 195 | RIGHTARG = istore 196 | ); 197 | 198 | ---- 199 | CREATE OPERATOR %% ( 200 | PROCEDURE = istore_to_array, 201 | RIGHTARG = istore 202 | ); 203 | 204 | ---- 205 | CREATE OPERATOR || ( 206 | PROCEDURE = concat, 207 | LEFTARG = istore, 208 | RIGHTARG = istore 209 | ); 210 | 211 | ---- 212 | CREATE OPERATOR ?| ( 213 | PROCEDURE = exists_any, 214 | LEFTARG = istore, 215 | RIGHTARG = _int4 216 | ); 217 | 218 | ---- 219 | CREATE OPERATOR ?& ( 220 | PROCEDURE = exists_all, 221 | LEFTARG = istore, 222 | RIGHTARG = _int4 223 | ); 224 | -------------------------------------------------------------------------------- /istore--0.1.6--0.1.5.sql: -------------------------------------------------------------------------------- 1 | ----operators---- 2 | DROP OPERATOR IF EXISTS ?& (bigistore, _int4); 3 | ---- 4 | DROP OPERATOR IF EXISTS %# (NONE, bigistore); 5 | ---- 6 | DROP OPERATOR IF EXISTS %% (NONE, bigistore); 7 | ---- 8 | DROP OPERATOR IF EXISTS -> (bigistore, _int4); 9 | ---- 10 | DROP OPERATOR IF EXISTS -> (istore, _int4); 11 | ---- 12 | DROP OPERATOR IF EXISTS || (bigistore, bigistore); 13 | ---- 14 | DROP OPERATOR IF EXISTS ?| (bigistore, _int4); 15 | ---- 16 | DROP OPERATOR IF EXISTS %# (NONE, istore); 17 | ---- 18 | DROP OPERATOR IF EXISTS %% (NONE, istore); 19 | ---- 20 | DROP OPERATOR IF EXISTS || (istore, istore); 21 | ---- 22 | DROP OPERATOR IF EXISTS ?| (istore, _int4); 23 | ---- 24 | DROP OPERATOR IF EXISTS ?& (istore, _int4); 25 | ----functions---- 26 | DROP FUNCTION IF EXISTS concat(istore, istore); 27 | ---- 28 | DROP FUNCTION IF EXISTS max_key(istore); 29 | ---- 30 | DROP FUNCTION IF EXISTS min_key(istore); 31 | ---- 32 | DROP FUNCTION IF EXISTS delete(bigistore, bigistore); 33 | ---- 34 | DROP FUNCTION IF EXISTS exists_any(bigistore, integer[]); 35 | ---- 36 | DROP FUNCTION IF EXISTS exists_all(bigistore, integer[]); 37 | ---- 38 | DROP FUNCTION IF EXISTS delete(bigistore, integer[]); 39 | ---- 40 | DROP FUNCTION IF EXISTS delete(bigistore, integer); 41 | ---- 42 | DROP FUNCTION IF EXISTS slice_array(bigistore, integer[]); 43 | ---- 44 | DROP FUNCTION IF EXISTS slice(bigistore, integer[]); 45 | ---- 46 | DROP FUNCTION IF EXISTS istore_to_matrix(bigistore); 47 | ---- 48 | DROP FUNCTION IF EXISTS istore_to_array(bigistore); 49 | ---- 50 | DROP FUNCTION IF EXISTS concat(bigistore, bigistore); 51 | ---- 52 | DROP FUNCTION IF EXISTS max_key(bigistore); 53 | ---- 54 | DROP FUNCTION IF EXISTS min_key(bigistore); 55 | ---- 56 | DROP FUNCTION IF EXISTS delete(istore, istore); 57 | ---- 58 | DROP FUNCTION IF EXISTS exists_any(istore, integer[]); 59 | ---- 60 | DROP FUNCTION IF EXISTS exists_all(istore, integer[]); 61 | ---- 62 | DROP FUNCTION IF EXISTS delete(istore, integer[]); 63 | ---- 64 | DROP FUNCTION IF EXISTS delete(istore, integer); 65 | ---- 66 | DROP FUNCTION IF EXISTS slice_array(istore, integer[]); 67 | ---- 68 | DROP FUNCTION IF EXISTS slice(istore, integer[]); 69 | ---- 70 | DROP FUNCTION IF EXISTS istore_to_matrix(istore); 71 | ---- 72 | DROP FUNCTION IF EXISTS istore_to_array(istore); 73 | -------------------------------------------------------------------------------- /istore--0.1.6--0.1.7.sql: -------------------------------------------------------------------------------- 1 | ----functions---- 2 | CREATE OR REPLACE FUNCTION clamp_above(bigistore, integer) 3 | RETURNS bigistore 4 | LANGUAGE c 5 | IMMUTABLE STRICT 6 | AS 'istore', $function$bigistore_clamp_above$function$; 7 | ---- 8 | CREATE OR REPLACE FUNCTION clamp_below(bigistore, integer) 9 | RETURNS bigistore 10 | LANGUAGE c 11 | IMMUTABLE STRICT 12 | AS 'istore', $function$bigistore_clamp_below$function$; 13 | ---- 14 | CREATE OR REPLACE FUNCTION clamp_above(istore, integer) 15 | RETURNS istore 16 | LANGUAGE c 17 | IMMUTABLE STRICT 18 | AS 'istore', $function$istore_clamp_above$function$; 19 | ---- 20 | CREATE OR REPLACE FUNCTION clamp_below(istore, integer) 21 | RETURNS istore 22 | LANGUAGE c 23 | IMMUTABLE STRICT 24 | AS 'istore', $function$istore_clamp_below$function$; 25 | -------------------------------------------------------------------------------- /istore--0.1.7--0.1.6.sql: -------------------------------------------------------------------------------- 1 | ----functions---- 2 | DROP FUNCTION IF EXISTS clamp_above(bigistore, integer); 3 | ---- 4 | DROP FUNCTION IF EXISTS clamp_below(bigistore, integer); 5 | ---- 6 | DROP FUNCTION IF EXISTS clamp_above(istore, integer); 7 | ---- 8 | DROP FUNCTION IF EXISTS clamp_below(istore, integer); 9 | -------------------------------------------------------------------------------- /istore--0.1.8--0.1.7.sql: -------------------------------------------------------------------------------- 1 | --require types 2 | --require istore 3 | --require bigistore 4 | --require casts 5 | 6 | DO $$ 7 | DECLARE version_num integer; 8 | BEGIN 9 | SELECT current_setting('server_version_num') INTO STRICT version_num; 10 | IF version_num > 90600 THEN 11 | EXECUTE $E$ ALTER FUNCTION istore_in(cstring) PARALLEL UNSAFE $E$; 12 | EXECUTE $E$ ALTER FUNCTION istore_out(istore) PARALLEL UNSAFE $E$; 13 | EXECUTE $E$ ALTER FUNCTION istore_send(istore) PARALLEL UNSAFE $E$; 14 | EXECUTE $E$ ALTER FUNCTION istore_recv(internal) PARALLEL UNSAFE $E$; 15 | EXECUTE $E$ ALTER FUNCTION bigistore_in(cstring) PARALLEL UNSAFE $E$; 16 | EXECUTE $E$ ALTER FUNCTION bigistore_out(bigistore) PARALLEL UNSAFE $E$; 17 | EXECUTE $E$ ALTER FUNCTION bigistore_send(bigistore) PARALLEL UNSAFE $E$; 18 | EXECUTE $E$ ALTER FUNCTION bigistore_recv(internal) PARALLEL UNSAFE $E$; 19 | EXECUTE $E$ ALTER FUNCTION exist(istore, integer) PARALLEL UNSAFE $E$; 20 | EXECUTE $E$ ALTER FUNCTION fetchval(istore, integer) PARALLEL UNSAFE $E$; 21 | EXECUTE $E$ ALTER FUNCTION each(istore) PARALLEL UNSAFE $E$; 22 | EXECUTE $E$ ALTER FUNCTION min_key(istore) PARALLEL UNSAFE $E$; 23 | EXECUTE $E$ ALTER FUNCTION max_key(istore) PARALLEL UNSAFE $E$; 24 | EXECUTE $E$ ALTER FUNCTION compact(istore) PARALLEL UNSAFE $E$; 25 | EXECUTE $E$ ALTER FUNCTION add(istore, istore) PARALLEL UNSAFE $E$; 26 | EXECUTE $E$ ALTER FUNCTION add(istore, integer) PARALLEL UNSAFE $E$; 27 | EXECUTE $E$ ALTER FUNCTION subtract(istore, istore) PARALLEL UNSAFE $E$; 28 | EXECUTE $E$ ALTER FUNCTION subtract(istore, integer) PARALLEL UNSAFE $E$; 29 | EXECUTE $E$ ALTER FUNCTION multiply(istore, istore) PARALLEL UNSAFE $E$; 30 | EXECUTE $E$ ALTER FUNCTION multiply(istore, integer) PARALLEL UNSAFE $E$; 31 | EXECUTE $E$ ALTER FUNCTION divide(istore, istore) PARALLEL UNSAFE $E$; 32 | EXECUTE $E$ ALTER FUNCTION divide(istore, integer) PARALLEL UNSAFE $E$; 33 | EXECUTE $E$ ALTER FUNCTION concat(istore, istore) PARALLEL UNSAFE $E$; 34 | EXECUTE $E$ ALTER FUNCTION istore(integer[]) PARALLEL UNSAFE $E$; 35 | EXECUTE $E$ ALTER FUNCTION sum_up(istore) PARALLEL UNSAFE $E$; 36 | EXECUTE $E$ ALTER FUNCTION sum_up(istore, integer) PARALLEL UNSAFE $E$; 37 | EXECUTE $E$ ALTER FUNCTION istore(integer[], integer[]) PARALLEL UNSAFE $E$; 38 | EXECUTE $E$ ALTER FUNCTION fill_gaps(istore, integer, integer) PARALLEL UNSAFE $E$; 39 | EXECUTE $E$ ALTER FUNCTION accumulate(istore) PARALLEL UNSAFE $E$; 40 | EXECUTE $E$ ALTER FUNCTION accumulate(istore, integer) PARALLEL UNSAFE $E$; 41 | EXECUTE $E$ ALTER FUNCTION istore_seed(integer, integer, integer) PARALLEL UNSAFE $E$; 42 | EXECUTE $E$ ALTER FUNCTION istore_val_larger(istore, istore) PARALLEL UNSAFE $E$; 43 | EXECUTE $E$ ALTER FUNCTION istore_val_smaller(istore, istore) PARALLEL UNSAFE $E$; 44 | EXECUTE $E$ ALTER FUNCTION akeys(istore) PARALLEL UNSAFE $E$; 45 | EXECUTE $E$ ALTER FUNCTION avals(istore) PARALLEL UNSAFE $E$; 46 | EXECUTE $E$ ALTER FUNCTION skeys(istore) PARALLEL UNSAFE $E$; 47 | EXECUTE $E$ ALTER FUNCTION svals(istore) PARALLEL UNSAFE $E$; 48 | EXECUTE $E$ ALTER FUNCTION istore_sum_transfn(internal, istore) PARALLEL UNSAFE $E$; 49 | EXECUTE $E$ ALTER FUNCTION istore_min_transfn(internal, istore) PARALLEL UNSAFE $E$; 50 | EXECUTE $E$ ALTER FUNCTION istore_max_transfn(internal, istore) PARALLEL UNSAFE $E$; 51 | EXECUTE $E$ ALTER FUNCTION istore_agg_finalfn_pairs(internal) PARALLEL UNSAFE $E$; 52 | EXECUTE $E$ ALTER FUNCTION istore_to_json(istore) PARALLEL UNSAFE $E$; 53 | EXECUTE $E$ ALTER FUNCTION istore_to_array(istore) PARALLEL UNSAFE $E$; 54 | EXECUTE $E$ ALTER FUNCTION istore_to_matrix(istore) PARALLEL UNSAFE $E$; 55 | EXECUTE $E$ ALTER FUNCTION slice(istore, integer[]) PARALLEL UNSAFE $E$; 56 | EXECUTE $E$ ALTER FUNCTION slice_array(istore, integer[]) PARALLEL UNSAFE $E$; 57 | EXECUTE $E$ ALTER FUNCTION clamp_below(istore,int) PARALLEL UNSAFE $E$; 58 | EXECUTE $E$ ALTER FUNCTION clamp_above(istore,int) PARALLEL UNSAFE $E$; 59 | EXECUTE $E$ ALTER FUNCTION delete(istore,int) PARALLEL UNSAFE $E$; 60 | EXECUTE $E$ ALTER FUNCTION delete(istore,int[]) PARALLEL UNSAFE $E$; 61 | EXECUTE $E$ ALTER FUNCTION exists_all(istore,integer[]) PARALLEL UNSAFE $E$; 62 | EXECUTE $E$ ALTER FUNCTION exists_any(istore,integer[]) PARALLEL UNSAFE $E$; 63 | EXECUTE $E$ ALTER FUNCTION delete(istore, istore) PARALLEL UNSAFE $E$; 64 | EXECUTE $E$ ALTER FUNCTION bigistore_agg_finalfn(internal) PARALLEL UNSAFE $E$; 65 | EXECUTE $E$ ALTER FUNCTION istore_avl_transfn(internal, int, int) PARALLEL UNSAFE $E$; 66 | EXECUTE $E$ ALTER FUNCTION istore_avl_finalfn(internal) PARALLEL UNSAFE $E$; 67 | EXECUTE $E$ ALTER FUNCTION istore_length(istore) PARALLEL UNSAFE $E$; 68 | EXECUTE $E$ ALTER FUNCTION gin_extract_istore_key(internal, internal) PARALLEL UNSAFE $E$; 69 | EXECUTE $E$ ALTER FUNCTION gin_extract_istore_key_query(internal, internal, int2, internal, internal) PARALLEL UNSAFE $E$; 70 | EXECUTE $E$ ALTER FUNCTION gin_consistent_istore_key(internal, int2, internal, int4, internal, internal) PARALLEL UNSAFE $E$; 71 | EXECUTE $E$ ALTER FUNCTION istore(bigistore) PARALLEL UNSAFE $E$; 72 | EXECUTE $E$ ALTER FUNCTION bigistore(istore) PARALLEL UNSAFE $E$; 73 | EXECUTE $E$ ALTER FUNCTION exist(bigistore, integer) PARALLEL UNSAFE $E$; 74 | EXECUTE $E$ ALTER FUNCTION fetchval(bigistore, integer) PARALLEL UNSAFE $E$; 75 | EXECUTE $E$ ALTER FUNCTION each(is bigistore) PARALLEL UNSAFE $E$; 76 | EXECUTE $E$ ALTER FUNCTION min_key(bigistore) PARALLEL UNSAFE $E$; 77 | EXECUTE $E$ ALTER FUNCTION max_key(bigistore) PARALLEL UNSAFE $E$; 78 | EXECUTE $E$ ALTER FUNCTION compact(bigistore) PARALLEL UNSAFE $E$; 79 | EXECUTE $E$ ALTER FUNCTION add(bigistore, bigistore) PARALLEL UNSAFE $E$; 80 | EXECUTE $E$ ALTER FUNCTION add(bigistore, bigint) PARALLEL UNSAFE $E$; 81 | EXECUTE $E$ ALTER FUNCTION subtract(bigistore, bigistore) PARALLEL UNSAFE $E$; 82 | EXECUTE $E$ ALTER FUNCTION subtract(bigistore, bigint) PARALLEL UNSAFE $E$; 83 | EXECUTE $E$ ALTER FUNCTION multiply(bigistore, bigistore) PARALLEL UNSAFE $E$; 84 | EXECUTE $E$ ALTER FUNCTION multiply(bigistore, bigint) PARALLEL UNSAFE $E$; 85 | EXECUTE $E$ ALTER FUNCTION divide(bigistore, bigistore) PARALLEL UNSAFE $E$; 86 | EXECUTE $E$ ALTER FUNCTION divide(bigistore, bigint) PARALLEL UNSAFE $E$; 87 | EXECUTE $E$ ALTER FUNCTION concat(bigistore, bigistore) PARALLEL UNSAFE $E$; 88 | EXECUTE $E$ ALTER FUNCTION bigistore(integer[]) PARALLEL UNSAFE $E$; 89 | EXECUTE $E$ ALTER FUNCTION sum_up(bigistore) PARALLEL UNSAFE $E$; 90 | EXECUTE $E$ ALTER FUNCTION sum_up(bigistore, integer) PARALLEL UNSAFE $E$; 91 | EXECUTE $E$ ALTER FUNCTION bigistore(integer[], integer[]) PARALLEL UNSAFE $E$; 92 | EXECUTE $E$ ALTER FUNCTION bigistore(integer[], bigint[]) PARALLEL UNSAFE $E$; 93 | EXECUTE $E$ ALTER FUNCTION istore(integer[], bigint[]) PARALLEL UNSAFE $E$; 94 | EXECUTE $E$ ALTER FUNCTION fill_gaps(bigistore, integer, bigint) PARALLEL UNSAFE $E$; 95 | EXECUTE $E$ ALTER FUNCTION accumulate(bigistore) PARALLEL UNSAFE $E$; 96 | EXECUTE $E$ ALTER FUNCTION accumulate(bigistore, integer) PARALLEL UNSAFE $E$; 97 | EXECUTE $E$ ALTER FUNCTION istore_seed(integer, integer, bigint) PARALLEL UNSAFE $E$; 98 | EXECUTE $E$ ALTER FUNCTION istore_val_larger(bigistore, bigistore) PARALLEL UNSAFE $E$; 99 | EXECUTE $E$ ALTER FUNCTION istore_val_smaller(bigistore, bigistore) PARALLEL UNSAFE $E$; 100 | EXECUTE $E$ ALTER FUNCTION akeys(bigistore) PARALLEL UNSAFE $E$; 101 | EXECUTE $E$ ALTER FUNCTION avals(bigistore) PARALLEL UNSAFE $E$; 102 | EXECUTE $E$ ALTER FUNCTION skeys(bigistore) PARALLEL UNSAFE $E$; 103 | EXECUTE $E$ ALTER FUNCTION svals(bigistore) PARALLEL UNSAFE $E$; 104 | EXECUTE $E$ ALTER FUNCTION istore_length(bigistore) PARALLEL UNSAFE $E$; 105 | EXECUTE $E$ ALTER FUNCTION istore_to_json(bigistore) PARALLEL UNSAFE $E$; 106 | EXECUTE $E$ ALTER FUNCTION istore_to_array(bigistore) PARALLEL UNSAFE $E$; 107 | EXECUTE $E$ ALTER FUNCTION istore_to_matrix(bigistore) PARALLEL UNSAFE $E$; 108 | EXECUTE $E$ ALTER FUNCTION slice(bigistore, integer[]) PARALLEL UNSAFE $E$; 109 | EXECUTE $E$ ALTER FUNCTION slice_array(bigistore, integer[]) PARALLEL UNSAFE $E$; 110 | EXECUTE $E$ ALTER FUNCTION clamp_below(bigistore,int) PARALLEL UNSAFE $E$; 111 | EXECUTE $E$ ALTER FUNCTION clamp_above(bigistore,int) PARALLEL UNSAFE $E$; 112 | EXECUTE $E$ ALTER FUNCTION delete(bigistore,int) PARALLEL UNSAFE $E$; 113 | EXECUTE $E$ ALTER FUNCTION delete(bigistore,int[]) PARALLEL UNSAFE $E$; 114 | EXECUTE $E$ ALTER FUNCTION exists_all(bigistore,integer[]) PARALLEL UNSAFE $E$; 115 | EXECUTE $E$ ALTER FUNCTION exists_any(bigistore,integer[]) PARALLEL UNSAFE $E$; 116 | EXECUTE $E$ ALTER FUNCTION delete(bigistore,bigistore) PARALLEL UNSAFE $E$; 117 | EXECUTE $E$ ALTER FUNCTION istore_sum_transfn(internal, bigistore) PARALLEL UNSAFE $E$; 118 | EXECUTE $E$ ALTER FUNCTION istore_min_transfn(internal, bigistore) PARALLEL UNSAFE $E$; 119 | EXECUTE $E$ ALTER FUNCTION istore_max_transfn(internal, bigistore) PARALLEL UNSAFE $E$; 120 | EXECUTE $E$ ALTER FUNCTION bigistore_avl_transfn(internal, int, bigint) PARALLEL UNSAFE $E$; 121 | EXECUTE $E$ ALTER FUNCTION bigistore_avl_finalfn(internal) PARALLEL UNSAFE $E$; 122 | 123 | EXECUTE $E$ DROP AGGREGATE SUM (istore) $E$; 124 | EXECUTE $E$ DROP AGGREGATE MIN (istore) $E$; 125 | EXECUTE $E$ DROP AGGREGATE MAX (istore) $E$; 126 | EXECUTE $E$ DROP AGGREGATE SUM (bigistore) $E$; 127 | EXECUTE $E$ DROP AGGREGATE MIN (bigistore) $E$; 128 | EXECUTE $E$ DROP AGGREGATE MAX (bigistore) $E$; 129 | 130 | EXECUTE $E$ DROP FUNCTION istore_agg_sum_combine(internal, internal) $E$; 131 | EXECUTE $E$ DROP FUNCTION istore_agg_max_combine(internal, internal) $E$; 132 | EXECUTE $E$ DROP FUNCTION istore_agg_min_combine(internal, internal) $E$; 133 | EXECUTE $E$ DROP FUNCTION istore_agg_serial(internal) $E$; 134 | EXECUTE $E$ DROP FUNCTION istore_agg_deserial(bytea, internal) $E$; 135 | 136 | EXECUTE $E$ CREATE AGGREGATE SUM (istore) ( 137 | sfunc = istore_sum_transfn, 138 | stype = internal, 139 | finalfunc = bigistore_agg_finalfn, 140 | parallel = UNSAFE 141 | ) $E$ ; 142 | 143 | EXECUTE $E$ CREATE AGGREGATE MIN (istore) ( 144 | sfunc = istore_min_transfn, 145 | stype = internal, 146 | finalfunc = istore_agg_finalfn_pairs, 147 | parallel = UNSAFE 148 | ) $E$ ; 149 | 150 | EXECUTE $E$ CREATE AGGREGATE MAX (istore) ( 151 | sfunc = istore_max_transfn, 152 | stype = internal, 153 | finalfunc = istore_agg_finalfn_pairs, 154 | parallel = UNSAFE 155 | ) $E$ ; 156 | 157 | EXECUTE $E$ CREATE AGGREGATE SUM (bigistore) ( 158 | sfunc = istore_sum_transfn, 159 | stype = internal, 160 | finalfunc = bigistore_agg_finalfn, 161 | parallel = UNSAFE 162 | ) $E$; 163 | 164 | EXECUTE $E$ CREATE AGGREGATE MIN (bigistore) ( 165 | sfunc = istore_min_transfn, 166 | stype = internal, 167 | finalfunc = bigistore_agg_finalfn, 168 | parallel = UNSAFE 169 | ) $E$; 170 | 171 | EXECUTE $E$ CREATE AGGREGATE MAX (bigistore) ( 172 | sfunc = istore_max_transfn, 173 | stype = internal, 174 | finalfunc = bigistore_agg_finalfn, 175 | parallel = UNSAFE 176 | ) $E$; 177 | END IF; 178 | END; 179 | $$; 180 | 181 | -------------------------------------------------------------------------------- /istore--0.1.8--0.1.9.sql: -------------------------------------------------------------------------------- 1 | CREATE FUNCTION istore_in_range(istore, int, int) 2 | RETURNS boolean 3 | AS 'istore', 'istore_in_range' 4 | LANGUAGE C IMMUTABLE STRICT; 5 | 6 | CREATE FUNCTION istore_less_than(istore, int) 7 | RETURNS boolean 8 | AS 'istore', 'istore_less_than' 9 | LANGUAGE C IMMUTABLE STRICT; 10 | 11 | CREATE FUNCTION istore_less_than_or_equal(istore, int) 12 | RETURNS boolean 13 | AS 'istore', 'istore_less_than_or_equal' 14 | LANGUAGE C IMMUTABLE STRICT; 15 | 16 | CREATE FUNCTION istore_greater_than(istore, int) 17 | RETURNS boolean 18 | AS 'istore', 'istore_greater_than' 19 | LANGUAGE C IMMUTABLE STRICT; 20 | 21 | CREATE FUNCTION istore_greater_than_or_equal(istore, int) 22 | RETURNS boolean 23 | AS 'istore', 'istore_greater_than_or_equal' 24 | LANGUAGE C IMMUTABLE STRICT; 25 | 26 | CREATE FUNCTION istore_floor(istore, int) 27 | RETURNS istore 28 | AS 'istore', 'istore_floor' 29 | LANGUAGE C IMMUTABLE STRICT; 30 | 31 | CREATE FUNCTION istore_ceiling(istore, int) 32 | RETURNS istore 33 | AS 'istore', 'istore_ceiling' 34 | LANGUAGE C IMMUTABLE STRICT; 35 | 36 | CREATE FUNCTION istore_in_range(bigistore, bigint, bigint) 37 | RETURNS boolean 38 | AS 'istore', 'bigistore_in_range' 39 | LANGUAGE C IMMUTABLE STRICT; 40 | 41 | CREATE FUNCTION istore_less_than(bigistore, bigint) 42 | RETURNS boolean 43 | AS 'istore', 'bigistore_less_than' 44 | LANGUAGE C IMMUTABLE STRICT; 45 | 46 | CREATE FUNCTION istore_less_than_or_equal(bigistore, bigint) 47 | RETURNS boolean 48 | AS 'istore', 'bigistore_less_than_or_equal' 49 | LANGUAGE C IMMUTABLE STRICT; 50 | 51 | CREATE FUNCTION istore_greater_than(bigistore, bigint) 52 | RETURNS boolean 53 | AS 'istore', 'bigistore_greater_than' 54 | LANGUAGE C IMMUTABLE STRICT; 55 | 56 | CREATE FUNCTION istore_greater_than_or_equal(bigistore, bigint) 57 | RETURNS boolean 58 | AS 'istore', 'bigistore_greater_than_or_equal' 59 | LANGUAGE C IMMUTABLE STRICT; 60 | 61 | CREATE FUNCTION istore_floor(bigistore, bigint) 62 | RETURNS bigistore 63 | AS 'istore', 'bigistore_floor' 64 | LANGUAGE C IMMUTABLE STRICT; 65 | 66 | CREATE FUNCTION istore_ceiling(bigistore, bigint) 67 | RETURNS bigistore 68 | AS 'istore', 'bigistore_ceiling' 69 | LANGUAGE C IMMUTABLE STRICT; 70 | -------------------------------------------------------------------------------- /istore--0.1.9--0.1.10.sql: -------------------------------------------------------------------------------- 1 | CREATE FUNCTION slice(istore, min integer, max integer) 2 | RETURNS istore 3 | AS 'istore', 'istore_slice_min_max' 4 | LANGUAGE C IMMUTABLE STRICT; 5 | 6 | CREATE FUNCTION slice(bigistore, min integer, max integer) 7 | RETURNS bigistore 8 | AS 'istore', 'bigistore_slice_min_max' 9 | LANGUAGE C IMMUTABLE STRICT; -------------------------------------------------------------------------------- /istore--0.1.9--0.1.8.sql: -------------------------------------------------------------------------------- 1 | DROP FUNCTION IF EXISTS istore_in_range(istore, int, int); 2 | DROP FUNCTION IF EXISTS istore_less_than(istore, int); 3 | DROP FUNCTION IF EXISTS istore_less_than_or_equal(istore, int); 4 | DROP FUNCTION IF EXISTS istore_greater_than(istore, int); 5 | DROP FUNCTION IF EXISTS istore_greater_than_or_equal(istore, int); 6 | DROP FUNCTION IF EXISTS istore_floor(istore, int); 7 | DROP FUNCTION IF EXISTS istore_ceiling(istore, int); 8 | DROP FUNCTION IF EXISTS istore_in_range(bigistore, bigint, bigint); 9 | DROP FUNCTION IF EXISTS istore_less_than(bigistore, bigint); 10 | DROP FUNCTION IF EXISTS istore_less_than_or_equal(bigistore, bigint); 11 | DROP FUNCTION IF EXISTS istore_greater_than(bigistore, bigint); 12 | DROP FUNCTION IF EXISTS istore_greater_than_or_equal(bigistore, bigint); 13 | DROP FUNCTION IF EXISTS istore_floor(bigistore, bigint); 14 | DROP FUNCTION IF EXISTS istore_ceiling(bigistore, bigint); 15 | -------------------------------------------------------------------------------- /istore.control: -------------------------------------------------------------------------------- 1 | # istore extension 2 | comment = 'an integer based hstore' 3 | default_version = '0.1.12' 4 | relocatable = true 5 | module_pathname = '$libdir/istore' 6 | requires = '' 7 | -------------------------------------------------------------------------------- /sql/bigistore.sql: -------------------------------------------------------------------------------- 1 | --require types 2 | --require istore 3 | 4 | CREATE FUNCTION exist(bigistore, integer) 5 | RETURNS boolean 6 | AS 'istore', 'bigistore_exist' 7 | LANGUAGE C IMMUTABLE STRICT; 8 | 9 | CREATE FUNCTION fetchval(bigistore, integer) 10 | RETURNS bigint 11 | AS 'istore', 'bigistore_fetchval' 12 | LANGUAGE C IMMUTABLE STRICT; 13 | 14 | CREATE FUNCTION each(IN is bigistore, 15 | OUT key integer, 16 | OUT value bigint) 17 | RETURNS SETOF record 18 | AS 'istore','bigistore_each' 19 | LANGUAGE C STRICT IMMUTABLE; 20 | 21 | CREATE FUNCTION min_key(bigistore) 22 | RETURNS integer 23 | AS 'istore', 'bigistore_min_key' 24 | LANGUAGE C IMMUTABLE STRICT; 25 | 26 | CREATE FUNCTION max_key(bigistore) 27 | RETURNS integer 28 | AS 'istore', 'bigistore_max_key' 29 | LANGUAGE C IMMUTABLE STRICT; 30 | 31 | CREATE FUNCTION max_value(bigistore) 32 | RETURNS integer 33 | AS 'istore', 'bigistore_max_value' 34 | LANGUAGE C IMMUTABLE STRICT; 35 | 36 | CREATE FUNCTION compact(bigistore) 37 | RETURNS bigistore 38 | AS 'istore', 'bigistore_compact' 39 | LANGUAGE C IMMUTABLE STRICT; 40 | 41 | CREATE FUNCTION add(bigistore, bigistore) 42 | RETURNS bigistore 43 | AS 'istore', 'bigistore_add' 44 | LANGUAGE C IMMUTABLE STRICT; 45 | 46 | CREATE FUNCTION add(bigistore, bigint) 47 | RETURNS bigistore 48 | AS 'istore', 'bigistore_add_integer' 49 | LANGUAGE C IMMUTABLE STRICT; 50 | 51 | CREATE FUNCTION subtract(bigistore, bigistore) 52 | RETURNS bigistore 53 | AS 'istore', 'bigistore_subtract' 54 | LANGUAGE C IMMUTABLE STRICT; 55 | 56 | CREATE FUNCTION subtract(bigistore, bigint) 57 | RETURNS bigistore 58 | AS 'istore', 'bigistore_subtract_integer' 59 | LANGUAGE C IMMUTABLE STRICT; 60 | 61 | CREATE FUNCTION multiply(bigistore, bigistore) 62 | RETURNS bigistore 63 | AS 'istore', 'bigistore_multiply' 64 | LANGUAGE C IMMUTABLE STRICT; 65 | 66 | CREATE FUNCTION multiply(bigistore, bigint) 67 | RETURNS bigistore 68 | AS 'istore', 'bigistore_multiply_integer' 69 | LANGUAGE C IMMUTABLE STRICT; 70 | 71 | CREATE FUNCTION divide(bigistore, bigistore) 72 | RETURNS bigistore 73 | AS 'istore', 'bigistore_divide' 74 | LANGUAGE C IMMUTABLE STRICT; 75 | 76 | CREATE FUNCTION divide(bigistore, bigint) 77 | RETURNS bigistore 78 | AS 'istore', 'bigistore_divide_integer' 79 | LANGUAGE C IMMUTABLE STRICT; 80 | 81 | CREATE FUNCTION concat(bigistore, bigistore) 82 | RETURNS bigistore 83 | AS 'istore', 'bigistore_concat' 84 | LANGUAGE C IMMUTABLE STRICT; 85 | 86 | CREATE FUNCTION bigistore(integer[]) 87 | RETURNS bigistore 88 | AS 'istore', 'bigistore_from_intarray' 89 | LANGUAGE C IMMUTABLE STRICT; 90 | 91 | CREATE FUNCTION sum_up(bigistore) 92 | RETURNS bigint 93 | AS 'istore', 'bigistore_sum_up' 94 | LANGUAGE C IMMUTABLE STRICT; 95 | 96 | CREATE FUNCTION sum_up(bigistore, integer) 97 | RETURNS bigint 98 | AS 'istore', 'bigistore_sum_up' 99 | LANGUAGE C IMMUTABLE STRICT; 100 | 101 | CREATE FUNCTION bigistore(integer[], integer[]) 102 | RETURNS bigistore 103 | AS 'istore', 'bigistore_array_add' 104 | LANGUAGE C IMMUTABLE STRICT; 105 | 106 | CREATE FUNCTION bigistore(integer[], bigint[]) 107 | RETURNS bigistore 108 | AS 'istore', 'bigistore_array_add' 109 | LANGUAGE C IMMUTABLE STRICT; 110 | 111 | CREATE FUNCTION row_to_bigistore(record) 112 | RETURNS bigistore 113 | AS 'istore', 'row_to_bigistore' 114 | LANGUAGE C IMMUTABLE STRICT; 115 | 116 | CREATE FUNCTION istore(integer[], bigint[]) 117 | RETURNS bigistore 118 | AS 'istore', 'bigistore_array_add' 119 | LANGUAGE C IMMUTABLE STRICT; 120 | 121 | CREATE FUNCTION fill_gaps(bigistore, integer, bigint DEFAULT 0) 122 | RETURNS bigistore 123 | AS 'istore', 'bigistore_fill_gaps' 124 | LANGUAGE C IMMUTABLE STRICT; 125 | 126 | CREATE FUNCTION accumulate(bigistore) 127 | RETURNS bigistore 128 | AS 'istore', 'bigistore_accumulate' 129 | LANGUAGE C IMMUTABLE STRICT; 130 | 131 | CREATE FUNCTION accumulate(bigistore, integer) 132 | RETURNS bigistore 133 | AS 'istore', 'bigistore_accumulate' 134 | LANGUAGE C IMMUTABLE STRICT; 135 | 136 | CREATE FUNCTION istore_seed(integer, integer, bigint) 137 | RETURNS bigistore 138 | AS 'istore', 'bigistore_seed' 139 | LANGUAGE C IMMUTABLE STRICT; 140 | 141 | CREATE FUNCTION istore_val_larger(bigistore, bigistore) 142 | RETURNS bigistore 143 | AS 'istore', 'bigistore_val_larger' 144 | LANGUAGE C IMMUTABLE STRICT; 145 | 146 | CREATE FUNCTION istore_val_smaller(bigistore, bigistore) 147 | RETURNS bigistore 148 | AS 'istore', 'bigistore_val_smaller' 149 | LANGUAGE C IMMUTABLE STRICT; 150 | 151 | CREATE FUNCTION akeys(bigistore) 152 | RETURNS integer[] 153 | AS 'istore' ,'bigistore_akeys' 154 | LANGUAGE C IMMUTABLE STRICT; 155 | 156 | CREATE FUNCTION avals(bigistore) 157 | RETURNS bigint[] 158 | AS 'istore' ,'bigistore_avals' 159 | LANGUAGE C IMMUTABLE STRICT; 160 | 161 | CREATE FUNCTION skeys(bigistore) 162 | RETURNS setof integer 163 | AS 'istore' ,'bigistore_skeys' 164 | LANGUAGE C IMMUTABLE STRICT; 165 | 166 | CREATE FUNCTION svals(bigistore) 167 | RETURNS setof bigint 168 | AS 'istore' ,'bigistore_svals' 169 | LANGUAGE C IMMUTABLE STRICT; 170 | 171 | CREATE FUNCTION istore_length(bigistore) 172 | RETURNS integer 173 | AS 'istore', 'bigistore_length' 174 | LANGUAGE C IMMUTABLE STRICT; 175 | 176 | CREATE FUNCTION istore_to_json(bigistore) 177 | RETURNS json 178 | AS 'istore', 'bigistore_to_json' 179 | LANGUAGE C IMMUTABLE STRICT; 180 | 181 | CREATE FUNCTION istore_to_array(bigistore) 182 | RETURNS int[] 183 | AS 'istore', 'bigistore_to_array' 184 | LANGUAGE C IMMUTABLE STRICT; 185 | 186 | CREATE FUNCTION istore_to_matrix(bigistore) 187 | RETURNS int[] 188 | AS 'istore', 'bigistore_to_matrix' 189 | LANGUAGE C IMMUTABLE STRICT; 190 | 191 | CREATE FUNCTION slice(bigistore, integer[]) 192 | RETURNS bigistore 193 | AS 'istore', 'bigistore_slice' 194 | LANGUAGE C IMMUTABLE STRICT; 195 | 196 | CREATE FUNCTION slice(bigistore, min integer, max integer) 197 | RETURNS bigistore 198 | AS 'istore', 'bigistore_slice_min_max' 199 | LANGUAGE C IMMUTABLE STRICT; 200 | 201 | CREATE FUNCTION slice_array(bigistore, integer[]) 202 | RETURNS integer[] 203 | AS 'istore', 'bigistore_slice_to_array' 204 | LANGUAGE C IMMUTABLE STRICT; 205 | 206 | CREATE FUNCTION clamp_below(bigistore,int) 207 | RETURNS bigistore 208 | AS 'istore', 'bigistore_clamp_below' 209 | LANGUAGE C IMMUTABLE STRICT; 210 | 211 | CREATE FUNCTION clamp_above(bigistore,int) 212 | RETURNS bigistore 213 | AS 'istore', 'bigistore_clamp_above' 214 | LANGUAGE C IMMUTABLE STRICT; 215 | 216 | CREATE FUNCTION delete(bigistore,int) 217 | RETURNS bigistore 218 | AS 'istore', 'bigistore_delete' 219 | LANGUAGE C IMMUTABLE STRICT; 220 | 221 | CREATE FUNCTION delete(bigistore,int[]) 222 | RETURNS bigistore 223 | AS 'istore', 'bigistore_delete_array' 224 | LANGUAGE C IMMUTABLE STRICT; 225 | 226 | CREATE FUNCTION exists_all(bigistore,integer[]) 227 | RETURNS boolean 228 | AS 'istore', 'bigistore_exists_all' 229 | LANGUAGE C IMMUTABLE STRICT; 230 | 231 | CREATE FUNCTION exists_any(bigistore,integer[]) 232 | RETURNS boolean 233 | AS 'istore', 'bigistore_exists_any' 234 | LANGUAGE C IMMUTABLE STRICT; 235 | 236 | CREATE FUNCTION delete(bigistore,bigistore) 237 | RETURNS bigistore 238 | AS 'istore', 'bigistore_delete_istore' 239 | LANGUAGE C IMMUTABLE STRICT; 240 | 241 | CREATE FUNCTION istore_sum_transfn(internal, bigistore) 242 | RETURNS internal 243 | AS 'istore' ,'bigistore_sum_transfn' 244 | LANGUAGE C IMMUTABLE; 245 | 246 | CREATE FUNCTION istore_min_transfn(internal, bigistore) 247 | RETURNS internal 248 | AS 'istore' ,'bigistore_min_transfn' 249 | LANGUAGE C IMMUTABLE; 250 | 251 | CREATE FUNCTION istore_max_transfn(internal, bigistore) 252 | RETURNS internal 253 | AS 'istore' ,'bigistore_max_transfn' 254 | LANGUAGE C IMMUTABLE; 255 | 256 | CREATE FUNCTION bigistore_avl_transfn(internal, int, bigint) 257 | RETURNS internal 258 | AS 'istore' ,'bigistore_avl_transfn' 259 | LANGUAGE C IMMUTABLE; 260 | 261 | CREATE FUNCTION bigistore_avl_finalfn(internal) 262 | RETURNS bigistore 263 | AS 'istore' ,'bigistore_avl_finalfn' 264 | LANGUAGE C IMMUTABLE; 265 | 266 | CREATE FUNCTION istore_in_range(bigistore, bigint, bigint) 267 | RETURNS boolean 268 | AS 'istore', 'bigistore_in_range' 269 | LANGUAGE C IMMUTABLE STRICT; 270 | 271 | CREATE FUNCTION istore_less_than(bigistore, bigint) 272 | RETURNS boolean 273 | AS 'istore', 'bigistore_less_than' 274 | LANGUAGE C IMMUTABLE STRICT; 275 | 276 | CREATE FUNCTION istore_less_than_or_equal(bigistore, bigint) 277 | RETURNS boolean 278 | AS 'istore', 'bigistore_less_than_or_equal' 279 | LANGUAGE C IMMUTABLE STRICT; 280 | 281 | CREATE FUNCTION istore_greater_than(bigistore, bigint) 282 | RETURNS boolean 283 | AS 'istore', 'bigistore_greater_than' 284 | LANGUAGE C IMMUTABLE STRICT; 285 | 286 | CREATE FUNCTION istore_greater_than_or_equal(bigistore, bigint) 287 | RETURNS boolean 288 | AS 'istore', 'bigistore_greater_than_or_equal' 289 | LANGUAGE C IMMUTABLE STRICT; 290 | 291 | CREATE FUNCTION istore_floor(bigistore, bigint) 292 | RETURNS bigistore 293 | AS 'istore', 'bigistore_floor' 294 | LANGUAGE C IMMUTABLE STRICT; 295 | 296 | CREATE FUNCTION istore_ceiling(bigistore, bigint) 297 | RETURNS bigistore 298 | AS 'istore', 'bigistore_ceiling' 299 | LANGUAGE C IMMUTABLE STRICT; 300 | 301 | 302 | CREATE AGGREGATE SUM ( 303 | sfunc = istore_sum_transfn, 304 | basetype = bigistore, 305 | stype = internal, 306 | finalfunc = bigistore_agg_finalfn 307 | ); 308 | 309 | CREATE AGGREGATE MIN ( 310 | sfunc = istore_min_transfn, 311 | basetype = bigistore, 312 | stype = internal, 313 | finalfunc = bigistore_agg_finalfn 314 | ); 315 | 316 | CREATE AGGREGATE MAX ( 317 | sfunc = istore_max_transfn, 318 | basetype = bigistore, 319 | stype = internal, 320 | finalfunc = bigistore_agg_finalfn 321 | ); 322 | 323 | CREATE AGGREGATE ISAGG(int, bigint) ( 324 | sfunc = bigistore_avl_transfn, 325 | stype = internal, 326 | finalfunc = bigistore_avl_finalfn 327 | ); 328 | 329 | 330 | CREATE OPERATOR -> ( 331 | leftarg = bigistore, 332 | rightarg = integer, 333 | procedure = fetchval 334 | ); 335 | 336 | CREATE OPERATOR ? ( 337 | leftarg = bigistore, 338 | rightarg = integer, 339 | procedure = exist 340 | ); 341 | 342 | CREATE OPERATOR + ( 343 | leftarg = bigistore, 344 | rightarg = bigistore, 345 | procedure = add 346 | ); 347 | 348 | CREATE OPERATOR + ( 349 | leftarg = bigistore, 350 | rightarg = bigint, 351 | procedure = add 352 | ); 353 | 354 | CREATE OPERATOR - ( 355 | leftarg = bigistore, 356 | rightarg = bigistore, 357 | procedure = subtract 358 | ); 359 | 360 | CREATE OPERATOR - ( 361 | leftarg = bigistore, 362 | rightarg = bigint, 363 | procedure = subtract 364 | ); 365 | 366 | CREATE OPERATOR * ( 367 | leftarg = bigistore, 368 | rightarg = bigistore, 369 | procedure = multiply 370 | ); 371 | 372 | CREATE OPERATOR * ( 373 | leftarg = bigistore, 374 | rightarg = bigint, 375 | procedure = multiply 376 | ); 377 | 378 | CREATE OPERATOR / ( 379 | leftarg = bigistore, 380 | rightarg = bigistore, 381 | procedure = divide 382 | ); 383 | 384 | CREATE OPERATOR / ( 385 | leftarg = bigistore, 386 | rightarg = bigint, 387 | procedure = divide 388 | ); 389 | 390 | CREATE OPERATOR -> ( 391 | leftarg = bigistore, 392 | rightarg = integer[], 393 | procedure = slice_array 394 | ); 395 | 396 | CREATE OPERATOR %% ( 397 | rightarg = bigistore, 398 | procedure = istore_to_array 399 | ); 400 | 401 | CREATE OPERATOR %# ( 402 | rightarg = bigistore, 403 | procedure = istore_to_matrix 404 | ); 405 | 406 | CREATE OPERATOR ?& ( 407 | leftarg = bigistore, 408 | rightarg = integer[], 409 | procedure = exists_all 410 | ); 411 | 412 | CREATE OPERATOR ?| ( 413 | leftarg = bigistore, 414 | rightarg = integer[], 415 | procedure = exists_any 416 | ); 417 | 418 | CREATE OPERATOR || ( 419 | leftarg = bigistore, 420 | rightarg = bigistore, 421 | procedure = concat 422 | ); 423 | 424 | 425 | CREATE FUNCTION gin_extract_bigistore_key(internal, internal) 426 | RETURNS internal 427 | AS 'istore' 428 | LANGUAGE C IMMUTABLE STRICT; 429 | 430 | CREATE OPERATOR CLASS bigistore_key_ops 431 | DEFAULT FOR TYPE bigistore USING gin 432 | AS 433 | OPERATOR 9 ?(bigistore, integer), 434 | FUNCTION 1 btint4cmp(integer, integer), 435 | FUNCTION 2 gin_extract_bigistore_key(internal, internal), 436 | FUNCTION 3 gin_extract_istore_key_query(internal, internal, int2, internal, internal), 437 | FUNCTION 4 gin_consistent_istore_key(internal, int2, internal, int4, internal, internal), 438 | STORAGE integer; 439 | -------------------------------------------------------------------------------- /sql/casts.sql: -------------------------------------------------------------------------------- 1 | --require types 2 | 3 | CREATE FUNCTION istore(bigistore) 4 | RETURNS istore 5 | AS 'istore', 'bigistore_to_istore' 6 | LANGUAGE C IMMUTABLE STRICT; 7 | 8 | CREATE FUNCTION bigistore(istore) 9 | RETURNS bigistore 10 | AS 'istore', 'istore_to_big_istore' 11 | LANGUAGE C IMMUTABLE STRICT; 12 | 13 | CREATE CAST (istore as bigistore) WITH FUNCTION bigistore(istore) AS IMPLICIT; 14 | CREATE CAST (bigistore as istore) WITH FUNCTION istore(bigistore) AS ASSIGNMENT; -------------------------------------------------------------------------------- /sql/istore.sql: -------------------------------------------------------------------------------- 1 | --require types 2 | 3 | CREATE FUNCTION exist(istore, integer) 4 | RETURNS boolean 5 | AS 'istore', 'istore_exist' 6 | LANGUAGE C IMMUTABLE STRICT; 7 | 8 | CREATE FUNCTION fetchval(istore, integer) 9 | RETURNS integer 10 | AS 'istore', 'istore_fetchval' 11 | LANGUAGE C IMMUTABLE STRICT; 12 | 13 | CREATE FUNCTION each(IN is istore, 14 | OUT key integer, 15 | OUT value integer) 16 | RETURNS SETOF record 17 | AS 'istore','istore_each' 18 | LANGUAGE C STRICT IMMUTABLE; 19 | 20 | CREATE FUNCTION min_key(istore) 21 | RETURNS integer 22 | AS 'istore', 'istore_min_key' 23 | LANGUAGE C IMMUTABLE STRICT; 24 | 25 | CREATE FUNCTION max_key(istore) 26 | RETURNS integer 27 | AS 'istore', 'istore_max_key' 28 | LANGUAGE C IMMUTABLE STRICT; 29 | 30 | CREATE FUNCTION max_value(istore) 31 | RETURNS integer 32 | AS 'istore', 'istore_max_value' 33 | LANGUAGE C IMMUTABLE STRICT; 34 | 35 | CREATE FUNCTION compact(istore) 36 | RETURNS istore 37 | AS 'istore', 'istore_compact' 38 | LANGUAGE C IMMUTABLE STRICT; 39 | 40 | CREATE FUNCTION add(istore, istore) 41 | RETURNS istore 42 | AS 'istore', 'istore_add' 43 | LANGUAGE C IMMUTABLE STRICT; 44 | 45 | CREATE FUNCTION add(istore, integer) 46 | RETURNS istore 47 | AS 'istore', 'istore_add_integer' 48 | LANGUAGE C IMMUTABLE STRICT; 49 | 50 | CREATE FUNCTION subtract(istore, istore) 51 | RETURNS istore 52 | AS 'istore', 'istore_subtract' 53 | LANGUAGE C IMMUTABLE STRICT; 54 | 55 | CREATE FUNCTION subtract(istore, integer) 56 | RETURNS istore 57 | AS 'istore', 'istore_subtract_integer' 58 | LANGUAGE C IMMUTABLE STRICT; 59 | 60 | CREATE FUNCTION multiply(istore, istore) 61 | RETURNS istore 62 | AS 'istore', 'istore_multiply' 63 | LANGUAGE C IMMUTABLE STRICT; 64 | 65 | CREATE FUNCTION multiply(istore, integer) 66 | RETURNS istore 67 | AS 'istore', 'istore_multiply_integer' 68 | LANGUAGE C IMMUTABLE STRICT; 69 | 70 | CREATE FUNCTION divide(istore, istore) 71 | RETURNS istore 72 | AS 'istore', 'istore_divide' 73 | LANGUAGE C IMMUTABLE STRICT; 74 | 75 | CREATE FUNCTION divide(istore, integer) 76 | RETURNS istore 77 | AS 'istore', 'istore_divide_integer' 78 | LANGUAGE C IMMUTABLE STRICT; 79 | 80 | CREATE FUNCTION concat(istore, istore) 81 | RETURNS istore 82 | AS 'istore', 'istore_concat' 83 | LANGUAGE C IMMUTABLE STRICT; 84 | 85 | CREATE FUNCTION istore(integer[]) 86 | RETURNS istore 87 | AS 'istore', 'istore_from_intarray' 88 | LANGUAGE C IMMUTABLE STRICT; 89 | 90 | CREATE FUNCTION sum_up(istore) 91 | RETURNS bigint 92 | AS 'istore', 'istore_sum_up' 93 | LANGUAGE C IMMUTABLE STRICT; 94 | 95 | CREATE FUNCTION sum_up(istore, integer) 96 | RETURNS bigint 97 | AS 'istore', 'istore_sum_up' 98 | LANGUAGE C IMMUTABLE STRICT; 99 | 100 | CREATE FUNCTION istore(integer[], integer[]) 101 | RETURNS istore 102 | AS 'istore', 'istore_array_add' 103 | LANGUAGE C IMMUTABLE STRICT; 104 | 105 | CREATE FUNCTION row_to_istore(record) 106 | RETURNS istore 107 | AS 'istore', 'row_to_istore' 108 | LANGUAGE C IMMUTABLE STRICT; 109 | 110 | CREATE FUNCTION fill_gaps(istore, integer, integer DEFAULT 0) 111 | RETURNS istore 112 | AS 'istore', 'istore_fill_gaps' 113 | LANGUAGE C IMMUTABLE STRICT; 114 | 115 | CREATE FUNCTION accumulate(istore) 116 | RETURNS istore 117 | AS 'istore', 'istore_accumulate' 118 | LANGUAGE C IMMUTABLE STRICT; 119 | 120 | CREATE FUNCTION accumulate(istore, integer) 121 | RETURNS istore 122 | AS 'istore', 'istore_accumulate' 123 | LANGUAGE C IMMUTABLE STRICT; 124 | 125 | CREATE FUNCTION istore_seed(integer, integer, integer) 126 | RETURNS istore 127 | AS 'istore' 128 | LANGUAGE C IMMUTABLE STRICT; 129 | 130 | CREATE FUNCTION istore_val_larger(istore, istore) 131 | RETURNS istore 132 | AS 'istore' 133 | LANGUAGE C IMMUTABLE STRICT; 134 | 135 | CREATE FUNCTION istore_val_smaller(istore, istore) 136 | RETURNS istore 137 | AS 'istore' 138 | LANGUAGE C IMMUTABLE STRICT; 139 | 140 | CREATE FUNCTION akeys(istore) 141 | RETURNS integer[] 142 | AS 'istore' ,'istore_akeys' 143 | LANGUAGE C IMMUTABLE STRICT; 144 | 145 | CREATE FUNCTION avals(istore) 146 | RETURNS integer[] 147 | AS 'istore' ,'istore_avals' 148 | LANGUAGE C IMMUTABLE STRICT; 149 | 150 | CREATE FUNCTION skeys(istore) 151 | RETURNS setof int 152 | AS 'istore' ,'istore_skeys' 153 | LANGUAGE C IMMUTABLE STRICT; 154 | 155 | CREATE FUNCTION svals(istore) 156 | RETURNS setof int 157 | AS 'istore' ,'istore_svals' 158 | LANGUAGE C IMMUTABLE STRICT; 159 | 160 | CREATE FUNCTION istore_sum_transfn(internal, istore) 161 | RETURNS internal 162 | AS 'istore' ,'istore_sum_transfn' 163 | LANGUAGE C IMMUTABLE; 164 | 165 | CREATE FUNCTION istore_min_transfn(internal, istore) 166 | RETURNS internal 167 | AS 'istore' 168 | LANGUAGE C IMMUTABLE; 169 | 170 | CREATE FUNCTION istore_max_transfn(internal, istore) 171 | RETURNS internal 172 | AS 'istore' 173 | LANGUAGE C IMMUTABLE; 174 | 175 | CREATE FUNCTION istore_agg_finalfn_pairs(internal) 176 | RETURNS istore 177 | AS 'istore' ,'istore_agg_finalfn_pairs' 178 | LANGUAGE C IMMUTABLE STRICT; 179 | 180 | CREATE FUNCTION istore_to_json(istore) 181 | RETURNS json 182 | AS 'istore', 'istore_to_json' 183 | LANGUAGE C IMMUTABLE STRICT; 184 | 185 | CREATE FUNCTION istore_to_array(istore) 186 | RETURNS int[] 187 | AS 'istore', 'istore_to_array' 188 | LANGUAGE C IMMUTABLE STRICT; 189 | 190 | CREATE FUNCTION istore_to_matrix(istore) 191 | RETURNS int[] 192 | AS 'istore', 'istore_to_matrix' 193 | LANGUAGE C IMMUTABLE STRICT; 194 | 195 | CREATE FUNCTION slice(istore, integer[]) 196 | RETURNS istore 197 | AS 'istore', 'istore_slice' 198 | LANGUAGE C IMMUTABLE STRICT; 199 | 200 | CREATE FUNCTION slice(istore, min integer, max integer) 201 | RETURNS istore 202 | AS 'istore', 'istore_slice_min_max' 203 | LANGUAGE C IMMUTABLE STRICT; 204 | 205 | CREATE FUNCTION slice_array(istore, integer[]) 206 | RETURNS integer[] 207 | AS 'istore', 'istore_slice_to_array' 208 | LANGUAGE C IMMUTABLE STRICT; 209 | 210 | CREATE FUNCTION clamp_below(istore,int) 211 | RETURNS istore 212 | AS 'istore', 'istore_clamp_below' 213 | LANGUAGE C IMMUTABLE STRICT; 214 | 215 | CREATE FUNCTION clamp_above(istore,int) 216 | RETURNS istore 217 | AS 'istore', 'istore_clamp_above' 218 | LANGUAGE C IMMUTABLE STRICT; 219 | 220 | CREATE FUNCTION delete(istore,int) 221 | RETURNS istore 222 | AS 'istore', 'istore_delete' 223 | LANGUAGE C IMMUTABLE STRICT; 224 | 225 | CREATE FUNCTION delete(istore,int[]) 226 | RETURNS istore 227 | AS 'istore', 'istore_delete_array' 228 | LANGUAGE C IMMUTABLE STRICT; 229 | 230 | CREATE FUNCTION exists_all(istore,integer[]) 231 | RETURNS boolean 232 | AS 'istore', 'istore_exists_all' 233 | LANGUAGE C IMMUTABLE STRICT; 234 | 235 | CREATE FUNCTION exists_any(istore,integer[]) 236 | RETURNS boolean 237 | AS 'istore', 'istore_exists_any' 238 | LANGUAGE C IMMUTABLE STRICT; 239 | 240 | CREATE FUNCTION delete(istore, istore) 241 | RETURNS istore 242 | AS 'istore', 'istore_delete_istore' 243 | LANGUAGE C IMMUTABLE STRICT; 244 | 245 | /* 246 | -- populate_record(record,hstore) 247 | */ 248 | 249 | CREATE FUNCTION bigistore_agg_finalfn(internal) 250 | RETURNS bigistore 251 | AS 'istore' ,'bigistore_agg_finalfn_pairs' 252 | LANGUAGE C IMMUTABLE STRICT; 253 | 254 | CREATE FUNCTION istore_avl_transfn(internal, int, int) 255 | RETURNS internal 256 | AS 'istore' ,'istore_avl_transfn' 257 | LANGUAGE C IMMUTABLE; 258 | 259 | CREATE FUNCTION istore_avl_finalfn(internal) 260 | RETURNS istore 261 | AS 'istore' ,'istore_avl_finalfn' 262 | LANGUAGE C IMMUTABLE; 263 | 264 | CREATE FUNCTION istore_length(istore) 265 | RETURNS integer 266 | AS 'istore', 'istore_length' 267 | LANGUAGE C IMMUTABLE STRICT; 268 | 269 | CREATE FUNCTION istore_in_range(istore, int, int) 270 | RETURNS boolean 271 | AS 'istore', 'istore_in_range' 272 | LANGUAGE C IMMUTABLE STRICT; 273 | 274 | CREATE FUNCTION istore_less_than(istore, int) 275 | RETURNS boolean 276 | AS 'istore', 'istore_less_than' 277 | LANGUAGE C IMMUTABLE STRICT; 278 | 279 | CREATE FUNCTION istore_less_than_or_equal(istore, int) 280 | RETURNS boolean 281 | AS 'istore', 'istore_less_than_or_equal' 282 | LANGUAGE C IMMUTABLE STRICT; 283 | 284 | CREATE FUNCTION istore_greater_than(istore, int) 285 | RETURNS boolean 286 | AS 'istore', 'istore_greater_than' 287 | LANGUAGE C IMMUTABLE STRICT; 288 | 289 | CREATE FUNCTION istore_greater_than_or_equal(istore, int) 290 | RETURNS boolean 291 | AS 'istore', 'istore_greater_than_or_equal' 292 | LANGUAGE C IMMUTABLE STRICT; 293 | 294 | CREATE FUNCTION istore_floor(istore, int) 295 | RETURNS istore 296 | AS 'istore', 'istore_floor' 297 | LANGUAGE C IMMUTABLE STRICT; 298 | 299 | CREATE FUNCTION istore_ceiling(istore, int) 300 | RETURNS istore 301 | AS 'istore', 'istore_ceiling' 302 | LANGUAGE C IMMUTABLE STRICT; 303 | 304 | CREATE AGGREGATE SUM ( 305 | sfunc = istore_sum_transfn, 306 | basetype = istore, 307 | stype = internal, 308 | finalfunc = bigistore_agg_finalfn 309 | ); 310 | 311 | CREATE AGGREGATE MIN ( 312 | sfunc = istore_min_transfn, 313 | basetype = istore, 314 | stype = internal, 315 | finalfunc = istore_agg_finalfn_pairs 316 | ); 317 | 318 | CREATE AGGREGATE MAX ( 319 | sfunc = istore_max_transfn, 320 | basetype = istore, 321 | stype = internal, 322 | finalfunc = istore_agg_finalfn_pairs 323 | ); 324 | 325 | CREATE AGGREGATE ISAGG(int, int) ( 326 | sfunc = istore_avl_transfn, 327 | stype = internal, 328 | finalfunc = istore_avl_finalfn 329 | ); 330 | 331 | 332 | CREATE OPERATOR -> ( 333 | leftarg = istore, 334 | rightarg = integer, 335 | procedure = fetchval 336 | ); 337 | 338 | CREATE OPERATOR ? ( 339 | leftarg = istore, 340 | rightarg = integer, 341 | procedure = exist 342 | ); 343 | 344 | CREATE OPERATOR + ( 345 | leftarg = istore, 346 | rightarg = istore, 347 | procedure = add 348 | ); 349 | 350 | CREATE OPERATOR + ( 351 | leftarg = istore, 352 | rightarg = integer, 353 | procedure = add 354 | ); 355 | 356 | CREATE OPERATOR - ( 357 | leftarg = istore, 358 | rightarg = istore, 359 | procedure = subtract 360 | ); 361 | 362 | CREATE OPERATOR - ( 363 | leftarg = istore, 364 | rightarg = integer, 365 | procedure = subtract 366 | ); 367 | 368 | CREATE OPERATOR * ( 369 | leftarg = istore, 370 | rightarg = istore, 371 | procedure = multiply 372 | ); 373 | 374 | CREATE OPERATOR * ( 375 | leftarg = istore, 376 | rightarg = integer, 377 | procedure = multiply 378 | ); 379 | 380 | CREATE OPERATOR / ( 381 | leftarg = istore, 382 | rightarg = istore, 383 | procedure = divide 384 | ); 385 | 386 | CREATE OPERATOR / ( 387 | leftarg = istore, 388 | rightarg = integer, 389 | procedure = divide 390 | ); 391 | 392 | 393 | CREATE OPERATOR -> ( 394 | leftarg = istore, 395 | rightarg = integer[], 396 | procedure = slice_array 397 | ); 398 | 399 | CREATE OPERATOR %% ( 400 | rightarg = istore, 401 | procedure = istore_to_array 402 | ); 403 | 404 | CREATE OPERATOR %# ( 405 | rightarg = istore, 406 | procedure = istore_to_matrix 407 | ); 408 | 409 | CREATE OPERATOR ?& ( 410 | leftarg = istore, 411 | rightarg = integer[], 412 | procedure = exists_all 413 | ); 414 | 415 | CREATE OPERATOR ?| ( 416 | leftarg = istore, 417 | rightarg = integer[], 418 | procedure = exists_any 419 | ); 420 | 421 | CREATE OPERATOR || ( 422 | leftarg = istore, 423 | rightarg = istore, 424 | procedure = concat 425 | ); 426 | 427 | 428 | CREATE FUNCTION gin_extract_istore_key(internal, internal) 429 | RETURNS internal 430 | AS 'istore' 431 | LANGUAGE C IMMUTABLE STRICT; 432 | 433 | CREATE FUNCTION gin_extract_istore_key_query(internal, internal, int2, internal, internal) 434 | RETURNS internal 435 | AS 'istore' 436 | LANGUAGE C IMMUTABLE STRICT; 437 | 438 | CREATE FUNCTION gin_consistent_istore_key(internal, int2, internal, int4, internal, internal) 439 | RETURNS bool 440 | AS 'istore' 441 | LANGUAGE C IMMUTABLE STRICT; 442 | 443 | CREATE OPERATOR CLASS istore_key_ops 444 | DEFAULT FOR TYPE istore USING gin 445 | AS 446 | OPERATOR 9 ?(istore, integer), 447 | FUNCTION 1 btint4cmp(integer, integer), 448 | FUNCTION 2 gin_extract_istore_key(internal, internal), 449 | FUNCTION 3 gin_extract_istore_key_query(internal, internal, int2, internal, internal), 450 | FUNCTION 4 gin_consistent_istore_key(internal, int2, internal, int4, internal, internal), 451 | STORAGE integer; 452 | -------------------------------------------------------------------------------- /sql/types.sql: -------------------------------------------------------------------------------- 1 | CREATE FUNCTION istore_in(cstring) 2 | RETURNS istore 3 | AS 'istore' 4 | LANGUAGE C IMMUTABLE STRICT; 5 | 6 | CREATE FUNCTION istore_out(istore) 7 | RETURNS cstring 8 | AS 'istore' 9 | LANGUAGE C IMMUTABLE STRICT; 10 | 11 | CREATE FUNCTION istore_send(istore) 12 | RETURNS bytea 13 | AS 'istore' 14 | LANGUAGE C IMMUTABLE STRICT; 15 | 16 | CREATE FUNCTION istore_recv(internal) 17 | RETURNS istore 18 | AS 'istore' 19 | LANGUAGE C IMMUTABLE STRICT; 20 | 21 | CREATE TYPE istore ( 22 | INPUT = istore_in, 23 | OUTPUT = istore_out, 24 | RECEIVE = istore_recv, 25 | SEND = istore_send, 26 | STORAGE = EXTENDED 27 | ); 28 | 29 | CREATE FUNCTION bigistore_in(cstring) 30 | RETURNS bigistore 31 | AS 'istore' 32 | LANGUAGE C IMMUTABLE STRICT; 33 | 34 | CREATE FUNCTION bigistore_out(bigistore) 35 | RETURNS cstring 36 | AS 'istore' 37 | LANGUAGE C IMMUTABLE STRICT; 38 | 39 | CREATE FUNCTION bigistore_send(bigistore) 40 | RETURNS bytea 41 | AS 'istore' 42 | LANGUAGE C IMMUTABLE STRICT; 43 | 44 | CREATE FUNCTION bigistore_recv(internal) 45 | RETURNS bigistore 46 | AS 'istore' 47 | LANGUAGE C IMMUTABLE STRICT; 48 | 49 | CREATE TYPE bigistore ( 50 | INPUT = bigistore_in, 51 | OUTPUT = bigistore_out, 52 | RECEIVE = bigistore_recv, 53 | SEND = bigistore_send, 54 | STORAGE = EXTENDED 55 | ); 56 | -------------------------------------------------------------------------------- /src/avl.c: -------------------------------------------------------------------------------- 1 | /* 2 | * AVL tree implementation 3 | * 4 | * This module provides a basic AVL tree where a key can be inserted along with 5 | * a value. If the key already exists the value will be added (+) to the exiting value 6 | * 7 | */ 8 | 9 | #include "postgres.h" 10 | 11 | #include "avl.h" 12 | #include "utils/builtins.h" 13 | 14 | #define MAX(_a, _b) ((_a > _b) ? _a : _b) 15 | #define COMPARE(_a, _b) ((_a == _b) ? 0 : ((_a < _b) ? -1 : 1)) 16 | #define height(_p) ((_p == NULL) ? -1 : _p->height) 17 | 18 | /* 19 | * free the node along with all subnodes 20 | */ 21 | AvlNode * 22 | istore_make_empty(AvlNode *t) 23 | { 24 | if (t != NULL) 25 | { 26 | istore_make_empty(t->left); 27 | istore_make_empty(t->right); 28 | pfree(t); 29 | t = NULL; 30 | } 31 | return NULL; 32 | } 33 | 34 | /* 35 | * find a node for a given key 36 | */ 37 | AvlNode * 38 | is_tree_find(int32 key, AvlNode *t) 39 | { 40 | int32 cmp; 41 | 42 | if (t == NULL) 43 | return NULL; 44 | 45 | cmp = COMPARE(key, t->key); 46 | if (cmp < 0) 47 | return is_tree_find(key, t->left); 48 | else if (cmp > 0) 49 | return is_tree_find(key, t->right); 50 | else 51 | return t; 52 | } 53 | 54 | /* 55 | * This function can be called only if k2 has a left child 56 | * Perform a rotate between a node (k2) and its left child 57 | * Update heights, then return new root 58 | */ 59 | static inline AvlNode * 60 | singleRotateWithLeft(AvlNode *k2) 61 | { 62 | AvlNode *k1; 63 | 64 | k1 = k2->left; 65 | k2->left = k1->right; 66 | k1->right = k2; 67 | 68 | k2->height = MAX(height(k2->left), height(k2->right)) + 1; 69 | k1->height = MAX(height(k1->left), k2->height) + 1; 70 | 71 | return k1; /* New root */ 72 | } 73 | 74 | /* 75 | * This function can be called only if k1 has a right child 76 | * Perform a rotate between a node (k1) and its right child 77 | * Update heights, then return new root 78 | */ 79 | static inline AvlNode * 80 | singleRotateWithRight(AvlNode *k1) 81 | { 82 | AvlNode *k2; 83 | 84 | k2 = k1->right; 85 | k1->right = k2->left; 86 | k2->left = k1; 87 | 88 | k1->height = MAX(height(k1->left), height(k1->right)) + 1; 89 | k2->height = MAX(height(k2->right), k1->height) + 1; 90 | 91 | return k2; /* New root */ 92 | } 93 | 94 | /* 95 | * This function can be called only if k3 has a left 96 | * child and k3's left child has a right child 97 | * Do the left-right double rotation 98 | * Update heights, then return new root 99 | */ 100 | static inline AvlNode * 101 | doubleRotateWithLeft(AvlNode *k3) 102 | { 103 | /* Rotate between k1 and k2 */ 104 | k3->left = singleRotateWithRight(k3->left); 105 | 106 | /* Rotate between k3 and k2 */ 107 | return singleRotateWithLeft(k3); 108 | } 109 | 110 | /* 111 | * This function can be called only if k1 has a right 112 | * child and k1's right child has a left child 113 | * Do the right-left double rotation 114 | * Update heights, then return new root 115 | */ 116 | static inline AvlNode * 117 | doubleRotateWithRight(AvlNode *k1) 118 | { 119 | /* Rotate between k3 and k2 */ 120 | k1->right = singleRotateWithLeft(k1->right); 121 | 122 | /* Rotate between k1 and k2 */ 123 | return singleRotateWithRight(k1); 124 | } 125 | 126 | /* 127 | * return number of nodes 128 | */ 129 | int 130 | is_tree_length(AvlNode *t) 131 | { 132 | int n; 133 | if (t == NULL) 134 | return 0; 135 | n = is_tree_length(t->left); 136 | ++n; 137 | n += is_tree_length(t->right); 138 | return n; 139 | } 140 | 141 | /* 142 | * insert key/value into tree 143 | */ 144 | AvlNode * 145 | is_tree_insert(AvlNode *t, int32 key, int64 value) 146 | { 147 | if (t == NULL) 148 | { 149 | /* Create and return a one-node tree */ 150 | t = palloc0(sizeof(struct AvlNode)); 151 | if (t == NULL) 152 | elog(ERROR, "AvlTree is_tree_insert: could not allocate memory"); 153 | else 154 | { 155 | t->key = key; 156 | t->value = value; 157 | t->height = 0; 158 | t->left = NULL; 159 | t->right = NULL; 160 | } 161 | } 162 | else 163 | { 164 | int32 cmp = COMPARE(key, t->key); 165 | if (cmp < 0) 166 | { 167 | t->left = is_tree_insert(t->left, key, value); 168 | if (height(t->left) - height(t->right) == 2) 169 | { 170 | if (COMPARE(key, t->left->key) < 0) 171 | t = singleRotateWithLeft(t); 172 | else 173 | t = doubleRotateWithLeft(t); 174 | } 175 | } 176 | else if (cmp > 0) 177 | { 178 | t->right = is_tree_insert(t->right, key, value); 179 | if (height(t->right) - height(t->left) == 2) 180 | { 181 | if (COMPARE(key, t->right->key) > 0) 182 | t = singleRotateWithRight(t); 183 | else 184 | t = doubleRotateWithRight(t); 185 | } 186 | } 187 | else 188 | { 189 | t->value = DatumGetInt64(DirectFunctionCall2(int8pl, 190 | Int64GetDatum(t->value), 191 | Int64GetDatum(value))); 192 | return t; 193 | } 194 | } 195 | 196 | t->height = MAX(height(t->left), height(t->right)) + 1; 197 | return t; 198 | } 199 | -------------------------------------------------------------------------------- /src/avl.h: -------------------------------------------------------------------------------- 1 | #ifndef ISTORE_AVL_H 2 | #define ISTORE_AVL_H 3 | 4 | #include "postgres.h" 5 | 6 | 7 | typedef struct AvlNode AvlNode; 8 | 9 | struct AvlNode 10 | { 11 | int32 key; 12 | int64 value; 13 | AvlNode *left; 14 | AvlNode *right; 15 | int height; 16 | }; 17 | 18 | AvlNode* istore_make_empty(AvlNode *t); 19 | AvlNode* is_tree_find(int32 key, AvlNode *t); 20 | AvlNode* is_tree_insert(AvlNode *t, int32 key, int64 value); 21 | int is_tree_length(AvlNode* t); 22 | #endif // ISTORE_AVL_H 23 | -------------------------------------------------------------------------------- /src/depcode.c: -------------------------------------------------------------------------------- 1 | #include "istore.h" 2 | #include "funcapi.h" 3 | #include "utils/array.h" 4 | 5 | 6 | /* 7 | * Depricated code that is only needed for downgarde compatibility lives here 8 | */ 9 | 10 | 11 | static Datum istore_array_sum(Datum *data, int count, bool *nulls); 12 | static Datum bigistore_array_sum(Datum *data, int count, bool *nulls); 13 | 14 | /* 15 | * sum aggregation final function 16 | */ 17 | PG_FUNCTION_INFO_V1(bigistore_agg_finalfn); 18 | Datum 19 | bigistore_agg_finalfn(PG_FUNCTION_ARGS) 20 | { 21 | Datum result; 22 | ArrayBuildState *input; 23 | Datum *data; 24 | bool *nulls; 25 | int count; 26 | 27 | if (PG_ARGISNULL(0)) 28 | PG_RETURN_NULL(); 29 | Assert(AggCheckCallContext(fcinfo, NULL)); 30 | 31 | input = (ArrayBuildState *) PG_GETARG_POINTER(0); 32 | count = input->nelems; 33 | nulls = input->dnulls; 34 | data = input->dvalues; 35 | 36 | if (count == 0) 37 | PG_RETURN_NULL(); 38 | 39 | result = bigistore_array_sum(data, count, nulls); 40 | 41 | if (result == 0) 42 | PG_RETURN_NULL(); 43 | else 44 | return result; 45 | } 46 | 47 | 48 | PG_FUNCTION_INFO_V1(istore_agg_finalfn); 49 | Datum 50 | istore_agg_finalfn(PG_FUNCTION_ARGS) 51 | { 52 | Datum result; 53 | ArrayBuildState *input; 54 | Datum *data; 55 | bool *nulls; 56 | int count; 57 | 58 | if (PG_ARGISNULL(0)) 59 | PG_RETURN_NULL(); 60 | Assert(AggCheckCallContext(fcinfo, NULL)); 61 | 62 | input = (ArrayBuildState *) PG_GETARG_POINTER(0); 63 | count = input->nelems; 64 | nulls = input->dnulls; 65 | data = input->dvalues; 66 | 67 | if (count == 0) 68 | PG_RETURN_NULL(); 69 | 70 | result = istore_array_sum(data, count, nulls); 71 | 72 | if (result == 0) 73 | PG_RETURN_NULL(); 74 | else 75 | return result; 76 | } 77 | 78 | 79 | 80 | /* 81 | * summarize an array of istores 82 | */ 83 | static Datum 84 | istore_array_sum(Datum *data, int count, bool *nulls) 85 | { 86 | BigIStore *out; 87 | IStore *istore; 88 | AvlNode *tree; 89 | IStorePair *payload; 90 | BigIStorePairs *pairs; 91 | AvlNode *position; 92 | int i, 93 | n, 94 | index; 95 | 96 | 97 | tree = NULL; 98 | n = 0; 99 | 100 | for (i = 0; i < count; ++i) 101 | { 102 | if (nulls[i]) 103 | continue; 104 | 105 | istore = (IStore *) data[i]; 106 | payload = FIRST_PAIR(istore, IStorePair); 107 | for (index = 0; index < istore->len; ++index) 108 | { 109 | position = is_tree_find(payload[index].key, tree); 110 | if (position == NULL) 111 | { 112 | tree = is_tree_insert(tree, payload[index].key, payload[index].val); 113 | ++n; 114 | } 115 | else{ 116 | position->value += payload[index].val; 117 | } 118 | } 119 | } 120 | 121 | if (n == 0) 122 | return 0; 123 | pairs = palloc0(sizeof *pairs); 124 | bigistore_pairs_init(pairs, n); 125 | bigistore_tree_to_pairs(tree, pairs); 126 | istore_make_empty(tree); 127 | 128 | FINALIZE_BIGISTORE(out, pairs); 129 | PG_RETURN_POINTER(out); 130 | } 131 | 132 | /* 133 | * summarize an array of bigistores 134 | */ 135 | static Datum 136 | bigistore_array_sum(Datum *data, int count, bool *nulls) 137 | { 138 | BigIStore *out; 139 | BigIStore *istore; 140 | AvlNode *tree; 141 | BigIStorePair *payload; 142 | BigIStorePairs *pairs; 143 | AvlNode *position; 144 | int i, 145 | n, 146 | index; 147 | 148 | 149 | tree = NULL; 150 | n = 0; 151 | 152 | for (i = 0; i < count; ++i) 153 | { 154 | if (nulls[i]) 155 | continue; 156 | 157 | istore = (BigIStore *) data[i]; 158 | payload = FIRST_PAIR(istore, BigIStorePair); 159 | for (index = 0; index < istore->len; ++index) 160 | { 161 | position = is_tree_find(payload[index].key, tree); 162 | if (position == NULL) 163 | { 164 | tree = is_tree_insert(tree, payload[index].key, payload[index].val); 165 | ++n; 166 | } 167 | else{ 168 | position->value = 169 | DatumGetInt64(DirectFunctionCall2(int8pl, 170 | Int64GetDatum(position->value), 171 | Int64GetDatum(payload[index].val))); 172 | } 173 | } 174 | } 175 | 176 | if (n == 0) 177 | return 0; 178 | pairs = palloc0(sizeof *pairs); 179 | bigistore_pairs_init(pairs, n); 180 | bigistore_tree_to_pairs(tree, pairs); 181 | istore_make_empty(tree); 182 | 183 | FINALIZE_BIGISTORE(out, pairs); 184 | PG_RETURN_POINTER(out); 185 | } 186 | -------------------------------------------------------------------------------- /src/is_parser.c: -------------------------------------------------------------------------------- 1 | #include "is_parser.h" 2 | #include 3 | 4 | #define WKEY 0 5 | #define WVAL 1 6 | #define WEQ 2 7 | #define WGT 3 8 | #define WDEL 4 9 | #define WDELVAL 5 10 | #define WSQRBR 6 11 | #define WDELARR 7 12 | #define WENDBR 8 13 | 14 | static inline void 15 | raise_out_of_range(char *str) 16 | { 17 | ereport(ERROR, 18 | (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), 19 | errmsg("istore \"%s\" is out of range", str))); 20 | } 21 | 22 | static inline void 23 | raise_unexpected_sign(char sign, char *str, char *context) 24 | { 25 | if (sign) 26 | ereport(ERROR, 27 | (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), 28 | errmsg("invalid input syntax for istore: \"%s\"", str), 29 | errdetail("unexpected sign '%c', %s", sign, context))); 30 | else 31 | ereport(ERROR, 32 | (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), 33 | errmsg("invalid input syntax for istore: \"%s\"", str), 34 | errdetail("unexpected end of line, %s", context))); 35 | } 36 | 37 | #define GET_NUM(ptr, _num, whole) \ 38 | do { \ 39 | long _l; \ 40 | char *begin = ptr; \ 41 | errno = 0; \ 42 | _l = strtol(ptr, &ptr, 10); \ 43 | if (errno == ERANGE) \ 44 | raise_out_of_range(whole); \ 45 | if (ptr == begin) \ 46 | raise_unexpected_sign(*ptr, whole, "expected number"); \ 47 | _num = _l; \ 48 | } while (0) 49 | 50 | #define SKIP_SPACES(_ptr) \ 51 | while (isspace(*_ptr)) \ 52 | _ptr++; 53 | 54 | /* TODO really respect quotes and dont just skip them */ 55 | #define SKIP_ESCAPED(_ptr) \ 56 | if (*_ptr == '"') \ 57 | _ptr++; 58 | 59 | /* 60 | * parse cstring into an AVL tree 61 | */ 62 | AvlNode* 63 | is_parse(ISParser *parser) 64 | { 65 | int64 key; 66 | int64 val; 67 | 68 | parser->state = WKEY; 69 | parser->ptr = parser->begin; 70 | parser->tree = NULL; 71 | 72 | while(1) 73 | { 74 | if (parser->state == WKEY) 75 | { 76 | SKIP_SPACES(parser->ptr); 77 | SKIP_ESCAPED(parser->ptr); 78 | GET_NUM(parser->ptr, key, parser->begin); 79 | 80 | if (key < PG_INT32_MIN || key > PG_INT32_MAX) 81 | raise_out_of_range(parser->begin); 82 | 83 | parser->state = WEQ; 84 | SKIP_ESCAPED(parser->ptr); 85 | } 86 | else if (parser->state == WEQ) 87 | { 88 | SKIP_SPACES(parser->ptr); 89 | if (*(parser->ptr) == '=') 90 | { 91 | parser->state = WGT; 92 | parser->ptr++; 93 | } 94 | else 95 | raise_unexpected_sign(*(parser->ptr), parser->begin, "in istore key"); 96 | } 97 | else if (parser->state == WGT) 98 | { 99 | if (*(parser->ptr) == '>') 100 | { 101 | parser->state = WVAL; 102 | parser->ptr++; 103 | } 104 | else 105 | raise_unexpected_sign(*(parser->ptr), parser->begin, "expected '>'"); 106 | } 107 | else if (parser->state == WVAL) 108 | { 109 | SKIP_SPACES(parser->ptr); 110 | SKIP_ESCAPED(parser->ptr); 111 | GET_NUM(parser->ptr, val, parser->begin); 112 | SKIP_ESCAPED(parser->ptr); 113 | parser->state = WDEL; 114 | parser->tree = is_tree_insert(parser->tree, key, val); 115 | } 116 | else if (parser->state == WDEL) 117 | { 118 | SKIP_SPACES(parser->ptr); 119 | 120 | if (*(parser->ptr) == '\0') 121 | break; 122 | else if (*(parser->ptr) == ',') 123 | parser->state = WKEY; 124 | else 125 | raise_unexpected_sign(*(parser->ptr), parser->begin, "in istore value"); 126 | 127 | parser->ptr++; 128 | } 129 | else 130 | { 131 | elog(ERROR, "unknown parser state"); 132 | } 133 | } 134 | 135 | return parser->tree; 136 | } 137 | 138 | /* 139 | * parse arrays tuple cstring into an AVL tree 140 | */ 141 | AvlNode* 142 | is_parse_arr(ISParser *parser) 143 | { 144 | int64 key = 0; /* keep compiler quiet */ 145 | int64 val; 146 | 147 | char *valarr; 148 | 149 | parser->state = WKEY; 150 | parser->ptr = index(parser->begin, '['); 151 | parser->ptr2 = rindex(parser->begin, '['); 152 | 153 | if (parser->ptr == NULL || parser->ptr == parser->ptr2) 154 | ereport(ERROR, 155 | (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), 156 | errmsg("invalid input syntax for istore: \"%s\"", 157 | parser->begin))); 158 | 159 | valarr = parser->ptr2; 160 | parser->tree = NULL; 161 | parser->ptr++; 162 | parser->ptr2++; 163 | 164 | SKIP_SPACES(parser->ptr); 165 | if (*(parser->ptr) == ']') 166 | /* empty */ 167 | return parser->tree; 168 | 169 | while (1) 170 | { 171 | if (parser->state == WKEY) 172 | { 173 | SKIP_SPACES(parser->ptr); 174 | SKIP_ESCAPED(parser->ptr); 175 | GET_NUM(parser->ptr, key, parser->begin); 176 | 177 | if (key < PG_INT32_MIN || key > PG_INT32_MAX) 178 | raise_out_of_range(parser->begin); 179 | 180 | parser->state = WVAL; 181 | SKIP_ESCAPED(parser->ptr); 182 | } 183 | else if (parser->state == WDEL) 184 | { 185 | SKIP_SPACES(parser->ptr); 186 | 187 | if (*(parser->ptr) == ']') 188 | parser->state = WSQRBR; 189 | else if (*(parser->ptr) == ',') 190 | parser->state = WDELVAL; 191 | else 192 | raise_unexpected_sign(*(parser->ptr), parser->begin, "expected ',' in keys"); 193 | 194 | parser->ptr++; 195 | } 196 | else if (parser->state == WDELVAL) 197 | { 198 | SKIP_SPACES(parser->ptr2); 199 | 200 | if (*(parser->ptr2) == ']') 201 | raise_unexpected_sign(*(parser->ptr2), parser->begin, "expected value"); 202 | else if (*(parser->ptr2) == ',') 203 | parser->state = WKEY; 204 | else 205 | raise_unexpected_sign(*(parser->ptr2), parser->begin, "expected ',' in values"); 206 | 207 | parser->ptr2++; 208 | } 209 | else if (parser->state == WDELARR) 210 | { 211 | SKIP_SPACES(parser->ptr); 212 | 213 | if (*(parser->ptr) == ',') 214 | parser->state = WENDBR; 215 | else 216 | raise_unexpected_sign(*(parser->ptr), parser->begin, "expected valid arrays delimiter"); 217 | 218 | /* check second array starting */ 219 | parser->ptr++; 220 | SKIP_SPACES(parser->ptr); 221 | if (parser->ptr != valarr) 222 | raise_unexpected_sign(*(parser->ptr), parser->begin, "expected valid arrays delimiter"); 223 | } 224 | else if (parser->state == WVAL) 225 | { 226 | SKIP_SPACES(parser->ptr2); 227 | SKIP_ESCAPED(parser->ptr2); 228 | GET_NUM(parser->ptr2, val, parser->begin); 229 | SKIP_ESCAPED(parser->ptr2); 230 | 231 | parser->state = WDEL; 232 | parser->tree = is_tree_insert(parser->tree, key, val); 233 | } 234 | else if (parser->state == WSQRBR) 235 | { 236 | SKIP_SPACES(parser->ptr2); 237 | 238 | if (*(parser->ptr2) == ']') 239 | parser->state = WDELARR; 240 | else 241 | raise_unexpected_sign(*(parser->ptr2), parser->begin, "expected square bracket"); 242 | 243 | parser->ptr2++; 244 | } 245 | else if (parser->state == WENDBR) 246 | { 247 | SKIP_SPACES(parser->ptr2); 248 | 249 | if (*(parser->ptr2) != ')') 250 | raise_unexpected_sign(*(parser->ptr2), parser->begin, "expected ending bracket"); 251 | 252 | break; 253 | } 254 | else 255 | ereport(ERROR, 256 | (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), 257 | errmsg("invalid input syntax for istore: \"%s\"", 258 | parser->begin))); 259 | } 260 | 261 | return parser->tree; 262 | } 263 | -------------------------------------------------------------------------------- /src/is_parser.h: -------------------------------------------------------------------------------- 1 | #ifndef ISTORE_PARSER_H 2 | #define ISTORE_PARSER_H 3 | 4 | #include "postgres.h" 5 | #include "avl.h" 6 | 7 | typedef struct ISParser { 8 | char *begin; 9 | char *ptr; 10 | char *ptr2; /* parsing from arrays */ 11 | int state; 12 | AvlNode *tree; 13 | } ISParser; 14 | 15 | AvlNode* is_parse(ISParser *parser); 16 | AvlNode* is_parse_arr(ISParser *parser); 17 | 18 | #define EMPTY_ISTORE(_istore) \ 19 | do { \ 20 | _istore = palloc0(ISHDRSZ); \ 21 | _istore->buflen = 0; \ 22 | _istore->len = 0; \ 23 | SET_VARSIZE(_istore, ISHDRSZ); \ 24 | } while(0) 25 | 26 | 27 | #endif // ISTORE_PARSER_H 28 | -------------------------------------------------------------------------------- /src/istore.h: -------------------------------------------------------------------------------- 1 | #ifndef ISTORE_H 2 | #define ISTORE_H 3 | 4 | #include "postgres.h" 5 | 6 | // pg16 compability 7 | #ifndef SET_VARSIZE 8 | /* 9 | * pg >= 16 reorganized the toastable header files 10 | * https://github.com/postgres/postgres/commit/d952373a987bad331c0e499463159dd142ced1ef 11 | * to ensure cross version compatibility we do a bit of a hack here 12 | */ 13 | #include "varatt.h" 14 | #endif 15 | 16 | #include "avl.h" 17 | #include "fmgr.h" 18 | #include "utils/builtins.h" 19 | #include "utils/memutils.h" 20 | 21 | /* 22 | * Until version 9.4 postgres didn't have "extern" function declaration in 23 | * PG_FUNCTION_INFO_V1. This is a quick fix that allows us not to declare every 24 | * function manually. Copied from the PostgreSQL 12 source code (see fmgr.h) 25 | */ 26 | #if PG_VERSION_NUM < 90400 27 | #undef PG_FUNCTION_INFO_V1 28 | #define PG_FUNCTION_INFO_V1(funcname) \ 29 | extern Datum funcname(PG_FUNCTION_ARGS); \ 30 | extern PGDLLEXPORT const Pg_finfo_record *CppConcat(pg_finfo_, funcname)(void); \ 31 | const Pg_finfo_record * CppConcat(pg_finfo_, funcname)(void) \ 32 | { \ 33 | static const Pg_finfo_record my_finfo = { 1 }; \ 34 | return &my_finfo; \ 35 | } \ 36 | extern int no_such_variable 37 | #endif 38 | 39 | /* 40 | * a single key/value pair 41 | */ 42 | typedef struct 43 | { 44 | int32 key; 45 | int32 val; 46 | } IStorePair; 47 | 48 | /* 49 | * collection of pairs 50 | */ 51 | typedef struct 52 | { 53 | IStorePair *pairs; 54 | size_t size; 55 | int used; 56 | int buflen; 57 | } IStorePairs; 58 | 59 | /* 60 | * the istore 61 | */ 62 | typedef struct 63 | { 64 | int32 __varlen; 65 | int32 buflen; 66 | int32 len; 67 | } IStore; 68 | 69 | typedef struct 70 | { 71 | int32 key; 72 | int64 val; 73 | } BigIStorePair; 74 | 75 | typedef struct 76 | { 77 | BigIStorePair *pairs; 78 | size_t size; 79 | int used; 80 | int buflen; 81 | } BigIStorePairs; 82 | 83 | typedef struct 84 | { 85 | int32 __varlen; 86 | int32 buflen; 87 | int32 len; 88 | } BigIStore; 89 | 90 | void istore_copy_and_add_buflen(IStore *istore, BigIStorePair *pairs); 91 | void istore_pairs_init(IStorePairs *pairs, size_t initial_size); 92 | void istore_pairs_insert(IStorePairs *pairs, int32 key, int32 val); 93 | void istore_tree_to_pairs(AvlNode *p, IStorePairs *pairs); 94 | int is_pair_buf_len(IStorePair *pair); 95 | void bigistore_add_buflen(BigIStore *istore); 96 | void bigistore_pairs_init(BigIStorePairs *pairs, size_t initial_size); 97 | void bigistore_pairs_insert(BigIStorePairs *pairs, int32 key, int64 val); 98 | void bigistore_tree_to_pairs(AvlNode *p, BigIStorePairs *pairs); 99 | int bigis_pair_buf_len(BigIStorePair *pair); 100 | 101 | int is_int32_arr_comp(const void *a, const void *b); 102 | 103 | #define BUFLEN_OFFSET 8 104 | #define MAX(_a, _b) ((_a > _b) ? _a : _b) 105 | #define MIN(_a, _b) ((_a < _b) ? _a : _b) 106 | 107 | #define PAIRS_MAX(_pairtype) (MaxAllocSize / sizeof(_pairtype)) 108 | #define PAYLOAD_SIZE(_pairs, _pairtype) (_pairs->used * sizeof(_pairtype)) 109 | #define ISHDRSZ VARHDRSZ + sizeof(int32) + sizeof(int32) 110 | 111 | #define ISTORE_SIZE(x, _pairtype) (ISHDRSZ + x->len * sizeof(_pairtype)) 112 | 113 | /* 114 | * get the first pair of type 115 | */ 116 | #define FIRST_PAIR(x, _pairtype) ((_pairtype *) ((char *) x + ISHDRSZ)) 117 | #define LAST_PAIR(x, _pairtype) ((_pairtype *) ((char *) x + ISHDRSZ + (x->len - 1) * sizeof(_pairtype))) 118 | 119 | /* 120 | * get the istore 121 | */ 122 | #define PG_GETARG_IS(x) (IStore *) PG_DETOAST_DATUM(PG_GETARG_DATUM(x)) 123 | #define PG_GETARG_BIGIS(x) (BigIStore *) PG_DETOAST_DATUM(PG_GETARG_DATUM(x)) 124 | #define PG_GETARG_IS_COPY(x) (IStore *) PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(x)) 125 | #define PG_GETARG_BIGIS_COPY(x) (BigIStore *) PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(x)) 126 | 127 | /* 128 | * an empty istore 129 | */ 130 | #define PG_RETURN_EMPTY_ISTORE() \ 131 | do \ 132 | { \ 133 | IStore *x = (IStore *) palloc0(ISHDRSZ); \ 134 | SET_VARSIZE(x, ISHDRSZ); \ 135 | PG_RETURN_POINTER(x); \ 136 | } while (0) 137 | 138 | /* 139 | * creates the internal representation from a pairs collection 140 | */ 141 | #define FINALIZE_ISTORE_BASE(_istore, _pairs, _pairtype) \ 142 | _istore = palloc0(ISHDRSZ + PAYLOAD_SIZE(_pairs, _pairtype)); \ 143 | _istore->buflen = _pairs->buflen; \ 144 | _istore->len = _pairs->used; \ 145 | SET_VARSIZE(_istore, ISHDRSZ + PAYLOAD_SIZE(_pairs, _pairtype)); \ 146 | memcpy(FIRST_PAIR(_istore, _pairtype), _pairs->pairs, PAYLOAD_SIZE(_pairs, _pairtype)); 147 | 148 | #define FINALIZE_ISTORE(_istore, _pairs) \ 149 | do \ 150 | { \ 151 | FINALIZE_ISTORE_BASE(_istore, _pairs, IStorePair); \ 152 | pfree(_pairs->pairs); \ 153 | } while (0) 154 | 155 | #define FINALIZE_BIGISTORE(_istore, _pairs) \ 156 | do \ 157 | { \ 158 | FINALIZE_ISTORE_BASE(_istore, _pairs, BigIStorePair); \ 159 | pfree(_pairs->pairs); \ 160 | } while (0) 161 | 162 | #define SAMESIGN(a, b) (((a) < 0) == ((b) < 0)) 163 | 164 | #if defined(HAVE__BUILTIN_OP_OVERFLOW) 165 | #define INTPL(_a, _b, _r) \ 166 | do { \ 167 | if (__builtin_add_overflow(_a, _b, &_r)) \ 168 | ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("integer out of range"))); \ 169 | } while (0) 170 | #else 171 | #define INTPL(_a, _b, _r) \ 172 | do { \ 173 | int64 tmp = _a + _b; \ 174 | if (SAMESIGN(_a, _b) && !SAMESIGN(tmp, _a)) \ 175 | ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("integer out of range"))); \ 176 | _r = tmp; \ 177 | } while (0) 178 | #endif 179 | 180 | #endif // ISTORE_H 181 | -------------------------------------------------------------------------------- /src/istore_cast.c: -------------------------------------------------------------------------------- 1 | /* 2 | * cast routines from istore to bigistore and vise versa 3 | */ 4 | 5 | #include "istore.h" 6 | #include "istore.h" 7 | 8 | /* 9 | * cast bigistore to istore 10 | * will raise an error if any values is larger than INT4MAX 11 | */ 12 | PG_FUNCTION_INFO_V1(bigistore_to_istore); 13 | Datum 14 | bigistore_to_istore(PG_FUNCTION_ARGS) 15 | { 16 | BigIStore *is; 17 | BigIStorePair *pairs; 18 | IStore *result; 19 | IStorePairs *creator ; 20 | int index; 21 | 22 | creator = NULL; 23 | is = PG_GETARG_BIGIS(0); 24 | pairs = FIRST_PAIR(is, BigIStorePair); 25 | creator = palloc0(sizeof *creator); 26 | index = 0; 27 | istore_pairs_init(creator, is->len); 28 | while (index < is->len){ 29 | istore_pairs_insert(creator, 30 | pairs[index].key, 31 | DatumGetInt32(DirectFunctionCall1(int84, 32 | Int64GetDatum(pairs[index].val)))); 33 | ++index; 34 | } 35 | FINALIZE_ISTORE(result, creator); 36 | 37 | PG_RETURN_POINTER(result); 38 | } 39 | 40 | /* 41 | * cast istore to bigistore 42 | */ 43 | PG_FUNCTION_INFO_V1(istore_to_big_istore); 44 | Datum 45 | istore_to_big_istore(PG_FUNCTION_ARGS) 46 | { 47 | IStore *is; 48 | IStorePair *pairs; 49 | BigIStore *result; 50 | BigIStorePairs *creator ; 51 | int index; 52 | 53 | creator = NULL; 54 | is = PG_GETARG_IS(0); 55 | pairs = FIRST_PAIR(is, IStorePair); 56 | creator = palloc0(sizeof *creator); 57 | index = 0; 58 | 59 | bigistore_pairs_init(creator, is->len); 60 | while (index < is->len){ 61 | bigistore_pairs_insert(creator, pairs[index].key, pairs[index].val); 62 | ++index; 63 | } 64 | 65 | FINALIZE_BIGISTORE(result, creator); 66 | PG_RETURN_POINTER(result); 67 | } 68 | -------------------------------------------------------------------------------- /src/istore_io.c: -------------------------------------------------------------------------------- 1 | /* 2 | * input and output functions for istore 3 | */ 4 | 5 | #include "istore.h" 6 | #include "is_parser.h" 7 | #include "libpq/pqformat.h" 8 | #include "utils/builtins.h" 9 | 10 | PG_FUNCTION_INFO_V1(istore_out); 11 | Datum 12 | istore_out(PG_FUNCTION_ARGS) 13 | { 14 | IStore *in; 15 | int i; 16 | char *out, 17 | *walk; 18 | IStorePair *pairs; 19 | 20 | in = PG_GETARG_IS(0); 21 | 22 | if (in->len == 0) 23 | { 24 | out = palloc0(1); 25 | PG_RETURN_CSTRING(out); 26 | } 27 | out = palloc0(in->buflen + 1); 28 | pairs = FIRST_PAIR(in, IStorePair); 29 | walk = out; 30 | 31 | for (i = 0; ilen; ++i) 32 | { 33 | *walk++ = '"'; 34 | pg_ltoa(pairs[i].key, walk); 35 | while (*++walk != '\0') ; 36 | 37 | *walk++ = '"'; 38 | *walk++ = '='; 39 | *walk++ = '>'; 40 | *walk++ = '"'; 41 | pg_ltoa(pairs[i].val, walk); 42 | while (*++walk != '\0') ; 43 | *walk++ = '"'; 44 | *walk++ = ','; 45 | *walk++ = ' '; 46 | 47 | } 48 | // replace trailing ", " with terminating null 49 | --walk; 50 | *--walk = '\0'; 51 | PG_RETURN_CSTRING(out); 52 | } 53 | 54 | PG_FUNCTION_INFO_V1(istore_in); 55 | Datum 56 | istore_in(PG_FUNCTION_ARGS) 57 | { 58 | ISParser parser; 59 | IStore *out; 60 | IStorePairs *pairs; 61 | AvlNode *tree; 62 | int n; 63 | 64 | parser.begin = PG_GETARG_CSTRING(0); 65 | 66 | if (parser.begin[0] == '\0') 67 | { 68 | EMPTY_ISTORE(out); 69 | PG_RETURN_POINTER(out); 70 | } 71 | else if (parser.begin[0] == '(') 72 | tree = is_parse_arr(&parser); 73 | else 74 | tree = is_parse(&parser); 75 | 76 | pairs = palloc0(sizeof(IStorePairs)); 77 | n = is_tree_length(tree); 78 | istore_pairs_init(pairs, n); 79 | istore_tree_to_pairs(tree, pairs); 80 | istore_make_empty(tree); 81 | FINALIZE_ISTORE(out, pairs); 82 | PG_RETURN_POINTER(out); 83 | } 84 | 85 | PG_FUNCTION_INFO_V1(istore_recv); 86 | Datum 87 | istore_recv(PG_FUNCTION_ARGS) 88 | { 89 | IStore *result; 90 | StringInfo buf = (StringInfo) PG_GETARG_POINTER(0); 91 | int i = 0; 92 | IStorePairs *creator = palloc0(sizeof *creator); 93 | int32 len = pq_getmsgint(buf, 4); 94 | istore_pairs_init(creator, len); 95 | for (; i < len; ++i) 96 | { 97 | int32 key = pq_getmsgint(buf, 4); 98 | int32 val = pq_getmsgint(buf, 4); 99 | istore_pairs_insert(creator, key, val); 100 | } 101 | FINALIZE_ISTORE(result, creator); 102 | PG_RETURN_POINTER(result); 103 | } 104 | 105 | PG_FUNCTION_INFO_V1(istore_send); 106 | Datum 107 | istore_send(PG_FUNCTION_ARGS) 108 | { 109 | IStore *in = PG_GETARG_IS(0); 110 | IStorePair *pairs= FIRST_PAIR(in, IStorePair); 111 | int i = 0; 112 | StringInfoData buf; 113 | pq_begintypsend(&buf); 114 | pq_sendint(&buf, in->len, 4); 115 | for (; i < in->len; ++i) 116 | { 117 | int32 key = pairs[i].key; 118 | int32 val = pairs[i].val; 119 | pq_sendint(&buf, key, 4); 120 | pq_sendint(&buf, val, 4); 121 | } 122 | PG_RETURN_BYTEA_P(pq_endtypsend(&buf)); 123 | } 124 | 125 | /* 126 | * json representation of an istore 127 | */ 128 | PG_FUNCTION_INFO_V1(istore_to_json); 129 | Datum 130 | istore_to_json(PG_FUNCTION_ARGS) 131 | { 132 | IStore *is = PG_GETARG_IS(0); 133 | IStorePair *pairs; 134 | int i; 135 | StringInfoData dst; 136 | 137 | if (is->len == 0) 138 | PG_RETURN_TEXT_P(cstring_to_text_with_len("{}", 2)); 139 | 140 | pairs = FIRST_PAIR(is, IStorePair); 141 | initStringInfo(&dst); 142 | appendStringInfoChar(&dst, '{'); 143 | 144 | for (i = 0; i < is->len; i++) 145 | { 146 | char buf[12]; 147 | appendStringInfoString(&dst, "\""); 148 | pg_ltoa(pairs[i].key, buf); 149 | appendStringInfoString(&dst, buf); 150 | appendStringInfoString(&dst, "\": "); 151 | pg_ltoa(pairs[i].val, buf); 152 | appendStringInfoString(&dst, buf); 153 | if (i + 1 != is->len) 154 | appendStringInfoString(&dst, ", "); 155 | } 156 | appendStringInfoChar(&dst, '}'); 157 | 158 | PG_RETURN_TEXT_P(cstring_to_text(dst.data)); 159 | } 160 | 161 | PG_FUNCTION_INFO_V1(bigistore_out); 162 | Datum 163 | bigistore_out(PG_FUNCTION_ARGS) 164 | { 165 | BigIStore *in; 166 | int i; 167 | char *out, 168 | *walk; 169 | BigIStorePair *pairs; 170 | 171 | in = PG_GETARG_BIGIS(0); 172 | 173 | if (in->len == 0) 174 | { 175 | out = palloc0(1); 176 | PG_RETURN_CSTRING(out); 177 | } 178 | 179 | out = palloc0(in->buflen + 1); 180 | pairs = FIRST_PAIR(in, BigIStorePair); 181 | walk = out; 182 | 183 | for (i = 0; ilen; ++i) 184 | { 185 | *walk++ = '"'; 186 | pg_lltoa(pairs[i].key, walk); 187 | while (*++walk != '\0') ; 188 | 189 | *walk++ = '"'; 190 | *walk++ = '='; 191 | *walk++ = '>'; 192 | *walk++ = '"'; 193 | pg_lltoa(pairs[i].val, walk); 194 | while (*++walk != '\0') ; 195 | 196 | *walk++ = '"'; 197 | *walk++ = ','; 198 | *walk++ = ' '; 199 | 200 | } 201 | // replace trailing ", " with terminating null 202 | --walk; 203 | *--walk = '\0'; 204 | PG_RETURN_CSTRING(out); 205 | } 206 | 207 | PG_FUNCTION_INFO_V1(bigistore_in); 208 | Datum 209 | bigistore_in(PG_FUNCTION_ARGS) 210 | { 211 | ISParser parser; 212 | BigIStore *out; 213 | BigIStorePairs *pairs; 214 | AvlNode *tree; 215 | int n; 216 | 217 | parser.begin = PG_GETARG_CSTRING(0); 218 | 219 | if (parser.begin[0] == '\0') 220 | { 221 | EMPTY_ISTORE(out); 222 | PG_RETURN_POINTER(out); 223 | } 224 | else if (parser.begin[0] == '(') 225 | tree = is_parse_arr(&parser); 226 | else 227 | tree = is_parse(&parser); 228 | 229 | pairs = palloc0(sizeof(BigIStorePairs)); 230 | n = is_tree_length(tree); 231 | bigistore_pairs_init(pairs, n); 232 | bigistore_tree_to_pairs(tree, pairs); 233 | istore_make_empty(tree); 234 | FINALIZE_BIGISTORE(out, pairs); 235 | PG_RETURN_POINTER(out); 236 | } 237 | 238 | PG_FUNCTION_INFO_V1(bigistore_recv); 239 | Datum 240 | bigistore_recv(PG_FUNCTION_ARGS) 241 | { 242 | BigIStore *result; 243 | StringInfo buf = (StringInfo) PG_GETARG_POINTER(0); 244 | int i = 0; 245 | BigIStorePairs *creator = palloc0(sizeof *creator); 246 | int32 len = pq_getmsgint(buf, 4); 247 | bigistore_pairs_init(creator, len); 248 | for (; i < len; ++i) 249 | { 250 | int32 key = pq_getmsgint(buf, 4); 251 | int64 val = pq_getmsgint64(buf); 252 | bigistore_pairs_insert(creator, key, val); 253 | } 254 | FINALIZE_BIGISTORE(result, creator); 255 | PG_RETURN_POINTER(result); 256 | } 257 | 258 | PG_FUNCTION_INFO_V1(bigistore_send); 259 | Datum 260 | bigistore_send(PG_FUNCTION_ARGS) 261 | { 262 | BigIStore *in = PG_GETARG_BIGIS(0); 263 | BigIStorePair *pairs= FIRST_PAIR(in, BigIStorePair); 264 | int i = 0; 265 | StringInfoData buf; 266 | pq_begintypsend(&buf); 267 | pq_sendint(&buf, in->len, 4); 268 | for (; i < in->len; ++i) 269 | { 270 | int32 key = pairs[i].key; 271 | int64 val = pairs[i].val; 272 | pq_sendint(&buf, key, 4); 273 | pq_sendint64(&buf, val); 274 | } 275 | PG_RETURN_BYTEA_P(pq_endtypsend(&buf)); 276 | } 277 | 278 | /* 279 | * json representation of a bigistore 280 | */ 281 | PG_FUNCTION_INFO_V1(bigistore_to_json); 282 | Datum 283 | bigistore_to_json(PG_FUNCTION_ARGS) 284 | { 285 | BigIStore *is = PG_GETARG_BIGIS(0); 286 | BigIStorePair *pairs; 287 | int i; 288 | StringInfoData dst; 289 | 290 | if (is->len == 0) 291 | PG_RETURN_TEXT_P(cstring_to_text_with_len("{}", 2)); 292 | 293 | pairs = FIRST_PAIR(is, BigIStorePair); 294 | initStringInfo(&dst); 295 | appendStringInfoChar(&dst, '{'); 296 | 297 | for (i = 0; i < is->len; i++) 298 | { 299 | char buf[25 + 1]; 300 | 301 | appendStringInfoString(&dst, "\""); 302 | pg_ltoa(pairs[i].key, buf); 303 | appendStringInfoString(&dst, buf); 304 | appendStringInfoString(&dst, "\": "); 305 | pg_lltoa(pairs[i].val, buf); 306 | appendStringInfoString(&dst, buf); 307 | if (i + 1 != is->len) 308 | appendStringInfoString(&dst, ", "); 309 | } 310 | appendStringInfoChar(&dst, '}'); 311 | PG_RETURN_TEXT_P(cstring_to_text(dst.data)); 312 | } 313 | -------------------------------------------------------------------------------- /src/istore_key_gin.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Gin support routines for istore keys 3 | * 4 | * This module provides very basic Gin index support for istore. It indexes 5 | * only the keys of the istore, and supports only the strategy to check the 6 | * key is exist or not, namely the operator "?". 7 | * 8 | * The storage type of the index is 4 byte integer as the underlying type of 9 | * istore. We wouldn't be able to use it, if we would index values of istore 10 | * too. It seems a better approch to support other strategies with another 11 | * opclass to take the most advantage of the fixed length underlying type of 12 | * istore by making index as small of possible. 13 | * 14 | * Copyright (c) 2015, Emre Hasegeli 15 | */ 16 | 17 | #include "postgres.h" 18 | 19 | #include "access/gin.h" 20 | #include "access/skey.h" 21 | 22 | #include "istore.h" 23 | #include "istore.h" 24 | 25 | 26 | /* 27 | * The Gin key extractor 28 | */ 29 | PG_FUNCTION_INFO_V1(gin_extract_istore_key); 30 | Datum 31 | gin_extract_istore_key(PG_FUNCTION_ARGS) 32 | { 33 | IStore *is = PG_GETARG_IS(0); 34 | int32 *nentries = (int32 *) PG_GETARG_POINTER(1); 35 | Datum *entries = NULL; 36 | IStorePair *pairs = FIRST_PAIR(is,IStorePair); 37 | int count = is->len; 38 | int i; 39 | 40 | *nentries = count; 41 | 42 | if (count > 0) 43 | entries = (Datum *) palloc(sizeof(Datum) * count); 44 | 45 | for (i = 0; i < count; ++i) 46 | entries[i] = Int32GetDatum(pairs[i].key); 47 | 48 | PG_RETURN_POINTER(entries); 49 | } 50 | 51 | /* 52 | * The Gin key extractor 53 | */ 54 | PG_FUNCTION_INFO_V1(gin_extract_bigistore_key); 55 | Datum 56 | gin_extract_bigistore_key(PG_FUNCTION_ARGS) 57 | { 58 | BigIStore *is = PG_GETARG_BIGIS(0); 59 | int32 *nentries = (int32 *) PG_GETARG_POINTER(1); 60 | Datum *entries = NULL; 61 | BigIStorePair *pairs = FIRST_PAIR(is,BigIStorePair); 62 | int count = is->len; 63 | int i; 64 | 65 | *nentries = count; 66 | 67 | if (count > 0) 68 | entries = (Datum *) palloc(sizeof(Datum) * count); 69 | 70 | for (i = 0; i < count; ++i) 71 | entries[i] = Int32GetDatum(pairs[i].key); 72 | 73 | PG_RETURN_POINTER(entries); 74 | } 75 | 76 | /* 77 | * The Gin query extractor 78 | */ 79 | PG_FUNCTION_INFO_V1(gin_extract_istore_key_query); 80 | Datum 81 | gin_extract_istore_key_query(PG_FUNCTION_ARGS) 82 | { 83 | Datum query = PG_GETARG_DATUM(0); 84 | int32 *nentries = (int32 *) PG_GETARG_POINTER(1); 85 | Datum *entries; 86 | 87 | *nentries = 1; 88 | entries = (Datum *) palloc(sizeof(Datum)); 89 | entries[0] = query; 90 | 91 | PG_RETURN_POINTER(entries); 92 | } 93 | 94 | /* 95 | * The Gin consistency check 96 | */ 97 | PG_FUNCTION_INFO_V1(gin_consistent_istore_key); 98 | Datum 99 | gin_consistent_istore_key(PG_FUNCTION_ARGS) 100 | { 101 | bool *recheck = (bool *) PG_GETARG_POINTER(5); 102 | bool res = true; 103 | 104 | *recheck = false; 105 | 106 | PG_RETURN_BOOL(res); 107 | } 108 | -------------------------------------------------------------------------------- /src/pairs.c: -------------------------------------------------------------------------------- 1 | #include "avl.h" 2 | #include "istore.h" 3 | #include 4 | 5 | static inline int digits32(int32 num); 6 | static inline int digits64(int64 num); 7 | 8 | int 9 | is_pair_buf_len(IStorePair *pair) 10 | { 11 | return (digits32(pair->key) + digits32(pair->val) + BUFLEN_OFFSET); 12 | } 13 | 14 | int 15 | bigis_pair_buf_len(BigIStorePair *pair) 16 | { 17 | return (digits32(pair->key) + digits64(pair->val) + BUFLEN_OFFSET); 18 | } 19 | 20 | /* 21 | * copy *src_pairs to the IStorePair of *istore and add buflen to *istore 22 | */ 23 | void 24 | istore_copy_and_add_buflen(IStore *istore, BigIStorePair *src_pairs) 25 | { 26 | IStorePair *dest_pairs = FIRST_PAIR(istore, IStorePair); 27 | 28 | for (int i = 0; i < istore->len; ++i) 29 | { 30 | dest_pairs[i].key = src_pairs[i].key; 31 | dest_pairs[i].val = src_pairs[i].val; 32 | istore->buflen += digits32(dest_pairs[i].key) + digits32(dest_pairs[i].val) + BUFLEN_OFFSET; 33 | } 34 | 35 | if (istore->buflen < 0) 36 | elog(ERROR, "istore buffer overflow"); 37 | } 38 | 39 | /* 40 | * add buflen to bigistore 41 | */ 42 | void 43 | bigistore_add_buflen(BigIStore *istore) 44 | { 45 | BigIStorePair *pairs; 46 | 47 | pairs = FIRST_PAIR(istore, BigIStorePair); 48 | 49 | for (int i = 0; i < istore->len; i++) 50 | istore->buflen += digits32(pairs[i].key) + digits64(pairs[i].val) + BUFLEN_OFFSET; 51 | 52 | if (istore->buflen < 0) 53 | elog(ERROR, "istore buffer overflow"); 54 | } 55 | 56 | /* 57 | * adds a key/ value pair for each subnode to IStorePairs 58 | * due to the nature of the AVL tree the pairs will be ordered by key 59 | */ 60 | void 61 | istore_tree_to_pairs(AvlNode *p, IStorePairs *pairs) 62 | { 63 | if (p == NULL) 64 | return; 65 | istore_tree_to_pairs(p->left, pairs); 66 | istore_pairs_insert(pairs, p->key, DatumGetInt32(DirectFunctionCall1(int84, Int64GetDatum(p->value)))); 67 | istore_tree_to_pairs(p->right, pairs); 68 | } 69 | 70 | /* 71 | * initialize IStorePairs 72 | */ 73 | void 74 | istore_pairs_init(IStorePairs *pairs, size_t initial_size) 75 | { 76 | pairs->pairs = palloc0(initial_size * sizeof(IStorePair)); 77 | pairs->used = 0; 78 | pairs->size = initial_size; 79 | pairs->buflen = 0; 80 | } 81 | 82 | /* 83 | * insert key value to IStorePairs 84 | */ 85 | void 86 | istore_pairs_insert(IStorePairs *pairs, int32 key, int32 val) 87 | { 88 | if (pairs->size == pairs->used) 89 | { 90 | if (pairs->used == PAIRS_MAX(IStorePair)) 91 | elog(ERROR, "istore can't have more than %lu keys", PAIRS_MAX(IStorePair)); 92 | 93 | pairs->size *= 2; 94 | // overflow check pairs->size should have been grown but not exceed PAIRS_MAX(IStorePair) 95 | if (pairs->size < pairs->used || pairs->size > PAIRS_MAX(IStorePair)) 96 | pairs->size = PAIRS_MAX(IStorePair); 97 | 98 | pairs->pairs = repalloc(pairs->pairs, pairs->size * sizeof(IStorePair)); 99 | } 100 | 101 | pairs->pairs[pairs->used].key = key; 102 | pairs->pairs[pairs->used].val = val; 103 | pairs->buflen += digits32(key) + digits32(val) + BUFLEN_OFFSET; 104 | 105 | if (pairs->buflen < 0) 106 | elog(ERROR, "istore buffer overflow"); 107 | pairs->used++; 108 | } 109 | 110 | /* 111 | * adds a key/ value pair for each subnode to BigIStorePairs 112 | * due to the nature of the AVL tree the pairs will be ordered by key 113 | */ 114 | void 115 | bigistore_tree_to_pairs(AvlNode *p, BigIStorePairs *pairs) 116 | { 117 | if (p == NULL) 118 | return; 119 | bigistore_tree_to_pairs(p->left, pairs); 120 | bigistore_pairs_insert(pairs, p->key, p->value); 121 | bigistore_tree_to_pairs(p->right, pairs); 122 | } 123 | 124 | /* 125 | * initialize BigIStorePairs 126 | */ 127 | void 128 | bigistore_pairs_init(BigIStorePairs *pairs, size_t initial_size) 129 | { 130 | pairs->pairs = palloc0(initial_size * sizeof(BigIStorePair)); 131 | pairs->used = 0; 132 | pairs->size = initial_size; 133 | pairs->buflen = 0; 134 | } 135 | 136 | /* 137 | * insert key value to BigIStorePairs 138 | */ 139 | void 140 | bigistore_pairs_insert(BigIStorePairs *pairs, int32 key, int64 val) 141 | { 142 | if (pairs->size == pairs->used) 143 | { 144 | if (pairs->used == PAIRS_MAX(BigIStorePair)) 145 | elog(ERROR, "bigistore can't have more than %lu keys", PAIRS_MAX(BigIStorePair)); 146 | 147 | pairs->size *= 2; 148 | // overflow check pairs->size should have been grown but not exceed PAIRS_MAX(BigIStorePair) 149 | if (pairs->size < pairs->used || pairs->size > PAIRS_MAX(BigIStorePair)) 150 | pairs->size = PAIRS_MAX(BigIStorePair); 151 | 152 | pairs->pairs = repalloc(pairs->pairs, pairs->size * sizeof(BigIStorePair)); 153 | } 154 | 155 | pairs->pairs[pairs->used].key = key; 156 | pairs->pairs[pairs->used].val = val; 157 | pairs->buflen += digits64(key) + digits64(val) + BUFLEN_OFFSET; 158 | 159 | if (pairs->buflen < 0) 160 | elog(ERROR, "bigistore buffer overflow"); 161 | pairs->used++; 162 | } 163 | 164 | /* 165 | * return the number of digits 166 | */ 167 | static inline int 168 | digits32(int32 num) 169 | { 170 | int sign = 0; 171 | if (num < 0) 172 | { 173 | if (num == INT_MIN) 174 | // special case for -2^31 because 2^31 can't fit in a two's complement 32-bit integer 175 | return 12; 176 | sign = 1; 177 | num = -num; 178 | } 179 | 180 | if (num < 1e5) 181 | { 182 | if (num < 1e3) 183 | { 184 | if (num < 10) 185 | return 1 + sign; 186 | else if (num < 1e2) 187 | return 2 + sign; 188 | else 189 | return 3 + sign; 190 | } 191 | else 192 | { 193 | if (num < 1e4) 194 | return 4 + sign; 195 | else 196 | return 5 + sign; 197 | } 198 | } 199 | else 200 | { 201 | if (num < 1e7) 202 | { 203 | if (num < 1e6) 204 | return 6 + sign; 205 | else 206 | return 7 + sign; 207 | } 208 | else 209 | { 210 | if (num < 1e8) 211 | return 8 + sign; 212 | else if (num < 1e9) 213 | return 9 + sign; 214 | else 215 | return 10 + sign; 216 | } 217 | } 218 | } 219 | 220 | /* 221 | * return the number of digits 222 | */ 223 | static inline int 224 | digits64(int64 num) 225 | { 226 | int sign = 0; 227 | if (num < 0) 228 | { 229 | sign = 1; 230 | if (num == LLONG_MIN) 231 | // special case for -2^63 because 2^63 can't fit in a two's complement 64-bit integer 232 | return 19 + sign; 233 | num = -num; 234 | } 235 | 236 | if (num < 1e10) 237 | { 238 | if (num < 1e5) 239 | { 240 | if (num < 1e3) 241 | { 242 | if (num < 10) 243 | return 1 + sign; 244 | else if (num < 1e2) 245 | return 2 + sign; 246 | else 247 | return 3 + sign; 248 | } 249 | else 250 | { 251 | if (num < 1e4) 252 | return 4 + sign; 253 | else 254 | return 5 + sign; 255 | } 256 | } 257 | else 258 | { 259 | if (num < 1e7) 260 | { 261 | if (num < 1e6) 262 | return 6 + sign; 263 | else 264 | return 7 + sign; 265 | } 266 | else 267 | { 268 | if (num < 1e8) 269 | return 8 + sign; 270 | else if (num < 1e9) 271 | return 9 + sign; 272 | else 273 | return 10 + sign; 274 | } 275 | } 276 | } 277 | else 278 | { 279 | if (num < 1e15) 280 | { 281 | if (num < 1e12) 282 | { 283 | if (num < 1e11) 284 | return 11 + sign; 285 | else 286 | return 12 + sign; 287 | } 288 | else 289 | { 290 | if (num < 1e13) 291 | return 13 + sign; 292 | else if (num < 1e14) 293 | return 14 + sign; 294 | else 295 | return 15 + sign; 296 | } 297 | } 298 | else 299 | { 300 | if (num < 1e17) 301 | { 302 | if (num < 1e16) 303 | return 16 + sign; 304 | else 305 | return 17 + sign; 306 | } 307 | else 308 | { 309 | if (num < 1e18) 310 | return 18 + sign; 311 | else 312 | return 19 + sign; 313 | } 314 | } 315 | } 316 | } 317 | -------------------------------------------------------------------------------- /test/expected/aggregates_test.out: -------------------------------------------------------------------------------- 1 | -- isagg int should skip null keys; 2 | SELECT id, isagg(NULLIF(i%10,3), NULLIF(i::int, 50) ) FROM generate_series(1,100) i, generate_series(1,3) id GROUP BY id ORDER BY id;; 3 | id | isagg 4 | ----+------------------------------------------------------------------------------------------------------------ 5 | 1 | "0"=>"500", "1"=>"460", "2"=>"470", "4"=>"490", "5"=>"500", "6"=>"510", "7"=>"520", "8"=>"530", "9"=>"540" 6 | 2 | "0"=>"500", "1"=>"460", "2"=>"470", "4"=>"490", "5"=>"500", "6"=>"510", "7"=>"520", "8"=>"530", "9"=>"540" 7 | 3 | "0"=>"500", "1"=>"460", "2"=>"470", "4"=>"490", "5"=>"500", "6"=>"510", "7"=>"520", "8"=>"530", "9"=>"540" 8 | (3 rows) 9 | 10 | -- isagg int should skip null values; 11 | SELECT id, isagg((i%10), NULL::int) FROM generate_series(1,100) i, generate_series(1,3) id GROUP BY id ORDER BY id;; 12 | id | isagg 13 | ----+------- 14 | 1 | 15 | 2 | 16 | 3 | 17 | (3 rows) 18 | 19 | -- isagg bigint should skip null keys; 20 | SELECT id, isagg(NULLIF(i%10,3), NULLIF(i::bigint, 50) ) FROM generate_series(1,100) i, generate_series(1,3) id GROUP BY id ORDER BY id;; 21 | id | isagg 22 | ----+------------------------------------------------------------------------------------------------------------ 23 | 1 | "0"=>"500", "1"=>"460", "2"=>"470", "4"=>"490", "5"=>"500", "6"=>"510", "7"=>"520", "8"=>"530", "9"=>"540" 24 | 2 | "0"=>"500", "1"=>"460", "2"=>"470", "4"=>"490", "5"=>"500", "6"=>"510", "7"=>"520", "8"=>"530", "9"=>"540" 25 | 3 | "0"=>"500", "1"=>"460", "2"=>"470", "4"=>"490", "5"=>"500", "6"=>"510", "7"=>"520", "8"=>"530", "9"=>"540" 26 | (3 rows) 27 | 28 | -- isagg bigint should skip null values; 29 | SELECT id, isagg((i%10), NULL::bigint) FROM generate_series(1,100) i, generate_series(1,3) id GROUP BY id ORDER BY id;; 30 | id | isagg 31 | ----+------- 32 | 1 | 33 | 2 | 34 | 3 | 35 | (3 rows) 36 | 37 | -- extend istore should correctly extend internal aggregation state while summing istores which total length is larger than default capacity; 38 | CREATE TABLE test_istore (v istore); 39 | INSERT INTO test_istore SELECT istore(array_agg(x), array_agg(x)) FROM generate_series(1, 31, 2) AS a(x); 40 | INSERT INTO test_istore SELECT istore(array_agg(x), array_agg(x)) FROM generate_series(2, 32, 2) AS a(x); 41 | SELECT SUM(v) FROM test_istore; 42 | sum 43 | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ 44 | "1"=>"1", "2"=>"2", "3"=>"3", "4"=>"4", "5"=>"5", "6"=>"6", "7"=>"7", "8"=>"8", "9"=>"9", "10"=>"10", "11"=>"11", "12"=>"12", "13"=>"13", "14"=>"14", "15"=>"15", "16"=>"16", "17"=>"17", "18"=>"18", "19"=>"19", "20"=>"20", "21"=>"21", "22"=>"22", "23"=>"23", "24"=>"24", "25"=>"25", "26"=>"26", "27"=>"27", "28"=>"28", "29"=>"29", "30"=>"30", "31"=>"31", "32"=>"32" 45 | (1 row) 46 | 47 | -- extend bigistore should correctly extend internal aggregation state while summing istores which total length is larger than default capacity; 48 | CREATE TABLE test_bigistore (v bigistore); 49 | INSERT INTO test_bigistore SELECT bigistore(array_agg(x), array_agg(x)) FROM generate_series(1, 31, 2) AS a(x); 50 | INSERT INTO test_bigistore SELECT bigistore(array_agg(x), array_agg(x)) FROM generate_series(2, 32, 2) AS a(x); 51 | SELECT SUM(v) FROM test_bigistore; 52 | sum 53 | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ 54 | "1"=>"1", "2"=>"2", "3"=>"3", "4"=>"4", "5"=>"5", "6"=>"6", "7"=>"7", "8"=>"8", "9"=>"9", "10"=>"10", "11"=>"11", "12"=>"12", "13"=>"13", "14"=>"14", "15"=>"15", "16"=>"16", "17"=>"17", "18"=>"18", "19"=>"19", "20"=>"20", "21"=>"21", "22"=>"22", "23"=>"23", "24"=>"24", "25"=>"25", "26"=>"26", "27"=>"27", "28"=>"28", "29"=>"29", "30"=>"30", "31"=>"31", "32"=>"32" 55 | (1 row) 56 | 57 | -------------------------------------------------------------------------------- /test/expected/binary_copy_test.out: -------------------------------------------------------------------------------- 1 | -- bigistore binary_copy should copy data out and in again using binary format; 2 | CREATE TABLE before_bigistore (a bigistore); 3 | INSERT INTO before_bigistore values ('1=>1'),('1=>-9223372036854775807'),('1=>3'),('2=>1'),('2=>0'),('2=>9223372036854775806'); 4 | CREATE TABLE after_bigistore (a bigistore); 5 | COPY before_bigistore TO '/tmp/tst' WITH (FORMAT binary); 6 | COPY after_bigistore FROM '/tmp/tst' WITH (FORMAT binary); 7 | SELECT * FROM after_bigistore; 8 | a 9 | ----------------------------- 10 | "1"=>"1" 11 | "1"=>"-9223372036854775807" 12 | "1"=>"3" 13 | "2"=>"1" 14 | "2"=>"0" 15 | "2"=>"9223372036854775806" 16 | (6 rows) 17 | 18 | -- istore binary_copy should copy data out and in again using binary format; 19 | CREATE TABLE before_istore (a istore); 20 | INSERT INTO before_istore values ('1=>1'),('1=>-2147483647'),('1=>3'),('2=>1'),('2=>0'),('2=>2147483647'); 21 | CREATE TABLE after_istore (a istore); 22 | COPY before_istore TO '/tmp/tst' WITH (FORMAT binary); 23 | COPY after_istore FROM '/tmp/tst' WITH (FORMAT binary); 24 | SELECT * FROM after_istore; 25 | a 26 | -------------------- 27 | "1"=>"1" 28 | "1"=>"-2147483647" 29 | "1"=>"3" 30 | "2"=>"1" 31 | "2"=>"0" 32 | "2"=>"2147483647" 33 | (6 rows) 34 | 35 | -------------------------------------------------------------------------------- /test/expected/cast_test.out: -------------------------------------------------------------------------------- 1 | -- casts should cast from istore to bigistore; 2 | SELECT '1=>1, -1=>-1'::istore::bigistore; 3 | bigistore 4 | ---------------------- 5 | "-1"=>"-1", "1"=>"1" 6 | (1 row) 7 | 8 | -- casts should cast from bigistore to istore; 9 | SELECT '1=>1, -1=>-1'::bigistore::istore; 10 | istore 11 | ---------------------- 12 | "-1"=>"-1", "1"=>"1" 13 | (1 row) 14 | 15 | -- casts should fail cast from bigistore to istore if any value is to big; 16 | SELECT '1=>1, -1=>3000000000'::bigistore::istore; 17 | ERROR: integer out of range 18 | -------------------------------------------------------------------------------- /test/expected/functions_test.out: -------------------------------------------------------------------------------- 1 | -- istore test cases 2 | SELECT max_value(''::istore); 3 | max_value 4 | ----------- 5 | 6 | (1 row) 7 | 8 | SELECT max_value('1=>1'::istore); 9 | max_value 10 | ----------- 11 | 1 12 | (1 row) 13 | 14 | SELECT max_value('1=>1, 2=>1'::istore); 15 | max_value 16 | ----------- 17 | 1 18 | (1 row) 19 | 20 | SELECT max_value('0=>2, 1=>4, 3=>0 ,2=>2'::istore); 21 | max_value 22 | ----------- 23 | 4 24 | (1 row) 25 | 26 | SELECT max_value('10=>21, 11=>500, 13=>800 ,12=>4200'::istore); 27 | max_value 28 | ----------- 29 | 4200 30 | (1 row) 31 | 32 | -- bigistore test cases 33 | SELECT max_value(''::bigistore); 34 | max_value 35 | ----------- 36 | 37 | (1 row) 38 | 39 | SELECT max_value('1=>1'::bigistore); 40 | max_value 41 | ----------- 42 | 1 43 | (1 row) 44 | 45 | SELECT max_value('1=>1, 2=>1'::bigistore); 46 | max_value 47 | ----------- 48 | 1 49 | (1 row) 50 | 51 | SELECT max_value('0=>2, 1=>4, 3=>0 ,2=>2'::bigistore); 52 | max_value 53 | ----------- 54 | 4 55 | (1 row) 56 | 57 | SELECT max_value('10=>21, 11=>500, 13=>800 ,12=>4200'::bigistore); 58 | max_value 59 | ----------- 60 | 4200 61 | (1 row) 62 | 63 | SELECT max_value('10=>21, 11=>500, 13=>800 ,12=>3147483647'::bigistore); 64 | max_value 65 | ------------ 66 | 3147483647 67 | (1 row) 68 | 69 | -------------------------------------------------------------------------------- /test/expected/istore_key_gin_test.out: -------------------------------------------------------------------------------- 1 | -- bigistore gin access should do index scan using gin; 2 | CREATE TABLE t AS 3 | SELECT i, string_agg(j::text || '=>0', ',')::bigistore AS s 4 | FROM 5 | generate_series(0, 10000) AS i, 6 | generate_series(i, i + (i % 10)) AS j 7 | GROUP BY i; 8 | CREATE INDEX ON t USING gin(s); 9 | SET enable_seqscan = 0; 10 | EXPLAIN (COSTS OFF) SELECT * FROM t WHERE s ? 3; 11 | QUERY PLAN 12 | ------------------------------------ 13 | Bitmap Heap Scan on t 14 | Recheck Cond: (s ? 3) 15 | -> Bitmap Index Scan on t_s_idx 16 | Index Cond: (s ? 3) 17 | (4 rows) 18 | 19 | -- bigistore gin access should find the matching rows for key 300; 20 | SELECT s FROM t WHERE s ? 300 ORDER BY i; 21 | s 22 | ------------------------------------------------------------------------------------------------------------------------ 23 | "295"=>"0", "296"=>"0", "297"=>"0", "298"=>"0", "299"=>"0", "300"=>"0" 24 | "296"=>"0", "297"=>"0", "298"=>"0", "299"=>"0", "300"=>"0", "301"=>"0", "302"=>"0" 25 | "297"=>"0", "298"=>"0", "299"=>"0", "300"=>"0", "301"=>"0", "302"=>"0", "303"=>"0", "304"=>"0" 26 | "298"=>"0", "299"=>"0", "300"=>"0", "301"=>"0", "302"=>"0", "303"=>"0", "304"=>"0", "305"=>"0", "306"=>"0" 27 | "299"=>"0", "300"=>"0", "301"=>"0", "302"=>"0", "303"=>"0", "304"=>"0", "305"=>"0", "306"=>"0", "307"=>"0", "308"=>"0" 28 | "300"=>"0" 29 | (6 rows) 30 | 31 | -- bigistore gin access should find the matching rows for key 600; 32 | SELECT s FROM t WHERE s ? 600 ORDER BY i; 33 | s 34 | ------------------------------------------------------------------------------------------------------------------------ 35 | "595"=>"0", "596"=>"0", "597"=>"0", "598"=>"0", "599"=>"0", "600"=>"0" 36 | "596"=>"0", "597"=>"0", "598"=>"0", "599"=>"0", "600"=>"0", "601"=>"0", "602"=>"0" 37 | "597"=>"0", "598"=>"0", "599"=>"0", "600"=>"0", "601"=>"0", "602"=>"0", "603"=>"0", "604"=>"0" 38 | "598"=>"0", "599"=>"0", "600"=>"0", "601"=>"0", "602"=>"0", "603"=>"0", "604"=>"0", "605"=>"0", "606"=>"0" 39 | "599"=>"0", "600"=>"0", "601"=>"0", "602"=>"0", "603"=>"0", "604"=>"0", "605"=>"0", "606"=>"0", "607"=>"0", "608"=>"0" 40 | "600"=>"0" 41 | (6 rows) 42 | 43 | -- bigistore gin access should find the matching rows for key 900; 44 | SELECT s FROM t WHERE s ? 900 ORDER BY i; 45 | s 46 | ------------------------------------------------------------------------------------------------------------------------ 47 | "895"=>"0", "896"=>"0", "897"=>"0", "898"=>"0", "899"=>"0", "900"=>"0" 48 | "896"=>"0", "897"=>"0", "898"=>"0", "899"=>"0", "900"=>"0", "901"=>"0", "902"=>"0" 49 | "897"=>"0", "898"=>"0", "899"=>"0", "900"=>"0", "901"=>"0", "902"=>"0", "903"=>"0", "904"=>"0" 50 | "898"=>"0", "899"=>"0", "900"=>"0", "901"=>"0", "902"=>"0", "903"=>"0", "904"=>"0", "905"=>"0", "906"=>"0" 51 | "899"=>"0", "900"=>"0", "901"=>"0", "902"=>"0", "903"=>"0", "904"=>"0", "905"=>"0", "906"=>"0", "907"=>"0", "908"=>"0" 52 | "900"=>"0" 53 | (6 rows) 54 | 55 | -- istore gin access should do index scan using gin; 56 | EXPLAIN (COSTS OFF) SELECT * FROM t WHERE s ? 3; 57 | QUERY PLAN 58 | ------------------------------------ 59 | Bitmap Heap Scan on t 60 | Recheck Cond: (s ? 3) 61 | -> Bitmap Index Scan on t_s_idx 62 | Index Cond: (s ? 3) 63 | (4 rows) 64 | 65 | -- istore gin access should find the matching rows for key 300; 66 | SELECT s FROM t WHERE s ? 300 ORDER BY i; 67 | s 68 | ------------------------------------------------------------------------------------------------------------------------ 69 | "295"=>"0", "296"=>"0", "297"=>"0", "298"=>"0", "299"=>"0", "300"=>"0" 70 | "296"=>"0", "297"=>"0", "298"=>"0", "299"=>"0", "300"=>"0", "301"=>"0", "302"=>"0" 71 | "297"=>"0", "298"=>"0", "299"=>"0", "300"=>"0", "301"=>"0", "302"=>"0", "303"=>"0", "304"=>"0" 72 | "298"=>"0", "299"=>"0", "300"=>"0", "301"=>"0", "302"=>"0", "303"=>"0", "304"=>"0", "305"=>"0", "306"=>"0" 73 | "299"=>"0", "300"=>"0", "301"=>"0", "302"=>"0", "303"=>"0", "304"=>"0", "305"=>"0", "306"=>"0", "307"=>"0", "308"=>"0" 74 | "300"=>"0" 75 | (6 rows) 76 | 77 | -- istore gin access should find the matching rows for key 600; 78 | SELECT s FROM t WHERE s ? 600 ORDER BY i; 79 | s 80 | ------------------------------------------------------------------------------------------------------------------------ 81 | "595"=>"0", "596"=>"0", "597"=>"0", "598"=>"0", "599"=>"0", "600"=>"0" 82 | "596"=>"0", "597"=>"0", "598"=>"0", "599"=>"0", "600"=>"0", "601"=>"0", "602"=>"0" 83 | "597"=>"0", "598"=>"0", "599"=>"0", "600"=>"0", "601"=>"0", "602"=>"0", "603"=>"0", "604"=>"0" 84 | "598"=>"0", "599"=>"0", "600"=>"0", "601"=>"0", "602"=>"0", "603"=>"0", "604"=>"0", "605"=>"0", "606"=>"0" 85 | "599"=>"0", "600"=>"0", "601"=>"0", "602"=>"0", "603"=>"0", "604"=>"0", "605"=>"0", "606"=>"0", "607"=>"0", "608"=>"0" 86 | "600"=>"0" 87 | (6 rows) 88 | 89 | -- istore gin access should find the matching rows for key 900; 90 | SELECT s FROM t WHERE s ? 900 ORDER BY i; 91 | s 92 | ------------------------------------------------------------------------------------------------------------------------ 93 | "895"=>"0", "896"=>"0", "897"=>"0", "898"=>"0", "899"=>"0", "900"=>"0" 94 | "896"=>"0", "897"=>"0", "898"=>"0", "899"=>"0", "900"=>"0", "901"=>"0", "902"=>"0" 95 | "897"=>"0", "898"=>"0", "899"=>"0", "900"=>"0", "901"=>"0", "902"=>"0", "903"=>"0", "904"=>"0" 96 | "898"=>"0", "899"=>"0", "900"=>"0", "901"=>"0", "902"=>"0", "903"=>"0", "904"=>"0", "905"=>"0", "906"=>"0" 97 | "899"=>"0", "900"=>"0", "901"=>"0", "902"=>"0", "903"=>"0", "904"=>"0", "905"=>"0", "906"=>"0", "907"=>"0", "908"=>"0" 98 | "900"=>"0" 99 | (6 rows) 100 | 101 | RESET enable_seqscan; 102 | -------------------------------------------------------------------------------- /test/expected/migration_test.out: -------------------------------------------------------------------------------- 1 | -- istore should be downgradeable; 2 | ALTER EXTENSION istore UPDATE TO '0.1.3'; 3 | SELECT e.extname, e.extversion FROM pg_catalog.pg_extension e WHERE e.extname = 'istore'ORDER BY 1; 4 | extname | extversion 5 | ---------+------------ 6 | istore | 0.1.3 7 | (1 row) 8 | 9 | -- istore should be upgradeable; 10 | ALTER EXTENSION istore UPDATE TO '0.1.4'; 11 | ALTER EXTENSION istore UPDATE TO '0.1.3'; 12 | SELECT e.extname, e.extversion FROM pg_catalog.pg_extension e WHERE e.extname = 'istore'ORDER BY 1; 13 | extname | extversion 14 | ---------+------------ 15 | istore | 0.1.3 16 | (1 row) 17 | 18 | -- istore should be upgradable to latest version; 19 | ALTER EXTENSION istore UPDATE; 20 | -------------------------------------------------------------------------------- /test/sql/aggregates_test.sql: -------------------------------------------------------------------------------- 1 | -- isagg int should skip null keys; 2 | SELECT id, isagg(NULLIF(i%10,3), NULLIF(i::int, 50) ) FROM generate_series(1,100) i, generate_series(1,3) id GROUP BY id ORDER BY id;; 3 | -- isagg int should skip null values; 4 | SELECT id, isagg((i%10), NULL::int) FROM generate_series(1,100) i, generate_series(1,3) id GROUP BY id ORDER BY id;; 5 | -- isagg bigint should skip null keys; 6 | SELECT id, isagg(NULLIF(i%10,3), NULLIF(i::bigint, 50) ) FROM generate_series(1,100) i, generate_series(1,3) id GROUP BY id ORDER BY id;; 7 | -- isagg bigint should skip null values; 8 | SELECT id, isagg((i%10), NULL::bigint) FROM generate_series(1,100) i, generate_series(1,3) id GROUP BY id ORDER BY id;; 9 | -- extend istore should correctly extend internal aggregation state while summing istores which total length is larger than default capacity; 10 | CREATE TABLE test_istore (v istore); 11 | INSERT INTO test_istore SELECT istore(array_agg(x), array_agg(x)) FROM generate_series(1, 31, 2) AS a(x); 12 | INSERT INTO test_istore SELECT istore(array_agg(x), array_agg(x)) FROM generate_series(2, 32, 2) AS a(x); 13 | SELECT SUM(v) FROM test_istore; 14 | -- extend bigistore should correctly extend internal aggregation state while summing istores which total length is larger than default capacity; 15 | CREATE TABLE test_bigistore (v bigistore); 16 | INSERT INTO test_bigistore SELECT bigistore(array_agg(x), array_agg(x)) FROM generate_series(1, 31, 2) AS a(x); 17 | INSERT INTO test_bigistore SELECT bigistore(array_agg(x), array_agg(x)) FROM generate_series(2, 32, 2) AS a(x); 18 | SELECT SUM(v) FROM test_bigistore; 19 | -------------------------------------------------------------------------------- /test/sql/binary_copy_test.sql: -------------------------------------------------------------------------------- 1 | -- bigistore binary_copy should copy data out and in again using binary format; 2 | CREATE TABLE before_bigistore (a bigistore); 3 | INSERT INTO before_bigistore values ('1=>1'),('1=>-9223372036854775807'),('1=>3'),('2=>1'),('2=>0'),('2=>9223372036854775806'); 4 | CREATE TABLE after_bigistore (a bigistore); 5 | COPY before_bigistore TO '/tmp/tst' WITH (FORMAT binary); 6 | COPY after_bigistore FROM '/tmp/tst' WITH (FORMAT binary); 7 | SELECT * FROM after_bigistore; 8 | -- istore binary_copy should copy data out and in again using binary format; 9 | CREATE TABLE before_istore (a istore); 10 | INSERT INTO before_istore values ('1=>1'),('1=>-2147483647'),('1=>3'),('2=>1'),('2=>0'),('2=>2147483647'); 11 | CREATE TABLE after_istore (a istore); 12 | COPY before_istore TO '/tmp/tst' WITH (FORMAT binary); 13 | COPY after_istore FROM '/tmp/tst' WITH (FORMAT binary); 14 | SELECT * FROM after_istore; 15 | -------------------------------------------------------------------------------- /test/sql/cast_test.sql: -------------------------------------------------------------------------------- 1 | -- casts should cast from istore to bigistore; 2 | SELECT '1=>1, -1=>-1'::istore::bigistore; 3 | -- casts should cast from bigistore to istore; 4 | SELECT '1=>1, -1=>-1'::bigistore::istore; 5 | -- casts should fail cast from bigistore to istore if any value is to big; 6 | SELECT '1=>1, -1=>3000000000'::bigistore::istore; 7 | -------------------------------------------------------------------------------- /test/sql/functions_test.sql: -------------------------------------------------------------------------------- 1 | -- istore test cases 2 | SELECT max_value(''::istore); 3 | SELECT max_value('1=>1'::istore); 4 | SELECT max_value('1=>1, 2=>1'::istore); 5 | SELECT max_value('0=>2, 1=>4, 3=>0 ,2=>2'::istore); 6 | SELECT max_value('10=>21, 11=>500, 13=>800 ,12=>4200'::istore); 7 | 8 | -- bigistore test cases 9 | SELECT max_value(''::bigistore); 10 | SELECT max_value('1=>1'::bigistore); 11 | SELECT max_value('1=>1, 2=>1'::bigistore); 12 | SELECT max_value('0=>2, 1=>4, 3=>0 ,2=>2'::bigistore); 13 | SELECT max_value('10=>21, 11=>500, 13=>800 ,12=>4200'::bigistore); 14 | SELECT max_value('10=>21, 11=>500, 13=>800 ,12=>3147483647'::bigistore); 15 | -------------------------------------------------------------------------------- /test/sql/istore_io_test.sql: -------------------------------------------------------------------------------- 1 | -- bigistore istore_io should persist istores; 2 | CREATE TABLE istore_io1 AS SELECT '-2147483647 => 10, -10 => -9223372036854775807, 0 => 5, 10 => 9223372036854775806, 2147483647 => 10'::bigistore; 3 | SELECT * FROM istore_io1; 4 | -- bigistore istore_io should persist istores; 5 | CREATE TABLE istore_io2 AS SELECT '"-1"=>"+1","1"=>"2"'::bigistore; 6 | SELECT * FROM istore_io2; 7 | -- bigistore istore_io should persist istores; 8 | CREATE TABLE istore_io3 AS SELECT ' "-1"=>"+1","1"=>"2"'::bigistore; 9 | SELECT * FROM istore_io3; 10 | -- bigistore istore_io should persist empty istores; 11 | CREATE TABLE istore_io4 AS SELECT ''::bigistore; 12 | SELECT * FROM istore_io4; 13 | -- bigistore istore_io should turn istore to json; 14 | SELECT istore_to_json('-2147483647 => 10, -10 => -9223372036854775807, 0 => 5, 10 => 9223372036854775806, 2147483647 => 10'::bigistore); 15 | -- bigistore istore_io invalid input should report invalid value input; 16 | SELECT '2=>4, 1=>foo, 5=>17'::bigistore; 17 | -- bigistore istore_io invalid input should report invalid value input; 18 | SELECT '2=>4, 1=>5foo, 5=>17'::bigistore; 19 | -- bigistore istore_io invalid input should report to big value input; 20 | SELECT '2=>4, 1=>18446744073709551612, 5=>17'::bigistore; 21 | -- bigistore istore_io invalid input should report to small value input; 22 | SELECT '2=>4, 1=>-18446744073709551614, 5=>17'::bigistore; 23 | -- bigistore istore_io invalid input should report invalid key input; 24 | SELECT '2=>4, 54foo=>5, 5=>17'::bigistore; 25 | -- bigistore istore_io invalid input should report invalid key input; 26 | SELECT '2=>4, foo=>5, 5=>17'::bigistore; 27 | -- bigistore istore_io invalid input should report to big key input; 28 | SELECT '2=>4, 4000000000=>5, 5=>17'::bigistore; 29 | -- bigistore istore_io invalid input should report to small key input; 30 | SELECT '2=>4, -4000000000=>5, 5=>17'::bigistore; 31 | -- bigistore istore_io invalid input should report invalid delimiter input; 32 | SELECT '2=>4, 10=5, 5=>17'::bigistore; 33 | -- bigistore istore_io invalid input should report unexpected end of line; 34 | SELECT '1=>2,2='::bigistore; 35 | -- bigistore istore_io array input should parse normal arrays tuple; 36 | SELECT '([1,2], [11, 22])'::bigistore; 37 | -- bigistore istore_io array input should parse normal arrays tuple with spaces; 38 | SELECT '([1, 2] ,[ 11, 22])'::bigistore; 39 | -- bigistore istore_io array input should parse normal small arrays tuple; 40 | SELECT '([1],[11])'::bigistore; 41 | -- bigistore istore_io array input should parse normal empty arrays tuple; 42 | SELECT '([],[])'::bigistore; 43 | -- bigistore istore_io array invalid input should report unexpected end of line; 44 | SELECT '([1,2], ['::bigistore; 45 | -- bigistore istore_io array invalid input should report expected comma in values; 46 | SELECT '([1,2], [1'::bigistore; 47 | -- bigistore istore_io array invalid input should report expected number; 48 | SELECT '([1,2], [1,'::bigistore; 49 | -- bigistore istore_io array invalid input should report on uneven tuples; 50 | SELECT '([1,2], [1,2,3])'::bigistore; 51 | -- bigistore istore_io array invalid input should report on uneven tuples; 52 | SELECT '([1,2,3],[1,2])'::bigistore; 53 | -- bigistore istore_io array invalid input should report arrays delimiter; 54 | SELECT '([1,2]|[1,2])'::bigistore; 55 | -- bigistore istore_io array invalid input should report on ending bracket; 56 | SELECT '([1,2],[1,2]'::bigistore; 57 | -- bigistore istore_io array invalid input should report integer out of range; 58 | SELECT '([2147483648], [1])'::bigistore; 59 | -- bigistore istore_io arrays row input should create bigistore from row; 60 | SELECT row_to_bigistore((array[1,2], array[11, 22])); 61 | -- bigistore istore_io arrays row input should create bigistore from row with int8 keys; 62 | SELECT row_to_bigistore((array[1::int8,2::int8], array[11, 22])); 63 | -- bigistore istore_io arrays row input should fail on other kind of rows (case 1); 64 | SELECT row_to_bigistore((array[1,2], array[11, 22], array[1,2])); 65 | -- bigistore istore_io arrays row input should fail on other kind of rows (case 2); 66 | SELECT row_to_bigistore((array[1,2], 'qwerty')); 67 | -- bigistore istore_io arrays row input should fail on other kind of rows (case 3); 68 | SELECT row_to_bigistore((array[1,2], array['1', '2'])); 69 | -- bigistore istore_io arrays row input should fail on integer overflow (INT_MAX); 70 | SELECT row_to_bigistore((array[4147483647,2], array[11, 22])); 71 | -- bigistore istore_io arrays row input should fail on integer overflow (INT_MIN); 72 | SELECT row_to_bigistore((array[-4147483648,2], array[11, 22])); 73 | -- istore istore_io should persist istores; 74 | CREATE TABLE istore_io5 AS SELECT '-2147483647 => 10, -10 => -2147483647, 0 => 5, 10 => 2147483647, 2147483647 => 10'::istore; 75 | SELECT * FROM istore_io5; 76 | -- istore istore_io should persist istores; 77 | CREATE TABLE istore_io6 AS SELECT '"-1"=>"+1","1"=>"2"'::istore; 78 | SELECT * FROM istore_io6; 79 | -- istore istore_io should persist istores; 80 | CREATE TABLE istore_io7 AS SELECT ' "-1"=>"+1","1"=>"2"'::istore; 81 | SELECT * FROM istore_io7; 82 | -- istore istore_io should persist empty istores; 83 | CREATE TABLE istore_io8 AS SELECT ''::istore; 84 | SELECT * FROM istore_io8; 85 | -- istore istore_io should turn istore to json; 86 | SELECT istore_to_json('-2147483647 => 10, -10 => -2147483647, 0 => 5, 10 => 2147483647, 2147483647 => 10'::istore); 87 | -- istore istore_io invalid input should report invalid value input; 88 | SELECT '2=>4, 1=>foo, 5=>17'::istore; 89 | -- istore istore_io invalid input should report invalid value input; 90 | SELECT '2=>4, 1=>5foo, 5=>17'::istore; 91 | -- istore istore_io invalid input should report to big value input; 92 | SELECT '2=>4, 1=>4294967294, 5=>17'::istore; 93 | -- istore istore_io invalid input should report to small value input; 94 | SELECT '2=>4, 1=>-4294967294, 5=>17'::istore; 95 | -- istore istore_io invalid input should report invalid key input; 96 | SELECT '2=>4, 54foo=>5, 5=>17'::istore; 97 | -- istore istore_io invalid input should report invalid key input; 98 | SELECT '2=>4, foo=>5, 5=>17'::istore; 99 | -- istore istore_io invalid input should report to big key input; 100 | SELECT '2=>4, 4000000000=>5, 5=>17'::istore; 101 | -- istore istore_io invalid input should report to small key input; 102 | SELECT '2=>4, -4000000000=>5, 5=>17'::istore; 103 | -- istore istore_io invalid input should report invalid delimiter input; 104 | SELECT '2=>4, 10=5, 5=>17'::istore; 105 | -- istore istore_io invalid input should report unexpected end of line; 106 | SELECT '1=>2,2='::istore; 107 | -- istore istore_io array input should parse normal arrays tuple; 108 | SELECT '([1,2], [11, 22])'::istore; 109 | -- istore istore_io array input should parse normal arrays tuple with spaces; 110 | SELECT '([1, 2] ,[ 11, 22])'::istore; 111 | -- istore istore_io array input should parse normal small arrays tuple; 112 | SELECT '([1],[11])'::istore; 113 | -- istore istore_io array input should parse normal empty arrays tuple; 114 | SELECT '([],[])'::istore; 115 | -- istore istore_io array invalid input should report unexpected end of line; 116 | SELECT '([1,2], ['::istore; 117 | -- istore istore_io array invalid input should report expected comma in values; 118 | SELECT '([1,2], [1'::istore; 119 | -- istore istore_io array invalid input should report expected number; 120 | SELECT '([1,2], [1,'::istore; 121 | -- istore istore_io array invalid input should report on uneven tuples; 122 | SELECT '([1,2], [1,2,3])'::istore; 123 | -- istore istore_io array invalid input should report on uneven tuples; 124 | SELECT '([1,2,3],[1,2])'::istore; 125 | -- istore istore_io array invalid input should report arrays delimiter; 126 | SELECT '([1,2]|[1,2])'::istore; 127 | -- istore istore_io array invalid input should report on ending bracket; 128 | SELECT '([1,2],[1,2]'::istore; 129 | -- istore istore_io array invalid input should report integer out of range; 130 | SELECT '([2147483648], [1])'::istore; 131 | -- istore istore_io arrays row input should create istore from row; 132 | SELECT row_to_istore((array[1,2], array[11, 22])); 133 | -- istore istore_io arrays row input should create istore from row with int8 keys; 134 | SELECT row_to_istore((array[1::int8,2::int8], array[11, 22])); 135 | -- istore istore_io arrays row input should fail on other kind of rows (case 1); 136 | SELECT row_to_istore((array[1,2], array[11, 22], array[1,2])); 137 | -- istore istore_io arrays row input should fail on other kind of rows (case 2); 138 | SELECT row_to_istore((array[1,2], 'qwerty')); 139 | -- istore istore_io arrays row input should fail on other kind of rows (case 3); 140 | SELECT row_to_istore((array[1,2], array['1', '2'])); 141 | -- istore istore_io arrays row input should fail on integer overflow (INT_MAX); 142 | SELECT row_to_istore((array[4147483647,2], array[11, 22])); 143 | -- istore istore_io arrays row input should fail on integer overflow (INT_MIN); 144 | SELECT row_to_istore((array[-4147483648,2], array[11, 22])); 145 | -- istore should not fail on consecutive call of strtol 146 | select id, '1=>1'::bigistore from (values (2147483648)) v(id); 147 | select id, '1=>1'::bigistore from (values (2147483648)) v(id); 148 | -------------------------------------------------------------------------------- /test/sql/istore_key_gin_test.sql: -------------------------------------------------------------------------------- 1 | -- bigistore gin access should do index scan using gin; 2 | CREATE TABLE t AS 3 | SELECT i, string_agg(j::text || '=>0', ',')::bigistore AS s 4 | FROM 5 | generate_series(0, 10000) AS i, 6 | generate_series(i, i + (i % 10)) AS j 7 | GROUP BY i; 8 | CREATE INDEX ON t USING gin(s); 9 | SET enable_seqscan = 0; 10 | EXPLAIN (COSTS OFF) SELECT * FROM t WHERE s ? 3; 11 | -- bigistore gin access should find the matching rows for key 300; 12 | SELECT s FROM t WHERE s ? 300 ORDER BY i; 13 | -- bigistore gin access should find the matching rows for key 600; 14 | SELECT s FROM t WHERE s ? 600 ORDER BY i; 15 | -- bigistore gin access should find the matching rows for key 900; 16 | SELECT s FROM t WHERE s ? 900 ORDER BY i; 17 | -- istore gin access should do index scan using gin; 18 | EXPLAIN (COSTS OFF) SELECT * FROM t WHERE s ? 3; 19 | -- istore gin access should find the matching rows for key 300; 20 | SELECT s FROM t WHERE s ? 300 ORDER BY i; 21 | -- istore gin access should find the matching rows for key 600; 22 | SELECT s FROM t WHERE s ? 600 ORDER BY i; 23 | -- istore gin access should find the matching rows for key 900; 24 | SELECT s FROM t WHERE s ? 900 ORDER BY i; 25 | RESET enable_seqscan; 26 | -------------------------------------------------------------------------------- /test/sql/migration_test.sql: -------------------------------------------------------------------------------- 1 | -- istore should be downgradeable; 2 | ALTER EXTENSION istore UPDATE TO '0.1.3'; 3 | SELECT e.extname, e.extversion FROM pg_catalog.pg_extension e WHERE e.extname = 'istore'ORDER BY 1; 4 | -- istore should be upgradeable; 5 | ALTER EXTENSION istore UPDATE TO '0.1.4'; 6 | ALTER EXTENSION istore UPDATE TO '0.1.3'; 7 | SELECT e.extname, e.extversion FROM pg_catalog.pg_extension e WHERE e.extname = 'istore'ORDER BY 1; 8 | -- istore should be upgradable to latest version; 9 | ALTER EXTENSION istore UPDATE; 10 | -------------------------------------------------------------------------------- /test/sql/operator_test.sql: -------------------------------------------------------------------------------- 1 | -- bigistore operators bigistore should fetch values; 2 | SELECT '1=>1, -1=>0'::bigistore -> -1; 3 | SELECT '1=>1, -1=>3'::bigistore -> -1; 4 | SELECT '0=>40000000000'::bigistore->0; 5 | SELECT '-2147483647 => 10, -10 => -9223372036854775807, 0 => 5, 10 => 9223372036854775806, 2147483647 => 10'::bigistore -> 10; 6 | SELECT '-2147483647 => 10, -10 => -9223372036854775807, 0 => 5, 10 => 9223372036854775806, 2147483647 => 10'::bigistore -> Array[10,0]; 7 | -- bigistore operators bigistore should check existense of a key; 8 | SELECT '1=>1, -1=>3'::bigistore ? -1; 9 | SELECT '1=>1, -1=>3'::bigistore ? 5; 10 | -- bigistore operators bigistore should add two bigistore; 11 | SELECT '1=>1, -1=>3'::bigistore + '1=>1'::bigistore; 12 | SELECT '1=>1, -1=>3'::bigistore + '-1=>-1'::bigistore; 13 | SELECT '1=>1, -1=>3'::bigistore + '1=>-1'::bigistore; 14 | SELECT '1=>0, -1=>3'::bigistore + '1=>-1'::bigistore; 15 | SELECT '1=>1, -1=>0'::bigistore + '-1=>-1'::bigistore; 16 | -- bigistore operators bigistore should add an integer to #{type}; 17 | SELECT '1=>1, -1=>3'::bigistore + 1; 18 | SELECT '-1=>1, 1=>3'::bigistore + 1; 19 | SELECT '-1=>1, -1=>3'::bigistore + 1; 20 | SELECT '1=>1, -1=>3'::bigistore + 0; 21 | SELECT '-1=>1, 1=>3'::bigistore + 0; 22 | SELECT '-1=>1, -1=>3'::bigistore + 0; 23 | SELECT '1=>1, -1=>3'::bigistore + -1; 24 | SELECT '-1=>1, 1=>3'::bigistore + -1; 25 | SELECT '-1=>1, -1=>3'::bigistore + -1; 26 | -- bigistore operators bigistore should substract two bigistore; 27 | SELECT '1=>1, -1=>3'::bigistore - '1=>1'::bigistore; 28 | SELECT '1=>1, -1=>3'::bigistore - '-1=>-1'::bigistore; 29 | SELECT '1=>1, -1=>3'::bigistore - '1=>-1'::bigistore; 30 | SELECT '1=>0, -1=>3'::bigistore - '1=>-1'::bigistore; 31 | -- bigistore operators bigistore should substract integer from bigistore; 32 | SELECT '1=>1, -1=>3'::bigistore - 1; 33 | SELECT '-1=>1, 1=>3'::bigistore - 1; 34 | SELECT '-1=>1, -1=>3'::bigistore - 1; 35 | SELECT '1=>1, -1=>3'::bigistore - 0; 36 | SELECT '-1=>1, 1=>3'::bigistore - 0; 37 | SELECT '-1=>1, -1=>3'::bigistore - 0; 38 | SELECT '1=>1, -1=>3'::bigistore - -1; 39 | SELECT '-1=>1, 1=>3'::bigistore - -1; 40 | SELECT '-1=>1, -1=>3'::bigistore - -1; 41 | -- bigistore operators bigistore should multiply two bigistore; 42 | SELECT '1=>3, 2=>2'::bigistore * '1=>2, 3=>5'::bigistore; 43 | SELECT '-1=>3, 2=>2'::bigistore * '-1=>2, 3=>5'::bigistore; 44 | SELECT '-1=>3, 2=>2'::bigistore * '-1=>-2, 3=>5'::bigistore; 45 | SELECT '-1=>3, 2=>0'::bigistore * '-1=>-2, 3=>5'::bigistore; 46 | -- bigistore operators bigistore should multiply #{type} with integer; 47 | SELECT '1=>1, -1=>3'::bigistore * 1; 48 | SELECT '-1=>1, 1=>3'::bigistore * 1; 49 | SELECT '-1=>1, -1=>3'::bigistore * 1; 50 | SELECT '1=>1, -1=>3'::bigistore * 0; 51 | SELECT '-1=>1, 1=>3'::bigistore * 0; 52 | SELECT '-1=>1, -1=>3'::bigistore * 0; 53 | SELECT '1=>1, -1=>3'::bigistore * -1; 54 | SELECT '-1=>1, 1=>3'::bigistore * -1; 55 | SELECT '-1=>1, -1=>3'::bigistore * -1; 56 | -- bigistore operators bigistore should return convert to array; 57 | SELECT %%'-2147483647 => 10, -10 => -9223372036854775807, 0 => 5, 10 => 9223372036854775806, 2147483647 => 10'::bigistore; 58 | SELECT %#'-2147483647 => 10, -10 => -9223372036854775807, 0 => 5, 10 => 9223372036854775806, 2147483647 => 10'::bigistore; 59 | -- bigistore operators bigistore existence should check presence of a key; 60 | SELECT '-2147483647 => 10, -10 => -9223372036854775807, 0 => 5, 10 => 9223372036854775806, 2147483647 => 10'::bigistore ? 10; 61 | SELECT '-2147483647 => 10, -10 => -9223372036854775807, 0 => 5, 10 => 9223372036854775806, 2147483647 => 10'::bigistore ? 25; 62 | -- bigistore operators bigistore existence should check presence of any key; 63 | SELECT '-2147483647 => 10, -10 => -9223372036854775807, 0 => 5, 10 => 9223372036854775806, 2147483647 => 10'::bigistore ?| Array[10,0]; 64 | SELECT '-2147483647 => 10, -10 => -9223372036854775807, 0 => 5, 10 => 9223372036854775806, 2147483647 => 10'::bigistore ?| Array[27,25]; 65 | -- bigistore operators bigistore existence should check presence of all key; 66 | SELECT '-2147483647 => 10, -10 => -9223372036854775807, 0 => 5, 10 => 9223372036854775806, 2147483647 => 10'::bigistore ?& Array[10,0]; 67 | SELECT '-2147483647 => 10, -10 => -9223372036854775807, 0 => 5, 10 => 9223372036854775806, 2147483647 => 10'::bigistore ?& Array[27,25]; 68 | -- istore operators istore should fetch values; 69 | SELECT '1=>1, -1=>0'::istore -> -1; 70 | SELECT '1=>1, -1=>3'::istore -> -1; 71 | SELECT '-2147483647 => 10, -10 => -2147483647, 0 => 5, 10 => 2147483647, 2147483647 => 10'::istore -> 10; 72 | SELECT '-2147483647 => 10, -10 => -2147483647, 0 => 5, 10 => 2147483647, 2147483647 => 10'::istore -> Array[10,0]; 73 | -- istore operators istore should check existense of a key; 74 | SELECT '1=>1, -1=>3'::istore ? -1; 75 | SELECT '1=>1, -1=>3'::istore ? 5; 76 | -- istore operators istore should add two istore; 77 | SELECT '1=>1, -1=>3'::istore + '1=>1'::istore; 78 | SELECT '1=>1, -1=>3'::istore + '-1=>-1'::istore; 79 | SELECT '1=>1, -1=>3'::istore + '1=>-1'::istore; 80 | SELECT '1=>0, -1=>3'::istore + '1=>-1'::istore; 81 | SELECT '1=>1, -1=>0'::istore + '-1=>-1'::istore; 82 | -- istore operators istore should add an integer to #{type}; 83 | SELECT '1=>1, -1=>3'::istore + 1; 84 | SELECT '-1=>1, 1=>3'::istore + 1; 85 | SELECT '-1=>1, -1=>3'::istore + 1; 86 | SELECT '1=>1, -1=>3'::istore + 0; 87 | SELECT '-1=>1, 1=>3'::istore + 0; 88 | SELECT '-1=>1, -1=>3'::istore + 0; 89 | SELECT '1=>1, -1=>3'::istore + -1; 90 | SELECT '-1=>1, 1=>3'::istore + -1; 91 | SELECT '-1=>1, -1=>3'::istore + -1; 92 | -- istore operators istore should substract two istore; 93 | SELECT '1=>1, -1=>3'::istore - '1=>1'::istore; 94 | SELECT '1=>1, -1=>3'::istore - '-1=>-1'::istore; 95 | SELECT '1=>1, -1=>3'::istore - '1=>-1'::istore; 96 | SELECT '1=>0, -1=>3'::istore - '1=>-1'::istore; 97 | -- istore operators istore should substract integer from istore; 98 | SELECT '1=>1, -1=>3'::istore - 1; 99 | SELECT '-1=>1, 1=>3'::istore - 1; 100 | SELECT '-1=>1, -1=>3'::istore - 1; 101 | SELECT '1=>1, -1=>3'::istore - 0; 102 | SELECT '-1=>1, 1=>3'::istore - 0; 103 | SELECT '-1=>1, -1=>3'::istore - 0; 104 | SELECT '1=>1, -1=>3'::istore - -1; 105 | SELECT '-1=>1, 1=>3'::istore - -1; 106 | SELECT '-1=>1, -1=>3'::istore - -1; 107 | -- istore operators istore should multiply two istore; 108 | SELECT '1=>3, 2=>2'::istore * '1=>2, 3=>5'::istore; 109 | SELECT '-1=>3, 2=>2'::istore * '-1=>2, 3=>5'::istore; 110 | SELECT '-1=>3, 2=>2'::istore * '-1=>-2, 3=>5'::istore; 111 | SELECT '-1=>3, 2=>0'::istore * '-1=>-2, 3=>5'::istore; 112 | -- istore operators istore should multiply #{type} with integer; 113 | SELECT '1=>1, -1=>3'::istore * 1; 114 | SELECT '-1=>1, 1=>3'::istore * 1; 115 | SELECT '-1=>1, -1=>3'::istore * 1; 116 | SELECT '1=>1, -1=>3'::istore * 0; 117 | SELECT '-1=>1, 1=>3'::istore * 0; 118 | SELECT '-1=>1, -1=>3'::istore * 0; 119 | SELECT '1=>1, -1=>3'::istore * -1; 120 | SELECT '-1=>1, 1=>3'::istore * -1; 121 | SELECT '-1=>1, -1=>3'::istore * -1; 122 | -- istore operators istore should return convert to array; 123 | SELECT %%'-2147483647 => 10, -10 => -2147483647, 0 => 5, 10 => 2147483647, 2147483647 => 10'::istore; 124 | SELECT %#'-2147483647 => 10, -10 => -2147483647, 0 => 5, 10 => 2147483647, 2147483647 => 10'::istore; 125 | -- istore operators istore existence should check presence of a key; 126 | SELECT '-2147483647 => 10, -10 => -2147483647, 0 => 5, 10 => 2147483647, 2147483647 => 10'::istore ? 10; 127 | SELECT '-2147483647 => 10, -10 => -2147483647, 0 => 5, 10 => 2147483647, 2147483647 => 10'::istore ? 25; 128 | -- istore operators istore existence should check presence of any key; 129 | SELECT '-2147483647 => 10, -10 => -2147483647, 0 => 5, 10 => 2147483647, 2147483647 => 10'::istore ?| Array[10,0]; 130 | SELECT '-2147483647 => 10, -10 => -2147483647, 0 => 5, 10 => 2147483647, 2147483647 => 10'::istore ?| Array[27,25]; 131 | -- istore operators istore existence should check presence of all key; 132 | SELECT '-2147483647 => 10, -10 => -2147483647, 0 => 5, 10 => 2147483647, 2147483647 => 10'::istore ?& Array[10,0]; 133 | SELECT '-2147483647 => 10, -10 => -2147483647, 0 => 5, 10 => 2147483647, 2147483647 => 10'::istore ?& Array[27,25]; 134 | -------------------------------------------------------------------------------- /test/sql/parallel_test.sql: -------------------------------------------------------------------------------- 1 | SET max_parallel_workers_per_gather = 8; 2 | DO $$ 3 | BEGIN 4 | IF current_setting('server_version_num')::int >= 160000 THEN 5 | EXECUTE 'SET debug_parallel_query = on'; 6 | ELSE 7 | EXECUTE 'SET force_parallel_mode = on'; 8 | END IF; 9 | END $$; 10 | 11 | CREATE TABLE data AS 12 | SELECT id, isagg(k, id+dup+k) as data 13 | FROM generate_series(1000,10000, 100) id, generate_series(1,10) k, generate_series(1,1000) dup 14 | GROUP BY id, dup ORDER BY id; 15 | ALTER TABLE data set (parallel_workers=8); 16 | 17 | SELECT SUM(NULL::istore) FROM data; 18 | 19 | SELECT SUM(data) FROM data; 20 | EXPLAIN(COSTS OFF) SELECT SUM(data) FROM data; 21 | 22 | SELECT id, SUM(data) FROM data GROUP BY id ORDER BY id LIMIT 10; 23 | EXPLAIN(COSTS OFF) SELECT id, SUM(data) FROM data GROUP BY id ORDER BY id; 24 | 25 | SELECT MIN(data) FROM data; 26 | EXPLAIN(COSTS OFF) SELECT MIN(data) FROM data; 27 | 28 | SELECT id, MIN(data) FROM data GROUP BY id ORDER BY id LIMIT 10; 29 | EXPLAIN(COSTS OFF) SELECT id, MIN(data) FROM data GROUP BY id ORDER BY id; 30 | 31 | SELECT MAX(data) FROM data; 32 | EXPLAIN(COSTS OFF) SELECT MAX(data) FROM data; 33 | 34 | SELECT id, MAX(data) FROM data GROUP BY id ORDER BY id LIMIT 10; 35 | EXPLAIN(COSTS OFF) SELECT id, MAX(data) FROM data GROUP BY id ORDER BY id; 36 | 37 | 38 | CREATE TABLE bigdata AS 39 | SELECT id, isagg(k, (id+dup+k)::bigint) as data 40 | FROM generate_series(1000,10000, 100) id, generate_series(1,10) k, generate_series(1,1000) dup 41 | GROUP BY id, dup ORDER BY id; 42 | ALTER TABLE bigdata set (parallel_workers=8); 43 | 44 | SELECT SUM(data) FROM bigdata; 45 | EXPLAIN(COSTS OFF) SELECT SUM(data) FROM bigdata; 46 | 47 | SELECT id, SUM(data) FROM bigdata GROUP BY id ORDER BY id LIMIT 10; 48 | EXPLAIN(COSTS OFF) SELECT id, SUM(data) FROM bigdata GROUP BY id ORDER BY id; 49 | 50 | SELECT MIN(data) FROM bigdata; 51 | EXPLAIN(COSTS OFF) SELECT MIN(data) FROM bigdata; 52 | 53 | SELECT id, MIN(data) FROM bigdata GROUP BY id ORDER BY id LIMIT 10; 54 | EXPLAIN(COSTS OFF) SELECT id, MIN(data) FROM bigdata GROUP BY id ORDER BY id; 55 | 56 | SELECT MAX(data) FROM bigdata; 57 | EXPLAIN(COSTS OFF) SELECT MAX(data) FROM bigdata; 58 | 59 | SELECT id, MAX(data) FROM bigdata GROUP BY id ORDER BY id LIMIT 10; 60 | EXPLAIN(COSTS OFF) SELECT id, MAX(data) FROM bigdata GROUP BY id ORDER BY id; 61 | 62 | 63 | -- sanity checks 64 | 65 | SELECT SUM(data->5) FROM data; 66 | SELECT id, SUM(data->5) FROM data GROUP BY id ORDER BY id LIMIT 10; 67 | SELECT MIN(data->5) FROM data; 68 | SELECT id, MIN(data->5) FROM data GROUP BY id ORDER BY id LIMIT 10; 69 | SELECT MAX(data->5) FROM data; 70 | SELECT id, MAX(data->5) FROM data GROUP BY id ORDER BY id LIMIT 10; 71 | 72 | SELECT SUM(data->5) FROM bigdata; 73 | SELECT id, SUM(data->5) FROM bigdata GROUP BY id ORDER BY id LIMIT 10; 74 | SELECT MIN(data->5) FROM bigdata; 75 | SELECT id, MIN(data->5) FROM bigdata GROUP BY id ORDER BY id LIMIT 10; 76 | SELECT MAX(data->5) FROM bigdata; 77 | SELECT id, MAX(data->5) FROM bigdata GROUP BY id ORDER BY id LIMIT 10; 78 | --------------------------------------------------------------------------------