@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,472 @@
|
|
|
1
|
+
-- adapted from SQLite test/collate1-9.test
|
|
2
|
+
-- Collation propagation across query parts: ORDER BY, JOIN, DISTINCT, set operations,
|
|
3
|
+
-- aggregates, key ranges. Quereus supports BINARY (default), NOCASE, and RTRIM on TEXT.
|
|
4
|
+
-- The index-DDL-dependent parts live in 06.4.2.1-collation-index-access-paths.
|
|
5
|
+
-- Existing 06.4.1-schema-case-insensitive covers schema-name case handling.
|
|
6
|
+
-- Existing 03-expressions, 03.6-type-system, 07.5-window, 07.3-group-by-extras cover
|
|
7
|
+
-- basic WHERE / BETWEEN / GROUP BY / PARTITION BY usage. This file fills the gaps.
|
|
8
|
+
|
|
9
|
+
-- =============================================================================
|
|
10
|
+
-- ORDER BY with column-level COLLATE NOCASE
|
|
11
|
+
-- =============================================================================
|
|
12
|
+
|
|
13
|
+
create table coll_ord (id integer primary key, name text collate NOCASE);
|
|
14
|
+
insert into coll_ord values (1, 'charlie'), (2, 'Alice'), (3, 'bob'), (4, 'BANANA');
|
|
15
|
+
|
|
16
|
+
-- NOCASE column ordering: case-insensitive
|
|
17
|
+
select name from coll_ord order by name;
|
|
18
|
+
→ [{"name":"Alice"},{"name":"BANANA"},{"name":"bob"},{"name":"charlie"}]
|
|
19
|
+
|
|
20
|
+
-- Explicit COLLATE BINARY in ORDER BY overrides column collation
|
|
21
|
+
select name from coll_ord order by name collate BINARY;
|
|
22
|
+
→ [{"name":"Alice"},{"name":"BANANA"},{"name":"bob"},{"name":"charlie"}]
|
|
23
|
+
|
|
24
|
+
drop table coll_ord;
|
|
25
|
+
|
|
26
|
+
-- =============================================================================
|
|
27
|
+
-- ORDER BY with explicit COLLATE override on a BINARY-default column
|
|
28
|
+
-- =============================================================================
|
|
29
|
+
|
|
30
|
+
create table coll_bin (id integer primary key, name text);
|
|
31
|
+
insert into coll_bin values (1, 'charlie'), (2, 'Alice'), (3, 'bob'), (4, 'BANANA');
|
|
32
|
+
|
|
33
|
+
-- Default BINARY: uppercase letters sort before lowercase
|
|
34
|
+
select name from coll_bin order by name;
|
|
35
|
+
→ [{"name":"Alice"},{"name":"BANANA"},{"name":"bob"},{"name":"charlie"}]
|
|
36
|
+
|
|
37
|
+
-- Force NOCASE: reorders alphabetically ignoring case
|
|
38
|
+
select name from coll_bin order by name collate NOCASE;
|
|
39
|
+
→ [{"name":"Alice"},{"name":"BANANA"},{"name":"bob"},{"name":"charlie"}]
|
|
40
|
+
|
|
41
|
+
drop table coll_bin;
|
|
42
|
+
|
|
43
|
+
-- =============================================================================
|
|
44
|
+
-- RTRIM collation: trailing spaces ignored
|
|
45
|
+
-- =============================================================================
|
|
46
|
+
|
|
47
|
+
create table coll_rtrim (id integer primary key, val text collate RTRIM);
|
|
48
|
+
insert into coll_rtrim values (1, 'cat'), (2, 'cat '), (3, 'cat '), (4, 'dog'), (5, 'dog ');
|
|
49
|
+
|
|
50
|
+
-- Equality treats 'cat', 'cat ', 'cat ' as equal
|
|
51
|
+
select id from coll_rtrim where val = 'cat' order by id;
|
|
52
|
+
→ [{"id":1},{"id":2},{"id":3}]
|
|
53
|
+
|
|
54
|
+
-- ORDER BY groups RTRIM-equal values
|
|
55
|
+
select id from coll_rtrim order by val, id;
|
|
56
|
+
→ [{"id":1},{"id":2},{"id":3},{"id":4},{"id":5}]
|
|
57
|
+
|
|
58
|
+
-- DISTINCT under RTRIM dedups trailing-space variants
|
|
59
|
+
select distinct val from coll_rtrim order by val;
|
|
60
|
+
→ [{"val":"cat"},{"val":"dog"}]
|
|
61
|
+
|
|
62
|
+
drop table coll_rtrim;
|
|
63
|
+
|
|
64
|
+
-- =============================================================================
|
|
65
|
+
-- JOIN ON with COLLATE NOCASE — explicit collation on predicate
|
|
66
|
+
-- =============================================================================
|
|
67
|
+
|
|
68
|
+
create table jt1 (id integer primary key, name text);
|
|
69
|
+
create table jt2 (id integer primary key, name text);
|
|
70
|
+
insert into jt1 values (1, 'Alice'), (2, 'Bob');
|
|
71
|
+
insert into jt2 values (10, 'ALICE'), (20, 'bob');
|
|
72
|
+
|
|
73
|
+
-- Explicit COLLATE NOCASE on the join predicate matches case-insensitively
|
|
74
|
+
select jt1.id as l, jt2.id as r from jt1 join jt2 on jt1.name = jt2.name collate NOCASE order by jt1.id;
|
|
75
|
+
→ [{"l":1,"r":10},{"l":2,"r":20}]
|
|
76
|
+
|
|
77
|
+
-- Default BINARY: case-sensitive, no matches
|
|
78
|
+
select jt1.id as l, jt2.id as r from jt1 join jt2 on jt1.name = jt2.name order by jt1.id;
|
|
79
|
+
→ []
|
|
80
|
+
|
|
81
|
+
drop table jt1;
|
|
82
|
+
drop table jt2;
|
|
83
|
+
|
|
84
|
+
-- =============================================================================
|
|
85
|
+
-- DISTINCT with COLLATE NOCASE column
|
|
86
|
+
-- =============================================================================
|
|
87
|
+
|
|
88
|
+
create table coll_dist (id integer primary key, name text collate NOCASE);
|
|
89
|
+
insert into coll_dist values (1, 'Bob'), (2, 'bob'), (3, 'BOB'), (4, 'Alice'), (5, 'alice');
|
|
90
|
+
|
|
91
|
+
-- DISTINCT under NOCASE merges case-equal values
|
|
92
|
+
select distinct name from coll_dist order by name;
|
|
93
|
+
→ [{"name":"Alice"},{"name":"Bob"}]
|
|
94
|
+
|
|
95
|
+
drop table coll_dist;
|
|
96
|
+
|
|
97
|
+
-- =============================================================================
|
|
98
|
+
-- UNION / INTERSECT / EXCEPT with COLLATE NOCASE
|
|
99
|
+
-- =============================================================================
|
|
100
|
+
|
|
101
|
+
create table set_a (name text collate NOCASE);
|
|
102
|
+
create table set_b (name text collate NOCASE);
|
|
103
|
+
insert into set_a values ('Alice'), ('Bob');
|
|
104
|
+
insert into set_b values ('ALICE'), ('charlie');
|
|
105
|
+
|
|
106
|
+
-- UNION dedups using column collation: 'Alice' and 'ALICE' merge
|
|
107
|
+
select name from set_a union select name from set_b order by name;
|
|
108
|
+
→ [{"name":"Alice"},{"name":"Bob"},{"name":"charlie"}]
|
|
109
|
+
|
|
110
|
+
-- UNION ALL keeps duplicates as-is (no dedup)
|
|
111
|
+
select name from set_a union all select name from set_b order by name;
|
|
112
|
+
→ [{"name":"Alice"},{"name":"ALICE"},{"name":"Bob"},{"name":"charlie"}]
|
|
113
|
+
|
|
114
|
+
-- INTERSECT under NOCASE matches case-insensitively
|
|
115
|
+
select name from set_a intersect select name from set_b order by name;
|
|
116
|
+
→ [{"name":"Alice"}]
|
|
117
|
+
|
|
118
|
+
-- EXCEPT under NOCASE removes case-equal rows
|
|
119
|
+
select name from set_a except select name from set_b order by name;
|
|
120
|
+
→ [{"name":"Bob"}]
|
|
121
|
+
|
|
122
|
+
drop table set_a;
|
|
123
|
+
drop table set_b;
|
|
124
|
+
|
|
125
|
+
-- =============================================================================
|
|
126
|
+
-- MIN / MAX aggregates respect column collation
|
|
127
|
+
-- =============================================================================
|
|
128
|
+
|
|
129
|
+
create table coll_agg (id integer primary key, val text collate NOCASE);
|
|
130
|
+
insert into coll_agg values (1, 'apple'), (2, 'APPLE'), (3, 'Banana'), (4, 'banana'), (5, 'cherry');
|
|
131
|
+
|
|
132
|
+
-- MIN/MAX under NOCASE: comparison is case-insensitive, so first/last by case-folded
|
|
133
|
+
-- order. NOCASE-equal values ('apple' vs 'APPLE') tie, so which spelling survives is
|
|
134
|
+
-- unspecified — fold through upper() to assert the extremum without pinning the
|
|
135
|
+
-- representative. 'cherry' is tie-free, so it may be asserted verbatim.
|
|
136
|
+
select upper(min(val)) as mn, max(val) as mx from coll_agg;
|
|
137
|
+
→ [{"mn":"APPLE","mx":"cherry"}]
|
|
138
|
+
|
|
139
|
+
drop table coll_agg;
|
|
140
|
+
|
|
141
|
+
-- The index-shaped sections — an explicit per-column COLLATE on a `create index`,
|
|
142
|
+
-- and the seek/decline classification when a predicate's collation does not match
|
|
143
|
+
-- the index's — live in 06.4.2.1-collation-index-access-paths; they need standalone
|
|
144
|
+
-- CREATE INDEX.
|
|
145
|
+
|
|
146
|
+
-- =============================================================================
|
|
147
|
+
-- COLLATE in CASE expression
|
|
148
|
+
-- =============================================================================
|
|
149
|
+
|
|
150
|
+
create table coll_case (id integer primary key, status text);
|
|
151
|
+
insert into coll_case values (1, 'active'), (2, 'PENDING'), (3, 'closed'), (4, 'ACTIVE');
|
|
152
|
+
|
|
153
|
+
select id, case when status = 'active' collate NOCASE then 'match' else 'other' end as r
|
|
154
|
+
from coll_case order by id;
|
|
155
|
+
→ [{"id":1,"r":"match"},{"id":2,"r":"other"},{"id":3,"r":"other"},{"id":4,"r":"match"}]
|
|
156
|
+
|
|
157
|
+
drop table coll_case;
|
|
158
|
+
|
|
159
|
+
-- =============================================================================
|
|
160
|
+
-- Simple CASE resolves its collation exactly as `=` / IN do
|
|
161
|
+
-- =============================================================================
|
|
162
|
+
-- `case x when v` must decide each match the way `x = v` would, resolved
|
|
163
|
+
-- independently per WHEN clause through the provenance lattice (explicit COLLATE >
|
|
164
|
+
-- declared column collation > defaults > BINARY). Each assertion sits next to the
|
|
165
|
+
-- corresponding `=` / `in` assertion so a future divergence shows up in one place.
|
|
166
|
+
-- Regression for `simple-case-comparison-collation-and-type` (previously the
|
|
167
|
+
-- simple-CASE match compared raw bytes under BINARY and disagreed with `=`).
|
|
168
|
+
|
|
169
|
+
create table case_nc (id integer primary key, n text collate NOCASE);
|
|
170
|
+
insert into case_nc values (1, 'bob');
|
|
171
|
+
|
|
172
|
+
-- The declared NOCASE column collation governs all three surfaces alike.
|
|
173
|
+
select n = 'BOB' as r from case_nc;
|
|
174
|
+
→ [{"r":true}]
|
|
175
|
+
|
|
176
|
+
select n in ('BOB') as r from case_nc;
|
|
177
|
+
→ [{"r":true}]
|
|
178
|
+
|
|
179
|
+
select case n when 'BOB' then 'hit' else 'miss' end as r from case_nc;
|
|
180
|
+
→ [{"r":"hit"}]
|
|
181
|
+
|
|
182
|
+
-- No spurious matches: a NOCASE-distinct value still misses.
|
|
183
|
+
select case n when 'bill' then 'hit' else 'miss' end as r from case_nc;
|
|
184
|
+
→ [{"r":"miss"}]
|
|
185
|
+
|
|
186
|
+
drop table case_nc;
|
|
187
|
+
|
|
188
|
+
-- Explicit COLLATE on the base expression, and on the WHEN operand, each govern
|
|
189
|
+
-- the comparison on their own (a BINARY-defaulted column must not shadow either).
|
|
190
|
+
create table case_bin (id integer primary key, n text);
|
|
191
|
+
insert into case_bin values (1, 'a');
|
|
192
|
+
|
|
193
|
+
select case n collate NOCASE when 'A' then 'hit' else 'miss' end as r from case_bin;
|
|
194
|
+
→ [{"r":"hit"}]
|
|
195
|
+
|
|
196
|
+
select case n when 'A' collate NOCASE then 'hit' else 'miss' end as r from case_bin;
|
|
197
|
+
→ [{"r":"hit"}]
|
|
198
|
+
|
|
199
|
+
-- Desugared parity: the same operand pair under `=`.
|
|
200
|
+
select (n collate NOCASE = 'A') as r from case_bin;
|
|
201
|
+
→ [{"r":true}]
|
|
202
|
+
|
|
203
|
+
-- Plain BINARY stays case-sensitive.
|
|
204
|
+
select case n when 'A' then 'hit' else 'miss' end as r from case_bin;
|
|
205
|
+
→ [{"r":"miss"}]
|
|
206
|
+
|
|
207
|
+
drop table case_bin;
|
|
208
|
+
|
|
209
|
+
-- Per-clause resolution: clause 1 resolves under the column's NOCASE, clause 2
|
|
210
|
+
-- under its own explicit RTRIM, clause 3 under an explicit BINARY. Mirrors how
|
|
211
|
+
-- BETWEEN resolves its two bounds independently.
|
|
212
|
+
create table case_mix (id integer primary key, n text collate NOCASE);
|
|
213
|
+
insert into case_mix values (1, 'bob'), (2, 'cat '), (3, 'dog');
|
|
214
|
+
|
|
215
|
+
select id, case n
|
|
216
|
+
when 'BOB' then 'nocase-hit'
|
|
217
|
+
when 'cat' collate RTRIM then 'rtrim-hit'
|
|
218
|
+
when 'DOG' collate BINARY then 'binary-hit'
|
|
219
|
+
else 'miss'
|
|
220
|
+
end as r
|
|
221
|
+
from case_mix order by id;
|
|
222
|
+
→ [{"id":1,"r":"nocase-hit"},{"id":2,"r":"rtrim-hit"},{"id":3,"r":"miss"}]
|
|
223
|
+
|
|
224
|
+
drop table case_mix;
|
|
225
|
+
|
|
226
|
+
-- Collation conflict: an explicit COLLATE on the base AND a different explicit
|
|
227
|
+
-- COLLATE on a WHEN operand is the same error `=` raises for that operand pair.
|
|
228
|
+
create table case_conflict (id integer primary key, n text);
|
|
229
|
+
insert into case_conflict values (1, 'a');
|
|
230
|
+
|
|
231
|
+
select case n collate RTRIM when 'A' collate NOCASE then 'hit' else 'miss' end as r
|
|
232
|
+
from case_conflict;
|
|
233
|
+
-- error: conflicting COLLATE clauses in comparison
|
|
234
|
+
|
|
235
|
+
-- Same pair under `=` — identical error.
|
|
236
|
+
select (n collate RTRIM = 'A' collate NOCASE) as r from case_conflict;
|
|
237
|
+
-- error: conflicting COLLATE clauses in comparison
|
|
238
|
+
|
|
239
|
+
-- Declared-collation conflict between two NOCASE/RTRIM columns is the ambiguity error.
|
|
240
|
+
create table case_conflict2 (id integer primary key, a text collate NOCASE, b text collate RTRIM);
|
|
241
|
+
insert into case_conflict2 values (1, 'x', 'x');
|
|
242
|
+
|
|
243
|
+
select case a when b then 'hit' else 'miss' end as r from case_conflict2;
|
|
244
|
+
-- error: ambiguous collation for comparison
|
|
245
|
+
|
|
246
|
+
drop table case_conflict2;
|
|
247
|
+
drop table case_conflict;
|
|
248
|
+
|
|
249
|
+
-- A searched CASE is unaffected — its WHEN is an ordinary boolean expression whose
|
|
250
|
+
-- own comparison already resolved through the lattice.
|
|
251
|
+
create table case_searched (id integer primary key, n text collate NOCASE);
|
|
252
|
+
insert into case_searched values (1, 'bob');
|
|
253
|
+
|
|
254
|
+
select case when n = 'BOB' then 'hit' else 'miss' end as r from case_searched;
|
|
255
|
+
→ [{"r":"hit"}]
|
|
256
|
+
|
|
257
|
+
drop table case_searched;
|
|
258
|
+
|
|
259
|
+
-- =============================================================================
|
|
260
|
+
-- COLLATE on a BETWEEN *bound* (scan form)
|
|
261
|
+
-- =============================================================================
|
|
262
|
+
-- BETWEEN desugars to `expr >= lo AND expr <= hi`; each comparison resolves its
|
|
263
|
+
-- collation independently through the provenance lattice (explicit COLLATE >
|
|
264
|
+
-- declared column collation > defaults), so a COLLATE on a bound governs that
|
|
265
|
+
-- bound's comparison. The tested column's implicit BINARY default must NOT
|
|
266
|
+
-- shadow an explicit bound COLLATE. Regression for `collate-on-between-bound`.
|
|
267
|
+
|
|
268
|
+
create table btw (id integer primary key, name text);
|
|
269
|
+
insert into btw values (1, 'Alice'), (2, 'BOB'), (3, 'charlie'), (4, 'Bob');
|
|
270
|
+
|
|
271
|
+
-- Lower bound carries COLLATE NOCASE: `name >= 'bob' (NOCASE) AND name <= 'bob' (BINARY)`.
|
|
272
|
+
-- 'BOB'/'Bob' are NOCASE-equal to 'bob' (lower passes) and BINARY-less-or-equal to 'bob'
|
|
273
|
+
-- (upper passes). Previously returned [] because the BINARY column collation clobbered
|
|
274
|
+
-- the bound's NOCASE.
|
|
275
|
+
select id from btw where name between 'bob' collate NOCASE and 'bob' order by id;
|
|
276
|
+
→ [{"id":2},{"id":4}]
|
|
277
|
+
|
|
278
|
+
-- expr-side COLLATE stays correct (both comparisons inherit NOCASE).
|
|
279
|
+
select id from btw where name collate NOCASE between 'bob' and 'bob' order by id;
|
|
280
|
+
→ [{"id":2},{"id":4}]
|
|
281
|
+
|
|
282
|
+
-- Desugared parity: the two-comparison form resolves identically per-bound.
|
|
283
|
+
select id from btw where name >= 'bob' collate NOCASE and name <= 'bob' order by id;
|
|
284
|
+
→ [{"id":2},{"id":4}]
|
|
285
|
+
|
|
286
|
+
-- Upper bound carries the COLLATE: `name >= 'BOB' (BINARY) AND name <= 'bob' (NOCASE)`.
|
|
287
|
+
select id from btw where name between 'BOB' and 'bob' collate NOCASE order by id;
|
|
288
|
+
→ [{"id":2},{"id":4}]
|
|
289
|
+
|
|
290
|
+
-- Desugared parity for the upper-collated form.
|
|
291
|
+
select id from btw where name >= 'BOB' and name <= 'bob' collate NOCASE order by id;
|
|
292
|
+
→ [{"id":2},{"id":4}]
|
|
293
|
+
|
|
294
|
+
-- NOT BETWEEN with a collated lower bound = `v < 'bob' (NOCASE) OR v > 'bob' (BINARY)`:
|
|
295
|
+
-- the complement of the between rows, so 'Alice' (id 1) and 'charlie' (id 3).
|
|
296
|
+
select id from btw where name not between 'bob' collate NOCASE and 'bob' order by id;
|
|
297
|
+
→ [{"id":1},{"id":3}]
|
|
298
|
+
|
|
299
|
+
drop table btw;
|
|
300
|
+
|
|
301
|
+
-- The BETWEEN-bound-over-an-index classification lives in
|
|
302
|
+
-- 06.4.2.1-collation-index-access-paths.
|
|
303
|
+
|
|
304
|
+
-- =============================================================================
|
|
305
|
+
-- Collation-matched non-BINARY range / BETWEEN over a matching-collation KEY
|
|
306
|
+
-- =============================================================================
|
|
307
|
+
-- A NOCASE (or RTRIM) range whose predicate collation matches the KEY collation
|
|
308
|
+
-- uses a seek on BOTH backends: the in-memory vtab threads the key collation
|
|
309
|
+
-- into the bound filter + early-termination, and the store compares pushed bounds
|
|
310
|
+
-- under the column's declared collation in its post-fetch row filter
|
|
311
|
+
-- (StoreTable.compareValues) — both advertise `honorsCollatedRangeBounds`. The seek
|
|
312
|
+
-- drops the residual Filter, so these rows are produced by the module's own bound
|
|
313
|
+
-- filter. Result-only here so both backends are asserted identically; plan-shape
|
|
314
|
+
-- assertions live in test/optimizer/range-seek-collation-bounds.spec.ts (memory) and
|
|
315
|
+
-- packages/quereus-store/test/pushdown.spec.ts (store). Regression for
|
|
316
|
+
-- `memory-range-seek-collation-bounds` and `store-range-seek-collation-bounds`.
|
|
317
|
+
|
|
318
|
+
-- NOCASE primary-key range. PK values are NOCASE-distinct, but their BINARY order
|
|
319
|
+
-- ('Banana','CHERRY','apple','date') differs from NOCASE order ('apple','Banana',
|
|
320
|
+
-- 'CHERRY','date'), so a BINARY bound filter would under-fetch.
|
|
321
|
+
create table rng_pk_nc (name text collate NOCASE primary key, n integer);
|
|
322
|
+
insert into rng_pk_nc values ('apple', 1), ('Banana', 2), ('CHERRY', 3), ('date', 4);
|
|
323
|
+
|
|
324
|
+
select n from rng_pk_nc where name > 'banana' order by n;
|
|
325
|
+
→ [{"n":3},{"n":4}]
|
|
326
|
+
|
|
327
|
+
select n from rng_pk_nc where name between 'banana' and 'cherry' order by n;
|
|
328
|
+
→ [{"n":2},{"n":3}]
|
|
329
|
+
|
|
330
|
+
-- Mismatch negative control: an explicit BINARY bound collation does not match the
|
|
331
|
+
-- NOCASE PK, so the access path still declines the seek (scan + residual) on both
|
|
332
|
+
-- backends and returns the BINARY-correct rows (only 'date' is BINARY-> 'banana').
|
|
333
|
+
select n from rng_pk_nc where name > 'banana' collate BINARY order by n;
|
|
334
|
+
→ [{"n":4}]
|
|
335
|
+
|
|
336
|
+
drop table rng_pk_nc;
|
|
337
|
+
|
|
338
|
+
-- RTRIM primary-key range / BETWEEN. The bounds carry trailing spaces, so a raw
|
|
339
|
+
-- BINARY bound filter would both over-fetch ('cat ' > 'cat' in bytes, but they are
|
|
340
|
+
-- RTRIM-equal) and under-fetch ('cat ' < 'cat ' in bytes, but RTRIM-equal).
|
|
341
|
+
create table rng_pk_rt (val text collate RTRIM primary key, n integer);
|
|
342
|
+
insert into rng_pk_rt values ('ant', 1), ('cat ', 2), ('dog', 3);
|
|
343
|
+
|
|
344
|
+
-- 'cat ' RTRIM-equals the bound 'cat', so > excludes it.
|
|
345
|
+
select n from rng_pk_rt where val > 'cat' order by n;
|
|
346
|
+
→ [{"n":3}]
|
|
347
|
+
|
|
348
|
+
-- The bound's trailing spaces are ignored: >= 'cat ' includes the RTRIM-equal 'cat '.
|
|
349
|
+
select n from rng_pk_rt where val >= 'cat ' order by n;
|
|
350
|
+
→ [{"n":2},{"n":3}]
|
|
351
|
+
|
|
352
|
+
-- Both BETWEEN bounds trim: ['ant','cat'] keeps 'ant' and 'cat ', excludes 'dog'.
|
|
353
|
+
select n from rng_pk_rt where val between 'ant ' and 'cat ' order by n;
|
|
354
|
+
→ [{"n":1},{"n":2}]
|
|
355
|
+
|
|
356
|
+
drop table rng_pk_rt;
|
|
357
|
+
|
|
358
|
+
-- BINARY negative control: an EXPLICIT `collate BINARY` PK (explicit so the store
|
|
359
|
+
-- does not reconcile the column to its NOCASE key-collation default) keeps plain
|
|
360
|
+
-- BINARY range semantics on both backends — uppercase sorts before lowercase, so
|
|
361
|
+
-- 'apple' and 'date' are BINARY-greater than 'CHERRY' while 'Banana' is not.
|
|
362
|
+
create table rng_pk_b (name text collate BINARY primary key, n integer);
|
|
363
|
+
insert into rng_pk_b values ('Banana', 1), ('apple', 2), ('CHERRY', 3), ('date', 4);
|
|
364
|
+
|
|
365
|
+
select n from rng_pk_b where name > 'CHERRY' order by n;
|
|
366
|
+
→ [{"n":2},{"n":4}]
|
|
367
|
+
|
|
368
|
+
drop table rng_pk_b;
|
|
369
|
+
|
|
370
|
+
-- The SECONDARY-index variants of these ranges (NOCASE and RTRIM) live in
|
|
371
|
+
-- 06.4.2.1-collation-index-access-paths.
|
|
372
|
+
|
|
373
|
+
-- min/max under the column's declared collation (not unconditional BINARY):
|
|
374
|
+
-- NOCASE ranks 'a' below 'B', while BINARY would report mn=B, mx=a. The values
|
|
375
|
+
-- carry no NOCASE ties, so the extrema are deterministic; under a tie ('a' vs
|
|
376
|
+
-- 'A') which raw spelling survives is unspecified — same latitude as DISTINCT.
|
|
377
|
+
create table mm_nc (id integer primary key, t text collate NOCASE);
|
|
378
|
+
insert into mm_nc values (1, 'B'), (2, 'a');
|
|
379
|
+
|
|
380
|
+
-- min/max agree with the ordering sites (order by … limit 1)
|
|
381
|
+
select (min(t) = (select t from mm_nc order by t limit 1)) as min_agrees,
|
|
382
|
+
(max(t) = (select t from mm_nc order by t desc limit 1)) as max_agrees
|
|
383
|
+
from mm_nc;
|
|
384
|
+
→ [{"min_agrees":true,"max_agrees":true}]
|
|
385
|
+
|
|
386
|
+
select min(t) as mn, max(t) as mx from mm_nc;
|
|
387
|
+
→ [{"mn":"a","mx":"B"}]
|
|
388
|
+
|
|
389
|
+
drop table mm_nc;
|
|
390
|
+
|
|
391
|
+
-- =============================================================================
|
|
392
|
+
-- nullif / greatest / least resolve their comparison exactly as `=` does
|
|
393
|
+
-- =============================================================================
|
|
394
|
+
-- All three builtins declare their arguments as one comparison group, so each
|
|
395
|
+
-- call site resolves ONE collation through the same provenance lattice `=` uses
|
|
396
|
+
-- (explicit COLLATE > declared column collation > defaults > BINARY) and
|
|
397
|
+
-- compares under it. Each assertion sits next to the corresponding `=` form so
|
|
398
|
+
-- a future divergence shows up in one place. Regression for
|
|
399
|
+
-- `nullif-greatest-least-comparison-seam` (previously all three compared raw
|
|
400
|
+
-- bytes under BINARY and disagreed with `=` on collated columns).
|
|
401
|
+
|
|
402
|
+
create table nf (id integer primary key, n text collate NOCASE, m text collate NOCASE);
|
|
403
|
+
insert into nf values (1, 'a', 'B');
|
|
404
|
+
|
|
405
|
+
-- The declared NOCASE collation governs `=` and nullif alike.
|
|
406
|
+
select (n = 'A') as r from nf;
|
|
407
|
+
→ [{"r":true}]
|
|
408
|
+
|
|
409
|
+
select nullif(n, 'A') as r from nf;
|
|
410
|
+
→ [{"r":null}]
|
|
411
|
+
|
|
412
|
+
-- A NOCASE-distinct value still comes through unchanged.
|
|
413
|
+
select nullif(n, 'x') as r from nf;
|
|
414
|
+
→ [{"r":"a"}]
|
|
415
|
+
|
|
416
|
+
-- greatest/least rank under NOCASE: 'a' < 'B' (BINARY would rank 'B' < 'a').
|
|
417
|
+
-- The values are NOCASE-distinct, so no tie-representative is pinned.
|
|
418
|
+
select greatest(n, m) as g, least(n, m) as l from nf;
|
|
419
|
+
→ [{"g":"B","l":"a"}]
|
|
420
|
+
|
|
421
|
+
drop table nf;
|
|
422
|
+
|
|
423
|
+
-- Explicit COLLATE on either operand governs the group (a BINARY-defaulted
|
|
424
|
+
-- column must not shadow it) — same rule as `=`.
|
|
425
|
+
create table nfx (id integer primary key, n text);
|
|
426
|
+
insert into nfx values (1, 'a');
|
|
427
|
+
|
|
428
|
+
select (n collate NOCASE = 'A') as r from nfx;
|
|
429
|
+
→ [{"r":true}]
|
|
430
|
+
|
|
431
|
+
select nullif(n collate NOCASE, 'A') as r from nfx;
|
|
432
|
+
→ [{"r":null}]
|
|
433
|
+
|
|
434
|
+
select nullif(n, 'A' collate NOCASE) as r from nfx;
|
|
435
|
+
→ [{"r":null}]
|
|
436
|
+
|
|
437
|
+
-- Plain BINARY stays case-sensitive.
|
|
438
|
+
select nullif(n, 'A') as r from nfx;
|
|
439
|
+
→ [{"r":"a"}]
|
|
440
|
+
|
|
441
|
+
-- greatest/least under an explicit NOCASE: 'a' < 'B' (BINARY would flip both).
|
|
442
|
+
select greatest(n collate NOCASE, 'B') as g, least(n collate NOCASE, 'B') as l from nfx;
|
|
443
|
+
→ [{"g":"B","l":"a"}]
|
|
444
|
+
|
|
445
|
+
-- An explicit-COLLATE conflict inside the group is the same error `=` raises
|
|
446
|
+
-- for the same operand pair.
|
|
447
|
+
select nullif(n collate NOCASE, 'A' collate RTRIM) as r from nfx;
|
|
448
|
+
-- error: conflicting COLLATE clauses in comparison
|
|
449
|
+
|
|
450
|
+
select greatest(n collate NOCASE, 'A' collate RTRIM) as r from nfx;
|
|
451
|
+
-- error: conflicting COLLATE clauses in comparison
|
|
452
|
+
|
|
453
|
+
select (n collate NOCASE = 'A' collate RTRIM) as r from nfx;
|
|
454
|
+
-- error: conflicting COLLATE clauses in comparison
|
|
455
|
+
|
|
456
|
+
drop table nfx;
|
|
457
|
+
|
|
458
|
+
-- Declared-collation conflict between two differently-collated columns is the
|
|
459
|
+
-- ambiguity error, matching `=`.
|
|
460
|
+
create table nfc (id integer primary key, a text collate NOCASE, b text collate RTRIM);
|
|
461
|
+
insert into nfc values (1, 'x', 'x');
|
|
462
|
+
|
|
463
|
+
select (a = b) as r from nfc;
|
|
464
|
+
-- error: ambiguous collation for comparison
|
|
465
|
+
|
|
466
|
+
select nullif(a, b) as r from nfc;
|
|
467
|
+
-- error: ambiguous collation for comparison
|
|
468
|
+
|
|
469
|
+
select least(a, b) as r from nfc;
|
|
470
|
+
-- error: ambiguous collation for comparison
|
|
471
|
+
|
|
472
|
+
drop table nfc;
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
-- 06.4.2.1-collation-index-access-paths.sqllogic — collation through standalone index DDL.
|
|
2
|
+
--
|
|
3
|
+
-- requires-capability: standalone-index-ddl
|
|
4
|
+
--
|
|
5
|
+
-- Carved out of 06.4.2-collation-extras: the bulk of that file (ORDER BY, JOIN,
|
|
6
|
+
-- DISTINCT, set operations, MIN/MAX, CASE, BETWEEN, and the PRIMARY-KEY range /
|
|
7
|
+
-- BETWEEN seeks) proves collation propagation with no index DDL at all. The three
|
|
8
|
+
-- sections below need an explicit `create index`, either to give a key a collation
|
|
9
|
+
-- that differs from its column's or to place a SECONDARY index in the access path,
|
|
10
|
+
-- so they move here and leave the rest portable.
|
|
11
|
+
--
|
|
12
|
+
-- Subject: (1) `create index … (col collate X)` resolves to a per-column index
|
|
13
|
+
-- collation (and a genuine expression index is still rejected), (2) an equality or
|
|
14
|
+
-- range whose predicate collation does not match the index collation must decline the
|
|
15
|
+
-- seek and fall back to scan + residual rather than return the index's rows, and
|
|
16
|
+
-- (3) a matching-collation SECONDARY index seek returns the collation-correct rows.
|
|
17
|
+
|
|
18
|
+
-- =============================================================================
|
|
19
|
+
-- INDEX with an explicit per-column COLLATE
|
|
20
|
+
-- =============================================================================
|
|
21
|
+
-- The parser folds `name COLLATE NOCASE` into a collate expression over the column;
|
|
22
|
+
-- the live CREATE INDEX path resolves it to a per-column collation (it is NOT a
|
|
23
|
+
-- genuine expression index). A non-column operand like lower(name) is still rejected.
|
|
24
|
+
|
|
25
|
+
create table coll_idx (id integer primary key, name text);
|
|
26
|
+
insert into coll_idx values (1, 'Alice'), (2, 'BOB'), (3, 'charlie'), (4, 'Bob');
|
|
27
|
+
|
|
28
|
+
create index idx_name_nc on coll_idx (name collate NOCASE);
|
|
29
|
+
|
|
30
|
+
-- index_info reports the resolved per-column collation.
|
|
31
|
+
select column_name, collation from index_info('coll_idx');
|
|
32
|
+
→ [{"column_name":"name","collation":"NOCASE"}]
|
|
33
|
+
|
|
34
|
+
-- A genuine expression index (non-column operand) is still rejected.
|
|
35
|
+
create index idx_name_lower on coll_idx (lower(name));
|
|
36
|
+
-- error: Indices on expressions are not supported
|
|
37
|
+
|
|
38
|
+
-- Equality search whose predicate carries its own COLLATE NOCASE matches
|
|
39
|
+
-- case-insensitively (consistent with the NOCASE index, so correct either way).
|
|
40
|
+
select id from coll_idx where name = 'bob' collate NOCASE order by id;
|
|
41
|
+
→ [{"id":2},{"id":4}]
|
|
42
|
+
|
|
43
|
+
-- A plain BINARY equality (`where name = 'BOB'`) over the coarser NOCASE index
|
|
44
|
+
-- must re-apply the BINARY predicate as a residual filter above the seek, so the
|
|
45
|
+
-- collation-equal-but-BINARY-distinct 'Bob' (id 4) is discarded. (Previously a
|
|
46
|
+
-- latent planner bug returned id 2 AND 4, fixed by access-path collation cover.)
|
|
47
|
+
select id from coll_idx where name = 'BOB' order by id;
|
|
48
|
+
→ [{"id":2}]
|
|
49
|
+
|
|
50
|
+
-- A BINARY range over the NOCASE index must not walk the reordered index window;
|
|
51
|
+
-- the access path declines the seek and falls back to a scan + residual so the
|
|
52
|
+
-- BINARY-correct rows are returned ('charlie' id 3 and 'Bob' id 4 are both
|
|
53
|
+
-- BINARY-greater than 'BOB', while a NOCASE index seek would have missed 'Bob').
|
|
54
|
+
select id from coll_idx where name > 'BOB' order by id;
|
|
55
|
+
→ [{"id":3},{"id":4}]
|
|
56
|
+
|
|
57
|
+
drop table coll_idx;
|
|
58
|
+
|
|
59
|
+
-- =============================================================================
|
|
60
|
+
-- Symmetric case: BINARY index, NOCASE-collated predicate (finer index)
|
|
61
|
+
-- =============================================================================
|
|
62
|
+
-- A BINARY index cannot satisfy a NOCASE equality (it UNDER-fetches: a residual
|
|
63
|
+
-- cannot recover the rows the seek never visited), so the access path declines the
|
|
64
|
+
-- index and scans + residual — all case variants are returned.
|
|
65
|
+
|
|
66
|
+
create table coll_idx_bin (id integer primary key, name text);
|
|
67
|
+
insert into coll_idx_bin values (1, 'Alice'), (2, 'BOB'), (3, 'charlie'), (4, 'Bob');
|
|
68
|
+
create index idx_name_bin on coll_idx_bin (name);
|
|
69
|
+
|
|
70
|
+
select id from coll_idx_bin where name = 'bob' collate NOCASE order by id;
|
|
71
|
+
→ [{"id":2},{"id":4}]
|
|
72
|
+
|
|
73
|
+
-- Plain BINARY equality over the matching BINARY index is unaffected (no residual).
|
|
74
|
+
select id from coll_idx_bin where name = 'Bob' order by id;
|
|
75
|
+
→ [{"id":4}]
|
|
76
|
+
|
|
77
|
+
drop table coll_idx_bin;
|
|
78
|
+
|
|
79
|
+
-- =============================================================================
|
|
80
|
+
-- COLLATE on a BETWEEN bound over an index (access-path cover classification)
|
|
81
|
+
-- =============================================================================
|
|
82
|
+
-- The access path resolves each bound's effective collation per-constraint
|
|
83
|
+
-- (lower → `>=`, upper → `<=`) and either keeps the seek (collations match) or
|
|
84
|
+
-- declines to a scan + residual (mismatch). All forms must agree with the scan.
|
|
85
|
+
|
|
86
|
+
create table btw_nc (id integer primary key, name text);
|
|
87
|
+
insert into btw_nc values (1, 'Alice'), (2, 'BOB'), (3, 'charlie'), (4, 'Bob');
|
|
88
|
+
create index idx_btw_nc on btw_nc (name collate NOCASE);
|
|
89
|
+
|
|
90
|
+
-- Both bounds NOCASE over a NOCASE index: collations match on both bounds, so the
|
|
91
|
+
-- seek is usable and returns the NOCASE-'bob'-equal rows directly.
|
|
92
|
+
select id from btw_nc where name between 'bob' collate NOCASE and 'bob' collate NOCASE order by id;
|
|
93
|
+
→ [{"id":2},{"id":4}]
|
|
94
|
+
|
|
95
|
+
-- Mixed bounds over the NOCASE index (lower NOCASE matches, upper BINARY does not):
|
|
96
|
+
-- the access path declines the seek and scans + residual, matching the scan form.
|
|
97
|
+
select id from btw_nc where name between 'bob' collate NOCASE and 'bob' order by id;
|
|
98
|
+
→ [{"id":2},{"id":4}]
|
|
99
|
+
|
|
100
|
+
drop table btw_nc;
|
|
101
|
+
|
|
102
|
+
-- BINARY index, both bounds NOCASE: the NOCASE bound collations do not match the
|
|
103
|
+
-- BINARY index, so the seek is declined (it would under-fetch in BINARY order) and
|
|
104
|
+
-- the scan + residual returns the NOCASE-correct rows. Previously the bound collation
|
|
105
|
+
-- was ignored and the seek silently returned the wrong rows.
|
|
106
|
+
create table btw_bin (id integer primary key, name text);
|
|
107
|
+
insert into btw_bin values (1, 'Alice'), (2, 'BOB'), (3, 'charlie'), (4, 'Bob');
|
|
108
|
+
create index idx_btw_bin on btw_bin (name);
|
|
109
|
+
|
|
110
|
+
select id from btw_bin where name between 'bob' collate NOCASE and 'bob' collate NOCASE order by id;
|
|
111
|
+
→ [{"id":2},{"id":4}]
|
|
112
|
+
|
|
113
|
+
drop table btw_bin;
|
|
114
|
+
-- =============================================================================
|
|
115
|
+
-- Collation-matched non-BINARY range over a matching-collation SECONDARY index
|
|
116
|
+
-- =============================================================================
|
|
117
|
+
-- Same subject as 06.4.2's primary-key range/BETWEEN section (the module's own bound
|
|
118
|
+
-- filter produces these rows, no residual Filter), one level down on a secondary index.
|
|
119
|
+
|
|
120
|
+
-- NOCASE secondary index over case-variant rows (non-unique index): the >= bound
|
|
121
|
+
-- includes both 'Banana' and 'BANANA'.
|
|
122
|
+
create table rng_sec_nc (id integer primary key, name text collate NOCASE);
|
|
123
|
+
insert into rng_sec_nc values (1, 'apple'), (2, 'Banana'), (3, 'CHERRY'), (4, 'date'), (5, 'BANANA');
|
|
124
|
+
create index idx_rng_sec_nc on rng_sec_nc (name);
|
|
125
|
+
|
|
126
|
+
select id from rng_sec_nc where name >= 'banana' order by id;
|
|
127
|
+
→ [{"id":2},{"id":3},{"id":4},{"id":5}]
|
|
128
|
+
|
|
129
|
+
drop table rng_sec_nc;
|
|
130
|
+
|
|
131
|
+
-- RTRIM range: trailing spaces ignored on both the bound and the stored values.
|
|
132
|
+
create table rng_rtrim (id integer primary key, val text collate RTRIM);
|
|
133
|
+
insert into rng_rtrim values (1, 'cat'), (2, 'cat '), (3, 'dog'), (4, 'doe '), (5, 'ant');
|
|
134
|
+
create index idx_rng_rtrim on rng_rtrim (val);
|
|
135
|
+
|
|
136
|
+
select id from rng_rtrim where val > 'cat' order by id;
|
|
137
|
+
→ [{"id":3},{"id":4}]
|
|
138
|
+
|
|
139
|
+
drop table rng_rtrim;
|
|
140
|
+
|