* exec_stmt_call * * NOTE: this is used for both CALL and DO statements. */
| 2149 | * NOTE: this is used for both CALL and DO statements. |
| 2150 | */ |
| 2151 | static int |
| 2152 | exec_stmt_call(PLpgSQL_execstate *estate, PLpgSQL_stmt_call *stmt) |
| 2153 | { |
| 2154 | PLpgSQL_expr *expr = stmt->expr; |
| 2155 | LocalTransactionId before_lxid; |
| 2156 | LocalTransactionId after_lxid; |
| 2157 | ParamListInfo paramLI; |
| 2158 | SPIExecuteOptions options; |
| 2159 | int rc; |
| 2160 | |
| 2161 | /* |
| 2162 | * Make a plan if we don't have one already. |
| 2163 | */ |
| 2164 | if (expr->plan == NULL) |
| 2165 | exec_prepare_plan(estate, expr, 0); |
| 2166 | |
| 2167 | /* |
| 2168 | * A CALL or DO can never be a simple expression. |
| 2169 | */ |
| 2170 | Assert(!expr->expr_simple_expr); |
| 2171 | |
| 2172 | /* |
| 2173 | * Also construct a DTYPE_ROW datum representing the plpgsql variables |
| 2174 | * associated with the procedure's output arguments. Then we can use |
| 2175 | * exec_move_row() to do the assignments. |
| 2176 | */ |
| 2177 | if (stmt->is_call && stmt->target == NULL) |
| 2178 | stmt->target = make_callstmt_target(estate, expr); |
| 2179 | |
| 2180 | paramLI = setup_param_list(estate, expr); |
| 2181 | |
| 2182 | before_lxid = MyProc->lxid; |
| 2183 | |
| 2184 | /* |
| 2185 | * If we have a procedure-lifespan resowner, use that to hold the refcount |
| 2186 | * for the plan. This avoids refcount leakage complaints if the called |
| 2187 | * procedure ends the current transaction. |
| 2188 | * |
| 2189 | * Also, tell SPI to allow non-atomic execution. |
| 2190 | */ |
| 2191 | memset(&options, 0, sizeof(options)); |
| 2192 | options.params = paramLI; |
| 2193 | options.read_only = estate->readonly_func; |
| 2194 | options.allow_nonatomic = true; |
| 2195 | options.owner = estate->procedure_resowner; |
| 2196 | |
| 2197 | rc = SPI_execute_plan_extended(expr->plan, &options); |
| 2198 | |
| 2199 | if (rc < 0) |
| 2200 | elog(ERROR, "SPI_execute_plan_extended failed executing query \"%s\": %s", |
| 2201 | expr->query, SPI_result_code_string(rc)); |
| 2202 | |
| 2203 | after_lxid = MyProc->lxid; |
| 2204 | |
| 2205 | if (before_lxid != after_lxid) |
| 2206 | { |
| 2207 | /* |
| 2208 | * If we are in a new transaction after the call, we need to build new |
no test coverage detected