Skip to content

Commit

Permalink
Fix segfault when setting chunk replica identity
Browse files Browse the repository at this point in the history
The problem occurs because `currentEventTriggerState->currentCommand`
is not set up since `AlterTableInternal` is called without calling
`EventTriggerAlterTableStart`.

This is because `AlterTableInternal` is called as part of a different
statement, which do not "prepare" for an `AlterTable` correctly.

Fixed it by properly adding the proper start and end calls for the event
trigger on the underlying `AlterTable` to set the replica identity for a
new created chunk introduced by #5515.

Fixes #7406
  • Loading branch information
fabriziomello committed Nov 11, 2024
1 parent 7725448 commit 2951ac2
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/chunk.c
Original file line number Diff line number Diff line change
Expand Up @@ -900,7 +900,9 @@ chunk_set_replica_identity(const Chunk *chunk)
}

ts_catalog_database_info_become_owner(ts_catalog_database_info_get(), &sec_ctx);
EventTriggerAlterTableStart((Node *) &cmd);
AlterTableInternal(chunk->table_id, list_make1(&cmd), false);
EventTriggerAlterTableEnd();
ts_catalog_restore_user(&sec_ctx);
table_close(ht_rel, NoLock);
}
Expand Down
45 changes: 45 additions & 0 deletions test/expected/create_chunks.out
Original file line number Diff line number Diff line change
Expand Up @@ -221,3 +221,48 @@ ERROR: invalid interval: an explicit interval must be specified
SELECT set_chunk_time_interval('chunk_test2', NULL::INTERVAL);
ERROR: invalid interval: an explicit interval must be specified
\set ON_ERROR_STOP 1
-- Issue https://github.com/timescale/timescaledb/issues/7406
CREATE TABLE test_ht (time TIMESTAMPTZ, v1 INTEGER);
SELECT create_hypertable('test_ht', by_range('time', INTERVAL '1 hour'));
NOTICE: adding not-null constraint to column "time"
create_hypertable
-------------------
(4,t)
(1 row)

CREATE TABLE test_tb (time TIMESTAMPTZ, v1 INTEGER);
CREATE OR REPLACE FUNCTION test_tb_trg_insert() RETURNS TRIGGER AS $$
BEGIN
INSERT INTO test_ht VALUES (NEW.time, NEW.v1);
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER test_tb_trg_insert AFTER
INSERT ON test_tb
FOR EACH ROW EXECUTE FUNCTION test_tb_trg_insert();
CREATE TABLE test_output AS
WITH rows AS (
SELECT t, 1 FROM generate_series(NOW()-interval '1 day', NOW(), interval '1 hour') AS t
), inserted AS (
INSERT INTO test_tb SELECT * FROM rows RETURNING *
)
SELECT * FROM inserted;
-- All tables should have the same number of rows
SELECT count(*) FROM test_tb;
count
-------
25
(1 row)

SELECT count(*) FROM test_ht;
count
-------
25
(1 row)

SELECT count(*) FROM test_output;
count
-------
25
(1 row)

29 changes: 29 additions & 0 deletions test/sql/create_chunks.sql
Original file line number Diff line number Diff line change
Expand Up @@ -121,3 +121,32 @@ SELECT set_chunk_time_interval('chunk_test', NULL::BIGINT);
SELECT set_chunk_time_interval('chunk_test2', NULL::BIGINT);
SELECT set_chunk_time_interval('chunk_test2', NULL::INTERVAL);
\set ON_ERROR_STOP 1

-- Issue https://github.com/timescale/timescaledb/issues/7406
CREATE TABLE test_ht (time TIMESTAMPTZ, v1 INTEGER);
SELECT create_hypertable('test_ht', by_range('time', INTERVAL '1 hour'));
CREATE TABLE test_tb (time TIMESTAMPTZ, v1 INTEGER);

CREATE OR REPLACE FUNCTION test_tb_trg_insert() RETURNS TRIGGER AS $$
BEGIN
INSERT INTO test_ht VALUES (NEW.time, NEW.v1);
RETURN NEW;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER test_tb_trg_insert AFTER
INSERT ON test_tb
FOR EACH ROW EXECUTE FUNCTION test_tb_trg_insert();

CREATE TABLE test_output AS
WITH rows AS (
SELECT t, 1 FROM generate_series(NOW()-interval '1 day', NOW(), interval '1 hour') AS t
), inserted AS (
INSERT INTO test_tb SELECT * FROM rows RETURNING *
)
SELECT * FROM inserted;

-- All tables should have the same number of rows
SELECT count(*) FROM test_tb;
SELECT count(*) FROM test_ht;
SELECT count(*) FROM test_output;

0 comments on commit 2951ac2

Please sign in to comment.