rawsql-ts 0.11.43-beta → 0.11.44-beta

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 (278) hide show
  1. package/README.md +12 -12
  2. package/dist/esm/index.js +18 -0
  3. package/dist/esm/index.js.map +1 -1
  4. package/dist/esm/index.min.js +15 -19
  5. package/dist/esm/index.min.js.map +4 -4
  6. package/dist/esm/src/index.d.ts +18 -0
  7. package/dist/esm/src/index.js +18 -0
  8. package/dist/esm/src/index.js.map +1 -1
  9. package/dist/esm/src/models/BinarySelectQuery.d.ts +25 -1
  10. package/dist/esm/src/models/BinarySelectQuery.js +28 -0
  11. package/dist/esm/src/models/BinarySelectQuery.js.map +1 -1
  12. package/dist/esm/src/models/Clause.d.ts +14 -2
  13. package/dist/esm/src/models/Clause.js +26 -1
  14. package/dist/esm/src/models/Clause.js.map +1 -1
  15. package/dist/esm/src/models/CreateTableQuery.d.ts +99 -5
  16. package/dist/esm/src/models/CreateTableQuery.js +85 -10
  17. package/dist/esm/src/models/CreateTableQuery.js.map +1 -1
  18. package/dist/esm/src/models/DDLStatements.d.ts +157 -0
  19. package/dist/esm/src/models/DDLStatements.js +141 -0
  20. package/dist/esm/src/models/DDLStatements.js.map +1 -0
  21. package/dist/esm/src/models/DeleteQuery.d.ts +17 -0
  22. package/dist/esm/src/models/DeleteQuery.js +16 -0
  23. package/dist/esm/src/models/DeleteQuery.js.map +1 -0
  24. package/dist/esm/src/models/InsertQuery.d.ts +7 -1
  25. package/dist/esm/src/models/InsertQuery.js +6 -2
  26. package/dist/esm/src/models/InsertQuery.js.map +1 -1
  27. package/dist/esm/src/models/MergeQuery.d.ts +63 -0
  28. package/dist/esm/src/models/MergeQuery.js +94 -0
  29. package/dist/esm/src/models/MergeQuery.js.map +1 -0
  30. package/dist/esm/src/models/SelectQuery.d.ts +37 -1
  31. package/dist/esm/src/models/SelectQuery.js +4 -1
  32. package/dist/esm/src/models/SelectQuery.js.map +1 -1
  33. package/dist/esm/src/models/SimpleSelectQuery.d.ts +29 -1
  34. package/dist/esm/src/models/SimpleSelectQuery.js +32 -0
  35. package/dist/esm/src/models/SimpleSelectQuery.js.map +1 -1
  36. package/dist/esm/src/models/SqlComponent.d.ts +2 -1
  37. package/dist/esm/src/models/SqlComponent.js +1 -1
  38. package/dist/esm/src/models/SqlComponent.js.map +1 -1
  39. package/dist/esm/src/models/SqlPrintToken.d.ts +33 -0
  40. package/dist/esm/src/models/SqlPrintToken.js +32 -0
  41. package/dist/esm/src/models/SqlPrintToken.js.map +1 -1
  42. package/dist/esm/src/models/ValuesQuery.d.ts +25 -1
  43. package/dist/esm/src/models/ValuesQuery.js +28 -0
  44. package/dist/esm/src/models/ValuesQuery.js.map +1 -1
  45. package/dist/esm/src/parsers/AlterTableParser.d.ts +25 -0
  46. package/dist/esm/src/parsers/AlterTableParser.js +428 -0
  47. package/dist/esm/src/parsers/AlterTableParser.js.map +1 -0
  48. package/dist/esm/src/parsers/CreateIndexParser.d.ts +16 -0
  49. package/dist/esm/src/parsers/CreateIndexParser.js +237 -0
  50. package/dist/esm/src/parsers/CreateIndexParser.js.map +1 -0
  51. package/dist/esm/src/parsers/CreateTableParser.d.ts +41 -0
  52. package/dist/esm/src/parsers/CreateTableParser.js +734 -0
  53. package/dist/esm/src/parsers/CreateTableParser.js.map +1 -0
  54. package/dist/esm/src/parsers/DeleteClauseParser.d.ts +11 -0
  55. package/dist/esm/src/parsers/DeleteClauseParser.js +33 -0
  56. package/dist/esm/src/parsers/DeleteClauseParser.js.map +1 -0
  57. package/dist/esm/src/parsers/DeleteQueryParser.d.ts +16 -0
  58. package/dist/esm/src/parsers/DeleteQueryParser.js +73 -0
  59. package/dist/esm/src/parsers/DeleteQueryParser.js.map +1 -0
  60. package/dist/esm/src/parsers/DropConstraintParser.d.ts +12 -0
  61. package/dist/esm/src/parsers/DropConstraintParser.js +47 -0
  62. package/dist/esm/src/parsers/DropConstraintParser.js.map +1 -0
  63. package/dist/esm/src/parsers/DropIndexParser.d.ts +12 -0
  64. package/dist/esm/src/parsers/DropIndexParser.js +69 -0
  65. package/dist/esm/src/parsers/DropIndexParser.js.map +1 -0
  66. package/dist/esm/src/parsers/DropTableParser.d.ts +12 -0
  67. package/dist/esm/src/parsers/DropTableParser.js +59 -0
  68. package/dist/esm/src/parsers/DropTableParser.js.map +1 -0
  69. package/dist/esm/src/parsers/FunctionExpressionParser.d.ts +4 -0
  70. package/dist/esm/src/parsers/FunctionExpressionParser.js +25 -8
  71. package/dist/esm/src/parsers/FunctionExpressionParser.js.map +1 -1
  72. package/dist/esm/src/parsers/InsertQueryParser.js +103 -31
  73. package/dist/esm/src/parsers/InsertQueryParser.js.map +1 -1
  74. package/dist/esm/src/parsers/MergeQueryParser.d.ts +26 -0
  75. package/dist/esm/src/parsers/MergeQueryParser.js +479 -0
  76. package/dist/esm/src/parsers/MergeQueryParser.js.map +1 -0
  77. package/dist/esm/src/parsers/ReturningClauseParser.js +50 -7
  78. package/dist/esm/src/parsers/ReturningClauseParser.js.map +1 -1
  79. package/dist/esm/src/parsers/SelectClauseParser.js +3 -3
  80. package/dist/esm/src/parsers/SelectClauseParser.js.map +1 -1
  81. package/dist/esm/src/parsers/SelectQueryParser.d.ts +4 -0
  82. package/dist/esm/src/parsers/SelectQueryParser.js +4 -0
  83. package/dist/esm/src/parsers/SelectQueryParser.js.map +1 -1
  84. package/dist/esm/src/parsers/SetClauseParser.js +97 -15
  85. package/dist/esm/src/parsers/SetClauseParser.js.map +1 -1
  86. package/dist/esm/src/parsers/SqlParser.d.ts +38 -0
  87. package/dist/esm/src/parsers/SqlParser.js +344 -0
  88. package/dist/esm/src/parsers/SqlParser.js.map +1 -0
  89. package/dist/esm/src/parsers/SqlPrintTokenParser.d.ts +57 -3
  90. package/dist/esm/src/parsers/SqlPrintTokenParser.js +1016 -33
  91. package/dist/esm/src/parsers/SqlPrintTokenParser.js.map +1 -1
  92. package/dist/esm/src/parsers/SqlTokenizer.d.ts +24 -2
  93. package/dist/esm/src/parsers/SqlTokenizer.js +135 -74
  94. package/dist/esm/src/parsers/SqlTokenizer.js.map +1 -1
  95. package/dist/esm/src/parsers/UpdateQueryParser.js +11 -1
  96. package/dist/esm/src/parsers/UpdateQueryParser.js.map +1 -1
  97. package/dist/esm/src/parsers/UsingClauseParser.d.ts +11 -0
  98. package/dist/esm/src/parsers/UsingClauseParser.js +29 -0
  99. package/dist/esm/src/parsers/UsingClauseParser.js.map +1 -0
  100. package/dist/esm/src/parsers/ValueParser.js +5 -1
  101. package/dist/esm/src/parsers/ValueParser.js.map +1 -1
  102. package/dist/esm/src/parsers/ValuesQueryParser.d.ts +0 -2
  103. package/dist/esm/src/parsers/ValuesQueryParser.js +5 -45
  104. package/dist/esm/src/parsers/ValuesQueryParser.js.map +1 -1
  105. package/dist/esm/src/parsers/utils/LexemeCommentUtils.d.ts +6 -0
  106. package/dist/esm/src/parsers/utils/LexemeCommentUtils.js +26 -0
  107. package/dist/esm/src/parsers/utils/LexemeCommentUtils.js.map +1 -0
  108. package/dist/esm/src/tokenReaders/CommandTokenReader.js +49 -2
  109. package/dist/esm/src/tokenReaders/CommandTokenReader.js.map +1 -1
  110. package/dist/esm/src/tokenReaders/LiteralTokenReader.js +8 -5
  111. package/dist/esm/src/tokenReaders/LiteralTokenReader.js.map +1 -1
  112. package/dist/esm/src/tokenReaders/OperatorTokenReader.js +10 -1
  113. package/dist/esm/src/tokenReaders/OperatorTokenReader.js.map +1 -1
  114. package/dist/esm/src/tokenReaders/TypeTokenReader.js +11 -1
  115. package/dist/esm/src/tokenReaders/TypeTokenReader.js.map +1 -1
  116. package/dist/esm/src/transformers/InsertQuerySelectValuesConverter.d.ts +18 -0
  117. package/dist/esm/src/transformers/InsertQuerySelectValuesConverter.js +118 -0
  118. package/dist/esm/src/transformers/InsertQuerySelectValuesConverter.js.map +1 -0
  119. package/dist/esm/src/transformers/LinePrinter.d.ts +1 -0
  120. package/dist/esm/src/transformers/LinePrinter.js +12 -0
  121. package/dist/esm/src/transformers/LinePrinter.js.map +1 -1
  122. package/dist/esm/src/transformers/OnelineFormattingHelper.d.ts +29 -0
  123. package/dist/esm/src/transformers/OnelineFormattingHelper.js +88 -0
  124. package/dist/esm/src/transformers/OnelineFormattingHelper.js.map +1 -0
  125. package/dist/esm/src/transformers/QueryBuilder.d.ts +47 -13
  126. package/dist/esm/src/transformers/QueryBuilder.js +424 -62
  127. package/dist/esm/src/transformers/QueryBuilder.js.map +1 -1
  128. package/dist/esm/src/transformers/SqlFormatter.d.ts +13 -1
  129. package/dist/esm/src/transformers/SqlFormatter.js +13 -4
  130. package/dist/esm/src/transformers/SqlFormatter.js.map +1 -1
  131. package/dist/esm/src/transformers/SqlPrinter.d.ts +46 -8
  132. package/dist/esm/src/transformers/SqlPrinter.js +596 -71
  133. package/dist/esm/src/transformers/SqlPrinter.js.map +1 -1
  134. package/dist/esm/src/types/Formatting.d.ts +8 -0
  135. package/dist/esm/src/types/Formatting.js +2 -0
  136. package/dist/esm/src/types/Formatting.js.map +1 -0
  137. package/dist/esm/src/utils/ParserStringUtils.d.ts +6 -0
  138. package/dist/esm/src/utils/ParserStringUtils.js +28 -0
  139. package/dist/esm/src/utils/ParserStringUtils.js.map +1 -0
  140. package/dist/esm/tsconfig.browser.tsbuildinfo +1 -1
  141. package/dist/index.min.js +14 -18
  142. package/dist/index.min.js.map +4 -4
  143. package/dist/src/index.d.ts +18 -0
  144. package/dist/src/index.js +18 -0
  145. package/dist/src/index.js.map +1 -1
  146. package/dist/src/models/BinarySelectQuery.d.ts +25 -1
  147. package/dist/src/models/BinarySelectQuery.js +28 -0
  148. package/dist/src/models/BinarySelectQuery.js.map +1 -1
  149. package/dist/src/models/Clause.d.ts +14 -2
  150. package/dist/src/models/Clause.js +29 -2
  151. package/dist/src/models/Clause.js.map +1 -1
  152. package/dist/src/models/CreateTableQuery.d.ts +99 -5
  153. package/dist/src/models/CreateTableQuery.js +90 -11
  154. package/dist/src/models/CreateTableQuery.js.map +1 -1
  155. package/dist/src/models/DDLStatements.d.ts +157 -0
  156. package/dist/src/models/DDLStatements.js +153 -0
  157. package/dist/src/models/DDLStatements.js.map +1 -0
  158. package/dist/src/models/DeleteQuery.d.ts +17 -0
  159. package/dist/src/models/DeleteQuery.js +20 -0
  160. package/dist/src/models/DeleteQuery.js.map +1 -0
  161. package/dist/src/models/InsertQuery.d.ts +7 -1
  162. package/dist/src/models/InsertQuery.js +6 -2
  163. package/dist/src/models/InsertQuery.js.map +1 -1
  164. package/dist/src/models/MergeQuery.d.ts +63 -0
  165. package/dist/src/models/MergeQuery.js +104 -0
  166. package/dist/src/models/MergeQuery.js.map +1 -0
  167. package/dist/src/models/SelectQuery.d.ts +37 -1
  168. package/dist/src/models/SelectQuery.js +7 -1
  169. package/dist/src/models/SelectQuery.js.map +1 -1
  170. package/dist/src/models/SimpleSelectQuery.d.ts +29 -1
  171. package/dist/src/models/SimpleSelectQuery.js +32 -0
  172. package/dist/src/models/SimpleSelectQuery.js.map +1 -1
  173. package/dist/src/models/SqlComponent.d.ts +2 -1
  174. package/dist/src/models/SqlComponent.js +1 -1
  175. package/dist/src/models/SqlComponent.js.map +1 -1
  176. package/dist/src/models/SqlPrintToken.d.ts +33 -0
  177. package/dist/src/models/SqlPrintToken.js +32 -0
  178. package/dist/src/models/SqlPrintToken.js.map +1 -1
  179. package/dist/src/models/ValuesQuery.d.ts +25 -1
  180. package/dist/src/models/ValuesQuery.js +28 -0
  181. package/dist/src/models/ValuesQuery.js.map +1 -1
  182. package/dist/src/parsers/AlterTableParser.d.ts +25 -0
  183. package/dist/src/parsers/AlterTableParser.js +432 -0
  184. package/dist/src/parsers/AlterTableParser.js.map +1 -0
  185. package/dist/src/parsers/CreateIndexParser.d.ts +16 -0
  186. package/dist/src/parsers/CreateIndexParser.js +241 -0
  187. package/dist/src/parsers/CreateIndexParser.js.map +1 -0
  188. package/dist/src/parsers/CreateTableParser.d.ts +41 -0
  189. package/dist/src/parsers/CreateTableParser.js +738 -0
  190. package/dist/src/parsers/CreateTableParser.js.map +1 -0
  191. package/dist/src/parsers/DeleteClauseParser.d.ts +11 -0
  192. package/dist/src/parsers/DeleteClauseParser.js +37 -0
  193. package/dist/src/parsers/DeleteClauseParser.js.map +1 -0
  194. package/dist/src/parsers/DeleteQueryParser.d.ts +16 -0
  195. package/dist/src/parsers/DeleteQueryParser.js +77 -0
  196. package/dist/src/parsers/DeleteQueryParser.js.map +1 -0
  197. package/dist/src/parsers/DropConstraintParser.d.ts +12 -0
  198. package/dist/src/parsers/DropConstraintParser.js +51 -0
  199. package/dist/src/parsers/DropConstraintParser.js.map +1 -0
  200. package/dist/src/parsers/DropIndexParser.d.ts +12 -0
  201. package/dist/src/parsers/DropIndexParser.js +73 -0
  202. package/dist/src/parsers/DropIndexParser.js.map +1 -0
  203. package/dist/src/parsers/DropTableParser.d.ts +12 -0
  204. package/dist/src/parsers/DropTableParser.js +63 -0
  205. package/dist/src/parsers/DropTableParser.js.map +1 -0
  206. package/dist/src/parsers/FunctionExpressionParser.d.ts +4 -0
  207. package/dist/src/parsers/FunctionExpressionParser.js +25 -8
  208. package/dist/src/parsers/FunctionExpressionParser.js.map +1 -1
  209. package/dist/src/parsers/InsertQueryParser.js +103 -31
  210. package/dist/src/parsers/InsertQueryParser.js.map +1 -1
  211. package/dist/src/parsers/MergeQueryParser.d.ts +26 -0
  212. package/dist/src/parsers/MergeQueryParser.js +483 -0
  213. package/dist/src/parsers/MergeQueryParser.js.map +1 -0
  214. package/dist/src/parsers/ReturningClauseParser.js +50 -7
  215. package/dist/src/parsers/ReturningClauseParser.js.map +1 -1
  216. package/dist/src/parsers/SelectClauseParser.js +2 -2
  217. package/dist/src/parsers/SelectClauseParser.js.map +1 -1
  218. package/dist/src/parsers/SelectQueryParser.d.ts +4 -0
  219. package/dist/src/parsers/SelectQueryParser.js +4 -0
  220. package/dist/src/parsers/SelectQueryParser.js.map +1 -1
  221. package/dist/src/parsers/SetClauseParser.js +97 -15
  222. package/dist/src/parsers/SetClauseParser.js.map +1 -1
  223. package/dist/src/parsers/SqlParser.d.ts +38 -0
  224. package/dist/src/parsers/SqlParser.js +353 -0
  225. package/dist/src/parsers/SqlParser.js.map +1 -0
  226. package/dist/src/parsers/SqlPrintTokenParser.d.ts +57 -3
  227. package/dist/src/parsers/SqlPrintTokenParser.js +1014 -31
  228. package/dist/src/parsers/SqlPrintTokenParser.js.map +1 -1
  229. package/dist/src/parsers/SqlTokenizer.d.ts +24 -2
  230. package/dist/src/parsers/SqlTokenizer.js +139 -74
  231. package/dist/src/parsers/SqlTokenizer.js.map +1 -1
  232. package/dist/src/parsers/UpdateQueryParser.js +11 -1
  233. package/dist/src/parsers/UpdateQueryParser.js.map +1 -1
  234. package/dist/src/parsers/UsingClauseParser.d.ts +11 -0
  235. package/dist/src/parsers/UsingClauseParser.js +33 -0
  236. package/dist/src/parsers/UsingClauseParser.js.map +1 -0
  237. package/dist/src/parsers/ValueParser.js +5 -1
  238. package/dist/src/parsers/ValueParser.js.map +1 -1
  239. package/dist/src/parsers/ValuesQueryParser.d.ts +0 -2
  240. package/dist/src/parsers/ValuesQueryParser.js +5 -45
  241. package/dist/src/parsers/ValuesQueryParser.js.map +1 -1
  242. package/dist/src/parsers/utils/LexemeCommentUtils.d.ts +6 -0
  243. package/dist/src/parsers/utils/LexemeCommentUtils.js +29 -0
  244. package/dist/src/parsers/utils/LexemeCommentUtils.js.map +1 -0
  245. package/dist/src/tokenReaders/CommandTokenReader.js +49 -2
  246. package/dist/src/tokenReaders/CommandTokenReader.js.map +1 -1
  247. package/dist/src/tokenReaders/LiteralTokenReader.js +8 -5
  248. package/dist/src/tokenReaders/LiteralTokenReader.js.map +1 -1
  249. package/dist/src/tokenReaders/OperatorTokenReader.js +10 -1
  250. package/dist/src/tokenReaders/OperatorTokenReader.js.map +1 -1
  251. package/dist/src/tokenReaders/TypeTokenReader.js +11 -1
  252. package/dist/src/tokenReaders/TypeTokenReader.js.map +1 -1
  253. package/dist/src/transformers/InsertQuerySelectValuesConverter.d.ts +18 -0
  254. package/dist/src/transformers/InsertQuerySelectValuesConverter.js +122 -0
  255. package/dist/src/transformers/InsertQuerySelectValuesConverter.js.map +1 -0
  256. package/dist/src/transformers/LinePrinter.d.ts +1 -0
  257. package/dist/src/transformers/LinePrinter.js +12 -0
  258. package/dist/src/transformers/LinePrinter.js.map +1 -1
  259. package/dist/src/transformers/OnelineFormattingHelper.d.ts +29 -0
  260. package/dist/src/transformers/OnelineFormattingHelper.js +92 -0
  261. package/dist/src/transformers/OnelineFormattingHelper.js.map +1 -0
  262. package/dist/src/transformers/QueryBuilder.d.ts +47 -13
  263. package/dist/src/transformers/QueryBuilder.js +433 -60
  264. package/dist/src/transformers/QueryBuilder.js.map +1 -1
  265. package/dist/src/transformers/SqlFormatter.d.ts +13 -1
  266. package/dist/src/transformers/SqlFormatter.js +20 -5
  267. package/dist/src/transformers/SqlFormatter.js.map +1 -1
  268. package/dist/src/transformers/SqlPrinter.d.ts +46 -8
  269. package/dist/src/transformers/SqlPrinter.js +596 -71
  270. package/dist/src/transformers/SqlPrinter.js.map +1 -1
  271. package/dist/src/types/Formatting.d.ts +8 -0
  272. package/dist/src/types/Formatting.js +3 -0
  273. package/dist/src/types/Formatting.js.map +1 -0
  274. package/dist/src/utils/ParserStringUtils.d.ts +6 -0
  275. package/dist/src/utils/ParserStringUtils.js +31 -0
  276. package/dist/src/utils/ParserStringUtils.js.map +1 -0
  277. package/dist/tsconfig.tsbuildinfo +1 -1
  278. package/package.json +1 -1
