dirsql 0.4.124__tar.gz → 0.4.126__tar.gz

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 (488) hide show
  1. {dirsql-0.4.124 → dirsql-0.4.126}/Cargo.lock +2 -2
  2. {dirsql-0.4.124 → dirsql-0.4.126}/PKG-INFO +1 -1
  3. {dirsql-0.4.124/packages/rust → dirsql-0.4.126}/docs/reference/sdk.md +4 -5
  4. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/Cargo.toml +1 -1
  5. {dirsql-0.4.124 → dirsql-0.4.126/packages/python}/docs/reference/sdk.md +4 -5
  6. dirsql-0.4.126/packages/python/e2e-attestations/bot-1562-watch-speed-1102.json +7 -0
  7. {dirsql-0.4.124 → dirsql-0.4.126}/packages/rust/Cargo.toml +1 -1
  8. {dirsql-0.4.124/packages/python → dirsql-0.4.126/packages/rust}/docs/reference/sdk.md +4 -5
  9. {dirsql-0.4.124 → dirsql-0.4.126}/packages/rust/src/db.rs +124 -23
  10. {dirsql-0.4.124 → dirsql-0.4.126}/Cargo.toml +0 -0
  11. {dirsql-0.4.124 → dirsql-0.4.126}/README.md +0 -0
  12. {dirsql-0.4.124 → dirsql-0.4.126}/dirsql/__init__.py +0 -0
  13. {dirsql-0.4.124 → dirsql-0.4.126}/dirsql/_async.py +0 -0
  14. {dirsql-0.4.124 → dirsql-0.4.126}/dirsql/_dirsql.pyi +0 -0
  15. {dirsql-0.4.124 → dirsql-0.4.126}/dirsql/cli/__init__.py +0 -0
  16. {dirsql-0.4.124 → dirsql-0.4.126}/dirsql/cli/discover_plugins/__init__.py +0 -0
  17. {dirsql-0.4.124 → dirsql-0.4.126}/dirsql/cli/discover_plugins/discovered_fragments.py +0 -0
  18. {dirsql-0.4.124 → dirsql-0.4.126}/dirsql/cli/discover_plugins/discovery_disabled.py +0 -0
  19. {dirsql-0.4.124 → dirsql-0.4.126}/dirsql/cli/discover_plugins/fragment_path.py +0 -0
  20. {dirsql-0.4.124 → dirsql-0.4.126}/dirsql/cli/discover_plugins/with_discovered_plugins.py +0 -0
  21. {dirsql-0.4.124 → dirsql-0.4.126}/dirsql/cli/main.py +0 -0
  22. {dirsql-0.4.124 → dirsql-0.4.126}/dirsql/cli/resolve_config_extensions.py +0 -0
  23. {dirsql-0.4.124 → dirsql-0.4.126}/dirsql/plan_entry_path.py +0 -0
  24. {dirsql-0.4.124 → dirsql-0.4.126}/dirsql/py.typed +0 -0
  25. {dirsql-0.4.124 → dirsql-0.4.126}/dirsql/read_config.py +0 -0
  26. {dirsql-0.4.124 → dirsql-0.4.126}/dirsql/resolve_configs_extension_specs.py +0 -0
  27. {dirsql-0.4.124 → dirsql-0.4.126}/dirsql/resolve_extension.py +0 -0
  28. {dirsql-0.4.124 → dirsql-0.4.126}/dirsql/resolve_package.py +0 -0
  29. {dirsql-0.4.124 → dirsql-0.4.126}/docs/.claude/CLAUDE.md +0 -0
  30. {dirsql-0.4.124 → dirsql-0.4.126}/docs/.vitepress/config.ts +0 -0
  31. {dirsql-0.4.124 → dirsql-0.4.126}/docs/.vitepress/theme/index.ts +0 -0
  32. {dirsql-0.4.124 → dirsql-0.4.126}/docs/.vitepress/theme/lang.ts +0 -0
  33. {dirsql-0.4.124 → dirsql-0.4.126}/docs/AGENTS.md +0 -0
  34. {dirsql-0.4.124 → dirsql-0.4.126}/docs/context/.gitattributes +0 -0
  35. {dirsql-0.4.124 → dirsql-0.4.126}/docs/context/recipes.md +0 -0
  36. {dirsql-0.4.124 → dirsql-0.4.126}/docs/context/troubleshooting.md +0 -0
  37. {dirsql-0.4.124 → dirsql-0.4.126}/docs/context/usage.md +0 -0
  38. {dirsql-0.4.124 → dirsql-0.4.126}/docs/explanation.md +0 -0
  39. {dirsql-0.4.124 → dirsql-0.4.126}/docs/getting-started.md +0 -0
  40. {dirsql-0.4.124 → dirsql-0.4.126}/docs/howto/agent-skill.md +0 -0
  41. {dirsql-0.4.124 → dirsql-0.4.126}/docs/howto/columns-from-paths.md +0 -0
  42. {dirsql-0.4.124 → dirsql-0.4.126}/docs/howto/define-tables.md +0 -0
  43. {dirsql-0.4.124 → dirsql-0.4.126}/docs/howto/embed.md +0 -0
  44. {dirsql-0.4.124 → dirsql-0.4.126}/docs/howto/extract-from-contents.md +0 -0
  45. {dirsql-0.4.124 → dirsql-0.4.126}/docs/howto/load-extension.md +0 -0
  46. {dirsql-0.4.124 → dirsql-0.4.126}/docs/howto/parse-files-into-columns.md +0 -0
  47. {dirsql-0.4.124 → dirsql-0.4.126}/docs/howto/persist.md +0 -0
  48. {dirsql-0.4.124 → dirsql-0.4.126}/docs/howto/query-json.md +0 -0
  49. {dirsql-0.4.124 → dirsql-0.4.126}/docs/howto/query-without-config.md +0 -0
  50. {dirsql-0.4.124 → dirsql-0.4.126}/docs/howto/react-to-changes.md +0 -0
  51. {dirsql-0.4.124 → dirsql-0.4.126}/docs/howto/search-by-meaning.md +0 -0
  52. {dirsql-0.4.124 → dirsql-0.4.126}/docs/howto/search-indexes.md +0 -0
  53. {dirsql-0.4.124 → dirsql-0.4.126}/docs/howto/skip-files.md +0 -0
  54. {dirsql-0.4.124 → dirsql-0.4.126}/docs/howto/write-a-plugin.md +0 -0
  55. {dirsql-0.4.124 → dirsql-0.4.126}/docs/index.md +0 -0
  56. {dirsql-0.4.124 → dirsql-0.4.126}/docs/package.json +0 -0
  57. {dirsql-0.4.124 → dirsql-0.4.126}/docs/plugins.md +0 -0
  58. {dirsql-0.4.124 → dirsql-0.4.126}/docs/pnpm-lock.yaml +0 -0
  59. {dirsql-0.4.124 → dirsql-0.4.126}/docs/pnpm-workspace.yaml +0 -0
  60. {dirsql-0.4.124 → dirsql-0.4.126}/docs/reference/cli.md +0 -0
  61. {dirsql-0.4.124 → dirsql-0.4.126}/docs/reference/columns.md +0 -0
  62. {dirsql-0.4.124 → dirsql-0.4.126}/docs/reference/config.md +0 -0
  63. {dirsql-0.4.124 → dirsql-0.4.126}/docs/reference/glob.md +0 -0
  64. {dirsql-0.4.124 → dirsql-0.4.126}/docs/reference/hooks.md +0 -0
  65. {dirsql-0.4.124 → dirsql-0.4.126}/docs/reference/http-api.md +0 -0
  66. {dirsql-0.4.124 → dirsql-0.4.126}/docs/reference/path-tables.md +0 -0
  67. {dirsql-0.4.124 → dirsql-0.4.126}/docs/speed.json +0 -0
  68. {dirsql-0.4.124 → dirsql-0.4.126}/docs/speed.md +0 -0
  69. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/CHANGELOG.md +0 -0
  70. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/MIGRATIONS.md +0 -0
  71. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/README.md +0 -0
  72. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/changelog.d/2026-07-13-drop-cwd-config-auto-detect.md +0 -0
  73. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/changelog.d/2026-07-13-plugin-discovery.md +0 -0
  74. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/changelog.d/2026-07-13-rename-extract-to-on-file.md +0 -0
  75. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/changelog.d/2026-07-13-repeatable-config.md +0 -0
  76. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/changelog.d/2026-07-13-sdk-default-baked-in-config.md +0 -0
  77. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/changelog.d/2026-07-20-drop-implicit-files-table.md +0 -0
  78. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/changelog.d/2026-07-21-remove-glob-captures.md +0 -0
  79. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/changelog.d/2026-07-24-hookless-table-config-error.md +0 -0
  80. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/changelog.d/2026-07-24-remove-stat-fact-injection.md +0 -0
  81. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/changelog.d/2026-07-29-restore-python-310.md +0 -0
  82. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/changelog.d/2026-08-02-release-profile.md +0 -0
  83. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/changelog.d/2026-08-02-scan-failures.md +0 -0
  84. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/changelog.d/2026-08-03-discovery-ext-resolution.md +0 -0
  85. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/changelog.d/2026-08-03-manylinux-dynamic-binary.md +0 -0
  86. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/changelog.d/2026-08-03-python-no-ignore.md +0 -0
  87. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/changelog.d/2026-08-04-cast-lints.md +0 -0
  88. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/changelog.d/2026-08-04-cli-in-process.md +0 -0
  89. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/changelog.d/2026-08-20-curtaincall-dev-dependency.md +0 -0
  90. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/changelog.d/2026-08-20-declared-table-name.md +0 -0
  91. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/changelog.d/2026-09-04-config-paths-from-argv-module.md +0 -0
  92. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/changelog.d/2026-09-05-config-extension-loader-split.md +0 -0
  93. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/changelog.d/2026-09-05-resolve-config-extensions-split.md +0 -0
  94. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/changelog.d/2026-09-05-resolve-extension-split.md +0 -0
  95. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/changelog.d/2026-09-09-launcher-config-path-scan.md +0 -0
  96. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/changelog.d/2026-09-17-extension-resolution-via-core.md +0 -0
  97. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/changelog.d/2026-09-18-export-scan-failure.md +0 -0
  98. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/changelog.d/2026-09-18-flatten-row-event-in-core.md +0 -0
  99. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/changelog.d/2026-09-18-programmatic-extension-plan.md +0 -0
  100. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/changelog.d/2026-09-20-sigint-ends-a-run-in-progress.md +0 -0
  101. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/changelog.d/2026-09-24-query-rows-in-projection-order.md +0 -0
  102. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/changelog.d/2026-10-02-readme-docs-host.md +0 -0
  103. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/changelog.d/2026-10-03-one-glob-rule-for-config-globs.md +0 -0
  104. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/changelog.d/2026-10-03-path-table-directory-one-level.md +0 -0
  105. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/changelog.d/2026-10-04-path-table-dotfiles-hidden.md +0 -0
  106. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/changelog.d/2026-10-05-brace-groups-follow-bash.md +0 -0
  107. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/changelog.d/2026-10-05-cli-context.md +0 -0
  108. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/changelog.d/2026-10-05-gitignore-requires-repo.md +0 -0
  109. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/changelog.d/2026-10-05-path-table-node-modules-named.md +0 -0
  110. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/changelog.d/2026-10-05-path-table-symlinks.md +0 -0
  111. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/changelog.d/2026-10-05-path-table-trailing-slash.md +0 -0
  112. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/changelog.d/2026-10-05-unbalanced-brackets-literal.md +0 -0
  113. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/changelog.d/2026-10-06-config-braces.md +0 -0
  114. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/changelog.d/2026-10-06-config-directory.md +0 -0
  115. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/changelog.d/2026-10-06-config-dotnames.md +0 -0
  116. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/changelog.d/2026-10-06-config-gitignore.md +0 -0
  117. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/changelog.d/2026-10-06-config-globs-anchor-at-the-config.md +0 -0
  118. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/changelog.d/2026-10-06-config-links.md +0 -0
  119. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/changelog.d/2026-10-06-one-glob-compiler.md +0 -0
  120. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/changelog.d/2026-10-06-plugin-no-default-records.md +0 -0
  121. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/changelog.d/2026-10-06-watch-broadcast.md +0 -0
  122. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/changelog.d/2026-10-06-zero-match-config-table-warning.md +0 -0
  123. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/changelog.d/2026-10-07-bracket-slash-literal.md +0 -0
  124. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/changelog.d/2026-10-07-dotdot-and-double-slashes.md +0 -0
  125. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/changelog.d/2026-10-07-dotdot-as-written.md +0 -0
  126. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/changelog.d/2026-10-07-glob-walks-node-modules.md +0 -0
  127. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/changelog.d/2026-10-07-literal-gitignore.md +0 -0
  128. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/changelog.d/2026-10-07-on-file-ndjson.md +0 -0
  129. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/changelog.d/2026-10-07-parallel-hooks.md +0 -0
  130. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/changelog.d/2026-10-07-persist-cache-outside-root.md +0 -0
  131. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/changelog.d/2026-10-07-posix-classes-unicode.md +0 -0
  132. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/changelog.d/2026-10-07-spread-few-large-files.md +0 -0
  133. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/changelog.d/2026-10-08-small-walks-stay-on-one-thread.md +0 -0
  134. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/changelog.d/2026-10-08-watch-requires-named-table.md +0 -0
  135. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/changelog.d/2026-11-02-watch-dirs-created-mid-registration.md +0 -0
  136. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/changelog.d/2026-11-02-watch-live-on-return.md +0 -0
  137. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/changelog.d/README.md +0 -0
  138. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/conftest.py +0 -0
  139. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/docs/.claude/CLAUDE.md +0 -0
  140. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/docs/.vitepress/config.ts +0 -0
  141. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/docs/.vitepress/theme/index.ts +0 -0
  142. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/docs/.vitepress/theme/lang.ts +0 -0
  143. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/docs/AGENTS.md +0 -0
  144. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/docs/context/.gitattributes +0 -0
  145. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/docs/context/recipes.md +0 -0
  146. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/docs/context/troubleshooting.md +0 -0
  147. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/docs/context/usage.md +0 -0
  148. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/docs/explanation.md +0 -0
  149. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/docs/getting-started.md +0 -0
  150. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/docs/howto/agent-skill.md +0 -0
  151. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/docs/howto/columns-from-paths.md +0 -0
  152. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/docs/howto/define-tables.md +0 -0
  153. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/docs/howto/embed.md +0 -0
  154. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/docs/howto/extract-from-contents.md +0 -0
  155. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/docs/howto/load-extension.md +0 -0
  156. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/docs/howto/parse-files-into-columns.md +0 -0
  157. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/docs/howto/persist.md +0 -0
  158. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/docs/howto/query-json.md +0 -0
  159. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/docs/howto/query-without-config.md +0 -0
  160. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/docs/howto/react-to-changes.md +0 -0
  161. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/docs/howto/search-by-meaning.md +0 -0
  162. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/docs/howto/search-indexes.md +0 -0
  163. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/docs/howto/skip-files.md +0 -0
  164. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/docs/howto/write-a-plugin.md +0 -0
  165. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/docs/index.md +0 -0
  166. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/docs/package.json +0 -0
  167. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/docs/plugins.md +0 -0
  168. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/docs/pnpm-lock.yaml +0 -0
  169. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/docs/pnpm-workspace.yaml +0 -0
  170. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/docs/reference/cli.md +0 -0
  171. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/docs/reference/columns.md +0 -0
  172. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/docs/reference/config.md +0 -0
  173. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/docs/reference/glob.md +0 -0
  174. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/docs/reference/hooks.md +0 -0
  175. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/docs/reference/http-api.md +0 -0
  176. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/docs/reference/path-tables.md +0 -0
  177. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/docs/speed.json +0 -0
  178. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/docs/speed.md +0 -0
  179. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/bot-1334-listing-exemptions.json +0 -0
  180. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/bot-1397-watch-broadcast.json +0 -0
  181. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/bot-1398-inotify-error.json +0 -0
  182. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/bot-1399-server-cors.json +0 -0
  183. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/bot-1401-watch-scope.json +0 -0
  184. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/bot-1406-watch-no-tables-1008.json +0 -0
  185. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/bot-1407-child-place-depth.json +0 -0
  186. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/bot-1414-stat-speed.json +0 -0
  187. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/bot-1415-server-speed.json +0 -0
  188. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/bot-1416-watch-speed-1008.json +0 -0
  189. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/bot-1418-node-modules.json +0 -0
  190. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/bot-1419-dotdot-slashes.json +0 -0
  191. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/bot-1420-bracket-slash.json +0 -0
  192. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/bot-1421-posix-unicode.json +0 -0
  193. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/bot-1422-literal-gitignore.json +0 -0
  194. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/bot-1426-walk-spawn-threshold-1008.json +0 -0
  195. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/bot-1428-ndjson-hooks.json +0 -0
  196. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/bot-1429-parallel-hooks.json +0 -0
  197. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/bot-1430-dotdot-as-written.json +0 -0
  198. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/bot-1431-persist-cache-dir.json +0 -0
  199. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/bot-1437-test-cache-isolation.json +0 -0
  200. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/bot-1440-fix-main-build.json +0 -0
  201. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/bot-1448-wildcard-ignored-prefix.json +0 -0
  202. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/bot-1451-named-dir-never-hidden.json +0 -0
  203. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/bot-1454-split-few-files.json +0 -0
  204. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/bot-1457-incremental-refresh-1008.json +0 -0
  205. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/bot-1459-rescan-on-overflow-1008.json +0 -0
  206. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/bot-1461-chunked-read-1016.json +0 -0
  207. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/bot-1461-row-footprint-1008.json +0 -0
  208. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/bot-1461-step3-1020.json +0 -0
  209. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/bot-1461-wide-read-1015.json +0 -0
  210. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/bot-1462-paired-speed-harness-1008.json +0 -0
  211. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/bot-1464-fastest-native-1008.json +0 -0
  212. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/bot-1469-ci-speed-sanity-1009.json +0 -0
  213. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/bot-1470-perf-suite-1009.json +0 -0
  214. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/bot-1470-speed-page-1011.json +0 -0
  215. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/bot-1474-vtab-speed-1014.json +0 -0
  216. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/bot-1475-rowpath-1016.json +0 -0
  217. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/bot-1477-onelevel-speed-1015.json +0 -0
  218. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/bot-1477-onelevel-speed-1016.json +0 -0
  219. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/bot-1478-perdir-walk-1020.json +0 -0
  220. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/bot-1480-matcher-speed-1015.json +0 -0
  221. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/bot-1481-gitrepo-speed-1015.json +0 -0
  222. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/bot-1483-fm-speed-1015.json +0 -0
  223. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/bot-1484-jsonl-speed-1015.json +0 -0
  224. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/bot-1487-frontend-query-1011.json +0 -0
  225. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/bot-1488-frontend-metadata-1011.json +0 -0
  226. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/bot-1489-frontend-browse-1013.json +0 -0
  227. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/bot-1503-bench-watch-1011.json +0 -0
  228. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/bot-1504-bench-names-1011.json +0 -0
  229. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/bot-1514-watch-rerun-inline-1015.json +0 -0
  230. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/bot-1524-path-eq-1016.json +0 -0
  231. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/bot-1526-main-red-1016.json +0 -0
  232. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/bot-1532-gitignore-fastest-bar-1016.json +0 -0
  233. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/bot-1534-fm-native-1016.json +0 -0
  234. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/bot-1534-fm-native-1102.json +0 -0
  235. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/bot-1538-onfile-order-1019.json +0 -0
  236. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/bot-1540-update-in-place-1019.json +0 -0
  237. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/bot-1541-defer-fk-1019.json +0 -0
  238. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/bot-1544-perfile-update-1020.json +0 -0
  239. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/bot-1552-watch-gap-1102.json +0 -0
  240. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/bot-1557-watch-rename-1102.json +0 -0
  241. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/bot-fix-main-place-depth-20261007.json +0 -0
  242. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/bot-issue-1486-frontend-20261009.json +0 -0
  243. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/bot-speed-gap-childpath-1011.json +0 -0
  244. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/bot-speed-parse-overlap-1011.json +0 -0
  245. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/bot-speed-parse-paths-1009.json +0 -0
  246. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/bot-speed-parse-pragmas-1011.json +0 -0
  247. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/bot-speed-sql-valueref-1013.json +0 -0
  248. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/bot-speed-walk-components-1011.json +0 -0
  249. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/bot-speed-walk-rowpath-1011.json +0 -0
  250. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/bot-speed-walk-rows-1013.json +0 -0
  251. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/bot-speed-walk-sched-1009.json +0 -0
  252. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/cc-keen-knuth-f11gyq.json +0 -0
  253. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/claude-1056-py-ofpf9.json +0 -0
  254. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/claude-1066-p1-resolve-extension.json +0 -0
  255. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/claude-1078-argv-config-paths-core.json +0 -0
  256. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/claude-1079-p2-resolve-config-extensions.json +0 -0
  257. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/claude-1080-share-vtab-scaffolding.json +0 -0
  258. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/claude-1081-indicatif-progress.json +0 -0
  259. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/claude-1096-watch-moved-dir.json +0 -0
  260. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/claude-1109-watch-moved-out.json +0 -0
  261. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/claude-1119-ext-plan.json +0 -0
  262. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/claude-1120-py-ext.json +0 -0
  263. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/claude-1122-ext-cleanup.json +0 -0
  264. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/claude-1130-codec-crates.json +0 -0
  265. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/claude-1131-flatten-row-event.json +0 -0
  266. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/claude-1139-sse-flatten.json +0 -0
  267. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/claude-1140-scan-failure-export.json +0 -0
  268. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/claude-1148-clippy-all-targets.json +0 -0
  269. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/claude-1164-sigint-fatal.json +0 -0
  270. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/claude-1170-projection-order.json +0 -0
  271. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/claude-1172-on-file-path.json +0 -0
  272. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/claude-1173-py-projection-order.json +0 -0
  273. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/claude-1184-win-rel-paths.json +0 -0
  274. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/claude-1185-win-abs-table-names.json +0 -0
  275. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/claude-1186-win-test-harness.json +0 -0
  276. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/claude-1196-join-index.json +0 -0
  277. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/claude-1199-glob-prefix.json +0 -0
  278. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/claude-1201-single-walk.json +0 -0
  279. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/claude-1204-embed-batch.json +0 -0
  280. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/claude-1207-win-argv-quote.json +0 -0
  281. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/claude-1208-win-nonverbatim-paths.json +0 -0
  282. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/claude-1215-on-file-batch.json +0 -0
  283. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/claude-1216-on-file-cleanup.json +0 -0
  284. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/claude-1223-config-glob-rule.json +0 -0
  285. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/claude-1223-dir-one-level.json +0 -0
  286. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/claude-1225-plugin-no-default.json +0 -0
  287. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/claude-1226-stale-docs.json +0 -0
  288. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/claude-1232-anchor-plumbing.json +0 -0
  289. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/claude-1232-config-anchor.json +0 -0
  290. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/claude-1232-multi-watch.json +0 -0
  291. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/claude-1232-zero-match.json +0 -0
  292. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/claude-1238-parallel-walk.json +0 -0
  293. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/claude-1241-content-prefetch.json +0 -0
  294. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/claude-1243-ingest-perf.json +0 -0
  295. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/claude-1249-dotfiles.json +0 -0
  296. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/claude-1256-symlinks.json +0 -0
  297. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/claude-1257-trailing-slash.json +0 -0
  298. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/claude-1258-config-braces.json +0 -0
  299. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/claude-1258-config-directory.json +0 -0
  300. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/claude-1258-config-dotnames.json +0 -0
  301. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/claude-1258-config-gitignore.json +0 -0
  302. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/claude-1258-config-links.json +0 -0
  303. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/claude-1258-one-pattern.json +0 -0
  304. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/claude-1262-brace-literal.json +0 -0
  305. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/claude-1264-context.json +0 -0
  306. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/claude-1267-posix-classes.json +0 -0
  307. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/claude-1268-unbalanced-brackets.json +0 -0
  308. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/claude-1269-utf8-chars.json +0 -0
  309. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/claude-1271-node-modules-named.json +0 -0
  310. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/claude-1272-ancestor-gitignore.json +0 -0
  311. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/claude-1273-walk-prune.json +0 -0
  312. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/claude-1285-ingest-fast.json +0 -0
  313. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/claude-1286-nested-repo.json +0 -0
  314. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/claude-1305-glob-speed.json +0 -0
  315. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/claude-1308-glob-speed.json +0 -0
  316. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/claude-1310-glob-speed.json +0 -0
  317. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/claude-1311-glob-speed.json +0 -0
  318. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/claude-1312-glob-speed.json +0 -0
  319. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/claude-1318-lazy-stat.json +0 -0
  320. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/claude-1320-walk-speed.json +0 -0
  321. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/claude-1322-walk-readdir.json +0 -0
  322. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/claude-1325-parallel-walk.json +0 -0
  323. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/claude-1326-stream-rows.json +0 -0
  324. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/claude-1330-python-dirsql-patch.json +0 -0
  325. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/claude-1330-python-extensions-patch.json +0 -0
  326. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/claude-1330-scanner-effects.json +0 -0
  327. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/claude-1330-scanner-gitignore.json +0 -0
  328. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/claude-1330-vtab-prefetch-flag.json +0 -0
  329. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/claude-1330-vtab-read.json +0 -0
  330. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/claude-1351-dot-dirs.json +0 -0
  331. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/claude-819-oneshot-timeout.json +0 -0
  332. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/claude-827-unquote-doubled-quotes.json +0 -0
  333. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/claude-epic-953-slice2-reedline.json +0 -0
  334. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/claude-epic-953-slice3-format.json +0 -0
  335. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/claude-epic-953-stacked-prs-x59wm3.json +0 -0
  336. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/claude-github-issue-825-e4mhhp.json +0 -0
  337. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/claude-issue-951-0eease.json +0 -0
  338. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/claude-issue-962-0jjrfv.json +0 -0
  339. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/claude-issue-986-red-test-e7sjrb.json +0 -0
  340. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/claude-tackle-1034-cachesplit.json +0 -0
  341. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/claude-tackle-1042-py12.json +0 -0
  342. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/claude-tackle-956-xzen74.json +0 -0
  343. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/claude-tackle-957-lrm0z6-worker-calls.json +0 -0
  344. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/claude-tackle-957-lrm0z6.json +0 -0
  345. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/e2e-attestations/claude-tackle-975-n8mc2h.json +0 -0
  346. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/migrations.d/2026-07-13-drop-cwd-config-auto-detect.md +0 -0
  347. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/migrations.d/2026-07-13-rename-extract-to-on-file.md +0 -0
  348. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/migrations.d/2026-07-13-sdk-default-baked-in-config.md +0 -0
  349. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/migrations.d/2026-07-20-drop-implicit-files-table.md +0 -0
  350. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/migrations.d/2026-07-21-remove-glob-captures.md +0 -0
  351. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/migrations.d/2026-07-24-hookless-table-config-error.md +0 -0
  352. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/migrations.d/2026-07-24-remove-stat-fact-injection.md +0 -0
  353. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/migrations.d/2026-07-29-restore-python-310.md +0 -0
  354. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/migrations.d/2026-08-04-cli-in-process.md +0 -0
  355. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/migrations.d/2026-08-20-declared-table-name.md +0 -0
  356. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/migrations.d/2026-09-20-sigint-ends-a-run-in-progress.md +0 -0
  357. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/migrations.d/2026-09-24-query-rows-in-projection-order.md +0 -0
  358. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/migrations.d/2026-10-02-readme-docs-host.md +0 -0
  359. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/migrations.d/2026-10-03-one-glob-rule-for-config-globs.md +0 -0
  360. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/migrations.d/2026-10-03-path-table-directory-one-level.md +0 -0
  361. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/migrations.d/2026-10-04-path-table-dotfiles-hidden.md +0 -0
  362. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/migrations.d/2026-10-05-brace-groups-follow-bash.md +0 -0
  363. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/migrations.d/2026-10-05-cli-context.md +0 -0
  364. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/migrations.d/2026-10-05-gitignore-requires-repo.md +0 -0
  365. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/migrations.d/2026-10-05-path-table-node-modules-named.md +0 -0
  366. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/migrations.d/2026-10-05-path-table-symlinks.md +0 -0
  367. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/migrations.d/2026-10-05-path-table-trailing-slash.md +0 -0
  368. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/migrations.d/2026-10-05-unbalanced-brackets-literal.md +0 -0
  369. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/migrations.d/2026-10-06-config-braces.md +0 -0
  370. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/migrations.d/2026-10-06-config-directory.md +0 -0
  371. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/migrations.d/2026-10-06-config-dotnames.md +0 -0
  372. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/migrations.d/2026-10-06-config-gitignore.md +0 -0
  373. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/migrations.d/2026-10-06-config-globs-anchor-at-the-config.md +0 -0
  374. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/migrations.d/2026-10-06-config-links.md +0 -0
  375. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/migrations.d/2026-10-06-one-glob-compiler.md +0 -0
  376. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/migrations.d/2026-10-06-plugin-no-default-records.md +0 -0
  377. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/migrations.d/2026-10-06-watch-broadcast.md +0 -0
  378. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/migrations.d/2026-10-06-zero-match-config-table-warning.md +0 -0
  379. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/migrations.d/2026-10-07-bracket-slash-literal.md +0 -0
  380. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/migrations.d/2026-10-07-dotdot-and-double-slashes.md +0 -0
  381. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/migrations.d/2026-10-07-dotdot-as-written.md +0 -0
  382. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/migrations.d/2026-10-07-glob-walks-node-modules.md +0 -0
  383. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/migrations.d/2026-10-07-literal-gitignore.md +0 -0
  384. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/migrations.d/2026-10-07-on-file-ndjson.md +0 -0
  385. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/migrations.d/2026-10-07-parallel-hooks.md +0 -0
  386. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/migrations.d/2026-10-07-persist-cache-outside-root.md +0 -0
  387. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/migrations.d/2026-10-07-posix-classes-unicode.md +0 -0
  388. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/migrations.d/2026-10-07-spread-few-large-files.md +0 -0
  389. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/migrations.d/2026-10-08-small-walks-stay-on-one-thread.md +0 -0
  390. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/migrations.d/2026-10-08-watch-requires-named-table.md +0 -0
  391. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/migrations.d/2026-11-02-watch-dirs-created-mid-registration.md +0 -0
  392. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/migrations.d/2026-11-02-watch-live-on-return.md +0 -0
  393. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/migrations.d/README.md +0 -0
  394. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/src/lib.rs +0 -0
  395. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/testing-conventions.toml +0 -0
  396. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/tests/__init__.py +0 -0
  397. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/tests/conftest.py +0 -0
  398. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/tests/e2e/__init__.py +0 -0
  399. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/tests/e2e/bench_report.py +0 -0
  400. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/tests/e2e/bench_suite.py +0 -0
  401. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/tests/e2e/fixtures/dirsql_plugin_fixture/__init__.py +0 -0
  402. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/tests/e2e/fixtures/dirsql_plugin_fixture/dirsql.toml +0 -0
  403. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/tests/e2e/speed_of_light.py +0 -0
  404. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/tests/integration/__init__.py +0 -0
  405. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/tests/integration/binding/__init__.py +0 -0
  406. {dirsql-0.4.124 → dirsql-0.4.126}/packages/python/tests/integration/hermetic/__init__.py +0 -0
  407. {dirsql-0.4.124 → dirsql-0.4.126}/packages/rust/CHANGELOG.md +0 -0
  408. {dirsql-0.4.124 → dirsql-0.4.126}/packages/rust/MIGRATIONS.md +0 -0
  409. {dirsql-0.4.124 → dirsql-0.4.126}/packages/rust/README.md +0 -0
  410. {dirsql-0.4.124 → dirsql-0.4.126}/packages/rust/benches/db_bench.rs +0 -0
  411. {dirsql-0.4.124 → dirsql-0.4.126}/packages/rust/benches/differ_bench.rs +0 -0
  412. {dirsql-0.4.124 → dirsql-0.4.126}/packages/rust/benches/matcher_bench.rs +0 -0
  413. {dirsql-0.4.124 → dirsql-0.4.126}/packages/rust/benches/scanner_bench.rs +0 -0
  414. {dirsql-0.4.124 → dirsql-0.4.126}/packages/rust/docs/context/.gitattributes +0 -0
  415. {dirsql-0.4.124 → dirsql-0.4.126}/packages/rust/docs/context/recipes.md +0 -0
  416. {dirsql-0.4.124 → dirsql-0.4.126}/packages/rust/docs/context/troubleshooting.md +0 -0
  417. {dirsql-0.4.124 → dirsql-0.4.126}/packages/rust/docs/context/usage.md +0 -0
  418. {dirsql-0.4.124 → dirsql-0.4.126}/packages/rust/docs/explanation.md +0 -0
  419. {dirsql-0.4.124 → dirsql-0.4.126}/packages/rust/docs/getting-started.md +0 -0
  420. {dirsql-0.4.124 → dirsql-0.4.126}/packages/rust/docs/howto/agent-skill.md +0 -0
  421. {dirsql-0.4.124 → dirsql-0.4.126}/packages/rust/docs/howto/columns-from-paths.md +0 -0
  422. {dirsql-0.4.124 → dirsql-0.4.126}/packages/rust/docs/howto/define-tables.md +0 -0
  423. {dirsql-0.4.124 → dirsql-0.4.126}/packages/rust/docs/howto/embed.md +0 -0
  424. {dirsql-0.4.124 → dirsql-0.4.126}/packages/rust/docs/howto/extract-from-contents.md +0 -0
  425. {dirsql-0.4.124 → dirsql-0.4.126}/packages/rust/docs/howto/load-extension.md +0 -0
  426. {dirsql-0.4.124 → dirsql-0.4.126}/packages/rust/docs/howto/parse-files-into-columns.md +0 -0
  427. {dirsql-0.4.124 → dirsql-0.4.126}/packages/rust/docs/howto/persist.md +0 -0
  428. {dirsql-0.4.124 → dirsql-0.4.126}/packages/rust/docs/howto/query-json.md +0 -0
  429. {dirsql-0.4.124 → dirsql-0.4.126}/packages/rust/docs/howto/query-without-config.md +0 -0
  430. {dirsql-0.4.124 → dirsql-0.4.126}/packages/rust/docs/howto/react-to-changes.md +0 -0
  431. {dirsql-0.4.124 → dirsql-0.4.126}/packages/rust/docs/howto/search-by-meaning.md +0 -0
  432. {dirsql-0.4.124 → dirsql-0.4.126}/packages/rust/docs/howto/search-indexes.md +0 -0
  433. {dirsql-0.4.124 → dirsql-0.4.126}/packages/rust/docs/howto/skip-files.md +0 -0
  434. {dirsql-0.4.124 → dirsql-0.4.126}/packages/rust/docs/howto/write-a-plugin.md +0 -0
  435. {dirsql-0.4.124 → dirsql-0.4.126}/packages/rust/docs/index.md +0 -0
  436. {dirsql-0.4.124 → dirsql-0.4.126}/packages/rust/docs/plugins.md +0 -0
  437. {dirsql-0.4.124 → dirsql-0.4.126}/packages/rust/docs/reference/cli.md +0 -0
  438. {dirsql-0.4.124 → dirsql-0.4.126}/packages/rust/docs/reference/columns.md +0 -0
  439. {dirsql-0.4.124 → dirsql-0.4.126}/packages/rust/docs/reference/config.md +0 -0
  440. {dirsql-0.4.124 → dirsql-0.4.126}/packages/rust/docs/reference/glob.md +0 -0
  441. {dirsql-0.4.124 → dirsql-0.4.126}/packages/rust/docs/reference/hooks.md +0 -0
  442. {dirsql-0.4.124 → dirsql-0.4.126}/packages/rust/docs/reference/http-api.md +0 -0
  443. {dirsql-0.4.124 → dirsql-0.4.126}/packages/rust/docs/reference/path-tables.md +0 -0
  444. {dirsql-0.4.124 → dirsql-0.4.126}/packages/rust/docs/speed.json +0 -0
  445. {dirsql-0.4.124 → dirsql-0.4.126}/packages/rust/docs/speed.md +0 -0
  446. {dirsql-0.4.124 → dirsql-0.4.126}/packages/rust/src/bin/dirsql.rs +0 -0
  447. {dirsql-0.4.124 → dirsql-0.4.126}/packages/rust/src/brace.rs +0 -0
  448. {dirsql-0.4.124 → dirsql-0.4.126}/packages/rust/src/cli/context.rs +0 -0
  449. {dirsql-0.4.124 → dirsql-0.4.126}/packages/rust/src/cli/execute.rs +0 -0
  450. {dirsql-0.4.124 → dirsql-0.4.126}/packages/rust/src/cli/frontend.html +0 -0
  451. {dirsql-0.4.124 → dirsql-0.4.126}/packages/rust/src/cli/frontend.js +0 -0
  452. {dirsql-0.4.124 → dirsql-0.4.126}/packages/rust/src/cli/init.rs +0 -0
  453. {dirsql-0.4.124 → dirsql-0.4.126}/packages/rust/src/cli/mod.rs +0 -0
  454. {dirsql-0.4.124 → dirsql-0.4.126}/packages/rust/src/cli/repl.rs +0 -0
  455. {dirsql-0.4.124 → dirsql-0.4.126}/packages/rust/src/cli/router.rs +0 -0
  456. {dirsql-0.4.124 → dirsql-0.4.126}/packages/rust/src/cli/run.rs +0 -0
  457. {dirsql-0.4.124 → dirsql-0.4.126}/packages/rust/src/cli/serialize.rs +0 -0
  458. {dirsql-0.4.124 → dirsql-0.4.126}/packages/rust/src/cli/server.rs +0 -0
  459. {dirsql-0.4.124 → dirsql-0.4.126}/packages/rust/src/cli/table.rs +0 -0
  460. {dirsql-0.4.124 → dirsql-0.4.126}/packages/rust/src/command.rs +0 -0
  461. {dirsql-0.4.124 → dirsql-0.4.126}/packages/rust/src/config.rs +0 -0
  462. {dirsql-0.4.124 → dirsql-0.4.126}/packages/rust/src/default_config.toml +0 -0
  463. {dirsql-0.4.124 → dirsql-0.4.126}/packages/rust/src/differ.rs +0 -0
  464. {dirsql-0.4.124 → dirsql-0.4.126}/packages/rust/src/extension_resolution.rs +0 -0
  465. {dirsql-0.4.124 → dirsql-0.4.126}/packages/rust/src/foreign_key.rs +0 -0
  466. {dirsql-0.4.124 → dirsql-0.4.126}/packages/rust/src/functions.rs +0 -0
  467. {dirsql-0.4.124 → dirsql-0.4.126}/packages/rust/src/gitignore_frame.rs +0 -0
  468. {dirsql-0.4.124 → dirsql-0.4.126}/packages/rust/src/infer.rs +0 -0
  469. {dirsql-0.4.124 → dirsql-0.4.126}/packages/rust/src/launcher.rs +0 -0
  470. {dirsql-0.4.124 → dirsql-0.4.126}/packages/rust/src/lib.rs +0 -0
  471. {dirsql-0.4.124 → dirsql-0.4.126}/packages/rust/src/listing.rs +0 -0
  472. {dirsql-0.4.124 → dirsql-0.4.126}/packages/rust/src/matcher.rs +0 -0
  473. {dirsql-0.4.124 → dirsql-0.4.126}/packages/rust/src/on_file.rs +0 -0
  474. {dirsql-0.4.124 → dirsql-0.4.126}/packages/rust/src/parsed_vtab.rs +0 -0
  475. {dirsql-0.4.124 → dirsql-0.4.126}/packages/rust/src/path_table.rs +0 -0
  476. {dirsql-0.4.124 → dirsql-0.4.126}/packages/rust/src/per_thread.rs +0 -0
  477. {dirsql-0.4.124 → dirsql-0.4.126}/packages/rust/src/persist.rs +0 -0
  478. {dirsql-0.4.124 → dirsql-0.4.126}/packages/rust/src/posix_class.rs +0 -0
  479. {dirsql-0.4.124 → dirsql-0.4.126}/packages/rust/src/progress.rs +0 -0
  480. {dirsql-0.4.124 → dirsql-0.4.126}/packages/rust/src/row_event_flat.rs +0 -0
  481. {dirsql-0.4.124 → dirsql-0.4.126}/packages/rust/src/row_stream.rs +0 -0
  482. {dirsql-0.4.124 → dirsql-0.4.126}/packages/rust/src/scanner.rs +0 -0
  483. {dirsql-0.4.124 → dirsql-0.4.126}/packages/rust/src/sql_literal.rs +0 -0
  484. {dirsql-0.4.124 → dirsql-0.4.126}/packages/rust/src/tree_walk.rs +0 -0
  485. {dirsql-0.4.124 → dirsql-0.4.126}/packages/rust/src/vtab.rs +0 -0
  486. {dirsql-0.4.124 → dirsql-0.4.126}/packages/rust/src/vtab_scaffold.rs +0 -0
  487. {dirsql-0.4.124 → dirsql-0.4.126}/packages/rust/src/watcher.rs +0 -0
  488. {dirsql-0.4.124 → dirsql-0.4.126}/pyproject.toml +0 -0
