MCPcopy Create free account
hub / github.com/apache/cloudberry / check_sql_fn_retval

Function check_sql_fn_retval

src/backend/executor/functions.c:1748–2117  ·  view source on GitHub ↗

* check_sql_fn_retval() * Check return value of a list of lists of sql parse trees. * * The return value of a sql function is the value returned by the last * canSetTag query in the function. We do some ad-hoc type checking and * coercion here to ensure that the function returns what it's supposed to. * Note that we may actually modify the last query to make it match! * * This function r

Source from the content-addressed store, hash-verified

1746 * function is defined to return VOID then *resultTargetList is set to NIL.
1747 */
1748bool
1749check_sql_fn_retval(List *queryTreeLists,
1750 Oid rettype, TupleDesc rettupdesc,
1751 bool insertDroppedCols,
1752 List **resultTargetList)
1753{
1754 bool is_tuple_result = false;
1755 Query *parse;
1756 ListCell *parse_cell;
1757 List *tlist;
1758 int tlistlen;
1759 bool tlist_is_modifiable;
1760 char fn_typtype;
1761 List *upper_tlist = NIL;
1762 bool upper_tlist_nontrivial = false;
1763 ListCell *lc;
1764
1765 if (resultTargetList)
1766 *resultTargetList = NIL; /* initialize in case of VOID result */
1767
1768 /*
1769 * If it's declared to return VOID, we don't care what's in the function.
1770 * (This takes care of the procedure case, as well.)
1771 */
1772 if (rettype == VOIDOID)
1773 return false;
1774
1775 /*
1776 * Find the last canSetTag query in the function body (which is presented
1777 * to us as a list of sublists of Query nodes). This isn't necessarily
1778 * the last parsetree, because rule rewriting can insert queries after
1779 * what the user wrote. Note that it might not even be in the last
1780 * sublist, for example if the last query rewrites to DO INSTEAD NOTHING.
1781 * (It might not be unreasonable to throw an error in such a case, but
1782 * this is the historical behavior and it doesn't seem worth changing.)
1783 */
1784 parse = NULL;
1785 parse_cell = NULL;
1786 foreach(lc, queryTreeLists)
1787 {
1788 List *sublist = lfirst_node(List, lc);
1789 ListCell *lc2;
1790
1791 foreach(lc2, sublist)
1792 {
1793 Query *q = lfirst_node(Query, lc2);
1794
1795 if (q->canSetTag)
1796 {
1797 parse = q;
1798 parse_cell = lc2;
1799 }
1800 }
1801 }
1802
1803 /*
1804 * If it's a plain SELECT, it returns whatever the targetlist says.
1805 * Otherwise, if it's INSERT/UPDATE/DELETE with RETURNING, it returns

Callers 4

init_sql_fcacheFunction · 0.85
inline_functionFunction · 0.85
fmgr_sql_validatorFunction · 0.85

Calls 15

format_type_beFunction · 0.85
get_typtypeFunction · 0.85
coerce_fn_result_columnFunction · 0.85
exprTypeFunction · 0.85
makeConstFunction · 0.85
lappendFunction · 0.85
makeTargetEntryFunction · 0.85
list_lengthFunction · 0.85
makeStringFunction · 0.85
makeAliasFunction · 0.85
makeFromExprFunction · 0.85

Tested by

no test coverage detected