@intentius/chant-lexicon-sql 0.124.45 → 0.124.48

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 (360) 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/stream.d.ts +40 -0
  37. package/dist/clickhouse/plan/stream.d.ts.map +1 -0
  38. package/dist/clickhouse/plan/stream.js +107 -0
  39. package/dist/clickhouse/rebuild/observe.d.ts +3 -1
  40. package/dist/clickhouse/rebuild/observe.d.ts.map +1 -1
  41. package/dist/clickhouse/rebuild/observe.js +14 -1
  42. package/dist/clickhouse/review-catalog.d.ts +213 -0
  43. package/dist/clickhouse/review-catalog.d.ts.map +1 -0
  44. package/dist/clickhouse/review-catalog.js +330 -0
  45. package/dist/codegen/classifier-page.d.ts.map +1 -1
  46. package/dist/codegen/classifier-page.js +21 -4
  47. package/dist/codegen/clickhouse-module.d.ts.map +1 -1
  48. package/dist/codegen/clickhouse-module.js +3 -0
  49. package/dist/codegen/coverage-page.d.ts.map +1 -1
  50. package/dist/codegen/coverage-page.js +5 -3
  51. package/dist/codegen/docs.js +1 -1
  52. package/dist/codegen/postgres-classifier-page.js +1 -1
  53. package/dist/codegen/registry.d.ts.map +1 -1
  54. package/dist/codegen/registry.js +5 -0
  55. package/dist/composites/catalog.d.ts.map +1 -1
  56. package/dist/composites/catalog.js +100 -0
  57. package/dist/composites/clickhouse.d.ts +2 -0
  58. package/dist/composites/clickhouse.d.ts.map +1 -1
  59. package/dist/composites/clickhouse.js +2 -0
  60. package/dist/composites/otel-tables.d.ts +100 -0
  61. package/dist/composites/otel-tables.d.ts.map +1 -0
  62. package/dist/composites/otel-tables.js +282 -0
  63. package/dist/composites/stream-ingest.d.ts +63 -0
  64. package/dist/composites/stream-ingest.d.ts.map +1 -0
  65. package/dist/composites/stream-ingest.js +39 -0
  66. package/dist/coverage/clickhouse.json +1 -1
  67. package/dist/coverage/postgres.json +7 -7
  68. package/dist/coverage.d.ts +16 -6
  69. package/dist/coverage.d.ts.map +1 -1
  70. package/dist/coverage.js +10 -5
  71. package/dist/drizzle-command.d.ts +17 -0
  72. package/dist/drizzle-command.d.ts.map +1 -0
  73. package/dist/drizzle-command.js +91 -0
  74. package/dist/drizzle.d.ts +70 -0
  75. package/dist/drizzle.d.ts.map +1 -0
  76. package/dist/drizzle.js +684 -0
  77. package/dist/files/clickhouse.d.ts.map +1 -1
  78. package/dist/files/clickhouse.js +8 -1
  79. package/dist/files/common.d.ts +13 -0
  80. package/dist/files/common.d.ts.map +1 -1
  81. package/dist/files/common.js +5 -0
  82. package/dist/files/postgres.js +12 -2
  83. package/dist/generated/clickhouse.d.ts +2 -0
  84. package/dist/generated/clickhouse.d.ts.map +1 -1
  85. package/dist/generated/clickhouse.js +2 -0
  86. package/dist/import-parser.d.ts +21 -1
  87. package/dist/import-parser.d.ts.map +1 -1
  88. package/dist/import-parser.js +79 -5
  89. package/dist/index.d.ts +1 -1
  90. package/dist/index.d.ts.map +1 -1
  91. package/dist/index.js +1 -1
  92. package/dist/integrity.json +6 -5
  93. package/dist/lint/post-synth/audit-entries.d.ts.map +1 -1
  94. package/dist/lint/post-synth/audit-entries.js +1 -0
  95. package/dist/lint/post-synth/index.d.ts.map +1 -1
  96. package/dist/lint/post-synth/index.js +2 -0
  97. package/dist/lint/post-synth/sqlch128.d.ts +18 -0
  98. package/dist/lint/post-synth/sqlch128.d.ts.map +1 -0
  99. package/dist/lint/post-synth/sqlch128.js +222 -0
  100. package/dist/lint/rules/postgres-templates.js +2 -2
  101. package/dist/lsp/postgres-template.d.ts.map +1 -1
  102. package/dist/lsp/postgres-template.js +11 -0
  103. package/dist/manifest.json +1 -1
  104. package/dist/mcp/postgres.js +1 -1
  105. package/dist/meta.json +25 -0
  106. package/dist/migrate/from-postgres/detect.d.ts +4 -0
  107. package/dist/migrate/from-postgres/detect.d.ts.map +1 -0
  108. package/dist/migrate/from-postgres/detect.js +7 -0
  109. package/dist/migrate/from-postgres/emit.d.ts +26 -0
  110. package/dist/migrate/from-postgres/emit.d.ts.map +1 -0
  111. package/dist/migrate/from-postgres/emit.js +86 -0
  112. package/dist/migrate/from-postgres/index.d.ts +51 -0
  113. package/dist/migrate/from-postgres/index.d.ts.map +1 -0
  114. package/dist/migrate/from-postgres/index.js +115 -0
  115. package/dist/migrate/from-postgres/translate.d.ts +73 -0
  116. package/dist/migrate/from-postgres/translate.d.ts.map +1 -0
  117. package/dist/migrate/from-postgres/translate.js +261 -0
  118. package/dist/migrate/from-postgres/types.d.ts +51 -0
  119. package/dist/migrate/from-postgres/types.d.ts.map +1 -0
  120. package/dist/migrate/from-postgres/types.js +211 -0
  121. package/dist/migration-replay.d.ts +73 -0
  122. package/dist/migration-replay.d.ts.map +1 -0
  123. package/dist/migration-replay.js +294 -0
  124. package/dist/okf/index.md +6 -0
  125. package/dist/okf/rules/SQLCH128.md +11 -0
  126. package/dist/okf/types/PostgresForeignDataWrapper.md +9 -0
  127. package/dist/okf/types/PostgresForeignServer.md +9 -0
  128. package/dist/okf/types/PostgresOperator.md +9 -0
  129. package/dist/okf/types/PostgresPublication.md +9 -0
  130. package/dist/okf/types/PostgresStatistics.md +9 -0
  131. package/dist/op/activities/postgres-migration.d.ts.map +1 -1
  132. package/dist/op/activities/postgres-migration.js +4 -0
  133. package/dist/op/activity-contracts.d.ts +20 -0
  134. package/dist/op/activity-contracts.d.ts.map +1 -1
  135. package/dist/op/activity-contracts.js +2 -0
  136. package/dist/plugin.d.ts.map +1 -1
  137. package/dist/plugin.js +36 -2
  138. package/dist/postgres/apply/apply.js +8 -1
  139. package/dist/postgres/apply/statements.d.ts.map +1 -1
  140. package/dist/postgres/apply/statements.js +87 -2
  141. package/dist/postgres/constraint-names.d.ts +30 -0
  142. package/dist/postgres/constraint-names.d.ts.map +1 -0
  143. package/dist/postgres/constraint-names.js +72 -0
  144. package/dist/postgres/entities.d.ts +110 -1
  145. package/dist/postgres/entities.d.ts.map +1 -1
  146. package/dist/postgres/entities.js +146 -0
  147. package/dist/postgres/entity-types.d.ts +5 -0
  148. package/dist/postgres/entity-types.d.ts.map +1 -1
  149. package/dist/postgres/entity-types.js +5 -0
  150. package/dist/postgres/import/generator.d.ts.map +1 -1
  151. package/dist/postgres/import/generator.js +50 -2
  152. package/dist/postgres/import/live-export.d.ts.map +1 -1
  153. package/dist/postgres/import/live-export.js +2 -0
  154. package/dist/postgres/live/catalog-kinds.d.ts +14 -0
  155. package/dist/postgres/live/catalog-kinds.d.ts.map +1 -1
  156. package/dist/postgres/live/catalog-kinds.js +206 -0
  157. package/dist/postgres/live/catalog.d.ts +2 -0
  158. package/dist/postgres/live/catalog.d.ts.map +1 -1
  159. package/dist/postgres/live/catalog.js +3 -1
  160. package/dist/postgres/live/describe-resources.d.ts.map +1 -1
  161. package/dist/postgres/live/describe-resources.js +10 -2
  162. package/dist/postgres/migrate/backfill.d.ts +2 -0
  163. package/dist/postgres/migrate/backfill.d.ts.map +1 -1
  164. package/dist/postgres/migrate/backfill.js +7 -1
  165. package/dist/postgres/migrate/carry.d.ts +45 -1
  166. package/dist/postgres/migrate/carry.d.ts.map +1 -1
  167. package/dist/postgres/migrate/carry.js +72 -8
  168. package/dist/postgres/migrate/observe.d.ts +28 -4
  169. package/dist/postgres/migrate/observe.d.ts.map +1 -1
  170. package/dist/postgres/migrate/observe.js +41 -12
  171. package/dist/postgres/migrate/op.d.ts +26 -1
  172. package/dist/postgres/migrate/op.d.ts.map +1 -1
  173. package/dist/postgres/migrate/op.js +3 -1
  174. package/dist/postgres/migrate/steps.d.ts +35 -2
  175. package/dist/postgres/migrate/steps.d.ts.map +1 -1
  176. package/dist/postgres/migrate/steps.js +158 -12
  177. package/dist/postgres/parser.d.ts +72 -1
  178. package/dist/postgres/parser.d.ts.map +1 -1
  179. package/dist/postgres/parser.js +194 -2
  180. package/dist/postgres/plan/deep.d.ts.map +1 -1
  181. package/dist/postgres/plan/deep.js +29 -1
  182. package/dist/postgres/plan/diff.d.ts.map +1 -1
  183. package/dist/postgres/plan/diff.js +39 -1
  184. package/dist/postgres/plan/normalize.d.ts +17 -2
  185. package/dist/postgres/plan/normalize.d.ts.map +1 -1
  186. package/dist/postgres/plan/normalize.js +109 -1
  187. package/dist/postgres/plan/rules.d.ts +1 -0
  188. package/dist/postgres/plan/rules.d.ts.map +1 -1
  189. package/dist/postgres/plan/rules.js +3 -2
  190. package/dist/postgres/plan/schema.js +1 -1
  191. package/dist/postgres/secret-options.d.ts +10 -0
  192. package/dist/postgres/secret-options.d.ts.map +1 -0
  193. package/dist/postgres/secret-options.js +9 -0
  194. package/dist/postgres/testing/roundtrip-schema.d.ts +3 -2
  195. package/dist/postgres/testing/roundtrip-schema.d.ts.map +1 -1
  196. package/dist/postgres/testing/roundtrip-schema.js +13 -1
  197. package/dist/postgres.d.ts +1 -1
  198. package/dist/postgres.d.ts.map +1 -1
  199. package/dist/postgres.js +1 -1
  200. package/dist/rules/audit-entries.ts +1 -0
  201. package/dist/rules/postgres-templates.ts +2 -2
  202. package/dist/rules/sqlch128.ts +230 -0
  203. package/dist/serializer.d.ts +5 -0
  204. package/dist/serializer.d.ts.map +1 -1
  205. package/dist/serializer.js +13 -2
  206. package/dist/sql-types-command.d.ts +13 -0
  207. package/dist/sql-types-command.d.ts.map +1 -1
  208. package/dist/sql-types-command.js +31 -16
  209. package/dist/sql-types.d.ts +22 -0
  210. package/dist/sql-types.d.ts.map +1 -1
  211. package/dist/sql-types.js +10 -6
  212. package/dist/sqlserver/lexer.d.ts +37 -0
  213. package/dist/sqlserver/lexer.d.ts.map +1 -0
  214. package/dist/sqlserver/lexer.js +254 -0
  215. package/dist/sqlserver/parse.d.ts +185 -0
  216. package/dist/sqlserver/parse.d.ts.map +1 -0
  217. package/dist/sqlserver/parse.js +767 -0
  218. package/dist/sqlserver/translate.d.ts +34 -0
  219. package/dist/sqlserver/translate.d.ts.map +1 -0
  220. package/dist/sqlserver/translate.js +495 -0
  221. package/dist/sqlserver/types.d.ts +44 -0
  222. package/dist/sqlserver/types.d.ts.map +1 -0
  223. package/dist/sqlserver/types.js +133 -0
  224. package/dist/sqlserver/validate.d.ts +31 -0
  225. package/dist/sqlserver/validate.d.ts.map +1 -0
  226. package/dist/sqlserver/validate.js +67 -0
  227. package/dist/validate.d.ts.map +1 -1
  228. package/dist/validate.js +5 -0
  229. package/package.json +2 -2
  230. package/src/change-set.ts +2 -1
  231. package/src/clickhouse/apply/statements.ts +25 -0
  232. package/src/clickhouse/import/live-export.ts +20 -5
  233. package/src/clickhouse/live/named-collections.e2e.test.ts +88 -0
  234. package/src/clickhouse/live/named-collections.ts +61 -0
  235. package/src/clickhouse/live/undeclarable.e2e.test.ts +5 -3
  236. package/src/clickhouse/live/undeclarable.ts +20 -4
  237. package/src/clickhouse/named-collections.test.ts +187 -0
  238. package/src/clickhouse/named-collections.ts +224 -0
  239. package/src/clickhouse/parser.ts +2 -1
  240. package/src/clickhouse/plan/commands.ts +17 -2
  241. package/src/clickhouse/plan/diff.ts +57 -1
  242. package/src/clickhouse/plan/disruption.ts +5 -0
  243. package/src/clickhouse/plan/rebuild-handoff.ts +3 -0
  244. package/src/clickhouse/plan/report.ts +6 -1
  245. package/src/clickhouse/plan/rules.ts +14 -4
  246. package/src/clickhouse/plan/stream-s3queue.e2e.test.ts +148 -0
  247. package/src/clickhouse/plan/stream.test.ts +237 -0
  248. package/src/clickhouse/plan/stream.ts +111 -0
  249. package/src/clickhouse/rebuild/observe.ts +15 -1
  250. package/src/clickhouse/review-catalog.test.ts +181 -0
  251. package/src/clickhouse/review-catalog.ts +489 -0
  252. package/src/codegen/classifier-page.ts +21 -4
  253. package/src/codegen/clickhouse-module.ts +3 -0
  254. package/src/codegen/coverage-page.ts +5 -3
  255. package/src/codegen/docs.ts +1 -1
  256. package/src/codegen/postgres-classifier-page.ts +1 -1
  257. package/src/codegen/registry.ts +5 -0
  258. package/src/composites/catalog.test.ts +6 -1
  259. package/src/composites/catalog.ts +100 -0
  260. package/src/composites/clickhouse.ts +2 -0
  261. package/src/composites/composites.test.ts +1 -1
  262. package/src/composites/otel-tables.test.ts +118 -0
  263. package/src/composites/otel-tables.ts +339 -0
  264. package/src/composites/stream-ingest.test.ts +114 -0
  265. package/src/composites/stream-ingest.ts +82 -0
  266. package/src/core/undeclarable.test.ts +6 -5
  267. package/src/coverage/clickhouse.json +1 -1
  268. package/src/coverage/postgres.json +7 -7
  269. package/src/coverage.test.ts +27 -2
  270. package/src/coverage.ts +18 -7
  271. package/src/drizzle-command.ts +94 -0
  272. package/src/drizzle-kit.e2e.test.ts +89 -0
  273. package/src/drizzle-types.e2e.test.ts +67 -0
  274. package/src/drizzle.test.ts +358 -0
  275. package/src/drizzle.ts +737 -0
  276. package/src/files/clickhouse.ts +8 -1
  277. package/src/files/common.ts +14 -1
  278. package/src/files/postgres.ts +12 -2
  279. package/src/generated/clickhouse.ts +3 -0
  280. package/src/generated/lexicon-sql.json +25 -0
  281. package/src/import-parser.sqlserver.test.ts +92 -0
  282. package/src/import-parser.ts +79 -5
  283. package/src/index.ts +1 -1
  284. package/src/lint/post-synth/audit-entries.ts +1 -0
  285. package/src/lint/post-synth/index.ts +2 -0
  286. package/src/lint/post-synth/sqlch128.test.ts +107 -0
  287. package/src/lint/post-synth/sqlch128.ts +230 -0
  288. package/src/lint/rules/postgres-templates.ts +2 -2
  289. package/src/lsp/postgres-template.ts +11 -0
  290. package/src/mcp/postgres.ts +1 -1
  291. package/src/migrate/from-postgres/cli.test.ts +165 -0
  292. package/src/migrate/from-postgres/detect.ts +7 -0
  293. package/src/migrate/from-postgres/emit.ts +96 -0
  294. package/src/migrate/from-postgres/example.test.ts +205 -0
  295. package/src/migrate/from-postgres/index.ts +122 -0
  296. package/src/migrate/from-postgres/translate.test.ts +242 -0
  297. package/src/migrate/from-postgres/translate.ts +359 -0
  298. package/src/migrate/from-postgres/types.test.ts +116 -0
  299. package/src/migrate/from-postgres/types.ts +236 -0
  300. package/src/migrate/from-postgres/validate.e2e.test.ts +44 -0
  301. package/src/migrate/from-postgres/workspace.e2e.test.ts +114 -0
  302. package/src/migration-replay.e2e.test.ts +155 -0
  303. package/src/migration-replay.test.ts +173 -0
  304. package/src/migration-replay.ts +289 -0
  305. package/src/op/__snapshots__/watch-pipeline.test.ts.snap +2 -2
  306. package/src/op/activities/postgres-migration.ts +4 -0
  307. package/src/op/activity-contracts.ts +2 -0
  308. package/src/plugin.ts +37 -2
  309. package/src/postgres/apply/apply.ts +9 -1
  310. package/src/postgres/apply/statements.ts +74 -1
  311. package/src/postgres/constraint-names.ts +71 -0
  312. package/src/postgres/database-kinds.test.ts +384 -0
  313. package/src/postgres/entities.ts +266 -1
  314. package/src/postgres/entity-types.ts +5 -0
  315. package/src/postgres/import/generator.ts +42 -2
  316. package/src/postgres/import/live-export.ts +1 -0
  317. package/src/postgres/live/catalog-kinds.ts +223 -0
  318. package/src/postgres/live/catalog.ts +6 -1
  319. package/src/postgres/live/database-kinds.e2e.test.ts +164 -0
  320. package/src/postgres/live/describe-resources.ts +11 -2
  321. package/src/postgres/live/undeclarable.e2e.test.ts +13 -6
  322. package/src/postgres/migrate/backfill.ts +13 -1
  323. package/src/postgres/migrate/carry.ts +103 -8
  324. package/src/postgres/migrate/followups.e2e.test.ts +218 -0
  325. package/src/postgres/migrate/followups.test.ts +199 -0
  326. package/src/postgres/migrate/kinds.e2e.test.ts +5 -5
  327. package/src/postgres/migrate/observe.ts +53 -14
  328. package/src/postgres/migrate/op.ts +28 -1
  329. package/src/postgres/migrate/partition.e2e.test.ts +129 -0
  330. package/src/postgres/migrate/partition.test.ts +206 -0
  331. package/src/postgres/migrate/steps.ts +157 -12
  332. package/src/postgres/parser.ts +234 -2
  333. package/src/postgres/plan/deep.ts +28 -1
  334. package/src/postgres/plan/diff.ts +36 -1
  335. package/src/postgres/plan/normalize.ts +122 -1
  336. package/src/postgres/plan/rules.ts +10 -3
  337. package/src/postgres/plan/schema.ts +1 -1
  338. package/src/postgres/secret-options.ts +10 -0
  339. package/src/postgres/testing/roundtrip-schema.ts +13 -1
  340. package/src/postgres.ts +16 -0
  341. package/src/serializer.ts +13 -2
  342. package/src/skills/chant-sql-postgres-migration.md +3 -3
  343. package/src/skills/chant-sql-postgres.md +6 -1
  344. package/src/skills/chant-sql.md +2 -1
  345. package/src/sql-types-command.ts +38 -16
  346. package/src/sql-types.ts +11 -6
  347. package/src/sqlserver/fixture.test.ts +186 -0
  348. package/src/sqlserver/import-cli.test.ts +61 -0
  349. package/src/sqlserver/lexer.ts +260 -0
  350. package/src/sqlserver/parse.ts +865 -0
  351. package/src/sqlserver/translate.test.ts +396 -0
  352. package/src/sqlserver/translate.ts +558 -0
  353. package/src/sqlserver/types.test.ts +102 -0
  354. package/src/sqlserver/types.ts +154 -0
  355. package/src/sqlserver/validate.e2e.test.ts +32 -0
  356. package/src/sqlserver/validate.test.ts +49 -0
  357. package/src/sqlserver/validate.ts +76 -0
  358. package/src/validate.ts +5 -0
  359. package/src/workspace-kinds.test.ts +11 -0
  360. package/workspace-kinds.json +100 -2
@@ -57,7 +57,7 @@
57
57
  import type { AttrRef } from "@intentius/chant/attrref";
58
58
  import { setInterpolationFields } from "@intentius/chant/provenance";
59
59
  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";
60
+ import { identValue, parseStatements, type ColumnNode, type CommentNode, type ConstraintNode, type DefElem, type GenericOption, type GrantNode, type NameNode, type RowSecurityNode, type Span, type StatementNode } from "./parser";
61
61
  import { keywordCategory, quoteIdent } from "./keywords";
62
62
  import { feed, lineage, spanText as text, splice as spliceWith, templateSyntaxError, unparsedClauses, type TemplateCtx, type TemplateDialect, type UnparsedClause } from "../core/interpolation";
63
63
  import { SqlObject, isColumnRefOf, isSqlObjectOf, makeSqlEntity } from "../core/entity";
@@ -74,6 +74,7 @@ export type { AnyColumn, Column, ColumnTraits, KeyColumn, Named, NotNullColumn,
74
74
 
75
75
  export { POSTGRES_ENTITY_TYPES, type PostgresEntityType } from "./entity-types";
76
76
  import { POSTGRES_ENTITY_TYPES, type PostgresEntityType } from "./entity-types";
77
+ import { isSecretOption } from "./secret-options";
77
78
 
78
79
  // ── Values ─────────────────────────────────────────────────────────────
79
80
 
@@ -341,6 +342,74 @@ export interface EventTriggerProps extends Omit<CommonProps, "schema"> {
341
342
  functionName: string;
342
343
  }
343
344
 
345
+ export interface OperatorProps extends CommonProps {
346
+ /** `LEFTARG`, as written; absent for a prefix operator. */
347
+ leftArg?: string;
348
+ /** `RIGHTARG`, as written; absent for a postfix operator (removed in 14, so for none the server still holds). */
349
+ rightArg?: string;
350
+ /**
351
+ * The rest of the definition by option name, folded (`function`,
352
+ * `commutator`, `restrict`), to its value as written; `hashes` and `merges`
353
+ * to `true`. `procedure`, the old spelling, is `function`.
354
+ */
355
+ options: Record<string, string>;
356
+ }
357
+
358
+ /** `CREATE STATISTICS`: extended statistics on columns or expressions of one table. */
359
+ export interface StatisticsProps extends CommonProps {
360
+ ifNotExists?: boolean;
361
+ /** `ndistinct`, `dependencies`, `mcv`, folded; absent when the server computes all three. */
362
+ kinds?: string[];
363
+ /** Each column or expression, as written. */
364
+ targets: string[];
365
+ /** The table: the entity when interpolated, else its name. */
366
+ table: PostgresObject | string;
367
+ /** The table's SQL name. */
368
+ tableName: string;
369
+ }
370
+
371
+ export interface ForeignDataWrapperProps extends Omit<CommonProps, "schema"> {
372
+ /** The handler function: the entity when interpolated, else its name. */
373
+ handler?: PostgresObject | string;
374
+ handlerName?: string;
375
+ /** `NO HANDLER`, written out. */
376
+ noHandler?: boolean;
377
+ validator?: PostgresObject | string;
378
+ validatorName?: string;
379
+ noValidator?: boolean;
380
+ /** `OPTIONS (...)`: each option by its name to its string value. */
381
+ options: Record<string, string>;
382
+ }
383
+
384
+ export interface ForeignServerProps extends Omit<CommonProps, "schema"> {
385
+ ifNotExists?: boolean;
386
+ serverType?: string;
387
+ version?: string;
388
+ /** The wrapper: the entity when interpolated, else its name. */
389
+ wrapper: PostgresObject | string;
390
+ wrapperName: string;
391
+ options: Record<string, string>;
392
+ }
393
+
394
+ /** A table of a publication, with the column list and row filter it is published with. */
395
+ export interface PublicationTableDef {
396
+ /** The table: the entity when interpolated, else its name. */
397
+ table: PostgresObject | string;
398
+ tableName: string;
399
+ columns?: string[];
400
+ /** The row filter, as written with its parentheses. */
401
+ where?: string;
402
+ }
403
+
404
+ export interface PublicationProps extends Omit<CommonProps, "schema"> {
405
+ allTables?: boolean;
406
+ tables: PublicationTableDef[];
407
+ /** `TABLES IN SCHEMA`: the schema's SQL name, an interpolated schema by its name. */
408
+ schemas: string[];
409
+ /** `WITH (...)`: each option by its name to its value as written. */
410
+ options: Record<string, string>;
411
+ }
412
+
344
413
  export interface DomainProps extends CommonProps {
345
414
  /** The underlying data type. */
346
415
  dataType: string;
@@ -607,6 +676,31 @@ export interface PostgresEventTrigger extends PostgresObject {
607
676
  readonly props: EventTriggerProps;
608
677
  }
609
678
 
679
+ export interface PostgresOperator extends PostgresObject {
680
+ readonly entityType: "Postgres::Operator";
681
+ readonly props: OperatorProps;
682
+ }
683
+
684
+ export interface PostgresStatistics extends PostgresObject {
685
+ readonly entityType: "Postgres::Statistics";
686
+ readonly props: StatisticsProps;
687
+ }
688
+
689
+ export interface PostgresForeignDataWrapper extends PostgresObject {
690
+ readonly entityType: "Postgres::ForeignDataWrapper";
691
+ readonly props: ForeignDataWrapperProps;
692
+ }
693
+
694
+ export interface PostgresForeignServer extends PostgresObject {
695
+ readonly entityType: "Postgres::ForeignServer";
696
+ readonly props: ForeignServerProps;
697
+ }
698
+
699
+ export interface PostgresPublication extends PostgresObject {
700
+ readonly entityType: "Postgres::Publication";
701
+ readonly props: PublicationProps;
702
+ }
703
+
610
704
  export interface PostgresExtension extends PostgresObject {
611
705
  readonly entityType: "Postgres::Extension";
612
706
  readonly props: ExtensionProps;
@@ -765,6 +859,11 @@ export type PostgresTag =
765
859
  | "aggregate"
766
860
  | "trigger"
767
861
  | "eventTrigger"
862
+ | "operator"
863
+ | "statistics"
864
+ | "foreignDataWrapper"
865
+ | "foreignServer"
866
+ | "publication"
768
867
  | "collation"
769
868
  | "cast"
770
869
  | "policy"
@@ -786,6 +885,11 @@ export const STATEMENTS_OF: Record<PostgresTag, readonly StatementNode["statemen
786
885
  aggregate: ["aggregate"],
787
886
  trigger: ["trigger"],
788
887
  eventTrigger: ["eventTrigger"],
888
+ operator: ["operator"],
889
+ statistics: ["statistics"],
890
+ foreignDataWrapper: ["foreignDataWrapper"],
891
+ foreignServer: ["foreignServer"],
892
+ publication: ["publication"],
789
893
  collation: ["collation"],
790
894
  cast: ["cast"],
791
895
  policy: ["policy"],
@@ -809,6 +913,11 @@ const TAG_OF: Record<StatementNode["statement"], PostgresTag | undefined> = {
809
913
  aggregate: "aggregate",
810
914
  trigger: "trigger",
811
915
  eventTrigger: "eventTrigger",
916
+ operator: "operator",
917
+ statistics: "statistics",
918
+ foreignDataWrapper: "foreignDataWrapper",
919
+ foreignServer: "foreignServer",
920
+ publication: "publication",
812
921
  collation: "collation",
813
922
  cast: "cast",
814
923
  policy: "policy",
@@ -835,6 +944,11 @@ export const STATEMENT_NAMES: Record<StatementNode["statement"], string> = {
835
944
  aggregate: "CREATE AGGREGATE",
836
945
  trigger: "CREATE TRIGGER",
837
946
  eventTrigger: "CREATE EVENT TRIGGER",
947
+ operator: "CREATE OPERATOR",
948
+ statistics: "CREATE STATISTICS",
949
+ foreignDataWrapper: "CREATE FOREIGN DATA WRAPPER",
950
+ foreignServer: "CREATE SERVER",
951
+ publication: "CREATE PUBLICATION",
838
952
  collation: "CREATE COLLATION",
839
953
  cast: "CREATE CAST",
840
954
  policy: "CREATE POLICY",
@@ -871,6 +985,24 @@ function definitionValues(ctx: Ctx, elems: readonly DefElem[], path: string): Re
871
985
  return out;
872
986
  }
873
987
 
988
+ /** A database-wide object's name (a wrapper, a server, a publication): one piece, or an interpolated object's name. */
989
+ function databaseObjectName(ctx: Ctx, n: NameNode): string {
990
+ feed(ctx, n.span, "name");
991
+ return n.pieces[0] || identValue(req(text(ctx, n.span)));
992
+ }
993
+
994
+ /** An `OPTIONS (...)` list's values by option name, each a string constant's value. */
995
+ function genericOptionValues(tag: PostgresTag, ctx: Ctx, options: readonly GenericOption[]): Record<string, string> {
996
+ const out: Record<string, string> = {};
997
+ for (const o of options) {
998
+ if (isSecretOption(o.name)) {
999
+ 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);
1000
+ }
1001
+ out[o.name] = req(stringValue(text(ctx, o.value, "options")));
1002
+ }
1003
+ return out;
1004
+ }
1005
+
874
1006
  /** A qualified name's schema and name. An interpolated schema names the schema; an interpolated object gives both. */
875
1007
  function qualified(ctx: Ctx, n: NameNode): { schema?: string; name: string } {
876
1008
  const pieces: string[] = [];
@@ -1493,6 +1625,97 @@ function build(tag: PostgresTag, strings: TemplateStringsArray | readonly string
1493
1625
  );
1494
1626
  return make(POSTGRES_ENTITY_TYPES.eventTrigger, { name }, props);
1495
1627
  }
1628
+ case "operator": {
1629
+ const q = qualified(ctx, node.name);
1630
+ const comment = applyComments(tag, ctx, comments, q, ["OPERATOR"]);
1631
+ const opt = definitionValues(ctx, node.options, "options");
1632
+ const { leftarg, rightarg, procedure, ...rest } = opt;
1633
+ const props: OperatorProps = stripUnset({ ...q, leftArg: leftarg, rightArg: rightarg, options: { ...rest, function: opt.function ?? procedure }, comment, ddl, source });
1634
+ // The symbol is unquoted wherever the operator is named: `app.===`.
1635
+ return make(POSTGRES_ENTITY_TYPES.operator, q, props, undefined, q.schema ? `${quoteIdent(q.schema)}.${q.name}` : q.name);
1636
+ }
1637
+ case "statistics": {
1638
+ const q = qualified(ctx, node.name);
1639
+ const comment = applyComments(tag, ctx, comments, q, ["STATISTICS"]);
1640
+ const props: StatisticsProps = strip(
1641
+ {
1642
+ ...q,
1643
+ ifNotExists: node.ifNotExists || undefined,
1644
+ kinds: node.kinds.length > 0 ? node.kinds : undefined,
1645
+ targets: node.targets.map((t) => req(text(ctx, t, "targets"))),
1646
+ table: target(ctx, node.table),
1647
+ tableName: sqlNameOf(qualified(ctx, node.table)),
1648
+ comment,
1649
+ ddl,
1650
+ source,
1651
+ },
1652
+ ["targets"],
1653
+ );
1654
+ return make(POSTGRES_ENTITY_TYPES.statistics, q, props);
1655
+ }
1656
+ case "foreignDataWrapper": {
1657
+ const name = databaseObjectName(ctx, node.name);
1658
+ const comment = applyComments(tag, ctx, comments, { name }, ["FOREIGN DATA WRAPPER"]);
1659
+ const props: ForeignDataWrapperProps = strip(
1660
+ {
1661
+ name,
1662
+ handler: node.handler ? target(ctx, node.handler) : undefined,
1663
+ handlerName: node.handler ? targetName(ctx, node.handler) : undefined,
1664
+ noHandler: node.handler === null ? true : undefined,
1665
+ validator: node.validator ? target(ctx, node.validator) : undefined,
1666
+ validatorName: node.validator ? targetName(ctx, node.validator) : undefined,
1667
+ noValidator: node.validator === null ? true : undefined,
1668
+ options: genericOptionValues(tag, ctx, node.options),
1669
+ comment,
1670
+ ddl,
1671
+ source,
1672
+ },
1673
+ ["options"],
1674
+ );
1675
+ return make(POSTGRES_ENTITY_TYPES.foreignDataWrapper, { name }, props);
1676
+ }
1677
+ case "foreignServer": {
1678
+ const name = databaseObjectName(ctx, node.name);
1679
+ const comment = applyComments(tag, ctx, comments, { name }, ["SERVER"]);
1680
+ const props: ForeignServerProps = strip(
1681
+ {
1682
+ name,
1683
+ ifNotExists: node.ifNotExists || undefined,
1684
+ serverType: node.type ? stringValue(text(ctx, node.type, "serverType")) : undefined,
1685
+ version: node.version ? stringValue(text(ctx, node.version, "version")) : undefined,
1686
+ wrapper: target(ctx, node.wrapper),
1687
+ wrapperName: targetName(ctx, node.wrapper),
1688
+ options: genericOptionValues(tag, ctx, node.options),
1689
+ comment,
1690
+ ddl,
1691
+ source,
1692
+ },
1693
+ ["options"],
1694
+ );
1695
+ return make(POSTGRES_ENTITY_TYPES.foreignServer, { name }, props);
1696
+ }
1697
+ case "publication": {
1698
+ const name = databaseObjectName(ctx, node.name);
1699
+ const comment = applyComments(tag, ctx, comments, { name }, ["PUBLICATION"]);
1700
+ const tables = node.items.flatMap((i) =>
1701
+ i.kind !== "table"
1702
+ ? []
1703
+ : [
1704
+ stripUnset({
1705
+ table: target(ctx, i.table),
1706
+ tableName: sqlNameOf(qualified(ctx, i.table)),
1707
+ columns: i.columns?.map((c) => columnName(ctx, { name: c.name, span: c.span })),
1708
+ where: text(ctx, i.where, "tables"),
1709
+ }) as PublicationTableDef,
1710
+ ],
1711
+ );
1712
+ const schemas = node.items.flatMap((i) => (i.kind === "schema" ? [qualified(ctx, i.schema).name] : []));
1713
+ const props: PublicationProps = strip(
1714
+ { name, allTables: node.allTables || undefined, tables, schemas, options: definitionValues(ctx, node.options, "options"), comment, ddl, source },
1715
+ ["tables", "schemas", "options"],
1716
+ );
1717
+ return make(POSTGRES_ENTITY_TYPES.publication, { name }, props);
1718
+ }
1496
1719
  case "domain": {
1497
1720
  const q = qualified(ctx, node.name);
1498
1721
  const checks = node.checks.map((c) => stripUnset({ name: c.name, expr: req(text(ctx, c.expr, "checks")), notValid: c.notValid }) as CheckDef);
@@ -1961,6 +2184,48 @@ export function eventTrigger(strings: TemplateStringsArray, ...values: unknown[]
1961
2184
  return build("eventTrigger", strings, values) as PostgresEventTrigger;
1962
2185
  }
1963
2186
 
2187
+ /**
2188
+ * `` operator`CREATE OPERATOR app.=== (FUNCTION = ${fn}, LEFTARG = int, RIGHTARG = int)` ``:
2189
+ * one operator, identified by its name and operand types, as a function is by
2190
+ * its name and parameter types.
2191
+ */
2192
+ export function operator(strings: TemplateStringsArray, ...values: unknown[]): PostgresOperator {
2193
+ return build("operator", strings, values) as PostgresOperator;
2194
+ }
2195
+
2196
+ /**
2197
+ * `` statistics`CREATE STATISTICS name (ndistinct, dependencies) ON a, b FROM ${table}` ``:
2198
+ * extended statistics on columns or expressions of one table.
2199
+ */
2200
+ export function statistics(strings: TemplateStringsArray, ...values: unknown[]): PostgresStatistics {
2201
+ return build("statistics", strings, values) as PostgresStatistics;
2202
+ }
2203
+
2204
+ /**
2205
+ * `` foreignDataWrapper`CREATE FOREIGN DATA WRAPPER name HANDLER ${fn} OPTIONS (...)` ``:
2206
+ * one foreign data wrapper, the database's (no schema). Creating one takes a superuser.
2207
+ */
2208
+ export function foreignDataWrapper(strings: TemplateStringsArray, ...values: unknown[]): PostgresForeignDataWrapper {
2209
+ return build("foreignDataWrapper", strings, values) as PostgresForeignDataWrapper;
2210
+ }
2211
+
2212
+ /**
2213
+ * `` foreignServer`CREATE SERVER name FOREIGN DATA WRAPPER ${fdw} OPTIONS (host 'db.internal')` ``:
2214
+ * one foreign server, the database's. Its user mappings carry credentials and are
2215
+ * not declared; an option that holds a secret is the environment's to supply.
2216
+ */
2217
+ export function foreignServer(strings: TemplateStringsArray, ...values: unknown[]): PostgresForeignServer {
2218
+ return build("foreignServer", strings, values) as PostgresForeignServer;
2219
+ }
2220
+
2221
+ /**
2222
+ * `` publication`CREATE PUBLICATION name FOR TABLE ${t} WITH (publish = 'insert')` ``:
2223
+ * one logical-replication publication, the database's.
2224
+ */
2225
+ export function publication(strings: TemplateStringsArray, ...values: unknown[]): PostgresPublication {
2226
+ return build("publication", strings, values) as PostgresPublication;
2227
+ }
2228
+
1964
2229
  /** `` trigger`CREATE [OR REPLACE] [CONSTRAINT] TRIGGER name ... ON ${table} ... EXECUTE FUNCTION ${fn}()` ``: one trigger on its table. */
1965
2230
  export function trigger(strings: TemplateStringsArray, ...values: unknown[]): PostgresTrigger {
1966
2231
  return build("trigger", strings, values) as PostgresTrigger;
@@ -18,6 +18,11 @@ export const POSTGRES_ENTITY_TYPES = {
18
18
  collation: "Postgres::Collation",
19
19
  cast: "Postgres::Cast",
20
20
  eventTrigger: "Postgres::EventTrigger",
21
+ operator: "Postgres::Operator",
22
+ statistics: "Postgres::Statistics",
23
+ foreignDataWrapper: "Postgres::ForeignDataWrapper",
24
+ foreignServer: "Postgres::ForeignServer",
25
+ publication: "Postgres::Publication",
21
26
  extension: "Postgres::Extension",
22
27
  function: "Postgres::Function",
23
28
  procedure: "Postgres::Procedure",
@@ -60,6 +60,11 @@ const TAG: Record<string, string> = {
60
60
  [POSTGRES_ENTITY_TYPES.collation]: "collation",
61
61
  [POSTGRES_ENTITY_TYPES.cast]: "cast",
62
62
  [POSTGRES_ENTITY_TYPES.eventTrigger]: "eventTrigger",
63
+ [POSTGRES_ENTITY_TYPES.operator]: "operator",
64
+ [POSTGRES_ENTITY_TYPES.statistics]: "statistics",
65
+ [POSTGRES_ENTITY_TYPES.foreignDataWrapper]: "foreignDataWrapper",
66
+ [POSTGRES_ENTITY_TYPES.foreignServer]: "foreignServer",
67
+ [POSTGRES_ENTITY_TYPES.publication]: "publication",
63
68
  [POSTGRES_ENTITY_TYPES.extension]: "extension",
64
69
  [POSTGRES_ENTITY_TYPES.function]: "func",
65
70
  [POSTGRES_ENTITY_TYPES.procedure]: "procedure",
@@ -81,6 +86,10 @@ const UNREFERENCED: ReadonlySet<string> = new Set([
81
86
  POSTGRES_ENTITY_TYPES.extension,
82
87
  POSTGRES_ENTITY_TYPES.cast,
83
88
  POSTGRES_ENTITY_TYPES.eventTrigger,
89
+ POSTGRES_ENTITY_TYPES.operator,
90
+ POSTGRES_ENTITY_TYPES.statistics,
91
+ POSTGRES_ENTITY_TYPES.foreignServer,
92
+ POSTGRES_ENTITY_TYPES.publication,
84
93
  ]);
85
94
 
86
95
  /** The tag each entity type is declared with (`table`, `func`, ...). */
@@ -131,6 +140,12 @@ function bareSpots(tokens: Token[]): Set<number> {
131
140
  name(node.function);
132
141
  }
133
142
  if (node.statement === "eventTrigger") name(node.function);
143
+ if (node.statement === "foreignServer") name(node.wrapper);
144
+ if (node.statement === "foreignDataWrapper") {
145
+ name(node.handler ?? undefined);
146
+ name(node.validator ?? undefined);
147
+ }
148
+ if (node.statement === "statistics") name(node.table);
134
149
  if (node.statement === "index" || node.statement === "policy") name(node.table);
135
150
  if (node.statement === "trigger") {
136
151
  name(node.table);
@@ -141,6 +156,25 @@ function bareSpots(tokens: Token[]): Set<number> {
141
156
  return out;
142
157
  }
143
158
 
159
+ /** The tokens that name a schema in a publication's `TABLES IN SCHEMA a, b`, past the first, which follows the word SCHEMA. */
160
+ function schemaSpots(tokens: Token[]): Set<number> {
161
+ const out = new Set<number>();
162
+ let nodes: StatementNode[];
163
+ try {
164
+ nodes = parseStatements(tokens);
165
+ } catch {
166
+ return out;
167
+ }
168
+ for (const node of nodes) {
169
+ if (node.statement !== "publication") continue;
170
+ for (const i of node.items) {
171
+ if (i.kind !== "schema") continue;
172
+ for (let k = i.schema.span.from; k < i.schema.span.to; k++) if (!isTrivia(tokens[k]!)) { out.add(k); break; }
173
+ }
174
+ }
175
+ return out;
176
+ }
177
+
144
178
  function templateBody(item: Item, byQualified: Map<string, Item>, schemaExport: Map<string, string>): TemplateBody {
145
179
  const tokens = tokenizeText(item.ddl, 0);
146
180
  const sig: number[] = [];
@@ -148,6 +182,7 @@ function templateBody(item: Item, byQualified: Map<string, Item>, schemaExport:
148
182
  if (!isTrivia(t)) sig.push(i);
149
183
  });
150
184
  const spots = bareSpots(tokens);
185
+ const schemaAt = item.type === POSTGRES_ENTITY_TYPES.publication ? schemaSpots(tokens) : new Set<number>();
151
186
  const replace = new Map<number, { to: number; ref: string }>();
152
187
  const isSelf = (target: Item) => target === item || (target.exportName === item.exportName && target.type === item.type);
153
188
  for (let k = 0; k < sig.length; k++) {
@@ -169,10 +204,15 @@ function templateBody(item: Item, byQualified: Map<string, Item>, schemaExport:
169
204
  }
170
205
  const dot = tokens[sig[k + 1] ?? -1];
171
206
  const b = tokens[sig[k + 2] ?? -1];
207
+ // An operator's own `schema.symbol`: the schema is the schema's export, though the symbol is no name.
208
+ if (item.type === POSTGRES_ENTITY_TYPES.operator && isName(a) && dot?.kind === "punct" && dot.text === "." && b?.kind === "op" && identValue(a) === item.schema && schemaExport.has(item.schema)) {
209
+ replace.set(sig[k]!, { to: sig[k]! + 1, ref: schemaExport.get(item.schema)! });
210
+ continue;
211
+ }
172
212
  if (!isName(a) || dot?.kind !== "punct" || dot.text !== "." || !isName(b)) {
173
213
  // An extension's `WITH SCHEMA app`, a grant's `ON SCHEMA app`, default privileges' `IN SCHEMA app`.
174
- const bySchemaWord = item.type === POSTGRES_ENTITY_TYPES.extension || item.type === POSTGRES_ENTITY_TYPES.grant || item.type === POSTGRES_ENTITY_TYPES.defaultPrivileges;
175
- if (bySchemaWord && isName(a) && prev?.kind === "ident" && prev.text.toUpperCase() === "SCHEMA") {
214
+ const bySchemaWord = item.type === POSTGRES_ENTITY_TYPES.extension || item.type === POSTGRES_ENTITY_TYPES.grant || item.type === POSTGRES_ENTITY_TYPES.defaultPrivileges || schemaAt.size > 0;
215
+ if (bySchemaWord && isName(a) && ((prev?.kind === "ident" && prev.text.toUpperCase() === "SCHEMA") || schemaAt.has(sig[k]!))) {
176
216
  const s = schemaExport.get(identValue(a));
177
217
  if (s) replace.set(sig[k]!, { to: sig[k]! + 1, ref: s });
178
218
  continue;
@@ -84,6 +84,7 @@ export async function exportResources(options: ExportOptions): Promise<ExportedT
84
84
  warnings.push(`${o.schema ? `${o.schema}.` : ""}${o.name} is kept by ${o.foreign}; left out, since declaring it would have chant change what that tool owns`);
85
85
  continue;
86
86
  }
87
+ for (const w of o.warnings ?? []) warnings.push(`${o.schema ? `${o.schema}.` : ""}${o.name}: ${w}`);
87
88
  objects.push({ type: o.type, ...(o.schema ? { schema: o.schema } : {}), name: o.name, ddl: o.statement });
88
89
  }
89
90
  return objectsToIR([...objects, ...access], warnings) as ExportedTemplate;