fix(restore): drop overloaded functions by identity signature in the --empty pre-clean

A signature-less DROP FUNCTION aborts with 'function name is not unique' as soon as a schema overloads a name, killing the whole --empty replay under ON_ERROR_STOP. The function branch now emits name(identity args) via pg_get_function_identity_arguments; because that compound must not be identifier-quoted as a whole, quoting moves from the outer format into each branch, guarded by a unit test that pins the per-branch %I quoting.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-17 17:27:55 +02:00
parent 779f297c85
commit 01a00dd791
2 changed files with 23 additions and 7 deletions

View File

@@ -36,7 +36,21 @@ class TestPostgresEmptyDrop(unittest.TestCase):
sql = self._drop_sql()
for marker in ("pg_class", "pg_proc", "'SEQUENCE' AS type", "'TYPE' AS type"):
self.assertIn(marker, sql)
self.assertIn("DROP %s IF EXISTS public.%I CASCADE", sql)
self.assertIn("DROP %s IF EXISTS public.%s CASCADE", sql)
def test_functions_drop_with_identity_signature(self) -> None:
"""Overloaded functions share a proname; a signature-less DROP aborts
with "function name is not unique", so the function branch must emit
name(identity args) while every other branch stays %I-quoted."""
sql = self._drop_sql()
self.assertIn("pg_get_function_identity_arguments(p.oid)", sql)
self.assertIn("format('%I(%s)', p.proname", sql)
for branch in (
"format('%I', c.relname)",
"format('%I', t.typname)",
"format('%I', col.collname)",
):
self.assertIn(branch, sql)
if __name__ == "__main__":