@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
@@ -66,6 +67,7 @@ export { SqlLiteral, SqlTemplateError } from "../core/template.js";
66
67
  export { quoteIdent } from "./keywords.js";
67
68
  export { POSTGRES_ENTITY_TYPES } from "./entity-types.js";
68
69
  import { POSTGRES_ENTITY_TYPES } from "./entity-types.js";
70
+ import { isSecretOption } from "./secret-options.js";
69
71
  /**
70
72
  * A string as a quoted Postgres string literal: `'` doubled, a backslash left
71
73
  * as written (standard_conforming_strings is on). An interpolated plain string
@@ -193,6 +195,16 @@ export const STATEMENTS_OF = {
193
195
  aggregate: ["aggregate"],
194
196
  trigger: ["trigger"],
195
197
  eventTrigger: ["eventTrigger"],
198
+ operator: ["operator"],
199
+ operatorClass: ["operatorClass"],
200
+ operatorFamily: ["operatorFamily"],
201
+ foreignTable: ["foreignTable"],
202
+ textSearchConfiguration: ["textSearchConfiguration"],
203
+ textSearchDictionary: ["textSearchDictionary"],
204
+ statistics: ["statistics"],
205
+ foreignDataWrapper: ["foreignDataWrapper"],
206
+ foreignServer: ["foreignServer"],
207
+ publication: ["publication"],
196
208
  collation: ["collation"],
197
209
  cast: ["cast"],
198
210
  policy: ["policy"],
@@ -215,6 +227,17 @@ const TAG_OF = {
215
227
  aggregate: "aggregate",
216
228
  trigger: "trigger",
217
229
  eventTrigger: "eventTrigger",
230
+ operator: "operator",
231
+ operatorClass: "operatorClass",
232
+ operatorFamily: "operatorFamily",
233
+ foreignTable: "foreignTable",
234
+ textSearchConfiguration: "textSearchConfiguration",
235
+ textSearchDictionary: "textSearchDictionary",
236
+ textSearchMapping: undefined,
237
+ statistics: "statistics",
238
+ foreignDataWrapper: "foreignDataWrapper",
239
+ foreignServer: "foreignServer",
240
+ publication: "publication",
218
241
  collation: "collation",
219
242
  cast: "cast",
220
243
  policy: "policy",
@@ -240,6 +263,17 @@ export const STATEMENT_NAMES = {
240
263
  aggregate: "CREATE AGGREGATE",
241
264
  trigger: "CREATE TRIGGER",
242
265
  eventTrigger: "CREATE EVENT TRIGGER",
266
+ operator: "CREATE OPERATOR",
267
+ operatorClass: "CREATE OPERATOR CLASS",
268
+ operatorFamily: "CREATE OPERATOR FAMILY",
269
+ foreignTable: "CREATE FOREIGN TABLE",
270
+ textSearchConfiguration: "CREATE TEXT SEARCH CONFIGURATION",
271
+ textSearchDictionary: "CREATE TEXT SEARCH DICTIONARY",
272
+ textSearchMapping: "ALTER TEXT SEARCH CONFIGURATION",
273
+ statistics: "CREATE STATISTICS",
274
+ foreignDataWrapper: "CREATE FOREIGN DATA WRAPPER",
275
+ foreignServer: "CREATE SERVER",
276
+ publication: "CREATE PUBLICATION",
243
277
  collation: "CREATE COLLATION",
244
278
  cast: "CREATE CAST",
245
279
  policy: "CREATE POLICY",
@@ -273,6 +307,22 @@ function definitionValues(ctx, elems, path) {
273
307
  out[e.name] = e.value ? req(text(ctx, e.value, path)) : "true";
274
308
  return out;
275
309
  }
310
+ /** A database-wide object's name (a wrapper, a server, a publication): one piece, or an interpolated object's name. */
311
+ function databaseObjectName(ctx, n) {
312
+ feed(ctx, n.span, "name");
313
+ return n.pieces[0] || identValue(req(text(ctx, n.span)));
314
+ }
315
+ /** An `OPTIONS (...)` list's values by option name, each a string constant's value. */
316
+ function genericOptionValues(tag, ctx, options) {
317
+ const out = {};
318
+ for (const o of options) {
319
+ if (isSecretOption(o.name)) {
320
+ 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);
321
+ }
322
+ out[o.name] = req(stringValue(text(ctx, o.value, "options")));
323
+ }
324
+ return out;
325
+ }
276
326
  /** A qualified name's schema and name. An interpolated schema names the schema; an interpolated object gives both. */
