// change literals of a cacheable query into ConstantParameters ItemExpr* Substring::normalizeForCache(CacheWA& cwa, BindWA& bindWA) { if (nodeIsNormalizedForCache()) { return this; } // parameterize S in "substring(S from B for L)" but skip B & L child(0) = child(0)->normalizeForCache(cwa, bindWA); markAsNormalizedForCache(); return this; }
// change literals of a cacheable query into ConstantParameters ItemExpr* Like::normalizeForCache(CacheWA& cwa, BindWA& bindWA) { if (nodeIsNormalizedForCache()) { return this; } // replace only the matchValue child(0) = child(0)->normalizeForCache(cwa, bindWA); // but, don't touch the pattern or the escapeChar. markAsNormalizedForCache(); return this; }
// 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; } }
// change literals of a cacheable query into ConstantParameters ItemExpr* BiArith::normalizeForCache(CacheWA& cwa, BindWA& bindWA) { if (nodeIsNormalizedForCache()) { return this; } if (!isUnaryNegate()) { // set in sqlparser.y which transforms "-i" into // "0 - i" because apparently the executor does not have a unary negate. // so, we must avoid replacing this system-introduced "0". child(0) = child(0)->normalizeForCache(cwa, bindWA); } child(1) = child(1)->normalizeForCache(cwa, bindWA); markAsNormalizedForCache(); return this; }
// 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; }
// change literals of a cacheable query into ConstantParameters ItemExpr* Assign::normalizeForCache(CacheWA& cwa, BindWA& bindWA) { if (nodeIsNormalizedForCache()) { return this; } if (cwa.getPhase() == CmpMain::PARSE) { child(1) = child(1)->normalizeForCache(cwa, bindWA); } else if (cwa.getPhase() >= CmpMain::BIND) { ItemExpr *leftC=child(0), *rightC=child(1); OperatorTypeEnum leftO = leftC->getOperatorType(); OperatorTypeEnum rightO = rightC->getOperatorType(); ConstantParameter *cParam; if (leftO == ITM_BASECOLUMN && rightO == ITM_CONSTANT // normalizeForCache only constants that can be safely backpatched. // part of fix to CR 10-010726-4109. && isSafelyCoercible(cwa) // normalizeForCache only constants that are contained in the original // SQL query so that each parameter can be backpatched by the // corresponding constant from the query. This is to fix regression // failure MP core/test055 where a SystemLiteral was inserted when the // Keytag for a MP table column is not zero. see LeafInsert::bindNode(). // The offending query in MP core/test055 is // update t055t9v set b = b + 1 where current of c10; && NOT ((ConstValue*)rightC)->isSystemProvided() ) { ConstValue *val = (ConstValue*)rightC; if (!val->isNull()) { cParam = new (cwa.wHeap()) ConstantParameter ((ConstValue*)rightC, cwa.wHeap(), ((BaseColumn*)leftC)->getNAColumn()->getType()); cwa.addConstParam(cParam, bindWA); child(1) = cParam; } // else val is null; keep null as is. // this is part of a fix to genesis case: 10-010618-3484. } else { child(1) = child(1)->normalizeForCache(cwa, bindWA); } } markAsNormalizedForCache(); return this; }
// change literals of a cacheable query into ConstantParameters ItemExpr* ValueIdProxy::normalizeForCache(CacheWA& cwa, BindWA& bindWA) { if (nodeIsNormalizedForCache()) { return this; } if (cwa.getPhase() == CmpMain::PARSE) { // we want to parameterize tuple inserts derivedFrom_ = derivedFrom_.getItemExpr()->normalizeForCache(cwa, bindWA)->getValueId(); } else if (cwa.getPhase() == CmpMain::BIND) { if (derivedFrom_.getItemExpr()->isSafelyCoercible(cwa)) { // fix CR 10-010726-4109: make sure queries with constants that // cannot be safely backpatched such as // select case smallintcol when 4294967393 then 'max' end from t // are not parameterized derivedFrom_ = derivedFrom_.getItemExpr()->normalizeForCache(cwa, bindWA)->getValueId(); } } markAsNormalizedForCache(); return this; }
// change literals of a cacheable query into ConstantParameters ItemExpr* ItemExpr::normalizeForCache(CacheWA& cwa, BindWA& bindWA) { if (nodeIsNormalizedForCache()) { return this; } Int32 arity = getArity(); for (Int32 x = 0; x < arity; x++) { if (cwa.getPhase() == CmpMain::PARSE) { // we want to parameterize tuple inserts child(x) = child(x)->normalizeForCache(cwa, bindWA); } else if (cwa.getPhase() == CmpMain::BIND) { if (child(x)->isSafelyCoercible(cwa)) { // fix CR 10-010726-4109: make sure queries with constants that // cannot be safely backpatched such as // select case smallintcol when 4294967393 then 'max' end from t // are not parameterized child(x) = child(x)->normalizeForCache(cwa, bindWA); } } } markAsNormalizedForCache(); return this; }
// change literals of a cacheable query into ConstantParameters RelExpr* RelExpr::normalizeForCache(CacheWA& cwa, BindWA& bindWA) { if (nodeIsNormalizedForCache()) { return this; } // replace descendants' literals into ConstantParameters normalizeKidsForCache(cwa, bindWA); if (cwa.getPhase() >= CmpMain::BIND) { if (selection_) { selection_ = selection_->normalizeForCache(cwa, bindWA); } else { selectionPred().normalizeForCache(cwa, bindWA); } // RelExpr::bindSelf has done this line during binding; but, we // must redo it to recognize any new constantparameters created // by the above normalizeForCache call(s) as RelExpr inputs. getGroupAttr()->addCharacteristicInputs (bindWA.getCurrentScope()->getOuterRefs()); } markAsNormalizedForCache(); return this; }
// change literals of a cacheable query into ConstantParameters ItemExpr* UDFunction::normalizeForCache(CacheWA& cwa, BindWA& bindWA) { if (nodeIsNormalizedForCache()) { return this; } // Since the UDFunction::transformNode refers to both the // inputVars_ ValueIdSet and the children array we need to make sure // they are consistent. // The children array may contain cast() of the expressions in inputVars_ // If we have a UUDF function the inputs that were given // at parse time, really do not reflect reality anymore. // So here we will simply reinitialize them with what we find in the // inputVars_. CMPASSERT(udfDesc_); // we better have one after binding. NABoolean isUUDF(udfDesc_->isUUDFRoutine()); // Save off a copy of the original inputVars_ set. ValueIdSet origInputVars(inputVars_); // Loop through the given inputs for (Int32 x = 0; x < getArity(); x++) { NABoolean origInputIsChildOfCast(FALSE); ItemExpr * origIe = child(x); ItemExpr * newIe = NULL; ValueId vid = origIe->getValueId(); if (cwa.getPhase() == CmpMain::BIND) { if (origIe->isSafelyCoercible(cwa)) { // fix CR 10-010726-4109: make sure queries with constants that // cannot be safely backpatched such as // select case smallintcol when 4294967393 then 'max' end from t // are not parameterized newIe = origIe->normalizeForCache(cwa, bindWA); if (newIe != origIe ) { // normalizeForCache returned a new ItemExpr. We have to update // the UDFunction inputVars_ set, as this is used to determine // characteristic inputs for IsolatedScalarUDF at transform time. child(x) = newIe; // Is it a input that UDFunction::bindNode put a cast around? if ((origIe->getOperatorType() == ITM_CAST) && (origInputVars.contains(origIe->child(0)->getValueId()))) { // Since the original child was a CAST that UDFunction::bindNode // created, check to see if that CAST's child is part of the new // expression, if it is, we don't have to do anything, since the // CASTED value is part of the inputVars set, otherwise, we have // to update the inputVars set to keep the characteristic inputs // consistent. if (! newIe->referencesTheGivenValue( origIe->child(0)->getValueId()), TRUE) { // remove the original input from inputVars. It is the child // of origIe because origIe is a cast that UDFunction::bindNode // introduced. inputVars_ -= origIe->child(0)->getValueId(); if (newIe->getOperatorType() == ITM_CAST) { // If the new expression is a CAST, we assume the child is the // real input. We don't expect CAST(CAST(CAST(expr))) type // expressions only simple CAST(expr) ones. inputVars_ += newIe->child(0)->getValueId(); } else { // add the newIe itself if it was not a CAST. inputVars_ += newIe->getValueId(); } } } else { // If the newIe doesn't contain the original one, we need to update // the inputVars set. if (! newIe->referencesTheGivenValue( origIe->getValueId()), TRUE) { // the origIe was not a CAST introduced by UDFunction::bindNode() if (newIe->getOperatorType() == ITM_CAST) { if (!origInputVars.contains(newIe->child(0)->getValueId())) { inputVars_ -= origIe->getValueId(); // If the new expression is a CAST, we assume the child is the // real input. We don't expect CAST(CAST(CAST(expr))) type // expressions only simple CAST(expr) ones. inputVars_ += newIe->child(0)->getValueId(); } // we don't need to update inputVars_ if the origInputVars // contains the valueId of the newIe child already. } else { // This is an entirely new input. Remove the old one, and // add in the new. inputVars_ -= origIe->getValueId(); inputVars_ += newIe->getValueId(); } } } } } } } markAsNormalizedForCache(); return this; }