Skip to content
Closed
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
4 changes: 3 additions & 1 deletion src/agent_env/providers/env_state/env_state_provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,9 @@ def get_init_script(environment_names: list[str]) -> str:
SELECT schemaname, tablename
FROM pg_tables
WHERE schemaname = _schema_name
AND tablename != '_changelog'
-- Names starting with an underscore are a service's internal tables
-- (file bytes, caches), not domain rows; _changelog itself is one.
AND tablename NOT LIKE '\\_%'
LOOP
EXECUTE format(
'DROP TRIGGER IF EXISTS _changelog_trigger ON %I.%I',
Expand Down
27 changes: 27 additions & 0 deletions tst/integration/env/envs/service_db_changelog_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,3 +128,30 @@ def test_changelog_row_id_composite_pk(pg_conn):
f"WHERE schema_name='{schema}' AND table_name='daily' ORDER BY id DESC LIMIT 1",
)[0][0]
assert json.loads(row_id) == {"user_id": "u_jin", "day": "2025-11-05"}


def test_internal_tables_get_no_changelog_trigger(pg_conn):
"""A service's internal tables (a leading underscore, like _changelog) hold no
domain rows: the installer skips them, so a blob written there is not copied
into changed_fields while the domain table beside it is still audited."""
schema = "files_svc"
_exec(pg_conn, LocalPostgresStateProvider.get_init_script([schema]))
_exec(pg_conn, f'CREATE TABLE "{schema}".documents (id text PRIMARY KEY, title text)')
_exec(pg_conn, f'CREATE TABLE "{schema}"._files (path text PRIMARY KEY, content bytea)')
_exec(pg_conn, f"SELECT public._install_changelog_triggers('{schema}')")

_exec(pg_conn, f"INSERT INTO \"{schema}\".documents VALUES ('d1', 'brief')")
_exec(pg_conn, f"INSERT INTO \"{schema}\"._files VALUES ('a/brief.pdf', '\\x255044462d')")

rows = _rows(
pg_conn,
"SELECT table_name, operation FROM public._changelog "
f"WHERE schema_name='{schema}' ORDER BY id",
)
assert rows == [("documents", "INSERT")]
triggers = _rows(
pg_conn,
"SELECT event_object_table FROM information_schema.triggers "
f"WHERE trigger_schema='{schema}' AND trigger_name='_changelog_trigger'",
)
assert {t[0] for t in triggers} == {"documents"}
4 changes: 4 additions & 0 deletions tst/unit/providers/env_state/test_env_state_provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,10 @@ def test_get_init_script_changelog_components():
for op in ("TG_OP = 'INSERT'", "TG_OP = 'DELETE'", "TG_OP = 'UPDATE'"):
assert op in script
assert "_install_changelog_triggers(_schema_name TEXT)" in script
# Internal tables (a leading underscore, like _changelog itself) carry no
# domain rows and get no trigger.
assert "tablename NOT LIKE '\\_%'" in script
assert "tablename != '_changelog'" not in script
Comment thread
greptile-apps[bot] marked this conversation as resolved.
assert "WHERE schemaname = _schema_name" in script


Expand Down
Loading