diff options
Diffstat (limited to 'src/backend/optimizer')
-rw-r--r-- | src/backend/optimizer/path/allpaths.c | 13 | ||||
-rw-r--r-- | src/backend/optimizer/path/costsize.c | 3 | ||||
-rw-r--r-- | src/backend/optimizer/path/indxpath.c | 18 | ||||
-rw-r--r-- | src/backend/optimizer/plan/createplan.c | 4 | ||||
-rw-r--r-- | src/backend/optimizer/plan/initsplan.c | 1 | ||||
-rw-r--r-- | src/backend/optimizer/plan/planner.c | 13 | ||||
-rw-r--r-- | src/backend/optimizer/plan/setrefs.c | 2 | ||||
-rw-r--r-- | src/backend/optimizer/prep/prepjointree.c | 1 | ||||
-rw-r--r-- | src/backend/optimizer/prep/prepqual.c | 12 | ||||
-rw-r--r-- | src/backend/optimizer/util/clauses.c | 54 | ||||
-rw-r--r-- | src/backend/optimizer/util/orclauses.c | 2 | ||||
-rw-r--r-- | src/backend/optimizer/util/relnode.c | 34 | ||||
-rw-r--r-- | src/backend/optimizer/util/tlist.c | 5 |
13 files changed, 59 insertions, 103 deletions
diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c index e9ee32b7f43..db3a68a51dd 100644 --- a/src/backend/optimizer/path/allpaths.c +++ b/src/backend/optimizer/path/allpaths.c @@ -1266,7 +1266,7 @@ set_append_rel_pathlist(PlannerInfo *root, RelOptInfo *rel, if (rel->part_scheme) rel->partitioned_child_rels = list_concat(rel->partitioned_child_rels, - list_copy(childrel->partitioned_child_rels)); + childrel->partitioned_child_rels); /* * Child is live, so add it to the live_childrels list for use below. @@ -1347,9 +1347,8 @@ add_paths_to_append_rel(PlannerInfo *root, RelOptInfo *rel, component = root->simple_rel_array[relid]; Assert(component->part_scheme != NULL); Assert(list_length(component->partitioned_child_rels) >= 1); - partrels = - list_concat(partrels, - list_copy(component->partitioned_child_rels)); + partrels = list_concat(partrels, + component->partitioned_child_rels); } partitioned_rels = list_make1(partrels); @@ -2048,8 +2047,7 @@ accumulate_append_subpath(Path *path, List **subpaths, List **special_subpaths) if (!apath->path.parallel_aware || apath->first_partial_path == 0) { - /* list_copy is important here to avoid sharing list substructure */ - *subpaths = list_concat(*subpaths, list_copy(apath->subpaths)); + *subpaths = list_concat(*subpaths, apath->subpaths); return; } else if (special_subpaths != NULL) @@ -2072,8 +2070,7 @@ accumulate_append_subpath(Path *path, List **subpaths, List **special_subpaths) { MergeAppendPath *mpath = (MergeAppendPath *) path; - /* list_copy is important here to avoid sharing list substructure */ - *subpaths = list_concat(*subpaths, list_copy(mpath->subpaths)); + *subpaths = list_concat(*subpaths, mpath->subpaths); return; } diff --git a/src/backend/optimizer/path/costsize.c b/src/backend/optimizer/path/costsize.c index 3a9a994733b..bc6bc999573 100644 --- a/src/backend/optimizer/path/costsize.c +++ b/src/backend/optimizer/path/costsize.c @@ -4443,8 +4443,7 @@ get_parameterized_baserel_size(PlannerInfo *root, RelOptInfo *rel, * restriction clauses. Note that we force the clauses to be treated as * non-join clauses during selectivity estimation. */ - allclauses = list_concat(list_copy(param_clauses), - rel->baserestrictinfo); + allclauses = list_concat_copy(param_clauses, rel->baserestrictinfo); nrows = rel->tuples * clauselist_selectivity(root, allclauses, diff --git a/src/backend/optimizer/path/indxpath.c b/src/backend/optimizer/path/indxpath.c index 5f339fdfde7..37b257cd0e9 100644 --- a/src/backend/optimizer/path/indxpath.c +++ b/src/backend/optimizer/path/indxpath.c @@ -656,7 +656,7 @@ get_join_index_paths(PlannerInfo *root, RelOptInfo *rel, } } - /* Add restriction clauses (this is nondestructive to rclauseset) */ + /* Add restriction clauses */ clauseset.indexclauses[indexcol] = list_concat(clauseset.indexclauses[indexcol], rclauseset->indexclauses[indexcol]); @@ -1204,8 +1204,7 @@ build_paths_for_OR(PlannerInfo *root, RelOptInfo *rel, { /* Form all_clauses if not done already */ if (all_clauses == NIL) - all_clauses = list_concat(list_copy(clauses), - other_clauses); + all_clauses = list_concat_copy(clauses, other_clauses); if (!predicate_implied_by(index->indpred, all_clauses, false)) continue; /* can't use it at all */ @@ -1270,7 +1269,7 @@ generate_bitmap_or_paths(PlannerInfo *root, RelOptInfo *rel, * We can use both the current and other clauses as context for * build_paths_for_OR; no need to remove ORs from the lists. */ - all_clauses = list_concat(list_copy(clauses), other_clauses); + all_clauses = list_concat_copy(clauses, other_clauses); foreach(lc, clauses) { @@ -1506,8 +1505,7 @@ choose_bitmap_and(PlannerInfo *root, RelOptInfo *rel, List *paths) pathinfo = pathinfoarray[i]; paths = list_make1(pathinfo->path); costsofar = bitmap_scan_cost_est(root, rel, pathinfo->path); - qualsofar = list_concat(list_copy(pathinfo->quals), - list_copy(pathinfo->preds)); + qualsofar = list_concat_copy(pathinfo->quals, pathinfo->preds); clauseidsofar = bms_copy(pathinfo->clauseids); for (j = i + 1; j < npaths; j++) @@ -1543,10 +1541,8 @@ choose_bitmap_and(PlannerInfo *root, RelOptInfo *rel, List *paths) { /* keep new path in paths, update subsidiary variables */ costsofar = newcost; - qualsofar = list_concat(qualsofar, - list_copy(pathinfo->quals)); - qualsofar = list_concat(qualsofar, - list_copy(pathinfo->preds)); + qualsofar = list_concat(qualsofar, pathinfo->quals); + qualsofar = list_concat(qualsofar, pathinfo->preds); clauseidsofar = bms_add_members(clauseidsofar, pathinfo->clauseids); } @@ -1849,7 +1845,7 @@ find_indexpath_quals(Path *bitmapqual, List **quals, List **preds) *quals = lappend(*quals, iclause->rinfo->clause); } - *preds = list_concat(*preds, list_copy(ipath->indexinfo->indpred)); + *preds = list_concat(*preds, ipath->indexinfo->indpred); } else elog(ERROR, "unrecognized node type: %d", nodeTag(bitmapqual)); diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c index f2325694c53..0c036209f09 100644 --- a/src/backend/optimizer/plan/createplan.c +++ b/src/backend/optimizer/plan/createplan.c @@ -559,8 +559,8 @@ create_scan_plan(PlannerInfo *root, Path *best_path, int flags) * For paranoia's sake, don't modify the stored baserestrictinfo list. */ if (best_path->param_info) - scan_clauses = list_concat(list_copy(scan_clauses), - best_path->param_info->ppi_clauses); + scan_clauses = list_concat_copy(scan_clauses, + best_path->param_info->ppi_clauses); /* * Detect whether we have any pseudoconstant quals to deal with. Then, if diff --git a/src/backend/optimizer/plan/initsplan.c b/src/backend/optimizer/plan/initsplan.c index 73da0c2d8e1..274fea076cb 100644 --- a/src/backend/optimizer/plan/initsplan.c +++ b/src/backend/optimizer/plan/initsplan.c @@ -973,7 +973,6 @@ deconstruct_recurse(PlannerInfo *root, Node *jtnode, bool below_outer_join, *postponed_qual_list = lappend(*postponed_qual_list, pq); } } - /* list_concat is nondestructive of its second argument */ my_quals = list_concat(my_quals, (List *) j->quals); /* diff --git a/src/backend/optimizer/plan/planner.c b/src/backend/optimizer/plan/planner.c index 0f918dd358d..17c5f086fbf 100644 --- a/src/backend/optimizer/plan/planner.c +++ b/src/backend/optimizer/plan/planner.c @@ -3572,10 +3572,6 @@ reorder_grouping_sets(List *groupingsets, List *sortclause) } } - /* - * Safe to use list_concat (which shares cells of the second arg) - * because we know that new_elems does not share cells with anything. - */ previous = list_concat(previous, new_elems); gs->set = list_copy(previous); @@ -4287,8 +4283,8 @@ consider_groupingsets_paths(PlannerInfo *root, */ if (!rollup->hashable) return; - else - sets_data = list_concat(sets_data, list_copy(rollup->gsets_data)); + + sets_data = list_concat(sets_data, rollup->gsets_data); } foreach(lc, sets_data) { @@ -4473,7 +4469,7 @@ consider_groupingsets_paths(PlannerInfo *root, { if (bms_is_member(i, hash_items)) hash_sets = list_concat(hash_sets, - list_copy(rollup->gsets_data)); + rollup->gsets_data); else rollups = lappend(rollups, rollup); ++i; @@ -5642,8 +5638,7 @@ make_pathkeys_for_window(PlannerInfo *root, WindowClause *wc, errdetail("Window ordering columns must be of sortable datatypes."))); /* Okay, make the combined pathkeys */ - window_sortclauses = list_concat(list_copy(wc->partitionClause), - list_copy(wc->orderClause)); + window_sortclauses = list_concat_copy(wc->partitionClause, wc->orderClause); window_pathkeys = make_pathkeys_for_sortclauses(root, window_sortclauses, tlist); diff --git a/src/backend/optimizer/plan/setrefs.c b/src/backend/optimizer/plan/setrefs.c index 329ebd5f287..566ee96da8c 100644 --- a/src/backend/optimizer/plan/setrefs.c +++ b/src/backend/optimizer/plan/setrefs.c @@ -893,7 +893,7 @@ set_plan_refs(PlannerInfo *root, Plan *plan, int rtoffset) splan->resultRelIndex = list_length(root->glob->resultRelations); root->glob->resultRelations = list_concat(root->glob->resultRelations, - list_copy(splan->resultRelations)); + splan->resultRelations); /* * If the main target relation is a partitioned table, also diff --git a/src/backend/optimizer/prep/prepjointree.c b/src/backend/optimizer/prep/prepjointree.c index ccb32530ad2..d13cb582272 100644 --- a/src/backend/optimizer/prep/prepjointree.c +++ b/src/backend/optimizer/prep/prepjointree.c @@ -2659,7 +2659,6 @@ reduce_outer_joins_pass2(Node *jtnode, pass_nonnullable_rels = find_nonnullable_rels(f->quals); pass_nonnullable_rels = bms_add_members(pass_nonnullable_rels, nonnullable_rels); - /* NB: we rely on list_concat to not damage its second argument */ pass_nonnullable_vars = find_nonnullable_vars(f->quals); pass_nonnullable_vars = list_concat(pass_nonnullable_vars, nonnullable_vars); diff --git a/src/backend/optimizer/prep/prepqual.c b/src/backend/optimizer/prep/prepqual.c index e9a94976b73..ee919575c52 100644 --- a/src/backend/optimizer/prep/prepqual.c +++ b/src/backend/optimizer/prep/prepqual.c @@ -328,12 +328,6 @@ pull_ands(List *andlist) { Node *subexpr = (Node *) lfirst(arg); - /* - * Note: we can destructively concat the subexpression's arglist - * because we know the recursive invocation of pull_ands will have - * built a new arglist not shared with any other expr. Otherwise we'd - * need a list_copy here. - */ if (is_andclause(subexpr)) out_list = list_concat(out_list, pull_ands(((BoolExpr *) subexpr)->args)); @@ -360,12 +354,6 @@ pull_ors(List *orlist) { Node *subexpr = (Node *) lfirst(arg); - /* - * Note: we can destructively concat the subexpression's arglist - * because we know the recursive invocation of pull_ors will have - * built a new arglist not shared with any other expr. Otherwise we'd - * need a list_copy here. - */ if (is_orclause(subexpr)) out_list = list_concat(out_list, pull_ors(((BoolExpr *) subexpr)->args)); diff --git a/src/backend/optimizer/util/clauses.c b/src/backend/optimizer/util/clauses.c index 7ad9d9ab79e..a04b62274d2 100644 --- a/src/backend/optimizer/util/clauses.c +++ b/src/backend/optimizer/util/clauses.c @@ -1009,8 +1009,8 @@ max_parallel_hazard_walker(Node *node, max_parallel_hazard_context *context) max_parallel_hazard_test(PROPARALLEL_RESTRICTED, context)) return true; save_safe_param_ids = context->safe_param_ids; - context->safe_param_ids = list_concat(list_copy(subplan->paramIds), - context->safe_param_ids); + context->safe_param_ids = list_concat_copy(context->safe_param_ids, + subplan->paramIds); if (max_parallel_hazard_walker(subplan->testexpr, context)) return true; /* no need to restore safe_param_ids */ list_free(context->safe_param_ids); @@ -3697,18 +3697,12 @@ simplify_or_arguments(List *args, /* flatten nested ORs as per above comment */ if (is_orclause(arg)) { - List *subargs = list_copy(((BoolExpr *) arg)->args); + List *subargs = ((BoolExpr *) arg)->args; + List *oldlist = unprocessed_args; - /* overly tense code to avoid leaking unused list header */ - if (!unprocessed_args) - unprocessed_args = subargs; - else - { - List *oldhdr = unprocessed_args; - - unprocessed_args = list_concat(subargs, unprocessed_args); - pfree(oldhdr); - } + unprocessed_args = list_concat_copy(subargs, unprocessed_args); + /* perhaps-overly-tense code to avoid leaking old lists */ + list_free(oldlist); continue; } @@ -3718,14 +3712,14 @@ simplify_or_arguments(List *args, /* * It is unlikely but not impossible for simplification of a non-OR * clause to produce an OR. Recheck, but don't be too tense about it - * since it's not a mainstream case. In particular we don't worry - * about const-simplifying the input twice. + * since it's not a mainstream case. In particular we don't worry + * about const-simplifying the input twice, nor about list leakage. */ if (is_orclause(arg)) { - List *subargs = list_copy(((BoolExpr *) arg)->args); + List *subargs = ((BoolExpr *) arg)->args; - unprocessed_args = list_concat(subargs, unprocessed_args); + unprocessed_args = list_concat_copy(subargs, unprocessed_args); continue; } @@ -3799,18 +3793,12 @@ simplify_and_arguments(List *args, /* flatten nested ANDs as per above comment */ if (is_andclause(arg)) { - List *subargs = list_copy(((BoolExpr *) arg)->args); + List *subargs = ((BoolExpr *) arg)->args; + List *oldlist = unprocessed_args; - /* overly tense code to avoid leaking unused list header */ - if (!unprocessed_args) - unprocessed_args = subargs; - else - { - List *oldhdr = unprocessed_args; - - unprocessed_args = list_concat(subargs, unprocessed_args); - pfree(oldhdr); - } + unprocessed_args = list_concat_copy(subargs, unprocessed_args); + /* perhaps-overly-tense code to avoid leaking old lists */ + list_free(oldlist); continue; } @@ -3820,14 +3808,14 @@ simplify_and_arguments(List *args, /* * It is unlikely but not impossible for simplification of a non-AND * clause to produce an AND. Recheck, but don't be too tense about it - * since it's not a mainstream case. In particular we don't worry - * about const-simplifying the input twice. + * since it's not a mainstream case. In particular we don't worry + * about const-simplifying the input twice, nor about list leakage. */ if (is_andclause(arg)) { - List *subargs = list_copy(((BoolExpr *) arg)->args); + List *subargs = ((BoolExpr *) arg)->args; - unprocessed_args = list_concat(subargs, unprocessed_args); + unprocessed_args = list_concat_copy(subargs, unprocessed_args); continue; } @@ -4188,7 +4176,7 @@ add_function_defaults(List *args, HeapTuple func_tuple) defaults = list_copy_tail(defaults, ndelete); /* And form the combined argument list, not modifying the input list */ - return list_concat(list_copy(args), defaults); + return list_concat_copy(args, defaults); } /* diff --git a/src/backend/optimizer/util/orclauses.c b/src/backend/optimizer/util/orclauses.c index 18ebc51bcac..412a3964c30 100644 --- a/src/backend/optimizer/util/orclauses.c +++ b/src/backend/optimizer/util/orclauses.c @@ -236,7 +236,7 @@ extract_or_clause(RestrictInfo *or_rinfo, RelOptInfo *rel) subclause = (Node *) make_ands_explicit(subclauses); if (is_orclause(subclause)) clauselist = list_concat(clauselist, - list_copy(((BoolExpr *) subclause)->args)); + ((BoolExpr *) subclause)->args); else clauselist = lappend(clauselist, subclause); } diff --git a/src/backend/optimizer/util/relnode.c b/src/backend/optimizer/util/relnode.c index 582c5dd979b..19e5a449f75 100644 --- a/src/backend/optimizer/util/relnode.c +++ b/src/backend/optimizer/util/relnode.c @@ -1718,43 +1718,39 @@ build_joinrel_partition_info(RelOptInfo *joinrel, RelOptInfo *outer_rel, */ for (cnt = 0; cnt < partnatts; cnt++) { - List *outer_expr; - List *outer_null_expr; - List *inner_expr; - List *inner_null_expr; + /* mark these const to enforce that we copy them properly */ + const List *outer_expr = outer_rel->partexprs[cnt]; + const List *outer_null_expr = outer_rel->nullable_partexprs[cnt]; + const List *inner_expr = inner_rel->partexprs[cnt]; + const List *inner_null_expr = inner_rel->nullable_partexprs[cnt]; List *partexpr = NIL; List *nullable_partexpr = NIL; - outer_expr = list_copy(outer_rel->partexprs[cnt]); - outer_null_expr = list_copy(outer_rel->nullable_partexprs[cnt]); - inner_expr = list_copy(inner_rel->partexprs[cnt]); - inner_null_expr = list_copy(inner_rel->nullable_partexprs[cnt]); - switch (jointype) { case JOIN_INNER: - partexpr = list_concat(outer_expr, inner_expr); - nullable_partexpr = list_concat(outer_null_expr, - inner_null_expr); + partexpr = list_concat_copy(outer_expr, inner_expr); + nullable_partexpr = list_concat_copy(outer_null_expr, + inner_null_expr); break; case JOIN_SEMI: case JOIN_ANTI: - partexpr = outer_expr; - nullable_partexpr = outer_null_expr; + partexpr = list_copy(outer_expr); + nullable_partexpr = list_copy(outer_null_expr); break; case JOIN_LEFT: - partexpr = outer_expr; - nullable_partexpr = list_concat(inner_expr, - outer_null_expr); + partexpr = list_copy(outer_expr); + nullable_partexpr = list_concat_copy(inner_expr, + outer_null_expr); nullable_partexpr = list_concat(nullable_partexpr, inner_null_expr); break; case JOIN_FULL: - nullable_partexpr = list_concat(outer_expr, - inner_expr); + nullable_partexpr = list_concat_copy(outer_expr, + inner_expr); nullable_partexpr = list_concat(nullable_partexpr, outer_null_expr); nullable_partexpr = list_concat(nullable_partexpr, diff --git a/src/backend/optimizer/util/tlist.c b/src/backend/optimizer/util/tlist.c index 7ccb10e4e1b..d75796ac8b9 100644 --- a/src/backend/optimizer/util/tlist.c +++ b/src/backend/optimizer/util/tlist.c @@ -665,9 +665,8 @@ make_tlist_from_pathtarget(PathTarget *target) * copy_pathtarget * Copy a PathTarget. * - * The new PathTarget has its own List cells, but shares the underlying - * target expression trees with the old one. We duplicate the List cells - * so that items can be added to one target without damaging the other. + * The new PathTarget has its own exprs List, but shares the underlying + * target expression trees with the old one. */ PathTarget * copy_pathtarget(PathTarget *src) |