]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Further work on the new API. All the functions to execute queries are there
authordanielk1977 <danielk1977@noemail.net>
Fri, 21 May 2004 10:08:53 +0000 (10:08 +0000)
committerdanielk1977 <danielk1977@noemail.net>
Fri, 21 May 2004 10:08:53 +0000 (10:08 +0000)
now. (CVS 1427)

FossilOrigin-Name: fc94575d77f9865e1553bb70c2e3eda2a0b8669e

16 files changed:
manifest
manifest.uuid
src/main.c
src/sqlite.h.in
src/sqliteInt.h
src/test1.c
src/vdbe.c
src/vdbe.h
src/vdbeInt.h
src/vdbeaux.c
test/attach2.test
test/bind.test
test/capi2.test
test/capi3.test
test/tester.tcl
test/vacuum.test

index fdb098b3721732cd6465bb72441af3fe178cd91c..d43af6334a4362dfd2ec0fcd23fbdb7a41bc094d 100644 (file)
--- 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
index e091b3eeb425669eaec500ecca0ee897f62bc3b3..9f5cdd4fb7d8b0930d9b3e79c028a08cf5ba744d 100644 (file)
@@ -1 +1 @@
-25643a0137d395572f16cfec3ab3327d913138ba
\ No newline at end of file
+fc94575d77f9865e1553bb70c2e3eda2a0b8669e
\ No newline at end of file
index 186c012b84fe46d3836d98466bfc82cb0aed2678..0ef79c68b84f33716ac07f06eee808ec6ded96c8 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.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
 
index 123d1268eda2b66fc40f1ff67e68ee7fc17d5856..3a3a697b136354ec0f30d9db62bd5f031cff31b5 100644 (file)
@@ -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);
+/*
+** 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);
+
+/*
+** 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);
-double sqlite3_column_float(sqlite3_stmt*,int);
 
-#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 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 */
index 03dbfaaf67fb54b1816a33f0dcefc4324b64e39b..5d8cee4c3be967b4f9dbb9f1ba5f5371cd5aa781 100644 (file)
@@ -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*,...);
+
index 9a86ddff9f480896a35c33bf1490b02e6787aa65..959a9f74799bd2f2f2185dca392e1feb86a72993 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.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,67 +812,69 @@ 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), " <STMT>", 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 ){
-    char zBuf[50];
-    sprintf(zBuf, "(%d) ", rc);
-    Tcl_AppendResult(interp, zBuf, zErrMsg, 0);
-    sqlite3_freemem(zErrMsg);
     return TCL_ERROR;
   }
   return TCL_OK;
 }
 
 /*
-** Usage:  sqlite3_reset   VM 
+** Usage:  sqlite3_reset  STMT 
 **
-** Reset a virtual machine and prepare it to be run again.
+** Finalize a statement handle.
 */
 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 */
+  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), " <STMT>", 0);
     return TCL_ERROR;
   }
-  if( getVmPointer(interp, argv[1], &vm) ) return TCL_ERROR;
-  rc = sqlite3_reset(vm, &zErrMsg);
+
+  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;
 }
 
