From: drh Date: Tue, 29 Nov 2016 20:39:48 +0000 (+0000) Subject: The documentation says that the built-in date-time functions give undefined X-Git-Tag: version-3.16.0~93 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=3edb157e2316476aa88f28ad203382905fee363c;p=thirdparty%2Fsqlite.git The documentation says that the built-in date-time functions give undefined results for dates before 0000-01-01 and after 9999-12-31. Change the actually implementation so that the answer given is really NULL. This also avoids unnecessary hand-wringing over an signed integer overflow that might otherwise occur when processing out-of-bound dates. FossilOrigin-Name: d410a839752153c6d8be08f758abfbc16475745a --- diff --git a/manifest b/manifest index f7115da4be..733c2d390f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sbroken\shyperlinks\sto\sthe\ssqlite3_snapshot\sobjection\sdefinition\nin\sthe\sdocumentation.\s\sNo\schanges\sto\scode. -D 2016-11-28T21:22:26.486 +C The\sdocumentation\ssays\sthat\sthe\sbuilt-in\sdate-time\sfunctions\sgive\sundefined\nresults\sfor\sdates\sbefore\s0000-01-01\sand\safter\s9999-12-31.\s\sChange\sthe\nactually\simplementation\sso\sthat\sthe\sanswer\sgiven\sis\sreally\sNULL.\s\sThis\salso\navoids\sunnecessary\shand-wringing\sover\san\ssigned\sinteger\soverflow\sthat\smight\notherwise\soccur\swhen\sprocessing\sout-of-bound\sdates. +D 2016-11-29T20:39:48.413 F Makefile.in 6b572807415d3f0a379cebc9461416d8df4a12c8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc bb4d970894abbbe0e88d00aac29bd52af8bc95f4 @@ -337,7 +337,7 @@ F src/build.c 178f16698cbcb43402c343a9413fe22c99ffee21 F src/callback.c 2e76147783386374bf01b227f752c81ec872d730 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c a2a52d6e353f459d8ab0f07321f60fafa47d5421 -F src/date.c 95c9a8d00767e7221a8e9a31f4e913fc8029bf6b +F src/date.c 53a4019b90ae1c9cb990196eed0ed196d3f341e1 F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d F src/delete.c cac97d1117a3008934da3a6a587b3608e65e1495 F src/expr.c 8c224aa28278a5c1eed55247b7a571ff388ad5c2 @@ -626,7 +626,7 @@ F test/csv01.test e0ba3caaa57e4c667a0b45977689fb8082f14348 F test/ctime.test ff6c38e822459d6ca743c34901caf57740b08b54 F test/cursorhint.test 7bc346788390475e77a345da2b92270d04d35856 F test/cursorhint2.test fa41f0d997e67db921d08c31e73111b32811201a -F test/date.test 984ac1e3e5e031386866f034006148d3972b4a65 +F test/date.test 47e7f7057c0efac0e5e26da2d7b6a9a128139de6 F test/dbstatus.test 73149851b3aff14fc6db478e58f9083a66422cf5 F test/dbstatus2.test e93ab03bfae6d62d4d935f20de928c19ca0ed0ab F test/default.test 0cb49b1c315a0d81c81d775e407f66906a2a604d @@ -1535,7 +1535,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 7cc2d60dce90b8d4dca35708e33002ae6387806e -R de1f3e041fb172133322c08f2e17859a +P 9021f6875f897d8b609ebcc04162dc6e0b529a4a +R e95c6d806c4c5b465cfcf2c97462edc9 U drh -Z 0f2a9b7b29f5f440f84b18c2372070c3 +Z f7a67f418429ef937fb437b96080796e diff --git a/manifest.uuid b/manifest.uuid index aaf0921076..95eeb46ae6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9021f6875f897d8b609ebcc04162dc6e0b529a4a \ No newline at end of file +d410a839752153c6d8be08f758abfbc16475745a \ No newline at end of file diff --git a/src/date.c b/src/date.c index 8b2f2fa717..a90b5318b8 100644 --- a/src/date.c +++ b/src/date.c @@ -75,6 +75,7 @@ struct DateTime { char validJD; /* True (1) if iJD is valid */ char validTZ; /* True (1) if tz is valid */ char tzSet; /* Timezone was set explicitly */ + char isError; /* An overflow has occurred */ }; @@ -366,6 +367,15 @@ static int parseDateOrTime( return 1; } +/* +** 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>=148699540800000 && iJD<=464269060799999; +} + /* ** Compute the Year, Month, and Day from the julian day number. */ @@ -376,6 +386,10 @@ static void computeYMD(DateTime *p){ p->Y = 2000; p->M = 1; p->D = 1; + }else if( !validJulianDay(p->iJD) ){ + memset(p, 0, sizeof(*p)); + p->isError = 1; + return; }else{ Z = (int)((p->iJD + 43200000)/86400000); A = (int)((Z - 1867216.25)/36524.25); @@ -814,6 +828,7 @@ static int isDate( z = sqlite3_value_text(argv[i]); if( z==0 || parseModifier(context, (char*)z, p) ) return 1; } + if( p->isError || (p->validJD && !validJulianDay(p->iJD)) ) return 1; return 0; } diff --git a/test/date.test b/test/date.test index 2f48b111e6..0286bcc3bc 100644 --- a/test/date.test +++ b/test/date.test @@ -61,8 +61,8 @@ datetest 1.19 {julianday('2000-01-01 12:00:00.1')} 2451545.00000116 datetest 1.20 {julianday('2000-01-01 12:00:00.01')} 2451545.00000012 datetest 1.21 {julianday('2000-01-01 12:00:00.001')} 2451545.00000001 datetest 1.22 {julianday('2000-01-01 12:00:00.')} NULL -datetest 1.23 julianday(12345.6) 12345.6 -datetest 1.23b julianday('12345.6') 12345.6 +datetest 1.23 julianday(12345.6) NULL +datetest 1.23b julianday(1721059.5) 1721059.5 datetest 1.24 {julianday('2001-01-01 12:00:00 bogus')} NULL datetest 1.25 {julianday('2001-01-01 bogus')} NULL datetest 1.26 {julianday('2001-01-01 12:60:00')} NULL @@ -418,16 +418,6 @@ datetest 8.19 {datetime('now','11.25 seconds')} {2003-10-22 12:34:11} datetest 8.90 {datetime('now','abcdefghijklmnopqrstuvwyxzABCDEFGHIJLMNOP')} NULL set sqlite_current_time 0 -# Negative years work. Example: '-4713-11-26' is JD 1.5. -# -datetest 9.1 {julianday('-4713-11-24 12:00:00')} {0.0} -datetest 9.2 {julianday(datetime(5))} {5.0} -datetest 9.3 {julianday(datetime(10))} {10.0} -datetest 9.4 {julianday(datetime(100))} {100.0} -datetest 9.5 {julianday(datetime(1000))} {1000.0} -datetest 9.6 {julianday(datetime(10000))} {10000.0} -datetest 9.7 {julianday(datetime(100000))} {100000.0} - # datetime() with just an HH:MM:SS correctly inserts the date 2000-01-01. # datetest 10.1 {datetime('01:02:03')} {2000-01-01 01:02:03}