---------- * exec_stmt_open Execute an OPEN cursor statement * ---------- */
| 4599 | * ---------- |
| 4600 | */ |
| 4601 | static int |
| 4602 | exec_stmt_open(PLpgSQL_execstate *estate, PLpgSQL_stmt_open *stmt) |
| 4603 | { |
| 4604 | PLpgSQL_var *curvar; |
| 4605 | MemoryContext stmt_mcontext = NULL; |
| 4606 | char *curname = NULL; |
| 4607 | PLpgSQL_expr *query; |
| 4608 | Portal portal; |
| 4609 | ParamListInfo paramLI; |
| 4610 | |
| 4611 | /* ---------- |
| 4612 | * Get the cursor variable and if it has an assigned name, check |
| 4613 | * that it's not in use currently. |
| 4614 | * ---------- |
| 4615 | */ |
| 4616 | curvar = (PLpgSQL_var *) (estate->datums[stmt->curvar]); |
| 4617 | if (!curvar->isnull) |
| 4618 | { |
| 4619 | MemoryContext oldcontext; |
| 4620 | |
| 4621 | /* We only need stmt_mcontext to hold the cursor name string */ |
| 4622 | stmt_mcontext = get_stmt_mcontext(estate); |
| 4623 | oldcontext = MemoryContextSwitchTo(stmt_mcontext); |
| 4624 | curname = TextDatumGetCString(curvar->value); |
| 4625 | MemoryContextSwitchTo(oldcontext); |
| 4626 | |
| 4627 | if (SPI_cursor_find(curname) != NULL) |
| 4628 | ereport(ERROR, |
| 4629 | (errcode(ERRCODE_DUPLICATE_CURSOR), |
| 4630 | errmsg("cursor \"%s\" already in use", curname))); |
| 4631 | } |
| 4632 | |
| 4633 | /* ---------- |
| 4634 | * Process the OPEN according to it's type. |
| 4635 | * ---------- |
| 4636 | */ |
| 4637 | if (stmt->query != NULL) |
| 4638 | { |
| 4639 | /* ---------- |
| 4640 | * This is an OPEN refcursor FOR SELECT ... |
| 4641 | * |
| 4642 | * We just make sure the query is planned. The real work is |
| 4643 | * done downstairs. |
| 4644 | * ---------- |
| 4645 | */ |
| 4646 | query = stmt->query; |
| 4647 | if (query->plan == NULL) |
| 4648 | exec_prepare_plan(estate, query, stmt->cursor_options | CURSOR_OPT_UPDATABLE); |
| 4649 | } |
| 4650 | else if (stmt->dynquery != NULL) |
| 4651 | { |
| 4652 | /* ---------- |
| 4653 | * This is an OPEN refcursor FOR EXECUTE ... |
| 4654 | * ---------- |
| 4655 | */ |
| 4656 | portal = exec_dynquery_with_params(estate, |
| 4657 | stmt->dynquery, |
| 4658 | stmt->params, |
no test coverage detected