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());
}
Esempio n. 10
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;
}
Esempio n. 11
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

}