Enforce the restriction that 'unixepoch' only works as the first modifier
after the time-value. This has been documented since 2004, but has never actually been enforced before. Also add new test cases for date/time functions with evidence marks. FossilOrigin-Name: 64fa9e8c87179211cec248e6dfd7578502e6e969a19e91a4f0e21ed9b972a6bc
This commit is contained in:
parent
a5c9a70757
commit
4b51e8bd68
13
manifest
13
manifest
@ -1,5 +1,5 @@
|
||||
C Minor\sadjustment\sto\serror\shandling\sin\ssqlite3FinishCoding().
|
||||
D 2022-01-25T00:03:25.602
|
||||
C Enforce\sthe\srestriction\sthat\s'unixepoch'\sonly\sworks\sas\sthe\sfirst\smodifier\nafter\sthe\stime-value.\s\sThis\shas\sbeen\sdocumented\ssince\s2004,\sbut\shas\snever\nactually\sbeen\senforced\sbefore.\s\sAlso\sadd\snew\stest\scases\sfor\sdate/time\nfunctions\swith\sevidence\smarks.
|
||||
D 2022-01-27T13:52:01.555
|
||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
|
||||
@ -499,7 +499,7 @@ F src/build.c 9329120c4522d1ad881b9e62108870c8a5e994e31f4d813d0eb3de323d25e362
|
||||
F src/callback.c 4c19af69835787bfe790ac560f3071a824eb629f34e41f97b52ce5235c77de1c
|
||||
F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
|
||||
F src/ctime.c 2cce39df1a13e05b7633e6d21b651f21492471f991dd7b323a4ee4e7b7f0b7f1
|
||||
F src/date.c e25773f06a8f9043bfa1e5fa0bee93483c41933adfff0891752f00eadd12ab1c
|
||||
F src/date.c 41627dec396f3d33e2c317a065f9d59bb535982b2ea3a561c96e4d4cf1137b65
|
||||
F src/dbpage.c 8a01e865bf8bc6d7b1844b4314443a6436c07c3efe1d488ed89e81719047833a
|
||||
F src/dbstat.c 861e08690fcb0f2ee1165eff0060ea8d4f3e2ea10f80dab7d32ad70443a6ff2d
|
||||
F src/delete.c 52897a8516dc40753503c25eed0e305f09cc50ae474f22b0b4fd31d3b879cc08
|
||||
@ -837,6 +837,7 @@ F test/cursorhint2.test 6f3aa9cb19e7418967a10ec6905209bcbb5968054da855fc36c8beee
|
||||
F test/dataversion1.test 6e5e86ac681f0782e766ebcb56c019ae001522d114e0e111e5ebf68ccf2a7bb8
|
||||
F test/date.test 9b73bbeb1b82d9c1f44dec5cf563bf7da58d2373
|
||||
F test/date2.test 7e12ec14aaf4d5e6294b4ba140445b0eca06ea50062a9c3a69c4ee13d0b6f8b1
|
||||
F test/date3.test a1b77abf05c6772fe5ca2337cac1398892f2a41e62bce7e6be0f4a08a0e64ae5
|
||||
F test/dbdata.test 042f49acff3438f940eeba5868d3af080ae64ddf26ae78f80c92bec3ca7d8603
|
||||
F test/dbfuzz.c 73047c920d6210e5912c87cdffd9a1c281d4252e
|
||||
F test/dbfuzz001.test 55e1a3504f8dea84155e09912fe3b1c3ad77e0b1a938ec42ca03b8e51b321e30
|
||||
@ -1941,8 +1942,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
|
||||
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||
P e9361d72f362b390a31f667363b01cf9d4b78aa19ed5c97f21afe9da764b89c0
|
||||
R 2f204671367b290a50dcca5128a83ae4
|
||||
P a8db69411b0d1275909adeb21027784ada17af24efe3a59ae0ae2a897659ff17
|
||||
R a92b0ae1c265a80dc4f7e5c12c916bf4
|
||||
U drh
|
||||
Z 303c6274f1d08ea5df8933a6d290bc89
|
||||
Z 47b9e1bb1e6a61a53486ee72f7ca6190
|
||||
# Remove this line to create a well-formed Fossil manifest.
|
||||
|
@ -1 +1 @@
|
||||
a8db69411b0d1275909adeb21027784ada17af24efe3a59ae0ae2a897659ff17
|
||||
64fa9e8c87179211cec248e6dfd7578502e6e969a19e91a4f0e21ed9b972a6bc
|
@ -697,7 +697,7 @@ static int parseModifier(
|
||||
** SQLite (0..5373484.5) then the result will be NULL.
|
||||
*/
|
||||
if( sqlite3_stricmp(z, "julianday")==0 ){
|
||||
if( idx>1 ) return 1;
|
||||
if( idx>1 ) return 1; /* IMP: R-31176-64601 */
|
||||
if( p->validJD && p->rawS ){
|
||||
rc = 0;
|
||||
p->rawS = 0;
|
||||
@ -728,6 +728,7 @@ static int parseModifier(
|
||||
** seconds since 1970. Convert to a real julian day number.
|
||||
*/
|
||||
if( sqlite3_stricmp(z, "unixepoch")==0 && p->rawS ){
|
||||
if( idx>1 ) return 1; /* IMP: R-49255-55373 */
|
||||
r = p->s*1000.0 + 210866760000000.0;
|
||||
if( r>=0.0 && r<464269060800000.0 ){
|
||||
clearYMD_HMS_TZ(p);
|
||||
|
149
test/date3.test
Normal file
149
test/date3.test
Normal file
@ -0,0 +1,149 @@
|
||||
# 2022-01-27
|
||||
#
|
||||
# The author disclaims copyright to this source code. In place of
|
||||
# a legal notice, here is a blessing:
|
||||
#
|
||||
# May you do good and not evil.
|
||||
# May you find forgiveness for yourself and forgive others.
|
||||
# May you share freely, never taking more than you give.
|
||||
#
|
||||
#***********************************************************************
|
||||
# This file implements regression tests for SQLite library. The
|
||||
# focus of this file is testing date and time functions.
|
||||
#
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
|
||||
# Skip this whole file if date and time functions are omitted
|
||||
# at compile-time
|
||||
#
|
||||
ifcapable {!datetime} {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
|
||||
proc datetest {tnum expr result} {
|
||||
do_test date3-$tnum [subst {
|
||||
execsql "SELECT coalesce($expr,'NULL')"
|
||||
}] [list $result]
|
||||
}
|
||||
set tcl_precision 15
|
||||
|
||||
# EVIDENCE-OF: R-45708-63005 unixepoch(time-value, modifier, modifier,
|
||||
# ...)
|
||||
#
|
||||
datetest 1.1 {unixepoch('1970-01-01')} {0}
|
||||
datetest 1.2 {unixepoch('1969-12-31 23:59:59')} {-1}
|
||||
datetest 1.3 {unixepoch('2106-02-07 06:28:15')} {4294967295}
|
||||
datetest 1.4 {unixepoch('2106-02-07 06:28:16')} {4294967296}
|
||||
datetest 1.5 {unixepoch('9999-12-31 23:59:59')} {253402300799}
|
||||
datetest 1.6 {unixepoch('0000-01-01 00:00:00')} {-62167219200}
|
||||
|
||||
# EVIDENCE-OF: R-30877-63179 The unixepoch() function returns a unix
|
||||
# timestamp - the number of seconds since 1970-01-01 00:00:00 UTC.
|
||||
#
|
||||
for {set i 1} {$i<=100} {incr i} {
|
||||
set x [expr {int(rand()*0xfffffffff)-0xffffffff}]
|
||||
datetest 1.7.$i "unixepoch($x,'unixepoch')==$x" {1}
|
||||
}
|
||||
|
||||
# EVIDENCE-OF: R-62992-54137 The unixepoch() always returns an integer,
|
||||
# even if the input time-value has millisecond precision.
|
||||
#
|
||||
datetest 1.8 {unixepoch('2022-01-27 12:59:28.052')} {1643288368}
|
||||
|
||||
# EVIDENCE-OF: R-05412-24332 If the time-value is numeric (the
|
||||
# DDDDDDDDDD format) then the 'auto' modifier causes the time-value to
|
||||
# interpreted as either a julian day number or a unix timestamp,
|
||||
# depending on its magnitude.
|
||||
#
|
||||
# EVIDENCE-OF: R-56763-40111 If the value is between 0.0 and
|
||||
# 5373484.499999, then it is interpreted as a julian day number
|
||||
# (corresponding to dates between -4713-11-24 12:00:00 and 9999-12-31
|
||||
# 23:59:59, inclusive).
|
||||
#
|
||||
# EVIDENCE-OF: R-07289-49223 For numeric values outside of the range of
|
||||
# valid julian day numbers, but within the range of -210866760000 to
|
||||
# 253402300799, the 'auto' modifier causes the value to be interpreted
|
||||
# as a unix timestamp.
|
||||
#
|
||||
# EVIDENCE-OF: R-20795-34947 Other numeric values are out of range and
|
||||
# cause a NULL return.
|
||||
#
|
||||
foreach {tn jd date} {
|
||||
2.1 0.0 {-4713-11-24 12:00:00}
|
||||
2.2 5373484.4999999 {9999-12-31 23:59:59}
|
||||
2.3 2440587.5 {1970-01-01 00:00:00}
|
||||
2.4 2440587.49998843 {1969-12-31 23:59:59}
|
||||
2.5 2440615.7475463 {1970-01-29 05:56:28}
|
||||
|
||||
2.10 -1 {1969-12-31 23:59:59}
|
||||
2.11 5373485 {1970-03-04 04:38:05}
|
||||
2.12 -210866760000 {-4713-11-24 12:00:00}
|
||||
2.13 253402300799 {9999-12-31 23:59:59}
|
||||
|
||||
2.20 -210866760001 {NULL}
|
||||
2.21 253402300800 {NULL}
|
||||
} {
|
||||
datetest $tn "datetime($jd,'auto')" $date
|
||||
}
|
||||
|
||||
# EVIDENCE-OF: R-38886-35357 The 'auto' modifier is a no-op for text
|
||||
# time-values.
|
||||
#
|
||||
datetest 2.30 {date('2022-01-29','auto')==date('2022-01-29')} {1}
|
||||
|
||||
# EVIDENCE-OF: R-53132-26856 The 'auto' modifier can be used to work
|
||||
# with date/time values even in cases where it is not known if the
|
||||
# julian day number or unix timestamp formats are in use.
|
||||
#
|
||||
do_execsql_test date3-2.40 {
|
||||
WITH tx(timeval,datetime) AS (
|
||||
VALUES('2022-01-27 13:15:44','2022-01-27 13:15:44'),
|
||||
(2459607.05260275,'2022-01-27 13:15:44'),
|
||||
(1643289344,'2022-01-27 13:15:44')
|
||||
)
|
||||
SELECT datetime(timeval,'auto') == datetime FROM tx;
|
||||
} {1 1 1}
|
||||
|
||||
# EVIDENCE-OF: R-49255-55373 The "unixepoch" modifier (11) only works if
|
||||
# it immediately follows a time value in the DDDDDDDDDD format.
|
||||
#
|
||||
# EVIDENCE-OF: R-23075-39245 This modifier causes the DDDDDDDDDD to be
|
||||
# interpreted not as a Julian day number as it normally would be, but as
|
||||
# Unix Time - the number of seconds since 1970.
|
||||
#
|
||||
datetest 3.1 {datetime(2459607.05,'+1 hour','unixepoch')} {NULL}
|
||||
datetest 3.2 {datetime(2459607.05,'unixepoch','+1 hour')} {1970-01-29 12:13:27}
|
||||
|
||||
# EVIDENCE-OF: R-21150-52363 The "julianday" modifier must immediately
|
||||
# follow the initial time-value which must be of the form DDDDDDDDD.
|
||||
#
|
||||
# EVIDENCE-OF: R-31176-64601 Any other use of the 'julianday' modifier
|
||||
# is an error and causes the function to return NULL.
|
||||
#
|
||||
# EVIDENCE-OF: R-32483-36353 The 'julianday' modifier forces the
|
||||
# time-value number to be interpreted as a julian-day number.
|
||||
#
|
||||
# EVIDENCE-OF: R-25859-20124 The only difference is that adding
|
||||
# 'julianday' forces the DDDDDDDDD time-value format, and causes a NULL
|
||||
# to be returned if any other time-value format is used.
|
||||
#
|
||||
datetest 4.1 {datetime(2459607,'julianday')} {2022-01-27 12:00:00}
|
||||
datetest 4.2 {datetime(2459607,'+1 hour','julianday')} {NULL}
|
||||
datetest 4.3 {datetime('2022-01-27','julianday')} {NULL}
|
||||
|
||||
|
||||
|
||||
# EVIDENCE-OF: R-33431-18865 Unix timestamps for the first 63 days of
|
||||
# 1970 will be interpreted as julian day numbers.
|
||||
#
|
||||
do_execsql_test date3-5.0 {
|
||||
WITH inc(x) AS (VALUES(-10) UNION ALL SELECT x+1 FROM inc WHERE x<100)
|
||||
SELECT count(*) FROM inc
|
||||
WHERE datetime('1970-01-01',format('%+d days',x))
|
||||
<> datetime(unixepoch('1970-01-01',format('%+d days',x)),'auto');
|
||||
} {63}
|
||||
|
||||
finish_test
|
Loading…
Reference in New Issue
Block a user