/ Check-in [9b3bcde1]
Login

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

Overview
Comment:Code cleanup in the date and time functions. (CVS 1263)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:9b3bcde1530091602e551435ffd7820eb79727d5
User & Date: drh 2004-02-22 17:49:33
Context
2004-02-22
18:40
Use sqliteErrorMsg instead of sqliteSetString whereever practical. (CVS 1264) check-in: 69aac043 user: drh tags: trunk
17:49
Code cleanup in the date and time functions. (CVS 1263) check-in: 9b3bcde1 user: drh tags: trunk
16:27
Rearrange the grammar some so that tokens that are used together appear together in the grammar file. This reduces the size of the parser tables and some of the jump tables in switch statements. (CVS 1262) check-in: d372c16e 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
..
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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
...
147
148
149
150
151
152
153
154
155
156
157
158
159
160

161
162
163
164
165
166
167
168
...
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
...
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278

279
280
281
282

283
284
285
286
287
288
289
...
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
** 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.11 2004/02/21 03:28:18 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.
................................................................................
  char validHMS;   /* True if h,m,s are valid */
  char validJD;    /* True if rJD is valid */
  char validTZ;    /* True if tz is valid */
};


/*
** Convert N digits from zDate into an integer.  Return
** -1 if zDate does not begin with N digits.









*/
static int getDigits(const char *zDate, int N){















  int val = 0;
  while( N-- ){
    if( !isdigit(*zDate) ) return -1;


    val = val*10 + *zDate - '0';
    zDate++;
  }

  return val;






}

/*
** Read text from z[] and convert into a floating point number.  Return
** the number of digits converted.
*/
static int getValue(const char *z, double *pR){
  double r = 0.0;
  double rDivide = 1.0;
  int isNeg = 0;
  int nChar = 0;
  if( *z=='+' ){
    z++;
    nChar++;
  }else if( *z=='-' ){
    z++;
    isNeg = 1;
    nChar++;
  }
  if( !isdigit(*z) ) return 0;
  while( isdigit(*z) ){
    r = r*10.0 + *z - '0';
    nChar++;
    z++;
  }
  if( *z=='.' && isdigit(z[1]) ){
    z++;
    nChar++;
    while( isdigit(*z) ){
      r = r*10.0 + *z - '0';
      rDivide *= 10.0;
      nChar++;
      z++;
    }
    r /= rDivide;
  }
  if( *z!=0 && !isspace(*z) ) return 0;
  *pR = isNeg ? -r : r;
  return nChar;
}

