예제 #1
0
//CmpStoredProc::Status CmpInternalSP::open(CmpISPDataObject& data)
CmpStoredProc::ExecStatus CmpInternalSP::open(CmpISPDataObject& data)
{
  CMPASSERT(state_ == NONE);
  procFuncs_ = procFuncsLookupTable_[procName()];
  if (!procFuncsLookupTable_.ValidPFuncs(procFuncs_))
  {
    *(cmpContext()->diags()) << DgSqlCode(arkcmpErrorISPNotFound) 
      << DgString0(procName().data());
    return FAIL;       
  }

  initSP_ERROR_STRUCT();
  SP_STATUS spStatus =
      (*(procFuncs_.procFunc_))( SP_PROC_OPEN, 
				(SP_ROW_DATA)data.input(),
				CmpSPExtractFunc,
				(SP_ROW_DATA)data.output(), 
				CmpSPFormatFunc,
				(SP_KEY_VALUE)data.key(), 
				CmpSPKeyValueFunc,
				&procHandle_, 
				procFuncs_.spHandle_, 
				&spError_[0]);

  if (spStatus == SP_FAIL || spStatus == SP_SUCCESS_WARNING)
  {
    // Errors or warnings, go get them
    data.output()->MoveDiags(spError_, spStatus);
    if (spStatus == SP_FAIL)
      return FAIL;
  }
  state_ = PROCESS;
  return SUCCESS; 
}
CmpStatement::ReturnStatus
CmpStatementISP::process (CmpMessageISPRequest& isp)
{
#pragma nowarn(262)   // warning elimination 
  ReturnStatus ret = CmpStatement_ERROR;

#ifdef _DEBUG
  if (getenv("DEBUG_SP2"))  DebugBreak();
#endif
  CmpCommon::context()->sqlSession()->setParentQid(isp.getParentQid()); 

  // Instantiate a CmpInternalSP
  CmpInternalSP* storedProc = new(heap_) CmpInternalSP(isp.procName(), context_);
  CMPASSERT(storedProc);
  setStoredProc(storedProc);
  reply_ = new(outHeap_) CmpMessageReplyISP(outHeap_, isp.id(), 0, 0, outHeap_);
  
  // prepare the data for execution
  // Make sure the pointer that ispData owns won't be deleted until ispData is
  // out of scope. Because of the performance reason, the pointers are copied, 
  // not the contents. 
  // The procedure flow is : 
  // .CmpContext contains CmpStatements
  // .one CmpStatementISP is created per CmpMessageISPRequest, there might be many CmpMessageGetNext to fetch more data, 
  // but they all share the same CmpStatementISP. This CmpStatementISP will be deleted when the execution of ISP is finished. 
  // .CmpStatementISP owns a CmpInternalSP, the interface to stored procedure execution. CmpInternalSP will be deleted in
  // CmpStatement::~CmpStatement
  // . CmpInternalSP owns a CmpISPDataObject which contains data passed from executor for ISP execution. this 
  // CmpISPDataObject will only be deleted when CmpInternalSP is out of scope.
  // .CmpISPDataObject is constructed from the CmpMessageISPRequest, for better performance
  // the data pointers are copied instead of duplicating the data, so it should own the
  // data member and only delete them when CmpISPDataObject is out of scope.

  // storedProc_ owns this ispData, it should be deleted in storedProc is out of scope.
  CmpISPDataObject* ispData = new(heap_) 
    CmpISPDataObject(&isp, storedProc, context_->heap(), context_);
  ISPReqId_ = isp.id();

  // open ISP
  short inputStatus = 0;
  NABoolean bufferFull = FALSE;
  for (; !bufferFull && (inputStatus = ispData->input()->next() ) == 0; )
  {
    if (storedProc->open(*ispData) == CmpStoredProc::SUCCESS)
      bufferFull = ISPFetchPut(storedProc, ispData);
    else
    {
      if ( ispData->output()->AddEOR() == 1 )
        bufferFull = TRUE;
    }
   }

  CMPASSERT(inputStatus != -1); // fail for retrieving input data

  // prepare to send the data back to executor
  ISPPrepareReply(ispData, reply_, bufferFull);

  return CmpStatement_SUCCESS;
}
NABoolean CmpStatementISP::moreData()
{
  // check the CmpISPDataObject to see whether there is more data to be fetched.

  CmpISPDataObject* ispData;
  return ( storedProc_ && ( ispData = ((CmpInternalSP*)storedProc_)->ispData() ) &&
    ispData->moreData() );
}
예제 #4
0
CmpStoredProc::ExecStatus CmpInternalSP::close(CmpISPDataObject& data)
{
  CMPASSERT(state_ == PROCESS);

  initSP_ERROR_STRUCT();
  state_ = NONE;
  SP_STATUS spStatus =
    (*(procFuncs_.procFunc_))( SP_PROC_CLOSE, 
                              (SP_ROW_DATA)data.input(),
                              CmpSPExtractFunc,
                              (SP_ROW_DATA)data.output(), 
                              CmpSPFormatFunc,
                              (SP_KEY_VALUE)data.key(), 
                              CmpSPKeyValueFunc,
                              &procHandle_, 
                              procFuncs_.spHandle_, 
                              &spError_[0]);
  if (spStatus != SP_SUCCESS )
  {
    data.output()->MoveDiags(spError_, spStatus);
    return FAIL;
  }
  return SUCCESS;
} 
예제 #5
0
CmpStoredProc::ExecStatus CmpInternalSP::fetch(CmpISPDataObject& data)
{
  CMPASSERT(state_ == PROCESS);

  // Need to send controls explicitly from the compiler space to the
  // cli context so ISP requests can perform CLI operations to extract
  // their values.
  // For now, only send controls for MODIFY, POPULATE INDEX, TRANSFORM,
  // PURGEDATA, MV_refresh and VALIDATE sp requests.
  // This also means RECOVER since these operations
  // can be perfomed through a RECOVER operation.
  //
  // VO, Versioning Light: Also send controls for sp_SchLevel
  //                       (UPGRADE and DOWNGRADE)
  if (procName() == "sp_partn" || 
      procName() == "sp_populate" ||
      procName() == "sp_purgedata" ||
      procName() == "sp_recover" ||
      procName() == "sp_transform" ||
      procName() == "sp_validate" || 
      procName() == "sp_purgedata" ||
      procName() == "sp_refresh" ||
      procName() == "sp_SchLevel")  
    {
      sendAllControls(FALSE, FALSE, TRUE);
      
      // set the parent qid for this session
      const char *parentQid = cmpContext()->sqlSession()->getParentQid();
      if (parentQid != NULL)
	{
	  setParentQidAtSession(cmpContext()->statementHeap(), parentQid);
	}
    }

  // Send sqlparser_flags
  if (Get_SqlParser_Flags(ALLOW_FUNNY_IDENTIFIER))
    sendParserFlag(ALLOW_FUNNY_IDENTIFIER);

  initSP_ERROR_STRUCT();
  SP_STATUS spStatus =
      (*(procFuncs_.procFunc_))( SP_PROC_FETCH, 
                                (SP_ROW_DATA)data.input(),
                                CmpSPExtractFunc,
                                (SP_ROW_DATA)data.output(), 
                                CmpSPFormatFunc,
                                (SP_KEY_VALUE)data.key(), 
                                CmpSPKeyValueFunc,
                                &procHandle_, 
                                procFuncs_.spHandle_, 
                                &spError_[0]);

  if (spStatus == SP_FAIL)
  {
    // Errors, go get them
    data.output()->MoveDiags(spError_, spStatus);
    if (CmpCommon::diags() != NULL)
    {
      data.output()->MergeDiags(CmpCommon::diags());
      CmpCommon::diags()->clear();
    }
    return FAIL;
  }

  if (CmpCommon::diags() != NULL)
  {
    data.output()->MergeDiags(CmpCommon::diags());
    CmpCommon::diags()->clear();
  }

  if ( spStatus == SP_MOREDATA)
  {
    return MOREDATA;
  }
  return SUCCESS;
}