]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Fix a problem with ALTER TABLE DROP COLUMN commands where the column being dropped...
authordan <Dan Kennedy>
Tue, 2 Dec 2025 14:43:59 +0000 (14:43 +0000)
committerdan <Dan Kennedy>
Tue, 2 Dec 2025 14:43:59 +0000 (14:43 +0000)
FossilOrigin-Name: c872bd1ee7b219e055f40e43766e4ed6bc2d2ca8cb92577cd3560f4173b1f257

manifest
manifest.uuid
src/alter.c
test/altertab3.test

index bc0447d3768b621dd63f9966a7fefb70334079af..c5099f5f3d3ecda02ac7479a13a012e746867742 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Add\sdeveloper\snote\son\show\sto\smeasure\scoverage\sof\sQRF.
-D 2025-12-02T12:23:24.524
+C Fix\sa\sproblem\swith\sALTER\sTABLE\sDROP\sCOLUMN\scommands\swhere\sthe\scolumn\sbeing\sdropped\sis\sthe\srightmost\sin\stable\sand\sis\simmediately\spreceded\sby\sa\scomment\scontaining\sa\s","\scharacter.
+D 2025-12-02T14:43:59.730
 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
@@ -669,7 +669,7 @@ F mptest/multiwrite01.test dab5c5f8f9534971efce679152c5146da265222d
 F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b
 F sqlite3.1 1b9c24374a85dfc7eb8fa7c4266ee0db4f9609cceecfc5481cd8307e5af04366
 F sqlite3.pc.in e6dee284fba59ef500092fdc1843df3be8433323a3733c91da96690a50a5b398
-F src/alter.c fe6fa35700b968f8f9d2515939455e70f6b6ff2586a6e3ce9827bf44756354f2
+F src/alter.c 49274beed71d31591c8de17404f31e53ed8798507c8b3016d6f15b8ec478b1e2
 F src/analyze.c 03bcfc083fc0cccaa9ded93604e1d4244ea245c17285d463ef6a60425fcb247d
 F src/attach.c 9af61b63b10ee702b1594ecd24fb8cea0839cfdb6addee52fba26fa879f5db9d
 F src/auth.c 54ab9c6c5803b47c0d45b76ce27eff22a03b4b1f767c5945a3a4eb13aa4c78dc
@@ -852,7 +852,7 @@ F test/altermalloc3.test 8040e486368403f2fdd6fc3998258b499bd4cc2f3ddbb5f8f874cd4
 F test/alterqf.test 8ec03d776de9c391daa0078ea8f838903bdcfb11dfae4ba3576b48436834ccba
 F test/altertab.test 8a2712f9076da5012a002d0b5cc0a421398a5bf61c25bab41b77c427586a7a27
 F test/altertab2.test 0889ba0700cc1cdb7bc7d25975aa61fece34f621de963d0886e2395716b38576
-F test/altertab3.test 471b8898d10bbc6488db9c23dc76811f405de6707d2d342b1b8b6fd1f13cd3c8
+F test/altertab3.test 575e771e2f02b13eb98798dc92eabacd187d6dbcf596e70f11d699b0b6b5d0b2
 F test/altertrig.test aacc980b657354fe2d3d4d3a004f07d04ccc1a93e5ef82d68a79088c274ddc6b
 F test/amatch1.test b5ae7065f042b7f4c1c922933f4700add50cdb9f
 F test/analyze.test 2fb21d7d64748636384e6cb8998dbf83968caf644c07fcb4f76c18f2e7ede94b
@@ -2181,8 +2181,8 @@ F tool/version-info.c 33d0390ef484b3b1cb685d59362be891ea162123cea181cb8e6d2cf6dd
 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7
 F tool/warnings.sh d924598cf2f55a4ecbc2aeb055c10bd5f48114793e7ba25f9585435da29e7e98
 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
