Skip to content

Commit

Permalink
fallback queryNumber() if there are uncommitted records
Browse files Browse the repository at this point in the history
fixed sub-issue 1 of #2058
  • Loading branch information
javeme committed Dec 28, 2022
1 parent 6c3170c commit 736b156
Showing 1 changed file with 39 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -528,52 +528,64 @@ public void rollback() throws BackendException {
@Override
public QueryResults<BackendEntry> query(Query query) {
if (!(query instanceof ConditionQuery)) {
// It's a sysprop-query, don't need to optimize
LOG.debug("Query{final:{}}", query);
return super.query(query);
}

QueryList<BackendEntry> queries = this.optimizeQueries(query,
super::query);
QueryList<BackendEntry> queries = this.optimizeQueries(query, super::query);
LOG.debug("{}", queries);
return queries.empty() ? QueryResults.empty() :
queries.fetch(this.pageSize);
}

@Override
public Number queryNumber(Query query) {
E.checkArgument(!this.hasUpdate(),
"It's not allowed to query number when " +
"there are uncommitted records.");

if (!(query instanceof ConditionQuery)) {
return super.queryNumber(query);
}

boolean hasUpdate = this.hasUpdate();
Aggregate aggregate = query.aggregateNotNull();

QueryList<Number> queries = this.optimizeQueries(query, q -> {
boolean indexQuery = q.getClass() == IdQuery.class;
OptimizedType optimized = ((ConditionQuery) query).optimized();
boolean isIndexQuery = q instanceof IdQuery;
boolean isConditionQuery = query instanceof ConditionQuery;
assert isIndexQuery || isConditionQuery || q == query;
// Need to fallback if there are uncommitted records
boolean fallback = hasUpdate;
Number result;
if (!indexQuery) {

if (fallback) {
// Here just ignore it, and do fallback later
result = null;
} else if (!isIndexQuery || !isConditionQuery) {
// It's a sysprop-query, let parent tx do it
assert !fallback;
result = super.queryNumber(q);
} else {
E.checkArgument(aggregate.func() == AggregateFunc.COUNT,
"The %s operator on index is not supported now",
aggregate.func().string());
if (this.optimizeAggrByIndex &&
optimized == OptimizedType.INDEX) {
assert query instanceof ConditionQuery;
OptimizedType optimized = ((ConditionQuery) query).optimized();
if (this.optimizeAggrByIndex && optimized == OptimizedType.INDEX) {
// The ids size means results count (assume no left index)
result = q.idsSize();
} else {
assert optimized == OptimizedType.INDEX_FILTER ||
optimized == OptimizedType.INDEX;
assert q.resultType().isVertex() || q.resultType().isEdge();
result = IteratorUtils.count(q.resultType().isVertex() ?
this.queryVertices(q) :
this.queryEdges(q));
assert !fallback;
fallback = true;
result = null;
}
}

// Can't be optimized, then do fallback
if (fallback) {
assert result == null;
assert q.resultType().isVertex() || q.resultType().isEdge();
result = IteratorUtils.count(q.resultType().isVertex() ?
this.queryVertices(q) :
this.queryEdges(q));
}

return new QueryResults<>(IteratorUtils.of(result), q);
});

Expand Down Expand Up @@ -1335,14 +1347,20 @@ private static void verifyEdgesConditionQuery(ConditionQuery query) {

private <R> QueryList<R> optimizeQueries(Query query,
QueryResults.Fetcher<R> fetcher) {
boolean supportIn = this.storeFeatures().supportsQueryWithInCondition();
QueryList<R> queries = new QueryList<>(query, fetcher);
if (!(query instanceof ConditionQuery)) {
// It's a sysprop-query, add itself as subquery, don't need to flatten
queries.add(query);
return queries;
}

boolean supportIn = this.storeFeatures().supportsQueryWithInCondition();
for (ConditionQuery cq: ConditionQueryFlatten.flatten(
(ConditionQuery) query, supportIn)) {
// Optimize by sysprop
Query q = this.optimizeQuery(cq);
/*
* NOTE: There are two possibilities for this query:
* NOTE: There are two possibilities for the returned q:
* 1.sysprop-query, which would not be empty.
* 2.index-query result(ids after optimization), which may be empty.
*/
Expand Down

0 comments on commit 736b156

Please sign in to comment.