]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Permit sqlite_exec() to be called from within user-defined functions. (CVS 1166)
authordrh <drh@noemail.net>
Wed, 7 Jan 2004 19:24:48 +0000 (19:24 +0000)
committerdrh <drh@noemail.net>
Wed, 7 Jan 2004 19:24:48 +0000 (19:24 +0000)
FossilOrigin-Name: 03636c94a542b1f90a3acfbe65a9c2976872073f

manifest
manifest.uuid
src/test1.c
src/vdbe.c
test/misuse.test

index 7bff28b8185bfcd788916d736da936af87937cba..d485735a1dc7cfef9dbe65895c868cf950f13b83 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Defer\sthe\s{quote:\sMoveTo}\r\nopcode\sin\sVDBE\suntil\sthe\sdata\sis\sactually\sneeded.\s\sSometimes\r\nthe\sdata\sis\snever\sneeded,\sresulting\sin\sa\sperformance\sincrease.\s\sOn\san\sindexed\r\norder\ssearch\swith\sa\slarge\sOFFSET,\squeries\stimes\scan\sbe\san\sorder\sof\smagnitude\r\nfaster.\s(CVS\s1165)
-D 2004-01-07T18:52:57
+C Permit\ssqlite_exec()\sto\sbe\scalled\sfrom\swithin\suser-defined\sfunctions.\s(CVS\s1166)
+D 2004-01-07T19:24:48
 F Makefile.in 0515ff9218ad8d5a8f6220f0494b8ef94c67013b
 F Makefile.linux-gcc b86a99c493a5bfb402d1d9178dcdc4bd4b32f906
 F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
@@ -53,7 +53,7 @@ F src/sqlite.h.in e6cfff01fafc8a82ce82cd8c932af421dc9adb54
 F src/sqliteInt.h d9f2391451ae9636eb447dfa4dc35b70bfa3759d
 F src/table.c d845cb101b5afc1f7fea083c99e3d2fa7998d895
 F src/tclsqlite.c dcd18d1f0d51ac4863d1f9059f614f903bc1fffe
-F src/test1.c 1d297ca6c01601ee38d723ff08343dc01f351985
+F src/test1.c e8652055d04d241d4fb437b5c33ff07d9f13b4b4
 F src/test2.c 5014337d8576b731cce5b5a14bec4f0daf432700
 F src/test3.c 30985ebdfaf3ee1462a9b0652d3efbdc8d9798f5
 F src/test4.c dcbbbb382626fd466a7c46907f74db35fc8bad64
@@ -63,7 +63,7 @@ F src/trigger.c ce83e017b407d046e909d05373d7f8ee70f9f7f9
 F src/update.c 24260b4fda00c9726d27699a0561d53c0dccc397
 F src/util.c 64995b5949a5d377629ffd2598747bc771cade1e
 F src/vacuum.c 77485a64a6e4e358170f150fff681c1624a092b0
-F src/vdbe.c 651f294e3a56baf50d56e11fed822b963f3bf41f
+F src/vdbe.c 651fcdac5c865711169d5046836b31bd81e0cb8a
 F src/vdbe.h 3957844e46fea71fd030e78f6a3bd2f7e320fb43
 F src/vdbeInt.h eab39bc209b267271bc4afbcf4991d6c229bae9a
 F src/vdbeaux.c 6f2d43643f83656b2555b7ee320397805db11d4c
@@ -107,7 +107,7 @@ F test/minmax.test 6d9b6d6ee34f42e2a58dffece1f76d35f446b3af
 F test/misc1.test 0b98d493b0cf55cb5f53e1f3df8107c166eecb5a
 F test/misc2.test 10c2ce26407d37411b96273e552d5095393732be
 F test/misc3.test 73bdce2b7f82699fb4771e7acfbd37461263f59e
-F test/misuse.test a3aa2b18a97e4c409a1fcaff5151a4dd804a0162
+F test/misuse.test 1095f26d1aed406c65e1d2eba651c4bb7c38cbff
 F test/notnull.test 7a08117a71e74b0321aaa937dbeb41a09d6eb1d0
 F test/null.test c14d0f4739f21e929b8115b72bf0c765b6bb1721
 F test/pager.test dd31da9bee94a82e2e87e58cf286cfe809f8fc5f
@@ -179,7 +179,7 @@ F www/speed.tcl 2f6b1155b99d39adb185f900456d1d592c4832b3
 F www/sqlite.tcl 3c83b08cf9f18aa2d69453ff441a36c40e431604
 F www/tclsqlite.tcl b9271d44dcf147a93c98f8ecf28c927307abd6da
 F www/vdbe.tcl 9b9095d4495f37697fd1935d10e14c6015e80aa1
-P 6c858db2c099c7ba73d72e02b19bf6173620db13
-R 4cb210b9d1a4f8eeca46f83ab493882a
+P d3e96da20d269a068188915b3cc0eb02d330d316
+R ed517c12ad32df3998805d703dfd3733
 U drh
-Z c064aa79b059a29becbc8ed82d605d9d
+Z 9db3a07230e97c9741564f07ae589d3e
index 079c54afa95ce14fd8d454a4c1048088bc012e4b..03c751170c3077f47fa859917cfa36df4485b577 100644 (file)
@@ -1 +1 @@
-d3e96da20d269a068188915b3cc0eb02d330d316
\ No newline at end of file
+03636c94a542b1f90a3acfbe65a9c2976872073f
\ No newline at end of file
index 32896f8896c5bc78acf52cfb939d42fceeed082f..dd452a4479ab88745ff70d404c09f37526b7d4e8 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.31 2004/01/06 00:44:25 drh Exp $
+** $Id: test1.c,v 1.32 2004/01/07 19:24:48 drh Exp $
 */
 #include "sqliteInt.h"
 #include "tcl.h"
