Skip to content

Commit f791150

Browse files
committed
fix(plpgsql-deparser): fix PERFORM, INTO, and recfield bugs
- Fix PERFORM SELECT: Strip leading SELECT keyword since PERFORM replaces it - Fix INTO clause insertion: Use depth-aware scanner to avoid inserting INTO inside subqueries - Fix recfield qualification: Use recparentno to construct full qualified reference (e.g., new.is_active) Add comprehensive snapshot tests for all three fixes.
1 parent 28ce15a commit f791150

File tree

3 files changed

+680
-14
lines changed

3 files changed

+680
-14
lines changed
Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
2+
3+
exports[`plpgsql-deparser bug fixes INTO clause depth-aware scanner should handle INTO STRICT 1`] = `
4+
"DECLARE
5+
v_id integer;
6+
BEGIN
7+
SELECT id INTO STRICT v_id FROM users WHERE email = 'test@example.com';
8+
RETURN v_id;
9+
END"
10+
`;
11+
12+
exports[`plpgsql-deparser bug fixes INTO clause depth-aware scanner should handle INTO with CTE 1`] = `
13+
"DECLARE
14+
v_total integer;
15+
BEGIN
16+
WITH totals AS (
17+
SELECT sum(amount) as total FROM orders
18+
)
19+
SELECT total INTO v_total FROM totals;
20+
RETURN v_total;
21+
END"
22+
`;
23+
24+
exports[`plpgsql-deparser bug fixes INTO clause depth-aware scanner should handle INTO with UNION 1`] = `
25+
"DECLARE
26+
v_count integer;
27+
BEGIN
28+
SELECT count(*) INTO v_count FROM (
29+
SELECT id FROM users
30+
UNION ALL
31+
SELECT id FROM admins
32+
) combined;
33+
RETURN v_count;
34+
END"
35+
`;
36+
37+
exports[`plpgsql-deparser bug fixes INTO clause depth-aware scanner should handle INTO with dollar-quoted strings 1`] = `
38+
"DECLARE
39+
v_result text;
40+
BEGIN
41+
SELECT $tag$some FROM text$tag$ INTO v_result FROM dual;
42+
RETURN v_result;
43+
END"
44+
`;
45+
46+
exports[`plpgsql-deparser bug fixes INTO clause depth-aware scanner should handle INTO with quoted identifiers 1`] = `
47+
"DECLARE
48+
v_name text;
49+
BEGIN
50+
SELECT "user-name" INTO v_name FROM "my-schema"."user-table" WHERE id = 1;
51+
RETURN v_name;
52+
END"
53+
`;
54+
55+
exports[`plpgsql-deparser bug fixes INTO clause depth-aware scanner should insert INTO at correct position for simple SELECT 1`] = `
56+
"DECLARE
57+
v_count integer;
58+
BEGIN
59+
SELECT count(*) INTO v_count FROM users;
60+
RETURN v_count;
61+
END"
62+
`;
63+
64+
exports[`plpgsql-deparser bug fixes INTO clause depth-aware scanner should not insert INTO inside subqueries 1`] = `
65+
"DECLARE
66+
v_result integer;
67+
BEGIN
68+
SELECT (SELECT max(id) FROM orders) INTO v_result FROM users WHERE id = 1;
69+
RETURN v_result;
70+
END"
71+
`;
72+
73+
exports[`plpgsql-deparser bug fixes PERFORM SELECT fix should handle PERFORM with complex expressions 1`] = `
74+
"BEGIN
75+
PERFORM set_config('search_path', 'public', true);
76+
PERFORM nextval('my_sequence');
77+
RETURN;
78+
END"
79+
`;
80+
81+
exports[`plpgsql-deparser bug fixes PERFORM SELECT fix should handle PERFORM with subquery 1`] = `
82+
"BEGIN
83+
PERFORM 1 FROM users WHERE id = 1;
84+
RETURN;
85+
END"
86+
`;
87+
88+
exports[`plpgsql-deparser bug fixes PERFORM SELECT fix should strip SELECT keyword from PERFORM statements 1`] = `
89+
"BEGIN
90+
PERFORM pg_sleep(1);
91+
RETURN;
92+
END"
93+
`;
94+
95+
exports[`plpgsql-deparser bug fixes Record field qualification (recfield) should handle OLD and NEW record references 1`] = `
96+
"BEGIN
97+
IF OLD.status <> NEW.status THEN
98+
INSERT INTO audit_log (old_status, new_status) VALUES (OLD.status, NEW.status);
99+
END IF;
100+
RETURN NEW;
101+
END"
102+
`;
103+
104+
exports[`plpgsql-deparser bug fixes Record field qualification (recfield) should handle SELECT INTO with record fields 1`] = `
105+
"BEGIN
106+
SELECT is_active INTO new.is_active FROM users WHERE id = NEW.user_id;
107+
RETURN NEW;
108+
END"
109+
`;
110+
111+
exports[`plpgsql-deparser bug fixes Record field qualification (recfield) should handle custom record types 1`] = `
112+
"DECLARE
113+
r RECORD;
114+
BEGIN
115+
FOR r IN SELECT id, name FROM users LOOP
116+
RAISE NOTICE 'User: % - %', r.id, r.name;
117+
END LOOP;
118+
RETURN;
119+
END"
120+
`;
121+
122+
exports[`plpgsql-deparser bug fixes Record field qualification (recfield) should handle record field assignment 1`] = `
123+
"BEGIN
124+
NEW.created_at := COALESCE(NEW.created_at, now());
125+
NEW.updated_at := now();
126+
NEW.version := COALESCE(OLD.version, 0) + 1;
127+
RETURN NEW;
128+
END"
129+
`;
130+
131+
exports[`plpgsql-deparser bug fixes Record field qualification (recfield) should qualify record fields with parent record name in triggers 1`] = `
132+
"BEGIN
133+
IF NEW.is_active THEN
134+
NEW.updated_at := now();
135+
END IF;
136+
RETURN NEW;
137+
END"
138+
`;
139+
140+
exports[`plpgsql-deparser bug fixes combined scenarios should handle PERFORM with record fields 1`] = `
141+
"BEGIN
142+
PERFORM notify_change(NEW.id, NEW.status);
143+
RETURN NEW;
144+
END"
145+
`;
146+
147+
exports[`plpgsql-deparser bug fixes combined scenarios should handle SELECT INTO with subquery and record fields 1`] = `
148+
"DECLARE
149+
v_count integer;
150+
BEGIN
151+
SELECT count(*) INTO v_count FROM orders WHERE user_id = NEW.user_id;
152+
IF v_count > 100 THEN
153+
NEW.is_premium := true;
154+
END IF;
155+
RETURN NEW;
156+
END"
157+
`;

0 commit comments

Comments
 (0)