@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.
- package/README.md +2 -0
- package/dist/src/common/types.d.ts +4 -4
- package/dist/src/index.d.ts +1 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +3 -2
- package/dist/src/index.js.map +1 -1
- package/dist/src/schema/catalog-rendering.js +13 -1
- package/dist/src/schema/catalog-rendering.js.map +1 -1
- package/dist/src/schema/catalog.d.ts +35 -2
- package/dist/src/schema/catalog.d.ts.map +1 -1
- package/dist/src/schema/catalog.js +42 -33
- package/dist/src/schema/catalog.js.map +1 -1
- package/dist/src/schema/schema-differ.d.ts +1 -1
- package/dist/src/schema/schema-differ.d.ts.map +1 -1
- package/dist/src/schema/schema-differ.js +195 -33
- package/dist/src/schema/schema-differ.js.map +1 -1
- package/dist/src/schema/unique-enforcement.d.ts +23 -1
- package/dist/src/schema/unique-enforcement.d.ts.map +1 -1
- package/dist/src/schema/unique-enforcement.js +43 -1
- package/dist/src/schema/unique-enforcement.js.map +1 -1
- package/dist/src/vtab/memory/layer/manager.d.ts +15 -12
- package/dist/src/vtab/memory/layer/manager.d.ts.map +1 -1
- package/dist/src/vtab/memory/layer/manager.js +87 -100
- package/dist/src/vtab/memory/layer/manager.js.map +1 -1
- package/package.json +7 -4
- package/test/README.md +173 -0
- package/test/logic/01-basic.sqllogic +39 -0
- package/test/logic/01.1-select-projection-extras.sqllogic +130 -0
- package/test/logic/01.2-strings.sqllogic +43 -0
- package/test/logic/01.5-insert-select.sqllogic +237 -0
- package/test/logic/01.6-update-extras.sqllogic +118 -0
- package/test/logic/01.7-update-from.sqllogic +67 -0
- package/test/logic/01.8-delete-extras.sqllogic +122 -0
- package/test/logic/01.8.1-delete-range-cow.sqllogic +115 -0
- package/test/logic/01.9-query-expr-dml-gates.sqllogic +32 -0
- package/test/logic/01.9-query-expr-dml.sqllogic +171 -0
- package/test/logic/01.9-query-expr-values.sqllogic +111 -0
- package/test/logic/01.9.1-limit-over-dml-subquery.sqllogic +119 -0
- package/test/logic/02-filters.sqllogic +54 -0
- package/test/logic/02-smoke.sqllogic +62 -0
- package/test/logic/02.1-bind-parameters.sqllogic +223 -0
- package/test/logic/03-expressions.sqllogic +190 -0
- package/test/logic/03.1-quoted-identifiers.sqllogic +55 -0
- package/test/logic/03.4-defaults.sqllogic +554 -0
- package/test/logic/03.4.1-default-edge-cases.sqllogic +99 -0
- package/test/logic/03.5-tvf.sqllogic +61 -0
- package/test/logic/03.6-type-system.sqllogic +544 -0
- package/test/logic/03.6.1-numeric-text-comparison-coercion.sqllogic +244 -0
- package/test/logic/03.6.2-value-to-text.sqllogic +224 -0
- package/test/logic/03.7-bigint-mixed-arithmetic.sqllogic +65 -0
- package/test/logic/03.8-not-precedence.sqllogic +255 -0
- package/test/logic/03.9-is-bool-predicate.sqllogic +150 -0
- package/test/logic/03.9.1-is-bool-predicate-partial-index.sqllogic +34 -0
- package/test/logic/04-order-by.sqllogic +38 -0
- package/test/logic/04-transactions.sqllogic +239 -0
- package/test/logic/04a-savepoint-lazy-attach.sqllogic +122 -0
- package/test/logic/05-vtab_memory.sqllogic +50 -0
- package/test/logic/05.0.1-vtab-memory-unique-index-collation.sqllogic +34 -0
- package/test/logic/05.1-composite-pk-range-scan.sqllogic +147 -0
- package/test/logic/05.1.1-secondary-index-range-scan.sqllogic +56 -0
- package/test/logic/05.2-cast-seek-correctness.sqllogic +124 -0
- package/test/logic/06-builtin_functions.sqllogic +149 -0
- package/test/logic/06.1-string-functions.sqllogic +92 -0
- package/test/logic/06.1.3-like-glob-edges.sqllogic +53 -0
- package/test/logic/06.2-math-functions.sqllogic +82 -0
- package/test/logic/06.3-schema.sqllogic +48 -0
- package/test/logic/06.3.1-schema-all-schemas.sqllogic +39 -0
- package/test/logic/06.3.2-schema-foreign-keys.sqllogic +208 -0
- package/test/logic/06.3.3-introspection-tags.sqllogic +202 -0
- package/test/logic/06.3.3.1-introspection-tags-index.sqllogic +74 -0
- package/test/logic/06.3.4-view-info.sqllogic +378 -0
- package/test/logic/06.3.5-column-info.sqllogic +347 -0
- package/test/logic/06.3.6-schema-views.sqllogic +29 -0
- package/test/logic/06.4-schema-search-path.sqllogic +354 -0
- package/test/logic/06.4.1-schema-case-insensitive.sqllogic +83 -0
- package/test/logic/06.4.2-collation-extras.sqllogic +472 -0
- package/test/logic/06.4.2.1-collation-index-access-paths.sqllogic +140 -0
- package/test/logic/06.4.3-write-path-collation.sqllogic +99 -0
- package/test/logic/06.4.4-comparison-collation-precedence.sqllogic +342 -0
- package/test/logic/06.4.5-any-collate-declared-keys.sqllogic +92 -0
- package/test/logic/06.5-polymorphic-types.sqllogic +169 -0
- package/test/logic/06.5.1-conversion-functions.sqllogic +173 -0
- package/test/logic/06.5.2-scalar-minmax.sqllogic +16 -0
- package/test/logic/06.5.3-undeclared-return-type-comparison.sqllogic +244 -0
- package/test/logic/06.5.4-declared-return-type-builtins.sqllogic +288 -0
- package/test/logic/06.6-aggregate-extended.sqllogic +78 -0
- package/test/logic/06.7-json-extended.sqllogic +53 -0
- package/test/logic/06.8-json-path-operators.sqllogic +99 -0
- package/test/logic/06.9-json-canonical-key.sqllogic +65 -0
- package/test/logic/06.9.1-json-coerce-once.sqllogic +417 -0
- package/test/logic/06.9.1.1-json-coerce-once-index.sqllogic +39 -0
- package/test/logic/06.9.2-json-structural-equality.sqllogic +382 -0
- package/test/logic/06.9.2.1-json-structural-equality-index.sqllogic +76 -0
- package/test/logic/06.9.3-json-index-range-seek.sqllogic +205 -0
- package/test/logic/07-aggregates.sqllogic +193 -0
- package/test/logic/07.1-aggregate-filter-clause.sqllogic +12 -0
- package/test/logic/07.2-aggregate-order-by.sqllogic +11 -0
- package/test/logic/07.3-group-by-extras.sqllogic +602 -0
- package/test/logic/07.3.1-group-by-order-by-key.sqllogic +164 -0
- package/test/logic/07.3.2-grouped-select-list-shape.sqllogic +231 -0
- package/test/logic/07.4-group-by-filter-composite-pk.sqllogic +120 -0
- package/test/logic/07.5-sum-mixed-exact-and-float.sqllogic +151 -0
- package/test/logic/07.5-window.sqllogic +1941 -0
- package/test/logic/07.5.1-window-named.sqllogic +13 -0
- package/test/logic/07.5.2-window-nth-value.sqllogic +13 -0
- package/test/logic/07.6-subqueries.sqllogic +78 -0
- package/test/logic/07.6.1-subquery-extras.sqllogic +93 -0
- package/test/logic/07.7-and-or-short-circuit.sqllogic +58 -0
- package/test/logic/07.7-in-subquery-caching.sqllogic +174 -0
- package/test/logic/07.7-scalar-agg-decorrelation.sqllogic +197 -0
- package/test/logic/07.7.1-in-extras.sqllogic +158 -0
- package/test/logic/07.7.1-scalar-agg-decorrelation-filter.sqllogic +105 -0
- package/test/logic/07.7.2-scalar-agg-decorrelation-nested.sqllogic +115 -0
- package/test/logic/07.7.3-exists-in-select-decorrelation.sqllogic +107 -0
- package/test/logic/07.7.4-where-conjunct-ordering.sqllogic +121 -0
- package/test/logic/07.7.5-filter-lost-under-index-order.sqllogic +134 -0
- package/test/logic/07.7.6-correlated-predicate-scope.sqllogic +178 -0
- package/test/logic/07.7.7-join-source-scope-shadowing.sqllogic +137 -0
- package/test/logic/07.7.8-correlated-ref-to-computed-column.sqllogic +165 -0
- package/test/logic/07.7.9-conjunct-monotonicity.sqllogic +200 -0
- package/test/logic/07.8-correlated-subquery-edges.sqllogic +71 -0
- package/test/logic/07.8.1-correlated-in-decorrelation-gates.sqllogic +156 -0
- package/test/logic/07.9-in-value-list.sqllogic +154 -0
- package/test/logic/07.9.1-in-value-list-composite-index.sqllogic +38 -0
- package/test/logic/08-views.sqllogic +64 -0
- package/test/logic/08.1-semi-anti-join.sqllogic +191 -0
- package/test/logic/08.1-view-edge-cases.sqllogic +118 -0
- package/test/logic/08.1.1-uncorrelated-in-semijoin.sqllogic +251 -0
- package/test/logic/08.2-existence-flag-semijoin-recovery.sqllogic +197 -0
- package/test/logic/08.3-existence-flag-inner-recovery.sqllogic +102 -0
- package/test/logic/08.4-key-set-semi-join.sqllogic +447 -0
- package/test/logic/09-set_operations.sqllogic +244 -0
- package/test/logic/09.1-set-op-cross-collation.sqllogic +230 -0
- package/test/logic/10-distinct_datatypes.sqllogic +127 -0
- package/test/logic/10.1-ddl-lifecycle.sqllogic +203 -0
- package/test/logic/10.1.1-create-table-syntax-edges.sqllogic +47 -0
- package/test/logic/10.1.2-ddl-in-transaction.sqllogic +143 -0
- package/test/logic/10.1.2.1-add-constraint-in-transaction.sqllogic +59 -0
- package/test/logic/10.1.3-ddl-drop-in-transaction.sqllogic +187 -0
- package/test/logic/10.1.3.1-drop-constraint-in-transaction.sqllogic +45 -0
- package/test/logic/10.1.4-create-table-duplicate-constraint-names.sqllogic +149 -0
- package/test/logic/10.1.4-ddl-transaction-policy.sqllogic +314 -0
- package/test/logic/10.1.5-alter-add-constraint-minted-name-disambiguation.sqllogic +219 -0
- package/test/logic/10.1.5-create-index-lifecycle.sqllogic +72 -0
- package/test/logic/10.1.6-ddl-transaction-policy-index.sqllogic +143 -0
- package/test/logic/10.1.7-create-table-default-type-check.sqllogic +119 -0
- package/test/logic/10.1.8-alter-add-check-existing-rows.sqllogic +117 -0
- package/test/logic/10.2-column-features.sqllogic +365 -0
- package/test/logic/10.2.1-table-options-rejection.sqllogic +63 -0
- package/test/logic/10.2.2-default-collation-memory.sqllogic +30 -0
- package/test/logic/10.3-function-features.sqllogic +247 -0
- package/test/logic/10.4-schema-scale.sqllogic +168 -0
- package/test/logic/10.4.1-schema-scale-indexes.sqllogic +121 -0
- package/test/logic/10.5-indexes.sqllogic +164 -0
- package/test/logic/10.5.1-partial-indexes.sqllogic +526 -0
- package/test/logic/10.5.2-expression-indexes.sqllogic +34 -0
- package/test/logic/10.5.3-desc-index-ordering.sqllogic +130 -0
- package/test/logic/10.5.4-composite-pk-index-update-phantom.sqllogic +55 -0
- package/test/logic/10.5.5-index-name-uniqueness.sqllogic +76 -0
- package/test/logic/10.5.6-minmax-index-boundary.sqllogic +204 -0
- package/test/logic/10.5.7-implicit-unique-index-lifecycle.sqllogic +1216 -0
- package/test/logic/10.6-distinct-edge-cases.sqllogic +119 -0
- package/test/logic/100-predicate-normalization-edge-cases.sqllogic +238 -0
- package/test/logic/100.1-where-extras.sqllogic +163 -0
- package/test/logic/100.1.1-where-join-on-order-indexed.sqllogic +35 -0
- package/test/logic/101-builtin-mutation-kills.sqllogic +974 -0
- package/test/logic/101-transaction-edge-cases.sqllogic +395 -0
- package/test/logic/102-schema-catalog-edge-cases.sqllogic +252 -0
- package/test/logic/102-unique-constraints.sqllogic +145 -0
- package/test/logic/102.0.1-schema-catalog-indexed-table.sqllogic +32 -0
- package/test/logic/102.1-unique-edge-cases.sqllogic +111 -0
- package/test/logic/102.1.1-unique-index-creation-edge-cases.sqllogic +75 -0
- package/test/logic/102.2-unique-collation.sqllogic +181 -0
- package/test/logic/102.2.1-unique-collation-index-derived.sqllogic +305 -0
- package/test/logic/103-database-options-edge-cases.sqllogic +108 -0
- package/test/logic/103.1-pragma-boolean-values.sqllogic +126 -0
- package/test/logic/104-emit-mutation-kills.sqllogic +236 -0
- package/test/logic/105-vtab-memory-mutation-kills.sqllogic +754 -0
- package/test/logic/105.1-vtab-memory-index-mutation-kills.sqllogic +540 -0
- package/test/logic/106-constraint-extractor-mutation-kills.sqllogic +350 -0
- package/test/logic/107-temporal-arithmetic-mutation-kills.sqllogic +833 -0
- package/test/logic/108-cardinality-estimation.sqllogic +146 -0
- package/test/logic/108.1-analyze-name-resolution.sqllogic +102 -0
- package/test/logic/109-aggregate-physical-selection.sqllogic +103 -0
- package/test/logic/11-joins.sqllogic +86 -0
- package/test/logic/11.1-join-using.sqllogic +267 -0
- package/test/logic/11.2-comma-join.sqllogic +35 -0
- package/test/logic/11.3-index-nested-loop-join.sqllogic +305 -0
- package/test/logic/11.3-mismatched-collation-join.sqllogic +74 -0
- package/test/logic/11.4-hash-join-side-swap.sqllogic +118 -0
- package/test/logic/110-scan-emitter-mutation-kills.sqllogic +121 -0
- package/test/logic/110.1-scan-emitter-index-scan-kills.sqllogic +47 -0
- package/test/logic/12-empty-primary-key.sqllogic +124 -0
- package/test/logic/12-join_padding_order.sqllogic +58 -0
- package/test/logic/12.1-orderby-index-consumption.sqllogic +40 -0
- package/test/logic/13-cte.sqllogic +137 -0
- package/test/logic/13.1-cte-multiple-recursive.sqllogic +104 -0
- package/test/logic/13.10-cte-qualified-name.sqllogic +136 -0
- package/test/logic/13.11-unreferenced-dml-cte.sqllogic +414 -0
- package/test/logic/13.12-nested-dml-cte-rejected.sqllogic +280 -0
- package/test/logic/13.2-cte-bind-params.sqllogic +98 -0
- package/test/logic/13.3-cte-edge-cases.sqllogic +120 -0
- package/test/logic/13.4-cte-extras.sqllogic +98 -0
- package/test/logic/13.5-cte-join-order.sqllogic +166 -0
- package/test/logic/13.6-cte-dml-runs-once.sqllogic +318 -0
- package/test/logic/13.7-cte-sibling-visibility.sqllogic +227 -0
- package/test/logic/13.8-insert-with-clause-visibility.sqllogic +254 -0
- package/test/logic/13.9-schema-authored-cte-isolation.sqllogic +328 -0
- package/test/logic/13.9.1-schema-authored-schema-path-isolation.sqllogic +408 -0
- package/test/logic/14-utilities.sqllogic +168 -0
- package/test/logic/15-timespan.sqllogic +279 -0
- package/test/logic/15.1-semantic-ordering.sqllogic +960 -0
- package/test/logic/15.1.1-json-check-coercion.sqllogic +178 -0
- package/test/logic/15.1.2-semantic-ordering-index.sqllogic +41 -0
- package/test/logic/15.1.3-declared-form-write-contract.sqllogic +519 -0
- package/test/logic/16-epoch.sqllogic +187 -0
- package/test/logic/17-weekday-modifier.sqllogic +78 -0
- package/test/logic/18-json-string-escapes.sqllogic +86 -0
- package/test/logic/18-strftime-extended-formats.sqllogic +68 -0
- package/test/logic/20-empty-single-row.sqllogic +261 -0
- package/test/logic/21-null-edge-cases.sqllogic +227 -0
- package/test/logic/21.1-where-null-comparisons.sqllogic +151 -0
- package/test/logic/21.1.1-where-null-comparisons-secondary-index.sqllogic +35 -0
- package/test/logic/21.2-between-edges.sqllogic +157 -0
- package/test/logic/22-boundary-values.sqllogic +175 -0
- package/test/logic/23-self-joins-duplicates.sqllogic +74 -0
- package/test/logic/24-builtin-branches.sqllogic +611 -0
- package/test/logic/24.1-substr-extras.sqllogic +75 -0
- package/test/logic/24.2-random-extras.sqllogic +39 -0
- package/test/logic/25-aggregate-edge-cases.sqllogic +289 -0
- package/test/logic/25.1-nested-aggregates.sqllogic +74 -0
- package/test/logic/25.2-having-edge-cases.sqllogic +318 -0
- package/test/logic/25.3-aggregate-isnull-empty.sqllogic +16 -0
- package/test/logic/25.4-groupby-fd-constant-empty.sqllogic +55 -0
- package/test/logic/25.5-ungrouped-aggregate-column-free-select-item.sqllogic +196 -0
- package/test/logic/26-join-edge-cases.sqllogic +333 -0
- package/test/logic/26.1-left-join-isnull-on-notnull.sqllogic +26 -0
- package/test/logic/26.2-left-join-on-vs-where.sqllogic +67 -0
- package/test/logic/26.3-join-on-constants.sqllogic +61 -0
- package/test/logic/26.4-join-on-is-null-nullable.sqllogic +44 -0
- package/test/logic/27-window-edge-cases.sqllogic +206 -0
- package/test/logic/27.1-window-groups-frame.sqllogic +13 -0
- package/test/logic/27.2-window-exclude.sqllogic +13 -0
- package/test/logic/27.3-window-json-aggregation.sqllogic +66 -0
- package/test/logic/28-set-ops-sort-edge-cases.sqllogic +444 -0
- package/test/logic/28.1-compound-limit-offset.sqllogic +143 -0
- package/test/logic/28.2-orderby-expression-extras.sqllogic +698 -0
- package/test/logic/28.2-set-op-branch-types.sqllogic +217 -0
- package/test/logic/29-constraint-edge-cases.sqllogic +442 -0
- package/test/logic/29.1-column-level-conflict-clause.sqllogic +171 -0
- package/test/logic/29.2-table-level-pk-conflict-clause.sqllogic +113 -0
- package/test/logic/40-constraints.sqllogic +418 -0
- package/test/logic/40.1-pk-desc-direction.sqllogic +76 -0
- package/test/logic/40.2-check-extras.sqllogic +683 -0
- package/test/logic/41-alter-table.sqllogic +191 -0
- package/test/logic/41-fk-cascade-conflict-and-self-ref.sqllogic +263 -0
- package/test/logic/41-fk-cross-schema.sqllogic +155 -0
- package/test/logic/41-fk-extended-targets.sqllogic +173 -0
- package/test/logic/41-foreign-keys.sqllogic +1001 -0
- package/test/logic/41-generated-column-errors.sqllogic +225 -0
- package/test/logic/41-generated-column-extras.sqllogic +598 -0
- package/test/logic/41-generated-column-scope.sqllogic +329 -0
- package/test/logic/41-generated-columns.sqllogic +361 -0
- package/test/logic/41.1-alter-pk.sqllogic +230 -0
- package/test/logic/41.1-fk-collation-conflict.sqllogic +277 -0
- package/test/logic/41.10-alter-drop-column-foreign-key.sqllogic +274 -0
- package/test/logic/41.10.1-alter-drop-column-unique-index.sqllogic +169 -0
- package/test/logic/41.10.2-alter-drop-column-check-and-assertion.sqllogic +1616 -0
- package/test/logic/41.10.3-alter-drop-column-referencing-fk.sqllogic +292 -0
- package/test/logic/41.10.4-drop-object-expression-dependents.sqllogic +602 -0
- package/test/logic/41.11-deferred-fk-with-rename.sqllogic +232 -0
- package/test/logic/41.12-alter-default-coercion.sqllogic +200 -0
- package/test/logic/41.13-alter-add-column-generated-backfill.sqllogic +566 -0
- package/test/logic/41.14-alter-add-column-subquery-backfill.sqllogic +129 -0
- package/test/logic/41.15-alter-column-default-type-check.sqllogic +178 -0
- package/test/logic/41.16-fk-unenforceable.sqllogic +364 -0
- package/test/logic/41.2-alter-column.sqllogic +382 -0
- package/test/logic/41.2.1-alter-column-retype-deleted-row-memory.sqllogic +32 -0
- package/test/logic/41.2.2-alter-column-retype-index-rebuild.sqllogic +77 -0
- package/test/logic/41.2.3-alter-column-set-not-null-pk-backfill.sqllogic +310 -0
- package/test/logic/41.2.3.1-alter-column-set-not-null-pk-backfill-secondary-index.sqllogic +37 -0
- package/test/logic/41.3-alter-add-column-unique.sqllogic +184 -0
- package/test/logic/41.3-alter-rename-propagation.sqllogic +2352 -0
- package/test/logic/41.3.1-alter-rename-index-propagation.sqllogic +94 -0
- package/test/logic/41.4-alter-add-column-constraints.sqllogic +855 -0
- package/test/logic/41.5-alter-misc.sqllogic +48 -0
- package/test/logic/41.5-cross-schema-foreign-keys.sqllogic +253 -0
- package/test/logic/41.6-alter-drop-rename-constraint.sqllogic +354 -0
- package/test/logic/41.6.1-alter-drop-constraint-index-derived.sqllogic +22 -0
- package/test/logic/41.7-alter-column-collate.sqllogic +105 -0
- package/test/logic/41.7.1-alter-column-collate-unique.sqllogic +45 -0
- package/test/logic/41.7.2-alter-column-collate-unique-store.sqllogic +208 -0
- package/test/logic/41.7.2.1-alter-column-collate-unique-index-store.sqllogic +114 -0
- package/test/logic/41.7.3-alter-column-retype-unique.sqllogic +293 -0
- package/test/logic/41.7.3.1-alter-column-retype-staged-rows-memory.sqllogic +41 -0
- package/test/logic/41.7.3.2-alter-column-retype-unique-index.sqllogic +72 -0
- package/test/logic/41.7.4-alter-column-retype-semantic-memory.sqllogic +445 -0
- package/test/logic/41.7.4.1-alter-column-retype-semantic-index-memory.sqllogic +91 -0
- package/test/logic/41.7.5-alter-column-collate-pk-staged-delete-memory.sqllogic +106 -0
- package/test/logic/41.8-alter-add-constraint-unique-fk.sqllogic +275 -0
- package/test/logic/41.8-alter-savepoint-staged-rows.sqllogic +443 -0
- package/test/logic/41.8.1-alter-rename-savepoint-staged-rows.sqllogic +408 -0
- package/test/logic/41.9-alter-constraint-body-change.sqllogic +180 -0
- package/test/logic/41.9-fk-restrict-batched.sqllogic +290 -0
- package/test/logic/42-committed-snapshot.sqllogic +254 -0
- package/test/logic/42-returning.sqllogic +159 -0
- package/test/logic/42.1-returning-extras.sqllogic +232 -0
- package/test/logic/42.2-returning-stored-row.sqllogic +165 -0
- package/test/logic/43-default-nullability.sqllogic +131 -0
- package/test/logic/43-transition-constraints.sqllogic +341 -0
- package/test/logic/43.1-default-collation.sqllogic +140 -0
- package/test/logic/43.1-notnull-or-conflict.sqllogic +79 -0
- package/test/logic/43.2-deferred-check-new-on-delete.sqllogic +95 -0
- package/test/logic/43.3-nullable-primary-key.sqllogic +587 -0
- package/test/logic/44-determinism-validation.sqllogic +164 -0
- package/test/logic/44-orthogonality.sqllogic +146 -0
- package/test/logic/44.1-nondeterministic-schema.sqllogic +316 -0
- package/test/logic/45-udf-determinism.sqllogic +39 -0
- package/test/logic/46-mutation-context.sqllogic +595 -0
- package/test/logic/47-upsert.sqllogic +255 -0
- package/test/logic/47.1-upsert-conflict-targets.sqllogic +169 -0
- package/test/logic/47.2-replace-and-or-clauses.sqllogic +164 -0
- package/test/logic/47.2.1-pk-replace-secondary-unique.sqllogic +374 -0
- package/test/logic/47.3-engine-or-fail.sqllogic +122 -0
- package/test/logic/47.3-upsert-conflict-target-collation.sqllogic +139 -0
- package/test/logic/47.3.1-upsert-conflict-index-derived-collation.sqllogic +25 -0
- package/test/logic/47.4-upsert-conflict-target-affinity.sqllogic +59 -0
- package/test/logic/47.5-upsert-do-update-constraints.sqllogic +440 -0
- package/test/logic/47.6-upsert-do-update-decomposed.sqllogic +100 -0
- package/test/logic/49-reference-graph.sqllogic +84 -0
- package/test/logic/50-declarative-schema.sqllogic +2550 -0
- package/test/logic/50-metadata-tags.sqllogic +1033 -0
- package/test/logic/50.0.1-metadata-tags-index.sqllogic +141 -0
- package/test/logic/50.1-declare-schema-pk.sqllogic +150 -0
- package/test/logic/50.2-declare-schema-renames.sqllogic +949 -0
- package/test/logic/50.2.1-declare-schema-index-renames.sqllogic +173 -0
- package/test/logic/50.3-declare-schema-duplicate-names.sqllogic +280 -0
- package/test/logic/50.4-declare-schema-apply-restore.sqllogic +192 -0
- package/test/logic/51-lens-foundation.sqllogic +147 -0
- package/test/logic/51-materialized-views.sqllogic +376 -0
- package/test/logic/51.5-materialized-views-coarsened-key.sqllogic +198 -0
- package/test/logic/51.7-maintained-table-attach-detach.sqllogic +468 -0
- package/test/logic/51.8-maintained-table-declared-constraints.sqllogic +440 -0
- package/test/logic/51.85-maintained-table-parent-fk.sqllogic +103 -0
- package/test/logic/51.9-maintained-table-secondary-unique.sqllogic +237 -0
- package/test/logic/51.9.1-maintained-table-partial-unique.sqllogic +36 -0
- package/test/logic/52-lens-overrides.sqllogic +566 -0
- package/test/logic/53-materialized-views-rowtime.sqllogic +1601 -0
- package/test/logic/53-reserved-tags.sqllogic +252 -0
- package/test/logic/53.1-materialized-view-write-through.sqllogic +329 -0
- package/test/logic/53.2-materialized-view-rename-propagation.sqllogic +483 -0
- package/test/logic/53.3-materialized-view-constraint-only-ddl.sqllogic +409 -0
- package/test/logic/53.3.1-materialized-view-index-ddl-irrelevance.sqllogic +29 -0
- package/test/logic/53.4-materialized-view-structural-alter-restore.sqllogic +436 -0
- package/test/logic/54-covering-mv-enforcement.sqllogic +314 -0
- package/test/logic/54.1-covering-mv-partial-enforcement.sqllogic +34 -0
- package/test/logic/55-internal-eviction-reporting.sqllogic +89 -0
- package/test/logic/55-lens-prover.sqllogic +202 -0
- package/test/logic/55.1-eviction-restrict-fk.sqllogic +148 -0
- package/test/logic/55.5-lens-authored-inverse.sqllogic +1468 -0
- package/test/logic/80-grow-retrieve-pass.sqllogic +79 -0
- package/test/logic/81-quickpick.sqllogic +24 -0
- package/test/logic/82-bloom-join.sqllogic +185 -0
- package/test/logic/83-merge-join.sqllogic +280 -0
- package/test/logic/84-asof-scan.sqllogic +238 -0
- package/test/logic/84-key-cardinality.sqllogic +50 -0
- package/test/logic/85-relational-const-folding.sqllogic +51 -0
- package/test/logic/86-scalar-cse.sqllogic +42 -0
- package/test/logic/90-error_paths.sqllogic +114 -0
- package/test/logic/90.1-parse-errors.sqllogic +77 -0
- package/test/logic/90.2-alter-table-errors.sqllogic +53 -0
- package/test/logic/90.2.1-alter-extra-errors.sqllogic +51 -0
- package/test/logic/90.3-expression-errors.sqllogic +43 -0
- package/test/logic/90.4-dml-errors.sqllogic +47 -0
- package/test/logic/90.5-unsupported-join-types.sqllogic +37 -0
- package/test/logic/90.5.1-right-full-join-read.sqllogic +157 -0
- package/test/logic/90.6-select-error-paths.sqllogic +57 -0
- package/test/logic/91-merge-join-edge-cases.sqllogic +159 -0
- package/test/logic/92-hash-aggregate-edge-cases.sqllogic +139 -0
- package/test/logic/93-ddl-view-edge-cases.sqllogic +104 -0
- package/test/logic/93.1-view-error-paths.sqllogic +74 -0
- package/test/logic/93.2-view-mutation-pending.sqllogic +108 -0
- package/test/logic/93.3-view-mutation-or-clause.sqllogic +60 -0
- package/test/logic/93.4-view-mutation.sqllogic +4881 -0
- package/test/logic/93.4.1-view-mutation-partial-unique-cardinality.sqllogic +31 -0
- package/test/logic/93.5-authored-inverse.sqllogic +415 -0
- package/test/logic/93.6-set-op-flagless-write.sqllogic +862 -0
- package/test/logic/94-tvf-edge-cases.sqllogic +58 -0
- package/test/logic/94.1-limit-offset-edge-cases.sqllogic +109 -0
- package/test/logic/94.2-limit-offset-extras.sqllogic +98 -0
- package/test/logic/95-assertions.sqllogic +1417 -0
- package/test/logic/96-subquery-edge-cases.sqllogic +276 -0
- package/test/logic/97-json-function-edge-cases.sqllogic +633 -0
- package/test/logic/97.1-json-blob-and-special-values.sqllogic +92 -0
- package/test/logic/98-temporal-edge-cases.sqllogic +515 -0
- package/test/logic/99-conversion-edge-cases.sqllogic +325 -0
- package/test/logic/99.0.1-schema-index-listing.sqllogic +21 -0
- package/test/logic/99.1-cast-syntax-extras.sqllogic +167 -0
- package/test/logic/drop-unique-index.sqllogic +88 -0
- package/test/logic/pushdown-test.sqllogic +36 -0
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
-- Reserved `quereus.*` tag namespace validation (schema/reserved-tags.ts).
|
|
2
|
+
-- PoC wiring: `apply schema X` on a LOGICAL schema validates the reserved tags
|
|
3
|
+
-- on each logical table (`logical-table` site) and its constraints
|
|
4
|
+
-- (`logical-constraint` site) for shape + site. Unknown / mis-sited / malformed
|
|
5
|
+
-- keys fail the deploy loudly; an empty `quereus.lens.ack` rationale is only a
|
|
6
|
+
-- warning (deploy still succeeds). No reserved tag's *semantics* are read here.
|
|
7
|
+
|
|
8
|
+
-- Shared basis: a physical schema the logical schemas align against by name.
|
|
9
|
+
declare schema cars_basis {
|
|
10
|
+
table Car {
|
|
11
|
+
id integer primary key,
|
|
12
|
+
vin text
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
-- run
|
|
17
|
+
|
|
18
|
+
apply schema cars_basis;
|
|
19
|
+
|
|
20
|
+
-- run
|
|
21
|
+
|
|
22
|
+
insert into cars_basis.Car values (1, 'VIN001'), (2, 'VIN002');
|
|
23
|
+
|
|
24
|
+
-- run
|
|
25
|
+
|
|
26
|
+
-- ===================================
|
|
27
|
+
-- 1. Unknown reserved key on a logical table → error at apply
|
|
28
|
+
-- (`quereus.update.taget` is a typo of `target`)
|
|
29
|
+
-- ===================================
|
|
30
|
+
|
|
31
|
+
declare logical schema bad_unknown {
|
|
32
|
+
table Car {
|
|
33
|
+
id integer primary key,
|
|
34
|
+
vin text
|
|
35
|
+
} with tags ("quereus.update.taget" = 'Car')
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
-- run
|
|
39
|
+
|
|
40
|
+
apply schema bad_unknown;
|
|
41
|
+
-- error: unknown reserved tag
|
|
42
|
+
|
|
43
|
+
-- ===================================
|
|
44
|
+
-- 2. Mis-sited reserved key on a logical table → error at apply
|
|
45
|
+
-- (`quereus.lens.writable` is legal only on a logical column, never on the
|
|
46
|
+
-- logical table itself)
|
|
47
|
+
-- ===================================
|
|
48
|
+
|
|
49
|
+
declare logical schema bad_site {
|
|
50
|
+
table Car {
|
|
51
|
+
id integer primary key,
|
|
52
|
+
vin text
|
|
53
|
+
} with tags ("quereus.lens.writable" = true)
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
-- run
|
|
57
|
+
|
|
58
|
+
apply schema bad_site;
|
|
59
|
+
-- error: not allowed
|
|
60
|
+
|
|
61
|
+
-- ===================================
|
|
62
|
+
-- 2b. The retired `quereus.update.default_for.<col>` key → unknown at apply
|
|
63
|
+
-- (the first-class `with defaults (…)` view clause replaced it; a stray
|
|
64
|
+
-- occurrence is an unknown key now, no longer a mis-site)
|
|
65
|
+
-- ===================================
|
|
66
|
+
|
|
67
|
+
declare logical schema bad_retired {
|
|
68
|
+
table Car {
|
|
69
|
+
id integer primary key,
|
|
70
|
+
vin text
|
|
71
|
+
} with tags ("quereus.update.default_for.vin" = '0')
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
-- run
|
|
75
|
+
|
|
76
|
+
apply schema bad_retired;
|
|
77
|
+
-- error: unknown reserved tag
|
|
78
|
+
|
|
79
|
+
-- ===================================
|
|
80
|
+
-- 3. Empty lens.ack rationale → WARNING (deploy succeeds), not an error
|
|
81
|
+
-- ===================================
|
|
82
|
+
|
|
83
|
+
declare logical schema warn_ack {
|
|
84
|
+
table Car {
|
|
85
|
+
id integer primary key,
|
|
86
|
+
vin text
|
|
87
|
+
} with tags ("quereus.lens.ack.no-backing-index:vin" = '')
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
-- run
|
|
91
|
+
|
|
92
|
+
apply schema warn_ack;
|
|
93
|
+
|
|
94
|
+
-- run
|
|
95
|
+
|
|
96
|
+
-- Deploy succeeded despite the empty-rationale warning; reads work.
|
|
97
|
+
select * from warn_ack.Car order by id;
|
|
98
|
+
→ [{"id": 1, "vin": "VIN001"}, {"id": 2, "vin": "VIN002"}]
|
|
99
|
+
|
|
100
|
+
-- ===================================
|
|
101
|
+
-- 4. Valid lens.ack at a logical table → no diagnostic; deploy succeeds
|
|
102
|
+
-- ===================================
|
|
103
|
+
|
|
104
|
+
declare logical schema ok_ack {
|
|
105
|
+
table Car {
|
|
106
|
+
id integer primary key,
|
|
107
|
+
vin text
|
|
108
|
+
} with tags ("quereus.lens.ack.no-backing-index:vin" = 'low-write table; commit-time scan is acceptable')
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
-- run
|
|
112
|
+
|
|
113
|
+
apply schema ok_ack;
|
|
114
|
+
|
|
115
|
+
-- run
|
|
116
|
+
|
|
117
|
+
select vin from ok_ack.Car where id = 1;
|
|
118
|
+
→ [{"vin": "VIN001"}]
|
|
119
|
+
|
|
120
|
+
-- ===================================
|
|
121
|
+
-- 5. Valid lens.ack on a logical CONSTRAINT → deploy succeeds
|
|
122
|
+
-- ===================================
|
|
123
|
+
|
|
124
|
+
declare logical schema ok_ack_con {
|
|
125
|
+
table Car {
|
|
126
|
+
id integer primary key,
|
|
127
|
+
vin text,
|
|
128
|
+
constraint uq_vin unique (vin) with tags ("quereus.lens.ack.no-backing-index:vin" = 'acceptable')
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
-- run
|
|
133
|
+
|
|
134
|
+
apply schema ok_ack_con;
|
|
135
|
+
|
|
136
|
+
-- run
|
|
137
|
+
|
|
138
|
+
select * from ok_ack_con.Car order by id;
|
|
139
|
+
→ [{"id": 1, "vin": "VIN001"}, {"id": 2, "vin": "VIN002"}]
|
|
140
|
+
|
|
141
|
+
-- ===================================
|
|
142
|
+
-- 6. Free-form user tag on a logical table → untouched, deploy succeeds
|
|
143
|
+
-- ===================================
|
|
144
|
+
|
|
145
|
+
declare logical schema user_tag {
|
|
146
|
+
table Car {
|
|
147
|
+
id integer primary key,
|
|
148
|
+
vin text
|
|
149
|
+
} with tags (display_name = 'Cars')
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
-- run
|
|
153
|
+
|
|
154
|
+
apply schema user_tag;
|
|
155
|
+
|
|
156
|
+
-- run
|
|
157
|
+
|
|
158
|
+
select vin from user_tag.Car order by id;
|
|
159
|
+
→ [{"vin": "VIN001"}, {"vin": "VIN002"}]
|
|
160
|
+
|
|
161
|
+
-- ===================================
|
|
162
|
+
-- 7. Base-table DML statement tags (`insert/update/delete … with tags (…)`)
|
|
163
|
+
-- validate at the `dml-stmt` site at builder entry — the same hard error
|
|
164
|
+
-- the view-mediated path raises (93.4-view-mutation.sqllogic covers that
|
|
165
|
+
-- path). No reserved key is currently legal at the DML-statement site, so
|
|
166
|
+
-- every `quereus.*` key there is rejected: unknown key →
|
|
167
|
+
-- unknown-reserved-tag; known-but-mis-sited key → tag-not-allowed-here.
|
|
168
|
+
-- Free-form keys pass untouched. A rejected statement writes nothing.
|
|
169
|
+
-- ===================================
|
|
170
|
+
|
|
171
|
+
create table dml_tags (id integer primary key, note text);
|
|
172
|
+
|
|
173
|
+
-- run
|
|
174
|
+
|
|
175
|
+
insert into dml_tags values (1, 'seed');
|
|
176
|
+
|
|
177
|
+
-- run
|
|
178
|
+
|
|
179
|
+
-- unknown reserved key on a base-table INSERT → error; nothing written.
|
|
180
|
+
insert into dml_tags with tags ("quereus.bogus" = 1) values (2, 'x');
|
|
181
|
+
-- error: unknown reserved tag
|
|
182
|
+
|
|
183
|
+
select * from dml_tags order by id;
|
|
184
|
+
→ [{"id": 1, "note": "seed"}]
|
|
185
|
+
|
|
186
|
+
-- the retired statement-level `quereus.update.default_for.<col>` key is unknown
|
|
187
|
+
-- on a base-table UPDATE too (the view path already rejects it); row unchanged.
|
|
188
|
+
update dml_tags with tags ("quereus.update.default_for.note" = '0') set note = 'changed' where id = 1;
|
|
189
|
+
-- error: unknown reserved tag
|
|
190
|
+
|
|
191
|
+
select note from dml_tags where id = 1;
|
|
192
|
+
→ [{"note": "seed"}]
|
|
193
|
+
|
|
194
|
+
-- a KNOWN reserved key mis-sited on a DML statement → tag-not-allowed-here
|
|
195
|
+
-- (distinct from the unknown-key error); row still present.
|
|
196
|
+
delete from dml_tags with tags ("quereus.id" = 'x') where id = 1;
|
|
197
|
+
-- error: not allowed on a DML statement
|
|
198
|
+
|
|
199
|
+
select count(*) as n from dml_tags;
|
|
200
|
+
→ [{"n": 1}]
|
|
201
|
+
|
|
202
|
+
-- free-form statement tags (outside quereus.*) are untouched — the write lands.
|
|
203
|
+
insert into dml_tags with tags (provenance = 'import', audit = true) values (3, 'y');
|
|
204
|
+
|
|
205
|
+
-- run
|
|
206
|
+
|
|
207
|
+
select id from dml_tags order by id;
|
|
208
|
+
→ [{"id": 1}, {"id": 3}]
|
|
209
|
+
|
|
210
|
+
-- mixed free-form + reserved still fails atomically — nothing written.
|
|
211
|
+
insert into dml_tags with tags (audit = true, "quereus.bogus" = 1) values (4, 'z');
|
|
212
|
+
-- error: unknown reserved tag
|
|
213
|
+
|
|
214
|
+
select id from dml_tags order by id;
|
|
215
|
+
→ [{"id": 1}, {"id": 3}]
|
|
216
|
+
|
|
217
|
+
-- nested DML: a reserved statement tag on DML inside a CTE validates at the
|
|
218
|
+
-- nested statement's own builder entry.
|
|
219
|
+
with w as (insert into dml_tags with tags ("quereus.bogus" = 1) values (5, 'c') returning *) select id from w;
|
|
220
|
+
-- error: unknown reserved tag
|
|
221
|
+
|
|
222
|
+
select id from dml_tags order by id;
|
|
223
|
+
→ [{"id": 1}, {"id": 3}]
|
|
224
|
+
|
|
225
|
+
-- DML as INSERT source: the inner statement's reserved tag validates at the
|
|
226
|
+
-- inner statement's own builder entry; neither table is written.
|
|
227
|
+
create table dml_sink (id integer primary key, note text);
|
|
228
|
+
|
|
229
|
+
-- run
|
|
230
|
+
|
|
231
|
+
insert into dml_sink insert into dml_tags with tags ("quereus.bogus" = 1) values (9, 'q') returning *;
|
|
232
|
+
-- error: unknown reserved tag
|
|
233
|
+
|
|
234
|
+
select count(*) as n from dml_sink;
|
|
235
|
+
→ [{"n": 0}]
|
|
236
|
+
|
|
237
|
+
select id from dml_tags order by id;
|
|
238
|
+
→ [{"id": 1}, {"id": 3}]
|
|
239
|
+
|
|
240
|
+
-- view-mediated write with free-form statement tags: the single-source lowering
|
|
241
|
+
-- clones the statement (tags ride along) and re-enters the base builder, where
|
|
242
|
+
-- re-validation is a no-op — the write lands exactly once.
|
|
243
|
+
create view dml_v as select id, note from dml_tags;
|
|
244
|
+
|
|
245
|
+
-- run
|
|
246
|
+
|
|
247
|
+
insert into dml_v with tags (audit = true) values (7, 'via view');
|
|
248
|
+
|
|
249
|
+
-- run
|
|
250
|
+
|
|
251
|
+
select id from dml_tags order by id;
|
|
252
|
+
→ [{"id": 1}, {"id": 3}, {"id": 7}]
|
|
@@ -0,0 +1,329 @@
|
|
|
1
|
+
-- 53.1-materialized-view-write-through.sqllogic — DML targeting a materialized-view
|
|
2
|
+
-- *name* is rewritten to target the MV's source table (write-through via view
|
|
3
|
+
-- updateability) and re-planned through the ordinary base-table builder. The source
|
|
4
|
+
-- write then fires the existing row-time maintenance hook, so the backing is brought
|
|
5
|
+
-- into sync within the same statement/transaction: a subsequent read of the MV sees
|
|
6
|
+
-- the write (reads-own-writes), and a rollback reverts source + backing in lockstep.
|
|
7
|
+
--
|
|
8
|
+
-- A write-through to an MV is observably identical to writing the source and reading
|
|
9
|
+
-- the MV. Modeled on the plain-view 93.4-view-mutation.sqllogic; the per-column
|
|
10
|
+
-- writeability rules (passthrough writeable, computed read-only) and RETURNING
|
|
11
|
+
-- rejection are inherited verbatim from view updateability.
|
|
12
|
+
|
|
13
|
+
-- ===================================
|
|
14
|
+
-- 1. Round-trip (insert / update / delete) through a passthrough MV.
|
|
15
|
+
-- ===================================
|
|
16
|
+
|
|
17
|
+
create table t (id integer primary key, x integer);
|
|
18
|
+
insert into t values (1, 10), (2, 20);
|
|
19
|
+
create materialized view m as select id, x from t;
|
|
20
|
+
|
|
21
|
+
select id, x from m order by id;
|
|
22
|
+
→ [{"id":1,"x":10},{"id":2,"x":20}]
|
|
23
|
+
|
|
24
|
+
-- INSERT through the MV lands in the source and is reflected in the MV
|
|
25
|
+
insert into m (id, x) values (3, 30);
|
|
26
|
+
select id, x from m order by id;
|
|
27
|
+
→ [{"id":1,"x":10},{"id":2,"x":20},{"id":3,"x":30}]
|
|
28
|
+
select id, x from t order by id;
|
|
29
|
+
→ [{"id":1,"x":10},{"id":2,"x":20},{"id":3,"x":30}]
|
|
30
|
+
|
|
31
|
+
-- UPDATE through the MV (a projected column) routes to the source and re-keys the backing
|
|
32
|
+
update m set x = 99 where id = 2;
|
|
33
|
+
select id, x from m order by id;
|
|
34
|
+
→ [{"id":1,"x":10},{"id":2,"x":99},{"id":3,"x":30}]
|
|
35
|
+
|
|
36
|
+
-- DELETE through the MV removes the source row and its backing entry
|
|
37
|
+
delete from m where id = 1;
|
|
38
|
+
select id, x from m order by id;
|
|
39
|
+
→ [{"id":2,"x":99},{"id":3,"x":30}]
|
|
40
|
+
|
|
41
|
+
-- ===================================
|
|
42
|
+
-- 2. Reads-own-writes + rollback in lockstep. A write through the MV inside an open
|
|
43
|
+
-- transaction is visible to a later read of the MV before commit, and rollback
|
|
44
|
+
-- discards BOTH the source write and the backing delta.
|
|
45
|
+
-- ===================================
|
|
46
|
+
|
|
47
|
+
begin;
|
|
48
|
+
insert into m (id, x) values (4, 40);
|
|
49
|
+
-- reads-own-writes: the write is visible through the MV mid-transaction
|
|
50
|
+
select id, x from m order by id;
|
|
51
|
+
→ [{"id":2,"x":99},{"id":3,"x":30},{"id":4,"x":40}]
|
|
52
|
+
rollback;
|
|
53
|
+
-- rollback reverts the source AND the backing together
|
|
54
|
+
select id, x from m order by id;
|
|
55
|
+
→ [{"id":2,"x":99},{"id":3,"x":30}]
|
|
56
|
+
select id, x from t order by id;
|
|
57
|
+
→ [{"id":2,"x":99},{"id":3,"x":30}]
|
|
58
|
+
|
|
59
|
+
-- a committed write-through persists
|
|
60
|
+
begin;
|
|
61
|
+
insert into m (id, x) values (5, 50);
|
|
62
|
+
commit;
|
|
63
|
+
select id, x from m order by id;
|
|
64
|
+
→ [{"id":2,"x":99},{"id":3,"x":30},{"id":5,"x":50}]
|
|
65
|
+
|
|
66
|
+
-- ===================================
|
|
67
|
+
-- 3. Rename / reorder projection — the rewrite maps each MV column to its base column.
|
|
68
|
+
-- ===================================
|
|
69
|
+
|
|
70
|
+
create table u (uid integer primary key, name text);
|
|
71
|
+
insert into u values (1, 'Ann');
|
|
72
|
+
create materialized view uv as select uid as user_id, name as full_name from u;
|
|
73
|
+
select user_id, full_name from uv order by user_id;
|
|
74
|
+
→ [{"user_id":1,"full_name":"Ann"}]
|
|
75
|
+
|
|
76
|
+
insert into uv (user_id, full_name) values (2, 'Bo');
|
|
77
|
+
update uv set full_name = 'Bob' where user_id = 2;
|
|
78
|
+
select user_id, full_name from uv order by user_id;
|
|
79
|
+
→ [{"user_id":1,"full_name":"Ann"},{"user_id":2,"full_name":"Bob"}]
|
|
80
|
+
-- the writes landed on the base under the base column names
|
|
81
|
+
select uid, name from u order by uid;
|
|
82
|
+
→ [{"uid":1,"name":"Ann"},{"uid":2,"name":"Bob"}]
|
|
83
|
+
|
|
84
|
+
-- ===================================
|
|
85
|
+
-- 4. Filtered MV (equality predicate on a projected column): constant-FD default for
|
|
86
|
+
-- an omitted predicate column, predicate-scope transition on update, and a
|
|
87
|
+
-- plan-time predicate-contradiction rejection.
|
|
88
|
+
-- ===================================
|
|
89
|
+
|
|
90
|
+
create table task (id integer primary key, x integer, status text);
|
|
91
|
+
insert into task values (1, 10, 'open'), (2, 20, 'open'), (3, 30, 'closed');
|
|
92
|
+
create materialized view opentasks as select id, x, status from task where status = 'open';
|
|
93
|
+
select id, x, status from opentasks order by id;
|
|
94
|
+
→ [{"id":1,"x":10,"status":"open"},{"id":2,"x":20,"status":"open"}]
|
|
95
|
+
|
|
96
|
+
-- INSERT omitting the predicate column: the selection predicate supplies status='open'
|
|
97
|
+
-- on the base via the constant-FD path
|
|
98
|
+
insert into opentasks (id, x) values (4, 40);
|
|
99
|
+
select id, x, status from opentasks order by id;
|
|
100
|
+
→ [{"id":1,"x":10,"status":"open"},{"id":2,"x":20,"status":"open"},{"id":4,"x":40,"status":"open"}]
|
|
101
|
+
-- the base row carries the defaulted predicate value
|
|
102
|
+
select id, status from task where id = 4;
|
|
103
|
+
→ [{"id":4,"status":"open"}]
|
|
104
|
+
|
|
105
|
+
-- INSERT that provably contradicts the selection predicate is rejected at plan time
|
|
106
|
+
insert into opentasks (id, x, status) values (5, 50, 'closed');
|
|
107
|
+
-- error: contradicts its selection predicate
|
|
108
|
+
|
|
109
|
+
-- UPDATE carrying a row out of the WHERE scope removes it from the MV (maintenance
|
|
110
|
+
-- predicate-scope transition: delete old image, no new image upserted); the base row
|
|
111
|
+
-- survives with its new value
|
|
112
|
+
update opentasks set status = 'closed' where id = 1;
|
|
113
|
+
select id, x, status from opentasks order by id;
|
|
114
|
+
→ [{"id":2,"x":20,"status":"open"},{"id":4,"x":40,"status":"open"}]
|
|
115
|
+
select id, status from task where id = 1;
|
|
116
|
+
→ [{"id":1,"status":"closed"}]
|
|
117
|
+
|
|
118
|
+
-- ===================================
|
|
119
|
+
-- 5. Delete identity by a non-PK projected column removes exactly the matching backing
|
|
120
|
+
-- row(s). The projection includes the source PK, so the base delete is exact.
|
|
121
|
+
-- ===================================
|
|
122
|
+
|
|
123
|
+
create table d (id integer primary key, label text, x integer);
|
|
124
|
+
insert into d values (1, 'a', 10), (2, 'b', 20), (3, 'a', 30);
|
|
125
|
+
create materialized view dv as select id, label, x from d;
|
|
126
|
+
delete from dv where label = 'a';
|
|
127
|
+
select id, label, x from dv order by id;
|
|
128
|
+
→ [{"id":2,"label":"b","x":20}]
|
|
129
|
+
select id, label from d order by id;
|
|
130
|
+
→ [{"id":2,"label":"b"}]
|
|
131
|
+
|
|
132
|
+
-- ===================================
|
|
133
|
+
-- 6. RETURNING through an MV is shipped (inherited from view updateability — an MV
|
|
134
|
+
-- is a single-source projection, so the rewrite carries the RETURNING onto the
|
|
135
|
+
-- base op). The deleted view-projected row is returned (`*` → all view columns,
|
|
136
|
+
-- OLD image).
|
|
137
|
+
-- ===================================
|
|
138
|
+
|
|
139
|
+
create table r (id integer primary key, x integer);
|
|
140
|
+
insert into r values (1, 10);
|
|
141
|
+
create materialized view rv as select id, x from r;
|
|
142
|
+
delete from rv where id = 1 returning *;
|
|
143
|
+
→ [{"id":1,"x":10}]
|
|
144
|
+
|
|
145
|
+
-- ===================================
|
|
146
|
+
-- 7. Per-column lineage on the MV write-through spine (the single-source spine, so
|
|
147
|
+
-- it consumes inverses exactly as a plain view does): an INVERSE-profile column
|
|
148
|
+
-- (`y = x + 1`) is writable and stores the inverted base value, an OPAQUE column
|
|
149
|
+
-- (`z = x * 2`) is read-only (computed/non-invertible diagnostic), reads are
|
|
150
|
+
-- unaffected, and a write to the passthrough column still propagates. Every write
|
|
151
|
+
-- re-derives the computed columns via maintenance (reads-own-writes).
|
|
152
|
+
-- (Needs materialized-view-rowtime-expression-projections so the body is creatable.)
|
|
153
|
+
-- ===================================
|
|
154
|
+
|
|
155
|
+
create table e (id integer primary key, x integer);
|
|
156
|
+
insert into e values (1, 10), (2, 20);
|
|
157
|
+
create materialized view ev as select id, x, x + 1 as y, x * 2 as z from e;
|
|
158
|
+
select id, x, y, z from ev order by id;
|
|
159
|
+
→ [{"id":1,"x":10,"y":11,"z":20},{"id":2,"x":20,"y":21,"z":40}]
|
|
160
|
+
|
|
161
|
+
-- a write to the OPAQUE column z is rejected (read-only / non-invertible)
|
|
162
|
+
update ev set z = 99 where id = 1;
|
|
163
|
+
-- error: non-invertible
|
|
164
|
+
|
|
165
|
+
-- a write to the INVERSE-profile column y now propagates: it stores the inverted
|
|
166
|
+
-- base value (y = 99 ⇒ x = 98) and the computed columns re-derive (z = 196).
|
|
167
|
+
update ev set y = 99 where id = 1;
|
|
168
|
+
select id, x, y, z from ev order by id;
|
|
169
|
+
→ [{"id":1,"x":98,"y":99,"z":196},{"id":2,"x":20,"y":21,"z":40}]
|
|
170
|
+
|
|
171
|
+
-- a write to the passthrough column still propagates; the computed columns re-derive
|
|
172
|
+
update ev set x = 100 where id = 1;
|
|
173
|
+
select id, x, y, z from ev order by id;
|
|
174
|
+
→ [{"id":1,"x":100,"y":101,"z":200},{"id":2,"x":20,"y":21,"z":40}]
|
|
175
|
+
|
|
176
|
+
-- insert specifying only the passthrough columns works; y/z are derived by maintenance
|
|
177
|
+
insert into ev (id, x) values (3, 30);
|
|
178
|
+
select id, x, y, z from ev order by id;
|
|
179
|
+
→ [{"id":1,"x":100,"y":101,"z":200},{"id":2,"x":20,"y":21,"z":40},{"id":3,"x":30,"y":31,"z":60}]
|
|
180
|
+
|
|
181
|
+
-- ===================================
|
|
182
|
+
-- 8. Bulk multi-row write-through — an INSERT…SELECT source, a multi-row UPDATE, and a
|
|
183
|
+
-- multi-row DELETE all produce correct backing contents under per-statement
|
|
184
|
+
-- maintenance batching.
|
|
185
|
+
-- ===================================
|
|
186
|
+
|
|
187
|
+
create table b (id integer primary key, x integer);
|
|
188
|
+
insert into b values (1, 1);
|
|
189
|
+
create materialized view bv as select id, x from b;
|
|
190
|
+
|
|
191
|
+
create table src (id integer primary key, x integer);
|
|
192
|
+
insert into src values (10, 100), (11, 110), (12, 120);
|
|
193
|
+
|
|
194
|
+
-- INSERT … SELECT through the MV
|
|
195
|
+
insert into bv select id, x from src;
|
|
196
|
+
select id, x from bv order by id;
|
|
197
|
+
→ [{"id":1,"x":1},{"id":10,"x":100},{"id":11,"x":110},{"id":12,"x":120}]
|
|
198
|
+
|
|
199
|
+
-- multi-row UPDATE through the MV
|
|
200
|
+
update bv set x = x + 1000 where id >= 10;
|
|
201
|
+
select id, x from bv order by id;
|
|
202
|
+
→ [{"id":1,"x":1},{"id":10,"x":1100},{"id":11,"x":1110},{"id":12,"x":1120}]
|
|
203
|
+
|
|
204
|
+
-- multi-row DELETE through the MV
|
|
205
|
+
delete from bv where id >= 11;
|
|
206
|
+
select id, x from bv order by id;
|
|
207
|
+
→ [{"id":1,"x":1},{"id":10,"x":1100}]
|
|
208
|
+
|
|
209
|
+
-- ===================================
|
|
210
|
+
-- 9. MV-over-MV write-through. Write-through to a level-1 MV over a real table routes
|
|
211
|
+
-- to the base AND cascades to the level-2 MV. Write-through to the level-2 MV
|
|
212
|
+
-- itself (whose source is a materialized view) is rejected cleanly — its rewrite
|
|
213
|
+
-- would target the inner MV's read-only backing table. (The source→backing
|
|
214
|
+
-- maintenance cascade is the read/maintain direction and is unaffected.)
|
|
215
|
+
-- ===================================
|
|
216
|
+
|
|
217
|
+
create table base (id integer primary key, x integer);
|
|
218
|
+
insert into base values (1, 10);
|
|
219
|
+
create materialized view inner_mv as select id, x from base;
|
|
220
|
+
create materialized view outer_mv as select id, x from inner_mv;
|
|
221
|
+
|
|
222
|
+
-- write-through to the level-1 MV routes to base and cascades to the level-2 MV
|
|
223
|
+
insert into inner_mv (id, x) values (2, 20);
|
|
224
|
+
select id, x from outer_mv order by id;
|
|
225
|
+
→ [{"id":1,"x":10},{"id":2,"x":20}]
|
|
226
|
+
|
|
227
|
+
-- write-through to the level-2 MV (source is a materialized view) is rejected
|
|
228
|
+
insert into outer_mv (id, x) values (3, 30);
|
|
229
|
+
-- error: reads a materialized view
|
|
230
|
+
update outer_mv set x = 99 where id = 1;
|
|
231
|
+
-- error: reads a materialized view
|
|
232
|
+
delete from outer_mv where id = 1;
|
|
233
|
+
-- error: reads a materialized view
|
|
234
|
+
|
|
235
|
+
-- the rejected writes changed nothing; the chain is intact
|
|
236
|
+
select id, x from outer_mv order by id;
|
|
237
|
+
→ [{"id":1,"x":10},{"id":2,"x":20}]
|
|
238
|
+
|
|
239
|
+
-- ===================================
|
|
240
|
+
-- 10. Plain view over a materialized view — the same guard's broader reach. A plain
|
|
241
|
+
-- `view ... select ... from <mv>` resolves its body source to the MV's backing
|
|
242
|
+
-- table at plan time, so a write-through would target that read-only backing.
|
|
243
|
+
-- Write-through is rejected with the same diagnostic as the MV-over-MV case
|
|
244
|
+
-- (this closes a pre-existing latent hole, not just the MV path). Reads through
|
|
245
|
+
-- the plain view are unaffected.
|
|
246
|
+
-- ===================================
|
|
247
|
+
|
|
248
|
+
-- inner_mv from §9 still holds {1,10},{2,20}
|
|
249
|
+
create view pv as select id, x from inner_mv;
|
|
250
|
+
select id, x from pv order by id;
|
|
251
|
+
→ [{"id":1,"x":10},{"id":2,"x":20}]
|
|
252
|
+
|
|
253
|
+
insert into pv (id, x) values (4, 40);
|
|
254
|
+
-- error: reads a materialized view
|
|
255
|
+
update pv set x = 99 where id = 1;
|
|
256
|
+
-- error: reads a materialized view
|
|
257
|
+
delete from pv where id = 1;
|
|
258
|
+
-- error: reads a materialized view
|
|
259
|
+
|
|
260
|
+
-- the rejected writes changed nothing
|
|
261
|
+
select id, x from pv order by id;
|
|
262
|
+
→ [{"id":1,"x":10},{"id":2,"x":20}]
|
|
263
|
+
|
|
264
|
+
-- ===================================
|
|
265
|
+
-- 11. Aggregate (non-updatable) body. An aggregate-bodied MV is creatable and
|
|
266
|
+
-- maintained (the residual-recompute arm), but its body is NOT row-decomposable
|
|
267
|
+
-- for write-through, so user DML against the MV name is rejected at PLAN time.
|
|
268
|
+
-- The diagnostic names the target as a *materialized view* (not a plain "view") —
|
|
269
|
+
-- the body-shape reject threads the target's kind. The reject is plan-time, so
|
|
270
|
+
-- the MV contents are untouched and the source stays directly writable + maintained.
|
|
271
|
+
-- (Runs in both memory and store suites; the 'x'/'y' group keys carry no
|
|
272
|
+
-- case-variant collision, so the store's NOCASE backing-key default is moot.)
|
|
273
|
+
-- ===================================
|
|
274
|
+
|
|
275
|
+
create table words (id integer primary key, w text);
|
|
276
|
+
insert into words values (1, 'x'), (2, 'y'), (3, 'x');
|
|
277
|
+
create materialized view wcount as select w, count(*) as n from words group by w;
|
|
278
|
+
select w, n from wcount order by w;
|
|
279
|
+
→ [{"w":"x","n":2},{"w":"y","n":1}]
|
|
280
|
+
|
|
281
|
+
-- insert / update / delete against the aggregate MV are all rejected at plan time,
|
|
282
|
+
-- naming it a materialized view
|
|
283
|
+
insert into wcount (w, n) values ('z', 1);
|
|
284
|
+
-- error: cannot write through materialized view
|
|
285
|
+
update wcount set n = 99 where w = 'x';
|
|
286
|
+
-- error: cannot write through materialized view
|
|
287
|
+
delete from wcount where w = 'y';
|
|
288
|
+
-- error: cannot write through materialized view
|
|
289
|
+
|
|
290
|
+
-- the rejected writes changed nothing
|
|
291
|
+
select w, n from wcount order by w;
|
|
292
|
+
→ [{"w":"x","n":2},{"w":"y","n":1}]
|
|
293
|
+
|
|
294
|
+
-- the source remains directly writable and the MV maintains incrementally
|
|
295
|
+
insert into words values (4, 'y');
|
|
296
|
+
select w, n from wcount order by w;
|
|
297
|
+
→ [{"w":"x","n":2},{"w":"y","n":2}]
|
|
298
|
+
|
|
299
|
+
-- ===================================
|
|
300
|
+
-- 12. Subquery-in-FROM body. An MV whose body wraps its base in a derived-table
|
|
301
|
+
-- subquery is creatable + maintained, but write-through rejects it at the
|
|
302
|
+
-- single-base-source branch (the inner filters/projections live in the plan,
|
|
303
|
+
-- not in the rewrite-driving selectAst). That branch — distinct from the
|
|
304
|
+
-- aggregate (classifyViewBody) reject in § 11 — must ALSO name the target a
|
|
305
|
+
-- *materialized view*, not a plain "view": every body-shape reject in
|
|
306
|
+
-- analyzeView threads the target's kind, so a maintained table reaching this
|
|
307
|
+
-- branch is not misnamed. Plan-time reject; MV contents untouched.
|
|
308
|
+
-- ===================================
|
|
309
|
+
|
|
310
|
+
create table nums (id integer primary key, v integer);
|
|
311
|
+
insert into nums values (1, 10), (2, 20);
|
|
312
|
+
create materialized view sqmv as select id, v from (select id, v from nums);
|
|
313
|
+
select id, v from sqmv order by id;
|
|
314
|
+
→ [{"id":1,"v":10},{"id":2,"v":20}]
|
|
315
|
+
|
|
316
|
+
-- write-through is rejected at the single-base-source branch, naming it a materialized view
|
|
317
|
+
insert into sqmv (id, v) values (3, 30);
|
|
318
|
+
-- error: cannot write through materialized view
|
|
319
|
+
update sqmv set v = 99 where id = 1;
|
|
320
|
+
-- error: cannot write through materialized view
|
|
321
|
+
delete from sqmv where id = 2;
|
|
322
|
+
-- error: cannot write through materialized view
|
|
323
|
+
|
|
324
|
+
-- the rejected writes changed nothing; the source stays writable + maintained
|
|
325
|
+
select id, v from sqmv order by id;
|
|
326
|
+
→ [{"id":1,"v":10},{"id":2,"v":20}]
|
|
327
|
+
insert into nums values (3, 30);
|
|
328
|
+
select id, v from sqmv order by id;
|
|
329
|
+
→ [{"id":1,"v":10},{"id":2,"v":20},{"id":3,"v":30}]
|