aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/date.c8
-rw-r--r--src/func.c45
-rw-r--r--src/legacy.c6
-rw-r--r--src/md5.c9
-rw-r--r--src/sqlite.h.in658
-rw-r--r--src/tclsqlite.c4
-rw-r--r--src/test1.c32
-rw-r--r--src/test4.c7
-rw-r--r--src/vdbe.c974
-rw-r--r--src/vdbeInt.h31
-rw-r--r--src/vdbeapi.c503
-rw-r--r--src/vdbeaux.c4
-rw-r--r--src/vdbemem.c398
13 files changed, 1141 insertions, 1538 deletions
diff --git a/src/date.c b/src/date.c
index 3a15ba163..42f42f22d 100644
--- a/src/date.c
+++ b/src/date.c
@@ -16,7 +16,7 @@
** sqlite3RegisterDateTimeFunctions() found at the bottom of the file.
** All other code has file scope.
**
-** $Id: date.c,v 1.25 2004/05/26 16:54:42 drh Exp $
+** $Id: date.c,v 1.26 2004/05/26 23:25:31 drh Exp $
**
** NOTES:
**
@@ -645,10 +645,10 @@ static int isDate(int argc, sqlite3_value **argv, DateTime *p){
int i;
if( argc==0 ) return 1;
if( SQLITE3_NULL==sqlite3_value_type(argv[0]) ||
- parseDateOrTime(sqlite3_value_data(argv[0]), p) ) return 1;
+ parseDateOrTime(sqlite3_value_text(argv[0]), p) ) return 1;
for(i=1; i<argc; i++){
if( SQLITE3_NULL==sqlite3_value_type(argv[i]) ||
- parseModifier(sqlite3_value_data(argv[i]), p) ) return 1;
+ parseModifier(sqlite3_value_text(argv[i]), p) ) return 1;
}
return 0;
}
@@ -761,7 +761,7 @@ static void strftimeFunc(
DateTime x;
int n, i, j;
char *z;
- const char *zFmt = sqlite3_value_data(argv[0]);
+ const char *zFmt = sqlite3_value_text(argv[0]);
char zBuf[100];
if( zFmt==0 || isDate(argc-1, argv+1, &x) ) return;
for(i=0, n=1; zFmt[i]; i++, n++){
diff --git a/src/func.c b/src/func.c
index 7aaee79a3..b9f56ef7f 100644
--- a/src/func.c
+++ b/src/func.c
@@ -16,7 +16,7 @@
** sqliteRegisterBuildinFunctions() found at the bottom of the file.
** All other code has file scope.
**
-** $Id: func.c,v 1.57 2004/05/26 16:54:43 drh Exp $
+** $Id: func.c,v 1.58 2004/05/26 23:25:31 drh Exp $
*/
#include <ctype.h>
#include <math.h>
@@ -88,7 +88,7 @@ static void lengthFunc(
break;
}
case SQLITE3_TEXT: {
- const char *z = sqlite3_value_data(argv[0]);
+ const char *z = sqlite3_value_text(argv[0]);
for(len=0; *z; z++){ if( (0xc0&*z)!=0x80 ) len++; }
sqlite3_result_int32(context, len);
break;
@@ -108,7 +108,7 @@ static void absFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
assert( argc==1 );
switch( sqlite3_value_type(argv[0]) ){
case SQLITE3_INTEGER: {
- sqlite3_result_int64(context, -sqlite3_value_int(argv[0]));
+ sqlite3_result_int64(context, -sqlite3_value_int64(argv[0]));
break;
}
case SQLITE3_NULL: {
@@ -116,7 +116,7 @@ static void absFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
break;
}
default: {
- sqlite3_result_double(context, -sqlite3_value_float(argv[0]));
+ sqlite3_result_double(context, -sqlite3_value_double(argv[0]));
break;
}
}
@@ -136,7 +136,7 @@ static void substrFunc(
int p1, p2, len;
assert( argc==3 );
- z = sqlite3_value_data(argv[0]);
+ z = sqlite3_value_text(argv[0]);
if( z==0 ) return;
p1 = sqlite3_value_int(argv[1]);
p2 = sqlite3_value_int(argv[2]);
@@ -180,7 +180,7 @@ static void roundFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
if( n<0 ) n = 0;
}
if( SQLITE3_NULL==sqlite3_value_type(argv[0]) ) return;
- r = sqlite3_value_float(argv[0]);
+ r = sqlite3_value_double(argv[0]);
sprintf(zBuf,"%.*f",n,r);
sqlite3_result_text(context, zBuf, -1, 1);
}
@@ -194,7 +194,7 @@ static void upperFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
if( argc<1 || SQLITE3_NULL==sqlite3_value_type(argv[0]) ) return;
z = sqliteMalloc(sqlite3_value_bytes(argv[0]));
if( z==0 ) return;
- strcpy(z, sqlite3_value_data(argv[0]));
+ strcpy(z, sqlite3_value_text(argv[0]));
for(i=0; z[i]; i++){
if( islower(z[i]) ) z[i] = toupper(z[i]);
}
@@ -207,7 +207,7 @@ static void lowerFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
if( argc<1 || SQLITE3_NULL==sqlite3_value_type(argv[0]) ) return;
z = sqliteMalloc(sqlite3_value_bytes(argv[0]));
if( z==0 ) return;
- strcpy(z, sqlite3_value_data(argv[0]));
+ strcpy(z, sqlite3_value_text(argv[0]));
for(i=0; z[i]; i++){
if( isupper(z[i]) ) z[i] = tolower(z[i]);
}
@@ -301,8 +301,8 @@ static void likeFunc(
int argc,
sqlite3_value **argv
){
- const unsigned char *zA = sqlite3_value_data(argv[0]);
- const unsigned char *zB = sqlite3_value_data(argv[1]);
+ const unsigned char *zA = sqlite3_value_text(argv[0]);
+ const unsigned char *zB = sqlite3_value_text(argv[1]);
if( zA && zB ){
sqlite3_result_int32(context, sqlite3LikeCompare(zA, zB));
}
@@ -318,8 +318,8 @@ static void likeFunc(
** is implemented as glob(A,B).
*/
static void globFunc(sqlite3_context *context, int arg, sqlite3_value **argv){
- const unsigned char *zA = sqlite3_value_data(argv[0]);
- const unsigned char *zB = sqlite3_value_data(argv[1]);
+ const unsigned char *zA = sqlite3_value_text(argv[0]);
+ const unsigned char *zB = sqlite3_value_text(argv[1]);
if( zA && zB ){
sqlite3_result_int32(context, sqlite3GlobCompare(zA, zB));
}
@@ -364,7 +364,6 @@ static void versionFunc(
** single-quote escapes.
*/
static void quoteFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
- const char *zArg = sqlite3_value_data(argv[0]);
if( argc<1 ) return;
switch( sqlite3_value_type(argv[0]) ){
case SQLITE3_NULL: {
@@ -379,7 +378,7 @@ static void quoteFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
case SQLITE3_BLOB: /*** FIX ME. Use a BLOB encoding ***/
case SQLITE3_TEXT: {
int i,j,n;
- const char *zArg = sqlite3_value_data(argv[0]);
+ const char *zArg = sqlite3_value_text(argv[0]);
char *z;
for(i=n=0; zArg[i]; i++){ if( zArg[i]=='\'' ) n++; }
@@ -419,7 +418,7 @@ static void soundexFunc(sqlite3_context *context, int argc, sqlite3_value **argv
1, 2, 6, 2, 3, 0, 1, 0, 2, 0, 2, 0, 0, 0, 0, 0,
};
assert( argc==1 );
- zIn = sqlite3_value_data(argv[0]);
+ zIn = sqlite3_value_text(argv[0]);
for(i=0; zIn[i] && !isalpha(zIn[i]); i++){}
if( zIn[i] ){
zResult[0] = toupper(zIn[i]);
@@ -499,20 +498,20 @@ struct SumCtx {
static void sumStep(sqlite3_context *context, int argc, sqlite3_value **argv){
SumCtx *p;
if( argc<1 ) return;
- p = sqlite3_get_context(context, sizeof(*p));
+ p = sqlite3_aggregate_context(context, sizeof(*p));
if( p && SQLITE3_NULL!=sqlite3_value_type(argv[0]) ){
- p->sum += sqlite3_value_float(argv[0]);
+ p->sum += sqlite3_value_double(argv[0]);
p->cnt++;
}
}
static void sumFinalize(sqlite3_context *context){
SumCtx *p;
- p = sqlite3_get_context(context, sizeof(*p));
+ p = sqlite3_aggregate_context(context, sizeof(*p));
sqlite3_result_double(context, p ? p->sum : 0.0);
}
static void avgFinalize(sqlite3_context *context){
SumCtx *p;
- p = sqlite3_get_context(context, sizeof(*p));
+ p = sqlite3_aggregate_context(context, sizeof(*p));
if( p && p->cnt>0 ){
sqlite3_result_double(context, p->sum/(double)p->cnt);
}
@@ -570,14 +569,14 @@ struct CountCtx {
*/
static void countStep(sqlite3_context *context, int argc, sqlite3_value **argv){
CountCtx *p;
- p = sqlite3_get_context(context, sizeof(*p));
+ p = sqlite3_aggregate_context(context, sizeof(*p));
if( (argc==0 || SQLITE3_NULL!=sqlite3_value_type(argv[0])) && p ){
p->n++;
}
}
static void countFinalize(sqlite3_context *context){
CountCtx *p;
- p = sqlite3_get_context(context, sizeof(*p));
+ p = sqlite3_aggregate_context(context, sizeof(*p));
sqlite3_result_int32(context, p ? p->n : 0);
}
@@ -598,7 +597,7 @@ static void minmaxStep(sqlite3_context *context, int argc, sqlite3_value **argv)
int max = 0;
int cmp = 0;
Mem *pArg = (Mem *)argv[0];
- Mem *pBest = (Mem *)sqlite3_get_context(context, sizeof(*pBest));
+ Mem *pBest = (Mem *)sqlite3_aggregate_context(context, sizeof(*pBest));
if( SQLITE3_NULL==sqlite3_value_type(argv[0]) ) return;
@@ -622,7 +621,7 @@ static void minmaxStep(sqlite3_context *context, int argc, sqlite3_value **argv)
}
static void minMaxFinalize(sqlite3_context *context){
sqlite3_value *pRes;
- pRes = (sqlite3_value *)sqlite3_get_context(context, sizeof(Mem));
+ pRes = (sqlite3_value *)sqlite3_aggregate_context(context, sizeof(Mem));
if( pRes->flags ){
sqlite3_result(context, pRes);
}
diff --git a/src/legacy.c b/src/legacy.c
index 655f2bb7b..664705ba0 100644
--- a/src/legacy.c
+++ b/src/legacy.c
@@ -14,7 +14,7 @@
** other files are for internal use by SQLite and should not be
** accessed by users of the library.
**
-** $Id: legacy.c,v 1.2 2004/05/26 02:04:57 danielk1977 Exp $
+** $Id: legacy.c,v 1.3 2004/05/26 23:25:31 drh Exp $
*/
#include "sqliteInt.h"
@@ -90,7 +90,7 @@ int sqlite3_exec(
if( rc==SQLITE_ROW ){
azVals = &azCols[nCol];
for(i=0; i<nCol; i++){
- azVals[i] = (char *)sqlite3_column_data(pStmt, i);
+ azVals[i] = (char *)sqlite3_column_text(pStmt, i);
}
}
if( xCallback(pArg, nCol, azVals, azCols) ){
@@ -133,5 +133,3 @@ exec_out:
return rc;
}
-
-
diff --git a/src/md5.c b/src/md5.c
index ee5cb552e..a5b279157 100644
--- a/src/md5.c
+++ b/src/md5.c
@@ -360,13 +360,13 @@ static void md5step(sqlite3_context *context, int argc, sqlite3_value **argv){
MD5Context *p;
int i;
if( argc<1 ) return;
- p = sqlite3_get_context(context, sizeof(*p));
+ p = sqlite3_aggregate_context(context, sizeof(*p));
if( p==0 ) return;
if( sqlite3_aggregate_count(context)==1 ){
MD5Init(p);
}
for(i=0; i<argc; i++){
- const char *zData = sqlite3_value_data(argv[i]);
+ const char *zData = sqlite3_value_text(argv[i]);
if( zData ){
MD5Update(p, zData, strlen(zData));
}
@@ -376,7 +376,7 @@ static void md5finalize(sqlite3_context *context){
MD5Context *p;
unsigned char digest[16];
char zBuf[33];
- p = sqlite3_get_context(context, sizeof(*p));
+ p = sqlite3_aggregate_context(context, sizeof(*p));
MD5Final(digest,p);
DigestToBase16(digest, zBuf);
sqlite3_result_text(context, zBuf, -1, 1);
@@ -384,6 +384,3 @@ static void md5finalize(sqlite3_context *context){
void Md5_Register(sqlite *db){
sqlite3_create_function(db, "md5sum", -1, 0, 0, 0, 0, md5step, md5finalize);
}
-
-
-
diff --git a/src/sqlite.h.in b/src/sqlite.h.in
index 027ba7346..444ba5a56 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.81 2004/05/26 16:54:44 drh Exp $
+** @(#) $Id: sqlite.h.in,v 1.82 2004/05/26 23:25:31 drh Exp $
*/
#ifndef _SQLITE_H_
#define _SQLITE_H_
@@ -330,12 +330,14 @@ int sqlite3_get_table(
void sqlite3_free_table(char **result);
/*
-** The following routines are wrappers around sqlite3_exec() and
-** sqlite3_get_table(). The only difference between the routines that
-** follow and the originals is that the second argument to the
-** routines that follow is really a printf()-style format
-** string describing the SQL to be executed. Arguments to the format
-** string appear at the end of the argument list.
+** The following routines are variants of the "sprintf()" from the
+** standard C library. The resulting string is written into memory
+** obtained from malloc() so that there is never a possiblity of buffer
+** overflow. These routines also implement some additional formatting
+** options that are useful for constructing SQL statements.
+**
+** The strings returned by these routines should be freed by calling
+** sqlite3_free().
**
** All of the usual printf formatting options apply. In addition, there
** is a "%q" option. %q works like %s in that it substitutes a null-terminated
@@ -367,50 +369,9 @@ void sqlite3_free_table(char **result);
** should always use %q instead of %s when inserting text into a string
** literal.
*/
-int sqlite3_exec_printf(
- sqlite*, /* An open database */
- const char *sqlFormat, /* printf-style format string for the SQL */
- sqlite_callback, /* Callback function */
- void *, /* 1st argument to callback function */
- char **errmsg, /* Error msg written here */
- ... /* Arguments to the format string. */
-);
-int sqlite3_exec_vprintf(
- sqlite*, /* An open database */
- const char *sqlFormat, /* printf-style format string for the SQL */
- sqlite_callback, /* Callback function */
- void *, /* 1st argument to callback function */
- char **errmsg, /* Error msg written here */
- va_list ap /* Arguments to the format string. */
-);
-int sqlite3_get_table_printf(
- sqlite*, /* An open database */
- const char *sqlFormat, /* printf-style format string for the SQL */
- char ***resultp, /* Result written to a char *[] that this points to */
- int *nrow, /* Number of result rows written here */
- int *ncolumn, /* Number of result columns written here */
- char **errmsg, /* Error msg written here */
- ... /* Arguments to the format string */
-);
-int sqlite3_get_table_vprintf(
- sqlite*, /* An open database */
- const char *sqlFormat, /* printf-style format string for the SQL */
- char ***resultp, /* Result written to a char *[] that this points to */
- int *nrow, /* Number of result rows written here */
- int *ncolumn, /* Number of result columns written here */
- char **errmsg, /* Error msg written here */
- va_list ap /* Arguments to the format string */
-);
char *sqlite3_mprintf(const char*,...);
char *sqlite3_vmprintf(const char*, va_list);
-
-/*
-** Windows systems should call this routine to free memory that
-** is returned in the in the errmsg parameter of sqlite3_open() when
-** SQLite is a DLL. For some reason, it does not work to call free()
-** directly.
-*/
-void sqlite3_freemem(void *p);
+void sqlite3_free(char *z);
/*
** Windows systems need functions to call to return the sqlite3_version
@@ -533,77 +494,17 @@ void sqlite3_progress_handler(sqlite*, int, int(*)(void*), void*);
void *sqlite3_commit_hook(sqlite*, int(*)(void*), void*);
/*
-** Open an encrypted SQLite database. If pKey==0 or nKey==0, this routine
-** is the same as sqlite3_open().
-**
-** The code to implement this API is not available in the public release
-** of SQLite.
-*/
-sqlite *sqlite3_open_encrypted(
- const char *zFilename, /* Name of the encrypted database */
- const void *pKey, /* Pointer to the key */
- int nKey, /* Number of bytes in the key */
- int *pErrcode, /* Write error code here */
- char **pzErrmsg /* Write error message here */
-);
-
-/*
-** Change the key on an open database. If the current database is not
-** encrypted, this routine will encrypt it. If pNew==0 or nNew==0, the
-** database is decrypted.
-**
-** The code to implement this API is not available in the public release
-** of SQLite.
-*/
-int sqlite_rekey(
- sqlite *db, /* Database to be rekeyed */
- const void *pKey, int nKey /* The new key */
-);
-
-/*
-** Encode a binary buffer "in" of size n bytes so that it contains
-** no instances of characters '\'' or '\000'. The output is
-** null-terminated and can be used as a string value in an INSERT
-** or UPDATE statement. Use sqlite_decode_binary() to convert the
-** string back into its original binary.
-**
-** The result is written into a preallocated output buffer "out".
-** "out" must be able to hold at least 2 +(257*n)/254 bytes.
-** In other words, the output will be expanded by as much as 3
-** bytes for every 254 bytes of input plus 2 bytes of fixed overhead.
-** (This is approximately 2 + 1.0118*n or about a 1.2% size increase.)
-**
-** The return value is the number of characters in the encoded
-** string, excluding the "\000" terminator.
-**
-** If out==NULL then no output is generated but the routine still returns
-** the number of characters that would have been generated if out had
-** not been NULL.
-*/
-int sqlite_encode_binary(const unsigned char *in, int n, unsigned char *out);
-
-/*
-** Decode the string "in" into binary data and write it into "out".
-** This routine reverses the encoding created by sqlite_encode_binary().
-** The output will always be a few bytes less than the input. The number
-** of bytes of output is returned. If the input is not a well-formed
-** encoding, -1 is returned.
-**
-** The "in" and "out" parameters may point to the same buffer in order
-** to decode a string in place.
-*/
-int sqlite_decode_binary(const unsigned char *in, unsigned char *out);
-
-/*
-** Open the sqlite database file "filename", where "filename" is UTF-8
-** encoded. An sqlite3* handle is returned in *ppDb, even if an error
-** occurs. If the database is opened (or created) successfully, then
-** SQLITE_OK is returned. Otherwise an error code is returned and the
-** sqlite3_errmsg() function may be used to obtain an English language
-** explanation of the error.
+** Open the sqlite database file "filename". The "filename" is UTF-8
+** encoded for sqlite3_open() and UTF-16 encoded in the native byte order
+** for sqlite3_open16(). An sqlite3* handle is returned in *ppDb, even
+** if an error occurs. If the database is opened (or created) successfully,
+** then SQLITE_OK is returned. Otherwise an error code is returned. The
+** sqlite3_errmsg() or sqlite3_errmsg16() routines can be used to obtain
+** an English language description of the error.
**
-** If the database file does not exist, then a new database is created
-** using UTF-8 text encoding.
+** If the database file does not exist, then a new database is created.
+** The encoding for the database is UTF-8 if sqlite3_open() is called and
+** UTF-16 if sqlite3_open16 is used.
**
** Whether or not an error occurs when it is opened, resources associated
** with the sqlite3* handle should be released by passing it to
@@ -614,22 +515,6 @@ int sqlite3_open(
sqlite3 **ppDb, /* OUT: SQLite db handle */
const char **args /* Null terminated array of option strings */
);
-
-/*
-** Open the sqlite database file "filename", where "filename" is native
-** byte order UTF-16 encoded. An sqlite3* handle is returned in *ppDb, even
-** if an error occurs. If the database is opened (or created) successfully,
-** then SQLITE_OK is returned. Otherwise an error code is returned and the
-** sqlite3_errmsg() function may be used to obtain an English language
-** explanation of the error.
-**
-** If the database file does not exist, then a new database is created
-** using UTF-16 text encoding in the machines native byte order.
-**
-** Whether or not an error occurs when it is opened, resources associated
-** with the sqlite3* handle should be released by passing it to
-** sqlite3_close() when it is no longer required.
-*/
int sqlite3_open16(
const void *filename, /* Database filename (UTF-16) */
sqlite3 **ppDb, /* OUT: SQLite db handle */
@@ -720,6 +605,35 @@ int sqlite3_prepare16(
);
/*
+** In the SQL strings input to sqlite3_prepare() and sqlite3_prepare16(),
+** one or more literals can be replace by a wildcard "?" or ":N:" where
+** N is an integer. These value of these wildcard literals can be set
+** using the routines listed below.
+**
+** In every case, the first parameter is a pointer to the sqlite3_stmt
+** structure returned from sqlite3_prepare(). The second parameter is the
+** index of the wildcard. The first "?" has an index of 1. ":N:" wildcards
+** use the index N.
+**
+** When the eCopy parameter is true, a copy of the value is made into
+** memory obtained and managed by SQLite. When eCopy is false, SQLite
+** assumes that the value is a constant and just stores a pointer to the
+** value without making a copy.
+**
+** The sqlite3_bind_* routine must be called before sqlite3_step() after
+** an sqlite3_prepare() or sqlite3_reset(). Unbound wildcards are interpreted
+** as NULL.
+*/
+void sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, int eCopy);
+void sqlite3_bind_double(sqlite3_stmt*, int, double);
+void sqlite3_bind_int(sqlite3_stmt*, int, int);
+void sqlite3_bind_int64(sqlite3_stmt*, int, long long int);
+void sqlite3_bind_null(sqlite3_stmt*, int);
+void sqlite3_bind_text(sqlite3_stmt*, int, const char*, int n, int eCopy);
+void sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int n, int eCopy);
+void sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*);
+
+/*
** 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).
@@ -729,15 +643,10 @@ 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.
+** second function parameter. The string returned is UTF-8 for
+** sqlite3_column_name() and UTF-16 for sqlite3_column_name16().
*/
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);
/*
@@ -768,131 +677,18 @@ const char *sqlite3_column_decltype(sqlite3_stmt *, int i);
** 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);
+** CREATE TABLE t1(c1 INTEGER);
**
** And the following statement compiled:
**
** SELECT c1 + 1, 0 FROM t1;
**
-** Then this routine would return the string "VARIANT" for the second
+** Then this routine would return the string "INTEGER" 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);
-/*
-** This routine is used to bind a 32-bit integer value to a variable
-** in an SQL statement compiled by sqlite3_prepare(). See comments for
-** sqlite3_prepare() for more details on SQL statement variables.
-**
-** The first argument is a pointer to an SQL statement previously
-** obtained from a call to sqlite3_prepare(). The second parameter "i"
-** determines the parameter to bind the value "iValue" to.
-*/
-int sqlite3_bind_int32(sqlite3_stmt*, int i, int iValue);
-
-/*
-** This routine is used to bind a 64-bit integer value to a variable
-** in an SQL statement compiled by sqlite3_prepare(). See comments for
-** sqlite3_prepare() for more details on SQL statement variables.
-**
-** The first argument is a pointer to an SQL statement previously
-** obtained from a call to sqlite3_prepare(). The second parameter "i"
-** determines the parameter to bind the value "iValue" to.
-*/
-int sqlite3_bind_int64(sqlite3_stmt*, int i, long long int iValue);
-
-/*
-** This routine is used to bind a real (floating point) value to a variable
-** in an SQL statement compiled by sqlite3_prepare(). See comments for
-** sqlite3_prepare() for more details on SQL statement variables.
-**
-** The first argument is a pointer to an SQL statement previously obtained
-** from a call to sqlite3_prepare(). The second parameter "i" determines
-** the parameter to bind the value "iValue" to. Internally, SQLite will
-** manipulate the value as a 64-bit IEEE float.
-*/
-int sqlite3_bind_double(sqlite3_stmt*, int i, double iValue);
-
-/*
-** This routine is used to bind a NULL value to a variable in an SQL
-** statement compiled by sqlite3_prepare(). See comments for
-** sqlite3_prepare() for more details on SQL statement variables.
-**
-** The first argument is a pointer to an SQL statement previously obtained
-** from a call to sqlite3_prepare(). The second parameter "i" determines
-** the parameter to bind the NULL value to.
-*/
-int sqlite3_bind_null(sqlite3_stmt*, int i);
-
-/*
-** This routine is used to bind a UTF-8 string value to a variable in an
-** SQL statement compiled by sqlite3_prepare(). See comments for
-** sqlite3_prepare() for more details on SQL statement variables.
-**
-** The first argument is a pointer to an SQL statement previously obtained
-** from a call to sqlite3_prepare(). The second parameter "i" determines
-** the parameter to bind the value to. Parameter three "z" is a pointer
-** to the UTF-8 string.
-**
-** The fourth "n" parameter is the number of bytes (not characters) in the
-** string pointed to by "z". "n" may or may not include any nul terminator
-** character. If "n" is less than zero, then SQLite assumes that "z" is
-** a nul terminated string.
-**
-** If paramater "eCopy" is true, then SQLite makes a copy of the string
-** pointed to by "z". If "eCopy" is false, then SQLite stores a pointer to
-** the original string data. In this case the caller must ensure that the
-** string data remains stable until after the SQL statement has been
-** finalised or another value bound to variable "i".
-*/
-int sqlite3_bind_text(sqlite3_stmt*, int i, const char* z, int n, int eCopy);
-
-/*
-** This routine is used to bind a UTF-16 string value to a variable in an
-** SQL statement compiled by sqlite3_prepare(). See comments for
-** sqlite3_prepare() for more details on SQL statement variables.
-**
-** The first argument is a pointer to an SQL statement previously obtained
-** from a call to sqlite3_prepare(). The second parameter "i" determines
-** the parameter to bind the value to. Parameter three "z" is a pointer to
-** the UTF-16 string. If the string does not begin with a byte-order-mark,
-** it is assumed to be encoded in the native byte order of the machine.
-**
-** The fourth "n" parameter is the number of bytes (not characters) in the
-** string pointed to by "z". "n" may or may not include any nul terminator
-** character. If "n" is less than zero, then SQLite assumes that "z" is
-** terminated by a pair of 0x00 characters.
-**
-** If paramater "eCopy" is true, then SQLite makes a copy of the string
-** pointed to by "z". If "eCopy" is false, then SQLite stores a pointer to
-** the original string data. In this case the caller must ensure that the
-** string data remains stable until after the SQL statement has been
-** finalised or another value bound to variable "i".
-*/
-int sqlite3_bind_text16(sqlite3_stmt*, int i, const void *z, int, int eCopy);
-
-/*
-** This routine is used to bind a blob value to a variable in an
-** SQL statement compiled by sqlite3_prepare(). See comments for
-** sqlite3_prepare() for more details on SQL statement variables.
-**
-** The first argument is a pointer to an SQL statement previously obtained
-** from a call to sqlite3_prepare(). The second parameter "i" determines
-** the parameter to bind the value to. Parameter three "z" is a pointer to
-** the blob of data.
-**
-** The fourth "n" parameter is the number of bytes in the blob pointed to
-** by "z". "n" may not be less than zero.
-**
-** If paramater "eCopy" is true, then SQLite makes a copy of the blob
-** pointed to by "z". If "eCopy" is false, then SQLite stores a pointer to
-** the original blob data. In this case the caller must ensure that the
-** blob data remains stable until after the SQL statement has been
-** finalised or another value bound to variable "i".
-*/
-int sqlite3_bind_blob(sqlite3_stmt*, int i, const void *z, int n, int eCopy);
-
/*
** After an SQL query has been compiled with a call to either
** sqlite3_prepare() or sqlite3_prepare16(), then this function must be
@@ -938,108 +734,82 @@ int sqlite3_step(sqlite3_stmt*);
*/
int sqlite3_data_count(sqlite3_stmt *pStmt);
-#define SQLITE3_INTEGER 1
-#define SQLITE3_FLOAT 2
-#define SQLITE3_TEXT 3
-#define SQLITE3_BLOB 4
-#define SQLITE3_NULL 5
-
-/*
-** 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 bytes 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 length of the data in bytes returned by the
-** sqlite3_column_data() routine for the same second parameter value.
-**
-** If sqlite3_column_data() returns a UTF-16 string, then the length
-** returned by this function includes the nul terminator character (two
-** bytes) at the end of the UTF-16 string.
-*/
-int sqlite3_column_bytes16(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);
+** Values are stored in the database in one of the following fundamental
+** types.
+*/
+#define SQLITE_INTEGER 1
+#define SQLITE_FLOAT 2
+#define SQLITE_TEXT 3
+#define SQLITE_BLOB 4
+#define SQLITE_NULL 5
+
+/*
+** The next group of routines returns information about the information
+** in a single column of the current result row of a query. In every
+** case the first parameter is a pointer to the SQL statement that is being
+** executed (the sqlite_stmt* that was returned from sqlite3_prepare()) and
+** the second argument is the index of the column for which information
+** should be returned. iCol is zero-indexed. The left-most column as an
+** index of 0.
+**
+** If the SQL statement is not currently point to a valid row, or if the
+** the colulmn index is out of range, the result is undefined.
+**
+** These routines attempt to convert the value where appropriate. For
+** example, if the internal representation is FLOAT and a text result
+** is requested, sprintf() is used internally to do the conversion
+** automatically. The following table details the conversions that
+** are applied:
+**
+** Internal Type Requested Type Conversion
+** ------------- -------------- --------------------------
+** NULL INTEGER Result is 0
+** NULL FLOAT Result is 0.0
+** NULL TEXT Result is an empty string
+** NULL BLOB Result is a zero-length BLOB
+** INTEGER FLOAT Convert from integer to float
+** INTEGER TEXT ASCII rendering of the integer
+** INTEGER BLOB Same as for INTEGER->TEXT
+** FLOAT INTEGER Convert from float to integer
+** FLOAT TEXT ASCII rendering of the float
+** FLOAT BLOB Same as FLOAT->TEXT
+** TEXT INTEGER Use atoi()
+** TEXT FLOAT Use atof()
+** TEXT BLOB No change
+** BLOB INTEGER Convert to TEXT then use atoi()
+** BLOB FLOAT Convert to TEXT then use atof()
+** BLOB TEXT Add a \000 terminator if needed
+**
+** The following access routines are provided:
+**
+** _type() Return the datatype of the result. This is one of
+** SQLITE_INTEGER, SQLITE_FLOAT, SQLITE_TEXT, SQLITE_BLOB,
+** or SQLITE_NULL.
+** _blob() Return the value of a BLOB.
+** _bytes() Return the number of bytes in a BLOB value or the number
+** of bytes in a TEXT value represented as UTF-8. The \000
+** terminator is included in the byte count for TEXT values.
+** _bytes16() Return the number of bytes in a BLOB value or the number
+** of bytes in a TEXT value represented as UTF-16. The \u0000
+** terminator is included in the byte count for TEXT values.
+** _double() Return a FLOAT value.
+** _int() Return an INTEGER value in the host computer's native
+** integer representation. This might be either a 32- or 64-bit
+** integer depending on the host.
+** _int64() Return an INTEGER value as a 64-bit signed integer.
+** _text() Return the value as UTF-8 text.
+** _text16() Return the value as UTF-16 text.
+*/
+void *sqlite3_column_blob(sqlite3_stmt*, int iCol)
+int sqlite3_column_bytes(sqlite3_stmt*, int iCol)
+int sqlite3_column_bytes16(sqlite3_stmt*, int iCol)
+double sqlite3_column_double(sqlite3_stmt*, int iCol)
+int sqlite3_column_int(sqlite3_stmt*, int iCol)
+long long int sqlite3_column_int64(sqlite3_stmt*, int iCol)
+const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol)
+const void *sqlite3_column_text16(sqlite3_stmt*, int iCol)
+int sqlite3_column_type(sqlite3_stmt*, int iCol);
/*
** The sqlite3_finalize() function is called to delete a compiled
@@ -1131,79 +901,25 @@ int sqlite3_create_function16(
*/
int sqlite3_aggregate_count(sqlite3_context*);
-
/*
-** Return the type of the sqlite3_value* passed as the first argument.
-** The type is one of SQLITE3_NULL, SQLITE3_INTEGER, SQLITE3_FLOAT,
-** SQLITE3_TEXT or SQLITE3_BLOB.
-*/
+** The next group of routines returns information about parameters to
+** a user-defined function. Function implementations use these routines
+** to access their parameters. These routines are the same as the
+** sqlite3_column_* routines except that these routines take a single
+** sqlite3_value* pointer instead of an sqlite3_stmt* and an integer
+** column number.
+*/
+void *sqlite3_value_blob(sqlite3_value*)
+int sqlite3_value_bytes(sqlite3_value*)
+int sqlite3_value_bytes16(sqlite3_value*)
+double sqlite3_value_double(sqlite3_value*)
+int sqlite3_value_int(sqlite3_value*)
+long long int sqlite3_value_int64(sqlite3_value*)
+const unsigned char *sqlite3_value_text(sqlite3_value*)
+const void *sqlite3_value_text16(sqlite3_value*)
int sqlite3_value_type(sqlite3_value*);
/*
-** Return the value of the sqlite3_value* passed as the first argument.
-** The value returned depends on the type of the value, as returned by
-** sqlite3_value_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_value_data(sqlite3_value*);
-
-/*
-** Return the number of bytes in the string or blob returned by a call
-** to sqlite3_value_data() on the same sqlite3_value* object.
-*/
-int sqlite3_value_bytes(sqlite3_value*);
-
-/*
-** Return the value of the sqlite3_value* passed as the first argument.
-** The value returned depends on the type of the value, as returned by
-** sqlite3_value_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_value_data16(sqlite3_value*);
-
-/*
-** Return the number of bytes in the string or blob returned by a call
-** to sqlite3_value_data16() on the same sqlite3_value* object.
-*/
-int sqlite3_value_bytes16(sqlite3_value*);
-
-/*
-** Return the value of the sqlite3_value* passed as the first argument.
-** The value returned depends on the type of the value, as returned by
-** sqlite3_value_type():
-**
-** 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_value_int(sqlite3_value*);
-
-/*
-** Return the value of the sqlite3_value* passed as the first argument.
-** The value returned depends on the type of the value, as returned by
-** sqlite3_value_type():
-**
-** 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_value_float(sqlite3_value*);
-
-/*
** Aggregate functions use the following routine to allocate
** a structure for storing their state. The first time this routine
** is called for a particular aggregate, a new structure of size nBytes
@@ -1213,7 +929,7 @@ double sqlite3_value_float(sqlite3_value*);
**
** The buffer allocated is freed automatically by SQLite.
*/
-void *sqlite3_get_context(sqlite3_context*, int nBytes);
+void *sqlite3_aggregate_context(sqlite3_context*, int nBytes);
/*
** The pUserData parameter to the sqlite3_create_function() and
@@ -1224,89 +940,19 @@ void *sqlite3_get_context(sqlite3_context*, int nBytes);
void *sqlite3_user_data(sqlite3_context*);
/*
-** The following three functions may be called from within a user-defined
-** function callback or a user-defined aggregate finalizer callback. The
-** result of the user-defined function or aggregate is set to the value of
-** the second parameter. Any value previously set as the return value via
-** an sqlite3_result_*() call is overwritten.
-**
-** The first parameter to each of these routines must be a copy of the
-** sqlite3_context* pointer passed to the user-defined function or
-** aggregate finalizer function.
+** User-defined functions invoke the following routines in order to
+** set their return value.
*/
-void sqlite3_result_int32(sqlite3_context*, int);
-void sqlite3_result_int64(sqlite3_context*, long long int);
+void sqlite3_result_blob(sqlite3_context*, const void*, int n, int eCopy);
void sqlite3_result_double(sqlite3_context*, double);
-
-/*
-** This function may be called from within a user-defined function callback
-** or a user-defined aggregate finalizer callback. The result of the
-** user-defined function or aggregate is set to NULL. Any value previously
-** set as the return value via an sqlite3_result_*() call is overwritten.
-**
-** The parameter to this routine must be a copy of the sqlite3_context*
-** pointer passed to the user-defined function or aggregate finalizer
-** function.
-*/
+void sqlite3_result_error(sqlite3_context*, const char*, int);
+void sqlite3_result_error16(sqlite3_context*, const void*, int);
+void sqlite3_result_int(sqlite3_context*, int);
+void sqlite3_result_int64(sqlite3_context*, long long int);
void sqlite3_result_null(sqlite3_context*);
-
-/*
-** The following two functions may be called from within a user-defined or
-** a user-defined aggregate finalizer callback to return a text value.
-** The second parameter is a pointer to the string, encoded in UTF-8
-** for sqlite3_result_text() and UTF-16 (machine byte order) for
-** sqlite3_result_text16().
-**
-** If the third parameter, n, is positive, it is the number of bytes (not
-** characters) in the string data. A negative n value indicates that the
-** string may be read up to the nul terminator character.
-**
-** If the fourth parameter is non-zero, then a copy is made of the string.
-** Otherwise, SQLite stores a pointer to the original string data.
-**
-** The first parameter to this routine must be a copy of the
-** sqlite3_context* pointer passed to the user-defined function or
-** aggregate finalizer function.
-*/
void sqlite3_result_text(sqlite3_context*, const char*, int n, int eCopy);
void sqlite3_result_text16(sqlite3_context*, const void*, int n, int eCopy);
-
-/*
-** The following function may be called from within a user-defined or a
-** user-defined aggregate finalizer callback to return a blob value. The
-** second parameter is a pointer to the blob of data. The third parameter
-** is the number of bytes of data in the blob.
-**
-** If the fourth parameter is non-zero, then a copy is made of the blob.
-** Otherwise, SQLite stores a pointer to the original blob data.
-**
-** The first parameter to this routine must be a copy of the
-** sqlite3_context* pointer passed to the user-defined function or
-** aggregate finalizer function.
-*/
-void sqlite3_result_blob(sqlite3_context*, const void*, int n, int eCopy);
-
-/*
-** These routines are used from within a user-defined or a user-defined
-** aggregate finalizer callback to return an error. The second parameter
-** is a pointer to a string describing the error, or NULL if no explanation
-** is provided.
-**
-** The string should be encoded in UTF-8 for sqlite3_result_error() and
-** UTF-16 (machine byte order) for sqlite3_result_error16().
-**
-** If not negative, the third parameter is the number of bytes (not
-** characters) in the string passed as the second argument. If the third
-** parameter is negative, then the string is read up to the first nul
-** terminator character.
-*/
-void sqlite3_result_error(sqlite3_context*, const char*, int);
-void sqlite3_result_error16(sqlite3_context*, const void*, int);
-
-/*
-** Copy a function parameter into the result of the function.
-*/
-void sqlite3_result(sqlite3_context*, sqlite3_value*);
+void sqlite3_result_value(sqlite3_context*, sqlite3_value*);
#ifdef __cplusplus
} /* End of the 'extern "C"' block */
diff --git a/src/tclsqlite.c b/src/tclsqlite.c
index a1a1a44c9..33355ba2b 100644
--- a/src/tclsqlite.c
+++ b/src/tclsqlite.c
@@ -11,7 +11,7 @@
*************************************************************************
** A TCL Interface to SQLite
**
-** $Id: tclsqlite.c,v 1.72 2004/05/26 16:54:46 drh Exp $
+** $Id: tclsqlite.c,v 1.73 2004/05/26 23:25:31 drh Exp $
*/
#ifndef NO_TCL /* Omit this whole file if TCL is unavailable */
@@ -391,7 +391,7 @@ static void tclSqlFunc(sqlite3_context *context, int argc, sqlite3_value **argv)
if( SQLITE3_NULL==sqlite3_value_type(argv[i]) ){
Tcl_DStringAppendElement(&cmd, "");
}else{
- Tcl_DStringAppendElement(&cmd, sqlite3_value_data(argv[i]));
+ Tcl_DStringAppendElement(&cmd, sqlite3_value_text(argv[i]));
}
}
rc = Tcl_Eval(p->interp, Tcl_DStringValue(&cmd));
diff --git a/src/test1.c b/src/test1.c
index e695cce5f..c09ced4cd 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.58 2004/05/26 13:27:00 danielk1977 Exp $
+** $Id: test1.c,v 1.59 2004/05/26 23:25:31 drh Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"
@@ -300,7 +300,7 @@ static void ifnullFunc(sqlite3_context *context, int argc, sqlite3_value **argv)
int i;
for(i=0; i<argc; i++){
if( SQLITE3_NULL!=sqlite3_value_type(argv[i]) ){
- sqlite3_result_text(context, sqlite3_value_data(argv[i]), -1, 1);
+ sqlite3_result_text(context, sqlite3_value_text(argv[i]), -1, 1);
break;
}
}
@@ -373,7 +373,7 @@ static void sqlite3ExecFunc(
struct dstr x;
memset(&x, 0, sizeof(x));
sqlite3_exec((sqlite*)sqlite3_user_data(context),
- sqlite3_value_data(argv[0]),
+ sqlite3_value_text(argv[0]),
execFuncCallback, &x, 0);
sqlite3_result_text(context, x.z, x.nUsed, 1);
sqliteFree(x.z);
@@ -423,14 +423,14 @@ struct CountCtx {
};
static void countStep(sqlite3_context *context, int argc, sqlite3_value **argv){
CountCtx *p;
- p = sqlite3_get_context(context, sizeof(*p));
+ p = sqlite3_aggregate_context(context, sizeof(*p));
if( (argc==0 || SQLITE3_NULL!=sqlite3_value_type(argv[0]) ) && p ){
p->n++;
}
}
static void countFinalize(sqlite3_context *context){
CountCtx *p;
- p = sqlite3_get_context(context, sizeof(*p));
+ p = sqlite3_aggregate_context(context, sizeof(*p));
sqlite3_result_int32(context, p ? p->n : 0);
}
@@ -645,8 +645,8 @@ static int sqlite_abort(
*/
static void testFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
while( argc>=2 ){
- const char *zArg0 = sqlite3_value_data(argv[0]);
- const char *zArg1 = sqlite3_value_data(argv[1]);
+ const char *zArg0 = sqlite3_value_text(argv[0]);
+ const char *zArg1 = sqlite3_value_text(argv[1]);
if( zArg0==0 ){
sqlite3_result_error(context, "first argument to test function "
"may not be NULL", -1);
@@ -1316,11 +1316,11 @@ static int test_step(
}
/*
-** Usage: sqlite3_column_data STMT column
+** Usage: sqlite3_column_text STMT column
**
** Advance the statement to the next row.
*/
-static int test_column_data(
+static int test_column_text(
void * clientData,
Tcl_Interp *interp,
int objc,
@@ -1341,9 +1341,9 @@ static int test_column_data(
if( SQLITE3_BLOB==sqlite3_column_type(pStmt, col) ){
int len = sqlite3_column_bytes(pStmt, col);
- pRet = Tcl_NewByteArrayObj(sqlite3_column_data(pStmt, col), len);
+ pRet = Tcl_NewByteArrayObj(sqlite3_column_text(pStmt, col), len);
}else{
- pRet = Tcl_NewStringObj(sqlite3_column_data(pStmt, col), -1);
+ pRet = Tcl_NewStringObj(sqlite3_column_text(pStmt, col), -1);
}
Tcl_SetObjResult(interp, pRet);
@@ -1351,11 +1351,11 @@ static int test_column_data(
}
/*
-** Usage: sqlite3_column_data16 STMT column
+** Usage: sqlite3_column_text16 STMT column
**
** Advance the statement to the next row.
*/
-static int test_column_data16(
+static int test_column_text16(
void * clientData,
Tcl_Interp *interp,
int objc,
@@ -1376,7 +1376,7 @@ static int test_column_data16(
if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR;
len = sqlite3_column_bytes16(pStmt, col);
- pRet = Tcl_NewByteArrayObj(sqlite3_column_data16(pStmt, col), len);
+ pRet = Tcl_NewByteArrayObj(sqlite3_column_text16(pStmt, col), len);
Tcl_SetObjResult(interp, pRet);
return TCL_OK;
@@ -1663,8 +1663,8 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
{ "sqlite3_finalize", (Tcl_ObjCmdProc*)test_finalize },
{ "sqlite3_reset", (Tcl_ObjCmdProc*)test_reset },
{ "sqlite3_step", (Tcl_ObjCmdProc*)test_step},
- { "sqlite3_column_data", (Tcl_ObjCmdProc*)test_column_data },
- { "sqlite3_column_data16", (Tcl_ObjCmdProc*)test_column_data16 },
+ { "sqlite3_column_text", (Tcl_ObjCmdProc*)test_column_text },
+ { "sqlite3_column_text16", (Tcl_ObjCmdProc*)test_column_text16 },
{ "sqlite3_column_count", (Tcl_ObjCmdProc*)test_column_count },
{ "sqlite3_column_name", (Tcl_ObjCmdProc*)test_column_name },
{ "sqlite3_column_name16", (Tcl_ObjCmdProc*)test_column_name16 },
diff --git a/src/test4.c b/src/test4.c
index 054e578af..46d6e3c4f 100644
--- a/src/test4.c
+++ b/src/test4.c
@@ -11,7 +11,7 @@
*************************************************************************
** Code for testing the the SQLite library in a multithreaded environment.
**
-** $Id: test4.c,v 1.7 2004/05/26 02:04:57 danielk1977 Exp $
+** $Id: test4.c,v 1.8 2004/05/26 23:25:31 drh Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"
@@ -498,7 +498,7 @@ static void do_step(Thread *p){
if( p->rc==SQLITE_ROW ){
p->argc = sqlite3_column_count(p->pStmt);
for(i=0; i<sqlite3_data_count(p->pStmt); i++){
- p->argv[i] = sqlite3_column_data(p->pStmt, i);
+ p->argv[i] = sqlite3_column_text(p->pStmt, i);
}
for(i=0; i<p->argc; i++){
p->colv[i] = sqlite3_column_name(p->pStmt, i);
@@ -648,6 +648,3 @@ int Sqlitetest4_Init(Tcl_Interp *interp){
#else
int Sqlitetest4_Init(Tcl_Interp *interp){ return TCL_OK; }
#endif /* OS_UNIX */
-
-
-
diff --git a/src/vdbe.c b/src/vdbe.c
index 2b8e2822e..c5f75a9da 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.335 2004/05/26 16:54:47 drh Exp $
+** $Id: vdbe.c,v 1.336 2004/05/26 23:25:31 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
@@ -75,122 +75,8 @@ int sqlite3_interrupt_count = 0;
** TEXT_Utf16le or TEXT_Utf16be.
*/
#define MemEnc(p) ( \
- p->flags&MEM_Utf16le?TEXT_Utf16le: \
- (p->flags&MEM_Utf16le?TEXT_Utf16be:TEXT_Utf8) )
-
-/*
-** The following macros each take one parameter, a pointer to a Mem
-** structure. The value returned is non-zero if the value stored in
-** the Mem structure is of or can be losslessly converted to the
-** type implicit in the macro name.
-**
-** MemIsNull # NULL values
-** MemIsInt # Ints and reals and strings that can be converted to ints.
-** MemIsReal # Reals, ints and strings that look like numbers
-** MemIsStr # Strings, reals and ints.
-** MemIsBlob # Blobs.
-**
-** These macros do not alter the contents of the Mem structure.
-*/
-#define MemIsNull(p) ((p)->flags&Mem_Null)
-#define MemIsBlob(p) ((p)->flags&Mem_Blob)
-#define MemIsStr(p) ((p)->flags&(MEM_Int|MEM_Real|MEM_Str))
-#define MemIsInt(p) ((p)->flags&(MEM_Int|MEM_Real) || hardMemIsInt(p))
-#define MemIsReal(p) ((p)->flags&(MEM_Int|MEM_Real) || hardMemIsReal(p))
-static int hardMemIsInt(Mem *p){
- assert( !(p->flags&(MEM_Int|MEM_Real)) );
- if( p->flags&MEM_Str ){
- int realnum = 0;
- if( sqlite3IsNumber(p->z, &realnum, MemEnc(p)) && !realnum ){
- return 1;
- }
- }
- return 0;
-}
-static int hardMemIsReal(Mem *p){
- assert( !(p->flags&(MEM_Int|MEM_Real)) );
- if( p->flags&MEM_Str && sqlite3IsNumber(p->z, 0, MemEnc(p)) ){
- return 1;
- }
- return 0;
-}
-
-/*
-** The following two macros each take one parameter, a pointer to a Mem
-** structure. They return the value stored in the Mem structure coerced
-** to a 64-bit integer or real, respectively.
-**
-** MemInt
-** MemReal
-**
-** These macros do not alter the contents of the Mem structure, although
-** they may cache the integer or real value cast of the value.
-*/
-#define MemInt(p) (((p)->flags&MEM_Int)?(p)->i:hardMemInt(p))
-#define MemReal(p) (((p)->flags&MEM_Real)?(p)->r:hardMemReal(p))
-static i64 hardMemInt(Mem *p){
- assert( !(p->flags&MEM_Int) );
- if( !MemIsInt(p) ) return 0;
-
- if( p->flags&MEM_Real ){
- p->i = p->r;
- }else{
- assert( p->flags&MEM_Str );
- sqlite3atoi64(p->z, &(p->i), MemEnc(p));
- }
- p->flags |= MEM_Int;
- return p->i;
-}
-static double hardMemReal(Mem *p){
- assert( !(p->flags&MEM_Real) );
- if( !MemIsReal(p) ) return 0.0;
-
- if( p->flags&MEM_Int ){
- p->r = p->i;
- }else{
- assert( p->flags&MEM_Str );
- /* p->r = sqlite3AtoF(p->z, 0, MemEnc(p)); */
- p->r = sqlite3AtoF(p->z, 0);
- }
- p->flags |= MEM_Real;
- return p->r;
-}
-
-
-#if 0
-/*
-** MemStr(Mem *pMem)
-** MemBlob(Mem *pMem)
-** MemBloblen(Mem *pMem)
-**
-** MemType(Mem *pMem)
-**
-** MemSetBlob
-** MemSetStr
-**
-** MemSetEnc
-** MemSetType
-**
-** MemCopy
-*/
-struct MemRecord {
- char *zData; /* Serialized record */
- int nField; /* Number of fields in the header */
- int nHeader; /* Number of bytes in the entire header */
- u64 *aType; /* Type values for all entries in the record */
-};
-typedef struct MemRecord MemRecord;
-
-/*
-** Transform the value stored in pMem, which must be a blob into a
-** MemRecord. An Mem cell used to store a MemRecord works as follows:
-**
-** Mem.z points at a MemRecord struct
-*/
-static int Recordify(Mem *pMem){
- return 0;
-}
-#endif
+ ((p)->flags&MEM_Utf16le)?TEXT_Utf16le: \
+ ((p)->flags&MEM_Utf16be)?TEXT_Utf16be:TEXT_Utf8) )
/*
** Release the memory associated with the given stack level. This
@@ -223,7 +109,7 @@ static u8 flagsToEnc(int flags){
*/
static int encToFlags(u8 enc){
switch( enc ){
- case TEXT_Utf8: return MEM_Utf8;
+ case TEXT_Utf8: return MEM_Utf8;
case TEXT_Utf16be: return MEM_Utf16be;
case TEXT_Utf16le: return MEM_Utf16le;
}
@@ -240,23 +126,11 @@ static int encToFlags(u8 enc){
static int SetEncoding(Mem*, int);
/*
-** Set the MEM_TypeStr, MEM_TypeReal or MEM_TypeInt flags in pMem if
-** required.
-*/
-static void MemSetTypeFlags(Mem *pMem){
- int f = pMem->flags;
- if( f&MEM_Int ) pMem->flags |= MEM_TypeInt;
- else if( f&MEM_Real ) pMem->flags |= MEM_TypeReal;
- else if( f&MEM_Str ) pMem->flags |= MEM_TypeStr;
-}
-
-
-/*
** Convert the given stack entity into a string if it isn't one
** already. Return non-zero if a malloc() fails.
*/
#define Stringify(P, enc) \
-if( !((P)->flags&(MEM_Str|MEM_Blob)) ) hardStringify(P, enc);
+(!((P)->flags&(MEM_Str|MEM_Blob)) && hardStringify(P, enc))
static int hardStringify(Mem *pStack, u8 enc){
int rc = SQLITE_OK;
int fg = pStack->flags;
@@ -345,125 +219,6 @@ static int hardDeephem(Mem *pStack){
}
/*
-** 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.
-**
-** The second argument, "flags" consists of one of MEM_Utf8, MEM_Utf16le
-** or MEM_Utf16be, possible ORed with MEM_Term. If necessary this function
-** manipulates the value stored by pMem so that it matches the flags passed
-** in "flags".
-**
-** 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.
-*/
-int SetEncoding(Mem *pMem, int flags){
- u8 enc1; /* Current string encoding (TEXT_Utf* value) */
- u8 enc2; /* Required string encoding (TEXT_Utf* value) */
-
- /* If this is not a string, do nothing. */
- if( !(pMem->flags&MEM_Str) ){
- return SQLITE_OK;
- }
-
- enc1 = flagsToEnc(pMem->flags);
- enc2 = flagsToEnc(flags);
-
- if( enc1!=enc2 ){
- if( enc1==TEXT_Utf8 || enc2==TEXT_Utf8 ){
- /* If the current encoding does not match the desired encoding, then
- ** we will need to do some translation between encodings.
- */
- char *z;
- int n;
- int rc = sqlite3utfTranslate(pMem->z,pMem->n,enc1,(void **)&z,&n,enc2);
- if( rc!=SQLITE_OK ){
- return rc;
- }
-
- /* Result of sqlite3utfTranslate is currently always dynamically
- ** allocated and nul terminated. This might be altered as a performance
- ** enhancement later.
- */
- pMem->z = z;
- pMem->n = n;
- pMem->flags &= ~(MEM_Utf8|MEM_Utf16le|MEM_Utf16be);
- pMem->flags &= ~(MEM_Static|MEM_Short|MEM_Ephem);
- pMem->flags |= (MEM_Dyn|MEM_Term|flags);
- }else{
- /* Must be translating between UTF-16le and UTF-16be. */
- int i;
- if( pMem->flags&MEM_Static ){
- Dynamicify(pMem, enc1);
- }
- 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;
- }
- SetEncodingFlags(pMem, enc2);
- }
- }
-
- if( (flags&MEM_Term) && !(pMem->flags&MEM_Term) ){
- /* If we did not do any translation, but currently the string is
- ** not nul terminated (and is required to be), then we add the
- ** nul terminator now. We never have to do this if we translated
- ** the encoding of the string, as the translation functions return
- ** nul terminated values.
- */
- int f = pMem->flags;
- int nulTermLen = 2; /* The number of 0x00 bytes to append */
- if( enc2==MEM_Utf8 ){
- nulTermLen = 1;
- }
-
- if( pMem->n+nulTermLen<=NBFS ){
- /* If the string plus the nul terminator will fit in the Mem.zShort
- ** buffer, and it is not already stored there, copy it there.
- */
- if( !(f&MEM_Short) ){
- memcpy(pMem->z, pMem->zShort, pMem->n);
- if( f&MEM_Dyn ){
- sqliteFree(pMem->z);
- }
- pMem->z = pMem->zShort;
- pMem->flags &= ~(MEM_Static|MEM_Ephem|MEM_Dyn);
- pMem->flags |= MEM_Short;
- }
- }else{
- /* Otherwise we have to malloc for memory. If the string is already
- ** dynamic, use sqliteRealloc(). Otherwise sqliteMalloc() enough
- ** space for the string and the nul terminator, and copy the string
- ** data there.
- */
- if( f&MEM_Dyn ){
- pMem->z = (char *)sqliteRealloc(pMem->z, pMem->n+nulTermLen);
- if( !pMem->z ){
- return SQLITE_NOMEM;
- }
- }else{
- char *z = (char *)sqliteMalloc(pMem->n+nulTermLen);
- memcpy(z, pMem->z, pMem->n);
- pMem->z = z;
- pMem->flags &= ~(MEM_Static|MEM_Ephem|MEM_Short);
- pMem->flags |= MEM_Dyn;
- }
- }
-
- /* pMem->z now points at the string data, with enough space at the end
- ** to insert the nul nul terminator. pMem->n has not yet been updated.
- */
- memcpy(&pMem->z[pMem->n], "\0\0", nulTermLen);
- pMem->n += nulTermLen;
- pMem->flags |= MEM_Term;
- }
- return SQLITE_OK;
-}
-
-/*
** Convert the given stack entity into a integer if it isn't one
** already.
**
@@ -506,679 +261,6 @@ static void hardRealify(Mem *pStack, u8 enc){
pStack->flags = MEM_Real;
}
-/*
-** Execute the statement pStmt, either until a row of data is ready, the
-** statement is completely executed or an error occurs.
-*/
-int sqlite3_step(sqlite3_stmt *pStmt){
- Vdbe *p = (Vdbe*)pStmt;
- 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( 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_data_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_data_count(pStmt);
- if( i>=vals || i<0 ){
- sqlite3Error(pVm->db, SQLITE_RANGE, 0);
- return 0;
- }
-
- pVal = &pVm->pTos[(1-vals)+i];
- return sqlite3_value_data((sqlite3_value *)pVal);
-}
-
-/*
-** pVal is a Mem* cast to an sqlite_value* value. Return a pointer to
-** the nul terminated UTF-8 string representation if the value is
-** not a blob or NULL. If the value is a blob, then just return a pointer
-** to the blob of data. If it is a NULL, return a NULL pointer.
-**
-** This function may translate the encoding of the string stored by
-** pVal. The MEM_Utf8, MEM_Utf16le and MEM_Utf16be flags must be set
-** correctly when this function is called. If a translation occurs,
-** the flags are set to reflect the new encoding of the string.
-**
-** If a translation fails because of a malloc() failure, a NULL pointer
-** is returned.
-*/
-const unsigned char *sqlite3_value_data(sqlite3_value *pVal){
- int flags = pVal->flags;
-
- if( flags&MEM_Null ){
- /* For a NULL return a NULL Pointer */
- return 0;
- }
-
- if( flags&MEM_Str ){
- /* If there is already a string representation, make sure it is in
- ** encoded in UTF-8.
- */
- SetEncoding(pVal, MEM_Utf8|MEM_Term);
- }else if( !(flags&MEM_Blob) ){
- if( flags&MEM_Int ){
- sqlite3_snprintf(NBFS, pVal->zShort, "%lld", pVal->i);
- }else{
- assert( flags&MEM_Real );
- sqlite3_snprintf(NBFS, pVal->zShort, "%.15g", pVal->r);
- }
- pVal->z = pVal->zShort;
- pVal->n = strlen(pVal->z)+1;
- pVal->flags |= (MEM_Str|MEM_Short);
- }
-
- return pVal->z;
-}
-
-/*
-** pVal is a Mem* cast to an sqlite_value* value. Return a pointer to
-** the nul terminated UTF-16 string representation if the value is
-** not a blob or NULL. If the value is a blob, then just return a pointer
-** to the blob of data. If it is a NULL, return a NULL pointer.
-**
-** The byte-order of the returned string data is the machines native byte
-** order.
-**
-** This function may translate the encoding of the string stored by
-** pVal. The MEM_Utf8, MEM_Utf16le and MEM_Utf16be flags must be set
-** correctly when this function is called. If a translation occurs,
-** the flags are set to reflect the new encoding of the string.
-**
-** If a translation fails because of a malloc() failure, a NULL pointer
-** is returned.
-*/
-const void *sqlite3_value_data16(sqlite3_value* pVal){
- if( pVal->flags&MEM_Null ){
- /* For a NULL return a NULL Pointer */
- return 0;
- }
-
- if( pVal->flags&MEM_Str ){
- /* If there is already a string representation, make sure it is in
- ** encoded in UTF-16 machine byte order.
- */
- SetEncoding(pVal, encToFlags(TEXT_Utf16)|MEM_Term);
- }else if( !(pVal->flags&MEM_Blob) ){
- sqlite3_value_data(pVal);
- SetEncoding(pVal, encToFlags(TEXT_Utf16)|MEM_Term);
- }
-
- return (const void *)(pVal->z);
-}
-
-/*
-** Return the value of the 'i'th column of the current row of the currently
-** executing statement pStmt.
-*/
-const void *sqlite3_column_data16(sqlite3_stmt *pStmt, int i){
- int vals;
- Vdbe *pVm = (Vdbe *)pStmt;
- Mem *pVal;
-
- vals = sqlite3_data_count(pStmt);
- if( i>=vals || i<0 ){
- sqlite3Error(pVm->db, SQLITE_RANGE, 0);
- return 0;
- }
-
- pVal = &pVm->pTos[(1-vals)+i];
- return sqlite3_value_data16((sqlite3_value *)pVal);
-}
-
-/*
-** Return the number of bytes of data that will be returned by the
-** equivalent sqlite3_value_data() call.
-*/
-int sqlite3_value_bytes(sqlite3_value *pVal){
- if( sqlite3_value_data(pVal) ){
- return ((Mem *)pVal)->n;
- }
- return 0;
-}
-
-/*
-** Return the number of bytes of data that will be returned by the
-** equivalent sqlite3_value_data16() call.
-*/
-int sqlite3_value_bytes16(sqlite3_value *pVal){
- if( sqlite3_value_data16(pVal) ){
- return ((Mem *)pVal)->n;
- }
- return 0;
-}
-
-/*
-** Return the value of the sqlite_value* argument coerced to a 64-bit
-** integer.
-*/
-long long int sqlite3_value_int(sqlite3_value *pVal){
- Mem *pMem = (Mem *)pVal;
- return MemInt(pMem);
-}
-
-/*
-** Return the value of the sqlite_value* argument coerced to a 64-bit
-** IEEE float.
-*/
-double sqlite3_value_float(sqlite3_value *pVal){
- Mem *pMem = (Mem *)pVal;
- return MemReal(pMem);
-}
-
-/*
-** 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;
-
- if( sqlite3_column_data(pStmt, i) ){
- int vals = sqlite3_data_count(pStmt);
- return pVm->pTos[(1-vals)+i].n;
- }
- return 0;
-}
-
-/*
-** Return the number of bytes of data that will be returned by the
-** equivalent sqlite3_column_data16() call.
-*/
-int sqlite3_column_bytes16(sqlite3_stmt *pStmt, int i){
- Vdbe *pVm = (Vdbe *)pStmt;
-
- if( sqlite3_column_data16(pStmt, i) ){
- int vals = sqlite3_data_count(pStmt);
- 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_data_count(pStmt);
- if( i>=vals || i<0 ){
- sqlite3Error(pVm->db, SQLITE_RANGE, 0);
- return 0;
- }
-
- pVal = &pVm->pTos[(1-vals)+i];
- return sqlite3_value_int(pVal);
-}
-
-/*
-** 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_data_count(pStmt);
- if( i>=vals || i<0 ){
- sqlite3Error(pVm->db, SQLITE_RANGE, 0);
- return 0;
- }
-
- pVal = &pVm->pTos[(1-vals)+i];
- return sqlite3_value_float(pVal);
-}
-
-/*
-** 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;
- Mem *pColName;
-
- if( N>=sqlite3_column_count(pStmt) || N<0 ){
- sqlite3Error(p->db, SQLITE_RANGE, 0);
- return 0;
- }
-
- pColName = &(p->aColName[N]);
- return sqlite3_value_data(pColName);
-}
-
-/*
-** 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 N){
- Vdbe *p = (Vdbe *)pStmt;
- Mem *pColName;
-
- if( N>=sqlite3_column_count(pStmt) || N<0 ){
- sqlite3Error(p->db, SQLITE_RANGE, 0);
- return 0;
- }
-
- pColName = &(p->aColName[N]);
- return sqlite3_value_data16(pColName);
-}
-
-
-/*
-** Return the type of the value stored in the sqlite_value* object.
-*/
-int sqlite3_value_type(sqlite3_value* pVal){
- int f = ((Mem *)pVal)->flags;
- if( f&MEM_Null ){
- return SQLITE3_NULL;
- }
- if( f&MEM_TypeInt ){
- return SQLITE3_INTEGER;
- }
- if( f&MEM_TypeReal ){
- return SQLITE3_FLOAT;
- }
- if( f&MEM_TypeStr ){
- return SQLITE3_TEXT;
- }
- if( f&MEM_Blob ){
- return SQLITE3_BLOB;
- }
- assert(0);
-}
-
-/*
-** 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;
-
- vals = sqlite3_data_count(pStmt);
- if( i>=vals || i<0 ){
- sqlite3Error(p->db, SQLITE_RANGE, 0);
- return 0;
- }
-
- return sqlite3_value_type(&(p->pTos[(1-vals)+i]));
-}
-
-/*
-** 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 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);
-}
-
-/*
-** Unbind the value bound to variable $i in virtual machine p. This is the
-** the same as binding a NULL value to the column. If the "i" parameter is
-** out of range, then SQLITE_RANGE is returned. Othewise SQLITE_OK.
-**
-** The error code stored in database p->db is overwritten with the return
-** value in any case.
-*/
-static int vdbeUnbind(Vdbe *p, int i){
- Mem *pVar;
- if( p->magic!=VDBE_MAGIC_RUN || p->pc!=0 ){
- sqlite3Error(p->db, SQLITE_MISUSE, 0);
- return SQLITE_MISUSE;
- }
- if( i<1 || i>p->nVar ){
- sqlite3Error(p->db, SQLITE_RANGE, 0);
- return SQLITE_RANGE;
- }
- i--;
- pVar = &p->apVar[i];
- if( pVar->flags&MEM_Dyn ){
- sqliteFree(pVar->z);
- }
- pVar->flags = MEM_Null;
- sqlite3Error(p->db, SQLITE_OK, 0);
- return SQLITE_OK;
-}
-
-/*
-** This routine is used to bind text or blob data to an SQL variable (a ?).
-** It may also be used to bind a NULL value, by setting zVal to 0. Any
-** existing value is unbound.
-**
-** The error code stored in p->db is overwritten with the return value in
-** all cases.
-*/
-static int vdbeBindBlob(
- Vdbe *p, /* Virtual machine */
- int i, /* Var number to bind (numbered from 1 upward) */
- const char *zVal, /* Pointer to blob of data */
- int bytes, /* Number of bytes to copy */
- int copy, /* True to copy the memory, false to copy a pointer */
- int flags /* Valid combination of MEM_Blob, MEM_Str, MEM_Term */
-){
- Mem *pVar;
- int rc;
-
- rc = vdbeUnbind(p, i);
- if( rc!=SQLITE_OK ){
- return rc;
- }
- pVar = &p->apVar[i-1];
-
- if( zVal ){
- pVar->n = bytes;
- pVar->flags = flags;
- if( !copy ){
- pVar->z = (char *)zVal;
- pVar->flags |= MEM_Static;
- }else{
- if( bytes>NBFS ){
- pVar->z = (char *)sqliteMalloc(bytes);
- if( !pVar->z ){
- sqlite3Error(p->db, SQLITE_NOMEM, 0);
- return SQLITE_NOMEM;
- }
- pVar->flags |= MEM_Dyn;
- }else{
- pVar->z = pVar->zShort;
- pVar->flags |= MEM_Short;
- }
- memcpy(pVar->z, zVal, bytes);
- }
- }
-
- return SQLITE_OK;
-}
-
-/*
-** Bind a 64 bit integer to an SQL statement variable.
-*/
-int sqlite3_bind_int64(sqlite3_stmt *p, int i, long long int iValue){
- int rc;
- Vdbe *v = (Vdbe *)p;
- rc = vdbeUnbind(v, i);
- if( rc==SQLITE_OK ){
- Mem *pVar = &v->apVar[i-1];
- pVar->flags = MEM_Int;
- pVar->i = iValue;
- }
- return rc;
-}
-
-/*
-** Bind a 32 bit integer to an SQL statement variable.
-*/
-int sqlite3_bind_int32(sqlite3_stmt *p, int i, int iValue){
- return sqlite3_bind_int64(p, i, (long long int)iValue);
-}
-
-/*
-** Bind a double (real) to an SQL statement variable.
-*/
-int sqlite3_bind_double(sqlite3_stmt *p, int i, double iValue){
- int rc;
- Vdbe *v = (Vdbe *)p;
- rc = vdbeUnbind(v, i);
- if( rc==SQLITE_OK ){
- Mem *pVar = &v->apVar[i-1];
- pVar->flags = MEM_Real;
- pVar->r = iValue;
- }
- return SQLITE_OK;
-}
-
-/*
-** Bind a NULL value to an SQL statement variable.
-*/
-int sqlite3_bind_null(sqlite3_stmt* p, int i){
- return vdbeUnbind((Vdbe *)p, i);
-}
-
-/*
-** Bind a UTF-8 text value to an SQL statement variable.
-*/
-int sqlite3_bind_text(
- sqlite3_stmt *pStmt,
- int i,
- const char *zData,
- int nData,
- int eCopy
-){
- Mem *pVar;
- Vdbe *p = (Vdbe *)pStmt;
- int rc = SQLITE_OK;
- u8 db_enc = p->db->enc; /* Text encoding of the database */
-
- /* Unbind any previous variable value */
- rc = vdbeUnbind(p, i);
- if( rc==SQLITE_OK ){
- pVar = &p->apVar[i-1];
-
- if( !zData ){
- /* If zData is NULL, then bind an SQL NULL value */
- pVar->flags = MEM_Null;
- }else{
- if( zData && nData<0 ){
- nData = strlen(zData) + 1;
- }
- pVar->z = (char *)zData;
- pVar->n = nData;
- pVar->flags = MEM_Utf8|MEM_Str|(zData[nData-1]?0:MEM_Term);
- if( !eCopy || db_enc!=TEXT_Utf8 ){
- pVar->flags |= MEM_Static;
- rc = SetEncoding(pVar, encToFlags(db_enc)|MEM_Term);
- }else{
- pVar->flags |= MEM_Ephem;
- Deephemeralize(pVar);
- }
- }
- }
-
- sqlite3Error(p->db, rc, 0);
- return rc;
-
-no_mem:
- sqlite3Error(p->db, SQLITE_NOMEM, 0);
- return SQLITE_NOMEM;
-}
-
-/*
-** Bind a UTF-16 text value to an SQL statement variable.
-*/
-int sqlite3_bind_text16(
- sqlite3_stmt *pStmt,
- int i,
- const void *zData,
- int nData,
- int eCopy
-){
- Vdbe *p = (Vdbe *)pStmt;
- Mem *pVar;
- u8 db_enc = p->db->enc; /* Text encoding of the database */
- u8 txt_enc;
- int null_term = 0;
- int rc;
-
- rc = vdbeUnbind(p, i);
- if( rc!=SQLITE_OK ){
- return rc;
- }
- pVar = &p->apVar[i-1];
-
- /* If zData is NULL, then bind an SQL NULL value */
- if( !zData ){
- pVar->flags = MEM_Null;
- return SQLITE_OK;
- }
-
- if( db_enc==TEXT_Utf8 ){
- /* If the database encoding is UTF-8, then do a translation. */
- pVar->z = sqlite3utf16to8(zData, nData, SQLITE3_BIGENDIAN);
- if( !pVar->z ) return SQLITE_NOMEM;
- pVar->n = strlen(pVar->z)+1;
- pVar->flags = MEM_Str|MEM_Term|MEM_Dyn;
- return SQLITE_OK;
- }
-
- /* There may or may not be a byte order mark at the start of the UTF-16.
- ** Either way set 'txt_enc' to the TEXT_Utf16* value indicating the
- ** actual byte order used by this string. If the string does happen
- ** to contain a BOM, then move zData so that it points to the first
- ** byte after the BOM.
- */
- txt_enc = sqlite3UtfReadBom(zData, nData);
- if( txt_enc ){
- zData = (void *)(((u8 *)zData) + 2);
- }else{
- txt_enc = SQLITE3_BIGENDIAN?TEXT_Utf16be:TEXT_Utf16le;
- }
-
- if( nData<0 ){
- nData = sqlite3utf16ByteLen(zData, -1) + 2;
- null_term = 1;
- }else if( nData>1 && !((u8*)zData)[nData-1] && !((u8*)zData)[nData-2] ){
- null_term = 1;
- }
-
- if( db_enc==txt_enc && !eCopy ){
- /* If the byte order of the string matches the byte order of the
- ** database and the eCopy parameter is not set, then the string can
- ** be used without making a copy.
- */
- pVar->z = (char *)zData;
- pVar->n = nData;
- pVar->flags = MEM_Str|MEM_Static|(null_term?MEM_Term:0);
- }else{
- /* Make a copy. Swap the byte order if required */
- pVar->n = nData + (null_term?0:2);
- pVar->z = sqliteMalloc(pVar->n);
- pVar->flags = MEM_Str|MEM_Dyn|MEM_Term;
- if( db_enc==txt_enc ){
- memcpy(pVar->z, zData, nData);
- }else{
- swab(zData, pVar->z, nData);
- }
- pVar->z[pVar->n-1] = '\0';
- pVar->z[pVar->n-2] = '\0';
- }
-
- return SQLITE_OK;
-}
-
-/*
-** Bind a blob value to an SQL statement variable.
-*/
-int sqlite3_bind_blob(
- sqlite3_stmt *p,
- int i,
- const void *zData,
- int nData,
- int eCopy
-){
- return vdbeBindBlob((Vdbe *)p, i, zData, nData, eCopy, MEM_Blob);
-}
/*
@@ -1793,16 +875,6 @@ case OP_String: {
pTos++;
pTos->flags = 0;
- if( z ){
- /* FIX ME: For now the code in expr.c always puts UTF-8 in P3. It
- ** should transform text to the native encoding before doing so.
- */
- MemSetStr(pTos, z, -1, TEXT_Utf8, 0);
- SetEncoding(pTos, encToFlags(db->enc)|MEM_Term);
- }else if( op==OP_String ){
- pTos->flags = MEM_Null;
- }
-
/* If this is an OP_Real or OP_Integer opcode, set the pTos->r or pTos->i
** values respectively.
*/
@@ -1810,13 +882,34 @@ case OP_String: {
assert( z );
assert( sqlite3IsNumber(z, 0, TEXT_Utf8) );
pTos->r = sqlite3AtoF(z, 0);
- pTos->flags |= MEM_Real;
+ pTos->flags = MEM_Real;
}else if( op==OP_Integer ){
+ pTos->flags = MEM_Int;
pTos->i = pOp->p1;
if( pTos->i==0 && pOp->p3 ){
- sqlite3GetInt64(z, &pTos->i);
+ sqlite3GetInt64(pOp->p3, &pTos->i);
}
- pTos->flags |= MEM_Int;
+ }
+
+ if( z ){
+ /* FIX ME: For now the code in expr.c always puts UTF-8 in P3. It
+ ** should transform text to the native encoding before doing so.
+ */
+ if( db->enc!=TEXT_Utf8 ){
+ rc = sqlite3utfTranslate(z, -1, TEXT_Utf8, (void **)&pTos->z,
+ &pTos->n, db->enc);
+ if( rc!=SQLITE_OK ){
+ assert( !pTos->z );
+ goto abort_due_to_error;
+ }
+ pTos->flags |= MEM_Str | MEM_Dyn | MEM_Term;
+ }else{
+ pTos->z = z;
+ pTos->n = strlen(z) + 1;
+ pTos->flags |= MEM_Str | MEM_Static | MEM_Term;
+ }
+ }else if( op==OP_String ){
+ pTos->flags = MEM_Null;
}
break;
@@ -2036,8 +1129,7 @@ case OP_Callback: {
for(i=0; i<pOp->p1; i++){
Mem *pVal = &pTos[0-i];
SetEncodingFlags(pVal, db->enc);
- MemNulTerminate(pVal);
- MemSetTypeFlags(pVal);
+ sqlite3VdbeMemNulTerminate(pVal);
}
p->resOnStack = 1;
@@ -2288,7 +1380,6 @@ case OP_Function: {
pArg = &pTos[1-n];
for(i=0; i<n; i++, pArg++){
SetEncodingFlags(pArg, db->enc);
- MemSetTypeFlags(pArg);
apVal[i] = pArg;
}
@@ -5636,9 +4727,8 @@ case OP_AggFunc: {
assert( apVal || n==0 );
for(i=0; i<n; i++, pRec++){
- apVal[i] = pRec;
- SetEncodingFlags(pRec, db->enc);
- MemSetTypeFlags(pRec);
+ apVal[i] = pRec;
+ SetEncodingFlags(pRec, db->enc);
}
i = pTos->i;
assert( i>=0 && i<p->agg.nMem );
diff --git a/src/vdbeInt.h b/src/vdbeInt.h
index 733b333f6..10b32f9ea 100644
--- a/src/vdbeInt.h
+++ b/src/vdbeInt.h
@@ -137,31 +137,6 @@ struct Mem {
};
typedef struct Mem Mem;
-/*
-** The following three macros are used to set the value and manifest type
-** stored by a Mem structure.
-**
-** MemSetNull - Set the value to NULL.
-** MemSetInt - Set the value to an integer.
-** MemSetReal - Set the value to a real.
-** MemSetStr - Set the value to a string (or blob if enc==0).
-*/
-#define MemSetNull(p) sqlite3VdbeMemSetNull(p)
-#define MemSetInt(p,v) sqlite3VdbeMemSetInt(p,v)
-#define MemSetReal(p,v) sqlite3VdbeMemSetReal(p,v)
-#define MemSetStr(p,z,n,enc,eCopy) sqlite3VdbeMemSetStr(p,z,n,enc,eCopy)
-
-/*
-** This macro is used to ensure a string stored in a Mem struct is NULL
-** terminated. When used on an object that is not a string or is a nul
-** terminated string this is a no-op. When used on a non-nul-terminated
-** string a nul terminator character is appended.
-**
-** Non-zero is returned if a malloc() fails.
-*/
-#define MemNulTerminate(p) \
-if( ((p)->flags&MEM_Str) && !((p)->flags&MEM_Term) ) sqlite3VdbeMemNulTerminate(p);
-
/* One or more of the following flags are set to indicate the valid
** representations of the value stored in the Mem struct.
**
@@ -215,8 +190,8 @@ if( ((p)->flags&MEM_Str) && !((p)->flags&MEM_Term) ) sqlite3VdbeMemNulTerminate(
** When a user-defined function is called (see OP_Function), the Mem*
** objects that store the argument values for the function call are
** passed to the user-defined function routine cast to sqlite3_value*.
-** The user routine may then call sqlite3_value_data() or
-** sqlite3_value_data16() to request a UTF-8 or UTF-16 string. If the
+** The user routine may then call sqlite3_value_text() or
+** sqlite3_value_text16() to request a UTF-8 or UTF-16 string. If the
** string representation currently stored in Mem.z is not the requested
** encoding, then a translation occurs. To keep track of things, the
** MEM_Utf* flags are set correctly for the database encoding before a
@@ -228,7 +203,7 @@ if( ((p)->flags&MEM_Str) && !((p)->flags&MEM_Term) ) sqlite3VdbeMemNulTerminate(
** internally as Mem* objects. Before sqlite3_step() returns, the MEM_Utf*
** flags are set correctly for the database encoding. A translation may
** take place if the user requests a non-native encoding via
-** sqlite3_column_data() or sqlite3_column_data16(). If this occurs, then
+** sqlite3_column_text() or sqlite3_column_text16(). If this occurs, then
** the MEM_Utf* flags are updated accordingly.
*/
#define MEM_Utf8 0x2000 /* String uses UTF-8 encoding */
diff --git a/src/vdbeapi.c b/src/vdbeapi.c
new file mode 100644
index 000000000..1a5e86c65
--- /dev/null
+++ b/src/vdbeapi.c
@@ -0,0 +1,503 @@
+/*
+** 2004 May 26
+**
+** The author disclaims copyright to this source code. In place of
+** a legal notice, here is a blessing:
+**
+** May you do good and not evil.
+** May you find forgiveness for yourself and forgive others.
+** May you share freely, never taking more than you give.
+**
+*************************************************************************
+**
+** This file contains code use to implement APIs that are part of the
+** VDBE.
+*/
+#include "sqliteInt.h"
+#include "vdbeInt.h"
+
+/**************************** sqlite3_value_ *******************************
+** The following routines extract information from a Mem or sqlite3_value
+** structure.
+*/
+const void *sqlite3_value_blob(sqlite3_value *pVal){
+ Mem *p = (Mem*)pVal;
+ if( p->flags & (MEM_Blob|MEM_Str) ){
+ return p->z;
+ }else{
+ return sqlite3_value_text(pVal);
+ }
+}
+int sqlite3_value_bytes(sqlite3_value *pVal){
+ Mem *p = (Mem*)pVal;
+ if( (p->flags & MEM_Blob)!=0 || sqlite3_value_text(pVal) ){
+ return p->n;
+ }
+ return 0;
+}
+int sqlite3_value_bytes16(sqlite3_value *pVal){
+ Mem *p = (Mem*)pVal;
+ if( (p->flags & MEM_Blob)!=0 || sqlite3_value_text16(pVal) ){
+ return ((Mem *)pVal)->n;
+ }
+ return 0;
+}
+double sqlite3_value_double(sqlite3_value *pVal){
+ Mem *pMem = (Mem *)pVal;
+ Realify(pMem, flagsToEnc(pMem->flags));
+ return pMem->r;
+}
+int sqlite3_value_int(sqlite3_value *pVal){
+ Mem *pMem = (Mem *)pVal;
+ Integerify(pMem, flagsToEnc(pMem->flags));
+ return (int)pVal->i;
+}
+long long int sqlite3_value_int64(sqlite3_value *pVal){
+ Mem *pMem = (Mem *)pVal;
+ Integerify(pMem, flagsToEnc(pMem->flags));
+ return pVal->i;
+}
+const unsigned char *sqlite3_value_text(sqlite3_value *pVal){
+ if( pVal->flags&MEM_Null ){
+ /* For a NULL return a NULL Pointer */
+ return 0;
+ }
+
+ if( pVal->flags&MEM_Str ){
+ /* If there is already a string representation, make sure it is in
+ ** encoded in UTF-8.
+ */
+ SetEncoding(pVal, MEM_Utf8|MEM_Term);
+ }else if( !(pVal->flags&MEM_Blob) ){
+ /* Otherwise, unless this is a blob, convert it to a UTF-8 string */
+ Stringify(pVal, TEXT_Utf8);
+ }
+
+ return pVal->z;
+}
+const void *sqlite3_value_text16(sqlite3_value* pVal){
+ if( pVal->flags&MEM_Null ){
+ /* For a NULL return a NULL Pointer */
+ return 0;
+ }
+
+ if( pVal->flags&MEM_Str ){
+ /* If there is already a string representation, make sure it is in
+ ** encoded in UTF-16 machine byte order.
+ */
+ SetEncoding(pVal, encToFlags(TEXT_Utf16)|MEM_Term);
+ }else if( !(pVal->flags&MEM_Blob) ){
+ /* Otherwise, unless this is a blob, convert it to a UTF-16 string */
+ Stringify(pVal, TEXT_Utf16);
+ }
+
+ return (const void *)(pVal->z);
+}
+int sqlite3_value_type(sqlite3_value* pVal){
+ int f = ((Mem *)pVal)->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);
+}
+
+/**************************** sqlite3_result_ *******************************
+** The following routines are used by user-defined functions to specify
+** the function result.
+*/
+void sqlite3_result_blob(
+ sqlite3_context *pCtx,
+ const void *z,
+ int n,
+ int eCopy
+){
+ assert( n>0 );
+ MemSetStr(&pCtx->s, z, n, 0, eCopy);
+}
+void sqlite3_result_double(sqlite3_context *pCtx, double rVal){
+ sqlite3VdbeMemSetDouble(&pCtx->s, rVal);
+}
+void sqlite3_result_error(sqlite3_context *pCtx, const char *z, int n){
+ pCtx->isError = 1;
+ sqlite3VdbeMemSetStr(&pCtx->s, z, n, TEXT_Utf8, 1);
+}
+void sqlite3_result_error16(sqlite3_context *pCtx, const void *z, int n){
+ pCtx->isError = 1;
+ sqlite3VdbeMemSetStr(&pCtx->s, z, n, TEXT_Utf16, 1);
+}
+void sqlite3_result_int32(sqlite3_context *pCtx, int iVal){
+ sqlite3VdbeMemSetInt64(&pCtx->s, (i64)iVal);
+}
+void sqlite3_result_int64(sqlite3_context *pCtx, i64 iVal){
+ sqlite3VdbeMemSetInt64(&pCtx->s, iVal);
+}
+void sqlite3_result_null(sqlite3_context *pCtx){
+ sqilte3VdbeMemSetNull(&pCtx->s);
+}
+void sqlite3_result_text(
+ sqlite3_context *pCtx,
+ const char *z,
+ int n,
+ int eCopy
+){
+ MemSetStr(&pCtx->s, z, n, TEXT_Utf8, eCopy);
+}
+void sqlite3_result_text16(
+ sqlite3_context *pCtx,
+ const void *z,
+ int n,
+ int eCopy
+){
+ MemSetStr(&pCtx->s, z, n, TEXT_Utf16, eCopy);
+}
+void sqlite3_result_value(sqlite3_context *pCtx, sqlite3_value *pValue){
+ sqlite3VdbeMemCopy(&pCtx->s, pValue);
+}
+
+
+/*
+** Execute the statement pStmt, either until a row of data is ready, the
+** statement is completely executed or an error occurs.
+*/
+int sqlite3_step(sqlite3_stmt *pStmt){
+ Vdbe *p = (Vdbe*)pStmt;
+ 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( 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_data_count(sqlite3_stmt *pStmt){
+ Vdbe *pVm = (Vdbe *)pStmt;
+ if( !pVm->resOnStack ) return 0;
+ return pVm->nResColumn;
+}
+
+
+/*
+** Check to see if column iCol of the given statement is valid. If
+** it is, return a pointer to the Mem for the value of that column.
+** If iCol is not valid, return a pointer to a Mem which has a value
+** of NULL.
+*/
+static Mem *columnMem(sqlite3_stmt *pStmt, int i){
+ Vdbe *pVm = (Vdbe *)pStmt;
+ int vals = sqlite3_data_count(pStmt);
+ if( i>=vals || i<0 ){
+ static Mem nullMem;
+ if( nullMem.flags==0 ){ nullMem.flags = MEM_Null; }
+ sqlite3Error(pVm->db, SQLITE_RANGE, 0);
+ return &nullMem;
+ }
+ return &pVm->pTos[(1-vals)+i];
+}
+
+/**************************** sqlite3_column_ *******************************
+** The following routines are used to access elements of the current row
+** in the result set.
+*/
+int sqlite3_column_bytes(sqlite3_stmt *pStmt, int i){
+ return sqlite3_value_bytes( columnMem(pStmt,i) );
+}
+int sqlite3_column_bytes16(sqlite3_stmt *pStmt, int i){
+ return sqlite3_value_bytes16( columnMem(pStmt,i) );
+}
+double sqlite3_column_double(sqlite3_stmt *pStmt, int i){
+ return sqlite3_value_double( columnMem(pStmt,i) );
+}
+int sqlite3_column_int(sqlite3_stmt *pStmt, int i){
+ return sqlite3_value_int( columnMem(pStmt,i) );
+}
+long long int sqlite3_column_int64(sqlite3_stmt *pStmt, int i){
+ return sqlite3_value_int64( columnMem(pStmt,i) );
+}
+const unsigned char *sqlite3_column_text(sqlite3_stmt *pStmt, int i){
+ return sqlite3_value_text( columnMem(pStmt,i) );
+}
+const void *sqlite3_column_text16(sqlite3_stmt *pStmt, int i){
+ return sqlite3_value_text16( columnMem(pStmt,i) );
+}
+int sqlite3_column_type(sqlite3_stmt *pStmt, int i){
+ return sqlite3_value_type( columnMem(pStmt,i) );
+}
+
+
+/*
+** 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;
+ Mem *pColName;
+
+ if( N>=sqlite3_column_count(pStmt) || N<0 ){
+ sqlite3Error(p->db, SQLITE_RANGE, 0);
+ return 0;
+ }
+
+ pColName = &(p->aColName[N]);
+ return sqlite3_value_text(pColName);
+}
+
+/*
+** 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 N){
+ Vdbe *p = (Vdbe *)pStmt;
+ Mem *pColName;
+
+ if( N>=sqlite3_column_count(pStmt) || N<0 ){
+ sqlite3Error(p->db, SQLITE_RANGE, 0);
+ return 0;
+ }
+
+ pColName = &(p->aColName[N]);
+ return sqlite3_value_text16(pColName);
+}
+
+
+/*
+** 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 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);
+}
+
+/******************************* sqlite3_bind_ ***************************
+**
+** Routines used to attach values to wildcards in a compiled SQL statement.
+*/
+/*
+** Unbind the value bound to variable i in virtual machine p. This is the
+** the same as binding a NULL value to the column. If the "i" parameter is
+** out of range, then SQLITE_RANGE is returned. Othewise SQLITE_OK.
+**
+** The error code stored in database p->db is overwritten with the return
+** value in any case.
+*/
+static int vdbeUnbind(Vdbe *p, int i){
+ Mem *pVar;
+ if( p->magic!=VDBE_MAGIC_RUN || p->pc!=0 ){
+ sqlite3Error(p->db, SQLITE_MISUSE, 0);
+ return SQLITE_MISUSE;
+ }
+ if( i<1 || i>p->nVar ){
+ sqlite3Error(p->db, SQLITE_RANGE, 0);
+ return SQLITE_RANGE;
+ }
+ i--;
+ pVar = &p->apVar[i];
+ if( pVar->flags&MEM_Dyn ){
+ sqliteFree(pVar->z);
+ }
+ pVar->flags = MEM_Null;
+ sqlite3Error(p->db, SQLITE_OK, 0);
+ return SQLITE_OK;
+}
+
+/*
+** Bind a blob value to an SQL statement variable.
+*/
+int sqlite3_bind_blob(
+ sqlite3_stmt *p,
+ int i,
+ const void *zData,
+ int nData,
+ int eCopy
+){
+ Vdbe *p = (Vdbe *)pStmt;
+ Mem *pVar;
+ int rc;
+
+ rc = vdbeUnbind(p, i);
+ if( rc ){
+ return rc;
+ }
+ pVar = &p->apVar[i-1];
+ rc = sqlite3VdbeMemSetStr(pVar, zData, nData, 0, eCopy);
+ return rc;
+}
+int sqlite3_bind_double(sqlite3_stmt *pStmt, int i, double rValue){
+ int rc;
+ Vdbe *p = (Vdbe *)pStmt;
+ Mem *pVar;
+ rc = vdbeUnbind(p, i);
+ if( rc==SQLITE_OK ){
+ sqlite3VdbeMemSetReal(&p->apVar[i-1], rValue);
+ }
+ return SQLITE_OK;
+}
+int sqlite3_bind_int(sqlite3_stmt *p, int i, int iValue){
+ return sqlite3_bind_int64(p, i, (long long int)iValue);
+}
+int sqlite3_bind_int64(sqlite3_stmt *pStmt, int i, long long int iValue){
+ int rc;
+ Vdbe *p = (Vdbe *)pStmt;
+ rc = vdbeUnbind(p, i);
+ if( rc==SQLITE_OK ){
+ sqlite3VdbeMemSetInt(&p->apVar[i-1], iValue);
+ }
+ return rc;
+}
+int sqlite3_bind_null(sqlite3_stmt* p, int i){
+ return vdbeUnbind((Vdbe *)p, i);
+}
+int sqlite3_bind_text(
+ sqlite3_stmt *pStmt,
+ int i,
+ const char *zData,
+ int nData,
+ int eCopy
+){
+ Vdbe *p = (Vdbe *)pStmt;
+ Mem *pVar;
+ int rc;
+
+ rc = vdbeUnbind(p, i);
+ if( rc ){
+ return rc;
+ }
+ pVar = &p->apVar[i-1];
+ rc = sqlite3VdbeMemSetStr(pVar, zData, nData, TEXT_Utf8, eCopy);
+ if( rc ){
+ return rc;
+ }
+ rc = sqlite3VdbeSetEncoding(pVar, p->db->enc);
+ return rc;
+}
+int sqlite3_bind_text16(
+ sqlite3_stmt *pStmt,
+ int i,
+ const void *zData,
+ int nData,
+ int eCopy
+){
+ Vdbe *p = (Vdbe *)pStmt;
+ Mem *pVar;
+ int rc;
+
+ rc = vdbeUnbind(p, i);
+ if( rc ){
+ return rc;
+ }
+ Mem *pVar = &p->apVar[i-1];
+
+ /* There may or may not be a byte order mark at the start of the UTF-16.
+ ** Either way set 'txt_enc' to the TEXT_Utf16* value indicating the
+ ** actual byte order used by this string. If the string does happen
+ ** to contain a BOM, then move zData so that it points to the first
+ ** byte after the BOM.
+ */
+ txt_enc = sqlite3UtfReadBom(zData, nData);
+ if( txt_enc ){
+ zData = (void *)(((u8 *)zData) + 2);
+ nData -= 2;
+ }else{
+ txt_enc = SQLITE3_BIGENDIAN?TEXT_Utf16be:TEXT_Utf16le;
+ }
+ rc = sqlite3VdbeMemSetStr(pVar, zData, nData, txt_enc, eCopy);
+ if( rc ){
+ return rc;
+ }
+ rc = sqlite3VdbeSetEncoding(pVar, p->db->enc);
+ return rc;
+}
diff --git a/src/vdbeaux.c b/src/vdbeaux.c
index b03e49372..fd72c25ba 100644
--- a/src/vdbeaux.c
+++ b/src/vdbeaux.c
@@ -442,7 +442,7 @@ void *sqlite3_user_data(sqlite3_context *p){
** the internals of the sqlite3_context structure which is only defined in
** this source file.
*/
-void *sqlite3_get_context(sqlite3_context *p, int nByte){
+void *sqlite3_aggregate_context(sqlite3_context *p, int nByte){
assert( p && p->pFunc && p->pFunc->xStep );
if( p->pAgg==0 ){
if( nByte<=NBFS ){
@@ -584,7 +584,7 @@ int sqlite3VdbeList(
/* Even though this opcode does not put dynamic strings onto the
** the stack, they may become dynamic if the user calls
- ** sqlite3_column_data16(), causing a translation to UTF-16 encoding.
+ ** sqlite3_column_text16(), causing a translation to UTF-16 encoding.
*/
if( p->pTos==&p->aStack[4] ){
for(i=0; i<5; i++){
diff --git a/src/vdbemem.c b/src/vdbemem.c
new file mode 100644
index 000000000..309f21960
--- /dev/null
+++ b/src/vdbemem.c
@@ -0,0 +1,398 @@
+/*
+** 2004 May 26
+**
+** The author disclaims copyright to this source code. In place of
+** a legal notice, here is a blessing:
+**
+** May you do good and not evil.
+** May you find forgiveness for yourself and forgive others.
+** May you share freely, never taking more than you give.
+**
+*************************************************************************
+**
+** This file contains code use to manipulate "Mem" structure. A "Mem"
+** stores a single value in the VDBE. Mem is an opaque structure visible
+** only within the VDBE. Interface routines refer to a Mem using the
+** name sqlite_value
+*/
+#include "sqliteInt.h"
+#include "os.h"
+#include <ctype.h>
+#include "vdbeInt.h"
+
+/*
+** Given a Mem.flags value, return TEXT_Utf8, TEXT_Utf16le, or TEXT_Utf16be
+** as appropriate.
+*/
+#define flagsToEnc(F) \
+ (((F)&MEM_Utf8)?TEXT_Utf8: \
+ ((F)&MEM_Utf16be)?TEXT_Utf16be:TEXT_Utf16le)
+
+/*
+** 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.
+**
+** The second argument, "flags" consists of one of MEM_Utf8, MEM_Utf16le
+** or MEM_Utf16be, possible ORed with MEM_Term. If necessary this function
+** manipulates the value stored by pMem so that it matches the flags passed
+** in "flags".
+**
+** 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.
+*/
+int sqlite3VdbeSetEncoding(Mem *pMem, int flags){
+ u8 enc1; /* Current string encoding (TEXT_Utf* value) */
+ u8 enc2; /* Required string encoding (TEXT_Utf* value) */
+
+ /* If this is not a string, do nothing. */
+ if( !(pMem->flags&MEM_Str) ){
+ return SQLITE_OK;
+ }
+
+ enc1 = flagsToEnc(pMem->flags);
+ enc2 = flagsToEnc(flags);
+
+ if( enc1!=enc2 ){
+ if( enc1==TEXT_Utf8 || enc2==TEXT_Utf8 ){
+ /* If the current encoding does not match the desired encoding, then
+ ** we will need to do some translation between encodings.
+ */
+ char *z;
+ int n;
+ int rc = sqlite3utfTranslate(pMem->z,pMem->n,enc1,(void **)&z,&n,enc2);
+ if( rc!=SQLITE_OK ){
+ return rc;
+ }
+
+ /* Result of sqlite3utfTranslate is currently always dynamically
+ ** allocated and nul terminated. This might be altered as a performance
+ ** enhancement later.
+ */
+ pMem->z = z;
+ pMem->n = n;
+ pMem->flags = (MEM_Str | MEM_Dyn | MEM_Term | flags);
+ }else{
+ /* Must be translating between UTF-16le and UTF-16be. */
+ int i;
+ if( pMem->flags&MEM_Static ){
+ Dynamicify(pMem, enc1);
+ }
+ 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;
+ }
+ SetEncodingFlags(pMem, enc2);
+ }
+ }
+
+ if( (flags&MEM_Term) && !(pMem->flags&MEM_Term) ){
+ /* If we did not do any translation, but currently the string is
+ ** not nul terminated (and is required to be), then we add the
+ ** nul terminator now. We never have to do this if we translated
+ ** the encoding of the string, as the translation functions return
+ ** nul terminated values.
+ */
+ int f = pMem->flags;
+ int nulTermLen = 2; /* The number of 0x00 bytes to append */
+ if( enc2==MEM_Utf8 ){
+ nulTermLen = 1;
+ }
+
+ if( pMem->n+nulTermLen<=NBFS ){
+ /* If the string plus the nul terminator will fit in the Mem.zShort
+ ** buffer, and it is not already stored there, copy it there.
+ */
+ if( !(f&MEM_Short) ){
+ memcpy(pMem->z, pMem->zShort, pMem->n);
+ if( f&MEM_Dyn ){
+ sqliteFree(pMem->z);
+ }
+ pMem->z = pMem->zShort;
+ pMem->flags &= ~(MEM_Static|MEM_Ephem|MEM_Dyn);
+ pMem->flags |= MEM_Short;
+ }
+ }else{
+ /* Otherwise we have to malloc for memory. If the string is already
+ ** dynamic, use sqliteRealloc(). Otherwise sqliteMalloc() enough
+ ** space for the string and the nul terminator, and copy the string
+ ** data there.
+ */
+ if( f&MEM_Dyn ){
+ pMem->z = (char *)sqliteRealloc(pMem->z, pMem->n+nulTermLen);
+ if( !pMem->z ){
+ return SQLITE_NOMEM;
+ }
+ }else{
+ char *z = (char *)sqliteMallocRaw(pMem->n+nulTermLen);
+ memcpy(z, pMem->z, pMem->n);
+ pMem->z = z;
+ pMem->flags &= ~(MEM_Static|MEM_Ephem|MEM_Short);
+ pMem->flags |= MEM_Dyn;
+ }
+ }
+
+ /* pMem->z now points at the string data, with enough space at the end
+ ** to insert the nul nul terminator. pMem->n has not yet been updated.
+ */
+ memcpy(&pMem->z[pMem->n], "\0\0", nulTermLen);
+ pMem->n += nulTermLen;
+ pMem->flags |= MEM_Term;
+ }
+ return SQLITE_OK;
+}
+
+static void releaseMem(Mem *p){
+ if( p->flags & MEM_Dyn ){
+ sqliteFree(p);
+ }
+}
+
+/*
+** Delete any previous value and set the value stored in *pMem to NULL.
+*/
+void sqlite3VdbeMemSetNull(Mem *pMem){
+ releaseMem(pMem);
+ pMem->flags = MEM_Null;
+}
+
+/*
+** Delete any previous value and set the value stored in *pMem to val,
+** manifest type INTEGER.
+*/
+void sqlite3VdbeMemSetInt(Mem *pMem, i64 val){
+ releaseMem(pMem);
+ pMem->i = val;
+ pMem->flags = MEM_Int;
+}
+
+/*
+** Delete any previous value and set the value stored in *pMem to val,
+** manifest type REAL.
+*/
+void sqlite3VdbeMemSetReal(Mem *pMem, double val){
+ releaseMem(pMem);
+ pMem->r = val;
+ pMem->flags = MEM_Real;
+}
+
+/*
+** Copy the contents of memory cell pFrom into pTo.
+*/
+int sqlite3VdbeMemCopy(Mem *pTo, const Mem *pFrom){
+ releaseMem(pTo);
+ memcpy(pTo, pFrom, sizeof(*pFrom));
+ if( pTo->flags&MEM_Short ){
+ pTo->z = pTo->zShort;
+ }else if( pTo->flags&(MEM_Ephem|MEM_Dyn) ){
+ pTo->flags = pTo->flags&(~(MEM_Static|MEM_Ephem|MEM_Short|MEM_Dyn));
+ if( pTo->n>NBFS ){
+ pTo->z = sqliteMalloc(pTo->n);
+ if( !pTo->z ) return SQLITE_NOMEM;
+ pTo->flags |= MEM_Dyn;
+ }else{
+ pTo->z = pTo->zShort;
+ pTo->flags |= MEM_Short;
+ }
+ memcpy(pTo->z, pFrom->z, pTo->n);
+ }
+ return SQLITE_OK;
+}
+
+int sqlite3VdbeMemSetStr(
+ Mem *pMem, /* Memory cell to set to string value */
+ const char *z, /* String pointer */
+ int n, /* Bytes in string, or negative */
+ u8 enc, /* Encoding of z */
+ int eCopy /* True if this function should make a copy of z */
+){
+ Mem tmp;
+
+ releaseMem(pMem);
+ if( !z ){
+ /* If z is NULL, just set *pMem to contain NULL. */
+ return SQLITE_OK;
+ }
+
+ pMem->z = (char *)z;
+ if( eCopy ){
+ pMem->flags = MEM_Ephem|MEM_Str;
+ }else{
+ pMem->flags = MEM_Static|MEM_Str;
+ }
+ pMem->flags |= encToFlags(enc);
+ pMem->n = n;
+ switch( enc ){
+ case 0:
+ pMem->flags |= MEM_Blob;
+ break;
+
+ case TEXT_Utf8:
+ pMem->flags |= MEM_Utf8;
+ if( n<0 ){
+ pMem->n = strlen(z)+1;
+ pMem->flags |= MEM_Term;
+ }else if( z[pMem->n-1]==0 ){
+ pMem->flags |= MEM_Term;
+ }
+ break;
+
+ case TEXT_Utf16le:
+ case TEXT_Utf16be:
+ pMem->flags |= (enc==TEXT_Utf16le?MEM_Utf16le:MEM_Utf16be);
+ if( n<0 ){
+ pMem->n = sqlite3utf16ByteLen(z,-1)+1;
+ pMem->flags |= MEM_Term;
+ }else if( z[pMem->n-1]==0 && z[pMem->n-2]==0 ){
+ pMem->flags |= MEM_Term;
+ }
+ break;
+
+ default:
+ assert(0);
+ }
+ Deephemeralize(pMem);
+}
+
+int sqlite3VdbeMemNulTerminate(Mem *pMem){
+ int nulTermLen;
+ int f = pMem->flags;
+
+ assert( pMem->flags&MEM_Str && !pMem->flags&MEM_Term );
+ assert( flagsToEnc(pMem->flags) );
+
+ nulTermLen = (flagsToEnc(f)==TEXT_Utf8?1:2);
+
+ if( pMem->n+nulTermLen<=NBFS ){
+ /* If the string plus the nul terminator will fit in the Mem.zShort
+ ** buffer, and it is not already stored there, copy it there.
+ */
+ if( !(f&MEM_Short) ){
+ memcpy(pMem->z, pMem->zShort, pMem->n);
+ if( f&MEM_Dyn ){
+ sqliteFree(pMem->z);
+ }
+ pMem->z = pMem->zShort;
+ pMem->flags &= ~(MEM_Static|MEM_Ephem|MEM_Dyn);
+ pMem->flags |= MEM_Short;
+ }
+ }else{
+ /* Otherwise we have to malloc for memory. If the string is already
+ ** dynamic, use sqliteRealloc(). Otherwise sqliteMalloc() enough
+ ** space for the string and the nul terminator, and copy the string
+ ** data there.
+ */
+ if( f&MEM_Dyn ){
+ pMem->z = (char *)sqliteRealloc(pMem->z, pMem->n+nulTermLen);
+ if( !pMem->z ){
+ return SQLITE_NOMEM;
+ }
+ }else{
+ char *z = (char *)sqliteMalloc(pMem->n+nulTermLen);
+ memcpy(z, pMem->z, pMem->n);
+ pMem->z = z;
+ pMem->flags &= ~(MEM_Static|MEM_Ephem|MEM_Short);
+ pMem->flags |= MEM_Dyn;
+ }
+ }
+
+ /* pMem->z now points at the string data, with enough space at the end
+ ** to insert the nul nul terminator. pMem->n has not yet been updated.
+ */
+ memcpy(&pMem->z[pMem->n], "\0\0", nulTermLen);
+ pMem->n += nulTermLen;
+ pMem->flags |= MEM_Term;
+}
+
+/*
+** Compare the values contained by the two memory cells, returning
+** negative, zero or positive if pMem1 is less than, equal to, or greater
+** than pMem2. Sorting order is NULL's first, followed by numbers (integers
+** and reals) sorted numerically, followed by text ordered by the collating
+** sequence pColl and finally blob's ordered by memcmp().
+**
+** Two NULL values are considered equal by this function.
+*/
+int sqlite3MemCompare(const Mem *pMem1, const Mem *pMem2, const CollSeq *pColl){
+ int rc;
+ int f1, f2;
+ int combined_flags;
+
+ /* Interchange pMem1 and pMem2 if the collating sequence specifies
+ ** DESC order.
+ */
+ f1 = pMem1->flags;
+ f2 = pMem2->flags;
+ combined_flags = f1|f2;
+
+ /* If one value is NULL, it is less than the other. If both values
+ ** are NULL, return 0.
+ */
+ if( combined_flags&MEM_Null ){
+ return (f2&MEM_Null) - (f1&MEM_Null);
+ }
+
+ /* If one value is a number and the other is not, the number is less.
+ ** If both are numbers, compare as reals if one is a real, or as integers
+ ** if both values are integers.
+ */
+ if( combined_flags&(MEM_Int|MEM_Real) ){
+ if( !(f1&(MEM_Int|MEM_Real)) ){
+ return 1;
+ }
+ if( !(f2&(MEM_Int|MEM_Real)) ){
+ return -1;
+ }
+ if( (f1 & f2 & MEM_Int)==0 ){
+ double r1, r2;
+ if( (f1&MEM_Real)==0 ){
+ r1 = pMem1->i;
+ }else{
+ r1 = pMem1->r;
+ }
+ if( (f2&MEM_Real)==0 ){
+ r2 = pMem2->i;
+ }else{
+ r2 = pMem2->r;
+ }
+ if( r1<r2 ) return -1;
+ if( r1>r2 ) return 1;
+ return 0;
+ }else{
+ assert( f1&MEM_Int );
+ assert( f2&MEM_Int );
+ if( pMem1->i < pMem2->i ) return -1;
+ if( pMem1->i > pMem2->i ) return 1;
+ return 0;
+ }
+ }
+
+ /* If one value is a string and the other is a blob, the string is less.
+ ** If both are strings, compare using the collating functions.
+ */
+ if( combined_flags&MEM_Str ){
+ if( (f1 & MEM_Str)==0 ){
+ return 1;
+ }
+ if( (f2 & MEM_Str)==0 ){
+ return -1;
+ }
+ if( pColl && pColl->xCmp ){
+ return pColl->xCmp(pColl->pUser, pMem1->n, pMem1->z, pMem2->n, pMem2->z);
+ }else{
+ /* If no collating sequence is defined, fall through into the
+ ** blob case below and use memcmp() for the comparison. */
+ }
+ }
+
+ /* Both values must be blobs. Compare using memcmp().
+ */
+ rc = memcmp(pMem1->z, pMem2->z, (pMem1->n>pMem2->n)?pMem2->n:pMem1->n);
+ if( rc==0 ){
+ rc = pMem1->n - pMem2->n;
+ }
+ return rc;
+}