277
327
  function qualified(ctx, n) {
278
328
  const pieces = [];
@@ -332,7 +382,7 @@ function columnName(ctx, c) {
332
382
  const v = t?.kind === "ref" ? ctx.values[t.part] : undefined;
333
383
  return isColumnRef(v) ? v.attribute : req(text(ctx, c.span));
334
384
  }
335
- function columnDef(ctx, c) {
385
+ function columnDef(ctx, c, tag = "table") {
336
386
  for (const span of [c.nameSpan, c.type, c.default, c.collate, c.compression, c.storage, c.generated?.expr, c.generated?.options])
337
387
  feed(ctx, span, "columns");
338
388
  const def = { name: columnName(ctx, { name: c.name, span: c.nameSpan }) };
@@ -357,6 +407,8 @@ function columnDef(ctx, c) {
357
407
  set("collate", text(ctx, c.collate));
358
408
  set("compression", text(ctx, c.compression));
359
409
  set("storage", text(ctx, c.storage));
410
+ if (c.options && c.options.length > 0)
411
+ def.options = genericOptionValues(tag, ctx, c.options);
360
412
  return def;
361
413
  }
362
414
  function deferral(c) {
@@ -434,7 +486,7 @@ function exclusionDef(ctx, c) {
434
486
  * the object itself, one of its columns, or one of its named constraints.
435
487
  * Anything else is refused, since a template declares one object.
436
488
  */
437
- function applyComments(tag, ctx, comments, self, objectTypes, parts = {}) {
489
+ function applyComments(tag, ctx, comments, self, objectTypes, parts = {}, using) {
438
490
  let comment;
439
491
  const isSelf = (q) => q.name === self.name && (q.schema === undefined || self.schema === undefined || q.schema === self.schema);
440
492
  const refuse = (c, why) => {
@@ -492,6 +544,9 @@ function applyComments(tag, ctx, comments, self, objectTypes, parts = {}) {
492
544
  }
493
545
  else if (!isSelf(qualified(ctx, c.target)))
494
546
  refuse(c, `names another object than ${sqlNameOf(self)}`);
547
+ // An operator class or family is named by its index method too.
548
+ if (using !== undefined && c.using !== using)
549
+ refuse(c, `names another index method than ${using}`);
495
550
  comment = value;
496
551
  }
497
552
  }
@@ -515,7 +570,7 @@ function lastDot(ctx, span) {
515
570
  export function followOnStray(tag, rest) {
516
571
  if (tag === "grant")
517
572
  return rest[0];
518
- return rest.find((n) => n.statement !== "comment" && !(tag === "table" && n.statement === "rowSecurity"));
573
+ return rest.find((n) => n.statement !== "comment" && !(tag === "table" && n.statement === "rowSecurity") && !(tag === "textSearchConfiguration" && n.statement === "textSearchMapping"));
519
574
  }
520
575
  /**
521
576
  * The interpolations that sit inside a string constant (a routine's
@@ -748,7 +803,7 @@ function build(tag, strings, rawValues) {
748
803
  }
749
804
  const stray = followOnStray(tag, rest);
750
805
  if (stray) {
751
- throw new SqlTemplateError(tag, `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" : ""}`, 0, 0);
806
+ throw new SqlTemplateError(tag, `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" : ""}`, 0, 0);
752
807
  }
753
808
  const comments = rest.filter((n) => n.statement === "comment");
754
809
  const rowSecurity = rest.filter((n) => n.statement === "rowSecurity");
@@ -906,6 +961,196 @@ function build(tag, strings, rawValues) {
906
961
  }, []);
907
962
  return make(POSTGRES_ENTITY_TYPES.eventTrigger, { name }, props);
908
963
  }
964
+ case "operator": {
965
+ const q = qualified(ctx, node.name);
966
+ const comment = applyComments(tag, ctx, comments, q, ["OPERATOR"]);
967
+ const opt = definitionValues(ctx, node.options, "options");
968
+ const { leftarg, rightarg, procedure, ...rest } = opt;
969
+ const props = stripUnset({ ...q, leftArg: leftarg, rightArg: rightarg, options: { ...rest, function: opt.function ?? procedure }, comment, ddl, source });
970
+ // The symbol is unquoted wherever the operator is named: `app.===`.
971
+ return make(POSTGRES_ENTITY_TYPES.operator, q, props, undefined, q.schema ? `${quoteIdent(q.schema)}.${q.name}` : q.name);
972
+ }
973
+ case "operatorClass": {
974
+ const q = qualified(ctx, node.name);
975
+ if (node.method === "")
976
+ throw new SqlTemplateError(tag, "the index method is written out, not interpolated", 0, 0);
977
+ const comment = applyComments(tag, ctx, comments, q, ["OPERATOR CLASS"], {}, node.method);
978
+ const items = node.items.map((i) => {
979
+ if (i.kind === "storage")
980
+ return { kind: "storage", type: req(text(ctx, i.type, "items")) };
981
+ if (i.kind === "function") {
982
+ feed(ctx, i.function.span, "items");
983
+ 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") ?? "" });
984
+ }
985
+ return stripUnset({
986
+ kind: "operator",
987
+ number: req(text(ctx, i.number, "items")),
988
+ operator: req(text(ctx, i.operator.span, "items")),
989
+ types: text(ctx, i.types, "items"),
990
+ orderBy: i.orderBy ? targetName(ctx, i.orderBy) : undefined,
991
+ });
992
+ });
993
+ const props = stripUnset({
994
+ ...q,
995
+ default: node.default || undefined,
996
+ dataType: req(text(ctx, node.type, "dataType")),
997
+ method: node.method,
998
+ family: node.family ? targetName(ctx, node.family) : undefined,
999
+ items,
1000
+ comment,
1001
+ ddl,
1002
+ source,
1003
+ });
1004
+ return make(POSTGRES_ENTITY_TYPES.operatorClass, q, props);
1005
+ }
1006
+ case "operatorFamily": {
1007
+ const q = qualified(ctx, node.name);
1008
+ if (node.method === "")
1009
+ throw new SqlTemplateError(tag, "the index method is written out, not interpolated", 0, 0);
1010
+ const comment = applyComments(tag, ctx, comments, q, ["OPERATOR FAMILY"], {}, node.method);
1011
+ const props = stripUnset({ ...q, method: node.method, comment, ddl, source });
1012
+ return make(POSTGRES_ENTITY_TYPES.operatorFamily, q, props);
1013
+ }
1014
+ case "foreignTable": {
1015
+ const q = qualified(ctx, node.name);
1016
+ const columns = node.columns.map((c) => columnDef(ctx, c, tag));
1017
+ const checks = [];
1018
+ const file = (c, cols) => {
1019
+ if (c.kind === "CHECK")
1020
+ checks.push(checkDef(ctx, c));
1021
+ else if (c.kind === "NOT NULL") {
1022
+ const col = columns.find((x) => x.name === cols[0]);
1023
+ if (!col)
1024
+ throw new SqlTemplateError(tag, `NOT NULL ${cols[0]} names no column of ${sqlNameOf(q)}`, 0, 0);
1025
+ col.notNull = true;
1026
+ if (c.name)
1027
+ col.notNullName = c.name;
1028
+ }
1029
+ };
1030
+ node.columns.forEach((c, i) => c.constraints.forEach((k) => file(k, [columns[i].name])));
1031
+ node.constraints.forEach((k) => file(k, k.columns.map((x) => columnName(ctx, x))));
1032
+ const named = new Map();
1033
+ for (const c of checks)
1034
+ if (c.name)
1035
+ named.set(c.name, c);
1036
+ const comment = applyComments(tag, ctx, comments, q, ["FOREIGN TABLE"], { columns: new Map(columns.map((c) => [c.name, c])), constraints: named });
1037
+ const props = strip({
1038
+ ...q,
1039
+ ifNotExists: node.ifNotExists || undefined,
1040
+ columns,
1041
+ checks,
1042
+ serverName: databaseObjectName(ctx, node.server),
1043
+ options: genericOptionValues(tag, ctx, node.options),
1044
+ comment,
1045
+ ddl,
1046
+ source,
1047
+ }, ["columns", "checks", "options"]);
1048
+ return make(POSTGRES_ENTITY_TYPES.foreignTable, q, props, columns.map((c) => c.name));
1049
+ }
1050
+ case "textSearchDictionary": {
1051
+ const q = qualified(ctx, node.name);
1052
+ const comment = applyComments(tag, ctx, comments, q, ["TEXT SEARCH DICTIONARY"]);
1053
+ const { template, ...options } = definitionValues(ctx, node.options, "options");
1054
+ const props = strip({ ...q, template: req(template), options, comment, ddl, source }, ["options"]);
1055
+ return make(POSTGRES_ENTITY_TYPES.textSearchDictionary, q, props);
1056
+ }
1057
+ case "textSearchConfiguration": {
1058
+ const q = qualified(ctx, node.name);
1059
+ const comment = applyComments(tag, ctx, comments, q, ["TEXT SEARCH CONFIGURATION"]);
1060
+ const opt = definitionValues(ctx, node.options, "options");
1061
+ const seen = new Set();
1062
+ const mappings = rest
1063
+ .filter((n) => n.statement === "textSearchMapping")
1064
+ .map((m) => {
1065
+ feed(ctx, m.name.span, "mappings");
1066
+ const t = qualified(ctx, m.name);
1067
+ if (t.name !== q.name || (t.schema !== undefined && q.schema !== undefined && t.schema !== q.schema)) {
1068
+ throw new SqlTemplateError(tag, `ADD MAPPING names another configuration (${sqlNameOf(t)}) than ${sqlNameOf(q)}`, 0, 0);
1069
+ }
1070
+ const tokens = m.tokens.map((x) => x.name || identValue(req(text(ctx, x.span, "mappings"))));
1071
+ for (const tok of tokens) {
1072
+ if (seen.has(tok))
1073
+ throw new SqlTemplateError(tag, `the token type ${tok} is mapped twice in ${sqlNameOf(q)}`, 0, 0);
1074
+ seen.add(tok);
1075
+ }
1076
+ for (const d of m.dictionaries)
1077
+ feed(ctx, d.span, "mappings");
1078
+ return { tokens, dictionaries: m.dictionaries.map((d) => sqlNameOf(qualified(ctx, d))) };
1079
+ });
1080
+ const props = strip({ ...q, parser: req(opt.parser), mappings, comment, ddl, source }, ["mappings"]);
1081
+ return make(POSTGRES_ENTITY_TYPES.textSearchConfiguration, q, props);
1082
+ }
1083
+ case "textSearchMapping":
1084
+ // Only a configuration's follow-on statement (`followOnStray`); first in a template it is refused above.
1085
+ throw new SqlTemplateError(tag, "holds an ALTER TEXT SEARCH CONFIGURATION before any CREATE", 0, 0);
1086
+ case "statistics": {
1087
+ const q = qualified(ctx, node.name);
1088
+ const comment = applyComments(tag, ctx, comments, q, ["STATISTICS"]);
1089
+ const props = strip({
1090
+ ...q,
1091
+ ifNotExists: node.ifNotExists || undefined,
1092
+ kinds: node.kinds.length > 0 ? node.kinds : undefined,
1093
+ targets: node.targets.map((t) => req(text(ctx, t, "targets"))),
1094
+ table: target(ctx, node.table),
1095
+ tableName: sqlNameOf(qualified(ctx, node.table)),
1096
+ comment,
1097
+ ddl,
1098
+ source,
1099
+ }, ["targets"]);
1100
+ return make(POSTGRES_ENTITY_TYPES.statistics, q, props);
1101
+ }
1102
+ case "foreignDataWrapper": {
1103
+ const name = databaseObjectName(ctx, node.name);
1104
+ const comment = applyComments(tag, ctx, comments, { name }, ["FOREIGN DATA WRAPPER"]);
1105
+ const props = strip({
1106
+ name,
1107
+ handler: node.handler ? target(ctx, node.handler) : undefined,
1108
+ handlerName: node.handler ? targetName(ctx, node.handler) : undefined,
1109
+ noHandler: node.handler === null ? true : undefined,
1110
+ validator: node.validator ? target(ctx, node.validator) : undefined,
1111
+ validatorName: node.validator ? targetName(ctx, node.validator) : undefined,
1112
+ noValidator: node.validator === null ? true : undefined,
1113
+ options: genericOptionValues(tag, ctx, node.options),
1114
+ comment,
1115
+ ddl,
1116
+ source,
1117
+ }, ["options"]);
1118
+ return make(POSTGRES_ENTITY_TYPES.foreignDataWrapper, { name }, props);
1119
+ }
1120
+ case "foreignServer": {
1121
+ const name = databaseObjectName(ctx, node.name);
1122
+ const comment = applyComments(tag, ctx, comments, { name }, ["SERVER"]);
1123
+ const props = strip({
1124
+ name,
1125
+ ifNotExists: node.ifNotExists || undefined,
1126
+ serverType: node.type ? stringValue(text(ctx, node.type, "serverType")) : undefined,
1127
+ version: node.version ? stringValue(text(ctx, node.version, "version")) : undefined,
1128
+ wrapper: target(ctx, node.wrapper),
1129
+ wrapperName: targetName(ctx, node.wrapper),
1130
+ options: genericOptionValues(tag, ctx, node.options),
1131
+ comment,
1132
+ ddl,
1133
+ source,
1134
+ }, ["options"]);
1135
+ return make(POSTGRES_ENTITY_TYPES.foreignServer, { name }, props);
1136
+ }
1137
+ case "publication": {
1138
+ const name = databaseObjectName(ctx, node.name);
1139
+ const comment = applyComments(tag, ctx, comments, { name }, ["PUBLICATION"]);
1140
+ const tables = node.items.flatMap((i) => i.kind !== "table"
1141
+ ? []
1142
+ : [
1143
+ stripUnset({
1144
+ table: target(ctx, i.table),
1145
+ tableName: sqlNameOf(qualified(ctx, i.table)),
1146
+ columns: i.columns?.map((c) => columnName(ctx, { name: c.name, span: c.span })),
1147
+ where: text(ctx, i.where, "tables"),
1148
+ }),
1149
+ ]);
1150
+ const schemas = node.items.flatMap((i) => (i.kind === "schema" ? [qualified(ctx, i.schema).name] : []));
1151
+ const props = strip({ name, allTables: node.allTables || undefined, tables, schemas, options: definitionValues(ctx, node.options, "options"), comment, ddl, source }, ["tables", "schemas", "options"]);
1152
+ return make(POSTGRES_ENTITY_TYPES.publication, { name }, props);
1153
+ }
909
1154
  case "domain": {
910
1155
  const q = qualified(ctx, node.name);
911
1156
  const checks = node.checks.map((c) => stripUnset({ name: c.name, expr: req(text(ctx, c.expr, "checks")), notValid: c.notValid }));
@@ -1362,6 +1607,82 @@ export function cast(strings, ...values) {
1362
1607
  export function eventTrigger(strings, ...values) {
1363
1608
  return build("eventTrigger", strings, values);
1364
1609
  }
1610
+ /**
1611
+ * `` operator`CREATE OPERATOR app.=== (FUNCTION = ${fn}, LEFTARG = int, RIGHTARG = int)` ``:
1612
+ * one operator, identified by its name and operand types, as a function is by
1613
+ * its name and parameter types.
1614
+ */
1615
+ export function operator(strings, ...values) {
1616
+ return build("operator", strings, values);
1617
+ }
1618
+ /**
1619
+ * `` operatorClass`CREATE OPERATOR CLASS app.ops DEFAULT FOR TYPE int USING btree AS OPERATOR 1 <, FUNCTION 1 ${cmp}(int, int)` ``:
1620
+ * one operator class, identified by its name and index method. Creating one takes a superuser.
1621
+ */
1622
+ export function operatorClass(strings, ...values) {
1623
+ return build("operatorClass", strings, values);
1624
+ }
1625
+ /**
1626
+ * `` operatorFamily`CREATE OPERATOR FAMILY app.ops USING btree` ``: one operator
1627
+ * family, identified by its name and index method. Its members come with the
1628
+ * operator classes that name it. Creating one takes a superuser.
1629
+ */
1630
+ export function operatorFamily(strings, ...values) {
1631
+ return build("operatorFamily", strings, values);
1632
+ }
1633
+ /**
1634
+ * `` foreignTable`CREATE FOREIGN TABLE app.remote_orders (id int, total numeric) SERVER ${remote} OPTIONS (table_name 'orders')` ``:
1635
+ * one foreign table. It has its own tag, not `table`, because it is another
1636
+ * kind of relation: another CREATE and ALTER, no key, index, partitioning or
1637
+ * storage clauses, and a server it cannot move off.
1638
+ */
1639
+ export function foreignTable(strings, ...values) {
1640
+ return build("foreignTable", strings, values);
1641
+ }
1642
+ /**
1643
+ * `` textSearchDictionary`CREATE TEXT SEARCH DICTIONARY app.english_stop (TEMPLATE = snowball, Language = english, StopWords = english)` ``:
1644
+ * one text search dictionary: a template and its options.
1645
+ */
1646
+ export function textSearchDictionary(strings, ...values) {
1647
+ return build("textSearchDictionary", strings, values);
1648
+ }
1649
+ /**
1650
+ * `` textSearchConfiguration`CREATE TEXT SEARCH CONFIGURATION app.english2 (PARSER = default); ALTER TEXT SEARCH CONFIGURATION app.english2 ADD MAPPING FOR asciiword WITH ${dict}` ``:
1651
+ * one text search configuration: a parser, and the dictionaries each token
1652
+ * type it finds is looked up in.
1653
+ */
1654
+ export function textSearchConfiguration(strings, ...values) {
1655
+ return build("textSearchConfiguration", strings, values);
1656
+ }
1657
+ /**
1658
+ * `` statistics`CREATE STATISTICS name (ndistinct, dependencies) ON a, b FROM ${table}` ``:
1659
+ * extended statistics on columns or expressions of one table.
1660
+ */
1661
+ export function statistics(strings, ...values) {
1662
+ return build("statistics", strings, values);
1663
+ }
1664
+ /**
1665
+ * `` foreignDataWrapper`CREATE FOREIGN DATA WRAPPER name HANDLER ${fn} OPTIONS (...)` ``:
1666
+ * one foreign data wrapper, the database's (no schema). Creating one takes a superuser.
1667
+ */
1668
+ export function foreignDataWrapper(strings, ...values) {
1669
+ return build("foreignDataWrapper", strings, values);
1670
+ }
1671
+ /**
1672
+ * `` foreignServer`CREATE SERVER name FOREIGN DATA WRAPPER ${fdw} OPTIONS (host 'db.internal')` ``:
1673
+ * one foreign server, the database's. Its user mappings carry credentials and are
1674
+ * not declared; an option that holds a secret is the environment's to supply.
1675
+ */
1676
+ export function foreignServer(strings, ...values) {
1677
+ return build("foreignServer", strings, values);
1678
+ }
1679
+ /**
1680
+ * `` publication`CREATE PUBLICATION name FOR TABLE ${t} WITH (publish = 'insert')` ``:
1681
+ * one logical-replication publication, the database's.
1682
+ */
1683
+ export function publication(strings, ...values) {
1684
+ return build("publication", strings, values);
1685
+ }
1365
1686
  /** `` trigger`CREATE [OR REPLACE] [CONSTRAINT] TRIGGER name ... ON ${table} ... EXECUTE FUNCTION ${fn}()` ``: one trigger on its table. */
1366
1687
  export function trigger(strings, ...values) {
1367
1688
  return build("trigger", strings, values);
@@ -17,6 +17,16 @@ export declare const POSTGRES_ENTITY_TYPES: {
17
17
  readonly collation: "Postgres::Collation";
18
18
  readonly cast: "Postgres::Cast";
19
19
  readonly eventTrigger: "Postgres::EventTrigger";
20
+ readonly operator: "Postgres::Operator";
21
+ readonly operatorClass: "Postgres::OperatorClass";
22
+ readonly operatorFamily: "Postgres::OperatorFamily";
23
+ readonly foreignTable: "Postgres::ForeignTable";
24
+ readonly textSearchConfiguration: "Postgres::TextSearchConfiguration";
25
+ readonly textSearchDictionary: "Postgres::TextSearchDictionary";
26
+ readonly statistics: "Postgres::Statistics";
27
+ readonly foreignDataWrapper: "Postgres::ForeignDataWrapper";
28
+ readonly foreignServer: "Postgres::ForeignServer";
29
+ readonly publication: "Postgres::Publication";
20
30
  readonly extension: "Postgres::Extension";
21
31
  readonly function: "Postgres::Function";
22
32
  readonly procedure: "Postgres::Procedure";
@@ -1 +1 @@
1
- {"version":3,"file":"entity-types.d.ts","sourceRoot":"","sources":["../../src/postgres/entity-types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;CAuBxB,CAAC;AAEX,MAAM,MAAM,kBAAkB,GAAG,CAAC,OAAO,qBAAqB,CAAC,CAAC,MAAM,OAAO,qBAAqB,CAAC,CAAC"}
1
+ {"version":3,"file":"entity-types.d.ts","sourceRoot":"","sources":["../../src/postgres/entity-types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAiCxB,CAAC;AAEX,MAAM,MAAM,kBAAkB,GAAG,CAAC,OAAO,qBAAqB,CAAC,CAAC,MAAM,OAAO,qBAAqB,CAAC,CAAC"}
@@ -17,6 +17,16 @@ export const POSTGRES_ENTITY_TYPES = {
17
17
  collation: "Postgres::Collation",
18
18
  cast: "Postgres::Cast",
19
19
  eventTrigger: "Postgres::EventTrigger",
20
+ operator: "Postgres::Operator",
21
+ operatorClass: "Postgres::OperatorClass",
22
+ operatorFamily: "Postgres::OperatorFamily",
23
+ foreignTable: "Postgres::ForeignTable",
24
+ textSearchConfiguration: "Postgres::TextSearchConfiguration",
25
+ textSearchDictionary: "Postgres::TextSearchDictionary",
26
+ statistics: "Postgres::Statistics",
27
+ foreignDataWrapper: "Postgres::ForeignDataWrapper",
28
+ foreignServer: "Postgres::ForeignServer",
29
+ publication: "Postgres::Publication",
20
30
  extension: "Postgres::Extension",
21
31
  function: "Postgres::Function",
22
32
  procedure: "Postgres::Procedure",
@@ -1 +1 @@
1
- {"version":3,"file":"generator.d.ts","sourceRoot":"","sources":["../../../src/postgres/import/generator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAGH,OAAO,KAAK,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AAC5F,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gCAAgC,CAAC;AAKjE,kGAAkG;AAClG,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;CACb;AACD,KAAK,IAAI,GAAG,cAAc,CAAC;AAE3B,uHAAuH;AACvH,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB;AAwCD,wEAAwE;AACxE,eAAO,MAAM,eAAe,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAO,CAAC;AA+HrE,0DAA0D;AAC1D,eAAO,MAAM,QAAQ,GAAI,MAAM,YAAY,KAAG,MAA0F,CAAC;AAEzI;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,SAAS,IAAI,EAAE,EAAE,OAAO,GAAE,SAAS,IAAI,EAAU,GAAG;IAAE,KAAK,EAAE,IAAI,EAAE,CAAC;IAAC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,CAAA;CAAE,CA6BhJ;AAaD,qBAAa,iBAAkB,YAAW,mBAAmB;IAG/C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC;IAFpC,QAAQ,CAAC,UAAU,QAAQ;gBAEE,MAAM,CAAC,EAAE,MAAM,YAAA;IAE5C,QAAQ,CAAC,EAAE,EAAE,UAAU,GAAG,aAAa,EAAE;CAqB1C"}
1
+ {"version":3,"file":"generator.d.ts","sourceRoot":"","sources":["../../../src/postgres/import/generator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAGH,OAAO,KAAK,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AAC5F,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gCAAgC,CAAC;AAKjE,kGAAkG;AAClG,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;CACb;AACD,KAAK,IAAI,GAAG,cAAc,CAAC;AAE3B,uHAAuH;AACvH,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB;AAwDD,wEAAwE;AACxE,eAAO,MAAM,eAAe,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAO,CAAC;AAmKrE,0DAA0D;AAC1D,eAAO,MAAM,QAAQ,GAAI,MAAM,YAAY,KAAG,MAA0F,CAAC;AAEzI;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,SAAS,IAAI,EAAE,EAAE,OAAO,GAAE,SAAS,IAAI,EAAU,GAAG;IAAE,KAAK,EAAE,IAAI,EAAE,CAAC;IAAC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,CAAA;CAAE,CA6BhJ;AAaD,qBAAa,iBAAkB,YAAW,mBAAmB;IAG/C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC;IAFpC,QAAQ,CAAC,UAAU,QAAQ;gBAEE,MAAM,CAAC,EAAE,MAAM,YAAA;IAE5C,QAAQ,CAAC,EAAE,EAAE,UAAU,GAAG,aAAa,EAAE;CAqB1C"}
@@ -40,6 +40,16 @@ const TAG = {
40
40
  [POSTGRES_ENTITY_TYPES.collation]: "collation",
41
41
  [POSTGRES_ENTITY_TYPES.cast]: "cast",
42
42
  [POSTGRES_ENTITY_TYPES.eventTrigger]: "eventTrigger",
43
+ [POSTGRES_ENTITY_TYPES.operator]: "operator",
44
+ [POSTGRES_ENTITY_TYPES.operatorClass]: "operatorClass",
45
+ [POSTGRES_ENTITY_TYPES.operatorFamily]: "operatorFamily",
46
+ [POSTGRES_ENTITY_TYPES.foreignTable]: "foreignTable",
47
+ [POSTGRES_ENTITY_TYPES.textSearchConfiguration]: "textSearchConfiguration",
48
+ [POSTGRES_ENTITY_TYPES.textSearchDictionary]: "textSearchDictionary",
49
+ [POSTGRES_ENTITY_TYPES.statistics]: "statistics",
50
+ [POSTGRES_ENTITY_TYPES.foreignDataWrapper]: "foreignDataWrapper",
51
+ [POSTGRES_ENTITY_TYPES.foreignServer]: "foreignServer",
52
+ [POSTGRES_ENTITY_TYPES.publication]: "publication",
43
53
  [POSTGRES_ENTITY_TYPES.extension]: "extension",
44
54
  [POSTGRES_ENTITY_TYPES.function]: "func",
45
55
  [POSTGRES_ENTITY_TYPES.procedure]: "procedure",
@@ -60,6 +70,12 @@ const UNREFERENCED = new Set([
60
70
  POSTGRES_ENTITY_TYPES.extension,
61
71
  POSTGRES_ENTITY_TYPES.cast,
62
72
  POSTGRES_ENTITY_TYPES.eventTrigger,
73
+ POSTGRES_ENTITY_TYPES.operator,
74
+ // An index names a class, but a class and its own family share a name; a configuration shares one with a dictionary, which a mapping names.
75
+ POSTGRES_ENTITY_TYPES.operatorClass,
76
+ POSTGRES_ENTITY_TYPES.textSearchConfiguration,
77
+ POSTGRES_ENTITY_TYPES.statistics,
78
+ POSTGRES_ENTITY_TYPES.publication,
63
79
  ]);
64
80
  /** The tag each entity type is declared with (`table`, `func`, ...). */
65
81
  export const POSTGRES_TAG_OF = TAG;
@@ -115,6 +131,22 @@ function bareSpots(tokens) {
115
131
  }
116
132
  if (node.statement === "eventTrigger")
117
133
  name(node.function);
134
+ if (node.statement === "foreignServer")
135
+ name(node.wrapper);
136
+ if (node.statement === "foreignTable") {
137
+ for (const c of node.columns)
138
+ if (c.type)
139
+ first(c.type.from, c.type.to);
140
+ name(node.server);
141
+ }
142
+ if (node.statement === "operatorClass")
143
+ first(node.type.from, node.type.to);
144
+ if (node.statement === "foreignDataWrapper") {
145
+ name(node.handler ?? undefined);
146
+ name(node.validator ?? undefined);
147
+ }
148
+ if (node.statement === "statistics")
149
+ name(node.table);
118
150
  if (node.statement === "index" || node.statement === "policy")
119
151
  name(node.table);
120
152
  if (node.statement === "trigger") {
@@ -127,6 +159,31 @@ function bareSpots(tokens) {
127
159
  }
128
160
  return out;
129
161
  }
162
+ /** The tokens that name a schema in a publication's `TABLES IN SCHEMA a, b`, past the first, which follows the word SCHEMA. */
163
+ function schemaSpots(tokens) {
164
+ const out = new Set();
165
+ let nodes;
166
+ try {
167
+ nodes = parseStatements(tokens);
168
+ }
169
+ catch {
170
+ return out;
171
+ }
172
+ for (const node of nodes) {
173
+ if (node.statement !== "publication")
174
+ continue;
175
+ for (const i of node.items) {
176
+ if (i.kind !== "schema")
177
+ continue;
178
+ for (let k = i.schema.span.from; k < i.schema.span.to; k++)
179
+ if (!isTrivia(tokens[k])) {
180
+ out.add(k);
181
+ break;
182
+ }
183
+ }
184
+ }
185
+ return out;
186
+ }
130
187
  function templateBody(item, byQualified, schemaExport) {
131
188
  const tokens = tokenizeText(item.ddl, 0);
132
189
  const sig = [];
@@ -135,6 +192,7 @@ function templateBody(item, byQualified, schemaExport) {
135
192
  sig.push(i);
136
193
  });
137
194
  const spots = bareSpots(tokens);
195
+ const schemaAt = item.type === POSTGRES_ENTITY_TYPES.publication ? schemaSpots(tokens) : new Set();
138
196
  const replace = new Map();
139
197
  const isSelf = (target) => target === item || (target.exportName === item.exportName && target.type === item.type);
140
198
  for (let k = 0; k < sig.length; k++) {
@@ -157,10 +215,15 @@ function templateBody(item, byQualified, schemaExport) {
157
215
  }
158
216
  const dot = tokens[sig[k + 1] ?? -1];
159
217
  const b = tokens[sig[k + 2] ?? -1];
218
+ // An operator's own `schema.symbol`: the schema is the schema's export, though the symbol is no name.
219
+ 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)) {
220
+ replace.set(sig[k], { to: sig[k] + 1, ref: schemaExport.get(item.schema) });
221
+ continue;
222
+ }
160
223
  if (!isName(a) || dot?.kind !== "punct" || dot.text !== "." || !isName(b)) {
161
224
  // An extension's `WITH SCHEMA app`, a grant's `ON SCHEMA app`, default privileges' `IN SCHEMA app`.
162
- const bySchemaWord = item.type === POSTGRES_ENTITY_TYPES.extension || item.type === POSTGRES_ENTITY_TYPES.grant || item.type === POSTGRES_ENTITY_TYPES.defaultPrivileges;
163
- if (bySchemaWord && isName(a) && prev?.kind === "ident" && prev.text.toUpperCase() === "SCHEMA") {
225
+ const bySchemaWord = item.type === POSTGRES_ENTITY_TYPES.extension || item.type === POSTGRES_ENTITY_TYPES.grant || item.type === POSTGRES_ENTITY_TYPES.defaultPrivileges || schemaAt.size > 0;
226
+ if (bySchemaWord && isName(a) && ((prev?.kind === "ident" && prev.text.toUpperCase() === "SCHEMA") || schemaAt.has(sig[k]))) {
164
227
  const s = schemaExport.get(identValue(a));
165
228
  if (s)
166
229
  replace.set(sig[k], { to: sig[k] + 1, ref: s });
@@ -1 +1 @@
1
- {"version":3,"file":"live-export.d.ts","sourceRoot":"","sources":["../../../src/postgres/import/live-export.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AACnF,OAAO,EAAgB,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AAS9D,MAAM,WAAW,aAAc,SAAQ,IAAI,CAAC,WAAW,EAAE,aAAa,CAAC;IACrE,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,gBAAgB,CAAC;IAC5B,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,8HAA8H;IAC9H,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED,wBAAsB,eAAe,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAyCvF"}
1
+ {"version":3,"file":"live-export.d.ts","sourceRoot":"","sources":["../../../src/postgres/import/live-export.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AACnF,OAAO,EAAgB,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AAS9D,MAAM,WAAW,aAAc,SAAQ,IAAI,CAAC,WAAW,EAAE,aAAa,CAAC;IACrE,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,gBAAgB,CAAC;IAC5B,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,8HAA8H;IAC9H,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED,wBAAsB,eAAe,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,gBAAgB,CAAC,CA0CvF"}
@@ -77,6 +77,8 @@ export async function exportResources(options) {
77
77
  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`);
78
78
  continue;
79
79
  }
80
+ for (const w of o.warnings ?? [])
81
+ warnings.push(`${o.schema ? `${o.schema}.` : ""}${o.name}: ${w}`);
80
82
  objects.push({ type: o.type, ...(o.schema ? { schema: o.schema } : {}), name: o.name, ddl: o.statement });
81
83
  }
82
84
  return objectsToIR([...objects, ...access], warnings);
@@ -25,4 +25,24 @@ export declare function readTypeKinds(client: PostgresClient, scope: SchemaScope
25
25
  export declare function readCollations(client: PostgresClient, scope: SchemaScope): Promise<LivePgObject[]>;
26
26
  /** Aggregates, casts and event triggers: read after the functions they call. */
27
27
  export declare function readRoutineKinds(client: PostgresClient, scope: SchemaScope): Promise<LivePgObject[]>;
28
+ /**
29
+ * Operators: the ones a schema defines, not the server's own (oids below the
30
+ * first normal object id) or an extension's. Identified by name and operand
31
+ * types, `NONE` for a missing side (`DROP OPERATOR`'s spelling).
32
+ */
33
+ export declare function readOperators(client: PostgresClient, scope: SchemaScope): Promise<LivePgObject[]>;
34
+ /**
35
+ * The kinds of object #3911 adds that belong to the database or hang off a
36
+ * table: extended statistics (printed by the server), foreign data wrappers
37
+ * and servers, and publications, each assembled from its catalog rows. A
38
+ * wrapper, server or publication is the database's, so the schema scope does
39
+ * not narrow it. A credential in an option is left out and said so.
40
+ */
41
+ export declare function readDatabaseKinds(client: PostgresClient, scope: SchemaScope): Promise<LivePgObject[]>;
42
+ /**
43
+ * A dictionary's `dictinitoption`, which the server prints as
44
+ * `name = 'value', ...` (a quote and a backslash doubled in the value), as a
45
+ * list of name and value; undefined when the text is not that form.
46
+ */
47
+ export declare function parseDictionaryOptions(init: string | undefined): Array<[string, string]> | undefined;
28
48
  //# sourceMappingURL=catalog-kinds.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"catalog-kinds.d.ts","sourceRoot":"","sources":["../../../src/postgres/live/catalog-kinds.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAC/C,OAAO,EAA+B,KAAK,YAAY,EAAE,KAAK,WAAW,EAAE,MAAM,WAAW,CAAC;AA0C7F,4GAA4G;AAC5G,wBAAsB,aAAa,CAAC,MAAM,EAAE,cAAc,EAAE,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CA0EvG;AAED,kFAAkF;AAClF,wBAAsB,cAAc,CAAC,MAAM,EAAE,cAAc,EAAE,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAuCxG;AAID,gFAAgF;AAChF,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,cAAc,EAAE,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CA8H1G"}
1
+ {"version":3,"file":"catalog-kinds.d.ts","sourceRoot":"","sources":["../../../src/postgres/live/catalog-kinds.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAC/C,OAAO,EAA+B,KAAK,YAAY,EAAE,KAAK,WAAW,EAAE,MAAM,WAAW,CAAC;AA2C7F,4GAA4G;AAC5G,wBAAsB,aAAa,CAAC,MAAM,EAAE,cAAc,EAAE,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CA0EvG;AAED,kFAAkF;AAClF,wBAAsB,cAAc,CAAC,MAAM,EAAE,cAAc,EAAE,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAuCxG;AAID,gFAAgF;AAChF,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,cAAc,EAAE,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CA8H1G;AAMD;;;;GAIG;AACH,wBAAsB,aAAa,CAAC,MAAM,EAAE,cAAc,EAAE,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAwCvG;AAkBD;;;;;;GAMG;AACH,wBAAsB,iBAAiB,CAAC,MAAM,EAAE,cAAc,EAAE,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CA2E3G;AA0KD;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,KAAK,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,GAAG,SAAS,CAcpG"}