Package com.orientechnologies.orient.core.sql.operator

Source Code of com.orientechnologies.orient.core.sql.operator.OQueryOperator

/*
  *
  *  *  Copyright 2014 Orient Technologies LTD (info(at)orientechnologies.com)
  *  *
  *  *  Licensed under the Apache License, Version 2.0 (the "License");
  *  *  you may not use this file except in compliance with the License.
  *  *  You may obtain a copy of the License at
  *  *
  *  *       http://www.apache.org/licenses/LICENSE-2.0
  *  *
  *  *  Unless required by applicable law or agreed to in writing, software
  *  *  distributed under the License is distributed on an "AS IS" BASIS,
  *  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  *  *  See the License for the specific language governing permissions and
  *  *  limitations under the License.
  *  *
  *  * For more information: http://www.orientechnologies.com
  *
  */
package com.orientechnologies.orient.core.sql.operator;

import java.util.List;

import com.orientechnologies.common.profiler.OProfilerMBean;
import com.orientechnologies.orient.core.Orient;
import com.orientechnologies.orient.core.command.OCommandContext;
import com.orientechnologies.orient.core.db.record.OIdentifiable;
import com.orientechnologies.orient.core.id.ORID;
import com.orientechnologies.orient.core.index.OIndex;
import com.orientechnologies.orient.core.index.OIndexCursor;
import com.orientechnologies.orient.core.index.OIndexDefinition;
import com.orientechnologies.orient.core.metadata.schema.OClass;
import com.orientechnologies.orient.core.record.impl.ODocument;
import com.orientechnologies.orient.core.sql.OIndexSearchResult;
import com.orientechnologies.orient.core.sql.filter.OSQLFilterCondition;
import com.orientechnologies.orient.core.sql.operator.math.*;

/**
* Query Operators. Remember to handle the operator in OQueryItemCondition.
*
* @author Luca Garulli
*/
public abstract class OQueryOperator {

  public static enum ORDER {
    /**
     * Used when order compared to other operator can not be evaluated or has no consequences.
     */
    UNKNOWNED,
    /**
     * Used when this operator must be before the other one
     */
    BEFORE,
    /**
     * Used when this operator must be after the other one
     */
    AFTER,
    /**
     * Used when this operator is equal the other one
     */
    EQUAL
  }

  /**
   * Default operator order. can be used by additional operator to locate themself relatively to default ones.
   * <p/>
   * WARNING: ORDER IS IMPORTANT TO AVOID SUB-STRING LIKE "IS" and AND "INSTANCEOF": INSTANCEOF MUST BE PLACED BEFORE! AND ALSO FOR
   * PERFORMANCE (MOST USED BEFORE)
   */
  protected static final Class<?>[] DEFAULT_OPERATORS_ORDER = { OQueryOperatorEquals.class, OQueryOperatorAnd.class,
      OQueryOperatorOr.class, OQueryOperatorNotEquals.class, OQueryOperatorNot.class, OQueryOperatorMinorEquals.class,
      OQueryOperatorMinor.class, OQueryOperatorMajorEquals.class, OQueryOperatorContainsAll.class, OQueryOperatorMajor.class,
      OQueryOperatorLike.class, OQueryOperatorMatches.class, OQueryOperatorInstanceof.class, OQueryOperatorIs.class,
      OQueryOperatorIn.class, OQueryOperatorContainsKey.class, OQueryOperatorContainsValue.class, OQueryOperatorContainsText.class,
      OQueryOperatorContains.class, OQueryOperatorTraverse.class, OQueryOperatorBetween.class, OQueryOperatorPlus.class,
      OQueryOperatorMinus.class, OQueryOperatorMultiply.class, OQueryOperatorDivide.class, OQueryOperatorMod.class };

  public final String               keyword;
  public final int                  precedence;
  public final int                  expectedRightWords;
  public final boolean              unary;
  public final boolean              expectsParameters;

  protected OQueryOperator(final String iKeyword, final int iPrecedence, final boolean iUnary) {
    this(iKeyword, iPrecedence, iUnary, 1, false);
  }

  protected OQueryOperator(final String iKeyword, final int iPrecedence, final boolean iUnary, final int iExpectedRightWords) {
    this(iKeyword, iPrecedence, iUnary, iExpectedRightWords, false);
  }

  protected OQueryOperator(final String iKeyword, final int iPrecedence, final boolean iUnary, final int iExpectedRightWords,
      final boolean iExpectsParameters) {
    keyword = iKeyword;
    precedence = iPrecedence;
    unary = iUnary;
    expectedRightWords = iExpectedRightWords;
    expectsParameters = iExpectsParameters;
  }

