From 4f2ee34c9a5c519bdaac811dce961b4e76168f78 Mon Sep 17 00:00:00 2001 From: Azim Sonawalla Date: Tue, 6 Jan 2026 01:10:38 -0500 Subject: [PATCH] fix: add SearchPath comparison to functionsEqualExceptAttributes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The functionsEqualExceptAttributes() function was missing a SearchPath field comparison. This caused SET search_path changes to be detected but silently dropped — no DDL was generated. The other two comparison functions (functionsEqual and functionsEqualExceptComment) correctly compare SearchPath. This fix aligns functionsEqualExceptAttributes with them. Added test case to alter_function_attributes to verify SearchPath changes generate CREATE OR REPLACE FUNCTION statements. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- internal/diff/function.go | 3 +++ .../alter_function_attributes/diff.sql | 13 +++++++++++++ .../alter_function_attributes/new.sql | 10 ++++++++++ .../alter_function_attributes/old.sql | 9 +++++++++ .../alter_function_attributes/plan.json | 8 +++++++- .../alter_function_attributes/plan.sql | 13 +++++++++++++ .../alter_function_attributes/plan.txt | 18 ++++++++++++++++-- 7 files changed, 71 insertions(+), 3 deletions(-) diff --git a/internal/diff/function.go b/internal/diff/function.go index 01c86659..a4961f99 100644 --- a/internal/diff/function.go +++ b/internal/diff/function.go @@ -359,6 +359,9 @@ func functionsEqualExceptAttributes(old, new *ir.Function) bool { if old.IsSecurityDefiner != new.IsSecurityDefiner { return false } + if old.SearchPath != new.SearchPath { + return false + } // Note: We intentionally do NOT compare IsLeakproof or Parallel here // That's the whole point - we want to detect when only those attributes changed diff --git a/testdata/diff/create_function/alter_function_attributes/diff.sql b/testdata/diff/create_function/alter_function_attributes/diff.sql index 1125e2e6..c534db92 100644 --- a/testdata/diff/create_function/alter_function_attributes/diff.sql +++ b/testdata/diff/create_function/alter_function_attributes/diff.sql @@ -5,3 +5,16 @@ ALTER FUNCTION calculate_total(numeric, numeric) LEAKPROOF; ALTER FUNCTION process_data(text) PARALLEL SAFE; ALTER FUNCTION process_data(text) LEAKPROOF; + +CREATE OR REPLACE FUNCTION secure_lookup( + id integer +) +RETURNS text +LANGUAGE plpgsql +VOLATILE +SET search_path = pg_catalog +AS $$ +BEGIN + RETURN 'result'; +END; +$$; diff --git a/testdata/diff/create_function/alter_function_attributes/new.sql b/testdata/diff/create_function/alter_function_attributes/new.sql index 1fbb936b..f36f2624 100644 --- a/testdata/diff/create_function/alter_function_attributes/new.sql +++ b/testdata/diff/create_function/alter_function_attributes/new.sql @@ -19,3 +19,13 @@ LEAKPROOF AS $$ SELECT amount * (1 + tax_rate); $$; + +CREATE FUNCTION secure_lookup(id integer) +RETURNS text +LANGUAGE plpgsql +SET search_path = pg_catalog +AS $$ +BEGIN + RETURN 'result'; +END; +$$; diff --git a/testdata/diff/create_function/alter_function_attributes/old.sql b/testdata/diff/create_function/alter_function_attributes/old.sql index 5db2146d..b911b40c 100644 --- a/testdata/diff/create_function/alter_function_attributes/old.sql +++ b/testdata/diff/create_function/alter_function_attributes/old.sql @@ -15,3 +15,12 @@ STABLE AS $$ SELECT amount * (1 + tax_rate); $$; + +CREATE FUNCTION secure_lookup(id integer) +RETURNS text +LANGUAGE plpgsql +AS $$ +BEGIN + RETURN 'result'; +END; +$$; diff --git a/testdata/diff/create_function/alter_function_attributes/plan.json b/testdata/diff/create_function/alter_function_attributes/plan.json index bf950ee0..16aa5983 100644 --- a/testdata/diff/create_function/alter_function_attributes/plan.json +++ b/testdata/diff/create_function/alter_function_attributes/plan.json @@ -3,7 +3,7 @@ "pgschema_version": "1.6.0", "created_at": "1970-01-01T00:00:00Z", "source_fingerprint": { - "hash": "d3760381c0e30abb35769924c7ae22d0868a81496ec73d6c427a39d4a3abe131" + "hash": "1f121ae09b8a9c9a88444396c16c27b8690f6ff7a123cf72c204103111a49649" }, "groups": [ { @@ -31,6 +31,12 @@ "type": "function", "operation": "alter", "path": "public.process_data" + }, + { + "sql": "CREATE OR REPLACE FUNCTION secure_lookup(\n id integer\n)\nRETURNS text\nLANGUAGE plpgsql\nVOLATILE\nSET search_path = pg_catalog\nAS $$\nBEGIN\n RETURN 'result';\nEND;\n$$;", + "type": "function", + "operation": "alter", + "path": "public.secure_lookup" } ] } diff --git a/testdata/diff/create_function/alter_function_attributes/plan.sql b/testdata/diff/create_function/alter_function_attributes/plan.sql index 1125e2e6..c534db92 100644 --- a/testdata/diff/create_function/alter_function_attributes/plan.sql +++ b/testdata/diff/create_function/alter_function_attributes/plan.sql @@ -5,3 +5,16 @@ ALTER FUNCTION calculate_total(numeric, numeric) LEAKPROOF; ALTER FUNCTION process_data(text) PARALLEL SAFE; ALTER FUNCTION process_data(text) LEAKPROOF; + +CREATE OR REPLACE FUNCTION secure_lookup( + id integer +) +RETURNS text +LANGUAGE plpgsql +VOLATILE +SET search_path = pg_catalog +AS $$ +BEGIN + RETURN 'result'; +END; +$$; diff --git a/testdata/diff/create_function/alter_function_attributes/plan.txt b/testdata/diff/create_function/alter_function_attributes/plan.txt index bff6b852..3cc86a32 100644 --- a/testdata/diff/create_function/alter_function_attributes/plan.txt +++ b/testdata/diff/create_function/alter_function_attributes/plan.txt @@ -1,13 +1,14 @@ -Plan: 4 to modify. +Plan: 5 to modify. Summary by type: - functions: 4 to modify + functions: 5 to modify Functions: ~ calculate_total ~ calculate_total ~ process_data ~ process_data + ~ secure_lookup DDL to be executed: -------------------------------------------------- @@ -19,3 +20,16 @@ ALTER FUNCTION calculate_total(numeric, numeric) LEAKPROOF; ALTER FUNCTION process_data(text) PARALLEL SAFE; ALTER FUNCTION process_data(text) LEAKPROOF; + +CREATE OR REPLACE FUNCTION secure_lookup( + id integer +) +RETURNS text +LANGUAGE plpgsql +VOLATILE +SET search_path = pg_catalog +AS $$ +BEGIN + RETURN 'result'; +END; +$$;