* exec_describe_statement_message * * Process a "Describe" message for a prepared statement */
| 3403 | * Process a "Describe" message for a prepared statement |
| 3404 | */ |
| 3405 | static void |
| 3406 | exec_describe_statement_message(const char *stmt_name) |
| 3407 | { |
| 3408 | CachedPlanSource *psrc; |
| 3409 | |
| 3410 | /* |
| 3411 | * Start up a transaction command. (Note that this will normally change |
| 3412 | * current memory context.) Nothing happens if we are already in one. |
| 3413 | */ |
| 3414 | start_xact_command(); |
| 3415 | |
| 3416 | /* Switch back to message context */ |
| 3417 | MemoryContextSwitchTo(MessageContext); |
| 3418 | |
| 3419 | /* Find prepared statement */ |
| 3420 | if (stmt_name[0] != '\0') |
| 3421 | { |
| 3422 | PreparedStatement *pstmt; |
| 3423 | |
| 3424 | pstmt = FetchPreparedStatement(stmt_name, true); |
| 3425 | psrc = pstmt->plansource; |
| 3426 | } |
| 3427 | else |
| 3428 | { |
| 3429 | /* special-case the unnamed statement */ |
| 3430 | psrc = unnamed_stmt_psrc; |
| 3431 | if (!psrc) |
| 3432 | ereport(ERROR, |
| 3433 | (errcode(ERRCODE_UNDEFINED_PSTATEMENT), |
| 3434 | errmsg("unnamed prepared statement does not exist"))); |
| 3435 | } |
| 3436 | |
| 3437 | /* Prepared statements shouldn't have changeable result descs */ |
| 3438 | Assert(psrc->fixed_result); |
| 3439 | |
| 3440 | /* |
| 3441 | * If we are in aborted transaction state, we can't run |
| 3442 | * SendRowDescriptionMessage(), because that needs catalog accesses. |
| 3443 | * Hence, refuse to Describe statements that return data. (We shouldn't |
| 3444 | * just refuse all Describes, since that might break the ability of some |
| 3445 | * clients to issue COMMIT or ROLLBACK commands, if they use code that |
| 3446 | * blindly Describes whatever it does.) We can Describe parameters |
| 3447 | * without doing anything dangerous, so we don't restrict that. |
| 3448 | */ |
| 3449 | if (IsAbortedTransactionBlockState() && |
| 3450 | psrc->resultDesc) |
| 3451 | ereport(ERROR, |
| 3452 | (errcode(ERRCODE_IN_FAILED_SQL_TRANSACTION), |
| 3453 | errmsg("current transaction is aborted, " |
| 3454 | "commands ignored until end of transaction block"), |
| 3455 | errdetail_abort())); |
| 3456 | |
| 3457 | if (whereToSendOutput != DestRemote) |
| 3458 | return; /* can't actually do anything... */ |
| 3459 | |
| 3460 | /* |
| 3461 | * First describe the parameters... |
| 3462 | */ |
no test coverage detected