short ExExeUtilLongRunningTcb::processInitial(Lng32 &rc) { Int64 rowsAffected = 0; setInitialOutputVarPtrList(new(getHeap()) Queue(getHeap())); setContinuingOutputVarPtrList(new(getHeap()) Queue(getHeap())); lruStmtAndPartInfo_ = new(getHeap()) char[(UInt32)(lrTdb().getLruStmtLen() + lrTdb().getPredicateLen() + 10)]; ExExeStmtGlobals *exeGlob = getGlobals()->castToExExeStmtGlobals(); ExEspStmtGlobals *espGlob = exeGlob->castToExEspStmtGlobals(); ContextCli *currContext = NULL; CliGlobals *cliGlobals = NULL; if (espGlob) { cliGlobals = GetCliGlobals(); currContext = cliGlobals->currContext(); } else { currContext = exeGlob->castToExMasterStmtGlobals()->getStatement()->getContext(); } Int32 espNum = 1; // we are executing inside an ESP go ahead and set the partition number to the // ESP instance number. The added one is because ESP instances are 0 based if (espGlob) { espNum = (Int32) espGlob->getMyInstanceNumber() + 1; } if (lrTdb().getPredicate() != NULL) str_sprintf(lruStmtAndPartInfo_, lrTdb().getLruStmt(), espNum, lrTdb().getPredicate()); else str_sprintf(lruStmtAndPartInfo_, lrTdb().getLruStmt(), espNum); lruStmtWithCKAndPartInfo_ = new(getHeap()) char[(UInt32)(lrTdb().getLruStmtWithCKLen() + lrTdb().getPredicateLen() + 10)]; if (lrTdb().getPredicate() != NULL) str_sprintf(lruStmtWithCKAndPartInfo_, lrTdb().getLruStmtWithCK(), espNum, lrTdb().getPredicate()); else str_sprintf(lruStmtWithCKAndPartInfo_, lrTdb().getLruStmtWithCK(), espNum); // All internal queries issued from CliInterface assume that // they are in ISO_MAPPING. // For LongRunning we need to send the actual ISO_MAPPING. // Save it and restore after the prepare Int32 savedIsoMapping = cliInterface()->getIsoMapping(); cliInterface()->setIsoMapping (currContext->getSessionDefaults()->getIsoMappingEnum()); // If the table we are deleting from is an IUD log table, // we need to set the parserflags to accept the special // table type and the quoted column names if (lrTdb().useParserflags()) currContext->setSqlParserFlags(0x3); rc = cliInterface()->prepareAndExecRowsPrologue(lruStmtAndPartInfo_, lruStmtWithCKAndPartInfo_, getInitialOutputVarPtrList(), getContinuingOutputVarPtrList(), rowsAffected); cliInterface()->setIsoMapping(savedIsoMapping); if (rc < 0) { return -1; } if (rc >= 0 && rowsAffected > 0) addRowsDeleted(rowsAffected); 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 }