@intentius/chant-lexicon-sql 0.124.46 → 0.124.49

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 (402) hide show
  1. package/dist/change-set.d.ts +1 -1
  2. package/dist/change-set.d.ts.map +1 -1
  3. package/dist/change-set.js +2 -1
  4. package/dist/clickhouse/apply/statements.d.ts +9 -0
  5. package/dist/clickhouse/apply/statements.d.ts.map +1 -1
  6. package/dist/clickhouse/apply/statements.js +24 -0
  7. package/dist/clickhouse/import/live-export.d.ts +7 -3
  8. package/dist/clickhouse/import/live-export.d.ts.map +1 -1
  9. package/dist/clickhouse/import/live-export.js +21 -5
  10. package/dist/clickhouse/live/named-collections.d.ts +27 -0
  11. package/dist/clickhouse/live/named-collections.d.ts.map +1 -0
  12. package/dist/clickhouse/live/named-collections.js +53 -0
  13. package/dist/clickhouse/live/undeclarable.d.ts +15 -3
  14. package/dist/clickhouse/live/undeclarable.d.ts.map +1 -1
  15. package/dist/clickhouse/live/undeclarable.js +18 -4
  16. package/dist/clickhouse/named-collections.d.ts +83 -0
  17. package/dist/clickhouse/named-collections.d.ts.map +1 -0
  18. package/dist/clickhouse/named-collections.js +203 -0
  19. package/dist/clickhouse/parser.d.ts.map +1 -1
  20. package/dist/clickhouse/parser.js +1 -1
  21. package/dist/clickhouse/plan/commands.d.ts +2 -1
  22. package/dist/clickhouse/plan/commands.d.ts.map +1 -1
  23. package/dist/clickhouse/plan/commands.js +17 -2
  24. package/dist/clickhouse/plan/diff.d.ts +15 -0
  25. package/dist/clickhouse/plan/diff.d.ts.map +1 -1
  26. package/dist/clickhouse/plan/diff.js +43 -1
  27. package/dist/clickhouse/plan/disruption.d.ts.map +1 -1
  28. package/dist/clickhouse/plan/disruption.js +5 -0
  29. package/dist/clickhouse/plan/rebuild-handoff.d.ts.map +1 -1
  30. package/dist/clickhouse/plan/rebuild-handoff.js +4 -0
  31. package/dist/clickhouse/plan/report.d.ts.map +1 -1
  32. package/dist/clickhouse/plan/report.js +6 -1
  33. package/dist/clickhouse/plan/rules.d.ts +5 -1
  34. package/dist/clickhouse/plan/rules.d.ts.map +1 -1
  35. package/dist/clickhouse/plan/rules.js +7 -3
  36. package/dist/clickhouse/plan/statements.d.ts +29 -0
  37. package/dist/clickhouse/plan/statements.d.ts.map +1 -0
  38. package/dist/clickhouse/plan/statements.js +334 -0
  39. package/dist/clickhouse/plan/stream.d.ts +40 -0
  40. package/dist/clickhouse/plan/stream.d.ts.map +1 -0
  41. package/dist/clickhouse/plan/stream.js +107 -0
  42. package/dist/clickhouse/rebuild/observe.d.ts +3 -1
  43. package/dist/clickhouse/rebuild/observe.d.ts.map +1 -1
  44. package/dist/clickhouse/rebuild/observe.js +14 -1
  45. package/dist/clickhouse/review-catalog.d.ts +213 -0
  46. package/dist/clickhouse/review-catalog.d.ts.map +1 -0
  47. package/dist/clickhouse/review-catalog.js +330 -0
  48. package/dist/codegen/classifier-page.d.ts.map +1 -1
  49. package/dist/codegen/classifier-page.js +44 -4
  50. package/dist/codegen/clickhouse-module.d.ts.map +1 -1
  51. package/dist/codegen/clickhouse-module.js +3 -0
  52. package/dist/codegen/coverage-page.d.ts.map +1 -1
  53. package/dist/codegen/coverage-page.js +5 -3
  54. package/dist/codegen/docs.js +1 -1
  55. package/dist/codegen/postgres-classifier-page.js +2 -2
  56. package/dist/codegen/registry.d.ts.map +1 -1
  57. package/dist/codegen/registry.js +10 -0
  58. package/dist/composites/catalog.d.ts.map +1 -1
  59. package/dist/composites/catalog.js +100 -0
  60. package/dist/composites/clickhouse.d.ts +2 -0
  61. package/dist/composites/clickhouse.d.ts.map +1 -1
  62. package/dist/composites/clickhouse.js +2 -0
  63. package/dist/composites/otel-tables.d.ts +100 -0
  64. package/dist/composites/otel-tables.d.ts.map +1 -0
  65. package/dist/composites/otel-tables.js +282 -0
  66. package/dist/composites/stream-ingest.d.ts +63 -0
  67. package/dist/composites/stream-ingest.d.ts.map +1 -0
  68. package/dist/composites/stream-ingest.js +39 -0
  69. package/dist/core/statement-class.d.ts +55 -0
  70. package/dist/core/statement-class.d.ts.map +1 -0
  71. package/dist/core/statement-class.js +43 -0
  72. package/dist/coverage/clickhouse.json +1 -1
  73. package/dist/coverage/postgres.json +12 -12
  74. package/dist/coverage.d.ts +16 -6
  75. package/dist/coverage.d.ts.map +1 -1
  76. package/dist/coverage.js +10 -5
  77. package/dist/drizzle-command.d.ts +17 -0
  78. package/dist/drizzle-command.d.ts.map +1 -0
  79. package/dist/drizzle-command.js +91 -0
  80. package/dist/drizzle.d.ts +70 -0
  81. package/dist/drizzle.d.ts.map +1 -0
  82. package/dist/drizzle.js +689 -0
  83. package/dist/files/clickhouse.d.ts.map +1 -1
  84. package/dist/files/clickhouse.js +8 -1
  85. package/dist/files/common.d.ts +13 -0
  86. package/dist/files/common.d.ts.map +1 -1
  87. package/dist/files/common.js +5 -0
  88. package/dist/files/postgres.d.ts.map +1 -1
  89. package/dist/files/postgres.js +35 -3
  90. package/dist/generated/clickhouse.d.ts +2 -0
  91. package/dist/generated/clickhouse.d.ts.map +1 -1
  92. package/dist/generated/clickhouse.js +2 -0
  93. package/dist/import-parser.d.ts +21 -1
  94. package/dist/import-parser.d.ts.map +1 -1
  95. package/dist/import-parser.js +79 -5
  96. package/dist/index.d.ts +1 -1
  97. package/dist/index.d.ts.map +1 -1
  98. package/dist/index.js +1 -1
  99. package/dist/integrity.json +7 -6
  100. package/dist/lint/post-synth/audit-entries.d.ts.map +1 -1
  101. package/dist/lint/post-synth/audit-entries.js +1 -0
  102. package/dist/lint/post-synth/index.d.ts.map +1 -1
  103. package/dist/lint/post-synth/index.js +2 -0
  104. package/dist/lint/post-synth/postgres-names.d.ts.map +1 -1
  105. package/dist/lint/post-synth/postgres-names.js +3 -0
  106. package/dist/lint/post-synth/sqlch128.d.ts +18 -0
  107. package/dist/lint/post-synth/sqlch128.d.ts.map +1 -0
  108. package/dist/lint/post-synth/sqlch128.js +222 -0
  109. package/dist/lint/rules/postgres-templates.js +2 -2
  110. package/dist/lsp/postgres-template.d.ts.map +1 -1
  111. package/dist/lsp/postgres-template.js +21 -0
  112. package/dist/manifest.json +1 -1
  113. package/dist/mcp/postgres.js +1 -1
  114. package/dist/meta.json +50 -0
  115. package/dist/migrate/from-postgres/detect.d.ts +4 -0
  116. package/dist/migrate/from-postgres/detect.d.ts.map +1 -0
  117. package/dist/migrate/from-postgres/detect.js +7 -0
  118. package/dist/migrate/from-postgres/emit.d.ts +26 -0
  119. package/dist/migrate/from-postgres/emit.d.ts.map +1 -0
  120. package/dist/migrate/from-postgres/emit.js +86 -0
  121. package/dist/migrate/from-postgres/index.d.ts +51 -0
  122. package/dist/migrate/from-postgres/index.d.ts.map +1 -0
  123. package/dist/migrate/from-postgres/index.js +115 -0
  124. package/dist/migrate/from-postgres/translate.d.ts +73 -0
  125. package/dist/migrate/from-postgres/translate.d.ts.map +1 -0
  126. package/dist/migrate/from-postgres/translate.js +261 -0
  127. package/dist/migrate/from-postgres/types.d.ts +51 -0
  128. package/dist/migrate/from-postgres/types.d.ts.map +1 -0
  129. package/dist/migrate/from-postgres/types.js +211 -0
  130. package/dist/migration-classify.d.ts +23 -0
  131. package/dist/migration-classify.d.ts.map +1 -0
  132. package/dist/migration-classify.js +44 -0
  133. package/dist/migration-replay.d.ts +73 -0
  134. package/dist/migration-replay.d.ts.map +1 -0
  135. package/dist/migration-replay.js +294 -0
  136. package/dist/okf/index.md +11 -0
  137. package/dist/okf/rules/SQLCH128.md +11 -0
  138. package/dist/okf/types/PostgresForeignDataWrapper.md +9 -0
  139. package/dist/okf/types/PostgresForeignServer.md +9 -0
  140. package/dist/okf/types/PostgresForeignTable.md +9 -0
  141. package/dist/okf/types/PostgresOperator.md +9 -0
  142. package/dist/okf/types/PostgresOperatorClass.md +9 -0
  143. package/dist/okf/types/PostgresOperatorFamily.md +9 -0
  144. package/dist/okf/types/PostgresPublication.md +9 -0
  145. package/dist/okf/types/PostgresStatistics.md +9 -0
  146. package/dist/okf/types/PostgresTextSearchConfiguration.md +9 -0
  147. package/dist/okf/types/PostgresTextSearchDictionary.md +9 -0
  148. package/dist/op/activities/postgres-migration.d.ts.map +1 -1
  149. package/dist/op/activities/postgres-migration.js +4 -0
  150. package/dist/op/activity-contracts.d.ts +20 -0
  151. package/dist/op/activity-contracts.d.ts.map +1 -1
  152. package/dist/op/activity-contracts.js +2 -0
  153. package/dist/plugin.d.ts.map +1 -1
  154. package/dist/plugin.js +49 -2
  155. package/dist/postgres/access/acl.js +1 -1
  156. package/dist/postgres/access/import.js +1 -1
  157. package/dist/postgres/apply/apply.js +13 -1
  158. package/dist/postgres/apply/statements.d.ts.map +1 -1
  159. package/dist/postgres/apply/statements.js +243 -4
  160. package/dist/postgres/constraint-names.d.ts +30 -0
  161. package/dist/postgres/constraint-names.d.ts.map +1 -0
  162. package/dist/postgres/constraint-names.js +72 -0
  163. package/dist/postgres/entities.d.ts +229 -2
  164. package/dist/postgres/entities.d.ts.map +1 -1
  165. package/dist/postgres/entities.js +326 -5
  166. package/dist/postgres/entity-types.d.ts +10 -0
  167. package/dist/postgres/entity-types.d.ts.map +1 -1
  168. package/dist/postgres/entity-types.js +10 -0
  169. package/dist/postgres/import/generator.d.ts.map +1 -1
  170. package/dist/postgres/import/generator.js +65 -2
  171. package/dist/postgres/import/live-export.d.ts.map +1 -1
  172. package/dist/postgres/import/live-export.js +2 -0
  173. package/dist/postgres/live/catalog-kinds.d.ts +20 -0
  174. package/dist/postgres/live/catalog-kinds.d.ts.map +1 -1
  175. package/dist/postgres/live/catalog-kinds.js +452 -0
  176. package/dist/postgres/live/catalog.d.ts +2 -0
  177. package/dist/postgres/live/catalog.d.ts.map +1 -1
  178. package/dist/postgres/live/catalog.js +3 -1
  179. package/dist/postgres/live/describe-resources.d.ts.map +1 -1
  180. package/dist/postgres/live/describe-resources.js +12 -2
  181. package/dist/postgres/migrate/backfill.d.ts +2 -0
  182. package/dist/postgres/migrate/backfill.d.ts.map +1 -1
  183. package/dist/postgres/migrate/backfill.js +7 -1
  184. package/dist/postgres/migrate/carry.d.ts +45 -1
  185. package/dist/postgres/migrate/carry.d.ts.map +1 -1
  186. package/dist/postgres/migrate/carry.js +72 -8
  187. package/dist/postgres/migrate/observe.d.ts +28 -4
  188. package/dist/postgres/migrate/observe.d.ts.map +1 -1
  189. package/dist/postgres/migrate/observe.js +45 -13
  190. package/dist/postgres/migrate/op.d.ts +26 -1
  191. package/dist/postgres/migrate/op.d.ts.map +1 -1
  192. package/dist/postgres/migrate/op.js +3 -1
  193. package/dist/postgres/migrate/replication.d.ts +42 -0
  194. package/dist/postgres/migrate/replication.d.ts.map +1 -1
  195. package/dist/postgres/migrate/replication.js +53 -0
  196. package/dist/postgres/migrate/steps.d.ts +35 -2
  197. package/dist/postgres/migrate/steps.d.ts.map +1 -1
  198. package/dist/postgres/migrate/steps.js +158 -12
  199. package/dist/postgres/parser.d.ts +144 -1
  200. package/dist/postgres/parser.d.ts.map +1 -1
  201. package/dist/postgres/parser.js +370 -4
  202. package/dist/postgres/plan/deep.d.ts.map +1 -1
  203. package/dist/postgres/plan/deep.js +43 -4
  204. package/dist/postgres/plan/diff.d.ts.map +1 -1
  205. package/dist/postgres/plan/diff.js +154 -1
  206. package/dist/postgres/plan/normalize.d.ts +28 -2
  207. package/dist/postgres/plan/normalize.d.ts.map +1 -1
  208. package/dist/postgres/plan/normalize.js +260 -1
  209. package/dist/postgres/plan/rules.d.ts +4 -0
  210. package/dist/postgres/plan/rules.d.ts.map +1 -1
  211. package/dist/postgres/plan/rules.js +6 -2
  212. package/dist/postgres/plan/schema.js +1 -1
  213. package/dist/postgres/plan/statements.d.ts +26 -0
  214. package/dist/postgres/plan/statements.d.ts.map +1 -0
  215. package/dist/postgres/plan/statements.js +364 -0
  216. package/dist/postgres/secret-options.d.ts +10 -0
  217. package/dist/postgres/secret-options.d.ts.map +1 -0
  218. package/dist/postgres/secret-options.js +9 -0
  219. package/dist/postgres/testing/roundtrip-schema.d.ts +4 -2
  220. package/dist/postgres/testing/roundtrip-schema.d.ts.map +1 -1
  221. package/dist/postgres/testing/roundtrip-schema.js +24 -1
  222. package/dist/postgres.d.ts +1 -1
  223. package/dist/postgres.d.ts.map +1 -1
  224. package/dist/postgres.js +1 -1
  225. package/dist/rules/audit-entries.ts +1 -0
  226. package/dist/rules/postgres-names.ts +2 -0
  227. package/dist/rules/postgres-templates.ts +2 -2
  228. package/dist/rules/sqlch128.ts +230 -0
  229. package/dist/serializer.d.ts +5 -0
  230. package/dist/serializer.d.ts.map +1 -1
  231. package/dist/serializer.js +13 -2
  232. package/dist/sql-types-command.d.ts +13 -0
  233. package/dist/sql-types-command.d.ts.map +1 -1
  234. package/dist/sql-types-command.js +31 -16
  235. package/dist/sql-types.d.ts +22 -0
  236. package/dist/sql-types.d.ts.map +1 -1
  237. package/dist/sql-types.js +10 -6
  238. package/dist/sqlserver/lexer.d.ts +37 -0
  239. package/dist/sqlserver/lexer.d.ts.map +1 -0
  240. package/dist/sqlserver/lexer.js +254 -0
  241. package/dist/sqlserver/parse.d.ts +185 -0
  242. package/dist/sqlserver/parse.d.ts.map +1 -0
  243. package/dist/sqlserver/parse.js +767 -0
  244. package/dist/sqlserver/translate.d.ts +34 -0
  245. package/dist/sqlserver/translate.d.ts.map +1 -0
  246. package/dist/sqlserver/translate.js +495 -0
  247. package/dist/sqlserver/types.d.ts +44 -0
  248. package/dist/sqlserver/types.d.ts.map +1 -0
  249. package/dist/sqlserver/types.js +133 -0
  250. package/dist/sqlserver/validate.d.ts +31 -0
  251. package/dist/sqlserver/validate.d.ts.map +1 -0
  252. package/dist/sqlserver/validate.js +67 -0
  253. package/dist/validate.d.ts.map +1 -1
  254. package/dist/validate.js +10 -0
  255. package/package.json +2 -2
  256. package/src/change-set.ts +2 -1
  257. package/src/clickhouse/apply/statements.ts +25 -0
  258. package/src/clickhouse/import/live-export.ts +20 -5
  259. package/src/clickhouse/live/named-collections.e2e.test.ts +88 -0
  260. package/src/clickhouse/live/named-collections.ts +61 -0
  261. package/src/clickhouse/live/undeclarable.e2e.test.ts +5 -3
  262. package/src/clickhouse/live/undeclarable.ts +20 -4
  263. package/src/clickhouse/named-collections.test.ts +187 -0
  264. package/src/clickhouse/named-collections.ts +224 -0
  265. package/src/clickhouse/parser.ts +2 -1
  266. package/src/clickhouse/plan/commands.ts +17 -2
  267. package/src/clickhouse/plan/diff.ts +57 -1
  268. package/src/clickhouse/plan/disruption.ts +5 -0
  269. package/src/clickhouse/plan/rebuild-handoff.ts +3 -0
  270. package/src/clickhouse/plan/report.ts +6 -1
  271. package/src/clickhouse/plan/rules.ts +14 -4
  272. package/src/clickhouse/plan/statements.test.ts +61 -0
  273. package/src/clickhouse/plan/statements.ts +306 -0
  274. package/src/clickhouse/plan/stream-s3queue.e2e.test.ts +148 -0
  275. package/src/clickhouse/plan/stream.test.ts +237 -0
  276. package/src/clickhouse/plan/stream.ts +111 -0
  277. package/src/clickhouse/rebuild/observe.ts +15 -1
  278. package/src/clickhouse/review-catalog.test.ts +181 -0
  279. package/src/clickhouse/review-catalog.ts +489 -0
  280. package/src/codegen/classifier-page.ts +44 -4
  281. package/src/codegen/clickhouse-module.ts +3 -0
  282. package/src/codegen/coverage-page.ts +5 -3
  283. package/src/codegen/docs.ts +1 -1
  284. package/src/codegen/postgres-classifier-page.ts +2 -2
  285. package/src/codegen/registry.ts +10 -0
  286. package/src/composites/catalog.test.ts +6 -1
  287. package/src/composites/catalog.ts +100 -0
  288. package/src/composites/clickhouse.ts +2 -0
  289. package/src/composites/composites.test.ts +1 -1
  290. package/src/composites/otel-tables.test.ts +118 -0
  291. package/src/composites/otel-tables.ts +339 -0
  292. package/src/composites/stream-ingest.test.ts +114 -0
  293. package/src/composites/stream-ingest.ts +82 -0
  294. package/src/core/statement-class.ts +88 -0
  295. package/src/core/undeclarable.test.ts +6 -5
  296. package/src/coverage/clickhouse.json +1 -1
  297. package/src/coverage/postgres.json +12 -12
  298. package/src/coverage.test.ts +27 -2
  299. package/src/coverage.ts +18 -7
  300. package/src/drizzle-command.ts +94 -0
  301. package/src/drizzle-kit.e2e.test.ts +89 -0
  302. package/src/drizzle-types.e2e.test.ts +67 -0
  303. package/src/drizzle.test.ts +358 -0
  304. package/src/drizzle.ts +742 -0
  305. package/src/files/clickhouse.ts +8 -1
  306. package/src/files/common.ts +14 -1
  307. package/src/files/postgres.ts +34 -3
  308. package/src/generated/clickhouse.ts +3 -0
  309. package/src/generated/lexicon-sql.json +50 -0
  310. package/src/import-parser.sqlserver.test.ts +92 -0
  311. package/src/import-parser.ts +79 -5
  312. package/src/index.ts +1 -1
  313. package/src/lint/post-synth/audit-entries.ts +1 -0
  314. package/src/lint/post-synth/index.ts +2 -0
  315. package/src/lint/post-synth/postgres-checks.test.ts +8 -1
  316. package/src/lint/post-synth/postgres-names.ts +2 -0
  317. package/src/lint/post-synth/sqlch128.test.ts +107 -0
  318. package/src/lint/post-synth/sqlch128.ts +230 -0
  319. package/src/lint/rules/postgres-templates.ts +2 -2
  320. package/src/lsp/postgres-template.ts +20 -0
  321. package/src/mcp/postgres.ts +1 -1
  322. package/src/migrate/from-postgres/cli.test.ts +165 -0
  323. package/src/migrate/from-postgres/detect.ts +7 -0
  324. package/src/migrate/from-postgres/emit.ts +96 -0
  325. package/src/migrate/from-postgres/example.test.ts +205 -0
  326. package/src/migrate/from-postgres/index.ts +122 -0
  327. package/src/migrate/from-postgres/translate.test.ts +242 -0
  328. package/src/migrate/from-postgres/translate.ts +359 -0
  329. package/src/migrate/from-postgres/types.test.ts +116 -0
  330. package/src/migrate/from-postgres/types.ts +236 -0
  331. package/src/migrate/from-postgres/validate.e2e.test.ts +44 -0
  332. package/src/migrate/from-postgres/workspace.e2e.test.ts +114 -0
  333. package/src/migration-classify.test.ts +150 -0
  334. package/src/migration-classify.ts +45 -0
  335. package/src/migration-replay.e2e.test.ts +155 -0
  336. package/src/migration-replay.test.ts +173 -0
  337. package/src/migration-replay.ts +289 -0
  338. package/src/op/__snapshots__/watch-pipeline.test.ts.snap +2 -2
  339. package/src/op/activities/postgres-migration.ts +4 -0
  340. package/src/op/activity-contracts.ts +2 -0
  341. package/src/op/watch-pipeline.test.ts +8 -1
  342. package/src/plugin.ts +51 -2
  343. package/src/postgres/access/acl.ts +1 -1
  344. package/src/postgres/access/import.ts +1 -1
  345. package/src/postgres/apply/apply.ts +14 -1
  346. package/src/postgres/apply/statements.ts +225 -4
  347. package/src/postgres/constraint-names.ts +71 -0
  348. package/src/postgres/database-kinds.test.ts +865 -0
  349. package/src/postgres/entities.ts +541 -5
  350. package/src/postgres/entity-types.ts +10 -0
  351. package/src/postgres/import/generator.ts +54 -2
  352. package/src/postgres/import/live-export.ts +1 -0
  353. package/src/postgres/live/catalog-kinds.ts +494 -0
  354. package/src/postgres/live/catalog.ts +6 -1
  355. package/src/postgres/live/database-kinds.e2e.test.ts +164 -0
  356. package/src/postgres/live/describe-resources.ts +13 -2
  357. package/src/postgres/live/undeclarable.e2e.test.ts +13 -6
  358. package/src/postgres/migrate/backfill.ts +13 -1
  359. package/src/postgres/migrate/carry.ts +103 -8
  360. package/src/postgres/migrate/followups.e2e.test.ts +218 -0
  361. package/src/postgres/migrate/followups.test.ts +199 -0
  362. package/src/postgres/migrate/kinds.e2e.test.ts +5 -5
  363. package/src/postgres/migrate/observe.ts +56 -15
  364. package/src/postgres/migrate/op.ts +28 -1
  365. package/src/postgres/migrate/partition.e2e.test.ts +129 -0
  366. package/src/postgres/migrate/partition.test.ts +206 -0
  367. package/src/postgres/migrate/replication.ts +66 -0
  368. package/src/postgres/migrate/steps.ts +157 -12
  369. package/src/postgres/migrate/subscriber.e2e.test.ts +141 -0
  370. package/src/postgres/migrate/subscriber.test.ts +59 -0
  371. package/src/postgres/parser.ts +455 -4
  372. package/src/postgres/plan/deep.ts +42 -4
  373. package/src/postgres/plan/diff.ts +137 -1
  374. package/src/postgres/plan/normalize.ts +277 -1
  375. package/src/postgres/plan/rules.ts +32 -4
  376. package/src/postgres/plan/schema.ts +1 -1
  377. package/src/postgres/plan/statements.test.ts +78 -0
  378. package/src/postgres/plan/statements.ts +299 -0
  379. package/src/postgres/secret-options.ts +10 -0
  380. package/src/postgres/testing/roundtrip-schema.ts +24 -1
  381. package/src/postgres.ts +33 -0
  382. package/src/serializer.ts +13 -2
  383. package/src/skills/chant-sql-postgres-migration.md +4 -3
  384. package/src/skills/chant-sql-postgres.md +11 -1
  385. package/src/skills/chant-sql.md +2 -1
  386. package/src/sql-files.test.ts +33 -0
  387. package/src/sql-types-command.ts +38 -16
  388. package/src/sql-types.ts +11 -6
  389. package/src/sqlserver/fixture.test.ts +186 -0
  390. package/src/sqlserver/import-cli.test.ts +61 -0
  391. package/src/sqlserver/lexer.ts +260 -0
  392. package/src/sqlserver/parse.ts +865 -0
  393. package/src/sqlserver/translate.test.ts +396 -0
  394. package/src/sqlserver/translate.ts +558 -0
  395. package/src/sqlserver/types.test.ts +102 -0
  396. package/src/sqlserver/types.ts +154 -0
  397. package/src/sqlserver/validate.e2e.test.ts +32 -0
  398. package/src/sqlserver/validate.test.ts +49 -0
  399. package/src/sqlserver/validate.ts +76 -0
  400. package/src/validate.ts +10 -0
  401. package/src/workspace-kinds.test.ts +11 -0
  402. package/workspace-kinds.json +100 -2
