<commit_before>package com.tinkerpop.blueprints.impls.orient;

import com.orientechnologies.orient.core.db.record.OIdentifiable;
import com.orientechnologies.orient.core.sql.query.OSQLSynchQuery;
import com.tinkerpop.blueprints.Edge;
import com.tinkerpop.blueprints.Graph;
import com.tinkerpop.blueprints.Query;
import com.tinkerpop.blueprints.Vertex;
import com.tinkerpop.blueprints.util.DefaultGraphQuery;

import java.util.Collections;

/**
 * OrientDB implementation for Graph query.
 *
 * @author <NAME> (http://www.orientechnologies.com)
 */
public class OrientGraphQuery extends DefaultGraphQuery {

    private static final char SPACE = ' ';
    private static final String OPERATOR_DIFFERENT = "<>";
    private static final String OPERATOR_IS_NOT = "is not";
    private static final String OPERATOR_LET = "<=";
    private static final char OPERATOR_LT = '<';
    private static final String OPERATOR_GTE = ">=";
    private static final char OPERATOR_GT = '>';
    private static final String OPERATOR_EQUALS = "=";
    private static final String OPERATOR_IS = "is";
    private static final String OPERATOR_IN = " in ";

    private static final String QUERY_FILTER_AND = " and ";
    private static final String QUERY_FILTER_OR = " or ";
    private static final char QUERY_STRING = '\'';
    private static final char QUERY_SEPARATOR = ',';
    private static final char COLLECTION_BEGIN = '[';
    private static final char COLLECTION_END = ']';
    private static final char PARENTHESIS_BEGIN = '(';
    private static final char PARENTHESIS_END = ')';
    private static final String QUERY_LABEL_BEGIN = " and label in [";
    private static final String QUERY_LABEL_END = "]";
    private static final String QUERY_WHERE = " where 1=1";
    private static final String QUERY_SELECT_FROM = "select from ";
    private static final String LIMIT = " LIMIT ";
    private static final String SKIP = " SKIP ";

    public OrientGraphQuery(final Graph iGraph) {
        super(iGraph);
    }

    public Query labels(final String... labels) {
        this.labels = labels;
        return this;
    }

    @Override
    public Iterable<Vertex> vertices() {
        if (maximum == 0)
            return Collections.emptyList();

        final StringBuilder text = new StringBuilder();

        // GO DIRECTLY AGAINST E CLASS AND SUB-CLASSES
        text.append(QUERY_SELECT_FROM);

        if (((OrientBaseGraph) graph).isUseClassForVertexLabel()
                && labels != null && labels.length > 0) {
            // FILTER PER CLASS SAVING CHECKING OF LABEL PROPERTY
            if (labels.length == 1)
                // USE THE CLASS NAME
                text.append(OrientBaseGraph.encodeClassName(labels[0]));
            else {
                // MULTIPLE CLASSES NOT SUPPORTED DIRECTLY: CREATE A SUB-QUERY
                return super.vertices();
            }
        } else
            text.append(OrientVertex.CLASS_NAME);

        // APPEND ALWAYS WHERE 1=1 TO MAKE CONCATENATING EASIER
        text.append(QUERY_WHERE);
        manageFilters(text);
        if (!((OrientBaseGraph) graph).isUseClassForVertexLabel())
            manageLabels(text);

        if (maximum > 0 && maximum < Long.MAX_VALUE) {
            if (minimum > 0 && maximum < Long.MAX_VALUE) {
                text.append(SKIP);
                text.append(minimum);
                text.append(LIMIT);
                text.append(maximum - minimum);
            } else {
                text.append(LIMIT);
                text.append(maximum);
            }
        }
        final OSQLSynchQuery<OIdentifiable> query = new OSQLSynchQuery<OIdentifiable>(
                text.toString());
        return new OrientElementIterable<Vertex>(((OrientBaseGraph) graph),
                ((OrientBaseGraph) graph).getRawGraph().query(query));
    }

