From c3a153afed84e29dac664bdc6123724a9e3a906f Mon Sep 17 00:00:00 2001 From: Tom Lane <tgl@sss.pgh.pa.us> Date: Sat, 5 Jun 2004 19:48:09 +0000 Subject: [PATCH] Tweak palloc/repalloc to allow zero bytes to be requested, as per recent proposal. Eliminate several dozen now-unnecessary hacks to avoid palloc(0). (It's likely there are more that I didn't find.) --- src/backend/access/nbtree/nbtree.c | 4 +- src/backend/commands/analyze.c | 11 ++-- src/backend/commands/copy.c | 29 +++++---- src/backend/commands/tablecmds.c | 6 +- src/backend/commands/vacuum.c | 5 +- src/backend/commands/vacuumlazy.c | 5 +- src/backend/executor/execQual.c | 4 +- src/backend/optimizer/prep/prepunion.c | 6 +- src/backend/optimizer/util/clauses.c | 4 +- src/backend/storage/freespace/freespace.c | 4 +- src/backend/storage/lmgr/deadlock.c | 7 +-- src/backend/storage/lmgr/lock.c | 5 +- src/backend/tcop/pquery.c | 5 +- src/backend/utils/adt/name.c | 6 +- src/backend/utils/mmgr/README | 22 ++++++- src/backend/utils/mmgr/mcxt.c | 4 +- src/include/utils/memutils.h | 7 ++- src/pl/plpgsql/src/pl_exec.c | 21 +++---- src/pl/plpython/plpython.c | 71 +++++++++++------------ 19 files changed, 113 insertions(+), 113 deletions(-) diff --git a/src/backend/access/nbtree/nbtree.c b/src/backend/access/nbtree/nbtree.c index 7a1d8372d73..01fe502071e 100644 --- a/src/backend/access/nbtree/nbtree.c +++ b/src/backend/access/nbtree/nbtree.c @@ -12,7 +12,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/access/nbtree/nbtree.c,v 1.117 2004/06/02 17:28:17 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/access/nbtree/nbtree.c,v 1.118 2004/06/05 19:48:07 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -693,7 +693,7 @@ btvacuumcleanup(PG_FUNCTION_ARGS) /* No point in remembering more than MaxFSMPages pages */ maxFreePages = MaxFSMPages; if ((BlockNumber) maxFreePages > num_pages) - maxFreePages = (int) num_pages + 1; /* +1 to avoid palloc(0) */ + maxFreePages = (int) num_pages; freePages = (BlockNumber *) palloc(maxFreePages * sizeof(BlockNumber)); nFreePages = 0; diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index 4efaf653ede..cf1c2e9f1d2 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/commands/analyze.c,v 1.73 2004/05/26 04:41:09 neilc Exp $ + * $PostgreSQL: pgsql/src/backend/commands/analyze.c,v 1.74 2004/06/05 19:48:07 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -226,9 +226,8 @@ analyze_rel(Oid relid, VacuumStmt *vacstmt) else { attr_cnt = onerel->rd_att->natts; - /* +1 here is just to avoid palloc(0) with zero-column table */ - vacattrstats = (VacAttrStats **) palloc((attr_cnt + 1) * - sizeof(VacAttrStats *)); + vacattrstats = (VacAttrStats **) + palloc(attr_cnt * sizeof(VacAttrStats *)); tcnt = 0; for (i = 1; i <= attr_cnt; i++) { @@ -505,8 +504,8 @@ compute_index_stats(Relation onerel, double totalrows, estate); /* Compute and save index expression values */ - exprvals = (Datum *) palloc((numrows * attr_cnt + 1) * sizeof(Datum)); - exprnulls = (bool *) palloc((numrows * attr_cnt + 1) * sizeof(bool)); + exprvals = (Datum *) palloc(numrows * attr_cnt * sizeof(Datum)); + exprnulls = (bool *) palloc(numrows * attr_cnt * sizeof(bool)); numindexrows = 0; tcnt = 0; for (rowno = 0; rowno < numrows; rowno++) diff --git a/src/backend/commands/copy.c b/src/backend/commands/copy.c index a666516fb39..13ed62b8df2 100644 --- a/src/backend/commands/copy.c +++ b/src/backend/commands/copy.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/commands/copy.c,v 1.224 2004/05/26 04:41:10 neilc Exp $ + * $PostgreSQL: pgsql/src/backend/commands/copy.c,v 1.225 2004/06/05 19:48:07 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -1158,13 +1158,11 @@ CopyTo(Relation rel, List *attnumlist, bool binary, bool oids, /* * Get info about the columns we need to process. - * - * +1's here are to avoid palloc(0) in a zero-column table. */ - out_functions = (FmgrInfo *) palloc((num_phys_attrs + 1) * sizeof(FmgrInfo)); - elements = (Oid *) palloc((num_phys_attrs + 1) * sizeof(Oid)); - isvarlena = (bool *) palloc((num_phys_attrs + 1) * sizeof(bool)); - force_quote = (bool *) palloc((num_phys_attrs + 1) * sizeof(bool)); + out_functions = (FmgrInfo *) palloc(num_phys_attrs * sizeof(FmgrInfo)); + elements = (Oid *) palloc(num_phys_attrs * sizeof(Oid)); + isvarlena = (bool *) palloc(num_phys_attrs * sizeof(bool)); + force_quote = (bool *) palloc(num_phys_attrs * sizeof(bool)); foreach(cur, attnumlist) { int attnum = lfirst_int(cur); @@ -1501,14 +1499,13 @@ CopyFrom(Relation rel, List *attnumlist, bool binary, bool oids, * relation, including the input function, the element type (to pass * to the input function), and info about defaults and constraints. * (Which input function we use depends on text/binary format choice.) - * +1's here are to avoid palloc(0) in a zero-column table. */ - in_functions = (FmgrInfo *) palloc((num_phys_attrs + 1) * sizeof(FmgrInfo)); - elements = (Oid *) palloc((num_phys_attrs + 1) * sizeof(Oid)); - defmap = (int *) palloc((num_phys_attrs + 1) * sizeof(int)); - defexprs = (ExprState **) palloc((num_phys_attrs + 1) * sizeof(ExprState *)); - constraintexprs = (ExprState **) palloc0((num_phys_attrs + 1) * sizeof(ExprState *)); - force_notnull = (bool *) palloc((num_phys_attrs + 1) * sizeof(bool)); + in_functions = (FmgrInfo *) palloc(num_phys_attrs * sizeof(FmgrInfo)); + elements = (Oid *) palloc(num_phys_attrs * sizeof(Oid)); + defmap = (int *) palloc(num_phys_attrs * sizeof(int)); + defexprs = (ExprState **) palloc(num_phys_attrs * sizeof(ExprState *)); + constraintexprs = (ExprState **) palloc0(num_phys_attrs * sizeof(ExprState *)); + force_notnull = (bool *) palloc(num_phys_attrs * sizeof(bool)); for (attnum = 1; attnum <= num_phys_attrs; attnum++) { @@ -1635,8 +1632,8 @@ CopyFrom(Relation rel, List *attnumlist, bool binary, bool oids, fmgr_info(in_func_oid, &oid_in_function); } - values = (Datum *) palloc((num_phys_attrs + 1) * sizeof(Datum)); - nulls = (char *) palloc((num_phys_attrs + 1) * sizeof(char)); + values = (Datum *) palloc(num_phys_attrs * sizeof(Datum)); + nulls = (char *) palloc(num_phys_attrs * sizeof(char)); /* Make room for a PARAM_EXEC value for domain constraint checks */ if (hasConstraints) diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index 492532363a5..66c1b95135a 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.110 2004/06/04 20:35:21 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.111 2004/06/05 19:48:07 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -727,10 +727,10 @@ MergeAttributes(List *schema, List *supers, bool istemp, * newattno[] will contain the child-table attribute numbers for * the attributes of this parent table. (They are not the same * for parents after the first one, nor if we have dropped - * columns.) +1 is to prevent error if parent has zero columns. + * columns.) */ newattno = (AttrNumber *) - palloc((tupleDesc->natts + 1) * sizeof(AttrNumber)); + palloc(tupleDesc->natts * sizeof(AttrNumber)); for (parent_attno = 1; parent_attno <= tupleDesc->natts; parent_attno++) diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index aa6491af1c0..68164a9a80c 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -13,7 +13,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/commands/vacuum.c,v 1.279 2004/05/31 19:24:05 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/commands/vacuum.c,v 1.280 2004/06/05 19:48:07 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -2883,9 +2883,8 @@ vac_update_fsm(Relation onerel, VacPageList fraged_pages, */ threshold = GetAvgFSMRequestSize(&onerel->rd_node); - /* +1 to avoid palloc(0) */ pageSpaces = (PageFreeSpaceInfo *) - palloc((nPages + 1) * sizeof(PageFreeSpaceInfo)); + palloc(nPages * sizeof(PageFreeSpaceInfo)); outPages = 0; for (i = 0; i < nPages; i++) diff --git a/src/backend/commands/vacuumlazy.c b/src/backend/commands/vacuumlazy.c index f67c1c76fee..2e4b263b1a7 100644 --- a/src/backend/commands/vacuumlazy.c +++ b/src/backend/commands/vacuumlazy.c @@ -31,7 +31,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/commands/vacuumlazy.c,v 1.41 2004/05/31 19:24:05 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/commands/vacuumlazy.c,v 1.42 2004/06/05 19:48:07 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -918,9 +918,6 @@ lazy_space_alloc(LVRelStats *vacrelstats, BlockNumber relblocks) /* No need to allocate more pages than the relation has blocks */ if (relblocks < (BlockNumber) maxpages) maxpages = (int) relblocks; - /* avoid palloc(0) */ - if (maxpages < 1) - maxpages = 1; vacrelstats->fs_is_heap = false; vacrelstats->num_free_pages = 0; diff --git a/src/backend/executor/execQual.c b/src/backend/executor/execQual.c index e53820efed0..8ada5e6faf2 100644 --- a/src/backend/executor/execQual.c +++ b/src/backend/executor/execQual.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/executor/execQual.c,v 1.162 2004/06/01 03:28:41 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/executor/execQual.c,v 1.163 2004/06/05 19:48:08 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -2129,8 +2129,6 @@ ExecEvalRow(RowExprState *rstate, /* Allocate workspace */ nargs = list_length(rstate->args); - if (nargs == 0) /* avoid palloc(0) if no fields */ - nargs = 1; values = (Datum *) palloc(nargs * sizeof(Datum)); nulls = (char *) palloc(nargs * sizeof(char)); diff --git a/src/backend/optimizer/prep/prepunion.c b/src/backend/optimizer/prep/prepunion.c index abc5af7784f..0e1b4f2aec0 100644 --- a/src/backend/optimizer/prep/prepunion.c +++ b/src/backend/optimizer/prep/prepunion.c @@ -14,7 +14,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/optimizer/prep/prepunion.c,v 1.113 2004/06/05 01:55:04 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/optimizer/prep/prepunion.c,v 1.114 2004/06/05 19:48:08 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -538,9 +538,9 @@ generate_append_tlist(List *colTypes, bool flag, * First extract typmods to use. * * If the inputs all agree on type and typmod of a particular column, use - * that typmod; else use -1. (+1 here in case of zero columns.) + * that typmod; else use -1. */ - colTypmods = (int32 *) palloc(list_length(colTypes) * sizeof(int32) + 1); + colTypmods = (int32 *) palloc(list_length(colTypes) * sizeof(int32)); foreach(planl, input_plans) { diff --git a/src/backend/optimizer/util/clauses.c b/src/backend/optimizer/util/clauses.c index bf12320626d..b22360ac2b1 100644 --- a/src/backend/optimizer/util/clauses.c +++ b/src/backend/optimizer/util/clauses.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/optimizer/util/clauses.c,v 1.173 2004/06/01 04:47:45 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/optimizer/util/clauses.c,v 1.174 2004/06/05 19:48:08 tgl Exp $ * * HISTORY * AUTHOR DATE MAJOR EVENT @@ -2016,7 +2016,7 @@ inline_function(Oid funcid, Oid result_type, List *args, * actual substitution of the inputs. So start building expression * with inputs substituted. */ - usecounts = (int *) palloc0((funcform->pronargs + 1) * sizeof(int)); + usecounts = (int *) palloc0(funcform->pronargs * sizeof(int)); newexpr = substitute_actual_parameters(newexpr, funcform->pronargs, args, usecounts); diff --git a/src/backend/storage/freespace/freespace.c b/src/backend/storage/freespace/freespace.c index 3c149c3510b..527ad8496ab 100644 --- a/src/backend/storage/freespace/freespace.c +++ b/src/backend/storage/freespace/freespace.c @@ -8,7 +8,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/storage/freespace/freespace.c,v 1.30 2004/01/26 22:35:32 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/storage/freespace/freespace.c,v 1.31 2004/06/05 19:48:08 tgl Exp $ * * * NOTES: @@ -893,7 +893,7 @@ LoadFreeSpaceMap(void) len = nPages * sizeof(IndexFSMPageData); else len = nPages * sizeof(FSMPageData); - data = (char *) palloc(len + 1); /* +1 to avoid palloc(0) */ + data = (char *) palloc(len); if (fread(data, 1, len, fp) != len) { elog(LOG, "premature EOF in \"%s\"", cachefilename); diff --git a/src/backend/storage/lmgr/deadlock.c b/src/backend/storage/lmgr/deadlock.c index 905b96f66bf..4170221b22f 100644 --- a/src/backend/storage/lmgr/deadlock.c +++ b/src/backend/storage/lmgr/deadlock.c @@ -12,7 +12,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/storage/lmgr/deadlock.c,v 1.27 2003/12/01 21:59:25 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/storage/lmgr/deadlock.c,v 1.28 2004/06/05 19:48:08 tgl Exp $ * * Interface: * @@ -147,11 +147,10 @@ InitDeadLockChecking(void) * We need to consider rearranging at most MaxBackends/2 wait queues * (since it takes at least two waiters in a queue to create a soft * edge), and the expanded form of the wait queues can't involve more - * than MaxBackends total waiters. (But avoid palloc(0) if - * MaxBackends = 1.) + * than MaxBackends total waiters. */ waitOrders = (WAIT_ORDER *) - palloc(((MaxBackends + 1) / 2) * sizeof(WAIT_ORDER)); + palloc((MaxBackends / 2) * sizeof(WAIT_ORDER)); waitOrderProcs = (PGPROC **) palloc(MaxBackends * sizeof(PGPROC *)); /* diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 88179a0731a..c04f3b5c88a 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/storage/lmgr/lock.c,v 1.132 2004/05/28 05:13:05 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/storage/lmgr/lock.c,v 1.133 2004/06/05 19:48:08 tgl Exp $ * * NOTES * Outside modules can create a lock table and acquire/release @@ -1361,9 +1361,6 @@ GetLockStatusData(void) data->nelements = i = proclockTable->hctl->nentries; - if (i == 0) - i = 1; /* avoid palloc(0) if empty table */ - data->proclockaddrs = (SHMEM_OFFSET *) palloc(sizeof(SHMEM_OFFSET) * i); data->proclocks = (PROCLOCK *) palloc(sizeof(PROCLOCK) * i); data->procs = (PGPROC *) palloc(sizeof(PGPROC) * i); diff --git a/src/backend/tcop/pquery.c b/src/backend/tcop/pquery.c index e79c58f7025..85d05ed1b8b 100644 --- a/src/backend/tcop/pquery.c +++ b/src/backend/tcop/pquery.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/tcop/pquery.c,v 1.79 2004/05/26 18:54:08 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/tcop/pquery.c,v 1.80 2004/06/05 19:48:08 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -347,10 +347,9 @@ PortalSetResultFormat(Portal portal, int nFormats, int16 *formats) if (portal->tupDesc == NULL) return; natts = portal->tupDesc->natts; - /* +1 avoids palloc(0) if no columns */ portal->formats = (int16 *) MemoryContextAlloc(PortalGetHeapMemory(portal), - (natts + 1) * sizeof(int16)); + natts * sizeof(int16)); if (nFormats > 1) { /* format specified for each column */ diff --git a/src/backend/utils/adt/name.c b/src/backend/utils/adt/name.c index ecac8d2d500..cf4f14c3e15 100644 --- a/src/backend/utils/adt/name.c +++ b/src/backend/utils/adt/name.c @@ -14,7 +14,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/utils/adt/name.c,v 1.52 2004/05/30 23:40:35 neilc Exp $ + * $PostgreSQL: pgsql/src/backend/utils/adt/name.c,v 1.53 2004/06/05 19:48:09 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -358,9 +358,7 @@ current_schemas(PG_FUNCTION_ARGS) int i; ArrayType *array; - /* +1 here is just to avoid palloc(0) error */ - - names = (Datum *) palloc((list_length(search_path) + 1) * sizeof(Datum)); + names = (Datum *) palloc(list_length(search_path) * sizeof(Datum)); i = 0; foreach(l, search_path) { diff --git a/src/backend/utils/mmgr/README b/src/backend/utils/mmgr/README index 409cfd768c8..f705827c1b6 100644 --- a/src/backend/utils/mmgr/README +++ b/src/backend/utils/mmgr/README @@ -1,4 +1,4 @@ -$PostgreSQL: pgsql/src/backend/utils/mmgr/README,v 1.5 2003/11/29 19:52:04 pgsql Exp $ +$PostgreSQL: pgsql/src/backend/utils/mmgr/README,v 1.6 2004/06/05 19:48:09 tgl Exp $ Notes about memory allocation redesign -------------------------------------- @@ -53,6 +53,26 @@ that can be reset or deleted at strategic times within a query, such as after each tuple. +Some notes about the palloc API versus standard C library +--------------------------------------------------------- + +The behavior of palloc and friends is similar to the standard C library's +malloc and friends, but there are some deliberate differences too. Here +are some notes to clarify the behavior. + +* If out of memory, palloc and repalloc exit via elog(ERROR). They never +return NULL, and it is not necessary or useful to test for such a result. + +* palloc(0) is explicitly a valid operation. It does not return a NULL +pointer, but a valid chunk of which no bytes may be used. (However, the +chunk might later be repalloc'd larger; it can also be pfree'd without +error.) (Note: this behavior is new in Postgres 7.5; earlier versions +disallowed palloc(0). It seems more consistent to allow it, however.) +Similarly, repalloc allows realloc'ing to zero size. + +* pfree and repalloc do not accept a NULL pointer. This is intentional. + + pfree/repalloc no longer depend on CurrentMemoryContext ------------------------------------------------------- diff --git a/src/backend/utils/mmgr/mcxt.c b/src/backend/utils/mmgr/mcxt.c index bc139a7d96a..c444886e140 100644 --- a/src/backend/utils/mmgr/mcxt.c +++ b/src/backend/utils/mmgr/mcxt.c @@ -14,7 +14,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/utils/mmgr/mcxt.c,v 1.44 2003/11/29 19:52:04 pgsql Exp $ + * $PostgreSQL: pgsql/src/backend/utils/mmgr/mcxt.c,v 1.45 2004/06/05 19:48:09 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -565,7 +565,7 @@ pfree(void *pointer) /* * repalloc - * + * Adjust the size of a previously allocated chunk. */ void * repalloc(void *pointer, Size size) diff --git a/src/include/utils/memutils.h b/src/include/utils/memutils.h index 29e3878c998..7865859c062 100644 --- a/src/include/utils/memutils.h +++ b/src/include/utils/memutils.h @@ -10,7 +10,7 @@ * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/utils/memutils.h,v 1.54 2003/11/29 22:41:15 pgsql Exp $ + * $PostgreSQL: pgsql/src/include/utils/memutils.h,v 1.55 2004/06/05 19:48:09 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -31,10 +31,13 @@ * * XXX This is deliberately chosen to correspond to the limiting size * of varlena objects under TOAST. See VARATT_MASK_SIZE in postgres.h. + * + * XXX Also, various places in aset.c assume they can compute twice an + * allocation's size without overflow, so beware of raising this. */ #define MaxAllocSize ((Size) 0x3fffffff) /* 1 gigabyte - 1 */ -#define AllocSizeIsValid(size) (0 < (size) && (size) <= MaxAllocSize) +#define AllocSizeIsValid(size) ((Size) (size) <= MaxAllocSize) /* * All chunks allocated by any memory context manager are required to be diff --git a/src/pl/plpgsql/src/pl_exec.c b/src/pl/plpgsql/src/pl_exec.c index 5a3d77a07c6..e479094099e 100644 --- a/src/pl/plpgsql/src/pl_exec.c +++ b/src/pl/plpgsql/src/pl_exec.c @@ -3,7 +3,7 @@ * procedural language * * IDENTIFICATION - * $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.104 2004/06/04 02:37:06 tgl Exp $ + * $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.105 2004/06/05 19:48:09 tgl Exp $ * * This software is copyrighted by Jan Wieck - Hamburg. * @@ -1942,10 +1942,8 @@ exec_prepare_plan(PLpgSQL_execstate * estate, /* * We need a temporary argtypes array to load with data. (The finished * plan structure will contain a copy of it.) - * - * +1 is just to avoid palloc(0) error. */ - argtypes = (Oid *) palloc(sizeof(Oid) * (expr->nparams + 1)); + argtypes = (Oid *) palloc(expr->nparams * sizeof(Oid)); for (i = 0; i < expr->nparams; i++) { @@ -1998,8 +1996,8 @@ exec_stmt_execsql(PLpgSQL_execstate * estate, /* * Now build up the values and nulls arguments for SPI_execp() */ - values = palloc(sizeof(Datum) * (expr->nparams + 1)); - nulls = palloc(expr->nparams + 1); + values = (Datum *) palloc(expr->nparams * sizeof(Datum)); + nulls = (char *) palloc(expr->nparams * sizeof(char)); for (i = 0; i < expr->nparams; i++) { @@ -2479,8 +2477,8 @@ exec_stmt_open(PLpgSQL_execstate * estate, PLpgSQL_stmt_open * stmt) * refcursor opened with OPEN ... FOR SELECT ...; * ---------- */ - values = palloc(sizeof(Datum) * (query->nparams + 1)); - nulls = palloc(query->nparams + 1); + values = (Datum *) palloc(query->nparams * sizeof(Datum)); + nulls = (char *) palloc(query->nparams * sizeof(char)); for (i = 0; i < query->nparams; i++) { @@ -3324,8 +3322,8 @@ exec_run_select(PLpgSQL_execstate * estate, /* * Now build up the values and nulls arguments for SPI_execp() */ - values = palloc(sizeof(Datum) * (expr->nparams + 1)); - nulls = palloc(expr->nparams + 1); + values = (Datum *) palloc(expr->nparams * sizeof(Datum)); + nulls = (char *) palloc(expr->nparams * sizeof(char)); for (i = 0; i < expr->nparams; i++) { @@ -3528,8 +3526,7 @@ exec_move_row(PLpgSQL_execstate * estate, /* If we have a tupdesc but no data, form an all-nulls tuple */ char *nulls; - /* +1 to avoid possible palloc(0) if no attributes */ - nulls = (char *) palloc(tupdesc->natts * sizeof(char) + 1); + nulls = (char *) palloc(tupdesc->natts * sizeof(char)); memset(nulls, 'n', tupdesc->natts * sizeof(char)); rec->tup = heap_formtuple(tupdesc, NULL, nulls); diff --git a/src/pl/plpython/plpython.c b/src/pl/plpython/plpython.c index f660adf2973..d07af29c816 100644 --- a/src/pl/plpython/plpython.c +++ b/src/pl/plpython/plpython.c @@ -29,7 +29,7 @@ * MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. * * IDENTIFICATION - * $PostgreSQL: pgsql/src/pl/plpython/plpython.c,v 1.47 2004/05/07 00:24:59 tgl Exp $ + * $PostgreSQL: pgsql/src/pl/plpython/plpython.c,v 1.48 2004/06/05 19:48:09 tgl Exp $ * ********************************************************************* */ @@ -531,10 +531,9 @@ PLy_modify_tuple(PLyProcedure * proc, PyObject * pltd, TriggerData *tdata, plkeys = PyDict_Keys(plntup); natts = PyList_Size(plkeys); - /* +1 to avoid palloc(0) on empty tuple */ - modattrs = palloc(natts * sizeof(int) + 1); - modvalues = palloc(natts * sizeof(Datum) + 1); - modnulls = palloc(natts + 1); + modattrs = (int *) palloc(natts * sizeof(int)); + modvalues = (Datum *) palloc(natts * sizeof(Datum)); + modnulls = (char *) palloc(natts * sizeof(char)); tupdesc = tdata->tg_relation->rd_att; @@ -2174,48 +2173,46 @@ PLy_spi_execute_plan(PyObject * ob, PyObject * list, int limit) RERAISE_EXC(); } - if (nargs) + nulls = palloc(nargs * sizeof(char)); + + for (i = 0; i < nargs; i++) { - nulls = palloc((nargs + 1) * sizeof(char)); + PyObject *elem, + *so; + char *sv; - for (i = 0; i < nargs; i++) + elem = PySequence_GetItem(list, i); + if (elem != Py_None) { - PyObject *elem, - *so; - char *sv; + so = PyObject_Str(elem); + sv = PyString_AsString(so); - elem = PySequence_GetItem(list, i); - if (elem != Py_None) - { - so = PyObject_Str(elem); - sv = PyString_AsString(so); - - /* - * FIXME -- if this can elog, we have leak - */ - plan->values[i] = FunctionCall3(&(plan->args[i].out.d.typfunc), - CStringGetDatum(sv), - ObjectIdGetDatum(plan->args[i].out.d.typelem), - Int32GetDatum(-1)); + /* + * FIXME -- if this can elog, we have leak + */ + plan->values[i] = + FunctionCall3(&(plan->args[i].out.d.typfunc), + CStringGetDatum(sv), + ObjectIdGetDatum(plan->args[i].out.d.typelem), + Int32GetDatum(-1)); - Py_DECREF(so); - Py_DECREF(elem); + Py_DECREF(so); + Py_DECREF(elem); - nulls[i] = ' '; - } - else - { - Py_DECREF(elem); - plan->values[i] = (Datum) 0; - nulls[i] = 'n'; - } + nulls[i] = ' '; + } + else + { + Py_DECREF(elem); + plan->values[i] = (Datum) 0; + nulls[i] = 'n'; } - nulls[i] = '\0'; } - else - nulls = NULL; rv = SPI_execp(plan->plan, plan->values, nulls, limit); + + pfree(nulls); + RESTORE_EXC(); for (i = 0; i < nargs; i++) -- GitLab