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.
Files changed (54) hide show
  1. package/dist/esm/index.min.js +7 -7
  2. package/dist/esm/index.min.js.map +2 -2
  3. package/dist/esm/parsers/CommandExpressionParser.d.ts +2 -0
  4. package/dist/esm/parsers/CommandExpressionParser.js +49 -4
  5. package/dist/esm/parsers/CommandExpressionParser.js.map +1 -1
  6. package/dist/esm/parsers/HavingParser.js +6 -0
  7. package/dist/esm/parsers/HavingParser.js.map +1 -1
  8. package/dist/esm/parsers/JoinOnClauseParser.js +6 -0
  9. package/dist/esm/parsers/JoinOnClauseParser.js.map +1 -1
  10. package/dist/esm/parsers/LimitClauseParser.js +6 -0
  11. package/dist/esm/parsers/LimitClauseParser.js.map +1 -1
  12. package/dist/esm/parsers/OffsetClauseParser.js +6 -0
  13. package/dist/esm/parsers/OffsetClauseParser.js.map +1 -1
  14. package/dist/esm/parsers/OrderByClauseParser.d.ts +2 -0
  15. package/dist/esm/parsers/OrderByClauseParser.js +42 -29
  16. package/dist/esm/parsers/OrderByClauseParser.js.map +1 -1
  17. package/dist/esm/parsers/SqlPrintTokenParser.d.ts +3 -0
  18. package/dist/esm/parsers/SqlPrintTokenParser.js +70 -6
  19. package/dist/esm/parsers/SqlPrintTokenParser.js.map +1 -1
  20. package/dist/esm/parsers/ValueParser.js +5 -3
  21. package/dist/esm/parsers/ValueParser.js.map +1 -1
  22. package/dist/esm/transformers/SqlFormatter.d.ts +7 -1
  23. package/dist/esm/transformers/SqlFormatter.js.map +1 -1
  24. package/dist/esm/transformers/SqlPrinter.d.ts +32 -2
  25. package/dist/esm/transformers/SqlPrinter.js +255 -33
  26. package/dist/esm/transformers/SqlPrinter.js.map +1 -1
  27. package/dist/index.min.js +7 -7
  28. package/dist/index.min.js.map +2 -2
  29. package/dist/parsers/CommandExpressionParser.js +49 -4
  30. package/dist/parsers/CommandExpressionParser.js.map +1 -1
  31. package/dist/parsers/HavingParser.js +6 -0
  32. package/dist/parsers/HavingParser.js.map +1 -1
  33. package/dist/parsers/JoinOnClauseParser.js +6 -0
  34. package/dist/parsers/JoinOnClauseParser.js.map +1 -1
  35. package/dist/parsers/LimitClauseParser.js +6 -0
  36. package/dist/parsers/LimitClauseParser.js.map +1 -1
  37. package/dist/parsers/OffsetClauseParser.js +6 -0
  38. package/dist/parsers/OffsetClauseParser.js.map +1 -1
  39. package/dist/parsers/OrderByClauseParser.js +42 -29
  40. package/dist/parsers/OrderByClauseParser.js.map +1 -1
  41. package/dist/parsers/SqlPrintTokenParser.js +71 -6
  42. package/dist/parsers/SqlPrintTokenParser.js.map +1 -1
  43. package/dist/parsers/ValueParser.js +5 -3
  44. package/dist/parsers/ValueParser.js.map +1 -1
  45. package/dist/src/parsers/CommandExpressionParser.d.ts +2 -0
  46. package/dist/src/parsers/OrderByClauseParser.d.ts +2 -0
  47. package/dist/src/parsers/SqlPrintTokenParser.d.ts +3 -0
  48. package/dist/src/transformers/SqlFormatter.d.ts +7 -1
  49. package/dist/src/transformers/SqlPrinter.d.ts +32 -2
  50. package/dist/transformers/SqlFormatter.js.map +1 -1
  51. package/dist/transformers/SqlPrinter.js +255 -33
  52. package/dist/transformers/SqlPrinter.js.map +1 -1
  53. package/dist/tsconfig.browser.tsbuildinfo +1 -1
  54. 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.keywordCase = (_g = options === null || options === void 0 ? void 0 : options.keywordCase) !== null && _g !== void 0 ? _g : 'none';
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 = (_h = options === null || options === void 0 ? void 0 : options.withClauseStyle) !== null && _h !== void 0 ? _h : 'standard';
61
- this.commentStyle = (_j = options === null || options === void 0 ? void 0 : options.commentStyle) !== null && _j !== void 0 ? _j : 'block';
62
- this.parenthesesOneLine = (_k = options === null || options === void 0 ? void 0 : options.parenthesesOneLine) !== null && _k !== void 0 ? _k : false;
63
- this.betweenOneLine = (_l = options === null || options === void 0 ? void 0 : options.betweenOneLine) !== null && _l !== void 0 ? _l : false;
64
- this.valuesOneLine = (_m = options === null || options === void 0 ? void 0 : options.valuesOneLine) !== null && _m !== void 0 ? _m : false;
65
- this.joinOneLine = (_o = options === null || options === void 0 ? void 0 : options.joinOneLine) !== null && _o !== void 0 ? _o : false;
66
- this.caseOneLine = (_p = options === null || options === void 0 ? void 0 : options.caseOneLine) !== null && _p !== void 0 ? _p : false;
67
- this.subqueryOneLine = (_q = options === null || options === void 0 ? void 0 : options.subqueryOneLine) !== null && _q !== void 0 ? _q : false;
68
- this.indentNestedParentheses = (_r = options === null || options === void 0 ? void 0 : options.indentNestedParentheses) !== null && _r !== void 0 ? _r : false;
69
- this.insertColumnsOneLine = (_s = options === null || options === void 0 ? void 0 : options.insertColumnsOneLine) !== null && _s !== void 0 ? _s : false;
70
- this.whenOneLine = (_t = options === null || options === void 0 ? void 0 : options.whenOneLine) !== null && _t !== void 0 ? _t : false;
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((_u = options === null || options === void 0 ? void 0 : options.indentIncrementContainerTypes) !== null && _u !== void 0 ? _u : [
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(parentContainerType, level)
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
- this.linePrinter.appendNewline(this.pendingLineCommentBreak);
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
- const shouldIndentNested = this.shouldIndentNestedParentheses(token, previousSiblingWasOpenParen);
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.handleCteOnelineToken(token, level);
288
- return; // Return early to avoid processing innerTokens
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
- this.appendToken(child, innerLevel, token.containerType, nextCaseContextDepth, childIndentParentActive, childCommentContext, previousChildWasOpenParen);
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 && !(this.insideWithClause && this.withClauseStyle === 'full-oneline')) {
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 && !(this.insideWithClause && this.withClauseStyle === 'full-oneline')) {
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
- lines.push(content);
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
- handleCteOnelineToken(token, level) {
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
- this.linePrinter.appendText(cleanedResult.trim());
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
- handleOnelineToken(token, level) {
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) {