Example #1
0
// we want BiLogic to be cacheable
NABoolean BiLogic::isCacheableExpr(CacheWA& cwa)
{
  if (cwa.getPhase() >= CmpMain::BIND && getArity() == 2) {
    if (getOperatorType() == ITM_AND) {
      ItemExpr *leftC=child(0), *rightC=child(1);
      // we want to descend to both left & right
      // so cwa.usedKeys & cwa.keyCols get updated
      NABoolean leftOK = leftC->isCacheableExpr(cwa);
      NABoolean rightOK = rightC->isCacheableExpr(cwa);
      // return FALSE if both left & right are not cacheable.
      if (!leftOK && !rightOK) 
        return FALSE;

      // allow "select * from t where k1=1 and k2=2" as potentially cacheable
      return TRUE;
      // the definitive check whether a query's predicate covers
      // all referenced tables' key columns can be (and is) done
      // only in RelRoot::isCacheableExpr() when cwa.usedKeys &
      // cwa.keyCols are fully defined. Otherwise, queries like
      //   "select * from t1 join t2 on a=x and a=7 where x=7"
      // may be incorrectly rejected as non-cacheable if t1 has
      // primary key(a) and t2 has primary key(x).
    }
    else if (getOperatorType() == ITM_OR) {
      return TRUE;
      // ORs can be cacheable but are not necessarily
      // parameterizable, see Bilogic::normalizeForCache below.
    }
  }
  return FALSE;
}
short BiArithCount::codeGen(Generator * generator)
{
  Attributes ** attr;
  ExpGenerator * eg = generator->getExpGenerator();
  
  if (eg->genItemExpr(this, &attr, (1+getArity()), -1) == 1)
    return 0;

  // if temp space is needed for this operation, set it.
  if (attr[0]->isComplexType())
    {
      eg->addTempsLength(((ComplexType *)attr[0])->setTempSpaceInfo(getOperatorType(),
#pragma nowarn(1506)   // warning elimination 
								    eg->getTempsLength()));
#pragma warn(1506)  // warning elimination 
    }
			      
  ex_arith_count_clause * arith_clause =
    new(generator->getSpace()) 
    ex_arith_count_clause(getOperatorType(), 
			  attr, 
			  generator->getSpace());
  
  generator->getExpGenerator()->linkClause(this, arith_clause);

  return 0;
}
short Aggregate::codeGen(Generator * generator)
{
  Attributes ** attr;

  // If this Aggr has already been codeGenned, then bug out early.
  //
  MapInfo * aggrMapInfo = generator->getMapInfoAsIs(getValueId());
  if (aggrMapInfo && aggrMapInfo->isCodeGenerated())
    return 0;

  if (getOperatorType() != ITM_ONE_ROW)
  {
    if (generator->getExpGenerator()->genItemExpr(this, &attr, (1+getArity()), -1) == 1)
      return 0;
  }

  ex_clause * clause = 0;
  
  switch (getOperatorType())
    {
    case ITM_ONE_ROW:
      {
        Int32 degree = 0;
        findnumleaves(this, degree); // degree has number of leaves in the tree

        if (generator->getExpGenerator()->genItemExpr(this, &attr, (1+degree),
                                                               -1) == 1)
          return 0;

	clause =
	  new(generator->getSpace()) ex_aggr_one_row_clause(getOperatorType(),
							    (short)(1+degree), 
							    attr,
							    generator->getSpace());
      }
      break;

    case ITM_ANY_TRUE_MAX:
      {
	clause =
	  new(generator->getSpace()) ex_aggr_any_true_max_clause(getOperatorType(),
								 (short)(1+getArity()), 
								 attr, generator->getSpace());
      }
      break;
      
    default:
      break;
      
    }

  GenAssert(clause, "Aggregate::codeGen -- missing clause!");
  generator->getExpGenerator()->linkClause(this, clause);  

  return 0;
}
// Lookup the other table involved in this RI relationship,
// and find the other constraint in the other NATable constraint list.
// I.e., if called by a UniqueConstraint, this looks in the referencing table's
// refConstraints to find the FK constraint passed in riInfo;
// if called by a RefConstraint, this looks in the referenced table's
// uniqueConstraints to find the UC constraint passed in riInfo.
//
AbstractRIConstraint *AbstractRIConstraint::findConstraint(
				  BindWA *bindWA,
				  const ComplementaryRIConstraint &riInfo) const
{
  // Lookup errors should be impossible, due to Ansi transaction semantics
  // during compilation of a query, so no need for fancy diags, just assert
  // (should only happen if catalog corrupt or txn seriously haywire)

  CorrName tempName(riInfo.tableName_);
  NATable *naTable = bindWA->getNATable(tempName, FALSE);
  if (!naTable) return NULL;

  const AbstractRIConstraintList otherConstraints =
    (getOperatorType() == ITM_UNIQUE_CONSTRAINT) ?
      naTable->getRefConstraints() : naTable->getUniqueConstraints();

  // The find() from Collections template doesn't work for us, so roll our own
  AbstractRIConstraint *c;
  for (CollIndex i = 0; i < otherConstraints.entries(); i++)
  {
    c = otherConstraints[i];
    if (c->getConstraintName() == riInfo.constraintName_) return c;
  }
  *CmpCommon::diags() << DgSqlCode(-4353)
        << DgTableName(naTable->getTableName().getQualifiedNameAsAnsiString()) ;
  bindWA->setErrStatus();
  return NULL;

} // AbstractRIConstraint::findConstraint
void
ElemDDLList::initializeDataMembers(ElemDDLNode * commaExpr,
                                   ElemDDLNode * otherExpr)
{
  pParentListNode_ = NULL;

  setChild(INDEX_ELEM_DDL_LIST_CHILD, commaExpr);
  setChild(INDEX_ELEM_DDL_NODE_CHILD, otherExpr);

  // Besides pointing to a list node (a non-leaf node in
  // the left linear tree), commaExpr may also point to
  // a leaf node (which is the first element in the list)

  ComASSERT(commaExpr NEQ NULL);

  // Link the child list node (pointed by the pointer commaExpr with
  // the parent list node (this node).  The method traverseList will
  // use this link (in upward direction) to traverse the leaf nodes
  // of the left linear tree more efficiently.
  //
  // Only link the child list node to this node if both parent node
  // (this node) and child node represent the same kind of list node
  // (both nodes are instantiated from the same class; for example,
  // class ElemDDLPartitionList).  Note that class ElemDDLList and
  // class ElemDDLPartitionList represent two different kinds of list
  // nodes (even though class ElemDDLPartitionList is derived from
  // class ElemDDLList).

  ElemDDLList * pChildListNode = commaExpr->castToElemDDLList();
  if (pChildListNode NEQ NULL AND
      getOperatorType() EQU pChildListNode->getOperatorType())
    pChildListNode->setParentListNode(this);
}
short BiRelat::codeGen(Generator * generator)
{
  if (child(0)->getOperatorType() == ITM_ITEM_LIST)
    {
      GenAssert(0, "Multivalued predicated should have been converted in preCodeGen");
    }
  else
    {
      Attributes ** attr;
      
      if (generator->getExpGenerator()->genItemExpr(this, &attr, (1+getArity()), -1) == 1)
	return 0;
      
      ex_comp_clause * comp_clause =
	new(generator->getSpace()) ex_comp_clause(getOperatorType(), attr,
						  generator->getSpace(),
						  getSpecialNulls());

      comp_clause->setCollationEncodeComp(getCollationEncodeComp());
      
      generator->getExpGenerator()->linkClause(this, comp_clause);
    }
  
  return 0;
}
short ItmBitMuxFunction::codeGen(Generator * generator) {
  Attributes ** attr;

  if (generator->getExpGenerator()->genItemExpr(this, &attr, 
						(1 + getArity()), -1) == 1)
    return 0;

  ex_clause * function_clause =
    new(generator->getSpace()) ExpBitMuxFunction(getOperatorType(),
						 1 + getArity(),
						 attr, 
						 generator->getSpace());
  
  generator->getExpGenerator()->linkClause(this, function_clause);

#ifdef _DEBUG
  Lng32 totalLength = 0;

  for(Int32 i = 0; i < getArity(); i++) {
    totalLength += function_clause->getOperand((short)(i+1))->getStorageLength();
  }

  GenAssert(totalLength == function_clause->getOperand(0)->getLength(),
            "Not enough storage allocated for bitmux");
#endif

  return 0;
}
Example #8
0
Node* insertExpression(char* op,Node* exp){
    Node * newExpression = (Node*)calloc(sizeof(Node),1);
    if(newExpression == NULL) {
        if(DEBUG)
            printf("newCall: Error Malloc\n");
        assert(newExpression != NULL);
    }

    newExpression->n_type = getOperatorType(op);
    free(op);

    if(newExpression->n_type == -1 )
        exit(-2);
    if(newExpression->n_type == NODE_PLUS)
        newExpression->n_type = NODE_UNARYPLUS;
    if(newExpression->n_type == NODE_MINUS)
        newExpression->n_type = NODE_UNARYMINUS;
    newExpression->n1 = exp;
    if(exp == NULL)
        newExpression->n1 = createNull();

    newExpression->next = NULL;
    return newExpression;

}
short Assign::codeGen(Generator * generator)
{
  Attributes ** attr;

  // If this Assign has already been codeGenned, then bug out early.
  //
  MapInfo * assignMapInfo = generator->getMapInfoAsIs(getValueId());
  if (assignMapInfo && assignMapInfo->isCodeGenerated())
    return 0;

  // If the left child (lvalue) is already in the map table, then
  // add the Assign value Id to the map table with the same attributes
  // as the let child. Mark the Assign node as codeGenned. Also, allocate
  // space for the attributes.
  //
  MapInfo *leftChildMapInfo = generator->getMapInfoAsIs
    (child(0)->castToItemExpr()->getValueId());
  if (leftChildMapInfo)
    {
      if (! assignMapInfo)
	assignMapInfo = 
	  generator->addMapInfoToThis(generator->getLastMapTable(), 
				      getValueId(), 
				      leftChildMapInfo->getAttr());
      assignMapInfo->codeGenerated();
      attr = new(generator->wHeap()) Attributes*[2];

      // Set the result attribute
      //
      attr[0] = assignMapInfo->getAttr();
    }
  // Otherwise, go ahead and generate the Assign attributes (which also
  // allocates space for the Assign result). Add the left child to the
  // map table with the same attributes as the Assign node.
  //
  else
    {
      generator->getExpGenerator()->genItemExpr(this, &attr, 2, 0);
      generator->addMapInfoToThis(generator->getLastMapTable(), 
				  child(0)->castToItemExpr()->getValueId(),
				  attr[0]);
    }

  attr[0]->resetShowplan();

  // Now, generate code for the right child (rvalue).
  //
  generator->getExpGenerator()->setClauseLinked(FALSE);
  child(1)->codeGen(generator);
  attr[1] = generator->getAttr(child(1));
  generator->getExpGenerator()->setClauseLinked(FALSE);

  ex_conv_clause * conv_clause =
    new(generator->getSpace()) ex_conv_clause
    (getOperatorType(), attr, generator->getSpace());
  generator->getExpGenerator()->linkClause(this, conv_clause);

  return 0;
}
short ItemExpr::codeGen(Generator * generator)
{
  if (getOperatorType() == ITM_NATYPE ||
      getOperatorType() == ITM_NAMED_TYPE_TO_ITEM)
    {
      Attributes ** attr;
      
      if (generator->getExpGenerator()->genItemExpr(this, &attr, (1 + getArity()), -1) == 1)
	return 0;
      return 0;
    }
  
  NAString txt(getText());
  txt += " should never reach ItemExpr::codeGen";
  GenAssert(0, txt);
  return -1;
}
// Traverses the leaf nodes of the left linear tree.
// For each leaf node, invokes the function pointer
// visitNode passed by the caller.  Passes to the
// function pointer visitNode the index of the leaf
// node and the pointer to the left node.  Please
// read the comment header section in the definition
// of operator[] method to find out how the index
// value is determined.
//
// Note that this method visits the leaf nodes
// sequentially, with the first element in the list
// being visited first.
//
// The parameter pOtherNode contains a pointer pointing
// to the parse node that contains the left linear
// tree to be traversed.  This parameter will be
// pass to the function pointer visitNode during
// the invocation of visitNode so the code in 
// visitNode can update the contents of the parse
// node pointed by pOtherNode.
//
// traverseList also passed the index of and the
// pointer to the (currently visited) element to
// visitNode.  These two parameters contain
// information is used by visitNode to update the
// contents of the parse node pointed by pOtherNode.
//
/*virtual*/ void
ElemDDLList::traverseList(ElemDDLNode * pOtherNode,
                          void (*visitNode)(ElemDDLNode * pOtherNode,
                                            CollIndex indexOfLeafNode,
                                            ElemDDLNode * pLeafNode))
{
  OperatorTypeEnum operatorType = getOperatorType();
  ElemDDLList * pElemDDLList = this;
  CollIndex count = 0;
  ElemDDLNode * pElemDDLNode = (ElemDDLNode *)this;

  // go to the first element of the list

  while (pElemDDLNode->getOperatorType() EQU operatorType)
  {
    count++;
    ComASSERT(pElemDDLNode->castToElemDDLList() NEQ NULL);
    pElemDDLList = pElemDDLNode->castToElemDDLList();
    // getChild(0) returns the pointer to the left sub-tree
    ComASSERT(pElemDDLNode->getChild(0) NEQ NULL);
    pElemDDLNode = pElemDDLNode->getChild(0)->castToElemDDLNode();
  }

  // count now contains the number of the list (non-leaf) nodes
  // in the left linear tree.  Note that the number of leaf nodes
  // is equal to the number of list nodes plus one.

  count++;

  // count now contains the number of elements in the list
  // pElemDDLNode now points to the first element in the list
  // pElemDDLList now points to the list node that is the 
  //   parent node of the leaf node representing the first
  //   element in the list
  
  ComASSERT(pElemDDLNode NEQ NULL);

  // visit the first element in the list
  (*visitNode)(pOtherNode, 0, pElemDDLNode);
  
  // visit the remaining elements in the list sequentially

  ComASSERT(count > 1);

  for (CollIndex index = 1; index < count; index ++)
  {
    // getChild(1) returns the pointer to the right sub-tree
    ComASSERT(pElemDDLList NEQ NULL AND
              pElemDDLList->getOperatorType() EQU operatorType AND
              pElemDDLList->getChild(1) NEQ NULL);
    (*visitNode)(pOtherNode,
                 index,
                 pElemDDLList->getChild(1)->castToElemDDLNode());
    pElemDDLList = pElemDDLList->getParentListNode();
  }
  ComASSERT(pElemDDLList EQU NULL OR
            pElemDDLList->getOperatorType() EQU operatorType);
}
Example #12
0
// selectively change literals of a cacheable query into input parameters 
ItemExpr* BiLogic::normalizeForCache(CacheWA& cwa, BindWA& bindWA)
{
  if (nodeIsNormalizedForCache()) { 
    return this; 
  }
  if (getOperatorType() == ITM_AND) {
    return ItemExpr::normalizeForCache(cwa, bindWA);
  }
  else { 
    // do not replace literals in OR predicates
    markAsNormalizedForCache();
    return this;
  }
}
Example #13
0
// return any Scan node from this RelExpr
Scan *RelExpr::getAnyScanNode() const
{
  if (getOperatorType() == REL_SCAN) { 
    return (Scan*)this; 
  }
  Scan *result = NULL;
  Int32 arity = getArity();
  for (Int32 x = 0; x < arity && !result; x++) {
    if (child(x)) { 
      result = child(x)->getAnyScanNode(); 
    }
  }
  return result;
}
short BiArith::codeGen(Generator * generator)
{
  Attributes ** attr;
  ExpGenerator * eg = generator->getExpGenerator();
  
  if (eg->genItemExpr(this, &attr, (1+getArity()), -1) == 1)
    return 0;

  // if temp space is needed for this operation, set it.
  if (attr[0]->isComplexType())
    {
      eg->addTempsLength(((ComplexType *)attr[0])->setTempSpaceInfo(getOperatorType(),
#pragma nowarn(1506)   // warning elimination 
								    eg->getTempsLength()));
#pragma warn(1506)  // warning elimination 
    }
			      
  attr[0]->resetlastdaymonthflag();
  attr[0]->resetlastdayonerrflag();

// Check to see which type of rounding is needed for add_months, date_add
// functions.  Set flags here for use in executor datetime.cpp.
  if (isStandardNormalization())
     attr[0]->setlastdayonerrflag();
  if (isKeepLastDay())
     attr[0]->setlastdaymonthflag();

  ex_arith_clause * arith_clause =
    new(generator->getSpace()) 
    ex_arith_clause(getOperatorType(), attr, generator->getSpace(),
		    (short)getRoundingMode(),
		    getDivToDownscale());

  generator->getExpGenerator()->linkClause(this, arith_clause);

  return 0;
}
// index access (both reference and value) to the
// list represented by this left linear tree
//
//  1 entry     2 entries      > 2 entries
//                [op]             [op]
//    [0]         /  \             /  \
//              [0]  [1]         [op] [2]
//                               /  \
//                             [0]  [1]
//
//  [op] represents ElemDDLList node
//  [0], [1], [2] represent the leaf nodes.  The
//  number between the square brackets represents
//  the index of a leaf node in the list represented
//  by the left linear tree.
//
//  The case of 1 entry is not handled by this class.
//  This case is handled by the class ElemDDLNode.
//
//  The algorithem in this method is very inefficient.
//  If the list is long and you would like to visit
//  all leaf nodes in the left linear tree, please use
//  the method traverseList instead.
//
ElemDDLNode *
ElemDDLList::operator[](CollIndex index)
{
  CollIndex count;
  ElemDDLNode * pElemDDLNode = this;
  
  if (index >= entries())
  {
    return NULL;
  }

  if (index EQU 0)
  {
    for (count = 1; count < entries(); count ++)
    {
      pElemDDLNode = pElemDDLNode->getChild(0)->castToElemDDLNode();
    }
    ComASSERT(pElemDDLNode->getOperatorType() NEQ getOperatorType());
    return pElemDDLNode;
  }

  count = entries() - index;
  while (pElemDDLNode NEQ NULL AND count > 0)
  {
    if (pElemDDLNode->getOperatorType() EQU getOperatorType() AND
        pElemDDLNode->getArity() >= 2)
    {
      if (count EQU 1)
        pElemDDLNode = pElemDDLNode->getChild(1)->castToElemDDLNode();
      else
        pElemDDLNode = pElemDDLNode->getChild(0)->castToElemDDLNode();
    }
    count--;
  }
  ComASSERT(pElemDDLNode->getOperatorType() NEQ getOperatorType());
  return pElemDDLNode;
}
short UnLogic::codeGen(Generator * generator)
{
  Attributes ** attr;

  if (generator->getExpGenerator()->genItemExpr(this, &attr, 
						(1 + getArity()), -1) == 1)
    return 0;

  ex_unlogic_clause * unlogic_clause =
    new(generator->getSpace()) ex_unlogic_clause(getOperatorType(), attr,
						 generator->getSpace());
  
  generator->getExpGenerator()->linkClause(this, unlogic_clause);
  
  return 0;
}
Example #17
0
// append an ascii-version of biarith 
void BiArith::generateCacheKey(CacheWA& cwa) const
{
  ItemExpr::generateCacheKey(cwa); 

  // append an indication of rounding mode for datetime arithmetic functions
  if ( isKeepLastDay() ) cwa += "r1";
  else if ( isStandardNormalization() ) cwa += "r0";

  if (getOperatorType() == ITM_DIVIDE)
    {
      cwa += " arm:"; // arith rounding mode
      char dFmt[20]; 
      str_itoa(roundingMode_, dFmt); 
      cwa += dFmt;
    }
}
Example #18
0
// is it safe to parameterize this selection predicate term?
// change literals of a cacheable query into input parameters 
ItemExpr* BiRelat::normalizeForCache(CacheWA& cwa, BindWA& bindWA)
{
  if (cwa.getPhase() >= CmpMain::BIND) {
    // NB: we assume here that when a query is cacheable because it has a key
    //     equi-predicate, then its key equi-predicates can be parameterized
    if (getArity() == 2) {
      if (getOperatorType() == ITM_EQUAL) {
        // normalizeForCache only constants that can be safely backpatched.
        // part of fix to CR 10-010726-4109.
        ItemExpr *leftC=child(0), *rightC=child(1);
        OperatorTypeEnum leftO = leftC->getOperatorType();

        // fix case 10-061027-0129: discover the potential base column 
        // below the InstantiateNull node
        if ( leftO == ITM_INSTANTIATE_NULL ) {
           leftC = leftC->child(0);
           leftO = leftC->getOperatorType();
        }

        OperatorTypeEnum rightO = rightC->getOperatorType();

        // fix case 10-061027-0129.
        if ( rightO == ITM_INSTANTIATE_NULL ) {
           rightC = rightC->child(0);
           rightO = rightC->getOperatorType();
        }

        if (leftO == ITM_BASECOLUMN && rightO == ITM_CONSTANT) {
          parameterizeMe(cwa, bindWA, child(1),
                         (BaseColumn*)leftC, (ConstValue*)rightC);
        }
        else if (rightO == ITM_BASECOLUMN && leftO == ITM_CONSTANT) {
          parameterizeMe(cwa, bindWA, child(0),
                         (BaseColumn*)rightC, (ConstValue*)leftC);
        }
        else if (leftO == ITM_ITEM_LIST && rightO == ITM_ITEM_LIST) {
          child(0) = ((ItemList*)leftC)->normalizeListForCache
            (cwa, bindWA, (ItemList*)rightC);
        }
      }
      // FIXME: ie, parameterize other binary comparison predicates
      // if we can guarantee the correctness of such parameterizations
    }
  }
  markAsNormalizedForCache();
  return this;
}
short UnLogic::mdamPredGen(Generator * generator,
                           MdamPred ** head,
                           MdamPred ** tail,
                           MdamCodeGenHelper & mdamHelper,
                           ItemExpr * parent)
{
  short rc = 0;     // assume success
  
  enum MdamPred::MdamPredType predType = 
    MdamPred::MDAM_ISNULL; // just to initialize

  // find out what kind of predicate this is
  switch (getOperatorType())
    {
      case ITM_IS_NULL:
      {
        // We distinguish the ASCending and DESCending cases, because
        // the NULL value is considered high for ASCending keys, but
        // low for DESCending.
        predType = MdamPred::MDAM_ISNULL;
        if (mdamHelper.isDescending()) predType = MdamPred::MDAM_ISNULL_DESC;
        break;
      }
      
      case ITM_IS_NOT_NULL:
      {
        predType = MdamPred::MDAM_ISNOTNULL;
        break;
      }
      
      default:
      {
        GenAssert(0, "mdamPredGen: unsupported unary operator.");
        break;
      }
    }

#pragma nowarn(1506)   // warning elimination   
  *head = *tail = new(generator->getSpace())
                    MdamPred(mdamHelper.getDisjunctNumber(),
                             predType,
                             0 /* no expression for IS NULL and IS NOT NULL */);
#pragma warn(1506)  // warning elimination 
  
  return rc;
}
short UnArith::codeGen(Generator * generator)
{
  Attributes ** attr;
  ExpGenerator * eg = generator->getExpGenerator();
  
  if (eg->genItemExpr(this, &attr, (1+getArity()), -1) == 1)
    return 0;


  ex_arith_clause * arith_clause = 
    new(generator->getSpace()) 
    ex_arith_clause(getOperatorType(), attr, generator->getSpace(),
                    0, FALSE);
  
  generator->getExpGenerator()->linkClause(this, arith_clause);

  return 0;
}
Example #21
0
short GenericUpdate::generateShape(CollHeap * c, char * buf, NAString * shapeStr)
{
  Space * space = (Space *)c;
  char mybuf[100];

  switch (getOperatorType())
    {
    default:
      {
	sprintf (mybuf, "anything");
      }
    break;
    }

  outputBuffer(space, buf, mybuf, shapeStr);

  return 0;
}
short Convert::codeGen(Generator * generator)
{
  Attributes ** attr;

  if (generator->getExpGenerator()->genItemExpr(this, &attr, (1 + getArity()), -1) == 1)
    return 0;

  ex_conv_clause * conv_clause =
	  new(generator->getSpace()) ex_conv_clause(getOperatorType(), attr,
						    generator->getSpace());
  conv_clause->setLastVOAoffset(lastVOAOffset_);
  conv_clause->setLastNullIndicatorLength(lastNullIndicatorLength_);
  conv_clause->setLastVcIndicatorLength(lastVcIndicatorLength_);
  conv_clause->setAlignment(alignment_);

  generator->getExpGenerator()->linkClause(this, conv_clause);      
  
  return 0;
}
// ItmBlockFunction::codeGen
//
// The Block function executes the code represented by both its children and
// then returns the result of the right child (child(1)).
//
short ItmBlockFunction::codeGen(Generator * generator) {
  // Get local handles...
  //
  Attributes **attr;
  Space* space = generator->getSpace();
  CollHeap *heap = generator->wHeap();
  ExpGenerator *exp = generator->getExpGenerator();

  // If this Block has already been codeGenned, then bug out...
  // Otherwise, allocate space for the result if necessary and set
  // attr[0] to point to the result attribute data. Also, mark this
  // node as codeGenned.
  //
  if (exp->genItemExpr(this, &attr, 2, 0) == 1)
    return 0;

  // CodeGen the left child.
  //
  child(0)->codeGen(generator);

  // CodeGen the right child.
  //
  child(1)->codeGen(generator);

  // The result of the Block is the result of the right child. Set
  // the src attribute for the convert (added below) to be the right child
  // The dst attribute has already been set in genItemExpr().
  //
  attr[1] = generator->getMapInfo
    (child(1)->castToItemExpr()->getValueId())->getAttr();

  // Allocate a convert clause to move the result from child(1) to the
  // result of this node. This move is necessary so that future
  // side-effects of the result of child(1) -- if it is a local variable,
  // for instance -- will not change the result of the Block.
  //
  ex_conv_clause * convClause =
    new(generator->getSpace()) ex_conv_clause
    (getOperatorType(), attr, space);
  generator->getExpGenerator()->linkClause(this, convClause);

  return 0;
}
Example #24
0
// we want BiRelat to be cacheable
NABoolean BiRelat::isCacheableExpr(CacheWA& cwa)
{
  if (cwa.getPhase() >= CmpMain::BIND && getArity() == 2) {
    if (getOperatorType() == ITM_EQUAL) {
      ItemExpr *leftC=child(0), *rightC=child(1);
      OperatorTypeEnum leftO = leftC->getOperatorType();
      OperatorTypeEnum rightO = rightC->getOperatorType();
      BaseColumn *base;
      if (leftO == ITM_BASECOLUMN) {
        base = (BaseColumn*)leftC;
        if (base->isKeyColumnValue(*rightC)) {
          cwa.addToUsedKeys(base);
        }
        return TRUE;
      }
      else if (rightO == ITM_BASECOLUMN) {
        base = (BaseColumn*)rightC;
        if (base->isKeyColumnValue(*leftC)) {
          cwa.addToUsedKeys(base);
        }
        return TRUE;
      }
      else if (leftO == ITM_ITEM_LIST && rightO == ITM_ITEM_LIST &&
               ((ItemList*)leftC)->isListOfCacheableSelPred
               (cwa, (ItemList*)rightC)) {
        return TRUE;
      }
      else {
        // we want all other equality comparisons to be cacheable, eg,
        // retail_div_cd||acct_type_cd||substring(acct_id,1,8)='20V43085193'
        return TRUE;
      }
    }
    else {
      return TRUE;
      // other binary comparison predicates can be cacheable, but are
      // not necessarily parameterizable, see BiRelat::normalizeForCache
    }
  }
  return FALSE;
}
// returns number of entries in the list represented
// by a left linear tree (also called a left skewed
// binary tree).  Treat this node as the root node
// of a left linear tree.
//
//  1 entry     2 entries      > 2 entries
//                [op]             [op]
//    [0]         /  \             /  \
//              [0]  [1]         [op] [2]
//                               /  \
//                             [0]  [1]
//
//  op represents ElemDDLList node
//
//  The case of 1 entry is not handled by this class.
//  This case is handled by the class ElemDDLNode.
//
CollIndex  
ElemDDLList::entries() const
{
  CollIndex count = 0;
  ElemDDLNode * pElemDDLNode = (ElemDDLNode *)this;

  while (pElemDDLNode NEQ NULL)
  {
    count++;
    if (pElemDDLNode->getOperatorType() EQU getOperatorType() AND
        pElemDDLNode->getArity() >= 2)
    {
      pElemDDLNode = pElemDDLNode->getChild(0)->castToElemDDLNode();
    }
    else
    {
      pElemDDLNode = NULL;
    }
  }
  return count;
}
Example #26
0
mreal_t ASTOperator::evaluate(void* data) const
{
  mreal_t result;

  switch (getOperatorType())
  {
    case MOPERATOR_ASSIGN:
    {
      MP_ASSERT(_left->getElementType() == MELEMENT_VARIABLE);
      result = _right->evaluate(data);
      reinterpret_cast<mreal_t*>((char*)data +
        reinterpret_cast<ASTVariable*>(_left)->getOffset())[0] = result;
      break;
    }
    case MOPERATOR_PLUS:
      result = _left->evaluate(data) + _right->evaluate(data);
      break;
    case MOPERATOR_MINUS:
      result = _left->evaluate(data) - _right->evaluate(data);
      break;
    case MOPERATOR_MUL:
      result = _left->evaluate(data) * _right->evaluate(data);
      break;
    case MOPERATOR_DIV:
      result = _left->evaluate(data) / _right->evaluate(data);
      break;
    case MOPERATOR_MOD:
    {
      mreal_t vl = _left->evaluate(data);
      mreal_t vr = _right->evaluate(data);
      result = fmodf(vl, vr);
      break;
    }
  }

  return result;
}
Example #27
0
Node* insertDoubleExpression(Node* exp1,char* op,Node* exp2){
    Node * newExpression = (Node*)calloc(sizeof(Node),1);
    if(newExpression == NULL) {
        if(DEBUG)
            printf("newCall: Error Malloc\n");
        assert(newExpression != NULL);
    }

    newExpression-> n_type = getOperatorType(op);
    free(op);
    if(newExpression->n_type == -1 )
        exit(-2);
    newExpression->n1 = exp1;
    newExpression->n2 = exp2;

    if(exp1 == NULL)
        newExpression->n1 = createNull();
    if(exp2 == NULL)
        newExpression->n2 = createNull();

    newExpression->next = NULL;
    return newExpression;

}
void Aggregate::codegen_and_set_attributes( Generator * generator, Attributes **attr,
                                            Lng32 num_attrs )
{

  if ( getOperatorType() != ITM_ONE_ROW )
  {
    ItemExpr::codegen_and_set_attributes( generator, attr, num_attrs);
  }
  else
  {
    MapTable *map_table = generator->getMapTable();

    for (short i=0; i<getArity(); i++)
    {
      child(i)->codeGen(generator);
    }
    // collect attributes at leaves
    // note that variable num_attrs gives the number of leaves,
    // but not the arity

    Int32 counter = 0;
    collectAttributes( this, num_attrs, counter, attr, generator );
  }
} // Aggregate::codegen_and_set_attributes()
Example #29
0
// return true if ItemExpr & its descendants have no constants & noncacheables
NABoolean ItemExpr::hasNoLiterals(CacheWA& cwa)
{
  if (isNonCacheable()) {
    return FALSE;
  }
  OperatorTypeEnum opTyp = getOperatorType();
  switch (opTyp) {
  case ITM_CONSTANT:
  case ITM_HOSTVAR:
  case ITM_DYN_PARAM:
  case ITM_CACHE_PARAM: 
    return FALSE;
  default: // fall thru
    break;
  }
  NABoolean result = TRUE;
  Int32 arity = getArity();
  for (Int32 x = 0; x < arity && result; x++) {
    if (child(x)) { 
      result = child(x)->hasNoLiterals(cwa); 
    }
  }
  return result;
}
short BiLogic::codeGen(Generator * generator)
{
  Attributes ** attr;

  if (generator->getExpGenerator()->genItemExpr(this, &attr, (1+getArity()), 0) == 1)
    return 0;
    
  Space * space = generator->getSpace();
  ExpGenerator * expGen = generator->getExpGenerator();

  // Normally, if code for a value id has been generated, and if
  // that value id is seen again, then code is not generated. The
  // location where the result is available is returned instead.
  // The case of a logical operator is different. Code is generated
  // again if a value id from the left child is also present in
  // the right child. This is done 
  // because at expression evaluation time, some of the expressions
  // may be skipped due to short circuit evaluation. 
  //
  // Allocate a new map table before generating code for each child.
  // This map table contains all the temporary results produced by
  // the child. 
  // Remove this map table after generating code for each child.
  generator->appendAtEnd();
  expGen->incrementLevel();

  codegen_and_set_attributes(generator, attr, 2); 
  //  generator->getExpGenerator()->setClauseLinked(FALSE);
  // child(0)->codeGen(generator);
  // attr[1] = generator->getAttr(child(0));
  // generator->getExpGenerator()->setClauseLinked(FALSE);

  /* generate boolean short circuit code */
  Attributes ** branch_attr = new(generator->wHeap()) Attributes * [2];

  branch_attr[0] = attr[0]->newCopy(generator->wHeap());
  branch_attr[0]->copyLocationAttrs(attr[0]);

  branch_attr[1] = attr[1]->newCopy(generator->wHeap());
  branch_attr[1]->copyLocationAttrs(attr[1]);

  branch_attr[0]->resetShowplan();
  ex_branch_clause * branch_clause 
    = new(space) ex_branch_clause(getOperatorType(), branch_attr, space);
  
  generator->getExpGenerator()->linkClause(0, branch_clause);
 
  generator->removeLast();
  expGen->decrementLevel();
  generator->appendAtEnd();
  expGen->incrementLevel();

  ValueIdSet markedEntries;
  // This ia a MapTable entry related fix for RangeSpec transformation.
  if( child(1)->getOperatorType() == ITM_RANGE_SPEC_FUNC )
    markGeneratedEntries(generator, child(1)->child(1), markedEntries);
  else
    markGeneratedEntries(generator, child(1), markedEntries);
//  if( child(1)->getOperatorType() == ITM_RANGE_SPEC_FUNC )
//    child(1)->child(1)->codeGen(generator);
//  else
    child(1)->codeGen(generator);
  ItemExpr *rightMost;
  if( child(1)->getOperatorType() == ITM_RANGE_SPEC_FUNC )
    rightMost = child(1)->child(1)->castToItemExpr();
  else
    rightMost = child(1)->castToItemExpr();

  while (rightMost->getOperatorType() == ITM_ITEM_LIST)
    rightMost = rightMost->child(1)->castToItemExpr();

  attr[2] = generator->
    getMapInfo(rightMost->getValueId())->getAttr();

  ex_bool_clause * bool_clause =
    new(space) ex_bool_clause(getOperatorType(), attr, space);

  generator->getExpGenerator()->linkClause(this, bool_clause);

  branch_clause->set_branch_clause((ex_clause *)bool_clause);
  
  generator->removeLast();
  expGen->decrementLevel();
  if( child(1)->getOperatorType() == ITM_RANGE_SPEC_FUNC )
    unGenerate(generator, child(1)->child(1));
  else
    unGenerate(generator, child(1));
  generateMarkedEntries(generator, markedEntries);

  return 0;
}