]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Prevent collation sequences and user functions from being deleted or changed while...
authordanielk1977 <danielk1977@noemail.net>
Tue, 25 Jan 2005 04:27:54 +0000 (04:27 +0000)
committerdanielk1977 <danielk1977@noemail.net>
Tue, 25 Jan 2005 04:27:54 +0000 (04:27 +0000)
FossilOrigin-Name: cabab62bc10568d435806a7059fad7274f0dd4c8

manifest
manifest.uuid
src/main.c
src/tclsqlite.c
src/test1.c
test/schema.test
test/select2.test

index e464d4b5bc1a71d3afcb907a261c11322d9d291e..83d21a64c63b5c6c9d68581b36831cac617436d1 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Clarify\sdocumentation\sof\sDEFAULT\sCURRENT_TIME\setc.\s(version\s3.1.0\sand\sgreater\sonly).\s(CVS\s2274)
-D 2005-01-24T23:27:32
+C Prevent\scollation\ssequences\sand\suser\sfunctions\sfrom\sbeing\sdeleted\sor\schanged\swhile\sSQL\sstatements\sare\sexecuting.\s(CVS\s2275)
+D 2005-01-25T04:27:55
 F Makefile.in ffd81f5e926d40b457071b4de8d7c1fa18f39b5a
 F Makefile.linux-gcc a9e5a0d309fa7c38e7c14d3ecf7690879d3a5457
 F README a01693e454a00cc117967e3f9fdab2d4d52e9bc1
@@ -42,7 +42,7 @@ F src/hash.c a97721a55440b7bea31ffe471bb2f6b4123cddd5
 F src/hash.h 1b0c445e1c89ff2aaad9b4605ba61375af001e84
 F src/insert.c 037eb46630f027d0f93584db180d08ce163f3dbb
 F src/legacy.c d58ea507bce885298a2c8c3cbb0f4bff5d47830b
-F src/main.c 1fe0216dc01e1929e7e009cdedfb3e6e2391d717
+F src/main.c 302e21bdaa015f590fdb7e69d50f45788da0fb0b
 F src/md5.c 7ae1c39044b95de2f62e066f47bb1deb880a1070
 F src/os.h ae44064dc118b20d39450cb331409a775e8bb1c6
 F src/os_common.h 0e7f428ba0a6c40a61bc56c4e96f493231301b73
@@ -63,8 +63,8 @@ F src/shell.c 1f0da77ef0520afd6df71f4781076021874310f3
 F src/sqlite.h.in 7d7c28344e2bd770491b56ed9169be20859c707d
 F src/sqliteInt.h be6fa5e31c65e2b8e10112ee47a6e63ec7de37b5
 F src/table.c 25b3ff2b39b7d87e8d4a5da0713d68dfc06cbee9
-F src/tclsqlite.c 47ecdb00e9bc135b37ad5bed84fefe20d7c19611
-F src/test1.c 0a71a150659dd261be775c5eb60ae6c0c856c8a5
+F src/tclsqlite.c 101994a2c4c0eaa69f1de9bfe4a02167f6049e7d
+F src/test1.c 8c320f043b869c08fca86c4f01de027774eb85a8
 F src/test2.c bbc2ecc58ceeab12d1e40970f831b1017524e40d
 F src/test3.c 683e1e3819152ffd35da2f201e507228921148d0
 F src/test4.c 7c6b9fc33dd1f3f93c7f1ee6e5e6d016afa6c1df
@@ -174,9 +174,9 @@ F test/reindex.test 3552c6b944a3fab28cfd3049c04c65cb79419757
 F test/rollback.test 94cd981ee3a627d9f6466f69dcf1f7dbfe695d7a
 F test/rowid.test 040a3bef06f970c45f5fcd14b2355f7f4d62f0cf
 F test/safety.test 907b64fee719554a3622853812af3886fddbbb4f
-F test/schema.test 8725b41e19dec6c2d060b134417fe3da83c22d70
+F test/schema.test 3787768619706fc6f47c53cbe23472e782302e1e
 F test/select1.test ad700a2a1c325a23a7206ad4d189e33917de526f
-F test/select2.test 04103fbd55fca9558fd79d637fb7819d9d0b2f52
+F test/select2.test 01b9cbc06e5ed662ce0289aa5f47314d54541e82
 F test/select3.test 9de435aa84fc406708cd8dc1b1d60e7f27cea685
 F test/select4.test c239f516aa31f42f2ef7c6d7cd01105f08f934ca
 F test/select5.test 94db800bbeff2e426c0175e07f7a71d4617853b5
