@quereus/quereus 4.20.1 → 4.20.3
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/schema/schema-differ.d.ts.map +1 -1
- package/dist/src/schema/schema-differ.js +17 -69
- package/dist/src/schema/schema-differ.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 +210 -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,34 @@
|
|
|
1
|
+
-- adapted from SQLite test/index.test, test/index1.test, test/expridx.test ideas
|
|
2
|
+
-- expression indexes: CREATE INDEX ... ON tab(<expr>)
|
|
3
|
+
-- Quereus's parser accepts expressions in indexed-column lists, but the schema
|
|
4
|
+
-- manager rejects them at index-build time. This fixture pins the rejection so
|
|
5
|
+
-- that future support can flip the assertions in one place.
|
|
6
|
+
--
|
|
7
|
+
-- requires-capability: standalone-index-ddl
|
|
8
|
+
|
|
9
|
+
-- =====================================================
|
|
10
|
+
-- 1. Function-call expression in CREATE INDEX is rejected
|
|
11
|
+
-- =====================================================
|
|
12
|
+
create table e_upper (id integer primary key, name text);
|
|
13
|
+
create index ix_e_upper_name on e_upper(upper(name));
|
|
14
|
+
-- error: not supported
|
|
15
|
+
|
|
16
|
+
drop table e_upper;
|
|
17
|
+
|
|
18
|
+
-- =====================================================
|
|
19
|
+
-- 2. Arithmetic expression in CREATE INDEX is rejected
|
|
20
|
+
-- =====================================================
|
|
21
|
+
create table e_arith (id integer primary key, a integer, b integer);
|
|
22
|
+
create index ix_e_arith_sum on e_arith(a + b);
|
|
23
|
+
-- error: not supported
|
|
24
|
+
|
|
25
|
+
drop table e_arith;
|
|
26
|
+
|
|
27
|
+
-- =====================================================
|
|
28
|
+
-- 3. UNIQUE expression index is rejected at the same point
|
|
29
|
+
-- =====================================================
|
|
30
|
+
create table e_uniq (id integer primary key, name text);
|
|
31
|
+
create unique index ix_e_uniq_lower on e_uniq(lower(name));
|
|
32
|
+
-- error: not supported
|
|
33
|
+
|
|
34
|
+
drop table e_uniq;
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
-- adapted from SQLite test/descidx1.test, descidx2.test, descidx3.test
|
|
2
|
+
-- DESC indexes for output ordering. Companion to 40.1-pk-desc-direction (PK DESC)
|
|
3
|
+
-- and 10.5-indexes (single-column DESC creation). Pins composite mixed-direction
|
|
4
|
+
-- indexes, NULL ordering through DESC indexes, and range queries on DESC indexes.
|
|
5
|
+
--
|
|
6
|
+
-- requires-capability: standalone-index-ddl
|
|
7
|
+
|
|
8
|
+
-- =====================================================
|
|
9
|
+
-- 1. Single-column DESC index — descending traversal
|
|
10
|
+
-- =====================================================
|
|
11
|
+
create table d_one (id integer primary key, score integer);
|
|
12
|
+
insert into d_one values (1, 30);
|
|
13
|
+
insert into d_one values (2, 10);
|
|
14
|
+
insert into d_one values (3, 50);
|
|
15
|
+
insert into d_one values (4, 20);
|
|
16
|
+
insert into d_one values (5, 40);
|
|
17
|
+
|
|
18
|
+
create index ix_d_one_score on d_one(score desc);
|
|
19
|
+
|
|
20
|
+
-- ORDER BY DESC matches the index direction
|
|
21
|
+
select id, score from d_one order by score desc;
|
|
22
|
+
→ [{"id":3,"score":50},{"id":5,"score":40},{"id":1,"score":30},{"id":4,"score":20},{"id":2,"score":10}]
|
|
23
|
+
|
|
24
|
+
-- ORDER BY ASC also correct (engine may reverse-scan or sort, either way result is right)
|
|
25
|
+
select id, score from d_one order by score;
|
|
26
|
+
→ [{"id":2,"score":10},{"id":4,"score":20},{"id":1,"score":30},{"id":5,"score":40},{"id":3,"score":50}]
|
|
27
|
+
|
|
28
|
+
drop table d_one;
|
|
29
|
+
|
|
30
|
+
-- =====================================================
|
|
31
|
+
-- 2. Composite mixed-direction index (ASC, DESC)
|
|
32
|
+
-- =====================================================
|
|
33
|
+
create table d_mix (id integer primary key, category text, score integer);
|
|
34
|
+
insert into d_mix values (1, 'a', 10);
|
|
35
|
+
insert into d_mix values (2, 'a', 30);
|
|
36
|
+
insert into d_mix values (3, 'a', 20);
|
|
37
|
+
insert into d_mix values (4, 'b', 5);
|
|
38
|
+
insert into d_mix values (5, 'b', 25);
|
|
39
|
+
|
|
40
|
+
create index ix_d_mix on d_mix(category asc, score desc);
|
|
41
|
+
|
|
42
|
+
-- ORDER BY matching the index direction exactly
|
|
43
|
+
select id, category, score from d_mix order by category asc, score desc;
|
|
44
|
+
→ [{"id":2,"category":"a","score":30},{"id":3,"category":"a","score":20},{"id":1,"category":"a","score":10},{"id":5,"category":"b","score":25},{"id":4,"category":"b","score":5}]
|
|
45
|
+
|
|
46
|
+
-- Equality on the leading key followed by DESC scan of the trailing key
|
|
47
|
+
select id, score from d_mix where category = 'a' order by score desc;
|
|
48
|
+
→ [{"id":2,"score":30},{"id":3,"score":20},{"id":1,"score":10}]
|
|
49
|
+
|
|
50
|
+
drop table d_mix;
|
|
51
|
+
|
|
52
|
+
-- =====================================================
|
|
53
|
+
-- 3. DESC index with NULLs
|
|
54
|
+
-- =====================================================
|
|
55
|
+
create table d_null (id integer primary key, val text null);
|
|
56
|
+
insert into d_null values (1, 'z');
|
|
57
|
+
insert into d_null values (2, null);
|
|
58
|
+
insert into d_null values (3, 'a');
|
|
59
|
+
insert into d_null values (4, null);
|
|
60
|
+
insert into d_null values (5, 'm');
|
|
61
|
+
|
|
62
|
+
create index ix_d_null on d_null(val desc);
|
|
63
|
+
|
|
64
|
+
-- Bare DESC sort. The engine places NULLs FIRST for BOTH directions -- placement is
|
|
65
|
+
-- absolute, never conditioned on ASC/DESC. A DESC index walk emits them LAST, so the
|
|
66
|
+
-- index must decline the ordering claim here and leave the Sort in place; the answer is
|
|
67
|
+
-- the same with or without ix_d_null.
|
|
68
|
+
select val from d_null order by val desc;
|
|
69
|
+
→ [{"val":null},{"val":null},{"val":"z"},{"val":"m"},{"val":"a"}]
|
|
70
|
+
|
|
71
|
+
-- A NULL-excluding filter evicts every NULL, so the DESC index may claim the ordering
|
|
72
|
+
-- again -- the exception that keeps `where val is not null order by val desc` fast.
|
|
73
|
+
select val from d_null where val is not null order by val desc;
|
|
74
|
+
→ [{"val":"z"},{"val":"m"},{"val":"a"}]
|
|
75
|
+
|
|
76
|
+
-- Explicit NULLs FIRST under DESC
|
|
77
|
+
select val from d_null order by val desc nulls first;
|
|
78
|
+
→ [{"val":null},{"val":null},{"val":"z"},{"val":"m"},{"val":"a"}]
|
|
79
|
+
|
|
80
|
+
-- Explicit NULLs LAST under DESC
|
|
81
|
+
select val from d_null order by val desc nulls last;
|
|
82
|
+
→ [{"val":"z"},{"val":"m"},{"val":"a"},{"val":null},{"val":null}]
|
|
83
|
+
|
|
84
|
+
drop table d_null;
|
|
85
|
+
|
|
86
|
+
-- =====================================================
|
|
87
|
+
-- 4. Range scan on DESC index
|
|
88
|
+
-- =====================================================
|
|
89
|
+
create table d_range (id integer primary key, n integer);
|
|
90
|
+
insert into d_range values (1, 100);
|
|
91
|
+
insert into d_range values (2, 50);
|
|
92
|
+
insert into d_range values (3, 75);
|
|
93
|
+
insert into d_range values (4, 25);
|
|
94
|
+
insert into d_range values (5, 90);
|
|
95
|
+
|
|
96
|
+
create index ix_d_range on d_range(n desc);
|
|
97
|
+
|
|
98
|
+
-- Half-bounded range, DESC ordering
|
|
99
|
+
select n from d_range where n >= 60 order by n desc;
|
|
100
|
+
→ [{"n":100},{"n":90},{"n":75}]
|
|
101
|
+
|
|
102
|
+
-- Bounded range, DESC ordering
|
|
103
|
+
select n from d_range where n between 30 and 80 order by n desc;
|
|
104
|
+
→ [{"n":75},{"n":50}]
|
|
105
|
+
|
|
106
|
+
-- Same bounded range, ASC ordering still correct
|
|
107
|
+
select n from d_range where n between 30 and 80 order by n;
|
|
108
|
+
→ [{"n":50},{"n":75}]
|
|
109
|
+
|
|
110
|
+
drop table d_range;
|
|
111
|
+
|
|
112
|
+
-- =====================================================
|
|
113
|
+
-- 5. DESC index on TEXT — lexicographic descending
|
|
114
|
+
-- =====================================================
|
|
115
|
+
create table d_text (id integer primary key, name text);
|
|
116
|
+
insert into d_text values (1, 'banana');
|
|
117
|
+
insert into d_text values (2, 'apple');
|
|
118
|
+
insert into d_text values (3, 'cherry');
|
|
119
|
+
insert into d_text values (4, 'date');
|
|
120
|
+
|
|
121
|
+
create index ix_d_text on d_text(name desc);
|
|
122
|
+
|
|
123
|
+
select name from d_text order by name desc;
|
|
124
|
+
→ [{"name":"date"},{"name":"cherry"},{"name":"banana"},{"name":"apple"}]
|
|
125
|
+
|
|
126
|
+
-- Range on TEXT DESC index
|
|
127
|
+
select name from d_text where name >= 'b' order by name desc;
|
|
128
|
+
→ [{"name":"date"},{"name":"cherry"},{"name":"banana"}]
|
|
129
|
+
|
|
130
|
+
drop table d_text;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
-- 10.5.4-composite-pk-index-update-phantom.sqllogic
|
|
2
|
+
--
|
|
3
|
+
-- requires-capability: standalone-index-ddl
|
|
4
|
+
--
|
|
5
|
+
-- Regression: a composite-PK table with a secondary index on a non-PK column.
|
|
6
|
+
-- Updating (or deleting) the indexed column must drop the OLD index entry's
|
|
7
|
+
-- primary key so a later seek of the OLD value yields no phantom row.
|
|
8
|
+
--
|
|
9
|
+
-- Pre-fix, MemoryIndexEntry.primaryKeys was a JS Set keyed by reference; a
|
|
10
|
+
-- composite PK is a freshly-allocated array each extraction, so removeEntry
|
|
11
|
+
-- could never drop it by value. The stale PK lingered in the OLD index entry
|
|
12
|
+
-- and a `WHERE v = <old>` seek through that index surfaced the row even though
|
|
13
|
+
-- its value had changed.
|
|
14
|
+
--
|
|
15
|
+
-- NOTE: whether this manifests end-to-end depends on the access planner
|
|
16
|
+
-- routing the equality seek through the secondary index. If it full-scans the
|
|
17
|
+
-- primary tree it would return the correct (empty) result regardless of the
|
|
18
|
+
-- bug — the authoritative regression lives in
|
|
19
|
+
-- test/vtab/memory-index-pk-value-identity.spec.ts at the MemoryIndex level.
|
|
20
|
+
|
|
21
|
+
CREATE TABLE ci (a INTEGER, b INTEGER, v INTEGER, PRIMARY KEY (a, b));
|
|
22
|
+
INSERT INTO ci VALUES (1, 1, 100), (1, 2, 200), (2, 1, 300);
|
|
23
|
+
CREATE INDEX ci_v ON ci (v);
|
|
24
|
+
|
|
25
|
+
-- Baseline: the indexed seek finds the right row before any update.
|
|
26
|
+
SELECT a, b FROM ci WHERE v = 100;
|
|
27
|
+
→ [{"a":1,"b":1}]
|
|
28
|
+
|
|
29
|
+
-- Update the indexed column of the (1,1) row: 100 -> 999.
|
|
30
|
+
UPDATE ci SET v = 999 WHERE a = 1 AND b = 1;
|
|
31
|
+
|
|
32
|
+
-- Seek the OLD index value: must be empty (no phantom from a stale PK).
|
|
33
|
+
SELECT a, b FROM ci WHERE v = 100;
|
|
34
|
+
→ []
|
|
35
|
+
|
|
36
|
+
-- The NEW value is findable, mapped to exactly the updated row.
|
|
37
|
+
SELECT a, b FROM ci WHERE v = 999 ORDER BY a, b;
|
|
38
|
+
→ [{"a":1,"b":1}]
|
|
39
|
+
|
|
40
|
+
-- Untouched rows are unaffected.
|
|
41
|
+
SELECT a, b FROM ci WHERE v = 200;
|
|
42
|
+
→ [{"a":1,"b":2}]
|
|
43
|
+
SELECT a, b FROM ci WHERE v = 300;
|
|
44
|
+
→ [{"a":2,"b":1}]
|
|
45
|
+
|
|
46
|
+
-- Delete a composite-PK row and confirm its index value drops out too.
|
|
47
|
+
DELETE FROM ci WHERE a = 1 AND b = 2;
|
|
48
|
+
SELECT a, b FROM ci WHERE v = 200;
|
|
49
|
+
→ []
|
|
50
|
+
|
|
51
|
+
-- Full ordered view: only the live rows remain.
|
|
52
|
+
SELECT a, b, v FROM ci ORDER BY a, b;
|
|
53
|
+
→ [{"a":1,"b":1,"v":999},{"a":2,"b":1,"v":300}]
|
|
54
|
+
|
|
55
|
+
DROP TABLE ci;
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
-- 10.5.5-index-name-uniqueness.sqllogic
|
|
2
|
+
--
|
|
3
|
+
-- requires-capability: standalone-index-ddl
|
|
4
|
+
--
|
|
5
|
+
-- Index names are unique per schema, not per table (docs/sql-vtab.md §6.3).
|
|
6
|
+
-- DROP INDEX / ALTER INDEX / sync all resolve an index by name alone, so a
|
|
7
|
+
-- duplicate name would resolve by table-registration order.
|
|
8
|
+
|
|
9
|
+
CREATE TABLE iu_t1 (id INTEGER PRIMARY KEY, note TEXT);
|
|
10
|
+
CREATE TABLE iu_t2 (id INTEGER PRIMARY KEY, note TEXT);
|
|
11
|
+
|
|
12
|
+
CREATE INDEX idx_note ON iu_t1 (note);
|
|
13
|
+
|
|
14
|
+
-- Same name, different table in the same schema: rejected, naming the owner.
|
|
15
|
+
CREATE INDEX idx_note ON iu_t2 (note);
|
|
16
|
+
-- error: Index 'idx_note' already exists in schema 'main' on table 'iu_t1'
|
|
17
|
+
|
|
18
|
+
-- Case-divergent spelling collides too (index names compare case-insensitively).
|
|
19
|
+
CREATE INDEX IDX_NOTE ON iu_t2 (note);
|
|
20
|
+
-- error: already exists in schema 'main' on table 'iu_t1'
|
|
21
|
+
|
|
22
|
+
-- IF NOT EXISTS does NOT suppress a cross-table collision: an index of that name
|
|
23
|
+
-- on another table is a different object, and skipping would silently leave
|
|
24
|
+
-- iu_t2 without the requested index.
|
|
25
|
+
CREATE INDEX IF NOT EXISTS idx_note ON iu_t2 (note);
|
|
26
|
+
-- error: Index 'idx_note' already exists in schema 'main' on table 'iu_t1'
|
|
27
|
+
|
|
28
|
+
-- ...but IF NOT EXISTS still suppresses a same-table duplicate.
|
|
29
|
+
CREATE INDEX IF NOT EXISTS idx_note ON iu_t1 (note);
|
|
30
|
+
|
|
31
|
+
-- A UNIQUE index occupies the same namespace as a plain one.
|
|
32
|
+
CREATE UNIQUE INDEX idx_note ON iu_t2 (note);
|
|
33
|
+
-- error: Index 'idx_note' already exists in schema 'main' on table 'iu_t1'
|
|
34
|
+
|
|
35
|
+
-- The owner is unambiguous, so DROP INDEX resolves without guessing.
|
|
36
|
+
DROP INDEX idx_note;
|
|
37
|
+
|
|
38
|
+
-- Freed name: the previously rejected statement now succeeds on iu_t2.
|
|
39
|
+
CREATE INDEX idx_note ON iu_t2 (note);
|
|
40
|
+
|
|
41
|
+
INSERT INTO iu_t2 VALUES (1, 'alpha'), (2, 'beta');
|
|
42
|
+
SELECT id FROM iu_t2 WHERE note = 'beta';
|
|
43
|
+
→ [{"id":2}]
|
|
44
|
+
|
|
45
|
+
DROP INDEX idx_note;
|
|
46
|
+
|
|
47
|
+
-- ========================================
|
|
48
|
+
-- Implicit covering structures are NOT in the schema-wide namespace
|
|
49
|
+
-- ========================================
|
|
50
|
+
|
|
51
|
+
-- A plain UNIQUE constraint's auto-built covering structure takes the
|
|
52
|
+
-- constraint's name, and constraint names are unique per TABLE. Two tables may
|
|
53
|
+
-- each declare `constraint uq_email unique (email)`.
|
|
54
|
+
CREATE TABLE iu_a (id INTEGER PRIMARY KEY, email TEXT, CONSTRAINT uq_email UNIQUE (email));
|
|
55
|
+
CREATE TABLE iu_b (id INTEGER PRIMARY KEY, email TEXT, CONSTRAINT uq_email UNIQUE (email));
|
|
56
|
+
|
|
57
|
+
-- Both constraints still enforce independently.
|
|
58
|
+
INSERT INTO iu_a VALUES (1, 'x@example.com');
|
|
59
|
+
INSERT INTO iu_b VALUES (1, 'x@example.com');
|
|
60
|
+
|
|
61
|
+
SELECT count(*) AS n FROM iu_a;
|
|
62
|
+
→ [{"n":1}]
|
|
63
|
+
|
|
64
|
+
INSERT INTO iu_a VALUES (2, 'x@example.com');
|
|
65
|
+
-- error: UNIQUE constraint
|
|
66
|
+
|
|
67
|
+
-- An ordinary CREATE INDEX may take a name held only by another table's implicit
|
|
68
|
+
-- covering structure — that structure is not a user object in the namespace.
|
|
69
|
+
CREATE TABLE iu_c (id INTEGER PRIMARY KEY, email TEXT);
|
|
70
|
+
CREATE INDEX uq_email ON iu_c (email);
|
|
71
|
+
|
|
72
|
+
DROP TABLE iu_c;
|
|
73
|
+
DROP TABLE iu_b;
|
|
74
|
+
DROP TABLE iu_a;
|
|
75
|
+
DROP TABLE iu_t2;
|
|
76
|
+
DROP TABLE iu_t1;
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
-- 10.5.6-minmax-index-boundary.sqllogic — answers for the ungrouped MIN/MAX rewrite.
|
|
2
|
+
--
|
|
3
|
+
-- requires-capability: standalone-index-ddl
|
|
4
|
+
--
|
|
5
|
+
-- The optimizer rewrites an ungrouped `min(c)` / `max(c)` over an indexed column into
|
|
6
|
+
-- `min(c)` over `(… where c is not null order by c limit 1)`, keeping the aggregate
|
|
7
|
+
-- itself on top. That is a plan-shape change only, so every answer below must be
|
|
8
|
+
-- identical to what a full scan would produce — which is exactly what this file pins,
|
|
9
|
+
-- on BOTH backends.
|
|
10
|
+
--
|
|
11
|
+
-- Plan-shape claims (which index is used, whether a LIMIT survives, work counters)
|
|
12
|
+
-- are backend-dependent and live in test/optimizer/minmax-index-boundary.spec.ts.
|
|
13
|
+
-- Keep them out of here.
|
|
14
|
+
|
|
15
|
+
-- =====================================================
|
|
16
|
+
-- 1. Empty relation — one row, NULL
|
|
17
|
+
-- =====================================================
|
|
18
|
+
-- The aggregate survives the rewrite, so an ungrouped aggregate over zero rows still
|
|
19
|
+
-- emits exactly one row and min/max finalize an empty accumulator to NULL.
|
|
20
|
+
create table mm_empty (k integer primary key, c integer);
|
|
21
|
+
create index mm_empty_c on mm_empty(c);
|
|
22
|
+
create index mm_empty_c_desc on mm_empty(c desc);
|
|
23
|
+
|
|
24
|
+
select min(c) as v from mm_empty;
|
|
25
|
+
→ [{"v":null}]
|
|
26
|
+
|
|
27
|
+
select max(c) as v from mm_empty;
|
|
28
|
+
→ [{"v":null}]
|
|
29
|
+
|
|
30
|
+
select count(*) as n from mm_empty;
|
|
31
|
+
→ [{"n":0}]
|
|
32
|
+
|
|
33
|
+
drop table mm_empty;
|
|
34
|
+
|
|
35
|
+
-- =====================================================
|
|
36
|
+
-- 2. All-NULL column — one row, NULL
|
|
37
|
+
-- =====================================================
|
|
38
|
+
create table mm_null (k integer primary key, c integer null);
|
|
39
|
+
create index mm_null_c on mm_null(c);
|
|
40
|
+
create index mm_null_c_desc on mm_null(c desc);
|
|
41
|
+
insert into mm_null values (1, null), (2, null), (3, null);
|
|
42
|
+
|
|
43
|
+
select min(c) as v from mm_null;
|
|
44
|
+
→ [{"v":null}]
|
|
45
|
+
|
|
46
|
+
select max(c) as v from mm_null;
|
|
47
|
+
→ [{"v":null}]
|
|
48
|
+
|
|
49
|
+
drop table mm_null;
|
|
50
|
+
|
|
51
|
+
-- =====================================================
|
|
52
|
+
-- 3. NULLs at the boundary — the extreme NON-NULL value wins
|
|
53
|
+
-- =====================================================
|
|
54
|
+
-- ORDER BY in this engine places NULLs FIRST for both directions, so without the
|
|
55
|
+
-- rewrite's `is not null` arm a `limit 1` would hand the aggregate a NULL. Both an
|
|
56
|
+
-- ascending and a descending index are present so both directions take the rewrite.
|
|
57
|
+
create table mm_mix (k integer primary key, c integer null);
|
|
58
|
+
create index mm_mix_c on mm_mix(c);
|
|
59
|
+
create index mm_mix_c_desc on mm_mix(c desc);
|
|
60
|
+
insert into mm_mix values (1, 30), (2, null), (3, 10), (4, null), (5, 50), (6, 20);
|
|
61
|
+
|
|
62
|
+
select min(c) as v from mm_mix;
|
|
63
|
+
→ [{"v":10}]
|
|
64
|
+
|
|
65
|
+
select max(c) as v from mm_mix;
|
|
66
|
+
→ [{"v":50}]
|
|
67
|
+
|
|
68
|
+
-- DISTINCT never changes an extremum.
|
|
69
|
+
select min(distinct c) as v from mm_mix;
|
|
70
|
+
→ [{"v":10}]
|
|
71
|
+
|
|
72
|
+
select max(distinct c) as v from mm_mix;
|
|
73
|
+
→ [{"v":50}]
|
|
74
|
+
|
|
75
|
+
-- Only NULLs survive the WHERE, so the answer is NULL again.
|
|
76
|
+
select max(c) as v from mm_mix where c is null;
|
|
77
|
+
→ [{"v":null}]
|
|
78
|
+
|
|
79
|
+
drop table mm_mix;
|
|
80
|
+
|
|
81
|
+
-- =====================================================
|
|
82
|
+
-- 4. WHERE clauses must not be lost
|
|
83
|
+
-- =====================================================
|
|
84
|
+
create table mm_w (k integer primary key, g integer, c integer);
|
|
85
|
+
create index mm_w_gc on mm_w(g, c desc);
|
|
86
|
+
create index mm_w_gc_asc on mm_w(g, c);
|
|
87
|
+
insert into mm_w values (1, 1, 10), (2, 1, 40), (3, 2, 70), (4, 2, 20), (5, 1, 25);
|
|
88
|
+
|
|
89
|
+
-- Equality-bound composite prefix: the index orders `c` within each `g`.
|
|
90
|
+
select max(c) as v from mm_w where g = 1;
|
|
91
|
+
→ [{"v":40}]
|
|
92
|
+
|
|
93
|
+
select min(c) as v from mm_w where g = 2;
|
|
94
|
+
→ [{"v":20}]
|
|
95
|
+
|
|
96
|
+
-- Range predicate on the aggregated column itself.
|
|
97
|
+
select max(c) as v from mm_w where c < 40;
|
|
98
|
+
→ [{"v":25}]
|
|
99
|
+
|
|
100
|
+
select min(c) as v from mm_w where c > 20;
|
|
101
|
+
→ [{"v":25}]
|
|
102
|
+
|
|
103
|
+
-- A WHERE that matches nothing still emits one NULL row.
|
|
104
|
+
select max(c) as v from mm_w where g = 99;
|
|
105
|
+
→ [{"v":null}]
|
|
106
|
+
|
|
107
|
+
-- HAVING is a filter ABOVE the aggregate; unaffected by the rewrite.
|
|
108
|
+
select max(c) as v from mm_w having max(c) > 5;
|
|
109
|
+
→ [{"v":70}]
|
|
110
|
+
|
|
111
|
+
select max(c) as v from mm_w having max(c) > 500;
|
|
112
|
+
→ []
|
|
113
|
+
|
|
114
|
+
drop table mm_w;
|
|
115
|
+
|
|
116
|
+
-- =====================================================
|
|
117
|
+
-- 5. Correlated MIN/MAX subquery
|
|
118
|
+
-- =====================================================
|
|
119
|
+
create table mm_o (g integer primary key);
|
|
120
|
+
create table mm_i (k integer primary key, g integer, c integer);
|
|
121
|
+
create index mm_i_gc on mm_i(g, c desc);
|
|
122
|
+
insert into mm_o values (1), (2), (3);
|
|
123
|
+
insert into mm_i values (1, 1, 10), (2, 1, 40), (3, 2, 70);
|
|
124
|
+
|
|
125
|
+
select g, (select max(c) from mm_i where mm_i.g = mm_o.g) as m from mm_o order by g;
|
|
126
|
+
→ [{"g":1,"m":40},{"g":2,"m":70},{"g":3,"m":null}]
|
|
127
|
+
|
|
128
|
+
drop table mm_i;
|
|
129
|
+
drop table mm_o;
|
|
130
|
+
|
|
131
|
+
-- =====================================================
|
|
132
|
+
-- 6. Comparator agreement — the rewrite must rank like the aggregate does
|
|
133
|
+
-- =====================================================
|
|
134
|
+
-- The rewrite never compares values itself: it delegates to the access plan's
|
|
135
|
+
-- ordering claim, and min/max rank under the argument's semantic comparator. These
|
|
136
|
+
-- two columns are where a drift between the two would show up first, because their
|
|
137
|
+
-- ordering is NOT byte order.
|
|
138
|
+
|
|
139
|
+
-- COLLATE NOCASE: 'A' < 'b' < 'C', not 'A' < 'C' < 'b'.
|
|
140
|
+
create table mm_n (k integer primary key, n text collate nocase);
|
|
141
|
+
create index mm_n_n on mm_n(n);
|
|
142
|
+
create index mm_n_n_desc on mm_n(n desc);
|
|
143
|
+
insert into mm_n values (1, 'b'), (2, 'A'), (3, 'C');
|
|
144
|
+
|
|
145
|
+
select min(n) as v from mm_n;
|
|
146
|
+
→ [{"v":"A"}]
|
|
147
|
+
|
|
148
|
+
select max(n) as v from mm_n;
|
|
149
|
+
→ [{"v":"C"}]
|
|
150
|
+
|
|
151
|
+
drop table mm_n;
|
|
152
|
+
|
|
153
|
+
-- TIMESPAN: 'PT30M' < 'PT1H' < 'P1D' by duration, not by text.
|
|
154
|
+
create table mm_s (k integer primary key, s timespan);
|
|
155
|
+
create index mm_s_s on mm_s(s);
|
|
156
|
+
create index mm_s_s_desc on mm_s(s desc);
|
|
157
|
+
insert into mm_s values (1, 'PT1H'), (2, 'PT30M'), (3, 'P1D');
|
|
158
|
+
|
|
159
|
+
select min(s) as v from mm_s;
|
|
160
|
+
→ [{"v":"PT30M"}]
|
|
161
|
+
|
|
162
|
+
select max(s) as v from mm_s;
|
|
163
|
+
→ [{"v":"P1D"}]
|
|
164
|
+
|
|
165
|
+
drop table mm_s;
|
|
166
|
+
|
|
167
|
+
-- =====================================================
|
|
168
|
+
-- 7. Shapes the rewrite must decline — answers stay correct either way
|
|
169
|
+
-- =====================================================
|
|
170
|
+
create table mm_d (k integer primary key, g integer, c integer);
|
|
171
|
+
create index mm_d_c on mm_d(c);
|
|
172
|
+
create index mm_d_c_desc on mm_d(c desc);
|
|
173
|
+
insert into mm_d values (1, 1, 10), (2, 1, 40), (3, 2, 70), (4, 2, 20);
|
|
174
|
+
|
|
175
|
+
-- Both ends of the index at once.
|
|
176
|
+
select min(c) as lo, max(c) as hi from mm_d;
|
|
177
|
+
→ [{"lo":10,"hi":70}]
|
|
178
|
+
|
|
179
|
+
-- count(*) genuinely needs every row — truncating the source would return 1.
|
|
180
|
+
select max(c) as v, count(*) as n from mm_d;
|
|
181
|
+
→ [{"v":70,"n":4}]
|
|
182
|
+
|
|
183
|
+
-- GROUP BY present.
|
|
184
|
+
select g, max(c) as v from mm_d group by g order by g;
|
|
185
|
+
→ [{"g":1,"v":40},{"g":2,"v":70}]
|
|
186
|
+
|
|
187
|
+
-- A non-trivial argument.
|
|
188
|
+
select max(c + 1) as v from mm_d;
|
|
189
|
+
→ [{"v":71}]
|
|
190
|
+
|
|
191
|
+
-- A derived table between the aggregate and the base table.
|
|
192
|
+
select max(c) as v from (select c from mm_d) x;
|
|
193
|
+
→ [{"v":70}]
|
|
194
|
+
|
|
195
|
+
-- A primary-key range the module may prefer over the `c` ordering. Whether the
|
|
196
|
+
-- boundary read or a full scan wins is a module cost decision (and differs by
|
|
197
|
+
-- backend); the answer must not be.
|
|
198
|
+
select max(c) as v from mm_d where k > 1;
|
|
199
|
+
→ [{"v":70}]
|
|
200
|
+
|
|
201
|
+
select min(c) as v from mm_d where k > 1;
|
|
202
|
+
→ [{"v":20}]
|
|
203
|
+
|
|
204
|
+
drop table mm_d;
|