From 10a6439e657f9ef6268785544d55be6e4976acc7 Mon Sep 17 00:00:00 2001 From: Codechicken Date: Wed, 26 Nov 2025 23:00:35 -0500 Subject: [PATCH 1/3] Use without-rowid tables to reduce disk space use --- src/include/souffle/io/WriteStreamSQLite.h | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/include/souffle/io/WriteStreamSQLite.h b/src/include/souffle/io/WriteStreamSQLite.h index 240b6da2252..7fb2900591a 100644 --- a/src/include/souffle/io/WriteStreamSQLite.h +++ b/src/include/souffle/io/WriteStreamSQLite.h @@ -199,14 +199,30 @@ class WriteStreamSQLite : public WriteStream { void createRelationTable() { std::stringstream createTableText; createTableText << "CREATE TABLE IF NOT EXISTS '_" << relationName << "' ("; + // 8 bytes per datum worst case + 1 byte per datum in header + 1 byte header length < ~1/20 DB page + // size See https://sqlite.org/withoutrowid.html#when_to_use_without_rowid and + // https://sqlite.org/fileformat2.html#record_format for justification + bool shouldUseWithoutRowid = (arity * 9 + 1) < 200; if (arity > 0) { createTableText << "'0' INTEGER"; for (unsigned int i = 1; i < arity; i++) { createTableText << ",'" << std::to_string(i) << "' "; createTableText << "INTEGER"; } + if (shouldUseWithoutRowid) { + createTableText << ", PRIMARY KEY ("; + createTableText << "'0'"; + for (unsigned int i = 1; i < arity; i++) { + createTableText << ",'" << std::to_string(i) << "' "; + } + createTableText << ")"; + } + } + if (shouldUseWithoutRowid) { + createTableText << ") WITHOUT ROWID;"; + } else { + createTableText << ");"; } - createTableText << ");"; executeSQL(createTableText.str(), db); executeSQL("DELETE FROM '_" + relationName + "';", db); } From a7ac2c65f3c44247af70fbc7a5c44c852277ee6e Mon Sep 17 00:00:00 2001 From: Codechicken Date: Thu, 27 Nov 2025 21:55:01 -0500 Subject: [PATCH 2/3] Simplify selection of without rowid tables --- src/include/souffle/io/WriteStreamSQLite.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/include/souffle/io/WriteStreamSQLite.h b/src/include/souffle/io/WriteStreamSQLite.h index 7fb2900591a..e0f1ac69348 100644 --- a/src/include/souffle/io/WriteStreamSQLite.h +++ b/src/include/souffle/io/WriteStreamSQLite.h @@ -199,10 +199,11 @@ class WriteStreamSQLite : public WriteStream { void createRelationTable() { std::stringstream createTableText; createTableText << "CREATE TABLE IF NOT EXISTS '_" << relationName << "' ("; - // 8 bytes per datum worst case + 1 byte per datum in header + 1 byte header length < ~1/20 DB page + // 8 bytes per datum worst case + 1 byte per datum in header + 1 byte header length < ~1/20 DB page (4096 bytes) // size See https://sqlite.org/withoutrowid.html#when_to_use_without_rowid and // https://sqlite.org/fileformat2.html#record_format for justification - bool shouldUseWithoutRowid = (arity * 9 + 1) < 200; + // 22*9+1 = 199 < 200 + bool shouldUseWithoutRowid = (arity>0 && arity<23); if (arity > 0) { createTableText << "'0' INTEGER"; for (unsigned int i = 1; i < arity; i++) { From 2482112865e3b48217e50ff60600ae477009234e Mon Sep 17 00:00:00 2001 From: Codechicken Date: Wed, 10 Dec 2025 07:23:14 -0500 Subject: [PATCH 3/3] Fix formatting --- src/include/souffle/io/WriteStreamSQLite.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/include/souffle/io/WriteStreamSQLite.h b/src/include/souffle/io/WriteStreamSQLite.h index e0f1ac69348..60cc70c031f 100644 --- a/src/include/souffle/io/WriteStreamSQLite.h +++ b/src/include/souffle/io/WriteStreamSQLite.h @@ -199,11 +199,11 @@ class WriteStreamSQLite : public WriteStream { void createRelationTable() { std::stringstream createTableText; createTableText << "CREATE TABLE IF NOT EXISTS '_" << relationName << "' ("; - // 8 bytes per datum worst case + 1 byte per datum in header + 1 byte header length < ~1/20 DB page (4096 bytes) - // size See https://sqlite.org/withoutrowid.html#when_to_use_without_rowid and + // 8 bytes per datum worst case + 1 byte per datum in header + 1 byte header length < ~1/20 DB page + // (4096 bytes) size See https://sqlite.org/withoutrowid.html#when_to_use_without_rowid and // https://sqlite.org/fileformat2.html#record_format for justification - // 22*9+1 = 199 < 200 - bool shouldUseWithoutRowid = (arity>0 && arity<23); + // 22*9+1 = 199 < 200 + bool shouldUseWithoutRowid = (arity > 0 && arity < 23); if (arity > 0) { createTableText << "'0' INTEGER"; for (unsigned int i = 1; i < arity; i++) {