From 4f7dacc5b82af19788599671abe4ac633fd7ea4c Mon Sep 17 00:00:00 2001 From: Michael Paquier Date: Thu, 11 Dec 2025 14:29:12 +0900 Subject: [PATCH] Use palloc_object() and palloc_array(), the last change This is the last batch of changes that have been suggested by the author, this part covering the non-trivial changes. Some of the changes suggested have been discarded as they seem to lead to more instructions generated, leaving the parts that can be qualified as in-place replacements. Similar work has been done in 1b105f9472bd, 0c3c5c3b06a3 and 31d3847a37be. Author: David Geier Discussion: https://postgr.es/m/ad0748d4-3080-436e-b0bc-ac8f86a3466a@gmail.com --- contrib/pg_buffercache/pg_buffercache_pages.c | 8 +++--- contrib/pg_trgm/trgm_op.c | 14 +++++----- contrib/postgres_fdw/postgres_fdw.c | 20 ++++++------- src/backend/executor/execPartition.c | 28 ++++++++----------- src/backend/partitioning/partprune.c | 23 ++++++++------- src/backend/statistics/mvdistinct.c | 14 +++++----- src/backend/storage/buffer/bufmgr.c | 6 ++-- 7 files changed, 53 insertions(+), 60 deletions(-) diff --git a/contrib/pg_buffercache/pg_buffercache_pages.c b/contrib/pg_buffercache/pg_buffercache_pages.c index e18fed22046..0c58e4b265c 100644 --- a/contrib/pg_buffercache/pg_buffercache_pages.c +++ b/contrib/pg_buffercache/pg_buffercache_pages.c @@ -134,7 +134,7 @@ pg_buffercache_pages(PG_FUNCTION_ARGS) oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx); /* Create a user function context for cross-call persistence */ - fctx = (BufferCachePagesContext *) palloc(sizeof(BufferCachePagesContext)); + fctx = palloc_object(BufferCachePagesContext); /* * To smoothly support upgrades from version 1.0 of this extension @@ -382,8 +382,8 @@ pg_buffercache_os_pages_internal(FunctionCallInfo fcinfo, bool include_numa) os_page_count = (endptr - startptr) / os_page_size; /* Used to determine the NUMA node for all OS pages at once */ - os_page_ptrs = palloc0(sizeof(void *) * os_page_count); - os_page_status = palloc(sizeof(int) * os_page_count); + os_page_ptrs = palloc0_array(void *, os_page_count); + os_page_status = palloc_array(int, os_page_count); /* * Fill pointers for all the memory pages. This loop stores and @@ -425,7 +425,7 @@ pg_buffercache_os_pages_internal(FunctionCallInfo fcinfo, bool include_numa) oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx); /* Create a user function context for cross-call persistence */ - fctx = (BufferCacheOsPagesContext *) palloc(sizeof(BufferCacheOsPagesContext)); + fctx = palloc_object(BufferCacheOsPagesContext); if (get_call_result_type(fcinfo, NULL, &expected_tupledesc) != TYPEFUNC_COMPOSITE) elog(ERROR, "return type must be a row type"); diff --git a/contrib/pg_trgm/trgm_op.c b/contrib/pg_trgm/trgm_op.c index 29b39ec8a4c..81182a15e07 100644 --- a/contrib/pg_trgm/trgm_op.c +++ b/contrib/pg_trgm/trgm_op.c @@ -452,7 +452,7 @@ make_positional_trgm(trgm *trg1, int len1, trgm *trg2, int len2) int i, len = len1 + len2; - result = (pos_trgm *) palloc(sizeof(pos_trgm) * len); + result = palloc_array(pos_trgm, len); for (i = 0; i < len1; i++) { @@ -535,7 +535,7 @@ iterate_word_similarity(int *trg2indexes, lower = (flags & WORD_SIMILARITY_STRICT) ? 0 : -1; /* Memorise last position of each trigram */ - lastpos = (int *) palloc(sizeof(int) * len); + lastpos = palloc_array(int, len); memset(lastpos, -1, sizeof(int) * len); for (i = 0; i < len2; i++) @@ -711,8 +711,8 @@ calc_word_similarity(char *str1, int slen1, char *str2, int slen2, * Merge positional trigrams array: enumerate each trigram and find its * presence in required word. */ - trg2indexes = (int *) palloc(sizeof(int) * len2); - found = (bool *) palloc0(sizeof(bool) * len); + trg2indexes = palloc_array(int, len2); + found = palloc0_array(bool, len); ulen1 = 0; j = 0; @@ -938,7 +938,7 @@ generate_wildcard_trgm(const char *str, int slen) tptr = GETARR(trg); /* Allocate a buffer for blank-padded, but not yet case-folded, words */ - buf = palloc(sizeof(char) * (slen + 4)); + buf = palloc_array(char, slen + 4); /* * Extract trigrams from each substring extracted by get_wildcard_part. @@ -1008,7 +1008,7 @@ show_trgm(PG_FUNCTION_ARGS) int i; trg = generate_trgm(VARDATA_ANY(in), VARSIZE_ANY_EXHDR(in)); - d = (Datum *) palloc(sizeof(Datum) * (1 + ARRNELEM(trg))); + d = palloc_array(Datum, 1 + ARRNELEM(trg)); for (i = 0, ptr = GETARR(trg); i < ARRNELEM(trg); i++, ptr++) { @@ -1136,7 +1136,7 @@ trgm_presence_map(TRGM *query, TRGM *key) lenk = ARRNELEM(key), i; - result = (bool *) palloc0(lenq * sizeof(bool)); + result = palloc0_array(bool, lenq); /* for each query trigram, do a binary search in the key array */ for (i = 0; i < lenq; i++) diff --git a/contrib/postgres_fdw/postgres_fdw.c b/contrib/postgres_fdw/postgres_fdw.c index 06b52c65300..5e178c21b39 100644 --- a/contrib/postgres_fdw/postgres_fdw.c +++ b/contrib/postgres_fdw/postgres_fdw.c @@ -633,7 +633,7 @@ postgresGetForeignRelSize(PlannerInfo *root, * We use PgFdwRelationInfo to pass various information to subsequent * functions. */ - fpinfo = (PgFdwRelationInfo *) palloc0(sizeof(PgFdwRelationInfo)); + fpinfo = palloc0_object(PgFdwRelationInfo); baserel->fdw_private = fpinfo; /* Base foreign tables need to be pushed down always. */ @@ -1517,7 +1517,7 @@ postgresBeginForeignScan(ForeignScanState *node, int eflags) /* * We'll save private state in node->fdw_state. */ - fsstate = (PgFdwScanState *) palloc0(sizeof(PgFdwScanState)); + fsstate = palloc0_object(PgFdwScanState); node->fdw_state = fsstate; /* @@ -2663,7 +2663,7 @@ postgresBeginDirectModify(ForeignScanState *node, int eflags) /* * We'll save private state in node->fdw_state. */ - dmstate = (PgFdwDirectModifyState *) palloc0(sizeof(PgFdwDirectModifyState)); + dmstate = palloc0_object(PgFdwDirectModifyState); node->fdw_state = dmstate; /* @@ -3977,7 +3977,7 @@ create_foreign_modify(EState *estate, ListCell *lc; /* Begin constructing PgFdwModifyState. */ - fmstate = (PgFdwModifyState *) palloc0(sizeof(PgFdwModifyState)); + fmstate = palloc0_object(PgFdwModifyState); fmstate->rel = rel; /* Identify which user to do the remote access as. */ @@ -4014,7 +4014,7 @@ create_foreign_modify(EState *estate, /* Prepare for output conversion of parameters used in prepared stmt. */ n_params = list_length(fmstate->target_attrs) + 1; - fmstate->p_flinfo = (FmgrInfo *) palloc0(sizeof(FmgrInfo) * n_params); + fmstate->p_flinfo = palloc0_array(FmgrInfo, n_params); fmstate->p_nums = 0; if (operation == CMD_UPDATE || operation == CMD_DELETE) @@ -4814,7 +4814,7 @@ prepare_query_params(PlanState *node, Assert(numParams > 0); /* Prepare for output conversion of parameters used in remote query. */ - *param_flinfo = (FmgrInfo *) palloc0(sizeof(FmgrInfo) * numParams); + *param_flinfo = palloc0_array(FmgrInfo, numParams); i = 0; foreach(lc, fdw_exprs) @@ -6297,7 +6297,7 @@ postgresGetForeignJoinPaths(PlannerInfo *root, * if found safe. Once we know that this join can be pushed down, we fill * the entry. */ - fpinfo = (PgFdwRelationInfo *) palloc0(sizeof(PgFdwRelationInfo)); + fpinfo = palloc0_object(PgFdwRelationInfo); fpinfo->pushdown_safe = false; joinrel->fdw_private = fpinfo; /* attrs_used is only for base relations. */ @@ -6666,7 +6666,7 @@ postgresGetForeignUpperPaths(PlannerInfo *root, UpperRelationKind stage, output_rel->fdw_private) return; - fpinfo = (PgFdwRelationInfo *) palloc0(sizeof(PgFdwRelationInfo)); + fpinfo = palloc0_object(PgFdwRelationInfo); fpinfo->pushdown_safe = false; fpinfo->stage = stage; output_rel->fdw_private = fpinfo; @@ -6891,7 +6891,7 @@ add_foreign_ordered_paths(PlannerInfo *root, RelOptInfo *input_rel, fpinfo->pushdown_safe = true; /* Construct PgFdwPathExtraData */ - fpextra = (PgFdwPathExtraData *) palloc0(sizeof(PgFdwPathExtraData)); + fpextra = palloc0_object(PgFdwPathExtraData); fpextra->target = root->upper_targets[UPPERREL_ORDERED]; fpextra->has_final_sort = true; @@ -7125,7 +7125,7 @@ add_foreign_final_paths(PlannerInfo *root, RelOptInfo *input_rel, fpinfo->pushdown_safe = true; /* Construct PgFdwPathExtraData */ - fpextra = (PgFdwPathExtraData *) palloc0(sizeof(PgFdwPathExtraData)); + fpextra = palloc0_object(PgFdwPathExtraData); fpextra->target = root->upper_targets[UPPERREL_FINAL]; fpextra->has_final_sort = has_final_sort; fpextra->has_limit = extra->limit_needed; diff --git a/src/backend/executor/execPartition.c b/src/backend/executor/execPartition.c index b3960bb7151..e30db12113b 100644 --- a/src/backend/executor/execPartition.c +++ b/src/backend/executor/execPartition.c @@ -227,7 +227,7 @@ ExecSetupPartitionTupleRouting(EState *estate, Relation rel) * The reason for this is that a common case is for INSERT to insert a * single tuple into a partitioned table and this must be fast. */ - proute = (PartitionTupleRouting *) palloc0(sizeof(PartitionTupleRouting)); + proute = palloc0_object(PartitionTupleRouting); proute->partition_root = rel; proute->memcxt = CurrentMemoryContext; /* Rest of members initialized by zeroing */ @@ -1198,10 +1198,8 @@ ExecInitRoutingInfo(ModifyTableState *mtstate, if (proute->max_partitions == 0) { proute->max_partitions = 8; - proute->partitions = (ResultRelInfo **) - palloc(sizeof(ResultRelInfo *) * proute->max_partitions); - proute->is_borrowed_rel = (bool *) - palloc(sizeof(bool) * proute->max_partitions); + proute->partitions = palloc_array(ResultRelInfo *, proute->max_partitions); + proute->is_borrowed_rel = palloc_array(bool, proute->max_partitions); } else { @@ -1316,10 +1314,8 @@ ExecInitPartitionDispatchInfo(EState *estate, if (proute->max_dispatch == 0) { proute->max_dispatch = 4; - proute->partition_dispatch_info = (PartitionDispatch *) - palloc(sizeof(PartitionDispatch) * proute->max_dispatch); - proute->nonleaf_partitions = (ResultRelInfo **) - palloc(sizeof(ResultRelInfo *) * proute->max_dispatch); + proute->partition_dispatch_info = palloc_array(PartitionDispatch, proute->max_dispatch); + proute->nonleaf_partitions = palloc_array(ResultRelInfo *, proute->max_dispatch); } else { @@ -2211,7 +2207,7 @@ CreatePartitionPruneState(EState *estate, PartitionPruneInfo *pruneinfo, * arrays are in partition bounds order. */ pprune->nparts = partdesc->nparts; - pprune->subplan_map = palloc(sizeof(int) * partdesc->nparts); + pprune->subplan_map = palloc_array(int, partdesc->nparts); if (partdesc->nparts == pinfo->nparts && memcmp(partdesc->oids, pinfo->relid_map, @@ -2238,8 +2234,8 @@ CreatePartitionPruneState(EState *estate, PartitionPruneInfo *pruneinfo, * attached. Cope with that by creating a map that skips any * mismatches. */ - pprune->subpart_map = palloc(sizeof(int) * partdesc->nparts); - pprune->leafpart_rti_map = palloc(sizeof(int) * partdesc->nparts); + pprune->subpart_map = palloc_array(int, partdesc->nparts); + pprune->leafpart_rti_map = palloc_array(int, partdesc->nparts); for (pp_idx = 0; pp_idx < partdesc->nparts; pp_idx++) { @@ -2390,16 +2386,14 @@ InitPartitionPruneContext(PartitionPruneContext *context, context->partsupfunc = partkey->partsupfunc; /* We'll look up type-specific support functions as needed */ - context->stepcmpfuncs = (FmgrInfo *) - palloc0(sizeof(FmgrInfo) * n_steps * partnatts); + context->stepcmpfuncs = palloc0_array(FmgrInfo, n_steps * partnatts); context->ppccontext = CurrentMemoryContext; context->planstate = planstate; context->exprcontext = econtext; /* Initialize expression state for each expression we need */ - context->exprstates = (ExprState **) - palloc0(sizeof(ExprState *) * n_steps * partnatts); + context->exprstates = palloc0_array(ExprState *, n_steps * partnatts); foreach(lc, pruning_steps) { PartitionPruneStepOp *step = (PartitionPruneStepOp *) lfirst(lc); @@ -2500,7 +2494,7 @@ InitExecPartitionPruneContexts(PartitionPruneState *prunestate, * indexes to new ones. For convenience of initialization, we use * 1-based indexes in this array and leave pruned items as 0. */ - new_subplan_indexes = (int *) palloc0(sizeof(int) * n_total_subplans); + new_subplan_indexes = palloc0_array(int, n_total_subplans); newidx = 1; i = -1; while ((i = bms_next_member(initially_valid_subplans, i)) >= 0) diff --git a/src/backend/partitioning/partprune.c b/src/backend/partitioning/partprune.c index 6fff4034c24..0227a2c9281 100644 --- a/src/backend/partitioning/partprune.c +++ b/src/backend/partitioning/partprune.c @@ -246,7 +246,7 @@ make_partition_pruneinfo(PlannerInfo *root, RelOptInfo *parentrel, * that zero can represent an un-filled array entry. */ allpartrelids = NIL; - relid_subplan_map = palloc0(sizeof(int) * root->simple_rel_array_size); + relid_subplan_map = palloc0_array(int, root->simple_rel_array_size); i = 1; foreach(lc, subpaths) @@ -465,7 +465,7 @@ make_partitionedrel_pruneinfo(PlannerInfo *root, RelOptInfo *parentrel, * In this phase we discover whether runtime pruning is needed at all; if * not, we can avoid doing further work. */ - relid_subpart_map = palloc0(sizeof(int) * root->simple_rel_array_size); + relid_subpart_map = palloc0_array(int, root->simple_rel_array_size); i = 1; rti = -1; @@ -818,9 +818,8 @@ prune_append_rel_partitions(RelOptInfo *rel) context.boundinfo = rel->boundinfo; context.partcollation = rel->part_scheme->partcollation; context.partsupfunc = rel->part_scheme->partsupfunc; - context.stepcmpfuncs = (FmgrInfo *) palloc0(sizeof(FmgrInfo) * - context.partnatts * - list_length(pruning_steps)); + context.stepcmpfuncs = palloc0_array(FmgrInfo, + context.partnatts * list_length(pruning_steps)); context.ppccontext = CurrentMemoryContext; /* These are not valid when being called from the planner */ @@ -1890,7 +1889,7 @@ match_clause_to_partition_key(GeneratePruningStepsContext *context, return PARTCLAUSE_MATCH_STEPS; } - partclause = (PartClauseInfo *) palloc(sizeof(PartClauseInfo)); + partclause = palloc_object(PartClauseInfo); partclause->keyno = partkeyidx; /* Do pruning with the Boolean equality operator. */ partclause->opno = BooleanEqualOperator; @@ -2147,7 +2146,7 @@ match_clause_to_partition_key(GeneratePruningStepsContext *context, /* * Build the clause, passing the negator if applicable. */ - partclause = (PartClauseInfo *) palloc(sizeof(PartClauseInfo)); + partclause = palloc_object(PartClauseInfo); partclause->keyno = partkeyidx; if (is_opne_listp) { @@ -2693,7 +2692,7 @@ get_matching_hash_bounds(PartitionPruneContext *context, StrategyNumber opstrategy, const Datum *values, int nvalues, FmgrInfo *partsupfunc, Bitmapset *nullkeys) { - PruneStepResult *result = (PruneStepResult *) palloc0(sizeof(PruneStepResult)); + PruneStepResult *result = palloc0_object(PruneStepResult); PartitionBoundInfo boundinfo = context->boundinfo; int *partindices = boundinfo->indexes; int partnatts = context->partnatts; @@ -2770,7 +2769,7 @@ get_matching_list_bounds(PartitionPruneContext *context, StrategyNumber opstrategy, Datum value, int nvalues, FmgrInfo *partsupfunc, Bitmapset *nullkeys) { - PruneStepResult *result = (PruneStepResult *) palloc0(sizeof(PruneStepResult)); + PruneStepResult *result = palloc0_object(PruneStepResult); PartitionBoundInfo boundinfo = context->boundinfo; int off, minoff, @@ -2981,7 +2980,7 @@ get_matching_range_bounds(PartitionPruneContext *context, StrategyNumber opstrategy, const Datum *values, int nvalues, FmgrInfo *partsupfunc, Bitmapset *nullkeys) { - PruneStepResult *result = (PruneStepResult *) palloc0(sizeof(PruneStepResult)); + PruneStepResult *result = palloc0_object(PruneStepResult); PartitionBoundInfo boundinfo = context->boundinfo; Oid *partcollation = context->partcollation; int partnatts = context->partnatts; @@ -3504,7 +3503,7 @@ perform_pruning_base_step(PartitionPruneContext *context, { PruneStepResult *result; - result = (PruneStepResult *) palloc(sizeof(PruneStepResult)); + result = palloc_object(PruneStepResult); result->bound_offsets = NULL; result->scan_default = false; result->scan_null = false; @@ -3593,7 +3592,7 @@ perform_pruning_combine_step(PartitionPruneContext *context, PartitionPruneStepCombine *cstep, PruneStepResult **step_results) { - PruneStepResult *result = (PruneStepResult *) palloc0(sizeof(PruneStepResult)); + PruneStepResult *result = palloc0_object(PruneStepResult); bool firststep; ListCell *lc1; diff --git a/src/backend/statistics/mvdistinct.c b/src/backend/statistics/mvdistinct.c index fe452f53ae4..58046d2bd62 100644 --- a/src/backend/statistics/mvdistinct.c +++ b/src/backend/statistics/mvdistinct.c @@ -110,7 +110,7 @@ statext_ndistinct_build(double totalrows, StatsBuildData *data) MVNDistinctItem *item = &result->items[itemcnt]; int j; - item->attributes = palloc(sizeof(AttrNumber) * k); + item->attributes = palloc_array(AttrNumber, k); item->nattributes = k; /* translate the indexes to attnums */ @@ -359,9 +359,9 @@ ndistinct_for_combination(double totalrows, StatsBuildData *data, * using the specified column combination as dimensions. We could try to * sort in place, but it'd probably be more complex and bug-prone. */ - items = (SortItem *) palloc(numrows * sizeof(SortItem)); - values = (Datum *) palloc0(sizeof(Datum) * numrows * k); - isnull = (bool *) palloc0(sizeof(bool) * numrows * k); + items = palloc_array(SortItem, numrows); + values = palloc0_array(Datum, numrows * k); + isnull = palloc0_array(bool, numrows * k); for (i = 0; i < numrows; i++) { @@ -508,12 +508,12 @@ generator_init(int n, int k) Assert((n >= k) && (k > 0)); /* allocate the generator state as a single chunk of memory */ - state = (CombinationGenerator *) palloc(sizeof(CombinationGenerator)); + state = palloc_object(CombinationGenerator); state->ncombinations = n_choose_k(n, k); /* pre-allocate space for all combinations */ - state->combinations = (int *) palloc(sizeof(int) * k * state->ncombinations); + state->combinations = palloc_array(int, k * state->ncombinations); state->current = 0; state->k = k; @@ -606,7 +606,7 @@ generate_combinations_recurse(CombinationGenerator *state, static void generate_combinations(CombinationGenerator *state) { - int *current = (int *) palloc0(sizeof(int) * state->k); + int *current = palloc0_array(int, state->k); generate_combinations_recurse(state, 0, 0, current); diff --git a/src/backend/storage/buffer/bufmgr.c b/src/backend/storage/buffer/bufmgr.c index ce52d6ca81f..e78912cd141 100644 --- a/src/backend/storage/buffer/bufmgr.c +++ b/src/backend/storage/buffer/bufmgr.c @@ -4676,7 +4676,7 @@ DropRelationsAllBuffers(SMgrRelation *smgr_reln, int nlocators) if (nlocators == 0) return; - rels = palloc(sizeof(SMgrRelation) * nlocators); /* non-local relations */ + rels = palloc_array(SMgrRelation, nlocators); /* non-local relations */ /* If it's a local relation, it's localbuf.c's problem. */ for (i = 0; i < nlocators; i++) @@ -4758,7 +4758,7 @@ DropRelationsAllBuffers(SMgrRelation *smgr_reln, int nlocators) } pfree(block); - locators = palloc(sizeof(RelFileLocator) * n); /* non-local relations */ + locators = palloc_array(RelFileLocator, n); /* non-local relations */ for (i = 0; i < n; i++) locators[i] = rels[i]->smgr_rlocator.locator; @@ -5037,7 +5037,7 @@ FlushRelationsAllBuffers(SMgrRelation *smgrs, int nrels) return; /* fill-in array for qsort */ - srels = palloc(sizeof(SMgrSortArray) * nrels); + srels = palloc_array(SMgrSortArray, nrels); for (i = 0; i < nrels; i++) { -- 2.39.5