  public abstract Object evaluateRecord(final OIdentifiable iRecord, ODocument iCurrentResult,
      final OSQLFilterCondition iCondition, final Object iLeft, final Object iRight, OCommandContext iContext);

  /**
   * Returns hint how index can be used to calculate result of operator execution.
   *
   * @param iLeft
   *          Value of left query parameter.
   * @param iRight
   *          Value of right query parameter.
   * @return Hint how index can be used to calculate result of operator execution.
   */
  public abstract OIndexReuseType getIndexReuseType(Object iLeft, Object iRight);

  public OIndexSearchResult getOIndexSearchResult(OClass iSchemaClass, OSQLFilterCondition iCondition,
      List<OIndexSearchResult> iIndexSearchResults, OCommandContext context) {

    return null;
  }

  /**
   * Performs index query and returns index cursor which presents subset of index data which corresponds to result of execution of
   * given operator.
   *
   * <p/>
   * Query that should be executed can be presented like: [[property0 = keyParam0] and [property1 = keyParam1] and] propertyN
   * operator keyParamN.
   * <p/>
   * It is supped that index which passed in as parameter is used to index properties listed above and responsibility of given
   * method execute query using given parameters.
   * <p/>
   * Multiple parameters are passed in to implement composite indexes support.
   *
   *
   * @param iContext
   * @param index
   *          Instance of index that will be used to calculate result of operator execution.
   * @param keyParams
   *          Parameters of query is used to calculate query result.
   * @param ascSortOrder
   *          Data returned by cursors should be sorted in ascending or descending order.
   * @return Cursor instance if index can be used to evaluate result of execution of given operator and <code>null</code> otherwise.
   */
  public OIndexCursor executeIndexQuery(OCommandContext iContext, OIndex<?> index, final List<Object> keyParams,
      boolean ascSortOrder) {
    return null;
  }

  @Override
  public String toString() {
    return keyword;
  }

  /**
   * Default State-less implementation: does not save parameters and just return itself
   *
   * @param iParams
   * @return
   */
  public OQueryOperator configure(final List<String> iParams) {
    return this;
  }

  public String getSyntax() {
    return "<left> " + keyword + " <right>";
  }

  public abstract ORID getBeginRidRange(final Object iLeft, final Object iRight);

  public abstract ORID getEndRidRange(final Object iLeft, final Object iRight);

  public boolean isUnary() {
    return unary;
  }

  /**
   * Check priority of this operator compare to given operator.
   *
   * @param other
   * @return ORDER place of this operator compared to given operator
   */
  public ORDER compare(OQueryOperator other) {
    final Class<?> thisClass = this.getClass();
    final Class<?> otherClass = other.getClass();

    int thisPosition = -1;
    int otherPosition = -1;
    for (int i = 0; i < DEFAULT_OPERATORS_ORDER.length; i++) {
      // subclass of default operators inherit their parent ordering
      final Class<?> clazz = DEFAULT_OPERATORS_ORDER[i];
      if (clazz.isAssignableFrom(thisClass)) {
        thisPosition = i;
      }
      if (clazz.isAssignableFrom(otherClass)) {
        otherPosition = i;
      }
    }

    if (thisPosition == -1 || otherPosition == -1) {
      // can not decide which comes first
      return ORDER.UNKNOWNED;
    }

    if (thisPosition > otherPosition) {
      return ORDER.AFTER;
    } else if (thisPosition < otherPosition) {
      return ORDER.BEFORE;
    }

    return ORDER.EQUAL;
  }

  protected void updateProfiler(final OCommandContext iContext, final OIndex<?> index, final List<Object> keyParams,
      final OIndexDefinition indexDefinition) {
    if (iContext.isRecordingMetrics())
      iContext.updateMetric("compositeIndexUsed", +1);

    final OProfilerMBean profiler = Orient.instance().getProfiler();
    if (profiler.isRecording()) {
      profiler.updateCounter(profiler.getDatabaseMetric(index.getDatabaseName(), "query.indexUsed"), "Used index in query", +1);

      int params = indexDefinition.getParamCount();
      if (params > 1) {
        final String profiler_prefix = profiler.getDatabaseMetric(index.getDatabaseName(), "query.compositeIndexUsed");

        profiler.updateCounter(profiler_prefix, "Used composite index in query", +1);
        profiler.updateCounter(profiler_prefix + "." + params, "Used composite index in query with " + params + " params", +1);
        profiler.updateCounter(profiler_prefix + "." + params + '.' + keyParams.size(), "Used composite index in query with "
            + params + " params and " + keyParams.size() + " keys", +1);
      }
    }
  }
}
TOP

Related Classes of com.orientechnologies.orient.core.sql.operator.OQueryOperator

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.