PostgreSQL表的扫描

原创
2020/07/16 21:50
阅读数 507

本文演示如何在代码中访问表的数据,使用REL_13_STABLE分支。很多细节没有完全搞清楚,只是个demo,仅供参考。

 

1、假设存在如下表:

CREATE TABLE t1(
c1 int PRIMARY KEY,
c2 text,
);

 

2、打开表

可以利用:(1)、heap_open[rv]();(2)、relation_open[rv]();

获取Oid可以利用get_relname_relid,或者利用类型regclass向SQL函数传递对象名。

 

3、选择索引

当一个表记录很多,利用索引加过滤条件无疑会快得多,上例中可以利用主键 t1_pkey,假设它的Oid是16399。

 

4、函数systable_beginscan参数

(1) Relation heapRelation 前边提到的已打开的relation

(2) Oid indexId 主键Oid

(3) bool indexOK 因为我们有主键,传入true

(4) Snapshot snapshot 直接传入NULL,让PG自己选择,或者根据需要指定

(5)(6) 扫描条件

 

5、初始化扫描条件

ScanKeyData scanKey[1];
ScanKeyInit(&scanKey[0], 1, BTEqualStrategyNumber, F_INT4EQ, Int32GetDatum(100));

只有一个条件,在第一个字段扫描值等于 100 的结果,更多请自行在代码中找例子。

 

6、开始扫描

scanDescriptor = systable_beginscan(rel, 16399,
        true, GetTransactionSnapshot(), 1, scanKey);

注意第5个参数,必须是上边设置的条件数量。

 

7、获取并检查结果

tuple = systable_getnext(scanDescriptor);
if (!HeapTupleIsValid(bucketTuple))
  ereport(ERROR, ...

dat = fastgetattr(tuple, 2, rel->rd_att, &isnull);

取出第二个字段的值

 

8、关闭扫描

systable_endscan(scanDescriptor);
heap_close(rel, NoLock);

最后一句关闭但不释放锁,事务结束时再处理。当然也可以提前释放,一般不这么做。

 

按理,最后应该放一个完整例子,但是并没有。如果感兴趣,在dblink、sepgsql中有现成的代码。而pgrowlocks中有 heap_beginscan 的使用,并且这里也揭示行锁如何实现,建议学习。

 

水平不够,代码来凑

欢迎关注公众号

展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部