@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,318 @@
|
|
|
1
|
+
-- 13.6-cte-dml-runs-once.sqllogic - a data-modifying CTE runs ONCE per statement
|
|
2
|
+
--
|
|
3
|
+
-- `with c as (insert/update/delete ... returning ...) select ...` must execute its
|
|
4
|
+
-- write exactly once per statement execution, no matter how many times the rest of
|
|
5
|
+
-- the query names `c`. Every mention then replays one buffer of RETURNING rows.
|
|
6
|
+
--
|
|
7
|
+
-- This held only accidentally before: buffering was gated on the CTE's parent count
|
|
8
|
+
-- (two mentions sharing an alias collapse to ONE reference node, so the gate read
|
|
9
|
+
-- "referenced once") and the buffer was keyed on the plan node's id (which the
|
|
10
|
+
-- constant-folding pass can split into several ids for one CTE). A `values`-bodied
|
|
11
|
+
-- INSERT folds to a table literal and hit both; a `select`-bodied one hit only the
|
|
12
|
+
-- first. Both body shapes are covered below.
|
|
13
|
+
|
|
14
|
+
-- ===== INSERT body, referenced twice via scalar subqueries =====
|
|
15
|
+
|
|
16
|
+
create table t1 (k integer primary key, v integer default 0);
|
|
17
|
+
-- run
|
|
18
|
+
|
|
19
|
+
with c as (insert into t1 (k) values (1) returning k)
|
|
20
|
+
select (select count(*) from c) as a, (select count(*) from c) as b;
|
|
21
|
+
→ [{"a":1,"b":1}]
|
|
22
|
+
|
|
23
|
+
-- One row inserted, not two — the second mention replayed the buffer.
|
|
24
|
+
select k, v from t1 order by k;
|
|
25
|
+
→ [{"k":1,"v":0}]
|
|
26
|
+
|
|
27
|
+
-- ===== INSERT body, referenced twice via a self-join =====
|
|
28
|
+
|
|
29
|
+
create table t2 (k integer primary key);
|
|
30
|
+
-- run
|
|
31
|
+
|
|
32
|
+
with c as (insert into t2 (k) values (1) returning k)
|
|
33
|
+
select count(*) as n from c c1 join c c2 on c1.k = c2.k;
|
|
34
|
+
→ [{"n":1}]
|
|
35
|
+
|
|
36
|
+
select k from t2 order by k;
|
|
37
|
+
→ [{"k":1}]
|
|
38
|
+
|
|
39
|
+
-- ===== INSERT body reading a real table (not constant-foldable) =====
|
|
40
|
+
|
|
41
|
+
create table src (k integer primary key);
|
|
42
|
+
insert into src values (7), (8);
|
|
43
|
+
create table t3 (k integer primary key);
|
|
44
|
+
-- run
|
|
45
|
+
|
|
46
|
+
with c as (insert into t3 (k) select k from src returning k)
|
|
47
|
+
select (select count(*) from c) as a, (select count(*) from c) as b;
|
|
48
|
+
→ [{"a":2,"b":2}]
|
|
49
|
+
|
|
50
|
+
select k from t3 order by k;
|
|
51
|
+
→ [{"k":7},{"k":8}]
|
|
52
|
+
|
|
53
|
+
-- ===== UPDATE body, referenced twice =====
|
|
54
|
+
-- The silent-corruption case: no error, plausible output, doubled increment.
|
|
55
|
+
|
|
56
|
+
create table t4 (k integer primary key, v integer);
|
|
57
|
+
insert into t4 values (1, 0), (2, 0);
|
|
58
|
+
-- run
|
|
59
|
+
|
|
60
|
+
with c as (update t4 set v = v + 1 returning k, v)
|
|
61
|
+
select (select count(*) from c) as a, (select count(*) from c) as b;
|
|
62
|
+
→ [{"a":2,"b":2}]
|
|
63
|
+
|
|
64
|
+
-- v incremented once, not twice.
|
|
65
|
+
select k, v from t4 order by k;
|
|
66
|
+
→ [{"k":1,"v":1},{"k":2,"v":1}]
|
|
67
|
+
|
|
68
|
+
-- ===== DELETE body, referenced twice =====
|
|
69
|
+
-- Second mention must see the SAME returned rows, not an empty re-run.
|
|
70
|
+
|
|
71
|
+
create table t5 (k integer primary key);
|
|
72
|
+
insert into t5 values (1), (2), (3);
|
|
73
|
+
-- run
|
|
74
|
+
|
|
75
|
+
with c as (delete from t5 where k = 1 returning k)
|
|
76
|
+
select (select count(*) from c) as a, (select count(*) from c) as b;
|
|
77
|
+
→ [{"a":1,"b":1}]
|
|
78
|
+
|
|
79
|
+
select k from t5 order by k;
|
|
80
|
+
→ [{"k":2},{"k":3}]
|
|
81
|
+
|
|
82
|
+
-- ===== Explicit MATERIALIZED hint changes nothing =====
|
|
83
|
+
|
|
84
|
+
create table t6 (k integer primary key);
|
|
85
|
+
-- run
|
|
86
|
+
|
|
87
|
+
with c as materialized (insert into t6 (k) values (1) returning k)
|
|
88
|
+
select (select count(*) from c) as a, (select count(*) from c) as b;
|
|
89
|
+
→ [{"a":1,"b":1}]
|
|
90
|
+
|
|
91
|
+
select k from t6 order by k;
|
|
92
|
+
→ [{"k":1}]
|
|
93
|
+
|
|
94
|
+
-- ===== Explicit NOT MATERIALIZED does NOT license a second write =====
|
|
95
|
+
-- Correctness beats the hint: re-executing the body would mean writing twice.
|
|
96
|
+
-- (Same call the recursive-CTE branch already makes.)
|
|
97
|
+
|
|
98
|
+
create table t7 (k integer primary key);
|
|
99
|
+
-- run
|
|
100
|
+
|
|
101
|
+
with c as not materialized (insert into t7 (k) values (1) returning k)
|
|
102
|
+
select (select count(*) from c) as a, (select count(*) from c) as b;
|
|
103
|
+
→ [{"a":1,"b":1}]
|
|
104
|
+
|
|
105
|
+
select k from t7 order by k;
|
|
106
|
+
→ [{"k":1}]
|
|
107
|
+
|
|
108
|
+
-- ===== NOT MATERIALIZED on an UPDATE body =====
|
|
109
|
+
|
|
110
|
+
create table t8 (k integer primary key, v integer);
|
|
111
|
+
insert into t8 values (1, 0);
|
|
112
|
+
-- run
|
|
113
|
+
|
|
114
|
+
with c as not materialized (update t8 set v = v + 1 returning k, v)
|
|
115
|
+
select (select count(*) from c) as a, (select count(*) from c) as b;
|
|
116
|
+
→ [{"a":1,"b":1}]
|
|
117
|
+
|
|
118
|
+
select k, v from t8 order by k;
|
|
119
|
+
→ [{"k":1,"v":1}]
|
|
120
|
+
|
|
121
|
+
-- ===== Three mentions =====
|
|
122
|
+
|
|
123
|
+
create table t9 (k integer primary key, v integer);
|
|
124
|
+
insert into t9 values (1, 0);
|
|
125
|
+
-- run
|
|
126
|
+
|
|
127
|
+
with c as (update t9 set v = v + 5 returning k, v)
|
|
128
|
+
select (select count(*) from c) as a, (select sum(v) from c) as b, (select max(k) from c) as d;
|
|
129
|
+
→ [{"a":1,"b":5,"d":1}]
|
|
130
|
+
|
|
131
|
+
select k, v from t9 order by k;
|
|
132
|
+
→ [{"k":1,"v":5}]
|
|
133
|
+
|
|
134
|
+
-- ===== Control: referenced ONCE still works =====
|
|
135
|
+
|
|
136
|
+
create table t10 (k integer primary key);
|
|
137
|
+
-- run
|
|
138
|
+
|
|
139
|
+
with c as (insert into t10 (k) values (1) returning k) select k from c;
|
|
140
|
+
→ [{"k":1}]
|
|
141
|
+
|
|
142
|
+
select k from t10 order by k;
|
|
143
|
+
→ [{"k":1}]
|
|
144
|
+
|
|
145
|
+
-- ===== Control: referenced ZERO times still writes =====
|
|
146
|
+
-- The write is guaranteed, not reference-driven: `buildBlock` sinks an unreferenced
|
|
147
|
+
-- data-modifying member ahead of the statement (a SequenceNode prelude), matching
|
|
148
|
+
-- SQLite and PostgreSQL. Full coverage of the unreferenced arm lives in
|
|
149
|
+
-- test/logic/13.11-unreferenced-dml-cte.sqllogic.
|
|
150
|
+
|
|
151
|
+
create table t11 (k integer primary key);
|
|
152
|
+
-- run
|
|
153
|
+
|
|
154
|
+
with c as (insert into t11 (k) values (1) returning k) select 42 as x;
|
|
155
|
+
→ [{"x":42}]
|
|
156
|
+
|
|
157
|
+
select count(*) as cnt from t11;
|
|
158
|
+
→ [{"cnt":1}]
|
|
159
|
+
|
|
160
|
+
-- ===== Two data-modifying CTEs in one WITH clause, each referenced twice =====
|
|
161
|
+
-- Each CTE owns its own buffer key, so neither replays the other's rows.
|
|
162
|
+
|
|
163
|
+
create table t13a (k integer primary key);
|
|
164
|
+
create table t13b (k integer primary key);
|
|
165
|
+
-- run
|
|
166
|
+
|
|
167
|
+
with a as (insert into t13a (k) values (1) returning k),
|
|
168
|
+
b as (insert into t13b (k) values (2) returning k)
|
|
169
|
+
select (select count(*) from a) as a1, (select count(*) from a) as a2,
|
|
170
|
+
(select count(*) from b) as b1, (select count(*) from b) as b2;
|
|
171
|
+
→ [{"a1":1,"a2":1,"b1":1,"b2":1}]
|
|
172
|
+
|
|
173
|
+
select k from t13a order by k;
|
|
174
|
+
→ [{"k":1}]
|
|
175
|
+
select k from t13b order by k;
|
|
176
|
+
→ [{"k":2}]
|
|
177
|
+
|
|
178
|
+
-- ===== Early teardown: LIMIT 0 does NOT skip the write =====
|
|
179
|
+
-- Forced buffering detaches the source drive, so it runs to completion even when
|
|
180
|
+
-- every consumer is torn down first. That is the semantics a write wants: the
|
|
181
|
+
-- statement named the insert, so the insert happens.
|
|
182
|
+
|
|
183
|
+
create table t14 (k integer primary key);
|
|
184
|
+
-- run
|
|
185
|
+
|
|
186
|
+
with c as (insert into t14 (k) values (1) returning k) select k from c limit 0;
|
|
187
|
+
→ []
|
|
188
|
+
|
|
189
|
+
select k from t14 order by k;
|
|
190
|
+
→ [{"k":1}]
|
|
191
|
+
|
|
192
|
+
-- ===== ROLLBACK still undoes the buffered write =====
|
|
193
|
+
-- The buffer is per statement execution and lives in the runtime context, not in the
|
|
194
|
+
-- storage layer — it never shields a write from transaction rollback.
|
|
195
|
+
|
|
196
|
+
create table t15 (k integer primary key);
|
|
197
|
+
-- run
|
|
198
|
+
|
|
199
|
+
begin;
|
|
200
|
+
-- run
|
|
201
|
+
|
|
202
|
+
with c as (insert into t15 (k) values (1) returning k)
|
|
203
|
+
select (select count(*) from c) as a, (select count(*) from c) as b;
|
|
204
|
+
→ [{"a":1,"b":1}]
|
|
205
|
+
|
|
206
|
+
rollback;
|
|
207
|
+
-- run
|
|
208
|
+
|
|
209
|
+
select count(*) as cnt from t15;
|
|
210
|
+
→ [{"cnt":0}]
|
|
211
|
+
|
|
212
|
+
-- ===== A data-modifying CTE feeding an INSERT through a VIEW still runs once =====
|
|
213
|
+
-- INSERT now builds its leading WITH clause ONCE, above the view-target dispatch, so the
|
|
214
|
+
-- clause is built before `buildViewMutation` re-plans the statement through the same
|
|
215
|
+
-- builder — and the re-plan builds `stmt.withClause` a second time (buildWithClause
|
|
216
|
+
-- rebuilds the nodes, but every build of one source member shares one runtime identity
|
|
217
|
+
-- via PlanningContext.cteDescriptors, so all copies share one buffer). One of the two
|
|
218
|
+
-- node sets ends up unreferenced — wasted planning work rather than a behavior change;
|
|
219
|
+
-- pinned here because the thing that must NOT double is the write inside the CTE body.
|
|
220
|
+
-- (UPDATE has had this same hoist-then-re-plan ordering all along.)
|
|
221
|
+
|
|
222
|
+
create table t16log (id integer primary key, v text);
|
|
223
|
+
create table t16 (id integer primary key, w text);
|
|
224
|
+
create view vt16 as select id, w from t16;
|
|
225
|
+
-- run
|
|
226
|
+
|
|
227
|
+
with d as (insert into t16log values (1, 'x') returning id)
|
|
228
|
+
insert into vt16 select id, 'z' from d;
|
|
229
|
+
|
|
230
|
+
-- One log row, not two — the CTE body executed exactly once across both plannings.
|
|
231
|
+
select id, v from t16log order by id;
|
|
232
|
+
→ [{"id":1,"v":"x"}]
|
|
233
|
+
|
|
234
|
+
select id, w from t16 order by id;
|
|
235
|
+
→ [{"id":1,"w":"z"}]
|
|
236
|
+
|
|
237
|
+
-- Same shape with the CTE named twice, so the buffering path is exercised too.
|
|
238
|
+
|
|
239
|
+
create table t17log (id integer primary key, v text);
|
|
240
|
+
create table t17 (id integer primary key, w integer);
|
|
241
|
+
create view vt17 as select id, w from t17;
|
|
242
|
+
-- run
|
|
243
|
+
|
|
244
|
+
with d as (insert into t17log values (1, 'x') returning id)
|
|
245
|
+
insert into vt17 select id, (select count(*) from d) from d;
|
|
246
|
+
|
|
247
|
+
select id, v from t17log order by id;
|
|
248
|
+
→ [{"id":1,"v":"x"}]
|
|
249
|
+
|
|
250
|
+
select id, w from t17 order by id;
|
|
251
|
+
→ [{"id":1,"w":1}]
|
|
252
|
+
|
|
253
|
+
-- A MULTI-SOURCE view target is the stronger case: a join-bodied view decomposes into one
|
|
254
|
+
-- base insert per member, and each member re-enters the INSERT builder with the same
|
|
255
|
+
-- statement — so the hoisted WITH clause is built once per member on top of the outer
|
|
256
|
+
-- build. None of those extra plannings may run the CTE body's write.
|
|
257
|
+
|
|
258
|
+
create table t18log (id integer primary key, v text);
|
|
259
|
+
create table t18a (id integer primary key, a text);
|
|
260
|
+
create table t18b (id integer primary key, b text);
|
|
261
|
+
create view vt18 as select t18a.id as id, t18a.a as a, t18b.b as b
|
|
262
|
+
from t18a join t18b on t18a.id = t18b.id;
|
|
263
|
+
-- run
|
|
264
|
+
|
|
265
|
+
with d as (insert into t18log values (1, 'x') returning id)
|
|
266
|
+
insert into vt18 select id, 'aa', 'bb' from d;
|
|
267
|
+
|
|
268
|
+
-- One log row, not one per view member.
|
|
269
|
+
select id, v from t18log order by id;
|
|
270
|
+
→ [{"id":1,"v":"x"}]
|
|
271
|
+
|
|
272
|
+
select id, a from t18a order by id;
|
|
273
|
+
→ [{"id":1,"a":"aa"}]
|
|
274
|
+
|
|
275
|
+
select id, b from t18b order by id;
|
|
276
|
+
→ [{"id":1,"b":"bb"}]
|
|
277
|
+
|
|
278
|
+
-- ===== Control: a plain SELECT-bodied CTE is untouched =====
|
|
279
|
+
-- Re-evaluating a read-only body is a performance question, not a correctness one;
|
|
280
|
+
-- the row-set answer is identical either way. Pinned so the DML rule did not leak.
|
|
281
|
+
|
|
282
|
+
create table t12 (k integer primary key);
|
|
283
|
+
insert into t12 values (1), (2);
|
|
284
|
+
-- run
|
|
285
|
+
|
|
286
|
+
with c as (select k from t12)
|
|
287
|
+
select (select count(*) from c) as a, (select count(*) from c) as b;
|
|
288
|
+
→ [{"a":2,"b":2}]
|
|
289
|
+
|
|
290
|
+
-- Cleanup
|
|
291
|
+
drop table t1;
|
|
292
|
+
drop table t2;
|
|
293
|
+
drop table src;
|
|
294
|
+
drop table t3;
|
|
295
|
+
drop table t4;
|
|
296
|
+
drop table t5;
|
|
297
|
+
drop table t6;
|
|
298
|
+
drop table t7;
|
|
299
|
+
drop table t8;
|
|
300
|
+
drop table t9;
|
|
301
|
+
drop table t10;
|
|
302
|
+
drop table t11;
|
|
303
|
+
drop table t12;
|
|
304
|
+
drop table t13a;
|
|
305
|
+
drop table t13b;
|
|
306
|
+
drop table t14;
|
|
307
|
+
drop table t15;
|
|
308
|
+
drop view vt16;
|
|
309
|
+
drop table t16;
|
|
310
|
+
drop table t16log;
|
|
311
|
+
drop view vt17;
|
|
312
|
+
drop table t17;
|
|
313
|
+
drop table t17log;
|
|
314
|
+
drop view vt18;
|
|
315
|
+
drop table t18a;
|
|
316
|
+
drop table t18b;
|
|
317
|
+
drop table t18log;
|
|
318
|
+
-- run
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
-- 13.7-cte-sibling-visibility.sqllogic - every CTE sees the CTEs defined before it
|
|
2
|
+
--
|
|
3
|
+
-- A WITH clause may define several CTEs, and a later member may name an earlier one.
|
|
4
|
+
-- That held only while the later member's body was a SELECT: `buildCommonTableExpr`
|
|
5
|
+
-- handed the earlier members to `buildSelectStmt` as an explicit parent-CTE argument,
|
|
6
|
+
-- but the VALUES / INSERT / UPDATE / DELETE branches got nothing, and the DML builders
|
|
7
|
+
-- read their inherited definitions off the planning context. A reference inside a
|
|
8
|
+
-- writing body therefore fell through to ordinary schema lookup and failed with
|
|
9
|
+
-- `Table 'a' not found in schema path: main`.
|
|
10
|
+
--
|
|
11
|
+
-- The same line fixed a second arm: the explicit argument carried THIS clause's earlier
|
|
12
|
+
-- members only, and `buildWithContext` prefers a non-empty explicit argument over the
|
|
13
|
+
-- context wholesale, so a nested WITH clause's second and later members lost the
|
|
14
|
+
-- ENCLOSING statement's CTEs. Both arms are covered below.
|
|
15
|
+
|
|
16
|
+
-- ===== INSERT body reads a sibling =====
|
|
17
|
+
|
|
18
|
+
create table p1 (id integer primary key, v text);
|
|
19
|
+
insert into p1 values (1, 'a'), (2, 'b');
|
|
20
|
+
create table q1 (id integer primary key, w integer);
|
|
21
|
+
-- run
|
|
22
|
+
|
|
23
|
+
with a as (select id from p1),
|
|
24
|
+
b as (insert into q1 select id + 10, 1 from a returning id)
|
|
25
|
+
select count(*) as n from b;
|
|
26
|
+
→ [{"n":2}]
|
|
27
|
+
|
|
28
|
+
select id, w from q1 order by id;
|
|
29
|
+
→ [{"id":11,"w":1},{"id":12,"w":1}]
|
|
30
|
+
|
|
31
|
+
-- ===== UPDATE body reads a sibling =====
|
|
32
|
+
-- The sibling is read from a scalar subquery in SET, which resolves through the
|
|
33
|
+
-- CTE-aware context `buildUpdateStmt` builds from the inherited definitions.
|
|
34
|
+
|
|
35
|
+
create table q2 (id integer primary key, w integer);
|
|
36
|
+
insert into q2 values (1, 0), (2, 0);
|
|
37
|
+
-- run
|
|
38
|
+
|
|
39
|
+
with a as (select id from p1),
|
|
40
|
+
b as (update q2 set w = (select count(*) from a) where id = 1 returning id)
|
|
41
|
+
select count(*) as n from b;
|
|
42
|
+
→ [{"n":1}]
|
|
43
|
+
|
|
44
|
+
select id, w from q2 order by id;
|
|
45
|
+
→ [{"id":1,"w":2},{"id":2,"w":0}]
|
|
46
|
+
|
|
47
|
+
-- ===== DELETE body reads a sibling =====
|
|
48
|
+
|
|
49
|
+
create table q3 (id integer primary key, w integer);
|
|
50
|
+
insert into q3 values (1, 0), (2, 0), (3, 0);
|
|
51
|
+
-- run
|
|
52
|
+
|
|
53
|
+
with a as (select id from p1),
|
|
54
|
+
b as (delete from q3 where id in (select id from a) returning id)
|
|
55
|
+
select count(*) as n from b;
|
|
56
|
+
→ [{"n":2}]
|
|
57
|
+
|
|
58
|
+
select id, w from q3 order by id;
|
|
59
|
+
→ [{"id":3,"w":0}]
|
|
60
|
+
|
|
61
|
+
-- ===== A writing body's OWN WITH clause still shadows an enclosing sibling =====
|
|
62
|
+
-- The body's own clause is merged ON TOP of the inherited map, not beside it, so a
|
|
63
|
+
-- same-named local definition wins.
|
|
64
|
+
|
|
65
|
+
create table q4 (id integer primary key, w integer);
|
|
66
|
+
-- run
|
|
67
|
+
|
|
68
|
+
with a as (select id from p1),
|
|
69
|
+
b as (with a as (select 77 as id) insert into q4 select id, 5 from a returning id)
|
|
70
|
+
select count(*) as n from b;
|
|
71
|
+
→ [{"n":1}]
|
|
72
|
+
|
|
73
|
+
-- 77, not 1 and 2 — the inner `a` shadowed the sibling.
|
|
74
|
+
select id, w from q4 order by id;
|
|
75
|
+
→ [{"id":77,"w":5}]
|
|
76
|
+
|
|
77
|
+
-- ===== A writing body's own WITH clause can itself read an enclosing sibling =====
|
|
78
|
+
|
|
79
|
+
create table q5 (id integer primary key, w integer);
|
|
80
|
+
-- run
|
|
81
|
+
|
|
82
|
+
with a as (select id from p1),
|
|
83
|
+
b as (with c as (select id from a) insert into q5 select id + 10, 1 from c returning id)
|
|
84
|
+
select count(*) as n from b;
|
|
85
|
+
→ [{"n":2}]
|
|
86
|
+
|
|
87
|
+
select id, w from q5 order by id;
|
|
88
|
+
→ [{"id":11,"w":1},{"id":12,"w":1}]
|
|
89
|
+
|
|
90
|
+
-- ===== VALUES body sibling visibility is unaffected =====
|
|
91
|
+
-- A VALUES body cannot name a relation at all; pinned only so the context threading
|
|
92
|
+
-- did not change what a VALUES-bodied member produces.
|
|
93
|
+
|
|
94
|
+
with a as (select id from p1), b as (values (1), (2), (3))
|
|
95
|
+
select (select count(*) from a) as na, (select count(*) from b) as nb;
|
|
96
|
+
→ [{"na":2,"nb":3}]
|
|
97
|
+
|
|
98
|
+
-- ===== Nested WITH clause: the SECOND member sees the ENCLOSING statement's CTE =====
|
|
99
|
+
-- Before the fix this failed with `Table 'o' not found` — the first member alone would
|
|
100
|
+
-- have seen `o`, because the explicit argument was empty for it and the context was
|
|
101
|
+
-- then consulted.
|
|
102
|
+
|
|
103
|
+
with o as (select id from p1)
|
|
104
|
+
select n from (with z as (select 1 as k),
|
|
105
|
+
a as (select count(*) as n from o)
|
|
106
|
+
select n from a) x;
|
|
107
|
+
→ [{"n":2}]
|
|
108
|
+
|
|
109
|
+
-- ===== Nested WITH clause: a sibling shadows a same-named enclosing CTE =====
|
|
110
|
+
|
|
111
|
+
with o as (select 99 as id)
|
|
112
|
+
select n from (with o as (select 7 as id),
|
|
113
|
+
a as (select id as n from o)
|
|
114
|
+
select n from a) x;
|
|
115
|
+
→ [{"n":7}]
|
|
116
|
+
|
|
117
|
+
-- ===== Recursive CTEs unaffected =====
|
|
118
|
+
-- The recursive path gets the same merged map; a non-recursive sibling stays visible to
|
|
119
|
+
-- the base case and the recursion still terminates.
|
|
120
|
+
|
|
121
|
+
with recursive base as (select 1 as k),
|
|
122
|
+
r as (select k from base union all select k + 1 from r where k < 3)
|
|
123
|
+
select k from r order by k;
|
|
124
|
+
→ [{"k":1},{"k":2},{"k":3}]
|
|
125
|
+
|
|
126
|
+
-- ===== Reading a WRITING sibling yields its RETURNING rows, written ONCE =====
|
|
127
|
+
-- `b` reading `a` is what drives `a`'s write. A data-modifying CTE is always
|
|
128
|
+
-- materialized (docs/runtime-caching.md § Shared CTE materialization), so `b` consumes
|
|
129
|
+
-- `a`'s buffered RETURNING rows however many times it names `a`, and `a` writes once.
|
|
130
|
+
|
|
131
|
+
create table q6 (id integer primary key, w integer);
|
|
132
|
+
-- run
|
|
133
|
+
|
|
134
|
+
with a as (insert into q6 values (300, 1) returning id),
|
|
135
|
+
b as (insert into q6 select id + 1, 2 from a returning id)
|
|
136
|
+
select count(*) as n from b;
|
|
137
|
+
→ [{"n":1}]
|
|
138
|
+
|
|
139
|
+
-- Both rows present exactly once — a second drive of `a` would have tripped the
|
|
140
|
+
-- primary key, and a second drive of `b` would have too.
|
|
141
|
+
select id, w from q6 order by id;
|
|
142
|
+
→ [{"id":300,"w":1},{"id":301,"w":2}]
|
|
143
|
+
|
|
144
|
+
-- ===== A writing sibling named TWICE still writes once =====
|
|
145
|
+
|
|
146
|
+
create table q7 (id integer primary key, w integer);
|
|
147
|
+
create table q8 (id integer primary key, w integer);
|
|
148
|
+
-- run
|
|
149
|
+
|
|
150
|
+
with a as (insert into q7 values (400, 1) returning id),
|
|
151
|
+
b as (insert into q8 select id, (select count(*) from a) from a returning id)
|
|
152
|
+
select count(*) as n from b;
|
|
153
|
+
→ [{"n":1}]
|
|
154
|
+
|
|
155
|
+
select id, w from q7 order by id;
|
|
156
|
+
→ [{"id":400,"w":1}]
|
|
157
|
+
select id, w from q8 order by id;
|
|
158
|
+
→ [{"id":400,"w":1}]
|
|
159
|
+
|
|
160
|
+
-- ===== Control: a read-only sibling chain is unchanged =====
|
|
161
|
+
|
|
162
|
+
with a as (select id from p1),
|
|
163
|
+
b as (select id + 100 as id from a),
|
|
164
|
+
c as (select id + 1000 as id from b)
|
|
165
|
+
select id from c order by id;
|
|
166
|
+
→ [{"id":1101},{"id":1102}]
|
|
167
|
+
|
|
168
|
+
-- ===== Negative: a member still cannot name a LATER sibling, or itself =====
|
|
169
|
+
-- The visible map only ever holds members defined BEFORE this one, so a forward or
|
|
170
|
+
-- self reference falls through to ordinary schema lookup and reports table-not-found.
|
|
171
|
+
|
|
172
|
+
create table q9 (id integer primary key, w integer);
|
|
173
|
+
-- run
|
|
174
|
+
|
|
175
|
+
with b as (insert into q9 select id, 1 from a returning id),
|
|
176
|
+
a as (select id from p1)
|
|
177
|
+
select count(*) as n from b;
|
|
178
|
+
-- error: Table 'a' not found
|
|
179
|
+
|
|
180
|
+
with b as (select id from a),
|
|
181
|
+
a as (select id from p1)
|
|
182
|
+
select count(*) as n from b;
|
|
183
|
+
-- error: Table 'a' not found
|
|
184
|
+
|
|
185
|
+
with c as (insert into q9 select id, 1 from c returning id)
|
|
186
|
+
select count(*) as n from c;
|
|
187
|
+
-- error: Table 'c' not found
|
|
188
|
+
|
|
189
|
+
-- ===== A sibling shadows a same-named REAL table inside a writing body =====
|
|
190
|
+
-- `buildFrom` resolves a FROM name against the visible CTEs before the schema, so the
|
|
191
|
+
-- CTE wins over the base table of the same name.
|
|
192
|
+
|
|
193
|
+
create table p1shadow (id integer primary key);
|
|
194
|
+
insert into p1shadow values (1), (2), (3);
|
|
195
|
+
-- run
|
|
196
|
+
|
|
197
|
+
with p1shadow as (select 55 as id),
|
|
198
|
+
b as (insert into q9 select id, 1 from p1shadow returning id)
|
|
199
|
+
select count(*) as n from b;
|
|
200
|
+
→ [{"n":1}]
|
|
201
|
+
|
|
202
|
+
select id, w from q9 order by id;
|
|
203
|
+
→ [{"id":55,"w":1}]
|
|
204
|
+
|
|
205
|
+
-- ===== Three clause levels deep =====
|
|
206
|
+
-- Coverage above stops at two; this pins that the merge composes at each level.
|
|
207
|
+
|
|
208
|
+
with o as (select 1 as k)
|
|
209
|
+
select n from (with z as (select 2 as k)
|
|
210
|
+
select n from (with y as (select 3 as k)
|
|
211
|
+
select (select k from o) + (select k from z)
|
|
212
|
+
+ (select k from y) as n) i) m;
|
|
213
|
+
→ [{"n":6}]
|
|
214
|
+
|
|
215
|
+
-- Cleanup
|
|
216
|
+
drop table p1;
|
|
217
|
+
drop table p1shadow;
|
|
218
|
+
drop table q9;
|
|
219
|
+
drop table q1;
|
|
220
|
+
drop table q2;
|
|
221
|
+
drop table q3;
|
|
222
|
+
drop table q4;
|
|
223
|
+
drop table q5;
|
|
224
|
+
drop table q6;
|
|
225
|
+
drop table q7;
|
|
226
|
+
drop table q8;
|
|
227
|
+
-- run
|