diff --git a/manifest b/manifest
index 19f4d37fde..5d7ac80310 100644
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C The\scontent\scolumns\sof\sthe\sindex-btree\sthat\simplements\sa\sWITHOUT\sROWID\ntable\sare\snot\sordered\sand\sso\sthe\squery\splanner\sshould\snot\sassume\sthey\nare\sordered.\s\sFix\sfor\sthe\sissue\sidentified\sby\n[forum:/forumpost/6c8960f545|forum\spost\s6c8960f545].
-D 2021-05-13T13:43:40.565
+C Modify\sthe\ssqlite3_stmt_readonly()\sinterface\sso\sthat\sit\sreturns\sfalse\sfor\nCREATE\sTABLE\sIF\sNOT\sEXISTS\sstatements\seven\sif\sthe\stable\salready\sexists\sand\nthe\sstatement\sis\sreally\sa\sread-only\sno-op.\s\sLikewise\sfor\sDROP\sTABLE,\s\nCREATE\sINDEX,\sand\sDROP\sINDEX.\s\sUpdate\sthe\sdocumentation\sfor\nsqlite3_stmt_readonly()\sto\sreflect\sthis\snew\sbehavior.
+D 2021-05-13T18:24:22.567
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -487,7 +487,7 @@ F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6
 F src/btree.c 5372d8bca3374145477e129be5ed6e907731e1d117c0dc1b524b536f1cc0e577
 F src/btree.h 096cc53baa58be22b02c896d1cf933c38cfc6d65f9253c1367ece8cc88a24de5
 F src/btreeInt.h 7bc15a24a02662409ebcd6aeaa1065522d14b7fda71573a2b0568b458f514ae0
-F src/build.c bf4f76eb77ff0193ef826f9dbd0285e8b55fe8ecb24d1f6b14bf72b68df6a422
+F src/build.c a7866beda66a7c8971e013674c7f659d19977d9ad51e11032479b1f754d1ef21
 F src/callback.c d0b853dd413255d2e337b34545e54d888ea02f20da5ad0e63585b389624c4a6c
 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
 F src/ctime.c 2a322b9a3d75771fb4d99e0702851f4f68dda982507a0f798eefb0712969a410
@@ -545,7 +545,7 @@ F src/resolve.c c38bbb89d7ba7a8673ec4f59b63e0980eb859c39ff2acc5df8b3d0f2dcd33115
 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92
 F src/select.c 57dbb27e0d0cb2438487c797365a4c17294d0df3c25c970ca87f123105f33ed0
 F src/shell.c.in 1b32ba2918ede13b68df47c7b92b72ba0d06e68d384e78bb9d7456527271d400
-F src/sqlite.h.in c0969405cc053220ebf81d487c5851007928e45e487237dd23435d13c25daab0
+F src/sqlite.h.in 5c950066775ca9efdaa49077c05d38d0bef6418f3bd07d2dce0210f1d2f3c326
 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
 F src/sqlite3ext.h 61b38c073d5e1e96a3d45271b257aef27d0d13da2bea5347692ae579475cd95e
 F src/sqliteInt.h 2b1cbc7f78346ac83ea962e5daf6a201e223cf1902e0cfde54f37cf3d82fcc24
@@ -1913,7 +1913,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
 F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P b2b0e23ba885f22c88b03492e42c3cd1cbd59289e452263951bb757a871699f0
-R 764f06f91ab95ce9134e7e810a3df5f2
+P c21bc5a2353e660f2acf5ed916921a4ee416910d0b3f2deb512a05c54138d1c0
+R 2e9914ba2c75f0fbf85c89829a93e146
 U drh
