@@ -199,14 +199,30 @@ class WriteStreamSQLite : public WriteStream {
199199 void createRelationTable () {
200200 std::stringstream createTableText;
201201 createTableText << " CREATE TABLE IF NOT EXISTS '_" << relationName << " ' (" ;
202+ // 8 bytes per datum worst case + 1 byte per datum in header + 1 byte header length < ~1/20 DB page
203+ // size See https://sqlite.org/withoutrowid.html#when_to_use_without_rowid and
204+ // https://sqlite.org/fileformat2.html#record_format for justification
205+ bool shouldUseWithoutRowid = (arity * 9 + 1 ) < 200 ;
202206 if (arity > 0 ) {
203207 createTableText << " '0' INTEGER" ;
204208 for (unsigned int i = 1 ; i < arity; i++) {
205209 createTableText << " ,'" << std::to_string (i) << " ' " ;
206210 createTableText << " INTEGER" ;
207211 }
212+ if (shouldUseWithoutRowid) {
213+ createTableText << " , PRIMARY KEY (" ;
214+ createTableText << " '0'" ;
215+ for (unsigned int i = 1 ; i < arity; i++) {
216+ createTableText << " ,'" << std::to_string (i) << " ' " ;
217+ }
218+ createTableText << " )" ;
219+ }
220+ }
221+ if (shouldUseWithoutRowid) {
222+ createTableText << " ) WITHOUT ROWID;" ;
223+ } else {
224+ createTableText << " );" ;
208225 }
209- createTableText << " );" ;
210226 executeSQL (createTableText.str (), db);
211227 executeSQL (" DELETE FROM '_" + relationName + " ';" , db);
212228 }
0 commit comments