+/*
+** Usage:  sqlite3_reset   VM 
+**
+** Reset a virtual machine and prepare it to be run again.
+*/
+
 /*
 ** This is the "static_bind_value" that variables are bound to when
 ** the FLAG option of sqlite3_bind is "static"
@@ -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;
index 849ffe10f78031a701515cb75abe3dfc941a092c..c81fb67b62ae79e8965fe41502268347e484153c 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.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,6 +69,221 @@ int sqlite3_search_count = 0;
 */
 int sqlite3_interrupt_count = 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){
+  int flags = pStack->flags;
+
+  assert( !(flags&MEM_Term) && (flags&MEM_Str) );
+  assert( flags&(MEM_Utf8|MEM_Utf16le|MEM_Utf16be) );
+
+  if( flags&MEM_Utf8 ){
+    /* If the string is already dynamically allocated, use sqliteRealloc()
+    ** to allocate extra space for the terminator.
+    */
+    if( flags&MEM_Dyn ){
+      pStack->z = sqliteRealloc(pStack->z, pStack->n+1);
+      if( !pStack->z ){
+        return 1;
+      }
+    }
+
+    if( flags&(MEM_Static|MEM_Ephem|MEM_Short) ){
+      if( pStack->n+1<NBFS ){
+        if( flags&MEM_Short ){
+          memcpy(pStack->zShort, pStack->z, pStack->n);
+          pStack->flags = MEM_Short|MEM_Str|MEM_Utf8|MEM_Term;
+        }
+      }else{
+        char *z = sqliteMalloc(pStack->n+1);
+        if( !z ){
+          return 1;
+        }
+        memcpy(z, pStack->z, pStack->n);
+        pStack->z = z;
+        pStack->flags = MEM_Dyn|MEM_Str|MEM_Utf8|MEM_Term;
+      }
+    }
+
+    pStack->z[pStack->n] = '\0';
+    pStack->n++;
+  }else{
+    assert(0);
+  }
+
+  return 0;
+}
+
+/*
+** Convert the given stack entity into a string if it isn't one
+** already.
+*/
+#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 ){
+    sqlite3_snprintf(sizeof(pStack->zShort),pStack->zShort,"%.15g",pStack->r);
+  }else if( fg & MEM_Int ){
+    sqlite3_snprintf(sizeof(pStack->zShort),pStack->zShort,"%lld",pStack->i);
+  }else{
+    pStack->zShort[0] = 0;
+  }
+  pStack->z = pStack->zShort;
+  pStack->n = strlen(pStack->zShort)+1;
+  pStack->flags = MEM_Str | MEM_Short | MEM_Term | MEM_Utf8;
+  return 0;
+}
+
+/*
+** Release the memory associated with the given stack level.  This
+** leaves the Mem.flags field in an inconsistent state.
+*/
+#define Release(P) if((P)->flags&MEM_Dyn){ sqliteFree((P)->z); }
+
+/*
+** Convert the given stack entity into a integer if it isn't one
+** already.
+**
+** Any prior string or real representation is invalidated.  
+** NULLs are converted into 0.
+*/
+#define Integerify(P) if(((P)->flags&MEM_Int)==0){ hardIntegerify(P); }
+static void hardIntegerify(Mem *pStack){
+  if( pStack->flags & MEM_Real ){
+    pStack->i = (int)pStack->r;
+    Release(pStack);
+  }else if( pStack->flags & MEM_Str ){
+    sqlite3atoi64(pStack->z, &pStack->i);
+    Release(pStack);
+  }else{
+    pStack->i = 0;
+  }
+  pStack->flags = MEM_Int;
+}
+
+/*
+** Get a valid Real representation for the given stack element.
+**
+** Any prior string or integer representation is retained.
+** NULLs are converted into 0.0.
+*/
+#define Realify(P) if(((P)->flags&MEM_Real)==0){ hardRealify(P); }
+static void hardRealify(Mem *pStack){
+  if( pStack->flags & MEM_Str ){
+    pStack->r = sqlite3AtoF(pStack->z, 0);
+  }else if( pStack->flags & MEM_Int ){
+    pStack->r = pStack->i;
+  }else{
+    pStack->r = 0.0;
+  }
+  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; i<pMem->n; 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.
 **
@@ -110,7 +325,48 @@ int sqlite3_step(
   const char ***pazValue,      /* OUT: Column data */
   const char ***pazColName     /* OUT: Column names and datatypes */
 ){
-  Vdbe *p = (Vdbe*)pVm;
+  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; i<cols; i++){
+      (*pazColName)[i] = sqlite3_column_name(pStmt, i);
+    }
+    for(i=cols; i<(2*cols); i++){
+      (*pazColName)[i] = sqlite3_column_decltype(pStmt, i-cols);
+    }
+
+    if( rc==SQLITE_ROW ){
+      if( vals ) *pazValue = sqliteMalloc(sizeof(char *)*vals); 
+      for(i=0; i<vals; i++){
+        (*pazValue)[i] = sqlite3_column_data(pStmt, i);
+      }
+    }
+  }
+
+  return rc;
+}
+
+/*
+** Execute the statement pStmt, either until a row of data is ready, the
+** statement is completely executed or an error occurs.
+*/
+int sqlite3_step_new(sqlite3_stmt *pStmt){
+  Vdbe *p = (Vdbe*)pStmt;
   sqlite *db;
   int rc;
 
@@ -127,24 +383,239 @@ int sqlite3_step(
   }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( sqlite3SafetyOff(db) ){
+    rc = SQLITE_MISUSE;
   }
-  if( pazValue ){
-    if( rc==SQLITE_ROW ){
-      *pazValue = (const char**)p->azResColumn;
-    }else{
-      *pazValue = 0;
+
+  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( sqlite3SafetyOff(db) ){
-    return SQLITE_MISUSE;
+  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 rc;
+  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);
 }
 
 /*
@@ -189,94 +660,6 @@ static AggElem *_AggInFocus(Agg *p){
   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){
-  int flags = pStack->flags;
-
-  assert( !(flags&MEM_Term) && (flags&MEM_Str) );
-  assert( flags&(MEM_Utf8|MEM_Utf16le|MEM_Utf16be) );
-
-  if( flags&MEM_Utf8 ){
-    /* If the string is already dynamically allocated, use sqliteRealloc()
-    ** to allocate extra space for the terminator.
-    */
-    if( flags&MEM_Dyn ){
-      pStack->z = sqliteRealloc(pStack->z, pStack->n+1);
-      if( !pStack->z ){
-        return 1;
-      }
-    }
-
-    if( flags&(MEM_Static|MEM_Ephem|MEM_Short) ){
-      if( pStack->n+1<NBFS ){
-        if( flags&MEM_Short ){
-          memcpy(pStack->zShort, pStack->z, pStack->n);
-          pStack->flags = MEM_Short|MEM_Str|MEM_Utf8|MEM_Term;
-        }
-      }else{
-        char *z = sqliteMalloc(pStack->n+1);
-        if( !z ){
-          return 1;
-        }
-        memcpy(z, pStack->z, pStack->n);
-        pStack->z = z;
-        pStack->flags = MEM_Dyn|MEM_Str|MEM_Utf8|MEM_Term;
-      }
-    }
-
-    pStack->z[pStack->n] = '\0';
-    pStack->n++;
-  }else{
-    assert(0);
-  }
-
-  return 0;
-}
-
-/*
-** 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);}
-static int hardStringify(Mem *pStack){
-  int fg = pStack->flags;
-  if( fg & MEM_Real ){
-    sqlite3_snprintf(sizeof(pStack->zShort),pStack->zShort,"%.15g",pStack->r);
-  }else if( fg & MEM_Int ){
-    sqlite3_snprintf(sizeof(pStack->zShort),pStack->zShort,"%lld",pStack->i);
-  }else{
-    pStack->zShort[0] = 0;
-  }
-  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
@@ -302,12 +685,6 @@ static int hardDeephem(Mem *pStack){
   return 0;
 }
 
-/*
-** Release the memory associated with the given stack level.  This
-** leaves the Mem.flags field in an inconsistent state.
-*/
-#define Release(P) if((P)->flags&MEM_Dyn){ sqliteFree((P)->z); }
-
 /*
 ** Pop the stack N times.
 */
