From 3074915222f2941ca7b5de2ccb48c8cda30f6cce Mon Sep 17 00:00:00 2001 From: Tomas Vondra Date: Fri, 3 Feb 2023 13:19:24 +0100 Subject: [PATCH 09/11] wip: add brinsort regression tests --- src/test/regress/expected/brin_sort.out | 543 ++++++++++++ src/test/regress/expected/brin_sort_exprs.out | 788 ++++++++++++++++++ src/test/regress/expected/brin_sort_multi.out | 545 ++++++++++++ .../expected/brin_sort_multi_exprs.out | 784 +++++++++++++++++ src/test/regress/parallel_schedule | 6 + src/test/regress/sql/brin_sort.sql | 238 ++++++ src/test/regress/sql/brin_sort_exprs.sql | 373 +++++++++ src/test/regress/sql/brin_sort_multi.sql | 235 ++++++ .../regress/sql/brin_sort_multi_exprs.sql | 369 ++++++++ 9 files changed, 3881 insertions(+) create mode 100644 src/test/regress/expected/brin_sort.out create mode 100644 src/test/regress/expected/brin_sort_exprs.out create mode 100644 src/test/regress/expected/brin_sort_multi.out create mode 100644 src/test/regress/expected/brin_sort_multi_exprs.out create mode 100644 src/test/regress/sql/brin_sort.sql create mode 100644 src/test/regress/sql/brin_sort_exprs.sql create mode 100644 src/test/regress/sql/brin_sort_multi.sql create mode 100644 src/test/regress/sql/brin_sort_multi_exprs.sql diff --git a/src/test/regress/expected/brin_sort.out b/src/test/regress/expected/brin_sort.out new file mode 100644 index 00000000000..0e207cf4f6f --- /dev/null +++ b/src/test/regress/expected/brin_sort.out @@ -0,0 +1,543 @@ +-- function to verify various sort-related data (total rows, ordering) +create or replace function brinsort_check_ordering(p_sql text, p_rows_expected int, p_desc boolean) returns void as $$ +declare + v_curs refcursor; + v_row record; + v_prev record; + v_brin_sort_found bool := false; + v_count int := 0; +begin + + -- needed because the p_sql query has different data types + execute 'discard plans'; + + OPEN v_curs NO SCROLL FOR EXECUTE format('explain %s', p_sql); + + LOOP + FETCH v_curs INTO v_row; + + IF NOT FOUND THEN + EXIT; + END IF; + + IF v_row::text LIKE '%BRIN Sort%' THEN + v_brin_sort_found := true; + EXIT; + END IF; + END LOOP; + + CLOSE v_curs; + + IF NOT v_brin_sort_found THEN + RAISE EXCEPTION 'BRIN Sort: not found'; + END IF; + + OPEN v_curs NO SCROLL FOR EXECUTE format(p_sql); + + LOOP + FETCH v_curs INTO v_row; + + IF NOT FOUND THEN + EXIT; + END IF; + + IF v_prev IS NOT NULL THEN + IF v_prev.val > v_row.val AND NOT p_desc THEN + RAISE EXCEPTION 'ordering mismatch % > % (asc)', v_prev.val, v_row.val; + END IF; + IF v_prev.val < v_row.val AND p_desc THEN + RAISE EXCEPTION 'ordering mismatch % < % (desc)', v_prev.val, v_row.val; + END IF; + END IF; + + v_prev := v_row; + v_count := v_count + 1; + END LOOP; + + CLOSE v_curs; + + IF v_count != p_rows_expected THEN + RAISE EXCEPTION 'count mismatch: % != %', v_count, p_rows_expected; + END IF; + +end; +$$ language plpgsql; +create table brin_sort_test (int_val int, bigint_val bigint, text_val text, inet_val inet) with (fillfactor=10); +-- sequential values +insert into brin_sort_test +select + i, + -i, -- same as int, but at least opposite + lpad(i::text || md5(i::text), 40, '0'), + '10.0.0.0'::inet + i +from generate_series(1,1000) s(i); +-- create brin indexes on individual columns +create index brin_sort_test_int_idx on brin_sort_test using brin (int_val) with (pages_per_range=1); +create index brin_sort_test_bigint_idx on brin_sort_test using brin (bigint_val) with (pages_per_range=1); +create index brin_sort_test_text_idx on brin_sort_test using brin (text_val) with (pages_per_range=1); +create index brin_sort_test_inet_idx on brin_sort_test using brin (inet_val inet_minmax_ops) with (pages_per_range=1); +-- +vacuum analyze brin_sort_test; +set enable_seqscan = off; +select brinsort_check_ordering('select int_val as val from brin_sort_test order by int_val', 1000, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select int_val as val from brin_sort_test order by int_val desc', 1000, true); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select int_val as val from brin_sort_test order by int_val limit 100', 100, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select int_val as val from brin_sort_test order by int_val desc limit 100', 100, true); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select int_val as val from brin_sort_test order by int_val limit 100 offset 100', 100, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select int_val as val from brin_sort_test order by int_val desc limit 100 offset 100', 100, true); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select bigint_val as val from brin_sort_test order by bigint_val', 1000, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select bigint_val as val from brin_sort_test order by bigint_val desc', 1000, true); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select bigint_val as val from brin_sort_test order by bigint_val limit 100', 100, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select bigint_val as val from brin_sort_test order by bigint_val desc limit 100', 100, true); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select bigint_val as val from brin_sort_test order by bigint_val limit 100 offset 100', 100, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select bigint_val as val from brin_sort_test order by bigint_val desc limit 100 offset 100', 100, true); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select inet_val as val from brin_sort_test order by inet_val', 1000, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select inet_val as val from brin_sort_test order by inet_val desc', 1000, true); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select inet_val as val from brin_sort_test order by inet_val limit 100', 100, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select inet_val as val from brin_sort_test order by inet_val desc limit 100', 100, true); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select inet_val as val from brin_sort_test order by inet_val limit 100 offset 100', 100, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select inet_val as val from brin_sort_test order by inet_val desc limit 100 offset 100', 100, true); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select text_val as val from brin_sort_test order by text_val', 1000, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select text_val as val from brin_sort_test order by text_val desc', 1000, true); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select text_val as val from brin_sort_test order by text_val limit 100', 100, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select text_val as val from brin_sort_test order by text_val desc limit 100', 100, true); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select text_val as val from brin_sort_test order by text_val limit 100 offset 100', 100, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select text_val as val from brin_sort_test order by text_val desc limit 100 offset 100', 100, true); + brinsort_check_ordering +------------------------- + +(1 row) + +-- semi-random data (sequential + randomness) +truncate table brin_sort_test; +insert into brin_sort_test +select + i + (100 * random())::int, + -(i + (100 * random())::int), -- same as int, but at least opposite + lpad((i + (100 * random())::int)::text || md5(i::text), 40, '0'), + '10.0.0.0'::inet + (i + 100 * random()::int) +from generate_series(1,1000) s(i); +reindex table brin_sort_test; +vacuum analyze brin_sort_test; +select brinsort_check_ordering('select int_val as val from brin_sort_test order by int_val', 1000, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select int_val as val from brin_sort_test order by int_val desc', 1000, true); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select int_val as val from brin_sort_test order by int_val limit 100', 100, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select int_val as val from brin_sort_test order by int_val desc limit 100', 100, true); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select int_val as val from brin_sort_test order by int_val limit 100 offset 100', 100, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select int_val as val from brin_sort_test order by int_val desc limit 100 offset 100', 100, true); + brinsort_check_ordering +------------------------- + +(1 row) + + +select brinsort_check_ordering('select bigint_val as val from brin_sort_test order by bigint_val', 1000, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select bigint_val as val from brin_sort_test order by bigint_val desc', 1000, true); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select bigint_val as val from brin_sort_test order by bigint_val limit 100', 100, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select bigint_val as val from brin_sort_test order by bigint_val desc limit 100', 100, true); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select bigint_val as val from brin_sort_test order by bigint_val limit 100 offset 100', 100, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select bigint_val as val from brin_sort_test order by bigint_val desc limit 100 offset 100', 100, true); + brinsort_check_ordering +------------------------- + +(1 row) + + +select brinsort_check_ordering('select inet_val as val from brin_sort_test order by inet_val', 1000, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select inet_val as val from brin_sort_test order by inet_val desc', 1000, true); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select inet_val as val from brin_sort_test order by inet_val limit 100', 100, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select inet_val as val from brin_sort_test order by inet_val desc limit 100', 100, true); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select inet_val as val from brin_sort_test order by inet_val limit 100 offset 100', 100, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select inet_val as val from brin_sort_test order by inet_val desc limit 100 offset 100', 100, true); + brinsort_check_ordering +------------------------- + +(1 row) + + +select brinsort_check_ordering('select text_val as val from brin_sort_test order by text_val', 1000, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select text_val as val from brin_sort_test order by text_val desc', 1000, true); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select text_val as val from brin_sort_test order by text_val limit 100', 100, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select text_val as val from brin_sort_test order by text_val desc limit 100', 100, true); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select text_val as val from brin_sort_test order by text_val limit 100 offset 100', 100, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select text_val as val from brin_sort_test order by text_val desc limit 100 offset 100', 100, true); + brinsort_check_ordering +------------------------- + +(1 row) + +-- random data +truncate table brin_sort_test; +insert into brin_sort_test +select + (1000 * random())::int, + -((1000 * random())::int), -- same as int, but at least opposite + lpad(((1000 * random())::int)::text || md5(i::text), 40, '0'), + '10.0.0.0'::inet + (1000 * random()::int) +from generate_series(1,1000) s(i); +reindex table brin_sort_test; +vacuum analyze brin_sort_test; + +select brinsort_check_ordering('select int_val as val from brin_sort_test order by int_val', 1000, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select int_val as val from brin_sort_test order by int_val desc', 1000, true); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select int_val as val from brin_sort_test order by int_val limit 100', 100, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select int_val as val from brin_sort_test order by int_val desc limit 100', 100, true); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select int_val as val from brin_sort_test order by int_val limit 100 offset 100', 100, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select int_val as val from brin_sort_test order by int_val desc limit 100 offset 100', 100, true); + brinsort_check_ordering +------------------------- + +(1 row) + + +select brinsort_check_ordering('select bigint_val as val from brin_sort_test order by bigint_val', 1000, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select bigint_val as val from brin_sort_test order by bigint_val desc', 1000, true); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select bigint_val as val from brin_sort_test order by bigint_val limit 100', 100, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select bigint_val as val from brin_sort_test order by bigint_val desc limit 100', 100, true); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select bigint_val as val from brin_sort_test order by bigint_val limit 100 offset 100', 100, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select bigint_val as val from brin_sort_test order by bigint_val desc limit 100 offset 100', 100, true); + brinsort_check_ordering +------------------------- + +(1 row) + + +select brinsort_check_ordering('select inet_val as val from brin_sort_test order by inet_val', 1000, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select inet_val as val from brin_sort_test order by inet_val desc', 1000, true); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select inet_val as val from brin_sort_test order by inet_val limit 100', 100, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select inet_val as val from brin_sort_test order by inet_val desc limit 100', 100, true); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select inet_val as val from brin_sort_test order by inet_val limit 100 offset 100', 100, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select inet_val as val from brin_sort_test order by inet_val desc limit 100 offset 100', 100, true); + brinsort_check_ordering +------------------------- + +(1 row) + + +select brinsort_check_ordering('select text_val as val from brin_sort_test order by text_val', 1000, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select text_val as val from brin_sort_test order by text_val desc', 1000, true); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select text_val as val from brin_sort_test order by text_val limit 100', 100, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select text_val as val from brin_sort_test order by text_val desc limit 100', 100, true); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select text_val as val from brin_sort_test order by text_val limit 100 offset 100', 100, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select text_val as val from brin_sort_test order by text_val desc limit 100 offset 100', 100, true); + brinsort_check_ordering +------------------------- + +(1 row) + +drop table brin_sort_test; diff --git a/src/test/regress/expected/brin_sort_exprs.out b/src/test/regress/expected/brin_sort_exprs.out new file mode 100644 index 00000000000..87e58a10883 --- /dev/null +++ b/src/test/regress/expected/brin_sort_exprs.out @@ -0,0 +1,788 @@ +-- function to verify various sort-related data (total rows, ordering) +create or replace function brinsort_check_ordering(p_sql text, p_rows_expected int, p_desc boolean) returns void as $$ +declare + v_curs refcursor; + v_row record; + v_prev record; + v_brin_sort_found bool := false; + v_count int := 0; +begin + + -- needed because the p_sql query has different data types + execute 'discard plans'; + + OPEN v_curs NO SCROLL FOR EXECUTE format('explain %s', p_sql); + + LOOP + FETCH v_curs INTO v_row; + + IF NOT FOUND THEN + EXIT; + END IF; + + IF v_row::text LIKE '%BRIN Sort%' THEN + v_brin_sort_found := true; + EXIT; + END IF; + END LOOP; + + CLOSE v_curs; + + IF NOT v_brin_sort_found THEN + RAISE EXCEPTION 'BRIN Sort: not found'; + END IF; + + OPEN v_curs NO SCROLL FOR EXECUTE format(p_sql); + + LOOP + FETCH v_curs INTO v_row; + + IF NOT FOUND THEN + EXIT; + END IF; + + IF v_prev IS NOT NULL THEN + IF v_prev.val > v_row.val AND NOT p_desc THEN + RAISE EXCEPTION 'ordering mismatch % > % (asc)', v_prev.val, v_row.val; + END IF; + IF v_prev.val < v_row.val AND p_desc THEN + RAISE EXCEPTION 'ordering mismatch % < % (desc)', v_prev.val, v_row.val; + END IF; + END IF; + + v_prev := v_row; + v_count := v_count + 1; + END LOOP; + + CLOSE v_curs; + + IF v_count != p_rows_expected THEN + RAISE EXCEPTION 'count mismatch: % != %', v_count, p_rows_expected; + END IF; + +end; +$$ language plpgsql; +create table brin_sort_test (int_val int, bigint_val bigint, text_val text, inet_val inet) with (fillfactor=10); +-- sequential values +insert into brin_sort_test +select + i, + -i, -- same as int, but at least opposite + lpad(i::text || md5(i::text), 40, '0'), + '10.0.0.0'::inet + i +from generate_series(1,1000) s(i); +-- create brin indexes on individual columns +create index brin_sort_test_int_idx on brin_sort_test using brin ((int_val + 1)) with (pages_per_range=1); +create index brin_sort_test_bigint_idx on brin_sort_test using brin ((bigint_val + 1)) with (pages_per_range=1); +create index brin_sort_test_text_idx on brin_sort_test using brin (('x' || text_val)) with (pages_per_range=1); +create index brin_sort_test_inet_idx on brin_sort_test using brin ((inet_val + 1) inet_minmax_ops) with (pages_per_range=1); +-- +vacuum analyze brin_sort_test; +set enable_seqscan = off; + +-- matching expression +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val + 1)', 1000, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val + 1) desc', 1000, true); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val + 1) limit 100', 100, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val + 1) desc limit 100', 100, true); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val + 1) limit 100 offset 100', 100, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val + 1) desc limit 100 offset 100', 100, true); + brinsort_check_ordering +------------------------- + +(1 row) + +-- mismatching expression +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val - 1)', 1000, false); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val - 1) desc', 1000, true); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val - 1) limit 100', 100, false); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val - 1) desc limit 100', 100, true); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val - 1) limit 100 offset 100', 100, false); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val - 1) desc limit 100 offset 100', 100, true); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE + +-- matching expression +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val + 1)', 1000, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val + 1) desc', 1000, true); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val + 1) limit 100', 100, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val + 1) desc limit 100', 100, true); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val + 1) limit 100 offset 100', 100, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val + 1) desc limit 100 offset 100', 100, true); + brinsort_check_ordering +------------------------- + +(1 row) + +-- mismatching expression +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val - 1)', 1000, false); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val - 1) desc', 1000, true); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val - 1) limit 100', 100, false); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val - 1) desc limit 100', 100, true); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val - 1) limit 100 offset 100', 100, false); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val - 1) desc limit 100 offset 100', 100, true); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE + +-- matching expression +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''x'' || text_val)', 1000, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''x'' || text_val) desc', 1000, true); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''x'' || text_val) limit 100', 100, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''x'' || text_val) desc limit 100', 100, true); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''x'' || text_val) limit 100 offset 100', 100, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''x'' || text_val) desc limit 100 offset 100', 100, true); + brinsort_check_ordering +------------------------- + +(1 row) + +-- mismatching expression +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''y'' || text_val)', 1000, false); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''y'' || text_val) desc', 1000, true); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''y'' || text_val) limit 100', 100, false); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''y'' || text_val) desc limit 100', 100, true); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''y'' || text_val) limit 100 offset 100', 100, false); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''y'' || text_val) desc limit 100 offset 100', 100, true); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE + +-- matching expression +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val + 1)', 1000, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val + 1) desc', 1000, true); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val + 1) limit 100', 100, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val + 1) desc limit 100', 100, true); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val + 1) limit 100 offset 100', 100, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val + 1) desc limit 100 offset 100', 100, true); + brinsort_check_ordering +------------------------- + +(1 row) + +-- mismatching expression +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val - 1)', 1000, false); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val - 1) desc', 1000, true); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val - 1) limit 100', 100, false); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val - 1) desc limit 100', 100, true); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val - 1) limit 100 offset 100', 100, false); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val - 1) desc limit 100 offset 100', 100, true); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +-- semi-random data (sequential + randomness) +truncate table brin_sort_test; +insert into brin_sort_test +select + i + (100 * random())::int, + -(i + (100 * random())::int), -- same as int, but at least opposite + lpad((i + (100 * random())::int)::text || md5(i::text), 40, '0'), + '10.0.0.0'::inet + (i + 100 * random()::int) +from generate_series(1,1000) s(i); +reindex table brin_sort_test; +vacuum analyze brin_sort_test; + +-- matching expression +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val + 1)', 1000, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val + 1) desc', 1000, true); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val + 1) limit 100', 100, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val + 1) desc limit 100', 100, true); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val + 1) limit 100 offset 100', 100, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val + 1) desc limit 100 offset 100', 100, true); + brinsort_check_ordering +------------------------- + +(1 row) + +-- mismatching expression +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val - 1)', 1000, false); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val - 1) desc', 1000, true); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val - 1) limit 100', 100, false); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val - 1) desc limit 100', 100, true); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val - 1) limit 100 offset 100', 100, false); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val - 1) desc limit 100 offset 100', 100, true); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE + +-- matching expression +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val + 1)', 1000, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val + 1) desc', 1000, true); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val + 1) limit 100', 100, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val + 1) desc limit 100', 100, true); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val + 1) limit 100 offset 100', 100, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val + 1) desc limit 100 offset 100', 100, true); + brinsort_check_ordering +------------------------- + +(1 row) + +-- mismatching expression +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val - 1)', 1000, false); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val - 1) desc', 1000, true); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val - 1) limit 100', 100, false); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val - 1) desc limit 100', 100, true); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val - 1) limit 100 offset 100', 100, false); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val - 1) desc limit 100 offset 100', 100, true); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE + +-- matching expression +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''x'' || text_val)', 1000, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''x'' || text_val) desc', 1000, true); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''x'' || text_val) limit 100', 100, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''x'' || text_val) desc limit 100', 100, true); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''x'' || text_val) limit 100 offset 100', 100, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''x'' || text_val) desc limit 100 offset 100', 100, true); + brinsort_check_ordering +------------------------- + +(1 row) + +-- mismatching expression +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''y'' || text_val)', 1000, false); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''y'' || text_val) desc', 1000, true); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''y'' || text_val) limit 100', 100, false); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''y'' || text_val) desc limit 100', 100, true); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''y'' || text_val) limit 100 offset 100', 100, false); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''y'' || text_val) desc limit 100 offset 100', 100, true); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE + +-- matching expression +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val + 1)', 1000, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val + 1) desc', 1000, true); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val + 1) limit 100', 100, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val + 1) desc limit 100', 100, true); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val + 1) limit 100 offset 100', 100, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val + 1) desc limit 100 offset 100', 100, true); + brinsort_check_ordering +------------------------- + +(1 row) + +-- mismatching expression +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val - 1)', 1000, false); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val - 1) desc', 1000, true); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val - 1) limit 100', 100, false); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val - 1) desc limit 100', 100, true); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val - 1) limit 100 offset 100', 100, false); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val - 1) desc limit 100 offset 100', 100, true); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +-- random data +truncate table brin_sort_test; +insert into brin_sort_test +select + (1000 * random())::int, + -((1000 * random())::int), -- same as int, but at least opposite + lpad(((1000 * random())::int)::text || md5(i::text), 40, '0'), + '10.0.0.0'::inet + (1000 * random()::int) +from generate_series(1,1000) s(i); +reindex table brin_sort_test; +vacuum analyze brin_sort_test; + +-- matching expression +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val + 1)', 1000, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val + 1) desc', 1000, true); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val + 1) limit 100', 100, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val + 1) desc limit 100', 100, true); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val + 1) limit 100 offset 100', 100, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val + 1) desc limit 100 offset 100', 100, true); + brinsort_check_ordering +------------------------- + +(1 row) + +-- mismatching expression +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val - 1)', 1000, false); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val - 1) desc', 1000, true); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val - 1) limit 100', 100, false); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val - 1) desc limit 100', 100, true); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val - 1) limit 100 offset 100', 100, false); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val - 1) desc limit 100 offset 100', 100, true); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE + +-- matching expression +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val + 1)', 1000, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val + 1) desc', 1000, true); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val + 1) limit 100', 100, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val + 1) desc limit 100', 100, true); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val + 1) limit 100 offset 100', 100, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val + 1) desc limit 100 offset 100', 100, true); + brinsort_check_ordering +------------------------- + +(1 row) + +-- mismatching expression +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val - 1)', 1000, false); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val - 1) desc', 1000, true); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val - 1) limit 100', 100, false); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val - 1) desc limit 100', 100, true); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val - 1) limit 100 offset 100', 100, false); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val - 1) desc limit 100 offset 100', 100, true); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE + +-- matching expression +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''x'' || text_val)', 1000, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''x'' || text_val) desc', 1000, true); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''x'' || text_val) limit 100', 100, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''x'' || text_val) desc limit 100', 100, true); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''x'' || text_val) limit 100 offset 100', 100, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''x'' || text_val) desc limit 100 offset 100', 100, true); + brinsort_check_ordering +------------------------- + +(1 row) + +-- mismatching expression +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''y'' || text_val)', 1000, false); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''y'' || text_val) desc', 1000, true); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''y'' || text_val) limit 100', 100, false); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''y'' || text_val) desc limit 100', 100, true); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''y'' || text_val) limit 100 offset 100', 100, false); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''y'' || text_val) desc limit 100 offset 100', 100, true); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE + +-- matching expression +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val + 1)', 1000, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val + 1) desc', 1000, true); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val + 1) limit 100', 100, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val + 1) desc limit 100', 100, true); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val + 1) limit 100 offset 100', 100, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val + 1) desc limit 100 offset 100', 100, true); + brinsort_check_ordering +------------------------- + +(1 row) + +-- mismatching expression +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val - 1)', 1000, false); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val - 1) desc', 1000, true); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val - 1) limit 100', 100, false); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val - 1) desc limit 100', 100, true); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val - 1) limit 100 offset 100', 100, false); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val - 1) desc limit 100 offset 100', 100, true); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +drop table brin_sort_test; diff --git a/src/test/regress/expected/brin_sort_multi.out b/src/test/regress/expected/brin_sort_multi.out new file mode 100644 index 00000000000..22fa8331d38 --- /dev/null +++ b/src/test/regress/expected/brin_sort_multi.out @@ -0,0 +1,545 @@ +-- function to verify various sort-related data (total rows, ordering) +create or replace function brinsort_check_ordering(p_sql text, p_rows_expected int, p_desc boolean) returns void as $$ +declare + v_curs refcursor; + v_row record; + v_prev record; + v_brin_sort_found bool := false; + v_count int := 0; +begin + + -- needed because the p_sql query has different data types + execute 'discard plans'; + + OPEN v_curs NO SCROLL FOR EXECUTE format('explain %s', p_sql); + + LOOP + FETCH v_curs INTO v_row; + + IF NOT FOUND THEN + EXIT; + END IF; + + IF v_row::text LIKE '%BRIN Sort%' THEN + v_brin_sort_found := true; + EXIT; + END IF; + END LOOP; + + CLOSE v_curs; + + IF NOT v_brin_sort_found THEN + RAISE EXCEPTION 'BRIN Sort: not found'; + END IF; + + OPEN v_curs NO SCROLL FOR EXECUTE format(p_sql); + + LOOP + FETCH v_curs INTO v_row; + + IF NOT FOUND THEN + EXIT; + END IF; + + IF v_prev IS NOT NULL THEN + IF v_prev.val > v_row.val AND NOT p_desc THEN + RAISE EXCEPTION 'ordering mismatch % > % (asc)', v_prev.val, v_row.val; + END IF; + IF v_prev.val < v_row.val AND p_desc THEN + RAISE EXCEPTION 'ordering mismatch % < % (desc)', v_prev.val, v_row.val; + END IF; + END IF; + + v_prev := v_row; + v_count := v_count + 1; + END LOOP; + + CLOSE v_curs; + + IF v_count != p_rows_expected THEN + RAISE EXCEPTION 'count mismatch: % != %', v_count, p_rows_expected; + END IF; + +end; +$$ language plpgsql; +create table brin_sort_test (int_val int, bigint_val bigint, text_val text, inet_val inet) with (fillfactor=10); +-- sequential values +insert into brin_sort_test +select + i, + -i, -- same as int, but at least opposite + lpad(i::text || md5(i::text), 40, '0'), + '10.0.0.0'::inet + i +from generate_series(1,1000) s(i); +-- create brin indexes on individual columns +create index brin_sort_test_multi_idx on brin_sort_test using brin (int_val, bigint_val, text_val, inet_val inet_minmax_ops) with (pages_per_range=1); +-- +vacuum analyze brin_sort_test; +set enable_seqscan = off; + +select brinsort_check_ordering('select int_val as val from brin_sort_test order by int_val', 1000, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select int_val as val from brin_sort_test order by int_val desc', 1000, true); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select int_val as val from brin_sort_test order by int_val limit 100', 100, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select int_val as val from brin_sort_test order by int_val desc limit 100', 100, true); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select int_val as val from brin_sort_test order by int_val limit 100 offset 100', 100, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select int_val as val from brin_sort_test order by int_val desc limit 100 offset 100', 100, true); + brinsort_check_ordering +------------------------- + +(1 row) + + +select brinsort_check_ordering('select bigint_val as val from brin_sort_test order by bigint_val', 1000, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select bigint_val as val from brin_sort_test order by bigint_val desc', 1000, true); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select bigint_val as val from brin_sort_test order by bigint_val limit 100', 100, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select bigint_val as val from brin_sort_test order by bigint_val desc limit 100', 100, true); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select bigint_val as val from brin_sort_test order by bigint_val limit 100 offset 100', 100, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select bigint_val as val from brin_sort_test order by bigint_val desc limit 100 offset 100', 100, true); + brinsort_check_ordering +------------------------- + +(1 row) + + +select brinsort_check_ordering('select inet_val as val from brin_sort_test order by inet_val', 1000, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select inet_val as val from brin_sort_test order by inet_val desc', 1000, true); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select inet_val as val from brin_sort_test order by inet_val limit 100', 100, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select inet_val as val from brin_sort_test order by inet_val desc limit 100', 100, true); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select inet_val as val from brin_sort_test order by inet_val limit 100 offset 100', 100, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select inet_val as val from brin_sort_test order by inet_val desc limit 100 offset 100', 100, true); + brinsort_check_ordering +------------------------- + +(1 row) + + +select brinsort_check_ordering('select text_val as val from brin_sort_test order by text_val', 1000, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select text_val as val from brin_sort_test order by text_val desc', 1000, true); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select text_val as val from brin_sort_test order by text_val limit 100', 100, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select text_val as val from brin_sort_test order by text_val desc limit 100', 100, true); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select text_val as val from brin_sort_test order by text_val limit 100 offset 100', 100, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select text_val as val from brin_sort_test order by text_val desc limit 100 offset 100', 100, true); + brinsort_check_ordering +------------------------- + +(1 row) + +-- semi-random data (sequential + randomness) +truncate table brin_sort_test; +insert into brin_sort_test +select + i + (100 * random())::int, + -(i + (100 * random())::int), -- same as int, but at least opposite + lpad((i + (100 * random())::int)::text || md5(i::text), 40, '0'), + '10.0.0.0'::inet + (i + 100 * random()::int) +from generate_series(1,1000) s(i); +reindex table brin_sort_test; +vacuum analyze brin_sort_test; + +select brinsort_check_ordering('select int_val as val from brin_sort_test order by int_val', 1000, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select int_val as val from brin_sort_test order by int_val desc', 1000, true); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select int_val as val from brin_sort_test order by int_val limit 100', 100, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select int_val as val from brin_sort_test order by int_val desc limit 100', 100, true); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select int_val as val from brin_sort_test order by int_val limit 100 offset 100', 100, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select int_val as val from brin_sort_test order by int_val desc limit 100 offset 100', 100, true); + brinsort_check_ordering +------------------------- + +(1 row) + + +select brinsort_check_ordering('select bigint_val as val from brin_sort_test order by bigint_val', 1000, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select bigint_val as val from brin_sort_test order by bigint_val desc', 1000, true); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select bigint_val as val from brin_sort_test order by bigint_val limit 100', 100, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select bigint_val as val from brin_sort_test order by bigint_val desc limit 100', 100, true); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select bigint_val as val from brin_sort_test order by bigint_val limit 100 offset 100', 100, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select bigint_val as val from brin_sort_test order by bigint_val desc limit 100 offset 100', 100, true); + brinsort_check_ordering +------------------------- + +(1 row) + + +select brinsort_check_ordering('select inet_val as val from brin_sort_test order by inet_val', 1000, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select inet_val as val from brin_sort_test order by inet_val desc', 1000, true); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select inet_val as val from brin_sort_test order by inet_val limit 100', 100, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select inet_val as val from brin_sort_test order by inet_val desc limit 100', 100, true); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select inet_val as val from brin_sort_test order by inet_val limit 100 offset 100', 100, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select inet_val as val from brin_sort_test order by inet_val desc limit 100 offset 100', 100, true); + brinsort_check_ordering +------------------------- + +(1 row) + + +select brinsort_check_ordering('select text_val as val from brin_sort_test order by text_val', 1000, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select text_val as val from brin_sort_test order by text_val desc', 1000, true); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select text_val as val from brin_sort_test order by text_val limit 100', 100, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select text_val as val from brin_sort_test order by text_val desc limit 100', 100, true); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select text_val as val from brin_sort_test order by text_val limit 100 offset 100', 100, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select text_val as val from brin_sort_test order by text_val desc limit 100 offset 100', 100, true); + brinsort_check_ordering +------------------------- + +(1 row) + +-- random data +truncate table brin_sort_test; +insert into brin_sort_test +select + (1000 * random())::int, + -((1000 * random())::int), -- same as int, but at least opposite + lpad(((1000 * random())::int)::text || md5(i::text), 40, '0'), + '10.0.0.0'::inet + (1000 * random()::int) +from generate_series(1,1000) s(i); +reindex table brin_sort_test; +vacuum analyze brin_sort_test; + +select brinsort_check_ordering('select int_val as val from brin_sort_test order by int_val', 1000, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select int_val as val from brin_sort_test order by int_val desc', 1000, true); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select int_val as val from brin_sort_test order by int_val limit 100', 100, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select int_val as val from brin_sort_test order by int_val desc limit 100', 100, true); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select int_val as val from brin_sort_test order by int_val limit 100 offset 100', 100, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select int_val as val from brin_sort_test order by int_val desc limit 100 offset 100', 100, true); + brinsort_check_ordering +------------------------- + +(1 row) + + +select brinsort_check_ordering('select bigint_val as val from brin_sort_test order by bigint_val', 1000, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select bigint_val as val from brin_sort_test order by bigint_val desc', 1000, true); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select bigint_val as val from brin_sort_test order by bigint_val limit 100', 100, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select bigint_val as val from brin_sort_test order by bigint_val desc limit 100', 100, true); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select bigint_val as val from brin_sort_test order by bigint_val limit 100 offset 100', 100, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select bigint_val as val from brin_sort_test order by bigint_val desc limit 100 offset 100', 100, true); + brinsort_check_ordering +------------------------- + +(1 row) + + +select brinsort_check_ordering('select inet_val as val from brin_sort_test order by inet_val', 1000, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select inet_val as val from brin_sort_test order by inet_val desc', 1000, true); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select inet_val as val from brin_sort_test order by inet_val limit 100', 100, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select inet_val as val from brin_sort_test order by inet_val desc limit 100', 100, true); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select inet_val as val from brin_sort_test order by inet_val limit 100 offset 100', 100, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select inet_val as val from brin_sort_test order by inet_val desc limit 100 offset 100', 100, true); + brinsort_check_ordering +------------------------- + +(1 row) + + +select brinsort_check_ordering('select text_val as val from brin_sort_test order by text_val', 1000, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select text_val as val from brin_sort_test order by text_val desc', 1000, true); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select text_val as val from brin_sort_test order by text_val limit 100', 100, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select text_val as val from brin_sort_test order by text_val desc limit 100', 100, true); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select text_val as val from brin_sort_test order by text_val limit 100 offset 100', 100, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select text_val as val from brin_sort_test order by text_val desc limit 100 offset 100', 100, true); + brinsort_check_ordering +------------------------- + +(1 row) + +drop table brin_sort_test; diff --git a/src/test/regress/expected/brin_sort_multi_exprs.out b/src/test/regress/expected/brin_sort_multi_exprs.out new file mode 100644 index 00000000000..0e9f4ea3182 --- /dev/null +++ b/src/test/regress/expected/brin_sort_multi_exprs.out @@ -0,0 +1,784 @@ +-- function to verify various sort-related data (total rows, ordering) +create or replace function brinsort_check_ordering(p_sql text, p_rows_expected int, p_desc boolean) returns void as $$ +declare + v_curs refcursor; + v_row record; + v_prev record; + v_brin_sort_found bool := false; + v_count int := 0; +begin + + -- needed because the p_sql query has different data types + execute 'discard plans'; + + OPEN v_curs NO SCROLL FOR EXECUTE format('explain %s', p_sql); + + LOOP + FETCH v_curs INTO v_row; + + IF NOT FOUND THEN + EXIT; + END IF; + + IF v_row::text LIKE '%BRIN Sort%' THEN + v_brin_sort_found := true; + EXIT; + END IF; + END LOOP; + + CLOSE v_curs; + + IF NOT v_brin_sort_found THEN + RAISE EXCEPTION 'BRIN Sort: not found'; + END IF; + + OPEN v_curs NO SCROLL FOR EXECUTE format(p_sql); + + LOOP + FETCH v_curs INTO v_row; + + IF NOT FOUND THEN + EXIT; + END IF; + + IF v_prev IS NOT NULL THEN + IF v_prev.val > v_row.val AND NOT p_desc THEN + RAISE EXCEPTION 'ordering mismatch % > % (asc)', v_prev.val, v_row.val; + END IF; + IF v_prev.val < v_row.val AND p_desc THEN + RAISE EXCEPTION 'ordering mismatch % < % (desc)', v_prev.val, v_row.val; + END IF; + END IF; + + v_prev := v_row; + v_count := v_count + 1; + END LOOP; + + CLOSE v_curs; + + IF v_count != p_rows_expected THEN + RAISE EXCEPTION 'count mismatch: % != %', v_count, p_rows_expected; + END IF; + +end; +$$ language plpgsql; +create table brin_sort_test (int_val int, bigint_val bigint, text_val text, inet_val inet) with (fillfactor=10); +-- sequential values +insert into brin_sort_test +select + i, + -i, -- same as int, but at least opposite + lpad(i::text || md5(i::text), 40, '0'), + '10.0.0.0'::inet + i +from generate_series(1,1000) s(i); +-- create brin indexes on individual columns +create index brin_sort_test_int_idx on brin_sort_test using brin ((int_val + 1), (bigint_val + 1), ('x' || text_val), (inet_val + 1) inet_minmax_ops) with (pages_per_range=1); +vacuum analyze brin_sort_test; +set enable_seqscan = off; + +-- matching expression +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val + 1)', 1000, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val + 1) desc', 1000, true); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val + 1) limit 100', 100, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val + 1) desc limit 100', 100, true); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val + 1) limit 100 offset 100', 100, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val + 1) desc limit 100 offset 100', 100, true); + brinsort_check_ordering +------------------------- + +(1 row) + +-- mismatching expression +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val - 1)', 1000, false); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val - 1) desc', 1000, true); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val - 1) limit 100', 100, false); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val - 1) desc limit 100', 100, true); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val - 1) limit 100 offset 100', 100, false); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val - 1) desc limit 100 offset 100', 100, true); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE + +-- matching expression +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val + 1)', 1000, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val + 1) desc', 1000, true); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val + 1) limit 100', 100, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val + 1) desc limit 100', 100, true); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val + 1) limit 100 offset 100', 100, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val + 1) desc limit 100 offset 100', 100, true); + brinsort_check_ordering +------------------------- + +(1 row) + +-- mismatching expression +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val - 1)', 1000, false); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val - 1) desc', 1000, true); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val - 1) limit 100', 100, false); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val - 1) desc limit 100', 100, true); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val - 1) limit 100 offset 100', 100, false); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val - 1) desc limit 100 offset 100', 100, true); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE + +-- matching expression +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''x'' || text_val)', 1000, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''x'' || text_val) desc', 1000, true); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''x'' || text_val) limit 100', 100, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''x'' || text_val) desc limit 100', 100, true); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''x'' || text_val) limit 100 offset 100', 100, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''x'' || text_val) desc limit 100 offset 100', 100, true); + brinsort_check_ordering +------------------------- + +(1 row) + +-- mismatching expression +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''y'' || text_val)', 1000, false); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''y'' || text_val) desc', 1000, true); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''y'' || text_val) limit 100', 100, false); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''y'' || text_val) desc limit 100', 100, true); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''y'' || text_val) limit 100 offset 100', 100, false); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''y'' || text_val) desc limit 100 offset 100', 100, true); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE + +-- matching expression +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val + 1)', 1000, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val + 1) desc', 1000, true); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val + 1) limit 100', 100, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val + 1) desc limit 100', 100, true); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val + 1) limit 100 offset 100', 100, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val + 1) desc limit 100 offset 100', 100, true); + brinsort_check_ordering +------------------------- + +(1 row) + +-- mismatching expression +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val - 1)', 1000, false); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val - 1) desc', 1000, true); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val - 1) limit 100', 100, false); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val - 1) desc limit 100', 100, true); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val - 1) limit 100 offset 100', 100, false); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val - 1) desc limit 100 offset 100', 100, true); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +-- semi-random data (sequential + randomness) +truncate table brin_sort_test; +insert into brin_sort_test +select + i + (100 * random())::int, + -(i + (100 * random())::int), -- same as int, but at least opposite + lpad((i + (100 * random())::int)::text || md5(i::text), 40, '0'), + '10.0.0.0'::inet + (i + 100 * random()::int) +from generate_series(1,1000) s(i); +reindex table brin_sort_test; +vacuum analyze brin_sort_test; + +-- matching expression +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val + 1)', 1000, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val + 1) desc', 1000, true); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val + 1) limit 100', 100, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val + 1) desc limit 100', 100, true); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val + 1) limit 100 offset 100', 100, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val + 1) desc limit 100 offset 100', 100, true); + brinsort_check_ordering +------------------------- + +(1 row) + +-- mismatching expression +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val - 1)', 1000, false); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val - 1) desc', 1000, true); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val - 1) limit 100', 100, false); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val - 1) desc limit 100', 100, true); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val - 1) limit 100 offset 100', 100, false); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val - 1) desc limit 100 offset 100', 100, true); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE + +-- matching expression +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val + 1)', 1000, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val + 1) desc', 1000, true); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val + 1) limit 100', 100, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val + 1) desc limit 100', 100, true); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val + 1) limit 100 offset 100', 100, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val + 1) desc limit 100 offset 100', 100, true); + brinsort_check_ordering +------------------------- + +(1 row) + +-- mismatching expression +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val - 1)', 1000, false); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val - 1) desc', 1000, true); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val - 1) limit 100', 100, false); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val - 1) desc limit 100', 100, true); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val - 1) limit 100 offset 100', 100, false); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val - 1) desc limit 100 offset 100', 100, true); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE + +-- matching expression +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''x'' || text_val)', 1000, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''x'' || text_val) desc', 1000, true); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''x'' || text_val) limit 100', 100, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''x'' || text_val) desc limit 100', 100, true); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''x'' || text_val) limit 100 offset 100', 100, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''x'' || text_val) desc limit 100 offset 100', 100, true); + brinsort_check_ordering +------------------------- + +(1 row) + +-- mismatching expression +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''y'' || text_val)', 1000, false); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''y'' || text_val) desc', 1000, true); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''y'' || text_val) limit 100', 100, false); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''y'' || text_val) desc limit 100', 100, true); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''y'' || text_val) limit 100 offset 100', 100, false); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''y'' || text_val) desc limit 100 offset 100', 100, true); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE + +-- matching expression +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val + 1)', 1000, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val + 1) desc', 1000, true); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val + 1) limit 100', 100, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val + 1) desc limit 100', 100, true); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val + 1) limit 100 offset 100', 100, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val + 1) desc limit 100 offset 100', 100, true); + brinsort_check_ordering +------------------------- + +(1 row) + +-- mismatching expression +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val - 1)', 1000, false); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val - 1) desc', 1000, true); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val - 1) limit 100', 100, false); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val - 1) desc limit 100', 100, true); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val - 1) limit 100 offset 100', 100, false); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val - 1) desc limit 100 offset 100', 100, true); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +-- random data +truncate table brin_sort_test; +insert into brin_sort_test +select + (1000 * random())::int, + -((1000 * random())::int), -- same as int, but at least opposite + lpad(((1000 * random())::int)::text || md5(i::text), 40, '0'), + '10.0.0.0'::inet + (1000 * random()::int) +from generate_series(1,1000) s(i); +reindex table brin_sort_test; +vacuum analyze brin_sort_test; + +-- matching expression +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val + 1)', 1000, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val + 1) desc', 1000, true); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val + 1) limit 100', 100, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val + 1) desc limit 100', 100, true); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val + 1) limit 100 offset 100', 100, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val + 1) desc limit 100 offset 100', 100, true); + brinsort_check_ordering +------------------------- + +(1 row) + +-- mismatching expression +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val - 1)', 1000, false); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val - 1) desc', 1000, true); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val - 1) limit 100', 100, false); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val - 1) desc limit 100', 100, true); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val - 1) limit 100 offset 100', 100, false); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val - 1) desc limit 100 offset 100', 100, true); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE + +-- matching expression +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val + 1)', 1000, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val + 1) desc', 1000, true); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val + 1) limit 100', 100, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val + 1) desc limit 100', 100, true); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val + 1) limit 100 offset 100', 100, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val + 1) desc limit 100 offset 100', 100, true); + brinsort_check_ordering +------------------------- + +(1 row) + +-- mismatching expression +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val - 1)', 1000, false); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val - 1) desc', 1000, true); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val - 1) limit 100', 100, false); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val - 1) desc limit 100', 100, true); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val - 1) limit 100 offset 100', 100, false); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val - 1) desc limit 100 offset 100', 100, true); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE + +-- matching expression +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''x'' || text_val)', 1000, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''x'' || text_val) desc', 1000, true); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''x'' || text_val) limit 100', 100, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''x'' || text_val) desc limit 100', 100, true); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''x'' || text_val) limit 100 offset 100', 100, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''x'' || text_val) desc limit 100 offset 100', 100, true); + brinsort_check_ordering +------------------------- + +(1 row) + +-- mismatching expression +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''y'' || text_val)', 1000, false); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''y'' || text_val) desc', 1000, true); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''y'' || text_val) limit 100', 100, false); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''y'' || text_val) desc limit 100', 100, true); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''y'' || text_val) limit 100 offset 100', 100, false); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''y'' || text_val) desc limit 100 offset 100', 100, true); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE + +-- matching expression +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val + 1)', 1000, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val + 1) desc', 1000, true); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val + 1) limit 100', 100, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val + 1) desc limit 100', 100, true); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val + 1) limit 100 offset 100', 100, false); + brinsort_check_ordering +------------------------- + +(1 row) + +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val + 1) desc limit 100 offset 100', 100, true); + brinsort_check_ordering +------------------------- + +(1 row) + +-- mismatching expression +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val - 1)', 1000, false); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val - 1) desc', 1000, true); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val - 1) limit 100', 100, false); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val - 1) desc limit 100', 100, true); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val - 1) limit 100 offset 100', 100, false); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val - 1) desc limit 100 offset 100', 100, true); +ERROR: BRIN Sort: not found +CONTEXT: PL/pgSQL function brinsort_check_ordering(text,integer,boolean) line 31 at RAISE +drop table brin_sort_test; diff --git a/src/test/regress/parallel_schedule b/src/test/regress/parallel_schedule index 15e015b3d64..39af15bb5d8 100644 --- a/src/test/regress/parallel_schedule +++ b/src/test/regress/parallel_schedule @@ -131,3 +131,9 @@ test: fast_default # run tablespace test at the end because it drops the tablespace created during # setup that other tests may use. test: tablespace + +# try sorting using BRIN index +test: brin_sort +test: brin_sort_multi +test: brin_sort_exprs +test: brin_sort_multi_exprs diff --git a/src/test/regress/sql/brin_sort.sql b/src/test/regress/sql/brin_sort.sql new file mode 100644 index 00000000000..f4458bdc386 --- /dev/null +++ b/src/test/regress/sql/brin_sort.sql @@ -0,0 +1,238 @@ +-- function to verify various sort-related data (total rows, ordering) +create or replace function brinsort_check_ordering(p_sql text, p_rows_expected int, p_desc boolean) returns void as $$ +declare + v_curs refcursor; + v_row record; + v_prev record; + v_brin_sort_found bool := false; + v_count int := 0; +begin + + -- needed because the p_sql query has different data types + execute 'discard plans'; + + OPEN v_curs NO SCROLL FOR EXECUTE format('explain %s', p_sql); + + LOOP + FETCH v_curs INTO v_row; + + IF NOT FOUND THEN + EXIT; + END IF; + + IF v_row::text LIKE '%BRIN Sort%' THEN + v_brin_sort_found := true; + EXIT; + END IF; + END LOOP; + + CLOSE v_curs; + + IF NOT v_brin_sort_found THEN + RAISE EXCEPTION 'BRIN Sort: not found'; + END IF; + + OPEN v_curs NO SCROLL FOR EXECUTE format(p_sql); + + LOOP + FETCH v_curs INTO v_row; + + IF NOT FOUND THEN + EXIT; + END IF; + + IF v_prev IS NOT NULL THEN + IF v_prev.val > v_row.val AND NOT p_desc THEN + RAISE EXCEPTION 'ordering mismatch % > % (asc)', v_prev.val, v_row.val; + END IF; + IF v_prev.val < v_row.val AND p_desc THEN + RAISE EXCEPTION 'ordering mismatch % < % (desc)', v_prev.val, v_row.val; + END IF; + END IF; + + v_prev := v_row; + v_count := v_count + 1; + END LOOP; + + CLOSE v_curs; + + IF v_count != p_rows_expected THEN + RAISE EXCEPTION 'count mismatch: % != %', v_count, p_rows_expected; + END IF; + +end; +$$ language plpgsql; + +create table brin_sort_test (int_val int, bigint_val bigint, text_val text, inet_val inet) with (fillfactor=10); + +-- sequential values +insert into brin_sort_test +select + i, + -i, -- same as int, but at least opposite + lpad(i::text || md5(i::text), 40, '0'), + '10.0.0.0'::inet + i +from generate_series(1,1000) s(i); + +-- create brin indexes on individual columns +create index brin_sort_test_int_idx on brin_sort_test using brin (int_val) with (pages_per_range=1); +create index brin_sort_test_bigint_idx on brin_sort_test using brin (bigint_val) with (pages_per_range=1); +create index brin_sort_test_text_idx on brin_sort_test using brin (text_val) with (pages_per_range=1); +create index brin_sort_test_inet_idx on brin_sort_test using brin (inet_val inet_minmax_ops) with (pages_per_range=1); + +-- +vacuum analyze brin_sort_test; + +set enable_seqscan = off; + +select brinsort_check_ordering('select int_val as val from brin_sort_test order by int_val', 1000, false); +select brinsort_check_ordering('select int_val as val from brin_sort_test order by int_val desc', 1000, true); + +select brinsort_check_ordering('select int_val as val from brin_sort_test order by int_val limit 100', 100, false); +select brinsort_check_ordering('select int_val as val from brin_sort_test order by int_val desc limit 100', 100, true); + +select brinsort_check_ordering('select int_val as val from brin_sort_test order by int_val limit 100 offset 100', 100, false); +select brinsort_check_ordering('select int_val as val from brin_sort_test order by int_val desc limit 100 offset 100', 100, true); + + +select brinsort_check_ordering('select bigint_val as val from brin_sort_test order by bigint_val', 1000, false); +select brinsort_check_ordering('select bigint_val as val from brin_sort_test order by bigint_val desc', 1000, true); + +select brinsort_check_ordering('select bigint_val as val from brin_sort_test order by bigint_val limit 100', 100, false); +select brinsort_check_ordering('select bigint_val as val from brin_sort_test order by bigint_val desc limit 100', 100, true); + +select brinsort_check_ordering('select bigint_val as val from brin_sort_test order by bigint_val limit 100 offset 100', 100, false); +select brinsort_check_ordering('select bigint_val as val from brin_sort_test order by bigint_val desc limit 100 offset 100', 100, true); + + +select brinsort_check_ordering('select inet_val as val from brin_sort_test order by inet_val', 1000, false); +select brinsort_check_ordering('select inet_val as val from brin_sort_test order by inet_val desc', 1000, true); + +select brinsort_check_ordering('select inet_val as val from brin_sort_test order by inet_val limit 100', 100, false); +select brinsort_check_ordering('select inet_val as val from brin_sort_test order by inet_val desc limit 100', 100, true); + +select brinsort_check_ordering('select inet_val as val from brin_sort_test order by inet_val limit 100 offset 100', 100, false); +select brinsort_check_ordering('select inet_val as val from brin_sort_test order by inet_val desc limit 100 offset 100', 100, true); + + +select brinsort_check_ordering('select text_val as val from brin_sort_test order by text_val', 1000, false); +select brinsort_check_ordering('select text_val as val from brin_sort_test order by text_val desc', 1000, true); + +select brinsort_check_ordering('select text_val as val from brin_sort_test order by text_val limit 100', 100, false); +select brinsort_check_ordering('select text_val as val from brin_sort_test order by text_val desc limit 100', 100, true); + +select brinsort_check_ordering('select text_val as val from brin_sort_test order by text_val limit 100 offset 100', 100, false); +select brinsort_check_ordering('select text_val as val from brin_sort_test order by text_val desc limit 100 offset 100', 100, true); + + +-- semi-random data (sequential + randomness) +truncate table brin_sort_test; +insert into brin_sort_test +select + i + (100 * random())::int, + -(i + (100 * random())::int), -- same as int, but at least opposite + lpad((i + (100 * random())::int)::text || md5(i::text), 40, '0'), + '10.0.0.0'::inet + (i + 100 * random()::int) +from generate_series(1,1000) s(i); + +reindex table brin_sort_test; + +vacuum analyze brin_sort_test; + + +select brinsort_check_ordering('select int_val as val from brin_sort_test order by int_val', 1000, false); +select brinsort_check_ordering('select int_val as val from brin_sort_test order by int_val desc', 1000, true); + +select brinsort_check_ordering('select int_val as val from brin_sort_test order by int_val limit 100', 100, false); +select brinsort_check_ordering('select int_val as val from brin_sort_test order by int_val desc limit 100', 100, true); + +select brinsort_check_ordering('select int_val as val from brin_sort_test order by int_val limit 100 offset 100', 100, false); +select brinsort_check_ordering('select int_val as val from brin_sort_test order by int_val desc limit 100 offset 100', 100, true); + + +select brinsort_check_ordering('select bigint_val as val from brin_sort_test order by bigint_val', 1000, false); +select brinsort_check_ordering('select bigint_val as val from brin_sort_test order by bigint_val desc', 1000, true); + +select brinsort_check_ordering('select bigint_val as val from brin_sort_test order by bigint_val limit 100', 100, false); +select brinsort_check_ordering('select bigint_val as val from brin_sort_test order by bigint_val desc limit 100', 100, true); + +select brinsort_check_ordering('select bigint_val as val from brin_sort_test order by bigint_val limit 100 offset 100', 100, false); +select brinsort_check_ordering('select bigint_val as val from brin_sort_test order by bigint_val desc limit 100 offset 100', 100, true); + + +select brinsort_check_ordering('select inet_val as val from brin_sort_test order by inet_val', 1000, false); +select brinsort_check_ordering('select inet_val as val from brin_sort_test order by inet_val desc', 1000, true); + +select brinsort_check_ordering('select inet_val as val from brin_sort_test order by inet_val limit 100', 100, false); +select brinsort_check_ordering('select inet_val as val from brin_sort_test order by inet_val desc limit 100', 100, true); + +select brinsort_check_ordering('select inet_val as val from brin_sort_test order by inet_val limit 100 offset 100', 100, false); +select brinsort_check_ordering('select inet_val as val from brin_sort_test order by inet_val desc limit 100 offset 100', 100, true); + + +select brinsort_check_ordering('select text_val as val from brin_sort_test order by text_val', 1000, false); +select brinsort_check_ordering('select text_val as val from brin_sort_test order by text_val desc', 1000, true); + +select brinsort_check_ordering('select text_val as val from brin_sort_test order by text_val limit 100', 100, false); +select brinsort_check_ordering('select text_val as val from brin_sort_test order by text_val desc limit 100', 100, true); + +select brinsort_check_ordering('select text_val as val from brin_sort_test order by text_val limit 100 offset 100', 100, false); +select brinsort_check_ordering('select text_val as val from brin_sort_test order by text_val desc limit 100 offset 100', 100, true); + + +-- random data +truncate table brin_sort_test; +insert into brin_sort_test +select + (1000 * random())::int, + -((1000 * random())::int), -- same as int, but at least opposite + lpad(((1000 * random())::int)::text || md5(i::text), 40, '0'), + '10.0.0.0'::inet + (1000 * random()::int) +from generate_series(1,1000) s(i); + +reindex table brin_sort_test; + +vacuum analyze brin_sort_test; + + +select brinsort_check_ordering('select int_val as val from brin_sort_test order by int_val', 1000, false); +select brinsort_check_ordering('select int_val as val from brin_sort_test order by int_val desc', 1000, true); + +select brinsort_check_ordering('select int_val as val from brin_sort_test order by int_val limit 100', 100, false); +select brinsort_check_ordering('select int_val as val from brin_sort_test order by int_val desc limit 100', 100, true); + +select brinsort_check_ordering('select int_val as val from brin_sort_test order by int_val limit 100 offset 100', 100, false); +select brinsort_check_ordering('select int_val as val from brin_sort_test order by int_val desc limit 100 offset 100', 100, true); + + +select brinsort_check_ordering('select bigint_val as val from brin_sort_test order by bigint_val', 1000, false); +select brinsort_check_ordering('select bigint_val as val from brin_sort_test order by bigint_val desc', 1000, true); + +select brinsort_check_ordering('select bigint_val as val from brin_sort_test order by bigint_val limit 100', 100, false); +select brinsort_check_ordering('select bigint_val as val from brin_sort_test order by bigint_val desc limit 100', 100, true); + +select brinsort_check_ordering('select bigint_val as val from brin_sort_test order by bigint_val limit 100 offset 100', 100, false); +select brinsort_check_ordering('select bigint_val as val from brin_sort_test order by bigint_val desc limit 100 offset 100', 100, true); + + +select brinsort_check_ordering('select inet_val as val from brin_sort_test order by inet_val', 1000, false); +select brinsort_check_ordering('select inet_val as val from brin_sort_test order by inet_val desc', 1000, true); + +select brinsort_check_ordering('select inet_val as val from brin_sort_test order by inet_val limit 100', 100, false); +select brinsort_check_ordering('select inet_val as val from brin_sort_test order by inet_val desc limit 100', 100, true); + +select brinsort_check_ordering('select inet_val as val from brin_sort_test order by inet_val limit 100 offset 100', 100, false); +select brinsort_check_ordering('select inet_val as val from brin_sort_test order by inet_val desc limit 100 offset 100', 100, true); + + +select brinsort_check_ordering('select text_val as val from brin_sort_test order by text_val', 1000, false); +select brinsort_check_ordering('select text_val as val from brin_sort_test order by text_val desc', 1000, true); + +select brinsort_check_ordering('select text_val as val from brin_sort_test order by text_val limit 100', 100, false); +select brinsort_check_ordering('select text_val as val from brin_sort_test order by text_val desc limit 100', 100, true); + +select brinsort_check_ordering('select text_val as val from brin_sort_test order by text_val limit 100 offset 100', 100, false); +select brinsort_check_ordering('select text_val as val from brin_sort_test order by text_val desc limit 100 offset 100', 100, true); + + +drop table brin_sort_test; diff --git a/src/test/regress/sql/brin_sort_exprs.sql b/src/test/regress/sql/brin_sort_exprs.sql new file mode 100644 index 00000000000..de1f1e7d8fe --- /dev/null +++ b/src/test/regress/sql/brin_sort_exprs.sql @@ -0,0 +1,373 @@ +-- function to verify various sort-related data (total rows, ordering) +create or replace function brinsort_check_ordering(p_sql text, p_rows_expected int, p_desc boolean) returns void as $$ +declare + v_curs refcursor; + v_row record; + v_prev record; + v_brin_sort_found bool := false; + v_count int := 0; +begin + + -- needed because the p_sql query has different data types + execute 'discard plans'; + + OPEN v_curs NO SCROLL FOR EXECUTE format('explain %s', p_sql); + + LOOP + FETCH v_curs INTO v_row; + + IF NOT FOUND THEN + EXIT; + END IF; + + IF v_row::text LIKE '%BRIN Sort%' THEN + v_brin_sort_found := true; + EXIT; + END IF; + END LOOP; + + CLOSE v_curs; + + IF NOT v_brin_sort_found THEN + RAISE EXCEPTION 'BRIN Sort: not found'; + END IF; + + OPEN v_curs NO SCROLL FOR EXECUTE format(p_sql); + + LOOP + FETCH v_curs INTO v_row; + + IF NOT FOUND THEN + EXIT; + END IF; + + IF v_prev IS NOT NULL THEN + IF v_prev.val > v_row.val AND NOT p_desc THEN + RAISE EXCEPTION 'ordering mismatch % > % (asc)', v_prev.val, v_row.val; + END IF; + IF v_prev.val < v_row.val AND p_desc THEN + RAISE EXCEPTION 'ordering mismatch % < % (desc)', v_prev.val, v_row.val; + END IF; + END IF; + + v_prev := v_row; + v_count := v_count + 1; + END LOOP; + + CLOSE v_curs; + + IF v_count != p_rows_expected THEN + RAISE EXCEPTION 'count mismatch: % != %', v_count, p_rows_expected; + END IF; + +end; +$$ language plpgsql; + +create table brin_sort_test (int_val int, bigint_val bigint, text_val text, inet_val inet) with (fillfactor=10); + +-- sequential values +insert into brin_sort_test +select + i, + -i, -- same as int, but at least opposite + lpad(i::text || md5(i::text), 40, '0'), + '10.0.0.0'::inet + i +from generate_series(1,1000) s(i); + +-- create brin indexes on individual columns +create index brin_sort_test_int_idx on brin_sort_test using brin ((int_val + 1)) with (pages_per_range=1); +create index brin_sort_test_bigint_idx on brin_sort_test using brin ((bigint_val + 1)) with (pages_per_range=1); +create index brin_sort_test_text_idx on brin_sort_test using brin (('x' || text_val)) with (pages_per_range=1); +create index brin_sort_test_inet_idx on brin_sort_test using brin ((inet_val + 1) inet_minmax_ops) with (pages_per_range=1); + +-- +vacuum analyze brin_sort_test; + +set enable_seqscan = off; + +-- matching expression +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val + 1)', 1000, false); +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val + 1) desc', 1000, true); + +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val + 1) limit 100', 100, false); +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val + 1) desc limit 100', 100, true); + +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val + 1) limit 100 offset 100', 100, false); +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val + 1) desc limit 100 offset 100', 100, true); + +-- mismatching expression +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val - 1)', 1000, false); +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val - 1) desc', 1000, true); + +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val - 1) limit 100', 100, false); +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val - 1) desc limit 100', 100, true); + +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val - 1) limit 100 offset 100', 100, false); +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val - 1) desc limit 100 offset 100', 100, true); + + + +-- matching expression +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val + 1)', 1000, false); +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val + 1) desc', 1000, true); + +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val + 1) limit 100', 100, false); +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val + 1) desc limit 100', 100, true); + +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val + 1) limit 100 offset 100', 100, false); +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val + 1) desc limit 100 offset 100', 100, true); + +-- mismatching expression +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val - 1)', 1000, false); +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val - 1) desc', 1000, true); + +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val - 1) limit 100', 100, false); +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val - 1) desc limit 100', 100, true); + +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val - 1) limit 100 offset 100', 100, false); +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val - 1) desc limit 100 offset 100', 100, true); + + +-- matching expression +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''x'' || text_val)', 1000, false); +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''x'' || text_val) desc', 1000, true); + +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''x'' || text_val) limit 100', 100, false); +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''x'' || text_val) desc limit 100', 100, true); + +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''x'' || text_val) limit 100 offset 100', 100, false); +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''x'' || text_val) desc limit 100 offset 100', 100, true); + +-- mismatching expression +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''y'' || text_val)', 1000, false); +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''y'' || text_val) desc', 1000, true); + +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''y'' || text_val) limit 100', 100, false); +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''y'' || text_val) desc limit 100', 100, true); + +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''y'' || text_val) limit 100 offset 100', 100, false); +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''y'' || text_val) desc limit 100 offset 100', 100, true); + + +-- matching expression +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val + 1)', 1000, false); +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val + 1) desc', 1000, true); + +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val + 1) limit 100', 100, false); +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val + 1) desc limit 100', 100, true); + +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val + 1) limit 100 offset 100', 100, false); +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val + 1) desc limit 100 offset 100', 100, true); + +-- mismatching expression +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val - 1)', 1000, false); +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val - 1) desc', 1000, true); + +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val - 1) limit 100', 100, false); +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val - 1) desc limit 100', 100, true); + +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val - 1) limit 100 offset 100', 100, false); +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val - 1) desc limit 100 offset 100', 100, true); + + +-- semi-random data (sequential + randomness) +truncate table brin_sort_test; +insert into brin_sort_test +select + i + (100 * random())::int, + -(i + (100 * random())::int), -- same as int, but at least opposite + lpad((i + (100 * random())::int)::text || md5(i::text), 40, '0'), + '10.0.0.0'::inet + (i + 100 * random()::int) +from generate_series(1,1000) s(i); + +reindex table brin_sort_test; + +vacuum analyze brin_sort_test; + + +-- matching expression +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val + 1)', 1000, false); +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val + 1) desc', 1000, true); + +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val + 1) limit 100', 100, false); +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val + 1) desc limit 100', 100, true); + +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val + 1) limit 100 offset 100', 100, false); +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val + 1) desc limit 100 offset 100', 100, true); + +-- mismatching expression +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val - 1)', 1000, false); +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val - 1) desc', 1000, true); + +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val - 1) limit 100', 100, false); +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val - 1) desc limit 100', 100, true); + +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val - 1) limit 100 offset 100', 100, false); +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val - 1) desc limit 100 offset 100', 100, true); + + + +-- matching expression +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val + 1)', 1000, false); +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val + 1) desc', 1000, true); + +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val + 1) limit 100', 100, false); +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val + 1) desc limit 100', 100, true); + +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val + 1) limit 100 offset 100', 100, false); +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val + 1) desc limit 100 offset 100', 100, true); + +-- mismatching expression +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val - 1)', 1000, false); +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val - 1) desc', 1000, true); + +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val - 1) limit 100', 100, false); +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val - 1) desc limit 100', 100, true); + +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val - 1) limit 100 offset 100', 100, false); +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val - 1) desc limit 100 offset 100', 100, true); + + +-- matching expression +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''x'' || text_val)', 1000, false); +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''x'' || text_val) desc', 1000, true); + +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''x'' || text_val) limit 100', 100, false); +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''x'' || text_val) desc limit 100', 100, true); + +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''x'' || text_val) limit 100 offset 100', 100, false); +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''x'' || text_val) desc limit 100 offset 100', 100, true); + +-- mismatching expression +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''y'' || text_val)', 1000, false); +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''y'' || text_val) desc', 1000, true); + +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''y'' || text_val) limit 100', 100, false); +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''y'' || text_val) desc limit 100', 100, true); + +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''y'' || text_val) limit 100 offset 100', 100, false); +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''y'' || text_val) desc limit 100 offset 100', 100, true); + + +-- matching expression +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val + 1)', 1000, false); +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val + 1) desc', 1000, true); + +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val + 1) limit 100', 100, false); +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val + 1) desc limit 100', 100, true); + +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val + 1) limit 100 offset 100', 100, false); +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val + 1) desc limit 100 offset 100', 100, true); + +-- mismatching expression +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val - 1)', 1000, false); +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val - 1) desc', 1000, true); + +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val - 1) limit 100', 100, false); +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val - 1) desc limit 100', 100, true); + +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val - 1) limit 100 offset 100', 100, false); +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val - 1) desc limit 100 offset 100', 100, true); + + +-- random data +truncate table brin_sort_test; +insert into brin_sort_test +select + (1000 * random())::int, + -((1000 * random())::int), -- same as int, but at least opposite + lpad(((1000 * random())::int)::text || md5(i::text), 40, '0'), + '10.0.0.0'::inet + (1000 * random()::int) +from generate_series(1,1000) s(i); + +reindex table brin_sort_test; + +vacuum analyze brin_sort_test; + + +-- matching expression +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val + 1)', 1000, false); +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val + 1) desc', 1000, true); + +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val + 1) limit 100', 100, false); +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val + 1) desc limit 100', 100, true); + +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val + 1) limit 100 offset 100', 100, false); +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val + 1) desc limit 100 offset 100', 100, true); + +-- mismatching expression +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val - 1)', 1000, false); +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val - 1) desc', 1000, true); + +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val - 1) limit 100', 100, false); +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val - 1) desc limit 100', 100, true); + +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val - 1) limit 100 offset 100', 100, false); +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val - 1) desc limit 100 offset 100', 100, true); + + + +-- matching expression +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val + 1)', 1000, false); +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val + 1) desc', 1000, true); + +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val + 1) limit 100', 100, false); +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val + 1) desc limit 100', 100, true); + +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val + 1) limit 100 offset 100', 100, false); +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val + 1) desc limit 100 offset 100', 100, true); + +-- mismatching expression +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val - 1)', 1000, false); +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val - 1) desc', 1000, true); + +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val - 1) limit 100', 100, false); +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val - 1) desc limit 100', 100, true); + +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val - 1) limit 100 offset 100', 100, false); +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val - 1) desc limit 100 offset 100', 100, true); + + +-- matching expression +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''x'' || text_val)', 1000, false); +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''x'' || text_val) desc', 1000, true); + +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''x'' || text_val) limit 100', 100, false); +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''x'' || text_val) desc limit 100', 100, true); + +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''x'' || text_val) limit 100 offset 100', 100, false); +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''x'' || text_val) desc limit 100 offset 100', 100, true); + +-- mismatching expression +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''y'' || text_val)', 1000, false); +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''y'' || text_val) desc', 1000, true); + +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''y'' || text_val) limit 100', 100, false); +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''y'' || text_val) desc limit 100', 100, true); + +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''y'' || text_val) limit 100 offset 100', 100, false); +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''y'' || text_val) desc limit 100 offset 100', 100, true); + + +-- matching expression +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val + 1)', 1000, false); +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val + 1) desc', 1000, true); + +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val + 1) limit 100', 100, false); +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val + 1) desc limit 100', 100, true); + +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val + 1) limit 100 offset 100', 100, false); +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val + 1) desc limit 100 offset 100', 100, true); + +-- mismatching expression +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val - 1)', 1000, false); +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val - 1) desc', 1000, true); + +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val - 1) limit 100', 100, false); +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val - 1) desc limit 100', 100, true); + +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val - 1) limit 100 offset 100', 100, false); +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val - 1) desc limit 100 offset 100', 100, true); + + +drop table brin_sort_test; diff --git a/src/test/regress/sql/brin_sort_multi.sql b/src/test/regress/sql/brin_sort_multi.sql new file mode 100644 index 00000000000..d0544ad7069 --- /dev/null +++ b/src/test/regress/sql/brin_sort_multi.sql @@ -0,0 +1,235 @@ +-- function to verify various sort-related data (total rows, ordering) +create or replace function brinsort_check_ordering(p_sql text, p_rows_expected int, p_desc boolean) returns void as $$ +declare + v_curs refcursor; + v_row record; + v_prev record; + v_brin_sort_found bool := false; + v_count int := 0; +begin + + -- needed because the p_sql query has different data types + execute 'discard plans'; + + OPEN v_curs NO SCROLL FOR EXECUTE format('explain %s', p_sql); + + LOOP + FETCH v_curs INTO v_row; + + IF NOT FOUND THEN + EXIT; + END IF; + + IF v_row::text LIKE '%BRIN Sort%' THEN + v_brin_sort_found := true; + EXIT; + END IF; + END LOOP; + + CLOSE v_curs; + + IF NOT v_brin_sort_found THEN + RAISE EXCEPTION 'BRIN Sort: not found'; + END IF; + + OPEN v_curs NO SCROLL FOR EXECUTE format(p_sql); + + LOOP + FETCH v_curs INTO v_row; + + IF NOT FOUND THEN + EXIT; + END IF; + + IF v_prev IS NOT NULL THEN + IF v_prev.val > v_row.val AND NOT p_desc THEN + RAISE EXCEPTION 'ordering mismatch % > % (asc)', v_prev.val, v_row.val; + END IF; + IF v_prev.val < v_row.val AND p_desc THEN + RAISE EXCEPTION 'ordering mismatch % < % (desc)', v_prev.val, v_row.val; + END IF; + END IF; + + v_prev := v_row; + v_count := v_count + 1; + END LOOP; + + CLOSE v_curs; + + IF v_count != p_rows_expected THEN + RAISE EXCEPTION 'count mismatch: % != %', v_count, p_rows_expected; + END IF; + +end; +$$ language plpgsql; + +create table brin_sort_test (int_val int, bigint_val bigint, text_val text, inet_val inet) with (fillfactor=10); + +-- sequential values +insert into brin_sort_test +select + i, + -i, -- same as int, but at least opposite + lpad(i::text || md5(i::text), 40, '0'), + '10.0.0.0'::inet + i +from generate_series(1,1000) s(i); + +-- create brin indexes on individual columns +create index brin_sort_test_multi_idx on brin_sort_test using brin (int_val, bigint_val, text_val, inet_val inet_minmax_ops) with (pages_per_range=1); + +-- +vacuum analyze brin_sort_test; + +set enable_seqscan = off; + +select brinsort_check_ordering('select int_val as val from brin_sort_test order by int_val', 1000, false); +select brinsort_check_ordering('select int_val as val from brin_sort_test order by int_val desc', 1000, true); + +select brinsort_check_ordering('select int_val as val from brin_sort_test order by int_val limit 100', 100, false); +select brinsort_check_ordering('select int_val as val from brin_sort_test order by int_val desc limit 100', 100, true); + +select brinsort_check_ordering('select int_val as val from brin_sort_test order by int_val limit 100 offset 100', 100, false); +select brinsort_check_ordering('select int_val as val from brin_sort_test order by int_val desc limit 100 offset 100', 100, true); + + +select brinsort_check_ordering('select bigint_val as val from brin_sort_test order by bigint_val', 1000, false); +select brinsort_check_ordering('select bigint_val as val from brin_sort_test order by bigint_val desc', 1000, true); + +select brinsort_check_ordering('select bigint_val as val from brin_sort_test order by bigint_val limit 100', 100, false); +select brinsort_check_ordering('select bigint_val as val from brin_sort_test order by bigint_val desc limit 100', 100, true); + +select brinsort_check_ordering('select bigint_val as val from brin_sort_test order by bigint_val limit 100 offset 100', 100, false); +select brinsort_check_ordering('select bigint_val as val from brin_sort_test order by bigint_val desc limit 100 offset 100', 100, true); + + +select brinsort_check_ordering('select inet_val as val from brin_sort_test order by inet_val', 1000, false); +select brinsort_check_ordering('select inet_val as val from brin_sort_test order by inet_val desc', 1000, true); + +select brinsort_check_ordering('select inet_val as val from brin_sort_test order by inet_val limit 100', 100, false); +select brinsort_check_ordering('select inet_val as val from brin_sort_test order by inet_val desc limit 100', 100, true); + +select brinsort_check_ordering('select inet_val as val from brin_sort_test order by inet_val limit 100 offset 100', 100, false); +select brinsort_check_ordering('select inet_val as val from brin_sort_test order by inet_val desc limit 100 offset 100', 100, true); + + +select brinsort_check_ordering('select text_val as val from brin_sort_test order by text_val', 1000, false); +select brinsort_check_ordering('select text_val as val from brin_sort_test order by text_val desc', 1000, true); + +select brinsort_check_ordering('select text_val as val from brin_sort_test order by text_val limit 100', 100, false); +select brinsort_check_ordering('select text_val as val from brin_sort_test order by text_val desc limit 100', 100, true); + +select brinsort_check_ordering('select text_val as val from brin_sort_test order by text_val limit 100 offset 100', 100, false); +select brinsort_check_ordering('select text_val as val from brin_sort_test order by text_val desc limit 100 offset 100', 100, true); + + +-- semi-random data (sequential + randomness) +truncate table brin_sort_test; +insert into brin_sort_test +select + i + (100 * random())::int, + -(i + (100 * random())::int), -- same as int, but at least opposite + lpad((i + (100 * random())::int)::text || md5(i::text), 40, '0'), + '10.0.0.0'::inet + (i + 100 * random()::int) +from generate_series(1,1000) s(i); + +reindex table brin_sort_test; + +vacuum analyze brin_sort_test; + + +select brinsort_check_ordering('select int_val as val from brin_sort_test order by int_val', 1000, false); +select brinsort_check_ordering('select int_val as val from brin_sort_test order by int_val desc', 1000, true); + +select brinsort_check_ordering('select int_val as val from brin_sort_test order by int_val limit 100', 100, false); +select brinsort_check_ordering('select int_val as val from brin_sort_test order by int_val desc limit 100', 100, true); + +select brinsort_check_ordering('select int_val as val from brin_sort_test order by int_val limit 100 offset 100', 100, false); +select brinsort_check_ordering('select int_val as val from brin_sort_test order by int_val desc limit 100 offset 100', 100, true); + + +select brinsort_check_ordering('select bigint_val as val from brin_sort_test order by bigint_val', 1000, false); +select brinsort_check_ordering('select bigint_val as val from brin_sort_test order by bigint_val desc', 1000, true); + +select brinsort_check_ordering('select bigint_val as val from brin_sort_test order by bigint_val limit 100', 100, false); +select brinsort_check_ordering('select bigint_val as val from brin_sort_test order by bigint_val desc limit 100', 100, true); + +select brinsort_check_ordering('select bigint_val as val from brin_sort_test order by bigint_val limit 100 offset 100', 100, false); +select brinsort_check_ordering('select bigint_val as val from brin_sort_test order by bigint_val desc limit 100 offset 100', 100, true); + + +select brinsort_check_ordering('select inet_val as val from brin_sort_test order by inet_val', 1000, false); +select brinsort_check_ordering('select inet_val as val from brin_sort_test order by inet_val desc', 1000, true); + +select brinsort_check_ordering('select inet_val as val from brin_sort_test order by inet_val limit 100', 100, false); +select brinsort_check_ordering('select inet_val as val from brin_sort_test order by inet_val desc limit 100', 100, true); + +select brinsort_check_ordering('select inet_val as val from brin_sort_test order by inet_val limit 100 offset 100', 100, false); +select brinsort_check_ordering('select inet_val as val from brin_sort_test order by inet_val desc limit 100 offset 100', 100, true); + + +select brinsort_check_ordering('select text_val as val from brin_sort_test order by text_val', 1000, false); +select brinsort_check_ordering('select text_val as val from brin_sort_test order by text_val desc', 1000, true); + +select brinsort_check_ordering('select text_val as val from brin_sort_test order by text_val limit 100', 100, false); +select brinsort_check_ordering('select text_val as val from brin_sort_test order by text_val desc limit 100', 100, true); + +select brinsort_check_ordering('select text_val as val from brin_sort_test order by text_val limit 100 offset 100', 100, false); +select brinsort_check_ordering('select text_val as val from brin_sort_test order by text_val desc limit 100 offset 100', 100, true); + + +-- random data +truncate table brin_sort_test; +insert into brin_sort_test +select + (1000 * random())::int, + -((1000 * random())::int), -- same as int, but at least opposite + lpad(((1000 * random())::int)::text || md5(i::text), 40, '0'), + '10.0.0.0'::inet + (1000 * random()::int) +from generate_series(1,1000) s(i); + +reindex table brin_sort_test; + +vacuum analyze brin_sort_test; + + +select brinsort_check_ordering('select int_val as val from brin_sort_test order by int_val', 1000, false); +select brinsort_check_ordering('select int_val as val from brin_sort_test order by int_val desc', 1000, true); + +select brinsort_check_ordering('select int_val as val from brin_sort_test order by int_val limit 100', 100, false); +select brinsort_check_ordering('select int_val as val from brin_sort_test order by int_val desc limit 100', 100, true); + +select brinsort_check_ordering('select int_val as val from brin_sort_test order by int_val limit 100 offset 100', 100, false); +select brinsort_check_ordering('select int_val as val from brin_sort_test order by int_val desc limit 100 offset 100', 100, true); + + +select brinsort_check_ordering('select bigint_val as val from brin_sort_test order by bigint_val', 1000, false); +select brinsort_check_ordering('select bigint_val as val from brin_sort_test order by bigint_val desc', 1000, true); + +select brinsort_check_ordering('select bigint_val as val from brin_sort_test order by bigint_val limit 100', 100, false); +select brinsort_check_ordering('select bigint_val as val from brin_sort_test order by bigint_val desc limit 100', 100, true); + +select brinsort_check_ordering('select bigint_val as val from brin_sort_test order by bigint_val limit 100 offset 100', 100, false); +select brinsort_check_ordering('select bigint_val as val from brin_sort_test order by bigint_val desc limit 100 offset 100', 100, true); + + +select brinsort_check_ordering('select inet_val as val from brin_sort_test order by inet_val', 1000, false); +select brinsort_check_ordering('select inet_val as val from brin_sort_test order by inet_val desc', 1000, true); + +select brinsort_check_ordering('select inet_val as val from brin_sort_test order by inet_val limit 100', 100, false); +select brinsort_check_ordering('select inet_val as val from brin_sort_test order by inet_val desc limit 100', 100, true); + +select brinsort_check_ordering('select inet_val as val from brin_sort_test order by inet_val limit 100 offset 100', 100, false); +select brinsort_check_ordering('select inet_val as val from brin_sort_test order by inet_val desc limit 100 offset 100', 100, true); + + +select brinsort_check_ordering('select text_val as val from brin_sort_test order by text_val', 1000, false); +select brinsort_check_ordering('select text_val as val from brin_sort_test order by text_val desc', 1000, true); + +select brinsort_check_ordering('select text_val as val from brin_sort_test order by text_val limit 100', 100, false); +select brinsort_check_ordering('select text_val as val from brin_sort_test order by text_val desc limit 100', 100, true); + +select brinsort_check_ordering('select text_val as val from brin_sort_test order by text_val limit 100 offset 100', 100, false); +select brinsort_check_ordering('select text_val as val from brin_sort_test order by text_val desc limit 100 offset 100', 100, true); + + +drop table brin_sort_test; diff --git a/src/test/regress/sql/brin_sort_multi_exprs.sql b/src/test/regress/sql/brin_sort_multi_exprs.sql new file mode 100644 index 00000000000..299c7979326 --- /dev/null +++ b/src/test/regress/sql/brin_sort_multi_exprs.sql @@ -0,0 +1,369 @@ +-- function to verify various sort-related data (total rows, ordering) +create or replace function brinsort_check_ordering(p_sql text, p_rows_expected int, p_desc boolean) returns void as $$ +declare + v_curs refcursor; + v_row record; + v_prev record; + v_brin_sort_found bool := false; + v_count int := 0; +begin + + -- needed because the p_sql query has different data types + execute 'discard plans'; + + OPEN v_curs NO SCROLL FOR EXECUTE format('explain %s', p_sql); + + LOOP + FETCH v_curs INTO v_row; + + IF NOT FOUND THEN + EXIT; + END IF; + + IF v_row::text LIKE '%BRIN Sort%' THEN + v_brin_sort_found := true; + EXIT; + END IF; + END LOOP; + + CLOSE v_curs; + + IF NOT v_brin_sort_found THEN + RAISE EXCEPTION 'BRIN Sort: not found'; + END IF; + + OPEN v_curs NO SCROLL FOR EXECUTE format(p_sql); + + LOOP + FETCH v_curs INTO v_row; + + IF NOT FOUND THEN + EXIT; + END IF; + + IF v_prev IS NOT NULL THEN + IF v_prev.val > v_row.val AND NOT p_desc THEN + RAISE EXCEPTION 'ordering mismatch % > % (asc)', v_prev.val, v_row.val; + END IF; + IF v_prev.val < v_row.val AND p_desc THEN + RAISE EXCEPTION 'ordering mismatch % < % (desc)', v_prev.val, v_row.val; + END IF; + END IF; + + v_prev := v_row; + v_count := v_count + 1; + END LOOP; + + CLOSE v_curs; + + IF v_count != p_rows_expected THEN + RAISE EXCEPTION 'count mismatch: % != %', v_count, p_rows_expected; + END IF; + +end; +$$ language plpgsql; + +create table brin_sort_test (int_val int, bigint_val bigint, text_val text, inet_val inet) with (fillfactor=10); + +-- sequential values +insert into brin_sort_test +select + i, + -i, -- same as int, but at least opposite + lpad(i::text || md5(i::text), 40, '0'), + '10.0.0.0'::inet + i +from generate_series(1,1000) s(i); + +-- create brin indexes on individual columns +create index brin_sort_test_int_idx on brin_sort_test using brin ((int_val + 1), (bigint_val + 1), ('x' || text_val), (inet_val + 1) inet_minmax_ops) with (pages_per_range=1); + +vacuum analyze brin_sort_test; + +set enable_seqscan = off; + +-- matching expression +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val + 1)', 1000, false); +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val + 1) desc', 1000, true); + +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val + 1) limit 100', 100, false); +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val + 1) desc limit 100', 100, true); + +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val + 1) limit 100 offset 100', 100, false); +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val + 1) desc limit 100 offset 100', 100, true); + +-- mismatching expression +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val - 1)', 1000, false); +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val - 1) desc', 1000, true); + +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val - 1) limit 100', 100, false); +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val - 1) desc limit 100', 100, true); + +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val - 1) limit 100 offset 100', 100, false); +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val - 1) desc limit 100 offset 100', 100, true); + + + +-- matching expression +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val + 1)', 1000, false); +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val + 1) desc', 1000, true); + +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val + 1) limit 100', 100, false); +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val + 1) desc limit 100', 100, true); + +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val + 1) limit 100 offset 100', 100, false); +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val + 1) desc limit 100 offset 100', 100, true); + +-- mismatching expression +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val - 1)', 1000, false); +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val - 1) desc', 1000, true); + +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val - 1) limit 100', 100, false); +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val - 1) desc limit 100', 100, true); + +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val - 1) limit 100 offset 100', 100, false); +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val - 1) desc limit 100 offset 100', 100, true); + + +-- matching expression +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''x'' || text_val)', 1000, false); +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''x'' || text_val) desc', 1000, true); + +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''x'' || text_val) limit 100', 100, false); +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''x'' || text_val) desc limit 100', 100, true); + +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''x'' || text_val) limit 100 offset 100', 100, false); +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''x'' || text_val) desc limit 100 offset 100', 100, true); + +-- mismatching expression +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''y'' || text_val)', 1000, false); +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''y'' || text_val) desc', 1000, true); + +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''y'' || text_val) limit 100', 100, false); +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''y'' || text_val) desc limit 100', 100, true); + +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''y'' || text_val) limit 100 offset 100', 100, false); +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''y'' || text_val) desc limit 100 offset 100', 100, true); + + +-- matching expression +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val + 1)', 1000, false); +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val + 1) desc', 1000, true); + +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val + 1) limit 100', 100, false); +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val + 1) desc limit 100', 100, true); + +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val + 1) limit 100 offset 100', 100, false); +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val + 1) desc limit 100 offset 100', 100, true); + +-- mismatching expression +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val - 1)', 1000, false); +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val - 1) desc', 1000, true); + +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val - 1) limit 100', 100, false); +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val - 1) desc limit 100', 100, true); + +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val - 1) limit 100 offset 100', 100, false); +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val - 1) desc limit 100 offset 100', 100, true); + + +-- semi-random data (sequential + randomness) +truncate table brin_sort_test; +insert into brin_sort_test +select + i + (100 * random())::int, + -(i + (100 * random())::int), -- same as int, but at least opposite + lpad((i + (100 * random())::int)::text || md5(i::text), 40, '0'), + '10.0.0.0'::inet + (i + 100 * random()::int) +from generate_series(1,1000) s(i); + +reindex table brin_sort_test; + +vacuum analyze brin_sort_test; + + +-- matching expression +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val + 1)', 1000, false); +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val + 1) desc', 1000, true); + +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val + 1) limit 100', 100, false); +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val + 1) desc limit 100', 100, true); + +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val + 1) limit 100 offset 100', 100, false); +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val + 1) desc limit 100 offset 100', 100, true); + +-- mismatching expression +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val - 1)', 1000, false); +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val - 1) desc', 1000, true); + +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val - 1) limit 100', 100, false); +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val - 1) desc limit 100', 100, true); + +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val - 1) limit 100 offset 100', 100, false); +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val - 1) desc limit 100 offset 100', 100, true); + + + +-- matching expression +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val + 1)', 1000, false); +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val + 1) desc', 1000, true); + +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val + 1) limit 100', 100, false); +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val + 1) desc limit 100', 100, true); + +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val + 1) limit 100 offset 100', 100, false); +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val + 1) desc limit 100 offset 100', 100, true); + +-- mismatching expression +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val - 1)', 1000, false); +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val - 1) desc', 1000, true); + +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val - 1) limit 100', 100, false); +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val - 1) desc limit 100', 100, true); + +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val - 1) limit 100 offset 100', 100, false); +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val - 1) desc limit 100 offset 100', 100, true); + + +-- matching expression +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''x'' || text_val)', 1000, false); +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''x'' || text_val) desc', 1000, true); + +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''x'' || text_val) limit 100', 100, false); +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''x'' || text_val) desc limit 100', 100, true); + +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''x'' || text_val) limit 100 offset 100', 100, false); +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''x'' || text_val) desc limit 100 offset 100', 100, true); + +-- mismatching expression +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''y'' || text_val)', 1000, false); +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''y'' || text_val) desc', 1000, true); + +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''y'' || text_val) limit 100', 100, false); +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''y'' || text_val) desc limit 100', 100, true); + +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''y'' || text_val) limit 100 offset 100', 100, false); +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''y'' || text_val) desc limit 100 offset 100', 100, true); + + +-- matching expression +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val + 1)', 1000, false); +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val + 1) desc', 1000, true); + +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val + 1) limit 100', 100, false); +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val + 1) desc limit 100', 100, true); + +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val + 1) limit 100 offset 100', 100, false); +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val + 1) desc limit 100 offset 100', 100, true); + +-- mismatching expression +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val - 1)', 1000, false); +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val - 1) desc', 1000, true); + +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val - 1) limit 100', 100, false); +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val - 1) desc limit 100', 100, true); + +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val - 1) limit 100 offset 100', 100, false); +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val - 1) desc limit 100 offset 100', 100, true); + + +-- random data +truncate table brin_sort_test; +insert into brin_sort_test +select + (1000 * random())::int, + -((1000 * random())::int), -- same as int, but at least opposite + lpad(((1000 * random())::int)::text || md5(i::text), 40, '0'), + '10.0.0.0'::inet + (1000 * random()::int) +from generate_series(1,1000) s(i); + +reindex table brin_sort_test; + +vacuum analyze brin_sort_test; + + +-- matching expression +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val + 1)', 1000, false); +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val + 1) desc', 1000, true); + +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val + 1) limit 100', 100, false); +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val + 1) desc limit 100', 100, true); + +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val + 1) limit 100 offset 100', 100, false); +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val + 1) desc limit 100 offset 100', 100, true); + +-- mismatching expression +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val - 1)', 1000, false); +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val - 1) desc', 1000, true); + +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val - 1) limit 100', 100, false); +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val - 1) desc limit 100', 100, true); + +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val - 1) limit 100 offset 100', 100, false); +select brinsort_check_ordering('select (int_val + 1) as val from brin_sort_test order by (int_val - 1) desc limit 100 offset 100', 100, true); + + + +-- matching expression +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val + 1)', 1000, false); +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val + 1) desc', 1000, true); + +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val + 1) limit 100', 100, false); +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val + 1) desc limit 100', 100, true); + +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val + 1) limit 100 offset 100', 100, false); +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val + 1) desc limit 100 offset 100', 100, true); + +-- mismatching expression +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val - 1)', 1000, false); +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val - 1) desc', 1000, true); + +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val - 1) limit 100', 100, false); +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val - 1) desc limit 100', 100, true); + +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val - 1) limit 100 offset 100', 100, false); +select brinsort_check_ordering('select (bigint_val + 1) as val from brin_sort_test order by (bigint_val - 1) desc limit 100 offset 100', 100, true); + + +-- matching expression +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''x'' || text_val)', 1000, false); +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''x'' || text_val) desc', 1000, true); + +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''x'' || text_val) limit 100', 100, false); +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''x'' || text_val) desc limit 100', 100, true); + +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''x'' || text_val) limit 100 offset 100', 100, false); +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''x'' || text_val) desc limit 100 offset 100', 100, true); + +-- mismatching expression +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''y'' || text_val)', 1000, false); +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''y'' || text_val) desc', 1000, true); + +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''y'' || text_val) limit 100', 100, false); +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''y'' || text_val) desc limit 100', 100, true); + +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''y'' || text_val) limit 100 offset 100', 100, false); +select brinsort_check_ordering('select (''x'' || text_val) as val from brin_sort_test order by (''y'' || text_val) desc limit 100 offset 100', 100, true); + + +-- matching expression +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val + 1)', 1000, false); +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val + 1) desc', 1000, true); + +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val + 1) limit 100', 100, false); +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val + 1) desc limit 100', 100, true); + +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val + 1) limit 100 offset 100', 100, false); +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val + 1) desc limit 100 offset 100', 100, true); + +-- mismatching expression +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val - 1)', 1000, false); +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val - 1) desc', 1000, true); + +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val - 1) limit 100', 100, false); +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val - 1) desc limit 100', 100, true); + +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val - 1) limit 100 offset 100', 100, false); +select brinsort_check_ordering('select (inet_val + 1) as val from brin_sort_test order by (inet_val - 1) desc limit 100 offset 100', 100, true); + + +drop table brin_sort_test; -- 2.39.2