diff --git a/manifest b/manifest index e261002aac..b333d406e1 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -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 @@ -31,8 +31,8 @@ F src/copy.c 6eb7cc08ae6dc60bf83ecadf4508a0bef909dbd2 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 @@ -49,33 +49,33 @@ F src/os_win.c 92b51a38437b98d8aa3ac05b57c71e1d1092e5be 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 @@ -83,14 +83,14 @@ F test/attach2.test 5472d442bb2ef1ee587e0ae7472bb68b52509a38 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 @@ -205,7 +205,7 @@ F www/sqlite.tcl 3c83b08cf9f18aa2d69453ff441a36c40e431604 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 diff --git a/manifest.uuid b/manifest.uuid index 58c5fee64c..9b982b3ef2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f33d15d95f195e26e1ef396158597a2caa06f374 \ No newline at end of file +67a140cf78d99e38ccd94751c4f8ead1a2b96859 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 2058e8acd5..20cd58f49d 100644 --- a/src/expr.c +++ b/src/expr.c @@ -12,7 +12,7 @@ ** 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 @@ -423,6 +423,7 @@ int sqlite3ExprIsConstant(Expr *p){ return 0; case TK_NULL: case TK_STRING: + case TK_BLOB: case TK_INTEGER: case TK_FLOAT: case TK_VARIABLE: @@ -1039,6 +1040,7 @@ int sqlite3ExprType(Expr *p){ while( p ) switch( p->op ){ case TK_CONCAT: case TK_STRING: + case TK_BLOB: return SQLITE_AFF_TEXT; case TK_AS: @@ -1105,6 +1107,7 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){ 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 ){ @@ -1128,6 +1131,11 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){ 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; diff --git a/src/func.c b/src/func.c index 6ab0829422..31dd1f2fef 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.59 2004/05/27 03:12:55 drh Exp $ +** $Id: func.c,v 1.60 2004/05/27 09:28:42 danielk1977 Exp $ */ #include #include @@ -40,9 +40,10 @@ static void minmaxFunc( if( argc==0 ) return; mask = (int)sqlite3_user_data(context); + assert( mask==-1 || mask==0 ); iBest = 0; for(i=1; i=0 ){ iBest = i; } } @@ -190,7 +191,7 @@ static void upperFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ 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++){ @@ -203,7 +204,7 @@ static void lowerFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ 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++){ @@ -690,12 +691,20 @@ void sqlite3RegisterBuiltinFunctions(sqlite *db){ int i; for(i=0; iiTable = ++pParse->nVar; diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 9068c2790f..72b2b3d5ad 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.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_ @@ -373,6 +373,8 @@ char *sqlite3_mprintf(const char*,...); 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. diff --git a/src/test1.c b/src/test1.c index 42116532a2..095e5b2763 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.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" @@ -27,6 +27,32 @@ # 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 ){ @@ -265,7 +291,7 @@ static int test_last_rowid( 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; } @@ -431,7 +457,7 @@ static void countStep(sqlite3_context *context, int argc, sqlite3_value **argv){ 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); } /* @@ -656,7 +682,7 @@ static void testFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ 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{ @@ -855,7 +881,7 @@ static int test_bind_int32( 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; } @@ -1431,7 +1457,7 @@ static int test_column_blob( int col; int len; - void *pBlob; + const void *pBlob; if( objc!=3 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", @@ -1473,7 +1499,7 @@ static int test_column_double( 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; } @@ -1558,7 +1584,7 @@ static int test_stmt_utf8( ){ 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 \"", @@ -1589,7 +1615,7 @@ static int test_stmt_utf16( 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 \"", @@ -1623,7 +1649,7 @@ static int test_stmt_int( ){ 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 \"", @@ -1721,7 +1747,8 @@ int Sqlitetest1_Init(Tcl_Interp *interp){ Tcl_CreateCommand(interp, aCmd[i].zName, aCmd[i].xProc, 0, 0); } for(i=0; i @@ -1298,3 +1298,37 @@ int sqlite3VarintLen(u64 v){ }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; i47 && 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; + } +} + + + + diff --git a/src/vdbe.c b/src/vdbe.c index 4d60260946..42a2266b0e 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.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" @@ -127,6 +127,30 @@ int sqlite3_interrupt_count = 0; #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 @@ -284,6 +308,7 @@ static void applyAffinity(Mem *pRec, char affinity, u8 enc){ ** it looks like a number. */ int realnum; + sqlite3VdbeMemNulTerminate(pRec); if( pRec->flags&MEM_Str && sqlite3IsNumber(pRec->z, &realnum, enc) ){ if( realnum ){ Realify(pRec, enc); @@ -295,7 +320,7 @@ static void applyAffinity(Mem *pRec, char affinity, u8 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; @@ -762,11 +787,36 @@ case OP_Real: { */ 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; } @@ -985,6 +1035,7 @@ case OP_Callback: { for(i=0; ip1; i++){ Mem *pVal = &pTos[0-i]; sqlite3VdbeMemNulTerminate(pVal); + StoreTypeInfo(pVal, db->enc); } p->resOnStack = 1; @@ -1027,6 +1078,7 @@ case OP_Concat: { 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. */ @@ -1073,7 +1125,7 @@ case OP_Concat: { } zNew[j] = 0; zNew[j+1] = 0; - assert( j==nByte-1 ); + assert( j==nByte ); if( pOp->p2==0 ){ popStack(&pTos, nField); @@ -1231,6 +1283,7 @@ case OP_Function: { pArg = &pTos[1-n]; for(i=0; ienc); } ctx.pFunc = (FuncDef*)pOp->p3; @@ -4107,6 +4160,7 @@ case OP_SortPut: { 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; @@ -4346,7 +4400,10 @@ fileread_jump: ** 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 && inField ); @@ -4357,13 +4414,14 @@ case OP_FileColumn: { } 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; } @@ -4520,7 +4578,8 @@ case OP_AggFunc: { assert( apVal || n==0 ); for(i=0; ienc); } i = pTos->i; assert( i>=0 && iagg.nMem ); @@ -4728,24 +4787,7 @@ default: { #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); diff --git a/src/vdbeInt.h b/src/vdbeInt.h index 1c0a680b66..c0c99b12aa 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -364,3 +364,7 @@ int sqlite3VdbeMemDynamicify(Mem*); int sqlite3VdbeMemStringify(Mem*, int); int sqlite3VdbeMemIntegerify(Mem*); int sqlite3VdbeMemRealify(Mem*); +#ifndef NDEBUG +void sqlite3VdbeMemSanity(Mem*, u8); +#endif + diff --git a/src/vdbeapi.c b/src/vdbeapi.c index bd34f942d3..167178af34 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -95,25 +95,6 @@ const void *sqlite3_value_text16(sqlite3_value* pVal){ } 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_ ******************************* @@ -286,6 +267,9 @@ static Mem *columnMem(sqlite3_stmt *pStmt, int i){ ** 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) ); } diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 8c16d5836b..56155d9037 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -606,6 +606,28 @@ int sqlite3VdbeList( 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. @@ -677,6 +699,12 @@ void sqlite3VdbeMakeReady( } } #endif + { + int i; + for(i=0; inOp; i++){ + translateOp(&p->aOp[i]); + } + } } @@ -1270,12 +1298,13 @@ int sqlite3VdbeSerialGet( /* 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; diff --git a/src/vdbemem.c b/src/vdbemem.c index c6bb66afa4..05e304d1ec 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -82,7 +82,7 @@ int sqlite3VdbeChangeEncoding(Mem *pMem, int desiredEnc){ ** 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; @@ -199,7 +199,8 @@ int sqlite3VdbeMemStringify(Mem *pMem, int enc){ */ static void releaseMem(Mem *p){ if( p->flags & MEM_Dyn ){ - sqliteFree(p); + sqliteFree(p->z); + p->z = 0; } } @@ -235,7 +236,7 @@ int sqlite3VdbeMemIntegerify(Mem *pMem){ */ 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) @@ -444,3 +445,43 @@ int sqlite3MemCompare(const Mem *pMem1, const Mem *pMem2, const CollSeq *pColl){ } 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 + diff --git a/test/bind.test b/test/bind.test index c18e75b489..0b7eae63fe 100644 --- a/test/bind.test +++ b/test/bind.test @@ -11,7 +11,7 @@ # This file implements regression tests for SQLite library. The # focus of this script testing the sqlite_bind API. # -# $Id: bind.test,v 1.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] @@ -174,7 +174,7 @@ do_test bind-5.3 { # 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 diff --git a/test/capi3.test b/test/capi3.test index 16560e1e98..c3745e1a53 100644 --- a/test/capi3.test +++ b/test/capi3.test @@ -11,7 +11,7 @@ # This file implements regression tests for SQLite library. The # focus of this script testing the callback-free C/C++ API. # -# $Id: capi3.test,v 1.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] @@ -152,7 +152,7 @@ do_test capi3-4.3 { 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 } {} @@ -174,14 +174,14 @@ do_test capi3-4.4 { # 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 { @@ -239,9 +239,9 @@ proc check_data {STMT test types ints doubles strings} { # 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 { @@ -313,6 +313,7 @@ do_test capi3-5.0 { 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] @@ -338,9 +339,16 @@ check_data $STMT capi3-5.7 {TEXT TEXT NULL} {0 0 0} {0 0 0} {one two {}} 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