@@ -321,45 +698,6 @@ static void popStack(Mem **ppTos, int N){
   *ppTos = pTos;
 }
 
-/*
-** Convert the given stack entity into a integer if it isn't one
-** already.
-**
-** Any prior string or real representation is invalidated.  
-** NULLs are converted into 0.
-*/
-#define Integerify(P) if(((P)->flags&MEM_Int)==0){ hardIntegerify(P); }
-static void hardIntegerify(Mem *pStack){
-  if( pStack->flags & MEM_Real ){
-    pStack->i = (int)pStack->r;
-    Release(pStack);
-  }else if( pStack->flags & MEM_Str ){
-    sqlite3atoi64(pStack->z, &pStack->i);
-    Release(pStack);
-  }else{
-    pStack->i = 0;
-  }
-  pStack->flags = MEM_Int;
-}
-
-/*
-** Get a valid Real representation for the given stack element.
-**
-** Any prior string or integer representation is retained.
-** NULLs are converted into 0.0.
-*/
-#define Realify(P) if(((P)->flags&MEM_Real)==0){ hardRealify(P); }
-static void hardRealify(Mem *pStack){
-  if( pStack->flags & MEM_Str ){
-    pStack->r = sqlite3AtoF(pStack->z, 0);
-  }else if( pStack->flags & MEM_Int ){
-    pStack->r = pStack->i;
-  }else{
-    pStack->r = 0.0;
-  }
-  pStack->flags |= MEM_Real;
-}
-
 /*
 ** 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 && pc<p->nOp );
@@ -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 && i<p->nCursor );
-  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 && i<p->nCursor );
   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; k<n && i>0; 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 && i<p->nMem );
   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] = ' ';
index 236b584dcdb39f9b5687173d63aa9e7849fecaf8..b270b104998c1e07f92ca5de82ef4fc6edb0619c 100644 (file)
@@ -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*);
index 38de81981617c4a1484a8ec9aee75513369981d7..96a0f8720daa5d75cd93b888596706ebbc9b12c0 100644 (file)
@@ -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*);
index 6831459e4e76a7166e1880061a097d101aef7508..b6bc0b965d1f93d5ad89b614d3cdd236f59349b6 100644 (file)
@@ -460,7 +460,7 @@ char *sqlite3_set_result_string(sqlite_func *p, const char *zResult, int n){
     if( n<NBFS-1 ){
       memcpy(p->s.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;
 }
+
+
+
index 58ff5e2b56a4352f3fbca9adda4d9d80c123fd73..8cc11aa2a5dbc55a0711bdb93a71e00ca79f1254 100644 (file)
@@ -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}
 
index bc7dbd629b170c23fffbb16c40030776b6e359cd..76b36d671020858293e573bde42f3cd38cb53308 100644 (file)
@@ -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
 } {}
 
 
index 1efe3299ea87ffa3f1ee7a103bd688d64cc371a9..f1d9afebbf4c9164bdad8b5e95412638b2ed2b32 100644 (file)
@@ -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
index 23eab119c4604713d89b9ce46f51720c94550e27..291232ea49603874778e8f6808fca92baadd1c99 100644 (file)
@@ -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
 
 
index 08b11cb2c07ba512d621e74b7417f918a9423ef9..9c9107970c136638a33ed9bd324635fe2e9e8f03 100644 (file)
@@ -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]
     }
   }
index df4bbe598da123ac88b32fe25d4a70acfb2dd51e..151a82a576b62d23e233cac5702342b42d62fd9f 100644 (file)
@@ -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