All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.gemstone.gemfire.cache.query.internal.AbstractCompiledValue Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) 2010-2015 Pivotal Software, Inc. All rights reserved.
 *
 * 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. See accompanying
 * LICENSE file.
 */
package com.gemstone.gemfire.cache.query.internal;

import java.util.*;
import com.gemstone.gemfire.cache.query.*;
import com.gemstone.gemfire.cache.query.types.*;
import com.gemstone.gemfire.cache.query.internal.parse.OQLLexerTokenTypes;
import com.gemstone.gemfire.cache.query.internal.types.StructTypeImpl;
import com.gemstone.gemfire.internal.i18n.LocalizedStrings;

//import com.gemstone.gemfire.cache.query.internal.types.TypeUtils;
/**
 * Class Description
 * 
 * @version $Revision: 1.1 $
 * @author ericz
 * @author asif
 */
public abstract class AbstractCompiledValue implements CompiledValue, Filter,
    OQLLexerTokenTypes {

  ObjectType typecast = null;

  public ObjectType getTypecast() {
    return this.typecast;
  }

  // used for typecasts
  void setTypecast(ObjectType objectType) {
    this.typecast = objectType;
  }

  /** Default impl returns null as N/A */
  public List getPathOnIterator(RuntimeIterator itr, ExecutionContext context)
      throws TypeMismatchException, AmbiguousNameException {
    return null;
  }

  /**
   * Asif : This function has a meaningful implementaion only in
   * CompiledComparison & Compiled Undefined
   */
   
  public SelectResults filterEvaluate(ExecutionContext context,
      SelectResults iterationLimit, boolean completeExpansionNeeded,
      CompiledValue iterOperands, RuntimeIterator[] indpndntItrs, boolean isIntersection, boolean conditioningNeeded, boolean evalProj)
      throws FunctionDomainException, TypeMismatchException,
      NameResolutionException, QueryInvocationTargetException {
    Support
        .assertionFailed("This method should not have invoked as CompieldComparison & CompiledUndefined are the only classes on which this invocation should have occured ");
    return null;
  }

  // determine whether should evaluate as filters, and what indexes will
  // be used
  // default is true for evalAsFilter if independent of iterator, otherwise
  // calls protGetPlanInfo (which defaults to false for evalAsFilter)
  public PlanInfo getPlanInfo(ExecutionContext context)
      throws FunctionDomainException, TypeMismatchException,
      NameResolutionException, QueryInvocationTargetException {
    PlanInfo planInfo;
    //RuntimeIterator itr = context.getCurrentIterator();
    //Support.Assert(itr != null);
    if (!isDependentOnCurrentScope(context)) {
      // Asif :If the current junction or CompliedComparison
      // happens to be independent , then its basic nature to be
      // evaluatable as Filter depends upon its boolean value.
      // If the operand is part of a Junction , then if it evaluates
      // to false, it can always support filterEvaluatable. But if it
      // evaluates to true, its nature is not to support filterEvaluatable
      // The gist being that if an independent operand evaluates to
      // false & if the junction is AND , the whole junction can be
      // filter evaluatable. But if it evaluates to true, then by itself
      // it cannot make junction filterEvaluatable, but if there exists
      // any other operand which had an index or is independent ( with value
      // as false), then the current operand can get AuxFilterEvaluated
      // along with the other auxFilterEvaluatable operand.
      // But if it is an OR junction , a true value would mean that the
      // Junction cannot be evaluated as filter , but if it is false then
      // junction can be evaluated as a filter , provided all the operands
      // are also filterEvaluatable.
      planInfo = new PlanInfo();
      Object result = evaluate(context);
      if (!(result instanceof Boolean))
          throw new TypeMismatchException(LocalizedStrings.AbstractCompiledValue_BOOLEAN_VALUE_EXPECTED_NOT_TYPE_0.toLocalizedString(result.getClass().getName()));
      boolean b = ((Boolean) result).booleanValue();
      planInfo.evalAsFilter = !b;
      return planInfo;
    }
    planInfo = protGetPlanInfo(context);
    return planInfo;
  }

  public Set computeDependencies(ExecutionContext context)
      throws TypeMismatchException, AmbiguousNameException,
      NameResolutionException {
    // default implementation has no dependencies
    // override in subclasses to add dependencies
    return Collections.EMPTY_SET;
  }

  public boolean isDependentOnIterator(RuntimeIterator itr,
      ExecutionContext context) {
    return context.isDependentOn(this, itr);
  }

  /**
   * Return true if this value is dependent on any iterator in the current scope
   */
  public boolean isDependentOnCurrentScope(ExecutionContext context) {
    return context.isDependentOnCurrentScope(this);
  }

  // Invariant: the receiver is dependent on the current iterator.
  protected PlanInfo protGetPlanInfo(ExecutionContext context)
      throws FunctionDomainException, TypeMismatchException,
      NameResolutionException, QueryInvocationTargetException {
    return new PlanInfo(); // default behavior
  }

  // Utility methods
  /**
   * return operator used when terms are reversed, maintaining the semantics e.g
   * salary < 100000 swapped to 100000 > salary, salary >= 100000 swapped to
   * 100000 <= salary or salary = 100000 swapped to salary = 100000
   */
  protected int reflectOperator(int op) {
    switch (op) {
      case TOK_EQ:
        return TOK_EQ;
      case TOK_NE:
        return TOK_NE;
      case TOK_LT:
        return TOK_GT;
      case TOK_GE:
        return TOK_LE;
      case TOK_LE:
        return TOK_GE;
      case TOK_GT:
        return TOK_LT;
      default:
        Support.assertionFailed("unknown operator: " + op);
        throw new Error("this line of code can never be executed");
    }
  }

  /**
   * return operator to invert the value of the result. e.g. salary < 100000
   * will become salary >= 100000 or salary = 100000 becomes salary != 100000
   */
  protected int inverseOperator(int op) {
    switch (op) {
      case LITERAL_and:
        return LITERAL_or;
      case LITERAL_or:
        return LITERAL_and;
      case TOK_EQ:
        return TOK_NE;
      case TOK_NE:
        return TOK_EQ;
      case TOK_LT:
        return TOK_GE;
      case TOK_GE:
        return TOK_LT;
      case TOK_LE:
        return TOK_GT;
      case TOK_GT:
        return TOK_LE;
      default:
        Support.assertionFailed("unknown operator: " + op);
        throw new Error("this line of code can never be executed");
    }
  }

  /**
   * this is a lower level filter evaluation call. Most Filters do nothing
   * different here than a normal filterEvaluate. This is here for benefit of
   * nested CompiledJunctions: filterEvaluate is called first, then
   * auxFilterEvaluate is called on the operands that have been organized to be
   * filters
   * 
   * @see CompiledJunction#filterEvaluate
   */
  public SelectResults auxFilterEvaluate(ExecutionContext context,
      SelectResults intermediateResults) throws FunctionDomainException,
      TypeMismatchException, NameResolutionException,
      QueryInvocationTargetException {
    return filterEvaluate(context, intermediateResults);
  }

  public SelectResults filterEvaluate(ExecutionContext context,
      SelectResults intermediateResults) throws FunctionDomainException,
      TypeMismatchException, NameResolutionException,
      QueryInvocationTargetException {
    // for the general case of filter evaluation, most compiled values
    // can only be evaluated in this way if they are independent of the current
    // iterator,
    // This method is also only applicable in places where a boolean value is
    // expected.
    //RuntimeIterator itr = context.getCurrentIterator();
    //Support.Assert(itr != null);
    // if it is possible for the following assertion to be false,
    // then this method as well as protGetPlanInfo must be overridden
    Support.Assert(!isDependentOnCurrentScope(context));
    Object result = evaluate(context);
    if (result == null || result == QueryService.UNDEFINED)
        return new ResultsBag(intermediateResults.getCollectionType()
            .getElementType(), 0, context.getCachePerfStats());
    if (!(result instanceof Boolean))
        throw new TypeMismatchException(LocalizedStrings.AbstractCompiledValue_BOOLEAN_VALUE_EXPECTED_NOT_TYPE_0.toLocalizedString(result.getClass().getName()));
    boolean b = ((Boolean) result).booleanValue();
    //Asif : Boolean true, means the cartesian of all the RuntimeIterators
    // indicated by null value. A false means an empty ResultSet
    if (b) {
      return null;
    }
    else {
      //Asif : We need to return either an empty ResultSet or an empty
      // StructSet based
      // on the number of iterators in the current scope.
      SelectResults emptySet = null;
      List iterators = context.getCurrentIterators();
      int len = iterators.size();
      if (len == 1) {
        emptySet = new ResultsBag(((RuntimeIterator) iterators.get(0))
            .getElementType(), 0,  context.getCachePerfStats());
      }
      else {
        String fieldNames[] = new String[len];
        ObjectType fieldTypes[] = new ObjectType[len];
        for (int i = 0; i < len; i++) {
          RuntimeIterator iter = (RuntimeIterator) iterators.get(i);
          fieldNames[i] = iter.getInternalId();
          fieldTypes[i] = iter.getElementType();
        }
        emptySet = new StructBag(0,
                                 new StructTypeImpl(fieldNames, fieldTypes), 
                                 context.getCachePerfStats());
      }
      return emptySet;
    }
  }

  // This function needs to be appropriately overridden in the derived classes
  public void generateCanonicalizedExpression(StringBuffer clauseBuffer,
      ExecutionContext context) throws AmbiguousNameException,
      TypeMismatchException, NameResolutionException {
    clauseBuffer.insert(0, System.currentTimeMillis());
    clauseBuffer.insert(0, this.getClass());
    clauseBuffer.insert(0, '.');
  }
  
  public void getRegionsInQuery(Set regionsInQuery, Object[] parameters) {
    for (Iterator itr = getChildren().iterator(); itr.hasNext(); ) {
      CompiledValue v = (CompiledValue)itr.next();
      if (v == null) {
        throw new NullPointerException(LocalizedStrings.AbstractCompiledValue_GOT_NULL_AS_A_CHILD_FROM_0.toLocalizedString(this));
      }
      v.getRegionsInQuery(regionsInQuery, parameters);
    }
  }
  
  /** Get the CompiledValues that this owns */
  public List getChildren() {
    return Collections.EMPTY_LIST;
  }
  public int getSizeEstimate(ExecutionContext context)throws FunctionDomainException, TypeMismatchException, NameResolutionException, QueryInvocationTargetException  {
	  throw new UnsupportedOperationException("This method should not have been invoked");
  }
  public void visitNodes(NodeVisitor visitor) {
    visitor.visit(this);
    for (Iterator itr = getChildren().iterator(); itr.hasNext(); ) {
      if (!visitor.visit((CompiledValue)itr.next())) {
        break;
      }
    }
  }
    
  public boolean isProjectionEvaluationAPossibility(ExecutionContext context) throws FunctionDomainException, TypeMismatchException, NameResolutionException, QueryInvocationTargetException
  {
    throw new UnsupportedOperationException("This method should not have been invoked");
  }
  
  public boolean isLimitApplicableAtIndexLevel(ExecutionContext context) throws FunctionDomainException, TypeMismatchException, NameResolutionException, QueryInvocationTargetException  {
    throw new UnsupportedOperationException("This method should not have been invoked");
  }
  
  public boolean isOrderByApplicableAtIndexLevel(ExecutionContext context, String canonicalizedOrderByClause) throws FunctionDomainException, TypeMismatchException, NameResolutionException, QueryInvocationTargetException {
    throw new UnsupportedOperationException("This method should not have been invoked");
  }
  
  public boolean isConditioningNeededForIndex(RuntimeIterator independentIter, ExecutionContext context,  boolean completeExpnsNeeded) throws AmbiguousNameException, TypeMismatchException, NameResolutionException {
    throw new UnsupportedOperationException("This method should not have been invoked");
  }
  
  public int getOperator() {
    throw new UnsupportedOperationException("This method should not have been invoked");
  }
  
  public boolean isBetterFilter(Filter comparedTo, ExecutionContext context, int thisSize)  throws FunctionDomainException, TypeMismatchException, NameResolutionException, QueryInvocationTargetException {
    throw new UnsupportedOperationException("This method should not have been invoked");
  }

  public CompiledValue getReceiver() {
      throw new UnsupportedOperationException("This method should not have been invoked");
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy