---------- * exec_stmt_fetch Fetch from a cursor into a target, or just * move the current position of the cursor * ---------- */
| 4755 | * ---------- |
| 4756 | */ |
| 4757 | static int |
| 4758 | exec_stmt_fetch(PLpgSQL_execstate *estate, PLpgSQL_stmt_fetch *stmt) |
| 4759 | { |
| 4760 | PLpgSQL_var *curvar; |
| 4761 | long how_many = stmt->how_many; |
| 4762 | SPITupleTable *tuptab; |
| 4763 | Portal portal; |
| 4764 | char *curname; |
| 4765 | uint64 n; |
| 4766 | MemoryContext oldcontext; |
| 4767 | |
| 4768 | /* ---------- |
| 4769 | * Get the portal of the cursor by name |
| 4770 | * ---------- |
| 4771 | */ |
| 4772 | curvar = (PLpgSQL_var *) (estate->datums[stmt->curvar]); |
| 4773 | if (curvar->isnull) |
| 4774 | ereport(ERROR, |
| 4775 | (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED), |
| 4776 | errmsg("cursor variable \"%s\" is null", curvar->refname))); |
| 4777 | |
| 4778 | /* Use eval_mcontext for short-lived string */ |
| 4779 | oldcontext = MemoryContextSwitchTo(get_eval_mcontext(estate)); |
| 4780 | curname = TextDatumGetCString(curvar->value); |
| 4781 | MemoryContextSwitchTo(oldcontext); |
| 4782 | |
| 4783 | portal = SPI_cursor_find(curname); |
| 4784 | if (portal == NULL) |
| 4785 | ereport(ERROR, |
| 4786 | (errcode(ERRCODE_UNDEFINED_CURSOR), |
| 4787 | errmsg("cursor \"%s\" does not exist", curname))); |
| 4788 | |
| 4789 | /* Calculate position for FETCH_RELATIVE or FETCH_ABSOLUTE */ |
| 4790 | if (stmt->expr) |
| 4791 | { |
| 4792 | bool isnull; |
| 4793 | |
| 4794 | /* XXX should be doing this in LONG not INT width */ |
| 4795 | how_many = exec_eval_integer(estate, stmt->expr, &isnull); |
| 4796 | |
| 4797 | if (isnull) |
| 4798 | ereport(ERROR, |
| 4799 | (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED), |
| 4800 | errmsg("relative or absolute cursor position is null"))); |
| 4801 | |
| 4802 | exec_eval_cleanup(estate); |
| 4803 | } |
| 4804 | |
| 4805 | if (!stmt->is_move) |
| 4806 | { |
| 4807 | PLpgSQL_variable *target; |
| 4808 | |
| 4809 | /* ---------- |
| 4810 | * Fetch 1 tuple from the cursor |
| 4811 | * ---------- |
| 4812 | */ |
| 4813 | SPI_scroll_cursor_fetch(portal, stmt->direction, how_many); |
| 4814 | tuptab = SPI_tuptable; |
no test coverage detected