* End the gp-specific part of the executor. * * In here we collect the dispatch results if there are any, tear * down the interconnect if it is set-up. */
| 1997 | * down the interconnect if it is set-up. |
| 1998 | */ |
| 1999 | void mppExecutorFinishup(QueryDesc *queryDesc) |
| 2000 | { |
| 2001 | EState *estate; |
| 2002 | ExecSlice *currentSlice; |
| 2003 | int primaryWriterSliceIndex; |
| 2004 | |
| 2005 | /* caller must have switched into per-query memory context already */ |
| 2006 | estate = queryDesc->estate; |
| 2007 | |
| 2008 | currentSlice = getCurrentSlice(estate, LocallyExecutingSliceIndex(estate)); |
| 2009 | primaryWriterSliceIndex = PrimaryWriterSliceIndex(estate); |
| 2010 | |
| 2011 | /* Teardown the Interconnect */ |
| 2012 | if (estate->es_interconnect_is_setup) |
| 2013 | { |
| 2014 | Assert(CurrentMotionIPCLayer); |
| 2015 | CurrentMotionIPCLayer->TeardownInterconnect(estate->interconnect_context, false); |
| 2016 | estate->interconnect_context = NULL; |
| 2017 | estate->es_interconnect_is_setup = false; |
| 2018 | } |
| 2019 | /* |
| 2020 | * If we are finishing a query before all the tuples of the query |
| 2021 | * plan were fetched we must call ExecSquelchNode before checking |
| 2022 | * the dispatch results in order to tell we no longer |
| 2023 | * need any more tuples. |
| 2024 | */ |
| 2025 | if (Gp_role == GP_ROLE_DISPATCH && !estate->es_got_eos && |
| 2026 | !(estate->es_top_eflags & EXEC_FLAG_EXPLAIN_ONLY)) |
| 2027 | { |
| 2028 | ExecSquelchNode(queryDesc->planstate, true); |
| 2029 | } |
| 2030 | /* |
| 2031 | * If QD, wait for QEs to finish and check their results. |
| 2032 | */ |
| 2033 | if (estate->dispatcherState && estate->dispatcherState->primaryResults) |
| 2034 | { |
| 2035 | CdbDispatchResults *pr = NULL; |
| 2036 | CdbDispatcherState *ds = estate->dispatcherState; |
| 2037 | DispatchWaitMode waitMode = DISPATCH_WAIT_NONE; |
| 2038 | ErrorData *qeError = NULL; |
| 2039 | |
| 2040 | /* |
| 2041 | * Wait for completion of all QEs. We send a "graceful" query |
| 2042 | * finish, not cancel signal. Since the query has succeeded, |
| 2043 | * don't confuse QEs by sending erroneous message. |
| 2044 | */ |
| 2045 | if (estate->cancelUnfinished) |
| 2046 | waitMode = DISPATCH_WAIT_FINISH; |
| 2047 | |
| 2048 | cdbdisp_checkDispatchResult(ds, waitMode); |
| 2049 | |
| 2050 | pr = cdbdisp_getDispatchResults(ds, &qeError); |
| 2051 | |
| 2052 | if (qeError) |
| 2053 | { |
| 2054 | estate->dispatcherState = NULL; |
| 2055 | FlushErrorState(); |
| 2056 | ThrowErrorData(qeError); |
no test coverage detected