    @Override
    public Iterable<Edge> edges() {
        if (maximum == 0)
            return Collections.emptyList();

        if (((OrientBaseGraph) graph).isUseLightweightEdges())
            return super.edges();

        final StringBuilder text = new StringBuilder();

        // GO DIRECTLY AGAINST E CLASS AND SUB-CLASSES
        text.append(QUERY_SELECT_FROM);

        if (((OrientBaseGraph) graph).isUseClassForEdgeLabel()
                && labels != null && labels.length > 0) {
            // FILTER PER CLASS SAVING CHECKING OF LABEL PROPERTY
            if (labels.length == 1)
                // USE THE CLASS NAME
                text.append(OrientBaseGraph.encodeClassName(labels[0]));
            else {
                // MULTIPLE CLASSES NOT SUPPORTED DIRECTLY: CREATE A SUB-QUERY
                return super.edges();
            }
        } else
            text.append(OrientEdge.CLASS_NAME);

        // APPEND ALWAYS WHERE 1=1 TO MAKE CONCATENATING EASIER
        text.append(QUERY_WHERE);

        manageFilters(text);
        if (!((OrientBaseGraph) graph).isUseClassForEdgeLabel())
            manageLabels(text);

        final OSQLSynchQuery<OIdentifiable> query = new OSQLSynchQuery<OIdentifiable>(
                text.toString());

        if (maximum > 0 && maximum < Long.MAX_VALUE)
            query.setLimit((int) maximum);

        return new OrientElementIterable<Edge>(((OrientBaseGraph) graph),
                ((OrientBaseGraph) graph).getRawGraph().query(query));
    }

    private void manageLabels(final StringBuilder text) {
        if (labels != null && labels.length > 0) {
            // APPEND LABELS
            text.append(QUERY_LABEL_BEGIN);
            for (int i = 0; i < labels.length; ++i) {
                if (i > 0)
                    text.append(QUERY_SEPARATOR);
                text.append(QUERY_STRING);
                text.append(labels[i]);
                text.append(QUERY_STRING);
            }
            text.append(QUERY_LABEL_END);
        }
    }

