diff --git a/buildheader/db.h_4_1 b/buildheader/db.h_4_1 index b8db03a7600..ab361f32efe 100644 --- a/buildheader/db.h_4_1 +++ b/buildheader/db.h_4_1 @@ -91,6 +91,7 @@ typedef enum { #define DB_DONOTINDEX -30999 #define DB_BADFORMAT -30500 #define DB_DELETE_ANY 65536 +#define DB_TRUNCATE_WITHCURSORS 131072 #define DB_FIRST 10 #define DB_GET_BOTH 11 #define DB_GET_BOTH_RANGE 13 diff --git a/buildheader/db.h_4_3 b/buildheader/db.h_4_3 index 1dbf25b154d..5e8bcb7a90f 100644 --- a/buildheader/db.h_4_3 +++ b/buildheader/db.h_4_3 @@ -92,6 +92,7 @@ typedef enum { #define DB_BUFFER_SMALL -30999 #define DB_BADFORMAT -30500 #define DB_DELETE_ANY 65536 +#define DB_TRUNCATE_WITHCURSORS 131072 #define DB_FIRST 9 #define DB_GET_BOTH 10 #define DB_GET_BOTH_RANGE 12 diff --git a/buildheader/db.h_4_4 b/buildheader/db.h_4_4 index 3e230033a23..4a44a11af13 100644 --- a/buildheader/db.h_4_4 +++ b/buildheader/db.h_4_4 @@ -93,6 +93,7 @@ typedef enum { #define DB_BUFFER_SMALL -30999 #define DB_BADFORMAT -30500 #define DB_DELETE_ANY 65536 +#define DB_TRUNCATE_WITHCURSORS 131072 #define DB_FIRST 9 #define DB_GET_BOTH 10 #define DB_GET_BOTH_RANGE 12 diff --git a/buildheader/db.h_4_5 b/buildheader/db.h_4_5 index 923d21bcfbc..b92388bfb2b 100644 --- a/buildheader/db.h_4_5 +++ b/buildheader/db.h_4_5 @@ -93,6 +93,7 @@ typedef enum { #define DB_BUFFER_SMALL -30999 #define DB_BADFORMAT -30500 #define DB_DELETE_ANY 65536 +#define DB_TRUNCATE_WITHCURSORS 131072 #define DB_FIRST 7 #define DB_GET_BOTH 8 #define DB_GET_BOTH_RANGE 10 diff --git a/buildheader/db.h_4_6 b/buildheader/db.h_4_6 index a7dd71afec8..550efb5a073 100644 --- a/buildheader/db.h_4_6 +++ b/buildheader/db.h_4_6 @@ -93,6 +93,7 @@ typedef enum { #define DB_BUFFER_SMALL -30999 #define DB_BADFORMAT -30500 #define DB_DELETE_ANY 65536 +#define DB_TRUNCATE_WITHCURSORS 131072 #define DB_FIRST 7 #define DB_GET_BOTH 8 #define DB_GET_BOTH_RANGE 10 diff --git a/buildheader/make_db_h.c b/buildheader/make_db_h.c index 9edf19e4f58..19e65f91461 100644 --- a/buildheader/make_db_h.c +++ b/buildheader/make_db_h.c @@ -101,6 +101,7 @@ void print_defines (void) { #endif printf("#define DB_BADFORMAT -30500\n"); // private tokudb printf("#define DB_DELETE_ANY %d\n", 1<<16); // private tokudb + printf("#define DB_TRUNCATE_WITHCURSORS %d\n", 1<<17); // private tokudb dodefine(DB_FIRST); dodefine(DB_GET_BOTH); diff --git a/buildheader/tdb.h b/buildheader/tdb.h index 14d05aeda86..6d7c9ec2ae8 100644 --- a/buildheader/tdb.h +++ b/buildheader/tdb.h @@ -93,6 +93,7 @@ typedef enum { #define DB_BUFFER_SMALL -30999 #define DB_BADFORMAT -30500 #define DB_DELETE_ANY 65536 +#define DB_TRUNCATE_WITHCURSORS 131072 #define DB_FIRST 7 #define DB_GET_BOTH 8 #define DB_GET_BOTH_RANGE 10 diff --git a/include/db.h b/include/db.h index 14d05aeda86..6d7c9ec2ae8 100644 --- a/include/db.h +++ b/include/db.h @@ -93,6 +93,7 @@ typedef enum { #define DB_BUFFER_SMALL -30999 #define DB_BADFORMAT -30500 #define DB_DELETE_ANY 65536 +#define DB_TRUNCATE_WITHCURSORS 131072 #define DB_FIRST 7 #define DB_GET_BOTH 8 #define DB_GET_BOTH_RANGE 10 diff --git a/src/tests/test_truncate_with_cursors.c b/src/tests/test_truncate_with_cursors.c index e1ac599dcec..eff3fed07cc 100644 --- a/src/tests/test_truncate_with_cursors.c +++ b/src/tests/test_truncate_with_cursors.c @@ -13,7 +13,7 @@ #include #ifdef USE_BDB -int test_errors = 0; +int test_errors; static void test_errcall (const DB_ENV *env __attribute__((__unused__)), const char *errpfx, const char *msg) { @@ -21,11 +21,15 @@ test_errcall (const DB_ENV *env __attribute__((__unused__)), const char *errpfx, test_errors++; } +#define DB_TRUNCATE_WITHCURSORS 0 #endif // try to truncate with cursors active static int -test_truncate_with_cursors (int n) { +test_truncate_with_cursors (int n, u_int32_t trunc_flag) { +#ifdef USE_BDB + test_errors = 0; +#endif int r; DB_ENV *env; @@ -72,7 +76,9 @@ test_truncate_with_cursors (int n) { assert(test_errors == 0); #endif u_int32_t row_count = 0; - r = db->truncate(db, 0, &row_count, 0); + r = db->truncate(db, 0, &row_count, trunc_flag); + + BOOL truncated = FALSE; #ifdef USE_BDB // It looks like for 4.6 there's no error code, even though the documentation says "it is an error to truncate with open cursors". // For 4.3 and 4.7 the error code is EINVAL @@ -83,13 +89,20 @@ test_truncate_with_cursors (int n) { assert(r == EINVAL && test_errors); } #else - assert(r == EINVAL); + if (trunc_flag == 0) + assert(r == EINVAL); + else { + assert(trunc_flag == DB_TRUNCATE_WITHCURSORS); + assert(r == 0); + truncated = TRUE; + } #endif r = cursor->c_close(cursor); assert(r == 0); - // ok, now try it - r = db->truncate(db, 0, &row_count, 0); assert(r == 0); + if (!truncated) { + r = db->truncate(db, 0, &row_count, 0); assert(r == 0); + } i = 0; r = db->cursor(db, 0, &cursor, 0); assert(r == 0); @@ -131,8 +144,14 @@ test_main(int argc, char *argv[]) { int nodesize = 1024*1024; int leafentry = 25; int n = (nodesize/leafentry) * 2; + int r; system("rm -rf " ENVDIR); toku_os_mkdir(ENVDIR, S_IRWXU+S_IRWXG+S_IRWXO); - int r = test_truncate_with_cursors(n); - return r; + r = test_truncate_with_cursors(n, 0); + CKERR(r); + system("rm -rf " ENVDIR); + toku_os_mkdir(ENVDIR, S_IRWXU+S_IRWXG+S_IRWXO); + r = test_truncate_with_cursors(n, DB_TRUNCATE_WITHCURSORS); + CKERR(r); + return 0; } diff --git a/src/ydb.c b/src/ydb.c index a34d0331d18..8bfee872c10 100644 --- a/src/ydb.c +++ b/src/ydb.c @@ -3545,11 +3545,18 @@ static int toku_db_truncate(DB *db, DB_TXN *txn, u_int32_t *row_count, u_int32_t HANDLE_PANICKED_DB(db); int r; + u_int32_t unhandled_flags = flags; + int ignore_cursors = 0; + if (flags & DB_TRUNCATE_WITHCURSORS) { + ignore_cursors = 1; + unhandled_flags &= ~DB_TRUNCATE_WITHCURSORS; + } + // dont support flags (yet) - if (flags) + if (unhandled_flags) return EINVAL; - // dont support cursors - if (toku_brt_get_cursor_count(db->i->brt) > 0) + // dont support cursors unless explicitly told to + if (!ignore_cursors && toku_brt_get_cursor_count(db->i->brt) > 0) return EINVAL; // acquire a table lock