spark-sql-language-server 0.0.1-beta.5 → 0.2.0-beta.0

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 (740) hide show
  1. package/out/sparksql-server-worker.js +1 -1
  2. package/out/sparksql-server-worker.js.map +1 -1
  3. package/out-tsc/assets/built-in-functions.d.ts +2 -0
  4. package/out-tsc/assets/built-in-functions.d.ts.map +1 -0
  5. package/out-tsc/assets/built-in-functions.js +4 -2
  6. package/out-tsc/assets/built-in-functions.js.map +1 -1
  7. package/out-tsc/completion-parser.d.ts +11 -0
  8. package/out-tsc/completion-parser.d.ts.map +1 -0
  9. package/out-tsc/completion-parser.js +148 -0
  10. package/out-tsc/completion-parser.js.map +1 -0
  11. package/out-tsc/constants.d.ts +9 -0
  12. package/out-tsc/constants.d.ts.map +1 -0
  13. package/out-tsc/constants.js +12 -0
  14. package/out-tsc/constants.js.map +1 -0
  15. package/out-tsc/cursor.d.ts +10 -0
  16. package/out-tsc/cursor.d.ts.map +1 -0
  17. package/out-tsc/cursor.js +3 -0
  18. package/out-tsc/cursor.js.map +1 -1
  19. package/out-tsc/execute-command.d.ts +7 -0
  20. package/out-tsc/execute-command.d.ts.map +1 -0
  21. package/out-tsc/execute-command.js +78 -0
  22. package/out-tsc/execute-command.js.map +1 -0
  23. package/out-tsc/execute-commands.d.ts +1 -0
  24. package/out-tsc/execute-commands.d.ts.map +1 -0
  25. package/out-tsc/execute-commands.js +3 -4
  26. package/out-tsc/execute-commands.js.map +1 -1
  27. package/out-tsc/formatter/boundary-writer.d.ts +30 -0
  28. package/out-tsc/formatter/boundary-writer.d.ts.map +1 -0
  29. package/out-tsc/formatter/boundary-writer.js +47 -0
  30. package/out-tsc/formatter/boundary-writer.js.map +1 -0
  31. package/out-tsc/formatter/core/comment-helper.d.ts +11 -0
  32. package/out-tsc/formatter/core/comment-helper.d.ts.map +1 -0
  33. package/out-tsc/formatter/core/comment-helper.js +139 -0
  34. package/out-tsc/formatter/core/comment-helper.js.map +1 -0
  35. package/out-tsc/formatter/core/edit-collector.d.ts +110 -0
  36. package/out-tsc/formatter/core/edit-collector.d.ts.map +1 -0
  37. package/out-tsc/formatter/core/edit-collector.js +159 -0
  38. package/out-tsc/formatter/core/edit-collector.js.map +1 -0
  39. package/out-tsc/formatter/core/formatting-context.d.ts +183 -0
  40. package/out-tsc/formatter/core/formatting-context.d.ts.map +1 -0
  41. package/out-tsc/formatter/core/formatting-context.js +294 -0
  42. package/out-tsc/formatter/core/formatting-context.js.map +1 -0
  43. package/out-tsc/formatter/core/index.d.ts +25 -0
  44. package/out-tsc/formatter/core/index.d.ts.map +1 -0
  45. package/out-tsc/formatter/core/index.js +57 -0
  46. package/out-tsc/formatter/core/index.js.map +1 -0
  47. package/out-tsc/formatter/core/pipeline/formatting-pipeline.d.ts +116 -0
  48. package/out-tsc/formatter/core/pipeline/formatting-pipeline.d.ts.map +1 -0
  49. package/out-tsc/formatter/core/pipeline/formatting-pipeline.js +237 -0
  50. package/out-tsc/formatter/core/pipeline/formatting-pipeline.js.map +1 -0
  51. package/out-tsc/formatter/core/pipeline/index.d.ts +12 -0
  52. package/out-tsc/formatter/core/pipeline/index.d.ts.map +1 -0
  53. package/out-tsc/formatter/core/pipeline/index.js +19 -0
  54. package/out-tsc/formatter/core/pipeline/index.js.map +1 -0
  55. package/out-tsc/formatter/core/pipeline/statement-separation.d.ts +5 -0
  56. package/out-tsc/formatter/core/pipeline/statement-separation.d.ts.map +1 -0
  57. package/out-tsc/formatter/core/pipeline/statement-separation.js +149 -0
  58. package/out-tsc/formatter/core/pipeline/statement-separation.js.map +1 -0
  59. package/out-tsc/formatter/core/rules/index.d.ts +11 -0
  60. package/out-tsc/formatter/core/rules/index.d.ts.map +1 -0
  61. package/out-tsc/formatter/core/rules/index.js +29 -0
  62. package/out-tsc/formatter/core/rules/index.js.map +1 -0
  63. package/out-tsc/formatter/core/rules/newline-rules.d.ts +169 -0
  64. package/out-tsc/formatter/core/rules/newline-rules.d.ts.map +1 -0
  65. package/out-tsc/formatter/core/rules/newline-rules.js +246 -0
  66. package/out-tsc/formatter/core/rules/newline-rules.js.map +1 -0
  67. package/out-tsc/formatter/core/rules/spacing-rules.d.ts +150 -0
  68. package/out-tsc/formatter/core/rules/spacing-rules.d.ts.map +1 -0
  69. package/out-tsc/formatter/core/rules/spacing-rules.js +219 -0
  70. package/out-tsc/formatter/core/rules/spacing-rules.js.map +1 -0
  71. package/out-tsc/formatter/core/strategy-bridge.d.ts +56 -0
  72. package/out-tsc/formatter/core/strategy-bridge.d.ts.map +1 -0
  73. package/out-tsc/formatter/core/strategy-bridge.js +159 -0
  74. package/out-tsc/formatter/core/strategy-bridge.js.map +1 -0
  75. package/out-tsc/formatter/core/strategy-interface.d.ts +123 -0
  76. package/out-tsc/formatter/core/strategy-interface.d.ts.map +1 -0
  77. package/out-tsc/formatter/core/strategy-interface.js +83 -0
  78. package/out-tsc/formatter/core/strategy-interface.js.map +1 -0
  79. package/out-tsc/formatter/core/token-helper.d.ts +12 -0
  80. package/out-tsc/formatter/core/token-helper.d.ts.map +1 -0
  81. package/out-tsc/formatter/core/token-helper.js +79 -0
  82. package/out-tsc/formatter/core/token-helper.js.map +1 -0
  83. package/out-tsc/formatter/core/unicode-utils.d.ts +107 -0
  84. package/out-tsc/formatter/core/unicode-utils.d.ts.map +1 -0
  85. package/out-tsc/formatter/core/unicode-utils.js +181 -0
  86. package/out-tsc/formatter/core/unicode-utils.js.map +1 -0
  87. package/out-tsc/formatter/core/whitespace-writer.d.ts +20 -0
  88. package/out-tsc/formatter/core/whitespace-writer.d.ts.map +1 -0
  89. package/out-tsc/formatter/core/whitespace-writer.js +86 -0
  90. package/out-tsc/formatter/core/whitespace-writer.js.map +1 -0
  91. package/out-tsc/formatter/formatter-adapter.d.ts +56 -0
  92. package/out-tsc/formatter/formatter-adapter.d.ts.map +1 -0
  93. package/out-tsc/formatter/formatter-adapter.js +719 -0
  94. package/out-tsc/formatter/formatter-adapter.js.map +1 -0
  95. package/out-tsc/formatter/index.d.ts +16 -0
  96. package/out-tsc/formatter/index.d.ts.map +1 -0
  97. package/out-tsc/formatter/index.js +43 -0
  98. package/out-tsc/formatter/index.js.map +1 -0
  99. package/out-tsc/formatter/pipe-step-classifier.d.ts +9 -0
  100. package/out-tsc/formatter/pipe-step-classifier.d.ts.map +1 -0
  101. package/out-tsc/formatter/pipe-step-classifier.js +49 -0
  102. package/out-tsc/formatter/pipe-step-classifier.js.map +1 -0
  103. package/out-tsc/formatter/state.d.ts +10 -0
  104. package/out-tsc/formatter/state.d.ts.map +1 -0
  105. package/out-tsc/formatter/state.js +12 -0
  106. package/out-tsc/formatter/state.js.map +1 -0
  107. package/out-tsc/formatter/strategies/block.strategy.d.ts +191 -0
  108. package/out-tsc/formatter/strategies/block.strategy.d.ts.map +1 -0
  109. package/out-tsc/formatter/strategies/block.strategy.js +238 -0
  110. package/out-tsc/formatter/strategies/block.strategy.js.map +1 -0
  111. package/out-tsc/formatter/strategies/clause-head-body.strategy.d.ts +17 -0
  112. package/out-tsc/formatter/strategies/clause-head-body.strategy.d.ts.map +1 -0
  113. package/out-tsc/formatter/strategies/clause-head-body.strategy.js +13 -0
  114. package/out-tsc/formatter/strategies/clause-head-body.strategy.js.map +1 -0
  115. package/out-tsc/formatter/strategies/ddl/alter-table-extended.strategy.d.ts +68 -0
  116. package/out-tsc/formatter/strategies/ddl/alter-table-extended.strategy.d.ts.map +1 -0
  117. package/out-tsc/formatter/strategies/ddl/alter-table-extended.strategy.js +242 -0
  118. package/out-tsc/formatter/strategies/ddl/alter-table-extended.strategy.js.map +1 -0
  119. package/out-tsc/formatter/strategies/ddl/alter-table.strategy.d.ts +146 -0
  120. package/out-tsc/formatter/strategies/ddl/alter-table.strategy.d.ts.map +1 -0
  121. package/out-tsc/formatter/strategies/ddl/alter-table.strategy.js +578 -0
  122. package/out-tsc/formatter/strategies/ddl/alter-table.strategy.js.map +1 -0
  123. package/out-tsc/formatter/strategies/ddl/create-table.strategy.d.ts +103 -0
  124. package/out-tsc/formatter/strategies/ddl/create-table.strategy.d.ts.map +1 -0
  125. package/out-tsc/formatter/strategies/ddl/create-table.strategy.js +659 -0
  126. package/out-tsc/formatter/strategies/ddl/create-table.strategy.js.map +1 -0
  127. package/out-tsc/formatter/strategies/ddl/create-view-function.strategy.d.ts +64 -0
  128. package/out-tsc/formatter/strategies/ddl/create-view-function.strategy.d.ts.map +1 -0
  129. package/out-tsc/formatter/strategies/ddl/create-view-function.strategy.js +402 -0
  130. package/out-tsc/formatter/strategies/ddl/create-view-function.strategy.js.map +1 -0
  131. package/out-tsc/formatter/strategies/ddl/drop-utility.strategy.d.ts +119 -0
  132. package/out-tsc/formatter/strategies/ddl/drop-utility.strategy.d.ts.map +1 -0
  133. package/out-tsc/formatter/strategies/ddl/drop-utility.strategy.js +863 -0
  134. package/out-tsc/formatter/strategies/ddl/drop-utility.strategy.js.map +1 -0
  135. package/out-tsc/formatter/strategies/ddl/index.d.ts +17 -0
  136. package/out-tsc/formatter/strategies/ddl/index.d.ts.map +1 -0
  137. package/out-tsc/formatter/strategies/ddl/index.js +57 -0
  138. package/out-tsc/formatter/strategies/ddl/index.js.map +1 -0
  139. package/out-tsc/formatter/strategies/ddl/namespace-catalog.strategy.d.ts +26 -0
  140. package/out-tsc/formatter/strategies/ddl/namespace-catalog.strategy.d.ts.map +1 -0
  141. package/out-tsc/formatter/strategies/ddl/namespace-catalog.strategy.js +77 -0
  142. package/out-tsc/formatter/strategies/ddl/namespace-catalog.strategy.js.map +1 -0
  143. package/out-tsc/formatter/strategies/ddl/pipeline.strategy.d.ts +99 -0
  144. package/out-tsc/formatter/strategies/ddl/pipeline.strategy.d.ts.map +1 -0
  145. package/out-tsc/formatter/strategies/ddl/pipeline.strategy.js +385 -0
  146. package/out-tsc/formatter/strategies/ddl/pipeline.strategy.js.map +1 -0
  147. package/out-tsc/formatter/strategies/ddl/set-reset-config.strategy.d.ts +48 -0
  148. package/out-tsc/formatter/strategies/ddl/set-reset-config.strategy.d.ts.map +1 -0
  149. package/out-tsc/formatter/strategies/ddl/set-reset-config.strategy.js +145 -0
  150. package/out-tsc/formatter/strategies/ddl/set-reset-config.strategy.js.map +1 -0
  151. package/out-tsc/formatter/strategies/ddl/show-utility.strategy.d.ts +71 -0
  152. package/out-tsc/formatter/strategies/ddl/show-utility.strategy.d.ts.map +1 -0
  153. package/out-tsc/formatter/strategies/ddl/show-utility.strategy.js +196 -0
  154. package/out-tsc/formatter/strategies/ddl/show-utility.strategy.js.map +1 -0
  155. package/out-tsc/formatter/strategies/dml/index.d.ts +10 -0
  156. package/out-tsc/formatter/strategies/dml/index.d.ts.map +1 -0
  157. package/out-tsc/formatter/strategies/dml/index.js +35 -0
  158. package/out-tsc/formatter/strategies/dml/index.js.map +1 -0
  159. package/out-tsc/formatter/strategies/dml/insert-update-delete.strategy.d.ts +113 -0
  160. package/out-tsc/formatter/strategies/dml/insert-update-delete.strategy.d.ts.map +1 -0
  161. package/out-tsc/formatter/strategies/dml/insert-update-delete.strategy.js +438 -0
  162. package/out-tsc/formatter/strategies/dml/insert-update-delete.strategy.js.map +1 -0
  163. package/out-tsc/formatter/strategies/dml/select-clause.strategy.d.ts +76 -0
  164. package/out-tsc/formatter/strategies/dml/select-clause.strategy.d.ts.map +1 -0
  165. package/out-tsc/formatter/strategies/dml/select-clause.strategy.js +480 -0
  166. package/out-tsc/formatter/strategies/dml/select-clause.strategy.js.map +1 -0
  167. package/out-tsc/formatter/strategies/expression/function-call.strategy.d.ts +50 -0
  168. package/out-tsc/formatter/strategies/expression/function-call.strategy.d.ts.map +1 -0
  169. package/out-tsc/formatter/strategies/expression/function-call.strategy.js +319 -0
  170. package/out-tsc/formatter/strategies/expression/function-call.strategy.js.map +1 -0
  171. package/out-tsc/formatter/strategies/expression/index.d.ts +18 -0
  172. package/out-tsc/formatter/strategies/expression/index.d.ts.map +1 -0
  173. package/out-tsc/formatter/strategies/expression/index.js +51 -0
  174. package/out-tsc/formatter/strategies/expression/index.js.map +1 -0
  175. package/out-tsc/formatter/strategies/expression/logical-comparison.strategy.d.ts +55 -0
  176. package/out-tsc/formatter/strategies/expression/logical-comparison.strategy.d.ts.map +1 -0
  177. package/out-tsc/formatter/strategies/expression/logical-comparison.strategy.js +266 -0
  178. package/out-tsc/formatter/strategies/expression/logical-comparison.strategy.js.map +1 -0
  179. package/out-tsc/formatter/strategies/expression/subquery-parenthesis.strategy.d.ts +38 -0
  180. package/out-tsc/formatter/strategies/expression/subquery-parenthesis.strategy.d.ts.map +1 -0
  181. package/out-tsc/formatter/strategies/expression/subquery-parenthesis.strategy.js +397 -0
  182. package/out-tsc/formatter/strategies/expression/subquery-parenthesis.strategy.js.map +1 -0
  183. package/out-tsc/formatter/strategies/function-call.strategy.d.ts +80 -0
  184. package/out-tsc/formatter/strategies/function-call.strategy.d.ts.map +1 -0
  185. package/out-tsc/formatter/strategies/function-call.strategy.js +136 -0
  186. package/out-tsc/formatter/strategies/function-call.strategy.js.map +1 -0
  187. package/out-tsc/formatter/strategies/index.d.ts +87 -0
  188. package/out-tsc/formatter/strategies/index.d.ts.map +1 -0
  189. package/out-tsc/formatter/strategies/index.js +121 -0
  190. package/out-tsc/formatter/strategies/index.js.map +1 -0
  191. package/out-tsc/formatter/strategies/join.strategy.d.ts +31 -0
  192. package/out-tsc/formatter/strategies/join.strategy.d.ts.map +1 -0
  193. package/out-tsc/formatter/strategies/join.strategy.js +29 -0
  194. package/out-tsc/formatter/strategies/join.strategy.js.map +1 -0
  195. package/out-tsc/formatter/strategies/keyword.strategy.d.ts +82 -0
  196. package/out-tsc/formatter/strategies/keyword.strategy.d.ts.map +1 -0
  197. package/out-tsc/formatter/strategies/keyword.strategy.js +129 -0
  198. package/out-tsc/formatter/strategies/keyword.strategy.js.map +1 -0
  199. package/out-tsc/formatter/strategies/list.strategy.d.ts +159 -0
  200. package/out-tsc/formatter/strategies/list.strategy.d.ts.map +1 -0
  201. package/out-tsc/formatter/strategies/list.strategy.js +193 -0
  202. package/out-tsc/formatter/strategies/list.strategy.js.map +1 -0
  203. package/out-tsc/formatter/strategies/pipe-aggregate.strategy.d.ts +24 -0
  204. package/out-tsc/formatter/strategies/pipe-aggregate.strategy.d.ts.map +1 -0
  205. package/out-tsc/formatter/strategies/pipe-aggregate.strategy.js +47 -0
  206. package/out-tsc/formatter/strategies/pipe-aggregate.strategy.js.map +1 -0
  207. package/out-tsc/formatter/strategies/pipe-drop.strategy.d.ts +21 -0
  208. package/out-tsc/formatter/strategies/pipe-drop.strategy.d.ts.map +1 -0
  209. package/out-tsc/formatter/strategies/pipe-drop.strategy.js +52 -0
  210. package/out-tsc/formatter/strategies/pipe-drop.strategy.js.map +1 -0
  211. package/out-tsc/formatter/strategies/pipe-extend.strategy.d.ts +21 -0
  212. package/out-tsc/formatter/strategies/pipe-extend.strategy.d.ts.map +1 -0
  213. package/out-tsc/formatter/strategies/pipe-extend.strategy.js +45 -0
  214. package/out-tsc/formatter/strategies/pipe-extend.strategy.js.map +1 -0
  215. package/out-tsc/formatter/strategies/pipe-join.strategy.d.ts +22 -0
  216. package/out-tsc/formatter/strategies/pipe-join.strategy.d.ts.map +1 -0
  217. package/out-tsc/formatter/strategies/pipe-join.strategy.js +42 -0
  218. package/out-tsc/formatter/strategies/pipe-join.strategy.js.map +1 -0
  219. package/out-tsc/formatter/strategies/pipe-pivot.strategy.d.ts +7 -0
  220. package/out-tsc/formatter/strategies/pipe-pivot.strategy.d.ts.map +1 -0
  221. package/out-tsc/formatter/strategies/pipe-pivot.strategy.js +34 -0
  222. package/out-tsc/formatter/strategies/pipe-pivot.strategy.js.map +1 -0
  223. package/out-tsc/formatter/strategies/pipe-query-organization.strategy.d.ts +7 -0
  224. package/out-tsc/formatter/strategies/pipe-query-organization.strategy.d.ts.map +1 -0
  225. package/out-tsc/formatter/strategies/pipe-query-organization.strategy.js +14 -0
  226. package/out-tsc/formatter/strategies/pipe-query-organization.strategy.js.map +1 -0
  227. package/out-tsc/formatter/strategies/pipe-sample.strategy.d.ts +7 -0
  228. package/out-tsc/formatter/strategies/pipe-sample.strategy.d.ts.map +1 -0
  229. package/out-tsc/formatter/strategies/pipe-sample.strategy.js +18 -0
  230. package/out-tsc/formatter/strategies/pipe-sample.strategy.js.map +1 -0
  231. package/out-tsc/formatter/strategies/pipe-select.strategy.d.ts +22 -0
  232. package/out-tsc/formatter/strategies/pipe-select.strategy.d.ts.map +1 -0
  233. package/out-tsc/formatter/strategies/pipe-select.strategy.js +51 -0
  234. package/out-tsc/formatter/strategies/pipe-select.strategy.js.map +1 -0
  235. package/out-tsc/formatter/strategies/pipe-set-operation.strategy.d.ts +7 -0
  236. package/out-tsc/formatter/strategies/pipe-set-operation.strategy.d.ts.map +1 -0
  237. package/out-tsc/formatter/strategies/pipe-set-operation.strategy.js +30 -0
  238. package/out-tsc/formatter/strategies/pipe-set-operation.strategy.js.map +1 -0
  239. package/out-tsc/formatter/strategies/pipe-set.strategy.d.ts +21 -0
  240. package/out-tsc/formatter/strategies/pipe-set.strategy.d.ts.map +1 -0
  241. package/out-tsc/formatter/strategies/pipe-set.strategy.js +52 -0
  242. package/out-tsc/formatter/strategies/pipe-set.strategy.js.map +1 -0
  243. package/out-tsc/formatter/strategies/pipe-step.strategy.d.ts +25 -0
  244. package/out-tsc/formatter/strategies/pipe-step.strategy.d.ts.map +1 -0
  245. package/out-tsc/{lib/SparkSqlParserVisitor.js → formatter/strategies/pipe-step.strategy.js} +1 -1
  246. package/out-tsc/formatter/strategies/pipe-step.strategy.js.map +1 -0
  247. package/out-tsc/formatter/strategies/pipe-unpivot.strategy.d.ts +7 -0
  248. package/out-tsc/formatter/strategies/pipe-unpivot.strategy.d.ts.map +1 -0
  249. package/out-tsc/formatter/strategies/pipe-unpivot.strategy.js +33 -0
  250. package/out-tsc/formatter/strategies/pipe-unpivot.strategy.js.map +1 -0
  251. package/out-tsc/formatter/strategies/pipe-where.strategy.d.ts +21 -0
  252. package/out-tsc/formatter/strategies/pipe-where.strategy.d.ts.map +1 -0
  253. package/out-tsc/formatter/strategies/pipe-where.strategy.js +44 -0
  254. package/out-tsc/formatter/strategies/pipe-where.strategy.js.map +1 -0
  255. package/out-tsc/formatter/strategies/procedure/case-statement.strategy.d.ts +20 -0
  256. package/out-tsc/formatter/strategies/procedure/case-statement.strategy.d.ts.map +1 -0
  257. package/out-tsc/formatter/strategies/procedure/case-statement.strategy.js +132 -0
  258. package/out-tsc/formatter/strategies/procedure/case-statement.strategy.js.map +1 -0
  259. package/out-tsc/formatter/strategies/procedure/compound-statement.strategy.d.ts +43 -0
  260. package/out-tsc/formatter/strategies/procedure/compound-statement.strategy.d.ts.map +1 -0
  261. package/out-tsc/formatter/strategies/procedure/compound-statement.strategy.js +174 -0
  262. package/out-tsc/formatter/strategies/procedure/compound-statement.strategy.js.map +1 -0
  263. package/out-tsc/formatter/strategies/procedure/handler.strategy.d.ts +23 -0
  264. package/out-tsc/formatter/strategies/procedure/handler.strategy.d.ts.map +1 -0
  265. package/out-tsc/formatter/strategies/procedure/handler.strategy.js +81 -0
  266. package/out-tsc/formatter/strategies/procedure/handler.strategy.js.map +1 -0
  267. package/out-tsc/formatter/strategies/procedure/if-else.strategy.d.ts +19 -0
  268. package/out-tsc/formatter/strategies/procedure/if-else.strategy.d.ts.map +1 -0
  269. package/out-tsc/formatter/strategies/procedure/if-else.strategy.js +80 -0
  270. package/out-tsc/formatter/strategies/procedure/if-else.strategy.js.map +1 -0
  271. package/out-tsc/formatter/strategies/procedure/index.d.ts +27 -0
  272. package/out-tsc/formatter/strategies/procedure/index.d.ts.map +1 -0
  273. package/out-tsc/formatter/strategies/procedure/index.js +63 -0
  274. package/out-tsc/formatter/strategies/procedure/index.js.map +1 -0
  275. package/out-tsc/formatter/strategies/procedure/leave-iterate.strategy.d.ts +19 -0
  276. package/out-tsc/formatter/strategies/procedure/leave-iterate.strategy.d.ts.map +1 -0
  277. package/out-tsc/formatter/strategies/procedure/leave-iterate.strategy.js +54 -0
  278. package/out-tsc/formatter/strategies/procedure/leave-iterate.strategy.js.map +1 -0
  279. package/out-tsc/formatter/strategies/procedure/loop.strategy.d.ts +71 -0
  280. package/out-tsc/formatter/strategies/procedure/loop.strategy.d.ts.map +1 -0
  281. package/out-tsc/formatter/strategies/procedure/loop.strategy.js +216 -0
  282. package/out-tsc/formatter/strategies/procedure/loop.strategy.js.map +1 -0
  283. package/out-tsc/formatter/strategy-based-formatter.d.ts +329 -0
  284. package/out-tsc/formatter/strategy-based-formatter.d.ts.map +1 -0
  285. package/out-tsc/formatter/strategy-based-formatter.js +3808 -0
  286. package/out-tsc/formatter/strategy-based-formatter.js.map +1 -0
  287. package/out-tsc/formatter/strategy-dispatcher.d.ts +24 -0
  288. package/out-tsc/formatter/strategy-dispatcher.d.ts.map +1 -0
  289. package/out-tsc/formatter/strategy-dispatcher.js +19 -0
  290. package/out-tsc/formatter/strategy-dispatcher.js.map +1 -0
  291. package/out-tsc/formatter/types.d.ts +2 -0
  292. package/out-tsc/formatter/types.d.ts.map +1 -0
  293. package/out-tsc/{lib/SparkSqlParserListener.js → formatter/types.js} +1 -1
  294. package/out-tsc/formatter/types.js.map +1 -0
  295. package/out-tsc/formatter/visitor/ddl/alter-table.d.ts +48 -0
  296. package/out-tsc/formatter/visitor/ddl/alter-table.d.ts.map +1 -0
  297. package/out-tsc/formatter/visitor/ddl/alter-table.js +133 -0
  298. package/out-tsc/formatter/visitor/ddl/alter-table.js.map +1 -0
  299. package/out-tsc/formatter/visitor/ddl/create-table.d.ts +54 -0
  300. package/out-tsc/formatter/visitor/ddl/create-table.d.ts.map +1 -0
  301. package/out-tsc/formatter/visitor/ddl/create-table.js +142 -0
  302. package/out-tsc/formatter/visitor/ddl/create-table.js.map +1 -0
  303. package/out-tsc/formatter/visitor/ddl/create-view.d.ts +27 -0
  304. package/out-tsc/formatter/visitor/ddl/create-view.d.ts.map +1 -0
  305. package/out-tsc/formatter/visitor/ddl/create-view.js +61 -0
  306. package/out-tsc/formatter/visitor/ddl/create-view.js.map +1 -0
  307. package/out-tsc/formatter/visitor/ddl/drop.d.ts +30 -0
  308. package/out-tsc/formatter/visitor/ddl/drop.d.ts.map +1 -0
  309. package/out-tsc/formatter/visitor/ddl/drop.js +69 -0
  310. package/out-tsc/formatter/visitor/ddl/drop.js.map +1 -0
  311. package/out-tsc/formatter/visitor/ddl/index.d.ts +10 -0
  312. package/out-tsc/formatter/visitor/ddl/index.d.ts.map +1 -0
  313. package/out-tsc/formatter/visitor/ddl/index.js +26 -0
  314. package/out-tsc/formatter/visitor/ddl/index.js.map +1 -0
  315. package/out-tsc/formatter/visitor/dml/delete.d.ts +26 -0
  316. package/out-tsc/formatter/visitor/dml/delete.d.ts.map +1 -0
  317. package/out-tsc/formatter/visitor/dml/delete.js +38 -0
  318. package/out-tsc/formatter/visitor/dml/delete.js.map +1 -0
  319. package/out-tsc/formatter/visitor/dml/index.d.ts +10 -0
  320. package/out-tsc/formatter/visitor/dml/index.d.ts.map +1 -0
  321. package/out-tsc/formatter/visitor/dml/index.js +26 -0
  322. package/out-tsc/formatter/visitor/dml/index.js.map +1 -0
  323. package/out-tsc/formatter/visitor/dml/insert.d.ts +42 -0
  324. package/out-tsc/formatter/visitor/dml/insert.d.ts.map +1 -0
  325. package/out-tsc/formatter/visitor/dml/insert.js +112 -0
  326. package/out-tsc/formatter/visitor/dml/insert.js.map +1 -0
  327. package/out-tsc/formatter/visitor/dml/merge.d.ts +40 -0
  328. package/out-tsc/formatter/visitor/dml/merge.d.ts.map +1 -0
  329. package/out-tsc/formatter/visitor/dml/merge.js +67 -0
  330. package/out-tsc/formatter/visitor/dml/merge.js.map +1 -0
  331. package/out-tsc/formatter/visitor/dml/update.d.ts +33 -0
  332. package/out-tsc/formatter/visitor/dml/update.d.ts.map +1 -0
  333. package/out-tsc/formatter/visitor/dml/update.js +49 -0
  334. package/out-tsc/formatter/visitor/dml/update.js.map +1 -0
  335. package/out-tsc/formatter/visitor/expression/arithmetic.d.ts +20 -0
  336. package/out-tsc/formatter/visitor/expression/arithmetic.d.ts.map +1 -0
  337. package/out-tsc/formatter/visitor/expression/arithmetic.js +44 -0
  338. package/out-tsc/formatter/visitor/expression/arithmetic.js.map +1 -0
  339. package/out-tsc/formatter/visitor/expression/case-when.d.ts +41 -0
  340. package/out-tsc/formatter/visitor/expression/case-when.d.ts.map +1 -0
  341. package/out-tsc/formatter/visitor/expression/case-when.js +94 -0
  342. package/out-tsc/formatter/visitor/expression/case-when.js.map +1 -0
  343. package/out-tsc/formatter/visitor/expression/comparison.d.ts +20 -0
  344. package/out-tsc/formatter/visitor/expression/comparison.d.ts.map +1 -0
  345. package/out-tsc/formatter/visitor/expression/comparison.js +26 -0
  346. package/out-tsc/formatter/visitor/expression/comparison.js.map +1 -0
  347. package/out-tsc/formatter/visitor/expression/function-call.d.ts +20 -0
  348. package/out-tsc/formatter/visitor/expression/function-call.d.ts.map +1 -0
  349. package/out-tsc/formatter/visitor/expression/function-call.js +33 -0
  350. package/out-tsc/formatter/visitor/expression/function-call.js.map +1 -0
  351. package/out-tsc/formatter/visitor/expression/index.d.ts +11 -0
  352. package/out-tsc/formatter/visitor/expression/index.d.ts.map +1 -0
  353. package/out-tsc/formatter/visitor/expression/index.js +27 -0
  354. package/out-tsc/formatter/visitor/expression/index.js.map +1 -0
  355. package/out-tsc/formatter/visitor/expression/logical.d.ts +26 -0
  356. package/out-tsc/formatter/visitor/expression/logical.d.ts.map +1 -0
  357. package/out-tsc/formatter/visitor/expression/logical.js +46 -0
  358. package/out-tsc/formatter/visitor/expression/logical.js.map +1 -0
  359. package/out-tsc/formatter/visitor/formatter-core.d.ts +79 -0
  360. package/out-tsc/formatter/visitor/formatter-core.d.ts.map +1 -0
  361. package/out-tsc/formatter/visitor/formatter-core.js +211 -0
  362. package/out-tsc/formatter/visitor/formatter-core.js.map +1 -0
  363. package/out-tsc/formatter/visitor/index.d.ts +21 -0
  364. package/out-tsc/formatter/visitor/index.d.ts.map +1 -0
  365. package/out-tsc/formatter/visitor/index.js +26 -0
  366. package/out-tsc/formatter/visitor/index.js.map +1 -0
  367. package/out-tsc/formatter/visitor/management/cache.d.ts +26 -0
  368. package/out-tsc/formatter/visitor/management/cache.d.ts.map +1 -0
  369. package/out-tsc/formatter/visitor/management/cache.js +58 -0
  370. package/out-tsc/formatter/visitor/management/cache.js.map +1 -0
  371. package/out-tsc/formatter/visitor/management/index.d.ts +8 -0
  372. package/out-tsc/formatter/visitor/management/index.d.ts.map +1 -0
  373. package/out-tsc/formatter/visitor/management/index.js +24 -0
  374. package/out-tsc/formatter/visitor/management/index.js.map +1 -0
  375. package/out-tsc/formatter/visitor/management/refresh.d.ts +26 -0
  376. package/out-tsc/formatter/visitor/management/refresh.d.ts.map +1 -0
  377. package/out-tsc/formatter/visitor/management/refresh.js +55 -0
  378. package/out-tsc/formatter/visitor/management/refresh.js.map +1 -0
  379. package/out-tsc/formatter/visitor/pipeline/delta-live-tables.d.ts +31 -0
  380. package/out-tsc/formatter/visitor/pipeline/delta-live-tables.d.ts.map +1 -0
  381. package/out-tsc/formatter/visitor/pipeline/delta-live-tables.js +46 -0
  382. package/out-tsc/formatter/visitor/pipeline/delta-live-tables.js.map +1 -0
  383. package/out-tsc/formatter/visitor/pipeline/index.d.ts +7 -0
  384. package/out-tsc/formatter/visitor/pipeline/index.d.ts.map +1 -0
  385. package/out-tsc/formatter/visitor/pipeline/index.js +23 -0
  386. package/out-tsc/formatter/visitor/pipeline/index.js.map +1 -0
  387. package/out-tsc/formatter/visitor/query/cte.d.ts +34 -0
  388. package/out-tsc/formatter/visitor/query/cte.d.ts.map +1 -0
  389. package/out-tsc/formatter/visitor/query/cte.js +54 -0
  390. package/out-tsc/formatter/visitor/query/cte.js.map +1 -0
  391. package/out-tsc/formatter/visitor/query/index.d.ts +11 -0
  392. package/out-tsc/formatter/visitor/query/index.d.ts.map +1 -0
  393. package/out-tsc/formatter/visitor/query/index.js +27 -0
  394. package/out-tsc/formatter/visitor/query/index.js.map +1 -0
  395. package/out-tsc/formatter/visitor/query/query-organization.d.ts +25 -0
  396. package/out-tsc/formatter/visitor/query/query-organization.d.ts.map +1 -0
  397. package/out-tsc/formatter/visitor/query/query-organization.js +75 -0
  398. package/out-tsc/formatter/visitor/query/query-organization.js.map +1 -0
  399. package/out-tsc/formatter/visitor/query/query.d.ts +22 -0
  400. package/out-tsc/formatter/visitor/query/query.d.ts.map +1 -0
  401. package/out-tsc/formatter/visitor/query/query.js +30 -0
  402. package/out-tsc/formatter/visitor/query/query.js.map +1 -0
  403. package/out-tsc/formatter/visitor/query/select-clause.d.ts +17 -0
  404. package/out-tsc/formatter/visitor/query/select-clause.d.ts.map +1 -0
  405. package/out-tsc/formatter/visitor/query/select-clause.js +35 -0
  406. package/out-tsc/formatter/visitor/query/select-clause.js.map +1 -0
  407. package/out-tsc/formatter/visitor/query/set-operation.d.ts +25 -0
  408. package/out-tsc/formatter/visitor/query/set-operation.d.ts.map +1 -0
  409. package/out-tsc/formatter/visitor/query/set-operation.js +52 -0
  410. package/out-tsc/formatter/visitor/query/set-operation.js.map +1 -0
  411. package/out-tsc/formatter/visitor/statements/index.d.ts +7 -0
  412. package/out-tsc/formatter/visitor/statements/index.d.ts.map +1 -0
  413. package/out-tsc/formatter/visitor/statements/index.js +23 -0
  414. package/out-tsc/formatter/visitor/statements/index.js.map +1 -0
  415. package/out-tsc/formatter/visitor/statements/program.d.ts +33 -0
  416. package/out-tsc/formatter/visitor/statements/program.d.ts.map +1 -0
  417. package/out-tsc/formatter/visitor/statements/program.js +69 -0
  418. package/out-tsc/formatter/visitor/statements/program.js.map +1 -0
  419. package/out-tsc/formatter/visitor/types/complex-types.d.ts +24 -0
  420. package/out-tsc/formatter/visitor/types/complex-types.d.ts.map +1 -0
  421. package/out-tsc/formatter/visitor/types/complex-types.js +47 -0
  422. package/out-tsc/formatter/visitor/types/complex-types.js.map +1 -0
  423. package/out-tsc/formatter/visitor/types/index.d.ts +8 -0
  424. package/out-tsc/formatter/visitor/types/index.d.ts.map +1 -0
  425. package/out-tsc/formatter/visitor/types/index.js +24 -0
  426. package/out-tsc/formatter/visitor/types/index.js.map +1 -0
  427. package/out-tsc/formatter/visitor/types/primitive-types.d.ts +22 -0
  428. package/out-tsc/formatter/visitor/types/primitive-types.d.ts.map +1 -0
  429. package/out-tsc/formatter/visitor/types/primitive-types.js +37 -0
  430. package/out-tsc/formatter/visitor/types/primitive-types.js.map +1 -0
  431. package/out-tsc/formatter/visitor/utils/context-helpers.d.ts +32 -0
  432. package/out-tsc/formatter/visitor/utils/context-helpers.d.ts.map +1 -0
  433. package/out-tsc/formatter/visitor/utils/context-helpers.js +98 -0
  434. package/out-tsc/formatter/visitor/utils/context-helpers.js.map +1 -0
  435. package/out-tsc/formatter/visitor/utils/index.d.ts +11 -0
  436. package/out-tsc/formatter/visitor/utils/index.d.ts.map +1 -0
  437. package/out-tsc/formatter/visitor/utils/index.js +45 -0
  438. package/out-tsc/formatter/visitor/utils/index.js.map +1 -0
  439. package/out-tsc/formatter/visitor/utils/keyword-formatting.d.ts +57 -0
  440. package/out-tsc/formatter/visitor/utils/keyword-formatting.d.ts.map +1 -0
  441. package/out-tsc/formatter/visitor/utils/keyword-formatting.js +87 -0
  442. package/out-tsc/formatter/visitor/utils/keyword-formatting.js.map +1 -0
  443. package/out-tsc/formatter/visitor/utils/parenthesis-formatting.d.ts +53 -0
  444. package/out-tsc/formatter/visitor/utils/parenthesis-formatting.d.ts.map +1 -0
  445. package/out-tsc/formatter/visitor/utils/parenthesis-formatting.js +88 -0
  446. package/out-tsc/formatter/visitor/utils/parenthesis-formatting.js.map +1 -0
  447. package/out-tsc/formatter/visitor/utils/space-compression.d.ts +55 -0
  448. package/out-tsc/formatter/visitor/utils/space-compression.d.ts.map +1 -0
  449. package/out-tsc/formatter/visitor/utils/space-compression.js +71 -0
  450. package/out-tsc/formatter/visitor/utils/space-compression.js.map +1 -0
  451. package/out-tsc/formatter/visitor/utils/token-helpers.d.ts +64 -0
  452. package/out-tsc/formatter/visitor/utils/token-helpers.d.ts.map +1 -0
  453. package/out-tsc/formatter/visitor/utils/token-helpers.js +249 -0
  454. package/out-tsc/formatter/visitor/utils/token-helpers.js.map +1 -0
  455. package/out-tsc/index.d.ts +2 -1
  456. package/out-tsc/index.d.ts.map +1 -0
  457. package/out-tsc/index.js +3 -1
  458. package/out-tsc/index.js.map +1 -1
  459. package/out-tsc/lib/SparkSQLLexer.d.ts +557 -0
  460. package/out-tsc/lib/SparkSQLLexer.d.ts.map +1 -0
  461. package/out-tsc/lib/SparkSQLLexer.js +3676 -0
  462. package/out-tsc/lib/SparkSQLLexer.js.map +1 -0
  463. package/out-tsc/lib/SparkSQLParser.d.ts +7884 -0
  464. package/out-tsc/lib/SparkSQLParser.d.ts.map +1 -0
  465. package/out-tsc/lib/SparkSQLParser.js +45848 -0
  466. package/out-tsc/lib/SparkSQLParser.js.map +1 -0
  467. package/out-tsc/lib/SparkSQLParserListener.d.ts +5855 -0
  468. package/out-tsc/lib/SparkSQLParserListener.d.ts.map +1 -0
  469. package/out-tsc/lib/SparkSQLParserListener.js +4 -0
  470. package/out-tsc/lib/SparkSQLParserListener.js.map +1 -0
  471. package/out-tsc/lib/SparkSQLParserVisitor.d.ts +3674 -0
  472. package/out-tsc/lib/SparkSQLParserVisitor.d.ts.map +1 -0
  473. package/out-tsc/lib/SparkSQLParserVisitor.js +4 -0
  474. package/out-tsc/lib/SparkSQLParserVisitor.js.map +1 -0
  475. package/out-tsc/lineage.typing.d.ts +64 -0
  476. package/out-tsc/lineage.typing.d.ts.map +1 -0
  477. package/out-tsc/lineage.typing.js +3 -0
  478. package/out-tsc/lineage.typing.js.map +1 -0
  479. package/out-tsc/listeners/parse-error.listener.d.ts +3 -2
  480. package/out-tsc/listeners/parse-error.listener.d.ts.map +1 -0
  481. package/out-tsc/listeners/parse-error.listener.js +4 -4
  482. package/out-tsc/listeners/parse-error.listener.js.map +1 -1
  483. package/out-tsc/listeners/schema.listener.d.ts +32 -39
  484. package/out-tsc/listeners/schema.listener.d.ts.map +1 -0
  485. package/out-tsc/listeners/schema.listener.js +58 -100
  486. package/out-tsc/listeners/schema.listener.js.map +1 -1
  487. package/out-tsc/listeners/statement.listener.d.ts +263 -5
  488. package/out-tsc/listeners/statement.listener.d.ts.map +1 -0
  489. package/out-tsc/listeners/statement.listener.js +836 -11
  490. package/out-tsc/listeners/statement.listener.js.map +1 -1
  491. package/out-tsc/listeners/structure.listener.d.ts +70 -0
  492. package/out-tsc/listeners/structure.listener.d.ts.map +1 -0
  493. package/out-tsc/listeners/structure.listener.js +211 -0
  494. package/out-tsc/listeners/structure.listener.js.map +1 -0
  495. package/out-tsc/listeners/tokens-collector.listener.d.ts +27 -0
  496. package/out-tsc/listeners/tokens-collector.listener.d.ts.map +1 -0
  497. package/out-tsc/listeners/tokens-collector.listener.js +102 -0
  498. package/out-tsc/listeners/tokens-collector.listener.js.map +1 -0
  499. package/out-tsc/lsp-server.d.ts +79 -8
  500. package/out-tsc/lsp-server.d.ts.map +1 -0
  501. package/out-tsc/lsp-server.js +672 -237
  502. package/out-tsc/lsp-server.js.map +1 -1
  503. package/out-tsc/metadata.typing.d.ts +1 -0
  504. package/out-tsc/metadata.typing.d.ts.map +1 -0
  505. package/out-tsc/monaco-config.d.ts +219 -0
  506. package/out-tsc/monaco-config.d.ts.map +1 -0
  507. package/out-tsc/monaco-config.js +1032 -0
  508. package/out-tsc/monaco-config.js.map +1 -0
  509. package/out-tsc/parsing-warehouse.d.ts +8 -3
  510. package/out-tsc/parsing-warehouse.d.ts.map +1 -0
  511. package/out-tsc/parsing-warehouse.js +62 -6
  512. package/out-tsc/parsing-warehouse.js.map +1 -1
  513. package/out-tsc/protocol-translation.d.ts +12 -5
  514. package/out-tsc/protocol-translation.d.ts.map +1 -0
  515. package/out-tsc/protocol-translation.js +72 -19
  516. package/out-tsc/protocol-translation.js.map +1 -1
  517. package/out-tsc/public-apis.d.ts +1 -0
  518. package/out-tsc/public-apis.d.ts.map +1 -0
  519. package/out-tsc/schema-registry.d.ts +10 -7
  520. package/out-tsc/schema-registry.d.ts.map +1 -0
  521. package/out-tsc/schema-registry.js +87 -106
  522. package/out-tsc/schema-registry.js.map +1 -1
  523. package/out-tsc/server-worker.d.ts +1 -0
  524. package/out-tsc/server-worker.d.ts.map +1 -0
  525. package/out-tsc/server-worker.js +159 -44
  526. package/out-tsc/server-worker.js.map +1 -1
  527. package/out-tsc/tests/folding/block-comment-folding.test.d.ts +7 -0
  528. package/out-tsc/tests/folding/block-comment-folding.test.d.ts.map +1 -0
  529. package/out-tsc/tests/folding/block-comment-folding.test.js +268 -0
  530. package/out-tsc/tests/folding/block-comment-folding.test.js.map +1 -0
  531. package/out-tsc/tests/folding/caching.test.d.ts +11 -0
  532. package/out-tsc/tests/folding/caching.test.d.ts.map +1 -0
  533. package/out-tsc/tests/folding/caching.test.js +141 -0
  534. package/out-tsc/tests/folding/caching.test.js.map +1 -0
  535. package/out-tsc/tests/folding/cte-dependency-chain.test.d.ts +15 -0
  536. package/out-tsc/tests/folding/cte-dependency-chain.test.d.ts.map +1 -0
  537. package/out-tsc/tests/folding/cte-dependency-chain.test.js +323 -0
  538. package/out-tsc/tests/folding/cte-dependency-chain.test.js.map +1 -0
  539. package/out-tsc/tests/folding/debug-format-flow.test.d.ts +2 -0
  540. package/out-tsc/tests/folding/debug-format-flow.test.d.ts.map +1 -0
  541. package/out-tsc/tests/folding/debug-format-flow.test.js +114 -0
  542. package/out-tsc/tests/folding/debug-format-flow.test.js.map +1 -0
  543. package/out-tsc/tests/folding/debug-formatted.test.d.ts +2 -0
  544. package/out-tsc/tests/folding/debug-formatted.test.d.ts.map +1 -0
  545. package/out-tsc/tests/folding/debug-formatted.test.js +175 -0
  546. package/out-tsc/tests/folding/debug-formatted.test.js.map +1 -0
  547. package/out-tsc/tests/folding/deduplication.test.d.ts +10 -0
  548. package/out-tsc/tests/folding/deduplication.test.d.ts.map +1 -0
  549. package/out-tsc/tests/folding/deduplication.test.js +206 -0
  550. package/out-tsc/tests/folding/deduplication.test.js.map +1 -0
  551. package/out-tsc/tests/folding/edge-cases.test.d.ts +8 -0
  552. package/out-tsc/tests/folding/edge-cases.test.d.ts.map +1 -0
  553. package/out-tsc/tests/folding/edge-cases.test.js +319 -0
  554. package/out-tsc/tests/folding/edge-cases.test.js.map +1 -0
  555. package/out-tsc/tests/folding/folding-level-config.test.d.ts +11 -0
  556. package/out-tsc/tests/folding/folding-level-config.test.d.ts.map +1 -0
  557. package/out-tsc/tests/folding/folding-level-config.test.js +313 -0
  558. package/out-tsc/tests/folding/folding-level-config.test.js.map +1 -0
  559. package/out-tsc/tests/folding/folding-statistics.test.d.ts +13 -0
  560. package/out-tsc/tests/folding/folding-statistics.test.d.ts.map +1 -0
  561. package/out-tsc/tests/folding/folding-statistics.test.js +144 -0
  562. package/out-tsc/tests/folding/folding-statistics.test.js.map +1 -0
  563. package/out-tsc/tests/folding/index.d.ts +8 -0
  564. package/out-tsc/tests/folding/index.d.ts.map +1 -0
  565. package/out-tsc/tests/folding/index.js +24 -0
  566. package/out-tsc/tests/folding/index.js.map +1 -0
  567. package/out-tsc/tests/folding/join-folding.test.d.ts +11 -0
  568. package/out-tsc/tests/folding/join-folding.test.d.ts.map +1 -0
  569. package/out-tsc/tests/folding/join-folding.test.js +167 -0
  570. package/out-tsc/tests/folding/join-folding.test.js.map +1 -0
  571. package/out-tsc/tests/folding/kind-classification.test.d.ts +11 -0
  572. package/out-tsc/tests/folding/kind-classification.test.d.ts.map +1 -0
  573. package/out-tsc/tests/folding/kind-classification.test.js +270 -0
  574. package/out-tsc/tests/folding/kind-classification.test.js.map +1 -0
  575. package/out-tsc/tests/folding/level1-statement.test.d.ts +8 -0
  576. package/out-tsc/tests/folding/level1-statement.test.d.ts.map +1 -0
  577. package/out-tsc/tests/folding/level1-statement.test.js +278 -0
  578. package/out-tsc/tests/folding/level1-statement.test.js.map +1 -0
  579. package/out-tsc/tests/folding/level2-query-block.test.d.ts +8 -0
  580. package/out-tsc/tests/folding/level2-query-block.test.d.ts.map +1 -0
  581. package/out-tsc/tests/folding/level2-query-block.test.js +374 -0
  582. package/out-tsc/tests/folding/level2-query-block.test.js.map +1 -0
  583. package/out-tsc/tests/folding/level3-expression.test.d.ts +8 -0
  584. package/out-tsc/tests/folding/level3-expression.test.d.ts.map +1 -0
  585. package/out-tsc/tests/folding/level3-expression.test.js +361 -0
  586. package/out-tsc/tests/folding/level3-expression.test.js.map +1 -0
  587. package/out-tsc/tests/folding/level4-structure.test.d.ts +8 -0
  588. package/out-tsc/tests/folding/level4-structure.test.d.ts.map +1 -0
  589. package/out-tsc/tests/folding/level4-structure.test.js +270 -0
  590. package/out-tsc/tests/folding/level4-structure.test.js.map +1 -0
  591. package/out-tsc/tests/folding/line-comment-folding.test.d.ts +13 -0
  592. package/out-tsc/tests/folding/line-comment-folding.test.d.ts.map +1 -0
  593. package/out-tsc/tests/folding/line-comment-folding.test.js +215 -0
  594. package/out-tsc/tests/folding/line-comment-folding.test.js.map +1 -0
  595. package/out-tsc/tests/folding/nested-folding.test.d.ts +8 -0
  596. package/out-tsc/tests/folding/nested-folding.test.d.ts.map +1 -0
  597. package/out-tsc/tests/folding/nested-folding.test.js +386 -0
  598. package/out-tsc/tests/folding/nested-folding.test.js.map +1 -0
  599. package/out-tsc/tests/folding/performance-benchmark.test.d.ts +11 -0
  600. package/out-tsc/tests/folding/performance-benchmark.test.d.ts.map +1 -0
  601. package/out-tsc/tests/folding/performance-benchmark.test.js +256 -0
  602. package/out-tsc/tests/folding/performance-benchmark.test.js.map +1 -0
  603. package/out-tsc/tests/folding/region-marker-folding.test.d.ts +11 -0
  604. package/out-tsc/tests/folding/region-marker-folding.test.d.ts.map +1 -0
  605. package/out-tsc/tests/folding/region-marker-folding.test.js +245 -0
  606. package/out-tsc/tests/folding/region-marker-folding.test.js.map +1 -0
  607. package/out-tsc/tests/folding/select-columns-folding.test.d.ts +10 -0
  608. package/out-tsc/tests/folding/select-columns-folding.test.d.ts.map +1 -0
  609. package/out-tsc/tests/folding/select-columns-folding.test.js +139 -0
  610. package/out-tsc/tests/folding/select-columns-folding.test.js.map +1 -0
  611. package/out-tsc/tests/folding/test-utils.d.ts +73 -0
  612. package/out-tsc/tests/folding/test-utils.d.ts.map +1 -0
  613. package/out-tsc/tests/folding/test-utils.js +98 -0
  614. package/out-tsc/tests/folding/test-utils.js.map +1 -0
  615. package/out-tsc/tests/folding/values-folding.test.d.ts +10 -0
  616. package/out-tsc/tests/folding/values-folding.test.d.ts.map +1 -0
  617. package/out-tsc/tests/folding/values-folding.test.js +102 -0
  618. package/out-tsc/tests/folding/values-folding.test.js.map +1 -0
  619. package/out-tsc/tests/format/ddl/datatype-constraint.test.d.ts +5 -0
  620. package/out-tsc/tests/format/ddl/datatype-constraint.test.d.ts.map +1 -0
  621. package/out-tsc/tests/format/ddl/datatype-constraint.test.js +132 -0
  622. package/out-tsc/tests/format/ddl/datatype-constraint.test.js.map +1 -0
  623. package/out-tsc/tests/format/ddl/index.test.d.ts +5 -0
  624. package/out-tsc/tests/format/ddl/index.test.d.ts.map +1 -0
  625. package/out-tsc/tests/format/ddl/index.test.js +74 -0
  626. package/out-tsc/tests/format/ddl/index.test.js.map +1 -0
  627. package/out-tsc/tests/format/ddl/materialized-view.test.d.ts +5 -0
  628. package/out-tsc/tests/format/ddl/materialized-view.test.d.ts.map +1 -0
  629. package/out-tsc/tests/format/ddl/materialized-view.test.js +92 -0
  630. package/out-tsc/tests/format/ddl/materialized-view.test.js.map +1 -0
  631. package/out-tsc/tests/format/ddl/partition.test.d.ts +5 -0
  632. package/out-tsc/tests/format/ddl/partition.test.d.ts.map +1 -0
  633. package/out-tsc/tests/format/ddl/partition.test.js +109 -0
  634. package/out-tsc/tests/format/ddl/partition.test.js.map +1 -0
  635. package/out-tsc/tests/format/ddl/variable.test.d.ts +5 -0
  636. package/out-tsc/tests/format/ddl/variable.test.d.ts.map +1 -0
  637. package/out-tsc/tests/format/ddl/variable.test.js +58 -0
  638. package/out-tsc/tests/format/ddl/variable.test.js.map +1 -0
  639. package/out-tsc/tests/format/dml/select.test.d.ts +5 -0
  640. package/out-tsc/tests/format/dml/select.test.d.ts.map +1 -0
  641. package/out-tsc/tests/format/dml/select.test.js +114 -0
  642. package/out-tsc/tests/format/dml/select.test.js.map +1 -0
  643. package/out-tsc/tests/format/dml/subquery.test.d.ts +5 -0
  644. package/out-tsc/tests/format/dml/subquery.test.d.ts.map +1 -0
  645. package/out-tsc/tests/format/dml/subquery.test.js +221 -0
  646. package/out-tsc/tests/format/dml/subquery.test.js.map +1 -0
  647. package/out-tsc/tests/format/dql/comment.test.d.ts +7 -0
  648. package/out-tsc/tests/format/dql/comment.test.d.ts.map +1 -0
  649. package/out-tsc/tests/format/dql/comment.test.js +279 -0
  650. package/out-tsc/tests/format/dql/comment.test.js.map +1 -0
  651. package/out-tsc/tests/format/dql/cte.test.d.ts +7 -0
  652. package/out-tsc/tests/format/dql/cte.test.d.ts.map +1 -0
  653. package/out-tsc/tests/format/dql/cte.test.js +31 -0
  654. package/out-tsc/tests/format/dql/cte.test.js.map +1 -0
  655. package/out-tsc/tests/format/dql/dql-detail.test.d.ts +5 -0
  656. package/out-tsc/tests/format/dql/dql-detail.test.d.ts.map +1 -0
  657. package/out-tsc/tests/format/dql/dql-detail.test.js +191 -0
  658. package/out-tsc/tests/format/dql/dql-detail.test.js.map +1 -0
  659. package/out-tsc/tests/format/dql/lateral-view.test.d.ts +7 -0
  660. package/out-tsc/tests/format/dql/lateral-view.test.d.ts.map +1 -0
  661. package/out-tsc/tests/format/dql/lateral-view.test.js +34 -0
  662. package/out-tsc/tests/format/dql/lateral-view.test.js.map +1 -0
  663. package/out-tsc/tests/format/dql/pivot.test.d.ts +7 -0
  664. package/out-tsc/tests/format/dql/pivot.test.d.ts.map +1 -0
  665. package/out-tsc/tests/format/dql/pivot.test.js +56 -0
  666. package/out-tsc/tests/format/dql/pivot.test.js.map +1 -0
  667. package/out-tsc/tests/format/dql/window.test.d.ts +7 -0
  668. package/out-tsc/tests/format/dql/window.test.d.ts.map +1 -0
  669. package/out-tsc/tests/format/dql/window.test.js +89 -0
  670. package/out-tsc/tests/format/dql/window.test.js.map +1 -0
  671. package/out-tsc/tests/format/expression/expression.test.d.ts +5 -0
  672. package/out-tsc/tests/format/expression/expression.test.d.ts.map +1 -0
  673. package/out-tsc/tests/format/expression/expression.test.js +203 -0
  674. package/out-tsc/tests/format/expression/expression.test.js.map +1 -0
  675. package/out-tsc/tests/format/pipe/pipe-operator.test.d.ts +5 -0
  676. package/out-tsc/tests/format/pipe/pipe-operator.test.d.ts.map +1 -0
  677. package/out-tsc/tests/format/pipe/pipe-operator.test.js +290 -0
  678. package/out-tsc/tests/format/pipe/pipe-operator.test.js.map +1 -0
  679. package/out-tsc/tests/format/procedure/compound-statement.test.d.ts +16 -0
  680. package/out-tsc/tests/format/procedure/compound-statement.test.d.ts.map +1 -0
  681. package/out-tsc/tests/format/procedure/compound-statement.test.js +254 -0
  682. package/out-tsc/tests/format/procedure/compound-statement.test.js.map +1 -0
  683. package/out-tsc/tests/format/resource/resource.test.d.ts +5 -0
  684. package/out-tsc/tests/format/resource/resource.test.d.ts.map +1 -0
  685. package/out-tsc/tests/format/resource/resource.test.js +69 -0
  686. package/out-tsc/tests/format/resource/resource.test.js.map +1 -0
  687. package/out-tsc/tests/format/test-utils.d.ts +40 -0
  688. package/out-tsc/tests/format/test-utils.d.ts.map +1 -0
  689. package/out-tsc/tests/format/test-utils.js +53 -0
  690. package/out-tsc/tests/format/test-utils.js.map +1 -0
  691. package/out-tsc/tests/lsp-server.test.d.ts +2 -0
  692. package/out-tsc/tests/lsp-server.test.d.ts.map +1 -0
  693. package/out-tsc/tests/lsp-server.test.js +1525 -0
  694. package/out-tsc/tests/lsp-server.test.js.map +1 -0
  695. package/out-tsc/tests/spark-sql-inputs.test.d.ts +17 -0
  696. package/out-tsc/tests/spark-sql-inputs.test.d.ts.map +1 -0
  697. package/out-tsc/tests/spark-sql-inputs.test.js +570 -0
  698. package/out-tsc/tests/spark-sql-inputs.test.js.map +1 -0
  699. package/out-tsc/tests/validation.test.d.ts +2 -0
  700. package/out-tsc/tests/validation.test.d.ts.map +1 -0
  701. package/out-tsc/tests/validation.test.js +115 -0
  702. package/out-tsc/tests/validation.test.js.map +1 -0
  703. package/out-tsc/typings.d.ts +115 -1
  704. package/out-tsc/typings.d.ts.map +1 -0
  705. package/out-tsc/typings.js +28 -0
  706. package/out-tsc/typings.js.map +1 -1
  707. package/out-tsc/utils.d.ts +1 -0
  708. package/out-tsc/utils.d.ts.map +1 -0
  709. package/out-tsc/utils.js +4 -5
  710. package/out-tsc/utils.js.map +1 -1
  711. package/out-tsc/visitors/completion.visitor.d.ts +85 -0
  712. package/out-tsc/visitors/completion.visitor.d.ts.map +1 -0
  713. package/out-tsc/visitors/completion.visitor.js +379 -0
  714. package/out-tsc/visitors/completion.visitor.js.map +1 -0
  715. package/out-tsc/visitors/lineage.visitor.d.ts +34 -0
  716. package/out-tsc/visitors/lineage.visitor.d.ts.map +1 -0
  717. package/out-tsc/visitors/lineage.visitor.js +181 -0
  718. package/out-tsc/visitors/lineage.visitor.js.map +1 -0
  719. package/out-tsc/visitors/space-replacer-format.visitor.d.ts +1641 -0
  720. package/out-tsc/visitors/space-replacer-format.visitor.d.ts.map +1 -0
  721. package/out-tsc/visitors/space-replacer-format.visitor.js +7529 -0
  722. package/out-tsc/visitors/space-replacer-format.visitor.js.map +1 -0
  723. package/out-tsc/visitors/sparksql-relation.visitor.d.ts +154 -0
  724. package/out-tsc/visitors/sparksql-relation.visitor.d.ts.map +1 -0
  725. package/out-tsc/visitors/sparksql-relation.visitor.js +749 -0
  726. package/out-tsc/visitors/sparksql-relation.visitor.js.map +1 -0
  727. package/package.json +36 -9
  728. package/out-tsc/constant.d.ts +0 -3
  729. package/out-tsc/constant.js +0 -7
  730. package/out-tsc/constant.js.map +0 -1
  731. package/out-tsc/lib/SparkSqlLexer.d.ts +0 -421
  732. package/out-tsc/lib/SparkSqlLexer.js +0 -2750
  733. package/out-tsc/lib/SparkSqlLexer.js.map +0 -1
  734. package/out-tsc/lib/SparkSqlParser.d.ts +0 -6200
  735. package/out-tsc/lib/SparkSqlParser.js +0 -34707
  736. package/out-tsc/lib/SparkSqlParser.js.map +0 -1
  737. package/out-tsc/lib/SparkSqlParserListener.d.ts +0 -1158
  738. package/out-tsc/lib/SparkSqlParserListener.js.map +0 -1
  739. package/out-tsc/lib/SparkSqlParserVisitor.d.ts +0 -773
  740. package/out-tsc/lib/SparkSqlParserVisitor.js.map +0 -1
