diff options
| author | Hiroshi Inoue <inoue@tpf.co.jp> | 2000-08-10 02:33:20 +0000 |
|---|---|---|
| committer | Hiroshi Inoue <inoue@tpf.co.jp> | 2000-08-10 02:33:20 +0000 |
| commit | b0d5036c7cadb7458d00faffe9b194be8471c84a (patch) | |
| tree | 6ecc2307506c4f37f24250739e89cad122f7f872 /src/backend/access/nbtree/nbtree.c | |
| parent | 5ab40f0b85723caefecad972820580a8109d5e73 (diff) | |
| download | postgresql-b0d5036c7cadb7458d00faffe9b194be8471c84a.tar.gz | |
CREATE btree INDEX takes dead tuples into account when old transactions
are running.
Diffstat (limited to 'src/backend/access/nbtree/nbtree.c')
| -rw-r--r-- | src/backend/access/nbtree/nbtree.c | 62 |
1 files changed, 58 insertions, 4 deletions
diff --git a/src/backend/access/nbtree/nbtree.c b/src/backend/access/nbtree/nbtree.c index 072d400070..7fec982fa2 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 - * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtree.c,v 1.62 2000/07/21 06:42:32 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtree.c,v 1.63 2000/08/10 02:33:20 inoue Exp $ * *------------------------------------------------------------------------- */ @@ -25,6 +25,7 @@ #include "catalog/index.h" #include "executor/executor.h" #include "miscadmin.h" +#include "storage/sinval.h" bool BuildingBtree = false; /* see comment in btbuild() */ @@ -70,6 +71,16 @@ btbuild(PG_FUNCTION_ARGS) BTSpool *spool = NULL; BTItem btitem; bool usefast; + Snapshot snapshot; + TransactionId XmaxRecent; + /* + * spool2 is needed only when the index is an unique index. + * Dead tuples are put into spool2 instead of spool in + * order to avoid uniqueness check. + */ + BTSpool *spool2 = NULL; + bool tupleIsAlive; + int dead_count; /* note that this is a new btree */ BuildingBtree = true; @@ -135,13 +146,41 @@ btbuild(PG_FUNCTION_ARGS) nhtups = nitups = 0; if (usefast) + { spool = _bt_spoolinit(index, indexInfo->ii_Unique); + /* + * Different from spool,the uniqueness isn't checked + * for spool2. + */ + if (indexInfo->ii_Unique) + spool2 = _bt_spoolinit(index, false); + } /* start a heap scan */ - hscan = heap_beginscan(heap, 0, SnapshotNow, 0, (ScanKey) NULL); + dead_count = 0; + snapshot = (IsBootstrapProcessingMode() ? SnapshotNow : SnapshotAny); + hscan = heap_beginscan(heap, 0, snapshot, 0, (ScanKey) NULL); + XmaxRecent = 0; + if (snapshot == SnapshotAny) + GetXmaxRecent(&XmaxRecent); while (HeapTupleIsValid(htup = heap_getnext(hscan, 0))) { + if (snapshot == SnapshotAny) + { + tupleIsAlive = HeapTupleSatisfiesNow(htup->t_data); + if (!tupleIsAlive) + { + if ((htup->t_data->t_infomask & HEAP_XMIN_INVALID) != 0) + continue; + if (htup->t_data->t_infomask & HEAP_XMAX_COMMITTED && + htup->t_data->t_xmax < XmaxRecent) + continue; + } + } + else + tupleIsAlive = true; + MemoryContextReset(econtext->ecxt_per_tuple_memory); nhtups++; @@ -222,7 +261,15 @@ btbuild(PG_FUNCTION_ARGS) * into the btree. */ if (usefast) - _bt_spool(btitem, spool); + { + if (tupleIsAlive || !spool2) + _bt_spool(btitem, spool); + else /* dead tuples are put into spool2 */ + { + dead_count++; + _bt_spool(btitem, spool2); + } + } else res = _bt_doinsert(index, btitem, indexInfo->ii_Unique, heap); @@ -234,6 +281,11 @@ btbuild(PG_FUNCTION_ARGS) /* okay, all heap tuples are indexed */ heap_endscan(hscan); + if (spool2 && !dead_count) /* spool2 was found to be unnecessary */ + { + _bt_spooldestroy(spool2); + spool2 = NULL; + } #ifndef OMIT_PARTIAL_INDEX if (pred != NULL || oldPred != NULL) @@ -250,8 +302,10 @@ btbuild(PG_FUNCTION_ARGS) */ if (usefast) { - _bt_leafbuild(spool); + _bt_leafbuild(spool, spool2); _bt_spooldestroy(spool); + if (spool2) + _bt_spooldestroy(spool2); } #ifdef BTREE_BUILD_STATS |