@@ -272,7 +272,7 @@ F www/tclsqlite.tcl e73f8f8e5f20e8277619433f7970060ab01088fc
 F www/vdbe.tcl 095f106d93875c94b47367384ebc870517431618
 F www/version3.tcl 092a01f5ef430d2c4acc0ae558d74c4bb89638a0
 F www/whentouse.tcl 3e522a06ad41992023c80ca29a048ae2331ca5bd
-P b243681a0e328ee0bbf1140abfb60d65d2102ad5
-R ccb6447e7156933de8fc182a220c72ff
+P 557eb2ec9d825c0a2830d3355d0d27b4b5937de2
+R ccc679b6d9c5516b3defef2b60c271aa
 U danielk1977
-Z dad25937f9866029c7d3ceaad1989791
+Z 95e1deb222b350d5a7b99118f5214f27
index 2ad32a7ff3ac473a3d092e33d07dc5bffb4fa03a..fbe7a2cf5a16b387ff0443b58316f5271e2a8944 100644 (file)
@@ -1 +1 @@
-557eb2ec9d825c0a2830d3355d0d27b4b5937de2
\ No newline at end of file
+cabab62bc10568d435806a7059fad7274f0dd4c8
\ No newline at end of file
index 9ab3d75628866fcae5456b72efdfd8bc0b7f3044..e993b816171003df4e9ef62f3efee5cfa5c4ad9d 100644 (file)
@@ -14,7 +14,7 @@
 ** other files are for internal use by SQLite and should not be
 ** accessed by users of the library.
 **
-** $Id: main.c,v 1.274 2005/01/24 10:25:59 danielk1977 Exp $
+** $Id: main.c,v 1.275 2005/01/25 04:27:55 danielk1977 Exp $
 */
 #include "sqliteInt.h"
 #include "os.h"
