Repository navigation
Native lookup_by_key raises without an index, as the JVM build does - #96
Merged
Merged
Conversation
Database.lookup_by_key on the native build ran a SELECT ... WHERE, which scans the type when no index serves it, so the same call returned a record on the arcadedb wheel and raised on the arcadedb-jvm wheel (the engine's lookupByKey needs an index and throws IllegalArgumentException). The native build now checks schema:indexes first, with the engine's rule: an LSM_TREE or HASH index on exactly the given properties, in the index's order, on the type or a supertype. Otherwise it raises ArcadeDBError with the engine's message (No index has been created on type ... properties [...], or No key index ... for a FULL_TEXT index). An unknown type still raises the not-found error of the SELECT. The docstring of the JVM method now states the contract. tests/test_lookup_by_key_index.py runs on both backends. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
tae898
marked this pull request as draft
October 26, 2026 12:04
The first version checked schema:indexes before the SELECT, one more query on a hot point-lookup path. The native glue now has an entry point, arcadedb_n_lookup, that calls Database.lookupByKey(type, keys, values) in the image and replies with the first hit as the rows of a statement reply, so Python reads it as it reads a SELECT. The engine's IllegalArgumentException (no LSM_TREE or HASH index on exactly those properties of the type or a supertype) and SchemaException (unknown type) are the error reply, and become the ArcadeDBError that the JVM build raises. No statement has that raise-on-unindexed rule, so this is the case where a Java call is wrapped. _require_key_index and its two schema queries are gone. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
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.
Database.lookup_by_keyon an unindexed key scanned the type on the native wheel (arcadedb) and raised on the JVM wheel (arcadedb-jvm). Measured on the CI wheels of main 662851c (26.11.1.dev0), same script, same database.Before, per backend (type
Dwith an integerk, no index; then an index onk; a composite index on(a, b); a FULL_TEXT index ont):["k"], no index, hitNo index has been created on type 'D' properties [k]["k"], no index, miss["k"], UNIQUE index, hit / miss["a"]and["b", "a"]on index(a, b)["t"]on a FULL_TEXT indexNo key index has been created ... FULL_TEXTwas not foundwas not foundThe contract is the JVM one, because that is the engine:
LocalDatabase.lookupByKeythrowsIllegalArgumentExceptionunless the type or a supertype has a ready LSM_TREE or HASH index on exactly that property list (getPolymorphicIndexByProperties,isExactKeyLookup). The docstring already says the keys "must be indexed" and the user docs do not mention the method, so no document promises a scan.The fix: the native
lookup_by_keyno longer runs aSELECT ... WHERE. A new entry point of the native library,arcadedb_n_lookupinNativeExtras.java, calls the engine's ownDatabase.lookupByKey(type, keys, values)inside the image and replies with the first hit (none or one row) in the shape of a statement reply, so Python reads it with the reader of aSELECTand wraps it as a Document, Vertex or Edge. The engine's exceptions become the error reply and so the sameArcadeDBErrortext as on the JVM build, with no extra query on the hot path (one crossing, as before). This is the case where the bindings wrap a Java call instead of a statement: no SQL or Cypher statement raises when no index serves the keys. The docstring of the JVM method gains a Raises section and the exact-index rule.vector.pyalready catchesArcadeDBErrorfrom this call and falls back to a query, sofind_nearestby key behaves as before.Tests:
tests/test_lookup_by_key_index.py(15 tests) is shared, no conftest entry. Unindexed hit and miss raise, UNIQUE/NOTUNIQUE/UNIQUE_HASH/NOTUNIQUE_HASH work once created, a dropped index raises again, an index on another property does not serve, a composite index serves exactly its list (prefix and reordered raise), FULL_TEXT raises, an index on a supertype serves subtypes two levels down but a subtype index does not serve the supertype, vertex and edge types follow the same rule, an unknown type names the type. On the CI wheels of main, 14 of the 15 fail on the native wheel and all 15 pass on the JVM wheel (the 15th is the one that already holds). With this change: JVM 15 of 15 (local, thecore.pydocstring is the only change there). Native: not run yet at the time of writing.Test nativein CI builds the image from this commit, but it skips a draft PR, so it starts when the PR is marked ready for review. A local image build from this commit (native/scripts/build-image.shthroughquiet_build.sh, then the new tests and the existing lookup tests on the native backend) is queued; its result will be added here. The Java compiles (GraalVM CE 25.4.4.1.1,mvn -o compileinnative/).Separate observation, not part of this change: on the native wheel
SELECT FROM schema:indexesreportstypeNameDfor the bucket index of a subtypeSubofD(Sub_0_...), where the JVM wheel reportsSub. Same engine rows, differenttypeName; worth its own look.black and isort are clean,
scripts/check_no_embedded_name.py --root .passes.🤖 Generated with Claude Code