private Query optimizeQuery()

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


    private Query optimizeQuery(ConditionQuery query) {
        if (query.idsSize() > 0) {
            throw new HugeException(
                      "Not supported querying by id and conditions: %s", query);
        }

        Id label = (Id) query.condition(HugeKeys.LABEL);

        // Optimize vertex query
        if (label != null && query.resultType().isVertex()) {
            VertexLabel vertexLabel = this.graph().vertexLabel(label);
            if (vertexLabel.idStrategy() == IdStrategy.PRIMARY_KEY) {
                List<Id> keys = vertexLabel.primaryKeys();
                E.checkState(!keys.isEmpty(),
                             "The primary keys can't be empty when using " +
                             "'%s' id strategy for vertex label '%s'",
                             IdStrategy.PRIMARY_KEY, vertexLabel.name());
                if (query.matchUserpropKeys(keys)) {
                    // Query vertex by label + primary-values
                    query.optimized(OptimizedType.PRIMARY_KEY);
                    String primaryValues = query.userpropValuesString(keys);
                    LOG.debug("Query vertices by primaryKeys: {}", query);
                    // Convert {vertex-label + primary-key} to vertex-id
                    Id id = SplicingIdGenerator.splicing(label.asString(),
                                                         primaryValues);
                    /*
                     * Just query by primary-key(id), ignore other userprop(if
                     * exists) that it will be filtered by queryVertices(Query)
                     */
                    return new IdQuery(query, id);
                }
            }
        }

        // Optimize edge query
        if (query.resultType().isEdge() && label != null &&
            query.condition(HugeKeys.OWNER_VERTEX) != null &&
            query.condition(HugeKeys.DIRECTION) != null &&
            matchEdgeSortKeys(query, false, this.graph())) {
            // Query edge by sourceVertex + direction + label + sort-values
            query.optimized(OptimizedType.SORT_KEYS);
            query = query.copy();
            // Serialize sort-values
            List<Id> keys = this.graph().edgeLabel(label).sortKeys();
            List<Condition> conditions =
                            GraphIndexTransaction.constructShardConditions(
                            query, keys, HugeKeys.SORT_VALUES);
            query.query(conditions);
            /*
             * Reset all userprop since transferred to sort-keys, ignore other
             * userprop(if exists) that it will be filtered by queryEdges(Query)
             */
            query.resetUserpropConditions();

            LOG.debug("Query edges by sortKeys: {}", query);
            return query;
        }

        /*
         * Query only by sysprops, like: by vertex label, by edge label.
         * NOTE: we assume sysprops would be indexed by backend store
         * but we don't support query edges only by direction/target-vertex.
         */
        if (query.allSysprop()) {
            if (query.resultType().isVertex()) {
                verifyVerticesConditionQuery(query);
            } else if (query.resultType().isEdge()) {
                verifyEdgesConditionQuery(query);
            }
            /*
             * Just support:
             *  1.not query by label
             *  2.or query by label and store supports this feature
             */
            boolean byLabel = (label != null && query.conditionsSize() == 1);
            if (!byLabel || this.store().features().supportsQueryByLabel()) {
                return query;
            }
        }

        return null;
    }