1 2# Copyright (c) 2021, PostgreSQL Global Development Group 3 4# This regression test checks the behavior of the btree validation in the 5# presence of breaking sort order changes. 6# 7use strict; 8use warnings; 9use PostgresNode; 10use TestLib; 11use Test::More tests => 5; 12 13my $node = get_new_node('test'); 14$node->init; 15$node->start; 16 17# Create a custom operator class and an index which uses it. 18$node->safe_psql( 19 'postgres', q( 20 CREATE EXTENSION amcheck; 21 22 CREATE FUNCTION int4_asc_cmp (a int4, b int4) RETURNS int LANGUAGE sql AS $$ 23 SELECT CASE WHEN $1 = $2 THEN 0 WHEN $1 > $2 THEN 1 ELSE -1 END; $$; 24 25 CREATE OPERATOR CLASS int4_fickle_ops FOR TYPE int4 USING btree AS 26 OPERATOR 1 < (int4, int4), OPERATOR 2 <= (int4, int4), 27 OPERATOR 3 = (int4, int4), OPERATOR 4 >= (int4, int4), 28 OPERATOR 5 > (int4, int4), FUNCTION 1 int4_asc_cmp(int4, int4); 29 30 CREATE TABLE int4tbl (i int4); 31 INSERT INTO int4tbl (SELECT * FROM generate_series(1,1000) gs); 32 CREATE INDEX fickleidx ON int4tbl USING btree (i int4_fickle_ops); 33)); 34 35# We have not yet broken the index, so we should get no corruption 36$node->command_like( 37 [ 'pg_amcheck', '-p', $node->port, 'postgres' ], 38 qr/^$/, 39 'pg_amcheck all schemas, tables and indexes reports no corruption'); 40 41# Change the operator class to use a function which sorts in a different 42# order to corrupt the btree index 43$node->safe_psql( 44 'postgres', q( 45 CREATE FUNCTION int4_desc_cmp (int4, int4) RETURNS int LANGUAGE sql AS $$ 46 SELECT CASE WHEN $1 = $2 THEN 0 WHEN $1 > $2 THEN -1 ELSE 1 END; $$; 47 UPDATE pg_catalog.pg_amproc 48 SET amproc = 'int4_desc_cmp'::regproc 49 WHERE amproc = 'int4_asc_cmp'::regproc 50)); 51 52# Index corruption should now be reported 53$node->command_checks_all( 54 [ 'pg_amcheck', '-p', $node->port, 'postgres' ], 55 2, 56 [qr/item order invariant violated for index "fickleidx"/], 57 [], 58 'pg_amcheck all schemas, tables and indexes reports fickleidx corruption' 59); 60