/*
** Parse a timezone extension on the end of a date-time.
** The extension is of the form:
**
**        (+/-)HH:MM
................................................................................
    sgn = -1;
  }else if( *zDate=='+' ){
    sgn = +1;
  }else{
    return *zDate!=0;
  }
  zDate++;
  nHr = getDigits(zDate, 2);
  if( nHr<0 || nHr>14 ) return 1;
  zDate += 2;
  if( zDate[0]!=':' ) return 1;
  zDate++;
  nMn = getDigits(zDate, 2);
  if( nMn<0 || nMn>59 ) return 1;

  zDate += 2;
  p->tz = sgn*(nMn + nHr*60);
  while( isspace(*zDate) ){ zDate++; }
  return *zDate!=0;
}

/*
** Parse times of the form HH:MM or HH:MM:SS or HH:MM:SS.FFFF.
................................................................................
** fractional seconds FFFF can be one or more digits.
**
** Return 1 if there is a parsing error and 0 on success.
*/
static int parseHhMmSs(const char *zDate, DateTime *p){
  int h, m, s;
  double ms = 0.0;
  h = getDigits(zDate, 2);
  if( h<0 || zDate[2]!=':' ) return 1;
  zDate += 3;
  m = getDigits(zDate, 2);
  if( m<0 || m>59 ) return 1;
  zDate += 2;
  if( *zDate==':' ){
    s = getDigits(&zDate[1], 2);
    if( s<0 || s>59 ) return 1;
    zDate += 3;
    if( *zDate=='.' && isdigit(zDate[1]) ){
      double rScale = 1.0;
      zDate++;
      while( isdigit(*zDate) ){
        ms = ms*10.0 + *zDate - '0';
        rScale *= 10.0;
        zDate++;
................................................................................

  if( zDate[0]=='-' ){
    zDate++;
    neg = 1;
  }else{
    neg = 0;
  }
  Y = getDigits(zDate, 4);
  if( Y<0 || zDate[4]!='-' ) return 1;
  zDate += 5;
  M = getDigits(zDate, 2);
  if( M<=0 || M>12 || zDate[2]!='-' ) return 1;
  zDate += 3;
  D = getDigits(zDate, 2);
  if( D<=0 || D>31 ) return 1;

  zDate += 2;
  while( isspace(*zDate) ){ zDate++; }
  if( isdigit(*zDate) ){
    if( parseHhMmSs(zDate, p) ) return 1;

  }else if( *zDate==0 ){
    p->validHMS = 0;
  }else{
    return 1;
  }
  p->validJD = 0;
  p->validYMD = 1;
................................................................................
    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;
}

/*







|







 







|
|
>
>
>
>
>
>
>
>
>

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







|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|







 







|
<
<
|
<
<
<
>
|







 







|
|
|
|
|
|
|
|
|
|







 







|
<
<
<
<
<
<
|
>
|

<
|
>







 







|







12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
..
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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129





























130
131
132
133
134
135
136
137
...
151
152
153
154
155
156
157
158


159



160
161
162
163
164
165
166
167
168
...
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
...
264
265
266
267
268
269
270
271






272
273
274
275

276
277
278
279
280
281
282
283
284
...
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.12 2004/02/22 17:49:33 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.
................................................................................
  char validHMS;   /* True if h,m,s are valid */
  char validJD;    /* True if rJD is valid */
  char validTZ;    /* True if tz is valid */
};


/*
** Convert zDate into one or more integers.  Additional arguments
** come in groups of 5 as follows:
**
**       N       number of digits in the integer
**       min     minimum allowed value of the integer
**       max     maximum allowed value of the integer
**       nextC   first character after the integer
**       pVal    where to write the integers value.
**
** Conversions continue until one with nextC==0 is encountered.
** The function returns the number of successful conversions.
*/
static int getDigits(const char *zDate, ...){
  va_list ap;
  int val;
  int N;
  int min;
  int max;
  int nextC;
  int *pVal;
  int cnt = 0;
  va_start(ap, zDate);
  do{
    N = va_arg(ap, int);
    min = va_arg(ap, int);
    max = va_arg(ap, int);
    nextC = va_arg(ap, int);
    pVal = va_arg(ap, int*);
    val = 0;
    while( N-- ){
      if( !isdigit(*zDate) ){
        return cnt;
      }
      val = val*10 + *zDate - '0';
      zDate++;
    }
    if( val<min || val>max || (nextC!=0 && nextC!=*zDate) ){
      return cnt;
    }
    *pVal = val;
    zDate++;
    cnt++;
  }while( nextC );
  return cnt;
}

/*
** Read text from z[] and convert into a floating point number.  Return
** the number of digits converted.
*/
static int getValue(const char *z, double *pR){
  const char *zEnd;
  *pR = sqliteAtoF(z, &zEnd);





























  return zEnd - z;
}

/*
** Parse a timezone extension on the end of a date-time.
** The extension is of the form:
**
**        (+/-)HH:MM
................................................................................
    sgn = -1;
  }else if( *zDate=='+' ){
    sgn = +1;
  }else{
    return *zDate!=0;
  }
  zDate++;
  if( getDigits(zDate, 2, 0, 14, ':', &nHr, 2, 0, 59, 0, &nMn)!=2 ){


    return 1;



  }
  zDate += 5;
  p->tz = sgn*(nMn + nHr*60);
  while( isspace(*zDate) ){ zDate++; }
  return *zDate!=0;
}

/*
** Parse times of the form HH:MM or HH:MM:SS or HH:MM:SS.FFFF.
................................................................................
** fractional seconds FFFF can be one or more digits.
**
** Return 1 if there is a parsing error and 0 on success.
*/
static int parseHhMmSs(const char *zDate, DateTime *p){
  int h, m, s;
  double ms = 0.0;
  if( getDigits(zDate, 2, 0, 24, ':', &h, 2, 0, 59, 0, &m)!=2 ){
    return 1;
  }
  zDate += 5;
  if( *zDate==':' ){
    zDate++;
    if( getDigits(zDate, 2, 0, 59, 0, &s)!=1 ){
      return 1;
    }
    zDate += 2;
    if( *zDate=='.' && isdigit(zDate[1]) ){
      double rScale = 1.0;
      zDate++;
      while( isdigit(*zDate) ){
        ms = ms*10.0 + *zDate - '0';
        rScale *= 10.0;
        zDate++;
................................................................................

  if( zDate[0]=='-' ){
    zDate++;
    neg = 1;
  }else{
    neg = 0;
  }
  if( getDigits(zDate,4,0,9999,'-',&Y,2,1,12,'-',&M,2,1,31,0,&D)!=3 ){






    return 1;
  }
  zDate += 10;
  while( isspace(*zDate) ){ zDate++; }

  if( parseHhMmSs(zDate, p)==0 ){
    /* We got the time */
  }else if( *zDate==0 ){
    p->validHMS = 0;
  }else{
    return 1;
  }
  p->validJD = 0;
  p->validYMD = 1;
................................................................................
    if( sqliteOsCurrentTime(&r)==0 ){
      p->rJD = r;
      p->validJD = 1;
      return 0;
    }
    return 1;
  }else if( sqliteIsNumber(zDate) ){
    p->rJD = sqliteAtoF(zDate, 0);
    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
...
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
...
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
...
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
** 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.40 2004/02/20 22:53:39 rdc 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);







|







 







|







 







|







 







|







12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
...
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
...
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
...
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
** 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.41 2004/02/22 17:49:34 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], 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], 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], 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/sqliteInt.h.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
....
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
**    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.217 2004/02/21 19:02:30 drh Exp $
*/
#include "config.h"
#include "sqlite.h"
#include "hash.h"
#include "parse.h"
#include "btree.h"
#include <stdio.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);
char *sqlite_snprintf(int,char*,const char*,...);
int sqliteFitsIn32Bits(const char *);







|







 







|


7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
....
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
**    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.218 2004/02/22 17:49:34 drh Exp $
*/
#include "config.h"
#include "sqlite.h"
#include "hash.h"
#include "parse.h"
#include "btree.h"
#include <stdio.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, const char **);
char *sqlite_snprintf(int,char*,const char*,...);
int sqliteFitsIn32Bits(const char *);

Changes to src/test1.c.

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
...
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
**    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.35 2004/02/21 19:41:04 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;
  }







|







 







|







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
...
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
**    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.36 2004/02/22 17:49:34 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], 0));
    }else{
      sqlite_set_result_error(context,"first argument should be one of: "
          "string int double", -1);
    }
    argc -= 2;
    argv += 2;
  }

