-C Fixes\sto\sthe\sMEM\schanges.\s\sThe\slibrary\snow\slinks.\s(CVS\s1470)
-D 2004-05-27T03:12:54
+C Various\sbugfixes.\s68\sTest\scases\sstill\sfail.\s(CVS\s1471)
+D 2004-05-27T09:28:42
F Makefile.in ab7b0d5118e2da97bac66be8684a1034e3500f5a
F Makefile.linux-gcc b86a99c493a5bfb402d1d9178dcdc4bd4b32f906
F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
F src/date.c 0eb922af5c5f5e2455f8dc2f98023ed3e04a857e
F src/delete.c 66c5ab98cbad7e6b315fc997bfe6c8080784a701
F src/encode.c a876af473d1d636faa3dca51c7571f2e007eea37
-F src/expr.c 70d6c955c046c07d51521c99786716f49e44023c
-F src/func.c 0910036111443d294739f03d7c9c5b4f759b79cb
+F src/expr.c 3f43cae2c8cf51ea8ee2abbf4dcc900b1326c5d6
+F src/func.c 17303ed9137d7d4c5a738cb70b5300fc237217de
F src/hash.c 440c2f8cb373ee1b4e13a0988489c7cd95d55b6f
F src/hash.h 762d95f1e567664d1eafc1687de755626be962fb
F src/insert.c dd117e8b3f50e943e6cf5fbcf4bbdc0b907b0b4c
F src/os_win.h 5d41af24caaef6c13a2d8e2399caa1c57d45c84d
F src/pager.c 6ff6b906427d4824099140776cb8768f922f3dc5
F src/pager.h 78a00ac280899bcba1a89dc51585dcae6b7b3253
-F src/parse.y 567718866b94d58a6c7681cc45ba7987771d583a
+F src/parse.y 1a39b21982af48cf5c61a4085eece9cab84f9b71
F src/pragma.c f2b05b087a5764802296a28d7abdd75728beedee
F src/printf.c ef750e8e2398ca7e8b58be991075f08c6a7f0e53
F src/random.c eff68e3f257e05e81eae6c4d50a51eb88beb4ff3
F src/select.c e90e2a147273cdcdb1ee9e14574ab28f04382e63
F src/shell.c ed4d237b3e52a0a42512bfcc53530e46de20c28f
-F src/sqlite.h.in a7dc2479fd94f617755a20425f99719d26416a34
+F src/sqlite.h.in cda883efb11c6f767eaf3fea06b3e3419d9cfe7f
F src/sqliteInt.h dbf4fd06e89cdab13f4f1129d76bf79a38ec2b39
F src/table.c af14284fa36c8d41f6829e3f2819dce07d3e2de2
F src/tclsqlite.c 86daf7bf6ba715bf0f0c7a47beb1d947a15cb868
-F src/test1.c ff7cc8729c320aec038e7d9d116bed9eabd642d0
+F src/test1.c 32c2135b95c94c9a8155b6a471ccaa702778c3f8
F src/test2.c 6195a1ca2c8d0d2d93644e86da3289b403486872
F src/test3.c 5e4a6d596f982f6f47a5f9f75ede9b4a3b739968
F src/test4.c 34848a9fd31aa65857b20a8bfc03aff77d8c3426
F src/test5.c 9a1f15133f6955f067c5246e564723b5f23ff221
-F src/tokenize.c e7536dd31205d5afb76c1bdc832dea009c7a3847
+F src/tokenize.c 28ece63a104850f2e06bd7121aeb3449858a27f3
F src/trigger.c 11afe9abfba13a2ba142944c797c952e162d117f
F src/update.c 96461bcf4e946697e83c09c77c7e61b545a2f66e
-F src/utf.c 73d70f2764cb34b072e2d7b0f0c23c389cfc1baa
-F src/util.c 1f6e8febdd15be17e5ee867a7e015596d2bb62de
+F src/utf.c 59b5c8f06a4384a9f64933d6c57a2de02ce3673b
+F src/util.c 179c1347c712dff6671fc5d2dc9d2b009b542a97
F src/vacuum.c 8734f89742f246abd91dbd3e087fc153bddbfbad
-F src/vdbe.c e9d8818bbdf5b4d9123786009d581140487d6f1f
+F src/vdbe.c 54a758cc50b7eb9fe67fab9f2804d3b900536538
F src/vdbe.h e73f890e0f2a6c42b183d7d6937947930fe4fdeb
-F src/vdbeInt.h 8941eb5515430faa1a1b7645b773e7a0933d8221
-F src/vdbeapi.c d3deff8e52e5d58af23c84bcbbd0002193b04a21
-F src/vdbeaux.c 02ad53b5c0ec453b8a4fb4c361c7e0ce223e74c9
-F src/vdbemem.c b7a94817d8ff47ab5b25b814028a7c4320503804
+F src/vdbeInt.h fab8bb7f7a7f4e0714d9b3217c3db97366e16b99
+F src/vdbeapi.c b0bb1f98c899ba00c8a5cbca612c2a28a1bb79de
+F src/vdbeaux.c f36130df1ceff0c461590304a3738cf9da506a0f
+F src/vdbemem.c 6e843650b8d49481e64e3dd47fe8fdba4ab94689
F src/where.c efe5d25fe18cd7381722457898cd863e84097a0c
F test/all.test 569a92a8ee88f5300c057cc4a8f50fbbc69a3242
F test/attach.test cb9b884344e6cfa5e165965d5b1adea679a24c83
F test/auth.test 5c4d95cdaf539c0c236e20ce1f71a93e7dde9185
F test/bigfile.test ea904b853ce2d703b16c5ce90e2b54951bc1ae81
F test/bigrow.test 8ab252dba108f12ad64e337b0f2ff31a807ac578
-F test/bind.test ef1efd5cf63b27c11acda9a1c0c7403960f12400
+F test/bind.test 4f5a19e84077b61ea797644b4942bb98b17bdd42
F test/btree.test 08e4093c78d2bc1d54e27266f8d17fed14751125
F test/btree2.test aa4a6d05b1ea90b1acaf83ba89039dd302a88635
F test/btree4.test 3797b4305694c7af6828675b0f4b1424b8ca30e4
F test/btree5.test 8e5ff32c02e685d36516c6499add9375fe1377f2
F test/btree6.test a5ede6bfbbb2ec8b27e62813612c0f28e8f3e027
F test/capi2.test 8fb64e8ab7f78b8254cd4d04bb96822167f731b2
-F test/capi3.test f207b48dfdedae3ffef715afc0e4fe268eb6af71
+F test/capi3.test 4ac3a6c5f73317afc3fe1c183f715b20095264b4
F test/conflict.test 0911bb2f079046914a6e9c3341b36658c4e2103e
F test/copy.test f07ea8d60878da7a67416ab62f78e9706b9d3c45
F test/crashtest1.c 09c1c7d728ccf4feb9e481671e29dda5669bbcc2
F www/tclsqlite.tcl b9271d44dcf147a93c98f8ecf28c927307abd6da
F www/vdbe.tcl 9b9095d4495f37697fd1935d10e14c6015e80aa1
F www/whentouse.tcl a8335bce47cc2fddb07f19052cb0cb4d9129a8e4
-P dbdd1a7f316e576d0611748ec63c9ef00d4c10db
-R b31d420b5a3ee4ab74bd71f733217eb1
-U drh
-Z 9c2574737dba2ee53b82558a62ddf903
+P f33d15d95f195e26e1ef396158597a2caa06f374
+R 4eac96782e19eea7402fcc99da6a8349
+U danielk1977
+Z b27cf317a49b62f4bb1221f66ee3bfcf
-f33d15d95f195e26e1ef396158597a2caa06f374
\ No newline at end of file
+67a140cf78d99e38ccd94751c4f8ead1a2b96859
\ No newline at end of file
** This file contains routines used for analyzing expressions and
** for generating VDBE code that evaluates expressions in SQLite.
**
-** $Id: expr.c,v 1.129 2004/05/27 03:12:54 drh Exp $
+** $Id: expr.c,v 1.130 2004/05/27 09:28:42 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
return 0;
case TK_NULL:
case TK_STRING:
+ case TK_BLOB:
case TK_INTEGER:
case TK_FLOAT:
case TK_VARIABLE:
while( p ) switch( p->op ){
case TK_CONCAT:
case TK_STRING:
+ case TK_BLOB:
return SQLITE_AFF_TEXT;
case TK_AS:
case TK_REM: op = OP_Remainder; break;
case TK_FLOAT: op = OP_Real; break;
case TK_STRING: op = OP_String; break;
+ case TK_BLOB: op = OP_HexBlob; break;
default: break;
}
switch( pExpr->op ){
sqlite3VdbeDequoteP3(v, -1);
break;
}
+ case TK_BLOB: {
+ sqlite3VdbeOp3(v, op, 0, 0, pExpr->token.z+1, pExpr->token.n-1);
+ sqlite3VdbeDequoteP3(v, -1);
+ break;
+ }
case TK_NULL: {
sqlite3VdbeAddOp(v, OP_String, 0, 0);
break;
** sqliteRegisterBuildinFunctions() found at the bottom of the file.
** All other code has file scope.
**
-** $Id: func.c,v 1.59 2004/05/27 03:12:55 drh Exp $
+** $Id: func.c,v 1.60 2004/05/27 09:28:42 danielk1977 Exp $
*/
#include <ctype.h>
#include <math.h>
if( argc==0 ) return;
mask = (int)sqlite3_user_data(context);
+ assert( mask==-1 || mask==0 );
iBest = 0;
for(i=1; i<argc; i++){
- if( (sqlite3MemCompare(argv[iBest], argv[i], 0)^mask)<0 ){
+ if( (sqlite3MemCompare(argv[iBest], argv[i], 0)^mask)>=0 ){
iBest = i;
}
}
char *z;
int i;
if( argc<1 || SQLITE3_NULL==sqlite3_value_type(argv[0]) ) return;
- z = sqliteMalloc(sqlite3_value_bytes(argv[0]));
+ z = sqliteMalloc(sqlite3_value_bytes(argv[0])+1);
if( z==0 ) return;
strcpy(z, sqlite3_value_text(argv[0]));
for(i=0; z[i]; i++){
char *z;
int i;
if( argc<1 || SQLITE3_NULL==sqlite3_value_type(argv[0]) ) return;
- z = sqliteMalloc(sqlite3_value_bytes(argv[0]));
+ z = sqliteMalloc(sqlite3_value_bytes(argv[0])+1);
if( z==0 ) return;
strcpy(z, sqlite3_value_text(argv[0]));
for(i=0; z[i]; i++){
int i;
for(i=0; i<sizeof(aFuncs)/sizeof(aFuncs[0]); i++){
- void *pArg = aFuncs[i].argType==2 ? (void*)(-1) : db;
+ void *pArg = 0;
+ switch( aFuncs[i].argType ){
+ case 1: pArg = db; break;
+ case 2: pArg = (void *)(-1); break;
+ }
sqlite3_create_function(db, aFuncs[i].zName, aFuncs[i].nArg, 0, 0,
pArg, aFuncs[i].xFunc, 0, 0);
}
for(i=0; i<sizeof(aAggs)/sizeof(aAggs[0]); i++){
- void *pArg = aAggs[i].argType==2 ? (void*)(-1) : db;
+ void *pArg = 0;
+ switch( aAggs[i].argType ){
+ case 1: pArg = db; break;
+ case 2: pArg = (void *)(-1); break;
+ }
sqlite3_create_function(db, aAggs[i].zName, aAggs[i].nArg, 0, 0, pArg,
0, aAggs[i].xStep, aAggs[i].xFinalize);
}
** the parser. Lemon will also generate a header file containing
** numeric codes for all of the tokens.
**
-** @(#) $Id: parse.y,v 1.117 2004/05/20 23:37:55 drh Exp $
+** @(#) $Id: parse.y,v 1.118 2004/05/27 09:28:43 danielk1977 Exp $
*/
%token_prefix TK_
%token_type {Token}
expr(A) ::= INTEGER(X). {A = sqlite3Expr(TK_INTEGER, 0, 0, &X);}
expr(A) ::= FLOAT(X). {A = sqlite3Expr(TK_FLOAT, 0, 0, &X);}
expr(A) ::= STRING(X). {A = sqlite3Expr(TK_STRING, 0, 0, &X);}
+expr(A) ::= BLOB(X). {A = sqlite3Expr(TK_BLOB, 0, 0, &X);}
expr(A) ::= VARIABLE(X). {
A = sqlite3Expr(TK_VARIABLE, 0, 0, &X);
if( A ) A->iTable = ++pParse->nVar;
** This header file defines the interface that the SQLite library
** presents to client programs.
**
-** @(#) $Id: sqlite.h.in,v 1.83 2004/05/27 03:12:55 drh Exp $
+** @(#) $Id: sqlite.h.in,v 1.84 2004/05/27 09:28:43 danielk1977 Exp $
*/
#ifndef _SQLITE_H_
#define _SQLITE_H_
char *sqlite3_vmprintf(const char*, va_list);
void sqlite3_free(char *z);
+void sqlite3_freemem(void *z);
+
/*
** Windows systems need functions to call to return the sqlite3_version
** and sqlite3_encoding strings.
** is not included in the SQLite library. It is used for automated
** testing of the SQLite library.
**
-** $Id: test1.c,v 1.61 2004/05/27 01:49:51 danielk1977 Exp $
+** $Id: test1.c,v 1.62 2004/05/27 09:28:43 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"
# define PTR_FMT "%p"
#endif
+int sqlite3_exec_printf(
+ sqlite *db, /* An open database */
+ const char *sqlFormat, /* printf-style format string for the SQL */
+ sqlite_callback xCallback, /* Callback function */
+ void *pArg, /* 1st argument to callback function */
+ char **errmsg, /* Error msg written here */
+ ... /* Arguments to the format string. */
+);
+int sqlite3_exec_printf(
+ sqlite *db, /* An open database */
+ const char *sqlFormat, /* printf-style format string for the SQL */
+ sqlite_callback xCallback, /* Callback function */
+ void *pArg, /* 1st argument to callback function */
+ char **errmsg, /* Error msg written here */
+ ... /* Arguments to the format string. */
+);
+int sqlite3_get_table_printf(
+ sqlite *db, /* 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 *ncol, /* Number of result columns written here */
+ char **errmsg, /* Error msg written here */
+ ... /* Arguments to the format string */
+);
+
static const char * errorName(int rc){
const char *zName = 0;
switch( rc ){
return TCL_ERROR;
}
if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
- sprintf(zBuf, "%d", sqlite3_last_insert_rowid(db));
+ sprintf(zBuf, "%lld", sqlite3_last_insert_rowid(db));
Tcl_AppendResult(interp, zBuf, 0);
return SQLITE_OK;
}
static void countFinalize(sqlite3_context *context){
CountCtx *p;
p = sqlite3_aggregate_context(context, sizeof(*p));
- sqlite3_result_int32(context, p ? p->n : 0);
+ sqlite3_result_int(context, p ? p->n : 0);
}
/*
sqlite3_result_error(context, "2nd argument may not be NULL if the "
"first argument is not \"string\"", -1);
}else if( sqlite3StrICmp(zArg0,"int")==0 ){
- sqlite3_result_int32(context, atoi(zArg1));
+ sqlite3_result_int(context, atoi(zArg1));
}else if( sqlite3StrICmp(zArg0,"double")==0 ){
sqlite3_result_double(context, sqlite3AtoF(zArg1, 0));
}else{
if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR;
if( Tcl_GetIntFromObj(interp, objv[3], &value) ) return TCL_ERROR;
- rc = sqlite3_bind_int32(pStmt, idx, value);
+ rc = sqlite3_bind_int(pStmt, idx, value);
if( rc!=SQLITE_OK ){
return TCL_ERROR;
}
int col;
int len;
- void *pBlob;
+ const void *pBlob;
if( objc!=3 ){
Tcl_AppendResult(interp, "wrong # args: should be \"",
if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR;
rVal = sqlite3_column_double(pStmt, col);
- Tcl_SetObjResult(interp, Tcl_NewDoubleObj(iVal));
+ Tcl_SetObjResult(interp, Tcl_NewDoubleObj(rVal));
return TCL_OK;
}
){
sqlite3_stmt *pStmt;
int col;
- const char *(xFunc *)(sqlite3_stmt*, int) = clientData;
+ const char *(*xFunc)(sqlite3_stmt*, int) = clientData;
if( objc!=3 ){
Tcl_AppendResult(interp, "wrong # args: should be \"",
int col;
Tcl_Obj *pRet;
const void *zName16;
- const void *(xFunc *)(sqlite3_stmt*, int) = clientData;
+ const void *(*xFunc)(sqlite3_stmt*, int) = clientData;
if( objc!=3 ){
Tcl_AppendResult(interp, "wrong # args: should be \"",
){
sqlite3_stmt *pStmt;
int col;
- int (xFunc *)(sqlite3_stmt*, int) = clientData;
+ int (*xFunc)(sqlite3_stmt*, int) = clientData;
if( objc!=3 ){
Tcl_AppendResult(interp, "wrong # args: should be \"",
Tcl_CreateCommand(interp, aCmd[i].zName, aCmd[i].xProc, 0, 0);
}
for(i=0; i<sizeof(aObjCmd)/sizeof(aObjCmd[0]); i++){
- Tcl_CreateObjCommand(interp, aObjCmd[i].zName, aObjCmd[i].xProc, 0, 0);
+ Tcl_CreateObjCommand(interp, aObjCmd[i].zName,
+ aObjCmd[i].xProc, aObjCmd[i].clientData, 0);
}
Tcl_LinkVar(interp, "sqlite_search_count",
(char*)&sqlite3_search_count, TCL_LINK_INT);
** individual tokens and sends those tokens one-by-one over to the
** parser for analysis.
**
-** $Id: tokenize.c,v 1.70 2004/05/10 10:34:53 danielk1977 Exp $
+** $Id: tokenize.c,v 1.71 2004/05/27 09:28:43 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "os.h"
*tokenType = TK_VARIABLE;
return 1;
}
+ case 'x': case 'X': {
+ if( z[1]=='\'' || z[1]=='"' ){
+ int delim = z[0];
+ for(i=1; z[i]; i++){
+ if( z[i]==delim ){
+ break;
+ }
+ }
+ if( z[i] ) i++;
+ *tokenType = TK_BLOB;
+ return i;
+ }
+ /* Otherwise fall through to the next case */
+ }
default: {
if( (*z&0x80)==0 && !isIdChar[*z] ){
break;
** This file contains routines used to translate between UTF-8,
** UTF-16, UTF-16BE, and UTF-16LE.
**
-** $Id: utf.c,v 1.11 2004/05/27 01:53:56 drh Exp $
+** $Id: utf.c,v 1.12 2004/05/27 09:28:43 danielk1977 Exp $
**
** Notes on UTF-8:
**
*zOut = sqlite3utf8to16be(zData, nData);
}
if( !(*zOut) ) return SQLITE_NOMEM;
- *nOut = sqlite3utf16ByteLen(*zOut, -1)+2;
+ *nOut = sqlite3utf16ByteLen(*zOut, -1);
}else{
*zOut = sqlite3utf16to8(zData, nData, enc1==TEXT_Utf16be);
if( !(*zOut) ) return SQLITE_NOMEM;
- *nOut = strlen(*zOut)+1;
+ *nOut = strlen(*zOut);
}
return SQLITE_OK;
}
** This file contains functions for allocating memory, comparing
** strings, and stuff like that.
**
-** $Id: util.c,v 1.90 2004/05/27 03:12:55 drh Exp $
+** $Id: util.c,v 1.91 2004/05/27 09:28:43 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include <stdarg.h>
}while( v!=0 && i<9 );
return i;
}
+
+char * sqlite3HexToBlob(const char *z){
+ char *zBlob;
+ int i;
+ int n = strlen(z);
+ if( n%2 ) return 0;
+
+ zBlob = (char *)sqliteMalloc(n/2);
+
+ for(i=0; i<n; i+=2){
+ u8 c;
+
+ if ( z[i]>47 && z[i]<58 ) c = (z[i]-48)<<4;
+ else if( z[i]>64 && z[i]<71 ) c = (z[i]-55)<<4;
+ else if( z[i]>96 && z[i]<103 ) c = (z[i]-87)<<4;
+ else {
+ sqliteFree(zBlob);
+ return 0;
+ }
+ if ( z[i]>47 && z[i]<58 ) c += (z[i]-48);
+ else if( z[i]>64 && z[i]<71 ) c += (z[i]-55);
+ else if( z[i]>96 && z[i]<103 ) c += (z[i]-87);
+ else {
+ sqliteFree(zBlob);
+ return 0;
+ }
+
+ zBlob[i/2] = c;
+ }
+}
+
+
+
+
** 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.338 2004/05/27 03:12:55 drh Exp $
+** $Id: vdbe.c,v 1.339 2004/05/27 09:28:43 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#define Realify(P,enc) \
if(((P)->flags&MEM_Real)==0){ sqlite3VdbeMemRealify(P); }
+/*
+** Argument pMem points at a memory cell that will be passed to a
+** user-defined function or returned to the user as the result of a query.
+** The second argument, 'db_enc' is the text encoding used by the vdbe for
+** stack variables. This routine sets the pMem->enc and pMem->type
+** variables used by the sqlite3_value_*() routines.
+*/
+static void StoreTypeInfo(Mem *pMem, u8 db_enc){
+ int flags = pMem->flags;
+ if( flags & MEM_Null ){
+ pMem->type = SQLITE3_NULL;
+ }
+ else if( flags & MEM_Int ){
+ pMem->type = SQLITE3_INTEGER;
+ }
+ else if( flags & MEM_Real ){
+ pMem->type = SQLITE3_FLOAT;
+ }
+ else if( flags & MEM_Str ){
+ pMem->type = SQLITE3_TEXT;
+ }else{
+ pMem->type = SQLITE3_BLOB;
+ }
+}
/*
** Insert a new aggregate element and make it the element that
** it looks like a number.
*/
int realnum;
+ sqlite3VdbeMemNulTerminate(pRec);
if( pRec->flags&MEM_Str && sqlite3IsNumber(pRec->z, &realnum, enc) ){
if( realnum ){
Realify(pRec, enc);
if( affinity==SQLITE_AFF_INTEGER ){
/* For INTEGER affinity, try to convert a real value to an int */
- if( pRec->flags&MEM_Real ){
+ if( (pRec->flags&MEM_Real) && !(pRec->flags&MEM_Int) ){
pRec->i = pRec->r;
if( ((double)pRec->i)==pRec->r ){
pRec->flags |= MEM_Int;
*/
case OP_String: {
pTos++;
- pTos->flags = MEM_Str|MEM_Static|MEM_Term;
- pTos->enc = TEXT_Utf8;
- pTos->z = pOp->p3;
- pTos->n = strlen(pTos->z);
- sqlite3VdbeChangeEncoding(pTos, db->enc);
+ if( pOp->p3 ){
+ pTos->flags = MEM_Str|MEM_Static|MEM_Term;
+ pTos->enc = TEXT_Utf8;
+ pTos->z = pOp->p3;
+ pTos->n = strlen(pTos->z);
+ sqlite3VdbeChangeEncoding(pTos, db->enc);
+ }else{
+ pTos->flags = MEM_Null;
+ }
+ break;
+}
+
+#if 0
+/* Opcode: HexBlob * * P3
+**
+** This opcode does not exist at vdbe execution time.
+*/
+case OP_HexBlob: {
+ break;
+}
+#endif
+
+/* Opcode: Blob P1 * P3
+**
+** P3 points to a blob of data P1 bytes long. Push this
+** value onto the stack.
+*/
+case OP_Blob: {
+ pTos++;
+ sqlite3VdbeMemSetStr(pTos, pOp->p3, pOp->p1, 0, 0);
break;
}
for(i=0; i<pOp->p1; i++){
Mem *pVal = &pTos[0-i];
sqlite3VdbeMemNulTerminate(pVal);
+ StoreTypeInfo(pVal, db->enc);
}
p->resOnStack = 1;
sqlite3VdbeChangeEncoding(&mSep, db->enc);
}else{
mSep.flags = MEM_Null;
+ mSep.n = 0;
}
/* Loop through the stack elements to see how long the result will be. */
}
zNew[j] = 0;
zNew[j+1] = 0;
- assert( j==nByte-1 );
+ assert( j==nByte );
if( pOp->p2==0 ){
popStack(&pTos, nField);
pArg = &pTos[1-n];
for(i=0; i<n; i++, pArg++){
apVal[i] = pArg;
+ StoreTypeInfo(pArg, db->enc);
}
ctx.pFunc = (FuncDef*)pOp->p3;
Mem *pNos = &pTos[-1];
Sorter *pSorter;
assert( pNos>=p->aStack );
+ Stringify(pNos, db->enc);
if( Dynamicify(pTos, db->enc) || Dynamicify(pNos, db->enc) ) goto no_mem;
pSorter = sqliteMallocRaw( sizeof(Sorter) );
if( pSorter==0 ) goto no_mem;
** from the input file.
*/
case OP_FileColumn: {
-#if 0 /* Will be deleting this soon */
+/*
+** FIX ME: This will be deleted, but loads of test case files have
+** to be updated first...
+*/
int i = pOp->p1;
char *z;
assert( i>=0 && i<p->nField );
}
pTos++;
if( z ){
- pTos->n = strlen(z) + 1;
+ pTos->n = strlen(z);
pTos->z = z;
pTos->flags = MEM_Str | MEM_Ephem | MEM_Term;
+ pTos->enc = TEXT_Utf8;
+ sqlite3VdbeChangeEncoding(pTos, db->enc);
}else{
pTos->flags = MEM_Null;
}
-#endif
break;
}
assert( apVal || n==0 );
for(i=0; i<n; i++, pRec++){
- apVal[i] = pRec;
+ apVal[i] = pRec;
+ StoreTypeInfo(pRec, db->enc);
}
i = pTos->i;
assert( i>=0 && i<p->agg.nMem );
#ifndef NDEBUG
/* Sanity checking on the top element of the stack */
if( pTos>=p->aStack ){
- assert( pTos->flags!=0 ); /* Must define some type */
- if( pTos->flags & (MEM_Str|MEM_Blob) ){
- int x = pTos->flags & (MEM_Static|MEM_Dyn|MEM_Ephem|MEM_Short);
- assert( x!=0 ); /* Strings must define a string subtype */
- assert( (x & (x-1))==0 ); /* Only one string subtype can be defined */
- assert( pTos->z!=0 ); /* Strings must have a value */
- /* Mem.z points to Mem.zShort iff the subtype is MEM_Short */
- assert( (pTos->flags & MEM_Short)==0 || pTos->z==pTos->zShort );
- assert( (pTos->flags & MEM_Short)!=0 || pTos->z!=pTos->zShort );
- assert( (pTos->flags & MEM_Term)==0 || (pTos->flags & MEM_Str)==0
- || db->enc!=TEXT_Utf8 || strlen(pTos->z)==pTos->n );
- }else{
- /* Cannot define a string subtype for non-string objects */
- assert( (pTos->flags & (MEM_Static|MEM_Dyn|MEM_Ephem|MEM_Short))==0 );
- }
- /* MEM_Null excludes all other types */
- assert( (pTos->flags&(MEM_Str|MEM_Int|MEM_Real|MEM_Blob))==0
- || (pTos->flags&MEM_Null)==0 );
+ sqlite3VdbeMemSanity(pTos, db->enc);
}
if( pc<-1 || pc>=p->nOp ){
sqlite3SetString(&p->zErrMsg, "jump destination out of range", (char*)0);
int sqlite3VdbeMemStringify(Mem*, int);
int sqlite3VdbeMemIntegerify(Mem*);
int sqlite3VdbeMemRealify(Mem*);
+#ifndef NDEBUG
+void sqlite3VdbeMemSanity(Mem*, u8);
+#endif
+
}
int sqlite3_value_type(sqlite3_value* pVal){
return pVal->type;
-#if 0
- 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);
-#endif
}
/**************************** sqlite3_result_ *******************************
** The following routines are used to access elements of the current row
** in the result set.
*/
+const void *sqlite3_column_blob(sqlite3_stmt *pStmt, int i){
+ return sqlite3_value_blob( columnMem(pStmt,i) );
+}
int sqlite3_column_bytes(sqlite3_stmt *pStmt, int i){
return sqlite3_value_bytes( columnMem(pStmt,i) );
}
return rc;
}
+/*
+** If pOp is an OP_HexBlob opcode, then transform it to an OP_Blob
+** opcode.
+*/
+static int translateOp(Op *pOp){
+ if( pOp->opcode==OP_HexBlob ){
+ char *zBlob = sqlite3HexToBlob(pOp->p3);
+ if( !zBlob ){
+ if( sqlite3_malloc_failed ){
+ return SQLITE_NOMEM;
+ }
+ return SQLITE_ERROR;
+ }
+ pOp->p1 = strlen(pOp->p3)/2;
+ if( pOp->p3type==P3_DYNAMIC ){
+ sqliteFree(pOp->p3);
+ }
+ pOp->p3 = zBlob;
+ pOp->p3type = P3_DYNAMIC;
+ }
+}
+
/*
** Prepare a virtual machine for execution. This involves things such
** as allocating stack space and initializing the program counter.
}
}
#endif
+ {
+ int i;
+ for(i=0; i<p->nOp; i++){
+ translateOp(&p->aOp[i]);
+ }
+ }
}
/* String or blob */
assert( serial_type>=12 );
len = sqlite3VdbeSerialTypeLen(serial_type);
+ pMem->z = buf;
+ pMem->n = len;
if( serial_type&0x01 ){
pMem->flags = MEM_Str | MEM_Ephem;
- pMem->n = len;
+ pMem->enc = enc;
}else{
pMem->flags = MEM_Blob | MEM_Ephem;
- pMem->n = len;
}
sqlite3VdbeMemMakeWriteable(pMem);
return len;
** Return SQLITE_OK on success or SQLITE_NOMEM if malloc fails.
*/
int sqlite3VdbeMemDynamicify(Mem *pMem){
- int n;
+ int n = pMem->n;
u8 *z;
if( (pMem->flags & (MEM_Ephem|MEM_Static|MEM_Short))==0 ){
return SQLITE_OK;
*/
static void releaseMem(Mem *p){
if( p->flags & MEM_Dyn ){
- sqliteFree(p);
+ sqliteFree(p->z);
+ p->z = 0;
}
}
*/
int sqlite3VdbeMemRealify(Mem *pMem){
if( pMem->flags & MEM_Int ){
- pMem->r = pMem->r;
+ pMem->r = pMem->i;
pMem->flags |= MEM_Real;
}else if( pMem->flags & (MEM_Str|MEM_Blob) ){
if( sqlite3VdbeChangeEncoding(pMem, TEXT_Utf8)
}
return rc;
}
+
+#ifndef NDEBUG
+/*
+** Perform various checks on the memory cell pMem. An assert() will
+** fail if pMem is internally inconsistent.
+*/
+void sqlite3VdbeMemSanity(Mem *pMem, u8 db_enc){
+ int flags = pMem->flags;
+ assert( flags!=0 ); /* Must define some type */
+ if( pMem->flags & (MEM_Str|MEM_Blob) ){
+ int x = pMem->flags & (MEM_Static|MEM_Dyn|MEM_Ephem|MEM_Short);
+ assert( x!=0 ); /* Strings must define a string subtype */
+ assert( (x & (x-1))==0 ); /* Only one string subtype can be defined */
+ assert( pMem->z!=0 ); /* Strings must have a value */
+ /* Mem.z points to Mem.zShort iff the subtype is MEM_Short */
+ assert( (pMem->flags & MEM_Short)==0 || pMem->z==pMem->zShort );
+ assert( (pMem->flags & MEM_Short)!=0 || pMem->z!=pMem->zShort );
+
+ if( (flags & MEM_Str) ){
+ assert( pMem->enc==TEXT_Utf8 ||
+ pMem->enc==TEXT_Utf16le ||
+ pMem->enc==TEXT_Utf16be
+ );
+ /* If the string is UTF-8 encoded and nul terminated, then pMem->n
+ ** must be the length of the string.
+ */
+ if( pMem->enc==TEXT_Utf8 && (flags & MEM_Term) ){
+ assert( strlen(pMem->z)==pMem->n );
+ }
+ }
+ }else{
+ /* Cannot define a string subtype for non-string objects */
+ assert( (pMem->flags & (MEM_Static|MEM_Dyn|MEM_Ephem|MEM_Short))==0 );
+ }
+ /* MEM_Null excludes all other types */
+ assert( (pMem->flags&(MEM_Str|MEM_Int|MEM_Real|MEM_Blob))==0
+ || (pMem->flags&MEM_Null)==0 );
+}
+#endif
+
# This file implements regression tests for SQLite library. The
# focus of this script testing the sqlite_bind API.
#
-# $Id: bind.test,v 1.10 2004/05/27 01:53:56 drh Exp $
+# $Id: bind.test,v 1.11 2004/05/27 09:28:44 danielk1977 Exp $
#
set testdir [file dirname $argv0]
# UTF-8 text
do_test bind-6.1 {
sqlite3_bind_text $VM 1 hellothere 5
- sqlite3_bind_text $VM 2 "." 2
+ sqlite3_bind_text $VM 2 ".." 1
sqlite3_bind_text $VM 3 world -1
sqlite_step $VM N VALUES COLNAMES
sqlite3_reset $VM
# This file implements regression tests for SQLite library. The
# focus of this script testing the callback-free C/C++ API.
#
-# $Id: capi3.test,v 1.7 2004/05/27 01:49:51 danielk1977 Exp $
+# $Id: capi3.test,v 1.8 2004/05/27 09:28:44 danielk1977 Exp $
#
set testdir [file dirname $argv0]
do_test capi3-4.4 {
utf8 [sqlite3_errmsg16 $db2]
} {unable to open database file}
-do_test capi3-4.4 {
+do_test capi3-4.5 {
sqlite3_close $db2
} {}
# set STMT [sqlite3_prepare "SELECT 1, 2, 2;" -1 DUMMY]
# check_header test1.1 {1 2 3} {"" "" ""}
#
-proc check_header {STMT test names decltypes} }
+proc check_header {STMT test names decltypes} {
# Use the return value of sqlite3_column_count() to build
# a list of column indexes. i.e. If sqlite3_column_count
# is 3, build the list {0 1 2}.
- set idxlist [list]
+ set ::idxlist [list]
set numcols [sqlite3_column_count $STMT]
- for {set i 0} {$i < $numcols} {incr i} {lappend idxlist $i}
+ for {set i 0} {$i < $numcols} {incr i} {lappend ::idxlist $i}
# Column names in UTF-8
do_test $test.1 {
# Use the return value of sqlite3_column_count() to build
# a list of column indexes. i.e. If sqlite3_column_count
# is 3, build the list {0 1 2}.
- set idxlist [list]
+ set ::idxlist [list]
set numcols [sqlite3_data_count $STMT]
- for {set i 0} {$i < $numcols} {incr i} {lappend idxlist $i}
+ for {set i 0} {$i < $numcols} {incr i} {lappend ::idxlist $i}
# types
do_test $test.1 {
CREATE TABLE t1(a VARINT, b BLOB, c VARCHAR(16));
INSERT INTO t1 VALUES(1, 2, 3);
INSERT INTO t1 VALUES('one', 'two', NULL);
+ INSERT INTO t1 VALUES(1.2, 1.3, 1.4);
}
set sql "SELECT * FROM t1"
set STMT [sqlite3_prepare $DB $sql -1 TAIL]
do_test capi3-5.8 {
sqlite3_step $STMT
+} SQLITE_ROW
+
+check_header $STMT capi3-5.9 {a b c} {VARIANT BLOB VARCHAR(16)}
+check_data $STMT capi3-5.10 {REAL REAL TEXT} {1 1 1} {1.2 1.3 1.4} {1.2 1.3 1.4}
+
+do_test capi3-5.11 {
+ sqlite3_step $STMT
} SQLITE_DONE
-do_test capi3-5.9 {
+do_test capi3-5.12 {
sqlite3_finalize $STMT
} SQLITE_OK