1 CREATE TABLE brintest_multi (
8 float8col double precision,
14 timecol time without time zone,
15 timestampcol timestamp without time zone,
16 timestamptzcol timestamp with time zone,
18 timetzcol time with time zone,
22 ) WITH (fillfactor=10);
23 INSERT INTO brintest_multi SELECT
28 format('(%s,%s)', tenthous, twenty)::tid,
29 (four + 1.0)/(hundred+1),
30 odd::float8 / (tenthous + 1),
31 format('%s:00:%s:00:%s:00', to_hex(odd), to_hex(even), to_hex(hundred))::macaddr,
32 substr(fipshash(unique1::text), 1, 16)::macaddr8,
33 inet '10.2.3.4/24' + tenthous,
34 cidr '10.2.3/24' + tenthous,
35 date '1995-08-15' + tenthous,
36 time '01:20:30' + thousand * interval '18.5 second',
37 timestamp '1942-07-23 03:05:09' + tenthous * interval '36.38 hours',
38 timestamptz '1972-10-10 03:00' + thousand * interval '1 hour',
39 justify_days(justify_hours(tenthous * interval '12 minutes')),
40 timetz '01:30:20+02' + hundred * interval '15 seconds',
41 tenthous::numeric(36,30) * fivethous * even / (hundred + 1),
42 format('%s%s-%s-%s-%s-%s%s%s', to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'))::uuid,
43 format('%s/%s%s', odd, even, tenthous)::pg_lsn
44 FROM tenk1 ORDER BY unique2 LIMIT 100;
45 -- throw in some NULL's and different values
46 INSERT INTO brintest_multi (inetcol, cidrcol) SELECT
47 inet 'fe80::6e40:8ff:fea9:8c46' + tenthous,
48 cidr 'fe80::6e40:8ff:fea9:8c46' + tenthous
49 FROM tenk1 ORDER BY thousand, tenthous LIMIT 25;
50 -- test minmax-multi specific index options
51 -- number of values must be >= 16
52 CREATE INDEX brinidx_multi ON brintest_multi USING brin (
53 int8col int8_minmax_multi_ops(values_per_range = 7)
55 ERROR: value 7 out of bounds for option "values_per_range"
56 DETAIL: Valid values are between "8" and "256".
57 -- number of values must be <= 256
58 CREATE INDEX brinidx_multi ON brintest_multi USING brin (
59 int8col int8_minmax_multi_ops(values_per_range = 257)
61 ERROR: value 257 out of bounds for option "values_per_range"
62 DETAIL: Valid values are between "8" and "256".
63 -- first create an index with a single page range, to force compaction
64 -- due to exceeding the number of values per summary
65 CREATE INDEX brinidx_multi ON brintest_multi USING brin (
66 int8col int8_minmax_multi_ops,
67 int2col int2_minmax_multi_ops,
68 int4col int4_minmax_multi_ops,
69 oidcol oid_minmax_multi_ops,
70 tidcol tid_minmax_multi_ops,
71 float4col float4_minmax_multi_ops,
72 float8col float8_minmax_multi_ops,
73 macaddrcol macaddr_minmax_multi_ops,
74 macaddr8col macaddr8_minmax_multi_ops,
75 inetcol inet_minmax_multi_ops,
76 cidrcol inet_minmax_multi_ops,
77 datecol date_minmax_multi_ops,
78 timecol time_minmax_multi_ops,
79 timestampcol timestamp_minmax_multi_ops,
80 timestamptzcol timestamptz_minmax_multi_ops,
81 intervalcol interval_minmax_multi_ops,
82 timetzcol timetz_minmax_multi_ops,
83 numericcol numeric_minmax_multi_ops,
84 uuidcol uuid_minmax_multi_ops,
85 lsncol pg_lsn_minmax_multi_ops
87 DROP INDEX brinidx_multi;
88 CREATE INDEX brinidx_multi ON brintest_multi USING brin (
89 int8col int8_minmax_multi_ops,
90 int2col int2_minmax_multi_ops,
91 int4col int4_minmax_multi_ops,
92 oidcol oid_minmax_multi_ops,
93 tidcol tid_minmax_multi_ops,
94 float4col float4_minmax_multi_ops,
95 float8col float8_minmax_multi_ops,
96 macaddrcol macaddr_minmax_multi_ops,
97 macaddr8col macaddr8_minmax_multi_ops,
98 inetcol inet_minmax_multi_ops,
99 cidrcol inet_minmax_multi_ops,
100 datecol date_minmax_multi_ops,
101 timecol time_minmax_multi_ops,
102 timestampcol timestamp_minmax_multi_ops,
103 timestamptzcol timestamptz_minmax_multi_ops,
104 intervalcol interval_minmax_multi_ops,
105 timetzcol timetz_minmax_multi_ops,
106 numericcol numeric_minmax_multi_ops,
107 uuidcol uuid_minmax_multi_ops,
108 lsncol pg_lsn_minmax_multi_ops
109 ) with (pages_per_range = 1);
110 CREATE TABLE brinopers_multi (colname name, typ text,
111 op text[], value text[], matches int[],
112 check (cardinality(op) = cardinality(value)),
113 check (cardinality(op) = cardinality(matches)));
114 INSERT INTO brinopers_multi VALUES
117 '{0, 0, 800, 999, 999}',
118 '{100, 100, 1, 100, 100}'),
121 '{0, 0, 800, 999, 1999}',
122 '{100, 100, 1, 100, 100}'),
125 '{0, 0, 800, 999, 1428427143}',
126 '{100, 100, 1, 100, 100}'),
129 '{0, 0, 800, 1999, 1999}',
130 '{100, 100, 1, 100, 100}'),
133 '{0, 0, 800, 1999, 1999}',
134 '{100, 100, 1, 100, 100}'),
137 '{0, 0, 800, 1999, 1428427143}',
138 '{100, 100, 1, 100, 100}'),
149 '{0, 0, 1257141600, 1428427143, 1428427143}',
150 '{100, 100, 1, 100, 100}'),
153 '{0, 0, 8800, 9999, 9999}',
154 '{100, 100, 1, 100, 100}'),
157 '{"(0,0)", "(0,0)", "(8800,0)", "(9999,19)", "(9999,19)"}',
158 '{100, 100, 1, 100, 100}'),
159 ('float4col', 'float4',
161 '{0.0103093, 0.0103093, 1, 1, 1}',
162 '{100, 100, 4, 100, 96}'),
163 ('float4col', 'float8',
165 '{0.0103093, 0.0103093, 1, 1, 1}',
166 '{100, 100, 4, 100, 96}'),
167 ('float8col', 'float4',
169 '{0, 0, 0, 1.98, 1.98}',
170 '{99, 100, 1, 100, 100}'),
171 ('float8col', 'float8',
173 '{0, 0, 0, 1.98, 1.98}',
174 '{99, 100, 1, 100, 100}'),
175 ('macaddrcol', 'macaddr',
177 '{00:00:01:00:00:00, 00:00:01:00:00:00, 2c:00:2d:00:16:00, ff:fe:00:00:00:00, ff:fe:00:00:00:00}',
178 '{99, 100, 2, 100, 100}'),
179 ('macaddr8col', 'macaddr8',
181 '{b1:d1:0e:7b:af:a4:42:12, d9:35:91:bd:f7:86:0e:1e, 72:8f:20:6c:2a:01:bf:57, 23:e8:46:63:86:07:ad:cb, 13:16:8e:6a:2e:6c:84:b4}',
182 '{31, 17, 1, 11, 4}'),
185 '{10.2.14.231/24, 255.255.255.255, 255.255.255.255, 0.0.0.0, 0.0.0.0}',
186 '{1, 100, 100, 125, 125}'),
189 '{255.255.255.255, 255.255.255.255, 0.0.0.0, 0.0.0.0}',
190 '{100, 100, 125, 125}'),
193 '{10.2.14/24, 255.255.255.255, 255.255.255.255, 0.0.0.0, 0.0.0.0}',
194 '{2, 100, 100, 125, 125}'),
197 '{10.2.14/24, 255.255.255.255, 255.255.255.255, 0.0.0.0, 0.0.0.0}',
198 '{2, 100, 100, 125, 125}'),
201 '{1995-08-15, 1995-08-15, 2009-12-01, 2022-12-30, 2022-12-30}',
202 '{100, 100, 1, 100, 100}'),
205 '{01:20:30, 01:20:30, 02:28:57, 06:28:31.5, 06:28:31.5}',
206 '{100, 100, 1, 100, 100}'),
207 ('timestampcol', 'timestamp',
209 '{1942-07-23 03:05:09, 1942-07-23 03:05:09, 1964-03-24 19:26:45, 1984-01-20 22:42:21, 1984-01-20 22:42:21}',
210 '{100, 100, 1, 100, 100}'),
211 ('timestampcol', 'timestamptz',
213 '{1942-07-23 03:05:09, 1942-07-23 03:05:09, 1964-03-24 19:26:45, 1984-01-20 22:42:21, 1984-01-20 22:42:21}',
214 '{100, 100, 1, 100, 100}'),
215 ('timestamptzcol', 'timestamptz',
217 '{1972-10-10 03:00:00-04, 1972-10-10 03:00:00-04, 1972-10-19 09:00:00-07, 1972-11-20 19:00:00-03, 1972-11-20 19:00:00-03}',
218 '{100, 100, 1, 100, 100}'),
219 ('intervalcol', 'interval',
221 '{00:00:00, 00:00:00, 1 mons 13 days 12:24, 2 mons 23 days 07:48:00, 1 year}',
222 '{100, 100, 1, 100, 100}'),
223 ('timetzcol', 'timetz',
225 '{01:30:20+02, 01:30:20+02, 01:35:50+02, 23:55:05+02, 23:55:05+02}',
226 '{99, 100, 2, 100, 100}'),
227 ('numericcol', 'numeric',
229 '{0.00, 0.01, 2268164.347826086956521739130434782609, 99470151.9, 99470151.9}',
230 '{100, 100, 1, 100, 100}'),
233 '{00040004-0004-0004-0004-000400040004, 00040004-0004-0004-0004-000400040004, 52225222-5222-5222-5222-522252225222, 99989998-9998-9998-9998-999899989998, 99989998-9998-9998-9998-999899989998}',
234 '{100, 100, 1, 100, 100}'),
236 '{>, >=, =, <=, <, IS, IS NOT}',
237 '{0/1200, 0/1200, 44/455222, 198/1999799, 198/1999799, NULL, NULL}',
238 '{100, 100, 1, 100, 100, 25, 100}');
250 FOR r IN SELECT colname, oper, typ, value[ordinality], matches[ordinality] FROM brinopers_multi, unnest(op) WITH ORDINALITY AS oper LOOP
252 -- prepare the condition
253 IF r.value IS NULL THEN
254 cond := format('%I %s %L', r.colname, r.oper, r.value);
256 cond := format('%I %s %L::%s', r.colname, r.oper, r.value, r.typ);
259 -- run the query using the brin index
260 SET enable_seqscan = 0;
261 SET enable_bitmapscan = 1;
264 FOR plan_line IN EXECUTE format($y$EXPLAIN SELECT array_agg(ctid) FROM brintest_multi WHERE %s $y$, cond) LOOP
265 IF plan_line LIKE '%Bitmap Heap Scan on brintest_multi%' THEN
270 RAISE WARNING 'did not get bitmap indexscan plan for %', r;
273 EXECUTE format($y$SELECT array_agg(ctid) FROM brintest_multi WHERE %s $y$, cond)
276 -- run the query using a seqscan
277 SET enable_seqscan = 1;
278 SET enable_bitmapscan = 0;
281 FOR plan_line IN EXECUTE format($y$EXPLAIN SELECT array_agg(ctid) FROM brintest_multi WHERE %s $y$, cond) LOOP
282 IF plan_line LIKE '%Seq Scan on brintest_multi%' THEN
287 RAISE WARNING 'did not get seqscan plan for %', r;
290 EXECUTE format($y$SELECT array_agg(ctid) FROM brintest_multi WHERE %s $y$, cond)
293 -- make sure both return the same results
294 count := array_length(idx_ctids, 1);
296 IF NOT (count = array_length(ss_ctids, 1) AND
297 idx_ctids @> ss_ctids AND
298 idx_ctids <@ ss_ctids) THEN
299 -- report the results of each scan to make the differences obvious
300 RAISE WARNING 'something not right in %: count %', r, count;
301 SET enable_seqscan = 1;
302 SET enable_bitmapscan = 0;
303 FOR r2 IN EXECUTE 'SELECT ' || r.colname || ' FROM brintest_multi WHERE ' || cond LOOP
304 RAISE NOTICE 'seqscan: %', r2;
307 SET enable_seqscan = 0;
308 SET enable_bitmapscan = 1;
309 FOR r2 IN EXECUTE 'SELECT ' || r.colname || ' FROM brintest_multi WHERE ' || cond LOOP
310 RAISE NOTICE 'bitmapscan: %', r2;
314 -- make sure we found expected number of matches
315 IF count != r.matches THEN RAISE WARNING 'unexpected number of results % for %', count, r; END IF;
319 RESET enable_seqscan;
320 RESET enable_bitmapscan;
321 INSERT INTO brintest_multi SELECT
326 format('(%s,%s)', tenthous, twenty)::tid,
327 (four + 1.0)/(hundred+1),
328 odd::float8 / (tenthous + 1),
329 format('%s:00:%s:00:%s:00', to_hex(odd), to_hex(even), to_hex(hundred))::macaddr,
330 substr(fipshash(unique1::text), 1, 16)::macaddr8,
331 inet '10.2.3.4' + tenthous,
332 cidr '10.2.3/24' + tenthous,
333 date '1995-08-15' + tenthous,
334 time '01:20:30' + thousand * interval '18.5 second',
335 timestamp '1942-07-23 03:05:09' + tenthous * interval '36.38 hours',
336 timestamptz '1972-10-10 03:00' + thousand * interval '1 hour',
337 justify_days(justify_hours(tenthous * interval '12 minutes')),
338 timetz '01:30:20' + hundred * interval '15 seconds',
339 tenthous::numeric(36,30) * fivethous * even / (hundred + 1),
340 format('%s%s-%s-%s-%s-%s%s%s', to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'), to_char(tenthous, 'FM0000'))::uuid,
341 format('%s/%s%s', odd, even, tenthous)::pg_lsn
342 FROM tenk1 ORDER BY unique2 LIMIT 5 OFFSET 5;
343 SELECT brin_desummarize_range('brinidx_multi', 0);
344 brin_desummarize_range
345 ------------------------
349 VACUUM brintest_multi; -- force a summarization cycle in brinidx
350 -- Try inserting a values with NaN, to test distance calculation.
351 insert into public.brintest_multi (float4col) values (real 'nan');
352 insert into public.brintest_multi (float8col) values (real 'nan');
353 UPDATE brintest_multi SET int8col = int8col * int4col;
354 -- Test handling of inet netmasks with inet_minmax_multi_ops
355 CREATE TABLE brin_test_inet (a inet);
356 CREATE INDEX ON brin_test_inet USING brin (a inet_minmax_multi_ops);
357 INSERT INTO brin_test_inet VALUES ('127.0.0.1/0');
358 INSERT INTO brin_test_inet VALUES ('0.0.0.0/12');
359 DROP TABLE brin_test_inet;
360 -- Tests for brin_summarize_new_values
361 SELECT brin_summarize_new_values('brintest_multi'); -- error, not an index
362 ERROR: "brintest_multi" is not an index
363 SELECT brin_summarize_new_values('tenk1_unique1'); -- error, not a BRIN index
364 ERROR: "tenk1_unique1" is not a BRIN index
365 SELECT brin_summarize_new_values('brinidx_multi'); -- ok, no change expected
366 brin_summarize_new_values
367 ---------------------------
371 -- Tests for brin_desummarize_range
372 SELECT brin_desummarize_range('brinidx_multi', -1); -- error, invalid range
373 ERROR: block number out of range: -1
374 SELECT brin_desummarize_range('brinidx_multi', 0);
375 brin_desummarize_range
376 ------------------------
380 SELECT brin_desummarize_range('brinidx_multi', 0);
381 brin_desummarize_range
382 ------------------------
386 SELECT brin_desummarize_range('brinidx_multi', 100000000);
387 brin_desummarize_range
388 ------------------------
392 -- test building an index with many values, to force compaction of the buffer
393 CREATE TABLE brin_large_range (a int4);
394 INSERT INTO brin_large_range SELECT i FROM generate_series(1,10000) s(i);
395 CREATE INDEX brin_large_range_idx ON brin_large_range USING brin (a int4_minmax_multi_ops);
396 DROP TABLE brin_large_range;
397 -- Test brin_summarize_range
398 CREATE TABLE brin_summarize_multi (
400 ) WITH (fillfactor=10, autovacuum_enabled=false);
401 CREATE INDEX brin_summarize_multi_idx ON brin_summarize_multi USING brin (value) WITH (pages_per_range=2);
407 INSERT INTO brin_summarize_multi VALUES (1) RETURNING ctid INTO curtid;
408 EXIT WHEN curtid > tid '(2, 0)';
412 -- summarize one range
413 SELECT brin_summarize_range('brin_summarize_multi_idx', 0);
415 ----------------------
419 -- nothing: already summarized
420 SELECT brin_summarize_range('brin_summarize_multi_idx', 1);
422 ----------------------
426 -- summarize one range
427 SELECT brin_summarize_range('brin_summarize_multi_idx', 2);
429 ----------------------
433 -- nothing: page doesn't exist in table
434 SELECT brin_summarize_range('brin_summarize_multi_idx', 4294967295);
436 ----------------------
440 -- invalid block number values
441 SELECT brin_summarize_range('brin_summarize_multi_idx', -1);
442 ERROR: block number out of range: -1
443 SELECT brin_summarize_range('brin_summarize_multi_idx', 4294967296);
444 ERROR: block number out of range: 4294967296
445 -- test brin cost estimates behave sanely based on correlation of values
446 CREATE TABLE brin_test_multi (a INT, b INT);
447 INSERT INTO brin_test_multi SELECT x/100,x%100 FROM generate_series(1,10000) x(x);
448 CREATE INDEX brin_test_multi_a_idx ON brin_test_multi USING brin (a) WITH (pages_per_range = 2);
449 CREATE INDEX brin_test_multi_b_idx ON brin_test_multi USING brin (b) WITH (pages_per_range = 2);
450 VACUUM ANALYZE brin_test_multi;
451 -- Ensure brin index is used when columns are perfectly correlated
452 EXPLAIN (COSTS OFF) SELECT * FROM brin_test_multi WHERE a = 1;
454 --------------------------------------------------
455 Bitmap Heap Scan on brin_test_multi
456 Recheck Cond: (a = 1)
457 -> Bitmap Index Scan on brin_test_multi_a_idx
461 -- Ensure brin index is not used when values are not correlated
462 EXPLAIN (COSTS OFF) SELECT * FROM brin_test_multi WHERE b = 1;
464 -----------------------------
465 Seq Scan on brin_test_multi
469 -- do some inequality tests
470 CREATE TABLE brin_test_multi_1 (a INT, b BIGINT) WITH (fillfactor=10);
471 INSERT INTO brin_test_multi_1
472 SELECT i/5 + mod(911 * i + 483, 25),
473 i/10 + mod(751 * i + 221, 41)
474 FROM generate_series(1,1000) s(i);
475 CREATE INDEX brin_test_multi_1_idx_1 ON brin_test_multi_1 USING brin (a int4_minmax_multi_ops) WITH (pages_per_range=5);
476 CREATE INDEX brin_test_multi_1_idx_2 ON brin_test_multi_1 USING brin (b int8_minmax_multi_ops) WITH (pages_per_range=5);
477 SET enable_seqscan=off;
479 SELECT COUNT(*) FROM brin_test_multi_1 WHERE a < 37;
485 SELECT COUNT(*) FROM brin_test_multi_1 WHERE a < 113;
491 SELECT COUNT(*) FROM brin_test_multi_1 WHERE a <= 177;
497 SELECT COUNT(*) FROM brin_test_multi_1 WHERE a <= 25;
504 SELECT COUNT(*) FROM brin_test_multi_1 WHERE a > 120;
510 SELECT COUNT(*) FROM brin_test_multi_1 WHERE a >= 180;
516 SELECT COUNT(*) FROM brin_test_multi_1 WHERE a > 71;
522 SELECT COUNT(*) FROM brin_test_multi_1 WHERE a >= 63;
529 SELECT COUNT(*) FROM brin_test_multi_1 WHERE a = 207;
535 SELECT COUNT(*) FROM brin_test_multi_1 WHERE a = 177;
542 SELECT COUNT(*) FROM brin_test_multi_1 WHERE b < 73;
548 SELECT COUNT(*) FROM brin_test_multi_1 WHERE b <= 47;
554 SELECT COUNT(*) FROM brin_test_multi_1 WHERE b < 199;
560 SELECT COUNT(*) FROM brin_test_multi_1 WHERE b <= 150;
566 -- bigint: greater than
567 SELECT COUNT(*) FROM brin_test_multi_1 WHERE b > 93;
573 SELECT COUNT(*) FROM brin_test_multi_1 WHERE b > 37;
579 SELECT COUNT(*) FROM brin_test_multi_1 WHERE b >= 215;
585 SELECT COUNT(*) FROM brin_test_multi_1 WHERE b > 201;
592 SELECT COUNT(*) FROM brin_test_multi_1 WHERE b = 88;
598 SELECT COUNT(*) FROM brin_test_multi_1 WHERE b = 103;
604 -- now do the same, but insert the rows with the indexes already created
605 -- so that we don't use the "build callback" and instead use the regular
606 -- approach of adding rows into existing ranges
607 TRUNCATE brin_test_multi_1;
608 INSERT INTO brin_test_multi_1
609 SELECT i/5 + mod(911 * i + 483, 25),
610 i/10 + mod(751 * i + 221, 41)
611 FROM generate_series(1,1000) s(i);
613 SELECT COUNT(*) FROM brin_test_multi_1 WHERE a < 37;
619 SELECT COUNT(*) FROM brin_test_multi_1 WHERE a < 113;
625 SELECT COUNT(*) FROM brin_test_multi_1 WHERE a <= 177;
631 SELECT COUNT(*) FROM brin_test_multi_1 WHERE a <= 25;
638 SELECT COUNT(*) FROM brin_test_multi_1 WHERE a > 120;
644 SELECT COUNT(*) FROM brin_test_multi_1 WHERE a >= 180;
650 SELECT COUNT(*) FROM brin_test_multi_1 WHERE a > 71;
656 SELECT COUNT(*) FROM brin_test_multi_1 WHERE a >= 63;
663 SELECT COUNT(*) FROM brin_test_multi_1 WHERE a = 207;
669 SELECT COUNT(*) FROM brin_test_multi_1 WHERE a = 177;
676 SELECT COUNT(*) FROM brin_test_multi_1 WHERE b < 73;
682 SELECT COUNT(*) FROM brin_test_multi_1 WHERE b <= 47;
688 SELECT COUNT(*) FROM brin_test_multi_1 WHERE b < 199;
694 SELECT COUNT(*) FROM brin_test_multi_1 WHERE b <= 150;
700 -- bigint: greater than
701 SELECT COUNT(*) FROM brin_test_multi_1 WHERE b > 93;
707 SELECT COUNT(*) FROM brin_test_multi_1 WHERE b > 37;
713 SELECT COUNT(*) FROM brin_test_multi_1 WHERE b >= 215;
719 SELECT COUNT(*) FROM brin_test_multi_1 WHERE b > 201;
726 SELECT COUNT(*) FROM brin_test_multi_1 WHERE b = 88;
732 SELECT COUNT(*) FROM brin_test_multi_1 WHERE b = 103;
738 DROP TABLE brin_test_multi_1;
739 RESET enable_seqscan;
740 -- do some inequality tests for varlena data types
741 CREATE TABLE brin_test_multi_2 (a UUID) WITH (fillfactor=10);
742 INSERT INTO brin_test_multi_2
743 SELECT v::uuid FROM (SELECT row_number() OVER (ORDER BY v) c, v FROM (SELECT fipshash((i/13)::text) AS v FROM generate_series(1,1000) s(i)) foo) bar ORDER BY c + 25 * random();
744 CREATE INDEX brin_test_multi_2_idx ON brin_test_multi_2 USING brin (a uuid_minmax_multi_ops) WITH (pages_per_range=5);
745 SET enable_seqscan=off;
746 SELECT COUNT(*) FROM brin_test_multi_2 WHERE a < '3d914f93-48c9-cc0f-f8a7-9716700b9fcd';
752 SELECT COUNT(*) FROM brin_test_multi_2 WHERE a > '3d914f93-48c9-cc0f-f8a7-9716700b9fcd';
758 SELECT COUNT(*) FROM brin_test_multi_2 WHERE a <= 'f369cb89-fc62-7e66-8987-007d121ed1ea';
764 SELECT COUNT(*) FROM brin_test_multi_2 WHERE a >= 'aea92132-c4cb-eb26-3e6a-c2bf6c183b5d';
770 SELECT COUNT(*) FROM brin_test_multi_2 WHERE a = '5feceb66-ffc8-6f38-d952-786c6d696c79';
776 SELECT COUNT(*) FROM brin_test_multi_2 WHERE a = '86e50149-6586-6131-2a9e-0b35558d84f6';
782 -- now do the same, but insert the rows with the indexes already created
783 -- so that we don't use the "build callback" and instead use the regular
784 -- approach of adding rows into existing ranges
785 TRUNCATE brin_test_multi_2;
786 INSERT INTO brin_test_multi_2
787 SELECT v::uuid FROM (SELECT row_number() OVER (ORDER BY v) c, v FROM (SELECT fipshash((i/13)::text) AS v FROM generate_series(1,1000) s(i)) foo) bar ORDER BY c + 25 * random();
788 SELECT COUNT(*) FROM brin_test_multi_2 WHERE a < '3d914f93-48c9-cc0f-f8a7-9716700b9fcd';
794 SELECT COUNT(*) FROM brin_test_multi_2 WHERE a > '3d914f93-48c9-cc0f-f8a7-9716700b9fcd';
800 SELECT COUNT(*) FROM brin_test_multi_2 WHERE a <= 'f369cb89-fc62-7e66-8987-007d121ed1ea';
806 SELECT COUNT(*) FROM brin_test_multi_2 WHERE a >= 'aea92132-c4cb-eb26-3e6a-c2bf6c183b5d';
812 SELECT COUNT(*) FROM brin_test_multi_2 WHERE a = '5feceb66-ffc8-6f38-d952-786c6d696c79';
818 SELECT COUNT(*) FROM brin_test_multi_2 WHERE a = '86e50149-6586-6131-2a9e-0b35558d84f6';
824 DROP TABLE brin_test_multi_2;
825 RESET enable_seqscan;
826 -- test overflows during CREATE INDEX with extreme timestamp values
827 CREATE TABLE brin_timestamp_test(a TIMESTAMPTZ);
828 SET datestyle TO iso;
829 -- values close to timestamp minimum
830 INSERT INTO brin_timestamp_test
831 SELECT '4713-01-01 00:00:01 BC'::timestamptz + (i || ' seconds')::interval
832 FROM generate_series(1,30) s(i);
833 -- values close to timestamp maximum
834 INSERT INTO brin_timestamp_test
835 SELECT '294276-12-01 00:00:01'::timestamptz + (i || ' seconds')::interval
836 FROM generate_series(1,30) s(i);
837 CREATE INDEX ON brin_timestamp_test USING brin (a timestamptz_minmax_multi_ops) WITH (pages_per_range=1);
838 DROP TABLE brin_timestamp_test;
839 -- test overflows during CREATE INDEX with extreme date values
840 CREATE TABLE brin_date_test(a DATE);
841 -- insert values close to date minimum
842 INSERT INTO brin_date_test SELECT '4713-01-01 BC'::date + i FROM generate_series(1, 30) s(i);
843 -- insert values close to date minimum
844 INSERT INTO brin_date_test SELECT '5874897-12-01'::date + i FROM generate_series(1, 30) s(i);
845 CREATE INDEX ON brin_date_test USING brin (a date_minmax_multi_ops) WITH (pages_per_range=1);
846 SET enable_seqscan = off;
847 -- make sure the ranges were built correctly and 2023-01-01 eliminates all
848 EXPLAIN (ANALYZE, TIMING OFF, COSTS OFF, SUMMARY OFF, BUFFERS OFF)
849 SELECT * FROM brin_date_test WHERE a = '2023-01-01'::date;
851 -------------------------------------------------------------------------
852 Bitmap Heap Scan on brin_date_test (actual rows=0 loops=1)
853 Recheck Cond: (a = '2023-01-01'::date)
854 -> Bitmap Index Scan on brin_date_test_a_idx (actual rows=0 loops=1)
855 Index Cond: (a = '2023-01-01'::date)
858 DROP TABLE brin_date_test;
859 RESET enable_seqscan;
860 -- test handling of infinite timestamp values
861 CREATE TABLE brin_timestamp_test(a TIMESTAMP);
862 INSERT INTO brin_timestamp_test VALUES ('-infinity'), ('infinity');
863 INSERT INTO brin_timestamp_test
864 SELECT i FROM generate_series('2000-01-01'::timestamp, '2000-02-09'::timestamp, '1 day'::interval) s(i);
865 CREATE INDEX ON brin_timestamp_test USING brin (a timestamp_minmax_multi_ops) WITH (pages_per_range=1);
866 SET enable_seqscan = off;
867 EXPLAIN (ANALYZE, TIMING OFF, COSTS OFF, SUMMARY OFF, BUFFERS OFF)
868 SELECT * FROM brin_timestamp_test WHERE a = '2023-01-01'::timestamp;
870 ------------------------------------------------------------------------------
871 Bitmap Heap Scan on brin_timestamp_test (actual rows=0 loops=1)
872 Recheck Cond: (a = '2023-01-01 00:00:00'::timestamp without time zone)
873 -> Bitmap Index Scan on brin_timestamp_test_a_idx (actual rows=0 loops=1)
874 Index Cond: (a = '2023-01-01 00:00:00'::timestamp without time zone)
877 EXPLAIN (ANALYZE, TIMING OFF, COSTS OFF, SUMMARY OFF, BUFFERS OFF)
878 SELECT * FROM brin_timestamp_test WHERE a = '1900-01-01'::timestamp;
880 ------------------------------------------------------------------------------
881 Bitmap Heap Scan on brin_timestamp_test (actual rows=0 loops=1)
882 Recheck Cond: (a = '1900-01-01 00:00:00'::timestamp without time zone)
883 -> Bitmap Index Scan on brin_timestamp_test_a_idx (actual rows=0 loops=1)
884 Index Cond: (a = '1900-01-01 00:00:00'::timestamp without time zone)
887 DROP TABLE brin_timestamp_test;
888 RESET enable_seqscan;
889 -- test handling of infinite date values
890 CREATE TABLE brin_date_test(a DATE);
891 INSERT INTO brin_date_test VALUES ('-infinity'), ('infinity');
892 INSERT INTO brin_date_test SELECT '2000-01-01'::date + i FROM generate_series(1, 40) s(i);
893 CREATE INDEX ON brin_date_test USING brin (a date_minmax_multi_ops) WITH (pages_per_range=1);
894 SET enable_seqscan = off;
895 EXPLAIN (ANALYZE, TIMING OFF, COSTS OFF, SUMMARY OFF, BUFFERS OFF)
896 SELECT * FROM brin_date_test WHERE a = '2023-01-01'::date;
898 -------------------------------------------------------------------------
899 Bitmap Heap Scan on brin_date_test (actual rows=0 loops=1)
900 Recheck Cond: (a = '2023-01-01'::date)
901 -> Bitmap Index Scan on brin_date_test_a_idx (actual rows=0 loops=1)
902 Index Cond: (a = '2023-01-01'::date)
905 EXPLAIN (ANALYZE, TIMING OFF, COSTS OFF, SUMMARY OFF, BUFFERS OFF)
906 SELECT * FROM brin_date_test WHERE a = '1900-01-01'::date;
908 -------------------------------------------------------------------------
909 Bitmap Heap Scan on brin_date_test (actual rows=0 loops=1)
910 Recheck Cond: (a = '1900-01-01'::date)
911 -> Bitmap Index Scan on brin_date_test_a_idx (actual rows=0 loops=1)
912 Index Cond: (a = '1900-01-01'::date)
915 DROP TABLE brin_date_test;
916 RESET enable_seqscan;
918 -- test handling of overflow for interval values
919 CREATE TABLE brin_interval_test(a INTERVAL);
920 INSERT INTO brin_interval_test SELECT (i || ' years')::interval FROM generate_series(-178000000, -177999980) s(i);
921 INSERT INTO brin_interval_test SELECT (i || ' years')::interval FROM generate_series( 177999980, 178000000) s(i);
922 CREATE INDEX ON brin_interval_test USING brin (a interval_minmax_multi_ops) WITH (pages_per_range=1);
923 SET enable_seqscan = off;
924 EXPLAIN (ANALYZE, TIMING OFF, COSTS OFF, SUMMARY OFF, BUFFERS OFF)
925 SELECT * FROM brin_interval_test WHERE a = '-30 years'::interval;
927 -----------------------------------------------------------------------------
928 Bitmap Heap Scan on brin_interval_test (actual rows=0 loops=1)
929 Recheck Cond: (a = '@ 30 years ago'::interval)
930 -> Bitmap Index Scan on brin_interval_test_a_idx (actual rows=0 loops=1)
931 Index Cond: (a = '@ 30 years ago'::interval)
934 EXPLAIN (ANALYZE, TIMING OFF, COSTS OFF, SUMMARY OFF, BUFFERS OFF)
935 SELECT * FROM brin_interval_test WHERE a = '30 years'::interval;
937 -----------------------------------------------------------------------------
938 Bitmap Heap Scan on brin_interval_test (actual rows=0 loops=1)
939 Recheck Cond: (a = '@ 30 years'::interval)
940 -> Bitmap Index Scan on brin_interval_test_a_idx (actual rows=0 loops=1)
941 Index Cond: (a = '@ 30 years'::interval)
944 DROP TABLE brin_interval_test;
945 RESET enable_seqscan;
946 -- test handling of infinite interval values
947 CREATE TABLE brin_interval_test(a INTERVAL);
948 INSERT INTO brin_interval_test VALUES ('-infinity'), ('infinity');
949 INSERT INTO brin_interval_test SELECT (i || ' days')::interval FROM generate_series(100, 140) s(i);
950 CREATE INDEX ON brin_interval_test USING brin (a interval_minmax_multi_ops) WITH (pages_per_range=1);
951 SET enable_seqscan = off;
952 EXPLAIN (ANALYZE, TIMING OFF, COSTS OFF, SUMMARY OFF, BUFFERS OFF)
953 SELECT * FROM brin_interval_test WHERE a = '-30 years'::interval;
955 -----------------------------------------------------------------------------
956 Bitmap Heap Scan on brin_interval_test (actual rows=0 loops=1)
957 Recheck Cond: (a = '@ 30 years ago'::interval)
958 -> Bitmap Index Scan on brin_interval_test_a_idx (actual rows=0 loops=1)
959 Index Cond: (a = '@ 30 years ago'::interval)
962 EXPLAIN (ANALYZE, TIMING OFF, COSTS OFF, SUMMARY OFF, BUFFERS OFF)
963 SELECT * FROM brin_interval_test WHERE a = '30 years'::interval;
965 -----------------------------------------------------------------------------
966 Bitmap Heap Scan on brin_interval_test (actual rows=0 loops=1)
967 Recheck Cond: (a = '@ 30 years'::interval)
968 -> Bitmap Index Scan on brin_interval_test_a_idx (actual rows=0 loops=1)
969 Index Cond: (a = '@ 30 years'::interval)
972 DROP TABLE brin_interval_test;
973 RESET enable_seqscan;