| Index: third_party/sqlite/src/src/date.c | 
| diff --git a/third_party/sqlite/src/src/date.c b/third_party/sqlite/src/src/date.c | 
| index 3d7604ab45380a6ca1282464cd338b3e301f7000..a08248ce2f2504bd18626c0f2b92639f6ff85943 100644 | 
| --- a/third_party/sqlite/src/src/date.c | 
| +++ b/third_party/sqlite/src/src/date.c | 
| @@ -50,54 +50,80 @@ | 
|  | 
| #ifndef SQLITE_OMIT_DATETIME_FUNCS | 
|  | 
| +/* | 
| +** The MSVC CRT on Windows CE may not have a localtime() function. | 
| +** So declare a substitute.  The substitute function itself is | 
| +** defined in "os_win.c". | 
| +*/ | 
| +#if !defined(SQLITE_OMIT_LOCALTIME) && defined(_WIN32_WCE) && \ | 
| +    (!defined(SQLITE_MSVC_LOCALTIME_API) || !SQLITE_MSVC_LOCALTIME_API) | 
| +struct tm *__cdecl localtime(const time_t *); | 
| +#endif | 
|  | 
| /* | 
| ** A structure for holding a single date and time. | 
| */ | 
| typedef struct DateTime DateTime; | 
| struct DateTime { | 
| -  sqlite3_int64 iJD; /* The julian day number times 86400000 */ | 
| -  int Y, M, D;       /* Year, month, and day */ | 
| -  int h, m;          /* Hour and minutes */ | 
| -  int tz;            /* Timezone offset in minutes */ | 
| -  double s;          /* Seconds */ | 
| -  char validYMD;     /* True (1) if Y,M,D are valid */ | 
| -  char validHMS;     /* True (1) if h,m,s are valid */ | 
| -  char validJD;      /* True (1) if iJD is valid */ | 
| -  char validTZ;      /* True (1) if tz is valid */ | 
| -  char tzSet;        /* Timezone was set explicitly */ | 
| +  sqlite3_int64 iJD;  /* The julian day number times 86400000 */ | 
| +  int Y, M, D;        /* Year, month, and day */ | 
| +  int h, m;           /* Hour and minutes */ | 
| +  int tz;             /* Timezone offset in minutes */ | 
| +  double s;           /* Seconds */ | 
| +  char validJD;       /* True (1) if iJD is valid */ | 
| +  char rawS;          /* Raw numeric value stored in s */ | 
| +  char validYMD;      /* True (1) if Y,M,D are valid */ | 
| +  char validHMS;      /* True (1) if h,m,s are valid */ | 
| +  char validTZ;       /* True (1) if tz is valid */ | 
| +  char tzSet;         /* Timezone was set explicitly */ | 
| +  char isError;       /* An overflow has occurred */ | 
| }; | 
|  | 
|  | 
| /* | 
| -** Convert zDate into one or more integers.  Additional arguments | 
| -** come in groups of 5 as follows: | 
| +** Convert zDate into one or more integers according to the conversion | 
| +** specifier zFormat. | 
| +** | 
| +** zFormat[] contains 4 characters for each integer converted, except for | 
| +** the last integer which is specified by three characters.  The meaning | 
| +** of a four-character format specifiers ABCD is: | 
| ** | 
| -**       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. | 
| +**    A:   number of digits to convert.  Always "2" or "4". | 
| +**    B:   minimum value.  Always "0" or "1". | 
| +**    C:   maximum value, decoded as: | 
| +**           a:  12 | 
| +**           b:  14 | 
| +**           c:  24 | 
| +**           d:  31 | 
| +**           e:  59 | 
| +**           f:  9999 | 
| +**    D:   the separator character, or \000 to indicate this is the | 
| +**         last number to convert. | 
| +** | 
| +** Example:  To translate an ISO-8601 date YYYY-MM-DD, the format would | 
| +** be "40f-21a-20c".  The "40f-" indicates the 4-digit year followed by "-". | 
| +** The "21a-" indicates the 2-digit month followed by "-".  The "20c" indicates | 
| +** the 2-digit day which is the last integer in the set. | 
| ** | 
| -** Conversions continue until one with nextC==0 is encountered. | 
| ** The function returns the number of successful conversions. | 
| */ | 
| -static int getDigits(const char *zDate, ...){ | 
| +static int getDigits(const char *zDate, const char *zFormat, ...){ | 
| +  /* The aMx[] array translates the 3rd character of each format | 
| +  ** spec into a max size:    a   b   c   d   e     f */ | 
| +  static const u16 aMx[] = { 12, 14, 24, 31, 59, 9999 }; | 
| va_list ap; | 
| -  int val; | 
| -  int N; | 
| -  int min; | 
| -  int max; | 
| -  int nextC; | 
| -  int *pVal; | 
| int cnt = 0; | 
| -  va_start(ap, zDate); | 
| +  char nextC; | 
| +  va_start(ap, zFormat); | 
| 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*); | 
| +    char N = zFormat[0] - '0'; | 
| +    char min = zFormat[1] - '0'; | 
| +    int val = 0; | 
| +    u16 max; | 
| + | 
| +    assert( zFormat[2]>='a' && zFormat[2]<='f' ); | 
| +    max = aMx[zFormat[2] - 'a']; | 
| +    nextC = zFormat[3]; | 
| val = 0; | 
| while( N-- ){ | 
| if( !sqlite3Isdigit(*zDate) ){ | 
| @@ -106,12 +132,13 @@ static int getDigits(const char *zDate, ...){ | 
| val = val*10 + *zDate - '0'; | 
| zDate++; | 
| } | 
| -    if( val<min || val>max || (nextC!=0 && nextC!=*zDate) ){ | 
| +    if( val<(int)min || val>(int)max || (nextC!=0 && nextC!=*zDate) ){ | 
| goto end_getDigits; | 
| } | 
| -    *pVal = val; | 
| +    *va_arg(ap,int*) = val; | 
| zDate++; | 
| cnt++; | 
| +    zFormat += 4; | 
| }while( nextC ); | 
| end_getDigits: | 
| va_end(ap); | 
| @@ -152,7 +179,7 @@ static int parseTimezone(const char *zDate, DateTime *p){ | 
| return c!=0; | 
| } | 
| zDate++; | 
| -  if( getDigits(zDate, 2, 0, 14, ':', &nHr, 2, 0, 59, 0, &nMn)!=2 ){ | 
| +  if( getDigits(zDate, "20b:20e", &nHr, &nMn)!=2 ){ | 
| return 1; | 
| } | 
| zDate += 5; | 
| @@ -173,13 +200,13 @@ zulu_time: | 
| 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 ){ | 
| +  if( getDigits(zDate, "20c:20e", &h, &m)!=2 ){ | 
| return 1; | 
| } | 
| zDate += 5; | 
| if( *zDate==':' ){ | 
| zDate++; | 
| -    if( getDigits(zDate, 2, 0, 59, 0, &s)!=1 ){ | 
| +    if( getDigits(zDate, "20e", &s)!=1 ){ | 
| return 1; | 
| } | 
| zDate += 2; | 
| @@ -197,6 +224,7 @@ static int parseHhMmSs(const char *zDate, DateTime *p){ | 
| s = 0; | 
| } | 
| p->validJD = 0; | 
| +  p->rawS = 0; | 
| p->validHMS = 1; | 
| p->h = h; | 
| p->m = m; | 
| @@ -207,6 +235,14 @@ static int parseHhMmSs(const char *zDate, DateTime *p){ | 
| } | 
|  | 
| /* | 
| +** Put the DateTime object into its error state. | 
| +*/ | 
| +static void datetimeError(DateTime *p){ | 
| +  memset(p, 0, sizeof(*p)); | 
| +  p->isError = 1; | 
| +} | 
| + | 
| +/* | 
| ** Convert from YYYY-MM-DD HH:MM:SS to julian day.  We always assume | 
| ** that the YYYY-MM-DD is according to the Gregorian calendar. | 
| ** | 
| @@ -225,6 +261,10 @@ static void computeJD(DateTime *p){ | 
| M = 1; | 
| D = 1; | 
| } | 
| +  if( Y<-4713 || Y>9999 || p->rawS ){ | 
| +    datetimeError(p); | 
| +    return; | 
| +  } | 
| if( M<=2 ){ | 
| Y--; | 
| M += 12; | 
| @@ -267,7 +307,7 @@ static int parseYyyyMmDd(const char *zDate, DateTime *p){ | 
| }else{ | 
| neg = 0; | 
| } | 
| -  if( getDigits(zDate,4,0,9999,'-',&Y,2,1,12,'-',&M,2,1,31,0,&D)!=3 ){ | 
| +  if( getDigits(zDate, "40f-21a-21d", &Y, &M, &D)!=3 ){ | 
| return 1; | 
| } | 
| zDate += 10; | 
| @@ -306,6 +346,21 @@ static int setDateTimeToCurrent(sqlite3_context *context, DateTime *p){ | 
| } | 
|  | 
| /* | 
| +** Input "r" is a numeric quantity which might be a julian day number, | 
| +** or the number of seconds since 1970.  If the value if r is within | 
| +** range of a julian day number, install it as such and set validJD. | 
| +** If the value is a valid unix timestamp, put it in p->s and set p->rawS. | 
| +*/ | 
| +static void setRawDateNumber(DateTime *p, double r){ | 
| +  p->s = r; | 
| +  p->rawS = 1; | 
| +  if( r>=0.0 && r<5373484.5 ){ | 
| +    p->iJD = (sqlite3_int64)(r*86400000.0 + 0.5); | 
| +    p->validJD = 1; | 
| +  } | 
| +} | 
| + | 
| +/* | 
| ** Attempt to parse the given string into a julian day number.  Return | 
| ** the number of errors. | 
| ** | 
| @@ -334,13 +389,30 @@ static int parseDateOrTime( | 
| }else if( sqlite3StrICmp(zDate,"now")==0){ | 
| return setDateTimeToCurrent(context, p); | 
| }else if( sqlite3AtoF(zDate, &r, sqlite3Strlen30(zDate), SQLITE_UTF8) ){ | 
| -    p->iJD = (sqlite3_int64)(r*86400000.0 + 0.5); | 
| -    p->validJD = 1; | 
| +    setRawDateNumber(p, r); | 
| return 0; | 
| } | 
| return 1; | 
| } | 
|  | 
| +/* The julian day number for 9999-12-31 23:59:59.999 is 5373484.4999999. | 
| +** Multiplying this by 86400000 gives 464269060799999 as the maximum value | 
| +** for DateTime.iJD. | 
| +** | 
| +** But some older compilers (ex: gcc 4.2.1 on older Macs) cannot deal with | 
| +** such a large integer literal, so we have to encode it. | 
| +*/ | 
| +#define INT_464269060799999  ((((i64)0x1a640)<<32)|0x1072fdff) | 
| + | 
| +/* | 
| +** Return TRUE if the given julian day number is within range. | 
| +** | 
| +** The input is the JulianDay times 86400000. | 
| +*/ | 
| +static int validJulianDay(sqlite3_int64 iJD){ | 
| +  return iJD>=0 && iJD<=INT_464269060799999; | 
| +} | 
| + | 
| /* | 
| ** Compute the Year, Month, and Day from the julian day number. | 
| */ | 
| @@ -352,6 +424,7 @@ static void computeYMD(DateTime *p){ | 
| p->M = 1; | 
| p->D = 1; | 
| }else{ | 
| +    assert( validJulianDay(p->iJD) ); | 
| Z = (int)((p->iJD + 43200000)/86400000); | 
| A = (int)((Z - 1867216.25)/36524.25); | 
| A = Z + 1 + A - (A/4); | 
| @@ -382,6 +455,7 @@ static void computeHMS(DateTime *p){ | 
| s -= p->h*3600; | 
| p->m = s/60; | 
| p->s += s - p->m*60; | 
| +  p->rawS = 0; | 
| p->validHMS = 1; | 
| } | 
|  | 
| @@ -402,6 +476,7 @@ static void clearYMD_HMS_TZ(DateTime *p){ | 
| p->validTZ = 0; | 
| } | 
|  | 
| +#ifndef SQLITE_OMIT_LOCALTIME | 
| /* | 
| ** On recent Windows platforms, the localtime_s() function is available | 
| ** as part of the "Secure CRT". It is essentially equivalent to | 
| @@ -420,7 +495,6 @@ static void clearYMD_HMS_TZ(DateTime *p){ | 
| #define HAVE_LOCALTIME_S 1 | 
| #endif | 
|  | 
| -#ifndef SQLITE_OMIT_LOCALTIME | 
| /* | 
| ** The following routine implements the rough equivalent of localtime_r() | 
| ** using whatever operating-system specific localtime facility that | 
| @@ -443,14 +517,14 @@ static int osLocaltime(time_t *t, struct tm *pTm){ | 
| #endif | 
| sqlite3_mutex_enter(mutex); | 
| pX = localtime(t); | 
| -#ifndef SQLITE_OMIT_BUILTIN_TEST | 
| +#ifndef SQLITE_UNTESTABLE | 
| if( sqlite3GlobalConfig.bLocaltimeFault ) pX = 0; | 
| #endif | 
| if( pX ) *pTm = *pX; | 
| sqlite3_mutex_leave(mutex); | 
| rc = pX==0; | 
| #else | 
| -#ifndef SQLITE_OMIT_BUILTIN_TEST | 
| +#ifndef SQLITE_UNTESTABLE | 
| if( sqlite3GlobalConfig.bLocaltimeFault ) return 1; | 
| #endif | 
| #if HAVE_LOCALTIME_R | 
| @@ -521,7 +595,9 @@ static sqlite3_int64 localtimeOffset( | 
| y.validYMD = 1; | 
| y.validHMS = 1; | 
| y.validJD = 0; | 
| +  y.rawS = 0; | 
| y.validTZ = 0; | 
| +  y.isError = 0; | 
| computeJD(&y); | 
| *pRc = SQLITE_OK; | 
| return y.iJD - x.iJD; | 
| @@ -529,6 +605,29 @@ static sqlite3_int64 localtimeOffset( | 
| #endif /* SQLITE_OMIT_LOCALTIME */ | 
|  | 
| /* | 
| +** The following table defines various date transformations of the form | 
| +** | 
| +**            'NNN days' | 
| +** | 
| +** Where NNN is an arbitrary floating-point number and "days" can be one | 
| +** of several units of time. | 
| +*/ | 
| +static const struct { | 
| +  u8 eType;           /* Transformation type code */ | 
| +  u8 nName;           /* Length of th name */ | 
| +  char *zName;        /* Name of the transformation */ | 
| +  double rLimit;      /* Maximum NNN value for this transform */ | 
| +  double rXform;      /* Constant used for this transform */ | 
| +} aXformType[] = { | 
| +  { 0, 6, "second", 464269060800.0, 86400000.0/(24.0*60.0*60.0) }, | 
| +  { 0, 6, "minute", 7737817680.0,   86400000.0/(24.0*60.0)      }, | 
| +  { 0, 4, "hour",   128963628.0,    86400000.0/24.0             }, | 
| +  { 0, 3, "day",    5373485.0,      86400000.0                  }, | 
| +  { 1, 5, "month",  176546.0,       30.0*86400000.0             }, | 
| +  { 2, 4, "year",   14713.0,        365.0*86400000.0            }, | 
| +}; | 
| + | 
| +/* | 
| ** Process a modifier to a date-time stamp.  The modifiers are | 
| ** as follows: | 
| ** | 
| @@ -552,17 +651,15 @@ static sqlite3_int64 localtimeOffset( | 
| ** to context pCtx. If the error is an unrecognized modifier, no error is | 
| ** written to pCtx. | 
| */ | 
| -static int parseModifier(sqlite3_context *pCtx, const char *zMod, DateTime *p){ | 
| +static int parseModifier( | 
| +  sqlite3_context *pCtx,      /* Function context */ | 
| +  const char *z,              /* The text of the modifier */ | 
| +  int n,                      /* Length of zMod in bytes */ | 
| +  DateTime *p                 /* The date/time value to be modified */ | 
| +){ | 
| int rc = 1; | 
| -  int n; | 
| double r; | 
| -  char *z, zBuf[30]; | 
| -  z = zBuf; | 
| -  for(n=0; n<ArraySize(zBuf)-1 && zMod[n]; n++){ | 
| -    z[n] = (char)sqlite3UpperToLower[(u8)zMod[n]]; | 
| -  } | 
| -  z[n] = 0; | 
| -  switch( z[0] ){ | 
| +  switch(sqlite3UpperToLower[(u8)z[0]] ){ | 
| #ifndef SQLITE_OMIT_LOCALTIME | 
| case 'l': { | 
| /*    localtime | 
| @@ -570,7 +667,7 @@ static int parseModifier(sqlite3_context *pCtx, const char *zMod, DateTime *p){ | 
| ** Assuming the current time value is UTC (a.k.a. GMT), shift it to | 
| ** show local time. | 
| */ | 
| -      if( strcmp(z, "localtime")==0 ){ | 
| +      if( sqlite3_stricmp(z, "localtime")==0 ){ | 
| computeJD(p); | 
| p->iJD += localtimeOffset(p, pCtx, &rc); | 
| clearYMD_HMS_TZ(p); | 
| @@ -582,16 +679,21 @@ static int parseModifier(sqlite3_context *pCtx, const char *zMod, DateTime *p){ | 
| /* | 
| **    unixepoch | 
| ** | 
| -      ** Treat the current value of p->iJD as the number of | 
| +      ** Treat the current value of p->s as the number of | 
| ** seconds since 1970.  Convert to a real julian day number. | 
| */ | 
| -      if( strcmp(z, "unixepoch")==0 && p->validJD ){ | 
| -        p->iJD = (p->iJD + 43200)/86400 + 21086676*(i64)10000000; | 
| -        clearYMD_HMS_TZ(p); | 
| -        rc = 0; | 
| +      if( sqlite3_stricmp(z, "unixepoch")==0 && p->rawS ){ | 
| +        r = p->s*1000.0 + 210866760000000.0; | 
| +        if( r>=0.0 && r<464269060800000.0 ){ | 
| +          clearYMD_HMS_TZ(p); | 
| +          p->iJD = (sqlite3_int64)r; | 
| +          p->validJD = 1; | 
| +          p->rawS = 0; | 
| +          rc = 0; | 
| +        } | 
| } | 
| #ifndef SQLITE_OMIT_LOCALTIME | 
| -      else if( strcmp(z, "utc")==0 ){ | 
| +      else if( sqlite3_stricmp(z, "utc")==0 ){ | 
| if( p->tzSet==0 ){ | 
| sqlite3_int64 c1; | 
| computeJD(p); | 
| @@ -617,7 +719,7 @@ static int parseModifier(sqlite3_context *pCtx, const char *zMod, DateTime *p){ | 
| ** weekday N where 0==Sunday, 1==Monday, and so forth.  If the | 
| ** date is already on the appropriate weekday, this is a no-op. | 
| */ | 
| -      if( strncmp(z, "weekday ", 8)==0 | 
| +      if( sqlite3_strnicmp(z, "weekday ", 8)==0 | 
| && sqlite3AtoF(&z[8], &r, sqlite3Strlen30(&z[8]), SQLITE_UTF8) | 
| && (n=(int)r)==r && n>=0 && r<7 ){ | 
| sqlite3_int64 Z; | 
| @@ -640,7 +742,7 @@ static int parseModifier(sqlite3_context *pCtx, const char *zMod, DateTime *p){ | 
| ** Move the date backwards to the beginning of the current day, | 
| ** or month or year. | 
| */ | 
| -      if( strncmp(z, "start of ", 9)!=0 ) break; | 
| +      if( sqlite3_strnicmp(z, "start of ", 9)!=0 ) break; | 
| z += 9; | 
| computeYMD(p); | 
| p->validHMS = 1; | 
| @@ -648,15 +750,15 @@ static int parseModifier(sqlite3_context *pCtx, const char *zMod, DateTime *p){ | 
| p->s = 0.0; | 
| p->validTZ = 0; | 
| p->validJD = 0; | 
| -      if( strcmp(z,"month")==0 ){ | 
| +      if( sqlite3_stricmp(z,"month")==0 ){ | 
| p->D = 1; | 
| rc = 0; | 
| -      }else if( strcmp(z,"year")==0 ){ | 
| +      }else if( sqlite3_stricmp(z,"year")==0 ){ | 
| computeYMD(p); | 
| p->M = 1; | 
| p->D = 1; | 
| rc = 0; | 
| -      }else if( strcmp(z,"day")==0 ){ | 
| +      }else if( sqlite3_stricmp(z,"day")==0 ){ | 
| rc = 0; | 
| } | 
| break; | 
| @@ -674,6 +776,7 @@ static int parseModifier(sqlite3_context *pCtx, const char *zMod, DateTime *p){ | 
| case '8': | 
| case '9': { | 
| double rRounder; | 
| +      int i; | 
| for(n=1; z[n] && z[n]!=':' && !sqlite3Isspace(z[n]); n++){} | 
| if( !sqlite3AtoF(z, &r, n, SQLITE_UTF8) ){ | 
| rc = 1; | 
| @@ -702,46 +805,48 @@ static int parseModifier(sqlite3_context *pCtx, const char *zMod, DateTime *p){ | 
| rc = 0; | 
| break; | 
| } | 
| + | 
| +      /* If control reaches this point, it means the transformation is | 
| +      ** one of the forms like "+NNN days".  */ | 
| z += n; | 
| while( sqlite3Isspace(*z) ) z++; | 
| n = sqlite3Strlen30(z); | 
| if( n>10 || n<3 ) break; | 
| -      if( z[n-1]=='s' ){ z[n-1] = 0; n--; } | 
| +      if( sqlite3UpperToLower[(u8)z[n-1]]=='s' ) n--; | 
| computeJD(p); | 
| -      rc = 0; | 
| +      rc = 1; | 
| rRounder = r<0 ? -0.5 : +0.5; | 
| -      if( n==3 && strcmp(z,"day")==0 ){ | 
| -        p->iJD += (sqlite3_int64)(r*86400000.0 + rRounder); | 
| -      }else if( n==4 && strcmp(z,"hour")==0 ){ | 
| -        p->iJD += (sqlite3_int64)(r*(86400000.0/24.0) + rRounder); | 
| -      }else if( n==6 && strcmp(z,"minute")==0 ){ | 
| -        p->iJD += (sqlite3_int64)(r*(86400000.0/(24.0*60.0)) + rRounder); | 
| -      }else if( n==6 && strcmp(z,"second")==0 ){ | 
| -        p->iJD += (sqlite3_int64)(r*(86400000.0/(24.0*60.0*60.0)) + rRounder); | 
| -      }else if( n==5 && strcmp(z,"month")==0 ){ | 
| -        int x, y; | 
| -        computeYMD_HMS(p); | 
| -        p->M += (int)r; | 
| -        x = p->M>0 ? (p->M-1)/12 : (p->M-12)/12; | 
| -        p->Y += x; | 
| -        p->M -= x*12; | 
| -        p->validJD = 0; | 
| -        computeJD(p); | 
| -        y = (int)r; | 
| -        if( y!=r ){ | 
| -          p->iJD += (sqlite3_int64)((r - y)*30.0*86400000.0 + rRounder); | 
| -        } | 
| -      }else if( n==4 && strcmp(z,"year")==0 ){ | 
| -        int y = (int)r; | 
| -        computeYMD_HMS(p); | 
| -        p->Y += y; | 
| -        p->validJD = 0; | 
| -        computeJD(p); | 
| -        if( y!=r ){ | 
| -          p->iJD += (sqlite3_int64)((r - y)*365.0*86400000.0 + rRounder); | 
| +      for(i=0; i<ArraySize(aXformType); i++){ | 
| +        if( aXformType[i].nName==n | 
| +         && sqlite3_strnicmp(aXformType[i].zName, z, n)==0 | 
| +         && r>-aXformType[i].rLimit && r<aXformType[i].rLimit | 
| +        ){ | 
| +          switch( aXformType[i].eType ){ | 
| +            case 1: { /* Special processing to add months */ | 
| +              int x; | 
| +              computeYMD_HMS(p); | 
| +              p->M += (int)r; | 
| +              x = p->M>0 ? (p->M-1)/12 : (p->M-12)/12; | 
| +              p->Y += x; | 
| +              p->M -= x*12; | 
| +              p->validJD = 0; | 
| +              r -= (int)r; | 
| +              break; | 
| +            } | 
| +            case 2: { /* Special processing to add years */ | 
| +              int y = (int)r; | 
| +              computeYMD_HMS(p); | 
| +              p->Y += y; | 
| +              p->validJD = 0; | 
| +              r -= (int)r; | 
| +              break; | 
| +            } | 
| +          } | 
| +          computeJD(p); | 
| +          p->iJD += (sqlite3_int64)(r*aXformType[i].rXform + rRounder); | 
| +          rc = 0; | 
| +          break; | 
| } | 
| -      }else{ | 
| -        rc = 1; | 
| } | 
| clearYMD_HMS_TZ(p); | 
| break; | 
| @@ -768,7 +873,7 @@ static int isDate( | 
| sqlite3_value **argv, | 
| DateTime *p | 
| ){ | 
| -  int i; | 
| +  int i, n; | 
| const unsigned char *z; | 
| int eType; | 
| memset(p, 0, sizeof(*p)); | 
| @@ -777,8 +882,7 @@ static int isDate( | 
| } | 
| if( (eType = sqlite3_value_type(argv[0]))==SQLITE_FLOAT | 
| || eType==SQLITE_INTEGER ){ | 
| -    p->iJD = (sqlite3_int64)(sqlite3_value_double(argv[0])*86400000.0 + 0.5); | 
| -    p->validJD = 1; | 
| +    setRawDateNumber(p, sqlite3_value_double(argv[0])); | 
| }else{ | 
| z = sqlite3_value_text(argv[0]); | 
| if( !z || parseDateOrTime(context, (char*)z, p) ){ | 
| @@ -787,8 +891,11 @@ static int isDate( | 
| } | 
| for(i=1; i<argc; i++){ | 
| z = sqlite3_value_text(argv[i]); | 
| -    if( z==0 || parseModifier(context, (char*)z, p) ) return 1; | 
| +    n = sqlite3_value_bytes(argv[i]); | 
| +    if( z==0 || parseModifier(context, (char*)z, n, p) ) return 1; | 
| } | 
| +  computeJD(p); | 
| +  if( p->isError || !validJulianDay(p->iJD) ) return 1; | 
| return 0; | 
| } | 
|  | 
| @@ -951,7 +1058,7 @@ static void strftimeFunc( | 
| sqlite3_result_error_toobig(context); | 
| return; | 
| }else{ | 
| -    z = sqlite3DbMallocRaw(db, (int)n); | 
| +    z = sqlite3DbMallocRawNN(db, (int)n); | 
| if( z==0 ){ | 
| sqlite3_result_error_nomem(context); | 
| return; | 
| @@ -1087,7 +1194,6 @@ static void currentTimeFunc( | 
| ){ | 
| time_t t; | 
| char *zFormat = (char *)sqlite3_user_data(context); | 
| -  sqlite3 *db; | 
| sqlite3_int64 iT; | 
| struct tm *pTm; | 
| struct tm sNow; | 
| @@ -1120,7 +1226,7 @@ static void currentTimeFunc( | 
| ** external linkage. | 
| */ | 
| void sqlite3RegisterDateTimeFunctions(void){ | 
| -  static SQLITE_WSD FuncDef aDateTimeFuncs[] = { | 
| +  static FuncDef aDateTimeFuncs[] = { | 
| #ifndef SQLITE_OMIT_DATETIME_FUNCS | 
| DFUNCTION(julianday,        -1, 0, 0, juliandayFunc ), | 
| DFUNCTION(date,             -1, 0, 0, dateFunc      ), | 
| @@ -1136,11 +1242,5 @@ void sqlite3RegisterDateTimeFunctions(void){ | 
| STR_FUNCTION(current_timestamp, 0, "%Y-%m-%d %H:%M:%S", 0, currentTimeFunc), | 
| #endif | 
| }; | 
| -  int i; | 
| -  FuncDefHash *pHash = &GLOBAL(FuncDefHash, sqlite3GlobalFunctions); | 
| -  FuncDef *aFunc = (FuncDef*)&GLOBAL(FuncDef, aDateTimeFuncs); | 
| - | 
| -  for(i=0; i<ArraySize(aDateTimeFuncs); i++){ | 
| -    sqlite3FuncDefInsert(pHash, &aFunc[i]); | 
| -  } | 
| +  sqlite3InsertBuiltinFuncs(aDateTimeFuncs, ArraySize(aDateTimeFuncs)); | 
| } | 
|  |