LmResult LmRoutineCppObj::invokeRoutineMethod( /* IN */ tmudr::UDRInvocationInfo::CallPhase phase, /* IN */ const char *serializedInvocationInfo, /* IN */ Int32 invocationInfoLen, /* OUT */ Int32 *invocationInfoLenOut, /* IN */ const char *serializedPlanInfo, /* IN */ Int32 planInfoLen, /* IN */ Int32 planNum, /* OUT */ Int32 *planInfoLenOut, /* IN */ char *inputParamRow, /* IN */ Int32 inputParamRowLen, /* OUT */ char *outputRow, /* IN */ Int32 outputRowLen, /* IN/OUT */ ComDiagsArea *da) { LmResult result = LM_OK; // initialize out parameters *invocationInfoLenOut = 0; *planInfoLenOut = 0; // some parameter checks if (invocationInfoLen <= 0 && invocationInfo_ == NULL) { // we need to have an Invocation info *da << DgSqlCode(-LME_OBJECT_INTERFACE_ERROR) << DgString0(getNameForDiags()) << DgString1(tmudr::UDRInvocationInfo::callPhaseToString( tmudr::UDRInvocationInfo::COMPILER_INITIAL_CALL)) << DgString2("LmRoutineCppObj::invokeRoutineMethod()") << DgString3("Missing UDRInvocationInfo"); } try { if (invocationInfoLen > 0) { if (invocationInfo_ == NULL) invocationInfo_ = new tmudr::UDRInvocationInfo; // unpack the invocation info invocationInfo_->deserializeObj(serializedInvocationInfo, invocationInfoLen); } if (planInfoLen > 0) { if (!planInfos_.used(planNum)) planInfos_.insertAt(planNum, new tmudr::UDRPlanInfo(invocationInfo_, planNum)); // unpack the invocation info planInfos_[planNum]->deserializeObj(serializedPlanInfo, planInfoLen); } // some parameter checks if (inputParamRowLen < inputParamRowLen_) return LM_ERR; // test to do for scalar UDFs // if (outputRowLen < invocationInfo_->out().getRecordLength()) // return LM_ERR; if (inputParamRow && inputParamRowLen_ > 0) // copy parameter row memcpy(invocationInfo_->par().getRowPtr(), inputParamRow, inputParamRowLen_); invocationInfo_->callPhase_ = phase; switch (phase) { case tmudr::UDRInvocationInfo::COMPILER_INITIAL_CALL: if (invocationInfo_->getDebugFlags() & tmudr::UDRInvocationInfo::PRINT_INVOCATION_INFO_INITIAL) invocationInfo_->print(); if (invocationInfo_->getDebugFlags() & tmudr::UDRInvocationInfo::DEBUG_INITIAL_COMPILE_TIME_LOOP) if (invocationInfo_->getSessionUser() == ComUser::getRootUserName()) interfaceObj_->debugLoop(); else if (da) *da << DgSqlCode(1260); // warning, only root user can debug interfaceObj_->describeParamsAndColumns(*invocationInfo_); break; case tmudr::UDRInvocationInfo::COMPILER_DATAFLOW_CALL: interfaceObj_->describeDataflowAndPredicates(*invocationInfo_); break; case tmudr::UDRInvocationInfo::COMPILER_CONSTRAINTS_CALL: interfaceObj_->describeConstraints(*invocationInfo_); break; case tmudr::UDRInvocationInfo::COMPILER_STATISTICS_CALL: interfaceObj_->describeStatistics(*invocationInfo_); break; case tmudr::UDRInvocationInfo::COMPILER_DOP_CALL: interfaceObj_->describeDesiredDegreeOfParallelism( *invocationInfo_, *planInfos_[planNum]); break; case tmudr::UDRInvocationInfo::COMPILER_PLAN_CALL: interfaceObj_->describePlanProperties(*invocationInfo_, *planInfos_[planNum]); break; case tmudr::UDRInvocationInfo::COMPILER_COMPLETION_CALL: interfaceObj_->completeDescription(*invocationInfo_, *planInfos_[planNum]); if (invocationInfo_->getDebugFlags() & tmudr::UDRInvocationInfo::PRINT_INVOCATION_INFO_END_COMPILE) { invocationInfo_->print(); printf("\n"); for (CollIndex i=0; i<planInfos_.getUsedLength(); i++) if (planInfos_.used(i)) { if (i == planNum) printf("++++++++++ Chosen plan: ++++++++++\n"); else printf("-------- Plan not chosen: --------\n"); planInfos_[i]->print(); } } break; case tmudr::UDRInvocationInfo::RUNTIME_WORK_CALL: { if (invocationInfo_->getDebugFlags() & tmudr::UDRInvocationInfo::PRINT_INVOCATION_INFO_AT_RUN_TIME) { invocationInfo_->print(); planInfos_[planNum]->print(); } if ((invocationInfo_->getDebugFlags() & tmudr::UDRInvocationInfo::DEBUG_INITIAL_RUN_TIME_LOOP_ALL) || (invocationInfo_->getDebugFlags() & tmudr::UDRInvocationInfo::DEBUG_INITIAL_RUN_TIME_LOOP_ONE && invocationInfo_->getMyInstanceNum() == 0)) interfaceObj_->debugLoop(); interfaceObj_->processData(*invocationInfo_, *planInfos_[planNum]); if (result == LM_OK) { if (invocationInfo_->getDebugFlags() & tmudr::UDRInvocationInfo::TRACE_ROWS) printf("(%d) Emitting EOD\n", invocationInfo_->getMyInstanceNum()); // call emitRow to indicate EOD, something the // C interface would do inside the UDF SQLUDR_Q_STATE qstate = SQLUDR_Q_EOD; (*interfaceObj_->emitRowPtr_)( invocationInfo_->out().getRowPtr(), 0, &qstate); } } break; default: *da << DgSqlCode(-11111) << DgString0("Invalid call phase in LmRoutineCppObj::invokeRoutineMethod()"); result = LM_ERR; break; } // return length of updated invocation and plan info for // compile-time phases if (invocationInfo_ && phase < tmudr::UDRInvocationInfo::RUNTIME_WORK_CALL) { *invocationInfoLenOut = invocationInfo_->serializedLength(); if (planInfos_.used(planNum)) *planInfoLenOut = planInfos_[planNum]->serializedLength(); } } catch (tmudr::UDRException e) { // Check the returned SQLSTATE value and raise appropriate // SQL code. Valid SQLSTATE values begin with "38" except "38000" const char *sqlState = e.getSQLState(); if ((strncmp(sqlState, "38", 2) == 0) && (strncmp(sqlState, "38000", 5) != 0)) { *da << DgSqlCode(-LME_CUSTOM_ERROR) << DgString0(e.getMessage().c_str()) << DgString1(sqlState); *da << DgCustomSQLState(sqlState); } else { *da << DgSqlCode(-LME_UDF_ERROR) << DgString0(invocationInfo_->getUDRName().c_str()) << DgString1(sqlState) << DgString2(e.getMessage().c_str()); } result = LM_ERR; } catch (...) { *da << DgSqlCode(-LME_OBJECT_INTERFACE_ERROR) << DgString0(getNameForDiags()) << DgString1(invocationInfo_->callPhaseToString(phase)) << DgString2("LmRoutineCppObj::invokeRoutineMethod()") << DgString3("general exception"); result = LM_ERR; } invocationInfo_->callPhase_ = tmudr::UDRInvocationInfo::UNKNOWN_CALL_PHASE; return result; }
LmResult LmRoutineCppObj::getRoutineInvocationInfo( /* IN/OUT */ char *serializedInvocationInfo, /* IN */ Int32 invocationInfoMaxLen, /* OUT */ Int32 *invocationInfoLenOut, /* IN/OUT */ char *serializedPlanInfo, /* IN */ Int32 planInfoMaxLen, /* IN */ Int32 planNum, /* OUT */ Int32 *planInfoLenOut, /* IN/OUT */ ComDiagsArea *da) { LmResult result = LM_OK; // Retrieve updated invocation and plan info. // The invokeRoutineMethod provided the required buffer // space, so there is no excuse for having insufficient // buffer when calling this, and doing so will raise // an exception in the try block below. try { if (invocationInfo_ && invocationInfoMaxLen > 0) { char *tempiibuf = serializedInvocationInfo; int tempiilen = invocationInfoMaxLen; *invocationInfoLenOut = invocationInfo_->serialize( tempiibuf, tempiilen); } else *invocationInfoLenOut = 0; if (planInfos_.used(planNum) && planInfoMaxLen > 0) { char *temppibuf = serializedPlanInfo; int temppilen = planInfoMaxLen; *planInfoLenOut = planInfos_[planNum]->serialize( temppibuf, temppilen); } else *planInfoLenOut = 0; } catch (tmudr::UDRException e) { // this UDRException is generated by Trafodion code and // it is an internal error to fail serializing the structs, // even though the user might have caused it by corrupting // these structs *da << DgSqlCode(-LME_OBJECT_INTERFACE_ERROR) << DgString0(getNameForDiags()) << DgString1(invocationInfo_->callPhaseToString(invocationInfo_->getCallPhase())) << DgString2("LmRoutineCppObj::getRoutineInvocationInfo()") << DgString3(e.getMessage().c_str()); result = LM_ERR; } catch (...) { *da << DgSqlCode(-LME_OBJECT_INTERFACE_ERROR) << DgString0(getNameForDiags()) << DgString1(invocationInfo_->callPhaseToString(invocationInfo_->getCallPhase())) << DgString2("LmRoutineCppObj::getRoutineInvocationInfo()") << DgString3("general exception"); result = LM_ERR; } return result; }
static void CmpSPERROR2Diags(const SP_ERROR_STRUCT* spError, ComDiagsArea* diags) { if ( !diags ) return; if (spError[0].error == arkcmpErrorISPMergeCatDiags) { // Special error message to indicate that errors should really be // merged in from the catalog manager diags area. // not supported, raise unsupported error instead *diags << DgSqlCode(-4222) << DgString0("CmpSPERROR2Diags"); return; } for ( Int32 i=0; i< SP_MAX_ERROR_STRUCTS; i++) { const SP_ERROR_STRUCT* pSET = &(spError[i]); if (pSET->error) { *diags << DgSqlCode(pSET->error); if(pSET->error == -20067) { //IDS_UTILITIES_BADSYNTAX = 20067 // If utilities parser returned syntax error for syntax based // utilities, error IDS_UTILITIES_BADSYNTAX is returned by // utilities code to mxmcp. // pSET->optionalString[1] has the utilities command from command line. // pSET->optionalInteger[0] has the approximate position of error in // the syntax of the utilities command given by user in command line. // The approximate error position is returned by utilities parser. // Function StoreSyntaxError(.....) takes the information to put a // caret (^) in the approximate position of the command and the // information is saved in diags. StoreSyntaxError(pSET->optionalString[1], // const char * input_str pSET->optionalInteger[0], // Int32 input_pos *diags, // ComDiagsArea & diagsArea 0, // Int32 dgStrNum CharInfo::UTF8, // CharInfo::CharSet input_str_cs CharInfo::UTF8); // CharInfo::CharSet terminal_cs } else{ if ( pSET->optionalString[0] && pSET->optionalString[0] != (char *) ComDiags_UnInitialized_Int ) *diags << DgString0(pSET->optionalString[0]); if ( pSET->optionalString[1] && pSET->optionalString[1] != (char *)ComDiags_UnInitialized_Int ) *diags << DgString1(pSET->optionalString[1]); if ( pSET->optionalString[2] && pSET->optionalString[2] != (char *)ComDiags_UnInitialized_Int ) *diags << DgString2(pSET->optionalString[2]); if ( pSET->optionalString[3] && pSET->optionalString[3] != (char *)ComDiags_UnInitialized_Int ) *diags << DgString3(pSET->optionalString[3]); if ( pSET->optionalString[4] && pSET->optionalString[4] != (char *)ComDiags_UnInitialized_Int ) *diags << DgString4(pSET->optionalString[4]); if ( pSET->optionalInteger[0] != ComDiags_UnInitialized_Int ) *diags << DgInt0(pSET->optionalInteger[0]); if ( pSET->optionalInteger[1] != ComDiags_UnInitialized_Int ) *diags << DgInt1(pSET->optionalInteger[1]); if ( pSET->optionalInteger[2] != ComDiags_UnInitialized_Int ) *diags << DgInt2(pSET->optionalInteger[2]); if ( pSET->optionalInteger[3] != ComDiags_UnInitialized_Int ) *diags << DgInt3(pSET->optionalInteger[3]); if ( pSET->optionalInteger[4] != ComDiags_UnInitialized_Int ) *diags << DgInt4(pSET->optionalInteger[4]); } } else if ( i==0 ) { // this is the case that ISP implementation does not return any // SP_ERROR_STRUCT info back, but does return with error status. *diags << DgSqlCode(arkcmpErrorISPNoSPError); break; } else // no more SP_ERROR_STRUCT. break; } }