* cdbexplain_sendExecStats * Called by qExec process to send EXPLAIN ANALYZE statistics to qDisp. * On the qDisp, libpq will recognize our special message type ('Y') and * attach the message to the current command's PGresult object. */
| 381 | * attach the message to the current command's PGresult object. |
| 382 | */ |
| 383 | void |
| 384 | cdbexplain_sendExecStats(QueryDesc *queryDesc) |
| 385 | { |
| 386 | EState *estate; |
| 387 | PlanState *planstate; |
| 388 | CdbExplain_SendStatCtx ctx; |
| 389 | StringInfoData notebuf; |
| 390 | |
| 391 | /* Header offset (where header begins in the message buffer) */ |
| 392 | int hoff; |
| 393 | |
| 394 | Assert(Gp_role == GP_ROLE_EXECUTE); |
| 395 | |
| 396 | if (!queryDesc || |
| 397 | !queryDesc->estate) |
| 398 | return; |
| 399 | |
| 400 | /* If executing a root slice (UPD/DEL/INS), start at top of plan tree. */ |
| 401 | estate = queryDesc->estate; |
| 402 | if (LocallyExecutingSliceIndex(estate) == RootSliceIndex(estate)) |
| 403 | planstate = queryDesc->planstate; |
| 404 | |
| 405 | /* Non-root slice: Start at child of our sending Motion node. */ |
| 406 | else |
| 407 | { |
| 408 | planstate = &(getMotionState(queryDesc->planstate, LocallyExecutingSliceIndex(estate))->ps); |
| 409 | Assert(planstate && |
| 410 | IsA(planstate, MotionState) && |
| 411 | planstate->lefttree); |
| 412 | planstate = planstate->lefttree; |
| 413 | } |
| 414 | |
| 415 | if (planstate == NULL) |
| 416 | return; |
| 417 | |
| 418 | /* Start building the message header in our context area. */ |
| 419 | memset(&ctx, 0, sizeof(ctx)); |
| 420 | ctx.hdr.type = T_CdbExplain_StatHdr; |
| 421 | ctx.hdr.segindex = GpIdentity.segindex; |
| 422 | ctx.hdr.nInst = 0; |
| 423 | |
| 424 | /* Allocate a separate buffer where nodes can append extra message text. */ |
| 425 | initStringInfo(¬ebuf); |
| 426 | ctx.notebuf = ¬ebuf; |
| 427 | |
| 428 | /* Reserve buffer space for the message header (excluding 'inst' array). */ |
| 429 | pq_beginmessage(&ctx.buf, 'Y'); |
| 430 | |
| 431 | /* Where the actual StatHdr begins */ |
| 432 | hoff = ctx.buf.len; |
| 433 | |
| 434 | /* |
| 435 | * Write everything until inst member including "CdbExplain_SliceWorker |
| 436 | * worker" |
| 437 | */ |
| 438 | appendBinaryStringInfo(&ctx.buf, (char *) &ctx.hdr, sizeof(ctx.hdr) - sizeof(ctx.hdr.inst)); |
| 439 | |
| 440 | /* Append statistics from each PlanState node in this slice. */ |
no test coverage detected