@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
package/test/README.md
ADDED
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
# Quereus Tests
|
|
2
|
+
|
|
3
|
+
Tests for the Quereus engine. Most behavior is exercised through SQL logic tests; lower-level unit tests live alongside in subdirectories.
|
|
4
|
+
|
|
5
|
+
## Layout
|
|
6
|
+
|
|
7
|
+
| Path | What lives there |
|
|
8
|
+
|---|---|
|
|
9
|
+
| `logic/*.sqllogic` | Primary regression suite — black-box SQL with expected results. Runner is `logic.spec.ts`. |
|
|
10
|
+
| `plan/` | Optimizer plan-shape and golden-plan tests. See `plan/README.md`. |
|
|
11
|
+
| `optimizer/` | Per-rule optimizer unit tests (pushdown, joins, aggregate strategy, statistics, etc.). |
|
|
12
|
+
| `planner/` | Planner framework, cost model, predicate normalization, validation, stats. |
|
|
13
|
+
| `runtime/` | Runtime emitter and execution unit tests (caches, scan emitter, temporal arithmetic, shadow DDL). |
|
|
14
|
+
| `schema/` | Catalog and schema-differ tests. |
|
|
15
|
+
| `vtab/` | Virtual-table contract tests (best-access plan, events, scan bounds, remote disconnect). |
|
|
16
|
+
| `core/` | Core database/options API tests. |
|
|
17
|
+
| `cross-platform/` | Browser and environment-compatibility checks. |
|
|
18
|
+
| `util/` | Pure utility tests (hash, hrtime, plugin helpers, mutation-statement). |
|
|
19
|
+
| `*.spec.ts` (top level) | Cross-cutting suites: parser, type system, fuzz, property, lifecycle, multi-statement, exports, capabilities, performance sentinels, etc. |
|
|
20
|
+
|
|
21
|
+
## Running tests
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
yarn test # default — memory vtab; this is what agents should run
|
|
25
|
+
yarn test:store # re-run logic suite against the LevelDB store module
|
|
26
|
+
yarn test:full # both (only for store-specific diagnosis or release prep)
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Diagnostics for logic-test failures (flags are picked up by `logic.spec.ts`):
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
yarn test --show-plan # concise query plan
|
|
33
|
+
yarn test --plan-summary # one-line execution path
|
|
34
|
+
yarn test --plan-full-detail # full plan as JSON
|
|
35
|
+
yarn test --show-plan --expand-nodes "node1,node2" # expand specific nodes
|
|
36
|
+
yarn test --show-plan --max-plan-depth 3 # cap plan depth
|
|
37
|
+
yarn test --show-program # instruction program
|
|
38
|
+
yarn test --show-trace # execution trace
|
|
39
|
+
yarn test --trace-plan-stack # plan stack tracing in runtime
|
|
40
|
+
yarn test --show-stack # full stack traces
|
|
41
|
+
yarn test --verbose # verbose progress
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
`DEBUG=quereus:...` enables namespaced log output. To run a single ad-hoc spec without the workspace harness:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
node --import ./packages/quereus/register.mjs node_modules/mocha/bin/mocha.js 'packages/quereus/test/**/*.spec.ts' --colors --bail
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Logic-test conventions
|
|
51
|
+
|
|
52
|
+
- `→ [expected_json_results]` marks expected rows.
|
|
53
|
+
- `-- error: <substring>` marks expected errors.
|
|
54
|
+
- `-- requires-capability: <tokens>` declares database features the file needs; a backend that lacks one skips the whole file. See below.
|
|
55
|
+
- Lowercase SQL keywords. Match the existing fixtures' style.
|
|
56
|
+
- Inside a file, order scenarios **mundane → exotic** so the most general failure surfaces first.
|
|
57
|
+
- File names carry a numeric prefix that places them in run order. The same mundane → exotic principle applies across files. Anchors:
|
|
58
|
+
- `01–17` — feature basics (parser, expressions, transactions, vtab, builtins, aggregates, joins, set ops, CTEs, temporal).
|
|
59
|
+
- `20–29` — feature edge cases (NULL, boundaries, self-join duplicates).
|
|
60
|
+
- `40–50` — semantics-heavy features (constraints, FKs, generated cols, RETURNING, declarative schema, assertions).
|
|
61
|
+
- `80–86` — optimizer / plan-shape concerns.
|
|
62
|
+
- `90–99`, `100+` — error paths, exotic edge cases, mutation kills.
|
|
63
|
+
- Use a decimal sub-number to slot between adjacent files (`06.2.1-…` between `06.2-…` and `06.3-…`); don't renumber existing files.
|
|
64
|
+
- Tests represent expected behavior when features are fully implemented. A failing test is a roadmap item, not a regression to silence.
|
|
65
|
+
|
|
66
|
+
### `-- requires-capability:` directive
|
|
67
|
+
|
|
68
|
+
`logic/*.sqllogic` is a **shared corpus** — other projects run the same files against their own storage
|
|
69
|
+
engine. When a file's *subject* is a feature a backend deliberately does not implement, that file should
|
|
70
|
+
skip there. Rather than have every consumer hand-maintain an O(corpus) list of file names, the file
|
|
71
|
+
declares what it needs and each harness declares once what its backend has.
|
|
72
|
+
|
|
73
|
+
**This section is the format spec, and the format is the cross-repo contract** — downstream harnesses
|
|
74
|
+
reimplement the ~10-line parse against it. Quereus's own implementation is `test/logic-capabilities.ts`
|
|
75
|
+
(not published — the npm package ships the corpus and this README, not the harness or compiled tests;
|
|
76
|
+
see [Consuming the corpus from the npm package](#consuming-the-corpus-from-the-npm-package)).
|
|
77
|
+
|
|
78
|
+
Grammar — the directive lives in the file's **leading comment block**, before the first line that is
|
|
79
|
+
neither blank nor a `--` comment:
|
|
80
|
+
|
|
81
|
+
```
|
|
82
|
+
-- Row-validating DDL inside an open transaction.
|
|
83
|
+
-- requires-capability: standalone-index-ddl
|
|
84
|
+
|
|
85
|
+
create table ddl_tx_a (id integer primary key, v text);
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
- Canonical line shape after trimming: `-- requires-capability: <tokens>`. The directive name matches
|
|
89
|
+
case-insensitively; tokens are lowercased before lookup.
|
|
90
|
+
- `<tokens>` is one or more tokens separated by whitespace and/or commas.
|
|
91
|
+
- The directive may appear on several lines; the declared sets **union**. Duplicate tokens are fine.
|
|
92
|
+
- **No trailing comment on a directive line** — the whole remainder is read as tokens, so
|
|
93
|
+
`-- requires-capability: x -- why` errors on `--` and `why`.
|
|
94
|
+
- Granularity is **whole file**; there is no section-scoped form. If only part of a file needs a
|
|
95
|
+
capability and the rest is worth running elsewhere, **split the file** (`10.5.2-…` style decimal
|
|
96
|
+
sub-numbering) rather than inventing a scoped directive.
|
|
97
|
+
|
|
98
|
+
Each of these is a **hard error** that fails that one file's test — never a silent skip, never a silent pass:
|
|
99
|
+
|
|
100
|
+
- an unknown capability token,
|
|
101
|
+
- a directive with no tokens,
|
|
102
|
+
- a canonical directive appearing after the file's first SQL line,
|
|
103
|
+
- a **near-miss spelling** — `-- require-capability:`, `-- requires_capability:`, `-- requires capability:`.
|
|
104
|
+
This last one matters: the runner `continue`s past every unrecognized `--` line, so without the guard a
|
|
105
|
+
typo'd directive would vanish and the file would run with nobody the wiser.
|
|
106
|
+
|
|
107
|
+
**Vocabulary** (closed set):
|
|
108
|
+
|
|
109
|
+
| Token | Meaning |
|
|
110
|
+
|---|---|
|
|
111
|
+
| `standalone-index-ddl` | Backend accepts `create index`, `create unique index`, and `drop index` as standalone statements. |
|
|
112
|
+
|
|
113
|
+
Adding a member is a deliberate quereus change: one entry in `SQLLOGIC_CAPABILITIES`, one row in this
|
|
114
|
+
table, and at least one file annotated with it. The set being closed is the point — every consumer of the
|
|
115
|
+
corpus agrees on what the tokens mean, so a downstream backend cannot mint private tokens. Group tokens
|
|
116
|
+
by "a feature a backend would realistically choose to omit wholesale"; do **not** mint a capability per test.
|
|
117
|
+
|
|
118
|
+
**What this is NOT.** Two adjacent concepts exist; keep them apart.
|
|
119
|
+
|
|
120
|
+
- `ModuleCapabilities` (`src/vtab/capabilities.ts`) is a *runtime* interface a virtual-table module
|
|
121
|
+
advertises to the engine (`isolation`, `savepoints`, `secondaryIndexes`, `ddlTransactionality`, …). This
|
|
122
|
+
directive is a *test-harness* concept about whole SQL statements a backend accepts. One is not derived
|
|
123
|
+
from the other: `secondaryIndexes: true` means "supports secondary indexes", which a backend can satisfy
|
|
124
|
+
through declared schema or covering materialized views while still having no standalone `create index`
|
|
125
|
+
statement. Different question, different answer — hence the distinct type name `SqllogicCapability`.
|
|
126
|
+
- `MEMORY_ONLY_FILES` (`logic.spec.ts`) is quereus's own store-mode exclusion list and stays as it is.
|
|
127
|
+
Split rule: capability-shaped divergence → file directive; memory-engine quirk, cost-model choice,
|
|
128
|
+
harness-config assertion, white-box internals, or known-bug divergence → that set.
|
|
129
|
+
|
|
130
|
+
Both of quereus's backends ship standalone index DDL, so the mechanism produces **zero local skips** today.
|
|
131
|
+
That is expected — the payoff is downstream. A file skipping locally means the capability sets or the
|
|
132
|
+
directive are wrong.
|
|
133
|
+
|
|
134
|
+
### Consuming the corpus from the npm package
|
|
135
|
+
|
|
136
|
+
`@quereus/quereus` ships `test/logic/*.sqllogic` and `test/README.md` in its tarball, so a consumer
|
|
137
|
+
runs the corpus that matches the engine version it installed. The `exports` map exposes `./package.json` for exactly this: resolve it, take its directory,
|
|
138
|
+
and read `test/logic` from there.
|
|
139
|
+
|
|
140
|
+
```ts
|
|
141
|
+
import { createRequire } from 'node:module';
|
|
142
|
+
import { dirname, join } from 'node:path';
|
|
143
|
+
const corpusDir = join(dirname(createRequire(import.meta.url).resolve('@quereus/quereus/package.json')), 'test', 'logic');
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
No other path under `test/` is exported or guaranteed to ship. A pattern export such as
|
|
147
|
+
`./test/logic/*` was rejected because it resolves single files but cannot be listed.
|
|
148
|
+
|
|
149
|
+
## Test philosophy
|
|
150
|
+
|
|
151
|
+
Tests are the contract. When a feature is incomplete, write the test the way the feature *should* behave and let it fail — that documents the gap. Don't add `-- skip` markers, don't relax expected results to match observed output, don't comment out assertions.
|
|
152
|
+
|
|
153
|
+
## Historical: SQLite test cross-check
|
|
154
|
+
|
|
155
|
+
Between 2026-04 and 2026-05, the suite was systematically expanded by cross-checking SQLite's own test corpus (the TCL `test/*.test` files in the upstream `sqlite/sqlite` repo, with the sqllogictest corpus as a secondary reference) against `test/logic/`. The shared workspace doc was `docs/sqlite-test-crosscheck.md`; the workflow was `docs/sqlite-test-crosscheck-process.md`. Twelve `5-sqlite-xref-*` implement tickets carried out the work, one per category (SELECT/output, WHERE/BETWEEN, joins, indexes, subqueries/CTE, aggregates/windows, expressions/types, scalar functions, temporal/JSON functions, DML, DDL/constraints, transactions/bind/errors).
|
|
156
|
+
|
|
157
|
+
Key rules that shaped the resulting fixtures:
|
|
158
|
+
|
|
159
|
+
- **Applicability filter.** SQLite tests covering rowids, btree/pager/wal internals, vacuum/backup/attach, triggers, type-affinity coercion, fault injection, and file-page pragmas are `n/a` to Quereus by design — see the out-of-scope block in the cross-check doc and `docs/architecture.md` § Design Differences from SQLite. They were dead-marked, not translated.
|
|
160
|
+
- **Distill, don't transliterate.** SQLite TCL tests carry a lot of plumbing (procs, do_test wrappers, db open/close, file deletion). The SQL kept in our fixtures is the minimum that exercises the scenario.
|
|
161
|
+
- **Adapt to Quereus semantics.** NOT NULL by default, no rowids, explicit type conversions, key-based addressing — expected results were rewritten where SQLite's defaults differ. Where Quereus deliberately rejects an SQLite input, the fixture asserts the rejection via `-- error: <substring>`.
|
|
162
|
+
- **Failing tests were the deliverable.** The cross-check passes wrote fixtures that document gaps; making them pass is a separate downstream pass. Look for fixtures whose internal scenarios fail to find the still-open work.
|
|
163
|
+
- **Status calibration.** Each row in the index landed at `covered`, `partial`, `gap`, or `n/a`. `partial` and `gap` rows produced new fixtures, logged in the doc's Gaps Log with their final filenames.
|
|
164
|
+
|
|
165
|
+
The full state, status legend, per-category index, and per-fixture Gaps Log live in `docs/sqlite-test-crosscheck.md` — consult it when adding more SQLite-derived coverage so existing classifications aren't redone, and when triaging which failing fixture covers which SQLite scenario.
|
|
166
|
+
|
|
167
|
+
## Adding new tests
|
|
168
|
+
|
|
169
|
+
1. Pick the right kind: `.sqllogic` first; property test (`property.spec.ts`) only when an invariant naturally generalizes; unit test only when SQL-level coverage can't reach the surface.
|
|
170
|
+
- Fixing a clause the parser accepted but no builder ever read? The behaviour goes in a `.sqllogic`, and a row also goes in `clause-canary.spec.ts` — one query per clause whose answer must differ from the same query with the clause removed. That suite guards the *class* (a silently-dropped clause), not any one clause's correctness.
|
|
171
|
+
2. For `.sqllogic`, name the file by feature/scenario (`between-with-nulls.sqllogic`), prefix it numerically per the run-order anchors above, and order scenarios inside the file mundane → exotic.
|
|
172
|
+
3. Run `yarn test` to confirm the test exercises what you expect. If it's documenting a gap, leave it failing — don't paper over it.
|
|
173
|
+
4. Update the relevant docs (this README, the cross-check doc, or the topic doc in `docs/`) when adding a whole new category.
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
-- Test the basics of create and select
|
|
2
|
+
|
|
3
|
+
CREATE TABLE t (a TEXT, b INTEGER);
|
|
4
|
+
INSERT INTO t VALUES ('a', 10);
|
|
5
|
+
|
|
6
|
+
select a, b from t;
|
|
7
|
+
→ [{"a": "a", "b": 10}]
|
|
8
|
+
|
|
9
|
+
DROP TABLE t;
|
|
10
|
+
|
|
11
|
+
-- Test CREATE TABLE IF NOT EXISTS
|
|
12
|
+
|
|
13
|
+
CREATE TABLE IF NOT EXISTS t1 (id INTEGER PRIMARY KEY, name TEXT);
|
|
14
|
+
|
|
15
|
+
-- Insert a row to verify the table was created
|
|
16
|
+
INSERT INTO t1 VALUES (1, 'Alice');
|
|
17
|
+
|
|
18
|
+
SELECT * FROM t1;
|
|
19
|
+
→ [{"id": 1, "name": "Alice"}]
|
|
20
|
+
|
|
21
|
+
-- Second CREATE TABLE IF NOT EXISTS should be a no-op (not error)
|
|
22
|
+
CREATE TABLE IF NOT EXISTS t1 (id INTEGER PRIMARY KEY, name TEXT);
|
|
23
|
+
|
|
24
|
+
-- Verify original data is still there (not reset)
|
|
25
|
+
SELECT * FROM t1;
|
|
26
|
+
→ [{"id": 1, "name": "Alice"}]
|
|
27
|
+
|
|
28
|
+
-- Insert another row to confirm table still works
|
|
29
|
+
INSERT INTO t1 VALUES (2, 'Bob');
|
|
30
|
+
|
|
31
|
+
SELECT * FROM t1 ORDER BY id;
|
|
32
|
+
→ [{"id": 1, "name": "Alice"}, {"id": 2, "name": "Bob"}]
|
|
33
|
+
|
|
34
|
+
DROP TABLE t1;
|
|
35
|
+
|
|
36
|
+
-- Test that CREATE TABLE without IF NOT EXISTS errors when table exists
|
|
37
|
+
CREATE TABLE t2 (x INTEGER);
|
|
38
|
+
CREATE TABLE t2 (x INTEGER);
|
|
39
|
+
-- error: already exists
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
-- adapted from SQLite test/select1.test, test/selectD.test, test/e_select.test
|
|
2
|
+
-- SELECT projection corner cases: duplicate wildcard expansion,
|
|
3
|
+
-- qualified column refs across self-join, parenthesized FROM clauses.
|
|
4
|
+
|
|
5
|
+
create table t1 (a integer primary key, b text);
|
|
6
|
+
insert into t1 values (1, 'one');
|
|
7
|
+
|
|
8
|
+
-- Single-row sanity check before exercising projection
|
|
9
|
+
select a, b from t1;
|
|
10
|
+
→ [{"a":1,"b":"one"}]
|
|
11
|
+
|
|
12
|
+
-- Duplicate wildcard in projection — column names disambiguated
|
|
13
|
+
select *, * from t1;
|
|
14
|
+
→ [{"a":1,"b":"one","a:1":1,"b:1":"one"}]
|
|
15
|
+
|
|
16
|
+
-- Wildcard plus literal expression
|
|
17
|
+
select *, 'lit' as marker from t1;
|
|
18
|
+
→ [{"a":1,"b":"one","marker":"lit"}]
|
|
19
|
+
|
|
20
|
+
-- =============================================================================
|
|
21
|
+
-- Star position: a `*` in the select list is expanded in place, not hoisted to
|
|
22
|
+
-- the front of the output. Regression for
|
|
23
|
+
-- bug-star-in-select-list-ignores-its-position.
|
|
24
|
+
-- =============================================================================
|
|
25
|
+
|
|
26
|
+
-- A named column before the star: the star's own `a` collides with the named
|
|
27
|
+
-- one and is disambiguated (`a:1`), the star's `b` is not.
|
|
28
|
+
select a, * from t1;
|
|
29
|
+
→ [{"a":1,"a:1":1,"b":"one"}]
|
|
30
|
+
|
|
31
|
+
-- A named column aliased onto the star's own column name: order decides which
|
|
32
|
+
-- occurrence keeps the bare name and which gets the `:1` suffix, so this is
|
|
33
|
+
-- the case that actually distinguishes written order from star-first — the
|
|
34
|
+
-- two occurrences carry different values (`b`'s value vs `a`'s value).
|
|
35
|
+
select b as a, * from t1;
|
|
36
|
+
→ [{"a":"one","a:1":1,"b":"one"}]
|
|
37
|
+
|
|
38
|
+
-- A star between two named columns.
|
|
39
|
+
select a, *, b from t1;
|
|
40
|
+
→ [{"a":1,"a:1":1,"b":"one","b:1":"one"}]
|
|
41
|
+
|
|
42
|
+
-- A star after a computed column.
|
|
43
|
+
select upper(b) u, * from t1;
|
|
44
|
+
→ [{"u":"ONE","a":1,"b":"one"}]
|
|
45
|
+
|
|
46
|
+
-- Qualified column refs over a self-join (cross join)
|
|
47
|
+
insert into t1 values (2, 'two');
|
|
48
|
+
|
|
49
|
+
select A.a as la, B.a as ra from t1 as A cross join t1 as B order by la, ra;
|
|
50
|
+
→ [{"la":1,"ra":1},{"la":1,"ra":2},{"la":2,"ra":1},{"la":2,"ra":2}]
|
|
51
|
+
|
|
52
|
+
select A.*, B.* from t1 as A cross join t1 as B order by A.a, B.a;
|
|
53
|
+
→ [{"a":1,"b":"one","a:1":1,"b:1":"one"},{"a":1,"b":"one","a:1":2,"b:1":"two"},{"a":2,"b":"two","a:1":1,"b:1":"one"},{"a":2,"b":"two","a:1":2,"b:1":"two"}]
|
|
54
|
+
|
|
55
|
+
-- A qualified star after a named column, over the same self-join.
|
|
56
|
+
select A.a as la, B.* from t1 as A cross join t1 as B order by la, B.a;
|
|
57
|
+
→ [{"la":1,"a":1,"b":"one"},{"la":1,"a":2,"b":"two"},{"la":2,"a":1,"b":"one"},{"la":2,"a":2,"b":"two"}]
|
|
58
|
+
|
|
59
|
+
drop table t1;
|
|
60
|
+
|
|
61
|
+
-- =============================================================================
|
|
62
|
+
-- Parenthesized FROM expressions: (a join b) join c
|
|
63
|
+
-- =============================================================================
|
|
64
|
+
|
|
65
|
+
create table p1 (id integer primary key, val text);
|
|
66
|
+
create table p2 (id integer primary key, p1_id integer);
|
|
67
|
+
create table p3 (id integer primary key, p2_id integer);
|
|
68
|
+
insert into p1 values (1, 'A'), (2, 'B');
|
|
69
|
+
insert into p2 values (10, 1), (20, 2);
|
|
70
|
+
insert into p3 values (100, 10), (200, 20);
|
|
71
|
+
|
|
72
|
+
-- Inner join wrapped in parentheses, then joined to a third table
|
|
73
|
+
select p1.id as l, p2.id as m, p3.id as r
|
|
74
|
+
from (p1 join p2 on p1.id = p2.p1_id) join p3 on p2.id = p3.p2_id
|
|
75
|
+
order by l;
|
|
76
|
+
-- error: Expected table name
|
|
77
|
+
|
|
78
|
+
-- Left side scalar table joined to a parenthesized inner-join subexpression
|
|
79
|
+
select p1.id as l, p2.id as m, p3.id as r
|
|
80
|
+
from p1 left join (p2 join p3 on p2.id = p3.p2_id) on p1.id = p2.p1_id
|
|
81
|
+
order by l;
|
|
82
|
+
-- error: Expected table name
|
|
83
|
+
|
|
84
|
+
drop table p3;
|
|
85
|
+
drop table p2;
|
|
86
|
+
drop table p1;
|
|
87
|
+
|
|
88
|
+
-- =============================================================================
|
|
89
|
+
-- UNION column-name derivation: names come from the left SELECT
|
|
90
|
+
-- =============================================================================
|
|
91
|
+
|
|
92
|
+
create table u1 (f1 integer);
|
|
93
|
+
create table u2 (r2 real);
|
|
94
|
+
insert into u1 values (11);
|
|
95
|
+
insert into u2 values (1.5);
|
|
96
|
+
|
|
97
|
+
-- Result column is named after the left SELECT's expression
|
|
98
|
+
select f1 from u1
|
|
99
|
+
union
|
|
100
|
+
select r2 from u2
|
|
101
|
+
order by f1;
|
|
102
|
+
→ [{"f1":1.5},{"f1":11}]
|
|
103
|
+
|
|
104
|
+
-- ORDER BY can reference the left-side name even though right side has different name
|
|
105
|
+
select f1 as label from u1
|
|
106
|
+
union all
|
|
107
|
+
select r2 from u2
|
|
108
|
+
order by label;
|
|
109
|
+
→ [{"label":1.5},{"label":11}]
|
|
110
|
+
|
|
111
|
+
drop table u2;
|
|
112
|
+
drop table u1;
|
|
113
|
+
|
|
114
|
+
-- =============================================================================
|
|
115
|
+
-- Bare (no-AS) aliases followed by more list items — regression coverage for
|
|
116
|
+
-- a parser bug where a bare alias was rejected whenever a comma followed it
|
|
117
|
+
-- =============================================================================
|
|
118
|
+
|
|
119
|
+
create table b1 (k integer primary key, j integer);
|
|
120
|
+
insert into b1 values (1, 10), (2, 20);
|
|
121
|
+
|
|
122
|
+
-- Bare column aliases, none of which is the last item in the list
|
|
123
|
+
select k kk, j jj from b1 order by kk;
|
|
124
|
+
→ [{"kk":1,"jj":10},{"kk":2,"jj":20}]
|
|
125
|
+
|
|
126
|
+
-- Bare alias immediately before a window function column
|
|
127
|
+
select k kk, row_number() over (order by k) rn from b1 order by kk;
|
|
128
|
+
→ [{"kk":1,"rn":1},{"kk":2,"rn":2}]
|
|
129
|
+
|
|
130
|
+
drop table b1;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
-- various string literals
|
|
2
|
+
|
|
3
|
+
-- Basic multi-line single-quoted string
|
|
4
|
+
SELECT 'hello
|
|
5
|
+
world' as multiline;
|
|
6
|
+
→ [{"multiline":"hello\nworld"}]
|
|
7
|
+
|
|
8
|
+
-- Multi-line string with explicit content
|
|
9
|
+
SELECT 'line one
|
|
10
|
+
line two
|
|
11
|
+
line three' as text;
|
|
12
|
+
→ [{"text":"line one\nline two\nline three"}]
|
|
13
|
+
|
|
14
|
+
-- Multi-line string in WHERE clause
|
|
15
|
+
CREATE TABLE test_multiline (id INTEGER PRIMARY KEY, content TEXT);
|
|
16
|
+
INSERT INTO test_multiline VALUES (1, 'hello
|
|
17
|
+
world');
|
|
18
|
+
SELECT * FROM test_multiline WHERE content = 'hello
|
|
19
|
+
world';
|
|
20
|
+
→ [{"id":1,"content":"hello\nworld"}]
|
|
21
|
+
|
|
22
|
+
-- Multi-line string with special characters
|
|
23
|
+
SELECT 'first line
|
|
24
|
+
second line with spaces
|
|
25
|
+
third line' as formatted;
|
|
26
|
+
→ [{"formatted":"first line\nsecond line with spaces\nthird line"}]
|
|
27
|
+
|
|
28
|
+
-- String concatenation with multi-line strings
|
|
29
|
+
SELECT 'multi
|
|
30
|
+
line' || ' ' || 'another
|
|
31
|
+
multi
|
|
32
|
+
line' as concatenated;
|
|
33
|
+
→ [{"concatenated":"multi\nline another\nmulti\nline"}]
|
|
34
|
+
|
|
35
|
+
-- SQL standard escaped quotes ('' represents a single quote)
|
|
36
|
+
SELECT 'hello''world' as escaped;
|
|
37
|
+
→ [{"escaped":"hello'world"}]
|
|
38
|
+
|
|
39
|
+
-- Escaped quotes in multi-line string (inch marks example)
|
|
40
|
+
SELECT '60'''' total: 36'''' center' as measurement;
|
|
41
|
+
→ [{"measurement":"60'' total: 36'' center"}]
|
|
42
|
+
|
|
43
|
+
DROP TABLE test_multiline;
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
-- adapted from SQLite test/insert2.test, test/insert4.test, test/insert5.test
|
|
2
|
+
-- INSERT ... SELECT variants beyond the simple form covered in 01-basic and 13-cte.
|
|
3
|
+
-- Quereus has no rowids and NOT NULL by default; subagent reports flagged
|
|
4
|
+
-- column-reordering, compound select, JOIN, GROUP BY, DISTINCT, LIMIT,
|
|
5
|
+
-- self-reference and view-mediated INSERT...SELECT as uncovered scenarios.
|
|
6
|
+
|
|
7
|
+
-- ===================================
|
|
8
|
+
-- 1. INSERT ... SELECT with column reordering / partial mapping
|
|
9
|
+
-- ===================================
|
|
10
|
+
|
|
11
|
+
create table src_basic (a integer primary key, b text null, c integer null);
|
|
12
|
+
create table dst_basic (a integer primary key, b text null, c integer null);
|
|
13
|
+
|
|
14
|
+
insert into src_basic values (1, 'x', 10), (2, 'y', 20);
|
|
15
|
+
|
|
16
|
+
-- target column list reorders columns relative to SELECT projection
|
|
17
|
+
insert into dst_basic (c, a) select c, a from src_basic;
|
|
18
|
+
|
|
19
|
+
select a, b, c from dst_basic order by a;
|
|
20
|
+
→ [{"a":1,"b":null,"c":10},{"a":2,"b":null,"c":20}]
|
|
21
|
+
|
|
22
|
+
drop table dst_basic;
|
|
23
|
+
drop table src_basic;
|
|
24
|
+
|
|
25
|
+
-- ===================================
|
|
26
|
+
-- 2. INSERT ... SELECT with GROUP BY aggregation
|
|
27
|
+
-- ===================================
|
|
28
|
+
|
|
29
|
+
create table events (id integer primary key, grp text, n integer);
|
|
30
|
+
insert into events values (1, 'A', 10), (2, 'A', 5), (3, 'B', 20);
|
|
31
|
+
|
|
32
|
+
create table summary (grp text primary key, total integer);
|
|
33
|
+
insert into summary (grp, total) select grp, sum(n) from events group by grp;
|
|
34
|
+
|
|
35
|
+
select grp, total from summary order by grp;
|
|
36
|
+
→ [{"grp":"A","total":15},{"grp":"B","total":20}]
|
|
37
|
+
|
|
38
|
+
drop table summary;
|
|
39
|
+
drop table events;
|
|
40
|
+
|
|
41
|
+
-- ===================================
|
|
42
|
+
-- 3. INSERT ... SELECT with compound (UNION ALL, EXCEPT)
|
|
43
|
+
-- ===================================
|
|
44
|
+
|
|
45
|
+
create table s1 (id integer primary key, val text);
|
|
46
|
+
create table s2 (id integer primary key, val text);
|
|
47
|
+
insert into s1 values (1, 'apple'), (2, 'banana');
|
|
48
|
+
insert into s2 values (2, 'banana'), (3, 'cherry');
|
|
49
|
+
|
|
50
|
+
create table u_dst (id integer primary key, val text);
|
|
51
|
+
|
|
52
|
+
insert into u_dst (id, val) select id, val from s1 union all select id + 100, val from s2;
|
|
53
|
+
select id, val from u_dst order by id;
|
|
54
|
+
→ [{"id":1,"val":"apple"},{"id":2,"val":"banana"},{"id":102,"val":"banana"},{"id":103,"val":"cherry"}]
|
|
55
|
+
|
|
56
|
+
drop table u_dst;
|
|
57
|
+
|
|
58
|
+
create table e_dst (id integer primary key, val text);
|
|
59
|
+
insert into e_dst (id, val) select id, val from s1 except select id, val from s2;
|
|
60
|
+
select id, val from e_dst order by id;
|
|
61
|
+
→ [{"id":1,"val":"apple"}]
|
|
62
|
+
|
|
63
|
+
drop table e_dst;
|
|
64
|
+
drop table s2;
|
|
65
|
+
drop table s1;
|
|
66
|
+
|
|
67
|
+
-- ===================================
|
|
68
|
+
-- 4. INSERT ... SELECT from JOIN (LEFT JOIN with NULL padding)
|
|
69
|
+
-- ===================================
|
|
70
|
+
|
|
71
|
+
create table l (id integer primary key, val text);
|
|
72
|
+
create table r (id integer primary key, left_id integer, info text);
|
|
73
|
+
insert into l values (1, 'a'), (2, 'b');
|
|
74
|
+
insert into r values (10, 1, 'x');
|
|
75
|
+
|
|
76
|
+
create table joined (id integer primary key, val text, info text null);
|
|
77
|
+
|
|
78
|
+
insert into joined (id, val, info)
|
|
79
|
+
select l.id, l.val, r.info from l left join r on l.id = r.left_id;
|
|
80
|
+
|
|
81
|
+
select id, val, info from joined order by id;
|
|
82
|
+
→ [{"id":1,"val":"a","info":"x"},{"id":2,"val":"b","info":null}]
|
|
83
|
+
|
|
84
|
+
drop table joined;
|
|
85
|
+
drop table r;
|
|
86
|
+
drop table l;
|
|
87
|
+
|
|
88
|
+
-- ===================================
|
|
89
|
+
-- 5. INSERT ... SELECT with DISTINCT (suppress duplicates)
|
|
90
|
+
-- ===================================
|
|
91
|
+
|
|
92
|
+
create table dup_src (id integer primary key, x integer, y integer);
|
|
93
|
+
insert into dup_src values (1, 1, 10), (2, 1, 10), (3, 2, 20);
|
|
94
|
+
|
|
95
|
+
create table dup_dst (x integer, y integer, primary key (x, y));
|
|
96
|
+
insert into dup_dst select distinct x, y from dup_src;
|
|
97
|
+
|
|
98
|
+
select x, y from dup_dst order by x, y;
|
|
99
|
+
→ [{"x":1,"y":10},{"x":2,"y":20}]
|
|
100
|
+
|
|
101
|
+
drop table dup_dst;
|
|
102
|
+
drop table dup_src;
|
|
103
|
+
|
|
104
|
+
-- ===================================
|
|
105
|
+
-- 6. INSERT ... SELECT with LIMIT
|
|
106
|
+
-- ===================================
|
|
107
|
+
|
|
108
|
+
create table lim_src (id integer primary key, val integer);
|
|
109
|
+
create table lim_dst (id integer primary key, val integer);
|
|
110
|
+
|
|
111
|
+
insert into lim_src values (1, 100), (2, 200), (3, 300);
|
|
112
|
+
insert into lim_dst select id, val from lim_src order by id limit 2;
|
|
113
|
+
|
|
114
|
+
select id, val from lim_dst order by id;
|
|
115
|
+
→ [{"id":1,"val":100},{"id":2,"val":200}]
|
|
116
|
+
|
|
117
|
+
drop table lim_dst;
|
|
118
|
+
drop table lim_src;
|
|
119
|
+
|
|
120
|
+
-- ===================================
|
|
121
|
+
-- 7. INSERT ... SELECT self-referential (insert from same table)
|
|
122
|
+
-- ===================================
|
|
123
|
+
|
|
124
|
+
create table doubler (id integer primary key, val integer);
|
|
125
|
+
insert into doubler values (1, 10), (2, 20);
|
|
126
|
+
|
|
127
|
+
insert into doubler (id, val) select id + 100, val * 2 from doubler;
|
|
128
|
+
|
|
129
|
+
select id, val from doubler order by id;
|
|
130
|
+
→ [{"id":1,"val":10},{"id":2,"val":20},{"id":101,"val":20},{"id":102,"val":40}]
|
|
131
|
+
|
|
132
|
+
drop table doubler;
|
|
133
|
+
|
|
134
|
+
-- ===================================
|
|
135
|
+
-- 7b. INSERT ... SELECT self-referential, mid-transaction (after prior writes)
|
|
136
|
+
-- ===================================
|
|
137
|
+
-- Same shape as section 7, but wrapped in BEGIN ... COMMIT with a seeding
|
|
138
|
+
-- INSERT VALUES so the connection's pendingTransactionLayer is non-null when
|
|
139
|
+
-- the self-ref INSERT runs. This exercises the eager savepoint-snapshot
|
|
140
|
+
-- branch in MemoryTableConnection.createSavepoint: without the readLayer
|
|
141
|
+
-- swap, the SELECT iterator and the INSERT mutate the same BTree and the
|
|
142
|
+
-- new rows feed back into the SELECT (halloween), causing val*2 to keep
|
|
143
|
+
-- doubling row by row until Number.isSafeInteger rejects it.
|
|
144
|
+
|
|
145
|
+
create table doubler_tx (id integer primary key, val integer);
|
|
146
|
+
|
|
147
|
+
begin;
|
|
148
|
+
insert into doubler_tx values (1, 10), (2, 20);
|
|
149
|
+
insert into doubler_tx (id, val) select id + 100, val * 2 from doubler_tx;
|
|
150
|
+
commit;
|
|
151
|
+
|
|
152
|
+
select id, val from doubler_tx order by id;
|
|
153
|
+
→ [{"id":1,"val":10},{"id":2,"val":20},{"id":101,"val":20},{"id":102,"val":40}]
|
|
154
|
+
|
|
155
|
+
drop table doubler_tx;
|
|
156
|
+
|
|
157
|
+
-- ===================================
|
|
158
|
+
-- 8. INSERT ... SELECT through a view of the target table
|
|
159
|
+
-- ===================================
|
|
160
|
+
|
|
161
|
+
create table v_target (id integer primary key, name text);
|
|
162
|
+
insert into v_target values (1, 'Alice'), (2, 'Bob');
|
|
163
|
+
|
|
164
|
+
create view v_target_v as select id, name from v_target where id > 0;
|
|
165
|
+
|
|
166
|
+
insert into v_target (id, name) select id + 10, name || '_v' from v_target_v;
|
|
167
|
+
|
|
168
|
+
select id, name from v_target order by id;
|
|
169
|
+
→ [{"id":1,"name":"Alice"},{"id":2,"name":"Bob"},{"id":11,"name":"Alice_v"},{"id":12,"name":"Bob_v"}]
|
|
170
|
+
|
|
171
|
+
drop view v_target_v;
|
|
172
|
+
drop table v_target;
|
|
173
|
+
|
|
174
|
+
-- ===================================
|
|
175
|
+
-- 9. INSERT ... SELECT with CHECK constraint enforcement on target
|
|
176
|
+
-- ===================================
|
|
177
|
+
|
|
178
|
+
create table chk_src (a integer, b integer);
|
|
179
|
+
create table chk_dst (a integer, b integer check (b > a));
|
|
180
|
+
insert into chk_src values (10, 20), (30, 25);
|
|
181
|
+
|
|
182
|
+
-- only the row that satisfies CHECK should be admitted; the other should error
|
|
183
|
+
insert into chk_dst select a, b from chk_src where b > a;
|
|
184
|
+
select a, b from chk_dst order by a;
|
|
185
|
+
→ [{"a":10,"b":20}]
|
|
186
|
+
|
|
187
|
+
-- attempting to insert the violating row directly errors
|
|
188
|
+
insert into chk_dst select a, b from chk_src where a = 30;
|
|
189
|
+
-- error: CHECK constraint failed
|
|
190
|
+
|
|
191
|
+
drop table chk_dst;
|
|
192
|
+
drop table chk_src;
|
|
193
|
+
|
|
194
|
+
-- ===================================
|
|
195
|
+
-- 10. INSERT ... SELECT with correlated subquery in WHERE referencing target
|
|
196
|
+
-- ===================================
|
|
197
|
+
|
|
198
|
+
create table self_ref (id integer primary key, val integer);
|
|
199
|
+
insert into self_ref values (1, 10), (2, 20), (3, 30);
|
|
200
|
+
|
|
201
|
+
insert into self_ref (id, val)
|
|
202
|
+
select id + 100, 99 from self_ref where id in (select id from self_ref where val > 15);
|
|
203
|
+
|
|
204
|
+
select id, val from self_ref order by id;
|
|
205
|
+
→ [{"id":1,"val":10},{"id":2,"val":20},{"id":3,"val":30},{"id":102,"val":99},{"id":103,"val":99}]
|
|
206
|
+
|
|
207
|
+
drop table self_ref;
|
|
208
|
+
|
|
209
|
+
-- ===================================
|
|
210
|
+
-- 11. Duplicate column in the INSERT column list is rejected (no silent
|
|
211
|
+
-- last-wins / confusing shape). PostgreSQL rejects this as
|
|
212
|
+
-- "column \"a\" specified more than once". See ticket
|
|
213
|
+
-- insert-family-duplicate-column-targets-silent-last-wins.
|
|
214
|
+
-- ===================================
|
|
215
|
+
|
|
216
|
+
create table dup_cols (a integer primary key, b integer null);
|
|
217
|
+
|
|
218
|
+
insert into dup_cols (a, a) values (1, 2);
|
|
219
|
+
-- error: specified more than once
|
|
220
|
+
|
|
221
|
+
-- case-insensitive duplicate is also rejected.
|
|
222
|
+
insert into dup_cols (a, b, A) values (1, 2, 3);
|
|
223
|
+
-- error: specified more than once
|
|
224
|
+
|
|
225
|
+
-- the rejected inserts made no change.
|
|
226
|
+
select a, b from dup_cols order by a;
|
|
227
|
+
→ []
|
|
228
|
+
|
|
229
|
+
-- false-positive guard: the check keys on exact-name collision, so a legitimate
|
|
230
|
+
-- distinct-column list still works — including columns that merely share a prefix.
|
|
231
|
+
create table prefix_cols (ab integer primary key, abc integer null);
|
|
232
|
+
insert into prefix_cols (ab, abc) values (1, 2);
|
|
233
|
+
select ab, abc from prefix_cols order by ab;
|
|
234
|
+
→ [{"ab":1,"abc":2}]
|
|
235
|
+
drop table prefix_cols;
|
|
236
|
+
|
|
237
|
+
drop table dup_cols;
|