@quereus/quereus 4.20.1 → 4.20.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (377) hide show
  1. package/README.md +2 -0
  2. package/package.json +7 -4
  3. package/test/README.md +173 -0
  4. package/test/logic/01-basic.sqllogic +39 -0
  5. package/test/logic/01.1-select-projection-extras.sqllogic +130 -0
  6. package/test/logic/01.2-strings.sqllogic +43 -0
  7. package/test/logic/01.5-insert-select.sqllogic +237 -0
  8. package/test/logic/01.6-update-extras.sqllogic +118 -0
  9. package/test/logic/01.7-update-from.sqllogic +67 -0
  10. package/test/logic/01.8-delete-extras.sqllogic +122 -0
  11. package/test/logic/01.8.1-delete-range-cow.sqllogic +115 -0
  12. package/test/logic/01.9-query-expr-dml-gates.sqllogic +32 -0
  13. package/test/logic/01.9-query-expr-dml.sqllogic +171 -0
  14. package/test/logic/01.9-query-expr-values.sqllogic +111 -0
  15. package/test/logic/01.9.1-limit-over-dml-subquery.sqllogic +119 -0
  16. package/test/logic/02-filters.sqllogic +54 -0
  17. package/test/logic/02-smoke.sqllogic +62 -0
  18. package/test/logic/02.1-bind-parameters.sqllogic +223 -0
  19. package/test/logic/03-expressions.sqllogic +190 -0
  20. package/test/logic/03.1-quoted-identifiers.sqllogic +55 -0
  21. package/test/logic/03.4-defaults.sqllogic +554 -0
  22. package/test/logic/03.4.1-default-edge-cases.sqllogic +99 -0
  23. package/test/logic/03.5-tvf.sqllogic +61 -0
  24. package/test/logic/03.6-type-system.sqllogic +544 -0
  25. package/test/logic/03.6.1-numeric-text-comparison-coercion.sqllogic +244 -0
  26. package/test/logic/03.6.2-value-to-text.sqllogic +224 -0
  27. package/test/logic/03.7-bigint-mixed-arithmetic.sqllogic +65 -0
  28. package/test/logic/03.8-not-precedence.sqllogic +255 -0
  29. package/test/logic/03.9-is-bool-predicate.sqllogic +150 -0
  30. package/test/logic/03.9.1-is-bool-predicate-partial-index.sqllogic +34 -0
  31. package/test/logic/04-order-by.sqllogic +38 -0
  32. package/test/logic/04-transactions.sqllogic +239 -0
  33. package/test/logic/04a-savepoint-lazy-attach.sqllogic +122 -0
  34. package/test/logic/05-vtab_memory.sqllogic +50 -0
  35. package/test/logic/05.0.1-vtab-memory-unique-index-collation.sqllogic +34 -0
  36. package/test/logic/05.1-composite-pk-range-scan.sqllogic +147 -0
  37. package/test/logic/05.1.1-secondary-index-range-scan.sqllogic +56 -0
  38. package/test/logic/05.2-cast-seek-correctness.sqllogic +124 -0
  39. package/test/logic/06-builtin_functions.sqllogic +149 -0
  40. package/test/logic/06.1-string-functions.sqllogic +92 -0
  41. package/test/logic/06.1.3-like-glob-edges.sqllogic +53 -0
  42. package/test/logic/06.2-math-functions.sqllogic +82 -0
  43. package/test/logic/06.3-schema.sqllogic +48 -0
  44. package/test/logic/06.3.1-schema-all-schemas.sqllogic +39 -0
  45. package/test/logic/06.3.2-schema-foreign-keys.sqllogic +208 -0
  46. package/test/logic/06.3.3-introspection-tags.sqllogic +202 -0
  47. package/test/logic/06.3.3.1-introspection-tags-index.sqllogic +74 -0
  48. package/test/logic/06.3.4-view-info.sqllogic +378 -0
  49. package/test/logic/06.3.5-column-info.sqllogic +347 -0
  50. package/test/logic/06.3.6-schema-views.sqllogic +29 -0
  51. package/test/logic/06.4-schema-search-path.sqllogic +354 -0
  52. package/test/logic/06.4.1-schema-case-insensitive.sqllogic +83 -0
  53. package/test/logic/06.4.2-collation-extras.sqllogic +472 -0
  54. package/test/logic/06.4.2.1-collation-index-access-paths.sqllogic +140 -0
  55. package/test/logic/06.4.3-write-path-collation.sqllogic +99 -0
  56. package/test/logic/06.4.4-comparison-collation-precedence.sqllogic +342 -0
  57. package/test/logic/06.4.5-any-collate-declared-keys.sqllogic +92 -0
  58. package/test/logic/06.5-polymorphic-types.sqllogic +169 -0
  59. package/test/logic/06.5.1-conversion-functions.sqllogic +173 -0
  60. package/test/logic/06.5.2-scalar-minmax.sqllogic +16 -0
  61. package/test/logic/06.5.3-undeclared-return-type-comparison.sqllogic +244 -0
  62. package/test/logic/06.5.4-declared-return-type-builtins.sqllogic +288 -0
  63. package/test/logic/06.6-aggregate-extended.sqllogic +78 -0
  64. package/test/logic/06.7-json-extended.sqllogic +53 -0
  65. package/test/logic/06.8-json-path-operators.sqllogic +99 -0
  66. package/test/logic/06.9-json-canonical-key.sqllogic +65 -0
  67. package/test/logic/06.9.1-json-coerce-once.sqllogic +417 -0
  68. package/test/logic/06.9.1.1-json-coerce-once-index.sqllogic +39 -0
  69. package/test/logic/06.9.2-json-structural-equality.sqllogic +382 -0
  70. package/test/logic/06.9.2.1-json-structural-equality-index.sqllogic +76 -0
  71. package/test/logic/06.9.3-json-index-range-seek.sqllogic +205 -0
  72. package/test/logic/07-aggregates.sqllogic +193 -0
  73. package/test/logic/07.1-aggregate-filter-clause.sqllogic +12 -0
  74. package/test/logic/07.2-aggregate-order-by.sqllogic +11 -0
  75. package/test/logic/07.3-group-by-extras.sqllogic +602 -0
  76. package/test/logic/07.3.1-group-by-order-by-key.sqllogic +164 -0
  77. package/test/logic/07.3.2-grouped-select-list-shape.sqllogic +231 -0
  78. package/test/logic/07.4-group-by-filter-composite-pk.sqllogic +120 -0
  79. package/test/logic/07.5-sum-mixed-exact-and-float.sqllogic +151 -0
  80. package/test/logic/07.5-window.sqllogic +1941 -0
  81. package/test/logic/07.5.1-window-named.sqllogic +13 -0
  82. package/test/logic/07.5.2-window-nth-value.sqllogic +13 -0
  83. package/test/logic/07.6-subqueries.sqllogic +78 -0
  84. package/test/logic/07.6.1-subquery-extras.sqllogic +93 -0
  85. package/test/logic/07.7-and-or-short-circuit.sqllogic +58 -0
  86. package/test/logic/07.7-in-subquery-caching.sqllogic +174 -0
  87. package/test/logic/07.7-scalar-agg-decorrelation.sqllogic +197 -0
  88. package/test/logic/07.7.1-in-extras.sqllogic +158 -0
  89. package/test/logic/07.7.1-scalar-agg-decorrelation-filter.sqllogic +105 -0
  90. package/test/logic/07.7.2-scalar-agg-decorrelation-nested.sqllogic +115 -0
  91. package/test/logic/07.7.3-exists-in-select-decorrelation.sqllogic +107 -0
  92. package/test/logic/07.7.4-where-conjunct-ordering.sqllogic +121 -0
  93. package/test/logic/07.7.5-filter-lost-under-index-order.sqllogic +134 -0
  94. package/test/logic/07.7.6-correlated-predicate-scope.sqllogic +178 -0
  95. package/test/logic/07.7.7-join-source-scope-shadowing.sqllogic +137 -0
  96. package/test/logic/07.7.8-correlated-ref-to-computed-column.sqllogic +165 -0
  97. package/test/logic/07.7.9-conjunct-monotonicity.sqllogic +200 -0
  98. package/test/logic/07.8-correlated-subquery-edges.sqllogic +71 -0
  99. package/test/logic/07.8.1-correlated-in-decorrelation-gates.sqllogic +156 -0
  100. package/test/logic/07.9-in-value-list.sqllogic +154 -0
  101. package/test/logic/07.9.1-in-value-list-composite-index.sqllogic +38 -0
  102. package/test/logic/08-views.sqllogic +64 -0
  103. package/test/logic/08.1-semi-anti-join.sqllogic +191 -0
  104. package/test/logic/08.1-view-edge-cases.sqllogic +118 -0
  105. package/test/logic/08.1.1-uncorrelated-in-semijoin.sqllogic +251 -0
  106. package/test/logic/08.2-existence-flag-semijoin-recovery.sqllogic +197 -0
  107. package/test/logic/08.3-existence-flag-inner-recovery.sqllogic +102 -0
  108. package/test/logic/08.4-key-set-semi-join.sqllogic +447 -0
  109. package/test/logic/09-set_operations.sqllogic +244 -0
  110. package/test/logic/09.1-set-op-cross-collation.sqllogic +230 -0
  111. package/test/logic/10-distinct_datatypes.sqllogic +127 -0
  112. package/test/logic/10.1-ddl-lifecycle.sqllogic +203 -0
  113. package/test/logic/10.1.1-create-table-syntax-edges.sqllogic +47 -0
  114. package/test/logic/10.1.2-ddl-in-transaction.sqllogic +143 -0
  115. package/test/logic/10.1.2.1-add-constraint-in-transaction.sqllogic +59 -0
  116. package/test/logic/10.1.3-ddl-drop-in-transaction.sqllogic +187 -0
  117. package/test/logic/10.1.3.1-drop-constraint-in-transaction.sqllogic +45 -0
  118. package/test/logic/10.1.4-create-table-duplicate-constraint-names.sqllogic +149 -0
  119. package/test/logic/10.1.4-ddl-transaction-policy.sqllogic +314 -0
  120. package/test/logic/10.1.5-alter-add-constraint-minted-name-disambiguation.sqllogic +219 -0
  121. package/test/logic/10.1.5-create-index-lifecycle.sqllogic +72 -0
  122. package/test/logic/10.1.6-ddl-transaction-policy-index.sqllogic +143 -0
  123. package/test/logic/10.1.7-create-table-default-type-check.sqllogic +119 -0
  124. package/test/logic/10.1.8-alter-add-check-existing-rows.sqllogic +117 -0
  125. package/test/logic/10.2-column-features.sqllogic +365 -0
  126. package/test/logic/10.2.1-table-options-rejection.sqllogic +63 -0
  127. package/test/logic/10.2.2-default-collation-memory.sqllogic +30 -0
  128. package/test/logic/10.3-function-features.sqllogic +247 -0
  129. package/test/logic/10.4-schema-scale.sqllogic +168 -0
  130. package/test/logic/10.4.1-schema-scale-indexes.sqllogic +121 -0
  131. package/test/logic/10.5-indexes.sqllogic +164 -0
  132. package/test/logic/10.5.1-partial-indexes.sqllogic +526 -0
  133. package/test/logic/10.5.2-expression-indexes.sqllogic +34 -0
  134. package/test/logic/10.5.3-desc-index-ordering.sqllogic +130 -0
  135. package/test/logic/10.5.4-composite-pk-index-update-phantom.sqllogic +55 -0
  136. package/test/logic/10.5.5-index-name-uniqueness.sqllogic +76 -0
  137. package/test/logic/10.5.6-minmax-index-boundary.sqllogic +204 -0
  138. package/test/logic/10.5.7-implicit-unique-index-lifecycle.sqllogic +1216 -0
  139. package/test/logic/10.6-distinct-edge-cases.sqllogic +119 -0
  140. package/test/logic/100-predicate-normalization-edge-cases.sqllogic +238 -0
  141. package/test/logic/100.1-where-extras.sqllogic +163 -0
  142. package/test/logic/100.1.1-where-join-on-order-indexed.sqllogic +35 -0
  143. package/test/logic/101-builtin-mutation-kills.sqllogic +974 -0
  144. package/test/logic/101-transaction-edge-cases.sqllogic +395 -0
  145. package/test/logic/102-schema-catalog-edge-cases.sqllogic +252 -0
  146. package/test/logic/102-unique-constraints.sqllogic +145 -0
  147. package/test/logic/102.0.1-schema-catalog-indexed-table.sqllogic +32 -0
  148. package/test/logic/102.1-unique-edge-cases.sqllogic +111 -0
  149. package/test/logic/102.1.1-unique-index-creation-edge-cases.sqllogic +75 -0
  150. package/test/logic/102.2-unique-collation.sqllogic +181 -0
  151. package/test/logic/102.2.1-unique-collation-index-derived.sqllogic +305 -0
  152. package/test/logic/103-database-options-edge-cases.sqllogic +108 -0
  153. package/test/logic/103.1-pragma-boolean-values.sqllogic +126 -0
  154. package/test/logic/104-emit-mutation-kills.sqllogic +236 -0
  155. package/test/logic/105-vtab-memory-mutation-kills.sqllogic +754 -0
  156. package/test/logic/105.1-vtab-memory-index-mutation-kills.sqllogic +540 -0
  157. package/test/logic/106-constraint-extractor-mutation-kills.sqllogic +350 -0
  158. package/test/logic/107-temporal-arithmetic-mutation-kills.sqllogic +833 -0
  159. package/test/logic/108-cardinality-estimation.sqllogic +146 -0
  160. package/test/logic/108.1-analyze-name-resolution.sqllogic +102 -0
  161. package/test/logic/109-aggregate-physical-selection.sqllogic +103 -0
  162. package/test/logic/11-joins.sqllogic +86 -0
  163. package/test/logic/11.1-join-using.sqllogic +267 -0
  164. package/test/logic/11.2-comma-join.sqllogic +35 -0
  165. package/test/logic/11.3-index-nested-loop-join.sqllogic +305 -0
  166. package/test/logic/11.3-mismatched-collation-join.sqllogic +74 -0
  167. package/test/logic/11.4-hash-join-side-swap.sqllogic +118 -0
  168. package/test/logic/110-scan-emitter-mutation-kills.sqllogic +121 -0
  169. package/test/logic/110.1-scan-emitter-index-scan-kills.sqllogic +47 -0
  170. package/test/logic/12-empty-primary-key.sqllogic +124 -0
  171. package/test/logic/12-join_padding_order.sqllogic +58 -0
  172. package/test/logic/12.1-orderby-index-consumption.sqllogic +40 -0
  173. package/test/logic/13-cte.sqllogic +137 -0
  174. package/test/logic/13.1-cte-multiple-recursive.sqllogic +104 -0
  175. package/test/logic/13.10-cte-qualified-name.sqllogic +136 -0
  176. package/test/logic/13.11-unreferenced-dml-cte.sqllogic +414 -0
  177. package/test/logic/13.12-nested-dml-cte-rejected.sqllogic +280 -0
  178. package/test/logic/13.2-cte-bind-params.sqllogic +98 -0
  179. package/test/logic/13.3-cte-edge-cases.sqllogic +120 -0
  180. package/test/logic/13.4-cte-extras.sqllogic +98 -0
  181. package/test/logic/13.5-cte-join-order.sqllogic +166 -0
  182. package/test/logic/13.6-cte-dml-runs-once.sqllogic +318 -0
  183. package/test/logic/13.7-cte-sibling-visibility.sqllogic +227 -0
  184. package/test/logic/13.8-insert-with-clause-visibility.sqllogic +254 -0
  185. package/test/logic/13.9-schema-authored-cte-isolation.sqllogic +328 -0
  186. package/test/logic/13.9.1-schema-authored-schema-path-isolation.sqllogic +408 -0
  187. package/test/logic/14-utilities.sqllogic +168 -0
  188. package/test/logic/15-timespan.sqllogic +279 -0
  189. package/test/logic/15.1-semantic-ordering.sqllogic +960 -0
  190. package/test/logic/15.1.1-json-check-coercion.sqllogic +178 -0
  191. package/test/logic/15.1.2-semantic-ordering-index.sqllogic +41 -0
  192. package/test/logic/15.1.3-declared-form-write-contract.sqllogic +519 -0
  193. package/test/logic/16-epoch.sqllogic +187 -0
  194. package/test/logic/17-weekday-modifier.sqllogic +78 -0
  195. package/test/logic/18-json-string-escapes.sqllogic +86 -0
  196. package/test/logic/18-strftime-extended-formats.sqllogic +68 -0
  197. package/test/logic/20-empty-single-row.sqllogic +261 -0
  198. package/test/logic/21-null-edge-cases.sqllogic +227 -0
  199. package/test/logic/21.1-where-null-comparisons.sqllogic +151 -0
  200. package/test/logic/21.1.1-where-null-comparisons-secondary-index.sqllogic +35 -0
  201. package/test/logic/21.2-between-edges.sqllogic +157 -0
  202. package/test/logic/22-boundary-values.sqllogic +175 -0
  203. package/test/logic/23-self-joins-duplicates.sqllogic +74 -0
  204. package/test/logic/24-builtin-branches.sqllogic +611 -0
  205. package/test/logic/24.1-substr-extras.sqllogic +75 -0
  206. package/test/logic/24.2-random-extras.sqllogic +39 -0
  207. package/test/logic/25-aggregate-edge-cases.sqllogic +289 -0
  208. package/test/logic/25.1-nested-aggregates.sqllogic +74 -0
  209. package/test/logic/25.2-having-edge-cases.sqllogic +318 -0
  210. package/test/logic/25.3-aggregate-isnull-empty.sqllogic +16 -0
  211. package/test/logic/25.4-groupby-fd-constant-empty.sqllogic +55 -0
  212. package/test/logic/25.5-ungrouped-aggregate-column-free-select-item.sqllogic +196 -0
  213. package/test/logic/26-join-edge-cases.sqllogic +333 -0
  214. package/test/logic/26.1-left-join-isnull-on-notnull.sqllogic +26 -0
  215. package/test/logic/26.2-left-join-on-vs-where.sqllogic +67 -0
  216. package/test/logic/26.3-join-on-constants.sqllogic +61 -0
  217. package/test/logic/26.4-join-on-is-null-nullable.sqllogic +44 -0
  218. package/test/logic/27-window-edge-cases.sqllogic +206 -0
  219. package/test/logic/27.1-window-groups-frame.sqllogic +13 -0
  220. package/test/logic/27.2-window-exclude.sqllogic +13 -0
  221. package/test/logic/27.3-window-json-aggregation.sqllogic +66 -0
  222. package/test/logic/28-set-ops-sort-edge-cases.sqllogic +444 -0
  223. package/test/logic/28.1-compound-limit-offset.sqllogic +143 -0
  224. package/test/logic/28.2-orderby-expression-extras.sqllogic +698 -0
  225. package/test/logic/28.2-set-op-branch-types.sqllogic +217 -0
  226. package/test/logic/29-constraint-edge-cases.sqllogic +442 -0
  227. package/test/logic/29.1-column-level-conflict-clause.sqllogic +171 -0
  228. package/test/logic/29.2-table-level-pk-conflict-clause.sqllogic +113 -0
  229. package/test/logic/40-constraints.sqllogic +418 -0
  230. package/test/logic/40.1-pk-desc-direction.sqllogic +76 -0
  231. package/test/logic/40.2-check-extras.sqllogic +683 -0
  232. package/test/logic/41-alter-table.sqllogic +191 -0
  233. package/test/logic/41-fk-cascade-conflict-and-self-ref.sqllogic +263 -0
  234. package/test/logic/41-fk-cross-schema.sqllogic +155 -0
  235. package/test/logic/41-fk-extended-targets.sqllogic +173 -0
  236. package/test/logic/41-foreign-keys.sqllogic +1001 -0
  237. package/test/logic/41-generated-column-errors.sqllogic +225 -0
  238. package/test/logic/41-generated-column-extras.sqllogic +598 -0
  239. package/test/logic/41-generated-column-scope.sqllogic +329 -0
  240. package/test/logic/41-generated-columns.sqllogic +361 -0
  241. package/test/logic/41.1-alter-pk.sqllogic +230 -0
  242. package/test/logic/41.1-fk-collation-conflict.sqllogic +277 -0
  243. package/test/logic/41.10-alter-drop-column-foreign-key.sqllogic +274 -0
  244. package/test/logic/41.10.1-alter-drop-column-unique-index.sqllogic +169 -0
  245. package/test/logic/41.10.2-alter-drop-column-check-and-assertion.sqllogic +1616 -0
  246. package/test/logic/41.10.3-alter-drop-column-referencing-fk.sqllogic +292 -0
  247. package/test/logic/41.10.4-drop-object-expression-dependents.sqllogic +602 -0
  248. package/test/logic/41.11-deferred-fk-with-rename.sqllogic +232 -0
  249. package/test/logic/41.12-alter-default-coercion.sqllogic +200 -0
  250. package/test/logic/41.13-alter-add-column-generated-backfill.sqllogic +566 -0
  251. package/test/logic/41.14-alter-add-column-subquery-backfill.sqllogic +129 -0
  252. package/test/logic/41.15-alter-column-default-type-check.sqllogic +178 -0
  253. package/test/logic/41.16-fk-unenforceable.sqllogic +364 -0
  254. package/test/logic/41.2-alter-column.sqllogic +382 -0
  255. package/test/logic/41.2.1-alter-column-retype-deleted-row-memory.sqllogic +32 -0
  256. package/test/logic/41.2.2-alter-column-retype-index-rebuild.sqllogic +77 -0
  257. package/test/logic/41.2.3-alter-column-set-not-null-pk-backfill.sqllogic +310 -0
  258. package/test/logic/41.2.3.1-alter-column-set-not-null-pk-backfill-secondary-index.sqllogic +37 -0
  259. package/test/logic/41.3-alter-add-column-unique.sqllogic +184 -0
  260. package/test/logic/41.3-alter-rename-propagation.sqllogic +2352 -0
  261. package/test/logic/41.3.1-alter-rename-index-propagation.sqllogic +94 -0
  262. package/test/logic/41.4-alter-add-column-constraints.sqllogic +855 -0
  263. package/test/logic/41.5-alter-misc.sqllogic +48 -0
  264. package/test/logic/41.5-cross-schema-foreign-keys.sqllogic +253 -0
  265. package/test/logic/41.6-alter-drop-rename-constraint.sqllogic +354 -0
  266. package/test/logic/41.6.1-alter-drop-constraint-index-derived.sqllogic +22 -0
  267. package/test/logic/41.7-alter-column-collate.sqllogic +105 -0
  268. package/test/logic/41.7.1-alter-column-collate-unique.sqllogic +45 -0
  269. package/test/logic/41.7.2-alter-column-collate-unique-store.sqllogic +208 -0
  270. package/test/logic/41.7.2.1-alter-column-collate-unique-index-store.sqllogic +114 -0
  271. package/test/logic/41.7.3-alter-column-retype-unique.sqllogic +293 -0
  272. package/test/logic/41.7.3.1-alter-column-retype-staged-rows-memory.sqllogic +41 -0
  273. package/test/logic/41.7.3.2-alter-column-retype-unique-index.sqllogic +72 -0
  274. package/test/logic/41.7.4-alter-column-retype-semantic-memory.sqllogic +445 -0
  275. package/test/logic/41.7.4.1-alter-column-retype-semantic-index-memory.sqllogic +91 -0
  276. package/test/logic/41.7.5-alter-column-collate-pk-staged-delete-memory.sqllogic +106 -0
  277. package/test/logic/41.8-alter-add-constraint-unique-fk.sqllogic +275 -0
  278. package/test/logic/41.8-alter-savepoint-staged-rows.sqllogic +443 -0
  279. package/test/logic/41.8.1-alter-rename-savepoint-staged-rows.sqllogic +408 -0
  280. package/test/logic/41.9-alter-constraint-body-change.sqllogic +180 -0
  281. package/test/logic/41.9-fk-restrict-batched.sqllogic +290 -0
  282. package/test/logic/42-committed-snapshot.sqllogic +254 -0
  283. package/test/logic/42-returning.sqllogic +159 -0
  284. package/test/logic/42.1-returning-extras.sqllogic +232 -0
  285. package/test/logic/42.2-returning-stored-row.sqllogic +165 -0
  286. package/test/logic/43-default-nullability.sqllogic +131 -0
  287. package/test/logic/43-transition-constraints.sqllogic +341 -0
  288. package/test/logic/43.1-default-collation.sqllogic +140 -0
  289. package/test/logic/43.1-notnull-or-conflict.sqllogic +79 -0
  290. package/test/logic/43.2-deferred-check-new-on-delete.sqllogic +95 -0
  291. package/test/logic/43.3-nullable-primary-key.sqllogic +587 -0
  292. package/test/logic/44-determinism-validation.sqllogic +164 -0
  293. package/test/logic/44-orthogonality.sqllogic +146 -0
  294. package/test/logic/44.1-nondeterministic-schema.sqllogic +316 -0
  295. package/test/logic/45-udf-determinism.sqllogic +39 -0
  296. package/test/logic/46-mutation-context.sqllogic +595 -0
  297. package/test/logic/47-upsert.sqllogic +255 -0
  298. package/test/logic/47.1-upsert-conflict-targets.sqllogic +169 -0
  299. package/test/logic/47.2-replace-and-or-clauses.sqllogic +164 -0
  300. package/test/logic/47.2.1-pk-replace-secondary-unique.sqllogic +374 -0
  301. package/test/logic/47.3-engine-or-fail.sqllogic +122 -0
  302. package/test/logic/47.3-upsert-conflict-target-collation.sqllogic +139 -0
  303. package/test/logic/47.3.1-upsert-conflict-index-derived-collation.sqllogic +25 -0
  304. package/test/logic/47.4-upsert-conflict-target-affinity.sqllogic +59 -0
  305. package/test/logic/47.5-upsert-do-update-constraints.sqllogic +440 -0
  306. package/test/logic/47.6-upsert-do-update-decomposed.sqllogic +100 -0
  307. package/test/logic/49-reference-graph.sqllogic +84 -0
  308. package/test/logic/50-declarative-schema.sqllogic +2550 -0
  309. package/test/logic/50-metadata-tags.sqllogic +1033 -0
  310. package/test/logic/50.0.1-metadata-tags-index.sqllogic +141 -0
  311. package/test/logic/50.1-declare-schema-pk.sqllogic +150 -0
  312. package/test/logic/50.2-declare-schema-renames.sqllogic +949 -0
  313. package/test/logic/50.2.1-declare-schema-index-renames.sqllogic +173 -0
  314. package/test/logic/50.3-declare-schema-duplicate-names.sqllogic +280 -0
  315. package/test/logic/50.4-declare-schema-apply-restore.sqllogic +192 -0
  316. package/test/logic/51-lens-foundation.sqllogic +147 -0
  317. package/test/logic/51-materialized-views.sqllogic +376 -0
  318. package/test/logic/51.5-materialized-views-coarsened-key.sqllogic +198 -0
  319. package/test/logic/51.7-maintained-table-attach-detach.sqllogic +468 -0
  320. package/test/logic/51.8-maintained-table-declared-constraints.sqllogic +440 -0
  321. package/test/logic/51.85-maintained-table-parent-fk.sqllogic +103 -0
  322. package/test/logic/51.9-maintained-table-secondary-unique.sqllogic +237 -0
  323. package/test/logic/51.9.1-maintained-table-partial-unique.sqllogic +36 -0
  324. package/test/logic/52-lens-overrides.sqllogic +566 -0
  325. package/test/logic/53-materialized-views-rowtime.sqllogic +1601 -0
  326. package/test/logic/53-reserved-tags.sqllogic +252 -0
  327. package/test/logic/53.1-materialized-view-write-through.sqllogic +329 -0
  328. package/test/logic/53.2-materialized-view-rename-propagation.sqllogic +483 -0
  329. package/test/logic/53.3-materialized-view-constraint-only-ddl.sqllogic +409 -0
  330. package/test/logic/53.3.1-materialized-view-index-ddl-irrelevance.sqllogic +29 -0
  331. package/test/logic/53.4-materialized-view-structural-alter-restore.sqllogic +436 -0
  332. package/test/logic/54-covering-mv-enforcement.sqllogic +314 -0
  333. package/test/logic/54.1-covering-mv-partial-enforcement.sqllogic +34 -0
  334. package/test/logic/55-internal-eviction-reporting.sqllogic +89 -0
  335. package/test/logic/55-lens-prover.sqllogic +202 -0
  336. package/test/logic/55.1-eviction-restrict-fk.sqllogic +148 -0
  337. package/test/logic/55.5-lens-authored-inverse.sqllogic +1468 -0
  338. package/test/logic/80-grow-retrieve-pass.sqllogic +79 -0
  339. package/test/logic/81-quickpick.sqllogic +24 -0
  340. package/test/logic/82-bloom-join.sqllogic +185 -0
  341. package/test/logic/83-merge-join.sqllogic +280 -0
  342. package/test/logic/84-asof-scan.sqllogic +238 -0
  343. package/test/logic/84-key-cardinality.sqllogic +50 -0
  344. package/test/logic/85-relational-const-folding.sqllogic +51 -0
  345. package/test/logic/86-scalar-cse.sqllogic +42 -0
  346. package/test/logic/90-error_paths.sqllogic +114 -0
  347. package/test/logic/90.1-parse-errors.sqllogic +77 -0
  348. package/test/logic/90.2-alter-table-errors.sqllogic +53 -0
  349. package/test/logic/90.2.1-alter-extra-errors.sqllogic +51 -0
  350. package/test/logic/90.3-expression-errors.sqllogic +43 -0
  351. package/test/logic/90.4-dml-errors.sqllogic +47 -0
  352. package/test/logic/90.5-unsupported-join-types.sqllogic +37 -0
  353. package/test/logic/90.5.1-right-full-join-read.sqllogic +157 -0
  354. package/test/logic/90.6-select-error-paths.sqllogic +57 -0
  355. package/test/logic/91-merge-join-edge-cases.sqllogic +159 -0
  356. package/test/logic/92-hash-aggregate-edge-cases.sqllogic +139 -0
  357. package/test/logic/93-ddl-view-edge-cases.sqllogic +104 -0
  358. package/test/logic/93.1-view-error-paths.sqllogic +74 -0
  359. package/test/logic/93.2-view-mutation-pending.sqllogic +108 -0
  360. package/test/logic/93.3-view-mutation-or-clause.sqllogic +60 -0
  361. package/test/logic/93.4-view-mutation.sqllogic +4881 -0
  362. package/test/logic/93.4.1-view-mutation-partial-unique-cardinality.sqllogic +31 -0
  363. package/test/logic/93.5-authored-inverse.sqllogic +415 -0
  364. package/test/logic/93.6-set-op-flagless-write.sqllogic +862 -0
  365. package/test/logic/94-tvf-edge-cases.sqllogic +58 -0
  366. package/test/logic/94.1-limit-offset-edge-cases.sqllogic +109 -0
  367. package/test/logic/94.2-limit-offset-extras.sqllogic +98 -0
  368. package/test/logic/95-assertions.sqllogic +1417 -0
  369. package/test/logic/96-subquery-edge-cases.sqllogic +276 -0
  370. package/test/logic/97-json-function-edge-cases.sqllogic +633 -0
  371. package/test/logic/97.1-json-blob-and-special-values.sqllogic +92 -0
  372. package/test/logic/98-temporal-edge-cases.sqllogic +515 -0
  373. package/test/logic/99-conversion-edge-cases.sqllogic +325 -0
  374. package/test/logic/99.0.1-schema-index-listing.sqllogic +21 -0
  375. package/test/logic/99.1-cast-syntax-extras.sqllogic +167 -0
  376. package/test/logic/drop-unique-index.sqllogic +88 -0
  377. package/test/logic/pushdown-test.sqllogic +36 -0
