Skip to content

Commit 78284c2

Browse files
committed
test: add snapshot tests for OUT parameters with SELECT INTO multiple variables
Add explicit test cases to deparser-fixes.test.ts for: - SELECT INTO multiple OUT parameters (auth function pattern) - SELECT INTO STRICT with multiple OUT parameters These tests generate snapshots to verify the deparser correctly handles PLpgSQL_row.fields for multiple INTO targets.
1 parent 52f7c7e commit 78284c2

File tree

2 files changed

+87
-0
lines changed

2 files changed

+87
-0
lines changed

packages/plpgsql-deparser/__tests__/__snapshots__/deparser-fixes.test.ts.snap

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,30 @@ BEGIN
7070
END"
7171
`;
7272

73+
exports[`plpgsql-deparser bug fixes OUT parameters with SELECT INTO multiple variables should handle SELECT INTO STRICT with multiple OUT parameters 1`] = `
74+
"BEGIN
75+
SELECT u.name, u.email INTO STRICT name, email FROM users u
76+
WHERE u.id = p_id;
77+
RETURN;
78+
END"
79+
`;
80+
81+
exports[`plpgsql-deparser bug fixes OUT parameters with SELECT INTO multiple variables should handle SELECT INTO multiple OUT parameters 1`] = `
82+
"DECLARE
83+
v_token_id uuid;
84+
v_plaintext_token text;
85+
BEGIN
86+
v_plaintext_token := encode(gen_random_bytes(48), 'hex');
87+
v_token_id := uuid_generate_v5(uuid_ns_url(), v_plaintext_token);
88+
INSERT INTO tokens (id, user_id, access_token_hash)
89+
VALUES (v_token_id, p_user_id, digest(v_plaintext_token, 'sha256'));
90+
SELECT tkn.id, tkn.user_id, v_plaintext_token, tkn.access_token_expires_at, tkn.is_verified, tkn.totp_enabled INTO id, user_id, access_token, access_token_expires_at, is_verified, totp_enabled
91+
FROM tokens AS tkn
92+
WHERE tkn.id = v_token_id;
93+
RETURN;
94+
END"
95+
`;
96+
7397
exports[`plpgsql-deparser bug fixes PERFORM SELECT fix should handle PERFORM with complex expressions 1`] = `
7498
"BEGIN
7599
PERFORM set_config('search_path', 'public', true);

packages/plpgsql-deparser/__tests__/deparser-fixes.test.ts

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,69 @@ $$`;
307307
});
308308
});
309309

310+
describe('OUT parameters with SELECT INTO multiple variables', () => {
311+
it('should handle SELECT INTO multiple OUT parameters', async () => {
312+
const sql = `CREATE FUNCTION test_out_params_select_into(
313+
p_user_id uuid,
314+
OUT id uuid,
315+
OUT user_id uuid,
316+
OUT access_token text,
317+
OUT access_token_expires_at timestamptz,
318+
OUT is_verified boolean,
319+
OUT totp_enabled boolean
320+
)
321+
LANGUAGE plpgsql AS $$
322+
DECLARE
323+
v_token_id uuid;
324+
v_plaintext_token text;
325+
BEGIN
326+
v_plaintext_token := encode(gen_random_bytes(48), 'hex');
327+
v_token_id := uuid_generate_v5(uuid_ns_url(), v_plaintext_token);
328+
329+
INSERT INTO tokens (id, user_id, access_token_hash)
330+
VALUES (v_token_id, p_user_id, digest(v_plaintext_token, 'sha256'));
331+
332+
SELECT tkn.id, tkn.user_id, v_plaintext_token, tkn.access_token_expires_at, tkn.is_verified, tkn.totp_enabled
333+
INTO id, user_id, access_token, access_token_expires_at, is_verified, totp_enabled
334+
FROM tokens AS tkn
335+
WHERE tkn.id = v_token_id;
336+
337+
RETURN;
338+
END$$`;
339+
340+
await testUtils.expectAstMatch('OUT params SELECT INTO', sql);
341+
342+
const parsed = parsePlPgSQLSync(sql) as unknown as PLpgSQLParseResult;
343+
const deparsed = deparseSync(parsed);
344+
expect(deparsed).toMatchSnapshot();
345+
// Verify multiple INTO targets are present
346+
expect(deparsed).toMatch(/INTO\s+id\s*,\s*user_id\s*,\s*access_token/i);
347+
});
348+
349+
it('should handle SELECT INTO STRICT with multiple OUT parameters', async () => {
350+
const sql = `CREATE FUNCTION test_out_params_strict(
351+
p_id uuid,
352+
OUT name text,
353+
OUT email text
354+
)
355+
LANGUAGE plpgsql AS $$
356+
BEGIN
357+
SELECT u.name, u.email INTO STRICT name, email
358+
FROM users u
359+
WHERE u.id = p_id;
360+
END$$`;
361+
362+
await testUtils.expectAstMatch('OUT params STRICT', sql);
363+
364+
const parsed = parsePlPgSQLSync(sql) as unknown as PLpgSQLParseResult;
365+
const deparsed = deparseSync(parsed);
366+
expect(deparsed).toMatchSnapshot();
367+
expect(deparsed).toContain('STRICT');
368+
// Verify multiple INTO targets are present
369+
expect(deparsed).toMatch(/INTO\s+STRICT\s+name\s*,\s*email/i);
370+
});
371+
});
372+
310373
describe('combined scenarios', () => {
311374
it('should handle PERFORM with record fields', async () => {
312375
const sql = `CREATE FUNCTION test_perform_record() RETURNS trigger

0 commit comments

Comments
 (0)