@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
@@ -201,7 +201,7 @@ function diffUnparsed(key, before, after, out, hints) {
201
201
  }
202
202
  }
203
203
  /** The kinds (#3911) whose definition has no ALTER: a change is a drop and a create, or (an aggregate's) CREATE OR REPLACE. */
204
- const REPLACED_KINDS = new Set(["composite", "range", "aggregate", "collation", "cast", "eventTrigger"]);
204
+ const REPLACED_KINDS = new Set(["composite", "range", "aggregate", "collation", "cast", "eventTrigger", "operator", "operatorClass", "operatorFamily", "statistics"]);
205
205
  /** What each of {@link REPLACED_KINDS} compares besides its name and comment. */
206
206
  const DEFINITION = {
207
207
  composite: ["attributeDefs"],
@@ -210,7 +210,142 @@ const DEFINITION = {
210
210
  collation: ["provider", "lcCollate", "lcCtype", "locale", "nondeterministic", "rules"],
211
211
  cast: ["castMethod", "function", "context"],
212
212
  eventTrigger: ["event", "tags", "function"],
213
+ operator: ["definition"],
214
+ // A class's members, type, family and default flag have no ALTER; a family has no definition besides its name and method (its identity).
215
+ operatorClass: ["default", "dataType", "family", "items"],
216
+ operatorFamily: [],
217
+ statistics: ["table", "kinds", "targets"],
213
218
  };
219
+ /** The kinds (#3911) the server alters in place, with the fields that cannot be altered (the object is dropped and created) and those that can. */
220
+ const ALTERED_KINDS = {
221
+ foreignDataWrapper: { recreate: [], inPlace: ["handler", "validator", "options"] },
222
+ foreignServer: { recreate: ["serverType", "wrapper"], inPlace: ["version", "options"] },
223
+ publication: { recreate: ["allTables"], inPlace: ["tables", "schemas", "publish", "viaRoot", "generatedColumns"] },
224
+ // ALTER TEXT SEARCH DICTIONARY sets options and cannot change the template; ALTER TEXT SEARCH CONFIGURATION maps token types and cannot change the parser (SQLPG305).
225
+ textSearchDictionary: { recreate: ["template"], inPlace: ["options"], rule: "SQLPG305" },
226
+ textSearchConfiguration: { recreate: ["parser"], inPlace: ["mappings"], rule: "SQLPG305" },
227
+ };
228
+ /**
229
+ * A foreign data wrapper's, foreign server's or publication's change: the
230
+ * comment and each field ALTER reaches in place (SQLPG303); a field it does
231
+ * not reach (a server's type and wrapper, a publication's FOR ALL TABLES) by
232
+ * dropping and creating the object (SQLPG300), refused while something
233
+ * depends on it (SQLPG301).
234
+ */
235
+ function diffAltered(key, before, after, out) {
236
+ if (!same(before.fields.comment, after.fields.comment))
237
+ out.push(change(key, "comment", "SQLPG216", show(before.fields.comment), show(after.fields.comment)));
238
+ const { recreate, inPlace, rule = "SQLPG303" } = ALTERED_KINDS[after.kind];
239
+ const replaced = recreate.filter((k) => !same(before.fields[k], after.fields[k]));
240
+ // An object that lives in a schema is another object under another name: a rename between builds is a drop and a create.
241
+ if (after.schema !== undefined && (before.schema !== after.schema || before.name !== after.name))
242
+ replaced.unshift("name");
243
+ if (replaced.length > 0) {
244
+ const value = (o, k) => (k === "name" ? qualified(o) : (show(o.fields[k]) ?? "-"));
245
+ const was = replaced.map((k) => `${k} ${value(before, k)}`).join("; ");
246
+ const now = replaced.map((k) => `${k} ${value(after, k)}`).join("; ");
247
+ if (before.dependents && before.dependents.length > 0) {
248
+ out.push(change(key, replaced.join(", "), "SQLPG301", was, now, { note: `${before.dependents.join(", ")} depend${before.dependents.length === 1 ? "s" : ""} on it` }));
249
+ }
250
+ else
251
+ out.push(change(key, replaced.join(", "), "SQLPG300", was, now));
252
+ return;
253
+ }
254
+ for (const k of inPlace)
255
+ if (!same(before.fields[k], after.fields[k]))
256
+ out.push(change(key, k, rule, show(before.fields[k]), show(after.fields[k])));
257
+ }
258
+ /**
259
+ * Which of an operator's attributes `ALTER OPERATOR ... SET` can change from
260
+ * what the server holds (the Postgres 18 page, with the supported majors):
261
+ * RESTRICT and JOIN on every major, set or removed; from 17 COMMUTATOR and
262
+ * NEGATOR when the operator has none, and HASHES and MERGES when off, never
263
+ * back. Anything else about the definition is dropped and created.
264
+ */
265
+ function operatorAlterable(key, before, after, major) {
266
+ if (key === "restrict" || key === "join")
267
+ return true;
268
+ if (major < 17)
269
+ return false;
270
+ if (key === "commutator" || key === "negator")
271
+ return before[key] === undefined && after[key] !== undefined;
272
+ if (key === "hashes" || key === "merges")
273
+ return before[key] === undefined && after[key] === "true";
274
+ return false;
275
+ }
276
+ /** An operator's change: in place (SQLPG304) when every attribute that changed is one ALTER OPERATOR reaches, else dropped and created like the other kinds without an ALTER. */
277
+ function diffOperator(key, before, after, out, major) {
278
+ const bo = (before.fields.definition ?? {});
279
+ const ao = (after.fields.definition ?? {});
280
+ const renamed = before.schema !== after.schema || before.name !== after.name || before.signature !== after.signature;
281
+ // In the order the page lists them, so the statement reads the same whatever the order the options were written in.
282
+ const ORDER = ["restrict", "join", "commutator", "negator", "hashes", "merges"];
283
+ const rank = (k) => (ORDER.includes(k) ? ORDER.indexOf(k) : ORDER.length);
284
+ const changed = [...new Set([...Object.keys(bo), ...Object.keys(ao)])].filter((k) => !same(bo[k], ao[k])).sort((a, b) => rank(a) - rank(b) || (a < b ? -1 : 1));
285
+ if (renamed || !changed.every((k) => operatorAlterable(k, bo, ao, major))) {
286
+ diffReplaced(key, before, after, out);
287
+ return;
288
+ }
289
+ if (!same(before.fields.comment, after.fields.comment))
290
+ out.push(change(key, "comment", "SQLPG216", show(before.fields.comment), show(after.fields.comment)));
291
+ const note = major < 17 ? undefined : "from 17 ALTER OPERATOR also sets a commutator's or negator's own commutator or negator";
292
+ for (const k of changed)
293
+ out.push(change(key, `definition.${k}`, "SQLPG304", show(bo[k]), show(ao[k]), note && (k === "commutator" || k === "negator") ? { note } : {}));
294
+ }
295
+ /**
296
+ * A foreign table's columns, as ALTER FOREIGN TABLE changes them (SQLPG306):
297
+ * all catalog changes, none reading the remote side. A column is its name
298
+ * (a rename is a drop and an add); its comment is the generic comment rule.
299
+ */
300
+ function diffForeignColumns(key, before, after, out) {
301
+ const byName = new Map(before.columns.map((c) => [c.name, c]));
302
+ const afterNames = new Set(after.columns.map((c) => c.name));
303
+ for (const b of before.columns)
304
+ if (!afterNames.has(b.name))
305
+ out.push(change(key, `columns.${b.name}`, "SQLPG306", `${b.name} ${b.type ?? ""}`.trim(), undefined));
306
+ for (const a of after.columns) {
307
+ const b = byName.get(a.name);
308
+ if (!b) {
309
+ out.push(change(key, `columns.${a.name}`, "SQLPG306", undefined, `${a.name} ${a.type ?? ""}`.trim()));
310
+ continue;
311
+ }
312
+ const at = `columns.${a.name}`;
313
+ if (b.type !== a.type)
314
+ out.push(change(key, `${at}.type`, "SQLPG306", b.type, a.type));
315
+ if (b.collate !== a.collate)
316
+ out.push(change(key, `${at}.collate`, "SQLPG306", b.collate, a.collate));
317
+ if (b.default !== a.default)
318
+ out.push(change(key, `${at}.default`, "SQLPG306", b.default, a.default));
319
+ if (b.notNull !== a.notNull)
320
+ out.push(change(key, `${at}.notNull`, "SQLPG306", b.notNull ? "NOT NULL" : "NULL", a.notNull ? "NOT NULL" : "NULL"));
321
+ if (!same(b.options, a.options))
322
+ out.push(change(key, `${at}.options`, "SQLPG306", show(b.options), show(a.options)));
323
+ if (b.comment !== a.comment)
324
+ out.push(change(key, `${at}.comment`, "SQLPG216", b.comment, a.comment));
325
+ }
326
+ }
327
+ /** A foreign table's CHECK constraints: a dropped one first, so a constraint replaced under its name is dropped before it is added. */
328
+ function diffForeignConstraints(key, before, after, out) {
329
+ const label = (c) => (c.name ? `${c.name}: ${c.body}` : c.body);
330
+ const remaining = [...before.constraints];
331
+ const added = [];
332
+ const comments = [];
333
+ for (const a of after.constraints) {
334
+ const i = remaining.findIndex((b) => sameConstraint(a, b));
335
+ if (i < 0) {
336
+ added.push(a);
337
+ continue;
338
+ }
339
+ const b = remaining.splice(i, 1)[0];
340
+ if (b.comment !== a.comment)
341
+ comments.push(change(key, `constraints.${a.name ?? b.name}.comment`, "SQLPG216", b.comment, a.comment));
342
+ }
343
+ for (const b of remaining)
344
+ out.push(change(key, `constraints.${b.name ?? b.kind.toLowerCase()}`, "SQLPG306", label(b), undefined));
345
+ for (const a of added)
346
+ out.push(change(key, `constraints.${a.name ?? a.kind.toLowerCase()}`, "SQLPG306", undefined, label(a)));
347
+ out.push(...comments);
348
+ }
214
349
  /**
215
350
  * A type's, aggregate's, collation's, cast's or event trigger's change: its
216
351
  * comment in place; its definition by CREATE OR REPLACE AGGREGATE where that
@@ -251,6 +386,15 @@ function diffObject(key, before, after, out, hints, major) {
251
386
  if (!same(b, a))
252
387
  out.push(change(key, name, rule, show(b), show(a), extra));
253
388
  };
389
+ if (after.kind === "operator") {
390
+ diffOperator(key, before, after, out, major);
391
+ return;
392
+ }
393
+ // A foreign table moved to another server is another table: ALTER FOREIGN TABLE has no SERVER action.
394
+ if (after.kind === "foreignTable" && before.schema === after.schema && before.name === after.name && !same(before.fields.server, after.fields.server)) {
395
+ out.push(change(key, "server", before.dependents && before.dependents.length > 0 ? "SQLPG301" : "SQLPG300", show(before.fields.server), show(after.fields.server), before.dependents && before.dependents.length > 0 ? { note: `${before.dependents.join(", ")} depend${before.dependents.length === 1 ? "s" : ""} on it` } : {}));
396
+ return;
397
+ }
254
398
  if (REPLACED_KINDS.has(after.kind)) {
255
399
  // A cast is named by its types, and an aggregate's argument types are its identity: either changed, between two builds, is another object.
256
400
  if (after.kind === "cast" && before.name !== after.name) {
@@ -260,6 +404,10 @@ function diffObject(key, before, after, out, hints, major) {
260
404
  diffReplaced(key, before, after, out);
261
405
  return;
262
406
  }
407
+ if (after.kind in ALTERED_KINDS) {
408
+ diffAltered(key, before, after, out);
409
+ return;
410
+ }
263
411
  if (before.schema !== after.schema || before.name !== after.name) {
264
412
  out.push(change(key, "name", after.kind === "index" ? "SQLPG229" : "SQLPG228", qualified(before), qualified(after)));
265
413
  }
@@ -387,6 +535,11 @@ function diffObject(key, before, after, out, hints, major) {
387
535
  field("attributes", "SQLPG294");
388
536
  field("connectionLimit", "SQLPG294");
389
537
  break;
538
+ case "foreignTable":
539
+ diffForeignColumns(key, before, after, out);
540
+ diffForeignConstraints(key, before, after, out);
541
+ field("options", "SQLPG306");
542
+ break;
390
543
  case "table":
391
544
  if (!same(before.fields.rowSecurity, after.fields.rowSecurity) || !same(before.fields.forceRowSecurity, after.fields.forceRowSecurity)) {
392
545
  const state = (o) => (o.fields.rowSecurity ? (o.fields.forceRowSecurity ? "enabled, forced" : "enabled") : o.fields.forceRowSecurity ? "disabled, forced" : "disabled");
@@ -42,7 +42,7 @@
42
42
  * plan or a deep read has one (`./server-normalize.ts`). Offline, between two
43
43
  * builds, only the rules apply.
44
44
  */
45
- import type { AggregateProps, CastProps, RoutineProps } from "../entities.js";
45
+ import type { OperatorProps, AggregateProps, CastProps, RoutineProps } from "../entities.js";
46
46
  /** The integer type a serial spelling stands for, or undefined for any other type. */
47
47
  export declare const serialBase: (type: string | undefined) => string | undefined;
48
48
  /** A qualified name in canonical form: each piece unquoted where it can be, the default schema added to a bare one. */
@@ -73,6 +73,8 @@ export interface CanonicalColumn {
73
73
  collate?: string;
74
74
  compression?: string;
75
75
  storage?: string;
76
+ /** A foreign table column's `OPTIONS`, sorted by name. */
77
+ options?: Record<string, string>;
76
78
  comment?: string;
77
79
  }
78
80
  export interface CanonicalConstraint {
@@ -85,7 +87,7 @@ export interface CanonicalConstraint {
85
87
  notValid?: boolean;
86
88
  comment?: string;
87
89
  }
88
- export type CanonicalKind = "schema" | "table" | "index" | "view" | "materializedView" | "sequence" | "enum" | "composite" | "range" | "domain" | "extension" | "aggregate" | "collation" | "cast" | "eventTrigger" | "function" | "procedure" | "trigger" | "policy" | "role" | "grant" | "defaultPrivileges";
90
+ export type CanonicalKind = "schema" | "table" | "index" | "view" | "materializedView" | "sequence" | "enum" | "composite" | "range" | "domain" | "extension" | "aggregate" | "collation" | "cast" | "eventTrigger" | "operator" | "operatorClass" | "operatorFamily" | "foreignTable" | "textSearchConfiguration" | "textSearchDictionary" | "statistics" | "foreignDataWrapper" | "foreignServer" | "publication" | "function" | "procedure" | "trigger" | "policy" | "role" | "grant" | "defaultPrivileges";
89
91
  /** The kinds whose declarations are privileges, compared as the access they add up to (`../access/`), not one by one. */
90
92
  export declare const ACCESS_KINDS: ReadonlySet<CanonicalKind>;
91
93
  /** The kinds a profile manages only when it says so (`sql.profiles.<env>.access`). */
@@ -135,6 +137,30 @@ export declare const canonicalCollation: (text: string) => string;
135
137
  export declare function defaultMultirangeName(range: string): string;
136
138
  /** An aggregate's identity among its overloads: `(integer)`, `(*)`, `(text ORDER BY integer)`. */
137
139
  export declare function aggregateSignature(p: Pick<AggregateProps, "args" | "orderBy">, defaultSchema: string): string;
140
+ /** An operator's identity among its overloads: its operand types, `(integer,integer)`, `NONE` for a missing side. */
141
+ export declare function operatorSignature(p: Pick<OperatorProps, "leftArg" | "rightArg">, defaultSchema: string): string;
142
+ /**
143
+ * An operator named where another object names it (a COMMUTATOR or NEGATOR):
144
+ * `OPERATOR(app.===)`, `app.===` or a bare symbol, which the server looks for
145
+ * in the new operator's own schema, as `schema.symbol`.
146
+ */
147
+ export declare function canonicalOperatorRef(text: string, ownSchema: string): string;
148
+ /**
149
+ * A name where an object is named (a text search parser, template or
150
+ * dictionary, an operator family): the schema left off when it is
151
+ * `pg_catalog` or the default schema, since a bare name is looked for in both.
152
+ * The catalog prints every schema, so both sides are brought to this form.
153
+ */
154
+ export declare function canonicalRef(text: string, defaultSchema: string): string;
155
+ /** An operator named in an operator class: `OPERATOR(app.<<)`, `app.<<` or a bare symbol, by `canonicalRef`'s rule for the schema. */
156
+ export declare function canonicalOperatorName(text: string, defaultSchema: string): string;
157
+ /**
158
+ * The kinds of statistics gathered, sorted. Left out, the server builds all
159
+ * three, except for a lone expression, which gets none of them (only the
160
+ * expression's own statistics); `pg_get_statisticsobjdef` prints the list only
161
+ * when it is not that default.
162
+ */
163
+ export declare function statisticsKinds(kinds: readonly string[] | undefined, targets: readonly string[]): string[] | undefined;
138
164
  /** A cast's name, `(source AS target)`, its types canonical. */
139
165
  export declare const castName: (p: Pick<CastProps, "sourceType" | "targetType">, defaultSchema: string) => string;
140
166
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"normalize.d.ts","sourceRoot":"","sources":["../../../src/postgres/plan/normalize.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"normalize.d.ts","sourceRoot":"","sources":["../../../src/postgres/plan/normalize.ts"],"names":[],"mappings":"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"}
@@ -303,6 +303,16 @@ const kindOf = {
303
303
  "Postgres::Collation": "collation",
304
304
  "Postgres::Cast": "cast",
305
305
  "Postgres::EventTrigger": "eventTrigger",
306
+ "Postgres::Operator": "operator",
307
+ "Postgres::OperatorClass": "operatorClass",
308
+ "Postgres::OperatorFamily": "operatorFamily",
309
+ "Postgres::ForeignTable": "foreignTable",
310
+ "Postgres::TextSearchConfiguration": "textSearchConfiguration",
311
+ "Postgres::TextSearchDictionary": "textSearchDictionary",
312
+ "Postgres::Statistics": "statistics",
313
+ "Postgres::ForeignDataWrapper": "foreignDataWrapper",
314
+ "Postgres::ForeignServer": "foreignServer",
315
+ "Postgres::Publication": "publication",
306
316
  "Postgres::Extension": "extension",
307
317
  "Postgres::Function": "function",
308
318
  "Postgres::Procedure": "procedure",
@@ -524,7 +534,7 @@ function triggerFields(p, defaultSchema, fields) {
524
534
  }
525
535
  // ── Types, aggregates, collations, casts, event triggers (#3911) ──────
526
536
  /** The kinds that live in no schema. */
527
- const UNPLACED = new Set(["schema", "extension", "role", "cast", "eventTrigger"]);
537
+ const UNPLACED = new Set(["schema", "extension", "role", "cast", "eventTrigger", "foreignDataWrapper", "foreignServer", "publication"]);
528
538
  /**
529
539
  * A function named where an object calls it (an aggregate's SFUNC, a cast's
530
540
  * or an event trigger's function), as the catalog's `regproc` prints it with
@@ -616,6 +626,183 @@ function collationFields(p, fields) {
616
626
  fields.nondeterministic = p.options.deterministic !== undefined && !isTrue(p.options.deterministic);
617
627
  fields.rules = o.rules;
618
628
  }
629
+ /** An operator's identity among its overloads: its operand types, `(integer,integer)`, `NONE` for a missing side. */
630
+ export function operatorSignature(p, defaultSchema) {
631
+ const side = (t) => (t === undefined ? "NONE" : canonicalArgType(t, defaultSchema));
632
+ return `(${side(p.leftArg)},${side(p.rightArg)})`;
633
+ }
634
+ /**
635
+ * An operator named where another object names it (a COMMUTATOR or NEGATOR):
636
+ * `OPERATOR(app.===)`, `app.===` or a bare symbol, which the server looks for
637
+ * in the new operator's own schema, as `schema.symbol`.
638
+ */
639
+ export function canonicalOperatorRef(text, ownSchema) {
640
+ const inner = text.trim().replace(/^OPERATOR\s*\(\s*(.*?)\s*\)$/is, "$1");
641
+ const m = /^("(?:[^"]|"")+"|[A-Za-z_][A-Za-z0-9_$]*)\s*\.\s*(\S.*)$/s.exec(inner);
642
+ return `${quoteIdent(m ? identValue(m[1]) : ownSchema)}.${(m ? m[2] : inner).trim()}`;
643
+ }
644
+ /** An operator's definition as compared: each function and operator named canonically, a flag only when set. */
645
+ function operatorOptions(p, ownSchema, defaultSchema) {
646
+ const out = {};
647
+ for (const [k, v] of Object.entries(p.options)) {
648
+ if (k === "function" || k === "restrict" || k === "join")
649
+ out[k] = canonicalFunctionName(v, defaultSchema);
650
+ else if (k === "commutator" || k === "negator")
651
+ out[k] = canonicalOperatorRef(v, ownSchema);
652
+ else if (k === "hashes" || k === "merges") {
653
+ if (isTrue(v))
654
+ out[k] = "true";
655
+ }
656
+ else
657
+ out[k] = defValue(v);
658
+ }
659
+ return Object.fromEntries(Object.entries(out).sort(([a], [b]) => (a < b ? -1 : 1)));
660
+ }
661
+ /**
662
+ * A name where an object is named (a text search parser, template or
663
+ * dictionary, an operator family): the schema left off when it is
664
+ * `pg_catalog` or the default schema, since a bare name is looked for in both.
665
+ * The catalog prints every schema, so both sides are brought to this form.
666
+ */
667
+ export function canonicalRef(text, defaultSchema) {
668
+ const pieces = canonicalName(text).split(/\.(?=(?:[^"]*"[^"]*")*[^"]*$)/);
669
+ if (pieces.length >= 2) {
670
+ const schema = identValue(pieces[0]);
671
+ return schema === "pg_catalog" || schema === defaultSchema ? pieces.slice(1).join(".") : pieces.join(".");
672
+ }
673
+ return pieces[0];
674
+ }
675
+ /** An operator named in an operator class: `OPERATOR(app.<<)`, `app.<<` or a bare symbol, by `canonicalRef`'s rule for the schema. */
676
+ export function canonicalOperatorName(text, defaultSchema) {
677
+ const inner = text.trim().replace(/^OPERATOR\s*\(\s*(.*?)\s*\)$/is, "$1").trim();
678
+ const m = /^("(?:[^"]|"")+"|[A-Za-z_][A-Za-z0-9_$]*)\s*\.\s*(\S.*)$/s.exec(inner);
679
+ if (!m)
680
+ return inner;
681
+ const schema = identValue(m[1]);
682
+ return schema === "pg_catalog" || schema === defaultSchema ? m[2].trim() : `${quoteIdent(schema)}.${m[2].trim()}`;
683
+ }
684
+ /** A comma list split at its top level: `numeric(12,2), text` is two items. */
685
+ function splitTopLevel(text) {
686
+ const out = [];
687
+ let depth = 0;
688
+ let current = "";
689
+ for (const ch of text) {
690
+ if (ch === "(" || ch === "[")
691
+ depth++;
692
+ else if (ch === ")" || ch === "]")
693
+ depth--;
694
+ if (ch === "," && depth === 0) {
695
+ out.push(current.trim());
696
+ current = "";
697
+ }
698
+ else
699
+ current += ch;
700
+ }
701
+ if (current.trim() !== "")
702
+ out.push(current.trim());
703
+ return out;
704
+ }
705
+ /**
706
+ * The operand types a support function of an operator class is registered
707
+ * for when `FUNCTION n (left, right)` does not say (sql-createopclass): a
708
+ * B-tree comparison function's (1) and a hash function's (1, 2) are the
709
+ * function's own input types, a B-tree `in_range` function's (3) its first
710
+ * and third, and every other support function's the class's type. The catalog
711
+ * always stores both, so a declaration is brought to them.
712
+ */
713
+ function supportTypes(method, number, classType, args) {
714
+ if (method === "btree" && number === 1)
715
+ return [args[0] ?? classType, args[1] ?? args[0] ?? classType];
716
+ if (method === "btree" && number === 3)
717
+ return [args[0] ?? classType, args[2] ?? classType];
718
+ if (method === "hash" && (number === 1 || number === 2))
719
+ return [args[0] ?? classType, args[0] ?? classType];
720
+ return [classType, classType];
721
+ }
722
+ /** An operator class as compared: its type, family, default flag and members, each member canonical and the list sorted. */
723
+ function operatorClassFields(p, schema, defaultSchema, fields) {
724
+ const type = canonicalType(p.dataType, defaultSchema);
725
+ fields.default = p.default === true;
726
+ fields.dataType = type;
727
+ // A class with no FAMILY is in a family of its own name; so is one that names that family.
728
+ const own = canonicalRef(`${quoteIdent(schema)}.${quoteIdent(p.name)}`, defaultSchema);
729
+ const named = p.family === undefined ? own : /^\s*("(?:[^"]|"")+"|[A-Za-z_][A-Za-z0-9_$]*)\s*$/.test(p.family) && identValue(p.family.trim()) === p.name ? own : canonicalRef(p.family, defaultSchema);
730
+ fields.family = named === own ? undefined : named;
731
+ const side = (t) => (t.trim().toUpperCase() === "NONE" ? "NONE" : canonicalArgType(t, defaultSchema));
732
+ const members = p.items.map((i) => {
733
+ if (i.kind === "storage")
734
+ return { rank: 2, number: 0, text: `storage ${canonicalType(i.type, defaultSchema)}` };
735
+ const n = Number(i.number);
736
+ if (i.kind === "operator") {
737
+ const [l, r] = i.types !== undefined ? splitTopLevel(i.types) : [type, type];
738
+ const sorted = i.orderBy !== undefined ? ` for order by ${canonicalRef(i.orderBy, defaultSchema)}` : "";
739
+ return { rank: 0, number: n, text: `operator ${n} ${canonicalOperatorName(i.operator, defaultSchema)} (${side(l ?? type)},${side(r ?? l ?? type)})${sorted}` };
740
+ }
741
+ const args = splitTopLevel(i.args).map((a) => canonicalArgType(a, defaultSchema));
742
+ const given = i.types !== undefined ? splitTopLevel(i.types).map(side) : undefined;
743
+ const [l, r] = given ? [given[0], given[1] ?? given[0]] : supportTypes(p.method, n, type, args);
744
+ return { rank: 1, number: n, text: `function ${n} (${l},${r}) ${canonicalFunctionName(i.function, defaultSchema)}(${args.join(",")})` };
745
+ });
746
+ members.sort((a, b) => a.rank - b.rank || a.number - b.number || (a.text < b.text ? -1 : 1));
747
+ fields.items = members.map((m) => m.text);
748
+ }
749
+ /** A dictionary option's value as compared: a string constant's value, a quoted name's, a bare word folded, a number as written. */
750
+ function dictionaryValue(v) {
751
+ const t = v.trim();
752
+ if (/^([Ee]?'|\$)/.test(t))
753
+ return stringValue(t) ?? t;
754
+ if (/^"/.test(t))
755
+ return identValue(t);
756
+ return t.toLowerCase();
757
+ }
758
+ /** A text search configuration's mappings as compared: each token type to its dictionaries in order, sorted by token type. */
759
+ function mappingFields(p, defaultSchema) {
760
+ const out = {};
761
+ for (const m of p.mappings)
762
+ for (const t of m.tokens)
763
+ out[t.toLowerCase()] = m.dictionaries.map((d) => canonicalRef(d, defaultSchema));
764
+ const entries = Object.entries(out).sort(([a], [b]) => (a < b ? -1 : 1));
765
+ return entries.length > 0 ? Object.fromEntries(entries) : undefined;
766
+ }
767
+ /** An `OPTIONS (...)` list as compared: by name, none as nothing. */
768
+ function sortedOptions(options) {
769
+ const entries = Object.entries(options ?? {}).sort(([a], [b]) => (a < b ? -1 : 1));
770
+ return entries.length > 0 ? Object.fromEntries(entries) : undefined;
771
+ }
772
+ const STATISTICS_ALL = ["dependencies", "mcv", "ndistinct"];
773
+ /**
774
+ * The kinds of statistics gathered, sorted. Left out, the server builds all
775
+ * three, except for a lone expression, which gets none of them (only the
776
+ * expression's own statistics); `pg_get_statisticsobjdef` prints the list only
777
+ * when it is not that default.
778
+ */
779
+ export function statisticsKinds(kinds, targets) {
780
+ if (kinds && kinds.length > 0) {
781
+ const sorted = [...new Set(kinds.map((k) => k.toLowerCase()))].sort();
782
+ return sorted.join() === STATISTICS_ALL.join() ? undefined : sorted;
783
+ }
784
+ const lone = targets.length === 1 && !/^"?[A-Za-z_][A-Za-z0-9_$]*"?$/.test(targets[0].trim());
785
+ return lone ? ["none"] : undefined;
786
+ }
787
+ /** Every action a publication publishes when `publish` is not given. */
788
+ const PUBLISH_ALL = ["delete", "insert", "truncate", "update"];
789
+ /** A publication as compared: its tables with their column lists and row filters, its schemas, and each option at its default left out. */
790
+ function publicationFields(p, defaultSchema, fields) {
791
+ fields.allTables = p.allTables === true;
792
+ const tables = p.tables.map((t) => ({
793
+ table: canonicalName(t.tableName, defaultSchema),
794
+ ...(t.columns && t.columns.length > 0 ? { columns: [...t.columns].sort() } : {}),
795
+ ...(t.where ? { where: canonicalExpr(t.where) } : {}),
796
+ }));
797
+ fields.tables = tables.length > 0 ? tables.sort((a, b) => (a.table < b.table ? -1 : 1)) : undefined;
798
+ fields.schemas = p.schemas.length > 0 ? p.schemas.map((s) => quoteIdent(identValue(s))).sort() : undefined;
799
+ const o = p.options;
800
+ const publish = o.publish === undefined ? PUBLISH_ALL : [...new Set(defValue(o.publish).split(",").map((x) => x.trim().toLowerCase()).filter(Boolean))].sort();
801
+ fields.publish = publish.join() === PUBLISH_ALL.join() ? undefined : publish;
802
+ fields.viaRoot = isTrue(o.publish_via_partition_root);
803
+ const generated = o.publish_generated_columns === undefined ? "none" : defValue(o.publish_generated_columns);
804
+ fields.generatedColumns = generated === "none" ? undefined : generated;
805
+ }
619
806
  /** A cast's name, `(source AS target)`, its types canonical. */
620
807
  export const castName = (p, defaultSchema) => `(${canonicalType(p.sourceType, defaultSchema)} AS ${canonicalType(p.targetType, defaultSchema)})`;
621
808
  /**
@@ -688,6 +875,78 @@ export function canonicalPgObject(entityType, props, defaultSchema = "public") {
688
875
  fields.function = canonicalFunctionName(p.functionName, defaultSchema);
689
876
  break;
690
877
  }
878
+ case "operator": {
879
+ const p = props;
880
+ base.signature = operatorSignature(p, defaultSchema);
881
+ fields.definition = operatorOptions(p, base.schema, defaultSchema);
882
+ break;
883
+ }
884
+ case "operatorClass":
885
+ operatorClassFields(props, base.schema, defaultSchema, fields);
886
+ base.signature = ` USING ${props.method}`;
887
+ break;
888
+ case "operatorFamily":
889
+ base.signature = ` USING ${props.method}`;
890
+ break;
891
+ case "textSearchDictionary": {
892
+ const p = props;
893
+ fields.template = canonicalRef(p.template, defaultSchema);
894
+ fields.options = sortedOptions(Object.fromEntries(Object.entries(p.options).map(([k, v]) => [k.toLowerCase(), dictionaryValue(v)])));
895
+ break;
896
+ }
897
+ case "textSearchConfiguration": {
898
+ const p = props;
899
+ fields.parser = canonicalRef(p.parser, defaultSchema);
900
+ fields.mappings = mappingFields(p, defaultSchema);
901
+ break;
902
+ }
903
+ case "foreignTable": {
904
+ const p = props;
905
+ p.columns.forEach((c, position) => {
906
+ const options = sortedOptions(c.options);
907
+ columns.push({
908
+ name: c.name,
909
+ position,
910
+ type: canonicalType(c.type, defaultSchema),
911
+ notNull: c.notNull === true,
912
+ default: canonicalExpr(c.default),
913
+ collate: c.collate ? canonicalName(c.collate) : undefined,
914
+ comment: comment(c.comment),
915
+ ...(options ? { options } : {}),
916
+ });
917
+ });
918
+ for (const c of p.checks)
919
+ constraints.push({ kind: "CHECK", name: c.name, body: ["check", canonicalExpr(c.expr), c.noInherit ? "no inherit" : ""].filter(Boolean).join(" "), ...(c.notValid ? { notValid: true } : {}), comment: comment(c.comment) });
920
+ fields.server = quoteIdent(p.serverName);
921
+ fields.options = sortedOptions(p.options);
922
+ break;
923
+ }
924
+ case "statistics": {
925
+ const p = props;
926
+ fields.table = canonicalName(p.tableName, defaultSchema);
927
+ const targets = p.targets.map((t) => canonicalExpr(t)).sort();
928
+ fields.targets = targets;
929
+ fields.kinds = statisticsKinds(p.kinds, p.targets);
930
+ break;
931
+ }
932
+ case "foreignDataWrapper": {
933
+ const p = props;
934
+ fields.handler = p.handlerName && !p.noHandler ? canonicalFunctionName(p.handlerName, defaultSchema) : undefined;
935
+ fields.validator = p.validatorName && !p.noValidator ? canonicalFunctionName(p.validatorName, defaultSchema) : undefined;
936
+ fields.options = sortedOptions(p.options);
937
+ break;
938
+ }
939
+ case "foreignServer": {
940
+ const p = props;
941
+ fields.serverType = p.serverType;
942
+ fields.version = p.version;
943
+ fields.wrapper = quoteIdent(identValue(p.wrapperName));
944
+ fields.options = sortedOptions(p.options);
945
+ break;
946
+ }
947
+ case "publication":
948
+ publicationFields(props, defaultSchema, fields);
949
+ break;
691
950
  case "function":
692
951
  case "procedure": {
693
952
  const p = props;
@@ -96,6 +96,10 @@ export declare const PG_CLASSIFIER_RULES: {
96
96
  readonly SQLPG300: PgClassifierRule;
97
97
  readonly SQLPG301: PgClassifierRule;
98
98
  readonly SQLPG302: PgClassifierRule;
99
+ readonly SQLPG303: PgClassifierRule;
100
+ readonly SQLPG304: PgClassifierRule;
101
+ readonly SQLPG305: PgClassifierRule;
102
+ readonly SQLPG306: PgClassifierRule;
99
103
  readonly SQLPG270: PgClassifierRule;
100
104
  };
101
105
  export type PgClassifierRuleId = keyof typeof PG_CLASSIFIER_RULES;
@@ -1 +1 @@
1
- {"version":3,"file":"rules.d.ts","sourceRoot":"","sources":["../../../src/postgres/plan/rules.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,OAAO,EAAkB,KAAK,aAAa,EAAE,KAAK,cAAc,IAAI,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAErH,MAAM,MAAM,aAAa,GAAG,UAAU,GAAG,UAAU,GAAG,cAAc,GAAG,SAAS,GAAG,QAAQ,GAAG,QAAQ,GAAG,MAAM,CAAC;AAEhH,MAAM,MAAM,gBAAgB,GAAG,iBAAiB,CAAC,aAAa,CAAC,CAAC;AAEhE,eAAO,MAAM,iBAAiB,EAAE,aAAa,CAAC,aAAa,CAY1D,CAAC;AASF,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAqUqB,CAAC;AAEtD,MAAM,MAAM,kBAAkB,GAAG,MAAM,OAAO,mBAAmB,CAAC"}
1
+ {"version":3,"file":"rules.d.ts","sourceRoot":"","sources":["../../../src/postgres/plan/rules.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,OAAO,EAAkB,KAAK,aAAa,EAAE,KAAK,cAAc,IAAI,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAErH,MAAM,MAAM,aAAa,GAAG,UAAU,GAAG,UAAU,GAAG,cAAc,GAAG,SAAS,GAAG,QAAQ,GAAG,QAAQ,GAAG,MAAM,CAAC;AAEhH,MAAM,MAAM,gBAAgB,GAAG,iBAAiB,CAAC,aAAa,CAAC,CAAC;AAEhE,eAAO,MAAM,iBAAiB,EAAE,aAAa,CAAC,aAAa,CAY1D,CAAC;AASF,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAiWqB,CAAC;AAEtD,MAAM,MAAM,kBAAkB,GAAG,MAAM,OAAO,mBAAmB,CAAC"}
@@ -108,8 +108,12 @@ export const PG_CLASSIFIER_RULES = {
108
108
  SQLPG297: rule("SQLPG297", "metadata", "Revoke a privilege", "REVOKE removes from the object's privileges in the catalog. The role loses it at once: its next statement that needs it fails, so move every reader off it first.", `${DOCS}/sql-revoke.html`),
109
109
  SQLPG298: rule("SQLPG298", "metadata", "Change default privileges", "ALTER DEFAULT PRIVILEGES changes what objects created afterwards are given; objects that exist keep their privileges.", `${DOCS}/sql-alterdefaultprivileges.html`),
110
110
  SQLPG299: rule("SQLPG299", "expand", "Change a clause chant does not read", "chant's parser does not know this clause, so it cannot tell which lock the change takes or whether an in-place statement makes it; the plan refuses it rather than guess. Review it: make it by hand with the ALTER the server documents for the clause, or as expand and contract.", `${DOCS}/sql-altertable.html`),
111
- SQLPG300: rule("SQLPG300", "metadata", "Drop and create a type, aggregate, collation, cast or event trigger", "A composite or range type's definition, a collation's, a cast's and an event trigger's have no ALTER, and an aggregate's argument types, state type and final function cannot be replaced: the object is dropped and created in one transaction. Nothing on the server depends on it (a column, a view, a function or a cast would make the DROP fail); the locks are on its catalog rows only.", `${DOCS}/sql-createtype.html`),
112
- SQLPG301: rule("SQLPG301", "expand", "Change a type, aggregate, collation or cast that other objects depend on", "No ALTER makes the change, and DROP refuses while a column, a view, a function or another object depends on the object. Create the new definition under another name, move what depends on it, then drop the old.", `${DOCS}/sql-droptype.html`),
111
+ SQLPG300: rule("SQLPG300", "metadata", "Drop and create a type, aggregate, collation, cast, event trigger, operator, operator class or family, foreign table's server, text search object, statistics object, foreign server or publication", "A composite or range type's definition, a collation's, a cast's, an event trigger's, an operator's function and operands, and any attribute of it that SQLPG304 does not alter, an operator class's members, type, family and default flag, an operator family's index method, and extended statistics' have no ALTER (ALTER OPERATOR CLASS and ALTER OPERATOR FAMILY change a name, an owner or a schema only), an aggregate's argument types, state type and final function cannot be replaced, and neither can a foreign server's type or wrapper, a foreign table's server, a text search configuration's parser, a text search dictionary's template or a publication's FOR ALL TABLES: the object is dropped and created in one transaction. Nothing on the server depends on it (a column, a view, an index, a function or a cast would make the DROP fail); the locks are on its catalog rows only. Dropped statistics are empty until the next ANALYZE, and a publication that is dropped stops its subscribers until it is created again.", `${DOCS}/sql-createtype.html`),
112
+ SQLPG301: rule("SQLPG301", "expand", "Change a type, aggregate, collation, cast, operator, operator class, text search object, foreign table's server, foreign server or publication that other objects depend on", "No ALTER makes the change, and DROP refuses while a column, a view, an index, a function or another object depends on the object. Create the new definition under another name, move what depends on it, then drop the old.", `${DOCS}/sql-droptype.html`),
113
113
  SQLPG302: rule("SQLPG302", "metadata", "Replace an aggregate's definition", "CREATE OR REPLACE AGGREGATE (14 and later) replaces the aggregate's functions and options in the catalog; no table is locked. Its argument types, its result and its kind (plain, ordered-set, hypothetical-set) have to stay the same, so a change of the state type or the final function is dropped and created instead (SQLPG300).", `${DOCS}/sql-createaggregate.html`),
114
+ SQLPG303: rule("SQLPG303", "metadata", "Alter a foreign data wrapper, foreign server or publication in place", "ALTER FOREIGN DATA WRAPPER (handler, validator, options), ALTER SERVER (version, options) and ALTER PUBLICATION (SET options, ADD and DROP TABLE and TABLES IN SCHEMA) change the object's catalog rows under a brief lock; no table is rewritten. A publication's change reaches its subscribers as the walsender next reads it: a table added is not copied to a subscription until the subscriber runs REFRESH PUBLICATION.", `${DOCS}/sql-alterpublication.html`),
115
+ SQLPG304: rule("SQLPG304", "metadata", "Alter an operator in place", "ALTER OPERATOR ... SET changes the operator's catalog row under a brief lock; no index or table is read. RESTRICT and JOIN can be set or removed (NONE) on every supported major. From 17, COMMUTATOR and NEGATOR can be set when the operator has none, and HASHES and MERGES turned on, never off (the Postgres 18 page: \"Can only be changed if the operator does not have an existing commutator\", \"Can only be enabled and not disabled\"); setting a commutator or negator also sets the other operator's. On 14 to 16 only RESTRICT and JOIN are alterable, so any other change drops and creates the operator (SQLPG300), as does a change of function or operands on any major.", `${DOCS}/sql-alteroperator.html`),
116
+ SQLPG305: rule("SQLPG305", "metadata", "Alter a text search configuration's mappings or a dictionary's options in place", "ALTER TEXT SEARCH CONFIGURATION ADD MAPPING, ALTER MAPPING and DROP MAPPING change the token types mapped to dictionaries; ALTER TEXT SEARCH DICTIONARY sets a template's options, and an option named with no value is removed. Both change catalog rows under a brief lock and leave the parser or template as it is, so a parser or template change is dropped and created (SQLPG300). A tsvector already stored keeps the tokens it was built with: rebuild the columns and indexes that hold one when the mappings or options change what a word becomes. The same applies on 14 to 18.", `${DOCS}/sql-altertsconfig.html`),
117
+ SQLPG306: rule("SQLPG306", "metadata", "Alter a foreign table in place", "ALTER FOREIGN TABLE adds and drops columns, changes a column's type, default, NOT NULL and OPTIONS, adds and drops CHECK and NOT NULL constraints, and sets the table's OPTIONS, all in the catalog. Nothing is checked against the remote side and no row is rewritten or scanned (\"It is the user's responsibility to ensure that the table definition matches the remote side\"), so a CHECK is added with no validation pass. A foreign table's server cannot be altered, so a change of server is dropped and created (SQLPG300).", `${DOCS}/sql-alterforeigntable.html`),
114
118
  SQLPG270: rule("SQLPG270", "drop", "Drop an object", "The object and, for a table, a materialized view or a sequence, its data are gone.", `${DOCS}/sql-droptable.html`),
115
119
  };
@@ -73,7 +73,7 @@ export function pgSchemaFromBuildFile(path, defaultSchema = "public") {
73
73
  export function pgNamespace(kind) {
74
74
  if (kind === "schema" || kind === "extension" || kind === "trigger" || kind === "policy" || kind === "role")
75
75
  return kind;
76
- if (kind === "collation" || kind === "cast" || kind === "eventTrigger")
76
+ if (kind === "collation" || kind === "cast" || kind === "eventTrigger" || kind === "operator" || kind === "operatorClass" || kind === "operatorFamily" || kind === "textSearchConfiguration" || kind === "textSearchDictionary" || kind === "statistics" || kind === "foreignDataWrapper" || kind === "foreignServer" || kind === "publication")
77
77
  return kind;
78
78
  if (kind === "grant" || kind === "defaultPrivileges")
79
79
  return "grant";
@@ -0,0 +1,26 @@
1
+ /**
2
+ * The Postgres statement classifier (#4407): a migration file's statements,
3
+ * each given the class and rule the schema-diff classifier (`./rules.ts`)
4
+ * gives the same change, with the lock the rule's restriction names. It reads
5
+ * text and contacts no server.
6
+ *
7
+ * `CREATE`, `GRANT`, `REVOKE`, `COMMENT ON` and `ALTER TABLE ... ROW LEVEL
8
+ * SECURITY` go through the declaration parser (`../parser.ts`). The parser
9
+ * has no `ALTER` grammar, so the other `ALTER` and `DROP` statements are read
10
+ * word by word from the same tokens.
11
+ *
12
+ * A statement alone cannot decide some changes. `ALTER COLUMN ... TYPE` is a
13
+ * catalog change or a table rewrite by the column's old type, which the file
14
+ * does not state: it is `undecided`, naming SQLPG206 and SQLPG207 (and
15
+ * SQLPG208 with a `USING` expression). `CREATE OR REPLACE VIEW` is SQLPG250
16
+ * or SQLPG251 by whether the columns stay. A statement no rule covers is
17
+ * `unclassified` with a note.
18
+ */
19
+ import { type StatementVerdict } from "../../core/statement-class.js";
20
+ /**
21
+ * Classify a migration's up statements, in order. The statements are the
22
+ * file's own text, one per entry (a Flyway file after placeholder
23
+ * substitution).
24
+ */
25
+ export declare function classifyPgStatements(statements: readonly string[]): StatementVerdict[];
26
+ //# sourceMappingURL=statements.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"statements.d.ts","sourceRoot":"","sources":["../../../src/postgres/plan/statements.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAIH,OAAO,EAA0E,KAAK,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAuP3I;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,GAAG,gBAAgB,EAAE,CAyBtF"}