本文展示如何使用另一种形式编码,实现函数返回结果集。
以下代码来自 pgrowlocks
插件。
1、元组结构的获取
上一个例子中,结果集结构是我们自己定义的,还有一种动态获取的方法:
TupleDesc tupdesc;if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE) elog(ERROR, "return type must be a row type");
也能够利用返回结果检查函数定义的正确性。
根据注释,get_call_result_type
函数的代价较高,如果用前边的方式,最好只在 SRF_IS_FIRSTCALL
时调用。
2、准备元组的存储结构
ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;randomAccess = (rsinfo->allowedModes & SFRM_Materialize_Random) != 0;tupstore = tuplestore_begin_heap(randomAccess, false, work_mem);rsinfo->returnMode = SFRM_Materialize;rsinfo->setResult = tupstore;rsinfo->setDesc = tupdesc;
随后我们将要创建的元组都会放到这个 tupstore 中。
代码就不多做解释,需要的时候照搬即可。
3、元组数据的构建
虽然元组结构可以动态获取,仍然需要知道结果集字段的数量和类型,因为数据不是凭空产生,还需要我们编写自己的数据生成逻辑,只是让代码变得简单,尤其是有很多返回字段的时候。
元组的构建方法是一样的:
tuple = BuildTupleFromCStrings(attinmeta, values);
4、元组存放至返回结果
tuplestore_puttuple(tupstore, tuple);
元组全部生成完毕后:
return (Datum) 0;
5、与前一种方法的区别
(1)、返回方法不一样
(2)、不需要使用 SRF_IS_FIRSTCALL、SRF_PERCALL_SETUP、SRF_RETURN_NEXT、SRF_RETURN_DONE
(3)、函数不需要多次进入,一次得到整个结果集
欢迎关注