SQLite4
Check-in [ae34cd8492]
Not logged in

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

Overview
Comment:Use decimal arithmetic in affinity routines.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | sqlite4-num
Files: files | file ages | folders
SHA1: ae34cd8492cf98b71640cedca034b401bf303d2b
User & Date: dan 2013-05-31 17:13:32
Context
2013-05-31
19:19
Remove uses of type 'double' from the vdbe. check-in: e018823162 user: dan tags: sqlite4-num
17:13
Use decimal arithmetic in affinity routines. check-in: ae34cd8492 user: dan tags: sqlite4-num
2013-05-30
19:01
Use the same code to encode keys for rowid indexes as regular indexes. check-in: 9265ac66c8 user: dan tags: sqlite4-num
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/expr.c.

1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
....
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
** like the continuation of the number.
*/
static void codeReal(Vdbe *v, const char *z, int negateFlag, int iMem){
  if( ALWAYS(z!=0) ){
    int s = sizeof(sqlite4_num);
    sqlite4_num *p = (sqlite4_num *)sqlite4DbMallocZero(sqlite4VdbeDb(v), s);
    if( p ){
      *p = sqlite4_num_from_text(z, -1, 0);
      assert( p->sign==0 );
      assert( negateFlag==0 || negateFlag==1 );
      p->sign = negateFlag;
      sqlite4VdbeAddOp4(v, OP_Num, 0, iMem, 0, (const char *)p, P4_NUM);
    }
#if 0
    double value;
................................................................................
    int c;
    i64 value;
    const char *z = pExpr->u.zToken;
    assert( z!=0 );

    p = (sqlite4_num *)sqlite4DbMallocRaw(pParse->db, sizeof(sqlite4_num));
    if( p ){
      *p = sqlite4_num_from_text(z, -1, (negFlag ? SQLITE4_NEGATIVE : 0));
      sqlite4VdbeAddOp4(v, OP_Num, p->e==0, iMem, 0, (const char *)p, P4_NUM);
    }

#if 0
    c = sqlite4Atoi64(z, &value, sqlite4Strlen30(z), SQLITE4_UTF8);
    if( c==0 || (c==2 && negFlag) ){
      char *zV;







|







 







|







1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
....
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
** like the continuation of the number.
*/
static void codeReal(Vdbe *v, const char *z, int negateFlag, int iMem){
  if( ALWAYS(z!=0) ){
    int s = sizeof(sqlite4_num);
    sqlite4_num *p = (sqlite4_num *)sqlite4DbMallocZero(sqlite4VdbeDb(v), s);
    if( p ){
      *p = sqlite4_num_from_text(z, -1, 0, 0);
      assert( p->sign==0 );
      assert( negateFlag==0 || negateFlag==1 );
      p->sign = negateFlag;
      sqlite4VdbeAddOp4(v, OP_Num, 0, iMem, 0, (const char *)p, P4_NUM);
    }
#if 0
    double value;
................................................................................
    int c;
    i64 value;
    const char *z = pExpr->u.zToken;
    assert( z!=0 );

    p = (sqlite4_num *)sqlite4DbMallocRaw(pParse->db, sizeof(sqlite4_num));
    if( p ){
      *p = sqlite4_num_from_text(z, -1, (negFlag ? SQLITE4_NEGATIVE : 0), 0);
      sqlite4VdbeAddOp4(v, OP_Num, p->e==0, iMem, 0, (const char *)p, P4_NUM);
    }

#if 0
    c = sqlite4Atoi64(z, &value, sqlite4Strlen30(z), SQLITE4_UTF8);
    if( c==0 || (c==2 && negFlag) ){
      char *zV;

Changes to src/math.c.

307
308
309
310
311
312
313
314







315
316
317
318
319
320

321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336

337

338
339

340
341
342
343

344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362

363
364
365
366
367
368
369
370

371
372
373
374
375
376
377
378
379
380
381
...
388
389
390
391
392
393
394

395
396
397
398
399



400


401

402
403
404
405
406
407
408
409
410
411


412
413
414
415

416
417
418
419
420
421
422
423
424
425
426
427
428
429

430



431




432
433
434
435



436
437
438
439
440
441
442
...
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
** are scanned, which we assume is more than will be found in any valid
** numeric string.
**
** If the value does not contain a decimal point or exponent, and is
** within the range of a signed 64-bit integer, it is guaranteed that
** the exponent of the returned value is zero.
*/
sqlite4_num sqlite4_num_from_text(const char *zIn, int nIn, unsigned flags){








  static const i64 L10 = (LARGEST_INT64 / 10);
  int aMaxFinal[2] = {7, 8};

  static int one = 1;             /* Used to test machine endianness */
  int bRnd = 1;                   /* If mantissa overflows, round it */

  int seenRadix = 0;              /* True after decimal point has been parsed */
  int seenDigit = 0;              /* True after first non-zero digit parsed */
  int incr = 1;                   /* 1 for utf-8, 2 for utf-16 */
  int bInvalid = 1;               /* True for a bad parse */
  sqlite4_num r;                  /* Value to return */
  char c;
  int nDigit = 0;
  int i;

  assert( L10==922337203685477580 );
  
  memset(&r, 0, sizeof(r));
  if( nIn<0 ) nIn = 1000000000;
  c = flags & 0xf;
  if( c==0 || c==SQLITE4_UTF8 ){
    incr = 1;

  }else if( c==SQLITE4_UTF16 ){

    incr = 2;
    c = *(char*)&one;

    zIn += c;
    nIn -= c;
  }
  

  /* If the PREFIX_ONLY flag is set, ignore any leading whitespace. */
  i = 0;
  if( flags & SQLITE4_PREFIX_ONLY ){
    while( sqlite4Isspace(zIn[i]) && i<nIn ) i+=incr;
  }
  if( nIn<=i ) goto finished;

  /* Check for a leading '+' or '-' symbol. */
  if( zIn[i]=='-' ){
    r.sign = 1;
    i += incr;
  }else if( zIn[i]=='+' ){
    i += incr;
  }else if( flags & SQLITE4_NEGATIVE ){
    r.sign = 1;
  }
  if( nIn<=i ) goto finished;

  /* Check for the string "inf". This is a special case. */

  if( (nIn-i)>=incr*3
   && ((c=zIn[i])=='i' || c=='I')
   && ((c=zIn[i+incr])=='n' || c=='N')
   && ((c=zIn[i+incr*2])=='f' || c=='F')
  ){
    r.e = SQLITE4_MX_EXP+1;
    r.m = nIn<=i+incr*3 || zIn[i+incr*3]==0;
    return r;

  }

  while( i<nIn && (c = zIn[i])!=0 ){
    i += incr;
    if( c>='0' && c<='9' ){
      int iDigit = (c - '0');

      if( iDigit==0 && seenDigit==0 ){
        /* Handle leading zeroes. If they occur to the right of the decimal
        ** point they can just be ignored. Otherwise, decrease the exponent
        ** by one.  */
................................................................................
        /* Mantissa overflow. */
        if( seenRadix==0 ) r.e++;
        if( iDigit!=0 ){ r.approx = 1; }
        if( bRnd ){
          if( iDigit>5 && r.m<((u64)LARGEST_INT64 + r.sign)) r.m++;
          bRnd = 0;
        }

      }else{
        if( seenRadix ) r.e -= 1;
        r.m = (r.m*10) + iDigit;
      }




    }else if( c=='.' ){


      seenRadix = 1;

    }else if( c=='e' || c=='E' ){
      int exp = 0;
      int expsign = 0;
      int nEDigit = 0;
      if( zIn[i]=='-' ){
        expsign = 1;
        i += incr;
      }else if( zIn[i]=='+' ){
        i += incr;
      }


      if( i>=nIn ) goto finished;
      while( i<nIn && (c = zIn[i])!=0 ){
        i += incr;
        if( c<'0' || c>'9' ) goto finished;

        if( c=='0' && nEDigit==0 ) continue;
        nEDigit++;
        if( nEDigit>3 ) goto finished;
        exp = exp*10 + c - '0';
      }
      if( expsign ) exp = -exp;
      r.e += exp;
      break;
    }else{
      goto finished;
    }
  }
  bInvalid = 0;


finished:



  if( bInvalid && (flags & SQLITE4_PREFIX_ONLY)==0 ){




    r.e = SQLITE4_MX_EXP+1;
    r.m = 0;
  }




  return r;
}

/*
** Convert an sqlite4_int64 to a number and return that number.
*/
sqlite4_num sqlite4_num_from_int64(sqlite4_int64 n){
................................................................................
    iRet = iRet / 10;
  }
  *piOut = iRet;
  return SQLITE4_OK;
}


/*
** Return true if the sqlite4_num value passed as the first argument 
** may be stored in an i64 without loss of precision.
**
** TODO: This only works with values just returned from
** sqlite4_num_from_text().
*/
int sqlite4_num_is_int64(sqlite4_num num){
  if( num.approx==1 ) return 0;
  if( num.e<0 ){
  }
}

/*
** Convert an integer into text in the buffer supplied. The
** text is zero-terminated and right-justified in the buffer.
** A pointer to the first character of text is returned.
**
** The buffer needs to be at least 21 bytes in length.
*/







|
>
>
>
>
>
>
>



<


>



<












>
|
>

<
>
|
|
|
|
>
|

|


|










|


>
|





|
|
>


|
<







 







>





>
>
>
|
>
>
|
>
|
<
<
<
<
<
<
<
|
<
>
>
|
<
<
|
>
|
|
<
<
<
<
<
|
|
|
|
|
<
|
>

>
>
>
|
>
>
>
>
|
|
|
|
>
>
>







 







<
<
<
<
<
<
<
<
<
<
<
<
<







307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324

325
326
327
328
329
330

331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346

347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384

385
386
387
388
389
390
391
...
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419







420

421
422
423


424
425
426
427





428
429
430
431
432

433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
...
539
540
541
542
543
544
545













546
547
548
549
550
551
552
** are scanned, which we assume is more than will be found in any valid
** numeric string.
**
** If the value does not contain a decimal point or exponent, and is
** within the range of a signed 64-bit integer, it is guaranteed that
** the exponent of the returned value is zero.
*/
sqlite4_num sqlite4_num_from_text(
  const char *zIn,                /* Pointer to text to parse */
  int nIn,                        /* Size of zIn in bytes or (-ve) */
  unsigned flags,                 /* Conversion flags */
  int *pbReal                     /* OUT: True if text looks like a real */
){
  /* Return this value (NaN) if a parse error occurs. */
  static const sqlite4_num error_value = {0, 0, SQLITE4_MX_EXP+1, 0};

  static const i64 L10 = (LARGEST_INT64 / 10);
  int aMaxFinal[2] = {7, 8};

  static int one = 1;             /* Used to test machine endianness */
  int bRnd = 1;                   /* If mantissa overflows, round it */
  int bReal = 0;                  /* If text looks like a real */
  int seenRadix = 0;              /* True after decimal point has been parsed */
  int seenDigit = 0;              /* True after first non-zero digit parsed */
  int incr = 1;                   /* 1 for utf-8, 2 for utf-16 */

  sqlite4_num r;                  /* Value to return */
  char c;
  int nDigit = 0;
  int i;

  assert( L10==922337203685477580 );
  
  memset(&r, 0, sizeof(r));
  if( nIn<0 ) nIn = 1000000000;
  c = flags & 0xf;
  if( c==0 || c==SQLITE4_UTF8 ){
    incr = 1;
  }else{
    if( c==SQLITE4_UTF16 ){ c = (3 - *(char*)&one); }
    assert( c==SQLITE4_UTF16LE || c==SQLITE4_UTF16BE );
    incr = 2;

    if( c==SQLITE4_UTF16BE ){
      zIn += 1;
      nIn -= 1;
    }
  }
  
  /* If the IGNORE_WHITESPACE flag is set, ignore any leading whitespace. */
  i = 0;
  if( flags & SQLITE4_IGNORE_WHITESPACE ){
    while( sqlite4Isspace(zIn[i]) && i<nIn ) i+=incr;
  }
  if( nIn<=i ) return error_value;

  /* Check for a leading '+' or '-' symbol. */
  if( zIn[i]=='-' ){
    r.sign = 1;
    i += incr;
  }else if( zIn[i]=='+' ){
    i += incr;
  }else if( flags & SQLITE4_NEGATIVE ){
    r.sign = 1;
  }
  if( nIn<=i ) return error_value;

  /* Check for the string "inf". This is a special case. */
  if( (flags & SQLITE4_INTEGER_ONLY)==0 
   && (nIn-i)>=incr*3
   && ((c=zIn[i])=='i' || c=='I')
   && ((c=zIn[i+incr])=='n' || c=='N')
   && ((c=zIn[i+incr*2])=='f' || c=='F')
  ){
    r.e = SQLITE4_MX_EXP+1;
    r.m = 1;
    if( pbReal ) *pbReal = 1;
    goto finished;
  }

  for( ; i<nIn && (c = zIn[i])!=0; i+=incr){

    if( c>='0' && c<='9' ){
      int iDigit = (c - '0');

      if( iDigit==0 && seenDigit==0 ){
        /* Handle leading zeroes. If they occur to the right of the decimal
        ** point they can just be ignored. Otherwise, decrease the exponent
        ** by one.  */
................................................................................
        /* Mantissa overflow. */
        if( seenRadix==0 ) r.e++;
        if( iDigit!=0 ){ r.approx = 1; }
        if( bRnd ){
          if( iDigit>5 && r.m<((u64)LARGEST_INT64 + r.sign)) r.m++;
          bRnd = 0;
        }
        bReal = 1;
      }else{
        if( seenRadix ) r.e -= 1;
        r.m = (r.m*10) + iDigit;
      }

    }else{
      if( flags & SQLITE4_INTEGER_ONLY ) goto finished;

      if( c=='.' ){
        /* Permit only a single radix in each number */
        if( seenRadix ) goto finished;
        seenRadix = 1;
        bReal = 1;
      }else if( c=='e' || c=='E' ){







        int f = (flags & (SQLITE4_PREFIX_ONLY|SQLITE4_IGNORE_WHITESPACE));

        sqlite4_num exp;
        exp = sqlite4_num_from_text(&zIn[i+incr], nIn-i-incr, f, 0);
        if( sqlite4_num_isnan(exp) ) goto finished;


        if( exp.e || exp.m>999 ) goto finished;
        bReal = 1;
        r.e += (int)(exp.m) * (exp.sign ? -1 : 1);
        i = nIn;





        break;
      }else{
        goto finished;
      }
    }

  }

finished:

  /* Check for a parse error. If one has occurred, set the return value
  ** to NaN.  */
  if( (flags & SQLITE4_PREFIX_ONLY)==0 && i<nIn && zIn[i] ){
    if( flags & SQLITE4_IGNORE_WHITESPACE ){
      while( i<nIn && sqlite4Isspace(zIn[i]) ) i += incr;
    }
    if( i<nIn && zIn[i] ){
      r.e = SQLITE4_MX_EXP+1;
      r.m = 0;
    }
  }


  if( pbReal ) *pbReal = bReal;
  return r;
}

/*
** Convert an sqlite4_int64 to a number and return that number.
*/
sqlite4_num sqlite4_num_from_int64(sqlite4_int64 n){
................................................................................
    iRet = iRet / 10;
  }
  *piOut = iRet;
  return SQLITE4_OK;
}















/*
** Convert an integer into text in the buffer supplied. The
** text is zero-terminated and right-justified in the buffer.
** A pointer to the first character of text is returned.
**
** The buffer needs to be at least 21 bytes in length.
*/

Changes to src/sqlite.h.in.

4108
4109
4110
4111
4112
4113
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124
4125
4126
4127
4128

4129
4130
4131
4132
4133
4134
4135
sqlite4_num sqlite4_num_sub(sqlite4_num, sqlite4_num);
sqlite4_num sqlite4_num_mul(sqlite4_num, sqlite4_num);
sqlite4_num sqlite4_num_div(sqlite4_num, sqlite4_num);
int sqlite4_num_isinf(sqlite4_num);
int sqlite4_num_isnan(sqlite4_num);
sqlite4_num sqlite4_num_round(sqlite4_num, int iDigit);
int sqlite4_num_compare(sqlite4_num, sqlite4_num);
sqlite4_num sqlite4_num_from_text(const char*, int n, unsigned flags);
sqlite4_num sqlite4_num_from_int64(sqlite4_int64);
sqlite4_num sqlite4_num_from_double(double);
int sqlite4_num_to_int32(sqlite4_num, int*);
int sqlite4_num_to_int64(sqlite4_num, sqlite4_int64*);
int sqlite4_num_to_double(sqlite4_num, double *);
int sqlite4_num_to_text(sqlite4_num, char*, int);

/*
** CAPI4REF: Flags For Text-To-Numeric Conversion
*/
#define SQLITE4_PREFIX_ONLY         0x10
#define SQLITE4_IGNORE_WHITESPACE   0x20
#define SQLITE4_NEGATIVE            0x40


typedef struct sqlite4_tokenizer sqlite4_tokenizer;

/*
** CAPI4REF: Register an FTS tokenizer implementation
**
** xTokenize:







|













>







4108
4109
4110
4111
4112
4113
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124
4125
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136
sqlite4_num sqlite4_num_sub(sqlite4_num, sqlite4_num);
sqlite4_num sqlite4_num_mul(sqlite4_num, sqlite4_num);
sqlite4_num sqlite4_num_div(sqlite4_num, sqlite4_num);
int sqlite4_num_isinf(sqlite4_num);
int sqlite4_num_isnan(sqlite4_num);
sqlite4_num sqlite4_num_round(sqlite4_num, int iDigit);
int sqlite4_num_compare(sqlite4_num, sqlite4_num);
sqlite4_num sqlite4_num_from_text(const char*, int n, unsigned flags, int*);
sqlite4_num sqlite4_num_from_int64(sqlite4_int64);
sqlite4_num sqlite4_num_from_double(double);
int sqlite4_num_to_int32(sqlite4_num, int*);
int sqlite4_num_to_int64(sqlite4_num, sqlite4_int64*);
int sqlite4_num_to_double(sqlite4_num, double *);
int sqlite4_num_to_text(sqlite4_num, char*, int);

/*
** CAPI4REF: Flags For Text-To-Numeric Conversion
*/
#define SQLITE4_PREFIX_ONLY         0x10
#define SQLITE4_IGNORE_WHITESPACE   0x20
#define SQLITE4_NEGATIVE            0x40
#define SQLITE4_INTEGER_ONLY        0x80

typedef struct sqlite4_tokenizer sqlite4_tokenizer;

/*
** CAPI4REF: Register an FTS tokenizer implementation
**
** xTokenize:

Changes to src/vdbe.c.

225
226
227
228
229
230
231
232
233
234
235
236

237
238
239
240
241
242
243
244
245
246
247
248
249
250
...
417
418
419
420
421
422
423








424

425
426
427
428
429
430
431
432
433
/*
** Try to convert a value into a numeric representation if we can
** do so without loss of information.  In other words, if the string
** looks like a number, convert it into a number.  If it does not
** look like a number, leave it alone.
*/
static void applyNumericAffinity(Mem *pRec){
  if( (pRec->flags & (MEM_Real|MEM_Int))==0 ){
    double rValue;
    i64 iValue;
    u8 enc = pRec->enc;
    if( (pRec->flags&MEM_Str)==0 ) return;

    if( sqlite4AtoF(pRec->z, &rValue, pRec->n, enc)==0 ) return;
    if( 0==sqlite4Atoi64(pRec->z, &iValue, pRec->n, enc) ){
      pRec->u.num = sqlite4_num_from_int64(iValue);
      pRec->flags |= MEM_Int;
    }else{
      pRec->u.num = sqlite4_num_from_double(rValue);
      pRec->flags |= MEM_Real;
    }
  }
}

/*
** Processing is determine by the affinity parameter:
**
................................................................................
  fprintf(out, "REG[%d] = ", iReg);
  memTracePrint(out, p);
  fprintf(out, "\n");
}
#endif

#ifdef SQLITE4_DEBUG








#  define REGISTER_TRACE(R,M) if(p->trace)registerTrace(p->trace,R,M)

#else
#  define REGISTER_TRACE(R,M)
#endif


#ifdef VDBE_PROFILE

/* 
** hwtime.h contains inline assembler code for implementing 







|
|
|
|
<
>
|
|
|
|
<
<
<







 







>
>
>
>
>
>
>
>
|
>

|







225
226
227
228
229
230
231
232
233
234
235

236
237
238
239
240



241
242
243
244
245
246
247
...
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
/*
** Try to convert a value into a numeric representation if we can
** do so without loss of information.  In other words, if the string
** looks like a number, convert it into a number.  If it does not
** look like a number, leave it alone.
*/
static void applyNumericAffinity(Mem *pRec){
  if( (pRec->flags & (MEM_Real|MEM_Int))==0 && (pRec->flags & MEM_Str) ){
    int flags = pRec->enc | SQLITE4_IGNORE_WHITESPACE;
    int bReal = 0;
    sqlite4_num num;

    
    num = sqlite4_num_from_text(pRec->z, pRec->n, flags, &bReal);
    if( sqlite4_num_isnan(num)==0 ){
      pRec->u.num = num;
      MemSetTypeFlag(pRec, (bReal ? MEM_Real : MEM_Int));



    }
  }
}

/*
** Processing is determine by the affinity parameter:
**
................................................................................
  fprintf(out, "REG[%d] = ", iReg);
  memTracePrint(out, p);
  fprintf(out, "\n");
}
#endif

#ifdef SQLITE4_DEBUG
static int assertFlagsOk(Mem *p){
  u16 flags = p->flags;
  assert( (flags&MEM_Int)==0 || (flags&MEM_Real)==0 );
  return 1;
}
#endif

#ifdef SQLITE4_DEBUG
# define REGISTER_TRACE(R,M) \
    if(assertFlagsOk(M) && p->trace)registerTrace(p->trace,R,M)
#else
# define REGISTER_TRACE(R,M)
#endif


#ifdef VDBE_PROFILE

/* 
** hwtime.h contains inline assembler code for implementing 

Changes to src/vdbemem.c.

349
350
351
352
353
354
355

356
357
358
359
360
361
362
363
...
425
426
427
428
429
430
431

432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
** Extract and return a numeric value from memory cell pMem. This call
** does not modify the contents or flags of *pMem in any way.
*/
sqlite4_num sqlite4VdbeNumValue(Mem *pMem){
  if( pMem->flags & (MEM_Real|MEM_Int) ){
    return pMem->u.num;
  }else if( pMem->flags & (MEM_Str|MEM_Blob) ){

    return sqlite4_num_from_text(pMem->z, pMem->n, SQLITE4_PREFIX_ONLY);
  }else{
    sqlite4_num zero = {0,0,0,0};
    return zero;
  }
}

/*
................................................................................
**
** Every effort is made to force the conversion, even if the input
** is a string that does not look completely like a number.  Convert
** as much of the string as we can and ignore the rest.
*/
int sqlite4VdbeMemNumerify(Mem *pMem){
  if( (pMem->flags & (MEM_Int|MEM_Real|MEM_Null))==0 ){

    int flags = (pMem->enc | SQLITE4_PREFIX_ONLY);

    assert( (pMem->flags & (MEM_Blob|MEM_Str))!=0 );
    assert( pMem->db==0 || sqlite4_mutex_held(pMem->db->mutex) );
    pMem->u.num = sqlite4_num_from_text(pMem->z, pMem->n, flags);
    if( pMem->u.num.e==0 ){
      MemSetTypeFlag(pMem, MEM_Int);
    }else{
      MemSetTypeFlag(pMem, MEM_Real);
    }
  }
  assert( (pMem->flags & (MEM_Int|MEM_Real|MEM_Null))!=0 );
  pMem->flags &= ~(MEM_Str|MEM_Blob);
  return SQLITE4_OK;
}

/*







>
|







 







>
|



|
<
|
<
<
<







349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
...
426
427
428
429
430
431
432
433
434
435
436
437
438

439



440
441
442
443
444
445
446
** Extract and return a numeric value from memory cell pMem. This call
** does not modify the contents or flags of *pMem in any way.
*/
sqlite4_num sqlite4VdbeNumValue(Mem *pMem){
  if( pMem->flags & (MEM_Real|MEM_Int) ){
    return pMem->u.num;
  }else if( pMem->flags & (MEM_Str|MEM_Blob) ){
    int flags = SQLITE4_PREFIX_ONLY | pMem->enc;
    return sqlite4_num_from_text(pMem->z, pMem->n, flags, 0);
  }else{
    sqlite4_num zero = {0,0,0,0};
    return zero;
  }
}

/*
................................................................................
**
** Every effort is made to force the conversion, even if the input
** is a string that does not look completely like a number.  Convert
** as much of the string as we can and ignore the rest.
*/
int sqlite4VdbeMemNumerify(Mem *pMem){
  if( (pMem->flags & (MEM_Int|MEM_Real|MEM_Null))==0 ){
    int bReal = 0;
    int flags = (pMem->enc | SQLITE4_PREFIX_ONLY | SQLITE4_IGNORE_WHITESPACE);

    assert( (pMem->flags & (MEM_Blob|MEM_Str))!=0 );
    assert( pMem->db==0 || sqlite4_mutex_held(pMem->db->mutex) );
    pMem->u.num = sqlite4_num_from_text(pMem->z, pMem->n, flags, &bReal);

    MemSetTypeFlag(pMem, (bReal ? MEM_Real : MEM_Int));



  }
  assert( (pMem->flags & (MEM_Int|MEM_Real|MEM_Null))!=0 );
  pMem->flags &= ~(MEM_Str|MEM_Blob);
  return SQLITE4_OK;
}

/*