| 249 | } |
| 250 | |
| 251 | static void |
| 252 | buildWaitGraph(GddCtx *ctx) |
| 253 | { |
| 254 | SPITupleTable *tuptable; |
| 255 | TupleDesc tupdesc; |
| 256 | List *gxids; |
| 257 | bool isnull; |
| 258 | int tuple_num; |
| 259 | int i; |
| 260 | int res; |
| 261 | volatile bool connected = false; |
| 262 | |
| 263 | /* |
| 264 | * SPI_connect() will switch to SPI memory context |
| 265 | */ |
| 266 | |
| 267 | PG_TRY(); |
| 268 | { |
| 269 | if (SPI_OK_CONNECT != SPI_connect()) |
| 270 | { |
| 271 | ereport(ERROR, |
| 272 | (errcode(ERRCODE_INTERNAL_ERROR), |
| 273 | errmsg("unable to connect to execute internal query"))); |
| 274 | } |
| 275 | |
| 276 | connected = true; |
| 277 | |
| 278 | PushActiveSnapshot(GetTransactionSnapshot()); |
| 279 | |
| 280 | res = SPI_execute("select * from gp_dist_wait_status();", true, 0); |
| 281 | |
| 282 | PopActiveSnapshot(); |
| 283 | |
| 284 | if (res == SPI_OK_SELECT && SPI_tuptable != NULL) |
| 285 | { |
| 286 | tuple_num = (int) SPI_processed; |
| 287 | tupdesc = SPI_tuptable->tupdesc; |
| 288 | tuptable = SPI_tuptable; |
| 289 | |
| 290 | elogif(tuple_num > 0, LOG, |
| 291 | "GDD get %d wait relationship from all segments.", tuple_num); |
| 292 | |
| 293 | /* |
| 294 | * Switch back to gdd memory context otherwise the graphs will be |
| 295 | * created in SPI memory context and freed in SPI_finish(). |
| 296 | */ |
| 297 | MemoryContextSwitchTo(gddContext); |
| 298 | |
| 299 | /* Get all valid gxids, any other gxids are considered invalid. */ |
| 300 | gxids = ListAllGxid(); |
| 301 | |
| 302 | for (i = 0; i < tuple_num; i++) |
| 303 | { |
| 304 | DistributedTransactionId waiter_xid; |
| 305 | DistributedTransactionId holder_xid; |
| 306 | HeapTuple tuple; |
| 307 | Datum d; |
| 308 | bool solidedge; |
no test coverage detected