Skip to content

Commit 9dda8d1

Browse files
committed
feat(deparser): add pretty printing for CREATE FUNCTION params and RETURNS TABLE
- Add context.isPretty() check in CreateFunctionStmt handler - Format function parameters on separate lines in pretty mode - Format RETURNS TABLE columns on separate lines in pretty mode - Update plpgsql-deparser to use workspace pgsql-deparser dependency - Update snapshots to reflect new pretty printing format
1 parent 769a30d commit 9dda8d1

6 files changed

Lines changed: 2729 additions & 5581 deletions

File tree

packages/deparser/__tests__/pretty/__snapshots__/formatting-pretty.test.ts.snap

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,23 @@ exports[`pretty: pretty/formatting-6.sql 1`] = `
7878
('name', 'val', CAST('f' AS boolean), 'abcdefg')"
7979
`;
8080

81-
exports[`pretty: pretty/formatting-7.sql 1`] = `"CREATE FUNCTION test_func(IN p1 pos_int) RETURNS void AS $$ BEGIN NULL; END; $$ LANGUAGE plpgsql"`;
81+
exports[`pretty: pretty/formatting-7.sql 1`] = `
82+
"CREATE FUNCTION test_func(
83+
IN p1 pos_int
84+
) RETURNS void AS $$ BEGIN NULL; END; $$ LANGUAGE plpgsql"
85+
`;
8286

83-
exports[`pretty: pretty/formatting-8.sql 1`] = `"CREATE FUNCTION test_func2(IN p1 pos_int, IN p2 text) RETURNS void AS $$ BEGIN NULL; END; $$ LANGUAGE plpgsql"`;
87+
exports[`pretty: pretty/formatting-8.sql 1`] = `
88+
"CREATE FUNCTION test_func2(
89+
IN p1 pos_int,
90+
IN p2 text
91+
) RETURNS void AS $$ BEGIN NULL; END; $$ LANGUAGE plpgsql"
92+
`;
8493

85-
exports[`pretty: pretty/formatting-9.sql 1`] = `"CREATE FUNCTION test_func3(IN p1 int, OUT p2 text, INOUT p3 boolean) RETURNS record AS $$ BEGIN p2 := 'test'; END; $$ LANGUAGE plpgsql"`;
94+
exports[`pretty: pretty/formatting-9.sql 1`] = `
95+
"CREATE FUNCTION test_func3(
96+
IN p1 int,
97+
OUT p2 text,
98+
INOUT p3 boolean
99+
) RETURNS record AS $$ BEGIN p2 := 'test'; END; $$ LANGUAGE plpgsql"
100+
`;

packages/deparser/__tests__/pretty/__snapshots__/quoting-pretty.test.ts.snap

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,31 +69,43 @@ exports[`non-pretty: pretty/quoting-15.sql 1`] = `"SELECT CAST(100 AS custom.int
6969
exports[`non-pretty: pretty/quoting-16.sql 1`] = `"SELECT CAST(true AS myapp.boolean)"`;
7070

7171
exports[`pretty: pretty/quoting-1.sql 1`] = `
72-
"CREATE FUNCTION faker.float(min double precision DEFAULT 0, max double precision DEFAULT 100) RETURNS double precision AS $$
72+
"CREATE FUNCTION faker.float(
73+
min double precision DEFAULT 0,
74+
max double precision DEFAULT 100
75+
) RETURNS double precision AS $$
7376
BEGIN
7477
RETURN min + random() * (max - min);
7578
END;
7679
$$ LANGUAGE plpgsql"
7780
`;
7881

7982
exports[`pretty: pretty/quoting-2.sql 1`] = `
80-
"CREATE FUNCTION faker.float(min double precision DEFAULT 0, max double precision DEFAULT 100) RETURNS double precision AS $$
83+
"CREATE FUNCTION faker.float(
84+
min double precision DEFAULT 0,
85+
max double precision DEFAULT 100
86+
) RETURNS double precision AS $$
8187
BEGIN
8288
RETURN min + random() * (max - min);
8389
END;
8490
$$ LANGUAGE plpgsql"
8591
`;
8692

8793
exports[`pretty: pretty/quoting-3.sql 1`] = `
88-
"CREATE FUNCTION faker.interval(min int, max int) RETURNS interval AS $$
94+
"CREATE FUNCTION faker.interval(
95+
min int,
96+
max int
97+
) RETURNS interval AS $$
8998
BEGIN
9099
RETURN make_interval(secs => (min + floor(random() * (max - min + 1)))::int);
91100
END;
92101
$$ LANGUAGE plpgsql"
93102
`;
94103

95104
exports[`pretty: pretty/quoting-4.sql 1`] = `
96-
"CREATE FUNCTION faker.interval(min int, max int) RETURNS interval AS $$
105+
"CREATE FUNCTION faker.interval(
106+
min int,
107+
max int
108+
) RETURNS interval AS $$
97109
BEGIN
98110
RETURN make_interval(secs => (min + floor(random() * (max - min + 1)))::int);
99111
END;

