Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

What is the main implementation logic of the master planning function make_one_rel in query_planner in PostgreSQL?

2025-01-18 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Database >

Share

Shulou(Shulou.com)05/31 Report--

This article mainly introduces "what is the main implementation logic of make_one_rel in query_planner in PostgreSQL". In daily operation, I believe that many people have doubts about what is the main implementation logic of make_one_rel in query_planner in PostgreSQL. The editor consulted all kinds of materials and sorted out simple and useful operation methods. I hope it will be helpful to answer the question of "what is the main implementation logic of the main planning function make_one_rel in query_planner in PostgreSQL"! Next, please follow the editor to study!

Query_planner code snippet:

/ /... / * * Ready to do the primary planning. * / final_rel = make_one_rel (root, joinlist); / / execute the main planning process / * Check that we got at least one usable path * / if (! final_rel | |! final_rel- > cheapest_total_path | | final_rel- > cheapest_total_path- > param_info! = NULL) elog (ERROR, "failed to construct the join relation"); / / check the result returned by return final_rel;//. I. data structure

RelOptInfo

Typedef struct RelOptInfo {NodeTag type;// node identifies RelOptKind reloptkind;//RelOpt type / * all relations included in this RelOptInfo * / Relids relids; / * Relids (rtindex) collection set of base relids (rangetable indexes) * / * size estimates generated by planner * / double rows / * does the estimated number of tuples estimated number of result tuples * / / * per-relation planner control flags * / bool consider_startup; / * consider the startup cost? Yes, do you need to keep the path keep cheap-startup-cost paths with low startup cost? * / bool consider_param_startup; / * do you want to consider parameterization? Does the path ditto, for parameterized paths? * / bool consider_parallel; / * consider parallel processing path consider parallel paths? * / * default result targetlist for Paths scanning this relation * / struct PathTarget * reltarget; / * when scanning the Relation, the default result list of Vars/Exprs, cost, width * / * materialization information * / List * pathlist; / * access path list Path structures * / List * ppilist / * ParamPathInfos used in pathlist using parameterized paths in the path list * / List * partial_pathlist; / * partial Paths * / struct Path * cheapest_startup_path;// the lowest startup path struct Path * cheapest_total_path;// the lowest overall path struct Path * cheapest_unique_path;// the path List * cheapest_parameterized_paths with the lowest cost to get a unique value / / the lowest cost parameterization? Path linked list / * parameterization information needed for both base rels and join rels * / * (see also lateral_vars and lateral_referencers) * / Relids direct_lateral_relids; / * uses explicit syntax and depends on Relids rels directly laterally referenced * / Relids lateral_relids The data structure Index relid; / * Relation ID * / Oid reltablespace; / * tablespace containing tablespace * / RTEKind rtekind; / * base table used in / * minimum parameterization of rel * / * information about a base rel (not set for join rels!) * / reloptkind=RELOPT_BASEREL? Subquery? Or functions and so on? RELATION, SUBQUERY, FUNCTION, etc * / AttrNumber min_attr; / * lowest attribute number smallest attrno of rel (often all_baserels = NULL; for (rti = 1; rti)

< root->

Simple_rel_array_size; rti++) / / traversing RelOptInfo {RelOptInfo * brel = root- > simple_rel_ Array [RTI]; / * there may be empty slots corresponding to non-baserel RTEs * / if (brel = = NULL) continue; Assert (brel- > relid = = rti) / * sanity check on array * / * ignore RTEs that are "other rels" * / if (brel- > reloptkind! = RELOPT_BASEREL) continue; root- > all_baserels = bms_add_member (root- > all_baserels, brel- > relid) / / add to all_baserels traversal} / * Mark baserels as to whether we care about fast-start plans * / / set the consider_param_startup variable of RelOptInfo, whether to consider fast-start plans set_base_rel_consider_startup (root); / * Compute size estimates and consider_parallel flags for each baserel, * then generate access paths. * / set_base_rel_sizes (root); / / estimate the Size of Relation and set the consider_parallel flag set_base_rel_pathlists (root); / / generate the scanning (access) path of Relation / * * Generate access paths for the entire join tree. * generate the connection path through dynamic programming or genetic algorithm * / rel = make_rel_from_joinlist (root, joinlist); / * The result should join all and only the query's base rels. * / Assert (bms_equal (rel- > relids, root- > all_baserels)); / / return the top RelOptInfo return rel } / /-- / * * set_base_rel_consider_startup * Set the consider_ [param_] startup flags for each base-relation entry. * * For the moment, we only deal with consider_param_startup here; because the * logic for consider_startup is pretty trivial and is the same for every base * relation, we just let build_simple_rel () initialize that flag correctly to * start with. If that logic ever gets more complicated it would probably * be better to move it here. * / static void set_base_rel_consider_startup (PlannerInfo * root) {/ * Since parameterized paths can only be used on the inside of a nestloop * join plan, there is usually little value in considering fast-start * plans for them. However, for relations that are on the RHS of a SEMI * or ANTI join, a fast-start plan can be useful because we're only going * to care about fetching one tuple anyway. * * To minimize growth of planning time, we currently restrict this to * cases where the RHS is a single base relation, not a join; there is no * provision for consider_param_startup to get set at all on joinrels. * Also we don't worry about appendrels. Costsize.c's costing rules for * nestloop semi/antijoins don't consider such cases either. * / ListCell * lc; foreach (lc, root- > join_info_list) {SpecialJoinInfo * sjinfo = (SpecialJoinInfo *) lfirst (lc); int varno If ((sjinfo- > jointype = = JOIN_SEMI | | sjinfo- > jointype = = JOIN_ANTI) & & bms_get_singleton_member (sjinfo- > syn_righthand, & varno)) {RelOptInfo * rel = find_base_rel (root, varno); rel- > consider_param_startup = true } / /-- / * * set_base_rel_sizes * Set the size estimates (rows and widths) for each base-relation entry. * Also determine whether to consider parallel paths for base relations. * * We do this in a separate pass over the base rels so that rowcount * estimates are available for parameterized path generation, and also so * that each rel's consider_parallel flag is set correctly before we begin to * generate paths. * / static void set_base_rel_sizes (PlannerInfo * root) {Index rti; for (rti = 1; rti)

< root->

Simple_rel_array_size; rti++) / / traversing the RelOptInfo array {RelOptInfo * rel = root- > simple_rel_ array [RTI]; RangeTblEntry * rte; / * there may be empty slots corresponding to non-baserel RTEs * / if (rel = = NULL) continue; Assert (rel- > relid = = rti) / * sanity check on array * / * ignore RTEs that are "other rels" * / if (rel- > reloptkind! = RELOPT_BASEREL) continue; rte = root- > simple_rte_ array [RTI]; / * If parallelism is allowable for this query in general, see whether * it's allowable for this rel in particular. We have to do this * before set_rel_size (), because (a) if this rel is an inheritance * parent, set_append_rel_size () will use and perhaps change the rel's * consider_parallel flag, and (b) for some RTE types, set_rel_size () * goes ahead and makes paths immediately. * / if (root- > glob- > parallelModeOK) set_rel_consider_parallel (root, rel, rte); set_rel_size (root, rel, rti, rte) }} / * * set_rel_size * Set size estimates for a base relation * / static void set_rel_size (PlannerInfo * root, RelOptInfo * rel, Index rti, RangeTblEntry * rte) {if (rel- > reloptkind = = RELOPT_BASEREL & & relation_excluded_by_constraints (root, rel, rte)) {/ * We proved we don't need to scan the rel via constraint exclusion * so set up a single dummy path for it. Here we only check this for * regular baserels; if it's an otherrel, CE was already checked in * set_append_rel_size (). * In this case, we go ahead and set up the relation's path right away * instead of leaving it for set_rel_pathlist to do. This is because * we don't have a convention for marking a rel as dummy except by * assigning a dummy path to it. * / set_dummy_rel_pathlist (rel); / /} else if (rte- > inh) / / inherit table {/ * It's an "append relation", process accordingly * / set_append_rel_size (root, rel, rti, rte) } else {switch (rel- > rtekind) {case RTE_RELATION:// data Table if (rte- > relkind = = RELKIND_FOREIGN_TABLE) / / FDW {/ * Foreign table * / set_foreign_size (root, rel, rte) } else if (rte- > relkind = = RELKIND_PARTITIONED_TABLE) / / partition table {/ * * A partitioned table without any partitions is marked as * a dummy rel. * / set_dummy_rel_pathlist (rel);} else if (rte- > tablesample! = NULL) / / sampling table {/ * Sampled relation * / set_tablesample_rel_size (root, rel, rte) } else {/ * Plain relation * / set_plain_rel_size (root, rel, rte); / / regular datasheet} break Case RTE_SUBQUERY:// subquery / * * Subqueries don't support making a choice between * parameterized and unparameterized paths, so just go ahead * and build their paths immediately. * / set_subquery_pathlist (root, rel, rti, rte); / / generate sub-query access path break; case RTE_FUNCTION://FUNCTION set_function_size_estimates (root, rel); break; case RTE_TABLEFUNC://TABLEFUNC set_tablefunc_size_estimates (root, rel) Break; case RTE_VALUES://VALUES set_values_size_estimates (root, rel); break Case RTE_CTE://CTE / * * CTEs don't support making a choice between parameterized * and unparameterized paths, so just go ahead and build their * paths immediately. * / if (rte- > self_reference) set_worktable_pathlist (root, rel, rte); else set_cte_pathlist (root, rel, rte); break; case RTE_NAMEDTUPLESTORE://NAMEDTUPLESTORE, named tuple storage set_namedtuplestore_pathlist (root, rel, rte) Break; default: elog (ERROR, "unexpected rtekind:% d", (int) rel- > rtekind); break;}} / * * We insist that all non-dummy rels have a nonzero rowcount estimate. * / Assert (rel- > rows > 0 | | IS_DUMMY_REL (rel));} / /-- / * * set_base_rel_pathlists * Finds all paths available for scanning each base-relation entry. * Sequential scan and any available indices are considered. * Each useful path is attached to its relation's' pathlist' field. * * find all available access paths for each base rels (sequential scans and all available indexes are taken into account) * every available path is added to the pathlist linked list * * / static void set_base_rel_pathlists (PlannerInfo * root) {Index rti; for (rti = 1; rti)

< root->

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Database

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report