/ Check-in [4d9edbc5]
Login

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

Overview
Comment:Use a built-in atof() function instead of the one from the library to avoid problems with locale. Ticket #305. (CVS 1144)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:4d9edbc50f7dee64edbadad2e2dc4f93d8248b3b
User & Date: drh 2003-12-23 02:17:35
Context
2003-12-23
03:06
Test functions tolerate an "0x" before a pointer value. Ticket #452. (CVS 1145) check-in: c6c5e07b user: drh tags: trunk
02:17
Use a built-in atof() function instead of the one from the library to avoid problems with locale. Ticket #305. (CVS 1144) check-in: 4d9edbc5 user: drh tags: trunk
2003-12-22
14:53
Optimizations to the LEMON parser template. (CVS 1143) check-in: 06db29df user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/date.c.

12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
...
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
** This file contains the C functions that implement date and time
** functions for SQLite.  
**
** There is only one exported symbol in this file - the function
** sqliteRegisterDateTimeFunctions() found at the bottom of the file.
** All other code has file scope.
**
** $Id: date.c,v 1.1 2003/11/01 01:53:54 drh Exp $
**
** NOTES:
**
** SQLite processes all times and dates as Julian Day numbers.  The
** dates and times are stored as the number of days since noon
** in Greenwich on November 24, 4714 B.C. according to the Gregorian
** calendar system.
................................................................................
    if( sqliteOsCurrentTime(&r)==0 ){
      p->rJD = r;
      p->validJD = 1;
      return 0;
    }
    return 1;
  }else if( sqliteIsNumber(zDate) ){
    p->rJD = atof(zDate);
    p->validJD = 1;
    return 0;
  }
  return 1;
}

/*







|







 







|







12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
...
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
** This file contains the C functions that implement date and time
** functions for SQLite.  
**
** There is only one exported symbol in this file - the function
** sqliteRegisterDateTimeFunctions() found at the bottom of the file.
** All other code has file scope.
**
** $Id: date.c,v 1.2 2003/12/23 02:17:35 drh Exp $
**
** NOTES:
**
** SQLite processes all times and dates as Julian Day numbers.  The
** dates and times are stored as the number of days since noon
** in Greenwich on November 24, 4714 B.C. according to the Gregorian
** calendar system.
................................................................................
    if( sqliteOsCurrentTime(&r)==0 ){
      p->rJD = r;
      p->validJD = 1;
      return 0;
    }
    return 1;
  }else if( sqliteIsNumber(zDate) ){
    p->rJD = sqliteAtoF(zDate);
    p->validJD = 1;
    return 0;
  }
  return 1;
}

/*

Changes to src/func.c.

12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
...
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
...
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
...
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
** This file contains the C functions that implement various SQL
** functions of SQLite.  
**
** There is only one exported symbol in this file - the function
** sqliteRegisterBuildinFunctions() found at the bottom of the file.
** All other code has file scope.
**
** $Id: func.c,v 1.33 2003/11/01 01:53:54 drh Exp $
*/
#include <ctype.h>
#include <math.h>
#include <stdlib.h>
#include <assert.h>
#include "sqliteInt.h"
#include "os.h"
................................................................................
  double r;
  char zBuf[100];
  assert( argc==1 || argc==2 );
  if( argv[0]==0 || (argc==2 && argv[1]==0) ) return;
  n = argc==2 ? atoi(argv[1]) : 0;
  if( n>30 ) n = 30;
  if( n<0 ) n = 0;
  r = atof(argv[0]);
  sprintf(zBuf,"%.*f",n,r);
  sqlite_set_result_string(context, zBuf, -1);
}