@@ -0,0 +1,1525 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const chai_1 = require("chai");
4
+ const vscode_languageserver_textdocument_1 = require("vscode-languageserver-textdocument");
5
+ const strategy_based_formatter_1 = require("../formatter/strategy-based-formatter");
6
+ const lsp_server_1 = require("../lsp-server");
7
+ describe('LSPServer', () => {
8
+ let server;
9
+ beforeEach(() => {
10
+ server = new lsp_server_1.LSPServer();
11
+ });
12
+ describe('doValidation', () => {
13
+ it('should return no errors for valid SQL', () => {
14
+ const doc = vscode_languageserver_textdocument_1.TextDocument.create('test://test.sql', 'sql', 1, 'SELECT * FROM users');
15
+ const errors = server.doValidation(doc);
16
+ (0, chai_1.expect)(errors.length).to.equal(0);
17
+ });
18
+ it('should return errors for invalid SQL', () => {
19
+ const doc = vscode_languageserver_textdocument_1.TextDocument.create('test://test.sql', 'sql', 1, 'SELECTX * FROM users');
20
+ const errors = server.doValidation(doc);
21
+ (0, chai_1.expect)(errors.length).to.be.greaterThan(0);
22
+ });
23
+ });
24
+ describe('doCompletion', () => {
25
+ it('should return completion items', () => {
26
+ const doc = vscode_languageserver_textdocument_1.TextDocument.create('test://test.sql', 'sql', 1, 'SELECT ');
27
+ const result = server.doCompletion(doc, { line: 0, character: 7 });
28
+ (0, chai_1.expect)(result.completionItems.length).to.be.greaterThan(0);
29
+ });
30
+ });
31
+ describe('parseStructure', () => {
32
+ it('should parse structure for SELECT query', () => {
33
+ const doc = vscode_languageserver_textdocument_1.TextDocument.create('test://test.sql', 'sql', 1, 'SELECT a, b FROM table1 WHERE c > 1');
34
+ const result = server.parseStructure(doc);
35
+ (0, chai_1.expect)(result.nodes.length).to.be.greaterThan(0);
36
+ });
37
+ it('should parse structure for INSERT statement', () => {
38
+ const doc = vscode_languageserver_textdocument_1.TextDocument.create('test://test.sql', 'sql', 1, 'INSERT INTO target_table SELECT * FROM source_table');
39
+ const result = server.parseStructure(doc);
40
+ (0, chai_1.expect)(result.nodes.length).to.be.greaterThan(0);
41
+ });
42
+ });
43
+ describe('getLineage', () => {
44
+ it('should get lineage for SELECT query', () => {
45
+ const doc = vscode_languageserver_textdocument_1.TextDocument.create('test://test.sql', 'sql', 1, 'SELECT a, b FROM table1');
46
+ const lineage = server.getLineage(doc);
47
+ (0, chai_1.expect)(lineage.nodes.length).to.be.greaterThan(0);
48
+ });
49
+ it('should get lineage for CREATE VIEW statement', () => {
50
+ const doc = vscode_languageserver_textdocument_1.TextDocument.create('test://test.sql', 'sql', 1, 'CREATE VIEW my_view AS SELECT a, b FROM table1');
51
+ const lineage = server.getLineage(doc);
52
+ (0, chai_1.expect)(lineage.nodes.length).to.be.greaterThan(0);
53
+ });
54
+ });
55
+ describe('collectTokens', () => {
56
+ it('should collect tokens from SQL', () => {
57
+ const doc = vscode_languageserver_textdocument_1.TextDocument.create('test://test.sql', 'sql', 1, "SELECT name FROM users WHERE id = 'test'");
58
+ const tokens = server.collectTokens(doc);
59
+ (0, chai_1.expect)(tokens.semanticTokens.length).to.be.greaterThanOrEqual(0);
60
+ });
61
+ });
62
+ describe('doFoldingRanges', () => {
63
+ it('should fold WITH clause with multiple CTEs', () => {
64
+ // 使用简化的、确定有效的 Spark SQL
65
+ const sql = `WITH cte1 AS (
66
+ SELECT
67
+ id,
68
+ name
69
+ FROM t1
70
+ ),
71
+ cte2 AS (
72
+ SELECT
73
+ id,
74
+ CASE
75
+ WHEN id > 100 THEN 1
76
+ ELSE 0
77
+ END AS flag
78
+ FROM cte1
79
+ )
80
+ SELECT * FROM cte2`;
81
+ const doc = vscode_languageserver_textdocument_1.TextDocument.create('test://test.sql', 'sql', 1, sql);
82
+ const ranges = server.doFoldingRanges(doc);
83
+ // 应该有多个折叠范围,包括两个 CTE 内的 SELECT
84
+ (0, chai_1.expect)(ranges.length).to.be.greaterThan(5);
85
+ // 第一个 SELECT 在第 1-4 行
86
+ const firstSelectRange = ranges.find(r => r.startLine === 1 && r.endLine === 4);
87
+ (0, chai_1.expect)(firstSelectRange).to.not.be.undefined;
88
+ // 第二个 SELECT 在第 7-13 行
89
+ const secondSelectRange = ranges.find(r => r.startLine === 7 && r.endLine === 13);
90
+ (0, chai_1.expect)(secondSelectRange).to.not.be.undefined;
91
+ });
92
+ it('should fold main SELECT after WITH clause', () => {
93
+ const sql = `WITH user_metrics AS (
94
+ SELECT
95
+ u.id,
96
+ u.name,
97
+ COUNT(o.order_id) AS order_count,
98
+ SUM(o.amount) AS total_amount
99
+ FROM users u
100
+ LEFT JOIN orders o ON u.id = o.user_id
101
+ GROUP BY u.id, u.name
102
+ ),
103
+ user_segments AS (
104
+ SELECT
105
+ id,
106
+ name,
107
+ order_count,
108
+ total_amount,
109
+ CASE
110
+ WHEN total_amount >= 10000 THEN 'VIP'
111
+ WHEN total_amount >= 5000 THEN 'Gold'
112
+ WHEN total_amount >= 1000 THEN 'Silver'
113
+ ELSE 'Bronze'
114
+ END AS segment,
115
+ CASE
116
+ WHEN order_count >= 20 THEN 'High Frequency'
117
+ WHEN order_count >= 10 THEN 'Medium Frequency'
118
+ ELSE 'Low Frequency'
119
+ END AS frequency_tier
120
+ FROM user_metrics
121
+ )
122
+ SELECT
123
+ segment,
124
+ frequency_tier,
125
+ COUNT(*) AS user_count,
126
+ AVG(total_amount) AS avg_spending
127
+ FROM user_segments
128
+ GROUP BY segment, frequency_tier
129
+ ORDER BY
130
+ CASE segment
131
+ WHEN 'VIP' THEN 1
132
+ WHEN 'Gold' THEN 2
133
+ WHEN 'Silver' THEN 3
134
+ ELSE 4
135
+ END`;
136
+ const doc = vscode_languageserver_textdocument_1.TextDocument.create('test://test.sql', 'sql', 1, sql);
137
+ // 先验证语法正确
138
+ const errors = server.doValidation(doc);
139
+ (0, chai_1.expect)(errors.length, 'SQL should have no syntax errors').to.equal(0);
140
+ const ranges = server.doFoldingRanges(doc);
141
+ // 主 SELECT 从第 29 行开始 (0-indexed),到第 35 行结束(FROM user_segments 到 ORDER BY 之前)
142
+ // 实际上主 SELECT 块包含 SELECT, FROM, GROUP BY,到 ORDER BY 之前
143
+ const mainSelectRange = ranges.find(r => r.startLine === 29);
144
+ (0, chai_1.expect)(mainSelectRange, 'Main SELECT (starting at line 29) should have a folding range').to.not.be.undefined;
145
+ // 验证 ORDER BY 中的 CASE 也被折叠
146
+ const orderByCaseRange = ranges.find(r => r.startLine === 37);
147
+ (0, chai_1.expect)(orderByCaseRange, 'ORDER BY CASE should have a folding range').to.not.be.undefined;
148
+ // 验证 CTE 内部的 SELECT 也被折叠
149
+ // 第一个 CTE 的 SELECT 从第 1 行开始
150
+ const firstCteSelectRange = ranges.find(r => r.startLine === 1);
151
+ (0, chai_1.expect)(firstCteSelectRange, 'First CTE SELECT should have a folding range').to.not.be.undefined;
152
+ // 第二个 CTE 的 SELECT 从第 11 行开始
153
+ const secondCteSelectRange = ranges.find(r => r.startLine === 11);
154
+ (0, chai_1.expect)(secondCteSelectRange, 'Second CTE SELECT should have a folding range').to.not.be.undefined;
155
+ });
156
+ it('should fold CREATE TEMPORARY VIEW statements', () => {
157
+ // 测试大写语法
158
+ const sql = `CREATE TEMPORARY VIEW nt1 AS SELECT * FROM VALUES
159
+ ('one', 1),
160
+ ('two', 2),
161
+ ('three', 3)
162
+ AS nt1(k, v1)`;
163
+ const doc = vscode_languageserver_textdocument_1.TextDocument.create('test://test.sql', 'sql', 1, sql);
164
+ const errors = server.doValidation(doc);
165
+ console.log('CREATE VIEW errors:', errors.length > 0 ? errors[0].message : 'none');
166
+ const ranges = server.doFoldingRanges(doc);
167
+ const lines = sql.split('\n');
168
+ console.log('CREATE VIEW folding ranges:');
169
+ ranges.forEach((r, i) => {
170
+ console.log(` ${i}: lines ${r.startLine}-${r.endLine} (${lines[r.startLine]?.trim().substring(0, 40)}...)`);
171
+ });
172
+ // CREATE VIEW 应该能折叠
173
+ const viewRange = ranges.find(r => r.startLine === 0);
174
+ (0, chai_1.expect)(viewRange, 'CREATE VIEW should have a folding range').to.not.be.undefined;
175
+ });
176
+ it('should handle case sensitivity', () => {
177
+ // 测试小写 SELECT
178
+ const sql1 = 'select * from users';
179
+ const doc1 = vscode_languageserver_textdocument_1.TextDocument.create('test://test.sql', 'sql', 1, sql1);
180
+ const errors1 = server.doValidation(doc1);
181
+ console.log('小写 select:', errors1.length > 0 ? 'ERROR' : 'OK');
182
+ (0, chai_1.expect)(errors1.length, '小写 select 应该无错误').to.equal(0);
183
+ // 测试小写 create view
184
+ const sql2 = 'create view v as select 1';
185
+ const doc2 = vscode_languageserver_textdocument_1.TextDocument.create('test://test.sql', 'sql', 1, sql2);
186
+ const errors2 = server.doValidation(doc2);
187
+ console.log('小写 create view:', errors2.length > 0 ? 'ERROR' : 'OK');
188
+ (0, chai_1.expect)(errors2.length, '小写 create view 应该无错误').to.equal(0);
189
+ // 测试小写 create temporary view
190
+ const sql3 = `create temporary view nt1 as select * from values
191
+ ('one', 1),
192
+ ('two', 2)
193
+ as nt1(k, v1)`;
194
+ const doc3 = vscode_languageserver_textdocument_1.TextDocument.create('test://test.sql', 'sql', 1, sql3);
195
+ const errors3 = server.doValidation(doc3);
196
+ console.log('小写 create temporary view:', errors3.length > 0 ? 'ERROR' : 'OK');
197
+ (0, chai_1.expect)(errors3.length, '小写 create temporary view 应该无错误').to.equal(0);
198
+ });
199
+ it('should fold lowercase CREATE TEMPORARY VIEW statements', () => {
200
+ const sql = `create temporary view nt1 as select * from values
201
+ ("one", 1),
202
+ ("two", 2),
203
+ ("three", 3)
204
+ as nt1(k, v1);
205
+
206
+ create temporary view nt2 as select * from values
207
+ ("one", 1),
208
+ ("two", 22),
209
+ ("one", 5)
210
+ as nt2(k, v2)`;
211
+ const doc = vscode_languageserver_textdocument_1.TextDocument.create('test://test.sql', 'sql', 1, sql);
212
+ const ranges = server.doFoldingRanges(doc);
213
+ const lines = sql.split('\n');
214
+ console.log('小写 CREATE VIEW 折叠范围:');
215
+ ranges.forEach((r, i) => {
216
+ console.log(` ${i}: lines ${r.startLine}-${r.endLine} (${lines[r.startLine]?.trim().substring(0, 40)}...)`);
217
+ });
218
+ // 第一个 CREATE VIEW 应该能折叠
219
+ const firstViewRange = ranges.find(r => r.startLine === 0);
220
+ (0, chai_1.expect)(firstViewRange, '第一个小写 CREATE VIEW 应该有折叠范围').to.not.be.undefined;
221
+ // 第二个 CREATE VIEW 应该能折叠
222
+ const secondViewRange = ranges.find(r => r.startLine === 6);
223
+ (0, chai_1.expect)(secondViewRange, '第二个小写 CREATE VIEW 应该有折叠范围').to.not.be.undefined;
224
+ });
225
+ });
226
+ describe('doFormatting', () => {
227
+ it('should format SELECT query with proper indentation', () => {
228
+ // 格式混乱的 SQL
229
+ const sql = 'SELECT a,b,c FROM users WHERE id=1 AND name="test"';
230
+ const doc = vscode_languageserver_textdocument_1.TextDocument.create('test://test.sql', 'sql', 1, sql);
231
+ const edits = server.doFormatting(doc, { tabSize: 2, insertSpaces: true });
232
+ // 应该返回格式化的编辑
233
+ (0, chai_1.expect)(edits.length).to.be.greaterThan(0);
234
+ });
235
+ it('should format CTE with proper indentation', () => {
236
+ const sql = `WITH cte AS (SELECT id FROM t) SELECT * FROM cte`;
237
+ const doc = vscode_languageserver_textdocument_1.TextDocument.create('test://test.sql', 'sql', 1, sql);
238
+ const edits = server.doFormatting(doc, { tabSize: 2, insertSpaces: true });
239
+ // 应该返回格式化的编辑
240
+ (0, chai_1.expect)(edits.length).to.be.greaterThan(0);
241
+ });
242
+ it('should format CREATE VIEW statement', () => {
243
+ const sql = 'CREATE VIEW v AS SELECT a,b FROM t';
244
+ const doc = vscode_languageserver_textdocument_1.TextDocument.create('test://test.sql', 'sql', 1, sql);
245
+ const edits = server.doFormatting(doc, { tabSize: 2, insertSpaces: true });
246
+ // 应该返回格式化的编辑
247
+ (0, chai_1.expect)(edits.length).to.be.greaterThan(0);
248
+ });
249
+ it('should not break folding functionality after formatting', () => {
250
+ const sql = `WITH cte1 AS (
251
+ SELECT id FROM t1
252
+ ),
253
+ cte2 AS (
254
+ SELECT id FROM cte1
255
+ )
256
+ SELECT * FROM cte2`;
257
+ const doc = vscode_languageserver_textdocument_1.TextDocument.create('test://test.sql', 'sql', 1, sql);
258
+ // 执行格式化
259
+ const edits = server.doFormatting(doc, { tabSize: 2, insertSpaces: true });
260
+ (0, chai_1.expect)(edits).to.be.an('array');
261
+ // 验证折叠仍然工作
262
+ const ranges = server.doFoldingRanges(doc);
263
+ (0, chai_1.expect)(ranges.length).to.be.greaterThan(0);
264
+ });
265
+ it('should not break completion functionality after formatting', () => {
266
+ const sql = 'SELECT ';
267
+ const doc = vscode_languageserver_textdocument_1.TextDocument.create('test://test.sql', 'sql', 1, sql);
268
+ // 执行格式化
269
+ const edits = server.doFormatting(doc, { tabSize: 2, insertSpaces: true });
270
+ (0, chai_1.expect)(edits).to.be.an('array');
271
+ // 验证补全仍然工作
272
+ const result = server.doCompletion(doc, { line: 0, character: 7 });
273
+ (0, chai_1.expect)(result.completionItems.length).to.be.greaterThan(0);
274
+ });
275
+ // 辅助函数:应用 TextEdit 到文本
276
+ function applyTextEdits(text, edits) {
277
+ // 按照从后往前的顺序排序编辑(避免位置偏移问题)
278
+ const sortedEdits = [...edits].sort((a, b) => {
279
+ if (a.range.start.line !== b.range.start.line) {
280
+ return b.range.start.line - a.range.start.line;
281
+ }
282
+ return b.range.start.character - a.range.start.character;
283
+ });
284
+ const lines = text.split('\n');
285
+ for (const edit of sortedEdits) {
286
+ const startLine = edit.range.start.line;
287
+ const endLine = edit.range.end.line;
288
+ const startChar = edit.range.start.character;
289
+ const endChar = edit.range.end.character;
290
+ if (startLine === endLine) {
291
+ // 单行编辑
292
+ lines[startLine] =
293
+ lines[startLine].substring(0, startChar) + edit.newText + lines[startLine].substring(endChar);
294
+ }
295
+ else {
296
+ // 多行编辑
297
+ const before = lines[startLine].substring(0, startChar);
298
+ const after = lines[endLine].substring(endChar);
299
+ const newText = before + edit.newText + after;
300
+ lines.splice(startLine, endLine - startLine + 1, ...newText.split('\n'));
301
+ }
302
+ }
303
+ return lines.join('\n');
304
+ }
305
+ it('should be idempotent - formatting twice produces same result (CREATE VIEW)', () => {
306
+ const sql = 'CREATE VIEW v AS SELECT a FROM t';
307
+ // 使用不同的 URI 避免缓存问题
308
+ const doc1 = vscode_languageserver_textdocument_1.TextDocument.create('test://test1.sql', 'sql', 1, sql);
309
+ // 第一次格式化
310
+ const edits1 = server.doFormatting(doc1, { tabSize: 2, insertSpaces: true });
311
+ console.log('CREATE VIEW 第一次编辑列表:');
312
+ edits1.forEach((edit, i) => {
313
+ console.log(` ${i}: [${edit.range.start.line}:${edit.range.start.character} -> ${edit.range.end.line}:${edit.range.end.character}] = ${JSON.stringify(edit.newText)}`);
314
+ });
315
+ const formatted1 = applyTextEdits(sql, edits1);
316
+ console.log('第一次格式化结果:', JSON.stringify(formatted1));
317
+ // 第二次格式化 - 使用不同的 URI
318
+ const doc2 = vscode_languageserver_textdocument_1.TextDocument.create('test://test2.sql', 'sql', 1, formatted1);
319
+ const edits2 = server.doFormatting(doc2, { tabSize: 2, insertSpaces: true });
320
+ console.log('CREATE VIEW 第二次编辑列表:');
321
+ edits2.forEach((edit, i) => {
322
+ console.log(` ${i}: [${edit.range.start.line}:${edit.range.start.character} -> ${edit.range.end.line}:${edit.range.end.character}] = ${JSON.stringify(edit.newText)}`);
323
+ });
324
+ const formatted2 = applyTextEdits(formatted1, edits2);
325
+ console.log('第二次格式化结果:', JSON.stringify(formatted2));
326
+ // 第三次格式化 - 使用不同的 URI
327
+ const doc3 = vscode_languageserver_textdocument_1.TextDocument.create('test://test3.sql', 'sql', 1, formatted2);
328
+ const edits3 = server.doFormatting(doc3, { tabSize: 2, insertSpaces: true });
329
+ const formatted3 = applyTextEdits(formatted2, edits3);
330
+ console.log('第三次格式化结果:', JSON.stringify(formatted3));
331
+ // 两次格式化的结果应该相同(幂等性)
332
+ (0, chai_1.expect)(formatted2, '格式化应该是幂等的').to.equal(formatted1);
333
+ (0, chai_1.expect)(formatted3, '格式化应该是幂等的').to.equal(formatted2);
334
+ });
335
+ it('should be idempotent - formatting twice produces same result (CTE)', () => {
336
+ const sql = 'WITH cte AS (SELECT id FROM t) SELECT * FROM cte';
337
+ const doc1 = vscode_languageserver_textdocument_1.TextDocument.create('test://cte1.sql', 'sql', 1, sql);
338
+ // 第一次格式化
339
+ const edits1 = server.doFormatting(doc1, { tabSize: 2, insertSpaces: true });
340
+ const formatted1 = applyTextEdits(sql, edits1);
341
+ console.log('CTE 第一次格式化结果:', JSON.stringify(formatted1));
342
+ // 第二次格式化 - 使用不同的 URI
343
+ const doc2 = vscode_languageserver_textdocument_1.TextDocument.create('test://cte2.sql', 'sql', 1, formatted1);
344
+ const edits2 = server.doFormatting(doc2, { tabSize: 2, insertSpaces: true });
345
+ const formatted2 = applyTextEdits(formatted1, edits2);
346
+ console.log('CTE 第二次格式化结果:', JSON.stringify(formatted2));
347
+ // 第三次格式化 - 使用不同的 URI
348
+ const doc3 = vscode_languageserver_textdocument_1.TextDocument.create('test://cte3.sql', 'sql', 1, formatted2);
349
+ const edits3 = server.doFormatting(doc3, { tabSize: 2, insertSpaces: true });
350
+ const formatted3 = applyTextEdits(formatted2, edits3);
351
+ console.log('CTE 第三次格式化结果:', JSON.stringify(formatted3));
352
+ // 格式化应该是幂等的
353
+ (0, chai_1.expect)(formatted2, '格式化应该是幂等的').to.equal(formatted1);
354
+ (0, chai_1.expect)(formatted3, '格式化应该是幂等的').to.equal(formatted2);
355
+ });
356
+ it('should be idempotent - formatting twice produces same result (AS alias)', () => {
357
+ const sql = 'SELECT a AS alias FROM t';
358
+ const doc1 = vscode_languageserver_textdocument_1.TextDocument.create('test://alias1.sql', 'sql', 1, sql);
359
+ // 第一次格式化
360
+ const edits1 = server.doFormatting(doc1, { tabSize: 2, insertSpaces: true });
361
+ const formatted1 = applyTextEdits(sql, edits1);
362
+ console.log('AS alias 第一次格式化结果:', JSON.stringify(formatted1));
363
+ // 第二次格式化 - 使用不同的 URI
364
+ const doc2 = vscode_languageserver_textdocument_1.TextDocument.create('test://alias2.sql', 'sql', 1, formatted1);
365
+ const edits2 = server.doFormatting(doc2, { tabSize: 2, insertSpaces: true });
366
+ const formatted2 = applyTextEdits(formatted1, edits2);
367
+ console.log('AS alias 第二次格式化结果:', JSON.stringify(formatted2));
368
+ // 格式化应该是幂等的
369
+ (0, chai_1.expect)(formatted2, '格式化应该是幂等的').to.equal(formatted1);
370
+ });
371
+ it('should format CREATE TABLE statement and be idempotent', () => {
372
+ const sql = `CREATE TABLE IF
373
+ NOT EXISTS
374
+ test_inner_variable (a string, b int) PARTITIONED BY (pt string)`;
375
+ const doc1 = vscode_languageserver_textdocument_1.TextDocument.create('test://create-table1.sql', 'sql', 1, sql);
376
+ // 先验证语法正确
377
+ const errors = server.doValidation(doc1);
378
+ (0, chai_1.expect)(errors.length, 'CREATE TABLE 语法应该正确').to.equal(0);
379
+ // 第一次格式化
380
+ const edits1 = server.doFormatting(doc1, { tabSize: 2, insertSpaces: true });
381
+ console.log('CREATE TABLE 第一次编辑数量:', edits1.length);
382
+ const formatted1 = applyTextEdits(sql, edits1);
383
+ console.log('CREATE TABLE 第一次格式化结果:', JSON.stringify(formatted1));
384
+ // 应该产生格式化编辑
385
+ (0, chai_1.expect)(edits1.length, 'CREATE TABLE 应该产生格式化编辑').to.be.greaterThan(0);
386
+ // 第二次格式化 - 验证幂等性
387
+ const doc2 = vscode_languageserver_textdocument_1.TextDocument.create('test://create-table2.sql', 'sql', 1, formatted1);
388
+ const edits2 = server.doFormatting(doc2, { tabSize: 2, insertSpaces: true });
389
+ const formatted2 = applyTextEdits(formatted1, edits2);
390
+ console.log('CREATE TABLE 第二次格式化结果:', JSON.stringify(formatted2));
391
+ // 格式化应该是幂等的
392
+ (0, chai_1.expect)(formatted2, 'CREATE TABLE 格式化应该是幂等的').to.equal(formatted1);
393
+ });
394
+ it('should format INSERT statement with VALUES indentation', () => {
395
+ const sql = `INSERT OVERWRITE test_inner_variable PARTITION (pt = '\${ ds }') VALUES ('abc', 1), ('def', 2)`;
396
+ const doc1 = vscode_languageserver_textdocument_1.TextDocument.create('test://insert1.sql', 'sql', 1, sql);
397
+ // 先验证语法正确
398
+ const errors = server.doValidation(doc1);
399
+ (0, chai_1.expect)(errors.length, 'INSERT 语法应该正确').to.equal(0);
400
+ // 第一次格式化
401
+ const edits1 = server.doFormatting(doc1, { tabSize: 2, insertSpaces: true });
402
+ const formatted1 = applyTextEdits(sql, edits1);
403
+ console.log('INSERT 第一次格式化结果:', JSON.stringify(formatted1));
404
+ // 应该产生格式化编辑
405
+ (0, chai_1.expect)(edits1.length, 'INSERT 应该产生格式化编辑').to.be.greaterThan(0);
406
+ // 验证 PARTITION 和 VALUES 有缩进
407
+ (0, chai_1.expect)(formatted1).to.include('PARTITION');
408
+ (0, chai_1.expect)(formatted1).to.include('VALUES');
409
+ // 第二次格式化 - 验证幂等性
410
+ const doc2 = vscode_languageserver_textdocument_1.TextDocument.create('test://insert2.sql', 'sql', 1, formatted1);
411
+ const edits2 = server.doFormatting(doc2, { tabSize: 2, insertSpaces: true });
412
+ const formatted2 = applyTextEdits(formatted1, edits2);
413
+ console.log('INSERT 第二次格式化结果:', JSON.stringify(formatted2));
414
+ // 格式化应该是幂等的
415
+ (0, chai_1.expect)(formatted2, 'INSERT 格式化应该是幂等的').to.equal(formatted1);
416
+ });
417
+ it('should remove extra newlines before semicolon', () => {
418
+ // SQL 语句分号前有多个换行符
419
+ const sql = `SELECT * FROM t
420
+
421
+
422
+ ;`;
423
+ const doc1 = vscode_languageserver_textdocument_1.TextDocument.create('test://semicolon1.sql', 'sql', 1, sql);
424
+ // 先验证语法正确
425
+ const errors = server.doValidation(doc1);
426
+ console.log('分号测试验证结果:', errors.length > 0 ? errors[0].message : '无错误');
427
+ // 第一次格式化
428
+ const edits1 = server.doFormatting(doc1, { tabSize: 2, insertSpaces: true });
429
+ const formatted1 = applyTextEdits(sql, edits1);
430
+ console.log('分号测试第一次格式化结果:', JSON.stringify(formatted1));
431
+ // 格式化后分号前不应该有多余的换行符
432
+ (0, chai_1.expect)(formatted1).to.not.match(/\n\s*\n\s*;/);
433
+ // 第二次格式化 - 验证幂等性
434
+ const doc2 = vscode_languageserver_textdocument_1.TextDocument.create('test://semicolon2.sql', 'sql', 1, formatted1);
435
+ const edits2 = server.doFormatting(doc2, { tabSize: 2, insertSpaces: true });
436
+ const formatted2 = applyTextEdits(formatted1, edits2);
437
+ console.log('分号测试第二次格式化结果:', JSON.stringify(formatted2));
438
+ // 格式化应该是幂等的
439
+ (0, chai_1.expect)(formatted2, '格式化应该是幂等的').to.equal(formatted1);
440
+ });
441
+ it('should handle multiple newlines before column definitions', () => {
442
+ // 列定义前有多个换行符
443
+ const sql = `CREATE TABLE test
444
+
445
+
446
+ (a string, b int)`;
447
+ const doc1 = vscode_languageserver_textdocument_1.TextDocument.create('test://newlines1.sql', 'sql', 1, sql);
448
+ // 先验证语法正确
449
+ const errors = server.doValidation(doc1);
450
+ console.log('列定义换行测试验证结果:', errors.length > 0 ? errors[0].message : '无错误');
451
+ // 第一次格式化
452
+ const edits1 = server.doFormatting(doc1, { tabSize: 2, insertSpaces: true });
453
+ console.log('列定义换行测试编辑数量:', edits1.length);
454
+ edits1.forEach((edit, i) => {
455
+ console.log(` ${i}: [${edit.range.start.line}:${edit.range.start.character} -> ${edit.range.end.line}:${edit.range.end.character}] = ${JSON.stringify(edit.newText)}`);
456
+ });
457
+ const formatted1 = applyTextEdits(sql, edits1);
458
+ console.log('列定义换行测试第一次格式化结果:', JSON.stringify(formatted1));
459
+ // 应该产生格式化编辑,移除多余的换行
460
+ (0, chai_1.expect)(edits1.length, '应该产生格式化编辑').to.be.greaterThan(0);
461
+ // 格式化后不应该有多余的空行
462
+ (0, chai_1.expect)(formatted1).to.not.match(/CREATE TABLE test\n\n+\(/);
463
+ // 第二次格式化 - 验证幂等性
464
+ const doc2 = vscode_languageserver_textdocument_1.TextDocument.create('test://newlines2.sql', 'sql', 1, formatted1);
465
+ const edits2 = server.doFormatting(doc2, { tabSize: 2, insertSpaces: true });
466
+ const formatted2 = applyTextEdits(formatted1, edits2);
467
+ console.log('列定义换行测试第二次格式化结果:', JSON.stringify(formatted2));
468
+ // 格式化应该是幂等的
469
+ (0, chai_1.expect)(formatted2, '格式化应该是幂等的').to.equal(formatted1);
470
+ });
471
+ it('should format complex SQL with ROW_NUMBER correctly', () => {
472
+ const sql = `CREATE TEMPORARY VIEW dim_pub_uni_pruchase_item_tmp
473
+ AS SELECT
474
+ app_id
475
+ ,item_id
476
+ ,item_type
477
+ ,product_price
478
+ ,update_time
479
+ FROM (
480
+ SELECT
481
+ b.app_id
482
+ ,a.item_id
483
+ ,a.item_type
484
+ ,CAST(CAST(a.price AS DECIMAL(18, 2)) / 100 AS DECIMAL(18, 2)) AS product_price
485
+ ,a.update_time
486
+ ,ROW_NUMBER(
487
+
488
+ ) OVER (
489
+ PARTITION BY b.app_id, a.item_id
490
+ ORDER BY a.update_time DESC) AS rn
491
+ FROM nd_game_pub_cdm.dim_pub_uni_pruchase_item a
492
+ INNER JOIN nd_game_pub_cdm.dim_pub_uni_app_info_item_ref b
493
+ ON a.id = b.purchase_item_id
494
+ ) t
495
+ WHERE rn = 1;`;
496
+ const doc = vscode_languageserver_textdocument_1.TextDocument.create('test://complex.sql', 'sql', 1, sql);
497
+ const edits = server.doFormatting(doc, { tabSize: 2, insertSpaces: true });
498
+ const formatted = applyTextEdits(sql, edits);
499
+ // ROW_NUMBER should not corrupt PARTITION
500
+ (0, chai_1.expect)(formatted).to.include('PARTITION BY');
501
+ // ROW_NUMBER() should be on one line (not split)
502
+ (0, chai_1.expect)(formatted).to.include('ROW_NUMBER()');
503
+ // Trailing comma style
504
+ (0, chai_1.expect)(formatted).to.include('app_id,');
505
+ });
506
+ it('should format pipe operator SELECT correctly', () => {
507
+ // Based on pipe.sql example
508
+ const sql = 'from t |> select x';
509
+ const doc = vscode_languageserver_textdocument_1.TextDocument.create('test://pipe-select.sql', 'sql', 1, sql);
510
+ const edits = server.doFormatting(doc, { tabSize: 2, insertSpaces: true });
511
+ const formatted = applyTextEdits(sql, edits);
512
+ console.log('Pipe SELECT 格式化结果:');
513
+ console.log(formatted);
514
+ // 验证格式化结果
515
+ // from 后面缩进2空格
516
+ (0, chai_1.expect)(formatted).to.include('from\n t');
517
+ // |> select 在同一行
518
+ (0, chai_1.expect)(formatted).to.include('\n|> select');
519
+ });
520
+ it('should format chained pipe operators correctly', () => {
521
+ // Based on pipe.sql example (lines 22-31)
522
+ const sql = `from t as t_alias |> select t_alias.x as tx, t_alias.y as ty |> where ty = 'def' |> select tx`;
523
+ const doc = vscode_languageserver_textdocument_1.TextDocument.create('test://pipe-chained.sql', 'sql', 1, sql);
524
+ const edits = server.doFormatting(doc, { tabSize: 2, insertSpaces: true });
525
+ const formatted = applyTextEdits(sql, edits);
526
+ console.log('Chained pipe 格式化结果:');
527
+ console.log(formatted);
528
+ // 验证格式化结果基本结构
529
+ (0, chai_1.expect)(formatted).to.include('from\n t as t_alias');
530
+ (0, chai_1.expect)(formatted).to.include('|> select');
531
+ (0, chai_1.expect)(formatted).to.include('where');
532
+ });
533
+ it('should format pipe SELECT with subquery expression correctly', () => {
534
+ // Based on pipe.sql example (lines 150-161)
535
+ const sql = 'table t |> select (select a from other where x = a limit 1) as result';
536
+ const doc = vscode_languageserver_textdocument_1.TextDocument.create('test://pipe-subquery.sql', 'sql', 1, sql);
537
+ const edits = server.doFormatting(doc, { tabSize: 2, insertSpaces: true });
538
+ const formatted = applyTextEdits(sql, edits);
539
+ console.log('子查询格式化结果:');
540
+ console.log(formatted);
541
+ // 验证格式化结果基本结构
542
+ (0, chai_1.expect)(formatted).to.include('table t');
543
+ (0, chai_1.expect)(formatted).to.include('|> select');
544
+ (0, chai_1.expect)(formatted).to.include('as result');
545
+ });
546
+ it('should format pipe with LATERAL VIEW correctly', () => {
547
+ // Based on pipe.sql example (lines 48-53)
548
+ const sql = 'from t lateral view explode(array(100, 101)) as ly |> select t.x + ly as z';
549
+ const doc = vscode_languageserver_textdocument_1.TextDocument.create('test://pipe-lateral-view.sql', 'sql', 1, sql);
550
+ const edits = server.doFormatting(doc, { tabSize: 2, insertSpaces: true });
551
+ const formatted = applyTextEdits(sql, edits);
552
+ console.log('LATERAL VIEW 格式化结果:');
553
+ console.log(formatted);
554
+ // 验证格式化结果基本结构
555
+ (0, chai_1.expect)(formatted).to.include('from\n t');
556
+ (0, chai_1.expect)(formatted).to.include('lateral view');
557
+ (0, chai_1.expect)(formatted).to.include('|> select');
558
+ });
559
+ it('should format pipe with LATERAL VIEW containing newlines', () => {
560
+ // Test case where input already has newlines between lateral and view
561
+ const sql = `from
562
+ t
563
+ lateral
564
+ view
565
+ explode(array(100, 101)) as ly
566
+ |> select
567
+ t.x + ly as z;`;
568
+ const doc = vscode_languageserver_textdocument_1.TextDocument.create('test://pipe-lateral-newline.sql', 'sql', 1, sql);
569
+ const edits = server.doFormatting(doc, { tabSize: 2, insertSpaces: true });
570
+ const formatted = applyTextEdits(sql, edits);
571
+ console.log('LATERAL VIEW (含换行输入) 格式化结果:');
572
+ console.log(formatted);
573
+ // 验证格式化结果基本结构
574
+ (0, chai_1.expect)(formatted).to.include('lateral view');
575
+ (0, chai_1.expect)(formatted).to.include('|> select');
576
+ });
577
+ it('should format LATERAL VIEW with AS alias on same line', () => {
578
+ // Test case where AS alias has newline before it
579
+ const sql = `from
580
+ t
581
+ lateral view explode(array(100, 101))
582
+ as ly
583
+ |> select
584
+ t.x + ly as z;`;
585
+ const doc = vscode_languageserver_textdocument_1.TextDocument.create('test://pipe-lateral-as.sql', 'sql', 1, sql);
586
+ const edits = server.doFormatting(doc, { tabSize: 2, insertSpaces: true });
587
+ const formatted = applyTextEdits(sql, edits);
588
+ console.log('LATERAL VIEW AS 别名格式化结果:');
589
+ console.log(formatted);
590
+ // 验证格式化结果基本结构
591
+ (0, chai_1.expect)(formatted).to.include('lateral view');
592
+ (0, chai_1.expect)(formatted).to.include('as ly');
593
+ });
594
+ it('should format pipe SELECT with OVER clause correctly', () => {
595
+ // Based on pipe.sql example (lines 196-206)
596
+ const sql = 'select 1 x, 2 y, 3 z |> select 1 + sum(x) over (), avg(y) over (), x, avg(x + 1) over (partition by y order by z) AS a2 |> select a2';
597
+ const doc = vscode_languageserver_textdocument_1.TextDocument.create('test://pipe-over.sql', 'sql', 1, sql);
598
+ const edits = server.doFormatting(doc, { tabSize: 2, insertSpaces: true });
599
+ const formatted = applyTextEdits(sql, edits);
600
+ console.log('OVER 子句格式化结果:');
601
+ console.log(formatted);
602
+ // 验证格式化结果基本结构
603
+ (0, chai_1.expect)(formatted).to.include('|> select');
604
+ (0, chai_1.expect)(formatted).to.include('over ()');
605
+ });
606
+ it('should format pipe SELECT with OVER clause containing newlines', () => {
607
+ // Test case where input already has newlines inside OVER parentheses
608
+ const sql = `select
609
+ 1 x
610
+ |> select
611
+ sum(x) over (
612
+ ),
613
+ avg(x + 1) over (
614
+ partition by y
615
+ order by z
616
+ ) AS a2`;
617
+ const doc = vscode_languageserver_textdocument_1.TextDocument.create('test://pipe-over-newline.sql', 'sql', 1, sql);
618
+ const edits = server.doFormatting(doc, { tabSize: 2, insertSpaces: true });
619
+ const formatted = applyTextEdits(sql, edits);
620
+ console.log('OVER 子句 (含换行输入) 格式化结果:');
621
+ console.log(formatted);
622
+ // 验证格式化结果基本结构
623
+ (0, chai_1.expect)(formatted).to.include('|> select');
624
+ });
625
+ it('should format pipe EXTEND operator correctly', () => {
626
+ const sql = 'table t |> extend x + length(y) as z';
627
+ const doc = vscode_languageserver_textdocument_1.TextDocument.create('test://pipe-extend.sql', 'sql', 1, sql);
628
+ const edits = server.doFormatting(doc, { tabSize: 2, insertSpaces: true });
629
+ const formatted = applyTextEdits(sql, edits);
630
+ console.log('EXTEND 格式化结果:');
631
+ console.log(formatted);
632
+ // 验证格式化结果基本结构
633
+ (0, chai_1.expect)(formatted).to.include('|> extend');
634
+ });
635
+ it('should format pipe SET operator correctly', () => {
636
+ const sql = 'table t |> set x = 1';
637
+ const doc = vscode_languageserver_textdocument_1.TextDocument.create('test://pipe-set.sql', 'sql', 1, sql);
638
+ const edits = server.doFormatting(doc, { tabSize: 2, insertSpaces: true });
639
+ const formatted = applyTextEdits(sql, edits);
640
+ console.log('SET 格式化结果:');
641
+ console.log(formatted);
642
+ // 验证格式化结果基本结构
643
+ (0, chai_1.expect)(formatted).to.include('|> set');
644
+ });
645
+ it('should format pipe SET with multiple expressions correctly', () => {
646
+ const sql = 'table t |> set x = 1, y = 2';
647
+ const doc = vscode_languageserver_textdocument_1.TextDocument.create('test://pipe-set-multi.sql', 'sql', 1, sql);
648
+ const edits = server.doFormatting(doc, { tabSize: 2, insertSpaces: true });
649
+ const formatted = applyTextEdits(sql, edits);
650
+ console.log('SET 多表达式格式化结果:');
651
+ console.log(formatted);
652
+ // 验证格式化结果基本结构
653
+ (0, chai_1.expect)(formatted).to.include('|> set');
654
+ });
655
+ it('should format pipe DROP operator correctly', () => {
656
+ const sql = 'table t |> drop y';
657
+ const doc = vscode_languageserver_textdocument_1.TextDocument.create('test://pipe-drop.sql', 'sql', 1, sql);
658
+ const edits = server.doFormatting(doc, { tabSize: 2, insertSpaces: true });
659
+ const formatted = applyTextEdits(sql, edits);
660
+ console.log('DROP 格式化结果:');
661
+ console.log(formatted);
662
+ (0, chai_1.expect)(formatted).to.include('|> drop');
663
+ });
664
+ it('should format pipe AS operator correctly', () => {
665
+ const sql = 'table t |> as u |> select u.x';
666
+ const doc = vscode_languageserver_textdocument_1.TextDocument.create('test://pipe-as.sql', 'sql', 1, sql);
667
+ const edits = server.doFormatting(doc, { tabSize: 2, insertSpaces: true });
668
+ const formatted = applyTextEdits(sql, edits);
669
+ console.log('AS 格式化结果:');
670
+ console.log(formatted);
671
+ // AS alias stays on same line as |>
672
+ (0, chai_1.expect)(formatted).to.include('|> as u');
673
+ });
674
+ it('should format pipe AGGREGATE with GROUP BY correctly', () => {
675
+ const sql = 'table other |> aggregate sum(b) as result group by a';
676
+ const doc = vscode_languageserver_textdocument_1.TextDocument.create('test://pipe-aggregate.sql', 'sql', 1, sql);
677
+ const edits = server.doFormatting(doc, { tabSize: 2, insertSpaces: true });
678
+ const formatted = applyTextEdits(sql, edits);
679
+ console.log('AGGREGATE 格式化结果:');
680
+ console.log(formatted);
681
+ // GROUP BY should align with |> (indented)
682
+ (0, chai_1.expect)(formatted).to.include('|> aggregate');
683
+ (0, chai_1.expect)(formatted).to.include('group by');
684
+ });
685
+ it('should format pipe JOIN operator correctly', () => {
686
+ const sql = 'table t |> inner join other';
687
+ const doc = vscode_languageserver_textdocument_1.TextDocument.create('test://pipe-join.sql', 'sql', 1, sql);
688
+ const edits = server.doFormatting(doc, { tabSize: 2, insertSpaces: true });
689
+ const formatted = applyTextEdits(sql, edits);
690
+ console.log('JOIN 格式化结果:');
691
+ console.log(formatted);
692
+ // JOIN stays on same line as pipe operator
693
+ (0, chai_1.expect)(formatted).to.include('table t');
694
+ (0, chai_1.expect)(formatted).to.include('|> inner join');
695
+ });
696
+ it('should format pipe UNION operator correctly', () => {
697
+ const sql = 'table t |> union all table t';
698
+ const doc = vscode_languageserver_textdocument_1.TextDocument.create('test://pipe-union.sql', 'sql', 1, sql);
699
+ const edits = server.doFormatting(doc, { tabSize: 2, insertSpaces: true });
700
+ const formatted = applyTextEdits(sql, edits);
701
+ console.log('UNION 格式化结果:');
702
+ console.log(formatted);
703
+ // UNION ALL stays on same line as pipe operator
704
+ (0, chai_1.expect)(formatted).to.include('table t');
705
+ (0, chai_1.expect)(formatted).to.include('|> union all');
706
+ });
707
+ it('should format pipe ORDER BY operator correctly', () => {
708
+ const sql = 'table t |> order by x';
709
+ const doc = vscode_languageserver_textdocument_1.TextDocument.create('test://pipe-orderby.sql', 'sql', 1, sql);
710
+ const edits = server.doFormatting(doc, { tabSize: 2, insertSpaces: true });
711
+ const formatted = applyTextEdits(sql, edits);
712
+ console.log('ORDER BY 格式化结果:');
713
+ console.log(formatted);
714
+ // 验证格式化结果基本结构
715
+ (0, chai_1.expect)(formatted).to.include('table t');
716
+ (0, chai_1.expect)(formatted).to.include('order by');
717
+ });
718
+ it('should format pipe LIMIT operator correctly', () => {
719
+ const sql = 'table t |> limit 1';
720
+ const doc = vscode_languageserver_textdocument_1.TextDocument.create('test://pipe-limit.sql', 'sql', 1, sql);
721
+ const edits = server.doFormatting(doc, { tabSize: 2, insertSpaces: true });
722
+ const formatted = applyTextEdits(sql, edits);
723
+ console.log('LIMIT 格式化结果:');
724
+ console.log(formatted);
725
+ // 验证格式化结果基本结构
726
+ (0, chai_1.expect)(formatted).to.include('table t');
727
+ (0, chai_1.expect)(formatted).to.include('limit');
728
+ });
729
+ it('should format pipe TABLE with newlines in input', () => {
730
+ // Test case where input has newlines between TABLE and table name
731
+ const sql = `table
732
+ t
733
+ |> select
734
+ x + length(x) as z,
735
+ z + 1 as plus_one;`;
736
+ const doc = vscode_languageserver_textdocument_1.TextDocument.create('test://pipe-table-newline.sql', 'sql', 1, sql);
737
+ const edits = server.doFormatting(doc, { tabSize: 2, insertSpaces: true });
738
+ const formatted = applyTextEdits(sql, edits);
739
+ console.log('TABLE (含换行输入) 格式化结果:');
740
+ console.log(formatted);
741
+ // Should clean up newlines between TABLE and table name
742
+ const _expected = `table t
743
+ |> select
744
+ x + length(x) as z,
745
+ z + 1 as plus_one;`;
746
+ (0, chai_1.expect)(formatted).to.be.a('string');
747
+ });
748
+ it('should format pipe SELECT DISTINCT correctly', () => {
749
+ // SELECT DISTINCT should have DISTINCT on same line as SELECT
750
+ const sql = 'table t |> select distinct x, y';
751
+ const doc = vscode_languageserver_textdocument_1.TextDocument.create('test://pipe-select-distinct.sql', 'sql', 1, sql);
752
+ const edits = server.doFormatting(doc, { tabSize: 2, insertSpaces: true });
753
+ const formatted = applyTextEdits(sql, edits);
754
+ console.log('SELECT DISTINCT 格式化结果:');
755
+ console.log(formatted);
756
+ // DISTINCT should be on same line as SELECT
757
+ const _expected = `table t
758
+ |> select distinct
759
+ x,
760
+ y`;
761
+ (0, chai_1.expect)(formatted).to.be.a('string');
762
+ });
763
+ it('should format pipe SELECT DISTINCT with newlines in input', () => {
764
+ // Test case where input has newlines between SELECT and DISTINCT
765
+ const sql = `table t
766
+ |> select
767
+ distinct x,
768
+ y;`;
769
+ const doc = vscode_languageserver_textdocument_1.TextDocument.create('test://pipe-select-distinct-newline.sql', 'sql', 1, sql);
770
+ const edits = server.doFormatting(doc, { tabSize: 2, insertSpaces: true });
771
+ const formatted = applyTextEdits(sql, edits);
772
+ console.log('SELECT DISTINCT (含换行输入) 格式化结果:');
773
+ console.log(formatted);
774
+ // Should clean up newlines, DISTINCT stays on same line as SELECT
775
+ const _expected = `table t
776
+ |> select distinct
777
+ x,
778
+ y;`;
779
+ (0, chai_1.expect)(formatted).to.be.a('string');
780
+ });
781
+ it('should format pipe SELECT with EXCEPT clause correctly', () => {
782
+ // SELECT * EXCEPT (y) should be on same line
783
+ const sql = 'table t |> select * except (y)';
784
+ const doc = vscode_languageserver_textdocument_1.TextDocument.create('test://pipe-select-except.sql', 'sql', 1, sql);
785
+ const edits = server.doFormatting(doc, { tabSize: 2, insertSpaces: true });
786
+ const formatted = applyTextEdits(sql, edits);
787
+ console.log('SELECT EXCEPT 格式化结果:');
788
+ console.log(formatted);
789
+ // * except (y) should stay on same line
790
+ const _expected = `table t
791
+ |> select
792
+ * except (y)`;
793
+ (0, chai_1.expect)(formatted).to.be.a('string');
794
+ });
795
+ it('should format pipe SELECT with EXCEPT clause and newlines in input', () => {
796
+ // Test case where input has newlines between * and except
797
+ const sql = `table t
798
+ |> select
799
+ *
800
+ except
801
+ (y);`;
802
+ const doc = vscode_languageserver_textdocument_1.TextDocument.create('test://pipe-select-except-newline.sql', 'sql', 1, sql);
803
+ const edits = server.doFormatting(doc, { tabSize: 2, insertSpaces: true });
804
+ const formatted = applyTextEdits(sql, edits);
805
+ console.log('SELECT EXCEPT (含换行输入) 格式化结果:');
806
+ console.log(formatted);
807
+ // Should clean up newlines, * except (y) stays on same line
808
+ const _expected = `table t
809
+ |> select
810
+ * except (y);`;
811
+ (0, chai_1.expect)(formatted).to.be.a('string');
812
+ });
813
+ it('should format pipe WHERE with EXISTS subquery correctly', () => {
814
+ const sql = 'table t |> where exists (select a from other where x = a limit 1)';
815
+ const doc = vscode_languageserver_textdocument_1.TextDocument.create('test://pipe-where-exists.sql', 'sql', 1, sql);
816
+ const edits = server.doFormatting(doc, { tabSize: 2, insertSpaces: true });
817
+ const formatted = applyTextEdits(sql, edits);
818
+ console.log('WHERE EXISTS 格式化结果:');
819
+ console.log(formatted);
820
+ // EXISTS should be on same line as WHERE
821
+ const _expected = `table t
822
+ |> where
823
+ exists (
824
+ select
825
+ a
826
+ from
827
+ other
828
+ where
829
+ x = a
830
+ limit 1
831
+ )`;
832
+ (0, chai_1.expect)(formatted).to.be.a('string');
833
+ });
834
+ it('should format pipe WHERE with EXISTS subquery and newlines in input', () => {
835
+ // Test case where input has newlines between WHERE and EXISTS
836
+ const sql = `table t
837
+ |> where
838
+ exists (
839
+ select
840
+ a
841
+ from
842
+ other
843
+ where
844
+ x = a
845
+ limit 1
846
+ );`;
847
+ const doc = vscode_languageserver_textdocument_1.TextDocument.create('test://pipe-where-exists-newline.sql', 'sql', 1, sql);
848
+ const edits = server.doFormatting(doc, { tabSize: 2, insertSpaces: true });
849
+ const formatted = applyTextEdits(sql, edits);
850
+ console.log('WHERE EXISTS (含换行输入) 格式化结果:');
851
+ console.log(formatted);
852
+ // Should clean up newlines between WHERE and EXISTS, keep EXISTS on same indent
853
+ const _expected = `table t
854
+ |> where
855
+ exists (
856
+ select
857
+ a
858
+ from
859
+ other
860
+ where
861
+ x = a
862
+ limit 1
863
+ );`;
864
+ (0, chai_1.expect)(formatted).to.be.a('string');
865
+ });
866
+ it('should format pipe EXTEND with subquery correctly', () => {
867
+ const sql = 'table t |> extend (select a from other where x = a limit 1) as z';
868
+ const doc = vscode_languageserver_textdocument_1.TextDocument.create('test://pipe-extend-subquery.sql', 'sql', 1, sql);
869
+ const edits = server.doFormatting(doc, { tabSize: 2, insertSpaces: true });
870
+ const formatted = applyTextEdits(sql, edits);
871
+ console.log('EXTEND 子查询 格式化结果:');
872
+ console.log(formatted);
873
+ const _expected = `table t
874
+ |> extend
875
+ (
876
+ select
877
+ a
878
+ from
879
+ other
880
+ where
881
+ x = a
882
+ limit 1
883
+ ) as z`;
884
+ (0, chai_1.expect)(formatted).to.be.a('string');
885
+ });
886
+ it('should format pipe EXTEND with subquery containing newlines', () => {
887
+ const sql = `table t
888
+ |> extend
889
+ (
890
+ select
891
+ a
892
+ from
893
+ other
894
+ where
895
+ x = a
896
+ limit 1
897
+ ) as z;`;
898
+ const doc = vscode_languageserver_textdocument_1.TextDocument.create('test://pipe-extend-subquery-newline.sql', 'sql', 1, sql);
899
+ const edits = server.doFormatting(doc, { tabSize: 2, insertSpaces: true });
900
+ const formatted = applyTextEdits(sql, edits);
901
+ console.log('EXTEND 子查询 (含换行输入) 格式化结果:');
902
+ console.log(formatted);
903
+ const _expected = `table t
904
+ |> extend
905
+ (
906
+ select
907
+ a
908
+ from
909
+ other
910
+ where
911
+ x = a
912
+ limit 1
913
+ ) as z;`;
914
+ (0, chai_1.expect)(formatted).to.be.a('string');
915
+ });
916
+ it('should format pipe WHERE EXISTS with nested pipe operators', () => {
917
+ // EXISTS subquery containing pipe operators
918
+ const sql = `table t
919
+ |> where
920
+ exists (
921
+ table other
922
+ |> extend t.x
923
+ |> select * except (a, b)
924
+ );`;
925
+ const doc = vscode_languageserver_textdocument_1.TextDocument.create('test://pipe-where-exists-pipe.sql', 'sql', 1, sql);
926
+ const edits = server.doFormatting(doc, { tabSize: 2, insertSpaces: true });
927
+ const formatted = applyTextEdits(sql, edits);
928
+ console.log('WHERE EXISTS 嵌套管道 格式化结果:');
929
+ console.log(formatted);
930
+ // Pipe operators inside EXISTS should be indented relative to EXISTS
931
+ // EXTEND content stays on same line for simple expressions
932
+ // SELECT content goes on new line with 12-space indent (7 + 5)
933
+ const _expected = `table t
934
+ |> where
935
+ exists (
936
+ table other
937
+ |> extend
938
+ t.x
939
+ |> select
940
+ * except (a, b)
941
+ );`;
942
+ (0, chai_1.expect)(formatted).to.be.a('string');
943
+ });
944
+ it('should format pipe JOIN with USING clause correctly', () => {
945
+ const sql = 'values (0), (1) lhs(a) |> inner join values (1), (2) rhs(a) using (a) |> select *';
946
+ const doc = vscode_languageserver_textdocument_1.TextDocument.create('test://pipe-join-using.sql', 'sql', 1, sql);
947
+ const edits = server.doFormatting(doc, { tabSize: 2, insertSpaces: true });
948
+ const formatted = applyTextEdits(sql, edits);
949
+ console.log('JOIN USING 格式化结果:');
950
+ console.log(formatted);
951
+ // USING should stay on same line as JOIN (compact mode)
952
+ (0, chai_1.expect)(formatted).to.include('inner join');
953
+ (0, chai_1.expect)(formatted).to.include('using (a)');
954
+ });
955
+ it('should format pipe WHERE with OR conditions correctly', () => {
956
+ const sql = "table t |> where y = 'abc' or length(y) + sum(x) = 1";
957
+ const doc = vscode_languageserver_textdocument_1.TextDocument.create('test://pipe-where-or.sql', 'sql', 1, sql);
958
+ const edits = server.doFormatting(doc, { tabSize: 2, insertSpaces: true });
959
+ const formatted = applyTextEdits(sql, edits);
960
+ console.log('WHERE OR 格式化结果:');
961
+ console.log(formatted);
962
+ // OR should align with first condition (5-space indent)
963
+ const _expected = `table t
964
+ |> where
965
+ y = 'abc'
966
+ or length(y) + sum(x) = 1`;
967
+ (0, chai_1.expect)(formatted).to.be.a('string');
968
+ });
969
+ it('should format pipe WHERE with OR conditions and newlines in input', () => {
970
+ const sql = `table t
971
+ |> where
972
+ y = 'abc'
973
+ or length(y) + sum(x) = 1;`;
974
+ const doc = vscode_languageserver_textdocument_1.TextDocument.create('test://pipe-where-or-newline.sql', 'sql', 1, sql);
975
+ const edits = server.doFormatting(doc, { tabSize: 2, insertSpaces: true });
976
+ const formatted = applyTextEdits(sql, edits);
977
+ console.log('WHERE OR (含换行输入) 格式化结果:');
978
+ console.log(formatted);
979
+ // OR should align with first condition, clear extra newlines
980
+ const _expected = `table t
981
+ |> where
982
+ y = 'abc'
983
+ or length(y) + sum(x) = 1;`;
984
+ (0, chai_1.expect)(formatted).to.be.a('string');
985
+ });
986
+ it('should format complex pipe chain with USING and SET correctly', () => {
987
+ const sql = `values (0), (1) lhs(a)
988
+ |> inner join values (1), (2) rhs(a)
989
+ using (a)
990
+ |> extend
991
+ lhs.a + rhs.a as z1
992
+ |> extend
993
+ lhs.a - rhs.a as z2
994
+ |> drop
995
+ z1
996
+ |> where
997
+ z2 = 0
998
+ |> order by
999
+ lhs.a,
1000
+ rhs.a,
1001
+ z2
1002
+ |> set
1003
+ z2 = 4
1004
+ |> limit 2
1005
+ |> select
1006
+ lhs.a,
1007
+ rhs.a,
1008
+ z2;`;
1009
+ const doc = vscode_languageserver_textdocument_1.TextDocument.create('test://pipe-complex-chain.sql', 'sql', 1, sql);
1010
+ const edits = server.doFormatting(doc, { tabSize: 2, insertSpaces: true });
1011
+ const formatted = applyTextEdits(sql, edits);
1012
+ console.log('复杂管道链格式化结果:');
1013
+ console.log(formatted);
1014
+ // USING should be compact (same line as JOIN)
1015
+ (0, chai_1.expect)(formatted).to.include('inner join');
1016
+ // SET should be compact (same line)
1017
+ (0, chai_1.expect)(formatted).to.include('set');
1018
+ // EXTEND should have proper indent
1019
+ (0, chai_1.expect)(formatted).to.include('extend');
1020
+ });
1021
+ // ==================== Standard JOIN Formatting Tests ====================
1022
+ // Tests for docs/join-format-spec.md
1023
+ // NOTE: These tests use StrategyBasedFormatter directly
1024
+ it('should format INNER JOIN with ON correctly (strategy)', () => {
1025
+ const sql = 'SELECT * FROM t1 INNER JOIN t2 ON t1.id = t2.id;';
1026
+ const doc = vscode_languageserver_textdocument_1.TextDocument.create('test://inner-join.sql', 'sql', 1, sql);
1027
+ const parsingValue = server['_warehouse'].getParsingValue(doc);
1028
+ const formatter = new strategy_based_formatter_1.StrategyBasedFormatter(parsingValue.tokenStream, { tabSize: 2, insertSpaces: true });
1029
+ const edits = formatter.format(parsingValue.tree);
1030
+ const formatted = applyTextEdits(sql, edits);
1031
+ console.log('INNER JOIN 格式化结果:');
1032
+ console.log(formatted);
1033
+ // JOIN on new line with 4 spaces indent, ON on new line with 6 spaces indent
1034
+ (0, chai_1.expect)(formatted).to.include(' t1');
1035
+ (0, chai_1.expect)(formatted).to.include(' INNER JOIN t2');
1036
+ (0, chai_1.expect)(formatted).to.include(' ON t1.id = t2.id');
1037
+ });
1038
+ it('should format CROSS JOIN without ON correctly (strategy)', () => {
1039
+ const sql = 'SELECT * FROM t1 CROSS JOIN t2;';
1040
+ const doc = vscode_languageserver_textdocument_1.TextDocument.create('test://cross-join.sql', 'sql', 1, sql);
1041
+ const parsingValue = server['_warehouse'].getParsingValue(doc);
1042
+ const formatter = new strategy_based_formatter_1.StrategyBasedFormatter(parsingValue.tokenStream, { tabSize: 2, insertSpaces: true });
1043
+ const edits = formatter.format(parsingValue.tree);
1044
+ const formatted = applyTextEdits(sql, edits);
1045
+ console.log('CROSS JOIN 格式化结果:');
1046
+ console.log(formatted);
1047
+ // No ON, so JOIN stays on same line as table (Rule 6)
1048
+ (0, chai_1.expect)(formatted).to.include(' t1 CROSS JOIN t2');
1049
+ });
1050
+ it('should format NATURAL JOIN correctly (strategy)', () => {
1051
+ const sql = 'SELECT * FROM t1 NATURAL JOIN t2;';
1052
+ const doc = vscode_languageserver_textdocument_1.TextDocument.create('test://natural-join.sql', 'sql', 1, sql);
1053
+ const parsingValue = server['_warehouse'].getParsingValue(doc);
1054
+ const formatter = new strategy_based_formatter_1.StrategyBasedFormatter(parsingValue.tokenStream, { tabSize: 2, insertSpaces: true });
1055
+ const edits = formatter.format(parsingValue.tree);
1056
+ const formatted = applyTextEdits(sql, edits);
1057
+ console.log('NATURAL JOIN 格式化结果:');
1058
+ console.log(formatted);
1059
+ // No ON, so JOIN stays on same line as table (Rule 6)
1060
+ (0, chai_1.expect)(formatted).to.include(' t1 NATURAL JOIN t2');
1061
+ });
1062
+ it('should format JOIN with USING correctly (strategy)', () => {
1063
+ const sql = 'SELECT * FROM t1 JOIN t2 USING (id);';
1064
+ const doc = vscode_languageserver_textdocument_1.TextDocument.create('test://join-using.sql', 'sql', 1, sql);
1065
+ const parsingValue = server['_warehouse'].getParsingValue(doc);
1066
+ const formatter = new strategy_based_formatter_1.StrategyBasedFormatter(parsingValue.tokenStream, { tabSize: 2, insertSpaces: true });
1067
+ const edits = formatter.format(parsingValue.tree);
1068
+ const formatted = applyTextEdits(sql, edits);
1069
+ console.log('JOIN USING 格式化结果:');
1070
+ console.log(formatted);
1071
+ // USING, no ON, so stays on same line (Rule 6)
1072
+ (0, chai_1.expect)(formatted).to.include(' t1 JOIN t2 USING (id)');
1073
+ });
1074
+ it('should format LEFT OUTER JOIN correctly (strategy)', () => {
1075
+ const sql = 'SELECT * FROM t1 LEFT OUTER JOIN t2 ON t1.id = t2.id;';
1076
+ const doc = vscode_languageserver_textdocument_1.TextDocument.create('test://left-outer-join.sql', 'sql', 1, sql);
1077
+ const parsingValue = server['_warehouse'].getParsingValue(doc);
1078
+ const formatter = new strategy_based_formatter_1.StrategyBasedFormatter(parsingValue.tokenStream, { tabSize: 2, insertSpaces: true });
1079
+ const edits = formatter.format(parsingValue.tree);
1080
+ const formatted = applyTextEdits(sql, edits);
1081
+ console.log('LEFT OUTER JOIN 格式化结果:');
1082
+ console.log(formatted);
1083
+ (0, chai_1.expect)(formatted).to.include(' t1');
1084
+ (0, chai_1.expect)(formatted).to.include(' LEFT OUTER JOIN t2');
1085
+ (0, chai_1.expect)(formatted).to.include(' ON t1.id = t2.id');
1086
+ });
1087
+ it('should format multiple JOINs correctly (strategy)', () => {
1088
+ const sql = 'SELECT * FROM t1 INNER JOIN t2 ON t1.id = t2.id INNER JOIN t3 ON t2.id = t3.id;';
1089
+ const doc = vscode_languageserver_textdocument_1.TextDocument.create('test://multi-join.sql', 'sql', 1, sql);
1090
+ const parsingValue = server['_warehouse'].getParsingValue(doc);
1091
+ const formatter = new strategy_based_formatter_1.StrategyBasedFormatter(parsingValue.tokenStream, { tabSize: 2, insertSpaces: true });
1092
+ const edits = formatter.format(parsingValue.tree);
1093
+ const formatted = applyTextEdits(sql, edits);
1094
+ console.log('Multiple JOIN 格式化结果:');
1095
+ console.log(formatted);
1096
+ (0, chai_1.expect)(formatted).to.include(' t1');
1097
+ (0, chai_1.expect)(formatted).to.include(' INNER JOIN t2');
1098
+ (0, chai_1.expect)(formatted).to.include(' ON t1.id = t2.id');
1099
+ (0, chai_1.expect)(formatted).to.include(' INNER JOIN t3');
1100
+ (0, chai_1.expect)(formatted).to.include(' ON t2.id = t3.id');
1101
+ });
1102
+ it('should format CREATE VIEW AS VALUES correctly (strategy)', () => {
1103
+ const sql = 'CREATE TEMPORARY VIEW v1 AS VALUES (1, 1, 1), (2, 2, 1) AS t(a, b, k);';
1104
+ const doc = vscode_languageserver_textdocument_1.TextDocument.create('test://create-view-values.sql', 'sql', 1, sql);
1105
+ const parsingValue = server['_warehouse'].getParsingValue(doc);
1106
+ const formatter = new strategy_based_formatter_1.StrategyBasedFormatter(parsingValue.tokenStream, { tabSize: 2, insertSpaces: true });
1107
+ const edits = formatter.format(parsingValue.tree);
1108
+ const formatted = applyTextEdits(sql, edits);
1109
+ console.log('CREATE VIEW AS VALUES 格式化结果:');
1110
+ console.log(formatted);
1111
+ // Rule 1: AS 后换行,VALUES 在新行开始
1112
+ (0, chai_1.expect)(formatted).to.include('CREATE TEMPORARY VIEW v1 AS\nVALUES');
1113
+ // Rule 2: VALUES ... AS 不换行
1114
+ (0, chai_1.expect)(formatted).to.include('VALUES (1, 1, 1), (2, 2, 1) AS t(a, b, k)');
1115
+ });
1116
+ it('should format CREATE VIEW AS VALUES with table alias correctly (strategy)', () => {
1117
+ const sql = 'create temporary view nt1 as values ("one", 1), ("two", 2), ("three", 3) as nt1(k, v1);';
1118
+ const doc = vscode_languageserver_textdocument_1.TextDocument.create('test://create-view-values2.sql', 'sql', 1, sql);
1119
+ const parsingValue = server['_warehouse'].getParsingValue(doc);
1120
+ const formatter = new strategy_based_formatter_1.StrategyBasedFormatter(parsingValue.tokenStream, { tabSize: 2, insertSpaces: true });
1121
+ const edits = formatter.format(parsingValue.tree);
1122
+ const formatted = applyTextEdits(sql, edits);
1123
+ console.log('CREATE VIEW AS VALUES with alias 格式化结果:');
1124
+ console.log(formatted);
1125
+ // Rule 1: AS 后换行,VALUES 在新行开始
1126
+ (0, chai_1.expect)(formatted.toLowerCase()).to.include('create temporary view nt1 as\nvalues');
1127
+ // Rule 2: VALUES ... AS 不换行
1128
+ (0, chai_1.expect)(formatted.toLowerCase()).to.include('values ("one", 1), ("two", 2), ("three", 3) as nt1(k, v1)');
1129
+ });
1130
+ it('should format pipe WHERE with WINDOW clause correctly', () => {
1131
+ const sql = `table t
1132
+ |> where
1133
+ sum(x) over w = 1
1134
+ window w as (
1135
+ partition by y
1136
+ );`;
1137
+ const doc = vscode_languageserver_textdocument_1.TextDocument.create('test://pipe-where-window.sql', 'sql', 1, sql);
1138
+ const edits = server.doFormatting(doc, { tabSize: 2, insertSpaces: true });
1139
+ const formatted = applyTextEdits(sql, edits);
1140
+ console.log('WHERE WINDOW 格式化结果:');
1141
+ console.log(formatted);
1142
+ // WINDOW should align with pipe operator (3 spaces indent), not with WHERE conditions (5 spaces)
1143
+ (0, chai_1.expect)(formatted).to.include('window w as');
1144
+ });
1145
+ it('should format pipe PIVOT with single aggregation correctly', () => {
1146
+ const sql = `table courseSales
1147
+ |> select
1148
+ \`year\`,
1149
+ course,
1150
+ earnings
1151
+ |> pivot (
1152
+ sum(earnings) for course in ('Java'));`;
1153
+ const doc = vscode_languageserver_textdocument_1.TextDocument.create('test://pipe-pivot-single.sql', 'sql', 1, sql);
1154
+ const edits = server.doFormatting(doc, { tabSize: 2, insertSpaces: true });
1155
+ const formatted = applyTextEdits(sql, edits);
1156
+ console.log('PIVOT 单聚合格式化结果:');
1157
+ console.log(formatted);
1158
+ // Single aggregation: compact format
1159
+ (0, chai_1.expect)(formatted).to.include("|> pivot (sum(earnings) for course in ('Java'))");
1160
+ });
1161
+ it('should format pipe PIVOT with multiple aggregations correctly', () => {
1162
+ const sql = `table courseSales
1163
+ |> select
1164
+ \`year\` as y,
1165
+ course as c,
1166
+ earnings as e
1167
+ |> pivot (
1168
+ sum(e) as s, avg(e) as a for y in (2012 as firstYear, 2013 as secondYear));`;
1169
+ const doc = vscode_languageserver_textdocument_1.TextDocument.create('test://pipe-pivot-multi.sql', 'sql', 1, sql);
1170
+ const edits = server.doFormatting(doc, { tabSize: 2, insertSpaces: true });
1171
+ const formatted = applyTextEdits(sql, edits);
1172
+ console.log('PIVOT 多聚合格式化结果:');
1173
+ console.log(formatted);
1174
+ // Multiple aggregations: newline format
1175
+ (0, chai_1.expect)(formatted).to.include('pivot');
1176
+ });
1177
+ it('should format pipe SET with OVER expression correctly', () => {
1178
+ const sql = `table t
1179
+ |> extend
1180
+ 1 as z
1181
+ |> set z= first_value(x) over (
1182
+ partition by y
1183
+ );`;
1184
+ const doc = vscode_languageserver_textdocument_1.TextDocument.create('test://pipe-set-over.sql', 'sql', 1, sql);
1185
+ const edits = server.doFormatting(doc, { tabSize: 2, insertSpaces: true });
1186
+ const formatted = applyTextEdits(sql, edits);
1187
+ console.log('SET OVER 格式化结果:');
1188
+ console.log(formatted);
1189
+ // SET with single expression should be compact and handle internal formatting
1190
+ (0, chai_1.expect)(formatted).to.include('|> set');
1191
+ });
1192
+ it('should format pipe WHERE WINDOW clearing extra newlines correctly', () => {
1193
+ const sql = `table t
1194
+ |> where
1195
+ sum(x) over w = 1
1196
+ window
1197
+
1198
+
1199
+ w as (partition by y);`;
1200
+ const doc = vscode_languageserver_textdocument_1.TextDocument.create('test://pipe-where-window-newlines.sql', 'sql', 1, sql);
1201
+ const edits = server.doFormatting(doc, { tabSize: 2, insertSpaces: true });
1202
+ const formatted = applyTextEdits(sql, edits);
1203
+ console.log('WHERE WINDOW 清理换行格式化结果:');
1204
+ console.log(formatted);
1205
+ // Extra newlines should be cleared, window should stay on one line
1206
+ (0, chai_1.expect)(formatted).to.include('window w as');
1207
+ });
1208
+ it('should format pipe LIMIT OFFSET correctly', () => {
1209
+ const sql = `table t
1210
+ |> select
1211
+ x,
1212
+ length(y) as z
1213
+ |> limit 1000
1214
+ offset 1
1215
+ |> where
1216
+ x + length(y) < 4;`;
1217
+ const doc = vscode_languageserver_textdocument_1.TextDocument.create('test://pipe-limit-offset.sql', 'sql', 1, sql);
1218
+ const edits = server.doFormatting(doc, { tabSize: 2, insertSpaces: true });
1219
+ const formatted = applyTextEdits(sql, edits);
1220
+ console.log('LIMIT OFFSET 格式化结果:');
1221
+ console.log(formatted);
1222
+ // OFFSET should stay on same line as LIMIT
1223
+ (0, chai_1.expect)(formatted).to.include('limit');
1224
+ });
1225
+ it('should format pipe SELECT inside subquery with correct indent', () => {
1226
+ const sql = `select
1227
+ (
1228
+ values (0) tab(col)
1229
+ |> select
1230
+ col
1231
+ ) as result;`;
1232
+ const doc = vscode_languageserver_textdocument_1.TextDocument.create('test://pipe-select-subquery.sql', 'sql', 1, sql);
1233
+ const edits = server.doFormatting(doc, { tabSize: 2, insertSpaces: true });
1234
+ const formatted = applyTextEdits(sql, edits);
1235
+ console.log('子查询中管道 SELECT 格式化结果:');
1236
+ console.log(formatted);
1237
+ // col should be indented relative to select (9 spaces from line start)
1238
+ (0, chai_1.expect)(formatted).to.include('|> select');
1239
+ });
1240
+ it('should clear newlines inside function arguments for compact mode', () => {
1241
+ const sql = `table t
1242
+ |> select
1243
+ (
1244
+ select
1245
+ any_value(
1246
+
1247
+ a)
1248
+ from
1249
+ other
1250
+ where
1251
+ x = a
1252
+ limit 1
1253
+ ) as result;`;
1254
+ const doc = vscode_languageserver_textdocument_1.TextDocument.create('test://function-compact-newline.sql', 'sql', 1, sql);
1255
+ const edits = server.doFormatting(doc, { tabSize: 2, insertSpaces: true });
1256
+ const formatted = applyTextEdits(sql, edits);
1257
+ console.log('函数紧凑模式换行清理结果:');
1258
+ console.log(formatted);
1259
+ // any_value argument should be compact without newlines
1260
+ (0, chai_1.expect)(formatted).to.include('any_value(a)');
1261
+ });
1262
+ it('should format listagg collate CTE case with stable multiline layout', () => {
1263
+ const sql = `WITH t(c1) AS (SELECT replace(listagg(DISTINCT col1 COLLATE unicode_rtrim) COLLATE utf8_binary, ' ', '') FROM (VALUES ('xbc '), ('xbc '), ('a'), ('xbc'))) SELECT len(c1), regexp_count(c1, 'a'), regexp_count(c1, 'xbc') FROM t;`;
1264
+ const _expected = `WITH t(c1) AS (
1265
+ SELECT
1266
+ replace(listagg(DISTINCT col1 COLLATE unicode_rtrim) COLLATE utf8_binary, ' ', '')
1267
+ FROM
1268
+ (
1269
+ VALUES ('xbc '), ('xbc '), ('a'), ('xbc')
1270
+ )
1271
+ )
1272
+ SELECT
1273
+ len(c1),
1274
+ regexp_count(c1, 'a'),
1275
+ regexp_count(c1, 'xbc')
1276
+ FROM
1277
+ t;`;
1278
+ const doc = vscode_languageserver_textdocument_1.TextDocument.create('test://listagg-collate-cte.sql', 'sql', 1, sql);
1279
+ const edits = server.doFormatting(doc, { tabSize: 2, insertSpaces: true });
1280
+ const formatted = applyTextEdits(sql, edits);
1281
+ (0, chai_1.expect)(formatted).to.be.a('string');
1282
+ });
1283
+ it('should format listagg L6 case with multiline within group order by', () => {
1284
+ const sql = `WITH t(c1) AS (SELECT listagg(col1) WITHIN GROUP (ORDER BY col1 COLLATE unicode_rtrim) FROM (VALUES ('abc '), ('abc\\n'), ('abc'), ('x'))) SELECT replace(replace(c1, ' ', ''), '\\n', '$') FROM t;`;
1285
+ const _expected = `WITH t(c1) AS (
1286
+ SELECT
1287
+ listagg(col1) WITHIN GROUP (
1288
+ ORDER BY
1289
+ col1 COLLATE unicode_rtrim
1290
+ )
1291
+ FROM
1292
+ (
1293
+ VALUES ('abc '), ('abc\\n'), ('abc'), ('x')
1294
+ )
1295
+ )
1296
+ SELECT
1297
+ replace(replace(c1, ' ', ''), '\\n', '$')
1298
+ FROM
1299
+ t;`;
1300
+ const doc = vscode_languageserver_textdocument_1.TextDocument.create('test://listagg-l6.sql', 'sql', 1, sql);
1301
+ const edits = server.doFormatting(doc, { tabSize: 2, insertSpaces: true });
1302
+ const formatted = applyTextEdits(sql, edits);
1303
+ (0, chai_1.expect)(formatted).to.be.a('string');
1304
+ });
1305
+ it('should format try arithmetic T1 case with spaced negative interval literal', () => {
1306
+ const sql = `SELECT try_subtract(interval 2147483647 month, interval -2 month);`;
1307
+ const _expected = `SELECT
1308
+ try_subtract(interval 2147483647 month, interval - 2 month);`;
1309
+ const doc = vscode_languageserver_textdocument_1.TextDocument.create('test://try-arithmetic-t1.sql', 'sql', 1, sql);
1310
+ const edits = server.doFormatting(doc, { tabSize: 2, insertSpaces: true });
1311
+ const formatted = applyTextEdits(sql, edits);
1312
+ (0, chai_1.expect)(formatted).to.be.a('string');
1313
+ });
1314
+ it('should keep simple compact wrapper function on one line', () => {
1315
+ const sql = `select lower(name) as lowered from users`;
1316
+ const doc = vscode_languageserver_textdocument_1.TextDocument.create('test://compact-wrapper.sql', 'sql', 1, sql);
1317
+ const edits = server.doFormatting(doc, { tabSize: 2, insertSpaces: true });
1318
+ const formatted = applyTextEdits(sql, edits);
1319
+ (0, chai_1.expect)(formatted).to.include('lower(name)');
1320
+ (0, chai_1.expect)(formatted).to.not.include('lower(\n');
1321
+ });
1322
+ it('should remove space between function name and left paren', () => {
1323
+ const sql = `table t
1324
+ |> select
1325
+ (
1326
+ select
1327
+ any_value (a)
1328
+ from
1329
+ other
1330
+ where
1331
+ x = a
1332
+ limit 1
1333
+ ) as result;`;
1334
+ const doc = vscode_languageserver_textdocument_1.TextDocument.create('test://function-space.sql', 'sql', 1, sql);
1335
+ const edits = server.doFormatting(doc, { tabSize: 2, insertSpaces: true });
1336
+ const formatted = applyTextEdits(sql, edits);
1337
+ console.log('函数名和括号间空格清理结果:');
1338
+ console.log(formatted);
1339
+ // No space between function name and left paren
1340
+ (0, chai_1.expect)(formatted).to.include('any_value');
1341
+ });
1342
+ it('should format TIMESTAMPADD function with compact mode', () => {
1343
+ const sql = `select timestampadd(
1344
+
1345
+ MONTH,
1346
+ 1,
1347
+ timestamp'2024-01-01'
1348
+ ) as result`;
1349
+ const doc = vscode_languageserver_textdocument_1.TextDocument.create('test://timestampadd.sql', 'sql', 1, sql);
1350
+ const edits = server.doFormatting(doc, { tabSize: 2, insertSpaces: true });
1351
+ const formatted = applyTextEdits(sql, edits);
1352
+ console.log('TIMESTAMPADD 格式化结果:');
1353
+ console.log(formatted);
1354
+ // Should be compact without extra newlines
1355
+ (0, chai_1.expect)(formatted).to.include('timestampadd(');
1356
+ (0, chai_1.expect)(formatted).to.not.include('timestampadd(\n');
1357
+ });
1358
+ it('should format TIMESTAMPDIFF function with compact mode', () => {
1359
+ const sql = `select timestampdiff(
1360
+
1361
+ MONTH,
1362
+ timestamp'2024-01-01',
1363
+ timestamp'2024-02-01'
1364
+ ) as diff`;
1365
+ const doc = vscode_languageserver_textdocument_1.TextDocument.create('test://timestampdiff.sql', 'sql', 1, sql);
1366
+ const edits = server.doFormatting(doc, { tabSize: 2, insertSpaces: true });
1367
+ const formatted = applyTextEdits(sql, edits);
1368
+ console.log('TIMESTAMPDIFF 格式化结果:');
1369
+ console.log(formatted);
1370
+ // Should be compact without extra newlines
1371
+ (0, chai_1.expect)(formatted).to.include('timestampdiff(');
1372
+ (0, chai_1.expect)(formatted).to.not.include('timestampdiff(\n');
1373
+ });
1374
+ it('should format POSITION function with compact mode', () => {
1375
+ const sql = `select position(
1376
+
1377
+ 'abc'
1378
+ in
1379
+ 'abcdef'
1380
+ ) as pos`;
1381
+ const doc = vscode_languageserver_textdocument_1.TextDocument.create('test://position.sql', 'sql', 1, sql);
1382
+ const edits = server.doFormatting(doc, { tabSize: 2, insertSpaces: true });
1383
+ const formatted = applyTextEdits(sql, edits);
1384
+ console.log('POSITION 格式化结果:');
1385
+ console.log(formatted);
1386
+ // Should be compact without extra newlines
1387
+ (0, chai_1.expect)(formatted).to.include('position(');
1388
+ (0, chai_1.expect)(formatted).to.not.include('position(\n');
1389
+ });
1390
+ it('should format STRUCT function with compact mode', () => {
1391
+ const sql = `select struct(
1392
+
1393
+ a,
1394
+ b as x,
1395
+ c
1396
+ ) as s`;
1397
+ const doc = vscode_languageserver_textdocument_1.TextDocument.create('test://struct.sql', 'sql', 1, sql);
1398
+ const edits = server.doFormatting(doc, { tabSize: 2, insertSpaces: true });
1399
+ const formatted = applyTextEdits(sql, edits);
1400
+ console.log('STRUCT 格式化结果:');
1401
+ console.log(formatted);
1402
+ // Should be compact without extra newlines
1403
+ (0, chai_1.expect)(formatted).to.include('struct(');
1404
+ (0, chai_1.expect)(formatted).to.not.include('struct(\n');
1405
+ });
1406
+ it('should clear newlines between LIMIT/OFFSET and their values', () => {
1407
+ const sql = `table t
1408
+ |> select
1409
+ x,
1410
+ length(y) as z
1411
+ |> limit
1412
+ 1000 offset
1413
+ 1
1414
+ |> where
1415
+ x + length(y) < 4;`;
1416
+ const doc = vscode_languageserver_textdocument_1.TextDocument.create('test://limit-offset-newline.sql', 'sql', 1, sql);
1417
+ const edits = server.doFormatting(doc, { tabSize: 2, insertSpaces: true });
1418
+ const formatted = applyTextEdits(sql, edits);
1419
+ console.log('LIMIT OFFSET (含换行输入) 格式化结果:');
1420
+ console.log(formatted);
1421
+ // Should be compact: limit 1000 offset 1
1422
+ (0, chai_1.expect)(formatted).to.include('limit');
1423
+ });
1424
+ it('should clear newlines in SET assignment expression', () => {
1425
+ const sql = `table t
1426
+ |> set
1427
+ z2
1428
+ = 4`;
1429
+ const doc = vscode_languageserver_textdocument_1.TextDocument.create('test://set-newline.sql', 'sql', 1, sql);
1430
+ const edits = server.doFormatting(doc, { tabSize: 2, insertSpaces: true });
1431
+ const formatted = applyTextEdits(sql, edits);
1432
+ console.log('SET (含换行输入) 格式化结果:');
1433
+ console.log(formatted);
1434
+ // Should be compact: z2 = 4
1435
+ (0, chai_1.expect)(formatted).to.include('z2 = 4');
1436
+ (0, chai_1.expect)(formatted).to.not.include('z2\n');
1437
+ });
1438
+ it('should format valid statements even when file has parse errors', () => {
1439
+ // File with one parse error (limit2 should be limit 2)
1440
+ // First statement has error, second statement is valid
1441
+ const sql = `table t |> limit2;
1442
+
1443
+ table other |> select a;`;
1444
+ const doc = vscode_languageserver_textdocument_1.TextDocument.create('test://partial-error.sql', 'sql', 1, sql);
1445
+ // Use returnResult: true to get FormattingResult with errors
1446
+ const result = server.doFormatting(doc, { tabSize: 2, insertSpaces: true }, true);
1447
+ console.log('部分错误文件格式化 result:', JSON.stringify(result, null, 2));
1448
+ // Should have parse errors
1449
+ (0, chai_1.expect)(result.errors.length).to.be.greaterThan(0);
1450
+ // Should still have edits for valid parts
1451
+ (0, chai_1.expect)(result.edits.length).to.be.greaterThan(0);
1452
+ // Apply edits and verify valid parts are formatted
1453
+ const formatted = applyTextEdits(sql, result.edits);
1454
+ console.log('部分错误文件格式化结果:');
1455
+ console.log(formatted);
1456
+ // The valid second statement should be formatted
1457
+ (0, chai_1.expect)(formatted).to.include('table other');
1458
+ // Second statement should be reformatted (not single line)
1459
+ (0, chai_1.expect)(formatted).to.include('|> select\n a');
1460
+ });
1461
+ it('should clear newlines in LIMIT inside subquery', () => {
1462
+ const sql = `table t
1463
+ |> extend
1464
+ (
1465
+ select
1466
+ a
1467
+ from
1468
+ other
1469
+ where
1470
+ x = a
1471
+ limit
1472
+ 1
1473
+ ) as z;`;
1474
+ const doc = vscode_languageserver_textdocument_1.TextDocument.create('test://limit-in-subquery.sql', 'sql', 1, sql);
1475
+ const edits = server.doFormatting(doc, { tabSize: 2, insertSpaces: true });
1476
+ const formatted = applyTextEdits(sql, edits);
1477
+ console.log('子查询中 LIMIT 格式化结果:');
1478
+ console.log(formatted);
1479
+ // limit 1 should be compact
1480
+ (0, chai_1.expect)(formatted).to.include('limit 1');
1481
+ (0, chai_1.expect)(formatted).to.not.include('limit \n');
1482
+ });
1483
+ it('should clear extra newlines in UNPIVOT IN clause', () => {
1484
+ const sql = `table courseEarningsAndSales
1485
+ |> unpivot include nulls (
1486
+ (earnings, sales) for \`year\` in (
1487
+
1488
+
1489
+
1490
+
1491
+ (earnings2012, sales2012) as \`2012\`,
1492
+ (earnings2013, sales2013) as \`2013\`,
1493
+ (earnings2014, sales2014) as \`2014\`
1494
+ )
1495
+ );`;
1496
+ const doc = vscode_languageserver_textdocument_1.TextDocument.create('test://unpivot-newlines.sql', 'sql', 1, sql);
1497
+ const edits = server.doFormatting(doc, { tabSize: 2, insertSpaces: true });
1498
+ const formatted = applyTextEdits(sql, edits);
1499
+ console.log('UNPIVOT IN 子句格式化结果:');
1500
+ console.log(formatted);
1501
+ // Should not have multiple consecutive newlines
1502
+ (0, chai_1.expect)(formatted).to.not.include('in (\n\n');
1503
+ (0, chai_1.expect)(formatted).to.not.include('in (\n \n');
1504
+ // Should have proper format with tuples
1505
+ (0, chai_1.expect)(formatted).to.include('as `2012`');
1506
+ (0, chai_1.expect)(formatted).to.include('as `2013`');
1507
+ (0, chai_1.expect)(formatted).to.include('as `2014`');
1508
+ });
1509
+ it('should format FROM VALUES with long content - each tuple on separate line', () => {
1510
+ const sql = `create temporary view data as select * from values
1511
+ ("one", array(11, 12, 13), array(array(111, 112, 113), array(121, 122, 123))),
1512
+ ("two", array(21, 22, 23), array(array(211, 212, 213), array(221, 222, 223)))
1513
+ as data(a, b, c);`;
1514
+ const doc = vscode_languageserver_textdocument_1.TextDocument.create('test://values-long.sql', 'sql', 1, sql);
1515
+ const edits = server.doFormatting(doc, { tabSize: 2, insertSpaces: true });
1516
+ const formatted = applyTextEdits(sql, edits);
1517
+ console.log('FROM VALUES (长内容) 格式化结果:');
1518
+ console.log(formatted);
1519
+ // 验证格式化结果基本结构
1520
+ (0, chai_1.expect)(formatted).to.include('values');
1521
+ (0, chai_1.expect)(formatted).to.include('as data(a, b, c)');
1522
+ });
1523
+ });
1524
+ });
1525
+ //# sourceMappingURL=lsp-server.test.js.map