rawsql-ts 0.11.42-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 -13
  2. package/dist/esm/index.js +18 -0
  3. package/dist/esm/index.js.map +1 -1
  4. package/dist/esm/index.min.js +23 -18
  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 +68 -21
  90. package/dist/esm/src/parsers/SqlPrintTokenParser.js +1145 -254
  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 +2 -0
  120. package/dist/esm/src/transformers/LinePrinter.js +34 -1
  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 -3
  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 +63 -10
  132. package/dist/esm/src/transformers/SqlPrinter.js +954 -64
  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 +22 -17
  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 +68 -21
  227. package/dist/src/parsers/SqlPrintTokenParser.js +1143 -252
  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 +2 -0
  257. package/dist/src/transformers/LinePrinter.js +34 -1
  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 -3
  266. package/dist/src/transformers/SqlFormatter.js +20 -6
  267. package/dist/src/transformers/SqlFormatter.js.map +1 -1
  268. package/dist/src/transformers/SqlPrinter.d.ts +63 -10
  269. package/dist/src/transformers/SqlPrinter.js +954 -64
  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,4 +1,4 @@
1
- import { PartitionByClause, OrderByClause, OrderByItem, SelectClause, SelectItem, Distinct, DistinctOn, SortDirection, NullsSortDirection, TableSource, SourceExpression, FromClause, JoinClause, JoinOnClause, JoinUsingClause, FunctionSource, SourceAliasExpression, WhereClause, GroupByClause, HavingClause, SubQuerySource, WindowFrameClause, LimitClause, ForClause, OffsetClause, WindowsClause as WindowClause, CommonTable, WithClause, FetchClause, FetchExpression, InsertClause, UpdateClause, SetClause, ReturningClause, SetClauseItem } from "../models/Clause";
1
+ import { PartitionByClause, OrderByClause, OrderByItem, SelectClause, SelectItem, Distinct, DistinctOn, SortDirection, NullsSortDirection, TableSource, SourceExpression, FromClause, JoinClause, JoinOnClause, JoinUsingClause, FunctionSource, SourceAliasExpression, WhereClause, GroupByClause, HavingClause, SubQuerySource, WindowFrameClause, LimitClause, ForClause, OffsetClause, WindowsClause as WindowClause, CommonTable, WithClause, FetchClause, FetchExpression, InsertClause, UpdateClause, DeleteClause, UsingClause, SetClause, ReturningClause, SetClauseItem } from "../models/Clause";
2
2
  import { HintClause } from "../models/HintClause";
3
3
  import { BinarySelectQuery, SimpleSelectQuery, ValuesQuery } from "../models/SelectQuery";
4
4
  import { SqlPrintToken, SqlPrintTokenType, SqlPrintTokenContainerType } from "../models/SqlPrintToken";
@@ -8,7 +8,10 @@ import { IdentifierDecorator } from "./IdentifierDecorator";
8
8
  import { ParameterDecorator } from "./ParameterDecorator";
9
9
  import { InsertQuery } from "../models/InsertQuery";
10
10
  import { UpdateQuery } from "../models/UpdateQuery";
11
- import { CreateTableQuery } from "../models/CreateTableQuery";
11
+ import { DeleteQuery } from "../models/DeleteQuery";
12
+ import { CreateTableQuery, TableColumnDefinition, ColumnConstraintDefinition, TableConstraintDefinition, ReferenceDefinition } from "../models/CreateTableQuery";
13
+ import { MergeQuery, MergeWhenClause, MergeUpdateAction, MergeDeleteAction, MergeInsertAction, MergeDoNothingAction } from "../models/MergeQuery";
14
+ import { DropTableStatement, DropIndexStatement, CreateIndexStatement, IndexColumnDefinition, AlterTableStatement, AlterTableAddConstraint, AlterTableDropConstraint, AlterTableDropColumn, DropConstraintStatement } from "../models/DDLStatements";
12
15
  export var ParameterStyle;
