/*
* get_baserel_parampathinfo
* Get the ParamPathInfo for a parameterized path for a base relation,
* constructing one if we don't have one already.
*
* This centralizes estimating the rowcounts for parameterized paths.
* We need to cache those to be sure we use the same rowcount for all paths
* of the same parameterization for a given rel. This is also a convenient
* place to determine which movable join clauses the parameterized path will
* be responsible for evaluating.
*/
ParamPathInfo *
get_baserel_parampathinfo(PlannerInfo *root, RelOptInfo *baserel,
Relids required_outer)
{
ParamPathInfo *ppi;
Relids joinrelids;
List *pclauses;
double rows;
ListCell *lc; /* Unparameterized paths have no ParamPathInfo */
if (bms_is_empty(required_outer))
return NULL; Assert(!bms_overlap(baserel->relids, required_outer)); /* If we already have a PPI for this parameterization, just return it */
foreach(lc, baserel->ppilist)
{
ppi = (ParamPathInfo *) lfirst(lc);
if (bms_equal(ppi->ppi_req_outer, required_outer))
return ppi;
} /*
* Identify all joinclauses that are movable to this base rel given this
* parameterization.
*/
joinrelids = bms_union(baserel->relids, required_outer);
pclauses = NIL;
foreach(lc, baserel->joininfo)
{
RestrictInfo *rinfo = (RestrictInfo *) lfirst(lc); if (join_clause_is_movable_into(rinfo,
baserel->relids,
joinrelids))
pclauses = lappend(pclauses, rinfo);
} /*
* Add in joinclauses generated by EquivalenceClasses, too. (These
* necessarily satisfy join_clause_is_movable_into.)
*/
pclauses = list_concat(pclauses,
generate_join_implied_equalities(root,
joinrelids,
required_outer,
baserel)); /* Estimate the number of rows returned by the parameterized scan */
rows = get_parameterized_baserel_size(root, baserel, pclauses); /* And now we can build the ParamPathInfo */
ppi = makeNode(ParamPathInfo);
ppi->ppi_req_outer = required_outer;
ppi->ppi_rows = rows;
ppi->ppi_clauses = pclauses;
baserel->ppilist = lappend(baserel->ppilist, ppi); return ppi;
}

上溯来看:

/*
* set_plain_rel_pathlist
* Build access paths for a plain relation (no subquery, no inheritance)
*/
static void
set_plain_rel_pathlist(PlannerInfo *root, RelOptInfo *rel, RangeTblEntry *rte)
{
/* Consider sequential scan */
add_path(rel, create_seqscan_path(root, rel, NULL)); /* Consider index scans */
create_index_paths(root, rel); /* Consider TID scans */
create_tidscan_paths(root, rel); /* Now find the cheapest of the paths for this rel */
set_cheapest(rel);
}

只要进入了 set_plain_rel_pathlist 函数,进行

add_path(rel, create_seqscan_path(root, rel, NULL))调用是,给予 create_seqscan_path 的第三个参数是NULL

再看 create_seqscan_path:

/*
* create_seqscan_path
* Creates a path corresponding to a sequential scan, returning the
* pathnode.
*/
Path *
create_seqscan_path(PlannerInfo *root, RelOptInfo *rel, Relids required_outer)
{
Path *pathnode = makeNode(Path); pathnode->pathtype = T_SeqScan;
pathnode->parent = rel;
pathnode->param_info = get_baserel_parampathinfo(root, rel,
required_outer); pathnode->pathkeys = NIL; /* seqscan has unordered result */ cost_seqscan(pathnode, root, rel, pathnode->param_info); return pathnode;
}

看这句话:pathnode->param_info = get_baserel_parampathinfo(root, rel, required_outer);

由于传递的required_outer是NULL,所以就是 get_baserel_parampathinfo(root, rel, NULL);

那么:

/*
* get_baserel_parampathinfo
* Get the ParamPathInfo for a parameterized path for a base relation,
* constructing one if we don't have one already.
*
* This centralizes estimating the rowcounts for parameterized paths.
* We need to cache those to be sure we use the same rowcount for all paths
* of the same parameterization for a given rel. This is also a convenient
* place to determine which movable join clauses the parameterized path will
* be responsible for evaluating.
*/
ParamPathInfo *
get_baserel_parampathinfo(PlannerInfo *root, RelOptInfo *baserel,
Relids required_outer)
{
ParamPathInfo *ppi;
Relids joinrelids;
List *pclauses;
double rows;
ListCell *lc; /* Unparameterized paths have no ParamPathInfo */
if (bms_is_empty(required_outer))
return NULL; Assert(!bms_overlap(baserel->relids, required_outer)); /* If we already have a PPI for this parameterization, just return it */
foreach(lc, baserel->ppilist)
{
ppi = (ParamPathInfo *) lfirst(lc);
if (bms_equal(ppi->ppi_req_outer, required_outer))
return ppi;
} /*
* Identify all joinclauses that are movable to this base rel given this
* parameterization.
*/
joinrelids = bms_union(baserel->relids, required_outer);
pclauses = NIL;
foreach(lc, baserel->joininfo)
{
RestrictInfo *rinfo = (RestrictInfo *) lfirst(lc); if (join_clause_is_movable_into(rinfo,
baserel->relids,
joinrelids))
pclauses = lappend(pclauses, rinfo);
} /*
* Add in joinclauses generated by EquivalenceClasses, too. (These
* necessarily satisfy join_clause_is_movable_into.)
*/
pclauses = list_concat(pclauses,
generate_join_implied_equalities(root,
joinrelids,
required_outer,
baserel)); /* Estimate the number of rows returned by the parameterized scan */
rows = get_parameterized_baserel_size(root, baserel, pclauses); /* And now we can build the ParamPathInfo */
ppi = makeNode(ParamPathInfo);
ppi->ppi_req_outer = required_outer;
ppi->ppi_rows = rows;
ppi->ppi_clauses = pclauses;
baserel->ppilist = lappend(baserel->ppilist, ppi); return ppi;
}