packages/deparser/src/deparser.ts

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5504,7 +5504,12 @@ export class Deparser implements DeparserVisitor {
55045504
.map((param: any) => this.visit(param, context));
55055505

55065506
if (params.length > 0) {
5507-
output.push(funcName + '(' + params.join(', ') + ')');
5507+
if (context.isPretty()) {
5508+
const formattedParams = params.map(p => context.indent(p)).join(',' + context.newline());
5509+
output.push(funcName + '(' + context.newline() + formattedParams + context.newline() + ')');
5510+
} else {
5511+
output.push(funcName + '(' + params.join(', ') + ')');
5512+
}
55085513
} else {
55095514
output.push(funcName + '()');
55105515
}
@@ -5519,15 +5524,20 @@ export class Deparser implements DeparserVisitor {
55195524
});
55205525

55215526
if (hasTableParams) {
5522-
output.push('RETURNS TABLE (');
55235527
const tableParams = node.parameters
55245528
.filter((param: any) => {
55255529
const paramData = this.getNodeData(param);
55265530
return paramData.mode === 'FUNC_PARAM_TABLE';
55275531
})
55285532
.map((param: any) => this.visit(param, context));
5529-
output.push(tableParams.join(', '));
5530-
output.push(')');
5533+
if (context.isPretty()) {
5534+
const formattedTableParams = tableParams.map(p => context.indent(p)).join(',' + context.newline());
5535+
output.push('RETURNS TABLE (' + context.newline() + formattedTableParams + context.newline() + ')');
5536+
} else {
5537+
output.push('RETURNS TABLE (');
5538+
output.push(tableParams.join(', '));
5539+
output.push(')');
5540+
}
55315541
} else if (node.returnType) {
55325542
output.push('RETURNS');
55335543
output.push(this.TypeName(node.returnType as any, context));

packages/plpgsql-deparser/__tests__/__snapshots__/hydrate-demo.test.ts.snap

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,37 @@
11
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
22

33
exports[`hydrate demonstration with big-function.sql should parse, hydrate, modify, and deparse big-function.sql with full CREATE FUNCTION 1`] = `
4-
"CREATE OR REPLACE FUNCTION app_public.order_rollup_calculator(p_org_id uuid, p_user_id uuid, p_from_ts timestamptz DEFAULT now() - '30 days'::interval, p_to_ts timestamptz DEFAULT now(), p_min_total numeric DEFAULT 0, p_max_rows int DEFAULT 250, p_currency text DEFAULT 'USD', p_apply_discount boolean DEFAULT true, p_discount_rate numeric DEFAULT 0.05, p_tax_rate numeric DEFAULT 0.0875, p_round_to int DEFAULT 2, p_note text DEFAULT NULL, p_lock boolean DEFAULT false, p_debug boolean DEFAULT false) RETURNS TABLE ( org_id uuid, user_id uuid, period_from timestamptz, period_to timestamptz, orders_scanned int, orders_upserted int, gross_total numeric, discount_total numeric, tax_total numeric, net_total numeric, avg_order_total numeric, top_sku text, top_sku_qty bigint, message text ) LANGUAGE plpgsql AS $$DECLARE
4+
"CREATE OR REPLACE FUNCTION app_public.order_rollup_calculator(
5+
p_org_id uuid,
6+
p_user_id uuid,
7+
p_from_ts timestamptz DEFAULT now() - '30 days'::interval,
8+
p_to_ts timestamptz DEFAULT now(),
9+
p_min_total numeric DEFAULT 0,
10+
p_max_rows int DEFAULT 250,
11+
p_currency text DEFAULT 'USD',
12+
p_apply_discount boolean DEFAULT true,
13+
p_discount_rate numeric DEFAULT 0.05,
14+
p_tax_rate numeric DEFAULT 0.0875,
15+
p_round_to int DEFAULT 2,
16+
p_note text DEFAULT NULL,
17+
p_lock boolean DEFAULT false,
18+
p_debug boolean DEFAULT false
19+
) RETURNS TABLE (
20+
org_id uuid,
21+
user_id uuid,
22+
period_from timestamptz,
23+
period_to timestamptz,
24+
orders_scanned int,
25+
orders_upserted int,
26+
gross_total numeric,
27+
discount_total numeric,
28+
tax_total numeric,
29+
net_total numeric,
30+
avg_order_total numeric,
31+
top_sku text,
32+
top_sku_qty bigint,
33+
message text
34+
) LANGUAGE plpgsql AS $$DECLARE
535
v_orders_scanned int := 42;
636
v_orders_upserted int := 42;
737
v_gross numeric := 42;

packages/plpgsql-deparser/package.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,8 @@
4646
"libpg-query": "17.7.3",
4747
"makage": "^0.1.8"
4848
},
49-
"dependencies": {
50-
"@pgsql/types": "^17.6.2",
51-
"pgsql-deparser": "^17.15.2"
52-
}
49+
"dependencies": {
50+
"@pgsql/types": "^17.6.2",
51+
"pgsql-deparser": "workspace:*"
52+
}
5353
}

0 commit comments

Comments
 (0)