@@ -573,7 +573,7 @@ dependencies = [
573
573
 
574
574
  [[package]]
575
575
  name = "dirsql"
576
- version = "0.4.124"
576
+ version = "0.4.126"
577
577
  dependencies = [
578
578
  "assert_cmd",
579
579
  "axum",
@@ -625,7 +625,7 @@ dependencies = [
625
625
 
626
626
  [[package]]
627
627
  name = "dirsql-py-ext"
628
- version = "0.4.124"
628
+ version = "0.4.126"
629
629
  dependencies = [
630
630
  "dirsql",
631
631
  "pyo3",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dirsql
3
- Version: 0.4.124
3
+ Version: 0.4.126
4
4
  Requires-Dist: bin-shim>=0.1
5
5
  Summary: Ephemeral SQL index over a local directory
6
6
  Keywords: sql,filesystem,directory,sqlite,index
@@ -300,11 +300,10 @@ Returns a stream of [`RowEvent`](#rowevent)s reflecting filesystem changes
300
300
  under the root. The stream never terminates on its own; stop consuming it
301
301
  to stop.
302
302
 
303
- A file written once the watcher is live produces an event and reaches the
304
- index. Rust: the watcher is live when `watch()` returns. Python: it is live
305
- once both `watch()` and `ready()` have returned, in either order; a write made
306
- while the initial scan is still running may be missed. TypeScript: the watcher
307
- starts on first iteration.
303
+ The watcher is live once both `watch()` and [`ready`](#ready) have returned,
304
+ in either order (a Rust `DirSQL` is ready when `build()` returns); a file
305
+ written after that point produces an event and reaches the index. A write
306
+ made while the initial scan is still running may be missed.
308
307
 
309
308
  An instance with no named tables cannot be watched: path-tables emit no
310
309
  watch events, so `watch()` (and the polling primitives) raise an error naming
@@ -4,7 +4,7 @@ name = "dirsql-py-ext"
4
4
  # pypi/maturin handler can rewrite it via `write-version` before
5
5
  # `maturin build`. `pyproject.toml` declares `dynamic = ["version"]`
6
6
  # and maturin reads this field. Mirrors `packages/rust/Cargo.toml`.
7
- version = "0.4.124"
7
+ version = "0.4.126"
8
8
  # abi3 note: the `abi3-py310` pyo3 feature (below) builds ONE stable-ABI
9
9
  # `cp310-abi3` wheel per platform that loads on every CPython >= 3.10
10
10
  # (matching `pyproject.toml`'s `requires-python = ">=3.10"`), instead of
@@ -300,11 +300,10 @@ Returns a stream of [`RowEvent`](#rowevent)s reflecting filesystem changes
300
300
  under the root. The stream never terminates on its own; stop consuming it
301
301
  to stop.
302
302
 
303
- A file written once the watcher is live produces an event and reaches the
304
- index. Rust: the watcher is live when `watch()` returns. Python: it is live
305
- once both `watch()` and `ready()` have returned, in either order; a write made
306
- while the initial scan is still running may be missed. TypeScript: the watcher
307
- starts on first iteration.
303
+ The watcher is live once both `watch()` and [`ready`](#ready) have returned,
304
+ in either order (a Rust `DirSQL` is ready when `build()` returns); a file
305
+ written after that point produces an event and reaches the index. A write
306
+ made while the initial scan is still running may be missed.
308
307
 
309
308
  An instance with no named tables cannot be watched: path-tables emit no
310
309
  watch events, so `watch()` (and the polling primitives) raise an error naming
@@ -0,0 +1,7 @@
1
+ {
2
+ "command": "uv run python -m pytest tests/e2e/on_file_query_test.py tests/e2e/query_contract_test.py tests/e2e/declared_table_name_test.py tests/e2e/fanout_test.py tests/e2e/use_case_dossier_test.py tests/e2e/use_case_join_test.py tests/e2e/use_case_notebook_test.py tests/e2e/use_case_transcripts_test.py tests/e2e/watch_speed_test.py -q -p no:cacheprovider",
3
+ "ran_at": 1793662313,
4
+ "exit_code": 0,
5
+ "commit": "900d89821767c1af609f1c1b2f21bf87c97c2332",
6
+ "branch": "bot/1562-watch-speed-1102"
7
+ }
@@ -6,7 +6,7 @@ description = "Ephemeral SQL index over a local directory"
6
6
  # version stays for the binding crates (publish = false). The literal
7
7
  # intentionally lags the published version: putitoutthere rewrites it to
8
8
  # the planned release version at build time and never commits it back.
9
- version = "0.4.124"
9
+ version = "0.4.126"
10
10
  edition.workspace = true
11
11
  # Literal `license` (not `license.workspace = true`) because
12
12
  # putitoutthere's preflight check reads `[package].license` directly
@@ -300,11 +300,10 @@ Returns a stream of [`RowEvent`](#rowevent)s reflecting filesystem changes
300
300
  under the root. The stream never terminates on its own; stop consuming it
301
301
  to stop.
302
302
 
303
- A file written once the watcher is live produces an event and reaches the
304
- index. Rust: the watcher is live when `watch()` returns. Python: it is live
305
- once both `watch()` and `ready()` have returned, in either order; a write made
306
- while the initial scan is still running may be missed. TypeScript: the watcher
307
- starts on first iteration.
303
+ The watcher is live once both `watch()` and [`ready`](#ready) have returned,
304
+ in either order (a Rust `DirSQL` is ready when `build()` returns); a file
305
+ written after that point produces an event and reaches the index. A write
306
+ made while the initial scan is still running may be missed.
308
307
 
309
308
  An instance with no named tables cannot be watched: path-tables emit no
310
309
  watch events, so `watch()` (and the polling primitives) raise an error naming
@@ -1,5 +1,6 @@
1
1
  use rusqlite::Connection;
2
2
  use rusqlite::types::{ToSql, ToSqlOutput, ValueRef};
3
+ use std::cell::RefCell;
3
4
  use std::collections::{HashMap, HashSet};
4
5
  use std::path::{Path, PathBuf};
5
6
  use std::sync::Arc;
@@ -468,8 +469,15 @@ pub struct Db {
468
469
  /// The declared functions that batch. Every statement opens a collect
469
470
  /// pass on each of them; empty, a statement runs exactly once.
470
471
  batched: Vec<Arc<Worker>>,
472
+ /// Each table's key candidates (see [`Self::row_key`]) as of a schema
473
+ /// version: reading them takes three pragma queries, and a watched
474
+ /// change would otherwise pay for them every time.
475
+ keys: RefCell<HashMap<String, (i64, KeyCandidates)>>,
471
476
  }
472
477
 
478
+ /// A table's `PRIMARY KEY` column names, then each plain `UNIQUE` index's.
479
+ type KeyCandidates = Vec<Vec<Option<String>>>;
480
+
473
481
  /// Drops every batching worker's gathered replies when the statement that
474
482
  /// gathered them is done, whichever way it left.
475
483
  struct ClearOnDrop<'a>(&'a [Arc<Worker>]);
@@ -521,6 +529,7 @@ impl Db {
521
529
  path_table_parser: None,
522
530
  calls: CallReporter::new(),
523
531
  batched: Vec::new(),
532
+ keys: RefCell::default(),
524
533
  })
525
534
  }
526
535
 
@@ -546,6 +555,7 @@ impl Db {
546
555
  path_table_parser: None,
547
556
  calls: CallReporter::new(),
548
557
  batched: Vec::new(),
558
+ keys: RefCell::default(),
549
559
  })
550
560
  }
551
561
 
@@ -657,12 +667,11 @@ impl Db {
657
667
  /// Return the column names declared in `table`'s DDL.
658
668
  pub fn get_table_columns(&self, table: &str) -> Result<Vec<String>> {
659
669
  validate_identifier(table)?;
660
- let mut stmt = self.conn.prepare(&format!(
661
- "PRAGMA table_info({})",
662
- crate::sql_literal::quote_identifier(table)
663
- ))?;
670
+ let mut stmt = self
671
+ .conn
672
+ .prepare_cached("SELECT name FROM pragma_table_info(?1) ORDER BY cid")?;
664
673
  let columns: Vec<String> = stmt
665
- .query_map([], |row| row.get::<_, String>(1))?
674
+ .query_map([table], |row| row.get::<_, String>(0))?
666
675
  .filter_map(|r| r.ok())
667
676
  .collect();
668
677
  Ok(columns)
@@ -902,20 +911,19 @@ impl Db {
902
911
  &mut stored,
903
912
  )?;
904
913
  let key = self.row_key(table, rows)?;
905
- let (changes, _) = self.reconcile_rows(table, &stored, rows, key.as_deref())?;
906
- if changes.is_empty() {
914
+ let (changes, placed) = self.reconcile_rows(table, &stored, rows, key.as_deref())?;
915
+ // An update keeps its rowid, so only a removal or an addition can move
916
+ // the owner's range.
917
+ if changes.removed.is_empty() && changes.added.is_empty() {
907
918
  return Ok(changes);
908
919
  }
909
- self.conn.execute(
910
- "DELETE FROM _dirsql_internal_ranges WHERE table_name = ?1 AND file_path = ?2",
911
- rusqlite::params![table, owner],
912
- )?;
913
- let (first, last): (Option<i64>, Option<i64>) = self.conn.query_row(
914
- &format!("SELECT min(rowid), max(rowid) FROM \"{table}\""),
915
- [],
916
- |r| Ok((r.get(0)?, r.get(1)?)),
917
- )?;
918
- if let (Some(first), Some(last)) = (first, last) {
920
+ self.conn
921
+ .prepare_cached(
922
+ "DELETE FROM _dirsql_internal_ranges WHERE table_name = ?1 AND file_path = ?2",
923
+ )?
924
+ .execute(rusqlite::params![table, owner])?;
925
+ // `placed` holds every row the table keeps.
926
+ if let (Some(&first), Some(&last)) = (placed.iter().min(), placed.iter().max()) {
919
927
  self.conn
920
928
  .prepare_cached(RANGE_INSERT)?
921
929
  .execute(rusqlite::params![table, owner, first, last])?;
@@ -1135,12 +1143,10 @@ impl Db {
1135
1143
  Ok((changes, placed))
1136
1144
  }
1137
1145
 
1138
- /// The positions in `rows.columns` of `table`'s key: its `PRIMARY KEY`,
1139
- /// else the first `UNIQUE` index whose columns `rows` emits non-NULL in
1140
- /// every row. A key the rows leave unset (a generated `INTEGER PRIMARY
1141
- /// KEY`) cannot match anything, so it is passed over.
1142
- fn row_key(&self, table: &str, rows: &ShapedRows) -> Result<Option<Vec<usize>>> {
1143
- let mut candidates: Vec<Vec<Option<String>>> = vec![
1146
+ /// `table`'s `PRIMARY KEY` column names, then each plain `UNIQUE`
1147
+ /// index's, as the schema declares them now.
1148
+ fn key_candidates(&self, table: &str) -> Result<KeyCandidates> {
1149
+ let mut candidates: KeyCandidates = vec![
1144
1150
  self.conn
1145
1151
  .prepare_cached("SELECT name FROM pragma_table_info(?1) WHERE pk > 0 ORDER BY pk")?
1146
1152
  .query_map([table], |r| r.get(0))?
@@ -1164,6 +1170,34 @@ impl Db {
1164
1170
  .collect::<rusqlite::Result<_>>()?,
1165
1171
  );
1166
1172
  }
1173
+ Ok(candidates)
1174
+ }
1175
+
1176
+ /// The positions in `rows.columns` of `table`'s key: its `PRIMARY KEY`,
1177
+ /// else the first `UNIQUE` index whose columns `rows` emits non-NULL in
1178
+ /// every row. A key the rows leave unset (a generated `INTEGER PRIMARY
1179
+ /// KEY`) cannot match anything, so it is passed over.
1180
+ fn row_key(&self, table: &str, rows: &ShapedRows) -> Result<Option<Vec<usize>>> {
1181
+ let version: i64 = self
1182
+ .conn
1183
+ .prepare_cached("PRAGMA schema_version")?
1184
+ .query_row([], |r| r.get(0))?;
1185
+ let cached = self
1186
+ .keys
1187
+ .borrow()
1188
+ .get(table)
1189
+ .filter(|(at, _)| *at == version)
1190
+ .map(|(_, candidates)| candidates.clone());
1191
+ let candidates = match cached {
1192
+ Some(candidates) => candidates,
1193
+ None => {
1194
+ let candidates = self.key_candidates(table)?;
1195
+ self.keys
1196
+ .borrow_mut()
1197
+ .insert(table.to_string(), (version, candidates.clone()));
1198
+ candidates
1199
+ }
1200
+ };
1167
1201
  Ok(candidates.into_iter().find_map(|names| {
1168
1202
  let at = names
1169
1203
  .iter()
@@ -4176,6 +4210,73 @@ mod tests {
4176
4210
  assert_eq!(changes.added.len(), 1, "got: {:?}", changes.added);
4177
4211
  }
4178
4212
 
4213
+ #[test]
4214
+ fn reconcile_batch_rows_writes_only_the_update_when_rows_change_in_place() {
4215
+ let db = experiments_db();
4216
+ let next = shaped(
4217
+ &db,
4218
+ "experiments",
4219
+ serde_json::json!([
4220
+ {"folder_name":"a","name":"Alpha"},
4221
+ {"folder_name":"b","name":"Renamed"}
4222
+ ]),
4223
+ );
4224
+ let before = db.conn().total_changes();
4225
+
4226
+ db.reconcile_batch_rows("experiments", "", &next).unwrap();
4227
+
4228
+ assert_eq!(db.conn().total_changes() - before, 1);
4229
+ assert_eq!(range_rows(&db, "experiments"), vec![(String::new(), 1, 2)]);
4230
+ }
4231
+
4232
+ #[test]
4233
+ fn reconcile_batch_rows_keys_by_an_index_created_after_an_earlier_reconcile() {
4234
+ let changes = |db: &Db, v: &str| {
4235
+ let next = shaped(db, "t", serde_json::json!([{"k":"a","v":v}]));
4236
+ db.reconcile_batch_rows("t", "", &next).unwrap()
4237
+ };
4238
+ let db = Db::new().unwrap();
4239
+ db.create_table("t", "CREATE TABLE t (k TEXT, v TEXT)")
4240
+ .unwrap();
4241
+ db.insert_rows(
4242
+ "t",
4243
+ &shaped(&db, "t", serde_json::json!([{"k":"a","v":"0"}])),
4244
+ "",
4245
+ )
4246
+ .unwrap();
4247
+ assert!(!changes(&db, "1").keyed);
4248
+
4249
+ db.conn()
4250
+ .execute_batch("CREATE UNIQUE INDEX t_k ON t(k)")
4251
+ .unwrap();
4252
+
4253
+ assert!(changes(&db, "2").keyed);
4254
+ }
4255
+
4256
+ #[test]
4257
+ fn reconcile_batch_rows_reuses_the_key_read_at_the_same_schema_version() {
4258
+ let db = experiments_db();
4259
+ let version: i64 = db
4260
+ .conn()
4261
+ .query_row("PRAGMA schema_version", [], |r| r.get(0))
4262
+ .unwrap();
4263
+ db.keys
4264
+ .borrow_mut()
4265
+ .insert("experiments".into(), (version, Vec::new()));
4266
+ let next = shaped(
4267
+ &db,
4268
+ "experiments",
4269
+ serde_json::json!([
4270
+ {"folder_name":"a","name":"Alpha"},
4271
+ {"folder_name":"b","name":"Renamed"}
4272
+ ]),
4273
+ );
4274
+
4275
+ let changes = db.reconcile_batch_rows("experiments", "", &next).unwrap();
4276
+
4277
+ assert!(!changes.keyed);
4278
+ }
4279
+
4179
4280
  #[test]
4180
4281
  fn reconcile_batch_rows_writes_nothing_for_an_unchanged_keyed_table() {
4181
4282
  let db = experiments_db();
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes