From 738c8b733799df74598103bee6d135fe5352e917 Mon Sep 17 00:00:00 2001 From: Karina Litskevich Date: Wed, 13 Nov 2024 10:24:35 +0300 Subject: [PATCH 1/2] [PGPRO-11556] Stabilize array test. Make this test output more independent of PostgreSQL server version and system. --- expected/array.out | 73 ++-- expected/array_1.out | 73 ++-- expected/array_2.out | 899 ------------------------------------------- expected/array_3.out | 892 ------------------------------------------ sql/array.sql | 41 +- 5 files changed, 128 insertions(+), 1850 deletions(-) delete mode 100644 expected/array_2.out delete mode 100644 expected/array_3.out diff --git a/expected/array.out b/expected/array.out index fe64c54f24..35ea87a5f8 100644 --- a/expected/array.out +++ b/expected/array.out @@ -7,12 +7,6 @@ * array.sql and array_1.sql * -------------------- * Test output for 64-bit and 32-bit systems respectively. - * - * -------------------- - * array_2.sql and array_3.sql - * -------------------- - * Since 6ed83d5fa55c in PostgreSQL 17, the order of rows - * in the output has been changed. */ set enable_seqscan=off; set enable_sort=off; @@ -859,41 +853,70 @@ EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i % '{}'; DROP INDEX idx_array; /* * Check ordering using distance operator + * + * The idea of the test: + * We want to check that index scan provides as correct ordering by distance + * operator. File 'data/rum_array.data' contains two arrays that statisfy + * i @> '{23,20}' and have finite distance i <=> '{51}', and a bunch of arrays + * that statisfy i @> '{23,20}' and have infinite distance i <=> '{51}'. When + * ordering by distance the order of this bunch of arrays with infinite + * distance is not determined and may depend of PostgreSQL version and system. + * Adding another sort expression to ORDER BY may cause another plan that + * doesn't use ordering provided by index. + * That's why we use the query you see below. We substitute 'Infinity' distance + * value with -1 because 'Infinity' are printed differently in output in + * different PostgreSQL versions. We substitute arrays that have infinite + * distance with {-1} because their order is undefined and we wnat to determine + * the test output. */ CREATE TABLE test_array_order ( i int2[] ); \copy test_array_order(i) from 'data/rum_array.data'; CREATE INDEX idx_array_order ON test_array_order USING rum (i rum_anyarray_ops); +/* Check that plan of the query uses ordering provided by index scan */ EXPLAIN (COSTS OFF) -SELECT *, i <=> '{51}' from test_array_order WHERE i @> '{23,20}' order by i <=> '{51}'; - QUERY PLAN ------------------------------------------------------- - Index Scan using idx_array_order on test_array_order - Index Cond: (i @> '{23,20}'::smallint[]) - Order By: (i <=> '{51}'::smallint[]) -(3 rows) +SELECT + CASE WHEN distance = 'Infinity' THEN '{-1}' + ELSE i + END i, + CASE WHEN distance = 'Infinity' THEN -1 + ELSE distance::numeric(18,14) + END distance + FROM + (SELECT *, (i <=> '{51}') AS distance + FROM test_array_order WHERE i @> '{23,20}' ORDER BY distance) t; + QUERY PLAN +------------------------------------------------------------ + Subquery Scan on t + -> Index Scan using idx_array_order on test_array_order + Index Cond: (i @> '{23,20}'::smallint[]) + Order By: (i <=> '{51}'::smallint[]) +(4 rows) -SELECT i, +SELECT + CASE WHEN distance = 'Infinity' THEN '{-1}' + ELSE i + END i, CASE WHEN distance = 'Infinity' THEN -1 ELSE distance::numeric(18,14) END distance FROM (SELECT *, (i <=> '{51}') AS distance - FROM test_array_order WHERE i @> '{23,20}' ORDER BY i <=> '{51}') t; + FROM test_array_order WHERE i @> '{23,20}' ORDER BY distance) t; i | distance ---------------------+------------------ {20,23,51} | 1.73205080756888 {33,51,20,77,23,65} | 2.44948974278318 - {23,76,34,23,2,20} | -1 - {20,60,45,23,29} | -1 - {23,89,38,20,40,95} | -1 - {23,20,72} | -1 - {73,23,20} | -1 - {6,97,20,89,23} | -1 - {20,98,30,23,1,66} | -1 - {57,23,39,46,50,20} | -1 - {81,20,26,22,23} | -1 - {18,23,10,90,15,20} | -1 + {-1} | -1 + {-1} | -1 + {-1} | -1 + {-1} | -1 + {-1} | -1 + {-1} | -1 + {-1} | -1 + {-1} | -1 + {-1} | -1 + {-1} | -1 (12 rows) diff --git a/expected/array_1.out b/expected/array_1.out index 3f3bf80bf0..4478dee5de 100644 --- a/expected/array_1.out +++ b/expected/array_1.out @@ -7,12 +7,6 @@ * array.sql and array_1.sql * -------------------- * Test output for 64-bit and 32-bit systems respectively. - * - * -------------------- - * array_2.sql and array_3.sql - * -------------------- - * Since 6ed83d5fa55c in PostgreSQL 17, the order of rows - * in the output has been changed. */ set enable_seqscan=off; set enable_sort=off; @@ -852,41 +846,70 @@ EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i % '{}'; DROP INDEX idx_array; /* * Check ordering using distance operator + * + * The idea of the test: + * We want to check that index scan provides as correct ordering by distance + * operator. File 'data/rum_array.data' contains two arrays that statisfy + * i @> '{23,20}' and have finite distance i <=> '{51}', and a bunch of arrays + * that statisfy i @> '{23,20}' and have infinite distance i <=> '{51}'. When + * ordering by distance the order of this bunch of arrays with infinite + * distance is not determined and may depend of PostgreSQL version and system. + * Adding another sort expression to ORDER BY may cause another plan that + * doesn't use ordering provided by index. + * That's why we use the query you see below. We substitute 'Infinity' distance + * value with -1 because 'Infinity' are printed differently in output in + * different PostgreSQL versions. We substitute arrays that have infinite + * distance with {-1} because their order is undefined and we wnat to determine + * the test output. */ CREATE TABLE test_array_order ( i int2[] ); \copy test_array_order(i) from 'data/rum_array.data'; CREATE INDEX idx_array_order ON test_array_order USING rum (i rum_anyarray_ops); +/* Check that plan of the query uses ordering provided by index scan */ EXPLAIN (COSTS OFF) -SELECT *, i <=> '{51}' from test_array_order WHERE i @> '{23,20}' order by i <=> '{51}'; - QUERY PLAN ------------------------------------------------------- - Index Scan using idx_array_order on test_array_order - Index Cond: (i @> '{23,20}'::smallint[]) - Order By: (i <=> '{51}'::smallint[]) -(3 rows) +SELECT + CASE WHEN distance = 'Infinity' THEN '{-1}' + ELSE i + END i, + CASE WHEN distance = 'Infinity' THEN -1 + ELSE distance::numeric(18,14) + END distance + FROM + (SELECT *, (i <=> '{51}') AS distance + FROM test_array_order WHERE i @> '{23,20}' ORDER BY distance) t; + QUERY PLAN +------------------------------------------------------------ + Subquery Scan on t + -> Index Scan using idx_array_order on test_array_order + Index Cond: (i @> '{23,20}'::smallint[]) + Order By: (i <=> '{51}'::smallint[]) +(4 rows) -SELECT i, +SELECT + CASE WHEN distance = 'Infinity' THEN '{-1}' + ELSE i + END i, CASE WHEN distance = 'Infinity' THEN -1 ELSE distance::numeric(18,14) END distance FROM (SELECT *, (i <=> '{51}') AS distance - FROM test_array_order WHERE i @> '{23,20}' ORDER BY i <=> '{51}') t; + FROM test_array_order WHERE i @> '{23,20}' ORDER BY distance) t; i | distance ---------------------+------------------ {20,23,51} | 1.73205080756888 {33,51,20,77,23,65} | 2.44948974278318 - {23,76,34,23,2,20} | -1 - {20,60,45,23,29} | -1 - {23,89,38,20,40,95} | -1 - {23,20,72} | -1 - {73,23,20} | -1 - {6,97,20,89,23} | -1 - {20,98,30,23,1,66} | -1 - {57,23,39,46,50,20} | -1 - {81,20,26,22,23} | -1 - {18,23,10,90,15,20} | -1 + {-1} | -1 + {-1} | -1 + {-1} | -1 + {-1} | -1 + {-1} | -1 + {-1} | -1 + {-1} | -1 + {-1} | -1 + {-1} | -1 + {-1} | -1 (12 rows) diff --git a/expected/array_2.out b/expected/array_2.out deleted file mode 100644 index 0097a5b5f4..0000000000 --- a/expected/array_2.out +++ /dev/null @@ -1,899 +0,0 @@ -/* - * --------------------------------------------- - * NOTE: This test behaves differenly on PgPro - * --------------------------------------------- - * - * -------------------- - * array.sql and array_1.sql - * -------------------- - * Test output for 64-bit and 32-bit systems respectively. - * - * -------------------- - * array_2.sql and array_3.sql - * -------------------- - * Since 6ed83d5fa55c in PostgreSQL 17, the order of rows - * in the output has been changed. - */ -set enable_seqscan=off; -set enable_sort=off; -/* - * Complete checks for int2[]. - */ -CREATE TABLE test_array ( - i int2[] -); -INSERT INTO test_array VALUES ('{}'), ('{0}'), ('{1,2,3,4}'), ('{1,2,3}'), ('{1,2}'), ('{1}'); -CREATE INDEX idx_array ON test_array USING rum (i rum_anyarray_ops); -SELECT NULL::int[] = '{1}'; - ?column? ----------- - -(1 row) - -SELECT NULL::int[] && '{1}'; - ?column? ----------- - -(1 row) - -SELECT NULL::int[] @> '{1}'; - ?column? ----------- - -(1 row) - -SELECT NULL::int[] <@ '{1}'; - ?column? ----------- - -(1 row) - -SELECT NULL::int[] % '{1}'; - ?column? ----------- - -(1 row) - -SELECT NULL::int[] <=> '{1}'; - ?column? ----------- - -(1 row) - -INSERT INTO test_array VALUES (NULL); -SELECT * FROM test_array WHERE i = '{1}'; - i ------ - {1} -(1 row) - -DELETE FROM test_array WHERE i IS NULL; -SELECT * FROM test_array WHERE i = '{NULL}'; -ERROR: array must not contain nulls -SELECT * FROM test_array WHERE i = '{1,2,3,NULL}'; -ERROR: array must not contain nulls -SELECT * FROM test_array WHERE i = '{{1,2},{3,4}}'; -ERROR: array must have 1 dimension -EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i = '{}'; - QUERY PLAN ------------------------------------------- - Index Scan using idx_array on test_array - Index Cond: (i = '{}'::smallint[]) -(2 rows) - -SELECT * FROM test_array WHERE i = '{}'; - i ----- - {} -(1 row) - -SELECT * FROM test_array WHERE i = '{0}'; - i ------ - {0} -(1 row) - -SELECT * FROM test_array WHERE i = '{1}'; - i ------ - {1} -(1 row) - -SELECT * FROM test_array WHERE i = '{1,2}'; - i -------- - {1,2} -(1 row) - -SELECT * FROM test_array WHERE i = '{2,1}'; - i ---- -(0 rows) - -SELECT * FROM test_array WHERE i = '{1,2,3,3}'; - i ---- -(0 rows) - -SELECT * FROM test_array WHERE i = '{0,0}'; - i ---- -(0 rows) - -SELECT * FROM test_array WHERE i = '{100}'; - i ---- -(0 rows) - -EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i && '{}'; - QUERY PLAN ------------------------------------------- - Index Scan using idx_array on test_array - Index Cond: (i && '{}'::smallint[]) -(2 rows) - -SELECT * FROM test_array WHERE i && '{}'; - i ---- -(0 rows) - -SELECT * FROM test_array WHERE i && '{1}'; - i ------------ - {1,2,3,4} - {1,2,3} - {1,2} - {1} -(4 rows) - -SELECT * FROM test_array WHERE i && '{2}'; - i ------------ - {1,2,3,4} - {1,2,3} - {1,2} -(3 rows) - -SELECT * FROM test_array WHERE i && '{3}'; - i ------------ - {1,2,3,4} - {1,2,3} -(2 rows) - -SELECT * FROM test_array WHERE i && '{4}'; - i ------------ - {1,2,3,4} -(1 row) - -SELECT * FROM test_array WHERE i && '{1,2}'; - i ------------ - {1,2,3,4} - {1,2,3} - {1,2} - {1} -(4 rows) - -SELECT * FROM test_array WHERE i && '{1,2,3}'; - i ------------ - {1,2,3,4} - {1,2,3} - {1,2} - {1} -(4 rows) - -SELECT * FROM test_array WHERE i && '{1,2,3,4}'; - i ------------ - {1,2,3,4} - {1,2,3} - {1,2} - {1} -(4 rows) - -SELECT * FROM test_array WHERE i && '{4,3,2,1}'; - i ------------ - {1,2,3,4} - {1,2,3} - {1,2} - {1} -(4 rows) - -SELECT * FROM test_array WHERE i && '{0,0}'; - i ------ - {0} -(1 row) - -SELECT * FROM test_array WHERE i && '{100}'; - i ---- -(0 rows) - -EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i @> '{}'; - QUERY PLAN ------------------------------------------- - Index Scan using idx_array on test_array - Index Cond: (i @> '{}'::smallint[]) -(2 rows) - -SELECT * FROM test_array WHERE i @> '{}'; - i ------------ - {} - {0} - {1,2,3,4} - {1,2,3} - {1,2} - {1} -(6 rows) - -SELECT * FROM test_array WHERE i @> '{1}'; - i ------------ - {1,2,3,4} - {1,2,3} - {1,2} - {1} -(4 rows) - -SELECT * FROM test_array WHERE i @> '{2}'; - i ------------ - {1,2,3,4} - {1,2,3} - {1,2} -(3 rows) - -SELECT * FROM test_array WHERE i @> '{3}'; - i ------------ - {1,2,3,4} - {1,2,3} -(2 rows) - -SELECT * FROM test_array WHERE i @> '{4}'; - i ------------ - {1,2,3,4} -(1 row) - -SELECT * FROM test_array WHERE i @> '{1,2,4}'; - i ------------ - {1,2,3,4} -(1 row) - -SELECT * FROM test_array WHERE i @> '{1,2,3,4}'; - i ------------ - {1,2,3,4} -(1 row) - -SELECT * FROM test_array WHERE i @> '{4,3,2,1}'; - i ------------ - {1,2,3,4} -(1 row) - -SELECT * FROM test_array WHERE i @> '{0,0}'; - i ------ - {0} -(1 row) - -SELECT * FROM test_array WHERE i @> '{100}'; - i ---- -(0 rows) - -EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i <@ '{}'; - QUERY PLAN ------------------------------------------- - Index Scan using idx_array on test_array - Index Cond: (i <@ '{}'::smallint[]) -(2 rows) - -SELECT * FROM test_array WHERE i <@ '{}'; - i ----- - {} -(1 row) - -SELECT * FROM test_array WHERE i <@ '{1}'; - i ------ - {} - {1} -(2 rows) - -SELECT * FROM test_array WHERE i <@ '{2}'; - i ----- - {} -(1 row) - -SELECT * FROM test_array WHERE i <@ '{1,2,4}'; - i -------- - {} - {1,2} - {1} -(3 rows) - -SELECT * FROM test_array WHERE i <@ '{1,2,3,4}'; - i ------------ - {} - {1,2,3,4} - {1,2,3} - {1,2} - {1} -(5 rows) - -SELECT * FROM test_array WHERE i <@ '{4,3,2,1}'; - i ------------ - {} - {1,2,3,4} - {1,2,3} - {1,2} - {1} -(5 rows) - -SELECT * FROM test_array WHERE i <@ '{0,0}'; - i ------ - {} - {0} -(2 rows) - -SELECT * FROM test_array WHERE i <@ '{100}'; - i ----- - {} -(1 row) - -EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i % '{}'; - QUERY PLAN ------------------------------------------- - Index Scan using idx_array on test_array - Index Cond: (i % '{}'::smallint[]) -(2 rows) - -SELECT * FROM test_array WHERE i % '{}'; - i ---- -(0 rows) - -SELECT * FROM test_array WHERE i % '{1}'; - i ------------ - {1,2,3,4} - {1,2,3} - {1,2} - {1} -(4 rows) - -SELECT * FROM test_array WHERE i % '{2}'; - i ------------ - {1,2,3,4} - {1,2,3} - {1,2} -(3 rows) - -SELECT * FROM test_array WHERE i % '{1,2}'; - i ------------ - {1,2,3,4} - {1,2,3} - {1,2} - {1} -(4 rows) - -SELECT * FROM test_array WHERE i % '{1,2,4}'; - i ------------ - {1,2,3,4} - {1,2,3} - {1,2} - {1} -(4 rows) - -SELECT * FROM test_array WHERE i % '{1,2,3,4}'; - i ------------ - {1,2,3,4} - {1,2,3} - {1,2} - {1} -(4 rows) - -SELECT * FROM test_array WHERE i % '{4,3,2,1}'; - i ------------ - {1,2,3,4} - {1,2,3} - {1,2} - {1} -(4 rows) - -SELECT * FROM test_array WHERE i % '{1,2,3,4,5}'; - i ------------ - {1,2,3,4} - {1,2,3} - {1,2} -(3 rows) - -SELECT * FROM test_array WHERE i % '{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}'; - i ------------ - {1,2,3,4} -(1 row) - -SELECT * FROM test_array WHERE i % '{1,10,20,30,40,50}'; - i ---- -(0 rows) - -SELECT * FROM test_array WHERE i % '{1,10,20,30}'; - i ------ - {1} -(1 row) - -SELECT * FROM test_array WHERE i % '{1,1,1,1,1}'; - i ------------ - {1,2,3,4} - {1,2,3} - {1,2} - {1} -(4 rows) - -SELECT * FROM test_array WHERE i % '{0,0}'; - i ------ - {0} -(1 row) - -SELECT * FROM test_array WHERE i % '{100}'; - i ---- -(0 rows) - -EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i && '{1}' ORDER BY i <=> '{1}' ASC; - QUERY PLAN ------------------------------------------- - Index Scan using idx_array on test_array - Index Cond: (i && '{1}'::smallint[]) - Order By: (i <=> '{1}'::smallint[]) -(3 rows) - -SELECT * FROM test_array WHERE i && '{1}' ORDER BY i <=> '{1}' ASC; - i ------------ - {1} - {1,2} - {1,2,3} - {1,2,3,4} -(4 rows) - -DROP INDEX idx_array; -ALTER TABLE test_array ADD COLUMN add_info timestamp; -CREATE INDEX idx_array ON test_array -USING rum (i rum_anyarray_addon_ops, add_info) -WITH (attach = 'add_info', to = 'i'); -WITH q as ( - SELECT row_number() OVER (ORDER BY i) idx, ctid FROM test_array -) -UPDATE test_array SET add_info = '2016-05-16 14:21:25'::timestamp + - format('%s days', q.idx)::interval -FROM q WHERE test_array.ctid = q.ctid; -EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i = '{}'; - QUERY PLAN ------------------------------------------- - Index Scan using idx_array on test_array - Index Cond: (i = '{}'::smallint[]) -(2 rows) - -EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i && '{}'; - QUERY PLAN ------------------------------------------- - Index Scan using idx_array on test_array - Index Cond: (i && '{}'::smallint[]) -(2 rows) - -EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i @> '{}'; - QUERY PLAN ------------------------------------------- - Index Scan using idx_array on test_array - Index Cond: (i @> '{}'::smallint[]) -(2 rows) - -EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i <@ '{}'; - QUERY PLAN ------------------------------------------- - Index Scan using idx_array on test_array - Index Cond: (i <@ '{}'::smallint[]) -(2 rows) - -EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i % '{}'; - QUERY PLAN ----------------------------------- - Seq Scan on test_array - Filter: (i % '{}'::smallint[]) -(2 rows) - -EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i && '{1}' ORDER BY add_info <=> '2016-05-16 14:21:25' LIMIT 10; - QUERY PLAN ------------------------------------------------------------------------------------------- - Limit - -> Index Scan using idx_array on test_array - Index Cond: (i && '{1}'::smallint[]) - Order By: (add_info <=> 'Mon May 16 14:21:25 2016'::timestamp without time zone) -(4 rows) - -SELECT * FROM test_array WHERE i && '{1}' ORDER BY add_info <=> '2016-05-16 14:21:25' LIMIT 10; - i | add_info ------------+-------------------------- - {1} | Thu May 19 14:21:25 2016 - {1,2} | Fri May 20 14:21:25 2016 - {1,2,3} | Sat May 21 14:21:25 2016 - {1,2,3,4} | Sun May 22 14:21:25 2016 -(4 rows) - -DROP INDEX idx_array; -/* - * Sanity checks for popular array types. - */ -ALTER TABLE test_array ALTER COLUMN i TYPE int4[]; -CREATE INDEX idx_array ON test_array USING rum (i rum_anyarray_ops); -EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i = '{}'; - QUERY PLAN ------------------------------------------- - Index Scan using idx_array on test_array - Index Cond: (i = '{}'::integer[]) -(2 rows) - -EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i && '{}'; - QUERY PLAN ------------------------------------------- - Index Scan using idx_array on test_array - Index Cond: (i && '{}'::integer[]) -(2 rows) - -EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i @> '{}'; - QUERY PLAN ------------------------------------------- - Index Scan using idx_array on test_array - Index Cond: (i @> '{}'::integer[]) -(2 rows) - -EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i <@ '{}'; - QUERY PLAN ------------------------------------------- - Index Scan using idx_array on test_array - Index Cond: (i <@ '{}'::integer[]) -(2 rows) - -EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i % '{}'; - QUERY PLAN ------------------------------------------- - Index Scan using idx_array on test_array - Index Cond: (i % '{}'::integer[]) -(2 rows) - -DROP INDEX idx_array; -ALTER TABLE test_array ALTER COLUMN i TYPE int8[]; -CREATE INDEX idx_array ON test_array USING rum (i rum_anyarray_ops); -EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i = '{}'; - QUERY PLAN ------------------------------------------- - Index Scan using idx_array on test_array - Index Cond: (i = '{}'::bigint[]) -(2 rows) - -EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i && '{}'; - QUERY PLAN ------------------------------------------- - Index Scan using idx_array on test_array - Index Cond: (i && '{}'::bigint[]) -(2 rows) - -EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i @> '{}'; - QUERY PLAN ------------------------------------------- - Index Scan using idx_array on test_array - Index Cond: (i @> '{}'::bigint[]) -(2 rows) - -EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i <@ '{}'; - QUERY PLAN ------------------------------------------- - Index Scan using idx_array on test_array - Index Cond: (i <@ '{}'::bigint[]) -(2 rows) - -EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i % '{}'; - QUERY PLAN ------------------------------------------- - Index Scan using idx_array on test_array - Index Cond: (i % '{}'::bigint[]) -(2 rows) - -DROP INDEX idx_array; -ALTER TABLE test_array ALTER COLUMN i TYPE text[]; -CREATE INDEX idx_array ON test_array USING rum (i rum_anyarray_ops); -EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i = '{}'; - QUERY PLAN ------------------------------------------- - Index Scan using idx_array on test_array - Index Cond: (i = '{}'::text[]) -(2 rows) - -EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i && '{}'; - QUERY PLAN ------------------------------------------- - Index Scan using idx_array on test_array - Index Cond: (i && '{}'::text[]) -(2 rows) - -EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i @> '{}'; - QUERY PLAN ------------------------------------------- - Index Scan using idx_array on test_array - Index Cond: (i @> '{}'::text[]) -(2 rows) - -EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i <@ '{}'; - QUERY PLAN ------------------------------------------- - Index Scan using idx_array on test_array - Index Cond: (i <@ '{}'::text[]) -(2 rows) - -EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i % '{}'; - QUERY PLAN ------------------------------------------- - Index Scan using idx_array on test_array - Index Cond: (i % '{}'::text[]) -(2 rows) - -DROP INDEX idx_array; -ALTER TABLE test_array ALTER COLUMN i TYPE varchar[]; -CREATE INDEX idx_array ON test_array USING rum (i rum_anyarray_ops); -EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i = '{}'; - QUERY PLAN ------------------------------------------------ - Index Scan using idx_array on test_array - Index Cond: (i = '{}'::character varying[]) -(2 rows) - -EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i && '{}'; - QUERY PLAN ------------------------------------------------- - Index Scan using idx_array on test_array - Index Cond: (i && '{}'::character varying[]) -(2 rows) - -EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i @> '{}'; - QUERY PLAN ------------------------------------------------- - Index Scan using idx_array on test_array - Index Cond: (i @> '{}'::character varying[]) -(2 rows) - -EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i <@ '{}'; - QUERY PLAN ------------------------------------------------- - Index Scan using idx_array on test_array - Index Cond: (i <@ '{}'::character varying[]) -(2 rows) - -EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i % '{}'; - QUERY PLAN ------------------------------------------------ - Index Scan using idx_array on test_array - Index Cond: (i % '{}'::character varying[]) -(2 rows) - -DROP INDEX idx_array; -ALTER TABLE test_array ALTER COLUMN i TYPE char[]; -CREATE INDEX idx_array ON test_array USING rum (i rum_anyarray_ops); -EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i = '{}'; - QUERY PLAN ------------------------------------------- - Index Scan using idx_array on test_array - Index Cond: (i = '{}'::bpchar[]) -(2 rows) - -EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i && '{}'; - QUERY PLAN ------------------------------------------- - Index Scan using idx_array on test_array - Index Cond: (i && '{}'::bpchar[]) -(2 rows) - -EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i @> '{}'; - QUERY PLAN ------------------------------------------- - Index Scan using idx_array on test_array - Index Cond: (i @> '{}'::bpchar[]) -(2 rows) - -EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i <@ '{}'; - QUERY PLAN ------------------------------------------- - Index Scan using idx_array on test_array - Index Cond: (i <@ '{}'::bpchar[]) -(2 rows) - -EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i % '{}'; - QUERY PLAN ------------------------------------------- - Index Scan using idx_array on test_array - Index Cond: (i % '{}'::bpchar[]) -(2 rows) - -DROP INDEX idx_array; -ALTER TABLE test_array ALTER COLUMN i TYPE numeric[] USING i::numeric[]; -CREATE INDEX idx_array ON test_array USING rum (i rum_anyarray_ops); -EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i = '{}'; - QUERY PLAN ------------------------------------------- - Index Scan using idx_array on test_array - Index Cond: (i = '{}'::numeric[]) -(2 rows) - -EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i && '{}'; - QUERY PLAN ------------------------------------------- - Index Scan using idx_array on test_array - Index Cond: (i && '{}'::numeric[]) -(2 rows) - -EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i @> '{}'; - QUERY PLAN ------------------------------------------- - Index Scan using idx_array on test_array - Index Cond: (i @> '{}'::numeric[]) -(2 rows) - -EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i <@ '{}'; - QUERY PLAN ------------------------------------------- - Index Scan using idx_array on test_array - Index Cond: (i <@ '{}'::numeric[]) -(2 rows) - -EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i % '{}'; - QUERY PLAN ------------------------------------------- - Index Scan using idx_array on test_array - Index Cond: (i % '{}'::numeric[]) -(2 rows) - -DROP INDEX idx_array; -ALTER TABLE test_array ALTER COLUMN i TYPE float4[] USING i::float4[]; -CREATE INDEX idx_array ON test_array USING rum (i rum_anyarray_ops); -EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i = '{}'; - QUERY PLAN ------------------------------------------- - Index Scan using idx_array on test_array - Index Cond: (i = '{}'::real[]) -(2 rows) - -EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i && '{}'; - QUERY PLAN ------------------------------------------- - Index Scan using idx_array on test_array - Index Cond: (i && '{}'::real[]) -(2 rows) - -EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i @> '{}'; - QUERY PLAN ------------------------------------------- - Index Scan using idx_array on test_array - Index Cond: (i @> '{}'::real[]) -(2 rows) - -EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i <@ '{}'; - QUERY PLAN ------------------------------------------- - Index Scan using idx_array on test_array - Index Cond: (i <@ '{}'::real[]) -(2 rows) - -EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i % '{}'; - QUERY PLAN ------------------------------------------- - Index Scan using idx_array on test_array - Index Cond: (i % '{}'::real[]) -(2 rows) - -DROP INDEX idx_array; -ALTER TABLE test_array ALTER COLUMN i TYPE float8[] USING i::float8[]; -CREATE INDEX idx_array ON test_array USING rum (i rum_anyarray_ops); -EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i = '{}'; - QUERY PLAN ----------------------------------------------- - Index Scan using idx_array on test_array - Index Cond: (i = '{}'::double precision[]) -(2 rows) - -EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i && '{}'; - QUERY PLAN ------------------------------------------------ - Index Scan using idx_array on test_array - Index Cond: (i && '{}'::double precision[]) -(2 rows) - -EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i @> '{}'; - QUERY PLAN ------------------------------------------------ - Index Scan using idx_array on test_array - Index Cond: (i @> '{}'::double precision[]) -(2 rows) - -EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i <@ '{}'; - QUERY PLAN ------------------------------------------------ - Index Scan using idx_array on test_array - Index Cond: (i <@ '{}'::double precision[]) -(2 rows) - -EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i % '{}'; - QUERY PLAN ----------------------------------------------- - Index Scan using idx_array on test_array - Index Cond: (i % '{}'::double precision[]) -(2 rows) - -DROP INDEX idx_array; -/* - * Check ordering using distance operator - */ -CREATE TABLE test_array_order ( - i int2[] -); -\copy test_array_order(i) from 'data/rum_array.data'; -CREATE INDEX idx_array_order ON test_array_order USING rum (i rum_anyarray_ops); -EXPLAIN (COSTS OFF) -SELECT *, i <=> '{51}' from test_array_order WHERE i @> '{23,20}' order by i <=> '{51}'; - QUERY PLAN ------------------------------------------------------- - Index Scan using idx_array_order on test_array_order - Index Cond: (i @> '{23,20}'::smallint[]) - Order By: (i <=> '{51}'::smallint[]) -(3 rows) - -SELECT i, - CASE WHEN distance = 'Infinity' THEN -1 - ELSE distance::numeric(18,14) - END distance - FROM - (SELECT *, (i <=> '{51}') AS distance - FROM test_array_order WHERE i @> '{23,20}' ORDER BY i <=> '{51}') t; - i | distance ----------------------+------------------ - {20,23,51} | 1.73205080756888 - {33,51,20,77,23,65} | 2.44948974278318 - {6,97,20,89,23} | -1 - {20,98,30,23,1,66} | -1 - {57,23,39,46,50,20} | -1 - {81,20,26,22,23} | -1 - {73,23,20} | -1 - {18,23,10,90,15,20} | -1 - {23,76,34,23,2,20} | -1 - {20,60,45,23,29} | -1 - {23,89,38,20,40,95} | -1 - {23,20,72} | -1 -(12 rows) - diff --git a/expected/array_3.out b/expected/array_3.out deleted file mode 100644 index d5012c3a38..0000000000 --- a/expected/array_3.out +++ /dev/null @@ -1,892 +0,0 @@ -/* - * --------------------------------------------- - * NOTE: This test behaves differenly on PgPro - * --------------------------------------------- - * - * -------------------- - * array.sql and array_1.sql - * -------------------- - * Test output for 64-bit and 32-bit systems respectively. - * - * -------------------- - * array_2.sql and array_3.sql - * -------------------- - * Since 6ed83d5fa55c in PostgreSQL 17, the order of rows - * in the output has been changed. - */ -set enable_seqscan=off; -set enable_sort=off; -/* - * Complete checks for int2[]. - */ -CREATE TABLE test_array ( - i int2[] -); -INSERT INTO test_array VALUES ('{}'), ('{0}'), ('{1,2,3,4}'), ('{1,2,3}'), ('{1,2}'), ('{1}'); -CREATE INDEX idx_array ON test_array USING rum (i rum_anyarray_ops); -SELECT NULL::int[] = '{1}'; - ?column? ----------- - -(1 row) - -SELECT NULL::int[] && '{1}'; - ?column? ----------- - -(1 row) - -SELECT NULL::int[] @> '{1}'; - ?column? ----------- - -(1 row) - -SELECT NULL::int[] <@ '{1}'; - ?column? ----------- - -(1 row) - -SELECT NULL::int[] % '{1}'; - ?column? ----------- - -(1 row) - -SELECT NULL::int[] <=> '{1}'; - ?column? ----------- - -(1 row) - -INSERT INTO test_array VALUES (NULL); -SELECT * FROM test_array WHERE i = '{1}'; - i ------ - {1} -(1 row) - -DELETE FROM test_array WHERE i IS NULL; -SELECT * FROM test_array WHERE i = '{NULL}'; -ERROR: array must not contain nulls -SELECT * FROM test_array WHERE i = '{1,2,3,NULL}'; -ERROR: array must not contain nulls -SELECT * FROM test_array WHERE i = '{{1,2},{3,4}}'; -ERROR: array must have 1 dimension -EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i = '{}'; - QUERY PLAN ------------------------------------------- - Index Scan using idx_array on test_array - Index Cond: (i = '{}'::smallint[]) -(2 rows) - -SELECT * FROM test_array WHERE i = '{}'; - i ----- - {} -(1 row) - -SELECT * FROM test_array WHERE i = '{0}'; - i ------ - {0} -(1 row) - -SELECT * FROM test_array WHERE i = '{1}'; - i ------ - {1} -(1 row) - -SELECT * FROM test_array WHERE i = '{1,2}'; - i -------- - {1,2} -(1 row) - -SELECT * FROM test_array WHERE i = '{2,1}'; - i ---- -(0 rows) - -SELECT * FROM test_array WHERE i = '{1,2,3,3}'; - i ---- -(0 rows) - -SELECT * FROM test_array WHERE i = '{0,0}'; - i ---- -(0 rows) - -SELECT * FROM test_array WHERE i = '{100}'; - i ---- -(0 rows) - -EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i && '{}'; - QUERY PLAN ------------------------------------------- - Index Scan using idx_array on test_array - Index Cond: (i && '{}'::smallint[]) -(2 rows) - -SELECT * FROM test_array WHERE i && '{}'; - i ---- -(0 rows) - -SELECT * FROM test_array WHERE i && '{1}'; - i ------------ - {1,2,3,4} - {1,2,3} - {1,2} - {1} -(4 rows) - -SELECT * FROM test_array WHERE i && '{2}'; - i ------------ - {1,2,3,4} - {1,2,3} - {1,2} -(3 rows) - -SELECT * FROM test_array WHERE i && '{3}'; - i ------------ - {1,2,3,4} - {1,2,3} -(2 rows) - -SELECT * FROM test_array WHERE i && '{4}'; - i ------------ - {1,2,3,4} -(1 row) - -SELECT * FROM test_array WHERE i && '{1,2}'; - i ------------ - {1,2,3,4} - {1,2,3} - {1,2} - {1} -(4 rows) - -SELECT * FROM test_array WHERE i && '{1,2,3}'; - i ------------ - {1,2,3,4} - {1,2,3} - {1,2} - {1} -(4 rows) - -SELECT * FROM test_array WHERE i && '{1,2,3,4}'; - i ------------ - {1,2,3,4} - {1,2,3} - {1,2} - {1} -(4 rows) - -SELECT * FROM test_array WHERE i && '{4,3,2,1}'; - i ------------ - {1,2,3,4} - {1,2,3} - {1,2} - {1} -(4 rows) - -SELECT * FROM test_array WHERE i && '{0,0}'; - i ------ - {0} -(1 row) - -SELECT * FROM test_array WHERE i && '{100}'; - i ---- -(0 rows) - -EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i @> '{}'; - QUERY PLAN ------------------------------------------- - Index Scan using idx_array on test_array - Index Cond: (i @> '{}'::smallint[]) -(2 rows) - -SELECT * FROM test_array WHERE i @> '{}'; - i ------------ - {} - {0} - {1,2,3,4} - {1,2,3} - {1,2} - {1} -(6 rows) - -SELECT * FROM test_array WHERE i @> '{1}'; - i ------------ - {1,2,3,4} - {1,2,3} - {1,2} - {1} -(4 rows) - -SELECT * FROM test_array WHERE i @> '{2}'; - i ------------ - {1,2,3,4} - {1,2,3} - {1,2} -(3 rows) - -SELECT * FROM test_array WHERE i @> '{3}'; - i ------------ - {1,2,3,4} - {1,2,3} -(2 rows) - -SELECT * FROM test_array WHERE i @> '{4}'; - i ------------ - {1,2,3,4} -(1 row) - -SELECT * FROM test_array WHERE i @> '{1,2,4}'; - i ------------ - {1,2,3,4} -(1 row) - -SELECT * FROM test_array WHERE i @> '{1,2,3,4}'; - i ------------ - {1,2,3,4} -(1 row) - -SELECT * FROM test_array WHERE i @> '{4,3,2,1}'; - i ------------ - {1,2,3,4} -(1 row) - -SELECT * FROM test_array WHERE i @> '{0,0}'; - i ------ - {0} -(1 row) - -SELECT * FROM test_array WHERE i @> '{100}'; - i ---- -(0 rows) - -EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i <@ '{}'; - QUERY PLAN ------------------------------------------- - Index Scan using idx_array on test_array - Index Cond: (i <@ '{}'::smallint[]) -(2 rows) - -SELECT * FROM test_array WHERE i <@ '{}'; - i ----- - {} -(1 row) - -SELECT * FROM test_array WHERE i <@ '{1}'; - i ------ - {} - {1} -(2 rows) - -SELECT * FROM test_array WHERE i <@ '{2}'; - i ----- - {} -(1 row) - -SELECT * FROM test_array WHERE i <@ '{1,2,4}'; - i -------- - {} - {1,2} - {1} -(3 rows) - -SELECT * FROM test_array WHERE i <@ '{1,2,3,4}'; - i ------------ - {} - {1,2,3,4} - {1,2,3} - {1,2} - {1} -(5 rows) - -SELECT * FROM test_array WHERE i <@ '{4,3,2,1}'; - i ------------ - {} - {1,2,3,4} - {1,2,3} - {1,2} - {1} -(5 rows) - -SELECT * FROM test_array WHERE i <@ '{0,0}'; - i ------ - {} - {0} -(2 rows) - -SELECT * FROM test_array WHERE i <@ '{100}'; - i ----- - {} -(1 row) - -EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i % '{}'; - QUERY PLAN ------------------------------------------- - Index Scan using idx_array on test_array - Index Cond: (i % '{}'::smallint[]) -(2 rows) - -SELECT * FROM test_array WHERE i % '{}'; - i ---- -(0 rows) - -SELECT * FROM test_array WHERE i % '{1}'; - i ------------ - {1,2,3,4} - {1,2,3} - {1,2} - {1} -(4 rows) - -SELECT * FROM test_array WHERE i % '{2}'; - i ------------ - {1,2,3,4} - {1,2,3} - {1,2} -(3 rows) - -SELECT * FROM test_array WHERE i % '{1,2}'; - i ------------ - {1,2,3,4} - {1,2,3} - {1,2} - {1} -(4 rows) - -SELECT * FROM test_array WHERE i % '{1,2,4}'; - i ------------ - {1,2,3,4} - {1,2,3} - {1,2} - {1} -(4 rows) - -SELECT * FROM test_array WHERE i % '{1,2,3,4}'; - i ------------ - {1,2,3,4} - {1,2,3} - {1,2} - {1} -(4 rows) - -SELECT * FROM test_array WHERE i % '{4,3,2,1}'; - i ------------ - {1,2,3,4} - {1,2,3} - {1,2} - {1} -(4 rows) - -SELECT * FROM test_array WHERE i % '{1,2,3,4,5}'; - i ------------ - {1,2,3,4} - {1,2,3} - {1,2} -(3 rows) - -SELECT * FROM test_array WHERE i % '{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}'; - i ------------ - {1,2,3,4} -(1 row) - -SELECT * FROM test_array WHERE i % '{1,10,20,30,40,50}'; - i ---- -(0 rows) - -SELECT * FROM test_array WHERE i % '{1,10,20,30}'; - i ------ - {1} -(1 row) - -SELECT * FROM test_array WHERE i % '{1,1,1,1,1}'; - i ------------ - {1,2,3,4} - {1,2,3} - {1,2} - {1} -(4 rows) - -SELECT * FROM test_array WHERE i % '{0,0}'; - i ------ - {0} -(1 row) - -SELECT * FROM test_array WHERE i % '{100}'; - i ---- -(0 rows) - -EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i && '{1}' ORDER BY i <=> '{1}' ASC; - QUERY PLAN ------------------------------------------- - Index Scan using idx_array on test_array - Index Cond: (i && '{1}'::smallint[]) - Order By: (i <=> '{1}'::smallint[]) -(3 rows) - -SELECT * FROM test_array WHERE i && '{1}' ORDER BY i <=> '{1}' ASC; - i ------------ - {1} - {1,2} - {1,2,3} - {1,2,3,4} -(4 rows) - -DROP INDEX idx_array; -ALTER TABLE test_array ADD COLUMN add_info timestamp; -CREATE INDEX idx_array ON test_array -USING rum (i rum_anyarray_addon_ops, add_info) -WITH (attach = 'add_info', to = 'i'); -WITH q as ( - SELECT row_number() OVER (ORDER BY i) idx, ctid FROM test_array -) -UPDATE test_array SET add_info = '2016-05-16 14:21:25'::timestamp + - format('%s days', q.idx)::interval -FROM q WHERE test_array.ctid = q.ctid; -EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i = '{}'; - QUERY PLAN ------------------------------------------- - Index Scan using idx_array on test_array - Index Cond: (i = '{}'::smallint[]) -(2 rows) - -EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i && '{}'; - QUERY PLAN ------------------------------------------- - Index Scan using idx_array on test_array - Index Cond: (i && '{}'::smallint[]) -(2 rows) - -EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i @> '{}'; - QUERY PLAN ------------------------------------------- - Index Scan using idx_array on test_array - Index Cond: (i @> '{}'::smallint[]) -(2 rows) - -EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i <@ '{}'; - QUERY PLAN ------------------------------------------- - Index Scan using idx_array on test_array - Index Cond: (i <@ '{}'::smallint[]) -(2 rows) - -EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i % '{}'; - QUERY PLAN ----------------------------------- - Seq Scan on test_array - Filter: (i % '{}'::smallint[]) -(2 rows) - -EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i && '{1}' ORDER BY add_info <=> '2016-05-16 14:21:25' LIMIT 10; - QUERY PLAN ------------------------------------------------------------------------------------------- - Limit - -> Index Scan using idx_array on test_array - Index Cond: (i && '{1}'::smallint[]) - Order By: (add_info <=> 'Mon May 16 14:21:25 2016'::timestamp without time zone) -(4 rows) - -SELECT * FROM test_array WHERE i && '{1}' ORDER BY add_info <=> '2016-05-16 14:21:25' LIMIT 10; -ERROR: doesn't support order by over pass-by-reference column -DROP INDEX idx_array; -/* - * Sanity checks for popular array types. - */ -ALTER TABLE test_array ALTER COLUMN i TYPE int4[]; -CREATE INDEX idx_array ON test_array USING rum (i rum_anyarray_ops); -EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i = '{}'; - QUERY PLAN ------------------------------------------- - Index Scan using idx_array on test_array - Index Cond: (i = '{}'::integer[]) -(2 rows) - -EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i && '{}'; - QUERY PLAN ------------------------------------------- - Index Scan using idx_array on test_array - Index Cond: (i && '{}'::integer[]) -(2 rows) - -EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i @> '{}'; - QUERY PLAN ------------------------------------------- - Index Scan using idx_array on test_array - Index Cond: (i @> '{}'::integer[]) -(2 rows) - -EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i <@ '{}'; - QUERY PLAN ------------------------------------------- - Index Scan using idx_array on test_array - Index Cond: (i <@ '{}'::integer[]) -(2 rows) - -EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i % '{}'; - QUERY PLAN ------------------------------------------- - Index Scan using idx_array on test_array - Index Cond: (i % '{}'::integer[]) -(2 rows) - -DROP INDEX idx_array; -ALTER TABLE test_array ALTER COLUMN i TYPE int8[]; -CREATE INDEX idx_array ON test_array USING rum (i rum_anyarray_ops); -EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i = '{}'; - QUERY PLAN ------------------------------------------- - Index Scan using idx_array on test_array - Index Cond: (i = '{}'::bigint[]) -(2 rows) - -EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i && '{}'; - QUERY PLAN ------------------------------------------- - Index Scan using idx_array on test_array - Index Cond: (i && '{}'::bigint[]) -(2 rows) - -EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i @> '{}'; - QUERY PLAN ------------------------------------------- - Index Scan using idx_array on test_array - Index Cond: (i @> '{}'::bigint[]) -(2 rows) - -EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i <@ '{}'; - QUERY PLAN ------------------------------------------- - Index Scan using idx_array on test_array - Index Cond: (i <@ '{}'::bigint[]) -(2 rows) - -EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i % '{}'; - QUERY PLAN ------------------------------------------- - Index Scan using idx_array on test_array - Index Cond: (i % '{}'::bigint[]) -(2 rows) - -DROP INDEX idx_array; -ALTER TABLE test_array ALTER COLUMN i TYPE text[]; -CREATE INDEX idx_array ON test_array USING rum (i rum_anyarray_ops); -EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i = '{}'; - QUERY PLAN ------------------------------------------- - Index Scan using idx_array on test_array - Index Cond: (i = '{}'::text[]) -(2 rows) - -EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i && '{}'; - QUERY PLAN ------------------------------------------- - Index Scan using idx_array on test_array - Index Cond: (i && '{}'::text[]) -(2 rows) - -EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i @> '{}'; - QUERY PLAN ------------------------------------------- - Index Scan using idx_array on test_array - Index Cond: (i @> '{}'::text[]) -(2 rows) - -EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i <@ '{}'; - QUERY PLAN ------------------------------------------- - Index Scan using idx_array on test_array - Index Cond: (i <@ '{}'::text[]) -(2 rows) - -EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i % '{}'; - QUERY PLAN ------------------------------------------- - Index Scan using idx_array on test_array - Index Cond: (i % '{}'::text[]) -(2 rows) - -DROP INDEX idx_array; -ALTER TABLE test_array ALTER COLUMN i TYPE varchar[]; -CREATE INDEX idx_array ON test_array USING rum (i rum_anyarray_ops); -EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i = '{}'; - QUERY PLAN ------------------------------------------------ - Index Scan using idx_array on test_array - Index Cond: (i = '{}'::character varying[]) -(2 rows) - -EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i && '{}'; - QUERY PLAN ------------------------------------------------- - Index Scan using idx_array on test_array - Index Cond: (i && '{}'::character varying[]) -(2 rows) - -EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i @> '{}'; - QUERY PLAN ------------------------------------------------- - Index Scan using idx_array on test_array - Index Cond: (i @> '{}'::character varying[]) -(2 rows) - -EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i <@ '{}'; - QUERY PLAN ------------------------------------------------- - Index Scan using idx_array on test_array - Index Cond: (i <@ '{}'::character varying[]) -(2 rows) - -EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i % '{}'; - QUERY PLAN ------------------------------------------------ - Index Scan using idx_array on test_array - Index Cond: (i % '{}'::character varying[]) -(2 rows) - -DROP INDEX idx_array; -ALTER TABLE test_array ALTER COLUMN i TYPE char[]; -CREATE INDEX idx_array ON test_array USING rum (i rum_anyarray_ops); -EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i = '{}'; - QUERY PLAN ------------------------------------------- - Index Scan using idx_array on test_array - Index Cond: (i = '{}'::bpchar[]) -(2 rows) - -EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i && '{}'; - QUERY PLAN ------------------------------------------- - Index Scan using idx_array on test_array - Index Cond: (i && '{}'::bpchar[]) -(2 rows) - -EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i @> '{}'; - QUERY PLAN ------------------------------------------- - Index Scan using idx_array on test_array - Index Cond: (i @> '{}'::bpchar[]) -(2 rows) - -EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i <@ '{}'; - QUERY PLAN ------------------------------------------- - Index Scan using idx_array on test_array - Index Cond: (i <@ '{}'::bpchar[]) -(2 rows) - -EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i % '{}'; - QUERY PLAN ------------------------------------------- - Index Scan using idx_array on test_array - Index Cond: (i % '{}'::bpchar[]) -(2 rows) - -DROP INDEX idx_array; -ALTER TABLE test_array ALTER COLUMN i TYPE numeric[] USING i::numeric[]; -CREATE INDEX idx_array ON test_array USING rum (i rum_anyarray_ops); -EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i = '{}'; - QUERY PLAN ------------------------------------------- - Index Scan using idx_array on test_array - Index Cond: (i = '{}'::numeric[]) -(2 rows) - -EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i && '{}'; - QUERY PLAN ------------------------------------------- - Index Scan using idx_array on test_array - Index Cond: (i && '{}'::numeric[]) -(2 rows) - -EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i @> '{}'; - QUERY PLAN ------------------------------------------- - Index Scan using idx_array on test_array - Index Cond: (i @> '{}'::numeric[]) -(2 rows) - -EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i <@ '{}'; - QUERY PLAN ------------------------------------------- - Index Scan using idx_array on test_array - Index Cond: (i <@ '{}'::numeric[]) -(2 rows) - -EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i % '{}'; - QUERY PLAN ------------------------------------------- - Index Scan using idx_array on test_array - Index Cond: (i % '{}'::numeric[]) -(2 rows) - -DROP INDEX idx_array; -ALTER TABLE test_array ALTER COLUMN i TYPE float4[] USING i::float4[]; -CREATE INDEX idx_array ON test_array USING rum (i rum_anyarray_ops); -EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i = '{}'; - QUERY PLAN ------------------------------------------- - Index Scan using idx_array on test_array - Index Cond: (i = '{}'::real[]) -(2 rows) - -EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i && '{}'; - QUERY PLAN ------------------------------------------- - Index Scan using idx_array on test_array - Index Cond: (i && '{}'::real[]) -(2 rows) - -EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i @> '{}'; - QUERY PLAN ------------------------------------------- - Index Scan using idx_array on test_array - Index Cond: (i @> '{}'::real[]) -(2 rows) - -EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i <@ '{}'; - QUERY PLAN ------------------------------------------- - Index Scan using idx_array on test_array - Index Cond: (i <@ '{}'::real[]) -(2 rows) - -EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i % '{}'; - QUERY PLAN ------------------------------------------- - Index Scan using idx_array on test_array - Index Cond: (i % '{}'::real[]) -(2 rows) - -DROP INDEX idx_array; -ALTER TABLE test_array ALTER COLUMN i TYPE float8[] USING i::float8[]; -CREATE INDEX idx_array ON test_array USING rum (i rum_anyarray_ops); -EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i = '{}'; - QUERY PLAN ----------------------------------------------- - Index Scan using idx_array on test_array - Index Cond: (i = '{}'::double precision[]) -(2 rows) - -EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i && '{}'; - QUERY PLAN ------------------------------------------------ - Index Scan using idx_array on test_array - Index Cond: (i && '{}'::double precision[]) -(2 rows) - -EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i @> '{}'; - QUERY PLAN ------------------------------------------------ - Index Scan using idx_array on test_array - Index Cond: (i @> '{}'::double precision[]) -(2 rows) - -EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i <@ '{}'; - QUERY PLAN ------------------------------------------------ - Index Scan using idx_array on test_array - Index Cond: (i <@ '{}'::double precision[]) -(2 rows) - -EXPLAIN (COSTS OFF) SELECT * FROM test_array WHERE i % '{}'; - QUERY PLAN ----------------------------------------------- - Index Scan using idx_array on test_array - Index Cond: (i % '{}'::double precision[]) -(2 rows) - -DROP INDEX idx_array; -/* - * Check ordering using distance operator - */ -CREATE TABLE test_array_order ( - i int2[] -); -\copy test_array_order(i) from 'data/rum_array.data'; -CREATE INDEX idx_array_order ON test_array_order USING rum (i rum_anyarray_ops); -EXPLAIN (COSTS OFF) -SELECT *, i <=> '{51}' from test_array_order WHERE i @> '{23,20}' order by i <=> '{51}'; - QUERY PLAN ------------------------------------------------------- - Index Scan using idx_array_order on test_array_order - Index Cond: (i @> '{23,20}'::smallint[]) - Order By: (i <=> '{51}'::smallint[]) -(3 rows) - -SELECT i, - CASE WHEN distance = 'Infinity' THEN -1 - ELSE distance::numeric(18,14) - END distance - FROM - (SELECT *, (i <=> '{51}') AS distance - FROM test_array_order WHERE i @> '{23,20}' ORDER BY i <=> '{51}') t; - i | distance ----------------------+------------------ - {20,23,51} | 1.73205080756888 - {33,51,20,77,23,65} | 2.44948974278318 - {18,23,10,90,15,20} | -1 - {23,76,34,23,2,20} | -1 - {73,23,20} | -1 - {23,89,38,20,40,95} | -1 - {23,20,72} | -1 - {20,60,45,23,29} | -1 - {81,20,26,22,23} | -1 - {6,97,20,89,23} | -1 - {20,98,30,23,1,66} | -1 - {57,23,39,46,50,20} | -1 -(12 rows) - diff --git a/sql/array.sql b/sql/array.sql index c17c1252c8..ed6d50b81f 100644 --- a/sql/array.sql +++ b/sql/array.sql @@ -7,12 +7,6 @@ * array.sql and array_1.sql * -------------------- * Test output for 64-bit and 32-bit systems respectively. - * - * -------------------- - * array_2.sql and array_3.sql - * -------------------- - * Since 6ed83d5fa55c in PostgreSQL 17, the order of rows - * in the output has been changed. */ @@ -216,6 +210,21 @@ DROP INDEX idx_array; /* * Check ordering using distance operator + * + * The idea of the test: + * We want to check that index scan provides as correct ordering by distance + * operator. File 'data/rum_array.data' contains two arrays that statisfy + * i @> '{23,20}' and have finite distance i <=> '{51}', and a bunch of arrays + * that statisfy i @> '{23,20}' and have infinite distance i <=> '{51}'. When + * ordering by distance the order of this bunch of arrays with infinite + * distance is not determined and may depend of PostgreSQL version and system. + * Adding another sort expression to ORDER BY may cause another plan that + * doesn't use ordering provided by index. + * That's why we use the query you see below. We substitute 'Infinity' distance + * value with -1 because 'Infinity' are printed differently in output in + * different PostgreSQL versions. We substitute arrays that have infinite + * distance with {-1} because their order is undefined and we wnat to determine + * the test output. */ CREATE TABLE test_array_order ( @@ -225,12 +234,26 @@ CREATE TABLE test_array_order ( CREATE INDEX idx_array_order ON test_array_order USING rum (i rum_anyarray_ops); +/* Check that plan of the query uses ordering provided by index scan */ EXPLAIN (COSTS OFF) -SELECT *, i <=> '{51}' from test_array_order WHERE i @> '{23,20}' order by i <=> '{51}'; -SELECT i, +SELECT + CASE WHEN distance = 'Infinity' THEN '{-1}' + ELSE i + END i, + CASE WHEN distance = 'Infinity' THEN -1 + ELSE distance::numeric(18,14) + END distance + FROM + (SELECT *, (i <=> '{51}') AS distance + FROM test_array_order WHERE i @> '{23,20}' ORDER BY distance) t; + +SELECT + CASE WHEN distance = 'Infinity' THEN '{-1}' + ELSE i + END i, CASE WHEN distance = 'Infinity' THEN -1 ELSE distance::numeric(18,14) END distance FROM (SELECT *, (i <=> '{51}') AS distance - FROM test_array_order WHERE i @> '{23,20}' ORDER BY i <=> '{51}') t; + FROM test_array_order WHERE i @> '{23,20}' ORDER BY distance) t; From ab2b0b5ae3a02fe932149b2db7b7be3e49d9b37c Mon Sep 17 00:00:00 2001 From: Karina Litskevich Date: Tue, 26 Nov 2024 15:28:12 +0300 Subject: [PATCH 2/2] [PGPRO-11556] Fixes after review --- expected/array.out | 25 +++++++++++++------------ expected/array_1.out | 25 +++++++++++++------------ sql/array.sql | 26 ++++++++++++++------------ 3 files changed, 40 insertions(+), 36 deletions(-) diff --git a/expected/array.out b/expected/array.out index 35ea87a5f8..1e45885ad1 100644 --- a/expected/array.out +++ b/expected/array.out @@ -854,27 +854,28 @@ DROP INDEX idx_array; /* * Check ordering using distance operator * - * The idea of the test: - * We want to check that index scan provides as correct ordering by distance + * We want to check that index scan provides us correct ordering by distance * operator. File 'data/rum_array.data' contains two arrays that statisfy * i @> '{23,20}' and have finite distance i <=> '{51}', and a bunch of arrays - * that statisfy i @> '{23,20}' and have infinite distance i <=> '{51}'. When - * ordering by distance the order of this bunch of arrays with infinite + * that statisfy i @> '{23,20}' and have infinite distance i <=> '{51}'. + * + * When ordering by distance the order of this bunch of arrays with infinite * distance is not determined and may depend of PostgreSQL version and system. - * Adding another sort expression to ORDER BY may cause another plan that - * doesn't use ordering provided by index. - * That's why we use the query you see below. We substitute 'Infinity' distance - * value with -1 because 'Infinity' are printed differently in output in - * different PostgreSQL versions. We substitute arrays that have infinite - * distance with {-1} because their order is undefined and we wnat to determine - * the test output. + * We don't add another sort expression to ORDER BY because that might cause + * the planner to avoid using the index. Instead, we replace arrays that have + * infinite distance with {-1} to unambiguously determine the test output. + * + * 'Infinity' is printed differently in the output in different PostgreSQL + * versions, so we replace it with -1. */ CREATE TABLE test_array_order ( i int2[] ); \copy test_array_order(i) from 'data/rum_array.data'; CREATE INDEX idx_array_order ON test_array_order USING rum (i rum_anyarray_ops); -/* Check that plan of the query uses ordering provided by index scan */ +/* + * Check that plan of the query uses ordering provided by index scan + */ EXPLAIN (COSTS OFF) SELECT CASE WHEN distance = 'Infinity' THEN '{-1}' diff --git a/expected/array_1.out b/expected/array_1.out index 4478dee5de..c0876801bc 100644 --- a/expected/array_1.out +++ b/expected/array_1.out @@ -847,27 +847,28 @@ DROP INDEX idx_array; /* * Check ordering using distance operator * - * The idea of the test: - * We want to check that index scan provides as correct ordering by distance + * We want to check that index scan provides us correct ordering by distance * operator. File 'data/rum_array.data' contains two arrays that statisfy * i @> '{23,20}' and have finite distance i <=> '{51}', and a bunch of arrays - * that statisfy i @> '{23,20}' and have infinite distance i <=> '{51}'. When - * ordering by distance the order of this bunch of arrays with infinite + * that statisfy i @> '{23,20}' and have infinite distance i <=> '{51}'. + * + * When ordering by distance the order of this bunch of arrays with infinite * distance is not determined and may depend of PostgreSQL version and system. - * Adding another sort expression to ORDER BY may cause another plan that - * doesn't use ordering provided by index. - * That's why we use the query you see below. We substitute 'Infinity' distance - * value with -1 because 'Infinity' are printed differently in output in - * different PostgreSQL versions. We substitute arrays that have infinite - * distance with {-1} because their order is undefined and we wnat to determine - * the test output. + * We don't add another sort expression to ORDER BY because that might cause + * the planner to avoid using the index. Instead, we replace arrays that have + * infinite distance with {-1} to unambiguously determine the test output. + * + * 'Infinity' is printed differently in the output in different PostgreSQL + * versions, so we replace it with -1. */ CREATE TABLE test_array_order ( i int2[] ); \copy test_array_order(i) from 'data/rum_array.data'; CREATE INDEX idx_array_order ON test_array_order USING rum (i rum_anyarray_ops); -/* Check that plan of the query uses ordering provided by index scan */ +/* + * Check that plan of the query uses ordering provided by index scan + */ EXPLAIN (COSTS OFF) SELECT CASE WHEN distance = 'Infinity' THEN '{-1}' diff --git a/sql/array.sql b/sql/array.sql index ed6d50b81f..ba6886780d 100644 --- a/sql/array.sql +++ b/sql/array.sql @@ -211,20 +211,19 @@ DROP INDEX idx_array; /* * Check ordering using distance operator * - * The idea of the test: - * We want to check that index scan provides as correct ordering by distance + * We want to check that index scan provides us correct ordering by distance * operator. File 'data/rum_array.data' contains two arrays that statisfy * i @> '{23,20}' and have finite distance i <=> '{51}', and a bunch of arrays - * that statisfy i @> '{23,20}' and have infinite distance i <=> '{51}'. When - * ordering by distance the order of this bunch of arrays with infinite + * that statisfy i @> '{23,20}' and have infinite distance i <=> '{51}'. + * + * When ordering by distance the order of this bunch of arrays with infinite * distance is not determined and may depend of PostgreSQL version and system. - * Adding another sort expression to ORDER BY may cause another plan that - * doesn't use ordering provided by index. - * That's why we use the query you see below. We substitute 'Infinity' distance - * value with -1 because 'Infinity' are printed differently in output in - * different PostgreSQL versions. We substitute arrays that have infinite - * distance with {-1} because their order is undefined and we wnat to determine - * the test output. + * We don't add another sort expression to ORDER BY because that might cause + * the planner to avoid using the index. Instead, we replace arrays that have + * infinite distance with {-1} to unambiguously determine the test output. + * + * 'Infinity' is printed differently in the output in different PostgreSQL + * versions, so we replace it with -1. */ CREATE TABLE test_array_order ( @@ -234,7 +233,10 @@ CREATE TABLE test_array_order ( CREATE INDEX idx_array_order ON test_array_order USING rum (i rum_anyarray_ops); -/* Check that plan of the query uses ordering provided by index scan */ +/* + * Check that plan of the query uses ordering provided by index scan + */ + EXPLAIN (COSTS OFF) SELECT CASE WHEN distance = 'Infinity' THEN '{-1}'