// 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; }
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); }
// 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; } }
// 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; }
// 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; } }
// 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; }
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; }
// 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; }
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; }
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()
// 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; }