JanusGraph / JanusGraph/janusgraph

updateIndex on a mixed index fails an unrelated precondition when no key is in an applicable status

Open
#4,930 0 comments 0 reactions 0 assignees View on GitHub

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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.