Execute a stored procedure. Begin by assigning the input parameters. End by assigning the output parameters.
| 3318 | // Execute a stored procedure. Begin by assigning the input parameters. |
| 3319 | // End by assigning the output parameters. |
| 3320 | void ExecProcedureNode::executeProcedure(thread_db* tdbb, Request* request) const |
| 3321 | { |
| 3322 | if (!procedure->isImplemented()) |
| 3323 | { |
| 3324 | status_exception::raise( |
| 3325 | Arg::Gds(isc_proc_pack_not_implemented) << |
| 3326 | Arg::Str(procedure->getName().identifier) << Arg::Str(procedure->getName().package)); |
| 3327 | } |
| 3328 | else if (!procedure->isDefined()) |
| 3329 | { |
| 3330 | status_exception::raise( |
| 3331 | Arg::Gds(isc_prcnotdef) << Arg::Str(procedure->getName().toString()) << |
| 3332 | Arg::Gds(isc_modnotfound)); |
| 3333 | } |
| 3334 | |
| 3335 | const_cast<jrd_prc*>(procedure.getObject())->checkReload(tdbb); |
| 3336 | |
| 3337 | UserId* invoker = procedure->invoker ? procedure->invoker : tdbb->getAttachment()->att_ss_user; |
| 3338 | AutoSetRestore<UserId*> userIdHolder(&tdbb->getAttachment()->att_ss_user, invoker); |
| 3339 | |
| 3340 | ULONG inMsgLength = 0; |
| 3341 | UCHAR* inMsg = NULL; |
| 3342 | |
| 3343 | if (inputMessage) |
| 3344 | { |
| 3345 | inMsgLength = inputMessage->format->fmt_length; |
| 3346 | inMsg = request->getImpure<UCHAR>(inputMessage->impureOffset); |
| 3347 | } |
| 3348 | |
| 3349 | const Format* format = NULL; |
| 3350 | ULONG outMsgLength = 0; |
| 3351 | UCHAR* outMsg = NULL; |
| 3352 | Array<UCHAR> tempBuffer; |
| 3353 | |
| 3354 | if (outputMessage) |
| 3355 | { |
| 3356 | format = outputMessage->format; |
| 3357 | outMsgLength = format->fmt_length; |
| 3358 | outMsg = request->getImpure<UCHAR>(outputMessage->impureOffset); |
| 3359 | } |
| 3360 | else |
| 3361 | { |
| 3362 | format = procedure->getOutputFormat(); |
| 3363 | outMsgLength = format->fmt_length; |
| 3364 | outMsg = tempBuffer.getBuffer(outMsgLength + FB_DOUBLE_ALIGN - 1); |
| 3365 | outMsg = FB_ALIGN(outMsg, FB_DOUBLE_ALIGN); |
| 3366 | } |
| 3367 | |
| 3368 | if (inputSources) |
| 3369 | { |
| 3370 | const NestConst<ValueExprNode>* const sourceEnd = inputSources->items.end(); |
| 3371 | const NestConst<ValueExprNode>* sourcePtr = inputSources->items.begin(); |
| 3372 | const NestConst<ValueExprNode>* targetPtr = inputTargets->items.begin(); |
| 3373 | |
| 3374 | for (; sourcePtr != sourceEnd; ++sourcePtr, ++targetPtr) |
| 3375 | EXE_assignment(tdbb, *sourcePtr, *targetPtr); |
| 3376 | } |
| 3377 |
nothing calls this directly
no test coverage detected