diff --git a/src/gausskernel/optimizer/path/allpaths.cpp b/src/gausskernel/optimizer/path/allpaths.cpp index 8b768d2af..a8d77bc4b 100755 --- a/src/gausskernel/optimizer/path/allpaths.cpp +++ b/src/gausskernel/optimizer/path/allpaths.cpp @@ -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; diff --git a/src/gausskernel/optimizer/path/clausesel.cpp b/src/gausskernel/optimizer/path/clausesel.cpp index e26a57713..0d5bb9d11 100755 --- a/src/gausskernel/optimizer/path/clausesel.cpp +++ b/src/gausskernel/optimizer/path/clausesel.cpp @@ -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; diff --git a/src/gausskernel/optimizer/path/costsize.cpp b/src/gausskernel/optimizer/path/costsize.cpp index 14765833e..ecbb56d5c 100755 --- a/src/gausskernel/optimizer/path/costsize.cpp +++ b/src/gausskernel/optimizer/path/costsize.cpp @@ -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) { diff --git a/src/gausskernel/optimizer/path/equivclass.cpp b/src/gausskernel/optimizer/path/equivclass.cpp index ba1924521..308329c14 100644 --- a/src/gausskernel/optimizer/path/equivclass.cpp +++ b/src/gausskernel/optimizer/path/equivclass.cpp @@ -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; diff --git a/src/gausskernel/optimizer/path/es_selectivity.cpp b/src/gausskernel/optimizer/path/es_selectivity.cpp index 73e6ef109..40a7e11d3 100644 --- a/src/gausskernel/optimizer/path/es_selectivity.cpp +++ b/src/gausskernel/optimizer/path/es_selectivity.cpp @@ -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); diff --git a/src/gausskernel/optimizer/path/indxpath.cpp b/src/gausskernel/optimizer/path/indxpath.cpp index 2afe50bdf..2ea3dee4b 100755 --- a/src/gausskernel/optimizer/path/indxpath.cpp +++ b/src/gausskernel/optimizer/path/indxpath.cpp @@ -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) { diff --git a/src/gausskernel/optimizer/path/joinpath.cpp b/src/gausskernel/optimizer/path/joinpath.cpp index 1dad81610..f7b00b57a 100755 --- a/src/gausskernel/optimizer/path/joinpath.cpp +++ b/src/gausskernel/optimizer/path/joinpath.cpp @@ -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) { diff --git a/src/gausskernel/optimizer/path/pathkeys.cpp b/src/gausskernel/optimizer/path/pathkeys.cpp index 02d04e8be..c09308bde 100644 --- a/src/gausskernel/optimizer/path/pathkeys.cpp +++ b/src/gausskernel/optimizer/path/pathkeys.cpp @@ -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; diff --git a/src/gausskernel/optimizer/path/streampath_base.cpp b/src/gausskernel/optimizer/path/streampath_base.cpp index 45cf4b2aa..7e03e9650 100755 --- a/src/gausskernel/optimizer/path/streampath_base.cpp +++ b/src/gausskernel/optimizer/path/streampath_base.cpp @@ -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); diff --git a/src/gausskernel/optimizer/plan/createplan.cpp b/src/gausskernel/optimizer/plan/createplan.cpp index 9ada54aa5..11266d756 100755 --- a/src/gausskernel/optimizer/plan/createplan.cpp +++ b/src/gausskernel/optimizer/plan/createplan.cpp @@ -764,6 +764,16 @@ static Plan* create_scan_plan(PlannerInfo* root, Path* best_path) return plan; } +/* + * function name: IsScanPath + * description: This function determines whether a given NodeTag corresponds to a scan path type. + * arguments: + * - type: The NodeTag to be checked. + * return value: A boolean value indicating whether the NodeTag corresponds to a scan path type. + * note: None + * date: 2023/8/19 + * contact tel: 18720816902 + */ static bool IsScanPath(NodeTag type) { return ( @@ -772,6 +782,19 @@ static bool IsScanPath(NodeTag type) ); } +/* + * function name: ScanQualsViolateNotNullConstr + * description: This function checks if scan qualifications violate NOT NULL constraints in the context of a query plan. + * arguments: + * - root: PlannerInfo structure containing planner state for the query. + * - rel: RelOptInfo structure representing the base relation. + * - best_path: Path representing the best scan plan. + * return value: A boolean value indicating whether scan qualifications violate NOT NULL constraints. + * note: This function focuses on checking if any scan qualifications contain NullTest expressions that violate + * NOT NULL constraints on attributes. + * date: 2023/8/19 + * contact tel: 18720816902 + */ static bool ScanQualsViolateNotNullConstr(PlannerInfo* root, RelOptInfo* rel, Path* best_path) { /* For now, we only support table scan optimization */ @@ -2326,6 +2349,23 @@ static CStoreScan* create_cstorescan_plan(PlannerInfo* root, Path* best_path, Li return scan_plan; } +/* + * function name: create_dfsscan_plan + * description: This function creates a plan node for performing a Dfs scan in the query execution. + * arguments: + * - root: PlannerInfo structure containing planner state for the query. + * - bestPath: The best execution path representing the scan plan. + * - tList: The target list of the scan plan. + * - scanClauses: List of scan qualifications. + * - indexFlag: A boolean flag indicating if it's an index scan. + * - excludedCol: List of columns excluded from the scan. + * - indexOnly: A boolean flag indicating if it's an index-only scan. + * return value: A pointer to the created DfsScan plan node. + * note: This function constructs a DfsScan node for the provided scan parameters, including building target + * lists, handling qualifications, and setting various properties. + * date: 2023/8/19 + * contact tel: 18720816902 + */ static DfsScan* create_dfsscan_plan(PlannerInfo* root, Path* bestPath, List* tList, List* scanClauses, bool indexFlag, List* excludedCol, bool indexOnly) { @@ -4086,6 +4126,21 @@ static ExtensiblePlan* create_extensible_plan( * * JOIN METHODS *****************************************************************************/ +/* + * function name: create_nestloop_plan + * description: This function constructs a NestLoop plan node based on the provided parameters, + * including building target lists, handling join clauses, and setting various properties. + * arguments: + * - root: PlannerInfo structure containing information about the current query. + * - best_path: The best NestPath to build the plan from. + * - outer_plan: The plan for the outer (left) side of the join. + * - inner_plan: The plan for the inner (right) side of the join. + * return value: A pointer to the constructed NestLoop plan node. + * note: This function handles the creation of a NestLoop plan node, including processing join clauses + * and parameters, optimizing plans with informational constraints, and handling null equality conditions. + * date: 2023/8/19 + * contact tel: 18720816902 + */ static NestLoop* create_nestloop_plan(PlannerInfo* root, NestPath* best_path, Plan* outer_plan, Plan* inner_plan) { NestLoop* join_plan = NULL; @@ -4183,6 +4238,23 @@ static NestLoop* create_nestloop_plan(PlannerInfo* root, NestPath* best_path, Pl return join_plan; } +/* + * function name: create_mergejoin_plan + * description: This function constructs a MergeJoin plan node based on the provided parameters, including building target lists, + * handling join clauses, sorting input paths, and optimizing plan using informational constraints. + * arguments: + * - root: PlannerInfo struct containing information about the current planning context. + * - best_path: The best MergePath representing the merge join path to be used. + * - outer_plan: The outer subplan to be joined. + * - inner_plan: The inner subplan to be joined. + * return value: A pointer to the constructed MergeJoin plan node. + * note: This function takes the best_path's join clauses, merge clauses, and join type, and constructs a MergeJoin plan node that + * represents a merge join between the outer and inner subplans. It handles various optimization steps including sorting + * input paths, replacing outer-relation variables with nestloop parameters, and checking if plan optimization can be done + * using informational constraints. The constructed MergeJoin plan node is returned. + * date: 2023/8/19 + * contact tel: 18720816902 + */ static MergeJoin* create_mergejoin_plan(PlannerInfo* root, MergePath* best_path, Plan* outer_plan, Plan* inner_plan) { List* tlist = build_relation_tlist(best_path->jpath.path.parent); @@ -5615,6 +5687,20 @@ void copy_plan_costsize(Plan* dest, Plan* src) * Some of these are exported because they are called to build plan nodes * in contexts where we're not deriving the plan node from a path node. *****************************************************************************/ +/* + * function name: make_seqscan + * description: This function creates a sequence scan plan node (SeqScan). + * arguments: + * - qptlist: The targetlist of the query, containing the list of target attributes. + * - qpqual: The qualification conditions of the query. + * - scanrelid: The index (relation identifier) of the relation to be scanned. + * return value: A pointer to the constructed sequence scan plan node (SeqScan). + * note: This function constructs a SeqScan plan node by setting various attributes, including the targetlist, + * qualification conditions, left and right subtrees, and other properties of the plan. The cost estimation + * information should be inserted by the caller before using the constructed node. + * date: 2023/8/19 + * contact tel: 18720816902 + */ static SeqScan* make_seqscan(List* qptlist, List* qpqual, Index scanrelid) { SeqScan* node = makeNode(SeqScan); @@ -5632,6 +5718,20 @@ static SeqScan* make_seqscan(List* qptlist, List* qpqual, Index scanrelid) return node; } +/* + * function name: make_cstorescan + * description: This function creates a columnar store scan plan node (CStoreScan). + * arguments: + * - qptlist: The targetlist of the query, containing the list of target attributes. + * - qpqual: The qualification conditions of the query. + * - scanrelid: The index (relation identifier) of the relation to be scanned. + * return value: A pointer to the constructed columnar store scan plan node (CStoreScan). + * note: This function constructs a CStoreScan plan node by setting various attributes, including the targetlist, + * qualification conditions, left and right subtrees, vector output property, and other properties of the plan. + * The cost estimation information should be inserted by the caller before using the constructed node. + * date: 2023/8/19 + * contact tel: 18720816902 + */ static CStoreScan* make_cstorescan(List* qptlist, List* qpqual, Index scanrelid) { CStoreScan* node = makeNode(CStoreScan); @@ -5692,6 +5792,20 @@ static DfsScan* make_dfsscan(List* tList, List* qual, Index scanReId, List* priv } #ifdef ENABLE_MULTIPLE_NODES +/* + * function name: make_tsstorescan + * description: This function creates a time-series store scan plan node (TsStoreScan). + * arguments: + * - qptlist: The targetlist of the query, containing the list of target attributes. + * - qpqual: The qualification conditions of the query. + * - scanrelid: The index (relation identifier) of the relation to be scanned. + * return value: A pointer to the constructed time-series store scan plan node (TsStoreScan). + * note: This function constructs a TsStoreScan plan node by setting various attributes, including the targetlist, + * qualification conditions, left and right subtrees, vector output property, and other properties of the plan. + * The cost estimation information should be inserted by the caller before using the constructed node. + * date: 2023/8/19 + * contact tel: 18720816902 + */ static TsStoreScan* make_tsstorescan(List* qptlist, List* qpqual, Index scanrelid) { TsStoreScan* node = makeNode(TsStoreScan); @@ -5718,6 +5832,27 @@ static TsStoreScan* make_tsstorescan(List* qptlist, List* qpqual, Index scanreli } #endif /* ENABLE_MULTIPLE_NODES */ +/* + * function name: make_indexscan + * description: This function creates an index scan plan node (IndexScan). + * arguments: + * - qptlist: The targetlist of the query, containing the list of target attributes. + * - qpqual: The qualification conditions of the query. + * - scanrelid: The index (relation identifier) of the relation to be scanned. + * - indexid: The OID of the index to be used for scanning. + * - indexqual: The index qualification conditions. + * - indexqualorig: The original index qualification conditions. + * - indexorderby: The index ordering conditions. + * - indexorderbyorig: The original index ordering conditions. + * - indexscandir: The scan direction of the index. + * return value: A pointer to the constructed index scan plan node (IndexScan). + * note: This function constructs an IndexScan plan node by setting various attributes, including the targetlist, + * qualification conditions, left and right subtrees, scan relation identifier, index OID, index qualification, + * original index qualification, index ordering, original index ordering, and index scan direction. The cost + * estimation information should be inserted by the caller before using the constructed node. + * date: 2023/8/19 + * contact tel: 18720816902 + */ static IndexScan* make_indexscan(List* qptlist, List* qpqual, Index scanrelid, Oid indexid, List* indexqual, List* indexqualorig, List* indexorderby, List* indexorderbyorig, ScanDirection indexscandir) { @@ -5740,6 +5875,26 @@ static IndexScan* make_indexscan(List* qptlist, List* qpqual, Index scanrelid, O return node; } +/* + * function name: make_indexonlyscan + * description: This function creates an index-only scan plan node (IndexOnlyScan). + * arguments: + * - qptlist: The targetlist of the query, containing the list of target attributes. + * - qpqual: The qualification conditions of the query. + * - scanrelid: The index (relation identifier) of the relation to be scanned. + * - indexid: The OID of the index to be used for scanning. + * - indexqual: The index qualification conditions. + * - indexorderby: The index ordering conditions. + * - indextlist: The targetlist for the index-only scan. + * - indexscandir: The scan direction of the index. + * return value: A pointer to the constructed index-only scan plan node (IndexOnlyScan). + * note: This function constructs an IndexOnlyScan plan node by setting various attributes, including the targetlist, + * qualification conditions, left and right subtrees, scan relation identifier, index OID, index qualification, + * index ordering, targetlist for index-only scan, and index scan direction. The cost estimation information + * should be inserted by the caller before using the constructed node. + * date: 2023/8/19 + * contact tel: 18720816902 + */ static IndexOnlyScan* make_indexonlyscan(List* qptlist, List* qpqual, Index scanrelid, Oid indexid, List* indexqual, List* indexorderby, List* indextlist, ScanDirection indexscandir) { @@ -5761,6 +5916,33 @@ static IndexOnlyScan* make_indexonlyscan(List* qptlist, List* qpqual, Index scan return node; } +/* + * function name: make_cstoreindexscan + * description: This function creates a columnar store index scan plan node (CStoreIndexScan). + * arguments: + * - root: The PlannerInfo structure for query planning. + * - best_path: The best access path for the index scan. + * - qptlist: The targetlist of the query, containing the list of target attributes. + * - qpqual: The qualification conditions of the query. + * - scanrelid: The index (relation identifier) of the relation to be scanned. + * - indexid: The OID of the index to be used for scanning. + * - indexqual: The index qualification conditions. + * - indexqualorig: The original index qualification conditions. + * - indexorderby: The index ordering conditions. + * - indexorderbyorig: The original index ordering conditions. + * - indextlist: The targetlist for the index scan. + * - indexscandir: The scan direction of the index. + * - indexonly: Whether it's an index-only scan. + * return value: A pointer to the constructed columnar store index scan plan node (CStoreIndexScan). + * note: This function constructs a CStoreIndexScan plan node by setting various attributes, including the targetlist, + * qualification conditions, left and right subtrees, scan relation identifier, index OID, index qualification, + * original index qualification, index ordering, original index ordering, targetlist for index scan, + * index scan direction, relation store location, and index-only property. The cost estimation information should + * be inserted by the caller before using the constructed node. It also calculates the memory information for + * CStoreIndexScan based on the chosen access method. + * date: 2023/8/19 + * contact tel: 18720816902 + */ static CStoreIndexScan* make_cstoreindexscan(PlannerInfo* root, Path* best_path, List* qptlist, List* qpqual, Index scanrelid, Oid indexid, List* indexqual, List* indexqualorig, List* indexorderby, List* indexorderbyorig, List* indextlist, ScanDirection indexscandir, bool indexonly) @@ -5816,6 +5998,32 @@ static CStoreIndexScan* make_cstoreindexscan(PlannerInfo* root, Path* best_path, return node; } +/* + * function name: make_dfsindexscan + * description: This function creates a DFS index scan plan node (DfsIndexScan). + * arguments: + * - root: The PlannerInfo structure for query planning. + * - best_path: The best access path for the index scan. + * - qptlist: The targetlist of the query, containing the list of target attributes. + * - qpqual: The qualification conditions of the query. + * - scanrelid: The index (relation identifier) of the relation to be scanned. + * - indexid: The OID of the index to be used for scanning. + * - indexqual: The index qualification conditions. + * - indexqualorig: The original index qualification conditions. + * - indexorderby: The index ordering conditions. + * - indexorderbyorig: The original index ordering conditions. + * - indexinfo: Information about the index being scanned. + * - indexscandir: The scan direction of the index. + * - indexonly: Whether it's an index-only scan. + * return value: A pointer to the constructed DFS index scan plan node (DfsIndexScan). + * note: This function constructs a DfsIndexScan plan node by setting various attributes, including the targetlist, + * qualification conditions, left and right subtrees, scan relation identifier, index OID, targetlist for the + * index scan, index qualification, original index qualification, index ordering, original index ordering, + * index scan direction, relation store location, index-only property, and DFS scan plan. It calculates the + * memory information for DfsIndexScan based on the chosen access method and indexonly property. + * date: 2023/8/19 + * contact tel: 18720816902 + */ static DfsIndexScan* make_dfsindexscan(PlannerInfo* root, Path* best_path, List* qptlist, List* qpqual, Index scanrelid, Oid indexid, List* indexqual, List* indexqualorig, List* indexorderby, List* indexorderbyorig, IndexOptInfo* indexinfo, ScanDirection indexscandir, bool indexonly) @@ -5885,6 +6093,22 @@ static DfsIndexScan* make_dfsindexscan(PlannerInfo* root, Path* best_path, List* return node; } +/* + * function name: make_bitmap_indexscan + * description: This function creates a bitmap index scan plan node (BitmapIndexScan). + * arguments: + * - scanrelid: The index (relation identifier) of the relation to be scanned. + * - indexid: The OID of the index to be used for scanning. + * - indexqual: The index qualification conditions. + * - indexqualorig: The original index qualification conditions. + * return value: A pointer to the constructed bitmap index scan plan node (BitmapIndexScan). + * note: This function constructs a BitmapIndexScan plan node by setting various attributes, including the scan relation + * identifier, index OID, index qualification, and original index qualification. The cost estimation information + * should be inserted by the caller before using the constructed node. This node is typically used as part of a + * BitmapAnd or BitmapOr plan to represent a bitmap index scan operation. + * date: 2023/8/19 + * contact tel: 18720816902 + */ static BitmapIndexScan* make_bitmap_indexscan(Index scanrelid, Oid indexid, List* indexqual, List* indexqualorig) { BitmapIndexScan* node = makeNode(BitmapIndexScan); @@ -5903,6 +6127,24 @@ static BitmapIndexScan* make_bitmap_indexscan(Index scanrelid, Oid indexid, List return node; } +/* + * function name: make_bitmap_heapscan + * description: This function creates a bitmap heap scan plan node (BitmapHeapScan). + * arguments: + * - qptlist: The targetlist of the query, containing the list of target attributes. + * - qpqual: The qualification conditions of the query. + * - lefttree: The left subtree plan node. + * - bitmapqualorig: The original bitmap qualification conditions. + * - scanrelid: The index (relation identifier) of the relation to be scanned. + * return value: A pointer to the constructed bitmap heap scan plan node (BitmapHeapScan). + * note: This function constructs a BitmapHeapScan plan node by setting various attributes, including the targetlist, + * qualification conditions, left and right subtrees, scan relation identifier, and original bitmap qualification. + * The cost estimation information should be inserted by the caller before using the constructed node. This node + * represents a bitmap heap scan operation, where a bitmap index scan is used to generate a bitmap of TIDs, which + * is then used to scan the heap relation. + * date: 2023/8/19 + * contact tel: 18720816902 + */ static BitmapHeapScan* make_bitmap_heapscan( List* qptlist, List* qpqual, Plan* lefttree, List* bitmapqualorig, Index scanrelid) { @@ -5922,6 +6164,24 @@ static BitmapHeapScan* make_bitmap_heapscan( return node; } +/* + * function name: make_cstoreindex_ctidscan + * description: This function creates a columnar store index CTID scan plan node (CStoreIndexCtidScan). + * arguments: + * - root: The PlannerInfo structure for query planning. + * - scanrelid: The index (relation identifier) of the relation to be scanned. + * - indexid: The OID of the index to be used for scanning. + * - indexqual: The index qualification conditions. + * - indexqualorig: The original index qualification conditions. + * - indextlist: The targetlist for the index CTID scan. + * return value: A pointer to the constructed columnar store index CTID scan plan node (CStoreIndexCtidScan). + * note: This function constructs a CStoreIndexCtidScan plan node by setting various attributes, including the scan + * relation identifier, index OID, columnar store qualification, index qualification, original index qualification, + * and targetlist for index CTID scan. The cost estimation information should be inserted by the caller before + * using the constructed node. This node represents a CTID scan operation using a columnar store index. + * date: 2023/8/19 + * contact tel: 18720816902 + */ static CStoreIndexCtidScan* make_cstoreindex_ctidscan( PlannerInfo* root, Index scanrelid, Oid indexid, List* indexqual, List* indexqualorig, List* indextlist) { @@ -5944,6 +6204,26 @@ static CStoreIndexCtidScan* make_cstoreindex_ctidscan( return node; } +/* + * function name: make_cstoreindex_heapscan + * description: This function creates a columnar store index heap scan plan node (CStoreIndexHeapScan). + * arguments: + * - root: The PlannerInfo structure for query planning. + * - best_path: The best access path for the index heap scan. + * - qptlist: The targetlist of the query, containing the list of target attributes. + * - qpqual: The qualification conditions of the query. + * - lefttree: The left subtree plan node. + * - bitmapqualorig: The original bitmap qualification conditions. + * - scanrelid: The index (relation identifier) of the relation to be scanned. + * return value: A pointer to the constructed columnar store index heap scan plan node (CStoreIndexHeapScan). + * note: This function constructs a CStoreIndexHeapScan plan node by setting various attributes, including the targetlist, + * qualification conditions, left and right subtrees, scan relation identifier, original bitmap qualification, and + * memory information for sorting. The cost estimation information should be inserted by the caller before using + * the constructed node. This node represents a combination of a columnar store index scan and a heap scan where + * the heap scan uses a bitmap generated from the index scan. + * date: 2023/8/19 + * contact tel: 18720816902 + */ static CStoreIndexHeapScan* make_cstoreindex_heapscan(PlannerInfo* root, Path* best_path, List* qptlist, List* qpqual, Plan* lefttree, List* bitmapqualorig, Index scanrelid) { @@ -5985,6 +6265,22 @@ static CStoreIndexHeapScan* make_cstoreindex_heapscan(PlannerInfo* root, Path* b return node; } +/* + * function name: make_tidscan + * description: This function creates a TID scan plan node (TidScan). + * arguments: + * - qptlist: The targetlist of the query, containing the list of target attributes. + * - qpqual: The qualification conditions of the query. + * - scanrelid: The index (relation identifier) of the relation to be scanned. + * - tidquals: The TID qualification conditions. + * return value: A pointer to the constructed TID scan plan node (TidScan). + * note: This function constructs a TidScan plan node by setting various attributes, including the targetlist, + * qualification conditions, left and right subtrees, scan relation identifier, and TID qualification conditions. + * The cost estimation information should be inserted by the caller before using the constructed node. This node + * represents a scan operation based on TID conditions, where specific rows are selected based on their TID values. + * date: 2023/8/19 + * contact tel: 18720816902 + */ static TidScan* make_tidscan(List* qptlist, List* qpqual, Index scanrelid, List* tidquals) { TidScan* node = makeNode(TidScan); @@ -6001,6 +6297,22 @@ static TidScan* make_tidscan(List* qptlist, List* qpqual, Index scanrelid, List* return node; } +/* + * function name: make_subqueryscan + * description: This function creates a subquery scan plan node (SubqueryScan). + * arguments: + * - qptlist: The targetlist of the query, containing the list of target attributes. + * - qpqual: The qualification conditions of the query. + * - scanrelid: The index (relation identifier) of the relation to be scanned. + * - subplan: The subplan representing the subquery to be executed. + * return value: A pointer to the constructed subquery scan plan node (SubqueryScan). + * note: This function constructs a SubqueryScan plan node by setting various attributes, including the targetlist, + * qualification conditions, left and right subtrees, scan relation identifier, and the subplan to be executed. + * The cost estimation information is calculated based on the subplan and adjusted for the convenience of + * prepunion.c. This node represents the execution of a subquery as part of the main query execution. + * date: 2023/8/19 + * contact tel: 18720816902 + */ SubqueryScan* make_subqueryscan(List* qptlist, List* qpqual, Index scanrelid, Plan* subplan) { SubqueryScan* node = makeNode(SubqueryScan); @@ -6133,6 +6445,21 @@ Plan* create_globalpartInterator_plan(PlannerInfo* root, PartIteratorPath* pIter return plan; } +/* + * function name: create_partIterator_plan + * description: This function constructs a PartIterator plan node (PartIterator) for partitioned table scanning. + * arguments: + * - root: The PlannerInfo structure for query planning. + * - pIterpath: The PartIteratorPath containing information about the partitioned table scan path. + * - gpIter: The GlobalPartIterator containing global partition iterator information (if available). + * return value: A pointer to the constructed PartIterator plan node (PartIterator). + * note: This function constructs a PartIterator plan node by setting various attributes, including the partition + * iterator direction, iteration information, partition type, and parameters. It also constructs the subplan + * (left subtree) and adjusts the targetlist, external parameters, and all parameters. The function handles the + * case where there are pseudoconstant clauses attached to the subplan by inserting a gating Result node. + * date: 2023/8/19 + * contact tel: 18720816902 + */ static PartIterator* create_partIterator_plan( PlannerInfo* root, PartIteratorPath* pIterpath, GlobalPartIterator* gpIter) { @@ -6208,6 +6535,27 @@ static PartIterator* create_partIterator_plan( return partItr; } +/* + * function name: make_functionscan + * description: This function creates a function scan plan node (FunctionScan). + * arguments: + * - qptlist: The targetlist of the query, containing the list of target attributes. + * - qpqual: The qualification conditions of the query. + * - scanrelid: The index (relation identifier) of the relation to be scanned. + * - funcexpr: The expression representing the function to be scanned. + * - funccolnames: The names of the columns returned by the function. + * - funccoltypes: The data types of the columns returned by the function. + * - funccoltypmods: The type modifiers of the columns returned by the function. + * - funccolcollations: The collations of the columns returned by the function. + * return value: A pointer to the constructed function scan plan node (FunctionScan). + * note: This function constructs a FunctionScan plan node by setting various attributes, including the targetlist, + * qualification conditions, left and right subtrees, scan relation identifier, function expression, column names, + * column data types, type modifiers, and collations. The cost estimation information should be inserted by the + * caller before using the constructed node. This node represents a scan operation that involves evaluating a + * function and returning the result as columns. + * date: 2023/8/19 + * contact tel: 18720816902 + */ static FunctionScan* make_functionscan(List* qptlist, List* qpqual, Index scanrelid, Node* funcexpr, List* funccolnames, List* funccoltypes, List* funccoltypmods, List* funccolcollations) { @@ -6229,6 +6577,23 @@ static FunctionScan* make_functionscan(List* qptlist, List* qpqual, Index scanre return node; } +/* + * function name: make_valuesscan + * description: Creates a values scan plan node (ValuesScan). + * arguments: + * - qptlist: The targetlist of the query, containing the list of target attributes. + * - qpqual: The qualification conditions of the query. + * - scanrelid: The index (relation identifier) of the relation to be scanned. + * - values_lists: The list of lists containing the values to be scanned. + * return value: A pointer to the constructed values scan plan node (ValuesScan). + * note: This function constructs a ValuesScan plan node by setting various attributes, including the targetlist, + * qualification conditions, left and right subtrees, scan relation identifier, and the list of values to be + * scanned. The cost estimation information should be inserted by the caller before using the constructed node. + * This node represents a scan operation where the values are provided explicitly, typically used for constructing + * temporary tables or constant value tables. + * date: 2023/8/19 + * contact tel: 18720816902 + */ static ValuesScan* make_valuesscan(List* qptlist, List* qpqual, Index scanrelid, List* values_lists) { ValuesScan* node = makeNode(ValuesScan); @@ -6245,6 +6610,23 @@ static ValuesScan* make_valuesscan(List* qptlist, List* qpqual, Index scanrelid, return node; } +/* + * function name: make_ctescan + * description: Creates a common table expression (CTE) scan plan node (CteScan). + * arguments: + * - qptlist: The targetlist of the query, containing the list of target attributes. + * - qpqual: The qualification conditions of the query. + * - scanrelid: The index (relation identifier) of the relation to be scanned. + * - ctePlanId: The ID of the CTE plan node that provides the data for scanning. + * - cteParam: The parameter ID used to access the CTE plan's output. + * return value: A pointer to the constructed CTE scan plan node (CteScan). + * note: This function constructs a CteScan plan node by setting various attributes, including the targetlist, + * qualification conditions, left and right subtrees, scan relation identifier, CTE plan ID, and CTE parameter. + * The cost estimation information should be inserted by the caller before using the constructed node. + * This node represents a scan operation that retrieves data from a previously defined common table expression. + * date: 2023/8/19 + * contact tel: 18720816902 + */ static CteScan* make_ctescan(List* qptlist, List* qpqual, Index scanrelid, int ctePlanId, int cteParam) { CteScan* node = makeNode(CteScan); @@ -6262,6 +6644,23 @@ static CteScan* make_ctescan(List* qptlist, List* qpqual, Index scanrelid, int c return node; } +/* + * function name: make_worktablescan + * description: Creates a worktable scan plan node (WorkTableScan). + * arguments: + * - qptlist: The targetlist of the query, containing the list of target attributes. + * - qpqual: The qualification conditions of the query. + * - scanrelid: The index (relation identifier) of the relation to be scanned. + * - wtParam: The parameter ID used to access the worktable plan's output. + * return value: A pointer to the constructed worktable scan plan node (WorkTableScan). + * note: This function constructs a WorkTableScan plan node by setting various attributes, including the targetlist, + * qualification conditions, left and right subtrees, scan relation identifier, and worktable parameter. + * The cost estimation information should be inserted by the caller before using the constructed node. + * This node represents a scan operation that retrieves data from a worktable, which is a temporary storage + * area used during query execution, often associated with recursive CTEs. + * date: 2023/8/19 + * contact tel: 18720816902 + */ static WorkTableScan* make_worktablescan(List* qptlist, List* qpqual, Index scanrelid, int wtParam) { WorkTableScan* node = makeNode(WorkTableScan); @@ -6278,6 +6677,25 @@ static WorkTableScan* make_worktablescan(List* qptlist, List* qpqual, Index scan return node; } +/* + * function name: make_foreignscan + * description: Creates a foreign scan plan node (ForeignScan). + * arguments: + * - qptlist: The targetlist of the query, containing the list of target attributes. + * - qpqual: The qualification conditions of the query. + * - scanrelid: The index (relation identifier) of the relation to be scanned. + * - fdw_exprs: List of expressions representing remote data retrieval from the foreign data source. + * - fdw_private: Private information used by the foreign data wrapper (FDW). + * - type: The execution type for the remote query (single-node or distributed execution). + * return value: A pointer to the constructed foreign scan plan node (ForeignScan). + * note: This function constructs a ForeignScan plan node by setting various attributes, including the targetlist, + * qualification conditions, left and right subtrees, scan relation identifier, expressions for remote data + * retrieval, private information for the foreign data wrapper, execution type, distributed keys (if applicable), + * and system column information. The cost estimation information will be filled in by the caller of + * create_foreignscan_plan. This node represents a scan operation that retrieves data from a foreign data source. + * date: 2023/8/19 + * contact tel: 18720816902 + */ ForeignScan* make_foreignscan( List* qptlist, List* qpqual, Index scanrelid, List* fdw_exprs, List* fdw_private, RemoteQueryExecType type) { @@ -6310,6 +6728,21 @@ ForeignScan* make_foreignscan( return node; } +/* + * function name: make_append + * description: Creates an append plan node (Append). + * arguments: + * - appendplans: List of subplans to be appended together. + * - tlist: The targetlist of the query, containing the list of target attributes. + * return value: A pointer to the constructed append plan node (Append). + * note: This function constructs an Append plan node by setting various attributes, including the list of subplans + * to be appended, targetlist, qualification conditions, left and right subtrees, degree of parallelism (DOP), + * execution nodes, startup cost, total cost, plan rows, plan width, and multiple. The cost estimation information + * and other parameters will be filled in according to the provided subplans. This node represents a plan that + * appends the results of multiple subplans together to produce a combined output. + * date: 2023/8/19 + * contact tel: 18720816902 + */ Append* make_append(List* appendplans, List* tlist) { Append* node = makeNode(Append); @@ -6388,6 +6821,24 @@ Append* make_append(List* appendplans, List* tlist) return node; } +/* + * function name: make_recursive_union + * description: Creates a recursive union plan node (RecursiveUnion). + * arguments: + * - tlist: The targetlist of the query, containing the list of target attributes. + * - lefttree: The left subplan of the recursive union. + * - righttree: The right subplan of the recursive union. + * - wtParam: The parameter ID used to access the recursive union plan's output. + * - distinctList: List of distinct attributes for grouping. + * - numGroups: The estimated number of distinct groups. + * return value: A pointer to the constructed recursive union plan node (RecursiveUnion). + * note: This function constructs a RecursiveUnion plan node by setting various attributes, including the targetlist, + * qualification conditions, left and right subtrees, parameter ID, distinct attributes, number of distinct groups, + * and other related parameters. The cost estimation information will be computed by the cost_recursive_union + * function. This node represents a plan that performs a recursive union operation. + * date: 2023/8/19 + * contact tel: 18720816902 + */ RecursiveUnion* make_recursive_union( List* tlist, Plan* lefttree, Plan* righttree, int wtParam, List* distinctList, long numGroups) { @@ -6434,6 +6885,19 @@ RecursiveUnion* make_recursive_union( return node; } +/* + * function name: make_bitmap_and + * description: Creates a bitmap AND plan node (BitmapAnd). + * arguments: + * - bitmapplans: List of subplans producing bitmap scans. + * return value: A pointer to the constructed bitmap AND plan node (BitmapAnd). + * note: This function constructs a BitmapAnd plan node by setting various attributes, including the list of subplans + * producing bitmap scans, targetlist, qualification conditions, left and right subtrees. The cost estimation + * information should be inserted by the caller before using the constructed node. This node represents a plan + * that performs a bitmap AND operation on multiple bitmap scans. + * date: 2023/8/19 + * contact tel: 18720816902 + */ static BitmapAnd* make_bitmap_and(List* bitmapplans) { BitmapAnd* node = makeNode(BitmapAnd); @@ -6454,6 +6918,19 @@ static BitmapAnd* make_bitmap_and(List* bitmapplans) return node; } +/* + * function name: make_cstoreindex_and + * description: Creates a columnar store index AND plan node (CStoreIndexAnd). + * arguments: + * - ctidplans: List of subplans producing columnar store index scans. + * return value: A pointer to the constructed columnar store index AND plan node (CStoreIndexAnd). + * note: This function constructs a CStoreIndexAnd plan node by setting various attributes, including the list of + * subplans producing columnar store index scans, targetlist, qualification conditions, left and right subtrees. + * The cost estimation information should be inserted by the caller before using the constructed node. This node + * represents a plan that performs an AND operation on multiple columnar store index scans. + * date: 2023/8/19 + * contact tel: 18720816902 + */ static CStoreIndexAnd* make_cstoreindex_and(List* ctidplans) { CStoreIndexAnd* node = makeNode(CStoreIndexAnd); @@ -6474,6 +6951,19 @@ static CStoreIndexAnd* make_cstoreindex_and(List* ctidplans) return node; } +/* + * function name: make_bitmap_or + * description: Creates a bitmap OR plan node (BitmapOr). + * arguments: + * - bitmapplans: List of subplans producing bitmap scans. + * return value: A pointer to the constructed bitmap OR plan node (BitmapOr). + * note: This function constructs a BitmapOr plan node by setting various attributes, including the list of subplans + * producing bitmap scans, targetlist, qualification conditions, left and right subtrees. The cost estimation + * information should be inserted by the caller before using the constructed node. This node represents a plan + * that performs a bitmap OR operation on multiple bitmap scans. + * date: 2023/8/19 + * contact tel: 18720816902 + */ static BitmapOr* make_bitmap_or(List* bitmapplans) { BitmapOr* node = makeNode(BitmapOr); @@ -6494,6 +6984,19 @@ static BitmapOr* make_bitmap_or(List* bitmapplans) return node; } +/* + * function name: make_cstoreindex_or + * description: Creates a columnar store index OR plan node (CStoreIndexOr). + * arguments: + * - ctidplans: List of subplans producing columnar store index scans. + * return value: A pointer to the constructed columnar store index OR plan node (CStoreIndexOr). + * note: This function constructs a CStoreIndexOr plan node by setting various attributes, including the list of + * subplans producing columnar store index scans, targetlist, qualification conditions, left and right subtrees. + * The cost estimation information should be inserted by the caller before using the constructed node. This node + * represents a plan that performs an OR operation on multiple columnar store index scans. + * date: 2023/8/19 + * contact tel: 18720816902 + */ static CStoreIndexOr* make_cstoreindex_or(List* ctidplans) { CStoreIndexOr* node = makeNode(CStoreIndexOr); @@ -6514,6 +7017,25 @@ static CStoreIndexOr* make_cstoreindex_or(List* ctidplans) return node; } +/* + * function name: make_nestloop + * description: Creates a nested loop join plan node (NestLoop). + * arguments: + * - tlist: The targetlist of the query, containing the list of target attributes. + * - joinclauses: List of join clauses. + * - otherclauses: List of additional qualification conditions. + * - nestParams: List of NestLoopParams specifying parameterized paths. + * - lefttree: The left subplan of the nested loop join. + * - righttree: The right subplan of the nested loop join. + * - jointype: The type of join to be performed (inner, left, right, full outer, etc.). + * return value: A pointer to the constructed nested loop join plan node (NestLoop). + * note: This function constructs a NestLoop plan node by setting various attributes, including the targetlist, + * join clauses, additional qualification conditions, left and right subtrees, join type, and nest loop parameters. + * The cost estimation information should be inserted by the caller before using the constructed node. This node + * represents a plan that performs a nested loop join operation. + * date: 2023/8/19 + * contact tel: 18720816902 + */ static NestLoop* make_nestloop(List* tlist, List* joinclauses, List* otherclauses, List* nestParams, Plan* lefttree, Plan* righttree, JoinType jointype) { @@ -6619,6 +7141,24 @@ static void estimate_directHashjoin_Cost( join_plan->join.plan.plan_width = outer_width; } +/* + * function name: create_direct_hashjoin + * description: Creates a hash join plan node (HashJoin) for a direct hash join operation. + * arguments: + * - root: The planner's main data structure, containing various planning information. + * - outerPlan: The left subplan of the hash join. + * - innerPlan: The right subplan of the hash join. + * - tlist: The targetlist of the query, containing the list of target attributes. + * - joinClauses: List of join clauses. + * - joinType: The type of join to be performed (inner, left, right, full outer, etc.). + * return value: A pointer to the constructed hash join plan node (HashJoin). + * note: This function constructs a HashJoin plan node for a direct hash join operation by setting various attributes, + * including the targetlist, join clauses, left and right subtrees, and various other parameters. The cost + * estimation information should be estimated before using the constructed node. This node represents a plan that + * performs a hash join operation between the provided subplans. + * date: 2023/8/19 + * contact tel: 18720816902 + */ HashJoin* create_direct_hashjoin( PlannerInfo* root, Plan* outerPlan, Plan* innerPlan, List* tlist, List* joinClauses, JoinType joinType) { @@ -6721,6 +7261,19 @@ typedef struct replace_scan_clause_context { List* scan_clauses; } replace_scan_clause_context; +/* + * function name: replace_scan_clause_walker + * description: Walks through a parse tree node and replaces scan clauses with a new destination index. + * arguments: + * - node: The current node being processed in the parse tree. + * - context: Context information containing the destination index for replacement. + * return value: A boolean indicating whether the walk should continue (true) or stop (false). + * note: This function is used to traverse a parse tree and replace scan clauses with a specified destination index. + * It handles cases where the node is a Var (variable reference) and updates its varno to the new destination + * index. It also skips HashFilter nodes and continues the walk through other nodes. + * date: 2023/8/19 + * contact tel: 18720816902 + */ static bool replace_scan_clause_walker(Node* node, replace_scan_clause_context* context) { if (node == NULL) @@ -6737,6 +7290,19 @@ static bool replace_scan_clause_walker(Node* node, replace_scan_clause_context* return expression_tree_walker(node, (bool (*)())replace_scan_clause_walker, (void*)context); } +/* + * function name: replace_scan_clause + * description: Replaces scan clauses in a list with a new destination index. + * arguments: + * - scan_clauses: List of scan clauses to be processed. + * - idx: The new destination index for replacement. + * return value: A new list containing the scan clauses with updated destination index. + * note: This function takes a list of scan clauses and a new destination index. It walks through each scan clause in + * the list and uses the replace_scan_clause_walker function to replace Var nodes with the new destination index. + * The modified scan clauses are collected in a new list and returned. + * date: 2023/8/19 + * contact tel: 18720816902 + */ static List* replace_scan_clause(List* scan_clauses, Index idx) { replace_scan_clause_context context; @@ -6757,6 +7323,23 @@ static List* replace_scan_clause(List* scan_clauses, Index idx) return context.scan_clauses; } +/* + * function name: create_direct_scan + * description: Creates a scan plan for direct table access based on the specified table orientation. + * arguments: + * - root: The planner's main data structure, containing various planning information. + * - tlist: The targetlist of the query, containing the list of target attributes. + * - realResultRTE: The RangeTblEntry representing the table being accessed. + * - src_idx: The index of the source relation in the simple_rel_array. + * - dest_idx: The new destination index for replacement in scan clauses. + * return value: A pointer to the constructed scan plan. + * note: This function constructs a scan plan for direct table access based on the table's orientation (column-oriented, + * row-oriented, or timeseries-oriented). It generates the appropriate scan node (e.g., CStoreScan or SeqScan), + * sets targetlist and scan clauses, calculates costs, and handles partitioned tables. The plan is then configured + * for execution on datanodes and distributed based on the table's distribution keys. + * date: 2023/8/19 + * contact tel: 18720816902 + */ Plan* create_direct_scan(PlannerInfo* root, List* tlist, RangeTblEntry* realResultRTE, Index src_idx, Index dest_idx) { Plan* result = NULL; @@ -6900,6 +7483,24 @@ Plan* create_direct_righttree( return righttree; } +/* + * function name: make_hashjoin + * description: Creates a HashJoin plan node based on the provided information. + * arguments: + * - tlist: The targetlist of the query, containing the list of target attributes. + * - joinclauses: List of join clauses. + * - otherclauses: List of additional quals. + * - hashclauses: List of hash join clauses. + * - lefttree: The left subtree of the hash join. + * - righttree: The right subtree of the hash join. + * - jointype: The type of join to be performed (inner, left, right, full outer, etc.). + * return value: A pointer to the constructed HashJoin plan node. + * note: This function constructs a HashJoin plan node with the provided attributes, including targetlist, join clauses, + * other quals, hash join clauses, left and right subtrees, and join type. The cost should be set by the caller + * before using the constructed node. + * date: 2023/8/19 + * contact tel: 18720816902 + */ static HashJoin* make_hashjoin(List* tlist, List* joinclauses, List* otherclauses, List* hashclauses, Plan* lefttree, Plan* righttree, JoinType jointype) { @@ -6918,6 +7519,24 @@ static HashJoin* make_hashjoin(List* tlist, List* joinclauses, List* otherclause return node; } +/* + * function name: make_hash + * description: Creates a Hash plan node for hash-based join processing. + * arguments: + * - lefttree: The left subtree of the hash join. + * - skewTable: OID of the table to be used for skew optimization. + * - skewColumn: Attribute number of the column to be used for skew optimization. + * - skewInherit: Flag indicating whether skew optimization should inherit to child nodes. + * - skewColType: Data type OID of the skew column. + * - skewColTypmod: Type modifier of the skew column. + * return value: A pointer to the constructed Hash plan node. + * note: This function constructs a Hash plan node, which is used for hash-based join processing. It copies cost and + * size information from the input left subtree, sets the startup cost to be equal to the total cost for plausibility + * reasons, and includes information about skew optimization if provided. The constructed Hash node represents + * the hash-based join plan. + * date: 2023/8/19 + * contact tel: 18720816902 + */ static Hash* make_hash( Plan* lefttree, Oid skewTable, AttrNumber skewColumn, bool skewInherit, Oid skewColType, int32 skewColTypmod) { @@ -6950,6 +7569,28 @@ static Hash* make_hash( return node; } +/* + * function name: make_mergejoin + * description: Creates a MergeJoin plan node for merge join processing. + * arguments: + * - tlist: The targetlist of the query, containing the list of target attributes. + * - joinclauses: List of join clauses. + * - otherclauses: List of additional quals. + * - mergeclauses: List of merge join clauses. + * - mergefamilies: Array of operator families for merge join clauses. + * - mergecollations: Array of collations for merge join clauses. + * - mergestrategies: Array of merge strategies for merge join clauses. + * - mergenullsfirst: Array indicating whether NULLs come first for each merge join clause. + * - lefttree: The left subtree of the merge join. + * - righttree: The right subtree of the merge join. + * - jointype: The type of join to be performed (inner, left, right, full outer, etc.). + * return value: A pointer to the constructed MergeJoin plan node. + * note: This function constructs a MergeJoin plan node, which is used for merge join processing. It sets various attributes + * such as targetlist, join clauses, merge clauses, operator families, collations, strategies, NULLs ordering, + * left and right subtrees, and join type. The cost should be set by the caller before using the constructed node. + * date: 2023/8/19 + * contact tel: 18720816902 + */ static MergeJoin* make_mergejoin(List* tlist, List* joinclauses, List* otherclauses, List* mergeclauses, Oid* mergefamilies, Oid* mergecollations, int* mergestrategies, bool* mergenullsfirst, Plan* lefttree, Plan* righttree, JoinType jointype) @@ -7510,6 +8151,19 @@ Sort* make_sort_from_targetlist(PlannerInfo* root, Plan* lefttree, double limit_ } } +/* + * function name: make_material + * description: Creates a Material plan node for materializing intermediate results. + * arguments: + * - lefttree: The input plan subtree to be materialized. + * - materialize_all: Flag indicating whether to materialize all rows. + * return value: A pointer to the constructed Material plan node. + * note: This function constructs a Material plan node, which is used for materializing intermediate query results. + * It copies the targetlist and DOP (Degree of Parallelism) from the input plan, sets materialization properties, + * and inherits other relevant attributes. The cost should be set by the caller before using the constructed node. + * date: 2023/8/19 + * contact tel: 18720816902 + */ Material* make_material(Plan* lefttree, bool materialize_all) { Material* node = makeNode(Material); @@ -7611,6 +8265,35 @@ void adjust_all_pathkeys_by_agg_tlist(PlannerInfo* root, List* tlist, WindowList root->query_pathkeys = NIL; } +/* + * function name: make_agg + * description: Creates an Agg plan node for aggregate computation. + * arguments: + * - root: The planner's main data structure, containing various planning information. + * - tlist: The targetlist of the query, containing the list of target attributes. + * - qual: List of quals representing the aggregate filter (HAVING clause). + * - aggstrategy: The strategy for performing aggregation (PLAIN, SORTED, HASHED). + * - aggcosts: Cost information related to aggregation operations. + * - numGroupCols: The number of grouping columns. + * - grpColIdx: Array of attribute numbers representing grouping columns. + * - grpOperators: Array of operator OIDs for grouping columns. + * - numGroups: The estimated number of distinct groups. + * - lefttree: The input plan subtree for aggregation. + * - wflists: Window function information for optimization. + * - need_stream: Flag indicating whether stream plan is required. + * - trans_agg: Flag indicating if transition aggregates are present. + * - groupingSets: List of grouping sets. + * - hash_entry_size: Size of hash table entry for hash aggregation. + * - add_width: Flag indicating whether to add agg function width to total width. + * - agg_orientation: Orientation of aggregation (DISTINCT_INTENT, AGG_LEVEL_1_INTENT, etc.). + * - unique_check: Flag indicating whether unique check is required. + * return value: A pointer to the constructed Agg plan node. + * note: This function constructs an Agg plan node for performing aggregate computation. It sets various attributes such + * as targetlist, quals, grouping columns, strategies, estimated number of groups, distribution information, + * costs, and more. The constructed node represents the aggregation plan for execution. + * date: 2023/8/19 + * contact tel: 18720816902 + */ Agg* make_agg(PlannerInfo* root, List* tlist, List* qual, AggStrategy aggstrategy, const AggClauseCosts* aggcosts, int numGroupCols, AttrNumber* grpColIdx, Oid* grpOperators, long numGroups, Plan* lefttree, WindowLists* wflists, bool need_stream, bool trans_agg, List* groupingSets, Size hash_entry_size, bool add_width, @@ -7767,6 +8450,31 @@ Agg* make_agg(PlannerInfo* root, List* tlist, List* qual, AggStrategy aggstrateg return node; } +/* + * function name: make_windowagg + * description: Creates a WindowAgg plan node for window function computation. + * arguments: + * - root: The planner's main data structure, containing various planning information. + * - tlist: The targetlist of the query, containing the list of target attributes. + * - windowFuncs: List of window functions to be computed. + * - winref: Reference number for the window specification. + * - partNumCols: The number of partitioning columns. + * - partColIdx: Array of attribute numbers representing partitioning columns. + * - partOperators: Array of operator OIDs for partitioning columns. + * - ordNumCols: The number of ordering columns. + * - ordColIdx: Array of attribute numbers representing ordering columns. + * - ordOperators: Array of operator OIDs for ordering columns. + * - frameOptions: Options for defining the window frame. + * - startOffset: Starting offset for the window frame. + * - endOffset: Ending offset for the window frame. + * - lefttree: The input plan subtree for window function computation. + * return value: A pointer to the constructed WindowAgg plan node. + * note: This function constructs a WindowAgg plan node for performing window function computation. It sets various attributes + * such as targetlist, window function definitions, partitioning and ordering columns, frame options, distribution + * information, costs, and more. The constructed node represents the window function computation plan for execution. + * date: 2023/8/19 + * contact tel: 18720816902 + */ WindowAgg* make_windowagg(PlannerInfo* root, List* tlist, List* windowFuncs, Index winref, int partNumCols, AttrNumber* partColIdx, Oid* partOperators, int ordNumCols, AttrNumber* ordColIdx, Oid* ordOperators, int frameOptions, Node* startOffset, Node* endOffset, Plan* lefttree) @@ -7820,6 +8528,25 @@ WindowAgg* make_windowagg(PlannerInfo* root, List* tlist, List* windowFuncs, Ind return node; } +/* + * function name: make_group + * description: Creates a Group plan node for grouping operation. + * arguments: + * - root: The planner's main data structure, containing various planning information. + * - tlist: The targetlist of the query, containing the list of target attributes. + * - qual: List of quals representing the grouping filter (HAVING clause). + * - numGroupCols: The number of grouping columns. + * - grpColIdx: Array of attribute numbers representing grouping columns. + * - grpOperators: Array of operator OIDs for grouping columns. + * - numGroups: The estimated number of distinct groups. + * - lefttree: The input plan subtree for grouping operation. + * return value: A pointer to the constructed Group plan node. + * note: This function constructs a Group plan node for performing grouping operation. It sets various attributes such as + * targetlist, quals, grouping columns, estimated number of groups, distribution information, costs, and more. + * The constructed node represents the grouping operation plan for execution. + * date: 2023/8/19 + * contact tel: 18720816902 + */ Group* make_group(PlannerInfo* root, List* tlist, List* qual, int numGroupCols, AttrNumber* grpColIdx, Oid* grpOperators, double numGroups, Plan* lefttree) { @@ -8226,6 +8953,18 @@ static Plan* parallel_limit_sort( return plan; } +/* + * function name: create_offset_count + * description: Creates a new Node with an offset/count value. + * arguments: + * - offsetCount: Node representing an offset/count value (optional). + * - value: The value to assign to the offset/count node. + * return value: A pointer to the newly created Node. + * note: This function creates a new Node with an offset/count value, typically used in window function frames. + * It checks the type of the input offsetCount and constructs a new Node accordingly. + * date: 2023/8/19 + * contact tel: 18720816902 + */ static Node* create_offset_count(Node* offsetCount, Datum value) { Node* node = NULL; @@ -8635,6 +9374,19 @@ BaseResult* make_result(PlannerInfo* root, List* tlist, Node* resconstantqual, P return node; } +/* + * function name: FindForeignScan + * description: Searches for a ForeignScan node within the given Plan tree. + * arguments: + * - plan: The root of the Plan tree to search within. + * return value: A pointer to the found ForeignScan node, or NULL if not found. + * note: This function recursively searches through the given Plan tree and its subplans for a ForeignScan node. + * If a ForeignScan node is found, it checks whether the scan relates to certain types of foreign tables. + * If yes, it returns NULL to indicate that further optimization should not be applied on this node. + * Otherwise, it returns the pointer to the found ForeignScan node, allowing further optimization. + * date: 2023/8/19 + * contact tel: 18720816902 + */ static Plan* FindForeignScan(Plan* plan) { Plan* result = NULL; @@ -8717,6 +9469,18 @@ static Plan* FindForeignScan(Plan* plan) return result; } +/* + * function name: getDistSessionKey + * description: Retrieves the distributed session key from the given list of FDW private data. + * arguments: + * - fdw_private: List of FDW private data containing information for a foreign table scan. + * return value: The distributed session key value retrieved from the FDW private data. + * note: This function iterates through the given FDW private data list and extracts the distributed session key. + * The session key is usually stored as a "DefElem" with the name "session_key" within the list. + * It returns the retrieved distributed session key value, which can be used for further processing. + * date: 2023/8/19 + * contact tel: 18720816902 + */ #ifdef STREAMPLAN uint32 getDistSessionKey(List* fdw_private) { @@ -8745,6 +9509,21 @@ uint32 getDistSessionKey(List* fdw_private) } #endif +/* + * function name: PlanForeignModify + * description: Constructs private plan data for each foreign table result relation in a ModifyTable node. + * arguments: + * - root: The planner's main data structure, containing various planning information. + * - node: The ModifyTable node representing the modify operation (INSERT/UPDATE/DELETE). + * - resultRelations: List of indexes representing result relations to be modified. + * return value: None (void function). + * note: This function iterates through the list of result relations in a ModifyTable node that correspond to + * foreign tables. It retrieves the FdwRoutine for each relation and invokes the PlanForeignModify function + * provided by the FDW. The private plan data returned by the FDW is accumulated into a list and assigned to + * the fdwPrivLists field of the ModifyTable node for later use during execution. + * date: 2023/8/19 + * contact tel: 18720816902 + */ static void PlanForeignModify(PlannerInfo* root, ModifyTable* node, List* resultRelations) { List* fdw_private_list = NIL; @@ -9710,6 +10489,19 @@ RowToVec* make_rowtovec(Plan* lefttree) return node; } +/* + * function name: make_vectorow + * description: Creates a VecToRow plan node to convert vectorized output to row format. + * arguments: + * - lefttree: The input plan subtree that produces vectorized output. + * return value: A pointer to the constructed VecToRow plan node. + * note: This function constructs a VecToRow plan node, which is used to convert vectorized output + * into row format. It inherits various attributes and costs from the input plan and sets up + * the necessary information for the VecToRow node. The VecToRow node is typically used in vectorized + * execution plans. + * date: 2023/8/19 + * contact tel: 18720816902 + */ VecToRow* make_vectorow(Plan* lefttree) { VecToRow* node = makeNode(VecToRow); @@ -9872,6 +10664,24 @@ Plan* make_stream_plan( return plan; } +/* + * function name: make_redistribute_for_agg + * description: Creates a redistribution plan node for aggregation operations. + * arguments: + * - root: The planner's main data structure, containing various planning information. + * - lefttree: The input plan subtree for aggregation. + * - redistribute_keys: List of keys used for redistribution. + * - multiple: Cost multiple factor for the plan. + * - distribution: Distribution information for the plan (NULL if needs to be determined). + * - is_local_redistribute: Flag indicating if local redistribution is preferred. + * return value: A pointer to the constructed redistribution plan node. + * note: This function constructs a Stream plan node with the STREAM_REDISTRIBUTE type, typically used for + * redistributing data for aggregation operations. It sets various attributes including redistribution keys, + * distribution, targetlist, costs, parallelism, and more. The constructed node represents a redistribution + * operation in the execution plan. + * date: 2023/8/19 + * contact tel: 18720816902 + */ Plan* make_redistribute_for_agg(PlannerInfo* root, Plan* lefttree, List* redistribute_keys, double multiple, Distribution* distribution, bool is_local_redistribute) { diff --git a/src/gausskernel/optimizer/rewrite/rewriteManip.cpp b/src/gausskernel/optimizer/rewrite/rewriteManip.cpp index ec4ffd181..5e48b2733 100644 --- a/src/gausskernel/optimizer/rewrite/rewriteManip.cpp +++ b/src/gausskernel/optimizer/rewrite/rewriteManip.cpp @@ -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)