fix(engine) #5637: persist the partition strategy, and report the index change that undoes it - #5644
Conversation
|
Tick the box to add this pull request to the merge queue (same as
|
…ex change that undoes it Two loose ends of the partitioned-strategy series (#5589, #5595, #5603), both about what happens to a type after it has been configured. 1. `ALTER TYPE ... BucketSelectionStrategy` never persisted. The strategy was set in memory and nothing wrote it out, so a type partitioned by that DDL alone reopened as round-robin unless a later, unrelated schema mutation happened to flush the configuration. It is the one schema mutator that left the write to somebody else; the flag ABOUT the partitioning (needsRepartition) saved itself while the partitioning did not. It now calls schema.saveConfiguration(), skipped while the schema is being read back so a partitioned database does not rewrite an identical schema.json on every open. 2. An index created on an already-partitioned type could undo the suitability #5603 checks at assignment time - recollating the partition index COLLATE CI makes it unprunable, an index on other properties adds a lookup that fans out - and nothing said so until the next restart. TypeIndexBuilder.create() re-runs the same diagnosis, once per CREATE INDEX rather than once per bucket, and never refuses: the index is what the user asked for and it is useful, so the partitioning is what gives way. Persisting the strategy made a third, pre-existing fault reachable. Binding it demanded the unique automatic index on the partition properties, on every rebind including the schema loader's, so a DROP INDEX on the partition key made the next open throw from inside the loader - aborting the remaining strategies, the triggers, the function libraries, the extensions and the compaction file-migration map, reported only as "The schema will be reset". Binding no longer validates: the requirement moved into checkSuitability(), refused at assignment exactly as before and warned about on load, so the type keeps its partitioned placement. LocalSchema also isolates a per-type strategy failure now, so any other unusable strategy costs that type its pruning instead of the rest of the schema. Suitability.canPrune() is renamed isUsable(), since a missing partition index does not stop the strategy computing a bucket - it removes the lookup that would have been pruned. New PartitionedStrategyLifecycleTest (9 tests, 4 red before the fix and the two load-path guards individually mutation-checked); the explicit saveConfiguration() workaround in PartitionedStrategySuitabilityTest comes out.
Up to standards ✅🟢 Issues
|
| Metric | Results |
|---|---|
| Complexity | 7 |
🟢 Coverage 94.74% diff coverage · -6.21% coverage variation
Metric Results Coverage variation ✅ -6.21% coverage variation Diff coverage ✅ 94.74% diff coverage Coverage variation details
Coverable lines Covered lines Coverage Common ancestor commit (7081057) 149675 112546 75.19% Head commit (2550afe) 174679 (+25004) 120508 (+7962) 68.99% (-6.21%) Coverage variation is the difference between the coverage for the head and common ancestor commits of the pull request branch:
<coverage of head commit> - <coverage of common ancestor commit>Diff coverage details
Coverable lines Covered lines Diff coverage Pull request (#5644) 38 36 94.74% Diff coverage is the percentage of lines that are covered by tests out of the coverable lines that the pull request added or modified:
<covered lines added or modified>/<coverable lines added or modified> * 100%
NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.
2f71d3d to
bca4a40
Compare
Review: #5644 - persist the partition strategy, and report the index change that undoes itThorough, well-reasoned change. I traced all five source hunks against Correctness (verified, looks right)
Minor: redundant re-reporting on unrelated
|
- Document why SCHEMA_CHANGE reports the whole current picture rather than the delta caused by the new index. Attributing each finding to an index would mean matching on message text or teaching checkSuitability() to attribute, and would report a blocked state as partly acceptable; the line count is bounded by the indexes on the type and CREATE INDEX is rare. - Document why the new saveConfiguration() is deliberately NOT guarded on "the strategy actually changed", unlike several sibling mutators. saveConfiguration() reports an IOException by logging SEVERE and returning, so memory and schema.json can diverge, and re-issuing the same ALTER TYPE is the operator's repair for exactly that. A skip-if-unchanged guard reads the in-memory value and turns the repair into a silent no-op. - Extract the log-capture helper this PR had duplicated across the two partitioning test classes into WarningCapture, and record there that the logger swap is process-global and so assumes the sequential execution the engine suite uses. - Drop an HTML <p> that had been copied into a non-Javadoc // comment in TypeIndexBuilder.
`**/src/test/*` does not cross a directory separator, so it only ever matched the direct children of src/test (the `java` directory itself) and never a source file. Test code was therefore excluded only when its name happened to end in Test.java or IT.java, which is why the new WarningCapture test-support class in #5644 was analysed as production code and reported a complexity issue. Widened to `**/src/test/**`, which is what the entry was clearly meant to say; the *Test.java / *IT.java entries stay for anything outside src/test.
Review of PR #5644 — persist the partition strategy, and report the index change that undoes itOverall this is a high-quality, carefully reasoned fix. The three faults (strategy not persisted, later I verified the key claims against the source rather than the description:
A few minor, non-blocking observations: 1. Redundant 2. The explicit save now also fires on the inheritance path. 3. Coverage gap: inheriting a partitioned strategy. Removing the throw from 4. Transaction/rollback of Nice touches: extracting No blocking concerns. The minor points above are optional polish. |
Review: persist the partition strategy, and report the index change that undoes itThorough, well-reasoned change. I traced the four moving parts ( Strengths
Minor points / questions
Nothing blocking. The reasoning in the inline comments is unusually complete and made this easy to verify. Nice work. |
- Skip the explicit saveConfiguration() when the needsRepartition flip in the same call already wrote schema.json. setNeedsRepartition now answers whether it transitioned (and therefore saved); the strategy field is assigned before it runs, so that write already carries the strategy. Distinct from the operator-repair case the comment defends, which stays unguarded. - Cover the inheritance path, which reaches the assignment-time refusal without any ALTER TYPE now that binding no longer validates: a subtype inheriting a partitioned parent keeps a suitable, pruning, separately persisted strategy, and dropping a partitioned type from the middle of a hierarchy re-attaches the leaf to the grandparent with the strategy intact (the one caller that passes createIndexes = false). The subtype in the first test declares its parent's bucket count on purpose: a partitioned type whose subtype has a different one crashes on the first indexed insert, because TypeIndex.getIndexesByKeys applies the bucket index derived from the parent's modulus to each subtype's own bucket list. That line predates the partitioned-strategy series and nothing here touches it, so it is recorded in the test and reported separately.
…ucket-count crash (#5645)
- The setter no longer persists on its own when an enclosing recordFileChanges block is going to save anyway. Only the supertype-inheritance path is in that position, and it now says so at the call site; every caller that is the whole operation still persists, which is the point of the issue. - The loader's fault-isolating catch has to stay broad to give the guarantee it exists for, so the LEVEL now carries what the catch cannot: a SchemaException or IllegalArgumentException is the strategy declining to be restored - a property of that database - and stays a WARNING, while anything else is a fault in the bind path and is reported at SEVERE. Otherwise a real regression here would be indistinguishable from an expected refusal in the log of a database that opens successfully. WarningCapture gained a SEVERE-only variant so the split is asserted rather than assumed; mutation-checked by making the catch unconditionally SEVERE, which reddens the test.
|
Review: PR #5644 - persist partition strategy & report index changes Solid, well-scoped fix. I traced each of the three sub-changes through the schema mutation, reload, and index-creation paths. Overall this is high quality: the diagnosis is centralized in A few observations, mostly minor. 1. Diagnostic outside the try can fail a successfully-created index (minor robustness). 2. Broad catch(Exception) in the loader (intentional, worth a note). 3. Unconditional saveConfiguration() now also persists non-partitioned strategies. The new 4. alreadySaved optimization - verified correct. The Nits. Nothing here is blocking. Item 1 is the only one I would suggest acting on before merge; the rest are notes. Nice work - the test coverage in particular is a model for this kind of lifecycle fix. |
|
Review of #5644 - persist the partition strategy, and report the index change that undoes it Thorough, well-scoped fix with excellent inline documentation and strong test coverage. The design decisions (moving validation out of the binding path, the three-way PartitionReport reaction split, and per-type fault isolation on load) are sound and address a real correctness gap: a correctly-partitioned type silently coming back round-robin after a restart. Nice work. I verified the change against the surrounding code rather than just the diff. What holds up well
Minor observations (non-blocking)
Not verified I could not run mvn verify in the review sandbox (permission-gated), so I am relying on the stated "engine suite green (10545 tests) + PartitionedStrategyRefusalHttpTest" for the dynamic result. Everything checks out statically. Overall: clean, careful, and the reasoning in the comments is unusually good. LGTM pending CI. |
- Complete the reason the SCHEMA_CHANGE diagnosis sits outside TypeIndexBuilder's try/catch. Keeping it out of the cleanup arm stopped it undoing a good index, but anything unexpected escaping it still failed the command over an index that was already built, committed and registered - and the obvious retry then failed again with "already exists". It now logs and returns the index. - Report the loader's isolated strategy failure by toString() when the exception carries no message. The catch is broad enough to reach failures that have none, an NPE above all, and "...: null" names neither what went wrong nor where on the one line an operator reads. - Release notes: say that the fix is on the mutator rather than on `partitioned`, so `thread` stops being lost across a restart on the same terms, and that round-robin is still deliberately absent from schema.json.
Review: #5644 - persist the partition strategy, and report the index change that undoes itReviewed the full diff against the current tree. This is a high-quality, well-iterated change: the failure modes are real, the fixes are minimal and correctly placed, the reasoning is captured in the code (not just the PR body), and the test coverage is genuinely adversarial (red-before/green-after plus the "stays quiet" controls that keep the reports from becoming noise). The A few observations, none of them blocking: 1. A bare
|
Review: #5644 - persist the partition strategy, and report the index change that undoes itThoroughly reviewed the diff, the surrounding What holds up well
Observations (non-blocking)
Nits
Overall: correct, well-tested, and the documentation makes the intent auditable. LGTM modulo the |
…on diagnosis Raised in review of #5644. A drop that leaves a partitioned type without its partition index is a blocker, and it is reported only on the next open. Hooking the drop is not the fix: recollating an index is a drop followed by a create, so the line would claim there is no unique automatic index in the middle of a sequence about to put one back, and would print ahead of the accurate one the create emits. Closing it properly means deferring the diagnosis to the end of the enclosing transaction, tracked as #5646.
|
Review of PR 5644 - persist the partition strategy, and report the index change that undoes it I read the full diff (all 8 commits) against the surrounding code in LocalDocumentType, LocalSchema, TypeIndexBuilder, and PartitionedBucketSelectionStrategy. This is a careful, well-reasoned fix and the test coverage is genuinely strong. What holds up well
Points worth a look (none blocking)
Style / conventions Consistent with CLAUDE.md: final throughout, classes imported (no FQNs), assertThat(...).isTrue() test style, no System.out, cold-path allocation only. The .codacy.yml /src/test/ widening is a correct, self-contained fix for the non-recursive src/test/* glob. Nice work - the fix is minimal where it matters and the tests pin the behavior tightly. My only real ask is confirming the inheritance-path exception-type change (point 1) does not surprise a caller. |
…and why the IAE arm stays Both raised in review of #5644. - An inherited partition that is unsuitable for the subtype still refuses, as it always has; what changed is that the refusal arrives as the SchemaException the suitability check raises rather than the IllegalArgumentException the binding used to throw. Checked every caller of addSuperType - CreateTypeAbstractStatement, AlterTypeStatement's SUPERTYPE branch, TypeBuilder, the Cypher Labels helper and LocalSchema's dropType re-attach - and none catches either type, so nothing distinguishes them; neither is a CommandParsingException, so the HTTP status is unchanged too. Recorded at the call site so the next reader need not repeat the search. - The loader's "expected" classification still lists IllegalArgumentException for the strategies this engine does not ship: a custom BucketSelectionStrategy named by class in schema.json runs its own setType() there, and rejecting the type it is handed is what that exception is for. On a stock database only the SchemaException arm now fires.
|
Code review — PR 5644 Reviewed the full diff (9 commits) against main, focusing on the engine schema/partitioning paths. This is a carefully reasoned change; the fixes are correct and the rationale is captured well in code comments. What the PR does well
Observations / minor points
Not verified locally Maven runs require approval in this environment, so I did not re-run the suite; the PR reports the full arcadedb-engine suite green (10545 tests, 0 failures) plus PartitionedStrategyRefusalHttpTest. The changed sources read as internally consistent. Overall: correct, well-tested, and unusually well-documented. No blocking issues found. |
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #5644 +/- ##
============================================
+ Coverage 66.86% 67.31% +0.44%
============================================
Files 1771 1771
Lines 149846 149871 +25
Branches 31768 31773 +5
============================================
+ Hits 100197 100879 +682
+ Misses 36522 35857 -665
- Partials 13127 13135 +8 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Up to standards ✅🟢 Issues
|
| Metric | Results |
|---|---|
| Complexity | 7 |
🟢 Coverage 94.74% diff coverage · -6.41% coverage variation
Metric Results Coverage variation ✅ -6.41% coverage variation Diff coverage ✅ 94.74% diff coverage Coverage variation details
Coverable lines Covered lines Coverage Common ancestor commit (3275298) 149846 113368 75.66% Head commit (00f5eb4) 181863 (+32017) 125935 (+12567) 69.25% (-6.41%) Coverage variation is the difference between the coverage for the head and common ancestor commits of the pull request branch:
<coverage of head commit> - <coverage of common ancestor commit>Diff coverage details
Coverable lines Covered lines Diff coverage Pull request (#5644) 38 36 94.74% Diff coverage is the percentage of lines that are covered by tests out of the coverable lines that the pull request added or modified:
<covered lines added or modified>/<coverable lines added or modified> * 100%
NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.
|
Code Review Reviewed the full diff against main. This is a careful, well-reasoned fix and the inline documentation is genuinely excellent - the why is recorded exactly where a future reader needs it. Summary: looks correct and well-tested. Notes below are mostly confirmations plus a few small observations; no blocking issues found. Correctness - the load-order dependency is the crux, and it holds. The whole fix hinges on Persistence logic is sound. Fault isolation is a real robustness win. Moving validation out of Test coverage. Minor observations (non-blocking):
Build/verification. Author reports the full arcadedb-engine suite green (10545 tests) plus PartitionedStrategyRefusalHttpTest. I reviewed the logic paths by hand (could not run Maven in this sandbox); nothing I traced contradicts that. Nice work - the change is minimal at the mutator, the fault isolation is the right instinct, and the tests target the actual regressions rather than the happy path. |
Bumps [undici](https://github.com/nodejs/undici) from 8.5.0 to 8.10.0. Release notes *Sourced from [undici's releases](https://github.com/nodejs/undici/releases).* > v8.10.0 > ------- > > What's Changed > -------------- > > * feat: namespace h2 options by [`@metcoder95`](https://github.com/metcoder95) in [nodejs/undici#5498](https://redirect.github.com/nodejs/undici/pull/5498) > * test: update WPT expectations by [`@mcollina`](https://github.com/mcollina) in [nodejs/undici#5587](https://redirect.github.com/nodejs/undici/pull/5587) > * test: add cache/dedupe + dns re-dispatch integration tests by [`@GiHoon1123`](https://github.com/GiHoon1123) in [nodejs/undici#5535](https://redirect.github.com/nodejs/undici/pull/5535) > * fix(websocket): support process.unref by [`@mcollina`](https://github.com/mcollina) in [nodejs/undici#5578](https://redirect.github.com/nodejs/undici/pull/5578) > * fix(h2): ensure every request settles by [`@mcollina`](https://github.com/mcollina) in [nodejs/undici#5603](https://redirect.github.com/nodejs/undici/pull/5603) > * fix(readable): consume a body whose end has already been emitted by [`@marko1olo`](https://github.com/marko1olo) in [nodejs/undici#5617](https://redirect.github.com/nodejs/undici/pull/5617) > * fix(retry): skip the content-length checkpoint for HEAD and for a 206 without content-range by [`@marko1olo`](https://github.com/marko1olo) in [nodejs/undici#5610](https://redirect.github.com/nodejs/undici/pull/5610) > * fix: revert idle socket validation to setTimeout(0) to prevent stall on idle event loop by [`@marceli1404`](https://github.com/marceli1404) in [nodejs/undici#5606](https://redirect.github.com/nodejs/undici/pull/5606) > * fix(env-http-proxy-agent): match bare IPv6 addresses in no\_proxy by [`@marko1olo`](https://github.com/marko1olo) in [nodejs/undici#5623](https://redirect.github.com/nodejs/undici/pull/5623) > * test: handle aggregate balanced pool errors by [`@marko1olo`](https://github.com/marko1olo) in [nodejs/undici#5377](https://redirect.github.com/nodejs/undici/pull/5377) > * fix(readable): keep body bytes that arrive after setEncoding() by [`@mcollina`](https://github.com/mcollina) in [nodejs/undici#5620](https://redirect.github.com/nodejs/undici/pull/5620) > * fix(socks5): evict unused origin pools by [`@Kkartik14`](https://github.com/Kkartik14) in [nodejs/undici#5595](https://redirect.github.com/nodejs/undici/pull/5595) > * fix: skip deduplication for upgrade requests by [`@Ram-blip`](https://github.com/Ram-blip) in [nodejs/undici#5593](https://redirect.github.com/nodejs/undici/pull/5593) > * fix(retry): forward informational responses by [`@mcollina`](https://github.com/mcollina) in [nodejs/undici#5625](https://redirect.github.com/nodejs/undici/pull/5625) > * fix(mock): non-string path matchers under ignoreTrailingSlash, and DataView reply bodies by [`@marko1olo`](https://github.com/marko1olo) in [nodejs/undici#5619](https://redirect.github.com/nodejs/undici/pull/5619) > * fix(interceptors): cache() and deduplicate() silently inert on Client/Pool without opts.origin by [`@marko1olo`](https://github.com/marko1olo) in [nodejs/undici#5628](https://redirect.github.com/nodejs/undici/pull/5628) > * build(deps): bump ossf/scorecard-action from 2.4.3 to 2.4.4 by [`@dependabot`](https://github.com/dependabot)[bot] in [nodejs/undici#5633](https://redirect.github.com/nodejs/undici/pull/5633) > * build(deps): bump github/codeql-action/init from 4.36.2 to 4.37.3 by [`@dependabot`](https://github.com/dependabot)[bot] in [nodejs/undici#5634](https://redirect.github.com/nodejs/undici/pull/5634) > * build(deps): bump actions/setup-node from 6.4.0 to 7.0.0 by [`@dependabot`](https://github.com/dependabot)[bot] in [nodejs/undici#5636](https://redirect.github.com/nodejs/undici/pull/5636) > * fix(mock): emit request body lifecycle hooks by [`@marko1olo`](https://github.com/marko1olo) in [nodejs/undici#5367](https://redirect.github.com/nodejs/undici/pull/5367) > * fix(h2): detach upgrade close handler after GOAWAY by [`@pacocartones`](https://github.com/pacocartones) in [nodejs/undici#5641](https://redirect.github.com/nodejs/undici/pull/5641) > * fix: retry refused HTTP/2 streams by [`@mcollina`](https://github.com/mcollina) in [nodejs/undici#5598](https://redirect.github.com/nodejs/undici/pull/5598) > * fix: preserve DNS origin hostname on sockets by [`@cyphercodes`](https://github.com/cyphercodes) in [nodejs/undici#5577](https://redirect.github.com/nodejs/undici/pull/5577) > > New Contributors > ---------------- > > * [`@marceli1404`](https://github.com/marceli1404) made their first contribution in [nodejs/undici#5606](https://redirect.github.com/nodejs/undici/pull/5606) > * [`@Kkartik14`](https://github.com/Kkartik14) made their first contribution in [nodejs/undici#5595](https://redirect.github.com/nodejs/undici/pull/5595) > * [`@pacocartones`](https://github.com/pacocartones) made their first contribution in [nodejs/undici#5641](https://redirect.github.com/nodejs/undici/pull/5641) > * [`@cyphercodes`](https://github.com/cyphercodes) made their first contribution in [nodejs/undici#5577](https://redirect.github.com/nodejs/undici/pull/5577) > > **Full Changelog**: <nodejs/undici@v8.9.0...v8.10.0> > > v8.9.0 > ------ > >⚠️ Security fixes > ----------------- > > ### High severity > > * [GHSA-4cwx-7wf7-3272](GHSA-4cwx-7wf7-3272): malformed qualified `private` Cache-Control directives could cause cross-user information disclosure in shared caches or a parse-time crash. The cache parser now treats empty qualified directives conservatively and safely handles mixed qualified and unqualified directives. Fixed by [4fe5bc5f](nodejs/undici@4fe5bc5) with regression coverage in [9f09b49a](nodejs/undici@9f09b49). > > ### Medium severity > > * [GHSA-m8rv-5g2x-5cg5](GHSA-m8rv-5g2x-5cg5): a malicious `type` property on a duck-typed blob-like HTTP/1.1 request body could inject CRLF sequences into the generated `content-type` header. Undici now coerces and validates the value before adding it to the request. Fixed by [7d3cf924](nodejs/undici@7d3cf92). > * [GHSA-jr45-8vmc-qm54](GHSA-jr45-8vmc-qm54): optional whitespace around `=` in qualified `no-cache` and `private` directives could bypass shared-cache restrictions and disclose authenticated data across users. Cache-Control parsing now normalizes these forms and applies conservative cache decisions. Fixed by [c601fff1](nodejs/undici@c601fff). > * [GHSA-8xcm-r25x-g524](GHSA-8xcm-r25x-g524): the retry interceptor could expose a stale `Content-Length` after resuming a partial response, potentially causing downstream response desynchronization, hangs, or corruption. Undici now rejects partial responses whose `Content-Length` is inconsistent with `Content-Range`. Fixed by [e11a68ed](nodejs/undici@e11a68e), with corrected fixtures in [2b3f7493](nodejs/undici@2b3f749). > * [GHSA-v3r7-h72x-cjcm](GHSA-v3r7-h72x-cjcm): unsanitized `domain` and `unparsed` values passed to `setCookie()` could inject cookie attributes. Undici now validates cookie domains, paths, and unparsed attributes more strictly. Fixed by [10d93fc3](nodejs/undici@10d93fc). > > Additional hardening > -------------------- ... (truncated) Commits * [`c8d80e6`](nodejs/undici@c8d80e6) Bumped v8.10.0 ([#5644](https://redirect.github.com/nodejs/undici/issues/5644)) * [`66923b4`](nodejs/undici@66923b4) fix: preserve DNS origin hostname on sockets ([#5577](https://redirect.github.com/nodejs/undici/issues/5577)) * [`3926499`](nodejs/undici@3926499) fix: retry refused HTTP/2 streams ([#5598](https://redirect.github.com/nodejs/undici/issues/5598)) * [`73d6e9e`](nodejs/undici@73d6e9e) fix(h2): detach upgrade close handler after GOAWAY ([#5641](https://redirect.github.com/nodejs/undici/issues/5641)) * [`b111adb`](nodejs/undici@b111adb) fix(mock): emit request body lifecycle hooks ([#5367](https://redirect.github.com/nodejs/undici/issues/5367)) * [`ae4a3e3`](nodejs/undici@ae4a3e3) build(deps): bump actions/setup-node from 6.4.0 to 7.0.0 ([#5636](https://redirect.github.com/nodejs/undici/issues/5636)) * [`ec3fbf1`](nodejs/undici@ec3fbf1) build(deps): bump github/codeql-action/init from 4.36.2 to 4.37.3 ([#5634](https://redirect.github.com/nodejs/undici/issues/5634)) * [`2151720`](nodejs/undici@2151720) build(deps): bump ossf/scorecard-action from 2.4.3 to 2.4.4 ([#5633](https://redirect.github.com/nodejs/undici/issues/5633)) * [`b96a116`](nodejs/undici@b96a116) fix(interceptors): allow interceptors without opts.origin ([#5628](https://redirect.github.com/nodejs/undici/issues/5628)) * [`a18ef2d`](nodejs/undici@a18ef2d) fix(mock): non-string path matchers under ignoreTrailingSlash, and DataView r... * Additional commits viewable in [compare view](nodejs/undici@v8.5.0...v8.10.0) [](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) --- Dependabot commands and options You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) You can disable automated security fix PRs for this repo from the [Security Alerts page](https://github.com/ArcadeData/arcadedb/network/alerts).
…p ci] Bumps [undici](https://github.com/nodejs/undici) from 8.5.0 to 8.10.0. Release notes *Sourced from [undici's releases](https://github.com/nodejs/undici/releases).* > v8.10.0 > ------- > > What's Changed > -------------- > > * feat: namespace h2 options by [`@metcoder95`](https://github.com/metcoder95) in [nodejs/undici#5498](https://redirect.github.com/nodejs/undici/pull/5498) > * test: update WPT expectations by [`@mcollina`](https://github.com/mcollina) in [nodejs/undici#5587](https://redirect.github.com/nodejs/undici/pull/5587) > * test: add cache/dedupe + dns re-dispatch integration tests by [`@GiHoon1123`](https://github.com/GiHoon1123) in [nodejs/undici#5535](https://redirect.github.com/nodejs/undici/pull/5535) > * fix(websocket): support process.unref by [`@mcollina`](https://github.com/mcollina) in [nodejs/undici#5578](https://redirect.github.com/nodejs/undici/pull/5578) > * fix(h2): ensure every request settles by [`@mcollina`](https://github.com/mcollina) in [nodejs/undici#5603](https://redirect.github.com/nodejs/undici/pull/5603) > * fix(readable): consume a body whose end has already been emitted by [`@marko1olo`](https://github.com/marko1olo) in [nodejs/undici#5617](https://redirect.github.com/nodejs/undici/pull/5617) > * fix(retry): skip the content-length checkpoint for HEAD and for a 206 without content-range by [`@marko1olo`](https://github.com/marko1olo) in [nodejs/undici#5610](https://redirect.github.com/nodejs/undici/pull/5610) > * fix: revert idle socket validation to setTimeout(0) to prevent stall on idle event loop by [`@marceli1404`](https://github.com/marceli1404) in [nodejs/undici#5606](https://redirect.github.com/nodejs/undici/pull/5606) > * fix(env-http-proxy-agent): match bare IPv6 addresses in no\_proxy by [`@marko1olo`](https://github.com/marko1olo) in [nodejs/undici#5623](https://redirect.github.com/nodejs/undici/pull/5623) > * test: handle aggregate balanced pool errors by [`@marko1olo`](https://github.com/marko1olo) in [nodejs/undici#5377](https://redirect.github.com/nodejs/undici/pull/5377) > * fix(readable): keep body bytes that arrive after setEncoding() by [`@mcollina`](https://github.com/mcollina) in [nodejs/undici#5620](https://redirect.github.com/nodejs/undici/pull/5620) > * fix(socks5): evict unused origin pools by [`@Kkartik14`](https://github.com/Kkartik14) in [nodejs/undici#5595](https://redirect.github.com/nodejs/undici/pull/5595) > * fix: skip deduplication for upgrade requests by [`@Ram-blip`](https://github.com/Ram-blip) in [nodejs/undici#5593](https://redirect.github.com/nodejs/undici/pull/5593) > * fix(retry): forward informational responses by [`@mcollina`](https://github.com/mcollina) in [nodejs/undici#5625](https://redirect.github.com/nodejs/undici/pull/5625) > * fix(mock): non-string path matchers under ignoreTrailingSlash, and DataView reply bodies by [`@marko1olo`](https://github.com/marko1olo) in [nodejs/undici#5619](https://redirect.github.com/nodejs/undici/pull/5619) > * fix(interceptors): cache() and deduplicate() silently inert on Client/Pool without opts.origin by [`@marko1olo`](https://github.com/marko1olo) in [nodejs/undici#5628](https://redirect.github.com/nodejs/undici/pull/5628) > * build(deps): bump ossf/scorecard-action from 2.4.3 to 2.4.4 by [`@dependabot`](https://github.com/dependabot)[bot] in [nodejs/undici#5633](https://redirect.github.com/nodejs/undici/pull/5633) > * build(deps): bump github/codeql-action/init from 4.36.2 to 4.37.3 by [`@dependabot`](https://github.com/dependabot)[bot] in [nodejs/undici#5634](https://redirect.github.com/nodejs/undici/pull/5634) > * build(deps): bump actions/setup-node from 6.4.0 to 7.0.0 by [`@dependabot`](https://github.com/dependabot)[bot] in [nodejs/undici#5636](https://redirect.github.com/nodejs/undici/pull/5636) > * fix(mock): emit request body lifecycle hooks by [`@marko1olo`](https://github.com/marko1olo) in [nodejs/undici#5367](https://redirect.github.com/nodejs/undici/pull/5367) > * fix(h2): detach upgrade close handler after GOAWAY by [`@pacocartones`](https://github.com/pacocartones) in [nodejs/undici#5641](https://redirect.github.com/nodejs/undici/pull/5641) > * fix: retry refused HTTP/2 streams by [`@mcollina`](https://github.com/mcollina) in [nodejs/undici#5598](https://redirect.github.com/nodejs/undici/pull/5598) > * fix: preserve DNS origin hostname on sockets by [`@cyphercodes`](https://github.com/cyphercodes) in [nodejs/undici#5577](https://redirect.github.com/nodejs/undici/pull/5577) > > New Contributors > ---------------- > > * [`@marceli1404`](https://github.com/marceli1404) made their first contribution in [nodejs/undici#5606](https://redirect.github.com/nodejs/undici/pull/5606) > * [`@Kkartik14`](https://github.com/Kkartik14) made their first contribution in [nodejs/undici#5595](https://redirect.github.com/nodejs/undici/pull/5595) > * [`@pacocartones`](https://github.com/pacocartones) made their first contribution in [nodejs/undici#5641](https://redirect.github.com/nodejs/undici/pull/5641) > * [`@cyphercodes`](https://github.com/cyphercodes) made their first contribution in [nodejs/undici#5577](https://redirect.github.com/nodejs/undici/pull/5577) > > **Full Changelog**: <nodejs/undici@v8.9.0...v8.10.0> > > v8.9.0 > ------ > >⚠️ Security fixes > ----------------- > > ### High severity > > * [GHSA-4cwx-7wf7-3272](GHSA-4cwx-7wf7-3272): malformed qualified `private` Cache-Control directives could cause cross-user information disclosure in shared caches or a parse-time crash. The cache parser now treats empty qualified directives conservatively and safely handles mixed qualified and unqualified directives. Fixed by [4fe5bc5f](nodejs/undici@4fe5bc5) with regression coverage in [9f09b49a](nodejs/undici@9f09b49). > > ### Medium severity > > * [GHSA-m8rv-5g2x-5cg5](GHSA-m8rv-5g2x-5cg5): a malicious `type` property on a duck-typed blob-like HTTP/1.1 request body could inject CRLF sequences into the generated `content-type` header. Undici now coerces and validates the value before adding it to the request. Fixed by [7d3cf924](nodejs/undici@7d3cf92). > * [GHSA-jr45-8vmc-qm54](GHSA-jr45-8vmc-qm54): optional whitespace around `=` in qualified `no-cache` and `private` directives could bypass shared-cache restrictions and disclose authenticated data across users. Cache-Control parsing now normalizes these forms and applies conservative cache decisions. Fixed by [c601fff1](nodejs/undici@c601fff). > * [GHSA-8xcm-r25x-g524](GHSA-8xcm-r25x-g524): the retry interceptor could expose a stale `Content-Length` after resuming a partial response, potentially causing downstream response desynchronization, hangs, or corruption. Undici now rejects partial responses whose `Content-Length` is inconsistent with `Content-Range`. Fixed by [e11a68ed](nodejs/undici@e11a68e), with corrected fixtures in [2b3f7493](nodejs/undici@2b3f749). > * [GHSA-v3r7-h72x-cjcm](GHSA-v3r7-h72x-cjcm): unsanitized `domain` and `unparsed` values passed to `setCookie()` could inject cookie attributes. Undici now validates cookie domains, paths, and unparsed attributes more strictly. Fixed by [10d93fc3](nodejs/undici@10d93fc). > > Additional hardening > -------------------- ... (truncated) Commits * [`c8d80e6`](nodejs/undici@c8d80e6) Bumped v8.10.0 ([#5644](https://redirect.github.com/nodejs/undici/issues/5644)) * [`66923b4`](nodejs/undici@66923b4) fix: preserve DNS origin hostname on sockets ([#5577](https://redirect.github.com/nodejs/undici/issues/5577)) * [`3926499`](nodejs/undici@3926499) fix: retry refused HTTP/2 streams ([#5598](https://redirect.github.com/nodejs/undici/issues/5598)) * [`73d6e9e`](nodejs/undici@73d6e9e) fix(h2): detach upgrade close handler after GOAWAY ([#5641](https://redirect.github.com/nodejs/undici/issues/5641)) * [`b111adb`](nodejs/undici@b111adb) fix(mock): emit request body lifecycle hooks ([#5367](https://redirect.github.com/nodejs/undici/issues/5367)) * [`ae4a3e3`](nodejs/undici@ae4a3e3) build(deps): bump actions/setup-node from 6.4.0 to 7.0.0 ([#5636](https://redirect.github.com/nodejs/undici/issues/5636)) * [`ec3fbf1`](nodejs/undici@ec3fbf1) build(deps): bump github/codeql-action/init from 4.36.2 to 4.37.3 ([#5634](https://redirect.github.com/nodejs/undici/issues/5634)) * [`2151720`](nodejs/undici@2151720) build(deps): bump ossf/scorecard-action from 2.4.3 to 2.4.4 ([#5633](https://redirect.github.com/nodejs/undici/issues/5633)) * [`b96a116`](nodejs/undici@b96a116) fix(interceptors): allow interceptors without opts.origin ([#5628](https://redirect.github.com/nodejs/undici/issues/5628)) * [`a18ef2d`](nodejs/undici@a18ef2d) fix(mock): non-string path matchers under ignoreTrailingSlash, and DataView r... * Additional commits viewable in [compare view](nodejs/undici@v8.5.0...v8.10.0) [](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) --- Dependabot commands and options You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) You can disable automated security fix PRs for this repo from the [Security Alerts page](https://github.com/ArcadeData/arcadedb/network/alerts).
Closes #5637.
Two loose ends of the partitioned-strategy series (#5589, #5595, #5603), both about what happens to a type after it has been configured.
1.
ALTER TYPE ... BucketSelectionStrategyis persistedThe strategy was set in memory and nothing wrote it out, so a type partitioned by that DDL alone came back
round-robinafter a restart - unless some later, unrelated schema mutation happened to flush the configuration first. This hits correctly configured types, which is what makes it worse than the states #5603 refuses: new records were placed round-robin among rows the partition hash had placed, every partition-aware lookup silently fanned out, and nothing warned.It is the one schema mutator that left the write to somebody else - every sibling either calls
saveConfiguration()directly or goes throughrecordFileChanges, which does - and the flag about the partitioning (needsRepartition, in the same class) saved itself while the partitioning did not. It now saves, skipped while the schema is being read back so a partitioned database does not rewrite an identicalschema.jsonon every open.2. An index created on an already-partitioned type is diagnosed when it is created
#5603 refuses an unsuitable partition at assignment time, but the same state was reachable by reordering the DDL:
Correctness always held - the strategy declines to prune, so lookups fan out and
UNIQUEstays global - but between theCREATE INDEXand the next restart nothing said the partitioning had stopped doing anything.TypeIndexBuilder.create()now re-runs the same check, once perCREATE INDEXrather than once per bucket (which is why the hook is not inaddIndexInternal, and why it does not fire during schema reload).It never refuses: at assignment time the strategy is what was asked for and a blocked one is pure cost, whereas here the index is what was asked for and it is useful, so the partitioning is what gives way. An index change that leaves the partition exactly as suitable as it was stays quiet.
3. Persisting the strategy made a pre-existing fault reachable
Binding the strategy demanded the unique automatic index on the partition properties, and did so on every rebind - including the one the schema loader performs on every open. With the strategy now reaching
schema.json, aDROP INDEXon the partition key made the next open throw from inside the loader, which aborts everything it has not reached yet: the remaining types' strategies, the triggers, the function libraries, the extensions, and the compaction file-migration map WAL recovery redirects through - surfacing only asError on loading schema. The schema will be reset.Binding no longer validates anything. The requirement moved into
checkSuitability(), which still refuses it at assignment time and now warns about it on load, so the type keeps its partitioned placement and records written after the index was dropped still land where a lookup would look for them.The refusal is not byte-for-byte what it was, and anything matching on the old form should know it: it used to be an
IllegalArgumentExceptionthrown straight out ofsetType, and it is now aSchemaExceptionraised by the suitability check and wrapped in the usual "Cannot use the partitioned bucket selection strategy on ... for type ..." sentence. What is unchanged is what callers actually depend on - thecannot find a unique automatic index on the partition properties [...]substring, and theCommandSQLParsingException-> HTTP 400 classification, sinceAlterTypeStatementalready caught both exception types.LocalSchemaadditionally isolates a per-type strategy failure, so any other unusable strategy - an implementation class that no longer resolves, say - costs that one type its pruning instead of the rest of the schema.Suitability.canPrune()is renamedisUsable(): a missing partition index does not stop the strategy computing a bucket, it removes the index lookup that would have been pruned, so the old name no longer described the whole set.Verification
New
PartitionedStrategyLifecycleTest(9 tests). Four were red before the fix (persistence toschema.json, survival of a reopen, and both index-change reports), and the two load-path guards were mutation-checked individually - reinstating the binding validation reddensaPartitionedTypeWhoseIndexWasDroppedStillOpens, removing the loader's per-type catch reddensanUnresolvableStrategyDoesNotCostTheRestOfTheSchema. Three controls keep them honest: an unchanged index re-creation stays quiet, a round-robin type is never diagnosed, and reverting toround-robinpersists as the absence of the entry.The explicit
saveConfiguration()workaround inPartitionedStrategySuitabilityTest.theFanOutWarningIsNotRepeatedOnEveryReopen, added in #5605 with a comment saying why, comes out.Full
arcadedb-enginesuite green (10545 tests, 0 failures), plusPartitionedStrategyRefusalHttpTestinarcadedb-server.🤖 Generated with Claude Code
https://claude.ai/code/session_017dDUKvQXJGBBoXiEQgtc2v