Changes to src/util.c.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
...
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
...
597
598
599
600
601
602
603

604
605
606
607
608
609
610
...
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
...
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
**
*************************************************************************
** Utility functions used throughout sqlite.
**
** This file contains functions for allocating memory, comparing
** strings, and stuff like that.
**
** $Id: util.c,v 1.73 2004/02/21 19:02:31 drh Exp $
*/
#include "sqliteInt.h"
#include <stdarg.h>
#include <ctype.h>

/*
** If malloc() ever fails, this global variable gets set to 1.
................................................................................
** 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;
  LONGDOUBLE_TYPE v1 = 0.0;
  if( *z=='-' ){
    sign = -1;
    z++;
  }else if( *z=='+' ){
    z++;
................................................................................
    while( eval>=1 ){ scale *= 1.0e+1; eval -= 1; }
    if( esign<0 ){
      v1 /= scale;
    }else{
      v1 *= scale;
    }
  }

  return sign<0 ? -v1 : v1;
}

/*
** The string zNum represents an integer.  There might be some other
** information following the integer too, but that part is ignored.
** If the integer that the prefix of zNum represents will fit in a
................................................................................
  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;







|







 







|







 







>







 







|
|







 







|
|







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
...
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
...
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
...
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
...
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
**
*************************************************************************
** Utility functions used throughout sqlite.
**
** This file contains functions for allocating memory, comparing
** strings, and stuff like that.
**
** $Id: util.c,v 1.74 2004/02/22 17:49:34 drh Exp $
*/
#include "sqliteInt.h"
#include <stdarg.h>
#include <ctype.h>