/*
** Implementation of the upper() and lower() SQL functions.
*/
................................................................................
** Routines used to compute the sum or average.
*/
static void sumStep(sqlite_func *context, int argc, const char **argv){
  SumCtx *p;
  if( argc<1 ) return;
  p = sqlite_aggregate_context(context, sizeof(*p));
  if( p && argv[0] ){
    p->sum += atof(argv[0]);
    p->cnt++;
  }
}
static void sumFinalize(sqlite_func *context){
  SumCtx *p;
  p = sqlite_aggregate_context(context, sizeof(*p));
  sqlite_set_result_double(context, p ? p->sum : 0.0);
................................................................................
*/
static void stdDevStep(sqlite_func *context, int argc, const char **argv){
  StdDevCtx *p;
  double x;
  if( argc<1 ) return;
  p = sqlite_aggregate_context(context, sizeof(*p));
  if( p && argv[0] ){
    x = atof(argv[0]);
    p->sum += x;
    p->sum2 += x*x;
    p->cnt++;
  }
}
static void stdDevFinalize(sqlite_func *context){
  double rN = sqlite_aggregate_count(context);







|







 







|







 







|







 







|







12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
...
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
...
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
...
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
** This file contains the C functions that implement various SQL
** functions of SQLite.  
**
** There is only one exported symbol in this file - the function
** sqliteRegisterBuildinFunctions() found at the bottom of the file.
** All other code has file scope.
**
** $Id: func.c,v 1.34 2003/12/23 02:17:35 drh Exp $
*/
#include <ctype.h>
#include <math.h>
#include <stdlib.h>
#include <assert.h>
#include "sqliteInt.h"
#include "os.h"
................................................................................
  double r;
  char zBuf[100];
  assert( argc==1 || argc==2 );
  if( argv[0]==0 || (argc==2 && argv[1]==0) ) return;
  n = argc==2 ? atoi(argv[1]) : 0;
  if( n>30 ) n = 30;
  if( n<0 ) n = 0;
  r = sqliteAtoF(argv[0]);
  sprintf(zBuf,"%.*f",n,r);
  sqlite_set_result_string(context, zBuf, -1);
}

/*
** Implementation of the upper() and lower() SQL functions.
*/
................................................................................
** Routines used to compute the sum or average.
*/
static void sumStep(sqlite_func *context, int argc, const char **argv){
  SumCtx *p;
  if( argc<1 ) return;
  p = sqlite_aggregate_context(context, sizeof(*p));
  if( p && argv[0] ){
    p->sum += sqliteAtoF(argv[0]);
    p->cnt++;
  }
}
static void sumFinalize(sqlite_func *context){
  SumCtx *p;
  p = sqlite_aggregate_context(context, sizeof(*p));
  sqlite_set_result_double(context, p ? p->sum : 0.0);
................................................................................
*/
static void stdDevStep(sqlite_func *context, int argc, const char **argv){
  StdDevCtx *p;
  double x;
  if( argc<1 ) return;
  p = sqlite_aggregate_context(context, sizeof(*p));
  if( p && argv[0] ){
    x = sqliteAtoF(argv[0]);
    p->sum += x;
    p->sum2 += x*x;
    p->cnt++;
  }
}
static void stdDevFinalize(sqlite_func *context){
  double rN = sqlite_aggregate_count(context);

Changes to src/printf.c.

753
754
755
756
757
758
759









































760
761
762
763
764
765
766
  zNew = malloc( sMprintf.nChar+1 );
  if( zNew ) strcpy(zNew,sMprintf.zText);
  if( sMprintf.zText!=sMprintf.zBase ){
    sqliteFree(sMprintf.zText);
  }
  return zNew;
}










































/*
** The following four routines implement the varargs versions of the
** sqlite_exec() and sqlite_get_table() interfaces.  See the sqlite.h
** header files for a more detailed description of how these interfaces
** work.
**







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
  zNew = malloc( sMprintf.nChar+1 );
  if( zNew ) strcpy(zNew,sMprintf.zText);
  if( sMprintf.zText!=sMprintf.zBase ){
    sqliteFree(sMprintf.zText);
  }
  return zNew;
}

/* 
** This function implements the callback from vxprintf. 
**
** This routine add nNewChar characters of text in zNewText to
** the sgMprintf structure pointed to by "arg".  Unlike mout() above,
** this routine does not allocate new space when the buffer fills.
** It just truncates.
*/
static void sout(void *arg, char *zNewText, int nNewChar){
  struct sgMprintf *pM = (struct sgMprintf*)arg;
  if( pM->nChar + nNewChar + 1 > pM->nAlloc ){
    nNewChar = pM->nAlloc - pM->nChar - 1;
    if( nNewChar<=0 ) return;
  }
  memcpy(&pM->zText[pM->nChar], zNewText, nNewChar);
  pM->nChar += nNewChar;
  pM->zText[pM->nChar] = 0;
}

/*
** sqlite_sprintf() works like sprintf() except that it ignores the
** current locale settings.  This is important for SQLite because we
** are not able to use a "," as the decimal point in place of "." as
** specified by some locales.
*/
int sqlite_snprintf(int n, char *zBuf, const char *zFormat, ...){
  va_list ap;
  struct sgMprintf sMprintf;

  sMprintf.nChar = 0;
  sMprintf.nAlloc = n;
  sMprintf.zText = zBuf;
  sMprintf.zBase = zBuf;
  va_start(ap,zFormat);
  vxprintf(sout,&sMprintf,zFormat,ap);
  va_end(ap);
  return sMprintf.nChar;
}



/*
** The following four routines implement the varargs versions of the
** sqlite_exec() and sqlite_get_table() interfaces.  See the sqlite.h
** header files for a more detailed description of how these interfaces
** work.
**

Changes to src/sqliteInt.h.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
....
1199
1200
1201
1202
1203
1204
1205


**    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.
**
*************************************************************************
** Internal interface definitions for SQLite.
**
** @(#) $Id: sqliteInt.h,v 1.204 2003/12/07 00:24:35 drh Exp $
*/
#include "config.h"
#include "sqlite.h"
#include "hash.h"
#include "vdbe.h"
#include "parse.h"
#include "btree.h"
................................................................................
                       int mode, int nPg, Btree **ppBtree);
int sqliteFixInit(DbFixer*, Parse*, int, const char*, const Token*);
int sqliteFixSrcList(DbFixer*, SrcList*);
int sqliteFixSelect(DbFixer*, Select*);
int sqliteFixExpr(DbFixer*, Expr*);
int sqliteFixExprList(DbFixer*, ExprList*);
int sqliteFixTriggerStep(DbFixer*, TriggerStep*);









|







 







>
>
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
....
1199
1200
1201
1202
1203
1204
1205
1206
1207
**    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.
**
*************************************************************************
** Internal interface definitions for SQLite.
**
** @(#) $Id: sqliteInt.h,v 1.205 2003/12/23 02:17:35 drh Exp $
*/
#include "config.h"
#include "sqlite.h"
#include "hash.h"
#include "vdbe.h"
#include "parse.h"
#include "btree.h"
................................................................................
                       int mode, int nPg, Btree **ppBtree);
int sqliteFixInit(DbFixer*, Parse*, int, const char*, const Token*);
int sqliteFixSrcList(DbFixer*, SrcList*);
int sqliteFixSelect(DbFixer*, Select*);
int sqliteFixExpr(DbFixer*, Expr*);
int sqliteFixExprList(DbFixer*, ExprList*);
int sqliteFixTriggerStep(DbFixer*, TriggerStep*);
double sqliteAtoF(const char *z);
int sqlite_snprintf(int,char*,const char*,...);

Changes to src/test1.c.

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
...
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Code for testing the printf() interface to SQLite.  This code
** is not included in the SQLite library.  It is used for automated
** testing of the SQLite library.
**
** $Id: test1.c,v 1.28 2003/09/06 22:18:08 drh Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"
#include "os.h"
#include <stdlib.h>
#include <string.h>

................................................................................
      sqlite_set_result_string(context, argv[1], -1);
    }else if( argv[1]==0 ){
      sqlite_set_result_error(context, "2nd argument may not be NULL if the "
         "first argument is not \"string\"", -1);
    }else if( sqliteStrICmp(argv[0],"int")==0 ){
      sqlite_set_result_int(context, atoi(argv[1]));
    }else if( sqliteStrICmp(argv[0],"double")==0 ){
      sqlite_set_result_double(context, atof(argv[1]));
    }else{
      sqlite_set_result_error(context,"first argument should be one of: "
          "string int double", -1);
    }
    argc -= 2;
    argv += 2;
  }







