* ExplainOnePlan - * given a planned query, execute it if needed, and then print * EXPLAIN output * * "into" is NULL unless we are explaining the contents of a CreateTableAsStmt, * in which case executing the query should result in creating that table. * * This is exported because it's called back from prepare.c in the * EXPLAIN EXECUTE case, and because an index advisor plugin would nee
| 675 | * to call it. |
| 676 | */ |
| 677 | void |
| 678 | ExplainOnePlan(PlannedStmt *plannedstmt, IntoClause *into, ExplainState *es, |
| 679 | const char *queryString, ParamListInfo params, |
| 680 | QueryEnvironment *queryEnv, const instr_time *planduration, |
| 681 | const BufferUsage *bufusage, |
| 682 | int cursorOptions) |
| 683 | { |
| 684 | DestReceiver *dest; |
| 685 | QueryDesc *queryDesc; |
| 686 | instr_time starttime; |
| 687 | double totaltime = 0; |
| 688 | int eflags; |
| 689 | int instrument_option = 0; |
| 690 | |
| 691 | Assert(plannedstmt->commandType != CMD_UTILITY); |
| 692 | |
| 693 | if (es->analyze && es->timing) |
| 694 | instrument_option |= INSTRUMENT_TIMER; |
| 695 | else if (es->analyze) |
| 696 | instrument_option |= INSTRUMENT_ROWS; |
| 697 | |
| 698 | if (es->buffers) |
| 699 | instrument_option |= INSTRUMENT_BUFFERS; |
| 700 | if (es->wal) |
| 701 | instrument_option |= INSTRUMENT_WAL; |
| 702 | |
| 703 | if (es->analyze) |
| 704 | instrument_option |= INSTRUMENT_CDB; |
| 705 | |
| 706 | if (es->memory_detail) |
| 707 | instrument_option |= INSTRUMENT_MEMORY_DETAIL; |
| 708 | |
| 709 | /* |
| 710 | * We always collect timing for the entire statement, even when node-level |
| 711 | * timing is off, so we don't look at es->timing here. (We could skip |
| 712 | * this if !es->summary, but it's hardly worth the complication.) |
| 713 | */ |
| 714 | INSTR_TIME_SET_CURRENT(starttime); |
| 715 | |
| 716 | /* |
| 717 | * Use a snapshot with an updated command ID to ensure this query sees |
| 718 | * results of any previously executed queries. |
| 719 | */ |
| 720 | PushCopiedSnapshot(GetActiveSnapshot()); |
| 721 | UpdateActiveSnapshotCommandId(); |
| 722 | |
| 723 | /* |
| 724 | * Normally we discard the query's output, but if explaining CREATE TABLE |
| 725 | * AS, we'd better use the appropriate tuple receiver. |
| 726 | */ |
| 727 | if (into) |
| 728 | dest = CreateIntoRelDestReceiver(into); |
| 729 | else |
| 730 | dest = None_Receiver; |
| 731 | |
| 732 | // GPDB_14_MERGE_FIXME: fix intoClause in optimizer |
| 733 | plannedstmt->intoClause = copyObject(into); |
| 734 | /* Create a QueryDesc for the query */ |
no test coverage detected