/*
** If malloc() ever fails, this global variable gets set to 1.
................................................................................
** 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, const char **pzEnd){
  int sign = 1;
  LONGDOUBLE_TYPE v1 = 0.0;
  if( *z=='-' ){
    sign = -1;
    z++;
  }else if( *z=='+' ){
    z++;
................................................................................
    while( eval>=1 ){ scale *= 1.0e+1; eval -= 1; }
    if( esign<0 ){
      v1 /= scale;
    }else{
      v1 *= scale;
    }
  }
  if( pzEnd ) *pzEnd = z;
  return sign<0 ? -v1 : v1;
}

/*
** The string zNum represents an integer.  There might be some other
** information following the integer too, but that part is ignored.
** If the integer that the prefix of zNum represents will fit in a
................................................................................
  isNumA = sqliteIsNumber(atext);
  isNumB = sqliteIsNumber(btext);
  if( isNumA ){
    if( !isNumB ){
      result = -1;
    }else{
      double rA, rB;
      rA = sqliteAtoF(atext, 0);
      rB = sqliteAtoF(btext, 0);
      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], 0);
        rB = sqliteAtoF(&b[1], 0);
        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
...
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
....
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
**
** 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.266 2004/02/20 22:53:39 rdc Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>
#include "vdbeInt.h"

/*
................................................................................
**
** Any prior string or integer representation is retained.
** NULLs are converted into 0.0.
*/
#define Realify(P) if(((P)->flags&MEM_Real)==0){ hardRealify(P); }
static void hardRealify(Mem *pStack){
  if( pStack->flags & MEM_Str ){
    pStack->r = sqliteAtoF(pStack->z);
  }else if( pStack->flags & MEM_Int ){
    pStack->r = pStack->i;
  }else{
    pStack->r = 0.0;
  }
  pStack->flags |= MEM_Real;
}
................................................................................
      Stringify(pRec);
      pRec->flags &= ~(MEM_Int|MEM_Real);
      nByte += pRec->n+1;
    }else if( (flags & (MEM_Real|MEM_Int))!=0 || sqliteIsNumber(pRec->z) ){
      if( (flags & (MEM_Real|MEM_Int))==MEM_Int ){
        pRec->r = pRec->i;
      }else if( (flags & (MEM_Real|MEM_Int))==0 ){
        pRec->r = sqliteAtoF(pRec->z);
      }
      Release(pRec);
      z = pRec->zShort;
      sqliteRealToSortable(pRec->r, z);
      len = strlen(z);
      pRec->z = 0;
      pRec->flags = MEM_Real;







|







 







|







 







|







39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
...
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
....
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
**
** 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.267 2004/02/22 17:49:34 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>
#include "vdbeInt.h"

/*
................................................................................
**
** Any prior string or integer representation is retained.
** NULLs are converted into 0.0.
*/
#define Realify(P) if(((P)->flags&MEM_Real)==0){ hardRealify(P); }
static void hardRealify(Mem *pStack){
  if( pStack->flags & MEM_Str ){
    pStack->r = sqliteAtoF(pStack->z, 0);
  }else if( pStack->flags & MEM_Int ){
    pStack->r = pStack->i;
  }else{
    pStack->r = 0.0;
  }
  pStack->flags |= MEM_Real;
}
................................................................................
      Stringify(pRec);
      pRec->flags &= ~(MEM_Int|MEM_Real);
      nByte += pRec->n+1;
    }else if( (flags & (MEM_Real|MEM_Int))!=0 || sqliteIsNumber(pRec->z) ){
      if( (flags & (MEM_Real|MEM_Int))==MEM_Int ){
        pRec->r = pRec->i;
      }else if( (flags & (MEM_Real|MEM_Int))==0 ){
        pRec->r = sqliteAtoF(pRec->z, 0);
      }
      Release(pRec);
      z = pRec->zShort;
      sqliteRealToSortable(pRec->r, z);
      len = strlen(z);
      pRec->z = 0;
      pRec->flags = MEM_Real;