diff --git a/internal/diff/function.go b/internal/diff/function.go index 014e7514..c3190b4b 100644 --- a/internal/diff/function.go +++ b/internal/diff/function.go @@ -36,18 +36,68 @@ func generateCreateFunctionsSQL(functions []*ir.Function, targetSchema string, c // generateModifyFunctionsSQL generates ALTER FUNCTION statements func generateModifyFunctionsSQL(diffs []*functionDiff, targetSchema string, collector *diffCollector) { for _, diff := range diffs { - sql := generateFunctionSQL(diff.New, targetSchema) - - // Create context for this statement - context := &diffContext{ - Type: DiffTypeFunction, - Operation: DiffOperationAlter, - Path: fmt.Sprintf("%s.%s", diff.New.Schema, diff.New.Name), - Source: diff, - CanRunInTransaction: true, + oldFunc := diff.Old + newFunc := diff.New + + // Check if only LEAKPROOF or PARALLEL attributes changed (not the function body/definition) + onlyAttributesChanged := functionsEqualExceptAttributes(oldFunc, newFunc) + + if onlyAttributesChanged { + // Generate ALTER FUNCTION statements for attribute-only changes + // Check PARALLEL changes + if oldFunc.Parallel != newFunc.Parallel { + stmt := fmt.Sprintf("ALTER FUNCTION %s(%s) PARALLEL %s;", + qualifyEntityName(newFunc.Schema, newFunc.Name, targetSchema), + newFunc.GetArguments(), + newFunc.Parallel) + + context := &diffContext{ + Type: DiffTypeFunction, + Operation: DiffOperationAlter, + Path: fmt.Sprintf("%s.%s", newFunc.Schema, newFunc.Name), + Source: diff, + CanRunInTransaction: true, + } + collector.collect(context, stmt) + } + + // Check LEAKPROOF changes + if oldFunc.IsLeakproof != newFunc.IsLeakproof { + var stmt string + if newFunc.IsLeakproof { + stmt = fmt.Sprintf("ALTER FUNCTION %s(%s) LEAKPROOF;", + qualifyEntityName(newFunc.Schema, newFunc.Name, targetSchema), + newFunc.GetArguments()) + } else { + stmt = fmt.Sprintf("ALTER FUNCTION %s(%s) NOT LEAKPROOF;", + qualifyEntityName(newFunc.Schema, newFunc.Name, targetSchema), + newFunc.GetArguments()) + } + + context := &diffContext{ + Type: DiffTypeFunction, + Operation: DiffOperationAlter, + Path: fmt.Sprintf("%s.%s", newFunc.Schema, newFunc.Name), + Source: diff, + CanRunInTransaction: true, + } + collector.collect(context, stmt) + } + } else { + // Function body or other attributes changed - use CREATE OR REPLACE + sql := generateFunctionSQL(newFunc, targetSchema) + + // Create context for this statement + context := &diffContext{ + Type: DiffTypeFunction, + Operation: DiffOperationAlter, + Path: fmt.Sprintf("%s.%s", newFunc.Schema, newFunc.Name), + Source: diff, + CanRunInTransaction: true, + } + + collector.collect(context, sql) } - - collector.collect(context, sql) } } @@ -120,13 +170,6 @@ func generateFunctionSQL(function *ir.Function, targetSchema string) string { stmt.WriteString(fmt.Sprintf("\nLANGUAGE %s", function.Language)) } - // Add security definer/invoker - PostgreSQL default is INVOKER - if function.IsSecurityDefiner { - stmt.WriteString("\nSECURITY DEFINER") - } else { - stmt.WriteString("\nSECURITY INVOKER") - } - // Add volatility if not default if function.Volatility != "" { stmt.WriteString(fmt.Sprintf("\n%s", function.Volatility)) @@ -137,6 +180,25 @@ func generateFunctionSQL(function *ir.Function, targetSchema string) string { stmt.WriteString("\nSTRICT") } + // Add SECURITY DEFINER if true (INVOKER is default and not output) + if function.IsSecurityDefiner { + stmt.WriteString("\nSECURITY DEFINER") + } + + // Add LEAKPROOF if true + if function.IsLeakproof { + stmt.WriteString("\nLEAKPROOF") + } + // Note: Don't output NOT LEAKPROOF (it's the default) + + // Add PARALLEL if not default (UNSAFE) + if function.Parallel == "SAFE" { + stmt.WriteString("\nPARALLEL SAFE") + } else if function.Parallel == "RESTRICTED" { + stmt.WriteString("\nPARALLEL RESTRICTED") + } + // Note: Don't output PARALLEL UNSAFE (it's the default) + // Add the function body if function.Definition != "" { // Check if this uses RETURN clause syntax (PG14+) @@ -232,6 +294,42 @@ func formatFunctionParameter(param *ir.Parameter, includeDefault bool, targetSch return part } +// functionsEqualExceptAttributes compares two functions ignoring LEAKPROOF and PARALLEL attributes +// Used to determine if ALTER FUNCTION can be used instead of CREATE OR REPLACE +func functionsEqualExceptAttributes(old, new *ir.Function) bool { + if old.Schema != new.Schema { + return false + } + if old.Name != new.Name { + return false + } + if old.Definition != new.Definition { + return false + } + if old.ReturnType != new.ReturnType { + return false + } + if old.Language != new.Language { + return false + } + if old.Volatility != new.Volatility { + return false + } + if old.IsStrict != new.IsStrict { + return false + } + if old.IsSecurityDefiner != new.IsSecurityDefiner { + 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 + + // Compare using normalized Parameters array + oldInputParams := filterNonTableParameters(old.Parameters) + newInputParams := filterNonTableParameters(new.Parameters) + return parametersEqual(oldInputParams, newInputParams) +} + // functionsEqual compares two functions for equality func functionsEqual(old, new *ir.Function) bool { if old.Schema != new.Schema { @@ -258,6 +356,12 @@ func functionsEqual(old, new *ir.Function) bool { if old.IsSecurityDefiner != new.IsSecurityDefiner { return false } + if old.IsLeakproof != new.IsLeakproof { + return false + } + if old.Parallel != new.Parallel { + return false + } // Compare using normalized Parameters array // This ensures type aliases like "character varying" vs "varchar" are treated as equal diff --git a/ir/inspector.go b/ir/inspector.go index a3b00b46..dc8ebf91 100644 --- a/ir/inspector.go +++ b/ir/inspector.go @@ -913,6 +913,23 @@ func (i *Inspector) buildFunctions(ctx context.Context, schema *IR, targetSchema // Handle security definer isSecurityDefiner := fn.IsSecurityDefiner + // Handle leakproof + isLeakproof := fn.IsLeakproof + + // Handle parallel mode + parallelMode := "" + proparallel := i.safeInterfaceToString(fn.ParallelMode) + switch proparallel { + case "s": + parallelMode = "SAFE" + case "r": + parallelMode = "RESTRICTED" + case "u": + parallelMode = "UNSAFE" + default: + parallelMode = "UNSAFE" // Defensive default + } + // Parse parameters from the complete signature provided by pg_get_function_arguments() // This signature includes all parameter information including modes, names, types, and defaults parameters := i.parseParametersFromSignature(signature, schemaName) @@ -928,6 +945,8 @@ func (i *Inspector) buildFunctions(ctx context.Context, schema *IR, targetSchema Volatility: volatility, IsStrict: isStrict, IsSecurityDefiner: isSecurityDefiner, + IsLeakproof: isLeakproof, + Parallel: parallelMode, } dbSchema.SetFunction(functionName, function) diff --git a/ir/ir.go b/ir/ir.go index ac33bd6a..26b6cb1d 100644 --- a/ir/ir.go +++ b/ir/ir.go @@ -133,6 +133,8 @@ type Function struct { Volatility string `json:"volatility,omitempty"` // IMMUTABLE, STABLE, VOLATILE IsStrict bool `json:"is_strict,omitempty"` // STRICT or null behavior IsSecurityDefiner bool `json:"is_security_definer,omitempty"` // SECURITY DEFINER + IsLeakproof bool `json:"is_leakproof,omitempty"` // LEAKPROOF + Parallel string `json:"parallel,omitempty"` // SAFE, UNSAFE, RESTRICTED } // GetArguments returns the function arguments string (types only) for function identification. diff --git a/ir/queries/queries.sql b/ir/queries/queries.sql index 370e57a7..2f9c54cc 100644 --- a/ir/queries/queries.sql +++ b/ir/queries/queries.sql @@ -813,7 +813,9 @@ SELECT ELSE NULL END AS volatility, p.proisstrict AS is_strict, - p.prosecdef AS is_security_definer + p.prosecdef AS is_security_definer, + p.proleakproof AS is_leakproof, + p.proparallel AS parallel_mode FROM information_schema.routines r LEFT JOIN pg_proc p ON p.proname = r.routine_name AND p.pronamespace = (SELECT oid FROM pg_namespace WHERE nspname = r.routine_schema) diff --git a/ir/queries/queries.sql.go b/ir/queries/queries.sql.go index 60c7a373..9f85a054 100644 --- a/ir/queries/queries.sql.go +++ b/ir/queries/queries.sql.go @@ -1236,7 +1236,9 @@ SELECT ELSE NULL END AS volatility, p.proisstrict AS is_strict, - p.prosecdef AS is_security_definer + p.prosecdef AS is_security_definer, + p.proleakproof AS is_leakproof, + p.proparallel AS parallel_mode FROM information_schema.routines r LEFT JOIN pg_proc p ON p.proname = r.routine_name AND p.pronamespace = (SELECT oid FROM pg_namespace WHERE nspname = r.routine_schema) @@ -1261,6 +1263,8 @@ type GetFunctionsForSchemaRow struct { Volatility sql.NullString `db:"volatility" json:"volatility"` IsStrict bool `db:"is_strict" json:"is_strict"` IsSecurityDefiner bool `db:"is_security_definer" json:"is_security_definer"` + IsLeakproof bool `db:"is_leakproof" json:"is_leakproof"` + ParallelMode interface{} `db:"parallel_mode" json:"parallel_mode"` } // GetFunctionsForSchema retrieves all user-defined functions for a specific schema @@ -1286,6 +1290,8 @@ func (q *Queries) GetFunctionsForSchema(ctx context.Context, dollar_1 sql.NullSt &i.Volatility, &i.IsStrict, &i.IsSecurityDefiner, + &i.IsLeakproof, + &i.ParallelMode, ); err != nil { return nil, err } diff --git a/testdata/diff/create_function/add_function/diff.sql b/testdata/diff/create_function/add_function/diff.sql index a4e635ba..b1bf99f6 100644 --- a/testdata/diff/create_function/add_function/diff.sql +++ b/testdata/diff/create_function/add_function/diff.sql @@ -1,9 +1,25 @@ -CREATE OR REPLACE FUNCTION days_since_special_date() -RETURNS SETOF timestamp with time zone +CREATE OR REPLACE FUNCTION calculate_tax( + amount numeric, + rate numeric +) +RETURNS numeric +LANGUAGE sql +IMMUTABLE +PARALLEL SAFE +AS $$ + SELECT amount * rate; +$$; + +CREATE OR REPLACE FUNCTION mask_sensitive_data( + input text +) +RETURNS text LANGUAGE sql -SECURITY INVOKER STABLE -RETURN generate_series((date_trunc('day'::text, '2025-01-01 00:00:00'::timestamp without time zone))::timestamp with time zone, date_trunc('day'::text, now()), '1 day'::interval); +LEAKPROOF +AS $$ + SELECT '***' || substring(input from 4); +$$; CREATE OR REPLACE FUNCTION process_order( order_id integer, @@ -16,9 +32,11 @@ CREATE OR REPLACE FUNCTION process_order( ) RETURNS numeric LANGUAGE plpgsql -SECURITY DEFINER VOLATILE STRICT +SECURITY DEFINER +LEAKPROOF +PARALLEL RESTRICTED AS $$ DECLARE total numeric; diff --git a/testdata/diff/create_function/add_function/new.sql b/testdata/diff/create_function/add_function/new.sql index a884a33f..f6d6bbc8 100644 --- a/testdata/diff/create_function/add_function/new.sql +++ b/testdata/diff/create_function/add_function/new.sql @@ -1,3 +1,4 @@ +-- Complex function demonstrating all qualifiers CREATE FUNCTION process_order( order_id integer, -- Simple numeric defaults @@ -12,9 +13,11 @@ CREATE FUNCTION process_order( ) RETURNS numeric LANGUAGE plpgsql -SECURITY DEFINER VOLATILE STRICT +SECURITY DEFINER +LEAKPROOF +PARALLEL RESTRICTED AS $$ DECLARE total numeric; @@ -24,7 +27,22 @@ BEGIN END; $$; --- Table function with RETURN clause (bug report test case) -CREATE FUNCTION days_since_special_date() RETURNS SETOF timestamptz - LANGUAGE sql STABLE PARALLEL SAFE - RETURN generate_series(date_trunc('day', '2025-01-01'::timestamp), date_trunc('day', NOW()), '1 day'::interval); \ No newline at end of file +-- Function testing PARALLEL SAFE only +CREATE FUNCTION calculate_tax(amount numeric, rate numeric) +RETURNS numeric +LANGUAGE sql +IMMUTABLE +PARALLEL SAFE +AS $$ + SELECT amount * rate; +$$; + +-- Function testing LEAKPROOF only +CREATE FUNCTION mask_sensitive_data(input text) +RETURNS text +LANGUAGE sql +STABLE +LEAKPROOF +AS $$ + SELECT '***' || substring(input from 4); +$$; \ No newline at end of file diff --git a/testdata/diff/create_function/add_function/plan.json b/testdata/diff/create_function/add_function/plan.json index 0b22a107..326ffd75 100644 --- a/testdata/diff/create_function/add_function/plan.json +++ b/testdata/diff/create_function/add_function/plan.json @@ -1,6 +1,6 @@ { "version": "1.0.0", - "pgschema_version": "1.4.0", + "pgschema_version": "1.4.3", "created_at": "1970-01-01T00:00:00Z", "source_fingerprint": { "hash": "965b1131737c955e24c7f827c55bd78e4cb49a75adfd04229e0ba297376f5085" @@ -9,13 +9,19 @@ { "steps": [ { - "sql": "CREATE OR REPLACE FUNCTION days_since_special_date()\nRETURNS SETOF timestamp with time zone\nLANGUAGE sql\nSECURITY INVOKER\nSTABLE\nRETURN generate_series((date_trunc('day'::text, '2025-01-01 00:00:00'::timestamp without time zone))::timestamp with time zone, date_trunc('day'::text, now()), '1 day'::interval);", + "sql": "CREATE OR REPLACE FUNCTION calculate_tax(\n amount numeric,\n rate numeric\n)\nRETURNS numeric\nLANGUAGE sql\nIMMUTABLE\nPARALLEL SAFE\nAS $$\n SELECT amount * rate;\n$$;", "type": "function", "operation": "create", - "path": "public.days_since_special_date" + "path": "public.calculate_tax" }, { - "sql": "CREATE OR REPLACE FUNCTION process_order(\n order_id integer,\n discount_percent numeric DEFAULT 0,\n priority_level integer DEFAULT 1,\n note varchar DEFAULT '',\n status text DEFAULT 'pending',\n apply_tax boolean DEFAULT true,\n is_priority boolean DEFAULT false\n)\nRETURNS numeric\nLANGUAGE plpgsql\nSECURITY DEFINER\nVOLATILE\nSTRICT\nAS $$\nDECLARE\n total numeric;\nBEGIN\n SELECT amount INTO total FROM orders WHERE id = order_id;\n RETURN total - (total * discount_percent / 100);\nEND;\n$$;", + "sql": "CREATE OR REPLACE FUNCTION mask_sensitive_data(\n input text\n)\nRETURNS text\nLANGUAGE sql\nSTABLE\nLEAKPROOF\nAS $$\n SELECT '***' || substring(input from 4);\n$$;", + "type": "function", + "operation": "create", + "path": "public.mask_sensitive_data" + }, + { + "sql": "CREATE OR REPLACE FUNCTION process_order(\n order_id integer,\n discount_percent numeric DEFAULT 0,\n priority_level integer DEFAULT 1,\n note varchar DEFAULT '',\n status text DEFAULT 'pending',\n apply_tax boolean DEFAULT true,\n is_priority boolean DEFAULT false\n)\nRETURNS numeric\nLANGUAGE plpgsql\nVOLATILE\nSTRICT\nSECURITY DEFINER\nLEAKPROOF\nPARALLEL RESTRICTED\nAS $$\nDECLARE\n total numeric;\nBEGIN\n SELECT amount INTO total FROM orders WHERE id = order_id;\n RETURN total - (total * discount_percent / 100);\nEND;\n$$;", "type": "function", "operation": "create", "path": "public.process_order" diff --git a/testdata/diff/create_function/add_function/plan.sql b/testdata/diff/create_function/add_function/plan.sql index a4e635ba..b1bf99f6 100644 --- a/testdata/diff/create_function/add_function/plan.sql +++ b/testdata/diff/create_function/add_function/plan.sql @@ -1,9 +1,25 @@ -CREATE OR REPLACE FUNCTION days_since_special_date() -RETURNS SETOF timestamp with time zone +CREATE OR REPLACE FUNCTION calculate_tax( + amount numeric, + rate numeric +) +RETURNS numeric +LANGUAGE sql +IMMUTABLE +PARALLEL SAFE +AS $$ + SELECT amount * rate; +$$; + +CREATE OR REPLACE FUNCTION mask_sensitive_data( + input text +) +RETURNS text LANGUAGE sql -SECURITY INVOKER STABLE -RETURN generate_series((date_trunc('day'::text, '2025-01-01 00:00:00'::timestamp without time zone))::timestamp with time zone, date_trunc('day'::text, now()), '1 day'::interval); +LEAKPROOF +AS $$ + SELECT '***' || substring(input from 4); +$$; CREATE OR REPLACE FUNCTION process_order( order_id integer, @@ -16,9 +32,11 @@ CREATE OR REPLACE FUNCTION process_order( ) RETURNS numeric LANGUAGE plpgsql -SECURITY DEFINER VOLATILE STRICT +SECURITY DEFINER +LEAKPROOF +PARALLEL RESTRICTED AS $$ DECLARE total numeric; diff --git a/testdata/diff/create_function/add_function/plan.txt b/testdata/diff/create_function/add_function/plan.txt index cae2ecd3..e8bed1ad 100644 --- a/testdata/diff/create_function/add_function/plan.txt +++ b/testdata/diff/create_function/add_function/plan.txt @@ -1,21 +1,38 @@ -Plan: 2 to add. +Plan: 3 to add. Summary by type: - functions: 2 to add + functions: 3 to add Functions: - + days_since_special_date + + calculate_tax + + mask_sensitive_data + process_order DDL to be executed: -------------------------------------------------- -CREATE OR REPLACE FUNCTION days_since_special_date() -RETURNS SETOF timestamp with time zone +CREATE OR REPLACE FUNCTION calculate_tax( + amount numeric, + rate numeric +) +RETURNS numeric +LANGUAGE sql +IMMUTABLE +PARALLEL SAFE +AS $$ + SELECT amount * rate; +$$; + +CREATE OR REPLACE FUNCTION mask_sensitive_data( + input text +) +RETURNS text LANGUAGE sql -SECURITY INVOKER STABLE -RETURN generate_series((date_trunc('day'::text, '2025-01-01 00:00:00'::timestamp without time zone))::timestamp with time zone, date_trunc('day'::text, now()), '1 day'::interval); +LEAKPROOF +AS $$ + SELECT '***' || substring(input from 4); +$$; CREATE OR REPLACE FUNCTION process_order( order_id integer, @@ -28,9 +45,11 @@ CREATE OR REPLACE FUNCTION process_order( ) RETURNS numeric LANGUAGE plpgsql -SECURITY DEFINER VOLATILE STRICT +SECURITY DEFINER +LEAKPROOF +PARALLEL RESTRICTED AS $$ DECLARE total numeric; diff --git a/testdata/diff/create_function/alter_function_attributes/diff.sql b/testdata/diff/create_function/alter_function_attributes/diff.sql new file mode 100644 index 00000000..1125e2e6 --- /dev/null +++ b/testdata/diff/create_function/alter_function_attributes/diff.sql @@ -0,0 +1,7 @@ +ALTER FUNCTION calculate_total(numeric, numeric) PARALLEL SAFE; + +ALTER FUNCTION calculate_total(numeric, numeric) LEAKPROOF; + +ALTER FUNCTION process_data(text) PARALLEL SAFE; + +ALTER FUNCTION process_data(text) LEAKPROOF; diff --git a/testdata/diff/create_function/alter_function_attributes/new.sql b/testdata/diff/create_function/alter_function_attributes/new.sql new file mode 100644 index 00000000..1fbb936b --- /dev/null +++ b/testdata/diff/create_function/alter_function_attributes/new.sql @@ -0,0 +1,21 @@ +CREATE FUNCTION process_data(input text) +RETURNS text +LANGUAGE plpgsql +VOLATILE +PARALLEL SAFE +LEAKPROOF +AS $$ +BEGIN + RETURN upper(input); +END; +$$; + +CREATE FUNCTION calculate_total(amount numeric, tax_rate numeric) +RETURNS numeric +LANGUAGE sql +STABLE +PARALLEL SAFE +LEAKPROOF +AS $$ + SELECT amount * (1 + tax_rate); +$$; diff --git a/testdata/diff/create_function/alter_function_attributes/old.sql b/testdata/diff/create_function/alter_function_attributes/old.sql new file mode 100644 index 00000000..5db2146d --- /dev/null +++ b/testdata/diff/create_function/alter_function_attributes/old.sql @@ -0,0 +1,17 @@ +CREATE FUNCTION process_data(input text) +RETURNS text +LANGUAGE plpgsql +VOLATILE +AS $$ +BEGIN + RETURN upper(input); +END; +$$; + +CREATE FUNCTION calculate_total(amount numeric, tax_rate numeric) +RETURNS numeric +LANGUAGE sql +STABLE +AS $$ + SELECT amount * (1 + tax_rate); +$$; diff --git a/testdata/diff/create_function/alter_function_attributes/plan.json b/testdata/diff/create_function/alter_function_attributes/plan.json new file mode 100644 index 00000000..66d91aea --- /dev/null +++ b/testdata/diff/create_function/alter_function_attributes/plan.json @@ -0,0 +1,38 @@ +{ + "version": "1.0.0", + "pgschema_version": "1.4.3", + "created_at": "1970-01-01T00:00:00Z", + "source_fingerprint": { + "hash": "547c251b85c0364b36816db73820a51c5980be1979e614ead337b3f93052cb1c" + }, + "groups": [ + { + "steps": [ + { + "sql": "ALTER FUNCTION calculate_total(numeric, numeric) PARALLEL SAFE;", + "type": "function", + "operation": "alter", + "path": "public.calculate_total" + }, + { + "sql": "ALTER FUNCTION calculate_total(numeric, numeric) LEAKPROOF;", + "type": "function", + "operation": "alter", + "path": "public.calculate_total" + }, + { + "sql": "ALTER FUNCTION process_data(text) PARALLEL SAFE;", + "type": "function", + "operation": "alter", + "path": "public.process_data" + }, + { + "sql": "ALTER FUNCTION process_data(text) LEAKPROOF;", + "type": "function", + "operation": "alter", + "path": "public.process_data" + } + ] + } + ] +} diff --git a/testdata/diff/create_function/alter_function_attributes/plan.sql b/testdata/diff/create_function/alter_function_attributes/plan.sql new file mode 100644 index 00000000..1125e2e6 --- /dev/null +++ b/testdata/diff/create_function/alter_function_attributes/plan.sql @@ -0,0 +1,7 @@ +ALTER FUNCTION calculate_total(numeric, numeric) PARALLEL SAFE; + +ALTER FUNCTION calculate_total(numeric, numeric) LEAKPROOF; + +ALTER FUNCTION process_data(text) PARALLEL SAFE; + +ALTER FUNCTION process_data(text) LEAKPROOF; diff --git a/testdata/diff/create_function/alter_function_attributes/plan.txt b/testdata/diff/create_function/alter_function_attributes/plan.txt new file mode 100644 index 00000000..bff6b852 --- /dev/null +++ b/testdata/diff/create_function/alter_function_attributes/plan.txt @@ -0,0 +1,21 @@ +Plan: 4 to modify. + +Summary by type: + functions: 4 to modify + +Functions: + ~ calculate_total + ~ calculate_total + ~ process_data + ~ process_data + +DDL to be executed: +-------------------------------------------------- + +ALTER FUNCTION calculate_total(numeric, numeric) PARALLEL SAFE; + +ALTER FUNCTION calculate_total(numeric, numeric) LEAKPROOF; + +ALTER FUNCTION process_data(text) PARALLEL SAFE; + +ALTER FUNCTION process_data(text) LEAKPROOF; diff --git a/testdata/diff/create_function/alter_function_different_signature/diff.sql b/testdata/diff/create_function/alter_function_different_signature/diff.sql index c65d0503..f86565e5 100644 --- a/testdata/diff/create_function/alter_function_different_signature/diff.sql +++ b/testdata/diff/create_function/alter_function_different_signature/diff.sql @@ -6,8 +6,8 @@ CREATE OR REPLACE FUNCTION process_order( ) RETURNS TABLE(status text, processed_at timestamp) LANGUAGE plpgsql -SECURITY DEFINER STABLE +SECURITY DEFINER AS $$ BEGIN RETURN QUERY diff --git a/testdata/diff/create_function/alter_function_different_signature/plan.json b/testdata/diff/create_function/alter_function_different_signature/plan.json index 63da2859..77c7433f 100644 --- a/testdata/diff/create_function/alter_function_different_signature/plan.json +++ b/testdata/diff/create_function/alter_function_different_signature/plan.json @@ -1,9 +1,9 @@ { "version": "1.0.0", - "pgschema_version": "1.4.0", + "pgschema_version": "1.4.3", "created_at": "1970-01-01T00:00:00Z", "source_fingerprint": { - "hash": "6999cab9e41f75143c1f09a16bb229452a4a06cd1171eece2a7466ca8d1323d6" + "hash": "60f48278b090a2550f1634778976ec483638f67d06485a7e54b22a59d79f31b2" }, "groups": [ { @@ -15,7 +15,7 @@ "path": "public.process_order" }, { - "sql": "CREATE OR REPLACE FUNCTION process_order(\n customer_email text,\n priority boolean\n)\nRETURNS TABLE(status text, processed_at timestamp)\nLANGUAGE plpgsql\nSECURITY DEFINER\nSTABLE\nAS $$\nBEGIN\n RETURN QUERY\n SELECT 'completed'::text, NOW()\n WHERE priority = true;\nEND;\n$$;", + "sql": "CREATE OR REPLACE FUNCTION process_order(\n customer_email text,\n priority boolean\n)\nRETURNS TABLE(status text, processed_at timestamp)\nLANGUAGE plpgsql\nSTABLE\nSECURITY DEFINER\nAS $$\nBEGIN\n RETURN QUERY\n SELECT 'completed'::text, NOW()\n WHERE priority = true;\nEND;\n$$;", "type": "function", "operation": "create", "path": "public.process_order" diff --git a/testdata/diff/create_function/alter_function_different_signature/plan.sql b/testdata/diff/create_function/alter_function_different_signature/plan.sql index c65d0503..f86565e5 100644 --- a/testdata/diff/create_function/alter_function_different_signature/plan.sql +++ b/testdata/diff/create_function/alter_function_different_signature/plan.sql @@ -6,8 +6,8 @@ CREATE OR REPLACE FUNCTION process_order( ) RETURNS TABLE(status text, processed_at timestamp) LANGUAGE plpgsql -SECURITY DEFINER STABLE +SECURITY DEFINER AS $$ BEGIN RETURN QUERY diff --git a/testdata/diff/create_function/alter_function_different_signature/plan.txt b/testdata/diff/create_function/alter_function_different_signature/plan.txt index c4caf7b2..533163d7 100644 --- a/testdata/diff/create_function/alter_function_different_signature/plan.txt +++ b/testdata/diff/create_function/alter_function_different_signature/plan.txt @@ -18,8 +18,8 @@ CREATE OR REPLACE FUNCTION process_order( ) RETURNS TABLE(status text, processed_at timestamp) LANGUAGE plpgsql -SECURITY DEFINER STABLE +SECURITY DEFINER AS $$ BEGIN RETURN QUERY diff --git a/testdata/diff/create_function/alter_function_same_signature/diff.sql b/testdata/diff/create_function/alter_function_same_signature/diff.sql index c86be39a..ee039c57 100644 --- a/testdata/diff/create_function/alter_function_same_signature/diff.sql +++ b/testdata/diff/create_function/alter_function_same_signature/diff.sql @@ -6,7 +6,6 @@ CREATE OR REPLACE FUNCTION process_order( ) RETURNS numeric LANGUAGE plpgsql -SECURITY INVOKER STABLE AS $$ DECLARE diff --git a/testdata/diff/create_function/alter_function_same_signature/plan.json b/testdata/diff/create_function/alter_function_same_signature/plan.json index b2fc2ee6..9ba5ace2 100644 --- a/testdata/diff/create_function/alter_function_same_signature/plan.json +++ b/testdata/diff/create_function/alter_function_same_signature/plan.json @@ -1,15 +1,15 @@ { "version": "1.0.0", - "pgschema_version": "1.4.1", + "pgschema_version": "1.4.3", "created_at": "1970-01-01T00:00:00Z", "source_fingerprint": { - "hash": "6d0c7bd072cf940b17ecae1b64566b63a06bd9cd0aaf2c69a12af2fe77ae6d47" + "hash": "f8f674906f2aa0fee086c386c8ee9da81b6be4db116ef22b9e2e97411fd7e695" }, "groups": [ { "steps": [ { - "sql": "CREATE OR REPLACE FUNCTION process_order(\n order_id integer,\n discount_percent numeric DEFAULT 0,\n status order_status DEFAULT 'pending',\n priority utils.priority_level DEFAULT 'medium'\n)\nRETURNS numeric\nLANGUAGE plpgsql\nSECURITY INVOKER\nSTABLE\nAS $$\nDECLARE\n base_price numeric;\n tax_rate numeric := 0.08;\nBEGIN\n -- Different logic: calculate with tax instead of just discount\n -- Status and priority parameters are available but not used in this simplified version\n SELECT price INTO base_price FROM products WHERE id = order_id;\n RETURN base_price * (1 - discount_percent / 100) * (1 + tax_rate);\nEND;\n$$;", + "sql": "CREATE OR REPLACE FUNCTION process_order(\n order_id integer,\n discount_percent numeric DEFAULT 0,\n status order_status DEFAULT 'pending',\n priority utils.priority_level DEFAULT 'medium'\n)\nRETURNS numeric\nLANGUAGE plpgsql\nSTABLE\nAS $$\nDECLARE\n base_price numeric;\n tax_rate numeric := 0.08;\nBEGIN\n -- Different logic: calculate with tax instead of just discount\n -- Status and priority parameters are available but not used in this simplified version\n SELECT price INTO base_price FROM products WHERE id = order_id;\n RETURN base_price * (1 - discount_percent / 100) * (1 + tax_rate);\nEND;\n$$;", "type": "function", "operation": "alter", "path": "public.process_order" diff --git a/testdata/diff/create_function/alter_function_same_signature/plan.sql b/testdata/diff/create_function/alter_function_same_signature/plan.sql index c86be39a..ee039c57 100644 --- a/testdata/diff/create_function/alter_function_same_signature/plan.sql +++ b/testdata/diff/create_function/alter_function_same_signature/plan.sql @@ -6,7 +6,6 @@ CREATE OR REPLACE FUNCTION process_order( ) RETURNS numeric LANGUAGE plpgsql -SECURITY INVOKER STABLE AS $$ DECLARE diff --git a/testdata/diff/create_function/alter_function_same_signature/plan.txt b/testdata/diff/create_function/alter_function_same_signature/plan.txt index c5a872f0..88e4ac1d 100644 --- a/testdata/diff/create_function/alter_function_same_signature/plan.txt +++ b/testdata/diff/create_function/alter_function_same_signature/plan.txt @@ -17,7 +17,6 @@ CREATE OR REPLACE FUNCTION process_order( ) RETURNS numeric LANGUAGE plpgsql -SECURITY INVOKER STABLE AS $$ DECLARE diff --git a/testdata/diff/create_function/drop_function/plan.json b/testdata/diff/create_function/drop_function/plan.json index 5cc8fb2d..446c0d57 100644 --- a/testdata/diff/create_function/drop_function/plan.json +++ b/testdata/diff/create_function/drop_function/plan.json @@ -1,9 +1,9 @@ { "version": "1.0.0", - "pgschema_version": "1.4.0", + "pgschema_version": "1.4.3", "created_at": "1970-01-01T00:00:00Z", "source_fingerprint": { - "hash": "c34208400ed55b8e5d1ee74c1200d4e126ed191b12f9005e80d878e34885968e" + "hash": "b50e4d62ed25f92850157eef13f4f129a5f082f37da2fe5731342900892c263f" }, "groups": [ { diff --git a/testdata/diff/create_trigger/add_trigger/plan.json b/testdata/diff/create_trigger/add_trigger/plan.json index 0799344b..aa933bfa 100644 --- a/testdata/diff/create_trigger/add_trigger/plan.json +++ b/testdata/diff/create_trigger/add_trigger/plan.json @@ -1,9 +1,9 @@ { "version": "1.0.0", - "pgschema_version": "1.4.0", + "pgschema_version": "1.4.3", "created_at": "1970-01-01T00:00:00Z", "source_fingerprint": { - "hash": "5c096500ddbec5e8aca1b76512fd7076f787118fde4fae6d0a80d99c4335abc1" + "hash": "76b8935489231ab4bd0742f7f1273e9302474f4f6e73ef99b4e24e211058ce37" }, "groups": [ { diff --git a/testdata/diff/create_trigger/add_trigger_constraint/plan.json b/testdata/diff/create_trigger/add_trigger_constraint/plan.json index 810fa1d2..e110af09 100644 --- a/testdata/diff/create_trigger/add_trigger_constraint/plan.json +++ b/testdata/diff/create_trigger/add_trigger_constraint/plan.json @@ -1,9 +1,9 @@ { "version": "1.0.0", - "pgschema_version": "1.4.0", + "pgschema_version": "1.4.3", "created_at": "1970-01-01T00:00:00Z", "source_fingerprint": { - "hash": "08f4c7258568484a7571fb1a332a97279e6dcb5336ddbbf021d777cc1b73730d" + "hash": "40681940fc8b6f55df564abf77a173d29f0faf13cc2a6d3f346ee17f1727dae2" }, "groups": [ { diff --git a/testdata/diff/create_trigger/add_trigger_old_table/plan.json b/testdata/diff/create_trigger/add_trigger_old_table/plan.json index bbc24a43..20771fe9 100644 --- a/testdata/diff/create_trigger/add_trigger_old_table/plan.json +++ b/testdata/diff/create_trigger/add_trigger_old_table/plan.json @@ -1,9 +1,9 @@ { "version": "1.0.0", - "pgschema_version": "1.4.0", + "pgschema_version": "1.4.3", "created_at": "1970-01-01T00:00:00Z", "source_fingerprint": { - "hash": "087a74a25f6a817a556750d274e732048ca5281379e6c0bedd1f5a35176daa2e" + "hash": "c7d5d7ce56f814aa8bc8287c6054c7dbbe0b2df7bdc9563d709d074d7ba4b863" }, "groups": [ { diff --git a/testdata/diff/create_trigger/add_trigger_system_catalog/plan.json b/testdata/diff/create_trigger/add_trigger_system_catalog/plan.json index 33245736..bf57f24c 100644 --- a/testdata/diff/create_trigger/add_trigger_system_catalog/plan.json +++ b/testdata/diff/create_trigger/add_trigger_system_catalog/plan.json @@ -1,6 +1,6 @@ { "version": "1.0.0", - "pgschema_version": "1.4.0", + "pgschema_version": "1.4.3", "created_at": "1970-01-01T00:00:00Z", "source_fingerprint": { "hash": "4620d5c78a7c107496877b2ce463eaaa25ad87fac2cecb93a987e0d9a8ea803a" diff --git a/testdata/diff/create_trigger/add_trigger_when_distinct/plan.json b/testdata/diff/create_trigger/add_trigger_when_distinct/plan.json index 484c3807..55c8cb0d 100644 --- a/testdata/diff/create_trigger/add_trigger_when_distinct/plan.json +++ b/testdata/diff/create_trigger/add_trigger_when_distinct/plan.json @@ -1,9 +1,9 @@ { "version": "1.0.0", - "pgschema_version": "1.4.0", + "pgschema_version": "1.4.3", "created_at": "1970-01-01T00:00:00Z", "source_fingerprint": { - "hash": "98db11096a7a86d2175ff6821924a2b64dddbf240681f23079c0d912d3ea22b5" + "hash": "9f531a58a8a6e5160d9c22fd497d42a0fadbb9324994494f819629b94e46b868" }, "groups": [ { diff --git a/testdata/diff/create_trigger/alter_trigger/plan.json b/testdata/diff/create_trigger/alter_trigger/plan.json index 28c76d72..2052a83c 100644 --- a/testdata/diff/create_trigger/alter_trigger/plan.json +++ b/testdata/diff/create_trigger/alter_trigger/plan.json @@ -1,9 +1,9 @@ { "version": "1.0.0", - "pgschema_version": "1.4.0", + "pgschema_version": "1.4.3", "created_at": "1970-01-01T00:00:00Z", "source_fingerprint": { - "hash": "3532aafb5a93b1bfbd03aab1db8e95d7c02b248ebfa893bfb4af4ab9ac32039a" + "hash": "ba218be2c63f4cf69ba70b4f8dca11b3832609c271cde6166f570aa47026b923" }, "groups": [ { diff --git a/testdata/diff/create_trigger/drop_trigger/plan.json b/testdata/diff/create_trigger/drop_trigger/plan.json index 1f02e3ef..07833b10 100644 --- a/testdata/diff/create_trigger/drop_trigger/plan.json +++ b/testdata/diff/create_trigger/drop_trigger/plan.json @@ -1,9 +1,9 @@ { "version": "1.0.0", - "pgschema_version": "1.4.0", + "pgschema_version": "1.4.3", "created_at": "1970-01-01T00:00:00Z", "source_fingerprint": { - "hash": "3532aafb5a93b1bfbd03aab1db8e95d7c02b248ebfa893bfb4af4ab9ac32039a" + "hash": "ba218be2c63f4cf69ba70b4f8dca11b3832609c271cde6166f570aa47026b923" }, "groups": [ { diff --git a/testdata/diff/dependency/function_to_table/diff.sql b/testdata/diff/dependency/function_to_table/diff.sql index 5baeaa94..31d6e645 100644 --- a/testdata/diff/dependency/function_to_table/diff.sql +++ b/testdata/diff/dependency/function_to_table/diff.sql @@ -1,7 +1,6 @@ CREATE OR REPLACE FUNCTION get_default_status() RETURNS text LANGUAGE plpgsql -SECURITY INVOKER VOLATILE AS $$ BEGIN diff --git a/testdata/diff/dependency/function_to_table/plan.json b/testdata/diff/dependency/function_to_table/plan.json index 487d002e..478ff569 100644 --- a/testdata/diff/dependency/function_to_table/plan.json +++ b/testdata/diff/dependency/function_to_table/plan.json @@ -9,7 +9,7 @@ { "steps": [ { - "sql": "CREATE OR REPLACE FUNCTION get_default_status()\nRETURNS text\nLANGUAGE plpgsql\nSECURITY INVOKER\nVOLATILE\nAS $$\nBEGIN\n RETURN 'active';\nEND;\n$$;", + "sql": "CREATE OR REPLACE FUNCTION get_default_status()\nRETURNS text\nLANGUAGE plpgsql\nVOLATILE\nAS $$\nBEGIN\n RETURN 'active';\nEND;\n$$;", "type": "function", "operation": "create", "path": "public.get_default_status" diff --git a/testdata/diff/dependency/function_to_table/plan.sql b/testdata/diff/dependency/function_to_table/plan.sql index 5baeaa94..31d6e645 100644 --- a/testdata/diff/dependency/function_to_table/plan.sql +++ b/testdata/diff/dependency/function_to_table/plan.sql @@ -1,7 +1,6 @@ CREATE OR REPLACE FUNCTION get_default_status() RETURNS text LANGUAGE plpgsql -SECURITY INVOKER VOLATILE AS $$ BEGIN diff --git a/testdata/diff/dependency/function_to_table/plan.txt b/testdata/diff/dependency/function_to_table/plan.txt index cdfd16b5..9807303d 100644 --- a/testdata/diff/dependency/function_to_table/plan.txt +++ b/testdata/diff/dependency/function_to_table/plan.txt @@ -16,7 +16,6 @@ DDL to be executed: CREATE OR REPLACE FUNCTION get_default_status() RETURNS text LANGUAGE plpgsql -SECURITY INVOKER VOLATILE AS $$ BEGIN diff --git a/testdata/diff/dependency/function_to_trigger/diff.sql b/testdata/diff/dependency/function_to_trigger/diff.sql index 30881a81..9f601547 100644 --- a/testdata/diff/dependency/function_to_trigger/diff.sql +++ b/testdata/diff/dependency/function_to_trigger/diff.sql @@ -4,7 +4,6 @@ DROP FUNCTION IF EXISTS update_modified_time(); CREATE OR REPLACE FUNCTION log_user_changes() RETURNS trigger LANGUAGE plpgsql -SECURITY INVOKER VOLATILE AS $$ BEGIN diff --git a/testdata/diff/dependency/function_to_trigger/plan.json b/testdata/diff/dependency/function_to_trigger/plan.json index 4aafeb21..bbb96a84 100644 --- a/testdata/diff/dependency/function_to_trigger/plan.json +++ b/testdata/diff/dependency/function_to_trigger/plan.json @@ -1,9 +1,9 @@ { "version": "1.0.0", - "pgschema_version": "1.4.0", + "pgschema_version": "1.4.3", "created_at": "1970-01-01T00:00:00Z", "source_fingerprint": { - "hash": "838be5bff5331655f93ff85bf9e620d007f6c664b57889a1efb31343310534c8" + "hash": "318032a6f9451c9ed14e90c4ff0557d9ecf9a5620e9305314a549d884da5f154" }, "groups": [ { @@ -21,7 +21,7 @@ "path": "public.update_modified_time" }, { - "sql": "CREATE OR REPLACE FUNCTION log_user_changes()\nRETURNS trigger\nLANGUAGE plpgsql\nSECURITY INVOKER\nVOLATILE\nAS $$\nBEGIN\n RAISE NOTICE 'User record changed: %', NEW.id;\n RETURN NEW;\nEND;\n$$;", + "sql": "CREATE OR REPLACE FUNCTION log_user_changes()\nRETURNS trigger\nLANGUAGE plpgsql\nVOLATILE\nAS $$\nBEGIN\n RAISE NOTICE 'User record changed: %', NEW.id;\n RETURN NEW;\nEND;\n$$;", "type": "function", "operation": "create", "path": "public.log_user_changes" diff --git a/testdata/diff/dependency/function_to_trigger/plan.sql b/testdata/diff/dependency/function_to_trigger/plan.sql index 1f0084bd..e9f402cb 100644 --- a/testdata/diff/dependency/function_to_trigger/plan.sql +++ b/testdata/diff/dependency/function_to_trigger/plan.sql @@ -5,7 +5,6 @@ DROP FUNCTION IF EXISTS update_modified_time(); CREATE OR REPLACE FUNCTION log_user_changes() RETURNS trigger LANGUAGE plpgsql -SECURITY INVOKER VOLATILE AS $$ BEGIN diff --git a/testdata/diff/dependency/function_to_trigger/plan.txt b/testdata/diff/dependency/function_to_trigger/plan.txt index f3c34cf2..9a45b225 100644 --- a/testdata/diff/dependency/function_to_trigger/plan.txt +++ b/testdata/diff/dependency/function_to_trigger/plan.txt @@ -23,7 +23,6 @@ DROP FUNCTION IF EXISTS update_modified_time(); CREATE OR REPLACE FUNCTION log_user_changes() RETURNS trigger LANGUAGE plpgsql -SECURITY INVOKER VOLATILE AS $$ BEGIN diff --git a/testdata/diff/dependency/table_to_function/diff.sql b/testdata/diff/dependency/table_to_function/diff.sql index bf16996a..22faba8c 100644 --- a/testdata/diff/dependency/table_to_function/diff.sql +++ b/testdata/diff/dependency/table_to_function/diff.sql @@ -9,7 +9,7 @@ CREATE TABLE IF NOT EXISTS documents ( CREATE OR REPLACE FUNCTION get_document_count() RETURNS integer LANGUAGE plpgsql -SECURITY INVOKER + VOLATILE AS $$ BEGIN diff --git a/testdata/diff/dependency/table_to_function/plan.json b/testdata/diff/dependency/table_to_function/plan.json index 14432a86..da534f54 100644 --- a/testdata/diff/dependency/table_to_function/plan.json +++ b/testdata/diff/dependency/table_to_function/plan.json @@ -1,6 +1,6 @@ { "version": "1.0.0", - "pgschema_version": "1.4.0", + "pgschema_version": "1.4.3", "created_at": "1970-01-01T00:00:00Z", "source_fingerprint": { "hash": "965b1131737c955e24c7f827c55bd78e4cb49a75adfd04229e0ba297376f5085" @@ -15,7 +15,7 @@ "path": "public.documents" }, { - "sql": "CREATE OR REPLACE FUNCTION get_document_count()\nRETURNS integer\nLANGUAGE plpgsql\nSECURITY INVOKER\nVOLATILE\nAS $$\nBEGIN\n RETURN (SELECT COUNT(*) FROM documents);\nEND;\n$$;", + "sql": "CREATE OR REPLACE FUNCTION get_document_count()\nRETURNS integer\nLANGUAGE plpgsql\nVOLATILE\nAS $$\nBEGIN\n RETURN (SELECT COUNT(*) FROM documents);\nEND;\n$$;", "type": "function", "operation": "create", "path": "public.get_document_count" diff --git a/testdata/diff/dependency/table_to_function/plan.sql b/testdata/diff/dependency/table_to_function/plan.sql index 69753cb4..61ef271d 100644 --- a/testdata/diff/dependency/table_to_function/plan.sql +++ b/testdata/diff/dependency/table_to_function/plan.sql @@ -9,7 +9,6 @@ CREATE TABLE IF NOT EXISTS documents ( CREATE OR REPLACE FUNCTION get_document_count() RETURNS integer LANGUAGE plpgsql -SECURITY INVOKER VOLATILE AS $$ BEGIN diff --git a/testdata/diff/dependency/table_to_function/plan.txt b/testdata/diff/dependency/table_to_function/plan.txt index 40591717..3a2c94b2 100644 --- a/testdata/diff/dependency/table_to_function/plan.txt +++ b/testdata/diff/dependency/table_to_function/plan.txt @@ -24,7 +24,6 @@ CREATE TABLE IF NOT EXISTS documents ( CREATE OR REPLACE FUNCTION get_document_count() RETURNS integer LANGUAGE plpgsql -SECURITY INVOKER VOLATILE AS $$ BEGIN diff --git a/testdata/diff/dependency/table_to_table/plan.json b/testdata/diff/dependency/table_to_table/plan.json index 04fc9ece..6e9f5136 100644 --- a/testdata/diff/dependency/table_to_table/plan.json +++ b/testdata/diff/dependency/table_to_table/plan.json @@ -1,6 +1,6 @@ { "version": "1.0.0", - "pgschema_version": "1.4.0", + "pgschema_version": "1.4.3", "created_at": "1970-01-01T00:00:00Z", "source_fingerprint": { "hash": "965b1131737c955e24c7f827c55bd78e4cb49a75adfd04229e0ba297376f5085" diff --git a/testdata/diff/migrate/v1/plan.json b/testdata/diff/migrate/v1/plan.json index 50cfbf53..6c85219d 100644 --- a/testdata/diff/migrate/v1/plan.json +++ b/testdata/diff/migrate/v1/plan.json @@ -1,6 +1,6 @@ { "version": "1.0.0", - "pgschema_version": "1.4.0", + "pgschema_version": "1.4.3", "created_at": "1970-01-01T00:00:00Z", "source_fingerprint": { "hash": "965b1131737c955e24c7f827c55bd78e4cb49a75adfd04229e0ba297376f5085" diff --git a/testdata/diff/migrate/v2/plan.json b/testdata/diff/migrate/v2/plan.json index a0e2ce1f..cf14e13b 100644 --- a/testdata/diff/migrate/v2/plan.json +++ b/testdata/diff/migrate/v2/plan.json @@ -1,6 +1,6 @@ { "version": "1.0.0", - "pgschema_version": "1.4.0", + "pgschema_version": "1.4.3", "created_at": "1970-01-01T00:00:00Z", "source_fingerprint": { "hash": "e989216806a1e82a6a01d6d5898b00b5d94d3a5888c6ef481fa5f931f649aab5" diff --git a/testdata/diff/migrate/v3/diff.sql b/testdata/diff/migrate/v3/diff.sql index 601646cc..94cf41ed 100644 --- a/testdata/diff/migrate/v3/diff.sql +++ b/testdata/diff/migrate/v3/diff.sql @@ -12,7 +12,6 @@ CREATE INDEX IF NOT EXISTS idx_audit_changed_at ON audit (changed_at); CREATE OR REPLACE FUNCTION log_dml_operations() RETURNS trigger LANGUAGE plpgsql -SECURITY INVOKER VOLATILE AS $$ BEGIN diff --git a/testdata/diff/migrate/v3/plan.json b/testdata/diff/migrate/v3/plan.json index 6e302e7e..8c558556 100644 --- a/testdata/diff/migrate/v3/plan.json +++ b/testdata/diff/migrate/v3/plan.json @@ -1,6 +1,6 @@ { "version": "1.0.0", - "pgschema_version": "1.4.0", + "pgschema_version": "1.4.3", "created_at": "1970-01-01T00:00:00Z", "source_fingerprint": { "hash": "b07ab6318b6ff348aa5554a1f6e1a1ec9ad6b987a6d47e455fbdf97f1b0b96fb" @@ -21,7 +21,7 @@ "path": "public.audit.idx_audit_changed_at" }, { - "sql": "CREATE OR REPLACE FUNCTION log_dml_operations()\nRETURNS trigger\nLANGUAGE plpgsql\nSECURITY INVOKER\nVOLATILE\nAS $$\nBEGIN\n IF (TG_OP = 'INSERT') THEN\n INSERT INTO audit (operation, query, user_name)\n VALUES ('INSERT', current_query(), current_user);\n RETURN NEW;\n ELSIF (TG_OP = 'UPDATE') THEN\n INSERT INTO audit (operation, query, user_name)\n VALUES ('UPDATE', current_query(), current_user);\n RETURN NEW;\n ELSIF (TG_OP = 'DELETE') THEN\n INSERT INTO audit (operation, query, user_name)\n VALUES ('DELETE', current_query(), current_user);\n RETURN OLD;\n END IF;\n RETURN NULL;\nEND;\n$$;", + "sql": "CREATE OR REPLACE FUNCTION log_dml_operations()\nRETURNS trigger\nLANGUAGE plpgsql\nVOLATILE\nAS $$\nBEGIN\n IF (TG_OP = 'INSERT') THEN\n INSERT INTO audit (operation, query, user_name)\n VALUES ('INSERT', current_query(), current_user);\n RETURN NEW;\n ELSIF (TG_OP = 'UPDATE') THEN\n INSERT INTO audit (operation, query, user_name)\n VALUES ('UPDATE', current_query(), current_user);\n RETURN NEW;\n ELSIF (TG_OP = 'DELETE') THEN\n INSERT INTO audit (operation, query, user_name)\n VALUES ('DELETE', current_query(), current_user);\n RETURN OLD;\n END IF;\n RETURN NULL;\nEND;\n$$;", "type": "function", "operation": "create", "path": "public.log_dml_operations" diff --git a/testdata/diff/migrate/v3/plan.sql b/testdata/diff/migrate/v3/plan.sql index 601646cc..94cf41ed 100644 --- a/testdata/diff/migrate/v3/plan.sql +++ b/testdata/diff/migrate/v3/plan.sql @@ -12,7 +12,6 @@ CREATE INDEX IF NOT EXISTS idx_audit_changed_at ON audit (changed_at); CREATE OR REPLACE FUNCTION log_dml_operations() RETURNS trigger LANGUAGE plpgsql -SECURITY INVOKER VOLATILE AS $$ BEGIN diff --git a/testdata/diff/migrate/v3/plan.txt b/testdata/diff/migrate/v3/plan.txt index cccb1741..a4bed376 100644 --- a/testdata/diff/migrate/v3/plan.txt +++ b/testdata/diff/migrate/v3/plan.txt @@ -30,7 +30,6 @@ CREATE INDEX IF NOT EXISTS idx_audit_changed_at ON audit (changed_at); CREATE OR REPLACE FUNCTION log_dml_operations() RETURNS trigger LANGUAGE plpgsql -SECURITY INVOKER VOLATILE AS $$ BEGIN diff --git a/testdata/diff/migrate/v4/diff.sql b/testdata/diff/migrate/v4/diff.sql index d562a0b6..505054e4 100644 --- a/testdata/diff/migrate/v4/diff.sql +++ b/testdata/diff/migrate/v4/diff.sql @@ -58,7 +58,6 @@ CREATE OR REPLACE TRIGGER salary_log_trigger CREATE OR REPLACE FUNCTION log_dml_operations() RETURNS trigger LANGUAGE plpgsql -SECURITY INVOKER VOLATILE AS $$ DECLARE diff --git a/testdata/diff/migrate/v4/plan.json b/testdata/diff/migrate/v4/plan.json index f6a7d717..c1a3dce6 100644 --- a/testdata/diff/migrate/v4/plan.json +++ b/testdata/diff/migrate/v4/plan.json @@ -1,9 +1,9 @@ { "version": "1.0.0", - "pgschema_version": "1.4.0", + "pgschema_version": "1.4.3", "created_at": "1970-01-01T00:00:00Z", "source_fingerprint": { - "hash": "953c5263c9185d170429fab8c78931f7801f8479579faf963c0ac9635bf2a8ed" + "hash": "c21343c0165a56727a51734705b31278a07e32f8a88cd17fb12dd0a026756403" }, "groups": [ { @@ -97,7 +97,7 @@ "path": "public.salary.salary_log_trigger" }, { - "sql": "CREATE OR REPLACE FUNCTION log_dml_operations()\nRETURNS trigger\nLANGUAGE plpgsql\nSECURITY INVOKER\nVOLATILE\nAS $$\nDECLARE\n table_category TEXT;\n log_level TEXT;\nBEGIN\n -- Get arguments passed from trigger (if any)\n -- TG_ARGV[0] is the first argument, TG_ARGV[1] is the second\n table_category := COALESCE(TG_ARGV[0], 'default');\n log_level := COALESCE(TG_ARGV[1], 'standard');\n\n IF (TG_OP = 'INSERT') THEN\n INSERT INTO audit (operation, query, user_name)\n VALUES (\n 'INSERT [' || table_category || ':' || log_level || ']',\n current_query(),\n current_user\n );\n RETURN NEW;\n ELSIF (TG_OP = 'UPDATE') THEN\n INSERT INTO audit (operation, query, user_name)\n VALUES (\n 'UPDATE [' || table_category || ':' || log_level || ']',\n current_query(),\n current_user\n );\n RETURN NEW;\n ELSIF (TG_OP = 'DELETE') THEN\n INSERT INTO audit (operation, query, user_name)\n VALUES (\n 'DELETE [' || table_category || ':' || log_level || ']',\n current_query(),\n current_user\n );\n RETURN OLD;\n END IF;\n RETURN NULL;\nEND;\n$$;", + "sql": "CREATE OR REPLACE FUNCTION log_dml_operations()\nRETURNS trigger\nLANGUAGE plpgsql\nVOLATILE\nAS $$\nDECLARE\n table_category TEXT;\n log_level TEXT;\nBEGIN\n -- Get arguments passed from trigger (if any)\n -- TG_ARGV[0] is the first argument, TG_ARGV[1] is the second\n table_category := COALESCE(TG_ARGV[0], 'default');\n log_level := COALESCE(TG_ARGV[1], 'standard');\n\n IF (TG_OP = 'INSERT') THEN\n INSERT INTO audit (operation, query, user_name)\n VALUES (\n 'INSERT [' || table_category || ':' || log_level || ']',\n current_query(),\n current_user\n );\n RETURN NEW;\n ELSIF (TG_OP = 'UPDATE') THEN\n INSERT INTO audit (operation, query, user_name)\n VALUES (\n 'UPDATE [' || table_category || ':' || log_level || ']',\n current_query(),\n current_user\n );\n RETURN NEW;\n ELSIF (TG_OP = 'DELETE') THEN\n INSERT INTO audit (operation, query, user_name)\n VALUES (\n 'DELETE [' || table_category || ':' || log_level || ']',\n current_query(),\n current_user\n );\n RETURN OLD;\n END IF;\n RETURN NULL;\nEND;\n$$;", "type": "function", "operation": "alter", "path": "public.log_dml_operations" diff --git a/testdata/diff/migrate/v4/plan.sql b/testdata/diff/migrate/v4/plan.sql index 6d23c874..e6c6016b 100644 --- a/testdata/diff/migrate/v4/plan.sql +++ b/testdata/diff/migrate/v4/plan.sql @@ -82,7 +82,6 @@ CREATE OR REPLACE TRIGGER salary_log_trigger CREATE OR REPLACE FUNCTION log_dml_operations() RETURNS trigger LANGUAGE plpgsql -SECURITY INVOKER VOLATILE AS $$ DECLARE diff --git a/testdata/diff/migrate/v4/plan.txt b/testdata/diff/migrate/v4/plan.txt index 3a245ba7..4496e76b 100644 --- a/testdata/diff/migrate/v4/plan.txt +++ b/testdata/diff/migrate/v4/plan.txt @@ -121,7 +121,6 @@ CREATE OR REPLACE TRIGGER salary_log_trigger CREATE OR REPLACE FUNCTION log_dml_operations() RETURNS trigger LANGUAGE plpgsql -SECURITY INVOKER VOLATILE AS $$ DECLARE diff --git a/testdata/diff/migrate/v5/plan.json b/testdata/diff/migrate/v5/plan.json index 652aea01..49dbf0ab 100644 --- a/testdata/diff/migrate/v5/plan.json +++ b/testdata/diff/migrate/v5/plan.json @@ -1,9 +1,9 @@ { "version": "1.0.0", - "pgschema_version": "1.4.0", + "pgschema_version": "1.4.3", "created_at": "1970-01-01T00:00:00Z", "source_fingerprint": { - "hash": "00cecda254bb0731ef1d20915ed24ba4cdfd550430d43bfb9e0d0815c4f1b738" + "hash": "9a12c55798891493337f5358504b1c58cddb3260d0d581698c849c6ae57a4359" }, "groups": [ { diff --git a/testdata/dump/employee/pgschema.sql b/testdata/dump/employee/pgschema.sql index c9aeb029..a2023f67 100644 --- a/testdata/dump/employee/pgschema.sql +++ b/testdata/dump/employee/pgschema.sql @@ -3,7 +3,7 @@ -- -- Dumped from database version PostgreSQL 17.5 --- Dumped by pgschema version 1.4.1 +-- Dumped by pgschema version 1.4.3 -- @@ -154,7 +154,6 @@ CREATE TABLE IF NOT EXISTS title ( CREATE OR REPLACE FUNCTION log_dml_operations() RETURNS trigger LANGUAGE plpgsql -SECURITY INVOKER VOLATILE AS $$ DECLARE diff --git a/testdata/dump/issue_125_function_default/pgschema.sql b/testdata/dump/issue_125_function_default/pgschema.sql index 0ae6b165..51b53434 100644 --- a/testdata/dump/issue_125_function_default/pgschema.sql +++ b/testdata/dump/issue_125_function_default/pgschema.sql @@ -3,7 +3,7 @@ -- -- Dumped from database version PostgreSQL 17.5 --- Dumped by pgschema version 1.4.0 +-- Dumped by pgschema version 1.4.3 -- @@ -18,7 +18,6 @@ CREATE OR REPLACE FUNCTION test_complex_defaults( ) RETURNS jsonb LANGUAGE plpgsql -SECURITY INVOKER VOLATILE AS $$ BEGIN @@ -42,7 +41,6 @@ CREATE OR REPLACE FUNCTION test_inout_params( ) RETURNS record LANGUAGE plpgsql -SECURITY INVOKER VOLATILE AS $$ BEGIN @@ -64,7 +62,6 @@ CREATE OR REPLACE FUNCTION test_mixed_params( ) RETURNS record LANGUAGE plpgsql -SECURITY INVOKER VOLATILE AS $$ BEGIN @@ -86,7 +83,6 @@ CREATE OR REPLACE FUNCTION test_simple_defaults( ) RETURNS text LANGUAGE plpgsql -SECURITY INVOKER VOLATILE AS $$ BEGIN @@ -104,7 +100,6 @@ CREATE OR REPLACE FUNCTION test_variadic_defaults( ) RETURNS text LANGUAGE plpgsql -SECURITY INVOKER VOLATILE AS $$ BEGIN diff --git a/testdata/dump/sakila/pgschema.sql b/testdata/dump/sakila/pgschema.sql index c8a90104..bfcb5efe 100644 --- a/testdata/dump/sakila/pgschema.sql +++ b/testdata/dump/sakila/pgschema.sql @@ -3,7 +3,7 @@ -- -- Dumped from database version PostgreSQL 17.5 --- Dumped by pgschema version 1.4.0 +-- Dumped by pgschema version 1.4.3 -- @@ -601,7 +601,6 @@ CREATE OR REPLACE FUNCTION _group_concat( ) RETURNS text LANGUAGE sql -SECURITY INVOKER IMMUTABLE AS $_$ SELECT CASE @@ -622,7 +621,6 @@ CREATE OR REPLACE FUNCTION film_in_stock( ) RETURNS SETOF integer LANGUAGE sql -SECURITY INVOKER VOLATILE AS $_$ SELECT inventory_id @@ -643,7 +641,6 @@ CREATE OR REPLACE FUNCTION film_not_in_stock( ) RETURNS SETOF integer LANGUAGE sql -SECURITY INVOKER VOLATILE AS $_$ SELECT inventory_id @@ -663,7 +660,6 @@ CREATE OR REPLACE FUNCTION get_customer_balance( ) RETURNS numeric LANGUAGE plpgsql -SECURITY INVOKER VOLATILE AS $$ --#OK, WE NEED TO CALCULATE THE CURRENT BALANCE GIVEN A CUSTOMER_ID AND A DATE @@ -710,7 +706,6 @@ CREATE OR REPLACE FUNCTION inventory_held_by_customer( ) RETURNS integer LANGUAGE plpgsql -SECURITY INVOKER VOLATILE AS $$ DECLARE @@ -735,7 +730,6 @@ CREATE OR REPLACE FUNCTION inventory_in_stock( ) RETURNS boolean LANGUAGE plpgsql -SECURITY INVOKER VOLATILE AS $$ DECLARE @@ -775,7 +769,6 @@ CREATE OR REPLACE FUNCTION last_day( ) RETURNS date LANGUAGE sql -SECURITY INVOKER IMMUTABLE STRICT AS $_$ @@ -794,7 +787,6 @@ $_$; CREATE OR REPLACE FUNCTION last_updated() RETURNS trigger LANGUAGE plpgsql -SECURITY INVOKER VOLATILE AS $$ BEGIN @@ -813,8 +805,8 @@ CREATE OR REPLACE FUNCTION rewards_report( ) RETURNS SETOF customer LANGUAGE plpgsql -SECURITY DEFINER VOLATILE +SECURITY DEFINER AS $_$ DECLARE last_month_start DATE; diff --git a/testdata/dump/tenant/pgschema.sql b/testdata/dump/tenant/pgschema.sql index 87931cd1..2de303de 100644 --- a/testdata/dump/tenant/pgschema.sql +++ b/testdata/dump/tenant/pgschema.sql @@ -3,7 +3,7 @@ -- -- Dumped from database version PostgreSQL 17.5 --- Dumped by pgschema version 1.4.0 +-- Dumped by pgschema version 1.4.3 -- @@ -100,7 +100,6 @@ CREATE OR REPLACE FUNCTION create_task_assignment( ) RETURNS task_assignment LANGUAGE plpgsql -SECURITY INVOKER VOLATILE AS $$ DECLARE @@ -120,7 +119,6 @@ $$; CREATE OR REPLACE FUNCTION generate_task_id() RETURNS text LANGUAGE plpgsql -SECURITY INVOKER VOLATILE AS $$ BEGIN @@ -137,7 +135,6 @@ CREATE OR REPLACE FUNCTION set_task_priority( ) RETURNS void LANGUAGE plpgsql -SECURITY INVOKER VOLATILE AS $$ BEGIN diff --git a/testdata/include/expected_full_schema.sql b/testdata/include/expected_full_schema.sql index 8d444e55..d25fc315 100644 --- a/testdata/include/expected_full_schema.sql +++ b/testdata/include/expected_full_schema.sql @@ -59,7 +59,6 @@ CREATE SEQUENCE IF NOT EXISTS order_number_seq; CREATE OR REPLACE FUNCTION update_timestamp() RETURNS trigger LANGUAGE plpgsql -SECURITY INVOKER STABLE AS $$ BEGIN @@ -167,7 +166,6 @@ CREATE POLICY orders_policy ON orders TO PUBLIC USING (user_id = 1); CREATE OR REPLACE FUNCTION get_user_count() RETURNS integer LANGUAGE sql -SECURITY INVOKER VOLATILE AS $$ SELECT COUNT(*) FROM users; @@ -181,7 +179,6 @@ CREATE OR REPLACE FUNCTION get_order_count( ) RETURNS integer LANGUAGE sql -SECURITY INVOKER VOLATILE AS $$ SELECT COUNT(*) FROM orders WHERE user_id = user_id_param; diff --git a/testdata/include/functions/get_order_count.sql b/testdata/include/functions/get_order_count.sql index 81f22968..91d79ef0 100644 --- a/testdata/include/functions/get_order_count.sql +++ b/testdata/include/functions/get_order_count.sql @@ -7,7 +7,6 @@ CREATE OR REPLACE FUNCTION get_order_count( ) RETURNS integer LANGUAGE sql -SECURITY INVOKER VOLATILE AS $$ SELECT COUNT(*) FROM orders WHERE user_id = user_id_param; diff --git a/testdata/include/functions/get_user_count.sql b/testdata/include/functions/get_user_count.sql index 73f71229..34df79b0 100644 --- a/testdata/include/functions/get_user_count.sql +++ b/testdata/include/functions/get_user_count.sql @@ -5,7 +5,6 @@ CREATE OR REPLACE FUNCTION get_user_count() RETURNS integer LANGUAGE sql -SECURITY INVOKER VOLATILE AS $$ SELECT COUNT(*) FROM users; diff --git a/testdata/include/functions/update_timestamp.sql b/testdata/include/functions/update_timestamp.sql index c90dc720..773c4244 100644 --- a/testdata/include/functions/update_timestamp.sql +++ b/testdata/include/functions/update_timestamp.sql @@ -5,7 +5,6 @@ CREATE OR REPLACE FUNCTION update_timestamp() RETURNS trigger LANGUAGE plpgsql -SECURITY INVOKER STABLE AS $$ BEGIN