From c23e3e6beb273ae8c0f8e616edb7ed1acb0271c4 Mon Sep 17 00:00:00 2001 From: David Rowley Date: Wed, 13 Jul 2022 15:03:47 +1200 Subject: [PATCH] Use list_copy_head() instead of list_truncate(list_copy(...), ...) Truncating off the end of a freshly copied List is not a very efficient way of copying the first N elements of a List. In many of the cases that are updated here, the pattern was only being used to remove the final element of a List. That's about the best case for it, but there were many instances where the truncate trimming the List down much further. 4cc832f94 added list_copy_head(), so let's use it in cases where it's useful. Author: David Rowley Discussion: https://postgr.es/m/1986787.1657666922%40sss.pgh.pa.us --- src/backend/catalog/objectaddress.c | 8 ++++---- src/backend/commands/dropcmds.c | 15 +++++++-------- src/backend/commands/sequence.c | 2 +- src/backend/optimizer/path/allpaths.c | 9 ++++----- src/backend/optimizer/path/indxpath.c | 14 ++++++-------- src/backend/optimizer/path/pathkeys.c | 2 +- src/backend/optimizer/plan/createplan.c | 5 ++--- 7 files changed, 25 insertions(+), 30 deletions(-) diff --git a/src/backend/catalog/objectaddress.c b/src/backend/catalog/objectaddress.c index 2d21db46901..6080ff8f5f7 100644 --- a/src/backend/catalog/objectaddress.c +++ b/src/backend/catalog/objectaddress.c @@ -1453,7 +1453,7 @@ get_object_address_relobject(ObjectType objtype, List *object, errmsg("must specify relation and object name"))); /* Extract relation name and open relation. */ - relname = list_truncate(list_copy(object), nnames - 1); + relname = list_copy_head(object, nnames - 1); relation = table_openrv_extended(makeRangeVarFromNameList(relname), AccessShareLock, missing_ok); @@ -1528,7 +1528,7 @@ get_object_address_attribute(ObjectType objtype, List *object, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("column name must be qualified"))); attname = strVal(llast(object)); - relname = list_truncate(list_copy(object), list_length(object) - 1); + relname = list_copy_head(object, list_length(object) - 1); /* XXX no missing_ok support here */ relation = relation_openrv(makeRangeVarFromNameList(relname), lockmode); reloid = RelationGetRelid(relation); @@ -1581,7 +1581,7 @@ get_object_address_attrdef(ObjectType objtype, List *object, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("column name must be qualified"))); attname = strVal(llast(object)); - relname = list_truncate(list_copy(object), list_length(object) - 1); + relname = list_copy_head(object, list_length(object) - 1); /* XXX no missing_ok support here */ relation = relation_openrv(makeRangeVarFromNameList(relname), lockmode); reloid = RelationGetRelid(relation); @@ -1715,7 +1715,7 @@ get_object_address_opf_member(ObjectType objtype, * address. The rest can be used directly by get_object_address_opcf(). */ membernum = atoi(strVal(llast(linitial(object)))); - copy = list_truncate(list_copy(linitial(object)), list_length(linitial(object)) - 1); + copy = list_copy_head(linitial(object), list_length(linitial(object)) - 1); /* no missing_ok support here */ famaddr = get_object_address_opcf(OBJECT_OPFAMILY, copy, false); diff --git a/src/backend/commands/dropcmds.c b/src/backend/commands/dropcmds.c index c9b5732448e..26157eb4e3f 100644 --- a/src/backend/commands/dropcmds.c +++ b/src/backend/commands/dropcmds.c @@ -145,8 +145,7 @@ owningrel_does_not_exist_skipping(List *object, const char **msg, char **name) List *parent_object; RangeVar *parent_rel; - parent_object = list_truncate(list_copy(object), - list_length(object) - 1); + parent_object = list_copy_head(object, list_length(object) - 1); if (schema_does_not_exist_skipping(parent_object, msg, name)) return true; @@ -419,8 +418,8 @@ does_not_exist_skipping(ObjectType objtype, Node *object) { msg = gettext_noop("trigger \"%s\" for relation \"%s\" does not exist, skipping"); name = strVal(llast(castNode(List, object))); - args = NameListToString(list_truncate(list_copy(castNode(List, object)), - list_length(castNode(List, object)) - 1)); + args = NameListToString(list_copy_head(castNode(List, object), + list_length(castNode(List, object)) - 1)); } break; case OBJECT_POLICY: @@ -428,8 +427,8 @@ does_not_exist_skipping(ObjectType objtype, Node *object) { msg = gettext_noop("policy \"%s\" for relation \"%s\" does not exist, skipping"); name = strVal(llast(castNode(List, object))); - args = NameListToString(list_truncate(list_copy(castNode(List, object)), - list_length(castNode(List, object)) - 1)); + args = NameListToString(list_copy_head(castNode(List, object), + list_length(castNode(List, object)) - 1)); } break; case OBJECT_EVENT_TRIGGER: @@ -441,8 +440,8 @@ does_not_exist_skipping(ObjectType objtype, Node *object) { msg = gettext_noop("rule \"%s\" for relation \"%s\" does not exist, skipping"); name = strVal(llast(castNode(List, object))); - args = NameListToString(list_truncate(list_copy(castNode(List, object)), - list_length(castNode(List, object)) - 1)); + args = NameListToString(list_copy_head(castNode(List, object), + list_length(castNode(List, object)) - 1)); } break; case OBJECT_FDW: diff --git a/src/backend/commands/sequence.c b/src/backend/commands/sequence.c index 48d9d43dac6..b0b211891c3 100644 --- a/src/backend/commands/sequence.c +++ b/src/backend/commands/sequence.c @@ -1620,7 +1620,7 @@ process_owned_by(Relation seqrel, List *owned_by, bool for_identity) RangeVar *rel; /* Separate relname and attr name */ - relname = list_truncate(list_copy(owned_by), nnames - 1); + relname = list_copy_head(owned_by, nnames - 1); attrname = strVal(llast(owned_by)); /* Open and lock rel to ensure it won't go away meanwhile */ diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c index e9342097e52..358bb2aed6f 100644 --- a/src/backend/optimizer/path/allpaths.c +++ b/src/backend/optimizer/path/allpaths.c @@ -2053,9 +2053,8 @@ accumulate_append_subpath(Path *path, List **subpaths, List **special_subpaths) *subpaths = list_concat(*subpaths, list_copy_tail(apath->subpaths, apath->first_partial_path)); - new_special_subpaths = - list_truncate(list_copy(apath->subpaths), - apath->first_partial_path); + new_special_subpaths = list_copy_head(apath->subpaths, + apath->first_partial_path); *special_subpaths = list_concat(*special_subpaths, new_special_subpaths); return; @@ -3086,8 +3085,8 @@ get_useful_pathkeys_for_relation(PlannerInfo *root, RelOptInfo *rel, root->query_pathkeys); else if (npathkeys > 0) useful_pathkeys_list = lappend(useful_pathkeys_list, - list_truncate(list_copy(root->query_pathkeys), - npathkeys)); + list_copy_head(root->query_pathkeys, + npathkeys)); } return useful_pathkeys_list; diff --git a/src/backend/optimizer/path/indxpath.c b/src/backend/optimizer/path/indxpath.c index 0ef70ad7f11..7d176e7b00a 100644 --- a/src/backend/optimizer/path/indxpath.c +++ b/src/backend/optimizer/path/indxpath.c @@ -3026,14 +3026,12 @@ expand_indexqual_rowcompare(PlannerInfo *root, rc->rctype = (RowCompareType) op_strategy; rc->opnos = new_ops; - rc->opfamilies = list_truncate(list_copy(clause->opfamilies), - matching_cols); - rc->inputcollids = list_truncate(list_copy(clause->inputcollids), - matching_cols); - rc->largs = list_truncate(copyObject(var_args), - matching_cols); - rc->rargs = list_truncate(copyObject(non_var_args), - matching_cols); + rc->opfamilies = list_copy_head(clause->opfamilies, + matching_cols); + rc->inputcollids = list_copy_head(clause->inputcollids, + matching_cols); + rc->largs = list_copy_head(var_args, matching_cols); + rc->rargs = list_copy_head(non_var_args, matching_cols); iclause->indexquals = list_make1(make_simple_restrictinfo(root, (Expr *) rc)); } diff --git a/src/backend/optimizer/path/pathkeys.c b/src/backend/optimizer/path/pathkeys.c index 985b5d8de9b..b5d6c977eef 100644 --- a/src/backend/optimizer/path/pathkeys.c +++ b/src/backend/optimizer/path/pathkeys.c @@ -2464,7 +2464,7 @@ truncate_useless_pathkeys(PlannerInfo *root, else if (nuseful == list_length(pathkeys)) return pathkeys; else - return list_truncate(list_copy(pathkeys), nuseful); + return list_copy_head(pathkeys, nuseful); } /* diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c index 76606faa3e4..e37f2933eb8 100644 --- a/src/backend/optimizer/plan/createplan.c +++ b/src/backend/optimizer/plan/createplan.c @@ -1397,8 +1397,7 @@ create_append_plan(PlannerInfo *root, AppendPath *best_path, int flags) */ if (tlist_was_changed && (flags & (CP_EXACT_TLIST | CP_SMALL_TLIST))) { - tlist = list_truncate(list_copy(plan->plan.targetlist), - orig_tlist_length); + tlist = list_copy_head(plan->plan.targetlist, orig_tlist_length); return inject_projection_plan((Plan *) plan, tlist, plan->plan.parallel_safe); } @@ -1557,7 +1556,7 @@ create_merge_append_plan(PlannerInfo *root, MergeAppendPath *best_path, */ if (tlist_was_changed && (flags & (CP_EXACT_TLIST | CP_SMALL_TLIST))) { - tlist = list_truncate(list_copy(plan->targetlist), orig_tlist_length); + tlist = list_copy_head(plan->targetlist, orig_tlist_length); return inject_projection_plan(plan, tlist, plan->parallel_safe); } else