Repository navigation
Give the bindings one local URL and one default database - #640
Merged
wudidapaopao merged 2 commits intoSep 11, 2026
Merged
wudidapaopao merged 2 commits into
wudidapaopao merged 2 commits into
Conversation
Cross-binding recovery testing turned up two places where the same durable object needed different code depending on which language opened it, and neither difference was anything the contract asked for. The local backend answered only to `local:`, while chdb-node answered only to `file:` and chdb-go took either. A namespace URL is the sort of thing that gets shared between a Python job and a Node service, so it now takes both here too (chdb-node takes both as of its own change). A `file:` URL is percent-encoded and a `local:` path is not, which is the only difference between them. A cold object was created in a database called `mem` here and `default` in Node and Go. The head is authoritative once an object exists, so this never broke interop -- but the same application ported between bindings addressed a differently-named table, which is worse than a name nobody likes. `default` wins because two of three bindings already had it and it is what an unqualified statement means in chDB anyway. The contract now states it, so there is one answer rather than three implementations. The engine-compatibility refusal also stopped telling people to run `pip install -U chdb-core`. Not every chdb-core release goes to PyPI -- the wheels are large and the quota only moves one way -- so the newest one there can be older than the release that has the ABI, and following that hint left you exactly where you started. It now reports the engine version actually loaded, which separates "no engine with the ABI" from "the wrapper is not loading the engine you installed", and gives the install form that works: the release wheel and chdb in one pip command, so chdb's own chdb/__init__.py lands on top of the engine's. Two tests changed rather than being added to. `test_control_statements_refused` and `test_reopen_honors_persisted_db` both relied on the default being `mem`, and with the default moved to `default` the first one's `USE default` would have been a no-op and the second would have had nothing to disagree with. Both now name `mem` explicitly, which is what they were really testing. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The refusal named the ABI it needed and nothing else, so the two ways it fires read identically: an engine too old to have the ABI, and a new engine that the wrapper is not loading because something else owns `chdb/`. It now reports the version actually loaded, which separates them in one line. `pip install -U chdb-core` is the fix, and naming chdb-core rather than chdb is the point of it. pip's default upgrade strategy leaves a dependency alone once it is satisfied, and an installed 26.7.0 satisfies chdb's floor, so upgrading chdb reports success and moves no engine at all. That command only became true with 26.7.3: it is the first release carrying the ABI that is published to PyPI, and before it the newest chdb-core there was 26.7.0. The durable docs gained an installation section saying the same thing, including why a fresh install and an existing one need different commands. Checked from where a user actually is: chdb on PyPI's chdb-core 26.7.0 refuses with this message naming 26.7.0. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Contributor
Author
|
@wudidapaopao please review this PR |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Two things the same durable object needed different code for depending on which language opened it, and neither difference was anything the contract asked for.
One URL. The local backend answered only to
local:, chdb-node only tofile:, chdb-go to either — so no single namespace URL could be handed to all three. It now takes both here (chdb-node takes both as of chdb-io/chdb-node#94). Afile:URL is percent-encoded and alocal:path is not; that is the only difference between them.One default database. A cold object was created in
memhere anddefaultin Node and Go. The head is authoritative once an object exists, so this never broke interop — but the same application ported between bindings addressed a differently-named table.defaultwins because two of three bindings already had it and it is what an unqualified statement means in chDB anyway. The contract now states it, so there is one answer rather than three implementations.The refusal says which engine is loaded. It named the ABI it needed and nothing else, so its two causes read identically: an engine too old to have the ABI, and a new engine that the wrapper is not loading because something else owns
chdb/. And the command it printed only became true with chdb-core 26.7.3 — the first release carrying the ABI that is published to PyPI. It nameschdb-corerather thanchdbbecause pip leaves a satisfied dependency alone, so upgradingchdbreports success and moves no engine.Verified
Cross-binding recovery, contract §7.5 — the item no repository had implemented. Every writer produces a 100-row checkpointed base plus a 50-row WAL tail that is flushed and not checkpointed, so a reader has to restore the base and replay the WAL. 3×3, on the local backend and again on real AWS S3, every cell 150 rows /
sum(id)11175 /base100 +wal50, each reader taking the database name fromhead.json:After this change all three take the same URL string and the same database name.
Also:
tests/test_durable.py50 passed against chdb-core 26.7.2-rc.2, and the whole suite again against real AWS S3 (DAO_TEST_URL=s3://…, 49 passed in 7 minutes). The refusal message was checked from where a user actually is —chdbon PyPI's newest chdb-core, 26.7.0 — and it names 26.7.0.Two tests changed rather than being added to
test_control_statements_refusedandtest_reopen_honors_persisted_dbboth relied on the default beingmem. With the default moved, the first one'sUSE defaultwould have been a no-op instead of a refusal, and the second would have had nothing to disagree with. Both now namememexplicitly, which is what they were really testing.Follow-ups, once 26.7.3 is on PyPI
chdb-core>=26.7.3to thedurableextra, sopip install "chdb[durable]"resolves an ABI-carrying engine deterministicallyCHDB_CORE_ABI_WHEELpin from the durable conformance step in the four wheel workflows; it exists only because no chdb-core on PyPI exported the ABI🤖 Generated with Claude Code
Note
Standardize durable bindings on
defaultdatabase and addfile:URL support tomake_backendDEFAULT_DATABASEconstant (valuedefault) in protocol.py and switchesDurableObject,Namespace, and contract docs from the oldmemdefault to it. Persisted head data remains authoritative on reopen.make_backendin backends/init.py to routefile:URLs into the local filesystem backend, percent-decoding the path before resolution;local:and bare paths stay literal.ManagedConnection, the missing required attributes.chdb-coreto 26.7.2-rc.2.dbnow land indefaultinstead ofmem; existing tests that relied on the implicitmemdefault are updated to pass it explicitly.Macroscope summarized 0dad0fc.