SQLite Forum

iOS 14 - table sqlite_master may not be modified

iOS 14 - table sqlite_master may not be modified

(1.1) By James (JamesMc) on 2020-10-21 10:55:02 edited from 1.0 [source]


I have an application which modifies the database structure by manipulating the sqlite_master table directly following the instructions on https://sqlite.org/lang_altertable.html#making_other_kinds_of_table_schema_changes

This has been working successfully for several years but with iOS 14 this process fails with the following exception.

Error Domain=FMDatabase Code=1 "table sqlite_master may not be modified" UserInfo={NSLocalizedDescription=table sqlite_master may not be modified})
sql 'UPDATE sqlite_master SET sql = replace(sql, 'cloud_file_id INT,', 'cloud_file_id INT REFERENCES cloudfile (id),') WHERE name = 'attachment' AND type = 'table'' args []}

I have checked that I am setting pragma writable_schema = ON by querying pragma writable_schema, it returns 1 (ON) but it still the update fails.

From scouring the documentation I was wondering if SQLITE_DBCONFIG_DEFENSIVE connection config property had been enabled but I can't see any way to determine this.

Are there any other reasons that sqlite_master cannot be written?

The version of SQLite iOS 14 is using is 3.32.3. I have successfully tested this process on iOS 12 & version 3.24.0 (I think), OSX & version 3.27.1 and Android & version 3.22.0

Many thanks for any help or guidance


(2.1) By James (JamesMc) on 2020-10-22 12:29:17 edited from 2.0 in reply to 1.1 [link] [source]


(3) By James (JamesMc) on 2020-10-22 12:28:57 in reply to 2.0 [link] [source]

Running the following directly after sqlite3_open_v2() has disabled the defensive mode

int bDefensive;
sqlite3_db_config(_db, SQLITE_DBCONFIG_DEFENSIVE, 0, &bDefensive);
if ( bDefensive == SQLITE_OK ){
  NSLog(@"Connection defensive mode deactivated\n");
} else {
  NSLog(@"Connection defensive mode NOT deactivated\n");