public Number queryNumber()

in hugegraph-core/src/main/java/org/apache/hugegraph/backend/tx/GraphTransaction.java [542:602]


    public Number queryNumber(Query query) {
        boolean isConditionQuery = query instanceof ConditionQuery;
        boolean hasUpdate = this.hasUpdate();
        Aggregate aggregate = query.aggregateNotNull();

        // TODO: we can concat index-query results and tx uncommitted records.
        if (hasUpdate) {
            E.checkArgument(!isConditionQuery,
                            "It's not allowed to query by index when " +
                            "there are uncommitted records.");
        }

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

            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());
                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 !fallback;
                    fallback = true;
                    result = null;
                }
            }

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

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

        QueryResults<Number> results = queries.empty() ?
                                       QueryResults.empty() :
                                       queries.fetch(this.pageSize);
        return aggregate.reduce(results.iterator());
    }