Skip to content

Commit ee520e1

Browse files
committed
Sort functions and triggers
1 parent b2b41c0 commit ee520e1

2 files changed

Lines changed: 35 additions & 4 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
1010
## [0.3.0] - 2026-06-02
1111

1212
- Add Rails 8.0 & 8.1 as known versions
13+
- Sort functions and triggers
1314

1415
## [0.2.0] - 2024-12-03
1516

lib/active_record/full_text_search/7.2/postgresql_adapter.rb

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,44 @@ module PostgreSQLAdapter
1515
def functions
1616
# List of functions in the current schema with their argument types, return type, language, immutability, and body.
1717
# List only functions that don't depend on extensions.
18+
# Functions are ordered by dependency depth (via pg_depend) so that dependencies come first.
1819
res = exec_query(<<-SQL.strip_heredoc, "SCHEMA")
20+
WITH RECURSIVE
21+
func_deps AS (
22+
SELECT p.oid AS func_oid, dep_p.oid AS dep_func_oid
23+
FROM pg_catalog.pg_proc p
24+
JOIN pg_catalog.pg_namespace n ON n.oid = p.pronamespace
25+
JOIN pg_catalog.pg_depend fd ON fd.objid = p.oid AND fd.deptype = 'n'
26+
JOIN pg_catalog.pg_proc dep_p ON dep_p.oid = fd.refobjid
27+
JOIN pg_catalog.pg_namespace dep_n ON dep_n.oid = dep_p.pronamespace
28+
WHERE n.nspname = ANY (current_schemas(false))
29+
AND dep_n.nspname = ANY (current_schemas(false))
30+
AND p.oid != dep_p.oid
31+
),
32+
levels(oid, level) AS (
33+
SELECT p.oid, 0
34+
FROM pg_catalog.pg_proc p
35+
JOIN pg_catalog.pg_namespace n ON n.oid = p.pronamespace
36+
WHERE n.nspname = ANY (current_schemas(false))
37+
AND p.oid NOT IN (SELECT func_oid FROM func_deps)
38+
UNION ALL
39+
SELECT fd.func_oid, l.level + 1
40+
FROM func_deps fd
41+
JOIN levels l ON l.oid = fd.dep_func_oid
42+
),
43+
max_levels AS (
44+
SELECT oid, MAX(level) AS level FROM levels GROUP BY oid
45+
)
1946
SELECT proname, pg_catalog.pg_get_function_arguments(p.oid) AS argtypes, pg_catalog.pg_get_function_result(p.oid) AS rettype, lanname, provolatile, prosrc
2047
FROM pg_catalog.pg_proc p
21-
JOIN pg_catalog.pg_namespace n ON n.oid = pronamespace
22-
JOIN pg_catalog.pg_language l ON l.oid = prolang
48+
JOIN pg_catalog.pg_namespace n ON n.oid = p.pronamespace
49+
JOIN pg_catalog.pg_language l ON l.oid = p.prolang
2350
LEFT JOIN pg_catalog.pg_depend d ON d.objid = p.oid AND d.deptype = 'e'
2451
LEFT JOIN pg_catalog.pg_extension e ON e.oid = d.refobjid
52+
JOIN max_levels ml ON ml.oid = p.oid
2553
WHERE n.nspname = ANY (current_schemas(false))
26-
AND e.extname IS NULL;
54+
AND e.extname IS NULL
55+
ORDER BY ml.level, proname;
2756
SQL
2857

2958
res.rows.each_with_object({}) do |(name, args, ret, lang, vol, src), memo|
@@ -60,7 +89,8 @@ def triggers
6089
LEFT JOIN pg_catalog.pg_extension e ON e.oid = d.refobjid
6190
WHERE n.nspname = ANY (current_schemas(false))
6291
AND tgisinternal = FALSE
63-
AND e.extname IS NULL;
92+
AND e.extname IS NULL
93+
ORDER BY c.relname, tgname;
6494
SQL
6595

6696
res.rows.each_with_object({}) do |(name, table, function, timing, ops, for_each, definition, deferrable, initially_deferred), memo|

0 commit comments

Comments
 (0)