From 9339da1f224fe26ff4304f21a1bfc158fda60727 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 30 Sep 2010 00:50:49 +0000 Subject: [PATCH 1/8] Rework the text to numeric conversion routines so that they work with either UTF8 or UTF16 and do not require a NULL terminator. This allowed text to numeric conversion without reallocating the string. FossilOrigin-Name: 14eed3a0e0a45c6f2904a3a134aa27c159916f7b --- manifest | 44 ++++++++----- manifest.uuid | 2 +- src/date.c | 24 +++----- src/expr.c | 6 +- src/func.c | 2 +- src/pragma.c | 2 +- src/sqliteInt.h | 5 +- src/test1.c | 2 +- src/util.c | 160 +++++++++++++++++++++--------------------------- src/vdbe.c | 34 +++------- src/vdbemem.c | 14 ++--- 11 files changed, 134 insertions(+), 161 deletions(-) diff --git a/manifest b/manifest index 9ac8249785..39e52bb943 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,8 @@ -C Add\stest\scases\sto\se_createtable.test. -D 2010-09-29T18:26:24 +-----BEGIN PGP SIGNED MESSAGE----- +Hash: SHA1 + +C Rework\sthe\stext\sto\snumeric\sconversion\sroutines\sso\sthat\sthey\swork\swith\seither\nUTF8\sor\sUTF16\sand\sdo\snot\srequire\sa\sNULL\sterminator.\s\sThis\sallowed\stext\sto\nnumeric\sconversion\swithout\sreallocating\sthe\sstring. +D 2010-09-30T00:50:50 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in c599a15d268b1db2aeadea19df2adc3bf2eb6bee F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -125,12 +128,12 @@ F src/build.c 00a327120d81ace6267e714ae8010c997d55de5d F src/callback.c a1d1b1c9c85415dff013af033e2fed9c8382d33b F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c 4f3aadad62c6c9f0d4e5a96718516ac4e3c598df -F src/date.c 5dd8448a0bfea8d31fb14cff487d0c06ff8c8b20 +F src/date.c 1548fdac51377e4e7833251de878b4058c148e1b F src/delete.c 7ed8a8c8b5f748ece92df173d7e0f7810c899ebd -F src/expr.c 1caa723c3ab7a7e35952bc85a6f4a7da3632308f +F src/expr.c 05dbb04833ea04c28e835bf67295e367ca1c52d8 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 17950a28f28b23e8ad3feaac5fc88c324d2f600a -F src/func.c b5664982355274c264afe90efd7f694d447a594a +F src/func.c 2b7cf54d2569c2eba42fe81165d1932b546681a3 F src/global.c 02335177cf6946fe5525c6f0755cf181140debf3 F src/hash.c 458488dcc159c301b8e7686280ab209f1fb915af F src/hash.h 2894c932d84d9f892d4b4023a75e501f83050970 @@ -167,7 +170,7 @@ F src/parse.y 12b7ebd61ea54f0e1b1083ff69cc2c8ce9353d58 F src/pcache.c 09d38c44ab275db581f7a2f6ff8b9bc7f8c0faaa F src/pcache.h c683390d50f856d4cd8e24342ae62027d1bb6050 F src/pcache1.c e9578a3beac26f229ee558a4e16c863f2498185f -F src/pragma.c 8b24ce00a93de345b6c3bd1e1e2cfba9f63d2325 +F src/pragma.c 216d12e4546e65ca6cfcd3221e64573889ae8f34 F src/prepare.c ce4c35a2b1d5fe916e4a46b70d24a6e997d7c4c6 F src/printf.c 8ae5082dd38a1b5456030c3755ec3a392cd51506 F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50 @@ -177,12 +180,12 @@ F src/select.c cf3013b1953348c7c6ff9636342e87b9fda68466 F src/shell.c 8517fc1f9c59ae4007e6cc8b9af91ab231ea2056 F src/sqlite.h.in a5b50e1bc4d4d9a3cc95386747220a839d0c40f7 F src/sqlite3ext.h 69dfb8116af51b84a029cddb3b35062354270c89 -F src/sqliteInt.h ea31c7867d910c1da9b20adb6614e474011fbae0 +F src/sqliteInt.h 6fb1558f7810dc13406c7629b9ea20ec46b701e8 F src/sqliteLimit.h a17dcd3fb775d63b64a43a55c54cb282f9726f44 F src/status.c 496913d4e8441195f6f2a75b1c95993a45b9b30b F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e F src/tclsqlite.c e91019fb6787166abca23a81b16c07fecc2ed751 -F src/test1.c a0f135000894cb5a3d32d23fd74a83939ca854fa +F src/test1.c 6fbbb504a7d1069415e443ae687d61cab72fa51e F src/test2.c 80d323d11e909cf0eb1b6fbb4ac22276483bcf31 F src/test3.c 056093cfef69ff4227a6bdb9108564dc7f45e4bc F src/test4.c 0528360b5025688002a5feb6be906ddce52eaaee @@ -223,15 +226,15 @@ F src/tokenize.c 604607d6813e9551cf5189d899e0a25c12681080 F src/trigger.c b8bedb9c0084ceb51a40f54fcca2ce048c8de852 F src/update.c 227e6cd512108b84f69421fc6c7aa1b83d60d6e0 F src/utf.c 1baeeac91707a4df97ccc6141ec0f808278af685 -F src/util.c 5f5f4db4e799224713582bb49124827b16aa8e54 +F src/util.c 7a5fb16c0b9a3e4c9fa6c375c8f514bc3bb155b6 F src/vacuum.c 924bd1bcee2dfb05376f79845bd3b4cec7b54b2f -F src/vdbe.c 69812aabf486a2d6a5b0960ffd9a47d141442735 +F src/vdbe.c 04cf7c1b0b7a7dc825ddde202307ca15c1115fbb F src/vdbe.h 4de0efb4b0fdaaa900cf419b35c458933ef1c6d2 F src/vdbeInt.h 7f4cf1b2b69bef3a432b1f23dfebef57275436b4 F src/vdbeapi.c 03cddfa4f85cadf608c0d28ff6b622b7da432446 F src/vdbeaux.c de0b06b11a25293e820a49159eca9f1c51a64716 F src/vdbeblob.c 258a6010ba7a82b72b327fb24c55790655689256 -F src/vdbemem.c 8ff4f80a35d51f3690c191ec44778ef4bf949ac0 +F src/vdbemem.c cfb178242f38fb03a44672268afa05716d55e769 F src/vdbetrace.c 864cef96919323482ebd9986f2132435115e9cc2 F src/vtab.c 6c90e3e65b2f026fc54703a8f3c917155f419d87 F src/wal.c 7081f148cb52b0cf2280e6384196402dc58130a3 @@ -869,7 +872,18 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P 1ef0dc9328f47506cb2dcd142150e96cb4755216 -R 02e67e0f9fa41ba7fd1a6b2afec8e896 -U dan -Z d7addcf9b4085ef482cc086b59137f66 +P f34dc54d46d05adf1f52db51442195b3285a26b9 +R 5e9e2523f82be46cc8ebbb892165bffa +T *bgcolor * #c0ffc0 +T *branch * experimental +T *sym-experimental * +T -sym-trunk * +U drh +Z 0c6ebf88312d1668689f16e4194172bb +-----BEGIN PGP SIGNATURE----- +Version: GnuPG v1.4.6 (GNU/Linux) + +iD8DBQFMo97toxKgR168RlERAi5jAJsFDVqJu9wdOQNwlT2y3q2TNuHUGQCdFwrP +sR9IRwN4k3Y2ZVtzQE0tnsY= +=6xoC +-----END PGP SIGNATURE----- diff --git a/manifest.uuid b/manifest.uuid index 99bd7efabf..59c95200ea 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f34dc54d46d05adf1f52db51442195b3285a26b9 \ No newline at end of file +14eed3a0e0a45c6f2904a3a134aa27c159916f7b \ No newline at end of file diff --git a/src/date.c b/src/date.c index 04ffbe23ce..b81049aa65 100644 --- a/src/date.c +++ b/src/date.c @@ -133,12 +133,6 @@ end_getDigits: return cnt; } -/* -** Read text from z[] and convert into a floating point number. Return -** the number of digits converted. -*/ -#define getValue sqlite3AtoF - /* ** Parse a timezone extension on the end of a date-time. ** The extension is of the form: @@ -340,7 +334,7 @@ static int parseDateOrTime( const char *zDate, DateTime *p ){ - int isRealNum; /* Return from sqlite3IsNumber(). Not used */ + double r; if( parseYyyyMmDd(zDate,p)==0 ){ return 0; }else if( parseHhMmSs(zDate, p)==0 ){ @@ -348,9 +342,7 @@ static int parseDateOrTime( }else if( sqlite3StrICmp(zDate,"now")==0){ setDateTimeToCurrent(context, p); return 0; - }else if( sqlite3IsNumber(zDate, &isRealNum, SQLITE_UTF8) ){ - double r; - getValue(zDate, &r); + }else if( sqlite3AtoF(zDate, &r, sqlite3Strlen30(zDate), SQLITE_UTF8) ){ p->iJD = (sqlite3_int64)(r*86400000.0 + 0.5); p->validJD = 1; return 0; @@ -571,8 +563,9 @@ static int parseModifier(const char *zMod, DateTime *p){ ** weekday N where 0==Sunday, 1==Monday, and so forth. If the ** date is already on the appropriate weekday, this is a no-op. */ - if( strncmp(z, "weekday ", 8)==0 && getValue(&z[8],&r)>0 - && (n=(int)r)==r && n>=0 && r<7 ){ + if( strncmp(z, "weekday ", 8)==0 + && sqlite3AtoF(&z[8], &r, sqlite3Strlen30(&z[8]), SQLITE_UTF8) + && (n=(int)r)==r && n>=0 && r<7 ){ sqlite3_int64 Z; computeYMD_HMS(p); p->validTZ = 0; @@ -627,8 +620,11 @@ static int parseModifier(const char *zMod, DateTime *p){ case '8': case '9': { double rRounder; - n = getValue(z, &r); - assert( n>=1 ); + for(n=1; z[n] && z[n]!=':' && !sqlite3Isspace(z[n]); n++){} + if( !sqlite3AtoF(z, &r, n, SQLITE_UTF8) ){ + rc = 1; + break; + } if( z[n]==':' ){ /* A modifier of the form (+|-)HH:MM:SS.FFF adds (or subtracts) the ** specified number of hours, minutes, seconds, and fractional seconds diff --git a/src/expr.c b/src/expr.c index 2474635218..cf1823d9d8 100644 --- a/src/expr.c +++ b/src/expr.c @@ -555,7 +555,7 @@ void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr){ /* Wildcard of the form "?nnn". Convert "nnn" to an integer and ** use it as the variable number */ i64 i; - int bOk = sqlite3Atoi64(&z[1], &i); + int bOk = sqlite3Atoi64(&z[1], &i, sqlite3Strlen30(&z[1]), SQLITE_UTF8); pExpr->iColumn = (ynVar)i; testcase( i==0 ); testcase( i==1 ); @@ -1918,7 +1918,7 @@ static void codeReal(Vdbe *v, const char *z, int negateFlag, int iMem){ if( ALWAYS(z!=0) ){ double value; char *zV; - sqlite3AtoF(z, &value); + sqlite3AtoF(z, &value, sqlite3Strlen30(z), SQLITE_UTF8); assert( !sqlite3IsNaN(value) ); /* The new AtoF never returns NaN */ if( negateFlag ) value = -value; zV = dup8bytes(v, (char*)&value); @@ -1948,7 +1948,7 @@ static void codeInteger(Parse *pParse, Expr *pExpr, int negFlag, int iMem){ if( sqlite3FitsIn64Bits(z, negFlag) ){ i64 value; char *zV; - sqlite3Atoi64(z, &value); + sqlite3Atoi64(z, &value, sqlite3Strlen30(z), SQLITE_UTF8); if( negFlag ) value = -value; zV = dup8bytes(v, (char*)&value); sqlite3VdbeAddOp4(v, OP_Int64, 0, iMem, 0, zV, P4_INT64); diff --git a/src/func.c b/src/func.c index 6119e4a956..8b7086f600 100644 --- a/src/func.c +++ b/src/func.c @@ -285,7 +285,7 @@ static void roundFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ sqlite3_result_error_nomem(context); return; } - sqlite3AtoF(zBuf, &r); + sqlite3AtoF(zBuf, &r, sqlite3Strlen30(zBuf), SQLITE_UTF8); sqlite3_free(zBuf); } sqlite3_result_double(context, r); diff --git a/src/pragma.c b/src/pragma.c index 0f3ce3c524..362e77f29e 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -587,7 +587,7 @@ void sqlite3Pragma( Pager *pPager = sqlite3BtreePager(pDb->pBt); i64 iLimit = -2; if( zRight ){ - sqlite3Atoi64(zRight, &iLimit); + sqlite3Atoi64(zRight, &iLimit, 1000000, SQLITE_UTF8); if( iLimit<-1 ) iLimit = -1; } iLimit = sqlite3PagerJournalSizeLimit(pPager, iLimit); diff --git a/src/sqliteInt.h b/src/sqliteInt.h index adf6ce8a28..dd5d239438 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2507,7 +2507,6 @@ int sqlite3CantopenError(int); ** Internal function prototypes */ int sqlite3StrICmp(const char *, const char *); -int sqlite3IsNumber(const char*, int*, u8); int sqlite3Strlen30(const char*); #define sqlite3StrNICmp sqlite3_strnicmp @@ -2827,7 +2826,7 @@ int sqlite3FixSelect(DbFixer*, Select*); int sqlite3FixExpr(DbFixer*, Expr*); int sqlite3FixExprList(DbFixer*, ExprList*); int sqlite3FixTriggerStep(DbFixer*, TriggerStep*); -int sqlite3AtoF(const char *z, double*); +int sqlite3AtoF(const char *z, double*, int, u8); int sqlite3GetInt32(const char *, int*); int sqlite3FitsIn64Bits(const char *, int); int sqlite3Utf16ByteLen(const void *pData, int nChar); @@ -2875,7 +2874,7 @@ void sqlite3TableAffinityStr(Vdbe *, Table *); char sqlite3CompareAffinity(Expr *pExpr, char aff2); int sqlite3IndexAffinityOk(Expr *pExpr, char idx_affinity); char sqlite3ExprAffinity(Expr *pExpr); -int sqlite3Atoi64(const char*, i64*); +int sqlite3Atoi64(const char*, i64*, int, u8); void sqlite3Error(sqlite3*, int, const char*,...); void *sqlite3HexToBlob(sqlite3*, const char *z, int n); int sqlite3TwoPartName(Parse *, Token *, Token *, Token **); diff --git a/src/test1.c b/src/test1.c index 8e827f07ba..b83263d00b 100644 --- a/src/test1.c +++ b/src/test1.c @@ -1235,7 +1235,7 @@ static int sqlite3_mprintf_int64( return TCL_ERROR; } for(i=2; i<5; i++){ - if( !sqlite3Atoi64(argv[i], &a[i-2]) ){ + if( !sqlite3Atoi64(argv[i], &a[i-2], 1000000, SQLITE_UTF8) ){ Tcl_AppendResult(interp, "argument is not a valid 64-bit integer", 0); return TCL_ERROR; } diff --git a/src/util.c b/src/util.c index 6b30b311ae..36689ec1d3 100644 --- a/src/util.c +++ b/src/util.c @@ -238,61 +238,19 @@ int sqlite3_strnicmp(const char *zLeft, const char *zRight, int N){ } /* -** Return TRUE if z is a pure numeric string. Return FALSE and leave -** *realnum unchanged if the string contains any character which is not -** part of a number. -** -** If the string is pure numeric, set *realnum to TRUE if the string -** contains the '.' character or an "E+000" style exponentiation suffix. -** Otherwise set *realnum to FALSE. Note that just becaue *realnum is -** false does not mean that the number can be successfully converted into -** an integer - it might be too big. -** -** An empty string is considered non-numeric. -*/ -int sqlite3IsNumber(const char *z, int *realnum, u8 enc){ - int incr = (enc==SQLITE_UTF8?1:2); - if( enc==SQLITE_UTF16BE ) z++; - if( *z=='-' || *z=='+' ) z += incr; - if( !sqlite3Isdigit(*z) ){ - return 0; - } - z += incr; - *realnum = 0; - while( sqlite3Isdigit(*z) ){ z += incr; } -#ifndef SQLITE_OMIT_FLOATING_POINT - if( *z=='.' ){ - z += incr; - if( !sqlite3Isdigit(*z) ) return 0; - while( sqlite3Isdigit(*z) ){ z += incr; } - *realnum = 1; - } - if( *z=='e' || *z=='E' ){ - z += incr; - if( *z=='+' || *z=='-' ) z += incr; - if( !sqlite3Isdigit(*z) ) return 0; - while( sqlite3Isdigit(*z) ){ z += incr; } - *realnum = 1; - } -#endif - return *z==0; -} - -/* -** The string z[] is an ASCII representation of a real number. +** The string z[] is an text representation of a real number. ** Convert this string to a double. ** -** This routine assumes that z[] really is a valid number. If it -** is not, the result is undefined. +** The string z[] is length bytes in length (bytes, not characters) and +** uses the encoding enc. The string is not necessarily zero-terminated. ** -** This routine is used instead of the library atof() function because -** the library atof() might want to use "," as the decimal point instead -** of "." depending on how locale is set. But that would cause problems -** for SQL. So this routine always uses "." regardless of locale. +** Return TRUE if the result is a valid real number (or integer) and FALSE +** if the string is empty or contains extraneous text. */ -int sqlite3AtoF(const char *z, double *pResult){ +int sqlite3AtoF(const char *z, double *pResult, int length, u8 enc){ #ifndef SQLITE_OMIT_FLOATING_POINT - const char *zBegin = z; + int incr = (enc==SQLITE_UTF8?1:2); + const char *zEnd = z + length; /* sign * significand * (10 ^ (esign * exponent)) */ int sign = 1; /* sign of significand */ i64 s = 0; /* significand */ @@ -302,57 +260,70 @@ int sqlite3AtoF(const char *z, double *pResult){ double result; int nDigits = 0; + if( enc==SQLITE_UTF16BE ) z++; + /* skip leading spaces */ - while( sqlite3Isspace(*z) ) z++; + while( z=zEnd ){ + *pResult = 0.0; + return 0; + } + /* get sign of significand */ if( *z=='-' ){ sign = -1; - z++; + z+=incr; }else if( *z=='+' ){ - z++; + z+=incr; } + /* skip leading zeroes */ - while( z[0]=='0' ) z++, nDigits++; + while( z=zEnd ) goto do_atof_calc; /* if decimal point is present */ if( *z=='.' ){ - z++; + z+=incr; /* copy digits from after decimal to significand ** (decrease exponent by d to shift decimal right) */ - while( sqlite3Isdigit(*z) && s<((LARGEST_INT64-9)/10) ){ + while( z=zEnd ) goto do_atof_calc; /* if exponent is present */ if( *z=='e' || *z=='E' ){ - z++; + z+=incr; + if( z>=zEnd ) goto do_atof_calc; /* get sign of exponent */ if( *z=='-' ){ esign = -1; - z++; + z+=incr; }else if( *z=='+' ){ - z++; + z+=incr; } /* copy digits to exponent */ - while( sqlite3Isdigit(*z) ){ + while( z=zEnd && sqlite3Isdigit(z[-incr]); #else - return sqlite3Atoi64(z, pResult); + return sqlite3Atoi64(z, pResult, length, enc); #endif /* SQLITE_OMIT_FLOATING_POINT */ } @@ -427,15 +398,20 @@ int sqlite3AtoF(const char *z, double *pResult){ ** in the values of the last digit if the only difference is in the ** last digit. So, for example, ** -** compare2pow63("9223372036854775800") +** compare2pow63("9223372036854775800", 1) ** ** will return -8. */ -static int compare2pow63(const char *zNum){ - int c; - c = memcmp(zNum,"922337203685477580",18)*10; +static int compare2pow63(const char *zNum, int incr){ + int c = 0; + int i; + /* 012345678901234567 */ + const char *pow63 = "922337203685477580"; + for(i=0; c==0 && i<18; i++){ + c = (zNum[i*incr]-pow63[i])*10; + } if( c==0 ){ - c = zNum[18] - '8'; + c = zNum[18*incr] - '8'; testcase( c==(-1) ); testcase( c==0 ); testcase( c==(+1) ); @@ -450,46 +426,52 @@ static int compare2pow63(const char *zNum){ ** or is an integer that is too large to be expressed with 64 bits, ** then return false. ** -** When this routine was originally written it dealt with only -** 32-bit numbers. At that time, it was much faster than the -** atoi() library routine in RedHat 7.2. +** length is the number of bytes in the string (bytes, not characters). +** The string is not necessarily zero-terminated. The encoding is +** given by enc. */ -int sqlite3Atoi64(const char *zNum, i64 *pNum){ +int sqlite3Atoi64(const char *zNum, i64 *pNum, int length, u8 enc){ + int incr = (enc==SQLITE_UTF8?1:2); i64 v = 0; - int neg; - int i, c; + int neg = 0; + int i; + int c = 0; const char *zStart; - while( sqlite3Isspace(*zNum) ) zNum++; + const char *zEnd = zNum + length; + if( enc==SQLITE_UTF16BE ) zNum++; + while( zNum=zEnd ) goto do_atoi_calc; if( *zNum=='-' ){ neg = 1; - zNum++; + zNum+=incr; }else if( *zNum=='+' ){ neg = 0; - zNum++; + zNum+=incr; }else{ neg = 0; } +do_atoi_calc: zStart = zNum; - while( zNum[0]=='0' ){ zNum++; } /* Skip over leading zeros. Ticket #2454 */ - for(i=0; (c=zNum[i])>='0' && c<='9'; i++){ + while( zNum='0' && c<='9'; i+=incr){ v = v*10 + c - '0'; } *pNum = neg ? -v : v; testcase( i==18 ); testcase( i==19 ); testcase( i==20 ); - if( c!=0 || (i==0 && zStart==zNum) || i>19 ){ + if( (c!=0 && &zNum[i]19*incr ){ /* zNum is empty or contains non-numeric text or is longer ** than 19 digits (thus guaranting that it is too large) */ return 0; - }else if( i<19 ){ + }else if( i<19*incr ){ /* Less than 19 digits, so we know that it fits in 64 bits */ return 1; }else{ /* 19-digit numbers must be no larger than 9223372036854775807 if positive ** or 9223372036854775808 if negative. Note that 9223372036854665808 ** is 2^63. */ - return compare2pow63(zNum)flags & (MEM_Real|MEM_Int))==0 ){ - int realnum; + double rValue; + i64 iValue; u8 enc = pRec->enc; - sqlite3VdbeMemNulTerminate(pRec); - if( (pRec->flags&MEM_Str) && sqlite3IsNumber(pRec->z, &realnum, enc) ){ - i64 value; - char *zUtf8 = pRec->z; -#ifndef SQLITE_OMIT_UTF16 - if( enc!=SQLITE_UTF8 ){ - assert( pRec->db ); - zUtf8 = sqlite3Utf16to8(pRec->db, pRec->z, pRec->n, enc); - if( !zUtf8 ) return; - } -#endif - if( !realnum && sqlite3Atoi64(zUtf8, &value) ){ - pRec->u.i = value; - MemSetTypeFlag(pRec, MEM_Int); - }else{ - sqlite3AtoF(zUtf8, &pRec->r); - MemSetTypeFlag(pRec, MEM_Real); - } -#ifndef SQLITE_OMIT_UTF16 - if( enc!=SQLITE_UTF8 ){ - sqlite3DbFree(pRec->db, zUtf8); - } -#endif + if( (pRec->flags&MEM_Str)==0 ) return; + if( sqlite3AtoF(pRec->z, &rValue, pRec->n, enc)==0 ) return; + if( sqlite3Atoi64(pRec->z, &iValue, pRec->n, enc) ){ + pRec->u.i = iValue; + pRec->flags |= MEM_Int; + }else{ + pRec->r = rValue; + pRec->flags |= MEM_Real; } } } diff --git a/src/vdbemem.c b/src/vdbemem.c index 0b7c70d3bd..bab2ff3c0f 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -368,13 +368,9 @@ i64 sqlite3VdbeIntValue(Mem *pMem){ return doubleToInt64(pMem->r); }else if( flags & (MEM_Str|MEM_Blob) ){ i64 value; - pMem->flags |= MEM_Str; - if( sqlite3VdbeChangeEncoding(pMem, SQLITE_UTF8) - || sqlite3VdbeMemNulTerminate(pMem) ){ - return 0; - } - assert( pMem->z ); - sqlite3Atoi64(pMem->z, &value); + assert( pMem->z || pMem->n==0 ); + testcase( pMem->z==0 ); + sqlite3Atoi64(pMem->z, &value, pMem->n, pMem->enc); return value; }else{ return 0; @@ -404,7 +400,7 @@ double sqlite3VdbeRealValue(Mem *pMem){ return (double)0; } assert( pMem->z ); - sqlite3AtoF(pMem->z, &val); + sqlite3AtoF(pMem->z, &val, pMem->n, SQLITE_UTF8); return val; }else{ /* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */ @@ -485,7 +481,7 @@ int sqlite3VdbeMemNumerify(Mem *pMem){ if( rc ) return rc; rc = sqlite3VdbeMemNulTerminate(pMem); if( rc ) return rc; - if( sqlite3Atoi64(pMem->z, &pMem->u.i) ){ + if( sqlite3Atoi64(pMem->z, &pMem->u.i, pMem->n, SQLITE_UTF8) ){ MemSetTypeFlag(pMem, MEM_Int); }else{ pMem->r = sqlite3VdbeRealValue(pMem); From 9351862b6d269c96c18df8519bfd1a6ddb029e07 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 30 Sep 2010 14:48:06 +0000 Subject: [PATCH 2/8] Fix the handling of default values for ALTER TABLE ADD COLUMN columns so that is able to deal with negative numbers, including large negative numbers. Ticket [8454a207b9fd2243c4] FossilOrigin-Name: ce6cc16e3a151a0c67855abde1411422dfcc8828 --- manifest | 25 +++++++-------- manifest.uuid | 2 +- src/vdbe.c | 4 +-- src/vdbemem.c | 47 ++++++++++++++++++---------- test/tkt-8454a207b9.test | 67 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 111 insertions(+), 34 deletions(-) create mode 100644 test/tkt-8454a207b9.test diff --git a/manifest b/manifest index 39e52bb943..ba581099d8 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,8 @@ -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 -C Rework\sthe\stext\sto\snumeric\sconversion\sroutines\sso\sthat\sthey\swork\swith\seither\nUTF8\sor\sUTF16\sand\sdo\snot\srequire\sa\sNULL\sterminator.\s\sThis\sallowed\stext\sto\nnumeric\sconversion\swithout\sreallocating\sthe\sstring. -D 2010-09-30T00:50:50 +C Fix\sthe\shandling\sof\sdefault\svalues\sfor\sALTER\sTABLE\sADD\sCOLUMN\scolumns\sso\nthat\sis\sable\sto\sdeal\swith\snegative\snumbers,\sincluding\slarge\snegative\snumbers.\nTicket\s[8454a207b9fd2243c4] +D 2010-09-30T14:48:06 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in c599a15d268b1db2aeadea19df2adc3bf2eb6bee F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -228,13 +228,13 @@ F src/update.c 227e6cd512108b84f69421fc6c7aa1b83d60d6e0 F src/utf.c 1baeeac91707a4df97ccc6141ec0f808278af685 F src/util.c 7a5fb16c0b9a3e4c9fa6c375c8f514bc3bb155b6 F src/vacuum.c 924bd1bcee2dfb05376f79845bd3b4cec7b54b2f -F src/vdbe.c 04cf7c1b0b7a7dc825ddde202307ca15c1115fbb +F src/vdbe.c 597ef9aceeb4d695eb65a61453dc1139175cf893 F src/vdbe.h 4de0efb4b0fdaaa900cf419b35c458933ef1c6d2 F src/vdbeInt.h 7f4cf1b2b69bef3a432b1f23dfebef57275436b4 F src/vdbeapi.c 03cddfa4f85cadf608c0d28ff6b622b7da432446 F src/vdbeaux.c de0b06b11a25293e820a49159eca9f1c51a64716 F src/vdbeblob.c 258a6010ba7a82b72b327fb24c55790655689256 -F src/vdbemem.c cfb178242f38fb03a44672268afa05716d55e769 +F src/vdbemem.c 09b637201d66dae067f2beb838996a7e8adae44f F src/vdbetrace.c 864cef96919323482ebd9986f2132435115e9cc2 F src/vtab.c 6c90e3e65b2f026fc54703a8f3c917155f419d87 F src/wal.c 7081f148cb52b0cf2280e6384196402dc58130a3 @@ -669,6 +669,7 @@ F test/tkt-5e10420e8d.test 904d1687b3c06d43e5b3555bbcf6802e7c0ffd84 F test/tkt-5ee23731f.test 3581260f2a71e51db94e1506ba6b0f7311d002a9 F test/tkt-78e04e52ea.test fb5430c675e708f5cbafdf3e7e5593da5145a527 F test/tkt-80e031a00f.test 9a154173461a4dbe2de49cda73963e04842d52f7 +F test/tkt-8454a207b9.test c583a9f814a82a2b5ba95207f55001c9f0cd816c F test/tkt-94c04eaadb.test be5ea61cb04dfdc047d19b5c5a9e75fa3da67a7f F test/tkt-9d68c883.test 458f7d82a523d7644b54b497c986378a7d8c8b67 F test/tkt-b351d95f9.test d14a503c414c5c58fdde3e80f9a3cfef986498c0 @@ -872,18 +873,14 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P f34dc54d46d05adf1f52db51442195b3285a26b9 -R 5e9e2523f82be46cc8ebbb892165bffa -T *bgcolor * #c0ffc0 -T *branch * experimental -T *sym-experimental * -T -sym-trunk * +P 14eed3a0e0a45c6f2904a3a134aa27c159916f7b +R 4d517dec75ee1dd489234109dd0359e9 U drh -Z 0c6ebf88312d1668689f16e4194172bb +Z 470c7c5b24a8c0836423cc96a5b1f790 -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.6 (GNU/Linux) -iD8DBQFMo97toxKgR168RlERAi5jAJsFDVqJu9wdOQNwlT2y3q2TNuHUGQCdFwrP -sR9IRwN4k3Y2ZVtzQE0tnsY= -=6xoC +iD8DBQFMpKMqoxKgR168RlERAvkLAJ0XiYNxedhD7GFhtTggvRsz2xpfLQCgjac7 +zIAfAuf6n9xnxhw6RMuzDI0= +=1JR8 -----END PGP SIGNATURE----- diff --git a/manifest.uuid b/manifest.uuid index 59c95200ea..3ddafafe18 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -14eed3a0e0a45c6f2904a3a134aa27c159916f7b \ No newline at end of file +ce6cc16e3a151a0c67855abde1411422dfcc8828 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 79dfff3ea9..8c5f8c8d9a 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -1610,9 +1610,7 @@ case OP_ToBlob: { /* same as TK_TO_BLOB, in1 */ case OP_ToNumeric: { /* same as TK_TO_NUMERIC, in1 */ pIn1 = &aMem[pOp->p1]; memAboutToChange(p, pIn1); - if( (pIn1->flags & (MEM_Null|MEM_Int|MEM_Real))==0 ){ - sqlite3VdbeMemNumerify(pIn1); - } + sqlite3VdbeMemNumerify(pIn1); break; } #endif /* SQLITE_OMIT_CAST */ diff --git a/src/vdbemem.c b/src/vdbemem.c index bab2ff3c0f..ec7086ed38 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -473,21 +473,19 @@ int sqlite3VdbeMemRealify(Mem *pMem){ ** as much of the string as we can and ignore the rest. */ int sqlite3VdbeMemNumerify(Mem *pMem){ - int rc; - assert( (pMem->flags & (MEM_Int|MEM_Real|MEM_Null))==0 ); - assert( (pMem->flags & (MEM_Blob|MEM_Str))!=0 ); - assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); - rc = sqlite3VdbeChangeEncoding(pMem, SQLITE_UTF8); - if( rc ) return rc; - rc = sqlite3VdbeMemNulTerminate(pMem); - if( rc ) return rc; - if( sqlite3Atoi64(pMem->z, &pMem->u.i, pMem->n, SQLITE_UTF8) ){ - MemSetTypeFlag(pMem, MEM_Int); - }else{ - pMem->r = sqlite3VdbeRealValue(pMem); - MemSetTypeFlag(pMem, MEM_Real); - sqlite3VdbeIntegerAffinity(pMem); + if( (pMem->flags & (MEM_Int|MEM_Real|MEM_Null))==0 ){ + assert( (pMem->flags & (MEM_Blob|MEM_Str))!=0 ); + assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); + if( sqlite3Atoi64(pMem->z, &pMem->u.i, pMem->n, pMem->enc) ){ + MemSetTypeFlag(pMem, MEM_Int); + }else{ + pMem->r = sqlite3VdbeRealValue(pMem); + MemSetTypeFlag(pMem, MEM_Real); + sqlite3VdbeIntegerAffinity(pMem); + } } + assert( (pMem->flags & (MEM_Int|MEM_Real|MEM_Null))!=0 ); + pMem->flags &= ~(MEM_Str|MEM_Blob); return SQLITE_OK; } @@ -1030,6 +1028,8 @@ int sqlite3ValueFromExpr( int op; char *zVal = 0; sqlite3_value *pVal = 0; + int negInt = 1; + const char *zNeg = ""; if( !pExpr ){ *ppVal = 0; @@ -1047,13 +1047,24 @@ int sqlite3ValueFromExpr( if( NEVER(op==TK_REGISTER) ) op = pExpr->op2; #endif + /* Handle negative integers in a single step. This is needed in the + ** case when the value is -9223372036854775808. + */ + if( op==TK_UMINUS + && (pExpr->pLeft->op==TK_INTEGER || pExpr->pLeft->op==TK_FLOAT) ){ + pExpr = pExpr->pLeft; + op = pExpr->op; + negInt = -1; + zNeg = "-"; + } + if( op==TK_STRING || op==TK_FLOAT || op==TK_INTEGER ){ pVal = sqlite3ValueNew(db); if( pVal==0 ) goto no_mem; if( ExprHasProperty(pExpr, EP_IntValue) ){ - sqlite3VdbeMemSetInt64(pVal, (i64)pExpr->u.iValue); + sqlite3VdbeMemSetInt64(pVal, (i64)pExpr->u.iValue*negInt); }else{ - zVal = sqlite3DbStrDup(db, pExpr->u.zToken); + zVal = sqlite3MPrintf(db, "%s%s", zNeg, pExpr->u.zToken); if( zVal==0 ) goto no_mem; sqlite3ValueSetStr(pVal, -1, zVal, SQLITE_UTF8, SQLITE_DYNAMIC); if( op==TK_FLOAT ) pVal->type = SQLITE_FLOAT; @@ -1063,14 +1074,18 @@ int sqlite3ValueFromExpr( }else{ sqlite3ValueApplyAffinity(pVal, affinity, SQLITE_UTF8); } + if( pVal->flags & (MEM_Int|MEM_Real) ) pVal->flags &= ~MEM_Str; if( enc!=SQLITE_UTF8 ){ sqlite3VdbeChangeEncoding(pVal, enc); } }else if( op==TK_UMINUS ) { + /* This branch happens for multiple negative signs. Ex: -(-5) */ if( SQLITE_OK==sqlite3ValueFromExpr(db,pExpr->pLeft,enc,affinity,&pVal) ){ + sqlite3VdbeMemNumerify(pVal); pVal->u.i = -1 * pVal->u.i; /* (double)-1 In case of SQLITE_OMIT_FLOATING_POINT... */ pVal->r = (double)-1 * pVal->r; + sqlite3ValueApplyAffinity(pVal, affinity, enc); } } #ifndef SQLITE_OMIT_BLOB_LITERAL diff --git a/test/tkt-8454a207b9.test b/test/tkt-8454a207b9.test new file mode 100644 index 0000000000..88a8614f82 --- /dev/null +++ b/test/tkt-8454a207b9.test @@ -0,0 +1,67 @@ +# 2010 September 30 +# +# 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 implements regression tests for SQLite library. Specifically, +# it tests that ticket [8454a207b9fd2243c4c6b7a73f67ea0315717c1a]. Verify +# that a negative default value on an added text column actually comes +# out negative. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl + +do_test tkt-8454a207b9.1 { + db eval { + CREATE TABLE t1(a); + INSERT INTO t1 VALUES(1); + ALTER TABLE t1 ADD COLUMN b TEXT DEFAULT -123.0; + SELECT b, typeof(b) FROM t1; + } +} {-123.0 text} +do_test tkt-8454a207b9.2 { + db eval { + ALTER TABLE t1 ADD COLUMN c TEXT DEFAULT -123.5; + SELECT c, typeof(c) FROM t1; + } +} {-123.5 text} +do_test tkt-8454a207b9.3 { + db eval { + ALTER TABLE t1 ADD COLUMN d TEXT DEFAULT -'hello'; + SELECT d, typeof(d) FROM t1; + } +} {0 text} +do_test tkt-8454a207b9.4 { + db eval { + ALTER TABLE t1 ADD COLUMN e DEFAULT -123.0; + SELECT e, typeof(e) FROM t1; + } +} {-123 integer} +do_test tkt-8454a207b9.5 { + db eval { + ALTER TABLE t1 ADD COLUMN f DEFAULT -123.5; + SELECT f, typeof(f) FROM t1; + } +} {-123.5 real} +do_test tkt-8454a207b9.6 { + db eval { + ALTER TABLE t1 ADD COLUMN g DEFAULT -9223372036854775808; + SELECT g, typeof(g) FROM t1; + } +} {-9223372036854775808 integer} +do_test tkt-8454a207b9.7 { + db eval { + ALTER TABLE t1 ADD COLUMN h DEFAULT 9223372036854775807; + SELECT h, typeof(h) FROM t1; + } +} {9223372036854775807 integer} + + +finish_test From 5f1d6b616e003f511fe113bcfe808698127fbf30 Mon Sep 17 00:00:00 2001 From: shaneh Date: Thu, 30 Sep 2010 16:51:25 +0000 Subject: [PATCH 3/8] Changes to remove sqlite3FitsIn64Bits(). FossilOrigin-Name: 43fef1cab6315f837782ea601d5a2aeb9843ab3c --- manifest | 36 +++++++++-------------- manifest.uuid | 2 +- src/expr.c | 15 +++++----- src/sqliteInt.h | 1 - src/test1.c | 2 +- src/util.c | 77 ++++++++++++------------------------------------- src/vdbe.c | 2 +- src/vdbemem.c | 2 +- test/expr.test | 2 +- 9 files changed, 44 insertions(+), 95 deletions(-) diff --git a/manifest b/manifest index ba581099d8..24b3c8385d 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,5 @@ ------BEGIN PGP SIGNED MESSAGE----- -Hash: SHA1 - -C Fix\sthe\shandling\sof\sdefault\svalues\sfor\sALTER\sTABLE\sADD\sCOLUMN\scolumns\sso\nthat\sis\sable\sto\sdeal\swith\snegative\snumbers,\sincluding\slarge\snegative\snumbers.\nTicket\s[8454a207b9fd2243c4] -D 2010-09-30T14:48:06 +C Changes\sto\sremove\ssqlite3FitsIn64Bits(). +D 2010-09-30T16:51:26 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in c599a15d268b1db2aeadea19df2adc3bf2eb6bee F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -130,7 +127,7 @@ F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c 4f3aadad62c6c9f0d4e5a96718516ac4e3c598df F src/date.c 1548fdac51377e4e7833251de878b4058c148e1b F src/delete.c 7ed8a8c8b5f748ece92df173d7e0f7810c899ebd -F src/expr.c 05dbb04833ea04c28e835bf67295e367ca1c52d8 +F src/expr.c c5749e45576a58d9de27e6a8462fa84eac0b32fd F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 17950a28f28b23e8ad3feaac5fc88c324d2f600a F src/func.c 2b7cf54d2569c2eba42fe81165d1932b546681a3 @@ -180,12 +177,12 @@ F src/select.c cf3013b1953348c7c6ff9636342e87b9fda68466 F src/shell.c 8517fc1f9c59ae4007e6cc8b9af91ab231ea2056 F src/sqlite.h.in a5b50e1bc4d4d9a3cc95386747220a839d0c40f7 F src/sqlite3ext.h 69dfb8116af51b84a029cddb3b35062354270c89 -F src/sqliteInt.h 6fb1558f7810dc13406c7629b9ea20ec46b701e8 +F src/sqliteInt.h c63b0340dfdfde18ff255ddccf004edd2d073288 F src/sqliteLimit.h a17dcd3fb775d63b64a43a55c54cb282f9726f44 F src/status.c 496913d4e8441195f6f2a75b1c95993a45b9b30b F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e F src/tclsqlite.c e91019fb6787166abca23a81b16c07fecc2ed751 -F src/test1.c 6fbbb504a7d1069415e443ae687d61cab72fa51e +F src/test1.c e8803ee4bf6766f1b9cd8a3fed1559cc05caa306 F src/test2.c 80d323d11e909cf0eb1b6fbb4ac22276483bcf31 F src/test3.c 056093cfef69ff4227a6bdb9108564dc7f45e4bc F src/test4.c 0528360b5025688002a5feb6be906ddce52eaaee @@ -226,15 +223,15 @@ F src/tokenize.c 604607d6813e9551cf5189d899e0a25c12681080 F src/trigger.c b8bedb9c0084ceb51a40f54fcca2ce048c8de852 F src/update.c 227e6cd512108b84f69421fc6c7aa1b83d60d6e0 F src/utf.c 1baeeac91707a4df97ccc6141ec0f808278af685 -F src/util.c 7a5fb16c0b9a3e4c9fa6c375c8f514bc3bb155b6 +F src/util.c 0cca1dff4d04bbb378e0a7c2d342396363e9f0b4 F src/vacuum.c 924bd1bcee2dfb05376f79845bd3b4cec7b54b2f -F src/vdbe.c 597ef9aceeb4d695eb65a61453dc1139175cf893 +F src/vdbe.c 447577ca9db7cccac30dd8ea07aeb6a4ddee9cde F src/vdbe.h 4de0efb4b0fdaaa900cf419b35c458933ef1c6d2 F src/vdbeInt.h 7f4cf1b2b69bef3a432b1f23dfebef57275436b4 F src/vdbeapi.c 03cddfa4f85cadf608c0d28ff6b622b7da432446 F src/vdbeaux.c de0b06b11a25293e820a49159eca9f1c51a64716 F src/vdbeblob.c 258a6010ba7a82b72b327fb24c55790655689256 -F src/vdbemem.c 09b637201d66dae067f2beb838996a7e8adae44f +F src/vdbemem.c ef015d9d05fbf3fcce664dadd5b589663878ab50 F src/vdbetrace.c 864cef96919323482ebd9986f2132435115e9cc2 F src/vtab.c 6c90e3e65b2f026fc54703a8f3c917155f419d87 F src/wal.c 7081f148cb52b0cf2280e6384196402dc58130a3 @@ -369,7 +366,7 @@ F test/eval.test bc269c365ba877554948441e91ad5373f9f91be3 F test/exclusive.test 0ba00fb15aeec1eba3d4b03a271b5081e21c35be F test/exclusive2.test 76e63c05349cb70d09d60b99d2ae625525ff5155 F test/exec.test e949714dc127eaa5ecc7d723efec1ec27118fdd7 -F test/expr.test 9f521ae22f00e074959f72ce2e55d46b9ed23f68 +F test/expr.test 620a636cf7b7d4e5834a0b9d83a4da372e24a7b7 F test/fallocate.test 43dc34b8c24be6baffadc3b4401ee15710ce83c6 F test/filectrl.test 97003734290887566e01dded09dc9e99cb937e9e F test/filefmt.test f77c92141960b7933bc6691631d2ad62257ef40a @@ -873,14 +870,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P 14eed3a0e0a45c6f2904a3a134aa27c159916f7b -R 4d517dec75ee1dd489234109dd0359e9 -U drh -Z 470c7c5b24a8c0836423cc96a5b1f790 ------BEGIN PGP SIGNATURE----- -Version: GnuPG v1.4.6 (GNU/Linux) - -iD8DBQFMpKMqoxKgR168RlERAvkLAJ0XiYNxedhD7GFhtTggvRsz2xpfLQCgjac7 -zIAfAuf6n9xnxhw6RMuzDI0= -=1JR8 ------END PGP SIGNATURE----- +P ce6cc16e3a151a0c67855abde1411422dfcc8828 +R f10482e4b62453ab01ff046fc673997a +U shaneh +Z e009fe1b0e7c264af8f0ee9d5e4c3177 diff --git a/manifest.uuid b/manifest.uuid index 3ddafafe18..8a49352421 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ce6cc16e3a151a0c67855abde1411422dfcc8828 \ No newline at end of file +43fef1cab6315f837782ea601d5a2aeb9843ab3c \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index cf1823d9d8..41be16260f 100644 --- a/src/expr.c +++ b/src/expr.c @@ -555,7 +555,7 @@ void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr){ /* Wildcard of the form "?nnn". Convert "nnn" to an integer and ** use it as the variable number */ i64 i; - int bOk = sqlite3Atoi64(&z[1], &i, sqlite3Strlen30(&z[1]), SQLITE_UTF8); + int bOk = 0==sqlite3Atoi64(&z[1], &i, sqlite3Strlen30(&z[1]), SQLITE_UTF8); pExpr->iColumn = (ynVar)i; testcase( i==0 ); testcase( i==1 ); @@ -1932,9 +1932,7 @@ static void codeReal(Vdbe *v, const char *z, int negateFlag, int iMem){ ** Generate an instruction that will put the integer describe by ** text z[0..n-1] into register iMem. ** -** The z[] string will probably not be zero-terminated. But the -** z[n] character is guaranteed to be something that does not look -** like the continuation of the number. +** Expr.u.zToken is always UTF8 and zero-terminated. */ static void codeInteger(Parse *pParse, Expr *pExpr, int negFlag, int iMem){ Vdbe *v = pParse->pVdbe; @@ -1943,13 +1941,14 @@ static void codeInteger(Parse *pParse, Expr *pExpr, int negFlag, int iMem){ if( negFlag ) i = -i; sqlite3VdbeAddOp2(v, OP_Integer, i, iMem); }else{ + int c; + i64 value; const char *z = pExpr->u.zToken; assert( z!=0 ); - if( sqlite3FitsIn64Bits(z, negFlag) ){ - i64 value; + c = sqlite3Atoi64(z, &value, sqlite3Strlen30(z), SQLITE_UTF8); + if( c==0 || (c==2 && negFlag) ){ char *zV; - sqlite3Atoi64(z, &value, sqlite3Strlen30(z), SQLITE_UTF8); - if( negFlag ) value = -value; + if( negFlag ){ value = -value; } zV = dup8bytes(v, (char*)&value); sqlite3VdbeAddOp4(v, OP_Int64, 0, iMem, 0, zV, P4_INT64); }else{ diff --git a/src/sqliteInt.h b/src/sqliteInt.h index dd5d239438..8515efcc49 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2828,7 +2828,6 @@ int sqlite3FixExprList(DbFixer*, ExprList*); int sqlite3FixTriggerStep(DbFixer*, TriggerStep*); int sqlite3AtoF(const char *z, double*, int, u8); int sqlite3GetInt32(const char *, int*); -int sqlite3FitsIn64Bits(const char *, int); int sqlite3Utf16ByteLen(const void *pData, int nChar); int sqlite3Utf8CharLen(const char *pData, int nByte); int sqlite3Utf8Read(const u8*, const u8**); diff --git a/src/test1.c b/src/test1.c index b83263d00b..af83d5cb45 100644 --- a/src/test1.c +++ b/src/test1.c @@ -1235,7 +1235,7 @@ static int sqlite3_mprintf_int64( return TCL_ERROR; } for(i=2; i<5; i++){ - if( !sqlite3Atoi64(argv[i], &a[i-2], 1000000, SQLITE_UTF8) ){ + if( sqlite3Atoi64(argv[i], &a[i-2], 1000000, SQLITE_UTF8) ){ Tcl_AppendResult(interp, "argument is not a valid 64-bit integer", 0); return TCL_ERROR; } diff --git a/src/util.c b/src/util.c index 36689ec1d3..2fa178f507 100644 --- a/src/util.c +++ b/src/util.c @@ -382,10 +382,10 @@ do_atof_calc: /* store the result */ *pResult = result; - /* return number of bytes used */ + /* return true if number and no extra chracters after */ return z>=zEnd && sqlite3Isdigit(z[-incr]); #else - return sqlite3Atoi64(z, pResult, length, enc); + return !sqlite3Atoi64(z, pResult, length, enc); #endif /* SQLITE_OMIT_FLOATING_POINT */ } @@ -393,6 +393,7 @@ do_atof_calc: ** Compare the 19-character string zNum against the text representation ** value 2^63: 9223372036854775808. Return negative, zero, or positive ** if zNum is less than, equal to, or greater than the string. +** Note that zNum must contain exactly 19 characters. ** ** Unlike memcmp() this routine is guaranteed to return the difference ** in the values of the last digit if the only difference is in the @@ -421,10 +422,14 @@ static int compare2pow63(const char *zNum, int incr){ /* -** Return TRUE if zNum is a 64-bit signed integer and write -** the value of the integer into *pNum. If zNum is not an integer -** or is an integer that is too large to be expressed with 64 bits, -** then return false. +** Convert zNum to a 64-bit signed integer and write +** the value of the integer into *pNum. +** If zNum is exactly 9223372036854665808, return 2. +** This is a special case as the context will determine +** if it is too big (used as a negative). +** If zNum is not an integer or is an integer that +** is too large to be expressed with 64 bits, +** then return 1. Otherwise return 0. ** ** length is the number of bytes in the string (bytes, not characters). ** The string is not necessarily zero-terminated. The encoding is @@ -433,7 +438,7 @@ static int compare2pow63(const char *zNum, int incr){ int sqlite3Atoi64(const char *zNum, i64 *pNum, int length, u8 enc){ int incr = (enc==SQLITE_UTF8?1:2); i64 v = 0; - int neg = 0; + int neg = 0; /* assume positive */ int i; int c = 0; const char *zStart; @@ -445,10 +450,7 @@ int sqlite3Atoi64(const char *zNum, i64 *pNum, int length, u8 enc){ neg = 1; zNum+=incr; }else if( *zNum=='+' ){ - neg = 0; zNum+=incr; - }else{ - neg = 0; } do_atoi_calc: zStart = zNum; @@ -462,59 +464,18 @@ do_atoi_calc: testcase( i==20 ); if( (c!=0 && &zNum[i]19*incr ){ /* zNum is empty or contains non-numeric text or is longer - ** than 19 digits (thus guaranting that it is too large) */ - return 0; + ** than 19 digits (thus guaranteeing that it is too large) */ + return 1; }else if( i<19*incr ){ /* Less than 19 digits, so we know that it fits in 64 bits */ - return 1; + return 0; }else{ /* 19-digit numbers must be no larger than 9223372036854775807 if positive ** or 9223372036854775808 if negative. Note that 9223372036854665808 - ** is 2^63. */ - return compare2pow63(zNum, incr)='0' && zNum[0]<='9' ); /* zNum is an unsigned number */ - - if( negFlag ) neg = 1-neg; - while( *zNum=='0' ){ - zNum++; /* Skip leading zeros. Ticket #2454 */ - } - for(i=0; zNum[i]; i++){ assert( zNum[i]>='0' && zNum[i]<='9' ); } - testcase( i==18 ); - testcase( i==19 ); - testcase( i==20 ); - if( i<19 ){ - /* Guaranteed to fit if less than 19 digits */ - return 1; - }else if( i>19 ){ - /* Guaranteed to be too big if greater than 19 digits */ - return 0; - }else{ - /* Compare against 2^63. */ - return compare2pow63(zNum, 1)enc; if( (pRec->flags&MEM_Str)==0 ) return; if( sqlite3AtoF(pRec->z, &rValue, pRec->n, enc)==0 ) return; - if( sqlite3Atoi64(pRec->z, &iValue, pRec->n, enc) ){ + if( 0==sqlite3Atoi64(pRec->z, &iValue, pRec->n, enc) ){ pRec->u.i = iValue; pRec->flags |= MEM_Int; }else{ diff --git a/src/vdbemem.c b/src/vdbemem.c index ec7086ed38..598cb9d661 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -476,7 +476,7 @@ int sqlite3VdbeMemNumerify(Mem *pMem){ if( (pMem->flags & (MEM_Int|MEM_Real|MEM_Null))==0 ){ assert( (pMem->flags & (MEM_Blob|MEM_Str))!=0 ); assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); - if( sqlite3Atoi64(pMem->z, &pMem->u.i, pMem->n, pMem->enc) ){ + if( 0==sqlite3Atoi64(pMem->z, &pMem->u.i, pMem->n, pMem->enc) ){ MemSetTypeFlag(pMem, MEM_Int); }else{ pMem->r = sqlite3VdbeRealValue(pMem); diff --git a/test/expr.test b/test/expr.test index 87ee8ed3ca..140ab8d8b3 100644 --- a/test/expr.test +++ b/test/expr.test @@ -290,7 +290,7 @@ ifcapable floatingpoint { test_expr expr-4.14 {r1='abc', r2='Bbc'} {r1>r2} 1 test_expr expr-4.15 {r1='0', r2='0.0'} {r1==r2} 1 test_expr expr-4.16 {r1='0.000', r2='0.0'} {r1==r2} 1 - test_expr expr-4.17 {r1=' 0.000', r2=' 0.0'} {r1==r2} 0 + test_expr expr-4.17 {r1=' 0.000', r2=' 0.0'} {r1==r2} 1 test_expr expr-4.18 {r1='0.0', r2='abc'} {r1r2} 0 From 025586a259b68a5a81ad1114ec19881e996a2a54 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 30 Sep 2010 17:33:11 +0000 Subject: [PATCH 4/8] Do correct affinity transformations on floating point values which have a decimal point at the beginning or end of the mantissa. Ticket [3998683a16a7076e08f5]. FossilOrigin-Name: ca154f97a590745539b2cbfd77eb319fd7392a40 --- manifest | 29 +++++++++++++++++-------- manifest.uuid | 2 +- src/util.c | 45 +++++++++++++++++++++++++++------------ test/date.test | 2 +- test/index.test | 15 ++++++++++--- test/tkt-3998683a16.test | 46 ++++++++++++++++++++++++++++++++++++++++ 6 files changed, 112 insertions(+), 27 deletions(-) create mode 100644 test/tkt-3998683a16.test diff --git a/manifest b/manifest index 24b3c8385d..607886fbf2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,8 @@ -C Changes\sto\sremove\ssqlite3FitsIn64Bits(). -D 2010-09-30T16:51:26 +-----BEGIN PGP SIGNED MESSAGE----- +Hash: SHA1 + +C Do\scorrect\saffinity\stransformations\son\sfloating\spoint\svalues\swhich\shave\na\sdecimal\spoint\sat\sthe\sbeginning\sor\send\sof\sthe\smantissa.\nTicket\s[3998683a16a7076e08f5]. +D 2010-09-30T17:33:12 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in c599a15d268b1db2aeadea19df2adc3bf2eb6bee F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -223,7 +226,7 @@ F src/tokenize.c 604607d6813e9551cf5189d899e0a25c12681080 F src/trigger.c b8bedb9c0084ceb51a40f54fcca2ce048c8de852 F src/update.c 227e6cd512108b84f69421fc6c7aa1b83d60d6e0 F src/utf.c 1baeeac91707a4df97ccc6141ec0f808278af685 -F src/util.c 0cca1dff4d04bbb378e0a7c2d342396363e9f0b4 +F src/util.c cd78524566fe45671863eee78685969a4bfd4e4c F src/vacuum.c 924bd1bcee2dfb05376f79845bd3b4cec7b54b2f F src/vdbe.c 447577ca9db7cccac30dd8ea07aeb6a4ddee9cde F src/vdbe.h 4de0efb4b0fdaaa900cf419b35c458933ef1c6d2 @@ -337,7 +340,7 @@ F test/crashtest1.c 09c1c7d728ccf4feb9e481671e29dda5669bbcc2 F test/createtab.test 199cf68f44e5d9e87a0b8afc7130fdeb4def3272 F test/cse.test 277350a26264495e86b1785f34d2d0c8600e021c F test/ctime.test 7bd009071e242aac4f18521581536b652b789a47 -F test/date.test 6354b883f922c38046a8efbad187cc95df6da023 +F test/date.test a18a2ce81add84b17b06559e82ad7bb91bc6ddff F test/dbstatus.test 175b088308f2ce3f7afb8208f25c10878ee05921 F test/default.test 6faf23ccb300114924353007795aa9a8ec0aa9dc F test/delete.test f7629d9eb245dfca170169cc5c7a735dec34aeb4 @@ -461,7 +464,7 @@ F test/incrblob_err.test c577c91d4ed9e8336cdb188b15d6ee2a6fe9604e F test/incrvacuum.test 453d1e490d8f5ad2c9b3a54282a0690d6ae56462 F test/incrvacuum2.test 9e22a794899c91b7d8c8e12eaacac8df249faafe F test/incrvacuum_ioerr.test 57d2f5777ab13fa03b87b262a4ea1bad5cfc0291 -F test/index.test cbf301cdb2da43e4eac636c3400c2439af1834ad +F test/index.test df7c00c6edd9504ab71c83a9514f1c5ca0fa54d8 F test/index2.test ee83c6b5e3173a3d7137140d945d9a5d4fdfb9d6 F test/index3.test 423a25c789fc8cc51aaf2a4370bbdde2d9e9eed7 F test/indexedby.test 5a1180602f2e72c481467bd4cae05dae5dc36f47 @@ -660,6 +663,7 @@ F test/tkt-26ff0c2d1e.test 888324e751512972c6e0d1a09df740d8f5aaf660 F test/tkt-2ea2425d34.test 1cf13e6f75d149b3209a0cb32927a82d3d79fb28 F test/tkt-31338dca7e.test 5741cd48de500347a437ba1be58c8335e83c5a5e F test/tkt-313723c356.test c47f8a9330523e6f35698bf4489bcb29609b53ac +F test/tkt-3998683a16.test 6d1d04d551ed1704eb3396ca87bb9ccc8c5c1eb7 F test/tkt-3fe897352e.test 10de1a67bd5c66b238a4c96abe55531b37bb4f00 F test/tkt-4a03edc4c8.test 2865e4edbc075b954daa82f8da7cc973033ec76e F test/tkt-5e10420e8d.test 904d1687b3c06d43e5b3555bbcf6802e7c0ffd84 @@ -870,7 +874,14 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P ce6cc16e3a151a0c67855abde1411422dfcc8828 -R f10482e4b62453ab01ff046fc673997a -U shaneh -Z e009fe1b0e7c264af8f0ee9d5e4c3177 +P 43fef1cab6315f837782ea601d5a2aeb9843ab3c +R 9f0571eacddb9a3dd22902b2fc6da09d +U drh +Z c3bfcfff0e351511af94c6133a9e5932 +-----BEGIN PGP SIGNATURE----- +Version: GnuPG v1.4.6 (GNU/Linux) + +iD8DBQFMpMncoxKgR168RlERApVjAJ9CgWo7czjJJMuzPPhDGIuxcWDpSACeLMY+ +2nv8gkZ9kYhTsRmCj46G7ik= +=tJZ/ +-----END PGP SIGNATURE----- diff --git a/manifest.uuid b/manifest.uuid index 8a49352421..8e6154f471 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -43fef1cab6315f837782ea601d5a2aeb9843ab3c \ No newline at end of file +ca154f97a590745539b2cbfd77eb319fd7392a40 \ No newline at end of file diff --git a/src/util.c b/src/util.c index 2fa178f507..4b603b3086 100644 --- a/src/util.c +++ b/src/util.c @@ -239,35 +239,47 @@ int sqlite3_strnicmp(const char *zLeft, const char *zRight, int N){ /* ** The string z[] is an text representation of a real number. -** Convert this string to a double. +** Convert this string to a double and write it into *pResult. ** ** The string z[] is length bytes in length (bytes, not characters) and ** uses the encoding enc. The string is not necessarily zero-terminated. ** ** Return TRUE if the result is a valid real number (or integer) and FALSE -** if the string is empty or contains extraneous text. +** if the string is empty or contains extraneous text. Valid numbers +** are in one of these formats: +** +** [+-]digits[E[+-]digits] +** [+-]digits.[digits][E[+-]digits] +** [+-].digits[E[+-]digits] +** +** Leading and trailing whitespace is ignored for the purpose of determining +** validity. +** +** If some prefix of the input string is a valid number, this routine +** returns FALSE but it still converts the prefix and writes the result +** into *pResult. */ int sqlite3AtoF(const char *z, double *pResult, int length, u8 enc){ #ifndef SQLITE_OMIT_FLOATING_POINT int incr = (enc==SQLITE_UTF8?1:2); const char *zEnd = z + length; /* sign * significand * (10 ^ (esign * exponent)) */ - int sign = 1; /* sign of significand */ - i64 s = 0; /* significand */ - int d = 0; /* adjust exponent for shifting decimal point */ - int esign = 1; /* sign of exponent */ - int e = 0; /* exponent */ + int sign = 1; /* sign of significand */ + i64 s = 0; /* significand */ + int d = 0; /* adjust exponent for shifting decimal point */ + int esign = 1; /* sign of exponent */ + int e = 0; /* exponent */ + int eValid = 1; /* True exponent is either not used or is well-formed */ double result; int nDigits = 0; + *pResult = 0.0; /* Default return value, in case of an error */ + if( enc==SQLITE_UTF16BE ) z++; /* skip leading spaces */ while( z=zEnd ){ - *pResult = 0.0; - return 0; - } + if( z>=zEnd ) return 0; /* get sign of significand */ if( *z=='-' ){ @@ -308,6 +320,7 @@ int sqlite3AtoF(const char *z, double *pResult, int length, u8 enc){ /* if exponent is present */ if( *z=='e' || *z=='E' ){ z+=incr; + eValid = 0; if( z>=zEnd ) goto do_atof_calc; /* get sign of exponent */ if( *z=='-' ){ @@ -320,9 +333,15 @@ int sqlite3AtoF(const char *z, double *pResult, int length, u8 enc){ while( z=zEnd && sqlite3Isdigit(z[-incr]); + /* return true if number and no extra non-whitespace chracters after */ + return z>=zEnd && nDigits>0 && eValid; #else return !sqlite3Atoi64(z, pResult, length, enc); #endif /* SQLITE_OMIT_FLOATING_POINT */ diff --git a/test/date.test b/test/date.test index 29b5ed4d1d..9bfec12626 100644 --- a/test/date.test +++ b/test/date.test @@ -84,7 +84,7 @@ for {set i 0} {$i<1000} {incr i} { datetest 2.3 {date('2003-10-22','weekday 0')} 2003-10-26 datetest 2.4 {date('2003-10-22','weekday 1')} 2003-10-27 datetest 2.4a {date('2003-10-22','weekday 1')} 2003-10-27 -datetest 2.4b {date('2003-10-22','weekday 1x')} 2003-10-27 +datetest 2.4b {date('2003-10-22','weekday 1x')} NULL datetest 2.4c {date('2003-10-22','weekday -1')} NULL datetest 2.4d {date('2003-10-22','weakday 1x')} NULL datetest 2.4e {date('2003-10-22','weekday ')} NULL diff --git a/test/index.test b/test/index.test index a278ac8889..0a41a6de3e 100644 --- a/test/index.test +++ b/test/index.test @@ -532,10 +532,19 @@ do_test index-15.2 { INSERT INTO t1 VALUES('+',9); INSERT INTO t1 VALUES('+12347.E+02',10); INSERT INTO t1 VALUES('+12347E+02',11); - SELECT b FROM t1 ORDER BY a; + INSERT INTO t1 VALUES('+.125E+04',12); + INSERT INTO t1 VALUES('-.125E+04',13); + INSERT INTO t1 VALUES('.125E+0',14); + INSERT INTO t1 VALUES('.125',15); + SELECT b FROM t1 ORDER BY a, b; } -} {8 5 2 1 3 6 11 9 10 4 7} -integrity_check index-15.1 +} {13 14 15 12 8 5 2 1 3 6 10 11 9 4 7} +do_test index-15.3 { + execsql { + SELECT b FROM t1 WHERE typeof(a) IN ('integer','real') ORDER BY b; + } +} {1 2 3 5 6 8 10 11 12 13 14 15} +integrity_check index-15.4 # The following tests - index-16.* - test that when a table definition # includes qualifications that specify the same constraint twice only a diff --git a/test/tkt-3998683a16.test b/test/tkt-3998683a16.test new file mode 100644 index 0000000000..919dc23368 --- /dev/null +++ b/test/tkt-3998683a16.test @@ -0,0 +1,46 @@ +# 2010 September 30 +# +# 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 implements regression tests for SQLite library. Specifically, +# it tests that ticket [3998683a16a7076e08f5585c1f4816414c8c653a] where in +# floating point values with a decimal point at the beginning or end +# of the mantissa are used. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl + +do_test tkt-3998683a16.1 { + db eval { + CREATE TABLE t1(x, y REAL); + INSERT INTO t1 VALUES(1, '1.0'); + INSERT INTO t1 VALUES(2, '.125'); + INSERT INTO t1 VALUES(3, '123.'); + INSERT INTO t1 VALUES(4, '123.e+2'); + INSERT INTO t1 VALUES(5, '.125e+3'); + INSERT INTO t1 VALUES(6, '123e4'); + INSERT INTO t1 VALUES(11, ' 1.0'); + INSERT INTO t1 VALUES(12, ' .125'); + INSERT INTO t1 VALUES(13, ' 123.'); + INSERT INTO t1 VALUES(14, ' 123.e+2'); + INSERT INTO t1 VALUES(15, ' .125e+3'); + INSERT INTO t1 VALUES(16, ' 123e4'); + INSERT INTO t1 VALUES(21, '1.0 '); + INSERT INTO t1 VALUES(22, '.125 '); + INSERT INTO t1 VALUES(23, '123. '); + INSERT INTO t1 VALUES(24, '123.e+2 '); + INSERT INTO t1 VALUES(25, '.125e+3 '); + INSERT INTO t1 VALUES(26, '123e4 '); + SELECT x FROM t1 WHERE typeof(y)=='real' ORDER BY x; + } +} {1 2 3 4 5 6 11 12 13 14 15 16 21 22 23 24 25 26} + +finish_test From 6b8705657030299a735de2ce525f995b2e0c418c Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 30 Sep 2010 18:12:01 +0000 Subject: [PATCH 5/8] Remove unnecessary calls to memAboutToChange() in vdbe.c. An affinity change no longer invalidates shallow copies. FossilOrigin-Name: afb0fd0b0421c42630c5e6e5e8811aca634bc9d0 --- manifest | 18 +++++++++--------- manifest.uuid | 2 +- src/vdbe.c | 8 -------- 3 files changed, 10 insertions(+), 18 deletions(-) diff --git a/manifest b/manifest index 607886fbf2..8e2bfc803b 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,8 @@ -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 -C Do\scorrect\saffinity\stransformations\son\sfloating\spoint\svalues\swhich\shave\na\sdecimal\spoint\sat\sthe\sbeginning\sor\send\sof\sthe\smantissa.\nTicket\s[3998683a16a7076e08f5]. -D 2010-09-30T17:33:12 +C Remove\sunnecessary\scalls\sto\smemAboutToChange()\sin\svdbe.c.\s\sAn\saffinity\nchange\sno\slonger\sinvalidates\sshallow\scopies. +D 2010-09-30T18:12:02 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in c599a15d268b1db2aeadea19df2adc3bf2eb6bee F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -228,7 +228,7 @@ F src/update.c 227e6cd512108b84f69421fc6c7aa1b83d60d6e0 F src/utf.c 1baeeac91707a4df97ccc6141ec0f808278af685 F src/util.c cd78524566fe45671863eee78685969a4bfd4e4c F src/vacuum.c 924bd1bcee2dfb05376f79845bd3b4cec7b54b2f -F src/vdbe.c 447577ca9db7cccac30dd8ea07aeb6a4ddee9cde +F src/vdbe.c e1aa917961e69f71c80f46ce231b496d3c841ae1 F src/vdbe.h 4de0efb4b0fdaaa900cf419b35c458933ef1c6d2 F src/vdbeInt.h 7f4cf1b2b69bef3a432b1f23dfebef57275436b4 F src/vdbeapi.c 03cddfa4f85cadf608c0d28ff6b622b7da432446 @@ -874,14 +874,14 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P 43fef1cab6315f837782ea601d5a2aeb9843ab3c -R 9f0571eacddb9a3dd22902b2fc6da09d +P ca154f97a590745539b2cbfd77eb319fd7392a40 +R 748449bce6ae506eaa073ea594abdada U drh -Z c3bfcfff0e351511af94c6133a9e5932 +Z 093ac075ab4b1886bb1eccb584418581 -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.6 (GNU/Linux) -iD8DBQFMpMncoxKgR168RlERApVjAJ9CgWo7czjJJMuzPPhDGIuxcWDpSACeLMY+ -2nv8gkZ9kYhTsRmCj46G7ik= -=tJZ/ +iD8DBQFMpNL1oxKgR168RlERAjjtAJ4+t7sulYFx05+58t1+K8swwMqAWQCfbEoM +G6/RegdDSppspf4YTh1aD/Y= +=7FrQ -----END PGP SIGNATURE----- diff --git a/manifest.uuid b/manifest.uuid index 8e6154f471..e03860e931 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ca154f97a590745539b2cbfd77eb319fd7392a40 \ No newline at end of file +afb0fd0b0421c42630c5e6e5e8811aca634bc9d0 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 7718516faa..02d1a406c9 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -1541,7 +1541,6 @@ case OP_MustBeInt: { /* jump, in1 */ */ case OP_RealAffinity: { /* in1 */ pIn1 = &aMem[pOp->p1]; - memAboutToChange(p, pIn1); if( pIn1->flags & MEM_Int ){ sqlite3VdbeMemRealify(pIn1); } @@ -1584,7 +1583,6 @@ case OP_ToText: { /* same as TK_TO_TEXT, in1 */ */ case OP_ToBlob: { /* same as TK_TO_BLOB, in1 */ pIn1 = &aMem[pOp->p1]; - memAboutToChange(p, pIn1); if( pIn1->flags & MEM_Null ) break; if( (pIn1->flags & MEM_Blob)==0 ){ applyAffinity(pIn1, SQLITE_AFF_TEXT, encoding); @@ -1609,7 +1607,6 @@ case OP_ToBlob: { /* same as TK_TO_BLOB, in1 */ */ case OP_ToNumeric: { /* same as TK_TO_NUMERIC, in1 */ pIn1 = &aMem[pOp->p1]; - memAboutToChange(p, pIn1); sqlite3VdbeMemNumerify(pIn1); break; } @@ -1626,7 +1623,6 @@ case OP_ToNumeric: { /* same as TK_TO_NUMERIC, in1 */ */ case OP_ToInt: { /* same as TK_TO_INT, in1 */ pIn1 = &aMem[pOp->p1]; - memAboutToChange(p, pIn1); if( (pIn1->flags & MEM_Null)==0 ){ sqlite3VdbeMemIntegerify(pIn1); } @@ -1738,8 +1734,6 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */ pIn1 = &aMem[pOp->p1]; pIn3 = &aMem[pOp->p3]; - memAboutToChange(p, pIn1); - memAboutToChange(p, pIn3); flags1 = pIn1->flags; flags3 = pIn3->flags; if( (pIn1->flags | pIn3->flags)&MEM_Null ){ @@ -2362,7 +2356,6 @@ case OP_Affinity: { while( (cAff = *(zAffinity++))!=0 ){ assert( pIn1 <= &p->aMem[p->nMem] ); assert( memIsValid(pIn1) ); - memAboutToChange(p, pIn1); ExpandBlob(pIn1); applyAffinity(pIn1, cAff, encoding); pIn1++; @@ -2440,7 +2433,6 @@ case OP_MakeRecord: { for(pRec=pData0; pRec<=pLast; pRec++){ assert( memIsValid(pRec) ); if( zAffinity ){ - memAboutToChange(p, pRec); applyAffinity(pRec, zAffinity[pRec-pData0], encoding); } if( pRec->flags&MEM_Zero && pRec->n>0 ){ From 9fc47111f0458e9b4ff1d4773f1753dbde1b05bd Mon Sep 17 00:00:00 2001 From: shaneh Date: Thu, 30 Sep 2010 18:19:44 +0000 Subject: [PATCH 6/8] Additional encoding tests. FossilOrigin-Name: c7f9363617a66ee43a87816ad42aaf2b75f13ea2 --- manifest | 23 +++------ manifest.uuid | 2 +- test/enc4.test | 124 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 132 insertions(+), 17 deletions(-) create mode 100644 test/enc4.test diff --git a/manifest b/manifest index 8e2bfc803b..8a21045b64 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,5 @@ ------BEGIN PGP SIGNED MESSAGE----- -Hash: SHA1 - -C Remove\sunnecessary\scalls\sto\smemAboutToChange()\sin\svdbe.c.\s\sAn\saffinity\nchange\sno\slonger\sinvalidates\sshallow\scopies. -D 2010-09-30T18:12:02 +C Additional\sencoding\stests. +D 2010-09-30T18:19:44 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in c599a15d268b1db2aeadea19df2adc3bf2eb6bee F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -365,6 +362,7 @@ F test/e_vacuum.test 057cc29445746fc1d2542984ff0253d511a234bd F test/enc.test e54531cd6bf941ee6760be041dff19a104c7acea F test/enc2.test 6d91a5286f59add0cfcbb2d0da913b76f2242398 F test/enc3.test 5c550d59ff31dccdba5d1a02ae11c7047d77c041 +F test/enc4.test f77a8172fc789f346f8cfaa201969d9251855ab2 F test/eval.test bc269c365ba877554948441e91ad5373f9f91be3 F test/exclusive.test 0ba00fb15aeec1eba3d4b03a271b5081e21c35be F test/exclusive2.test 76e63c05349cb70d09d60b99d2ae625525ff5155 @@ -874,14 +872,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P ca154f97a590745539b2cbfd77eb319fd7392a40 -R 748449bce6ae506eaa073ea594abdada -U drh -Z 093ac075ab4b1886bb1eccb584418581 ------BEGIN PGP SIGNATURE----- -Version: GnuPG v1.4.6 (GNU/Linux) - -iD8DBQFMpNL1oxKgR168RlERAjjtAJ4+t7sulYFx05+58t1+K8swwMqAWQCfbEoM -G6/RegdDSppspf4YTh1aD/Y= -=7FrQ ------END PGP SIGNATURE----- +P afb0fd0b0421c42630c5e6e5e8811aca634bc9d0 +R cd06bfdd4d6b826a69cbc7d431c4e132 +U shaneh +Z 43d49001f03bba36add05ffc6539647c diff --git a/manifest.uuid b/manifest.uuid index e03860e931..af001fec10 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -afb0fd0b0421c42630c5e6e5e8811aca634bc9d0 \ No newline at end of file +c7f9363617a66ee43a87816ad42aaf2b75f13ea2 \ No newline at end of file diff --git a/test/enc4.test b/test/enc4.test new file mode 100644 index 0000000000..f8403c30fc --- /dev/null +++ b/test/enc4.test @@ -0,0 +1,124 @@ +# 2010 Sept 29 +# +# 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 implements regression tests for SQLite library. The focus of +# this file is testing the SQLite routines used for converting between the +# various suported unicode encodings (UTF-8, UTF-16, UTF-16le and +# UTF-16be). +# +# $Id: enc4.test,v 1.0 2010/09/29 08:29:32 shaneh Exp $ + +set testdir [file dirname $argv0] +source $testdir/tester.tcl + +# If UTF16 support is disabled, ignore the tests in this file +# +ifcapable {!utf16} { + finish_test + return +} + +db close + +# The three unicode encodings understood by SQLite. +set encodings [list UTF-8 UTF-16le UTF-16be] + +# initial value to use in SELECT +set inits [list 1 1.0] + +# vals +set vals [list\ +"922337203685477580792233720368547758079223372036854775807"\ +"100000000000000000000000000000000000000000000000000000000"\ +"1.0000000000000000000000000000000000000000000000000000000"\ +] + +set i 1 +foreach enc $encodings { + + file delete -force test.db + sqlite3 db test.db + db eval "PRAGMA encoding = \"$enc\"" + + do_test enc4-$i.1 { + db eval {PRAGMA encoding} + } $enc + + set j 1 + foreach init $inits { + + do_test enc4-$i.$j.2 { + set S [sqlite3_prepare_v2 db "SELECT $init+?" -1 dummy] + sqlite3_expired $S + } {0} + + set k 1 + foreach val $vals { + for {set x 1} {$x<18} {incr x} { + set part [expr $init + [string range $val 0 [expr $x-1]]] + + do_test enc4-$i.$j.$k.3.$x { + sqlite3_reset $S + sqlite3_bind_text $S 1 $val $x + sqlite3_step $S + sqlite3_column_text $S 0 + } [list $part] + + do_test enc4-$i.$j.$k.4.$x { + sqlite3_reset $S + sqlite3_bind_text16 $S 1 [encoding convertto unicode $val] [expr $x*2] + sqlite3_step $S + sqlite3_column_text $S 0 + } [list $part] + } + + incr k + } + + do_test enc4-$i.$j.5 { + sqlite3_finalize $S + } {SQLITE_OK} + + incr j + } + + db close + incr i +} + +file delete -force test.db +sqlite3 db test.db + +do_test enc4-4.1 { + db eval "select 1+1." +} {2.0} + +do_test enc4-4.2 { + set S [sqlite3_prepare_v2 db "SELECT 1+1." -1 dummy] + sqlite3_step $S + sqlite3_column_text $S 0 +} {2.0} + +do_test enc4-4.3 { + set S [sqlite3_prepare_v2 db "SELECT 1+?" -1 dummy] + sqlite3_bind_text $S 1 "1." 2 + sqlite3_step $S + sqlite3_column_text $S 0 +} {2.0} + +do_test enc4-4.4 { + set S [sqlite3_prepare_v2 db "SELECT 1+?" -1 dummy] + sqlite3_bind_text $S 1 "1.0" 2 + sqlite3_step $S + sqlite3_column_text $S 0 +} {2.0} + + +finish_test From 0246dced24e525b8b9027bbb936f1fadbfa640c2 Mon Sep 17 00:00:00 2001 From: shaneh Date: Thu, 30 Sep 2010 18:30:17 +0000 Subject: [PATCH 7/8] Fix memory leak in enc4.test script. FossilOrigin-Name: bfc294ae437e02984c08d47bed7b7fb49b71a1c2 --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/enc4.test | 21 +++++++++++++++++---- 3 files changed, 24 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 8a21045b64..d27205cf36 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Additional\sencoding\stests. -D 2010-09-30T18:19:44 +C Fix\smemory\sleak\sin\senc4.test\sscript. +D 2010-09-30T18:30:18 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in c599a15d268b1db2aeadea19df2adc3bf2eb6bee F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -362,7 +362,7 @@ F test/e_vacuum.test 057cc29445746fc1d2542984ff0253d511a234bd F test/enc.test e54531cd6bf941ee6760be041dff19a104c7acea F test/enc2.test 6d91a5286f59add0cfcbb2d0da913b76f2242398 F test/enc3.test 5c550d59ff31dccdba5d1a02ae11c7047d77c041 -F test/enc4.test f77a8172fc789f346f8cfaa201969d9251855ab2 +F test/enc4.test bd6e3543d9a7758edbd1bed0871326f001583418 F test/eval.test bc269c365ba877554948441e91ad5373f9f91be3 F test/exclusive.test 0ba00fb15aeec1eba3d4b03a271b5081e21c35be F test/exclusive2.test 76e63c05349cb70d09d60b99d2ae625525ff5155 @@ -872,7 +872,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P afb0fd0b0421c42630c5e6e5e8811aca634bc9d0 -R cd06bfdd4d6b826a69cbc7d431c4e132 +P c7f9363617a66ee43a87816ad42aaf2b75f13ea2 +R f57941c58a3f28e9d056eb0ddaa57ab8 U shaneh -Z 43d49001f03bba36add05ffc6539647c +Z 08306689a2b387b72cdadc0bc128e945 diff --git a/manifest.uuid b/manifest.uuid index af001fec10..128f2f3ab4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c7f9363617a66ee43a87816ad42aaf2b75f13ea2 \ No newline at end of file +bfc294ae437e02984c08d47bed7b7fb49b71a1c2 \ No newline at end of file diff --git a/test/enc4.test b/test/enc4.test index f8403c30fc..bf3bea268f 100644 --- a/test/enc4.test +++ b/test/enc4.test @@ -31,7 +31,7 @@ db close set encodings [list UTF-8 UTF-16le UTF-16be] # initial value to use in SELECT -set inits [list 1 1.0] +set inits [list 1 1.0 1. 1e0] # vals set vals [list\ @@ -100,25 +100,38 @@ do_test enc4-4.1 { db eval "select 1+1." } {2.0} -do_test enc4-4.2 { +do_test enc4-4.2.1 { set S [sqlite3_prepare_v2 db "SELECT 1+1." -1 dummy] sqlite3_step $S sqlite3_column_text $S 0 } {2.0} -do_test enc4-4.3 { +do_test enc4-4.2.2 { + sqlite3_finalize $S +} {SQLITE_OK} + +do_test enc4-4.3.1 { set S [sqlite3_prepare_v2 db "SELECT 1+?" -1 dummy] sqlite3_bind_text $S 1 "1." 2 sqlite3_step $S sqlite3_column_text $S 0 } {2.0} -do_test enc4-4.4 { +do_test enc4-4.3.2 { + sqlite3_finalize $S +} {SQLITE_OK} + +do_test enc4-4.4.1 { set S [sqlite3_prepare_v2 db "SELECT 1+?" -1 dummy] sqlite3_bind_text $S 1 "1.0" 2 sqlite3_step $S sqlite3_column_text $S 0 } {2.0} +do_test enc4-4.4.2 { + sqlite3_finalize $S +} {SQLITE_OK} + +db close finish_test From a03a0563c1a74c49f6a9a4f6ea8d12f6a8843273 Mon Sep 17 00:00:00 2001 From: shaneh Date: Thu, 30 Sep 2010 20:11:24 +0000 Subject: [PATCH 8/8] Fix some matching issues in enc4.test affected by TCL versions. FossilOrigin-Name: dd6d61a967e3c0d98b78987f6f7bb9bdf090174e --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/enc4.test | 2 ++ 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index d27205cf36..8bc640343f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\smemory\sleak\sin\senc4.test\sscript. -D 2010-09-30T18:30:18 +C Fix\ssome\smatching\sissues\sin\senc4.test\saffected\sby\sTCL\sversions. +D 2010-09-30T20:11:24 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in c599a15d268b1db2aeadea19df2adc3bf2eb6bee F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -362,7 +362,7 @@ F test/e_vacuum.test 057cc29445746fc1d2542984ff0253d511a234bd F test/enc.test e54531cd6bf941ee6760be041dff19a104c7acea F test/enc2.test 6d91a5286f59add0cfcbb2d0da913b76f2242398 F test/enc3.test 5c550d59ff31dccdba5d1a02ae11c7047d77c041 -F test/enc4.test bd6e3543d9a7758edbd1bed0871326f001583418 +F test/enc4.test 4b575ef09e0eff896e73bd24076f96c2aa6a42de F test/eval.test bc269c365ba877554948441e91ad5373f9f91be3 F test/exclusive.test 0ba00fb15aeec1eba3d4b03a271b5081e21c35be F test/exclusive2.test 76e63c05349cb70d09d60b99d2ae625525ff5155 @@ -872,7 +872,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P c7f9363617a66ee43a87816ad42aaf2b75f13ea2 -R f57941c58a3f28e9d056eb0ddaa57ab8 +P bfc294ae437e02984c08d47bed7b7fb49b71a1c2 +R 7552db8dcb12c2a18499c922a224a015 U shaneh -Z 08306689a2b387b72cdadc0bc128e945 +Z 32c63a4384668fcaade4669548caae85 diff --git a/manifest.uuid b/manifest.uuid index 128f2f3ab4..d64876130f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bfc294ae437e02984c08d47bed7b7fb49b71a1c2 \ No newline at end of file +dd6d61a967e3c0d98b78987f6f7bb9bdf090174e \ No newline at end of file diff --git a/test/enc4.test b/test/enc4.test index bf3bea268f..de2a1b88d0 100644 --- a/test/enc4.test +++ b/test/enc4.test @@ -63,6 +63,8 @@ foreach enc $encodings { foreach val $vals { for {set x 1} {$x<18} {incr x} { set part [expr $init + [string range $val 0 [expr $x-1]]] + regsub {e\+0} $part {e+} part + regsub {^1e} $part {1.0e} part do_test enc4-$i.$j.$k.3.$x { sqlite3_reset $S