// append an ascii-version of Union into cachewa.qryText_ void Union::generateCacheKey(CacheWA &cwa) const { RelExpr::generateCacheKeyNode(cwa); char buf[40]; cwa += " flgs_: "; convertInt64ToAscii(flags_, buf); cwa += buf; cwa += " ctrFlgs_: "; convertInt64ToAscii(controlFlags_, buf); cwa += buf; cwa += " sysGen_: "; cwa += (isSystemGenerated_) ? "1" : "0"; // turn on the following when condExprTree_ and trigExceptExprTree_ // are considered part of the key // //if (condExprTree_) { // cwa += " condExprTree_: "; // condExprTree_->generateCacheKey(cwa); //} //if (trigExceptExprTree_) { // cwa += " trigExceptExprTree_: "; // trigExceptExprTree_->generateCacheKey(cwa); //} generateCacheKeyForKids(cwa); }
// append an ascii-version of UDFunction into cachewa.qryText_ void UDFunction::generateCacheKey(CacheWA& cwa) const { NARoutine *routine = NULL; NARoutine *action = NULL; cwa += " nam:"; cwa += functionName_.getExternalName().data(); if (cwa.getPhase() >= CmpMain::BIND && getRoutineDesc() && (routine=getRoutineDesc()->getNARoutine()) != NULL) { char redefTime[40]; convertInt64ToAscii(routine->getRedefTime(), redefTime); cwa += " redef:"; cwa += redefTime; if ((routine->getSchemaLabelFileName()) && (str_len(routine->getSchemaLabelFileName()) > 0)) { char schRedefTime[40]; convertInt64ToAscii(routine->getSchemaRedefTime(), schRedefTime); cwa += " schredef:"; cwa += schRedefTime; } } if (getRoutineDesc() && getRoutineDesc()->getActionNameAsGiven().length() != 0) { cwa += " actnam:"; cwa += getRoutineDesc()->getActionNameAsGiven(); if (cwa.getPhase() >= CmpMain::BIND && getRoutineDesc() && (action=getRoutineDesc()->getActionNARoutine()) != NULL) { char redefTime[40]; convertInt64ToAscii(action->getRedefTime(), redefTime); cwa += " actredef:"; cwa += redefTime; } } cwa += "("; Lng32 arity = (Lng32) getArity(); for (Lng32 i = 0; i < arity; i++) { if (i > 0) { cwa += ", "; } child(i)->generateCacheKey(cwa); } if (getRoutineDesc()->getLocale() != 0 ) { cwa += ", LOCALE: "; char dFmt[20]; str_itoa(getRoutineDesc()->getLocale(), dFmt); cwa += dFmt; } cwa += ")"; }
// append an ascii-version of IsolatedScalarUDF into cachewa.qryText_ void IsolatedScalarUDF::generateCacheKey(CacheWA &cwa) const { NARoutine *routine = NULL; NARoutine *action = NULL; RelExpr::generateCacheKey(cwa); cwa += " UDFname:"; cwa += getRoutineName().getQualifiedNameAsAnsiString().data(); if (cwa.getPhase() >= CmpMain::BIND && getRoutineDesc() && (routine=getRoutineDesc()->getNARoutine()) != NULL) { char redefTime[40]; convertInt64ToAscii(routine->getRedefTime(), redefTime); cwa += " redef:"; cwa += redefTime; } if (getRoutineDesc() != NULL && getRoutineDesc()->isUUDFRoutine()) { cwa += " action:"; cwa += getRoutineDesc()->getActionNameAsGiven(); if (cwa.getPhase() >= CmpMain::BIND && getRoutineDesc() && (action=getRoutineDesc()->getActionNARoutine()) != NULL) { char redefTime[40]; convertInt64ToAscii(action->getRedefTime(), redefTime); cwa += " actredef:"; cwa += redefTime; } } const ItemExpr *paramExpr = (getProcAllParamsTree() == NULL) ? getProcInputParamsVids().rebuildExprTree(ITM_ITEM_LIST) : getProcAllParamsTree(); if (paramExpr) { cwa += " arg:("; paramExpr->generateCacheKey(cwa); cwa += ")"; } }
void TriggerStatusWA::print(ostream& os, const NAString& tableName) { os << endl << "Trigger Status Array for Table " << tableName << " : " << currentNumEntries_ << endl; os << "----------------------------------------" << endl; char int64Str[128]; for (UInt32 i=0; i<currentNumEntries_; i++) { convertInt64ToAscii(triggerStatusArray_[i].getTriggerId(), int64Str); os << int64Str << " : " << triggerStatusArray_[i].getEnableStatus() << endl; } }
// This method is not invoked from anywhere, need to determine if we should keep it, if so, we have to add // a way to invoke it. void displayStatement(SQLSTMT_ID s) { cout << " Statement ID :" << endl; cout << " Version :" << s.version << endl; cout << " Name Mode :" << s.name_mode << endl; cout << " Module :" << endl; cout << " Version :" << s.module->version << endl; cout << " Name :" << s.module->module_name << endl; #if defined( _MSC_VER ) char ct[100]; convertInt64ToAscii(s.module->creation_timestamp, ct); cout << " Creation Timestamp :" << ct << endl; #endif cout << " Char Set :" << s.module->charset << endl; cout << " Name Length :" << s.module->module_name_len << endl; cout << " Identifier :" << s.identifier << endl; cout << " Handle :" << s.handle << endl; cout << " Char Set :" << s.charset << endl; cout << " Identifier Length :" << s.identifier_len << endl; } // displayStatement
// append an ascii-version of RelExpr node into cachewa.qryText_ void RelExpr::generateCacheKeyNode(CacheWA &cwa) const { // emit any "[firstn_sorted]" modifier if (firstNRows_ != -1) { char firstN[40]; convertInt64ToAscii(((RelExpr*)this)->getFirstNRows(), firstN); cwa += firstN; cwa += " "; } // emit other "significant" parts of RelExpr cwa += getText(); ItemExpr *pred = selPredTree() ? selPredTree() : getSelectionPred().rebuildExprTree(); if (pred) { cwa += " selPred:"; pred->generateCacheKey(cwa); } // make any optimizer hints part of the postbinder cache key so that // 2 cacheable queries with different optimizer hints do not match if (hint_) { CollIndex x, cnt=hint_->indexCnt(); if (cnt > 0) { cwa += " xhint:"; for (x = 0; x < cnt; x++) { cwa += (*hint_)[x].data(); cwa += ","; } } char str[100]; if (hint_->hasCardinality()) { sprintf(str, "card:%g", hint_->getCardinality()); cwa += str; } if (hint_->hasSelectivity()) { sprintf(str, ",sel:%g", hint_->getSelectivity()); cwa += str; } } }
// LCOV_EXCL_START void displaySqlBuffer(SqlBuffer *sbuf, Lng32 sbuflen, ostream &os) { os << "Display an SQL Buffer:" << endl; os << " Buffer Size : " << sbuf->get_buffer_size() << endl; os << " Used Size : " << sbuf->get_used_size() << endl; os << " Free Size : " << (sbuf->get_buffer_size() - sbuf->get_used_size()) << endl; switch (sbuf->bufType()) { case SqlBufferBase::NORMAL_: os << " Buffer Type : Normal" << endl; break; case SqlBufferBase::DENSE_: os << " Buffer Type : Dense" << endl; break; case SqlBufferBase::OLT_: os << " Buffer Type : OLT" << endl; break; default: os << " Buffer Type : Unknown (" << sbuf->bufType() << ")" << endl; break; } os << " Packed? : " << TF_STRING(sbuf->packed()) << endl; os << " Empty? : " << TF_STRING(sbuf->isFull()) << endl; os << " Full? : " << TF_STRING(sbuf->isEmpty()) << endl; os << " Free? : " << TF_STRING(sbuf->isFree()) << endl; Lng32 numtuppdescs = sbuf->getTotalTuppDescs(); os << " Total Tupp Descs : " << numtuppdescs << endl; os << " Processed Tupp Descs : " << sbuf->getProcessedTuppDescs() << endl; #ifdef SQL_BUFFER_SIGNATURE char csig[100]; convertInt64ToAscii(sbuf->getSignature(), csig); os << " Signature : " << csig << endl; #endif tupp_descriptor *td; char *ctupp; ControlInfo *ci; for (Lng32 i = 1; i <= numtuppdescs; i++) { td = sbuf->getTuppDescriptor(i); if (td == NULL) { break; } ctupp = td->getTupleAddress(); if (td->isDataTuple()) { ServerDebug(""); ServerDebug("Data Tuple:"); os << " Tupp(" << i << ") Ref Count : " << td->getReferenceCount() << endl; os << " Tupp(" << i << ") Allocated Size: " << td->getAllocatedSize() << endl; dumpBuffer((unsigned char *)ctupp, td->getAllocatedSize()); } else if (td->isStatsTuple()) { ServerDebug(""); ServerDebug("Stats Tuple:"); os << " Tupp(" << i << ") Ref Count : " << td->getReferenceCount() << endl; os << " Tupp(" << i << ") Allocated Size: " << td->getAllocatedSize() << endl; } else if (td->isDiagsTuple()) { ServerDebug(""); ServerDebug("Diags Tuple:"); os << " Tupp(" << i << ") Ref Count : " << td->getReferenceCount() << endl; os << " Tupp(" << i << ") Allocated Size: " << td->getAllocatedSize() << endl; } else if (td->isControlTuple()) { ServerDebug(""); ServerDebug("Control Tuple:"); os << " Tupp(" << i << ") Ref Count : " << td->getReferenceCount() << endl; os << " Tupp(" << i << ") Allocated Size: " << td->getAllocatedSize() << endl; ci = (ControlInfo *)td->getTupleAddress(); up_state us = ci->getUpState(); down_state ds = ci->getDownState(); os << " Tupp(" << i << ") UpState : " << endl; os << " Tupp(" << i << ") Parent Index : " << us.parentIndex << endl; os << " Tupp(" << i << ") Down Index : " << us.downIndex << endl; switch (us.status) { case ex_queue::Q_NO_DATA: { os << " Tupp(" << i << ") Status : Q_NO_DATA" << endl; break; } case ex_queue::Q_OK_MMORE: { os << " Tupp(" << i << ") Status : Q_OK_MMORE" << endl; break; } case ex_queue::Q_SQLERROR: { os << " Tupp(" << i << ") Status : Q_SQLERROR" << endl; break; } case ex_queue::Q_INVALID: { os << " Tupp(" << i<< ") Status : Q_INVALID" << endl; break; } case ex_queue::Q_GET_DONE: { os << " Tupp(" << i << ") Status : Q_GET_DONE" << endl; break; } default: { os << " Tupp(" << i << ") Request : Unknown (" << us.status << ")" << endl; break; } } os << " Tupp(" << i << ") Match Nbr : " << us.getMatchNo() << endl; os << " Tupp(" << i << ") DownState : " << endl; switch (ds.request) { case ex_queue::GET_N: { os << " Tupp(" << i << ") Request : GET_N" << endl; break; } case ex_queue::GET_ALL: { os << " Tupp(" << i << ") Request : GET_ALL" << endl; break; } case ex_queue::GET_NOMORE: { os << " Tupp(" << i << ") Request : GET_NOMORE" << endl; break; } case ex_queue::GET_EMPTY: { os << " Tupp(" << i << ") Request : GET_EMPTY" << endl; break; } case ex_queue::GET_EOD: { os << " Tupp(" << i << ") Request : GET_EOD" << endl; break; } case ex_queue::GET_NEXT_N: { os << " Tupp(" << i << ") Request : GET_NEXT_N" << endl; break; } case ex_queue::GET_NEXT_N_MAYBE_WAIT: { os << " Tupp(" << i << ") Request : GET_NEXT_N_MAYBE_WAIT" << endl; break; } case ex_queue::GET_NEXT_0_MAYBE_WAIT: { os << " Tupp(" << i << ") Request : GET_NEXT_0_MAYBE_WAIT" << endl; break; } default: { os << " Tupp(" << i << ") Request : Unknown (" << ds.request << ")" << endl; break; } } os << " Tupp(" << i << ") Request : " << ds.request << endl; os << " Tupp(" << i << ") Request Value : " << ds.requestValue << endl; os << " Tupp(" << i << ") Nbr Get Nexts : " << ds.numGetNextsIssued << endl; os << " Tupp(" << i << ") Parent Index : " << ds.parentIndex << endl; os << " Tupp(" << i << ") Buff Seq Nbr : " << ci->getBufferSequenceNumber() << endl; os << " Tupp(" << i << ") Diags Area? : " << TF_STRING(ci->getIsDiagsAreaPresent()) << endl; os << " Tupp(" << i << ") Ext Diags Area? : " << TF_STRING(ci->getIsExtDiagsAreaPresent()) << endl; os << " Tupp(" << i << ") Data Row? : " << TF_STRING(ci->getIsDataRowPresent()) << endl; os << " Tupp(" << i << ") Stats Area? : " << TF_STRING(ci->getIsStatsAreaPresent()) << endl; os << " Tupp(" << i << ") ExtStats Area? : " << TF_STRING(ci->getIsExtStatsAreaPresent()) << endl; } // if (td->isControlTuple()) else { // some other type of tuple... ServerDebug(""); ServerDebug("Unknown Tuple:"); os << " Tupp(" << i << ") Ref Count : " << td->getReferenceCount() << endl; os << " Tupp(" << i << ") Allocated Size: " << td->getAllocatedSize() << endl; } } // for (long i = 1; i <= numtuppdescs; i++) os << endl; } // displaySqlBuffer
void processALoadMessage(UdrGlobals *UdrGlob, UdrServerReplyStream &msgStream, UdrLoadMsg &request, IpcEnvironment &env) { const char *moduleName = "processALoadMessage"; char errorText[MAXERRTEXT]; ComDiagsArea *diags = ComDiagsArea::allocate(UdrGlob->getIpcHeap()); doMessageBox(UdrGlob, TRACE_SHOW_DIALOGS, UdrGlob->showLoad_, moduleName); NABoolean showLoadLogic = (UdrGlob->verbose_ && UdrGlob->traceLevel_ >= TRACE_IPMS && UdrGlob->showLoad_); if (showLoadLogic) { ServerDebug("[UdrServ (%s)] Processing load request", moduleName); } // UDR_LOAD message always comes with transaction and they are out // side Enter Tx and Exit Tx pair. Make sure we are under correct // transaction. msgStream.activateCurrentMsgTransaction(); // // Check to see if the incoming UDR handle has already been seen // NABoolean handleAlreadyExists = FALSE; SPInfo *sp = UdrGlob->getSPList()->spFind(request.getHandle()); if (sp) { handleAlreadyExists = TRUE; if (showLoadLogic) { ServerDebug(" Duplicate handle arrived"); ServerDebug(" SPInfoState is %s", sp->getSPInfoStateString()); } if (sp->getSPInfoState() != SPInfo::UNLOADING) { // // An SPInfo exists but it is not one of the token instances to // represent an out-of-sequence LOAD/UNLOAD. This is an internal // error. Something has been botched in the message protocol. // char buf[100]; convertInt64ToAscii(request.getHandle(), buf); *diags << DgSqlCode(-UDR_ERR_DUPLICATE_LOADS); *diags << DgString0(buf); } else { // The LOAD/UNLOAD requests for this handle arrived // out-of-sequence. Nothing to do at this point. An empty reply // will be generated later in this function. } } if (!handleAlreadyExists) { if (!UdrHandleIsValid(request.getHandle())) { *diags << DgSqlCode(-UDR_ERR_MISSING_UDRHANDLE); *diags << DgString0("Load Message"); } else { // // First process the metadata in the LOAD requests and then // contact Language Manager to load the SP. // sp = processLoadParameters(UdrGlob, request, *diags); if (showLoadLogic) { ServerDebug("[UdrServ (%s)] About to call LM::getRoutine", moduleName); } if (sp == NULL) { *diags << DgSqlCode(-UDR_ERR_UNABLE_TO_ALLOCATE_MEMORY); *diags << DgString0("SPInfo"); } else { UdrGlob->setCurrSP(sp); LmRoutine *lmRoutine; LmResult lmResult; LmLanguageManager *lm = UdrGlob->getOrCreateLM(lmResult, sp->getLanguage(), diags); LmHandle emitRowFuncPtr; if (sp->getParamStyle() == COM_STYLE_CPP_OBJ) emitRowFuncPtr = (LmHandle)&SpInfoEmitRowCpp; else emitRowFuncPtr = (LmHandle)&SpInfoEmitRow; if (lm) { if (sp->getParamStyle() == COM_STYLE_JAVA_OBJ || sp->getParamStyle() == COM_STYLE_CPP_OBJ) { lmResult = lm->getObjRoutine( request.getUDRSerInvocationInfo(), request.getUDRSerInvocationInfoLen(), request.getUDRSerPlanInfo(), request.getUDRSerPlanInfoLen(), sp->getLanguage(), sp->getParamStyle(), sp->getExternalName(), sp->getContainerName(), sp->getExternalPathName(), sp->getLibrarySqlName(), &lmRoutine, diags); if (lmRoutine) { LmRoutineCppObj *objRoutine = static_cast<LmRoutineCppObj *>(lmRoutine); if (sp->getParamStyle() == COM_STYLE_CPP_OBJ) // set function pointers for functions provided // by tdm_udrserv objRoutine->setFunctionPtrs(SpInfoGetNextRow, SpInfoEmitRowCpp); // add items to the UDRInvocationInfo that are not // known at compile time (total # of instances is // kind of known, but we want to give the executor a // chance to change it) lmRoutine->setRuntimeInfo(request.getParentQid(), request.getNumInstances(), request.getInstanceNum()); #ifndef NDEBUG int debugLoop = 2; if (objRoutine->getInvocationInfo()->getDebugFlags() & tmudr::UDRInvocationInfo::DEBUG_LOAD_MSG_LOOP) debugLoop = 1; // go into a loop to allow the user to attach a debugger, // if requested, set debugLoop = 2 in the debugger to get out while (debugLoop < 2) debugLoop = 1-debugLoop; #endif } } else lmResult = lm->getRoutine(sp->getNumParameters(), sp->getLmParameters(), sp->getNumTables(), sp->getLmTables(), sp->getReturnValue(), sp->getParamStyle(), sp->getTransactionAttrs(), sp->getSQLAccessMode(), sp->getParentQid(), sp->getRequestRowSize(), sp->getReplyRowSize(), sp->getSqlName(), sp->getExternalName(), sp->getRoutineSig(), sp->getContainerName(), sp->getExternalPathName(), sp->getLibrarySqlName(), UdrGlob->getCurrentUserName(), UdrGlob->getSessionUserName(), sp->getExternalSecurity(), sp->getRoutineOwnerId(), &lmRoutine, (LmHandle)&SpInfoGetNextRow, emitRowFuncPtr, sp->getMaxNumResultSets(), diags); } if (lmResult == LM_OK) { if (lmRoutine == NULL) { *diags << DgSqlCode(-UDR_ERR_MISSING_LMROUTINE); *diags << DgString0("error: returned a null LM handle"); *diags << DgInt1((Int32)0); } else { sp->setLMHandle(lmRoutine); // Retrieve any optional data from UdrLoadMsg. copyRoutineOptionalData(request, sp); reportLoadResults(UdrGlob, sp, lmRoutine); sp->setSPInfoState(SPInfo::LOADED); } } // lmResult == LM_OK if (showLoadLogic) { if (lmResult == LM_OK) { sprintf(errorText, "[UdrServ (%.30s)] LM::getRoutine was successful.", moduleName); } else { sprintf(errorText, "[UdrServ (%.30s)] LM::getRoutine resulted in error.", moduleName); } ServerDebug(errorText); doMessageBox(UdrGlob, TRACE_SHOW_DIALOGS, UdrGlob->showMain_, errorText); } if (sp && !(sp->isLoaded())) { sp->setSPInfoState(SPInfo::LOAD_FAILED); } } // if (sp == NULL) else ... } // if (handle is not valid) else ... } // !handleAlreadyExists // build a reply and send it msgStream.clearAllObjects(); UdrLoadReply *reply = new (UdrGlob->getIpcHeap()) UdrLoadReply(UdrGlob->getIpcHeap()); if (reply == NULL) { // no reply buffer build... controlErrorReply(UdrGlob, msgStream, UDR_ERR_MESSAGE_PROCESSING, INVOKE_ERR_NO_REPLY_BUFFER, NULL); return; } // Only return a valid UDR Handle if diagnostics are not present and // no LM errors occurred. We also return a valid handle if this LOAD // arrived out-of-sequence after the UNLOAD and no diagnostics have // been generated yet. if (diags && diags->getNumber() > 0) { reply->setHandle(INVALID_UDR_HANDLE); } else if (sp) { if (sp->isLoaded() || handleAlreadyExists) { reply->setHandle(sp->getUdrHandle()); } else { reply->setHandle(INVALID_UDR_HANDLE); } } msgStream << *reply; if (diags && diags->getNumber() > 0) { msgStream << *diags; UdrGlob->numErrUDR_++; UdrGlob->numErrSP_++; UdrGlob->numErrLoadSP_++; if (showLoadLogic) dumpDiagnostics(diags, 2); } if (showLoadLogic) { ServerDebug("[UdrServ (%s)] About to send LOAD reply", moduleName); } #ifdef NA_DEBUG_C_RUNTIME if (UdrGlob && UdrGlob->getJavaLM()) { sleepIfPropertySet(*(UdrGlob->getJavaLM()), "MXUDR_LOAD_DELAY", diags); } #endif // NA_DEBUG_C_RUNTIME sendControlReply(UdrGlob, msgStream, sp); if (diags) { diags->decrRefCount(); } reply->decrRefCount(); } // processALoadMessage
// append an ascii-version of GenericUpdate into cachewa.qryText_ void GenericUpdate::generateCacheKey(CacheWA& cwa) const // NB: This comment applies to all generateCacheKey methods. // generateCacheKey is used to generate a string representation s of the // "parameterized" query. Since this string s is used by QCache::lookUp // to determine if a query is in the cache, it is essential that: // (1) two different queries have different string representations // (2) two queries that differ only in their query literals should // have the same string representations // One possible implementation of generateCacheKey is to use the query's // original query text. But, original query text does not satisfy (2). // To get (2), we call generateCacheKey() from RelRoot::normalizeForCache // which, by definition, replaced query literals with constant parameters. // However, generateCacheKey must also satisfy (1). generateCacheKey must // generate two different strings for two logically different queries. // // To satisfy requirements (1) and (2), generateCacheKey and // normalizeForCache must be in sync -- every user-specified expr that // generateCacheKey emits into cwa.qryText_ must be examined by // normalizeForCache for possible replacement of any literal there into // a constant parameter. // // In order for the literal-into-constantparameter replacement to be safe, // isCacheableExpr must visit all user-specified exprs to make sure that // only constants that can be safely cast into the query's target types // are considered cacheable. For example, given this update query // update t set a = 'xyz' where pk = 1; // isCacheableeExpr, normalizeForCache, and generateCacheKey must cooperate // so that: // 1) isCacheableExpr rejects the query as noncacheble if 'xyz' cannot be // safely cast into a's target type, eg, 'xyz' may be too long if a's // type is char(1). // 2) normalizeForCache must visit and replace both 'xyz' and 1 with // appropriate constant parameters. // 3) generateCacheKey must emit some string representation of the // parameterized query, eg, "update t set a = % where pk = %". // generateCacheKey can emit more stuff, eg, internally specified // begin/end-key predicates, but it must emit a string representation // of all user-specified parts of the query. { // append to cwa.qryText_ GenericUpdate's "essential" data members RelExpr::generateCacheKey(cwa); // An extension of the fix to 10-010618-3505, 10-010619-3515: // for "after bind" Insert/Update/Delete queries, include table's // RedefTime into cwa.qryText_ to make sure we get a cache hit only on // query that reference table(s) that have not changed since the query's // addition to the cache. The queries that reference altered table(s) // will never be hit again and will eventually age out of the cache. // This is not strictly necessary, but it speeds up the processing // of insert/update/delete queries on altered tables. const NATable *tbl; if (cwa.getPhase() >= CmpMain::BIND && getTableDesc() && (tbl=getTableDesc()->getNATable()) != NULL) { char redefTime[40]; convertInt64ToAscii(tbl->getRedefTime(), redefTime); cwa += " redef:"; cwa += redefTime; } ItemExpr *newExpr = newRecExprTree_ ? newRecExprTree_ : newRecExpr_.rebuildExprTree(ITM_ITEM_LIST); if (newExpr) { cwa += " newRecExpr:"; newExpr->generateCacheKey(cwa); } // make sure cache key can distinguish these 2 queries: // prepare s from select * from (update t042qT8 set b=7 where a=2) as t; // prepare s from select * from (update t042qT8 set b=7 set on rollback c=2 // where a=2) as t; ItemExpr *setOnRollback; if (newRecBeforeExpr_.entries() > 0 && (setOnRollback=newRecBeforeExpr_.rebuildExprTree(ITM_ITEM_LIST))) { cwa += " setOnRollback:"; setOnRollback->generateCacheKey(cwa); } ItemExpr *execPred = executorPredTree_ ? executorPredTree_ : executorPred_.rebuildExprTree(); if (execPred) { cwa += " execPred:"; execPred->generateCacheKey(cwa); } // MVs -- // The NOLOG parameter is essential. if (isNoLogOperation()) { cwa += " NOLOG"; } // "current of cursor/hostvar" is essential if (currOfCursorName_) { currOfCursorName_->generateCacheKey(cwa); } // not sure if the following are essential, but better to be safe & // slightly inefficient than to deliver a false hit (ie, wrong plan) cwa += mtsStatement_ ? "m1" : "m0"; cwa += noFlow_ ? "n1" : "n0"; cwa += noRollback_ ? "o1" : "o0"; cwa += noCheck_ ? "nc" : "dc"; // not sure if the following are essential, but we don't know how // to quickly & cheaply include them into our cachekey: // updatedTableName_, tabId_, updateToSelectMap_, indexDesc_, // newRecExprArray_, usedColumns_, newRecBeforeExpr_, // newRecBeforeExprArray_, usedBeforeColumns_, potentialOutputs_ // indexNumberArray_, scanIndexDesc_, rowsAffected_, stoi_, // oldToNewMap_ // The following data members are not "essential" to generateCacheKey // (at least "after bind") because they are either covered by other // data members (eg, beginKeyPred and endKeyPred_ are covered by the // selection pred in RelExpr) or they are not yet defined until later // (eg, after the optimize phase): // indexNewRecExprArrays_, beginKeyPred_, endKeyPred_, // pathKeys_, partKeys_, indexBeginKeyPredArray_, // indexEndKeyPredArray_, checkConstraints_ }
// append an ascii-version of Scan into cachewa.qryText_ void Scan::generateCacheKey(CacheWA &cwa) const { RelExpr::generateCacheKey(cwa); // Fix to 10-010618-3505, 10-010619-3515: include this Scan table's // RedefTime into cwa.qryText_ to make sure we get a cache hit only on // query that reference table(s) that have not changed since the query's // addition to the cache. The queries that reference altered table(s) // will never be hit again and will eventually age out of the cache. const NATable *tbl; if (cwa.getPhase() >= CmpMain::BIND && getTableDesc() && (tbl=getTableDesc()->getNATable()) != NULL) { char redefTime[40]; convertInt64ToAscii(tbl->getRedefTime(), redefTime); cwa += " redef:"; cwa += redefTime; if (tbl->isHiveTable()) { char lastModTime[40]; Int64 mTime = tbl->getClusteringIndex()->getHHDFSTableStats()->getModificationTS(); convertInt64ToAscii(mTime, lastModTime); cwa += " lastMod:"; cwa += lastModTime; cwa += " numFiles:"; char numFiles[20]; Int64 numberOfFiles = tbl->getClusteringIndex()->getHHDFSTableStats()->getNumFiles(); sprintf(numFiles, " %ld", numberOfFiles); cwa += numFiles ; } // save pointer to this table. later, QueryCache::addEntry will use // this pointer to get to this table's histograms's timestamp cwa.addTable( (NATable*)tbl ); // If PARTITION clause has been used we must reflect that in the key. if (tbl->isPartitionNameSpecified()) { cwa += " partition:"; cwa += tbl->getClusteringIndex()->getFileSetName().getQualifiedNameAsString().data(); } // If PARTITION range has been used we must reflect that in the key. else if (tbl->isPartitionRangeSpecified()) { cwa += " partition:"; char str[100]; sprintf(str, " from %d to %d", tbl->getExtendedQualName().getPartnClause().getBeginPartitionNumber() , tbl->getExtendedQualName().getPartnClause().getEndPartitionNumber()); cwa += str; } } // We must reflect userTableName_.location into cache key. // Otherwise, two queries which differ only in location such as // table table (table T058a, location $system.zsd12345.x1234500); // table table (table T058a, location $data .zsd12345.x1234500); // can confuse our query caching code to return a false hit and // cause fullstack/test058 to fail. cwa += userTableName_.getLocationName().data(); // Same with stream_ because queries like // "select * from t" and "select * from stream(t)" can // confuse query caching into a false hit causing test079 to fail. if (stream_) { cwa += " stream "; } // mark mpalias queries so they can be decached upon user request if (getTableDesc()->getNATable()->isAnMPTableWithAnsiName()) { cwa += AM_AN_MPALIAS_QUERY; } if (getHbaseAccessOptions()) { cwa += " hbaseVersions: "; char numVersions[20]; sprintf(numVersions, " %d", getHbaseAccessOptions()->getHbaseVersions()); cwa += numVersions ; } }
short Env::process(SqlciEnv *sqlci_env) { // ## Should any of this text come from the message file, // ## i.e. from a translatable file for I18N? // When adding new variables, please keep the information in // alphabetic order Logfile *log = sqlci_env->get_logfile(); log->WriteAll("----------------------------------"); log->WriteAll("Current Environment"); log->WriteAll("----------------------------------"); bool authenticationEnabled = false; bool authorizationEnabled = false; bool authorizationReady = false; bool auditingEnabled = false; Int32 rc = sqlci_env->getAuthState(authenticationEnabled, authorizationEnabled, authorizationReady, auditingEnabled); // TDB: add auditing state log->WriteAllWithoutEOL("AUTHENTICATION "); if (authenticationEnabled) log->WriteAll("enabled"); else log->WriteAll("disabled"); log->WriteAllWithoutEOL("AUTHORIZATION "); if (authorizationEnabled) log->WriteAll("enabled"); else log->WriteAll("disabled"); log->WriteAllWithoutEOL("CURRENT DIRECTORY "); // NT_PORT (bv 10/24/96) Added NA_MAX_PATH here and in common/Platform.h log->WriteAll(getcwd((char *)NULL, NA_MAX_PATH)); log->WriteAllWithoutEOL("LIST_COUNT "); char buf[100]; Int32 len = sprintf(buf, "%u", sqlci_env->getListCount()); if (len-- > 0) if (buf[len] == 'L' || buf[len] == 'l') buf[len] = '\0'; log->WriteAll(buf); if (log->IsOpen()) { log->WriteAllWithoutEOL("LOG FILE "); log->WriteAll(log->Logname()); } else { log->WriteAll("LOG FILE"); } log->WriteAllWithoutEOL("MESSAGEFILE "); const char *mf = GetErrorMessageFileName(); log->WriteAll(mf ? mf : ""); #if 0 log->WriteAllWithoutEOL("ISO88591 MAPPING "); log->WriteAll(CharInfo::getCharSetName(sqlci_env->getIsoMappingCharset())); log->WriteAllWithoutEOL("DEFAULT CHARSET "); log->WriteAll(CharInfo::getCharSetName(sqlci_env->getDefaultCharset())); log->WriteAllWithoutEOL("INFER CHARSET "); log->WriteAll((sqlci_env->getInferCharset())?"ON":"OFF"); #endif // ## These need to have real values detected from the env and written out: // "US English" is more "politically correct" than "American English". // log->WriteAllWithoutEOL("MESSAGEFILE LANG US English\n"); log->WriteAllWithoutEOL("MESSAGEFILE VRSN "); char vmsgcode[10]; sprintf(vmsgcode, "%d", SQLERRORS_MSGFILE_VERSION_INFO); #pragma nowarn(1506) // warning elimination Error vmsg(vmsgcode, strlen(vmsgcode), Error::ENVCMD_); #pragma warn(1506) // warning elimination vmsg.process(sqlci_env); ComAnsiNamePart defaultCat; ComAnsiNamePart defaultSch; sqlci_env->getDefaultCatAndSch (defaultCat, defaultSch); CharInfo::CharSet TCS = sqlci_env->getTerminalCharset(); CharInfo::CharSet ISOMAPCS = sqlci_env->getIsoMappingCharset(); if(TCS != CharInfo::UTF8 ) { NAString dCat = defaultCat.getExternalName(); NAString dSch = defaultSch.getExternalName(); charBuf cbufCat((unsigned char*)dCat.data(), dCat.length()); charBuf cbufSch((unsigned char*)dSch.data(), dSch.length()); NAWcharBuf* wcbuf = 0; Int32 errorcode = 0; wcbuf = csetToUnicode(cbufCat, 0, wcbuf, CharInfo::UTF8, errorcode); NAString* tempstr; if (errorcode != 0){ tempstr = new NAString(defaultCat.getExternalName().data()); } else { tempstr = unicodeToChar(wcbuf->data(),wcbuf->getStrLen(), TCS, NULL, TRUE); TrimNAStringSpace(*tempstr, FALSE, TRUE); // trim trailing blanks } log->WriteAllWithoutEOL("SQL CATALOG "); log->WriteAll(tempstr->data()); // Default Schema wcbuf = 0; // must 0 out to get next call to allocate memory. wcbuf = csetToUnicode(cbufSch, 0, wcbuf, CharInfo::UTF8, errorcode); if (errorcode != 0){ tempstr = new NAString(defaultSch.getExternalName().data()); } else { tempstr = unicodeToChar(wcbuf->data(),wcbuf->getStrLen(), TCS, NULL, TRUE); TrimNAStringSpace(*tempstr, FALSE, TRUE); // trim trailing blanks } log->WriteAllWithoutEOL("SQL SCHEMA "); log->WriteAll(tempstr->data()); } else { log->WriteAllWithoutEOL("SQL CATALOG "); log->WriteAll(defaultCat.getExternalName()); log->WriteAllWithoutEOL("SQL SCHEMA "); log->WriteAll(defaultSch.getExternalName()); } // On Linux we include the database user name and user ID in the // command output NAString username; rc = sqlci_env->getExternalUserName(username); log->WriteAllWithoutEOL("SQL USER CONNECTED "); if (rc >= 0) log->WriteAll(username.data()); else log->WriteAll("?"); rc = sqlci_env->getDatabaseUserName(username); log->WriteAllWithoutEOL("SQL USER DB NAME "); if (rc >= 0) log->WriteAll(username.data()); else log->WriteAll("?"); Int32 uid = 0; rc = sqlci_env->getDatabaseUserID(uid); log->WriteAllWithoutEOL("SQL USER ID "); if (rc >= 0) sprintf(buf, "%d", (int) uid); else strcpy(buf, "?"); log->WriteAll(buf); log->WriteAllWithoutEOL("TERMINAL CHARSET "); log->WriteAll(CharInfo::getCharSetName(sqlci_env->getTerminalCharset())); Int64 transid; if (sqlci_env->statusTransaction(&transid)) { // transaction is active. char transid_str[20]; convertInt64ToAscii(transid, transid_str); log->WriteAllWithoutEOL("TRANSACTION ID "); log->WriteAll(transid_str); log->WriteAll("TRANSACTION STATE in progress"); } else { log->WriteAll("TRANSACTION ID "); log->WriteAll("TRANSACTION STATE not in progress"); } if (log->isVerbose()) log->WriteAll("WARNINGS on"); else log->WriteAll("WARNINGS off"); return 0; }