/ Check-in [b910a3d5]
Login

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

Overview
Comment: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.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:b910a3d53769689d9212a06f974ccce54844bbe4
User & Date: drh 2015-12-23 10:54:48
Context
2015-12-23
16:42
Fix some harmless gcc compiler warnings. Mostly in fts5, but also two in the core code. check-in: 5d44d4a6 user: dan tags: trunk
10:54
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. check-in: b910a3d5 user: drh tags: trunk
2015-12-21
15:22
Ensure that the Expr objects that describe indexed expressions are not modified by code generation. Fix for an assert() problem found by Jon Metzman using AFL. check-in: 34073ce8 user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/date.c.

    61     61     int h, m;          /* Hour and minutes */
    62     62     int tz;            /* Timezone offset in minutes */
    63     63     double s;          /* Seconds */
    64     64     char validYMD;     /* True (1) if Y,M,D are valid */
    65     65     char validHMS;     /* True (1) if h,m,s are valid */
    66     66     char validJD;      /* True (1) if iJD is valid */
    67     67     char validTZ;      /* True (1) if tz is valid */
           68  +  char tzSet;        /* Timezone was set explicitly */
    68     69   };
    69     70   
    70     71   
    71     72   /*
    72     73   ** Convert zDate into one or more integers.  Additional arguments
    73     74   ** come in groups of 5 as follows:
    74     75   **
................................................................................
   154    155     if( getDigits(zDate, 2, 0, 14, ':', &nHr, 2, 0, 59, 0, &nMn)!=2 ){
   155    156       return 1;
   156    157     }
   157    158     zDate += 5;
   158    159     p->tz = sgn*(nMn + nHr*60);
   159    160   zulu_time:
   160    161     while( sqlite3Isspace(*zDate) ){ zDate++; }
          162  +  p->tzSet = 1;
   161    163     return *zDate!=0;
   162    164   }
   163    165   
   164    166   /*
   165    167   ** Parse times of the form HH:MM or HH:MM:SS or HH:MM:SS.FFFF.
   166    168   ** The HH, MM, and SS must each be exactly 2 digits.  The
   167    169   ** fractional seconds FFFF can be one or more digits.
................................................................................
   586    588         if( strcmp(z, "unixepoch")==0 && p->validJD ){
   587    589           p->iJD = (p->iJD + 43200)/86400 + 21086676*(i64)10000000;
   588    590           clearYMD_HMS_TZ(p);
   589    591           rc = 0;
   590    592         }
   591    593   #ifndef SQLITE_OMIT_LOCALTIME
   592    594         else if( strcmp(z, "utc")==0 ){
   593         -        sqlite3_int64 c1;
   594         -        computeJD(p);
   595         -        c1 = localtimeOffset(p, pCtx, &rc);
   596         -        if( rc==SQLITE_OK ){
   597         -          p->iJD -= c1;
   598         -          clearYMD_HMS_TZ(p);
   599         -          p->iJD += c1 - localtimeOffset(p, pCtx, &rc);
          595  +        if( p->tzSet==0 ){
          596  +          sqlite3_int64 c1;
          597  +          computeJD(p);
          598  +          c1 = localtimeOffset(p, pCtx, &rc);
          599  +          if( rc==SQLITE_OK ){
          600  +            p->iJD -= c1;
          601  +            clearYMD_HMS_TZ(p);
          602  +            p->iJD += c1 - localtimeOffset(p, pCtx, &rc);
          603  +          }
          604  +          p->tzSet = 1;
          605  +        }else{
          606  +          rc = SQLITE_OK;
   600    607           }
   601    608         }
   602    609   #endif
   603    610         break;
   604    611       }
   605    612       case 'w': {
   606    613         /*

Changes to test/date.test.

   331    331       datetest 6.7.1 {datetime('2006-04-02 01:59:00','utc')} {2006-04-02 06:59:00}
   332    332     }
   333    333     datetest 6.7.2 {datetime('2007-03-11 01:59:00','utc')} {2007-03-11 06:59:00}
   334    334   
   335    335     datetest 6.8 {datetime('2000-04-02 02:00:00','utc')} {2000-04-02 06:00:00}
   336    336     datetest 6.8.1 {datetime('2006-04-02 02:00:00','utc')} {2006-04-02 06:00:00}
   337    337     datetest 6.8.2 {datetime('2007-03-11 02:00:00','utc')} {2007-03-11 06:00:00}
          338  +
          339  +  # The 'utc' modifier is a no-op if the LHS is known to already be in UTC
          340  +  datetest 6.9.1 {datetime('2015-12-23 12:00:00','utc')} {2015-12-23 17:00:00}
          341  +  datetest 6.9.2 {datetime('2015-12-23 12:00:00z','utc')} {2015-12-23 12:00:00}
          342  +  datetest 6.9.3 {datetime('2015-12-23 12:00:00-03:00','utc')} \
          343  +         {2015-12-23 15:00:00}
          344  +  datetest 6.9.4 {datetime('2015-12-23 12:00:00','utc','utc','utc')} \
          345  +         {2015-12-23 17:00:00}
          346  +
   338    347   
   339    348     datetest 6.10 {datetime('2000-01-01 12:00:00','localtime')} \
   340    349         {2000-01-01 07:00:00}
   341    350     datetest 6.11 {datetime('1969-01-01 12:00:00','localtime')} \
   342    351         {1969-01-01 07:00:00}
   343    352     datetest 6.12 {datetime('2039-01-01 12:00:00','localtime')} \
   344    353         {2039-01-01 07:00:00}