]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Prototype implementation of a proposed "timediff(X,Y)" SQL function.
authordrh <>
Mon, 29 May 2023 18:01:42 +0000 (18:01 +0000)
committerdrh <>
Mon, 29 May 2023 18:01:42 +0000 (18:01 +0000)
FossilOrigin-Name: 054a195125a273bab026ada5f07cc7c32818007027a1fd028ca59d2f179276d4

manifest
manifest.uuid
src/date.c

index 59a53cb9fbc90717e3330510fd0b5bc2ce2b48f3..7bca2b96d283b29372cbbe3a67a0ef04d98a775e 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Fix\san\sissue\swith\ssqldiff\sreported\sby\n[forum:/info/9bd2155bdfae25a7|forum\spost\s9bd2155bdfae25a7].
-D 2023-05-27T20:08:23.912
+C Prototype\simplementation\sof\sa\sproposed\s"timediff(X,Y)"\sSQL\sfunction.
+D 2023-05-29T18:01:42.123
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -583,7 +583,7 @@ F src/build.c 5512d5a335334b48d116f1ecd051edef96a60add18ae48e0ea302a395f00f3d9
 F src/callback.c db3a45e376deff6a16c0058163fe0ae2b73a2945f3f408ca32cf74960b28d490
 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
 F src/ctime.c 20507cc0b0a6c19cd882fcd0eaeda32ae6a4229fb4b024cfdf3183043d9b703d
-F src/date.c aca9e0c08b400b21238b609aea7c09585396cd770985cf8f475560f69222dad3
+F src/date.c 6ac049e14f0da389ed5f5166d7beefd7c456a736f859f2d82c6a0755d1eb644e
 F src/dbpage.c f3eea5f7ec47e09ee7da40f42b25092ecbe961fc59566b8e5f705f34335b2387
 F src/dbstat.c ec92074baa61d883de58c945162d9e666c13cd7cf3a23bc38b4d1c4d0b2c2bef
 F src/delete.c 05e27e3a55dcfeadf2f7ca95a5c5e0928f182c04640ec1954ffa42f3d5c19341
@@ -2071,8 +2071,11 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
 F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P b5b5eaeed3ef55415e27aa04561ab446f3be881b56b7cbf9b8ba3307f0b2bf69
-R a97b6bbc5714e405091cdcf5e322eddf
+P 736a79c1491065f4ee77ce644af0e529e555ca733c78dbd55487d55d4ddbe5bd
+R 7cd65956485b173b36f53ea0da1803ea
+T *branch * timediff
+T *sym-timediff *
+T -sym-trunk *
 U drh
-Z 1c9966bc9ba55db651e2a9b574f4ed8b
+Z 45e81044200c651866d6b14e1f654b51
 # Remove this line to create a well-formed Fossil manifest.
index 6ce0a15694c746d009267ebed76d6bd52cc988bc..0f63d3a2bb3dfac5df62f81e0330be465b96f619 100644 (file)
@@ -1 +1 @@
-736a79c1491065f4ee77ce644af0e529e555ca733c78dbd55487d55d4ddbe5bd
\ No newline at end of file
+054a195125a273bab026ada5f07cc7c32818007027a1fd028ca59d2f179276d4
\ No newline at end of file
index 9b7957bbf08a90e61974f2da91ca29df3a0ef2b6..028c3389e7ffd3fc12e6e8fa42057e5bc42fb993 100644 (file)
@@ -641,6 +641,25 @@ static const struct {
   { 4, "year",   14713.0,   31536000.0  },
 };
 
