From caeca516a7df7ca63e662006f34a1b968a20b369 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 23 Dec 2015 10:54:48 +0000 Subject: [PATCH] Enhance the 'utc' modifier on date/time functions so that if the LHS is already known to be in UTC, the modifier becomes a no-op. This is not an incompatibility because the behavior is documented as "undefined" in that scenario. FossilOrigin-Name: b910a3d53769689d9212a06f974ccce54844bbe4 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/date.c | 21 ++++++++++++++------- test/date.test | 9 +++++++++ 4 files changed, 31 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index e171b344af..078eaef167 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Ensure\sthat\sthe\sExpr\sobjects\sthat\sdescribe\sindexed\sexpressions\sare\snot\smodified\nby\scode\sgeneration.\s\sFix\sfor\san\sassert()\sproblem\sfound\sby\sJon\sMetzman\susing\sAFL. -D 2015-12-21T15:22:13.811 +C Enhance\sthe\s'utc'\smodifier\son\sdate/time\sfunctions\sso\sthat\sif\sthe\sLHS\sis\nalready\sknown\sto\sbe\sin\sUTC,\sthe\smodifier\sbecomes\sa\sno-op.\s\sThis\sis\snot\san\nincompatibility\sbecause\sthe\sbehavior\sis\sdocumented\sas\s"undefined"\sin\sthat\nscenario. +D 2015-12-23T10:54:48.693 F Makefile.in 28bcd6149e050dff35d4dcfd97e890cd387a499d F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 5fff077fcc46de7714ed6eebb6159a4c00eab751 @@ -283,7 +283,7 @@ F src/build.c e83da4d004a4e050c01acbb821ff7a7b1019c29b F src/callback.c 7b44ce59674338ad48b0e84e7b72f935ea4f68b0 F src/complete.c addcd8160b081131005d5bc2d34adf20c1c5c92f F src/ctime.c 60e135af364d777a9ab41c97e5e89cd224da6198 -F src/date.c fb1c99172017dcc8e237339132c91a21a0788584 +F src/date.c e4655393bb403fa310eef66cc4583d75d4d7fd93 F src/dbstat.c ffd63fc8ba7541476ced189b95e95d7f2bc63f78 F src/delete.c 00af9f08a15ddc5cba5962d3d3e5bf2d67b2e7da F src/expr.c 414f4c6b016c4494bfb11713da79f27966871d91 @@ -563,7 +563,7 @@ F test/createtab.test b5de160630b209c4b8925bdcbbaf48cc90b67fe8 F test/cse.test 277350a26264495e86b1785f34d2d0c8600e021c F test/ctime.test 7bd009071e242aac4f18521581536b652b789a47 F test/cursorhint.test 432811b62bd5ffb812729f49bba3b9ad687550bb -F test/date.test 42973251b9429f2c41b77eb98a7b0b0ba2d3b2c0 +F test/date.test 984ac1e3e5e031386866f034006148d3972b4a65 F test/dbstatus.test 8de104bb5606f19537d23cd553b41349b5ab1204 F test/dbstatus2.test 10418e62b3db5dca070f0c3eef3ea13946f339c2 F test/default.test 0cb49b1c315a0d81c81d775e407f66906a2a604d @@ -1405,7 +1405,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 8bf5e056eb8beb6e0ed5874fb24d7fe9f0b66d2b -R e0404c0cd537e70ac5aa95195290d5e7 +P 34073ce87d88a02313217023ae92e15939192cd9 +R fb37875a5634d72cf8280c2958a6e17e U drh -Z ae8c1424b866e12742c6a5c15035540f +Z 5e4e9bf785bd86d0086510037196235b diff --git a/manifest.uuid b/manifest.uuid index 9837f3d4d4..c74bd62134 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -34073ce87d88a02313217023ae92e15939192cd9 \ No newline at end of file +b910a3d53769689d9212a06f974ccce54844bbe4 \ No newline at end of file diff --git a/src/date.c b/src/date.c index 8a66eae900..3d7604ab45 100644 --- a/src/date.c +++ b/src/date.c @@ -65,6 +65,7 @@ struct DateTime { 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 */ }; @@ -158,6 +159,7 @@ static int parseTimezone(const char *zDate, DateTime *p){ p->tz = sgn*(nMn + nHr*60); zulu_time: while( sqlite3Isspace(*zDate) ){ zDate++; } + p->tzSet = 1; return *zDate!=0; } @@ -590,13 +592,18 @@ static int parseModifier(sqlite3_context *pCtx, const char *zMod, DateTime *p){ } #ifndef SQLITE_OMIT_LOCALTIME else if( strcmp(z, "utc")==0 ){ - sqlite3_int64 c1; - computeJD(p); - c1 = localtimeOffset(p, pCtx, &rc); - if( rc==SQLITE_OK ){ - p->iJD -= c1; - clearYMD_HMS_TZ(p); - p->iJD += c1 - localtimeOffset(p, pCtx, &rc); + if( p->tzSet==0 ){ + sqlite3_int64 c1; + computeJD(p); + c1 = localtimeOffset(p, pCtx, &rc); + if( rc==SQLITE_OK ){ + p->iJD -= c1; + clearYMD_HMS_TZ(p); + p->iJD += c1 - localtimeOffset(p, pCtx, &rc); + } + p->tzSet = 1; + }else{ + rc = SQLITE_OK; } } #endif diff --git a/test/date.test b/test/date.test index b1d1c677c1..2f48b111e6 100644 --- a/test/date.test +++ b/test/date.test @@ -336,6 +336,15 @@ if {$tzoffset_new==4} { datetest 6.8.1 {datetime('2006-04-02 02:00:00','utc')} {2006-04-02 06:00:00} datetest 6.8.2 {datetime('2007-03-11 02:00:00','utc')} {2007-03-11 06:00:00} + # The 'utc' modifier is a no-op if the LHS is known to already be in UTC + datetest 6.9.1 {datetime('2015-12-23 12:00:00','utc')} {2015-12-23 17:00:00} + datetest 6.9.2 {datetime('2015-12-23 12:00:00z','utc')} {2015-12-23 12:00:00} + datetest 6.9.3 {datetime('2015-12-23 12:00:00-03:00','utc')} \ + {2015-12-23 15:00:00} + datetest 6.9.4 {datetime('2015-12-23 12:00:00','utc','utc','utc')} \ + {2015-12-23 17:00:00} + + datetest 6.10 {datetime('2000-01-01 12:00:00','localtime')} \ {2000-01-01 07:00:00} datetest 6.11 {datetime('1969-01-01 12:00:00','localtime')} \