/ Check-in [14eed3a0]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment: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.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | experimental
Files: files | file ages | folders
SHA1: 14eed3a0e0a45c6f2904a3a134aa27c159916f7b
User & Date: drh 2010-09-30 00:50:50
Context
2010-09-30
14:48
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] check-in: ce6cc16e user: drh tags: experimental
00:50
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. check-in: 14eed3a0 user: drh tags: experimental
2010-09-29
18:26
Add test cases to e_createtable.test. check-in: f34dc54d user: dan tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/date.c.

   129    129       cnt++;
   130    130     }while( nextC );
   131    131   end_getDigits:
   132    132     va_end(ap);
   133    133     return cnt;
   134    134   }
   135    135   
   136         -/*
   137         -** Read text from z[] and convert into a floating point number.  Return
   138         -** the number of digits converted.
   139         -*/
   140         -#define getValue sqlite3AtoF
   141         -
   142    136   /*
   143    137   ** Parse a timezone extension on the end of a date-time.
   144    138   ** The extension is of the form:
   145    139   **
   146    140   **        (+/-)HH:MM
   147    141   **
   148    142   ** Or the "zulu" notation:
................................................................................
   336    330   ** as there is a year and date.
   337    331   */
   338    332   static int parseDateOrTime(
   339    333     sqlite3_context *context, 
   340    334     const char *zDate, 
   341    335     DateTime *p
   342    336   ){
   343         -  int isRealNum;    /* Return from sqlite3IsNumber().  Not used */
          337  +  double r;
   344    338     if( parseYyyyMmDd(zDate,p)==0 ){
   345    339       return 0;
   346    340     }else if( parseHhMmSs(zDate, p)==0 ){
   347    341       return 0;
   348    342     }else if( sqlite3StrICmp(zDate,"now")==0){
   349    343       setDateTimeToCurrent(context, p);
   350    344       return 0;
   351         -  }else if( sqlite3IsNumber(zDate, &isRealNum, SQLITE_UTF8) ){
   352         -    double r;
   353         -    getValue(zDate, &r);
          345  +  }else if( sqlite3AtoF(zDate, &r, sqlite3Strlen30(zDate), SQLITE_UTF8) ){
   354    346       p->iJD = (sqlite3_int64)(r*86400000.0 + 0.5);
   355    347       p->validJD = 1;
   356    348       return 0;
   357    349     }
   358    350     return 1;
   359    351   }
   360    352   
................................................................................
   567    559         /*
   568    560         **    weekday N
   569    561         **
   570    562         ** Move the date to the same time on the next occurrence of
   571    563         ** weekday N where 0==Sunday, 1==Monday, and so forth.  If the
   572    564         ** date is already on the appropriate weekday, this is a no-op.
   573    565         */
   574         -      if( strncmp(z, "weekday ", 8)==0 && getValue(&z[8],&r)>0
   575         -                 && (n=(int)r)==r && n>=0 && r<7 ){
          566  +      if( strncmp(z, "weekday ", 8)==0
          567  +               && sqlite3AtoF(&z[8], &r, sqlite3Strlen30(&z[8]), SQLITE_UTF8)
          568  +               && (n=(int)r)==r && n>=0 && r<7 ){
   576    569           sqlite3_int64 Z;
   577    570           computeYMD_HMS(p);
   578    571           p->validTZ = 0;
   579    572           p->validJD = 0;
   580    573           computeJD(p);
   581    574           Z = ((p->iJD + 129600000)/86400000) % 7;
   582    575           if( Z>n ) Z -= 7;
................................................................................
   623    616       case '4':
   624    617       case '5':
   625    618       case '6':
   626    619       case '7':
   627    620       case '8':
   628    621       case '9': {
   629    622         double rRounder;
   630         -      n = getValue(z, &r);
   631         -      assert( n>=1 );
          623  +      for(n=1; z[n] && z[n]!=':' && !sqlite3Isspace(z[n]); n++){}
          624  +      if( !sqlite3AtoF(z, &r, n, SQLITE_UTF8) ){
          625  +        rc = 1;
          626  +        break;
          627  +      }
   632    628         if( z[n]==':' ){
   633    629           /* A modifier of the form (+|-)HH:MM:SS.FFF adds (or subtracts) the
   634    630           ** specified number of hours, minutes, seconds, and fractional seconds
   635    631           ** to the time.  The ".FFF" may be omitted.  The ":SS.FFF" may be
   636    632           ** omitted.
   637    633           */
   638    634           const char *z2 = z;

Changes to src/expr.c.

   551    551       /* Wildcard of the form "?".  Assign the next variable number */
   552    552       assert( z[0]=='?' );
   553    553       pExpr->iColumn = (ynVar)(++pParse->nVar);
   554    554     }else if( z[0]=='?' ){
   555    555       /* Wildcard of the form "?nnn".  Convert "nnn" to an integer and
   556    556       ** use it as the variable number */
   557    557       i64 i;
   558         -    int bOk = sqlite3Atoi64(&z[1], &i);
          558  +    int bOk = sqlite3Atoi64(&z[1], &i, sqlite3Strlen30(&z[1]), SQLITE_UTF8);
   559    559       pExpr->iColumn = (ynVar)i;
   560    560       testcase( i==0 );
   561    561       testcase( i==1 );
   562    562       testcase( i==db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER]-1 );
   563    563       testcase( i==db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] );
   564    564       if( bOk==0 || i<1 || i>db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ){
   565    565         sqlite3ErrorMsg(pParse, "variable number must be between ?1 and ?%d",
................................................................................
  1914   1914   ** z[n] character is guaranteed to be something that does not look
  1915   1915   ** like the continuation of the number.
  1916   1916   */
  1917   1917   static void codeReal(Vdbe *v, const char *z, int negateFlag, int iMem){
  1918   1918     if( ALWAYS(z!=0) ){
  1919   1919       double value;
  1920   1920       char *zV;
  1921         -    sqlite3AtoF(z, &value);
         1921  +    sqlite3AtoF(z, &value, sqlite3Strlen30(z), SQLITE_UTF8);
  1922   1922       assert( !sqlite3IsNaN(value) ); /* The new AtoF never returns NaN */
  1923   1923       if( negateFlag ) value = -value;
  1924   1924       zV = dup8bytes(v, (char*)&value);
  1925   1925       sqlite3VdbeAddOp4(v, OP_Real, 0, iMem, 0, zV, P4_REAL);
  1926   1926     }
  1927   1927   }
  1928   1928   #endif
................................................................................
  1944   1944       sqlite3VdbeAddOp2(v, OP_Integer, i, iMem);
  1945   1945     }else{
  1946   1946       const char *z = pExpr->u.zToken;
  1947   1947       assert( z!=0 );
  1948   1948       if( sqlite3FitsIn64Bits(z, negFlag) ){
  1949   1949         i64 value;
  1950   1950         char *zV;
  1951         -      sqlite3Atoi64(z, &value);
         1951  +      sqlite3Atoi64(z, &value, sqlite3Strlen30(z), SQLITE_UTF8);
  1952   1952         if( negFlag ) value = -value;
  1953   1953         zV = dup8bytes(v, (char*)&value);
  1954   1954         sqlite3VdbeAddOp4(v, OP_Int64, 0, iMem, 0, zV, P4_INT64);
  1955   1955       }else{
  1956   1956   #ifdef SQLITE_OMIT_FLOATING_POINT
  1957   1957         sqlite3ErrorMsg(pParse, "oversized integer: %s%s", negFlag ? "-" : "", z);
  1958   1958   #else

Changes to src/func.c.

   281    281       r = -(double)((sqlite_int64)((-r)+0.5));
   282    282     }else{
   283    283       zBuf = sqlite3_mprintf("%.*f",n,r);
   284    284       if( zBuf==0 ){
   285    285         sqlite3_result_error_nomem(context);
   286    286         return;
   287    287       }
   288         -    sqlite3AtoF(zBuf, &r);
          288  +    sqlite3AtoF(zBuf, &r, sqlite3Strlen30(zBuf), SQLITE_UTF8);
   289    289       sqlite3_free(zBuf);
   290    290     }
   291    291     sqlite3_result_double(context, r);
   292    292   }
   293    293   #endif
   294    294   
   295    295   /*

Changes to src/pragma.c.

   583    583     **
   584    584     ** Get or set the size limit on rollback journal files.
   585    585     */
   586    586     if( sqlite3StrICmp(zLeft,"journal_size_limit")==0 ){
   587    587       Pager *pPager = sqlite3BtreePager(pDb->pBt);
   588    588       i64 iLimit = -2;
   589    589       if( zRight ){
   590         -      sqlite3Atoi64(zRight, &iLimit);
          590  +      sqlite3Atoi64(zRight, &iLimit, 1000000, SQLITE_UTF8);
   591    591         if( iLimit<-1 ) iLimit = -1;
   592    592       }
   593    593       iLimit = sqlite3PagerJournalSizeLimit(pPager, iLimit);
   594    594       returnSingleInt(pParse, "journal_size_limit", iLimit);
   595    595     }else
   596    596   
   597    597   #endif /* SQLITE_OMIT_PAGER_PRAGMAS */

Changes to src/sqliteInt.h.

  2503   2503   # define sqlite3Tolower(x)   tolower((unsigned char)(x))
  2504   2504   #endif
  2505   2505   
  2506   2506   /*
  2507   2507   ** Internal function prototypes
  2508   2508   */
  2509   2509   int sqlite3StrICmp(const char *, const char *);
  2510         -int sqlite3IsNumber(const char*, int*, u8);
  2511   2510   int sqlite3Strlen30(const char*);
  2512   2511   #define sqlite3StrNICmp sqlite3_strnicmp
  2513   2512   
  2514   2513   int sqlite3MallocInit(void);
  2515   2514   void sqlite3MallocEnd(void);
  2516   2515   void *sqlite3Malloc(int);
  2517   2516   void *sqlite3MallocZero(int);
................................................................................
  2823   2822   void sqlite3Detach(Parse*, Expr*);
  2824   2823   int sqlite3FixInit(DbFixer*, Parse*, int, const char*, const Token*);
  2825   2824   int sqlite3FixSrcList(DbFixer*, SrcList*);
  2826   2825   int sqlite3FixSelect(DbFixer*, Select*);
  2827   2826   int sqlite3FixExpr(DbFixer*, Expr*);
  2828   2827   int sqlite3FixExprList(DbFixer*, ExprList*);
  2829   2828   int sqlite3FixTriggerStep(DbFixer*, TriggerStep*);
  2830         -int sqlite3AtoF(const char *z, double*);
         2829  +int sqlite3AtoF(const char *z, double*, int, u8);
  2831   2830   int sqlite3GetInt32(const char *, int*);
  2832   2831   int sqlite3FitsIn64Bits(const char *, int);
  2833   2832   int sqlite3Utf16ByteLen(const void *pData, int nChar);
  2834   2833   int sqlite3Utf8CharLen(const char *pData, int nByte);
  2835   2834   int sqlite3Utf8Read(const u8*, const u8**);
  2836   2835   
  2837   2836   /*
................................................................................
  2871   2870   
  2872   2871   
  2873   2872   const char *sqlite3IndexAffinityStr(Vdbe *, Index *);
  2874   2873   void sqlite3TableAffinityStr(Vdbe *, Table *);
  2875   2874   char sqlite3CompareAffinity(Expr *pExpr, char aff2);
  2876   2875   int sqlite3IndexAffinityOk(Expr *pExpr, char idx_affinity);
  2877   2876   char sqlite3ExprAffinity(Expr *pExpr);
  2878         -int sqlite3Atoi64(const char*, i64*);
         2877  +int sqlite3Atoi64(const char*, i64*, int, u8);
  2879   2878   void sqlite3Error(sqlite3*, int, const char*,...);
  2880   2879   void *sqlite3HexToBlob(sqlite3*, const char *z, int n);
  2881   2880   int sqlite3TwoPartName(Parse *, Token *, Token *, Token **);
  2882   2881   const char *sqlite3ErrStr(int);
  2883   2882   int sqlite3ReadSchema(Parse *pParse);
  2884   2883   CollSeq *sqlite3FindCollSeq(sqlite3*,u8 enc, const char*,int);
  2885   2884   CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char*zName);

Changes to src/test1.c.

  1231   1231     char *z;
  1232   1232     if( argc!=5 ){
  1233   1233       Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
  1234   1234          " FORMAT INT INT INT\"", 0);
  1235   1235       return TCL_ERROR;
  1236   1236     }
  1237   1237     for(i=2; i<5; i++){
  1238         -    if( !sqlite3Atoi64(argv[i], &a[i-2]) ){
         1238  +    if( !sqlite3Atoi64(argv[i], &a[i-2], 1000000, SQLITE_UTF8) ){
  1239   1239         Tcl_AppendResult(interp, "argument is not a valid 64-bit integer", 0);
  1240   1240         return TCL_ERROR;
  1241   1241       }
  1242   1242     }
  1243   1243     z = sqlite3_mprintf(argv[1], a[0], a[1], a[2]);
  1244   1244     Tcl_AppendResult(interp, z, 0);
  1245   1245     sqlite3_free(z);

Changes to src/util.c.

   234    234     a = (unsigned char *)zLeft;
   235    235     b = (unsigned char *)zRight;
   236    236     while( N-- > 0 && *a!=0 && UpperToLower[*a]==UpperToLower[*b]){ a++; b++; }
   237    237     return N<0 ? 0 : UpperToLower[*a] - UpperToLower[*b];
   238    238   }
   239    239   
   240    240   /*
   241         -** Return TRUE if z is a pure numeric string.  Return FALSE and leave
   242         -** *realnum unchanged if the string contains any character which is not
   243         -** part of a number.
   244         -**
   245         -** If the string is pure numeric, set *realnum to TRUE if the string
   246         -** contains the '.' character or an "E+000" style exponentiation suffix.
   247         -** Otherwise set *realnum to FALSE.  Note that just becaue *realnum is
   248         -** false does not mean that the number can be successfully converted into
   249         -** an integer - it might be too big.
   250         -**
   251         -** An empty string is considered non-numeric.
   252         -*/
   253         -int sqlite3IsNumber(const char *z, int *realnum, u8 enc){
   254         -  int incr = (enc==SQLITE_UTF8?1:2);
   255         -  if( enc==SQLITE_UTF16BE ) z++;
   256         -  if( *z=='-' || *z=='+' ) z += incr;
   257         -  if( !sqlite3Isdigit(*z) ){
   258         -    return 0;
   259         -  }
   260         -  z += incr;
   261         -  *realnum = 0;
   262         -  while( sqlite3Isdigit(*z) ){ z += incr; }
   263         -#ifndef SQLITE_OMIT_FLOATING_POINT
   264         -  if( *z=='.' ){
   265         -    z += incr;
   266         -    if( !sqlite3Isdigit(*z) ) return 0;
   267         -    while( sqlite3Isdigit(*z) ){ z += incr; }
   268         -    *realnum = 1;
   269         -  }
   270         -  if( *z=='e' || *z=='E' ){
   271         -    z += incr;
   272         -    if( *z=='+' || *z=='-' ) z += incr;
   273         -    if( !sqlite3Isdigit(*z) ) return 0;
   274         -    while( sqlite3Isdigit(*z) ){ z += incr; }
   275         -    *realnum = 1;
   276         -  }
   277         -#endif
   278         -  return *z==0;
   279         -}
   280         -
   281         -/*
   282         -** The string z[] is an ASCII representation of a real number.
          241  +** The string z[] is an text representation of a real number.
   283    242   ** Convert this string to a double.
   284    243   **
   285         -** This routine assumes that z[] really is a valid number.  If it
   286         -** is not, the result is undefined.
          244  +** The string z[] is length bytes in length (bytes, not characters) and
          245  +** uses the encoding enc.  The string is not necessarily zero-terminated.
   287    246   **
   288         -** This routine is used instead of the library atof() function because
   289         -** the library atof() might want to use "," as the decimal point instead
   290         -** of "." depending on how locale is set.  But that would cause problems
   291         -** for SQL.  So this routine always uses "." regardless of locale.
          247  +** Return TRUE if the result is a valid real number (or integer) and FALSE
          248  +** if the string is empty or contains extraneous text.
   292    249   */
   293         -int sqlite3AtoF(const char *z, double *pResult){
          250  +int sqlite3AtoF(const char *z, double *pResult, int length, u8 enc){
   294    251   #ifndef SQLITE_OMIT_FLOATING_POINT
   295         -  const char *zBegin = z;
          252  +  int incr = (enc==SQLITE_UTF8?1:2);
          253  +  const char *zEnd = z + length;
   296    254     /* sign * significand * (10 ^ (esign * exponent)) */
   297    255     int sign = 1;   /* sign of significand */
   298    256     i64 s = 0;      /* significand */
   299    257     int d = 0;      /* adjust exponent for shifting decimal point */
   300    258     int esign = 1;  /* sign of exponent */
   301    259     int e = 0;      /* exponent */
   302    260     double result;
   303    261     int nDigits = 0;
   304    262   
          263  +  if( enc==SQLITE_UTF16BE ) z++;
          264  +
   305    265     /* skip leading spaces */
   306         -  while( sqlite3Isspace(*z) ) z++;
          266  +  while( z<zEnd && sqlite3Isspace(*z) ) z+=incr;
          267  +  if( z>=zEnd ){
          268  +    *pResult = 0.0;
          269  +    return 0;
          270  +  }
          271  +
   307    272     /* get sign of significand */
   308    273     if( *z=='-' ){
   309    274       sign = -1;
   310         -    z++;
          275  +    z+=incr;
   311    276     }else if( *z=='+' ){
   312         -    z++;
          277  +    z+=incr;
   313    278     }
          279  +
   314    280     /* skip leading zeroes */
   315         -  while( z[0]=='0' ) z++, nDigits++;
          281  +  while( z<zEnd && z[0]=='0' ) z+=incr, nDigits++;
   316    282   
   317    283     /* copy max significant digits to significand */
   318         -  while( sqlite3Isdigit(*z) && s<((LARGEST_INT64-9)/10) ){
          284  +  while( z<zEnd && sqlite3Isdigit(*z) && s<((LARGEST_INT64-9)/10) ){
   319    285       s = s*10 + (*z - '0');
   320         -    z++, nDigits++;
          286  +    z+=incr, nDigits++;
   321    287     }
          288  +
   322    289     /* skip non-significant significand digits
   323    290     ** (increase exponent by d to shift decimal left) */
   324         -  while( sqlite3Isdigit(*z) ) z++, nDigits++, d++;
          291  +  while( z<zEnd && sqlite3Isdigit(*z) ) z+=incr, nDigits++, d++;
          292  +  if( z>=zEnd ) goto do_atof_calc;
   325    293   
   326    294     /* if decimal point is present */
   327    295     if( *z=='.' ){
   328         -    z++;
          296  +    z+=incr;
   329    297       /* copy digits from after decimal to significand
   330    298       ** (decrease exponent by d to shift decimal right) */
   331         -    while( sqlite3Isdigit(*z) && s<((LARGEST_INT64-9)/10) ){
          299  +    while( z<zEnd && sqlite3Isdigit(*z) && s<((LARGEST_INT64-9)/10) ){
   332    300         s = s*10 + (*z - '0');
   333         -      z++, nDigits++, d--;
          301  +      z+=incr, nDigits++, d--;
   334    302       }
   335    303       /* skip non-significant digits */
   336         -    while( sqlite3Isdigit(*z) ) z++, nDigits++;
          304  +    while( z<zEnd && sqlite3Isdigit(*z) ) z+=incr, nDigits++;
   337    305     }
          306  +  if( z>=zEnd ) goto do_atof_calc;
   338    307   
   339    308     /* if exponent is present */
   340    309     if( *z=='e' || *z=='E' ){
   341         -    z++;
          310  +    z+=incr;
          311  +    if( z>=zEnd ) goto do_atof_calc;
   342    312       /* get sign of exponent */
   343    313       if( *z=='-' ){
   344    314         esign = -1;
   345         -      z++;
          315  +      z+=incr;
   346    316       }else if( *z=='+' ){
   347         -      z++;
          317  +      z+=incr;
   348    318       }
   349    319       /* copy digits to exponent */
   350         -    while( sqlite3Isdigit(*z) ){
          320  +    while( z<zEnd && sqlite3Isdigit(*z) ){
   351    321         e = e*10 + (*z - '0');
   352         -      z++;
          322  +      z+=incr;
   353    323       }
   354    324     }
   355    325   
          326  +do_atof_calc:
   356    327     /* adjust exponent by d, and update sign */
   357    328     e = (e*esign) + d;
   358    329     if( e<0 ) {
   359    330       esign = -1;
   360    331       e *= -1;
   361    332     } else {
   362    333       esign = 1;
................................................................................
   407    378         result = (double)s;
   408    379       }
   409    380     }
   410    381   
   411    382     /* store the result */
   412    383     *pResult = result;
   413    384   
   414         -  /* return number of characters used */
   415         -  return (int)(z - zBegin);
          385  +  /* return number of bytes used */
          386  +  return z>=zEnd && sqlite3Isdigit(z[-incr]);
   416    387   #else
   417         -  return sqlite3Atoi64(z, pResult);
          388  +  return sqlite3Atoi64(z, pResult, length, enc);
   418    389   #endif /* SQLITE_OMIT_FLOATING_POINT */
   419    390   }
   420    391   
   421    392   /*
   422    393   ** Compare the 19-character string zNum against the text representation
   423    394   ** value 2^63:  9223372036854775808.  Return negative, zero, or positive
   424    395   ** if zNum is less than, equal to, or greater than the string.
   425    396   **
   426    397   ** Unlike memcmp() this routine is guaranteed to return the difference
   427    398   ** in the values of the last digit if the only difference is in the
   428    399   ** last digit.  So, for example,
   429    400   **
   430         -**      compare2pow63("9223372036854775800")
          401  +**      compare2pow63("9223372036854775800", 1)
   431    402   **
   432    403   ** will return -8.
   433    404   */
   434         -static int compare2pow63(const char *zNum){
   435         -  int c;
   436         -  c = memcmp(zNum,"922337203685477580",18)*10;
          405  +static int compare2pow63(const char *zNum, int incr){
          406  +  int c = 0;
          407  +  int i;
          408  +                    /* 012345678901234567 */
          409  +  const char *pow63 = "922337203685477580";
          410  +  for(i=0; c==0 && i<18; i++){
          411  +    c = (zNum[i*incr]-pow63[i])*10;
          412  +  }
   437    413     if( c==0 ){
   438         -    c = zNum[18] - '8';
          414  +    c = zNum[18*incr] - '8';
   439    415       testcase( c==(-1) );
   440    416       testcase( c==0 );
   441    417       testcase( c==(+1) );
   442    418     }
   443    419     return c;
   444    420   }
   445    421   
................................................................................
   446    422   
   447    423   /*
   448    424   ** Return TRUE if zNum is a 64-bit signed integer and write
   449    425   ** the value of the integer into *pNum.  If zNum is not an integer
   450    426   ** or is an integer that is too large to be expressed with 64 bits,
   451    427   ** then return false.
   452    428   **
   453         -** When this routine was originally written it dealt with only
   454         -** 32-bit numbers.  At that time, it was much faster than the
   455         -** atoi() library routine in RedHat 7.2.
          429  +** length is the number of bytes in the string (bytes, not characters).
          430  +** The string is not necessarily zero-terminated.  The encoding is
          431  +** given by enc.
   456    432   */
   457         -int sqlite3Atoi64(const char *zNum, i64 *pNum){
          433  +int sqlite3Atoi64(const char *zNum, i64 *pNum, int length, u8 enc){
          434  +  int incr = (enc==SQLITE_UTF8?1:2);
   458    435     i64 v = 0;
   459         -  int neg;
   460         -  int i, c;
          436  +  int neg = 0;
          437  +  int i;
          438  +  int c = 0;
   461    439     const char *zStart;
   462         -  while( sqlite3Isspace(*zNum) ) zNum++;
          440  +  const char *zEnd = zNum + length;
          441  +  if( enc==SQLITE_UTF16BE ) zNum++;
          442  +  while( zNum<zEnd && sqlite3Isspace(*zNum) ) zNum+=incr;
          443  +  if( zNum>=zEnd ) goto do_atoi_calc;
   463    444     if( *zNum=='-' ){
   464    445       neg = 1;
   465         -    zNum++;
          446  +    zNum+=incr;
   466    447     }else if( *zNum=='+' ){
   467    448       neg = 0;
   468         -    zNum++;
          449  +    zNum+=incr;
   469    450     }else{
   470    451       neg = 0;
   471    452     }
          453  +do_atoi_calc:
   472    454     zStart = zNum;
   473         -  while( zNum[0]=='0' ){ zNum++; } /* Skip over leading zeros. Ticket #2454 */
   474         -  for(i=0; (c=zNum[i])>='0' && c<='9'; i++){
          455  +  while( zNum<zEnd && zNum[0]=='0' ){ zNum+=incr; } /* Skip leading zeros. */
          456  +  for(i=0; &zNum[i]<zEnd && (c=zNum[i])>='0' && c<='9'; i+=incr){
   475    457       v = v*10 + c - '0';
   476    458     }
   477    459     *pNum = neg ? -v : v;
   478    460     testcase( i==18 );
   479    461     testcase( i==19 );
   480    462     testcase( i==20 );
   481         -  if( c!=0 || (i==0 && zStart==zNum) || i>19 ){
          463  +  if( (c!=0 && &zNum[i]<zEnd) || (i==0 && zStart==zNum) || i>19*incr ){
   482    464       /* zNum is empty or contains non-numeric text or is longer
   483    465       ** than 19 digits (thus guaranting that it is too large) */
   484    466       return 0;
   485         -  }else if( i<19 ){
          467  +  }else if( i<19*incr ){
   486    468       /* Less than 19 digits, so we know that it fits in 64 bits */
   487    469       return 1;
   488    470     }else{
   489    471       /* 19-digit numbers must be no larger than 9223372036854775807 if positive
   490    472       ** or 9223372036854775808 if negative.  Note that 9223372036854665808
   491    473       ** is 2^63. */
   492         -    return compare2pow63(zNum)<neg;
          474  +    return compare2pow63(zNum, incr)<neg;
   493    475     }
   494    476   }
   495    477   
   496    478   /*
   497    479   ** The string zNum represents an unsigned integer.  The zNum string
   498    480   ** consists of one or more digit characters and is terminated by
   499    481   ** a zero character.  Any stray characters in zNum result in undefined
................................................................................
   528    510       /* Guaranteed to fit if less than 19 digits */
   529    511       return 1;
   530    512     }else if( i>19 ){
   531    513       /* Guaranteed to be too big if greater than 19 digits */
   532    514       return 0;
   533    515     }else{
   534    516       /* Compare against 2^63. */
   535         -    return compare2pow63(zNum)<neg;
          517  +    return compare2pow63(zNum, 1)<neg;
   536    518     }
   537    519   }
   538    520   
   539    521   /*
   540    522   ** If zNum represents an integer that will fit in 32-bits, then set
   541    523   ** *pValue to that integer and return true.  Otherwise return false.
   542    524   **

Changes to src/vdbe.c.

   245    245   ** Try to convert a value into a numeric representation if we can
   246    246   ** do so without loss of information.  In other words, if the string
   247    247   ** looks like a number, convert it into a number.  If it does not
   248    248   ** look like a number, leave it alone.
   249    249   */
   250    250   static void applyNumericAffinity(Mem *pRec){
   251    251     if( (pRec->flags & (MEM_Real|MEM_Int))==0 ){
   252         -    int realnum;
          252  +    double rValue;
          253  +    i64 iValue;
   253    254       u8 enc = pRec->enc;
   254         -    sqlite3VdbeMemNulTerminate(pRec);
   255         -    if( (pRec->flags&MEM_Str) && sqlite3IsNumber(pRec->z, &realnum, enc) ){
   256         -      i64 value;
   257         -      char *zUtf8 = pRec->z;
   258         -#ifndef SQLITE_OMIT_UTF16
   259         -      if( enc!=SQLITE_UTF8 ){
   260         -        assert( pRec->db );
   261         -        zUtf8 = sqlite3Utf16to8(pRec->db, pRec->z, pRec->n, enc);
   262         -        if( !zUtf8 ) return;
   263         -      }
   264         -#endif
   265         -      if( !realnum && sqlite3Atoi64(zUtf8, &value) ){
   266         -        pRec->u.i = value;
   267         -        MemSetTypeFlag(pRec, MEM_Int);
   268         -      }else{
   269         -        sqlite3AtoF(zUtf8, &pRec->r);
   270         -        MemSetTypeFlag(pRec, MEM_Real);
   271         -      }
   272         -#ifndef SQLITE_OMIT_UTF16
   273         -      if( enc!=SQLITE_UTF8 ){
   274         -        sqlite3DbFree(pRec->db, zUtf8);
   275         -      }
   276         -#endif
          255  +    if( (pRec->flags&MEM_Str)==0 ) return;
          256  +    if( sqlite3AtoF(pRec->z, &rValue, pRec->n, enc)==0 ) return;
          257  +    if( sqlite3Atoi64(pRec->z, &iValue, pRec->n, enc) ){
          258  +      pRec->u.i = iValue;
          259  +      pRec->flags |= MEM_Int;
          260  +    }else{
          261  +      pRec->r = rValue;
          262  +      pRec->flags |= MEM_Real;
   277    263       }
   278    264     }
   279    265   }
   280    266   
   281    267   /*
   282    268   ** Processing is determine by the affinity parameter:
   283    269   **

Changes to src/vdbemem.c.

   364    364     flags = pMem->flags;
   365    365     if( flags & MEM_Int ){
   366    366       return pMem->u.i;
   367    367     }else if( flags & MEM_Real ){
   368    368       return doubleToInt64(pMem->r);
   369    369     }else if( flags & (MEM_Str|MEM_Blob) ){
   370    370       i64 value;
   371         -    pMem->flags |= MEM_Str;
   372         -    if( sqlite3VdbeChangeEncoding(pMem, SQLITE_UTF8)
   373         -       || sqlite3VdbeMemNulTerminate(pMem) ){
   374         -      return 0;
   375         -    }
   376         -    assert( pMem->z );
   377         -    sqlite3Atoi64(pMem->z, &value);
          371  +    assert( pMem->z || pMem->n==0 );
          372  +    testcase( pMem->z==0 );
          373  +    sqlite3Atoi64(pMem->z, &value, pMem->n, pMem->enc);
   378    374       return value;
   379    375     }else{
   380    376       return 0;
   381    377     }
   382    378   }
   383    379   
   384    380   /*
................................................................................
   400    396       pMem->flags |= MEM_Str;
   401    397       if( sqlite3VdbeChangeEncoding(pMem, SQLITE_UTF8)
   402    398          || sqlite3VdbeMemNulTerminate(pMem) ){
   403    399         /* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */
   404    400         return (double)0;
   405    401       }
   406    402       assert( pMem->z );
   407         -    sqlite3AtoF(pMem->z, &val);
          403  +    sqlite3AtoF(pMem->z, &val, pMem->n, SQLITE_UTF8);
   408    404       return val;
   409    405     }else{
   410    406       /* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */
   411    407       return (double)0;
   412    408     }
   413    409   }
   414    410   
................................................................................
   481    477     assert( (pMem->flags & (MEM_Int|MEM_Real|MEM_Null))==0 );
   482    478     assert( (pMem->flags & (MEM_Blob|MEM_Str))!=0 );
   483    479     assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
   484    480     rc = sqlite3VdbeChangeEncoding(pMem, SQLITE_UTF8);
   485    481     if( rc ) return rc;
   486    482     rc = sqlite3VdbeMemNulTerminate(pMem);
   487    483     if( rc ) return rc;
   488         -  if( sqlite3Atoi64(pMem->z, &pMem->u.i) ){
          484  +  if( sqlite3Atoi64(pMem->z, &pMem->u.i, pMem->n, SQLITE_UTF8) ){
   489    485       MemSetTypeFlag(pMem, MEM_Int);
   490    486     }else{
   491    487       pMem->r = sqlite3VdbeRealValue(pMem);
   492    488       MemSetTypeFlag(pMem, MEM_Real);
   493    489       sqlite3VdbeIntegerAffinity(pMem);
   494    490     }
   495    491     return SQLITE_OK;