@quereus/quereus 4.20.1 → 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/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,698 @@
|
|
|
1
|
+
-- adapted from SQLite test/select1.test, test/orderby1.test, test/orderby5.test,
|
|
2
|
+
-- test/orderby8.test, test/orderby9.test, test/e_select.test
|
|
3
|
+
-- ORDER BY targets that aren't bare column names: positional references,
|
|
4
|
+
-- arithmetic / function expressions, mixed CASE, multi-column COLLATE, and
|
|
5
|
+
-- expression-derived ORDER BY in the absence of GROUP BY.
|
|
6
|
+
|
|
7
|
+
create table ob (id integer primary key, a integer, b integer null, c text);
|
|
8
|
+
insert into ob values
|
|
9
|
+
(1, 10, null, 'p'),
|
|
10
|
+
(2, 20, 5, 'q'),
|
|
11
|
+
(3, 5, 3, 'r'),
|
|
12
|
+
(4, 15, null, 'p'),
|
|
13
|
+
(5, 30, 10, 'q'),
|
|
14
|
+
(6, 1, 7, 's');
|
|
15
|
+
|
|
16
|
+
-- ORDER BY positional reference (1 → first SELECT column)
|
|
17
|
+
select a from ob order by 1;
|
|
18
|
+
→ [{"a":1},{"a":5},{"a":10},{"a":15},{"a":20},{"a":30}]
|
|
19
|
+
|
|
20
|
+
-- ORDER BY positional, multi-column, mixed direction
|
|
21
|
+
select c, a from ob order by 1, 2 desc;
|
|
22
|
+
→ [{"c":"p","a":15},{"c":"p","a":10},{"c":"q","a":30},{"c":"q","a":20},{"c":"r","a":5},{"c":"s","a":1}]
|
|
23
|
+
|
|
24
|
+
-- ORDER BY with DESC on the first key, and an expression alias second
|
|
25
|
+
select a, b * 2 as bx from ob where b is not null order by a desc, bx;
|
|
26
|
+
→ [{"a":30,"bx":20},{"a":20,"bx":10},{"a":5,"bx":6},{"a":1,"bx":14}]
|
|
27
|
+
|
|
28
|
+
-- ORDER BY arithmetic expression on a non-projected column
|
|
29
|
+
select id from ob where b is not null order by abs(b - 6), id;
|
|
30
|
+
→ [{"id":2},{"id":6},{"id":3},{"id":5}]
|
|
31
|
+
|
|
32
|
+
-- ORDER BY a CASE expression — null bucketed past real values
|
|
33
|
+
select id, b from ob order by case when b is null then 999 else b end, id;
|
|
34
|
+
→ [{"id":3,"b":3},{"id":2,"b":5},{"id":6,"b":7},{"id":5,"b":10},{"id":1,"b":null},{"id":4,"b":null}]
|
|
35
|
+
|
|
36
|
+
-- ORDER BY a + b with null propagation; nulls land last via NULLS LAST
|
|
37
|
+
select id, b from ob order by a + b nulls last, id;
|
|
38
|
+
→ [{"id":3,"b":3},{"id":6,"b":7},{"id":2,"b":5},{"id":5,"b":10},{"id":1,"b":null},{"id":4,"b":null}]
|
|
39
|
+
|
|
40
|
+
drop table ob;
|
|
41
|
+
|
|
42
|
+
-- =============================================================================
|
|
43
|
+
-- ORDER BY with per-column COLLATE directives in a multi-key sort
|
|
44
|
+
-- =============================================================================
|
|
45
|
+
|
|
46
|
+
create table cm (id integer primary key, a text, b text);
|
|
47
|
+
insert into cm values
|
|
48
|
+
(1, 'Alice', 'bob'),
|
|
49
|
+
(2, 'bob', 'ALICE'),
|
|
50
|
+
(3, 'alice', 'Bob');
|
|
51
|
+
|
|
52
|
+
-- a COLLATE binary, b COLLATE nocase: 'A'<'a' under binary
|
|
53
|
+
select id from cm order by a collate binary, b collate nocase;
|
|
54
|
+
→ [{"id":1},{"id":3},{"id":2}]
|
|
55
|
+
|
|
56
|
+
-- Reverse roles: a NOCASE then b BINARY
|
|
57
|
+
-- Under nocase, 'Alice'~'alice', tie broken by b binary: 'bob' (id=1) vs 'Bob' (id=3) → 'Bob' first.
|
|
58
|
+
select id from cm order by a collate nocase, b collate binary;
|
|
59
|
+
→ [{"id":3},{"id":1},{"id":2}]
|
|
60
|
+
|
|
61
|
+
drop table cm;
|
|
62
|
+
|
|
63
|
+
-- =============================================================================
|
|
64
|
+
-- ORDER BY many computed columns — sort key precedence remains correct
|
|
65
|
+
-- =============================================================================
|
|
66
|
+
|
|
67
|
+
create table many (x integer);
|
|
68
|
+
insert into many values (1), (5), (9), (7), (3), (2), (4), (6), (8);
|
|
69
|
+
|
|
70
|
+
-- Several computed result columns alongside the sort key
|
|
71
|
+
select x, x + 1 as p1, x + 2 as p2, x + 10 as p10, x + 100 as p100
|
|
72
|
+
from many order by x;
|
|
73
|
+
→ [{"x":1,"p1":2,"p2":3,"p10":11,"p100":101},{"x":2,"p1":3,"p2":4,"p10":12,"p100":102},{"x":3,"p1":4,"p2":5,"p10":13,"p100":103},{"x":4,"p1":5,"p2":6,"p10":14,"p100":104},{"x":5,"p1":6,"p2":7,"p10":15,"p100":105},{"x":6,"p1":7,"p2":8,"p10":16,"p100":106},{"x":7,"p1":8,"p2":9,"p10":17,"p100":107},{"x":8,"p1":9,"p2":10,"p10":18,"p100":108},{"x":9,"p1":10,"p2":11,"p10":19,"p100":109}]
|
|
74
|
+
|
|
75
|
+
-- Alias and positional references resolve to the same expression
|
|
76
|
+
select abs(x - 5) as dist from many order by dist;
|
|
77
|
+
→ [{"dist":0},{"dist":1},{"dist":1},{"dist":2},{"dist":2},{"dist":3},{"dist":3},{"dist":4},{"dist":4}]
|
|
78
|
+
|
|
79
|
+
-- ORDER BY positional ordinal resolves to the SELECT-list expression
|
|
80
|
+
select abs(x - 5) as dist from many order by 1;
|
|
81
|
+
→ [{"dist":0},{"dist":1},{"dist":1},{"dist":2},{"dist":2},{"dist":3},{"dist":3},{"dist":4},{"dist":4}]
|
|
82
|
+
|
|
83
|
+
drop table many;
|
|
84
|
+
|
|
85
|
+
-- =============================================================================
|
|
86
|
+
-- ORDER BY / GROUP BY positional references bind to an OUTPUT POSITION, never
|
|
87
|
+
-- to the name of the expression that produced it. Each case below is paired
|
|
88
|
+
-- with a control query that must produce a DIFFERENT row order than a
|
|
89
|
+
-- name-based resolution would, so a regression cannot pass by coincidence.
|
|
90
|
+
-- =============================================================================
|
|
91
|
+
|
|
92
|
+
create table nk (a text primary key, b text);
|
|
93
|
+
insert into nk values ('x','1'), ('w','9');
|
|
94
|
+
|
|
95
|
+
-- A SELECT-list alias shadows the column the ordinal points at.
|
|
96
|
+
-- Position 2 is `z` (= nk.a), so the 'w' row sorts first. Resolving the ordinal
|
|
97
|
+
-- through the name `a` would find the alias over nk.b and sort '1' before '9'.
|
|
98
|
+
select b as a, a as z from nk order by 2;
|
|
99
|
+
→ [{"a":"9","z":"w"},{"a":"1","z":"x"}]
|
|
100
|
+
|
|
101
|
+
-- Control: the same sort spelled by alias
|
|
102
|
+
select b as a, a as z from nk order by z;
|
|
103
|
+
→ [{"a":"9","z":"w"},{"a":"1","z":"x"}]
|
|
104
|
+
|
|
105
|
+
-- Discriminator: sorting by output position 1 gives the OPPOSITE order
|
|
106
|
+
select b as a, a as z from nk order by 1;
|
|
107
|
+
→ [{"a":"1","z":"x"},{"a":"9","z":"w"}]
|
|
108
|
+
|
|
109
|
+
-- Same shadowing, with the target column arriving via a star
|
|
110
|
+
select b as a, * from nk order by 2;
|
|
111
|
+
→ [{"a":"9","a:1":"w","b":"9"},{"a":"1","a:1":"x","b":"1"}]
|
|
112
|
+
|
|
113
|
+
-- Control: qualified name for the star-expanded column
|
|
114
|
+
select b as a, * from nk order by nk.a;
|
|
115
|
+
→ [{"a":"9","a:1":"w","b":"9"},{"a":"1","a:1":"x","b":"1"}]
|
|
116
|
+
|
|
117
|
+
-- A pre-projection sort (second key is not a projected output column) keeps
|
|
118
|
+
-- resolving the ordinal against the SELECT list, and still lands on `z`
|
|
119
|
+
select b as a, a as z from nk order by 2, a;
|
|
120
|
+
→ [{"a":"9","z":"w"},{"a":"1","z":"x"}]
|
|
121
|
+
|
|
122
|
+
select b as a, a as z from nk order by z, a;
|
|
123
|
+
→ [{"a":"9","z":"w"},{"a":"1","z":"x"}]
|
|
124
|
+
|
|
125
|
+
-- Out-of-range ordinals still fail at prepare time
|
|
126
|
+
select a from nk order by 3;
|
|
127
|
+
-- error: ORDER BY position 3 is not in the SELECT list (1..1)
|
|
128
|
+
|
|
129
|
+
drop table nk;
|
|
130
|
+
|
|
131
|
+
-- -----------------------------------------------------------------------------
|
|
132
|
+
-- Two joined tables expose the same column name under `*`
|
|
133
|
+
-- -----------------------------------------------------------------------------
|
|
134
|
+
|
|
135
|
+
create table ot1 (k integer primary key, v text);
|
|
136
|
+
create table ot2 (k integer primary key, v text);
|
|
137
|
+
insert into ot1 values (1,'a1'), (2,'b1');
|
|
138
|
+
insert into ot2 values (1,'z2'), (2,'y2');
|
|
139
|
+
|
|
140
|
+
-- Output column 4 is ot2.v, so the k=2 row ('y2') sorts first
|
|
141
|
+
select * from ot1 join ot2 on ot1.k = ot2.k order by 4;
|
|
142
|
+
→ [{"k":2,"v":"b1","k:1":2,"v:1":"y2"},{"k":1,"v":"a1","k:1":1,"v:1":"z2"}]
|
|
143
|
+
|
|
144
|
+
-- Control: matches the qualified ot2.v spelling
|
|
145
|
+
select * from ot1 join ot2 on ot1.k = ot2.k order by ot2.v;
|
|
146
|
+
→ [{"k":2,"v":"b1","k:1":2,"v:1":"y2"},{"k":1,"v":"a1","k:1":1,"v:1":"z2"}]
|
|
147
|
+
|
|
148
|
+
-- Discriminator: ot1.v produces the OPPOSITE order, so a name-based resolution
|
|
149
|
+
-- (which picks the first `v` in scope) cannot pass the case above
|
|
150
|
+
select * from ot1 join ot2 on ot1.k = ot2.k order by ot1.v;
|
|
151
|
+
→ [{"k":1,"v":"a1","k:1":1,"v:1":"z2"},{"k":2,"v":"b1","k:1":2,"v:1":"y2"}]
|
|
152
|
+
|
|
153
|
+
drop table ot2;
|
|
154
|
+
drop table ot1;
|
|
155
|
+
|
|
156
|
+
-- -----------------------------------------------------------------------------
|
|
157
|
+
-- Ordinals pointing at computed output columns (window / aggregate)
|
|
158
|
+
-- -----------------------------------------------------------------------------
|
|
159
|
+
|
|
160
|
+
create table og (id integer primary key, a text, b text);
|
|
161
|
+
insert into og values (1,'x','1'), (2,'w','9');
|
|
162
|
+
|
|
163
|
+
-- DISTINCT takes the same path; position 2 is still `z`
|
|
164
|
+
select distinct b as a, a as z from og order by 2;
|
|
165
|
+
→ [{"a":"9","z":"w"},{"a":"1","z":"x"}]
|
|
166
|
+
|
|
167
|
+
select distinct b as a, a as z from og order by z;
|
|
168
|
+
→ [{"a":"9","z":"w"},{"a":"1","z":"x"}]
|
|
169
|
+
|
|
170
|
+
-- The ordinal points at a window function: it must READ the computed column,
|
|
171
|
+
-- not re-plan a fresh window expression inside the sort
|
|
172
|
+
select b as a, row_number() over (order by a) as z from og order by 2;
|
|
173
|
+
→ [{"a":"9","z":1},{"a":"1","z":2}]
|
|
174
|
+
|
|
175
|
+
select b as a, row_number() over (order by a) as z from og order by z;
|
|
176
|
+
→ [{"a":"9","z":1},{"a":"1","z":2}]
|
|
177
|
+
|
|
178
|
+
-- The ordinal points at an aggregate in a query with no GROUP BY
|
|
179
|
+
select count(*) as c from og order by 1;
|
|
180
|
+
→ [{"c":2}]
|
|
181
|
+
|
|
182
|
+
select count(*) as c from og order by count(*);
|
|
183
|
+
→ [{"c":2}]
|
|
184
|
+
|
|
185
|
+
select count(*) as c, max(a) as m from og order by 2;
|
|
186
|
+
→ [{"c":2,"m":"x"}]
|
|
187
|
+
|
|
188
|
+
-- GROUP BY ordinal binds to the aliased expression, not to the alias name
|
|
189
|
+
select b as a, count(*) as c from og group by 1 order by 1;
|
|
190
|
+
→ [{"a":"1","c":1},{"a":"9","c":1}]
|
|
191
|
+
|
|
192
|
+
select b as a, count(*) as c from og group by b order by 1;
|
|
193
|
+
→ [{"a":"1","c":1},{"a":"9","c":1}]
|
|
194
|
+
|
|
195
|
+
-- Grouped query, ORDER BY ordinal on the aggregate output column
|
|
196
|
+
select b as q, count(*) as c from og group by b order by 2 desc, 1;
|
|
197
|
+
→ [{"q":"1","c":1},{"q":"9","c":1}]
|
|
198
|
+
|
|
199
|
+
drop table og;
|
|
200
|
+
|
|
201
|
+
-- -----------------------------------------------------------------------------
|
|
202
|
+
-- GROUP BY ordinal onto a star-expanded column whose name is shared
|
|
203
|
+
-- -----------------------------------------------------------------------------
|
|
204
|
+
|
|
205
|
+
create table jt1 (id integer primary key, k integer, v text);
|
|
206
|
+
create table jt2 (k integer primary key, v text);
|
|
207
|
+
insert into jt1 values (1,1,'L'), (2,1,'L'), (3,2,'L');
|
|
208
|
+
insert into jt2 values (1,'R1'), (2,'R2');
|
|
209
|
+
|
|
210
|
+
-- Positions 1 and 2 are jt2.k / jt2.v (from `jt2.*`). Resolving them through
|
|
211
|
+
-- the bare names `k` / `v` finds jt1's columns first, which leaves jt2.k and
|
|
212
|
+
-- jt2.v ungrouped and fails the GROUP BY coverage check.
|
|
213
|
+
select jt2.*, count(*) as n from jt1 join jt2 on jt1.k = jt2.k group by 1, 2 order by 1;
|
|
214
|
+
→ [{"k":1,"v":"R1","n":2},{"k":2,"v":"R2","n":1}]
|
|
215
|
+
|
|
216
|
+
select jt2.*, count(*) as n from jt1 join jt2 on jt1.k = jt2.k group by jt2.k, jt2.v order by 1;
|
|
217
|
+
→ [{"k":1,"v":"R1","n":2},{"k":2,"v":"R2","n":1}]
|
|
218
|
+
|
|
219
|
+
-- ORDER BY ordinal over that grouped output: position 3 is the count
|
|
220
|
+
select jt2.*, count(*) as n from jt1 join jt2 on jt1.k = jt2.k group by 1, 2 order by 3 desc;
|
|
221
|
+
→ [{"k":1,"v":"R1","n":2},{"k":2,"v":"R2","n":1}]
|
|
222
|
+
|
|
223
|
+
-- An ORDER BY that names an aggregate the select list lacks sorts in the same
|
|
224
|
+
-- place as every other aggregate ORDER BY: above the grouped query's final
|
|
225
|
+
-- projection. A second ordinal key in the same clause therefore binds to that
|
|
226
|
+
-- projection's output attributes. Position 2 is jt2.v either way -- binding to
|
|
227
|
+
-- the output attribute and falling back to the select list agree here -- so
|
|
228
|
+
-- these two pin the result, not the route.
|
|
229
|
+
select jt2.*, count(*) as n from jt1 join jt2 on jt1.k = jt2.k group by 1, 2 order by count(*) desc, 2;
|
|
230
|
+
→ [{"k":1,"v":"R1","n":2},{"k":2,"v":"R2","n":1}]
|
|
231
|
+
|
|
232
|
+
select jt2.*, count(*) as n from jt1 join jt2 on jt1.k = jt2.k group by jt2.k, jt2.v order by count(*) desc, jt2.v;
|
|
233
|
+
→ [{"k":1,"v":"R1","n":2},{"k":2,"v":"R2","n":1}]
|
|
234
|
+
|
|
235
|
+
drop table jt2;
|
|
236
|
+
drop table jt1;
|
|
237
|
+
|
|
238
|
+
-- -----------------------------------------------------------------------------
|
|
239
|
+
-- Qualified stars from more than two sources
|
|
240
|
+
-- -----------------------------------------------------------------------------
|
|
241
|
+
|
|
242
|
+
create table os1 (k integer primary key, v text);
|
|
243
|
+
create table os2 (k integer primary key, v text);
|
|
244
|
+
create table os3 (k integer primary key, v text);
|
|
245
|
+
insert into os1 values (1,'a1'), (2,'b1');
|
|
246
|
+
insert into os2 values (1,'z2'), (2,'y2');
|
|
247
|
+
insert into os3 values (1,'m3'), (2,'n3');
|
|
248
|
+
|
|
249
|
+
-- All three sources expose a `v`; position 6 is os3.v and position 4 is os2.v,
|
|
250
|
+
-- and the two produce OPPOSITE row orders, so neither can pass by coincidence.
|
|
251
|
+
select os1.*, os2.*, os3.* from os1 join os2 on os1.k = os2.k join os3 on os1.k = os3.k order by 6;
|
|
252
|
+
→ [{"k":1,"v":"a1","k:1":1,"v:1":"z2","k:2":1,"v:2":"m3"},{"k":2,"v":"b1","k:1":2,"v:1":"y2","k:2":2,"v:2":"n3"}]
|
|
253
|
+
|
|
254
|
+
select os1.*, os2.*, os3.* from os1 join os2 on os1.k = os2.k join os3 on os1.k = os3.k order by os3.v;
|
|
255
|
+
→ [{"k":1,"v":"a1","k:1":1,"v:1":"z2","k:2":1,"v:2":"m3"},{"k":2,"v":"b1","k:1":2,"v:1":"y2","k:2":2,"v:2":"n3"}]
|
|
256
|
+
|
|
257
|
+
select os1.*, os2.*, os3.* from os1 join os2 on os1.k = os2.k join os3 on os1.k = os3.k order by 4;
|
|
258
|
+
→ [{"k":2,"v":"b1","k:1":2,"v:1":"y2","k:2":2,"v:2":"n3"},{"k":1,"v":"a1","k:1":1,"v:1":"z2","k:2":1,"v:2":"m3"}]
|
|
259
|
+
|
|
260
|
+
select os1.*, os2.*, os3.* from os1 join os2 on os1.k = os2.k join os3 on os1.k = os3.k order by os2.v;
|
|
261
|
+
→ [{"k":2,"v":"b1","k:1":2,"v:1":"y2","k:2":2,"v:2":"n3"},{"k":1,"v":"a1","k:1":1,"v:1":"z2","k:2":1,"v:2":"m3"}]
|
|
262
|
+
|
|
263
|
+
drop table os3;
|
|
264
|
+
drop table os2;
|
|
265
|
+
drop table os1;
|
|
266
|
+
|
|
267
|
+
-- -----------------------------------------------------------------------------
|
|
268
|
+
-- Ordinals through the remaining ORDER BY shapes
|
|
269
|
+
-- -----------------------------------------------------------------------------
|
|
270
|
+
|
|
271
|
+
create table ow (id integer primary key, a text, b text);
|
|
272
|
+
insert into ow values (1,'x','p'), (2,'w','q'), (3,'v','q');
|
|
273
|
+
|
|
274
|
+
-- Ordinals compose with the rest of the clause: direction, a second key,
|
|
275
|
+
-- LIMIT, and NULLS placement all still apply to the bound output column.
|
|
276
|
+
select b as z, id from ow order by 1, 2;
|
|
277
|
+
→ [{"z":"p","id":1},{"z":"q","id":2},{"z":"q","id":3}]
|
|
278
|
+
|
|
279
|
+
select b as z, id from ow order by 1 desc, 2;
|
|
280
|
+
→ [{"z":"q","id":2},{"z":"q","id":3},{"z":"p","id":1}]
|
|
281
|
+
|
|
282
|
+
select b as z, id from ow order by 1, 2 limit 2;
|
|
283
|
+
→ [{"z":"p","id":1},{"z":"q","id":2}]
|
|
284
|
+
|
|
285
|
+
-- A star select list under GROUP BY: the ordinals name the grouped columns
|
|
286
|
+
select * from ow group by 1, 2, 3 order by 2;
|
|
287
|
+
→ [{"id":3,"a":"v","b":"q"},{"id":2,"a":"w","b":"q"},{"id":1,"a":"x","b":"p"}]
|
|
288
|
+
|
|
289
|
+
select * from ow group by id, a, b order by a;
|
|
290
|
+
→ [{"id":3,"a":"v","b":"q"},{"id":2,"a":"w","b":"q"},{"id":1,"a":"x","b":"p"}]
|
|
291
|
+
|
|
292
|
+
-- Through a CTE and through a derived table: the outer `select *` publishes the
|
|
293
|
+
-- inner names, and position 2 is still the inner `z`
|
|
294
|
+
with cw as (select b as a, a as z from ow) select * from cw order by 2;
|
|
295
|
+
→ [{"a":"q","z":"v"},{"a":"q","z":"w"},{"a":"p","z":"x"}]
|
|
296
|
+
|
|
297
|
+
select * from (select b as a, a as z from ow) order by 2;
|
|
298
|
+
→ [{"a":"q","z":"v"},{"a":"q","z":"w"},{"a":"p","z":"x"}]
|
|
299
|
+
|
|
300
|
+
-- Zero is out of range, like a negative or too-large position
|
|
301
|
+
select a from ow order by 0;
|
|
302
|
+
-- error: ORDER BY position 0 is not in the SELECT list (1..1)
|
|
303
|
+
|
|
304
|
+
-- A window query containing `*` publishes one output attribute per SELECT-list
|
|
305
|
+
-- column, stars expanded, so an ordinal binds the window column directly:
|
|
306
|
+
-- position 4 is `w`, after the three star columns.
|
|
307
|
+
select *, row_number() over (order by a) as w from ow order by 4;
|
|
308
|
+
→ [{"id":3,"a":"v","b":"q","w":1},{"id":2,"a":"w","b":"q","w":2},{"id":1,"a":"x","b":"p","w":3}]
|
|
309
|
+
|
|
310
|
+
select *, row_number() over (order by a) as w from ow order by 4 desc;
|
|
311
|
+
→ [{"id":1,"a":"x","b":"p","w":3},{"id":2,"a":"w","b":"q","w":2},{"id":3,"a":"v","b":"q","w":1}]
|
|
312
|
+
|
|
313
|
+
-- ...and position 5 is out of range: the select list has 4 entries.
|
|
314
|
+
select *, row_number() over (order by a) as w from ow order by 5;
|
|
315
|
+
-- error: ORDER BY position 5 is not in the SELECT list (1..4)
|
|
316
|
+
|
|
317
|
+
drop table ow;
|
|
318
|
+
|
|
319
|
+
-- NULLS FIRST / LAST apply to the bound output column
|
|
320
|
+
create table onul (id integer primary key, v text null);
|
|
321
|
+
insert into onul values (1, null), (2, 'a');
|
|
322
|
+
|
|
323
|
+
select v as z, id from onul order by 1 nulls first;
|
|
324
|
+
→ [{"z":null,"id":1},{"z":"a","id":2}]
|
|
325
|
+
|
|
326
|
+
select v as z, id from onul order by 1 nulls last;
|
|
327
|
+
→ [{"z":"a","id":2},{"z":null,"id":1}]
|
|
328
|
+
|
|
329
|
+
drop table onul;
|
|
330
|
+
|
|
331
|
+
-- The bound output column carries its declared collation, so an ordinal sorts
|
|
332
|
+
-- identically to the name form
|
|
333
|
+
create table ocol (id integer primary key, v text collate nocase);
|
|
334
|
+
insert into ocol values (1,'B'), (2,'a');
|
|
335
|
+
|
|
336
|
+
select v as z from ocol order by 1;
|
|
337
|
+
→ [{"z":"a"},{"z":"B"}]
|
|
338
|
+
|
|
339
|
+
select v as z from ocol order by z;
|
|
340
|
+
→ [{"z":"a"},{"z":"B"}]
|
|
341
|
+
|
|
342
|
+
drop table ocol;
|
|
343
|
+
|
|
344
|
+
-- =============================================================================
|
|
345
|
+
-- An UNGROUPED aggregate query's ORDER BY can name the query's own output
|
|
346
|
+
-- columns by SELECT-list alias. The alias only exists above the aggregation, so
|
|
347
|
+
-- the sort has to run there rather than on the per-input rows.
|
|
348
|
+
-- =============================================================================
|
|
349
|
+
|
|
350
|
+
create table g (id integer primary key, a text, b text);
|
|
351
|
+
insert into g values (1,'p','1'), (2,'p','2'), (3,'q','1');
|
|
352
|
+
|
|
353
|
+
-- The whole query is one row; naming its own column just returns it
|
|
354
|
+
select count(*) as c from g order by c;
|
|
355
|
+
→ [{"c":3}]
|
|
356
|
+
|
|
357
|
+
select count(*) as c from g order by c desc;
|
|
358
|
+
→ [{"c":3}]
|
|
359
|
+
|
|
360
|
+
-- The alias of the SECOND aggregate, not the first
|
|
361
|
+
select count(*) as c, max(a) as m from g order by m;
|
|
362
|
+
→ [{"c":3,"m":"q"}]
|
|
363
|
+
|
|
364
|
+
-- A WRAPPED aggregate: the aggregate entry is aliased `count(*)`, so `c` names
|
|
365
|
+
-- the final projection's output column, not the AggregateNode's
|
|
366
|
+
select count(*) + 1 as c from g order by c;
|
|
367
|
+
→ [{"c":4}]
|
|
368
|
+
|
|
369
|
+
-- The alias inside a larger ORDER BY expression, and under COLLATE
|
|
370
|
+
select count(*) as c from g order by c + 1;
|
|
371
|
+
→ [{"c":3}]
|
|
372
|
+
|
|
373
|
+
select max(a) as c from g order by c collate nocase;
|
|
374
|
+
→ [{"c":"q"}]
|
|
375
|
+
|
|
376
|
+
-- Alias matching is case-insensitive
|
|
377
|
+
select count(*) as "C" from g order by c;
|
|
378
|
+
→ [{"C":3}]
|
|
379
|
+
|
|
380
|
+
-- Composes with a second sort key and with LIMIT
|
|
381
|
+
select count(*) as c from g order by c, max(a);
|
|
382
|
+
→ [{"c":3}]
|
|
383
|
+
|
|
384
|
+
select count(*) as c from g order by c limit 1;
|
|
385
|
+
→ [{"c":3}]
|
|
386
|
+
|
|
387
|
+
-- ...but the second key must itself be legal above the aggregate. ORDER BY
|
|
388
|
+
-- placement is decided for the WHOLE list, not per term: naming the alias `c`
|
|
389
|
+
-- moves every term above the AggregateNode, and a bare source column up there is
|
|
390
|
+
-- neither a grouping key (there are none) nor an aggregate.
|
|
391
|
+
select count(*) as c from g order by c, id;
|
|
392
|
+
-- error: Column 'id' must appear in the GROUP BY clause or be used in an aggregate function
|
|
393
|
+
|
|
394
|
+
-- Same list, other order — the rejection is about the list, not about which term
|
|
395
|
+
-- came first.
|
|
396
|
+
select count(*) as c from g order by id, c;
|
|
397
|
+
-- error: Column 'id' must appear in the GROUP BY clause or be used in an aggregate function
|
|
398
|
+
|
|
399
|
+
-- Control: with NO alias and no aggregate in the list, the whole list stays below
|
|
400
|
+
-- the aggregate and `id` is an ordinary pre-aggregate sort key.
|
|
401
|
+
select count(*) as c from g order by id;
|
|
402
|
+
→ [{"c":3}]
|
|
403
|
+
|
|
404
|
+
-- ...and with HAVING
|
|
405
|
+
select count(*) as c from g having count(*) > 0 order by c;
|
|
406
|
+
→ [{"c":3}]
|
|
407
|
+
|
|
408
|
+
-- A SELECT-list alias OUTRANKS a same-named source column, matching SQLite and
|
|
409
|
+
-- the non-aggregate / grouped paths. Observable through an order-sensitive
|
|
410
|
+
-- aggregate: `a` names the one-row output, so the sort is a no-op and the
|
|
411
|
+
-- concatenation keeps insertion order.
|
|
412
|
+
select group_concat(b) as a from g order by a desc;
|
|
413
|
+
→ [{"a":"1,2,1"}]
|
|
414
|
+
|
|
415
|
+
-- Control: with no alias to claim the name, `a` is still g.a and the
|
|
416
|
+
-- pre-aggregate sort extension still orders the input before concatenating.
|
|
417
|
+
-- The `, id` tiebreak keeps the two a='p' rows in a fixed order.
|
|
418
|
+
select group_concat(b) as gc from g order by a desc, id;
|
|
419
|
+
→ [{"gc":"1,1,2"}]
|
|
420
|
+
|
|
421
|
+
select group_concat(b) as gc from g order by a, id;
|
|
422
|
+
→ [{"gc":"1,2,1"}]
|
|
423
|
+
|
|
424
|
+
-- Same control spelled with a table qualifier: `g.a` is never an alias, so the
|
|
425
|
+
-- input sort survives even though a select-list alias `a` exists
|
|
426
|
+
select group_concat(b) as a from g order by g.a desc, id;
|
|
427
|
+
→ [{"a":"1,1,2"}]
|
|
428
|
+
|
|
429
|
+
-- A scalar subquery's ProjectNode does not forward the aggregate's own output
|
|
430
|
+
-- column, yet both spellings still resolve
|
|
431
|
+
select (select count(*) + 1 as c from g order by c) as v;
|
|
432
|
+
→ [{"v":4}]
|
|
433
|
+
|
|
434
|
+
select (select count(*) + 1 as c from g order by count(*)) as v;
|
|
435
|
+
→ [{"v":4}]
|
|
436
|
+
|
|
437
|
+
-- A subquery in ORDER BY: the alias scan walks into it, so it must not trip over
|
|
438
|
+
-- the subquery's own SELECT-list result columns
|
|
439
|
+
select count(*) as zz from g order by (select 1);
|
|
440
|
+
→ [{"zz":3}]
|
|
441
|
+
|
|
442
|
+
-- Non-regressions: the spelled-out aggregate, the ordinal, and a qualified name
|
|
443
|
+
select count(*) as c from g order by count(*);
|
|
444
|
+
→ [{"c":3}]
|
|
445
|
+
|
|
446
|
+
select count(*) as c from g order by 1;
|
|
447
|
+
→ [{"c":3}]
|
|
448
|
+
|
|
449
|
+
select count(*) as c from g order by g.a;
|
|
450
|
+
→ [{"c":3}]
|
|
451
|
+
|
|
452
|
+
-- Two select-list columns claiming the same alias: the routing predicate only asks
|
|
453
|
+
-- whether the name is mentioned and leaves resolution to the scope, which rejects it.
|
|
454
|
+
-- Deliberate divergence: SQLite binds the first match (returns `3|q`), and Quereus's
|
|
455
|
+
-- own non-aggregate and grouped paths accept the duplicate too; only the aggregate
|
|
456
|
+
-- output scope treats it as ambiguous. Erroring on a genuinely ambiguous name is the
|
|
457
|
+
-- behaviour we want here — this pins it so a change is a decision, not an accident.
|
|
458
|
+
select count(*) as c, max(a) as c from g order by c;
|
|
459
|
+
-- error: ambiguous column name: c
|
|
460
|
+
|
|
461
|
+
-- An alias that is neither a select-list alias nor a source column still fails
|
|
462
|
+
select count(*) as c from g order by cc;
|
|
463
|
+
-- error: Column not found: cc
|
|
464
|
+
|
|
465
|
+
-- DISTINCT and a compound select take the same alias route
|
|
466
|
+
select distinct count(*) as c from g order by c;
|
|
467
|
+
→ [{"c":3}]
|
|
468
|
+
|
|
469
|
+
select count(*) as c from g union all select count(*) from g order by c;
|
|
470
|
+
→ [{"c":3},{"c":3}]
|
|
471
|
+
|
|
472
|
+
-- Non-regressions: the grouped forms, which never took the pre-aggregate path
|
|
473
|
+
select a, count(*) as c from g group by a order by c;
|
|
474
|
+
→ [{"a":"q","c":1},{"a":"p","c":2}]
|
|
475
|
+
|
|
476
|
+
select a, count(*) as c from g group by a order by c + 1;
|
|
477
|
+
→ [{"a":"q","c":1},{"a":"p","c":2}]
|
|
478
|
+
|
|
479
|
+
drop table g;
|
|
480
|
+
|
|
481
|
+
-- =============================================================================
|
|
482
|
+
-- ORDER BY that names BOTH an aggregate the SELECT list lacks AND a SELECT-list
|
|
483
|
+
-- alias. The sort-only aggregate is computed by the AggregateNode but stripped
|
|
484
|
+
-- by the final projection; the alias exists only ON that final projection. One
|
|
485
|
+
-- sort placement -- above the final projection -- has to serve both names.
|
|
486
|
+
-- Rows below are SQLite's.
|
|
487
|
+
-- =============================================================================
|
|
488
|
+
|
|
489
|
+
create table soa (id integer primary key, a text, b text);
|
|
490
|
+
insert into soa values (1,'x','p'), (2,'y','q'), (3,'x','r');
|
|
491
|
+
|
|
492
|
+
-- --- UNGROUPED: the whole table is one row, so only the key resolution is
|
|
493
|
+
-- --- under test, not the ordering.
|
|
494
|
+
|
|
495
|
+
-- bare-aggregate alias (`c` also names the AggregateNode's own output column)
|
|
496
|
+
select count(*) as c from soa order by max(a), c;
|
|
497
|
+
→ [{"c":3}]
|
|
498
|
+
|
|
499
|
+
-- computed-aggregate alias: the aggregate entry is aliased `count(*)`, so `c`
|
|
500
|
+
-- names ONLY the final projection's output column. This is the shape that used
|
|
501
|
+
-- to fail with "Column not found: c".
|
|
502
|
+
select count(*) + 1 as c from soa order by max(a), c;
|
|
503
|
+
→ [{"c":4}]
|
|
504
|
+
|
|
505
|
+
-- positional reference alongside the sort-only aggregate
|
|
506
|
+
select count(*) + 1 as c from soa order by max(a), 1;
|
|
507
|
+
→ [{"c":4}]
|
|
508
|
+
|
|
509
|
+
-- the alias inside a larger ORDER BY expression
|
|
510
|
+
select count(*) + 1 as c from soa order by max(a), c + 0;
|
|
511
|
+
→ [{"c":4}]
|
|
512
|
+
|
|
513
|
+
-- the sort-only aggregate need not be the same function as the selected one
|
|
514
|
+
select length(max(a)) as c from soa order by min(b), c;
|
|
515
|
+
→ [{"c":1}]
|
|
516
|
+
|
|
517
|
+
-- the ungrouped counterpart of the grouped grouping-key-alias case below: an
|
|
518
|
+
-- ungrouped aggregate query has no grouping key, so a column-free select-list
|
|
519
|
+
-- item stands in for one. Its alias has to resolve on the final projection while
|
|
520
|
+
-- `max(a)` resolves on the AggregateNode below it -- the same two-name split.
|
|
521
|
+
select 'all' as k, count(*) as c from soa order by max(a), k;
|
|
522
|
+
→ [{"k":"all","c":3}]
|
|
523
|
+
|
|
524
|
+
-- --- GROUPED: group 'x' has max(b)='r' and 2 rows, group 'y' has max(b)='q'
|
|
525
|
+
-- --- and 1 row, so ordering by max(b) puts 'y' first.
|
|
526
|
+
|
|
527
|
+
-- bare-aggregate alias
|
|
528
|
+
select a, count(*) as c from soa group by a order by max(b), c;
|
|
529
|
+
→ [{"a":"y","c":1},{"a":"x","c":2}]
|
|
530
|
+
|
|
531
|
+
-- computed-aggregate alias
|
|
532
|
+
select a, count(*) + 1 as c from soa group by a order by max(b), c;
|
|
533
|
+
→ [{"a":"y","c":2},{"a":"x","c":3}]
|
|
534
|
+
|
|
535
|
+
-- grouping-key alias
|
|
536
|
+
select a as k, count(*) as c from soa group by a order by max(b), k;
|
|
537
|
+
→ [{"k":"y","c":1},{"k":"x","c":2}]
|
|
538
|
+
|
|
539
|
+
-- positional reference (position 2 is the computed alias)
|
|
540
|
+
select a, count(*) + 1 as c from soa group by a order by max(b), 2;
|
|
541
|
+
→ [{"a":"y","c":2},{"a":"x","c":3}]
|
|
542
|
+
|
|
543
|
+
-- the alias inside a larger ORDER BY expression
|
|
544
|
+
select a, count(*) + 1 as c from soa group by a order by max(b), c + 0;
|
|
545
|
+
→ [{"a":"y","c":2},{"a":"x","c":3}]
|
|
546
|
+
|
|
547
|
+
-- --- The same pairing under each surrounding modifier. DISTINCT and LIMIT sit
|
|
548
|
+
-- --- above this sort, HAVING below it.
|
|
549
|
+
|
|
550
|
+
select distinct count(*) + 1 as c from soa order by max(a), c;
|
|
551
|
+
→ [{"c":4}]
|
|
552
|
+
|
|
553
|
+
select distinct a, count(*) + 1 as c from soa group by a order by max(b), c;
|
|
554
|
+
→ [{"a":"y","c":2},{"a":"x","c":3}]
|
|
555
|
+
|
|
556
|
+
select a, count(*) + 1 as c from soa group by a order by max(b), c limit 1;
|
|
557
|
+
→ [{"a":"y","c":2}]
|
|
558
|
+
|
|
559
|
+
select a, count(*) + 1 as c from soa group by a having count(*) >= 1 order by max(b), c;
|
|
560
|
+
→ [{"a":"y","c":2},{"a":"x","c":3}]
|
|
561
|
+
|
|
562
|
+
-- --- Nested spellings: a derived table and a scalar subquery each wrap the
|
|
563
|
+
-- --- query in another ProjectNode above the sort.
|
|
564
|
+
|
|
565
|
+
select * from (select count(*) + 1 as c from soa order by max(a), c);
|
|
566
|
+
→ [{"c":4}]
|
|
567
|
+
|
|
568
|
+
select (select count(*) + 1 as c from soa order by max(a), c) as v;
|
|
569
|
+
→ [{"v":4}]
|
|
570
|
+
|
|
571
|
+
drop table soa;
|
|
572
|
+
|
|
573
|
+
-- =============================================================================
|
|
574
|
+
-- Ordering correctness for the same pairing. The sort-only aggregate max(val)
|
|
575
|
+
-- is deliberately anti-correlated with BOTH the group name and the group size,
|
|
576
|
+
-- so a plan that silently sorted by either would produce a different order:
|
|
577
|
+
--
|
|
578
|
+
-- grp | rows | max(val) by max(val) asc: a, c, d, e, b
|
|
579
|
+
-- ----+------+--------- by grp asc: a, b, c, d, e
|
|
580
|
+
-- a | 3 | m1 by size asc: b, d, a, c, e
|
|
581
|
+
-- b | 1 | m4
|
|
582
|
+
-- c | 4 | m2 Groups d and e TIE on max(val)='m3'; the computed
|
|
583
|
+
-- d | 2 | m3 alias count(*)+1 (3 vs 6) breaks the tie, so the
|
|
584
|
+
-- e | 5 | m3 second key's own direction is observable too.
|
|
585
|
+
-- =============================================================================
|
|
586
|
+
|
|
587
|
+
create table sog (id integer primary key, grp text, val text);
|
|
588
|
+
insert into sog values
|
|
589
|
+
(1,'a','m1'), (2,'a','l0'), (3,'a','k0'),
|
|
590
|
+
(4,'b','m4'),
|
|
591
|
+
(5,'c','m2'), (6,'c','l1'), (7,'c','l2'), (8,'c','k1'),
|
|
592
|
+
(9,'d','m3'), (10,'d','a0'),
|
|
593
|
+
(11,'e','m3'), (12,'e','b0'), (13,'e','b1'), (14,'e','b2'), (15,'e','b3');
|
|
594
|
+
|
|
595
|
+
-- ascending: tie d/e broken ascending by the alias
|
|
596
|
+
select grp, count(*) + 1 as c from sog group by grp order by max(val), c;
|
|
597
|
+
→ [{"grp":"a","c":4},{"grp":"c","c":5},{"grp":"d","c":3},{"grp":"e","c":6},{"grp":"b","c":2}]
|
|
598
|
+
|
|
599
|
+
-- descending first key, ascending tiebreak: whole order reverses, d still before e
|
|
600
|
+
select grp, count(*) + 1 as c from sog group by grp order by max(val) desc, c;
|
|
601
|
+
→ [{"grp":"b","c":2},{"grp":"d","c":3},{"grp":"e","c":6},{"grp":"c","c":5},{"grp":"a","c":4}]
|
|
602
|
+
|
|
603
|
+
-- both descending: only the tied pair swaps
|
|
604
|
+
select grp, count(*) + 1 as c from sog group by grp order by max(val) desc, c desc;
|
|
605
|
+
→ [{"grp":"b","c":2},{"grp":"e","c":6},{"grp":"d","c":3},{"grp":"c","c":5},{"grp":"a","c":4}]
|
|
606
|
+
|
|
607
|
+
-- LIMIT cuts the sorted prefix, and the tiebreak direction decides row 3
|
|
608
|
+
select grp, count(*) + 1 as c from sog group by grp order by max(val), c limit 3;
|
|
609
|
+
→ [{"grp":"a","c":4},{"grp":"c","c":5},{"grp":"d","c":3}]
|
|
610
|
+
|
|
611
|
+
select grp, count(*) + 1 as c from sog group by grp order by max(val), c desc limit 3;
|
|
612
|
+
→ [{"grp":"a","c":4},{"grp":"c","c":5},{"grp":"e","c":6}]
|
|
613
|
+
|
|
614
|
+
-- a grouping-key alias as the tiebreak, over a different sort-only aggregate
|
|
615
|
+
select grp as k, count(*) as n from sog group by grp order by min(val) desc, k;
|
|
616
|
+
→ [{"k":"b","n":1},{"k":"c","n":4},{"k":"a","n":3},{"k":"e","n":5},{"k":"d","n":2}]
|
|
617
|
+
|
|
618
|
+
drop table sog;
|
|
619
|
+
|
|
620
|
+
-- =============================================================================
|
|
621
|
+
-- DISTINCT actually collapsing rows, with a sort-only aggregate as the key. The
|
|
622
|
+
-- DistinctNode sits BETWEEN the final projection and this sort, so these pin two
|
|
623
|
+
-- things at once: DISTINCT dedupes before the sort (the direction of max(v) is
|
|
624
|
+
-- observable in the surviving order), and the sort-only aggregate key still
|
|
625
|
+
-- resolves through the DistinctNode -- it yields per source row rather than
|
|
626
|
+
-- buffering, so the projection's source row context is still live.
|
|
627
|
+
--
|
|
628
|
+
-- g | rows | max(v) by max(v) asc: b(3), a(2), c(2) -> distinct 3, 2
|
|
629
|
+
-- --+------+------- by max(v) desc: c(2), a(2), b(3) -> distinct 2, 3
|
|
630
|
+
-- a | 2 | m1
|
|
631
|
+
-- b | 3 | a2
|
|
632
|
+
-- c | 2 | z1
|
|
633
|
+
-- Rows below are SQLite's.
|
|
634
|
+
-- =============================================================================
|
|
635
|
+
|
|
636
|
+
create table sod (id integer primary key, g text, v text);
|
|
637
|
+
insert into sod values
|
|
638
|
+
(1,'b','a0'), (2,'b','a1'), (3,'b','a2'),
|
|
639
|
+
(4,'a','m0'), (5,'a','m1'),
|
|
640
|
+
(6,'c','z0'), (7,'c','z1');
|
|
641
|
+
|
|
642
|
+
select distinct count(*) as c from sod group by g order by max(v);
|
|
643
|
+
→ [{"c":3},{"c":2}]
|
|
644
|
+
|
|
645
|
+
select distinct count(*) as c from sod group by g order by max(v) desc;
|
|
646
|
+
→ [{"c":2},{"c":3}]
|
|
647
|
+
|
|
648
|
+
-- same, with a computed alias the final projection alone publishes
|
|
649
|
+
select distinct count(*) + 1 as c from sod group by g order by max(v);
|
|
650
|
+
→ [{"c":4},{"c":3}]
|
|
651
|
+
|
|
652
|
+
drop table sod;
|
|
653
|
+
|
|
654
|
+
-- A SELECT-list alias that shadows a real column of the table, with the shadowed
|
|
655
|
+
-- column inside the sort-only aggregate: `max(c)` must still read the table's c
|
|
656
|
+
-- (group x has 'p','r' -> 'r'; group y has 'q'), while the bare `c` key is the
|
|
657
|
+
-- alias on the final projection. One sort placement resolves both. Rows are
|
|
658
|
+
-- SQLite's.
|
|
659
|
+
create table sh (id integer primary key, a text, c text);
|
|
660
|
+
insert into sh values (1,'x','p'), (2,'y','q'), (3,'x','r');
|
|
661
|
+
|
|
662
|
+
select a, count(*) + 1 as c from sh group by a order by max(c), c;
|
|
663
|
+
→ [{"a":"y","c":2},{"a":"x","c":3}]
|
|
664
|
+
|
|
665
|
+
select a, count(*) + 1 as c from sh group by a order by max(c) desc, c;
|
|
666
|
+
→ [{"a":"x","c":3},{"a":"y","c":2}]
|
|
667
|
+
|
|
668
|
+
drop table sh;
|
|
669
|
+
|
|
670
|
+
-- The same pairing where another builder wraps or re-plans the query: a CTE
|
|
671
|
+
-- body, and the window path (whose ORDER BY was never routed through the
|
|
672
|
+
-- retired early placement, so this pins that the two paths now agree).
|
|
673
|
+
-- Rows are SQLite's.
|
|
674
|
+
create table soa2 (id integer primary key, a text, b text);
|
|
675
|
+
insert into soa2 values (1,'x','p'), (2,'y','q'), (3,'x','r');
|
|
676
|
+
|
|
677
|
+
with w as (select a, count(*) + 1 as c from soa2 group by a order by max(b), c) select * from w;
|
|
678
|
+
→ [{"a":"y","c":2},{"a":"x","c":3}]
|
|
679
|
+
|
|
680
|
+
select a, count(*) over () as w, count(*) + 1 as c from soa2 group by a order by max(b), c;
|
|
681
|
+
→ [{"a":"y","w":2,"c":2},{"a":"x","w":2,"c":3}]
|
|
682
|
+
|
|
683
|
+
drop table soa2;
|
|
684
|
+
|
|
685
|
+
-- The sort-only aggregate does NOT relax the grouped-plan boundary check for the
|
|
686
|
+
-- keys beside it: `b` is neither grouped nor aggregated, and moving the sort above
|
|
687
|
+
-- the final projection must still reject it at plan time with the user-facing GROUP
|
|
688
|
+
-- BY message -- not ship a plan that dies at run time with "No row context found".
|
|
689
|
+
-- (Deliberate divergence: SQLite accepts this and sorts by an arbitrary row of the
|
|
690
|
+
-- group. See docs/runtime.md § "Corollary: a published source row reaches only the
|
|
691
|
+
-- adjacent consumer".)
|
|
692
|
+
create table sob (id integer primary key, a text, b text);
|
|
693
|
+
insert into sob values (1,'x','p'), (2,'y','q'), (3,'x','r');
|
|
694
|
+
|
|
695
|
+
select a, count(*) + 1 as c from sob group by a order by max(b), b;
|
|
696
|
+
-- error: Column 'b' must appear in the GROUP BY clause or be used in an aggregate function
|
|
697
|
+
|
|
698
|
+
drop table sob;
|