]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Fix authorization callbacks for the new commands on this branch.
authordan <Dan Kennedy>
Sat, 27 Sep 2025 16:13:56 +0000 (16:13 +0000)
committerdan <Dan Kennedy>
Sat, 27 Sep 2025 16:13:56 +0000 (16:13 +0000)
FossilOrigin-Name: 0165e2afa8b640c9d7a31414f06144e089844dc13691f06f363a50d14fec62bc

manifest
manifest.uuid
src/alter.c
src/parse.y
src/sqliteInt.h
test/altercons.test

index d9014583b495ce0ff3ff53b59db3d48804c285f0..4b8f457a965a2f23f97f6e9b58ad8b82b0a72609 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Add\sexperimental\simplementations\sof\sALTER\sTABLE\scommands\sto\sadd\sand\sdrop\sCHECK\sand\sNOT\sNULL\sconstraints.
-D 2025-09-27T14:59:21.750
+C Fix\sauthorization\scallbacks\sfor\sthe\snew\scommands\son\sthis\sbranch.
+D 2025-09-27T16:13:56.339
 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
@@ -670,7 +670,7 @@ F mptest/multiwrite01.test dab5c5f8f9534971efce679152c5146da265222d
 F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b
 F sqlite3.1 1b9c24374a85dfc7eb8fa7c4266ee0db4f9609cceecfc5481cd8307e5af04366
 F sqlite3.pc.in e6dee284fba59ef500092fdc1843df3be8433323a3733c91da96690a50a5b398
-F src/alter.c 8eeaacd19f6b5948600c7d567c1e22a906d60777c1de8be0d2caa6b68a058a3a
+F src/alter.c b126042887cccd2c6476685f634cbcfa7b7f2812ca4dc96bbb6d606fa9ba56e6
 F src/analyze.c 03bcfc083fc0cccaa9ded93604e1d4244ea245c17285d463ef6a60425fcb247d
 F src/attach.c 9af61b63b10ee702b1594ecd24fb8cea0839cfdb6addee52fba26fa879f5db9d
 F src/auth.c 54ab9c6c5803b47c0d45b76ce27eff22a03b4b1f767c5945a3a4eb13aa4c78dc
@@ -726,7 +726,7 @@ F src/os_win.c f81a7cffdfe8c593a840895b3f64290714f0186b06302d2c397012252d830374
 F src/os_win.h 4c247cdb6d407c75186c94a1e84d5a22cbae4adcec93fcae8d2bc1f956fd1f19
 F src/pager.c 113f9149092ccff6cf90e97c2611200e5a237f13d26c394bc9fd933377852764
 F src/pager.h 6137149346e6c8a3ddc1eeb40aee46381e9bc8b0fcc6dda8a1efde993c2275b8
-F src/parse.y 853bfe037292ab3731b0753a92291d248161e721dd6893affb9d181d65f43702
+F src/parse.y 834ba749a6a9f34ef49ad4dd30531252739f6f796f1589d0c4ba548385276535
 F src/pcache.c 588cc3c5ccaaadde689ed35ce5c5c891a1f7b1f4d1f56f6cf0143b74d8ee6484
 F src/pcache.h 1497ce1b823cf00094bb0cf3bac37b345937e6f910890c626b16512316d3abf5
 F src/pcache1.c 131ca0daf4e66b4608d2945ae76d6ed90de3f60539afbd5ef9ec65667a5f2fcd
@@ -741,7 +741,7 @@ F src/shell.c.in 0ab96b4d875ec03e1b5d0c97aa3f2f68d3b6c926f270488e26f3088d1755481
 F src/sqlite.h.in 5732519a2acb09066032ceac21f25996eb3f28f807a4468e30633c7c70faae1c
 F src/sqlite3.rc 015537e6ac1eec6c7050e17b616c2ffe6f70fca241835a84a4f0d5937383c479
 F src/sqlite3ext.h 3f0c4ed6934e7309a61c6f3c30f70a30a5b869f785bb3d9f721a36c5e4359126
