diff options
Diffstat (limited to 'src/backend/access/heap')
| -rw-r--r-- | src/backend/access/heap/heapam.c | 62 | ||||
| -rw-r--r-- | src/backend/access/heap/hio.c | 16 |
2 files changed, 72 insertions, 6 deletions
diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index 15556fda53..cf3344c200 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/access/heap/heapam.c,v 1.213 2006/05/28 02:27:08 alvherre Exp $ + * $PostgreSQL: pgsql/src/backend/access/heap/heapam.c,v 1.214 2006/07/02 02:23:18 momjian Exp $ * * * INTERFACE ROUTINES @@ -46,9 +46,13 @@ #include "access/xlogutils.h" #include "catalog/catalog.h" #include "catalog/namespace.h" +#include "commands/defrem.h" #include "miscadmin.h" +#include "nodes/parsenodes.h" +#include "parser/parse_clause.h" #include "pgstat.h" #include "storage/procarray.h" +#include "utils/catcache.h" #include "utils/inval.h" #include "utils/relcache.h" @@ -3588,3 +3592,59 @@ heap_desc(StringInfo buf, uint8 xl_info, char *rec) else appendStringInfo(buf, "UNKNOWN"); } + +/* + * Parse options for heaps. + * + * relkind Kind of relation + * options Options as text[] + */ +bytea * +heap_option(char relkind, ArrayType *options) +{ + /* + * XXX: What fillfactor should be default? + * overriding databases: + * - Oracle, DB2 = 90% + * - SQL Server = 100% + * non-overriding database: + * - Firebird = 70% + */ +#define HEAP_MIN_FILLFACTOR 50 +#define HEAP_DEFAULT_FILLFACTOR 100 + + int fillfactor; + HeapOption *result; + + DefElem kwds[] = + { + { T_DefElem, "fillfactor" }, + }; + + /* + * parse options + */ + OptionParse(options, lengthof(kwds), kwds, true); + + /* 0: fillfactor */ + if (kwds[0].arg) + fillfactor = (int) defGetInt64(&kwds[0]); + else + fillfactor = HEAP_DEFAULT_FILLFACTOR; + if (fillfactor < HEAP_MIN_FILLFACTOR || 100 < fillfactor) + { + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("fillfactor=%d should be between %d and 100", + fillfactor, HEAP_MIN_FILLFACTOR))); + } + + /* + * build option + */ + result = (HeapOption *) + MemoryContextAlloc(CacheMemoryContext, sizeof(HeapOption)); + VARATT_SIZEP(result) = sizeof(HeapOption); + result->fillfactor = fillfactor; + return (bytea *) result; +} diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c index ccaaacefea..82fb0a3268 100644 --- a/src/backend/access/heap/hio.c +++ b/src/backend/access/heap/hio.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/access/heap/hio.c,v 1.61 2006/03/05 15:58:21 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/access/heap/hio.c,v 1.62 2006/07/02 02:23:18 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -102,12 +102,18 @@ RelationGetBufferForTuple(Relation relation, Size len, { Buffer buffer = InvalidBuffer; Page pageHeader; - Size pageFreeSpace; + Size pageFreeSpace, + freespace; BlockNumber targetBlock, otherBlock; bool needLock; + if (relation->rd_options == NULL) + elog(ERROR, "RelationGetBufferForTuple %s IS NULL", RelationGetRelationName(relation)); + Assert(relation->rd_options != NULL); + len = MAXALIGN(len); /* be conservative */ + freespace = HeapGetPageFreeSpace(relation); /* * If we're gonna fail for oversize tuple, do it right away @@ -146,7 +152,7 @@ RelationGetBufferForTuple(Relation relation, Size len, * We have no cached target page, so ask the FSM for an initial * target. */ - targetBlock = GetPageWithFreeSpace(&relation->rd_node, len); + targetBlock = GetPageWithFreeSpace(&relation->rd_node, len + freespace); /* * If the FSM knows nothing of the rel, try the last page before we @@ -202,7 +208,7 @@ RelationGetBufferForTuple(Relation relation, Size len, */ pageHeader = (Page) BufferGetPage(buffer); pageFreeSpace = PageGetFreeSpace(pageHeader); - if (len <= pageFreeSpace) + if (len + freespace <= pageFreeSpace) { /* use this page as future insert target, too */ relation->rd_targblock = targetBlock; @@ -235,7 +241,7 @@ RelationGetBufferForTuple(Relation relation, Size len, targetBlock = RecordAndGetPageWithFreeSpace(&relation->rd_node, targetBlock, pageFreeSpace, - len); + len + freespace); } /* |
