@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,227 @@
|
|
|
1
|
+
-- null-edge-cases.sqllogic - Systematic NULL behavior tests across SQL positions
|
|
2
|
+
|
|
3
|
+
-- =============================================================================
|
|
4
|
+
-- Setup
|
|
5
|
+
-- =============================================================================
|
|
6
|
+
|
|
7
|
+
create table n1 (id integer primary key, val integer null, txt text null);
|
|
8
|
+
insert into n1 values (1, 10, 'a'), (2, null, 'b'), (3, 30, null), (4, null, null);
|
|
9
|
+
|
|
10
|
+
-- =============================================================================
|
|
11
|
+
-- NULL in join keys
|
|
12
|
+
-- =============================================================================
|
|
13
|
+
|
|
14
|
+
create table n2 (id integer primary key, ref integer null);
|
|
15
|
+
insert into n2 values (1, 10), (2, null), (3, 30);
|
|
16
|
+
|
|
17
|
+
-- INNER JOIN: NULL keys should NOT match
|
|
18
|
+
select n1.id, n1.val, n2.id, n2.ref from n1 inner join n2 on n1.val = n2.ref order by n1.id;
|
|
19
|
+
→ [{"id":1,"val":10,"id:1":1,"ref":10},{"id":3,"val":30,"id:1":3,"ref":30}]
|
|
20
|
+
|
|
21
|
+
-- LEFT JOIN: rows with null val get null on right side
|
|
22
|
+
select n1.id, n1.val, n2.id, n2.ref from n1 left join n2 on n1.val = n2.ref order by n1.id;
|
|
23
|
+
→ [{"id":1,"val":10,"id:1":1,"ref":10},{"id":2,"val":null,"id:1":null,"ref":null},{"id":3,"val":30,"id:1":3,"ref":30},{"id":4,"val":null,"id:1":null,"ref":null}]
|
|
24
|
+
|
|
25
|
+
-- Both sides NULL: verify NULLs don't join (NULL ≠ NULL)
|
|
26
|
+
select count(*) as cnt from n1 inner join n2 on n1.val = n2.ref;
|
|
27
|
+
→ [{"cnt":2}]
|
|
28
|
+
|
|
29
|
+
drop table n2;
|
|
30
|
+
|
|
31
|
+
-- =============================================================================
|
|
32
|
+
-- NULL in GROUP BY key
|
|
33
|
+
-- =============================================================================
|
|
34
|
+
|
|
35
|
+
-- NULLs grouped together into one group (NULLs first in default ordering)
|
|
36
|
+
select val, count(*) as cnt from n1 group by val order by val;
|
|
37
|
+
→ [{"val":null,"cnt":2},{"val":10,"cnt":1},{"val":30,"cnt":1}]
|
|
38
|
+
|
|
39
|
+
-- =============================================================================
|
|
40
|
+
-- NULL in ORDER BY
|
|
41
|
+
-- =============================================================================
|
|
42
|
+
|
|
43
|
+
-- Default ASC: NULLs come first
|
|
44
|
+
select id, val from n1 order by val, id;
|
|
45
|
+
→ [{"id":2,"val":null},{"id":4,"val":null},{"id":1,"val":10},{"id":3,"val":30}]
|
|
46
|
+
|
|
47
|
+
-- NULLS FIRST explicit (same as default ASC)
|
|
48
|
+
select id, val from n1 order by val nulls first, id;
|
|
49
|
+
→ [{"id":2,"val":null},{"id":4,"val":null},{"id":1,"val":10},{"id":3,"val":30}]
|
|
50
|
+
|
|
51
|
+
-- NULLS LAST moves NULLs to end
|
|
52
|
+
select id, val from n1 order by val nulls last, id;
|
|
53
|
+
→ [{"id":1,"val":10},{"id":3,"val":30},{"id":2,"val":null},{"id":4,"val":null}]
|
|
54
|
+
|
|
55
|
+
-- DESC with NULLS FIRST on text column
|
|
56
|
+
select id, txt from n1 order by txt desc nulls first, id;
|
|
57
|
+
→ [{"id":3,"txt":null},{"id":4,"txt":null},{"id":2,"txt":"b"},{"id":1,"txt":"a"}]
|
|
58
|
+
|
|
59
|
+
-- DESC with NULLS LAST moves NULLs to end
|
|
60
|
+
select id, val from n1 order by val desc nulls last, id;
|
|
61
|
+
→ [{"id":3,"val":30},{"id":1,"val":10},{"id":2,"val":null},{"id":4,"val":null}]
|
|
62
|
+
|
|
63
|
+
-- DESC with NULLS LAST on text column
|
|
64
|
+
select id, txt from n1 order by txt desc nulls last, id;
|
|
65
|
+
→ [{"id":2,"txt":"b"},{"id":1,"txt":"a"},{"id":3,"txt":null},{"id":4,"txt":null}]
|
|
66
|
+
|
|
67
|
+
-- =============================================================================
|
|
68
|
+
-- NULL in CASE WHEN
|
|
69
|
+
-- =============================================================================
|
|
70
|
+
|
|
71
|
+
-- NULL condition is falsy → else branch
|
|
72
|
+
select case when null then 'yes' else 'no' end as r;
|
|
73
|
+
→ [{"r":"no"}]
|
|
74
|
+
|
|
75
|
+
-- IS NULL in CASE WHEN
|
|
76
|
+
select id, case when val is null then 'missing' else 'present' end as status from n1 order by id;
|
|
77
|
+
→ [{"id":1,"status":"present"},{"id":2,"status":"missing"},{"id":3,"status":"present"},{"id":4,"status":"missing"}]
|
|
78
|
+
|
|
79
|
+
-- Simple CASE: NULL ≠ NULL so 'no match'
|
|
80
|
+
select case null when null then 'match' else 'no match' end as r;
|
|
81
|
+
→ [{"r":"no match"}]
|
|
82
|
+
|
|
83
|
+
-- CASE with NULL result branch
|
|
84
|
+
select id, case when id = 2 then null else val end as r from n1 order by id;
|
|
85
|
+
→ [{"id":1,"r":10},{"id":2,"r":null},{"id":3,"r":30},{"id":4,"r":null}]
|
|
86
|
+
|
|
87
|
+
-- =============================================================================
|
|
88
|
+
-- NULL in IN list and as IN operand
|
|
89
|
+
-- =============================================================================
|
|
90
|
+
|
|
91
|
+
-- NULL in IN list doesn't match NULL vals; only exact matches
|
|
92
|
+
select id, val from n1 where val in (10, null, 30) order by id;
|
|
93
|
+
→ [{"id":1,"val":10},{"id":3,"val":30}]
|
|
94
|
+
|
|
95
|
+
-- NOT IN with NULL in list: returns no rows
|
|
96
|
+
-- val NOT IN (10, NULL) → val<>10 AND val<>NULL → unknown for all non-10 values
|
|
97
|
+
select id, val from n1 where val not in (10, null) order by id;
|
|
98
|
+
→ []
|
|
99
|
+
|
|
100
|
+
-- NULL as IN operand: always unknown
|
|
101
|
+
select * from n1 where null in (1, 2, 3);
|
|
102
|
+
→ []
|
|
103
|
+
|
|
104
|
+
-- =============================================================================
|
|
105
|
+
-- NULL in aggregate arguments
|
|
106
|
+
-- =============================================================================
|
|
107
|
+
|
|
108
|
+
-- count(col) skips NULLs
|
|
109
|
+
select count(val) as cnt from n1;
|
|
110
|
+
→ [{"cnt":2}]
|
|
111
|
+
|
|
112
|
+
-- count(*) counts all rows
|
|
113
|
+
select count(*) as cnt from n1;
|
|
114
|
+
→ [{"cnt":4}]
|
|
115
|
+
|
|
116
|
+
-- sum skips NULLs
|
|
117
|
+
select sum(val) as s from n1;
|
|
118
|
+
→ [{"s":40}]
|
|
119
|
+
|
|
120
|
+
-- avg skips NULLs (40/2 = 20)
|
|
121
|
+
select avg(val) as a from n1;
|
|
122
|
+
→ [{"a":20}]
|
|
123
|
+
|
|
124
|
+
-- min skips NULLs
|
|
125
|
+
select min(val) as mn from n1;
|
|
126
|
+
→ [{"mn":10}]
|
|
127
|
+
|
|
128
|
+
-- max skips NULLs
|
|
129
|
+
select max(val) as mx from n1;
|
|
130
|
+
→ [{"mx":30}]
|
|
131
|
+
|
|
132
|
+
-- group_concat skips NULLs
|
|
133
|
+
select group_concat(txt, ',') as g from n1;
|
|
134
|
+
→ [{"g":"a,b"}]
|
|
135
|
+
|
|
136
|
+
-- =============================================================================
|
|
137
|
+
-- NULL in window functions
|
|
138
|
+
-- =============================================================================
|
|
139
|
+
|
|
140
|
+
-- PARTITION BY groups NULLs together
|
|
141
|
+
select id, val, row_number() over (partition by val order by id) as rn from n1 order by id;
|
|
142
|
+
→ [{"id":1,"val":10,"rn":1},{"id":2,"val":null,"rn":1},{"id":3,"val":30,"rn":1},{"id":4,"val":null,"rn":2}]
|
|
143
|
+
|
|
144
|
+
-- RANK with NULLs: null vals get same rank
|
|
145
|
+
select id, val, rank() over (order by val) as rnk from n1 order by id;
|
|
146
|
+
→ [{"id":1,"val":10,"rnk":3},{"id":2,"val":null,"rnk":1},{"id":3,"val":30,"rnk":4},{"id":4,"val":null,"rnk":1}]
|
|
147
|
+
|
|
148
|
+
-- =============================================================================
|
|
149
|
+
-- NULL in COALESCE chains
|
|
150
|
+
-- =============================================================================
|
|
151
|
+
|
|
152
|
+
select coalesce(null) as r;
|
|
153
|
+
→ [{"r":null}]
|
|
154
|
+
|
|
155
|
+
select coalesce(null, null, null) as r;
|
|
156
|
+
→ [{"r":null}]
|
|
157
|
+
|
|
158
|
+
select coalesce(null, null, 'found') as r;
|
|
159
|
+
→ [{"r":"found"}]
|
|
160
|
+
|
|
161
|
+
-- Per-row cascade: first non-null wins
|
|
162
|
+
select id, coalesce(val, txt, 'default') as r from n1 order by id;
|
|
163
|
+
→ [{"id":1,"r":10},{"id":2,"r":"b"},{"id":3,"r":30},{"id":4,"r":"default"}]
|
|
164
|
+
|
|
165
|
+
-- =============================================================================
|
|
166
|
+
-- NULL with every comparison operator
|
|
167
|
+
-- =============================================================================
|
|
168
|
+
|
|
169
|
+
select null = null as r;
|
|
170
|
+
→ [{"r":null}]
|
|
171
|
+
|
|
172
|
+
select null <> null as r;
|
|
173
|
+
→ [{"r":null}]
|
|
174
|
+
|
|
175
|
+
select null < 1 as r;
|
|
176
|
+
→ [{"r":null}]
|
|
177
|
+
|
|
178
|
+
select null > 1 as r;
|
|
179
|
+
→ [{"r":null}]
|
|
180
|
+
|
|
181
|
+
select null <= 1 as r;
|
|
182
|
+
→ [{"r":null}]
|
|
183
|
+
|
|
184
|
+
select null >= 1 as r;
|
|
185
|
+
→ [{"r":null}]
|
|
186
|
+
|
|
187
|
+
select null is null as r;
|
|
188
|
+
→ [{"r":true}]
|
|
189
|
+
|
|
190
|
+
select null is not null as r;
|
|
191
|
+
→ [{"r":false}]
|
|
192
|
+
|
|
193
|
+
select 1 is null as r;
|
|
194
|
+
→ [{"r":false}]
|
|
195
|
+
|
|
196
|
+
select 1 is not null as r;
|
|
197
|
+
→ [{"r":true}]
|
|
198
|
+
|
|
199
|
+
-- =============================================================================
|
|
200
|
+
-- NULL in DISTINCT
|
|
201
|
+
-- =============================================================================
|
|
202
|
+
|
|
203
|
+
-- NULLs are equal for DISTINCT: only one NULL in output
|
|
204
|
+
select distinct val from n1 order by val;
|
|
205
|
+
→ [{"val":null},{"val":10},{"val":30}]
|
|
206
|
+
|
|
207
|
+
-- =============================================================================
|
|
208
|
+
-- NULL in subqueries
|
|
209
|
+
-- =============================================================================
|
|
210
|
+
|
|
211
|
+
-- EXISTS with subquery returning null row: true (row exists, value doesn't matter)
|
|
212
|
+
select exists (select null) as r;
|
|
213
|
+
→ [{"r":true}]
|
|
214
|
+
|
|
215
|
+
-- Scalar subquery returning null
|
|
216
|
+
select (select null) as r;
|
|
217
|
+
→ [{"r":null}]
|
|
218
|
+
|
|
219
|
+
-- IN with null subquery result: unknown
|
|
220
|
+
select 1 in (select null) as r;
|
|
221
|
+
→ [{"r":null}]
|
|
222
|
+
|
|
223
|
+
-- =============================================================================
|
|
224
|
+
-- Cleanup
|
|
225
|
+
-- =============================================================================
|
|
226
|
+
|
|
227
|
+
drop table n1;
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
-- where-null-comparisons.sqllogic - WHERE-clause three-valued logic for NULL operands
|
|
2
|
+
-- Distilled from SQLite test/where5.test and test/null.test
|
|
3
|
+
|
|
4
|
+
create table wn (id integer primary key, val integer null, txt text null);
|
|
5
|
+
insert into wn values (1, 10, 'a'), (2, null, 'b'), (3, 30, null), (4, null, null);
|
|
6
|
+
|
|
7
|
+
-- =============================================================================
|
|
8
|
+
-- col <op> NULL is unknown -> WHERE filters out all rows
|
|
9
|
+
-- =============================================================================
|
|
10
|
+
|
|
11
|
+
select id from wn where val = null order by id;
|
|
12
|
+
→ []
|
|
13
|
+
|
|
14
|
+
select id from wn where val != null order by id;
|
|
15
|
+
→ []
|
|
16
|
+
|
|
17
|
+
select id from wn where val <> null order by id;
|
|
18
|
+
→ []
|
|
19
|
+
|
|
20
|
+
select id from wn where val < null order by id;
|
|
21
|
+
→ []
|
|
22
|
+
|
|
23
|
+
select id from wn where val <= null order by id;
|
|
24
|
+
→ []
|
|
25
|
+
|
|
26
|
+
select id from wn where val > null order by id;
|
|
27
|
+
→ []
|
|
28
|
+
|
|
29
|
+
select id from wn where val >= null order by id;
|
|
30
|
+
→ []
|
|
31
|
+
|
|
32
|
+
select id from wn where txt = null order by id;
|
|
33
|
+
→ []
|
|
34
|
+
|
|
35
|
+
-- =============================================================================
|
|
36
|
+
-- NULL <op> col / NULL <op> NULL is unknown -> no rows
|
|
37
|
+
-- =============================================================================
|
|
38
|
+
|
|
39
|
+
select id from wn where null = val order by id;
|
|
40
|
+
→ []
|
|
41
|
+
|
|
42
|
+
select id from wn where null < val order by id;
|
|
43
|
+
→ []
|
|
44
|
+
|
|
45
|
+
select id from wn where null = null order by id;
|
|
46
|
+
→ []
|
|
47
|
+
|
|
48
|
+
select id from wn where null != null order by id;
|
|
49
|
+
→ []
|
|
50
|
+
|
|
51
|
+
-- Bare NULL in WHERE is falsy
|
|
52
|
+
select id from wn where null order by id;
|
|
53
|
+
→ []
|
|
54
|
+
|
|
55
|
+
-- NOT NULL in WHERE is also unknown -> no rows
|
|
56
|
+
select id from wn where not null order by id;
|
|
57
|
+
→ []
|
|
58
|
+
|
|
59
|
+
-- =============================================================================
|
|
60
|
+
-- Arithmetic propagating NULL into a comparison
|
|
61
|
+
-- =============================================================================
|
|
62
|
+
|
|
63
|
+
select id from wn where val + null > 5 order by id;
|
|
64
|
+
→ []
|
|
65
|
+
|
|
66
|
+
select id from wn where val + null is null order by id;
|
|
67
|
+
→ [{"id":1},{"id":2},{"id":3},{"id":4}]
|
|
68
|
+
|
|
69
|
+
select id from wn where (val * 0) = null order by id;
|
|
70
|
+
→ []
|
|
71
|
+
|
|
72
|
+
-- =============================================================================
|
|
73
|
+
-- NOT around a NULL-producing comparison stays unknown
|
|
74
|
+
-- =============================================================================
|
|
75
|
+
|
|
76
|
+
select id from wn where not (val = null) order by id;
|
|
77
|
+
→ []
|
|
78
|
+
|
|
79
|
+
select id from wn where not (val < null) order by id;
|
|
80
|
+
→ []
|
|
81
|
+
|
|
82
|
+
select id from wn where not (val + null > 5) order by id;
|
|
83
|
+
→ []
|
|
84
|
+
|
|
85
|
+
-- =============================================================================
|
|
86
|
+
-- IS / IS NOT are null-safe and produce TRUE/FALSE, never NULL
|
|
87
|
+
-- =============================================================================
|
|
88
|
+
|
|
89
|
+
select id from wn where val is null order by id;
|
|
90
|
+
→ [{"id":2},{"id":4}]
|
|
91
|
+
|
|
92
|
+
select id from wn where val is not null order by id;
|
|
93
|
+
→ [{"id":1},{"id":3}]
|
|
94
|
+
|
|
95
|
+
-- (Quereus parser restricts IS to IS NULL / IS NOT NULL — null-safe equality form not supported)
|
|
96
|
+
|
|
97
|
+
-- IS NULL inside a NOT is still TRUE/FALSE
|
|
98
|
+
select id from wn where not (val is null) order by id;
|
|
99
|
+
→ [{"id":1},{"id":3}]
|
|
100
|
+
|
|
101
|
+
select id from wn where not (val is not null) order by id;
|
|
102
|
+
→ [{"id":2},{"id":4}]
|
|
103
|
+
|
|
104
|
+
-- =============================================================================
|
|
105
|
+
-- Compound with AND/OR: unknown short-circuits AND but not OR-with-true
|
|
106
|
+
-- =============================================================================
|
|
107
|
+
|
|
108
|
+
-- val > 5 AND val = NULL: AND of (true|null) and unknown -> all unknown
|
|
109
|
+
select id from wn where val > 5 and val = null order by id;
|
|
110
|
+
→ []
|
|
111
|
+
|
|
112
|
+
-- val > 5 OR val = NULL: OR of (true|null) and unknown -> id=1,3 keep true; id=2,4 stay null
|
|
113
|
+
select id from wn where val > 5 or val = null order by id;
|
|
114
|
+
→ [{"id":1},{"id":3}]
|
|
115
|
+
|
|
116
|
+
-- TRUE OR unknown -> TRUE: id=1 wins via val=10; rest stay unknown
|
|
117
|
+
select id from wn where val = 10 or val = null order by id;
|
|
118
|
+
→ [{"id":1}]
|
|
119
|
+
|
|
120
|
+
-- =============================================================================
|
|
121
|
+
-- NULL comparisons against key columns must not become seek bounds
|
|
122
|
+
-- (key ordering sorts NULL below everything, so a pushed `> NULL` lower bound
|
|
123
|
+
-- would wrongly match every row)
|
|
124
|
+
-- =============================================================================
|
|
125
|
+
|
|
126
|
+
select id from wn where id > null order by id;
|
|
127
|
+
→ []
|
|
128
|
+
|
|
129
|
+
select id from wn where null < id order by id;
|
|
130
|
+
→ []
|
|
131
|
+
|
|
132
|
+
select id from wn where id >= null order by id;
|
|
133
|
+
→ []
|
|
134
|
+
|
|
135
|
+
select id from wn where id between null and 3 order by id;
|
|
136
|
+
→ []
|
|
137
|
+
|
|
138
|
+
select id from wn where id between 1 and null order by id;
|
|
139
|
+
→ []
|
|
140
|
+
|
|
141
|
+
select id from wn where (+ null) < id order by id;
|
|
142
|
+
→ []
|
|
143
|
+
|
|
144
|
+
-- Sanity: non-NULL bounds on the same column still seek correctly
|
|
145
|
+
select id from wn where id > 3 order by id;
|
|
146
|
+
→ [{"id":4}]
|
|
147
|
+
|
|
148
|
+
-- The same assertions against a SECONDARY-INDEXED column live in
|
|
149
|
+
-- 21.1.1-where-null-comparisons-secondary-index (they need standalone CREATE INDEX).
|
|
150
|
+
|
|
151
|
+
drop table wn;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
-- 21.1.1-where-null-comparisons-secondary-index.sqllogic
|
|
2
|
+
--
|
|
3
|
+
-- requires-capability: standalone-index-ddl
|
|
4
|
+
--
|
|
5
|
+
-- Carved out of 21.1-where-null-comparisons: that file's three-valued-logic
|
|
6
|
+
-- coverage, including "a NULL bound must not become a seek bound", is already
|
|
7
|
+
-- made against the PRIMARY KEY column with no index DDL. This section repeats the
|
|
8
|
+
-- same assertions one level down, on a column reachable only through a standalone
|
|
9
|
+
-- secondary index, so it moves here instead of costing a backend without
|
|
10
|
+
-- first-class CREATE INDEX the whole NULL-comparison file.
|
|
11
|
+
--
|
|
12
|
+
-- Subject: a NULL comparison against a SECONDARY-INDEXED column must not be pushed
|
|
13
|
+
-- down as a seek bound either (key ordering sorts NULL below everything, so a
|
|
14
|
+
-- pushed `> NULL` lower bound would wrongly match every row).
|
|
15
|
+
|
|
16
|
+
create table wn (id integer primary key, val integer null, txt text null);
|
|
17
|
+
insert into wn values (1, 10, 'a'), (2, null, 'b'), (3, 30, null), (4, null, null);
|
|
18
|
+
|
|
19
|
+
create index wn_val on wn (val);
|
|
20
|
+
|
|
21
|
+
select id from wn where val > null order by id;
|
|
22
|
+
→ []
|
|
23
|
+
|
|
24
|
+
select id from wn where null < val order by id;
|
|
25
|
+
→ []
|
|
26
|
+
|
|
27
|
+
select id from wn where val between null and 30 order by id;
|
|
28
|
+
→ []
|
|
29
|
+
|
|
30
|
+
-- Sanity: non-NULL bounds on the same column still seek correctly
|
|
31
|
+
select id from wn where val between 10 and 30 order by id;
|
|
32
|
+
→ [{"id":1},{"id":3}]
|
|
33
|
+
|
|
34
|
+
drop index wn_val;
|
|
35
|
+
drop table wn;
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
-- between-edges.sqllogic - BETWEEN edge cases beyond the basic operator
|
|
2
|
+
-- Distilled from SQLite test/between.test
|
|
3
|
+
|
|
4
|
+
create table bt (id integer primary key, val integer null, lo integer null, hi integer null);
|
|
5
|
+
insert into bt values
|
|
6
|
+
(1, 5, 1, 10),
|
|
7
|
+
(2, 15, 5, 12),
|
|
8
|
+
(3, 8, null, 10),
|
|
9
|
+
(4, 8, 5, null),
|
|
10
|
+
(5, null, 1, 10),
|
|
11
|
+
(6, 25, 30, 20);
|
|
12
|
+
|
|
13
|
+
-- =============================================================================
|
|
14
|
+
-- Basic NULL propagation in BETWEEN operands (in WHERE: filters out)
|
|
15
|
+
-- =============================================================================
|
|
16
|
+
|
|
17
|
+
-- value is NULL -> unknown -> no row
|
|
18
|
+
select id from bt where val between 1 and 100 order by id;
|
|
19
|
+
→ [{"id":1},{"id":2},{"id":3},{"id":4},{"id":6}]
|
|
20
|
+
|
|
21
|
+
-- lower bound is NULL: row 3 (val=8, lo=null, hi=10): 8 BETWEEN null AND 10 -> unknown
|
|
22
|
+
-- row 2 (val=15, lo=5, hi=12): 15 between 5 and 12 -> false
|
|
23
|
+
-- row 6 (val=25, lo=30, hi=20): reversed bounds -> false
|
|
24
|
+
select id from bt where val between lo and hi order by id;
|
|
25
|
+
→ [{"id":1}]
|
|
26
|
+
|
|
27
|
+
-- upper bound is NULL alone, value satisfies low side:
|
|
28
|
+
-- 8 BETWEEN 5 AND null -> unknown -> excluded
|
|
29
|
+
select id from bt where id = 4 and val between lo and hi;
|
|
30
|
+
→ []
|
|
31
|
+
|
|
32
|
+
-- =============================================================================
|
|
33
|
+
-- BETWEEN as a SELECT expression: NULL in any operand returns NULL
|
|
34
|
+
-- =============================================================================
|
|
35
|
+
|
|
36
|
+
select null between 1 and 10 as r;
|
|
37
|
+
→ [{"r":null}]
|
|
38
|
+
|
|
39
|
+
select 5 between null and 10 as r;
|
|
40
|
+
→ [{"r":null}]
|
|
41
|
+
|
|
42
|
+
select 5 between 1 and null as r;
|
|
43
|
+
→ [{"r":null}]
|
|
44
|
+
|
|
45
|
+
select 50 between 1 and null as r;
|
|
46
|
+
→ [{"r":null}]
|
|
47
|
+
|
|
48
|
+
select null between null and null as r;
|
|
49
|
+
→ [{"r":null}]
|
|
50
|
+
|
|
51
|
+
-- =============================================================================
|
|
52
|
+
-- Reversed bounds (lower > upper): always false, never matches
|
|
53
|
+
-- =============================================================================
|
|
54
|
+
|
|
55
|
+
select id from bt where val between 10 and 5;
|
|
56
|
+
→ []
|
|
57
|
+
|
|
58
|
+
select 5 between 10 and 1 as r;
|
|
59
|
+
→ [{"r":false}]
|
|
60
|
+
|
|
61
|
+
-- NOT BETWEEN with reversed bounds: rows with non-null val all qualify (NOT false = true);
|
|
62
|
+
-- rows with null val stay unknown
|
|
63
|
+
select id from bt where val not between 10 and 5 order by id;
|
|
64
|
+
→ [{"id":1},{"id":2},{"id":3},{"id":4},{"id":6}]
|
|
65
|
+
|
|
66
|
+
-- BETWEEN against column-stored reversed bounds (id=6 has lo=30, hi=20)
|
|
67
|
+
select id from bt where id = 6 and val between lo and hi;
|
|
68
|
+
→ []
|
|
69
|
+
|
|
70
|
+
-- =============================================================================
|
|
71
|
+
-- NOT BETWEEN preserves unknown for NULL operands
|
|
72
|
+
-- =============================================================================
|
|
73
|
+
|
|
74
|
+
-- Row 5 has val=null: NOT (null between 1 and 10) -> NOT unknown -> unknown -> excluded
|
|
75
|
+
select id from bt where val not between 1 and 10 order by id;
|
|
76
|
+
→ [{"id":2},{"id":6}]
|
|
77
|
+
|
|
78
|
+
select null not between 1 and 10 as r;
|
|
79
|
+
→ [{"r":null}]
|
|
80
|
+
|
|
81
|
+
-- =============================================================================
|
|
82
|
+
-- Expression bounds (arithmetic in lower / upper / both)
|
|
83
|
+
-- =============================================================================
|
|
84
|
+
|
|
85
|
+
create table bx (id integer primary key, x integer, a integer, b integer);
|
|
86
|
+
insert into bx values (1, 5, 2, 10), (2, 15, 8, 12), (3, 22, 3, 30);
|
|
87
|
+
|
|
88
|
+
select id from bx where x between a + 1 and 100 order by id;
|
|
89
|
+
→ [{"id":1},{"id":2},{"id":3}]
|
|
90
|
+
|
|
91
|
+
select id from bx where x between 0 and b * 2 order by id;
|
|
92
|
+
→ [{"id":1},{"id":2},{"id":3}]
|
|
93
|
+
|
|
94
|
+
select id from bx where x between a + 3 and b * 2 order by id;
|
|
95
|
+
→ [{"id":1},{"id":2},{"id":3}]
|
|
96
|
+
|
|
97
|
+
-- LHS is also an expression
|
|
98
|
+
select id from bx where (x - 5) between a and b order by id;
|
|
99
|
+
→ [{"id":2},{"id":3}]
|
|
100
|
+
|
|
101
|
+
drop table bx;
|
|
102
|
+
|
|
103
|
+
-- =============================================================================
|
|
104
|
+
-- BETWEEN with TEXT operands and lexicographic ordering
|
|
105
|
+
-- =============================================================================
|
|
106
|
+
|
|
107
|
+
create table bs (id integer primary key, s text null);
|
|
108
|
+
insert into bs values (1, 'apple'), (2, 'mango'), (3, 'zebra'), (4, null);
|
|
109
|
+
|
|
110
|
+
select id from bs where s between 'banana' and 'orange' order by id;
|
|
111
|
+
→ [{"id":2}]
|
|
112
|
+
|
|
113
|
+
select id from bs where s not between 'banana' and 'orange' order by id;
|
|
114
|
+
→ [{"id":1},{"id":3}]
|
|
115
|
+
|
|
116
|
+
-- Reversed lexicographic bounds: empty
|
|
117
|
+
select id from bs where s between 'z' and 'a' order by id;
|
|
118
|
+
→ []
|
|
119
|
+
|
|
120
|
+
drop table bs;
|
|
121
|
+
|
|
122
|
+
-- =============================================================================
|
|
123
|
+
-- BETWEEN inside HAVING and CASE
|
|
124
|
+
-- =============================================================================
|
|
125
|
+
|
|
126
|
+
create table bg (id integer primary key, grp text, n integer);
|
|
127
|
+
insert into bg values (1, 'a', 2), (2, 'a', 4), (3, 'b', 7), (4, 'b', 9), (5, 'c', 1);
|
|
128
|
+
|
|
129
|
+
select grp, sum(n) as s from bg group by grp having sum(n) between 5 and 10 order by grp;
|
|
130
|
+
→ [{"grp":"a","s":6}]
|
|
131
|
+
|
|
132
|
+
select id, case when n between 3 and 8 then 'mid' else 'edge' end as bucket from bg order by id;
|
|
133
|
+
→ [{"id":1,"bucket":"edge"},{"id":2,"bucket":"mid"},{"id":3,"bucket":"mid"},{"id":4,"bucket":"edge"},{"id":5,"bucket":"edge"}]
|
|
134
|
+
|
|
135
|
+
drop table bg;
|
|
136
|
+
|
|
137
|
+
-- =============================================================================
|
|
138
|
+
-- BETWEEN in JOIN ON clause (range join)
|
|
139
|
+
-- =============================================================================
|
|
140
|
+
|
|
141
|
+
create table bj_l (id integer primary key, x integer);
|
|
142
|
+
create table bj_r (id integer primary key, lo integer, hi integer, tag text);
|
|
143
|
+
insert into bj_l values (1, 5), (2, 15), (3, 25);
|
|
144
|
+
insert into bj_r values (10, 1, 10, 'low'), (20, 11, 20, 'mid'), (30, 21, 30, 'high');
|
|
145
|
+
|
|
146
|
+
select bj_l.id as lid, bj_r.tag from bj_l join bj_r on bj_l.x between bj_r.lo and bj_r.hi order by lid;
|
|
147
|
+
→ [{"lid":1,"tag":"low"},{"lid":2,"tag":"mid"},{"lid":3,"tag":"high"}]
|
|
148
|
+
|
|
149
|
+
-- LEFT JOIN with BETWEEN ON clause: unmatched left rows preserved
|
|
150
|
+
insert into bj_l values (4, 100);
|
|
151
|
+
select bj_l.id as lid, bj_r.tag from bj_l left join bj_r on bj_l.x between bj_r.lo and bj_r.hi order by lid;
|
|
152
|
+
→ [{"lid":1,"tag":"low"},{"lid":2,"tag":"mid"},{"lid":3,"tag":"high"},{"lid":4,"tag":null}]
|
|
153
|
+
|
|
154
|
+
drop table bj_l;
|
|
155
|
+
drop table bj_r;
|
|
156
|
+
|
|
157
|
+
drop table bt;
|