-F src/sqliteInt.h 9e65623e73c1c6d45e8bba3bad2d86d90cc289b2923ca35a26db5328d9f1ed60
+F src/sqliteInt.h d555ae8089e7032ae47823a58150f424e2f8715eaadc0eb3071a5c3de028a8a7
 F src/sqliteLimit.h fe70bd8983e5d317a264f2ea97473b359faf3ebb0827877a76813f5cf0cdc364
 F src/status.c 0e72e4f6be6ccfde2488eb63210297e75f569f3ce9920f6c3d77590ec6ce5ffd
 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1
@@ -839,7 +839,7 @@ F test/alter4.test 37cafe164067a6590a0ee4cec780bddbbaa33dc50b11542dcfbe0e6562649
 F test/alterauth.test 63442ba61ceb0c1eeb63aac1f4f5cebfa509d352276059d27106ae256bafc959
 F test/alterauth2.test 48967abae0494d9a300d1c92473d99fcb66edfcc23579c89322f033f49410adc
 F test/altercol.test b43fb5725332f4cf8cff0280605202c1672e808281accea60a066d2ccc5129e5
-F test/altercons.test 2e05836679a139317b8ac18c48c86d814b38011a7f225cbd52880fc8bc22c2f5
+F test/altercons.test 33fb8117e669b14536a7cf5df694a6027e5773c2e5d12dd2a240c7b2046c9cc5
 F test/altercorrupt.test 2e1d705342cf9d7de884518ddbb053fd52d7e60d2b8869b7b63b2fda68435c12
 F test/alterdropcol.test a653a3945f964d26845ec0cd0a8e74189f46de3119a984c5bc45457da392612e
 F test/alterdropcol2.test 527fce683b200d620f560f666c44ae33e22728e990a10a48a543280dfd4b4d41
@@ -2170,11 +2170,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350
 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7
 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd
 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
-P b44650f907e9cb4ec908bb7525488e309946fac9d84cdac4cdde730527a440a9
-R 62bf02b8a31c34d045e943408d7ca34a
-T *branch * alter-table-constraints
-T *sym-alter-table-constraints *
-T -sym-trunk *
+P d939b25d76fe70a3255cfe38097d4489323028cd05e5512a98dce06b48eee445
+R df87aa2ddd3ec2e579d06904451a2687
 U dan
-Z df1bd70c76c4689d412ec3f686f545c6
+Z afa946c19eec2db0cf6e37984f361e84
 # Remove this line to create a well-formed Fossil manifest.
index 8d93d0bad356ea8e07f31df7981ff5f0c1db28bb..f37679958e4bf42861009fa7154bf70b3732268f 100644 (file)
@@ -1 +1 @@
-d939b25d76fe70a3255cfe38097d4489323028cd05e5512a98dce06b48eee445
+0165e2afa8b640c9d7a31414f06144e089844dc13691f06f363a50d14fec62bc
index 23847470a49961905b8f1294bb1de2a1351ee767..f8692c0cdc9648f70a02c42f2d3e249ef3937185 100644 (file)
@@ -563,7 +563,7 @@ exit_begin_add_column:
 ** Or, if pTab is not a view or virtual table, zero is returned.
 */
 #if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE)
