@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
@@ -2,7 +2,8 @@
2
2
  * The Postgres entities: `schema`, `table`, `index`, `view`, `sequence`,
3
3
  * `type` (enum, composite and range), `domain`, `extension`, `func`,
4
4
  * `procedure`, `aggregate`, `trigger`, `eventTrigger`, `collation`, `cast`,
5
- * `policy`, `role` and `grant` tagged templates that parse their DDL at fold
5
+ * `operatorClass`, `operatorFamily`, `foreignTable`, `textSearchConfiguration`,
6
+ * `textSearchDictionary`, `policy`, `role` and `grant` tagged templates that parse their DDL at fold
6
7
  * time into one Declarable each (chant #3278, #3279, #3680, #3681, #3911).
7
8
  *
8
9
  * ```ts
@@ -57,7 +58,7 @@
57
58
  import type { AttrRef } from "@intentius/chant/attrref";
58
59
  import { setInterpolationFields } from "@intentius/chant/provenance";
59
60
  import { isTrivia, POSTGRES_LEXICAL, SqlSyntaxError, untokenize, type Token } from "./tokens";
60
- import { identValue, parseStatements, type ColumnNode, type CommentNode, type ConstraintNode, type DefElem, type GrantNode, type NameNode, type RowSecurityNode, type Span, type StatementNode } from "./parser";
61
+ import { identValue, parseStatements, type ColumnNode, type CommentNode, type ConstraintNode, type DefElem, type GenericOption, type GrantNode, type NameNode, type RowSecurityNode, type Span, type StatementNode, type TextSearchMappingNode } from "./parser";
61
62
  import { keywordCategory, quoteIdent } from "./keywords";
62
63
  import { feed, lineage, spanText as text, splice as spliceWith, templateSyntaxError, unparsedClauses, type TemplateCtx, type TemplateDialect, type UnparsedClause } from "../core/interpolation";
63
64
  import { SqlObject, isColumnRefOf, isSqlObjectOf, makeSqlEntity } from "../core/entity";
@@ -74,6 +75,7 @@ export type { AnyColumn, Column, ColumnTraits, KeyColumn, Named, NotNullColumn,
74
75
 
75
76
  export { POSTGRES_ENTITY_TYPES, type PostgresEntityType } from "./entity-types";
76
77
  import { POSTGRES_ENTITY_TYPES, type PostgresEntityType } from "./entity-types";
78
+ import { isSecretOption } from "./secret-options";
77
79
 
78
80
  // ── Values ─────────────────────────────────────────────────────────────
79
81
 
@@ -92,6 +94,8 @@ export interface ColumnDef {
92
94
  collate?: string;
93
95
  compression?: string;
94
96
  storage?: string;
97
+ /** A foreign table column's `OPTIONS (...)`: each option by its name to its string value. */
98
+ options?: Record<string, string>;
95
99
  comment?: string;
96
100
  }
97
101
 
@@ -341,6 +345,141 @@ export interface EventTriggerProps extends Omit<CommonProps, "schema"> {
341
345
  functionName: string;
342
346
  }
343
347
 
348
+ export interface OperatorProps extends CommonProps {
349
+ /** `LEFTARG`, as written; absent for a prefix operator. */
350
+ leftArg?: string;
351
+ /** `RIGHTARG`, as written; absent for a postfix operator (removed in 14, so for none the server still holds). */
352
+ rightArg?: string;
353
+ /**
354
+ * The rest of the definition by option name, folded (`function`,
355
+ * `commutator`, `restrict`), to its value as written; `hashes` and `merges`
356
+ * to `true`. `procedure`, the old spelling, is `function`.
357
+ */
358
+ options: Record<string, string>;
359
+ }
360
+
361
+ /** One member of an operator class, as written. */
362
+ export type OperatorClassItemDef =
363
+ | {
364
+ kind: "operator";
365
+ number: string;
366
+ /** The operator, `schema.symbol` or a bare symbol. */
367
+ operator: string;
368
+ /** `(left, right)` as written, parentheses excluded; absent when both are the class's type. */
369
+ types?: string;
370
+ /** `FOR ORDER BY`'s btree operator family; absent for `FOR SEARCH`, the default. */
371
+ orderBy?: string;
372
+ }
373
+ | { kind: "function"; number: string; types?: string; function: string; args: string }
374
+ | { kind: "storage"; type: string };
375
+
376
+ /** `CREATE OPERATOR CLASS`: the operators and support functions an index access method uses for a data type. */
377
+ export interface OperatorClassProps extends CommonProps {
378
+ default?: boolean;
379
+ /** `FOR TYPE`, as written. Not `type`: a serialized object has that key for its entity type. */
380
+ dataType: string;
381
+ /** `USING`: the index access method, folded. */
382
+ method: string;
383
+ /** `FAMILY`, as written; absent when the class is in a family of its own name. */
384
+ family?: string;
385
+ items: OperatorClassItemDef[];
386
+ }
387
+
388
+ /** `CREATE OPERATOR FAMILY`: a set of operator classes that work together; members arrive with the classes. */
389
+ export interface OperatorFamilyProps extends CommonProps {
390
+ /** `USING`: the index access method, folded. */
391
+ method: string;
392
+ }
393
+
394
+ /** `CREATE FOREIGN TABLE`: a table whose rows are on a foreign server. */
395
+ export interface ForeignTableProps extends CommonProps {
396
+ ifNotExists?: boolean;
397
+ columns: ColumnDef[];
398
+ checks: CheckDef[];
399
+ /** `SERVER`: the foreign server's SQL name. */
400
+ serverName: string;
401
+ /** `OPTIONS (...)`: each option by its name to its string value. */
402
+ options: Record<string, string>;
403
+ }
404
+
405
+ /** `CREATE TEXT SEARCH DICTIONARY`: a template with its options. */
406
+ export interface TextSearchDictionaryProps extends CommonProps {
407
+ /** `TEMPLATE`, as written. */
408
+ template: string;
409
+ /** The template's options by name, folded, to their value as written. */
410
+ options: Record<string, string>;
411
+ }
412
+
413
+ /** One `ADD MAPPING FOR tokens WITH dictionaries` of a text search configuration. */
414
+ export interface TextSearchMappingDef {
415
+ /** The token types, folded. */
416
+ tokens: string[];
417
+ /** The dictionaries in the order they are consulted, as written. */
418
+ dictionaries: string[];
419
+ }
420
+
421
+ /** `CREATE TEXT SEARCH CONFIGURATION`: a parser and what each token type it finds is mapped to. */
422
+ export interface TextSearchConfigurationProps extends CommonProps {
423
+ /** `PARSER`, as written. */
424
+ parser: string;
425
+ mappings: TextSearchMappingDef[];
426
+ }
427
+
428
+ /** `CREATE STATISTICS`: extended statistics on columns or expressions of one table. */
429
+ export interface StatisticsProps extends CommonProps {
430
+ ifNotExists?: boolean;
431
+ /** `ndistinct`, `dependencies`, `mcv`, folded; absent when the server computes all three. */
432
+ kinds?: string[];
433
+ /** Each column or expression, as written. */
434
+ targets: string[];
435
+ /** The table: the entity when interpolated, else its name. */
436
+ table: PostgresObject | string;
437
+ /** The table's SQL name. */
438
+ tableName: string;
439
+ }
440
+
441
+ export interface ForeignDataWrapperProps extends Omit<CommonProps, "schema"> {
442
+ /** The handler function: the entity when interpolated, else its name. */
443
+ handler?: PostgresObject | string;
444
+ handlerName?: string;
445
+ /** `NO HANDLER`, written out. */
446
+ noHandler?: boolean;
447
+ validator?: PostgresObject | string;
448
+ validatorName?: string;
449
+ noValidator?: boolean;
450
+ /** `OPTIONS (...)`: each option by its name to its string value. */
451
+ options: Record<string, string>;
452
+ }
453
+
454
+ export interface ForeignServerProps extends Omit<CommonProps, "schema"> {
455
+ ifNotExists?: boolean;
456
+ serverType?: string;
457
+ version?: string;
458
+ /** The wrapper: the entity when interpolated, else its name. */
459
+ wrapper: PostgresObject | string;
460
+ wrapperName: string;
461
+ options: Record<string, string>;
462
+ }
463
+
464
+ /** A table of a publication, with the column list and row filter it is published with. */
465
+ export interface PublicationTableDef {
466
+ /** The table: the entity when interpolated, else its name. */
467
+ table: PostgresObject | string;
468
+ tableName: string;
469
+ columns?: string[];
470
+ /** The row filter, as written with its parentheses. */
471
+ where?: string;
472
+ }
473
+
474
+ export interface PublicationProps extends Omit<CommonProps, "schema"> {
475
+ allTables?: boolean;
476
+ tables: PublicationTableDef[];
477
+ /** `TABLES IN SCHEMA`: the schema's SQL name, an interpolated schema by its name. */
478
+ schemas: string[];
479
+ /** `WITH (...)`: each option by its name to its value as written. */
480
+ options: Record<string, string>;
481
+ }
482
+
344
483
  export interface DomainProps extends CommonProps {
345
484
  /** The underlying data type. */
346
485
  dataType: string;
@@ -607,6 +746,56 @@ export interface PostgresEventTrigger extends PostgresObject {
607
746
  readonly props: EventTriggerProps;
608
747
  }
609
748
 
749
+ export interface PostgresOperator extends PostgresObject {
750
+ readonly entityType: "Postgres::Operator";
751
+ readonly props: OperatorProps;
752
+ }
753
+
754
+ export interface PostgresOperatorClass extends PostgresObject {
755
+ readonly entityType: "Postgres::OperatorClass";
756
+ readonly props: OperatorClassProps;
757
+ }
758
+
759
+ export interface PostgresOperatorFamily extends PostgresObject {
760
+ readonly entityType: "Postgres::OperatorFamily";
761
+ readonly props: OperatorFamilyProps;
762
+ }
763
+
764
+ export interface PostgresForeignTable extends PostgresObject {
765
+ readonly entityType: "Postgres::ForeignTable";
766
+ readonly props: ForeignTableProps;
767
+ }
768
+
769
+ export interface PostgresTextSearchDictionary extends PostgresObject {
770
+ readonly entityType: "Postgres::TextSearchDictionary";
771
+ readonly props: TextSearchDictionaryProps;
772
+ }
773
+
774
+ export interface PostgresTextSearchConfiguration extends PostgresObject {
775
+ readonly entityType: "Postgres::TextSearchConfiguration";
776
+ readonly props: TextSearchConfigurationProps;
777
+ }
778
+
779
+ export interface PostgresStatistics extends PostgresObject {
780
+ readonly entityType: "Postgres::Statistics";
781
+ readonly props: StatisticsProps;
782
+ }
783
+
784
+ export interface PostgresForeignDataWrapper extends PostgresObject {
785
+ readonly entityType: "Postgres::ForeignDataWrapper";
786
+ readonly props: ForeignDataWrapperProps;
787
+ }
788
+
789
+ export interface PostgresForeignServer extends PostgresObject {
790
+ readonly entityType: "Postgres::ForeignServer";
791
+ readonly props: ForeignServerProps;
792
+ }
793
+
794
+ export interface PostgresPublication extends PostgresObject {
795
+ readonly entityType: "Postgres::Publication";
796
+ readonly props: PublicationProps;
797
+ }
798
+
610
799
  export interface PostgresExtension extends PostgresObject {
611
800
  readonly entityType: "Postgres::Extension";
612
801
  readonly props: ExtensionProps;
@@ -765,6 +954,16 @@ export type PostgresTag =
765
954
  | "aggregate"
766
955
  | "trigger"
767
956
  | "eventTrigger"
957
+ | "operator"
958
+ | "operatorClass"
959
+ | "operatorFamily"
960
+ | "foreignTable"
961
+ | "textSearchConfiguration"
962
+ | "textSearchDictionary"
963
+ | "statistics"
964
+ | "foreignDataWrapper"
965
+ | "foreignServer"
966
+ | "publication"
768
967
  | "collation"
769
968
  | "cast"
770
969
  | "policy"
@@ -786,6 +985,16 @@ export const STATEMENTS_OF: Record<PostgresTag, readonly StatementNode["statemen
786
985
  aggregate: ["aggregate"],
787
986
  trigger: ["trigger"],
788
987
  eventTrigger: ["eventTrigger"],
988
+ operator: ["operator"],
989
+ operatorClass: ["operatorClass"],
990
+ operatorFamily: ["operatorFamily"],
991
+ foreignTable: ["foreignTable"],
992
+ textSearchConfiguration: ["textSearchConfiguration"],
993
+ textSearchDictionary: ["textSearchDictionary"],
994
+ statistics: ["statistics"],
995
+ foreignDataWrapper: ["foreignDataWrapper"],
996
+ foreignServer: ["foreignServer"],
997
+ publication: ["publication"],
789
998
  collation: ["collation"],
790
999
  cast: ["cast"],
791
1000
  policy: ["policy"],
@@ -809,6 +1018,17 @@ const TAG_OF: Record<StatementNode["statement"], PostgresTag | undefined> = {
809
1018
  aggregate: "aggregate",
810
1019
  trigger: "trigger",
811
1020
  eventTrigger: "eventTrigger",
1021
+ operator: "operator",
1022
+ operatorClass: "operatorClass",
1023
+ operatorFamily: "operatorFamily",
1024
+ foreignTable: "foreignTable",
1025
+ textSearchConfiguration: "textSearchConfiguration",
1026
+ textSearchDictionary: "textSearchDictionary",
1027
+ textSearchMapping: undefined,
1028
+ statistics: "statistics",
1029
+ foreignDataWrapper: "foreignDataWrapper",
1030
+ foreignServer: "foreignServer",
1031
+ publication: "publication",
812
1032
  collation: "collation",
813
1033
  cast: "cast",
814
1034
  policy: "policy",
@@ -835,6 +1055,17 @@ export const STATEMENT_NAMES: Record<StatementNode["statement"], string> = {
835
1055
  aggregate: "CREATE AGGREGATE",
836
1056
  trigger: "CREATE TRIGGER",
837
1057
  eventTrigger: "CREATE EVENT TRIGGER",
1058
+ operator: "CREATE OPERATOR",
1059
+ operatorClass: "CREATE OPERATOR CLASS",
1060
+ operatorFamily: "CREATE OPERATOR FAMILY",
1061
+ foreignTable: "CREATE FOREIGN TABLE",
1062
+ textSearchConfiguration: "CREATE TEXT SEARCH CONFIGURATION",
1063
+ textSearchDictionary: "CREATE TEXT SEARCH DICTIONARY",
1064
+ textSearchMapping: "ALTER TEXT SEARCH CONFIGURATION",
1065
+ statistics: "CREATE STATISTICS",
1066
+ foreignDataWrapper: "CREATE FOREIGN DATA WRAPPER",
1067
+ foreignServer: "CREATE SERVER",
1068
+ publication: "CREATE PUBLICATION",
838
1069
  collation: "CREATE COLLATION",
839
1070
  cast: "CREATE CAST",
840
1071
  policy: "CREATE POLICY",
@@ -871,6 +1102,24 @@ function definitionValues(ctx: Ctx, elems: readonly DefElem[], path: string): Re
871
1102
  return out;
872
1103
  }
873
1104
 
1105
+ /** A database-wide object's name (a wrapper, a server, a publication): one piece, or an interpolated object's name. */
1106
+ function databaseObjectName(ctx: Ctx, n: NameNode): string {
1107
+ feed(ctx, n.span, "name");
1108
+ return n.pieces[0] || identValue(req(text(ctx, n.span)));
1109
+ }
1110
+
1111
+ /** An `OPTIONS (...)` list's values by option name, each a string constant's value. */
1112
+ function genericOptionValues(tag: PostgresTag, ctx: Ctx, options: readonly GenericOption[]): Record<string, string> {
1113
+ const out: Record<string, string> = {};
1114
+ for (const o of options) {
1115
+ if (isSecretOption(o.name)) {
1116
+ throw new SqlTemplateError(tag, `the option ${o.name} holds a credential, which the environment supplies (a user mapping, or its secret store); a declaration never carries one`, 0, 0);
1117
+ }
1118
+ out[o.name] = req(stringValue(text(ctx, o.value, "options")));
1119
+ }
1120
+ return out;
1121
+ }
1122
+
874
1123
  /** A qualified name's schema and name. An interpolated schema names the schema; an interpolated object gives both. */
875
1124
  function qualified(ctx: Ctx, n: NameNode): { schema?: string; name: string } {
876
1125
  const pieces: string[] = [];
@@ -929,7 +1178,7 @@ function columnName(ctx: Ctx, c: { name: string; span: Span }): string {
929
1178
  return isColumnRef(v) ? v.attribute : req(text(ctx, c.span));
930
1179
  }
931
1180
 
932
- function columnDef(ctx: Ctx, c: ColumnNode): ColumnDef {
1181
+ function columnDef(ctx: Ctx, c: ColumnNode, tag: PostgresTag = "table"): ColumnDef {
933
1182
  for (const span of [c.nameSpan, c.type, c.default, c.collate, c.compression, c.storage, c.generated?.expr, c.generated?.options]) feed(ctx, span, "columns");
934
1183
  const def: ColumnDef = { name: columnName(ctx, { name: c.name, span: c.nameSpan }) };
935
1184
  const set = <K extends keyof ColumnDef>(k: K, v: ColumnDef[K] | undefined) => {
@@ -952,6 +1201,7 @@ function columnDef(ctx: Ctx, c: ColumnNode): ColumnDef {
952
1201
  set("collate", text(ctx, c.collate));
953
1202
  set("compression", text(ctx, c.compression));
954
1203
  set("storage", text(ctx, c.storage));
1204
+ if (c.options && c.options.length > 0) def.options = genericOptionValues(tag, ctx, c.options);
955
1205
  return def;
956
1206
  }
957
1207
 
@@ -1050,6 +1300,7 @@ function applyComments(
1050
1300
  self: { schema?: string; name: string },
1051
1301
  objectTypes: readonly string[],
1052
1302
  parts: { columns?: Map<string, Commentable>; constraints?: Map<string, Commentable>; columnComments?: Record<string, string> } = {},
1303
+ using?: string,
1053
1304
  ): string | undefined {
1054
1305
  let comment: string | undefined;
1055
1306
  const isSelf = (q: { schema?: string; name: string }) => q.name === self.name && (q.schema === undefined || self.schema === undefined || q.schema === self.schema);
@@ -1091,6 +1342,8 @@ function applyComments(
1091
1342
  // `COMMENT ON TRIGGER name ON table`: the name is the trigger's, the table its own.
1092
1343
  if (qualified(ctx, c.target).name !== self.name || !c.on || !isSelf({ ...qualified(ctx, c.on), name: self.name })) refuse(c, `names another ${c.objectType.toLowerCase()} than ${self.name}`);
1093
1344
  } else if (!isSelf(qualified(ctx, c.target))) refuse(c, `names another object than ${sqlNameOf(self)}`);
1345
+ // An operator class or family is named by its index method too.
1346
+ if (using !== undefined && c.using !== using) refuse(c, `names another index method than ${using}`);
1094
1347
  comment = value;
1095
1348
  }
1096
1349
  }
@@ -1114,7 +1367,7 @@ function lastDot(ctx: Ctx, span: Span): number {
1114
1367
  */
1115
1368
  export function followOnStray(tag: PostgresTag, rest: readonly StatementNode[]): StatementNode | undefined {
1116
1369
  if (tag === "grant") return rest[0];
1117
- return rest.find((n) => n.statement !== "comment" && !(tag === "table" && n.statement === "rowSecurity"));
1370
+ return rest.find((n) => n.statement !== "comment" && !(tag === "table" && n.statement === "rowSecurity") && !(tag === "textSearchConfiguration" && n.statement === "textSearchMapping"));
1118
1371
  }
1119
1372
 
1120
1373
  /**
@@ -1331,7 +1584,7 @@ function build(tag: PostgresTag, strings: TemplateStringsArray | readonly string
1331
1584
  if (stray) {
1332
1585
  throw new SqlTemplateError(
1333
1586
  tag,
1334
- `holds a second statement (${STATEMENT_NAMES[stray.statement]}); a template declares one object, followed only by COMMENT ON statements for it${tag === "table" ? " and ALTER TABLE ... ROW LEVEL SECURITY" : ""}`,
1587
+ `holds a second statement (${STATEMENT_NAMES[stray.statement]}); a template declares one object, followed only by COMMENT ON statements for it${tag === "table" ? " and ALTER TABLE ... ROW LEVEL SECURITY" : tag === "textSearchConfiguration" ? " and ALTER TEXT SEARCH CONFIGURATION ... ADD MAPPING" : ""}`,
1335
1588
  0,
1336
1589
  0,
1337
1590
  );
@@ -1493,6 +1746,203 @@ function build(tag: PostgresTag, strings: TemplateStringsArray | readonly string
1493
1746
  );
1494
1747
  return make(POSTGRES_ENTITY_TYPES.eventTrigger, { name }, props);
1495
1748
  }
1749
+ case "operator": {
1750
+ const q = qualified(ctx, node.name);
1751
+ const comment = applyComments(tag, ctx, comments, q, ["OPERATOR"]);
1752
+ const opt = definitionValues(ctx, node.options, "options");
1753
+ const { leftarg, rightarg, procedure, ...rest } = opt;
1754
+ const props: OperatorProps = stripUnset({ ...q, leftArg: leftarg, rightArg: rightarg, options: { ...rest, function: opt.function ?? procedure }, comment, ddl, source });
1755
+ // The symbol is unquoted wherever the operator is named: `app.===`.
1756
+ return make(POSTGRES_ENTITY_TYPES.operator, q, props, undefined, q.schema ? `${quoteIdent(q.schema)}.${q.name}` : q.name);
1757
+ }
1758
+ case "operatorClass": {
1759
+ const q = qualified(ctx, node.name);
1760
+ if (node.method === "") throw new SqlTemplateError(tag, "the index method is written out, not interpolated", 0, 0);
1761
+ const comment = applyComments(tag, ctx, comments, q, ["OPERATOR CLASS"], {}, node.method);
1762
+ const items = node.items.map((i): OperatorClassItemDef => {
1763
+ if (i.kind === "storage") return { kind: "storage", type: req(text(ctx, i.type, "items")) };
1764
+ if (i.kind === "function") {
1765
+ feed(ctx, i.function.span, "items");
1766
+ return stripUnset({ kind: "function", number: req(text(ctx, i.number, "items")), types: text(ctx, i.types, "items"), function: targetName(ctx, i.function), args: text(ctx, i.args, "items") ?? "" }) as OperatorClassItemDef;
1767
+ }
1768
+ return stripUnset({
1769
+ kind: "operator",
1770
+ number: req(text(ctx, i.number, "items")),
1771
+ operator: req(text(ctx, i.operator.span, "items")),
1772
+ types: text(ctx, i.types, "items"),
1773
+ orderBy: i.orderBy ? targetName(ctx, i.orderBy) : undefined,
1774
+ }) as OperatorClassItemDef;
1775
+ });
1776
+ const props: OperatorClassProps = stripUnset({
1777
+ ...q,
1778
+ default: node.default || undefined,
1779
+ dataType: req(text(ctx, node.type, "dataType")),
1780
+ method: node.method,
1781
+ family: node.family ? targetName(ctx, node.family) : undefined,
1782
+ items,
1783
+ comment,
1784
+ ddl,
1785
+ source,
1786
+ });
1787
+ return make(POSTGRES_ENTITY_TYPES.operatorClass, q, props);
1788
+ }
1789
+ case "operatorFamily": {
1790
+ const q = qualified(ctx, node.name);
1791
+ if (node.method === "") throw new SqlTemplateError(tag, "the index method is written out, not interpolated", 0, 0);
1792
+ const comment = applyComments(tag, ctx, comments, q, ["OPERATOR FAMILY"], {}, node.method);
1793
+ const props: OperatorFamilyProps = stripUnset({ ...q, method: node.method, comment, ddl, source });
1794
+ return make(POSTGRES_ENTITY_TYPES.operatorFamily, q, props);
1795
+ }
1796
+ case "foreignTable": {
1797
+ const q = qualified(ctx, node.name);
1798
+ const columns = node.columns.map((c) => columnDef(ctx, c, tag));
1799
+ const checks: CheckDef[] = [];
1800
+ const file = (c: ConstraintNode, cols: string[]) => {
1801
+ if (c.kind === "CHECK") checks.push(checkDef(ctx, c));
1802
+ else if (c.kind === "NOT NULL") {
1803
+ const col = columns.find((x) => x.name === cols[0]);
1804
+ if (!col) throw new SqlTemplateError(tag, `NOT NULL ${cols[0]} names no column of ${sqlNameOf(q)}`, 0, 0);
1805
+ col.notNull = true;
1806
+ if (c.name) col.notNullName = c.name;
1807
+ }
1808
+ };
1809
+ node.columns.forEach((c, i) => c.constraints.forEach((k) => file(k, [columns[i]!.name])));
1810
+ node.constraints.forEach((k) => file(k, k.columns.map((x) => columnName(ctx, x))));
1811
+ const named = new Map<string, Commentable>();
1812
+ for (const c of checks) if (c.name) named.set(c.name, c);
1813
+ const comment = applyComments(tag, ctx, comments, q, ["FOREIGN TABLE"], { columns: new Map(columns.map((c) => [c.name, c])), constraints: named });
1814
+ const props: ForeignTableProps = strip(
1815
+ {
1816
+ ...q,
1817
+ ifNotExists: node.ifNotExists || undefined,
1818
+ columns,
1819
+ checks,
1820
+ serverName: databaseObjectName(ctx, node.server),
1821
+ options: genericOptionValues(tag, ctx, node.options),
1822
+ comment,
1823
+ ddl,
1824
+ source,
1825
+ },
1826
+ ["columns", "checks", "options"],
1827
+ );
1828
+ return make(POSTGRES_ENTITY_TYPES.foreignTable, q, props, columns.map((c) => c.name));
1829
+ }
1830
+ case "textSearchDictionary": {
1831
+ const q = qualified(ctx, node.name);
1832
+ const comment = applyComments(tag, ctx, comments, q, ["TEXT SEARCH DICTIONARY"]);
1833
+ const { template, ...options } = definitionValues(ctx, node.options, "options");
1834
+ const props: TextSearchDictionaryProps = strip({ ...q, template: req(template), options, comment, ddl, source }, ["options"]);
1835
+ return make(POSTGRES_ENTITY_TYPES.textSearchDictionary, q, props);
1836
+ }
1837
+ case "textSearchConfiguration": {
1838
+ const q = qualified(ctx, node.name);
1839
+ const comment = applyComments(tag, ctx, comments, q, ["TEXT SEARCH CONFIGURATION"]);
1840
+ const opt = definitionValues(ctx, node.options, "options");
1841
+ const seen = new Set<string>();
1842
+ const mappings = rest
1843
+ .filter((n): n is TextSearchMappingNode => n.statement === "textSearchMapping")
1844
+ .map((m): TextSearchMappingDef => {
1845
+ feed(ctx, m.name.span, "mappings");
1846
+ const t = qualified(ctx, m.name);
1847
+ if (t.name !== q.name || (t.schema !== undefined && q.schema !== undefined && t.schema !== q.schema)) {
1848
+ throw new SqlTemplateError(tag, `ADD MAPPING names another configuration (${sqlNameOf(t)}) than ${sqlNameOf(q)}`, 0, 0);
1849
+ }
1850
+ const tokens = m.tokens.map((x) => x.name || identValue(req(text(ctx, x.span, "mappings"))));
1851
+ for (const tok of tokens) {
1852
+ if (seen.has(tok)) throw new SqlTemplateError(tag, `the token type ${tok} is mapped twice in ${sqlNameOf(q)}`, 0, 0);
1853
+ seen.add(tok);
1854
+ }
1855
+ for (const d of m.dictionaries) feed(ctx, d.span, "mappings");
1856
+ return { tokens, dictionaries: m.dictionaries.map((d) => sqlNameOf(qualified(ctx, d))) };
1857
+ });
1858
+ const props: TextSearchConfigurationProps = strip({ ...q, parser: req(opt.parser), mappings, comment, ddl, source }, ["mappings"]);
1859
+ return make(POSTGRES_ENTITY_TYPES.textSearchConfiguration, q, props);
1860
+ }
1861
+ case "textSearchMapping":
1862
+ // Only a configuration's follow-on statement (`followOnStray`); first in a template it is refused above.
1863
+ throw new SqlTemplateError(tag, "holds an ALTER TEXT SEARCH CONFIGURATION before any CREATE", 0, 0);
1864
+ case "statistics": {
1865
+ const q = qualified(ctx, node.name);
1866
+ const comment = applyComments(tag, ctx, comments, q, ["STATISTICS"]);
1867
+ const props: StatisticsProps = strip(
1868
+ {
1869
+ ...q,
1870
+ ifNotExists: node.ifNotExists || undefined,
1871
+ kinds: node.kinds.length > 0 ? node.kinds : undefined,
1872
+ targets: node.targets.map((t) => req(text(ctx, t, "targets"))),
1873
+ table: target(ctx, node.table),
1874
+ tableName: sqlNameOf(qualified(ctx, node.table)),
1875
+ comment,
1876
+ ddl,
1877
+ source,
1878
+ },
1879
+ ["targets"],
1880
+ );
1881
+ return make(POSTGRES_ENTITY_TYPES.statistics, q, props);
1882
+ }
1883
+ case "foreignDataWrapper": {
1884
+ const name = databaseObjectName(ctx, node.name);
1885
+ const comment = applyComments(tag, ctx, comments, { name }, ["FOREIGN DATA WRAPPER"]);
1886
+ const props: ForeignDataWrapperProps = strip(
1887
+ {
1888
+ name,
1889
+ handler: node.handler ? target(ctx, node.handler) : undefined,
1890
+ handlerName: node.handler ? targetName(ctx, node.handler) : undefined,
1891
+ noHandler: node.handler === null ? true : undefined,
1892
+ validator: node.validator ? target(ctx, node.validator) : undefined,
1893
+ validatorName: node.validator ? targetName(ctx, node.validator) : undefined,
1894
+ noValidator: node.validator === null ? true : undefined,
1895
+ options: genericOptionValues(tag, ctx, node.options),
1896
+ comment,
1897
+ ddl,
1898
+ source,
1899
+ },
1900
+ ["options"],
1901
+ );
1902
+ return make(POSTGRES_ENTITY_TYPES.foreignDataWrapper, { name }, props);
1903
+ }
1904
+ case "foreignServer": {
1905
+ const name = databaseObjectName(ctx, node.name);
1906
+ const comment = applyComments(tag, ctx, comments, { name }, ["SERVER"]);
1907
+ const props: ForeignServerProps = strip(
1908
+ {
1909
+ name,
1910
+ ifNotExists: node.ifNotExists || undefined,
1911
+ serverType: node.type ? stringValue(text(ctx, node.type, "serverType")) : undefined,
1912
+ version: node.version ? stringValue(text(ctx, node.version, "version")) : undefined,
1913
+ wrapper: target(ctx, node.wrapper),
1914
+ wrapperName: targetName(ctx, node.wrapper),
1915
+ options: genericOptionValues(tag, ctx, node.options),
1916
+ comment,
1917
+ ddl,
1918
+ source,
1919
+ },
1920
+ ["options"],
1921
+ );
1922
+ return make(POSTGRES_ENTITY_TYPES.foreignServer, { name }, props);
1923
+ }
1924
+ case "publication": {
1925
+ const name = databaseObjectName(ctx, node.name);
1926
+ const comment = applyComments(tag, ctx, comments, { name }, ["PUBLICATION"]);
1927
+ const tables = node.items.flatMap((i) =>
1928
+ i.kind !== "table"
1929
+ ? []
1930
+ : [
1931
+ stripUnset({
1932
+ table: target(ctx, i.table),
1933
+ tableName: sqlNameOf(qualified(ctx, i.table)),
1934
+ columns: i.columns?.map((c) => columnName(ctx, { name: c.name, span: c.span })),
1935
+ where: text(ctx, i.where, "tables"),
1936
+ }) as PublicationTableDef,
1937
+ ],
1938
+ );
1939
+ const schemas = node.items.flatMap((i) => (i.kind === "schema" ? [qualified(ctx, i.schema).name] : []));
1940
+ const props: PublicationProps = strip(
1941
+ { name, allTables: node.allTables || undefined, tables, schemas, options: definitionValues(ctx, node.options, "options"), comment, ddl, source },
1942
+ ["tables", "schemas", "options"],
1943
+ );
1944
+ return make(POSTGRES_ENTITY_TYPES.publication, { name }, props);
1945
+ }
1496
1946
  case "domain": {
1497
1947
  const q = qualified(ctx, node.name);
1498
1948
  const checks = node.checks.map((c) => stripUnset({ name: c.name, expr: req(text(ctx, c.expr, "checks")), notValid: c.notValid }) as CheckDef);
@@ -1961,6 +2411,92 @@ export function eventTrigger(strings: TemplateStringsArray, ...values: unknown[]
1961
2411
  return build("eventTrigger", strings, values) as PostgresEventTrigger;
1962
2412
  }
1963
2413
 
2414
+ /**
2415
+ * `` operator`CREATE OPERATOR app.=== (FUNCTION = ${fn}, LEFTARG = int, RIGHTARG = int)` ``:
2416
+ * one operator, identified by its name and operand types, as a function is by
2417
+ * its name and parameter types.
2418
+ */
2419
+ export function operator(strings: TemplateStringsArray, ...values: unknown[]): PostgresOperator {
2420
+ return build("operator", strings, values) as PostgresOperator;
2421
+ }
2422
+
2423
+ /**
2424
+ * `` operatorClass`CREATE OPERATOR CLASS app.ops DEFAULT FOR TYPE int USING btree AS OPERATOR 1 <, FUNCTION 1 ${cmp}(int, int)` ``:
2425
+ * one operator class, identified by its name and index method. Creating one takes a superuser.
2426
+ */
2427
+ export function operatorClass(strings: TemplateStringsArray, ...values: unknown[]): PostgresOperatorClass {
2428
+ return build("operatorClass", strings, values) as PostgresOperatorClass;
2429
+ }
2430
+
2431
+ /**
2432
+ * `` operatorFamily`CREATE OPERATOR FAMILY app.ops USING btree` ``: one operator
2433
+ * family, identified by its name and index method. Its members come with the
2434
+ * operator classes that name it. Creating one takes a superuser.
2435
+ */
2436
+ export function operatorFamily(strings: TemplateStringsArray, ...values: unknown[]): PostgresOperatorFamily {
2437
+ return build("operatorFamily", strings, values) as PostgresOperatorFamily;
2438
+ }
2439
+
2440
+ /**
2441
+ * `` foreignTable`CREATE FOREIGN TABLE app.remote_orders (id int, total numeric) SERVER ${remote} OPTIONS (table_name 'orders')` ``:
2442
+ * one foreign table. It has its own tag, not `table`, because it is another
2443
+ * kind of relation: another CREATE and ALTER, no key, index, partitioning or
2444
+ * storage clauses, and a server it cannot move off.
2445
+ */
2446
+ export function foreignTable(strings: TemplateStringsArray, ...values: unknown[]): PostgresForeignTable {
2447
+ return build("foreignTable", strings, values) as PostgresForeignTable;
2448
+ }
2449
+
2450
+ /**
2451
+ * `` textSearchDictionary`CREATE TEXT SEARCH DICTIONARY app.english_stop (TEMPLATE = snowball, Language = english, StopWords = english)` ``:
2452
+ * one text search dictionary: a template and its options.
2453
+ */
2454
+ export function textSearchDictionary(strings: TemplateStringsArray, ...values: unknown[]): PostgresTextSearchDictionary {
2455
+ return build("textSearchDictionary", strings, values) as PostgresTextSearchDictionary;
2456
+ }
2457
+
2458
+ /**
2459
+ * `` textSearchConfiguration`CREATE TEXT SEARCH CONFIGURATION app.english2 (PARSER = default); ALTER TEXT SEARCH CONFIGURATION app.english2 ADD MAPPING FOR asciiword WITH ${dict}` ``:
2460
+ * one text search configuration: a parser, and the dictionaries each token
2461
+ * type it finds is looked up in.
2462
+ */
2463
+ export function textSearchConfiguration(strings: TemplateStringsArray, ...values: unknown[]): PostgresTextSearchConfiguration {
2464
+ return build("textSearchConfiguration", strings, values) as PostgresTextSearchConfiguration;
2465
+ }
2466
+
2467
+ /**
2468
+ * `` statistics`CREATE STATISTICS name (ndistinct, dependencies) ON a, b FROM ${table}` ``:
2469
+ * extended statistics on columns or expressions of one table.
2470
+ */
2471
+ export function statistics(strings: TemplateStringsArray, ...values: unknown[]): PostgresStatistics {
2472
+ return build("statistics", strings, values) as PostgresStatistics;
2473
+ }
2474
+
2475
+ /**
2476
+ * `` foreignDataWrapper`CREATE FOREIGN DATA WRAPPER name HANDLER ${fn} OPTIONS (...)` ``:
2477
+ * one foreign data wrapper, the database's (no schema). Creating one takes a superuser.
2478
+ */
2479
+ export function foreignDataWrapper(strings: TemplateStringsArray, ...values: unknown[]): PostgresForeignDataWrapper {
2480
+ return build("foreignDataWrapper", strings, values) as PostgresForeignDataWrapper;
2481
+ }
2482
+
2483
+ /**
2484
+ * `` foreignServer`CREATE SERVER name FOREIGN DATA WRAPPER ${fdw} OPTIONS (host 'db.internal')` ``:
2485
+ * one foreign server, the database's. Its user mappings carry credentials and are
2486
+ * not declared; an option that holds a secret is the environment's to supply.
2487
+ */
2488
+ export function foreignServer(strings: TemplateStringsArray, ...values: unknown[]): PostgresForeignServer {
2489
+ return build("foreignServer", strings, values) as PostgresForeignServer;
2490
+ }
2491
+
2492
+ /**
2493
+ * `` publication`CREATE PUBLICATION name FOR TABLE ${t} WITH (publish = 'insert')` ``:
2494
+ * one logical-replication publication, the database's.
2495
+ */
2496
+ export function publication(strings: TemplateStringsArray, ...values: unknown[]): PostgresPublication {
2497
+ return build("publication", strings, values) as PostgresPublication;
2498
+ }
2499
+
1964
2500
  /** `` trigger`CREATE [OR REPLACE] [CONSTRAINT] TRIGGER name ... ON ${table} ... EXECUTE FUNCTION ${fn}()` ``: one trigger on its table. */
1965
2501
  export function trigger(strings: TemplateStringsArray, ...values: unknown[]): PostgresTrigger {
1966
2502
  return build("trigger", strings, values) as PostgresTrigger;