I want to add even more input for this issue.
I understand why there is implicit savepoint, when I remove row from 'parent'
table.
But why is this also true for a 'child' table when I perform 'INSERT OR
REPLACE'?
Removing FK reference disables journal growth. I don't understand...
I have a new test application.
As before, to compile:
# clang -o test -L/usr/local/lib -lsqlite3 test.c
Still, I do not understand, why does extra transaction (nested savepoint)
matters.
test.c
#include <stdio.h>
#include <stdlib.h>
#include <sqlite3.h>
#include <unistd.h>
#include <string.h>
int main(int argc, char ** argv)
{
const char * database_file = "/tmp/memusage_test_db";
// Clear old database file is there is one.
unlink(database_file);
sqlite3 * db = NULL;
if (sqlite3_open(database_file, &db) != SQLITE_OK)
return 1;
// Set busy timeout just in case...
if (sqlite3_busy_timeout(db, 10000) != SQLITE_OK) {
sqlite3_close(db);
return 1;
}
// Set pragmas.
if (sqlite3_exec(db,
" PRAGMA page_size = 4096;"
" PRAGMA temp_store = MEMORY;"
" PRAGMA journal_mode = MEMORY;"
" PRAGMA cache_size = 10000;"
" PRAGMA foreign_keys = ON;"
" PRAGMA synchronous = OFF;",
NULL, NULL, NULL) != SQLITE_OK) {
sqlite3_close(db);
return 1;
}
// Create database structure.
if (sqlite3_exec(db,
"CREATE TABLE foo ("
" id INTEGER,"
" x INTEGER,"
" PRIMARY KEY(id)"
");"
""
"CREATE TABLE bar ("
" id INTEGER,"
" y INTEGER,"
" PRIMARY KEY(id, y),"
" FOREIGN KEY(id) REFERENCES foo(id) ON DELETE CASCADE"
");",
NULL, NULL, NULL) != SQLITE_OK) {
sqlite3_close(db);
return 1;
}
// Populate database with data.
{
// Open transaction.
if (sqlite3_exec(db, "BEGIN IMMEDIATE;", NULL, NULL, NULL) !=
SQLITE_OK) {
sqlite3_close(db);
return 1;
}
if (sqlite3_exec(db, "SAVEPOINT XXX;", NULL, NULL, NULL) != SQLITE_OK) {
sqlite3_close(db);
return 1;
}
char buffer[256];
for (int i = 0; i < 100000; ++i) {
snprintf(buffer, sizeof(buffer), "INSERT INTO foo(id, x) VALUES(%u,
%u)", i + 1, 2 * i + 1);
if (sqlite3_exec(db, buffer, NULL, NULL, NULL) != SQLITE_OK) {
sqlite3_close(db);
return 1;
}
#ifndef NO_CHILD_RECORDS
snprintf(buffer, sizeof(buffer), "INSERT OR REPLACE INTO bar(id, y)
VALUES(%u, %u)", i + 1, 2 * i + 1);
if (sqlite3_exec(db, buffer, NULL, NULL, NULL) != SQLITE_OK) {
sqlite3_close(db);
return 1;
}
#endif
}
// Rollback savepoint (no need to commit anything).
if (sqlite3_exec(db, "ROLLBACK TO SAVEPOINT XXX;", NULL, NULL, NULL) !=
SQLITE_OK) {
sqlite3_close(db);
return 1;
}
// Commit transaction.
if (sqlite3_exec(db, "COMMIT;", NULL, NULL, NULL) != SQLITE_OK) {
sqlite3_close(db);
return 1;
}
}
sqlite3_close(db);
// Dump memory usage statistics.
int current_mem = 0;
int hi_mem = 0;
sqlite3_status(SQLITE_STATUS_MEMORY_USED, ¤t_mem, &hi_mem, 0);
printf("Current mem: %u\nHi mem: %u\n", current_mem, hi_mem);
// Do not leave database file behind.
unlink(database_file);
return 0;
}
_______________________________________________
sqlite-users mailing list
[email protected]
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users