@@ -736,6 +736,22 @@ int sqlite3_create_function(
 #else
   enc = SQLITE_UTF8;
 #endif
+  
+  /* Check if an existing function is being overridden or deleted. If so,
+  ** and there are active VMs, then return SQLITE_BUSY. If a function
+  ** is being overridden/deleted but there are no active VMs, allow the
+  ** operation to continue but invalidate all precompiled statements.
+  */
+  p = sqlite3FindFunction(db, zFunctionName, nName, nArg, enc, 0);
+  if( p && p->iPrefEnc==enc && p->nArg==nArg ){
+    if( db->activeVdbeCnt ){
+      sqlite3Error(db, SQLITE_BUSY, 
+        "Unable to delete/modify user-function due to active statements");
+      return SQLITE_BUSY;
+    }else{
+      sqlite3ExpirePreparedStatements(db);
+    }
+  }
 
   p = sqlite3FindFunction(db, zFunctionName, nName, nArg, enc, 1);
   if( p==0 ) return SQLITE_NOMEM;
@@ -1288,10 +1304,17 @@ int sqlite3_create_collation(
     return SQLITE_ERROR;
   }
 
-  /* If removing a collation sequence, then set the expired flag for
-  ** all precompiled statements.
+  /* Check if this call is removing or replacing an existing collation 
+  ** sequence. If so, and there are active VMs, return busy. If there
+  ** are no active VMs, invalidate any pre-compiled statements.
   */
-  if( !xCompare ){
+  pColl = sqlite3FindCollSeq(db, (u8)enc, zName, strlen(zName), 0);
+  if( pColl && pColl->xCmp ){
+    if( db->activeVdbeCnt ){
+      sqlite3Error(db, SQLITE_BUSY, 
+        "Unable to delete/modify collation sequence due to active statements");
+      return SQLITE_BUSY;
+    }
     sqlite3ExpirePreparedStatements(db);
   }
 
index dc05eab0ade696cc1a9e0b32ae2b658832636b2d..a5ef6106ce62b43c34fa4e6f20c4459e55c76615 100644 (file)
@@ -11,7 +11,7 @@
 *************************************************************************
 ** A TCL Interface to SQLite
 **
-** $Id: tclsqlite.c,v 1.117 2005/01/24 10:25:59 danielk1977 Exp $
+** $Id: tclsqlite.c,v 1.118 2005/01/25 04:27:55 danielk1977 Exp $
 */
 #ifndef NO_TCL     /* Omit this whole file if TCL is unavailable */
 
@@ -696,6 +696,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
     strcpy(pCollate->zScript, zScript);
     if( sqlite3_create_collation(pDb->db, zName, SQLITE_UTF8, 
         pCollate, tclSqlCollate) ){
+      Tcl_SetResult(interp, (char *)sqlite3_errmsg(pDb->db), TCL_VOLATILE);
       return TCL_ERROR;
     }
     break;
@@ -1128,7 +1129,8 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
     rc = sqlite3_create_function(pDb->db, zName, -1, SQLITE_UTF8,
         pFunc, tclSqlFunc, 0, 0);
     if( rc!=SQLITE_OK ){
-       rc = TCL_ERROR;
+      rc = TCL_ERROR;
+      Tcl_SetResult(interp, (char *)sqlite3_errmsg(pDb->db), TCL_VOLATILE);
     }else{
       /* Must flush any cached statements */
       flushStmtCache( pDb );
index c751861a8906d5bdc38206b2ce596ea6da66042b..0d197f0861ae4ceb1228f30822907c806208d128 100644 (file)
@@ -13,7 +13,7 @@
 ** is not included in the SQLite library.  It is used for automated
 ** testing of the SQLite library.
 **
-** $Id: test1.c,v 1.127 2005/01/22 03:03:55 drh Exp $
+** $Id: test1.c,v 1.128 2005/01/25 04:27:55 danielk1977 Exp $
 */
 #include "sqliteInt.h"
 #include "tcl.h"
@@ -2599,6 +2599,58 @@ static int test_sleep(
 }
 #endif
 
+/*
+** Usage: sqlite_delete_function DB function-name
+**
+** Delete the user function 'function-name' from database handle DB. It
+** is assumed that the user function was created as UTF8, any number of
+** arguments (the way the TCL interface does it).
+*/
+static int delete_function(
+  void * clientData,
+  Tcl_Interp *interp,
+  int argc,
+  char **argv
+){
+  int rc;
+  sqlite3 *db;
+  if( argc!=3 ){
+    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 
+        " DB function-name", 0);
+    return TCL_ERROR;
+  }
+  if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
+  rc = sqlite3_create_function(db, argv[2], -1, SQLITE_UTF8, 0, 0, 0, 0);
+  Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC);
+  return TCL_OK;
+}
+
+/*
+** Usage: sqlite_delete_collation DB collation-name
+**
+** Delete the collation sequence 'collation-name' from database handle 
+** DB. It is assumed that the collation sequence was created as UTF8 (the 
+** way the TCL interface does it).
+*/
+static int delete_collation(
+  void * clientData,
+  Tcl_Interp *interp,
+  int argc,
+  char **argv
+){
+  int rc;
+  sqlite3 *db;
+  if( argc!=3 ){
+    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 
+        " DB function-name", 0);
+    return TCL_ERROR;
+  }
+  if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
+  rc = sqlite3_create_collation(db, argv[2], SQLITE_UTF8, 0, 0);
+  Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC);
+  return TCL_OK;
+}
+
 /*
 ** Usage:  tcl_variable_type VARIABLENAME
 **
@@ -2840,6 +2892,8 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
 #if 0
      { "sqlite3_sleep",                 (Tcl_CmdProc*)test_sleep            },
 #endif
+     { "sqlite_delete_function",       (Tcl_CmdProc*)delete_function        },
+     { "sqlite_delete_collation",      (Tcl_CmdProc*)delete_collation       }
   };
   static struct {
      char *zName;
index 04f7f13485eeb55c64c4ba2af74235e5be3c91da..262fc4bf5aa43369a191d389b062f8f04984f828 100644 (file)
@@ -1,4 +1,4 @@
-# 2004 Jan 24
+# 2005 Jan 24
 #
 # The author disclaims copyright to this source code.  In place of
 # a legal notice, here is a blessing:
@@ -13,7 +13,7 @@
 # This file tests the various conditions under which an SQLITE_SCHEMA
 # error should be returned.
 #
-# $Id: schema.test,v 1.2 2005/01/24 13:03:32 danielk1977 Exp $
+# $Id: schema.test,v 1.3 2005/01/25 04:27:55 danielk1977 Exp $
 
 #---------------------------------------------------------------------
 # When any of the following types of SQL statements or actions are 
 #
 # Note: Test cases schema-6.* are missing right now.
 #
+# Test cases schema-9.* and schema-10.* test some specific bugs
+# that came up during development.
+#
+# Test cases schema-11.* test that it is impossible to delete or
+# change a collation sequence or user-function while SQL statements
+# are executing. Adding new collations or functions is allowed.
+#
+# Note: Test cases schema-11.* are also missing right now.
 
 set testdir [file dirname $argv0]
 source $testdir/tester.tcl
@@ -153,6 +161,26 @@ do_test schema-5.4 {
   sqlite3_finalize $::STMT
 } {SQLITE_SCHEMA}
 
+#---------------------------------------------------------------------
+# Tests 6.* check that prepared statements are invalidated when
+# a user-function is deleted (but not when one is added).
+do_test schema-6.1 {
+  set sql {SELECT * FROM abc;}
+  set ::STMT [sqlite3_prepare $::DB $sql -1 TAIL]
+  db function hello_function {}
+  sqlite3_step $::STMT
+} {SQLITE_DONE}
+do_test schema-6.2 {
+  sqlite3_reset $::STMT
+} {SQLITE_OK}
+do_test schema-6.3 {
+  sqlite_delete_function $::DB hello_function
+  sqlite3_step $::STMT
+} {SQLITE_ERROR}
+do_test schema-6.4 {
+  sqlite3_finalize $::STMT
+} {SQLITE_SCHEMA}
+
 #---------------------------------------------------------------------
 # Tests 7.* check that prepared statements are invalidated when
 # a collation sequence is deleted (but not when one is added).
@@ -255,5 +283,49 @@ do_test schema-10.5 {
   db2 close
 } {}
 
+#---------------------------------------------------------------------
+# Attempting to delete or replace a user-function or collation sequence 
+# while there are active statements returns an SQLITE_BUSY error.
+#
+# schema-11.1 - 11.4: User function.
+# schema-11.5 - 11.8: Collation sequence.
+#
+do_test schema-11.1 {
+  db function tstfunc {}
+  set sql {SELECT * FROM abc}
+  set ::STMT [sqlite3_prepare $::DB $sql -1 TAIL]
+  sqlite3_step $::STMT
+} {SQLITE_ROW}
+do_test schema-11.2 {
+  sqlite_delete_function $::DB tstfunc
+} {SQLITE_BUSY}
+do_test schema-11.3 {
+  set rc [catch {
+    db function tstfunc {}
+  } msg]
+  list $rc $msg
+} {1 {Unable to delete/modify user-function due to active statements}}
+do_test schema-11.4 {
+  sqlite3_finalize $::STMT
+} {SQLITE_OK}
+do_test schema-11.5 {
+  db collate tstcollate {}
+  set sql {SELECT * FROM abc}
+  set ::STMT [sqlite3_prepare $::DB $sql -1 TAIL]
+  sqlite3_step $::STMT
+} {SQLITE_ROW}
+do_test schema-11.6 {
+  sqlite_delete_collation $::DB tstcollate
+} {SQLITE_BUSY}
+do_test schema-11.7 {
+  set rc [catch {
+    db collate tstcollate {}
+  } msg]
+  list $rc $msg
+} {1 {Unable to delete/modify collation sequence due to active statements}}
+do_test schema-11.8 {
+  sqlite3_finalize $::STMT
+} {SQLITE_OK}
+
 finish_test
 
index 1d9d87bd17ce1a5075e17e3b8b10b37c21fd417d..52525a6d5a3b9a50650493a40e85f2463be4d9e3 100644 (file)
@@ -11,7 +11,7 @@
 # This file implements regression tests for SQLite library.  The
 # focus of this file is testing the SELECT statement.
 #
-# $Id: select2.test,v 1.23 2005/01/24 12:46:14 drh Exp $
+# $Id: select2.test,v 1.24 2005/01/25 04:27:55 danielk1977 Exp $
 
 set testdir [file dirname $argv0]
 source $testdir/tester.tcl
@@ -71,7 +71,7 @@ ifcapable tclvar {
       }
       execsql {COMMIT}
     }]
-    set result {}
+    list
   } {}
   puts "time with cache: $::t1"
 }
@@ -86,7 +86,7 @@ do_test select2-2.0.2 {
     }
     execsql {COMMIT}
   }]
-  set result {}
+  list
 } {}
 puts "time without cache: $t2"
 ifcapable tclvar {