rawsql-ts 0.24.1 → 0.24.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esm/index.min.js +7 -7
- package/dist/esm/index.min.js.map +2 -2
- package/dist/esm/parsers/CommandExpressionParser.d.ts +2 -0
- package/dist/esm/parsers/CommandExpressionParser.js +49 -4
- package/dist/esm/parsers/CommandExpressionParser.js.map +1 -1
- package/dist/esm/parsers/HavingParser.js +6 -0
- package/dist/esm/parsers/HavingParser.js.map +1 -1
- package/dist/esm/parsers/JoinOnClauseParser.js +6 -0
- package/dist/esm/parsers/JoinOnClauseParser.js.map +1 -1
- package/dist/esm/parsers/LimitClauseParser.js +6 -0
- package/dist/esm/parsers/LimitClauseParser.js.map +1 -1
- package/dist/esm/parsers/OffsetClauseParser.js +6 -0
- package/dist/esm/parsers/OffsetClauseParser.js.map +1 -1
- package/dist/esm/parsers/OrderByClauseParser.d.ts +2 -0
- package/dist/esm/parsers/OrderByClauseParser.js +42 -29
- package/dist/esm/parsers/OrderByClauseParser.js.map +1 -1
- package/dist/esm/parsers/SqlPrintTokenParser.d.ts +3 -0
- package/dist/esm/parsers/SqlPrintTokenParser.js +70 -6
- package/dist/esm/parsers/SqlPrintTokenParser.js.map +1 -1
- package/dist/esm/parsers/ValueParser.js +5 -3
- package/dist/esm/parsers/ValueParser.js.map +1 -1
- package/dist/esm/transformers/SqlFormatter.d.ts +7 -1
- package/dist/esm/transformers/SqlFormatter.js.map +1 -1
- package/dist/esm/transformers/SqlPrinter.d.ts +32 -2
- package/dist/esm/transformers/SqlPrinter.js +255 -33
- package/dist/esm/transformers/SqlPrinter.js.map +1 -1
- package/dist/index.min.js +7 -7
- package/dist/index.min.js.map +2 -2
- package/dist/parsers/CommandExpressionParser.js +49 -4
- package/dist/parsers/CommandExpressionParser.js.map +1 -1
- package/dist/parsers/HavingParser.js +6 -0
- package/dist/parsers/HavingParser.js.map +1 -1
- package/dist/parsers/JoinOnClauseParser.js +6 -0
- package/dist/parsers/JoinOnClauseParser.js.map +1 -1
- package/dist/parsers/LimitClauseParser.js +6 -0
- package/dist/parsers/LimitClauseParser.js.map +1 -1
- package/dist/parsers/OffsetClauseParser.js +6 -0
- package/dist/parsers/OffsetClauseParser.js.map +1 -1
- package/dist/parsers/OrderByClauseParser.js +42 -29
- package/dist/parsers/OrderByClauseParser.js.map +1 -1
- package/dist/parsers/SqlPrintTokenParser.js +71 -6
- package/dist/parsers/SqlPrintTokenParser.js.map +1 -1
- package/dist/parsers/ValueParser.js +5 -3
- package/dist/parsers/ValueParser.js.map +1 -1
- package/dist/src/parsers/CommandExpressionParser.d.ts +2 -0
- package/dist/src/parsers/OrderByClauseParser.d.ts +2 -0
- package/dist/src/parsers/SqlPrintTokenParser.d.ts +3 -0
- package/dist/src/transformers/SqlFormatter.d.ts +7 -1
- package/dist/src/transformers/SqlPrinter.d.ts +32 -2
- package/dist/transformers/SqlFormatter.js.map +1 -1
- package/dist/transformers/SqlPrinter.js +255 -33
- package/dist/transformers/SqlPrinter.js.map +1 -1
- package/dist/tsconfig.browser.tsbuildinfo +1 -1
- package/package.json +1 -1
|
@@ -33,15 +33,21 @@ class SqlPrinter {
|
|
|
33
33
|
* @param options Optional style settings for pretty printing
|
|
34
34
|
*/
|
|
35
35
|
constructor(options) {
|
|
36
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u;
|
|
36
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w;
|
|
37
37
|
/** Track whether we are currently inside a WITH clause for full-oneline formatting */
|
|
38
38
|
this.insideWithClause = false;
|
|
39
39
|
/** Tracks nesting depth while formatting MERGE WHEN predicate segments */
|
|
40
40
|
this.mergeWhenPredicateDepth = 0;
|
|
41
|
+
/** Tracks nesting depth while formatting JOIN ON condition segments */
|
|
42
|
+
this.joinOnClauseDepth = 0;
|
|
43
|
+
/** Containers whose one-line rendering was rejected by oneLineMaxLength */
|
|
44
|
+
this.expandedOneLineFallbackTokens = new WeakSet();
|
|
41
45
|
/** Pending line comment that needs a forced newline before next token */
|
|
42
46
|
this.pendingLineCommentBreak = null;
|
|
43
47
|
/** Accumulates lines when reconstructing multi-line block comments inside CommentBlocks */
|
|
44
48
|
this.smartCommentBlockBuilder = null;
|
|
49
|
+
/** Tracks function calls whose arguments must expand because rendered comments are present */
|
|
50
|
+
this.commentedFunctionCallDepth = 0;
|
|
45
51
|
// Resolve logical options to their control character representations before applying defaults.
|
|
46
52
|
const resolvedIndentChar = (0, FormatOptionResolver_1.resolveIndentCharOption)(options === null || options === void 0 ? void 0 : options.indentChar);
|
|
47
53
|
const resolvedNewline = (0, FormatOptionResolver_1.resolveNewlineOption)(options === null || options === void 0 ? void 0 : options.newline);
|
|
@@ -55,19 +61,22 @@ class SqlPrinter {
|
|
|
55
61
|
this.valuesCommaBreak = (_d = options === null || options === void 0 ? void 0 : options.valuesCommaBreak) !== null && _d !== void 0 ? _d : this.commaBreak;
|
|
56
62
|
this.andBreak = (_e = options === null || options === void 0 ? void 0 : options.andBreak) !== null && _e !== void 0 ? _e : 'none';
|
|
57
63
|
this.orBreak = (_f = options === null || options === void 0 ? void 0 : options.orBreak) !== null && _f !== void 0 ? _f : 'none';
|
|
58
|
-
this.
|
|
64
|
+
this.joinOnBreak = (_g = options === null || options === void 0 ? void 0 : options.joinOnBreak) !== null && _g !== void 0 ? _g : 'none';
|
|
65
|
+
this.keywordCase = (_h = options === null || options === void 0 ? void 0 : options.keywordCase) !== null && _h !== void 0 ? _h : 'none';
|
|
59
66
|
this.commentExportMode = this.resolveCommentExportMode(options === null || options === void 0 ? void 0 : options.exportComment);
|
|
60
|
-
this.withClauseStyle = (
|
|
61
|
-
this.commentStyle = (
|
|
62
|
-
this.parenthesesOneLine = (
|
|
63
|
-
this.betweenOneLine = (
|
|
64
|
-
this.valuesOneLine = (
|
|
65
|
-
this.joinOneLine = (
|
|
66
|
-
this.caseOneLine = (
|
|
67
|
-
this.subqueryOneLine = (
|
|
68
|
-
this.indentNestedParentheses = (
|
|
69
|
-
this.insertColumnsOneLine = (
|
|
70
|
-
this.whenOneLine = (
|
|
67
|
+
this.withClauseStyle = (_j = options === null || options === void 0 ? void 0 : options.withClauseStyle) !== null && _j !== void 0 ? _j : 'standard';
|
|
68
|
+
this.commentStyle = (_k = options === null || options === void 0 ? void 0 : options.commentStyle) !== null && _k !== void 0 ? _k : 'block';
|
|
69
|
+
this.parenthesesOneLine = (_l = options === null || options === void 0 ? void 0 : options.parenthesesOneLine) !== null && _l !== void 0 ? _l : false;
|
|
70
|
+
this.betweenOneLine = (_m = options === null || options === void 0 ? void 0 : options.betweenOneLine) !== null && _m !== void 0 ? _m : false;
|
|
71
|
+
this.valuesOneLine = (_o = options === null || options === void 0 ? void 0 : options.valuesOneLine) !== null && _o !== void 0 ? _o : false;
|
|
72
|
+
this.joinOneLine = (_p = options === null || options === void 0 ? void 0 : options.joinOneLine) !== null && _p !== void 0 ? _p : false;
|
|
73
|
+
this.caseOneLine = (_q = options === null || options === void 0 ? void 0 : options.caseOneLine) !== null && _q !== void 0 ? _q : false;
|
|
74
|
+
this.subqueryOneLine = (_r = options === null || options === void 0 ? void 0 : options.subqueryOneLine) !== null && _r !== void 0 ? _r : false;
|
|
75
|
+
this.indentNestedParentheses = (_s = options === null || options === void 0 ? void 0 : options.indentNestedParentheses) !== null && _s !== void 0 ? _s : false;
|
|
76
|
+
this.insertColumnsOneLine = (_t = options === null || options === void 0 ? void 0 : options.insertColumnsOneLine) !== null && _t !== void 0 ? _t : false;
|
|
77
|
+
this.whenOneLine = (_u = options === null || options === void 0 ? void 0 : options.whenOneLine) !== null && _u !== void 0 ? _u : false;
|
|
78
|
+
this.oneLineMaxLength = this.normalizeOneLineMaxLength(options === null || options === void 0 ? void 0 : options.oneLineMaxLength);
|
|
79
|
+
this.joinConditionContinuationIndent = (_v = options === null || options === void 0 ? void 0 : options.joinConditionContinuationIndent) !== null && _v !== void 0 ? _v : false;
|
|
71
80
|
const onelineOptions = {
|
|
72
81
|
parenthesesOneLine: this.parenthesesOneLine,
|
|
73
82
|
betweenOneLine: this.betweenOneLine,
|
|
@@ -81,7 +90,7 @@ class SqlPrinter {
|
|
|
81
90
|
this.onelineHelper = new OnelineFormattingHelper_1.OnelineFormattingHelper(onelineOptions);
|
|
82
91
|
this.linePrinter = new LinePrinter_1.LinePrinter(this.indentChar, this.indentSize, this.newline, this.commaBreak);
|
|
83
92
|
// Initialize
|
|
84
|
-
this.indentIncrementContainers = new Set((
|
|
93
|
+
this.indentIncrementContainers = new Set((_w = options === null || options === void 0 ? void 0 : options.indentIncrementContainerTypes) !== null && _w !== void 0 ? _w : [
|
|
85
94
|
SqlPrintToken_1.SqlPrintTokenContainerType.SelectClause,
|
|
86
95
|
SqlPrintToken_1.SqlPrintTokenContainerType.ReturningClause,
|
|
87
96
|
SqlPrintToken_1.SqlPrintTokenContainerType.FromClause,
|
|
@@ -127,8 +136,11 @@ class SqlPrinter {
|
|
|
127
136
|
// initialize
|
|
128
137
|
this.linePrinter = new LinePrinter_1.LinePrinter(this.indentChar, this.indentSize, this.newline, this.commaBreak);
|
|
129
138
|
this.insideWithClause = false; // Reset WITH clause context
|
|
139
|
+
this.joinOnClauseDepth = 0;
|
|
130
140
|
this.pendingLineCommentBreak = null;
|
|
131
141
|
this.smartCommentBlockBuilder = null;
|
|
142
|
+
this.expandedOneLineFallbackTokens = new WeakSet();
|
|
143
|
+
this.commentedFunctionCallDepth = 0;
|
|
132
144
|
if (this.linePrinter.lines.length > 0 && level !== this.linePrinter.lines[0].level) {
|
|
133
145
|
this.linePrinter.lines[0].level = level;
|
|
134
146
|
}
|
|
@@ -171,6 +183,7 @@ class SqlPrinter {
|
|
|
171
183
|
}
|
|
172
184
|
}
|
|
173
185
|
appendToken(token, level, parentContainerType, caseContextDepth = 0, indentParentActive = false, commentContext, previousSiblingWasOpenParen = false) {
|
|
186
|
+
var _a;
|
|
174
187
|
// Track WITH clause context for full-oneline formatting
|
|
175
188
|
const wasInsideWithClause = this.insideWithClause;
|
|
176
189
|
if (token.containerType === SqlPrintToken_1.SqlPrintTokenContainerType.WithClause && this.withClauseStyle === 'full-oneline') {
|
|
@@ -199,12 +212,16 @@ class SqlPrinter {
|
|
|
199
212
|
}
|
|
200
213
|
}
|
|
201
214
|
const hasRenderableLeadingComment = leadingCommentContexts.some(item => item.shouldRender);
|
|
215
|
+
const leadingCommentFollowsLogicalOperator = hasRenderableLeadingComment && this.currentLineEndsWithLogicalOperator();
|
|
202
216
|
const leadingCommentIndentLevel = hasRenderableLeadingComment
|
|
203
|
-
? this.getLeadingCommentIndentLevel(
|
|
217
|
+
? this.getLeadingCommentIndentLevel(token.containerType === SqlPrintToken_1.SqlPrintTokenContainerType.SelectItem
|
|
218
|
+
? token.containerType
|
|
219
|
+
: parentContainerType, level)
|
|
204
220
|
: null;
|
|
205
221
|
if (hasRenderableLeadingComment
|
|
206
222
|
&& !this.isOnelineMode()
|
|
207
|
-
&& this.shouldAddNewlineBeforeLeadingComments(parentContainerType)
|
|
223
|
+
&& this.shouldAddNewlineBeforeLeadingComments(parentContainerType)
|
|
224
|
+
&& !this.shouldKeepLeadingCommentOnCommaLine()) {
|
|
208
225
|
const currentLine = this.linePrinter.getCurrentLine();
|
|
209
226
|
if (currentLine.text.trim().length > 0) {
|
|
210
227
|
// Align the newline before leading comments with the intended comment indentation.
|
|
@@ -217,13 +234,26 @@ class SqlPrinter {
|
|
|
217
234
|
}
|
|
218
235
|
// Keep leading comment processing aligned with its computed indentation level.
|
|
219
236
|
this.appendToken(leading.token, leadingCommentIndentLevel !== null && leadingCommentIndentLevel !== void 0 ? leadingCommentIndentLevel : level, token.containerType, caseContextDepth, indentParentActive, leading.context, false);
|
|
237
|
+
if (token.containerType === SqlPrintToken_1.SqlPrintTokenContainerType.SelectItem &&
|
|
238
|
+
((_a = this.smartCommentBlockBuilder) === null || _a === void 0 ? void 0 : _a.mode) === 'line') {
|
|
239
|
+
this.flushSmartCommentBlockBuilder();
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
if (leadingCommentFollowsLogicalOperator &&
|
|
243
|
+
this.pendingLineCommentBreak === null &&
|
|
244
|
+
!this.isOnelineMode() &&
|
|
245
|
+
this.linePrinter.getCurrentLine().text.trim().endsWith('*/')) {
|
|
246
|
+
this.linePrinter.appendNewline(level + 1);
|
|
220
247
|
}
|
|
221
248
|
if (this.smartCommentBlockBuilder && token.containerType !== SqlPrintToken_1.SqlPrintTokenContainerType.CommentBlock && token.type !== SqlPrintToken_1.SqlPrintTokenType.commentNewline) {
|
|
222
249
|
this.flushSmartCommentBlockBuilder();
|
|
223
250
|
}
|
|
224
251
|
if (this.pendingLineCommentBreak !== null) {
|
|
225
252
|
if (!this.isOnelineMode()) {
|
|
226
|
-
|
|
253
|
+
const pendingBreakLevel = leadingCommentFollowsLogicalOperator
|
|
254
|
+
? this.pendingLineCommentBreak + 1
|
|
255
|
+
: this.pendingLineCommentBreak;
|
|
256
|
+
this.linePrinter.appendNewline(pendingBreakLevel);
|
|
227
257
|
}
|
|
228
258
|
const shouldSkipToken = token.type === SqlPrintToken_1.SqlPrintTokenType.commentNewline;
|
|
229
259
|
this.pendingLineCommentBreak = null;
|
|
@@ -240,14 +270,22 @@ class SqlPrinter {
|
|
|
240
270
|
if (!this.shouldRenderComment(token, effectiveCommentContext)) {
|
|
241
271
|
return;
|
|
242
272
|
}
|
|
273
|
+
if (this.shouldKeepLeadingCommentOnCommaLine()) {
|
|
274
|
+
this.ensureTrailingSpace();
|
|
275
|
+
}
|
|
243
276
|
const commentLevel = this.getCommentBaseIndentLevel(level, parentContainerType);
|
|
277
|
+
if (parentContainerType === SqlPrintToken_1.SqlPrintTokenContainerType.SelectItem &&
|
|
278
|
+
effectiveCommentContext.position === 'leading' &&
|
|
279
|
+
this.linePrinter.getCurrentLine().text.trim() === '') {
|
|
280
|
+
this.linePrinter.getCurrentLine().level = commentLevel;
|
|
281
|
+
}
|
|
244
282
|
this.handleCommentBlockContainer(token, commentLevel, effectiveCommentContext);
|
|
245
283
|
return;
|
|
246
284
|
}
|
|
247
285
|
const current = this.linePrinter.getCurrentLine();
|
|
248
286
|
const isCaseContext = this.isCaseContext(token.containerType);
|
|
249
287
|
const nextCaseContextDepth = isCaseContext ? caseContextDepth + 1 : caseContextDepth;
|
|
250
|
-
|
|
288
|
+
let shouldIndentNested = this.shouldIndentNestedParentheses(token, previousSiblingWasOpenParen);
|
|
251
289
|
// Handle different token types
|
|
252
290
|
if (token.type === SqlPrintToken_1.SqlPrintTokenType.keyword) {
|
|
253
291
|
this.handleKeywordToken(token, level, parentContainerType, caseContextDepth);
|
|
@@ -255,6 +293,9 @@ class SqlPrinter {
|
|
|
255
293
|
else if (token.type === SqlPrintToken_1.SqlPrintTokenType.comma) {
|
|
256
294
|
this.handleCommaToken(token, level, parentContainerType);
|
|
257
295
|
}
|
|
296
|
+
else if (token.type === SqlPrintToken_1.SqlPrintTokenType.argumentSplitter) {
|
|
297
|
+
this.handleArgumentSplitterToken(token, level, parentContainerType);
|
|
298
|
+
}
|
|
258
299
|
else if (token.type === SqlPrintToken_1.SqlPrintTokenType.parenthesis) {
|
|
259
300
|
this.handleParenthesisToken(token, level, indentParentActive, parentContainerType);
|
|
260
301
|
}
|
|
@@ -284,16 +325,25 @@ class SqlPrinter {
|
|
|
284
325
|
this.handleCommentNewlineToken(token, commentLevel);
|
|
285
326
|
}
|
|
286
327
|
else if (token.containerType === SqlPrintToken_1.SqlPrintTokenContainerType.CommonTable && this.withClauseStyle === 'cte-oneline') {
|
|
287
|
-
this.
|
|
288
|
-
|
|
328
|
+
if (this.tryHandleCteOnelineToken(token, level)) {
|
|
329
|
+
return; // Return early to avoid processing innerTokens
|
|
330
|
+
}
|
|
289
331
|
}
|
|
290
|
-
else if (this.shouldFormatContainerAsOneline(token, shouldIndentNested)) {
|
|
291
|
-
this.handleOnelineToken(token, level);
|
|
332
|
+
else if (this.shouldFormatContainerAsOneline(token, shouldIndentNested) && this.tryHandleOnelineToken(token, level)) {
|
|
292
333
|
return; // Return early to avoid processing innerTokens
|
|
293
334
|
}
|
|
294
335
|
else if (!this.tryAppendInsertClauseTokenText(token.text, parentContainerType)) {
|
|
295
336
|
this.linePrinter.appendText(token.text);
|
|
296
337
|
}
|
|
338
|
+
if (token.containerType === SqlPrintToken_1.SqlPrintTokenContainerType.JoinOnClause &&
|
|
339
|
+
this.joinOnBreak === 'before' &&
|
|
340
|
+
!this.isOnelineMode() &&
|
|
341
|
+
this.linePrinter.getCurrentLine().text.trim().length > 0) {
|
|
342
|
+
this.linePrinter.appendNewline(level + 1);
|
|
343
|
+
}
|
|
344
|
+
if (this.expandedOneLineFallbackTokens.has(token)) {
|
|
345
|
+
shouldIndentNested = true;
|
|
346
|
+
}
|
|
297
347
|
// append keyword tokens(not indented)
|
|
298
348
|
if (token.keywordTokens && token.keywordTokens.length > 0) {
|
|
299
349
|
for (let i = 0; i < token.keywordTokens.length; i++) {
|
|
@@ -307,6 +357,9 @@ class SqlPrinter {
|
|
|
307
357
|
const delayIndentNewline = shouldIndentNested && token.containerType === SqlPrintToken_1.SqlPrintTokenContainerType.ParenExpression;
|
|
308
358
|
const isAlterTableStatement = token.containerType === SqlPrintToken_1.SqlPrintTokenContainerType.AlterTableStatement;
|
|
309
359
|
let deferAlterTableIndent = false;
|
|
360
|
+
if (token.containerType === SqlPrintToken_1.SqlPrintTokenContainerType.JoinOnClause && this.joinOnBreak === 'before' && !this.isOnelineMode()) {
|
|
361
|
+
innerLevel = level + 1;
|
|
362
|
+
}
|
|
310
363
|
const alignExplainChild = this.shouldAlignExplainStatementChild(parentContainerType, token.containerType);
|
|
311
364
|
if (alignExplainChild) {
|
|
312
365
|
// Keep EXPLAIN target statements flush left so they render like standalone statements.
|
|
@@ -359,6 +412,15 @@ class SqlPrinter {
|
|
|
359
412
|
let mergePredicateActive = isMergeWhenClause;
|
|
360
413
|
let alterTableTableRendered = false;
|
|
361
414
|
let alterTableIndentInserted = false;
|
|
415
|
+
const enteredJoinOnClause = token.containerType === SqlPrintToken_1.SqlPrintTokenContainerType.JoinOnClause;
|
|
416
|
+
if (enteredJoinOnClause) {
|
|
417
|
+
this.joinOnClauseDepth++;
|
|
418
|
+
}
|
|
419
|
+
const enteredCommentedFunctionCall = this.shouldExpandCommentedFunctionCall(token);
|
|
420
|
+
if (enteredCommentedFunctionCall) {
|
|
421
|
+
this.commentedFunctionCallDepth++;
|
|
422
|
+
}
|
|
423
|
+
const enteredLogicalOperatorWithComment = this.isLogicalOperatorWithComment(token);
|
|
362
424
|
for (let i = leadingCommentCount; i < token.innerTokens.length; i++) {
|
|
363
425
|
const child = token.innerTokens[i];
|
|
364
426
|
const nextChild = token.innerTokens[i + 1];
|
|
@@ -409,7 +471,10 @@ class SqlPrinter {
|
|
|
409
471
|
const childCommentContext = child.containerType === SqlPrintToken_1.SqlPrintTokenContainerType.CommentBlock
|
|
410
472
|
? { position: 'inline', isTopLevelContainer: containerIsTopLevel }
|
|
411
473
|
: undefined;
|
|
412
|
-
|
|
474
|
+
const childLevel = enteredCommentedFunctionCall && child.containerType === SqlPrintToken_1.SqlPrintTokenContainerType.ValueList
|
|
475
|
+
? innerLevel + 1
|
|
476
|
+
: innerLevel;
|
|
477
|
+
this.appendToken(child, childLevel, token.containerType, nextCaseContextDepth, childIndentParentActive, childCommentContext, previousChildWasOpenParen);
|
|
413
478
|
if (inMergePredicate) {
|
|
414
479
|
this.mergeWhenPredicateDepth--;
|
|
415
480
|
}
|
|
@@ -417,9 +482,24 @@ class SqlPrinter {
|
|
|
417
482
|
mergePredicateActive = false;
|
|
418
483
|
}
|
|
419
484
|
}
|
|
485
|
+
if (enteredLogicalOperatorWithComment && !this.isOnelineMode()) {
|
|
486
|
+
const currentLine = this.linePrinter.getCurrentLine();
|
|
487
|
+
if (currentLine.text.trim() === '') {
|
|
488
|
+
currentLine.level = level + 1;
|
|
489
|
+
}
|
|
490
|
+
else {
|
|
491
|
+
this.linePrinter.appendNewline(level + 1);
|
|
492
|
+
}
|
|
493
|
+
}
|
|
420
494
|
if (this.smartCommentBlockBuilder && this.smartCommentBlockBuilder.mode === 'line') {
|
|
421
495
|
this.flushSmartCommentBlockBuilder();
|
|
422
496
|
}
|
|
497
|
+
if (enteredJoinOnClause) {
|
|
498
|
+
this.joinOnClauseDepth--;
|
|
499
|
+
}
|
|
500
|
+
if (enteredCommentedFunctionCall) {
|
|
501
|
+
this.commentedFunctionCallDepth--;
|
|
502
|
+
}
|
|
423
503
|
// Exit WITH clause context when we finish processing WithClause container
|
|
424
504
|
if (token.containerType === SqlPrintToken_1.SqlPrintTokenContainerType.WithClause && this.withClauseStyle === 'full-oneline') {
|
|
425
505
|
this.insideWithClause = false;
|
|
@@ -447,6 +527,27 @@ class SqlPrinter {
|
|
|
447
527
|
return false;
|
|
448
528
|
}
|
|
449
529
|
}
|
|
530
|
+
shouldExpandCommentedFunctionCall(token) {
|
|
531
|
+
return this.commentExportMode !== 'none' &&
|
|
532
|
+
token.containerType === SqlPrintToken_1.SqlPrintTokenContainerType.FunctionCall &&
|
|
533
|
+
token.innerTokens.some(child => child.containerType === SqlPrintToken_1.SqlPrintTokenContainerType.ValueList &&
|
|
534
|
+
this.containsCommentBlock(child));
|
|
535
|
+
}
|
|
536
|
+
containsCommentBlock(token) {
|
|
537
|
+
if (token.containerType === SqlPrintToken_1.SqlPrintTokenContainerType.CommentBlock) {
|
|
538
|
+
return true;
|
|
539
|
+
}
|
|
540
|
+
return token.innerTokens.some(child => this.containsCommentBlock(child));
|
|
541
|
+
}
|
|
542
|
+
isLogicalOperatorWithComment(token) {
|
|
543
|
+
return this.containsCommentBlock(token) &&
|
|
544
|
+
token.type === SqlPrintToken_1.SqlPrintTokenType.operator &&
|
|
545
|
+
['and', 'or'].includes(token.text.toLowerCase());
|
|
546
|
+
}
|
|
547
|
+
currentLineEndsWithLogicalOperator() {
|
|
548
|
+
const trimmed = this.linePrinter.getCurrentLine().text.trim().toLowerCase();
|
|
549
|
+
return trimmed === 'and' || trimmed === 'or';
|
|
550
|
+
}
|
|
450
551
|
isCaseContext(containerType) {
|
|
451
552
|
switch (containerType) {
|
|
452
553
|
case SqlPrintToken_1.SqlPrintTokenContainerType.CaseExpression:
|
|
@@ -606,6 +707,14 @@ class SqlPrinter {
|
|
|
606
707
|
this.linePrinter.appendText(text);
|
|
607
708
|
}
|
|
608
709
|
}
|
|
710
|
+
handleArgumentSplitterToken(token, level, parentContainerType) {
|
|
711
|
+
this.linePrinter.appendText(token.text);
|
|
712
|
+
if (this.commentedFunctionCallDepth > 0 &&
|
|
713
|
+
parentContainerType === SqlPrintToken_1.SqlPrintTokenContainerType.ValueList &&
|
|
714
|
+
!this.isOnelineMode()) {
|
|
715
|
+
this.linePrinter.appendNewline(level);
|
|
716
|
+
}
|
|
717
|
+
}
|
|
609
718
|
handleAndOperatorToken(token, level, parentContainerType, caseContextDepth = 0) {
|
|
610
719
|
const text = this.applyKeywordCase(token.text);
|
|
611
720
|
if (caseContextDepth > 0) {
|
|
@@ -620,7 +729,7 @@ class SqlPrinter {
|
|
|
620
729
|
if (this.andBreak === 'before') {
|
|
621
730
|
// Skip newline when inside WITH clause with full-oneline style
|
|
622
731
|
if (!(this.insideWithClause && this.withClauseStyle === 'full-oneline')) {
|
|
623
|
-
this.linePrinter.appendNewline(level);
|
|
732
|
+
this.linePrinter.appendNewline(this.getJoinConditionContinuationLevel(level));
|
|
624
733
|
}
|
|
625
734
|
this.linePrinter.appendText(text);
|
|
626
735
|
}
|
|
@@ -628,7 +737,7 @@ class SqlPrinter {
|
|
|
628
737
|
this.linePrinter.appendText(text);
|
|
629
738
|
// Skip newline when inside WITH clause with full-oneline style
|
|
630
739
|
if (!(this.insideWithClause && this.withClauseStyle === 'full-oneline')) {
|
|
631
|
-
this.linePrinter.appendNewline(level);
|
|
740
|
+
this.linePrinter.appendNewline(this.getJoinConditionContinuationLevel(level));
|
|
632
741
|
}
|
|
633
742
|
}
|
|
634
743
|
else {
|
|
@@ -638,6 +747,12 @@ class SqlPrinter {
|
|
|
638
747
|
handleParenthesisToken(token, level, indentParentActive, parentContainerType) {
|
|
639
748
|
if (token.text === '(') {
|
|
640
749
|
this.linePrinter.appendText(token.text);
|
|
750
|
+
if (this.commentedFunctionCallDepth > 0 &&
|
|
751
|
+
parentContainerType === SqlPrintToken_1.SqlPrintTokenContainerType.FunctionCall &&
|
|
752
|
+
!this.isOnelineMode()) {
|
|
753
|
+
this.linePrinter.appendNewline(level + 1);
|
|
754
|
+
return;
|
|
755
|
+
}
|
|
641
756
|
if ((parentContainerType === SqlPrintToken_1.SqlPrintTokenContainerType.InsertClause ||
|
|
642
757
|
parentContainerType === SqlPrintToken_1.SqlPrintTokenContainerType.MergeInsertAction) &&
|
|
643
758
|
this.insertColumnsOneLine) {
|
|
@@ -647,19 +762,29 @@ class SqlPrinter {
|
|
|
647
762
|
if (this.shouldBreakAfterOpeningParen(parentContainerType)) {
|
|
648
763
|
this.linePrinter.appendNewline(level + 1);
|
|
649
764
|
}
|
|
650
|
-
else if (indentParentActive &&
|
|
765
|
+
else if (indentParentActive &&
|
|
766
|
+
parentContainerType === SqlPrintToken_1.SqlPrintTokenContainerType.ParenExpression &&
|
|
767
|
+
!(this.insideWithClause && this.withClauseStyle === 'full-oneline')) {
|
|
651
768
|
this.linePrinter.appendNewline(level);
|
|
652
769
|
}
|
|
653
770
|
}
|
|
654
771
|
return;
|
|
655
772
|
}
|
|
656
773
|
if (token.text === ')' && !this.isOnelineMode()) {
|
|
774
|
+
if (this.commentedFunctionCallDepth > 0 &&
|
|
775
|
+
parentContainerType === SqlPrintToken_1.SqlPrintTokenContainerType.FunctionCall) {
|
|
776
|
+
this.linePrinter.appendNewline(level);
|
|
777
|
+
this.linePrinter.appendText(token.text);
|
|
778
|
+
return;
|
|
779
|
+
}
|
|
657
780
|
if (this.shouldBreakBeforeClosingParen(parentContainerType)) {
|
|
658
781
|
this.linePrinter.appendNewline(Math.max(level, 0));
|
|
659
782
|
this.linePrinter.appendText(token.text);
|
|
660
783
|
return;
|
|
661
784
|
}
|
|
662
|
-
if (indentParentActive &&
|
|
785
|
+
if (indentParentActive &&
|
|
786
|
+
parentContainerType === SqlPrintToken_1.SqlPrintTokenContainerType.ParenExpression &&
|
|
787
|
+
!(this.insideWithClause && this.withClauseStyle === 'full-oneline')) {
|
|
663
788
|
const closingLevel = Math.max(level - 1, 0);
|
|
664
789
|
this.linePrinter.appendNewline(closingLevel);
|
|
665
790
|
}
|
|
@@ -681,7 +806,7 @@ class SqlPrinter {
|
|
|
681
806
|
if (this.orBreak === 'before') {
|
|
682
807
|
// Insert a newline before OR unless WITH full-oneline mode suppresses breaks.
|
|
683
808
|
if (!(this.insideWithClause && this.withClauseStyle === 'full-oneline')) {
|
|
684
|
-
this.linePrinter.appendNewline(level);
|
|
809
|
+
this.linePrinter.appendNewline(this.getJoinConditionContinuationLevel(level));
|
|
685
810
|
}
|
|
686
811
|
this.linePrinter.appendText(text);
|
|
687
812
|
}
|
|
@@ -689,13 +814,22 @@ class SqlPrinter {
|
|
|
689
814
|
this.linePrinter.appendText(text);
|
|
690
815
|
// Break after OR when multi-line formatting is active.
|
|
691
816
|
if (!(this.insideWithClause && this.withClauseStyle === 'full-oneline')) {
|
|
692
|
-
this.linePrinter.appendNewline(level);
|
|
817
|
+
this.linePrinter.appendNewline(this.getJoinConditionContinuationLevel(level));
|
|
693
818
|
}
|
|
694
819
|
}
|
|
695
820
|
else {
|
|
696
821
|
this.linePrinter.appendText(text);
|
|
697
822
|
}
|
|
698
823
|
}
|
|
824
|
+
getJoinConditionContinuationLevel(level) {
|
|
825
|
+
if (this.joinOnClauseDepth === 0) {
|
|
826
|
+
return level;
|
|
827
|
+
}
|
|
828
|
+
if (this.joinOnBreak === 'before') {
|
|
829
|
+
return level;
|
|
830
|
+
}
|
|
831
|
+
return this.joinConditionContinuationIndent ? level + 1 : level;
|
|
832
|
+
}
|
|
699
833
|
/**
|
|
700
834
|
* Decide whether a parentheses group should increase indentation when inside nested structures.
|
|
701
835
|
* We only expand groups that contain further parentheses so simple comparisons stay compact.
|
|
@@ -707,6 +841,9 @@ class SqlPrinter {
|
|
|
707
841
|
if (token.containerType !== SqlPrintToken_1.SqlPrintTokenContainerType.ParenExpression) {
|
|
708
842
|
return false;
|
|
709
843
|
}
|
|
844
|
+
if (this.expandedOneLineFallbackTokens.has(token)) {
|
|
845
|
+
return true;
|
|
846
|
+
}
|
|
710
847
|
// Look for nested parentheses containers. If present, indent to highlight grouping.
|
|
711
848
|
return previousSiblingWasOpenParen || token.innerTokens.some((child) => this.containsParenExpression(child));
|
|
712
849
|
}
|
|
@@ -753,6 +890,12 @@ class SqlPrinter {
|
|
|
753
890
|
if (this.smartCommentBlockBuilder && this.smartCommentBlockBuilder.mode === 'line') {
|
|
754
891
|
this.flushSmartCommentBlockBuilder();
|
|
755
892
|
}
|
|
893
|
+
if (this.commentedFunctionCallDepth > 0 &&
|
|
894
|
+
parentContainerType === SqlPrintToken_1.SqlPrintTokenContainerType.ValueList &&
|
|
895
|
+
(previousToken === null || previousToken === void 0 ? void 0 : previousToken.type) === SqlPrintToken_1.SqlPrintTokenType.argumentSplitter &&
|
|
896
|
+
!this.isOnelineMode()) {
|
|
897
|
+
return;
|
|
898
|
+
}
|
|
756
899
|
const currentLineText = this.linePrinter.getCurrentLine().text;
|
|
757
900
|
if (this.onelineHelper.shouldSkipInsertClauseSpace(parentContainerType, nextToken, currentLineText)) {
|
|
758
901
|
return;
|
|
@@ -977,6 +1120,11 @@ class SqlPrinter {
|
|
|
977
1120
|
}
|
|
978
1121
|
return;
|
|
979
1122
|
}
|
|
1123
|
+
const emptyBlockCommentText = this.getEmptyBlockCommentText(token);
|
|
1124
|
+
if (emptyBlockCommentText !== null) {
|
|
1125
|
+
this.linePrinter.appendText(emptyBlockCommentText);
|
|
1126
|
+
return;
|
|
1127
|
+
}
|
|
980
1128
|
const lines = this.collectCommentBlockLines(token);
|
|
981
1129
|
if (lines.length === 0 && !this.smartCommentBlockBuilder) {
|
|
982
1130
|
// No meaningful content; treat as empty line comment to preserve spacing
|
|
@@ -998,6 +1146,18 @@ class SqlPrinter {
|
|
|
998
1146
|
this.smartCommentBlockBuilder.lines.push(...lines);
|
|
999
1147
|
}
|
|
1000
1148
|
}
|
|
1149
|
+
getEmptyBlockCommentText(token) {
|
|
1150
|
+
var _a;
|
|
1151
|
+
const commentTokens = ((_a = token.innerTokens) !== null && _a !== void 0 ? _a : []).filter(child => child.type === SqlPrintToken_1.SqlPrintTokenType.comment);
|
|
1152
|
+
if (commentTokens.length !== 1) {
|
|
1153
|
+
return null;
|
|
1154
|
+
}
|
|
1155
|
+
const trimmed = commentTokens[0].text.trim();
|
|
1156
|
+
if (!trimmed.startsWith('/*') || !trimmed.endsWith('*/')) {
|
|
1157
|
+
return null;
|
|
1158
|
+
}
|
|
1159
|
+
return trimmed.slice(2, -2).trim() === '' ? trimmed : null;
|
|
1160
|
+
}
|
|
1001
1161
|
normalizeSmartBlockLine(raw) {
|
|
1002
1162
|
// Remove trailing whitespace that only carries formatting artifacts
|
|
1003
1163
|
let line = raw.replace(/\s+$/g, '');
|
|
@@ -1073,7 +1233,12 @@ class SqlPrinter {
|
|
|
1073
1233
|
}
|
|
1074
1234
|
const content = this.extractLineCommentContent(trimmed);
|
|
1075
1235
|
if (content !== null) {
|
|
1076
|
-
|
|
1236
|
+
if (!content && trimmed.startsWith('/*') && trimmed.endsWith('*/')) {
|
|
1237
|
+
lines.push(this.sanitizeCommentLine(this.escapeCommentDelimiters(trimmed)));
|
|
1238
|
+
}
|
|
1239
|
+
else {
|
|
1240
|
+
lines.push(content);
|
|
1241
|
+
}
|
|
1077
1242
|
}
|
|
1078
1243
|
}
|
|
1079
1244
|
}
|
|
@@ -1259,6 +1424,10 @@ class SqlPrinter {
|
|
|
1259
1424
|
if (parentType === SqlPrintToken_1.SqlPrintTokenContainerType.SelectClause) {
|
|
1260
1425
|
return true;
|
|
1261
1426
|
}
|
|
1427
|
+
if (parentType === SqlPrintToken_1.SqlPrintTokenContainerType.OrderByItem ||
|
|
1428
|
+
parentType === SqlPrintToken_1.SqlPrintTokenContainerType.GroupByClause) {
|
|
1429
|
+
return true;
|
|
1430
|
+
}
|
|
1262
1431
|
if (parentType === SqlPrintToken_1.SqlPrintTokenContainerType.ExplainStatement) {
|
|
1263
1432
|
// Ensure EXPLAIN targets print header comments on a dedicated line.
|
|
1264
1433
|
return true;
|
|
@@ -1269,6 +1438,13 @@ class SqlPrinter {
|
|
|
1269
1438
|
return false;
|
|
1270
1439
|
}
|
|
1271
1440
|
getLeadingCommentIndentLevel(parentType, currentLevel) {
|
|
1441
|
+
if (parentType === SqlPrintToken_1.SqlPrintTokenContainerType.SelectItem) {
|
|
1442
|
+
return currentLevel;
|
|
1443
|
+
}
|
|
1444
|
+
if (parentType === SqlPrintToken_1.SqlPrintTokenContainerType.OrderByItem ||
|
|
1445
|
+
parentType === SqlPrintToken_1.SqlPrintTokenContainerType.GroupByClause) {
|
|
1446
|
+
return currentLevel;
|
|
1447
|
+
}
|
|
1272
1448
|
if (parentType === SqlPrintToken_1.SqlPrintTokenContainerType.TupleExpression) {
|
|
1273
1449
|
return currentLevel + 1;
|
|
1274
1450
|
}
|
|
@@ -1283,6 +1459,12 @@ class SqlPrinter {
|
|
|
1283
1459
|
}
|
|
1284
1460
|
return currentLevel;
|
|
1285
1461
|
}
|
|
1462
|
+
shouldKeepLeadingCommentOnCommaLine() {
|
|
1463
|
+
if (this.commaBreak !== 'before') {
|
|
1464
|
+
return false;
|
|
1465
|
+
}
|
|
1466
|
+
return this.linePrinter.getCurrentLine().text.trim() === ',';
|
|
1467
|
+
}
|
|
1286
1468
|
/**
|
|
1287
1469
|
* Determines if the printer is in oneliner mode.
|
|
1288
1470
|
* Oneliner mode uses single spaces instead of actual newlines.
|
|
@@ -1290,16 +1472,36 @@ class SqlPrinter {
|
|
|
1290
1472
|
isOnelineMode() {
|
|
1291
1473
|
return this.newline === ' ';
|
|
1292
1474
|
}
|
|
1475
|
+
normalizeOneLineMaxLength(value) {
|
|
1476
|
+
if (value === undefined || !Number.isFinite(value) || value <= 0) {
|
|
1477
|
+
return undefined;
|
|
1478
|
+
}
|
|
1479
|
+
const normalized = Math.floor(value);
|
|
1480
|
+
return normalized > 0 ? normalized : undefined;
|
|
1481
|
+
}
|
|
1482
|
+
fitsOneLineMaxLength(text) {
|
|
1483
|
+
if (this.oneLineMaxLength === undefined) {
|
|
1484
|
+
return true;
|
|
1485
|
+
}
|
|
1486
|
+
const currentLine = this.linePrinter.getCurrentLine();
|
|
1487
|
+
const indentWidth = currentLine.level * this.indentSize * String(this.indentChar).length;
|
|
1488
|
+
return indentWidth + currentLine.text.length + text.length <= this.oneLineMaxLength;
|
|
1489
|
+
}
|
|
1293
1490
|
/**
|
|
1294
1491
|
* Handles CTE tokens with one-liner formatting.
|
|
1295
1492
|
* Creates a nested SqlPrinter instance for proper CTE oneline formatting.
|
|
1296
1493
|
*/
|
|
1297
|
-
|
|
1494
|
+
tryHandleCteOnelineToken(token, level) {
|
|
1298
1495
|
const onelinePrinter = this.createCteOnelinePrinter();
|
|
1299
1496
|
const onelineResult = onelinePrinter.print(token, level);
|
|
1300
1497
|
let cleanedResult = this.cleanDuplicateSpaces(onelineResult);
|
|
1301
1498
|
cleanedResult = cleanedResult.replace(/\(\s+/g, '(').replace(/\s+\)/g, ' )');
|
|
1302
|
-
|
|
1499
|
+
const trimmedResult = cleanedResult.trim();
|
|
1500
|
+
if (!this.fitsOneLineMaxLength(trimmedResult)) {
|
|
1501
|
+
return false;
|
|
1502
|
+
}
|
|
1503
|
+
this.linePrinter.appendText(trimmedResult);
|
|
1504
|
+
return true;
|
|
1303
1505
|
}
|
|
1304
1506
|
/**
|
|
1305
1507
|
* Creates a SqlPrinter instance configured for CTE oneline formatting.
|
|
@@ -1325,11 +1527,31 @@ class SqlPrinter {
|
|
|
1325
1527
|
* Handles tokens with oneline formatting (parentheses, BETWEEN, VALUES, JOIN, CASE, subqueries).
|
|
1326
1528
|
* Creates a unified oneline printer that formats everything as one line regardless of content type.
|
|
1327
1529
|
*/
|
|
1328
|
-
|
|
1530
|
+
tryHandleOnelineToken(token, level) {
|
|
1329
1531
|
const onelinePrinter = this.createOnelinePrinter();
|
|
1330
1532
|
const onelineResult = onelinePrinter.print(token, level);
|
|
1331
1533
|
const cleanedResult = this.cleanDuplicateSpaces(onelineResult);
|
|
1534
|
+
if (!this.fitsOneLineMaxLength(cleanedResult)) {
|
|
1535
|
+
if (this.isBooleanParenExpression(token)) {
|
|
1536
|
+
this.expandedOneLineFallbackTokens.add(token);
|
|
1537
|
+
}
|
|
1538
|
+
return false;
|
|
1539
|
+
}
|
|
1332
1540
|
this.linePrinter.appendText(cleanedResult);
|
|
1541
|
+
return true;
|
|
1542
|
+
}
|
|
1543
|
+
isBooleanParenExpression(token) {
|
|
1544
|
+
if (token.containerType !== SqlPrintToken_1.SqlPrintTokenContainerType.ParenExpression) {
|
|
1545
|
+
return false;
|
|
1546
|
+
}
|
|
1547
|
+
return this.containsLogicalOperator(token);
|
|
1548
|
+
}
|
|
1549
|
+
containsLogicalOperator(token) {
|
|
1550
|
+
if ((token.type === SqlPrintToken_1.SqlPrintTokenType.operator || token.type === SqlPrintToken_1.SqlPrintTokenType.keyword) &&
|
|
1551
|
+
['and', 'or'].includes(token.text.toLowerCase())) {
|
|
1552
|
+
return true;
|
|
1553
|
+
}
|
|
1554
|
+
return token.innerTokens.some((child) => this.containsLogicalOperator(child));
|
|
1333
1555
|
}
|
|
1334
1556
|
getClauseBreakIndentLevel(parentType, level) {
|
|
1335
1557
|
if (!parentType) {
|