Repository navigation
COLUMNAR index on both builds: reflection metadata, reopen and the columnar settings (closes #292) - #300
Merged
Conversation
…#292) Why no change to reachability-metadata.json: I read every class of the engine's index/columnar and query/facet packages (26.12.1 snapshot, ArcadeData/arcadedb main 4a91847) for reflection, ServiceLoader, resources and Class.forName. There is none: the projection is plain JDK (FileChannel, VarHandle byte-array views, java.util.concurrent pools and a daemon ticker thread), the index handler is registered by instance in LocalSchema, facet.searchValues by instance in DefaultSQLFunctionFactory, and the only parser nodes the COLUMNAR and FACETS statements add are FacetsClause, FacetItem and FacetRangeItem, which PR #299 already listed. Upstream's own reachability-metadata.json lists no columnar class either. The entries upstream has and ours lacks (SQLFunctionEnsureLabelTypes, antlr StatementExpression and SubqueryExpression, three Ratis gRPC classes) are not columnar and are left for a change of their own. Why a child process for the unclean close: DatabaseInternal.kill(), which the engine's ColumnarCrashRecoveryTest uses, is not reachable from the native package, and a JVM-only hook would not test both. A writer that ends with os._exit after its commits leaves database.lck behind and the commits in the write-ahead log, which is the state the engine's recovery reads (a crash of the process, not a power loss). Two variants: commits unflushed, and commits flushed to published segments before the rest is written. Why no new setter for arcadedb.columnar.*: ALTER DATABASE already takes the DATABASE-scope keys (immediately, stored with the database) and refuses the JVM and SERVER ones; those are system properties through ARCADEDB_JVM_ARGS or ARCADEDB_NATIVE_ISOLATE_ARGS, as for arcadedb.fileSync. The test pins that, and that GROUP BY returns the same rows with the acceleration on and off (PROFILE names the path). tests/test_columnar_index.py is version-gated like the smoke test (an older engine must refuse the index and the keys with its own error), runs on both packages with the public API, and polls states with deadlines. Nothing was run locally (the laptop guard blocks workloads); CI is the first run. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
… list_vector_indexes() on arcadedb-jvm (refs #292) The first CI run of tests/test_columnar_index.py failed on arcadedb-jvm only: Database.get_database_path() returned the raw java.lang.String of getDatabasePath(), which os.path.join refuses (TypeError: expected str, bytes or os.PathLike object, not String). The native build returns a str, so the lanes disagreed. Same family as #286 (get_type_name, fixed in #287): the binding wraps the Java getter in str(). Sweep of src/arcadedb/*.py for a method that documents a str and returns a Java getter result unconverted (an AST pass over every def annotated with str or Path, looking at what each return expression is): Database.get_name(), Database.get_database_path() and Schema.list_vector_indexes() (a list of java.lang.String). Fixed with str(). Left alone because they are documented as returning Java objects: Document.get_identity(), Schema.get_type(), get_types(), get_index_by_name(), Document.get_raw(), Result.get_raw(). Result.get_rid(), Document.get_rid(), get_type_name() and the vector index names already convert. tests/test_str_returns.py asserts type(x) is str on both packages for the four str returns that can be read through the public API (name, path, vector index names, Result.get_rid), plus that the path joins. Nothing was run locally; CI is the first run. 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.
Closes #292. Part of #289.
I added
tests/test_columnar_index.py, which runs on both packages with the public API only, and a short docs page,how-to/columnar-index.adoc. I did not change the Java bridge, the native library orreachability-metadata.json, and the reasons for each of the four points of the issue are below.Create and drop from Python, and the native build. The tests run
CREATE INDEX ON Item (category) COLUMNAR, the same on a numeric property and(tags BY ITEM)on aLIST OF STRING, check the index inschema:indexes(Item[category]_columnar, plus one row per bucket), ingest in several commits, update and delete, queryFACETSandGROUP BY, and compare both with what Python counts over the rows it inserted. AfterDROP INDEXthe facets come from a scan andGROUP BYruns its normal plan. A test creates the index on records that are already there, so the maintenance pool rebuilds the projection, and one setsflushIntervalandapplyIntervallow andmergeMaxSegmentsto 2, streams small commits and polls the manifests undercolumnar/b*/manifest.jsonuntil every row is in a published segment. On the native build that is the apply, flush, merge and maintenance threads running inside the shared library. For the reflection metadata I read every class ofindex/columnarandquery/facetin the engine (main at4a91847) for reflection,ServiceLoader, resources andClass.forName, and found none: the projection is plain JDK, the index handler andfacet.searchValuesare registered by instance, and the only parser nodes the statements add areFacetsClause,FacetItemandFacetRangeItem, which #299 already listed. Upstream'sreachability-metadata.jsonlists no columnar class either. The entries upstream has and ours lacks (SQLFunctionEnsureLabelTypes, the antlrStatementExpressionandSubqueryExpression, three Ratis gRPC classes) are not columnar, so I left them for a change of their own. The dispatched native run is what proves this, not the audit.Close and reopen. A clean close and reopen keeps the facets exact: from the projection, or from a scan while the engine rebuilds it, and the test then waits (with a deadline) for the projection to serve them again with nobody asking. For the unclean close,
DatabaseInternal.kill()(what the engine'sColumnarCrashRecoveryTestuses) is not reachable from the native package and a JVM-only hook would not test both, so the writer is a child process that ends withos._exitafter its commits. That leavesdatabase.lckbehind (the test asserts it) and the commits in the write-ahead log, which is the state the engine's recovery reads. Two variants: all commits unflushed, and the first batch already in published segments before the second is written. This is a crash of the process, not a power loss, and Python cannot produce the engine's kill points (a kill in the middle of a flush or a merge). Those stay covered by the engine's own tests.Settings. I added no setter.
ALTER DATABASEalready takes theDATABASE-scope keys (groupByAcceleration,flushInterval,mergeDeadRatioand the rest of the list inGlobalConfiguration), takes effect at once and is stored with the database. It refuses theJVMandSERVERones withcannot be set per database, and those are system properties (ARCADEDB_JVM_ARGS,jvm_kwargs,ARCADEDB_NATIVE_ISOLATE_ARGS), as forarcadedb.fileSync. The docs page says so. The tests pin the listing inschema:database, the refusals, the values after a reopen, and thatGROUP BYreturns the same rows witharcadedb.columnar.groupByAccelerationon and off.PROFILEshowspath: columnarorpath: normal (reason: disabled by arcadedb.columnar.groupByAcceleration), so the test also proves which path ran. No test sets a system property, and the page says that.Tests and lanes. Like the smoke test, the file reads
SELECT version(): an engine older than 26.12.1 must refuseCREATE INDEX ... COLUMNARwithIndex type 'COLUMNAR' is not supportedandALTER DATABASEof the new keys withnot found, and a newer one must run everything. The JVM lane takes its jars from thelatestimage and runs the real tests on this pull request. The native pull request gate links 26.11.1, so it only runs the refusal branches. The real native run is the dispatched proof withengine=26.12.1-SNAPSHOT.Binding fix found by the first CI run.
Database.get_database_path()returned a rawjava.lang.Stringonarcadedb-jvm, whichos.path.joinrefuses, while the native build returned astr(the family of #286 and #287). I wrapped it instr()and did the same forDatabase.get_name()andSchema.list_vector_indexes(), the only methods I found that document astrand return a Java getter result unconverted (an AST pass over everystr-annotated method insrc/arcadedb). I leftDocument.get_identity(),Schema.get_type(),get_types(),get_index_by_name()and the twoget_raw()methods alone, because they are documented as returning Java objects.tests/test_str_returns.pyassertstype(x) is stron both packages.Not verified. Nothing ran locally (the laptop queue guard blocks workloads), so CI is the first run of the test file. I could not check on all four platforms that the threads behave the same in the native image, only what the dispatched run on Linux x86-64 shows. I wrote the
PROFILEpath strings, theschema:indexesnames and the facetsourcevalues from the engine source on main, not from a run.🤖 Generated with Claude Code