| 1420 | |
| 1421 | |
| 1422 | bool |
| 1423 | dispatchDtxCommand(const char *cmd) |
| 1424 | { |
| 1425 | int i, |
| 1426 | numOfFailed = 0; |
| 1427 | |
| 1428 | CdbPgResults cdb_pgresults = {NULL, 0}; |
| 1429 | |
| 1430 | elog(DTM_DEBUG5, "dispatchDtxCommand: '%s'", cmd); |
| 1431 | |
| 1432 | if (currentGxactWriterGangLost()) |
| 1433 | { |
| 1434 | ereport(WARNING, |
| 1435 | (errmsg("writer gang of current global transaction is lost"))); |
| 1436 | return false; |
| 1437 | } |
| 1438 | |
| 1439 | CdbDispatchCommand(cmd, DF_NEED_TWO_PHASE, &cdb_pgresults); |
| 1440 | |
| 1441 | if (cdb_pgresults.numResults == 0) |
| 1442 | { |
| 1443 | return false; /* If we got no results, we need to treat it |
| 1444 | * as an error! */ |
| 1445 | } |
| 1446 | |
| 1447 | for (i = 0; i < cdb_pgresults.numResults; i++) |
| 1448 | { |
| 1449 | char *cmdStatus; |
| 1450 | ExecStatusType resultStatus; |
| 1451 | |
| 1452 | /* |
| 1453 | * note: PQresultStatus() is smart enough to deal with results[i] == |
| 1454 | * NULL |
| 1455 | */ |
| 1456 | resultStatus = PQresultStatus(cdb_pgresults.pg_results[i]); |
| 1457 | if (resultStatus != PGRES_COMMAND_OK && |
| 1458 | resultStatus != PGRES_TUPLES_OK) |
| 1459 | { |
| 1460 | numOfFailed++; |
| 1461 | } |
| 1462 | else |
| 1463 | { |
| 1464 | /* |
| 1465 | * success ? If an error happened during a transaction which |
| 1466 | * hasn't already been caught when we try a prepare we'll get a |
| 1467 | * rollback from our prepare ON ONE SEGMENT: so we go look at the |
| 1468 | * status, otherwise we could issue a COMMIT when we don't want |
| 1469 | * to! |
| 1470 | */ |
| 1471 | cmdStatus = PQcmdStatus(cdb_pgresults.pg_results[i]); |
| 1472 | |
| 1473 | elog(DEBUG3, "DTM: status message cmd '%s' [%d] result '%s'", cmd, i, cmdStatus); |
| 1474 | if (strncmp(cmdStatus, cmd, strlen(cmdStatus)) != 0) |
| 1475 | { |
| 1476 | /* failed */ |
| 1477 | numOfFailed++; |
| 1478 | } |
| 1479 | } |
no test coverage detected