@@ -1,6 +1,10 @@
1
1
  import { SqlPrintTokenType, SqlPrintTokenContainerType } from "../models/SqlPrintToken";
2
2
  import { LinePrinter } from "./LinePrinter";
3
3
  import { resolveIndentCharOption, resolveNewlineOption } from "./FormatOptionResolver";
4
+ import { OnelineFormattingHelper, } from "./OnelineFormattingHelper";
5
+ const CREATE_TABLE_SINGLE_PAREN_KEYWORDS = new Set(['unique', 'check', 'key', 'index']);
6
+ const CREATE_TABLE_MULTI_PAREN_KEYWORDS = new Set(['primary key', 'foreign key', 'unique key']);
7
+ const CREATE_TABLE_PAREN_KEYWORDS_WITH_IDENTIFIER = new Set(['references']);
4
8
  /**
5
9
  * SqlPrinter formats a SqlPrintToken tree into a SQL string with flexible style options.
6
10
  *
@@ -26,9 +30,11 @@ export class SqlPrinter {
26
30
  * @param options Optional style settings for pretty printing
27
31
  */
28
32
  constructor(options) {
29
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t;
33
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u;
30
34
  /** Track whether we are currently inside a WITH clause for full-oneline formatting */
31
35
  this.insideWithClause = false;
36
+ /** Tracks nesting depth while formatting MERGE WHEN predicate segments */
37
+ this.mergeWhenPredicateDepth = 0;
32
38
  /** Pending line comment that needs a forced newline before next token */
33
39
  this.pendingLineCommentBreak = null;
34
40
  /** Accumulates lines when reconstructing multi-line block comments inside CommentBlocks */
@@ -47,19 +53,32 @@ export class SqlPrinter {
47
53
  this.andBreak = (_e = options === null || options === void 0 ? void 0 : options.andBreak) !== null && _e !== void 0 ? _e : 'none';
48
54
  this.orBreak = (_f = options === null || options === void 0 ? void 0 : options.orBreak) !== null && _f !== void 0 ? _f : 'none';
49
55
  this.keywordCase = (_g = options === null || options === void 0 ? void 0 : options.keywordCase) !== null && _g !== void 0 ? _g : 'none';
50
- this.exportComment = (_h = options === null || options === void 0 ? void 0 : options.exportComment) !== null && _h !== void 0 ? _h : false;
51
- this.withClauseStyle = (_j = options === null || options === void 0 ? void 0 : options.withClauseStyle) !== null && _j !== void 0 ? _j : 'standard';
52
- this.commentStyle = (_k = options === null || options === void 0 ? void 0 : options.commentStyle) !== null && _k !== void 0 ? _k : 'block';
53
- this.parenthesesOneLine = (_l = options === null || options === void 0 ? void 0 : options.parenthesesOneLine) !== null && _l !== void 0 ? _l : false;
54
- this.betweenOneLine = (_m = options === null || options === void 0 ? void 0 : options.betweenOneLine) !== null && _m !== void 0 ? _m : false;
55
- this.valuesOneLine = (_o = options === null || options === void 0 ? void 0 : options.valuesOneLine) !== null && _o !== void 0 ? _o : false;
56
- this.joinOneLine = (_p = options === null || options === void 0 ? void 0 : options.joinOneLine) !== null && _p !== void 0 ? _p : false;
57
- this.caseOneLine = (_q = options === null || options === void 0 ? void 0 : options.caseOneLine) !== null && _q !== void 0 ? _q : false;
58
- this.subqueryOneLine = (_r = options === null || options === void 0 ? void 0 : options.subqueryOneLine) !== null && _r !== void 0 ? _r : false;
59
- this.indentNestedParentheses = (_s = options === null || options === void 0 ? void 0 : options.indentNestedParentheses) !== null && _s !== void 0 ? _s : false;
56
+ this.commentExportMode = this.resolveCommentExportMode(options === null || options === void 0 ? void 0 : options.exportComment);
57
+ this.withClauseStyle = (_h = options === null || options === void 0 ? void 0 : options.withClauseStyle) !== null && _h !== void 0 ? _h : 'standard';
58
+ this.commentStyle = (_j = options === null || options === void 0 ? void 0 : options.commentStyle) !== null && _j !== void 0 ? _j : 'block';
59
+ this.parenthesesOneLine = (_k = options === null || options === void 0 ? void 0 : options.parenthesesOneLine) !== null && _k !== void 0 ? _k : false;
60
+ this.betweenOneLine = (_l = options === null || options === void 0 ? void 0 : options.betweenOneLine) !== null && _l !== void 0 ? _l : false;
61
+ this.valuesOneLine = (_m = options === null || options === void 0 ? void 0 : options.valuesOneLine) !== null && _m !== void 0 ? _m : false;
62
+ this.joinOneLine = (_o = options === null || options === void 0 ? void 0 : options.joinOneLine) !== null && _o !== void 0 ? _o : false;
63
+ this.caseOneLine = (_p = options === null || options === void 0 ? void 0 : options.caseOneLine) !== null && _p !== void 0 ? _p : false;
64
+ this.subqueryOneLine = (_q = options === null || options === void 0 ? void 0 : options.subqueryOneLine) !== null && _q !== void 0 ? _q : false;
65
+ this.indentNestedParentheses = (_r = options === null || options === void 0 ? void 0 : options.indentNestedParentheses) !== null && _r !== void 0 ? _r : false;
66
+ this.insertColumnsOneLine = (_s = options === null || options === void 0 ? void 0 : options.insertColumnsOneLine) !== null && _s !== void 0 ? _s : false;
67
+ this.whenOneLine = (_t = options === null || options === void 0 ? void 0 : options.whenOneLine) !== null && _t !== void 0 ? _t : false;
68
+ const onelineOptions = {
69
+ parenthesesOneLine: this.parenthesesOneLine,
70
+ betweenOneLine: this.betweenOneLine,
71
+ valuesOneLine: this.valuesOneLine,
72
+ joinOneLine: this.joinOneLine,
73
+ caseOneLine: this.caseOneLine,
74
+ subqueryOneLine: this.subqueryOneLine,
75
+ insertColumnsOneLine: this.insertColumnsOneLine,
76
+ withClauseStyle: this.withClauseStyle,
77
+ };
78
+ this.onelineHelper = new OnelineFormattingHelper(onelineOptions);
60
79
  this.linePrinter = new LinePrinter(this.indentChar, this.indentSize, this.newline, this.commaBreak);
61
80
  // Initialize
62
- this.indentIncrementContainers = new Set((_t = options === null || options === void 0 ? void 0 : options.indentIncrementContainerTypes) !== null && _t !== void 0 ? _t : [
81
+ this.indentIncrementContainers = new Set((_u = options === null || options === void 0 ? void 0 : options.indentIncrementContainerTypes) !== null && _u !== void 0 ? _u : [
63
82
  SqlPrintTokenContainerType.SelectClause,
64
83
  SqlPrintTokenContainerType.FromClause,
65
84
  SqlPrintTokenContainerType.WhereClause,
@@ -79,7 +98,11 @@ export class SqlPrinter {
79
98
  SqlPrintTokenContainerType.CaseThenValue,
80
99
  SqlPrintTokenContainerType.ElseClause,
81
100
  SqlPrintTokenContainerType.CaseElseValue,
82
- SqlPrintTokenContainerType.SimpleSelectQuery
101
+ SqlPrintTokenContainerType.SimpleSelectQuery,
102
+ SqlPrintTokenContainerType.CreateTableDefinition,
103
+ SqlPrintTokenContainerType.AlterTableStatement,
104
+ SqlPrintTokenContainerType.IndexColumnList,
105
+ SqlPrintTokenContainerType.SetClause
83
106
  // Note: CommentBlock is intentionally excluded from indentIncrementContainers
84
107
  // because it serves as a grouping mechanism without affecting indentation.
85
108
  // CaseExpression, SwitchCaseArgument, CaseKeyValuePair, and ElseClause
@@ -108,7 +131,42 @@ export class SqlPrinter {
108
131
  this.appendToken(token, level, undefined, 0, false);
109
132
  return this.linePrinter.print();
110
133
  }
111
- appendToken(token, level, parentContainerType, caseContextDepth = 0, indentParentActive = false) {
134
+ // Resolve legacy boolean values into explicit comment export modes.
135
+ resolveCommentExportMode(option) {
136
+ if (option === undefined) {
137
+ return 'none';
138
+ }
139
+ if (option === true) {
140
+ return 'full';
141
+ }
142
+ if (option === false) {
143
+ return 'none';
144
+ }
145
+ return option;
146
+ }
147
+ // Determine whether the current mode allows emitting inline comments.
148
+ rendersInlineComments() {
149
+ return this.commentExportMode === 'full';
150
+ }
151
+ // Decide if a comment block or token should be rendered given its context.
152
+ shouldRenderComment(token, context) {
153
+ if (context === null || context === void 0 ? void 0 : context.forceRender) {
154
+ return this.commentExportMode !== 'none';
155
+ }
156
+ switch (this.commentExportMode) {
157
+ case 'full':
158
+ return true;
159
+ case 'none':
160
+ return false;
161
+ case 'header-only':
162
+ return token.isHeaderComment === true;
163
+ case 'top-header-only':
164
+ return token.isHeaderComment === true && Boolean(context === null || context === void 0 ? void 0 : context.isTopLevelContainer);
165
+ default:
166
+ return false;
167
+ }
168
+ }
169
+ appendToken(token, level, parentContainerType, caseContextDepth = 0, indentParentActive = false, commentContext) {
112
170
  // Track WITH clause context for full-oneline formatting
113
171
  const wasInsideWithClause = this.insideWithClause;
114
172
  if (token.containerType === SqlPrintTokenContainerType.WithClause && this.withClauseStyle === 'full-oneline') {
@@ -117,6 +175,45 @@ export class SqlPrinter {
117
175
  if (this.shouldSkipToken(token)) {
118
176
  return;
119
177
  }
178
+ const containerIsTopLevel = parentContainerType === undefined;
179
+ let leadingCommentCount = 0;
180
+ // Collect leading comment blocks with context so we can respect the export mode.
181
+ const leadingCommentContexts = [];
182
+ if (token.innerTokens && token.innerTokens.length > 0) {
183
+ while (leadingCommentCount < token.innerTokens.length) {
184
+ const leadingCandidate = token.innerTokens[leadingCommentCount];
185
+ if (leadingCandidate.containerType !== SqlPrintTokenContainerType.CommentBlock) {
186
+ break;
187
+ }
188
+ const context = {
189
+ position: 'leading',
190
+ isTopLevelContainer: containerIsTopLevel,
191
+ };
192
+ const shouldRender = this.shouldRenderComment(leadingCandidate, context);
193
+ leadingCommentContexts.push({ token: leadingCandidate, context, shouldRender });
194
+ leadingCommentCount++;
195
+ }
196
+ }
197
+ const hasRenderableLeadingComment = leadingCommentContexts.some(item => item.shouldRender);
198
+ const leadingCommentIndentLevel = hasRenderableLeadingComment
199
+ ? this.getLeadingCommentIndentLevel(parentContainerType, level)
200
+ : null;
201
+ if (hasRenderableLeadingComment
202
+ && !this.isOnelineMode()
203
+ && this.shouldAddNewlineBeforeLeadingComments(parentContainerType)) {
204
+ const currentLine = this.linePrinter.getCurrentLine();
205
+ if (currentLine.text.trim().length > 0) {
206
+ // Align the newline before leading comments with the intended comment indentation.
207
+ this.linePrinter.appendNewline(leadingCommentIndentLevel !== null && leadingCommentIndentLevel !== void 0 ? leadingCommentIndentLevel : level);
208
+ }
209
+ }
210
+ for (const leading of leadingCommentContexts) {
211
+ if (!leading.shouldRender) {
212
+ continue;
213
+ }
214
+ // Keep leading comment processing aligned with its computed indentation level.
215
+ this.appendToken(leading.token, leadingCommentIndentLevel !== null && leadingCommentIndentLevel !== void 0 ? leadingCommentIndentLevel : level, token.containerType, caseContextDepth, indentParentActive, leading.context);
216
+ }
120
217
  if (this.smartCommentBlockBuilder && token.containerType !== SqlPrintTokenContainerType.CommentBlock && token.type !== SqlPrintTokenType.commentNewline) {
121
218
  this.flushSmartCommentBlockBuilder();
122
219
  }
@@ -130,8 +227,17 @@ export class SqlPrinter {
130
227
  return;
131
228
  }
132
229
  }
230
+ // Fallback context applies when the caller did not provide comment metadata.
231
+ const effectiveCommentContext = commentContext !== null && commentContext !== void 0 ? commentContext : {
232
+ position: 'inline',
233
+ isTopLevelContainer: containerIsTopLevel,
234
+ };
133
235
  if (token.containerType === SqlPrintTokenContainerType.CommentBlock) {
134
- this.handleCommentBlockContainer(token, level);
236
+ if (!this.shouldRenderComment(token, effectiveCommentContext)) {
237
+ return;
238
+ }
239
+ const commentLevel = this.getCommentBaseIndentLevel(level, parentContainerType);
240
+ this.handleCommentBlockContainer(token, commentLevel, effectiveCommentContext);
135
241
  return;
136
242
  }
137
243
  const current = this.linePrinter.getCurrentLine();
@@ -146,7 +252,7 @@ export class SqlPrinter {
146
252
  this.handleCommaToken(token, level, parentContainerType);
147
253
  }
148
254
  else if (token.type === SqlPrintTokenType.parenthesis) {
149
- this.handleParenthesisToken(token, level, indentParentActive);
255
+ this.handleParenthesisToken(token, level, indentParentActive, parentContainerType);
150
256
  }
151
257
  else if (token.type === SqlPrintTokenType.operator && token.text.toLowerCase() === 'and') {
152
258
  this.handleAndOperatorToken(token, level, parentContainerType, caseContextDepth);
@@ -154,34 +260,34 @@ export class SqlPrinter {
154
260
  else if (token.type === SqlPrintTokenType.operator && token.text.toLowerCase() === 'or') {
155
261
  this.handleOrOperatorToken(token, level, parentContainerType, caseContextDepth);
156
262
  }
157
- else if (token.containerType === "JoinClause") {
263
+ else if (token.containerType === SqlPrintTokenContainerType.JoinClause) {
158
264
  this.handleJoinClauseToken(token, level);
159
265
  }
160
266
  else if (token.type === SqlPrintTokenType.comment) {
161
- if (this.exportComment) {
162
- this.printCommentToken(token.text, level, parentContainerType);
267
+ if (this.shouldRenderComment(token, effectiveCommentContext)) {
268
+ const commentLevel = this.getCommentBaseIndentLevel(level, parentContainerType);
269
+ this.printCommentToken(token.text, commentLevel, parentContainerType);
163
270
  }
164
271
  }
165
272
  else if (token.type === SqlPrintTokenType.space) {
166
273
  this.handleSpaceToken(token, parentContainerType);
167
274
  }
168
275
  else if (token.type === SqlPrintTokenType.commentNewline) {
169
- this.handleCommentNewlineToken(token, level);
276
+ if (this.whenOneLine && parentContainerType === SqlPrintTokenContainerType.MergeWhenClause) {
277
+ return;
278
+ }
279
+ const commentLevel = this.getCommentBaseIndentLevel(level, parentContainerType);
280
+ this.handleCommentNewlineToken(token, commentLevel);
170
281
  }
171
282
  else if (token.containerType === SqlPrintTokenContainerType.CommonTable && this.withClauseStyle === 'cte-oneline') {
172
283
  this.handleCteOnelineToken(token, level);
173
284
  return; // Return early to avoid processing innerTokens
174
285
  }
175
- else if ((token.containerType === SqlPrintTokenContainerType.ParenExpression && this.parenthesesOneLine && !shouldIndentNested) ||
176
- (token.containerType === SqlPrintTokenContainerType.BetweenExpression && this.betweenOneLine) ||
177
- (token.containerType === SqlPrintTokenContainerType.Values && this.valuesOneLine) ||
178
- (token.containerType === SqlPrintTokenContainerType.JoinOnClause && this.joinOneLine) ||
179
- (token.containerType === SqlPrintTokenContainerType.CaseExpression && this.caseOneLine) ||
180
- (token.containerType === SqlPrintTokenContainerType.InlineQuery && this.subqueryOneLine)) {
286
+ else if (this.shouldFormatContainerAsOneline(token, shouldIndentNested)) {
181
287
  this.handleOnelineToken(token, level);
182
288
  return; // Return early to avoid processing innerTokens
183
289
  }
184
- else {
290
+ else if (!this.tryAppendInsertClauseTokenText(token.text, parentContainerType)) {
185
291
  this.linePrinter.appendText(token.text);
186
292
  }
187
293
  // append keyword tokens(not indented)
@@ -195,6 +301,8 @@ export class SqlPrinter {
195
301
  let increasedIndent = false;
196
302
  const shouldIncreaseIndent = this.indentIncrementContainers.has(token.containerType) || shouldIndentNested;
197
303
  const delayIndentNewline = shouldIndentNested && token.containerType === SqlPrintTokenContainerType.ParenExpression;
304
+ const isAlterTableStatement = token.containerType === SqlPrintTokenContainerType.AlterTableStatement;
305
+ let deferAlterTableIndent = false;
198
306
  if (!this.isOnelineMode() && shouldIncreaseIndent) {
199
307
  if (this.insideWithClause && this.withClauseStyle === 'full-oneline') {
200
308
  // Keep everything on one line for full-oneline WITH clauses.
@@ -204,15 +312,96 @@ export class SqlPrinter {
204
312
  increasedIndent = true;
205
313
  }
206
314
  else if (current.text !== '') {
207
- innerLevel = level + 1;
315
+ if (isAlterTableStatement) {
316
+ // Delay the first line break so ALTER TABLE keeps the table name on the opening line.
317
+ innerLevel = level + 1;
318
+ increasedIndent = true;
319
+ deferAlterTableIndent = true;
320
+ }
321
+ else {
322
+ let targetIndentLevel = level + 1;
323
+ if (token.containerType === SqlPrintTokenContainerType.SetClause &&
324
+ parentContainerType === SqlPrintTokenContainerType.MergeUpdateAction) {
325
+ targetIndentLevel = level + 2;
326
+ }
327
+ if (this.shouldAlignCreateTableSelect(token.containerType, parentContainerType)) {
328
+ innerLevel = level;
329
+ increasedIndent = false;
330
+ this.linePrinter.appendNewline(level);
331
+ }
332
+ else {
333
+ innerLevel = targetIndentLevel;
334
+ increasedIndent = true;
335
+ this.linePrinter.appendNewline(innerLevel);
336
+ }
337
+ }
338
+ }
339
+ else if (token.containerType === SqlPrintTokenContainerType.SetClause) {
340
+ innerLevel = parentContainerType === SqlPrintTokenContainerType.MergeUpdateAction ? level + 2 : level + 1;
208
341
  increasedIndent = true;
209
- this.linePrinter.appendNewline(innerLevel);
342
+ current.level = innerLevel;
210
343
  }
211
344
  }
212
- for (let i = 0; i < token.innerTokens.length; i++) {
345
+ const isMergeWhenClause = this.whenOneLine && token.containerType === SqlPrintTokenContainerType.MergeWhenClause;
346
+ let mergePredicateActive = isMergeWhenClause;
347
+ let alterTableTableRendered = false;
348
+ let alterTableIndentInserted = false;
349
+ for (let i = leadingCommentCount; i < token.innerTokens.length; i++) {
213
350
  const child = token.innerTokens[i];
351
+ const nextChild = token.innerTokens[i + 1];
352
+ const previousEntry = this.findPreviousSignificantToken(token.innerTokens, i);
353
+ const previousChild = previousEntry === null || previousEntry === void 0 ? void 0 : previousEntry.token;
354
+ const priorEntry = previousEntry ? this.findPreviousSignificantToken(token.innerTokens, previousEntry.index) : undefined;
355
+ const priorChild = priorEntry === null || priorEntry === void 0 ? void 0 : priorEntry.token;
356
+ const childIsAction = this.isMergeActionContainer(child);
357
+ const nextIsAction = this.isMergeActionContainer(nextChild);
358
+ const inMergePredicate = mergePredicateActive && !childIsAction;
359
+ if (isAlterTableStatement) {
360
+ if (child.containerType === SqlPrintTokenContainerType.QualifiedName) {
361
+ // Track when the table name has been printed so we can defer indentation until after it.
362
+ alterTableTableRendered = true;
363
+ }
364
+ else if (deferAlterTableIndent && alterTableTableRendered && !alterTableIndentInserted) {
365
+ if (!this.isOnelineMode()) {
366
+ this.linePrinter.appendNewline(innerLevel);
367
+ }
368
+ alterTableIndentInserted = true;
369
+ deferAlterTableIndent = false;
370
+ if (!this.isOnelineMode() && child.type === SqlPrintTokenType.space) {
371
+ // Drop the space token because we already emitted a newline.
372
+ continue;
373
+ }
374
+ }
375
+ }
376
+ if (child.type === SqlPrintTokenType.space) {
377
+ if (this.shouldConvertSpaceToClauseBreak(token.containerType, nextChild)) {
378
+ if (!this.isOnelineMode()) {
379
+ // Use a dedicated indent resolver so clause breaks can shift indentation for nested blocks.
380
+ const clauseBreakIndent = this.getClauseBreakIndentLevel(token.containerType, innerLevel);
381
+ this.linePrinter.appendNewline(clauseBreakIndent);
382
+ }
383
+ if (isMergeWhenClause && nextIsAction) {
384
+ mergePredicateActive = false;
385
+ }
386
+ continue;
387
+ }
388
+ this.handleSpaceToken(child, token.containerType, nextChild, previousChild, priorChild);
389
+ continue;
390
+ }
214
391
  const childIndentParentActive = token.containerType === SqlPrintTokenContainerType.ParenExpression ? shouldIndentNested : indentParentActive;
215
- this.appendToken(child, innerLevel, token.containerType, nextCaseContextDepth, childIndentParentActive);
392
+ if (inMergePredicate) {
393
+ this.mergeWhenPredicateDepth++;
394
+ }
395
+ const childCommentContext = child.containerType === SqlPrintTokenContainerType.CommentBlock
396
+ ? { position: 'inline', isTopLevelContainer: containerIsTopLevel }
397
+ : undefined;
398
+ this.appendToken(child, innerLevel, token.containerType, nextCaseContextDepth, childIndentParentActive, childCommentContext);
399
+ if (inMergePredicate) {
400
+ this.mergeWhenPredicateDepth--;
401
+ }
402
+ if (childIsAction && isMergeWhenClause) {
403
+ mergePredicateActive = false;
404
+ }
216
405
  }
217
406
  if (this.smartCommentBlockBuilder && this.smartCommentBlockBuilder.mode === 'line') {
218
407
  this.flushSmartCommentBlockBuilder();
@@ -265,11 +454,13 @@ export class SqlPrinter {
265
454
  }
266
455
  handleKeywordToken(token, level, parentContainerType, caseContextDepth = 0) {
267
456
  const lower = token.text.toLowerCase();
268
- if (lower === 'and' && this.andBreak !== 'none') {
457
+ if (lower === 'and' &&
458
+ (this.andBreak !== 'none' || (this.whenOneLine && parentContainerType === SqlPrintTokenContainerType.MergeWhenClause))) {
269
459
  this.handleAndOperatorToken(token, level, parentContainerType, caseContextDepth);
270
460
  return;
271
461
  }
272
- else if (lower === 'or' && this.orBreak !== 'none') {
462
+ else if (lower === 'or' &&
463
+ (this.orBreak !== 'none' || (this.whenOneLine && parentContainerType === SqlPrintTokenContainerType.MergeWhenClause))) {
273
464
  this.handleOrOperatorToken(token, level, parentContainerType, caseContextDepth);
274
465
  return;
275
466
  }
@@ -278,18 +469,50 @@ export class SqlPrinter {
278
469
  this.linePrinter.appendText(text);
279
470
  return;
280
471
  }
472
+ this.ensureSpaceBeforeKeyword();
281
473
  this.linePrinter.appendText(text);
282
474
  }
475
+ ensureSpaceBeforeKeyword() {
476
+ const currentLine = this.linePrinter.getCurrentLine();
477
+ if (currentLine.text === '') {
478
+ return;
479
+ }
480
+ const lastChar = currentLine.text[currentLine.text.length - 1];
481
+ if (lastChar === '(') {
482
+ return;
483
+ }
484
+ this.ensureTrailingSpace();
485
+ }
486
+ ensureTrailingSpace() {
487
+ const currentLine = this.linePrinter.getCurrentLine();
488
+ if (currentLine.text === '') {
489
+ return;
490
+ }
491
+ if (!currentLine.text.endsWith(' ')) {
492
+ currentLine.text += ' ';
493
+ }
494
+ currentLine.text = currentLine.text.replace(/\s+$/, ' ');
495
+ }
496
+ /**
497
+ * Normalizes INSERT column list token text when one-line formatting is active.
498
+ */
499
+ tryAppendInsertClauseTokenText(text, parentContainerType) {
500
+ const currentLineText = this.linePrinter.getCurrentLine().text;
501
+ const result = this.onelineHelper.formatInsertClauseToken(text, parentContainerType, currentLineText, () => this.ensureTrailingSpace());
502
+ if (!result.handled) {
503
+ return false;
504
+ }
505
+ if (result.text) {
506
+ this.linePrinter.appendText(result.text);
507
+ }
508
+ return true;
509
+ }
283
510
  handleCommaToken(token, level, parentContainerType) {
284
511
  const text = token.text;
285
512
  const isWithinWithClause = parentContainerType === SqlPrintTokenContainerType.WithClause;
286
- const isWithinValuesClause = parentContainerType === SqlPrintTokenContainerType.Values;
287
- let effectiveCommaBreak = this.commaBreak;
288
- if (isWithinWithClause) {
289
- effectiveCommaBreak = this.cteCommaBreak;
290
- }
291
- else if (isWithinValuesClause) {
292
- effectiveCommaBreak = this.valuesCommaBreak;
513
+ let effectiveCommaBreak = this.onelineHelper.resolveCommaBreak(parentContainerType, this.commaBreak, this.cteCommaBreak, this.valuesCommaBreak);
514
+ if (parentContainerType === SqlPrintTokenContainerType.SetClause) {
515
+ effectiveCommaBreak = 'before';
293
516
  }
294
517
  // Skip comma newlines when inside WITH clause with full-oneline style
295
518
  if (this.insideWithClause && this.withClauseStyle === 'full-oneline') {
@@ -307,6 +530,14 @@ export class SqlPrinter {
307
530
  }
308
531
  if (!(this.insideWithClause && this.withClauseStyle === 'full-oneline')) {
309
532
  this.linePrinter.appendNewline(level);
533
+ if (this.newline === ' ') {
534
+ // Remove the spacer introduced by space newlines so commas attach directly to the preceding token.
535
+ this.linePrinter.trimTrailingWhitespaceFromPreviousLine();
536
+ }
537
+ if (parentContainerType === SqlPrintTokenContainerType.InsertClause) {
538
+ // Align comma-prefixed column entries under the INSERT column indentation.
539
+ this.linePrinter.getCurrentLine().level = level + 1;
540
+ }
310
541
  }
311
542
  this.linePrinter.appendText(text);
312
543
  if (previousCommaBreak !== 'before') {
@@ -335,6 +566,9 @@ export class SqlPrinter {
335
566
  this.linePrinter.commaBreak = 'none';
336
567
  }
337
568
  this.linePrinter.appendText(text);
569
+ if (this.onelineHelper.isInsertClauseOneline(parentContainerType)) {
570
+ this.ensureTrailingSpace();
571
+ }
338
572
  if (previousCommaBreak !== 'none') {
339
573
  this.linePrinter.commaBreak = previousCommaBreak;
340
574
  }
@@ -349,6 +583,11 @@ export class SqlPrinter {
349
583
  this.linePrinter.appendText(text);
350
584
  return;
351
585
  }
586
+ if (this.whenOneLine &&
587
+ (parentContainerType === SqlPrintTokenContainerType.MergeWhenClause || this.mergeWhenPredicateDepth > 0)) {
588
+ this.linePrinter.appendText(text);
589
+ return;
590
+ }
352
591
  if (this.andBreak === 'before') {
353
592
  // Skip newline when inside WITH clause with full-oneline style
354
593
  if (!(this.insideWithClause && this.withClauseStyle === 'full-oneline')) {
@@ -367,20 +606,32 @@ export class SqlPrinter {
367
606
  this.linePrinter.appendText(text);
368
607
  }
369
608
  }
370
- handleParenthesisToken(token, level, indentParentActive) {
609
+ handleParenthesisToken(token, level, indentParentActive, parentContainerType) {
371
610
  if (token.text === '(') {
372
611
  this.linePrinter.appendText(token.text);
373
- if (indentParentActive && !this.isOnelineMode()) {
374
- if (!(this.insideWithClause && this.withClauseStyle === 'full-oneline')) {
612
+ if ((parentContainerType === SqlPrintTokenContainerType.InsertClause ||
613
+ parentContainerType === SqlPrintTokenContainerType.MergeInsertAction) &&
614
+ this.insertColumnsOneLine) {
615
+ return;
616
+ }
617
+ if (!this.isOnelineMode()) {
618
+ if (this.shouldBreakAfterOpeningParen(parentContainerType)) {
619
+ this.linePrinter.appendNewline(level + 1);
620
+ }
621
+ else if (indentParentActive && !(this.insideWithClause && this.withClauseStyle === 'full-oneline')) {
375
622
  this.linePrinter.appendNewline(level);
376
623
  }
377
624
  }
378
625
  return;
379
626
  }
380
- if (token.text === ')' && indentParentActive && !this.isOnelineMode()) {
381
- // Align closing parenthesis with the outer indentation level when nested groups expand.
382
- const closingLevel = Math.max(level - 1, 0);
383
- if (!(this.insideWithClause && this.withClauseStyle === 'full-oneline')) {
627
+ if (token.text === ')' && !this.isOnelineMode()) {
628
+ if (this.shouldBreakBeforeClosingParen(parentContainerType)) {
629
+ this.linePrinter.appendNewline(Math.max(level, 0));
630
+ this.linePrinter.appendText(token.text);
631
+ return;
632
+ }
633
+ if (indentParentActive && !(this.insideWithClause && this.withClauseStyle === 'full-oneline')) {
634
+ const closingLevel = Math.max(level - 1, 0);
384
635
  this.linePrinter.appendNewline(closingLevel);
385
636
  }
386
637
  }
@@ -393,6 +644,11 @@ export class SqlPrinter {
393
644
  this.linePrinter.appendText(text);
394
645
  return;
395
646
  }
647
+ if (this.whenOneLine &&
648
+ (parentContainerType === SqlPrintTokenContainerType.MergeWhenClause || this.mergeWhenPredicateDepth > 0)) {
649
+ this.linePrinter.appendText(text);
650
+ return;
651
+ }
396
652
  if (this.orBreak === 'before') {
397
653
  // Insert a newline before OR unless WITH full-oneline mode suppresses breaks.
398
654
  if (!(this.insideWithClause && this.withClauseStyle === 'full-oneline')) {
@@ -442,37 +698,140 @@ export class SqlPrinter {
442
698
  }
443
699
  handleJoinClauseToken(token, level) {
444
700
  const text = this.applyKeywordCase(token.text);
445
- // before join clause, add newline (skip when inside WITH clause with full-oneline style)
446
- if (!(this.insideWithClause && this.withClauseStyle === 'full-oneline')) {
701
+ // before join clause, add newline when multiline formatting is allowed
702
+ if (this.onelineHelper.shouldInsertJoinNewline(this.insideWithClause)) {
447
703
  this.linePrinter.appendNewline(level);
448
704
  }
449
705
  this.linePrinter.appendText(text);
450
706
  }
707
+ /**
708
+ * Decides whether the current container should collapse into a single line.
709
+ */
710
+ shouldFormatContainerAsOneline(token, shouldIndentNested) {
711
+ return this.onelineHelper.shouldFormatContainer(token, shouldIndentNested);
712
+ }
713
+ /**
714
+ * Detects an INSERT column list that must stay on a single line.
715
+ */
716
+ isInsertClauseOneline(parentContainerType) {
717
+ return this.onelineHelper.isInsertClauseOneline(parentContainerType);
718
+ }
451
719
  /**
452
720
  * Handles space tokens with context-aware filtering.
453
721
  * Skips spaces in CommentBlocks when in specific CTE modes to prevent duplication.
454
722
  */
455
- handleSpaceToken(token, parentContainerType) {
723
+ handleSpaceToken(token, parentContainerType, nextToken, previousToken, priorToken) {
456
724
  if (this.smartCommentBlockBuilder && this.smartCommentBlockBuilder.mode === 'line') {
457
725
  this.flushSmartCommentBlockBuilder();
458
726
  }
459
- if (this.shouldSkipCommentBlockSpace(parentContainerType)) {
727
+ const currentLineText = this.linePrinter.getCurrentLine().text;
728
+ if (this.onelineHelper.shouldSkipInsertClauseSpace(parentContainerType, nextToken, currentLineText)) {
729
+ return;
730
+ }
731
+ if (this.onelineHelper.shouldSkipCommentBlockSpace(parentContainerType, this.insideWithClause)) {
460
732
  const currentLine = this.linePrinter.getCurrentLine();
461
733
  if (currentLine.text !== '' && !currentLine.text.endsWith(' ')) {
462
734
  this.linePrinter.appendText(' ');
463
735
  }
464
736
  return;
465
737
  }
738
+ // Skip redundant spaces before structural parentheses in CREATE TABLE DDL.
739
+ if (this.shouldSkipSpaceBeforeParenthesis(parentContainerType, nextToken, previousToken, priorToken)) {
740
+ return;
741
+ }
466
742
  this.linePrinter.appendText(token.text);
467
743
  }
468
- /**
469
- * Determines whether to skip space tokens in CommentBlocks.
470
- * Prevents duplicate spacing in CTE full-oneline mode only.
471
- */
472
- shouldSkipCommentBlockSpace(parentContainerType) {
473
- return parentContainerType === SqlPrintTokenContainerType.CommentBlock &&
474
- this.insideWithClause &&
475
- this.withClauseStyle === 'full-oneline';
744
+ findPreviousSignificantToken(tokens, index) {
745
+ for (let i = index - 1; i >= 0; i--) {
746
+ const candidate = tokens[i];
747
+ if (candidate.type === SqlPrintTokenType.space || candidate.type === SqlPrintTokenType.commentNewline) {
748
+ continue;
749
+ }
750
+ if (candidate.type === SqlPrintTokenType.comment && !this.rendersInlineComments()) {
751
+ continue;
752
+ }
753
+ return { token: candidate, index: i };
754
+ }
755
+ return undefined;
756
+ }
757
+ shouldSkipSpaceBeforeParenthesis(parentContainerType, nextToken, previousToken, priorToken) {
758
+ if (!nextToken || nextToken.type !== SqlPrintTokenType.parenthesis || nextToken.text !== '(') {
759
+ return false;
760
+ }
761
+ if (!parentContainerType || !this.isCreateTableSpacingContext(parentContainerType)) {
762
+ return false;
763
+ }
764
+ if (!previousToken) {
765
+ return false;
766
+ }
767
+ if (this.isCreateTableNameToken(previousToken, parentContainerType)) {
768
+ return true;
769
+ }
770
+ if (this.isCreateTableConstraintKeyword(previousToken, parentContainerType)) {
771
+ return true;
772
+ }
773
+ if (priorToken && this.isCreateTableConstraintKeyword(priorToken, parentContainerType)) {
774
+ if (this.isIdentifierAttachedToConstraint(previousToken, priorToken, parentContainerType)) {
775
+ return true;
776
+ }
777
+ }
778
+ return false;
779
+ }
780
+ shouldAlignCreateTableSelect(containerType, parentContainerType) {
781
+ return containerType === SqlPrintTokenContainerType.SimpleSelectQuery &&
782
+ parentContainerType === SqlPrintTokenContainerType.CreateTableQuery;
783
+ }
784
+ isCreateTableSpacingContext(parentContainerType) {
785
+ switch (parentContainerType) {
786
+ case SqlPrintTokenContainerType.CreateTableQuery:
787
+ case SqlPrintTokenContainerType.CreateTableDefinition:
788
+ case SqlPrintTokenContainerType.TableConstraintDefinition:
789
+ case SqlPrintTokenContainerType.ColumnConstraintDefinition:
790
+ case SqlPrintTokenContainerType.ReferenceDefinition:
791
+ return true;
792
+ default:
793
+ return false;
794
+ }
795
+ }
796
+ isCreateTableNameToken(previousToken, parentContainerType) {
797
+ if (parentContainerType !== SqlPrintTokenContainerType.CreateTableQuery) {
798
+ return false;
799
+ }
800
+ return previousToken.containerType === SqlPrintTokenContainerType.QualifiedName;
801
+ }
802
+ isCreateTableConstraintKeyword(token, parentContainerType) {
803
+ if (token.type !== SqlPrintTokenType.keyword) {
804
+ return false;
805
+ }
806
+ const text = token.text.toLowerCase();
807
+ if (parentContainerType === SqlPrintTokenContainerType.ReferenceDefinition) {
808
+ return CREATE_TABLE_PAREN_KEYWORDS_WITH_IDENTIFIER.has(text);
809
+ }
810
+ if (CREATE_TABLE_SINGLE_PAREN_KEYWORDS.has(text)) {
811
+ return true;
812
+ }
813
+ if (CREATE_TABLE_MULTI_PAREN_KEYWORDS.has(text)) {
814
+ return true;
815
+ }
816
+ return false;
817
+ }
818
+ isIdentifierAttachedToConstraint(token, keywordToken, parentContainerType) {
819
+ if (!token) {
820
+ return false;
821
+ }
822
+ if (parentContainerType === SqlPrintTokenContainerType.ReferenceDefinition) {
823
+ return token.containerType === SqlPrintTokenContainerType.QualifiedName &&
824
+ CREATE_TABLE_PAREN_KEYWORDS_WITH_IDENTIFIER.has(keywordToken.text.toLowerCase());
825
+ }
826
+ if (parentContainerType === SqlPrintTokenContainerType.TableConstraintDefinition ||
827
+ parentContainerType === SqlPrintTokenContainerType.ColumnConstraintDefinition) {
828
+ const normalized = keywordToken.text.toLowerCase();
829
+ if (CREATE_TABLE_SINGLE_PAREN_KEYWORDS.has(normalized) ||
830
+ CREATE_TABLE_MULTI_PAREN_KEYWORDS.has(normalized)) {
831
+ return token.containerType === SqlPrintTokenContainerType.IdentifierString;
832
+ }
833
+ }
834
+ return false;
476
835
  }
477
836
  printCommentToken(text, level, parentContainerType) {
478
837
  const trimmed = text.trim();
@@ -495,11 +854,12 @@ export class SqlPrinter {
495
854
  const lineText = content ? `-- ${content}` : '--';
496
855
  if (parentContainerType === SqlPrintTokenContainerType.CommentBlock) {
497
856
  this.linePrinter.appendText(lineText);
498
- this.pendingLineCommentBreak = level;
857
+ this.pendingLineCommentBreak = this.resolveCommentIndentLevel(level, parentContainerType);
499
858
  }
500
859
  else {
501
860
  this.linePrinter.appendText(lineText);
502
- this.linePrinter.appendNewline(level);
861
+ const effectiveLevel = this.resolveCommentIndentLevel(level, parentContainerType);
862
+ this.linePrinter.appendNewline(effectiveLevel);
503
863
  }
504
864
  }
505
865
  }
@@ -520,10 +880,11 @@ export class SqlPrinter {
520
880
  }
521
881
  if (trimmed.startsWith('--')) {
522
882
  if (parentContainerType === SqlPrintTokenContainerType.CommentBlock) {
523
- this.pendingLineCommentBreak = level;
883
+ this.pendingLineCommentBreak = this.resolveCommentIndentLevel(level, parentContainerType);
524
884
  }
525
885
  else {
526
- this.linePrinter.appendNewline(level);
886
+ const effectiveLevel = this.resolveCommentIndentLevel(level, parentContainerType);
887
+ this.linePrinter.appendNewline(effectiveLevel);
527
888
  }
528
889
  }
529
890
  }
@@ -566,11 +927,8 @@ export class SqlPrinter {
566
927
  this.flushSmartCommentBlockBuilder();
567
928
  return false;
568
929
  }
569
- handleCommentBlockContainer(token, level) {
930
+ handleCommentBlockContainer(token, level, context) {
570
931
  var _a;
571
- if (!this.exportComment) {
572
- return;
573
- }
574
932
  if (this.commentStyle !== 'smart') {
575
933
  const rawLines = this.extractRawCommentBlockLines(token);
576
934
  if (rawLines.length > 0) {
@@ -580,7 +938,13 @@ export class SqlPrinter {
580
938
  return;
581
939
  }
582
940
  for (const child of token.innerTokens) {
583
- this.appendToken(child, level, token.containerType, 0, false);
941
+ // Force inner comment tokens to render once the block is approved.
942
+ const childContext = {
943
+ position: context.position,
944
+ isTopLevelContainer: context.isTopLevelContainer,
945
+ forceRender: true,
946
+ };
947
+ this.appendToken(child, level, token.containerType, 0, false, childContext);
584
948
  }
585
949
  return;
586
950
  }
@@ -642,7 +1006,8 @@ export class SqlPrinter {
642
1006
  }
643
1007
  const { lines, level, mode } = this.smartCommentBlockBuilder;
644
1008
  if (mode === 'line') {
645
- if (lines.length > 1) {
1009
+ const meaningfulLineCount = lines.filter(line => line.trim() !== '').length;
1010
+ if (meaningfulLineCount > 1) {
646
1011
  const blockText = this.buildBlockComment(lines, level);
647
1012
  this.linePrinter.appendText(blockText);
648
1013
  }
@@ -805,6 +1170,19 @@ export class SqlPrinter {
805
1170
  .replace(/\/\*/g, '\\/\\*')
806
1171
  .replace(/\*\//g, '*\\/');
807
1172
  }
1173
+ getCommentBaseIndentLevel(level, parentContainerType) {
1174
+ if (!parentContainerType) {
1175
+ return level;
1176
+ }
1177
+ const clauseAlignedLevel = this.getClauseBreakIndentLevel(parentContainerType, level);
1178
+ return Math.max(level, clauseAlignedLevel);
1179
+ }
1180
+ resolveCommentIndentLevel(level, parentContainerType) {
1181
+ var _a;
1182
+ const baseLevel = this.getCommentBaseIndentLevel(level, parentContainerType);
1183
+ const currentLevel = (_a = this.linePrinter.getCurrentLine().level) !== null && _a !== void 0 ? _a : baseLevel;
1184
+ return Math.max(baseLevel, currentLevel);
1185
+ }
808
1186
  /**
809
1187
  * Handles commentNewline tokens with conditional newline behavior.
810
1188
  * In multiline mode (newline !== ' '), adds a newline after comments.
@@ -835,6 +1213,39 @@ export class SqlPrinter {
835
1213
  return (this.insideWithClause && this.withClauseStyle === 'full-oneline') ||
836
1214
  this.withClauseStyle === 'cte-oneline';
837
1215
  }
1216
+ shouldAddNewlineBeforeLeadingComments(parentType) {
1217
+ if (!parentType) {
1218
+ return false;
1219
+ }
1220
+ if (parentType === SqlPrintTokenContainerType.TupleExpression) {
1221
+ return true;
1222
+ }
1223
+ if (parentType === SqlPrintTokenContainerType.InsertClause ||
1224
+ parentType === SqlPrintTokenContainerType.MergeInsertAction) {
1225
+ return !this.insertColumnsOneLine;
1226
+ }
1227
+ if (parentType === SqlPrintTokenContainerType.SetClause) {
1228
+ return true;
1229
+ }
1230
+ if (parentType === SqlPrintTokenContainerType.SelectClause) {
1231
+ return true;
1232
+ }
1233
+ return false;
1234
+ }
1235
+ getLeadingCommentIndentLevel(parentType, currentLevel) {
1236
+ if (parentType === SqlPrintTokenContainerType.TupleExpression) {
1237
+ return currentLevel + 1;
1238
+ }
1239
+ if (parentType === SqlPrintTokenContainerType.InsertClause ||
1240
+ parentType === SqlPrintTokenContainerType.MergeInsertAction ||
1241
+ parentType === SqlPrintTokenContainerType.SelectClause) {
1242
+ return currentLevel + 1;
1243
+ }
1244
+ if (parentType === SqlPrintTokenContainerType.SetClause) {
1245
+ return currentLevel + 1;
1246
+ }
1247
+ return currentLevel;
1248
+ }
838
1249
  /**
839
1250
  * Determines if the printer is in oneliner mode.
840
1251
  * Oneliner mode uses single spaces instead of actual newlines.
@@ -867,9 +1278,10 @@ export class SqlPrinter {
867
1278
  andBreak: this.andBreak,
868
1279
  orBreak: this.orBreak,
869
1280
  keywordCase: this.keywordCase,
870
- exportComment: false,
1281
+ exportComment: 'none',
871
1282
  withClauseStyle: 'standard', // Prevent recursive processing
872
1283
  indentNestedParentheses: false,
1284
+ insertColumnsOneLine: this.insertColumnsOneLine,
873
1285
  });
874
1286
  }
875
1287
  /**
@@ -882,6 +1294,117 @@ export class SqlPrinter {
882
1294
  const cleanedResult = this.cleanDuplicateSpaces(onelineResult);
883
1295
  this.linePrinter.appendText(cleanedResult);
884
1296
  }
1297
+ getClauseBreakIndentLevel(parentType, level) {
1298
+ if (!parentType) {
1299
+ return level;
1300
+ }
1301
+ switch (parentType) {
1302
+ case SqlPrintTokenContainerType.MergeWhenClause:
1303
+ // Actions under WHEN clauses should be indented one level deeper than the WHEN line.
1304
+ return level + 1;
1305
+ case SqlPrintTokenContainerType.MergeUpdateAction:
1306
+ case SqlPrintTokenContainerType.MergeDeleteAction:
1307
+ case SqlPrintTokenContainerType.MergeInsertAction:
1308
+ // Keep MERGE actions and their follow-up keywords (e.g., VALUES, WHERE) aligned with the action keyword.
1309
+ return level + 1;
1310
+ default:
1311
+ return level;
1312
+ }
1313
+ }
1314
+ isMergeActionContainer(token) {
1315
+ if (!token) {
1316
+ return false;
1317
+ }
1318
+ switch (token.containerType) {
1319
+ case SqlPrintTokenContainerType.MergeUpdateAction:
1320
+ case SqlPrintTokenContainerType.MergeDeleteAction:
1321
+ case SqlPrintTokenContainerType.MergeInsertAction:
1322
+ case SqlPrintTokenContainerType.MergeDoNothingAction:
1323
+ return true;
1324
+ default:
1325
+ return false;
1326
+ }
1327
+ }
1328
+ shouldBreakAfterOpeningParen(parentType) {
1329
+ if (!parentType) {
1330
+ return false;
1331
+ }
1332
+ if (parentType === SqlPrintTokenContainerType.InsertClause ||
1333
+ parentType === SqlPrintTokenContainerType.MergeInsertAction) {
1334
+ return !this.isInsertClauseOneline(parentType);
1335
+ }
1336
+ return false;
1337
+ }
1338
+ shouldBreakBeforeClosingParen(parentType) {
1339
+ if (!parentType) {
1340
+ return false;
1341
+ }
1342
+ if (parentType === SqlPrintTokenContainerType.InsertClause ||
1343
+ parentType === SqlPrintTokenContainerType.MergeInsertAction) {
1344
+ return !this.isInsertClauseOneline(parentType);
1345
+ }
1346
+ return false;
1347
+ }
1348
+ shouldConvertSpaceToClauseBreak(parentType, nextToken) {
1349
+ if (!parentType || !nextToken) {
1350
+ return false;
1351
+ }
1352
+ const nextKeyword = nextToken.type === SqlPrintTokenType.keyword ? nextToken.text.toLowerCase() : null;
1353
+ const nextContainer = nextToken.containerType;
1354
+ if (parentType === SqlPrintTokenContainerType.MergeQuery) {
1355
+ // Break before USING blocks and before each WHEN clause to mirror statement structure.
1356
+ if (nextKeyword === 'using') {
1357
+ return true;
1358
+ }
1359
+ if (nextContainer === SqlPrintTokenContainerType.MergeWhenClause) {
1360
+ return true;
1361
+ }
1362
+ }
1363
+ if (parentType === SqlPrintTokenContainerType.MergeWhenClause) {
1364
+ // Force the action to start on the next line with additional indentation.
1365
+ if (nextContainer === SqlPrintTokenContainerType.MergeUpdateAction ||
1366
+ nextContainer === SqlPrintTokenContainerType.MergeDeleteAction ||
1367
+ nextContainer === SqlPrintTokenContainerType.MergeInsertAction ||
1368
+ nextContainer === SqlPrintTokenContainerType.MergeDoNothingAction) {
1369
+ return true;
1370
+ }
1371
+ }
1372
+ if (parentType === SqlPrintTokenContainerType.UpdateQuery) {
1373
+ if (nextKeyword === 'set' || nextKeyword === 'from' || nextKeyword === 'where' || nextKeyword === 'returning') {
1374
+ return true;
1375
+ }
1376
+ }
1377
+ if (parentType === SqlPrintTokenContainerType.InsertQuery) {
1378
+ if (nextKeyword === 'returning') {
1379
+ return true;
1380
+ }
1381
+ if (nextKeyword && (nextKeyword.startsWith('select') || nextKeyword.startsWith('values'))) {
1382
+ return true;
1383
+ }
1384
+ if (nextContainer === SqlPrintTokenContainerType.ValuesQuery || nextContainer === SqlPrintTokenContainerType.SimpleSelectQuery) {
1385
+ return true;
1386
+ }
1387
+ if (nextContainer === SqlPrintTokenContainerType.InsertClause) {
1388
+ return true;
1389
+ }
1390
+ }
1391
+ if (parentType === SqlPrintTokenContainerType.DeleteQuery) {
1392
+ if (nextKeyword === 'using' || nextKeyword === 'where' || nextKeyword === 'returning') {
1393
+ return true;
1394
+ }
1395
+ }
1396
+ if (parentType === SqlPrintTokenContainerType.MergeUpdateAction || parentType === SqlPrintTokenContainerType.MergeDeleteAction) {
1397
+ if (nextKeyword === 'where') {
1398
+ return true;
1399
+ }
1400
+ }
1401
+ if (parentType === SqlPrintTokenContainerType.MergeInsertAction) {
1402
+ if (nextKeyword && (nextKeyword.startsWith('values') || nextKeyword === 'default values')) {
1403
+ return true;
1404
+ }
1405
+ }
1406
+ return false;
1407
+ }
885
1408
  /**
886
1409
  * Creates a unified SqlPrinter instance configured for oneline formatting.
887
1410
  * Works for all oneline options: parentheses, BETWEEN, VALUES, JOIN, CASE, subqueries.
@@ -898,7 +1421,8 @@ export class SqlPrinter {
898
1421
  andBreak: 'none', // Disable AND-based line breaks
899
1422
  orBreak: 'none', // Disable OR-based line breaks
900
1423
  keywordCase: this.keywordCase,
901
- exportComment: this.exportComment,
1424
+ exportComment: this.commentExportMode,
1425
+ commentStyle: this.commentStyle,
902
1426
  withClauseStyle: 'standard',
903
1427
  parenthesesOneLine: false, // Prevent recursive processing (avoid infinite loops)
904
1428
  betweenOneLine: false, // Prevent recursive processing (avoid infinite loops)
@@ -907,6 +1431,7 @@ export class SqlPrinter {
907
1431
  caseOneLine: false, // Prevent recursive processing (avoid infinite loops)
908
1432
  subqueryOneLine: false, // Prevent recursive processing (avoid infinite loops)
909
1433
  indentNestedParentheses: false,
1434
+ insertColumnsOneLine: this.insertColumnsOneLine,
910
1435
  });
911
1436
  }
912
1437
  /**