@quereus/quereus 4.20.0 → 4.20.2

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 (400) hide show
  1. package/README.md +2 -0
  2. package/dist/src/common/types.d.ts +4 -4
  3. package/dist/src/index.d.ts +1 -1
  4. package/dist/src/index.d.ts.map +1 -1
  5. package/dist/src/index.js +3 -2
  6. package/dist/src/index.js.map +1 -1
  7. package/dist/src/schema/catalog-rendering.js +13 -1
  8. package/dist/src/schema/catalog-rendering.js.map +1 -1
  9. package/dist/src/schema/catalog.d.ts +35 -2
  10. package/dist/src/schema/catalog.d.ts.map +1 -1
  11. package/dist/src/schema/catalog.js +42 -33
  12. package/dist/src/schema/catalog.js.map +1 -1
  13. package/dist/src/schema/schema-differ.d.ts +1 -1
  14. package/dist/src/schema/schema-differ.d.ts.map +1 -1
  15. package/dist/src/schema/schema-differ.js +195 -33
  16. package/dist/src/schema/schema-differ.js.map +1 -1
  17. package/dist/src/schema/unique-enforcement.d.ts +23 -1
  18. package/dist/src/schema/unique-enforcement.d.ts.map +1 -1
  19. package/dist/src/schema/unique-enforcement.js +43 -1
  20. package/dist/src/schema/unique-enforcement.js.map +1 -1
  21. package/dist/src/vtab/memory/layer/manager.d.ts +15 -12
  22. package/dist/src/vtab/memory/layer/manager.d.ts.map +1 -1
  23. package/dist/src/vtab/memory/layer/manager.js +87 -100
  24. package/dist/src/vtab/memory/layer/manager.js.map +1 -1
  25. package/package.json +7 -4
  26. package/test/README.md +173 -0
  27. package/test/logic/01-basic.sqllogic +39 -0
  28. package/test/logic/01.1-select-projection-extras.sqllogic +130 -0
  29. package/test/logic/01.2-strings.sqllogic +43 -0
  30. package/test/logic/01.5-insert-select.sqllogic +237 -0
  31. package/test/logic/01.6-update-extras.sqllogic +118 -0
  32. package/test/logic/01.7-update-from.sqllogic +67 -0
  33. package/test/logic/01.8-delete-extras.sqllogic +122 -0
  34. package/test/logic/01.8.1-delete-range-cow.sqllogic +115 -0
  35. package/test/logic/01.9-query-expr-dml-gates.sqllogic +32 -0
  36. package/test/logic/01.9-query-expr-dml.sqllogic +171 -0
  37. package/test/logic/01.9-query-expr-values.sqllogic +111 -0
  38. package/test/logic/01.9.1-limit-over-dml-subquery.sqllogic +119 -0
  39. package/test/logic/02-filters.sqllogic +54 -0
  40. package/test/logic/02-smoke.sqllogic +62 -0
  41. package/test/logic/02.1-bind-parameters.sqllogic +223 -0
  42. package/test/logic/03-expressions.sqllogic +190 -0
  43. package/test/logic/03.1-quoted-identifiers.sqllogic +55 -0
  44. package/test/logic/03.4-defaults.sqllogic +554 -0
  45. package/test/logic/03.4.1-default-edge-cases.sqllogic +99 -0
  46. package/test/logic/03.5-tvf.sqllogic +61 -0
  47. package/test/logic/03.6-type-system.sqllogic +544 -0
  48. package/test/logic/03.6.1-numeric-text-comparison-coercion.sqllogic +244 -0
  49. package/test/logic/03.6.2-value-to-text.sqllogic +224 -0
  50. package/test/logic/03.7-bigint-mixed-arithmetic.sqllogic +65 -0
  51. package/test/logic/03.8-not-precedence.sqllogic +255 -0
  52. package/test/logic/03.9-is-bool-predicate.sqllogic +150 -0
  53. package/test/logic/03.9.1-is-bool-predicate-partial-index.sqllogic +34 -0
  54. package/test/logic/04-order-by.sqllogic +38 -0
  55. package/test/logic/04-transactions.sqllogic +239 -0
  56. package/test/logic/04a-savepoint-lazy-attach.sqllogic +122 -0
  57. package/test/logic/05-vtab_memory.sqllogic +50 -0
  58. package/test/logic/05.0.1-vtab-memory-unique-index-collation.sqllogic +34 -0
  59. package/test/logic/05.1-composite-pk-range-scan.sqllogic +147 -0
  60. package/test/logic/05.1.1-secondary-index-range-scan.sqllogic +56 -0
  61. package/test/logic/05.2-cast-seek-correctness.sqllogic +124 -0
  62. package/test/logic/06-builtin_functions.sqllogic +149 -0
  63. package/test/logic/06.1-string-functions.sqllogic +92 -0
  64. package/test/logic/06.1.3-like-glob-edges.sqllogic +53 -0
  65. package/test/logic/06.2-math-functions.sqllogic +82 -0
  66. package/test/logic/06.3-schema.sqllogic +48 -0
  67. package/test/logic/06.3.1-schema-all-schemas.sqllogic +39 -0
  68. package/test/logic/06.3.2-schema-foreign-keys.sqllogic +208 -0
  69. package/test/logic/06.3.3-introspection-tags.sqllogic +202 -0
  70. package/test/logic/06.3.3.1-introspection-tags-index.sqllogic +74 -0
  71. package/test/logic/06.3.4-view-info.sqllogic +378 -0
  72. package/test/logic/06.3.5-column-info.sqllogic +347 -0
  73. package/test/logic/06.3.6-schema-views.sqllogic +29 -0
  74. package/test/logic/06.4-schema-search-path.sqllogic +354 -0
  75. package/test/logic/06.4.1-schema-case-insensitive.sqllogic +83 -0
  76. package/test/logic/06.4.2-collation-extras.sqllogic +472 -0
  77. package/test/logic/06.4.2.1-collation-index-access-paths.sqllogic +140 -0
  78. package/test/logic/06.4.3-write-path-collation.sqllogic +99 -0
  79. package/test/logic/06.4.4-comparison-collation-precedence.sqllogic +342 -0
  80. package/test/logic/06.4.5-any-collate-declared-keys.sqllogic +92 -0
  81. package/test/logic/06.5-polymorphic-types.sqllogic +169 -0
  82. package/test/logic/06.5.1-conversion-functions.sqllogic +173 -0
  83. package/test/logic/06.5.2-scalar-minmax.sqllogic +16 -0
  84. package/test/logic/06.5.3-undeclared-return-type-comparison.sqllogic +244 -0
  85. package/test/logic/06.5.4-declared-return-type-builtins.sqllogic +288 -0
  86. package/test/logic/06.6-aggregate-extended.sqllogic +78 -0
  87. package/test/logic/06.7-json-extended.sqllogic +53 -0
  88. package/test/logic/06.8-json-path-operators.sqllogic +99 -0
  89. package/test/logic/06.9-json-canonical-key.sqllogic +65 -0
  90. package/test/logic/06.9.1-json-coerce-once.sqllogic +417 -0
  91. package/test/logic/06.9.1.1-json-coerce-once-index.sqllogic +39 -0
  92. package/test/logic/06.9.2-json-structural-equality.sqllogic +382 -0
  93. package/test/logic/06.9.2.1-json-structural-equality-index.sqllogic +76 -0
  94. package/test/logic/06.9.3-json-index-range-seek.sqllogic +205 -0
  95. package/test/logic/07-aggregates.sqllogic +193 -0
  96. package/test/logic/07.1-aggregate-filter-clause.sqllogic +12 -0
  97. package/test/logic/07.2-aggregate-order-by.sqllogic +11 -0
  98. package/test/logic/07.3-group-by-extras.sqllogic +602 -0
  99. package/test/logic/07.3.1-group-by-order-by-key.sqllogic +164 -0
  100. package/test/logic/07.3.2-grouped-select-list-shape.sqllogic +231 -0
  101. package/test/logic/07.4-group-by-filter-composite-pk.sqllogic +120 -0
  102. package/test/logic/07.5-sum-mixed-exact-and-float.sqllogic +151 -0
  103. package/test/logic/07.5-window.sqllogic +1941 -0
  104. package/test/logic/07.5.1-window-named.sqllogic +13 -0
  105. package/test/logic/07.5.2-window-nth-value.sqllogic +13 -0
  106. package/test/logic/07.6-subqueries.sqllogic +78 -0
  107. package/test/logic/07.6.1-subquery-extras.sqllogic +93 -0
  108. package/test/logic/07.7-and-or-short-circuit.sqllogic +58 -0
  109. package/test/logic/07.7-in-subquery-caching.sqllogic +174 -0
  110. package/test/logic/07.7-scalar-agg-decorrelation.sqllogic +197 -0
  111. package/test/logic/07.7.1-in-extras.sqllogic +158 -0
  112. package/test/logic/07.7.1-scalar-agg-decorrelation-filter.sqllogic +105 -0
  113. package/test/logic/07.7.2-scalar-agg-decorrelation-nested.sqllogic +115 -0
  114. package/test/logic/07.7.3-exists-in-select-decorrelation.sqllogic +107 -0
  115. package/test/logic/07.7.4-where-conjunct-ordering.sqllogic +121 -0
  116. package/test/logic/07.7.5-filter-lost-under-index-order.sqllogic +134 -0
  117. package/test/logic/07.7.6-correlated-predicate-scope.sqllogic +178 -0
  118. package/test/logic/07.7.7-join-source-scope-shadowing.sqllogic +137 -0
  119. package/test/logic/07.7.8-correlated-ref-to-computed-column.sqllogic +165 -0
  120. package/test/logic/07.7.9-conjunct-monotonicity.sqllogic +200 -0
  121. package/test/logic/07.8-correlated-subquery-edges.sqllogic +71 -0
  122. package/test/logic/07.8.1-correlated-in-decorrelation-gates.sqllogic +156 -0
  123. package/test/logic/07.9-in-value-list.sqllogic +154 -0
  124. package/test/logic/07.9.1-in-value-list-composite-index.sqllogic +38 -0
  125. package/test/logic/08-views.sqllogic +64 -0
  126. package/test/logic/08.1-semi-anti-join.sqllogic +191 -0
  127. package/test/logic/08.1-view-edge-cases.sqllogic +118 -0
  128. package/test/logic/08.1.1-uncorrelated-in-semijoin.sqllogic +251 -0
  129. package/test/logic/08.2-existence-flag-semijoin-recovery.sqllogic +197 -0
  130. package/test/logic/08.3-existence-flag-inner-recovery.sqllogic +102 -0
  131. package/test/logic/08.4-key-set-semi-join.sqllogic +447 -0
  132. package/test/logic/09-set_operations.sqllogic +244 -0
  133. package/test/logic/09.1-set-op-cross-collation.sqllogic +230 -0
  134. package/test/logic/10-distinct_datatypes.sqllogic +127 -0
  135. package/test/logic/10.1-ddl-lifecycle.sqllogic +203 -0
  136. package/test/logic/10.1.1-create-table-syntax-edges.sqllogic +47 -0
  137. package/test/logic/10.1.2-ddl-in-transaction.sqllogic +143 -0
  138. package/test/logic/10.1.2.1-add-constraint-in-transaction.sqllogic +59 -0
  139. package/test/logic/10.1.3-ddl-drop-in-transaction.sqllogic +187 -0
  140. package/test/logic/10.1.3.1-drop-constraint-in-transaction.sqllogic +45 -0
  141. package/test/logic/10.1.4-create-table-duplicate-constraint-names.sqllogic +149 -0
  142. package/test/logic/10.1.4-ddl-transaction-policy.sqllogic +314 -0
  143. package/test/logic/10.1.5-alter-add-constraint-minted-name-disambiguation.sqllogic +219 -0
  144. package/test/logic/10.1.5-create-index-lifecycle.sqllogic +72 -0
  145. package/test/logic/10.1.6-ddl-transaction-policy-index.sqllogic +143 -0
  146. package/test/logic/10.1.7-create-table-default-type-check.sqllogic +119 -0
  147. package/test/logic/10.1.8-alter-add-check-existing-rows.sqllogic +117 -0
  148. package/test/logic/10.2-column-features.sqllogic +365 -0
  149. package/test/logic/10.2.1-table-options-rejection.sqllogic +63 -0
  150. package/test/logic/10.2.2-default-collation-memory.sqllogic +30 -0
  151. package/test/logic/10.3-function-features.sqllogic +247 -0
  152. package/test/logic/10.4-schema-scale.sqllogic +168 -0
  153. package/test/logic/10.4.1-schema-scale-indexes.sqllogic +121 -0
  154. package/test/logic/10.5-indexes.sqllogic +164 -0
  155. package/test/logic/10.5.1-partial-indexes.sqllogic +526 -0
  156. package/test/logic/10.5.2-expression-indexes.sqllogic +34 -0
  157. package/test/logic/10.5.3-desc-index-ordering.sqllogic +130 -0
  158. package/test/logic/10.5.4-composite-pk-index-update-phantom.sqllogic +55 -0
  159. package/test/logic/10.5.5-index-name-uniqueness.sqllogic +76 -0
  160. package/test/logic/10.5.6-minmax-index-boundary.sqllogic +204 -0
  161. package/test/logic/10.5.7-implicit-unique-index-lifecycle.sqllogic +1216 -0
  162. package/test/logic/10.6-distinct-edge-cases.sqllogic +119 -0
  163. package/test/logic/100-predicate-normalization-edge-cases.sqllogic +238 -0
  164. package/test/logic/100.1-where-extras.sqllogic +163 -0
  165. package/test/logic/100.1.1-where-join-on-order-indexed.sqllogic +35 -0
  166. package/test/logic/101-builtin-mutation-kills.sqllogic +974 -0
  167. package/test/logic/101-transaction-edge-cases.sqllogic +395 -0
  168. package/test/logic/102-schema-catalog-edge-cases.sqllogic +252 -0
  169. package/test/logic/102-unique-constraints.sqllogic +145 -0
  170. package/test/logic/102.0.1-schema-catalog-indexed-table.sqllogic +32 -0
  171. package/test/logic/102.1-unique-edge-cases.sqllogic +111 -0
  172. package/test/logic/102.1.1-unique-index-creation-edge-cases.sqllogic +75 -0
  173. package/test/logic/102.2-unique-collation.sqllogic +181 -0
  174. package/test/logic/102.2.1-unique-collation-index-derived.sqllogic +305 -0
  175. package/test/logic/103-database-options-edge-cases.sqllogic +108 -0
  176. package/test/logic/103.1-pragma-boolean-values.sqllogic +126 -0
  177. package/test/logic/104-emit-mutation-kills.sqllogic +236 -0
  178. package/test/logic/105-vtab-memory-mutation-kills.sqllogic +754 -0
  179. package/test/logic/105.1-vtab-memory-index-mutation-kills.sqllogic +540 -0
  180. package/test/logic/106-constraint-extractor-mutation-kills.sqllogic +350 -0
  181. package/test/logic/107-temporal-arithmetic-mutation-kills.sqllogic +833 -0
  182. package/test/logic/108-cardinality-estimation.sqllogic +146 -0
  183. package/test/logic/108.1-analyze-name-resolution.sqllogic +102 -0
  184. package/test/logic/109-aggregate-physical-selection.sqllogic +103 -0
  185. package/test/logic/11-joins.sqllogic +86 -0
  186. package/test/logic/11.1-join-using.sqllogic +267 -0
  187. package/test/logic/11.2-comma-join.sqllogic +35 -0
  188. package/test/logic/11.3-index-nested-loop-join.sqllogic +305 -0
  189. package/test/logic/11.3-mismatched-collation-join.sqllogic +74 -0
  190. package/test/logic/11.4-hash-join-side-swap.sqllogic +118 -0
  191. package/test/logic/110-scan-emitter-mutation-kills.sqllogic +121 -0
  192. package/test/logic/110.1-scan-emitter-index-scan-kills.sqllogic +47 -0
  193. package/test/logic/12-empty-primary-key.sqllogic +124 -0
  194. package/test/logic/12-join_padding_order.sqllogic +58 -0
  195. package/test/logic/12.1-orderby-index-consumption.sqllogic +40 -0
  196. package/test/logic/13-cte.sqllogic +137 -0
  197. package/test/logic/13.1-cte-multiple-recursive.sqllogic +104 -0
  198. package/test/logic/13.10-cte-qualified-name.sqllogic +136 -0
  199. package/test/logic/13.11-unreferenced-dml-cte.sqllogic +414 -0
  200. package/test/logic/13.12-nested-dml-cte-rejected.sqllogic +280 -0
  201. package/test/logic/13.2-cte-bind-params.sqllogic +98 -0
  202. package/test/logic/13.3-cte-edge-cases.sqllogic +120 -0
  203. package/test/logic/13.4-cte-extras.sqllogic +98 -0
  204. package/test/logic/13.5-cte-join-order.sqllogic +166 -0
  205. package/test/logic/13.6-cte-dml-runs-once.sqllogic +318 -0
  206. package/test/logic/13.7-cte-sibling-visibility.sqllogic +227 -0
  207. package/test/logic/13.8-insert-with-clause-visibility.sqllogic +254 -0
  208. package/test/logic/13.9-schema-authored-cte-isolation.sqllogic +328 -0
  209. package/test/logic/13.9.1-schema-authored-schema-path-isolation.sqllogic +408 -0
  210. package/test/logic/14-utilities.sqllogic +168 -0
  211. package/test/logic/15-timespan.sqllogic +279 -0
  212. package/test/logic/15.1-semantic-ordering.sqllogic +960 -0
  213. package/test/logic/15.1.1-json-check-coercion.sqllogic +178 -0
  214. package/test/logic/15.1.2-semantic-ordering-index.sqllogic +41 -0
  215. package/test/logic/15.1.3-declared-form-write-contract.sqllogic +519 -0
  216. package/test/logic/16-epoch.sqllogic +187 -0
  217. package/test/logic/17-weekday-modifier.sqllogic +78 -0
  218. package/test/logic/18-json-string-escapes.sqllogic +86 -0
  219. package/test/logic/18-strftime-extended-formats.sqllogic +68 -0
  220. package/test/logic/20-empty-single-row.sqllogic +261 -0
  221. package/test/logic/21-null-edge-cases.sqllogic +227 -0
  222. package/test/logic/21.1-where-null-comparisons.sqllogic +151 -0
  223. package/test/logic/21.1.1-where-null-comparisons-secondary-index.sqllogic +35 -0
  224. package/test/logic/21.2-between-edges.sqllogic +157 -0
  225. package/test/logic/22-boundary-values.sqllogic +175 -0
  226. package/test/logic/23-self-joins-duplicates.sqllogic +74 -0
  227. package/test/logic/24-builtin-branches.sqllogic +611 -0
  228. package/test/logic/24.1-substr-extras.sqllogic +75 -0
  229. package/test/logic/24.2-random-extras.sqllogic +39 -0
  230. package/test/logic/25-aggregate-edge-cases.sqllogic +289 -0
  231. package/test/logic/25.1-nested-aggregates.sqllogic +74 -0
  232. package/test/logic/25.2-having-edge-cases.sqllogic +318 -0
  233. package/test/logic/25.3-aggregate-isnull-empty.sqllogic +16 -0
  234. package/test/logic/25.4-groupby-fd-constant-empty.sqllogic +55 -0
  235. package/test/logic/25.5-ungrouped-aggregate-column-free-select-item.sqllogic +196 -0
  236. package/test/logic/26-join-edge-cases.sqllogic +333 -0
  237. package/test/logic/26.1-left-join-isnull-on-notnull.sqllogic +26 -0
  238. package/test/logic/26.2-left-join-on-vs-where.sqllogic +67 -0
  239. package/test/logic/26.3-join-on-constants.sqllogic +61 -0
  240. package/test/logic/26.4-join-on-is-null-nullable.sqllogic +44 -0
  241. package/test/logic/27-window-edge-cases.sqllogic +206 -0
  242. package/test/logic/27.1-window-groups-frame.sqllogic +13 -0
  243. package/test/logic/27.2-window-exclude.sqllogic +13 -0
  244. package/test/logic/27.3-window-json-aggregation.sqllogic +66 -0
  245. package/test/logic/28-set-ops-sort-edge-cases.sqllogic +444 -0
  246. package/test/logic/28.1-compound-limit-offset.sqllogic +143 -0
  247. package/test/logic/28.2-orderby-expression-extras.sqllogic +698 -0
  248. package/test/logic/28.2-set-op-branch-types.sqllogic +217 -0
  249. package/test/logic/29-constraint-edge-cases.sqllogic +442 -0
  250. package/test/logic/29.1-column-level-conflict-clause.sqllogic +171 -0
  251. package/test/logic/29.2-table-level-pk-conflict-clause.sqllogic +113 -0
  252. package/test/logic/40-constraints.sqllogic +418 -0
  253. package/test/logic/40.1-pk-desc-direction.sqllogic +76 -0
  254. package/test/logic/40.2-check-extras.sqllogic +683 -0
  255. package/test/logic/41-alter-table.sqllogic +191 -0
  256. package/test/logic/41-fk-cascade-conflict-and-self-ref.sqllogic +263 -0
  257. package/test/logic/41-fk-cross-schema.sqllogic +155 -0
  258. package/test/logic/41-fk-extended-targets.sqllogic +173 -0
  259. package/test/logic/41-foreign-keys.sqllogic +1001 -0
  260. package/test/logic/41-generated-column-errors.sqllogic +225 -0
  261. package/test/logic/41-generated-column-extras.sqllogic +598 -0
  262. package/test/logic/41-generated-column-scope.sqllogic +329 -0
  263. package/test/logic/41-generated-columns.sqllogic +361 -0
  264. package/test/logic/41.1-alter-pk.sqllogic +230 -0
  265. package/test/logic/41.1-fk-collation-conflict.sqllogic +277 -0
  266. package/test/logic/41.10-alter-drop-column-foreign-key.sqllogic +274 -0
  267. package/test/logic/41.10.1-alter-drop-column-unique-index.sqllogic +169 -0
  268. package/test/logic/41.10.2-alter-drop-column-check-and-assertion.sqllogic +1616 -0
  269. package/test/logic/41.10.3-alter-drop-column-referencing-fk.sqllogic +292 -0
  270. package/test/logic/41.10.4-drop-object-expression-dependents.sqllogic +602 -0
  271. package/test/logic/41.11-deferred-fk-with-rename.sqllogic +232 -0
  272. package/test/logic/41.12-alter-default-coercion.sqllogic +200 -0
  273. package/test/logic/41.13-alter-add-column-generated-backfill.sqllogic +566 -0
  274. package/test/logic/41.14-alter-add-column-subquery-backfill.sqllogic +129 -0
  275. package/test/logic/41.15-alter-column-default-type-check.sqllogic +178 -0
  276. package/test/logic/41.16-fk-unenforceable.sqllogic +364 -0
  277. package/test/logic/41.2-alter-column.sqllogic +382 -0
  278. package/test/logic/41.2.1-alter-column-retype-deleted-row-memory.sqllogic +32 -0
  279. package/test/logic/41.2.2-alter-column-retype-index-rebuild.sqllogic +77 -0
  280. package/test/logic/41.2.3-alter-column-set-not-null-pk-backfill.sqllogic +310 -0
  281. package/test/logic/41.2.3.1-alter-column-set-not-null-pk-backfill-secondary-index.sqllogic +37 -0
  282. package/test/logic/41.3-alter-add-column-unique.sqllogic +184 -0
  283. package/test/logic/41.3-alter-rename-propagation.sqllogic +2352 -0
  284. package/test/logic/41.3.1-alter-rename-index-propagation.sqllogic +94 -0
  285. package/test/logic/41.4-alter-add-column-constraints.sqllogic +855 -0
  286. package/test/logic/41.5-alter-misc.sqllogic +48 -0
  287. package/test/logic/41.5-cross-schema-foreign-keys.sqllogic +253 -0
  288. package/test/logic/41.6-alter-drop-rename-constraint.sqllogic +354 -0
  289. package/test/logic/41.6.1-alter-drop-constraint-index-derived.sqllogic +22 -0
  290. package/test/logic/41.7-alter-column-collate.sqllogic +105 -0
  291. package/test/logic/41.7.1-alter-column-collate-unique.sqllogic +45 -0
  292. package/test/logic/41.7.2-alter-column-collate-unique-store.sqllogic +208 -0
  293. package/test/logic/41.7.2.1-alter-column-collate-unique-index-store.sqllogic +114 -0
  294. package/test/logic/41.7.3-alter-column-retype-unique.sqllogic +293 -0
  295. package/test/logic/41.7.3.1-alter-column-retype-staged-rows-memory.sqllogic +41 -0
  296. package/test/logic/41.7.3.2-alter-column-retype-unique-index.sqllogic +72 -0
  297. package/test/logic/41.7.4-alter-column-retype-semantic-memory.sqllogic +445 -0
  298. package/test/logic/41.7.4.1-alter-column-retype-semantic-index-memory.sqllogic +91 -0
  299. package/test/logic/41.7.5-alter-column-collate-pk-staged-delete-memory.sqllogic +106 -0
  300. package/test/logic/41.8-alter-add-constraint-unique-fk.sqllogic +275 -0
  301. package/test/logic/41.8-alter-savepoint-staged-rows.sqllogic +443 -0
  302. package/test/logic/41.8.1-alter-rename-savepoint-staged-rows.sqllogic +408 -0
  303. package/test/logic/41.9-alter-constraint-body-change.sqllogic +180 -0
  304. package/test/logic/41.9-fk-restrict-batched.sqllogic +290 -0
  305. package/test/logic/42-committed-snapshot.sqllogic +254 -0
  306. package/test/logic/42-returning.sqllogic +159 -0
  307. package/test/logic/42.1-returning-extras.sqllogic +232 -0
  308. package/test/logic/42.2-returning-stored-row.sqllogic +165 -0
  309. package/test/logic/43-default-nullability.sqllogic +131 -0
  310. package/test/logic/43-transition-constraints.sqllogic +341 -0
  311. package/test/logic/43.1-default-collation.sqllogic +140 -0
  312. package/test/logic/43.1-notnull-or-conflict.sqllogic +79 -0
  313. package/test/logic/43.2-deferred-check-new-on-delete.sqllogic +95 -0
  314. package/test/logic/43.3-nullable-primary-key.sqllogic +587 -0
  315. package/test/logic/44-determinism-validation.sqllogic +164 -0
  316. package/test/logic/44-orthogonality.sqllogic +146 -0
  317. package/test/logic/44.1-nondeterministic-schema.sqllogic +316 -0
  318. package/test/logic/45-udf-determinism.sqllogic +39 -0
  319. package/test/logic/46-mutation-context.sqllogic +595 -0
  320. package/test/logic/47-upsert.sqllogic +255 -0
  321. package/test/logic/47.1-upsert-conflict-targets.sqllogic +169 -0
  322. package/test/logic/47.2-replace-and-or-clauses.sqllogic +164 -0
  323. package/test/logic/47.2.1-pk-replace-secondary-unique.sqllogic +374 -0
  324. package/test/logic/47.3-engine-or-fail.sqllogic +122 -0
  325. package/test/logic/47.3-upsert-conflict-target-collation.sqllogic +139 -0
  326. package/test/logic/47.3.1-upsert-conflict-index-derived-collation.sqllogic +25 -0
  327. package/test/logic/47.4-upsert-conflict-target-affinity.sqllogic +59 -0
  328. package/test/logic/47.5-upsert-do-update-constraints.sqllogic +440 -0
  329. package/test/logic/47.6-upsert-do-update-decomposed.sqllogic +100 -0
  330. package/test/logic/49-reference-graph.sqllogic +84 -0
  331. package/test/logic/50-declarative-schema.sqllogic +2550 -0
  332. package/test/logic/50-metadata-tags.sqllogic +1033 -0
  333. package/test/logic/50.0.1-metadata-tags-index.sqllogic +141 -0
  334. package/test/logic/50.1-declare-schema-pk.sqllogic +150 -0
  335. package/test/logic/50.2-declare-schema-renames.sqllogic +949 -0
  336. package/test/logic/50.2.1-declare-schema-index-renames.sqllogic +173 -0
  337. package/test/logic/50.3-declare-schema-duplicate-names.sqllogic +280 -0
  338. package/test/logic/50.4-declare-schema-apply-restore.sqllogic +192 -0
  339. package/test/logic/51-lens-foundation.sqllogic +147 -0
  340. package/test/logic/51-materialized-views.sqllogic +376 -0
  341. package/test/logic/51.5-materialized-views-coarsened-key.sqllogic +198 -0
  342. package/test/logic/51.7-maintained-table-attach-detach.sqllogic +468 -0
  343. package/test/logic/51.8-maintained-table-declared-constraints.sqllogic +440 -0
  344. package/test/logic/51.85-maintained-table-parent-fk.sqllogic +103 -0
  345. package/test/logic/51.9-maintained-table-secondary-unique.sqllogic +237 -0
  346. package/test/logic/51.9.1-maintained-table-partial-unique.sqllogic +36 -0
  347. package/test/logic/52-lens-overrides.sqllogic +566 -0
  348. package/test/logic/53-materialized-views-rowtime.sqllogic +1601 -0
  349. package/test/logic/53-reserved-tags.sqllogic +252 -0
  350. package/test/logic/53.1-materialized-view-write-through.sqllogic +329 -0
  351. package/test/logic/53.2-materialized-view-rename-propagation.sqllogic +483 -0
  352. package/test/logic/53.3-materialized-view-constraint-only-ddl.sqllogic +409 -0
  353. package/test/logic/53.3.1-materialized-view-index-ddl-irrelevance.sqllogic +29 -0
  354. package/test/logic/53.4-materialized-view-structural-alter-restore.sqllogic +436 -0
  355. package/test/logic/54-covering-mv-enforcement.sqllogic +314 -0
  356. package/test/logic/54.1-covering-mv-partial-enforcement.sqllogic +34 -0
  357. package/test/logic/55-internal-eviction-reporting.sqllogic +89 -0
  358. package/test/logic/55-lens-prover.sqllogic +202 -0
  359. package/test/logic/55.1-eviction-restrict-fk.sqllogic +148 -0
  360. package/test/logic/55.5-lens-authored-inverse.sqllogic +1468 -0
  361. package/test/logic/80-grow-retrieve-pass.sqllogic +79 -0
  362. package/test/logic/81-quickpick.sqllogic +24 -0
  363. package/test/logic/82-bloom-join.sqllogic +185 -0
  364. package/test/logic/83-merge-join.sqllogic +280 -0
  365. package/test/logic/84-asof-scan.sqllogic +238 -0
  366. package/test/logic/84-key-cardinality.sqllogic +50 -0
  367. package/test/logic/85-relational-const-folding.sqllogic +51 -0
  368. package/test/logic/86-scalar-cse.sqllogic +42 -0
  369. package/test/logic/90-error_paths.sqllogic +114 -0
  370. package/test/logic/90.1-parse-errors.sqllogic +77 -0
  371. package/test/logic/90.2-alter-table-errors.sqllogic +53 -0
  372. package/test/logic/90.2.1-alter-extra-errors.sqllogic +51 -0
  373. package/test/logic/90.3-expression-errors.sqllogic +43 -0
  374. package/test/logic/90.4-dml-errors.sqllogic +47 -0
  375. package/test/logic/90.5-unsupported-join-types.sqllogic +37 -0
  376. package/test/logic/90.5.1-right-full-join-read.sqllogic +157 -0
  377. package/test/logic/90.6-select-error-paths.sqllogic +57 -0
  378. package/test/logic/91-merge-join-edge-cases.sqllogic +159 -0
  379. package/test/logic/92-hash-aggregate-edge-cases.sqllogic +139 -0
  380. package/test/logic/93-ddl-view-edge-cases.sqllogic +104 -0
  381. package/test/logic/93.1-view-error-paths.sqllogic +74 -0
  382. package/test/logic/93.2-view-mutation-pending.sqllogic +108 -0
  383. package/test/logic/93.3-view-mutation-or-clause.sqllogic +60 -0
  384. package/test/logic/93.4-view-mutation.sqllogic +4881 -0
  385. package/test/logic/93.4.1-view-mutation-partial-unique-cardinality.sqllogic +31 -0
  386. package/test/logic/93.5-authored-inverse.sqllogic +415 -0
  387. package/test/logic/93.6-set-op-flagless-write.sqllogic +862 -0
  388. package/test/logic/94-tvf-edge-cases.sqllogic +58 -0
  389. package/test/logic/94.1-limit-offset-edge-cases.sqllogic +109 -0
  390. package/test/logic/94.2-limit-offset-extras.sqllogic +98 -0
  391. package/test/logic/95-assertions.sqllogic +1417 -0
  392. package/test/logic/96-subquery-edge-cases.sqllogic +276 -0
  393. package/test/logic/97-json-function-edge-cases.sqllogic +633 -0
  394. package/test/logic/97.1-json-blob-and-special-values.sqllogic +92 -0
  395. package/test/logic/98-temporal-edge-cases.sqllogic +515 -0
  396. package/test/logic/99-conversion-edge-cases.sqllogic +325 -0
  397. package/test/logic/99.0.1-schema-index-listing.sqllogic +21 -0
  398. package/test/logic/99.1-cast-syntax-extras.sqllogic +167 -0
  399. package/test/logic/drop-unique-index.sqllogic +88 -0
  400. package/test/logic/pushdown-test.sqllogic +36 -0
