From 323edd19b673f0ac7cf476d1ebf881b67272a7d2 Mon Sep 17 00:00:00 2001 From: Tomas Vondra Date: Sat, 18 Feb 2023 16:41:33 +0100 Subject: [PATCH 10/11] wip: add brinsort amstats regression tests --- .../regress/expected/brin_sort_amstats.out | 537 ++++++++++++ .../expected/brin_sort_exprs_amstats.out | 762 ++++++++++++++++++ .../expected/brin_sort_multi_amstats.out | 534 ++++++++++++ .../brin_sort_multi_exprs_amstats.out | 758 +++++++++++++++++ src/test/regress/parallel_schedule | 6 + src/test/regress/sql/brin_sort_amstats.sql | 240 ++++++ .../regress/sql/brin_sort_exprs_amstats.sql | 270 +++++++ .../regress/sql/brin_sort_multi_amstats.sql | 237 ++++++ .../sql/brin_sort_multi_exprs_amstats.sql | 265 ++++++ 9 files changed, 3609 insertions(+) create mode 100644 src/test/regress/expected/brin_sort_amstats.out create mode 100644 src/test/regress/expected/brin_sort_exprs_amstats.out create mode 100644 src/test/regress/expected/brin_sort_multi_amstats.out create mode 100644 src/test/regress/expected/brin_sort_multi_exprs_amstats.out create mode 100644 src/test/regress/sql/brin_sort_amstats.sql create mode 100644 src/test/regress/sql/brin_sort_exprs_amstats.sql create mode 100644 src/test/regress/sql/brin_sort_multi_amstats.sql create mode 100644 src/test/regress/sql/brin_sort_multi_exprs_amstats.sql diff --git a/src/test/regress/expected/brin_sort_amstats.out b/src/test/regress/expected/brin_sort_amstats.out new file mode 100644 index 0000000000..c3cba20502 --- /dev/null +++ b/src/test/regress/expected/brin_sort_amstats.out @@ -0,0 +1,537 @@ +set enable_indexam_stats = true; +-- 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_amstats.out b/src/test/regress/expected/brin_sort_exprs_amstats.out new file mode 100644 index 0000000000..b038f7ce01 --- /dev/null +++ b/src/test/regress/expected/brin_sort_exprs_amstats.out @@ -0,0 +1,762 @@ +set enable_indexam_stats = true; +-- 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 at RAISE +drop table brin_sort_test; diff --git a/src/test/regress/expected/brin_sort_multi_amstats.out b/src/test/regress/expected/brin_sort_multi_amstats.out new file mode 100644 index 0000000000..4e71f21cf3 --- /dev/null +++ b/src/test/regress/expected/brin_sort_multi_amstats.out @@ -0,0 +1,534 @@ +set enable_indexam_stats = true; +-- 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_amstats.out b/src/test/regress/expected/brin_sort_multi_exprs_amstats.out new file mode 100644 index 0000000000..2b9adfce62 --- /dev/null +++ b/src/test/regress/expected/brin_sort_multi_exprs_amstats.out @@ -0,0 +1,758 @@ +set enable_indexam_stats = true; +-- 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 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 24 at RAISE +drop table brin_sort_test; diff --git a/src/test/regress/parallel_schedule b/src/test/regress/parallel_schedule index 15ead24d4d..9b36202518 100644 --- a/src/test/regress/parallel_schedule +++ b/src/test/regress/parallel_schedule @@ -137,3 +137,9 @@ test: brin_sort test: brin_sort_multi test: brin_sort_exprs test: brin_sort_multi_exprs + +# try sorting using BRIN index with indexam stats +test: brin_sort_amstats +test: brin_sort_multi_amstats +test: brin_sort_exprs_amstats +test: brin_sort_multi_exprs_amstats diff --git a/src/test/regress/sql/brin_sort_amstats.sql b/src/test/regress/sql/brin_sort_amstats.sql new file mode 100644 index 0000000000..c3da189675 --- /dev/null +++ b/src/test/regress/sql/brin_sort_amstats.sql @@ -0,0 +1,240 @@ +set enable_indexam_stats = true; + +-- 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_amstats.sql b/src/test/regress/sql/brin_sort_exprs_amstats.sql new file mode 100644 index 0000000000..02a9f23f80 --- /dev/null +++ b/src/test/regress/sql/brin_sort_exprs_amstats.sql @@ -0,0 +1,270 @@ +set enable_indexam_stats = true; +-- 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_amstats.sql b/src/test/regress/sql/brin_sort_multi_amstats.sql new file mode 100644 index 0000000000..1bd8c7802e --- /dev/null +++ b/src/test/regress/sql/brin_sort_multi_amstats.sql @@ -0,0 +1,237 @@ +set enable_indexam_stats = true; + +-- 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_amstats.sql b/src/test/regress/sql/brin_sort_multi_exprs_amstats.sql new file mode 100644 index 0000000000..d91666642c --- /dev/null +++ b/src/test/regress/sql/brin_sort_multi_exprs_amstats.sql @@ -0,0 +1,265 @@ +set enable_indexam_stats = true; +-- 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.41.0