short ExExeUtilTcb::alterAuditFlag(NABoolean audited, char * tableName, NABoolean isIndex) { char buf[4000]; Lng32 cliRC = 0; // Get the globals stucture of the master executor. ExExeStmtGlobals *exeGlob = getGlobals()->castToExExeStmtGlobals(); ExMasterStmtGlobals *masterGlob = exeGlob->castToExMasterStmtGlobals(); // change the corrupt bit in the label if (isIndex) str_sprintf(buf, "LABEL_ALTER INDEX_TABLE %s PARALLEL EXECUTION ON OPCODE %s ''", tableName, (audited ? "65" : "66")); else str_sprintf(buf, "LABEL_ALTER TABLE %s PARALLEL EXECUTION ON OPCODE %s ''", tableName, (audited ? "65" : "66")); // set sqlparserflags to allow 'label_alter' syntax masterGlob->getStatement()->getContext()->setSqlParserFlags(0x1); cliRC = cliInterface()->executeImmediate(buf); masterGlob->getStatement()->getContext()->resetSqlParserFlags(0x1); if (cliRC < 0) { return -1; } return 0; }
short ExExeUtilTcb::alterObjectState(NABoolean online, char * tableName, char * failReason, NABoolean forPurgedata) { char buf[4000]; Lng32 cliRC = 0; // Get the globals stucture of the master executor. ExExeStmtGlobals *exeGlob = getGlobals()->castToExExeStmtGlobals(); ExMasterStmtGlobals *masterGlob = exeGlob->castToExMasterStmtGlobals(); // make object online str_sprintf(buf, "ALTER TABLE %s %s %s", tableName, (online ? "ONLINE" : "OFFLINE"), (forPurgedata ? "FOR PURGEDATA" : " ")); // set sqlparserflags to allow 'FOR PURGEDATA' syntax masterGlob->getStatement()->getContext()->setSqlParserFlags(0x1); cliRC = cliInterface()->executeImmediate(buf); masterGlob->getStatement()->getContext()->resetSqlParserFlags(0x1); if (cliRC < 0) { str_sprintf(failReason, "Could not alter the state of table %s to %s.", tableName, (online ? "online" : "offline")); return -1; } return 0; }
short ExExeUtilTcb::alterCorruptBit(short val, char * tableName, char * failReason, Queue* indexList) { char buf[4000]; Lng32 cliRC = 0; // Get the globals stucture of the master executor. ExExeStmtGlobals *exeGlob = getGlobals()->castToExExeStmtGlobals(); ExMasterStmtGlobals *masterGlob = exeGlob->castToExMasterStmtGlobals(); // change the corrupt bit in the label str_sprintf(buf, "LABEL_ALTER TABLE %s PARALLEL EXECUTION ON OPCODE 9 '%s'", tableName, (val == 1 ? "1" : "0")); // set sqlparserflags to allow 'label_alter' syntax masterGlob->getStatement()->getContext()->setSqlParserFlags(0x1); cliRC = cliInterface()->executeImmediate(buf); masterGlob->getStatement()->getContext()->resetSqlParserFlags(0x1); if (cliRC < 0) { str_sprintf(failReason, "Could not %s the corrupt bit on table %s.", (val == 1 ? "set" : "reset"), tableName); return -1; } if (indexList) { indexList->position(); while (NOT indexList->atEnd()) { char * indexName = (char*)indexList->getNext(); str_sprintf(buf, "LABEL_ALTER INDEX_TABLE %s PARALLEL EXECUTION ON OPCODE 9 '%s'", indexName, (val == 1 ? "1" : "0")); // set sqlparserflags to allow 'label_alter' syntax masterGlob->getStatement()->getContext()->setSqlParserFlags(0x1); cliRC = cliInterface()->executeImmediate(buf); masterGlob->getStatement()->getContext()->resetSqlParserFlags(0x1); if (cliRC < 0) { str_sprintf(failReason, "Could not %s the corrupt bit on index %s.", (val == 1 ? "set" : "reset"), indexName); return -1; } } // while } // index present return 0; }
short ExExeUtilTcb::lockUnlockObject(char * tableName, NABoolean lock, NABoolean parallel, char * failReason) { char buf[4000]; Lng32 cliRC = 0; // Get the globals stucture of the master executor. ExExeStmtGlobals *exeGlob = getGlobals()->castToExExeStmtGlobals(); ExMasterStmtGlobals *masterGlob = exeGlob->castToExMasterStmtGlobals(); // lock or unlock the table. if (parallel) { if (lock) str_sprintf(buf, "LOCK TABLE %s IN PROTECTED MODE NO INDEX LOCK PARALLEL EXECUTION ON", tableName); else str_sprintf(buf, "UNLOCK TABLE %s PARALLEL EXECUTION ON", tableName); } else { if (lock) str_sprintf(buf, "LOCK TABLE %s IN PROTECTED MODE", tableName); else str_sprintf(buf, "UNLOCK TABLE %s", tableName); } masterGlob->getStatement()->getContext()->setSqlParserFlags(0x100001); cliRC = cliInterface()->executeImmediate(buf); masterGlob->getStatement()->getContext()->resetSqlParserFlags(0x100001); if (cliRC < 0) { if (lock) str_sprintf(failReason, "Could not lock table %s in protected mode using parallel execution.", tableName); else str_sprintf(failReason, "Could not unlock table %s using parallel execution.", tableName); return -1; } return 0; }
Lng32 ExExeUtilTcb::changeAuditAttribute(char * tableName, NABoolean makeAudited, NABoolean isVolatile, NABoolean isIndex, NABoolean parallelAlter) { Lng32 retcode = 0; // Get the globals stucture of the master executor. ExExeStmtGlobals *exeGlob = getGlobals()->castToExExeStmtGlobals(); ExMasterStmtGlobals *masterGlob = exeGlob->castToExMasterStmtGlobals(); // set sqlparserflags to allow change of audit attribute masterGlob->getStatement()->getContext()->setSqlParserFlags(0x400); // ALLOW_AUDIT_CHANGE // make table unaudited char stmt[500]; strcpy(stmt, "alter "); if (isVolatile) strcat(stmt, "volatile "); strcat(stmt, "table "); strcat(stmt, tableName); if (makeAudited) strcat(stmt, " attribute audit"); else strcat(stmt, " attribute no audit"); if (parallelAlter) strcat(stmt, " no label update"); strcat(stmt, ";"); retcode = cliInterface()->executeImmediate (stmt, NULL, NULL, TRUE, NULL, 0, &(masterGlob->getStatement()->getContext()->diags())); masterGlob->getStatement()->getContext()->resetSqlParserFlags(0x400); // ALLOW_AUDIT_CHANGE if (retcode < 0) return retcode; if (parallelAlter) { retcode = alterAuditFlag(makeAudited, tableName, isIndex); if (retcode < 0) return retcode; } return 0; }
// lockType: COM_UTIL_PURGEDATA (= 9), COM_UTIL_REPLICATE (= 19). // (definition in common/ComSmallDefs.h). short ExExeUtilTcb::alterDDLLock(NABoolean add, char * tableName, char * failReason, NABoolean isMV, Int32 lockType, const char * lockSuffix, NABoolean skipDDLLockCheck) { char buf[4000]; Lng32 cliRC = 0; // Get the globals stucture of the master executor. ExExeStmtGlobals *exeGlob = getGlobals()->castToExExeStmtGlobals(); ExMasterStmtGlobals *masterGlob = exeGlob->castToExMasterStmtGlobals(); AnsiOrNskName aonn(tableName); aonn.convertAnsiOrNskName(FALSE); char * parts[4]; Lng32 numParts; aonn.extractParts(numParts, parts); char * quotedParts0 = NULL; char * quotedParts1 = NULL; if (numParts == 3) { quotedParts0 = new(getGlobals()->getDefaultHeap()) char[strlen(parts[0]) * 2 + 1]; quotedParts1 = new(getGlobals()->getDefaultHeap()) char[strlen(parts[1]) * 2 + 1]; doubleQuoteStr(parts[0], quotedParts0, FALSE); doubleQuoteStr(parts[1], quotedParts1, FALSE); } //////////////////////////////////////////////////////////////// // see sqlshare/catapirequest.h for details on CAT API params. // CatApi has the form: // CREATE TANDEM_CAT_REQUEST&1 <request-type> <num-params> // <lock-name> <object-name> <object-type> <operation-type> // request-type: 1 (create lock) or 2 (drop lock) // num-params: 5 // lock-name: getTableName() appended with _DDL_LOCK // object-name: getTableName() // object-type: 0 (table) or 2 (MV) // operation-type: 9 (purgedata) // lockStatus: 9 (parallel purgedata) //////////////////////////////////////////////////////////////// char sdlc[200]; if (skipDDLLockCheck) { str_sprintf(sdlc, "<> <0> <1>"); } // alter(add or drop) DDL lock if (numParts == 3) { char lockNameSuffix[200]; str_sprintf(lockNameSuffix, "_DDL_LOCK%s", (lockSuffix ? lockSuffix : "")); generateLockName(parts[2], lockNameSuffix, buf, sizeof buf - 20); char quotedLockName[ComMAX_3_PART_EXTERNAL_UTF8_NAME_LEN_IN_BYTES+200]; // a big buffer doubleQuoteStr(buf, quotedLockName, FALSE); str_sprintf(buf, "CREATE TANDEM_CAT_REQUEST&1 %s %d <\"%s\".\"%s\".\"%s\"> <%s%s> <%s> <%d> %s %s", (add ? "1" : "2"), (skipDDLLockCheck ? 8 : 5), //(lockType == COM_UTIL_PURGEDATA ? 5 : 4), quotedParts0, quotedParts1, quotedLockName, tableName, "", (isMV ? "2" : "0"), lockType, (lockType == COM_UTIL_PURGEDATA ? "<9>" : "<0>"), skipDDLLockCheck ? sdlc : ""); } else str_sprintf(buf, "CREATE TANDEM_CAT_REQUEST&1 %s %d <%s_DDL_LOCK%s> <%s%s> <%s> <%d> %s %s", (add ? "1" : "2"), // (lockType == COM_UTIL_PURGEDATA ? 5 : 4), (skipDDLLockCheck ? 8 : 5), //(lockType == COM_UTIL_PURGEDATA ? 5 : 4), tableName, (lockSuffix ? lockSuffix : ""), tableName, "", (isMV ? "2" : "0"), lockType, (lockType == COM_UTIL_PURGEDATA ? "<9>" : "<0>"), skipDDLLockCheck ? sdlc : ""); // set sqlparserflags to allow CAT_API_REQUEST masterGlob->getStatement()->getContext()->setSqlParserFlags(0x1); cliRC = cliInterface()->executeImmediate(buf); masterGlob->getStatement()->getContext()->resetSqlParserFlags(0x1); NADELETEBASIC(quotedParts0, getGlobals()->getDefaultHeap()); NADELETEBASIC(quotedParts1, getGlobals()->getDefaultHeap()); if (cliRC < 0) { str_sprintf(failReason, "Could not %s ddl lock for object %s.", (add ? "add" : "drop"), tableName); return (short)cliRC; } else return 0; }
short ExExeUtilPopulateInMemStatsTcb::work() { // short rc = 0; Lng32 cliRC = 0; // if no parent request, return if (qparent_.down->isEmpty()) return WORK_OK; // if no room in up queue, won't be able to return data/status. // Come back later. if (qparent_.up->isFull()) return WORK_OK; ex_queue_entry * pentry_down = qparent_.down->getHeadEntry(); ExExeUtilPrivateState & pstate = *((ExExeUtilPrivateState*) pentry_down->pstate); // Get the globals stucture of the master executor. ExExeStmtGlobals *exeGlob = getGlobals()->castToExExeStmtGlobals(); ExMasterStmtGlobals *masterGlob = exeGlob->castToExMasterStmtGlobals(); ContextCli * currContext = masterGlob->getStatement()->getContext(); while (1) { switch (step_) { case INITIAL_: { if (getDiagsArea()) { getDiagsArea()->clear(); getDiagsArea()->deAllocate(); } setDiagsArea(ComDiagsArea::allocate(getHeap())); step_ = PROLOGUE_; } break; case PROLOGUE_: { if (disableCQS()) { step_ = ERROR_; break; } if (setSchemaVersion(pimsTdb().sourceTableCatName_)) { step_ = ERROR_; break; } // set sqlparserflags to allow use of volatile schema in queries. masterGlob->getStatement()->getContext()-> setSqlParserFlags(0x10000);//ALLOW_VOLATILE_SCHEMA_IN_TABLE_NAME step_ = DELETE_STATS_; } break; case DELETE_STATS_: { Int32 qry_array_size = sizeof(deleteStatsQuery) / sizeof(QueryString); const QueryString * queryString = deleteStatsQuery;; char * gluedQuery; Lng32 gluedQuerySize; glueQueryFragments(qry_array_size, queryString, gluedQuery, gluedQuerySize); Lng32 extraSpace = ComMAX_3_PART_EXTERNAL_UTF8_NAME_LEN_IN_BYTES /* fullyQualTableName */ + 20 /* UID */ + 200 /* overhead */; char * query = new(getHeap()) char[gluedQuerySize + extraSpace]; str_sprintf(query, gluedQuery, (char*)pimsTdb().inMemHistogramsTableName_, pimsTdb().uid_); cliRC = cliInterface()->executeImmediate(query); if (cliRC >= 0) { str_sprintf(query, gluedQuery, (char*)pimsTdb().inMemHistintsTableName_, pimsTdb().uid_); cliRC = cliInterface()->executeImmediate(query); } // Delete new'd string NADELETEBASIC(gluedQuery, getHeap()); gluedQuery = NULL; NADELETEBASIC(query, getHeap()); query = NULL; if (cliRC < 0) { cliInterface()->allocAndRetrieveSQLDiagnostics(diagsArea_); step_ = ERROR_; } else step_ = POPULATE_HISTOGRAMS_STATS_; } break; case POPULATE_HISTOGRAMS_STATS_: { Int32 qry_array_size = sizeof(populateHistogramsStatsQuery) / sizeof(QueryString); const QueryString * queryString = populateHistogramsStatsQuery;; char * gluedQuery; Lng32 gluedQuerySize; glueQueryFragments(qry_array_size, queryString, gluedQuery, gluedQuerySize); Lng32 extraSpace = ComMAX_3_PART_EXTERNAL_UTF8_NAME_LEN_IN_BYTES /* fullyQualInMemHistTableName */ + 20 /* UID */ + ComMAX_3_PART_EXTERNAL_UTF8_NAME_LEN_IN_BYTES /* fullyQualSourceHistTableName */ + 2 * 10 /*segment name*/ + ComMAX_1_PART_EXTERNAL_UTF8_NAME_LEN_IN_BYTES /*cat name*/ + 10 /*version*/ + ComMAX_1_PART_EXTERNAL_UTF8_NAME_LEN_IN_BYTES /*cat name*/ + ComMAX_1_PART_EXTERNAL_UTF8_NAME_LEN_IN_BYTES /*sch name*/ + ComMAX_1_PART_EXTERNAL_UTF8_NAME_LEN_IN_BYTES /*obj name*/ + 200 /* overhead */; char * query = new(getHeap()) char[gluedQuerySize + extraSpace]; str_sprintf(query, gluedQuery, (char*)pimsTdb().inMemHistogramsTableName_, pimsTdb().uid_, (char*)pimsTdb().sourceHistogramsTableName_, (char*)pimsTdb().sourceTableCatName_, (char*)pimsTdb().sourceTableCatName_, (char*)pimsTdb().sourceTableSchName_, (char*)pimsTdb().sourceTableObjName_ ); cliRC = cliInterface()->executeImmediate(query); // Delete new'd string NADELETEBASIC(gluedQuery, getHeap()); gluedQuery = NULL; NADELETEBASIC(query, getHeap()); query = NULL; if (cliRC < 0) { cliInterface()->allocAndRetrieveSQLDiagnostics(diagsArea_); step_ = ERROR_; } else step_ = POPULATE_HISTINTS_STATS_; } break; case POPULATE_HISTINTS_STATS_: { Int32 qry_array_size = sizeof(populateHistintsStatsQuery) / sizeof(QueryString); const QueryString * queryString = populateHistintsStatsQuery;; char * gluedQuery; Lng32 gluedQuerySize; glueQueryFragments(qry_array_size, queryString, gluedQuery, gluedQuerySize); Lng32 extraSpace = ComMAX_3_PART_EXTERNAL_UTF8_NAME_LEN_IN_BYTES /* fullyQualInMemHistTableName */ + 20 /* UID */ + ComMAX_3_PART_EXTERNAL_UTF8_NAME_LEN_IN_BYTES /* fullyQualSourceHistTableName */ + 2 * 10 /*segment name*/ + ComMAX_1_PART_EXTERNAL_UTF8_NAME_LEN_IN_BYTES /*cat name*/ + 10 /*version*/ + ComMAX_1_PART_EXTERNAL_UTF8_NAME_LEN_IN_BYTES /*cat name*/ + ComMAX_1_PART_EXTERNAL_UTF8_NAME_LEN_IN_BYTES /*sch name*/ + ComMAX_1_PART_EXTERNAL_UTF8_NAME_LEN_IN_BYTES /*obj name*/ + 200 /* overhead */; char * query = new(getHeap()) char[gluedQuerySize + extraSpace]; str_sprintf(query, gluedQuery, (char*)pimsTdb().inMemHistintsTableName_, pimsTdb().uid_, (char*)pimsTdb().sourceHistintsTableName_, (char*)pimsTdb().sourceTableCatName_, (char*)pimsTdb().sourceTableCatName_, (char*)pimsTdb().sourceTableSchName_, (char*)pimsTdb().sourceTableObjName_ ); cliRC = cliInterface()->executeImmediate(query); // Delete new'd string NADELETEBASIC(gluedQuery, getHeap()); gluedQuery = NULL; NADELETEBASIC(query, getHeap()); query = NULL; if (cliRC < 0) { cliInterface()->allocAndRetrieveSQLDiagnostics(diagsArea_); step_ = ERROR_; } else step_ = EPILOGUE_; } break; case EPILOGUE_: case EPILOGUE_AND_ERROR_RETURN_: { // reset sqlparserflags masterGlob->getStatement()->getContext()-> resetSqlParserFlags(0x10000);//ALLOW_VOLATILE_SCHEMA_IN_TABLE_NAME restoreCQS(); if (step_ == EPILOGUE_AND_ERROR_RETURN_) step_ = ERROR_RETURN_; else step_ = DONE_; } break; case ERROR_: { step_ = EPILOGUE_AND_ERROR_RETURN_; } break; case ERROR_RETURN_: { if (qparent_.up->isFull()) return WORK_OK; // Return EOF. ex_queue_entry * up_entry = qparent_.up->getTailEntry(); up_entry->upState.parentIndex = pentry_down->downState.parentIndex; up_entry->upState.setMatchNo(0); up_entry->upState.status = ex_queue::Q_SQLERROR; ComDiagsArea *diagsArea = up_entry->getDiagsArea(); if (diagsArea == NULL) diagsArea = ComDiagsArea::allocate(this->getGlobals()->getDefaultHeap()); if (getDiagsArea()) diagsArea->mergeAfter(*getDiagsArea()); up_entry->setDiagsArea (diagsArea); // insert into parent qparent_.up->insert(); step_ = DONE_; } break; case DONE_: { if (qparent_.up->isFull()) return WORK_OK; // Return EOF. ex_queue_entry * up_entry = qparent_.up->getTailEntry(); up_entry->upState.parentIndex = pentry_down->downState.parentIndex; up_entry->upState.setMatchNo(0); up_entry->upState.status = ex_queue::Q_NO_DATA; // insert into parent qparent_.up->insert(); qparent_.down->removeHead(); step_ = INITIAL_; return WORK_OK; } break; default: break; } } return 0; }
short ExExeUtilLongRunningTcb::doLongRunning() { Lng32 cliRC =0; short retcode = 0; NABoolean xnAlreadyStarted = FALSE; // Get the globals stucture of the master executor. ExExeStmtGlobals *exeGlob = getGlobals()->castToExExeStmtGlobals(); ExMasterStmtGlobals *masterGlob = exeGlob->castToExMasterStmtGlobals(); ex_queue_entry * pentry_down = qparent_.down->getHeadEntry(); ExExeUtilPrivateState & pstate = *((ExExeUtilPrivateState*) pentry_down->pstate); CliGlobals *cliGlobals = 0; cliGlobals = GetCliGlobals(); ex_assert(cliGlobals != NULL, "Cli globals is NULL - should have been allocated already"); if (cliGlobals->isESPProcess()) { if (!currTransaction_) currTransaction_ = new (getHeap()) ExTransaction (cliGlobals, getHeap()); } else // in master executor { currTransaction_ = masterGlob->getStatement()->getContext()->getTransaction(); } if (currTransaction_->xnInProgress()) { xnAlreadyStarted = TRUE; } // cannot run LRU when a user transaction is in progress if (xnAlreadyStarted) { ExHandleErrors(qparent_, pentry_down, 0, getGlobals(), NULL, (ExeErrorCode)(-8603), NULL, exeUtilTdb().getTableName() ); return (-8603); } SQL_EXEC_ClearDiagnostics(NULL); // no Xn in progress. Start one. cliRC = currTransaction_->beginTransaction (); if (cliRC < 0) { ExHandleErrors(qparent_, pentry_down, 0, getGlobals(), NULL, (ExeErrorCode)(cliRC), NULL, exeUtilTdb().getTableName() ); return (short) cliRC; } retcode = executeLongRunningQuery(); // Rollback the transaction, if there is an error. if (retcode < 0) { // rollback the transaction cliRC = currTransaction_->rollbackTransaction (); return retcode; } else { // commit the transaction cliRC = currTransaction_->commitTransaction (); if (cliRC < 0) { ExHandleErrors(qparent_, pentry_down, 0, getGlobals(), NULL, (ExeErrorCode)(cliRC), NULL, exeUtilTdb().getTableName() ); return short(cliRC); } addTransactionCount(); } return retcode; }
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_."); }