// print MDFWriter errors to cout void SQLJFile::printMDFWriterErrors(char *errFileName) { char args[1024], EorW[10]; Int32 errNum; FILE *errFile = fopen(errFileName, "r"); if (errFile) { // accommodate case of MDFWriter dumping more entries into its errFile // than can fit into the fixed-size diags area. Do this by feeding // and then dumping diags one entry at a time. ComDiagsArea *myDiags = ComDiagsArea::allocate(mxCUMptr->heap()); while (fscanf(errFile, "%s %d ", EorW, &errNum) != EOF) { size_t sLen = 0; if (fgets(args, 1024, errFile) == NULL) { // fgets got EOF or an error args[0] = 0; // empty string *mxCUMptr << FAIL; } else { // fgets got something sLen = strlen(args); // chop off terminating newline if (args[sLen-1] == '\n') { args[sLen-1] = 0; } if (sLen >= 1023) { // diagnostic msg is too long // toss rest of line Int32 nxtCh; do { nxtCh = fgetc(errFile); } while (nxtCh != '\n' && nxtCh != EOF); } } if (!myDiags) { // no diags *mxCUMptr << FAIL; if (sLen >= 1023) { // diagnostic msg is too long cerr << "Diagnostic message is over 1023 characters long." << endl; } // echo error file entry to cerr cerr << EorW << " " << errNum << " " << args << endl; } else { if (sLen >= 1023) { // diagnostic msg is too long *mxCUMptr << WARNING; *myDiags << DgSqlCode(2237); } switch (errNum) { case 2224: case 2225: case 2226: *mxCUMptr << FAIL; *myDiags << DgSqlCode(-errNum); break; case 2227: case 2228: case 2230: *mxCUMptr << FAIL; *myDiags << DgSqlCode(-errNum) << DgString0(args); break; case 2229: *mxCUMptr << ERROR; *myDiags << DgSqlCode(-errNum) << DgString0(args); break; default: *mxCUMptr << (EorW[0]=='E' ? ERROR : (EorW[0]=='W' ? WARNING : FAIL)); *myDiags << DgSqlCode(-2231) << DgInt0(errNum) << DgString0(EorW) << DgString1(args); break; } // end switch NADumpDiags(cerr, myDiags, TRUE); myDiags->clear(); } // end if } // end while if (myDiags) { myDiags->decrRefCount(); } fclose(errFile); } else { *mxCUMptr << FAIL << DgSqlCode(-2218) << DgString0(errFileName); } // clean up temporary file (MDFWriter errors) remove(errFileName); }
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
void EspNewIncomingConnectionStream::actOnReceive(IpcConnection *connection) { // check for OS errors if (getState() == ERROR_STATE) { ex_assert(FALSE,"Error while receiving first message from client"); } // check for protocol errors bool willPassTheAssertion = (getType() == IPC_MSG_SQLESP_DATA_REQUEST OR getType() == IPC_MSG_SQLESP_CANCEL_REQUEST) AND getVersion() == CurrEspRequestMessageVersion AND moreObjects(); if (!willPassTheAssertion) { char *doCatchBugCRx = getenv("ESP_BUGCATCHER_CR_NONUMBER"); if (!doCatchBugCRx || *doCatchBugCRx != '0') { connection->dumpAndStopOtherEnd(true, false); environment_->getControlConnection()-> castToGuaReceiveControlConnection()-> getConnection()->dumpAndStopOtherEnd(true, false); } } ex_assert((getType() == IPC_MSG_SQLESP_DATA_REQUEST OR getType() == IPC_MSG_SQLESP_CANCEL_REQUEST) AND getVersion() == CurrEspRequestMessageVersion AND moreObjects(), "Invalid first message from client"); // take a look at the type of the first object in the message IpcMessageObjType nextObjType = getNextObjType(); switch (nextObjType) { case ESP_OPEN_HDR: case ESP_LATE_CANCEL_HDR: { ExFragKey key; Lng32 remoteInstNum; NABoolean isParallelExtract = false; // peek at the message header to see for whom it is if (nextObjType == ESP_OPEN_HDR) { ExEspOpenReqHeader reqHdr((NAMemory *) NULL); *this >> reqHdr; key = reqHdr.key_; remoteInstNum = reqHdr.myInstanceNum_; if (reqHdr.getOpenType() == ExEspOpenReqHeader::PARALLEL_EXTRACT) { isParallelExtract = true; } } else { // note that the late cancel request may or may not // arrive as the first request (only in the former case // will we reach here) ExEspLateCancelReqHeader reqHdr((NAMemory *) NULL); *this >> reqHdr; key = reqHdr.key_; remoteInstNum = reqHdr.myInstanceNum_; } if (!isParallelExtract) { ExFragInstanceHandle handle = espFragInstanceDir_->findHandle(key); if (handle != NullFragInstanceHandle) { // the send bottom node # myInstanceNum of this downloaded fragment // is the true recipient of this open request ex_split_bottom_tcb * receivingTcb = espFragInstanceDir_->getTopTcb(handle); ex_send_bottom_tcb *receivingSendTcb = receivingTcb->getSendNode(remoteInstNum); // Check the connection for a co-located client, and if so, // tell the split bottom, because it may prefer this send // bottom when using skew buster uniform distribution. if (espFragInstanceDir_-> getEnvironment()-> getMyOwnProcessId(IPC_DOM_GUA_PHANDLE).match( connection->getOtherEnd().getNodeName(), connection->getOtherEnd().getCpuNum())) receivingTcb->setLocalSendBottom(remoteInstNum); // Portability note for the code above: we pass IPC_DOM_GUA_PHANDLE // for IpcEnvironment::getMyOwnProcessId, even though that method // can be called with the default param (IpcNetworkDomain // IPC_DOM_INVALID). In fact it would probably be better // to call the object without specifying the IpcNetworkDomain so // that it can decide for itself what domain it is using. // But there is a problem with the Windows implementation // of IpcEnvironment::getMyOwnProcessId, it seems to assume // that its domain is IPC_DOM_INTERNET and so this will // cause the botch of an assertion that its control connection // (which is type EspGuaControlConnection) can be cast to a // SockControlConnection. When this problem is fixed, the // IPC_DOM_GUA_PHANDLE param above can be removed. Also, // when this code is ported to run it a domain other than // "guardian", it will be necessary to fix this and to // fix IpcEnvironment::getMyOwnProcessId to work properly on // windows. receivingSendTcb->setClient(connection); receivingSendTcb->routeMsg(*this); } else { connection->dumpAndStopOtherEnd(true, false); ex_assert(FALSE,"entry not found, set diagnostics area and reply"); } } // normal case, not parallel extract else { // The OPEN request is from a parallel extract consumer. The // incoming request contains a user ID which we will compare // against the current user ID for this ESP. // NOTE: The user ID for the extract security check is // currently sent and compared as a C string. On Linux it is // possible to send and compare integers which would lead to // simpler code. The code to send/compare strings is still // used because it works on all platforms. char errorStr[150]; // check if next msg is of securityInfo type. ex_assert(moreObjects(), "expected object not received"); ex_assert(getNextObjType() == ESP_SECURITY_INFO, "received message for unknown message type"); // unpack security info ExMsgSecurityInfo secInfo(environment_->getHeap()); *this >> secInfo; // Get the auth ID of this ESP in text form and compare it // to the auth ID that arrived in the message. Skip this // step in the debug build if an environment variable is // set. NABoolean doAuthIdCheck = TRUE; Int32 status = 0; #ifdef _DEBUG const char *envvar = getenv("NO_EXTRACT_AUTHID_CHECK"); if (envvar && envvar[0]) doAuthIdCheck = FALSE; #endif if (doAuthIdCheck) { // Get user ID from ExMsgSecurityInfo -> (secUserID) // the user ID is the integer value made into a string // Convert it back into its integer value short userIDLen = (short) str_len(secInfo.getAuthID()); Int32 secUserID = str_atoi(secInfo.getAuthID(), userIDLen); // Get the current user ID Int32 curUserID = ComUser::getSessionUser(); // Report an error if the user ID is not valid if (curUserID == NA_UserIdDefault || secUserID == NA_UserIdDefault) { str_cpy_c(errorStr, "Producer ESP could not authenticate the consumer, " "no valid current user."); status = -1; } // Make sure user id passed in ExMsgSecurityInfo matches // the user id associated with the current session #if defined(_DEBUG) NABoolean doDebug = (getenv("DBUSER_DEBUG") ? TRUE : FALSE); if (doDebug) printf("[DBUSER:%d] ESP extract user ID: " "local [%d], msg [%d]\n", (int) getpid(), curUserID, secUserID); #endif // Compare user ID, Report an error, if comparison fails if (curUserID != secUserID) { str_cpy_c(errorStr, "Producer ESP could not authenticate the consumer, " "user named passed in ExMsgSecurityInfo is not the " "current user"); status = -1; } } // if (doAuthIdCheck) // get the split bottom TCB that matches the securityKey ex_split_bottom_tcb *receivingTcb = NULL; if (status == 0) { receivingTcb = espFragInstanceDir_->getExtractTop(secInfo.getSecurityKey()); if (receivingTcb == NULL) { str_cpy_c(errorStr, "Producer ESP could not locate extract node"); status = -1; } } // get the sendBottom TCB if not already connected to a client ex_send_bottom_tcb *receivingSendTcb = NULL; if (status == 0) { receivingSendTcb = receivingTcb->getConsumerSendBottom(); if (receivingSendTcb == NULL) { str_cpy_c(errorStr, "Producer ESP already connected to a client"); status = -1; } } // send the error message to the consumer if (status != 0) { clearAllObjects(); setType(IPC_MSG_SQLESP_DATA_REPLY); NAMemory *heap = environment_->getHeap(); IpcMessageObj* baseObj = new(heap)IpcMessageObj(IPC_SQL_DIAG_AREA, CurrEspReplyMessageVersion); *this << *baseObj; // prepare proper error message char phandle[100]; MyGuaProcessHandle myHandle; myHandle.toAscii(phandle, 100); ComDiagsArea *diags = ComDiagsArea::allocate(heap); *diags << DgSqlCode(-EXE_PARALLEL_EXTRACT_OPEN_ERROR) << DgString0(phandle) << DgString1(errorStr); *this << *diags; diags->decrRefCount(); send(TRUE /* TRUE indicates waited */); } // if everything okay, then make the connection if (status == 0) { receivingSendTcb->setClient(connection); receivingSendTcb->routeMsg(*this); } } // parallel extract case } // open or cancel header
ExWorkProcRetcode ExCancelTcb::work() { ExMasterStmtGlobals *masterGlobals = getGlobals()->castToExExeStmtGlobals()->castToExMasterStmtGlobals(); CliGlobals *cliGlobals = masterGlobals->getCliGlobals(); while ((qparent_.down->isEmpty() == FALSE) && (qparent_.up->isFull() == FALSE)) { ex_queue_entry *pentry_down = qparent_.down->getHeadEntry(); switch (step_) { case NOT_STARTED: { if (pentry_down->downState.request == ex_queue::GET_NOMORE) step_ = DONE; else { retryCount_ = 0; // Priv checking is done during compilation. To support // REVOKE, prevent a prepared CANCEL/SUSPEND/ACTIVATE // that was compiled more than 1 second ago from executing // by raising the 8734 error to force an AQR. Int64 microSecondsSinceCompile = NA_JulianTimestamp() - masterGlobals->getStatement()->getCompileEndTime(); if (microSecondsSinceCompile > 1000*1000) { ComDiagsArea *diagsArea = ComDiagsArea::allocate(getGlobals()->getDefaultHeap()); *diagsArea << DgSqlCode(-CLI_INVALID_QUERY_PRIVS); reportError(diagsArea); step_ = DONE; break; } // Figure out which MXSSMP broker to use. if (cancelTdb().getAction() == ComTdbCancel::CancelByPname) { int nid = -1; int rc = msg_mon_get_process_info(cancelTdb().getCancelPname(), &nid, &pid_); switch (rc) { case XZFIL_ERR_OK: cpu_ = (short) nid; break; case XZFIL_ERR_NOTFOUND: case XZFIL_ERR_BADNAME: case XZFIL_ERR_NOSUCHDEV: { ComDiagsArea *diagsArea = ComDiagsArea::allocate(getGlobals()->getDefaultHeap()); *diagsArea << DgSqlCode(-EXE_CANCEL_PROCESS_NOT_FOUND); *diagsArea << DgString0(cancelTdb().getCancelPname()); reportError(diagsArea); step_ = DONE; break; } default: { char buf[200]; str_sprintf(buf, "Unexpected error %d returned from " "msg_mon_get_process_info", rc); ex_assert(0, buf); } } if (step_ != NOT_STARTED) break; } else if (cancelTdb().getAction() == ComTdbCancel::CancelByNidPid) { cpu_ = (short) cancelTdb().getCancelNid(); pid_ = cancelTdb().getCancelPid(); // check that process exists, if not report error. char processName[MS_MON_MAX_PROCESS_NAME]; int rc = msg_mon_get_process_name(cpu_, pid_, processName); if (XZFIL_ERR_OK == rc) ; // good. nid & pid are valid. else { if ((XZFIL_ERR_NOTFOUND != rc) && (XZFIL_ERR_BADNAME != rc) && (XZFIL_ERR_NOSUCHDEV != rc)) { // Log rc in case it needs investigation later. char buf[200]; str_sprintf(buf, "Unexpected error %d returned from " "msg_mon_get_process_name", rc); SQLMXLoggingArea::logExecRtInfo(__FILE__, __LINE__, buf, 0); } char nid_pid_str[32]; str_sprintf(nid_pid_str, "%d, %d", cpu_, pid_); ComDiagsArea *diagsArea = ComDiagsArea::allocate(getGlobals()->getDefaultHeap()); *diagsArea << DgSqlCode(-EXE_CANCEL_PROCESS_NOT_FOUND); *diagsArea << DgString0(nid_pid_str); reportError(diagsArea); step_ = DONE; break; } } else { char * qid = cancelTdb().qid_; Lng32 qid_len = str_len(qid); // This static method is defined in SqlStats.cpp. It side-effects // the nodeName and cpu_ according to the input qid. if (getMasterCpu( qid, qid_len, nodeName_, sizeof(nodeName_) - 1, cpu_) == -1) { ComDiagsArea *diagsArea = ComDiagsArea::allocate(getGlobals()->getDefaultHeap()); *diagsArea << DgSqlCode(-EXE_RTS_INVALID_QID); reportError(diagsArea); step_ = DONE; break; } } // Testpoints for hard to reproduce problems: bool fakeError8028 = false; fakeError8028 = (getenv("HP_FAKE_ERROR_8028") != NULL); if ((cliGlobals->getCbServerClass() == NULL) || fakeError8028) { ComDiagsArea *diagsArea = ComDiagsArea::allocate(getGlobals()->getDefaultHeap()); *diagsArea << DgSqlCode(-EXE_CANCEL_PROCESS_NOT_FOUND); *diagsArea << DgString0("$ZSM000"); reportError(diagsArea); step_ = DONE; break; } ComDiagsArea *diagsArea = NULL; bool fakeError2024 = false; fakeError2024 = (getenv("HP_FAKE_ERROR_2024") != NULL); if (fakeError2024) { cbServer_ = NULL; diagsArea = ComDiagsArea::allocate(getGlobals()->getDefaultHeap()); if (getenv("HP_FAKE_ERROR_8142")) { *diagsArea << DgSqlCode(-8142); *diagsArea << DgString0(__FILE__); *diagsArea << DgString1("cbServer_ is NULL"); } else *diagsArea << DgSqlCode(-2024); } else cbServer_ = cliGlobals->getCbServerClass()->allocateServerProcess( &diagsArea, cliGlobals->getEnvironment()->getHeap(), nodeName_, cpu_, IPC_PRIORITY_DONT_CARE, FALSE, // usesTransactions TRUE, // waitedCreation 2 // maxNowaitRequests -- cancel+(1 extra). ); if (cbServer_ == NULL || cbServer_->getControlConnection() == NULL) { ex_assert(diagsArea != NULL, "allocateServerProcess failed, but no diags"); // look for SQLCode 2024 // "*** ERROR[2024] Server Process $0~string0 // is not running or could not be created. Operating System // Error $1~int0 was returned." // Remap to cancel-specfic error 8028. if (diagsArea->contains(-2024) && cancelTdb().actionIsCancel()) { diagsArea->deleteError(diagsArea->returnIndex(-2024)); reportError(diagsArea, true, EXE_CANCEL_PROCESS_NOT_FOUND, nodeName_, cpu_); } else reportError(diagsArea); step_ = DONE; break; } // the reportError method was not called -- see break above. if (diagsArea != NULL) diagsArea->decrRefCount(); //Create the stream on the IpcHeap, since we don't dispose // of it immediately. We just add it to the list of completed // messages in the IpcEnv, and it is disposed of later. cancelStream_ = new (cliGlobals->getIpcHeap()) CancelMsgStream(cliGlobals->getEnvironment(), this); cancelStream_->addRecipient(cbServer_->getControlConnection()); } step_ = SEND_MESSAGE; break; } // end case NOT_STARTED #pragma warning (disable : 4291) case SEND_MESSAGE: { RtsHandle rtsHandle = (RtsHandle) this; if (cancelTdb().actionIsCancel()) { Int64 cancelStartTime = JULIANTIMESTAMP(); Lng32 firstEscalationInterval = cliGlobals->currContext()-> getSessionDefaults()->getCancelEscalationInterval(); Lng32 secondEscalationInterval = cliGlobals->currContext()-> getSessionDefaults()->getCancelEscalationMxosrvrInterval(); NABoolean cancelEscalationSaveabend = cliGlobals->currContext()-> getSessionDefaults()->getCancelEscalationSaveabend(); bool cancelLogging = (TRUE == cliGlobals->currContext()-> getSessionDefaults()->getCancelLogging()); CancelQueryRequest *cancelMsg = new (cliGlobals->getIpcHeap()) CancelQueryRequest(rtsHandle, cliGlobals->getIpcHeap(), cancelStartTime, firstEscalationInterval, secondEscalationInterval, cancelEscalationSaveabend, cancelTdb().getCommentText(), str_len(cancelTdb().getCommentText()), cancelLogging, cancelTdb().action_ != ComTdbCancel::CancelByQid, pid_, cancelTdb().getCancelPidBlockThreshold()); #pragma warning (default : 4291) *cancelStream_ << *cancelMsg; cancelMsg->decrRefCount(); } else if (ComTdbCancel::Suspend == cancelTdb().action_) { bool suspendLogging = (TRUE == cliGlobals->currContext()-> getSessionDefaults()->getSuspendLogging()); #pragma warning (disable : 4291) SuspendQueryRequest * suspendMsg = new (cliGlobals->getIpcHeap()) SuspendQueryRequest(rtsHandle, cliGlobals->getIpcHeap(), ComTdbCancel::Force == cancelTdb().forced_, suspendLogging); #pragma warning (default : 4291) *cancelStream_ << *suspendMsg; suspendMsg->decrRefCount(); } else { ex_assert( ComTdbCancel::Activate == cancelTdb().action_, "invalid action for ExCancelTcb"); bool suspendLogging = (TRUE == cliGlobals->currContext()-> getSessionDefaults()->getSuspendLogging()); #pragma warning (disable : 4291) ActivateQueryRequest * activateMsg = new (cliGlobals->getIpcHeap()) ActivateQueryRequest(rtsHandle, cliGlobals->getIpcHeap(), suspendLogging); #pragma warning (default : 4291) *cancelStream_ << *activateMsg; activateMsg->decrRefCount(); } if ((cancelTdb().getAction() != ComTdbCancel::CancelByPname) && (cancelTdb().getAction() != ComTdbCancel::CancelByNidPid)) { char * qid = cancelTdb().qid_; Lng32 qid_len = str_len(qid); #pragma warning (disable : 4291) RtsQueryId *rtsQueryId = new (cliGlobals->getIpcHeap()) RtsQueryId( cliGlobals->getIpcHeap(), qid, qid_len); #pragma warning (default : 4291) *cancelStream_ << *rtsQueryId; rtsQueryId->decrRefCount(); } // send a no-wait request to the cancel broker. cancelStream_->send(FALSE); step_ = GET_REPLY; // Come back when I/O completes. return WORK_OK; break; } // end case SEND_MESSAGE case GET_REPLY: { // Handle general IPC error. bool fakeError201 = false; fakeError201 = (getenv("HP_FAKE_ERROR_201") != NULL); if ((cbServer_->getControlConnection()->getErrorInfo() != 0) || fakeError201) { ComDiagsArea *diagsArea = ComDiagsArea::allocate(getGlobals()->getDefaultHeap()); cbServer_->getControlConnection()-> populateDiagsArea( diagsArea, getGlobals()->getDefaultHeap()); if (fakeError201) { *diagsArea << DgSqlCode(-2034) << DgInt0(201) << DgString0("I say") << DgString1("control broker"); } if (diagsArea->contains(-8921)) { // Should not get timeout error 8921. Get a core-file // of the SSMP and this process too so that this can be // debugged. cbServer_->getControlConnection()-> dumpAndStopOtherEnd(true, false); genLinuxCorefile("Unexpected timeout error"); } reportError(diagsArea); step_ = DONE; break; } // See if stream has the reply yet. if (!cancelStream_->moreObjects()) return WORK_OK; #pragma warning (disable : 4291) ControlQueryReply *reply = new (cliGlobals->getIpcHeap()) ControlQueryReply(INVALID_RTS_HANDLE, cliGlobals->getIpcHeap()); #pragma warning (default : 4291) *cancelStream_ >> *reply; if (reply->didAttemptControl()) { // yeaah! cancelStream_->clearAllObjects(); } else { if (cancelStream_->moreObjects() && cancelStream_->getNextObjType() == IPC_SQL_DIAG_AREA) { ComDiagsArea *diagsArea = ComDiagsArea::allocate(getGlobals()->getDefaultHeap()); *cancelStream_ >> *diagsArea; cancelStream_->clearAllObjects(); if ( retryQidNotActive_ && (diagsArea->mainSQLCODE() == -EXE_SUSPEND_QID_NOT_ACTIVE) && (++retryCount_ <= 60)) { SQLMXLoggingArea::logExecRtInfo(__FILE__, __LINE__, "Retrying error 8672.", 0); DELAY(500); diagsArea->decrRefCount(); step_ = SEND_MESSAGE; break; } reportError(diagsArea); } else ex_assert(0, "Control failed, but no diagnostics."); } step_ = DONE; break; } case DONE: { if (cancelStream_) { cancelStream_->addToCompletedList(); cancelStream_ = NULL; } if (cbServer_) { cbServer_->release(); cbServer_ = NULL; } ex_queue_entry * up_entry = qparent_.up->getTailEntry(); up_entry->copyAtp(pentry_down); up_entry->upState.parentIndex = pentry_down->downState.parentIndex; up_entry->upState.downIndex = qparent_.down->getHeadIndex(); up_entry->upState.setMatchNo(1); up_entry->upState.status = ex_queue::Q_NO_DATA; qparent_.up->insert(); qparent_.down->removeHead(); step_ = NOT_STARTED; break; } default: ex_assert( 0, "Unknown step_."); }