@quereus/quereus 0.17.0 → 0.18.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 (512) hide show
  1. package/README.md +372 -361
  2. package/dist/src/common/errors.d.ts +2 -18
  3. package/dist/src/common/errors.d.ts.map +1 -1
  4. package/dist/src/common/errors.js +6 -29
  5. package/dist/src/common/errors.js.map +1 -1
  6. package/dist/src/common/types.d.ts +8 -0
  7. package/dist/src/common/types.d.ts.map +1 -1
  8. package/dist/src/common/types.js +20 -0
  9. package/dist/src/common/types.js.map +1 -1
  10. package/dist/src/core/database-assertions.d.ts +19 -2
  11. package/dist/src/core/database-assertions.d.ts.map +1 -1
  12. package/dist/src/core/database-assertions.js +113 -32
  13. package/dist/src/core/database-assertions.js.map +1 -1
  14. package/dist/src/core/database-events.d.ts +17 -0
  15. package/dist/src/core/database-events.d.ts.map +1 -1
  16. package/dist/src/core/database-events.js +36 -0
  17. package/dist/src/core/database-events.js.map +1 -1
  18. package/dist/src/core/database.d.ts +11 -0
  19. package/dist/src/core/database.d.ts.map +1 -1
  20. package/dist/src/core/database.js +178 -85
  21. package/dist/src/core/database.js.map +1 -1
  22. package/dist/src/core/statement.d.ts +6 -0
  23. package/dist/src/core/statement.d.ts.map +1 -1
  24. package/dist/src/core/statement.js +42 -56
  25. package/dist/src/core/statement.js.map +1 -1
  26. package/dist/src/emit/ast-stringify.d.ts +1 -0
  27. package/dist/src/emit/ast-stringify.d.ts.map +1 -1
  28. package/dist/src/emit/ast-stringify.js +12 -2
  29. package/dist/src/emit/ast-stringify.js.map +1 -1
  30. package/dist/src/func/builtins/builtin-window-functions.d.ts.map +1 -1
  31. package/dist/src/func/builtins/builtin-window-functions.js +75 -0
  32. package/dist/src/func/builtins/builtin-window-functions.js.map +1 -1
  33. package/dist/src/func/builtins/conversion.js +9 -12
  34. package/dist/src/func/builtins/conversion.js.map +1 -1
  35. package/dist/src/func/builtins/datetime.js +1 -1
  36. package/dist/src/func/builtins/datetime.js.map +1 -1
  37. package/dist/src/func/builtins/explain.d.ts.map +1 -1
  38. package/dist/src/func/builtins/explain.js +15 -3
  39. package/dist/src/func/builtins/explain.js.map +1 -1
  40. package/dist/src/func/builtins/index.d.ts.map +1 -1
  41. package/dist/src/func/builtins/index.js +1 -11
  42. package/dist/src/func/builtins/index.js.map +1 -1
  43. package/dist/src/func/builtins/json-helpers.js +1 -1
  44. package/dist/src/func/builtins/json-helpers.js.map +1 -1
  45. package/dist/src/func/builtins/json.d.ts.map +1 -1
  46. package/dist/src/func/builtins/json.js +2 -5
  47. package/dist/src/func/builtins/json.js.map +1 -1
  48. package/dist/src/func/builtins/schema.d.ts.map +1 -1
  49. package/dist/src/func/builtins/schema.js +30 -32
  50. package/dist/src/func/builtins/schema.js.map +1 -1
  51. package/dist/src/func/builtins/string.d.ts.map +1 -1
  52. package/dist/src/func/builtins/string.js +40 -64
  53. package/dist/src/func/builtins/string.js.map +1 -1
  54. package/dist/src/func/builtins/timespan.d.ts.map +1 -1
  55. package/dist/src/func/builtins/timespan.js.map +1 -1
  56. package/dist/src/index.d.ts +2 -2
  57. package/dist/src/index.d.ts.map +1 -1
  58. package/dist/src/index.js +2 -2
  59. package/dist/src/index.js.map +1 -1
  60. package/dist/src/parser/ast.d.ts +9 -2
  61. package/dist/src/parser/ast.d.ts.map +1 -1
  62. package/dist/src/parser/lexer.d.ts +1 -0
  63. package/dist/src/parser/lexer.d.ts.map +1 -1
  64. package/dist/src/parser/lexer.js +3 -0
  65. package/dist/src/parser/lexer.js.map +1 -1
  66. package/dist/src/parser/parser.d.ts +11 -1
  67. package/dist/src/parser/parser.d.ts.map +1 -1
  68. package/dist/src/parser/parser.js +75 -135
  69. package/dist/src/parser/parser.js.map +1 -1
  70. package/dist/src/planner/analysis/const-evaluator.d.ts.map +1 -1
  71. package/dist/src/planner/analysis/const-evaluator.js +6 -3
  72. package/dist/src/planner/analysis/const-evaluator.js.map +1 -1
  73. package/dist/src/planner/analysis/constraint-extractor.d.ts +2 -1
  74. package/dist/src/planner/analysis/constraint-extractor.d.ts.map +1 -1
  75. package/dist/src/planner/analysis/constraint-extractor.js +154 -22
  76. package/dist/src/planner/analysis/constraint-extractor.js.map +1 -1
  77. package/dist/src/planner/building/alter-table.d.ts.map +1 -1
  78. package/dist/src/planner/building/alter-table.js +18 -1
  79. package/dist/src/planner/building/alter-table.js.map +1 -1
  80. package/dist/src/planner/building/analyze.d.ts +5 -0
  81. package/dist/src/planner/building/analyze.d.ts.map +1 -0
  82. package/dist/src/planner/building/analyze.js +5 -0
  83. package/dist/src/planner/building/analyze.js.map +1 -0
  84. package/dist/src/planner/building/block.d.ts.map +1 -1
  85. package/dist/src/planner/building/block.js +3 -0
  86. package/dist/src/planner/building/block.js.map +1 -1
  87. package/dist/src/planner/building/constraint-builder.d.ts.map +1 -1
  88. package/dist/src/planner/building/constraint-builder.js +25 -3
  89. package/dist/src/planner/building/constraint-builder.js.map +1 -1
  90. package/dist/src/planner/building/delete.d.ts.map +1 -1
  91. package/dist/src/planner/building/delete.js +11 -0
  92. package/dist/src/planner/building/delete.js.map +1 -1
  93. package/dist/src/planner/building/drop-assertion.d.ts.map +1 -1
  94. package/dist/src/planner/building/drop-assertion.js +2 -1
  95. package/dist/src/planner/building/drop-assertion.js.map +1 -1
  96. package/dist/src/planner/building/expression.d.ts.map +1 -1
  97. package/dist/src/planner/building/expression.js +55 -7
  98. package/dist/src/planner/building/expression.js.map +1 -1
  99. package/dist/src/planner/building/foreign-key-builder.d.ts +16 -0
  100. package/dist/src/planner/building/foreign-key-builder.d.ts.map +1 -0
  101. package/dist/src/planner/building/foreign-key-builder.js +269 -0
  102. package/dist/src/planner/building/foreign-key-builder.js.map +1 -0
  103. package/dist/src/planner/building/function-call.d.ts.map +1 -1
  104. package/dist/src/planner/building/function-call.js +3 -2
  105. package/dist/src/planner/building/function-call.js.map +1 -1
  106. package/dist/src/planner/building/insert.d.ts.map +1 -1
  107. package/dist/src/planner/building/insert.js +91 -10
  108. package/dist/src/planner/building/insert.js.map +1 -1
  109. package/dist/src/planner/building/schema-resolution.d.ts +4 -0
  110. package/dist/src/planner/building/schema-resolution.d.ts.map +1 -1
  111. package/dist/src/planner/building/schema-resolution.js +14 -3
  112. package/dist/src/planner/building/schema-resolution.js.map +1 -1
  113. package/dist/src/planner/building/select-aggregates.d.ts +1 -0
  114. package/dist/src/planner/building/select-aggregates.d.ts.map +1 -1
  115. package/dist/src/planner/building/select-aggregates.js +118 -3
  116. package/dist/src/planner/building/select-aggregates.js.map +1 -1
  117. package/dist/src/planner/building/select-modifiers.js +3 -3
  118. package/dist/src/planner/building/select-modifiers.js.map +1 -1
  119. package/dist/src/planner/building/select-window.js +9 -8
  120. package/dist/src/planner/building/select-window.js.map +1 -1
  121. package/dist/src/planner/building/select.d.ts.map +1 -1
  122. package/dist/src/planner/building/select.js +21 -10
  123. package/dist/src/planner/building/select.js.map +1 -1
  124. package/dist/src/planner/building/table.d.ts.map +1 -1
  125. package/dist/src/planner/building/table.js +5 -3
  126. package/dist/src/planner/building/table.js.map +1 -1
  127. package/dist/src/planner/building/update.d.ts.map +1 -1
  128. package/dist/src/planner/building/update.js +30 -1
  129. package/dist/src/planner/building/update.js.map +1 -1
  130. package/dist/src/planner/building/with.js +1 -1
  131. package/dist/src/planner/building/with.js.map +1 -1
  132. package/dist/src/planner/cache/reference-graph.d.ts +1 -1
  133. package/dist/src/planner/cache/reference-graph.js +1 -1
  134. package/dist/src/planner/cost/index.d.ts +10 -3
  135. package/dist/src/planner/cost/index.d.ts.map +1 -1
  136. package/dist/src/planner/cost/index.js +17 -3
  137. package/dist/src/planner/cost/index.js.map +1 -1
  138. package/dist/src/planner/debug.js +1 -1
  139. package/dist/src/planner/debug.js.map +1 -1
  140. package/dist/src/planner/framework/characteristics.d.ts +1 -1
  141. package/dist/src/planner/framework/characteristics.d.ts.map +1 -1
  142. package/dist/src/planner/framework/pass.d.ts +3 -1
  143. package/dist/src/planner/framework/pass.d.ts.map +1 -1
  144. package/dist/src/planner/framework/pass.js +62 -18
  145. package/dist/src/planner/framework/pass.js.map +1 -1
  146. package/dist/src/planner/framework/physical-utils.d.ts +5 -0
  147. package/dist/src/planner/framework/physical-utils.d.ts.map +1 -1
  148. package/dist/src/planner/framework/physical-utils.js +19 -0
  149. package/dist/src/planner/framework/physical-utils.js.map +1 -1
  150. package/dist/src/planner/framework/trace.d.ts.map +1 -1
  151. package/dist/src/planner/framework/trace.js +3 -2
  152. package/dist/src/planner/framework/trace.js.map +1 -1
  153. package/dist/src/planner/nodes/alias-node.d.ts +2 -1
  154. package/dist/src/planner/nodes/alias-node.d.ts.map +1 -1
  155. package/dist/src/planner/nodes/alias-node.js +8 -0
  156. package/dist/src/planner/nodes/alias-node.js.map +1 -1
  157. package/dist/src/planner/nodes/alter-table-node.d.ts +42 -0
  158. package/dist/src/planner/nodes/alter-table-node.d.ts.map +1 -0
  159. package/dist/src/planner/nodes/alter-table-node.js +55 -0
  160. package/dist/src/planner/nodes/alter-table-node.js.map +1 -0
  161. package/dist/src/planner/nodes/analyze-node.d.ts +25 -0
  162. package/dist/src/planner/nodes/analyze-node.d.ts.map +1 -0
  163. package/dist/src/planner/nodes/analyze-node.js +83 -0
  164. package/dist/src/planner/nodes/analyze-node.js.map +1 -0
  165. package/dist/src/planner/nodes/bloom-join-node.d.ts +66 -0
  166. package/dist/src/planner/nodes/bloom-join-node.d.ts.map +1 -0
  167. package/dist/src/planner/nodes/bloom-join-node.js +200 -0
  168. package/dist/src/planner/nodes/bloom-join-node.js.map +1 -0
  169. package/dist/src/planner/nodes/constraint-check-node.d.ts +1 -1
  170. package/dist/src/planner/nodes/constraint-check-node.d.ts.map +1 -1
  171. package/dist/src/planner/nodes/cte-reference-node.js +7 -7
  172. package/dist/src/planner/nodes/cte-reference-node.js.map +1 -1
  173. package/dist/src/planner/nodes/join-node.d.ts +9 -1
  174. package/dist/src/planner/nodes/join-node.d.ts.map +1 -1
  175. package/dist/src/planner/nodes/join-node.js +69 -79
  176. package/dist/src/planner/nodes/join-node.js.map +1 -1
  177. package/dist/src/planner/nodes/merge-join-node.d.ts +60 -0
  178. package/dist/src/planner/nodes/merge-join-node.d.ts.map +1 -0
  179. package/dist/src/planner/nodes/merge-join-node.js +207 -0
  180. package/dist/src/planner/nodes/merge-join-node.js.map +1 -0
  181. package/dist/src/planner/nodes/plan-node-type.d.ts +1 -0
  182. package/dist/src/planner/nodes/plan-node-type.d.ts.map +1 -1
  183. package/dist/src/planner/nodes/plan-node-type.js +1 -0
  184. package/dist/src/planner/nodes/plan-node-type.js.map +1 -1
  185. package/dist/src/planner/nodes/project-node.d.ts.map +1 -1
  186. package/dist/src/planner/nodes/project-node.js +3 -2
  187. package/dist/src/planner/nodes/project-node.js.map +1 -1
  188. package/dist/src/planner/nodes/reference.d.ts +2 -1
  189. package/dist/src/planner/nodes/reference.d.ts.map +1 -1
  190. package/dist/src/planner/nodes/reference.js +6 -2
  191. package/dist/src/planner/nodes/reference.js.map +1 -1
  192. package/dist/src/planner/nodes/returning-node.d.ts.map +1 -1
  193. package/dist/src/planner/nodes/returning-node.js +3 -2
  194. package/dist/src/planner/nodes/returning-node.js.map +1 -1
  195. package/dist/src/planner/nodes/scalar.d.ts.map +1 -1
  196. package/dist/src/planner/nodes/subquery.js.map +1 -1
  197. package/dist/src/planner/nodes/table-access-nodes.js +1 -1
  198. package/dist/src/planner/nodes/table-access-nodes.js.map +1 -1
  199. package/dist/src/planner/nodes/update-node.d.ts +2 -0
  200. package/dist/src/planner/nodes/update-node.d.ts.map +1 -1
  201. package/dist/src/planner/nodes/update-node.js +2 -1
  202. package/dist/src/planner/nodes/update-node.js.map +1 -1
  203. package/dist/src/planner/nodes/window-function.d.ts.map +1 -1
  204. package/dist/src/planner/nodes/window-function.js +7 -7
  205. package/dist/src/planner/nodes/window-function.js.map +1 -1
  206. package/dist/src/planner/nodes/window-node.d.ts +2 -2
  207. package/dist/src/planner/nodes/window-node.d.ts.map +1 -1
  208. package/dist/src/planner/nodes/window-node.js +9 -14
  209. package/dist/src/planner/nodes/window-node.js.map +1 -1
  210. package/dist/src/planner/optimizer.d.ts.map +1 -1
  211. package/dist/src/planner/optimizer.js +40 -2
  212. package/dist/src/planner/optimizer.js.map +1 -1
  213. package/dist/src/planner/planning-context.d.ts.map +1 -1
  214. package/dist/src/planner/planning-context.js +1 -6
  215. package/dist/src/planner/planning-context.js.map +1 -1
  216. package/dist/src/planner/resolve.d.ts.map +1 -1
  217. package/dist/src/planner/resolve.js.map +1 -1
  218. package/dist/src/planner/rules/access/rule-select-access-path.js +157 -28
  219. package/dist/src/planner/rules/access/rule-select-access-path.js.map +1 -1
  220. package/dist/src/planner/rules/aggregate/rule-aggregate-streaming.d.ts.map +1 -1
  221. package/dist/src/planner/rules/aggregate/rule-aggregate-streaming.js +27 -6
  222. package/dist/src/planner/rules/aggregate/rule-aggregate-streaming.js.map +1 -1
  223. package/dist/src/planner/rules/cache/rule-in-subquery-cache.d.ts +19 -0
  224. package/dist/src/planner/rules/cache/rule-in-subquery-cache.d.ts.map +1 -0
  225. package/dist/src/planner/rules/cache/rule-in-subquery-cache.js +53 -0
  226. package/dist/src/planner/rules/cache/rule-in-subquery-cache.js.map +1 -0
  227. package/dist/src/planner/rules/cache/rule-mutating-subquery-cache.d.ts.map +1 -1
  228. package/dist/src/planner/rules/cache/rule-mutating-subquery-cache.js +5 -0
  229. package/dist/src/planner/rules/cache/rule-mutating-subquery-cache.js.map +1 -1
  230. package/dist/src/planner/rules/distinct/rule-distinct-elimination.d.ts +18 -0
  231. package/dist/src/planner/rules/distinct/rule-distinct-elimination.d.ts.map +1 -0
  232. package/dist/src/planner/rules/distinct/rule-distinct-elimination.js +37 -0
  233. package/dist/src/planner/rules/distinct/rule-distinct-elimination.js.map +1 -0
  234. package/dist/src/planner/rules/join/rule-join-key-inference.d.ts +8 -3
  235. package/dist/src/planner/rules/join/rule-join-key-inference.d.ts.map +1 -1
  236. package/dist/src/planner/rules/join/rule-join-key-inference.js +28 -17
  237. package/dist/src/planner/rules/join/rule-join-key-inference.js.map +1 -1
  238. package/dist/src/planner/rules/join/rule-join-physical-selection.d.ts +16 -0
  239. package/dist/src/planner/rules/join/rule-join-physical-selection.d.ts.map +1 -0
  240. package/dist/src/planner/rules/join/rule-join-physical-selection.js +216 -0
  241. package/dist/src/planner/rules/join/rule-join-physical-selection.js.map +1 -0
  242. package/dist/src/planner/rules/retrieve/rule-grow-retrieve.d.ts.map +1 -1
  243. package/dist/src/planner/rules/retrieve/rule-grow-retrieve.js +34 -4
  244. package/dist/src/planner/rules/retrieve/rule-grow-retrieve.js.map +1 -1
  245. package/dist/src/planner/rules/subquery/rule-subquery-decorrelation.d.ts +23 -0
  246. package/dist/src/planner/rules/subquery/rule-subquery-decorrelation.d.ts.map +1 -0
  247. package/dist/src/planner/rules/subquery/rule-subquery-decorrelation.js +293 -0
  248. package/dist/src/planner/rules/subquery/rule-subquery-decorrelation.js.map +1 -0
  249. package/dist/src/planner/scopes/multi.d.ts +3 -2
  250. package/dist/src/planner/scopes/multi.d.ts.map +1 -1
  251. package/dist/src/planner/scopes/multi.js +32 -7
  252. package/dist/src/planner/scopes/multi.js.map +1 -1
  253. package/dist/src/planner/scopes/shadow.d.ts +20 -0
  254. package/dist/src/planner/scopes/shadow.d.ts.map +1 -0
  255. package/dist/src/planner/scopes/shadow.js +31 -0
  256. package/dist/src/planner/scopes/shadow.js.map +1 -0
  257. package/dist/src/planner/stats/analyze.d.ts +17 -0
  258. package/dist/src/planner/stats/analyze.d.ts.map +1 -0
  259. package/dist/src/planner/stats/analyze.js +114 -0
  260. package/dist/src/planner/stats/analyze.js.map +1 -0
  261. package/dist/src/planner/stats/catalog-stats.d.ts +80 -0
  262. package/dist/src/planner/stats/catalog-stats.d.ts.map +1 -0
  263. package/dist/src/planner/stats/catalog-stats.js +248 -0
  264. package/dist/src/planner/stats/catalog-stats.js.map +1 -0
  265. package/dist/src/planner/stats/histogram.d.ts +24 -0
  266. package/dist/src/planner/stats/histogram.d.ts.map +1 -0
  267. package/dist/src/planner/stats/histogram.js +142 -0
  268. package/dist/src/planner/stats/histogram.js.map +1 -0
  269. package/dist/src/planner/type-utils.d.ts.map +1 -1
  270. package/dist/src/planner/type-utils.js +8 -2
  271. package/dist/src/planner/type-utils.js.map +1 -1
  272. package/dist/src/planner/util/key-utils.d.ts +48 -2
  273. package/dist/src/planner/util/key-utils.d.ts.map +1 -1
  274. package/dist/src/planner/util/key-utils.js +123 -0
  275. package/dist/src/planner/util/key-utils.js.map +1 -1
  276. package/dist/src/planner/validation/determinism-validator.d.ts +9 -0
  277. package/dist/src/planner/validation/determinism-validator.d.ts.map +1 -1
  278. package/dist/src/planner/validation/determinism-validator.js +11 -0
  279. package/dist/src/planner/validation/determinism-validator.js.map +1 -1
  280. package/dist/src/planner/validation/plan-validator.d.ts.map +1 -1
  281. package/dist/src/planner/validation/plan-validator.js +1 -0
  282. package/dist/src/planner/validation/plan-validator.js.map +1 -1
  283. package/dist/src/runtime/context-helpers.d.ts +34 -10
  284. package/dist/src/runtime/context-helpers.d.ts.map +1 -1
  285. package/dist/src/runtime/context-helpers.js +115 -39
  286. package/dist/src/runtime/context-helpers.js.map +1 -1
  287. package/dist/src/runtime/deferred-constraint-queue.d.ts +0 -1
  288. package/dist/src/runtime/deferred-constraint-queue.d.ts.map +1 -1
  289. package/dist/src/runtime/deferred-constraint-queue.js +10 -23
  290. package/dist/src/runtime/deferred-constraint-queue.js.map +1 -1
  291. package/dist/src/runtime/descriptor-helpers.d.ts +7 -0
  292. package/dist/src/runtime/descriptor-helpers.d.ts.map +1 -0
  293. package/dist/src/runtime/descriptor-helpers.js +24 -0
  294. package/dist/src/runtime/descriptor-helpers.js.map +1 -0
  295. package/dist/src/runtime/emission-context.d.ts +7 -1
  296. package/dist/src/runtime/emission-context.d.ts.map +1 -1
  297. package/dist/src/runtime/emission-context.js +16 -0
  298. package/dist/src/runtime/emission-context.js.map +1 -1
  299. package/dist/src/runtime/emit/aggregate.d.ts.map +1 -1
  300. package/dist/src/runtime/emit/aggregate.js +97 -93
  301. package/dist/src/runtime/emit/aggregate.js.map +1 -1
  302. package/dist/src/runtime/emit/alter-table.d.ts +5 -0
  303. package/dist/src/runtime/emit/alter-table.d.ts.map +1 -0
  304. package/dist/src/runtime/emit/alter-table.js +209 -0
  305. package/dist/src/runtime/emit/alter-table.js.map +1 -0
  306. package/dist/src/runtime/emit/analyze.d.ts +9 -0
  307. package/dist/src/runtime/emit/analyze.d.ts.map +1 -0
  308. package/dist/src/runtime/emit/analyze.js +72 -0
  309. package/dist/src/runtime/emit/analyze.js.map +1 -0
  310. package/dist/src/runtime/emit/array-index.d.ts.map +1 -1
  311. package/dist/src/runtime/emit/array-index.js +4 -2
  312. package/dist/src/runtime/emit/array-index.js.map +1 -1
  313. package/dist/src/runtime/emit/between.d.ts.map +1 -1
  314. package/dist/src/runtime/emit/between.js +8 -20
  315. package/dist/src/runtime/emit/between.js.map +1 -1
  316. package/dist/src/runtime/emit/binary.d.ts.map +1 -1
  317. package/dist/src/runtime/emit/binary.js +155 -126
  318. package/dist/src/runtime/emit/binary.js.map +1 -1
  319. package/dist/src/runtime/emit/bloom-join.d.ts +12 -0
  320. package/dist/src/runtime/emit/bloom-join.d.ts.map +1 -0
  321. package/dist/src/runtime/emit/bloom-join.js +114 -0
  322. package/dist/src/runtime/emit/bloom-join.js.map +1 -0
  323. package/dist/src/runtime/emit/cache.js +2 -2
  324. package/dist/src/runtime/emit/cache.js.map +1 -1
  325. package/dist/src/runtime/emit/cast.d.ts.map +1 -1
  326. package/dist/src/runtime/emit/cast.js +31 -117
  327. package/dist/src/runtime/emit/cast.js.map +1 -1
  328. package/dist/src/runtime/emit/constraint-check.d.ts.map +1 -1
  329. package/dist/src/runtime/emit/constraint-check.js +2 -24
  330. package/dist/src/runtime/emit/constraint-check.js.map +1 -1
  331. package/dist/src/runtime/emit/cte-reference.d.ts.map +1 -1
  332. package/dist/src/runtime/emit/cte-reference.js +11 -5
  333. package/dist/src/runtime/emit/cte-reference.js.map +1 -1
  334. package/dist/src/runtime/emit/distinct.d.ts.map +1 -1
  335. package/dist/src/runtime/emit/distinct.js +21 -12
  336. package/dist/src/runtime/emit/distinct.js.map +1 -1
  337. package/dist/src/runtime/emit/dml-executor.d.ts.map +1 -1
  338. package/dist/src/runtime/emit/dml-executor.js +5 -1
  339. package/dist/src/runtime/emit/dml-executor.js.map +1 -1
  340. package/dist/src/runtime/emit/drop-assertion.d.ts.map +1 -1
  341. package/dist/src/runtime/emit/drop-assertion.js +2 -0
  342. package/dist/src/runtime/emit/drop-assertion.js.map +1 -1
  343. package/dist/src/runtime/emit/filter.d.ts.map +1 -1
  344. package/dist/src/runtime/emit/filter.js +26 -7
  345. package/dist/src/runtime/emit/filter.js.map +1 -1
  346. package/dist/src/runtime/emit/internal-recursive-cte-ref.d.ts.map +1 -1
  347. package/dist/src/runtime/emit/internal-recursive-cte-ref.js +11 -5
  348. package/dist/src/runtime/emit/internal-recursive-cte-ref.js.map +1 -1
  349. package/dist/src/runtime/emit/join.d.ts +1 -1
  350. package/dist/src/runtime/emit/join.d.ts.map +1 -1
  351. package/dist/src/runtime/emit/join.js +44 -33
  352. package/dist/src/runtime/emit/join.js.map +1 -1
  353. package/dist/src/runtime/emit/merge-join.d.ts +14 -0
  354. package/dist/src/runtime/emit/merge-join.d.ts.map +1 -0
  355. package/dist/src/runtime/emit/merge-join.js +152 -0
  356. package/dist/src/runtime/emit/merge-join.js.map +1 -0
  357. package/dist/src/runtime/emit/parameter.d.ts.map +1 -1
  358. package/dist/src/runtime/emit/parameter.js +10 -32
  359. package/dist/src/runtime/emit/parameter.js.map +1 -1
  360. package/dist/src/runtime/emit/project.d.ts.map +1 -1
  361. package/dist/src/runtime/emit/project.js +22 -12
  362. package/dist/src/runtime/emit/project.js.map +1 -1
  363. package/dist/src/runtime/emit/recursive-cte.d.ts.map +1 -1
  364. package/dist/src/runtime/emit/recursive-cte.js +5 -9
  365. package/dist/src/runtime/emit/recursive-cte.js.map +1 -1
  366. package/dist/src/runtime/emit/returning.d.ts.map +1 -1
  367. package/dist/src/runtime/emit/returning.js +14 -8
  368. package/dist/src/runtime/emit/returning.js.map +1 -1
  369. package/dist/src/runtime/emit/scan.d.ts.map +1 -1
  370. package/dist/src/runtime/emit/scan.js +4 -1
  371. package/dist/src/runtime/emit/scan.js.map +1 -1
  372. package/dist/src/runtime/emit/set-operation.d.ts.map +1 -1
  373. package/dist/src/runtime/emit/set-operation.js +8 -5
  374. package/dist/src/runtime/emit/set-operation.js.map +1 -1
  375. package/dist/src/runtime/emit/sort.js +2 -2
  376. package/dist/src/runtime/emit/sort.js.map +1 -1
  377. package/dist/src/runtime/emit/subquery.js +2 -2
  378. package/dist/src/runtime/emit/subquery.js.map +1 -1
  379. package/dist/src/runtime/emit/table-valued-function.d.ts.map +1 -1
  380. package/dist/src/runtime/emit/table-valued-function.js +21 -7
  381. package/dist/src/runtime/emit/table-valued-function.js.map +1 -1
  382. package/dist/src/runtime/emit/unary.js +2 -2
  383. package/dist/src/runtime/emit/unary.js.map +1 -1
  384. package/dist/src/runtime/emit/update.d.ts.map +1 -1
  385. package/dist/src/runtime/emit/update.js +43 -21
  386. package/dist/src/runtime/emit/update.js.map +1 -1
  387. package/dist/src/runtime/emit/window.d.ts.map +1 -1
  388. package/dist/src/runtime/emit/window.js +368 -126
  389. package/dist/src/runtime/emit/window.js.map +1 -1
  390. package/dist/src/runtime/foreign-key-actions.d.ts +15 -0
  391. package/dist/src/runtime/foreign-key-actions.d.ts.map +1 -0
  392. package/dist/src/runtime/foreign-key-actions.js +109 -0
  393. package/dist/src/runtime/foreign-key-actions.js.map +1 -0
  394. package/dist/src/runtime/register.d.ts.map +1 -1
  395. package/dist/src/runtime/register.js +8 -0
  396. package/dist/src/runtime/register.js.map +1 -1
  397. package/dist/src/runtime/scheduler.d.ts.map +1 -1
  398. package/dist/src/runtime/scheduler.js +4 -1
  399. package/dist/src/runtime/scheduler.js.map +1 -1
  400. package/dist/src/runtime/types.d.ts +6 -5
  401. package/dist/src/runtime/types.d.ts.map +1 -1
  402. package/dist/src/runtime/types.js.map +1 -1
  403. package/dist/src/schema/change-events.d.ts +36 -8
  404. package/dist/src/schema/change-events.d.ts.map +1 -1
  405. package/dist/src/schema/change-events.js.map +1 -1
  406. package/dist/src/schema/column.d.ts +5 -1
  407. package/dist/src/schema/column.d.ts.map +1 -1
  408. package/dist/src/schema/column.js +1 -2
  409. package/dist/src/schema/column.js.map +1 -1
  410. package/dist/src/schema/manager.d.ts +54 -4
  411. package/dist/src/schema/manager.d.ts.map +1 -1
  412. package/dist/src/schema/manager.js +353 -313
  413. package/dist/src/schema/manager.js.map +1 -1
  414. package/dist/src/schema/schema-differ.js +3 -3
  415. package/dist/src/schema/schema-differ.js.map +1 -1
  416. package/dist/src/schema/schema.d.ts +1 -1
  417. package/dist/src/schema/schema.js +2 -2
  418. package/dist/src/schema/schema.js.map +1 -1
  419. package/dist/src/schema/table.d.ts +49 -0
  420. package/dist/src/schema/table.d.ts.map +1 -1
  421. package/dist/src/schema/table.js +30 -11
  422. package/dist/src/schema/table.js.map +1 -1
  423. package/dist/src/types/builtin-types.d.ts.map +1 -1
  424. package/dist/src/types/builtin-types.js +26 -95
  425. package/dist/src/types/builtin-types.js.map +1 -1
  426. package/dist/src/types/index.d.ts +1 -1
  427. package/dist/src/types/index.d.ts.map +1 -1
  428. package/dist/src/types/index.js +1 -1
  429. package/dist/src/types/index.js.map +1 -1
  430. package/dist/src/types/json-type.d.ts.map +1 -1
  431. package/dist/src/types/json-type.js +28 -40
  432. package/dist/src/types/json-type.js.map +1 -1
  433. package/dist/src/types/logical-type.d.ts +6 -0
  434. package/dist/src/types/logical-type.d.ts.map +1 -1
  435. package/dist/src/types/logical-type.js +12 -0
  436. package/dist/src/types/logical-type.js.map +1 -1
  437. package/dist/src/types/temporal-types.d.ts.map +1 -1
  438. package/dist/src/types/temporal-types.js +8 -37
  439. package/dist/src/types/temporal-types.js.map +1 -1
  440. package/dist/src/util/coercion.d.ts +4 -5
  441. package/dist/src/util/coercion.d.ts.map +1 -1
  442. package/dist/src/util/coercion.js +10 -14
  443. package/dist/src/util/coercion.js.map +1 -1
  444. package/dist/src/util/comparison.d.ts +34 -21
  445. package/dist/src/util/comparison.d.ts.map +1 -1
  446. package/dist/src/util/comparison.js +77 -43
  447. package/dist/src/util/comparison.js.map +1 -1
  448. package/dist/src/util/environment.d.ts +0 -8
  449. package/dist/src/util/environment.d.ts.map +1 -1
  450. package/dist/src/util/environment.js +0 -12
  451. package/dist/src/util/environment.js.map +1 -1
  452. package/dist/src/util/key-serializer.d.ts +33 -0
  453. package/dist/src/util/key-serializer.d.ts.map +1 -0
  454. package/dist/src/util/key-serializer.js +95 -0
  455. package/dist/src/util/key-serializer.js.map +1 -0
  456. package/dist/src/util/plugin-helper.d.ts.map +1 -1
  457. package/dist/src/util/plugin-helper.js +21 -45
  458. package/dist/src/util/plugin-helper.js.map +1 -1
  459. package/dist/src/util/serialization.d.ts +1 -0
  460. package/dist/src/util/serialization.d.ts.map +1 -1
  461. package/dist/src/util/serialization.js +8 -1
  462. package/dist/src/util/serialization.js.map +1 -1
  463. package/dist/src/util/working-table-iterable.d.ts +6 -5
  464. package/dist/src/util/working-table-iterable.d.ts.map +1 -1
  465. package/dist/src/util/working-table-iterable.js +8 -15
  466. package/dist/src/util/working-table-iterable.js.map +1 -1
  467. package/dist/src/vtab/best-access-plan.d.ts +12 -0
  468. package/dist/src/vtab/best-access-plan.d.ts.map +1 -1
  469. package/dist/src/vtab/best-access-plan.js +22 -0
  470. package/dist/src/vtab/best-access-plan.js.map +1 -1
  471. package/dist/src/vtab/manifest.d.ts +3 -1
  472. package/dist/src/vtab/manifest.d.ts.map +1 -1
  473. package/dist/src/vtab/memory/index.d.ts +2 -2
  474. package/dist/src/vtab/memory/index.d.ts.map +1 -1
  475. package/dist/src/vtab/memory/index.js +4 -7
  476. package/dist/src/vtab/memory/index.js.map +1 -1
  477. package/dist/src/vtab/memory/layer/base-cursor.d.ts.map +1 -1
  478. package/dist/src/vtab/memory/layer/base-cursor.js +37 -9
  479. package/dist/src/vtab/memory/layer/base-cursor.js.map +1 -1
  480. package/dist/src/vtab/memory/layer/base.js +1 -1
  481. package/dist/src/vtab/memory/layer/base.js.map +1 -1
  482. package/dist/src/vtab/memory/layer/manager.d.ts +15 -3
  483. package/dist/src/vtab/memory/layer/manager.d.ts.map +1 -1
  484. package/dist/src/vtab/memory/layer/manager.js +85 -37
  485. package/dist/src/vtab/memory/layer/manager.js.map +1 -1
  486. package/dist/src/vtab/memory/layer/scan-plan.d.ts +2 -0
  487. package/dist/src/vtab/memory/layer/scan-plan.d.ts.map +1 -1
  488. package/dist/src/vtab/memory/layer/scan-plan.js +153 -78
  489. package/dist/src/vtab/memory/layer/scan-plan.js.map +1 -1
  490. package/dist/src/vtab/memory/layer/transaction-cursor.d.ts.map +1 -1
  491. package/dist/src/vtab/memory/layer/transaction-cursor.js +39 -9
  492. package/dist/src/vtab/memory/layer/transaction-cursor.js.map +1 -1
  493. package/dist/src/vtab/memory/layer/transaction.d.ts.map +1 -1
  494. package/dist/src/vtab/memory/layer/transaction.js +1 -5
  495. package/dist/src/vtab/memory/layer/transaction.js.map +1 -1
  496. package/dist/src/vtab/memory/module.d.ts +14 -24
  497. package/dist/src/vtab/memory/module.d.ts.map +1 -1
  498. package/dist/src/vtab/memory/module.js +88 -283
  499. package/dist/src/vtab/memory/module.js.map +1 -1
  500. package/dist/src/vtab/memory/table.d.ts +9 -0
  501. package/dist/src/vtab/memory/table.d.ts.map +1 -1
  502. package/dist/src/vtab/memory/table.js +121 -18
  503. package/dist/src/vtab/memory/table.js.map +1 -1
  504. package/dist/src/vtab/memory/types.d.ts +1 -0
  505. package/dist/src/vtab/memory/types.d.ts.map +1 -1
  506. package/dist/src/vtab/memory/utils/primary-key.js.map +1 -1
  507. package/dist/src/vtab/module.d.ts +13 -0
  508. package/dist/src/vtab/module.d.ts.map +1 -1
  509. package/dist/src/vtab/table.d.ts +9 -0
  510. package/dist/src/vtab/table.d.ts.map +1 -1
  511. package/dist/src/vtab/table.js.map +1 -1
  512. package/package.json +2 -2
