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 b81049aa6531de3158c3f6656024b36011f419c4..11b04ea004b611457422108af8d83360be9d80ae 100644 |
--- a/third_party/sqlite/src/src/date.c |
+++ b/third_party/sqlite/src/src/date.c |
@@ -24,7 +24,7 @@ |
** 1970-01-01 00:00:00 is JD 2440587.5 |
** 2000-01-01 00:00:00 is JD 2451544.5 |
** |
-** This implemention requires years to be expressed as a 4-digit number |
+** This implementation requires years to be expressed as a 4-digit number |
** which means that only dates between 0000-01-01 and 9999-12-31 can |
** be represented, even though julian day numbers allow a much wider |
** range of dates. |
@@ -50,22 +50,6 @@ |
#ifndef SQLITE_OMIT_DATETIME_FUNCS |
-/* |
-** On recent Windows platforms, the localtime_s() function is available |
-** as part of the "Secure CRT". It is essentially equivalent to |
-** localtime_r() available under most POSIX platforms, except that the |
-** order of the parameters is reversed. |
-** |
-** See http://msdn.microsoft.com/en-us/library/a442x3ye(VS.80).aspx. |
-** |
-** If the user has not indicated to use localtime_r() or localtime_s() |
-** already, check for an MSVC build environment that provides |
-** localtime_s(). |
-*/ |
-#if !defined(HAVE_LOCALTIME_R) && !defined(HAVE_LOCALTIME_S) && \ |
- defined(_MSC_VER) && defined(_CRT_INSECURE_DEPRECATE) |
-#define HAVE_LOCALTIME_S 1 |
-#endif |
/* |
** A structure for holding a single date and time. |
@@ -305,12 +289,18 @@ static int parseYyyyMmDd(const char *zDate, DateTime *p){ |
} |
/* |
-** Set the time to the current time reported by the VFS |
+** Set the time to the current time reported by the VFS. |
+** |
+** Return the number of errors. |
*/ |
-static void setDateTimeToCurrent(sqlite3_context *context, DateTime *p){ |
- sqlite3 *db = sqlite3_context_db_handle(context); |
- sqlite3OsCurrentTimeInt64(db->pVfs, &p->iJD); |
- p->validJD = 1; |
+static int setDateTimeToCurrent(sqlite3_context *context, DateTime *p){ |
+ p->iJD = sqlite3StmtCurrentTime(context); |
+ if( p->iJD>0 ){ |
+ p->validJD = 1; |
+ return 0; |
+ }else{ |
+ return 1; |
+ } |
} |
/* |
@@ -340,8 +330,7 @@ static int parseDateOrTime( |
}else if( parseHhMmSs(zDate, p)==0 ){ |
return 0; |
}else if( sqlite3StrICmp(zDate,"now")==0){ |
- setDateTimeToCurrent(context, p); |
- return 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; |
@@ -411,18 +400,97 @@ static void clearYMD_HMS_TZ(DateTime *p){ |
p->validTZ = 0; |
} |
+/* |
+** On recent Windows platforms, the localtime_s() function is available |
+** as part of the "Secure CRT". It is essentially equivalent to |
+** localtime_r() available under most POSIX platforms, except that the |
+** order of the parameters is reversed. |
+** |
+** See http://msdn.microsoft.com/en-us/library/a442x3ye(VS.80).aspx. |
+** |
+** If the user has not indicated to use localtime_r() or localtime_s() |
+** already, check for an MSVC build environment that provides |
+** localtime_s(). |
+*/ |
+#if !defined(HAVE_LOCALTIME_R) && !defined(HAVE_LOCALTIME_S) && \ |
+ defined(_MSC_VER) && defined(_CRT_INSECURE_DEPRECATE) |
+#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 |
+** is available. This routine returns 0 on success and |
+** non-zero on any kind of error. |
+** |
+** If the sqlite3GlobalConfig.bLocaltimeFault variable is true then this |
+** routine will always fail. |
+** |
+** EVIDENCE-OF: R-62172-00036 In this implementation, the standard C |
+** library function localtime_r() is used to assist in the calculation of |
+** local time. |
+*/ |
+static int osLocaltime(time_t *t, struct tm *pTm){ |
+ int rc; |
+#if (!defined(HAVE_LOCALTIME_R) || !HAVE_LOCALTIME_R) \ |
+ && (!defined(HAVE_LOCALTIME_S) || !HAVE_LOCALTIME_S) |
+ struct tm *pX; |
+#if SQLITE_THREADSAFE>0 |
+ sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); |
+#endif |
+ sqlite3_mutex_enter(mutex); |
+ pX = localtime(t); |
+#ifndef SQLITE_OMIT_BUILTIN_TEST |
+ if( sqlite3GlobalConfig.bLocaltimeFault ) pX = 0; |
+#endif |
+ if( pX ) *pTm = *pX; |
+ sqlite3_mutex_leave(mutex); |
+ rc = pX==0; |
+#else |
+#ifndef SQLITE_OMIT_BUILTIN_TEST |
+ if( sqlite3GlobalConfig.bLocaltimeFault ) return 1; |
+#endif |
+#if defined(HAVE_LOCALTIME_R) && HAVE_LOCALTIME_R |
+ rc = localtime_r(t, pTm)==0; |
+#else |
+ rc = localtime_s(pTm, t); |
+#endif /* HAVE_LOCALTIME_R */ |
+#endif /* HAVE_LOCALTIME_R || HAVE_LOCALTIME_S */ |
+ return rc; |
+} |
+#endif /* SQLITE_OMIT_LOCALTIME */ |
+ |
+ |
#ifndef SQLITE_OMIT_LOCALTIME |
/* |
-** Compute the difference (in milliseconds) |
-** between localtime and UTC (a.k.a. GMT) |
-** for the time value p where p is in UTC. |
+** Compute the difference (in milliseconds) between localtime and UTC |
+** (a.k.a. GMT) for the time value p where p is in UTC. If no error occurs, |
+** return this value and set *pRc to SQLITE_OK. |
+** |
+** Or, if an error does occur, set *pRc to SQLITE_ERROR. The returned value |
+** is undefined in this case. |
*/ |
-static sqlite3_int64 localtimeOffset(DateTime *p){ |
+static sqlite3_int64 localtimeOffset( |
+ DateTime *p, /* Date at which to calculate offset */ |
+ sqlite3_context *pCtx, /* Write error here if one occurs */ |
+ int *pRc /* OUT: Error code. SQLITE_OK or ERROR */ |
+){ |
DateTime x, y; |
time_t t; |
+ struct tm sLocal; |
+ |
+ /* Initialize the contents of sLocal to avoid a compiler warning. */ |
+ memset(&sLocal, 0, sizeof(sLocal)); |
+ |
x = *p; |
computeYMD_HMS(&x); |
if( x.Y<1971 || x.Y>=2038 ){ |
+ /* EVIDENCE-OF: R-55269-29598 The localtime_r() C function normally only |
+ ** works for years between 1970 and 2037. For dates outside this range, |
+ ** SQLite attempts to map the year into an equivalent year within this |
+ ** range, do the calculation, then map the year back. |
+ */ |
x.Y = 2000; |
x.M = 1; |
x.D = 1; |
@@ -437,47 +505,23 @@ static sqlite3_int64 localtimeOffset(DateTime *p){ |
x.validJD = 0; |
computeJD(&x); |
t = (time_t)(x.iJD/1000 - 21086676*(i64)10000); |
-#ifdef HAVE_LOCALTIME_R |
- { |
- struct tm sLocal; |
- localtime_r(&t, &sLocal); |
- y.Y = sLocal.tm_year + 1900; |
- y.M = sLocal.tm_mon + 1; |
- y.D = sLocal.tm_mday; |
- y.h = sLocal.tm_hour; |
- y.m = sLocal.tm_min; |
- y.s = sLocal.tm_sec; |
- } |
-#elif defined(HAVE_LOCALTIME_S) && HAVE_LOCALTIME_S |
- { |
- struct tm sLocal; |
- localtime_s(&sLocal, &t); |
- y.Y = sLocal.tm_year + 1900; |
- y.M = sLocal.tm_mon + 1; |
- y.D = sLocal.tm_mday; |
- y.h = sLocal.tm_hour; |
- y.m = sLocal.tm_min; |
- y.s = sLocal.tm_sec; |
- } |
-#else |
- { |
- struct tm *pTm; |
- sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)); |
- pTm = localtime(&t); |
- y.Y = pTm->tm_year + 1900; |
- y.M = pTm->tm_mon + 1; |
- y.D = pTm->tm_mday; |
- y.h = pTm->tm_hour; |
- y.m = pTm->tm_min; |
- y.s = pTm->tm_sec; |
- sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)); |
+ if( osLocaltime(&t, &sLocal) ){ |
+ sqlite3_result_error(pCtx, "local time unavailable", -1); |
+ *pRc = SQLITE_ERROR; |
+ return 0; |
} |
-#endif |
+ y.Y = sLocal.tm_year + 1900; |
+ y.M = sLocal.tm_mon + 1; |
+ y.D = sLocal.tm_mday; |
+ y.h = sLocal.tm_hour; |
+ y.m = sLocal.tm_min; |
+ y.s = sLocal.tm_sec; |
y.validYMD = 1; |
y.validHMS = 1; |
y.validJD = 0; |
y.validTZ = 0; |
computeJD(&y); |
+ *pRc = SQLITE_OK; |
return y.iJD - x.iJD; |
} |
#endif /* SQLITE_OMIT_LOCALTIME */ |
@@ -501,9 +545,12 @@ static sqlite3_int64 localtimeOffset(DateTime *p){ |
** localtime |
** utc |
** |
-** Return 0 on success and 1 if there is any kind of error. |
+** Return 0 on success and 1 if there is any kind of error. If the error |
+** is in a system call (i.e. localtime()), then an error message is written |
+** to context pCtx. If the error is an unrecognized modifier, no error is |
+** written to pCtx. |
*/ |
-static int parseModifier(const char *zMod, DateTime *p){ |
+static int parseModifier(sqlite3_context *pCtx, const char *zMod, DateTime *p){ |
int rc = 1; |
int n; |
double r; |
@@ -523,9 +570,8 @@ static int parseModifier(const char *zMod, DateTime *p){ |
*/ |
if( strcmp(z, "localtime")==0 ){ |
computeJD(p); |
- p->iJD += localtimeOffset(p); |
+ p->iJD += localtimeOffset(p, pCtx, &rc); |
clearYMD_HMS_TZ(p); |
- rc = 0; |
} |
break; |
} |
@@ -546,11 +592,12 @@ static int parseModifier(const char *zMod, DateTime *p){ |
else if( strcmp(z, "utc")==0 ){ |
sqlite3_int64 c1; |
computeJD(p); |
- c1 = localtimeOffset(p); |
- p->iJD -= c1; |
- clearYMD_HMS_TZ(p); |
- p->iJD += c1 - localtimeOffset(p); |
- rc = 0; |
+ c1 = localtimeOffset(p, pCtx, &rc); |
+ if( rc==SQLITE_OK ){ |
+ p->iJD -= c1; |
+ clearYMD_HMS_TZ(p); |
+ p->iJD += c1 - localtimeOffset(p, pCtx, &rc); |
+ } |
} |
#endif |
break; |
@@ -719,8 +766,9 @@ static int isDate( |
int eType; |
memset(p, 0, sizeof(*p)); |
if( argc==0 ){ |
- setDateTimeToCurrent(context, p); |
- }else if( (eType = sqlite3_value_type(argv[0]))==SQLITE_FLOAT |
+ return setDateTimeToCurrent(context, p); |
+ } |
+ 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; |
@@ -731,9 +779,8 @@ static int isDate( |
} |
} |
for(i=1; i<argc; i++){ |
- if( (z = sqlite3_value_text(argv[i]))==0 || parseModifier((char*)z, p) ){ |
- return 1; |
- } |
+ z = sqlite3_value_text(argv[i]); |
+ if( z==0 || parseModifier(context, (char*)z, p) ) return 1; |
} |
return 0; |
} |
@@ -1033,31 +1080,28 @@ static void currentTimeFunc( |
char *zFormat = (char *)sqlite3_user_data(context); |
sqlite3 *db; |
sqlite3_int64 iT; |
+ struct tm *pTm; |
+ struct tm sNow; |
char zBuf[20]; |
UNUSED_PARAMETER(argc); |
UNUSED_PARAMETER(argv); |
- db = sqlite3_context_db_handle(context); |
- sqlite3OsCurrentTimeInt64(db->pVfs, &iT); |
+ iT = sqlite3StmtCurrentTime(context); |
+ if( iT<=0 ) return; |
t = iT/1000 - 10000*(sqlite3_int64)21086676; |
#ifdef HAVE_GMTIME_R |
- { |
- struct tm sNow; |
- gmtime_r(&t, &sNow); |
- strftime(zBuf, 20, zFormat, &sNow); |
- } |
+ pTm = gmtime_r(&t, &sNow); |
#else |
- { |
- struct tm *pTm; |
- sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)); |
- pTm = gmtime(&t); |
- strftime(zBuf, 20, zFormat, pTm); |
- sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)); |
- } |
+ sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)); |
+ pTm = gmtime(&t); |
+ if( pTm ) memcpy(&sNow, pTm, sizeof(sNow)); |
+ sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)); |
#endif |
- |
- sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT); |
+ if( pTm ){ |
+ strftime(zBuf, 20, zFormat, &sNow); |
+ sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT); |
+ } |
} |
#endif |