1577{
1581 bool randomAccess;
1582 bool lazyEvalOK;
1583 bool pushed_snapshot;
1587
1588 /* Check call context */
1589 if (fcinfo->flinfo->fn_retset)
1590 {
1592
1593 /*
1594 * For simplicity, we require callers to support both set eval modes.
1595 * There are cases where we must use one or must use the other, and
1596 * it's not really worthwhile to postpone the check till we know. But
1597 * note we do not require caller to provide an expectedDesc.
1598 */
1603 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1604 errmsg(
"set-valued function called in context that cannot accept a set")));
1607 /* tuplestore, if used, must have query lifespan */
1609 }
1610 else
1611 {
1612 randomAccess = false;
1613 lazyEvalOK = true;
1614 /* we won't need a tuplestore */
1615 tscontext = NULL;
1616 }
1617
1618 /*
1619 * Initialize fcache if starting a fresh execution.
1620 */
1622
1623 /* Mark fcache as active */
1625
1626 /* Remember info that we might need later to construct tuplestore */
1629
1630 /*
1631 * Now we can set up error traceback support for ereport()
1632 */
1634 sqlerrcontext.
arg = fcache;
1637
1638 /*
1639 * Find first unfinished execution_state. If none, advance to the next
1640 * query in function.
1641 */
1642 do
1643 {
1647 if (es)
1648 break;
1650
1651 /*
1652 * Execute each command in the function one after another until we either
1653 * run out of commands or get a result row from a lazily-evaluated SELECT.
1654 *
1655 * Notes about snapshot management:
1656 *
1657 * In a read-only function, we just use the surrounding query's snapshot.
1658 *
1659 * In a non-read-only function, we rely on the fact that we'll never
1660 * suspend execution between queries of the function: the only reason to
1661 * suspend execution before completion is if we are returning a row from a
1662 * lazily-evaluated SELECT. So, when first entering this loop, we'll
1663 * either start a new query (and push a fresh snapshot) or re-establish
1664 * the active snapshot from the existing query descriptor. If we need to
1665 * start a new query in a subsequent execution of the loop, either we need
1666 * a fresh snapshot (and pushed_snapshot is false) or the existing
1667 * snapshot is on the active stack and we can just bump its command ID.
1668 */
1669 pushed_snapshot = false;
1670 while (es)
1671 {
1672 bool completed;
1673
1675 {
1676 /*
1677 * If not read-only, be sure to advance the command counter for
1678 * each command, so that all work to date in this transaction is
1679 * visible. Take a new snapshot if we don't have one yet,
1680 * otherwise just bump the command ID in the existing snapshot.
1681 */
1683 {
1685 if (!pushed_snapshot)
1686 {
1688 pushed_snapshot = true;
1689 }
1690 else
1692 }
1693
1695 }
1697 {
1698 /* Re-establish active snapshot when re-entering function */
1700 pushed_snapshot = true;
1701 }
1702
1704
1705 /*
1706 * If we ran the command to completion, we can shut it down now. Any
1707 * row(s) we need to return are safely stashed in the result slot or
1708 * tuplestore, and we want to be sure that, for example, AFTER
1709 * triggers get fired before we return anything. Also, if the
1710 * function doesn't return set, we can shut it down anyway because it
1711 * must be a SELECT and we don't care about fetching any more result
1712 * rows.
1713 */
1716
1717 /*
1718 * Break from loop if we didn't shut down (implying we got a
1719 * lazily-evaluated row). Otherwise we'll press on till the whole
1720 * function is done, relying on the tuplestore to keep hold of the
1721 * data to eventually be returned. This is necessary since an
1722 * INSERT/UPDATE/DELETE RETURNING that sets the result might be
1723 * followed by additional rule-inserted commands, and we want to
1724 * finish doing all those commands before we return anything.
1725 */
1727 break;
1728
1729 /*
1730 * Advance to next execution_state, and perhaps next query.
1731 */
1733 while (!es)
1734 {
1735 /*
1736 * Flush the current snapshot so that we will take a new one for
1737 * the new query list. This ensures that new snaps are taken at
1738 * original-query boundaries, matching the behavior of interactive
1739 * execution.
1740 */
1741 if (pushed_snapshot)
1742 {
1744 pushed_snapshot = false;
1745 }
1746
1748 break; /* end of function */
1749
1751 }
1752 }
1753
1754 /*
1755 * The result slot or tuplestore now contains whatever row(s) we are
1756 * supposed to return.
1757 */
1759 {
1761
1763 {
1764 /*
1765 * If we stopped short of being done, we must have a lazy-eval
1766 * row.
1767 */
1769 /* The junkfilter's result slot contains the query result tuple */
1773 /* Extract the result as a datum, and copy out from the slot */
1775
1776 /*
1777 * Let caller know we're not finished.
1778 */
1780
1781 /*
1782 * Ensure we will get shut down cleanly if the exprcontext is not
1783 * run to completion.
1784 */
1786 {
1791 }
1792 }
1794 {
1795 /*
1796 * We are done with a lazy evaluation. Let caller know we're
1797 * finished.
1798 */
1800
1801 fcinfo->isnull = true;
1803
1804 /* Deregister shutdown callback, if we made one */
1806 {
1811 }
1812 }
1813 else
1814 {
1815 /*
1816 * We are done with a non-lazy evaluation. Return whatever is in
1817 * the tuplestore. (It is now caller's responsibility to free the
1818 * tuplestore when done.)
1819 *
1820 * Note an edge case: we could get here without having made a
1821 * tuplestore if the function is declared to return SETOF VOID.
1822 * ExecMakeTableFunctionResult will cope with null setResult.
1823 */
1828 /* must copy desc because execSRF.c will free it */
1831
1832 fcinfo->isnull = true;
1834
1835 /* Deregister shutdown callback, if we made one */
1837 {
1842 }
1843 }
1844 }
1845 else
1846 {
1847 /*
1848 * Non-set function. If we got a row, return it; else return NULL.
1849 */
1851 {
1852 /* The junkfilter's result slot contains the query result tuple */
1856 else
1857 {
1858 fcinfo->isnull = true;
1860 }
1861 }
1862 else
1863 {
1864 /* Should only get here for VOID functions and procedures */
1866 fcinfo->isnull = true;
1868 }
1869 }
1870
1871 /* Pop snapshot if we have pushed one */
1872 if (pushed_snapshot)
1874
1875 /*
1876 * If we've gone through every command in the function, we are done. Reset
1877 * state to start over again on next call.
1878 */
1879 if (es == NULL)
1881
1882 /* Mark fcache as inactive */
1884
1886
1887 return result;
1888}
ErrorContextCallback * error_context_stack
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
void UnregisterExprContextCallback(ExprContext *econtext, ExprContextCallbackFunction function, Datum arg)
void RegisterExprContextCallback(ExprContext *econtext, ExprContextCallbackFunction function, Datum arg)
@ SFRM_Materialize_Preferred
@ SFRM_Materialize_Random
static Datum postquel_get_single_result(TupleTableSlot *slot, FunctionCallInfo fcinfo, SQLFunctionCachePtr fcache)
static bool postquel_getnext(execution_state *es, SQLFunctionCachePtr fcache)
static void postquel_start(execution_state *es, SQLFunctionCachePtr fcache)
static bool init_execution_state(SQLFunctionCachePtr fcache)
static void postquel_end(execution_state *es, SQLFunctionCachePtr fcache)
static void sql_exec_error_callback(void *arg)
static void ShutdownSQLFunction(Datum arg)
static SQLFunctionCache * init_sql_fcache(FunctionCallInfo fcinfo, bool lazyEvalOK)
Assert(PointerIsAligned(start, uint64))
if(TABLE==NULL||TABLE_index==NULL)
#define IsA(nodeptr, _type_)
static Datum PointerGetDatum(const void *X)
Snapshot GetTransactionSnapshot(void)
void PushActiveSnapshot(Snapshot snapshot)
void UpdateActiveSnapshotCommandId(void)
void PopActiveSnapshot(void)
struct ErrorContextCallback * previous
void(* callback)(void *arg)
MemoryContext ecxt_per_query_memory
TupleDesc jf_cleanTupType
TupleTableSlot * jf_resultSlot
SetFunctionReturnMode returnMode
Tuplestorestate * setResult
SQLFunctionHashEntry * func
struct execution_state * next
TupleDesc CreateTupleDescCopy(TupleDesc tupdesc)
void CommandCounterIncrement(void)