@@ -204,9 +204,9 @@ export class SchemaManager {
204
204
  if (this.schemas.has(lowerName)) {
205
205
  throw new QuereusError(`Schema '${name}' already exists`, StatusCode.ERROR);
206
206
  }
207
- const schema = new Schema(name);
207
+ const schema = new Schema(lowerName);
208
208
  this.schemas.set(lowerName, schema);
209
- log(`Added schema '%s'`, name);
209
+ log(`Added schema '%s'`, lowerName);
210
210
  return schema;
211
211
  }
212
212
  /**
@@ -314,7 +314,7 @@ export class SchemaManager {
314
314
  * @returns The ViewSchema or undefined if not found
315
315
  */
316
316
  getView(schemaName, viewName) {
317
- const targetSchemaName = schemaName ?? this.currentSchemaName;
317
+ const targetSchemaName = (schemaName ?? this.currentSchemaName).toLowerCase();
318
318
  const schema = this.schemas.get(targetSchemaName);
319
319
  return schema?.getView(viewName);
320
320
  }
@@ -326,7 +326,7 @@ export class SchemaManager {
326
326
  * @returns The TableSchema or ViewSchema, or undefined if not found
327
327
  */
328
328
  getSchemaItem(schemaName, itemName) {
329
- const targetSchemaName = schemaName ?? this.currentSchemaName;
329
+ const targetSchemaName = (schemaName ?? this.currentSchemaName).toLowerCase();
330
330
  const schema = this.schemas.get(targetSchemaName);
331
331
  if (!schema)
332
332
  return undefined;
@@ -414,7 +414,7 @@ export class SchemaManager {
414
414
  * @returns True if the view was found and dropped, false otherwise
415
415
  */
416
416
  dropView(schemaName, viewName) {
417
- const schema = this.schemas.get(schemaName);
417
+ const schema = this.schemas.get(schemaName.toLowerCase());
418
418
  if (!schema)
419
419
  return false;
420
420
  return schema.removeView(viewName);
@@ -452,137 +452,15 @@ export class SchemaManager {
452
452
  * @returns The TableSchema or undefined if not found
453
453
  */
454
454
  getTable(schemaName, tableName) {
455
- const targetSchemaName = schemaName ?? this.currentSchemaName;
455
+ const targetSchemaName = (schemaName ?? this.currentSchemaName).toLowerCase();
456
456
  const schema = this.schemas.get(targetSchemaName);
457
457
  return schema?.getTable(tableName);
458
458
  }
459
459
  /**
460
- * Creates a new index on an existing table based on an AST.CreateIndexStmt.
461
- * This method validates the index definition and calls the virtual table's createIndex method.
462
- *
463
- * @param stmt The AST node for the CREATE INDEX statement.
464
- * @returns A Promise that resolves when the index is created.
465
- * @throws QuereusError on errors (e.g., table not found, column not found, createIndex fails).
466
- */
467
- async createIndex(stmt) {
468
- const targetSchemaName = stmt.table.schema || this.getCurrentSchemaName();
469
- const tableName = stmt.table.name;
470
- const indexName = stmt.index.name;
471
- // Find the table schema
472
- const tableSchema = this.getTable(targetSchemaName, tableName);
473
- if (!tableSchema) {
474
- throw new QuereusError(`no such table: ${tableName}`, StatusCode.ERROR, undefined, stmt.table.loc?.start.line, stmt.table.loc?.start.column);
475
- }
476
- // Check if the virtual table module supports createIndex
477
- if (!tableSchema.vtabModule.createIndex) {
478
- throw new QuereusError(`Virtual table module '${tableSchema.vtabModuleName}' for table '${tableName}' does not support CREATE INDEX.`, StatusCode.ERROR, undefined, stmt.table.loc?.start.line, stmt.table.loc?.start.column);
479
- }
480
- // Check if index already exists (if not IF NOT EXISTS)
481
- const existingIndex = tableSchema.indexes?.find(idx => idx.name.toLowerCase() === indexName.toLowerCase());
482
- if (existingIndex) {
483
- if (stmt.ifNotExists) {
484
- log(`Skipping CREATE INDEX: Index %s.%s already exists (IF NOT EXISTS).`, targetSchemaName, indexName);
485
- return;
486
- }
487
- else {
488
- throw new QuereusError(`Index ${indexName} already exists on table ${tableName}`, StatusCode.CONSTRAINT, undefined, stmt.index.loc?.start.line, stmt.index.loc?.start.column);
489
- }
490
- }
491
- // Convert AST columns to IndexSchema columns
492
- const indexColumns = stmt.columns.map((indexedCol) => {
493
- if (indexedCol.expr) {
494
- throw new QuereusError(`Indices on expressions are not supported yet.`, StatusCode.ERROR, undefined, indexedCol.expr.loc?.start.line, indexedCol.expr.loc?.start.column);
495
- }
496
- const colName = indexedCol.name;
497
- if (!colName) {
498
- // Should not happen if expr is checked first
499
- throw new QuereusError(`Indexed column must be a simple column name.`, StatusCode.ERROR);
500
- }
501
- const tableColIndex = tableSchema.columnIndexMap.get(colName.toLowerCase());
502
- if (tableColIndex === undefined) {
503
- throw new QuereusError(`Column '${colName}' not found in table '${tableName}'`, StatusCode.ERROR, undefined, stmt.loc?.start.line, stmt.loc?.start.column);
504
- }
505
- const tableColSchema = tableSchema.columns[tableColIndex];
506
- return {
507
- index: tableColIndex,
508
- desc: indexedCol.direction === 'desc',
509
- collation: indexedCol.collation || tableColSchema.collation // Use specified collation or inherit from table column
510
- };
511
- });
512
- // Construct the IndexSchema object
513
- const indexSchema = {
514
- name: indexName,
515
- columns: Object.freeze(indexColumns),
516
- };
517
- try {
518
- // Call createIndex on the virtual table module
519
- await tableSchema.vtabModule.createIndex(this.db, targetSchemaName, tableName, indexSchema);
520
- // Update the table schema with the new index by creating a new schema object
521
- const updatedIndexes = [...(tableSchema.indexes || []), indexSchema];
522
- const updatedTableSchema = {
523
- ...tableSchema,
524
- indexes: Object.freeze(updatedIndexes),
525
- };
526
- // Replace the table schema in the schema
527
- const schema = this.getSchemaOrFail(targetSchemaName);
528
- schema.addTable(updatedTableSchema);
529
- // Notify schema change listeners that the table was modified
530
- this.changeNotifier.notifyChange({
531
- type: 'table_modified',
532
- schemaName: targetSchemaName,
533
- objectName: tableName,
534
- oldObject: tableSchema,
535
- newObject: updatedTableSchema
536
- });
537
- // Emit auto schema event for modules without native event support
538
- const moduleReg = tableSchema.vtabModuleName ? this.getModule(tableSchema.vtabModuleName) : undefined;
539
- if (this.db.hasSchemaListeners() && !hasNativeEventSupport(moduleReg?.module)) {
540
- this.db._getEventEmitter().emitAutoSchemaEvent(tableSchema.vtabModuleName ?? 'memory', {
541
- type: 'create',
542
- objectType: 'index',
543
- schemaName: targetSchemaName,
544
- objectName: indexName,
545
- });
546
- }
547
- log(`Successfully created index %s on table %s.%s`, indexName, targetSchemaName, tableName);
548
- }
549
- catch (e) {
550
- const message = e instanceof Error ? e.message : String(e);
551
- const code = e instanceof QuereusError ? e.code : StatusCode.ERROR;
552
- throw new QuereusError(`createIndex failed for index '${indexName}' on table '${tableName}': ${message}`, code, e instanceof Error ? e : undefined, stmt.loc?.start.line, stmt.loc?.start.column);
553
- }
554
- }
555
- /**
556
- * Defines a new table in the schema based on an AST.CreateTableStmt.
557
- * This method encapsulates the logic for interacting with VTab modules (create)
558
- * and registering the new table schema.
559
- *
560
- * @param stmt The AST node for the CREATE TABLE statement.
561
- * @returns A Promise that resolves to the created TableSchema.
562
- * @throws QuereusError on errors (e.g., module not found, create fails, table exists).
460
+ * Resolves the VTab module name and args from a CREATE TABLE statement,
461
+ * falling back to configured defaults when USING is omitted.
563
462
  */
564
- async createTable(stmt) {
565
- const targetSchemaName = stmt.table.schema || this.getCurrentSchemaName();
566
- const tableName = stmt.table.name;
567
- // Check IF NOT EXISTS
568
- const schema = this.getSchema(targetSchemaName);
569
- if (!schema) {
570
- throw new QuereusError(`Internal error: Schema '${targetSchemaName}' not found.`, StatusCode.INTERNAL);
571
- }
572
- const existingTable = schema.getTable(tableName);
573
- const existingView = schema.getView(tableName);
574
- if (existingTable || existingView) {
575
- if (stmt.ifNotExists) {
576
- log(`Skipping CREATE TABLE: Item %s.%s already exists (IF NOT EXISTS).`, targetSchemaName, tableName);
577
- if (existingTable)
578
- return existingTable;
579
- throw new QuereusError(`Cannot CREATE TABLE ${targetSchemaName}.${tableName}: a VIEW with the same name already exists.`, StatusCode.CONSTRAINT, undefined, stmt.table.loc?.start.line, stmt.table.loc?.start.column);
580
- }
581
- else {
582
- const itemType = existingTable ? 'Table' : 'View';
583
- throw new QuereusError(`${itemType} ${targetSchemaName}.${tableName} already exists`, StatusCode.CONSTRAINT, undefined, stmt.table.loc?.start.line, stmt.table.loc?.start.column);
584
- }
585
- }
463
+ resolveModuleInfo(stmt) {
586
464
  let moduleName;
587
465
  let effectiveModuleArgs;
588
466
  if (stmt.moduleName) {
@@ -598,31 +476,38 @@ export class SchemaManager {
598
476
  if (!moduleInfo || !moduleInfo.module) {
599
477
  throw new QuereusError(`No virtual table module named '${moduleName}'`, StatusCode.ERROR, undefined, stmt.loc?.start.line, stmt.loc?.start.column);
600
478
  }
601
- const astColumnsToProcess = stmt.columns || [];
602
- const astConstraintsToProcess = stmt.constraints;
603
- // Get default nullability setting from database options
604
- const defaultNullability = this.db.options.getStringOption('default_column_nullability');
605
- const defaultNotNull = defaultNullability === 'not_null';
606
- const preliminaryColumnSchemas = astColumnsToProcess.map(colDef => columnDefToSchema(colDef, defaultNotNull));
607
- const pkDefinition = findPKDefinition(preliminaryColumnSchemas, astConstraintsToProcess);
608
- const finalColumnSchemas = preliminaryColumnSchemas.map((col, idx) => {
479
+ return { moduleName, effectiveModuleArgs, moduleInfo };
480
+ }
481
+ /**
482
+ * Builds column schemas from AST column/constraint definitions,
483
+ * resolving PK membership and nullability.
484
+ */
485
+ buildColumnSchemas(astColumns, astConstraints, defaultNotNull) {
486
+ const preliminaryColumnSchemas = astColumns.map(colDef => columnDefToSchema(colDef, defaultNotNull));
487
+ const pkDefinition = findPKDefinition(preliminaryColumnSchemas, astConstraints);
488
+ const columns = preliminaryColumnSchemas.map((col, idx) => {
609
489
  const isPkColumn = pkDefinition.some(pkCol => pkCol.index === idx);
610
- let pkOrder = 0;
611
- if (isPkColumn) {
612
- pkOrder = pkDefinition.findIndex(pkC => pkC.index === idx) + 1;
613
- }
490
+ const pkOrder = isPkColumn
491
+ ? pkDefinition.findIndex(pkC => pkC.index === idx) + 1
492
+ : 0;
614
493
  return {
615
494
  ...col,
616
495
  primaryKey: isPkColumn,
617
- pkOrder: pkOrder,
496
+ pkOrder,
618
497
  notNull: isPkColumn ? true : col.notNull,
619
498
  };
620
499
  });
621
- const checkConstraintsSchema = [];
622
- astColumnsToProcess.forEach(colDef => {
623
- colDef.constraints?.forEach(con => {
500
+ return { columns, pkDefinition };
501
+ }
502
+ /**
503
+ * Extracts CHECK constraints from AST column and table constraint definitions.
504
+ */
505
+ extractCheckConstraints(astColumns, astConstraints) {
506
+ const result = [];
507
+ for (const colDef of astColumns) {
508
+ for (const con of colDef.constraints ?? []) {
624
509
  if (con.type === 'check' && con.expr) {
625
- checkConstraintsSchema.push({
510
+ result.push({
626
511
  name: con.name ?? `_check_${colDef.name}`,
627
512
  expr: con.expr,
628
513
  operations: opsToMask(con.operations),
@@ -630,11 +515,11 @@ export class SchemaManager {
630
515
  initiallyDeferred: con.initiallyDeferred
631
516
  });
632
517
  }
633
- });
634
- });
635
- (astConstraintsToProcess || []).forEach(con => {
518
+ }
519
+ }
520
+ for (const con of astConstraints ?? []) {
636
521
  if (con.type === 'check' && con.expr) {
637
- checkConstraintsSchema.push({
522
+ result.push({
638
523
  name: con.name,
639
524
  expr: con.expr,
640
525
  operations: opsToMask(con.operations),
@@ -642,16 +527,147 @@ export class SchemaManager {
642
527
  initiallyDeferred: con.initiallyDeferred
643
528
  });
644
529
  }
645
- });
646
- // Process mutation context definitions if present
530
+ }
531
+ return result;
532
+ }
533
+ /**
534
+ * Extracts FOREIGN KEY constraints from AST column and table constraint definitions.
535
+ * Resolves column indices in the child table. Parent table resolution is deferred
536
+ * to enforcement time (the parent table may not exist yet during declarative schema setup).
537
+ */
538
+ extractForeignKeys(astColumns, astConstraints, columnIndexMap, tableName, schemaName) {
539
+ const result = [];
540
+ // Column-level foreign keys
541
+ for (const colDef of astColumns) {
542
+ for (const con of colDef.constraints ?? []) {
543
+ if (con.type === 'foreignKey' && con.foreignKey) {
544
+ const fk = con.foreignKey;
545
+ const childColIndex = columnIndexMap.get(colDef.name.toLowerCase());
546
+ if (childColIndex === undefined) {
547
+ throw new QuereusError(`FK column '${colDef.name}' not found in table '${tableName}'`, StatusCode.ERROR);
548
+ }
549
+ // Parent column resolution is deferred — store names for now
550
+ // We need the parent table schema to resolve indices, but it may not exist yet
551
+ result.push({
552
+ name: con.name ?? `_fk_${tableName}_${colDef.name}`,
553
+ columns: Object.freeze([childColIndex]),
554
+ referencedTable: fk.table,
555
+ referencedSchema: schemaName,
556
+ referencedColumns: Object.freeze([]), // resolved at enforcement time
557
+ referencedColumnNames: fk.columns, // deferred resolution via resolveReferencedColumns
558
+ onDelete: fk.onDelete ?? 'noAction',
559
+ onUpdate: fk.onUpdate ?? 'noAction',
560
+ deferred: fk.initiallyDeferred ?? false,
561
+ });
562
+ }
563
+ }
564
+ }
565
+ // Table-level foreign keys
566
+ for (const con of astConstraints ?? []) {
567
+ if (con.type === 'foreignKey' && con.foreignKey && con.columns) {
568
+ const fk = con.foreignKey;
569
+ const childColIndices = con.columns.map(col => {
570
+ const idx = columnIndexMap.get(col.name.toLowerCase());
571
+ if (idx === undefined) {
572
+ throw new QuereusError(`FK column '${col.name}' not found in table '${tableName}'`, StatusCode.ERROR);
573
+ }
574
+ return idx;
575
+ });
576
+ result.push({
577
+ name: con.name ?? `_fk_${tableName}_${con.columns.map(c => c.name).join('_')}`,
578
+ columns: Object.freeze(childColIndices),
579
+ referencedTable: fk.table,
580
+ referencedSchema: schemaName,
581
+ referencedColumns: Object.freeze([]), // resolved at enforcement time
582
+ referencedColumnNames: fk.columns, // deferred resolution via resolveReferencedColumns
583
+ onDelete: fk.onDelete ?? 'noAction',
584
+ onUpdate: fk.onUpdate ?? 'noAction',
585
+ deferred: fk.initiallyDeferred ?? false,
586
+ });
587
+ }
588
+ }
589
+ return result;
590
+ }
591
+ /**
592
+ * Extracts UNIQUE constraints from AST column and table constraint definitions.
593
+ * Resolves column names to indices.
594
+ */
595
+ extractUniqueConstraints(astColumns, astConstraints, columnIndexMap) {
596
+ const result = [];
597
+ // Column-level unique constraints
598
+ for (const colDef of astColumns) {
599
+ for (const con of colDef.constraints ?? []) {
600
+ if (con.type === 'unique') {
601
+ const colIndex = columnIndexMap.get(colDef.name.toLowerCase());
602
+ if (colIndex !== undefined) {
603
+ result.push({
604
+ name: con.name,
605
+ columns: Object.freeze([colIndex]),
606
+ });
607
+ }
608
+ }
609
+ }
610
+ }
611
+ // Table-level unique constraints
612
+ for (const con of astConstraints ?? []) {
613
+ if (con.type === 'unique' && con.columns && con.columns.length > 0) {
614
+ const colIndices = con.columns.map(col => {
615
+ const idx = columnIndexMap.get(col.name.toLowerCase());
616
+ if (idx === undefined) {
617
+ throw new QuereusError(`UNIQUE constraint column '${col.name}' not found`, StatusCode.ERROR);
618
+ }
619
+ return idx;
620
+ });
621
+ result.push({
622
+ name: con.name,
623
+ columns: Object.freeze(colIndices),
624
+ });
625
+ }
626
+ }
627
+ return result;
628
+ }
629
+ /**
630
+ * Builds a base TableSchema from an AST CREATE TABLE statement.
631
+ * Shared by both createTable (new storage) and importTable (existing storage).
632
+ */
633
+ buildTableSchemaFromAST(stmt, moduleName, effectiveModuleArgs, moduleInfo) {
634
+ const targetSchemaName = stmt.table.schema || this.getCurrentSchemaName();
635
+ const tableName = stmt.table.name;
636
+ const defaultNullability = this.db.options.getStringOption('default_column_nullability');
637
+ const defaultNotNull = defaultNullability === 'not_null';
638
+ const astColumns = stmt.columns || [];
639
+ const { columns, pkDefinition } = this.buildColumnSchemas(astColumns, stmt.constraints, defaultNotNull);
640
+ const checkConstraints = this.extractCheckConstraints(astColumns, stmt.constraints);
641
+ const columnIndexMap = buildColumnIndexMap(columns);
642
+ const foreignKeys = this.extractForeignKeys(astColumns, stmt.constraints, columnIndexMap, tableName, targetSchemaName);
643
+ const uniqueConstraints = this.extractUniqueConstraints(astColumns, stmt.constraints, columnIndexMap);
647
644
  const mutationContextSchemas = stmt.contextDefinitions
648
645
  ? stmt.contextDefinitions.map(varDef => mutationContextVarToSchema(varDef, defaultNotNull))
649
646
  : undefined;
650
- // Validate that default expressions are deterministic
651
- // We need to build them temporarily to check their physical properties
652
- // Note: We only validate defaults here, not CHECK constraints, because CHECK constraints
653
- // may reference table columns which don't exist yet at CREATE TABLE time.
654
- // CHECK constraints are validated at INSERT/UPDATE time in constraint-builder.ts
647
+ return {
648
+ name: tableName,
649
+ schemaName: targetSchemaName,
650
+ columns: Object.freeze(columns),
651
+ columnIndexMap,
652
+ primaryKeyDefinition: pkDefinition,
653
+ checkConstraints: Object.freeze(checkConstraints),
654
+ foreignKeys: foreignKeys.length > 0 ? Object.freeze(foreignKeys) : undefined,
655
+ uniqueConstraints: uniqueConstraints.length > 0 ? Object.freeze(uniqueConstraints) : undefined,
656
+ isTemporary: !!stmt.isTemporary,
657
+ isView: false,
658
+ vtabModuleName: moduleName,
659
+ vtabArgs: effectiveModuleArgs,
660
+ vtabModule: moduleInfo.module,
661
+ vtabAuxData: moduleInfo.auxData,
662
+ estimatedRows: 0,
663
+ mutationContext: mutationContextSchemas ? Object.freeze(mutationContextSchemas) : undefined,
664
+ };
665
+ }
666
+ /**
667
+ * Validates that all DEFAULT expressions in the column schemas are deterministic.
668
+ * Skips expressions that reference columns (validated at INSERT time instead).
669
+ */
670
+ validateDefaultDeterminism(columns, tableName) {
655
671
  const globalScope = new GlobalScope(this.db.schemaManager);
656
672
  const parameterScope = new ParameterScope(globalScope);
657
673
  const planningCtx = {
@@ -665,63 +681,36 @@ export class SchemaManager {
665
681
  cteReferenceCache: new Map(),
666
682
  outputScopes: new Map()
667
683
  };
668
- // Validate default expressions
669
- // Note: We can only validate defaults that don't reference table columns,
670
- // since the table doesn't exist yet. Defaults that reference columns will be
671
- // validated at INSERT time in insert.ts
672
- for (const col of finalColumnSchemas) {
673
- if (col.defaultValue && typeof col.defaultValue === 'object' && col.defaultValue !== null && 'type' in col.defaultValue) {
674
- let defaultExpr;
675
- try {
676
- // Try to build the expression - may fail if it references columns that don't exist yet
677
- defaultExpr = buildExpression(planningCtx, col.defaultValue);
678
- }
679
- catch (e) {
680
- // If we can't build the expression (e.g., it references columns that don't exist yet),
681
- // skip validation here. It will be validated at INSERT time.
682
- log('Skipping determinism validation for default on column %s.%s at CREATE TABLE time (will validate at INSERT time): %s', tableName, col.name, e.message);
683
- }
684
- // If expression built successfully, check determinism (non-throwing)
685
- if (defaultExpr) {
686
- const result = checkDeterministic(defaultExpr);
687
- if (!result.valid) {
688
- throw new QuereusError(`Non-deterministic expression not allowed in DEFAULT for column '${col.name}' in table '${tableName}'. ` +
689
- `Expression: ${result.expression}. ` +
690
- `Use mutation context to pass non-deterministic values (e.g., WITH CONTEXT (timestamp = datetime('now'))).`, StatusCode.ERROR);
691
- }
684
+ for (const col of columns) {
685
+ if (!col.defaultValue || typeof col.defaultValue !== 'object' || col.defaultValue === null || !('type' in col.defaultValue)) {
686
+ continue;
687
+ }
688
+ let defaultExpr;
689
+ try {
690
+ defaultExpr = buildExpression(planningCtx, col.defaultValue);
691
+ }
692
+ catch (_e) {
693
+ log('Skipping determinism validation for default on column %s.%s at CREATE TABLE time (will validate at INSERT time): %s', tableName, col.name, _e.message);
694
+ }
695
+ if (defaultExpr) {
696
+ const result = checkDeterministic(defaultExpr);
697
+ if (!result.valid) {
698
+ throw new QuereusError(`Non-deterministic expression not allowed in DEFAULT for column '${col.name}' in table '${tableName}'. ` +
699
+ `Expression: ${result.expression}. ` +
700
+ `Use mutation context to pass non-deterministic values (e.g., WITH CONTEXT (timestamp = datetime('now'))).`, StatusCode.ERROR);
692
701
  }
693
702
  }
694
703
  }
695
- const baseTableSchema = {
696
- name: tableName,
697
- schemaName: targetSchemaName,
698
- columns: Object.freeze(finalColumnSchemas),
699
- columnIndexMap: buildColumnIndexMap(finalColumnSchemas),
700
- primaryKeyDefinition: pkDefinition,
701
- checkConstraints: Object.freeze(checkConstraintsSchema),
702
- isTemporary: !!stmt.isTemporary,
703
- isView: false,
704
- vtabModuleName: moduleName,
705
- vtabArgs: effectiveModuleArgs,
706
- vtabModule: moduleInfo.module,
707
- vtabAuxData: moduleInfo.auxData,
708
- estimatedRows: 0,
709
- mutationContext: mutationContextSchemas ? Object.freeze(mutationContextSchemas) : undefined,
710
- };
711
- let tableInstance;
712
- try {
713
- tableInstance = await moduleInfo.module.create(this.db, baseTableSchema);
714
- }
715
- catch (e) {
716
- const message = e instanceof Error ? e.message : String(e);
717
- const code = e instanceof QuereusError ? e.code : StatusCode.ERROR;
718
- throw new QuereusError(`Module '${moduleName}' create failed for table '${tableName}': ${message}`, code, e instanceof Error ? e : undefined, stmt.loc?.start.line, stmt.loc?.start.column);
719
- }
704
+ }
705
+ /**
706
+ * Registers a table schema after module.create() returns, correcting
707
+ * name/schema if the module returned different values.
708
+ */
709
+ finalizeCreatedTableSchema(tableInstance, tableName, targetSchemaName, moduleName, effectiveModuleArgs, moduleInfo) {
720
710
  const finalRegisteredSchema = tableInstance.tableSchema;
721
711
  if (!finalRegisteredSchema) {
722
712
  throw new QuereusError(`Module '${moduleName}' create did not provide a tableSchema for '${tableName}'.`, StatusCode.INTERNAL);
723
713
  }
724
- // Create a properly typed schema object instead of mutating properties
725
714
  let correctedSchema = finalRegisteredSchema;
726
715
  if (finalRegisteredSchema.name.toLowerCase() !== tableName.toLowerCase() ||
727
716
  finalRegisteredSchema.schemaName.toLowerCase() !== targetSchemaName.toLowerCase()) {
@@ -732,8 +721,7 @@ export class SchemaManager {
732
721
  schemaName: targetSchemaName,
733
722
  };
734
723
  }
735
- // Ensure all required properties are properly set
736
- const completeTableSchema = {
724
+ return {
737
725
  ...correctedSchema,
738
726
  vtabModuleName: moduleName,
739
727
  vtabArgs: effectiveModuleArgs,
@@ -741,25 +729,161 @@ export class SchemaManager {
741
729
  vtabAuxData: moduleInfo.auxData,
742
730
  estimatedRows: correctedSchema.estimatedRows ?? 0,
743
731
  };
732
+ }
733
+ /**
734
+ * Creates a new index on an existing table based on an AST.CreateIndexStmt.
735
+ *
736
+ * @param stmt The AST node for the CREATE INDEX statement.
737
+ * @throws QuereusError on errors (e.g., table not found, column not found, createIndex fails).
738
+ */
739
+ async createIndex(stmt) {
740
+ const targetSchemaName = stmt.table.schema || this.getCurrentSchemaName();
741
+ const tableName = stmt.table.name;
742
+ const indexName = stmt.index.name;
743
+ const tableSchema = this.getTable(targetSchemaName, tableName);
744
+ if (!tableSchema) {
745
+ throw new QuereusError(`no such table: ${tableName}`, StatusCode.ERROR, undefined, stmt.table.loc?.start.line, stmt.table.loc?.start.column);
746
+ }
747
+ if (!tableSchema.vtabModule.createIndex) {
748
+ throw new QuereusError(`Virtual table module '${tableSchema.vtabModuleName}' for table '${tableName}' does not support CREATE INDEX.`, StatusCode.ERROR, undefined, stmt.table.loc?.start.line, stmt.table.loc?.start.column);
749
+ }
750
+ const existingIndex = tableSchema.indexes?.find(idx => idx.name.toLowerCase() === indexName.toLowerCase());
751
+ if (existingIndex) {
752
+ if (stmt.ifNotExists) {
753
+ log(`Skipping CREATE INDEX: Index %s.%s already exists (IF NOT EXISTS).`, targetSchemaName, indexName);
754
+ return;
755
+ }
756
+ throw new QuereusError(`Index ${indexName} already exists on table ${tableName}`, StatusCode.CONSTRAINT, undefined, stmt.index.loc?.start.line, stmt.index.loc?.start.column);
757
+ }
758
+ const indexSchema = this.buildIndexSchema(stmt, tableSchema, tableName, indexName);
759
+ try {
760
+ await tableSchema.vtabModule.createIndex(this.db, targetSchemaName, tableName, indexSchema);
761
+ }
762
+ catch (e) {
763
+ const message = e instanceof Error ? e.message : String(e);
764
+ const code = e instanceof QuereusError ? e.code : StatusCode.ERROR;
765
+ throw new QuereusError(`createIndex failed for index '${indexName}' on table '${tableName}': ${message}`, code, e instanceof Error ? e : undefined, stmt.loc?.start.line, stmt.loc?.start.column);
766
+ }
767
+ const updatedTableSchema = this.addIndexToTableSchema(tableSchema, indexSchema);
768
+ const schema = this.getSchemaOrFail(targetSchemaName);
769
+ schema.addTable(updatedTableSchema);
770
+ this.changeNotifier.notifyChange({
771
+ type: 'table_modified',
772
+ schemaName: targetSchemaName,
773
+ objectName: tableName,
774
+ oldObject: tableSchema,
775
+ newObject: updatedTableSchema
776
+ });
777
+ this.emitAutoSchemaEventIfNeeded(tableSchema.vtabModuleName, {
778
+ type: 'create',
779
+ objectType: 'index',
780
+ schemaName: targetSchemaName,
781
+ objectName: indexName,
782
+ });
783
+ log(`Successfully created index %s on table %s.%s`, indexName, targetSchemaName, tableName);
784
+ }
785
+ /**
786
+ * Builds an IndexSchema from AST column definitions, validating against the table schema.
787
+ */
788
+ buildIndexSchema(stmt, tableSchema, tableName, indexName) {
789
+ const indexColumns = stmt.columns.map((indexedCol) => {
790
+ if (indexedCol.expr) {
791
+ throw new QuereusError(`Indices on expressions are not supported yet.`, StatusCode.ERROR, undefined, indexedCol.expr.loc?.start.line, indexedCol.expr.loc?.start.column);
792
+ }
793
+ const colName = indexedCol.name;
794
+ if (!colName) {
795
+ throw new QuereusError(`Indexed column must be a simple column name.`, StatusCode.ERROR);
796
+ }
797
+ const tableColIndex = tableSchema.columnIndexMap.get(colName.toLowerCase());
798
+ if (tableColIndex === undefined) {
799
+ throw new QuereusError(`Column '${colName}' not found in table '${tableName}'`, StatusCode.ERROR, undefined, stmt.loc?.start.line, stmt.loc?.start.column);
800
+ }
801
+ const tableColSchema = tableSchema.columns[tableColIndex];
802
+ return {
803
+ index: tableColIndex,
804
+ desc: indexedCol.direction === 'desc',
805
+ collation: indexedCol.collation || tableColSchema.collation
806
+ };
807
+ });
808
+ return {
809
+ name: indexName,
810
+ columns: Object.freeze(indexColumns),
811
+ };
812
+ }
813
+ /**
814
+ * Returns a new TableSchema with the given index appended.
815
+ */
816
+ addIndexToTableSchema(tableSchema, indexSchema) {
817
+ const updatedIndexes = [...(tableSchema.indexes || []), indexSchema];
818
+ return {
819
+ ...tableSchema,
820
+ indexes: Object.freeze(updatedIndexes),
821
+ };
822
+ }
823
+ /**
824
+ * Emits an auto schema event for modules that don't have native event support,
825
+ * if any schema listeners are registered.
826
+ */
827
+ emitAutoSchemaEventIfNeeded(moduleName, event) {
828
+ const moduleReg = moduleName ? this.getModule(moduleName) : undefined;
829
+ if (this.db.hasSchemaListeners() && !hasNativeEventSupport(moduleReg?.module)) {
830
+ this.db._getEventEmitter().emitAutoSchemaEvent(moduleName ?? 'memory', event);
831
+ }
832
+ }
833
+ /**
834
+ * Defines a new table in the schema based on an AST.CreateTableStmt.
835
+ * Interacts with VTab modules (create) and registers the new table schema.
836
+ *
837
+ * @param stmt The AST node for the CREATE TABLE statement.
838
+ * @returns A Promise that resolves to the created TableSchema.
839
+ * @throws QuereusError on errors (e.g., module not found, create fails, table exists).
840
+ */
841
+ async createTable(stmt) {
842
+ const targetSchemaName = stmt.table.schema || this.getCurrentSchemaName();
843
+ const tableName = stmt.table.name;
844
+ const schema = this.getSchema(targetSchemaName);
845
+ if (!schema) {
846
+ throw new QuereusError(`Internal error: Schema '${targetSchemaName}' not found.`, StatusCode.INTERNAL);
847
+ }
848
+ const existingTable = schema.getTable(tableName);
849
+ const existingView = schema.getView(tableName);
850
+ if (existingTable || existingView) {
851
+ if (stmt.ifNotExists) {
852
+ log(`Skipping CREATE TABLE: Item %s.%s already exists (IF NOT EXISTS).`, targetSchemaName, tableName);
853
+ if (existingTable)
854
+ return existingTable;
855
+ throw new QuereusError(`Cannot CREATE TABLE ${targetSchemaName}.${tableName}: a VIEW with the same name already exists.`, StatusCode.CONSTRAINT, undefined, stmt.table.loc?.start.line, stmt.table.loc?.start.column);
856
+ }
857
+ const itemType = existingTable ? 'Table' : 'View';
858
+ throw new QuereusError(`${itemType} ${targetSchemaName}.${tableName} already exists`, StatusCode.CONSTRAINT, undefined, stmt.table.loc?.start.line, stmt.table.loc?.start.column);
859
+ }
860
+ const { moduleName, effectiveModuleArgs, moduleInfo } = this.resolveModuleInfo(stmt);
861
+ const baseTableSchema = this.buildTableSchemaFromAST(stmt, moduleName, effectiveModuleArgs, moduleInfo);
862
+ this.validateDefaultDeterminism(baseTableSchema.columns, tableName);
863
+ let tableInstance;
864
+ try {
865
+ tableInstance = await moduleInfo.module.create(this.db, baseTableSchema);
866
+ }
867
+ catch (e) {
868
+ const message = e instanceof Error ? e.message : String(e);
869
+ const code = e instanceof QuereusError ? e.code : StatusCode.ERROR;
870
+ throw new QuereusError(`Module '${moduleName}' create failed for table '${tableName}': ${message}`, code, e instanceof Error ? e : undefined, stmt.loc?.start.line, stmt.loc?.start.column);
871
+ }
872
+ const completeTableSchema = this.finalizeCreatedTableSchema(tableInstance, tableName, targetSchemaName, moduleName, effectiveModuleArgs, moduleInfo);
744
873
  schema.addTable(completeTableSchema);
745
874
  log(`Successfully created table %s.%s using module %s`, targetSchemaName, tableName, moduleName);
746
- // Notify schema change listeners
747
875
  this.changeNotifier.notifyChange({
748
876
  type: 'table_added',
749
877
  schemaName: targetSchemaName,
750
878
  objectName: tableName,
751
879
  newObject: completeTableSchema
752
880
  });
753
- // Emit auto schema event for modules without native event support
754
- // (Modules with native events emit during their create() method)
755
- if (this.db.hasSchemaListeners() && !hasNativeEventSupport(moduleInfo.module)) {
756
- this.db._getEventEmitter().emitAutoSchemaEvent(moduleName, {
757
- type: 'create',
758
- objectType: 'table',
759
- schemaName: targetSchemaName,
760
- objectName: tableName,
761
- });
762
- }
881
+ this.emitAutoSchemaEventIfNeeded(moduleName, {
882
+ type: 'create',
883
+ objectType: 'table',
884
+ schemaName: targetSchemaName,
885
+ objectName: tableName,
886
+ });
763
887
  return completeTableSchema;
764
888
  }
765
889
  /**
@@ -800,7 +924,6 @@ export class SchemaManager {
800
924
  * Import a single DDL statement without creating storage.
801
925
  */
802
926
  async importSingleDDL(ddl) {
803
- // Parse the DDL using the parser
804
927
  const parser = new Parser();
805
928
  const statements = parser.parseAll(ddl);
806
929
  if (statements.length !== 1) {
@@ -813,9 +936,7 @@ export class SchemaManager {
813
936
  else if (stmt.type === 'createIndex') {
814
937
  return this.importIndex(stmt);
815
938
  }
816
- else {
817
- throw new QuereusError(`importCatalog does not support statement type: ${stmt.type}`, StatusCode.ERROR);
818
- }
939
+ throw new QuereusError(`importCatalog does not support statement type: ${stmt.type}`, StatusCode.ERROR);
819
940
  }
820
941
  /**
821
942
  * Import a table schema without calling module.create().
@@ -824,102 +945,21 @@ export class SchemaManager {
824
945
  async importTable(stmt) {
825
946
  const targetSchemaName = stmt.table.schema || this.getCurrentSchemaName();
826
947
  const tableName = stmt.table.name;
827
- let moduleName;
828
- let effectiveModuleArgs;
829
- if (stmt.moduleName) {
830
- moduleName = stmt.moduleName;
831
- effectiveModuleArgs = Object.freeze(stmt.moduleArgs || {});
832
- }
833
- else {
834
- const defaultVtab = this.getDefaultVTabModule();
835
- moduleName = defaultVtab.name;
836
- effectiveModuleArgs = Object.freeze(defaultVtab.args || {});
837
- }
838
- const moduleInfo = this.getModule(moduleName);
839
- if (!moduleInfo || !moduleInfo.module) {
840
- throw new QuereusError(`No virtual table module named '${moduleName}'`, StatusCode.ERROR);
841
- }
842
- // Get default nullability setting from database options
843
- const defaultNullability = this.db.options.getStringOption('default_column_nullability');
844
- const defaultNotNull = defaultNullability === 'not_null';
845
- const astColumnsToProcess = stmt.columns || [];
846
- const astConstraintsToProcess = stmt.constraints;
847
- const preliminaryColumnSchemas = astColumnsToProcess.map(colDef => columnDefToSchema(colDef, defaultNotNull));
848
- const pkDefinition = findPKDefinition(preliminaryColumnSchemas, astConstraintsToProcess);
849
- const finalColumnSchemas = preliminaryColumnSchemas.map((col, idx) => {
850
- const isPkColumn = pkDefinition.some(pkCol => pkCol.index === idx);
851
- let pkOrder = 0;
852
- if (isPkColumn) {
853
- pkOrder = pkDefinition.findIndex(pkC => pkC.index === idx) + 1;
854
- }
855
- return {
856
- ...col,
857
- primaryKey: isPkColumn,
858
- pkOrder: pkOrder,
859
- notNull: isPkColumn ? true : col.notNull,
860
- };
861
- });
862
- const checkConstraintsSchema = [];
863
- astColumnsToProcess.forEach(colDef => {
864
- colDef.constraints?.forEach(con => {
865
- if (con.type === 'check' && con.expr) {
866
- checkConstraintsSchema.push({
867
- name: con.name ?? `_check_${colDef.name}`,
868
- expr: con.expr,
869
- operations: opsToMask(con.operations),
870
- deferrable: con.deferrable,
871
- initiallyDeferred: con.initiallyDeferred
872
- });
873
- }
874
- });
875
- });
876
- (astConstraintsToProcess || []).forEach(con => {
877
- if (con.type === 'check' && con.expr) {
878
- checkConstraintsSchema.push({
879
- name: con.name,
880
- expr: con.expr,
881
- operations: opsToMask(con.operations),
882
- deferrable: con.deferrable,
883
- initiallyDeferred: con.initiallyDeferred
884
- });
885
- }
886
- });
887
- // Process mutation context definitions if present
888
- const mutationContextSchemas = stmt.contextDefinitions
889
- ? stmt.contextDefinitions.map(varDef => mutationContextVarToSchema(varDef, defaultNotNull))
890
- : undefined;
891
- const tableSchema = {
892
- name: tableName,
893
- schemaName: targetSchemaName,
894
- columns: Object.freeze(finalColumnSchemas),
895
- columnIndexMap: buildColumnIndexMap(finalColumnSchemas),
896
- primaryKeyDefinition: pkDefinition,
897
- checkConstraints: Object.freeze(checkConstraintsSchema),
898
- isTemporary: !!stmt.isTemporary,
899
- isView: false,
900
- vtabModuleName: moduleName,
901
- vtabArgs: effectiveModuleArgs,
902
- vtabModule: moduleInfo.module,
903
- vtabAuxData: moduleInfo.auxData,
904
- estimatedRows: 0,
905
- mutationContext: mutationContextSchemas ? Object.freeze(mutationContextSchemas) : undefined,
906
- };
907
- // Use connect() instead of create() - the storage already exists
948
+ const { moduleName, effectiveModuleArgs, moduleInfo } = this.resolveModuleInfo(stmt);
949
+ const tableSchema = this.buildTableSchemaFromAST(stmt, moduleName, effectiveModuleArgs, moduleInfo);
908
950
  try {
909
- await moduleInfo.module.connect(this.db, moduleInfo.auxData, moduleName, targetSchemaName, tableName, effectiveModuleArgs, tableSchema // Pass the full schema so the module can use it
910
- );
951
+ await moduleInfo.module.connect(this.db, moduleInfo.auxData, moduleName, targetSchemaName, tableName, effectiveModuleArgs, tableSchema);
911
952
  }
912
953
  catch (e) {
913
954
  const message = e instanceof Error ? e.message : String(e);
914
955
  throw new QuereusError(`Module '${moduleName}' connect failed during import for table '${tableName}': ${message}`, StatusCode.ERROR);
915
956
  }
916
- // Ensure schema exists
917
957
  let schema = this.getSchema(targetSchemaName);
918
958
  if (!schema) {
919
- schema = new Schema(targetSchemaName);
920
- this.schemas.set(targetSchemaName.toLowerCase(), schema);
959
+ const lowerSchemaName = targetSchemaName.toLowerCase();
960
+ schema = new Schema(lowerSchemaName);
961
+ this.schemas.set(lowerSchemaName, schema);
921
962
  }
922
- // Register without notifying change listeners (this is an import, not a create)
923
963
  schema.addTable(tableSchema);
924
964
  log(`Imported table %s.%s using module %s`, targetSchemaName, tableName, moduleName);
925
965
  return { type: 'table', name: `${targetSchemaName}.${tableName}` };