|







 







|







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
...
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Code for testing the printf() interface to SQLite.  This code
** is not included in the SQLite library.  It is used for automated
** testing of the SQLite library.
**
** $Id: test1.c,v 1.29 2003/12/23 02:17:35 drh Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"
#include "os.h"
#include <stdlib.h>
#include <string.h>

................................................................................
      sqlite_set_result_string(context, argv[1], -1);
    }else if( argv[1]==0 ){
      sqlite_set_result_error(context, "2nd argument may not be NULL if the "
         "first argument is not \"string\"", -1);
    }else if( sqliteStrICmp(argv[0],"int")==0 ){
      sqlite_set_result_int(context, atoi(argv[1]));
    }else if( sqliteStrICmp(argv[0],"double")==0 ){
      sqlite_set_result_double(context, sqliteAtoF(argv[1]));
    }else{
      sqlite_set_result_error(context,"first argument should be one of: "
          "string int double", -1);
    }
    argc -= 2;
    argv += 2;
  }

Changes to src/tokenize.c.

11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
...
151
152
153
154
155
156
157
158

159
160
161

162
163
164
165
166
167
168
169
170
171

172
173
174
175
176
177
178
*************************************************************************
** An tokenizer for SQL
**
** This file contains C code that splits an SQL input string up into
** individual tokens and sends those tokens one-by-one over to the
** parser for analysis.
**
** $Id: tokenize.c,v 1.65 2003/12/06 21:43:56 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>
#include <stdlib.h>

/*
................................................................................
** This function looks up an identifier to determine if it is a
** keyword.  If it is a keyword, the token code of that keyword is 
** returned.  If the input is not a keyword, TK_ID is returned.
*/
int sqliteKeywordCode(const char *z, int n){
  int h;
  Keyword *p;
  if( aKeywordTable[0].len==0 ){

    /* Initialize the keyword hash table */
    sqliteOsEnterMutex();
    if( aKeywordTable[0].len==0 ){

      int i;
      int n;
      n = sizeof(aKeywordTable)/sizeof(aKeywordTable[0]);
      for(i=0; i<n; i++){
        aKeywordTable[i].len = strlen(aKeywordTable[i].zName);
        h = sqliteHashNoCase(aKeywordTable[i].zName, aKeywordTable[i].len);
        h %= KEY_HASH_SIZE;
        aKeywordTable[i].pNext = apHashTable[h];
        apHashTable[h] = &aKeywordTable[i];
      }

    }
    sqliteOsLeaveMutex();
  }
  h = sqliteHashNoCase(z, n) % KEY_HASH_SIZE;
  for(p=apHashTable[h]; p; p=p->pNext){
    if( p->len==n && sqliteStrNICmp(p->zName, z, n)==0 ){
      return p->tokenType;







|







 







|
>


<
>










>







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
...
151
152
153
154
155
156
157
158
159
160
161

162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
*************************************************************************
** An tokenizer for SQL
**
** This file contains C code that splits an SQL input string up into
** individual tokens and sends those tokens one-by-one over to the
** parser for analysis.
**
** $Id: tokenize.c,v 1.66 2003/12/23 02:17:35 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>
#include <stdlib.h>

/*
................................................................................
** This function looks up an identifier to determine if it is a
** keyword.  If it is a keyword, the token code of that keyword is 
** returned.  If the input is not a keyword, TK_ID is returned.
*/
int sqliteKeywordCode(const char *z, int n){
  int h;
  Keyword *p;
  static char needInit = 1;
  if( needInit ){
    /* Initialize the keyword hash table */
    sqliteOsEnterMutex();

    if( needInit ){
      int i;
      int n;
      n = sizeof(aKeywordTable)/sizeof(aKeywordTable[0]);
      for(i=0; i<n; i++){
        aKeywordTable[i].len = strlen(aKeywordTable[i].zName);
        h = sqliteHashNoCase(aKeywordTable[i].zName, aKeywordTable[i].len);
        h %= KEY_HASH_SIZE;
        aKeywordTable[i].pNext = apHashTable[h];
        apHashTable[h] = &aKeywordTable[i];
      }
      needInit = 0;
    }
    sqliteOsLeaveMutex();
  }
  h = sqliteHashNoCase(z, n) % KEY_HASH_SIZE;
  for(p=apHashTable[h]; p; p=p->pNext){
    if( p->len==n && sqliteStrNICmp(p->zName, z, n)==0 ){
      return p->tokenType;

Changes to src/util.c.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
...
645
646
647
648
649
650
651































































652
653
654
655
656
657
658
...
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
...
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
**
*************************************************************************
** Utility functions used throughout sqlite.
**
** This file contains functions for allocating memory, comparing
** strings, and stuff like that.
**
** $Id: util.c,v 1.68 2003/10/22 22:15:28 drh Exp $
*/
#include "sqliteInt.h"
#include <stdarg.h>
#include <ctype.h>

/*
** If malloc() ever fails, this global variable gets set to 1.
................................................................................
    z++;
    if( *z=='+' || *z=='-' ) z++;
    if( !isdigit(*z) ) return 0;
    while( isdigit(*z) ){ z++; }
  }
  return *z==0;
}
































































/* This comparison routine is what we use for comparison operations
** between numeric values in an SQL expression.  "Numeric" is a little
** bit misleading here.  What we mean is that the strings have a
** type of "numeric" from the point of view of SQL.  The strings
** do not necessarily contain numbers.  They could contain text.
**
................................................................................
  isNumA = sqliteIsNumber(atext);
  isNumB = sqliteIsNumber(btext);
  if( isNumA ){
    if( !isNumB ){
      result = -1;
    }else{
      double rA, rB;
      rA = atof(atext);
      rB = atof(btext);
      if( rA<rB ){
        result = -1;
      }else if( rA>rB ){
        result = +1;
      }else{
        result = 0;
      }
................................................................................
      isNumB = sqliteIsNumber(&b[1]);
      if( isNumA ){
        double rA, rB;
        if( !isNumB ){
          res = -1;
          break;
        }
        rA = atof(&a[1]);
        rB = atof(&b[1]);
        if( rA<rB ){
          res = -1;
          break;
        }
        if( rA>rB ){
          res = +1;
          break;







|







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







|
|







 







|
|







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
...
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
...
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
...
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
**
*************************************************************************
** Utility functions used throughout sqlite.
**
** This file contains functions for allocating memory, comparing
** strings, and stuff like that.
**
** $Id: util.c,v 1.69 2003/12/23 02:17:35 drh Exp $
*/
#include "sqliteInt.h"
#include <stdarg.h>
#include <ctype.h>

/*
** If malloc() ever fails, this global variable gets set to 1.
................................................................................
    z++;
    if( *z=='+' || *z=='-' ) z++;
    if( !isdigit(*z) ) return 0;
    while( isdigit(*z) ){ z++; }
  }
  return *z==0;
}

/*
** The string z[] is an ascii 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.
**
** 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.
*/
double sqliteAtoF(const char *z){
  int sign = 1;
  double v1 = 0.0;
  if( *z=='-' ){
    sign = -1;
    z++;
  }else if( *z=='+' ){
    z++;
  }
  while( isdigit(*z) ){
    v1 = v1*10.0 + (*z - '0');
    z++;
  }
  if( *z=='.' ){
    double divisor = 1.0;
    z++;
    while( isdigit(*z) ){
      v1 = v1*10.0 + (*z - '0');
      divisor *= 10.0;
      z++;
    }
    v1 /= divisor;
  }
  if( *z=='e' || *z=='E' ){
    int esign = 1;
    int eval = 0;
    double scale = 1.0;
    z++;
    if( *z=='-' ){
      esign = -1;
      z++;
    }else if( *z=='+' ){
      z++;
    }
    while( isdigit(*z) ){
      eval = eval*10 + *z - '0';
      z++;
    }
    while( eval>=64 ){ scale *= 1.0e+64; eval -= 64; }
    while( eval>=16 ){ scale *= 1.0e+16; eval -= 16; }
    while( eval>=4 ){ scale *= 1.0e+4; eval -= 4; }
    while( eval>=1 ){ scale *= 1.0e+1; eval -= 1; }
    if( esign<0 ){
      v1 /= scale;
    }else{
      v1 *= scale;
    }
  }
  return sign<0 ? -v1 : v1;
}

/* This comparison routine is what we use for comparison operations
** between numeric values in an SQL expression.  "Numeric" is a little
** bit misleading here.  What we mean is that the strings have a
** type of "numeric" from the point of view of SQL.  The strings
** do not necessarily contain numbers.  They could contain text.
**
................................................................................
  isNumA = sqliteIsNumber(atext);
  isNumB = sqliteIsNumber(btext);
  if( isNumA ){
    if( !isNumB ){
      result = -1;
    }else{
      double rA, rB;
      rA = sqliteAtoF(atext);
      rB = sqliteAtoF(btext);
      if( rA<rB ){
        result = -1;
      }else if( rA>rB ){
        result = +1;
      }else{
        result = 0;
      }
................................................................................
      isNumB = sqliteIsNumber(&b[1]);
      if( isNumA ){
        double rA, rB;
        if( !isNumB ){
          res = -1;
          break;
        }
        rA = sqliteAtoF(&a[1]);
        rB = sqliteAtoF(&b[1]);
        if( rA<rB ){
          res = -1;
          break;
        }
        if( rA>rB ){
          res = +1;
          break;

Changes to src/vdbe.c.

39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
...
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
...
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
....
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
....
4664
4665
4666
4667
4668
4669
4670
4671
4672
4673
4674
4675
4676
4677
4678
....
4805
4806
4807
4808
4809
4810
4811
4812
4813
4814
4815
4816
4817
4818
4819
4820
4821
4822
4823
4824
4825
4826
**
** Various scripts scan this source file in order to generate HTML
** documentation, headers files, or other derived files.  The formatting
** of the code in this file is, therefore, important.  See other comments
** in this file for details.  If in doubt, do not deviate from existing
** commenting and indentation practices when changing or adding code.
**
** $Id: vdbe.c,v 1.245 2003/12/10 01:31:21 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>
#include "vdbeInt.h"

/*
................................................................................
** already.
*/
#define Stringify(P,I) if((aStack[I].flags & STK_Str)==0){hardStringify(P,I);}
static int hardStringify(Vdbe *p, int i){
  Stack *pStack = &p->aStack[i];
  int fg = pStack->flags;
  if( fg & STK_Real ){
    sprintf(pStack->z,"%.15g",pStack->r);
  }else if( fg & STK_Int ){
    sprintf(pStack->z,"%d",pStack->i);
  }else{
    pStack->z[0] = 0;
  }
  p->zStack[i] = pStack->z;
  pStack->n = strlen(pStack->z)+1;
  pStack->flags = STK_Str;
  return 0;
................................................................................
** Any prior string or integer representation is retained.
** NULLs are converted into 0.0.
*/
#define Realify(P,I) \
    if(((P)->aStack[(I)].flags&STK_Real)==0){ hardRealify(P,I); }
static void hardRealify(Vdbe *p, int i){
  if( p->aStack[i].flags & STK_Str ){
    p->aStack[i].r = atof(p->zStack[i]);
  }else if( p->aStack[i].flags & STK_Int ){
    p->aStack[i].r = p->aStack[i].i;
  }else{
    p->aStack[i].r = 0.0;
  }
  p->aStack[i].flags |= STK_Real;
}
................................................................................
      Stringify(p, i);
      aStack[i].flags &= ~(STK_Int|STK_Real);
      nByte += aStack[i].n+1;
    }else if( (flags & (STK_Real|STK_Int))!=0 || sqliteIsNumber(zStack[i]) ){
      if( (flags & (STK_Real|STK_Int))==STK_Int ){
        aStack[i].r = aStack[i].i;
      }else if( (flags & (STK_Real|STK_Int))==0 ){
        aStack[i].r = atof(zStack[i]);
      }
      Release(p, i);
      z = aStack[i].z;
      sqliteRealToSortable(aStack[i].r, z);
      len = strlen(z);
      zStack[i] = 0;
      aStack[i].flags = STK_Real;
................................................................................
  if( sqliteSafetyOn(db) ) goto abort_due_to_misuse;
  break;
}

/* An other opcode is illegal...
*/
default: {
  sprintf(zBuf,"%d",pOp->opcode);
  sqliteSetString(&p->zErrMsg, "unknown opcode ", zBuf, (char*)0);
  rc = SQLITE_INTERNAL;
  break;
}

/*****************************************************************************
** The cases of the switch statement above this line should all be indented
................................................................................
  sqliteSetString(&p->zErrMsg, sqlite_error_string(rc), (char*)0);
  goto vdbe_halt;

  /* Jump to here if a operator is encountered that requires more stack
  ** operands than are currently available on the stack.
  */
not_enough_stack:
  sprintf(zBuf,"%d",pc);
  sqliteSetString(&p->zErrMsg, "too few operands on stack at ", zBuf, (char*)0);
  rc = SQLITE_INTERNAL;
  goto vdbe_halt;

  /* Jump here if an illegal or illformed instruction is executed.
  */
VERIFY(
bad_instruction:
  sprintf(zBuf,"%d",pc);
  sqliteSetString(&p->zErrMsg, "illegal operation at ", zBuf, (char*)0);
  rc = SQLITE_INTERNAL;
  goto vdbe_halt;
)
}







|







 







|

|







 







|







 







|







 







|







 







|








|





39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
...
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
...
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
....
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
....
4664
4665
4666
4667
4668
4669
4670
4671
4672
4673
4674
4675
4676
4677
4678
....
4805
4806
4807
4808
4809
4810
4811
4812
4813
4814
4815
4816
4817
4818
4819
4820
4821
4822
4823
4824
4825
4826
**
** Various scripts scan this source file in order to generate HTML
** documentation, headers files, or other derived files.  The formatting
** of the code in this file is, therefore, important.  See other comments
** in this file for details.  If in doubt, do not deviate from existing
** commenting and indentation practices when changing or adding code.
**
** $Id: vdbe.c,v 1.246 2003/12/23 02:17:35 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>
#include "vdbeInt.h"

/*
................................................................................
** already.
*/
#define Stringify(P,I) if((aStack[I].flags & STK_Str)==0){hardStringify(P,I);}
static int hardStringify(Vdbe *p, int i){
  Stack *pStack = &p->aStack[i];
  int fg = pStack->flags;
  if( fg & STK_Real ){
    sqlite_snprintf(sizeof(pStack->z),pStack->z,"%.15g",pStack->r);
  }else if( fg & STK_Int ){
    sqlite_snprintf(sizeof(pStack->z),pStack->z,"%d",pStack->i);
  }else{
    pStack->z[0] = 0;
  }
  p->zStack[i] = pStack->z;
  pStack->n = strlen(pStack->z)+1;
  pStack->flags = STK_Str;
  return 0;
................................................................................
** Any prior string or integer representation is retained.
** NULLs are converted into 0.0.
*/
#define Realify(P,I) \
    if(((P)->aStack[(I)].flags&STK_Real)==0){ hardRealify(P,I); }
static void hardRealify(Vdbe *p, int i){
  if( p->aStack[i].flags & STK_Str ){
    p->aStack[i].r = sqliteAtoF(p->zStack[i]);
  }else if( p->aStack[i].flags & STK_Int ){
    p->aStack[i].r = p->aStack[i].i;
  }else{
    p->aStack[i].r = 0.0;
  }
  p->aStack[i].flags |= STK_Real;
}
................................................................................
      Stringify(p, i);
      aStack[i].flags &= ~(STK_Int|STK_Real);
      nByte += aStack[i].n+1;
    }else if( (flags & (STK_Real|STK_Int))!=0 || sqliteIsNumber(zStack[i]) ){
      if( (flags & (STK_Real|STK_Int))==STK_Int ){
        aStack[i].r = aStack[i].i;
      }else if( (flags & (STK_Real|STK_Int))==0 ){
        aStack[i].r = sqliteAtoF(zStack[i]);
      }
      Release(p, i);
      z = aStack[i].z;
      sqliteRealToSortable(aStack[i].r, z);
      len = strlen(z);
      zStack[i] = 0;
      aStack[i].flags = STK_Real;
................................................................................
  if( sqliteSafetyOn(db) ) goto abort_due_to_misuse;
  break;
}

/* An other opcode is illegal...
*/
default: {
  sqlite_snprintf(sizeof(zBuf),zBuf,"%d",pOp->opcode);
  sqliteSetString(&p->zErrMsg, "unknown opcode ", zBuf, (char*)0);
  rc = SQLITE_INTERNAL;
  break;
}

/*****************************************************************************
** The cases of the switch statement above this line should all be indented
................................................................................
  sqliteSetString(&p->zErrMsg, sqlite_error_string(rc), (char*)0);
  goto vdbe_halt;

  /* Jump to here if a operator is encountered that requires more stack
  ** operands than are currently available on the stack.
  */
not_enough_stack:
  sqlite_snprintf(sizeof(zBuf),zBuf,"%d",pc);
  sqliteSetString(&p->zErrMsg, "too few operands on stack at ", zBuf, (char*)0);
  rc = SQLITE_INTERNAL;
  goto vdbe_halt;

  /* Jump here if an illegal or illformed instruction is executed.
  */
VERIFY(
bad_instruction:
  sqlite_snprintf(sizeof(zBuf),zBuf,"%d",pc);
  sqliteSetString(&p->zErrMsg, "illegal operation at ", zBuf, (char*)0);
  rc = SQLITE_INTERNAL;
  goto vdbe_halt;
)
}

Changes to test/format3.test.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
#    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 the library is able to correctly
# handle file-format 3 (version 2.6.x) databases.
#
# $Id: format3.test,v 1.3 2003/06/03 01:47:12 drh Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

# Create a bunch of data to sort against
#
do_test format3-1.0 {
................................................................................
do_test format3-11.1 {
  execsql {SELECT '0'=='0.0'}
} {1}
do_test format3-11.2 {
  execsql {SELECT '0'==0.0}
} {1}
do_test format3-11.3 {
  execsql {SELECT '12345678901234567890'=='12345678901234567891'}
} {1}
do_test format3-11.4 {
  execsql {
    CREATE TABLE t6(a INT UNIQUE, b TEXT UNIQUE);
    INSERT INTO t6 VALUES('0','0.0');
    SELECT * FROM t6;
  }







|







 







|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
#    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 the library is able to correctly
# handle file-format 3 (version 2.6.x) databases.
#
# $Id: format3.test,v 1.4 2003/12/23 02:17:35 drh Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

# Create a bunch of data to sort against
#
do_test format3-1.0 {
................................................................................
do_test format3-11.1 {
  execsql {SELECT '0'=='0.0'}
} {1}
do_test format3-11.2 {
  execsql {SELECT '0'==0.0}
} {1}
do_test format3-11.3 {
  execsql {SELECT '123456789012345678901'=='123456789012345678900'}
} {1}
do_test format3-11.4 {
  execsql {
    CREATE TABLE t6(a INT UNIQUE, b TEXT UNIQUE);
    INSERT INTO t6 VALUES('0','0.0');
    SELECT * FROM t6;
  }

Changes to test/misc3.test.

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
..
63
64
65
66
67
68
69
70































71
#
#***********************************************************************
# This file implements regression tests for SQLite library.
#
# This file implements tests for miscellanous features that were
# left out of other test files.
#
# $Id: misc3.test,v 1.1 2003/12/17 23:57:36 drh Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

# Ticket #529.  Make sure an ABORT does not damage the in-memory cache
# that will be used by subsequent statements in the same transaction.
#
................................................................................
  catchsql {UPDATE t1 SET a=CASE a WHEN 128 THEN 127 ELSE a END, b='';}
  execsql {
    INSERT INTO t1 VALUES(200,'hello out there');
    COMMIT;
    PRAGMA integrity_check;
  }
} ok
































finish_test







|







 








>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
..
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
#
#***********************************************************************
# This file implements regression tests for SQLite library.
#
# This file implements tests for miscellanous features that were
# left out of other test files.
#
# $Id: misc3.test,v 1.2 2003/12/23 02:17:35 drh Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

# Ticket #529.  Make sure an ABORT does not damage the in-memory cache
# that will be used by subsequent statements in the same transaction.
#
................................................................................
  catchsql {UPDATE t1 SET a=CASE a WHEN 128 THEN 127 ELSE a END, b='';}
  execsql {
    INSERT INTO t1 VALUES(200,'hello out there');
    COMMIT;
    PRAGMA integrity_check;
  }
} ok

# Tests of the sqliteAtoF() function in util.c
#
do_test misc3-2.1 {
  execsql {SELECT 2e-25*0.5e25}
} 1
do_test misc3-2.2 {
  execsql {SELECT 2.0e-25*000000.500000000000000000000000000000e+00025}
} 1
do_test misc3-2.3 {
  execsql {SELECT 000000000002e-0000000025*0.5e25}
} 1
do_test misc3-2.4 {
  execsql {SELECT 2e-25*0.5e250}
} 1e+225
do_test misc3-2.5 {
  execsql {SELECT 2.0e-250*0.5e25}
} 1e-225
do_test misc3-2.6 {
  execsql {SELECT '-2.0e-127' * '-0.5e27'}
} 1e-100
do_test misc3-2.7 {
  execsql {SELECT '+2.0e-127' * '-0.5e27'}
} -1e-100
do_test misc3-2.8 {
  execsql {SELECT 2.0e-27 * '+0.5e+127'}
} 1e+100
do_test misc3-2.9 {
  execsql {SELECT 2.0e-27 * '+0.000005e+132'}
} 1e+100


finish_test