* ExtensionExecuteQueryViaSPI executes given query via SPI and returns first * attribute of the first tuple returned. * * Throws an error if command fails, or connection establishment to SPI fails * for some reason. * * Note that returning NULL doesn't mean failure. It either means returned * attribute is NULL or query returned nothing at all. In that case, isNull * is set to true. */
| 53 | * is set to true. |
| 54 | */ |
| 55 | Datum |
| 56 | ExtensionExecuteQueryViaSPI(const char *query, bool readOnly, int expectedSPIOK, |
| 57 | bool *isNull) |
| 58 | { |
| 59 | if (SPI_connect() != SPI_OK_CONNECT) |
| 60 | { |
| 61 | ereport(ERROR, (errmsg("could not connect to SPI manager"))); |
| 62 | } |
| 63 | |
| 64 | ereport(DEBUG1, (errmsg("executing \"%s\" via SPI", query), errhidestmt(true), |
| 65 | errhidecontext(true))); |
| 66 | |
| 67 | int tupleCountLimit = 1; |
| 68 | int spiErrorCode = SPI_execute(query, readOnly, tupleCountLimit); |
| 69 | if (spiErrorCode != expectedSPIOK) |
| 70 | { |
| 71 | ereport(ERROR, (errmsg("could not run SPI query %d", spiErrorCode))); |
| 72 | } |
| 73 | |
| 74 | Datum retDatum = SPIReturnDatum(isNull, 1); |
| 75 | |
| 76 | if (SPI_finish() != SPI_OK_FINISH) |
| 77 | { |
| 78 | ereport(ERROR, (errmsg("could not finish SPI connection"))); |
| 79 | } |
| 80 | |
| 81 | return retDatum; |
| 82 | } |
| 83 | |
| 84 | |
| 85 | /* |
no test coverage detected