13
16
  (function (ParameterStyle) {
14
17
  ParameterStyle["Anonymous"] = "anonymous";
@@ -20,36 +23,45 @@ export const PRESETS = {
20
23
  identifierEscape: { start: '`', end: '`' },
21
24
  parameterSymbol: '?',
22
25
  parameterStyle: ParameterStyle.Anonymous,
26
+ constraintStyle: 'mysql',
23
27
  },
24
28
  postgres: {
25
29
  identifierEscape: { start: '"', end: '"' },
26
30
  parameterSymbol: '$',
27
31
  parameterStyle: ParameterStyle.Indexed,
32
+ castStyle: 'postgres',
33
+ constraintStyle: 'postgres',
28
34
  },
29
35
  postgresWithNamedParams: {
30
36
  identifierEscape: { start: '"', end: '"' },
31
37
  parameterSymbol: ':',
32
38
  parameterStyle: ParameterStyle.Named,
39
+ castStyle: 'postgres',
40
+ constraintStyle: 'postgres',
33
41
  },
34
42
  sqlserver: {
35
43
  identifierEscape: { start: '[', end: ']' },
36
44
  parameterSymbol: '@',
37
45
  parameterStyle: ParameterStyle.Named,
46
+ constraintStyle: 'postgres',
38
47
  },
39
48
  sqlite: {
40
49
  identifierEscape: { start: '"', end: '"' },
41
50
  parameterSymbol: ':',
42
51
  parameterStyle: ParameterStyle.Named,
52
+ constraintStyle: 'postgres',
43
53
  },
44
54
  oracle: {
45
55
  identifierEscape: { start: '"', end: '"' },
46
56
  parameterSymbol: ':',
47
57
  parameterStyle: ParameterStyle.Named,
58
+ constraintStyle: 'postgres',
48
59
  },
49
60
  clickhouse: {
50
61
  identifierEscape: { start: '`', end: '`' },
51
62
  parameterSymbol: '?',
52
63
  parameterStyle: ParameterStyle.Anonymous,
64
+ constraintStyle: 'postgres',
53
65
  },
54
66
  firebird: {
55
67
  identifierEscape: { start: '"', end: '"' },
@@ -80,6 +92,7 @@ export const PRESETS = {
80
92
  identifierEscape: { start: '"', end: '"' },
81
93
  parameterSymbol: '$',
82
94
  parameterStyle: ParameterStyle.Indexed,
95
+ castStyle: 'postgres',
83
96
  },
84
97
  athena: {
85
98
  identifierEscape: { start: '"', end: '"' },
@@ -105,6 +118,7 @@ export const PRESETS = {
105
118
  identifierEscape: { start: '"', end: '"' },
106
119
  parameterSymbol: '$',
107
120
  parameterStyle: ParameterStyle.Indexed,
121
+ castStyle: 'postgres',
108
122
  },
109
123
  flinksql: {
110
124
  identifierEscape: { start: '`', end: '`' },
@@ -139,10 +153,10 @@ export class SqlPrintTokenParser {
139
153
  return this._selfHandlingComponentTypes;
140
154
  }
141
155
  constructor(options) {
142
- var _a, _b, _c, _d, _e, _f, _g, _h;
156
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
143
157
  this.handlers = new Map();
144
158
  this.index = 1;
145
- this.commentStyle = 'block';
159
+ this.joinConditionContexts = [];
146
160
  if (options === null || options === void 0 ? void 0 : options.preset) {
147
161
  const preset = options.preset;
148
162
  options = Object.assign(Object.assign({}, preset), options);
@@ -156,7 +170,9 @@ export class SqlPrintTokenParser {
156
170
  start: (_e = (_d = options === null || options === void 0 ? void 0 : options.identifierEscape) === null || _d === void 0 ? void 0 : _d.start) !== null && _e !== void 0 ? _e : '"',
157
171
  end: (_g = (_f = options === null || options === void 0 ? void 0 : options.identifierEscape) === null || _f === void 0 ? void 0 : _f.end) !== null && _g !== void 0 ? _g : '"'
158
172
  });
159
- this.commentStyle = (_h = options === null || options === void 0 ? void 0 : options.commentStyle) !== null && _h !== void 0 ? _h : 'block';
173
+ this.castStyle = (_h = options === null || options === void 0 ? void 0 : options.castStyle) !== null && _h !== void 0 ? _h : 'standard';
174
+ this.constraintStyle = (_j = options === null || options === void 0 ? void 0 : options.constraintStyle) !== null && _j !== void 0 ? _j : 'postgres';
175
+ this.normalizeJoinConditionOrder = (_k = options === null || options === void 0 ? void 0 : options.joinConditionOrderByDeclaration) !== null && _k !== void 0 ? _k : false;
160
176
  this.handlers.set(ValueList.kind, (expr) => this.visitValueList(expr));
161
177
  this.handlers.set(ColumnReference.kind, (expr) => this.visitColumnReference(expr));
162
178
  this.handlers.set(QualifiedName.kind, (expr) => this.visitQualifiedName(expr));
@@ -228,10 +244,32 @@ export class SqlPrintTokenParser {
228
244
  this.handlers.set(InsertClause.kind, (expr) => this.visitInsertClause(expr));
229
245
  this.handlers.set(UpdateQuery.kind, (expr) => this.visitUpdateQuery(expr));
230
246
  this.handlers.set(UpdateClause.kind, (expr) => this.visitUpdateClause(expr));
247
+ this.handlers.set(DeleteQuery.kind, (expr) => this.visitDeleteQuery(expr));
248
+ this.handlers.set(DeleteClause.kind, (expr) => this.visitDeleteClause(expr));
249
+ this.handlers.set(UsingClause.kind, (expr) => this.visitUsingClause(expr));
231
250
  this.handlers.set(SetClause.kind, (expr) => this.visitSetClause(expr));
232
251
  this.handlers.set(SetClauseItem.kind, (expr) => this.visitSetClauseItem(expr));
233
252
  this.handlers.set(ReturningClause.kind, (expr) => this.visitReturningClause(expr));
234
253
  this.handlers.set(CreateTableQuery.kind, (expr) => this.visitCreateTableQuery(expr));
254
+ this.handlers.set(TableColumnDefinition.kind, (expr) => this.visitTableColumnDefinition(expr));
255
+ this.handlers.set(ColumnConstraintDefinition.kind, (expr) => this.visitColumnConstraintDefinition(expr));
256
+ this.handlers.set(TableConstraintDefinition.kind, (expr) => this.visitTableConstraintDefinition(expr));
257
+ this.handlers.set(ReferenceDefinition.kind, (expr) => this.visitReferenceDefinition(expr));
258
+ this.handlers.set(CreateIndexStatement.kind, (expr) => this.visitCreateIndexStatement(expr));
259
+ this.handlers.set(IndexColumnDefinition.kind, (expr) => this.visitIndexColumnDefinition(expr));
260
+ this.handlers.set(DropTableStatement.kind, (expr) => this.visitDropTableStatement(expr));
261
+ this.handlers.set(DropIndexStatement.kind, (expr) => this.visitDropIndexStatement(expr));
262
+ this.handlers.set(AlterTableStatement.kind, (expr) => this.visitAlterTableStatement(expr));
263
+ this.handlers.set(AlterTableAddConstraint.kind, (expr) => this.visitAlterTableAddConstraint(expr));
264
+ this.handlers.set(AlterTableDropConstraint.kind, (expr) => this.visitAlterTableDropConstraint(expr));
265
+ this.handlers.set(AlterTableDropColumn.kind, (expr) => this.visitAlterTableDropColumn(expr));
266
+ this.handlers.set(DropConstraintStatement.kind, (expr) => this.visitDropConstraintStatement(expr));
267
+ this.handlers.set(MergeQuery.kind, (expr) => this.visitMergeQuery(expr));
268
+ this.handlers.set(MergeWhenClause.kind, (expr) => this.visitMergeWhenClause(expr));
269
+ this.handlers.set(MergeUpdateAction.kind, (expr) => this.visitMergeUpdateAction(expr));
270
+ this.handlers.set(MergeDeleteAction.kind, (expr) => this.visitMergeDeleteAction(expr));
271
+ this.handlers.set(MergeInsertAction.kind, (expr) => this.visitMergeInsertAction(expr));
272
+ this.handlers.set(MergeDoNothingAction.kind, (expr) => this.visitMergeDoNothingAction(expr));
235
273
  }
236
274
  /**
237
275
  * Pretty-prints a BinarySelectQuery (e.g., UNION, INTERSECT, EXCEPT).
@@ -247,14 +285,12 @@ export class SqlPrintTokenParser {
247
285
  arg.positionedComments = null;
248
286
  }
249
287
  else if (arg.headerComments && arg.headerComments.length > 0) {
250
- // Fallback to legacy headerComments if no positioned comments
251
- // For smart comment style, treat headerComments as a single multi-line block
252
- if (this.commentStyle === 'smart' && arg.headerComments.length > 1) {
288
+ if (this.shouldMergeHeaderComments(arg.headerComments)) {
253
289
  const mergedHeaderComment = this.createHeaderMultiLineCommentBlock(arg.headerComments);
254
290
  token.innerTokens.push(mergedHeaderComment);
255
291
  }
256
292
  else {
257
- const headerCommentBlocks = this.createCommentBlocks(arg.headerComments);
293
+ const headerCommentBlocks = this.createCommentBlocks(arg.headerComments, true);
258
294
  token.innerTokens.push(...headerCommentBlocks);
259
295
  }
260
296
  token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
@@ -438,14 +474,9 @@ export class SqlPrintTokenParser {
438
474
  const beforeComments = component.getPositionedComments('before');
439
475
  if (beforeComments.length > 0) {
440
476
  const commentBlocks = this.createCommentBlocks(beforeComments);
441
- // Create a single inline sequence: /* comment */ content
442
- const beforeTokens = [];
443
- for (const commentBlock of commentBlocks) {
444
- beforeTokens.push(commentBlock);
445
- beforeTokens.push(new SqlPrintToken(SqlPrintTokenType.space, ' '));
477
+ for (let i = commentBlocks.length - 1; i >= 0; i--) {
478
+ token.innerTokens.unshift(commentBlocks[i]);
446
479
  }
447
- // Insert before the existing content
448
- token.innerTokens.unshift(...beforeTokens);
449
480
  }
450
481
  // Handle 'after' comments - add inline after the main content
451
482
  const afterComments = component.getPositionedComments('after');
@@ -453,7 +484,7 @@ export class SqlPrintTokenParser {
453
484
  const commentBlocks = this.createCommentBlocks(afterComments);
454
485
  // Append after comments with spaces for inline formatting
455
486
  for (const commentBlock of commentBlocks) {
456
- token.innerTokens.push(new SqlPrintToken(SqlPrintTokenType.space, ' '));
487
+ token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
457
488
  token.innerTokens.push(commentBlock);
458
489
  }
459
490
  }
@@ -482,16 +513,8 @@ export class SqlPrintTokenParser {
482
513
  if (!(comments === null || comments === void 0 ? void 0 : comments.length)) {
483
514
  return;
484
515
  }
485
- // For multiple comments, create inline comment sequence instead of separate blocks
486
- if (comments.length > 1) {
487
- const inlineComments = this.createInlineCommentSequence(comments);
488
- this.insertCommentBlocksWithSpacing(token, inlineComments);
489
- }
490
- else {
491
- // Create CommentBlock containers for single comment
492
- const commentBlocks = this.createCommentBlocks(comments);
493
- this.insertCommentBlocksWithSpacing(token, commentBlocks);
494
- }
516
+ const commentBlocks = this.createCommentBlocks(comments);
517
+ this.insertCommentBlocksWithSpacing(token, commentBlocks);
495
518
  }
496
519
  /**
497
520
  * Creates inline comment sequence for multiple comments without newlines
@@ -502,7 +525,7 @@ export class SqlPrintTokenParser {
502
525
  const comment = comments[i];
503
526
  if (comment.trim()) {
504
527
  // Add comment token directly
505
- const commentToken = new SqlPrintToken(SqlPrintTokenType.comment, this.formatBlockComment(comment));
528
+ const commentToken = new SqlPrintToken(SqlPrintTokenType.comment, this.formatComment(comment));
506
529
  commentTokens.push(commentToken);
507
530
  // Add space between comments (except after last comment)
508
531
  if (i < comments.length - 1) {
@@ -515,63 +538,21 @@ export class SqlPrintTokenParser {
515
538
  }
516
539
  /**
517
540
  * Creates CommentBlock containers for the given comments.
518
- * Each CommentBlock contains: Comment -> CommentNewline -> Space
519
- * This structure supports both oneliner and multiline formatting modes.
541
+ * Each CommentBlock contains: Comment -> CommentNewline -> Space.
542
+ * @param comments Raw comment strings to convert into CommentBlock tokens.
543
+ * @param isHeaderComment Marks the generated blocks as originating from header comments when true.
520
544
  */
521
- createCommentBlocks(comments) {
522
- if (this.commentStyle === 'smart') {
523
- return this.createSmartCommentBlocks(comments);
524
- }
525
- // Block style (default) - each comment gets its own block
545
+ createCommentBlocks(comments, isHeaderComment = false) {
546
+ // Create individual comment blocks for each comment entry
526
547
  const commentBlocks = [];
527
548
  for (const comment of comments) {
528
549
  // Accept comments that have content after trim OR are separator lines OR are empty (for structure preservation)
529
550
  const trimmed = comment.trim();
530
551
  const isSeparatorLine = /^[-=_+*#]+$/.test(trimmed);
531
552
  if (trimmed || isSeparatorLine || comment === '') {
532
- commentBlocks.push(this.createSingleCommentBlock(comment));
533
- }
534
- }
535
- return commentBlocks;
536
- }
537
- /**
538
- * Creates smart comment blocks by merging consecutive block comments into multi-line format
539
- */
540
- createSmartCommentBlocks(comments) {
541
- const commentBlocks = [];
542
- const blockComments = [];
543
- const flushBlockComments = () => {
544
- if (blockComments.length > 0) {
545
- if (blockComments.length === 1) {
546
- // Single comment - keep as-is
547
- commentBlocks.push(this.createSingleCommentBlock(blockComments[0]));
548
- }
549
- else {
550
- // Multiple consecutive comments - create multi-line block
551
- commentBlocks.push(this.createMultiLineCommentBlock(blockComments));
552
- }
553
- blockComments.length = 0;
554
- }
555
- };
556
- for (const comment of comments) {
557
- const trimmed = comment.trim();
558
- const isSeparatorLine = /^[-=_+*#]+$/.test(trimmed);
559
- if (!trimmed && !isSeparatorLine && comment !== '') {
560
- continue;
561
- }
562
- // Check if this is a block comment that should be merged
563
- if (this.shouldMergeComment(trimmed)) {
564
- blockComments.push(comment);
565
- }
566
- else {
567
- // Flush any accumulated block comments first
568
- flushBlockComments();
569
- // Add this comment as-is
570
- commentBlocks.push(this.createSingleCommentBlock(comment));
553
+ commentBlocks.push(this.createSingleCommentBlock(comment, isHeaderComment));
571
554
  }
572
555
  }
573
- // Flush any remaining block comments
574
- flushBlockComments();
575
556
  return commentBlocks;
576
557
  }
577
558
  /**
@@ -584,8 +565,14 @@ export class SqlPrintTokenParser {
584
565
  return false;
585
566
  }
586
567
  // Don't merge if it's already a proper multi-line block comment
587
- if (trimmed.startsWith('/*') && trimmed.endsWith('*/') && trimmed.includes('\n')) {
588
- return false;
568
+ if (trimmed.startsWith('/*') && trimmed.endsWith('*/')) {
569
+ const inner = trimmed.slice(2, -2).trim();
570
+ if (!inner) {
571
+ return false;
572
+ }
573
+ if (trimmed.includes('\n')) {
574
+ return false;
575
+ }
589
576
  }
590
577
  // Merge all other content including separator lines, plain text, and single-line block comments
591
578
  // Separator lines within comment blocks should be merged together
@@ -595,98 +582,6 @@ export class SqlPrintTokenParser {
595
582
  * Creates a multi-line block comment structure from consecutive comments
596
583
  * Returns a CommentBlock containing multiple comment lines for proper LinePrinter integration
597
584
  */
598
- createMultiLineCommentBlock(comments) {
599
- const lines = [];
600
- for (const comment of comments) {
601
- const trimmed = comment.trim();
602
- // Remove existing /* */ markers if present and extract content
603
- if (trimmed.startsWith('/*') && trimmed.endsWith('*/')) {
604
- const content = trimmed.slice(2, -2);
605
- if (content.trim()) {
606
- // Sanitize the content (only remove /* and */)
607
- const sanitized = content
608
- .replace(/\*\//g, '*') // Remove */ sequences
609
- .replace(/\/\*/g, '*'); // Remove /* sequences
610
- // Split multi-line content and add each line
611
- const contentLines = sanitized.split('\n').map(line => line.trim()).filter(line => line);
612
- lines.push(...contentLines);
613
- }
614
- }
615
- else if (trimmed) {
616
- // Sanitize plain text content
617
- const sanitized = trimmed
618
- .replace(/\*\//g, '*') // Remove */ sequences
619
- .replace(/\/\*/g, '*'); // Remove /* sequences
620
- // Split plain text content by lines
621
- const contentLines = sanitized.split('\n').map(line => line.trim()).filter(line => line);
622
- lines.push(...contentLines);
623
- }
624
- }
625
- // Create multi-line comment block structure
626
- const commentBlock = new SqlPrintToken(SqlPrintTokenType.container, '', SqlPrintTokenContainerType.CommentBlock);
627
- if (lines.length === 0) {
628
- // Empty comment
629
- const commentToken = new SqlPrintToken(SqlPrintTokenType.comment, '/* */');
630
- commentBlock.innerTokens.push(commentToken);
631
- }
632
- else {
633
- // Opening /*
634
- const openToken = new SqlPrintToken(SqlPrintTokenType.comment, '/*');
635
- commentBlock.innerTokens.push(openToken);
636
- commentBlock.innerTokens.push(new SqlPrintToken(SqlPrintTokenType.commentNewline, ''));
637
- // Content lines (each as separate comment token)
638
- for (const line of lines) {
639
- const lineToken = new SqlPrintToken(SqlPrintTokenType.comment, ` ${line}`);
640
- commentBlock.innerTokens.push(lineToken);
641
- commentBlock.innerTokens.push(new SqlPrintToken(SqlPrintTokenType.commentNewline, ''));
642
- }
643
- // Closing */
644
- const closeToken = new SqlPrintToken(SqlPrintTokenType.comment, '*/');
645
- commentBlock.innerTokens.push(closeToken);
646
- }
647
- // Add final newline and space for standard structure
648
- commentBlock.innerTokens.push(new SqlPrintToken(SqlPrintTokenType.commentNewline, ''));
649
- commentBlock.innerTokens.push(new SqlPrintToken(SqlPrintTokenType.space, ' '));
650
- return commentBlock;
651
- }
652
- /**
653
- * Creates a multi-line comment block specifically for headerComments
654
- * headerComments come as pre-split lines, so we handle them differently
655
- */
656
- createHeaderMultiLineCommentBlock(headerComments) {
657
- // Keep all lines including empty ones to preserve structure
658
- const lines = headerComments;
659
- // Create multi-line comment block structure
660
- const commentBlock = new SqlPrintToken(SqlPrintTokenType.container, '', SqlPrintTokenContainerType.CommentBlock);
661
- if (lines.length === 0) {
662
- // Empty comment
663
- const commentToken = new SqlPrintToken(SqlPrintTokenType.comment, '/* */');
664
- commentBlock.innerTokens.push(commentToken);
665
- }
666
- else {
667
- // Opening /*
668
- const openToken = new SqlPrintToken(SqlPrintTokenType.comment, '/*');
669
- commentBlock.innerTokens.push(openToken);
670
- commentBlock.innerTokens.push(new SqlPrintToken(SqlPrintTokenType.commentNewline, ''));
671
- // Content lines (each as separate comment token)
672
- for (const line of lines) {
673
- // Sanitize the line content
674
- const sanitized = line
675
- .replace(/\*\//g, '*') // Remove */ sequences
676
- .replace(/\/\*/g, '*'); // Remove /* sequences
677
- const lineToken = new SqlPrintToken(SqlPrintTokenType.comment, ` ${sanitized}`);
678
- commentBlock.innerTokens.push(lineToken);
679
- commentBlock.innerTokens.push(new SqlPrintToken(SqlPrintTokenType.commentNewline, ''));
680
- }
681
- // Closing */
682
- const closeToken = new SqlPrintToken(SqlPrintTokenType.comment, '*/');
683
- commentBlock.innerTokens.push(closeToken);
684
- }
685
- // Add final newline and space for standard structure
686
- commentBlock.innerTokens.push(new SqlPrintToken(SqlPrintTokenType.commentNewline, ''));
687
- commentBlock.innerTokens.push(new SqlPrintToken(SqlPrintTokenType.space, ' '));
688
- return commentBlock;
689
- }
690
585
  /**
691
586
  * Creates a single CommentBlock with the standard structure:
692
587
  * Comment -> CommentNewline -> Space
@@ -695,8 +590,11 @@ export class SqlPrintTokenParser {
695
590
  * - Multiline mode: Comment + newline (space is filtered as leading space)
696
591
  * - Oneliner mode: Comment + space (commentNewline is skipped)
697
592
  */
698
- createSingleCommentBlock(comment) {
593
+ createSingleCommentBlock(comment, isHeaderComment = false) {
699
594
  const commentBlock = new SqlPrintToken(SqlPrintTokenType.container, '', SqlPrintTokenContainerType.CommentBlock);
595
+ if (isHeaderComment) {
596
+ commentBlock.markAsHeaderComment();
597
+ }
700
598
  // Add comment token - preserve original format for line comments
701
599
  const commentToken = new SqlPrintToken(SqlPrintTokenType.comment, this.formatComment(comment));
702
600
  commentBlock.innerTokens.push(commentToken);
@@ -714,42 +612,28 @@ export class SqlPrintTokenParser {
714
612
  */
715
613
  formatComment(comment) {
716
614
  const trimmed = comment.trim();
717
- // Smart style processing
718
- if (this.commentStyle === 'smart') {
719
- return this.formatCommentSmart(trimmed);
615
+ if (!trimmed) {
616
+ return '/* */';
720
617
  }
721
- // Default block style processing
722
- // If it's already a line comment, preserve it
723
- // But exclude separator lines (lines with only dashes, equals, etc.)
724
- if (trimmed.startsWith('--') && !/^--[-=_+*#]*$/.test(trimmed)) {
725
- return trimmed;
618
+ const isSeparatorLine = /^[-=_+*#]+$/.test(trimmed);
619
+ if (isSeparatorLine) {
620
+ return this.formatBlockComment(trimmed);
621
+ }
622
+ if (trimmed.startsWith('--')) {
623
+ return this.formatLineComment(trimmed.slice(2));
726
624
  }
727
- // If it's already a block comment, preserve it (but sanitize)
728
625
  if (trimmed.startsWith('/*') && trimmed.endsWith('*/')) {
729
- // Pass the entire comment including /* and */ for proper sanitization
730
626
  return this.formatBlockComment(trimmed);
731
627
  }
732
- // For plain text comments, convert to block format
733
628
  return this.formatBlockComment(trimmed);
734
629
  }
735
- /**
736
- * Formats comments using smart style rules:
737
- * - Only multi-line block comment merging is supported
738
- * - Single-line comments remain as block comments (no dash conversion)
739
- */
740
- formatCommentSmart(comment) {
741
- // Smart style only affects multi-line comment merging at createSmartCommentBlocks level
742
- // Individual comment formatting remains the same as block style
743
- return this.formatBlockComment(comment);
744
- }
745
630
  /**
746
631
  * Inserts comment blocks into a token and handles spacing logic.
747
632
  * Adds separator spaces for clause-level containers and manages duplicate space removal.
748
633
  */
749
634
  insertCommentBlocksWithSpacing(token, commentBlocks) {
750
- // For SelectItem, append comments at the end with proper spacing
635
+ // For SelectItem, append comment blocks after ensuring spacing
751
636
  if (token.containerType === SqlPrintTokenContainerType.SelectItem) {
752
- // Add space before comment if not already present
753
637
  if (token.innerTokens.length > 0) {
754
638
  const lastToken = token.innerTokens[token.innerTokens.length - 1];
755
639
  if (lastToken.type !== SqlPrintTokenType.space) {
@@ -769,7 +653,6 @@ export class SqlPrintTokenParser {
769
653
  }
770
654
  // Special handling for IdentifierString to add space before comment
771
655
  if (token.containerType === SqlPrintTokenContainerType.IdentifierString) {
772
- // Add space before comment if not already present
773
656
  if (token.innerTokens.length > 0) {
774
657
  const lastToken = token.innerTokens[token.innerTokens.length - 1];
775
658
  if (lastToken.type !== SqlPrintTokenType.space) {
@@ -872,27 +755,95 @@ export class SqlPrintTokenParser {
872
755
  * Prevents SQL injection by removing dangerous comment sequences.
873
756
  */
874
757
  formatBlockComment(comment) {
875
- // Sanitize dangerous comment sequences to prevent SQL injection
876
- let sanitizedComment = comment
877
- .replace(/\*\//g, '*') // Remove comment close sequences
878
- .replace(/\/\*/g, '*'); // Remove comment open sequences
879
- // Check if this is a separator line (like ----------) before processing
880
- const trimmed = sanitizedComment.trim();
881
- const isSeparatorLine = /^[-=_+*#]+$/.test(trimmed);
882
- if (isSeparatorLine) {
883
- // For separator lines, preserve as-is (already sanitized above)
884
- return `/* ${trimmed} */`;
885
- }
886
- // For multiline comments: convert newlines to spaces (security requirement)
887
- sanitizedComment = sanitizedComment
888
- .replace(/\r?\n/g, ' ') // Replace newlines with spaces
889
- .replace(/\s+/g, ' ') // Collapse multiple spaces into single space
890
- .trim(); // Remove leading/trailing whitespace
891
- // Return empty string if comment becomes empty after sanitization
892
- if (!sanitizedComment) {
893
- return '';
758
+ const hasDelimiters = comment.startsWith('/*') && comment.endsWith('*/');
759
+ const rawContent = hasDelimiters ? comment.slice(2, -2) : comment;
760
+ const escapedContent = this.escapeCommentDelimiters(rawContent);
761
+ const normalized = escapedContent.replace(/\r?\n/g, '\n');
762
+ const lines = normalized
763
+ .split('\n')
764
+ .map(line => line.replace(/\s+/g, ' ').trim())
765
+ .filter(line => line.length > 0);
766
+ if (lines.length === 0) {
767
+ return '/* */';
768
+ }
769
+ const isSeparatorLine = lines.length === 1 && /^[-=_+*#]+$/.test(lines[0]);
770
+ if (!hasDelimiters) {
771
+ // Flatten free-form comments to a single block to avoid leaking multi-line structures.
772
+ if (isSeparatorLine) {
773
+ return `/* ${lines[0]} */`;
774
+ }
775
+ const flattened = lines.join(' ');
776
+ return `/* ${flattened} */`;
777
+ }
778
+ if (isSeparatorLine || lines.length === 1) {
779
+ return `/* ${lines[0]} */`;
780
+ }
781
+ const body = lines.map(line => ` ${line}`).join('\n');
782
+ return `/*\n${body}\n*/`;
783
+ }
784
+ shouldMergeHeaderComments(comments) {
785
+ if (comments.length <= 1) {
786
+ return false;
787
+ }
788
+ return comments.some(comment => {
789
+ const trimmed = comment.trim();
790
+ return /^[-=_+*#]{3,}$/.test(trimmed) || trimmed.startsWith('- ') || trimmed.startsWith('* ');
791
+ });
792
+ }
793
+ createHeaderMultiLineCommentBlock(headerComments) {
794
+ const commentBlock = new SqlPrintToken(SqlPrintTokenType.container, '', SqlPrintTokenContainerType.CommentBlock);
795
+ commentBlock.markAsHeaderComment();
796
+ if (headerComments.length === 0) {
797
+ const commentToken = new SqlPrintToken(SqlPrintTokenType.comment, '/* */');
798
+ commentBlock.innerTokens.push(commentToken);
799
+ }
800
+ else {
801
+ const openToken = new SqlPrintToken(SqlPrintTokenType.comment, '/*');
802
+ commentBlock.innerTokens.push(openToken);
803
+ commentBlock.innerTokens.push(new SqlPrintToken(SqlPrintTokenType.commentNewline, ''));
804
+ for (const line of headerComments) {
805
+ const sanitized = this.escapeCommentDelimiters(line);
806
+ const lineToken = new SqlPrintToken(SqlPrintTokenType.comment, ` ${sanitized}`);
807
+ commentBlock.innerTokens.push(lineToken);
808
+ commentBlock.innerTokens.push(new SqlPrintToken(SqlPrintTokenType.commentNewline, ''));
809
+ }
810
+ const closeToken = new SqlPrintToken(SqlPrintTokenType.comment, '*/');
811
+ commentBlock.innerTokens.push(closeToken);
812
+ }
813
+ commentBlock.innerTokens.push(new SqlPrintToken(SqlPrintTokenType.commentNewline, ''));
814
+ commentBlock.innerTokens.push(new SqlPrintToken(SqlPrintTokenType.space, ' '));
815
+ return commentBlock;
816
+ }
817
+ /**
818
+ * Formats text as a single-line comment while sanitizing unsafe sequences.
819
+ */
820
+ formatLineComment(content) {
821
+ // Normalize content to a single line and remove dangerous sequences
822
+ const sanitized = this.sanitizeLineCommentContent(content);
823
+ if (!sanitized) {
824
+ return '--';
894
825
  }
895
- return `/* ${sanitizedComment} */`;
826
+ return `-- ${sanitized}`;
827
+ }
828
+ /**
829
+ * Sanitizes content intended for a single-line comment.
830
+ */
831
+ sanitizeLineCommentContent(content) {
832
+ // Replace comment delimiters to avoid nested comment injection
833
+ let sanitized = this.escapeCommentDelimiters(content)
834
+ .replace(/\r?\n/g, ' ')
835
+ .replace(/\u2028|\u2029/g, ' ')
836
+ .replace(/\s+/g, ' ')
837
+ .trim();
838
+ if (sanitized.startsWith('--')) {
839
+ sanitized = sanitized.slice(2).trimStart();
840
+ }
841
+ return sanitized;
842
+ }
843
+ escapeCommentDelimiters(content) {
844
+ return content
845
+ .replace(/\/\*/g, '\\/\\*')
846
+ .replace(/\*\//g, '*\\/');
896
847
  }
897
848
  visitValueList(arg) {
898
849
  const token = new SqlPrintToken(SqlPrintTokenType.container, '', SqlPrintTokenContainerType.ValueList);
@@ -912,7 +863,6 @@ export class SqlPrintTokenParser {
912
863
  }
913
864
  visitFunctionCall(arg) {
914
865
  const token = new SqlPrintToken(SqlPrintTokenType.container, '', SqlPrintTokenContainerType.FunctionCall);
915
- this.addComponentComments(token, arg);
916
866
  token.innerTokens.push(arg.qualifiedName.accept(this));
917
867
  token.innerTokens.push(SqlPrintTokenParser.PAREN_OPEN_TOKEN);
918
868
  if (arg.argument) {
@@ -950,6 +900,7 @@ export class SqlPrintTokenParser {
950
900
  token.innerTokens.push(SqlPrintTokenParser.PAREN_CLOSE_TOKEN);
951
901
  }
952
902
  }
903
+ this.addComponentComments(token, arg);
953
904
  return token;
954
905
  }
955
906
  visitUnaryExpression(arg) {
@@ -1154,9 +1105,22 @@ export class SqlPrintTokenParser {
1154
1105
  }
1155
1106
  visitCastExpression(arg) {
1156
1107
  const token = new SqlPrintToken(SqlPrintTokenType.container, '', SqlPrintTokenContainerType.CastExpression);
1108
+ // Use PostgreSQL-specific :: casts only when the preset explicitly opts in.
1109
+ if (this.castStyle === 'postgres') {
1110
+ token.innerTokens.push(this.visit(arg.input));
1111
+ token.innerTokens.push(new SqlPrintToken(SqlPrintTokenType.operator, '::'));
1112
+ token.innerTokens.push(this.visit(arg.castType));
1113
+ return token;
1114
+ }
1115
+ // Default to ANSI-compliant CAST(expression AS type) syntax for broader compatibility.
1116
+ token.innerTokens.push(new SqlPrintToken(SqlPrintTokenType.keyword, 'cast'));
1117
+ token.innerTokens.push(SqlPrintTokenParser.PAREN_OPEN_TOKEN);
1157
1118
  token.innerTokens.push(this.visit(arg.input));
1158
- token.innerTokens.push(new SqlPrintToken(SqlPrintTokenType.operator, '::'));
1119
+ token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
1120
+ token.innerTokens.push(new SqlPrintToken(SqlPrintTokenType.keyword, 'as'));
1121
+ token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
1159
1122
  token.innerTokens.push(this.visit(arg.castType));
1123
+ token.innerTokens.push(SqlPrintTokenParser.PAREN_CLOSE_TOKEN);
1160
1124
  return token;
1161
1125
  }
1162
1126
  visitCaseExpression(arg) {
@@ -1167,20 +1131,148 @@ export class SqlPrintTokenParser {
1167
1131
  // Clear positioned comments to prevent duplicate processing
1168
1132
  arg.positionedComments = null;
1169
1133
  }
1134
+ const promotedComments = [];
1135
+ const trailingSwitchComments = this.extractSwitchAfterComments(arg.switchCase);
1136
+ let conditionToken = null;
1137
+ if (arg.condition) {
1138
+ conditionToken = this.visit(arg.condition);
1139
+ promotedComments.push(...this.collectCaseLeadingCommentBlocks(conditionToken));
1140
+ }
1141
+ const switchToken = this.visit(arg.switchCase);
1142
+ promotedComments.push(...this.collectCaseLeadingCommentsFromSwitch(switchToken));
1143
+ if (promotedComments.length > 0) {
1144
+ token.innerTokens.push(...promotedComments);
1145
+ }
1170
1146
  // Add the CASE keyword
1171
1147
  token.innerTokens.push(new SqlPrintToken(SqlPrintTokenType.keyword, 'case'));
1172
1148
  // Add the condition if exists
1173
- if (arg.condition) {
1149
+ if (conditionToken) {
1174
1150
  token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
1175
- token.innerTokens.push(this.visit(arg.condition));
1151
+ token.innerTokens.push(conditionToken);
1176
1152
  }
1177
1153
  // Add the WHEN/THEN pairs and ELSE
1178
- token.innerTokens.push(this.visit(arg.switchCase));
1154
+ token.innerTokens.push(switchToken);
1179
1155
  // Add the END keyword
1180
1156
  token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
1181
1157
  token.innerTokens.push(new SqlPrintToken(SqlPrintTokenType.keyword, 'end'));
1158
+ if (trailingSwitchComments.length > 0) {
1159
+ token.innerTokens.push(new SqlPrintToken(SqlPrintTokenType.commentNewline, ''));
1160
+ const trailingBlocks = this.createCommentBlocks(trailingSwitchComments);
1161
+ token.innerTokens.push(...trailingBlocks);
1162
+ }
1182
1163
  return token;
1183
1164
  }
1165
+ extractSwitchAfterComments(arg) {
1166
+ if (!arg.positionedComments || arg.positionedComments.length === 0) {
1167
+ return [];
1168
+ }
1169
+ const trailing = [];
1170
+ const retained = [];
1171
+ for (const entry of arg.positionedComments) {
1172
+ if (entry.position === 'after') {
1173
+ trailing.push(...entry.comments);
1174
+ }
1175
+ else {
1176
+ retained.push(entry);
1177
+ }
1178
+ }
1179
+ arg.positionedComments = retained.length > 0 ? retained : null;
1180
+ return trailing;
1181
+ }
1182
+ collectCaseLeadingCommentsFromSwitch(token) {
1183
+ if (!token.innerTokens || token.innerTokens.length === 0) {
1184
+ return [];
1185
+ }
1186
+ const pairToken = token.innerTokens.find(child => child.containerType === SqlPrintTokenContainerType.CaseKeyValuePair);
1187
+ if (!pairToken) {
1188
+ return [];
1189
+ }
1190
+ const keyToken = this.findCaseKeyToken(pairToken);
1191
+ if (!keyToken) {
1192
+ return [];
1193
+ }
1194
+ return this.collectCaseLeadingCommentBlocks(keyToken);
1195
+ }
1196
+ findCaseKeyToken(pairToken) {
1197
+ for (const child of pairToken.innerTokens) {
1198
+ if (child.containerType === SqlPrintTokenContainerType.CommentBlock) {
1199
+ continue;
1200
+ }
1201
+ if (child.type === SqlPrintTokenType.space) {
1202
+ continue;
1203
+ }
1204
+ if (child.type === SqlPrintTokenType.keyword) {
1205
+ continue;
1206
+ }
1207
+ if (child.containerType === SqlPrintTokenContainerType.CaseThenValue) {
1208
+ continue;
1209
+ }
1210
+ return child;
1211
+ }
1212
+ return undefined;
1213
+ }
1214
+ collectCaseLeadingCommentBlocks(token) {
1215
+ if (!token.innerTokens || token.innerTokens.length === 0) {
1216
+ return [];
1217
+ }
1218
+ const collected = [];
1219
+ this.collectCaseLeadingCommentBlocksRecursive(token, collected, new Set(), 0);
1220
+ return collected;
1221
+ }
1222
+ collectCaseLeadingCommentBlocksRecursive(token, collected, seen, depth) {
1223
+ if (!token.innerTokens || token.innerTokens.length === 0) {
1224
+ return;
1225
+ }
1226
+ let removedAny = false;
1227
+ while (token.innerTokens.length > 0) {
1228
+ const first = token.innerTokens[0];
1229
+ if (first.containerType === SqlPrintTokenContainerType.CommentBlock) {
1230
+ token.innerTokens.shift();
1231
+ const signature = this.commentBlockSignature(first);
1232
+ if (!(depth > 0 && seen.has(signature))) {
1233
+ collected.push(first);
1234
+ seen.add(signature);
1235
+ }
1236
+ removedAny = true;
1237
+ continue;
1238
+ }
1239
+ if (!removedAny && first.type === SqlPrintTokenType.space) {
1240
+ return;
1241
+ }
1242
+ break;
1243
+ }
1244
+ if (!token.innerTokens || token.innerTokens.length === 0) {
1245
+ return;
1246
+ }
1247
+ const firstChild = token.innerTokens[0];
1248
+ if (this.isTransparentCaseWrapper(firstChild)) {
1249
+ this.collectCaseLeadingCommentBlocksRecursive(firstChild, collected, seen, depth + 1);
1250
+ }
1251
+ }
1252
+ isTransparentCaseWrapper(token) {
1253
+ if (!token) {
1254
+ return false;
1255
+ }
1256
+ const transparentContainers = [
1257
+ SqlPrintTokenContainerType.ColumnReference,
1258
+ SqlPrintTokenContainerType.QualifiedName,
1259
+ SqlPrintTokenContainerType.IdentifierString,
1260
+ SqlPrintTokenContainerType.RawString,
1261
+ SqlPrintTokenContainerType.LiteralValue,
1262
+ SqlPrintTokenContainerType.ParenExpression,
1263
+ SqlPrintTokenContainerType.UnaryExpression,
1264
+ ];
1265
+ return transparentContainers.includes(token.containerType);
1266
+ }
1267
+ commentBlockSignature(commentBlock) {
1268
+ if (!commentBlock.innerTokens || commentBlock.innerTokens.length === 0) {
1269
+ return '';
1270
+ }
1271
+ return commentBlock.innerTokens
1272
+ .filter(inner => inner.text !== '')
1273
+ .map(inner => inner.text)
1274
+ .join('|');
1275
+ }
1184
1276
  visitArrayExpression(arg) {
1185
1277
  const token = new SqlPrintToken(SqlPrintTokenType.container, '', SqlPrintTokenContainerType.ArrayExpression);
1186
1278
  token.innerTokens.push(new SqlPrintToken(SqlPrintTokenType.keyword, 'array'));
@@ -1266,6 +1358,7 @@ export class SqlPrintTokenParser {
1266
1358
  }
1267
1359
  visitTupleExpression(arg) {
1268
1360
  const token = new SqlPrintToken(SqlPrintTokenType.container, '', SqlPrintTokenContainerType.TupleExpression);
1361
+ const requiresMultiline = this.tupleRequiresMultiline(arg);
1269
1362
  token.innerTokens.push(SqlPrintTokenParser.PAREN_OPEN_TOKEN);
1270
1363
  for (let i = 0; i < arg.values.length; i++) {
1271
1364
  if (i > 0) {
@@ -1273,10 +1366,38 @@ export class SqlPrintTokenParser {
1273
1366
  }
1274
1367
  token.innerTokens.push(this.visit(arg.values[i]));
1275
1368
  }
1369
+ if (requiresMultiline) {
1370
+ token.innerTokens.push(new SqlPrintToken(SqlPrintTokenType.commentNewline, '', SqlPrintTokenContainerType.TupleExpression));
1371
+ }
1276
1372
  token.innerTokens.push(SqlPrintTokenParser.PAREN_CLOSE_TOKEN);
1277
- this.addComponentComments(token, arg);
1278
1373
  return token;
1279
1374
  }
1375
+ tupleRequiresMultiline(tuple) {
1376
+ for (const value of tuple.values) {
1377
+ if (this.hasInlineComments(value)) {
1378
+ return true;
1379
+ }
1380
+ }
1381
+ return false;
1382
+ }
1383
+ hasInlineComments(component) {
1384
+ if (this.hasLeadingComments(component)) {
1385
+ return true;
1386
+ }
1387
+ if (component instanceof TupleExpression) {
1388
+ return this.tupleRequiresMultiline(component);
1389
+ }
1390
+ return false;
1391
+ }
1392
+ hasLeadingComments(component) {
1393
+ var _a;
1394
+ const positioned = (_a = component.positionedComments) !== null && _a !== void 0 ? _a : [];
1395
+ const before = positioned.find(pc => pc.position === 'before');
1396
+ if (before && before.comments.some(comment => comment.trim().length > 0)) {
1397
+ return true;
1398
+ }
1399
+ return false;
1400
+ }
1280
1401
  visitWindowFrameExpression(arg) {
1281
1402
  // Compose window frame expression: over(partition by ... order by ... rows ...)
1282
1403
  const token = new SqlPrintToken(SqlPrintTokenType.container, '', SqlPrintTokenContainerType.WindowFrameExpression);
@@ -1355,19 +1476,16 @@ export class SqlPrintTokenParser {
1355
1476
  const originalValuePositionedComments = arg.value.positionedComments;
1356
1477
  // Clear positioned comments from the value to avoid duplication since SelectItem handles them
1357
1478
  arg.value.positionedComments = null;
1358
- // Add 'before' positioned comments
1479
+ // Add positioned comments in recorded order
1359
1480
  const beforeComments = arg.getPositionedComments('before');
1481
+ const afterComments = arg.getPositionedComments('after');
1482
+ const isParenExpression = arg.value instanceof ParenExpression;
1360
1483
  if (beforeComments.length > 0) {
1361
1484
  const commentTokens = this.createInlineCommentSequence(beforeComments);
1362
1485
  token.innerTokens.push(...commentTokens);
1363
1486
  token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
1364
1487
  }
1365
- // Add the value (column name)
1366
1488
  token.innerTokens.push(this.visit(arg.value));
1367
- // Add 'after' positioned comments for the value
1368
- // Skip after comments if the value is ParenExpression (already handled in ParenExpression processing)
1369
- const afterComments = arg.getPositionedComments('after');
1370
- const isParenExpression = arg.value.constructor.name === 'ParenExpression';
1371
1489
  if (afterComments.length > 0 && !isParenExpression) {
1372
1490
  token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
1373
1491
  const commentTokens = this.createInlineCommentSequence(afterComments);
@@ -1560,16 +1678,32 @@ export class SqlPrintTokenParser {
1560
1678
  }
1561
1679
  }
1562
1680
  visitFromClause(arg) {
1563
- const token = new SqlPrintToken(SqlPrintTokenType.keyword, 'from', SqlPrintTokenContainerType.FromClause);
1564
- token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
1565
- token.innerTokens.push(this.visit(arg.source));
1566
- if (arg.joins) {
1567
- for (let i = 0; i < arg.joins.length; i++) {
1568
- token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
1569
- token.innerTokens.push(this.visit(arg.joins[i]));
1681
+ // Build a declaration order map so JOIN ON operands can be normalized later.
1682
+ let contextPushed = false;
1683
+ if (this.normalizeJoinConditionOrder) {
1684
+ const aliasOrder = this.buildJoinAliasOrder(arg);
1685
+ if (aliasOrder.size > 0) {
1686
+ this.joinConditionContexts.push({ aliasOrder });
1687
+ contextPushed = true;
1688
+ }
1689
+ }
1690
+ try {
1691
+ const token = new SqlPrintToken(SqlPrintTokenType.keyword, 'from', SqlPrintTokenContainerType.FromClause);
1692
+ token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
1693
+ token.innerTokens.push(this.visit(arg.source));
1694
+ if (arg.joins) {
1695
+ for (let i = 0; i < arg.joins.length; i++) {
1696
+ token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
1697
+ token.innerTokens.push(this.visit(arg.joins[i]));
1698
+ }
1699
+ }
1700
+ return token;
1701
+ }
1702
+ finally {
1703
+ if (contextPushed) {
1704
+ this.joinConditionContexts.pop();
1570
1705
  }
1571
1706
  }
1572
- return token;
1573
1707
  }
1574
1708
  visitJoinClause(arg) {
1575
1709
  // Print join clause: [joinType] [lateral] [source] [on/using ...]
@@ -1619,12 +1753,123 @@ export class SqlPrintTokenParser {
1619
1753
  return token;
1620
1754
  }
1621
1755
  visitJoinOnClause(arg) {
1756
+ // Normalize JOIN ON predicate columns to follow declaration order when enabled.
1757
+ if (this.normalizeJoinConditionOrder) {
1758
+ const aliasOrder = this.getCurrentJoinAliasOrder();
1759
+ if (aliasOrder) {
1760
+ this.normalizeJoinConditionValue(arg.condition, aliasOrder);
1761
+ }
1762
+ }
1622
1763
  const token = new SqlPrintToken(SqlPrintTokenType.container, '', SqlPrintTokenContainerType.JoinOnClause);
1623
1764
  token.innerTokens.push(new SqlPrintToken(SqlPrintTokenType.keyword, 'on'));
1624
1765
  token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
1625
1766
  token.innerTokens.push(this.visit(arg.condition));
1626
1767
  return token;
1627
1768
  }
1769
+ getCurrentJoinAliasOrder() {
1770
+ if (this.joinConditionContexts.length === 0) {
1771
+ return null;
1772
+ }
1773
+ return this.joinConditionContexts[this.joinConditionContexts.length - 1].aliasOrder;
1774
+ }
1775
+ buildJoinAliasOrder(fromClause) {
1776
+ const aliasOrder = new Map();
1777
+ let nextIndex = 0;
1778
+ const registerSource = (source) => {
1779
+ const identifiers = this.collectSourceIdentifiers(source);
1780
+ if (identifiers.length === 0) {
1781
+ return;
1782
+ }
1783
+ // Track the earliest declaration index for each identifier found in the FROM clause.
1784
+ for (const identifier of identifiers) {
1785
+ const key = identifier.toLowerCase();
1786
+ if (!aliasOrder.has(key)) {
1787
+ aliasOrder.set(key, nextIndex);
1788
+ }
1789
+ }
1790
+ nextIndex++;
1791
+ };
1792
+ registerSource(fromClause.source);
1793
+ if (fromClause.joins) {
1794
+ for (const joinClause of fromClause.joins) {
1795
+ registerSource(joinClause.source);
1796
+ }
1797
+ }
1798
+ return aliasOrder;
1799
+ }
1800
+ collectSourceIdentifiers(source) {
1801
+ const identifiers = [];
1802
+ const aliasName = source.getAliasName();
1803
+ if (aliasName) {
1804
+ identifiers.push(aliasName);
1805
+ }
1806
+ // Capture table identifiers so unaliased tables can still be matched.
1807
+ if (source.datasource instanceof TableSource) {
1808
+ const tableComponent = source.datasource.table.name;
1809
+ identifiers.push(tableComponent);
1810
+ const fullName = source.datasource.getSourceName();
1811
+ if (fullName && fullName !== tableComponent) {
1812
+ identifiers.push(fullName);
1813
+ }
1814
+ }
1815
+ return identifiers;
1816
+ }
1817
+ normalizeJoinConditionValue(condition, aliasOrder) {
1818
+ // Walk the value tree so every comparison within the JOIN predicate is inspected.
1819
+ const kind = condition.getKind();
1820
+ if (kind === ParenExpression.kind) {
1821
+ const paren = condition;
1822
+ this.normalizeJoinConditionValue(paren.expression, aliasOrder);
1823
+ return;
1824
+ }
1825
+ if (kind === BinaryExpression.kind) {
1826
+ const binary = condition;
1827
+ this.normalizeJoinConditionValue(binary.left, aliasOrder);
1828
+ this.normalizeJoinConditionValue(binary.right, aliasOrder);
1829
+ this.normalizeBinaryEquality(binary, aliasOrder);
1830
+ }
1831
+ }
1832
+ normalizeBinaryEquality(binary, aliasOrder) {
1833
+ // Only normalize simple equality comparisons, leaving other operators untouched.
1834
+ const operatorValue = binary.operator.value.toLowerCase();
1835
+ if (operatorValue !== '=') {
1836
+ return;
1837
+ }
1838
+ const leftOwner = this.resolveColumnOwner(binary.left);
1839
+ const rightOwner = this.resolveColumnOwner(binary.right);
1840
+ if (!leftOwner || !rightOwner || leftOwner === rightOwner) {
1841
+ return;
1842
+ }
1843
+ const leftOrder = aliasOrder.get(leftOwner);
1844
+ const rightOrder = aliasOrder.get(rightOwner);
1845
+ if (leftOrder === undefined || rightOrder === undefined) {
1846
+ return;
1847
+ }
1848
+ if (leftOrder > rightOrder) {
1849
+ // Swap operands so the earlier declared table appears on the left.
1850
+ const originalLeft = binary.left;
1851
+ binary.left = binary.right;
1852
+ binary.right = originalLeft;
1853
+ }
1854
+ }
1855
+ resolveColumnOwner(value) {
1856
+ var _a;
1857
+ const kind = value.getKind();
1858
+ if (kind === ColumnReference.kind) {
1859
+ // Column references expose their qualifier namespace, which we normalize for lookups.
1860
+ const columnRef = value;
1861
+ const namespace = columnRef.getNamespace();
1862
+ if (!namespace) {
1863
+ return null;
1864
+ }
1865
+ const qualifier = namespace.includes('.') ? (_a = namespace.split('.').pop()) !== null && _a !== void 0 ? _a : '' : namespace;
1866
+ return qualifier.toLowerCase();
1867
+ }
1868
+ if (kind === ParenExpression.kind) {
1869
+ return this.resolveColumnOwner(value.expression);
1870
+ }
1871
+ return null;
1872
+ }
1628
1873
  visitJoinUsingClause(arg) {
1629
1874
  const token = new SqlPrintToken(SqlPrintTokenType.container, '', SqlPrintTokenContainerType.JoinUsingClause);
1630
1875
  token.innerTokens.push(new SqlPrintToken(SqlPrintTokenType.keyword, 'using'));
@@ -1803,14 +2048,12 @@ export class SqlPrintTokenParser {
1803
2048
  const token = new SqlPrintToken(SqlPrintTokenType.container, '', SqlPrintTokenContainerType.SimpleSelectQuery);
1804
2049
  // Handle positioned comments for SimpleSelectQuery (unified spec)
1805
2050
  if (arg.headerComments && arg.headerComments.length > 0) {
1806
- // Fallback to legacy headerComments if no positioned comments
1807
- // For smart comment style, treat headerComments as a single multi-line block
1808
- if (this.commentStyle === 'smart' && arg.headerComments.length > 1) {
2051
+ if (this.shouldMergeHeaderComments(arg.headerComments)) {
1809
2052
  const mergedHeaderComment = this.createHeaderMultiLineCommentBlock(arg.headerComments);
1810
2053
  token.innerTokens.push(mergedHeaderComment);
1811
2054
  }
1812
2055
  else {
1813
- const headerCommentBlocks = this.createCommentBlocks(arg.headerComments);
2056
+ const headerCommentBlocks = this.createCommentBlocks(arg.headerComments, true);
1814
2057
  token.innerTokens.push(...headerCommentBlocks);
1815
2058
  }
1816
2059
  if (arg.withClause) {
@@ -1891,11 +2134,18 @@ export class SqlPrintTokenParser {
1891
2134
  const token = new SqlPrintToken(SqlPrintTokenType.keyword, 'values', SqlPrintTokenContainerType.ValuesQuery);
1892
2135
  // Add headerComments before VALUES keyword
1893
2136
  if (arg.headerComments && arg.headerComments.length > 0) {
1894
- const headerCommentBlocks = this.createCommentBlocks(arg.headerComments);
1895
- for (const commentBlock of headerCommentBlocks) {
1896
- token.innerTokens.push(commentBlock);
2137
+ if (this.shouldMergeHeaderComments(arg.headerComments)) {
2138
+ const mergedHeaderComment = this.createHeaderMultiLineCommentBlock(arg.headerComments);
2139
+ token.innerTokens.push(mergedHeaderComment);
1897
2140
  token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
1898
2141
  }
2142
+ else {
2143
+ const headerCommentBlocks = this.createCommentBlocks(arg.headerComments, true);
2144
+ for (const commentBlock of headerCommentBlocks) {
2145
+ token.innerTokens.push(commentBlock);
2146
+ token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
2147
+ }
2148
+ }
1899
2149
  }
1900
2150
  token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
1901
2151
  const values = new SqlPrintToken(SqlPrintTokenType.container, '', SqlPrintTokenContainerType.Values);
@@ -1931,22 +2181,27 @@ export class SqlPrintTokenParser {
1931
2181
  }
1932
2182
  visitInsertQuery(arg) {
1933
2183
  const token = new SqlPrintToken(SqlPrintTokenType.container, '', SqlPrintTokenContainerType.InsertQuery);
1934
- // Process the insert clause
2184
+ if (arg.withClause) {
2185
+ token.innerTokens.push(arg.withClause.accept(this));
2186
+ }
1935
2187
  token.innerTokens.push(this.visit(arg.insertClause));
1936
2188
  // Process the select query if present
1937
2189
  if (arg.selectQuery) {
1938
2190
  token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
1939
2191
  token.innerTokens.push(this.visit(arg.selectQuery));
1940
2192
  }
2193
+ if (arg.returningClause) {
2194
+ token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
2195
+ token.innerTokens.push(arg.returningClause.accept(this));
2196
+ }
1941
2197
  return token;
1942
2198
  }
1943
2199
  visitInsertClause(arg) {
1944
- const token = new SqlPrintToken(SqlPrintTokenType.container, '');
1945
- token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
2200
+ const token = new SqlPrintToken(SqlPrintTokenType.container, '', SqlPrintTokenContainerType.InsertClause);
1946
2201
  token.innerTokens.push(new SqlPrintToken(SqlPrintTokenType.keyword, 'insert into'));
1947
2202
  token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
1948
2203
  token.innerTokens.push(arg.source.accept(this));
1949
- if (arg.columns.length > 0) {
2204
+ if (arg.columns && arg.columns.length > 0) {
1950
2205
  token.innerTokens.push(SqlPrintTokenParser.PAREN_OPEN_TOKEN);
1951
2206
  for (let i = 0; i < arg.columns.length; i++) {
1952
2207
  if (i > 0) {
@@ -1958,14 +2213,184 @@ export class SqlPrintTokenParser {
1958
2213
  }
1959
2214
  return token;
1960
2215
  }
1961
- visitUpdateQuery(arg) {
1962
- const token = new SqlPrintToken(SqlPrintTokenType.container, '', SqlPrintTokenContainerType.UpdateQuery);
2216
+ visitDeleteQuery(arg) {
2217
+ const token = new SqlPrintToken(SqlPrintTokenType.container, '', SqlPrintTokenContainerType.DeleteQuery);
2218
+ // Attach WITH clause tokens when present before the DELETE command.
1963
2219
  if (arg.withClause) {
1964
2220
  token.innerTokens.push(arg.withClause.accept(this));
1965
2221
  }
1966
- token.innerTokens.push(arg.updateClause.accept(this));
1967
- token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
1968
- token.innerTokens.push(arg.setClause.accept(this));
2222
+ token.innerTokens.push(arg.deleteClause.accept(this));
2223
+ // Append USING clause when the DELETE references additional sources.
2224
+ if (arg.usingClause) {
2225
+ token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
2226
+ token.innerTokens.push(arg.usingClause.accept(this));
2227
+ }
2228
+ // Append WHERE clause to restrict affected rows.
2229
+ if (arg.whereClause) {
2230
+ token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
2231
+ token.innerTokens.push(arg.whereClause.accept(this));
2232
+ }
2233
+ // Append RETURNING clause when the DELETE yields output columns.
2234
+ if (arg.returningClause) {
2235
+ token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
2236
+ token.innerTokens.push(arg.returningClause.accept(this));
2237
+ }
2238
+ return token;
2239
+ }
2240
+ visitDeleteClause(arg) {
2241
+ const token = new SqlPrintToken(SqlPrintTokenType.keyword, 'delete from', SqlPrintTokenContainerType.DeleteClause);
2242
+ // Render the target relation immediately after the DELETE FROM keyword.
2243
+ token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
2244
+ token.innerTokens.push(arg.source.accept(this));
2245
+ return token;
2246
+ }
2247
+ visitUsingClause(arg) {
2248
+ const token = new SqlPrintToken(SqlPrintTokenType.keyword, 'using', SqlPrintTokenContainerType.UsingClause);
2249
+ if (arg.sources.length > 0) {
2250
+ // Attach the first USING source directly after the keyword.
2251
+ token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
2252
+ for (let i = 0; i < arg.sources.length; i++) {
2253
+ if (i > 0) {
2254
+ // Separate subsequent sources with comma and space for clarity.
2255
+ token.innerTokens.push(...SqlPrintTokenParser.commaSpaceTokens());
2256
+ }
2257
+ token.innerTokens.push(this.visit(arg.sources[i]));
2258
+ }
2259
+ }
2260
+ return token;
2261
+ }
2262
+ visitMergeQuery(arg) {
2263
+ const token = new SqlPrintToken(SqlPrintTokenType.container, '', SqlPrintTokenContainerType.MergeQuery);
2264
+ if (arg.withClause) {
2265
+ token.innerTokens.push(arg.withClause.accept(this));
2266
+ }
2267
+ token.innerTokens.push(new SqlPrintToken(SqlPrintTokenType.keyword, 'merge into'));
2268
+ token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
2269
+ token.innerTokens.push(arg.target.accept(this));
2270
+ token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
2271
+ token.innerTokens.push(new SqlPrintToken(SqlPrintTokenType.keyword, 'using'));
2272
+ token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
2273
+ token.innerTokens.push(arg.source.accept(this));
2274
+ token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
2275
+ const onClauseToken = new SqlPrintToken(SqlPrintTokenType.container, '', SqlPrintTokenContainerType.JoinOnClause);
2276
+ onClauseToken.innerTokens.push(new SqlPrintToken(SqlPrintTokenType.keyword, 'on'));
2277
+ onClauseToken.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
2278
+ onClauseToken.innerTokens.push(arg.onCondition.accept(this));
2279
+ token.innerTokens.push(onClauseToken);
2280
+ for (const clause of arg.whenClauses) {
2281
+ token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
2282
+ token.innerTokens.push(clause.accept(this));
2283
+ }
2284
+ return token;
2285
+ }
2286
+ visitMergeWhenClause(arg) {
2287
+ const token = new SqlPrintToken(SqlPrintTokenType.container, '', SqlPrintTokenContainerType.MergeWhenClause);
2288
+ token.innerTokens.push(new SqlPrintToken(SqlPrintTokenType.keyword, this.mergeMatchTypeToKeyword(arg.matchType)));
2289
+ if (arg.condition) {
2290
+ token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
2291
+ token.innerTokens.push(new SqlPrintToken(SqlPrintTokenType.keyword, 'and'));
2292
+ token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
2293
+ token.innerTokens.push(arg.condition.accept(this));
2294
+ }
2295
+ const thenLeadingComments = arg.getThenLeadingComments();
2296
+ const thenKeywordToken = new SqlPrintToken(SqlPrintTokenType.keyword, 'then');
2297
+ if (thenLeadingComments.length > 0) {
2298
+ token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
2299
+ const commentBlocks = this.createCommentBlocks(thenLeadingComments);
2300
+ token.innerTokens.push(...commentBlocks);
2301
+ token.innerTokens.push(thenKeywordToken);
2302
+ }
2303
+ else {
2304
+ token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
2305
+ token.innerTokens.push(thenKeywordToken);
2306
+ }
2307
+ token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
2308
+ token.innerTokens.push(arg.action.accept(this));
2309
+ return token;
2310
+ }
2311
+ visitMergeUpdateAction(arg) {
2312
+ const token = new SqlPrintToken(SqlPrintTokenType.container, '', SqlPrintTokenContainerType.MergeUpdateAction);
2313
+ token.innerTokens.push(new SqlPrintToken(SqlPrintTokenType.keyword, 'update'));
2314
+ token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
2315
+ token.innerTokens.push(arg.setClause.accept(this));
2316
+ if (arg.whereClause) {
2317
+ token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
2318
+ token.innerTokens.push(arg.whereClause.accept(this));
2319
+ }
2320
+ return token;
2321
+ }
2322
+ visitMergeDeleteAction(arg) {
2323
+ const token = new SqlPrintToken(SqlPrintTokenType.container, '', SqlPrintTokenContainerType.MergeDeleteAction);
2324
+ token.innerTokens.push(new SqlPrintToken(SqlPrintTokenType.keyword, 'delete'));
2325
+ if (arg.whereClause) {
2326
+ token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
2327
+ token.innerTokens.push(arg.whereClause.accept(this));
2328
+ }
2329
+ return token;
2330
+ }
2331
+ visitMergeInsertAction(arg) {
2332
+ const token = new SqlPrintToken(SqlPrintTokenType.container, '', SqlPrintTokenContainerType.MergeInsertAction);
2333
+ token.innerTokens.push(new SqlPrintToken(SqlPrintTokenType.keyword, 'insert'));
2334
+ if (arg.columns && arg.columns.length > 0) {
2335
+ token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
2336
+ token.innerTokens.push(SqlPrintTokenParser.PAREN_OPEN_TOKEN);
2337
+ for (let i = 0; i < arg.columns.length; i++) {
2338
+ if (i > 0) {
2339
+ token.innerTokens.push(...SqlPrintTokenParser.commaSpaceTokens());
2340
+ }
2341
+ token.innerTokens.push(arg.columns[i].accept(this));
2342
+ }
2343
+ token.innerTokens.push(SqlPrintTokenParser.PAREN_CLOSE_TOKEN);
2344
+ }
2345
+ if (arg.defaultValues) {
2346
+ token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
2347
+ token.innerTokens.push(new SqlPrintToken(SqlPrintTokenType.keyword, 'default values'));
2348
+ return token;
2349
+ }
2350
+ if (arg.values) {
2351
+ const leadingValuesComments = arg.getValuesLeadingComments();
2352
+ if (leadingValuesComments.length > 0) {
2353
+ token.innerTokens.push(new SqlPrintToken(SqlPrintTokenType.commentNewline, ''));
2354
+ const commentBlocks = this.createCommentBlocks(leadingValuesComments);
2355
+ token.innerTokens.push(...commentBlocks);
2356
+ }
2357
+ else {
2358
+ token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
2359
+ }
2360
+ const valuesKeywordToken = new SqlPrintToken(SqlPrintTokenType.keyword, 'values');
2361
+ token.innerTokens.push(valuesKeywordToken);
2362
+ token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
2363
+ token.innerTokens.push(SqlPrintTokenParser.PAREN_OPEN_TOKEN);
2364
+ token.innerTokens.push(arg.values.accept(this));
2365
+ token.innerTokens.push(SqlPrintTokenParser.PAREN_CLOSE_TOKEN);
2366
+ }
2367
+ return token;
2368
+ }
2369
+ visitMergeDoNothingAction(_) {
2370
+ return new SqlPrintToken(SqlPrintTokenType.keyword, 'do nothing', SqlPrintTokenContainerType.MergeDoNothingAction);
2371
+ }
2372
+ mergeMatchTypeToKeyword(matchType) {
2373
+ switch (matchType) {
2374
+ case 'matched':
2375
+ return 'when matched';
2376
+ case 'not_matched':
2377
+ return 'when not matched';
2378
+ case 'not_matched_by_source':
2379
+ return 'when not matched by source';
2380
+ case 'not_matched_by_target':
2381
+ return 'when not matched by target';
2382
+ default:
2383
+ return 'when';
2384
+ }
2385
+ }
2386
+ visitUpdateQuery(arg) {
2387
+ const token = new SqlPrintToken(SqlPrintTokenType.container, '', SqlPrintTokenContainerType.UpdateQuery);
2388
+ if (arg.withClause) {
2389
+ token.innerTokens.push(arg.withClause.accept(this));
2390
+ }
2391
+ token.innerTokens.push(arg.updateClause.accept(this));
2392
+ token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
2393
+ token.innerTokens.push(arg.setClause.accept(this));
1969
2394
  if (arg.fromClause) {
1970
2395
  token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
1971
2396
  token.innerTokens.push(arg.fromClause.accept(this));
@@ -1987,7 +2412,7 @@ export class SqlPrintTokenParser {
1987
2412
  return token;
1988
2413
  }
1989
2414
  visitSetClause(arg) {
1990
- const token = new SqlPrintToken(SqlPrintTokenType.keyword, 'set', SqlPrintTokenContainerType.SelectClause);
2415
+ const token = new SqlPrintToken(SqlPrintTokenType.keyword, 'set', SqlPrintTokenContainerType.SetClause);
1991
2416
  token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
1992
2417
  for (let i = 0; i < arg.items.length; i++) {
1993
2418
  if (i > 0) {
@@ -2018,15 +2443,481 @@ export class SqlPrintTokenParser {
2018
2443
  return token;
2019
2444
  }
2020
2445
  visitCreateTableQuery(arg) {
2021
- const token = new SqlPrintToken(SqlPrintTokenType.keyword, arg.isTemporary ? 'create temporary table' : 'create table', SqlPrintTokenContainerType.CreateTableQuery);
2446
+ var _a;
2447
+ const baseKeyword = arg.isTemporary ? 'create temporary table' : 'create table';
2448
+ let keywordText = arg.ifNotExists ? `${baseKeyword} if not exists` : baseKeyword;
2449
+ const token = new SqlPrintToken(SqlPrintTokenType.keyword, keywordText, SqlPrintTokenContainerType.CreateTableQuery);
2022
2450
  token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
2023
- token.innerTokens.push(arg.tableName.accept(this));
2451
+ const qualifiedName = new QualifiedName((_a = arg.namespaces) !== null && _a !== void 0 ? _a : null, arg.tableName);
2452
+ token.innerTokens.push(qualifiedName.accept(this));
2453
+ const definitionEntries = [...arg.columns, ...arg.tableConstraints];
2454
+ if (definitionEntries.length > 0) {
2455
+ token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
2456
+ token.innerTokens.push(SqlPrintTokenParser.PAREN_OPEN_TOKEN);
2457
+ const definitionToken = new SqlPrintToken(SqlPrintTokenType.container, '', SqlPrintTokenContainerType.CreateTableDefinition);
2458
+ for (let i = 0; i < definitionEntries.length; i++) {
2459
+ if (i > 0) {
2460
+ definitionToken.innerTokens.push(...SqlPrintTokenParser.commaSpaceTokens());
2461
+ }
2462
+ definitionToken.innerTokens.push(definitionEntries[i].accept(this));
2463
+ }
2464
+ token.innerTokens.push(definitionToken);
2465
+ token.innerTokens.push(SqlPrintTokenParser.PAREN_CLOSE_TOKEN);
2466
+ }
2467
+ if (arg.tableOptions) {
2468
+ token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
2469
+ token.innerTokens.push(arg.tableOptions.accept(this));
2470
+ }
2024
2471
  if (arg.asSelectQuery) {
2025
2472
  token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
2026
2473
  token.innerTokens.push(new SqlPrintToken(SqlPrintTokenType.keyword, 'as'));
2027
2474
  token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
2028
2475
  token.innerTokens.push(arg.asSelectQuery.accept(this));
2029
2476
  }
2477
+ if (arg.withDataOption) {
2478
+ // Reconstruct WITH [NO] DATA clause to mirror PostgreSQL CREATE TABLE semantics.
2479
+ token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
2480
+ token.innerTokens.push(new SqlPrintToken(SqlPrintTokenType.keyword, 'with'));
2481
+ token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
2482
+ if (arg.withDataOption === 'with-no-data') {
2483
+ token.innerTokens.push(new SqlPrintToken(SqlPrintTokenType.keyword, 'no'));
2484
+ token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
2485
+ }
2486
+ token.innerTokens.push(new SqlPrintToken(SqlPrintTokenType.keyword, 'data'));
2487
+ }
2488
+ return token;
2489
+ }
2490
+ visitTableColumnDefinition(arg) {
2491
+ const token = new SqlPrintToken(SqlPrintTokenType.container, '', SqlPrintTokenContainerType.TableColumnDefinition);
2492
+ token.innerTokens.push(arg.name.accept(this));
2493
+ if (arg.dataType) {
2494
+ token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
2495
+ token.innerTokens.push(arg.dataType.accept(this));
2496
+ }
2497
+ for (const constraint of arg.constraints) {
2498
+ token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
2499
+ token.innerTokens.push(constraint.accept(this));
2500
+ }
2501
+ return token;
2502
+ }
2503
+ visitColumnConstraintDefinition(arg) {
2504
+ const token = new SqlPrintToken(SqlPrintTokenType.container, '', SqlPrintTokenContainerType.ColumnConstraintDefinition);
2505
+ if (arg.constraintName) {
2506
+ token.innerTokens.push(new SqlPrintToken(SqlPrintTokenType.keyword, 'constraint'));
2507
+ token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
2508
+ token.innerTokens.push(arg.constraintName.accept(this));
2509
+ }
2510
+ const appendKeyword = (text) => {
2511
+ if (token.innerTokens.length > 0) {
2512
+ token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
2513
+ }
2514
+ token.innerTokens.push(new SqlPrintToken(SqlPrintTokenType.keyword, text));
2515
+ };
2516
+ const appendComponent = (component) => {
2517
+ if (token.innerTokens.length > 0) {
2518
+ token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
2519
+ }
2520
+ token.innerTokens.push(component.accept(this));
2521
+ };
2522
+ switch (arg.kind) {
2523
+ case 'not-null':
2524
+ appendKeyword('not null');
2525
+ break;
2526
+ case 'null':
2527
+ appendKeyword('null');
2528
+ break;
2529
+ case 'default':
2530
+ appendKeyword('default');
2531
+ if (arg.defaultValue) {
2532
+ token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
2533
+ token.innerTokens.push(arg.defaultValue.accept(this));
2534
+ }
2535
+ break;
2536
+ case 'primary-key':
2537
+ appendKeyword('primary key');
2538
+ break;
2539
+ case 'unique':
2540
+ appendKeyword('unique');
2541
+ break;
2542
+ case 'references':
2543
+ if (arg.reference) {
2544
+ appendComponent(arg.reference);
2545
+ }
2546
+ break;
2547
+ case 'check':
2548
+ if (arg.checkExpression) {
2549
+ appendKeyword('check');
2550
+ token.innerTokens.push(this.wrapWithParenExpression(arg.checkExpression));
2551
+ }
2552
+ break;
2553
+ case 'generated-always-identity':
2554
+ case 'generated-by-default-identity':
2555
+ case 'raw':
2556
+ if (arg.rawClause) {
2557
+ appendComponent(arg.rawClause);
2558
+ }
2559
+ break;
2560
+ }
2561
+ return token;
2562
+ }
2563
+ visitTableConstraintDefinition(arg) {
2564
+ var _a, _b, _c;
2565
+ const token = new SqlPrintToken(SqlPrintTokenType.container, '', SqlPrintTokenContainerType.TableConstraintDefinition);
2566
+ const appendKeyword = (text) => {
2567
+ if (token.innerTokens.length > 0) {
2568
+ token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
2569
+ }
2570
+ token.innerTokens.push(new SqlPrintToken(SqlPrintTokenType.keyword, text));
2571
+ };
2572
+ const appendComponent = (component) => {
2573
+ if (token.innerTokens.length > 0) {
2574
+ token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
2575
+ }
2576
+ token.innerTokens.push(component.accept(this));
2577
+ };
2578
+ const appendColumns = (columns) => {
2579
+ if (!columns || columns.length === 0) {
2580
+ return;
2581
+ }
2582
+ token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
2583
+ token.innerTokens.push(SqlPrintTokenParser.PAREN_OPEN_TOKEN);
2584
+ const listToken = new SqlPrintToken(SqlPrintTokenType.container, '', SqlPrintTokenContainerType.ValueList);
2585
+ for (let i = 0; i < columns.length; i++) {
2586
+ if (i > 0) {
2587
+ listToken.innerTokens.push(...SqlPrintTokenParser.commaSpaceTokens());
2588
+ }
2589
+ listToken.innerTokens.push(columns[i].accept(this));
2590
+ }
2591
+ token.innerTokens.push(listToken);
2592
+ token.innerTokens.push(SqlPrintTokenParser.PAREN_CLOSE_TOKEN);
2593
+ };
2594
+ const useMysqlConstraintStyle = this.constraintStyle === 'mysql';
2595
+ const inlineNameKinds = new Set(['primary-key', 'unique', 'foreign-key']);
2596
+ const shouldInlineConstraintName = useMysqlConstraintStyle && !!arg.constraintName && inlineNameKinds.has(arg.kind);
2597
+ if (arg.constraintName && !shouldInlineConstraintName) {
2598
+ appendKeyword('constraint');
2599
+ token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
2600
+ token.innerTokens.push(arg.constraintName.accept(this));
2601
+ }
2602
+ switch (arg.kind) {
2603
+ case 'primary-key':
2604
+ appendKeyword('primary key');
2605
+ if (shouldInlineConstraintName && arg.constraintName) {
2606
+ token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
2607
+ token.innerTokens.push(arg.constraintName.accept(this));
2608
+ }
2609
+ appendColumns((_a = arg.columns) !== null && _a !== void 0 ? _a : []);
2610
+ break;
2611
+ case 'unique':
2612
+ if (useMysqlConstraintStyle) {
2613
+ appendKeyword('unique key');
2614
+ if (shouldInlineConstraintName && arg.constraintName) {
2615
+ token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
2616
+ token.innerTokens.push(arg.constraintName.accept(this));
2617
+ }
2618
+ }
2619
+ else {
2620
+ appendKeyword('unique');
2621
+ }
2622
+ appendColumns((_b = arg.columns) !== null && _b !== void 0 ? _b : []);
2623
+ break;
2624
+ case 'foreign-key':
2625
+ appendKeyword('foreign key');
2626
+ if (shouldInlineConstraintName && arg.constraintName) {
2627
+ token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
2628
+ token.innerTokens.push(arg.constraintName.accept(this));
2629
+ }
2630
+ appendColumns((_c = arg.columns) !== null && _c !== void 0 ? _c : []);
2631
+ if (arg.reference) {
2632
+ token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
2633
+ token.innerTokens.push(arg.reference.accept(this));
2634
+ }
2635
+ break;
2636
+ case 'check':
2637
+ if (arg.checkExpression) {
2638
+ appendKeyword('check');
2639
+ token.innerTokens.push(this.wrapWithParenExpression(arg.checkExpression));
2640
+ }
2641
+ break;
2642
+ case 'raw':
2643
+ if (arg.rawClause) {
2644
+ appendComponent(arg.rawClause);
2645
+ }
2646
+ break;
2647
+ }
2648
+ return token;
2649
+ }
2650
+ wrapWithParenExpression(expression) {
2651
+ // Reuse existing parentheses groups to avoid double-wrapping when callers already provided them.
2652
+ if (expression instanceof ParenExpression) {
2653
+ return this.visit(expression);
2654
+ }
2655
+ // Synthesize a ParenExpression wrapper so nested boolean groups render with consistent indentation.
2656
+ const synthetic = new ParenExpression(expression);
2657
+ return this.visit(synthetic);
2658
+ }
2659
+ visitReferenceDefinition(arg) {
2660
+ const token = new SqlPrintToken(SqlPrintTokenType.container, '', SqlPrintTokenContainerType.ReferenceDefinition);
2661
+ token.innerTokens.push(new SqlPrintToken(SqlPrintTokenType.keyword, 'references'));
2662
+ token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
2663
+ token.innerTokens.push(arg.targetTable.accept(this));
2664
+ if (arg.columns && arg.columns.length > 0) {
2665
+ token.innerTokens.push(SqlPrintTokenParser.PAREN_OPEN_TOKEN);
2666
+ const columnList = new SqlPrintToken(SqlPrintTokenType.container, '', SqlPrintTokenContainerType.ValueList);
2667
+ for (let i = 0; i < arg.columns.length; i++) {
2668
+ if (i > 0) {
2669
+ columnList.innerTokens.push(...SqlPrintTokenParser.commaSpaceTokens());
2670
+ }
2671
+ columnList.innerTokens.push(arg.columns[i].accept(this));
2672
+ }
2673
+ token.innerTokens.push(columnList);
2674
+ token.innerTokens.push(SqlPrintTokenParser.PAREN_CLOSE_TOKEN);
2675
+ }
2676
+ if (arg.matchType) {
2677
+ token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
2678
+ token.innerTokens.push(new SqlPrintToken(SqlPrintTokenType.keyword, `match ${arg.matchType}`));
2679
+ }
2680
+ if (arg.onDelete) {
2681
+ token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
2682
+ token.innerTokens.push(new SqlPrintToken(SqlPrintTokenType.keyword, 'on delete'));
2683
+ token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
2684
+ token.innerTokens.push(new SqlPrintToken(SqlPrintTokenType.keyword, arg.onDelete));
2685
+ }
2686
+ if (arg.onUpdate) {
2687
+ token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
2688
+ token.innerTokens.push(new SqlPrintToken(SqlPrintTokenType.keyword, 'on update'));
2689
+ token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
2690
+ token.innerTokens.push(new SqlPrintToken(SqlPrintTokenType.keyword, arg.onUpdate));
2691
+ }
2692
+ if (arg.deferrable === 'deferrable') {
2693
+ token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
2694
+ token.innerTokens.push(new SqlPrintToken(SqlPrintTokenType.keyword, 'deferrable'));
2695
+ }
2696
+ else if (arg.deferrable === 'not deferrable') {
2697
+ token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
2698
+ token.innerTokens.push(new SqlPrintToken(SqlPrintTokenType.keyword, 'not deferrable'));
2699
+ }
2700
+ if (arg.initially === 'immediate') {
2701
+ token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
2702
+ token.innerTokens.push(new SqlPrintToken(SqlPrintTokenType.keyword, 'initially immediate'));
2703
+ }
2704
+ else if (arg.initially === 'deferred') {
2705
+ token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
2706
+ token.innerTokens.push(new SqlPrintToken(SqlPrintTokenType.keyword, 'initially deferred'));
2707
+ }
2708
+ return token;
2709
+ }
2710
+ visitCreateIndexStatement(arg) {
2711
+ const keywordParts = ['create'];
2712
+ if (arg.unique) {
2713
+ keywordParts.push('unique');
2714
+ }
2715
+ keywordParts.push('index');
2716
+ if (arg.concurrently) {
2717
+ keywordParts.push('concurrently');
2718
+ }
2719
+ if (arg.ifNotExists) {
2720
+ keywordParts.push('if not exists');
2721
+ }
2722
+ const token = new SqlPrintToken(SqlPrintTokenType.keyword, keywordParts.join(' '), SqlPrintTokenContainerType.CreateIndexStatement);
2723
+ token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
2724
+ token.innerTokens.push(arg.indexName.accept(this));
2725
+ token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
2726
+ token.innerTokens.push(new SqlPrintToken(SqlPrintTokenType.keyword, 'on'));
2727
+ token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
2728
+ token.innerTokens.push(arg.tableName.accept(this));
2729
+ if (arg.usingMethod) {
2730
+ token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
2731
+ token.innerTokens.push(new SqlPrintToken(SqlPrintTokenType.keyword, 'using'));
2732
+ token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
2733
+ token.innerTokens.push(arg.usingMethod.accept(this));
2734
+ }
2735
+ token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
2736
+ token.innerTokens.push(SqlPrintTokenParser.PAREN_OPEN_TOKEN);
2737
+ const columnList = new SqlPrintToken(SqlPrintTokenType.container, '', SqlPrintTokenContainerType.IndexColumnList);
2738
+ for (let i = 0; i < arg.columns.length; i++) {
2739
+ if (i > 0) {
2740
+ columnList.innerTokens.push(...SqlPrintTokenParser.commaSpaceTokens());
2741
+ }
2742
+ columnList.innerTokens.push(arg.columns[i].accept(this));
2743
+ }
2744
+ token.innerTokens.push(columnList);
2745
+ token.innerTokens.push(SqlPrintTokenParser.PAREN_CLOSE_TOKEN);
2746
+ if (arg.include && arg.include.length > 0) {
2747
+ token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
2748
+ token.innerTokens.push(new SqlPrintToken(SqlPrintTokenType.keyword, 'include'));
2749
+ token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
2750
+ token.innerTokens.push(SqlPrintTokenParser.PAREN_OPEN_TOKEN);
2751
+ const includeList = new SqlPrintToken(SqlPrintTokenType.container, '', SqlPrintTokenContainerType.ValueList);
2752
+ for (let i = 0; i < arg.include.length; i++) {
2753
+ if (i > 0) {
2754
+ includeList.innerTokens.push(...SqlPrintTokenParser.commaSpaceTokens());
2755
+ }
2756
+ includeList.innerTokens.push(arg.include[i].accept(this));
2757
+ }
2758
+ token.innerTokens.push(includeList);
2759
+ token.innerTokens.push(SqlPrintTokenParser.PAREN_CLOSE_TOKEN);
2760
+ }
2761
+ if (arg.withOptions) {
2762
+ token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
2763
+ token.innerTokens.push(arg.withOptions.accept(this));
2764
+ }
2765
+ if (arg.tablespace) {
2766
+ token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
2767
+ token.innerTokens.push(new SqlPrintToken(SqlPrintTokenType.keyword, 'tablespace'));
2768
+ token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
2769
+ token.innerTokens.push(arg.tablespace.accept(this));
2770
+ }
2771
+ if (arg.where) {
2772
+ token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
2773
+ token.innerTokens.push(new SqlPrintToken(SqlPrintTokenType.keyword, 'where'));
2774
+ token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
2775
+ token.innerTokens.push(this.visit(arg.where));
2776
+ }
2777
+ return token;
2778
+ }
2779
+ visitIndexColumnDefinition(arg) {
2780
+ const token = new SqlPrintToken(SqlPrintTokenType.container, '', SqlPrintTokenContainerType.IndexColumnDefinition);
2781
+ token.innerTokens.push(this.visit(arg.expression));
2782
+ if (arg.collation) {
2783
+ token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
2784
+ token.innerTokens.push(new SqlPrintToken(SqlPrintTokenType.keyword, 'collate'));
2785
+ token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
2786
+ token.innerTokens.push(arg.collation.accept(this));
2787
+ }
2788
+ if (arg.operatorClass) {
2789
+ token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
2790
+ token.innerTokens.push(arg.operatorClass.accept(this));
2791
+ }
2792
+ if (arg.sortOrder) {
2793
+ token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
2794
+ token.innerTokens.push(new SqlPrintToken(SqlPrintTokenType.keyword, arg.sortOrder));
2795
+ }
2796
+ if (arg.nullsOrder) {
2797
+ token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
2798
+ token.innerTokens.push(new SqlPrintToken(SqlPrintTokenType.keyword, `nulls ${arg.nullsOrder}`));
2799
+ }
2800
+ return token;
2801
+ }
2802
+ visitDropTableStatement(arg) {
2803
+ const keyword = arg.ifExists ? 'drop table if exists' : 'drop table';
2804
+ const token = new SqlPrintToken(SqlPrintTokenType.keyword, keyword, SqlPrintTokenContainerType.DropTableStatement);
2805
+ token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
2806
+ const tableList = new SqlPrintToken(SqlPrintTokenType.container, '', SqlPrintTokenContainerType.ValueList);
2807
+ for (let i = 0; i < arg.tables.length; i++) {
2808
+ if (i > 0) {
2809
+ tableList.innerTokens.push(...SqlPrintTokenParser.commaSpaceTokens());
2810
+ }
2811
+ tableList.innerTokens.push(arg.tables[i].accept(this));
2812
+ }
2813
+ token.innerTokens.push(tableList);
2814
+ if (arg.behavior) {
2815
+ token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
2816
+ token.innerTokens.push(new SqlPrintToken(SqlPrintTokenType.keyword, arg.behavior));
2817
+ }
2818
+ return token;
2819
+ }
2820
+ visitDropIndexStatement(arg) {
2821
+ const keywordParts = ['drop', 'index'];
2822
+ if (arg.concurrently) {
2823
+ keywordParts.push('concurrently');
2824
+ }
2825
+ if (arg.ifExists) {
2826
+ keywordParts.push('if exists');
2827
+ }
2828
+ const token = new SqlPrintToken(SqlPrintTokenType.keyword, keywordParts.join(' '), SqlPrintTokenContainerType.DropIndexStatement);
2829
+ token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
2830
+ const indexList = new SqlPrintToken(SqlPrintTokenType.container, '', SqlPrintTokenContainerType.ValueList);
2831
+ for (let i = 0; i < arg.indexNames.length; i++) {
2832
+ if (i > 0) {
2833
+ indexList.innerTokens.push(...SqlPrintTokenParser.commaSpaceTokens());
2834
+ }
2835
+ indexList.innerTokens.push(arg.indexNames[i].accept(this));
2836
+ }
2837
+ token.innerTokens.push(indexList);
2838
+ if (arg.behavior) {
2839
+ token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
2840
+ token.innerTokens.push(new SqlPrintToken(SqlPrintTokenType.keyword, arg.behavior));
2841
+ }
2842
+ return token;
2843
+ }
2844
+ visitAlterTableStatement(arg) {
2845
+ const keywordParts = ['alter', 'table'];
2846
+ if (arg.ifExists) {
2847
+ keywordParts.push('if exists');
2848
+ }
2849
+ if (arg.only) {
2850
+ keywordParts.push('only');
2851
+ }
2852
+ const token = new SqlPrintToken(SqlPrintTokenType.keyword, keywordParts.join(' '), SqlPrintTokenContainerType.AlterTableStatement);
2853
+ token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
2854
+ token.innerTokens.push(arg.table.accept(this));
2855
+ for (let i = 0; i < arg.actions.length; i++) {
2856
+ if (i === 0) {
2857
+ token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
2858
+ }
2859
+ else {
2860
+ token.innerTokens.push(SqlPrintTokenParser.COMMA_TOKEN);
2861
+ token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
2862
+ }
2863
+ token.innerTokens.push(arg.actions[i].accept(this));
2864
+ }
2865
+ return token;
2866
+ }
2867
+ visitAlterTableAddConstraint(arg) {
2868
+ const keyword = arg.ifNotExists ? 'add if not exists' : 'add';
2869
+ const token = new SqlPrintToken(SqlPrintTokenType.container, '', SqlPrintTokenContainerType.AlterTableAddConstraint);
2870
+ token.innerTokens.push(new SqlPrintToken(SqlPrintTokenType.keyword, keyword));
2871
+ token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
2872
+ token.innerTokens.push(arg.constraint.accept(this));
2873
+ if (arg.notValid) {
2874
+ token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
2875
+ token.innerTokens.push(new SqlPrintToken(SqlPrintTokenType.keyword, 'not valid'));
2876
+ }
2877
+ return token;
2878
+ }
2879
+ visitAlterTableDropConstraint(arg) {
2880
+ let keyword = 'drop constraint';
2881
+ if (arg.ifExists) {
2882
+ keyword += ' if exists';
2883
+ }
2884
+ const token = new SqlPrintToken(SqlPrintTokenType.container, '', SqlPrintTokenContainerType.AlterTableDropConstraint);
2885
+ token.innerTokens.push(new SqlPrintToken(SqlPrintTokenType.keyword, keyword));
2886
+ token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
2887
+ token.innerTokens.push(arg.constraintName.accept(this));
2888
+ if (arg.behavior) {
2889
+ token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
2890
+ token.innerTokens.push(new SqlPrintToken(SqlPrintTokenType.keyword, arg.behavior));
2891
+ }
2892
+ return token;
2893
+ }
2894
+ visitAlterTableDropColumn(arg) {
2895
+ let keyword = 'drop column';
2896
+ if (arg.ifExists) {
2897
+ keyword += ' if exists';
2898
+ }
2899
+ const token = new SqlPrintToken(SqlPrintTokenType.container, '', SqlPrintTokenContainerType.AlterTableDropColumn);
2900
+ token.innerTokens.push(new SqlPrintToken(SqlPrintTokenType.keyword, keyword));
2901
+ token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
2902
+ token.innerTokens.push(arg.columnName.accept(this));
2903
+ if (arg.behavior) {
2904
+ token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
2905
+ token.innerTokens.push(new SqlPrintToken(SqlPrintTokenType.keyword, arg.behavior));
2906
+ }
2907
+ return token;
2908
+ }
2909
+ visitDropConstraintStatement(arg) {
2910
+ let keyword = 'drop constraint';
2911
+ if (arg.ifExists) {
2912
+ keyword += ' if exists';
2913
+ }
2914
+ const token = new SqlPrintToken(SqlPrintTokenType.keyword, keyword, SqlPrintTokenContainerType.DropConstraintStatement);
2915
+ token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
2916
+ token.innerTokens.push(arg.constraintName.accept(this));
2917
+ if (arg.behavior) {
2918
+ token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
2919
+ token.innerTokens.push(new SqlPrintToken(SqlPrintTokenType.keyword, arg.behavior));
2920
+ }
2030
2921
  return token;
2031
2922
  }
2032
2923
  }