@@ -0,0 +1,230 @@
1
+ import { DATABASE_ENGINES, FORMATS, TABLE_ENGINES } from "../../generated/clickhouse";
2
+ import { parseEngineSyntax } from "../../clickhouse/engine-syntax";
3
+ import { COLLECTION_ENGINES, engineCollection } from "../../clickhouse/named-collections";
4
+ import { isTrivia, tokenizeText, type Token } from "../../clickhouse/tokens";
5
+ import { checkOf, splitTop } from "./clickhouse-helpers";
6
+ import { clickhouseObjects, type OutputObject } from "./sql-helpers";
7
+
8
+ /** A syntax-line argument that holds a secret: `password`, `secret_access_key`, `account_key`, `session_token`, `oauth_token`. */
9
+ const SECRET_ARGUMENT = /password|secret|account_key|session_token|oauth_token/i;
10
+
11
+ /** A `key = value` argument or a setting that holds a secret: the above, and `kafka_sasl_password`, `nats_token`. */
12
+ const SECRET_KEY = /password|secret|account_key|session_token|oauth_token|(?:^|_)token$|private_key/i;
13
+
14
+ /** Credentials written inside another value: a URL's `user:password@`, an Azure connection string's key or signature. */
15
+ const EMBEDDED = [
16
+ { re: /^[a-z][a-z0-9+.-]*:\/\/[^/@:\s]+:[^/@\s]+@/i, what: "a URL with a password in it" },
17
+ { re: /(?:^|;)\s*(?:AccountKey|SharedAccessSignature)\s*=/i, what: "a connection string with an account key or signature in it" },
18
+ ];
19
+
20
+ /** Compression methods the integration engines take after the format. */
21
+ const COMPRESSION = new Set(["none", "auto", "gzip", "gz", "deflate", "br", "brotli", "xz", "lzma", "zstd", "zst", "lz4", "bz2", "snappy"]);
22
+ const FORMAT_NAMES = new Set(FORMATS.map((f) => f.toLowerCase()));
23
+
24
+ /** The table functions whose arguments follow an engine's syntax line, lower case, by engine. */
25
+ const FUNCTION_ENGINE: Readonly<Record<string, string>> = {
26
+ s3: "S3",
27
+ gcs: "S3",
28
+ oss: "S3",
29
+ cosn: "S3",
30
+ url: "URL",
31
+ mysql: "MySQL",
32
+ postgresql: "PostgreSQL",
33
+ mongodb: "MongoDB",
34
+ azureblobstorage: "AzureBlobStorage",
35
+ iceberg: "Iceberg",
36
+ icebergs3: "IcebergS3",
37
+ icebergazure: "IcebergAzure",
38
+ deltalake: "DeltaLake",
39
+ deltalakes3: "DeltaLakeS3",
40
+ deltalakeazure: "DeltaLakeAzure",
41
+ hudi: "Hudi",
42
+ paimon: "Paimon",
43
+ paimons3: "PaimonS3",
44
+ arrowflight: "ArrowFlight",
45
+ ytsaurus: "YTsaurus",
46
+ };
47
+
48
+ /** `remote('addresses', db, table, 'user', 'password')`: no syntax line says it, so its password's position is written here. */
49
+ const FUNCTION_SECRETS: Readonly<Record<string, Array<{ name: string; position: number }>>> = {
50
+ remote: [{ name: "password", position: 4 }],
51
+ remotesecure: [{ name: "password", position: 4 }],
52
+ };
53
+
54
+ const ENGINE_SYNTAX = { ...TABLE_ENGINES, ...DATABASE_ENGINES } as Readonly<Record<string, { syntax: string } | undefined>>;
55
+
56
+ /** The secret arguments an engine's syntax line names, with their positions. */
57
+ function secretPositions(engine: string): Array<{ name: string; position: number }> {
58
+ const syntax = ENGINE_SYNTAX[engine]?.syntax;
59
+ const parsed = syntax ? parseEngineSyntax(syntax) : undefined;
60
+ if (!parsed) return [];
61
+ return parsed.args
62
+ .filter((a) => !a.named && a.name.split("|").some((n) => SECRET_ARGUMENT.test(n)))
63
+ .map((a) => ({ name: a.name.split("|").find((n) => SECRET_ARGUMENT.test(n))!, position: a.position }));
64
+ }
65
+
66
+ /** The text of a string literal, or undefined for anything else. */
67
+ function stringValue(text: string): string | undefined {
68
+ const t = text.trim();
69
+ if (!/^'(?:[^'\\]|\\.|'')*'$/.test(t)) return undefined;
70
+ return t.slice(1, -1).replace(/\\(.)/g, "$1").replace(/''/g, "'");
71
+ }
72
+
73
+ /**
74
+ * Whether the arguments before `position` leave it where the syntax line puts
75
+ * it. An optional group (`[, access_key_id, secret_access_key]`) may be left
76
+ * out, and the format and compression move up into its place:
77
+ * `S3('url', 'Parquet', 'gzip')`. When a format, a compression method or
78
+ * `NOSIGN` comes earlier, the position says nothing.
79
+ */
80
+ function aligned(args: readonly string[], position: number): boolean {
81
+ for (const a of args.slice(1, position)) {
82
+ const t = a.trim();
83
+ if (t.toUpperCase() === "NOSIGN") return false;
84
+ const v = stringValue(t)?.toLowerCase();
85
+ if (v !== undefined && (FORMAT_NAMES.has(v) || COMPRESSION.has(v))) return false;
86
+ }
87
+ return true;
88
+ }
89
+
90
+ interface Finding {
91
+ where: string;
92
+ what: string;
93
+ masked: boolean;
94
+ }
95
+
96
+ /** The literal credentials in one engine's or table function's arguments. */
97
+ function argumentFindings(label: string, args: readonly string[], secrets: ReadonlyArray<{ name: string; position: number }>, collection: boolean): Finding[] {
98
+ const out: Finding[] = [];
99
+ const add = (where: string, what: string, value: string) => out.push({ where, what, masked: value === "[HIDDEN]" });
100
+ // After a named collection, the arguments are `key = value` overrides, not positions.
101
+ if (!collection) {
102
+ for (const s of secrets) {
103
+ const arg = args[s.position];
104
+ const value = arg !== undefined ? stringValue(arg) : undefined;
105
+ if (value && aligned(args, s.position)) add(`${label} argument ${s.name}`, "a literal credential", value);
106
+ }
107
+ }
108
+ args.forEach((arg, i) => {
109
+ const kv = /^\s*([A-Za-z_][A-Za-z0-9_]*)\s*=\s*([\s\S]+)$/.exec(arg);
110
+ if (kv) {
111
+ const value = stringValue(kv[2]!);
112
+ if (value && SECRET_KEY.test(kv[1]!)) add(`${label} argument ${kv[1]}`, "a literal credential", value);
113
+ return;
114
+ }
115
+ const value = stringValue(arg);
116
+ if (!value) return;
117
+ for (const e of EMBEDDED) if (e.re.test(value)) add(`${label} argument ${i + 1}`, e.what, value);
118
+ });
119
+ return out;
120
+ }
121
+
122
+ /** Each table function call in a SQL text, with its arguments as written. */
123
+ function functionCalls(text: string): Array<{ name: string; args: string[] }> {
124
+ let tokens: Token[];
125
+ try {
126
+ tokens = tokenizeText(text, 0);
127
+ } catch {
128
+ return [];
129
+ }
130
+ const sig = tokens.map((t, i) => ({ t, i })).filter(({ t }) => !isTrivia(t));
131
+ const out: Array<{ name: string; args: string[] }> = [];
132
+ for (let k = 0; k + 1 < sig.length; k++) {
133
+ const fn = sig[k]!.t;
134
+ const open = sig[k + 1]!;
135
+ if (fn.kind !== "ident" || open.t.kind !== "punct" || open.t.text !== "(") continue;
136
+ const lower = fn.text.toLowerCase();
137
+ const base = lower.endsWith("cluster") ? lower.slice(0, -"cluster".length) : lower;
138
+ if (!(base in FUNCTION_ENGINE) && !(base in FUNCTION_SECRETS)) continue;
139
+ let depth = 0;
140
+ let end = open.i;
141
+ for (let j = open.i; j < tokens.length; j++) {
142
+ const t = tokens[j]!;
143
+ if (t.kind === "punct" && t.text === "(") depth++;
144
+ else if (t.kind === "punct" && t.text === ")" && --depth === 0) {
145
+ end = j;
146
+ break;
147
+ }
148
+ }
149
+ const inner = tokens
150
+ .slice(open.i + 1, end)
151
+ .map((t) => t.text)
152
+ .join("");
153
+ out.push({ name: fn.text, args: inner.trim() === "" ? [] : splitTop(inner) });
154
+ }
155
+ return out;
156
+ }
157
+
158
+ /** The literal credentials in each table function call a SQL text makes. */
159
+ function callFindings(text: string): Finding[] {
160
+ return functionCalls(text).flatMap((call) => {
161
+ const lower = call.name.toLowerCase();
162
+ const clustered = lower.endsWith("cluster") && !(lower in FUNCTION_ENGINE);
163
+ const base = clustered ? lower.slice(0, -"cluster".length) : lower;
164
+ // `s3Cluster(cluster, url, ...)`: the cluster comes first.
165
+ const args = clustered ? call.args.slice(1) : call.args;
166
+ const engine = FUNCTION_ENGINE[base];
167
+ const secrets = engine ? secretPositions(engine) : (FUNCTION_SECRETS[base] ?? []);
168
+ const collection = args[0] !== undefined && /^\s*(?:[A-Za-z_][A-Za-z0-9_]*|`[^`]+`)\s*$/.test(args[0]) && args[0].trim().toUpperCase() !== "NOSIGN";
169
+ return argumentFindings(`${call.name}()`, args, secrets, collection);
170
+ });
171
+ }
172
+
173
+ /** The literal credentials in a table's or database's engine and its settings. */
174
+ function engineFindings(o: OutputObject & { settings?: Record<string, string> }): Finding[] {
175
+ const engine = o.engine;
176
+ if (!engine) return [];
177
+ const out = argumentFindings(`ENGINE = ${engine.name}`, engine.args ?? [], secretPositions(engine.name), engineCollection(engine) !== undefined);
178
+ if (COLLECTION_ENGINES.has(engine.name)) {
179
+ for (const [key, raw] of Object.entries(o.settings ?? {})) {
180
+ const value = stringValue(raw);
181
+ if (value && SECRET_KEY.test(key)) out.push({ where: `${engine.name} setting ${key}`, what: "a literal credential", masked: value === "[HIDDEN]" });
182
+ }
183
+ }
184
+ return out;
185
+ }
186
+
187
+ /** `PASSWORD 'secret'` in a dictionary's source. */
188
+ function sourceFindings(dataSource: string): Finding[] {
189
+ const m = /\bPASSWORD\s+('(?:[^'\\]|\\.|'')*')/i.exec(dataSource);
190
+ const value = m ? stringValue(m[1]!) : undefined;
191
+ return value ? [{ where: "SOURCE PASSWORD", what: "a literal credential", masked: value === "[HIDDEN]" }] : [];
192
+ }
193
+
194
+ /**
195
+ * SQLCH128: an integration engine's or table function's argument holds a
196
+ * literal credential (#4395): `ENGINE = S3('https://...', 'AKIA...', 'secret')`,
197
+ * `mysql('db:3306', 'shop', 'orders', 'app', 'secret')`, a Kafka table's
198
+ * `kafka_sasl_password` setting, a dictionary source's `PASSWORD`.
199
+ *
200
+ * A credential is the environment's, so it does not belong in a declaration,
201
+ * the build output or `clickhouse.sql`, as `IDENTIFIED BY` does not on a
202
+ * user (`../../clickhouse/access.ts`). The secret arguments are found by name
203
+ * from each engine's syntax line in the pinned catalog (`password`,
204
+ * `secret_access_key`, `account_key`, `session_token`, `oauth_token`), as
205
+ * `key = value` overrides and settings by the same names, and inside a URL
206
+ * (`user:password@`) or an Azure connection string (`AccountKey=`). The fix
207
+ * is a named collection the environment creates, named in place of the
208
+ * arguments: `ENGINE = S3(lake_creds, format = 'Parquet')`.
209
+ */
210
+ export const sqlch128 = checkOf({ id: "SQLCH128", description: "An integration engine or table function argument holds a literal credential" }, (ctx, report) => {
211
+ for (const o of clickhouseObjects(ctx)) {
212
+ const props = o as OutputObject & { settings?: Record<string, string>; asFunction?: string; select?: string; dataSource?: string };
213
+ const findings = [
214
+ ...engineFindings(props),
215
+ ...(props.asFunction ? callFindings(props.asFunction) : []),
216
+ ...(props.select ? callFindings(props.select) : []),
217
+ ...(props.dataSource ? sourceFindings(props.dataSource) : []),
218
+ ];
219
+ for (const f of findings) {
220
+ const held = f.masked ? "holds '[HIDDEN]', the server's mask for a credential, in place of one" : `holds ${f.what}, which is the environment's`;
221
+ report({
222
+ severity: "error",
223
+ message:
224
+ `${o.export} (${o.name}): ${f.where} ${held}. ` +
225
+ "Create a named collection with the credentials on the server and name it in place of the arguments (ENGINE = S3(lake_creds, format = 'Parquet'), s3(lake_creds), SOURCE(MYSQL(NAME mysql_creds))); chant sql plan checks that it exists",
226
+ entity: o.export,
227
+ });
228
+ }
229
+ }
230
+ });
@@ -21,6 +21,11 @@
21
21
  * of each. Two databases of different dialects are two projects (two
22
22
  * workspace members, #3047 question 1).
23
23
  *
24
+ * A ClickHouse object that names a named collection (an engine's first
25
+ * argument, a table function's, a dictionary source's `NAME`) carries
26
+ * `namedCollections`, and the document lists every one the build names, so
27
+ * a plan can check each exists on the server (#4395).
28
+ *
24
29
  * A Postgres document also carries `postgresMajor`, the major the project
25
30
  * targets (`sql.postgresMajor`, else the newest pinned major). Post-synth
26
31
  * checks and the lock classifier read it; ClickHouse output has no such field.
@@ -1 +1 @@
1
- {"version":3,"file":"serializer.d.ts","sourceRoot":"","sources":["../src/serializer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAoB,MAAM,kBAAkB,CAAC;AAYjF,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAE/C;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,WAAW,CAAC,MAAM,EAAE,UAAU,CAAC,GAAG,MAAM,EAAE,CAkBnF;AAED,yEAAyE;AACzE,eAAO,MAAM,mBAAmB,mBAAmB,CAAC;AAEpD,gEAAgE;AAChE,eAAO,MAAM,iBAAiB,iBAAiB,CAAC;AAqEhD,eAAO,MAAM,aAAa,EAAE,UAyC3B,CAAC"}
1
+ {"version":3,"file":"serializer.d.ts","sourceRoot":"","sources":["../src/serializer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAoB,MAAM,kBAAkB,CAAC;AAajF,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAE/C;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,WAAW,CAAC,MAAM,EAAE,UAAU,CAAC,GAAG,MAAM,EAAE,CAkBnF;AAED,yEAAyE;AACzE,eAAO,MAAM,mBAAmB,mBAAmB,CAAC;AAEpD,gEAAgE;AAChE,eAAO,MAAM,iBAAiB,iBAAiB,CAAC;AAsEhD,eAAO,MAAM,aAAa,EAAE,UA6C3B,CAAC"}
@@ -21,6 +21,11 @@
21
21
  * of each. Two databases of different dialects are two projects (two
22
22
  * workspace members, #3047 question 1).
23
23
  *
24
+ * A ClickHouse object that names a named collection (an engine's first
25
+ * argument, a table function's, a dictionary source's `NAME`) carries
26
+ * `namedCollections`, and the document lists every one the build names, so
27
+ * a plan can check each exists on the server (#4395).
28
+ *
24
29
  * A Postgres document also carries `postgresMajor`, the major the project
25
30
  * targets (`sql.postgresMajor`, else the newest pinned major). Post-synth
26
31
  * checks and the lock classifier read it; ClickHouse output has no such field.
@@ -39,6 +44,7 @@ import { applyOrder, lineageJson, referenceName } from "./core/references.js";
39
44
  import { sqlFileLineOf, sqlFileOf, sqlFileReferences } from "./sql-files.js";
40
45
  import { relative } from "node:path";
41
46
  import { getProvenance } from "@intentius/chant/provenance";
47
+ import { namedCollectionReferences } from "./clickhouse/named-collections.js";
42
48
  export { applyOrder } from "./core/references.js";
43
49
  /**
44
50
  * A warning for each clause chant's parser does not know (#3872): where it
@@ -81,7 +87,8 @@ function objectJson(name, obj, names, extra = []) {
81
87
  props.lineage = lineageJson(props.lineage, names);
82
88
  }
83
89
  const dependsOn = [...new Set([...obj.dependsOn.map((r) => referenceName(r, names)).filter((n) => n !== undefined), ...extra])];
84
- return JSON.parse(JSON.stringify({ export: name, type: obj.entityType, sqlName: obj.sqlName, ...props, dependsOn, ddl }));
90
+ const collections = namedCollectionReferences(props);
91
+ return JSON.parse(JSON.stringify({ export: name, type: obj.entityType, sqlName: obj.sqlName, ...props, dependsOn, ...(collections.length > 0 ? { namedCollections: collections } : {}), ddl }));
85
92
  }
86
93
  /** A props value with every entity and column reference in it written as its export name (`users`, `users.id`). */
87
94
  function postgresJsonValue(v, names) {
@@ -153,10 +160,14 @@ export const sqlSerializer = {
153
160
  names.set(entity, name);
154
161
  const extra = sqlFileReferences("clickhouse", objects);
155
162
  const order = applyOrder(objects, names, extra);
163
+ const json = order.map((n) => objectJson(n, objects.get(n), names, extra.get(n)));
164
+ // The named collections the build references (#4395), each once, by name: a plan checks each exists.
165
+ const collections = [...new Set(json.flatMap((o) => o.namedCollections ?? []))].sort();
156
166
  const doc = {
157
167
  dialect: "clickhouse",
158
168
  applyOrder: order,
159
- objects: order.map((n) => objectJson(n, objects.get(n), names, extra.get(n))),
169
+ ...(collections.length > 0 ? { namedCollections: collections } : {}),
170
+ objects: json,
160
171
  };
161
172
  const ddl = order
162
173
  .map((n) => `${objects.get(n).props.ddl};`)
@@ -13,7 +13,20 @@
13
13
  * the file instead of writing it: exit 1, naming the file, when they differ.
14
14
  */
15
15
  import type { CommandGroupContext } from "@intentius/chant/cli/command-group";
16
+ export interface ProjectLocation {
17
+ config: Awaited<ReturnType<typeof import("@intentius/chant/config").loadChantConfigUpward>>["config"];
18
+ projectDir: string;
19
+ sourceDir: string;
20
+ }
16
21
  /** The file tsc would read instead of `path`: `sql-types.ts` beside `sql-types.d.ts`. */
17
22
  export declare function shadowingSource(path: string): string | undefined;
23
+ /** The project the working directory belongs to: its config, its root and its source directory. */
24
+ export declare function loadProject(cwd: string): Promise<ProjectLocation>;
25
+ /**
26
+ * The fold build's entities: what `chant build` declares, `.sql` files and
27
+ * composite members included. Prints the build's errors and returns
28
+ * undefined when it fails.
29
+ */
30
+ export declare function buildFolded(project: ProjectLocation, command: string, consequence: string): Promise<import("@intentius/chant").BuildResult | undefined>;
18
31
  export declare function runTypes(ctx: CommandGroupContext): Promise<number>;
19
32
  //# sourceMappingURL=sql-types-command.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"sql-types-command.d.ts","sourceRoot":"","sources":["../src/sql-types-command.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAIH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oCAAoC,CAAC;AAqB9E,yFAAyF;AACzF,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAIhE;AAED,wBAAsB,QAAQ,CAAC,GAAG,EAAE,mBAAmB,GAAG,OAAO,CAAC,MAAM,CAAC,CAqDxE"}
1
+ {"version":3,"file":"sql-types-command.d.ts","sourceRoot":"","sources":["../src/sql-types-command.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAIH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oCAAoC,CAAC;AAG9E,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,OAAO,CAAC,UAAU,CAAC,cAAc,yBAAyB,EAAE,qBAAqB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;IACtG,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;CACnB;AAoBD,yFAAyF;AACzF,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAIhE;AAED,mGAAmG;AACnG,wBAAsB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CAKvE;AAED;;;;GAIG;AACH,wBAAsB,WAAW,CAAC,OAAO,EAAE,eAAe,EAAE,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,+DAe/F;AAED,wBAAsB,QAAQ,CAAC,GAAG,EAAE,mBAAmB,GAAG,OAAO,CAAC,MAAM,CAAC,CAuCxE"}
@@ -43,37 +43,52 @@ export function shadowingSource(path) {
43
43
  const source = `${path.slice(0, -".d.ts".length)}.ts`;
44
44
  return existsSync(source) ? source : undefined;
45
45
  }
46
- export async function runTypes(ctx) {
47
- const args = parseArgs(ctx.rawArgs);
48
- if ("error" in args) {
49
- console.error(`${args.error}\n${USAGE}`);
50
- return 1;
51
- }
52
- const cwd = process.cwd();
46
+ /** The project the working directory belongs to: its config, its root and its source directory. */
47
+ export async function loadProject(cwd) {
53
48
  const { loadChantConfigUpward } = await import("@intentius/chant/config");
54
49
  const { config, configPath } = await loadChantConfigUpward(cwd);
55
50
  const projectDir = configPath ? dirname(configPath) : cwd;
56
- const sourceDir = resolve(projectDir, config.sourceDir ?? ".");
57
- const output = args.output !== undefined ? resolve(cwd, args.output) : join(sourceDir, SQL_TYPES_FILE);
58
- const shadow = shadowingSource(output);
59
- if (shadow) {
60
- console.error(`chant sql types: ${relative(cwd, shadow) || basename(shadow)} sits beside ${relative(cwd, output) || basename(output)}, and tsc reads it instead of the declarations; rename one`);
61
- return 1;
62
- }
51
+ return { config, projectDir, sourceDir: resolve(projectDir, config.sourceDir ?? ".") };
52
+ }
53
+ /**
54
+ * The fold build's entities: what `chant build` declares, `.sql` files and
55
+ * composite members included. Prints the build's errors and returns
56
+ * undefined when it fails.
57
+ */
58
+ export async function buildFolded(project, command, consequence) {
59
+ const { config, projectDir, sourceDir } = project;
63
60
  const { build } = await import("@intentius/chant/build");
64
61
  const { resolveBuildModes, resolveProjectBuildOptions } = await import("@intentius/chant/cli/build-options");
65
62
  const { loadPlugins, resolveProjectLexicons } = await import("@intentius/chant/cli/plugins");
66
63
  const { sqlSerializer } = await import("./serializer.js");
67
64
  const plugins = await loadPlugins(await resolveProjectLexicons(projectDir, { lexicon: "sql" }));
68
- // The fold build's entities: what `chant build` declares, `.sql` files and composite members included.
69
65
  const options = resolveProjectBuildOptions({ config, configDir: projectDir, plugins, modes: resolveBuildModes(config, { fold: true }) });
70
66
  const result = await build(sourceDir, [sqlSerializer], undefined, options);
71
67
  if (result.errors.length > 0) {
72
68
  for (const e of result.errors)
73
69
  console.error(e instanceof Error ? e.message : String(e));
74
- console.error("chant sql types: the build failed, so nothing was written");
70
+ console.error(`${command}: the build failed, so ${consequence}`);
71
+ return undefined;
72
+ }
73
+ return result;
74
+ }
75
+ export async function runTypes(ctx) {
76
+ const args = parseArgs(ctx.rawArgs);
77
+ if ("error" in args) {
78
+ console.error(`${args.error}\n${USAGE}`);
75
79
  return 1;
76
80
  }
81
+ const cwd = process.cwd();
82
+ const { config, projectDir, sourceDir } = await loadProject(cwd);
83
+ const output = args.output !== undefined ? resolve(cwd, args.output) : join(sourceDir, SQL_TYPES_FILE);
84
+ const shadow = shadowingSource(output);
85
+ if (shadow) {
86
+ console.error(`chant sql types: ${relative(cwd, shadow) || basename(shadow)} sits beside ${relative(cwd, output) || basename(output)}, and tsc reads it instead of the declarations; rename one`);
87
+ return 1;
88
+ }
89
+ const result = await buildFolded({ config, projectDir, sourceDir }, "chant sql types", "nothing was written");
90
+ if (!result)
91
+ return 1;
77
92
  const text = renderSqlTypes(result.entities, { projectDir, config: config });
78
93
  const shown = relative(cwd, output);
79
94
  const named = shown && !shown.startsWith("..") ? shown : output;
@@ -30,6 +30,8 @@
30
30
  */
31
31
  import type { Declarable } from "@intentius/chant/declarable";
32
32
  import type { SqlDialect } from "./dialects.js";
33
+ import { type PgProject } from "./lint/post-synth/postgres-names.js";
34
+ import type { OutputObject } from "./lint/post-synth/sql-helpers.js";
33
35
  /** The file `chant sql types` writes, in the project's source directory. */
34
36
  export declare const SQL_TYPES_FILE = "sql-types.d.ts";
35
37
  /**
@@ -47,6 +49,26 @@ export interface RenderSqlTypesOptions {
47
49
  /** The project's config: `sql.postgresMajor` for the catalog, `sql.dialect` when nothing is declared. */
48
50
  config?: Record<string, unknown>;
49
51
  }
52
+ /** The names a relation's `.columns` record holds at run time, in order. */
53
+ export declare const runtimeColumns: (entity: Declarable | undefined) => string[];
54
+ /** A view's column that passes one column through: that column's export and name. */
55
+ export declare function passthrough(o: OutputObject, name: string, quote: (c: string) => string): {
56
+ export: string;
57
+ column: string;
58
+ } | undefined;
59
+ /** A Postgres type's spelling, row type, and whether the type itself forbids NULL (a serial, a NOT NULL domain). */
60
+ export declare function pgType(p: PgProject, text: string | undefined, depth?: number): {
61
+ sqlType: string;
62
+ ts: string;
63
+ notNull: boolean;
64
+ };
65
+ /** The dialect a build's entities declare, else the config's, else ClickHouse. */
66
+ export declare function dialectOf(entities: ReadonlyMap<string, Declarable>, config: Record<string, unknown>): SqlDialect;
67
+ /** The build's sql output as `chant build` writes it: the objects, and the Postgres major they were built for. */
68
+ export declare function serializedObjects(entities: ReadonlyMap<string, Declarable>, config: Record<string, unknown>): {
69
+ objects: OutputObject[];
70
+ postgresMajor?: number;
71
+ };
50
72
  /**
51
73
  * The `sql-types.d.ts` for a build's entities: one module that augments the
52
74
  * dialect's `SqlSchema` with each table, view and dictionary, in key order.
@@ -1 +1 @@
1
- {"version":3,"file":"sql-types.d.ts","sourceRoot":"","sources":["../src/sql-types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAIH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAW9D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAQ7C,4EAA4E;AAC5E,eAAO,MAAM,cAAc,mBAAmB,CAAC;AAE/C;;;GAGG;AACH,wBAAgB,YAAY,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,GAAG,MAAM,CAGpG;AAED,kGAAkG;AAClG,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,WAAW,CAAC,MAAM,EAAE,UAAU,CAAC,EACzC,IAAI,EAAE,MAAM,EACZ,IAAI,GAAE,qBAA0B,GAC/B,SAAS,GAAG,OAAO,GAAG,SAAS,CASjC;AAED,6DAA6D;AAC7D,eAAO,MAAM,gBAAgB,EAAE,QAAQ,CAAC,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,CAGjE,CAAC;AAEF,MAAM,WAAW,qBAAqB;IACpC,yGAAyG;IACzG,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,yGAAyG;IACzG,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC;AA+OD;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,WAAW,CAAC,MAAM,EAAE,UAAU,CAAC,EAAE,IAAI,GAAE,qBAA0B,GAAG,MAAM,CAiClH"}
1
+ {"version":3,"file":"sql-types.d.ts","sourceRoot":"","sources":["../src/sql-types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAIH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAW9D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAK7C,OAAO,EAA6E,KAAK,SAAS,EAAE,MAAM,kCAAkC,CAAC;AAC7I,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAElE,4EAA4E;AAC5E,eAAO,MAAM,cAAc,mBAAmB,CAAC;AAE/C;;;GAGG;AACH,wBAAgB,YAAY,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,GAAG,MAAM,CAGpG;AAED,kGAAkG;AAClG,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,WAAW,CAAC,MAAM,EAAE,UAAU,CAAC,EACzC,IAAI,EAAE,MAAM,EACZ,IAAI,GAAE,qBAA0B,GAC/B,SAAS,GAAG,OAAO,GAAG,SAAS,CASjC;AAED,6DAA6D;AAC7D,eAAO,MAAM,gBAAgB,EAAE,QAAQ,CAAC,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,CAGjE,CAAC;AAEF,MAAM,WAAW,qBAAqB;IACpC,yGAAyG;IACzG,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,yGAAyG;IACzG,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC;AA2CD,4EAA4E;AAC5E,eAAO,MAAM,cAAc,GAAI,QAAQ,UAAU,GAAG,SAAS,KAAG,MAAM,EAA8E,CAAC;AAcrJ,qFAAqF;AACrF,wBAAgB,WAAW,CAAC,CAAC,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAQvI;AAoBD,oHAAoH;AACpH,wBAAgB,MAAM,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,GAAG,SAAS,EAAE,KAAK,SAAI,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAwB3H;AAsHD,kFAAkF;AAClF,wBAAgB,SAAS,CAAC,QAAQ,EAAE,WAAW,CAAC,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,UAAU,CAMhH;AAED,kHAAkH;AAClH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,WAAW,CAAC,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG;IAAE,OAAO,EAAE,YAAY,EAAE,CAAC;IAAC,aAAa,CAAC,EAAE,MAAM,CAAA;CAAE,CAGjK;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,WAAW,CAAC,MAAM,EAAE,UAAU,CAAC,EAAE,IAAI,GAAE,qBAA0B,GAAG,MAAM,CAgClH"}
package/dist/sql-types.js CHANGED
@@ -90,14 +90,14 @@ function originOf(entity, exportName, projectDir) {
90
90
  return `${file ? posix(file) : "?"}: ${exportName}${composite}`;
91
91
  }
92
92
  /** The names a relation's `.columns` record holds at run time, in order. */
93
- const runtimeColumns = (entity) => Object.keys(entity?.columns ?? {});
93
+ export const runtimeColumns = (entity) => Object.keys(entity?.columns ?? {});
94
94
  /** Whether `expr` is the column `column` alone, bare or qualified (`o.user_id`). */
95
95
  function isBareColumn(expr, quoted) {
96
96
  const unqualified = expr.trim().replace(/^(?:"(?:[^"]|"")+"|`(?:[^`]|``)+`|[A-Za-z_][\w$]*)\./, "");
97
97
  return unqualified === quoted;
98
98
  }
99
99
  /** A view's column that passes one column through: that column's export and name. */
100
- function passthrough(o, name, quote) {
100
+ export function passthrough(o, name, quote) {
101
101
  const edge = (o.lineage ?? []).find((e) => e.output === name);
102
102
  const ref = edge?.from.length === 1 ? edge.from[0] : undefined;
103
103
  if (!edge || !ref)
@@ -124,7 +124,7 @@ function spell(canonical, t) {
124
124
  }
125
125
  const arrayOf = (ts) => `${/[|&]/.test(ts) && !/^\{.*\}$/s.test(ts) ? `(${ts})` : ts}[]`;
126
126
  /** A Postgres type's spelling, row type, and whether the type itself forbids NULL (a serial, a NOT NULL domain). */
127
- function pgType(p, text, depth = 0) {
127
+ export function pgType(p, text, depth = 0) {
128
128
  const t = parseType(text);
129
129
  if (!t || depth > 5)
130
130
  return { sqlType: text?.trim() || "unknown", ts: "unknown", notNull: false };
@@ -268,7 +268,7 @@ function renderEntry(e, lines) {
268
268
  lines.push(" };");
269
269
  }
270
270
  /** The dialect a build's entities declare, else the config's, else ClickHouse. */
271
- function dialectOf(entities, config) {
271
+ export function dialectOf(entities, config) {
272
272
  try {
273
273
  return filesDialect(entities, config);
274
274
  }
@@ -276,6 +276,11 @@ function dialectOf(entities, config) {
276
276
  return "clickhouse";
277
277
  }
278
278
  }
279
+ /** The build's sql output as `chant build` writes it: the objects, and the Postgres major they were built for. */
280
+ export function serializedObjects(entities, config) {
281
+ const out = sqlSerializer.serialize(new Map(entities), undefined, { config });
282
+ return JSON.parse(typeof out === "string" ? out : out.primary);
283
+ }
279
284
  /**
280
285
  * The `sql-types.d.ts` for a build's entities: one module that augments the
281
286
  * dialect's `SqlSchema` with each table, view and dictionary, in key order.
@@ -288,8 +293,7 @@ export function renderSqlTypes(entities, opts = {}) {
288
293
  const sqlEntities = new Map([...entities].filter(([, e]) => isPostgresObject(e) || isClickHouseObject(e)));
289
294
  let entries = [];
290
295
  if (sqlEntities.size > 0) {
291
- const out = sqlSerializer.serialize(new Map(entities), undefined, { config });
292
- const doc = JSON.parse(typeof out === "string" ? out : out.primary);
296
+ const doc = serializedObjects(entities, config);
293
297
  entries = dialect === "postgres" ? postgresEntries(doc.objects, doc.postgresMajor ?? PINNED_MAJOR, entities, projectDir) : clickhouseEntries(doc.objects, entities, projectDir);
294
298
  }
295
299
  const byKey = new Map();
@@ -0,0 +1,37 @@
1
+ /**
2
+ * A T-SQL tokenizer for the statements `chant import` reads from SQL Server.
3
+ *
4
+ * T-SQL differs from the lexers the other dialects use in four places: an
5
+ * identifier can be `[bracketed]` (a `]` inside is written `]]`) or
6
+ * "double quoted", a string can carry an `N` prefix, a line holding only `GO`
7
+ * ends a batch (it is a client command, not a statement), and statements need
8
+ * no terminating `;`. Comments (`--` and nestable `/* *\/`) are dropped; each
9
+ * token keeps its 1-based line and column in the source.
10
+ */
11
+ export type TokenKind = "word" | "qident" | "string" | "number" | "variable" | "punct" | "go";
12
+ export interface Token {
13
+ kind: TokenKind;
14
+ /** As written: a `qident` keeps its brackets; a string its quotes. */
15
+ text: string;
16
+ /** A `qident`'s name, a string's value, a word's text. */
17
+ value: string;
18
+ line: number;
19
+ column: number;
20
+ /** Offset of the first character. */
21
+ start: number;
22
+ /** Offset after the last. */
23
+ end: number;
24
+ }
25
+ export declare class TsqlLexError extends Error {
26
+ readonly line: number;
27
+ readonly column: number;
28
+ constructor(message: string, line: number, column: number);
29
+ }
30
+ /** Tokenize a file. A `GO` on a line of its own (optionally with a count) becomes one `go` token. */
31
+ export declare function tokenize(text: string): Token[];
32
+ /** Tokens split into batches at `go` tokens; empty batches are dropped. */
33
+ export declare function batches(tokens: readonly Token[]): Token[][];
34
+ export declare const upper: (t: Token | undefined) => string;
35
+ /** The source text of a run of tokens, from the first token's start to the last token's end. */
36
+ export declare function sourceOf(text: string, tokens: readonly Token[]): string;
37
+ //# sourceMappingURL=lexer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lexer.d.ts","sourceRoot":"","sources":["../../src/sqlserver/lexer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,UAAU,GAAG,OAAO,GAAG,IAAI,CAAC;AAE9F,MAAM,WAAW,KAAK;IACpB,IAAI,EAAE,SAAS,CAAC;IAChB,sEAAsE;IACtE,IAAI,EAAE,MAAM,CAAC;IACb,0DAA0D;IAC1D,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,qCAAqC;IACrC,KAAK,EAAE,MAAM,CAAC;IACd,6BAA6B;IAC7B,GAAG,EAAE,MAAM,CAAC;CACb;AAED,qBAAa,YAAa,SAAQ,KAAK;IAGnC,QAAQ,CAAC,IAAI,EAAE,MAAM;IACrB,QAAQ,CAAC,MAAM,EAAE,MAAM;gBAFvB,OAAO,EAAE,MAAM,EACN,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM;CAK1B;AAKD,qGAAqG;AACrG,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,KAAK,EAAE,CA4K9C;AAyBD,2EAA2E;AAC3E,wBAAgB,OAAO,CAAC,MAAM,EAAE,SAAS,KAAK,EAAE,GAAG,KAAK,EAAE,EAAE,CAW3D;AAED,eAAO,MAAM,KAAK,GAAI,GAAG,KAAK,GAAG,SAAS,KAAG,MAA+D,CAAC;AAE7G,gGAAgG;AAChG,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,KAAK,EAAE,GAAG,MAAM,CAGvE"}