]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Add the sqlite3_result_error_code() application interface. Use it in the
authordrh <drh@noemail.net>
Wed, 6 Feb 2008 14:11:34 +0000 (14:11 +0000)
committerdrh <drh@noemail.net>
Wed, 6 Feb 2008 14:11:34 +0000 (14:11 +0000)
ATTACH function so that a failed attach returns a proper error code.
Ticket #2914. (CVS 4775)

FossilOrigin-Name: c24616204307936d03d39d2ef0fe6856113f6977

manifest
manifest.uuid
src/attach.c
src/sqlite.h.in
src/vdbe.c
src/vdbeInt.h
src/vdbeapi.c
test/attach.test

index e81f489ee4203b7d825136cc0c190f6f045a0fdd..5430bb5d6e47fae975b5e97ad2523fe315a73fc0 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Delete\sunused\s"pager3_refinfo_enable"\sflag\sand\sits\sassociated\sdebugging\nmacros.\s\sTicket\s#2923.\s(CVS\s4774)
-D 2008-02-02T20:47:38
+C Add\sthe\ssqlite3_result_error_code()\sapplication\sinterface.\s\sUse\sit\sin\sthe\nATTACH\sfunction\sso\sthat\sa\sfailed\sattach\sreturns\sa\sproper\serror\scode.\nTicket\s#2914.\s(CVS\s4775)
+D 2008-02-06T14:11:35
 F Makefile.arm-wince-mingw32ce-gcc ac5f7b2cef0cd850d6f755ba6ee4ab961b1fadf7
 F Makefile.in bc2b5df3e3d0d4b801b824b7ef6dec43812b049b
 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
@@ -80,7 +80,7 @@ F sqlite3.def a96c1d0d39362b763d2ddba220a32da41a15c4b4
 F sqlite3.pc.in abed4664817e1cd500f2276142c71958087c16bc
 F src/alter.c 8a34c900811eec29725ab08ad46cc9dcec714867
 F src/analyze.c a78ac494668581fe7f54ee63700815bb0ea34261
-F src/attach.c 2a0b199467c6c0212fae26a6b51bef132680f881
+F src/attach.c 90665c7ef5145e066570f66d7f0f15cdd0a4d14b
 F src/auth.c c8b2ab5c8bad4bd90ed7c294694f48269162c627
 F src/btmutex.c 483ced3c52205b04b97df69161fadbf87f4f1ea2
 F src/btree.c 29ea577155f39be65bdec1c7782301ff2ee9eb3f
@@ -135,7 +135,7 @@ F src/random.c 02ef38b469237482f1ea14a78b2087cfbaec48bd
 F src/select.c 1a5d0aaf8f420b164eb775d3b1ba2bfb79597f65
 F src/server.c 087b92a39d883e3fa113cae259d64e4c7438bc96
 F src/shell.c ca06cb687c40a8bff6307b5fad41a0e86a0f8558
-F src/sqlite.h.in be6caded9ecc1d0da60670334edfb3426cc256d2
+F src/sqlite.h.in 690736613958e0f462e08ae2a9136fa335214edc
 F src/sqlite3ext.h a93f59cdee3638dc0c9c086f80df743a4e68c3cb
 F src/sqliteInt.h 9dabb5a68e1952a556b78558c87e26af2fdb5ddb
 F src/sqliteLimit.h ee4430f88f69bf63527967bb35ca52af7b0ccb1e
@@ -170,10 +170,10 @@ F src/update.c 31edd9c9764e80753930bd5f9b43e0edb404636f
 F src/utf.c ef4b7d83bae533b76c3e1bf635b113fdad86a736
 F src/util.c c56e41ed4769c1f2b8af9ffde4757a7b4fb08ed1
 F src/vacuum.c 3f34f278809bf3eb0b62ec46ff779e9c385b28f0
-F src/vdbe.c 451ead624d98c95dd9dd41c38afab85bba00122a
+F src/vdbe.c 1049375248b494e626598abffeeb31052c660c78
 F src/vdbe.h 58a7d931ffb704e034b2a725981cfa5bd406fad9
-F src/vdbeInt.h b7a18349e9b29eca4b642aee6233ac02dd63ad87
-F src/vdbeapi.c 93c72ed24d59ed86a634b6d593cdec8376b24513
+F src/vdbeInt.h 969d360acc85f7b2069a8169b4f8a3e1fbaccd44
+F src/vdbeapi.c 61b37dbe11baa221baea7f93c01780705d2419ed
 F src/vdbeaux.c 771b9ffd7b42cbb4bd029d7a9414a7cb03f924a7
 F src/vdbeblob.c 63c750acc7b5012479f508c0e9627372a82cb65d
 F src/vdbefifo.c 334c838c8f42d61a94813d136019ee566b5dc2f6
@@ -191,7 +191,7 @@ F test/analyze.test 2f55535aa335785db1a2f97d3f3831c16c09f8b0
 F test/async.test aecaa46ed0618a3c338f3651ca4f10fbb4021044
 F test/async2.test 8998e089b0fbb3d84cdd51c25a78833486d721af
 F test/async3.test 9ffa0977a78cc6351862a1583be2b1eecd41736d
-F test/attach.test 72529edb04115675894a7399609983ea46b73ba6
+F test/attach.test 4ab582932e3c815689f61afcdb9bce245f0bac53
 F test/attach2.test a295d2d7061adcee5884ef4a93c7c96a82765437
 F test/attach3.test 7b92dc8e40c1ebca9732ca6f2d3fefbd46f196df
 F test/attachmalloc.test 56c5e55563dba6d64641ef2f70ce06900df16912
@@ -615,7 +615,7 @@ F www/tclsqlite.tcl 8be95ee6dba05eabcd27a9d91331c803f2ce2130
 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
 F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
 F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5
-P 1d478e9091ef5775297ca4d50c85e39ccdf9e245
-R 271ed5b5d67fc1b6c6bee774d9b672d0
+P fccb217d91d08c5a2f5d51b21c6035474931957b
+R 824bd1a91af55f8de7934eee79d69c99
 U drh
-Z 6f8d1336c7b203985a0086e6d71252ce
+Z 2d09480bf715861bf09008aeafdc8195
index 7d12df0cda90a974d5de608f74edae1b2de2b887..d807abbf4ef93dc3325aa2111a9d11eb1e48d948 100644 (file)
@@ -1 +1 @@
-fccb217d91d08c5a2f5d51b21c6035474931957b
\ No newline at end of file
+c24616204307936d03d39d2ef0fe6856113f6977
\ No newline at end of file
index 63ad3c7b7b85b4d6c7e69fe43496f4273935b616..67a34b7b0842c30fff78f0eb17823d75f05b1b60 100644 (file)
@@ -11,7 +11,7 @@
 *************************************************************************
 ** This file contains code used to implement the ATTACH and DETACH commands.
 **
-** $Id: attach.c,v 1.70 2008/01/23 03:03:05 drh Exp $
+** $Id: attach.c,v 1.71 2008/02/06 14:11:35 drh Exp $
 */
 #include "sqliteInt.h"
 
@@ -222,6 +222,7 @@ attach_error:
     zErr[sizeof(zErr)-1] = 0;
     sqlite3_result_error(context, zErr, -1);
   }
+  if( rc ) sqlite3_result_error_code(context, rc);
 }
 
 /*
index e8d56b4e8bad5d8d19b607efac9aadcae3ebf12a..9b1aaf6ae3e5d05e9a875026ee30e72a1392a50d 100644 (file)
@@ -30,7 +30,7 @@
 ** the version number) and changes its name to "sqlite3.h" as
 ** part of the build process.
 **
-** @(#) $Id: sqlite.h.in,v 1.283 2008/01/31 17:21:22 drh Exp $
+** @(#) $Id: sqlite.h.in,v 1.284 2008/02/06 14:11:35 drh Exp $
 */
 #ifndef _SQLITE3_H_
 #define _SQLITE3_H_
