Skip to content
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
17 changes: 17 additions & 0 deletions lib/ecto_watch/watcher_trigger_validator.ex
Original file line number Diff line number Diff line change
Expand Up @@ -137,13 +137,30 @@ defmodule EctoWatch.WatcherTriggerValidator do
)
end

# When triggers are inserted for a partitioned table,
# Postgres will automatically add "clone" triggers for all partitions
# https://www.postgresql.org/docs/current/sql-createtrigger.html
# So when looking for stray triggers we exclude triggers on
# tables that have an entry in pg_inherits (= are partitions)
defp find_triggers(repo_mod) do
sql_query(
repo_mod,
"""
SELECT trigger_name, event_object_schema, event_object_table
FROM information_schema.triggers
WHERE trigger_name LIKE 'ew_%'
AND EXISTS (
SELECT 1
FROM pg_class c
JOIN pg_namespace n ON c.relnamespace = n.oid
WHERE n.nspname = event_object_schema
AND c.relname = event_object_table
AND NOT EXISTS (
SELECT 1
FROM pg_inherits inh
WHERE inh.inhrelid = c.oid
)
)
"""
)
|> Enum.map(fn [name, table_schema, table_name] ->
Expand Down
46 changes: 46 additions & 0 deletions test/ecto_watch_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,27 @@ defmodule EctoWatchTest do
[]
)

Ecto.Adapters.SQL.query!(
TestRepo,
"""
CREATE TABLE partitioned_root (
id SERIAL,
part_key INTEGER NOT NULL,
the_string TEXT,
PRIMARY KEY (id, part_key)
) PARTITION BY LIST (part_key)
""",
[]
)

Ecto.Adapters.SQL.query!(
TestRepo,
"""
CREATE TABLE partitioned_part1 PARTITION OF partitioned_root FOR VALUES IN (1)
""",
[]
)

%Postgrex.Result{
rows: [[already_existing_id1]]
} =
Expand Down Expand Up @@ -724,6 +745,19 @@ defmodule EctoWatchTest do
[]
)

Ecto.Adapters.SQL.query!(
TestRepo,
"""
CREATE OR REPLACE FUNCTION \"public\".non_ecto_watch_func()
RETURNS trigger AS $trigger$
BEGIN
RETURN NEW;
END;
$trigger$ LANGUAGE plpgsql;
""",
[]
)

Ecto.Adapters.SQL.query!(
TestRepo,
"""
Expand All @@ -734,6 +768,16 @@ defmodule EctoWatchTest do
[]
)

Ecto.Adapters.SQL.query!(
TestRepo,
"""
CREATE TRIGGER ew_partition_level_trigger
AFTER UPDATE ON \"public\".\"partitioned_part1\" FOR EACH ROW
EXECUTE PROCEDURE \"public\".non_ecto_watch_func();
""",
[]
)

Ecto.Adapters.SQL.query!(
TestRepo,
"""
Expand Down Expand Up @@ -783,6 +827,7 @@ defmodule EctoWatchTest do

refute log =~ ~r/non_ecto_watch_trigger/
refute log =~ ~r/non_ecto_watch_func/
refute log =~ ~r/ew_partition_level_trigger/
end

test "actual cleanup" do
Expand Down Expand Up @@ -815,6 +860,7 @@ defmodule EctoWatchTest do

assert "ew_some_weird_trigger" not in values
assert "non_ecto_watch_trigger" in values
assert "ew_partition_level_trigger" in values

%Postgrex.Result{rows: rows} =
Ecto.Adapters.SQL.query!(
Expand Down