Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle DEFAULT table access name in ALTER TABLE #7799

Merged
merged 1 commit into from
Mar 7, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .unreleased/pr_7799
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fixes: #7799 Handle DEFAULT table access name in ALTER TABLE
2 changes: 1 addition & 1 deletion src/process_utility.c
Original file line number Diff line number Diff line change
Expand Up @@ -3834,7 +3834,7 @@ process_set_access_method(AlterTableCmd *cmd, ProcessUtilityArgs *args)
Oid relid = AlterTableLookupRelation(stmt, NoLock);
Cache *hcache;
Hypertable *ht = ts_hypertable_cache_get_cache_and_entry(relid, CACHE_FLAG_MISSING_OK, &hcache);
if (ht && (strcmp(cmd->name, TS_HYPERCORE_TAM_NAME) == 0))
if (ht && cmd->name && (strcmp(cmd->name, TS_HYPERCORE_TAM_NAME) == 0))
{
/* For hypertables, we automatically add command to set the
* compression flag if we are setting the access method to be a
Expand Down
94 changes: 94 additions & 0 deletions test/expected/tableam_alter_defaults.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
-- This file and its contents are licensed under the Apache License 2.0.
-- Please see the included NOTICE for copyright information and
-- LICENSE-APACHE for a copy of the license.
-- Test support for setting table access method on hypertables using
-- ALTER TABLE for version 17 and later. This is in addition to the
-- tests in tableam_alter.sql.
\c :TEST_DBNAME :ROLE_SUPERUSER
CREATE ACCESS METHOD testam TYPE TABLE HANDLER heap_tableam_handler;
SET ROLE :ROLE_DEFAULT_PERM_USER;
CREATE VIEW chunk_info AS
SELECT hypertable_name AS hypertable,
chunk_name AS chunk,
amname
FROM timescaledb_information.chunks ch
JOIN pg_class cl ON (format('%I.%I', ch.chunk_schema, ch.chunk_name)::regclass = cl.oid)
JOIN pg_am am ON (am.oid = cl.relam);
CREATE TABLE test_table (time timestamptz not null, device int, temp float);
SELECT cl.relname, amname
FROM pg_class cl JOIN pg_am am ON cl.relam = am.oid
WHERE cl.relname = 'test_table';
relname | amname
------------+--------
test_table | heap
(1 row)

-- Check that setting default access method of a normal table works.
ALTER TABLE test_table SET ACCESS METHOD DEFAULT;
-- Check that changing the access method and then changing it back
-- works.
ALTER TABLE test_table SET ACCESS METHOD testam;
ALTER TABLE test_table SET ACCESS METHOD DEFAULT;
-- Check that setting default access method of a hypertable works.
SELECT create_hypertable('test_table', by_range('time'));
create_hypertable
-------------------
(1,t)
(1 row)

ALTER TABLE test_table SET ACCESS METHOD DEFAULT;
SELECT cl.relname, amname
FROM pg_class cl JOIN pg_am am ON cl.relam = am.oid
WHERE cl.relname = 'test_table';
relname | amname
------------+--------
test_table | heap
(1 row)

-- Test setting the access method together with other options. This
-- should not generate an error.
ALTER TABLE test_table
SET ACCESS METHOD testam,
SET (autovacuum_vacuum_threshold = 100);
-- Add some rows to generate a chunk. This should get the access
-- method of the hypertable.
INSERT INTO test_table
SELECT ts, 10 * random(), 100 * random()
FROM generate_series('2001-01-01'::timestamp, '2001-01-14', '1d'::interval) as x(ts);
SELECT * FROM chunk_info WHERE hypertable = 'test_table';
hypertable | chunk | amname
------------+------------------+--------
test_table | _hyper_1_1_chunk | testam
test_table | _hyper_1_2_chunk | testam
test_table | _hyper_1_3_chunk | testam
(3 rows)

-- Setting it to the default method after we have set it to a test
-- access method should work fine also on a hypertable.
SELECT cl.relname, amname
FROM pg_class cl JOIN pg_am am ON cl.relam = am.oid
WHERE cl.relname = 'test_table';
relname | amname
------------+--------
test_table | testam
(1 row)

ALTER TABLE test_table SET ACCESS METHOD DEFAULT;
SELECT cl.relname, amname
FROM pg_class cl JOIN pg_am am ON cl.relam = am.oid
WHERE cl.relname = 'test_table';
relname | amname
------------+--------
test_table | heap
(1 row)

SELECT chunk FROM show_chunks('test_table') t(chunk) limit 1 \gset
ALTER TABLE :chunk SET ACCESS METHOD DEFAULT;
SELECT * FROM chunk_info WHERE hypertable = 'test_table';
hypertable | chunk | amname
------------+------------------+--------
test_table | _hyper_1_1_chunk | heap
test_table | _hyper_1_2_chunk | testam
test_table | _hyper_1_3_chunk | testam
(3 rows)

4 changes: 4 additions & 0 deletions test/sql/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,10 @@ if((${PG_VERSION_MAJOR} GREATER_EQUAL "15"))
list(APPEND TEST_TEMPLATES ts_merge.sql.in)
endif()

if((${PG_VERSION_MAJOR} GREATER_EQUAL "17"))
list(APPEND TEST_FILES tableam_alter_defaults.sql)
endif()

# pg_dump_unprivileged.sql was fixed by an upstream change to pg_dump in 14.11,
# 15.6, and 16.2
if(((${PG_VERSION_MAJOR} EQUAL "14") AND (${PG_VERSION_MINOR} GREATER_EQUAL "11"
Expand Down
74 changes: 74 additions & 0 deletions test/sql/tableam_alter_defaults.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
-- This file and its contents are licensed under the Apache License 2.0.
-- Please see the included NOTICE for copyright information and
-- LICENSE-APACHE for a copy of the license.

-- Test support for setting table access method on hypertables using
-- ALTER TABLE for version 17 and later. This is in addition to the
-- tests in tableam_alter.sql.

\c :TEST_DBNAME :ROLE_SUPERUSER
CREATE ACCESS METHOD testam TYPE TABLE HANDLER heap_tableam_handler;

SET ROLE :ROLE_DEFAULT_PERM_USER;

CREATE VIEW chunk_info AS
SELECT hypertable_name AS hypertable,
chunk_name AS chunk,
amname
FROM timescaledb_information.chunks ch
JOIN pg_class cl ON (format('%I.%I', ch.chunk_schema, ch.chunk_name)::regclass = cl.oid)
JOIN pg_am am ON (am.oid = cl.relam);

CREATE TABLE test_table (time timestamptz not null, device int, temp float);

SELECT cl.relname, amname
FROM pg_class cl JOIN pg_am am ON cl.relam = am.oid
WHERE cl.relname = 'test_table';

-- Check that setting default access method of a normal table works.
ALTER TABLE test_table SET ACCESS METHOD DEFAULT;

-- Check that changing the access method and then changing it back
-- works.
ALTER TABLE test_table SET ACCESS METHOD testam;
ALTER TABLE test_table SET ACCESS METHOD DEFAULT;

-- Check that setting default access method of a hypertable works.
SELECT create_hypertable('test_table', by_range('time'));
ALTER TABLE test_table SET ACCESS METHOD DEFAULT;

SELECT cl.relname, amname
FROM pg_class cl JOIN pg_am am ON cl.relam = am.oid
WHERE cl.relname = 'test_table';

-- Test setting the access method together with other options. This
-- should not generate an error.
ALTER TABLE test_table
SET ACCESS METHOD testam,
SET (autovacuum_vacuum_threshold = 100);

-- Add some rows to generate a chunk. This should get the access
-- method of the hypertable.
INSERT INTO test_table
SELECT ts, 10 * random(), 100 * random()
FROM generate_series('2001-01-01'::timestamp, '2001-01-14', '1d'::interval) as x(ts);

SELECT * FROM chunk_info WHERE hypertable = 'test_table';

-- Setting it to the default method after we have set it to a test
-- access method should work fine also on a hypertable.
SELECT cl.relname, amname
FROM pg_class cl JOIN pg_am am ON cl.relam = am.oid
WHERE cl.relname = 'test_table';

ALTER TABLE test_table SET ACCESS METHOD DEFAULT;

SELECT cl.relname, amname
FROM pg_class cl JOIN pg_am am ON cl.relam = am.oid
WHERE cl.relname = 'test_table';

SELECT chunk FROM show_chunks('test_table') t(chunk) limit 1 \gset

ALTER TABLE :chunk SET ACCESS METHOD DEFAULT;

SELECT * FROM chunk_info WHERE hypertable = 'test_table';
7 changes: 6 additions & 1 deletion tsl/src/hypercore/hypercore_handler.c
Original file line number Diff line number Diff line change
Expand Up @@ -3839,9 +3839,14 @@
void
hypercore_alter_access_method_finish(Oid relid, bool to_other_am)
{
Chunk *chunk = ts_chunk_get_by_relid(relid, false);

Check warning on line 3842 in tsl/src/hypercore/hypercore_handler.c

View check run for this annotation

Codecov / codecov/patch

tsl/src/hypercore/hypercore_handler.c#L3842

Added line #L3842 was not covered by tests

/* If this is not a chunk, we just abort since there is nothing to do */
if (!chunk)
return;

Check warning on line 3846 in tsl/src/hypercore/hypercore_handler.c

View check run for this annotation

Codecov / codecov/patch

tsl/src/hypercore/hypercore_handler.c#L3846

Added line #L3846 was not covered by tests

if (to_other_am)
{
Chunk *chunk = ts_chunk_get_by_relid(relid, true);
Chunk *compress_chunk = ts_chunk_get_by_id(chunk->fd.compressed_chunk_id, false);

ts_compression_chunk_size_delete(chunk->fd.id);
Expand Down
6 changes: 4 additions & 2 deletions tsl/src/process_utility.c
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,8 @@ tsl_ddl_command_start(ProcessUtilityArgs *args)
case AT_SetAccessMethod:
{
Oid relid = AlterTableLookupRelation(stmt, NoLock);
bool to_hypercore = (strcmp(cmd->name, TS_HYPERCORE_TAM_NAME) == 0);
bool to_hypercore =
(cmd->name && strcmp(cmd->name, TS_HYPERCORE_TAM_NAME) == 0);
Relation rel = RelationIdGetRelation(relid);
bool is_hypercore = rel->rd_tableam == hypercore_routine();
RelationClose(rel);
Expand Down Expand Up @@ -278,7 +279,8 @@ tsl_ddl_command_end(EventTriggerData *command)
case AT_SetAccessMethod:
{
Oid relid = AlterTableLookupRelation(stmt, NoLock);
bool to_hypercore = (strcmp(cmd->name, TS_HYPERCORE_TAM_NAME) == 0);
bool to_hypercore =
(cmd->name && strcmp(cmd->name, TS_HYPERCORE_TAM_NAME) == 0);
hypercore_alter_access_method_finish(relid, !to_hypercore);
break;
}
Expand Down
Loading