diff options
Diffstat (limited to 'contrib')
-rw-r--r-- | contrib/amcheck/expected/check_heap.out | 6 | ||||
-rw-r--r-- | contrib/amcheck/t/001_verify_heapam.pl | 68 | ||||
-rw-r--r-- | contrib/amcheck/verify_heapam.c | 10 |
3 files changed, 79 insertions, 5 deletions
diff --git a/contrib/amcheck/expected/check_heap.out b/contrib/amcheck/expected/check_heap.out index ad3086d2aac..c010361025d 100644 --- a/contrib/amcheck/expected/check_heap.out +++ b/contrib/amcheck/expected/check_heap.out @@ -180,8 +180,10 @@ CREATE SEQUENCE test_sequence; SELECT * FROM verify_heapam('test_sequence', startblock := NULL, endblock := NULL); -ERROR: cannot check relation "test_sequence" -DETAIL: This operation is not supported for sequences. + blkno | offnum | attnum | msg +-------+--------+--------+----- +(0 rows) + -- Check that foreign tables are rejected CREATE FOREIGN DATA WRAPPER dummy; CREATE SERVER dummy_server FOREIGN DATA WRAPPER dummy; diff --git a/contrib/amcheck/t/001_verify_heapam.pl b/contrib/amcheck/t/001_verify_heapam.pl index 4f720a7ed03..ba40f64b581 100644 --- a/contrib/amcheck/t/001_verify_heapam.pl +++ b/contrib/amcheck/t/001_verify_heapam.pl @@ -8,7 +8,7 @@ use PostgresNode; use TestLib; use Fcntl qw(:seek); -use Test::More tests => 80; +use Test::More tests => 272; my ($node, $result); @@ -60,6 +60,22 @@ detects_no_corruption( "verify_heapam('test', skip := 'all-frozen')", "all-frozen corrupted table skipping all-frozen"); +# +# Check a sequence with no corruption. The current implementation of sequences +# doesn't require its own test setup, since sequences are really just heap +# tables under-the-hood. To guard against future implementation changes made +# without remembering to update verify_heapam, we create and exercise a +# sequence, checking along the way that it passes corruption checks. +# +fresh_test_sequence('test_seq'); +check_all_options_uncorrupted('test_seq', 'plain'); +advance_test_sequence('test_seq'); +check_all_options_uncorrupted('test_seq', 'plain'); +set_test_sequence('test_seq'); +check_all_options_uncorrupted('test_seq', 'plain'); +reset_test_sequence('test_seq'); +check_all_options_uncorrupted('test_seq', 'plain'); + # Returns the filesystem path for the named relation. sub relation_filepath { @@ -110,6 +126,56 @@ sub fresh_test_table )); } +# Create a test sequence of the given name. +sub fresh_test_sequence +{ + my ($seqname) = @_; + + return $node->safe_psql( + 'postgres', qq( + DROP SEQUENCE IF EXISTS $seqname CASCADE; + CREATE SEQUENCE $seqname + INCREMENT BY 13 + MINVALUE 17 + START WITH 23; + SELECT nextval('$seqname'); + SELECT setval('$seqname', currval('$seqname') + nextval('$seqname')); + )); +} + +# Call SQL functions to increment the sequence +sub advance_test_sequence +{ + my ($seqname) = @_; + + return $node->safe_psql( + 'postgres', qq( + SELECT nextval('$seqname'); + )); +} + +# Call SQL functions to set the sequence +sub set_test_sequence +{ + my ($seqname) = @_; + + return $node->safe_psql( + 'postgres', qq( + SELECT setval('$seqname', 102); + )); +} + +# Call SQL functions to reset the sequence +sub reset_test_sequence +{ + my ($seqname) = @_; + + return $node->safe_psql( + 'postgres', qq( + ALTER SEQUENCE $seqname RESTART WITH 51 + )); +} + # Stops the test node, corrupts the first page of the named relation, and # restarts the node. sub corrupt_first_page diff --git a/contrib/amcheck/verify_heapam.c b/contrib/amcheck/verify_heapam.c index 173f99d7870..91ef09a8ca8 100644 --- a/contrib/amcheck/verify_heapam.c +++ b/contrib/amcheck/verify_heapam.c @@ -305,14 +305,20 @@ verify_heapam(PG_FUNCTION_ARGS) */ if (ctx.rel->rd_rel->relkind != RELKIND_RELATION && ctx.rel->rd_rel->relkind != RELKIND_MATVIEW && - ctx.rel->rd_rel->relkind != RELKIND_TOASTVALUE) + ctx.rel->rd_rel->relkind != RELKIND_TOASTVALUE && + ctx.rel->rd_rel->relkind != RELKIND_SEQUENCE) ereport(ERROR, (errcode(ERRCODE_WRONG_OBJECT_TYPE), errmsg("cannot check relation \"%s\"", RelationGetRelationName(ctx.rel)), errdetail_relkind_not_supported(ctx.rel->rd_rel->relkind))); - if (ctx.rel->rd_rel->relam != HEAP_TABLE_AM_OID) + /* + * Sequences always use heap AM, but they don't show that in the catalogs. + * Other relkinds might be using a different AM, so check. + */ + if (ctx.rel->rd_rel->relkind != RELKIND_SEQUENCE && + ctx.rel->rd_rel->relam != HEAP_TABLE_AM_OID) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("only heap AM is supported"))); |