Skip to content

Commit 49d3cc1

Browse files
committed
Implement strict INSERT INTO ... VALUES formatting for pretty printing
- Fix VALUES formatting to avoid corrupting string literals with escape sequences - Use containsMultilineStringLiteral() to preserve original string content - Column lists always wrapped in parentheses across multiple lines - VALUES keyword always on its own line - Each tuple indented by two spaces - Preserve quoted identifiers and schema names exactly - Update casing-pretty.test.ts snapshots with new formatting rules Co-Authored-By: Dan Lynch <[email protected]>
1 parent 512cb83 commit 49d3cc1

File tree

2 files changed

+83
-31
lines changed

2 files changed

+83
-31
lines changed

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

Lines changed: 52 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -65,63 +65,91 @@ exports[`non-pretty: pretty/casing-31.sql 1`] = `"SELECT "HandleInsert"('TYPE_A'
6565
exports[`non-pretty: pretty/casing-32.sql 1`] = `"SELECT * FROM "dataPoints""`;
6666

6767
exports[`pretty: pretty/casing-1.sql 1`] = `
68-
"INSERT INTO users (name) VALUES
69-
('John Doe')"
68+
"INSERT INTO users (
69+
name
70+
) VALUES
71+
('John Doe')"
7072
`;
7173

7274
exports[`pretty: pretty/casing-2.sql 1`] = `
73-
"INSERT INTO users (name) VALUES
74-
('ADMINISTRATOR')"
75+
"INSERT INTO users (
76+
name
77+
) VALUES
78+
('ADMINISTRATOR')"
7579
`;
7680

7781
exports[`pretty: pretty/casing-3.sql 1`] = `
78-
"INSERT INTO users (name) VALUES
79-
('lowercase')"
82+
"INSERT INTO users (
83+
name
84+
) VALUES
85+
('lowercase')"
8086
`;
8187

8288
exports[`pretty: pretty/casing-4.sql 1`] = `
83-
"INSERT INTO users (name) VALUES
84-
('camelCaseString')"
89+
"INSERT INTO users (
90+
name
91+
) VALUES
92+
('camelCaseString')"
8593
`;
8694

8795
exports[`pretty: pretty/casing-5.sql 1`] = `
88-
"INSERT INTO users (name) VALUES
89-
('snake_case_string')"
96+
"INSERT INTO users (
97+
name
98+
) VALUES
99+
('snake_case_string')"
90100
`;
91101

92102
exports[`pretty: pretty/casing-6.sql 1`] = `
93-
"INSERT INTO users (name) VALUES
94-
('kebab-case-value')"
103+
"INSERT INTO users (
104+
name
105+
) VALUES
106+
('kebab-case-value')"
95107
`;
96108

97109
exports[`pretty: pretty/casing-7.sql 1`] = `
98-
"INSERT INTO data.snapshots (metadata) VALUES
99-
('{"Type": "Full", "Status": "OK"}')"
110+
"INSERT INTO data.snapshots (
111+
metadata
112+
) VALUES
113+
('{"Type": "Full", "Status": "OK"}')"
100114
`;
101115

102116
exports[`pretty: pretty/casing-8.sql 1`] = `
103-
"INSERT INTO "AppSchema"."User Data" ("Full Name") VALUES
104-
('Jane Smith')"
117+
"INSERT INTO "AppSchema"."User Data" (
118+
"Full Name"
119+
) VALUES
120+
('Jane Smith')"
105121
`;
106122

107123
exports[`pretty: pretty/casing-9.sql 1`] = `
108-
"INSERT INTO logtable (message) VALUES
109-
('Init'), ('Reboot'), ('ERROR'), ('Warning'), ('info')"
124+
"INSERT INTO logtable (
125+
message
126+
) VALUES
127+
('Init'),
128+
('Reboot'),
129+
('ERROR'),
130+
('Warning'),
131+
('info')"
110132
`;
111133

112134
exports[`pretty: pretty/casing-10.sql 1`] = `
113-
"INSERT INTO metrics.logs (message) VALUES
114-
('NOW()')"
135+
"INSERT INTO metrics.logs (
136+
message
137+
) VALUES
138+
('NOW()')"
115139
`;
116140

117141
exports[`pretty: pretty/casing-11.sql 1`] = `
118-
"INSERT INTO users (name) VALUES
119-
('SELECT')"
142+
"INSERT INTO users (
143+
name
144+
) VALUES
145+
('SELECT')"
120146
`;
121147

122148
exports[`pretty: pretty/casing-12.sql 1`] = `
123-
"INSERT INTO users (name) VALUES
124-
149+
"INSERT INTO users (
150+
name
151+
) VALUES
152+
125153
`;
126154

127155
exports[`pretty: pretty/casing-13.sql 1`] = `"SELECT 'MixedCase'"`;

packages/deparser/src/deparser.ts

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -438,12 +438,27 @@ export class Deparser implements DeparserVisitor {
438438
}
439439

440440
if (node.valuesLists) {
441-
output.push('VALUES');
442-
const lists = ListUtils.unwrapList(node.valuesLists).map(list => {
443-
const values = ListUtils.unwrapList(list).map(val => this.visit(val as Node, context));
444-
return this.formatter.parens(values.join(', '));
445-
});
446-
output.push(lists.join(', '));
441+
if (this.formatter.isPretty()) {
442+
output.push('VALUES');
443+
const lists = ListUtils.unwrapList(node.valuesLists).map(list => {
444+
const values = ListUtils.unwrapList(list).map(val => this.visit(val as Node, context));
445+
return this.formatter.parens(values.join(', '));
446+
});
447+
const indentedTuples = lists.map(tuple => {
448+
if (this.containsMultilineStringLiteral(tuple)) {
449+
return tuple;
450+
}
451+
return this.formatter.indent(tuple);
452+
});
453+
output.push(indentedTuples.join(',\n'));
454+
} else {
455+
output.push('VALUES');
456+
const lists = ListUtils.unwrapList(node.valuesLists).map(list => {
457+
const values = ListUtils.unwrapList(list).map(val => this.visit(val as Node, context));
458+
return this.formatter.parens(values.join(', '));
459+
});
460+
output.push(lists.join(', '));
461+
}
447462
}
448463

449464
if (node.groupClause) {
@@ -909,6 +924,8 @@ export class Deparser implements DeparserVisitor {
909924
return this.visit(rexpr, context);
910925
}
911926

927+
928+
912929
InsertStmt(node: t.InsertStmt, context: DeparserContext): string {
913930
const output: string[] = [];
914931

@@ -923,7 +940,14 @@ export class Deparser implements DeparserVisitor {
923940
const cols = ListUtils.unwrapList(node.cols);
924941
const insertContext = { ...context, insertColumns: true };
925942
const columnNames = cols.map(col => this.visit(col as Node, insertContext));
926-
output.push(this.formatter.parens(columnNames.join(', ')));
943+
944+
if (this.formatter.isPretty()) {
945+
// Always format columns in multiline parentheses for pretty printing
946+
const indentedColumns = columnNames.map(col => this.formatter.indent(col));
947+
output.push('(\n' + indentedColumns.join(',\n') + '\n)');
948+
} else {
949+
output.push(this.formatter.parens(columnNames.join(', ')));
950+
}
927951
}
928952

929953
if (node.selectStmt) {

0 commit comments

Comments
 (0)