diff --git a/manifest b/manifest index fdb098b372..d43af6334a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Eliminate\sthe\sOP_SortMakeRec\sand\sOP_SortCallback\sopcodes.\s\sSort\susing\sthe\nstandard\srecord\sformat.\s(CVS\s1426) -D 2004-05-21T03:01:59 +C Further\swork\son\sthe\snew\sAPI.\sAll\sthe\sfunctions\sto\sexecute\squeries\sare\sthere\nnow.\s(CVS\s1427) +D 2004-05-21T10:08:54 F Makefile.in ab7b0d5118e2da97bac66be8684a1034e3500f5a F Makefile.linux-gcc b86a99c493a5bfb402d1d9178dcdc4bd4b32f906 F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd @@ -37,7 +37,7 @@ F src/func.c cfbb7096efb58e2857e3b312a8958a12774b625a F src/hash.c 440c2f8cb373ee1b4e13a0988489c7cd95d55b6f F src/hash.h 762d95f1e567664d1eafc1687de755626be962fb F src/insert.c e510d62d23b4de4d901e7ccbbe7833b7fb3b9570 -F src/main.c a9ee98262a12454c72741d94da2317119d3a1071 +F src/main.c 02969649ff887304534293d714efdbe47e24eb33 F src/md5.c 8e39fdae6d8776b87558e91dcc94740c9b635a9c F src/os.c ddcda92f7fd71b4513c57c1ec797917f206d504e F src/os.h 6e446a17cbeb6c2ce470683a0bb8d9c63abe8607 @@ -49,11 +49,11 @@ F src/printf.c ef750e8e2398ca7e8b58be991075f08c6a7f0e53 F src/random.c eff68e3f257e05e81eae6c4d50a51eb88beb4ff3 F src/select.c 7d77a8bed7eeac23216d42fc1be006fb4352fcdc F src/shell.c 0c4662e13bfbfd3d13b066c5859cc97ad2f95d21 -F src/sqlite.h.in de337e211905c6bd4ad901916f78df28f1467df4 -F src/sqliteInt.h 2e5533ba50106d266cddfb00b2eb3ab6944b8f3e +F src/sqlite.h.in 75b6eb9eeff3e84052444584b5ad4f0d9a81b8ac +F src/sqliteInt.h a7b3f10c5e7231abee9ef12ee2d986554ad073df F src/table.c af14284fa36c8d41f6829e3f2819dce07d3e2de2 F src/tclsqlite.c fbf0fac73624ae246551a6c671f1de0235b5faa1 -F src/test1.c c72aed60609038b25c0782ec69b71f33f1157d64 +F src/test1.c e5ba63a9a36fe34f48e3363887984c4d71dbf066 F src/test2.c 6195a1ca2c8d0d2d93644e86da3289b403486872 F src/test3.c 5e4a6d596f982f6f47a5f9f75ede9b4a3b739968 F src/test4.c b3fab9aea7a8940a8a7386ce1c7e2157b09bd296 @@ -64,25 +64,25 @@ F src/update.c 1a5e9182596f3ea8c7a141e308a3d2a7e5689fee F src/utf.c c27c4f1120f7aaef00cd6942b3d9e3f4ca4fe0e4 F src/util.c 5cbeb452da09cfc7248de9948c15b14d840723f7 F src/vacuum.c c134702e023db8778e6be59ac0ea7b02315b5476 -F src/vdbe.c 4138d2f3ec2dd2b62251fc2b34e3c73322d8288e -F src/vdbe.h d6f66896137af3e313d44553618228d882a2cf85 -F src/vdbeInt.h cea492c1fcd85fb78f031e274d1844885d5222e2 -F src/vdbeaux.c 51f7d0cc6c515111b11576e2d82f4637156075cd +F src/vdbe.c cafe464b807f480491e4e5212833af1b78e75c3c +F src/vdbe.h 391d5642a83af686f35c228fcd36cb4456d68f44 +F src/vdbeInt.h 8ed2272e97bef20c5302c3b2cb4f900e8b5e2642 +F src/vdbeaux.c bceaa0b9756d547c5dba871676e5cfc19f4f4322 F src/where.c efe5d25fe18cd7381722457898cd863e84097a0c F test/all.test 569a92a8ee88f5300c057cc4a8f50fbbc69a3242 F test/attach.test cb9b884344e6cfa5e165965d5b1adea679a24c83 -F test/attach2.test 7a722607c1fa37837d3b2717605357d89b86c8b9 +F test/attach2.test 5472d442bb2ef1ee587e0ae7472bb68b52509a38 F test/auth.test 5c4d95cdaf539c0c236e20ce1f71a93e7dde9185 F test/bigfile.test ea904b853ce2d703b16c5ce90e2b54951bc1ae81 F test/bigrow.test 8ab252dba108f12ad64e337b0f2ff31a807ac578 -F test/bind.test f228f64e3d2258c2395ece636b82c492ffbddc4a +F test/bind.test 87a6c083da06b05c87a2a507ca5f566af0b53602 F test/btree.test 08e4093c78d2bc1d54e27266f8d17fed14751125 F test/btree2.test aa4a6d05b1ea90b1acaf83ba89039dd302a88635 F test/btree4.test 3797b4305694c7af6828675b0f4b1424b8ca30e4 F test/btree5.test 8e5ff32c02e685d36516c6499add9375fe1377f2 F test/btree6.test a5ede6bfbbb2ec8b27e62813612c0f28e8f3e027 -F test/capi2.test 007f856cc7fe5a9aaeb076d2df9aff92012a0d5e -F test/capi3.test ff3dfacdd07abad140c17eb58b235623c6957322 +F test/capi2.test 8fb64e8ab7f78b8254cd4d04bb96822167f731b2 +F test/capi3.test 5b01d70ec1510e6cee053b2a80ad3aa96ae2acf2 F test/conflict.test 0911bb2f079046914a6e9c3341b36658c4e2103e F test/copy.test f07ea8d60878da7a67416ab62f78e9706b9d3c45 F test/crashtest1.c 09c1c7d728ccf4feb9e481671e29dda5669bbcc2 @@ -137,7 +137,7 @@ F test/table.test 50e4534552d0385a0e59b3a6d7dde059ced02f83 F test/tableapi.test e0c4cce61e58343caa84dab33fa6823cb35fe1e1 F test/tclsqlite.test a684fc191b81e6cded8a81263663d5a130fbb013 F test/temptable.test a770ba6308d7f7332fce985086b8e06bed6430c2 -F test/tester.tcl 8c234ba903a437ce8c8a58f388d120310b54b44c +F test/tester.tcl fc10520db0d3ce4ef6a8b5ab91bd102fc3f4280a F test/thread1.test 53f050d5be6932d9430df7756edd379366508ff6 F test/threadtest1.c f7f896e62ed46feae1dc411114a48c15a0f82ee2 F test/threadtest2.c d94ca4114fd1504f7e0ae724bcd83d4b40931d86 @@ -150,7 +150,7 @@ F test/types.test e1e0d71c8e65f8aa5d9a36751f4c8cbce6f01f7a F test/types2.test 5d725fcb68dbd032c6d4950d568d75fa33872687 F test/unique.test 0e38d4cc7affeef2527720d1dafd1f6870f02f2b F test/update.test b29bd9061a1150426dab6959806fcc73a41b1217 -F test/vacuum.test 7b5f504636a13992344871f8155b8557b683232a +F test/vacuum.test 81417656043f2402ec4a7dd8255f88bb4d1b73af F test/varint.test ab7b110089a08b9926ed7390e7e97bdefeb74102 F test/version.test 2ba212ba06380e65e476bdf2fcd390e8b05af5a0 F test/view.test 1ee12c6f8f4791a2c0655120d5562a49400cfe53 @@ -195,7 +195,7 @@ F www/sqlite.tcl 3c83b08cf9f18aa2d69453ff441a36c40e431604 F www/tclsqlite.tcl b9271d44dcf147a93c98f8ecf28c927307abd6da F www/vdbe.tcl 9b9095d4495f37697fd1935d10e14c6015e80aa1 F www/whentouse.tcl a8335bce47cc2fddb07f19052cb0cb4d9129a8e4 -P 3b55095e036d68886d007239333bbf90acd15692 -R 9a5fbb7a46e686efdfa0c212c6a2c893 -U drh -Z 7b75e8f9ceca75d3da616e75f7688bd6 +P 25643a0137d395572f16cfec3ab3327d913138ba +R 538616d77e95f3accc922466e9ff1ada +U danielk1977 +Z d2021785293946a744d708c10c8e94e3 diff --git a/manifest.uuid b/manifest.uuid index e091b3eeb4..9f5cdd4fb7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -25643a0137d395572f16cfec3ab3327d913138ba \ No newline at end of file +fc94575d77f9865e1553bb70c2e3eda2a0b8669e \ No newline at end of file diff --git a/src/main.c b/src/main.c index 186c012b84..0ef79c68b8 100644 --- a/src/main.c +++ b/src/main.c @@ -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.179 2004/05/21 01:47:27 danielk1977 Exp $ +** $Id: main.c,v 1.180 2004/05/21 10:08:54 danielk1977 Exp $ */ #include "sqliteInt.h" #include "os.h" @@ -1361,6 +1361,32 @@ int sqlite3_open16( return rc; } +/* +** The following routine destroys a virtual machine that is created by +** the sqlite3_compile() routine. The integer returned is an SQLITE_ +** success/failure code that describes the result of executing the virtual +** machine. +** +** This routine sets the error code and string returned by +** sqlite3_errcode(), sqlite3_errmsg() and sqlite3_errmsg16(). +*/ +int sqlite3_finalize_new(sqlite3_stmt *pStmt){ + return sqlite3VdbeFinalize((Vdbe*)pStmt, 0); +} + +/* +** Terminate the current execution of an SQL statement and reset it +** back to its starting state so that it can be reused. A success code from +** the prior execution is returned. +** +** This routine sets the error code and string returned by +** sqlite3_errcode(), sqlite3_errmsg() and sqlite3_errmsg16(). +*/ +int sqlite3_reset_new(sqlite3_stmt *pStmt){ + int rc = sqlite3VdbeReset((Vdbe*)pStmt, 0); + sqlite3VdbeMakeReady((Vdbe*)pStmt, -1, 0); + return rc; +} #if 0 diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 123d1268ed..3a3a697b13 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -12,7 +12,7 @@ ** This header file defines the interface that the SQLite library ** presents to client programs. ** -** @(#) $Id: sqlite.h.in,v 1.67 2004/05/21 01:47:27 danielk1977 Exp $ +** @(#) $Id: sqlite.h.in,v 1.68 2004/05/21 10:08:54 danielk1977 Exp $ */ #ifndef _SQLITE_H_ #define _SQLITE_H_ @@ -998,6 +998,12 @@ int sqlite3_bind_blob(sqlite3_stmt*, int i, const void *z, int n, int eCopy); ** sqlite3_bind_text ** sqlite3_bind_text16 ** sqlite3_bind_blob +** sqlite3_open +** sqlite3_open16 +** sqlite3_prepare +** sqlite3_prepare16 +** sqlite3_step +** sqlite3_finalize ** ** Assuming no other intervening sqlite3_* API calls are made, the error ** code returned by this function is associated with the same error as @@ -1032,9 +1038,9 @@ const void *sqlite3_errmsg16(sqlite3*); ** to be compiled, encoded as UTF-8 text. If the next parameter, "nBytes", ** is less than zero, then zSql is read up to the first nul terminator. ** If "nBytes" is not less than zero, then it is the length of the -** string zSql, in bytes (not characters). +** string zSql in bytes (not characters). ** -** *pzTail is made to point to the first character past the end of the first +** *pzTail is made to point to the first byte past the end of the first ** SQL statement in zSql. This routine only compiles the first statement ** in zSql, so *pzTail is left pointing to what remains uncompiled. ** @@ -1054,6 +1060,27 @@ int sqlite3_prepare( const char **pzTail /* OUT: Pointer to unused portion of zSql */ ); +/* +** To execute an SQL query, it must first be compiled into a byte-code +** program using this routine. The first parameter "db" is an SQLite +** database handle. The second parameter "zSql" is the statement +** to be compiled, encoded as UTF-16 text. If the next parameter, "nBytes", +** is less than zero, then zSql is read up to the first pair of successive +** 0x00 bytes. If "nBytes" is not less than zero, then it is the length of +** the string zSql in bytes (not characters). +** +** *pzTail is made to point to the first byte past the end of the first +** SQL statement in zSql. This routine only compiles the first statement +** in zSql, so *pzTail is left pointing to what remains uncompiled. +** +** *ppStmt is left pointing to a compiled SQL statement that can be +** executed using sqlite3_step(). Or if there is an error, *ppStmt may be +** set to NULL. If the input text contained no SQL (if the input is and +** empty string or a comment) then *ppStmt is set to NULL. +** +** On success, SQLITE_OK is returned. Otherwise an error code is returned. +** +*/ int sqlite3_prepare16( sqlite3 *db, /* Database handle */ const void *zSql, /* SQL statement, UTF-16 encoded */ @@ -1062,6 +1089,120 @@ int sqlite3_prepare16( const void **pzTail /* OUT: Pointer to unused portion of zSql */ ); +/* +** Return the number of columns in the result set returned by the compiled +** SQL statement. This routine returns 0 if pStmt is an SQL statement +** that does not return data (for example an UPDATE). +*/ +int sqlite3_column_count(sqlite3_stmt *pStmt); + +/* +** The first parameter is a compiled SQL statement. This function returns +** the column heading for the Nth column of that statement, where N is the +** second function parameter. The string returned is UTF-8 encoded. +*/ +const char *sqlite3_column_name(sqlite3_stmt*,int); + +/* +** The first parameter is a compiled SQL statement. This function returns +** the column heading for the Nth column of that statement, where N is the +** second function parameter. The string returned is UTF-16 encoded. +*/ +const void *sqlite3_column_name16(sqlite3_stmt*,int); + +/* +** The first parameter is a compiled SQL statement. If this statement +** is a SELECT statement, the Nth column of the returned result set +** of the SELECT is a table column then the declared type of the table +** column is returned. If the Nth column of the result set is not at table +** column, then a NULL pointer is returned. The returned string is always +** UTF-8 encoded. For example, in the database schema: +** +** CREATE TABLE t1(c1 VARINT); +** +** And the following statement compiled: +** +** SELECT c1 + 1, 0 FROM t1; +** +** Then this routine would return the string "VARIANT" for the second +** result column (i==1), and a NULL pointer for the first result column +** (i==0). +*/ +const char *sqlite3_column_decltype(sqlite3_stmt *, int i); + +/* +** The first parameter is a compiled SQL statement. If this statement +** is a SELECT statement, the Nth column of the returned result set +** of the SELECT is a table column then the declared type of the table +** column is returned. If the Nth column of the result set is not at table +** column, then a NULL pointer is returned. The returned string is always +** UTF-16 encoded. For example, in the database schema: +** +** CREATE TABLE t1(c1 VARINT); +** +** And the following statement compiled: +** +** SELECT c1 + 1, 0 FROM t1; +** +** Then this routine would return the string "VARIANT" for the second +** result column (i==1), and a NULL pointer for the first result column +** (i==0). +*/ +const void *sqlite3_column_decltype16(sqlite3_stmt*,int); + +/* +** After an SQL query has been compiled with a call to either +** sqlite3_prepare() or sqlite3_prepare16(), then this function must be +** called one or more times to execute the statement. +** +** The return value will be either SQLITE_BUSY, SQLITE_DONE, +** SQLITE_ROW, SQLITE_ERROR, or SQLITE_MISUSE. +** +** SQLITE_BUSY means that the database engine attempted to open +** a locked database and there is no busy callback registered. +** Call sqlite3_step() again to retry the open. +** +** SQLITE_DONE means that the statement has finished executing +** successfully. sqlite3_step() should not be called again on this virtual +** machine. +** +** If the SQL statement being executed returns any data, then +** SQLITE_ROW is returned each time a new row of data is ready +** for processing by the caller. The values may be accessed using +** the sqlite3_column_*() functions described below. sqlite3_step() +** is called again to retrieve the next row of data. +** +** SQLITE_ERROR means that a run-time error (such as a constraint +** violation) has occurred. sqlite3_step() should not be called again on +** the VM. More information may be found by calling sqlite3_errmsg(). +** +** SQLITE_MISUSE means that the this routine was called inappropriately. +** Perhaps it was called on a virtual machine that had already been +** finalized or on one that had previously returned SQLITE_ERROR or +** SQLITE_DONE. Or it could be the case the the same database connection +** is being used simulataneously by two or more threads. +*/ +int sqlite3_step_new(sqlite3_stmt*); + + +/* +** The sqlite3_finalize() function is called to delete a compiled +** SQL statement obtained by a previous call to sqlite3_prepare() +** or sqlite3_prepare16(). If the statement was executed successfully, or +** not executed at all, then SQLITE_OK is returned. If execution of the +** statement failed then an error code is returned. +*/ +int sqlite3_finalize_new(sqlite3_stmt *pStmt); + +/* +** The sqlite3_reset() function is called to reset a compiled SQL +** statement obtained by a previous call to sqlite3_prepare() or +** sqlite3_prepare16() back to it's initial state, ready to be re-executed. +** Any SQL statement variables that had values bound to them using +** the sqlite3_bind_*() API retain their values. +*/ +int sqlite3_reset_new(sqlite3_stmt *pStmt); + int sqlite3_open_new( const char *filename, /* Database filename (UTF-8) */ sqlite3 **ppDb, /* OUT: SQLite db handle */ @@ -1074,15 +1215,16 @@ int sqlite3_open16( const char **args /* Null terminated array of option strings */ ); - -#if 0 - -int sqlite3_close(sqlite3*); - -int sqlite3_finalize(sqlite3_stmt*); -int sqlite3_reset(sqlite3_stmt*); - -int sqlite3_step(sqlite3_stmt*); +/* +** Return the number of values in the current row of the result set. +** +** After a call to sqlite3_step() that returns SQLITE_ROW, this routine +** will return the same value as the sqlite3_column_count() function. +** After sqlite3_step() has returned an SQLITE_DONE, SQLITE_BUSY or +** error code, or before sqlite3_step() has been called on a +** compiled SQL statement, this routine returns zero. +*/ +int sqlite3_value_count(sqlite3_stmt *pStmt); #define SQLITE3_INTEGER 1 #define SQLITE3_FLOAT 2 @@ -1090,19 +1232,90 @@ int sqlite3_step(sqlite3_stmt*); #define SQLITE3_BLOB 4 #define SQLITE3_NULL 5 -int sqlite3_column_count(sqlite3_stmt*); -int sqlite3_column_type(sqlite3_stmt*,int); -const char *sqlite3_column_decltype(sqlite3_stmt*,int); -const void *sqlite3_column_decltype16(sqlite3_stmt*,int); -const char *sqlite3_column_name(sqlite3_stmt*,int); -const void *sqlite3_column_name16(sqlite3_stmt*,int); -const unsigned char *sqlite3_column_data(sqlite3_stmt*,int); -const void *sqlite3_column_data16(sqlite3_stmt*,int); -int sqlite3_column_bytes(sqlite3_stmt*,int); -long long int sqlite3_column_int(sqlite3_stmt*,int); -double sqlite3_column_float(sqlite3_stmt*,int); +/* +** The first parameter is a compiled SQL statement for which the most +** recent call to sqlite3_step() has returned SQLITE_ROW. This routine +** retrieves the type of the Nth column of the current row, where +** N is the second function parameter. +** +** The value type is one of SQLITE3_INTEGER, SQLITE3_FLOAT, SQLITE3_TEXT, +** SQLITE3_BLOB and SQLITE3_NULL. +*/ +int sqlite3_column_type(sqlite3_stmt *pStmt, int i); -#endif +/* +** The first parameter is a compiled SQL statement for which the most +** recent call to sqlite3_step() has returned SQLITE_ROW. This routine +** retrieves the value of the Nth column of the current row, where +** N is the second function parameter. +** +** The value returned depends on the type of the SQL column value, as +** returned by sqlite3_column_type(): +** +** SQLITE3_NULL A Null pointer. +** SQLITE3_INTEGER String representation of the integer, UTF-8 encoded. +** SQLITE3_FLOAT String representation of the real, UTF-8 encoded. +** SQLITE3_TEXT The string UTF-8 encoded. +** SQLITE3_BLOB A pointer to the blob of data. +*/ +const unsigned char *sqlite3_column_data(sqlite3_stmt*,int); + +/* +** The first parameter is a compiled SQL statement for which the most +** recent call to sqlite3_step() has returned SQLITE_ROW. This routine +** retrieves the value of the Nth column of the current row, where +** N is the second function parameter. +** +** The value returned depends on the type of the SQL column value, as +** returned by sqlite3_column_type(): +** +** SQLITE3_NULL A Null pointer. +** SQLITE3_INTEGER String representation of the integer, UTF-16 encoded. +** SQLITE3_FLOAT String representation of the real, UTF-16 encoded. +** SQLITE3_TEXT The string UTF-16 encoded. +** SQLITE3_BLOB A pointer to the blob of data. +*/ +const void *sqlite3_column_data16(sqlite3_stmt*,int); + +/* +** The first parameter is a compiled SQL statement for which the most +** recent call to sqlite3_step() has returned SQLITE_ROW. This routine +** retrieves the length of the data in bytse returned by the +** sqlite3_column_data() routine for the same second parameter value. +** +** If sqlite3_column_data() returns a UTF-8 string, then the length +** returned by this function includes the nul terminator character at the +** end of the UTF-8 string. +*/ +int sqlite3_column_bytes(sqlite3_stmt*,int); + +/* +** The first parameter is a compiled SQL statement for which the most +** recent call to sqlite3_step() has returned SQLITE_ROW. This routine +** retrieves the value of the Nth column of the current row, where +** N is the second function parameter as an integer. +** +** SQLITE3_NULL 0 +** SQLITE3_INTEGER The integer value. +** SQLITE3_FLOAT The integer component of the real (2^63 if too large) +** SQLITE3_TEXT Integer conversion of string, or 0 +** SQLITE3_BLOB 0 +*/ +long long int sqlite3_column_int(sqlite3_stmt*,int); + +/* +** The first parameter is a compiled SQL statement for which the most +** recent call to sqlite3_step() has returned SQLITE_ROW. This routine +** retrieves the value of the Nth column of the current row, where +** N is the second function parameter as an integer. +** +** SQLITE3_NULL 0.0 +** SQLITE3_INTEGER The value of the integer. Some rounding may occur. +** SQLITE3_FLOAT The value of the float. +** SQLITE3_TEXT Real number conversion of string, or 0.0 +** SQLITE3_BLOB 0.0 +*/ +double sqlite3_column_float(sqlite3_stmt*,int); #ifdef __cplusplus } /* End of the 'extern "C"' block */ diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 03dbfaaf67..5d8cee4c3b 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -11,7 +11,7 @@ ************************************************************************* ** Internal interface definitions for SQLite. ** -** @(#) $Id: sqliteInt.h,v 1.243 2004/05/21 01:47:27 danielk1977 Exp $ +** @(#) $Id: sqliteInt.h,v 1.244 2004/05/21 10:08:54 danielk1977 Exp $ */ #include "config.h" #include "sqlite.h" @@ -322,6 +322,7 @@ struct Db { #define TEXT_Utf8 1 #define TEXT_Utf16le 2 #define TEXT_Utf16be 3 +#define TEXT_Utf16 4 /* ** Each database is an instance of the following structure. @@ -1360,3 +1361,4 @@ int sqlite3IndexAffinityOk(Expr *pExpr, char idx_affinity); char sqlite3ExprAffinity(Expr *pExpr); int sqlite3atoi64(const char*, i64*); void sqlite3Error(sqlite *, int, const char*,...); + diff --git a/src/test1.c b/src/test1.c index 9a86ddff9f..959a9f7479 100644 --- a/src/test1.c +++ b/src/test1.c @@ -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.44 2004/05/21 01:47:27 danielk1977 Exp $ +** $Id: test1.c,v 1.45 2004/05/21 10:08:54 danielk1977 Exp $ */ #include "sqliteInt.h" #include "tcl.h" @@ -812,31 +812,58 @@ static int test_step( } /* -** Usage: sqlite3_finalize VM +** Usage: sqlite3_finalize STMT ** -** Shutdown a virtual machine. +** Finalize a statement handle. */ static int test_finalize( - void *NotUsed, - Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ - int argc, /* Number of arguments */ - char **argv /* Text of each argument */ + void * clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *CONST objv[] ){ - sqlite_vm *vm; + sqlite3_stmt *pStmt; int rc; - char *zErrMsg = 0; - if( argc!=2 ){ - Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], - " VM\"", 0); + + if( objc!=2 ){ + Tcl_AppendResult(interp, "wrong # args: should be \"", + Tcl_GetStringFromObj(objv[0], 0), " ", 0); return TCL_ERROR; } - if( getVmPointer(interp, argv[1], &vm) ) return TCL_ERROR; - rc = sqlite3_finalize(vm, &zErrMsg); + + if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; + + rc = sqlite3_finalize_new(pStmt); + if( rc ){ + return TCL_ERROR; + } + return TCL_OK; +} + +/* +** Usage: sqlite3_reset STMT +** +** Finalize a statement handle. +*/ +static int test_reset( + void * clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *CONST objv[] +){ + sqlite3_stmt *pStmt; + int rc; + + if( objc!=2 ){ + Tcl_AppendResult(interp, "wrong # args: should be \"", + Tcl_GetStringFromObj(objv[0], 0), " ", 0); + return TCL_ERROR; + } + + if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; + + rc = sqlite3_reset_new(pStmt); if( rc ){ - char zBuf[50]; - sprintf(zBuf, "(%d) ", rc); - Tcl_AppendResult(interp, zBuf, zErrMsg, 0); - sqlite3_freemem(zErrMsg); return TCL_ERROR; } return TCL_OK; @@ -847,31 +874,6 @@ static int test_finalize( ** ** Reset a virtual machine and prepare it to be run again. */ -static int test_reset( - void *NotUsed, - Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ - int argc, /* Number of arguments */ - char **argv /* Text of each argument */ -){ - sqlite_vm *vm; - int rc; - char *zErrMsg = 0; - if( argc!=2 ){ - Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], - " VM\"", 0); - return TCL_ERROR; - } - if( getVmPointer(interp, argv[1], &vm) ) return TCL_ERROR; - rc = sqlite3_reset(vm, &zErrMsg); - if( rc ){ - char zBuf[50]; - sprintf(zBuf, "(%d) ", rc); - Tcl_AppendResult(interp, zBuf, zErrMsg, 0); - sqlite3_freemem(zErrMsg); - return TCL_ERROR; - } - return TCL_OK; -} /* ** This is the "static_bind_value" that variables are bound to when @@ -1400,6 +1402,33 @@ static int test_open16( return TCL_OK; } +/* +** Usage: sqlite3_step STMT +** +** Advance the statement to the next row. +*/ +static int test_step_new( + void * clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *CONST objv[] +){ + sqlite3_stmt *pStmt; + int rc; + + if( objc!=3 ){ + Tcl_AppendResult(interp, "wrong # args: should be \"", + Tcl_GetString(objv[0]), " STMT", 0); + return TCL_ERROR; + } + + if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; + rc = sqlite3_step_new(pStmt); + + if( rc!=SQLITE_OK ) return TCL_ERROR; + return TCL_OK; +} + /* ** This is a collating function named "REVERSE" which sorts text ** in reverse order. @@ -1474,9 +1503,9 @@ int Sqlitetest1_Init(Tcl_Interp *interp){ { "sqlite_malloc_stat", (Tcl_CmdProc*)sqlite_malloc_stat }, #endif { "sqlite_step", (Tcl_CmdProc*)test_step }, - { "sqlite_finalize", (Tcl_CmdProc*)test_finalize }, +// { "sqlite_finalize", (Tcl_CmdProc*)test_finalize }, { "sqlite_bind", (Tcl_CmdProc*)test_bind }, - { "sqlite_reset", (Tcl_CmdProc*)test_reset }, +// { "sqlite_reset", (Tcl_CmdProc*)test_reset }, { "breakpoint", (Tcl_CmdProc*)test_breakpoint }, }; static struct { @@ -1497,6 +1526,9 @@ int Sqlitetest1_Init(Tcl_Interp *interp){ { "sqlite3_prepare16", (Tcl_ObjCmdProc*)test_prepare16 }, { "sqlite3_open", (Tcl_ObjCmdProc*)test_open }, { "sqlite3_open16", (Tcl_ObjCmdProc*)test_open16 }, + { "sqlite3_finalize", (Tcl_ObjCmdProc*)test_finalize }, + { "sqlite3_reset", (Tcl_ObjCmdProc*)test_reset }, + { "sqlite3_step", (Tcl_ObjCmdProc*)test_step_new }, { "add_reverse_collating_func", (Tcl_ObjCmdProc*)reverse_collfunc }, }; int i; diff --git a/src/vdbe.c b/src/vdbe.c index 849ffe10f7..c81fb67b62 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -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.312 2004/05/21 03:01:59 drh Exp $ +** $Id: vdbe.c,v 1.313 2004/05/21 10:08:54 danielk1977 Exp $ */ #include "sqliteInt.h" #include "os.h" @@ -69,126 +69,6 @@ int sqlite3_search_count = 0; */ int sqlite3_interrupt_count = 0; -/* -** Advance the virtual machine to the next output row. -** -** The return vale will be either SQLITE_BUSY, SQLITE_DONE, -** SQLITE_ROW, SQLITE_ERROR, or SQLITE_MISUSE. -** -** SQLITE_BUSY means that the virtual machine attempted to open -** a locked database and there is no busy callback registered. -** Call sqlite3_step() again to retry the open. *pN is set to 0 -** and *pazColName and *pazValue are both set to NULL. -** -** SQLITE_DONE means that the virtual machine has finished -** executing. sqlite3_step() should not be called again on this -** virtual machine. *pN and *pazColName are set appropriately -** but *pazValue is set to NULL. -** -** SQLITE_ROW means that the virtual machine has generated another -** row of the result set. *pN is set to the number of columns in -** the row. *pazColName is set to the names of the columns followed -** by the column datatypes. *pazValue is set to the values of each -** column in the row. The value of the i-th column is (*pazValue)[i]. -** The name of the i-th column is (*pazColName)[i] and the datatype -** of the i-th column is (*pazColName)[i+*pN]. -** -** SQLITE_ERROR means that a run-time error (such as a constraint -** violation) has occurred. The details of the error will be returned -** by the next call to sqlite3_finalize(). sqlite3_step() should not -** be called again on the VM. -** -** SQLITE_MISUSE means that the this routine was called inappropriately. -** Perhaps it was called on a virtual machine that had already been -** finalized or on one that had previously returned SQLITE_ERROR or -** SQLITE_DONE. Or it could be the case the the same database connection -** is being used simulataneously by two or more threads. -*/ -int sqlite3_step( - sqlite_vm *pVm, /* The virtual machine to execute */ - int *pN, /* OUT: Number of columns in result */ - const char ***pazValue, /* OUT: Column data */ - const char ***pazColName /* OUT: Column names and datatypes */ -){ - Vdbe *p = (Vdbe*)pVm; - sqlite *db; - int rc; - - if( p->magic!=VDBE_MAGIC_RUN ){ - return SQLITE_MISUSE; - } - db = p->db; - if( sqlite3SafetyOn(db) ){ - p->rc = SQLITE_MISUSE; - return SQLITE_MISUSE; - } - if( p->explain ){ - rc = sqlite3VdbeList(p); - }else{ - rc = sqlite3VdbeExec(p); - } - if( rc==SQLITE_DONE || rc==SQLITE_ROW ){ - if( pazColName ) *pazColName = (const char**)p->azColName; - if( pN ) *pN = p->nResColumn; - }else{ - if( pazColName) *pazColName = 0; - if( pN ) *pN = 0; - } - if( pazValue ){ - if( rc==SQLITE_ROW ){ - *pazValue = (const char**)p->azResColumn; - }else{ - *pazValue = 0; - } - } - if( sqlite3SafetyOff(db) ){ - return SQLITE_MISUSE; - } - return rc; -} - -/* -** Insert a new aggregate element and make it the element that -** has focus. -** -** Return 0 on success and 1 if memory is exhausted. -*/ -static int AggInsert(Agg *p, char *zKey, int nKey){ - AggElem *pElem, *pOld; - int i; - Mem *pMem; - pElem = sqliteMalloc( sizeof(AggElem) + nKey + - (p->nMem-1)*sizeof(pElem->aMem[0]) ); - if( pElem==0 ) return 1; - pElem->zKey = (char*)&pElem->aMem[p->nMem]; - memcpy(pElem->zKey, zKey, nKey); - pElem->nKey = nKey; - pOld = sqlite3HashInsert(&p->hash, pElem->zKey, pElem->nKey, pElem); - if( pOld!=0 ){ - assert( pOld==pElem ); /* Malloc failed on insert */ - sqliteFree(pOld); - return 0; - } - for(i=0, pMem=pElem->aMem; inMem; i++, pMem++){ - pMem->flags = MEM_Null; - } - p->pCurrent = pElem; - return 0; -} - -/* -** Get the AggElem currently in focus -*/ -#define AggInFocus(P) ((P).pCurrent ? (P).pCurrent : _AggInFocus(&(P))) -static AggElem *_AggInFocus(Agg *p){ - HashElem *pElem = sqliteHashFirst(&p->hash); - if( pElem==0 ){ - AggInsert(p,"",1); - pElem = sqliteHashFirst(&p->hash); - } - return pElem ? sqliteHashData(pElem) : 0; -} - #define NulTermify(P) if(((P)->flags & MEM_Str)==0){hardStringify(P);} \ else if(((P)->flags & MEM_Term)==0){hardNulTermify(P);} static int hardNulTermify(Mem *pStack){ @@ -238,7 +118,7 @@ static int hardNulTermify(Mem *pStack){ ** Convert the given stack entity into a string if it isn't one ** already. */ -#define Stringify(P) if(((P)->flags & MEM_Str)==0){hardStringify(P);} +#define Stringify(P) if(!((P)->flags&(MEM_Str|MEM_Blob))){hardStringify(P);} static int hardStringify(Mem *pStack){ int fg = pStack->flags; if( fg & MEM_Real ){ @@ -250,55 +130,7 @@ static int hardStringify(Mem *pStack){ } pStack->z = pStack->zShort; pStack->n = strlen(pStack->zShort)+1; - pStack->flags = MEM_Str | MEM_Short | MEM_Term; - return 0; -} - -/* -** Convert the given stack entity into a string that has been obtained -** from sqliteMalloc(). This is different from Stringify() above in that -** Stringify() will use the NBFS bytes of static string space if the string -** will fit but this routine always mallocs for space. -** Return non-zero if we run out of memory. -*/ -#define Dynamicify(P) (((P)->flags & MEM_Dyn)==0 ? hardDynamicify(P):0) -static int hardDynamicify(Mem *pStack){ - int fg = pStack->flags; - char *z; - if( (fg & MEM_Str)==0 ){ - hardStringify(pStack); - } - assert( (fg & MEM_Dyn)==0 ); - z = sqliteMallocRaw( pStack->n ); - if( z==0 ) return 1; - memcpy(z, pStack->z, pStack->n); - pStack->z = z; - pStack->flags |= MEM_Dyn; - return 0; -} - -/* -** An ephemeral string value (signified by the MEM_Ephem flag) contains -** a pointer to a dynamically allocated string where some other entity -** is responsible for deallocating that string. Because the stack entry -** does not control the string, it might be deleted without the stack -** entry knowing it. -** -** This routine converts an ephemeral string into a dynamically allocated -** string that the stack entry itself controls. In other words, it -** converts an MEM_Ephem string into an MEM_Dyn string. -*/ -#define Deephemeralize(P) \ - if( ((P)->flags&MEM_Ephem)!=0 && hardDeephem(P) ){ goto no_mem;} -static int hardDeephem(Mem *pStack){ - char *z; - assert( (pStack->flags & MEM_Ephem)!=0 ); - z = sqliteMallocRaw( pStack->n ); - if( z==0 ) return 1; - memcpy(z, pStack->z, pStack->n); - pStack->z = z; - pStack->flags &= ~MEM_Ephem; - pStack->flags |= MEM_Dyn; + pStack->flags = MEM_Str | MEM_Short | MEM_Term | MEM_Utf8; return 0; } @@ -308,19 +140,6 @@ static int hardDeephem(Mem *pStack){ */ #define Release(P) if((P)->flags&MEM_Dyn){ sqliteFree((P)->z); } -/* -** Pop the stack N times. -*/ -static void popStack(Mem **ppTos, int N){ - Mem *pTos = *ppTos; - while( N>0 ){ - N--; - Release(pTos); - pTos--; - } - *ppTos = pTos; -} - /* ** Convert the given stack entity into a integer if it isn't one ** already. @@ -360,6 +179,525 @@ static void hardRealify(Mem *pStack){ pStack->flags |= MEM_Real; } +/* +** If pMem is a string object, this routine sets the encoding of the string +** (to one of UTF-8 or UTF16) and whether or not the string is +** nul-terminated. If pMem is not a string object, then this routine is +** a no-op. +** +** If argument "utf16" is true, then this routine will attempt to convert +** the string to native byte order UTF-16 encoding. Otherwise, the +** conversion is to UTF-8 encoding. If the "term" argument is true, then a +** nul terminator is added to the string if it does not already have one. +** +** +** +** SQLITE_OK is returned if the conversion is successful (or not required). +** SQLITE_NOMEM may be returned if a malloc() fails during conversion +** between formats. +*/ +static int SetEncoding(Mem *pMem, int flags){ + int f; + if( !(pMem->flags&MEM_Str) ){ + return SQLITE_OK; + } + + f = (pMem->flags)&(MEM_Utf8|MEM_Utf16le|MEM_Utf16be|MEM_Term); + assert( flags==(flags&(MEM_Utf8|MEM_Utf16le|MEM_Utf16be|MEM_Term))); + if( f==flags ){ + return SQLITE_OK; + } + + if( (SQLITE3_BIGENDIAN && (f&MEM_Utf16le)) || + (SQLITE3_LITTLEENDIAN && (f&MEM_Utf16be)) ){ + int i; + for(i=0; in; i+=2){ + char c = pMem->z[i]; + pMem->z[i] = pMem->z[i+1]; + pMem->z[i+1] = c; + } + } + + if( (flags&MEM_Utf8) && (f&(MEM_Utf16le|MEM_Utf16be)) ){ + char *z = sqlite3utf16to8(pMem->z, pMem->n); + if( !z ){ + return SQLITE_NOMEM; + } + Release(pMem); + pMem->z = z; + pMem->n = strlen(z)+1; + pMem->flags = (MEM_Utf8|MEM_Dyn|MEM_Str|MEM_Term); + return SQLITE_OK; + } + + if( (flags&MEM_Utf16le) && (f&MEM_Utf8) ){ + char *z = sqlite3utf8to16le(pMem->z, pMem->n); + if( !z ){ + return SQLITE_NOMEM; + } + Release(pMem); + pMem->z = z; + pMem->n = sqlite3utf16ByteLen(z, -1) + 2; + pMem->flags = (MEM_Utf16le|MEM_Dyn|MEM_Str|MEM_Term); + return SQLITE_OK; + } + + if( (flags&MEM_Utf16be) && (f&MEM_Utf8) ){ + char *z = sqlite3utf8to16be(pMem->z, pMem->n); + if( !z ){ + return SQLITE_NOMEM; + } + Release(pMem); + pMem->z = z; + pMem->n = sqlite3utf16ByteLen(z, -1) + 2; + pMem->flags = (MEM_Utf16be|MEM_Dyn|MEM_Str|MEM_Term); + return SQLITE_OK; + } + + if( (flags&MEM_Term) && !(f&&MEM_Term) ){ + NulTermify(pMem); + } + + return SQLITE_OK; +} + +/* +** Convert the given stack entity into a string that has been obtained +** from sqliteMalloc(). This is different from Stringify() above in that +** Stringify() will use the NBFS bytes of static string space if the string +** will fit but this routine always mallocs for space. +** Return non-zero if we run out of memory. +*/ +#define Dynamicify(P) (((P)->flags & MEM_Dyn)==0 ? hardDynamicify(P):0) +static int hardDynamicify(Mem *pStack){ + int fg = pStack->flags; + char *z; + if( (fg & MEM_Str)==0 ){ + hardStringify(pStack); + } + assert( (fg & MEM_Dyn)==0 ); + z = sqliteMallocRaw( pStack->n ); + if( z==0 ) return 1; + memcpy(z, pStack->z, pStack->n); + pStack->z = z; + pStack->flags |= MEM_Dyn; + return 0; +} + +/* +** Advance the virtual machine to the next output row. +** +** The return vale will be either SQLITE_BUSY, SQLITE_DONE, +** SQLITE_ROW, SQLITE_ERROR, or SQLITE_MISUSE. +** +** SQLITE_BUSY means that the virtual machine attempted to open +** a locked database and there is no busy callback registered. +** Call sqlite3_step() again to retry the open. *pN is set to 0 +** and *pazColName and *pazValue are both set to NULL. +** +** SQLITE_DONE means that the virtual machine has finished +** executing. sqlite3_step() should not be called again on this +** virtual machine. *pN and *pazColName are set appropriately +** but *pazValue is set to NULL. +** +** SQLITE_ROW means that the virtual machine has generated another +** row of the result set. *pN is set to the number of columns in +** the row. *pazColName is set to the names of the columns followed +** by the column datatypes. *pazValue is set to the values of each +** column in the row. The value of the i-th column is (*pazValue)[i]. +** The name of the i-th column is (*pazColName)[i] and the datatype +** of the i-th column is (*pazColName)[i+*pN]. +** +** SQLITE_ERROR means that a run-time error (such as a constraint +** violation) has occurred. The details of the error will be returned +** by the next call to sqlite3_finalize(). sqlite3_step() should not +** be called again on the VM. +** +** SQLITE_MISUSE means that the this routine was called inappropriately. +** Perhaps it was called on a virtual machine that had already been +** finalized or on one that had previously returned SQLITE_ERROR or +** SQLITE_DONE. Or it could be the case the the same database connection +** is being used simulataneously by two or more threads. +*/ +int sqlite3_step( + sqlite_vm *pVm, /* The virtual machine to execute */ + int *pN, /* OUT: Number of columns in result */ + const char ***pazValue, /* OUT: Column data */ + const char ***pazColName /* OUT: Column names and datatypes */ +){ + sqlite3_stmt *pStmt = (sqlite3_stmt*)pVm; + int rc; + + rc = sqlite3_step_new(pStmt); + + if( pazValue ) *pazValue = 0; + if( pazColName ) *pazColName = 0; + if( pN ) *pN = 0; + + if( rc==SQLITE_DONE || rc==SQLITE_ROW ){ + int i; + int cols = sqlite3_column_count(pStmt) * (pazColName?1:0); + int vals = sqlite3_value_count(pStmt) * (pazValue?1:0); + + /* Temporary memory leak */ + if( cols ) *pazColName = sqliteMalloc(sizeof(char *)*cols * 2); + if( pN ) *pN = cols; + + for(i=0; imagic!=VDBE_MAGIC_RUN ){ + return SQLITE_MISUSE; + } + db = p->db; + if( sqlite3SafetyOn(db) ){ + p->rc = SQLITE_MISUSE; + return SQLITE_MISUSE; + } + if( p->explain ){ + rc = sqlite3VdbeList(p); + }else{ + rc = sqlite3VdbeExec(p); + } + + if( sqlite3SafetyOff(db) ){ + rc = SQLITE_MISUSE; + } + + sqlite3Error(p->db, rc, p->zErrMsg); + return rc; +} + +/* +** Return the number of columns in the result set for the statement pStmt. +*/ +int sqlite3_column_count(sqlite3_stmt *pStmt){ + Vdbe *pVm = (Vdbe *)pStmt; + return pVm->nResColumn; +} + +/* +** Return the number of values available from the current row of the +** currently executing statement pStmt. +*/ +int sqlite3_value_count(sqlite3_stmt *pStmt){ + Vdbe *pVm = (Vdbe *)pStmt; + if( !pVm->resOnStack ) return 0; + return pVm->nResColumn; +} + +/* +** Return the value of the 'i'th column of the current row of the currently +** executing statement pStmt. +*/ +const unsigned char *sqlite3_column_data(sqlite3_stmt *pStmt, int i){ + int vals; + Vdbe *pVm = (Vdbe *)pStmt; + Mem *pVal; + + vals = sqlite3_value_count(pStmt); + if( i>=vals || i<0 ){ + sqlite3Error(pVm->db, SQLITE_RANGE, 0); + return 0; + } + + pVal = &pVm->pTos[(1-vals)+i]; + if( pVal->flags&MEM_Null ){ + return 0; + } + + if( !pVal->flags&MEM_Blob ){ + Stringify(pVal); + SetEncoding(pVal, MEM_Utf8|MEM_Term); + } + + return pVal->z; +} + +/* +** Return the number of bytes of data that will be returned by the +** equivalent sqlite3_column_data() call. +*/ +int sqlite3_column_bytes(sqlite3_stmt *pStmt, int i){ + Vdbe *pVm = (Vdbe *)pStmt; + int vals; + + vals = sqlite3_value_count(pStmt); + if( i>=vals || i<0 ){ + sqlite3Error(pVm->db, SQLITE_RANGE, 0); + return 0; + } + + if( sqlite3_column_data(pStmt, i) ){ + return pVm->pTos[(1-vals)+i].n; + } + return 0; +} + +/* +** Return the value of the 'i'th column of the current row of the currently +** executing statement pStmt. +*/ +long long int sqlite3_column_int(sqlite3_stmt *pStmt, int i){ + int vals; + Vdbe *pVm = (Vdbe *)pStmt; + Mem *pVal; + + vals = sqlite3_value_count(pStmt); + if( i>=vals || i<0 ){ + sqlite3Error(pVm->db, SQLITE_RANGE, 0); + return 0; + } + + pVal = &pVm->pTos[(1-vals)+i]; + Integerify(pVal); + return pVal->i; +} + +/* +** Return the value of the 'i'th column of the current row of the currently +** executing statement pStmt. +*/ +double sqlite3_column_float(sqlite3_stmt *pStmt, int i){ + int vals; + Vdbe *pVm = (Vdbe *)pStmt; + Mem *pVal; + + vals = sqlite3_value_count(pStmt); + if( i>=vals || i<0 ){ + sqlite3Error(pVm->db, SQLITE_RANGE, 0); + return 0; + } + + pVal = &pVm->pTos[(1-vals)+i]; + Realify(pVal); + return pVal->r; +} + +/* +** Return the name of the Nth column of the result set returned by SQL +** statement pStmt. +*/ +const char *sqlite3_column_name(sqlite3_stmt *pStmt, int N){ + Vdbe *p = (Vdbe *)pStmt; + + if( N>=sqlite3_column_count(pStmt) || N<0 ){ + sqlite3Error(p->db, SQLITE_RANGE, 0); + return 0; + } + + return p->azColName[N]; +} + +/* +** Return the type of the 'i'th column of the current row of the currently +** executing statement pStmt. +*/ +int sqlite3_column_type(sqlite3_stmt *pStmt, int i){ + int vals; + Vdbe *p = (Vdbe *)pStmt; + int f; + + vals = sqlite3_value_count(pStmt); + if( i>=vals || i<0 ){ + sqlite3Error(p->db, SQLITE_RANGE, 0); + return 0; + } + + f = p->pTos[(1-vals)+i].flags; + + if( f&MEM_Null ){ + return SQLITE3_NULL; + } + if( f&MEM_Int ){ + return SQLITE3_INTEGER; + } + if( f&MEM_Real ){ + return SQLITE3_FLOAT; + } + if( f&MEM_Str ){ + return SQLITE3_TEXT; + } + if( f&MEM_Blob ){ + return SQLITE3_BLOB; + } + assert(0); +} + +/* +** This routine returns either the column name, or declaration type (see +** sqlite3_column_decltype16() ) of the 'i'th column of the result set of +** SQL statement pStmt. The returned string is UTF-16 encoded. +** +** The declaration type is returned if 'decltype' is true, otherwise +** the column name. +*/ +static const void *columnName16(sqlite3_stmt *pStmt, int i, int decltype){ + Vdbe *p = (Vdbe *)pStmt; + + if( i>=sqlite3_column_count(pStmt) || i<0 ){ + sqlite3Error(p->db, SQLITE_RANGE, 0); + return 0; + } + + if( decltype ){ + i += p->nResColumn; + } + + if( !p->azColName16 ){ + p->azColName16 = (void **)sqliteMalloc(sizeof(void *)*p->nResColumn*2); + if( !p->azColName16 ){ + sqlite3Error(p->db, SQLITE_NOMEM, 0); + return 0; + } + } + if( !p->azColName16[i] ){ + if( SQLITE3_BIGENDIAN ){ + p->azColName16[i] = sqlite3utf8to16be(p->azColName[i], -1); + } + if( !p->azColName16[i] ){ + sqlite3Error(p->db, SQLITE_NOMEM, 0); + return 0; + } + } + return p->azColName16[i]; +} + +/* +** Return the name of the 'i'th column of the result set of SQL statement +** pStmt, encoded as UTF-16. +*/ +const void *sqlite3_column_name16(sqlite3_stmt *pStmt, int i){ + return columnName16(pStmt, i, 0); +} + +/* +** Return the column declaration type (if applicable) of the 'i'th column +** of the result set of SQL statement pStmt, encoded as UTF-8. +*/ +const char *sqlite3_column_decltype(sqlite3_stmt *pStmt, int i){ + Vdbe *p = (Vdbe *)pStmt; + + if( i>=sqlite3_column_count(pStmt) || i<0 ){ + sqlite3Error(p->db, SQLITE_RANGE, 0); + return 0; + } + + return p->azColName[i+p->nResColumn]; +} + +/* +** Return the column declaration type (if applicable) of the 'i'th column +** of the result set of SQL statement pStmt, encoded as UTF-16. +*/ +const void *sqlite3_column_decltype16(sqlite3_stmt *pStmt, int i){ + return columnName16(pStmt, i, 1); +} + +/* +** Insert a new aggregate element and make it the element that +** has focus. +** +** Return 0 on success and 1 if memory is exhausted. +*/ +static int AggInsert(Agg *p, char *zKey, int nKey){ + AggElem *pElem, *pOld; + int i; + Mem *pMem; + pElem = sqliteMalloc( sizeof(AggElem) + nKey + + (p->nMem-1)*sizeof(pElem->aMem[0]) ); + if( pElem==0 ) return 1; + pElem->zKey = (char*)&pElem->aMem[p->nMem]; + memcpy(pElem->zKey, zKey, nKey); + pElem->nKey = nKey; + pOld = sqlite3HashInsert(&p->hash, pElem->zKey, pElem->nKey, pElem); + if( pOld!=0 ){ + assert( pOld==pElem ); /* Malloc failed on insert */ + sqliteFree(pOld); + return 0; + } + for(i=0, pMem=pElem->aMem; inMem; i++, pMem++){ + pMem->flags = MEM_Null; + } + p->pCurrent = pElem; + return 0; +} + +/* +** Get the AggElem currently in focus +*/ +#define AggInFocus(P) ((P).pCurrent ? (P).pCurrent : _AggInFocus(&(P))) +static AggElem *_AggInFocus(Agg *p){ + HashElem *pElem = sqliteHashFirst(&p->hash); + if( pElem==0 ){ + AggInsert(p,"",1); + pElem = sqliteHashFirst(&p->hash); + } + return pElem ? sqliteHashData(pElem) : 0; +} + +/* +** An ephemeral string value (signified by the MEM_Ephem flag) contains +** a pointer to a dynamically allocated string where some other entity +** is responsible for deallocating that string. Because the stack entry +** does not control the string, it might be deleted without the stack +** entry knowing it. +** +** This routine converts an ephemeral string into a dynamically allocated +** string that the stack entry itself controls. In other words, it +** converts an MEM_Ephem string into an MEM_Dyn string. +*/ +#define Deephemeralize(P) \ + if( ((P)->flags&MEM_Ephem)!=0 && hardDeephem(P) ){ goto no_mem;} +static int hardDeephem(Mem *pStack){ + char *z; + assert( (pStack->flags & MEM_Ephem)!=0 ); + z = sqliteMallocRaw( pStack->n ); + if( z==0 ) return 1; + memcpy(z, pStack->z, pStack->n); + pStack->z = z; + pStack->flags &= ~MEM_Ephem; + pStack->flags |= MEM_Dyn; + return 0; +} + +/* +** Pop the stack N times. +*/ +static void popStack(Mem **ppTos, int N){ + Mem *pTos = *ppTos; + while( N>0 ){ + N--; + Release(pTos); + pTos--; + } + *ppTos = pTos; +} + /* ** The parameters are pointers to the head of two sorted lists ** of Sorter structures. Merge these two lists together and return @@ -649,6 +987,7 @@ int sqlite3VdbeExec( popStack(&pTos, p->popStack); p->popStack = 0; } + p->resOnStack = 0; CHECK_FOR_INTERRUPT; for(pc=p->pc; rc==SQLITE_OK; pc++){ assert( pc>=0 && pcnOp ); @@ -824,7 +1163,7 @@ case OP_Integer: { pTos->flags = MEM_Int; if( pOp->p3 ){ pTos->z = pOp->p3; - pTos->flags |= MEM_Str | MEM_Static; + pTos->flags |= MEM_Utf8 | MEM_Str | MEM_Static; pTos->n = strlen(pOp->p3)+1; if( pTos->i==0 ){ sqlite3GetInt64(pTos->z, &pTos->i); @@ -846,7 +1185,7 @@ case OP_String: { }else{ pTos->z = z; pTos->n = strlen(z) + 1; - pTos->flags = MEM_Str | MEM_Static; + pTos->flags = MEM_Str | MEM_Static | MEM_Utf8 | MEM_Term; } break; } @@ -865,7 +1204,7 @@ case OP_Real: { pTos->r = sqlite3AtoF(z, 0); pTos->z = z; pTos->n = strlen(z)+1; - pTos->flags = MEM_Real|MEM_Str|MEM_Static; + pTos->flags = MEM_Real|MEM_Str|MEM_Static|MEM_Utf8; break; } @@ -959,7 +1298,7 @@ case OP_Dup: { assert( pFrom<=pTos && pFrom>=p->aStack ); pTos++; memcpy(pTos, pFrom, sizeof(*pFrom)-NBFS); - if( pTos->flags & MEM_Str ){ + if( pTos->flags & (MEM_Str|MEM_Blob) ){ if( pOp->p2 && (pTos->flags & (MEM_Dyn|MEM_Ephem)) ){ pTos->flags &= ~MEM_Dyn; pTos->flags |= MEM_Ephem; @@ -999,14 +1338,14 @@ case OP_Pull: { *pFrom = pFrom[1]; assert( (pFrom->flags & MEM_Ephem)==0 ); if( pFrom->flags & MEM_Short ){ - assert( pFrom->flags & MEM_Str ); + assert( pFrom->flags & (MEM_Str|MEM_Blob) ); assert( pFrom->z==pFrom[1].zShort ); pFrom->z = pFrom->zShort; } } *pTos = ts; if( pTos->flags & MEM_Short ){ - assert( pTos->flags & MEM_Str ); + assert( pTos->flags & (MEM_Str|MEM_Blob) ); assert( pTos->z==pTos[-pOp->p1].zShort ); pTos->z = pTos->zShort; } @@ -1074,6 +1413,8 @@ case OP_Callback: { azArgv[i] = pCol->z; } } + p->resOnStack = 1; + azArgv[i] = 0; p->nCallback++; p->azResColumn = azArgv; @@ -1148,7 +1489,7 @@ case OP_Concat: { } pTos++; pTos->n = nByte; - pTos->flags = MEM_Str|MEM_Dyn; + pTos->flags = MEM_Str|MEM_Dyn|MEM_Utf8; pTos->z = zNew; break; } @@ -1833,7 +2174,7 @@ case OP_Class: { }; Release(pTos); - pTos->flags = MEM_Str|MEM_Static; + pTos->flags = MEM_Str|MEM_Static|MEM_Utf8; for(i=0; i<5; i++){ if( classes[i].mask&flags ){ @@ -1906,7 +2247,7 @@ case OP_Column: { u64 colType; /* The serial type of the value being read. */ assert( &pTos[i-1]>=p->aStack ); - assert( pTos[i].flags & MEM_Str ); + assert( pTos[i].flags & MEM_Blob ); assert( pTos[i-1].flags & MEM_Int ); if( pTos[i].n==0 ){ @@ -2148,7 +2489,7 @@ case OP_MakeRecord: { pTos++; pTos->n = nBytes; pTos->z = zNewRecord; - pTos->flags = MEM_Str | MEM_Dyn; + pTos->flags = MEM_Blob | MEM_Dyn; break; } @@ -2276,7 +2617,7 @@ case OP_MakeIdxKey: { popStack(&pTos, nField+addRowid); } pTos++; - pTos->flags = MEM_Str|MEM_Dyn; /* TODO: should eventually be MEM_Blob */ + pTos->flags = MEM_Blob|MEM_Dyn; /* TODO: should eventually be MEM_Blob */ pTos->z = zKey; pTos->n = nByte; @@ -3201,7 +3542,7 @@ case OP_PutStrKey: { pTos->z = 0; pTos->n = 0; }else{ - assert( pTos->flags & MEM_Str ); + assert( pTos->flags & (MEM_Blob|MEM_Str) ); } if( pC->pseudoTable ){ /* PutStrKey does not work for pseudo-tables. @@ -3341,12 +3682,12 @@ case OP_RowData: { } pTos->n = n; if( n<=NBFS ){ - pTos->flags = MEM_Str | MEM_Short; + pTos->flags = MEM_Blob | MEM_Short; pTos->z = pTos->zShort; }else{ char *z = sqliteMallocRaw( n ); if( z==0 ) goto no_mem; - pTos->flags = MEM_Str | MEM_Dyn; + pTos->flags = MEM_Blob | MEM_Dyn; pTos->z = z; } if( pC->keyAsData || pOp->opcode==OP_RowKey ){ @@ -3357,7 +3698,7 @@ case OP_RowData: { }else if( pC->pseudoTable ){ pTos->n = pC->nData; pTos->z = pC->pData; - pTos->flags = MEM_Str|MEM_Ephem; + pTos->flags = MEM_Blob|MEM_Ephem; }else{ pTos->flags = MEM_Null; } @@ -3481,10 +3822,10 @@ case OP_FullKey: { if( amt>NBFS ){ z = sqliteMallocRaw( amt ); if( z==0 ) goto no_mem; - pTos->flags = MEM_Str | MEM_Dyn; + pTos->flags = MEM_Blob | MEM_Dyn; }else{ z = pTos->zShort; - pTos->flags = MEM_Str | MEM_Short; + pTos->flags = MEM_Blob | MEM_Short; } sqlite3BtreeKey(pCrsr, 0, amt, z); pTos->z = z; @@ -3634,7 +3975,7 @@ case OP_IdxPut: { BtCursor *pCrsr; assert( pTos>=p->aStack ); assert( i>=0 && inCursor ); - assert( pTos->flags & MEM_Str ); + assert( pTos->flags & MEM_Blob ); if( (pCrsr = (pC = p->apCsr[i])->pCursor)!=0 ){ int nKey = pTos->n; const char *zKey = pTos->z; @@ -3690,7 +4031,7 @@ case OP_IdxDelete: { Cursor *pC; BtCursor *pCrsr; assert( pTos>=p->aStack ); - assert( pTos->flags & MEM_Str ); + assert( pTos->flags & MEM_Blob ); assert( i>=0 && inCursor ); if( (pCrsr = (pC = p->apCsr[i])->pCursor)!=0 ){ int rx, res; @@ -3857,7 +4198,7 @@ case OP_IdxIsNull: { const char *z; assert( pTos>=p->aStack ); - assert( pTos->flags & MEM_Str ); + assert( pTos->flags & MEM_Blob ); z = pTos->z; n = pTos->n; for(k=0; k0; i--){ @@ -4002,11 +4343,11 @@ case OP_IntegrityCk: { if( z ) sqliteFree(z); pTos->z = "ok"; pTos->n = 3; - pTos->flags = MEM_Str | MEM_Static; + pTos->flags = MEM_Utf8 | MEM_Str | MEM_Static; }else{ pTos->z = z; pTos->n = strlen(z) + 1; - pTos->flags = MEM_Str | MEM_Dyn; + pTos->flags = MEM_Utf8 | MEM_Str | MEM_Dyn; } sqliteFree(aRoot); break; @@ -4246,7 +4587,7 @@ case OP_SortNext: { pTos++; pTos->z = pSorter->pData; pTos->n = pSorter->nData; - pTos->flags = MEM_Str|MEM_Dyn; + pTos->flags = MEM_Blob|MEM_Dyn; sqliteFree(pSorter->zKey); sqliteFree(pSorter); }else{ @@ -4425,7 +4766,7 @@ case OP_FileColumn: { if( z ){ pTos->n = strlen(z) + 1; pTos->z = z; - pTos->flags = MEM_Str | MEM_Ephem; + pTos->flags = MEM_Utf8 | MEM_Str | MEM_Ephem; }else{ pTos->flags = MEM_Null; } @@ -4501,7 +4842,7 @@ case OP_MemLoad: { assert( i>=0 && inMem ); pTos++; memcpy(pTos, &p->aMem[i], sizeof(pTos[0])-NBFS);; - if( pTos->flags & MEM_Str ){ + if( pTos->flags & (MEM_Str|MEM_Blob) ){ pTos->flags |= MEM_Ephem; pTos->flags &= ~(MEM_Dyn|MEM_Static|MEM_Short); } @@ -4682,7 +5023,7 @@ case OP_AggGet: { pTos++; pMem = &pFocus->aMem[i]; *pTos = *pMem; - if( pTos->flags & MEM_Str ){ + if( pTos->flags & (MEM_Str|MEM_Blob) ){ pTos->flags &= ~(MEM_Dyn|MEM_Static|MEM_Short); pTos->flags |= MEM_Ephem; } @@ -4847,7 +5188,7 @@ case OP_SetNext: { pTos++; pTos->z = sqliteHashKey(pSet->prev); pTos->n = sqliteHashKeysize(pSet->prev); - pTos->flags = MEM_Str | MEM_Ephem; + pTos->flags = MEM_Utf8 | MEM_Str | MEM_Ephem; break; } @@ -4933,7 +5274,7 @@ default: { fprintf(p->trace, " i:%lld", pTos[i].i); }else if( pTos[i].flags & MEM_Real ){ fprintf(p->trace, " r:%g", pTos[i].r); - }else if( pTos[i].flags & MEM_Str ){ + }else if( pTos[i].flags & (MEM_Str|MEM_Blob) ){ int j, k; char zBuf[100]; zBuf[0] = ' '; diff --git a/src/vdbe.h b/src/vdbe.h index 236b584dcd..b270b10499 100644 --- a/src/vdbe.h +++ b/src/vdbe.h @@ -15,7 +15,7 @@ ** or VDBE. The VDBE implements an abstract machine that runs a ** simple program to access and modify the underlying database. ** -** $Id: vdbe.h,v 1.80 2004/05/21 01:29:06 drh Exp $ +** $Id: vdbe.h,v 1.81 2004/05/21 10:08:55 danielk1977 Exp $ */ #ifndef _SQLITE_VDBE_H_ #define _SQLITE_VDBE_H_ @@ -113,8 +113,6 @@ VdbeOp *sqlite3VdbeGetOp(Vdbe*, int); int sqlite3VdbeMakeLabel(Vdbe*); void sqlite3VdbeDelete(Vdbe*); void sqlite3VdbeMakeReady(Vdbe*,int,int); -int sqlite3VdbeExec(Vdbe*); -int sqlite3VdbeList(Vdbe*); int sqlite3VdbeFinalize(Vdbe*,char**); void sqlite3VdbeResolveLabel(Vdbe*, int); int sqlite3VdbeCurrentAddr(Vdbe*); diff --git a/src/vdbeInt.h b/src/vdbeInt.h index 38de819816..96a0f8720d 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -269,6 +269,7 @@ struct Vdbe { Mem *pTos; /* Top entry in the operand stack */ char **zArgv; /* Text values used by the callback */ char **azColName; /* Becomes the 4th parameter to callbacks */ + void **azColName16; /* UTF-16 encoded equivalent of azColName */ int nCursor; /* Number of slots in apCsr[] */ Cursor **apCsr; /* One element of this array for each open cursor */ Sorter *pSort; /* A linked list of objects to be sorted */ @@ -301,6 +302,7 @@ struct Vdbe { int returnDepth; /* Next unused element in returnStack[] */ int nResColumn; /* Number of columns in one row of the result set */ char **azResColumn; /* Values for one row of result */ + u8 resOnStack; /* True if there are result values on the stack */ int popStack; /* Pop the stack this much on entry to VdbeExec() */ char *zErrMsg; /* Error message written here */ u8 explain; /* True if EXPLAIN present on SQL command */ @@ -337,3 +339,5 @@ int sqlite3VdbeIdxRowid(BtCursor *, i64 *); int sqlite3MemCompare(const Mem*, const Mem*, const CollSeq*); int sqlite3VdbeKeyCompare(void*,int,const void*,int, const void*); int sqlite3VdbeRowCompare(void*,int,const void*,int, const void*); +int sqlite3VdbeExec(Vdbe*); +int sqlite3VdbeList(Vdbe*); diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 6831459e4e..b6bc0b965d 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -460,7 +460,7 @@ char *sqlite3_set_result_string(sqlite_func *p, const char *zResult, int n){ if( ns.zShort, zResult, n); p->s.zShort[n] = 0; - p->s.flags = MEM_Str | MEM_Short; + p->s.flags = MEM_Utf8 | MEM_Str | MEM_Short; p->s.z = p->s.zShort; }else{ p->s.z = sqliteMallocRaw( n+1 ); @@ -468,7 +468,7 @@ char *sqlite3_set_result_string(sqlite_func *p, const char *zResult, int n){ memcpy(p->s.z, zResult, n); p->s.z[n] = 0; } - p->s.flags = MEM_Str | MEM_Dyn; + p->s.flags = MEM_Utf8 | MEM_Str | MEM_Dyn; } p->s.n = n+1; } @@ -937,9 +937,11 @@ int sqlite3VdbeReset(Vdbe *p, char **pzErrMsg){ if( p->magic!=VDBE_MAGIC_RUN && p->magic!=VDBE_MAGIC_HALT ){ sqlite3SetString(pzErrMsg, sqlite3_error_string(SQLITE_MISUSE), (char*)0); + sqlite3Error(p->db, SQLITE_MISUSE, sqlite3_error_string(SQLITE_MISUSE),0); return SQLITE_MISUSE; } if( p->zErrMsg ){ + sqlite3Error(p->db, p->rc, "%s", p->zErrMsg, 0); if( pzErrMsg && *pzErrMsg==0 ){ *pzErrMsg = p->zErrMsg; }else{ @@ -948,6 +950,9 @@ int sqlite3VdbeReset(Vdbe *p, char **pzErrMsg){ p->zErrMsg = 0; }else if( p->rc ){ sqlite3SetString(pzErrMsg, sqlite3_error_string(p->rc), (char*)0); + sqlite3Error(p->db, p->rc, "%s", sqlite3_error_string(p->rc) , 0); + }else{ + sqlite3Error(p->db, SQLITE_OK, 0); } Cleanup(p); if( p->rc!=SQLITE_OK ){ @@ -1023,6 +1028,9 @@ int sqlite3VdbeFinalize(Vdbe *p, char **pzErrMsg){ if( p->magic!=VDBE_MAGIC_RUN && p->magic!=VDBE_MAGIC_HALT ){ sqlite3SetString(pzErrMsg, sqlite3_error_string(SQLITE_MISUSE), (char*)0); + if( p->magic==VDBE_MAGIC_INIT ){ + sqlite3Error(p->db, SQLITE_MISUSE, sqlite3_error_string(SQLITE_MISUSE),0); + } return SQLITE_MISUSE; } db = p->db; @@ -1490,7 +1498,7 @@ int sqlite3VdbeSerialGet(const unsigned char *buf, u64 serial_type, Mem *pMem){ assert( serial_type>=12 ); len = sqlite3VdbeSerialTypeLen(serial_type); if( serial_type&0x01 ){ - pMem->flags = MEM_Str; + pMem->flags = MEM_Str|MEM_Utf8; pMem->n = len+1; }else{ pMem->flags = MEM_Blob; @@ -1869,3 +1877,6 @@ int sqlite3VdbeIdxKeyCompare( } return SQLITE_OK; } + + + diff --git a/test/attach2.test b/test/attach2.test index 58ff5e2b56..8cc11aa2a5 100644 --- a/test/attach2.test +++ b/test/attach2.test @@ -12,7 +12,7 @@ # focus of this script is testing the ATTACH and DETACH commands # and related functionality. # -# $Id: attach2.test,v 1.8 2004/05/21 01:47:27 danielk1977 Exp $ +# $Id: attach2.test,v 1.9 2004/05/21 10:08:55 danielk1977 Exp $ # @@ -126,13 +126,13 @@ do_test attach2-3.1 { set DB [sqlite db test.db] set rc [catch {sqlite3_prepare $DB "ATTACH 'test2.db' AS t2" -1 TAIL} VM] if {$rc} {lappend rc $VM} - sqlite_finalize $VM + sqlite3_finalize $VM set rc } {0} do_test attach2-3.2 { set rc [catch {sqlite3_prepare $DB "DETACH t2" -1 TAIL} VM] if {$rc} {lappend rc $VM} - sqlite_finalize $VM + sqlite3_finalize $VM set rc } {0} diff --git a/test/bind.test b/test/bind.test index bc7dbd629b..76b36d6710 100644 --- a/test/bind.test +++ b/test/bind.test @@ -11,7 +11,7 @@ # This file implements regression tests for SQLite library. The # focus of this script testing the sqlite_bind API. # -# $Id: bind.test,v 1.5 2004/05/21 02:11:41 danielk1977 Exp $ +# $Id: bind.test,v 1.6 2004/05/21 10:08:55 danielk1977 Exp $ # set testdir [file dirname $argv0] @@ -31,7 +31,7 @@ do_test bind-1.3 { execsql {SELECT rowid, * FROM t1} } {1 {} {} {}} do_test bind-1.4 { - sqlite_reset $VM + sqlite3_reset $VM sqlite_bind $VM 1 {test value 1} normal sqlite_step $VM N VALUES COLNAMES } SQLITE_DONE @@ -39,7 +39,7 @@ do_test bind-1.5 { execsql {SELECT rowid, * FROM t1} } {1 {} {} {} 2 {test value 1} {} {}} do_test bind-1.6 { - sqlite_reset $VM + sqlite3_reset $VM sqlite_bind $VM 3 {'test value 2'} normal sqlite_step $VM N VALUES COLNAMES } SQLITE_DONE @@ -47,7 +47,7 @@ do_test bind-1.7 { execsql {SELECT rowid, * FROM t1} } {1 {} {} {} 2 {test value 1} {} {} 3 {test value 1} {} {'test value 2'}} do_test bind-1.8 { - sqlite_reset $VM + sqlite3_reset $VM set sqlite_static_bind_value 123 sqlite_bind $VM 1 {} static sqlite_bind $VM 2 {abcdefg} normal @@ -57,14 +57,14 @@ do_test bind-1.8 { execsql {SELECT rowid, * FROM t1} } {1 123 abcdefg {}} do_test bind-1.9 { - sqlite_reset $VM + sqlite3_reset $VM sqlite_bind $VM 1 {456} normal sqlite_step $VM N VALUES COLNAMES execsql {SELECT rowid, * FROM t1} } {1 123 abcdefg {} 2 456 abcdefg {}} do_test bind-1.99 { - sqlite_finalize $VM + sqlite3_finalize $VM } {} do_test bind-2.1 { @@ -81,14 +81,14 @@ do_test bind-2.2 { sqlite3_bind_int32 $VM 2 456 sqlite3_bind_int32 $VM 3 789 sqlite_step $VM N VALUES COLNAMES - sqlite_reset $VM + sqlite3_reset $VM execsql {SELECT rowid, * FROM t1} } {1 123 456 789} do_test bind-2.3 { sqlite3_bind_int32 $VM 2 -2000000000 sqlite3_bind_int32 $VM 3 2000000000 sqlite_step $VM N VALUES COLNAMES - sqlite_reset $VM + sqlite3_reset $VM execsql {SELECT rowid, * FROM t1} } {1 123 456 789 2 123 -2000000000 2000000000} do_test bind-2.4 { @@ -106,7 +106,7 @@ do_test bind-3.1 { sqlite3_bind_int64 $VM 2 -2000000000000 sqlite3_bind_int64 $VM 3 2000000000000 sqlite_step $VM N VALUES COLNAMES - sqlite_reset $VM + sqlite3_reset $VM execsql {SELECT rowid, * FROM t1} } {1 32 -2000000000000 2000000000000} do_test bind-3.2 { @@ -124,7 +124,7 @@ do_test bind-4.1 { sqlite3_bind_double $VM 2 0.00001 sqlite3_bind_double $VM 3 123456789 sqlite_step $VM N VALUES COLNAMES - sqlite_reset $VM + sqlite3_reset $VM execsql {SELECT rowid, * FROM t1} } {1 1234.1234 1e-05 123456789} do_test bind-4.2 { @@ -142,7 +142,7 @@ do_test bind-5.1 { sqlite3_bind_null $VM 2 sqlite3_bind_null $VM 3 sqlite_step $VM N VALUES COLNAMES - sqlite_reset $VM + sqlite3_reset $VM execsql {SELECT rowid, * FROM t1} } {1 {} {} {}} do_test bind-5.2 { @@ -160,7 +160,7 @@ do_test bind-6.1 { sqlite3_bind_text $VM 2 "." 2 sqlite3_bind_text $VM 3 world -1 sqlite_step $VM N VALUES COLNAMES - sqlite_reset $VM + sqlite3_reset $VM execsql {SELECT rowid, * FROM t1} } {1 hello . world} do_test bind-6.2 { @@ -178,7 +178,7 @@ do_test bind-7.1 { sqlite3_bind_text16 $VM 2 [encoding convertto unicode ""] 0 sqlite3_bind_text16 $VM 3 [encoding convertto unicode world] 10 sqlite_step $VM N VALUES COLNAMES - sqlite_reset $VM + sqlite3_reset $VM execsql {SELECT rowid, * FROM t1} } {1 hello {} world} do_test bind-7.2 { @@ -216,7 +216,7 @@ do_test bind-8.7 { do_test bind-9.99 { - sqlite_finalize $VM + sqlite3_finalize $VM } {} diff --git a/test/capi2.test b/test/capi2.test index 1efe3299ea..f1d9afebbf 100644 --- a/test/capi2.test +++ b/test/capi2.test @@ -11,7 +11,7 @@ # This file implements regression tests for SQLite library. The # focus of this script testing the callback-free C/C++ API. # -# $Id: capi2.test,v 1.11 2004/05/21 01:47:27 danielk1977 Exp $ +# $Id: capi2.test,v 1.12 2004/05/21 10:08:55 danielk1977 Exp $ # set testdir [file dirname $argv0] @@ -57,7 +57,7 @@ do_test capi2-1.9 { list $N $VALUES $COLNAMES } {0 {} {}} do_test capi2-1.10 { - sqlite_finalize $VM + sqlite3_finalize $VM } {} # Check to make sure that the "tail" of a multi-statement SQL script @@ -84,7 +84,7 @@ do_test capi2-2.3 { lappend r $n $val $colname } {SQLITE_DONE 2 {} {name rowid text INTEGER}} do_test capi2-2.4 { - sqlite_finalize $VM + sqlite3_finalize $VM } {} do_test capi2-2.5 { set VM [sqlite3_prepare $DB $SQL -1 SQL] @@ -97,7 +97,7 @@ do_test capi2-2.6 { lappend r $n $val $colname } {SQLITE_DONE 2 {} {name rowid text INTEGER}} do_test capi2-2.7 { - sqlite_finalize $VM + sqlite3_finalize $VM } {} do_test capi2-2.8 { set VM [sqlite3_prepare $DB $SQL -1 SQL] @@ -149,7 +149,7 @@ do_test capi2-3.7 { list [sqlite_step $VM N VALUE COLNAME] [set N] [set VALUE] [set COLNAME] } {SQLITE_ROW 1 {{}} {5/0 NUMERIC}} do_test capi2-3.8 { - sqlite_finalize $VM + sqlite3_finalize $VM } {} do_test capi2-3.9 { execsql {CREATE UNIQUE INDEX i1 ON t1(a)} @@ -165,11 +165,11 @@ do_test capi2-3.10 { } {SQLITE_DONE 0 {} {}} do_test capi2-3.10b {db changes} {1} do_test capi2-3.11 { - sqlite_finalize $VM + sqlite3_finalize $VM } {} do_test capi2-3.11b {db changes} {1} do_test capi2-3.12 { - list [catch {sqlite_finalize $VM} msg] [set msg] + list [catch {sqlite3_finalize $VM} msg] [set msg] } {1 {(21) library routine called out of sequence}} do_test capi2-3.13 { set VM [sqlite3_prepare $DB {INSERT INTO t1 VALUES(1,3,4)} -1 TAIL] @@ -177,7 +177,7 @@ do_test capi2-3.13 { } {SQLITE_ERROR 0 {} {}} do_test capi2-3.13b {db changes} {0} do_test capi2-3.14 { - list [catch {sqlite_finalize $VM} msg] [set msg] + list [catch {sqlite3_finalize $VM} msg] [set msg] } {1 {(19) column a is not unique}} do_test capi2-3.15 { set VM [sqlite3_prepare $DB {CREATE TABLE t2(a NOT NULL, b)} -1 TAIL] @@ -187,14 +187,14 @@ do_test capi2-3.16 { list [sqlite_step $VM N VALUE COLNAME] [set N] [set VALUE] [set COLNAME] } {SQLITE_DONE 0 {} {}} do_test capi2-3.17 { - list [catch {sqlite_finalize $VM} msg] [set msg] + list [catch {sqlite3_finalize $VM} msg] [set msg] } {0 {}} do_test capi2-3.18 { set VM [sqlite3_prepare $DB {INSERT INTO t2 VALUES(NULL,2)} -1 TAIL] list [sqlite_step $VM N VALUE COLNAME] [set N] [set VALUE] [set COLNAME] } {SQLITE_ERROR 0 {} {}} do_test capi2-3.19 { - list [catch {sqlite_finalize $VM} msg] [set msg] + list [catch {sqlite3_finalize $VM} msg] [set msg] } {1 {(19) t2.a may not be NULL}} # Two or more virtual machines exists at the same time. @@ -218,7 +218,7 @@ do_test capi2-4.5 { execsql {SELECT * FROM t2 ORDER BY a} } {2 3} do_test capi2-4.6 { - list [catch {sqlite_finalize $VM2} msg] [set msg] + list [catch {sqlite3_finalize $VM2} msg] [set msg] } {0 {}} do_test capi2-4.7 { list [sqlite_step $VM3 N VALUE COLNAME] [set N] [set VALUE] [set COLNAME] @@ -227,7 +227,7 @@ do_test capi2-4.8 { execsql {SELECT * FROM t2 ORDER BY a} } {2 3 3 4} do_test capi2-4.9 { - list [catch {sqlite_finalize $VM3} msg] [set msg] + list [catch {sqlite3_finalize $VM3} msg] [set msg] } {0 {}} do_test capi2-4.10 { list [sqlite_step $VM1 N VALUE COLNAME] [set N] [set VALUE] [set COLNAME] @@ -236,7 +236,7 @@ do_test capi2-4.11 { execsql {SELECT * FROM t2 ORDER BY a} } {1 2 2 3 3 4} do_test capi2-4.12 { - list [catch {sqlite_finalize $VM1} msg] [set msg] + list [catch {sqlite3_finalize $VM1} msg] [set msg] } {0 {}} # Interleaved SELECTs @@ -266,13 +266,13 @@ do_test capi2-5.7 { list [sqlite_step $VM3 N VALUE COLNAME] [set N] [set VALUE] [set COLNAME] } {SQLITE_DONE 2 {} {a b {} {}}} do_test capi2-5.8 { - list [catch {sqlite_finalize $VM3} msg] [set msg] + list [catch {sqlite3_finalize $VM3} msg] [set msg] } {0 {}} do_test capi2-5.9 { list [sqlite_step $VM1 N VALUE COLNAME] [set N] [set VALUE] [set COLNAME] } {SQLITE_ROW 2 {1 2} {a b {} {}}} do_test capi2-5.10 { - list [catch {sqlite_finalize $VM1} msg] [set msg] + list [catch {sqlite3_finalize $VM1} msg] [set msg] } {0 {}} do_test capi2-5.11 { list [sqlite_step $VM2 N VALUE COLNAME] [set N] [set VALUE] [set COLNAME] @@ -281,7 +281,7 @@ do_test capi2-5.12 { list [sqlite_step $VM2 N VALUE COLNAME] [set N] [set VALUE] [set COLNAME] } {SQLITE_ROW 2 {1 2} {a b {} {}}} do_test capi2-5.11 { - list [catch {sqlite_finalize $VM2} msg] [set msg] + list [catch {sqlite3_finalize $VM2} msg] [set msg] } {0 {}} # Check for proper SQLITE_BUSY returns. @@ -341,7 +341,7 @@ do_test capi2-6.13 { do_test capi2-6.14 { list [sqlite_step $VM1 N VALUE COLNAME] [set N] [set VALUE] [set COLNAME] } {SQLITE_ROW 1 6 {x counter}} -# puts [list [catch {sqlite_finalize $VM1} msg] [set msg]]; exit +# puts [list [catch {sqlite3_finalize $VM1} msg] [set msg]]; exit do_test capi2-6.15 { execsql {SELECT * FROM t1} } {1 2 3} @@ -391,7 +391,7 @@ do_test capi2-6.28 { list [sqlite_step $VM1 N VALUE COLNAME] [set N] [set VALUE] [set COLNAME] } {SQLITE_ROW 1 13 {x counter}} do_test capi2-6.99 { - list [catch {sqlite_finalize $VM1} msg] [set msg] + list [catch {sqlite3_finalize $VM1} msg] [set msg] } {0 {}} catchsql {ROLLBACK} @@ -458,7 +458,7 @@ do_test capi2-7.12 { # do_test capi2-8.1 { set VM1 [sqlite3_prepare $DB {SELECT * FROM t2} -1 TAIL] - sqlite_finalize $VM1 + sqlite3_finalize $VM1 } {} # Tickets #384 and #385 - make sure the TAIL argument to sqlite3_prepare @@ -467,7 +467,7 @@ do_test capi2-8.1 { do_test capi2-9.1 { set VM1 [sqlite3_prepare $DB {SELECT * FROM t2} -1 DUMMY] sqlite_step $VM1 - sqlite_finalize $VM1 + sqlite3_finalize $VM1 } {} db2 close diff --git a/test/capi3.test b/test/capi3.test index 23eab119c4..291232ea49 100644 --- a/test/capi3.test +++ b/test/capi3.test @@ -11,7 +11,7 @@ # This file implements regression tests for SQLite library. The # focus of this script testing the callback-free C/C++ API. # -# $Id: capi3.test,v 1.2 2004/05/21 01:47:27 danielk1977 Exp $ +# $Id: capi3.test,v 1.3 2004/05/21 10:08:55 danielk1977 Exp $ # set testdir [file dirname $argv0] @@ -54,7 +54,7 @@ set DB [sqlite db test.db] do_test capi3-1.1 { set STMT [sqlite3_prepare $DB {SELECT name FROM sqlite_master} -1 TAIL] - sqlite_finalize $STMT + sqlite3_finalize $STMT set TAIL } {} do_test capi3-1.2 { @@ -66,7 +66,7 @@ do_test capi3-1.3 { do_test capi3-1.4 { set sql {SELECT name FROM sqlite_master;SELECT 10} set STMT [sqlite3_prepare $DB $sql -1 TAIL] - sqlite_finalize $STMT + sqlite3_finalize $STMT set TAIL } {SELECT 10} do_test capi3-1.5 { @@ -85,13 +85,13 @@ do_test capi3-1.7 { do_test capi3-2.1 { set sql16 [utf16 {SELECT name FROM sqlite_master}] set STMT [sqlite3_prepare16 $DB $sql16 -1 ::TAIL] - sqlite_finalize $STMT + sqlite3_finalize $STMT utf8 $::TAIL } {} do_test capi3-2.2 { set sql [utf16 {SELECT name FROM sqlite_master;SELECT 10}] set STMT [sqlite3_prepare16 $DB $sql -1 TAIL] - sqlite_finalize $STMT + sqlite3_finalize $STMT utf8 $TAIL } {SELECT 10} do_test capi3-2.3 { @@ -155,6 +155,8 @@ do_test capi3-4.4 { sqlite3_close $db2 } {} +db close + finish_test diff --git a/test/tester.tcl b/test/tester.tcl index 08b11cb2c0..9c9107970c 100644 --- a/test/tester.tcl +++ b/test/tester.tcl @@ -11,7 +11,7 @@ # This file implements some common TCL routines used for regression # testing the SQLite library # -# $Id: tester.tcl,v 1.34 2004/05/21 01:47:27 danielk1977 Exp $ +# $Id: tester.tcl,v 1.35 2004/05/21 10:08:55 danielk1977 Exp $ # Make sure tclsqlite was compiled correctly. Abort now with an # error message if not. @@ -205,7 +205,7 @@ proc stepsql {dbptr sql} { while {[sqlite_step $vm N VAL COL]=="SQLITE_ROW"} { foreach v $VAL {lappend r $v} } - if {[catch {sqlite_finalize $vm} errmsg]} { + if {[catch {sqlite3_finalize $vm} errmsg]} { return [list 1 $errmsg] } } diff --git a/test/vacuum.test b/test/vacuum.test index df4bbe598d..151a82a576 100644 --- a/test/vacuum.test +++ b/test/vacuum.test @@ -11,7 +11,7 @@ # This file implements regression tests for SQLite library. The # focus of this file is testing the VACUUM statement. # -# $Id: vacuum.test,v 1.16 2004/05/21 01:47:27 danielk1977 Exp $ +# $Id: vacuum.test,v 1.17 2004/05/21 10:08:55 danielk1977 Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl @@ -139,7 +139,7 @@ do_test vacuum-4.1 { sqlite_step $VM N VALUES COLNAMES } {SQLITE_DONE} do_test vacuum-4.2 { - sqlite_finalize $VM + sqlite3_finalize $VM } {} # Ticket #515. VACUUM after deleting and recreating the table that