Commit b3e71841 authored by Yoni Fogel's avatar Yoni Fogel

[t:2350] Added DB_NOOVERWRITE_NO_ERROR flag for DB->put.

Will return EINVAL for ENV->put_multiple.

Has same semantics as INSERT IGNORE in mysql.
(equivalently) Has same semantics as DB_NOOVERWRITE except that it returns 0 if there is a duplicate key error
instead of DB_KEYEXISTS

git-svn-id: file:///svn/toku/tokudb@17682 c7de825b-a66e-492c-adef-691d508d4ae1
parent bb0b6324
...@@ -132,9 +132,10 @@ typedef enum { ...@@ -132,9 +132,10 @@ typedef enum {
#define DB_DUPSORT 4 #define DB_DUPSORT 4
#define DB_KEYFIRST 16 #define DB_KEYFIRST 16
#define DB_KEYLAST 17 #define DB_KEYLAST 17
#define DB_NODUPDATA 22
#define DB_NOOVERWRITE 23 #define DB_NOOVERWRITE 23
#define DB_YESOVERWRITE 254 #define DB_NODUPDATA 22
#define DB_YESOVERWRITE 1
#define DB_NOOVERWRITE_NO_ERROR 2
#define DB_OPFLAGS_MASK 255 #define DB_OPFLAGS_MASK 255
#define DB_AUTO_COMMIT 8388608 #define DB_AUTO_COMMIT 8388608
#define DB_INIT_LOCK 4096 #define DB_INIT_LOCK 4096
......
...@@ -132,9 +132,10 @@ typedef enum { ...@@ -132,9 +132,10 @@ typedef enum {
#define DB_DUPSORT 4 #define DB_DUPSORT 4
#define DB_KEYFIRST 15 #define DB_KEYFIRST 15
#define DB_KEYLAST 16 #define DB_KEYLAST 16
#define DB_NODUPDATA 21
#define DB_NOOVERWRITE 22 #define DB_NOOVERWRITE 22
#define DB_YESOVERWRITE 254 #define DB_NODUPDATA 21
#define DB_YESOVERWRITE 1
#define DB_NOOVERWRITE_NO_ERROR 2
#define DB_OPFLAGS_MASK 255 #define DB_OPFLAGS_MASK 255
#define DB_AUTO_COMMIT 16777216 #define DB_AUTO_COMMIT 16777216
#define DB_INIT_LOCK 8192 #define DB_INIT_LOCK 8192
......
...@@ -132,9 +132,10 @@ typedef enum { ...@@ -132,9 +132,10 @@ typedef enum {
#define DB_DUPSORT 32768 #define DB_DUPSORT 32768
#define DB_KEYFIRST 15 #define DB_KEYFIRST 15
#define DB_KEYLAST 16 #define DB_KEYLAST 16
#define DB_NODUPDATA 21
#define DB_NOOVERWRITE 22 #define DB_NOOVERWRITE 22
#define DB_YESOVERWRITE 254 #define DB_NODUPDATA 21
#define DB_YESOVERWRITE 1
#define DB_NOOVERWRITE_NO_ERROR 2
#define DB_OPFLAGS_MASK 255 #define DB_OPFLAGS_MASK 255
#define DB_AUTO_COMMIT 16777216 #define DB_AUTO_COMMIT 16777216
#define DB_INIT_LOCK 16384 #define DB_INIT_LOCK 16384
......
...@@ -132,9 +132,10 @@ typedef enum { ...@@ -132,9 +132,10 @@ typedef enum {
#define DB_DUPSORT 65536 #define DB_DUPSORT 65536
#define DB_KEYFIRST 13 #define DB_KEYFIRST 13
#define DB_KEYLAST 14 #define DB_KEYLAST 14
#define DB_NODUPDATA 19
#define DB_NOOVERWRITE 20 #define DB_NOOVERWRITE 20
#define DB_YESOVERWRITE 254 #define DB_NODUPDATA 19
#define DB_YESOVERWRITE 1
#define DB_NOOVERWRITE_NO_ERROR 2
#define DB_OPFLAGS_MASK 255 #define DB_OPFLAGS_MASK 255
#define DB_AUTO_COMMIT 33554432 #define DB_AUTO_COMMIT 33554432
#define DB_INIT_LOCK 32768 #define DB_INIT_LOCK 32768
......
...@@ -132,9 +132,10 @@ typedef enum { ...@@ -132,9 +132,10 @@ typedef enum {
#define DB_DUPSORT 65536 #define DB_DUPSORT 65536
#define DB_KEYFIRST 13 #define DB_KEYFIRST 13
#define DB_KEYLAST 14 #define DB_KEYLAST 14
#define DB_NODUPDATA 19
#define DB_NOOVERWRITE 20 #define DB_NOOVERWRITE 20
#define DB_YESOVERWRITE 254 #define DB_NODUPDATA 19
#define DB_YESOVERWRITE 1
#define DB_NOOVERWRITE_NO_ERROR 2
#define DB_OPFLAGS_MASK 255 #define DB_OPFLAGS_MASK 255
#define DB_AUTO_COMMIT 33554432 #define DB_AUTO_COMMIT 33554432
#define DB_INIT_LOCK 131072 #define DB_INIT_LOCK 131072
......
...@@ -43,6 +43,21 @@ void print_db_notices (void) { ...@@ -43,6 +43,21 @@ void print_db_notices (void) {
printf("#define %s %d\n", #name, bit); \ printf("#define %s %d\n", #name, bit); \
} while (0) } while (0)
#define dodefine_track_enum(flags, name) do {assert(!(flags[name])); \
flags[name] = 1; \
printf("#define %s %d\n", #name, name);} while (0)
#define dodefine_from_track_enum(flags, name) do { \
uint32_t which; \
/* don't use 0 */ \
for (which = 1; which < 256; which++) { \
if (!(flags[which])) break; \
} \
assert(which < 256); \
flags[which] = 1; \
printf("#define %s %d\n", #name, which); \
} while (0)
enum { enum {
TOKUDB_OUT_OF_LOCKS = -100000, TOKUDB_OUT_OF_LOCKS = -100000,
TOKUDB_SUCCEEDED_EARLY = -100001, TOKUDB_SUCCEEDED_EARLY = -100001,
...@@ -82,9 +97,13 @@ void print_defines (void) { ...@@ -82,9 +97,13 @@ void print_defines (void) {
dodefine(DB_KEYFIRST); dodefine(DB_KEYFIRST);
dodefine(DB_KEYLAST); dodefine(DB_KEYLAST);
dodefine(DB_NODUPDATA); {
dodefine(DB_NOOVERWRITE); static uint8_t insert_flags[256];
printf("#define DB_YESOVERWRITE 254\n"); // tokudb dodefine_track_enum(insert_flags, DB_NOOVERWRITE);
dodefine_track_enum(insert_flags, DB_NODUPDATA);
dodefine_from_track_enum(insert_flags, DB_YESOVERWRITE);
dodefine_from_track_enum(insert_flags, DB_NOOVERWRITE_NO_ERROR);
}
dodefine(DB_OPFLAGS_MASK); dodefine(DB_OPFLAGS_MASK);
dodefine(DB_AUTO_COMMIT); dodefine(DB_AUTO_COMMIT);
......
...@@ -132,9 +132,10 @@ typedef enum { ...@@ -132,9 +132,10 @@ typedef enum {
#define DB_DUPSORT 65536 #define DB_DUPSORT 65536
#define DB_KEYFIRST 13 #define DB_KEYFIRST 13
#define DB_KEYLAST 14 #define DB_KEYLAST 14
#define DB_NODUPDATA 19
#define DB_NOOVERWRITE 20 #define DB_NOOVERWRITE 20
#define DB_YESOVERWRITE 254 #define DB_NODUPDATA 19
#define DB_YESOVERWRITE 1
#define DB_NOOVERWRITE_NO_ERROR 2
#define DB_OPFLAGS_MASK 255 #define DB_OPFLAGS_MASK 255
#define DB_AUTO_COMMIT 33554432 #define DB_AUTO_COMMIT 33554432
#define DB_INIT_LOCK 131072 #define DB_INIT_LOCK 131072
......
...@@ -132,9 +132,10 @@ typedef enum { ...@@ -132,9 +132,10 @@ typedef enum {
#define DB_DUPSORT 65536 #define DB_DUPSORT 65536
#define DB_KEYFIRST 13 #define DB_KEYFIRST 13
#define DB_KEYLAST 14 #define DB_KEYLAST 14
#define DB_NODUPDATA 19
#define DB_NOOVERWRITE 20 #define DB_NOOVERWRITE 20
#define DB_YESOVERWRITE 254 #define DB_NODUPDATA 19
#define DB_YESOVERWRITE 1
#define DB_NOOVERWRITE_NO_ERROR 2
#define DB_OPFLAGS_MASK 255 #define DB_OPFLAGS_MASK 255
#define DB_AUTO_COMMIT 33554432 #define DB_AUTO_COMMIT 33554432
#define DB_INIT_LOCK 131072 #define DB_INIT_LOCK 131072
......
...@@ -1233,6 +1233,7 @@ should_compare_both_keys (BRTNODE node, BRT_MSG cmd) ...@@ -1233,6 +1233,7 @@ should_compare_both_keys (BRTNODE node, BRT_MSG cmd)
// Effect: Return nonzero if we need to compare both the key and the value. // Effect: Return nonzero if we need to compare both the key and the value.
{ {
switch (cmd->type) { switch (cmd->type) {
case BRT_INSERT_NO_OVERWRITE:
case BRT_INSERT: case BRT_INSERT:
return node->flags & TOKU_DB_DUPSORT; return node->flags & TOKU_DB_DUPSORT;
case BRT_DELETE_BOTH: case BRT_DELETE_BOTH:
...@@ -1520,6 +1521,7 @@ brt_leaf_put_cmd (BRT t, BRTNODE node, BRT_MSG cmd, ...@@ -1520,6 +1521,7 @@ brt_leaf_put_cmd (BRT t, BRTNODE node, BRT_MSG cmd,
node->u.l.seqinsert = 0; node->u.l.seqinsert = 0;
switch (cmd->type) { switch (cmd->type) {
case BRT_INSERT_NO_OVERWRITE:
case BRT_INSERT: case BRT_INSERT:
if (doing_seqinsert) { if (doing_seqinsert) {
idx = toku_omt_size(node->u.l.buffer); idx = toku_omt_size(node->u.l.buffer);
...@@ -1909,6 +1911,7 @@ brt_nonleaf_put_cmd (BRT t, BRTNODE node, BRT_MSG cmd, ...@@ -1909,6 +1911,7 @@ brt_nonleaf_put_cmd (BRT t, BRTNODE node, BRT_MSG cmd,
//TODO: Accessing type directly //TODO: Accessing type directly
switch (cmd->type) { switch (cmd->type) {
case BRT_INSERT_NO_OVERWRITE:
case BRT_INSERT: case BRT_INSERT:
case BRT_DELETE_BOTH: case BRT_DELETE_BOTH:
case BRT_ABORT_BOTH: case BRT_ABORT_BOTH:
...@@ -2629,7 +2632,7 @@ toku_brt_broadcast_commit_all (BRT brt) ...@@ -2629,7 +2632,7 @@ toku_brt_broadcast_commit_all (BRT brt)
// Effect: Insert the key-val pair into brt. // Effect: Insert the key-val pair into brt.
int toku_brt_insert (BRT brt, DBT *key, DBT *val, TOKUTXN txn) { int toku_brt_insert (BRT brt, DBT *key, DBT *val, TOKUTXN txn) {
return toku_brt_maybe_insert(brt, key, val, txn, FALSE, ZERO_LSN, TRUE); return toku_brt_maybe_insert(brt, key, val, txn, FALSE, ZERO_LSN, TRUE, BRT_INSERT);
} }
static void static void
...@@ -2660,7 +2663,8 @@ toku_brt_log_put_multiple (TOKUTXN txn, BRT src_brt, BRT *brts, int num_brts, co ...@@ -2660,7 +2663,8 @@ toku_brt_log_put_multiple (TOKUTXN txn, BRT src_brt, BRT *brts, int num_brts, co
return r; return r;
} }
int toku_brt_maybe_insert (BRT brt, DBT *key, DBT *val, TOKUTXN txn, BOOL oplsn_valid, LSN oplsn, int do_logging) { int toku_brt_maybe_insert (BRT brt, DBT *key, DBT *val, TOKUTXN txn, BOOL oplsn_valid, LSN oplsn, int do_logging, enum brt_msg_type type) {
assert(type==BRT_INSERT || type==BRT_INSERT_NO_OVERWRITE);
int r = 0; int r = 0;
XIDS message_xids; XIDS message_xids;
TXNID xid = toku_txn_get_txnid(txn); TXNID xid = toku_txn_get_txnid(txn);
...@@ -2688,7 +2692,12 @@ int toku_brt_maybe_insert (BRT brt, DBT *key, DBT *val, TOKUTXN txn, BOOL oplsn_ ...@@ -2688,7 +2692,12 @@ int toku_brt_maybe_insert (BRT brt, DBT *key, DBT *val, TOKUTXN txn, BOOL oplsn_
if (do_logging && logger) { if (do_logging && logger) {
BYTESTRING keybs = {.len=key->size, .data=key->data}; BYTESTRING keybs = {.len=key->size, .data=key->data};
BYTESTRING valbs = {.len=val->size, .data=val->data}; BYTESTRING valbs = {.len=val->size, .data=val->data};
r = toku_log_enq_insert(logger, (LSN*)0, 0, toku_cachefile_filenum(brt->cf), xid, keybs, valbs); if (type == BRT_INSERT) {
r = toku_log_enq_insert(logger, (LSN*)0, 0, toku_cachefile_filenum(brt->cf), xid, keybs, valbs);
}
else {
r = toku_log_enq_insert_no_overwrite(logger, (LSN*)0, 0, toku_cachefile_filenum(brt->cf), xid, keybs, valbs);
}
if (r!=0) return r; if (r!=0) return r;
} }
...@@ -2696,7 +2705,7 @@ int toku_brt_maybe_insert (BRT brt, DBT *key, DBT *val, TOKUTXN txn, BOOL oplsn_ ...@@ -2696,7 +2705,7 @@ int toku_brt_maybe_insert (BRT brt, DBT *key, DBT *val, TOKUTXN txn, BOOL oplsn_
if (oplsn_valid && oplsn.lsn <= treelsn.lsn) { if (oplsn_valid && oplsn.lsn <= treelsn.lsn) {
r = 0; r = 0;
} else { } else {
BRT_MSG_S brtcmd = { BRT_INSERT, message_xids, .u.id={key,val}}; BRT_MSG_S brtcmd = { type, message_xids, .u.id={key,val}};
r = toku_brt_root_put_cmd(brt, &brtcmd); r = toku_brt_root_put_cmd(brt, &brtcmd);
} }
return r; return r;
......
...@@ -61,7 +61,7 @@ int toku_brt_insert (BRT brt, DBT *k, DBT *v, TOKUTXN txn); ...@@ -61,7 +61,7 @@ int toku_brt_insert (BRT brt, DBT *k, DBT *v, TOKUTXN txn);
// Effect: Insert a key and data pair into a brt if the oplsn is newer than the brt lsn. This function is called during recovery. // Effect: Insert a key and data pair into a brt if the oplsn is newer than the brt lsn. This function is called during recovery.
// Returns 0 if successful // Returns 0 if successful
int toku_brt_maybe_insert (BRT brt, DBT *k, DBT *v, TOKUTXN txn, BOOL oplsn_valid, LSN oplsn, int do_logging); int toku_brt_maybe_insert (BRT brt, DBT *k, DBT *v, TOKUTXN txn, BOOL oplsn_valid, LSN oplsn, int do_logging, enum brt_msg_type type);
int toku_brt_log_put_multiple (TOKUTXN txn, BRT src_brt, BRT *brts, int num_brts, const DBT *key, const DBT *val); int toku_brt_log_put_multiple (TOKUTXN txn, BRT src_brt, BRT *brts, int num_brts, const DBT *key, const DBT *val);
int toku_brt_log_del_multiple (TOKUTXN txn, BRT src_brt, BRT *brts, int num_brts, const DBT *key, const DBT *val); int toku_brt_log_del_multiple (TOKUTXN txn, BRT src_brt, BRT *brts, int num_brts, const DBT *key, const DBT *val);
......
...@@ -112,6 +112,7 @@ dump_node (int f, BLOCKNUM blocknum, struct brt_header *h) { ...@@ -112,6 +112,7 @@ dump_node (int f, BLOCKNUM blocknum, struct brt_header *h) {
switch ((enum brt_msg_type)typ) { switch ((enum brt_msg_type)typ) {
case BRT_NONE: printf("NONE"); goto ok; case BRT_NONE: printf("NONE"); goto ok;
case BRT_INSERT: printf("INSERT"); goto ok; case BRT_INSERT: printf("INSERT"); goto ok;
case BRT_INSERT_NO_OVERWRITE: printf("INSERT_NO_OVERWRITE"); goto ok;
case BRT_DELETE_ANY: printf("DELETE_ANY"); goto ok; case BRT_DELETE_ANY: printf("DELETE_ANY"); goto ok;
case BRT_DELETE_BOTH: printf("DELETE_BOTH"); goto ok; case BRT_DELETE_BOTH: printf("DELETE_BOTH"); goto ok;
case BRT_ABORT_ANY: printf("ABORT_ANY"); goto ok; case BRT_ABORT_ANY: printf("ABORT_ANY"); goto ok;
......
...@@ -85,6 +85,7 @@ enum brt_msg_type { ...@@ -85,6 +85,7 @@ enum brt_msg_type {
BRT_COMMIT_BROADCAST_ALL = 8, // Broadcast to all leafentries, (commit all transactions). BRT_COMMIT_BROADCAST_ALL = 8, // Broadcast to all leafentries, (commit all transactions).
BRT_COMMIT_BROADCAST_TXN = 9, // Broadcast to all leafentries, (commit specific transaction). BRT_COMMIT_BROADCAST_TXN = 9, // Broadcast to all leafentries, (commit specific transaction).
BRT_ABORT_BROADCAST_TXN = 10, // Broadcast to all leafentries, (commit specific transaction). BRT_ABORT_BROADCAST_TXN = 10, // Broadcast to all leafentries, (commit specific transaction).
BRT_INSERT_NO_OVERWRITE = 11,
}; };
typedef struct xids_t *XIDS; typedef struct xids_t *XIDS;
......
...@@ -139,6 +139,11 @@ const struct logtype logtypes[] = { ...@@ -139,6 +139,11 @@ const struct logtype logtypes[] = {
{"tablelock_on_empty_table", 'L', FA{{"FILENUM", "filenum", 0}, {"tablelock_on_empty_table", 'L', FA{{"FILENUM", "filenum", 0},
{"TXNID", "xid", 0}, {"TXNID", "xid", 0},
NULLFIELD}}, NULLFIELD}},
{"enq_insert_no_overwrite", 'i', FA{{"FILENUM", "filenum", 0},
{"TXNID", "xid", 0},
{"BYTESTRING", "key", 0},
{"BYTESTRING", "value", 0},
NULLFIELD}},
{"enq_insert", 'I', FA{{"FILENUM", "filenum", 0}, {"enq_insert", 'I', FA{{"FILENUM", "filenum", 0},
{"TXNID", "xid", 0}, {"TXNID", "xid", 0},
{"BYTESTRING", "key", 0}, {"BYTESTRING", "key", 0},
......
...@@ -470,7 +470,7 @@ static int toku_recover_enq_insert (struct logtype_enq_insert *l, RECOVER_ENV re ...@@ -470,7 +470,7 @@ static int toku_recover_enq_insert (struct logtype_enq_insert *l, RECOVER_ENV re
DBT keydbt, valdbt; DBT keydbt, valdbt;
toku_fill_dbt(&keydbt, l->key.data, l->key.len); toku_fill_dbt(&keydbt, l->key.data, l->key.len);
toku_fill_dbt(&valdbt, l->value.data, l->value.len); toku_fill_dbt(&valdbt, l->value.data, l->value.len);
r = toku_brt_maybe_insert(tuple->brt, &keydbt, &valdbt, txn, TRUE, l->lsn, FALSE); r = toku_brt_maybe_insert(tuple->brt, &keydbt, &valdbt, txn, TRUE, l->lsn, FALSE, BRT_INSERT);
assert(r == 0); assert(r == 0);
return 0; return 0;
...@@ -481,6 +481,36 @@ static int toku_recover_backward_enq_insert (struct logtype_enq_insert *UU(l), R ...@@ -481,6 +481,36 @@ static int toku_recover_backward_enq_insert (struct logtype_enq_insert *UU(l), R
return 0; return 0;
} }
static int toku_recover_enq_insert_no_overwrite (struct logtype_enq_insert_no_overwrite *l, RECOVER_ENV renv) {
int r;
TOKUTXN txn = NULL;
r = toku_txnid2txn(renv->logger, l->xid, &txn);
assert(r == 0);
if (txn == NULL) {
//This is a straddle txn.
assert(renv->ss.ss == FORWARD_OLDER_CHECKPOINT_BEGIN); //cannot happen after checkpoint begin
return 0;
}
struct file_map_tuple *tuple = NULL;
r = file_map_find(&renv->fmap, l->filenum, &tuple);
if (r!=0) {
// if we didn't find a cachefile, then we don't have to do anything.
return 0;
}
DBT keydbt, valdbt;
toku_fill_dbt(&keydbt, l->key.data, l->key.len);
toku_fill_dbt(&valdbt, l->value.data, l->value.len);
r = toku_brt_maybe_insert(tuple->brt, &keydbt, &valdbt, txn, TRUE, l->lsn, FALSE, BRT_INSERT_NO_OVERWRITE);
assert(r == 0);
return 0;
}
static int toku_recover_backward_enq_insert_no_overwrite (struct logtype_enq_insert_no_overwrite *UU(l), RECOVER_ENV UU(renv)) {
// nothing
return 0;
}
static int toku_recover_enq_insert_multiple (struct logtype_enq_insert_multiple *l, RECOVER_ENV renv) { static int toku_recover_enq_insert_multiple (struct logtype_enq_insert_multiple *l, RECOVER_ENV renv) {
int r; int r;
TOKUTXN txn = NULL; TOKUTXN txn = NULL;
...@@ -521,7 +551,7 @@ static int toku_recover_enq_insert_multiple (struct logtype_enq_insert_multiple ...@@ -521,7 +551,7 @@ static int toku_recover_enq_insert_multiple (struct logtype_enq_insert_multiple
DB *db = tuple->brt->db; DB *db = tuple->brt->db;
r = renv->generate_row_for_put(db, src_db, &dest_key, &dest_val, &src_key, &src_val, NULL); r = renv->generate_row_for_put(db, src_db, &dest_key, &dest_val, &src_key, &src_val, NULL);
assert(r==0); assert(r==0);
r = toku_brt_maybe_insert(tuple->brt, &dest_key, &dest_val, txn, TRUE, l->lsn, FALSE); r = toku_brt_maybe_insert(tuple->brt, &dest_key, &dest_val, txn, TRUE, l->lsn, FALSE, BRT_INSERT);
assert(r == 0); assert(r == 0);
//flags==0 indicates the return values are stored in temporary memory that does //flags==0 indicates the return values are stored in temporary memory that does
//not need to be freed. We need to continue using DB_DBT_REALLOC however. //not need to be freed. We need to continue using DB_DBT_REALLOC however.
......
...@@ -154,6 +154,13 @@ msg_modify_ule(ULE ule, BRT_MSG msg) { ...@@ -154,6 +154,13 @@ msg_modify_ule(ULE ule, BRT_MSG msg) {
ule_do_implicit_promotions(ule, xids); ule_do_implicit_promotions(ule, xids);
enum brt_msg_type type = brt_msg_get_type(msg); enum brt_msg_type type = brt_msg_get_type(msg);
switch (type) { switch (type) {
case BRT_INSERT_NO_OVERWRITE: {
UXR old_innermost_uxr = ule_get_innermost_uxr(ule);
//If something exists, quit (no overwrite).
if (uxr_is_insert(old_innermost_uxr)) break;
//else it is just an insert, so
//fall through to BRT_INSERT on purpose.
}
case BRT_INSERT: ; case BRT_INSERT: ;
u_int32_t vallen = brt_msg_get_vallen(msg); u_int32_t vallen = brt_msg_get_vallen(msg);
void * valp = brt_msg_get_val(msg); void * valp = brt_msg_get_val(msg);
......
...@@ -4259,6 +4259,9 @@ db_put_check_overwrite_constraint(DB *db, DB_TXN *txn, DBT *key, DBT *UU(val), ...@@ -4259,6 +4259,9 @@ db_put_check_overwrite_constraint(DB *db, DB_TXN *txn, DBT *key, DBT *UU(val),
r = toku_ydb_do_error(db->dbenv, EINVAL, "Tokudb requires that db->put specify DB_YESOVERWRITE or DB_NOOVERWRITE on DB_DUPSORT databases"); r = toku_ydb_do_error(db->dbenv, EINVAL, "Tokudb requires that db->put specify DB_YESOVERWRITE or DB_NOOVERWRITE on DB_DUPSORT databases");
} }
} }
else if (overwrite_flag==DB_NOOVERWRITE_NO_ERROR) {
r = 0;
}
else { else {
//Other flags are not (yet) supported. //Other flags are not (yet) supported.
r = EINVAL; r = EINVAL;
...@@ -4293,7 +4296,11 @@ toku_db_put(DB *db, DB_TXN *txn, DBT *key, DBT *val, u_int32_t flags) { ...@@ -4293,7 +4296,11 @@ toku_db_put(DB *db, DB_TXN *txn, DBT *key, DBT *val, u_int32_t flags) {
} }
if (r==0) { if (r==0) {
//Insert into the brt. //Insert into the brt.
r = toku_brt_insert(db->i->brt, key, val, txn ? db_txn_struct_i(txn)->tokutxn : 0); TOKUTXN ttxn = txn ? db_txn_struct_i(txn)->tokutxn : NULL;
enum brt_msg_type type = BRT_INSERT;
if (flags==DB_NOOVERWRITE_NO_ERROR)
type = BRT_INSERT_NO_OVERWRITE;
r = toku_brt_maybe_insert(db->i->brt, key, val, ttxn, FALSE, ZERO_LSN, TRUE, type);
} }
return r; return r;
} }
...@@ -4326,6 +4333,11 @@ env_put_multiple(DB_ENV *env, DB *src_db, DB_TXN *txn, const DBT *key, const DBT ...@@ -4326,6 +4333,11 @@ env_put_multiple(DB_ENV *env, DB *src_db, DB_TXN *txn, const DBT *key, const DBT
&keys[which_db], &vals[which_db], &keys[which_db], &vals[which_db],
lock_flags[which_db], remaining_flags[which_db]); lock_flags[which_db], remaining_flags[which_db]);
if (r!=0) goto cleanup; if (r!=0) goto cleanup;
if (remaining_flags[which_db] == DB_NOOVERWRITE_NO_ERROR) {
//put_multiple does not support delaying the no error, since we would
//have to log the flag in the put_multiple.
r = EINVAL; goto cleanup;
}
//Do locking if necessary. //Do locking if necessary.
if (db->i->lt && !(lock_flags[which_db] & DB_PRELOCKED_WRITE)) { if (db->i->lt && !(lock_flags[which_db] & DB_PRELOCKED_WRITE)) {
//Needs locking //Needs locking
...@@ -4346,7 +4358,7 @@ env_put_multiple(DB_ENV *env, DB *src_db, DB_TXN *txn, const DBT *key, const DBT ...@@ -4346,7 +4358,7 @@ env_put_multiple(DB_ENV *env, DB *src_db, DB_TXN *txn, const DBT *key, const DBT
for (which_db = 0; which_db < num_dbs; which_db++) { for (which_db = 0; which_db < num_dbs; which_db++) {
DB *db = db_array[which_db]; DB *db = db_array[which_db];
num_inserts++; num_inserts++;
r = toku_brt_maybe_insert(db->i->brt, &keys[which_db], &vals[which_db], ttxn, FALSE, ZERO_LSN, FALSE); r = toku_brt_maybe_insert(db->i->brt, &keys[which_db], &vals[which_db], ttxn, FALSE, ZERO_LSN, FALSE, BRT_INSERT);
if (r!=0) goto cleanup; if (r!=0) goto cleanup;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment