]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Have ALTER TABLE RENAME COLUMN and DROP COLUMN use sqlite_rename_quotefix() to conver...
authordan <Dan Kennedy>
Tue, 16 Mar 2021 16:14:48 +0000 (16:14 +0000)
committerdan <Dan Kennedy>
Tue, 16 Mar 2021 16:14:48 +0000 (16:14 +0000)
FossilOrigin-Name: 6446c0961077396086251670102ea7bf17d54a6b0f0ca56c6af89028a1ff9039

manifest
manifest.uuid
src/alter.c
test/alterauth2.test
test/altercol.test

index 1e4bac5ad73891e87588980f6ce691330b3c0293..2a42d587a190e329090fa1abb3653c1114f38149 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Merge\strunk\schanges\sinto\sthis\sbranch.
-D 2021-03-16T11:21:36.460
+C Have\sALTER\sTABLE\sRENAME\sCOLUMN\sand\sDROP\sCOLUMN\suse\ssqlite_rename_quotefix()\sto\sconvert\sany\sdouble-quoted\sstrings\sin\sthe\sdatabase\sschema\sto\stheir\ssingle-quoted\sequivalents.
+D 2021-03-16T16:14:48.466
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -476,7 +476,7 @@ F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca
 F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b
 F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786
 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a
-F src/alter.c 36ff6fed67e383e65238e0a063795f0645a3eb3420cdacc3463d822874ecc06a
+F src/alter.c 4f2c88554c65dea16cc5fb37ba464a4ec23147e51d87d22651f96a39fdbe2134
 F src/analyze.c 01c6c6765cb4d40b473b71d85535093730770bb186f2f473abac25f07fcdee5c
 F src/attach.c 9cbe761e464025694df8e6f6ee4d9f41432c3a255ca9443ccbb4130eeb87cf72
 F src/auth.c 08954fdc4cc2da5264ba5b75cfd90b67a6fc7d1710a02ccf917c38eadec77853
@@ -646,8 +646,8 @@ F test/alter2.test a966ccfcddf9ce0a4e0e6ff1aca9e6e7948e0e242cd7e43fc091948521807
 F test/alter3.test e487958dec7932453e0b83baf21d6b1e71d5e7d9a55bc20eadfa62a51ddffc29
 F test/alter4.test dfd6086faf461b27ca2d2999848dcd207edf23352fc1592d0005c0844f3f08cf
 F test/alterauth.test 63442ba61ceb0c1eeb63aac1f4f5cebfa509d352276059d27106ae256bafc959
-F test/alterauth2.test 794ac5cef251819fe364b4fe20f12f86e9c5d68070513c7fd26c17cb244c89af
-F test/altercol.test 3456f7cc4196ef8f7d82d245d6e91940eb12bc95c36c91ac4b512f6b5c9a4fa9
+F test/alterauth2.test 381b1ab603c9ef96314a3158528ea17f7964449385a28eeaf8191120b2e24a8d
+F test/altercol.test 91f4eb0023d90beee000c06d45f521e07a2444d013b83381c62e88d5f209560f
 F test/altercorrupt.test 584d707a80e106952d6382790c8919bcf9f0db678ed3a1c09fd98b7f9d1d3a10
 F test/alterdropcol.test 596623cb8a72d9570bfb8417b0f302810efe007873796f03c17a9e9ff28dade1
 F test/alterdropcol2.test 527fce683b200d620f560f666c44ae33e22728e990a10a48a543280dfd4b4d41
@@ -1911,7 +1911,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 d874b300463ce0bbb53b7e2f88c6a12893e4fd751fcc7f810077ba108f4061ef 0e255b26872b50581d470952dd98e21dd82d081885006f58d49daa4b4576b35d
-R 5cdc3c3d5c2d0efb3f1add4791367d78
+P f15d51054afb1e3fec87938f2b04a5a0d0611b08248367850450de7c4166e3d1
+R ab802f6c03d96d9f26abdd92e7d8cf40
 U dan