@@ -0,0 +1,288 @@
1
+ -- declared-return-type-builtins.sqllogic
2
+ -- Ticket 2-builtin-scalar-function-declared-return-types gave every built-in scalar
3
+ -- function that used to ride the default an honest `returnType` (json.ts, datetime.ts,
4
+ -- timespan.ts, plus random/randomblob/pow/power and like/glob). `json_extract` is the one
5
+ -- deliberate holdout — genuinely polymorphic — and 06.5.3 covers that.
6
+ --
7
+ -- The declarations are supposed to change PLANS, not ANSWERS: a known return type routes
8
+ -- comparisons through the specialized `compare-fast` / `compare-typed` paths and lets
9
+ -- cross-type coercion fire, but the value each query produces must be the same. This file
10
+ -- pins the answers on both sides of the category boundaries the declarations cross.
11
+ --
12
+ -- No `using memory`, so store mode exercises the persisted path too.
13
+
14
+ create table drt (id integer primary key, j json, d text, ts timespan);
15
+ insert into drt values (1, '{"a":"x"}', '2024-03-04', 'P3D');
16
+ -- run
17
+
18
+ -- ===================================
19
+ -- 1. BOOLEAN-returning predicates compare against numbers as they always did
20
+ -- ===================================
21
+ -- json_valid used to type as ANY (BOOLEAN vs INTEGER now, ANY vs INTEGER before) — both
22
+ -- routes end in the same numeric comparison, because boolean is a NUMERIC storage class.
23
+ select json_valid('{}') = 1 as r;
24
+ → [{"r":true}]
25
+
26
+ select json_valid(j) = 1 as r from drt;
27
+ → [{"r":true}]
28
+
29
+ select json_valid('not json') = 0 as r;
30
+ → [{"r":true}]
31
+
32
+ select json_schema(j, 'string') = 0 as r from drt;
33
+ → [{"r":true}]
34
+
35
+ select IsISODate('2024-03-04') as a, IsISODate('04/03/2024') as b;
36
+ → [{"a":true,"b":false}]
37
+
38
+ select IsISODateTime('2024-03-04T05:06:07') as a, IsISODateTime('2024-03-04') as b;
39
+ → [{"a":true,"b":false}]
40
+
41
+ -- like/glob stay NULLABLE booleans: a null operand is NULL, not false.
42
+ select like('obj%', 'object') as a, glob('obj*', 'object') as b;
43
+ → [{"a":true,"b":true}]
44
+
45
+ select like('obj%', null) as a, glob(null, 'object') as b;
46
+ → [{"a":null,"b":null}]
47
+
48
+ -- ===================================
49
+ -- 2. INTEGER-returning functions
50
+ -- ===================================
51
+ select timespan_days(timespan('P3D')) = 3 as r;
52
+ → [{"r":true}]
53
+
54
+ select timespan_days(ts) = 3 as r from drt;
55
+ → [{"r":true}]
56
+
57
+ select timespan_hours(timespan('PT5H')) as r;
58
+ → [{"r":5}]
59
+
60
+ select json_array_length('[1,2,3]') as r;
61
+ → [{"r":3}]
62
+
63
+ -- The point of declaring INTEGER: the numeric↔textual arm of insertCrossTypeCoercion now
64
+ -- has something to key on, so a numeric-looking string literal is cast instead of being
65
+ -- compared across storage classes. This was FALSE while these functions typed as ANY.
66
+ select json_array_length('[1,2,3]') = '3' as r;
67
+ → [{"r":true}]
68
+
69
+ select epoch_s('2024-03-04') as r;
70
+ → [{"r":1709510400}]
71
+
72
+ select epoch_s(d) = '1709510400' as r from drt;
73
+ → [{"r":true}]
74
+
75
+ select epoch_ms(d) = '1709510400000' as r from drt;
76
+ → [{"r":true}]
77
+
78
+ select typeof(random()) as r;
79
+ → [{"r":"integer"}]
80
+
81
+ -- ===================================
82
+ -- 3. REAL-returning functions
83
+ -- ===================================
84
+ select pow(2, -1) as a, power(2, -1) as b;
85
+ → [{"a":0.5,"b":0.5}]
86
+
87
+ select pow(2, 3) = '8' as r;
88
+ → [{"r":true}]
89
+
90
+ select julianday('2024-03-04') as r;
91
+ → [{"r":2460373.5}]
92
+
93
+ select epoch_s_frac('2024-03-04T00:00:00.500Z') as r;
94
+ → [{"r":1709510400.5}]
95
+
96
+ -- timespan_seconds is REAL, not INTEGER like its six sibling component extractors: it
97
+ -- folds the sub-second components into its result.
98
+ select timespan_seconds('PT1.5S') as r;
99
+ → [{"r":1.5}]
100
+
101
+ select timespan_total_seconds('P1D') as a, timespan_total_hours('P1D') as b;
102
+ → [{"a":86400,"b":24}]
103
+
104
+ -- sqrt is REAL for the same reason as pow: Math.sqrt is not closed over the integers, so
105
+ -- inferring the argument's type would claim INTEGER for a value like sqrt(2). The write
106
+ -- path acts on that claim — see section 7.
107
+ select sqrt(2) as a, typeof(sqrt(2)) as t;
108
+ → [{"a":1.4142135623730951,"t":"real"}]
109
+
110
+ select sqrt(4) = '2' as r;
111
+ → [{"r":true}]
112
+
113
+ -- ===================================
114
+ -- 4. TEXT-returning functions
115
+ -- ===================================
116
+ select json_type(j) as r from drt;
117
+ → [{"r":"object"}]
118
+
119
+ select json_quote(j) = '{"a":"x"}' as r from drt;
120
+ → [{"r":true}]
121
+
122
+ select typeof(json_quote(j)) as r from drt;
123
+ → [{"r":"text"}]
124
+
125
+ select strftime('%Y', d) = '2024' as r from drt;
126
+ → [{"r":true}]
127
+
128
+ -- A TEXT-typed value is not a number: the numeric builtins reject it at plan time, the
129
+ -- same way they reject a text column. Convert first with integer()/real().
130
+ select abs(strftime('%Y', d)) as r from drt;
131
+ -- error: Invalid argument types for function abs
132
+
133
+ select abs(integer(strftime('%Y', d))) as r from drt;
134
+ → [{"r":2024}]
135
+
136
+ -- ===================================
137
+ -- 5. BLOB-returning randomblob
138
+ -- ===================================
139
+ select typeof(randomblob(4)) as t, length(randomblob(4)) as n;
140
+ → [{"t":"blob","n":4}]
141
+
142
+ select randomblob(0) = randomblob(0) as r;
143
+ → [{"r":true}]
144
+
145
+ -- ===================================
146
+ -- 6. JSON-returning functions compare structurally against a JSON column
147
+ -- ===================================
148
+ -- Both sides now declare JSON, so `=` routes through JSON_TYPE.compare (structural)
149
+ -- rather than the object-cast arm. The answer must not move.
150
+ select json_object('a','x') = j as r from drt;
151
+ → [{"r":true}]
152
+
153
+ select json_array(1,2) = json_array(1,2) as r;
154
+ → [{"r":true}]
155
+
156
+ select json_set(j, '$.b', 1) = json_object('a','x','b',1) as r from drt;
157
+ → [{"r":true}]
158
+
159
+ select json_remove(json_object('a','x','b',1), '$.b') = j as r from drt;
160
+ → [{"r":true}]
161
+
162
+ select json_insert(j, '$.b', 2) = json_object('a','x','b',2) as r from drt;
163
+ → [{"r":true}]
164
+
165
+ select json_replace(j, '$.a', 'y') = json_object('a','y') as r from drt;
166
+ → [{"r":true}]
167
+
168
+ select typeof(json_object('a','x')) as r;
169
+ → [{"r":"json"}]
170
+
171
+ -- A JSON mutator can yield a JSON *scalar* rather than an object. typeof reports the
172
+ -- storage class of a JSON scalar, so it reads 'integer' — the same answer `json('5')`
173
+ -- gives, and unchanged by the JSON declaration.
174
+ select json_set('{}', '$', 5) as r, typeof(json_set('{}', '$', 5)) as t, typeof(json('5')) as j;
175
+ → [{"r":5,"t":"integer","j":"integer"}]
176
+
177
+ -- ===================================
178
+ -- 7. Write path: convert exactly once
179
+ -- ===================================
180
+ -- A JSON-declared function's result matches a JSON column's type exactly, so
181
+ -- buildRowCoercion skips conversion and the native object is stored directly — no
182
+ -- second parse. Storing text (json_quote) into the same column DOES convert, once.
183
+ create table jw (id integer primary key, j json);
184
+ insert into jw(id, j) select 1, json_object('a','x');
185
+ insert into jw(id, j) select 2, json_quote(j) from drt;
186
+ -- run
187
+
188
+ select id, typeof(j) as t from jw order by id;
189
+ → [{"id":1,"t":"json"},{"id":2,"t":"json"}]
190
+
191
+ select count(*) as c from jw where j = json_object('a','x');
192
+ → [{"c":2}]
193
+
194
+ -- The mirror case: a REAL-declared result into an INTEGER column does NOT match the
195
+ -- column type, so conversion runs and the stored value is a whole number. Declaring the
196
+ -- argument's type instead would skip the conversion and leave 1.4142135623730951 in an
197
+ -- INTEGER column.
198
+ create table iw (id integer primary key, v integer);
199
+ insert into iw(id, v) select 1, sqrt(2);
200
+ insert into iw(id, v) select 2, pow(2, 0.5);
201
+ -- run
202
+
203
+ select id, v, typeof(v) as t from iw order by id;
204
+ → [{"id":1,"v":1,"t":"integer"},{"id":2,"v":1,"t":"integer"}]
205
+
206
+ -- Nullability is declared, not enforced: a nullable BOOLEAN that resolves to NULL still
207
+ -- meets the column's NOT NULL check at runtime rather than slipping past it.
208
+ create table bw (id integer primary key, ok boolean not null);
209
+ insert into bw(id, ok) select 1, json_valid('{}');
210
+ -- run
211
+
212
+ select ok from bw;
213
+ → [{"ok":true}]
214
+
215
+ insert into bw(id, ok) select 2, like('a%', null);
216
+ -- error: NOT NULL constraint failed: bw.ok
217
+
218
+ -- ===================================
219
+ -- 8. The variadic date/time/datetime functions declare TEXT, not DATE/TIME/DATETIME
220
+ -- ===================================
221
+ -- They emit SQLite's display spelling, which is NOT the canonical stored spelling of the
222
+ -- temporal types: datetime() uses a space separator and time(...,'subsec') always emits
223
+ -- three fractional digits. Declaring the temporal type would make the write path treat
224
+ -- those as already-canonical and store the display spelling, which the temporal types
225
+ -- compare as binary text — so a canonically-written value would stop matching. TEXT keeps
226
+ -- the conversion, and these are the values that conversion must produce.
227
+ select date('2024-03-04', '+1 day') as a, time('12:00:00', 'subsec') as b,
228
+ datetime('2024-03-04 05:06:07', '+1 day') as c;
229
+ → [{"a":"2024-03-05","b":"12:00:00.000","c":"2024-03-05 05:06:07"}]
230
+
231
+ create table dw (id integer primary key, dd date, tt time, dt datetime);
232
+ insert into dw(id, dd, tt, dt)
233
+ select 1, date('2024-03-04', '+1 day'), time('12:00:00', 'subsec'),
234
+ datetime('2024-03-04 05:06:07', '+1 day');
235
+ -- run
236
+
237
+ -- Stored in each type's canonical spelling — 'T' separator, trimmed milliseconds.
238
+ select dd, tt, dt from dw;
239
+ → [{"dd":"2024-03-05","tt":"12:00:00","dt":"2024-03-05T05:06:07"}]
240
+
241
+ select dt = '2024-03-05T05:06:07' as r from dw;
242
+ → [{"r":true}]
243
+
244
+ -- Comparing the function's own result against a literal is unchanged.
245
+ select date('2024-03-04', '+1 day') = '2024-03-05' as r;
246
+ → [{"r":true}]
247
+
248
+ select date(d, '+1 day') = '2024-03-05' as r from drt;
249
+ → [{"r":true}]
250
+
251
+ -- Temporal arithmetic over the result still works — it is dispatched on the runtime
252
+ -- value's shape, not on the declared type.
253
+ select date('2024-03-04', '+1 day') + 'P1D' as r;
254
+ → [{"r":"2024-03-06"}]
255
+
256
+ -- ===================================
257
+ -- 9. The plans actually changed — the point of the whole exercise
258
+ -- ===================================
259
+ -- Sections 1-8 prove the answers did not move; this one proves the declarations bought
260
+ -- something. `scheduler_program()` exposes each instruction's note, and the comparison
261
+ -- emitter tags itself with the path it chose (runtime/emit/binary.ts):
262
+ -- compare-fast — both operands the same category (numeric/textual), no coercion
263
+ -- compare-typed — both operands the same logical type with semantic ordering (JSON)
264
+ -- compare — the generic path: temporal check plus coercion
265
+ -- Every one of these read `compare` while the function rode the ANY default.
266
+ select count(*) as c from scheduler_program('select json_quote(j) = ''text'' from drt')
267
+ where description = '=(compare-fast)';
268
+ → [{"c":1}]
269
+
270
+ select count(*) as c from scheduler_program('select epoch_s(d) = 1 from drt')
271
+ where description = '=(compare-fast)';
272
+ → [{"c":1}]
273
+
274
+ select count(*) as c from scheduler_program('select json_object(''a'',''x'') = j from drt')
275
+ where description = '=(compare-typed)';
276
+ → [{"c":1}]
277
+
278
+ -- json_extract is the deliberate ANY holdout, so it still takes the generic path. This is
279
+ -- the control: it is what every row above looked like before the declarations landed.
280
+ select count(*) as c from scheduler_program('select json_extract(j, ''$.a'') = ''x'' from drt')
281
+ where description = '=(compare)';
282
+ → [{"c":1}]
283
+
284
+ drop table bw;
285
+ drop table iw;
286
+ drop table dw;
287
+ drop table jw;
288
+ drop table drt;
@@ -0,0 +1,78 @@
1
+ -- aggregate-extended.sqllogic - Testing aggregate functions not covered in 07-aggregates
2
+
3
+ -- Create test table
4
+ create table agg_ext (id integer primary key, val real null, grp text);
5
+ insert into agg_ext values (1, 10.0, 'a'), (2, 20.0, 'a'), (3, 30.0, 'a'), (4, 40.0, 'b'), (5, 50.0, 'b'), (6, null, 'b');
6
+
7
+ -- total (returns 0.0 for empty set, unlike sum which returns null)
8
+ select total(val) from agg_ext;
9
+ → [{"total(val)":150}]
10
+
11
+ -- total vs sum with empty set
12
+ create table empty_t (id integer primary key, x real null);
13
+ select total(x), sum(x) from empty_t;
14
+ → [{"total(x)":0,"sum(x)":null}]
15
+ drop table empty_t;
16
+
17
+ -- statistical aggregates: population variance
18
+ select var_pop(val) from agg_ext where grp = 'a';
19
+ → [{"var_pop(val)":66.66666666666669}]
20
+
21
+ -- sample variance
22
+ select var_samp(val) from agg_ext where grp = 'a';
23
+ → [{"var_samp(val)":100}]
24
+
25
+ -- population standard deviation
26
+ select stddev_pop(val) from agg_ext where grp = 'a';
27
+ → [{"stddev_pop(val)":8.16496580927726}]
28
+
29
+ -- var_samp with single value returns null
30
+ select var_samp(val) from agg_ext where id = 1;
31
+ → [{"var_samp(val)":null}]
32
+
33
+ -- string_concat aggregate
34
+ select string_concat(grp) from agg_ext;
35
+ → [{"string_concat(grp)":"a,a,a,b,b,b"}]
36
+
37
+ drop table agg_ext;
38
+
39
+ -- total with null-only values
40
+ create table null_t (id integer primary key, x real null);
41
+ insert into null_t values (1, null), (2, null);
42
+ select total(x), sum(x) from null_t;
43
+ → [{"total(x)":0,"sum(x)":null}]
44
+ drop table null_t;
45
+
46
+ -- var_pop with empty set returns null
47
+ create table empty_var (id integer primary key, x real null);
48
+ select var_pop(x) from empty_var;
49
+ → [{"var_pop(x)":null}]
50
+ drop table empty_var;
51
+
52
+ -- declared return types for the json/string aggregate builtins, pinned via the
53
+ -- maintained-table strict shape gate (declared column types must equal the
54
+ -- body-derived ones: json_group_array/json_group_object → json null,
55
+ -- string_concat → text null)
56
+ create table agg_rt (id integer primary key, grp text not null, v text not null);
57
+ insert into agg_rt values (1, 'a', 'x'), (2, 'a', 'y'), (3, 'b', 'z');
58
+ -- the PK column pins `collate binary` so the declared collation matches the
59
+ -- body-derived one under both suites (the store's key collation defaults to NOCASE)
60
+ create table agg_rt_mt (grp text not null collate binary primary key, ja json null, jo json null, sc text null)
61
+ maintained as select grp, json_group_array(v) as ja, json_group_object(v, id) as jo, string_concat(v) as sc from agg_rt group by grp;
62
+ select grp, ja, jo, sc from agg_rt_mt order by grp;
63
+ → [{"grp":"a","ja":["x","y"],"jo":{"x":1,"y":2},"sc":"x,y"},{"grp":"b","ja":["z"],"jo":{"z":3},"sc":"z"}]
64
+
65
+ -- a declared REAL column for a json aggregate is now a shape error (the old
66
+ -- implicit default derivation)
67
+ create table agg_rt_bad (grp text not null collate binary primary key, ja real null)
68
+ maintained as select grp, json_group_array(v) as ja from agg_rt group by grp;
69
+ -- error: body derives type
70
+
71
+ -- maintenance keeps the json/text columns consistent (storage round-trip
72
+ -- through the backing under the JSON type's hooks)
73
+ insert into agg_rt values (4, 'b', 'w');
74
+ select ja, jo, sc from agg_rt_mt where grp = 'b';
75
+ → [{"ja":["z","w"],"jo":{"z":3,"w":4},"sc":"z,w"}]
76
+
77
+ drop table agg_rt_mt;
78
+ drop table agg_rt;
@@ -0,0 +1,53 @@
1
+ -- json-extended.sqllogic - Testing JSON functions not covered in 06-builtin_functions
2
+
3
+ -- json_patch replace
4
+ select json_patch('{"a":1,"b":2}', '[{"op":"replace","path":"/a","value":3}]');
5
+ → [{"json_patch('{\"a\":1,\"b\":2}', '[{\"op\":\"replace\",\"path\":\"/a\",\"value\":3}]')":{"a":3,"b":2}}]
6
+
7
+ -- json_patch add
8
+ select json_patch('{"a":1}', '[{"op":"add","path":"/b","value":2}]');
9
+ → [{"json_patch('{\"a\":1}', '[{\"op\":\"add\",\"path\":\"/b\",\"value\":2}]')":{"a":1,"b":2}}]
10
+
11
+ -- json_patch remove
12
+ select json_patch('{"a":1,"b":2}', '[{"op":"remove","path":"/b"}]');
13
+ → [{"json_patch('{\"a\":1,\"b\":2}', '[{\"op\":\"remove\",\"path\":\"/b\"}]')":{"a":1}}]
14
+
15
+ -- json_extract with path
16
+ select json_extract('{"a":1,"b":2}', '$.a');
17
+ → [1]
18
+
19
+ -- json_array_length with nested path
20
+ select json_array_length('{"items":[1,2,3]}', '$.items');
21
+ → [3]
22
+
23
+ -- json_array_length with non-array returns 0
24
+ select json_array_length('{"a":1}');
25
+ → [0]
26
+
27
+ -- json_set creates new keys
28
+ select json_set('{"a":1}', '$.b', 'new');
29
+ → [{"a":1,"b":"new"}]
30
+
31
+ -- json_insert does NOT overwrite existing
32
+ select json_insert('{"a":1}', '$.a', 99);
33
+ → [{"a":1}]
34
+
35
+ -- json_replace does NOT create new keys
36
+ select json_replace('{"a":1}', '$.b', 99);
37
+ → [{"a":1}]
38
+
39
+ -- NULL handling
40
+ select json_valid(null), json_type(null), json_extract(null, '$.a');
41
+ → [{"json_valid(null)":false,"json_type(null)":"null","json_extract(null, '$.a')":null}]
42
+
43
+ -- json_array_length of empty array
44
+ select json_array_length('[]');
45
+ → [0]
46
+
47
+ -- json_set overwrite existing
48
+ select json_set('{"a":1}', '$.a', 99);
49
+ → [{"a":99}]
50
+
51
+ -- json_remove non-existent path (no change)
52
+ select json_remove('{"a":1}', '$.b');
53
+ → [{"a":1}]
@@ -0,0 +1,99 @@
1
+ -- json-path-operators.sqllogic - Testing -> and ->> JSON path operators
2
+
3
+ -- Basic -> with full JSON path
4
+ select '{"a":1}' -> '$.a';
5
+ → [1]
6
+
7
+ -- -> with nested path
8
+ select '{"a":{"b":2}}' -> '$.a.b';
9
+ → [2]
10
+
11
+ -- -> with string shorthand (auto-prepends $.)
12
+ select '{"name":"alice"}' -> 'name';
13
+ → ["alice"]
14
+
15
+ -- -> with integer shorthand (array index)
16
+ select '[10,20,30]' -> 0;
17
+ → [10]
18
+
19
+ select '[10,20,30]' -> 2;
20
+ → [30]
21
+
22
+ -- -> extracts nested objects as native JSON
23
+ select '{"a":[1,2]}' -> '$.a';
24
+ → [[1,2]]
25
+
26
+ -- ->> returns TEXT (using alias for clean output)
27
+ select '{"a":"hello"}' ->> '$.a' as val;
28
+ → [{"val":"hello"}]
29
+
30
+ -- ->> coerces number to TEXT
31
+ select '{"a":42}' ->> '$.a' as val;
32
+ → [{"val":"42"}]
33
+
34
+ -- ->> renders an array as JSON text (one value-to-text rule, src/util/value-text.ts
35
+ -- — this used to be the JS Array.toString() spelling '1,2')
36
+ select '{"a":[1,2]}' ->> '$.a' as val;
37
+ → [{"val":"[1,2]"}]
38
+
39
+ -- ->> with string shorthand
40
+ select '{"x":"y"}' ->> 'x' as val;
41
+ → [{"val":"y"}]
42
+
43
+ -- ->> with integer shorthand
44
+ select '["a","b"]' ->> 1 as val;
45
+ → [{"val":"b"}]
46
+
47
+ -- Chained -> operators
48
+ select '{"a":{"b":{"c":3}}}' -> 'a' -> 'b' -> 'c';
49
+ → [3]
50
+
51
+ -- NULL propagation
52
+ select null -> '$.a';
53
+ → [null]
54
+
55
+ select null ->> '$.a' as val;
56
+ → [{"val":null}]
57
+
58
+ -- Non-existent path returns NULL
59
+ select '{"a":1}' -> '$.b';
60
+ → [null]
61
+
62
+ -- -> with table data
63
+ create table jdoc (id integer primary key, data text);
64
+ insert into jdoc values (1, '{"name":"alice","age":30}'), (2, '{"name":"bob","age":25}');
65
+
66
+ select data -> 'name' from jdoc order by id;
67
+ → ["alice","bob"]
68
+
69
+ select data ->> 'age' as age from jdoc where id = 1;
70
+ → [{"age":"30"}]
71
+
72
+ -- -> with aliased result
73
+ select data -> 'name' as person_name from jdoc order by id;
74
+ → [{"person_name":"alice"},{"person_name":"bob"}]
75
+
76
+ -- -> in WHERE clause with subexpression
77
+ select id from jdoc where cast(data -> 'name' as text) = 'bob';
78
+ → [{"id":2}]
79
+
80
+ -- ->> in WHERE clause (returns text directly, no cast needed)
81
+ select id from jdoc where data ->> 'name' = 'bob';
82
+ → [{"id":2}]
83
+
84
+ -- Mixed -> and ->> chaining
85
+ select '{"a":{"b":"deep"}}' -> 'a' ->> 'b' as val;
86
+ → [{"val":"deep"}]
87
+
88
+ -- -> with boolean value
89
+ select '{"t":true}' -> 't';
90
+ → [true]
91
+
92
+ -- -> with JSON null value (distinct from SQL NULL for non-existent path)
93
+ select '{"n":null}' -> 'n';
94
+ → [null]
95
+
96
+ -- ->> with nested object returns the document's own text (one value-to-text rule,
97
+ -- src/util/value-text.ts — this used to be the placeholder '[object Object]')
98
+ select '{"a":{"x":1}}' ->> 'a' as val;
99
+ → [{"val":"{\"x\":1}"}]
@@ -0,0 +1,65 @@
1
+ -- json-canonical-key.sqllogic
2
+ -- Hash/encoded keys must agree with the JSON value comparator (deepCompareJson):
3
+ -- values that compare equal key alike, values that compare unequal key apart.
4
+ -- No `using memory`, so store mode exercises the persisted byte-key path too.
5
+
6
+ -- Distinct JSON objects form distinct groups. A PK on `id` leaves the scan ordered
7
+ -- by id, so GROUP BY on the unsorted `j` picks HashAggregate (the serializeKey path).
8
+ -- Before the canonical-key fix every object collapsed to one 'o:[object Object]' bucket.
9
+ create table jc_t (id integer primary key, j json);
10
+ insert into jc_t values (1, '{"a":1}'), (2, '{"a":2}'), (3, '{"b":9}');
11
+ -- run
12
+
13
+ select count(*) as groups from (select j from jc_t group by j);
14
+ → [{"groups":3}]
15
+
16
+ -- Reorder-equal objects ({a:1,b:2} == {b:2,a:1}) group and de-dup together.
17
+ create table jc_reorder (id integer primary key, j json);
18
+ insert into jc_reorder values (1, '{"a":1,"b":2}'), (2, '{"b":2,"a":1}'), (3, '{"a":1,"b":2}');
19
+ -- run
20
+
21
+ select count(*) as groups from (select j from jc_reorder group by j);
22
+ → [{"groups":1}]
23
+
24
+ select count(*) as c from (select distinct j from jc_reorder);
25
+ → [{"c":1}]
26
+
27
+ -- Array element order stays significant — [1,2] and [2,1] are distinct groups.
28
+ create table jc_arr (id integer primary key, j json);
29
+ insert into jc_arr values (1, '[1,2]'), (2, '[2,1]'), (3, '[1,2]');
30
+ -- run
31
+
32
+ select count(*) as groups from (select j from jc_arr group by j);
33
+ → [{"groups":2}]
34
+
35
+ -- Equality join on a JSON key matches reorder-equal values across the two sides.
36
+ create table jc_left (id integer primary key, j json);
37
+ create table jc_right (id integer primary key, j json, tag text);
38
+ insert into jc_left values (1, '{"a":1,"b":2}');
39
+ insert into jc_right values (1, '{"b":2,"a":1}', 'hit');
40
+ -- run
41
+
42
+ select l.id as lid, r.tag as tag from jc_left l join jc_right r on l.j = r.j;
43
+ → [{"lid":1,"tag":"hit"}]
44
+
45
+ -- JSON primary key: a reorder-equal insert conflicts with the existing key, so
46
+ -- `insert or replace` replaces the row rather than adding a second one.
47
+ create table jc_pk (id json primary key, n integer);
48
+ insert into jc_pk values ('{"a":1,"b":2}', 10);
49
+ insert or replace into jc_pk values ('{"b":2,"a":1}', 20);
50
+ -- run
51
+
52
+ select count(*) as c from jc_pk;
53
+ → [{"c":1}]
54
+
55
+ -- The replacing row wins; the stored/displayed JSON stays insertion-order (the
56
+ -- canonical form is used only to derive the key, never for storage or display).
57
+ select id, n from jc_pk;
58
+ → [{"id":{"b":2,"a":1},"n":20}]
59
+
60
+ -- A genuinely different JSON PK is a distinct row (no over-merge).
61
+ insert into jc_pk values ('{"a":1,"c":3}', 30);
62
+ -- run
63
+
64
+ select count(*) as c from jc_pk;
65
+ → [{"c":2}]