short ExExeUtilTcb::setSystemVersion() { Lng32 cliRC = 0; if (sysVersionStrLen_ == 0) { // since SUBSTRING isn't currently supported for UTF-8 strings // and GET VERSION OF SYSTEM returns a UTF-8 string, convert it // to UCS2, do the substring, then convert to ISO88591 (we // expect a number here so it would be an error to get anything // other than ISO88591 characters). cliRC = cliInterface()->executeImmediate("select translate(substring(translate(a using utf8toucs2), 10, 4) using ucs2toiso88591) from (get version of system) x(a)", sysVersionStr_, &sysVersionStrLen_); if (cliRC < 0) { cliInterface()->retrieveSQLDiagnostics(getDiagsArea()); return -1; } sysVersionStr_[sysVersionStrLen_] = 0; } return 0; }
ComDiagsArea *ExExeUtilLongRunningTcb::getDiagAreaFromUpQueueTail() { ex_queue_entry * up_entry = qparent_.up->getTailEntry(); ComDiagsArea *diagsArea = up_entry->getDiagsArea(); if (diagsArea == NULL) diagsArea = ComDiagsArea::allocate(this->getGlobals()->getDefaultHeap()); else diagsArea->incrRefCount (); // setDiagsArea call below will decr ref count // this is the side-effect of this function. Merge in this object's // diagsarea. if (getDiagsArea()) diagsArea->mergeAfter(*getDiagsArea()); up_entry->setDiagsArea (diagsArea); return diagsArea; }
short ExExeUtilTcb::getObjectUid(char * catName, char * schName, char * objName, NABoolean isIndex, NABoolean isMv, char* uid) { Lng32 cliRC = 0; ex_queue_entry * pentry_down = qparent_.down->getHeadEntry(); ExExeUtilPrivateState & pstate = *((ExExeUtilPrivateState*) pentry_down->pstate); ExExeStmtGlobals *exeGlob = getGlobals()->castToExExeStmtGlobals(); ExMasterStmtGlobals *masterGlob = exeGlob->castToExMasterStmtGlobals(); const QueryString * qs; Int32 sizeOfqs = 0; versionStrLen_ = 0; qs = getObjectUidQuery; sizeOfqs = sizeof(getObjectUidQuery); Int32 qryArraySize = sizeOfqs / sizeof(QueryString); char * gluedQuery; Lng32 gluedQuerySize; glueQueryFragments(qryArraySize, qs, gluedQuery, gluedQuerySize); Lng32 extraSpace = 10 /*segment name*/+ ComMAX_3_PART_EXTERNAL_UTF8_NAME_LEN_IN_BYTES/*cat/sch/obj name in UTF8*/ + 100; char * infoQuery = new(getHeap()) char[gluedQuerySize + extraSpace + 1]; str_sprintf(infoQuery, gluedQuery, catName, schName, objName, (isIndex ? "IX" : "TA"), (isMv ? "MV" : (isIndex ? "IX" : "BT"))); NADELETEBASIC(gluedQuery, getMyHeap()); Lng32 uidLen; cliRC = cliInterface()->executeImmediate(infoQuery, uid, &uidLen); if (cliRC < 0) { cliInterface()->retrieveSQLDiagnostics(getDiagsArea()); return -1; } uid[uidLen] = 0; return 0; }
void ExExeUtilTcb::restoreMaintainControlTableTimeout(char * catalog) { Lng32 cliRC; char buf[400+ComMAX_1_PART_EXTERNAL_UTF8_NAME_LEN_IN_BYTES]; Lng32 markValue = -1; // If the restoration timeout flag is not set, // then just return. if (!restoreTimeout_) return; markValue = getDiagsArea()->mark(); // Reset the timeout to its previous setting. // Errors are ignored. strcpy(buf, "SET TABLE "); strcat(buf, catalog); strcat(buf, ".\"@MAINTAIN_SCHEMA@\".\"@MAINTAIN_CONTROL_INFO@\" "); strcat(buf, " TIMEOUT RESET;"); cliRC = cliInterface()->executeImmediate(buf); if (cliRC < 0) { // ignore any error occurring from the executeImmediate call // rewind to not report this one error getDiagsArea()->rewind(markValue); SQL_EXEC_ClearDiagnostics(NULL); return; } restoreTimeout_ = FALSE; return; }
void ExExeUtilTcb::setMaintainControlTableTimeout(char * catalog) { Lng32 cliRC; char buf[400+ComMAX_1_PART_EXTERNAL_UTF8_NAME_LEN_IN_BYTES]; Lng32 markValue = -1; char timeoutHoldBuf[100]; Lng32 timeoutHoldBufLen = 0; // The MAINTAIN_CONTROL_TABLE_TIMEOUT CQD default is '30000', 5 minutes restoreTimeout_ = FALSE; strcpy(buf, "showcontrol default "); strcat(buf, "MAINTAIN_CONTROL_TABLE_TIMEOUT"); strcat(buf, " , match full, no header;"); markValue = getDiagsArea()->mark(); // get the current value of MAINTAIN_CONTROL_TABLE_TIMEOUT cliRC = cliInterface()-> executeImmediate(buf, timeoutHoldBuf, &timeoutHoldBufLen); // If we were unable to obtain the default value, // then just return and allow the 60 second general // timeout for a table to remain. if (cliRC < 0) { // Ignore any error occurring from the executeImmediate call. // Rewind to not report this one error. getDiagsArea()->rewind(markValue); SQL_EXEC_ClearDiagnostics(NULL); return; } // The timeout setting will be retained for the duration // of executing the maintain tasks. // Execute the set table timeout statement. // The SET TABLE TIMEOUT statement sets a dynamic timeout value for a lock timeout // or a stream timeout in the environment of the current session. The dynamic timeout // value overrides the compiled static timeout value in the execution of subsequent DML // statements. markValue = getDiagsArea()->mark(); strcpy(buf, "SET TABLE "); strcat(buf, catalog); strcat(buf, ".\"@MAINTAIN_SCHEMA@\".\"@MAINTAIN_CONTROL_INFO@\" "); strcat(buf, " TIMEOUT "); strcat(buf, " '"); strcat(buf, timeoutHoldBuf); strcat(buf, "';"); cliRC = cliInterface()->executeImmediate(buf); if (cliRC < 0) { // Ignore any error occurring from the executeImmediate call. // Rewind to not report this one error. getDiagsArea()->rewind(markValue); SQL_EXEC_ClearDiagnostics(NULL); return; } // Set the flag to indicate the timeout // should be restored restoreTimeout_ = TRUE; return; }
short ExExeUtilTcb::executeQuery(char * task, char * object, char * query, NABoolean displayStartTime, NABoolean displayEndTime, short &rc, short * warning, Lng32 * ec, NABoolean moveErrorRow, NABoolean continueOnError, NABoolean monitorThis) { short retcode = 0; char buf[BUFFER_SIZE]; while (1) { switch (pqStep_) { case PROLOGUE_: { warning_ = 0; startTime_ = NA_JulianTimestamp(); elapsedTime_ = 0; if (displayStartTime) { getStatusString(task, "Started", object, buf); if (moveRowToUpQueue(buf, 0, &rc)) return 1; } pqStep_ = EXECUTE_; rc = WORK_RESCHEDULE_AND_RETURN; return 1; } break; case EXECUTE_: { retcode = cliInterface()->fetchRowsPrologue(query,FALSE,monitorThis); if (retcode < 0) { pqStep_ = ERROR_RETURN_; break; } pqStep_ = FETCH_ROW_; } break; case FETCH_ROW_: { retcode = (short)cliInterface()->fetch(); if (retcode < 0) { pqStep_ = ERROR_RETURN_; break; } if ((retcode > 0) && (retcode != 100)) warning_ = retcode; if ((retcode != 100) && (cliInterface()->outputBuf())) pqStep_ = RETURN_ROW_; else pqStep_ = CLOSE_; } break; case RETURN_ROW_: { char * ptr; Lng32 len; cliInterface()->getPtrAndLen(1, ptr, len); retcode = moveRowToUpQueue(ptr, len, &rc); if (retcode) return 1; pqStep_ = FETCH_ROW_; } break; case CLOSE_: { retcode = cliInterface()->fetchRowsEpilogue(""); if (retcode < 0) { pqStep_ = ERROR_RETURN_; break; } pqStep_ = EPILOGUE_; } break; case EPILOGUE_: { endTime_ = NA_JulianTimestamp(); elapsedTime_ = endTime_ - startTime_; if (displayEndTime) { char timeBuf[200]; getTimeAsString(elapsedTime_, timeBuf); getStatusString(task, "Ended", object, buf, timeBuf); if (moveRowToUpQueue(buf, 0, &rc)) return 1; } pqStep_ = ALL_DONE_; rc = WORK_RESCHEDULE_AND_RETURN; return 1; } break; case ERROR_RETURN_: { Lng32 sqlcode = 0; char * stringParam1 = NULL; Lng32 intParam1 = ComDiags_UnInitialized_Int; retcode = (short)cliInterface()->retrieveSQLDiagnostics(getDiagsArea()); if (moveErrorRow) { if (retcode == 0) { ComDiagsArea * da = getDiagsArea(); sqlcode = (short)da->mainSQLCODE(); ComCondition * cc; if (sqlcode < 0) cc = da->getErrorEntry(1); else cc = da->getWarningEntry(1); if (sqlcode < 0 && ec != NULL) *ec = sqlcode; if (cc->getOptionalStringCharSet(0) == CharInfo::ISO88591 || cc->getOptionalStringCharSet(0) == CharInfo::UTF8) stringParam1 = (char*)cc->getOptionalString(0); else stringParam1 = NULL; intParam1 = cc->getOptionalInteger(0); } else { sqlcode = retcode; } Lng32 errorBufLen = 200 + (stringParam1 ? strlen(stringParam1) : 0); char * errorBuf = new(getHeap()) char[errorBufLen]; str_sprintf(errorBuf, "%d", sqlcode); if (stringParam1) str_sprintf(&errorBuf[strlen(errorBuf)], ", %s", stringParam1); if (intParam1 != ComDiags_UnInitialized_Int) str_sprintf(&errorBuf[strlen(errorBuf)], ", %d", intParam1); char * outBuf = new(getHeap()) char[errorBufLen+400]; getStatusString(task, "Error", NULL, outBuf, NULL, NULL, errorBuf); NADELETEBASIC(errorBuf, getHeap()); if ((moveErrorRow) && (moveRowToUpQueue(outBuf, 0, &rc))) { NADELETEBASIC(outBuf, getHeap()); return 1; } NADELETEBASIC(outBuf, getHeap()); } // close cursor, etc. Ignore errors. cliInterface()->fetchRowsEpilogue(""); if (continueOnError) { pqStep_ = ALL_DONE_; rc = WORK_RESCHEDULE_AND_RETURN; return 1; } else { pqStep_ = PROLOGUE_; return -1; } } break; case ALL_DONE_: { pqStep_ = PROLOGUE_; if (warning) *warning = warning_; return 0; } break; } } }
void ExExeUtilTcb::handleErrors(Lng32 rc) { cliInterface()->retrieveSQLDiagnostics(getDiagsArea()); }
Lng32 ExExeUtilTcb::extractParts (char * objectName, char ** paramParts0, char ** paramParts1, char ** paramParts2 ) { char * parts[4]; Lng32 numParts = 0; Lng32 rc = 0; // We want to ignore any "." dots within a delimited // name. The AnsiOrNskName object is ultimately deleted // in the ExExeUtilMainObjectTcb destructor. if (extractedPartsObj_) delete extractedPartsObj_; extractedPartsObj_ = new (getHeap()) AnsiOrNskName(objectName); if ((rc = extractedPartsObj_->extractParts(numParts, parts)) != 0 || (numParts != 3)) { *getDiagsArea() << DgSqlCode(-CLI_INTERNAL_ERROR); return -1; } char * parts0 = NULL; char * parts1 = NULL; char * parts2 = NULL; Lng32 parts0Len = strlen(parts[0]); Lng32 parts1Len = strlen(parts[1]); Lng32 parts2Len = strlen(parts[2]); Lng32 parts0OffsetLen = 0; Lng32 parts1OffsetLen = 0; Lng32 parts2OffsetLen = 0; Lng32 foundParts0 = 0; Lng32 foundParts1 = 0; Lng32 foundParts2 = 0; char * testParts = NULL; char * ptr = NULL; testParts = parts[0]; ptr = (char *) strchr (testParts, '\''); while (ptr != NULL) { foundParts0++; ptr = (char *) strchr (ptr+1,'\''); } testParts = parts[1]; ptr = (char *) strchr (testParts, '\''); while (ptr != NULL) { foundParts1++; ptr = (char *) strchr (ptr+1,'\''); } testParts = parts[2]; ptr = (char *) strchr (testParts, '\''); while (ptr != NULL) { foundParts2++; ptr = (char *) strchr (ptr+1,'\''); } Lng32 lenToCopy = 0; char * beginTestParts = NULL; char * formattedParts = NULL; Lng32 totalLen = 0; if (foundParts0) { totalLen = parts0Len + foundParts0 + 1; parts0 = new(getHeap()) char[totalLen]; for (Int32 i = 0; i < totalLen; i++) parts0[i] = ' '; parts0[totalLen-1] = '\0'; testParts = parts[0]; ptr = NULL; ptr = (char *) strchr (testParts, '\''); while (ptr != NULL) { lenToCopy = ptr - testParts; strncpy(parts0 + parts0OffsetLen,testParts,++lenToCopy); strncpy(parts0 + parts0OffsetLen + lenToCopy, "'",1); testParts = testParts + lenToCopy; parts0OffsetLen += lenToCopy; parts0OffsetLen++; ptr = (char *) strchr (ptr+1,'\''); } strncpy(parts0 + parts0OffsetLen, testParts,strlen(testParts)); parts0[totalLen-1] = '\0'; } else { totalLen = parts0Len + 1; parts0 = new(getHeap()) char[totalLen]; strcpy(parts0, parts[0]); } if (foundParts1) { totalLen = parts1Len + foundParts1 + 1; parts1 = new(getHeap()) char[totalLen]; for (Int32 i = 0; i < totalLen; i++) parts1[i] = ' '; parts1[totalLen-1] = '\0'; testParts = parts[1]; ptr = NULL; ptr = (char *) strchr (testParts, '\''); while (ptr != NULL) { lenToCopy = ptr - testParts; strncpy(parts1 + parts1OffsetLen,testParts,++lenToCopy); strncpy(parts1 + parts1OffsetLen + lenToCopy, "'",1); testParts = testParts + lenToCopy; parts1OffsetLen += lenToCopy; parts1OffsetLen++; ptr = (char *) strchr (ptr+1,'\''); } strncpy(parts1 + parts1OffsetLen, testParts,strlen(testParts)); parts1[totalLen-1] = '\0'; } else { totalLen = parts1Len + 1; parts1 = new(getHeap()) char[totalLen]; strcpy(parts1, parts[1]); } if (foundParts2) { totalLen = parts2Len + foundParts2 + 1; parts2 = new(getHeap()) char[totalLen]; for (Int32 i = 0; i < totalLen; i++) parts2[i] = ' '; parts2[totalLen-1] = '\0'; testParts = parts[2]; ptr = NULL; ptr = (char *) strchr (testParts, '\''); while (ptr != NULL) { lenToCopy = ptr - testParts; strncpy(parts2 + parts2OffsetLen,testParts,++lenToCopy); strncpy(parts2 + parts2OffsetLen + lenToCopy, "'",1); testParts = testParts + lenToCopy; parts2OffsetLen += lenToCopy; parts2OffsetLen++; ptr = (char *) strchr (ptr+1,'\''); } strncpy(parts2 + parts2OffsetLen, testParts,strlen(testParts)); parts2[totalLen-1] = '\0'; } else { totalLen = parts2Len + 1; parts2 = new(getHeap()) char[totalLen]; strcpy(parts2, parts[2]); } /* The AnsiOrNskName() method strips out the leading and ending double quotes. The following code is no longer needed. // // Strip out the delimited name quotes. // If these are not stripped out, then a maximum // name of 128 characters will cause an overflow // by actually having 130 characters. char maxName[129]; maxName[0] = '\0'; if (parts0[0] == '"') { strncpy(maxName,parts0+1,strlen(parts0) -2); maxName[strlen(parts0)-2] = '\0'; strncpy(parts0,maxName,strlen(parts0) -2); parts0[strlen(maxName)] = '\0'; } maxName[0] = '\0'; if (parts1[0] == '"') { strncpy(maxName,parts1+1,strlen(parts1) -2); maxName[strlen(parts1)-2] = '\0'; strncpy(parts1,maxName,strlen(parts1) -2); parts1[strlen(maxName)] = '\0'; } maxName[0] = '\0'; if (parts2[0] == '"') { strncpy(maxName,parts2+1,strlen(parts2) -2); maxName[strlen(parts2)-2] = '\0'; strncpy(parts2,maxName,strlen(parts2) -2); parts2[strlen(maxName)] = '\0'; } maxName[0] = '\0'; */ *paramParts0 = parts0; *paramParts1 = parts1; *paramParts2 = parts2; return 0; }
short ExExeUtilTcb::handleDone() { return ex_tcb::handleDone(&qparent_, getDiagsArea()); }
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; }
////////////////////////////////////////////////////// // work() for ExExeUtilLongRunningTcb ////////////////////////////////////////////////////// short ExExeUtilLongRunningTcb::work() { short rc = 0; Lng32 cliRC = 0; Int64 rowsDeleted = 0; Int64 transactions = 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 ESP if this is an ESP ExExeStmtGlobals *exeGlob = getGlobals()->castToExExeStmtGlobals(); ExEspStmtGlobals *espGlob = exeGlob->castToExEspStmtGlobals(); Int32 espNum = 1; // this is an ESP? if (espGlob != NULL) { espNum = (Int32) espGlob->getMyInstanceNumber(); } while (1) { switch (step_) { case INITIAL_: { step_ = LONG_RUNNING_; } break; case LONG_RUNNING_: { rc = doLongRunning(); if ((rc < 0) || (rc == 100)) { finalizeDoLongRunning(); if (rc <0) step_ = ERROR_; else // rc == 100 - done with all the transactions. step_ = DONE_; } // continue in LONG_RUNNING_ state if (rc >= 0) - success and warning. } 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; // before sending the Q_NO_DATA, send the rowcount as well thro' // the diagsArea. getDiagsArea()->setRowCount(getRowsDeleted()); ComDiagsArea *diagsArea = getDiagAreaFromUpQueueTail(); if (lrTdb().longRunningQueryPlan()) { (*diagsArea) << DgSqlCode(8450) << DgString0((char*)exeUtilTdb().getTableName()) << DgInt0(espNum) << DgInt1((Lng32)getTransactionCount()); } // insert into parent qparent_.up->insert(); //pstate.matches_ = 0; // reset the parameters. step_ = INITIAL_; transactions_ = 0; rowsDeleted_ = 0; initial_ = 1; // clear diags if any if (getDiagsArea()) { getDiagsArea()->clear(); } qparent_.down->removeHead(); return WORK_OK; } break; case ERROR_: { 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; // get rows deleted so far. getDiagsArea()->setRowCount(getRowsDeleted()); ComDiagsArea *diagsArea = up_entry->getDiagsArea(); if (diagsArea == NULL) diagsArea = ComDiagsArea::allocate(this->getGlobals()->getDefaultHeap()); else diagsArea->incrRefCount (); // setDiagsArea call below will decr ref count if (getDiagsArea()) diagsArea->mergeAfter(*getDiagsArea()); up_entry->setDiagsArea (diagsArea); // insert into parent qparent_.up->insert(); // clear diags if any, since we already sent the information // up and don't want to send it again as part of DONE_ if (getDiagsArea()) { rowsDeleted_ = 0; getDiagsArea()->clear(); } step_ = DONE_; } break; } // switch } // while }