---------- * exec_stmt_forc Execute a loop for each row from a cursor. * ---------- */
| 2809 | * ---------- |
| 2810 | */ |
| 2811 | static int |
| 2812 | exec_stmt_forc(PLpgSQL_execstate *estate, PLpgSQL_stmt_forc *stmt) |
| 2813 | { |
| 2814 | PLpgSQL_var *curvar; |
| 2815 | MemoryContext stmt_mcontext = NULL; |
| 2816 | char *curname = NULL; |
| 2817 | PLpgSQL_expr *query; |
| 2818 | ParamListInfo paramLI; |
| 2819 | Portal portal; |
| 2820 | int rc; |
| 2821 | |
| 2822 | /* ---------- |
| 2823 | * Get the cursor variable and if it has an assigned name, check |
| 2824 | * that it's not in use currently. |
| 2825 | * ---------- |
| 2826 | */ |
| 2827 | curvar = (PLpgSQL_var *) (estate->datums[stmt->curvar]); |
| 2828 | if (!curvar->isnull) |
| 2829 | { |
| 2830 | MemoryContext oldcontext; |
| 2831 | |
| 2832 | /* We only need stmt_mcontext to hold the cursor name string */ |
| 2833 | stmt_mcontext = get_stmt_mcontext(estate); |
| 2834 | oldcontext = MemoryContextSwitchTo(stmt_mcontext); |
| 2835 | curname = TextDatumGetCString(curvar->value); |
| 2836 | MemoryContextSwitchTo(oldcontext); |
| 2837 | |
| 2838 | if (SPI_cursor_find(curname) != NULL) |
| 2839 | ereport(ERROR, |
| 2840 | (errcode(ERRCODE_DUPLICATE_CURSOR), |
| 2841 | errmsg("cursor \"%s\" already in use", curname))); |
| 2842 | } |
| 2843 | |
| 2844 | /* ---------- |
| 2845 | * Open the cursor just like an OPEN command |
| 2846 | * |
| 2847 | * Note: parser should already have checked that statement supplies |
| 2848 | * args iff cursor needs them, but we check again to be safe. |
| 2849 | * ---------- |
| 2850 | */ |
| 2851 | if (stmt->argquery != NULL) |
| 2852 | { |
| 2853 | /* ---------- |
| 2854 | * OPEN CURSOR with args. We fake a SELECT ... INTO ... |
| 2855 | * statement to evaluate the args and put 'em into the |
| 2856 | * internal row. |
| 2857 | * ---------- |
| 2858 | */ |
| 2859 | PLpgSQL_stmt_execsql set_args; |
| 2860 | |
| 2861 | if (curvar->cursor_explicit_argrow < 0) |
| 2862 | ereport(ERROR, |
| 2863 | (errcode(ERRCODE_SYNTAX_ERROR), |
| 2864 | errmsg("arguments given for cursor without arguments"))); |
| 2865 | |
| 2866 | memset(&set_args, 0, sizeof(set_args)); |
| 2867 | set_args.cmd_type = PLPGSQL_STMT_EXECSQL; |
| 2868 | set_args.lineno = stmt->lineno; |
no test coverage detected