Repository navigation
Conversation
…ent text (N-09) lookup_by_rid, Vertex.get_out_edges/get_in_edges/get_both_edges, new_edge, Edge.get_in/get_out, save and delete pasted the record id into the SQL text. The engine keeps parsed statements in a cache keyed by statement text (default 300 entries) and leaves a record id in a FROM target in the text, so each record was a new text to parse and a new cache entry. The id now goes as a RID parameter (the "R" tag the library already decodes), so one operation has one text. Results and error messages are unchanged. Tests: behaviour tests in test_graph_api.py run on both backends; test_native_statement_texts.py (native only) counts the statement texts for 25 records. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This was referenced Oct 25, 2026
Author
|
Closing here: the bindings moved to ArcadeData/arcadedb-python. This change has no counterpart there yet and no queued A/B. If it is wanted, it goes there as its own PR: it is now a line in the tracking issue ArcadeData/arcadedb-python#19. The branch stays. |
tae898
added a commit
to ArcadeData/arcadedb-python
that referenced
this pull request
Nov 3, 2026
…ent text (#202) * Native: record ids go to the engine as a parameter, not in the statement text Port of humemai/arcadedb-embedded-python#529 (branch perf/native-rid-param, never merged there) onto current main. On the native build a record id was pasted into the SQL text, so each traversal step and each lookup_by_rid was a new statement text. The engine caches a parsed statement by its text (arcadedb.sqlStatementCache, 300 entries) and its literal parameterizer keeps a literal in a FROM target, so 25 records meant 25 cache entries. The id now goes over as a parameter (the RID the codec already tags as R): lookup_by_rid (SELECT FROM ?), Vertex.get_out_edges/get_in_edges/get_both_edges, Vertex.new_edge, Edge.get_in/get_out, save() (UPDATE :rid MERGE :row) and delete() (DELETE FROM :rid). Id validation and error messages are unchanged. test_native_statement_texts.py counts the distinct statement texts (native only, not collected on JPype); the new behaviour tests in test_graph_api.py run on both builds. Untimed counts only: a timed A/B decides it before merge. Refs #19 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Native: keep lookup_by_rid's literal id; the parameter path measured 2 % slower there First timed A/B (ab.py, laptop, native wheel of main vs this PR, 12 clean pairs): lookup_rid_us 1.022 [1.019, 1.025] (slower), out_edges_us 0.792 [0.790, 0.794], edge_ends_us 0.792 [0.789, 0.794], save_us 0.805 [0.801, 0.809] (faster). Guards flat, A/A clean. Narrow the PR to the paths that got faster; lookup_by_rid returns to main's text. database.py is now identical to main. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 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.
Row N-09 of the bindings backlog: on the native wheel, a record id was pasted into the SQL text, so each traversal step and each
lookup_by_ridwas a new statement text. The id now goes over as a parameter (theRIDthe codec already tags asR).Statement cache finding: the claim holds. The engine's parsed-statement cache is
StatementCacheoverSQLLiteralParameterizer/LiteralParameterizer, aSegmentedLRUCache<String, Lookup>keyed by the statement text (LiteralParameterizer.java:65,:134), sized byarcadedb.sqlStatementCache, default 300 (GlobalConfiguration.java:765). The literal extraction that lets texts share an entry only takes integer, floating point and non-empty string tokens (SQLLiteralParameterizer.java:112,isCandidate) and keeps every literal in a FROM target (class comment andclassify), soSELECT FROM #1:0andSELECT FROM #1:1are two entries. The native image reaches the same path:ArcadeNative.java:258-262callsdb.queryanddb.command, which end inSQLQueryEngine.parseParameterized(SQLQueryEngine.java:285). Checked on ArcadeData/arcadedb main at 26f0bf8. So 25 records meant 25 texts, and a loop over more than 300 records evicts the statements the application re-runs.What changed (Python only, no image rebuild):
NativeDatabase.lookup_by_rid(SELECT FROM ?), and inrecords.pytheVertex.get_out_edges/get_in_edges/get_both_edges,Vertex.new_edge,Edge.get_in/get_out,save()(UPDATE :rid MERGE :row) anddelete()(DELETE FROM :rid). The id validation and the error messages are unchanged, and a text without the leading#is still accepted as before. Docs: the Parameters section ofguide/core/queries.mdandlookup_by_ridinapi/database.md.Untimed counts (
test_native_statement_texts.py, 25 records):lookup_by_ridgave 25 distinct texts before and gives 1 after (the test failed on exactly this before the change);get_out_edges("Knows"),get_in_edges()andget_both_edges()over the 24 linked vertices are 72 calls and now 3 texts,Edge.get_in/get_outover 24 edges are 48 calls and now 2 texts,save()anddelete()are one text each, andnew_edgeis two texts (with and withoutCONTENT) per label instead of one per pair of records. Before the change every one of these carried the record id in its text (the second test failed onCREATE EDGELikesFROM #1:0 TO #1:1). No timing was run.Local checks, all against the image of
native-lib/nnext(the engine of the current native-preview) withARCADEDB_BACKEND=native: the two new tests fail before the change and pass after;test_native_statement_texts.py,test_graph_api.py,test_graph.py,test_core.py,test_resultset.py,test_graph_batch.py,test_schema.py,test_cypher.py,test_parameter_binding.py,test_restore_sql.py: 228 passed, 26 skipped (the NOTYET skips), 0 failed. The new behaviour tests intest_graph_api.py(traversal over a 12-vertex chain, save and delete by id,new_edgewith and without properties, the refusals oflookup_by_rid) pass on the JPype wheel too:test_graph.py,test_core.py,test_graph_api.py, 64 passed. Pre-commit (black, isort) ran and its changes are in the commit.Overlap with the open native PRs, checked with
git merge-treeagainst each head: independent of #520, #521, #523, #525 (which also editsrecords.py,database.pyandcodec.pybut in other hunks) and #526. Two adjacent-line conflicts, no semantic overlap: #514 in the import block of_native/database.py(it addsfrom .bulk import insert_rows_columnarnext to myfrom .codec import RID) and #522 intests/conftest.py(both add acollect_ignore.appendline at the same place). Whichever merges second needs a trivial resolution; I did not stack on any of them.🤖 Generated with Claude Code