@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.
Files changed (400) hide show
  1. package/README.md +2 -0
  2. package/dist/src/common/types.d.ts +4 -4
  3. package/dist/src/index.d.ts +1 -1
  4. package/dist/src/index.d.ts.map +1 -1
  5. package/dist/src/index.js +3 -2
  6. package/dist/src/index.js.map +1 -1
  7. package/dist/src/schema/catalog-rendering.js +13 -1
  8. package/dist/src/schema/catalog-rendering.js.map +1 -1
  9. package/dist/src/schema/catalog.d.ts +35 -2
  10. package/dist/src/schema/catalog.d.ts.map +1 -1
  11. package/dist/src/schema/catalog.js +42 -33
  12. package/dist/src/schema/catalog.js.map +1 -1
  13. package/dist/src/schema/schema-differ.d.ts +1 -1
  14. package/dist/src/schema/schema-differ.d.ts.map +1 -1
  15. package/dist/src/schema/schema-differ.js +195 -33
  16. package/dist/src/schema/schema-differ.js.map +1 -1
  17. package/dist/src/schema/unique-enforcement.d.ts +23 -1
  18. package/dist/src/schema/unique-enforcement.d.ts.map +1 -1
  19. package/dist/src/schema/unique-enforcement.js +43 -1
  20. package/dist/src/schema/unique-enforcement.js.map +1 -1
  21. package/dist/src/vtab/memory/layer/manager.d.ts +15 -12
  22. package/dist/src/vtab/memory/layer/manager.d.ts.map +1 -1
  23. package/dist/src/vtab/memory/layer/manager.js +87 -100
  24. package/dist/src/vtab/memory/layer/manager.js.map +1 -1
  25. package/package.json +7 -4
  26. package/test/README.md +173 -0
  27. package/test/logic/01-basic.sqllogic +39 -0
  28. package/test/logic/01.1-select-projection-extras.sqllogic +130 -0
  29. package/test/logic/01.2-strings.sqllogic +43 -0
  30. package/test/logic/01.5-insert-select.sqllogic +237 -0
  31. package/test/logic/01.6-update-extras.sqllogic +118 -0
  32. package/test/logic/01.7-update-from.sqllogic +67 -0
  33. package/test/logic/01.8-delete-extras.sqllogic +122 -0
  34. package/test/logic/01.8.1-delete-range-cow.sqllogic +115 -0
  35. package/test/logic/01.9-query-expr-dml-gates.sqllogic +32 -0
  36. package/test/logic/01.9-query-expr-dml.sqllogic +171 -0
  37. package/test/logic/01.9-query-expr-values.sqllogic +111 -0
  38. package/test/logic/01.9.1-limit-over-dml-subquery.sqllogic +119 -0
  39. package/test/logic/02-filters.sqllogic +54 -0
  40. package/test/logic/02-smoke.sqllogic +62 -0
  41. package/test/logic/02.1-bind-parameters.sqllogic +223 -0
  42. package/test/logic/03-expressions.sqllogic +190 -0
  43. package/test/logic/03.1-quoted-identifiers.sqllogic +55 -0
  44. package/test/logic/03.4-defaults.sqllogic +554 -0
  45. package/test/logic/03.4.1-default-edge-cases.sqllogic +99 -0
  46. package/test/logic/03.5-tvf.sqllogic +61 -0
  47. package/test/logic/03.6-type-system.sqllogic +544 -0
  48. package/test/logic/03.6.1-numeric-text-comparison-coercion.sqllogic +244 -0
  49. package/test/logic/03.6.2-value-to-text.sqllogic +224 -0
  50. package/test/logic/03.7-bigint-mixed-arithmetic.sqllogic +65 -0
  51. package/test/logic/03.8-not-precedence.sqllogic +255 -0
  52. package/test/logic/03.9-is-bool-predicate.sqllogic +150 -0
  53. package/test/logic/03.9.1-is-bool-predicate-partial-index.sqllogic +34 -0
  54. package/test/logic/04-order-by.sqllogic +38 -0
  55. package/test/logic/04-transactions.sqllogic +239 -0
  56. package/test/logic/04a-savepoint-lazy-attach.sqllogic +122 -0
  57. package/test/logic/05-vtab_memory.sqllogic +50 -0
  58. package/test/logic/05.0.1-vtab-memory-unique-index-collation.sqllogic +34 -0
  59. package/test/logic/05.1-composite-pk-range-scan.sqllogic +147 -0
  60. package/test/logic/05.1.1-secondary-index-range-scan.sqllogic +56 -0
  61. package/test/logic/05.2-cast-seek-correctness.sqllogic +124 -0
  62. package/test/logic/06-builtin_functions.sqllogic +149 -0
  63. package/test/logic/06.1-string-functions.sqllogic +92 -0
  64. package/test/logic/06.1.3-like-glob-edges.sqllogic +53 -0
  65. package/test/logic/06.2-math-functions.sqllogic +82 -0
  66. package/test/logic/06.3-schema.sqllogic +48 -0
  67. package/test/logic/06.3.1-schema-all-schemas.sqllogic +39 -0
  68. package/test/logic/06.3.2-schema-foreign-keys.sqllogic +208 -0
  69. package/test/logic/06.3.3-introspection-tags.sqllogic +202 -0
  70. package/test/logic/06.3.3.1-introspection-tags-index.sqllogic +74 -0
  71. package/test/logic/06.3.4-view-info.sqllogic +378 -0
  72. package/test/logic/06.3.5-column-info.sqllogic +347 -0
  73. package/test/logic/06.3.6-schema-views.sqllogic +29 -0
  74. package/test/logic/06.4-schema-search-path.sqllogic +354 -0
  75. package/test/logic/06.4.1-schema-case-insensitive.sqllogic +83 -0
  76. package/test/logic/06.4.2-collation-extras.sqllogic +472 -0
  77. package/test/logic/06.4.2.1-collation-index-access-paths.sqllogic +140 -0
  78. package/test/logic/06.4.3-write-path-collation.sqllogic +99 -0
  79. package/test/logic/06.4.4-comparison-collation-precedence.sqllogic +342 -0
  80. package/test/logic/06.4.5-any-collate-declared-keys.sqllogic +92 -0
  81. package/test/logic/06.5-polymorphic-types.sqllogic +169 -0
  82. package/test/logic/06.5.1-conversion-functions.sqllogic +173 -0
  83. package/test/logic/06.5.2-scalar-minmax.sqllogic +16 -0
  84. package/test/logic/06.5.3-undeclared-return-type-comparison.sqllogic +244 -0
  85. package/test/logic/06.5.4-declared-return-type-builtins.sqllogic +288 -0
  86. package/test/logic/06.6-aggregate-extended.sqllogic +78 -0
  87. package/test/logic/06.7-json-extended.sqllogic +53 -0
  88. package/test/logic/06.8-json-path-operators.sqllogic +99 -0
  89. package/test/logic/06.9-json-canonical-key.sqllogic +65 -0
  90. package/test/logic/06.9.1-json-coerce-once.sqllogic +417 -0
  91. package/test/logic/06.9.1.1-json-coerce-once-index.sqllogic +39 -0
  92. package/test/logic/06.9.2-json-structural-equality.sqllogic +382 -0
  93. package/test/logic/06.9.2.1-json-structural-equality-index.sqllogic +76 -0
  94. package/test/logic/06.9.3-json-index-range-seek.sqllogic +205 -0
  95. package/test/logic/07-aggregates.sqllogic +193 -0
  96. package/test/logic/07.1-aggregate-filter-clause.sqllogic +12 -0
  97. package/test/logic/07.2-aggregate-order-by.sqllogic +11 -0
  98. package/test/logic/07.3-group-by-extras.sqllogic +602 -0
  99. package/test/logic/07.3.1-group-by-order-by-key.sqllogic +164 -0
  100. package/test/logic/07.3.2-grouped-select-list-shape.sqllogic +231 -0
  101. package/test/logic/07.4-group-by-filter-composite-pk.sqllogic +120 -0
  102. package/test/logic/07.5-sum-mixed-exact-and-float.sqllogic +151 -0
  103. package/test/logic/07.5-window.sqllogic +1941 -0
  104. package/test/logic/07.5.1-window-named.sqllogic +13 -0
  105. package/test/logic/07.5.2-window-nth-value.sqllogic +13 -0
  106. package/test/logic/07.6-subqueries.sqllogic +78 -0
  107. package/test/logic/07.6.1-subquery-extras.sqllogic +93 -0
  108. package/test/logic/07.7-and-or-short-circuit.sqllogic +58 -0
  109. package/test/logic/07.7-in-subquery-caching.sqllogic +174 -0
  110. package/test/logic/07.7-scalar-agg-decorrelation.sqllogic +197 -0
  111. package/test/logic/07.7.1-in-extras.sqllogic +158 -0
  112. package/test/logic/07.7.1-scalar-agg-decorrelation-filter.sqllogic +105 -0
  113. package/test/logic/07.7.2-scalar-agg-decorrelation-nested.sqllogic +115 -0
  114. package/test/logic/07.7.3-exists-in-select-decorrelation.sqllogic +107 -0
  115. package/test/logic/07.7.4-where-conjunct-ordering.sqllogic +121 -0
  116. package/test/logic/07.7.5-filter-lost-under-index-order.sqllogic +134 -0
  117. package/test/logic/07.7.6-correlated-predicate-scope.sqllogic +178 -0
  118. package/test/logic/07.7.7-join-source-scope-shadowing.sqllogic +137 -0
  119. package/test/logic/07.7.8-correlated-ref-to-computed-column.sqllogic +165 -0
  120. package/test/logic/07.7.9-conjunct-monotonicity.sqllogic +200 -0
  121. package/test/logic/07.8-correlated-subquery-edges.sqllogic +71 -0
  122. package/test/logic/07.8.1-correlated-in-decorrelation-gates.sqllogic +156 -0
  123. package/test/logic/07.9-in-value-list.sqllogic +154 -0
  124. package/test/logic/07.9.1-in-value-list-composite-index.sqllogic +38 -0
  125. package/test/logic/08-views.sqllogic +64 -0
  126. package/test/logic/08.1-semi-anti-join.sqllogic +191 -0
  127. package/test/logic/08.1-view-edge-cases.sqllogic +118 -0
  128. package/test/logic/08.1.1-uncorrelated-in-semijoin.sqllogic +251 -0
  129. package/test/logic/08.2-existence-flag-semijoin-recovery.sqllogic +197 -0
  130. package/test/logic/08.3-existence-flag-inner-recovery.sqllogic +102 -0
  131. package/test/logic/08.4-key-set-semi-join.sqllogic +447 -0
  132. package/test/logic/09-set_operations.sqllogic +244 -0
  133. package/test/logic/09.1-set-op-cross-collation.sqllogic +230 -0
  134. package/test/logic/10-distinct_datatypes.sqllogic +127 -0
  135. package/test/logic/10.1-ddl-lifecycle.sqllogic +203 -0
  136. package/test/logic/10.1.1-create-table-syntax-edges.sqllogic +47 -0
  137. package/test/logic/10.1.2-ddl-in-transaction.sqllogic +143 -0
  138. package/test/logic/10.1.2.1-add-constraint-in-transaction.sqllogic +59 -0
  139. package/test/logic/10.1.3-ddl-drop-in-transaction.sqllogic +187 -0
  140. package/test/logic/10.1.3.1-drop-constraint-in-transaction.sqllogic +45 -0
  141. package/test/logic/10.1.4-create-table-duplicate-constraint-names.sqllogic +149 -0
  142. package/test/logic/10.1.4-ddl-transaction-policy.sqllogic +314 -0
  143. package/test/logic/10.1.5-alter-add-constraint-minted-name-disambiguation.sqllogic +219 -0
  144. package/test/logic/10.1.5-create-index-lifecycle.sqllogic +72 -0
  145. package/test/logic/10.1.6-ddl-transaction-policy-index.sqllogic +143 -0
  146. package/test/logic/10.1.7-create-table-default-type-check.sqllogic +119 -0
  147. package/test/logic/10.1.8-alter-add-check-existing-rows.sqllogic +117 -0
  148. package/test/logic/10.2-column-features.sqllogic +365 -0
  149. package/test/logic/10.2.1-table-options-rejection.sqllogic +63 -0
  150. package/test/logic/10.2.2-default-collation-memory.sqllogic +30 -0
  151. package/test/logic/10.3-function-features.sqllogic +247 -0
  152. package/test/logic/10.4-schema-scale.sqllogic +168 -0
  153. package/test/logic/10.4.1-schema-scale-indexes.sqllogic +121 -0
  154. package/test/logic/10.5-indexes.sqllogic +164 -0
  155. package/test/logic/10.5.1-partial-indexes.sqllogic +526 -0
  156. package/test/logic/10.5.2-expression-indexes.sqllogic +34 -0
  157. package/test/logic/10.5.3-desc-index-ordering.sqllogic +130 -0
  158. package/test/logic/10.5.4-composite-pk-index-update-phantom.sqllogic +55 -0
  159. package/test/logic/10.5.5-index-name-uniqueness.sqllogic +76 -0
  160. package/test/logic/10.5.6-minmax-index-boundary.sqllogic +204 -0
  161. package/test/logic/10.5.7-implicit-unique-index-lifecycle.sqllogic +1216 -0
  162. package/test/logic/10.6-distinct-edge-cases.sqllogic +119 -0
  163. package/test/logic/100-predicate-normalization-edge-cases.sqllogic +238 -0
  164. package/test/logic/100.1-where-extras.sqllogic +163 -0
  165. package/test/logic/100.1.1-where-join-on-order-indexed.sqllogic +35 -0
  166. package/test/logic/101-builtin-mutation-kills.sqllogic +974 -0
  167. package/test/logic/101-transaction-edge-cases.sqllogic +395 -0
  168. package/test/logic/102-schema-catalog-edge-cases.sqllogic +252 -0
  169. package/test/logic/102-unique-constraints.sqllogic +145 -0
  170. package/test/logic/102.0.1-schema-catalog-indexed-table.sqllogic +32 -0
  171. package/test/logic/102.1-unique-edge-cases.sqllogic +111 -0
  172. package/test/logic/102.1.1-unique-index-creation-edge-cases.sqllogic +75 -0
  173. package/test/logic/102.2-unique-collation.sqllogic +181 -0
  174. package/test/logic/102.2.1-unique-collation-index-derived.sqllogic +305 -0
  175. package/test/logic/103-database-options-edge-cases.sqllogic +108 -0
  176. package/test/logic/103.1-pragma-boolean-values.sqllogic +126 -0
  177. package/test/logic/104-emit-mutation-kills.sqllogic +236 -0
  178. package/test/logic/105-vtab-memory-mutation-kills.sqllogic +754 -0
  179. package/test/logic/105.1-vtab-memory-index-mutation-kills.sqllogic +540 -0
  180. package/test/logic/106-constraint-extractor-mutation-kills.sqllogic +350 -0
  181. package/test/logic/107-temporal-arithmetic-mutation-kills.sqllogic +833 -0
  182. package/test/logic/108-cardinality-estimation.sqllogic +146 -0
  183. package/test/logic/108.1-analyze-name-resolution.sqllogic +102 -0
  184. package/test/logic/109-aggregate-physical-selection.sqllogic +103 -0
  185. package/test/logic/11-joins.sqllogic +86 -0
  186. package/test/logic/11.1-join-using.sqllogic +267 -0
  187. package/test/logic/11.2-comma-join.sqllogic +35 -0
  188. package/test/logic/11.3-index-nested-loop-join.sqllogic +305 -0
  189. package/test/logic/11.3-mismatched-collation-join.sqllogic +74 -0
  190. package/test/logic/11.4-hash-join-side-swap.sqllogic +118 -0
  191. package/test/logic/110-scan-emitter-mutation-kills.sqllogic +121 -0
  192. package/test/logic/110.1-scan-emitter-index-scan-kills.sqllogic +47 -0
  193. package/test/logic/12-empty-primary-key.sqllogic +124 -0
  194. package/test/logic/12-join_padding_order.sqllogic +58 -0
  195. package/test/logic/12.1-orderby-index-consumption.sqllogic +40 -0
  196. package/test/logic/13-cte.sqllogic +137 -0
  197. package/test/logic/13.1-cte-multiple-recursive.sqllogic +104 -0
  198. package/test/logic/13.10-cte-qualified-name.sqllogic +136 -0
  199. package/test/logic/13.11-unreferenced-dml-cte.sqllogic +414 -0
  200. package/test/logic/13.12-nested-dml-cte-rejected.sqllogic +280 -0
  201. package/test/logic/13.2-cte-bind-params.sqllogic +98 -0
  202. package/test/logic/13.3-cte-edge-cases.sqllogic +120 -0
  203. package/test/logic/13.4-cte-extras.sqllogic +98 -0
  204. package/test/logic/13.5-cte-join-order.sqllogic +166 -0
  205. package/test/logic/13.6-cte-dml-runs-once.sqllogic +318 -0
  206. package/test/logic/13.7-cte-sibling-visibility.sqllogic +227 -0
  207. package/test/logic/13.8-insert-with-clause-visibility.sqllogic +254 -0
  208. package/test/logic/13.9-schema-authored-cte-isolation.sqllogic +328 -0
  209. package/test/logic/13.9.1-schema-authored-schema-path-isolation.sqllogic +408 -0
  210. package/test/logic/14-utilities.sqllogic +168 -0
  211. package/test/logic/15-timespan.sqllogic +279 -0
  212. package/test/logic/15.1-semantic-ordering.sqllogic +960 -0
  213. package/test/logic/15.1.1-json-check-coercion.sqllogic +178 -0
  214. package/test/logic/15.1.2-semantic-ordering-index.sqllogic +41 -0
  215. package/test/logic/15.1.3-declared-form-write-contract.sqllogic +519 -0
  216. package/test/logic/16-epoch.sqllogic +187 -0
  217. package/test/logic/17-weekday-modifier.sqllogic +78 -0
  218. package/test/logic/18-json-string-escapes.sqllogic +86 -0
  219. package/test/logic/18-strftime-extended-formats.sqllogic +68 -0
  220. package/test/logic/20-empty-single-row.sqllogic +261 -0
  221. package/test/logic/21-null-edge-cases.sqllogic +227 -0
  222. package/test/logic/21.1-where-null-comparisons.sqllogic +151 -0
  223. package/test/logic/21.1.1-where-null-comparisons-secondary-index.sqllogic +35 -0
  224. package/test/logic/21.2-between-edges.sqllogic +157 -0
  225. package/test/logic/22-boundary-values.sqllogic +175 -0
  226. package/test/logic/23-self-joins-duplicates.sqllogic +74 -0
  227. package/test/logic/24-builtin-branches.sqllogic +611 -0
  228. package/test/logic/24.1-substr-extras.sqllogic +75 -0
  229. package/test/logic/24.2-random-extras.sqllogic +39 -0
  230. package/test/logic/25-aggregate-edge-cases.sqllogic +289 -0
  231. package/test/logic/25.1-nested-aggregates.sqllogic +74 -0
  232. package/test/logic/25.2-having-edge-cases.sqllogic +318 -0
  233. package/test/logic/25.3-aggregate-isnull-empty.sqllogic +16 -0
  234. package/test/logic/25.4-groupby-fd-constant-empty.sqllogic +55 -0
  235. package/test/logic/25.5-ungrouped-aggregate-column-free-select-item.sqllogic +196 -0
  236. package/test/logic/26-join-edge-cases.sqllogic +333 -0
  237. package/test/logic/26.1-left-join-isnull-on-notnull.sqllogic +26 -0
  238. package/test/logic/26.2-left-join-on-vs-where.sqllogic +67 -0
  239. package/test/logic/26.3-join-on-constants.sqllogic +61 -0
  240. package/test/logic/26.4-join-on-is-null-nullable.sqllogic +44 -0
  241. package/test/logic/27-window-edge-cases.sqllogic +206 -0
  242. package/test/logic/27.1-window-groups-frame.sqllogic +13 -0
  243. package/test/logic/27.2-window-exclude.sqllogic +13 -0
  244. package/test/logic/27.3-window-json-aggregation.sqllogic +66 -0
  245. package/test/logic/28-set-ops-sort-edge-cases.sqllogic +444 -0
  246. package/test/logic/28.1-compound-limit-offset.sqllogic +143 -0
  247. package/test/logic/28.2-orderby-expression-extras.sqllogic +698 -0
  248. package/test/logic/28.2-set-op-branch-types.sqllogic +217 -0
  249. package/test/logic/29-constraint-edge-cases.sqllogic +442 -0
  250. package/test/logic/29.1-column-level-conflict-clause.sqllogic +171 -0
  251. package/test/logic/29.2-table-level-pk-conflict-clause.sqllogic +113 -0
  252. package/test/logic/40-constraints.sqllogic +418 -0
  253. package/test/logic/40.1-pk-desc-direction.sqllogic +76 -0
  254. package/test/logic/40.2-check-extras.sqllogic +683 -0
  255. package/test/logic/41-alter-table.sqllogic +191 -0
  256. package/test/logic/41-fk-cascade-conflict-and-self-ref.sqllogic +263 -0
  257. package/test/logic/41-fk-cross-schema.sqllogic +155 -0
  258. package/test/logic/41-fk-extended-targets.sqllogic +173 -0
  259. package/test/logic/41-foreign-keys.sqllogic +1001 -0
  260. package/test/logic/41-generated-column-errors.sqllogic +225 -0
  261. package/test/logic/41-generated-column-extras.sqllogic +598 -0
  262. package/test/logic/41-generated-column-scope.sqllogic +329 -0
  263. package/test/logic/41-generated-columns.sqllogic +361 -0
  264. package/test/logic/41.1-alter-pk.sqllogic +230 -0
  265. package/test/logic/41.1-fk-collation-conflict.sqllogic +277 -0
  266. package/test/logic/41.10-alter-drop-column-foreign-key.sqllogic +274 -0
  267. package/test/logic/41.10.1-alter-drop-column-unique-index.sqllogic +169 -0
  268. package/test/logic/41.10.2-alter-drop-column-check-and-assertion.sqllogic +1616 -0
  269. package/test/logic/41.10.3-alter-drop-column-referencing-fk.sqllogic +292 -0
  270. package/test/logic/41.10.4-drop-object-expression-dependents.sqllogic +602 -0
  271. package/test/logic/41.11-deferred-fk-with-rename.sqllogic +232 -0
  272. package/test/logic/41.12-alter-default-coercion.sqllogic +200 -0
  273. package/test/logic/41.13-alter-add-column-generated-backfill.sqllogic +566 -0
  274. package/test/logic/41.14-alter-add-column-subquery-backfill.sqllogic +129 -0
  275. package/test/logic/41.15-alter-column-default-type-check.sqllogic +178 -0
  276. package/test/logic/41.16-fk-unenforceable.sqllogic +364 -0
  277. package/test/logic/41.2-alter-column.sqllogic +382 -0
  278. package/test/logic/41.2.1-alter-column-retype-deleted-row-memory.sqllogic +32 -0
  279. package/test/logic/41.2.2-alter-column-retype-index-rebuild.sqllogic +77 -0
  280. package/test/logic/41.2.3-alter-column-set-not-null-pk-backfill.sqllogic +310 -0
  281. package/test/logic/41.2.3.1-alter-column-set-not-null-pk-backfill-secondary-index.sqllogic +37 -0
  282. package/test/logic/41.3-alter-add-column-unique.sqllogic +184 -0
  283. package/test/logic/41.3-alter-rename-propagation.sqllogic +2352 -0
  284. package/test/logic/41.3.1-alter-rename-index-propagation.sqllogic +94 -0
  285. package/test/logic/41.4-alter-add-column-constraints.sqllogic +855 -0
  286. package/test/logic/41.5-alter-misc.sqllogic +48 -0
  287. package/test/logic/41.5-cross-schema-foreign-keys.sqllogic +253 -0
  288. package/test/logic/41.6-alter-drop-rename-constraint.sqllogic +354 -0
  289. package/test/logic/41.6.1-alter-drop-constraint-index-derived.sqllogic +22 -0
  290. package/test/logic/41.7-alter-column-collate.sqllogic +105 -0
  291. package/test/logic/41.7.1-alter-column-collate-unique.sqllogic +45 -0
  292. package/test/logic/41.7.2-alter-column-collate-unique-store.sqllogic +208 -0
  293. package/test/logic/41.7.2.1-alter-column-collate-unique-index-store.sqllogic +114 -0
  294. package/test/logic/41.7.3-alter-column-retype-unique.sqllogic +293 -0
  295. package/test/logic/41.7.3.1-alter-column-retype-staged-rows-memory.sqllogic +41 -0
  296. package/test/logic/41.7.3.2-alter-column-retype-unique-index.sqllogic +72 -0
  297. package/test/logic/41.7.4-alter-column-retype-semantic-memory.sqllogic +445 -0
  298. package/test/logic/41.7.4.1-alter-column-retype-semantic-index-memory.sqllogic +91 -0
  299. package/test/logic/41.7.5-alter-column-collate-pk-staged-delete-memory.sqllogic +106 -0
  300. package/test/logic/41.8-alter-add-constraint-unique-fk.sqllogic +275 -0
  301. package/test/logic/41.8-alter-savepoint-staged-rows.sqllogic +443 -0
  302. package/test/logic/41.8.1-alter-rename-savepoint-staged-rows.sqllogic +408 -0
  303. package/test/logic/41.9-alter-constraint-body-change.sqllogic +180 -0
  304. package/test/logic/41.9-fk-restrict-batched.sqllogic +290 -0
  305. package/test/logic/42-committed-snapshot.sqllogic +254 -0
  306. package/test/logic/42-returning.sqllogic +159 -0
  307. package/test/logic/42.1-returning-extras.sqllogic +232 -0
  308. package/test/logic/42.2-returning-stored-row.sqllogic +165 -0
  309. package/test/logic/43-default-nullability.sqllogic +131 -0
  310. package/test/logic/43-transition-constraints.sqllogic +341 -0
  311. package/test/logic/43.1-default-collation.sqllogic +140 -0
  312. package/test/logic/43.1-notnull-or-conflict.sqllogic +79 -0
  313. package/test/logic/43.2-deferred-check-new-on-delete.sqllogic +95 -0
  314. package/test/logic/43.3-nullable-primary-key.sqllogic +587 -0
  315. package/test/logic/44-determinism-validation.sqllogic +164 -0
  316. package/test/logic/44-orthogonality.sqllogic +146 -0
  317. package/test/logic/44.1-nondeterministic-schema.sqllogic +316 -0
  318. package/test/logic/45-udf-determinism.sqllogic +39 -0
  319. package/test/logic/46-mutation-context.sqllogic +595 -0
  320. package/test/logic/47-upsert.sqllogic +255 -0
  321. package/test/logic/47.1-upsert-conflict-targets.sqllogic +169 -0
  322. package/test/logic/47.2-replace-and-or-clauses.sqllogic +164 -0
  323. package/test/logic/47.2.1-pk-replace-secondary-unique.sqllogic +374 -0
  324. package/test/logic/47.3-engine-or-fail.sqllogic +122 -0
  325. package/test/logic/47.3-upsert-conflict-target-collation.sqllogic +139 -0
  326. package/test/logic/47.3.1-upsert-conflict-index-derived-collation.sqllogic +25 -0
  327. package/test/logic/47.4-upsert-conflict-target-affinity.sqllogic +59 -0
  328. package/test/logic/47.5-upsert-do-update-constraints.sqllogic +440 -0
  329. package/test/logic/47.6-upsert-do-update-decomposed.sqllogic +100 -0
  330. package/test/logic/49-reference-graph.sqllogic +84 -0
  331. package/test/logic/50-declarative-schema.sqllogic +2550 -0
  332. package/test/logic/50-metadata-tags.sqllogic +1033 -0
  333. package/test/logic/50.0.1-metadata-tags-index.sqllogic +141 -0
  334. package/test/logic/50.1-declare-schema-pk.sqllogic +150 -0
  335. package/test/logic/50.2-declare-schema-renames.sqllogic +949 -0
  336. package/test/logic/50.2.1-declare-schema-index-renames.sqllogic +173 -0
  337. package/test/logic/50.3-declare-schema-duplicate-names.sqllogic +280 -0
  338. package/test/logic/50.4-declare-schema-apply-restore.sqllogic +192 -0
  339. package/test/logic/51-lens-foundation.sqllogic +147 -0
  340. package/test/logic/51-materialized-views.sqllogic +376 -0
  341. package/test/logic/51.5-materialized-views-coarsened-key.sqllogic +198 -0
  342. package/test/logic/51.7-maintained-table-attach-detach.sqllogic +468 -0
  343. package/test/logic/51.8-maintained-table-declared-constraints.sqllogic +440 -0
  344. package/test/logic/51.85-maintained-table-parent-fk.sqllogic +103 -0
  345. package/test/logic/51.9-maintained-table-secondary-unique.sqllogic +237 -0
  346. package/test/logic/51.9.1-maintained-table-partial-unique.sqllogic +36 -0
  347. package/test/logic/52-lens-overrides.sqllogic +566 -0
  348. package/test/logic/53-materialized-views-rowtime.sqllogic +1601 -0
  349. package/test/logic/53-reserved-tags.sqllogic +252 -0
  350. package/test/logic/53.1-materialized-view-write-through.sqllogic +329 -0
  351. package/test/logic/53.2-materialized-view-rename-propagation.sqllogic +483 -0
  352. package/test/logic/53.3-materialized-view-constraint-only-ddl.sqllogic +409 -0
  353. package/test/logic/53.3.1-materialized-view-index-ddl-irrelevance.sqllogic +29 -0
  354. package/test/logic/53.4-materialized-view-structural-alter-restore.sqllogic +436 -0
  355. package/test/logic/54-covering-mv-enforcement.sqllogic +314 -0
  356. package/test/logic/54.1-covering-mv-partial-enforcement.sqllogic +34 -0
  357. package/test/logic/55-internal-eviction-reporting.sqllogic +89 -0
  358. package/test/logic/55-lens-prover.sqllogic +202 -0
  359. package/test/logic/55.1-eviction-restrict-fk.sqllogic +148 -0
  360. package/test/logic/55.5-lens-authored-inverse.sqllogic +1468 -0
  361. package/test/logic/80-grow-retrieve-pass.sqllogic +79 -0
  362. package/test/logic/81-quickpick.sqllogic +24 -0
  363. package/test/logic/82-bloom-join.sqllogic +185 -0
  364. package/test/logic/83-merge-join.sqllogic +280 -0
  365. package/test/logic/84-asof-scan.sqllogic +238 -0
  366. package/test/logic/84-key-cardinality.sqllogic +50 -0
  367. package/test/logic/85-relational-const-folding.sqllogic +51 -0
  368. package/test/logic/86-scalar-cse.sqllogic +42 -0
  369. package/test/logic/90-error_paths.sqllogic +114 -0
  370. package/test/logic/90.1-parse-errors.sqllogic +77 -0
  371. package/test/logic/90.2-alter-table-errors.sqllogic +53 -0
  372. package/test/logic/90.2.1-alter-extra-errors.sqllogic +51 -0
  373. package/test/logic/90.3-expression-errors.sqllogic +43 -0
  374. package/test/logic/90.4-dml-errors.sqllogic +47 -0
  375. package/test/logic/90.5-unsupported-join-types.sqllogic +37 -0
  376. package/test/logic/90.5.1-right-full-join-read.sqllogic +157 -0
  377. package/test/logic/90.6-select-error-paths.sqllogic +57 -0
  378. package/test/logic/91-merge-join-edge-cases.sqllogic +159 -0
  379. package/test/logic/92-hash-aggregate-edge-cases.sqllogic +139 -0
  380. package/test/logic/93-ddl-view-edge-cases.sqllogic +104 -0
  381. package/test/logic/93.1-view-error-paths.sqllogic +74 -0
  382. package/test/logic/93.2-view-mutation-pending.sqllogic +108 -0
  383. package/test/logic/93.3-view-mutation-or-clause.sqllogic +60 -0
  384. package/test/logic/93.4-view-mutation.sqllogic +4881 -0
  385. package/test/logic/93.4.1-view-mutation-partial-unique-cardinality.sqllogic +31 -0
  386. package/test/logic/93.5-authored-inverse.sqllogic +415 -0
  387. package/test/logic/93.6-set-op-flagless-write.sqllogic +862 -0
  388. package/test/logic/94-tvf-edge-cases.sqllogic +58 -0
  389. package/test/logic/94.1-limit-offset-edge-cases.sqllogic +109 -0
  390. package/test/logic/94.2-limit-offset-extras.sqllogic +98 -0
  391. package/test/logic/95-assertions.sqllogic +1417 -0
  392. package/test/logic/96-subquery-edge-cases.sqllogic +276 -0
  393. package/test/logic/97-json-function-edge-cases.sqllogic +633 -0
  394. package/test/logic/97.1-json-blob-and-special-values.sqllogic +92 -0
  395. package/test/logic/98-temporal-edge-cases.sqllogic +515 -0
  396. package/test/logic/99-conversion-edge-cases.sqllogic +325 -0
  397. package/test/logic/99.0.1-schema-index-listing.sqllogic +21 -0
  398. package/test/logic/99.1-cast-syntax-extras.sqllogic +167 -0
  399. package/test/logic/drop-unique-index.sqllogic +88 -0
  400. package/test/logic/pushdown-test.sqllogic +36 -0