@@ -296,16 +296,72 @@ static void ifnullFunc(sqlite_func *context, int argc, const char **argv){
   }
 }
 
+/*
+** A structure into which to accumulate text.
+*/
+struct dstr {
+  int nAlloc;  /* Space allocated */
+  int nUsed;   /* Space used */
+  char *z;     /* The space */
+};
+
+/*
+** Append text to a dstr
+*/
+static void dstrAppend(struct dstr *p, const char *z, int divider){
+  int n = strlen(z);
+  if( p->nUsed + n + 2 > p->nAlloc ){
+    char *zNew;
+    p->nAlloc = p->nAlloc*2 + n + 200;
+    zNew = sqliteRealloc(p->z, p->nAlloc);
+    if( zNew==0 ){
+      sqliteFree(p->z);
+      memset(p, 0, sizeof(*p));
+      return;
+    }
+    p->z = zNew;
+  }
+  if( divider && p->nUsed>0 ){
+    p->z[p->nUsed++] = divider;
+  }
+  memcpy(&p->z[p->nUsed], z, n+1);
+  p->nUsed += n;
+}
+
+/*
+** Invoked for each callback from sqliteExecFunc
+*/
+static int execFuncCallback(void *pData, int argc, char **argv, char **NotUsed){
+  struct dstr *p = (struct dstr*)pData;
+  int i;
+  for(i=0; i<argc; i++){
+    if( argv[i]==0 ){
+      dstrAppend(p, "NULL", ' ');
+    }else{
+      dstrAppend(p, argv[i], ' ');
+    }
+  }
+  return 0;
+}
+
 /*
 ** Implementation of the x_sqlite_exec() function.  This function takes
 ** a single argument and attempts to execute that argument as SQL code.
 ** This is illegal and should set the SQLITE_MISUSE flag on the database.
+**
+** 2004-Jan-07:  We have changed this to make it legal to call sqlite_exec()
+** from within a function call.  
 ** 
 ** This routine simulates the effect of having two threads attempt to
 ** use the same database at the same time.
 */
 static void sqliteExecFunc(sqlite_func *context, int argc, const char **argv){
-  sqlite_exec((sqlite*)sqlite_user_data(context), argv[0], 0, 0, 0);
+  struct dstr x;
+  memset(&x, 0, sizeof(x));
+  sqlite_exec((sqlite*)sqlite_user_data(context), argv[0], 
+      execFuncCallback, &x, 0);
+  sqlite_set_result_string(context, x.z, x.nUsed);
+  sqliteFree(x.z);
 }
 
 /*
index 50f6f95cae21d1c316f6dbc8e5ae261672f7fb10..667591e22b14b4a526bb83ec295b97781edae8c9 100644 (file)
@@ -43,7 +43,7 @@
 ** in this file for details.  If in doubt, do not deviate from existing
 ** commenting and indentation practices when changing or adding code.
 **
-** $Id: vdbe.c,v 1.247 2004/01/07 18:52:57 drh Exp $
+** $Id: vdbe.c,v 1.248 2004/01/07 19:24:48 drh Exp $
 */
 #include "sqliteInt.h"
 #include "os.h"
@@ -1121,7 +1121,9 @@ case OP_Function: {
   ctx.z = 0;
   ctx.isError = 0;
   ctx.isStep = 0;
+  if( sqliteSafetyOff(db) ) goto abort_due_to_misuse;
   (*ctx.pFunc->xFunc)(&ctx, n, (const char**)&zStack[p->tos-n+1]);
+  if( sqliteSafetyOn(db) ) goto abort_due_to_misuse;
   sqliteVdbePopStack(p, n);
   p->tos++;
   aStack[p->tos] = ctx.s;
index 062b359fdafd100331b9259be55b0374029d3a4c..7f26280e8aa372ae57e79d2005463112be88334e 100644 (file)
@@ -13,7 +13,7 @@
 # This file implements tests for the SQLITE_MISUSE detection logic.
 # This test file leaks memory and file descriptors.
 #
-# $Id: misuse.test,v 1.3 2002/05/21 11:38:12 drh Exp $
+# $Id: misuse.test,v 1.4 2004/01/07 19:24:48 drh Exp $
 
 set testdir [file dirname $argv0]
 source $testdir/tester.tcl
@@ -41,19 +41,23 @@ do_test misuse-1.3 {
 # Use the x_sqlite_exec() SQL function to simulate the effect of two
 # threads trying to use the same database at the same time.
 #
+# It used to be prohibited to invoke sqlite_exec() from within a function,
+# but that has changed.  The following tests used to cause errors but now
+# they do not.
+#
 do_test misuse-1.4 {
   sqlite_exec_printf $::DB {
-     SELECT x_sqlite_exec('SELECT * FROM t1');
+     SELECT x_sqlite_exec('SELECT * FROM t1') AS xyz;
   } {}
-} {21 {library routine called out of sequence}}
+} {0 {xyz {1 2}}}
 do_test misuse-1.5 {
   sqlite_exec_printf $::DB {SELECT * FROM t1} {}
-} {21 {library routine called out of sequence}}
+} {0 {a b 1 2}}
 do_test misuse-1.6 {
   catchsql {
     SELECT * FROM t1
   }
-} {1 {library routine called out of sequence}}
+} {0 {1 2}}
 
 # Attempt to register a new SQL function while an sqlite_exec() is active.
 #