看这一小段:

    /* Unparameterized paths have no ParamPathInfo */
if (bms_is_empty(required_outer))
return NULL;

看看 bms_is_empty:

/*
* bms_is_empty - is a set empty?
*
* This is even faster than bms_membership().
*/
bool
bms_is_empty(const Bitmapset *a)
{
int nwords;
int wordnum; if (a == NULL)
return true
;

nwords = a->nwords;
for (wordnum = ; wordnum < nwords; wordnum++)
{
bitmapword w = a->words[wordnum]; if (w != )
return false;
}
return true;
}

对get_baserel_parampathinfo函数的学习的更多相关文章

  1. Hive自定义函数的学习笔记(1)

    前言: hive本身提供了丰富的函数集, 有普通函数(求平方sqrt), 聚合函数(求和sum), 以及表生成函数(explode, json_tuple)等等. 但不是所有的业务需求都能涉及和覆盖到 ...

  2. (转载)prepare函数的学习,我要学习php第二天

    (转载)http://www.boyuan78.com/htm/company/2012_1030_60.html prepare函数的学习,我要学习php第二天 $mysqli = new mysq ...

  3. QT QObject::connect函数的学习

      从Qobject(QObject.h)源码中可以看到QObject::connect的定义是这样的: static bool connect(const QObject *sender, cons ...

  4. Matlab中常见的神经网络训练函数和学习函数

    一.训练函数 1.traingd Name:Gradient descent backpropagation (梯度下降反向传播算法 ) Description:triangd is a networ ...

  5. python函数基础学习

    函数的定义与调用: def 函数名(参数1,参数2): ‘’’函数注释’’’ print(‘函数体’) return 返回值 定  义:def关键字开关,空格之后接函数名和圆括号,最后冒号结尾 def ...

  6. R语言函数化学习笔记6

    R语言函数化学习笔记 1.apply函数 可以让list或者vector的元素依次执行一遍调用的函数,输出的结果是list格式 2.sapply函数 原理和list一样,但是输出的结果是一个向量的形式 ...

  7. R语言函数化学习笔记3

    R语言函数化学习笔记3 R语言常用的一些命令函数 1.getwd()查看当前R的工作目录 2.setwd()修改当前工作目录 3.str()可以输出指定对象的结构(类型,位置等),同理还有class( ...

  8. JavaScript权威设计--JavaScript函数(简要学习笔记十一)

    1.函数调用的四种方式 第三种:构造函数调用 如果构造函数调用在圆括号内包含一组实参列表,先计算这些实参表达式,然后传入函数内.这和函数调用和方法调用是一致的.但如果构造函数没有形参,JavaScri ...

  9. JavaScript权威设计--JavaScript函数(简要学习笔记十)

    1.函数命名规范 函数命名通常以动词为前缀的词组.通常第一个字符小写.当包含多个单词时,一种约定是将单词以下划线分割,就像"like_Zqz()". 还有一种就是"lik ...

随机推荐

  1. JQUERY 选择器 总结,比较全

    jQuery 的选择器可谓之强大无比,这里简单地总结一下常用的元素查找方法 $("#myELement") 选择id值等于myElement的元素,id值不能重复在文档中只能有一个 ...

  2. python 控制vbox虚拟机

    (本机环境:win7:python 2.7.9: vbox 4.3.12) 目标: 完成官网(https://pypi.python.org/pypi/pyvbox)上的demo: > pyth ...

  3. 大四实习准备2_java异常处理_android控件练习

    2015-4-24 Java 异常处理 可以有多个catch;ArrayIndexOutOfBoundsException类是Exception类的子类RuntimeException类的一个间接子类 ...

  4. Spring data rest 如何显示主键

    How to expose the resourceId with Spring-Data-Rest? Spring-Data-Rest is a quite new project in the S ...

  5. spring+springMVC+JPA配置详解(使用缓存框架ehcache)

    SpringMVC是越来越火,自己也弄一个Spring+SpringMVC+JPA的简单框架. 1.搭建环境. 1)下载Spring3.1.2的发布包:Hibernate4.1.7的发布包(没有使用h ...

  6. [VC6]ONMESSAGE()宏编译时出现"sytax error ;"错误时

    自定义消息时编译出错,经排查,在定义消息的头文件里 #define WM_XXX (WM_USER+1000); 最后多加了一个分号引起. 吐血.

  7. java vm args

    这个问题主要还是由这个问题 java.lang.OutOfMemoryError: Java heap space 引起的.第一次出现这样的的问题以后,引发了其他的问题.在网上一查可能是JAVA的堆栈 ...

  8. java jvm学习笔记五(实践自己写的类装载器)

     欢迎装载请说明出处:http://blog.csdn.net/yfqnihao 课程源码:http://download.csdn.net/detail/yfqnihao/4866501 前面第三和 ...

  9. JMX学习一

    JMX        即 Java Management Extensions   Java管理扩展MBean   即 managed beans                         被管 ...

  10. How to cancel parallel loops in .NET C# z

    Cancellation token Parallel options CancellationTokenSource cancellationTokenSource = new Cancellati ...