@@ -0,0 +1,198 @@
1
+ -- 51.5-materialized-views-coarsened-key.sqllogic — coarsened backing key: the
2
+ -- collation-weakening parallel-migration shape (docs/migration.md § Convergence
3
+ -- hazards). A body with no provable unique key whose source primary key survives
4
+ -- through value-preserving passthrough lineage (bare column / collate / no-op
5
+ -- cast) is keyed on the coarsened lineage key K' instead of rejected. The create
6
+ -- emits the key-coarsening warning (record stamp covered in
7
+ -- coarsened-backing-key.spec.ts); behavior contract pinned here:
8
+ -- * create-fill stays LOUD on colliding seed data ("must be a set");
9
+ -- * steady-state row-time maintenance merges colliding source rows
10
+ -- last-writer-wins (deterministic oscillation until the sources are merged);
11
+ -- * a delete of one colliding sibling deletes the shared derived row while the
12
+ -- sibling source row lives (the documented anomaly); the sibling's next edit
13
+ -- or a REFRESH re-asserts it;
14
+ -- * REFRESH during a collision window is loud (it is a re-fill — same posture
15
+ -- as create-fill).
16
+ --
17
+ -- Source text PKs are declared `collate binary` explicitly so the case-variant
18
+ -- fixtures key identically cross-module (the store host reconciles
19
+ -- implicit-collation text PKs to its table-level key collation, NOCASE by
20
+ -- default, which would reject the colliding source rows at the SOURCE insert).
21
+
22
+ -- ===================================
23
+ -- 1. The migration shape creates over clean data (was: bag rejection)
24
+ -- ===================================
25
+
26
+ create table contact_v1 (handle text collate binary primary key, email text);
27
+ insert into contact_v1 values ('Bob', 'bob@x.test'), ('Carol', 'carol@x.test');
28
+
29
+ create materialized view contact_v2 as select handle collate nocase as handle, email from contact_v1;
30
+
31
+ select handle, email from contact_v2 order by handle;
32
+ → [{"handle":"Bob","email":"bob@x.test"},{"handle":"Carol","email":"carol@x.test"}]
33
+
34
+ -- ===================================
35
+ -- 2. Colliding seed data still fails loudly at fill (the at-deploy rejection)
36
+ -- ===================================
37
+
38
+ create table dup_src (handle text collate binary primary key);
39
+ insert into dup_src values ('Bob'), ('bob');
40
+ create materialized view dup_v2 as select handle collate nocase as handle from dup_src;
41
+ -- error: must be a set
42
+
43
+ -- nothing half-registered: the name is free again
44
+ create table dup_v2 (x integer primary key);
45
+ drop table dup_v2;
46
+
47
+ -- ===================================
48
+ -- 3. Steady state: a colliding source insert LWW-merges into the shared derived
49
+ -- row, and each sibling edit re-asserts its own image (deterministic oscillation)
50
+ -- ===================================
51
+
52
+ insert into contact_v1 values ('CAROL', 'caps@x.test');
53
+ select count(*) as n from contact_v1;
54
+ → [{"n":3}]
55
+
56
+ -- the two case-variants share one NOCASE backing key — last writer won
57
+ select count(*) as n from contact_v2;
58
+ → [{"n":2}]
59
+ select handle, email from contact_v2 where handle = 'carol';
60
+ → [{"handle":"CAROL","email":"caps@x.test"}]
61
+
62
+ -- an edit of the other sibling re-asserts ITS image into the shared key
63
+ update contact_v1 set email = 'carol2@x.test' where handle = 'Carol';
64
+ select handle, email from contact_v2 where handle = 'carol';
65
+ → [{"handle":"Carol","email":"carol2@x.test"}]
66
+
67
+ -- REFRESH is a re-fill: during a collision window it is loud, like create-fill
68
+ refresh materialized view contact_v2;
69
+ -- error: must be a set
70
+
71
+ -- ===================================
72
+ -- 4. Delete-one-sibling anomaly: the shared derived row vanishes while the
73
+ -- sibling source row lives; REFRESH recovers it
74
+ -- ===================================
75
+
76
+ delete from contact_v1 where handle = 'CAROL';
77
+ select count(*) as n from contact_v1;
78
+ → [{"n":2}]
79
+ -- 'Carol' still lives in the source, but its derived row is gone (documented anomaly)
80
+ select count(*) as n from contact_v2;
81
+ → [{"n":1}]
82
+
83
+ refresh materialized view contact_v2;
84
+ select handle, email from contact_v2 order by handle;
85
+ → [{"handle":"Bob","email":"bob@x.test"},{"handle":"Carol","email":"carol2@x.test"}]
86
+
87
+ -- the surviving sibling's next edit also recovers, without a refresh
88
+ insert into contact_v1 values ('DAVE', 'dave@x.test');
89
+ insert into contact_v1 values ('dave', 'dave2@x.test');
90
+ select email from contact_v2 where handle = 'dave';
91
+ → [{"email":"dave2@x.test"}]
92
+ delete from contact_v1 where handle = 'dave';
93
+ select count(*) as n from contact_v2 where handle = 'dave';
94
+ → [{"n":0}]
95
+ update contact_v1 set email = 'dave3@x.test' where handle = 'DAVE';
96
+ select handle, email from contact_v2 where handle = 'dave';
97
+ → [{"handle":"DAVE","email":"dave3@x.test"}]
98
+
99
+ -- ===================================
100
+ -- 5. Multi-column passthrough body (cannot be grouped) — composite coarsened key
101
+ -- ===================================
102
+
103
+ create table mc (a text collate binary, b text collate binary, v integer, primary key (a, b));
104
+ insert into mc values ('X', '1', 10), ('Y', '1', 20);
105
+ create materialized view mc_v as select a collate nocase as a, b, v from mc;
106
+ select a, b, v from mc_v order by a, b;
107
+ → [{"a":"X","b":"1","v":10},{"a":"Y","b":"1","v":20}]
108
+
109
+ -- distinct b keeps case-variants apart…
110
+ insert into mc values ('x', '2', 30);
111
+ select count(*) as n from mc_v;
112
+ → [{"n":3}]
113
+
114
+ -- …while a same-b case-variant LWW-merges
115
+ insert into mc values ('y', '1', 40);
116
+ select count(*) as n from mc_v;
117
+ → [{"n":3}]
118
+ select v from mc_v where a = 'y' and b = '1';
119
+ → [{"v":40}]
120
+
121
+ -- ===================================
122
+ -- 6. A key-dropping projection still keeps the bag rejection
123
+ -- ===================================
124
+
125
+ create materialized view still_bag as select email from contact_v1;
126
+ -- error: no provable unique key
127
+
128
+ -- A collated GROUP BY key registers with a REAL (non-coarsened) key: the group
129
+ -- columns genuinely key the aggregate output, published under exactly their
130
+ -- grouping (NOCASE) collation (ticket collated-groupby-key-completeness — the
131
+ -- non-coarsened complement to this file's coarsened-lineage shape). Here
132
+ -- contact_v1 = {Bob, Carol, DAVE} with no NOCASE collisions, so three groups.
133
+ create materialized view grp_bag as select handle collate nocase as h, count(*) as n from contact_v1 group by handle collate nocase;
134
+ select h, n from grp_bag order by h;
135
+ → [{"h":"Bob","n":1},{"h":"Carol","n":1},{"h":"DAVE","n":1}]
136
+
137
+ -- ===================================
138
+ -- 7. Refining direction (BINARY output over a NOCASE-keyed source) is a true
139
+ -- unique key — accepted silently, byte-exact backing keys
140
+ -- ===================================
141
+
142
+ create table nck (h text collate nocase primary key, v integer);
143
+ insert into nck values ('Bob', 1);
144
+ create materialized view nck_v as select h collate binary as h, v from nck;
145
+ select h, v from nck_v;
146
+ → [{"h":"Bob","v":1}]
147
+
148
+ -- ===================================
149
+ -- 8. An ORDER BY coarsened body keeps the contract: the ordering seed is
150
+ -- suppressed so the backing keys on K' alone — colliding seed data stays
151
+ -- LOUD and a colliding insert still LWW-merges (with the seed, the widened
152
+ -- physical key would have admitted both siblings silently)
153
+ -- ===================================
154
+
155
+ create table ord_src (handle text collate binary primary key, email text);
156
+ insert into ord_src values ('Bob', 'b@x.test'), ('bob', 'b2@x.test');
157
+ create materialized view ord_v as select handle collate nocase as handle, email from ord_src order by email;
158
+ -- error: must be a set
159
+
160
+ delete from ord_src where handle = 'bob';
161
+ create materialized view ord_v as select handle collate nocase as handle, email from ord_src order by email;
162
+ insert into ord_src values ('BOB', 'b3@x.test');
163
+ select handle, email from ord_v;
164
+ → [{"handle":"BOB","email":"b3@x.test"}]
165
+
166
+ -- ===================================
167
+ -- 9. Explicit-collation backing key survives the store reconcile
168
+ -- (ticket join-key-collation-resolution-alignment): an MV column published with
169
+ -- an EXPLICIT collation now stamps `ColumnSchema.collationExplicit`, so the store
170
+ -- module keys the backing PK under the PUBLISHED collation instead of re-keying
171
+ -- every implicit text PK under its table-level default (NOCASE). A body whose key
172
+ -- column is explicit `collate binary` must therefore keep case-variant rows that
173
+ -- are DISTINCT under BINARY but would collide under the store default — proving
174
+ -- the published collation, not the store default, governs the backing key. (Under
175
+ -- the memory module the backing already keys on the column's collation field; this
176
+ -- case earns its keep under `yarn test:store`.)
177
+ -- ===================================
178
+
179
+ create table bin_src (handle text collate binary primary key, v integer);
180
+ insert into bin_src values ('Bob', 1), ('bob', 2);
181
+ create materialized view bin_v as select handle collate binary as handle, v from bin_src;
182
+
183
+ -- Both case-variants survive: 'Bob' and 'bob' are distinct under the published
184
+ -- BINARY key. A NOCASE re-key (the historic implicit-default reconcile) would have
185
+ -- collapsed them to one row (or rejected the fill as "not a set").
186
+ select count(*) as n from bin_v;
187
+ → [{"n":2}]
188
+ select handle, v from bin_v order by v;
189
+ → [{"handle":"Bob","v":1},{"handle":"bob","v":2}]
190
+
191
+ -- A genuinely-implicit (default-collation) MV column keeps the historic behavior:
192
+ -- no explicit stamp, so the store applies its table-level default. Pin the
193
+ -- value-level result (collation-agnostic) so the case runs identically cross-module.
194
+ create table plain_src (id integer primary key, label text);
195
+ insert into plain_src values (1, 'Xyz'), (2, 'abc');
196
+ create materialized view plain_v as select id, label from plain_src;
197
+ select id, label from plain_v order by id;
198
+ → [{"id":1,"label":"Xyz"},{"id":2,"label":"abc"}]
@@ -0,0 +1,468 @@
1
+ -- 51.7-maintained-table-attach-detach.sqllogic — the maintained-table lifecycle
2
+ -- verbs: `create table … maintained as <body>` (declared-shape attach-to-empty),
3
+ -- `alter table … set maintained as <body>` (attach / re-attach with
4
+ -- verify-by-diff reconcile — derived content wins, identical content writes
5
+ -- nothing), and `alter table … drop maintained` (detach — catalog-only, rows
6
+ -- intact, table becomes ordinary and writable).
7
+
8
+ -- ===================================
9
+ -- 1. create table … maintained as — declared-shape form ≡ create-MV
10
+ -- ===================================
11
+
12
+ create table src (id integer primary key, v text);
13
+ insert into src values (1, 'a'), (2, 'b');
14
+
15
+ create table mt (id integer primary key, v text) maintained as select id, v from src;
16
+
17
+ select * from mt order by id;
18
+ → [{"id":1,"v":"a"},{"id":2,"v":"b"}]
19
+
20
+ -- row-time maintenance is live: source writes reflect immediately
21
+ insert into src values (3, 'c');
22
+ select * from mt order by id;
23
+ → [{"id":1,"v":"a"},{"id":2,"v":"b"},{"id":3,"v":"c"}]
24
+
25
+ update src set v = 'B' where id = 2;
26
+ select v from mt where id = 2;
27
+ → [{"v":"B"}]
28
+
29
+ delete from src where id = 3;
30
+ select count(*) as n from mt;
31
+ → [{"n":2}]
32
+
33
+ -- write-through: DML against the maintained table routes to the source
34
+ insert into mt values (9, 'z');
35
+ select v from src where id = 9;
36
+ → [{"v":"z"}]
37
+ delete from mt where id = 9;
38
+
39
+ -- refresh works on a table-form maintained table
40
+ refresh materialized view mt;
41
+ select count(*) as n from mt;
42
+ → [{"n":2}]
43
+
44
+ -- structural ALTER is rejected: the shape is body-defined
45
+ alter table mt add column extra text;
46
+ -- error: materialized view
47
+
48
+ -- drop materialized view drops the one unified record
49
+ drop materialized view mt;
50
+ select count(*) as n from src;
51
+ → [{"n":2}]
52
+
53
+ -- ===================================
54
+ -- 2. Declared-shape mismatches error before any catalog registration
55
+ -- ===================================
56
+
57
+ create table src2 (id integer primary key, v text not null);
58
+ insert into src2 values (1, 'a');
59
+
60
+ -- arity (build-time gate)
61
+ create table mt2 (id integer primary key, v text not null, extra integer) maintained as select id, v from src2;
62
+ -- error: body produces 2 columns
63
+
64
+ -- column name (strict: alias the body to the declared shape)
65
+ create table mt2 (id integer primary key, vv text not null) maintained as select id, v from src2;
66
+ -- error: alias the body output
67
+
68
+ -- type
69
+ create table mt2 (id integer primary key, v integer not null) maintained as select id, v from src2;
70
+ -- error: body derives type
71
+
72
+ -- not-null (strict in both directions; here the body derives not null but the
73
+ -- declared column is explicitly nullable)
74
+ create table mt2 (id integer primary key, v text null) maintained as select id, v from src2;
75
+ -- error: nullable
76
+
77
+ -- collation
78
+ create table mt2 (id integer primary key, v text not null collate nocase) maintained as select id, v from src2;
79
+ -- error: collation
80
+
81
+ -- physical PK column
82
+ create table mt2 (id integer not null, v text not null primary key) maintained as select id, v from src2;
83
+ -- error: primary-key component
84
+
85
+ -- physical PK direction
86
+ create table mt2 (id integer primary key desc, v text not null) maintained as select id, v from src2;
87
+ -- error: direction
88
+
89
+ -- nothing registered by the failures: the name stayed free and a plain create works
90
+ create table mt2 (id integer primary key, v text not null);
91
+ insert into mt2 values (1, 'x');
92
+ drop table mt2;
93
+
94
+ -- if not exists interplay: an existing table skips ENTIRELY — never half-attaches
95
+ create table keepme (id integer primary key, v text not null);
96
+ insert into keepme values (1, 'orig');
97
+ create table if not exists keepme (id integer primary key, v text not null) maintained as select id, v from src2;
98
+ select * from keepme order by id;
99
+ → [{"id":1,"v":"orig"}]
100
+ -- still plain (no derivation was attached) and still writable
101
+ alter table keepme drop maintained;
102
+ -- error: not a maintained table
103
+ insert into keepme values (2, 'still writable');
104
+ drop table keepme;
105
+
106
+ -- ===================================
107
+ -- 3. set maintained — fresh attach reconciles by diff (derived content wins)
108
+ -- ===================================
109
+
110
+ create table base (id integer primary key, v text not null);
111
+ insert into base values (1, 'a'), (2, 'b'), (3, 'c');
112
+
113
+ -- the upgrading-peer case: the target exists with drifted content —
114
+ -- row 1 identical (no write), row 2 lagged (update), row 3 missing (insert),
115
+ -- row 4 extra (delete)
116
+ create table tgt (id integer primary key, v text not null);
117
+ insert into tgt values (1, 'a'), (2, 'STALE'), (4, 'EXTRA');
118
+
119
+ alter table tgt set maintained as select id, v from base;
120
+
121
+ select * from tgt order by id;
122
+ → [{"id":1,"v":"a"},{"id":2,"v":"b"},{"id":3,"v":"c"}]
123
+
124
+ -- maintenance resumed: source writes propagate
125
+ insert into base values (5, 'e');
126
+ select v from tgt where id = 5;
127
+ → [{"v":"e"}]
128
+
129
+ -- the attached table is write-through, like any maintained table
130
+ update tgt set v = 'A' where id = 1;
131
+ select v from base where id = 1;
132
+ → [{"v":"A"}]
133
+
134
+ -- structural ALTER now rejected
135
+ alter table tgt add column x integer;
136
+ -- error: materialized view
137
+
138
+ -- ===================================
139
+ -- 4. detach round-trip: detach → user writes → re-attach reconciles the drift
140
+ -- ===================================
141
+
142
+ alter table tgt drop maintained;
143
+
144
+ -- rows intact
145
+ select count(*) as n from tgt;
146
+ → [{"n":4}]
147
+
148
+ -- maintenance stopped: a source write no longer propagates
149
+ insert into base values (6, 'f');
150
+ select count(*) as n from tgt where id = 6;
151
+ → [{"n":0}]
152
+
153
+ -- ordinary and user-writable: a direct write stays local (no write-through).
154
+ -- After detach the table carries no derivation, so the engine's READONLY backstop
155
+ -- (runtime DML executor) sheds with it — a direct INSERT/UPDATE/DELETE succeeds and
156
+ -- writes the table's own rows rather than routing to a source.
157
+ insert into tgt values (7, 'local');
158
+ select count(*) as n from base where id = 7;
159
+ → [{"n":0}]
160
+ -- the local row is readable directly in the detached (now ordinary) table
161
+ select v from tgt where id = 7;
162
+ → [{"v":"local"}]
163
+ update tgt set v = 'LOCAL' where id = 7;
164
+ select v from tgt where id = 7;
165
+ → [{"v":"LOCAL"}]
166
+ delete from tgt where id = 7;
167
+ select count(*) as n from tgt where id = 7;
168
+ → [{"n":0}]
169
+
170
+ -- structural ALTER allowed again
171
+ alter table tgt add column extra text null;
172
+ alter table tgt drop column extra;
173
+
174
+ -- re-attach reconciles exactly the user-written drift; maintenance resumes
175
+ alter table tgt set maintained as select id, v from base;
176
+ select * from tgt order by id;
177
+ → [{"id":1,"v":"A"},{"id":2,"v":"b"},{"id":3,"v":"c"},{"id":5,"v":"e"},{"id":6,"v":"f"}]
178
+ insert into base values (8, 'h');
179
+ select v from tgt where id = 8;
180
+ → [{"v":"h"}]
181
+
182
+ -- ===================================
183
+ -- 5. re-attach replaces the body atomically (the differ's body-change primitive)
184
+ -- ===================================
185
+
186
+ create table base2 (id integer primary key, v text not null);
187
+ insert into base2 values (100, 'x');
188
+
189
+ alter table tgt set maintained as select id, v from base2;
190
+ select * from tgt order by id;
191
+ → [{"id":100,"v":"x"}]
192
+
193
+ -- the old source no longer drives it
194
+ insert into base values (9, 'i');
195
+ select count(*) as n from tgt;
196
+ → [{"n":1}]
197
+
198
+ -- the new source does
199
+ insert into base2 values (101, 'y');
200
+ select * from tgt order by id;
201
+ → [{"id":100,"v":"x"},{"id":101,"v":"y"}]
202
+
203
+ alter table tgt drop maintained;
204
+ drop table tgt;
205
+ drop table base2;
206
+
207
+ -- an aggregate body attaches too: the strict shape check holds over the
208
+ -- derived aggregate types/key, and incremental maintenance runs post-attach.
209
+ create table words (id integer primary key, w text not null);
210
+ insert into words values (1, 'x'), (2, 'y'), (3, 'x');
211
+ -- the PK column pins `collate binary` so the declared collation matches the
212
+ -- body-derived one under both suites (the store's key collation defaults to NOCASE)
213
+ create table counts (w text not null collate binary primary key, n integer not null);
214
+ alter table counts set maintained as select w, count(*) as n from words group by w;
215
+ select * from counts order by w;
216
+ → [{"w":"x","n":2},{"w":"y","n":1}]
217
+ insert into words values (4, 'x');
218
+ select n from counts where w = 'x';
219
+ → [{"n":3}]
220
+ delete from words where id = 2;
221
+ select count(*) as remaining from counts;
222
+ → [{"remaining":1}]
223
+ drop materialized view counts;
224
+ drop table words;
225
+
226
+ -- ===================================
227
+ -- 6. duplicate derived keys ⇒ loud reject, table and catalog untouched
228
+ -- (the coarsened-key collision — the parallel-migration shape)
229
+ -- ===================================
230
+
231
+ -- the source PK is `collate binary` explicitly so the case-variant pair inserts
232
+ -- under both suites (the store's table-level key collation defaults to NOCASE)
233
+ create table contacts (handle text collate binary primary key, email text not null);
234
+ insert into contacts values ('alice', 'a@x'), ('ALICE', 'A@X');
235
+
236
+ -- create path: the loud reject rolls the whole record back
237
+ create table contacts2 (handle text not null collate nocase primary key, email text not null)
238
+ maintained as select handle collate nocase as handle, email from contacts;
239
+ -- error: duplicate rows for primary key
240
+
241
+ -- the name stayed free
242
+ create table contacts2 (handle text not null collate nocase primary key, email text not null);
243
+ insert into contacts2 values ('z', 'z@x');
244
+
245
+ -- attach path: same reject, table and catalog untouched
246
+ alter table contacts2 set maintained as select handle collate nocase as handle, email from contacts;
247
+ -- error: duplicate rows for primary key
248
+ select * from contacts2 order by handle;
249
+ → [{"handle":"z","email":"z@x"}]
250
+ insert into contacts2 values ('w', 'w@x');
251
+
252
+ -- merge the collision in the source; the coarsened-key attach then succeeds
253
+ -- (derived wins: the local rows are replaced by the derived contents)
254
+ delete from contacts where handle = 'ALICE';
255
+ alter table contacts2 set maintained as select handle collate nocase as handle, email from contacts;
256
+ select * from contacts2 order by handle;
257
+ → [{"handle":"alice","email":"a@x"}]
258
+
259
+ drop materialized view contacts2;
260
+ drop table contacts;
261
+
262
+ -- ===================================
263
+ -- 7. self-reference and cycles via attach are rejected; the consumer cascade
264
+ -- sees exactly the reconcile diff
265
+ -- ===================================
266
+
267
+ create table a1 (id integer primary key, v text not null);
268
+ insert into a1 values (1, 'a');
269
+
270
+ -- self-reference
271
+ alter table a1 set maintained as select id, v from a1;
272
+ -- error: derivation cycle
273
+
274
+ -- two-table cycle: b1 maintained from a1, then a1 from b1 would close the loop
275
+ create table b1 (id integer primary key, v text not null);
276
+ alter table b1 set maintained as select id, v from a1;
277
+ select * from b1 order by id;
278
+ → [{"id":1,"v":"a"}]
279
+ alter table a1 set maintained as select id, v from b1;
280
+ -- error: derivation cycle
281
+
282
+ -- a non-cyclic body over the same table works (c1 → a1 → b1 chain), and the
283
+ -- attach reconcile's changes cascade to the consumer
284
+ create table c1 (id integer primary key, v text not null);
285
+ insert into c1 values (5, 'c');
286
+ alter table a1 set maintained as select id, v from c1;
287
+ select * from a1 order by id;
288
+ → [{"id":5,"v":"c"}]
289
+ select * from b1 order by id;
290
+ → [{"id":5,"v":"c"}]
291
+
292
+ -- steady-state writes flow down the whole chain
293
+ insert into c1 values (6, 'd');
294
+ select * from b1 order by id;
295
+ → [{"id":5,"v":"c"},{"id":6,"v":"d"}]
296
+
297
+ drop materialized view b1;
298
+ drop materialized view a1;
299
+ drop table c1;
300
+
301
+ -- ===================================
302
+ -- 8. verb errors
303
+ -- ===================================
304
+
305
+ create table plain1 (id integer primary key);
306
+
307
+ alter table plain1 drop maintained;
308
+ -- error: not a maintained table
309
+
310
+ -- a DML body is rejected at build (and the mutation never executes)
311
+ alter table plain1 set maintained as insert into base values (99, 'x') returning id;
312
+ -- error: cannot be used as a view body
313
+ select count(*) as n from base where id = 99;
314
+ → [{"n":0}]
315
+
316
+ -- a shape-differing attach over a PLAIN table (the implicit form) RESHAPES the
317
+ -- backing to follow the body — here a trailing append; the plain rows are
318
+ -- discarded by the reconcile (derived content wins)
319
+ alter table plain1 set maintained as select id, v from base;
320
+ select count(*) as n from plain1;
321
+ → [{"n":7}]
322
+ alter table plain1 drop maintained;
323
+
324
+ -- an INEXPRESSIBLE reshape (a column reorder) is a sited error, table untouched
325
+ alter table plain1 set maintained as select v, id from base;
326
+ -- error: changed incompatibly
327
+ select count(*) as n from plain1;
328
+ → [{"n":7}]
329
+
330
+ -- a generated column is rejected on both authoring forms: the body supplies
331
+ -- every column's value, so the generation expression would silently diverge
332
+ create table gen1 (id integer primary key, v text not null generated always as ('x'));
333
+ alter table gen1 set maintained as select id, v from base;
334
+ -- error: generated
335
+ drop table gen1;
336
+ create table gen1 (id integer primary key, v text not null generated always as ('x')) maintained as select id, v from base;
337
+ -- error: generated
338
+
339
+ drop table plain1;
340
+ drop table base;
341
+
342
+ -- ===================================
343
+ -- 9. detach of a STALE maintained table is allowed — the flag leaves with the
344
+ -- derivation
345
+ -- ===================================
346
+
347
+ create table src3 (id integer primary key, v text not null);
348
+ insert into src3 values (1, 'a');
349
+ create table mt3 (id integer primary key, v text not null) maintained as select id, v from src3;
350
+
351
+ -- an incompatible source change (dropping a referenced column) marks the
352
+ -- consumer stale
353
+ alter table src3 drop column v;
354
+ select * from mt3;
355
+ -- error: stale
356
+
357
+ alter table mt3 drop maintained;
358
+
359
+ -- plain again: readable and writable, staleness gone with the derivation
360
+ select * from mt3 order by id;
361
+ → [{"id":1,"v":"a"}]
362
+ insert into mt3 values (2, 'b');
363
+ drop table mt3;
364
+ drop table src3;
365
+
366
+ -- ===================================
367
+ -- 10. with defaults clause on the table form (write-through supplies the
368
+ -- omitted column)
369
+ -- ===================================
370
+
371
+ create table src4 (id integer primary key, v text not null, created integer not null);
372
+ create table mt4 (id integer primary key, v text not null, created integer not null)
373
+ maintained as select id, v, created from src4
374
+ with defaults (created = 42);
375
+
376
+ insert into mt4 (id, v) values (1, 'a');
377
+ select * from src4;
378
+ → [{"id":1,"v":"a","created":42}]
379
+ select * from mt4;
380
+ → [{"id":1,"v":"a","created":42}]
381
+
382
+ drop materialized view mt4;
383
+
384
+ -- the clause also rides the attach verb
385
+ create table mt5 (id integer primary key, v text not null, created integer not null);
386
+ alter table mt5 set maintained as select id, v, created from src4
387
+ with defaults (created = 99);
388
+ insert into mt5 (id, v) values (2, 'b');
389
+ select * from src4 order by id;
390
+ → [{"id":1,"v":"a","created":42},{"id":2,"v":"b","created":99}]
391
+ select created from mt5 where id = 2;
392
+ → [{"created":99}]
393
+
394
+ drop materialized view mt5;
395
+ drop table src4;
396
+
397
+ -- ===================================
398
+ -- 11. `maintained` stays contextual — usable as an identifier
399
+ -- ===================================
400
+
401
+ create table maintained (maintained integer primary key);
402
+ insert into maintained values (1);
403
+ select maintained from maintained;
404
+ → [{"maintained":1}]
405
+ -- the bare DROP MAINTAINED verb wins over a column of that name…
406
+ alter table maintained drop maintained;
407
+ -- error: not a maintained table
408
+ drop table maintained;
409
+
410
+ -- ===================================
411
+ -- 12. set maintained (cols) as — explicit rename-list re-attach + backing reshape
412
+ -- ===================================
413
+
414
+ create table rsrc (id integer primary key, x text not null, y text not null);
415
+ insert into rsrc values (1, 'a', 'A'), (2, 'b', 'B');
416
+
417
+ -- explicit attach with an authored rename list (a, b) over the body's (id, x)
418
+ create table rmv (a integer primary key, b text not null) maintained (a, b) as select id, x from rsrc;
419
+ select a, b from rmv order by a;
420
+ → [{"a":1,"b":"a"},{"a":2,"b":"b"}]
421
+
422
+ -- rename-list change b → c (same body): the backing column is RENAMED in place,
423
+ -- rows relabeled (not rebuilt); the derivation re-records (a, c)
424
+ alter table rmv set maintained (a, c) as select id, x from rsrc;
425
+ select a, c from rmv order by a;
426
+ → [{"a":1,"c":"a"},{"a":2,"c":"b"}]
427
+
428
+ -- idempotent: re-running the same verb changes nothing
429
+ alter table rmv set maintained (a, c) as select id, x from rsrc;
430
+ select a, c from rmv order by a;
431
+ → [{"a":1,"c":"a"},{"a":2,"c":"b"}]
432
+
433
+ -- maintenance is live on the renamed backing
434
+ insert into rsrc values (3, 'c', 'C');
435
+ select c from rmv where a = 3;
436
+ → [{"c":"c"}]
437
+
438
+ -- body-only change with the list unchanged applies (a plain reconcile, no reshape)
439
+ alter table rmv set maintained (a, c) as select id, y from rsrc;
440
+ select a, c from rmv order by a;
441
+ → [{"a":1,"c":"A"},{"a":2,"c":"B"},{"a":3,"c":"C"}]
442
+
443
+ -- a rename-list swap (a, c) → (c, a) is an inexpressible reorder, table untouched
444
+ alter table rmv set maintained (c, a) as select id, y from rsrc;
445
+ -- error: changed incompatibly
446
+ select a, c from rmv order by a;
447
+ → [{"a":1,"c":"A"},{"a":2,"c":"B"},{"a":3,"c":"C"}]
448
+
449
+ -- a list/body arity mismatch is a sited error before anything is recorded
450
+ alter table rmv set maintained (a, c, d) as select id, y from rsrc;
451
+ -- error: rename list declares 3 columns but the body produces 2
452
+
453
+ -- a count drift (3-col list + body over the 2-col table) is the strict shape error
454
+ alter table rmv set maintained (a, c, d) as select id, y, x from rsrc;
455
+ -- error: body produces 3 columns but the table declares 2
456
+
457
+ -- still intact after the rejected re-attaches
458
+ select a, c from rmv order by a;
459
+ → [{"a":1,"c":"A"},{"a":2,"c":"B"},{"a":3,"c":"C"}]
460
+
461
+ -- the bare verb over the explicit table goes implicit: the backing relabels to the
462
+ -- body's natural names and the recorded list is abandoned (derivation.columns clears)
463
+ alter table rmv set maintained as select id, x from rsrc;
464
+ select id, x from rmv order by id;
465
+ → [{"id":1,"x":"a"},{"id":2,"x":"b"},{"id":3,"x":"c"}]
466
+
467
+ drop materialized view rmv;
468
+ drop table rsrc;