Compare commits
17 Commits
| Author | SHA1 | Date |
|---|---|---|
|
|
1c7126a2b5 | |
|
|
0cbb6eee5a | |
|
|
1221a2db97 | |
|
|
39bf3fd8b6 | |
|
|
a70a9141f4 | |
|
|
652dca18e2 | |
|
|
fa4f0dd52b | |
|
|
e63ca22f68 | |
|
|
9671f7748e | |
|
|
5563337f8a | |
|
|
eec179f902 | |
|
|
452dbf0b45 | |
|
|
4115c85171 | |
|
|
4b02a0c6d7 | |
|
|
ca071d6faf | |
|
|
6989e1c098 | |
|
|
2fdd03dfa8 |
|
|
@ -109,6 +109,21 @@ static void updateRelOptInfoMinSecurity(RelOptInfo* rel);
|
|||
static void find_index_path(RelOptInfo* rel);
|
||||
static void bitmap_path_walker(Path* path);
|
||||
|
||||
/*
|
||||
function name: check_func_walker
|
||||
description: This function recursively traverses an expression tree to determine if there are any FuncExpr nodes present.
|
||||
arguments: The first argument represents the current node in the expression tree.
|
||||
The second argument indicates the pointer to a boolean variable that indicates whether a function call node has been found.
|
||||
return value: Returns true if a FuncExpr node is found, otherwise returns false. The "found" variable is modified accordingly to indicate the presence of a FuncExpr node during the traversal.
|
||||
note: The main process is as follows:
|
||||
-> Recursively traverses the given expression tree, examining each node.
|
||||
-> If the current node is NULL, it returns `false`.
|
||||
-> If the node is of type `FuncExpr` (function call node), sets the `found` variable to `true` and returns `true`.
|
||||
-> Otherwise, invokes the general expression tree walker `expression_tree_walker` to traverse child nodes, passing along the `found` variable.
|
||||
-> Returns a boolean value indicating whether a function call node was found in the expression tree.
|
||||
date: 2023/8/12
|
||||
contact tel: 18720816902
|
||||
*/
|
||||
static bool check_func_walker(Node* node, bool* found)
|
||||
{
|
||||
if (node == NULL) {
|
||||
|
|
@ -421,6 +436,22 @@ static bool reduce_predpush_broadcast(PlannerInfo* root, Path *path)
|
|||
return reduce;
|
||||
}
|
||||
|
||||
/*
|
||||
function name: make_predpush_subpath
|
||||
description: This function is responsible for generating a subpath for predicate pushdown. It extracts restriction conditions from the given relation's restrictinfo and creates a new subpath incorporating these conditions.
|
||||
arguments: The first argument represents the pointer of a PlannerInfo structure containing query planner context.
|
||||
The second argument indicates the RelOptInfo structure containing information about the relation being optimized.
|
||||
The third argument indicates the Path to be processed.
|
||||
return value: Returns the newly generated subpath that incorporates the extracted restriction conditions and supports predicate pushdown optimization. This function plays a role in query optimization, enhancing the execution plan by considering relevant conditions during subpath creation.
|
||||
note: The main process is as follows:
|
||||
-> Initialize the "quals" list to hold restriction conditions.
|
||||
-> Iterate through the "subplanrestrictinfo" list within the given "rel", which contains restriction information.
|
||||
-> If the condition "SUBQUERY_PREDPUSH(root)" is met, collect upper-level parameter IDs using the "collect_param_clause" function from the condition expressions.
|
||||
-> Create a new subpath "subpath" using the "create_result_path" function, passing in "root", "rel", "quals", "path", and "upper_params" as arguments.
|
||||
-> Return the newly created subpath "subpath".
|
||||
date: 2023/8/13
|
||||
contact tel: 18720816902
|
||||
*/
|
||||
static Path *make_predpush_subpath(PlannerInfo* root, RelOptInfo* rel, Path *path)
|
||||
{
|
||||
List* quals = NULL;
|
||||
|
|
@ -859,6 +890,19 @@ static void set_rel_pathlist(PlannerInfo* root, RelOptInfo* rel, Index rti, Rang
|
|||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
function name: SetPlainReSizeWithPruningRatio
|
||||
description: This function adjusts the estimated size of a partitioned relation and its associated indexes based on a pruning ratio. It modifies the estimated number of pages in the relation and its indexes to reflect the effect of pruning.
|
||||
arguments: The first argument represents the pointer to the RelOptInfo structure representing the partitioned relation.
|
||||
The second argument indicates the ratio by which to adjust the estimated size due to pruning.
|
||||
return value: This function does not return a value; it directly modifies the estimated page counts for the partitioned relation and its indexes based on the provided pruning ratio. The adjustment accounts for the pruning effect on the size estimates, contributing to accurate query planning and optimization for partitioned tables.
|
||||
note: The main process is as follows:
|
||||
-> Validate that the given relation is a partitioned table (assertion).
|
||||
-> Update the estimated number of pages in the partitioned relation by multiplying it with the given pruningRatio and applying a clamp function (clamp_row_est).
|
||||
-> Iterate through the list of indexes associated with the partitioned relation.
|
||||
date: 2023/8/13
|
||||
contact tel: 18720816902
|
||||
*/
|
||||
static void SetPlainReSizeWithPruningRatio(RelOptInfo *rel, double pruningRatio)
|
||||
{
|
||||
ListCell *cell = NULL;
|
||||
|
|
@ -2190,6 +2234,27 @@ static bool has_multiple_baserels(PlannerInfo* root)
|
|||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
function name: can_push_qual_into_subquery
|
||||
description: This function determines whether a restriction condition can be pushed into a subquery. It evaluates various criteria including pseudoconstant, security barrier, safe pushdown conditions, and partial push conditions to make this determination.
|
||||
arguments:
|
||||
- `root`: PlannerInfo context for query planning.
|
||||
- `rinfo`: RestrictInfo representing the restriction condition.
|
||||
- `rte`: RangeTblEntry representing the table entry.
|
||||
- `rti`: Index of the range table entry.
|
||||
- `clause`: The restriction condition expression to be evaluated.
|
||||
- `unsafeColumns`: A boolean array indicating the presence of unsafe columns.
|
||||
return value: A boolean value indicating whether the given restriction condition can be pushed into a subquery. This function is utilized in query planning to make informed decisions about optimization strategies, ensuring that the pushdown of restriction conditions is performed while considering multiple crucial factors.
|
||||
note: The main process is as follows:
|
||||
-> Retrieve the subquery from the RangeTblEntry `rte`.
|
||||
-> Check the `pseudoconstant` property of the RestrictInfo. If true, return `false`, indicating the restriction condition cannot be pushed.
|
||||
-> If the `security_barrier` property of the RangeTblEntry is true and the restriction condition contains leaky functions (`contain_leaky_functions`), return `false`.
|
||||
-> Call the `qual_is_pushdown_safe` function to assess whether the restriction condition can be safely pushed into the subquery.
|
||||
-> Call the `qual_pushdown_in_partialpush` function to determine whether the restriction condition can be pushed under partial push conditions.
|
||||
-> Return `true` if all checks are satisfied, indicating that the restriction condition can be pushed into the subquery.
|
||||
date: 2023/8/13
|
||||
contact tel: 18720816902
|
||||
*/
|
||||
static bool can_push_qual_into_subquery(PlannerInfo* root,
|
||||
RestrictInfo* rinfo,
|
||||
RangeTblEntry* rte,
|
||||
|
|
@ -2229,6 +2294,22 @@ typedef struct trans_lateral_vars_t
|
|||
int levelsup;
|
||||
}trans_lateral_vars_t;
|
||||
|
||||
/*
|
||||
function name: trans_lateral_vars_mutator
|
||||
description: This function recursively traverses an expression tree and performs transformations on Var nodes based on the given lateral_vars information. It handles the conversion of inner Vars to subquery form and outer Vars to Params.
|
||||
arguments:
|
||||
- `node`: The current node being processed in the expression tree.
|
||||
- `lateral_vars`: A structure containing information about the transformation process.
|
||||
return value: A modified expression tree with transformed Var nodes.
|
||||
note: The main process is as follows:
|
||||
-> If the node is NULL, return NULL.
|
||||
-> If the node is a Var:
|
||||
- If it's an inner Var (varno matches lateral_vars->rti), convert it to subquery form using target_list and return the transformed expression.
|
||||
- If it's an outer Var, convert it to Param by adjusting varlevelsup and return the new Var.
|
||||
-> Recursively traverse the expression tree using expression_tree_mutator, applying the trans_lateral_vars_mutator function.
|
||||
date: 2023/8/13
|
||||
contact tel: 18720816902
|
||||
*/
|
||||
static Node* trans_lateral_vars_mutator(Node *node, trans_lateral_vars_t *lateral_vars)
|
||||
{
|
||||
if (node == NULL)
|
||||
|
|
@ -2261,6 +2342,21 @@ static Node* trans_lateral_vars_mutator(Node *node, trans_lateral_vars_t *latera
|
|||
(Node* (*)(Node*, void*))trans_lateral_vars_mutator, lateral_vars);
|
||||
}
|
||||
|
||||
/*
|
||||
function name: trans_lateral_vars
|
||||
description: This function performs the transformation of lateral references within a given subquery. It recursively traverses the expression tree using the trans_lateral_vars_mutator function to convert internal Var nodes into subquery forms and external Var nodes into Param nodes.
|
||||
arguments:
|
||||
- `subquery`: The subquery in which lateral references are to be transformed.
|
||||
- `rti`: The index of the subquery in the RangeTblEntry array.
|
||||
- `qual`: The restriction condition expression to be transformed.
|
||||
- `levelsup`: The number of levels up in which the transformation occurs within the subquery.
|
||||
return value: The transformed restriction condition expression.
|
||||
note: The main process is as follows:
|
||||
-> Create a trans_lateral_vars_t structure containing information such as subquery, target_list, rti, and levelsup.
|
||||
-> Recursively traverse the restriction condition expression using the query_or_expression_tree_mutator function, applying the trans_lateral_vars_mutator function for the conversion.
|
||||
date: 2023/8/13
|
||||
contact tel: 18720816902
|
||||
*/
|
||||
static Node* trans_lateral_vars(Query *subquery, Index rti, Node *qual, int levelsup)
|
||||
{
|
||||
trans_lateral_vars_t lateral_vars;
|
||||
|
|
@ -2282,6 +2378,21 @@ typedef struct collect_lateral_vars_t
|
|||
RelOptInfo *rel;
|
||||
}collect_lateral_vars_t;
|
||||
|
||||
/*
|
||||
function name: collect_lateral_vars_walker
|
||||
description: This function is used for walking through an expression tree and collecting lateral variables within it. It identifies outer Var nodes that reference tables outside the current relation and adds them to the lateral_relids and lateral_vars fields of the provided RelOptInfo structure. It also updates the lateral_info structures for the query planner's root.
|
||||
arguments:
|
||||
- `node`: The current node in the expression tree being traversed.
|
||||
- `context`: The context containing information about the relation and query planner.
|
||||
return value: A boolean value indicating whether the traversal should continue (always false).
|
||||
note: The main process is as follows:
|
||||
-> Extract RelOptInfo and PlannerInfo from the lateral_context.
|
||||
-> If the current node is a Var node and references a table outside the current relation, add its varno to the lateral_relids and add the Var to the lateral_vars list.
|
||||
-> Update lateral_info for the root by adding lateral reference information.
|
||||
-> If the current node is a RestrictInfo, extract its clause and continue traversal.
|
||||
date: 2023/8/13
|
||||
contact tel: 18720816902
|
||||
*/
|
||||
static bool collect_lateral_vars_walker(Node *node, void *context)
|
||||
{
|
||||
collect_lateral_vars_t *lateral_context = (collect_lateral_vars_t *)context;
|
||||
|
|
@ -2315,6 +2426,20 @@ static bool collect_lateral_vars_walker(Node *node, void *context)
|
|||
return expression_tree_walker(node, (bool (*)())collect_lateral_vars_walker, context);
|
||||
}
|
||||
|
||||
/*
|
||||
function name: collect_lateral_vars
|
||||
description: This function collects lateral variables within a given restriction condition expression. It utilizes the collect_lateral_vars_walker function to traverse the expression tree and identify outer Var nodes that reference tables outside the current relation. The lateral_relids and lateral_vars fields of the provided RelOptInfo structure are updated accordingly.
|
||||
arguments:
|
||||
- `root`: PlannerInfo context for query planning.
|
||||
- `restrict`: The restriction condition expression to be traversed.
|
||||
- `rel`: The RelOptInfo structure representing the current relation.
|
||||
return value: A boolean value indicating whether the traversal was successful (always true).
|
||||
note: The main process is as follows:
|
||||
-> Initialize the lateral_context containing PlannerInfo and RelOptInfo.
|
||||
-> Invoke the expression_tree_walker function with the restrict expression and the collect_lateral_vars_walker function as the walker.
|
||||
date: 2023/8/13
|
||||
contact tel: 18720816902
|
||||
*/
|
||||
static bool
|
||||
collect_lateral_vars(PlannerInfo *root, Node *restrict, RelOptInfo *rel)
|
||||
{
|
||||
|
|
@ -2350,6 +2475,20 @@ static Relids collect_child_relids(PlannerInfo* root, Index rti)
|
|||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
function name: predpush_candidates_append
|
||||
description: This function identifies potential append children for predicate pushdown based on the provided parent relation IDs. It iterates through each parent relation ID in the provided Relids set and collects the child relation IDs for each parent using the collect_child_relids function. The resulting child relation IDs are unioned to form the final set of potential append children for predicate pushdown.
|
||||
arguments:
|
||||
- `root`: PlannerInfo context for query planning.
|
||||
- `parents`: A set of parent relation IDs representing the potential append parents.
|
||||
return value: A Relids set containing the union of child relation IDs for all provided parent relation IDs.
|
||||
note: The main process is as follows:
|
||||
-> Initialize parent_id to -1.
|
||||
-> Iterate through each parent relation ID in the parents set.
|
||||
-> For each parent relation ID, collect the child relation IDs using collect_child_relids and union them with the results set.
|
||||
date: 2023/8/13
|
||||
contact tel: 18720816902
|
||||
*/
|
||||
static Relids predpush_candidates_append(PlannerInfo *root, Relids parents)
|
||||
{
|
||||
int parent_id = -1;
|
||||
|
|
@ -2361,6 +2500,24 @@ static Relids predpush_candidates_append(PlannerInfo *root, Relids parents)
|
|||
return results;
|
||||
}
|
||||
|
||||
/*
|
||||
function name: predpush_candidates
|
||||
description: This function identifies potential relations for predicate pushdown based on the given PlannerInfo and destination relation ID. It examines the hintState and predpush_hint in the parse tree's HintState to determine potential candidates for predicate pushdown. The function iterates through each PredpushHint in the hint list and, based on the dest_id and parent_rti, constructs a set of potential candidates for predicate pushdown. It then combines these candidates using union operations and returns the resulting Relids set.
|
||||
arguments:
|
||||
- `root`: PlannerInfo context for query planning.
|
||||
- `dest_id`: Destination relation ID for which predicate pushdown candidates are to be determined.
|
||||
return value: A Relids set containing the potential candidates for predicate pushdown based on the given PlannerInfo and destination relation ID.
|
||||
note: The main process is as follows:
|
||||
-> Retrieve the hintState from the parse tree's HintState.
|
||||
-> If hintState or predpush_hint is NULL, return NULL indicating no candidates.
|
||||
-> Initialize an empty result set.
|
||||
-> Iterate through each PredpushHint in the predpush_hint list.
|
||||
-> For each PredpushHint, check if dest_id matches or if dest_id is the parent_rti, and construct candidates using predpush_candidates_append.
|
||||
-> Union the constructed candidates with the result set and return it if a match is found.
|
||||
-> If no match is found, union the result set with candidates based on result itself using predpush_candidates_append.
|
||||
date: 2023/8/13
|
||||
contact tel: 18720816902
|
||||
*/
|
||||
static Relids predpush_candidates(PlannerInfo *root, int dest_id)
|
||||
{
|
||||
HintState *hstate = root->parse->hintState;
|
||||
|
|
@ -2408,6 +2565,29 @@ static Relids predpush_candidates(PlannerInfo *root, int dest_id)
|
|||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
function name: extract_predpush_equivclause
|
||||
description: This function extracts the predicate pushdown candidate equivalence clauses for a given relation based on the provided candidates, RelOptInfo, and relation index (rti). It iterates through the simple_rel_array and checks each relation to identify candidates for equivalence clauses that can be pushed down to the given relation. The function takes into account various conditions, including relation kinds, indexes, and parent-child relationships for append relations.
|
||||
arguments:
|
||||
- `root`: PlannerInfo context for query planning.
|
||||
- `candidates`: Relids set indicating potential candidates for predicate pushdown.
|
||||
- `rel`: RelOptInfo representing the given relation.
|
||||
- `rti`: Index of the relation.
|
||||
return value: A List containing the extracted candidate equivalence clauses for predicate pushdown to the given relation.
|
||||
note: The main process is as follows:
|
||||
-> Initialize an empty List to hold candidate_restricts.
|
||||
-> Iterate through the simple_rel_array using the `i` loop variable.
|
||||
-> For each relation in simple_rel_array, check its kind and index conditions.
|
||||
-> If candidates are specified and the relation is not a candidate, continue to the next relation.
|
||||
-> If ENABLE_PRED_PUSH_FORCE is not set and `i` is greater than `rti`, continue to the next relation.
|
||||
-> If the current relation is the same as the given `rel`, continue to the next relation.
|
||||
-> Generate candidate equivalence clauses based on join_relids and append relationships (if applicable).
|
||||
-> If generated restrict_list is empty, continue to the next relation.
|
||||
-> Concatenate the generated restrict_list with the candidate_restricts List.
|
||||
-> After processing all relations, return the candidate_restricts List containing extracted candidate equivalence clauses.
|
||||
date: 2023/8/13
|
||||
contact tel: 18720816902
|
||||
*/
|
||||
static List *extract_predpush_equivclause(PlannerInfo* root, Relids candidates,
|
||||
RelOptInfo* rel, Index rti)
|
||||
{
|
||||
|
|
@ -2597,6 +2777,29 @@ static bool predpush_subquery(PlannerInfo* root, RelOptInfo* rel, Index rti,
|
|||
return predpush;
|
||||
}
|
||||
|
||||
/*
|
||||
function name: judge_predpush_subquery
|
||||
description: This function determines whether predicate pushdown into a subquery is feasible based on various conditions. It evaluates criteria such as safe pushdown, relation kinds, recursion, enabling options, root conditions, and null handling. The function is utilized to make informed decisions about whether to proceed with predicate pushdown optimization.
|
||||
arguments:
|
||||
- `root`: PlannerInfo context for query planning.
|
||||
- `safe_pushdown`: A boolean indicating whether safe pushdown is possible.
|
||||
- `rel`: RelOptInfo representing the relation.
|
||||
- `rti`: Index of the relation in the range table.
|
||||
- `rte`: RangeTblEntry corresponding to the relation.
|
||||
return value: A boolean value indicating whether predicate pushdown into the subquery is a viable optimization strategy.
|
||||
note: The main process is as follows:
|
||||
-> Check whether safe pushdown is not possible, and return `false` if true.
|
||||
-> Check whether the relation kind is RELOPT_BASEREL or RELOPT_OTHER_MEMBER_REL, and return `false` if not.
|
||||
-> Check whether the query involves recursion or is under a recursive CTE, and return `false` if true.
|
||||
-> Check whether the ENABLE_PRED_PUSH_ALL option is not set, and return `false` if true.
|
||||
-> Check whether the given `rte` matches the corresponding simple_rte_array entry, and return `false` if not.
|
||||
-> Check whether the join_null_info is not empty, and return `false` if true.
|
||||
-> Check whether stream support is enabled using check_stream_support(), and return `false` if not.
|
||||
-> If the query is a sublink and rel has subplanrestrictinfo, return `false`.
|
||||
-> If all checks pass, return `true` indicating that predicate pushdown into the subquery is feasible.
|
||||
date: 2023/8/13
|
||||
contact tel: 18720816902
|
||||
*/
|
||||
static bool judge_predpush_subquery(PlannerInfo* root, bool safe_pushdown, RelOptInfo* rel,
|
||||
Index rti, RangeTblEntry *rte)
|
||||
{
|
||||
|
|
@ -3577,6 +3780,33 @@ static bool qual_is_pushdown_to_EXCEPT(PlannerInfo* root, Query* subquery,
|
|||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
function name: qual_is_pushdown_safe
|
||||
description: This function checks whether it is safe to push a given qualification clause into a subquery based on various conditions. It evaluates criteria including subselects, volatile functions, window functions, PHV (PlaceHolderVars), aggregates, subquery types, and attribute numbers. The function is used in query planning to determine the feasibility of pushdown optimization.
|
||||
arguments:
|
||||
- `root`: PlannerInfo context for query planning.
|
||||
- `subquery`: Subquery where the pushdown is being considered.
|
||||
- `rti`: Index of the range table entry corresponding to the subquery.
|
||||
- `qual`: The qualification clause to be evaluated for pushdown.
|
||||
- `unsafeColumns`: An array of booleans indicating unsafe columns.
|
||||
- `predpush`: A boolean indicating whether predpush is being considered.
|
||||
return value: A boolean value indicating whether the given qualification clause can be safely pushed into the subquery. If any of the safety checks fail, the function returns `false`, indicating that pushdown is not safe.
|
||||
note: The main process is as follows:
|
||||
-> Check if the qualification clause contains subselects using contain_subplans() and return `false` if true.
|
||||
-> If multiple nodes are not enabled, check if the qualification clause contains volatile functions, and return `false` if true.
|
||||
-> Check if the qualification clause contains window functions using contain_window_function() and AssertEreport() to indicate that this should not happen.
|
||||
-> Check whether the qualification clause is safe for pushdown to EXCEPT clauses using qual_is_pushdown_to_EXCEPT() and return `false` if false.
|
||||
-> Pull all Vars used in the clause, and iterate over them.
|
||||
-> If the Var is not an instance of Var, set `safe` to `false` and break.
|
||||
-> If predpush is enabled and the Var corresponds to a CTE, set `safe` to `false` and break.
|
||||
-> If the Var's varno does not match rti, continue to the next iteration.
|
||||
-> Check whether the Var's varattno is valid and not zero, and set `safe` to `false` and break if not.
|
||||
-> Check whether the Var's varattno corresponds to an unsafe column using the `unsafeColumns` array, and set `safe` to `false` and break if true.
|
||||
-> Free the memory allocated for the vars list using list_free_ext().
|
||||
-> Return `safe`, indicating whether the pushdown is safe.
|
||||
date: 2023/8/14
|
||||
contact tel: 18720816902
|
||||
*/
|
||||
static bool qual_is_pushdown_safe(PlannerInfo* root, Query* subquery, Index rti,
|
||||
Node* qual, const bool* unsafeColumns, bool predpush)
|
||||
{
|
||||
|
|
@ -4012,6 +4242,19 @@ bool CheckPathUseGlobalPartIndex(Path* path)
|
|||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* function name: create_partiterator_path
|
||||
* description: This function creates a PartIteratorPath for partitioned tables, which allows parallel scan and access to partitions based on the specified path type.
|
||||
* arguments:
|
||||
* - `root`: PlannerInfo context for query planning.
|
||||
* - `rel`: RelOptInfo representing the relation.
|
||||
* - `path`: The original path to be transformed into a PartIteratorPath.
|
||||
* - `relation`: The underlying partitioned relation.
|
||||
* return value: A pointer to the created PartIteratorPath representing the scan of partitions based on the specified path type. If the path type is not recognized or suitable, an error is raised.
|
||||
* note: The function first switches based on the original path type, and if it matches certain supported path types (such as sequential scan, index scan, etc.), it constructs a PartIteratorPath. The PartIteratorPath allows for parallel scanning of partitions, inherits pathkeys from the original path, and sets other relevant information.
|
||||
* date: 2023/8/14
|
||||
* contact tel: 18720816902
|
||||
*/
|
||||
static Path* create_partiterator_path(PlannerInfo* root, RelOptInfo* rel, Path* path, Relation relation)
|
||||
{
|
||||
Path* result = NULL;
|
||||
|
|
@ -4199,6 +4442,17 @@ bool is_single_baseresult_plan(Plan* plan)
|
|||
*****************************************************************************/
|
||||
#ifdef OPTIMIZER_DEBUG
|
||||
|
||||
/*
|
||||
* function name: print_relids
|
||||
* description: This function prints the IDs and names of relations represented by the given Relids set. It uses the RangeTblEntry information from the provided list to retrieve relation names.
|
||||
* arguments:
|
||||
* - `relids`: The set of relation IDs to be printed.
|
||||
* - `rtable`: List of RangeTblEntry representing the available relations.
|
||||
* return value: None.
|
||||
* note: The function iterates over the given Relids set, retrieves the corresponding relation name from the RangeTblEntry list, and prints the relation ID and name.
|
||||
* date: 2023/8/14
|
||||
* contact tel: 18720816902
|
||||
*/
|
||||
static void print_relids(Relids relids, List* rtable)
|
||||
{
|
||||
Relids tmprelids;
|
||||
|
|
@ -4218,6 +4472,17 @@ static void print_relids(Relids relids, List* rtable)
|
|||
bms_free_ext(tmprelids);
|
||||
}
|
||||
|
||||
/*
|
||||
* function name: print_restrictclauses
|
||||
* description: This function prints the clauses within the given list of RestrictInfo structures, using the provided PlannerInfo context to access the range table.
|
||||
* arguments:
|
||||
* - `root`: PlannerInfo context for query planning.
|
||||
* - `clauses`: List of RestrictInfo structures containing the clauses to be printed.
|
||||
* return value: None.
|
||||
* note: The function iterates over the list of RestrictInfo structures, extracts the clause expression from each structure, and prints it using the provided range table information. The clauses are printed comma-separated.
|
||||
* date: 2023/8/14
|
||||
* contact tel: 18720816902
|
||||
*/
|
||||
static void print_restrictclauses(PlannerInfo* root, List* clauses)
|
||||
{
|
||||
ListCell* l = NULL;
|
||||
|
|
@ -4231,12 +4496,37 @@ static void print_restrictclauses(PlannerInfo* root, List* clauses)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* function name: print_tab
|
||||
* description: This inline function prints a specified number of tab characters, used for indentation purposes.
|
||||
* arguments:
|
||||
* - `indent`: The number of tab characters to print for indentation.
|
||||
* return value: None.
|
||||
* note: The function prints the specified number of tab characters ('\t') to provide indentation in the output.
|
||||
* date: 2023/8/14
|
||||
* contact tel: 18720816902
|
||||
*/
|
||||
inline void print_tab(int indent)
|
||||
{
|
||||
for (int i = 0; i < indent; i++)
|
||||
printf("\t");
|
||||
}
|
||||
|
||||
/*
|
||||
* function name: print_path
|
||||
* description: This function prints the details of a given query planning path, including its type, relevant information,
|
||||
* and any subpaths in the plan.
|
||||
* arguments:
|
||||
* - `root`: PlannerInfo context for query planning.
|
||||
* - `path`: The query planning path to be printed.
|
||||
* - `indent`: The number of tab characters for indentation in the output.
|
||||
* return value: None.
|
||||
* note: The function outputs the path type and corresponding information, such as parent relations, rows, and cost.
|
||||
* It also prints any associated path keys and clauses. In the case of join paths, it recursively prints the details
|
||||
* of the outer and inner join paths. For material and unique paths, it prints details about their subpaths.
|
||||
* date: 2023/8/14
|
||||
* contact tel: 18720816902
|
||||
*/
|
||||
static void print_path(PlannerInfo* root, Path* path, int indent)
|
||||
{
|
||||
const char* ptype = NULL;
|
||||
|
|
@ -4314,6 +4604,21 @@ static void print_path(PlannerInfo* root, Path* path, int indent)
|
|||
print_path(root, subpath, indent + 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* function name: debug_print_rel
|
||||
* description: This function prints debugging information about a given RelOptInfo structure, providing details about
|
||||
* its rows, multiple, width, baserestrictinfo, joininfo, and paths.
|
||||
* arguments:
|
||||
* - `root`: PlannerInfo context for query planning.
|
||||
* - `rel`: The RelOptInfo structure to be debug printed.
|
||||
* return value: None.
|
||||
* note: The function prints the RelOptInfo's rows, multiple, and width values, followed by its baserestrictinfo and
|
||||
* joininfo clauses if they exist. It then iterates through the path list and prints details of each path,
|
||||
* including path type, parent relations, rows, cost, and pathkeys. The cheapest startup path and cheapest total path
|
||||
* are also printed.
|
||||
* date: 2023/8/14
|
||||
* contact tel: 18720816902
|
||||
*/
|
||||
void debug_print_rel(PlannerInfo* root, RelOptInfo* rel)
|
||||
{
|
||||
ListCell* l = NULL;
|
||||
|
|
|
|||
|
|
@ -816,6 +816,21 @@ static List* switch_arg_items(Node* funExpr, Const* cnst, Oid* eqlOprOid, Oid* i
|
|||
return argList;
|
||||
}
|
||||
|
||||
/*
|
||||
* function name: do_restrictinfo_conversion
|
||||
* description: This function performs restrictinfo conversion by switching argument items for equality operator.
|
||||
* arguments:
|
||||
* - `args`: List containing two arguments.
|
||||
* - `eqlOprOid`: Pointer to the OID of the equality operator.
|
||||
* - `inputcollid`: Pointer to the OID of the input collation.
|
||||
* - `isequal`: Boolean indicating whether it's an equality operation.
|
||||
* return value: List of argument items after performing the conversion.
|
||||
* note: The function checks whether the two argument items in the list are constants. If one is a constant and the other
|
||||
* is not, it performs a switch of argument items using the `switch_arg_items` function. The resulting list of
|
||||
* argument items is returned.
|
||||
* date: 2023/8/15
|
||||
* contact tel: 18720816902
|
||||
*/
|
||||
static List* do_restrictinfo_conversion(List* args, Oid* eqlOprOid, Oid* inputcollid, bool isequal)
|
||||
{
|
||||
AssertEreport(list_length(args) == 2, MOD_OPT, "");
|
||||
|
|
@ -899,6 +914,21 @@ static void get_vardata_for_filter_or_semijoin(
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* function name: do_restrictinfo_conversion
|
||||
* description: This function performs restrictinfo conversion by switching argument items for equality operator.
|
||||
* arguments:
|
||||
* - `args`: List containing two arguments.
|
||||
* - `eqlOprOid`: Pointer to the OID of the equality operator.
|
||||
* - `inputcollid`: Pointer to the OID of the input collation.
|
||||
* - `isequal`: Boolean indicating whether it's an equality operation.
|
||||
* return value: List of argument items after performing the conversion.
|
||||
* note: The function checks whether the two argument items in the list are constants. If one is a constant and the other
|
||||
* is not, it performs a switch of argument items using the `switch_arg_items` function. The resulting list of
|
||||
* argument items is returned.
|
||||
* date: 2023/8/15
|
||||
* contact tel: 18720816902
|
||||
*/
|
||||
void getVardataFromScalarArray(Node* node, get_vardata_for_filter_or_semijoin_context* context)
|
||||
{
|
||||
Node* left = NULL;
|
||||
|
|
|
|||
|
|
@ -151,6 +151,22 @@ void init_plan_cost(Plan* plan)
|
|||
plan->pred_max_memory = -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* function name: get_info_from_rel
|
||||
* description: This function retrieves various information from a given relation and updates the provided pointers
|
||||
* with the respective values.
|
||||
* arguments:
|
||||
* - `relation`: The relation for which information needs to be retrieved.
|
||||
* - `maxBatchRow`: Pointer to an integer to store the maximum batch rows.
|
||||
* - `isPartTable`: Pointer to a boolean to indicate whether the relation is partitioned.
|
||||
* - `isValuePartTable`: Pointer to a boolean to indicate whether the relation is value-partitioned.
|
||||
* - `partialClusterRows`: Pointer to an integer to store the partial cluster rows.
|
||||
* return value: None (void function).
|
||||
* note: The function uses macros and functions provided by the relation to extract the required information and
|
||||
* updates the pointers accordingly.
|
||||
* date: 2023/8/15
|
||||
* contact tel: 18720816902
|
||||
*/
|
||||
static inline void get_info_from_rel(
|
||||
Relation relation, int* maxBatchRow, bool* isPartTable, bool* isValuePartTable, int* partialClusterRows)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -661,6 +661,21 @@ void generate_base_implied_qualities(PlannerInfo* root)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* function name: generate_base_implied_quality_clause
|
||||
* description: This function generates implied quality clauses based on equivalence classes and a given restrict info.
|
||||
* arguments:
|
||||
* - `root`: PlannerInfo context for query planning.
|
||||
* - `rel`: The relational optimization info for the relation.
|
||||
* - `rinfo`: The restrict info for which implied quality clauses need to be generated.
|
||||
* return value: None (void function).
|
||||
* note: The function iterates through the equivalence classes and identifies potential sources to generate implied quality
|
||||
* clauses. It considers conditions like the number of members in the equivalence class, the presence of volatile
|
||||
* expressions, and subset relationships with the restrict info. It then processes and generates implied quality
|
||||
* clauses for the identified conditions.
|
||||
* date: 2023/8/16
|
||||
* contact tel: 18720816902
|
||||
*/
|
||||
static void generate_base_implied_quality_clause(PlannerInfo* root, RelOptInfo* rel, RestrictInfo* rinfo)
|
||||
{
|
||||
ListCell* em_cell = NULL;
|
||||
|
|
|
|||
|
|
@ -59,6 +59,15 @@ bool ES_SELECTIVITY::ContainIndexCols(const es_candidate* es, const IndexOptInfo
|
|||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* function name: MatchUniqueIndex
|
||||
* description: This function checks if there is a unique B-tree index that matches the given es_candidate's columns.
|
||||
* arguments:
|
||||
* - `es`: The es_candidate containing information about the candidate equivalence set and its components.
|
||||
* return value: A boolean indicating whether a matching unique B-tree index was found (true) or not (false).
|
||||
* date: 2023/8/16
|
||||
* contact tel: 18720816902
|
||||
*/
|
||||
bool ES_SELECTIVITY::MatchUniqueIndex(const es_candidate* es) const
|
||||
{
|
||||
ListCell* lci = NULL;
|
||||
|
|
@ -647,6 +656,19 @@ void ES_SELECTIVITY::modify_distinct_by_possion_model(es_candidate* es, bool lef
|
|||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* function name: ClauseIsLegal
|
||||
* description: This function checks if a given clause is legal for the given type of equivalence set.
|
||||
* arguments:
|
||||
* - `type`: The type of equivalence set (ES_EQSEL, ES_EQJOINSEL, etc.).
|
||||
* - `left`: The left-hand side of the clause.
|
||||
* - `right`: The right-hand side of the clause.
|
||||
* - `leftAttnum`: The attribute number of the left-hand side.
|
||||
* - `rightAttnum`: The attribute number of the right-hand side.
|
||||
* return value: A boolean indicating whether the clause is legal (true) or not (false) for the given equivalence set type.
|
||||
* date: 2023/8/16
|
||||
* contact tel: 18720816902
|
||||
*/
|
||||
static bool ClauseIsLegal(es_type type, const Node* left, const Node* right, int leftAttnum, int rightAttnum)
|
||||
{
|
||||
if (leftAttnum < 0 || rightAttnum < 0) {
|
||||
|
|
@ -670,11 +692,33 @@ static bool ClauseIsLegal(es_type type, const Node* left, const Node* right, int
|
|||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* function name: RteIsValid
|
||||
* description: This function checks whether a given RangeTblEntry pointer is valid and represents a relation.
|
||||
* arguments:
|
||||
* - `rte`: The RangeTblEntry pointer to be checked.
|
||||
* return value: A boolean indicating whether the RangeTblEntry is valid and represents a relation (true) or not (false).
|
||||
* note: This function is used to determine if a RangeTblEntry is correctly formed and corresponds to a relation.
|
||||
* date: 2023/8/16
|
||||
* contact tel: 18720816902
|
||||
*/
|
||||
static inline bool RteIsValid(const RangeTblEntry* rte)
|
||||
{
|
||||
return (rte != NULL && rte->rtekind == RTE_RELATION);
|
||||
}
|
||||
|
||||
/*
|
||||
* function name: setup_es
|
||||
* description: This function sets up an equivalence set candidate with relevant information.
|
||||
* arguments:
|
||||
* - `es`: Pointer to the equivalence set candidate to be set up.
|
||||
* - `type`: The type of the equivalence set (ES_EQSEL, ES_EQJOINSEL, etc.).
|
||||
* - `clause`: The RestrictInfo clause associated with the equivalence set.
|
||||
* return value: none
|
||||
* note: This function initializes an equivalence set candidate by assigning its type, clause_relids, and other attributes.
|
||||
* date: 2023/8/16
|
||||
* contact tel: 18720816902
|
||||
*/
|
||||
void ES_SELECTIVITY::setup_es(es_candidate* es, es_type type, RestrictInfo* clause)
|
||||
{
|
||||
es->tag = type;
|
||||
|
|
@ -685,6 +729,20 @@ void ES_SELECTIVITY::setup_es(es_candidate* es, es_type type, RestrictInfo* clau
|
|||
es->right_first_mcvfreq = 0.0;
|
||||
}
|
||||
|
||||
/*
|
||||
* function name: build_es_candidate_for_eqsel
|
||||
* description: This function builds an equivalence set candidate for an equality selectivity calculation.
|
||||
* arguments:
|
||||
* - `es`: Pointer to the equivalence set candidate being built.
|
||||
* - `var`: The variable node representing the column being analyzed.
|
||||
* - `attnum`: The attribute number of the column being analyzed.
|
||||
* - `left`: A boolean indicating whether the variable is on the left-hand side of the clause.
|
||||
* - `clause`: The RestrictInfo clause associated with the equivalence set.
|
||||
* return value: A boolean indicating the success (true) or failure (false) of building the candidate.
|
||||
* note: This function sets up an equivalence set candidate for equality selectivity calculation by extracting relevant information from the variable, clause, and left/right context.
|
||||
* date: 2023/8/16
|
||||
* contact tel: 18720816902
|
||||
*/
|
||||
bool ES_SELECTIVITY::build_es_candidate_for_eqsel(es_candidate* es, Node* var, int attnum, bool left,
|
||||
RestrictInfo* clause)
|
||||
{
|
||||
|
|
@ -840,6 +898,16 @@ void ES_SELECTIVITY::recheck_candidate_list()
|
|||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* function name: IsUnsupportedCases
|
||||
* description: This function checks whether the given EquivalenceClass falls under unsupported cases for generating substitutes.
|
||||
* arguments:
|
||||
* - `ec`: Pointer to the EquivalenceClass being checked.
|
||||
* return value: A boolean indicating whether the EquivalenceClass is unsupported (true) or not (false) for generating substitutes.
|
||||
* note: This function considers various conditions such as having constants, being a broken equivalence class, or having too few members.
|
||||
* date: 2023/8/16
|
||||
* contact tel: 18720816902
|
||||
*/
|
||||
static inline bool IsUnsupportedCases(const EquivalenceClass* ec)
|
||||
{
|
||||
/* only consider var = var situation */
|
||||
|
|
@ -1076,6 +1144,16 @@ void ES_SELECTIVITY::read_statistic()
|
|||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* function name: cal_stadistinct_eqjoinsel
|
||||
* description: This function calculates the selectivity for equality join clauses based on statistical information.
|
||||
* arguments:
|
||||
* - `es`: Pointer to the es_candidate containing the join candidate information.
|
||||
* return value: A boolean indicating whether the selectivity calculation was successful (true) or not (false).
|
||||
* note: This function considers various statistical information to calculate the selectivity for equality join clauses.
|
||||
* date: 2023/8/16
|
||||
* contact tel: 18720816902
|
||||
*/
|
||||
bool ES_SELECTIVITY::cal_stadistinct_eqjoinsel(es_candidate* es)
|
||||
{
|
||||
/*
|
||||
|
|
@ -1129,6 +1207,18 @@ bool ES_SELECTIVITY::cal_stadistinct_eqjoinsel(es_candidate* es)
|
|||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Macro name: CLEAN_UP_TEMP_OBJECTS
|
||||
* description: This macro is used to clean up temporary objects and resources used in a block of code.
|
||||
* arguments:
|
||||
* - `tmp_left`: Temporary object to be cleaned up.
|
||||
* - `tmp_right`: Temporary object to be cleaned up.
|
||||
* - `left_stats_list`: List of extended statistics objects to be cleared.
|
||||
* - `right_stats_list`: List of extended statistics objects to be cleared.
|
||||
* usage: Use this macro to conveniently clean up temporary objects and lists after a block of code.
|
||||
* date: 2023/8/16
|
||||
* contact tel: 18720816902
|
||||
*/
|
||||
#define CLEAN_UP_TEMP_OBJECTS(tmp_left, tmp_right, left_stats_list, right_stats_list) \
|
||||
do { \
|
||||
bms_free_ext(tmp_left); \
|
||||
|
|
@ -1220,6 +1310,18 @@ void ES_SELECTIVITY::read_statistic_eqjoinsel(es_candidate* es)
|
|||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* function name: remove_members_without_es_stats
|
||||
* description: This function removes members from an equivalence set candidate that do not have extended statistics.
|
||||
* arguments:
|
||||
* - `max_matched`: The maximum number of members matched.
|
||||
* - `num_members`: The total number of members.
|
||||
* - `es`: The equivalence set candidate to modify.
|
||||
* note: The function removes members from the `es` candidate's `left_attnums` and calls `remove_attnum` to remove
|
||||
* the corresponding attribute numbers.
|
||||
* date: 2023/8/16
|
||||
* contact tel: 18720816902
|
||||
*/
|
||||
void ES_SELECTIVITY::remove_members_without_es_stats(int max_matched, int num_members, es_candidate* es)
|
||||
{
|
||||
if (max_matched != num_members) {
|
||||
|
|
@ -1233,6 +1335,15 @@ void ES_SELECTIVITY::remove_members_without_es_stats(int max_matched, int num_me
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* function name: cal_stadistinct_eqsel
|
||||
* description: This function calculates the distinct estimate for an equivalence set candidate using extended statistics.
|
||||
* arguments:
|
||||
* - `es`: The equivalence set candidate to calculate distinct estimate for.
|
||||
* note: The function calculates the distinct estimate for the `es` candidate's left-hand side using extended statistics.
|
||||
* date: 2023/8/16
|
||||
* contact tel: 18720816902
|
||||
*/
|
||||
void ES_SELECTIVITY::cal_stadistinct_eqsel(es_candidate* es)
|
||||
{
|
||||
/*
|
||||
|
|
@ -1361,6 +1472,17 @@ int ES_SELECTIVITY::read_attnum(Node* node) const
|
|||
return attnum;
|
||||
}
|
||||
|
||||
/*
|
||||
* function name: BuildNewRelList
|
||||
* description: This function builds a new relation list based on the given attribute numbers and relation ID.
|
||||
* arguments:
|
||||
* - `attnumsTmp`: A Bitmapset containing attribute numbers.
|
||||
* - `relidOid`: The OID of the relation.
|
||||
* return value: A List containing the new relation list information.
|
||||
* note: The function constructs a new relation list by combining the attribute numbers and relation ID.
|
||||
* date: 2023/8/16
|
||||
* contact tel: 18720816902
|
||||
*/
|
||||
static List* BuildNewRelList(Bitmapset* attnumsTmp, Oid relidOid)
|
||||
{
|
||||
List* record = NIL;
|
||||
|
|
@ -1451,6 +1573,20 @@ void ES_SELECTIVITY::report_no_stats(Oid relid_oid, Bitmapset* attnums) const
|
|||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* function name: MatchOnSameSide
|
||||
* description: This function checks if a given clause matches on the same side of the equivalence set.
|
||||
* arguments:
|
||||
* - `clause`: The RestrictInfo clause to check.
|
||||
* - `temp`: The es_candidate structure.
|
||||
* - `leftAttnum`: The attribute number on the left side.
|
||||
* - `rightAttnum`: The attribute number on the right side.
|
||||
* return value: A boolean indicating whether the clause matches on the same side (true) or not (false).
|
||||
* note: The function checks if the clause's left_relids and right_relids are equal to temp's left_relids and right_relids,
|
||||
* and also ensures that the leftAttnum and rightAttnum are not members of temp's left_attnums and right_attnums.
|
||||
* date: 2023/8/16
|
||||
* contact tel: 18720816902
|
||||
*/
|
||||
static bool MatchOnSameSide(RestrictInfo* clause, es_candidate* temp, int leftAttnum, int rightAttnum)
|
||||
{
|
||||
return bms_equal(clause->left_relids, temp->left_relids) &&
|
||||
|
|
@ -1458,6 +1594,20 @@ static bool MatchOnSameSide(RestrictInfo* clause, es_candidate* temp, int leftAt
|
|||
!bms_is_member(leftAttnum, temp->left_attnums) && !bms_is_member(rightAttnum, temp->right_attnums);
|
||||
}
|
||||
|
||||
/*
|
||||
* function name: MatchOnOtherSide
|
||||
* description: This function checks if a given clause matches on the other side of the equivalence set.
|
||||
* arguments:
|
||||
* - `clause`: The RestrictInfo clause to check.
|
||||
* - `temp`: The es_candidate structure.
|
||||
* - `leftAttnum`: The attribute number on the left side.
|
||||
* - `rightAttnum`: The attribute number on the right side.
|
||||
* return value: A boolean indicating whether the clause matches on the other side (true) or not (false).
|
||||
* note: The function checks if the clause's right_relids and left_relids are equal to temp's left_relids and right_relids,
|
||||
* and also ensures that the rightAttnum and leftAttnum are not members of temp's left_attnums and right_attnums.
|
||||
* date: 2023/8/16
|
||||
* contact tel: 18720816902
|
||||
*/
|
||||
static bool MatchOnOtherSide(RestrictInfo* clause, es_candidate* temp, int leftAttnum, int rightAttnum)
|
||||
{
|
||||
return bms_equal(clause->right_relids, temp->left_relids) &&
|
||||
|
|
@ -1466,6 +1616,17 @@ static bool MatchOnOtherSide(RestrictInfo* clause, es_candidate* temp, int leftA
|
|||
!bms_is_member(leftAttnum, temp->right_attnums);
|
||||
}
|
||||
|
||||
/*
|
||||
* function name: AttnumIsInvalid
|
||||
* description: This function checks if the given attribute numbers are invalid.
|
||||
* arguments:
|
||||
* - `leftAttnum`: The attribute number on the left side.
|
||||
* - `rightAttnum`: The attribute number on the right side.
|
||||
* return value: A boolean indicating whether the attribute numbers are invalid (true) or not (false).
|
||||
* note: The function checks if either of the attribute numbers is less than 0 or if both attribute numbers are 0.
|
||||
* date: 2023/8/16
|
||||
* contact tel: 18720816902
|
||||
*/
|
||||
static inline bool AttnumIsInvalid(int leftAttnum, int rightAttnum)
|
||||
{
|
||||
return (leftAttnum < 0 || rightAttnum < 0 || (leftAttnum == 0 && rightAttnum == 0));
|
||||
|
|
@ -1608,6 +1769,20 @@ void ES_SELECTIVITY::read_rel_rte(Node* node, RelOptInfo** rel, RangeTblEntry**
|
|||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* function name: save_selectivity
|
||||
* description: This function saves selectivity information for the given equivalence set candidate.
|
||||
* arguments:
|
||||
* - `es`: The equivalence set candidate for which to save selectivity information.
|
||||
* - `left_join_ratio`: The join ratio for the left side of the join.
|
||||
* - `right_join_ratio`: The join ratio for the right side of the join.
|
||||
* - `save_semi_join`: A boolean indicating whether to save information for a semi-join (true) or not (false).
|
||||
* return value: None
|
||||
* note: The function sets selectivity information for the provided equivalence set candidate, including calculating
|
||||
* and saving selectivity ratios for the variables involved in the equivalence set.
|
||||
* date: 2023/8/16
|
||||
* contact tel: 18720816902
|
||||
*/
|
||||
void ES_SELECTIVITY::save_selectivity(
|
||||
es_candidate* es, double left_join_ratio, double right_join_ratio, bool save_semi_join)
|
||||
{
|
||||
|
|
@ -1692,6 +1867,20 @@ void ES_SELECTIVITY::cal_bucket_size(es_candidate* es, es_bucketsize* bucket) co
|
|||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* function name: estimate_hash_bucketsize
|
||||
* description: This function estimates the bucket size for hash joins.
|
||||
* arguments:
|
||||
* - `es_bucket`: The es_bucketsize structure containing information needed for the estimation.
|
||||
* - `distinctnum`: Pointer to the estimated number of distinct values.
|
||||
* - `left`: A boolean indicating whether to estimate for the left side (true) or the right side (false) of the join.
|
||||
* - `inner_path`: The inner side path of the join.
|
||||
* - `nbuckets`: The number of hash buckets.
|
||||
* return value: The estimated bucket size as a Selectivity value.
|
||||
* note: This function calculates an estimated bucket size for hash joins based on various statistics and factors.
|
||||
* date: 2023/8/16
|
||||
* contact tel: 18720816902
|
||||
*/
|
||||
Selectivity ES_SELECTIVITY::estimate_hash_bucketsize(
|
||||
es_bucketsize* es_bucket, double* distinctnum, bool left, Path* inner_path, double nbuckets)
|
||||
{
|
||||
|
|
@ -1813,6 +2002,17 @@ double ES_SELECTIVITY::estimate_local_numdistinct(es_bucketsize* bucket, bool le
|
|||
return ndistinct;
|
||||
}
|
||||
|
||||
/*
|
||||
* function name: cal_eqjoinsel
|
||||
* description: This function calculates the selectivity for equality join conditions.
|
||||
* arguments:
|
||||
* - `es`: The es_candidate structure containing information needed for the calculation.
|
||||
* - `jointype`: The type of join (JOIN_INNER, JOIN_LEFT, JOIN_FULL, etc.).
|
||||
* return value: The calculated selectivity as a Selectivity value.
|
||||
* note: This function calculates the selectivity for equality join conditions based on the provided information and join type.
|
||||
* date: 2023/8/16
|
||||
* contact tel: 18720816902
|
||||
*/
|
||||
Selectivity ES_SELECTIVITY::cal_eqjoinsel(es_candidate* es, JoinType jointype)
|
||||
{
|
||||
Selectivity result = 1.0;
|
||||
|
|
@ -2215,6 +2415,18 @@ Selectivity ES_SELECTIVITY::cal_eqjoinsel_inner(es_candidate* es)
|
|||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* function name: cal_eqjoinsel_semi
|
||||
* description: This function calculates the selectivity for equality semi-join conditions.
|
||||
* arguments:
|
||||
* - `es`: The es_candidate structure containing information needed for the calculation.
|
||||
* - `inner_rel`: The inner relation for the join.
|
||||
* - `inner_on_left`: A boolean indicating whether the inner relation is on the left side of the join.
|
||||
* return value: The calculated selectivity as a Selectivity value.
|
||||
* note: This function calculates the selectivity for equality semi-join conditions based on the provided information.
|
||||
* date: 2023/8/16
|
||||
* contact tel: 18720816902
|
||||
*/
|
||||
Selectivity ES_SELECTIVITY::cal_eqjoinsel_semi(es_candidate* es, RelOptInfo* inner_rel, bool inner_on_left)
|
||||
{
|
||||
Assert(es->left_extended_stats);
|
||||
|
|
@ -2530,6 +2742,17 @@ void ES_SELECTIVITY::debug_print()
|
|||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* function name: print_rel
|
||||
* description: This function prints information about a relation.
|
||||
* arguments:
|
||||
* - `rel`: The RangeTblEntry structure representing the relation.
|
||||
* return value: None
|
||||
* note: This function initializes a StringInfoData structure to format and print
|
||||
* information about the given relation, including its name, kind, and inheritance status.
|
||||
* date: 2023/8/16
|
||||
* contact tel: 18720816902
|
||||
*/
|
||||
void ES_SELECTIVITY::print_rel(RangeTblEntry* rel) const
|
||||
{
|
||||
StringInfoData buf;
|
||||
|
|
@ -2540,6 +2763,18 @@ void ES_SELECTIVITY::print_rel(RangeTblEntry* rel) const
|
|||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* function name: print_relids
|
||||
* description: This function prints a set of relation identifiers along with a provided string.
|
||||
* arguments:
|
||||
* - `relids`: The Bitmapset representing the set of relation identifiers.
|
||||
* - `str`: The string to be included in the output.
|
||||
* return value: None
|
||||
* note: This function initializes a StringInfoData structure to format and print
|
||||
* the provided string along with the identifiers from the Bitmapset.
|
||||
* date: 2023/8/16
|
||||
* contact tel: 18720816902
|
||||
*/
|
||||
void ES_SELECTIVITY::print_relids(Bitmapset* relids, const char* str) const
|
||||
{
|
||||
StringInfoData buf;
|
||||
|
|
@ -2556,6 +2791,17 @@ void ES_SELECTIVITY::print_relids(Bitmapset* relids, const char* str) const
|
|||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* function name: print_clauses
|
||||
* description: This function prints a list of clauses along with their expressions.
|
||||
* arguments:
|
||||
* - `clauses`: The list of RestrictInfo clauses to be printed.
|
||||
* return value: None
|
||||
* note: This function initializes a StringInfoData structure to format and print
|
||||
* the list of clauses and their expressions.
|
||||
* date: 2023/8/16
|
||||
* contact tel: 18720816902
|
||||
*/
|
||||
void ES_SELECTIVITY::print_clauses(List* clauses) const
|
||||
{
|
||||
if (root == NULL || list_length(clauses) == 0)
|
||||
|
|
@ -2583,6 +2829,17 @@ void ES_SELECTIVITY::print_clauses(List* clauses) const
|
|||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* function name: print_expr
|
||||
* description: This function converts a given expression node to its string representation.
|
||||
* arguments:
|
||||
* - `expr`: The expression node to be converted to string.
|
||||
* - `rtable`: The list of RangeTblEntry entries used for resolving references in the expression.
|
||||
* return value: A dynamically allocated string representing the expression.
|
||||
* note: This function utilizes the ExprToString function to convert the expression node.
|
||||
* date: 2023/8/16
|
||||
* contact tel: 18720816902
|
||||
*/
|
||||
char* ES_SELECTIVITY::print_expr(const Node* expr, const List* rtable) const
|
||||
{
|
||||
return ExprToString(expr, rtable);
|
||||
|
|
|
|||
|
|
@ -743,6 +743,16 @@ static void get_index_paths(
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* function name: index_relation_has_bucket
|
||||
* description: This function checks if an index relation has a bucket.
|
||||
* arguments:
|
||||
* - `index`: The IndexOptInfo structure representing the index.
|
||||
* return value: A boolean indicating whether the index relation has a bucket (true) or not (false).
|
||||
* note: This function opens the underlying heap relation of the index to check for the presence of a bucket.
|
||||
* date: 2023/8/16
|
||||
* contact tel: 18720816902
|
||||
*/
|
||||
static inline bool index_relation_has_bucket(IndexOptInfo* index)
|
||||
{
|
||||
Assert(index != NULL);
|
||||
|
|
@ -753,6 +763,16 @@ static inline bool index_relation_has_bucket(IndexOptInfo* index)
|
|||
return hasBucket;
|
||||
}
|
||||
|
||||
/*
|
||||
* function name: IsEqRestrict
|
||||
* description: This function checks if a RestrictInfo represents an equality restriction.
|
||||
* arguments:
|
||||
* - `rinfo`: The RestrictInfo structure representing the restriction.
|
||||
* return value: A boolean indicating whether the restriction is an equality restriction (true) or not (false).
|
||||
* note: The function checks if the given clause is an equality operator clause and if the operator's result type is EQSELRETURNOID.
|
||||
* date: 2023/8/16
|
||||
* contact tel: 18720816902
|
||||
*/
|
||||
inline bool IsEqRestrict(const RestrictInfo* rinfo)
|
||||
{
|
||||
Expr* clause = rinfo->clause;
|
||||
|
|
@ -814,6 +834,17 @@ void MarkUniqueIndexFirstRule(const RelOptInfo* rel, const IndexOptInfo* index,
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* function name: PathkeysIsUnusefulForPartition
|
||||
* description: This function checks if the path keys of an index are unuseful for partitioning purposes.
|
||||
* arguments:
|
||||
* - `index`: The IndexOptInfo structure representing the index.
|
||||
* return value: A boolean indicating whether the path keys are unuseful for partitioning (true) or not (false).
|
||||
* note: The function considers various conditions, including if the index is a partitioned index, if it's global or hypothetical,
|
||||
* and the type of partitioning being used.
|
||||
* date: 2023/8/16
|
||||
* contact tel: 18720816902
|
||||
*/
|
||||
static bool PathkeysIsUnusefulForPartition(const IndexOptInfo* index)
|
||||
{
|
||||
if (!index->ispartitionedindex) {
|
||||
|
|
|
|||
|
|
@ -76,6 +76,18 @@ static void getBoundaryFromPartSeq(
|
|||
static Path* fakePathForPWJ(Path* path);
|
||||
static bool* calculate_join_georgraphy(
|
||||
PlannerInfo* root, RelOptInfo* outerrel, RelOptInfo* innerrel, List* joinclauses);
|
||||
/*
|
||||
* function name: debug1_print_outerrel_and_innerrel
|
||||
* description: This function prints debug information about outer and inner relations during join planning.
|
||||
* arguments:
|
||||
* - `root`: The PlannerInfo structure representing the query being planned.
|
||||
* - `outerrel`: The outer relation being joined.
|
||||
* - `innerrel`: The inner relation being joined.
|
||||
* return value: None.
|
||||
* note: The function checks if the log_min_messages level is low enough for DEBUG1 messages before printing the information.
|
||||
* date: 2023/8/16
|
||||
* contact tel: 18720816902
|
||||
*/
|
||||
void debug1_print_outerrel_and_innerrel(PlannerInfo* root, RelOptInfo* outerrel, RelOptInfo* innerrel)
|
||||
{
|
||||
if (log_min_messages > DEBUG1)
|
||||
|
|
@ -478,6 +490,18 @@ static bool add_path_hintcheck(
|
|||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* function name: get_join_distribution_perference_type
|
||||
* description: This function determines the distribution preference type for a join operation.
|
||||
* arguments:
|
||||
* - `joinRel`: The joined relation.
|
||||
* - `innerPath`: The path for the inner relation.
|
||||
* - `outerPath`: The path for the outer relation.
|
||||
* return value: The distribution preference type (DPT_SINGLE or DPT_SHUFFLE).
|
||||
* note: The function checks the enable_dngather and is_dngather_support settings before making a decision.
|
||||
* date: 2023/8/17
|
||||
* contact tel: 18720816902
|
||||
*/
|
||||
DistrbutionPreferenceType get_join_distribution_perference_type(RelOptInfo* joinRel, Path* innerPath, Path* outerPath)
|
||||
{
|
||||
if (!u_sess->attr.attr_sql.enable_dngather || !u_sess->opt_cxt.is_dngather_support) {
|
||||
|
|
@ -885,6 +909,26 @@ static void try_mergejoin_path(PlannerInfo* root, RelOptInfo* joinrel, JoinType
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* function name: TryHashJoinPathSingle
|
||||
* description: Tries to generate a hash join path for a single pair of relations.
|
||||
* arguments:
|
||||
* - `root`: PlannerInfo containing the query context.
|
||||
* - `joinrel`: The joined relation.
|
||||
* - `jointype`: The type of join to be performed.
|
||||
* - `sjinfo`: SpecialJoinInfo for special join cases.
|
||||
* - `semifactors`: Factors for semi-joins or anti-joins.
|
||||
* - `outerPath`: Path for the outer relation.
|
||||
* - `innerPath`: Path for the inner relation.
|
||||
* - `restrictClauses`: List of join clauses.
|
||||
* - `hashclauses`: List of hash clauses.
|
||||
* - `requiredOuter`: Required outer relation.
|
||||
* - `workspace`: JoinCostWorkspace for cost estimation.
|
||||
* note: This function attempts to use partitionwise join if applicable, and adds the hash join path to the
|
||||
* joinrel's path list.
|
||||
* date: 2023/8/16
|
||||
* contact tel: 18720816902
|
||||
*/
|
||||
static void TryHashJoinPathSingle(PlannerInfo* root, RelOptInfo* joinrel, JoinType jointype,
|
||||
SpecialJoinInfo* sjinfo, SemiAntiJoinFactors* semifactors, Path* outerPath, Path* innerPath,
|
||||
List* restrictClauses, List* hashclauses, Relids requiredOuter, JoinCostWorkspace* workspace)
|
||||
|
|
@ -2034,6 +2078,19 @@ static List* select_mergejoin_clauses(PlannerInfo* root, RelOptInfo* joinrel, Re
|
|||
return result_list;
|
||||
}
|
||||
|
||||
/*
|
||||
* function name: checkForPWJ
|
||||
* description: Checks if partitionwise join is applicable for the given paths and conditions.
|
||||
* arguments:
|
||||
* - `root`: PlannerInfo containing the query context.
|
||||
* - `outer_path`: Path for the outer relation.
|
||||
* - `inner_path`: Path for the inner relation.
|
||||
* - `jointype`: The type of join to be performed.
|
||||
* - `joinrestrict`: List of join clauses.
|
||||
* returns: True if partitionwise join is applicable, false otherwise.
|
||||
* date: 2023/8/16
|
||||
* contact tel: 18720816902
|
||||
*/
|
||||
static bool checkForPWJ(PlannerInfo* root, Path* outer_path, Path* inner_path, JoinType jointype, List* joinrestrict)
|
||||
{
|
||||
/* Validate configuration */
|
||||
|
|
@ -2091,6 +2148,15 @@ static bool checkForPWJ(PlannerInfo* root, Path* outer_path, Path* inner_path, J
|
|||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* function name: checkIndexPathForPWJ
|
||||
* description: Checks if the given partition iterator path's index subpath is usable for partitionwise join.
|
||||
* arguments:
|
||||
* - `pIterpath`: Partition iterator path to be checked.
|
||||
* returns: True if the index subpath is usable, false otherwise.
|
||||
* date: 2023/8/16
|
||||
* contact tel: 18720816902
|
||||
*/
|
||||
static bool checkIndexPathForPWJ(PartIteratorPath* pIterpath)
|
||||
{
|
||||
bool result = false;
|
||||
|
|
@ -2110,6 +2176,16 @@ static bool checkIndexPathForPWJ(PartIteratorPath* pIterpath)
|
|||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* function name: checkPathForPWJ
|
||||
* description: Checks if the given path is usable for partitionwise join.
|
||||
* arguments:
|
||||
* - `root`: PlannerInfo struct for the current query.
|
||||
* - `path`: Path to be checked.
|
||||
* returns: True if the path is usable, false otherwise.
|
||||
* date: 2023/8/16
|
||||
* contact tel: 18720816902
|
||||
*/
|
||||
static bool checkPathForPWJ(PlannerInfo* root, Path* path)
|
||||
{
|
||||
bool result = false;
|
||||
|
|
@ -2137,6 +2213,16 @@ static bool checkPathForPWJ(PlannerInfo* root, Path* path)
|
|||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* function name: checkPruningResultForPWJ
|
||||
* description: Checks if the pruning result of outer and inner paths match for partitionwise join.
|
||||
* arguments:
|
||||
* - `outerpath`: Outer PartIteratorPath.
|
||||
* - `innerpath`: Inner PartIteratorPath.
|
||||
* returns: True if the pruning results match, false otherwise.
|
||||
* date: 2023/8/16
|
||||
* contact tel: 18720816902
|
||||
*/
|
||||
static bool checkPruningResultForPWJ(PartIteratorPath* outerpath, PartIteratorPath* innerpath)
|
||||
{
|
||||
if (outerpath->itrs > 0 && innerpath->itrs > 0 && outerpath->itrs == innerpath->itrs) {
|
||||
|
|
@ -2146,6 +2232,16 @@ static bool checkPruningResultForPWJ(PartIteratorPath* outerpath, PartIteratorPa
|
|||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* function name: checkScanDirectionPWJ
|
||||
* description: Checks if the scan directions of outer and inner paths match for partitionwise join.
|
||||
* arguments:
|
||||
* - `outerpath`: Outer PartIteratorPath.
|
||||
* - `innerpath`: Inner PartIteratorPath.
|
||||
* returns: True if the scan directions match, false otherwise.
|
||||
* date: 2023/8/16
|
||||
* contact tel: 18720816902
|
||||
*/
|
||||
static bool checkScanDirectionPWJ(PartIteratorPath* outerpath, PartIteratorPath* innerpath)
|
||||
{
|
||||
if (outerpath->direction != innerpath->direction)
|
||||
|
|
@ -2154,6 +2250,17 @@ static bool checkScanDirectionPWJ(PartIteratorPath* outerpath, PartIteratorPath*
|
|||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* function name: checkPartitionkeyForPWJ
|
||||
* description: Checks if the partition keys of outer and inner paths are compatible for partitionwise join.
|
||||
* arguments:
|
||||
* - `root`: PlannerInfo struct.
|
||||
* - `outer_path`: Outer path for join.
|
||||
* - `inner_path`: Inner path for join.
|
||||
* returns: True if partition keys are compatible, false otherwise.
|
||||
* date: 2023/8/16
|
||||
* contact tel: 18720816902
|
||||
*/
|
||||
static bool checkPartitionkeyForPWJ(PlannerInfo* root, Path* outer_path, Path* inner_path)
|
||||
{
|
||||
bool result = true;
|
||||
|
|
@ -2346,6 +2453,17 @@ static bool checkJoinClauseForPWJ(PlannerInfo* root, List* joinclause)
|
|||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* function name: checkBoundaryForPWJ
|
||||
* description: Checks if the boundary information of outer and inner paths is valid for partitionwise join.
|
||||
* arguments:
|
||||
* - `root`: PlannerInfo struct.
|
||||
* - `outerpath`: Outer PartIteratorPath for join.
|
||||
* - `innerpath`: Inner PartIteratorPath for join.
|
||||
* returns: True if boundary information is valid, false otherwise.
|
||||
* date: 2023/8/16
|
||||
* contact tel: 18720816902
|
||||
*/
|
||||
static bool checkBoundaryForPWJ(PlannerInfo* root, PartIteratorPath* outerpath, PartIteratorPath* innerpath)
|
||||
{
|
||||
RelOptInfo* outerrel = outerpath->path.parent;
|
||||
|
|
@ -2371,6 +2489,16 @@ static bool checkBoundaryForPWJ(PlannerInfo* root, PartIteratorPath* outerpath,
|
|||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* function name: checkBoundary
|
||||
* description: Checks if the boundary values of outer and inner partitions match for partitionwise join.
|
||||
* arguments:
|
||||
* - `outer_list`: List of Const values representing the boundary of outer partition.
|
||||
* - `inner_list`: List of Const values representing the boundary of inner partition.
|
||||
* returns: True if boundaries match, false otherwise.
|
||||
* date: 2023/8/16
|
||||
* contact tel: 18720816902
|
||||
*/
|
||||
static bool checkBoundary(List* outer_list, List* inner_list)
|
||||
{
|
||||
ListCell* outer_cell = NULL;
|
||||
|
|
@ -2391,6 +2519,16 @@ static bool checkBoundary(List* outer_list, List* inner_list)
|
|||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* function name: getPartitionkeyDataType
|
||||
* description: Gets the data types of the partition key columns for a given relation.
|
||||
* arguments:
|
||||
* - `root`: PlannerInfo structure containing query information.
|
||||
* - `rel`: RelOptInfo structure for the relation whose partition key data types are needed.
|
||||
* returns: List of OIDs representing the data types of the partition key columns.
|
||||
* date: 2023/8/16
|
||||
* contact tel: 18720816902
|
||||
*/
|
||||
static List* getPartitionkeyDataType(PlannerInfo* root, RelOptInfo* rel)
|
||||
{
|
||||
List* result = NIL;
|
||||
|
|
@ -2438,6 +2576,16 @@ static List* getPartitionkeyDataType(PlannerInfo* root, RelOptInfo* rel)
|
|||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* function name: getPartIteratorPathForPWJ
|
||||
* description: Retrieves the PartIteratorPath from a given path. It traverses through possible MaterialPath
|
||||
* wrappers to find the underlying PartIteratorPath.
|
||||
* arguments:
|
||||
* - `path`: The path from which the PartIteratorPath is to be retrieved.
|
||||
* returns: A pointer to the PartIteratorPath, or NULL if not found.
|
||||
* date: 2023/8/16
|
||||
* contact tel: 18720816902
|
||||
*/
|
||||
static PartIteratorPath* getPartIteratorPathForPWJ(Path* path)
|
||||
{
|
||||
Path* result = NULL;
|
||||
|
|
@ -2457,6 +2605,17 @@ static PartIteratorPath* getPartIteratorPathForPWJ(Path* path)
|
|||
return (PartIteratorPath*)result;
|
||||
}
|
||||
|
||||
/*
|
||||
* function name: getBoundaryFromBaseRel
|
||||
* description: Retrieves the upper and lower boundaries from a base relation's pruning result
|
||||
* and sets them in the provided PartIteratorPath structure.
|
||||
* arguments:
|
||||
* - `root`: The planner's root node.
|
||||
* - `itrpath`: The PartIteratorPath for which to set the boundaries.
|
||||
* returns: None.
|
||||
* date: 2023/8/16
|
||||
* contact tel: 18720816902
|
||||
*/
|
||||
static void getBoundaryFromBaseRel(PlannerInfo* root, PartIteratorPath* itrpath)
|
||||
{
|
||||
ListCell* cell = NULL;
|
||||
|
|
@ -2528,6 +2687,20 @@ static void getBoundaryFromBaseRel(PlannerInfo* root, PartIteratorPath* itrpath)
|
|||
heap_close(relation, NoLock);
|
||||
}
|
||||
|
||||
/*
|
||||
* function name: getBoundaryFromPartSeq
|
||||
* description: Retrieves the upper and lower boundary constants from a partition map based on the provided
|
||||
* partition sequence and attribute information.
|
||||
* arguments:
|
||||
* - `map`: The PartitionMap containing the partition information.
|
||||
* - `partitionSeq`: The sequence number of the partition for which to retrieve the boundaries.
|
||||
* - `att`: The Form_pg_attribute structure representing the attribute information.
|
||||
* - `upper`: A pointer to a Const pointer where the upper boundary constant will be stored.
|
||||
* - `lower`: A pointer to a Const pointer where the lower boundary constant will be stored.
|
||||
* returns: None.
|
||||
* date: 2023/8/16
|
||||
* contact tel: 18720816902
|
||||
*/
|
||||
static void getBoundaryFromPartSeq(
|
||||
PartitionMap* map, int partitionSeq, Form_pg_attribute att, Const** upper, Const** lower)
|
||||
{
|
||||
|
|
@ -2560,6 +2733,18 @@ static void getBoundaryFromPartSeq(
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* function name: buildPartitionWiseJoinPath
|
||||
* description: Builds a partitionwise join path based on the provided join path, outer path, and inner path.
|
||||
* arguments:
|
||||
* - `jpath`: The original join path to be used as the subpath for the partitionwise join path.
|
||||
* - `outter_path`: The outer path of the join.
|
||||
* - `inner_path`: The inner path of the join.
|
||||
* returns:
|
||||
* A new Path representing the partitionwise join path.
|
||||
* date: 2023/8/16
|
||||
* contact tel: 18720816902
|
||||
*/
|
||||
static Path* buildPartitionWiseJoinPath(Path* jpath, Path* outter_path, Path* inner_path)
|
||||
{
|
||||
PartIteratorPath* pwjpath = NULL;
|
||||
|
|
@ -2598,13 +2783,16 @@ static Path* buildPartitionWiseJoinPath(Path* jpath, Path* outter_path, Path* in
|
|||
}
|
||||
|
||||
/*
|
||||
* @@GaussDB@@
|
||||
* Target : data partition
|
||||
* Brief :
|
||||
* Description :
|
||||
* Input :
|
||||
* Output :
|
||||
* Notes :
|
||||
* function name: fakePathForPWJ
|
||||
* description: Creates a "fake" path suitable for use in partitionwise join processing.
|
||||
* This function is used to replace the current path with a path that conforms
|
||||
* to the requirements of partitionwise join.
|
||||
* arguments:
|
||||
* - `path`: The original path that needs to be replaced.
|
||||
* returns:
|
||||
* A new Path structure that meets the requirements of partitionwise join.
|
||||
* date: 2023/8/16
|
||||
* contact tel: 18720816902
|
||||
*/
|
||||
static Path* fakePathForPWJ(Path* path)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1072,6 +1072,18 @@ List* find_mergeclauses_for_outer_pathkeys(PlannerInfo* root, List* pathkeys, Li
|
|||
return mergeclauses;
|
||||
}
|
||||
|
||||
/*
|
||||
* function name: get_pathkey_index
|
||||
* description: Returns the index of the given EquivalenceClass pointer in the array of EquivalenceClass pointers.
|
||||
* arguments:
|
||||
* - `ecs`: An array of EquivalenceClass pointers.
|
||||
* - `necs`: The number of elements in the `ecs` array.
|
||||
* - `key`: The EquivalenceClass pointer to search for.
|
||||
* returns:
|
||||
* The index of the `key` pointer in the `ecs` array if found, or the index after the last element if not found.
|
||||
* date: 2023/8/16
|
||||
* contact tel: 18720816902
|
||||
*/
|
||||
inline int get_pathkey_index(EquivalenceClass** ecs, int necs, EquivalenceClass* key)
|
||||
{
|
||||
int idx;
|
||||
|
|
|
|||
|
|
@ -253,6 +253,14 @@ void JoinPathGenBase::init()
|
|||
m_redistributeOuter = false;
|
||||
}
|
||||
|
||||
/*
|
||||
* function name: initRangeListDistribution
|
||||
* description: This function initializes the distribution strategy for a join path based on range or list distribution.
|
||||
* arguments: None
|
||||
* returns: None
|
||||
* date: 2023/8/16
|
||||
* contact tel: 18720816902
|
||||
*/
|
||||
void JoinPathGenBase::initRangeListDistribution()
|
||||
{
|
||||
m_rangelistOuter = IsLocatorDistributedBySlice(m_outerPath->locator_type);
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -1045,7 +1045,22 @@ Node* replace_rte_variables(Node* node, int target_varno, int sublevels_up, repl
|
|||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
function name: replace_rte_variables_mutator
|
||||
description: This function recursively replaces Range Table Entry (RTE) variables in an expression tree with provided substitutions.
|
||||
arguments: The first argument represents the pointer of the current node in the expression tree.
|
||||
The second argument indicates the context information for the replacement process.
|
||||
return value: Returns the modified expression tree with RTE variable substitutions or the original tree if no changes were made.
|
||||
note: The main process is as follows:
|
||||
-> Traverses the expression tree recursively, handling different node types.
|
||||
-> If the node is a Var (RTE variable), substitutes it if matching target conditions.
|
||||
-> Handles CurrentOfExpr for applicable cases.
|
||||
-> Handles GroupingFunc nodes, checking for subplans.
|
||||
-> Recurses into Query nodes, updating inserted_sublink and hasSubLinks flags.
|
||||
-> Returns the modified expression tree.
|
||||
date: 2023/8/12
|
||||
contact tel: 18720816902
|
||||
*/
|
||||
Node* replace_rte_variables_mutator(Node* node, replace_rte_variables_context* context)
|
||||
{
|
||||
if (node == NULL)
|
||||
|
|
|
|||
Loading…
Reference in New Issue