@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,318 @@
|
|
|
1
|
+
-- adapted from SQLite test/having.test
|
|
2
|
+
-- HAVING edge cases: predicates over aggregate results, multiple aggregates in
|
|
3
|
+
-- one expression, NULL-aware predicates, and rejection of non-grouped columns.
|
|
4
|
+
|
|
5
|
+
create table he (id integer primary key, grp text, val integer null);
|
|
6
|
+
insert into he values
|
|
7
|
+
(1, 'a', 10),
|
|
8
|
+
(2, 'a', 20),
|
|
9
|
+
(3, 'b', null),
|
|
10
|
+
(4, 'b', null),
|
|
11
|
+
(5, 'c', 30),
|
|
12
|
+
(6, 'c', 40);
|
|
13
|
+
|
|
14
|
+
-- HAVING with IS NULL on aggregate output
|
|
15
|
+
-- Group 'b' has only NULL values, so min(val) is NULL
|
|
16
|
+
select grp from he group by grp having min(val) is null order by grp;
|
|
17
|
+
→ [{"grp":"b"}]
|
|
18
|
+
|
|
19
|
+
-- HAVING with IS NOT NULL on aggregate
|
|
20
|
+
select grp from he group by grp having min(val) is not null order by grp;
|
|
21
|
+
→ [{"grp":"a"},{"grp":"c"}]
|
|
22
|
+
|
|
23
|
+
-- HAVING comparing two aggregates
|
|
24
|
+
-- For 'a': sum=30, avg=15 → sum > avg*2? 30 > 30 → false
|
|
25
|
+
-- For 'c': sum=70, avg=35 → 70 > 70 → false
|
|
26
|
+
-- (none qualify)
|
|
27
|
+
select grp from he group by grp having sum(val) > avg(val) * 2 order by grp;
|
|
28
|
+
→ []
|
|
29
|
+
|
|
30
|
+
-- HAVING comparing two aggregates with strict inequality
|
|
31
|
+
-- For 'a': sum=30 vs count(*)*5 = 10 → 30 > 10 true
|
|
32
|
+
-- For 'b': sum=NULL vs count(*)*5 = 10 → NULL>10 false
|
|
33
|
+
-- For 'c': sum=70 vs count(*)*5 = 10 → 70 > 10 true
|
|
34
|
+
select grp from he group by grp having sum(val) > count(*) * 5 order by grp;
|
|
35
|
+
→ [{"grp":"a"},{"grp":"c"}]
|
|
36
|
+
|
|
37
|
+
-- HAVING uses an aggregate alias from the SELECT list
|
|
38
|
+
select grp, sum(val) as total from he group by grp having total > 30 order by grp;
|
|
39
|
+
→ [{"grp":"c","total":70}]
|
|
40
|
+
|
|
41
|
+
-- HAVING with arithmetic on aggregates: average of squared sums per group
|
|
42
|
+
-- (a's sum=30, b's sum=NULL → treated as no contribution, c's sum=70)
|
|
43
|
+
select grp from he group by grp having sum(val) + count(*) > 35 order by grp;
|
|
44
|
+
→ [{"grp":"c"}]
|
|
45
|
+
|
|
46
|
+
-- HAVING that filters out the only candidate group
|
|
47
|
+
select grp from he group by grp having sum(val) > 1000;
|
|
48
|
+
→ []
|
|
49
|
+
|
|
50
|
+
drop table he;
|
|
51
|
+
|
|
52
|
+
-- =============================================================================
|
|
53
|
+
-- HAVING referencing a non-grouped column should be rejected
|
|
54
|
+
-- =============================================================================
|
|
55
|
+
|
|
56
|
+
create table hu (id integer primary key, grp text, val integer);
|
|
57
|
+
insert into hu values (1, 'a', 10), (2, 'a', 20);
|
|
58
|
+
|
|
59
|
+
-- HAVING referencing a non-grouped, non-aggregated column (id) is rejected.
|
|
60
|
+
select grp from hu group by grp having id > 0;
|
|
61
|
+
-- error: id
|
|
62
|
+
|
|
63
|
+
-- HAVING referencing a non-grouped column alongside an aggregate in SELECT.
|
|
64
|
+
select grp, sum(val) from hu group by grp having val > 0;
|
|
65
|
+
-- error: val
|
|
66
|
+
|
|
67
|
+
-- HAVING with a mix of grouped and ungrouped columns is rejected for the
|
|
68
|
+
-- ungrouped reference (the AND'd `grp` reference itself is fine).
|
|
69
|
+
select grp, sum(val) from hu group by grp having grp = 'a' and val > 0;
|
|
70
|
+
-- error: val
|
|
71
|
+
|
|
72
|
+
-- HAVING over the implicit single group (no GROUP BY, aggregate in SELECT)
|
|
73
|
+
-- may not reference bare columns.
|
|
74
|
+
select count(*) from hu having id > 0;
|
|
75
|
+
-- error: id
|
|
76
|
+
|
|
77
|
+
-- Positive: HAVING with an aggregate is fine.
|
|
78
|
+
select grp from hu group by grp having sum(val) > 0 order by grp;
|
|
79
|
+
→ [{"grp":"a"}]
|
|
80
|
+
|
|
81
|
+
-- Positive: HAVING with a GROUP BY column is fine.
|
|
82
|
+
select grp from hu group by grp having grp = 'a';
|
|
83
|
+
→ [{"grp":"a"}]
|
|
84
|
+
|
|
85
|
+
-- Positive: HAVING references the same expression that appears in GROUP BY
|
|
86
|
+
-- (fingerprint-match path). val=10 → 20, val=20 → 40; only `val=20` group qualifies.
|
|
87
|
+
select val * 2 as v2 from hu group by val * 2 having val * 2 > 30 order by v2;
|
|
88
|
+
→ [{"v2":40}]
|
|
89
|
+
|
|
90
|
+
drop table hu;
|
|
91
|
+
|
|
92
|
+
-- =============================================================================
|
|
93
|
+
-- HAVING with bound parameters must resolve via the parameter scope
|
|
94
|
+
-- =============================================================================
|
|
95
|
+
|
|
96
|
+
create table hp (id integer, grp text, val integer);
|
|
97
|
+
insert into hp values (1,'a',10),(2,'a',20),(3,'b',5),(4,'b',5);
|
|
98
|
+
|
|
99
|
+
-- Anonymous ? parameter in HAVING: groups with count(*) matching the bound value.
|
|
100
|
+
-- params: [2]
|
|
101
|
+
select grp from hp group by grp having count(*) = ? order by grp;
|
|
102
|
+
→ [{"grp":"a"},{"grp":"b"}]
|
|
103
|
+
|
|
104
|
+
-- Named parameter in HAVING: groups whose sum exceeds the bound threshold.
|
|
105
|
+
-- params: {"threshold":15}
|
|
106
|
+
select grp from hp group by grp having sum(val) > :threshold order by grp;
|
|
107
|
+
→ [{"grp":"a"}]
|
|
108
|
+
|
|
109
|
+
-- Anonymous ? in both WHERE and HAVING: positional indexing must span clauses.
|
|
110
|
+
-- WHERE keeps only val >= 10 (rows 1,2 → group 'a' count 2; group 'b' empty),
|
|
111
|
+
-- then HAVING count(*) = 2 selects 'a'. Mirrors the original bug-report shape.
|
|
112
|
+
-- params: [10, 2]
|
|
113
|
+
select grp from hp where val >= ? group by grp having count(*) = ? order by grp;
|
|
114
|
+
→ [{"grp":"a"}]
|
|
115
|
+
|
|
116
|
+
drop table hp;
|
|
117
|
+
|
|
118
|
+
-- =============================================================================
|
|
119
|
+
-- HAVING with NO aggregate and NO GROUP BY
|
|
120
|
+
--
|
|
121
|
+
-- Such a query is still an aggregate query: it has one implicit group over all
|
|
122
|
+
-- input rows, and HAVING filters that single group. It therefore yields at most
|
|
123
|
+
-- one row, and every clause above the aggregation is subject to the usual
|
|
124
|
+
-- coverage rule (only grouping columns — here, none — and aggregates).
|
|
125
|
+
-- Regression: the clause used to be dropped from the plan entirely, so the
|
|
126
|
+
-- query returned every input row unfiltered.
|
|
127
|
+
-- =============================================================================
|
|
128
|
+
|
|
129
|
+
create table hn (id integer primary key, grp text, val integer);
|
|
130
|
+
insert into hn values (1, 'x', 10), (2, 'y', 20), (3, 'x', 30);
|
|
131
|
+
|
|
132
|
+
create table hnempty (id integer primary key, val integer);
|
|
133
|
+
|
|
134
|
+
-- A bare column above the aggregation is rejected: the implicit group carries no
|
|
135
|
+
-- such column. The SELECT list is checked before HAVING is built, so when both name
|
|
136
|
+
-- an ungrouped column the SELECT-list message is the one raised -- same order as a
|
|
137
|
+
-- GROUP BY query, whose select list is checked at the same point.
|
|
138
|
+
select grp from hn having grp = 'x';
|
|
139
|
+
-- error: Column 'grp' must appear in the GROUP BY clause
|
|
140
|
+
|
|
141
|
+
select * from hn having grp = 'x';
|
|
142
|
+
-- error: Column 'id' must appear in the GROUP BY clause
|
|
143
|
+
|
|
144
|
+
-- ...including when the HAVING predicate itself is a constant, so the only ungrouped
|
|
145
|
+
-- reference is in the SELECT list.
|
|
146
|
+
select grp from hn having 1 = 0;
|
|
147
|
+
-- error: Column 'grp' must appear in the GROUP BY clause
|
|
148
|
+
|
|
149
|
+
select * from hn having 1 = 1;
|
|
150
|
+
-- error: Column 'id' must appear in the GROUP BY clause
|
|
151
|
+
|
|
152
|
+
-- With a select list that carries no bare column, HAVING's own check is what fires,
|
|
153
|
+
-- under its dedicated message.
|
|
154
|
+
select 1 as one from hn having grp = 'x';
|
|
155
|
+
-- error: HAVING references non-grouped column 'grp'
|
|
156
|
+
|
|
157
|
+
-- A SELECT-list alias in HAVING is not a way around the rule: it denotes the same
|
|
158
|
+
-- ungrouped column.
|
|
159
|
+
select val as v from hn having v = 10;
|
|
160
|
+
-- error: Column 'val' must appear in the GROUP BY clause
|
|
161
|
+
|
|
162
|
+
-- Constant-true predicate keeps the single implicit group.
|
|
163
|
+
select 1 as one from hn having 1 = 1;
|
|
164
|
+
→ [{"one":1}]
|
|
165
|
+
|
|
166
|
+
-- Constant-false predicate filters it out. (Before the fix this returned all
|
|
167
|
+
-- three rows of `hn`.)
|
|
168
|
+
select 1 as one from hn having 1 = 0;
|
|
169
|
+
→ []
|
|
170
|
+
|
|
171
|
+
-- The implicit group exists even over an empty table — aggregation over no rows
|
|
172
|
+
-- still produces exactly one group.
|
|
173
|
+
select 1 as one from hnempty having 1 = 1;
|
|
174
|
+
→ [{"one":1}]
|
|
175
|
+
|
|
176
|
+
select 1 as one from hnempty having 1 = 0;
|
|
177
|
+
→ []
|
|
178
|
+
|
|
179
|
+
-- A WHERE that removes every row does not remove the group either: WHERE runs below
|
|
180
|
+
-- the aggregation, so the implicit group is still formed over the (now empty) input.
|
|
181
|
+
select 1 as one from hn where val > 100 having 1 = 1;
|
|
182
|
+
→ [{"one":1}]
|
|
183
|
+
|
|
184
|
+
select 1 as one from hn where val > 15 having 1 = 1;
|
|
185
|
+
→ [{"one":1}]
|
|
186
|
+
|
|
187
|
+
-- A NULL predicate does not pass the filter, exactly as in WHERE.
|
|
188
|
+
select 1 as one from hn having null;
|
|
189
|
+
→ []
|
|
190
|
+
|
|
191
|
+
-- The shape nested as a FROM-clause subquery: the outer query sees one row or none.
|
|
192
|
+
select count(*) as c from (select 1 as one from hn having 1 = 1);
|
|
193
|
+
→ [{"c":1}]
|
|
194
|
+
|
|
195
|
+
select count(*) as c from (select 1 as one from hn having 1 = 0);
|
|
196
|
+
→ [{"c":0}]
|
|
197
|
+
|
|
198
|
+
-- ...and as an arm of a compound select.
|
|
199
|
+
select 1 as one from hn having 1 = 0 union all select 2 as one from hn having 1 = 1;
|
|
200
|
+
→ [{"one":2}]
|
|
201
|
+
|
|
202
|
+
-- ...and as the source of an INSERT.
|
|
203
|
+
create table hnsink (id integer primary key, v integer);
|
|
204
|
+
insert into hnsink (id, v) select 1, 1 from hn having 1 = 0;
|
|
205
|
+
select count(*) as c from hnsink;
|
|
206
|
+
→ [{"c":0}]
|
|
207
|
+
|
|
208
|
+
insert into hnsink (id, v) select 1, 1 from hn having 1 = 1;
|
|
209
|
+
select count(*) as c from hnsink;
|
|
210
|
+
→ [{"c":1}]
|
|
211
|
+
|
|
212
|
+
drop table hnsink;
|
|
213
|
+
|
|
214
|
+
-- A scalar subquery is a legal HAVING predicate here: it is not a bare column of
|
|
215
|
+
-- the aggregated row.
|
|
216
|
+
select 1 as one from hn having (select count(*) from hn) > 2;
|
|
217
|
+
→ [{"one":1}]
|
|
218
|
+
|
|
219
|
+
select 1 as one from hn having (select count(*) from hn) > 5;
|
|
220
|
+
→ []
|
|
221
|
+
|
|
222
|
+
-- Compositions above the aggregation: LIMIT, DISTINCT, ORDER BY.
|
|
223
|
+
select 1 as one from hn having 1 = 1 limit 1;
|
|
224
|
+
→ [{"one":1}]
|
|
225
|
+
|
|
226
|
+
select distinct 1 as one from hn having 1 = 1;
|
|
227
|
+
→ [{"one":1}]
|
|
228
|
+
|
|
229
|
+
-- ORDER BY over an ungrouped aggregate query sorts the *input* rows below the
|
|
230
|
+
-- aggregation (a documented Quereus extension), so naming `val` here is legal
|
|
231
|
+
-- and the single output row is unaffected.
|
|
232
|
+
select 1 as one from hn having 1 = 1 order by val;
|
|
233
|
+
→ [{"one":1}]
|
|
234
|
+
|
|
235
|
+
-- The same shape as a view body.
|
|
236
|
+
create view hnv as select 1 as one from hn having 1 = 1;
|
|
237
|
+
select * from hnv;
|
|
238
|
+
→ [{"one":1}]
|
|
239
|
+
|
|
240
|
+
drop view hnv;
|
|
241
|
+
|
|
242
|
+
-- A HAVING inside a subquery may reference an *enclosing* query's column, exactly
|
|
243
|
+
-- as WHERE may — that is a correlated outer reference, not an ungrouped local
|
|
244
|
+
-- column, and the coverage check must still tell the two apart when the subquery
|
|
245
|
+
-- has no aggregates at all.
|
|
246
|
+
select h.val from hn h where exists (select 1 from hn t having h.grp = 'x') order by h.val;
|
|
247
|
+
→ [{"val":10},{"val":30}]
|
|
248
|
+
|
|
249
|
+
-- A window function over the implicit group runs over the *aggregated* row, not the
|
|
250
|
+
-- input rows: there is exactly one, so `count(*) over ()` is 1. (Before the fix this
|
|
251
|
+
-- ran over all three input rows and returned 3, three times.)
|
|
252
|
+
select count(*) over () as c from hn having 1 = 1;
|
|
253
|
+
→ [{"c":1}]
|
|
254
|
+
|
|
255
|
+
-- ORDER BY by output ordinal and by select-list alias both resolve above the single
|
|
256
|
+
-- aggregated row. (Before the fix each returned three rows.)
|
|
257
|
+
select 1 as one from hn having 1 = 1 order by 1;
|
|
258
|
+
→ [{"one":1}]
|
|
259
|
+
|
|
260
|
+
select 1 as one from hn having 1 = 1 order by one;
|
|
261
|
+
→ [{"one":1}]
|
|
262
|
+
|
|
263
|
+
-- An ORDER BY may also name an AGGREGATE here. A HAVING makes this an aggregate
|
|
264
|
+
-- query on its own, so `count(*)` is legal in its ORDER BY exactly as it is in the
|
|
265
|
+
-- ORDER BY of a query that names an aggregate in its SELECT list -- the aggregate
|
|
266
|
+
-- is collected into the AggregateNode for the post-aggregate sort and stripped by
|
|
267
|
+
-- the final projection. (Before the fix, both the collection step and applyOrderBy
|
|
268
|
+
-- asked "does this query name an aggregate?" instead of "is this an aggregate
|
|
269
|
+
-- query?", so the aggregate was never collected and the sort key was rejected with
|
|
270
|
+
-- "Aggregate function count not allowed in this context".)
|
|
271
|
+
select 1 as one from hn having 1 = 1 order by count(*);
|
|
272
|
+
→ [{"one":1}]
|
|
273
|
+
|
|
274
|
+
-- ...with more than one sort-only aggregate, and one of a different function.
|
|
275
|
+
select 1 as one from hn having 1 = 1 order by count(*), max(val);
|
|
276
|
+
→ [{"one":1}]
|
|
277
|
+
|
|
278
|
+
-- ...and mixed with the select-list alias, which resolves on the final projection
|
|
279
|
+
-- while the aggregates resolve on the AggregateNode below it.
|
|
280
|
+
select 1 as one from hn having 1 = 1 order by count(*), one;
|
|
281
|
+
→ [{"one":1}]
|
|
282
|
+
|
|
283
|
+
-- A HAVING that names an aggregate beside a column-free select list. The select
|
|
284
|
+
-- list carries no base-table column, so nothing is uncovered and the query is a
|
|
285
|
+
-- plain aggregate query whose single implicit group the predicate filters.
|
|
286
|
+
select 1 as one from hn having count(*) > 1;
|
|
287
|
+
→ [{"one":1}]
|
|
288
|
+
|
|
289
|
+
select 1 as one from hn having count(*) > 5;
|
|
290
|
+
→ []
|
|
291
|
+
|
|
292
|
+
select 'label' as k from hn having count(*) > 1 order by count(*);
|
|
293
|
+
→ [{"k":"label"}]
|
|
294
|
+
|
|
295
|
+
-- ...and the same over an empty table, where the implicit group still exists but
|
|
296
|
+
-- its count is 0.
|
|
297
|
+
select 1 as one from hnempty having count(*) > 0;
|
|
298
|
+
→ []
|
|
299
|
+
|
|
300
|
+
select 1 as one from hnempty having count(*) = 0;
|
|
301
|
+
→ [{"one":1}]
|
|
302
|
+
|
|
303
|
+
-- Regression guards: adding an aggregate or a GROUP BY must not change any of the
|
|
304
|
+
-- long-standing behaviour.
|
|
305
|
+
select count(*) as c from hn having count(*) > 5;
|
|
306
|
+
→ []
|
|
307
|
+
|
|
308
|
+
select count(*) as c from hn having count(*) > 1;
|
|
309
|
+
→ [{"c":3}]
|
|
310
|
+
|
|
311
|
+
select grp, count(*) as c from hn group by grp having grp = 'x';
|
|
312
|
+
→ [{"grp":"x","c":2}]
|
|
313
|
+
|
|
314
|
+
select count(*) as c from hn where grp = 'x' having count(*) > 1;
|
|
315
|
+
→ [{"c":2}]
|
|
316
|
+
|
|
317
|
+
drop table hn;
|
|
318
|
+
drop table hnempty;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
-- adapted from SQLite test/notnull2.test
|
|
2
|
+
-- IS NULL / IS NOT NULL evaluated under an aggregate over an empty NOT NULL
|
|
3
|
+
-- table. SQLite allows a bare column beside an aggregate without GROUP BY (its
|
|
4
|
+
-- "bare aggregate" mode, where the non-aggregate columns yield NULL on empty
|
|
5
|
+
-- input). Quereus rejects it by design: an ungrouped aggregate query has one
|
|
6
|
+
-- implicit group, which carries no base-table column, so `a` here is exactly as
|
|
7
|
+
-- uncovered as it would be under a GROUP BY that omits it -- and gets the same
|
|
8
|
+
-- message. A select-list item that references no column at all IS accepted
|
|
9
|
+
-- beside an aggregate; see 25.5. `a is null` is not one of those.
|
|
10
|
+
|
|
11
|
+
create table ag_t (a integer primary key, b text);
|
|
12
|
+
|
|
13
|
+
select a is null as a_is_null, a is not null as a_is_not_null, count(*) as n from ag_t;
|
|
14
|
+
-- error: Column 'a' must appear in the GROUP BY clause or be used in an aggregate function
|
|
15
|
+
|
|
16
|
+
drop table ag_t;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
-- 25.4-groupby-fd-constant-empty.sqllogic
|
|
2
|
+
-- Regression: ruleGroupByFdSimplification must never drop *every* GROUP BY
|
|
3
|
+
-- column. When all group columns are equality-pinned to constants
|
|
4
|
+
-- (`where a = 0 and k = 6`), FD propagation gives each an empty-determinant FD
|
|
5
|
+
-- (`{} -> col`), minimalCover drains the cover, and the rule used to rebuild the
|
|
6
|
+
-- aggregate with an empty GROUP BY (a scalar aggregate). A scalar aggregate
|
|
7
|
+
-- emits one all-NULL `count=0` row over an empty input; a grouped query must
|
|
8
|
+
-- emit ZERO rows. Target: rule-groupby-fd-simplification.ts.
|
|
9
|
+
|
|
10
|
+
create table t (id integer primary key, a integer, b integer, k integer);
|
|
11
|
+
insert into t values (2, 3, 4, 2), (3, 7, 1, 9);
|
|
12
|
+
|
|
13
|
+
-- Multi-column, constant-pinned, EMPTY match -> [] (the regression).
|
|
14
|
+
-- Pre-fix this returned [{"a":null,"k":null,"c":0,"s":null}].
|
|
15
|
+
select a, k, count(*) as c, sum(b) as s from t where a = 0 and k = 6 group by a, k;
|
|
16
|
+
→ []
|
|
17
|
+
|
|
18
|
+
-- Multi-column, constant-pinned, NON-EMPTY match -> exactly one group row.
|
|
19
|
+
-- Row id=3 (a=7, b=1, k=9) is the only match. Confirms the bail leaves the
|
|
20
|
+
-- non-empty result correct.
|
|
21
|
+
select a, k, count(*) as c, sum(b) as s from t where a = 7 and k = 9 group by a, k;
|
|
22
|
+
→ [{"a":7,"k":9,"c":1,"s":1}]
|
|
23
|
+
|
|
24
|
+
-- Single-column control, EMPTY match -> [] (must stay correct; rule never fires
|
|
25
|
+
-- for a one-column GROUP BY because of the `groupBy.length <= 1` early return).
|
|
26
|
+
select k, count(*) as c, sum(a) as s from t where k = 6 group by k;
|
|
27
|
+
→ []
|
|
28
|
+
|
|
29
|
+
-- Mixed: one constant-pinned column (`a`, dropped via the `{} -> a` FD and
|
|
30
|
+
-- re-emitted as MIN(a)) plus one free column (`b`, kept as the surviving group
|
|
31
|
+
-- key). Confirmed by plan dump to rewrite to `group by b -> min(a), count(*)`.
|
|
32
|
+
-- Over an EMPTY match (`a = 0` matches no row) the surviving key still gates row
|
|
33
|
+
-- production, so the result is zero rows — the partial-drop path must not
|
|
34
|
+
-- resurrect the spurious-row bug.
|
|
35
|
+
select a, b, count(*) as c from t where a = 0 group by a, b;
|
|
36
|
+
→ []
|
|
37
|
+
|
|
38
|
+
drop table t;
|
|
39
|
+
|
|
40
|
+
-- Partial-drop coverage: the guard must only trigger when ALL grouping columns
|
|
41
|
+
-- would be dropped. Here `name` is functionally determined by the primary key
|
|
42
|
+
-- `id`, so the rule legitimately drops `name` (re-emitting MIN(name)) while
|
|
43
|
+
-- KEEPING `id` as the surviving group key.
|
|
44
|
+
create table u (id integer primary key, name text, dept text);
|
|
45
|
+
insert into u values (1, 'alice', 'eng'), (2, 'bob', 'sales');
|
|
46
|
+
|
|
47
|
+
select id, name, count(*) as c from u group by id, name order by id;
|
|
48
|
+
→ [{"id":1,"name":"alice","c":1},{"id":2,"name":"bob","c":1}]
|
|
49
|
+
|
|
50
|
+
-- Same FD-simplifiable shape over an EMPTY match still yields zero rows: a
|
|
51
|
+
-- surviving key (`id`) gates row production, so no spurious row appears.
|
|
52
|
+
select id, name, count(*) as c from u where id = 99 group by id, name;
|
|
53
|
+
→ []
|
|
54
|
+
|
|
55
|
+
drop table u;
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
-- =============================================================================
|
|
2
|
+
-- An ungrouped aggregate query (aggregates in the SELECT list, no GROUP BY) has
|
|
3
|
+
-- exactly ONE implicit group over all input rows. That group's row carries the
|
|
4
|
+
-- aggregate results and nothing else -- no base-table column.
|
|
5
|
+
--
|
|
6
|
+
-- So the rule the SELECT list is checked against is "does this item reference a
|
|
7
|
+
-- column of the query's input?", NOT "is this item an aggregate?":
|
|
8
|
+
--
|
|
9
|
+
-- * a column-free item -- a literal, an expression over literals, a call whose
|
|
10
|
+
-- arguments are column-free, a `case` over aggregates, a scalar subquery --
|
|
11
|
+
-- references nothing the implicit group lacks, and is ACCEPTED. That is
|
|
12
|
+
-- standard SQL and what SQLite and PostgreSQL do.
|
|
13
|
+
-- * a bare column reference is REJECTED, with the same message and source
|
|
14
|
+
-- position a GROUP BY query gets when it omits the column. Quereus
|
|
15
|
+
-- deliberately does not import SQLite's permissive "bare columns" rule,
|
|
16
|
+
-- which picks an arbitrary row of the group.
|
|
17
|
+
--
|
|
18
|
+
-- Regression: every accepted query below used to fail with "Cannot mix aggregate
|
|
19
|
+
-- and non-aggregate columns in SELECT list without GROUP BY", a blanket throw
|
|
20
|
+
-- that never asked whether the item named a column.
|
|
21
|
+
-- =============================================================================
|
|
22
|
+
|
|
23
|
+
create table uac (id integer primary key, a text, n integer);
|
|
24
|
+
insert into uac values (1, 'x', 10), (2, 'y', 20);
|
|
25
|
+
|
|
26
|
+
create table uacempty (id integer primary key, a text);
|
|
27
|
+
|
|
28
|
+
-- --- Accepted: column-free items beside an aggregate.
|
|
29
|
+
|
|
30
|
+
-- a string literal
|
|
31
|
+
select 'total' as label, count(*) as c from uac;
|
|
32
|
+
→ [{"label":"total","c":2}]
|
|
33
|
+
|
|
34
|
+
-- an integer literal
|
|
35
|
+
select 1 as one, count(*) as c from uac;
|
|
36
|
+
→ [{"one":1,"c":2}]
|
|
37
|
+
|
|
38
|
+
-- an expression over literals only
|
|
39
|
+
select 1 + 1 as two, count(*) as c from uac;
|
|
40
|
+
→ [{"two":2,"c":2}]
|
|
41
|
+
|
|
42
|
+
-- a function call whose arguments are column-free
|
|
43
|
+
select abs(-1) as k, count(*) as c from uac;
|
|
44
|
+
→ [{"k":1,"c":2}]
|
|
45
|
+
|
|
46
|
+
-- NULL is column-free too
|
|
47
|
+
select null as z, count(*) as c from uac;
|
|
48
|
+
→ [{"z":null,"c":2}]
|
|
49
|
+
|
|
50
|
+
-- a cast over a literal
|
|
51
|
+
select cast(1 as text) as k, count(*) as c from uac;
|
|
52
|
+
→ [{"k":"1","c":2}]
|
|
53
|
+
|
|
54
|
+
-- an IN list over literals
|
|
55
|
+
select 1 in (1, 2) as k, count(*) as c from uac;
|
|
56
|
+
→ [{"k":true,"c":2}]
|
|
57
|
+
|
|
58
|
+
-- a COLLATE over a literal
|
|
59
|
+
select 'a' collate binary as k, count(*) as c from uac;
|
|
60
|
+
→ [{"k":"a","c":2}]
|
|
61
|
+
|
|
62
|
+
-- more than one column-free item, and the aggregate not written first
|
|
63
|
+
select count(*) as c, 'a' as x, 'b' as y from uac;
|
|
64
|
+
→ [{"c":2,"x":"a","y":"b"}]
|
|
65
|
+
|
|
66
|
+
-- several aggregates alongside
|
|
67
|
+
select 'summary' as label, count(*) as c, sum(n) as s, max(a) as m from uac;
|
|
68
|
+
→ [{"label":"summary","c":2,"s":30,"m":"y"}]
|
|
69
|
+
|
|
70
|
+
-- --- Accepted: items that read the AGGREGATE results rather than input columns.
|
|
71
|
+
|
|
72
|
+
-- a `case` over an aggregate
|
|
73
|
+
select case when count(*) > 1 then 'many' else 'few' end as k, count(*) as c from uac;
|
|
74
|
+
→ [{"k":"many","c":2}]
|
|
75
|
+
|
|
76
|
+
-- an arithmetic expression over an aggregate
|
|
77
|
+
select count(*) * 10 as k, count(*) as c from uac;
|
|
78
|
+
→ [{"k":20,"c":2}]
|
|
79
|
+
|
|
80
|
+
-- --- Accepted: a scalar subquery is a relational subtree that resolves its own
|
|
81
|
+
-- --- scope, so it references no column of THIS query's input.
|
|
82
|
+
|
|
83
|
+
select (select count(*) from uac) as sub, count(*) as c from uac;
|
|
84
|
+
→ [{"sub":2,"c":2}]
|
|
85
|
+
|
|
86
|
+
-- a correlated-looking subquery that is in fact uncorrelated
|
|
87
|
+
select (select max(n) from uac) as sub, sum(n) as s from uac;
|
|
88
|
+
→ [{"sub":20,"s":30}]
|
|
89
|
+
|
|
90
|
+
-- ...but a GENUINELY correlated subquery, one that reads an ungrouped column of
|
|
91
|
+
-- THIS query, is rejected. The select-list walk stops at every relational child,
|
|
92
|
+
-- so it does not catch this; the finished-plan check (assertGroupedPlanCoverage)
|
|
93
|
+
-- is the one that does, and it reports the same message. This is the seam between
|
|
94
|
+
-- "the walk skipped it" and "the item is truly column-free", and the two must not
|
|
95
|
+
-- be confused.
|
|
96
|
+
select (select count(*) from uac t where t.a = uac.a) as sub, count(*) as c from uac;
|
|
97
|
+
-- error: Column 'uac.a' must appear in the GROUP BY clause or be used in an aggregate function
|
|
98
|
+
|
|
99
|
+
select (select count(*) from uac t where t.n > uac.n) as sub, count(*) as c from uac;
|
|
100
|
+
-- error: Column 'uac.n' must appear in the GROUP BY clause or be used in an aggregate function
|
|
101
|
+
|
|
102
|
+
-- --- KNOWN DIVERGENCE: a reference to an ENCLOSING query's column is constant
|
|
103
|
+
-- --- with respect to this query's implicit group, so it should be accepted here
|
|
104
|
+
-- --- exactly as it is in `having` (see 25.2) and in `where`. It is not: the
|
|
105
|
+
-- --- select-list walk flags any column reference its coverage set lacks, with no
|
|
106
|
+
-- --- notion of which query the reference belongs to, so an outer reference is
|
|
107
|
+
-- --- rejected as though it were an uncovered column of this query. SQLite accepts
|
|
108
|
+
-- --- both queries below (the first yields `x`, `y`). Tracked as
|
|
109
|
+
-- --- backlog/bug-outer-column-rejected-in-aggregate-select-list; these pins flip
|
|
110
|
+
-- --- from `-- error:` to result rows when it lands. Not a regression -- the old
|
|
111
|
+
-- --- blanket mixing throw rejected the ungrouped form too, and the GROUPED form
|
|
112
|
+
-- --- (second query) has always been rejected.
|
|
113
|
+
|
|
114
|
+
select a from uac where exists (select uac.a, count(*) from uac t);
|
|
115
|
+
-- error: Column 'uac.a' must appear in the GROUP BY clause or be used in an aggregate function
|
|
116
|
+
|
|
117
|
+
select a from uac where exists (select uac.a, count(*) from uac t group by t.a);
|
|
118
|
+
-- error: Column 'uac.a' must appear in the GROUP BY clause or be used in an aggregate function
|
|
119
|
+
|
|
120
|
+
-- --- Accepted: the column-free item survives the clauses that sit above the
|
|
121
|
+
-- --- aggregation.
|
|
122
|
+
|
|
123
|
+
select distinct 'k' as label, count(*) as c from uac;
|
|
124
|
+
→ [{"label":"k","c":2}]
|
|
125
|
+
|
|
126
|
+
select 'k' as label, count(*) as c from uac limit 1;
|
|
127
|
+
→ [{"label":"k","c":2}]
|
|
128
|
+
|
|
129
|
+
select 'k' as label, count(*) as c from uac limit 0;
|
|
130
|
+
→ []
|
|
131
|
+
|
|
132
|
+
select 'k' as label, count(*) as c from uac order by count(*);
|
|
133
|
+
→ [{"label":"k","c":2}]
|
|
134
|
+
|
|
135
|
+
select 'k' as label, count(*) as c from uac having count(*) > 1;
|
|
136
|
+
→ [{"label":"k","c":2}]
|
|
137
|
+
|
|
138
|
+
select 'k' as label, count(*) as c from uac having count(*) > 5;
|
|
139
|
+
→ []
|
|
140
|
+
|
|
141
|
+
-- --- Accepted: over an empty table the implicit group still exists, so the
|
|
142
|
+
-- --- column-free item is emitted beside a zero count.
|
|
143
|
+
|
|
144
|
+
select 'total' as label, count(*) as c from uacempty;
|
|
145
|
+
→ [{"label":"total","c":0}]
|
|
146
|
+
|
|
147
|
+
-- --- Accepted: nested spellings, where another ProjectNode wraps the query.
|
|
148
|
+
|
|
149
|
+
select * from (select 'k' as label, count(*) as c from uac);
|
|
150
|
+
→ [{"label":"k","c":2}]
|
|
151
|
+
|
|
152
|
+
-- ...and as an arm of a compound select.
|
|
153
|
+
select 'k' as label, count(*) as c from uac union all select 'j', count(*) from uac;
|
|
154
|
+
→ [{"label":"k","c":2},{"label":"j","c":2}]
|
|
155
|
+
|
|
156
|
+
-- --- REJECTED: a bare column reference. This is the distinction the check makes,
|
|
157
|
+
-- --- and it must keep failing -- with the GROUP BY coverage message and the
|
|
158
|
+
-- --- offending column's own source position, not a generic mixing complaint.
|
|
159
|
+
|
|
160
|
+
select a, count(*) as c from uac;
|
|
161
|
+
-- error: Column 'a' must appear in the GROUP BY clause or be used in an aggregate function
|
|
162
|
+
|
|
163
|
+
-- the column need not be written first
|
|
164
|
+
select count(*) as c, a from uac;
|
|
165
|
+
-- error: Column 'a' must appear in the GROUP BY clause or be used in an aggregate function
|
|
166
|
+
|
|
167
|
+
-- a column buried inside an otherwise column-free expression is still a column
|
|
168
|
+
select 'p' || a as k, count(*) as c from uac;
|
|
169
|
+
-- error: Column 'a' must appear in the GROUP BY clause or be used in an aggregate function
|
|
170
|
+
|
|
171
|
+
-- ...including under a function call
|
|
172
|
+
select length(a) as k, count(*) as c from uac;
|
|
173
|
+
-- error: Column 'a' must appear in the GROUP BY clause or be used in an aggregate function
|
|
174
|
+
|
|
175
|
+
-- ...and inside a `case`
|
|
176
|
+
select case when n > 1 then 'big' else 'small' end as k, count(*) as c from uac;
|
|
177
|
+
-- error: Column 'n' must appear in the GROUP BY clause or be used in an aggregate function
|
|
178
|
+
|
|
179
|
+
-- a qualified spelling is the same column (the message echoes the spelling the
|
|
180
|
+
-- user wrote, so it names `uac.a` here)
|
|
181
|
+
select uac.a, count(*) as c from uac;
|
|
182
|
+
-- error: Column 'uac.a' must appear in the GROUP BY clause or be used in an aggregate function
|
|
183
|
+
|
|
184
|
+
-- `select *` beside an aggregate expands to bare columns and is rejected on the
|
|
185
|
+
-- first of them
|
|
186
|
+
select *, count(*) as c from uac;
|
|
187
|
+
-- error: Column 'id' must appear in the GROUP BY clause or be used in an aggregate function
|
|
188
|
+
|
|
189
|
+
-- --- Non-regression: adding the GROUP BY that covers the column accepts it, and
|
|
190
|
+
-- --- the column-free item rides along unchanged.
|
|
191
|
+
|
|
192
|
+
select 'k' as label, a, count(*) as c from uac group by a order by a;
|
|
193
|
+
→ [{"label":"k","a":"x","c":1},{"label":"k","a":"y","c":1}]
|
|
194
|
+
|
|
195
|
+
drop table uac;
|
|
196
|
+
drop table uacempty;
|