-Z 2bf41f499ef008f771df581659494cf8
+Z 708e967733b505d5e67438dc1caa81fb
diff --git a/manifest.uuid b/manifest.uuid
index b0a4922dc2..a7972e9082 100644
--- a/manifest.uuid
+++ b/manifest.uuid
@@ -1 +1 @@
-c21bc5a2353e660f2acf5ed916921a4ee416910d0b3f2deb512a05c54138d1c0
\ No newline at end of file
+cf8eb465974e596a13df56f3efbc98e098e7b74de9af4fde9ad58312db9750e4
\ No newline at end of file
diff --git a/src/build.c b/src/build.c
index d86b506d62..6339a97849 100644
--- a/src/build.c
+++ b/src/build.c
@@ -1048,6 +1048,22 @@ i16 sqlite3TableColumnToStorage(Table *pTab, i16 iCol){
 }
 #endif
 
+/*
+** Insert a single OP_JournalMode query opcode in order to force the
+** prepared statement to return false for sqlite3_stmt_readonly().  This
+** is used by CREATE TABLE IF NOT EXISTS and similar if the table already
+** exists, so that the prepared statement for CREATE TABLE IF NOT EXISTS
+** will return false for sqlite3_stmt_readonly() even if that statement
+** is a read-only no-op.
+*/
+static void sqlite3ForceNotReadOnly(Parse *pParse){
+  int iReg = ++pParse->nMem;
+  Vdbe *v = sqlite3GetVdbe(pParse);
+  if( v ){
+    sqlite3VdbeAddOp3(v, OP_JournalMode, 0, iReg, PAGER_JOURNALMODE_QUERY);
+  }
+}
+
 /*
 ** Begin constructing a new table representation in memory.  This is
 ** the first of several action routines that get called in response
@@ -1147,6 +1163,7 @@ void sqlite3StartTable(
       }else{
         assert( !db->init.busy || CORRUPT_DB );
         sqlite3CodeVerifySchema(pParse, iDb);
+        sqlite3ForceNotReadOnly(pParse);
       }
       goto begin_table_error;
     }
@@ -3197,7 +3214,10 @@ void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView, int noErr){
   if( noErr ) db->suppressErr--;
 
   if( pTab==0 ){
-    if( noErr ) sqlite3CodeVerifyNamedSchema(pParse, pName->a[0].zDatabase);
+    if( noErr ){
+      sqlite3CodeVerifyNamedSchema(pParse, pName->a[0].zDatabase);
+      sqlite3ForceNotReadOnly(pParse);
+    }
     goto exit_drop_table;
   }
   iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
@@ -3767,6 +3787,7 @@ void sqlite3CreateIndex(
         }else{
           assert( !db->init.busy );
           sqlite3CodeVerifySchema(pParse, iDb);
+          sqlite3ForceNotReadOnly(pParse);
         }
         goto exit_create_index;
       }
@@ -4285,6 +4306,7 @@ void sqlite3DropIndex(Parse *pParse, SrcList *pName, int ifExists){
       sqlite3ErrorMsg(pParse, "no such index: %S", pName->a);
     }else{
       sqlite3CodeVerifyNamedSchema(pParse, pName->a[0].zDatabase);
+      sqlite3ForceNotReadOnly(pParse);
     }
     pParse->checkSchema = 1;
     goto exit_drop_index;
diff --git a/src/sqlite.h.in b/src/sqlite.h.in
index 06bcf008e5..ef452e3244 100644
--- a/src/sqlite.h.in
+++ b/src/sqlite.h.in
@@ -4198,6 +4198,15 @@ const char *sqlite3_normalized_sql(sqlite3_stmt *pStmt);
 ** [BEGIN] merely sets internal flags, but the [BEGIN|BEGIN IMMEDIATE] and
 ** [BEGIN|BEGIN EXCLUSIVE] commands do touch the database and so
 ** sqlite3_stmt_readonly() returns false for those commands.
+**
+** ^This routine returns false if there is any possibility that the
+** statement might change the database file.  ^A false return does
+** not guarantee that the statement will change the database file.
+** ^For example, an UPDATE statement might have a WHERE clause that
+** makes it a no-op, but the sqlite3_stmt_readonly() result would still
+** be false.  ^Similarly, a CREATE TABLE IF NOT EXISTS statement is a
+** read-only no-op if the table already exists, but 
+** sqlite3_stmt_readonly() still returns false for such a statement.
 */
 int sqlite3_stmt_readonly(sqlite3_stmt *pStmt);