+/*
+** If the DateTime p is raw number, try to figure out if it is
+** a julian day number of a unix timestamp.  Set the p value
+** appropriately.
+*/
+static void autoAdjustDate(DateTime *p){
+  if( !p->rawS || p->validJD ){
+    p->rawS = 0;
+  }else if( p->s>=-21086676*(i64)10000        /* -4713-11-24 12:00:00 */
+         && p->s<=(25340230*(i64)10000)+799   /*  9999-12-31 23:59:59 */
+  ){
+    double r = p->s*1000.0 + 210866760000000.0;
+    clearYMD_HMS_TZ(p);
+    p->iJD = (sqlite3_int64)(r + 0.5);
+    p->validJD = 1;
+    p->rawS = 0;
+  }
+}
+
 /*
 ** Process a modifier to a date-time stamp.  The modifiers are
 ** as follows:
@@ -684,19 +703,8 @@ static int parseModifier(
       */
       if( sqlite3_stricmp(z, "auto")==0 ){
         if( idx>1 ) return 1; /* IMP: R-33611-57934 */
-        if( !p->rawS || p->validJD ){
-          rc = 0;
-          p->rawS = 0;
-        }else if( p->s>=-21086676*(i64)10000        /* -4713-11-24 12:00:00 */
-               && p->s<=(25340230*(i64)10000)+799   /*  9999-12-31 23:59:59 */
-        ){
-          r = p->s*1000.0 + 210866760000000.0;
-          clearYMD_HMS_TZ(p);
-          p->iJD = (sqlite3_int64)(r + 0.5);
-          p->validJD = 1;
-          p->rawS = 0;
-          rc = 0;
-        }
+        autoAdjustDate(p);
+        rc = 0;
       }
       break;
     }
@@ -1325,6 +1333,61 @@ static void cdateFunc(
   dateFunc(context, 0, 0);
 }
 
+/*
+** timediff(DATE1, DATE2)
+**
+** Return the that amount of time that DATE1 is later than DATE2 in
+** this format:
+**
+**     +YYYY-MM-DD HH:MM:SS.SSS
+**
+** The initial "+" becomes "-" if DATE1 occurs before DATE2.
+*/
+static void timediffFunc(
+  sqlite3_context *context,
+  int argc,
+  sqlite3_value **argv
+){
+  DateTime d1, d2;
+  sqlite3_str *pOut = 0;
+  char sign = '+';
+  int rc;
+  if( isDate(context, 1, argv, &d1)     ) return;
+  if( isDate(context, 1, &argv[1], &d2) ) return;
+  autoAdjustDate(&d1);
+  computeJD(&d1);
+  autoAdjustDate(&d2);
+  computeJD(&d2);
+  pOut = sqlite3_str_new(sqlite3_context_db_handle(context));
+  if( pOut==0 ){
+    sqlite3_result_error_nomem(context);
+    return;
+  }
+  if( d1.iJD<d2.iJD ){
+    sign = '-';
+    DateTime x = d1;
+    d1 = d2;
+    d2 = x;
+  }
+  d1.validYMD = 0;
+  d1.validHMS = 0;
+  d1.validTZ = 0;
+  d1.iJD -= d2.iJD;
+  d1.iJD += 148699540800000;
+  computeYMD_HMS(&d1);
+  sqlite3_str_appendf(pOut, "%c%04d-%02d-%02d %02d:%02d:%07.3f",
+     sign, d1.Y, d1.M-1, d1.D-1, d1.h, d1.m, d1.s);
+  rc = sqlite3_str_errcode(pOut);
+  if( rc ){
+    sqlite3_free(sqlite3_str_finish(pOut));
+    sqlite3_result_error_code(context, rc);
+  }else{
+    sqlite3_result_text(context, 
+        sqlite3_str_finish(pOut), -1, sqlite3_free);
+  }
+}
+
+
 /*
 ** current_timestamp()
 **
@@ -1399,6 +1462,7 @@ void sqlite3RegisterDateTimeFunctions(void){
     PURE_DATE(time,             -1, 0, 0, timeFunc      ),
     PURE_DATE(datetime,         -1, 0, 0, datetimeFunc  ),
     PURE_DATE(strftime,         -1, 0, 0, strftimeFunc  ),
+    PURE_DATE(timediff,          2, 0, 0, timediffFunc  ),
     DFUNCTION(current_time,      0, 0, 0, ctimeFunc     ),
     DFUNCTION(current_timestamp, 0, 0, 0, ctimestampFunc),
     DFUNCTION(current_date,      0, 0, 0, cdateFunc     ),