@@ -3560,6 +3560,9 @@ typedef void (*sqlite3_destructor_type)(void*);
 ** routines make a copy private copy of the error message text before
 ** they return.  {END} Hence, the calling function can deallocate or
 ** modify the text after they return without harm.
+** The sqlite3_result_error_code() function changes the error code
+** returned by SQLite as a result of an error in a function.  By default,
+** the error code is SQLITE_ERROR. 
 **
 ** {F16421} The sqlite3_result_toobig() interface causes SQLite
 ** to throw an error indicating that a string or BLOB is to long
@@ -3622,6 +3625,7 @@ void sqlite3_result_error(sqlite3_context*, const char*, int);
 void sqlite3_result_error16(sqlite3_context*, const void*, int);
 void sqlite3_result_error_toobig(sqlite3_context*);
 void sqlite3_result_error_nomem(sqlite3_context*);
+void sqlite3_result_error_code(sqlite3_context*, int);
 void sqlite3_result_int(sqlite3_context*, int);
 void sqlite3_result_int64(sqlite3_context*, sqlite3_int64);
 void sqlite3_result_null(sqlite3_context*);
index 2f70449b8935ba2c04bea64fc45b72143ec477cf..2901752a18cc339f2ab54f3960888ae38f897256 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.707 2008/01/31 19:34:52 drh Exp $
+** $Id: vdbe.c,v 1.708 2008/02/06 14:11:35 drh Exp $
 */
 #include "sqliteInt.h"
 #include <ctype.h>
