Add tests for special hash values (#5431)

We fixed some crashes a while back that would only occur in cases where
the value of a distribution column would have result in a high or a very
low hash value. This adds a regression test for those crashes.
pull/5414/head^2
Jelte Fennema 2021-11-03 13:42:39 +01:00 committed by GitHub
parent 0cb51f8c37
commit 9b784e58bf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 84 additions and 44 deletions

View File

@ -2,12 +2,36 @@ SET search_path TO "distributed planning";
-- Confirm the basics work -- Confirm the basics work
INSERT INTO test VALUES (1, 2), (3, 4), (5, 6), (2, 7), (4, 5); INSERT INTO test VALUES (1, 2), (3, 4), (5, 6), (2, 7), (4, 5);
INSERT INTO test VALUES (6, 7); INSERT INTO test VALUES (6, 7);
-- Insert two edge case values, the first value hashes to MAX_INT32 and the
-- second hashes to MIN_INT32. This should not break anything, but these cases
-- caused some crashes in the past.
-- See c6c31e0f1fe5b8cc955b0da42264578dcdae16cc and
-- 683279cc366069db9c2ccaca85dfaf8572113cda for details.
--
-- These specific values were found by using the following two queries:
-- select q.i from (select generate_series(0, 10000000000000) i) q where hashint8(q.i) = 2147483647 limit 1;
-- select q.i from (select generate_series(0, 10000000000000) i) q where hashint8(q.i) = -2147483648 limit 1;
INSERT INTO test VALUES (2608474032, 2608474032), (963809240, 963809240);
SELECT * FROM test WHERE x = 1 ORDER BY y, x; SELECT * FROM test WHERE x = 1 ORDER BY y, x;
x | y x | y
--------------------------------------------------------------------- ---------------------------------------------------------------------
1 | 2 1 | 2
(1 row) (1 row)
-- Confirm that hash values are as expected
SELECT hashint8(x) FROM test ORDER BY 1;
hashint8
---------------------------------------------------------------------
-2147483648
-1905060026
-1330264708
-1011077333
-28094569
566031088
1134484726
2147483647
(8 rows)
SELECT t1.x, t2.y FROM test t1 JOIN test t2 USING(x) WHERE t1.x = 1 AND t2.x = 1 ORDER BY t2.y, t1.x; SELECT t1.x, t2.y FROM test t1 JOIN test t2 USING(x) WHERE t1.x = 1 AND t2.x = 1 ORDER BY t2.y, t1.x;
x | y x | y
--------------------------------------------------------------------- ---------------------------------------------------------------------
@ -24,30 +48,34 @@ SELECT * FROM test WHERE x = 1 OR x = 2 ORDER BY y, x;
SELECT count(*) FROM test; SELECT count(*) FROM test;
count count
--------------------------------------------------------------------- ---------------------------------------------------------------------
6 8
(1 row) (1 row)
SELECT * FROM test ORDER BY x; SELECT * FROM test ORDER BY x;
x | y x | y
--------------------------------------------------------------------- ---------------------------------------------------------------------
1 | 2 1 | 2
2 | 7 2 | 7
3 | 4 3 | 4
4 | 5 4 | 5
5 | 6 5 | 6
6 | 7 6 | 7
(6 rows) 963809240 | 963809240
2608474032 | 2608474032
(8 rows)
WITH cte_1 AS (UPDATE test SET y = y - 1 RETURNING *) SELECT * FROM cte_1 ORDER BY 1,2; WITH cte_1 AS (UPDATE test SET y = y - 1 RETURNING *) SELECT * FROM cte_1 ORDER BY 1,2;
x | y x | y
--------------------------------------------------------------------- ---------------------------------------------------------------------
1 | 1 1 | 1
2 | 6 2 | 6
3 | 3 3 | 3
4 | 4 4 | 4
5 | 5 5 | 5
6 | 6 6 | 6
(6 rows) 963809240 | 963809239
2608474032 | 2608474031
(8 rows)
-- observe that there is a conflict and the following query does nothing -- observe that there is a conflict and the following query does nothing
INSERT INTO upsert_test (part_key, other_col) VALUES (1, 1) ON CONFLICT DO NOTHING RETURNING *; INSERT INTO upsert_test (part_key, other_col) VALUES (1, 1) ON CONFLICT DO NOTHING RETURNING *;
@ -117,7 +145,7 @@ BEGIN;
SELECT count(*) FROM cte_1, cte_2; SELECT count(*) FROM cte_1, cte_2;
count count
--------------------------------------------------------------------- ---------------------------------------------------------------------
1007 1009
(1 row) (1 row)
ROLLBACK; ROLLBACK;
@ -135,7 +163,7 @@ CREATE VIEW simple_view AS
SELECT * FROM simple_view; SELECT * FROM simple_view;
cnt cnt
--------------------------------------------------------------------- ---------------------------------------------------------------------
8 10
(1 row) (1 row)
SELECT * FROM simple_view, test WHERE test.x = simple_view.cnt; SELECT * FROM simple_view, test WHERE test.x = simple_view.cnt;
@ -148,11 +176,11 @@ BEGIN;
SELECT count(*) FROM test; SELECT count(*) FROM test;
count count
--------------------------------------------------------------------- ---------------------------------------------------------------------
16 18
(1 row) (1 row)
COPY (SELECT count(DISTINCT x) FROM test) TO STDOUT; COPY (SELECT count(DISTINCT x) FROM test) TO STDOUT;
10 12
INSERT INTO test SELECT i,i FROM generate_series(0,100)i; INSERT INTO test SELECT i,i FROM generate_series(0,100)i;
ROLLBACK; ROLLBACK;
-- prepared statements with custom types -- prepared statements with custom types
@ -258,13 +286,13 @@ WITH cte_1 AS (SELECT * FROM test_2) SELECT * FROM cte_1, test_2 WHERE test_2.x
SELECT count(DISTINCT x) FROM test; SELECT count(DISTINCT x) FROM test;
count count
--------------------------------------------------------------------- ---------------------------------------------------------------------
5 7
(1 row) (1 row)
SELECT count(DISTINCT y) FROM test; SELECT count(DISTINCT y) FROM test;
count count
--------------------------------------------------------------------- ---------------------------------------------------------------------
5 7
(1 row) (1 row)
-- query pushdown should work -- query pushdown should work
@ -300,7 +328,7 @@ INSERT INTO test(x, y) SELECT x, y FROM test WHERE x = 1;
SELECT count(*) from test; SELECT count(*) from test;
count count
--------------------------------------------------------------------- ---------------------------------------------------------------------
7 9
(1 row) (1 row)
ROLLBACK; ROLLBACK;
@ -310,7 +338,7 @@ INSERT INTO test(x, y) SELECT x, y FROM test;
SELECT count(*) from test; SELECT count(*) from test;
count count
--------------------------------------------------------------------- ---------------------------------------------------------------------
12 16
(1 row) (1 row)
ROLLBACK; ROLLBACK;
@ -320,7 +348,7 @@ INSERT INTO test(x, y) SELECT count(x), max(y) FROM test;
SELECT count(*) from test; SELECT count(*) from test;
count count
--------------------------------------------------------------------- ---------------------------------------------------------------------
7 9
(1 row) (1 row)
ROLLBACK; ROLLBACK;
@ -330,7 +358,7 @@ INSERT INTO test(x, y) SELECT y, x FROM test;
SELECT count(*) from test; SELECT count(*) from test;
count count
--------------------------------------------------------------------- ---------------------------------------------------------------------
12 16
(1 row) (1 row)
ROLLBACK; ROLLBACK;
@ -340,7 +368,7 @@ INSERT INTO test(x, y) SELECT a, b FROM ref;
SELECT count(*) from test; SELECT count(*) from test;
count count
--------------------------------------------------------------------- ---------------------------------------------------------------------
6 8
(1 row) (1 row)
ROLLBACK; ROLLBACK;
@ -350,7 +378,7 @@ INSERT INTO test(x, y) SELECT c, d FROM local;
SELECT count(*) from test; SELECT count(*) from test;
count count
--------------------------------------------------------------------- ---------------------------------------------------------------------
6 8
(1 row) (1 row)
ROLLBACK; ROLLBACK;
@ -360,7 +388,7 @@ INSERT INTO ref(a, b) SELECT x, y FROM test;
SELECT count(*) from ref; SELECT count(*) from ref;
count count
--------------------------------------------------------------------- ---------------------------------------------------------------------
6 8
(1 row) (1 row)
ROLLBACK; ROLLBACK;
@ -380,7 +408,7 @@ INSERT INTO local(c, d) SELECT x, y FROM test;
SELECT count(*) from local; SELECT count(*) from local;
count count
--------------------------------------------------------------------- ---------------------------------------------------------------------
6 8
(1 row) (1 row)
ROLLBACK; ROLLBACK;
@ -409,7 +437,7 @@ SELECT count(*) FROM test WHERE false GROUP BY GROUPING SETS (x,y);
SELECT count(*) FROM test; SELECT count(*) FROM test;
count count
--------------------------------------------------------------------- ---------------------------------------------------------------------
6 8
(1 row) (1 row)
-- INSERT SELECT from distributed table to local table -- INSERT SELECT from distributed table to local table
@ -418,7 +446,7 @@ INSERT INTO ref(a, b) SELECT x, y FROM test;
SELECT count(*) from ref; SELECT count(*) from ref;
count count
--------------------------------------------------------------------- ---------------------------------------------------------------------
6 8
(1 row) (1 row)
ROLLBACK; ROLLBACK;
@ -438,7 +466,7 @@ INSERT INTO local(c, d) SELECT x, y FROM test;
SELECT count(*) from local; SELECT count(*) from local;
count count
--------------------------------------------------------------------- ---------------------------------------------------------------------
6 8
(1 row) (1 row)
ROLLBACK; ROLLBACK;

View File

@ -24,7 +24,7 @@ SELECT create_time_partitions(table_name:='date_part_table',
INSERT INTO date_part_table INSERT INTO date_part_table
SELECT '2020-01-01'::timestamp + '3 hours'::interval * i, i, i % 20 FROM generate_series(0,100)i; SELECT '2020-01-01'::timestamp + '3 hours'::interval * i, i, i % 20 FROM generate_series(0,100)i;
CREATE TABLE test(x int, y int); CREATE TABLE test(x bigint, y bigint);
SELECT create_distributed_table('test','x'); SELECT create_distributed_table('test','x');
create_distributed_table create_distributed_table
--------------------------------------------------------------------- ---------------------------------------------------------------------
@ -32,28 +32,28 @@ SELECT create_distributed_table('test','x');
(1 row) (1 row)
CREATE TYPE new_type AS (n int, m text); CREATE TYPE new_type AS (n int, m text);
CREATE TABLE test_2(x int, y int, z new_type); CREATE TABLE test_2(x bigint, y bigint, z new_type);
SELECT create_distributed_table('test_2','x'); SELECT create_distributed_table('test_2','x');
create_distributed_table create_distributed_table
--------------------------------------------------------------------- ---------------------------------------------------------------------
(1 row) (1 row)
CREATE TABLE ref(a int, b int); CREATE TABLE ref(a bigint, b bigint);
SELECT create_reference_table('ref'); SELECT create_reference_table('ref');
create_reference_table create_reference_table
--------------------------------------------------------------------- ---------------------------------------------------------------------
(1 row) (1 row)
CREATE TABLE ref2(a int, b int); CREATE TABLE ref2(a bigint, b bigint);
SELECT create_reference_table('ref2'); SELECT create_reference_table('ref2');
create_reference_table create_reference_table
--------------------------------------------------------------------- ---------------------------------------------------------------------
(1 row) (1 row)
CREATE TABLE local(c int, d int); CREATE TABLE local(c bigint, d bigint);
select citus_add_local_table_to_metadata('local'); select citus_add_local_table_to_metadata('local');
citus_add_local_table_to_metadata citus_add_local_table_to_metadata
--------------------------------------------------------------------- ---------------------------------------------------------------------

View File

@ -3,7 +3,19 @@ SET search_path TO "distributed planning";
-- Confirm the basics work -- Confirm the basics work
INSERT INTO test VALUES (1, 2), (3, 4), (5, 6), (2, 7), (4, 5); INSERT INTO test VALUES (1, 2), (3, 4), (5, 6), (2, 7), (4, 5);
INSERT INTO test VALUES (6, 7); INSERT INTO test VALUES (6, 7);
-- Insert two edge case values, the first value hashes to MAX_INT32 and the
-- second hashes to MIN_INT32. This should not break anything, but these cases
-- caused some crashes in the past.
-- See c6c31e0f1fe5b8cc955b0da42264578dcdae16cc and
-- 683279cc366069db9c2ccaca85dfaf8572113cda for details.
--
-- These specific values were found by using the following two queries:
-- select q.i from (select generate_series(0, 10000000000000) i) q where hashint8(q.i) = 2147483647 limit 1;
-- select q.i from (select generate_series(0, 10000000000000) i) q where hashint8(q.i) = -2147483648 limit 1;
INSERT INTO test VALUES (2608474032, 2608474032), (963809240, 963809240);
SELECT * FROM test WHERE x = 1 ORDER BY y, x; SELECT * FROM test WHERE x = 1 ORDER BY y, x;
-- Confirm that hash values are as expected
SELECT hashint8(x) FROM test ORDER BY 1;
SELECT t1.x, t2.y FROM test t1 JOIN test t2 USING(x) WHERE t1.x = 1 AND t2.x = 1 ORDER BY t2.y, t1.x; SELECT t1.x, t2.y FROM test t1 JOIN test t2 USING(x) WHERE t1.x = 1 AND t2.x = 1 ORDER BY t2.y, t1.x;
SELECT * FROM test WHERE x = 1 OR x = 2 ORDER BY y, x; SELECT * FROM test WHERE x = 1 OR x = 2 ORDER BY y, x;
SELECT count(*) FROM test; SELECT count(*) FROM test;

View File

@ -20,20 +20,20 @@ SELECT create_time_partitions(table_name:='date_part_table',
INSERT INTO date_part_table INSERT INTO date_part_table
SELECT '2020-01-01'::timestamp + '3 hours'::interval * i, i, i % 20 FROM generate_series(0,100)i; SELECT '2020-01-01'::timestamp + '3 hours'::interval * i, i, i % 20 FROM generate_series(0,100)i;
CREATE TABLE test(x int, y int); CREATE TABLE test(x bigint, y bigint);
SELECT create_distributed_table('test','x'); SELECT create_distributed_table('test','x');
CREATE TYPE new_type AS (n int, m text); CREATE TYPE new_type AS (n int, m text);
CREATE TABLE test_2(x int, y int, z new_type); CREATE TABLE test_2(x bigint, y bigint, z new_type);
SELECT create_distributed_table('test_2','x'); SELECT create_distributed_table('test_2','x');
CREATE TABLE ref(a int, b int); CREATE TABLE ref(a bigint, b bigint);
SELECT create_reference_table('ref'); SELECT create_reference_table('ref');
CREATE TABLE ref2(a int, b int); CREATE TABLE ref2(a bigint, b bigint);
SELECT create_reference_table('ref2'); SELECT create_reference_table('ref2');
CREATE TABLE local(c int, d int); CREATE TABLE local(c bigint, d bigint);
select citus_add_local_table_to_metadata('local'); select citus_add_local_table_to_metadata('local');
CREATE TABLE non_binary_copy_test (key int PRIMARY KEY, value new_type); CREATE TABLE non_binary_copy_test (key int PRIMARY KEY, value new_type);