对get_baserel_parampathinfo函数的学习

简介:
复制代码
/*
 * 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 = 0; wordnum < nwords; wordnum++)
    {
        bitmapword    w = a->words[wordnum];

        if (w != 0)
            return false;
    }
    return true;
}
复制代码
目录
相关文章
|
2月前
|
XML 数据格式
Parameter ‘**‘ not found. Available parameters are [0, 1, param1, param2]解决办法
Parameter ‘**‘ not found. Available parameters are [0, 1, param1, param2]解决办法
80 0
|
5月前
|
Java 数据库连接 mybatis
mybatis参数报错Parameter ‘docId‘ not found. Available parameters are [arg1, arg0, param1, param2]
mybatis参数报错Parameter ‘docId‘ not found. Available parameters are [arg1, arg0, param1, param2]
@RequestParam()和@PathVariable()的区别
@RequestParam()和@PathVariable()的区别
|
11月前
|
前端开发 Java Spring
方法参数相关属性params、@PathVariable和@RequestParam用法与区别
方法参数相关属性params、@PathVariable和@RequestParam用法与区别
90 0
|
Java API Spring
@RequestParam和@PathVariable的区别
@RequestParam注解获取URL中携带的请求参数的值既URL中“?”后携带的参数,传递参数的格式是:key=value;@PathVariable注解用于获取URL中路径的参数值,参数名由RequestMapping注解请求路径时指定,常用于restful风格的api中,传递参数格式:直接在url后添加需要传递的值即可
183 0
|
前端开发 Java API
@RequestParam怎么使用
@RequestParam怎么使用
Parameter ‘bookID‘ not found. Available parameters are [param1, bookId]
Parameter ‘bookID‘ not found. Available parameters are [param1, bookId]
136 0
|
SQL Java 数据库连接
Parameter ‘XXX‘ not found.Available parameters are [arg2, arg1, arg0, param3, param1, param2]
当SQl语句的占位符和映射接口方法的参数名不一致时,需要将某个参数强行注入到某个占位符变量上时,可以使用@Param这个注解来标注映射的关系(@Param(“占位符的参数名”) 数据类型 自己定义的参数名)
339 0
Parameter ‘XXX‘ not found.Available parameters are [arg2, arg1, arg0, param3, param1, param2]
|
API Windows
WPARAM与LPARAM的区别
WPARAM与LPARAM的区别