summaryrefslogtreecommitdiff
path: root/src/backend/access/heap
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/access/heap')
-rw-r--r--src/backend/access/heap/heapam.c62
-rw-r--r--src/backend/access/heap/hio.c16
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);
}
/*