Skip to content
37 changes: 37 additions & 0 deletions docs/server-runtime.md
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,43 @@ without a preceding REST graph query, and subsequent REST queries must remain us
Gremlin scripts still cannot read restricted system properties such as `java.version`
or disable the security manager.

### Property-query index coverage

For type-compatible values, a global property-index query such as
`g.V().has("name", "alice")` or `g.E().has("weight", 0.5)` requires compatible
indexes on every visible candidate label. A candidate declares all queried non-OLAP
properties; even a label with no records requires coverage. Base edge labels have no
direct records; their indexes can cover sub-labels. An explicit sub-label query
also uses a compatible query-visible parent index when no compatible direct index
exists, while still filtering out sibling sub-labels. Shared OLAP indexes follow the graph read
mode.

| Candidate state | Query behavior |
| --- | --- |
| Every visible candidate has compatible indexes | The query combines the indexed results. Composite and joint index plans may serve different labels in the same query. |
| A visible candidate lacks a compatible index and the values pass the property-type check | The query fails with `NoIndexException`, including when other candidates are hidden or deleting. |
| Every candidate is excluded by visibility | The query returns an empty result, including after those labels' indexes have been removed. |

When query-visible candidates remain, index matching precedes the property-type
check. If at least one index matches but a value fails that check, the query returns
an empty result before complete coverage is checked. If no index matches, it still
raises `NoIndexException`, even for a type-mismatched value.

Normal queries exclude hidden labels and labels in `DELETING` or `UNDELETED`
status. Internal requests that enable `showHidden` or `showDeleting` include the
corresponding labels and still require their indexes. Visibility follows the outer
request when a query is split into subqueries. Each branch checks index state and
complete coverage before opening its backend iterators. If branch construction
fails, the query closes cursors from both the unfinished branch and earlier
branches, preserving the original error. Joint index planning closes unselected
cursors and transfers the selected cursor to the result. This does not provide a
snapshot against concurrent schema changes.

To fix incomplete coverage, specify an indexed label, for example
`g.V().hasLabel("person").has("name", "alice")`, or add indexes compatible with the
query predicates to every candidate label. Explicit-ID lookups and adjacency
filtering do not introduce a global property-index coverage requirement.

### Predicate and value compatibility

Version-specific handling retains negated predicates and filtering barriers where
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import org.apache.hugegraph.id.Id;
import org.apache.hugegraph.query.ConditionQuery;
import org.apache.hugegraph.query.Query;
import org.apache.hugegraph.backend.query.QueryBatch;
import org.apache.hugegraph.backend.store.BackendEntry;
import org.apache.hugegraph.iterator.CIter;
import org.apache.hugegraph.iterator.Metadatable;
Expand Down Expand Up @@ -231,16 +232,25 @@ public PageIds fetchNext(String page, long batchSize) {

@Override
public Set<Id> all() {
Set<Id> ids;
try {
Set<Id> ids = this.fetcher.apply(this.remaining());
ids = this.fetcher.apply(this.remaining());
if (this.currentBatch != null) {
ids.addAll(this.getFromCurrentBatch(Query.NO_LIMIT).ids());
}
this.count += ids.size();
return ids;
} finally {
this.close();
} catch (Throwable failure) {
try {
this.close();
} catch (Throwable closing) {
if (closing != failure) {
failure.addSuppressed(closing);
}
}
throw QueryBatch.propagate(failure);
}
this.close();
return ids;
}

public PageIds peekNext(long size) {
Expand Down
Loading
Loading