Skip to content

Commit 39b0985

Browse files
authored
Merge pull request #268 from constructive-io/devin/1767717431-schema-transform-demo
test(plpgsql-deparser): add schema transform demo test with fixture-based snapshots
2 parents e41670d + 08d5a57 commit 39b0985

File tree

4 files changed

+1450
-0
lines changed

4 files changed

+1450
-0
lines changed
Lines changed: 213 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,213 @@
1+
-- Fixtures to test schema rename traversal
2+
-- These exercise complex scenarios with multiple schema references across different contexts
3+
4+
-- Test 1: Function with schema-qualified table references in SELECT
5+
CREATE FUNCTION app_public.get_user_stats(p_user_id int)
6+
RETURNS int
7+
LANGUAGE plpgsql AS $$
8+
DECLARE
9+
total_count int;
10+
BEGIN
11+
SELECT count(*) INTO total_count
12+
FROM app_public.users u
13+
JOIN app_public.orders o ON o.user_id = u.id
14+
WHERE u.id = p_user_id;
15+
RETURN total_count;
16+
END$$;
17+
18+
-- Test 2: Trigger function with INSERT into schema-qualified table
19+
CREATE FUNCTION app_public.audit_changes()
20+
RETURNS trigger
21+
LANGUAGE plpgsql AS $$
22+
BEGIN
23+
INSERT INTO app_public.audit_log (table_name, operation, old_data, new_data, changed_at)
24+
VALUES (TG_TABLE_NAME, TG_OP, to_json(OLD), to_json(NEW), now());
25+
26+
IF TG_OP = 'DELETE' THEN
27+
RETURN OLD;
28+
END IF;
29+
RETURN NEW;
30+
END$$;
31+
32+
-- Test 3: Function with UPDATE to schema-qualified table
33+
CREATE FUNCTION app_public.update_user_status(p_user_id int, p_status text)
34+
RETURNS void
35+
LANGUAGE plpgsql AS $$
36+
BEGIN
37+
UPDATE app_public.users
38+
SET status = p_status, updated_at = now()
39+
WHERE id = p_user_id;
40+
41+
INSERT INTO app_public.status_history (user_id, status, changed_at)
42+
VALUES (p_user_id, p_status, now());
43+
END$$;
44+
45+
-- Test 4: Function with DELETE from schema-qualified table
46+
CREATE FUNCTION app_public.cleanup_old_sessions(p_days int)
47+
RETURNS int
48+
LANGUAGE plpgsql AS $$
49+
DECLARE
50+
deleted_count int;
51+
BEGIN
52+
DELETE FROM app_public.sessions
53+
WHERE created_at < now() - (p_days || ' days')::interval;
54+
55+
GET DIAGNOSTICS deleted_count = ROW_COUNT;
56+
RETURN deleted_count;
57+
END$$;
58+
59+
-- Test 5: SETOF function with RETURN QUERY and schema-qualified tables
60+
CREATE FUNCTION app_public.get_active_orders(p_status text)
61+
RETURNS SETOF int
62+
LANGUAGE plpgsql AS $$
63+
BEGIN
64+
RETURN QUERY
65+
SELECT o.id
66+
FROM app_public.orders o
67+
JOIN app_public.users u ON u.id = o.user_id
68+
WHERE o.status = p_status
69+
AND u.is_active = true;
70+
RETURN;
71+
END$$;
72+
73+
-- Test 6: Function with schema-qualified function calls in expressions
74+
CREATE FUNCTION app_public.calculate_order_total(p_order_id int)
75+
RETURNS numeric
76+
LANGUAGE plpgsql AS $$
77+
DECLARE
78+
subtotal numeric;
79+
tax_amount numeric;
80+
discount numeric;
81+
BEGIN
82+
SELECT sum(quantity * price) INTO subtotal
83+
FROM app_public.order_items
84+
WHERE order_id = p_order_id;
85+
86+
tax_amount := app_public.get_tax_rate() * subtotal;
87+
discount := app_public.get_discount(p_order_id);
88+
89+
RETURN subtotal + tax_amount - discount;
90+
END$$;
91+
92+
-- Test 7: Function with multiple schema references in complex query
93+
CREATE FUNCTION app_public.get_user_dashboard(p_user_id int)
94+
RETURNS TABLE(metric_name text, metric_value numeric)
95+
LANGUAGE plpgsql AS $$
96+
BEGIN
97+
RETURN QUERY
98+
SELECT 'total_orders'::text, count(*)::numeric
99+
FROM app_public.orders
100+
WHERE user_id = p_user_id
101+
UNION ALL
102+
SELECT 'total_spent'::text, coalesce(sum(total), 0)::numeric
103+
FROM app_public.orders
104+
WHERE user_id = p_user_id
105+
UNION ALL
106+
SELECT 'active_subscriptions'::text, count(*)::numeric
107+
FROM app_public.subscriptions
108+
WHERE user_id = p_user_id AND status = 'active';
109+
RETURN;
110+
END$$;
111+
112+
-- Test 8: Trigger function with conditional logic and multiple tables
113+
CREATE FUNCTION app_public.sync_user_profile()
114+
RETURNS trigger
115+
LANGUAGE plpgsql AS $$
116+
DECLARE
117+
profile_exists boolean;
118+
BEGIN
119+
SELECT EXISTS(
120+
SELECT 1 FROM app_public.profiles WHERE user_id = NEW.id
121+
) INTO profile_exists;
122+
123+
IF NOT profile_exists THEN
124+
INSERT INTO app_public.profiles (user_id, created_at)
125+
VALUES (NEW.id, now());
126+
ELSE
127+
UPDATE app_public.profiles
128+
SET updated_at = now()
129+
WHERE user_id = NEW.id;
130+
END IF;
131+
132+
PERFORM app_public.notify_profile_change(NEW.id);
133+
RETURN NEW;
134+
END$$;
135+
136+
-- Test 9: Function with CTE and schema-qualified references
137+
CREATE FUNCTION app_public.get_top_customers(p_limit int)
138+
RETURNS SETOF int
139+
LANGUAGE plpgsql AS $$
140+
BEGIN
141+
RETURN QUERY
142+
WITH customer_totals AS (
143+
SELECT user_id, sum(total) as total_spent
144+
FROM app_public.orders
145+
WHERE status = 'completed'
146+
GROUP BY user_id
147+
)
148+
SELECT ct.user_id
149+
FROM customer_totals ct
150+
JOIN app_public.users u ON u.id = ct.user_id
151+
WHERE u.is_active = true
152+
ORDER BY ct.total_spent DESC
153+
LIMIT p_limit;
154+
RETURN;
155+
END$$;
156+
157+
-- Test 10: Function with subquery in WHERE clause
158+
CREATE FUNCTION app_public.get_users_with_orders()
159+
RETURNS SETOF int
160+
LANGUAGE plpgsql AS $$
161+
BEGIN
162+
RETURN QUERY
163+
SELECT u.id
164+
FROM app_public.users u
165+
WHERE EXISTS (
166+
SELECT 1 FROM app_public.orders o
167+
WHERE o.user_id = u.id
168+
);
169+
RETURN;
170+
END$$;
171+
172+
-- Test 11: Function referencing multiple schemas
173+
CREATE FUNCTION app_public.cross_schema_report(p_date date)
174+
RETURNS TABLE(source text, count bigint)
175+
LANGUAGE plpgsql AS $$
176+
BEGIN
177+
RETURN QUERY
178+
SELECT 'public_users'::text, count(*)
179+
FROM app_public.users
180+
WHERE created_at::date = p_date
181+
UNION ALL
182+
SELECT 'private_logs'::text, count(*)
183+
FROM app_private.activity_logs
184+
WHERE logged_at::date = p_date
185+
UNION ALL
186+
SELECT 'internal_metrics'::text, count(*)
187+
FROM app_internal.metrics
188+
WHERE recorded_at::date = p_date;
189+
RETURN;
190+
END$$;
191+
192+
-- Test 12: Procedure with schema-qualified references
193+
CREATE PROCEDURE app_public.process_batch(p_batch_id int)
194+
LANGUAGE plpgsql AS $$
195+
DECLARE
196+
item record;
197+
BEGIN
198+
FOR item IN
199+
SELECT * FROM app_public.batch_items
200+
WHERE batch_id = p_batch_id
201+
LOOP
202+
INSERT INTO app_public.processed_items (item_id, processed_at)
203+
VALUES (item.id, now());
204+
205+
UPDATE app_public.batch_items
206+
SET status = 'processed'
207+
WHERE id = item.id;
208+
END LOOP;
209+
210+
UPDATE app_public.batches
211+
SET status = 'completed', completed_at = now()
212+
WHERE id = p_batch_id;
213+
END$$;

0 commit comments

Comments
 (0)