返回顶部
首页 > 资讯 > 数据库 >PostgreSQL 源码解读(205)- 查询#118(数据结构RangeTblEntry)
  • 331
分享到

PostgreSQL 源码解读(205)- 查询#118(数据结构RangeTblEntry)

2024-04-02 19:04:59 331人浏览 八月长安
摘要

本节简单介绍了postgresq

本节简单介绍了postgresql在执行逻辑优化中对应Relation的数据结构:RangeTblEntry.

一、数据结构

RangeTblEntry
RTE可能是普通表/FROM中的子查询/JOIN语句的结果等(只有显式的JOIN语法会产生RTE,由多个FROM项生成的隐式连接则不会生成.这是因为 我们只需要RTE来处理sql特性,比如外部连接和连接输出列别名)




typedef enum RTEKind
{
  //常规的关系引用
  RTE_RELATION,       
  //FROM中的子查询
  RTE_SUBQUERY,       
  //JOIN
  RTE_JOIN,         
  //FROM中的函数
  RTE_FUNCTION,       
  //TableFunc(..,列链表)
  RTE_TABLEFUNC,        
  //VALUES (<exprlist>), (<exprlist>), ...
  RTE_VALUES,         
  //CTE
  RTE_CTE,          
  //tuplestore,比如AFTER触发器
  RTE_NAMEDTUPLESTORE,    
  //表示空的FROM语句.通过规划器添加,在解析和重写阶段不会出现
  RTE_RESULT          
} RTEKind;
typedef struct RangeTblEntry
{
  nodeTag   type;
  //详见上述说明
  RTEKind   rtekind;    
  
  
  Oid     relid;      
  char    relkind;    
  int     rellockmode;  
  struct TableSampleClause *tablesample;  
  
  //子查询
  Query    *subquery;   
  //来自于安全栏视图?
  bool    security_barrier; 
  
  JoinType  jointype;   
  List     *joinaliasvars;  
  
  List     *functions;    
  bool    funcordinality; 
  
  TableFunc  *tablefunc;
  
  List     *values_lists; 
  
  //WITH链表条目名称
  char     *ctename;    
  //查询层次编号
  Index   ctelevelsup;  
  //是否递归?
  bool    self_reference; 
  
  List     *coltypes;   
  List     *coltypmods;   
  List     *colcollations;  
  
  char     *enrname;    
  double    enrtuples;    
  
  //用户自定义别名
  Alias    *alias;      
  //已扩展的引用名
  Alias    *eref;     
  //子查询/函数/VALUES是LATERAL
  bool    lateral;    
  //是否继承?
  bool    inh;      
  //在FROM中出现?
  bool    inFromCl;   
  //访问权限位掩码
  AclMode   requiredPerms;  
  //如有效,则使用此角色检查访问权限
  Oid     checkAsUser;  
  //需要SELECT的权限
  Bitmapset  *selectedCols; 
  Bitmapset  *insertedCols; 
  Bitmapset  *updatedCols;  
  //将要被update的列
  Bitmapset  *extraUpdatedCols; 
  //需应用的安全栏
  List     *securityQuals;  
} RangeTblEntry;

二、源码解读

N/A

三、跟踪分析

测试SQL语句:



