@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,244 @@
|
|
|
1
|
+
-- 03.6.1-numeric-text-comparison-coercion.sqllogic
|
|
2
|
+
-- Regression coverage for bug-numeric-text-coercion-skips-in-and-case:
|
|
3
|
+
-- `insertCrossTypeCoercion` (planner/building/coercion.ts) casts the textual side
|
|
4
|
+
-- of a numeric-vs-textual comparison so `int_col = '1'` reads as `int_col = 1`.
|
|
5
|
+
-- That rule used to apply only at the `=`/BETWEEN build sites; `IN` value lists,
|
|
6
|
+
-- simple CASE, nullif/greatest/least, the IN-subquery runtime path
|
|
7
|
+
-- (`inMembershipKeys`, runtime/emit/subquery.ts) and both IN decorrelation
|
|
8
|
+
-- rewrites (rule-subquery-decorrelation.ts) skipped it, so the SAME comparison
|
|
9
|
+
-- answered differently depending on how it was spelled. This file pins every
|
|
10
|
+
-- form agreeing with each other over an INTEGER column, a REAL column and a
|
|
11
|
+
-- TEXT column.
|
|
12
|
+
--
|
|
13
|
+
-- Section 6 pins the follow-on rule from
|
|
14
|
+
-- bug-comparison-coercion-corrupts-returned-value: the three builtins that RETURN
|
|
15
|
+
-- one of their arguments convert only a copy for the comparison, so the value
|
|
16
|
+
-- handed back is the argument as written.
|
|
17
|
+
|
|
18
|
+
create table nn (id integer primary key, i integer, r real);
|
|
19
|
+
insert into nn values (1, 1, 2.5);
|
|
20
|
+
-- run
|
|
21
|
+
|
|
22
|
+
create table tt (id integer primary key, t text);
|
|
23
|
+
insert into tt values (1, '1');
|
|
24
|
+
-- run
|
|
25
|
+
|
|
26
|
+
-- ===================================
|
|
27
|
+
-- 1. INTEGER column `i` (value 1) against textual operands — every form agrees
|
|
28
|
+
-- ===================================
|
|
29
|
+
select (i = '1') as v from nn;
|
|
30
|
+
→ [{"v":true}]
|
|
31
|
+
|
|
32
|
+
select (i between '0' and '2') as v from nn;
|
|
33
|
+
→ [{"v":true}]
|
|
34
|
+
|
|
35
|
+
select i in ('1') as v from nn;
|
|
36
|
+
→ [{"v":true}]
|
|
37
|
+
|
|
38
|
+
select i in (select t from tt) as v from nn;
|
|
39
|
+
→ [{"v":true}]
|
|
40
|
+
|
|
41
|
+
select case i when '1' then 'hit' else 'miss' end as v from nn;
|
|
42
|
+
→ [{"v":"hit"}]
|
|
43
|
+
|
|
44
|
+
select nullif(i, '1') as v from nn;
|
|
45
|
+
→ [{"v":null}]
|
|
46
|
+
|
|
47
|
+
-- `greatest`/`least`/`nullif` compare CONVERTED copies but return the ORIGINAL
|
|
48
|
+
-- argument, so the winner here is the text '2' the user wrote, not the INTEGER 2
|
|
49
|
+
-- the conversion produced. Section 6 pins that rule on its own; here the point is
|
|
50
|
+
-- that the comparison still ranks '2' above the integer 1.
|
|
51
|
+
select greatest(i, '2') as v from nn;
|
|
52
|
+
→ [{"v":"2"}]
|
|
53
|
+
|
|
54
|
+
-- `least` is unaffected here (1 is already the smaller value either way) — kept
|
|
55
|
+
-- as a control that the coercion did not change an already-correct answer.
|
|
56
|
+
select least(i, '2') as v from nn;
|
|
57
|
+
→ [{"v":1}]
|
|
58
|
+
|
|
59
|
+
-- An INTEGER column against fractional text: the text side converts to NUMERIC
|
|
60
|
+
-- (its full numeric value, 1.9), NOT to INTEGER — the prefix parse (`cast('1.9'
|
|
61
|
+
-- as integer)` is 1) used to decide these comparisons and made `i = '1.9'` true
|
|
62
|
+
-- for i = 1. Every form agrees on the numeric reading.
|
|
63
|
+
select (i = '1.9') as v from nn;
|
|
64
|
+
→ [{"v":false}]
|
|
65
|
+
|
|
66
|
+
select i in ('1.9') as v from nn;
|
|
67
|
+
→ [{"v":false}]
|
|
68
|
+
|
|
69
|
+
select case i when '1.9' then 'hit' else 'miss' end as v from nn;
|
|
70
|
+
→ [{"v":"miss"}]
|
|
71
|
+
|
|
72
|
+
-- ===================================
|
|
73
|
+
-- 2. REAL column `r` (value 2.5) against textual operands
|
|
74
|
+
-- ===================================
|
|
75
|
+
select (r = '2.5') as v from nn;
|
|
76
|
+
→ [{"v":true}]
|
|
77
|
+
|
|
78
|
+
select (r between '2' and '3') as v from nn;
|
|
79
|
+
→ [{"v":true}]
|
|
80
|
+
|
|
81
|
+
select r in ('2.5') as v from nn;
|
|
82
|
+
→ [{"v":true}]
|
|
83
|
+
|
|
84
|
+
select case r when '2.5' then 'hit' else 'miss' end as v from nn;
|
|
85
|
+
→ [{"v":"hit"}]
|
|
86
|
+
|
|
87
|
+
-- ===================================
|
|
88
|
+
-- 3. TEXT column `t` (value '1') against numeric operands — the reverse pairing
|
|
89
|
+
-- ===================================
|
|
90
|
+
select (t = 1) as v from tt;
|
|
91
|
+
→ [{"v":true}]
|
|
92
|
+
|
|
93
|
+
select (t between 0 and 2) as v from tt;
|
|
94
|
+
→ [{"v":true}]
|
|
95
|
+
|
|
96
|
+
select t in (1) as v from tt;
|
|
97
|
+
→ [{"v":true}]
|
|
98
|
+
|
|
99
|
+
select t in (select i from nn) as v from tt;
|
|
100
|
+
→ [{"v":true}]
|
|
101
|
+
|
|
102
|
+
select case t when 1 then 'hit' else 'miss' end as v from tt;
|
|
103
|
+
→ [{"v":"hit"}]
|
|
104
|
+
|
|
105
|
+
-- A NULL member does not defeat the hoisted probe cast (it is filtered out of the
|
|
106
|
+
-- all-numeric test), and the three-valued result still holds: a hit is true, a
|
|
107
|
+
-- miss over a list containing NULL is NULL rather than false.
|
|
108
|
+
select t in (1, null) as v from tt;
|
|
109
|
+
→ [{"v":true}]
|
|
110
|
+
|
|
111
|
+
select t in (9, null) as v from tt;
|
|
112
|
+
→ [{"v":null}]
|
|
113
|
+
|
|
114
|
+
select t not in (0, 2) as v from tt;
|
|
115
|
+
→ [{"v":true}]
|
|
116
|
+
|
|
117
|
+
select t not in (1, 2) as v from tt;
|
|
118
|
+
→ [{"v":false}]
|
|
119
|
+
|
|
120
|
+
-- Mixed INTEGER/REAL member list widens the hoisted probe cast to NUMERIC rather
|
|
121
|
+
-- than picking a lossy winner, so a textual '1' still matches the integer member.
|
|
122
|
+
select t in (1, 2.5) as v from tt;
|
|
123
|
+
→ [{"v":true}]
|
|
124
|
+
|
|
125
|
+
-- ===================================
|
|
126
|
+
-- 4. Negative controls — must NOT change, and are the things a future
|
|
127
|
+
-- "simplification" of the coercion would most likely break
|
|
128
|
+
-- ===================================
|
|
129
|
+
|
|
130
|
+
-- A non-numeric textual value never matches, in any form.
|
|
131
|
+
select i in ('abc') as v from nn;
|
|
132
|
+
→ [{"v":false}]
|
|
133
|
+
|
|
134
|
+
-- IN with a NULL member stays three-valued: NULL, not false.
|
|
135
|
+
select i in (null) as v from nn;
|
|
136
|
+
→ [{"v":null}]
|
|
137
|
+
|
|
138
|
+
-- NOT IN is the plain complement over a NULL-free list.
|
|
139
|
+
select i not in ('2') as v from nn;
|
|
140
|
+
→ [{"v":true}]
|
|
141
|
+
|
|
142
|
+
-- Mixed-WHEN simple CASE: `i` is numeric, so each WHEN casts independently —
|
|
143
|
+
-- this is the per-value path, not the hoisted-probe one, and is not the gap
|
|
144
|
+
-- below. (The parser requires a THEN per WHEN, so `when '1' when 2` is a
|
|
145
|
+
-- syntax error, not a shape to test.)
|
|
146
|
+
select case i when 'abc' then 'a' when '1' then 'b' else 'c' end as v from nn;
|
|
147
|
+
→ [{"v":"b"}]
|
|
148
|
+
|
|
149
|
+
-- ===================================
|
|
150
|
+
-- 5. The one remaining known gap: a TEXTUAL probe against a value list mixing
|
|
151
|
+
-- numeric and textual values. `coerceComparisonSet` deliberately declines to
|
|
152
|
+
-- hoist a probe cast over a MIXED list — `cast('abc' as real)` is 0, so
|
|
153
|
+
-- hoisting would make `s in (1, 'abc')` true for a stored '0'. The trade is a
|
|
154
|
+
-- visible disagreement with the `=` disjunction on the numeric member; see
|
|
155
|
+
-- the NOTE on `coerceComparisonSet` (planner/building/coercion.ts) and
|
|
156
|
+
-- docs/types.md "Type Coercion in Comparisons" for why closing it needs a
|
|
157
|
+
-- per-value probe that IN cannot express.
|
|
158
|
+
-- ===================================
|
|
159
|
+
create table nc_mix (id integer primary key, s text);
|
|
160
|
+
insert into nc_mix values (1, '0'), (2, '1');
|
|
161
|
+
-- run
|
|
162
|
+
|
|
163
|
+
-- Stored '0': IN and the `=` disjunction agree (both false) — this one is fine.
|
|
164
|
+
select s in (1, 'abc') as v from nc_mix where id = 1;
|
|
165
|
+
→ [{"v":false}]
|
|
166
|
+
|
|
167
|
+
select (s = 1 or s = 'abc') as v from nc_mix where id = 1;
|
|
168
|
+
→ [{"v":false}]
|
|
169
|
+
|
|
170
|
+
-- Stored '1': THIS is where the gap is visible. `s in (1, 'abc')` stays
|
|
171
|
+
-- uncoerced (false), but `s = 1 or s = 'abc'` reconciles the pairwise `=` and
|
|
172
|
+
-- matches (true). Pinned deliberately as a known, documented divergence —
|
|
173
|
+
-- not a typo.
|
|
174
|
+
select s in (1, 'abc') as v from nc_mix where id = 2;
|
|
175
|
+
→ [{"v":false}]
|
|
176
|
+
|
|
177
|
+
select (s = 1 or s = 'abc') as v from nc_mix where id = 2;
|
|
178
|
+
→ [{"v":true}]
|
|
179
|
+
|
|
180
|
+
-- ===================================
|
|
181
|
+
-- 6. Comparison answers unchanged, RETURNED values original
|
|
182
|
+
-- (bug-comparison-coercion-corrupts-returned-value)
|
|
183
|
+
--
|
|
184
|
+
-- `nullif`, `greatest` and `least` each return one of their arguments. The
|
|
185
|
+
-- coercion above used to REPLACE that argument with its cast, so the cast's
|
|
186
|
+
-- output was what came back: `greatest(t, 1)` handed back the integer 3 for the
|
|
187
|
+
-- stored text '3', and `least('abc', 1)` handed back 0 — a value that was never
|
|
188
|
+
-- an argument at all (`cast('abc' as integer)` is 0). Those three now coerce
|
|
189
|
+
-- comparison KEYS at emit time (`makeComparisonGroup`,
|
|
190
|
+
-- runtime/emit/operand-comparator.ts) and return the raw argument.
|
|
191
|
+
-- ===================================
|
|
192
|
+
|
|
193
|
+
create table t3 (id integer primary key, s text);
|
|
194
|
+
insert into t3 values (1, '3');
|
|
195
|
+
-- run
|
|
196
|
+
|
|
197
|
+
-- The returned value is the argument as written, storage class included.
|
|
198
|
+
select nullif('3', 1) as v, typeof(nullif('3', 1)) as t;
|
|
199
|
+
→ [{"v":"3","t":"text"}]
|
|
200
|
+
|
|
201
|
+
select nullif(s, 1) as v, typeof(nullif(s, 1)) as ty from t3;
|
|
202
|
+
→ [{"v":"3","ty":"text"}]
|
|
203
|
+
|
|
204
|
+
-- A non-numeric text argument: the comparison converts it to 0 and so does not
|
|
205
|
+
-- match 1, but 0 must never be the RESULT.
|
|
206
|
+
select nullif('abc', 1) as v;
|
|
207
|
+
→ [{"v":"abc"}]
|
|
208
|
+
|
|
209
|
+
-- Regression guard against over-correcting: the comparison itself must still
|
|
210
|
+
-- coerce, so a matching numeric text still nulls out — and '1.9' reads as the
|
|
211
|
+
-- NUMERIC 1.9 (no INTEGER truncation), so it does NOT match i = 1, exactly as
|
|
212
|
+
-- `i = '1.9'` answers false in section 1.
|
|
213
|
+
select nullif(i, '1') as a, nullif(i, '1.9') as b from nn;
|
|
214
|
+
→ [{"a":null,"b":1}]
|
|
215
|
+
|
|
216
|
+
-- Both orientations of the mixed pair. Argument order decides which side carries
|
|
217
|
+
-- the conversion (probe cast vs value cast), so both must be covered; either way
|
|
218
|
+
-- the result is one of the arguments, never 0.
|
|
219
|
+
select least('abc', 1) as v, typeof(least('abc', 1)) as t;
|
|
220
|
+
→ [{"v":"abc","t":"text"}]
|
|
221
|
+
|
|
222
|
+
select least(1, 'abc') as v, typeof(least(1, 'abc')) as t;
|
|
223
|
+
→ [{"v":"abc","t":"text"}]
|
|
224
|
+
|
|
225
|
+
-- The comparison still picks the numerically larger/smaller argument across the
|
|
226
|
+
-- category boundary — it is only the returned spelling that changed.
|
|
227
|
+
select greatest(1, '2') as g, typeof(greatest(1, '2')) as gt;
|
|
228
|
+
→ [{"g":"2","gt":"text"}]
|
|
229
|
+
|
|
230
|
+
select least(1, '2') as l, typeof(least(1, '2')) as lt;
|
|
231
|
+
→ [{"l":1,"lt":"integer"}]
|
|
232
|
+
|
|
233
|
+
-- A TEXT column on the probe side, the shape from the bug report.
|
|
234
|
+
select greatest(s, 1) as g, typeof(greatest(s, 1)) as gt from t3;
|
|
235
|
+
→ [{"g":"3","gt":"text"}]
|
|
236
|
+
|
|
237
|
+
-- Control: `coalesce` picks by nullness, not by comparison, so it declares no
|
|
238
|
+
-- comparison group and was never affected — it already returned its argument.
|
|
239
|
+
select coalesce(s, 1) as v, typeof(coalesce(s, 1)) as ty from t3;
|
|
240
|
+
→ [{"v":"3","ty":"text"}]
|
|
241
|
+
|
|
242
|
+
-- Control: a same-category group still returns the plain winner.
|
|
243
|
+
select greatest(1, 2) as g, least(1, 2) as l;
|
|
244
|
+
→ [{"g":2,"l":1}]
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
-- 03.6.2-value-to-text.sqllogic
|
|
2
|
+
-- ONE value-to-text conversion (src/util/value-text.ts) behind every site that has
|
|
3
|
+
-- to render a value as text: CAST / text() / TEXT-column writes, `||`, LIKE operand
|
|
4
|
+
-- coercion, and group_concat. The real invariant is AGREEMENT — the same value must
|
|
5
|
+
-- spell the same way whichever construct produced it. Per-type unit coverage lives in
|
|
6
|
+
-- test/util/value-text.spec.ts; this file pins the SQL-visible behaviour.
|
|
7
|
+
|
|
8
|
+
-- === Per-source-type table ===
|
|
9
|
+
|
|
10
|
+
select cast('hello' as text) as r;
|
|
11
|
+
→ [{"r":"hello"}]
|
|
12
|
+
|
|
13
|
+
select cast(123 as text) as r;
|
|
14
|
+
→ [{"r":"123"}]
|
|
15
|
+
|
|
16
|
+
select cast(3.14 as text) as r;
|
|
17
|
+
→ [{"r":"3.14"}]
|
|
18
|
+
|
|
19
|
+
select cast(true as text) as r;
|
|
20
|
+
→ [{"r":"true"}]
|
|
21
|
+
|
|
22
|
+
select cast(false as text) as r;
|
|
23
|
+
→ [{"r":"false"}]
|
|
24
|
+
|
|
25
|
+
select cast(null as text) as r;
|
|
26
|
+
→ [{"r":null}]
|
|
27
|
+
|
|
28
|
+
-- Bigint: exact decimal digits, no Number() round-trip.
|
|
29
|
+
select cast(cast('9007199254740993' as integer) as text) as r;
|
|
30
|
+
→ [{"r":"9007199254740993"}]
|
|
31
|
+
|
|
32
|
+
-- Blob: UTF-8 decode. Was hex ('6162') through CAST and decimal bytes ('97,98')
|
|
33
|
+
-- through `||`; both now read the bytes as text, the way SQLite does.
|
|
34
|
+
select cast(x'6162' as text) as r;
|
|
35
|
+
→ [{"r":"ab"}]
|
|
36
|
+
|
|
37
|
+
-- The conversion function shares the rule (it is TEXT_TYPE.parse).
|
|
38
|
+
select text(x'6162') as r;
|
|
39
|
+
→ [{"r":"ab"}]
|
|
40
|
+
|
|
41
|
+
-- JSON object: the document's own text, not the placeholder '[object Object]'.
|
|
42
|
+
select cast(json('{"a":1}') as text) as r;
|
|
43
|
+
→ [{"r":"{\"a\":1}"}]
|
|
44
|
+
|
|
45
|
+
-- JSON array: real JSON, not the JS Array.toString() spelling '1,2,3'.
|
|
46
|
+
select cast(json('[1,2,3]') as text) as r;
|
|
47
|
+
→ [{"r":"[1,2,3]"}]
|
|
48
|
+
|
|
49
|
+
-- Nested document survives whole.
|
|
50
|
+
select cast(json('{"a":{"x":1},"b":[1,null]}') as text) as r;
|
|
51
|
+
→ [{"r":"{\"a\":{\"x\":1},\"b\":[1,null]}"}]
|
|
52
|
+
|
|
53
|
+
-- Key order is the DOCUMENT's, deliberately not canonical (sorted) order:
|
|
54
|
+
-- canonical form is for grouping keys and fingerprints, not for display.
|
|
55
|
+
select cast(json('{"b":2,"a":1}') as text) as r;
|
|
56
|
+
→ [{"r":"{\"b\":2,\"a\":1}"}]
|
|
57
|
+
|
|
58
|
+
-- === Edge cases ===
|
|
59
|
+
|
|
60
|
+
-- Empty blob renders as the empty string, not NULL.
|
|
61
|
+
select cast(x'' as text) as r;
|
|
62
|
+
→ [{"r":""}]
|
|
63
|
+
|
|
64
|
+
-- BOM: the decoder is built with ignoreBOM, so EF BB BF stays ONE U+FEFF
|
|
65
|
+
-- character instead of being silently stripped to ''.
|
|
66
|
+
select length(cast(x'efbbbf' as text)) as r;
|
|
67
|
+
→ [{"r":1}]
|
|
68
|
+
|
|
69
|
+
-- Invalid UTF-8 becomes U+FFFD. This is LOSSY on purpose — the conversion has to
|
|
70
|
+
-- be total (castCanYieldNull declares TEXT total over non-null operands), so it
|
|
71
|
+
-- replaces rather than throws.
|
|
72
|
+
select cast(x'ff' as text) as r;
|
|
73
|
+
→ [{"r":"�"}]
|
|
74
|
+
|
|
75
|
+
-- ...and the loss is real: distinct invalid blobs collide onto the same text.
|
|
76
|
+
-- Pinned so nobody "fixes" the replacement behaviour by accident.
|
|
77
|
+
select cast(x'ff' as text) = cast(x'fe' as text) as r;
|
|
78
|
+
→ [{"r":true}]
|
|
79
|
+
|
|
80
|
+
-- Multi-byte sequences decode properly.
|
|
81
|
+
select cast(x'e4b8ad' as text) as r;
|
|
82
|
+
→ [{"r":"中"}]
|
|
83
|
+
|
|
84
|
+
-- A JSON column holding a string scalar is physically a JS string, so it renders
|
|
85
|
+
-- bare — the conversion dispatches on the runtime value and cannot see that the
|
|
86
|
+
-- declared type is JSON.
|
|
87
|
+
select cast(json('"hello"') as text) as r;
|
|
88
|
+
→ [{"r":"hello"}]
|
|
89
|
+
|
|
90
|
+
-- JSON null parses to SQL NULL, so the cast is NULL — not the text 'null'.
|
|
91
|
+
select cast(json('null') as text) as r;
|
|
92
|
+
→ [{"r":null}]
|
|
93
|
+
|
|
94
|
+
-- cast(<json> as blob) is the UTF-8 of the document's text ('{"a":1}'),
|
|
95
|
+
-- not of '[object Object]'.
|
|
96
|
+
select cast(json('{"a":1}') as blob) = x'7b2261223a317d' as r;
|
|
97
|
+
→ [{"r":true}]
|
|
98
|
+
|
|
99
|
+
-- === NULL propagation is unchanged ===
|
|
100
|
+
|
|
101
|
+
select null || 'x' as r;
|
|
102
|
+
→ [{"r":null}]
|
|
103
|
+
|
|
104
|
+
select 'x' || null as r;
|
|
105
|
+
→ [{"r":null}]
|
|
106
|
+
|
|
107
|
+
select cast(null as text) is null as r;
|
|
108
|
+
→ [{"r":true}]
|
|
109
|
+
|
|
110
|
+
-- === Concatenation, LIKE and group_concat use the same rule ===
|
|
111
|
+
|
|
112
|
+
create table vt_b (id integer primary key, b blob);
|
|
113
|
+
insert into vt_b values (1, x'6162'), (2, x'6163');
|
|
114
|
+
-- run
|
|
115
|
+
|
|
116
|
+
select b || '' as r from vt_b order by id;
|
|
117
|
+
→ [{"r":"ab"},{"r":"ac"}]
|
|
118
|
+
|
|
119
|
+
select id from vt_b where b like 'ab' order by id;
|
|
120
|
+
→ [{"id":1}]
|
|
121
|
+
|
|
122
|
+
-- Same LIKE through a non-constant pattern, so the dynamic per-row path is
|
|
123
|
+
-- exercised too: constLikePattern and emitLikeOp must derive the same string.
|
|
124
|
+
select id from vt_b where b like (select b from vt_b where id = 1) order by id;
|
|
125
|
+
→ [{"id":1}]
|
|
126
|
+
|
|
127
|
+
select group_concat(b) as r from vt_b;
|
|
128
|
+
→ [{"r":"ab,ac"}]
|
|
129
|
+
|
|
130
|
+
select group_concat(b, '-') as r from vt_b;
|
|
131
|
+
→ [{"r":"ab-ac"}]
|
|
132
|
+
|
|
133
|
+
-- === The agreement invariants ===
|
|
134
|
+
|
|
135
|
+
-- CAST and `||` derive the same text for every row.
|
|
136
|
+
select cast(b as text) = (b || '') as r from vt_b order by id;
|
|
137
|
+
→ [{"r":true},{"r":true}]
|
|
138
|
+
|
|
139
|
+
-- group_concat over the raw values agrees with group_concat over the cast values.
|
|
140
|
+
select group_concat(b) = group_concat(cast(b as text)) as r from vt_b;
|
|
141
|
+
→ [{"r":true}]
|
|
142
|
+
|
|
143
|
+
-- LIKE's operand coercion agrees with CAST.
|
|
144
|
+
select b like cast(b as text) as r from vt_b order by id;
|
|
145
|
+
→ [{"r":true},{"r":true}]
|
|
146
|
+
|
|
147
|
+
-- The `like` FUNCTION is the same operation as the LIKE operator, so it must derive
|
|
148
|
+
-- the same text. (It used to use JS stringification and answer false here.)
|
|
149
|
+
select like(cast(b as text), b) = (b like cast(b as text)) as r from vt_b order by id;
|
|
150
|
+
→ [{"r":true},{"r":true}]
|
|
151
|
+
|
|
152
|
+
select like('ab', x'6162') as r;
|
|
153
|
+
→ [{"r":true}]
|
|
154
|
+
|
|
155
|
+
-- glob() shares the coercion with like().
|
|
156
|
+
select glob('ab', x'6162') as r;
|
|
157
|
+
→ [{"r":true}]
|
|
158
|
+
|
|
159
|
+
-- Same for a JSON document rendered as its own text.
|
|
160
|
+
select like('%"a"%', json('{"a":1}')) as r;
|
|
161
|
+
→ [{"r":true}]
|
|
162
|
+
|
|
163
|
+
-- Same three-way agreement over a JSON value.
|
|
164
|
+
create table vt_j (id integer primary key, j json);
|
|
165
|
+
insert into vt_j values (1, '{"a":1}'), (2, '[1,2,3]');
|
|
166
|
+
-- run
|
|
167
|
+
|
|
168
|
+
select cast(j as text) = (j || '') as r from vt_j order by id;
|
|
169
|
+
→ [{"r":true},{"r":true}]
|
|
170
|
+
|
|
171
|
+
select group_concat(j) as r from vt_j;
|
|
172
|
+
→ [{"r":"{\"a\":1},[1,2,3]"}]
|
|
173
|
+
|
|
174
|
+
-- group_concat still skips NULLs.
|
|
175
|
+
create table vt_n (id integer primary key, v text null);
|
|
176
|
+
insert into vt_n values (1, 'a'), (2, null), (3, 'b');
|
|
177
|
+
-- run
|
|
178
|
+
|
|
179
|
+
select group_concat(v) as r from vt_n;
|
|
180
|
+
→ [{"r":"a,b"}]
|
|
181
|
+
|
|
182
|
+
-- === The write path stores the conversion, not just the display ===
|
|
183
|
+
|
|
184
|
+
-- Inserting a blob into a TEXT column now STORES the UTF-8 decode (was the hex
|
|
185
|
+
-- spelling). This changes stored values, and it is lossy for non-UTF-8 bytes.
|
|
186
|
+
create table vt_w (id integer primary key, t text);
|
|
187
|
+
insert into vt_w values (1, x'6162'), (2, x'e4b8ad');
|
|
188
|
+
-- run
|
|
189
|
+
|
|
190
|
+
select t from vt_w order by id;
|
|
191
|
+
→ [{"t":"ab"},{"t":"中"}]
|
|
192
|
+
|
|
193
|
+
select typeof(t) as ty from vt_w order by id;
|
|
194
|
+
→ [{"ty":"text"},{"ty":"text"}]
|
|
195
|
+
|
|
196
|
+
-- An ALTER that retypes a BLOB column to TEXT backfills through the same rule.
|
|
197
|
+
create table vt_r (id integer primary key, b blob);
|
|
198
|
+
insert into vt_r values (1, x'6162');
|
|
199
|
+
alter table vt_r alter column b set data type text;
|
|
200
|
+
-- run
|
|
201
|
+
|
|
202
|
+
select b from vt_r order by id;
|
|
203
|
+
→ [{"b":"ab"}]
|
|
204
|
+
|
|
205
|
+
-- A TEXT column DEFAULT written as a blob literal folds through the same rule.
|
|
206
|
+
create table vt_d (id integer primary key, t text default x'6162');
|
|
207
|
+
insert into vt_d (id) values (1);
|
|
208
|
+
-- run
|
|
209
|
+
|
|
210
|
+
select t from vt_d;
|
|
211
|
+
→ [{"t":"ab"}]
|
|
212
|
+
|
|
213
|
+
-- === `->>` comes along for free ===
|
|
214
|
+
-- The parser desugars `a ->> b` to cast(json_extract(a, b) as text), so fixing
|
|
215
|
+
-- CAST fixes the operator.
|
|
216
|
+
|
|
217
|
+
select '{"a":{"x":1}}' ->> 'a' as r;
|
|
218
|
+
→ [{"r":"{\"x\":1}"}]
|
|
219
|
+
|
|
220
|
+
select '{"a":[1,2]}' ->> 'a' as r;
|
|
221
|
+
→ [{"r":"[1,2]"}]
|
|
222
|
+
|
|
223
|
+
select '{"a":"s"}' ->> 'a' as r;
|
|
224
|
+
→ [{"r":"s"}]
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
-- bigint-mixed-arithmetic.sqllogic - Test mixed bigint/number arithmetic
|
|
2
|
+
-- Regression: mixed bigint + number silently returns null instead of numeric result
|
|
3
|
+
|
|
4
|
+
-- 9007199254740993 exceeds Number.MAX_SAFE_INTEGER, so it's stored as bigint
|
|
5
|
+
-- Adding a float (1.5) to it should produce float arithmetic, not null
|
|
6
|
+
-- Note: converting bigint to Number loses precision (expected for float ops)
|
|
7
|
+
|
|
8
|
+
SELECT 9007199254740993 + 1.5;
|
|
9
|
+
→ [{"9007199254740993 + 1.5":9007199254740994}]
|
|
10
|
+
|
|
11
|
+
-- bigint + integer (number): number promotes to bigint, stays in bigint domain
|
|
12
|
+
SELECT 9007199254740993 + 1;
|
|
13
|
+
→ [{"9007199254740993 + 1":9007199254740994}]
|
|
14
|
+
|
|
15
|
+
-- bigint - number (float) — test harness returns bare value for subtraction expressions
|
|
16
|
+
SELECT 9007199254740993 - 0.5;
|
|
17
|
+
→ [9007199254740992]
|
|
18
|
+
|
|
19
|
+
-- bigint * number (integer 2.0 promotes to BigInt)
|
|
20
|
+
SELECT 9007199254740993 * 2.0;
|
|
21
|
+
→ [{"9007199254740993 * 2.0":18014398509481986}]
|
|
22
|
+
|
|
23
|
+
-- number + bigint (reversed operand order)
|
|
24
|
+
SELECT 1.5 + 9007199254740993;
|
|
25
|
+
→ [{"1.5 + 9007199254740993":9007199254740994}]
|
|
26
|
+
|
|
27
|
+
-- bigint / number
|
|
28
|
+
SELECT 9007199254740993 / 2.0;
|
|
29
|
+
→ [{"9007199254740993 / 2.0":4503599627370496}]
|
|
30
|
+
|
|
31
|
+
-- bigint % number (integer 2.0 promotes to BigInt, gives exact result)
|
|
32
|
+
SELECT 9007199254740993 % 2.0;
|
|
33
|
+
→ [{"9007199254740993 % 2.0":1}]
|
|
34
|
+
|
|
35
|
+
-- Verify pure bigint + bigint still works
|
|
36
|
+
SELECT 9007199254740993 + 9007199254740993;
|
|
37
|
+
→ [{"9007199254740993 + 9007199254740993":18014398509481986}]
|
|
38
|
+
|
|
39
|
+
-- Verify typeof results
|
|
40
|
+
-- Float result is 9007199254740994 which is integer-valued (IEEE 754 rounding)
|
|
41
|
+
SELECT typeof(9007199254740993 + 1.5);
|
|
42
|
+
→ [{"typeof(9007199254740993 + 1.5)":"integer"}]
|
|
43
|
+
|
|
44
|
+
SELECT typeof(9007199254740993 + 1);
|
|
45
|
+
→ [{"typeof(9007199254740993 + 1)":"integer"}]
|
|
46
|
+
|
|
47
|
+
-- bigint + numeric string: text coerced through arithmetic affinity, then BigInt-promoted
|
|
48
|
+
SELECT 9007199254740993 + '3';
|
|
49
|
+
→ [{"9007199254740993 + '3'":9007199254740996}]
|
|
50
|
+
|
|
51
|
+
-- numeric string + bigint (reversed order)
|
|
52
|
+
SELECT '3' + 9007199254740993;
|
|
53
|
+
→ [{"'3' + 9007199254740993":9007199254740996}]
|
|
54
|
+
|
|
55
|
+
-- bigint + non-numeric string: string coerces to 0, stays in BigInt domain
|
|
56
|
+
SELECT 9007199254740993 + 'abc';
|
|
57
|
+
→ [{"9007199254740993 + 'abc'":9007199254740993}]
|
|
58
|
+
|
|
59
|
+
-- bigint + boolean: boolean coerces to 0/1, BigInt-promoted
|
|
60
|
+
SELECT 9007199254740993 + true;
|
|
61
|
+
→ [{"9007199254740993 + true":9007199254740994}]
|
|
62
|
+
|
|
63
|
+
-- bigint + fractional numeric string: float path
|
|
64
|
+
SELECT 9007199254740993 + '0.5';
|
|
65
|
+
→ [{"9007199254740993 + '0.5'":9007199254740992}]
|