-static int isRealTable(Parse *pParse, Table *pTab, int bDrop){
+static int isRealTable(Parse *pParse, Table *pTab, int iOp){
   const char *zType = 0;
 #ifndef SQLITE_OMIT_VIEW
   if( IsView(pTab) ){
@@ -576,9 +576,12 @@ static int isRealTable(Parse *pParse, Table *pTab, int bDrop){
   }
 #endif
   if( zType ){
+    const char *azMsg[] = {
+      "rename columns of", "drop column from", "edit constraints of"
+    };
+    assert( iOp>=0 && iOp<ArraySize(azMsg) );
     sqlite3ErrorMsg(pParse, "cannot %s %s \"%s\"",
-        (bDrop ? "drop column from" : "rename columns of"),
-        zType, pTab->zName
+        azMsg[iOp], zType, pTab->zName
     );
     return 1;
   }
@@ -2633,11 +2636,64 @@ static int alterFindCol(Parse *pParse, Table *pTab, Token *pCol, int *piCol){
     }
   }
 
+#ifndef SQLITE_OMIT_AUTHORIZATION
+  if( rc==SQLITE_OK ){
+    const char *zDb = db->aDb[sqlite3SchemaToIndex(db, pTab->pSchema)].zDbSName;
+    const char *zCol = pTab->aCol[iCol].zCnName;
+    if( sqlite3AuthCheck(pParse, SQLITE_ALTER_TABLE, zDb, pTab->zName, zCol) ){
+      pTab = 0;
+    }
+  }
+#endif
+
   sqlite3DbFree(db, zName);
   *piCol = iCol;
   return rc;
 }
 
+
+/*
+** Find the table named by the first entry in source list pSrc. If successful,
+** return a pointer to the Table structure and set output variable (*pzDb)
+** to point to the name of the database containin the table (i.e. "main",
+** "temp" or the name of an attached database). 
+**
+** If the table cannot be located, return NULL. The value of the two output
+** parameters is undefined in this case.
+*/
+static Table *alterFindTable(
+  Parse *pParse, 
+  SrcList *pSrc, 
+  int *piDb,
+  const char **pzDb,
+  int bAuth
+){
+  sqlite3 *db = pParse->db;
+  Table *pTab = 0;
+  assert( sqlite3BtreeHoldsAllMutexes(db) );
+  pTab = sqlite3LocateTableItem(pParse, 0, &pSrc->a[0]);
+  if( pTab ){
+    int iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
+    *pzDb = db->aDb[iDb].zDbSName;
+    *piDb = iDb;
+
+    if( SQLITE_OK!=isRealTable(pParse, pTab, 2) 
+     || SQLITE_OK!=isAlterableTable(pParse, pTab) 
+    ){
+      pTab = 0;
+    }
+  }
+#ifndef SQLITE_OMIT_AUTHORIZATION
+  if( pTab && bAuth ){
+    if( sqlite3AuthCheck(pParse, SQLITE_ALTER_TABLE, *pzDb, pTab->zName, 0) ){
+      pTab = 0;
+    }
+  }
+#endif
+  sqlite3SrcListDelete(db, pSrc);
+  return pTab;
+}
+
 void alterDropConstraint(
   Parse *pParse, 
   SrcList *pSrc, 
@@ -2650,26 +2706,14 @@ void alterDropConstraint(
   const char *zDb = 0;
   char *zArg = 0;
 
-  /* Look up the table being altered. */
-  assert( sqlite3BtreeHoldsAllMutexes(db) );
-  pTab = sqlite3LocateTableItem(pParse, 0, &pSrc->a[0]);
-  if( !pTab ) goto exit_drop_cons;
-
-  /* Make sure this is not an attempt to ALTER a view, virtual table or
-  ** system table. */
-  if( SQLITE_OK!=isAlterableTable(pParse, pTab) ) goto exit_drop_cons;
-  if( SQLITE_OK!=isRealTable(pParse, pTab, 1) ) goto exit_drop_cons;
-
-  /* Edit the sqlite_schema table */
-  iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
-  assert( iDb>=0 );
-  zDb = db->aDb[iDb].zDbSName;
+  pTab = alterFindTable(pParse, pSrc, &iDb, &zDb, pCons!=0);
+  if( !pTab ) return;
 
   if( pCons ){
     zArg = sqlite3MPrintf(db, "%.*Q", pCons->n, pCons->z);
   }else{
     int iCol;
-    if( alterFindCol(pParse, pTab, pCol, &iCol) ) goto exit_drop_cons;
+    if( alterFindCol(pParse, pTab, pCol, &iCol) ) return;
     zArg = sqlite3MPrintf(db, "%d", iCol);
   }
 
@@ -2684,9 +2728,6 @@ void alterDropConstraint(
 
   /* Finally, reload the database schema. */
   renameReloadSchema(pParse, iDb, INITFLAG_AlterDropCons);
-
- exit_drop_cons:
-  sqlite3SrcListDelete(db, pSrc);
 }
 
 
@@ -2724,34 +2765,6 @@ static void failConstraintFunc(
   sqlite3_result_error_code(ctx, err);
 }
 
-/*
-** Find the table named by the first entry in source list pSrc. If successful,
-** return a pointer to the Table structure and set output variable (*pzDb)
-** to point to the name of the database containin the table (i.e. "main",
-** "temp" or the name of an attached database). 
-**
-** If the table cannot be located, return NULL. The value of the two output
-** parameters is undefined in this case.
-*/
-static Table *alterFindTable(
-  Parse *pParse, 
-  SrcList *pSrc, 
-  int *piDb,
-  const char **pzDb
-){
-  sqlite3 *db = pParse->db;
-  Table *pTab = 0;
-  assert( sqlite3BtreeHoldsAllMutexes(db) );
-  pTab = sqlite3LocateTableItem(pParse, 0, &pSrc->a[0]);
-  sqlite3SrcListDelete(db, pSrc);
-  if( pTab ){
-    int iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
-    *pzDb = db->aDb[iDb].zDbSName;
-    *piDb = iDb;
-  }
-  return pTab;
-}
-
 /*
 ** Prepare a statement of the form:
 **
@@ -2760,7 +2773,8 @@ static Table *alterFindTable(
 void sqlite3AlterSetNotNull(
   Parse *pParse, 
   SrcList *pSrc, 
-  Token *pCol
+  Token *pCol,
+  Token *pFirst
 ){
   Table *pTab = 0;
   int iCol = 0;
@@ -2771,7 +2785,7 @@ void sqlite3AlterSetNotNull(
   int t = 0;
 
   /* Look up the table being altered. */
-  pTab = alterFindTable(pParse, pSrc, &iDb, &zDb);
+  pTab = alterFindTable(pParse, pSrc, &iDb, &zDb, 0);
   if( !pTab ) return;
 
   /* Find the column being altered. */
@@ -2779,12 +2793,8 @@ void sqlite3AlterSetNotNull(
     return;
   }
 
-  /* Find the start of the constraint definition */
-  pCons = &pCol->z[pCol->n];
-  pCons += getConstraintToken((const u8*)pCons, &t);
-  pCons += getWhitespace((const u8*)pCons);
-
   /* Find the length in bytes of the constraint definition */
+  pCons = pFirst->z;
   nCons = pParse->sLastToken.z - pCons;
   if( pCons[nCons-1]==';' ) nCons--;
   while( sqlite3Isspace(pCons[nCons-1]) ) nCons--;
@@ -2868,7 +2878,7 @@ void sqlite3AlterAddConstraint(
   int nCons;
 
   /* Look up the table being altered. */
-  pTab = alterFindTable(pParse, pSrc, &iDb, &zDb);
+  pTab = alterFindTable(pParse, pSrc, &iDb, &zDb, 1);
   if( !pTab ) return;
 
   /* If this new constraint has a name, check that it is not a duplicate of
index bcc3e61b2a1a687740574abd1cf2b6932a24d1c6..cfd1b5d4cb08534570e9e0f0f456a62ef58584b9 100644 (file)
@@ -1856,8 +1856,8 @@ cmd ::= ALTER TABLE fullname(X) DROP CONSTRAINT nm(Y). {
 cmd ::= ALTER TABLE fullname(X) ALTER kwcolumn_opt nm(Y) DROP NOT NULL. {
   sqlite3AlterDropNotNull(pParse, X, &Y);
 }
-cmd ::= ALTER TABLE fullname(X) ALTER kwcolumn_opt nm(Y) SET NOT NULL onconf. {
-  sqlite3AlterSetNotNull(pParse, X, &Y);
+cmd ::= ALTER TABLE fullname(X) ALTER kwcolumn_opt nm(Y) SET NOT(Z) NULL onconf. {
+  sqlite3AlterSetNotNull(pParse, X, &Y, &Z);
 }
 
 cmd ::= ALTER TABLE fullname(X) ADD CONSTRAINT(Y) nm(Z) CHECK LP(A) expr RP(B) onconf. {
index 81cfbf8ab3de0079556d6c74c4617954e80c6baa..94e387ace1ba901c8b73176aa7294b1c16cbb794 100644 (file)
@@ -5451,7 +5451,7 @@ void sqlite3AlterRenameColumn(Parse*, SrcList*, Token*, Token*);
 void sqlite3AlterDropConstraint(Parse*, SrcList*, Token*);
 void sqlite3AlterDropNotNull(Parse*, SrcList*, Token*);
 void sqlite3AlterAddConstraint(Parse*,SrcList*,Token*,Token*,const char*,int);
-void sqlite3AlterSetNotNull(Parse*, SrcList*, Token*);
+void sqlite3AlterSetNotNull(Parse*, SrcList*, Token*, Token*);
 int sqlite3GetToken(const unsigned char *, int *);
 void sqlite3NestedParse(Parse*, const char*, ...);
 void sqlite3ExpirePreparedStatements(sqlite3*, int);
index af70d0f562bfa2f7d6a03b9834e76ad251f54200..e145d31ad2df226aa1f0f92975883e11768bd637 100644 (file)
@@ -228,4 +228,46 @@ do_execsql_test 6.4.1 {
   SELECT sql FROM sqlite_schema WHERE tbl_name='b1'
 } {{CREATE TABLE b1(a, b, CONSTRAINT abc CHECK (a!=2))}}
 
+#-------------------------------------------------------------------------
+# Try attaching a NOT NULL to a generated column.
+#
+reset_db
+do_execsql_test 7.0 {
+  CREATE TABLE x1(a, b AS (a+1));
+  INSERT INTO x1 VALUES(1), (2), (3), (NULL);
+}
+
+do_catchsql_test 7.1 {
+  ALTER TABLE x1 ALTER b SET NOT NULL;
+} {1 {constraint failed}}
+
+do_catchsql_test 7.2 {
+  DELETE FROM x1 WHERE b IS NULL;
+  ALTER TABLE x1 ALTER b SET NOT NULL;
+} {0 {}}
+
+do_execsql_test 7.3 {
+  SELECT b FROM x1
+} {2 3 4}
+
+do_catchsql_test 7.4 {
+  ALTER TABLE x1 ALTER rowid SET NOT NULL;
+} {1 {no such column: rowid}}
+
+do_execsql_test 7.5 {
+  CREATE VIEW v1 AS SELECT a, b FROM x1;
+}
+do_catchsql_test 7.6 {
+  ALTER TABLE v1 RENAME a TO c;
+} {1 {cannot rename columns of view "v1"}}
+do_catchsql_test 7.7 {
+  ALTER TABLE v1 ALTER a SET NOT NULL;
+} {1 {cannot edit constraints of view "v1"}}
+do_catchsql_test 7.8 {
+  ALTER TABLE sqlite_schema ALTER sql SET NOT NULL;
+} {1 {table sqlite_master may not be altered}}
+do_catchsql_test 7.9 {
+  ALTER TABLE v1 ALTER a DROP NOT NULL
+} {1 {cannot edit constraints of view "v1"}}
+
 finish_test