@quereus/quereus 4.20.0 → 4.20.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/dist/src/common/types.d.ts +4 -4
- package/dist/src/index.d.ts +1 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +3 -2
- package/dist/src/index.js.map +1 -1
- package/dist/src/schema/catalog-rendering.js +13 -1
- package/dist/src/schema/catalog-rendering.js.map +1 -1
- package/dist/src/schema/catalog.d.ts +35 -2
- package/dist/src/schema/catalog.d.ts.map +1 -1
- package/dist/src/schema/catalog.js +42 -33
- package/dist/src/schema/catalog.js.map +1 -1
- package/dist/src/schema/schema-differ.d.ts +1 -1
- package/dist/src/schema/schema-differ.d.ts.map +1 -1
- package/dist/src/schema/schema-differ.js +195 -33
- package/dist/src/schema/schema-differ.js.map +1 -1
- package/dist/src/schema/unique-enforcement.d.ts +23 -1
- package/dist/src/schema/unique-enforcement.d.ts.map +1 -1
- package/dist/src/schema/unique-enforcement.js +43 -1
- package/dist/src/schema/unique-enforcement.js.map +1 -1
- package/dist/src/vtab/memory/layer/manager.d.ts +15 -12
- package/dist/src/vtab/memory/layer/manager.d.ts.map +1 -1
- package/dist/src/vtab/memory/layer/manager.js +87 -100
- package/dist/src/vtab/memory/layer/manager.js.map +1 -1
- package/package.json +7 -4
- package/test/README.md +173 -0
- package/test/logic/01-basic.sqllogic +39 -0
- package/test/logic/01.1-select-projection-extras.sqllogic +130 -0
- package/test/logic/01.2-strings.sqllogic +43 -0
- package/test/logic/01.5-insert-select.sqllogic +237 -0
- package/test/logic/01.6-update-extras.sqllogic +118 -0
- package/test/logic/01.7-update-from.sqllogic +67 -0
- package/test/logic/01.8-delete-extras.sqllogic +122 -0
- package/test/logic/01.8.1-delete-range-cow.sqllogic +115 -0
- package/test/logic/01.9-query-expr-dml-gates.sqllogic +32 -0
- package/test/logic/01.9-query-expr-dml.sqllogic +171 -0
- package/test/logic/01.9-query-expr-values.sqllogic +111 -0
- package/test/logic/01.9.1-limit-over-dml-subquery.sqllogic +119 -0
- package/test/logic/02-filters.sqllogic +54 -0
- package/test/logic/02-smoke.sqllogic +62 -0
- package/test/logic/02.1-bind-parameters.sqllogic +223 -0
- package/test/logic/03-expressions.sqllogic +190 -0
- package/test/logic/03.1-quoted-identifiers.sqllogic +55 -0
- package/test/logic/03.4-defaults.sqllogic +554 -0
- package/test/logic/03.4.1-default-edge-cases.sqllogic +99 -0
- package/test/logic/03.5-tvf.sqllogic +61 -0
- package/test/logic/03.6-type-system.sqllogic +544 -0
- package/test/logic/03.6.1-numeric-text-comparison-coercion.sqllogic +244 -0
- package/test/logic/03.6.2-value-to-text.sqllogic +224 -0
- package/test/logic/03.7-bigint-mixed-arithmetic.sqllogic +65 -0
- package/test/logic/03.8-not-precedence.sqllogic +255 -0
- package/test/logic/03.9-is-bool-predicate.sqllogic +150 -0
- package/test/logic/03.9.1-is-bool-predicate-partial-index.sqllogic +34 -0
- package/test/logic/04-order-by.sqllogic +38 -0
- package/test/logic/04-transactions.sqllogic +239 -0
- package/test/logic/04a-savepoint-lazy-attach.sqllogic +122 -0
- package/test/logic/05-vtab_memory.sqllogic +50 -0
- package/test/logic/05.0.1-vtab-memory-unique-index-collation.sqllogic +34 -0
- package/test/logic/05.1-composite-pk-range-scan.sqllogic +147 -0
- package/test/logic/05.1.1-secondary-index-range-scan.sqllogic +56 -0
- package/test/logic/05.2-cast-seek-correctness.sqllogic +124 -0
- package/test/logic/06-builtin_functions.sqllogic +149 -0
- package/test/logic/06.1-string-functions.sqllogic +92 -0
- package/test/logic/06.1.3-like-glob-edges.sqllogic +53 -0
- package/test/logic/06.2-math-functions.sqllogic +82 -0
- package/test/logic/06.3-schema.sqllogic +48 -0
- package/test/logic/06.3.1-schema-all-schemas.sqllogic +39 -0
- package/test/logic/06.3.2-schema-foreign-keys.sqllogic +208 -0
- package/test/logic/06.3.3-introspection-tags.sqllogic +202 -0
- package/test/logic/06.3.3.1-introspection-tags-index.sqllogic +74 -0
- package/test/logic/06.3.4-view-info.sqllogic +378 -0
- package/test/logic/06.3.5-column-info.sqllogic +347 -0
- package/test/logic/06.3.6-schema-views.sqllogic +29 -0
- package/test/logic/06.4-schema-search-path.sqllogic +354 -0
- package/test/logic/06.4.1-schema-case-insensitive.sqllogic +83 -0
- package/test/logic/06.4.2-collation-extras.sqllogic +472 -0
- package/test/logic/06.4.2.1-collation-index-access-paths.sqllogic +140 -0
- package/test/logic/06.4.3-write-path-collation.sqllogic +99 -0
- package/test/logic/06.4.4-comparison-collation-precedence.sqllogic +342 -0
- package/test/logic/06.4.5-any-collate-declared-keys.sqllogic +92 -0
- package/test/logic/06.5-polymorphic-types.sqllogic +169 -0
- package/test/logic/06.5.1-conversion-functions.sqllogic +173 -0
- package/test/logic/06.5.2-scalar-minmax.sqllogic +16 -0
- package/test/logic/06.5.3-undeclared-return-type-comparison.sqllogic +244 -0
- package/test/logic/06.5.4-declared-return-type-builtins.sqllogic +288 -0
- package/test/logic/06.6-aggregate-extended.sqllogic +78 -0
- package/test/logic/06.7-json-extended.sqllogic +53 -0
- package/test/logic/06.8-json-path-operators.sqllogic +99 -0
- package/test/logic/06.9-json-canonical-key.sqllogic +65 -0
- package/test/logic/06.9.1-json-coerce-once.sqllogic +417 -0
- package/test/logic/06.9.1.1-json-coerce-once-index.sqllogic +39 -0
- package/test/logic/06.9.2-json-structural-equality.sqllogic +382 -0
- package/test/logic/06.9.2.1-json-structural-equality-index.sqllogic +76 -0
- package/test/logic/06.9.3-json-index-range-seek.sqllogic +205 -0
- package/test/logic/07-aggregates.sqllogic +193 -0
- package/test/logic/07.1-aggregate-filter-clause.sqllogic +12 -0
- package/test/logic/07.2-aggregate-order-by.sqllogic +11 -0
- package/test/logic/07.3-group-by-extras.sqllogic +602 -0
- package/test/logic/07.3.1-group-by-order-by-key.sqllogic +164 -0
- package/test/logic/07.3.2-grouped-select-list-shape.sqllogic +231 -0
- package/test/logic/07.4-group-by-filter-composite-pk.sqllogic +120 -0
- package/test/logic/07.5-sum-mixed-exact-and-float.sqllogic +151 -0
- package/test/logic/07.5-window.sqllogic +1941 -0
- package/test/logic/07.5.1-window-named.sqllogic +13 -0
- package/test/logic/07.5.2-window-nth-value.sqllogic +13 -0
- package/test/logic/07.6-subqueries.sqllogic +78 -0
- package/test/logic/07.6.1-subquery-extras.sqllogic +93 -0
- package/test/logic/07.7-and-or-short-circuit.sqllogic +58 -0
- package/test/logic/07.7-in-subquery-caching.sqllogic +174 -0
- package/test/logic/07.7-scalar-agg-decorrelation.sqllogic +197 -0
- package/test/logic/07.7.1-in-extras.sqllogic +158 -0
- package/test/logic/07.7.1-scalar-agg-decorrelation-filter.sqllogic +105 -0
- package/test/logic/07.7.2-scalar-agg-decorrelation-nested.sqllogic +115 -0
- package/test/logic/07.7.3-exists-in-select-decorrelation.sqllogic +107 -0
- package/test/logic/07.7.4-where-conjunct-ordering.sqllogic +121 -0
- package/test/logic/07.7.5-filter-lost-under-index-order.sqllogic +134 -0
- package/test/logic/07.7.6-correlated-predicate-scope.sqllogic +178 -0
- package/test/logic/07.7.7-join-source-scope-shadowing.sqllogic +137 -0
- package/test/logic/07.7.8-correlated-ref-to-computed-column.sqllogic +165 -0
- package/test/logic/07.7.9-conjunct-monotonicity.sqllogic +200 -0
- package/test/logic/07.8-correlated-subquery-edges.sqllogic +71 -0
- package/test/logic/07.8.1-correlated-in-decorrelation-gates.sqllogic +156 -0
- package/test/logic/07.9-in-value-list.sqllogic +154 -0
- package/test/logic/07.9.1-in-value-list-composite-index.sqllogic +38 -0
- package/test/logic/08-views.sqllogic +64 -0
- package/test/logic/08.1-semi-anti-join.sqllogic +191 -0
- package/test/logic/08.1-view-edge-cases.sqllogic +118 -0
- package/test/logic/08.1.1-uncorrelated-in-semijoin.sqllogic +251 -0
- package/test/logic/08.2-existence-flag-semijoin-recovery.sqllogic +197 -0
- package/test/logic/08.3-existence-flag-inner-recovery.sqllogic +102 -0
- package/test/logic/08.4-key-set-semi-join.sqllogic +447 -0
- package/test/logic/09-set_operations.sqllogic +244 -0
- package/test/logic/09.1-set-op-cross-collation.sqllogic +230 -0
- package/test/logic/10-distinct_datatypes.sqllogic +127 -0
- package/test/logic/10.1-ddl-lifecycle.sqllogic +203 -0
- package/test/logic/10.1.1-create-table-syntax-edges.sqllogic +47 -0
- package/test/logic/10.1.2-ddl-in-transaction.sqllogic +143 -0
- package/test/logic/10.1.2.1-add-constraint-in-transaction.sqllogic +59 -0
- package/test/logic/10.1.3-ddl-drop-in-transaction.sqllogic +187 -0
- package/test/logic/10.1.3.1-drop-constraint-in-transaction.sqllogic +45 -0
- package/test/logic/10.1.4-create-table-duplicate-constraint-names.sqllogic +149 -0
- package/test/logic/10.1.4-ddl-transaction-policy.sqllogic +314 -0
- package/test/logic/10.1.5-alter-add-constraint-minted-name-disambiguation.sqllogic +219 -0
- package/test/logic/10.1.5-create-index-lifecycle.sqllogic +72 -0
- package/test/logic/10.1.6-ddl-transaction-policy-index.sqllogic +143 -0
- package/test/logic/10.1.7-create-table-default-type-check.sqllogic +119 -0
- package/test/logic/10.1.8-alter-add-check-existing-rows.sqllogic +117 -0
- package/test/logic/10.2-column-features.sqllogic +365 -0
- package/test/logic/10.2.1-table-options-rejection.sqllogic +63 -0
- package/test/logic/10.2.2-default-collation-memory.sqllogic +30 -0
- package/test/logic/10.3-function-features.sqllogic +247 -0
- package/test/logic/10.4-schema-scale.sqllogic +168 -0
- package/test/logic/10.4.1-schema-scale-indexes.sqllogic +121 -0
- package/test/logic/10.5-indexes.sqllogic +164 -0
- package/test/logic/10.5.1-partial-indexes.sqllogic +526 -0
- package/test/logic/10.5.2-expression-indexes.sqllogic +34 -0
- package/test/logic/10.5.3-desc-index-ordering.sqllogic +130 -0
- package/test/logic/10.5.4-composite-pk-index-update-phantom.sqllogic +55 -0
- package/test/logic/10.5.5-index-name-uniqueness.sqllogic +76 -0
- package/test/logic/10.5.6-minmax-index-boundary.sqllogic +204 -0
- package/test/logic/10.5.7-implicit-unique-index-lifecycle.sqllogic +1216 -0
- package/test/logic/10.6-distinct-edge-cases.sqllogic +119 -0
- package/test/logic/100-predicate-normalization-edge-cases.sqllogic +238 -0
- package/test/logic/100.1-where-extras.sqllogic +163 -0
- package/test/logic/100.1.1-where-join-on-order-indexed.sqllogic +35 -0
- package/test/logic/101-builtin-mutation-kills.sqllogic +974 -0
- package/test/logic/101-transaction-edge-cases.sqllogic +395 -0
- package/test/logic/102-schema-catalog-edge-cases.sqllogic +252 -0
- package/test/logic/102-unique-constraints.sqllogic +145 -0
- package/test/logic/102.0.1-schema-catalog-indexed-table.sqllogic +32 -0
- package/test/logic/102.1-unique-edge-cases.sqllogic +111 -0
- package/test/logic/102.1.1-unique-index-creation-edge-cases.sqllogic +75 -0
- package/test/logic/102.2-unique-collation.sqllogic +181 -0
- package/test/logic/102.2.1-unique-collation-index-derived.sqllogic +305 -0
- package/test/logic/103-database-options-edge-cases.sqllogic +108 -0
- package/test/logic/103.1-pragma-boolean-values.sqllogic +126 -0
- package/test/logic/104-emit-mutation-kills.sqllogic +236 -0
- package/test/logic/105-vtab-memory-mutation-kills.sqllogic +754 -0
- package/test/logic/105.1-vtab-memory-index-mutation-kills.sqllogic +540 -0
- package/test/logic/106-constraint-extractor-mutation-kills.sqllogic +350 -0
- package/test/logic/107-temporal-arithmetic-mutation-kills.sqllogic +833 -0
- package/test/logic/108-cardinality-estimation.sqllogic +146 -0
- package/test/logic/108.1-analyze-name-resolution.sqllogic +102 -0
- package/test/logic/109-aggregate-physical-selection.sqllogic +103 -0
- package/test/logic/11-joins.sqllogic +86 -0
- package/test/logic/11.1-join-using.sqllogic +267 -0
- package/test/logic/11.2-comma-join.sqllogic +35 -0
- package/test/logic/11.3-index-nested-loop-join.sqllogic +305 -0
- package/test/logic/11.3-mismatched-collation-join.sqllogic +74 -0
- package/test/logic/11.4-hash-join-side-swap.sqllogic +118 -0
- package/test/logic/110-scan-emitter-mutation-kills.sqllogic +121 -0
- package/test/logic/110.1-scan-emitter-index-scan-kills.sqllogic +47 -0
- package/test/logic/12-empty-primary-key.sqllogic +124 -0
- package/test/logic/12-join_padding_order.sqllogic +58 -0
- package/test/logic/12.1-orderby-index-consumption.sqllogic +40 -0
- package/test/logic/13-cte.sqllogic +137 -0
- package/test/logic/13.1-cte-multiple-recursive.sqllogic +104 -0
- package/test/logic/13.10-cte-qualified-name.sqllogic +136 -0
- package/test/logic/13.11-unreferenced-dml-cte.sqllogic +414 -0
- package/test/logic/13.12-nested-dml-cte-rejected.sqllogic +280 -0
- package/test/logic/13.2-cte-bind-params.sqllogic +98 -0
- package/test/logic/13.3-cte-edge-cases.sqllogic +120 -0
- package/test/logic/13.4-cte-extras.sqllogic +98 -0
- package/test/logic/13.5-cte-join-order.sqllogic +166 -0
- package/test/logic/13.6-cte-dml-runs-once.sqllogic +318 -0
- package/test/logic/13.7-cte-sibling-visibility.sqllogic +227 -0
- package/test/logic/13.8-insert-with-clause-visibility.sqllogic +254 -0
- package/test/logic/13.9-schema-authored-cte-isolation.sqllogic +328 -0
- package/test/logic/13.9.1-schema-authored-schema-path-isolation.sqllogic +408 -0
- package/test/logic/14-utilities.sqllogic +168 -0
- package/test/logic/15-timespan.sqllogic +279 -0
- package/test/logic/15.1-semantic-ordering.sqllogic +960 -0
- package/test/logic/15.1.1-json-check-coercion.sqllogic +178 -0
- package/test/logic/15.1.2-semantic-ordering-index.sqllogic +41 -0
- package/test/logic/15.1.3-declared-form-write-contract.sqllogic +519 -0
- package/test/logic/16-epoch.sqllogic +187 -0
- package/test/logic/17-weekday-modifier.sqllogic +78 -0
- package/test/logic/18-json-string-escapes.sqllogic +86 -0
- package/test/logic/18-strftime-extended-formats.sqllogic +68 -0
- package/test/logic/20-empty-single-row.sqllogic +261 -0
- package/test/logic/21-null-edge-cases.sqllogic +227 -0
- package/test/logic/21.1-where-null-comparisons.sqllogic +151 -0
- package/test/logic/21.1.1-where-null-comparisons-secondary-index.sqllogic +35 -0
- package/test/logic/21.2-between-edges.sqllogic +157 -0
- package/test/logic/22-boundary-values.sqllogic +175 -0
- package/test/logic/23-self-joins-duplicates.sqllogic +74 -0
- package/test/logic/24-builtin-branches.sqllogic +611 -0
- package/test/logic/24.1-substr-extras.sqllogic +75 -0
- package/test/logic/24.2-random-extras.sqllogic +39 -0
- package/test/logic/25-aggregate-edge-cases.sqllogic +289 -0
- package/test/logic/25.1-nested-aggregates.sqllogic +74 -0
- package/test/logic/25.2-having-edge-cases.sqllogic +318 -0
- package/test/logic/25.3-aggregate-isnull-empty.sqllogic +16 -0
- package/test/logic/25.4-groupby-fd-constant-empty.sqllogic +55 -0
- package/test/logic/25.5-ungrouped-aggregate-column-free-select-item.sqllogic +196 -0
- package/test/logic/26-join-edge-cases.sqllogic +333 -0
- package/test/logic/26.1-left-join-isnull-on-notnull.sqllogic +26 -0
- package/test/logic/26.2-left-join-on-vs-where.sqllogic +67 -0
- package/test/logic/26.3-join-on-constants.sqllogic +61 -0
- package/test/logic/26.4-join-on-is-null-nullable.sqllogic +44 -0
- package/test/logic/27-window-edge-cases.sqllogic +206 -0
- package/test/logic/27.1-window-groups-frame.sqllogic +13 -0
- package/test/logic/27.2-window-exclude.sqllogic +13 -0
- package/test/logic/27.3-window-json-aggregation.sqllogic +66 -0
- package/test/logic/28-set-ops-sort-edge-cases.sqllogic +444 -0
- package/test/logic/28.1-compound-limit-offset.sqllogic +143 -0
- package/test/logic/28.2-orderby-expression-extras.sqllogic +698 -0
- package/test/logic/28.2-set-op-branch-types.sqllogic +217 -0
- package/test/logic/29-constraint-edge-cases.sqllogic +442 -0
- package/test/logic/29.1-column-level-conflict-clause.sqllogic +171 -0
- package/test/logic/29.2-table-level-pk-conflict-clause.sqllogic +113 -0
- package/test/logic/40-constraints.sqllogic +418 -0
- package/test/logic/40.1-pk-desc-direction.sqllogic +76 -0
- package/test/logic/40.2-check-extras.sqllogic +683 -0
- package/test/logic/41-alter-table.sqllogic +191 -0
- package/test/logic/41-fk-cascade-conflict-and-self-ref.sqllogic +263 -0
- package/test/logic/41-fk-cross-schema.sqllogic +155 -0
- package/test/logic/41-fk-extended-targets.sqllogic +173 -0
- package/test/logic/41-foreign-keys.sqllogic +1001 -0
- package/test/logic/41-generated-column-errors.sqllogic +225 -0
- package/test/logic/41-generated-column-extras.sqllogic +598 -0
- package/test/logic/41-generated-column-scope.sqllogic +329 -0
- package/test/logic/41-generated-columns.sqllogic +361 -0
- package/test/logic/41.1-alter-pk.sqllogic +230 -0
- package/test/logic/41.1-fk-collation-conflict.sqllogic +277 -0
- package/test/logic/41.10-alter-drop-column-foreign-key.sqllogic +274 -0
- package/test/logic/41.10.1-alter-drop-column-unique-index.sqllogic +169 -0
- package/test/logic/41.10.2-alter-drop-column-check-and-assertion.sqllogic +1616 -0
- package/test/logic/41.10.3-alter-drop-column-referencing-fk.sqllogic +292 -0
- package/test/logic/41.10.4-drop-object-expression-dependents.sqllogic +602 -0
- package/test/logic/41.11-deferred-fk-with-rename.sqllogic +232 -0
- package/test/logic/41.12-alter-default-coercion.sqllogic +200 -0
- package/test/logic/41.13-alter-add-column-generated-backfill.sqllogic +566 -0
- package/test/logic/41.14-alter-add-column-subquery-backfill.sqllogic +129 -0
- package/test/logic/41.15-alter-column-default-type-check.sqllogic +178 -0
- package/test/logic/41.16-fk-unenforceable.sqllogic +364 -0
- package/test/logic/41.2-alter-column.sqllogic +382 -0
- package/test/logic/41.2.1-alter-column-retype-deleted-row-memory.sqllogic +32 -0
- package/test/logic/41.2.2-alter-column-retype-index-rebuild.sqllogic +77 -0
- package/test/logic/41.2.3-alter-column-set-not-null-pk-backfill.sqllogic +310 -0
- package/test/logic/41.2.3.1-alter-column-set-not-null-pk-backfill-secondary-index.sqllogic +37 -0
- package/test/logic/41.3-alter-add-column-unique.sqllogic +184 -0
- package/test/logic/41.3-alter-rename-propagation.sqllogic +2352 -0
- package/test/logic/41.3.1-alter-rename-index-propagation.sqllogic +94 -0
- package/test/logic/41.4-alter-add-column-constraints.sqllogic +855 -0
- package/test/logic/41.5-alter-misc.sqllogic +48 -0
- package/test/logic/41.5-cross-schema-foreign-keys.sqllogic +253 -0
- package/test/logic/41.6-alter-drop-rename-constraint.sqllogic +354 -0
- package/test/logic/41.6.1-alter-drop-constraint-index-derived.sqllogic +22 -0
- package/test/logic/41.7-alter-column-collate.sqllogic +105 -0
- package/test/logic/41.7.1-alter-column-collate-unique.sqllogic +45 -0
- package/test/logic/41.7.2-alter-column-collate-unique-store.sqllogic +208 -0
- package/test/logic/41.7.2.1-alter-column-collate-unique-index-store.sqllogic +114 -0
- package/test/logic/41.7.3-alter-column-retype-unique.sqllogic +293 -0
- package/test/logic/41.7.3.1-alter-column-retype-staged-rows-memory.sqllogic +41 -0
- package/test/logic/41.7.3.2-alter-column-retype-unique-index.sqllogic +72 -0
- package/test/logic/41.7.4-alter-column-retype-semantic-memory.sqllogic +445 -0
- package/test/logic/41.7.4.1-alter-column-retype-semantic-index-memory.sqllogic +91 -0
- package/test/logic/41.7.5-alter-column-collate-pk-staged-delete-memory.sqllogic +106 -0
- package/test/logic/41.8-alter-add-constraint-unique-fk.sqllogic +275 -0
- package/test/logic/41.8-alter-savepoint-staged-rows.sqllogic +443 -0
- package/test/logic/41.8.1-alter-rename-savepoint-staged-rows.sqllogic +408 -0
- package/test/logic/41.9-alter-constraint-body-change.sqllogic +180 -0
- package/test/logic/41.9-fk-restrict-batched.sqllogic +290 -0
- package/test/logic/42-committed-snapshot.sqllogic +254 -0
- package/test/logic/42-returning.sqllogic +159 -0
- package/test/logic/42.1-returning-extras.sqllogic +232 -0
- package/test/logic/42.2-returning-stored-row.sqllogic +165 -0
- package/test/logic/43-default-nullability.sqllogic +131 -0
- package/test/logic/43-transition-constraints.sqllogic +341 -0
- package/test/logic/43.1-default-collation.sqllogic +140 -0
- package/test/logic/43.1-notnull-or-conflict.sqllogic +79 -0
- package/test/logic/43.2-deferred-check-new-on-delete.sqllogic +95 -0
- package/test/logic/43.3-nullable-primary-key.sqllogic +587 -0
- package/test/logic/44-determinism-validation.sqllogic +164 -0
- package/test/logic/44-orthogonality.sqllogic +146 -0
- package/test/logic/44.1-nondeterministic-schema.sqllogic +316 -0
- package/test/logic/45-udf-determinism.sqllogic +39 -0
- package/test/logic/46-mutation-context.sqllogic +595 -0
- package/test/logic/47-upsert.sqllogic +255 -0
- package/test/logic/47.1-upsert-conflict-targets.sqllogic +169 -0
- package/test/logic/47.2-replace-and-or-clauses.sqllogic +164 -0
- package/test/logic/47.2.1-pk-replace-secondary-unique.sqllogic +374 -0
- package/test/logic/47.3-engine-or-fail.sqllogic +122 -0
- package/test/logic/47.3-upsert-conflict-target-collation.sqllogic +139 -0
- package/test/logic/47.3.1-upsert-conflict-index-derived-collation.sqllogic +25 -0
- package/test/logic/47.4-upsert-conflict-target-affinity.sqllogic +59 -0
- package/test/logic/47.5-upsert-do-update-constraints.sqllogic +440 -0
- package/test/logic/47.6-upsert-do-update-decomposed.sqllogic +100 -0
- package/test/logic/49-reference-graph.sqllogic +84 -0
- package/test/logic/50-declarative-schema.sqllogic +2550 -0
- package/test/logic/50-metadata-tags.sqllogic +1033 -0
- package/test/logic/50.0.1-metadata-tags-index.sqllogic +141 -0
- package/test/logic/50.1-declare-schema-pk.sqllogic +150 -0
- package/test/logic/50.2-declare-schema-renames.sqllogic +949 -0
- package/test/logic/50.2.1-declare-schema-index-renames.sqllogic +173 -0
- package/test/logic/50.3-declare-schema-duplicate-names.sqllogic +280 -0
- package/test/logic/50.4-declare-schema-apply-restore.sqllogic +192 -0
- package/test/logic/51-lens-foundation.sqllogic +147 -0
- package/test/logic/51-materialized-views.sqllogic +376 -0
- package/test/logic/51.5-materialized-views-coarsened-key.sqllogic +198 -0
- package/test/logic/51.7-maintained-table-attach-detach.sqllogic +468 -0
- package/test/logic/51.8-maintained-table-declared-constraints.sqllogic +440 -0
- package/test/logic/51.85-maintained-table-parent-fk.sqllogic +103 -0
- package/test/logic/51.9-maintained-table-secondary-unique.sqllogic +237 -0
- package/test/logic/51.9.1-maintained-table-partial-unique.sqllogic +36 -0
- package/test/logic/52-lens-overrides.sqllogic +566 -0
- package/test/logic/53-materialized-views-rowtime.sqllogic +1601 -0
- package/test/logic/53-reserved-tags.sqllogic +252 -0
- package/test/logic/53.1-materialized-view-write-through.sqllogic +329 -0
- package/test/logic/53.2-materialized-view-rename-propagation.sqllogic +483 -0
- package/test/logic/53.3-materialized-view-constraint-only-ddl.sqllogic +409 -0
- package/test/logic/53.3.1-materialized-view-index-ddl-irrelevance.sqllogic +29 -0
- package/test/logic/53.4-materialized-view-structural-alter-restore.sqllogic +436 -0
- package/test/logic/54-covering-mv-enforcement.sqllogic +314 -0
- package/test/logic/54.1-covering-mv-partial-enforcement.sqllogic +34 -0
- package/test/logic/55-internal-eviction-reporting.sqllogic +89 -0
- package/test/logic/55-lens-prover.sqllogic +202 -0
- package/test/logic/55.1-eviction-restrict-fk.sqllogic +148 -0
- package/test/logic/55.5-lens-authored-inverse.sqllogic +1468 -0
- package/test/logic/80-grow-retrieve-pass.sqllogic +79 -0
- package/test/logic/81-quickpick.sqllogic +24 -0
- package/test/logic/82-bloom-join.sqllogic +185 -0
- package/test/logic/83-merge-join.sqllogic +280 -0
- package/test/logic/84-asof-scan.sqllogic +238 -0
- package/test/logic/84-key-cardinality.sqllogic +50 -0
- package/test/logic/85-relational-const-folding.sqllogic +51 -0
- package/test/logic/86-scalar-cse.sqllogic +42 -0
- package/test/logic/90-error_paths.sqllogic +114 -0
- package/test/logic/90.1-parse-errors.sqllogic +77 -0
- package/test/logic/90.2-alter-table-errors.sqllogic +53 -0
- package/test/logic/90.2.1-alter-extra-errors.sqllogic +51 -0
- package/test/logic/90.3-expression-errors.sqllogic +43 -0
- package/test/logic/90.4-dml-errors.sqllogic +47 -0
- package/test/logic/90.5-unsupported-join-types.sqllogic +37 -0
- package/test/logic/90.5.1-right-full-join-read.sqllogic +157 -0
- package/test/logic/90.6-select-error-paths.sqllogic +57 -0
- package/test/logic/91-merge-join-edge-cases.sqllogic +159 -0
- package/test/logic/92-hash-aggregate-edge-cases.sqllogic +139 -0
- package/test/logic/93-ddl-view-edge-cases.sqllogic +104 -0
- package/test/logic/93.1-view-error-paths.sqllogic +74 -0
- package/test/logic/93.2-view-mutation-pending.sqllogic +108 -0
- package/test/logic/93.3-view-mutation-or-clause.sqllogic +60 -0
- package/test/logic/93.4-view-mutation.sqllogic +4881 -0
- package/test/logic/93.4.1-view-mutation-partial-unique-cardinality.sqllogic +31 -0
- package/test/logic/93.5-authored-inverse.sqllogic +415 -0
- package/test/logic/93.6-set-op-flagless-write.sqllogic +862 -0
- package/test/logic/94-tvf-edge-cases.sqllogic +58 -0
- package/test/logic/94.1-limit-offset-edge-cases.sqllogic +109 -0
- package/test/logic/94.2-limit-offset-extras.sqllogic +98 -0
- package/test/logic/95-assertions.sqllogic +1417 -0
- package/test/logic/96-subquery-edge-cases.sqllogic +276 -0
- package/test/logic/97-json-function-edge-cases.sqllogic +633 -0
- package/test/logic/97.1-json-blob-and-special-values.sqllogic +92 -0
- package/test/logic/98-temporal-edge-cases.sqllogic +515 -0
- package/test/logic/99-conversion-edge-cases.sqllogic +325 -0
- package/test/logic/99.0.1-schema-index-listing.sqllogic +21 -0
- package/test/logic/99.1-cast-syntax-extras.sqllogic +167 -0
- package/test/logic/drop-unique-index.sqllogic +88 -0
- package/test/logic/pushdown-test.sqllogic +36 -0
|
@@ -0,0 +1,974 @@
|
|
|
1
|
+
-- 101-builtin-mutation-kills.sqllogic
|
|
2
|
+
-- Mutation-killing tests for builtin functions in scalar.ts, string.ts,
|
|
3
|
+
-- aggregate.ts, and conversion.ts. Each test targets a specific code path
|
|
4
|
+
-- that a common mutant (flipped comparison, removed null guard, off-by-one,
|
|
5
|
+
-- swapped operator) would break.
|
|
6
|
+
|
|
7
|
+
-- ============================================================
|
|
8
|
+
-- SETUP
|
|
9
|
+
-- ============================================================
|
|
10
|
+
|
|
11
|
+
create table mk (id integer primary key, v_int integer null, v_real real null, v_text text null);
|
|
12
|
+
insert into mk values (1, null, null, null);
|
|
13
|
+
insert into mk values (2, 0, 0.0, '');
|
|
14
|
+
insert into mk values (3, -5, -3.14, 'hello');
|
|
15
|
+
insert into mk values (4, 42, 2.718, 'world');
|
|
16
|
+
|
|
17
|
+
-- ============================================================
|
|
18
|
+
-- scalar.ts: abs
|
|
19
|
+
-- ============================================================
|
|
20
|
+
|
|
21
|
+
-- Kill: remove "if (arg === null) return null" guard
|
|
22
|
+
select abs(v_int) as r from mk where id = 1;
|
|
23
|
+
→ [{"r":null}]
|
|
24
|
+
|
|
25
|
+
-- Kill: abs(0) must return 0, not null (guards n<0 vs n<=0 mutations)
|
|
26
|
+
select abs(v_int) as r from mk where id = 2;
|
|
27
|
+
→ [{"r":0}]
|
|
28
|
+
|
|
29
|
+
-- Kill: abs of negative integer
|
|
30
|
+
select abs(v_int) as r from mk where id = 3;
|
|
31
|
+
→ [{"r":5}]
|
|
32
|
+
|
|
33
|
+
-- Kill: abs of positive integer unchanged
|
|
34
|
+
select abs(v_int) as r from mk where id = 4;
|
|
35
|
+
→ [{"r":42}]
|
|
36
|
+
|
|
37
|
+
-- Kill: abs of negative real
|
|
38
|
+
select abs(v_real) as r from mk where id = 3;
|
|
39
|
+
→ [{"r":3.14}]
|
|
40
|
+
|
|
41
|
+
-- Kill: abs(0.0) must return 0
|
|
42
|
+
select abs(v_real) as r from mk where id = 2;
|
|
43
|
+
→ [{"r":0}]
|
|
44
|
+
|
|
45
|
+
-- ============================================================
|
|
46
|
+
-- scalar.ts: round
|
|
47
|
+
-- ============================================================
|
|
48
|
+
|
|
49
|
+
-- Kill: remove null guard for first argument
|
|
50
|
+
select round(v_real) as r from mk where id = 1;
|
|
51
|
+
→ [{"r":null}]
|
|
52
|
+
|
|
53
|
+
-- Kill: round(0.0) must be 0, not null
|
|
54
|
+
select round(v_real) as r from mk where id = 2;
|
|
55
|
+
→ [{"r":0}]
|
|
56
|
+
|
|
57
|
+
-- Kill: round with explicit 0 decimal places
|
|
58
|
+
select round(v_real, 0) as r from mk where id = 3;
|
|
59
|
+
→ [{"r":-3}]
|
|
60
|
+
|
|
61
|
+
-- Kill: round with negative precision
|
|
62
|
+
select round(12345, -3) as r;
|
|
63
|
+
→ [{"r":12000}]
|
|
64
|
+
|
|
65
|
+
-- Kill: round(x, null) treats null places as 0
|
|
66
|
+
select round(3.7, null) as r;
|
|
67
|
+
→ [{"r":4}]
|
|
68
|
+
|
|
69
|
+
-- ============================================================
|
|
70
|
+
-- scalar.ts: sqrt
|
|
71
|
+
-- ============================================================
|
|
72
|
+
|
|
73
|
+
-- Kill: remove null guard
|
|
74
|
+
select sqrt(v_real) as r from mk where id = 1;
|
|
75
|
+
→ [{"r":null}]
|
|
76
|
+
|
|
77
|
+
-- Kill: sqrt(0) must return 0, not null (guards num < 0 vs num <= 0)
|
|
78
|
+
select sqrt(0) as r;
|
|
79
|
+
→ [{"r":0}]
|
|
80
|
+
|
|
81
|
+
-- Kill: sqrt of negative returns null
|
|
82
|
+
select sqrt(-4) as r;
|
|
83
|
+
→ [{"r":null}]
|
|
84
|
+
|
|
85
|
+
-- Kill: sqrt of perfect square
|
|
86
|
+
select sqrt(25) as r;
|
|
87
|
+
→ [{"r":5}]
|
|
88
|
+
|
|
89
|
+
-- ============================================================
|
|
90
|
+
-- scalar.ts: pow / power
|
|
91
|
+
-- ============================================================
|
|
92
|
+
|
|
93
|
+
-- Kill: null propagation in base
|
|
94
|
+
select pow(v_real, 2) as r from mk where id = 1;
|
|
95
|
+
→ [{"r":null}]
|
|
96
|
+
|
|
97
|
+
-- Kill: null propagation in exponent
|
|
98
|
+
select pow(2, v_real) as r from mk where id = 1;
|
|
99
|
+
→ [{"r":null}]
|
|
100
|
+
|
|
101
|
+
-- Kill: pow(0, 0) = 1 (JavaScript Math.pow behavior)
|
|
102
|
+
select pow(0, 0) as r;
|
|
103
|
+
→ [{"r":1}]
|
|
104
|
+
|
|
105
|
+
-- Kill: pow(x, 1) = x
|
|
106
|
+
select pow(7, 1) as r;
|
|
107
|
+
→ [{"r":7}]
|
|
108
|
+
|
|
109
|
+
-- Kill: pow with negative base, even exponent
|
|
110
|
+
select pow(-3, 2) as r;
|
|
111
|
+
→ [{"r":9}]
|
|
112
|
+
|
|
113
|
+
-- Kill: pow with negative base, odd exponent
|
|
114
|
+
select pow(-2, 3) as r;
|
|
115
|
+
→ [{"r":-8}]
|
|
116
|
+
|
|
117
|
+
-- ============================================================
|
|
118
|
+
-- scalar.ts: floor / ceil
|
|
119
|
+
-- ============================================================
|
|
120
|
+
|
|
121
|
+
-- Kill: floor null guard
|
|
122
|
+
select floor(v_real) as r from mk where id = 1;
|
|
123
|
+
→ [{"r":null}]
|
|
124
|
+
|
|
125
|
+
-- Kill: ceil null guard
|
|
126
|
+
select ceil(v_real) as r from mk where id = 1;
|
|
127
|
+
→ [{"r":null}]
|
|
128
|
+
|
|
129
|
+
-- Kill: floor(0.0) = 0 (not null)
|
|
130
|
+
select floor(0.0) as r;
|
|
131
|
+
→ [{"r":0}]
|
|
132
|
+
|
|
133
|
+
-- Kill: ceil(0.0) = 0 (not null)
|
|
134
|
+
select ceil(0.0) as r;
|
|
135
|
+
→ [{"r":0}]
|
|
136
|
+
|
|
137
|
+
-- Kill: floor of negative fraction rounds toward negative infinity
|
|
138
|
+
select floor(-0.1) as r;
|
|
139
|
+
→ [{"r":-1}]
|
|
140
|
+
|
|
141
|
+
-- Kill: ceil of negative fraction rounds toward zero (JS: -0 == 0)
|
|
142
|
+
select ceil(-0.1) = 0 as r;
|
|
143
|
+
→ [{"r":true}]
|
|
144
|
+
|
|
145
|
+
-- Kill: floor of positive fraction rounds toward zero
|
|
146
|
+
select floor(0.9) as r;
|
|
147
|
+
→ [{"r":0}]
|
|
148
|
+
|
|
149
|
+
-- Kill: ceil of positive fraction rounds toward positive infinity
|
|
150
|
+
select ceil(0.1) as r;
|
|
151
|
+
→ [{"r":1}]
|
|
152
|
+
|
|
153
|
+
-- Kill: ceiling is alias for ceil
|
|
154
|
+
select ceiling(2.3) as r;
|
|
155
|
+
→ [{"r":3}]
|
|
156
|
+
|
|
157
|
+
-- ============================================================
|
|
158
|
+
-- scalar.ts: clamp
|
|
159
|
+
-- ============================================================
|
|
160
|
+
|
|
161
|
+
-- Kill: value exactly at min boundary
|
|
162
|
+
select clamp(0, 0, 10) as r;
|
|
163
|
+
→ [{"r":0}]
|
|
164
|
+
|
|
165
|
+
-- Kill: value exactly at max boundary
|
|
166
|
+
select clamp(10, 0, 10) as r;
|
|
167
|
+
→ [{"r":10}]
|
|
168
|
+
|
|
169
|
+
-- Kill: value one below min
|
|
170
|
+
select clamp(-1, 0, 10) as r;
|
|
171
|
+
→ [{"r":0}]
|
|
172
|
+
|
|
173
|
+
-- Kill: value one above max
|
|
174
|
+
select clamp(11, 0, 10) as r;
|
|
175
|
+
→ [{"r":10}]
|
|
176
|
+
|
|
177
|
+
-- Kill: min == max, value equal
|
|
178
|
+
select clamp(5, 5, 5) as r;
|
|
179
|
+
→ [{"r":5}]
|
|
180
|
+
|
|
181
|
+
-- Kill: min == max, value below
|
|
182
|
+
select clamp(3, 5, 5) as r;
|
|
183
|
+
→ [{"r":5}]
|
|
184
|
+
|
|
185
|
+
-- Kill: min == max, value above
|
|
186
|
+
select clamp(7, 5, 5) as r;
|
|
187
|
+
→ [{"r":5}]
|
|
188
|
+
|
|
189
|
+
-- ============================================================
|
|
190
|
+
-- scalar.ts: coalesce
|
|
191
|
+
-- ============================================================
|
|
192
|
+
|
|
193
|
+
-- Kill: single non-null arg returns it (not null)
|
|
194
|
+
select coalesce(42) as r;
|
|
195
|
+
→ [{"r":42}]
|
|
196
|
+
|
|
197
|
+
-- Kill: all null returns null
|
|
198
|
+
select coalesce(null, null) as r;
|
|
199
|
+
→ [{"r":null}]
|
|
200
|
+
|
|
201
|
+
-- Kill: first non-null wins (not second, not last)
|
|
202
|
+
select coalesce(null, 'first', 'second') as r;
|
|
203
|
+
→ [{"r":"first"}]
|
|
204
|
+
|
|
205
|
+
-- Kill: zero is non-null (not treated as falsy)
|
|
206
|
+
select coalesce(null, 0) as r;
|
|
207
|
+
→ [{"r":0}]
|
|
208
|
+
|
|
209
|
+
-- Kill: empty string is non-null
|
|
210
|
+
select coalesce(null, '') as r;
|
|
211
|
+
→ [{"r":""}]
|
|
212
|
+
|
|
213
|
+
-- Kill: false is non-null
|
|
214
|
+
select coalesce(null, false) as r;
|
|
215
|
+
→ [{"r":false}]
|
|
216
|
+
|
|
217
|
+
-- ============================================================
|
|
218
|
+
-- scalar.ts: nullif
|
|
219
|
+
-- ============================================================
|
|
220
|
+
|
|
221
|
+
-- Kill: nullif returns null when args equal
|
|
222
|
+
select nullif(5, 5) as r;
|
|
223
|
+
→ [{"r":null}]
|
|
224
|
+
|
|
225
|
+
-- Kill: nullif returns first arg when different
|
|
226
|
+
select nullif(5, 10) as r;
|
|
227
|
+
→ [{"r":5}]
|
|
228
|
+
|
|
229
|
+
-- Kill: nullif with zero — 0 equals 0
|
|
230
|
+
select nullif(0, 0) as r;
|
|
231
|
+
→ [{"r":null}]
|
|
232
|
+
|
|
233
|
+
-- Kill: nullif with zero and non-zero
|
|
234
|
+
select nullif(0, 1) as r;
|
|
235
|
+
→ [{"r":0}]
|
|
236
|
+
|
|
237
|
+
-- Kill: nullif(null, 1) — null first arg
|
|
238
|
+
select nullif(null, 1) as r;
|
|
239
|
+
→ [{"r":null}]
|
|
240
|
+
|
|
241
|
+
-- ============================================================
|
|
242
|
+
-- scalar.ts: iif
|
|
243
|
+
-- ============================================================
|
|
244
|
+
|
|
245
|
+
-- Kill: iif with bigint-like large integer condition (truthy)
|
|
246
|
+
select iif(999999, 'yes', 'no') as r;
|
|
247
|
+
→ [{"r":"yes"}]
|
|
248
|
+
|
|
249
|
+
-- Kill: iif with negative number (truthy, not zero)
|
|
250
|
+
select iif(-1, 'yes', 'no') as r;
|
|
251
|
+
→ [{"r":"yes"}]
|
|
252
|
+
|
|
253
|
+
-- Kill: iif with string '0' is falsy
|
|
254
|
+
select iif('0', 'yes', 'no') as r;
|
|
255
|
+
→ [{"r":"no"}]
|
|
256
|
+
|
|
257
|
+
-- Kill: iif with string '1' is truthy
|
|
258
|
+
select iif('1', 'yes', 'no') as r;
|
|
259
|
+
→ [{"r":"yes"}]
|
|
260
|
+
|
|
261
|
+
-- Kill: iif with non-numeric string is falsy (NaN → false)
|
|
262
|
+
select iif('abc', 'yes', 'no') as r;
|
|
263
|
+
→ [{"r":"no"}]
|
|
264
|
+
|
|
265
|
+
-- Kill: iif returns the actual value of the branch (not boolean)
|
|
266
|
+
select iif(1, 42, 99) as r;
|
|
267
|
+
→ [{"r":42}]
|
|
268
|
+
|
|
269
|
+
select iif(0, 42, 99) as r;
|
|
270
|
+
→ [{"r":99}]
|
|
271
|
+
|
|
272
|
+
-- ============================================================
|
|
273
|
+
-- scalar.ts: choose
|
|
274
|
+
-- ============================================================
|
|
275
|
+
|
|
276
|
+
-- Kill: index 1 returns first value arg
|
|
277
|
+
select choose(1, 'a', 'b', 'c') as r;
|
|
278
|
+
→ [{"r":"a"}]
|
|
279
|
+
|
|
280
|
+
-- Kill: index 3 returns last value arg
|
|
281
|
+
select choose(3, 'a', 'b', 'c') as r;
|
|
282
|
+
→ [{"r":"c"}]
|
|
283
|
+
|
|
284
|
+
-- Kill: index 0 out of range (1-based)
|
|
285
|
+
select choose(0, 'a', 'b') as r;
|
|
286
|
+
→ [{"r":null}]
|
|
287
|
+
|
|
288
|
+
-- Kill: index beyond length returns null
|
|
289
|
+
select choose(4, 'a', 'b', 'c') as r;
|
|
290
|
+
→ [{"r":null}]
|
|
291
|
+
|
|
292
|
+
-- Kill: negative index returns null
|
|
293
|
+
select choose(-1, 'a') as r;
|
|
294
|
+
→ [{"r":null}]
|
|
295
|
+
|
|
296
|
+
-- ============================================================
|
|
297
|
+
-- scalar.ts: greatest / least
|
|
298
|
+
-- ============================================================
|
|
299
|
+
|
|
300
|
+
-- Kill: greatest with all nulls returns null (not first arg)
|
|
301
|
+
select greatest(null, null, null) as r;
|
|
302
|
+
→ [{"r":null}]
|
|
303
|
+
|
|
304
|
+
-- Kill: greatest skips nulls and finds max
|
|
305
|
+
select greatest(null, 5, null, 3) as r;
|
|
306
|
+
→ [{"r":5}]
|
|
307
|
+
|
|
308
|
+
-- Kill: least with all nulls returns null
|
|
309
|
+
select least(null, null) as r;
|
|
310
|
+
→ [{"r":null}]
|
|
311
|
+
|
|
312
|
+
-- Kill: least skips nulls and finds min
|
|
313
|
+
select least(null, 5, null, 3) as r;
|
|
314
|
+
→ [{"r":3}]
|
|
315
|
+
|
|
316
|
+
-- Kill: least with negative values
|
|
317
|
+
select least(-10, -5, 0) as r;
|
|
318
|
+
→ [{"r":-10}]
|
|
319
|
+
|
|
320
|
+
-- Kill: greatest with negative values
|
|
321
|
+
select greatest(-10, -5, 0) as r;
|
|
322
|
+
→ [{"r":0}]
|
|
323
|
+
|
|
324
|
+
-- Kill: single-element greatest/least
|
|
325
|
+
select greatest(7) as g, least(7) as l;
|
|
326
|
+
→ [{"g":7,"l":7}]
|
|
327
|
+
|
|
328
|
+
-- ============================================================
|
|
329
|
+
-- string.ts: length
|
|
330
|
+
-- ============================================================
|
|
331
|
+
|
|
332
|
+
-- Kill: length(null) returns null
|
|
333
|
+
select length(v_text) as r from mk where id = 1;
|
|
334
|
+
→ [{"r":null}]
|
|
335
|
+
|
|
336
|
+
-- Kill: length('') returns 0, not null
|
|
337
|
+
select length(v_text) as r from mk where id = 2;
|
|
338
|
+
→ [{"r":0}]
|
|
339
|
+
|
|
340
|
+
-- Kill: length of non-empty string
|
|
341
|
+
select length(v_text) as r from mk where id = 3;
|
|
342
|
+
→ [{"r":5}]
|
|
343
|
+
|
|
344
|
+
-- ============================================================
|
|
345
|
+
-- string.ts: substr
|
|
346
|
+
-- ============================================================
|
|
347
|
+
|
|
348
|
+
-- Kill: substr(null, ...) returns null
|
|
349
|
+
select substr(v_text, 1) as r from mk where id = 1;
|
|
350
|
+
→ [{"r":null}]
|
|
351
|
+
|
|
352
|
+
-- Kill: substr with null start returns null
|
|
353
|
+
select substr('hello', null) as r;
|
|
354
|
+
→ [{"r":null}]
|
|
355
|
+
|
|
356
|
+
-- Kill: substr start=1 returns full string (1-based indexing)
|
|
357
|
+
select substr('hello', 1) as r;
|
|
358
|
+
→ [{"r":"hello"}]
|
|
359
|
+
|
|
360
|
+
-- Kill: substr start=1 len=0 returns empty string
|
|
361
|
+
select substr('hello', 1, 0) as r;
|
|
362
|
+
→ [{"r":""}]
|
|
363
|
+
|
|
364
|
+
-- Kill: substr on empty string
|
|
365
|
+
select substr('', 1) as r;
|
|
366
|
+
→ [{"r":""}]
|
|
367
|
+
|
|
368
|
+
-- Kill: substr start past end of string
|
|
369
|
+
select substr('hi', 5) as r;
|
|
370
|
+
→ [{"r":""}]
|
|
371
|
+
|
|
372
|
+
-- Kill: substr start=1 len=1 gets first character
|
|
373
|
+
select substr('hello', 1, 1) as r;
|
|
374
|
+
→ [{"r":"h"}]
|
|
375
|
+
|
|
376
|
+
-- Kill: substr len longer than remaining string
|
|
377
|
+
select substr('hello', 3, 100) as r;
|
|
378
|
+
→ [{"r":"llo"}]
|
|
379
|
+
|
|
380
|
+
-- ============================================================
|
|
381
|
+
-- string.ts: replace
|
|
382
|
+
-- ============================================================
|
|
383
|
+
|
|
384
|
+
-- Kill: all args null returns null
|
|
385
|
+
select replace(null, null, null) as r;
|
|
386
|
+
→ [{"r":null}]
|
|
387
|
+
|
|
388
|
+
-- Kill: null string returns null
|
|
389
|
+
select replace(null, 'a', 'b') as r;
|
|
390
|
+
→ [{"r":null}]
|
|
391
|
+
|
|
392
|
+
-- Kill: null pattern returns null
|
|
393
|
+
select replace('hello', null, 'b') as r;
|
|
394
|
+
→ [{"r":null}]
|
|
395
|
+
|
|
396
|
+
-- Kill: null replacement returns null
|
|
397
|
+
select replace('hello', 'l', null) as r;
|
|
398
|
+
→ [{"r":null}]
|
|
399
|
+
|
|
400
|
+
-- Kill: empty pattern returns original string unchanged
|
|
401
|
+
select replace('hello', '', 'x') as r;
|
|
402
|
+
→ [{"r":"hello"}]
|
|
403
|
+
|
|
404
|
+
-- Kill: replace when pattern not found returns original
|
|
405
|
+
select replace('hello', 'xyz', 'abc') as r;
|
|
406
|
+
→ [{"r":"hello"}]
|
|
407
|
+
|
|
408
|
+
-- Kill: replace all occurrences (not just first)
|
|
409
|
+
select replace('banana', 'a', 'o') as r;
|
|
410
|
+
→ [{"r":"bonono"}]
|
|
411
|
+
|
|
412
|
+
-- Kill: replace with empty replacement (deletion)
|
|
413
|
+
select replace('hello world', ' world', '') as r;
|
|
414
|
+
→ [{"r":"hello"}]
|
|
415
|
+
|
|
416
|
+
-- ============================================================
|
|
417
|
+
-- string.ts: instr
|
|
418
|
+
-- ============================================================
|
|
419
|
+
|
|
420
|
+
-- Kill: null propagation
|
|
421
|
+
select instr(null, 'a') as r;
|
|
422
|
+
→ [{"r":null}]
|
|
423
|
+
|
|
424
|
+
select instr('hello', null) as r;
|
|
425
|
+
→ [{"r":null}]
|
|
426
|
+
|
|
427
|
+
-- Kill: found at position 1 (not 0)
|
|
428
|
+
select instr('hello', 'h') as r;
|
|
429
|
+
→ [{"r":1}]
|
|
430
|
+
|
|
431
|
+
-- Kill: found at last position
|
|
432
|
+
select instr('hello', 'o') as r;
|
|
433
|
+
→ [{"r":5}]
|
|
434
|
+
|
|
435
|
+
-- Kill: not found returns 0 (not -1, not null)
|
|
436
|
+
select instr('hello', 'z') as r;
|
|
437
|
+
→ [{"r":0}]
|
|
438
|
+
|
|
439
|
+
-- Kill: empty substring returns 0
|
|
440
|
+
select instr('hello', '') as r;
|
|
441
|
+
→ [{"r":0}]
|
|
442
|
+
|
|
443
|
+
-- Kill: empty string searched returns 0
|
|
444
|
+
select instr('', 'a') as r;
|
|
445
|
+
→ [{"r":0}]
|
|
446
|
+
|
|
447
|
+
-- Kill: both empty returns 0
|
|
448
|
+
select instr('', '') as r;
|
|
449
|
+
→ [{"r":0}]
|
|
450
|
+
|
|
451
|
+
-- ============================================================
|
|
452
|
+
-- string.ts: trim / ltrim / rtrim
|
|
453
|
+
-- ============================================================
|
|
454
|
+
|
|
455
|
+
-- Kill: trim(null) returns null
|
|
456
|
+
select trim(null) as r;
|
|
457
|
+
→ [{"r":null}]
|
|
458
|
+
|
|
459
|
+
-- Kill: ltrim(null) returns null
|
|
460
|
+
select ltrim(null) as r;
|
|
461
|
+
→ [{"r":null}]
|
|
462
|
+
|
|
463
|
+
-- Kill: rtrim(null) returns null
|
|
464
|
+
select rtrim(null) as r;
|
|
465
|
+
→ [{"r":null}]
|
|
466
|
+
|
|
467
|
+
-- Kill: trim whitespace from both sides
|
|
468
|
+
select trim(' hello ') as r;
|
|
469
|
+
→ [{"r":"hello"}]
|
|
470
|
+
|
|
471
|
+
-- Kill: ltrim removes left only
|
|
472
|
+
select ltrim(' hello ') as r;
|
|
473
|
+
→ [{"r":"hello "}]
|
|
474
|
+
|
|
475
|
+
-- Kill: rtrim removes right only
|
|
476
|
+
select rtrim(' hello ') as r;
|
|
477
|
+
→ [{"r":" hello"}]
|
|
478
|
+
|
|
479
|
+
-- Kill: trim with no whitespace returns same string
|
|
480
|
+
select trim('hello') as r;
|
|
481
|
+
→ [{"r":"hello"}]
|
|
482
|
+
|
|
483
|
+
-- Kill: trim empty string returns empty
|
|
484
|
+
select trim('') as r;
|
|
485
|
+
→ [{"r":""}]
|
|
486
|
+
|
|
487
|
+
-- Kill: trim with custom chars null → default whitespace trim
|
|
488
|
+
select trim(' hello ', null) as r;
|
|
489
|
+
→ [{"r":"hello"}]
|
|
490
|
+
|
|
491
|
+
-- Kill: ltrim with custom chars
|
|
492
|
+
select ltrim('xxxhello', 'x') as r;
|
|
493
|
+
→ [{"r":"hello"}]
|
|
494
|
+
|
|
495
|
+
-- Kill: rtrim with custom chars
|
|
496
|
+
select rtrim('helloyyy', 'y') as r;
|
|
497
|
+
→ [{"r":"hello"}]
|
|
498
|
+
|
|
499
|
+
-- ============================================================
|
|
500
|
+
-- string.ts: lower / upper
|
|
501
|
+
-- ============================================================
|
|
502
|
+
|
|
503
|
+
-- Kill: lower(null) returns null
|
|
504
|
+
select lower(null) as r;
|
|
505
|
+
→ [{"r":null}]
|
|
506
|
+
|
|
507
|
+
-- Kill: upper(null) returns null
|
|
508
|
+
select upper(null) as r;
|
|
509
|
+
→ [{"r":null}]
|
|
510
|
+
|
|
511
|
+
-- Kill: lower of empty string
|
|
512
|
+
select lower('') as r;
|
|
513
|
+
→ [{"r":""}]
|
|
514
|
+
|
|
515
|
+
-- Kill: upper of empty string
|
|
516
|
+
select upper('') as r;
|
|
517
|
+
→ [{"r":""}]
|
|
518
|
+
|
|
519
|
+
-- Kill: lower of already-lowercase
|
|
520
|
+
select lower('hello') as r;
|
|
521
|
+
→ [{"r":"hello"}]
|
|
522
|
+
|
|
523
|
+
-- Kill: upper of already-uppercase
|
|
524
|
+
select upper('HELLO') as r;
|
|
525
|
+
→ [{"r":"HELLO"}]
|
|
526
|
+
|
|
527
|
+
-- Kill: lower on non-string returns null (not coerced)
|
|
528
|
+
select lower(v_int) as r from mk where id = 4;
|
|
529
|
+
→ [{"r":null}]
|
|
530
|
+
|
|
531
|
+
-- Kill: upper on non-string returns null
|
|
532
|
+
select upper(v_int) as r from mk where id = 4;
|
|
533
|
+
→ [{"r":null}]
|
|
534
|
+
|
|
535
|
+
-- ============================================================
|
|
536
|
+
-- string.ts: reverse
|
|
537
|
+
-- ============================================================
|
|
538
|
+
|
|
539
|
+
-- Kill: reverse of null returns null (non-string → null)
|
|
540
|
+
select reverse(null) as r;
|
|
541
|
+
→ [{"r":null}]
|
|
542
|
+
|
|
543
|
+
-- Kill: reverse of empty string
|
|
544
|
+
select reverse('') as r;
|
|
545
|
+
→ [{"r":""}]
|
|
546
|
+
|
|
547
|
+
-- Kill: reverse of single character
|
|
548
|
+
select reverse('x') as r;
|
|
549
|
+
→ [{"r":"x"}]
|
|
550
|
+
|
|
551
|
+
-- Kill: reverse of palindrome unchanged
|
|
552
|
+
select reverse('aba') as r;
|
|
553
|
+
→ [{"r":"aba"}]
|
|
554
|
+
|
|
555
|
+
-- ============================================================
|
|
556
|
+
-- string.ts: like / glob null propagation
|
|
557
|
+
-- ============================================================
|
|
558
|
+
|
|
559
|
+
-- Kill: like with null text returns null
|
|
560
|
+
select like('a%', null) as r;
|
|
561
|
+
→ [{"r":null}]
|
|
562
|
+
|
|
563
|
+
-- Kill: like with null pattern returns null
|
|
564
|
+
select like(null, 'abc') as r;
|
|
565
|
+
→ [{"r":null}]
|
|
566
|
+
|
|
567
|
+
-- Kill: glob with null text returns null
|
|
568
|
+
select glob('a*', null) as r;
|
|
569
|
+
→ [{"r":null}]
|
|
570
|
+
|
|
571
|
+
-- Kill: glob with null pattern returns null
|
|
572
|
+
select glob(null, 'abc') as r;
|
|
573
|
+
→ [{"r":null}]
|
|
574
|
+
|
|
575
|
+
-- ============================================================
|
|
576
|
+
-- string.ts: lpad / rpad
|
|
577
|
+
-- ============================================================
|
|
578
|
+
|
|
579
|
+
-- Kill: lpad with null string returns null
|
|
580
|
+
select lpad(null, 5, '*') as r;
|
|
581
|
+
→ [{"r":null}]
|
|
582
|
+
|
|
583
|
+
-- Kill: rpad with null string returns null
|
|
584
|
+
select rpad(null, 5, '*') as r;
|
|
585
|
+
→ [{"r":null}]
|
|
586
|
+
|
|
587
|
+
-- Kill: lpad when string already at target length (no padding needed)
|
|
588
|
+
select lpad('hello', 5, '*') as r;
|
|
589
|
+
→ [{"r":"hello"}]
|
|
590
|
+
|
|
591
|
+
-- Kill: rpad when string already at target length
|
|
592
|
+
select rpad('hello', 5, '*') as r;
|
|
593
|
+
→ [{"r":"hello"}]
|
|
594
|
+
|
|
595
|
+
-- Kill: lpad shorter than target
|
|
596
|
+
select lpad('hi', 4, '-') as r;
|
|
597
|
+
→ [{"r":"--hi"}]
|
|
598
|
+
|
|
599
|
+
-- Kill: rpad shorter than target
|
|
600
|
+
select rpad('hi', 4, '-') as r;
|
|
601
|
+
→ [{"r":"hi--"}]
|
|
602
|
+
|
|
603
|
+
-- ============================================================
|
|
604
|
+
-- aggregate.ts: count(*) vs count(X) on empty table
|
|
605
|
+
-- ============================================================
|
|
606
|
+
|
|
607
|
+
create table mk_agg_empty (id integer primary key, val integer null);
|
|
608
|
+
|
|
609
|
+
-- Kill: count(*) on empty table must be 0
|
|
610
|
+
select count(*) as r from mk_agg_empty;
|
|
611
|
+
→ [{"r":0}]
|
|
612
|
+
|
|
613
|
+
-- Kill: count(x) on empty table must be 0
|
|
614
|
+
select count(val) as r from mk_agg_empty;
|
|
615
|
+
→ [{"r":0}]
|
|
616
|
+
|
|
617
|
+
-- Kill: sum on empty table must be null (not 0)
|
|
618
|
+
select sum(val) as r from mk_agg_empty;
|
|
619
|
+
→ [{"r":null}]
|
|
620
|
+
|
|
621
|
+
-- Kill: avg on empty table must be null
|
|
622
|
+
select avg(val) as r from mk_agg_empty;
|
|
623
|
+
→ [{"r":null}]
|
|
624
|
+
|
|
625
|
+
-- Kill: min on empty table must be null
|
|
626
|
+
select min(val) as r from mk_agg_empty;
|
|
627
|
+
→ [{"r":null}]
|
|
628
|
+
|
|
629
|
+
-- Kill: max on empty table must be null
|
|
630
|
+
select max(val) as r from mk_agg_empty;
|
|
631
|
+
→ [{"r":null}]
|
|
632
|
+
|
|
633
|
+
-- Kill: total on empty table must be 0.0 (not null — SQLite compat)
|
|
634
|
+
select total(val) as r from mk_agg_empty;
|
|
635
|
+
→ [{"r":0}]
|
|
636
|
+
|
|
637
|
+
drop table mk_agg_empty;
|
|
638
|
+
|
|
639
|
+
-- ============================================================
|
|
640
|
+
-- aggregate.ts: count(X) skips nulls
|
|
641
|
+
-- ============================================================
|
|
642
|
+
|
|
643
|
+
create table mk_agg_nulls (id integer primary key, val integer null);
|
|
644
|
+
insert into mk_agg_nulls values (1, null), (2, 10), (3, null), (4, 20);
|
|
645
|
+
|
|
646
|
+
-- Kill: count(*) counts all rows including null
|
|
647
|
+
select count(*) as r from mk_agg_nulls;
|
|
648
|
+
→ [{"r":4}]
|
|
649
|
+
|
|
650
|
+
-- Kill: count(val) skips nulls
|
|
651
|
+
select count(val) as r from mk_agg_nulls;
|
|
652
|
+
→ [{"r":2}]
|
|
653
|
+
|
|
654
|
+
-- Kill: sum skips nulls
|
|
655
|
+
select sum(val) as r from mk_agg_nulls;
|
|
656
|
+
→ [{"r":30}]
|
|
657
|
+
|
|
658
|
+
-- Kill: avg skips nulls (30/2 = 15)
|
|
659
|
+
select avg(val) as r from mk_agg_nulls;
|
|
660
|
+
→ [{"r":15}]
|
|
661
|
+
|
|
662
|
+
-- Kill: min skips nulls
|
|
663
|
+
select min(val) as r from mk_agg_nulls;
|
|
664
|
+
→ [{"r":10}]
|
|
665
|
+
|
|
666
|
+
-- Kill: max skips nulls
|
|
667
|
+
select max(val) as r from mk_agg_nulls;
|
|
668
|
+
→ [{"r":20}]
|
|
669
|
+
|
|
670
|
+
drop table mk_agg_nulls;
|
|
671
|
+
|
|
672
|
+
-- ============================================================
|
|
673
|
+
-- aggregate.ts: all-null values
|
|
674
|
+
-- ============================================================
|
|
675
|
+
|
|
676
|
+
create table mk_agg_allnull (id integer primary key, val integer null);
|
|
677
|
+
insert into mk_agg_allnull values (1, null), (2, null);
|
|
678
|
+
|
|
679
|
+
-- Kill: sum of all-null is null (not 0)
|
|
680
|
+
select sum(val) as r from mk_agg_allnull;
|
|
681
|
+
→ [{"r":null}]
|
|
682
|
+
|
|
683
|
+
-- Kill: avg of all-null is null
|
|
684
|
+
select avg(val) as r from mk_agg_allnull;
|
|
685
|
+
→ [{"r":null}]
|
|
686
|
+
|
|
687
|
+
-- Kill: min of all-null is null
|
|
688
|
+
select min(val) as r from mk_agg_allnull;
|
|
689
|
+
→ [{"r":null}]
|
|
690
|
+
|
|
691
|
+
-- Kill: max of all-null is null
|
|
692
|
+
select max(val) as r from mk_agg_allnull;
|
|
693
|
+
→ [{"r":null}]
|
|
694
|
+
|
|
695
|
+
-- Kill: total of all-null is 0 (not null — total never returns null)
|
|
696
|
+
select total(val) as r from mk_agg_allnull;
|
|
697
|
+
→ [{"r":0}]
|
|
698
|
+
|
|
699
|
+
-- Kill: count(val) of all-null is 0
|
|
700
|
+
select count(val) as r from mk_agg_allnull;
|
|
701
|
+
→ [{"r":0}]
|
|
702
|
+
|
|
703
|
+
-- Kill: count(*) counts rows regardless of null values
|
|
704
|
+
select count(*) as r from mk_agg_allnull;
|
|
705
|
+
→ [{"r":2}]
|
|
706
|
+
|
|
707
|
+
drop table mk_agg_allnull;
|
|
708
|
+
|
|
709
|
+
-- ============================================================
|
|
710
|
+
-- aggregate.ts: single-value aggregates
|
|
711
|
+
-- ============================================================
|
|
712
|
+
|
|
713
|
+
create table mk_agg_one (id integer primary key, val real);
|
|
714
|
+
insert into mk_agg_one values (1, 7.5);
|
|
715
|
+
|
|
716
|
+
-- Kill: sum of single value
|
|
717
|
+
select sum(val) as r from mk_agg_one;
|
|
718
|
+
→ [{"r":7.5}]
|
|
719
|
+
|
|
720
|
+
-- Kill: avg of single value equals the value itself
|
|
721
|
+
select avg(val) as r from mk_agg_one;
|
|
722
|
+
→ [{"r":7.5}]
|
|
723
|
+
|
|
724
|
+
-- Kill: min == max for single value
|
|
725
|
+
select min(val) as r, max(val) as r2 from mk_agg_one;
|
|
726
|
+
→ [{"r":7.5,"r2":7.5}]
|
|
727
|
+
|
|
728
|
+
-- Kill: var_pop of single value is 0
|
|
729
|
+
select var_pop(val) as r from mk_agg_one;
|
|
730
|
+
→ [{"r":0}]
|
|
731
|
+
|
|
732
|
+
-- Kill: var_samp of single value is null (needs n > 1)
|
|
733
|
+
select var_samp(val) as r from mk_agg_one;
|
|
734
|
+
→ [{"r":null}]
|
|
735
|
+
|
|
736
|
+
-- Kill: stddev_pop of single value is 0
|
|
737
|
+
select stddev_pop(val) as r from mk_agg_one;
|
|
738
|
+
→ [{"r":0}]
|
|
739
|
+
|
|
740
|
+
-- Kill: stddev_samp of single value is null
|
|
741
|
+
select stddev_samp(val) as r from mk_agg_one;
|
|
742
|
+
→ [{"r":null}]
|
|
743
|
+
|
|
744
|
+
drop table mk_agg_one;
|
|
745
|
+
|
|
746
|
+
-- ============================================================
|
|
747
|
+
-- aggregate.ts: statistical functions on empty set
|
|
748
|
+
-- ============================================================
|
|
749
|
+
|
|
750
|
+
create table mk_agg_stat_empty (id integer primary key, val real null);
|
|
751
|
+
|
|
752
|
+
select var_pop(val) as r from mk_agg_stat_empty;
|
|
753
|
+
→ [{"r":null}]
|
|
754
|
+
|
|
755
|
+
select var_samp(val) as r from mk_agg_stat_empty;
|
|
756
|
+
→ [{"r":null}]
|
|
757
|
+
|
|
758
|
+
select stddev_pop(val) as r from mk_agg_stat_empty;
|
|
759
|
+
→ [{"r":null}]
|
|
760
|
+
|
|
761
|
+
select stddev_samp(val) as r from mk_agg_stat_empty;
|
|
762
|
+
→ [{"r":null}]
|
|
763
|
+
|
|
764
|
+
drop table mk_agg_stat_empty;
|
|
765
|
+
|
|
766
|
+
-- ============================================================
|
|
767
|
+
-- aggregate.ts: two-value var_samp (not null, unlike single-value)
|
|
768
|
+
-- ============================================================
|
|
769
|
+
|
|
770
|
+
create table mk_agg_two (id integer primary key, val real);
|
|
771
|
+
insert into mk_agg_two values (1, 10.0), (2, 20.0);
|
|
772
|
+
|
|
773
|
+
-- var_samp([10, 20]) = (sumSq - sum*sum/n) / (n-1)
|
|
774
|
+
-- = (100+400 - 900/2) / 1 = (500 - 450) / 1 = 50
|
|
775
|
+
select var_samp(val) as r from mk_agg_two;
|
|
776
|
+
→ [{"r":50}]
|
|
777
|
+
|
|
778
|
+
-- stddev_samp([10, 20]) = sqrt(50)
|
|
779
|
+
select stddev_samp(val) as r from mk_agg_two;
|
|
780
|
+
→ [{"r":7.0710678118654755}]
|
|
781
|
+
|
|
782
|
+
drop table mk_agg_two;
|
|
783
|
+
|
|
784
|
+
-- ============================================================
|
|
785
|
+
-- aggregate.ts: total always returns 0 for non-numeric
|
|
786
|
+
-- ============================================================
|
|
787
|
+
|
|
788
|
+
create table mk_total_text (id integer primary key, val text);
|
|
789
|
+
insert into mk_total_text values (1, 'hello'), (2, 'world');
|
|
790
|
+
|
|
791
|
+
-- Kill: total of non-numeric text → 0 (NaN treated as 0)
|
|
792
|
+
select total(val) as r from mk_total_text;
|
|
793
|
+
→ [{"r":0}]
|
|
794
|
+
|
|
795
|
+
drop table mk_total_text;
|
|
796
|
+
|
|
797
|
+
-- ============================================================
|
|
798
|
+
-- aggregate.ts: total with mixed numeric strings
|
|
799
|
+
-- ============================================================
|
|
800
|
+
|
|
801
|
+
create table mk_total_mixed (id integer primary key, val text null);
|
|
802
|
+
insert into mk_total_mixed values (1, '10'), (2, 'abc'), (3, '20'), (4, null);
|
|
803
|
+
|
|
804
|
+
-- Kill: total coerces numeric strings, treats non-numeric as 0, skips null
|
|
805
|
+
select total(val) as r from mk_total_mixed;
|
|
806
|
+
→ [{"r":30}]
|
|
807
|
+
|
|
808
|
+
drop table mk_total_mixed;
|
|
809
|
+
|
|
810
|
+
-- ============================================================
|
|
811
|
+
-- aggregate.ts: group_concat
|
|
812
|
+
-- ============================================================
|
|
813
|
+
|
|
814
|
+
create table mk_gc (id integer primary key, val text null);
|
|
815
|
+
insert into mk_gc values (1, 'a'), (2, null), (3, 'b'), (4, 'c');
|
|
816
|
+
|
|
817
|
+
-- Kill: group_concat with default separator (comma)
|
|
818
|
+
select group_concat(val) as r from mk_gc;
|
|
819
|
+
→ [{"r":"a,b,c"}]
|
|
820
|
+
|
|
821
|
+
-- Kill: group_concat skips nulls
|
|
822
|
+
select group_concat(val, '-') as r from mk_gc;
|
|
823
|
+
→ [{"r":"a-b-c"}]
|
|
824
|
+
|
|
825
|
+
-- Kill: group_concat empty separator joins directly
|
|
826
|
+
select group_concat(val, '') as r from mk_gc;
|
|
827
|
+
→ [{"r":"abc"}]
|
|
828
|
+
|
|
829
|
+
drop table mk_gc;
|
|
830
|
+
|
|
831
|
+
-- ============================================================
|
|
832
|
+
-- aggregate.ts: group_concat all nulls returns null
|
|
833
|
+
-- ============================================================
|
|
834
|
+
|
|
835
|
+
create table mk_gc_null (id integer primary key, val text null);
|
|
836
|
+
insert into mk_gc_null values (1, null), (2, null);
|
|
837
|
+
|
|
838
|
+
select group_concat(val) as r from mk_gc_null;
|
|
839
|
+
→ [{"r":null}]
|
|
840
|
+
|
|
841
|
+
drop table mk_gc_null;
|
|
842
|
+
|
|
843
|
+
-- ============================================================
|
|
844
|
+
-- conversion.ts: null handling for all conversion functions
|
|
845
|
+
-- ============================================================
|
|
846
|
+
|
|
847
|
+
select integer(null) as r;
|
|
848
|
+
→ [{"r":null}]
|
|
849
|
+
|
|
850
|
+
select real(null) as r;
|
|
851
|
+
→ [{"r":null}]
|
|
852
|
+
|
|
853
|
+
select text(null) as r;
|
|
854
|
+
→ [{"r":null}]
|
|
855
|
+
|
|
856
|
+
select boolean(null) as r;
|
|
857
|
+
→ [{"r":null}]
|
|
858
|
+
|
|
859
|
+
-- ============================================================
|
|
860
|
+
-- conversion.ts: identity conversions (already correct type)
|
|
861
|
+
-- ============================================================
|
|
862
|
+
|
|
863
|
+
select integer(42) as r;
|
|
864
|
+
→ [{"r":42}]
|
|
865
|
+
|
|
866
|
+
select real(3.14) as r;
|
|
867
|
+
→ [{"r":3.14}]
|
|
868
|
+
|
|
869
|
+
select text('hello') as r;
|
|
870
|
+
→ [{"r":"hello"}]
|
|
871
|
+
|
|
872
|
+
select boolean(true) as r;
|
|
873
|
+
→ [{"r":true}]
|
|
874
|
+
|
|
875
|
+
select boolean(false) as r;
|
|
876
|
+
→ [{"r":false}]
|
|
877
|
+
|
|
878
|
+
-- ============================================================
|
|
879
|
+
-- conversion.ts: cross-type conversions
|
|
880
|
+
-- ============================================================
|
|
881
|
+
|
|
882
|
+
-- Kill: integer from real truncates
|
|
883
|
+
select integer(3.9) as r;
|
|
884
|
+
→ [{"r":3}]
|
|
885
|
+
|
|
886
|
+
-- Kill: integer from negative real truncates toward zero
|
|
887
|
+
select integer(-3.9) as r;
|
|
888
|
+
→ [{"r":-3}]
|
|
889
|
+
|
|
890
|
+
-- Kill: integer from string
|
|
891
|
+
select integer('42') as r;
|
|
892
|
+
→ [{"r":42}]
|
|
893
|
+
|
|
894
|
+
-- Kill: integer from true/false
|
|
895
|
+
select integer(true) as r;
|
|
896
|
+
→ [{"r":1}]
|
|
897
|
+
|
|
898
|
+
select integer(false) as r;
|
|
899
|
+
→ [{"r":0}]
|
|
900
|
+
|
|
901
|
+
-- Kill: integer(0) is not null
|
|
902
|
+
select integer(0) as r;
|
|
903
|
+
→ [{"r":0}]
|
|
904
|
+
|
|
905
|
+
-- Kill: real from integer
|
|
906
|
+
select real(42) as r;
|
|
907
|
+
→ [{"r":42}]
|
|
908
|
+
|
|
909
|
+
-- Kill: real from string
|
|
910
|
+
select real('3.14') as r;
|
|
911
|
+
→ [{"r":3.14}]
|
|
912
|
+
|
|
913
|
+
-- Kill: text from integer
|
|
914
|
+
select text(42) as r;
|
|
915
|
+
→ [{"r":"42"}]
|
|
916
|
+
|
|
917
|
+
-- Kill: text from real
|
|
918
|
+
select text(3.14) as r;
|
|
919
|
+
→ [{"r":"3.14"}]
|
|
920
|
+
|
|
921
|
+
-- Kill: text from boolean
|
|
922
|
+
select text(true) as r;
|
|
923
|
+
→ [{"r":"true"}]
|
|
924
|
+
|
|
925
|
+
select text(false) as r;
|
|
926
|
+
→ [{"r":"false"}]
|
|
927
|
+
|
|
928
|
+
-- Kill: text of zero
|
|
929
|
+
select text(0) as r;
|
|
930
|
+
→ [{"r":"0"}]
|
|
931
|
+
|
|
932
|
+
-- Kill: text of empty string is empty string
|
|
933
|
+
select text('') as r;
|
|
934
|
+
→ [{"r":""}]
|
|
935
|
+
|
|
936
|
+
-- Kill: boolean from 1 and 0
|
|
937
|
+
select boolean(1) as r;
|
|
938
|
+
→ [{"r":true}]
|
|
939
|
+
|
|
940
|
+
select boolean(0) as r;
|
|
941
|
+
→ [{"r":false}]
|
|
942
|
+
|
|
943
|
+
-- Kill: boolean from 'yes'/'no'
|
|
944
|
+
select boolean('yes') as r;
|
|
945
|
+
→ [{"r":true}]
|
|
946
|
+
|
|
947
|
+
select boolean('no') as r;
|
|
948
|
+
→ [{"r":false}]
|
|
949
|
+
|
|
950
|
+
-- Kill: boolean from 'on'/'off'
|
|
951
|
+
select boolean('on') as r;
|
|
952
|
+
→ [{"r":true}]
|
|
953
|
+
|
|
954
|
+
select boolean('off') as r;
|
|
955
|
+
→ [{"r":false}]
|
|
956
|
+
|
|
957
|
+
-- ============================================================
|
|
958
|
+
-- conversion.ts: error paths
|
|
959
|
+
-- ============================================================
|
|
960
|
+
|
|
961
|
+
select integer('not_a_number');
|
|
962
|
+
-- error: Cannot convert to INTEGER
|
|
963
|
+
|
|
964
|
+
select real('not_a_number');
|
|
965
|
+
-- error: Cannot convert to REAL
|
|
966
|
+
|
|
967
|
+
select boolean('maybe');
|
|
968
|
+
-- error: Cannot convert to BOOLEAN
|
|
969
|
+
|
|
970
|
+
-- ============================================================
|
|
971
|
+
-- CLEANUP
|
|
972
|
+
-- ============================================================
|
|
973
|
+
|
|
974
|
+
drop table mk;
|