-P 7e99e93cddeba555836206a278c5dcfd8565cc2a486a83cffab64dad168e9464
-R de758b56921e31817918b1313754b07f
-U drh
-Z cc3cfdbf6b5a72385cbc0d52882a934a
+P 0fdd453c03addb8f5c1e546f7513e3498bccd61266174ce99a61ceebf04e97cf
+R a05db7d00d43861c033636a6b23ea3b7
+U dan
+Z 7c7543e8fa4c87f35bf5869e2e4f8ba1
 # Remove this line to create a well-formed Fossil manifest.
index 519daae95e72ca9cf0544ebe0feabe2804c0c6ef..fd5dff5037a00f33c9010a917a5335544a76f83a 100644 (file)
@@ -1 +1 @@
-0fdd453c03addb8f5c1e546f7513e3498bccd61266174ce99a61ceebf04e97cf
+c872bd1ee7b219e055f40e43766e4ed6bc2d2ca8cb92577cd3560f4173b1f257
index 21b90abdb50804a59da090a268f9f2a0eb6403fd..2a23076753ae6f8f12a05ec670bf527de0a25438 100644 (file)
@@ -2114,6 +2114,57 @@ static void renameTableTest(
 #endif
 }
 
+
+/*
+** Return the number of bytes until the end of the next non-whitespace and
+** non-comment token.  For the purpose of this function, a "(" token includes
+** all of the bytes through and including the matching ")", or until the
+** first illegal token, whichever comes first.
+**
+** Write the token type into *piToken.
+**
+** The value returned is the number of bytes in the token itself plus
+** the number of bytes of leading whitespace and comments skipped plus
+** all bytes through the next matching ")" if the token is TK_LP.
+**
+** Example:    (Note: '.' used in place of '*' in the example z[] text)
+**
+**                                    ,--------- *piToken := TK_RP
+**                                    v
+**    z[] = " /.comment./ --comment\n (two three four) five"
+**          |                                        |
+**          |<-------------------------------------->|
+**                              |
+**                              `--- return value
+*/
+static int getConstraintToken(const u8 *z, int *piToken){
+  int iOff = 0;
+  int t = 0;
+  do {
+    iOff += sqlite3GetToken(&z[iOff], &t);
+  }while( t==TK_SPACE || t==TK_COMMENT );
+
+  *piToken = t;
+
+  if( t==TK_LP ){
+    int nNest = 1;
+    while( nNest>0 ){
+      iOff += sqlite3GetToken(&z[iOff], &t);
+      if( t==TK_LP ){
+        nNest++;
+      }else if( t==TK_RP ){
+        t = TK_LP;
+        nNest--;
+      }else if( t==TK_ILLEGAL ){
+        break;
+      }
+    }
+  }
+
+  *piToken = t;
+  return iOff;
+}
+
 /*
 ** The implementation of internal UDF sqlite_drop_column().
 **
@@ -2158,15 +2209,24 @@ static void dropColumnFunc(
     goto drop_column_done;
   }
 
-  pCol = renameTokenFind(&sParse, 0, (void*)pTab->aCol[iCol].zCnName);
   if( iCol<pTab->nCol-1 ){
     RenameToken *pEnd;
+    pCol = renameTokenFind(&sParse, 0, (void*)pTab->aCol[iCol].zCnName);
     pEnd = renameTokenFind(&sParse, 0, (void*)pTab->aCol[iCol+1].zCnName);
     zEnd = (const char*)pEnd->t.z;
   }else{
+    int eTok;
     assert( IsOrdinaryTable(pTab) );
+    assert( iCol!=0 );
+    /* Point pCol->t.z at the "," immediately preceding the definition of
+    ** the column being dropped. To do this, start at the name of the 
+    ** previous column, and tokenize until the next ",".  */
+    pCol = renameTokenFind(&sParse, 0, (void*)pTab->aCol[iCol-1].zCnName);
+    do {
+      pCol->t.z += getConstraintToken(pCol->t.z, &eTok);
+    }while( eTok!=TK_COMMA );
+    pCol->t.z--;
     zEnd = (const char*)&zSql[pTab->u.tab.addColOffset];
