TSM 处理器函数返回一个通过 palloc 分配的 TsmRoutine 结构体指针,包含如下支持函数。大部分函数为必需实现,少数可选函数的指针可置为 NULL。
void
SampleScanGetSampleSize (PlannerInfo *root,
RelOptInfo *baserel,
List *paramexprs,
BlockNumber *pages,
double *tuples);
该函数在查询规划期间被调用。它必须预估采样扫描过程中将读取的物理关系页面总数以及将被选中的数据行总数(例如通过估算采样率,并将其乘以 baserel->pages 与 baserel->tuples 计算得出)。pages 与 tuples 参数为传出指针。
void
InitSampleScan (SampleScanState *node,
int eflags);
为 SampleScan 计划节点的执行执行初始化。在执行器启动阶段调用。可以在此时通过 palloc 分配采样方法所需的私有内部状态并存放于 node->tsm_state 中。当 (eflags & EXEC_FLAG_EXPLAIN_ONLY) 为真时,扫描不会真实执行,仅需完成供 EXPLAIN 展示所需的最小初始化。该函数可省略(设为 NULL)。
void
BeginSampleScan (SampleScanState *node,
Datum *params,
int nparams,
uint32 seed);
开始执行一次采样扫描。在首次尝试抓取元组前调用,若扫描需要重置重扫也会再次调用。params 数组传入了在 SQL 中指定的采样参数值,已确保非空。seed 为本次采样所使用的随机数种子。
该函数可以根据需要调整 node->use_bulkread(是否开启批量环形缓冲)与 node->use_pagemode(是否按数据页执行批量可见性检查)。
BlockNumber NextSampleBlock (SampleScanState *node, BlockNumber nblocks);
返回下一个待扫描数据块的物理块号;若所有数据块已扫描完毕则返回 InvalidBlockNumber。若省略该函数(设为 NULL),内核会对整张表执行顺序扫描。
OffsetNumber
NextSampleTuple (SampleScanState *node,
BlockNumber blockno,
OffsetNumber maxoffset);
返回指定数据页上下一个被采样命中的元组项偏移号;若该页采样结束则返回 InvalidOffsetNumber。
void EndSampleScan (SampleScanState *node);
结束采样扫描并清理释放占用的外部可见系统资源。在常规情况下(若无外部文件描述符或专用资源)该函数可省略(设为 NULL)。