@quereus/quereus 0.1.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 (1198) hide show
  1. package/README.md +228 -0
  2. package/dist/src/common/constants.d.ts +49 -0
  3. package/dist/src/common/constants.d.ts.map +1 -0
  4. package/dist/src/common/constants.js +62 -0
  5. package/dist/src/common/constants.js.map +1 -0
  6. package/dist/src/common/datatype.d.ts +72 -0
  7. package/dist/src/common/datatype.d.ts.map +1 -0
  8. package/dist/src/common/datatype.js +10 -0
  9. package/dist/src/common/datatype.js.map +1 -0
  10. package/dist/src/common/errors.d.ts +90 -0
  11. package/dist/src/common/errors.d.ts.map +1 -0
  12. package/dist/src/common/errors.js +142 -0
  13. package/dist/src/common/errors.js.map +1 -0
  14. package/dist/src/common/logger.d.ts +18 -0
  15. package/dist/src/common/logger.d.ts.map +1 -0
  16. package/dist/src/common/logger.js +22 -0
  17. package/dist/src/common/logger.js.map +1 -0
  18. package/dist/src/common/type-inference.d.ts +11 -0
  19. package/dist/src/common/type-inference.d.ts.map +1 -0
  20. package/dist/src/common/type-inference.js +44 -0
  21. package/dist/src/common/type-inference.js.map +1 -0
  22. package/dist/src/common/types.d.ts +131 -0
  23. package/dist/src/common/types.d.ts.map +1 -0
  24. package/dist/src/common/types.js +53 -0
  25. package/dist/src/common/types.js.map +1 -0
  26. package/dist/src/core/database-options.d.ts +67 -0
  27. package/dist/src/core/database-options.d.ts.map +1 -0
  28. package/dist/src/core/database-options.js +211 -0
  29. package/dist/src/core/database-options.js.map +1 -0
  30. package/dist/src/core/database.d.ts +214 -0
  31. package/dist/src/core/database.d.ts.map +1 -0
  32. package/dist/src/core/database.js +750 -0
  33. package/dist/src/core/database.js.map +1 -0
  34. package/dist/src/core/param.d.ts +4 -0
  35. package/dist/src/core/param.d.ts.map +1 -0
  36. package/dist/src/core/param.js +46 -0
  37. package/dist/src/core/param.js.map +1 -0
  38. package/dist/src/core/statement.d.ts +94 -0
  39. package/dist/src/core/statement.d.ts.map +1 -0
  40. package/dist/src/core/statement.js +482 -0
  41. package/dist/src/core/statement.js.map +1 -0
  42. package/dist/src/func/builtins/aggregate.d.ts +13 -0
  43. package/dist/src/func/builtins/aggregate.d.ts.map +1 -0
  44. package/dist/src/func/builtins/aggregate.js +190 -0
  45. package/dist/src/func/builtins/aggregate.js.map +1 -0
  46. package/dist/src/func/builtins/builtin-window-functions.d.ts +2 -0
  47. package/dist/src/func/builtins/builtin-window-functions.d.ts.map +1 -0
  48. package/dist/src/func/builtins/builtin-window-functions.js +161 -0
  49. package/dist/src/func/builtins/builtin-window-functions.js.map +1 -0
  50. package/dist/src/func/builtins/datetime.d.ts +6 -0
  51. package/dist/src/func/builtins/datetime.d.ts.map +1 -0
  52. package/dist/src/func/builtins/datetime.js +417 -0
  53. package/dist/src/func/builtins/datetime.js.map +1 -0
  54. package/dist/src/func/builtins/explain.d.ts +7 -0
  55. package/dist/src/func/builtins/explain.d.ts.map +1 -0
  56. package/dist/src/func/builtins/explain.js +570 -0
  57. package/dist/src/func/builtins/explain.js.map +1 -0
  58. package/dist/src/func/builtins/generation.d.ts +2 -0
  59. package/dist/src/func/builtins/generation.d.ts.map +1 -0
  60. package/dist/src/func/builtins/generation.js +36 -0
  61. package/dist/src/func/builtins/generation.js.map +1 -0
  62. package/dist/src/func/builtins/index.d.ts +4 -0
  63. package/dist/src/func/builtins/index.d.ts.map +1 -0
  64. package/dist/src/func/builtins/index.js +106 -0
  65. package/dist/src/func/builtins/index.js.map +1 -0
  66. package/dist/src/func/builtins/json-helpers.d.ts +64 -0
  67. package/dist/src/func/builtins/json-helpers.d.ts.map +1 -0
  68. package/dist/src/func/builtins/json-helpers.js +237 -0
  69. package/dist/src/func/builtins/json-helpers.js.map +1 -0
  70. package/dist/src/func/builtins/json-tvf.d.ts +3 -0
  71. package/dist/src/func/builtins/json-tvf.d.ts.map +1 -0
  72. package/dist/src/func/builtins/json-tvf.js +199 -0
  73. package/dist/src/func/builtins/json-tvf.js.map +1 -0
  74. package/dist/src/func/builtins/json.d.ts +15 -0
  75. package/dist/src/func/builtins/json.d.ts.map +1 -0
  76. package/dist/src/func/builtins/json.js +417 -0
  77. package/dist/src/func/builtins/json.js.map +1 -0
  78. package/dist/src/func/builtins/scalar.d.ts +19 -0
  79. package/dist/src/func/builtins/scalar.d.ts.map +1 -0
  80. package/dist/src/func/builtins/scalar.js +176 -0
  81. package/dist/src/func/builtins/scalar.js.map +1 -0
  82. package/dist/src/func/builtins/schema.d.ts +4 -0
  83. package/dist/src/func/builtins/schema.d.ts.map +1 -0
  84. package/dist/src/func/builtins/schema.js +167 -0
  85. package/dist/src/func/builtins/schema.js.map +1 -0
  86. package/dist/src/func/builtins/string.d.ts +18 -0
  87. package/dist/src/func/builtins/string.d.ts.map +1 -0
  88. package/dist/src/func/builtins/string.js +233 -0
  89. package/dist/src/func/builtins/string.js.map +1 -0
  90. package/dist/src/func/context.d.ts +102 -0
  91. package/dist/src/func/context.d.ts.map +1 -0
  92. package/dist/src/func/context.js +130 -0
  93. package/dist/src/func/context.js.map +1 -0
  94. package/dist/src/func/registration.d.ts +89 -0
  95. package/dist/src/func/registration.d.ts.map +1 -0
  96. package/dist/src/func/registration.js +103 -0
  97. package/dist/src/func/registration.js.map +1 -0
  98. package/dist/src/index.d.ts +34 -0
  99. package/dist/src/index.d.ts.map +1 -0
  100. package/dist/src/index.js +35 -0
  101. package/dist/src/index.js.map +1 -0
  102. package/dist/src/parser/ast.d.ts +376 -0
  103. package/dist/src/parser/ast.d.ts.map +1 -0
  104. package/dist/src/parser/ast.js +2 -0
  105. package/dist/src/parser/ast.js.map +1 -0
  106. package/dist/src/parser/index.d.ts +29 -0
  107. package/dist/src/parser/index.d.ts.map +1 -0
  108. package/dist/src/parser/index.js +50 -0
  109. package/dist/src/parser/index.js.map +1 -0
  110. package/dist/src/parser/lexer.d.ts +197 -0
  111. package/dist/src/parser/lexer.d.ts.map +1 -0
  112. package/dist/src/parser/lexer.js +762 -0
  113. package/dist/src/parser/lexer.js.map +1 -0
  114. package/dist/src/parser/parser.d.ts +216 -0
  115. package/dist/src/parser/parser.d.ts.map +1 -0
  116. package/dist/src/parser/parser.js +2619 -0
  117. package/dist/src/parser/parser.js.map +1 -0
  118. package/dist/src/parser/utils.d.ts +4 -0
  119. package/dist/src/parser/utils.d.ts.map +1 -0
  120. package/dist/src/parser/utils.js +8 -0
  121. package/dist/src/parser/utils.js.map +1 -0
  122. package/dist/src/parser/visitor.d.ts +38 -0
  123. package/dist/src/parser/visitor.d.ts.map +1 -0
  124. package/dist/src/parser/visitor.js +153 -0
  125. package/dist/src/parser/visitor.js.map +1 -0
  126. package/dist/src/planner/analysis/const-evaluator.d.ts +14 -0
  127. package/dist/src/planner/analysis/const-evaluator.d.ts.map +1 -0
  128. package/dist/src/planner/analysis/const-evaluator.js +50 -0
  129. package/dist/src/planner/analysis/const-evaluator.js.map +1 -0
  130. package/dist/src/planner/analysis/const-pass.d.ts +51 -0
  131. package/dist/src/planner/analysis/const-pass.d.ts.map +1 -0
  132. package/dist/src/planner/analysis/const-pass.js +200 -0
  133. package/dist/src/planner/analysis/const-pass.js.map +1 -0
  134. package/dist/src/planner/analysis/constraint-extractor.d.ts +57 -0
  135. package/dist/src/planner/analysis/constraint-extractor.d.ts.map +1 -0
  136. package/dist/src/planner/analysis/constraint-extractor.js +193 -0
  137. package/dist/src/planner/analysis/constraint-extractor.js.map +1 -0
  138. package/dist/src/planner/building/alter-table.d.ts +5 -0
  139. package/dist/src/planner/building/alter-table.d.ts.map +1 -0
  140. package/dist/src/planner/building/alter-table.js +26 -0
  141. package/dist/src/planner/building/alter-table.js.map +1 -0
  142. package/dist/src/planner/building/block.d.ts +5 -0
  143. package/dist/src/planner/building/block.d.ts.map +1 -0
  144. package/dist/src/planner/building/block.js +68 -0
  145. package/dist/src/planner/building/block.js.map +1 -0
  146. package/dist/src/planner/building/create-view.d.ts +8 -0
  147. package/dist/src/planner/building/create-view.d.ts.map +1 -0
  148. package/dist/src/planner/building/create-view.js +37 -0
  149. package/dist/src/planner/building/create-view.js.map +1 -0
  150. package/dist/src/planner/building/ddl.d.ts +7 -0
  151. package/dist/src/planner/building/ddl.d.ts.map +1 -0
  152. package/dist/src/planner/building/ddl.js +9 -0
  153. package/dist/src/planner/building/ddl.js.map +1 -0
  154. package/dist/src/planner/building/delete.d.ts +5 -0
  155. package/dist/src/planner/building/delete.d.ts.map +1 -0
  156. package/dist/src/planner/building/delete.js +105 -0
  157. package/dist/src/planner/building/delete.js.map +1 -0
  158. package/dist/src/planner/building/drop-table.d.ts +5 -0
  159. package/dist/src/planner/building/drop-table.d.ts.map +1 -0
  160. package/dist/src/planner/building/drop-table.js +5 -0
  161. package/dist/src/planner/building/drop-table.js.map +1 -0
  162. package/dist/src/planner/building/drop-view.d.ts +8 -0
  163. package/dist/src/planner/building/drop-view.d.ts.map +1 -0
  164. package/dist/src/planner/building/drop-view.js +11 -0
  165. package/dist/src/planner/building/drop-view.js.map +1 -0
  166. package/dist/src/planner/building/expression.d.ts +5 -0
  167. package/dist/src/planner/building/expression.d.ts.map +1 -0
  168. package/dist/src/planner/building/expression.js +147 -0
  169. package/dist/src/planner/building/expression.js.map +1 -0
  170. package/dist/src/planner/building/function-call.d.ts +5 -0
  171. package/dist/src/planner/building/function-call.d.ts.map +1 -0
  172. package/dist/src/planner/building/function-call.js +70 -0
  173. package/dist/src/planner/building/function-call.js.map +1 -0
  174. package/dist/src/planner/building/insert.d.ts +5 -0
  175. package/dist/src/planner/building/insert.d.ts.map +1 -0
  176. package/dist/src/planner/building/insert.js +261 -0
  177. package/dist/src/planner/building/insert.js.map +1 -0
  178. package/dist/src/planner/building/pragma.d.ts +5 -0
  179. package/dist/src/planner/building/pragma.d.ts.map +1 -0
  180. package/dist/src/planner/building/pragma.js +28 -0
  181. package/dist/src/planner/building/pragma.js.map +1 -0
  182. package/dist/src/planner/building/schema-resolution.d.ts +25 -0
  183. package/dist/src/planner/building/schema-resolution.d.ts.map +1 -0
  184. package/dist/src/planner/building/schema-resolution.js +119 -0
  185. package/dist/src/planner/building/schema-resolution.js.map +1 -0
  186. package/dist/src/planner/building/select-aggregates.d.ts +22 -0
  187. package/dist/src/planner/building/select-aggregates.d.ts.map +1 -0
  188. package/dist/src/planner/building/select-aggregates.js +164 -0
  189. package/dist/src/planner/building/select-aggregates.js.map +1 -0
  190. package/dist/src/planner/building/select-compound.d.ts +9 -0
  191. package/dist/src/planner/building/select-compound.d.ts.map +1 -0
  192. package/dist/src/planner/building/select-compound.js +78 -0
  193. package/dist/src/planner/building/select-compound.js.map +1 -0
  194. package/dist/src/planner/building/select-context.d.ts +18 -0
  195. package/dist/src/planner/building/select-context.d.ts.map +1 -0
  196. package/dist/src/planner/building/select-context.js +54 -0
  197. package/dist/src/planner/building/select-context.js.map +1 -0
  198. package/dist/src/planner/building/select-modifiers.d.ts +25 -0
  199. package/dist/src/planner/building/select-modifiers.d.ts.map +1 -0
  200. package/dist/src/planner/building/select-modifiers.js +120 -0
  201. package/dist/src/planner/building/select-modifiers.js.map +1 -0
  202. package/dist/src/planner/building/select-projections.d.ts +37 -0
  203. package/dist/src/planner/building/select-projections.d.ts.map +1 -0
  204. package/dist/src/planner/building/select-projections.js +132 -0
  205. package/dist/src/planner/building/select-projections.js.map +1 -0
  206. package/dist/src/planner/building/select-window.d.ts +12 -0
  207. package/dist/src/planner/building/select-window.d.ts.map +1 -0
  208. package/dist/src/planner/building/select-window.js +159 -0
  209. package/dist/src/planner/building/select-window.js.map +1 -0
  210. package/dist/src/planner/building/select.d.ts +28 -0
  211. package/dist/src/planner/building/select.d.ts.map +1 -0
  212. package/dist/src/planner/building/select.js +307 -0
  213. package/dist/src/planner/building/select.js.map +1 -0
  214. package/dist/src/planner/building/table-function.d.ts +5 -0
  215. package/dist/src/planner/building/table-function.d.ts.map +1 -0
  216. package/dist/src/planner/building/table-function.js +21 -0
  217. package/dist/src/planner/building/table-function.js.map +1 -0
  218. package/dist/src/planner/building/table.d.ts +23 -0
  219. package/dist/src/planner/building/table.d.ts.map +1 -0
  220. package/dist/src/planner/building/table.js +57 -0
  221. package/dist/src/planner/building/table.js.map +1 -0
  222. package/dist/src/planner/building/transaction.d.ts +9 -0
  223. package/dist/src/planner/building/transaction.d.ts.map +1 -0
  224. package/dist/src/planner/building/transaction.js +17 -0
  225. package/dist/src/planner/building/transaction.js.map +1 -0
  226. package/dist/src/planner/building/update.d.ts +5 -0
  227. package/dist/src/planner/building/update.d.ts.map +1 -0
  228. package/dist/src/planner/building/update.js +152 -0
  229. package/dist/src/planner/building/update.js.map +1 -0
  230. package/dist/src/planner/building/with.d.ts +13 -0
  231. package/dist/src/planner/building/with.d.ts.map +1 -0
  232. package/dist/src/planner/building/with.js +112 -0
  233. package/dist/src/planner/building/with.js.map +1 -0
  234. package/dist/src/planner/cache/materialization-advisory.d.ts +66 -0
  235. package/dist/src/planner/cache/materialization-advisory.d.ts.map +1 -0
  236. package/dist/src/planner/cache/materialization-advisory.js +187 -0
  237. package/dist/src/planner/cache/materialization-advisory.js.map +1 -0
  238. package/dist/src/planner/cache/reference-graph.d.ts +53 -0
  239. package/dist/src/planner/cache/reference-graph.d.ts.map +1 -0
  240. package/dist/src/planner/cache/reference-graph.js +139 -0
  241. package/dist/src/planner/cache/reference-graph.js.map +1 -0
  242. package/dist/src/planner/cost/index.d.ts +106 -0
  243. package/dist/src/planner/cost/index.d.ts.map +1 -0
  244. package/dist/src/planner/cost/index.js +143 -0
  245. package/dist/src/planner/cost/index.js.map +1 -0
  246. package/dist/src/planner/debug/logger-utils.d.ts +44 -0
  247. package/dist/src/planner/debug/logger-utils.d.ts.map +1 -0
  248. package/dist/src/planner/debug/logger-utils.js +58 -0
  249. package/dist/src/planner/debug/logger-utils.js.map +1 -0
  250. package/dist/src/planner/debug.d.ts +53 -0
  251. package/dist/src/planner/debug.d.ts.map +1 -0
  252. package/dist/src/planner/debug.js +228 -0
  253. package/dist/src/planner/debug.js.map +1 -0
  254. package/dist/src/planner/framework/context.d.ts +86 -0
  255. package/dist/src/planner/framework/context.d.ts.map +1 -0
  256. package/dist/src/planner/framework/context.js +117 -0
  257. package/dist/src/planner/framework/context.js.map +1 -0
  258. package/dist/src/planner/framework/physical-utils.d.ts +62 -0
  259. package/dist/src/planner/framework/physical-utils.d.ts.map +1 -0
  260. package/dist/src/planner/framework/physical-utils.js +149 -0
  261. package/dist/src/planner/framework/physical-utils.js.map +1 -0
  262. package/dist/src/planner/framework/registry.d.ts +75 -0
  263. package/dist/src/planner/framework/registry.d.ts.map +1 -0
  264. package/dist/src/planner/framework/registry.js +203 -0
  265. package/dist/src/planner/framework/registry.js.map +1 -0
  266. package/dist/src/planner/framework/trace.d.ts +84 -0
  267. package/dist/src/planner/framework/trace.d.ts.map +1 -0
  268. package/dist/src/planner/framework/trace.js +198 -0
  269. package/dist/src/planner/framework/trace.js.map +1 -0
  270. package/dist/src/planner/nodes/add-constraint-node.d.ts +23 -0
  271. package/dist/src/planner/nodes/add-constraint-node.d.ts.map +1 -0
  272. package/dist/src/planner/nodes/add-constraint-node.js +47 -0
  273. package/dist/src/planner/nodes/add-constraint-node.js.map +1 -0
  274. package/dist/src/planner/nodes/aggregate-function.d.ts +34 -0
  275. package/dist/src/planner/nodes/aggregate-function.d.ts.map +1 -0
  276. package/dist/src/planner/nodes/aggregate-function.js +119 -0
  277. package/dist/src/planner/nodes/aggregate-function.js.map +1 -0
  278. package/dist/src/planner/nodes/aggregate-node.d.ts +35 -0
  279. package/dist/src/planner/nodes/aggregate-node.d.ts.map +1 -0
  280. package/dist/src/planner/nodes/aggregate-node.js +176 -0
  281. package/dist/src/planner/nodes/aggregate-node.js.map +1 -0
  282. package/dist/src/planner/nodes/array-index-node.d.ts +22 -0
  283. package/dist/src/planner/nodes/array-index-node.d.ts.map +1 -0
  284. package/dist/src/planner/nodes/array-index-node.js +41 -0
  285. package/dist/src/planner/nodes/array-index-node.js.map +1 -0
  286. package/dist/src/planner/nodes/block.d.ts +26 -0
  287. package/dist/src/planner/nodes/block.d.ts.map +1 -0
  288. package/dist/src/planner/nodes/block.js +58 -0
  289. package/dist/src/planner/nodes/block.js.map +1 -0
  290. package/dist/src/planner/nodes/cache-node.d.ts +29 -0
  291. package/dist/src/planner/nodes/cache-node.d.ts.map +1 -0
  292. package/dist/src/planner/nodes/cache-node.js +73 -0
  293. package/dist/src/planner/nodes/cache-node.js.map +1 -0
  294. package/dist/src/planner/nodes/constraint-check-node.d.ts +28 -0
  295. package/dist/src/planner/nodes/constraint-check-node.d.ts.map +1 -0
  296. package/dist/src/planner/nodes/constraint-check-node.js +73 -0
  297. package/dist/src/planner/nodes/constraint-check-node.js.map +1 -0
  298. package/dist/src/planner/nodes/create-index-node.d.ts +15 -0
  299. package/dist/src/planner/nodes/create-index-node.d.ts.map +1 -0
  300. package/dist/src/planner/nodes/create-index-node.js +31 -0
  301. package/dist/src/planner/nodes/create-index-node.js.map +1 -0
  302. package/dist/src/planner/nodes/create-table-node.d.ts +15 -0
  303. package/dist/src/planner/nodes/create-table-node.d.ts.map +1 -0
  304. package/dist/src/planner/nodes/create-table-node.js +25 -0
  305. package/dist/src/planner/nodes/create-table-node.js.map +1 -0
  306. package/dist/src/planner/nodes/create-view-node.d.ts +21 -0
  307. package/dist/src/planner/nodes/create-view-node.d.ts.map +1 -0
  308. package/dist/src/planner/nodes/create-view-node.js +39 -0
  309. package/dist/src/planner/nodes/create-view-node.js.map +1 -0
  310. package/dist/src/planner/nodes/cte-node.d.ts +40 -0
  311. package/dist/src/planner/nodes/cte-node.d.ts.map +1 -0
  312. package/dist/src/planner/nodes/cte-node.js +88 -0
  313. package/dist/src/planner/nodes/cte-node.js.map +1 -0
  314. package/dist/src/planner/nodes/cte-reference-node.d.ts +27 -0
  315. package/dist/src/planner/nodes/cte-reference-node.d.ts.map +1 -0
  316. package/dist/src/planner/nodes/cte-reference-node.js +75 -0
  317. package/dist/src/planner/nodes/cte-reference-node.js.map +1 -0
  318. package/dist/src/planner/nodes/delete-node.d.ts +27 -0
  319. package/dist/src/planner/nodes/delete-node.d.ts.map +1 -0
  320. package/dist/src/planner/nodes/delete-node.js +62 -0
  321. package/dist/src/planner/nodes/delete-node.js.map +1 -0
  322. package/dist/src/planner/nodes/distinct-node.d.ts +22 -0
  323. package/dist/src/planner/nodes/distinct-node.d.ts.map +1 -0
  324. package/dist/src/planner/nodes/distinct-node.js +74 -0
  325. package/dist/src/planner/nodes/distinct-node.js.map +1 -0
  326. package/dist/src/planner/nodes/dml-executor-node.d.ts +30 -0
  327. package/dist/src/planner/nodes/dml-executor-node.d.ts.map +1 -0
  328. package/dist/src/planner/nodes/dml-executor-node.js +73 -0
  329. package/dist/src/planner/nodes/dml-executor-node.js.map +1 -0
  330. package/dist/src/planner/nodes/drop-table-node.d.ts +15 -0
  331. package/dist/src/planner/nodes/drop-table-node.d.ts.map +1 -0
  332. package/dist/src/planner/nodes/drop-table-node.js +25 -0
  333. package/dist/src/planner/nodes/drop-table-node.js.map +1 -0
  334. package/dist/src/planner/nodes/drop-view-node.d.ts +17 -0
  335. package/dist/src/planner/nodes/drop-view-node.d.ts.map +1 -0
  336. package/dist/src/planner/nodes/drop-view-node.js +30 -0
  337. package/dist/src/planner/nodes/drop-view-node.js.map +1 -0
  338. package/dist/src/planner/nodes/filter.d.ts +24 -0
  339. package/dist/src/planner/nodes/filter.d.ts.map +1 -0
  340. package/dist/src/planner/nodes/filter.js +72 -0
  341. package/dist/src/planner/nodes/filter.js.map +1 -0
  342. package/dist/src/planner/nodes/function.d.ts +21 -0
  343. package/dist/src/planner/nodes/function.d.ts.map +1 -0
  344. package/dist/src/planner/nodes/function.js +70 -0
  345. package/dist/src/planner/nodes/function.js.map +1 -0
  346. package/dist/src/planner/nodes/insert-node.d.ts +26 -0
  347. package/dist/src/planner/nodes/insert-node.d.ts.map +1 -0
  348. package/dist/src/planner/nodes/insert-node.js +82 -0
  349. package/dist/src/planner/nodes/insert-node.js.map +1 -0
  350. package/dist/src/planner/nodes/join-node.d.ts +30 -0
  351. package/dist/src/planner/nodes/join-node.d.ts.map +1 -0
  352. package/dist/src/planner/nodes/join-node.js +177 -0
  353. package/dist/src/planner/nodes/join-node.js.map +1 -0
  354. package/dist/src/planner/nodes/limit-offset.d.ts +24 -0
  355. package/dist/src/planner/nodes/limit-offset.d.ts.map +1 -0
  356. package/dist/src/planner/nodes/limit-offset.js +103 -0
  357. package/dist/src/planner/nodes/limit-offset.js.map +1 -0
  358. package/dist/src/planner/nodes/physical-access-nodes.d.ts +83 -0
  359. package/dist/src/planner/nodes/physical-access-nodes.d.ts.map +1 -0
  360. package/dist/src/planner/nodes/physical-access-nodes.js +226 -0
  361. package/dist/src/planner/nodes/physical-access-nodes.js.map +1 -0
  362. package/dist/src/planner/nodes/plan-node-type.d.ts +71 -0
  363. package/dist/src/planner/nodes/plan-node-type.d.ts.map +1 -0
  364. package/dist/src/planner/nodes/plan-node-type.js +81 -0
  365. package/dist/src/planner/nodes/plan-node-type.js.map +1 -0
  366. package/dist/src/planner/nodes/plan-node.d.ts +297 -0
  367. package/dist/src/planner/nodes/plan-node.d.ts.map +1 -0
  368. package/dist/src/planner/nodes/plan-node.js +198 -0
  369. package/dist/src/planner/nodes/plan-node.js.map +1 -0
  370. package/dist/src/planner/nodes/pragma.d.ts +21 -0
  371. package/dist/src/planner/nodes/pragma.d.ts.map +1 -0
  372. package/dist/src/planner/nodes/pragma.js +80 -0
  373. package/dist/src/planner/nodes/pragma.js.map +1 -0
  374. package/dist/src/planner/nodes/project-node.d.ts +34 -0
  375. package/dist/src/planner/nodes/project-node.d.ts.map +1 -0
  376. package/dist/src/planner/nodes/project-node.js +181 -0
  377. package/dist/src/planner/nodes/project-node.js.map +1 -0
  378. package/dist/src/planner/nodes/recursive-cte-node.d.ts +41 -0
  379. package/dist/src/planner/nodes/recursive-cte-node.d.ts.map +1 -0
  380. package/dist/src/planner/nodes/recursive-cte-node.js +114 -0
  381. package/dist/src/planner/nodes/recursive-cte-node.js.map +1 -0
  382. package/dist/src/planner/nodes/reference.d.ts +92 -0
  383. package/dist/src/planner/nodes/reference.d.ts.map +1 -0
  384. package/dist/src/planner/nodes/reference.js +258 -0
  385. package/dist/src/planner/nodes/reference.js.map +1 -0
  386. package/dist/src/planner/nodes/returning-node.d.ts +37 -0
  387. package/dist/src/planner/nodes/returning-node.d.ts.map +1 -0
  388. package/dist/src/planner/nodes/returning-node.js +183 -0
  389. package/dist/src/planner/nodes/returning-node.js.map +1 -0
  390. package/dist/src/planner/nodes/scalar.d.ts +106 -0
  391. package/dist/src/planner/nodes/scalar.d.ts.map +1 -0
  392. package/dist/src/planner/nodes/scalar.js +618 -0
  393. package/dist/src/planner/nodes/scalar.js.map +1 -0
  394. package/dist/src/planner/nodes/scan.d.ts +27 -0
  395. package/dist/src/planner/nodes/scan.d.ts.map +1 -0
  396. package/dist/src/planner/nodes/scan.js +78 -0
  397. package/dist/src/planner/nodes/scan.js.map +1 -0
  398. package/dist/src/planner/nodes/sequencing-node.d.ts +25 -0
  399. package/dist/src/planner/nodes/sequencing-node.d.ts.map +1 -0
  400. package/dist/src/planner/nodes/sequencing-node.js +88 -0
  401. package/dist/src/planner/nodes/sequencing-node.js.map +1 -0
  402. package/dist/src/planner/nodes/set-operation-node.d.ts +21 -0
  403. package/dist/src/planner/nodes/set-operation-node.d.ts.map +1 -0
  404. package/dist/src/planner/nodes/set-operation-node.js +68 -0
  405. package/dist/src/planner/nodes/set-operation-node.js.map +1 -0
  406. package/dist/src/planner/nodes/single-row.d.ts +24 -0
  407. package/dist/src/planner/nodes/single-row.d.ts.map +1 -0
  408. package/dist/src/planner/nodes/single-row.js +65 -0
  409. package/dist/src/planner/nodes/single-row.js.map +1 -0
  410. package/dist/src/planner/nodes/sink-node.d.ts +25 -0
  411. package/dist/src/planner/nodes/sink-node.d.ts.map +1 -0
  412. package/dist/src/planner/nodes/sink-node.js +52 -0
  413. package/dist/src/planner/nodes/sink-node.js.map +1 -0
  414. package/dist/src/planner/nodes/sort.d.ts +37 -0
  415. package/dist/src/planner/nodes/sort.d.ts.map +1 -0
  416. package/dist/src/planner/nodes/sort.js +97 -0
  417. package/dist/src/planner/nodes/sort.js.map +1 -0
  418. package/dist/src/planner/nodes/stream-aggregate.d.ts +35 -0
  419. package/dist/src/planner/nodes/stream-aggregate.d.ts.map +1 -0
  420. package/dist/src/planner/nodes/stream-aggregate.js +186 -0
  421. package/dist/src/planner/nodes/stream-aggregate.js.map +1 -0
  422. package/dist/src/planner/nodes/subquery.d.ts +54 -0
  423. package/dist/src/planner/nodes/subquery.d.ts.map +1 -0
  424. package/dist/src/planner/nodes/subquery.js +181 -0
  425. package/dist/src/planner/nodes/subquery.js.map +1 -0
  426. package/dist/src/planner/nodes/table-function-call.d.ts +27 -0
  427. package/dist/src/planner/nodes/table-function-call.d.ts.map +1 -0
  428. package/dist/src/planner/nodes/table-function-call.js +101 -0
  429. package/dist/src/planner/nodes/table-function-call.js.map +1 -0
  430. package/dist/src/planner/nodes/transaction-node.d.ts +22 -0
  431. package/dist/src/planner/nodes/transaction-node.d.ts.map +1 -0
  432. package/dist/src/planner/nodes/transaction-node.js +47 -0
  433. package/dist/src/planner/nodes/transaction-node.js.map +1 -0
  434. package/dist/src/planner/nodes/update-executor-node.d.ts +24 -0
  435. package/dist/src/planner/nodes/update-executor-node.d.ts.map +1 -0
  436. package/dist/src/planner/nodes/update-executor-node.js +57 -0
  437. package/dist/src/planner/nodes/update-executor-node.js.map +1 -0
  438. package/dist/src/planner/nodes/update-node.d.ts +38 -0
  439. package/dist/src/planner/nodes/update-node.d.ts.map +1 -0
  440. package/dist/src/planner/nodes/update-node.js +88 -0
  441. package/dist/src/planner/nodes/update-node.js.map +1 -0
  442. package/dist/src/planner/nodes/values-node.d.ts +49 -0
  443. package/dist/src/planner/nodes/values-node.d.ts.map +1 -0
  444. package/dist/src/planner/nodes/values-node.js +204 -0
  445. package/dist/src/planner/nodes/values-node.js.map +1 -0
  446. package/dist/src/planner/nodes/view-reference-node.d.ts +27 -0
  447. package/dist/src/planner/nodes/view-reference-node.d.ts.map +1 -0
  448. package/dist/src/planner/nodes/view-reference-node.js +83 -0
  449. package/dist/src/planner/nodes/view-reference-node.js.map +1 -0
  450. package/dist/src/planner/nodes/window-function.d.ts +25 -0
  451. package/dist/src/planner/nodes/window-function.d.ts.map +1 -0
  452. package/dist/src/planner/nodes/window-function.js +62 -0
  453. package/dist/src/planner/nodes/window-function.js.map +1 -0
  454. package/dist/src/planner/nodes/window-node.d.ts +40 -0
  455. package/dist/src/planner/nodes/window-node.d.ts.map +1 -0
  456. package/dist/src/planner/nodes/window-node.js +156 -0
  457. package/dist/src/planner/nodes/window-node.js.map +1 -0
  458. package/dist/src/planner/optimizer-tuning.d.ts +55 -0
  459. package/dist/src/planner/optimizer-tuning.d.ts.map +1 -0
  460. package/dist/src/planner/optimizer-tuning.js +31 -0
  461. package/dist/src/planner/optimizer-tuning.js.map +1 -0
  462. package/dist/src/planner/optimizer.d.ts +34 -0
  463. package/dist/src/planner/optimizer.d.ts.map +1 -0
  464. package/dist/src/planner/optimizer.js +194 -0
  465. package/dist/src/planner/optimizer.js.map +1 -0
  466. package/dist/src/planner/physical-utils.d.ts +36 -0
  467. package/dist/src/planner/physical-utils.d.ts.map +1 -0
  468. package/dist/src/planner/physical-utils.js +122 -0
  469. package/dist/src/planner/physical-utils.js.map +1 -0
  470. package/dist/src/planner/planning-context.d.ts +111 -0
  471. package/dist/src/planner/planning-context.d.ts.map +1 -0
  472. package/dist/src/planner/planning-context.js +75 -0
  473. package/dist/src/planner/planning-context.js.map +1 -0
  474. package/dist/src/planner/resolve.d.ts +8 -0
  475. package/dist/src/planner/resolve.d.ts.map +1 -0
  476. package/dist/src/planner/resolve.js +91 -0
  477. package/dist/src/planner/resolve.js.map +1 -0
  478. package/dist/src/planner/rules/access/rule-select-access-path.d.ts +11 -0
  479. package/dist/src/planner/rules/access/rule-select-access-path.d.ts.map +1 -0
  480. package/dist/src/planner/rules/access/rule-select-access-path.js +133 -0
  481. package/dist/src/planner/rules/access/rule-select-access-path.js.map +1 -0
  482. package/dist/src/planner/rules/aggregate/rule-aggregate-streaming.d.ts +11 -0
  483. package/dist/src/planner/rules/aggregate/rule-aggregate-streaming.d.ts.map +1 -0
  484. package/dist/src/planner/rules/aggregate/rule-aggregate-streaming.js +53 -0
  485. package/dist/src/planner/rules/aggregate/rule-aggregate-streaming.js.map +1 -0
  486. package/dist/src/planner/rules/cache/rule-cte-optimization.d.ts +11 -0
  487. package/dist/src/planner/rules/cache/rule-cte-optimization.d.ts.map +1 -0
  488. package/dist/src/planner/rules/cache/rule-cte-optimization.js +38 -0
  489. package/dist/src/planner/rules/cache/rule-cte-optimization.js.map +1 -0
  490. package/dist/src/planner/rules/cache/rule-materialization-advisory.d.ts +11 -0
  491. package/dist/src/planner/rules/cache/rule-materialization-advisory.d.ts.map +1 -0
  492. package/dist/src/planner/rules/cache/rule-materialization-advisory.js +51 -0
  493. package/dist/src/planner/rules/cache/rule-materialization-advisory.js.map +1 -0
  494. package/dist/src/planner/rules/cache/rule-mutating-subquery-cache.d.ts +11 -0
  495. package/dist/src/planner/rules/cache/rule-mutating-subquery-cache.d.ts.map +1 -0
  496. package/dist/src/planner/rules/cache/rule-mutating-subquery-cache.js +79 -0
  497. package/dist/src/planner/rules/cache/rule-mutating-subquery-cache.js.map +1 -0
  498. package/dist/src/planner/rules/physical/rule-filter-optimization.d.ts +11 -0
  499. package/dist/src/planner/rules/physical/rule-filter-optimization.d.ts.map +1 -0
  500. package/dist/src/planner/rules/physical/rule-filter-optimization.js +49 -0
  501. package/dist/src/planner/rules/physical/rule-filter-optimization.js.map +1 -0
  502. package/dist/src/planner/rules/physical/rule-mark-physical.d.ts +11 -0
  503. package/dist/src/planner/rules/physical/rule-mark-physical.d.ts.map +1 -0
  504. package/dist/src/planner/rules/physical/rule-mark-physical.js +29 -0
  505. package/dist/src/planner/rules/physical/rule-mark-physical.js.map +1 -0
  506. package/dist/src/planner/rules/physical/rule-project-optimization.d.ts +11 -0
  507. package/dist/src/planner/rules/physical/rule-project-optimization.d.ts.map +1 -0
  508. package/dist/src/planner/rules/physical/rule-project-optimization.js +44 -0
  509. package/dist/src/planner/rules/physical/rule-project-optimization.js.map +1 -0
  510. package/dist/src/planner/rules/physical/rule-sort-optimization.d.ts +11 -0
  511. package/dist/src/planner/rules/physical/rule-sort-optimization.d.ts.map +1 -0
  512. package/dist/src/planner/rules/physical/rule-sort-optimization.js +53 -0
  513. package/dist/src/planner/rules/physical/rule-sort-optimization.js.map +1 -0
  514. package/dist/src/planner/rules/rewrite/rule-constant-folding.d.ts +11 -0
  515. package/dist/src/planner/rules/rewrite/rule-constant-folding.d.ts.map +1 -0
  516. package/dist/src/planner/rules/rewrite/rule-constant-folding.js +59 -0
  517. package/dist/src/planner/rules/rewrite/rule-constant-folding.js.map +1 -0
  518. package/dist/src/planner/scopes/aliased.d.ts +18 -0
  519. package/dist/src/planner/scopes/aliased.d.ts.map +1 -0
  520. package/dist/src/planner/scopes/aliased.js +41 -0
  521. package/dist/src/planner/scopes/aliased.js.map +1 -0
  522. package/dist/src/planner/scopes/base.d.ts +20 -0
  523. package/dist/src/planner/scopes/base.d.ts.map +1 -0
  524. package/dist/src/planner/scopes/base.js +20 -0
  525. package/dist/src/planner/scopes/base.js.map +1 -0
  526. package/dist/src/planner/scopes/empty.d.ts +11 -0
  527. package/dist/src/planner/scopes/empty.d.ts.map +1 -0
  528. package/dist/src/planner/scopes/empty.js +16 -0
  529. package/dist/src/planner/scopes/empty.js.map +1 -0
  530. package/dist/src/planner/scopes/global.d.ts +12 -0
  531. package/dist/src/planner/scopes/global.d.ts.map +1 -0
  532. package/dist/src/planner/scopes/global.js +65 -0
  533. package/dist/src/planner/scopes/global.js.map +1 -0
  534. package/dist/src/planner/scopes/multi.d.ts +17 -0
  535. package/dist/src/planner/scopes/multi.d.ts.map +1 -0
  536. package/dist/src/planner/scopes/multi.js +35 -0
  537. package/dist/src/planner/scopes/multi.js.map +1 -0
  538. package/dist/src/planner/scopes/param.d.ts +23 -0
  539. package/dist/src/planner/scopes/param.d.ts.map +1 -0
  540. package/dist/src/planner/scopes/param.js +78 -0
  541. package/dist/src/planner/scopes/param.js.map +1 -0
  542. package/dist/src/planner/scopes/registered.d.ts +47 -0
  543. package/dist/src/planner/scopes/registered.d.ts.map +1 -0
  544. package/dist/src/planner/scopes/registered.js +70 -0
  545. package/dist/src/planner/scopes/registered.js.map +1 -0
  546. package/dist/src/planner/scopes/scope.d.ts +21 -0
  547. package/dist/src/planner/scopes/scope.d.ts.map +1 -0
  548. package/dist/src/planner/scopes/scope.js +3 -0
  549. package/dist/src/planner/scopes/scope.js.map +1 -0
  550. package/dist/src/planner/stats/basic-estimates.d.ts +47 -0
  551. package/dist/src/planner/stats/basic-estimates.d.ts.map +1 -0
  552. package/dist/src/planner/stats/basic-estimates.js +99 -0
  553. package/dist/src/planner/stats/basic-estimates.js.map +1 -0
  554. package/dist/src/planner/stats/index.d.ts +88 -0
  555. package/dist/src/planner/stats/index.d.ts.map +1 -0
  556. package/dist/src/planner/stats/index.js +152 -0
  557. package/dist/src/planner/stats/index.js.map +1 -0
  558. package/dist/src/planner/type-utils.d.ts +30 -0
  559. package/dist/src/planner/type-utils.d.ts.map +1 -0
  560. package/dist/src/planner/type-utils.js +91 -0
  561. package/dist/src/planner/type-utils.js.map +1 -0
  562. package/dist/src/planner/validation/plan-validator.d.ts +29 -0
  563. package/dist/src/planner/validation/plan-validator.d.ts.map +1 -0
  564. package/dist/src/planner/validation/plan-validator.js +238 -0
  565. package/dist/src/planner/validation/plan-validator.js.map +1 -0
  566. package/dist/src/runtime/async-util.d.ts +53 -0
  567. package/dist/src/runtime/async-util.d.ts.map +1 -0
  568. package/dist/src/runtime/async-util.js +238 -0
  569. package/dist/src/runtime/async-util.js.map +1 -0
  570. package/dist/src/runtime/cache/shared-cache.d.ts +68 -0
  571. package/dist/src/runtime/cache/shared-cache.d.ts.map +1 -0
  572. package/dist/src/runtime/cache/shared-cache.js +107 -0
  573. package/dist/src/runtime/cache/shared-cache.js.map +1 -0
  574. package/dist/src/runtime/emission-context.d.ts +121 -0
  575. package/dist/src/runtime/emission-context.d.ts.map +1 -0
  576. package/dist/src/runtime/emission-context.js +258 -0
  577. package/dist/src/runtime/emission-context.js.map +1 -0
  578. package/dist/src/runtime/emit/add-constraint.d.ts +5 -0
  579. package/dist/src/runtime/emit/add-constraint.d.ts.map +1 -0
  580. package/dist/src/runtime/emit/add-constraint.js +35 -0
  581. package/dist/src/runtime/emit/add-constraint.js.map +1 -0
  582. package/dist/src/runtime/emit/aggregate.d.ts +6 -0
  583. package/dist/src/runtime/emit/aggregate.d.ts.map +1 -0
  584. package/dist/src/runtime/emit/aggregate.js +465 -0
  585. package/dist/src/runtime/emit/aggregate.js.map +1 -0
  586. package/dist/src/runtime/emit/array-index.d.ts +5 -0
  587. package/dist/src/runtime/emit/array-index.d.ts.map +1 -0
  588. package/dist/src/runtime/emit/array-index.js +20 -0
  589. package/dist/src/runtime/emit/array-index.js.map +1 -0
  590. package/dist/src/runtime/emit/binary.d.ts +11 -0
  591. package/dist/src/runtime/emit/binary.d.ts.map +1 -0
  592. package/dist/src/runtime/emit/binary.js +310 -0
  593. package/dist/src/runtime/emit/binary.js.map +1 -0
  594. package/dist/src/runtime/emit/block.d.ts +5 -0
  595. package/dist/src/runtime/emit/block.d.ts.map +1 -0
  596. package/dist/src/runtime/emit/block.js +16 -0
  597. package/dist/src/runtime/emit/block.js.map +1 -0
  598. package/dist/src/runtime/emit/cache.d.ts +25 -0
  599. package/dist/src/runtime/emit/cache.d.ts.map +1 -0
  600. package/dist/src/runtime/emit/cache.js +52 -0
  601. package/dist/src/runtime/emit/cache.js.map +1 -0
  602. package/dist/src/runtime/emit/case.d.ts +5 -0
  603. package/dist/src/runtime/emit/case.d.ts.map +1 -0
  604. package/dist/src/runtime/emit/case.js +65 -0
  605. package/dist/src/runtime/emit/case.js.map +1 -0
  606. package/dist/src/runtime/emit/cast.d.ts +5 -0
  607. package/dist/src/runtime/emit/cast.d.ts.map +1 -0
  608. package/dist/src/runtime/emit/cast.js +132 -0
  609. package/dist/src/runtime/emit/cast.js.map +1 -0
  610. package/dist/src/runtime/emit/collate.d.ts +5 -0
  611. package/dist/src/runtime/emit/collate.d.ts.map +1 -0
  612. package/dist/src/runtime/emit/collate.js +6 -0
  613. package/dist/src/runtime/emit/collate.js.map +1 -0
  614. package/dist/src/runtime/emit/column-reference.d.ts +5 -0
  615. package/dist/src/runtime/emit/column-reference.d.ts.map +1 -0
  616. package/dist/src/runtime/emit/column-reference.js +36 -0
  617. package/dist/src/runtime/emit/column-reference.js.map +1 -0
  618. package/dist/src/runtime/emit/constraint-check.d.ts +5 -0
  619. package/dist/src/runtime/emit/constraint-check.d.ts.map +1 -0
  620. package/dist/src/runtime/emit/constraint-check.js +211 -0
  621. package/dist/src/runtime/emit/constraint-check.js.map +1 -0
  622. package/dist/src/runtime/emit/create-index.d.ts +5 -0
  623. package/dist/src/runtime/emit/create-index.d.ts.map +1 -0
  624. package/dist/src/runtime/emit/create-index.js +9 -0
  625. package/dist/src/runtime/emit/create-index.js.map +1 -0
  626. package/dist/src/runtime/emit/create-table.d.ts +5 -0
  627. package/dist/src/runtime/emit/create-table.d.ts.map +1 -0
  628. package/dist/src/runtime/emit/create-table.js +9 -0
  629. package/dist/src/runtime/emit/create-table.js.map +1 -0
  630. package/dist/src/runtime/emit/create-view.d.ts +5 -0
  631. package/dist/src/runtime/emit/create-view.d.ts.map +1 -0
  632. package/dist/src/runtime/emit/create-view.js +36 -0
  633. package/dist/src/runtime/emit/create-view.js.map +1 -0
  634. package/dist/src/runtime/emit/cte-reference.d.ts +5 -0
  635. package/dist/src/runtime/emit/cte-reference.d.ts.map +1 -0
  636. package/dist/src/runtime/emit/cte-reference.js +56 -0
  637. package/dist/src/runtime/emit/cte-reference.js.map +1 -0
  638. package/dist/src/runtime/emit/cte.d.ts +5 -0
  639. package/dist/src/runtime/emit/cte.d.ts.map +1 -0
  640. package/dist/src/runtime/emit/cte.js +34 -0
  641. package/dist/src/runtime/emit/cte.js.map +1 -0
  642. package/dist/src/runtime/emit/delete.d.ts +5 -0
  643. package/dist/src/runtime/emit/delete.d.ts.map +1 -0
  644. package/dist/src/runtime/emit/delete.js +18 -0
  645. package/dist/src/runtime/emit/delete.js.map +1 -0
  646. package/dist/src/runtime/emit/distinct.d.ts +5 -0
  647. package/dist/src/runtime/emit/distinct.d.ts.map +1 -0
  648. package/dist/src/runtime/emit/distinct.js +35 -0
  649. package/dist/src/runtime/emit/distinct.js.map +1 -0
  650. package/dist/src/runtime/emit/dml-executor.d.ts +5 -0
  651. package/dist/src/runtime/emit/dml-executor.d.ts.map +1 -0
  652. package/dist/src/runtime/emit/dml-executor.js +90 -0
  653. package/dist/src/runtime/emit/dml-executor.js.map +1 -0
  654. package/dist/src/runtime/emit/drop-table.d.ts +5 -0
  655. package/dist/src/runtime/emit/drop-table.d.ts.map +1 -0
  656. package/dist/src/runtime/emit/drop-table.js +19 -0
  657. package/dist/src/runtime/emit/drop-table.js.map +1 -0
  658. package/dist/src/runtime/emit/drop-view.d.ts +5 -0
  659. package/dist/src/runtime/emit/drop-view.d.ts.map +1 -0
  660. package/dist/src/runtime/emit/drop-view.js +31 -0
  661. package/dist/src/runtime/emit/drop-view.js.map +1 -0
  662. package/dist/src/runtime/emit/filter.d.ts +5 -0
  663. package/dist/src/runtime/emit/filter.d.ts.map +1 -0
  664. package/dist/src/runtime/emit/filter.js +30 -0
  665. package/dist/src/runtime/emit/filter.js.map +1 -0
  666. package/dist/src/runtime/emit/insert.d.ts +5 -0
  667. package/dist/src/runtime/emit/insert.d.ts.map +1 -0
  668. package/dist/src/runtime/emit/insert.js +52 -0
  669. package/dist/src/runtime/emit/insert.js.map +1 -0
  670. package/dist/src/runtime/emit/join.d.ts +9 -0
  671. package/dist/src/runtime/emit/join.d.ts.map +1 -0
  672. package/dist/src/runtime/emit/join.js +116 -0
  673. package/dist/src/runtime/emit/join.js.map +1 -0
  674. package/dist/src/runtime/emit/limit-offset.d.ts +5 -0
  675. package/dist/src/runtime/emit/limit-offset.d.ts.map +1 -0
  676. package/dist/src/runtime/emit/limit-offset.js +56 -0
  677. package/dist/src/runtime/emit/limit-offset.js.map +1 -0
  678. package/dist/src/runtime/emit/literal.d.ts +5 -0
  679. package/dist/src/runtime/emit/literal.d.ts.map +1 -0
  680. package/dist/src/runtime/emit/literal.js +12 -0
  681. package/dist/src/runtime/emit/literal.js.map +1 -0
  682. package/dist/src/runtime/emit/parameter.d.ts +5 -0
  683. package/dist/src/runtime/emit/parameter.d.ts.map +1 -0
  684. package/dist/src/runtime/emit/parameter.js +57 -0
  685. package/dist/src/runtime/emit/parameter.js.map +1 -0
  686. package/dist/src/runtime/emit/pragma.d.ts +5 -0
  687. package/dist/src/runtime/emit/pragma.d.ts.map +1 -0
  688. package/dist/src/runtime/emit/pragma.js +44 -0
  689. package/dist/src/runtime/emit/pragma.js.map +1 -0
  690. package/dist/src/runtime/emit/project.d.ts +5 -0
  691. package/dist/src/runtime/emit/project.d.ts.map +1 -0
  692. package/dist/src/runtime/emit/project.js +32 -0
  693. package/dist/src/runtime/emit/project.js.map +1 -0
  694. package/dist/src/runtime/emit/recursive-cte.d.ts +5 -0
  695. package/dist/src/runtime/emit/recursive-cte.d.ts.map +1 -0
  696. package/dist/src/runtime/emit/recursive-cte.js +92 -0
  697. package/dist/src/runtime/emit/recursive-cte.js.map +1 -0
  698. package/dist/src/runtime/emit/returning.d.ts +5 -0
  699. package/dist/src/runtime/emit/returning.d.ts.map +1 -0
  700. package/dist/src/runtime/emit/returning.js +34 -0
  701. package/dist/src/runtime/emit/returning.js.map +1 -0
  702. package/dist/src/runtime/emit/scalar-function.d.ts +5 -0
  703. package/dist/src/runtime/emit/scalar-function.d.ts.map +1 -0
  704. package/dist/src/runtime/emit/scalar-function.js +29 -0
  705. package/dist/src/runtime/emit/scalar-function.js.map +1 -0
  706. package/dist/src/runtime/emit/scan.d.ts +5 -0
  707. package/dist/src/runtime/emit/scan.d.ts.map +1 -0
  708. package/dist/src/runtime/emit/scan.js +63 -0
  709. package/dist/src/runtime/emit/scan.js.map +1 -0
  710. package/dist/src/runtime/emit/sequencing.d.ts +5 -0
  711. package/dist/src/runtime/emit/sequencing.d.ts.map +1 -0
  712. package/dist/src/runtime/emit/sequencing.js +17 -0
  713. package/dist/src/runtime/emit/sequencing.js.map +1 -0
  714. package/dist/src/runtime/emit/set-operation.d.ts +5 -0
  715. package/dist/src/runtime/emit/set-operation.d.ts.map +1 -0
  716. package/dist/src/runtime/emit/set-operation.js +99 -0
  717. package/dist/src/runtime/emit/set-operation.js.map +1 -0
  718. package/dist/src/runtime/emit/sink.d.ts +5 -0
  719. package/dist/src/runtime/emit/sink.d.ts.map +1 -0
  720. package/dist/src/runtime/emit/sink.js +19 -0
  721. package/dist/src/runtime/emit/sink.js.map +1 -0
  722. package/dist/src/runtime/emit/sort.d.ts +5 -0
  723. package/dist/src/runtime/emit/sort.d.ts.map +1 -0
  724. package/dist/src/runtime/emit/sort.js +59 -0
  725. package/dist/src/runtime/emit/sort.js.map +1 -0
  726. package/dist/src/runtime/emit/subquery.d.ts +7 -0
  727. package/dist/src/runtime/emit/subquery.d.ts.map +1 -0
  728. package/dist/src/runtime/emit/subquery.js +114 -0
  729. package/dist/src/runtime/emit/subquery.js.map +1 -0
  730. package/dist/src/runtime/emit/table-reference.d.ts +5 -0
  731. package/dist/src/runtime/emit/table-reference.d.ts.map +1 -0
  732. package/dist/src/runtime/emit/table-reference.js +67 -0
  733. package/dist/src/runtime/emit/table-reference.js.map +1 -0
  734. package/dist/src/runtime/emit/table-valued-function.d.ts +5 -0
  735. package/dist/src/runtime/emit/table-valued-function.d.ts.map +1 -0
  736. package/dist/src/runtime/emit/table-valued-function.js +98 -0
  737. package/dist/src/runtime/emit/table-valued-function.js.map +1 -0
  738. package/dist/src/runtime/emit/transaction.d.ts +5 -0
  739. package/dist/src/runtime/emit/transaction.d.ts.map +1 -0
  740. package/dist/src/runtime/emit/transaction.js +153 -0
  741. package/dist/src/runtime/emit/transaction.js.map +1 -0
  742. package/dist/src/runtime/emit/unary.d.ts +5 -0
  743. package/dist/src/runtime/emit/unary.d.ts.map +1 -0
  744. package/dist/src/runtime/emit/unary.js +81 -0
  745. package/dist/src/runtime/emit/unary.js.map +1 -0
  746. package/dist/src/runtime/emit/update-executor.d.ts +5 -0
  747. package/dist/src/runtime/emit/update-executor.d.ts.map +1 -0
  748. package/dist/src/runtime/emit/update-executor.js +54 -0
  749. package/dist/src/runtime/emit/update-executor.js.map +1 -0
  750. package/dist/src/runtime/emit/update.d.ts +5 -0
  751. package/dist/src/runtime/emit/update.d.ts.map +1 -0
  752. package/dist/src/runtime/emit/update.js +58 -0
  753. package/dist/src/runtime/emit/update.js.map +1 -0
  754. package/dist/src/runtime/emit/values.d.ts +9 -0
  755. package/dist/src/runtime/emit/values.d.ts.map +1 -0
  756. package/dist/src/runtime/emit/values.js +51 -0
  757. package/dist/src/runtime/emit/values.js.map +1 -0
  758. package/dist/src/runtime/emit/window-function.d.ts +5 -0
  759. package/dist/src/runtime/emit/window-function.d.ts.map +1 -0
  760. package/dist/src/runtime/emit/window-function.js +31 -0
  761. package/dist/src/runtime/emit/window-function.js.map +1 -0
  762. package/dist/src/runtime/emit/window.d.ts +5 -0
  763. package/dist/src/runtime/emit/window.d.ts.map +1 -0
  764. package/dist/src/runtime/emit/window.js +328 -0
  765. package/dist/src/runtime/emit/window.js.map +1 -0
  766. package/dist/src/runtime/emitters.d.ts +48 -0
  767. package/dist/src/runtime/emitters.d.ts.map +1 -0
  768. package/dist/src/runtime/emitters.js +73 -0
  769. package/dist/src/runtime/emitters.js.map +1 -0
  770. package/dist/src/runtime/register.d.ts +2 -0
  771. package/dist/src/runtime/register.d.ts.map +1 -0
  772. package/dist/src/runtime/register.js +122 -0
  773. package/dist/src/runtime/register.js.map +1 -0
  774. package/dist/src/runtime/scheduler.d.ts +27 -0
  775. package/dist/src/runtime/scheduler.d.ts.map +1 -0
  776. package/dist/src/runtime/scheduler.js +385 -0
  777. package/dist/src/runtime/scheduler.js.map +1 -0
  778. package/dist/src/runtime/types.d.ts +109 -0
  779. package/dist/src/runtime/types.d.ts.map +1 -0
  780. package/dist/src/runtime/types.js +90 -0
  781. package/dist/src/runtime/types.js.map +1 -0
  782. package/dist/src/runtime/utils.d.ts +32 -0
  783. package/dist/src/runtime/utils.d.ts.map +1 -0
  784. package/dist/src/runtime/utils.js +117 -0
  785. package/dist/src/runtime/utils.js.map +1 -0
  786. package/dist/src/schema/change-events.d.ts +42 -0
  787. package/dist/src/schema/change-events.d.ts.map +1 -0
  788. package/dist/src/schema/change-events.js +55 -0
  789. package/dist/src/schema/change-events.js.map +1 -0
  790. package/dist/src/schema/column.d.ts +33 -0
  791. package/dist/src/schema/column.d.ts.map +1 -0
  792. package/dist/src/schema/column.js +22 -0
  793. package/dist/src/schema/column.js.map +1 -0
  794. package/dist/src/schema/function.d.ts +109 -0
  795. package/dist/src/schema/function.d.ts.map +1 -0
  796. package/dist/src/schema/function.js +26 -0
  797. package/dist/src/schema/function.js.map +1 -0
  798. package/dist/src/schema/manager.d.ts +222 -0
  799. package/dist/src/schema/manager.d.ts.map +1 -0
  800. package/dist/src/schema/manager.js +608 -0
  801. package/dist/src/schema/manager.js.map +1 -0
  802. package/dist/src/schema/schema.d.ts +110 -0
  803. package/dist/src/schema/schema.d.ts.map +1 -0
  804. package/dist/src/schema/schema.js +179 -0
  805. package/dist/src/schema/schema.js.map +1 -0
  806. package/dist/src/schema/table.d.ts +143 -0
  807. package/dist/src/schema/table.d.ts.map +1 -0
  808. package/dist/src/schema/table.js +245 -0
  809. package/dist/src/schema/table.js.map +1 -0
  810. package/dist/src/schema/view.d.ts +18 -0
  811. package/dist/src/schema/view.d.ts.map +1 -0
  812. package/dist/src/schema/view.js +2 -0
  813. package/dist/src/schema/view.js.map +1 -0
  814. package/dist/src/schema/window-function.d.ts +26 -0
  815. package/dist/src/schema/window-function.d.ts.map +1 -0
  816. package/dist/src/schema/window-function.js +34 -0
  817. package/dist/src/schema/window-function.js.map +1 -0
  818. package/dist/src/util/affinity.d.ts +34 -0
  819. package/dist/src/util/affinity.d.ts.map +1 -0
  820. package/dist/src/util/affinity.js +153 -0
  821. package/dist/src/util/affinity.js.map +1 -0
  822. package/dist/src/util/ast-stringify.d.ts +23 -0
  823. package/dist/src/util/ast-stringify.d.ts.map +1 -0
  824. package/dist/src/util/ast-stringify.js +683 -0
  825. package/dist/src/util/ast-stringify.js.map +1 -0
  826. package/dist/src/util/cached.d.ts +11 -0
  827. package/dist/src/util/cached.d.ts.map +1 -0
  828. package/dist/src/util/cached.js +24 -0
  829. package/dist/src/util/cached.js.map +1 -0
  830. package/dist/src/util/coercion.d.ts +34 -0
  831. package/dist/src/util/coercion.d.ts.map +1 -0
  832. package/dist/src/util/coercion.js +106 -0
  833. package/dist/src/util/coercion.js.map +1 -0
  834. package/dist/src/util/comparison.d.ts +153 -0
  835. package/dist/src/util/comparison.d.ts.map +1 -0
  836. package/dist/src/util/comparison.js +397 -0
  837. package/dist/src/util/comparison.js.map +1 -0
  838. package/dist/src/util/environment.d.ts +28 -0
  839. package/dist/src/util/environment.d.ts.map +1 -0
  840. package/dist/src/util/environment.js +47 -0
  841. package/dist/src/util/environment.js.map +1 -0
  842. package/dist/src/util/latches.d.ts +16 -0
  843. package/dist/src/util/latches.d.ts.map +1 -0
  844. package/dist/src/util/latches.js +41 -0
  845. package/dist/src/util/latches.js.map +1 -0
  846. package/dist/src/util/patterns.d.ts +23 -0
  847. package/dist/src/util/patterns.d.ts.map +1 -0
  848. package/dist/src/util/patterns.js +54 -0
  849. package/dist/src/util/patterns.js.map +1 -0
  850. package/dist/src/util/plan-formatter.d.ts +23 -0
  851. package/dist/src/util/plan-formatter.d.ts.map +1 -0
  852. package/dist/src/util/plan-formatter.js +41 -0
  853. package/dist/src/util/plan-formatter.js.map +1 -0
  854. package/dist/src/util/plugin-loader.d.ts +20 -0
  855. package/dist/src/util/plugin-loader.d.ts.map +1 -0
  856. package/dist/src/util/plugin-loader.js +57 -0
  857. package/dist/src/util/plugin-loader.js.map +1 -0
  858. package/dist/src/util/row-descriptor.d.ts +35 -0
  859. package/dist/src/util/row-descriptor.d.ts.map +1 -0
  860. package/dist/src/util/row-descriptor.js +85 -0
  861. package/dist/src/util/row-descriptor.js.map +1 -0
  862. package/dist/src/util/serialization.d.ts +11 -0
  863. package/dist/src/util/serialization.d.ts.map +1 -0
  864. package/dist/src/util/serialization.js +41 -0
  865. package/dist/src/util/serialization.js.map +1 -0
  866. package/dist/src/util/working-table-iterable.d.ts +17 -0
  867. package/dist/src/util/working-table-iterable.d.ts.map +1 -0
  868. package/dist/src/util/working-table-iterable.js +30 -0
  869. package/dist/src/util/working-table-iterable.js.map +1 -0
  870. package/dist/src/vtab/best-access-plan.d.ts +144 -0
  871. package/dist/src/vtab/best-access-plan.d.ts.map +1 -0
  872. package/dist/src/vtab/best-access-plan.js +156 -0
  873. package/dist/src/vtab/best-access-plan.js.map +1 -0
  874. package/dist/src/vtab/connection.d.ts +27 -0
  875. package/dist/src/vtab/connection.d.ts.map +1 -0
  876. package/dist/src/vtab/connection.js +2 -0
  877. package/dist/src/vtab/connection.js.map +1 -0
  878. package/dist/src/vtab/filter-info.d.ts +26 -0
  879. package/dist/src/vtab/filter-info.d.ts.map +1 -0
  880. package/dist/src/vtab/filter-info.js +2 -0
  881. package/dist/src/vtab/filter-info.js.map +1 -0
  882. package/dist/src/vtab/index-info.d.ts +69 -0
  883. package/dist/src/vtab/index-info.d.ts.map +1 -0
  884. package/dist/src/vtab/index-info.js +7 -0
  885. package/dist/src/vtab/index-info.js.map +1 -0
  886. package/dist/src/vtab/manifest.d.ts +35 -0
  887. package/dist/src/vtab/manifest.d.ts.map +1 -0
  888. package/dist/src/vtab/manifest.js +2 -0
  889. package/dist/src/vtab/manifest.js.map +1 -0
  890. package/dist/src/vtab/memory/connection.d.ts +29 -0
  891. package/dist/src/vtab/memory/connection.d.ts.map +1 -0
  892. package/dist/src/vtab/memory/connection.js +61 -0
  893. package/dist/src/vtab/memory/connection.js.map +1 -0
  894. package/dist/src/vtab/memory/index.d.ts +38 -0
  895. package/dist/src/vtab/memory/index.d.ts.map +1 -0
  896. package/dist/src/vtab/memory/index.js +132 -0
  897. package/dist/src/vtab/memory/index.js.map +1 -0
  898. package/dist/src/vtab/memory/layer/base-cursor.d.ts +5 -0
  899. package/dist/src/vtab/memory/layer/base-cursor.d.ts.map +1 -0
  900. package/dist/src/vtab/memory/layer/base-cursor.js +111 -0
  901. package/dist/src/vtab/memory/layer/base-cursor.js.map +1 -0
  902. package/dist/src/vtab/memory/layer/base.d.ts +51 -0
  903. package/dist/src/vtab/memory/layer/base.d.ts.map +1 -0
  904. package/dist/src/vtab/memory/layer/base.js +199 -0
  905. package/dist/src/vtab/memory/layer/base.js.map +1 -0
  906. package/dist/src/vtab/memory/layer/connection.d.ts +38 -0
  907. package/dist/src/vtab/memory/layer/connection.d.ts.map +1 -0
  908. package/dist/src/vtab/memory/layer/connection.js +170 -0
  909. package/dist/src/vtab/memory/layer/connection.js.map +1 -0
  910. package/dist/src/vtab/memory/layer/interface.d.ts +41 -0
  911. package/dist/src/vtab/memory/layer/interface.d.ts.map +1 -0
  912. package/dist/src/vtab/memory/layer/interface.js +2 -0
  913. package/dist/src/vtab/memory/layer/interface.js.map +1 -0
  914. package/dist/src/vtab/memory/layer/manager.d.ts +68 -0
  915. package/dist/src/vtab/memory/layer/manager.d.ts.map +1 -0
  916. package/dist/src/vtab/memory/layer/manager.js +752 -0
  917. package/dist/src/vtab/memory/layer/manager.js.map +1 -0
  918. package/dist/src/vtab/memory/layer/safe-iterate.d.ts +9 -0
  919. package/dist/src/vtab/memory/layer/safe-iterate.d.ts.map +1 -0
  920. package/dist/src/vtab/memory/layer/safe-iterate.js +47 -0
  921. package/dist/src/vtab/memory/layer/safe-iterate.js.map +1 -0
  922. package/dist/src/vtab/memory/layer/scan-plan.d.ts +37 -0
  923. package/dist/src/vtab/memory/layer/scan-plan.d.ts.map +1 -0
  924. package/dist/src/vtab/memory/layer/scan-plan.js +87 -0
  925. package/dist/src/vtab/memory/layer/scan-plan.js.map +1 -0
  926. package/dist/src/vtab/memory/layer/transaction-cursor.d.ts +5 -0
  927. package/dist/src/vtab/memory/layer/transaction-cursor.d.ts.map +1 -0
  928. package/dist/src/vtab/memory/layer/transaction-cursor.js +149 -0
  929. package/dist/src/vtab/memory/layer/transaction-cursor.js.map +1 -0
  930. package/dist/src/vtab/memory/layer/transaction.d.ts +44 -0
  931. package/dist/src/vtab/memory/layer/transaction.d.ts.map +1 -0
  932. package/dist/src/vtab/memory/layer/transaction.js +183 -0
  933. package/dist/src/vtab/memory/layer/transaction.js.map +1 -0
  934. package/dist/src/vtab/memory/module.d.ts +89 -0
  935. package/dist/src/vtab/memory/module.d.ts.map +1 -0
  936. package/dist/src/vtab/memory/module.js +533 -0
  937. package/dist/src/vtab/memory/module.js.map +1 -0
  938. package/dist/src/vtab/memory/table.d.ts +49 -0
  939. package/dist/src/vtab/memory/table.d.ts.map +1 -0
  940. package/dist/src/vtab/memory/table.js +209 -0
  941. package/dist/src/vtab/memory/table.js.map +1 -0
  942. package/dist/src/vtab/memory/types.d.ts +19 -0
  943. package/dist/src/vtab/memory/types.d.ts.map +1 -0
  944. package/dist/src/vtab/memory/types.js +2 -0
  945. package/dist/src/vtab/memory/types.js.map +1 -0
  946. package/dist/src/vtab/memory/utils/logging.d.ts +13 -0
  947. package/dist/src/vtab/memory/utils/logging.d.ts.map +1 -0
  948. package/dist/src/vtab/memory/utils/logging.js +28 -0
  949. package/dist/src/vtab/memory/utils/logging.js.map +1 -0
  950. package/dist/src/vtab/memory/utils/primary-key.d.ts +21 -0
  951. package/dist/src/vtab/memory/utils/primary-key.d.ts.map +1 -0
  952. package/dist/src/vtab/memory/utils/primary-key.js +107 -0
  953. package/dist/src/vtab/memory/utils/primary-key.js.map +1 -0
  954. package/dist/src/vtab/module.d.ts +111 -0
  955. package/dist/src/vtab/module.d.ts.map +1 -0
  956. package/dist/src/vtab/module.js +2 -0
  957. package/dist/src/vtab/module.js.map +1 -0
  958. package/dist/src/vtab/table.d.ts +114 -0
  959. package/dist/src/vtab/table.d.ts.map +1 -0
  960. package/dist/src/vtab/table.js +26 -0
  961. package/dist/src/vtab/table.js.map +1 -0
  962. package/package.json +61 -0
  963. package/src/common/constants.ts +60 -0
  964. package/src/common/datatype.ts +86 -0
  965. package/src/common/errors.ts +189 -0
  966. package/src/common/logger.ts +23 -0
  967. package/src/common/type-inference.ts +40 -0
  968. package/src/common/types.ts +148 -0
  969. package/src/core/database-options.ts +258 -0
  970. package/src/core/database.ts +875 -0
  971. package/src/core/param.ts +41 -0
  972. package/src/core/statement.ts +490 -0
  973. package/src/func/builtins/aggregate.ts +247 -0
  974. package/src/func/builtins/builtin-window-functions.ts +165 -0
  975. package/src/func/builtins/datetime.ts +453 -0
  976. package/src/func/builtins/explain.ts +648 -0
  977. package/src/func/builtins/generation.ts +43 -0
  978. package/src/func/builtins/index.ts +126 -0
  979. package/src/func/builtins/json-helpers.ts +237 -0
  980. package/src/func/builtins/json-tvf.ts +225 -0
  981. package/src/func/builtins/json.ts +466 -0
  982. package/src/func/builtins/scalar.ts +232 -0
  983. package/src/func/builtins/schema.ts +193 -0
  984. package/src/func/builtins/string.ts +293 -0
  985. package/src/func/context.ts +251 -0
  986. package/src/func/registration.ts +167 -0
  987. package/src/index.ts +67 -0
  988. package/src/parser/ast.ts +475 -0
  989. package/src/parser/index.ts +65 -0
  990. package/src/parser/lexer.ts +767 -0
  991. package/src/parser/parser.ts +2783 -0
  992. package/src/parser/utils.ts +10 -0
  993. package/src/parser/visitor.ts +187 -0
  994. package/src/planner/analysis/README.md +93 -0
  995. package/src/planner/analysis/const-evaluator.ts +63 -0
  996. package/src/planner/analysis/const-pass.ts +270 -0
  997. package/src/planner/analysis/constraint-extractor.ts +277 -0
  998. package/src/planner/building/alter-table.ts +47 -0
  999. package/src/planner/building/block.ts +78 -0
  1000. package/src/planner/building/create-view.ts +56 -0
  1001. package/src/planner/building/ddl.ts +24 -0
  1002. package/src/planner/building/delete.ts +158 -0
  1003. package/src/planner/building/drop-table.ts +13 -0
  1004. package/src/planner/building/drop-view.ts +19 -0
  1005. package/src/planner/building/expression.ts +176 -0
  1006. package/src/planner/building/function-call.ts +87 -0
  1007. package/src/planner/building/insert.ts +336 -0
  1008. package/src/planner/building/pragma.ts +33 -0
  1009. package/src/planner/building/schema-resolution.ts +176 -0
  1010. package/src/planner/building/select-aggregates.ts +245 -0
  1011. package/src/planner/building/select-compound.ts +110 -0
  1012. package/src/planner/building/select-context.ts +75 -0
  1013. package/src/planner/building/select-modifiers.ts +170 -0
  1014. package/src/planner/building/select-projections.ts +177 -0
  1015. package/src/planner/building/select-window.ts +248 -0
  1016. package/src/planner/building/select.ts +388 -0
  1017. package/src/planner/building/table-function.ts +48 -0
  1018. package/src/planner/building/table.ts +73 -0
  1019. package/src/planner/building/transaction.ts +23 -0
  1020. package/src/planner/building/update.ts +255 -0
  1021. package/src/planner/building/with.ts +181 -0
  1022. package/src/planner/cache/materialization-advisory.ts +244 -0
  1023. package/src/planner/cache/reference-graph.ts +172 -0
  1024. package/src/planner/cost/index.ts +169 -0
  1025. package/src/planner/debug/logger-utils.ts +68 -0
  1026. package/src/planner/debug.ts +316 -0
  1027. package/src/planner/framework/README.md +132 -0
  1028. package/src/planner/framework/context.ts +188 -0
  1029. package/src/planner/framework/physical-utils.ts +210 -0
  1030. package/src/planner/framework/registry.ts +274 -0
  1031. package/src/planner/framework/trace.ts +259 -0
  1032. package/src/planner/nodes/add-constraint-node.ts +58 -0
  1033. package/src/planner/nodes/aggregate-function.ts +145 -0
  1034. package/src/planner/nodes/aggregate-node.ts +220 -0
  1035. package/src/planner/nodes/array-index-node.ts +50 -0
  1036. package/src/planner/nodes/block.ts +80 -0
  1037. package/src/planner/nodes/cache-node.ts +94 -0
  1038. package/src/planner/nodes/constraint-check-node.ts +95 -0
  1039. package/src/planner/nodes/create-index-node.ts +37 -0
  1040. package/src/planner/nodes/create-table-node.ts +31 -0
  1041. package/src/planner/nodes/create-view-node.ts +40 -0
  1042. package/src/planner/nodes/cte-node.ts +111 -0
  1043. package/src/planner/nodes/cte-reference-node.ts +89 -0
  1044. package/src/planner/nodes/delete-node.ts +72 -0
  1045. package/src/planner/nodes/distinct-node.ts +93 -0
  1046. package/src/planner/nodes/dml-executor-node.ts +98 -0
  1047. package/src/planner/nodes/drop-table-node.ts +31 -0
  1048. package/src/planner/nodes/drop-view-node.ts +33 -0
  1049. package/src/planner/nodes/filter.ts +91 -0
  1050. package/src/planner/nodes/function.ts +93 -0
  1051. package/src/planner/nodes/insert-node.ts +97 -0
  1052. package/src/planner/nodes/join-node.ts +213 -0
  1053. package/src/planner/nodes/limit-offset.ts +125 -0
  1054. package/src/planner/nodes/physical-access-nodes.ts +298 -0
  1055. package/src/planner/nodes/plan-node-type.ts +87 -0
  1056. package/src/planner/nodes/plan-node.ts +466 -0
  1057. package/src/planner/nodes/pragma.ts +94 -0
  1058. package/src/planner/nodes/project-node.ts +223 -0
  1059. package/src/planner/nodes/recursive-cte-node.ts +130 -0
  1060. package/src/planner/nodes/reference.ts +310 -0
  1061. package/src/planner/nodes/returning-node.ts +215 -0
  1062. package/src/planner/nodes/scalar.ts +736 -0
  1063. package/src/planner/nodes/scan.ts +103 -0
  1064. package/src/planner/nodes/sequencing-node.ts +113 -0
  1065. package/src/planner/nodes/set-operation-node.ts +87 -0
  1066. package/src/planner/nodes/single-row.ts +80 -0
  1067. package/src/planner/nodes/sink-node.ts +61 -0
  1068. package/src/planner/nodes/sort.ts +137 -0
  1069. package/src/planner/nodes/stream-aggregate.ts +225 -0
  1070. package/src/planner/nodes/subquery.ts +207 -0
  1071. package/src/planner/nodes/table-function-call.ts +127 -0
  1072. package/src/planner/nodes/transaction-node.ts +61 -0
  1073. package/src/planner/nodes/update-node.ts +114 -0
  1074. package/src/planner/nodes/values-node.ts +244 -0
  1075. package/src/planner/nodes/view-reference-node.ts +97 -0
  1076. package/src/planner/nodes/window-function.ts +73 -0
  1077. package/src/planner/nodes/window-node.ts +193 -0
  1078. package/src/planner/optimizer-tuning.ts +87 -0
  1079. package/src/planner/optimizer.ts +263 -0
  1080. package/src/planner/planning-context.ts +168 -0
  1081. package/src/planner/resolve.ts +100 -0
  1082. package/src/planner/rules/README.md +96 -0
  1083. package/src/planner/rules/access/rule-select-access-path.ts +180 -0
  1084. package/src/planner/rules/aggregate/rule-aggregate-streaming.ts +76 -0
  1085. package/src/planner/rules/cache/rule-cte-optimization.ts +66 -0
  1086. package/src/planner/rules/cache/rule-materialization-advisory.ts +66 -0
  1087. package/src/planner/rules/cache/rule-mutating-subquery-cache.ts +110 -0
  1088. package/src/planner/rules/physical/rule-mark-physical.ts +37 -0
  1089. package/src/planner/scopes/aliased.ts +50 -0
  1090. package/src/planner/scopes/base.ts +27 -0
  1091. package/src/planner/scopes/empty.ts +22 -0
  1092. package/src/planner/scopes/global.ts +73 -0
  1093. package/src/planner/scopes/multi.ts +41 -0
  1094. package/src/planner/scopes/param.ts +96 -0
  1095. package/src/planner/scopes/registered.ts +78 -0
  1096. package/src/planner/scopes/scope.ts +28 -0
  1097. package/src/planner/stats/basic-estimates.ts +107 -0
  1098. package/src/planner/stats/index.ts +223 -0
  1099. package/src/planner/type-utils.ts +95 -0
  1100. package/src/planner/validation/plan-validator.ts +340 -0
  1101. package/src/runtime/async-util.ts +282 -0
  1102. package/src/runtime/cache/shared-cache.ts +169 -0
  1103. package/src/runtime/emission-context.ts +310 -0
  1104. package/src/runtime/emit/add-constraint.ts +54 -0
  1105. package/src/runtime/emit/aggregate.ts +533 -0
  1106. package/src/runtime/emit/array-index.ts +25 -0
  1107. package/src/runtime/emit/binary.ts +335 -0
  1108. package/src/runtime/emit/block.ts +23 -0
  1109. package/src/runtime/emit/cache.ts +64 -0
  1110. package/src/runtime/emit/case.ts +87 -0
  1111. package/src/runtime/emit/cast.ts +151 -0
  1112. package/src/runtime/emit/collate.ts +9 -0
  1113. package/src/runtime/emit/column-reference.ts +50 -0
  1114. package/src/runtime/emit/constraint-check.ts +285 -0
  1115. package/src/runtime/emit/create-index.ts +15 -0
  1116. package/src/runtime/emit/create-table.ts +15 -0
  1117. package/src/runtime/emit/create-view.ts +52 -0
  1118. package/src/runtime/emit/cte-reference.ts +75 -0
  1119. package/src/runtime/emit/cte.ts +39 -0
  1120. package/src/runtime/emit/delete.ts +24 -0
  1121. package/src/runtime/emit/distinct.ts +45 -0
  1122. package/src/runtime/emit/dml-executor.ts +94 -0
  1123. package/src/runtime/emit/drop-table.ts +27 -0
  1124. package/src/runtime/emit/drop-view.ts +49 -0
  1125. package/src/runtime/emit/filter.ts +37 -0
  1126. package/src/runtime/emit/insert.ts +54 -0
  1127. package/src/runtime/emit/join.ts +145 -0
  1128. package/src/runtime/emit/limit-offset.ts +73 -0
  1129. package/src/runtime/emit/literal.ts +17 -0
  1130. package/src/runtime/emit/parameter.ts +59 -0
  1131. package/src/runtime/emit/pragma.ts +56 -0
  1132. package/src/runtime/emit/project.ts +40 -0
  1133. package/src/runtime/emit/recursive-cte.ts +120 -0
  1134. package/src/runtime/emit/returning.ts +48 -0
  1135. package/src/runtime/emit/scalar-function.ts +43 -0
  1136. package/src/runtime/emit/scan.ts +88 -0
  1137. package/src/runtime/emit/sequencing.ts +24 -0
  1138. package/src/runtime/emit/set-operation.ts +111 -0
  1139. package/src/runtime/emit/sink.ts +27 -0
  1140. package/src/runtime/emit/sort.ts +78 -0
  1141. package/src/runtime/emit/subquery.ts +143 -0
  1142. package/src/runtime/emit/table-reference.ts +92 -0
  1143. package/src/runtime/emit/table-valued-function.ts +119 -0
  1144. package/src/runtime/emit/transaction.ts +167 -0
  1145. package/src/runtime/emit/unary.ts +85 -0
  1146. package/src/runtime/emit/update.ts +73 -0
  1147. package/src/runtime/emit/values.ts +66 -0
  1148. package/src/runtime/emit/window-function.ts +42 -0
  1149. package/src/runtime/emit/window.ts +472 -0
  1150. package/src/runtime/emitters.ts +130 -0
  1151. package/src/runtime/register.ts +134 -0
  1152. package/src/runtime/scheduler.ts +488 -0
  1153. package/src/runtime/types.ts +191 -0
  1154. package/src/runtime/utils.ts +136 -0
  1155. package/src/schema/change-events.ts +80 -0
  1156. package/src/schema/column.ts +45 -0
  1157. package/src/schema/function.ts +139 -0
  1158. package/src/schema/manager.ts +694 -0
  1159. package/src/schema/schema.ts +199 -0
  1160. package/src/schema/table.ts +364 -0
  1161. package/src/schema/view.ts +19 -0
  1162. package/src/schema/window-function.ts +54 -0
  1163. package/src/util/affinity.ts +151 -0
  1164. package/src/util/ast-stringify.ts +764 -0
  1165. package/src/util/cached.ts +25 -0
  1166. package/src/util/coercion.ts +113 -0
  1167. package/src/util/comparison.ts +437 -0
  1168. package/src/util/environment.ts +52 -0
  1169. package/src/util/latches.ts +47 -0
  1170. package/src/util/patterns.ts +56 -0
  1171. package/src/util/plan-formatter.ts +51 -0
  1172. package/src/util/plugin-loader.ts +69 -0
  1173. package/src/util/row-descriptor.ts +105 -0
  1174. package/src/util/serialization.ts +45 -0
  1175. package/src/util/working-table-iterable.ts +30 -0
  1176. package/src/vtab/best-access-plan.ts +270 -0
  1177. package/src/vtab/connection.ts +36 -0
  1178. package/src/vtab/filter-info.ts +23 -0
  1179. package/src/vtab/index-info.ts +84 -0
  1180. package/src/vtab/manifest.ts +37 -0
  1181. package/src/vtab/memory/connection.ts +73 -0
  1182. package/src/vtab/memory/index.ts +178 -0
  1183. package/src/vtab/memory/layer/base-cursor.ts +124 -0
  1184. package/src/vtab/memory/layer/base.ts +273 -0
  1185. package/src/vtab/memory/layer/connection.ts +203 -0
  1186. package/src/vtab/memory/layer/interface.ts +47 -0
  1187. package/src/vtab/memory/layer/manager.ts +861 -0
  1188. package/src/vtab/memory/layer/safe-iterate.ts +49 -0
  1189. package/src/vtab/memory/layer/scan-plan.ts +84 -0
  1190. package/src/vtab/memory/layer/transaction-cursor.ts +162 -0
  1191. package/src/vtab/memory/layer/transaction.ts +229 -0
  1192. package/src/vtab/memory/module.ts +673 -0
  1193. package/src/vtab/memory/table.ts +253 -0
  1194. package/src/vtab/memory/types.ts +23 -0
  1195. package/src/vtab/memory/utils/logging.ts +33 -0
  1196. package/src/vtab/memory/utils/primary-key.ts +158 -0
  1197. package/src/vtab/module.ts +140 -0
  1198. package/src/vtab/table.ts +143 -0