-    while( ALWAYS(pCol->t.z[0]!=0) && pCol->t.z[0]!=',' ) pCol->t.z--;
   }
 
   zNew = sqlite3MPrintf(db, "%.*s%s", pCol->t.z-zSql, zSql, zEnd);
@@ -2350,56 +2410,6 @@ static int getWhitespace(const u8 *z){
 }
 
 
-/*
-** Return the number of bytes until the end of the next non-whitespace and
-** non-comment token.  For the purpose of this function, a "(" token includes
-** all of the bytes through and including the matching ")", or until the
-** first illegal token, whichever comes first.
-**
-** Write the token type into *piToken.
-**
-** The value returned is the number of bytes in the token itself plus
-** the number of bytes of leading whitespace and comments skipped plus
-** all bytes through the next matching ")" if the token is TK_LP.
-**
-** Example:    (Note: '.' used in place of '*' in the example z[] text)
-**
-**                                    ,--------- *piToken := TK_RP
-**                                    v
-**    z[] = " /.comment./ --comment\n (two three four) five"
-**          |                                        |
-**          |<-------------------------------------->|
-**                              |
-**                              `--- return value
-*/
-static int getConstraintToken(const u8 *z, int *piToken){
-  int iOff = 0;
-  int t = 0;
-  do {
-    iOff += sqlite3GetToken(&z[iOff], &t);
-  }while( t==TK_SPACE || t==TK_COMMENT );
-
-  *piToken = t;
-
-  if( t==TK_LP ){
-    int nNest = 1;
-    while( nNest>0 ){
-      iOff += sqlite3GetToken(&z[iOff], &t);
-      if( t==TK_LP ){
-        nNest++;
-      }else if( t==TK_RP ){
-        t = TK_LP;
-        nNest--;
-      }else if( t==TK_ILLEGAL ){
-        break;
-      }
-    }
-  }
-
-  *piToken = t;
-  return iOff;
-}
-
 /*
 ** Argument z points into the body of a constraint - specifically the 
 ** second token of the constraint definition.  For a named constraint,
index 92060fb41c643e7e590101f6cf55ce38f33a5847..36e08c7694068b1faf666dd2c07740abccc1f20c 100644 (file)
@@ -778,4 +778,52 @@ do_execsql_test 31.2 {
   SELECT rr FROM t1 LIMIT 1
 } {5.0}
 
+#-------------------------------------------------------------------------
+reset_db
+do_execsql_test 32.1.0 {
+  CREATE TABLE t1(
+      a INT,
+      b INT,
+      -- comment with comma
+      c INT
+  );
+}
+do_execsql_test 32.1.1 {
+  ALTER TABLE t1 DROP COLUMN c;
+}
+do_execsql_test 32.1.2 {
+  SELECT sql FROM sqlite_schema
+} {{CREATE TABLE t1(
+      a INT,
+      b INT)}}
+
+reset_db
+do_execsql_test 32.2.0 {
+  CREATE TABLE t1(
+      a INT,
+      b INT,
+      -- comment with, comma
+      c INT
+  );
+}
+do_execsql_test 32.2.1 {
+  ALTER TABLE t1 DROP COLUMN c;
+}
+do_execsql_test 32.2.2 {
+  SELECT sql FROM sqlite_schema
+} {{CREATE TABLE t1(
+      a INT,
+      b INT)}}
+
+#-------------------------------------------------------------------------
+reset_db
+do_execsql_test 33.1 {
+  CREATE TABLE x1(a TEXT, b INTEGER, c CHECK(c!=0));
+}
+
+do_execsql_test 33.2 {
+  ALTER TABLE x1 DROP COLUMN b;
+  SELECT sql FROM sqlite_schema;
+} {{CREATE TABLE x1(a TEXT, c CHECK(c!=0))}}
+
 finish_test