-Z f7f517381588ea598ea089070b1ed19b
+Z cd13fbb96f280d93ac5264d668cf2de0
index 68fe878edccf3f753cdaa598edb4a95f5d25aaaa..40604b2022d2ce83deeb2d0601c280e7b42c10e1 100644 (file)
@@ -1 +1 @@
-f15d51054afb1e3fec87938f2b04a5a0d0611b08248367850450de7c4166e3d1
\ No newline at end of file
+6446c0961077396086251670102ea7bf17d54a6b0f0ca56c6af89028a1ff9039
\ No newline at end of file
index c46228e2cdd419804e48b22fbe94563337e25e49..016d019d3e5bab783b7b72c32ce1174bb025ab19 100644 (file)
@@ -53,7 +53,8 @@ static void renameTestSchema(
   Parse *pParse,                  /* Parse context */
   const char *zDb,                /* Name of db to verify schema of */
   int bTemp,                      /* True if this is the temp db */
-  const char *zWhen               /* "when" part of error message */
+  const char *zWhen,              /* "when" part of error message */
+  int bNoDQS                      /* Do not allow DQS in the schema */
 ){
   pParse->colNamesSet = 1;
   sqlite3NestedParse(pParse, 
@@ -61,9 +62,9 @@ static void renameTestSchema(
       "FROM \"%w\"." DFLT_SCHEMA_TABLE " "
       "WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X'"
       " AND sql NOT LIKE 'create virtual%%'"
-      " AND sqlite_rename_test(%Q, sql, type, name, %d, %Q)=NULL ",
+      " AND sqlite_rename_test(%Q, sql, type, name, %d, %Q, %d)=NULL ",
       zDb,
-      zDb, bTemp, zWhen
+      zDb, bTemp, zWhen, bNoDQS
   );
 
   if( bTemp==0 ){
@@ -72,8 +73,32 @@ static void renameTestSchema(
         "FROM temp." DFLT_SCHEMA_TABLE " "
         "WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X'"
         " AND sql NOT LIKE 'create virtual%%'"
-        " AND sqlite_rename_test(%Q, sql, type, name, 1, %Q)=NULL ",
-        zDb, zWhen
+        " AND sqlite_rename_test(%Q, sql, type, name, 1, %Q, %d)=NULL ",
+        zDb, zWhen, bNoDQS
+    );
+  }
+}
+
+/*
+** Generate VM code to replace any double-quoted strings (but not double-quoted
+** identifiers) within the "sql" column of the sqlite_schema table in 
+** database zDb with their single-quoted equivalents. If argument bTemp is
+** not true, similarly update all SQL statements in the sqlite_schema table
+** of the temp db.
+*/
+static void renameFixQuotes(Parse *pParse, const char *zDb, int bTemp){
+  sqlite3NestedParse(pParse, 
+      "UPDATE \"%w\"." DFLT_SCHEMA_TABLE 
+      " SET sql = sqlite_rename_quotefix(%Q, sql)"
+      "WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X'"
+      " AND sql NOT LIKE 'create virtual%%'" , zDb, zDb
+  );
+  if( bTemp==0 ){
+    sqlite3NestedParse(pParse, 
+      "UPDATE temp." DFLT_SCHEMA_TABLE
+      " SET sql = sqlite_rename_quotefix('temp', sql)"
+      "WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X'"
+      " AND sql NOT LIKE 'create virtual%%'"
     );
   }
 }
@@ -236,7 +261,7 @@ void sqlite3AlterRenameTable(
             "sql = sqlite_rename_table(%Q, type, name, sql, %Q, %Q, 1), "
             "tbl_name = "
               "CASE WHEN tbl_name=%Q COLLATE nocase AND "
-              "    sqlite_rename_test(%Q, sql, type, name, 1, 'after rename') "
+              "  sqlite_rename_test(%Q, sql, type, name, 1, 'after rename', 0) "
               "THEN %Q ELSE tbl_name END "
             "WHERE type IN ('view', 'trigger')"
         , zDb, zTabName, zName, zTabName, zDb, zName);
@@ -256,7 +281,7 @@ void sqlite3AlterRenameTable(
 #endif
 
   renameReloadSchema(pParse, iDb, INITFLAG_AlterRename);
-  renameTestSchema(pParse, zDb, iDb==1, "after rename");
+  renameTestSchema(pParse, zDb, iDb==1, "after rename", 0);
 
 exit_rename_table:
   sqlite3SrcListDelete(db, pSrc);
@@ -595,6 +620,10 @@ void sqlite3AlterRenameColumn(
     goto exit_rename_column;
   }
 
+  /* Ensure the schema contains no double-quoted strings */
+  renameTestSchema(pParse, zDb, iSchema==1, "", 0);
+  renameFixQuotes(pParse, zDb, iSchema==1);
+
   /* Do the rename operation using a recursive UPDATE statement that
   ** uses the sqlite_rename_column() SQL function to compute the new
   ** CREATE statement text for the sqlite_schema table.
@@ -624,7 +653,7 @@ void sqlite3AlterRenameColumn(
 
   /* Drop and reload the database schema. */
   renameReloadSchema(pParse, iSchema, INITFLAG_AlterRename);
-  renameTestSchema(pParse, zDb, iSchema==1, "after rename");
+  renameTestSchema(pParse, zDb, iSchema==1, "after rename", 1);
 
  exit_rename_column:
   sqlite3SrcListDelete(db, pSrc);
@@ -1847,6 +1876,7 @@ static void renameQuotefixFunc(
 **   3: Object name.
 **   4: True if object is from temp schema.
 **   5: "when" part of error message.
+**   6: True to disable the DQS quirk when parsing SQL.
 **
 ** Unless it finds an error, this function normally returns NULL. However, it
 ** returns integer value 1 if:
@@ -1865,6 +1895,7 @@ static void renameTableTest(
   int bTemp = sqlite3_value_int(argv[4]);
   int isLegacy = (db->flags & SQLITE_LegacyAlter);
   char const *zWhen = (const char*)sqlite3_value_text(argv[5]);
+  int bNoDQS = sqlite3_value_int(argv[6]);
 
 #ifndef SQLITE_OMIT_AUTHORIZATION
   sqlite3_xauth xAuth = db->xAuth;
@@ -1872,10 +1903,14 @@ static void renameTableTest(
 #endif
 
   UNUSED_PARAMETER(NotUsed);
+
   if( zDb && zInput ){
     int rc;
     Parse sParse;
+    int flags = db->flags;
+    if( bNoDQS ) db->flags &= ~(SQLITE_DqsDML|SQLITE_DqsDDL);
     rc = renameParseSql(&sParse, zDb, db, zInput, bTemp);
+    db->flags |= (flags & (SQLITE_DqsDML|SQLITE_DqsDDL));
     if( rc==SQLITE_OK ){
       if( isLegacy==0 && sParse.pNewTable && sParse.pNewTable->pSelect ){
         NameContext sNC;
@@ -2036,7 +2071,8 @@ void sqlite3AlterDropColumn(Parse *pParse, SrcList *pSrc, Token *pName){
   iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
   assert( iDb>=0 );
   zDb = db->aDb[iDb].zDbSName;
-  renameTestSchema(pParse, zDb, iDb==1, "");
+  renameTestSchema(pParse, zDb, iDb==1, "", 0);
+  renameFixQuotes(pParse, zDb, iDb==1);
   sqlite3NestedParse(pParse, 
       "UPDATE \"%w\"." DFLT_SCHEMA_TABLE " SET "
       "sql = sqlite_drop_column(%d, sql, %d) "
@@ -2046,7 +2082,7 @@ void sqlite3AlterDropColumn(Parse *pParse, SrcList *pSrc, Token *pName){
 
   /* Drop and reload the database schema. */
   renameReloadSchema(pParse, iDb, INITFLAG_AlterDrop);
-  renameTestSchema(pParse, zDb, iDb==1, "after drop column");
+  renameTestSchema(pParse, zDb, iDb==1, "after drop column", 1);
 
   /* Edit rows of table on disk */
   if( pParse->nErr==0 && (pTab->aCol[iCol].colFlags & COLFLAG_VIRTUAL)==0 ){
@@ -2106,7 +2142,7 @@ void sqlite3AlterFunctions(void){
   static FuncDef aAlterTableFuncs[] = {
     INTERNAL_FUNCTION(sqlite_rename_column,  9, renameColumnFunc),
     INTERNAL_FUNCTION(sqlite_rename_table,   7, renameTableFunc),
-    INTERNAL_FUNCTION(sqlite_rename_test,    6, renameTableTest),
+    INTERNAL_FUNCTION(sqlite_rename_test,    7, renameTableTest),
     INTERNAL_FUNCTION(sqlite_drop_column,    3, dropColumnFunc),
     INTERNAL_FUNCTION(sqlite_rename_quotefix,2, renameQuotefixFunc),
   };
index a411408b589a85f51ec320f80d7758d8afdf3c16..27ded1c3ea811f484eb81fe4cea24e1b508fde5a 100644 (file)
@@ -82,6 +82,7 @@ do_auth_test 1.2 {
   {SQLITE_ALTER_TABLE main t2 {} {}} 
   {SQLITE_FUNCTION {} like {} {}} 
   {SQLITE_FUNCTION {} sqlite_rename_column {} {}} 
+  {SQLITE_FUNCTION {} sqlite_rename_quotefix {} {}} 
   {SQLITE_FUNCTION {} sqlite_rename_test {} {}} 
   {SQLITE_READ sqlite_master name main {}} 
   {SQLITE_READ sqlite_master sql main {}} 
@@ -100,6 +101,7 @@ do_auth_test 1.3 {
 } {
   {SQLITE_FUNCTION {} like {} {}} 
   {SQLITE_FUNCTION {} sqlite_drop_column {} {}}
+  {SQLITE_FUNCTION {} sqlite_rename_quotefix {} {}} 
   {SQLITE_FUNCTION {} sqlite_rename_test {} {}} 
   {SQLITE_READ sqlite_master name main {}} 
   {SQLITE_READ sqlite_master sql main {}} 
@@ -110,6 +112,7 @@ do_auth_test 1.3 {
   {SQLITE_READ sqlite_temp_master type temp {}} 
   {SQLITE_SELECT {} {} {} {}} 
   {SQLITE_UPDATE sqlite_master sql main {}}
+  {SQLITE_UPDATE sqlite_temp_master sql temp {}}
 }
 
 finish_test
index 047917e5a197679cf1deb497a579a4baa1ec8fe9..f2063e45ca0592968a67913345c98bf754c2fdbc 100644 (file)
@@ -567,7 +567,7 @@ do_execsql_test 13.1.6 {
 
 do_catchsql_test 13.1.7 {
   ALTER TABLE x1 RENAME COLUMN t TO ttt;
-} {1 {database disk image is malformed}}
+} {1 {error in index x1i: }}
 
 do_execsql_test 13.1.8 {
   DELETE FROM sqlite_master WHERE name = 'x1i';
@@ -835,5 +835,18 @@ do_execsql_test 22.0 {
   {CREATE TABLE t2(c, othername, extra AS (c + 1))}
 }
 
+#-------------------------------------------------------------------------
+#
+reset_db
+do_execsql_test 22.0 {
+  CREATE TABLE t1(a, b);
+  CREATE INDEX x1 on t1("c"=b);
+  INSERT INTO t1 VALUES('a', 'a');
+  INSERT INTO t1 VALUES('b', 'b');
+  INSERT INTO t1 VALUES('c', 'c');
+  ALTER TABLE t1 RENAME COLUMN a TO "c";
+  PRAGMA integrity_check;
+} {ok}
+
 
 finish_test