@@ -0,0 +1,2619 @@
1
+ import { createLogger } from '../common/logger.js'; // Import logger
2
+ import { Lexer, TokenType } from './lexer.js';
3
+ import { ConflictResolution } from '../common/constants.js';
4
+ import { quereusError } from '../common/errors.js';
5
+ import { StatusCode } from '../common/types.js';
6
+ import { getSyncLiteral } from './utils.js';
7
+ const log = createLogger('parser:parser'); // Create logger instance
8
+ const errorLog = log.extend('error');
9
+ export class ParseError extends Error {
10
+ token;
11
+ constructor(token, message) {
12
+ super(message);
13
+ this.token = token;
14
+ this.name = 'ParseError';
15
+ }
16
+ }
17
+ // Helper function to create the location object
18
+ function _createLoc(startToken, endToken) {
19
+ return {
20
+ start: {
21
+ line: startToken.startLine,
22
+ column: startToken.startColumn,
23
+ offset: startToken.startOffset,
24
+ },
25
+ end: {
26
+ line: endToken.endLine,
27
+ column: endToken.endColumn,
28
+ offset: endToken.endOffset,
29
+ },
30
+ };
31
+ }
32
+ export class Parser {
33
+ tokens = [];
34
+ current = 0;
35
+ // Counter for positional parameters
36
+ parameterPosition = 1;
37
+ /**
38
+ * Initialize the parser with tokens from a SQL string
39
+ * @param sql SQL string to parse
40
+ * @returns this parser instance for chaining
41
+ */
42
+ initialize(sql) {
43
+ const lexer = new Lexer(sql);
44
+ this.tokens = lexer.scanTokens();
45
+ this.current = 0;
46
+ this.parameterPosition = 1; // Reset parameter counter
47
+ // Check for errors from lexer
48
+ const errorToken = this.tokens.find(t => t.type === TokenType.ERROR);
49
+ if (errorToken) {
50
+ quereusError(`Lexer error: ${errorToken.lexeme}`, StatusCode.ERROR, undefined, {
51
+ loc: {
52
+ start: {
53
+ line: errorToken.startLine,
54
+ column: errorToken.startColumn,
55
+ },
56
+ end: {
57
+ line: errorToken.endLine,
58
+ column: errorToken.endColumn,
59
+ }
60
+ }
61
+ });
62
+ }
63
+ return this;
64
+ }
65
+ /**
66
+ * Parse SQL text into an array of ASTs
67
+ */
68
+ parseAll(sql) {
69
+ this.initialize(sql);
70
+ const statements = [];
71
+ while (!this.isAtEnd()) {
72
+ try {
73
+ const stmt = this.statement();
74
+ statements.push(stmt); // Cast needed as statement() returns AstNode
75
+ // Consume optional semicolon at the end of the statement
76
+ this.match(TokenType.SEMICOLON);
77
+ }
78
+ catch (e) {
79
+ // error() method now throws QuereusError directly with location info
80
+ if (e instanceof Error && e.name === 'QuereusError') {
81
+ throw e;
82
+ }
83
+ // Handle unexpected non-QuereusError exceptions
84
+ errorLog("Unhandled parser error: %O", e);
85
+ quereusError(`Parser error: ${e instanceof Error ? e.message : e}`, StatusCode.ERROR, e instanceof Error ? e : undefined);
86
+ }
87
+ }
88
+ // If we consumed all tokens and didn't parse any statements (e.g., empty input or only comments/whitespace),
89
+ // return an empty array instead of throwing an error.
90
+ return statements;
91
+ }
92
+ /**
93
+ * Parse SQL text into a single AST node.
94
+ * Use parseAll instead for potentially multi-statement strings.
95
+ * Throws error if more than one statement is found after the first.
96
+ */
97
+ parse(sql) {
98
+ const statements = this.parseAll(sql);
99
+ if (statements.length === 0) {
100
+ // Handle case of empty input or input with only comments/whitespace
101
+ // Depending on desired behavior, could return null, undefined, or throw.
102
+ // Throwing seems reasonable as prepare/eval expect a statement.
103
+ quereusError("No SQL statement found to parse.", StatusCode.ERROR);
104
+ }
105
+ if (statements.length > 1) {
106
+ // Find the token that starts the second statement for better error location
107
+ const secondStatementStartToken = statements[1]?.loc?.start;
108
+ const errToken = this.tokens.find(t => t.startOffset === secondStatementStartToken?.offset) ?? this.peek();
109
+ this.error(errToken, "Provided SQL string contains multiple statements. Use exec() for multi-statement execution.");
110
+ }
111
+ return statements[0];
112
+ }
113
+ /**
114
+ * Attempts to parse a WITH clause if present.
115
+ * @returns The WithClause AST node or undefined if no WITH clause is found.
116
+ */
117
+ tryParseWithClause() {
118
+ if (!this.check(TokenType.WITH)) {
119
+ return undefined;
120
+ }
121
+ const startToken = this.advance(); // Consume WITH
122
+ const recursive = this.match(TokenType.RECURSIVE);
123
+ const ctes = [];
124
+ do {
125
+ ctes.push(this.commonTableExpression());
126
+ } while (this.match(TokenType.COMMA));
127
+ // Parse optional OPTION clause
128
+ let options;
129
+ if (this.matchKeyword('OPTION')) {
130
+ this.consume(TokenType.LPAREN, "Expected '(' after OPTION.");
131
+ // Parse MAXRECURSION option
132
+ if (this.matchKeyword('MAXRECURSION')) {
133
+ if (!this.check(TokenType.INTEGER)) {
134
+ this.error(this.peek(), "Expected integer value after MAXRECURSION.");
135
+ }
136
+ const maxRecursionToken = this.advance();
137
+ const maxRecursion = maxRecursionToken.literal;
138
+ if (maxRecursion < 0) {
139
+ this.error(maxRecursionToken, "MAXRECURSION value must be non-negative.");
140
+ }
141
+ options = { maxRecursion };
142
+ }
143
+ else {
144
+ throw this.error(this.peek(), "Expected MAXRECURSION in OPTION clause.");
145
+ }
146
+ this.consume(TokenType.RPAREN, "Expected ')' after OPTION clause.");
147
+ }
148
+ const endToken = this.previous(); // Last token of the WITH clause
149
+ return { type: 'with', recursive, ctes, options, loc: _createLoc(startToken, endToken) };
150
+ }
151
+ /**
152
+ * Parses a single Common Table Expression (CTE).
153
+ * cte_name [(col1, col2, ...)] AS (query)
154
+ */
155
+ commonTableExpression() {
156
+ const startToken = this.peek(); // Peek before consuming name
157
+ const name = this.consumeIdentifier(['key', 'action', 'set', 'default', 'check', 'unique', 'like'], "Expected CTE name.");
158
+ let endToken = this.previous(); // End token initially is the name
159
+ let columns;
160
+ if (this.match(TokenType.LPAREN)) {
161
+ columns = [];
162
+ if (!this.check(TokenType.RPAREN)) {
163
+ do {
164
+ columns.push(this.consumeIdentifier(['key', 'action', 'set', 'default', 'check', 'unique', 'like'], "Expected column name in CTE definition."));
165
+ } while (this.match(TokenType.COMMA));
166
+ }
167
+ endToken = this.consume(TokenType.RPAREN, "Expected ')' after CTE column list.");
168
+ }
169
+ this.consume(TokenType.AS, "Expected 'AS' after CTE name.");
170
+ let materializationHint;
171
+ if (this.matchKeyword('MATERIALIZED')) {
172
+ materializationHint = 'materialized';
173
+ }
174
+ else if (this.matchKeyword('NOT')) {
175
+ this.consumeKeyword('MATERIALIZED', "Expected 'MATERIALIZED' after 'NOT'.");
176
+ materializationHint = 'not_materialized';
177
+ }
178
+ this.consume(TokenType.LPAREN, "Expected '(' before CTE query.");
179
+ // Parse the CTE query (can be SELECT, VALUES (via SELECT), INSERT, UPDATE, DELETE)
180
+ const queryStartToken = this.peek();
181
+ let query;
182
+ if (this.check(TokenType.SELECT)) {
183
+ this.advance(); // Consume SELECT token
184
+ query = this.selectStatement(queryStartToken); // Pass start token
185
+ }
186
+ else if (this.check(TokenType.INSERT)) {
187
+ this.advance(); // Consume INSERT token
188
+ query = this.insertStatement(queryStartToken);
189
+ }
190
+ else if (this.check(TokenType.UPDATE)) {
191
+ this.advance(); // Consume UPDATE token
192
+ query = this.updateStatement(queryStartToken);
193
+ }
194
+ else if (this.check(TokenType.DELETE)) {
195
+ this.advance(); // Consume DELETE token
196
+ query = this.deleteStatement(queryStartToken);
197
+ }
198
+ // TODO: Add support for VALUES directly if needed (though VALUES is usually part of SELECT)
199
+ else {
200
+ throw this.error(this.peek(), "Expected SELECT, INSERT, UPDATE, or DELETE statement for CTE query.");
201
+ }
202
+ endToken = this.consume(TokenType.RPAREN, "Expected ')' after CTE query."); // Capture ')' as end token
203
+ return { type: 'commonTableExpr', name, columns, query, materializationHint, loc: _createLoc(startToken, endToken) };
204
+ }
205
+ /**
206
+ * Parse a single SQL statement
207
+ */
208
+ statement() {
209
+ // Check for WITH clause first
210
+ let withClause;
211
+ if (this.check(TokenType.WITH)) {
212
+ withClause = this.tryParseWithClause();
213
+ }
214
+ const startToken = this.peek();
215
+ // --- Check for specific keywords first ---
216
+ const currentKeyword = startToken.lexeme.toUpperCase();
217
+ let stmt;
218
+ switch (currentKeyword) {
219
+ case 'SELECT':
220
+ this.advance();
221
+ stmt = this.selectStatement(startToken, withClause);
222
+ break;
223
+ case 'INSERT':
224
+ this.advance();
225
+ stmt = this.insertStatement(startToken, withClause);
226
+ break;
227
+ case 'UPDATE':
228
+ this.advance();
229
+ stmt = this.updateStatement(startToken, withClause);
230
+ break;
231
+ case 'DELETE':
232
+ this.advance();
233
+ stmt = this.deleteStatement(startToken, withClause);
234
+ break;
235
+ case 'VALUES':
236
+ this.advance();
237
+ stmt = this.valuesStatement(startToken);
238
+ break;
239
+ case 'CREATE':
240
+ this.advance();
241
+ stmt = this.createStatement(startToken, withClause);
242
+ break;
243
+ case 'DROP':
244
+ this.advance();
245
+ stmt = this.dropStatement(startToken, withClause);
246
+ break;
247
+ case 'ALTER':
248
+ this.advance();
249
+ stmt = this.alterTableStatement(startToken, withClause);
250
+ break;
251
+ case 'BEGIN':
252
+ this.advance();
253
+ stmt = this.beginStatement(startToken, withClause);
254
+ break;
255
+ case 'COMMIT':
256
+ this.advance();
257
+ stmt = this.commitStatement(startToken, withClause);
258
+ break;
259
+ case 'ROLLBACK':
260
+ this.advance();
261
+ stmt = this.rollbackStatement(startToken, withClause);
262
+ break;
263
+ case 'SAVEPOINT':
264
+ this.advance();
265
+ stmt = this.savepointStatement(startToken, withClause);
266
+ break;
267
+ case 'RELEASE':
268
+ this.advance();
269
+ stmt = this.releaseStatement(startToken, withClause);
270
+ break;
271
+ // TODO: Replace pragmas with build-in functions
272
+ case 'PRAGMA':
273
+ this.advance();
274
+ stmt = this.pragmaStatement(startToken, withClause);
275
+ break;
276
+ // --- Add default case ---
277
+ default:
278
+ // If it wasn't a recognized keyword starting the statement
279
+ throw this.error(startToken, `Expected statement type (SELECT, INSERT, UPDATE, DELETE, VALUES, CREATE, etc.), got '${startToken.lexeme}'.`);
280
+ }
281
+ // Attach WITH clause if present and supported
282
+ if (withClause && this.statementSupportsWithClause(stmt)) {
283
+ stmt.withClause = withClause;
284
+ if (withClause.loc && stmt.loc) {
285
+ stmt.loc.start = withClause.loc.start;
286
+ }
287
+ }
288
+ else if (withClause) {
289
+ throw this.error(this.previous(), `WITH clause cannot be used with ${stmt.type} statement.`);
290
+ }
291
+ return stmt;
292
+ }
293
+ /**
294
+ * Parse an INSERT statement
295
+ * @returns AST for the INSERT statement
296
+ */
297
+ insertStatement(startToken, withClause) {
298
+ // INTO keyword is optional in SQLite
299
+ this.matchKeyword('INTO'); // Handle missing keyword gracefully
300
+ // Parse the table reference
301
+ const table = this.tableIdentifier();
302
+ const contextualKeywords = ['key', 'action', 'set', 'default', 'check', 'unique', 'references', 'on', 'cascade', 'restrict', 'like'];
303
+ // Parse column list if provided
304
+ let columns;
305
+ if (this.match(TokenType.LPAREN)) {
306
+ columns = [];
307
+ do {
308
+ if (!this.checkIdentifierLike(contextualKeywords)) {
309
+ throw this.error(this.peek(), "Expected column name.");
310
+ }
311
+ columns.push(this.advance().lexeme);
312
+ } while (this.match(TokenType.COMMA));
313
+ this.consume(TokenType.RPAREN, "Expected ')' after column list.");
314
+ }
315
+ // Parse VALUES clause
316
+ let values;
317
+ let select;
318
+ let lastConsumedToken = this.previous(); // After columns or table id
319
+ if (this.match(TokenType.VALUES)) {
320
+ values = [];
321
+ do {
322
+ this.consume(TokenType.LPAREN, "Expected '(' before values.");
323
+ const valueList = [];
324
+ if (!this.check(TokenType.RPAREN)) { // Check for empty value list
325
+ do {
326
+ valueList.push(this.expression());
327
+ } while (this.match(TokenType.COMMA));
328
+ }
329
+ this.consume(TokenType.RPAREN, "Expected ')' after values.");
330
+ values.push(valueList);
331
+ lastConsumedToken = this.previous(); // Update after closing paren of value list
332
+ } while (this.match(TokenType.COMMA));
333
+ }
334
+ else if (this.check(TokenType.SELECT)) { // If current token is SELECT
335
+ // Handle INSERT ... SELECT
336
+ // Consume the SELECT token, as selectStatement expects to start parsing after it.
337
+ // selectKeywordToken will be the actual 'SELECT' token object, used for location.
338
+ const selectKeywordToken = this.advance(); // Consume 'SELECT'
339
+ // Pass the withClause so the embedded SELECT can (via the planner) resolve CTEs defined for the INSERT.
340
+ select = this.selectStatement(selectKeywordToken, withClause);
341
+ lastConsumedToken = this.previous(); // After SELECT statement is parsed
342
+ }
343
+ else {
344
+ throw this.error(this.peek(), "Expected VALUES or SELECT after INSERT.");
345
+ }
346
+ // Parse RETURNING clause if present
347
+ let returning;
348
+ if (this.matchKeyword('RETURNING')) {
349
+ returning = this.columnList();
350
+ lastConsumedToken = this.previous(); // Update after RETURNING clause
351
+ }
352
+ return {
353
+ type: 'insert',
354
+ table,
355
+ columns,
356
+ values,
357
+ select,
358
+ returning,
359
+ loc: _createLoc(startToken, lastConsumedToken),
360
+ };
361
+ }
362
+ /**
363
+ * Parse a SELECT statement
364
+ * @param startToken The 'SELECT' token or start token of a sub-query
365
+ * @param withClause The WITH clause context for CTE access
366
+ * @param isCompoundSubquery If true, don't parse ORDER BY/LIMIT as they belong to the outer compound
367
+ * @returns AST for the SELECT statement
368
+ */
369
+ selectStatement(startToken, withClause, isCompoundSubquery = false) {
370
+ const start = startToken ?? this.previous(); // Use provided or the keyword token
371
+ let lastConsumedToken = start; // Initialize lastConsumed
372
+ const distinct = this.matchKeyword('DISTINCT');
373
+ if (distinct)
374
+ lastConsumedToken = this.previous();
375
+ const all = !distinct && this.matchKeyword('ALL');
376
+ if (all)
377
+ lastConsumedToken = this.previous();
378
+ // Parse column list
379
+ const columns = this.columnList();
380
+ if (columns.length > 0)
381
+ lastConsumedToken = this.previous(); // Update after last column element
382
+ // Parse FROM clause if present
383
+ let from;
384
+ if (this.match(TokenType.FROM)) {
385
+ from = this.tableSourceList(withClause);
386
+ if (from.length > 0)
387
+ lastConsumedToken = this.previous(); // After last source/join
388
+ }
389
+ // Parse WHERE clause if present
390
+ let where;
391
+ if (this.match(TokenType.WHERE)) {
392
+ where = this.expression();
393
+ lastConsumedToken = this.previous(); // After where expression
394
+ }
395
+ // Parse GROUP BY clause if present
396
+ let groupBy;
397
+ if (this.match(TokenType.GROUP) && this.consume(TokenType.BY, "Expected 'BY' after 'GROUP'.")) {
398
+ groupBy = [];
399
+ do {
400
+ groupBy.push(this.expression());
401
+ } while (this.match(TokenType.COMMA));
402
+ lastConsumedToken = this.previous(); // After last group by expression
403
+ }
404
+ // Parse HAVING clause if present
405
+ let having;
406
+ if (this.match(TokenType.HAVING)) {
407
+ having = this.expression();
408
+ lastConsumedToken = this.previous(); // After having expression
409
+ }
410
+ // Check for compound set operations (UNION / INTERSECT / EXCEPT) BEFORE ORDER BY/LIMIT
411
+ let compound;
412
+ if (this.match(TokenType.UNION, TokenType.INTERSECT, TokenType.EXCEPT)) {
413
+ const tok = this.previous();
414
+ let op;
415
+ if (tok.type === TokenType.UNION) {
416
+ if (this.match(TokenType.ALL)) {
417
+ op = 'unionAll';
418
+ }
419
+ else {
420
+ op = 'union';
421
+ }
422
+ }
423
+ else if (tok.type === TokenType.INTERSECT) {
424
+ op = 'intersect';
425
+ }
426
+ else {
427
+ op = 'except';
428
+ }
429
+ let rightSelect;
430
+ // Handle parenthesized subquery after set operation
431
+ if (this.match(TokenType.LPAREN)) {
432
+ const selectToken = this.consume(TokenType.SELECT, "Expected 'SELECT' in parenthesized set operation.");
433
+ rightSelect = this.selectStatement(selectToken, withClause, true); // Pass true to indicate compound subquery
434
+ this.consume(TokenType.RPAREN, "Expected ')' after parenthesized set operation.");
435
+ }
436
+ else {
437
+ // Handle direct SELECT statement
438
+ const selectStartToken = this.peek();
439
+ if (this.match(TokenType.SELECT)) {
440
+ rightSelect = this.selectStatement(selectStartToken, withClause, true); // Pass true to indicate compound subquery
441
+ }
442
+ else {
443
+ throw this.error(this.peek(), "Expected 'SELECT' or '(' after set operation keyword.");
444
+ }
445
+ }
446
+ lastConsumedToken = this.previous();
447
+ compound = { op, select: rightSelect };
448
+ }
449
+ // Parse ORDER BY clause if present (applies to final result after compound operations)
450
+ // Skip if this is a compound subquery as ORDER BY belongs to the outer compound
451
+ let orderBy;
452
+ if (!isCompoundSubquery && this.match(TokenType.ORDER) && this.consume(TokenType.BY, "Expected 'BY' after 'ORDER'.")) {
453
+ orderBy = [];
454
+ do {
455
+ const expr = this.expression();
456
+ const direction = this.match(TokenType.DESC) ? 'desc' :
457
+ (this.match(TokenType.ASC) ? 'asc' : 'asc'); // Default to ASC
458
+ orderBy.push({ expr, direction });
459
+ } while (this.match(TokenType.COMMA));
460
+ lastConsumedToken = this.previous(); // After last order by clause
461
+ }
462
+ // Parse LIMIT clause if present (applies to final result after compound operations)
463
+ // Skip if this is a compound subquery as LIMIT belongs to the outer compound
464
+ let limit;
465
+ let offset;
466
+ if (!isCompoundSubquery && this.match(TokenType.LIMIT)) {
467
+ limit = this.expression();
468
+ lastConsumedToken = this.previous(); // After limit expression
469
+ // LIMIT x OFFSET y syntax
470
+ if (this.match(TokenType.OFFSET)) {
471
+ offset = this.expression();
472
+ lastConsumedToken = this.previous(); // After offset expression
473
+ }
474
+ // LIMIT x, y syntax (x is offset, y is limit)
475
+ else if (this.match(TokenType.COMMA)) {
476
+ offset = limit;
477
+ limit = this.expression();
478
+ lastConsumedToken = this.previous(); // After second limit expression
479
+ }
480
+ }
481
+ return {
482
+ type: 'select',
483
+ columns,
484
+ from,
485
+ where,
486
+ groupBy,
487
+ having,
488
+ orderBy,
489
+ limit,
490
+ offset,
491
+ distinct,
492
+ all,
493
+ compound,
494
+ loc: _createLoc(start, lastConsumedToken),
495
+ };
496
+ }
497
+ /**
498
+ * Parse a comma-separated list of result columns for SELECT
499
+ */
500
+ columnList() {
501
+ const columns = [];
502
+ const contextualKeywords = ['key', 'action', 'set', 'default', 'check', 'unique', 'references', 'on', 'cascade', 'restrict', 'like'];
503
+ do {
504
+ log(`columnList: Loop start. Current token: ${this.peek().lexeme} (${this.peek().type})`); // DEBUG
505
+ // Handle wildcard: * or table.*
506
+ if (this.match(TokenType.ASTERISK)) {
507
+ columns.push({ type: 'all' });
508
+ }
509
+ // Handle table.* syntax
510
+ else if (this.checkIdentifierLike(contextualKeywords) && this.checkNext(1, TokenType.DOT) &&
511
+ this.checkNext(2, TokenType.ASTERISK)) {
512
+ const table = this.consumeIdentifier(contextualKeywords, "Expected table name before '.*'.");
513
+ this.advance(); // consume DOT
514
+ this.advance(); // consume ASTERISK
515
+ columns.push({ type: 'all', table });
516
+ }
517
+ // Handle regular column expression
518
+ else {
519
+ log(`columnList: Parsing expression...`); // DEBUG
520
+ const expr = this.expression();
521
+ log(`columnList: Parsed expression. Current token: ${this.peek().lexeme} (${this.peek().type})`); // DEBUG
522
+ let alias;
523
+ // Handle AS alias or just alias
524
+ if (this.match(TokenType.AS)) {
525
+ if (this.checkIdentifierLike(contextualKeywords) || this.check(TokenType.STRING)) {
526
+ const aliasToken = this.advance();
527
+ alias = aliasToken.lexeme;
528
+ if (aliasToken.type === TokenType.STRING) {
529
+ alias = aliasToken.literal;
530
+ }
531
+ }
532
+ else {
533
+ throw this.error(this.peek(), "Expected identifier or string after 'AS'.");
534
+ }
535
+ }
536
+ // Implicit alias (no AS keyword)
537
+ else if (this.checkIdentifierLike([]) &&
538
+ !this.checkNext(1, TokenType.LPAREN) &&
539
+ !this.checkNext(1, TokenType.DOT) &&
540
+ !this.checkNext(1, TokenType.COMMA) &&
541
+ !this.isEndOfClause()) {
542
+ const aliasToken = this.advance();
543
+ alias = aliasToken.lexeme;
544
+ }
545
+ columns.push({ type: 'column', expr, alias });
546
+ }
547
+ log(`columnList: Checking for comma. Current token: ${this.peek().lexeme} (${this.peek().type})`); // DEBUG
548
+ } while (this.match(TokenType.COMMA));
549
+ log(`columnList: Loop ended. Current token: ${this.peek().lexeme} (${this.peek().type})`); // DEBUG
550
+ return columns;
551
+ }
552
+ /**
553
+ * Parse a table identifier (possibly schema-qualified)
554
+ */
555
+ tableIdentifier() {
556
+ const startToken = this.peek();
557
+ let schema;
558
+ let name;
559
+ let endToken = startToken;
560
+ const contextualKeywords = ['key', 'action', 'set', 'default', 'check', 'unique', 'references', 'on', 'cascade', 'restrict', 'like'];
561
+ // Check for schema.table pattern
562
+ if (this.checkIdentifierLike(contextualKeywords) && this.checkNext(1, TokenType.DOT)) {
563
+ schema = this.consumeIdentifier(contextualKeywords, "Expected schema name.");
564
+ this.advance(); // Consume DOT
565
+ name = this.consumeIdentifier(contextualKeywords, "Expected table name after schema.");
566
+ endToken = this.previous();
567
+ }
568
+ else if (this.checkIdentifierLike(contextualKeywords)) {
569
+ name = this.consumeIdentifier(contextualKeywords, "Expected table name.");
570
+ endToken = this.previous();
571
+ }
572
+ else {
573
+ throw this.error(this.peek(), "Expected table name.");
574
+ }
575
+ return {
576
+ type: 'identifier',
577
+ name,
578
+ schema,
579
+ loc: _createLoc(startToken, endToken),
580
+ };
581
+ }
582
+ /**
583
+ * Parse a comma-separated list of table sources (FROM clause)
584
+ */
585
+ tableSourceList(withClause) {
586
+ const sources = [];
587
+ do {
588
+ // Get the base table source
589
+ let source = this.tableSource(withClause);
590
+ // Look for JOINs
591
+ while (this.isJoinToken()) {
592
+ source = this.joinClause(source, withClause);
593
+ }
594
+ sources.push(source);
595
+ } while (this.match(TokenType.COMMA));
596
+ return sources;
597
+ }
598
+ /**
599
+ * Parse a single table source, which can now be a table name, table-valued function call, or subquery
600
+ */
601
+ tableSource(withClause) {
602
+ const startToken = this.peek();
603
+ const contextualKeywords = ['key', 'action', 'set', 'default', 'check', 'unique', 'references', 'on', 'cascade', 'restrict', 'like'];
604
+ // Check for subquery: ( SELECT ... or ( VALUES ... or ( INSERT/UPDATE/DELETE ...
605
+ if (this.check(TokenType.LPAREN)) {
606
+ // Look ahead to see if this is a subquery
607
+ const lookahead = this.current + 1;
608
+ if (lookahead < this.tokens.length) {
609
+ const nextTokenType = this.tokens[lookahead].type;
610
+ if (nextTokenType === TokenType.SELECT || nextTokenType === TokenType.VALUES) {
611
+ return this.subquerySource(startToken, withClause);
612
+ }
613
+ else if (nextTokenType === TokenType.INSERT || nextTokenType === TokenType.UPDATE || nextTokenType === TokenType.DELETE) {
614
+ return this.mutatingSubquerySource(startToken, withClause);
615
+ }
616
+ }
617
+ }
618
+ // Check for function call syntax: IDENTIFIER (
619
+ if (this.checkIdentifierLike(contextualKeywords) && this.checkNext(1, TokenType.LPAREN)) {
620
+ return this.functionSource(startToken);
621
+ }
622
+ // Otherwise, assume it's a standard table source
623
+ else {
624
+ return this.standardTableSource(startToken);
625
+ }
626
+ }
627
+ /** Parses a subquery source: (SELECT ...) AS alias */
628
+ subquerySource(startToken, withClause) {
629
+ this.consume(TokenType.LPAREN, "Expected '(' before subquery.");
630
+ let subquery;
631
+ if (this.check(TokenType.SELECT)) {
632
+ // Consume the SELECT token and pass it as startToken to selectStatement
633
+ const selectToken = this.advance();
634
+ subquery = this.selectStatement(selectToken, withClause);
635
+ }
636
+ else if (this.check(TokenType.VALUES)) {
637
+ // Handle VALUES subquery
638
+ const valuesToken = this.advance();
639
+ subquery = this.valuesStatement(valuesToken);
640
+ }
641
+ else {
642
+ throw this.error(this.peek(), "Expected 'SELECT' or 'VALUES' in subquery.");
643
+ }
644
+ this.consume(TokenType.RPAREN, "Expected ')' after subquery.");
645
+ // Parse optional alias for subquery
646
+ let alias;
647
+ let columns;
648
+ if (this.match(TokenType.AS)) {
649
+ if (!this.checkIdentifierLike([])) {
650
+ throw this.error(this.peek(), "Expected alias after 'AS'.");
651
+ }
652
+ const aliasToken = this.advance();
653
+ alias = aliasToken.lexeme;
654
+ }
655
+ else if (this.checkIdentifierLike([]) &&
656
+ !this.checkNext(1, TokenType.DOT) &&
657
+ !this.checkNext(1, TokenType.COMMA) &&
658
+ !this.isJoinToken() &&
659
+ !this.isEndOfClause()) {
660
+ const aliasToken = this.advance();
661
+ alias = aliasToken.lexeme;
662
+ }
663
+ else {
664
+ // Generate a default alias if none provided
665
+ alias = `subquery_${startToken.startOffset}`;
666
+ }
667
+ // Parse optional column list after alias: AS alias(col1, col2, ...)
668
+ if (this.match(TokenType.LPAREN)) {
669
+ columns = [];
670
+ const contextualKeywords = ['key', 'action', 'set', 'default', 'check', 'unique', 'references', 'on', 'cascade', 'restrict', 'like'];
671
+ if (!this.check(TokenType.RPAREN)) {
672
+ do {
673
+ columns.push(this.consumeIdentifier(contextualKeywords, "Expected column name in alias column list."));
674
+ } while (this.match(TokenType.COMMA));
675
+ }
676
+ this.consume(TokenType.RPAREN, "Expected ')' after alias column list.");
677
+ }
678
+ const endToken = this.previous();
679
+ return {
680
+ type: 'subquerySource',
681
+ subquery,
682
+ alias,
683
+ columns,
684
+ loc: _createLoc(startToken, endToken),
685
+ };
686
+ }
687
+ /** Parses a mutating subquery source: (INSERT/UPDATE/DELETE ... RETURNING ...) AS alias */
688
+ mutatingSubquerySource(startToken, withClause) {
689
+ this.consume(TokenType.LPAREN, "Expected '(' before mutating subquery.");
690
+ let stmt;
691
+ if (this.check(TokenType.INSERT)) {
692
+ const insertToken = this.advance();
693
+ stmt = this.insertStatement(insertToken, withClause);
694
+ }
695
+ else if (this.check(TokenType.UPDATE)) {
696
+ const updateToken = this.advance();
697
+ stmt = this.updateStatement(updateToken, withClause);
698
+ }
699
+ else if (this.check(TokenType.DELETE)) {
700
+ const deleteToken = this.advance();
701
+ stmt = this.deleteStatement(deleteToken, withClause);
702
+ }
703
+ else {
704
+ throw this.error(this.peek(), "Expected 'INSERT', 'UPDATE', or 'DELETE' in mutating subquery.");
705
+ }
706
+ // Validate that the statement has a RETURNING clause
707
+ if (!stmt.returning || stmt.returning.length === 0) {
708
+ throw this.error(this.previous(), "Mutating subqueries must have a RETURNING clause to be used as table sources.");
709
+ }
710
+ this.consume(TokenType.RPAREN, "Expected ')' after mutating subquery.");
711
+ // Parse optional alias for mutating subquery
712
+ let alias;
713
+ let columns;
714
+ if (this.match(TokenType.AS)) {
715
+ if (!this.checkIdentifierLike([])) {
716
+ throw this.error(this.peek(), "Expected alias after 'AS'.");
717
+ }
718
+ const aliasToken = this.advance();
719
+ alias = aliasToken.lexeme;
720
+ }
721
+ else if (this.checkIdentifierLike([]) &&
722
+ !this.checkNext(1, TokenType.DOT) &&
723
+ !this.checkNext(1, TokenType.COMMA) &&
724
+ !this.isJoinToken() &&
725
+ !this.isEndOfClause()) {
726
+ const aliasToken = this.advance();
727
+ alias = aliasToken.lexeme;
728
+ }
729
+ else {
730
+ // Generate a default alias if none provided
731
+ alias = `mutating_subquery_${startToken.startOffset}`;
732
+ }
733
+ // Parse optional column list after alias: AS alias(col1, col2, ...)
734
+ if (this.match(TokenType.LPAREN)) {
735
+ columns = [];
736
+ const contextualKeywords = ['key', 'action', 'set', 'default', 'check', 'unique', 'references', 'on', 'cascade', 'restrict', 'like'];
737
+ if (!this.check(TokenType.RPAREN)) {
738
+ do {
739
+ columns.push(this.consumeIdentifier(contextualKeywords, "Expected column name in alias column list."));
740
+ } while (this.match(TokenType.COMMA));
741
+ }
742
+ this.consume(TokenType.RPAREN, "Expected ')' after alias column list.");
743
+ }
744
+ const endToken = this.previous();
745
+ return {
746
+ type: 'mutatingSubquerySource',
747
+ stmt,
748
+ alias,
749
+ columns,
750
+ loc: _createLoc(startToken, endToken),
751
+ };
752
+ }
753
+ /** Parses a standard table source (schema.table or table) */
754
+ standardTableSource(startToken) {
755
+ const contextualKeywords = ['key', 'action', 'set', 'default', 'check', 'unique', 'references', 'on', 'cascade', 'restrict', 'like'];
756
+ // Parse table name (potentially schema-qualified)
757
+ const table = this.tableIdentifier();
758
+ let endToken = this.previous(); // Initialize endToken after parsing table identifier
759
+ // Parse optional alias
760
+ let alias;
761
+ if (this.match(TokenType.AS)) {
762
+ if (!this.checkIdentifierLike(contextualKeywords)) {
763
+ throw this.error(this.peek(), "Expected alias after 'AS'.");
764
+ }
765
+ const aliasToken = this.advance();
766
+ alias = aliasToken.lexeme;
767
+ endToken = aliasToken;
768
+ }
769
+ else if (this.checkIdentifierLike([]) &&
770
+ !this.checkNext(1, TokenType.DOT) &&
771
+ !this.checkNext(1, TokenType.COMMA) &&
772
+ !this.isJoinToken() &&
773
+ !this.isEndOfClause()) {
774
+ const aliasToken = this.advance();
775
+ alias = aliasToken.lexeme;
776
+ endToken = aliasToken;
777
+ }
778
+ return {
779
+ type: 'table',
780
+ table,
781
+ alias,
782
+ loc: _createLoc(startToken, endToken),
783
+ };
784
+ }
785
+ /** Parses a table-valued function source: name(arg1, ...) [AS alias] */
786
+ functionSource(startToken) {
787
+ const contextualKeywords = ['key', 'action', 'set', 'default', 'check', 'unique', 'references', 'on', 'cascade', 'restrict', 'like'];
788
+ const name = this.tableIdentifier(); // name has its own loc
789
+ let endToken = this.previous(); // Initialize endToken after parsing function identifier
790
+ this.consume(TokenType.LPAREN, "Expected '(' after table function name.");
791
+ const args = [];
792
+ if (!this.check(TokenType.RPAREN)) {
793
+ // Handle DISTINCT inside function calls like COUNT(DISTINCT col)
794
+ const distinct = this.matchKeyword('DISTINCT');
795
+ // Handle * argument AFTER checking for distinct
796
+ if (this.match(TokenType.ASTERISK)) {
797
+ // Do not add '*' as an argument to the list for aggregates like COUNT(*)
798
+ if (args.length > 0 || distinct) {
799
+ // '*' is only valid as the *only* argument, potentially after DISTINCT
800
+ // e.g. COUNT(*), COUNT(DISTINCT *) - though DISTINCT * might not be standard SQL?
801
+ // For now, disallow '*' if other args exist.
802
+ throw this.error(this.previous(), "'*' cannot be used with other arguments in function call.");
803
+ }
804
+ // If we parsed '*', the args list remains empty.
805
+ }
806
+ else {
807
+ // Parse regular arguments if '*' wasn't found
808
+ do {
809
+ args.push(this.expression());
810
+ } while (this.match(TokenType.COMMA));
811
+ }
812
+ }
813
+ endToken = this.consume(TokenType.RPAREN, "Expected ')' after table function arguments.");
814
+ // Parse optional alias (same logic as for standard tables)
815
+ let alias;
816
+ if (this.match(TokenType.AS)) {
817
+ if (!this.checkIdentifierLike(contextualKeywords)) {
818
+ throw this.error(this.peek(), "Expected alias after 'AS'.");
819
+ }
820
+ const aliasToken = this.advance();
821
+ alias = aliasToken.lexeme;
822
+ endToken = aliasToken;
823
+ }
824
+ else if (this.checkIdentifierLike([]) &&
825
+ !this.checkNext(1, TokenType.DOT) &&
826
+ !this.checkNext(1, TokenType.COMMA) &&
827
+ !this.isJoinToken() &&
828
+ !this.isEndOfClause()) {
829
+ const aliasToken = this.advance();
830
+ alias = aliasToken.lexeme;
831
+ endToken = aliasToken;
832
+ }
833
+ return {
834
+ type: 'functionSource',
835
+ name,
836
+ args,
837
+ alias,
838
+ loc: _createLoc(startToken, endToken),
839
+ };
840
+ }
841
+ /**
842
+ * Parse a JOIN clause
843
+ */
844
+ joinClause(left, withClause) {
845
+ const joinStartToken = this.peek(); // Capture token before parsing JOIN type
846
+ // Determine join type
847
+ let joinType = 'inner';
848
+ if (this.match(TokenType.LEFT)) {
849
+ this.match(TokenType.OUTER); // optional
850
+ joinType = 'left';
851
+ }
852
+ else if (this.match(TokenType.RIGHT)) {
853
+ this.match(TokenType.OUTER); // optional
854
+ joinType = 'right';
855
+ }
856
+ else if (this.match(TokenType.FULL)) {
857
+ this.match(TokenType.OUTER); // optional
858
+ joinType = 'full';
859
+ }
860
+ else if (this.match(TokenType.CROSS)) {
861
+ joinType = 'cross';
862
+ }
863
+ else if (this.match(TokenType.INNER)) {
864
+ joinType = 'inner';
865
+ }
866
+ // Consume JOIN token
867
+ this.consume(TokenType.JOIN, "Expected 'JOIN'.");
868
+ // Parse right side of join
869
+ const right = this.tableSource(withClause);
870
+ // Parse join condition
871
+ let condition;
872
+ let columns;
873
+ let endToken = this.previous(); // End token is end of right source initially
874
+ if (this.match(TokenType.ON)) {
875
+ condition = this.expression();
876
+ endToken = this.previous(); // End token is end of ON expression
877
+ }
878
+ else if (this.match(TokenType.USING)) {
879
+ this.consume(TokenType.LPAREN, "Expected '(' after 'USING'.");
880
+ columns = [];
881
+ const contextualKeywords = ['key', 'action', 'set', 'default', 'check', 'unique', 'references', 'on', 'cascade', 'restrict', 'like'];
882
+ do {
883
+ columns.push(this.consumeIdentifier(contextualKeywords, "Expected column name."));
884
+ } while (this.match(TokenType.COMMA));
885
+ endToken = this.consume(TokenType.RPAREN, "Expected ')' after columns.");
886
+ }
887
+ else if (joinType !== 'cross') {
888
+ throw this.error(this.peek(), "Expected 'ON' or 'USING' after JOIN.");
889
+ }
890
+ return {
891
+ type: 'join',
892
+ joinType,
893
+ left,
894
+ right,
895
+ condition,
896
+ columns,
897
+ loc: _createLoc(joinStartToken, endToken),
898
+ };
899
+ }
900
+ /**
901
+ * Parse an expression
902
+ */
903
+ expression() {
904
+ return this.logicalXorOr();
905
+ }
906
+ /**
907
+ * Parse logical OR and XOR expressions (lowest precedence)
908
+ */
909
+ logicalXorOr() {
910
+ let expr = this.logicalAnd();
911
+ const startToken = expr.loc ? this.tokens.find(t => t.startOffset === expr.loc.start.offset) ?? this.peek() : this.peek(); // Get start token of left expr
912
+ while (this.match(TokenType.OR, TokenType.XOR)) { // Added XOR
913
+ const operator = this.previous().type === TokenType.XOR ? 'XOR' : 'OR'; // Determine operator
914
+ const right = this.logicalAnd();
915
+ const endToken = this.previous(); // End token is end of right expr
916
+ expr = {
917
+ type: 'binary',
918
+ operator,
919
+ left: expr,
920
+ right,
921
+ loc: _createLoc(startToken, endToken),
922
+ };
923
+ }
924
+ return expr;
925
+ }
926
+ /**
927
+ * Parse logical AND expression
928
+ */
929
+ logicalAnd() {
930
+ let expr = this.isNull();
931
+ const startToken = expr.loc ? this.tokens.find(t => t.startOffset === expr.loc.start.offset) ?? this.peek() : this.peek(); // Get start token of left expr
932
+ while (this.match(TokenType.AND)) {
933
+ const operator = 'AND';
934
+ const right = this.isNull();
935
+ const endToken = this.previous(); // End token is end of right expr
936
+ expr = {
937
+ type: 'binary',
938
+ operator,
939
+ left: expr,
940
+ right,
941
+ loc: _createLoc(startToken, endToken),
942
+ };
943
+ }
944
+ return expr;
945
+ }
946
+ /**
947
+ * Parse IS NULL / IS NOT NULL expressions
948
+ */
949
+ isNull() {
950
+ const expr = this.equality();
951
+ const startToken = expr.loc ? this.tokens.find(t => t.startOffset === expr.loc.start.offset) ?? this.peek() : this.peek(); // Get start token of left expr
952
+ if (this.match(TokenType.IS)) {
953
+ let isNot = false;
954
+ if (this.match(TokenType.NOT)) {
955
+ isNot = true;
956
+ }
957
+ if (this.match(TokenType.NULL)) {
958
+ const endToken = this.previous(); // End token is NULL
959
+ const operator = isNot ? 'IS NOT NULL' : 'IS NULL';
960
+ // Represent IS NULL / IS NOT NULL as UnaryExpr for simplicity
961
+ return { type: 'unary', operator, expr, loc: _createLoc(startToken, endToken) };
962
+ }
963
+ // If it was IS or IS NOT but not followed by NULL, maybe it's IS TRUE/FALSE/DISTINCT FROM?
964
+ // For now, assume standard comparison if NULL doesn't follow IS [NOT]
965
+ // We need to "unread" the IS and optional NOT token if we didn't match NULL.
966
+ // Backtrack current position.
967
+ if (isNot)
968
+ this.current--; // Backtrack NOT
969
+ this.current--; // Backtrack IS
970
+ }
971
+ return expr;
972
+ }
973
+ /**
974
+ * Parse equality expression
975
+ */
976
+ equality() {
977
+ let expr = this.comparison();
978
+ const startToken = expr.loc ? this.tokens.find(t => t.startOffset === expr.loc.start.offset) ?? this.peek() : this.peek(); // Get start token of left expr
979
+ while (this.match(TokenType.EQUAL, TokenType.EQUAL_EQUAL, TokenType.NOT_EQUAL)) {
980
+ let operator;
981
+ switch (this.previous().type) {
982
+ case TokenType.NOT_EQUAL:
983
+ operator = '!=';
984
+ break;
985
+ case TokenType.EQUAL_EQUAL:
986
+ operator = '==';
987
+ break;
988
+ default:
989
+ operator = '=';
990
+ break;
991
+ }
992
+ const right = this.comparison();
993
+ const endToken = this.previous(); // End token is end of right expr
994
+ expr = {
995
+ type: 'binary',
996
+ operator,
997
+ left: expr,
998
+ right,
999
+ loc: _createLoc(startToken, endToken),
1000
+ };
1001
+ }
1002
+ return expr;
1003
+ }
1004
+ /**
1005
+ * Parse comparison expression
1006
+ */
1007
+ comparison() {
1008
+ let expr = this.term();
1009
+ const startToken = expr.loc ? this.tokens.find(t => t.startOffset === expr.loc.start.offset) ?? this.peek() : this.peek(); // Get start token of left expr
1010
+ while (this.match(TokenType.LESS, TokenType.LESS_EQUAL, TokenType.GREATER, TokenType.GREATER_EQUAL, TokenType.BETWEEN, TokenType.IN, TokenType.NOT, TokenType.LIKE)) {
1011
+ const operatorToken = this.previous();
1012
+ // Handle NOT IN, NOT BETWEEN, and NOT LIKE
1013
+ if (operatorToken.type === TokenType.NOT) {
1014
+ const notStartToken = operatorToken;
1015
+ if (this.match(TokenType.IN)) {
1016
+ // NOT IN
1017
+ this.consume(TokenType.LPAREN, "Expected '(' after NOT IN.");
1018
+ if (this.check(TokenType.SELECT)) {
1019
+ // NOT IN subquery: expr NOT IN (SELECT ...)
1020
+ const selectToken = this.advance(); // Consume SELECT
1021
+ const subquery = this.selectStatement(selectToken);
1022
+ const endToken = this.consume(TokenType.RPAREN, "Expected ')' after NOT IN subquery.");
1023
+ // Create an IN expression with subquery, then wrap in NOT
1024
+ const inExpr = {
1025
+ type: 'in',
1026
+ expr,
1027
+ subquery,
1028
+ loc: _createLoc(startToken, endToken),
1029
+ };
1030
+ expr = {
1031
+ type: 'unary',
1032
+ operator: 'NOT',
1033
+ expr: inExpr,
1034
+ loc: _createLoc(notStartToken, endToken),
1035
+ };
1036
+ }
1037
+ else {
1038
+ // NOT IN value list: expr NOT IN (value1, value2, ...)
1039
+ const values = [];
1040
+ if (!this.check(TokenType.RPAREN)) {
1041
+ do {
1042
+ values.push(this.expression());
1043
+ } while (this.match(TokenType.COMMA));
1044
+ }
1045
+ const endToken = this.consume(TokenType.RPAREN, "Expected ')' after NOT IN values.");
1046
+ // Create an IN expression with value list, then wrap in NOT
1047
+ const inExpr = {
1048
+ type: 'in',
1049
+ expr,
1050
+ values,
1051
+ loc: _createLoc(startToken, endToken),
1052
+ };
1053
+ expr = {
1054
+ type: 'unary',
1055
+ operator: 'NOT',
1056
+ expr: inExpr,
1057
+ loc: _createLoc(notStartToken, endToken),
1058
+ };
1059
+ }
1060
+ }
1061
+ else if (this.match(TokenType.BETWEEN)) {
1062
+ // NOT BETWEEN
1063
+ const low = this.term();
1064
+ this.consume(TokenType.AND, "Expected 'AND' after NOT BETWEEN lower bound.");
1065
+ const high = this.term();
1066
+ const endToken = this.previous(); // End token is end of high expr
1067
+ // Create a binary AND expression for the bounds
1068
+ const boundsExpr = {
1069
+ type: 'binary',
1070
+ operator: 'AND',
1071
+ left: low,
1072
+ right: high,
1073
+ loc: _createLoc(low.loc?.start ? this.tokens.find(t => t.startOffset === low.loc.start.offset) ?? this.peek() : this.peek(), endToken)
1074
+ };
1075
+ // Create the BETWEEN expression as a binary expression, then wrap in NOT
1076
+ const betweenExpr = {
1077
+ type: 'binary',
1078
+ operator: 'BETWEEN',
1079
+ left: expr,
1080
+ right: boundsExpr,
1081
+ loc: _createLoc(startToken, endToken),
1082
+ };
1083
+ expr = {
1084
+ type: 'unary',
1085
+ operator: 'NOT',
1086
+ expr: betweenExpr,
1087
+ loc: _createLoc(notStartToken, endToken),
1088
+ };
1089
+ }
1090
+ else if (this.match(TokenType.LIKE)) {
1091
+ // NOT LIKE
1092
+ const pattern = this.term();
1093
+ const endToken = this.previous(); // End token is end of pattern expr
1094
+ // Create the LIKE expression as a binary expression, then wrap in NOT
1095
+ const likeExpr = {
1096
+ type: 'binary',
1097
+ operator: 'LIKE',
1098
+ left: expr,
1099
+ right: pattern,
1100
+ loc: _createLoc(startToken, endToken),
1101
+ };
1102
+ expr = {
1103
+ type: 'unary',
1104
+ operator: 'NOT',
1105
+ expr: likeExpr,
1106
+ loc: _createLoc(notStartToken, endToken),
1107
+ };
1108
+ }
1109
+ else {
1110
+ // Put back the NOT token and break out of the loop
1111
+ this.current--;
1112
+ break;
1113
+ }
1114
+ }
1115
+ else if (operatorToken.type === TokenType.LIKE) {
1116
+ // Parse LIKE expression: expr LIKE pattern
1117
+ const pattern = this.term();
1118
+ const endToken = this.previous(); // End token is end of pattern expr
1119
+ // Create the LIKE expression as a binary expression
1120
+ expr = {
1121
+ type: 'binary',
1122
+ operator: 'LIKE',
1123
+ left: expr,
1124
+ right: pattern,
1125
+ loc: _createLoc(startToken, endToken),
1126
+ };
1127
+ }
1128
+ else if (operatorToken.type === TokenType.BETWEEN) {
1129
+ // Parse BETWEEN expression: expr BETWEEN low AND high
1130
+ const low = this.term();
1131
+ this.consume(TokenType.AND, "Expected 'AND' after BETWEEN lower bound.");
1132
+ const high = this.term();
1133
+ const endToken = this.previous(); // End token is end of high expr
1134
+ // Create a binary AND expression for the bounds
1135
+ const boundsExpr = {
1136
+ type: 'binary',
1137
+ operator: 'AND',
1138
+ left: low,
1139
+ right: high,
1140
+ loc: _createLoc(low.loc?.start ? this.tokens.find(t => t.startOffset === low.loc.start.offset) ?? this.peek() : this.peek(), endToken)
1141
+ };
1142
+ // Create the BETWEEN expression as a binary expression
1143
+ expr = {
1144
+ type: 'binary',
1145
+ operator: 'BETWEEN',
1146
+ left: expr,
1147
+ right: boundsExpr,
1148
+ loc: _createLoc(startToken, endToken),
1149
+ };
1150
+ }
1151
+ else if (operatorToken.type === TokenType.IN) {
1152
+ // Parse IN expression: expr IN (value1, value2, ...) or expr IN (subquery)
1153
+ this.consume(TokenType.LPAREN, "Expected '(' after IN.");
1154
+ // Check if this is a subquery or value list
1155
+ if (this.check(TokenType.SELECT)) {
1156
+ // IN subquery: expr IN (SELECT ...)
1157
+ const selectToken = this.advance(); // Consume SELECT
1158
+ const subquery = this.selectStatement(selectToken);
1159
+ const endToken = this.consume(TokenType.RPAREN, "Expected ')' after IN subquery.");
1160
+ // Create an IN expression with subquery
1161
+ expr = {
1162
+ type: 'in',
1163
+ expr,
1164
+ subquery,
1165
+ loc: _createLoc(startToken, endToken),
1166
+ };
1167
+ }
1168
+ else {
1169
+ // IN value list: expr IN (value1, value2, ...)
1170
+ const values = [];
1171
+ if (!this.check(TokenType.RPAREN)) {
1172
+ do {
1173
+ values.push(this.expression());
1174
+ } while (this.match(TokenType.COMMA));
1175
+ }
1176
+ const endToken = this.consume(TokenType.RPAREN, "Expected ')' after IN values.");
1177
+ // Create an IN expression with value list
1178
+ expr = {
1179
+ type: 'in',
1180
+ expr,
1181
+ values,
1182
+ loc: _createLoc(startToken, endToken),
1183
+ };
1184
+ }
1185
+ }
1186
+ else {
1187
+ // Handle other comparison operators
1188
+ let operator;
1189
+ switch (operatorToken.type) {
1190
+ case TokenType.LESS:
1191
+ operator = '<';
1192
+ break;
1193
+ case TokenType.LESS_EQUAL:
1194
+ operator = '<=';
1195
+ break;
1196
+ case TokenType.GREATER:
1197
+ operator = '>';
1198
+ break;
1199
+ case TokenType.GREATER_EQUAL:
1200
+ operator = '>=';
1201
+ break;
1202
+ default: operator = '?';
1203
+ }
1204
+ const right = this.term();
1205
+ const endToken = this.previous(); // End token is end of right expr
1206
+ expr = {
1207
+ type: 'binary',
1208
+ operator,
1209
+ left: expr,
1210
+ right,
1211
+ loc: _createLoc(startToken, endToken),
1212
+ };
1213
+ }
1214
+ }
1215
+ return expr;
1216
+ }
1217
+ /**
1218
+ * Parse addition and subtraction
1219
+ */
1220
+ term() {
1221
+ let expr = this.factor();
1222
+ const startToken = expr.loc ? this.tokens.find(t => t.startOffset === expr.loc.start.offset) ?? this.peek() : this.peek(); // Get start token of left expr
1223
+ while (this.match(TokenType.PLUS, TokenType.MINUS)) {
1224
+ const operator = this.previous().type === TokenType.PLUS ? '+' : '-';
1225
+ const right = this.factor();
1226
+ const endToken = this.previous(); // End token is end of right expr
1227
+ expr = {
1228
+ type: 'binary',
1229
+ operator,
1230
+ left: expr,
1231
+ right,
1232
+ loc: _createLoc(startToken, endToken),
1233
+ };
1234
+ }
1235
+ return expr;
1236
+ }
1237
+ /**
1238
+ * Parse multiplication and division
1239
+ */
1240
+ factor() {
1241
+ // First, handle unary operators
1242
+ if (this.match(TokenType.MINUS, TokenType.PLUS, TokenType.TILDE, TokenType.NOT)) { // Added NOT
1243
+ const operatorToken = this.previous();
1244
+ const operatorStartToken = operatorToken; // Start token is the operator itself
1245
+ const operator = operatorToken.lexeme;
1246
+ // Unary operator applies to the result of the *next* precedence level (concatenation)
1247
+ const right = this.concatenation(); // Should call concatenation (higher precedence than factor)
1248
+ const endToken = this.previous(); // End token is end of the operand
1249
+ return { type: 'unary', operator, expr: right, loc: _createLoc(operatorStartToken, endToken) };
1250
+ }
1251
+ let expr = this.concatenation(); // Factor operands have higher precedence (concatenation)
1252
+ const startToken = expr.loc ? this.tokens.find(t => t.startOffset === expr.loc.start.offset) ?? this.peek() : this.peek(); // Get start token of left expr
1253
+ while (this.match(TokenType.ASTERISK, TokenType.SLASH, TokenType.PERCENT)) {
1254
+ const operatorToken = this.previous();
1255
+ const operator = operatorToken.lexeme;
1256
+ const right = this.concatenation(); // Factor operands have higher precedence (concatenation)
1257
+ const endToken = this.previous(); // End token is end of right expr
1258
+ expr = { type: 'binary', operator, left: expr, right, loc: _createLoc(startToken, endToken) };
1259
+ }
1260
+ return expr;
1261
+ }
1262
+ /**
1263
+ * Parse concatenation expression (||)
1264
+ */
1265
+ concatenation() {
1266
+ let expr = this.collateExpression(); // Concatenation operands have higher precedence (collate)
1267
+ const startToken = expr.loc ? this.tokens.find(t => t.startOffset === expr.loc.start.offset) ?? this.peek() : this.peek(); // Get start token of left expr
1268
+ while (this.match(TokenType.PIPE_PIPE)) {
1269
+ const operator = '||';
1270
+ const right = this.collateExpression(); // Concatenation operands have higher precedence (collate)
1271
+ const endToken = this.previous(); // End token is end of right expr
1272
+ expr = {
1273
+ type: 'binary',
1274
+ operator,
1275
+ left: expr,
1276
+ right,
1277
+ loc: _createLoc(startToken, endToken),
1278
+ };
1279
+ }
1280
+ return expr;
1281
+ }
1282
+ /**
1283
+ * Parse COLLATE expression
1284
+ */
1285
+ collateExpression() {
1286
+ const expr = this.primary(); // Parse primary expression first
1287
+ if (this.matchKeyword('COLLATE')) {
1288
+ const collationToken = this.consume(TokenType.IDENTIFIER, "Expected collation name after COLLATE.");
1289
+ const collation = collationToken.lexeme;
1290
+ // Use the start of the original expression and end of collation name for location
1291
+ const startLocToken = expr.loc?.start ? this.tokens.find(t => t.startOffset === expr.loc.start.offset) ?? this.peek() : this.peek();
1292
+ return { type: 'collate', expr, collation, loc: _createLoc(startLocToken, collationToken) };
1293
+ }
1294
+ return expr;
1295
+ }
1296
+ /**
1297
+ * Parse primary expressions (literals, identifiers, etc.)
1298
+ */
1299
+ primary() {
1300
+ const startToken = this.peek();
1301
+ // Case expression
1302
+ if (this.matchKeyword('CASE')) {
1303
+ return this.parseCaseExpression(startToken);
1304
+ }
1305
+ // CAST expression: CAST(expr AS type)
1306
+ if (this.peekKeyword('CAST') && this.checkNext(1, TokenType.LPAREN)) {
1307
+ const castToken = this.advance(); // Consume CAST
1308
+ this.consume(TokenType.LPAREN, "Expected '(' after CAST.");
1309
+ const expr = this.expression();
1310
+ this.consumeKeyword('AS', "Expected 'AS' in CAST expression.");
1311
+ // Allow type names that might be keywords (e.g., TEXT, INTEGER, REAL, BLOB)
1312
+ // or multi-word type names if supported (e.g., "VARCHAR(255)") - for now, simple identifier
1313
+ if (!this.check(TokenType.IDENTIFIER) &&
1314
+ !this.isTypeNameKeyword(this.peek().lexeme.toUpperCase())) {
1315
+ throw this.error(this.peek(), "Expected type name after 'AS' in CAST expression.");
1316
+ }
1317
+ const typeToken = this.advance(); // Consume type name
1318
+ const targetType = typeToken.lexeme;
1319
+ const endToken = this.consume(TokenType.RPAREN, "Expected ')' after CAST expression type.");
1320
+ return { type: 'cast', expr, targetType, loc: _createLoc(castToken, endToken) };
1321
+ }
1322
+ // EXISTS expression: EXISTS(SELECT ...)
1323
+ if (this.match(TokenType.EXISTS)) {
1324
+ const existsToken = this.previous();
1325
+ this.consume(TokenType.LPAREN, "Expected '(' after EXISTS.");
1326
+ const selectToken = this.consume(TokenType.SELECT, "Expected 'SELECT' in EXISTS subquery.");
1327
+ const subquery = this.selectStatement(selectToken);
1328
+ const endToken = this.consume(TokenType.RPAREN, "Expected ')' after EXISTS subquery.");
1329
+ return {
1330
+ type: 'exists',
1331
+ subquery,
1332
+ loc: _createLoc(existsToken, endToken)
1333
+ };
1334
+ }
1335
+ // Literals
1336
+ if (this.match(TokenType.INTEGER, TokenType.FLOAT, TokenType.STRING, TokenType.NULL, TokenType.TRUE, TokenType.FALSE, TokenType.BLOB)) {
1337
+ const token = this.previous();
1338
+ let value;
1339
+ let lexeme = undefined;
1340
+ if (token.type === TokenType.NULL) {
1341
+ value = null;
1342
+ lexeme = token.lexeme; // Store original case (NULL vs null)
1343
+ }
1344
+ else if (token.type === TokenType.TRUE) {
1345
+ value = true;
1346
+ lexeme = token.lexeme; // Store original case (TRUE vs true)
1347
+ }
1348
+ else if (token.type === TokenType.FALSE) {
1349
+ value = false;
1350
+ lexeme = token.lexeme; // Store original case (FALSE vs false)
1351
+ }
1352
+ else if (token.type === TokenType.FLOAT) {
1353
+ // For FLOAT, parse the literal (which is the original string)
1354
+ value = parseFloat(token.literal);
1355
+ lexeme = token.literal; // Store original string as lexeme
1356
+ }
1357
+ else if (token.type === TokenType.INTEGER) {
1358
+ value = token.literal; // Already number or BigInt
1359
+ if (token.lexeme !== String(value)) { // Store lexeme only if different
1360
+ lexeme = token.lexeme;
1361
+ }
1362
+ }
1363
+ else {
1364
+ value = token.literal; // STRING, BLOB
1365
+ }
1366
+ const node = { type: 'literal', value, loc: _createLoc(startToken, token) };
1367
+ if (lexeme !== undefined) {
1368
+ node.lexeme = lexeme;
1369
+ }
1370
+ return node;
1371
+ }
1372
+ // Parameter expressions (?, :name, $name)
1373
+ if (this.match(TokenType.QUESTION)) {
1374
+ const token = this.previous();
1375
+ return { type: 'parameter', index: this.parameterPosition++, loc: _createLoc(startToken, token) };
1376
+ }
1377
+ if (this.match(TokenType.COLON, TokenType.DOLLAR)) {
1378
+ // Named parameter (can be identifier like :name or integer like :1)
1379
+ if (!this.check(TokenType.IDENTIFIER) && !this.check(TokenType.INTEGER)) {
1380
+ throw this.error(this.peek(), "Expected identifier or number after parameter prefix.");
1381
+ }
1382
+ const nameToken = this.advance();
1383
+ return { type: 'parameter', name: nameToken.lexeme, loc: _createLoc(startToken, nameToken) };
1384
+ }
1385
+ // Function call (with optional window function support)
1386
+ if (this.checkIdentifierLike(['key', 'action', 'set', 'default', 'check', 'unique', 'references', 'on', 'cascade', 'restrict', 'like']) && this.checkNext(1, TokenType.LPAREN)) {
1387
+ const name = this.consumeIdentifier(['key', 'action', 'set', 'default', 'check', 'unique', 'references', 'on', 'cascade', 'restrict', 'like'], "Expected function name.");
1388
+ this.consume(TokenType.LPAREN, "Expected '(' after function name.");
1389
+ const args = [];
1390
+ let distinct = false;
1391
+ if (!this.check(TokenType.RPAREN)) {
1392
+ // Handle DISTINCT inside function calls like COUNT(DISTINCT col)
1393
+ distinct = this.matchKeyword('DISTINCT');
1394
+ // Handle * argument AFTER checking for distinct
1395
+ if (this.match(TokenType.ASTERISK)) {
1396
+ // Do not add '*' as an argument to the list for aggregates like COUNT(*)
1397
+ if (args.length > 0 || distinct) {
1398
+ // '*' is only valid as the *only* argument, potentially after DISTINCT
1399
+ // e.g. COUNT(*), COUNT(DISTINCT *) - though DISTINCT * might not be standard SQL?
1400
+ // For now, disallow '*' if other args exist.
1401
+ throw this.error(this.previous(), "'*' cannot be used with other arguments in function call.");
1402
+ }
1403
+ // If we parsed '*', the args list remains empty.
1404
+ }
1405
+ else {
1406
+ // Parse regular arguments if '*' wasn't found
1407
+ do {
1408
+ args.push(this.expression());
1409
+ } while (this.match(TokenType.COMMA));
1410
+ }
1411
+ }
1412
+ const endToken = this.consume(TokenType.RPAREN, "Expected ')' after function arguments.");
1413
+ const funcExpr = {
1414
+ type: 'function',
1415
+ name,
1416
+ args,
1417
+ loc: _createLoc(startToken, endToken)
1418
+ };
1419
+ // Add distinct field if it was parsed
1420
+ if (distinct) {
1421
+ funcExpr.distinct = true;
1422
+ }
1423
+ // Check for OVER clause (window function)
1424
+ if (this.matchKeyword('OVER')) {
1425
+ const window = this.parseWindowSpecification();
1426
+ const overEndToken = this.previous();
1427
+ return {
1428
+ type: 'windowFunction',
1429
+ function: funcExpr,
1430
+ window,
1431
+ loc: _createLoc(startToken, overEndToken)
1432
+ };
1433
+ }
1434
+ return funcExpr;
1435
+ }
1436
+ // Column/identifier expressions
1437
+ const contextualKeywords = ['key', 'action', 'set', 'default', 'check', 'unique', 'references', 'on', 'cascade', 'restrict', 'like'];
1438
+ if (this.checkIdentifierLike(contextualKeywords)) {
1439
+ // Schema.table.column
1440
+ if (this.checkNext(1, TokenType.DOT) && this.checkIdentifierLikeAt(2, contextualKeywords) &&
1441
+ this.checkNext(3, TokenType.DOT) && this.checkIdentifierLikeAt(4, contextualKeywords)) {
1442
+ const schema = this.consumeIdentifier(contextualKeywords, "Expected schema name.");
1443
+ this.advance(); // Consume DOT
1444
+ const table = this.consumeIdentifier(contextualKeywords, "Expected table name.");
1445
+ this.advance(); // Consume DOT
1446
+ const name = this.consumeIdentifier(contextualKeywords, "Expected column name.");
1447
+ const nameToken = this.previous();
1448
+ return {
1449
+ type: 'column',
1450
+ name,
1451
+ table,
1452
+ schema,
1453
+ loc: _createLoc(startToken, nameToken),
1454
+ };
1455
+ }
1456
+ // table.column
1457
+ else if (this.checkNext(1, TokenType.DOT) && this.checkIdentifierLikeAt(2, contextualKeywords)) {
1458
+ const table = this.consumeIdentifier(contextualKeywords, "Expected table name.");
1459
+ this.advance(); // Consume DOT
1460
+ const name = this.consumeIdentifier(contextualKeywords, "Expected column name.");
1461
+ const nameToken = this.previous();
1462
+ return {
1463
+ type: 'column',
1464
+ name,
1465
+ table,
1466
+ loc: _createLoc(startToken, nameToken),
1467
+ };
1468
+ }
1469
+ // just column
1470
+ else {
1471
+ const name = this.consumeIdentifier(contextualKeywords, "Expected column name.");
1472
+ const nameToken = this.previous();
1473
+ return {
1474
+ type: 'column',
1475
+ name,
1476
+ loc: _createLoc(startToken, nameToken),
1477
+ };
1478
+ }
1479
+ }
1480
+ // Parenthesized expression or scalar subquery
1481
+ if (this.match(TokenType.LPAREN)) {
1482
+ // Look ahead to see if this is a scalar subquery (SELECT ...)
1483
+ if (this.check(TokenType.SELECT)) {
1484
+ const selectToken = this.consume(TokenType.SELECT, "Expected 'SELECT' in subquery.");
1485
+ const subquery = this.selectStatement(selectToken);
1486
+ this.consume(TokenType.RPAREN, "Expected ')' after subquery.");
1487
+ return {
1488
+ type: 'subquery',
1489
+ query: subquery,
1490
+ loc: _createLoc(startToken, this.previous())
1491
+ };
1492
+ }
1493
+ else {
1494
+ // Regular parenthesized expression
1495
+ const expr = this.expression();
1496
+ this.consume(TokenType.RPAREN, "Expected ')' after expression.");
1497
+ return expr;
1498
+ }
1499
+ }
1500
+ throw this.error(this.peek(), "Expected expression.");
1501
+ }
1502
+ /**
1503
+ * Parses a window specification: (PARTITION BY ... ORDER BY ... [frame])
1504
+ */
1505
+ parseWindowSpecification() {
1506
+ if (this.match(TokenType.LPAREN)) {
1507
+ let partitionBy;
1508
+ let orderBy;
1509
+ let frame;
1510
+ if (this.matchKeyword('PARTITION')) {
1511
+ this.consumeKeyword('BY', "Expected 'BY' after 'PARTITION'.");
1512
+ partitionBy = [];
1513
+ do {
1514
+ partitionBy.push(this.expression());
1515
+ } while (this.match(TokenType.COMMA));
1516
+ }
1517
+ if (this.matchKeyword('ORDER')) {
1518
+ this.consumeKeyword('BY', "Expected 'BY' after 'ORDER'.");
1519
+ orderBy = [];
1520
+ do {
1521
+ const expr = this.expression();
1522
+ const direction = this.match(TokenType.DESC) ? 'desc' : (this.match(TokenType.ASC) ? 'asc' : 'asc');
1523
+ // Handle NULLS FIRST/LAST
1524
+ let nullsOrdering;
1525
+ if (this.matchKeyword('NULLS')) {
1526
+ if (this.matchKeyword('FIRST')) {
1527
+ nullsOrdering = 'first';
1528
+ }
1529
+ else if (this.matchKeyword('LAST')) {
1530
+ nullsOrdering = 'last';
1531
+ }
1532
+ else {
1533
+ throw this.error(this.peek(), "Expected 'FIRST' or 'LAST' after 'NULLS'.");
1534
+ }
1535
+ }
1536
+ const orderClause = { expr, direction };
1537
+ if (nullsOrdering) {
1538
+ orderClause.nullsOrdering = nullsOrdering;
1539
+ }
1540
+ orderBy.push(orderClause);
1541
+ } while (this.match(TokenType.COMMA));
1542
+ }
1543
+ // Frame clause (ROWS|RANGE ...)
1544
+ if (this.matchKeyword('ROWS') || this.matchKeyword('RANGE')) {
1545
+ const frameType = this.previous().lexeme.toLowerCase();
1546
+ // Handle both BETWEEN...AND and single bound syntax
1547
+ if (this.matchKeyword('BETWEEN')) {
1548
+ // ROWS BETWEEN start_bound AND end_bound
1549
+ const start = this.parseWindowFrameBound();
1550
+ this.consumeKeyword('AND', "Expected 'AND' after frame start bound.");
1551
+ const end = this.parseWindowFrameBound();
1552
+ frame = { type: frameType, start, end };
1553
+ }
1554
+ else {
1555
+ // ROWS start_bound (shorthand for ROWS BETWEEN start_bound AND CURRENT ROW)
1556
+ const start = this.parseWindowFrameBound();
1557
+ frame = { type: frameType, start, end: null };
1558
+ }
1559
+ }
1560
+ this.consume(TokenType.RPAREN, "Expected ')' after window specification.");
1561
+ return { type: 'windowDefinition', partitionBy, orderBy, frame };
1562
+ }
1563
+ else {
1564
+ // Window name (not implemented)
1565
+ throw this.error(this.peek(), 'Window name references are not yet supported. Use explicit window specs.');
1566
+ }
1567
+ }
1568
+ /**
1569
+ * Parses a window frame bound (UNBOUNDED PRECEDING, CURRENT ROW, n PRECEDING/FOLLOWING)
1570
+ */
1571
+ parseWindowFrameBound() {
1572
+ if (this.matchKeyword('UNBOUNDED')) {
1573
+ if (this.matchKeyword('PRECEDING')) {
1574
+ return { type: 'unboundedPreceding' };
1575
+ }
1576
+ else if (this.matchKeyword('FOLLOWING')) {
1577
+ return { type: 'unboundedFollowing' };
1578
+ }
1579
+ else {
1580
+ throw this.error(this.peek(), "Expected PRECEDING or FOLLOWING after UNBOUNDED.");
1581
+ }
1582
+ }
1583
+ else if (this.matchKeyword('CURRENT')) {
1584
+ this.consumeKeyword('ROW', "Expected 'ROW' after 'CURRENT'.");
1585
+ return { type: 'currentRow' };
1586
+ }
1587
+ else {
1588
+ const value = this.expression();
1589
+ if (this.matchKeyword('PRECEDING')) {
1590
+ return { type: 'preceding', value };
1591
+ }
1592
+ else if (this.matchKeyword('FOLLOWING')) {
1593
+ return { type: 'following', value };
1594
+ }
1595
+ else {
1596
+ throw this.error(this.peek(), "Expected PRECEDING or FOLLOWING after frame value.");
1597
+ }
1598
+ }
1599
+ }
1600
+ // Helper methods for token management
1601
+ match(...types) {
1602
+ for (const type of types) {
1603
+ if (this.check(type)) {
1604
+ this.advance();
1605
+ return true;
1606
+ }
1607
+ }
1608
+ return false;
1609
+ }
1610
+ consume(type, message) {
1611
+ if (this.check(type)) {
1612
+ return this.advance();
1613
+ }
1614
+ this.error(this.peek(), message);
1615
+ }
1616
+ check(type) {
1617
+ if (this.isAtEnd())
1618
+ return false;
1619
+ return this.peek().type === type;
1620
+ }
1621
+ checkNext(n, type) {
1622
+ if (this.current + n >= this.tokens.length)
1623
+ return false;
1624
+ return this.tokens[this.current + n].type === type;
1625
+ }
1626
+ advance() {
1627
+ if (!this.isAtEnd())
1628
+ this.current++;
1629
+ return this.previous();
1630
+ }
1631
+ isAtEnd() {
1632
+ return this.peek().type === TokenType.EOF;
1633
+ }
1634
+ peek() {
1635
+ return this.tokens[this.current];
1636
+ }
1637
+ previous() {
1638
+ return this.tokens[this.current - 1];
1639
+ }
1640
+ error(token, message) {
1641
+ quereusError(message, StatusCode.ERROR, undefined, {
1642
+ loc: {
1643
+ start: {
1644
+ line: token.startLine,
1645
+ column: token.startColumn,
1646
+ },
1647
+ end: {
1648
+ line: token.endLine,
1649
+ column: token.endColumn,
1650
+ }
1651
+ }
1652
+ });
1653
+ }
1654
+ isJoinToken() {
1655
+ return this.check(TokenType.JOIN) ||
1656
+ this.check(TokenType.INNER) ||
1657
+ this.check(TokenType.LEFT) ||
1658
+ this.check(TokenType.RIGHT) ||
1659
+ this.check(TokenType.FULL) ||
1660
+ this.check(TokenType.CROSS);
1661
+ }
1662
+ isEndOfClause() {
1663
+ const token = this.peek().type;
1664
+ return token === TokenType.FROM ||
1665
+ token === TokenType.WHERE ||
1666
+ token === TokenType.GROUP ||
1667
+ token === TokenType.HAVING ||
1668
+ token === TokenType.ORDER ||
1669
+ token === TokenType.LIMIT ||
1670
+ token === TokenType.UNION ||
1671
+ token === TokenType.SEMICOLON ||
1672
+ token === TokenType.EOF;
1673
+ }
1674
+ // --- Statement Parsing Stubs ---
1675
+ /** @internal */
1676
+ updateStatement(startToken, _withClause) {
1677
+ const table = this.tableIdentifier();
1678
+ this.consume(TokenType.SET, "Expected 'SET' after table name in UPDATE.");
1679
+ const assignments = [];
1680
+ do {
1681
+ const column = this.consumeIdentifier(['key', 'action', 'set', 'default', 'check', 'unique', 'references', 'on', 'cascade', 'restrict', 'like'], "Expected column name in SET clause.");
1682
+ this.consume(TokenType.EQUAL, "Expected '=' after column name in SET clause.");
1683
+ const value = this.expression();
1684
+ assignments.push({ column, value });
1685
+ } while (this.match(TokenType.COMMA));
1686
+ let where;
1687
+ if (this.match(TokenType.WHERE)) {
1688
+ where = this.expression();
1689
+ }
1690
+ // Parse RETURNING clause if present
1691
+ let returning;
1692
+ if (this.matchKeyword('RETURNING')) {
1693
+ returning = this.columnList();
1694
+ }
1695
+ const endToken = this.previous();
1696
+ return { type: 'update', table, assignments, where, returning, loc: _createLoc(startToken, endToken) };
1697
+ }
1698
+ /** @internal */
1699
+ deleteStatement(startToken, _withClause) {
1700
+ this.matchKeyword('FROM');
1701
+ const table = this.tableIdentifier();
1702
+ let where;
1703
+ if (this.match(TokenType.WHERE)) {
1704
+ where = this.expression();
1705
+ }
1706
+ // Parse RETURNING clause if present
1707
+ let returning;
1708
+ if (this.matchKeyword('RETURNING')) {
1709
+ returning = this.columnList();
1710
+ }
1711
+ const endToken = this.previous();
1712
+ return { type: 'delete', table, where, returning, loc: _createLoc(startToken, endToken) };
1713
+ }
1714
+ /** @internal */
1715
+ valuesStatement(startToken) {
1716
+ const values = [];
1717
+ do {
1718
+ this.consume(TokenType.LPAREN, "Expected '(' before values.");
1719
+ const valueList = [];
1720
+ if (!this.check(TokenType.RPAREN)) { // Check for empty value list
1721
+ do {
1722
+ valueList.push(this.expression());
1723
+ } while (this.match(TokenType.COMMA));
1724
+ }
1725
+ this.consume(TokenType.RPAREN, "Expected ')' after values.");
1726
+ values.push(valueList);
1727
+ } while (this.match(TokenType.COMMA));
1728
+ const endToken = this.previous();
1729
+ return { type: 'values', values, loc: _createLoc(startToken, endToken) };
1730
+ }
1731
+ /** @internal */
1732
+ createStatement(startToken, withClause) {
1733
+ if (this.peekKeyword('TABLE')) {
1734
+ this.consumeKeyword('TABLE', "Expected 'TABLE' after CREATE.");
1735
+ return this.createTableStatement(startToken, withClause);
1736
+ }
1737
+ else if (this.peekKeyword('INDEX')) {
1738
+ this.consumeKeyword('INDEX', "Expected 'INDEX' after CREATE.");
1739
+ return this.createIndexStatement(startToken, false, withClause);
1740
+ }
1741
+ else if (this.peekKeyword('VIEW')) {
1742
+ this.consumeKeyword('VIEW', "Expected 'VIEW' after CREATE.");
1743
+ return this.createViewStatement(startToken, withClause);
1744
+ }
1745
+ else if (this.peekKeyword('UNIQUE')) {
1746
+ this.consumeKeyword('UNIQUE', "Expected 'UNIQUE' after CREATE.");
1747
+ this.consumeKeyword('INDEX', "Expected 'INDEX' after CREATE UNIQUE.");
1748
+ return this.createIndexStatement(startToken, true, withClause);
1749
+ }
1750
+ throw this.error(this.peek(), "Expected TABLE, [UNIQUE] INDEX, VIEW, or VIRTUAL after CREATE.");
1751
+ }
1752
+ /**
1753
+ * Parse CREATE TABLE statement
1754
+ * @returns AST for CREATE TABLE
1755
+ */
1756
+ createTableStatement(startToken, _withClause) {
1757
+ let isTemporary = false;
1758
+ if (this.peekKeyword('TEMP') || this.peekKeyword('TEMPORARY')) {
1759
+ isTemporary = true;
1760
+ this.advance();
1761
+ }
1762
+ let ifNotExists = false;
1763
+ if (this.matchKeyword('IF')) {
1764
+ this.consumeKeyword('NOT', "Expected 'NOT' after 'IF'.");
1765
+ this.consumeKeyword('EXISTS', "Expected 'EXISTS' after 'IF NOT'.");
1766
+ ifNotExists = true;
1767
+ }
1768
+ const table = this.tableIdentifier();
1769
+ const columns = [];
1770
+ const constraints = [];
1771
+ if (this.check(TokenType.LPAREN)) {
1772
+ this.consume(TokenType.LPAREN, "Expected '(' to start table definition.");
1773
+ do {
1774
+ if (this.peekKeyword('PRIMARY') || this.peekKeyword('UNIQUE') || this.peekKeyword('CHECK') || this.peekKeyword('FOREIGN') || this.peekKeyword('CONSTRAINT')) {
1775
+ constraints.push(this.tableConstraint());
1776
+ }
1777
+ else {
1778
+ columns.push(this.columnDefinition());
1779
+ }
1780
+ } while (this.match(TokenType.COMMA));
1781
+ this.consume(TokenType.RPAREN, "Expected ')' after table definition.");
1782
+ }
1783
+ else if (this.matchKeyword('AS')) {
1784
+ const token = this.previous();
1785
+ quereusError('CREATE TABLE AS SELECT is not supported.', StatusCode.UNSUPPORTED, undefined, { loc: { start: { line: token.startLine, column: token.startColumn } } });
1786
+ }
1787
+ else {
1788
+ throw this.error(this.peek(), "Expected '(' or 'AS' after table name.");
1789
+ }
1790
+ let moduleName;
1791
+ const moduleArgs = {};
1792
+ if (this.matchKeyword('USING')) {
1793
+ moduleName = this.consumeIdentifier("Expected module name after 'USING'.");
1794
+ if (this.matchKeyword('(')) {
1795
+ while (!this.match(TokenType.RPAREN)) {
1796
+ const nameValue = this.nameValueItem("module argument");
1797
+ moduleArgs[nameValue.name] = nameValue.value && nameValue.value.type === 'literal'
1798
+ ? getSyncLiteral(nameValue.value) : nameValue.name;
1799
+ if (!this.match(TokenType.COMMA) || this.check(TokenType.RPAREN)) {
1800
+ throw this.error(this.peek(), "Expected ',' or ')' after module argument.");
1801
+ }
1802
+ }
1803
+ }
1804
+ }
1805
+ return {
1806
+ type: 'createTable',
1807
+ table,
1808
+ ifNotExists,
1809
+ columns,
1810
+ constraints,
1811
+ isTemporary,
1812
+ moduleName,
1813
+ moduleArgs,
1814
+ loc: _createLoc(startToken, this.previous()),
1815
+ };
1816
+ }
1817
+ /**
1818
+ * Parse CREATE INDEX statement
1819
+ * @param isUnique Flag indicating if UNIQUE keyword was already parsed
1820
+ * @returns AST for CREATE INDEX
1821
+ */
1822
+ createIndexStatement(startToken, isUnique = false, _withClause) {
1823
+ if (!isUnique && this.peekKeyword('UNIQUE')) {
1824
+ isUnique = true;
1825
+ this.advance();
1826
+ }
1827
+ let ifNotExists = false;
1828
+ if (this.matchKeyword('IF')) {
1829
+ this.consumeKeyword('NOT', "Expected 'NOT' after 'IF'.");
1830
+ this.consumeKeyword('EXISTS', "Expected 'EXISTS' after 'IF NOT'.");
1831
+ ifNotExists = true;
1832
+ }
1833
+ const index = this.tableIdentifier();
1834
+ this.consumeKeyword('ON', "Expected 'ON' after index name.");
1835
+ const table = this.tableIdentifier();
1836
+ this.consume(TokenType.LPAREN, "Expected '(' before indexed columns.");
1837
+ const columns = this.indexedColumnList();
1838
+ this.consume(TokenType.RPAREN, "Expected ')' after indexed columns.");
1839
+ let where;
1840
+ if (this.matchKeyword('WHERE')) {
1841
+ where = this.expression();
1842
+ }
1843
+ return {
1844
+ type: 'createIndex',
1845
+ index,
1846
+ table,
1847
+ ifNotExists,
1848
+ columns,
1849
+ where,
1850
+ isUnique,
1851
+ loc: _createLoc(startToken, this.previous()),
1852
+ };
1853
+ }
1854
+ /**
1855
+ * Parse CREATE VIEW statement
1856
+ * @returns AST for CREATE VIEW
1857
+ */
1858
+ createViewStatement(startToken, withClause) {
1859
+ let isTemporary = false;
1860
+ if (this.peekKeyword('TEMP') || this.peekKeyword('TEMPORARY')) {
1861
+ isTemporary = true;
1862
+ this.advance();
1863
+ }
1864
+ let ifNotExists = false;
1865
+ if (this.matchKeyword('IF')) {
1866
+ this.consumeKeyword('NOT', "Expected 'NOT' after 'IF'.");
1867
+ this.consumeKeyword('EXISTS', "Expected 'EXISTS' after 'IF NOT'.");
1868
+ ifNotExists = true;
1869
+ }
1870
+ const view = this.tableIdentifier();
1871
+ let columns;
1872
+ if (this.check(TokenType.LPAREN)) {
1873
+ this.consume(TokenType.LPAREN, "Expected '(' to start view column list.");
1874
+ columns = [];
1875
+ const contextualKeywords = ['key', 'action', 'set', 'default', 'check', 'unique', 'references', 'on', 'cascade', 'restrict', 'like'];
1876
+ if (!this.check(TokenType.RPAREN)) {
1877
+ do {
1878
+ columns.push(this.consumeIdentifier(contextualKeywords, "Expected column name in view column list."));
1879
+ } while (this.match(TokenType.COMMA));
1880
+ }
1881
+ this.consume(TokenType.RPAREN, "Expected ')' after view column list.");
1882
+ }
1883
+ this.consumeKeyword('AS', "Expected 'AS' before SELECT statement for CREATE VIEW.");
1884
+ const selectStartToken = this.consume(TokenType.SELECT, "Expected 'SELECT' after 'AS' in CREATE VIEW.");
1885
+ const select = this.selectStatement(selectStartToken, withClause);
1886
+ return {
1887
+ type: 'createView',
1888
+ view,
1889
+ ifNotExists,
1890
+ columns,
1891
+ select,
1892
+ isTemporary,
1893
+ loc: _createLoc(startToken, this.previous()),
1894
+ };
1895
+ }
1896
+ /**
1897
+ * Parse DROP statement
1898
+ * @returns AST for DROP statement
1899
+ */
1900
+ dropStatement(startToken, _withClause) {
1901
+ let objectType;
1902
+ if (this.peekKeyword('TABLE')) {
1903
+ this.consumeKeyword('TABLE', "Expected TABLE after DROP.");
1904
+ objectType = 'table';
1905
+ }
1906
+ else if (this.peekKeyword('VIEW')) {
1907
+ this.consumeKeyword('VIEW', "Expected VIEW after DROP.");
1908
+ objectType = 'view';
1909
+ }
1910
+ else if (this.peekKeyword('INDEX')) {
1911
+ this.consumeKeyword('INDEX', "Expected INDEX after DROP.");
1912
+ objectType = 'index';
1913
+ }
1914
+ else {
1915
+ throw this.error(this.peek(), "Expected TABLE, VIEW, or INDEX after DROP.");
1916
+ }
1917
+ let ifExists = false;
1918
+ if (this.matchKeyword('IF')) {
1919
+ this.consumeKeyword('EXISTS', "Expected 'EXISTS' after 'IF'.");
1920
+ ifExists = true;
1921
+ }
1922
+ const name = this.tableIdentifier();
1923
+ return {
1924
+ type: 'drop',
1925
+ objectType,
1926
+ name,
1927
+ ifExists,
1928
+ loc: _createLoc(startToken, this.previous()),
1929
+ };
1930
+ }
1931
+ /**
1932
+ * Parse ALTER TABLE statement
1933
+ * @returns AST for ALTER TABLE statement
1934
+ */
1935
+ alterTableStatement(startToken, _withClause) {
1936
+ this.consumeKeyword('TABLE', "Expected 'TABLE' after ALTER.");
1937
+ const table = this.tableIdentifier();
1938
+ let action;
1939
+ if (this.peekKeyword('RENAME')) {
1940
+ this.consumeKeyword('RENAME', "Expected RENAME.");
1941
+ if (this.matchKeyword('COLUMN')) {
1942
+ const oldName = this.consumeIdentifier(['key', 'action', 'set', 'default', 'check', 'unique', 'references', 'on', 'cascade', 'restrict', 'like'], "Expected old column name after RENAME COLUMN.");
1943
+ this.consumeKeyword('TO', "Expected 'TO' after old column name.");
1944
+ const newName = this.consumeIdentifier(['key', 'action', 'set', 'default', 'check', 'unique', 'references', 'on', 'cascade', 'restrict', 'like'], "Expected new column name after TO.");
1945
+ action = { type: 'renameColumn', oldName, newName };
1946
+ }
1947
+ else {
1948
+ this.consumeKeyword('TO', "Expected 'TO' after RENAME.");
1949
+ const newName = this.consumeIdentifier(['key', 'action', 'set', 'default', 'check', 'unique', 'references', 'on', 'cascade', 'restrict', 'like'], "Expected new table name after RENAME TO.");
1950
+ action = { type: 'renameTable', newName };
1951
+ }
1952
+ }
1953
+ else if (this.peekKeyword('ADD')) {
1954
+ this.consumeKeyword('ADD', "Expected ADD.");
1955
+ if (this.peekKeyword('CONSTRAINT')) {
1956
+ // ADD CONSTRAINT ... - let tableConstraint parse everything including CONSTRAINT keyword
1957
+ const constraint = this.tableConstraint();
1958
+ action = { type: 'addConstraint', constraint };
1959
+ }
1960
+ else {
1961
+ // ADD [COLUMN] column_def
1962
+ this.matchKeyword('COLUMN');
1963
+ const column = this.columnDefinition();
1964
+ action = { type: 'addColumn', column };
1965
+ }
1966
+ }
1967
+ else if (this.peekKeyword('DROP')) {
1968
+ this.consumeKeyword('DROP', "Expected DROP.");
1969
+ this.matchKeyword('COLUMN');
1970
+ const name = this.consumeIdentifier(['key', 'action', 'set', 'default', 'check', 'unique', 'references', 'on', 'cascade', 'restrict', 'like'], "Expected column name after DROP COLUMN.");
1971
+ action = { type: 'dropColumn', name };
1972
+ }
1973
+ else {
1974
+ throw this.error(this.peek(), "Expected RENAME, ADD, or DROP after table name in ALTER TABLE.");
1975
+ }
1976
+ return {
1977
+ type: 'alterTable',
1978
+ table,
1979
+ action,
1980
+ loc: _createLoc(startToken, this.previous()),
1981
+ };
1982
+ }
1983
+ /**
1984
+ * Parse BEGIN statement
1985
+ * @returns AST for BEGIN statement
1986
+ */
1987
+ beginStatement(startToken, _withClause) {
1988
+ let mode;
1989
+ if (this.peekKeyword('DEFERRED')) {
1990
+ this.advance();
1991
+ mode = 'deferred';
1992
+ }
1993
+ else if (this.peekKeyword('IMMEDIATE')) {
1994
+ this.advance();
1995
+ mode = 'immediate';
1996
+ }
1997
+ else if (this.peekKeyword('EXCLUSIVE')) {
1998
+ this.advance();
1999
+ mode = 'exclusive';
2000
+ }
2001
+ this.matchKeyword('TRANSACTION');
2002
+ return { type: 'begin', mode, loc: _createLoc(startToken, this.previous()) };
2003
+ }
2004
+ /**
2005
+ * Parse COMMIT statement
2006
+ * @returns AST for COMMIT statement
2007
+ */
2008
+ commitStatement(startToken, _withClause) {
2009
+ this.matchKeyword('TRANSACTION');
2010
+ return { type: 'commit', loc: _createLoc(startToken, this.previous()) };
2011
+ }
2012
+ /**
2013
+ * Parse ROLLBACK statement
2014
+ * @returns AST for ROLLBACK statement
2015
+ */
2016
+ rollbackStatement(startToken, _withClause) {
2017
+ this.matchKeyword('TRANSACTION');
2018
+ let savepoint;
2019
+ if (this.matchKeyword('TO')) {
2020
+ this.matchKeyword('SAVEPOINT');
2021
+ if (!this.check(TokenType.IDENTIFIER)) {
2022
+ throw this.error(this.peek(), "Expected savepoint name after ROLLBACK TO.");
2023
+ }
2024
+ savepoint = this.advance().lexeme;
2025
+ }
2026
+ return { type: 'rollback', savepoint, loc: _createLoc(startToken, this.previous()) };
2027
+ }
2028
+ /**
2029
+ * Parse SAVEPOINT statement
2030
+ * @returns AST for SAVEPOINT statement
2031
+ */
2032
+ savepointStatement(startToken, _withClause) {
2033
+ const name = this.consumeIdentifier("Expected savepoint name after SAVEPOINT.");
2034
+ return { type: 'savepoint', name, loc: _createLoc(startToken, this.previous()) };
2035
+ }
2036
+ /**
2037
+ * Parse RELEASE statement
2038
+ * @returns AST for RELEASE statement
2039
+ */
2040
+ releaseStatement(startToken, _withClause) {
2041
+ this.matchKeyword('SAVEPOINT');
2042
+ const name = this.consumeIdentifier("Expected savepoint name after RELEASE [SAVEPOINT].");
2043
+ return { type: 'release', savepoint: name, loc: _createLoc(startToken, this.previous()) };
2044
+ }
2045
+ /**
2046
+ * Parse PRAGMA statement
2047
+ * @returns AST for PRAGMA statement
2048
+ */
2049
+ pragmaStatement(startToken, _withClause) {
2050
+ const nameValue = this.nameValueItem("pragma");
2051
+ return { type: 'pragma', ...nameValue, loc: _createLoc(startToken, this.previous()) };
2052
+ }
2053
+ nameValueItem(context) {
2054
+ const name = this.consumeIdentifier(`Expected ${context} name.`);
2055
+ let value;
2056
+ if (this.match(TokenType.EQUAL)) {
2057
+ if (this.check(TokenType.IDENTIFIER)) {
2058
+ value = { type: 'identifier', name: this.advance().lexeme };
2059
+ }
2060
+ else if (this.match(TokenType.STRING, TokenType.INTEGER, TokenType.FLOAT, TokenType.NULL, TokenType.TRUE, TokenType.FALSE)) {
2061
+ const token = this.previous();
2062
+ let literal_value;
2063
+ if (token.type === TokenType.NULL) {
2064
+ literal_value = null;
2065
+ }
2066
+ else if (token.type === TokenType.TRUE) {
2067
+ literal_value = 1;
2068
+ }
2069
+ else if (token.type === TokenType.FALSE) {
2070
+ literal_value = 0;
2071
+ }
2072
+ else {
2073
+ literal_value = token.literal;
2074
+ }
2075
+ value = { type: 'literal', value: literal_value };
2076
+ }
2077
+ else if (this.match(TokenType.MINUS)) {
2078
+ if (this.check(TokenType.INTEGER) || this.check(TokenType.FLOAT)) {
2079
+ const token = this.advance();
2080
+ value = { type: 'literal', value: -token.literal };
2081
+ }
2082
+ else {
2083
+ throw this.error(this.peek(), "Expected number after '-'.");
2084
+ }
2085
+ }
2086
+ else {
2087
+ throw this.error(this.peek(), `Expected ${context} value (identifier, string, number, or NULL).`);
2088
+ }
2089
+ }
2090
+ // If no '=' is found, value remains undefined (reading mode)
2091
+ return { name: name.toLowerCase(), value };
2092
+ }
2093
+ // --- Supporting Clause / Definition Parsers ---
2094
+ /** @internal Parses a comma-separated list of indexed columns */
2095
+ indexedColumnList() {
2096
+ const columns = [];
2097
+ do {
2098
+ columns.push(this.indexedColumn());
2099
+ } while (this.match(TokenType.COMMA));
2100
+ return columns;
2101
+ }
2102
+ /** @internal Parses a single indexed column definition */
2103
+ indexedColumn() {
2104
+ const expr = this.expression();
2105
+ let name;
2106
+ if (expr.type === 'column' && !expr.table && !expr.schema) {
2107
+ name = expr.name;
2108
+ }
2109
+ let direction;
2110
+ if (this.match(TokenType.ASC)) {
2111
+ direction = 'asc';
2112
+ }
2113
+ else if (this.match(TokenType.DESC)) {
2114
+ direction = 'desc';
2115
+ }
2116
+ if (name) {
2117
+ return { name, direction };
2118
+ }
2119
+ else {
2120
+ return { expr, direction };
2121
+ }
2122
+ }
2123
+ consumeIdentifier(errorMessageOrKeywords, errorMessage) {
2124
+ if (typeof errorMessageOrKeywords === 'string') {
2125
+ // Single parameter version - no contextual keywords
2126
+ return this.consumeIdentifierOrContextualKeyword([], errorMessageOrKeywords);
2127
+ }
2128
+ else {
2129
+ // Two parameter version - with contextual keywords
2130
+ return this.consumeIdentifierOrContextualKeyword(errorMessageOrKeywords, errorMessage);
2131
+ }
2132
+ }
2133
+ /**
2134
+ * @internal Helper to consume an IDENTIFIER token or specified contextual keywords
2135
+ * @param availableKeywords Array of keyword strings that can be used as identifiers in this context
2136
+ * @param errorMessage Error message if no valid token is found
2137
+ * @returns The lexeme of the consumed token
2138
+ */
2139
+ consumeIdentifierOrContextualKeyword(availableKeywords, errorMessage) {
2140
+ const token = this.peek();
2141
+ // First check for regular identifier
2142
+ if (this.check(TokenType.IDENTIFIER)) {
2143
+ return this.advance().lexeme;
2144
+ }
2145
+ // Then check for available contextual keywords
2146
+ for (const keyword of availableKeywords) {
2147
+ const keywordUpper = keyword.toUpperCase();
2148
+ const expectedTokenType = TokenType[keywordUpper];
2149
+ if (expectedTokenType && token.type === expectedTokenType) {
2150
+ // This keyword token is available as an identifier in this context
2151
+ return this.advance().lexeme;
2152
+ }
2153
+ }
2154
+ throw this.error(this.peek(), errorMessage);
2155
+ }
2156
+ /**
2157
+ * @internal Helper to check if current token is an identifier or available contextual keyword
2158
+ */
2159
+ checkIdentifierLike(availableKeywords = []) {
2160
+ if (this.check(TokenType.IDENTIFIER)) {
2161
+ return true;
2162
+ }
2163
+ return this.isContextualKeywordAvailable(availableKeywords);
2164
+ }
2165
+ /**
2166
+ * @internal Helper to check if token at offset is an identifier or available contextual keyword
2167
+ */
2168
+ checkIdentifierLikeAt(offset, availableKeywords = []) {
2169
+ if (this.checkNext(offset, TokenType.IDENTIFIER)) {
2170
+ return true;
2171
+ }
2172
+ if (this.current + offset >= this.tokens.length)
2173
+ return false;
2174
+ const token = this.tokens[this.current + offset];
2175
+ for (const keyword of availableKeywords) {
2176
+ const keywordUpper = keyword.toUpperCase();
2177
+ const expectedTokenType = TokenType[keywordUpper];
2178
+ if (expectedTokenType && token.type === expectedTokenType) {
2179
+ return true;
2180
+ }
2181
+ }
2182
+ return false;
2183
+ }
2184
+ /**
2185
+ * @internal Helper to check if any of the specified contextual keywords are available at current position
2186
+ */
2187
+ isContextualKeywordAvailable(availableKeywords) {
2188
+ const token = this.peek();
2189
+ for (const keyword of availableKeywords) {
2190
+ const keywordUpper = keyword.toUpperCase();
2191
+ const expectedTokenType = TokenType[keywordUpper];
2192
+ if (expectedTokenType && token.type === expectedTokenType) {
2193
+ return true;
2194
+ }
2195
+ }
2196
+ return false;
2197
+ }
2198
+ // --- Stubs for required helpers (implement fully for CREATE TABLE) ---
2199
+ /** @internal Parses a column definition */
2200
+ columnDefinition() {
2201
+ const name = this.consumeIdentifier(['key', 'action', 'set', 'default', 'check', 'unique', 'references', 'on', 'cascade', 'restrict', 'like'], "Expected column name.");
2202
+ let dataType;
2203
+ if (this.check(TokenType.IDENTIFIER)) {
2204
+ dataType = this.advance().lexeme;
2205
+ if (this.match(TokenType.LPAREN)) {
2206
+ dataType += '(';
2207
+ let parenLevel = 1;
2208
+ while (parenLevel > 0 && !this.isAtEnd()) {
2209
+ const token = this.peek();
2210
+ if (token.type === TokenType.LPAREN)
2211
+ parenLevel++;
2212
+ if (token.type === TokenType.RPAREN)
2213
+ parenLevel--;
2214
+ if (parenLevel > 0) {
2215
+ dataType += this.advance().lexeme;
2216
+ }
2217
+ }
2218
+ dataType += ')';
2219
+ this.consume(TokenType.RPAREN, "Expected ')' after type parameters.");
2220
+ }
2221
+ }
2222
+ const constraints = this.columnConstraintList();
2223
+ return { name, dataType, constraints };
2224
+ }
2225
+ /** @internal Parses column constraints */
2226
+ columnConstraintList() {
2227
+ const constraints = [];
2228
+ while (this.isColumnConstraintStart()) {
2229
+ constraints.push(this.columnConstraint());
2230
+ }
2231
+ return constraints;
2232
+ }
2233
+ /** @internal Checks if the current token can start a column constraint */
2234
+ isColumnConstraintStart() {
2235
+ return this.check(TokenType.CONSTRAINT) ||
2236
+ this.check(TokenType.PRIMARY) ||
2237
+ this.check(TokenType.NOT) ||
2238
+ this.check(TokenType.NULL) ||
2239
+ this.check(TokenType.UNIQUE) ||
2240
+ this.check(TokenType.CHECK) ||
2241
+ this.check(TokenType.DEFAULT) ||
2242
+ this.check(TokenType.COLLATE) ||
2243
+ this.check(TokenType.REFERENCES) ||
2244
+ this.check(TokenType.GENERATED);
2245
+ }
2246
+ /** @internal Parses a single column constraint */
2247
+ columnConstraint() {
2248
+ let name;
2249
+ const startToken = this.peek(); // Capture start token
2250
+ let endToken = startToken; // Initialize end token
2251
+ if (this.match(TokenType.CONSTRAINT)) {
2252
+ name = this.consumeIdentifier("Expected constraint name after CONSTRAINT.");
2253
+ endToken = this.previous();
2254
+ }
2255
+ if (this.match(TokenType.PRIMARY)) {
2256
+ this.consume(TokenType.KEY, "Expected KEY after PRIMARY.");
2257
+ const direction = this.match(TokenType.ASC) ? 'asc' : this.match(TokenType.DESC) ? 'desc' : undefined;
2258
+ if (direction)
2259
+ endToken = this.previous();
2260
+ const onConflict = this.parseConflictClause();
2261
+ if (onConflict)
2262
+ endToken = this.previous(); // Update endToken if conflict clause was parsed
2263
+ const autoincrement = this.match(TokenType.AUTOINCREMENT);
2264
+ if (autoincrement)
2265
+ endToken = this.previous();
2266
+ return { type: 'primaryKey', name, onConflict, autoincrement, direction, loc: _createLoc(startToken, endToken) };
2267
+ }
2268
+ else if (this.match(TokenType.NOT)) {
2269
+ this.consume(TokenType.NULL, "Expected NULL after NOT.");
2270
+ endToken = this.previous();
2271
+ const onConflict = this.parseConflictClause();
2272
+ if (onConflict)
2273
+ endToken = this.previous(); // Update endToken if conflict clause was parsed
2274
+ return { type: 'notNull', name, onConflict, loc: _createLoc(startToken, endToken) };
2275
+ }
2276
+ else if (this.match(TokenType.NULL)) {
2277
+ endToken = this.previous();
2278
+ const onConflict = this.parseConflictClause();
2279
+ if (onConflict)
2280
+ endToken = this.previous(); // Update endToken if conflict clause was parsed
2281
+ return { type: 'null', name, onConflict, loc: _createLoc(startToken, endToken) };
2282
+ }
2283
+ else if (this.match(TokenType.UNIQUE)) {
2284
+ endToken = this.previous();
2285
+ const onConflict = this.parseConflictClause();
2286
+ if (onConflict)
2287
+ endToken = this.previous(); // Update endToken if conflict clause was parsed
2288
+ return { type: 'unique', name, onConflict, loc: _createLoc(startToken, endToken) };
2289
+ }
2290
+ else if (this.match(TokenType.CHECK)) {
2291
+ // --- Parse optional ON clause before parentheses --- //
2292
+ let operations;
2293
+ if (this.matchKeyword('ON')) {
2294
+ operations = this.parseRowOpList();
2295
+ }
2296
+ // --- End Parse ON clause --- //
2297
+ this.consume(TokenType.LPAREN, "Expected '(' after CHECK.");
2298
+ const expr = this.expression();
2299
+ endToken = this.consume(TokenType.RPAREN, "Expected ')' after CHECK expression.");
2300
+ return { type: 'check', name, expr, operations, loc: _createLoc(startToken, endToken) };
2301
+ }
2302
+ else if (this.match(TokenType.DEFAULT)) {
2303
+ const expr = this.expression();
2304
+ endToken = this.previous();
2305
+ return { type: 'default', name, expr, loc: _createLoc(startToken, endToken) };
2306
+ }
2307
+ else if (this.match(TokenType.COLLATE)) {
2308
+ if (!this.check(TokenType.IDENTIFIER)) {
2309
+ throw this.error(this.peek(), "Expected collation name after COLLATE.");
2310
+ }
2311
+ const collation = this.advance().lexeme;
2312
+ endToken = this.previous();
2313
+ return { type: 'collate', name, collation, loc: _createLoc(startToken, endToken) };
2314
+ }
2315
+ else if (this.match(TokenType.REFERENCES)) {
2316
+ const fkClause = this.foreignKeyClause();
2317
+ endToken = this.previous(); // End token is end of FK clause
2318
+ return { type: 'foreignKey', name, foreignKey: fkClause, loc: _createLoc(startToken, endToken) };
2319
+ }
2320
+ else if (this.match(TokenType.GENERATED)) {
2321
+ this.consume(TokenType.ALWAYS, "Expected ALWAYS after GENERATED.");
2322
+ this.consume(TokenType.AS, "Expected AS after GENERATED ALWAYS.");
2323
+ this.consume(TokenType.LPAREN, "Expected '(' after AS.");
2324
+ const expr = this.expression();
2325
+ this.consume(TokenType.RPAREN, "Expected ')' after generated expression.");
2326
+ endToken = this.previous();
2327
+ let stored = false;
2328
+ if (this.match(TokenType.STORED)) {
2329
+ stored = true;
2330
+ endToken = this.previous();
2331
+ }
2332
+ else if (this.match(TokenType.VIRTUAL)) {
2333
+ endToken = this.previous();
2334
+ }
2335
+ return { type: 'generated', name, generated: { expr, stored }, loc: _createLoc(startToken, endToken) };
2336
+ }
2337
+ throw this.error(this.peek(), "Expected column constraint type (PRIMARY KEY, NOT NULL, UNIQUE, CHECK, DEFAULT, COLLATE, REFERENCES, GENERATED).");
2338
+ }
2339
+ /** @internal Parses a table constraint */
2340
+ tableConstraint() {
2341
+ let name;
2342
+ const startToken = this.peek(); // Capture start token
2343
+ let endToken = startToken; // Initialize end token
2344
+ if (this.match(TokenType.CONSTRAINT)) {
2345
+ name = this.consumeIdentifier("Expected constraint name after CONSTRAINT.");
2346
+ endToken = this.previous();
2347
+ }
2348
+ if (this.match(TokenType.PRIMARY)) {
2349
+ this.consume(TokenType.KEY, "Expected KEY after PRIMARY.");
2350
+ this.consume(TokenType.LPAREN, "Expected '(' before PRIMARY KEY columns.");
2351
+ // Handle empty PRIMARY KEY () for singleton tables (Third Manifesto feature)
2352
+ let columns = [];
2353
+ if (!this.check(TokenType.RPAREN)) {
2354
+ columns = this.identifierListWithDirection();
2355
+ }
2356
+ endToken = this.consume(TokenType.RPAREN, "Expected ')' after PRIMARY KEY columns.");
2357
+ const onConflict = this.parseConflictClause();
2358
+ if (onConflict)
2359
+ endToken = this.previous();
2360
+ return { type: 'primaryKey', name, columns, onConflict, loc: _createLoc(startToken, endToken) };
2361
+ }
2362
+ else if (this.match(TokenType.UNIQUE)) {
2363
+ this.consume(TokenType.LPAREN, "Expected '(' before UNIQUE columns.");
2364
+ const columnsSimple = this.identifierList();
2365
+ const columns = columnsSimple.map(name => ({ name }));
2366
+ endToken = this.consume(TokenType.RPAREN, "Expected ')' after UNIQUE columns.");
2367
+ const onConflict = this.parseConflictClause();
2368
+ if (onConflict)
2369
+ endToken = this.previous();
2370
+ return { type: 'unique', name, columns, onConflict, loc: _createLoc(startToken, endToken) };
2371
+ }
2372
+ else if (this.match(TokenType.CHECK)) {
2373
+ // --- Parse optional ON clause before parentheses --- //
2374
+ let operations;
2375
+ if (this.matchKeyword('ON')) {
2376
+ operations = this.parseRowOpList();
2377
+ }
2378
+ // --- End Parse ON clause --- //
2379
+ this.consume(TokenType.LPAREN, "Expected '(' after CHECK.");
2380
+ const expr = this.expression();
2381
+ endToken = this.consume(TokenType.RPAREN, "Expected ')' after CHECK expression.");
2382
+ return { type: 'check', name, expr, operations, loc: _createLoc(startToken, endToken) };
2383
+ }
2384
+ else if (this.match(TokenType.FOREIGN)) {
2385
+ this.consume(TokenType.KEY, "Expected KEY after FOREIGN.");
2386
+ this.consume(TokenType.LPAREN, "Expected '(' before FOREIGN KEY columns.");
2387
+ const columns = this.identifierList().map(name => ({ name }));
2388
+ this.consume(TokenType.RPAREN, "Expected ')' after FOREIGN KEY columns.");
2389
+ const fkClause = this.foreignKeyClause();
2390
+ endToken = this.previous(); // End token is end of FK clause
2391
+ return { type: 'foreignKey', name, columns, foreignKey: fkClause, loc: _createLoc(startToken, endToken) };
2392
+ }
2393
+ throw this.error(this.peek(), "Expected table constraint type (PRIMARY KEY, UNIQUE, CHECK, FOREIGN KEY).");
2394
+ }
2395
+ /** @internal Parses a foreign key clause */
2396
+ foreignKeyClause() {
2397
+ this.consume(TokenType.REFERENCES, "Expected REFERENCES for foreign key.");
2398
+ const table = this.consumeIdentifier("Expected foreign table name.");
2399
+ let columns;
2400
+ if (this.match(TokenType.LPAREN)) {
2401
+ columns = this.identifierList();
2402
+ this.consume(TokenType.RPAREN, "Expected ')' after foreign columns.");
2403
+ }
2404
+ let onDelete;
2405
+ let onUpdate;
2406
+ let deferrable;
2407
+ let initiallyDeferred;
2408
+ while (this.check(TokenType.ON) || this.check(TokenType.DEFERRABLE) || this.check(TokenType.NOT)) {
2409
+ if (this.match(TokenType.ON)) {
2410
+ if (this.match(TokenType.DELETE)) {
2411
+ onDelete = this.parseForeignKeyAction();
2412
+ }
2413
+ else if (this.match(TokenType.UPDATE)) {
2414
+ onUpdate = this.parseForeignKeyAction();
2415
+ }
2416
+ else {
2417
+ throw this.error(this.peek(), "Expected DELETE or UPDATE after ON.");
2418
+ }
2419
+ }
2420
+ else if (this.match(TokenType.DEFERRABLE)) {
2421
+ deferrable = true;
2422
+ if (this.match(TokenType.INITIALLY)) {
2423
+ if (this.match(TokenType.DEFERRED)) {
2424
+ initiallyDeferred = true;
2425
+ }
2426
+ else if (this.match(TokenType.IMMEDIATE)) {
2427
+ initiallyDeferred = false;
2428
+ }
2429
+ else {
2430
+ throw this.error(this.peek(), "Expected DEFERRED or IMMEDIATE after INITIALLY.");
2431
+ }
2432
+ }
2433
+ }
2434
+ else if (this.match(TokenType.NOT)) {
2435
+ this.consume(TokenType.DEFERRABLE, "Expected DEFERRABLE after NOT.");
2436
+ deferrable = false;
2437
+ if (this.match(TokenType.INITIALLY)) {
2438
+ if (this.match(TokenType.DEFERRED)) {
2439
+ initiallyDeferred = true;
2440
+ }
2441
+ else if (this.match(TokenType.IMMEDIATE)) {
2442
+ initiallyDeferred = false;
2443
+ }
2444
+ else {
2445
+ throw this.error(this.peek(), "Expected DEFERRED or IMMEDIATE after INITIALLY.");
2446
+ }
2447
+ }
2448
+ }
2449
+ else {
2450
+ break;
2451
+ }
2452
+ }
2453
+ return { table, columns, onDelete, onUpdate, deferrable, initiallyDeferred };
2454
+ }
2455
+ /** @internal Parses the ON CONFLICT clause */
2456
+ parseConflictClause() {
2457
+ if (this.match(TokenType.ON)) {
2458
+ this.consume(TokenType.CONFLICT, "Expected CONFLICT after ON.");
2459
+ if (this.match(TokenType.ROLLBACK))
2460
+ return ConflictResolution.ROLLBACK;
2461
+ if (this.match(TokenType.ABORT))
2462
+ return ConflictResolution.ABORT;
2463
+ if (this.match(TokenType.FAIL))
2464
+ return ConflictResolution.FAIL;
2465
+ if (this.match(TokenType.IGNORE))
2466
+ return ConflictResolution.IGNORE;
2467
+ if (this.match(TokenType.REPLACE))
2468
+ return ConflictResolution.REPLACE;
2469
+ throw this.error(this.peek(), "Expected conflict resolution algorithm (ROLLBACK, ABORT, FAIL, IGNORE, REPLACE).");
2470
+ }
2471
+ return undefined;
2472
+ }
2473
+ /** @internal Parses the foreign key action */
2474
+ parseForeignKeyAction() {
2475
+ if (this.match(TokenType.SET)) {
2476
+ if (this.match(TokenType.NULL))
2477
+ return 'setNull';
2478
+ if (this.match(TokenType.DEFAULT))
2479
+ return 'setDefault';
2480
+ throw this.error(this.peek(), "Expected NULL or DEFAULT after SET.");
2481
+ }
2482
+ else if (this.match(TokenType.CASCADE)) {
2483
+ return 'cascade';
2484
+ }
2485
+ else if (this.match(TokenType.RESTRICT)) {
2486
+ return 'restrict';
2487
+ }
2488
+ else if (this.match(TokenType.NO)) {
2489
+ this.consume(TokenType.ACTION, "Expected ACTION after NO.");
2490
+ return 'noAction';
2491
+ }
2492
+ throw this.error(this.peek(), "Expected foreign key action (SET NULL, SET DEFAULT, CASCADE, RESTRICT, NO ACTION).");
2493
+ }
2494
+ /** @internal Parses a comma-separated list of identifiers, optionally with ASC/DESC */
2495
+ identifierList() {
2496
+ const identifiers = [];
2497
+ do {
2498
+ identifiers.push(this.consumeIdentifier(['key', 'action', 'set', 'default', 'check', 'unique', 'references', 'on', 'cascade', 'restrict', 'like'], "Expected identifier in list."));
2499
+ } while (this.match(TokenType.COMMA));
2500
+ return identifiers;
2501
+ }
2502
+ /** @internal Parses a comma-separated list of identifiers, optionally with ASC/DESC */
2503
+ identifierListWithDirection() {
2504
+ const identifiers = [];
2505
+ do {
2506
+ const name = this.consumeIdentifier(['key', 'action', 'set', 'default', 'check', 'unique', 'references', 'on', 'cascade', 'restrict', 'like'], "Expected identifier in list.");
2507
+ const direction = this.match(TokenType.ASC) ? 'asc' : this.match(TokenType.DESC) ? 'desc' : undefined;
2508
+ identifiers.push({ name, direction });
2509
+ } while (this.match(TokenType.COMMA));
2510
+ return identifiers;
2511
+ }
2512
+ // --- Helper method to peek keywords case-insensitively ---
2513
+ peekKeyword(keyword) {
2514
+ if (this.isAtEnd())
2515
+ return false;
2516
+ const token = this.peek();
2517
+ // The keyword lookup string should be uppercase to match TokenType enum keys (e.g., TokenType.SELECT)
2518
+ const keywordKey = keyword.toUpperCase();
2519
+ const expectedTokenType = TokenType[keywordKey];
2520
+ // Check if the current token's type is the expected specific keyword TokenType.
2521
+ // This assumes the lexer has already correctly typed true keywords.
2522
+ if (expectedTokenType !== undefined && token.type === expectedTokenType) {
2523
+ return true;
2524
+ }
2525
+ // Fallback: if the token is a generic IDENTIFIER, check if its lexeme matches the keyword.
2526
+ // This handles contextual keywords like FIRST, LAST that aren't reserved keywords.
2527
+ if (token.type === TokenType.IDENTIFIER && token.lexeme.toUpperCase() === keywordKey) {
2528
+ return true;
2529
+ }
2530
+ return false;
2531
+ }
2532
+ // --- Helper method to match keywords case-insensitively ---
2533
+ matchKeyword(keyword) {
2534
+ if (this.isAtEnd())
2535
+ return false;
2536
+ if (this.peekKeyword(keyword)) {
2537
+ this.advance();
2538
+ return true;
2539
+ }
2540
+ return false;
2541
+ }
2542
+ // --- Helper method to consume keywords case-insensitively ---
2543
+ consumeKeyword(keyword, message) {
2544
+ if (this.peekKeyword(keyword)) {
2545
+ return this.advance();
2546
+ }
2547
+ throw this.error(this.peek(), message);
2548
+ }
2549
+ /** Parses the list of operations for CHECK ON */
2550
+ parseRowOpList() {
2551
+ const operations = [];
2552
+ // Parse operations in a comma-separated list
2553
+ do {
2554
+ if (this.match(TokenType.INSERT)) {
2555
+ operations.push('insert');
2556
+ }
2557
+ else if (this.match(TokenType.UPDATE)) {
2558
+ operations.push('update');
2559
+ }
2560
+ else if (this.match(TokenType.DELETE)) {
2561
+ operations.push('delete');
2562
+ }
2563
+ else {
2564
+ throw this.error(this.peek(), "Expected INSERT, UPDATE, or DELETE after ON.");
2565
+ }
2566
+ } while (this.match(TokenType.COMMA));
2567
+ // Optional: Check for duplicates? The design allows them but ignores them.
2568
+ return operations;
2569
+ }
2570
+ /**
2571
+ * Parses a CASE expression
2572
+ * CASE [base_expr] WHEN cond THEN result ... [ELSE else_result] END
2573
+ * CASE WHEN cond THEN result ... [ELSE else_result] END
2574
+ */
2575
+ parseCaseExpression(startToken) {
2576
+ let baseExpr;
2577
+ const whenThenClauses = [];
2578
+ let elseExpr;
2579
+ let endToken = startToken; // Initialize with CASE token
2580
+ // Check if it's CASE expr WHEN ... or CASE WHEN ...
2581
+ if (!this.peekKeyword('WHEN')) { // Changed from checkKeyword
2582
+ baseExpr = this.expression();
2583
+ }
2584
+ while (this.matchKeyword('WHEN')) {
2585
+ const whenCondition = this.expression();
2586
+ this.consumeKeyword('THEN', "Expected 'THEN' after WHEN condition in CASE expression.");
2587
+ const thenResult = this.expression();
2588
+ whenThenClauses.push({ when: whenCondition, then: thenResult });
2589
+ endToken = this.previous(); // Update endToken to the end of the THEN expression
2590
+ }
2591
+ if (whenThenClauses.length === 0) {
2592
+ throw this.error(this.peek(), "CASE expression must have at least one WHEN clause.");
2593
+ }
2594
+ if (this.matchKeyword('ELSE')) {
2595
+ elseExpr = this.expression();
2596
+ endToken = this.previous(); // Update endToken to the end of the ELSE expression
2597
+ }
2598
+ endToken = this.consumeKeyword('END', "Expected 'END' to terminate CASE expression.");
2599
+ return {
2600
+ type: 'case',
2601
+ baseExpr,
2602
+ whenThenClauses,
2603
+ elseExpr,
2604
+ loc: _createLoc(startToken, endToken),
2605
+ };
2606
+ }
2607
+ // Helper to check if a token lexeme is a common type name keyword for CAST
2608
+ isTypeNameKeyword(lexeme) {
2609
+ const typeKeywords = ['TEXT', 'INTEGER', 'REAL', 'BLOB', 'NUMERIC', 'VARCHAR', 'CHAR', 'DATE', 'DATETIME', 'BOOLEAN', 'INT'];
2610
+ return typeKeywords.includes(lexeme.toUpperCase());
2611
+ }
2612
+ statementSupportsWithClause(statement) {
2613
+ return statement.type === 'select' ||
2614
+ statement.type === 'insert' ||
2615
+ statement.type === 'update' ||
2616
+ statement.type === 'delete';
2617
+ }
2618
+ }
2619
+ //# sourceMappingURL=parser.js.map