Postgres FDW 中由 PGresult 结构生成 HeapTuple 的过程

PGresult 结构:

struct pg_result
{
	int			ntups;
	int			numAttributes;
	PGresAttDesc *attDescs;
	PGresAttValue **tuples;
	int			tupArrSize;	
	int			numParameters;
	PGresParamDesc *paramDescs;
	ExecStatusType resultStatus;
	char		cmdStatus[CMDSTATUS_LEN];


	PGNoticeHooks noticeHooks;
	PGEvent    *events;
	int			nEvents;
	int			client_encoding;	/* encoding id */


	char	   *errMsg;			/* error message, or NULL if no error */
	PGMessageField *errFields;	/* message broken into fields */
	char	   *errQuery;		/* text of triggering query, if available */


	PGresult_data *curBlock;	/* most recently allocated block */
	int			curOffset;		/* start offset of free space in block */
	int			spaceLeft;		/* number of free bytes remaining in block */
};


PGresult.tuples:

返回的 tuple 的实际的值都存放在 tuples 中,tuples 是一个 PGresAttValue * 类型的二位数组,
tuples[row_number][column_number] 就代表返回的表(关系)中第 row_number 行第 column_number 列中数据的值;


PGresult.PGresAttDesc:

该结构是对每一列(属性)的描述,attDescs[column_number] 就是第 column_number 列的描述信息,
typedef struct pgresAttDesc
{
	char	   *name;			/* column name */
	Oid			tableid;		/* source table, if known */
	int			columnid;		/* source column, if known */
	int			format;			/* format code for value (text/binary) */
	Oid			typid;			/* type id */
	int			typlen;			/* type size */
	int			atttypmod;		/* type-specific modifier info */
} PGresAttDesc;
name 是列名,typid 是列的类型的oid,format 则是列的格式,0 代表文本格式,1 代表二进制模式;


FDW 下 Postgres 将 PGresult 转化为本地 heaptuple 存储的过程为:
参照 make_tuple_from_result_row() 函数,

从远端取回的 PGresult 一定会对应一个本地已经生成的表,可能是一张基本表或是一张由 join 形成的临时的表,通过下面的语句获取该表的 tupleDesc 元组描述信息:

        if (rel)
		tupdesc = RelationGetDescr(rel);
	else
	{
		PgFdwScanState *fdw_sstate;

		Assert(fsstate);
		fdw_sstate = (PgFdwScanState *) fsstate->fdw_state;
		tupdesc = fdw_sstate->tupdesc;
	}

 

由于 FDW 会对发到远端执行的语句有筛选,所以函数还传入了一个 retrieved_attrs,retrieved_attrs 是一个 List,每一项表示从远端取回的列(属性)的列 id,从 1 开始计数,

	foreach(lc, retrieved_attrs)
	{
		int	   i = lfirst_int(lc);
		char	   *valstr;

		/* fetch next column's textual value */
		if (PQgetisnull(res, row, j))
			valstr = NULL;
		else
			valstr = PQgetvalue(res, row, j);

		/* convert value to internal representation */
		errpos.cur_attno = i;
		if (i > 0)
		{
			/* ordinary column */
			Assert(i <= tupdesc->natts);
			nulls[i - 1] = (valstr == NULL);
			/* Apply the input function even to nulls, to support domains */
			values[i - 1] = InputFunctionCall(&attinmeta->attinfuncs[i - 1],
											  valstr,
											  attinmeta->attioparams[i - 1],
											  attinmeta->atttypmods[i - 1]);
		}
对于取回的每一列,如果不为空的话,就将其中的文本值指针保存到 valstr 中( “valstr = PQgetvalue(res, row, j);” ),

在 bool nulls[] 数组中存储每一列中是否为空,值为 true(0) 或 false(1),

在 datum values[] 中则存放由 C 字符串转化为 tuple datum 格式的数据值,转化的方法由 attinmeta 提供。

上述的 tupleDesc, retrieved_attrs 和 attinmeta 若有需要,都是可以通过调用一些函数自己构造的,文末将会提供构造方法。

最后调用 heap_form_tuple(tupdesc, values, nulls) 由 tupdesc,、values[]、nulls[] 构造一个 HeapTuple。 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值