@@ -1245,7 +1245,7 @@ case OP_Function: {
   /* If the function returned an error, throw an exception */
   if( ctx.isError ){
     sqlite3SetString(&p->zErrMsg, sqlite3_value_text(&ctx.s), (char*)0);
-    rc = SQLITE_ERROR;
+    rc = ctx.isError;
   }
 
   /* Copy the result of the function into register P3 */
@@ -4218,7 +4218,7 @@ case OP_AggStep: {
   (ctx.pFunc->xStep)(&ctx, n, apVal);
   if( ctx.isError ){
     sqlite3SetString(&p->zErrMsg, sqlite3_value_text(&ctx.s), (char*)0);
-    rc = SQLITE_ERROR;
+    rc = ctx.isError;
   }
   sqlite3VdbeMemRelease(&ctx.s);
   break;
index a52df361951ba129b62ba3c1d9a6a86d9c01d117..407ed49c92bf58aab2496b80c68dc701db3a9b86 100644 (file)
@@ -209,7 +209,7 @@ struct sqlite3_context {
   VdbeFunc *pVdbeFunc;  /* Auxilary data, if created. */
   Mem s;                /* The return value is stored here */
   Mem *pMem;            /* Memory cell used to store aggregate context */
-  u8 isError;           /* Set to true for an error */
+  int isError;          /* Error code returned by the function. */
   CollSeq *pColl;       /* Collating sequence */
 };
 
index df9c75f68068567c7d2dcc277e5a464cdb32cb6e..e756c705152ff335b3af1abf2abccf598355ddfd 100644 (file)
@@ -163,13 +163,13 @@ void sqlite3_result_double(sqlite3_context *pCtx, double rVal){
 }
 void sqlite3_result_error(sqlite3_context *pCtx, const char *z, int n){
   assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
-  pCtx->isError = 1;
+  pCtx->isError = SQLITE_ERROR;
   sqlite3VdbeMemSetStr(&pCtx->s, z, n, SQLITE_UTF8, SQLITE_TRANSIENT);
 }
 #ifndef SQLITE_OMIT_UTF16
 void sqlite3_result_error16(sqlite3_context *pCtx, const void *z, int n){
   assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
-  pCtx->isError = 1;
+  pCtx->isError = SQLITE_ERROR;
   sqlite3VdbeMemSetStr(&pCtx->s, z, n, SQLITE_UTF16NATIVE, SQLITE_TRANSIENT);
 }
 #endif
@@ -231,6 +231,9 @@ void sqlite3_result_zeroblob(sqlite3_context *pCtx, int n){
   assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
   sqlite3VdbeMemSetZeroBlob(&pCtx->s, n);
 }
+void sqlite3_result_error_code(sqlite3_context *pCtx, int errCode){
+  pCtx->isError = errCode;
+}
 
 /* Force an SQLITE_TOOBIG error. */
 void sqlite3_result_error_toobig(sqlite3_context *pCtx){
@@ -242,7 +245,7 @@ void sqlite3_result_error_toobig(sqlite3_context *pCtx){
 void sqlite3_result_error_nomem(sqlite3_context *pCtx){
   assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
   sqlite3VdbeMemSetNull(&pCtx->s);
-  pCtx->isError = 1;
+  pCtx->isError = SQLITE_NOMEM;
   pCtx->s.db->mallocFailed = 1;
 }
 
index 096bb85faecaea59019da703cdca1665aef75ad9..3cb0c2db3e89ef7a3826a3daf949e50661984ca6 100644 (file)
@@ -12,7 +12,7 @@
 # focus of this script is testing the ATTACH and DETACH commands
 # and related functionality.
 #
-# $Id: attach.test,v 1.47 2007/10/09 08:29:32 danielk1977 Exp $
+# $Id: attach.test,v 1.48 2008/02/06 14:11:35 drh Exp $
 #
 
 set testdir [file dirname $argv0]
@@ -118,6 +118,9 @@ do_test attach-1.12 {
     ATTACH 'test.db' as db2;
   }
 } {1 {database db2 is already in use}}
+do_test attach-1.12.2 {
+  db errorcode
+} {1}
 do_test attach-1.13 {
   catchsql {
     ATTACH 'test.db' as db5;
@@ -156,6 +159,9 @@ do_test attach-1.19 {
     ATTACH 'test.db' as db12;
   }
 } {1 {too many attached databases - max 10}}
+do_test attach-1.19.1 {
+  db errorcode
+} {1}
 do_test attach-1.20.1 {
   execsql {
     DETACH db5;
@@ -180,6 +186,9 @@ do_test attach-1.22 {
     ATTACH 'test.db' as db13;
   }
 } {1 {too many attached databases - max 10}}
+do_test attach-1.22.1 {
+  db errorcode
+} {1}
 do_test attach-1.23 {
   catchsql {
     DETACH "db14";
@@ -724,6 +733,9 @@ if {$tcl_platform(platform)=="unix"} {
       ATTACH DATABASE 'cannot-read' AS noread;
     }
   } {1 {unable to open database: cannot-read}}
+  do_test attach-6.2.2 {
+    db errorcode
+  } {14}
   file delete -force cannot-read
 }
 
@@ -752,4 +764,34 @@ ifcapable subquery {
   } {1 {invalid name: "RAISE ( IGNORE ) IN ( SELECT "AAAAAA" . * ORDER BY 
       REGISTER LIMIT "AAAAAA" . "AAAAAA" OFFSET RAISE ( IGNORE ) NOT NULL )"}}
 }
+
+# Create a malformed file (a file that is not a valid database)
+# and try to attach it
+#
+do_test attach-8.1 {
+  set fd [open test2.db w]
+  puts $fd "This file is not a valid SQLite database"
+  close $fd
+  catchsql {
+    ATTACH 'test2.db' AS t2;
+  }
+} {1 {file is encrypted or is not a database}}
+do_test attach-8.2 {
+  db errorcode
+} {26}
+file delete -force test2.db
+do_test attach-8.3 {
+  sqlite3 db2 test2.db
+  db2 eval {CREATE TABLE t1(x); BEGIN EXCLUSIVE}
+  catchsql {
+    ATTACH 'test2.db' AS t2;
+  }
+} {1 {database is locked}}
+do_test attach-8.4 {
+  db errorcode
+} {5}
+db2 close
+file delete -force test2.db
+
+
 finish_test