这个时候生成的査询计划树仅包含一个TidScan节点,其扫描的对象是TidScan节点中保存的一个表达式链表,其中存储的表达式可以得到ctid的值,TidScan节点将根据ctid值取得对应的元组。TidScan节点只在Scan节点的基础上扩展了一个字段tidquals用于保存可以得到ctid的表达式链表。
TidScan 节点的初始化函数 ExecInitTidScan 会根据 tidquals 初始化 TidScanState 中的 tss_tidquals字段,然后调用ExecInitExpr初始化tidquals中的表达式,并根据节点中的scanrelid初始化扫描描述符 ss_currentScanDesc。
TidScan节点的执行函数(ExecTidScan)也同样调用函数ExecScan来完成执行工作,其中传递给ExecScan函数的指针是TidNext。函数TidNext首先需要通过计算TidScanState节点的tss_tidquals链表中的表达式来构造tss_TidList数组,该数组中存放的是一系列的ctid, tss_NumTidS用于记录数组的长度,tss_TidPtr用于记录当前处理的ctid在tss_TidList数组中的偏移量,初始值设为-1。然后从tss_TidList中获取下一个ctid值,接着调用存储模块提供的heap_fetch根据该ctid获取元组并返回。出于并发的需要,当TidScan节点用于“CURRENTOF".(游标名)”语句时,获取的ctid可能已经被其他事务修改,需要获取此ctid对应元组的最新版本(利用HOT链),然后再调用heap_fetch进行获取。