mirror of
https://github.com/postgres/postgres.git
synced 2025-05-02 11:44:50 +03:00
Added: UNIQUE feature to bulkload code.
This commit is contained in:
parent
2280e62d39
commit
36058981a4
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtree.c,v 1.14 1997/02/18 17:13:42 momjian Exp $
|
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtree.c,v 1.15 1997/02/22 10:04:14 vadim Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
* This file contains only the public interface routines.
|
* This file contains only the public interface routines.
|
||||||
@ -143,7 +143,7 @@ btbuild(Relation heap,
|
|||||||
nhtups = nitups = 0;
|
nhtups = nitups = 0;
|
||||||
|
|
||||||
if (usefast) {
|
if (usefast) {
|
||||||
spool = _bt_spoolinit(index, 7);
|
spool = _bt_spoolinit(index, 7, isunique);
|
||||||
res = (InsertIndexResult) NULL;
|
res = (InsertIndexResult) NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Id: nbtsort.c,v 1.10 1997/02/14 22:47:19 momjian Exp $
|
* $Id: nbtsort.c,v 1.11 1997/02/22 10:04:16 vadim Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
*
|
*
|
||||||
@ -81,6 +81,43 @@ extern int NDirectFileRead;
|
|||||||
extern int NDirectFileWrite;
|
extern int NDirectFileWrite;
|
||||||
extern char *mktemp(char *template);
|
extern char *mktemp(char *template);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* this is what we use to shovel BTItems in and out of memory. it's
|
||||||
|
* bigger than a standard block because we are doing a lot of strictly
|
||||||
|
* sequential i/o. this is obviously something of a tradeoff since we
|
||||||
|
* are potentially reading a bunch of zeroes off of disk in many
|
||||||
|
* cases.
|
||||||
|
*
|
||||||
|
* BTItems are packed in and DOUBLEALIGN'd.
|
||||||
|
*
|
||||||
|
* the fd should not be going out to disk, strictly speaking, but it's
|
||||||
|
* the only thing like that so i'm not going to worry about wasting a
|
||||||
|
* few bytes.
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
int bttb_magic; /* magic number */
|
||||||
|
int bttb_fd; /* file descriptor */
|
||||||
|
int bttb_top; /* top of free space within bttb_data */
|
||||||
|
short bttb_ntup; /* number of tuples in this block */
|
||||||
|
short bttb_eor; /* End-Of-Run marker */
|
||||||
|
char bttb_data[TAPEBLCKSZ - 2 * sizeof(double)];
|
||||||
|
} BTTapeBlock;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* this structure holds the bookkeeping for a simple balanced multiway
|
||||||
|
* merge. (polyphase merging is hairier than i want to get into right
|
||||||
|
* now, and i don't see why i have to care how many "tapes" i use
|
||||||
|
* right now. though if psort was in a condition that i could hack it
|
||||||
|
* to do this, you bet i would.)
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
int bts_ntapes;
|
||||||
|
int bts_tape;
|
||||||
|
BTTapeBlock **bts_itape; /* input tape blocks */
|
||||||
|
BTTapeBlock **bts_otape; /* output tape blocks */
|
||||||
|
bool isunique;
|
||||||
|
} BTSpool;
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------
|
/*-------------------------------------------------------------------------
|
||||||
* sorting comparison routine - returns {-1,0,1} depending on whether
|
* sorting comparison routine - returns {-1,0,1} depending on whether
|
||||||
* the key in the left BTItem is {<,=,>} the key in the right BTItem.
|
* the key in the left BTItem is {<,=,>} the key in the right BTItem.
|
||||||
@ -105,11 +142,13 @@ typedef struct {
|
|||||||
} BTSortKey;
|
} BTSortKey;
|
||||||
|
|
||||||
static Relation _bt_sortrel;
|
static Relation _bt_sortrel;
|
||||||
|
static BTSpool * _bt_inspool;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_bt_isortcmpinit(Relation index)
|
_bt_isortcmpinit(Relation index, BTSpool *spool)
|
||||||
{
|
{
|
||||||
_bt_sortrel = index;
|
_bt_sortrel = index;
|
||||||
|
_bt_inspool = spool;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -129,6 +168,11 @@ _bt_isortcmp(BTSortKey *k1, BTSortKey *k2)
|
|||||||
k2->btsk_datum, k1->btsk_datum)) {
|
k2->btsk_datum, k1->btsk_datum)) {
|
||||||
return(-1); /* 1 < 2 */
|
return(-1); /* 1 < 2 */
|
||||||
}
|
}
|
||||||
|
if ( _bt_inspool->isunique )
|
||||||
|
{
|
||||||
|
_bt_spooldestroy ((void*)_bt_inspool);
|
||||||
|
elog (WARN, "Cannot insert a duplicate key into a unique index.");
|
||||||
|
}
|
||||||
return(0); /* 1 = 2 */
|
return(0); /* 1 = 2 */
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -159,7 +203,6 @@ _bt_setsortkey(Relation index, BTItem bti, BTSortKey *sk)
|
|||||||
* XXX these probably ought to be generic library functions.
|
* XXX these probably ought to be generic library functions.
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int btpqe_tape; /* tape identifier */
|
int btpqe_tape; /* tape identifier */
|
||||||
BTSortKey btpqe_item; /* pointer to BTItem in tape buffer */
|
BTSortKey btpqe_item; /* pointer to BTItem in tape buffer */
|
||||||
@ -256,29 +299,6 @@ _bt_pqadd(BTPriQueue *q, BTPriQueueElem *e)
|
|||||||
((tape)->bttb_ntup <= 0)
|
((tape)->bttb_ntup <= 0)
|
||||||
#define BTTAPEMAGIC 0x19660226
|
#define BTTAPEMAGIC 0x19660226
|
||||||
|
|
||||||
/*
|
|
||||||
* this is what we use to shovel BTItems in and out of memory. it's
|
|
||||||
* bigger than a standard block because we are doing a lot of strictly
|
|
||||||
* sequential i/o. this is obviously something of a tradeoff since we
|
|
||||||
* are potentially reading a bunch of zeroes off of disk in many
|
|
||||||
* cases.
|
|
||||||
*
|
|
||||||
* BTItems are packed in and DOUBLEALIGN'd.
|
|
||||||
*
|
|
||||||
* the fd should not be going out to disk, strictly speaking, but it's
|
|
||||||
* the only thing like that so i'm not going to worry about wasting a
|
|
||||||
* few bytes.
|
|
||||||
*/
|
|
||||||
typedef struct {
|
|
||||||
int bttb_magic; /* magic number */
|
|
||||||
int bttb_fd; /* file descriptor */
|
|
||||||
int bttb_top; /* top of free space within bttb_data */
|
|
||||||
short bttb_ntup; /* number of tuples in this block */
|
|
||||||
short bttb_eor; /* End-Of-Run marker */
|
|
||||||
char bttb_data[TAPEBLCKSZ - 2 * sizeof(double)];
|
|
||||||
} BTTapeBlock;
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* reset the tape header for its next use without doing anything to
|
* reset the tape header for its next use without doing anything to
|
||||||
* the physical tape file. (setting bttb_top to 0 makes the block
|
* the physical tape file. (setting bttb_top to 0 makes the block
|
||||||
@ -455,26 +475,12 @@ _bt_tapeadd(BTTapeBlock *tape, BTItem item, int itemsz)
|
|||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
|
||||||
* this structure holds the bookkeeping for a simple balanced multiway
|
|
||||||
* merge. (polyphase merging is hairier than i want to get into right
|
|
||||||
* now, and i don't see why i have to care how many "tapes" i use
|
|
||||||
* right now. though if psort was in a condition that i could hack it
|
|
||||||
* to do this, you bet i would.)
|
|
||||||
*/
|
|
||||||
typedef struct {
|
|
||||||
int bts_ntapes;
|
|
||||||
int bts_tape;
|
|
||||||
BTTapeBlock **bts_itape; /* input tape blocks */
|
|
||||||
BTTapeBlock **bts_otape; /* output tape blocks */
|
|
||||||
} BTSpool;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* create and initialize a spool structure, including the underlying
|
* create and initialize a spool structure, including the underlying
|
||||||
* files.
|
* files.
|
||||||
*/
|
*/
|
||||||
void *
|
void *
|
||||||
_bt_spoolinit(Relation index, int ntapes)
|
_bt_spoolinit(Relation index, int ntapes, bool isunique)
|
||||||
{
|
{
|
||||||
BTSpool *btspool = (BTSpool *) palloc(sizeof(BTSpool));
|
BTSpool *btspool = (BTSpool *) palloc(sizeof(BTSpool));
|
||||||
int i;
|
int i;
|
||||||
@ -486,6 +492,7 @@ _bt_spoolinit(Relation index, int ntapes)
|
|||||||
(void) memset((char *) btspool, 0, sizeof(BTSpool));
|
(void) memset((char *) btspool, 0, sizeof(BTSpool));
|
||||||
btspool->bts_ntapes = ntapes;
|
btspool->bts_ntapes = ntapes;
|
||||||
btspool->bts_tape = 0;
|
btspool->bts_tape = 0;
|
||||||
|
btspool->isunique = isunique;
|
||||||
|
|
||||||
btspool->bts_itape =
|
btspool->bts_itape =
|
||||||
(BTTapeBlock **) palloc(sizeof(BTTapeBlock *) * ntapes);
|
(BTTapeBlock **) palloc(sizeof(BTTapeBlock *) * ntapes);
|
||||||
@ -504,7 +511,7 @@ _bt_spoolinit(Relation index, int ntapes)
|
|||||||
}
|
}
|
||||||
pfree((void *) fname);
|
pfree((void *) fname);
|
||||||
|
|
||||||
_bt_isortcmpinit(index);
|
_bt_isortcmpinit(index, btspool);
|
||||||
|
|
||||||
return((void *) btspool);
|
return((void *) btspool);
|
||||||
}
|
}
|
||||||
@ -597,6 +604,8 @@ _bt_spool(Relation index, BTItem btitem, void *spool)
|
|||||||
BTTapeBlock *itape;
|
BTTapeBlock *itape;
|
||||||
Size itemsz;
|
Size itemsz;
|
||||||
|
|
||||||
|
_bt_isortcmpinit (index, btspool);
|
||||||
|
|
||||||
itape = btspool->bts_itape[btspool->bts_tape];
|
itape = btspool->bts_itape[btspool->bts_tape];
|
||||||
itemsz = BTITEMSZ(btitem);
|
itemsz = BTITEMSZ(btitem);
|
||||||
itemsz = DOUBLEALIGN(itemsz);
|
itemsz = DOUBLEALIGN(itemsz);
|
||||||
@ -633,7 +642,6 @@ _bt_spool(Relation index, BTItem btitem, void *spool)
|
|||||||
/*
|
/*
|
||||||
* qsort the pointer array.
|
* qsort the pointer array.
|
||||||
*/
|
*/
|
||||||
_bt_isortcmpinit(index);
|
|
||||||
qsort((void *) parray, itape->bttb_ntup, sizeof(BTSortKey),
|
qsort((void *) parray, itape->bttb_ntup, sizeof(BTSortKey),
|
||||||
(int (*)(const void *,const void *))_bt_isortcmp);
|
(int (*)(const void *,const void *))_bt_isortcmp);
|
||||||
}
|
}
|
||||||
@ -1298,5 +1306,6 @@ _bt_upperbuild(Relation index)
|
|||||||
void
|
void
|
||||||
_bt_leafbuild(Relation index, void *spool)
|
_bt_leafbuild(Relation index, void *spool)
|
||||||
{
|
{
|
||||||
|
_bt_isortcmpinit (index, (BTSpool *) spool);
|
||||||
_bt_merge(index, (BTSpool *) spool);
|
_bt_merge(index, (BTSpool *) spool);
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
*
|
*
|
||||||
* Copyright (c) 1994, Regents of the University of California
|
* Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $Id: nbtree.h,v 1.8 1997/02/18 17:14:10 momjian Exp $
|
* $Id: nbtree.h,v 1.9 1997/02/22 10:08:27 vadim Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -278,7 +278,7 @@ extern BTItem _bt_formitem(IndexTuple itup);
|
|||||||
/*
|
/*
|
||||||
* prototypes for functions in nbtsort.c
|
* prototypes for functions in nbtsort.c
|
||||||
*/
|
*/
|
||||||
extern void *_bt_spoolinit(Relation index, int ntapes);
|
extern void *_bt_spoolinit(Relation index, int ntapes, bool isunique);
|
||||||
extern void *_bt_pagestate(Relation index, int flags, int level, bool doupper);
|
extern void *_bt_pagestate(Relation index, int flags, int level, bool doupper);
|
||||||
extern BTItem _bt_minitem(Page opage, BlockNumber oblkno, int atend);
|
extern BTItem _bt_minitem(Page opage, BlockNumber oblkno, int atend);
|
||||||
extern BTItem _bt_buildadd(Relation index, void *pstate, BTItem bti, int flags);
|
extern BTItem _bt_buildadd(Relation index, void *pstate, BTItem bti, int flags);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user