I am aware that the use of SQLITE_UNTESTABLE is discouraged. Still I
want to point developers to the fact that SQLITE_UNTESTABLE breaks RBU.
In particular, RBU relies on SQLITE_TESTCTRL_IMPOSTER to be fully
working. With SQLITE_UNTESTABLE defined, this is not the case. RBU
functions return errors not related to the problem. The target database
is not properly updated.
The C code below demonstrates this. It is based on rbusplit.test
(https://www.sqlite.org/src/artifact/69271c790732b28b).
To see the problem, compile with the C preprocessor directive
SQLITE_UNTESTABLE=1 #defined. Tested with MS Visual Studio 2017.
Ralf
----------
#include <stdio.h>
#include <conio.h>
#include "sqlite3.h"
#include "sqlite3rbu.h"
sqlite3 *db;
static void check(int r, int e) {
if (r != e) {
printf("ERROR %d %s\n", e, sqlite3_errmsg(db));
}
}
static int callback(void *user, int nCol, char **r, char **c) {
int i;
for (i = 0; i < nCol; i++) {
printf("%s ", r[i]);
}
printf("\n");
return 0;
}
#define rbu_db "rbu.db"
#define target_db "target.db"
int main(void)
{
int r;
sqlite3rbu *rbu;
char *zError;
// Create rbu_db
remove(rbu_db);
check(SQLITE_OK, sqlite3_open_v2(rbu_db, &db,
SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL));
check(SQLITE_OK, sqlite3_exec(db,
"BEGIN;" \
"CREATE TABLE data0_t1(a, b, c, rbu_control);" \
"CREATE TABLE data1_t1(a, b, c, rbu_control);" \
"CREATE TABLE data2_t1(a, b, c, rbu_control);" \
"CREATE TABLE data3_t1(a, b, c, rbu_control);" \
"CREATE TABLE data_t2(a, b, c, rbu_control);" \
"INSERT INTO data0_t1 VALUES(1, 1, 1, 0);" \
"INSERT INTO data0_t1 VALUES(2, 2, 2, 0);" \
"INSERT INTO data0_t1 VALUES(3, 3, 3, 0);" \
"INSERT INTO data0_t1 VALUES(4, 4, 4, 0);" \
"INSERT INTO data1_t1 VALUES(5, 5, 5, 0);" \
"INSERT INTO data1_t1 VALUES(6, 6, 6, 0);" \
"INSERT INTO data1_t1 VALUES(7, 7, 7, 0);" \
"INSERT INTO data1_t1 VALUES(8, 8, 8, 0);" \
"INSERT INTO data3_t1 VALUES(9, 9, 9, 0);" \
"INSERT INTO data_t2 VALUES(1, 1, 1, 0);" \
"INSERT INTO data_t2 VALUES(2, 2, 2, 0);" \
"INSERT INTO data_t2 VALUES(3, 3, 3, 0);" \
"INSERT INTO data_t2 VALUES(4, 4, 4, 0);" \
"INSERT INTO data_t2 VALUES(5, 5, 5, 0);" \
"INSERT INTO data_t2 VALUES(6, 6, 6, 0);" \
"INSERT INTO data_t2 VALUES(7, 7, 7, 0);" \
"INSERT INTO data_t2 VALUES(8, 8, 8, 0);" \
"INSERT INTO data_t2 VALUES(9, 9, 9, 0);" \
"COMMIT;",
callback, NULL, NULL));
check(SQLITE_OK, sqlite3_close(db));
// Create target.db
remove(target_db);
check(SQLITE_OK, sqlite3_open_v2(target_db, &db,
SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL));
check(SQLITE_OK, sqlite3_exec(db,
"CREATE TABLE t1(a PRIMARY KEY, b, c);"
"CREATE TABLE t2(a PRIMARY KEY, b, c);" \
"CREATE INDEX t1c ON t1(c);",
callback, NULL, NULL));
check(SQLITE_OK, sqlite3_close(db));
// Apply RBU.
rbu = sqlite3rbu_open(target_db, rbu_db, NULL);
do
r = sqlite3rbu_step(rbu);
while (r == SQLITE_OK);
check(SQLITE_DONE, r);
r = sqlite3rbu_close(rbu, &zError);
check(SQLITE_DONE, r);
if (zError) {
printf("%s\n", zError);
sqlite3_free(zError);
}
printf("Done - Press ENTER to exit.");
_getch();
return 0;
}
_______________________________________________
sqlite-users mailing list
sqlite-users@mailinglists.sqlite.org
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users