@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,74 @@
|
|
|
1
|
+
-- 11.3-mismatched-collation-join.sqllogic - joins over differently-collated key columns
|
|
2
|
+
--
|
|
3
|
+
-- The planner hash-joins these shapes (ticket join-collation-gate-blocks-hash-join):
|
|
4
|
+
-- a NOCASE-declared column joined to a defaulted-BINARY column resolves to a NOCASE
|
|
5
|
+
-- comparison through the symmetric provenance lattice, so case-variant matches MUST
|
|
6
|
+
-- be returned — identical to what the nested-loop `=` evaluation produced before the
|
|
7
|
+
-- planner change. Merge join is never eligible for these pairs.
|
|
8
|
+
|
|
9
|
+
-- ===== Collation on the parent (PK) side =====
|
|
10
|
+
|
|
11
|
+
create table parent (k text collate nocase primary key, v integer);
|
|
12
|
+
create table child (id integer primary key, fk text);
|
|
13
|
+
insert into parent values ('Bob', 1), ('X', 2);
|
|
14
|
+
insert into child values (1, 'bob'), (2, 'BOB'), (3, 'x'), (4, 'zz');
|
|
15
|
+
|
|
16
|
+
-- INNER: case-variant FK values match the NOCASE parent key
|
|
17
|
+
select c.id as id, p.v as v from child c join parent p on c.fk = p.k order by c.id;
|
|
18
|
+
→ [{"id":1,"v":1},{"id":2,"v":1},{"id":3,"v":2}]
|
|
19
|
+
|
|
20
|
+
-- INNER with operands flipped in the ON clause (resolution is symmetric)
|
|
21
|
+
select c.id as id, p.v as v from child c join parent p on p.k = c.fk order by c.id;
|
|
22
|
+
→ [{"id":1,"v":1},{"id":2,"v":1},{"id":3,"v":2}]
|
|
23
|
+
|
|
24
|
+
-- LEFT: the unmatched child row null-pads
|
|
25
|
+
select c.id as id, p.v as v from child c left join parent p on c.fk = p.k order by c.id;
|
|
26
|
+
→ [{"id":1,"v":1},{"id":2,"v":1},{"id":3,"v":2},{"id":4,"v":null}]
|
|
27
|
+
|
|
28
|
+
-- SEMI via IN: condition contributes nothing (defaulted BINARY), subquery column
|
|
29
|
+
-- contributes declared NOCASE — resolved NOCASE
|
|
30
|
+
select id from child where fk in (select k from parent) order by id;
|
|
31
|
+
→ [{"id":1},{"id":2},{"id":3}]
|
|
32
|
+
|
|
33
|
+
-- SEMI via correlated EXISTS
|
|
34
|
+
select id from child c where exists (select 1 from parent p where p.k = c.fk) order by id;
|
|
35
|
+
→ [{"id":1},{"id":2},{"id":3}]
|
|
36
|
+
|
|
37
|
+
-- ANTI via NOT EXISTS
|
|
38
|
+
select id from child c where not exists (select 1 from parent p where p.k = c.fk);
|
|
39
|
+
→ [{"id":4}]
|
|
40
|
+
|
|
41
|
+
-- ===== Collation on the child (FK) side; fan-out on the BINARY parent column =====
|
|
42
|
+
|
|
43
|
+
-- A NOCASE probe value matches BOTH binary-distinct parent values 'Bob' and 'bob':
|
|
44
|
+
-- the join must not claim at-most-one match per child row. (`k` is deliberately
|
|
45
|
+
-- NOT the primary key: on the persistent store an undecorated text PK defaults
|
|
46
|
+
-- to the table key collation NOCASE, which would collapse the case-variant rows.)
|
|
47
|
+
create table parent2 (id integer primary key, k text, v integer);
|
|
48
|
+
create table child2 (id integer primary key, fk text collate nocase);
|
|
49
|
+
insert into parent2 values (1, 'Bob', 1), (2, 'bob', 2), (3, 'X', 3), (4, 'zz', 4);
|
|
50
|
+
insert into child2 values (1, 'BOB'), (2, 'x');
|
|
51
|
+
|
|
52
|
+
select c.id as id, p.v as v from child2 c join parent2 p on c.fk = p.k order by c.id, p.v;
|
|
53
|
+
→ [{"id":1,"v":1},{"id":1,"v":2},{"id":2,"v":3}]
|
|
54
|
+
|
|
55
|
+
-- DISTINCT over the fanned-out join must not be elided by a false key claim
|
|
56
|
+
select distinct c.id as id from child2 c join parent2 p on c.fk = p.k order by c.id;
|
|
57
|
+
→ [{"id":1},{"id":2}]
|
|
58
|
+
|
|
59
|
+
-- SEMI: each child row emits once despite the double match
|
|
60
|
+
select id from child2 c where exists (select 1 from parent2 p where p.k = c.fk) order by id;
|
|
61
|
+
→ [{"id":1},{"id":2}]
|
|
62
|
+
|
|
63
|
+
-- ===== USING over differently-collated columns =====
|
|
64
|
+
|
|
65
|
+
create table u1 (k text collate nocase, a integer);
|
|
66
|
+
create table u2 (k text, b integer);
|
|
67
|
+
insert into u1 values ('Bob', 1), ('zz', 2);
|
|
68
|
+
insert into u2 values ('bob', 10), ('BOB', 20), ('yy', 30);
|
|
69
|
+
|
|
70
|
+
select a, b from u1 join u2 using (k) order by a, b;
|
|
71
|
+
→ [{"a":1,"b":10},{"a":1,"b":20}]
|
|
72
|
+
|
|
73
|
+
select a, b from u1 left join u2 using (k) order by a, b;
|
|
74
|
+
→ [{"a":1,"b":10},{"a":1,"b":20},{"a":2,"b":null}]
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
-- 11.4-hash-join-side-swap.sqllogic
|
|
2
|
+
-- Row-equality coverage for the hash join's build/probe side swap
|
|
3
|
+
-- (rule-join-physical-selection). When the logical LEFT input is the smaller of
|
|
4
|
+
-- the two, an INNER hash join swaps the sides so the smaller one is the hash
|
|
5
|
+
-- build side. The emitted row is then probe-then-build — the reverse of the
|
|
6
|
+
-- logical left-then-right order — and the node's advertised attributes must be
|
|
7
|
+
-- permuted to match. When they were not, any consumer mapping an attribute id
|
|
8
|
+
-- to a column index through the join's attributes and then indexing the row
|
|
9
|
+
-- positionally (the grouped-aggregate emitter is one) read the wrong slot and
|
|
10
|
+
-- silently returned wrong values.
|
|
11
|
+
--
|
|
12
|
+
-- Every assertion here is pure row equality, so it holds whichever physical
|
|
13
|
+
-- join the optimizer picks. The plan-shape assertions (that these shapes DO
|
|
14
|
+
-- swap, and what the swapped node must advertise) live in
|
|
15
|
+
-- test/optimizer/hash-join-side-swap.spec.ts.
|
|
16
|
+
--
|
|
17
|
+
-- NOTE: the 4 x 8 fixture sits near the hash/nested-loop cost crossover
|
|
18
|
+
-- (nl = 7.2 vs hash = 6.4 under today's constants in planner/cost/index.ts).
|
|
19
|
+
-- Because every assertion below is row equality, this file keeps passing if a
|
|
20
|
+
-- cost change stops the swap from firing — it would just stop testing anything.
|
|
21
|
+
-- The spec's "swap fired" assertion is the canary; if it goes red after a cost
|
|
22
|
+
-- change, widen the row counts HERE too rather than only there.
|
|
23
|
+
|
|
24
|
+
-- 4 x 8 with ANALYZE: hash beats nested loop and the left side is the smaller
|
|
25
|
+
-- one, so the swap fires. Without ANALYZE both sides report the un-analyzed
|
|
26
|
+
-- 100-row sentinel, `leftRows < rightRows` is false, and the swap never happens.
|
|
27
|
+
CREATE TABLE hjs_s (id INTEGER PRIMARY KEY, k INTEGER);
|
|
28
|
+
CREATE TABLE hjs_b (id INTEGER PRIMARY KEY, k INTEGER, v INTEGER);
|
|
29
|
+
INSERT INTO hjs_s VALUES (1,2),(2,1),(3,2),(4,1);
|
|
30
|
+
INSERT INTO hjs_b VALUES (1,2,1),(2,1,2),(3,2,3),(4,1,4),(5,2,5),(6,1,6),(7,2,7),(8,1,8);
|
|
31
|
+
|
|
32
|
+
-- Each ANALYZE is written as its OWN block with an expected result, not as a
|
|
33
|
+
-- bare setup statement. That expected result is the assertion that the
|
|
34
|
+
-- statistics this whole file depends on actually landed: no row counts, no
|
|
35
|
+
-- side swap, and every case below would pass vacuously.
|
|
36
|
+
ANALYZE hjs_s;
|
|
37
|
+
→ [{"table":"hjs_s","rows":4}]
|
|
38
|
+
|
|
39
|
+
ANALYZE hjs_b;
|
|
40
|
+
→ [{"table":"hjs_b","rows":8}]
|
|
41
|
+
|
|
42
|
+
-- ===== The failing shape: a grouped aggregate above the swapped join =====
|
|
43
|
+
-- k=1: s ids {2,4} x b v {2,4,6,8} -> 2 * 20 = 40
|
|
44
|
+
-- k=2: s ids {1,3} x b v {1,3,5,7} -> 2 * 16 = 32
|
|
45
|
+
SELECT s.k AS gk, sum(b.v) AS sv FROM hjs_s s JOIN hjs_b b ON b.k = s.k GROUP BY s.k ORDER BY s.k;
|
|
46
|
+
→ [{"gk":1,"sv":40},{"gk":2,"sv":32}]
|
|
47
|
+
|
|
48
|
+
-- The aggregate reading the PROBE side's column instead (both sides of the
|
|
49
|
+
-- emitted row must be addressed correctly, not just the build side)
|
|
50
|
+
-- k=1: (2+4) * 4 matching b rows = 24; k=2: (1+3) * 4 = 16
|
|
51
|
+
SELECT s.k AS gk, sum(s.id) AS si FROM hjs_s s JOIN hjs_b b ON b.k = s.k GROUP BY s.k ORDER BY s.k;
|
|
52
|
+
→ [{"gk":1,"si":24},{"gk":2,"si":16}]
|
|
53
|
+
|
|
54
|
+
-- Grouping on the build-side column, aggregating the probe side
|
|
55
|
+
SELECT b.k AS gk, sum(s.id) AS si FROM hjs_s s JOIN hjs_b b ON b.k = s.k GROUP BY b.k ORDER BY b.k;
|
|
56
|
+
→ [{"gk":1,"si":24},{"gk":2,"si":16}]
|
|
57
|
+
|
|
58
|
+
-- Both sides aggregated in one grouped query
|
|
59
|
+
SELECT s.k AS gk, sum(b.v) AS sv, sum(s.id) AS si FROM hjs_s s JOIN hjs_b b ON b.k = s.k GROUP BY s.k ORDER BY s.k;
|
|
60
|
+
→ [{"gk":1,"sv":40,"si":24},{"gk":2,"sv":32,"si":16}]
|
|
61
|
+
|
|
62
|
+
-- ===== Other aggregate kinds over the same swapped join =====
|
|
63
|
+
SELECT s.k AS gk, count(*) AS n, min(b.v) AS mn, max(b.v) AS mx
|
|
64
|
+
FROM hjs_s s JOIN hjs_b b ON b.k = s.k GROUP BY s.k ORDER BY s.k;
|
|
65
|
+
→ [{"gk":1,"n":8,"mn":2,"mx":8},{"gk":2,"n":8,"mn":1,"mx":7}]
|
|
66
|
+
|
|
67
|
+
-- Ungrouped aggregate over the whole swapped join
|
|
68
|
+
SELECT count(*) AS n, sum(b.v) AS sv, sum(s.id) AS si FROM hjs_s s JOIN hjs_b b ON b.k = s.k;
|
|
69
|
+
→ [{"n":16,"sv":72,"si":40}]
|
|
70
|
+
|
|
71
|
+
-- ===== The plain projection over the same join =====
|
|
72
|
+
-- Passes even with the bug (column references above the join resolve through
|
|
73
|
+
-- the join emitter's own per-side slots, each built from its own child's
|
|
74
|
+
-- attributes). Kept so a future regression says WHICH consumer style broke.
|
|
75
|
+
SELECT s.id AS sid, b.id AS bid, b.v AS bv FROM hjs_s s JOIN hjs_b b ON b.k = s.k ORDER BY sid, bid;
|
|
76
|
+
→ [{"sid":1,"bid":1,"bv":1},{"sid":1,"bid":3,"bv":3},{"sid":1,"bid":5,"bv":5},{"sid":1,"bid":7,"bv":7},{"sid":2,"bid":2,"bv":2},{"sid":2,"bid":4,"bv":4},{"sid":2,"bid":6,"bv":6},{"sid":2,"bid":8,"bv":8},{"sid":3,"bid":1,"bv":1},{"sid":3,"bid":3,"bv":3},{"sid":3,"bid":5,"bv":5},{"sid":3,"bid":7,"bv":7},{"sid":4,"bid":2,"bv":2},{"sid":4,"bid":4,"bv":4},{"sid":4,"bid":6,"bv":6},{"sid":4,"bid":8,"bv":8}]
|
|
77
|
+
|
|
78
|
+
-- ===== Sort and DISTINCT key extraction above the swapped join =====
|
|
79
|
+
-- Both resolve attribute ids to column indices through the join's advertised
|
|
80
|
+
-- attributes, so they read the emitted row positionally too.
|
|
81
|
+
SELECT b.v AS bv FROM hjs_s s JOIN hjs_b b ON b.k = s.k ORDER BY bv DESC LIMIT 3;
|
|
82
|
+
→ [{"bv":8},{"bv":8},{"bv":7}]
|
|
83
|
+
|
|
84
|
+
SELECT DISTINCT s.k AS sk, b.k AS bk FROM hjs_s s JOIN hjs_b b ON b.k = s.k ORDER BY sk;
|
|
85
|
+
→ [{"sk":1,"bk":1},{"sk":2,"bk":2}]
|
|
86
|
+
|
|
87
|
+
SELECT DISTINCT b.v AS bv FROM hjs_s s JOIN hjs_b b ON b.k = s.k ORDER BY bv;
|
|
88
|
+
→ [{"bv":1},{"bv":2},{"bv":3},{"bv":4},{"bv":5},{"bv":6},{"bv":7},{"bv":8}]
|
|
89
|
+
|
|
90
|
+
-- ===== Three-table join with the aggregate on top =====
|
|
91
|
+
CREATE TABLE hjs_t (id INTEGER PRIMARY KEY, k INTEGER, w INTEGER);
|
|
92
|
+
INSERT INTO hjs_t VALUES (1,1,100),(2,2,200);
|
|
93
|
+
ANALYZE hjs_t;
|
|
94
|
+
→ [{"table":"hjs_t","rows":2}]
|
|
95
|
+
|
|
96
|
+
-- Each group is s x b x t = 2 x 4 x 1 = 8 rows.
|
|
97
|
+
-- k=1: sum(b.v) = 2*(2+4+6+8) = 40, sum(t.w) = 8*100 = 800
|
|
98
|
+
-- k=2: sum(b.v) = 2*(1+3+5+7) = 32, sum(t.w) = 8*200 = 1600
|
|
99
|
+
SELECT s.k AS gk, count(*) AS n, sum(b.v) AS sv, sum(t.w) AS tw
|
|
100
|
+
FROM hjs_s s JOIN hjs_b b ON b.k = s.k JOIN hjs_t t ON t.k = s.k
|
|
101
|
+
GROUP BY s.k ORDER BY s.k;
|
|
102
|
+
→ [{"gk":1,"n":8,"sv":40,"tw":800},{"gk":2,"n":8,"sv":32,"tw":1600}]
|
|
103
|
+
|
|
104
|
+
-- Same spine, plain projection (no aggregate) — one row per (s,b) pair since
|
|
105
|
+
-- each key has exactly one t row
|
|
106
|
+
SELECT s.id AS sid, b.id AS bid, t.w AS tw
|
|
107
|
+
FROM hjs_s s JOIN hjs_b b ON b.k = s.k JOIN hjs_t t ON t.k = s.k
|
|
108
|
+
ORDER BY sid, bid;
|
|
109
|
+
→ [{"sid":1,"bid":1,"tw":200},{"sid":1,"bid":3,"tw":200},{"sid":1,"bid":5,"tw":200},{"sid":1,"bid":7,"tw":200},{"sid":2,"bid":2,"tw":100},{"sid":2,"bid":4,"tw":100},{"sid":2,"bid":6,"tw":100},{"sid":2,"bid":8,"tw":100},{"sid":3,"bid":1,"tw":200},{"sid":3,"bid":3,"tw":200},{"sid":3,"bid":5,"tw":200},{"sid":3,"bid":7,"tw":200},{"sid":4,"bid":2,"tw":100},{"sid":4,"bid":4,"tw":100},{"sid":4,"bid":6,"tw":100},{"sid":4,"bid":8,"tw":100}]
|
|
110
|
+
|
|
111
|
+
-- ===== HAVING and an aggregate expression above the swapped join =====
|
|
112
|
+
SELECT s.k AS gk, sum(b.v) AS sv FROM hjs_s s JOIN hjs_b b ON b.k = s.k
|
|
113
|
+
GROUP BY s.k HAVING sum(b.v) > 35 ORDER BY s.k;
|
|
114
|
+
→ [{"gk":1,"sv":40}]
|
|
115
|
+
|
|
116
|
+
SELECT s.k AS gk, sum(b.v) + count(*) AS mixed FROM hjs_s s JOIN hjs_b b ON b.k = s.k
|
|
117
|
+
GROUP BY s.k ORDER BY s.k;
|
|
118
|
+
→ [{"gk":1,"mixed":48},{"gk":2,"mixed":40}]
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
-- scan-emitter-mutation-kills.sqllogic — Mutation-killing tests for runtime/emit/scan.ts
|
|
2
|
+
-- Exercises SeqScan and IndexSeek paths through the memory vtab
|
|
3
|
+
-- (the IndexScan paths live in 110.1-scan-emitter-index-scan-kills — they need standalone index DDL)
|
|
4
|
+
|
|
5
|
+
-- =============================================================================
|
|
6
|
+
-- SeqScan — empty table, single row, multi-row
|
|
7
|
+
-- =============================================================================
|
|
8
|
+
|
|
9
|
+
create table scan_empty (id integer primary key, val text);
|
|
10
|
+
|
|
11
|
+
-- Empty table scan returns no rows
|
|
12
|
+
select * from scan_empty;
|
|
13
|
+
→ []
|
|
14
|
+
|
|
15
|
+
-- Single-row insertion + scan
|
|
16
|
+
insert into scan_empty values (1, 'only');
|
|
17
|
+
select id, val from scan_empty;
|
|
18
|
+
→ [{"id":1,"val":"only"}]
|
|
19
|
+
|
|
20
|
+
drop table scan_empty;
|
|
21
|
+
|
|
22
|
+
-- Multi-row sequential scan (verifies iteration loop)
|
|
23
|
+
create table scan_multi (id integer primary key, name text);
|
|
24
|
+
insert into scan_multi values (1, 'alice'), (2, 'bob'), (3, 'charlie');
|
|
25
|
+
|
|
26
|
+
select id, name from scan_multi order by id;
|
|
27
|
+
→ [{"id":1,"name":"alice"},{"id":2,"name":"bob"},{"id":3,"name":"charlie"}]
|
|
28
|
+
|
|
29
|
+
-- Larger scan — verify iteration handles multiple rows correctly
|
|
30
|
+
create table scan_many (id integer primary key, v integer);
|
|
31
|
+
insert into scan_many values (1, 10), (2, 20), (3, 30), (4, 40), (5, 50), (6, 60), (7, 70), (8, 80), (9, 90), (10, 100);
|
|
32
|
+
|
|
33
|
+
-- Verify count
|
|
34
|
+
select count(*) as c from scan_many;
|
|
35
|
+
→ [{"c":10}]
|
|
36
|
+
|
|
37
|
+
-- Verify sum to catch off-by-one in iteration
|
|
38
|
+
select sum(id) as s from scan_many;
|
|
39
|
+
→ [{"s":55}]
|
|
40
|
+
|
|
41
|
+
-- Verify first and last
|
|
42
|
+
select id, v from scan_many where id = 1;
|
|
43
|
+
→ [{"id":1,"v":10}]
|
|
44
|
+
|
|
45
|
+
select id, v from scan_many where id = 10;
|
|
46
|
+
→ [{"id":10,"v":100}]
|
|
47
|
+
|
|
48
|
+
drop table scan_many;
|
|
49
|
+
|
|
50
|
+
-- The IndexScan sections (ordered access and range access over a secondary index)
|
|
51
|
+
-- live in 110.1-scan-emitter-index-scan-kills; they need standalone CREATE INDEX.
|
|
52
|
+
|
|
53
|
+
-- =============================================================================
|
|
54
|
+
-- IndexSeek — point lookup with literal key
|
|
55
|
+
-- =============================================================================
|
|
56
|
+
|
|
57
|
+
create table seek_pk (id integer primary key, data text);
|
|
58
|
+
insert into seek_pk values (10, 'ten'), (20, 'twenty'), (30, 'thirty');
|
|
59
|
+
|
|
60
|
+
-- Primary key seek with literal
|
|
61
|
+
select data from seek_pk where id = 20;
|
|
62
|
+
→ [{"data":"twenty"}]
|
|
63
|
+
|
|
64
|
+
-- Seek miss returns empty
|
|
65
|
+
select data from seek_pk where id = 99;
|
|
66
|
+
→ []
|
|
67
|
+
|
|
68
|
+
drop table seek_pk;
|
|
69
|
+
|
|
70
|
+
-- =============================================================================
|
|
71
|
+
-- IndexSeek — composite key
|
|
72
|
+
-- =============================================================================
|
|
73
|
+
|
|
74
|
+
create table seek_comp (a integer, b integer, val text, primary key (a, b));
|
|
75
|
+
insert into seek_comp values (1, 1, 'one-one'), (1, 2, 'one-two'), (2, 1, 'two-one');
|
|
76
|
+
|
|
77
|
+
-- Composite key seek
|
|
78
|
+
select val from seek_comp where a = 1 and b = 2;
|
|
79
|
+
→ [{"val":"one-two"}]
|
|
80
|
+
|
|
81
|
+
-- Partial composite key (range scan on first part)
|
|
82
|
+
select val from seek_comp where a = 1 order by b;
|
|
83
|
+
→ [{"val":"one-one"},{"val":"one-two"}]
|
|
84
|
+
|
|
85
|
+
drop table seek_comp;
|
|
86
|
+
|
|
87
|
+
-- =============================================================================
|
|
88
|
+
-- IndexSeek — NULL seek key
|
|
89
|
+
-- =============================================================================
|
|
90
|
+
|
|
91
|
+
create table seek_null (id integer primary key, val text null);
|
|
92
|
+
insert into seek_null values (1, 'a'), (2, null), (3, 'c');
|
|
93
|
+
|
|
94
|
+
-- Seek with NULL — should not match anything (NULL ≠ NULL)
|
|
95
|
+
select id from seek_null where val = null;
|
|
96
|
+
→ []
|
|
97
|
+
|
|
98
|
+
-- IS NULL check
|
|
99
|
+
select id from seek_null where val is null;
|
|
100
|
+
→ [{"id":2}]
|
|
101
|
+
|
|
102
|
+
drop table seek_null;
|
|
103
|
+
|
|
104
|
+
-- =============================================================================
|
|
105
|
+
-- SeqScan — verify columns are mapped correctly (row descriptor)
|
|
106
|
+
-- =============================================================================
|
|
107
|
+
|
|
108
|
+
create table scan_cols (a integer primary key, b text, c real, d integer);
|
|
109
|
+
insert into scan_cols values (1, 'hello', 3.14, 42);
|
|
110
|
+
|
|
111
|
+
-- Access columns in different orders
|
|
112
|
+
select c, a from scan_cols;
|
|
113
|
+
→ [{"c":3.14,"a":1}]
|
|
114
|
+
|
|
115
|
+
select d, b, a from scan_cols;
|
|
116
|
+
→ [{"d":42,"b":"hello","a":1}]
|
|
117
|
+
|
|
118
|
+
drop table scan_cols;
|
|
119
|
+
|
|
120
|
+
-- Clean up the multi-row table
|
|
121
|
+
drop table scan_multi;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
-- 110.1-scan-emitter-index-scan-kills.sqllogic — Mutation-killing tests for the IndexScan path in runtime/emit/scan.ts
|
|
2
|
+
--
|
|
3
|
+
-- requires-capability: standalone-index-ddl
|
|
4
|
+
--
|
|
5
|
+
-- Carved out of 110-scan-emitter-mutation-kills: that file's SeqScan and IndexSeek
|
|
6
|
+
-- sections reach their access paths through PRIMARY KEY declarations alone. These
|
|
7
|
+
-- two IndexScan sections use `create index` only to route the plan onto the
|
|
8
|
+
-- secondary-index shape, so they move here and leave the rest of the emitter
|
|
9
|
+
-- coverage runnable on a backend without first-class CREATE INDEX.
|
|
10
|
+
--
|
|
11
|
+
-- Subject: ordered access and range access driven by a secondary index.
|
|
12
|
+
|
|
13
|
+
-- =============================================================================
|
|
14
|
+
-- IndexScan — ordered access via index
|
|
15
|
+
-- =============================================================================
|
|
16
|
+
|
|
17
|
+
create table scan_idx (id integer primary key, score integer);
|
|
18
|
+
create index idx_score on scan_idx(score);
|
|
19
|
+
insert into scan_idx values (1, 30), (2, 10), (3, 20);
|
|
20
|
+
|
|
21
|
+
-- Index scan with ordering by indexed column
|
|
22
|
+
select id, score from scan_idx order by score;
|
|
23
|
+
→ [{"id":2,"score":10},{"id":3,"score":20},{"id":1,"score":30}]
|
|
24
|
+
|
|
25
|
+
-- Descending index scan
|
|
26
|
+
select id, score from scan_idx order by score desc;
|
|
27
|
+
→ [{"id":1,"score":30},{"id":3,"score":20},{"id":2,"score":10}]
|
|
28
|
+
|
|
29
|
+
drop table scan_idx;
|
|
30
|
+
|
|
31
|
+
-- =============================================================================
|
|
32
|
+
-- IndexScan — secondary index with range
|
|
33
|
+
-- =============================================================================
|
|
34
|
+
|
|
35
|
+
create table scan_range (id integer primary key, v integer);
|
|
36
|
+
create index idx_v on scan_range(v);
|
|
37
|
+
insert into scan_range values (1, 100), (2, 200), (3, 300), (4, 400), (5, 500);
|
|
38
|
+
|
|
39
|
+
-- Range scan on indexed column
|
|
40
|
+
select id from scan_range where v >= 200 and v <= 400 order by v;
|
|
41
|
+
→ [{"id":2},{"id":3},{"id":4}]
|
|
42
|
+
|
|
43
|
+
-- Range scan with single bound
|
|
44
|
+
select id from scan_range where v > 300 order by v;
|
|
45
|
+
→ [{"id":4},{"id":5}]
|
|
46
|
+
|
|
47
|
+
drop table scan_range;
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
-- Empty Primary Key Tests (Third Manifesto Feature)
|
|
2
|
+
-- These tests verify support for PRIMARY KEY () which creates singleton tables
|
|
3
|
+
-- that can contain at most 0 or 1 rows
|
|
4
|
+
|
|
5
|
+
-- Test 1: Create table with empty primary key directly in CREATE TABLE
|
|
6
|
+
CREATE TABLE settings (
|
|
7
|
+
app_name TEXT NOT NULL,
|
|
8
|
+
version TEXT,
|
|
9
|
+
debug_mode INTEGER,
|
|
10
|
+
PRIMARY KEY ()
|
|
11
|
+
) USING memory;
|
|
12
|
+
|
|
13
|
+
-- Test 2: Insert first row should succeed
|
|
14
|
+
INSERT INTO settings (app_name, version, debug_mode) VALUES ('MyApp', '1.0.0', 1);
|
|
15
|
+
|
|
16
|
+
SELECT app_name, version, debug_mode FROM settings;
|
|
17
|
+
→ [{"app_name": "MyApp", "version": "1.0.0", "debug_mode": 1}]
|
|
18
|
+
|
|
19
|
+
-- Test 3: Second insert should fail (violates singleton constraint)
|
|
20
|
+
INSERT INTO settings (app_name, version, debug_mode) VALUES ('AnotherApp', '2.0.0', 0);
|
|
21
|
+
-- error: UNIQUE constraint failed: settings PK
|
|
22
|
+
|
|
23
|
+
-- Test 4: Update should work on the single row
|
|
24
|
+
UPDATE settings SET debug_mode = 0 WHERE app_name = 'MyApp';
|
|
25
|
+
|
|
26
|
+
SELECT app_name, version, debug_mode FROM settings;
|
|
27
|
+
→ [{"app_name": "MyApp", "version": "1.0.0", "debug_mode": 0}]
|
|
28
|
+
|
|
29
|
+
-- Test 5: Delete should work
|
|
30
|
+
DELETE FROM settings WHERE app_name = 'MyApp';
|
|
31
|
+
|
|
32
|
+
SELECT app_name, version, debug_mode FROM settings;
|
|
33
|
+
→ []
|
|
34
|
+
|
|
35
|
+
-- Test 6: After delete, should be able to insert again
|
|
36
|
+
INSERT INTO settings (app_name, version, debug_mode) VALUES ('NewApp', '2.0.0', 1);
|
|
37
|
+
|
|
38
|
+
SELECT app_name, version, debug_mode FROM settings;
|
|
39
|
+
→ [{"app_name": "NewApp", "version": "2.0.0", "debug_mode": 1}]
|
|
40
|
+
|
|
41
|
+
-- Test 7: Test with named constraint (using fresh table)
|
|
42
|
+
CREATE TABLE config1 (
|
|
43
|
+
config_key TEXT,
|
|
44
|
+
config_value TEXT,
|
|
45
|
+
CONSTRAINT singleton_config PRIMARY KEY ()
|
|
46
|
+
) USING memory;
|
|
47
|
+
|
|
48
|
+
-- Test 8: Insert into named constraint table
|
|
49
|
+
INSERT INTO config1 (config_key, config_value) VALUES ('theme', 'dark');
|
|
50
|
+
|
|
51
|
+
SELECT config_key, config_value FROM config1;
|
|
52
|
+
→ [{"config_key": "theme", "config_value": "dark"}]
|
|
53
|
+
|
|
54
|
+
-- Test 9: Second insert should fail with named constraint
|
|
55
|
+
INSERT INTO config1 (config_key, config_value) VALUES ('language', 'en');
|
|
56
|
+
-- error: UNIQUE constraint failed: config1 PK
|
|
57
|
+
|
|
58
|
+
-- Test 10: Test COUNT and aggregation functions on singleton tables
|
|
59
|
+
SELECT COUNT(*) FROM config1;
|
|
60
|
+
→ [{"count(*)": 1}]
|
|
61
|
+
|
|
62
|
+
SELECT COUNT(*) FROM settings;
|
|
63
|
+
→ [{"count(*)": 1}]
|
|
64
|
+
|
|
65
|
+
-- Test 11: Test with transactions using fresh table
|
|
66
|
+
CREATE TABLE config2 (
|
|
67
|
+
config_key TEXT,
|
|
68
|
+
config_value TEXT,
|
|
69
|
+
PRIMARY KEY ()
|
|
70
|
+
) USING memory;
|
|
71
|
+
|
|
72
|
+
INSERT INTO config2 (config_key, config_value) VALUES ('app_theme', 'light');
|
|
73
|
+
|
|
74
|
+
BEGIN;
|
|
75
|
+
DELETE FROM config2;
|
|
76
|
+
INSERT INTO config2 (config_key, config_value) VALUES ('temp_config', 'temp_value');
|
|
77
|
+
|
|
78
|
+
SELECT config_key, config_value FROM config2;
|
|
79
|
+
→ [{"config_key": "temp_config", "config_value": "temp_value"}]
|
|
80
|
+
|
|
81
|
+
ROLLBACK;
|
|
82
|
+
|
|
83
|
+
-- Should be back to previous state
|
|
84
|
+
SELECT config_key, config_value FROM config2;
|
|
85
|
+
→ [{"config_key": "app_theme", "config_value": "light"}]
|
|
86
|
+
|
|
87
|
+
-- Test 12: Test with savepoints
|
|
88
|
+
SAVEPOINT sp1;
|
|
89
|
+
UPDATE config2 SET config_value = 'very_dark';
|
|
90
|
+
|
|
91
|
+
SELECT config_key, config_value FROM config2;
|
|
92
|
+
→ [{"config_key": "app_theme", "config_value": "very_dark"}]
|
|
93
|
+
|
|
94
|
+
ROLLBACK TO sp1;
|
|
95
|
+
|
|
96
|
+
SELECT config_key, config_value FROM config2;
|
|
97
|
+
→ [{"config_key": "app_theme", "config_value": "light"}]
|
|
98
|
+
|
|
99
|
+
RELEASE sp1;
|
|
100
|
+
|
|
101
|
+
-- Test 13: Test JOIN with singleton tables
|
|
102
|
+
CREATE TABLE users (
|
|
103
|
+
id INTEGER PRIMARY KEY,
|
|
104
|
+
name TEXT
|
|
105
|
+
) USING memory;
|
|
106
|
+
|
|
107
|
+
INSERT INTO users (id, name) VALUES (1, 'Alice'), (2, 'Bob');
|
|
108
|
+
|
|
109
|
+
-- Cross join with singleton should produce one row per regular table row
|
|
110
|
+
SELECT u.id, u.name, c.config_value
|
|
111
|
+
FROM users u
|
|
112
|
+
CROSS JOIN config2 c
|
|
113
|
+
ORDER BY u.id;
|
|
114
|
+
→ [{"id": 1, "name": "Alice", "config_value": "light"}, {"id": 2, "name": "Bob", "config_value": "light"}]
|
|
115
|
+
|
|
116
|
+
-- Test 14: Test singleton tables work with ORDER BY and LIMIT
|
|
117
|
+
SELECT config_key, config_value FROM config2 ORDER BY config_key LIMIT 5;
|
|
118
|
+
→ [{"config_key": "app_theme", "config_value": "light"}]
|
|
119
|
+
|
|
120
|
+
-- Test 15: Cleanup
|
|
121
|
+
DROP TABLE IF EXISTS settings;
|
|
122
|
+
DROP TABLE IF EXISTS config1;
|
|
123
|
+
DROP TABLE IF EXISTS config2;
|
|
124
|
+
DROP TABLE IF EXISTS users;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
-- Test suite for LEFT JOIN NULL padding and ORDER BY consumption
|
|
2
|
+
|
|
3
|
+
-- Setup Tables
|
|
4
|
+
CREATE TABLE t1 (id INTEGER PRIMARY KEY, val TEXT);
|
|
5
|
+
INSERT INTO t1 VALUES (1, 'A'), (2, 'B'), (3, 'C');
|
|
6
|
+
|
|
7
|
+
CREATE TABLE t2 (id INTEGER PRIMARY KEY, t1_id INTEGER, info TEXT);
|
|
8
|
+
INSERT INTO t2 VALUES (101, 1, 'InfoA1'), (102, 1, 'InfoA2'), (103, 2, 'InfoB');
|
|
9
|
+
-- Note: t1.id = 3 has no match in t2
|
|
10
|
+
|
|
11
|
+
-- ==================================
|
|
12
|
+
-- LEFT JOIN Padding Tests
|
|
13
|
+
-- ==================================
|
|
14
|
+
|
|
15
|
+
-- Test: Direct Output Padding
|
|
16
|
+
-- Expect t2 columns to be NULL for t1.id = 3
|
|
17
|
+
SELECT t1.id, t1.val, t2.id, t2.info FROM t1 LEFT JOIN t2 ON t1.id = t2.t1_id ORDER BY t1.id, t2.id;
|
|
18
|
+
→ [{"id":1,"val":"A","id:1":101,"info":"InfoA1"},{"id":1,"val":"A","id:1":102,"info":"InfoA2"},{"id":2,"val":"B","id:1":103,"info":"InfoB"},{"id":3,"val":"C","id:1":null,"info":null}]
|
|
19
|
+
|
|
20
|
+
-- Test: Aggregate COUNT Padding
|
|
21
|
+
-- COUNT(t2.id) should be 0 for the group corresponding to t1.id = 3
|
|
22
|
+
SELECT t1.id, COUNT(t2.id) as count_t2, COUNT(*) as count_all FROM t1 LEFT JOIN t2 ON t1.id = t2.t1_id GROUP BY t1.id ORDER BY t1.id;
|
|
23
|
+
→ [{"id":1,"count_t2":2,"count_all":2},{"id":2,"count_t2":1,"count_all":1},{"id":3,"count_t2":0,"count_all":1}]
|
|
24
|
+
|
|
25
|
+
-- Test: Aggregate SUM Padding
|
|
26
|
+
-- SUM(t2.id) should be NULL (ignored NULLs) for the group corresponding to t1.id = 3
|
|
27
|
+
SELECT t1.id, SUM(t2.id) as sum_t2 FROM t1 LEFT JOIN t2 ON t1.id = t2.t1_id GROUP BY t1.id ORDER BY t1.id;
|
|
28
|
+
→ [{"id":1,"sum_t2":203},{"id":2,"sum_t2":103},{"id":3,"sum_t2":null}]
|
|
29
|
+
|
|
30
|
+
-- Test: Window Function ROW_NUMBER Padding
|
|
31
|
+
-- Partitioning by t1.id should work correctly, rows with NULL t2.id get numbered
|
|
32
|
+
SELECT t1.id, t2.id as t2_id, ROW_NUMBER() OVER (PARTITION BY t1.id ORDER BY t2.id) as rn
|
|
33
|
+
FROM t1 LEFT JOIN t2 ON t1.id = t2.t1_id
|
|
34
|
+
ORDER BY t1.id, t2.id;
|
|
35
|
+
→ [{"id":1,"t2_id":101,"rn":1},{"id":1,"t2_id":102,"rn":2},{"id":2,"t2_id":103,"rn":1},{"id":3,"t2_id":null,"rn":1}]
|
|
36
|
+
|
|
37
|
+
-- Test: Window Function SUM Padding
|
|
38
|
+
-- SUM(t2.id) OVER (...) should treat NULL t2.id correctly based on frame
|
|
39
|
+
SELECT t1.id, t2.id as t2_id,
|
|
40
|
+
SUM(t2.id) OVER (PARTITION BY t1.id ORDER BY t2.id ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) as running_sum
|
|
41
|
+
FROM t1 LEFT JOIN t2 ON t1.id = t2.t1_id
|
|
42
|
+
ORDER BY t1.id, t2.id;
|
|
43
|
+
→ [{"id":1,"t2_id":101,"running_sum":101},{"id":1,"t2_id":102,"running_sum":203},{"id":2,"t2_id":103,"running_sum":103},{"id":3,"t2_id":null,"running_sum":null}]
|
|
44
|
+
|
|
45
|
+
-- ==================================
|
|
46
|
+
-- ORDER BY Consumption Tests
|
|
47
|
+
-- ==================================
|
|
48
|
+
-- The secondary-index variants (ORDER BY consumed / not consumed on an indexed
|
|
49
|
+
-- column) live in 12.1-orderby-index-consumption; they need standalone CREATE INDEX.
|
|
50
|
+
|
|
51
|
+
-- Test: ORDER BY on JOIN result (Likely Not Consumed)
|
|
52
|
+
-- Order by t1.val, join order might not preserve this. Expect Sort.
|
|
53
|
+
SELECT t1.val, t2.info FROM t1 JOIN t2 ON t1.id = t2.t1_id ORDER BY t1.val DESC, t2.id ASC;
|
|
54
|
+
→ [{"val":"B","info":"InfoB"},{"val":"A","info":"InfoA1"},{"val":"A","info":"InfoA2"}]
|
|
55
|
+
|
|
56
|
+
DROP TABLE t1;
|
|
57
|
+
DROP TABLE t2;
|
|
58
|
+
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
-- 12.1-orderby-index-consumption.sqllogic — ORDER BY consumed (or not) by a secondary index.
|
|
2
|
+
--
|
|
3
|
+
-- requires-capability: standalone-index-ddl
|
|
4
|
+
--
|
|
5
|
+
-- Carved out of 12-join_padding_order: that file's subject is LEFT JOIN NULL
|
|
6
|
+
-- padding through direct output, aggregates and window functions, none of which
|
|
7
|
+
-- needs an index. This section builds an indexed table only so the planner can
|
|
8
|
+
-- elide the Sort node, so it moves here rather than costing a backend without
|
|
9
|
+
-- first-class CREATE INDEX the whole padding suite.
|
|
10
|
+
--
|
|
11
|
+
-- Subject: ORDER BY on the indexed column (ASC and DESC) is satisfied by the index
|
|
12
|
+
-- ordering; ORDER BY on another column or on an expression is not, and must still
|
|
13
|
+
-- return correctly sorted rows through a Sort.
|
|
14
|
+
|
|
15
|
+
-- Setup Indexed Table for ORDER BY consumption test
|
|
16
|
+
CREATE TABLE t_idx (id INTEGER PRIMARY KEY, name TEXT);
|
|
17
|
+
CREATE INDEX t_idx_name ON t_idx (name);
|
|
18
|
+
INSERT INTO t_idx VALUES (1, 'Xavier'), (2, 'Alice'), (3, 'Bob');
|
|
19
|
+
|
|
20
|
+
-- Test: ORDER BY Consumed by Index (ASC)
|
|
21
|
+
-- Expect query plan to use index on t_idx.name, no Sort operation needed
|
|
22
|
+
SELECT name FROM t_idx ORDER BY name ASC;
|
|
23
|
+
→ [{"name":"Alice"},{"name":"Bob"},{"name":"Xavier"}]
|
|
24
|
+
|
|
25
|
+
-- Test: ORDER BY Consumed by Index (DESC)
|
|
26
|
+
-- Expect query plan to use index on t_idx.name (backwards), no Sort operation needed
|
|
27
|
+
SELECT name FROM t_idx ORDER BY name DESC;
|
|
28
|
+
→ [{"name":"Xavier"},{"name":"Bob"},{"name":"Alice"}]
|
|
29
|
+
|
|
30
|
+
-- Test: ORDER BY Not Consumed (Different Column)
|
|
31
|
+
-- Expect query plan to use PK for scan, requires Sort operation
|
|
32
|
+
SELECT name FROM t_idx ORDER BY id DESC;
|
|
33
|
+
→ [{"name":"Bob"},{"name":"Alice"},{"name":"Xavier"}]
|
|
34
|
+
|
|
35
|
+
-- Test: ORDER BY Not Consumed (Expression)
|
|
36
|
+
-- Expect query plan to use PK for scan, requires Sort operation
|
|
37
|
+
SELECT name FROM t_idx ORDER BY lower(name);
|
|
38
|
+
→ [{"name":"Alice"},{"name":"Bob"},{"name":"Xavier"}]
|
|
39
|
+
|
|
40
|
+
DROP TABLE t_idx;
|