@@ -0,0 +1,633 @@
1
+ -- 97-json-function-edge-cases.sqllogic
2
+ -- Targeted coverage for uncovered branches in json.ts and json-helpers.ts:
3
+ -- json_valid Uint8Array, json_schema, json_type paths, json_extract fallback,
4
+ -- json_quote special types, json_object odd args, json_array_length non-string path,
5
+ -- json_patch error paths, json_insert/replace/set/remove edge cases,
6
+ -- json_group_array/object aggregation, coerceToJsonValue, prepareJsonValue,
7
+ -- resolveJsonPathForModify createParents, deepCopyJson, getJsonType, evaluateJsonPathBasic
8
+
9
+ -- ============================================================
10
+ -- json_valid: additional edge cases
11
+ -- ============================================================
12
+
13
+ -- Null input returns false
14
+ SELECT json_valid(null) as result;
15
+ → [{"result":false}]
16
+
17
+ -- Numeric types are valid JSON
18
+ SELECT json_valid(0) as result;
19
+ → [{"result":true}]
20
+
21
+ SELECT json_valid(3.14) as result;
22
+ → [{"result":true}]
23
+
24
+ -- Boolean types are valid JSON
25
+ SELECT json_valid(true) as result;
26
+ → [{"result":true}]
27
+
28
+ SELECT json_valid(false) as result;
29
+ → [{"result":true}]
30
+
31
+ -- Native objects are valid
32
+ SELECT json_valid(json_object('a', 1)) as result;
33
+ → [{"result":true}]
34
+
35
+ -- Malformed JSON strings
36
+ SELECT json_valid('{missing_quotes: 1}') as result;
37
+ → [{"result":false}]
38
+
39
+ SELECT json_valid('{"truncated":') as result;
40
+ → [{"result":false}]
41
+
42
+ SELECT json_valid('{]') as result;
43
+ → [{"result":false}]
44
+
45
+ -- ============================================================
46
+ -- json_schema: validation
47
+ -- ============================================================
48
+
49
+ -- Valid schema matching (use comma-separated fields to avoid semicolons)
50
+ SELECT json_schema('{"name":"Alice","age":30}', '{ name: string, age: number }') as result;
51
+ → [{"result":true}]
52
+
53
+ -- Schema mismatch
54
+ SELECT json_schema('{"name":"Alice","age":"thirty"}', '{ name: string, age: number }') as result;
55
+ → [{"result":false}]
56
+
57
+ -- Non-string schema returns false
58
+ SELECT json_schema('{"a":1}', 42) as result;
59
+ → [{"result":false}]
60
+
61
+ -- Invalid JSON input returns false
62
+ SELECT json_schema('not-json', '{ name: string }') as result;
63
+ → [{"result":false}]
64
+
65
+ -- Invalid schema syntax returns false
66
+ SELECT json_schema('{"a":1}', '!!!invalid!!!') as result;
67
+ → [{"result":false}]
68
+
69
+ -- Null input returns false
70
+ SELECT json_schema(null, '{ name: string }') as result;
71
+ → [{"result":false}]
72
+
73
+ -- ============================================================
74
+ -- json_type: path and edge cases
75
+ -- ============================================================
76
+
77
+ -- json_type with path argument
78
+ SELECT json_type('{"a":42}', '$.a') as result;
79
+ → [{"result":"integer"}]
80
+
81
+ SELECT json_type('{"a":3.14}', '$.a') as result;
82
+ → [{"result":"real"}]
83
+
84
+ SELECT json_type('{"a":"hello"}', '$.a') as result;
85
+ → [{"result":"text"}]
86
+
87
+ SELECT json_type('{"a":true}', '$.a') as result;
88
+ → [{"result":"true"}]
89
+
90
+ SELECT json_type('{"a":false}', '$.a') as result;
91
+ → [{"result":"false"}]
92
+
93
+ SELECT json_type('{"a":null}', '$.a') as result;
94
+ → [{"result":"null"}]
95
+
96
+ SELECT json_type('{"a":[1,2]}', '$.a') as result;
97
+ → [{"result":"array"}]
98
+
99
+ SELECT json_type('{"a":{"b":1}}', '$.a') as result;
100
+ → [{"result":"object"}]
101
+
102
+ -- Non-existent path returns null
103
+ SELECT json_type('{"a":1}', '$.b') as result;
104
+ → [{"result":null}]
105
+
106
+ -- Non-string path returns 'null'
107
+ SELECT json_type('{"a":1}', 42) as result;
108
+ → [{"result":"null"}]
109
+
110
+ -- Invalid JSON returns null
111
+ SELECT json_type('not-json') as result;
112
+ → [{"result":null}]
113
+
114
+ -- Null input: coerceToJsonValue(null) returns JSON null, getJsonType(null) returns 'null' string
115
+ SELECT json_type(null) as result;
116
+ → [{"result":"null"}]
117
+
118
+ -- No-path call on each type
119
+ SELECT json_type('42') as result;
120
+ → [{"result":"integer"}]
121
+
122
+ SELECT json_type('"hello"') as result;
123
+ → [{"result":"text"}]
124
+
125
+ -- ============================================================
126
+ -- json_extract: edge cases
127
+ -- ============================================================
128
+
129
+ -- No paths returns null
130
+ SELECT json_extract('{"a":1}') as result;
131
+ → [{"result":null}]
132
+
133
+ -- Non-string path returns null
134
+ SELECT json_extract('{"a":1}', 42) as result;
135
+ → [{"result":null}]
136
+
137
+ -- Boolean value extraction
138
+ SELECT json_extract('{"a":true}', '$.a') as result;
139
+ → [{"result":true}]
140
+
141
+ SELECT json_extract('{"a":false}', '$.a') as result;
142
+ → [{"result":false}]
143
+
144
+ -- Nested object extraction (returns native object)
145
+ SELECT json_extract('{"a":{"b":{"c":42}}}', '$.a.b') as result;
146
+ → [{"result":{"c":42}}]
147
+
148
+ -- Array extraction
149
+ SELECT json_extract('{"a":[10,20,30]}', '$.a') as result;
150
+ → [{"result":[10,20,30]}]
151
+
152
+ -- Array index extraction
153
+ SELECT json_extract('[10,20,30]', '$[1]') as result;
154
+ → [{"result":20}]
155
+
156
+ -- Deep nesting
157
+ SELECT json_extract('{"a":{"b":{"c":{"d":99}}}}', '$.a.b.c.d') as result;
158
+ → [{"result":99}]
159
+
160
+ -- Multiple paths: first found wins
161
+ SELECT json_extract('{"a":1,"b":2}', '$.x', '$.y', '$.b') as result;
162
+ → [{"result":2}]
163
+
164
+ -- All paths miss returns null
165
+ SELECT json_extract('{"a":1}', '$.x', '$.y', '$.z') as result;
166
+ → [{"result":null}]
167
+
168
+ -- Root path extraction
169
+ SELECT json_extract('42', '$') as result;
170
+ → [{"result":42}]
171
+
172
+ SELECT json_extract('"hello"', '$') as result;
173
+ → [{"result":"hello"}]
174
+
175
+ -- ============================================================
176
+ -- json_quote: edge cases
177
+ -- ============================================================
178
+
179
+ -- Null returns 'null' string
180
+ SELECT json_quote(null) as result;
181
+ → [{"result":"null"}]
182
+
183
+ -- Integer
184
+ SELECT json_quote(42) as result;
185
+ → [{"result":"42"}]
186
+
187
+ -- Float
188
+ SELECT json_quote(3.14) as result;
189
+ → [{"result":"3.14"}]
190
+
191
+ -- Boolean
192
+ SELECT json_quote(true) as result;
193
+ → [{"result":"true"}]
194
+
195
+ SELECT json_quote(false) as result;
196
+ → [{"result":"false"}]
197
+
198
+ -- String with special characters
199
+ SELECT json_quote('hello "world"') as result;
200
+ → [{"result":"\"hello \\\"world\\\"\""}]
201
+
202
+ -- Native object
203
+ SELECT json_quote(json_object('a', 1)) as result;
204
+ → [{"result":"{\"a\":1}"}]
205
+
206
+ -- ============================================================
207
+ -- json_object: edge cases
208
+ -- ============================================================
209
+
210
+ -- Odd number of args returns null
211
+ SELECT json_object('a') as result;
212
+ → [{"result":null}]
213
+
214
+ -- Non-string key returns null
215
+ SELECT json_object(42, 'value') as result;
216
+ → [{"result":null}]
217
+
218
+ -- Empty args returns empty object
219
+ SELECT json_object() as result;
220
+ → [{"result":{}}]
221
+
222
+ -- Multiple key-value pairs
223
+ SELECT json_object('a', 1, 'b', 'two', 'c', true) as result;
224
+ → [{"result":{"a":1,"b":"two","c":true}}]
225
+
226
+ -- ============================================================
227
+ -- json_array: edge cases
228
+ -- ============================================================
229
+
230
+ -- Empty args returns empty array
231
+ SELECT json_array() as result;
232
+ → [{"result":[]}]
233
+
234
+ -- Mixed types
235
+ SELECT json_array(1, 'two', true, null) as result;
236
+ → [{"result":[1,"two",true,null]}]
237
+
238
+ -- ============================================================
239
+ -- json_array_length: edge cases
240
+ -- ============================================================
241
+
242
+ -- Non-array returns 0
243
+ SELECT json_array_length('42') as result;
244
+ → [{"result":0}]
245
+
246
+ SELECT json_array_length('{}') as result;
247
+ → [{"result":0}]
248
+
249
+ -- Empty array
250
+ SELECT json_array_length('[]') as result;
251
+ → [{"result":0}]
252
+
253
+ -- Normal array
254
+ SELECT json_array_length('[1,2,3]') as result;
255
+ → [{"result":3}]
256
+
257
+ -- With path to array
258
+ SELECT json_array_length('{"a":[1,2,3,4]}', '$.a') as result;
259
+ → [{"result":4}]
260
+
261
+ -- Path to non-array returns 0
262
+ SELECT json_array_length('{"a":42}', '$.a') as result;
263
+ → [{"result":0}]
264
+
265
+ -- Non-string path returns 0
266
+ SELECT json_array_length('[1,2,3]', 42) as result;
267
+ → [{"result":0}]
268
+
269
+ -- Missing path returns 0
270
+ SELECT json_array_length('{"a":[1]}', '$.b') as result;
271
+ → [{"result":0}]
272
+
273
+ -- Null input: coerceToJsonValue(null) = JSON null, not undefined, so returns 0
274
+ SELECT json_array_length(null) as result;
275
+ → [{"result":0}]
276
+
277
+ -- ============================================================
278
+ -- json_patch: edge cases
279
+ -- ============================================================
280
+
281
+ -- Valid add operation
282
+ SELECT json_patch('{"a":1}', '[{"op":"add","path":"/b","value":2}]') as result;
283
+ → [{"result":{"a":1,"b":2}}]
284
+
285
+ -- Valid replace operation
286
+ SELECT json_patch('{"a":1}', '[{"op":"replace","path":"/a","value":99}]') as result;
287
+ → [{"result":{"a":99}}]
288
+
289
+ -- Valid remove operation
290
+ SELECT json_patch('{"a":1,"b":2}', '[{"op":"remove","path":"/b"}]') as result;
291
+ → [{"result":{"a":1}}]
292
+
293
+ -- Invalid first arg returns null
294
+ SELECT json_patch('not-json', '[{"op":"add","path":"/a","value":1}]') as result;
295
+ → [{"result":null}]
296
+
297
+ -- Invalid second arg returns null
298
+ SELECT json_patch('{"a":1}', 'not-json') as result;
299
+ → [{"result":null}]
300
+
301
+ -- Null first arg returns null
302
+ SELECT json_patch(null, '[{"op":"add","path":"/a","value":1}]') as result;
303
+ → [{"result":null}]
304
+
305
+ -- Patch with invalid path (triggers catch block)
306
+ SELECT json_patch('{"a":1}', '[{"op":"replace","path":"/nonexistent/deep/path","value":99}]') as result;
307
+ → [{"result":null}]
308
+
309
+ -- Patch operation missing required fields returns null
310
+ SELECT json_patch('{"a":1}', '[{"value":1}]') as result;
311
+ → [{"result":null}]
312
+
313
+ -- Multiple operations
314
+ SELECT json_patch('{"a":1}', '[{"op":"add","path":"/b","value":2},{"op":"remove","path":"/a"}]') as result;
315
+ → [{"result":{"b":2}}]
316
+
317
+ -- ============================================================
318
+ -- json_insert: edge cases
319
+ -- ============================================================
320
+
321
+ -- No args (odd) returns null
322
+ SELECT json_insert('{"a":1}') as result;
323
+ → [{"result":null}]
324
+
325
+ -- Non-string path returns null
326
+ SELECT json_insert('{"a":1}', 42, 'val') as result;
327
+ → [{"result":null}]
328
+
329
+ -- Insert doesn't overwrite existing
330
+ SELECT json_insert('{"a":1}', '$.a', 99) as result;
331
+ → [{"result":{"a":1}}]
332
+
333
+ -- Insert creates new key
334
+ SELECT json_insert('{"a":1}', '$.b', 2) as result;
335
+ → [{"result":{"a":1,"b":2}}]
336
+
337
+ -- Insert at array index within bounds (splice)
338
+ SELECT json_insert('[1,2,3]', '$[1]', 99) as result;
339
+ → [{"result":[1,2,3]}]
340
+
341
+ -- Insert at array end (append)
342
+ SELECT json_insert('[1,2]', '$[2]', 3) as result;
343
+ → [{"result":[1,2,3]}]
344
+
345
+ -- Invalid path syntax continues
346
+ SELECT json_insert('{"a":1}', '$invalid', 99) as result;
347
+ → [{"result":{"a":1}}]
348
+
349
+ -- Multiple inserts
350
+ SELECT json_insert('{}', '$.a', 1, '$.b', 2) as result;
351
+ → [{"result":{"a":1,"b":2}}]
352
+
353
+ -- Invalid JSON input
354
+ SELECT json_insert('not-json', '$.a', 1) as result;
355
+ → [{"result":null}]
356
+
357
+ -- Odd number of path/value args returns null
358
+ SELECT json_insert('{"a":1}', '$.b') as result;
359
+ → [{"result":null}]
360
+
361
+ -- ============================================================
362
+ -- json_replace: edge cases
363
+ -- ============================================================
364
+
365
+ -- Replace existing key
366
+ SELECT json_replace('{"a":1,"b":2}', '$.a', 99) as result;
367
+ → [{"result":{"a":99,"b":2}}]
368
+
369
+ -- Replace non-existing key does nothing
370
+ SELECT json_replace('{"a":1}', '$.b', 99) as result;
371
+ → [{"result":{"a":1}}]
372
+
373
+ -- Replace root path
374
+ SELECT json_replace('{"a":1}', '$', 42) as result;
375
+ → [{"result":42}]
376
+
377
+ -- Replace array element
378
+ SELECT json_replace('[10,20,30]', '$[1]', 99) as result;
379
+ → [{"result":[10,99,30]}]
380
+
381
+ -- Replace array element out of bounds does nothing
382
+ SELECT json_replace('[10,20,30]', '$[5]', 99) as result;
383
+ → [{"result":[10,20,30]}]
384
+
385
+ -- Invalid JSON
386
+ SELECT json_replace('not-json', '$.a', 1) as result;
387
+ → [{"result":null}]
388
+
389
+ -- No args returns null
390
+ SELECT json_replace('{"a":1}') as result;
391
+ → [{"result":null}]
392
+
393
+ -- Non-string path returns null
394
+ SELECT json_replace('{"a":1}', 42, 99) as result;
395
+ → [{"result":null}]
396
+
397
+ -- Multiple replacements
398
+ SELECT json_replace('{"a":1,"b":2}', '$.a', 10, '$.b', 20) as result;
399
+ → [{"result":{"a":10,"b":20}}]
400
+
401
+ -- ============================================================
402
+ -- json_set: edge cases
403
+ -- ============================================================
404
+
405
+ -- Set existing key (replace)
406
+ SELECT json_set('{"a":1}', '$.a', 99) as result;
407
+ → [{"result":{"a":99}}]
408
+
409
+ -- Set new key (create)
410
+ SELECT json_set('{"a":1}', '$.b', 2) as result;
411
+ → [{"result":{"a":1,"b":2}}]
412
+
413
+ -- Set root path
414
+ SELECT json_set('{"a":1}', '$', 42) as result;
415
+ → [{"result":42}]
416
+
417
+ -- Set array element in bounds
418
+ SELECT json_set('[10,20,30]', '$[1]', 99) as result;
419
+ → [{"result":[10,99,30]}]
420
+
421
+ -- Set array element at end (append)
422
+ SELECT json_set('[10,20]', '$[2]', 30) as result;
423
+ → [{"result":[10,20,30]}]
424
+
425
+ -- Set array element beyond end (gap-fill with nulls)
426
+ SELECT json_set('[1]', '$[4]', 'x') as result;
427
+ → [{"result":[1,null,null,null,"x"]}]
428
+
429
+ -- Set on deeply nested missing path: pathInfo null means continue (no-op)
430
+ SELECT json_set('{}', '$.a.b', 42) as result;
431
+ → [{"result":{}}]
432
+
433
+ -- Invalid JSON
434
+ SELECT json_set('not-json', '$.a', 1) as result;
435
+ → [{"result":null}]
436
+
437
+ -- No args returns null
438
+ SELECT json_set('{}') as result;
439
+ → [{"result":null}]
440
+
441
+ -- Non-string path returns null
442
+ SELECT json_set('{}', 42, 'val') as result;
443
+ → [{"result":null}]
444
+
445
+ -- Multiple sets
446
+ SELECT json_set('{}', '$.a', 1, '$.b', 2, '$.c', 3) as result;
447
+ → [{"result":{"a":1,"b":2,"c":3}}]
448
+
449
+ -- ============================================================
450
+ -- json_remove: edge cases
451
+ -- ============================================================
452
+
453
+ -- No paths returns original data
454
+ SELECT json_remove('{"a":1,"b":2}') as result;
455
+ → [{"result":{"a":1,"b":2}}]
456
+
457
+ -- Remove existing key
458
+ SELECT json_remove('{"a":1,"b":2}', '$.a') as result;
459
+ → [{"result":{"b":2}}]
460
+
461
+ -- Remove non-existing key does nothing
462
+ SELECT json_remove('{"a":1}', '$.z') as result;
463
+ → [{"result":{"a":1}}]
464
+
465
+ -- Remove array element
466
+ SELECT json_remove('[10,20,30]', '$[0]') as result;
467
+ → [{"result":[20,30]}]
468
+
469
+ -- Remove array element out of bounds does nothing
470
+ SELECT json_remove('[10,20,30]', '$[5]') as result;
471
+ → [{"result":[10,20,30]}]
472
+
473
+ -- Non-string path returns null
474
+ SELECT json_remove('{"a":1}', 42) as result;
475
+ → [{"result":null}]
476
+
477
+ -- Invalid JSON
478
+ SELECT json_remove('not-json', '$.a') as result;
479
+ → [{"result":null}]
480
+
481
+ -- Null JSON
482
+ SELECT json_remove(null, '$.a') as result;
483
+ → [{"result":null}]
484
+
485
+ -- Multiple removals
486
+ SELECT json_remove('{"a":1,"b":2,"c":3}', '$.a', '$.c') as result;
487
+ → [{"result":{"b":2}}]
488
+
489
+ -- Invalid path syntax continues silently
490
+ SELECT json_remove('{"a":1}', '$[invalid') as result;
491
+ → [{"result":{"a":1}}]
492
+
493
+ -- ============================================================
494
+ -- json_group_array / json_group_object: aggregation
495
+ -- ============================================================
496
+
497
+ CREATE TABLE json_agg_t (id INTEGER PRIMARY KEY, name TEXT NULL, val INTEGER NULL);
498
+ INSERT INTO json_agg_t VALUES (1, 'a', 10), (2, 'b', 20), (3, null, 30);
499
+ -- run
500
+
501
+ -- json_group_array collects non-null and null values
502
+ SELECT json_group_array(val) as result FROM json_agg_t;
503
+ → [{"result":[10,20,30]}]
504
+
505
+ -- json_group_object skips null keys
506
+ SELECT json_group_object(name, val) as result FROM json_agg_t;
507
+ → [{"result":{"a":10,"b":20}}]
508
+
509
+ -- json_group_array with all nulls still collects them
510
+ CREATE TABLE json_agg_nulls (id INTEGER PRIMARY KEY, val INTEGER NULL);
511
+ INSERT INTO json_agg_nulls VALUES (1, null), (2, null);
512
+ -- run
513
+
514
+ SELECT json_group_array(val) as result FROM json_agg_nulls;
515
+ → [{"result":[null,null]}]
516
+
517
+ -- json_group_object with empty table
518
+ CREATE TABLE json_agg_empty2 (id INTEGER PRIMARY KEY, name TEXT, val INTEGER);
519
+ SELECT json_group_object(name, val) as result FROM json_agg_empty2;
520
+ → [{"result":null}]
521
+
522
+ DROP TABLE json_agg_t;
523
+ DROP TABLE json_agg_nulls;
524
+ DROP TABLE json_agg_empty2;
525
+
526
+ -- ============================================================
527
+ -- json path: quoted keys, bracket notation, edge cases
528
+ -- ============================================================
529
+
530
+ -- Quoted key with dot in name
531
+ SELECT json_extract('{"a.b":42}', '$."a.b"') as result;
532
+ → [{"result":42}]
533
+
534
+ -- Bracket notation for arrays
535
+ SELECT json_extract('[[1,2],[3,4]]', '$[0][1]') as result;
536
+ → [{"result":2}]
537
+
538
+ -- Deeply nested mixed paths
539
+ SELECT json_extract('{"a":[{"b":99}]}', '$.a[0].b') as result;
540
+ → [{"result":99}]
541
+
542
+ -- Invalid path: unclosed bracket
543
+ SELECT json_extract('{"a":1}', '$[0') as result;
544
+ → [{"result":null}]
545
+
546
+ -- Invalid path: negative index
547
+ SELECT json_extract('[1,2,3]', '$[-1]') as result;
548
+ → [{"result":null}]
549
+
550
+ -- Invalid path: empty string
551
+ SELECT json_extract('{"a":1}', '') as result;
552
+ → [{"result":null}]
553
+
554
+ -- Root path returns full value
555
+ SELECT json_extract('{"a":1,"b":2}', '$') as result;
556
+ → [{"result":{"a":1,"b":2}}]
557
+
558
+ -- Path through null parent
559
+ SELECT json_extract('{"a":null}', '$.a.b') as result;
560
+ → [{"result":null}]
561
+
562
+ -- ============================================================
563
+ -- json_insert into nested structures
564
+ -- ============================================================
565
+
566
+ -- Insert into nested object
567
+ SELECT json_insert('{"a":{"b":1}}', '$.a.c', 2) as result;
568
+ → [{"result":{"a":{"b":1,"c":2}}}]
569
+
570
+ -- Insert into nested array
571
+ SELECT json_insert('{"a":[1,2]}', '$.a[2]', 3) as result;
572
+ → [{"result":{"a":[1,2,3]}}]
573
+
574
+ -- ============================================================
575
+ -- json_set with createParents on deep paths
576
+ -- ============================================================
577
+
578
+ -- Deep path where intermediate doesn't exist: returns unchanged
579
+ SELECT json_set('{"a":{}}', '$.a.b[0]', 'first') as result;
580
+ → [{"result":{"a":{}}}]
581
+
582
+ -- createParents: set new key on existing object
583
+ SELECT json_set('{"a":{"b":1}}', '$.a.c', 2) as result;
584
+ → [{"result":{"a":{"b":1,"c":2}}}]
585
+
586
+ -- ============================================================
587
+ -- json type detection on native objects
588
+ -- ============================================================
589
+
590
+ SELECT json_type(json_array(1, 2, 3)) as result;
591
+ → [{"result":"array"}]
592
+
593
+ SELECT json_type(json_object('a', 1)) as result;
594
+ → [{"result":"object"}]
595
+
596
+ SELECT json_type(42) as result;
597
+ → [{"result":"integer"}]
598
+
599
+ SELECT json_type(3.14) as result;
600
+ → [{"result":"real"}]
601
+
602
+ SELECT json_type(true) as result;
603
+ → [{"result":"true"}]
604
+
605
+ SELECT json_type(false) as result;
606
+ → [{"result":"false"}]
607
+
608
+ SELECT json_type(null) as result;
609
+ → [{"result":"null"}]
610
+
611
+ -- ============================================================
612
+ -- json_extract with string value
613
+ -- ============================================================
614
+
615
+ SELECT json_extract('{"a":"hello"}', '$.a') as result;
616
+ → [{"result":"hello"}]
617
+
618
+ -- ============================================================
619
+ -- Mutation doesn't affect original (deep copy verification)
620
+ -- ============================================================
621
+
622
+ CREATE TABLE json_mut (id INTEGER PRIMARY KEY, data JSON);
623
+ INSERT INTO json_mut VALUES (1, '{"a":[1,2,3]}');
624
+ -- run
625
+
626
+ -- json_set returns new data, original should be unchanged
627
+ SELECT json_set(data, '$.a[0]', 99) as modified FROM json_mut WHERE id = 1;
628
+ → [{"modified":{"a":[99,2,3]}}]
629
+
630
+ SELECT data FROM json_mut WHERE id = 1;
631
+ → [{"data":{"a":[1,2,3]}}]
632
+
633
+ DROP TABLE json_mut;