JanusGraph / JanusGraph/janusgraph
updateIndex on a mixed index fails an unrelated precondition when no key is in an applicable status
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 5.8k
- Forks
- 1.2k
- Avg merge
- 13h 53m
- Merged PRs (30d)
- 6
Description
- Version: `master` (`ac0eb23`)
- Storage Backend: any
- Mixed Index Backend: any
- Expected Behavior: `mgmt.updateIndex` on a mixed index whose keys are all already in the target state either no-ops or reports a clear error, as it does for composite indexes.
- Current Behavior: it fails an internal `Preconditions.checkArgument` with a message about `RelationTypeVertex` and composite indexes, which gives no indication of the real problem.
### Details
For a mixed index, `updateIndex` builds `keySubset` from the fields whose current status is in the action's applicable set:
https://github.com/JanusGraph/janusgraph/blob/ac0eb2392ddad3d96ab8cde2a5a9a123dbc5d839/janusgraph-core/src/main/java/org/janusgraph/graphdb/database/management/ManagementSystem.java#L1070-L1080
```java
keySubset = new HashSet<>();
MixedIndexType mixedIndexType = (MixedIndexType) indexType;
Set applicableStatus = updateAction.getApplicableStatus();
for (ParameterIndexField field : mixedIndexType.getFieldKeys()) {
if (applicableStatus.contains(field.getStatus()))
keySubset.add((PropertyKeyVertex) field.getFieldKey());
}
```
If no field matches, `keySubset` is empty. `setStatus` then routes to the vertex-level path:
https://github.com/JanusGraph/janusgraph/blob/ac0eb2392ddad3d96ab8cde2a5a9a123dbc5d839/janusgraph-core/src/main/java/org/janusgraph/graphdb/database/management/ManagementSystem.java#L1283-L1291
```java
private void setStatus(JanusGraphSchemaVertex vertex, SchemaStatus status, Set keys) {
if (keys.isEmpty()) setStatusVertex(vertex, status);
else setStatusEdges(vertex, status, keys);
...
}
private void setStatusVertex(JanusGraphSchemaVertex vertex, SchemaStatus status) {
Preconditions.checkArgument(vertex instanceof RelationTypeVertex || vertex.asIndexType().isCompositeIndex());
```
which is guaranteed to fail for a mixed index.
Note the asymmetry: the composite-index branch calls `updateAction.isApplicableStatus(schemaVertex.getStatus())` first, which either returns early or throws the helpful `"Update action [%s] cannot be invoked for index with status [%s]"`. The mixed-index branch performs no such validation, so it falls through into an unrelated precondition.
Realistic triggers, all of them idempotent schema scripts being re-run:
- `REGISTER_INDEX` after all keys are already `ENABLED` — applicable status is `{INSTALLED}`, so nothing matches.
- `DISABLE_INDEX` when no key is `ENABLED`/`DISABLED`/`REGISTERED`.
- `ENABLE_INDEX` on a freshly created index whose keys are all `INSTALLED`.
Separately, and possibly worth its own issue: because the mixed-index branch never calls `isApplicableStatus`, `DROP_INDEX` on a live mixed index is not gated on `DISCARDED` either. `schemaVertex.remove()` runs regardless, dropping the schema vertex while leaving every document in the index backend orphaned with no JanusGraph-side handle to remove them.
### Steps to Reproduce
```java
mgmt = graph.openManagement();
mgmt.buildIndex("byName", Vertex.class).addKey(name).buildMixedIndex("search");
mgmt.commit();
ManagementSystem.awaitGraphIndexStatus(graph, "byName").call();
mgmt = graph.openManagement();
mgmt.updateIndex(mgmt.getGraphIndex("byName"), SchemaAction.REGISTER_INDEX); // keys already ENABLED
// IllegalArgumentException from setStatusVertex
```
### Suggested Fix
Give the mixed-index branch the same guard the composite branch has: when `keySubset` is empty, either return `null` as the composite path does for an inapplicable status, or throw the descriptive `isApplicableStatus` error naming the action and the current field statuses.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in janusgraph-core/src/main/java/org/janusgraph/graphdb/database/management/ManagementSystem.java, reading updateIndex and the mixed-index path through setStatus. Reproduce the REGISTER_INDEX, DISABLE_INDEX, or ENABLE_INDEX cases with no applicable fields; done means the operation no-ops or reports the descriptive applicability error instead of the unrelated precondition failure.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java
- Domain
- database
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 76/100