    private void manageFilters(final StringBuilder text) {
        for (HasContainer has : hasContainers) {
            text.append(QUERY_FILTER_AND);

            if (has.compare == Compare.EQUAL && has.values.length > 1) {
                // IN
                text.append(has.key);
                text.append(OPERATOR_IN);
                text.append(COLLECTION_BEGIN);
<commit_msg>OrientDB: supported Fetch Plan in Query<commit_after>package com.tinkerpop.blueprints.impls.orient;

import com.orientechnologies.orient.core.db.record.OIdentifiable;
import com.orientechnologies.orient.core.sql.query.OSQLSynchQuery;
import com.tinkerpop.blueprints.Edge;
import com.tinkerpop.blueprints.Graph;
import com.tinkerpop.blueprints.Query;
import com.tinkerpop.blueprints.Vertex;
import com.tinkerpop.blueprints.util.DefaultGraphQuery;

import java.util.Collections;

/**
 * OrientDB implementation for Graph query.
 *
 * @author <NAME> (http://www.orientechnologies.com)
 */
public class OrientGraphQuery extends DefaultGraphQuery {

    protected static final char SPACE = ' ';
    protected static final String OPERATOR_DIFFERENT = "<>";
    protected static final String OPERATOR_IS_NOT = "is not";
    protected static final String OPERATOR_LET = "<=";
    protected static final char OPERATOR_LT = '<';
    protected static final String OPERATOR_GTE = ">=";
    protected static final char OPERATOR_GT = '>';
    protected static final String OPERATOR_EQUALS = "=";
    protected static final String OPERATOR_IS = "is";
    protected static final String OPERATOR_IN = " in ";

    protected static final String QUERY_FILTER_AND = " and ";
    protected static final String QUERY_FILTER_OR = " or ";
    protected static final char QUERY_STRING = '\'';
    protected static final char QUERY_SEPARATOR = ',';
    protected static final char COLLECTION_BEGIN = '[';
    protected static final char COLLECTION_END = ']';
    protected static final char PARENTHESIS_BEGIN = '(';
    protected static final char PARENTHESIS_END = ')';
    protected static final String QUERY_LABEL_BEGIN = " and label in [";
    protected static final String QUERY_LABEL_END = "]";
    protected static final String QUERY_WHERE = " where 1=1";
    protected static final String QUERY_SELECT_FROM = "select from ";
    protected static final String LIMIT = " LIMIT ";
    protected static final String SKIP = " SKIP ";
    
    protected String fetchPlan;

    public OrientGraphQuery(final Graph iGraph) {
        super(iGraph);
    }

    public Query labels(final String... labels) {
        this.labels = labels;
        return this;
    }

    @Override
    public Iterable<Vertex> vertices() {
        if (maximum == 0)
            return Collections.emptyList();

        final StringBuilder text = new StringBuilder();

        // GO DIRECTLY AGAINST E CLASS AND SUB-CLASSES
        text.append(QUERY_SELECT_FROM);

        if (((OrientBaseGraph) graph).isUseClassForVertexLabel()
                && labels != null && labels.length > 0) {
            // FILTER PER CLASS SAVING CHECKING OF LABEL PROPERTY
            if (labels.length == 1)
                // USE THE CLASS NAME
                text.append(OrientBaseGraph.encodeClassName(labels[0]));
            else {
                // MULTIPLE CLASSES NOT SUPPORTED DIRECTLY: CREATE A SUB-QUERY
                return super.vertices();
            }
        } else
            text.append(OrientVertex.CLASS_NAME);

        // APPEND ALWAYS WHERE 1=1 TO MAKE CONCATENATING EASIER
        text.append(QUERY_WHERE);
        manageFilters(text);
        if (!((OrientBaseGraph) graph).isUseClassForVertexLabel())
            manageLabels(text);

        if (maximum > 0 && maximum < Long.MAX_VALUE) {
            if (minimum > 0 && maximum < Long.MAX_VALUE) {
                text.append(SKIP);
                text.append(minimum);
                text.append(LIMIT);
                text.append(maximum - minimum);
            } else {
                text.append(LIMIT);
                text.append(maximum);
            }
        }
        final OSQLSynchQuery<OIdentifiable> query = new OSQLSynchQuery<OIdentifiable>(
                text.toString());
        
        if( fetchPlan != null )
        	query.setFetchPlan(fetchPlan);
        
        return new OrientElementIterable<Vertex>(((OrientBaseGraph) graph),
                ((OrientBaseGraph) graph).getRawGraph().query(query));
    }

    @Override
    public Iterable<Edge> edges() {
        if (maximum == 0)
            return Collections.emptyList();

        if (((OrientBaseGraph) graph).isUseLightweightEdges())
            return super.edges();

        final StringBuilder text = new StringBuilder();

        // GO DIRECTLY AGAINST E CLASS AND SUB-CLASSES
        text.append(QUERY_SELECT_FROM);

        if (((OrientBaseGraph) graph).isUseClassForEdgeLabel()
                && labels != null && labels.length > 0) {
            // FILTER PER CLASS SAVING CHECKING OF LABEL PROPERTY
            if (labels.length == 1)
                // USE THE CLASS NAME
                text.append(OrientBaseGraph.encodeClassName(labels[0]));
            else {
                // MULTIPLE CLASSES NOT SUPPORTED DIRECTLY: CREATE A SUB-QUERY
                return super.edges();
            }
        } else
            text.append(OrientEdge.CLASS_NAME);

        // APPEND ALWAYS WHERE 1=1 TO MAKE CONCATENATING EASIER
        text.append(QUERY_WHERE);

        manageFilters(text);
        if (!((OrientBaseGraph) graph).isUseClassForEdgeLabel())
            manageLabels(text);

        final OSQLSynchQuery<OIdentifiable> query = new OSQLSynchQuery<OIdentifiable>(
                text.toString());

        if( fetchPlan != null )
        	query.setFetchPlan(fetchPlan);
        
        if (maximum > 0 && maximum < Long.MAX_VALUE)
            query.setLimit((int) maximum);

        return new OrientElementIterable<Edge>(((OrientBaseGraph) graph),
                ((OrientBaseGraph) graph).getRawGraph().query(query));
    }

	public String getFetchPlan() {
		return fetchPlan;
	}

	public void setFetchPlan(final String fetchPlan) {
		this.fetchPlan = fetchPlan;
	}
	
    protected void manageLabels(final StringBuilder text) {
        if (labels != null && labels.length > 0) {
            // APPEND LABELS
            text.append(QUERY_LABEL_BEGIN);
            for (int i = 0; i < labels.length; ++i) {
                if (i > 0)
                    text.append(QUERY_SEPARATOR);
                text.append(QUERY_STRING);
                text.append(labels[i]);
                text.append(QUERY_STRING);
            }
            text.append(QUERY_LABEL_END);
        }
    }

    protected void manageFilters(final StringBuilder text) {
        for (HasContainer has : hasContainers) {
            text.append(QUERY_FILTER_AND);

            if (has.compare == Compare.EQUAL && has.values.length > 1) {
                // IN
                text.append(has.key);
                text.append(OPERATOR_IN);
                text.append(COLLECTION_BEGIN);

{'fraction_non_alphanumeric': 0.0993894427699204, 'fraction_numerical': 0.003246000463714352, 'mean_word_length': 2.2528908999497235, 'pattern_counts': {'":': 0, '<': 35, '<?xml version=': 0, '>': 43, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2684007', 'n_tokens_mistral': 3772, 'n_tokens_neox': 3507, 'n_words': 878}