-- 用于测试的查询语句
testdb=# select * from (
testdb(# select t_dwxx.dwmc,t_grxx.grbh,t_grxx.xm,t_jfxx.ny,t_jfxx.je
testdb(# from t_dwxx inner join t_grxx on t_dwxx.dwbh = t_grxx.dwbh
testdb(# inner join t_jfxx on t_grxx.grbh = t_jfxx.grbh
testdb(# where t_dwxx.dwbh IN ('1001')
testdb(# uNIOn all
testdb(# select t_dwxx.dwmc,t_grxx.grbh,t_grxx.xm,t_jfxx.ny,t_jfxx.je
testdb(# from t_dwxx inner join t_grxx on t_dwxx.dwbh = t_grxx.dwbh
testdb(# inner join t_jfxx on t_grxx.grbh = t_jfxx.grbh
testdb(# where t_dwxx.dwbh IN ('1002') 
testdb(# ) as ret
testdb-# order by ret.grbh
testdb-# limit 4;

样例数据如下:



...
(gdb) set $rtable=$query->rtable
(gdb) p *$rtable
$8 = {type = T_List, length = 3, head = 0x170be48, tail = 0x170f6b0}
(gdb) p *(Node *)($rtable->head->data.ptr_value)
$9 = {type = T_RangeTblEntry}
(gdb) p *(RangeTblEntry *)($rtable->head->data.ptr_value)
$10 = {type = T_RangeTblEntry, rtekind = RTE_SUBQUERY, relid = 0, relkind = 0 '\000', tablesample = 0x0, 
  subquery = 0x1667500, security_barrier = false, jointype = JOIN_INNER, joinaliasvars = 0x0, 
  functions = 0x0, funcordinality = false, tablefunc = 0x0, values_lists = 0x0, ctename = 0x0, 
  ctelevelsup = 0, self_reference = false, coltypes = 0x0, coltypmods = 0x0, colcollations = 0x0, 
  enrname = 0x0, enrtuples = 0, alias = 0x1666d40, eref = 0x170bc18, lateral = false, inh = true, 
  inFromCl = true, requiredPerms = 2, checkAsUser = 0, selectedCols = 0x0, insertedCols = 0x0, 
  updatedCols = 0x0, securityQuals = 0x0}
(gdb) set $rte=(RangeTblEntry *)($rtable->head->data.ptr_value)
(gdb) p *$rte->subquery
$12 = {type = T_Query, commandType = CMD_SELECT, querySource = QSRC_ORIGINAL, queryId = 0, canSetTag = true, 
  utilityStmt = 0x0, resultRelation = 0, hasAggs = false, hasWindowFuncs = false, hasTargetSRFs = false, 
  hasSubLinks = false, hasDistinctOn = false, hasRecursive = false, hasModifyinGCTE = false, 
  hasForUpdate = false, hasRowSecurity = false, cteList = 0x0, rtable = 0x16fe4e8, jointree = 0x170bbe8, 
  targetList = 0x170b358, override = OVERRIDING_NOT_SET, onConflict = 0x0, returningList = 0x0, 
  groupClause = 0x0, groupingSets = 0x0, havingQual = 0x0, windowClause = 0x0, distinctClause = 0x0, 
  sortClause = 0x0, limitOffset = 0x0, limitCount = 0x0, rowMarks = 0x0, setOperations = 0x1667610, 
  constraintDeps = 0x0, withCheckOptions = 0x0, stmt_location = 0, stmt_len = 0}
(gdb) p *$rte->alias
$13 = {type = T_Alias, aliasname = 0x1666d28 "ret", colnames = 0x0}
(gdb) p *$rte->eref
$14 = {type = T_Alias, aliasname = 0x170bc48 "ret", colnames = 0x170bcb8}
(gdb) p *$rte->eref->colnames
$15 = {type = T_List, length = 5, head = 0x170bc98, tail = 0x170be28}
(gdb) p *(Node *)$rte->eref->colnames->head->data.ptr_value
$16 = {type = T_String}
(gdb) p *(Value *)$rte->eref->colnames->head->data.ptr_value
$17 = {type = T_String, val = {ival = 24165472, str = 0x170bc60 "dwmc"}}
---->subquery
(gdb) p *(RangeTblEntry *)$rte->subquery->rtable->head->data.ptr_value
$26 = {type = T_RangeTblEntry, rtekind = RTE_SUBQUERY, relid = 0, relkind = 0 '\000', tablesample = 0x0, 
  subquery = 0x16faf98, security_barrier = false, jointype = JOIN_INNER, joinaliasvars = 0x0, 
  functions = 0x0, funcordinality = false, tablefunc = 0x0, values_lists = 0x0, ctename = 0x0, 
  ctelevelsup = 0, self_reference = false, coltypes = 0x0, coltypmods = 0x0, colcollations = 0x0, 
  enrname = 0x0, enrtuples = 0, alias = 0x16fe240, eref = 0x16fe290, lateral = false, inh = false, 
  inFromCl = false, requiredPerms = 0, checkAsUser = 0, selectedCols = 0x0, insertedCols = 0x0, 
  updatedCols = 0x0, securityQuals = 0x0}
(gdb) set $rte_sq_rte=((RangeTblEntry *)$rte->subquery->rtable->head->data.ptr_value)
(gdb) p *(RangeTblEntry *)$rte_sq_rte->subquery->rtable->head->data.ptr_value
$30 = {type = T_RangeTblEntry, rtekind = RTE_RELATION, relid = 26754, relkind = 114 'r', tablesample = 0x0, 
  subquery = 0x0, security_barrier = false, jointype = JOIN_INNER, joinaliasvars = 0x0, functions = 0x0, 
  funcordinality = false, tablefunc = 0x0, values_lists = 0x0, ctename = 0x0, ctelevelsup = 0, 
  self_reference = false, coltypes = 0x0, coltypmods = 0x0, colcollations = 0x0, enrname = 0x0, 
  enrtuples = 0, alias = 0x0, eref = 0x16677c0, lateral = false, inh = true, inFromCl = true, 
  requiredPerms = 2, checkAsUser = 0, selectedCols = 0x16fbda8, insertedCols = 0x0, updatedCols = 0x0, 
  securityQuals = 0x0}
(gdb) set $rte_sq_rte_sq_rte=(RangeTblEntry *)$rte_sq_rte->subquery->rtable->head->data.ptr_value
(gdb) p *$rte_sq_rte_sq_rte
$42 = {type = T_RangeTblEntry, rtekind = RTE_RELATION, relid = 26754, relkind = 114 'r', tablesample = 0x0, 
  subquery = 0x0, security_barrier = false, jointype = JOIN_INNER, joinaliasvars = 0x0, functions = 0x0, 
  funcordinality = false, tablefunc = 0x0, values_lists = 0x0, ctename = 0x0, ctelevelsup = 0, 
  self_reference = false, coltypes = 0x0, coltypmods = 0x0, colcollations = 0x0, enrname = 0x0, 
  enrtuples = 0, alias = 0x0, eref = 0x16677c0, lateral = false, inh = true, inFromCl = true, 
  requiredPerms = 2, checkAsUser = 0, selectedCols = 0x16fbda8, insertedCols = 0x0, updatedCols = 0x0, 
  securityQuals = 0x0}
(gdb) set $rte_sq_rte_sq_rtable=$rte_sq_rte->subquery->rtable
(gdb) p *(RangeTblEntry *)($rte_sq_rte_sq_rtable->head->data.ptr_value)
$60 = {type = T_RangeTblEntry, rtekind = RTE_RELATION, relid = 26754, relkind = 114 'r', tablesample = 0x0, 
  subquery = 0x0, security_barrier = false, jointype = JOIN_INNER, joinaliasvars = 0x0, functions = 0x0, 
  funcordinality = false, tablefunc = 0x0, values_lists = 0x0, ctename = 0x0, ctelevelsup = 0, 
  self_reference = false, coltypes = 0x0, coltypmods = 0x0, colcollations = 0x0, enrname = 0x0, 
  enrtuples = 0, alias = 0x0, eref = 0x16677c0, lateral = false, inh = true, inFromCl = true, 
  requiredPerms = 2, checkAsUser = 0, selectedCols = 0x16fbda8, insertedCols = 0x0, updatedCols = 0x0, 
  securityQuals = 0x0}
(gdb) p *(RangeTblEntry *)($rte_sq_rte_sq_rtable->head->next->data.ptr_value)
$61 = {type = T_RangeTblEntry, rtekind = RTE_RELATION, relid = 26757, relkind = 114 'r', tablesample = 0x0, 
  subquery = 0x0, security_barrier = false, jointype = JOIN_INNER, joinaliasvars = 0x0, functions = 0x0, 
  funcordinality = false, tablefunc = 0x0, values_lists = 0x0, ctename = 0x0, ctelevelsup = 0, 
  self_reference = false, coltypes = 0x0, coltypmods = 0x0, colcollations = 0x0, enrname = 0x0, 
  enrtuples = 0, alias = 0x0, eref = 0x16fb4f0, lateral = false, inh = true, inFromCl = true, 
  requiredPerms = 2, checkAsUser = 0, selectedCols = 0x16fbe10, insertedCols = 0x0, updatedCols = 0x0, 
  securityQuals = 0x0}
(gdb) p *(RangeTblEntry *)($rte_sq_rte_sq_rtable->head->next->next->data.ptr_value)
$62 = {type = T_RangeTblEntry, rtekind = RTE_JOIN, relid = 0, relkind = 0 '\000', tablesample = 0x0, 
  subquery = 0x0, security_barrier = false, jointype = JOIN_INNER, joinaliasvars = 0x16fbff8, 
  functions = 0x0, funcordinality = false, tablefunc = 0x0, values_lists = 0x0, ctename = 0x0, 
  ctelevelsup = 0, self_reference = false, coltypes = 0x0, coltypmods = 0x0, colcollations = 0x0, 
  enrname = 0x0, enrtuples = 0, alias = 0x0, eref = 0x16fc318, lateral = false, inh = false, inFromCl = true, 
  requiredPerms = 0, checkAsUser = 0, selectedCols = 0x0, insertedCols = 0x0, updatedCols = 0x0, 
  securityQuals = 0x0}
(gdb) p *(RangeTblEntry *)($rte_sq_rte_sq_rtable->head->next->next->next->data.ptr_value)
$63 = {type = T_RangeTblEntry, rtekind = RTE_RELATION, relid = 26760, relkind = 114 'r', tablesample = 0x0, 
  subquery = 0x0, security_barrier = false, jointype = JOIN_INNER, joinaliasvars = 0x0, functions = 0x0, 
  funcordinality = false, tablefunc = 0x0, values_lists = 0x0, ctename = 0x0, ctelevelsup = 0, 
  self_reference = false, coltypes = 0x0, coltypmods = 0x0, colcollations = 0x0, enrname = 0x0, 
  enrtuples = 0, alias = 0x0, eref = 0x16fc678, lateral = false, inh = true, inFromCl = true, 
  requiredPerms = 2, checkAsUser = 0, selectedCols = 0x16fd1d0, insertedCols = 0x0, updatedCols = 0x0, 
  securityQuals = 0x0}
(gdb) p *(RangeTblEntry *)($rte_sq_rte_sq_rtable->tail->data.ptr_value)
$64 = {type = T_RangeTblEntry, rtekind = RTE_JOIN, relid = 0, relkind = 0 '\000', tablesample = 0x0, 
  subquery = 0x0, security_barrier = false, jointype = JOIN_INNER, joinaliasvars = 0x16fd3b8, 
  functions = 0x0, funcordinality = false, tablefunc = 0x0, values_lists = 0x0, ctename = 0x0, 
  ctelevelsup = 0, self_reference = false, coltypes = 0x0, coltypmods = 0x0, colcollations = 0x0, 
  enrname = 0x0, enrtuples = 0, alias = 0x0, eref = 0x16fd798, lateral = false, inh = false, inFromCl = true, 
  requiredPerms = 0, checkAsUser = 0, selectedCols = 0x0, insertedCols = 0x0, updatedCols = 0x0, 
  securityQuals = 0x0}

四、参考资料

N/A

您可能感兴趣的文档:

--结束END--

本文标题: PostgreSQL 源码解读(205)- 查询#118(数据结构RangeTblEntry)

本文链接: https://lsjlt.com/news/49773.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作