* CREATE PROCEDURE dbms_sql.column_value(c int, pos int, INOUT value "any"); * Note - CALL statement is slow from PLpgSQL block (against function execution). * This is reason why this routine is in function form too. */
| 1701 | * This is reason why this routine is in function form too. |
| 1702 | */ |
| 1703 | Datum |
| 1704 | dbms_sql_column_value(PG_FUNCTION_ARGS) |
| 1705 | { |
| 1706 | CursorData *c; |
| 1707 | Datum value; |
| 1708 | Datum result; |
| 1709 | int pos; |
| 1710 | bool isnull; |
| 1711 | Oid targetTypeId; |
| 1712 | Oid resultTypeId; |
| 1713 | TupleDesc resulttupdesc; |
| 1714 | HeapTuple resulttuple; |
| 1715 | MemoryContext oldcxt; |
| 1716 | |
| 1717 | if (SPI_connect() != SPI_OK_CONNECT) |
| 1718 | elog(ERROR, "SPI_connact failed"); |
| 1719 | |
| 1720 | c = get_cursor(fcinfo, true); |
| 1721 | |
| 1722 | if (PG_ARGISNULL(1)) |
| 1723 | ereport(ERROR, |
| 1724 | (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED), |
| 1725 | errmsg("column position (number) is NULL"))); |
| 1726 | |
| 1727 | pos = PG_GETARG_INT32(1); |
| 1728 | |
| 1729 | if (!c->executed) |
| 1730 | ereport(ERROR, |
| 1731 | (errcode(ERRCODE_INVALID_CURSOR_STATE), |
| 1732 | errmsg("cursor is not executed"))); |
| 1733 | |
| 1734 | oldcxt = MemoryContextSwitchTo(c->result_cxt); |
| 1735 | |
| 1736 | |
| 1737 | /* |
| 1738 | * Setting of OUT field is little bit more complex, because although |
| 1739 | * there is only one output field, the result should be compisite type. |
| 1740 | */ |
| 1741 | if (get_call_result_type(fcinfo, &resultTypeId, &resulttupdesc) == TYPEFUNC_COMPOSITE) |
| 1742 | { |
| 1743 | /* check target types */ |
| 1744 | if (resulttupdesc->natts != 1) |
| 1745 | /* internal error, should not to be */ |
| 1746 | elog(ERROR, "unexpected number of result composite fields"); |
| 1747 | |
| 1748 | targetTypeId = get_fn_expr_argtype(fcinfo->flinfo, 2); |
| 1749 | Assert((TupleDescAttr(resulttupdesc, 0))->atttypid == targetTypeId); |
| 1750 | } |
| 1751 | else |
| 1752 | /* internal error, should not to be */ |
| 1753 | elog(ERROR, "unexpected function result type"); |
| 1754 | |
| 1755 | value = column_value(c, pos, targetTypeId, &isnull, false); |
| 1756 | |
| 1757 | resulttuple = heap_form_tuple(resulttupdesc, &value, &isnull); |
| 1758 | result = PointerGetDatum(SPI_returntuple(resulttuple, CreateTupleDescCopy(resulttupdesc))); |
| 1759 | |
| 1760 | SPI_finish(); |
nothing calls this directly
no test coverage detected