void processALoadMessage(UdrGlobals *UdrGlob, UdrServerReplyStream &msgStream, UdrLoadMsg &request, IpcEnvironment &env) { const char *moduleName = "processALoadMessage"; char errorText[MAXERRTEXT]; ComDiagsArea *diags = ComDiagsArea::allocate(UdrGlob->getIpcHeap()); doMessageBox(UdrGlob, TRACE_SHOW_DIALOGS, UdrGlob->showLoad_, moduleName); NABoolean showLoadLogic = (UdrGlob->verbose_ && UdrGlob->traceLevel_ >= TRACE_IPMS && UdrGlob->showLoad_); if (showLoadLogic) { ServerDebug("[UdrServ (%s)] Processing load request", moduleName); } // UDR_LOAD message always comes with transaction and they are out // side Enter Tx and Exit Tx pair. Make sure we are under correct // transaction. msgStream.activateCurrentMsgTransaction(); // // Check to see if the incoming UDR handle has already been seen // NABoolean handleAlreadyExists = FALSE; SPInfo *sp = UdrGlob->getSPList()->spFind(request.getHandle()); if (sp) { handleAlreadyExists = TRUE; if (showLoadLogic) { ServerDebug(" Duplicate handle arrived"); ServerDebug(" SPInfoState is %s", sp->getSPInfoStateString()); } if (sp->getSPInfoState() != SPInfo::UNLOADING) { // // An SPInfo exists but it is not one of the token instances to // represent an out-of-sequence LOAD/UNLOAD. This is an internal // error. Something has been botched in the message protocol. // char buf[100]; convertInt64ToAscii(request.getHandle(), buf); *diags << DgSqlCode(-UDR_ERR_DUPLICATE_LOADS); *diags << DgString0(buf); } else { // The LOAD/UNLOAD requests for this handle arrived // out-of-sequence. Nothing to do at this point. An empty reply // will be generated later in this function. } } if (!handleAlreadyExists) { if (!UdrHandleIsValid(request.getHandle())) { *diags << DgSqlCode(-UDR_ERR_MISSING_UDRHANDLE); *diags << DgString0("Load Message"); } else { // // First process the metadata in the LOAD requests and then // contact Language Manager to load the SP. // sp = processLoadParameters(UdrGlob, request, *diags); if (showLoadLogic) { ServerDebug("[UdrServ (%s)] About to call LM::getRoutine", moduleName); } if (sp == NULL) { *diags << DgSqlCode(-UDR_ERR_UNABLE_TO_ALLOCATE_MEMORY); *diags << DgString0("SPInfo"); } else { UdrGlob->setCurrSP(sp); LmRoutine *lmRoutine; LmResult lmResult; LmLanguageManager *lm = UdrGlob->getOrCreateLM(lmResult, sp->getLanguage(), diags); LmHandle emitRowFuncPtr; if (sp->getParamStyle() == COM_STYLE_CPP_OBJ) emitRowFuncPtr = (LmHandle)&SpInfoEmitRowCpp; else emitRowFuncPtr = (LmHandle)&SpInfoEmitRow; if (lm) { if (sp->getParamStyle() == COM_STYLE_JAVA_OBJ || sp->getParamStyle() == COM_STYLE_CPP_OBJ) { lmResult = lm->getObjRoutine( request.getUDRSerInvocationInfo(), request.getUDRSerInvocationInfoLen(), request.getUDRSerPlanInfo(), request.getUDRSerPlanInfoLen(), sp->getLanguage(), sp->getParamStyle(), sp->getExternalName(), sp->getContainerName(), sp->getExternalPathName(), sp->getLibrarySqlName(), &lmRoutine, diags); if (lmRoutine) { LmRoutineCppObj *objRoutine = static_cast<LmRoutineCppObj *>(lmRoutine); if (sp->getParamStyle() == COM_STYLE_CPP_OBJ) // set function pointers for functions provided // by tdm_udrserv objRoutine->setFunctionPtrs(SpInfoGetNextRow, SpInfoEmitRowCpp); // add items to the UDRInvocationInfo that are not // known at compile time (total # of instances is // kind of known, but we want to give the executor a // chance to change it) lmRoutine->setRuntimeInfo(request.getParentQid(), request.getNumInstances(), request.getInstanceNum()); #ifndef NDEBUG int debugLoop = 2; if (objRoutine->getInvocationInfo()->getDebugFlags() & tmudr::UDRInvocationInfo::DEBUG_LOAD_MSG_LOOP) debugLoop = 1; // go into a loop to allow the user to attach a debugger, // if requested, set debugLoop = 2 in the debugger to get out while (debugLoop < 2) debugLoop = 1-debugLoop; #endif } } else lmResult = lm->getRoutine(sp->getNumParameters(), sp->getLmParameters(), sp->getNumTables(), sp->getLmTables(), sp->getReturnValue(), sp->getParamStyle(), sp->getTransactionAttrs(), sp->getSQLAccessMode(), sp->getParentQid(), sp->getRequestRowSize(), sp->getReplyRowSize(), sp->getSqlName(), sp->getExternalName(), sp->getRoutineSig(), sp->getContainerName(), sp->getExternalPathName(), sp->getLibrarySqlName(), UdrGlob->getCurrentUserName(), UdrGlob->getSessionUserName(), sp->getExternalSecurity(), sp->getRoutineOwnerId(), &lmRoutine, (LmHandle)&SpInfoGetNextRow, emitRowFuncPtr, sp->getMaxNumResultSets(), diags); } if (lmResult == LM_OK) { if (lmRoutine == NULL) { *diags << DgSqlCode(-UDR_ERR_MISSING_LMROUTINE); *diags << DgString0("error: returned a null LM handle"); *diags << DgInt1((Int32)0); } else { sp->setLMHandle(lmRoutine); // Retrieve any optional data from UdrLoadMsg. copyRoutineOptionalData(request, sp); reportLoadResults(UdrGlob, sp, lmRoutine); sp->setSPInfoState(SPInfo::LOADED); } } // lmResult == LM_OK if (showLoadLogic) { if (lmResult == LM_OK) { sprintf(errorText, "[UdrServ (%.30s)] LM::getRoutine was successful.", moduleName); } else { sprintf(errorText, "[UdrServ (%.30s)] LM::getRoutine resulted in error.", moduleName); } ServerDebug(errorText); doMessageBox(UdrGlob, TRACE_SHOW_DIALOGS, UdrGlob->showMain_, errorText); } if (sp && !(sp->isLoaded())) { sp->setSPInfoState(SPInfo::LOAD_FAILED); } } // if (sp == NULL) else ... } // if (handle is not valid) else ... } // !handleAlreadyExists // build a reply and send it msgStream.clearAllObjects(); UdrLoadReply *reply = new (UdrGlob->getIpcHeap()) UdrLoadReply(UdrGlob->getIpcHeap()); if (reply == NULL) { // no reply buffer build... controlErrorReply(UdrGlob, msgStream, UDR_ERR_MESSAGE_PROCESSING, INVOKE_ERR_NO_REPLY_BUFFER, NULL); return; } // Only return a valid UDR Handle if diagnostics are not present and // no LM errors occurred. We also return a valid handle if this LOAD // arrived out-of-sequence after the UNLOAD and no diagnostics have // been generated yet. if (diags && diags->getNumber() > 0) { reply->setHandle(INVALID_UDR_HANDLE); } else if (sp) { if (sp->isLoaded() || handleAlreadyExists) { reply->setHandle(sp->getUdrHandle()); } else { reply->setHandle(INVALID_UDR_HANDLE); } } msgStream << *reply; if (diags && diags->getNumber() > 0) { msgStream << *diags; UdrGlob->numErrUDR_++; UdrGlob->numErrSP_++; UdrGlob->numErrLoadSP_++; if (showLoadLogic) dumpDiagnostics(diags, 2); } if (showLoadLogic) { ServerDebug("[UdrServ (%s)] About to send LOAD reply", moduleName); } #ifdef NA_DEBUG_C_RUNTIME if (UdrGlob && UdrGlob->getJavaLM()) { sleepIfPropertySet(*(UdrGlob->getJavaLM()), "MXUDR_LOAD_DELAY", diags); } #endif // NA_DEBUG_C_RUNTIME sendControlReply(UdrGlob, msgStream, sp); if (diags) { diags->decrRefCount(); } reply->decrRefCount(); } // processALoadMessage
SPInfo *processLoadParameters(UdrGlobals *UdrGlob, UdrLoadMsg &request, ComDiagsArea &d) { const char *moduleName = "processLoadParameters"; Lng32 oldDiags = 0; Lng32 newDiags = 0; doMessageBox(UdrGlob, TRACE_SHOW_DIALOGS, UdrGlob->showLoad_, moduleName); // check for test mode processing... SPInfo *sp = NULL; int numRetries = 0; // process message parameters... if (UdrGlob->traceLevel_ >= TRACE_DETAILS && UdrGlob->showLoad_) { displayLoadParameters(request); } doMessageBox(UdrGlob, TRACE_SHOW_DIALOGS, UdrGlob->showLoad_, "create SPInfo"); oldDiags = d.getNumber(); while (sp == NULL && numRetries < 1) { sp = new (UdrGlob->getUdrHeap()) SPInfo(UdrGlob, UdrGlob->getUdrHeap(), request.getHandle(), (char *)request.getSqlName(), (char *)request.getRoutineName(), (char *)request.getSignature(), (char *)request.getContainerName(), (char *)request.getExternalPath(), (char *)request.getLibrarySqlName(), request.getNumParameters(), request.getNumInValues(), request.getNumOutValues(), request.getMaxResultSets(), request.getTransactionAttrs(), request.getSqlAccessMode(), request.getLanguage(), request.getParamStyle(), request.isIsolate(), request.isCallOnNull(), request.isExtraCall(), request.isDeterministic(), request.getExternalSecurity(), request.getRoutineOwnerId(), request.getInBufferSize(), request.getOutBufferSize(), request.getInputRowSize(), request.getOutputRowSize(), /* ComDiagsArea */ d, (char *)request.getParentQid()); if (sp == NULL) { // memory problem UdrGlob->getSPList()->releaseOldestSPJ(/* ComDiagsArea */ d); numRetries++; } } if (sp == NULL) { return NULL; } newDiags = d.getNumber(); if (oldDiags != newDiags) { // diagnostics generated in ctor for SPInfo // something bad has happened. Bail out. delete sp; return NULL; } // Process IN/INOUT parameters ComUInt32 i; for (i = 0; i < sp->getNumInParameters(); i++) { UdrParameterInfo &pi = (UdrParameterInfo &)request.getInParam(i); // Copy information from the UdrParameterInfo into the spinfo. The // spinfo will initialize an LmParameter instance for this // parameter. sp->setInParam(i, pi); } // Process OUT/INOUT parameters for (ComUInt32 j = 0; j < sp->getNumOutParameters(); j++) { UdrParameterInfo &po = (UdrParameterInfo &)request.getOutParam(j); // Copy information from the UdrParameterInfo into the spinfo. The // spinfo will initialize an LmParameter instance for this // parameter. Note for INOUT parameters, the LmParameter will not // be completely re-initialized. It was partially initialized in // the loop above for input parameters. This setOutParam call // completes the LmParameter initialization. sp->setOutParam(j, po); } // Process table input info if any if(sp->getParamStyle() == COM_STYLE_SQLROW_TM || sp->getParamStyle() == COM_STYLE_CPP_OBJ || sp->getParamStyle() == COM_STYLE_JAVA_OBJ) { sp->setNumTableInfo(request.getNumInputTables()); sp->setTableInputInfo(request.getInputTables()); } if (UdrGlob->verbose_ && UdrGlob->traceLevel_ >= TRACE_DETAILS && UdrGlob->showLoad_) { sp->displaySPInfo(2); } if (UdrGlob->verbose_ && UdrGlob->traceLevel_ >= TRACE_DATA_AREAS && UdrGlob->showLoad_) { ServerDebug(" LmParameter array:"); for (ComUInt32 i = 0; i < sp->getNumParameters(); i++) { dumpLmParameter(sp->getLmParameter(i), i, " "); } } if (UdrGlob->verbose_ && UdrGlob->traceLevel_ >= TRACE_DATA_AREAS && UdrGlob->showLoad_) ServerDebug(""); return sp; } // processLoadParameters