Repository navigation
Expand file tree
/
Copy pathlint.sql
More file actions
191 lines (167 loc) · 5.49 KB
/
Copy pathlint.sql
File metadata and controls
191 lines (167 loc) · 5.49 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
-- ============================================================================
-- PL/pgSQL Linting with plpgsql_check
-- ============================================================================
--
-- This script validates all rrule functions using the plpgsql_check extension.
-- It catches semantic errors, type mismatches, and other issues before runtime.
--
-- Usage:
-- psql -d rrule_test -f lint.sql
--
-- Requirements:
-- - PostgreSQL 17.x
-- - plpgsql_check extension available
-- - rrule schema must be installed first
--
-- ============================================================================
\set ON_ERROR_STOP on
\set QUIET on
-- Enable plpgsql_check extension
CREATE EXTENSION IF NOT EXISTS plpgsql_check;
-- Create results table
CREATE TEMPORARY TABLE lint_results (
function_name TEXT,
issue_type TEXT,
message TEXT
);
-- Counter for progress
CREATE TEMPORARY TABLE lint_progress (
total INT DEFAULT 0,
current INT DEFAULT 0
);
INSERT INTO lint_progress VALUES (0, 0);
\echo ''
\echo '=============================================='
\echo 'PLPGSQL_CHECK LINTER FOR RRULE_PLPGSQL'
\echo '=============================================='
\echo ''
-- ============================================================================
-- Auto-discover and lint all PL/pgSQL functions in rrule schema
-- ============================================================================
\echo 'Discovering functions in rrule schema...'
DO $$
DECLARE
func_record RECORD;
func_oid OID;
func_signature TEXT;
lint_row RECORD;
func_count INT := 0;
linted_count INT := 0;
BEGIN
-- Count total plpgsql functions
SELECT COUNT(*) INTO func_count
FROM pg_proc p
JOIN pg_namespace n ON p.pronamespace = n.oid
JOIN pg_language l ON p.prolang = l.oid
WHERE n.nspname = 'rrule'
AND l.lanname = 'plpgsql';
RAISE NOTICE 'Found % PL/pgSQL functions to lint', func_count;
RAISE NOTICE '';
-- Iterate through all plpgsql functions in rrule schema
FOR func_record IN
SELECT
p.oid,
n.nspname || '.' || p.proname AS func_name,
pg_get_function_identity_arguments(p.oid) AS args,
p.proname
FROM pg_proc p
JOIN pg_namespace n ON p.pronamespace = n.oid
JOIN pg_language l ON p.prolang = l.oid
WHERE n.nspname = 'rrule'
AND l.lanname = 'plpgsql'
ORDER BY p.proname
LOOP
func_oid := func_record.oid;
func_signature := func_record.func_name || '(' || func_record.args || ')';
linted_count := linted_count + 1;
RAISE NOTICE '[%/%] Linting: %', linted_count, func_count, func_signature;
-- Run plpgsql_check on this function
BEGIN
FOR lint_row IN
SELECT * FROM plpgsql_check_function(func_oid)
LOOP
INSERT INTO lint_results VALUES (
func_signature,
CASE
WHEN lint_row.plpgsql_check_function LIKE 'error%' THEN 'ERROR'
WHEN lint_row.plpgsql_check_function LIKE 'warning%' THEN 'WARNING'
ELSE 'INFO'
END,
lint_row.plpgsql_check_function
);
END LOOP;
-- If no issues found, record as clean
IF NOT EXISTS (SELECT 1 FROM lint_results WHERE function_name = func_signature) THEN
INSERT INTO lint_results VALUES (func_signature, 'CLEAN', 'No issues found');
END IF;
EXCEPTION WHEN OTHERS THEN
INSERT INTO lint_results VALUES (
func_signature,
'SKIP',
'Could not lint: ' || SQLERRM
);
END;
END LOOP;
RAISE NOTICE '';
RAISE NOTICE 'Linting complete!';
END;
$$;
-- ============================================================================
-- Report results
-- ============================================================================
\echo ''
\echo '=============================================='
\echo 'LINT RESULTS'
\echo '=============================================='
-- Show errors first (these are critical)
\echo ''
\echo 'ERRORS (must fix):'
SELECT
function_name AS "Function",
message AS "Issue"
FROM lint_results
WHERE issue_type = 'ERROR'
ORDER BY function_name;
-- Show warnings (should review)
\echo ''
\echo 'WARNINGS (should review):'
SELECT
function_name AS "Function",
message AS "Issue"
FROM lint_results
WHERE issue_type = 'WARNING'
ORDER BY function_name;
-- Show skipped (informational)
\echo ''
\echo 'SKIPPED (could not lint):'
SELECT
function_name AS "Function",
message AS "Reason"
FROM lint_results
WHERE issue_type = 'SKIP'
ORDER BY function_name;
-- Summary
\echo ''
\echo '=============================================='
\echo 'SUMMARY'
\echo '=============================================='
SELECT
COUNT(*) FILTER (WHERE issue_type = 'ERROR') AS "Errors",
COUNT(*) FILTER (WHERE issue_type = 'WARNING') AS "Warnings",
COUNT(*) FILTER (WHERE issue_type = 'SKIP') AS "Skipped",
COUNT(*) FILTER (WHERE issue_type = 'CLEAN') AS "Clean"
FROM lint_results;
-- Fail if there are errors
DO $$
DECLARE
error_count INT;
BEGIN
SELECT COUNT(*) INTO error_count FROM lint_results WHERE issue_type = 'ERROR';
IF error_count > 0 THEN
RAISE EXCEPTION E'\n❌ LINTING FAILED: % error(s) found\n', error_count;
END IF;
END;
$$;
\echo ''
\echo '✅ All functions passed linting (no errors)!'
\echo ''