1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-08-08 14:02:16 +03:00

Merge trunk enhancements into the begin-concurrent branch.

FossilOrigin-Name: 85054a8691cec593b0490b78715a506f25a8cbe04cbf673129c0e17f7f5fa912
This commit is contained in:
drh
2022-02-04 17:40:59 +00:00
48 changed files with 1909 additions and 270 deletions

View File

@@ -969,4 +969,13 @@ foreach {tn file rc} {
db2 close
}
# 2021-01-31 https://sqlite.org/forum/forumpost/8b39fbf3e7
#
do_test backup-11.1 {
sqlite3 db1 :memory:
sqlite3 db2 :memory:
sqlite3_backup B db1 main db2 temp
B finish
} {SQLITE_OK}
finish_test

View File

@@ -29,7 +29,10 @@ proc vtab_command {method args} {
}
xBestIndex {
set clist [lindex $args 0]
set hdl [lindex $args 0]
set clist [$hdl constraints]
set orderby [$hdl orderby]
if {[llength $clist]!=1} { error "unexpected constraint list" }
catch { array unset C }
array set C [lindex $clist 0]
@@ -76,10 +79,13 @@ proc t1_vtab {mode method args} {
}
xBestIndex {
set hdl [lindex $args 0]
set clist [$hdl constraints]
set orderby [$hdl orderby]
set SQL_FILTER {SELECT * FROM t1x WHERE a='%1%'}
set SQL_SCAN {SELECT * FROM t1x}
set clist [lindex $args 0]
set idx 0
for {set idx 0} {$idx < [llength $clist]} {incr idx} {
array unset C
@@ -177,7 +183,10 @@ proc vtab_command {method args} {
}
xBestIndex {
set clist [lindex $args 0]
set hdl [lindex $args 0]
set clist [$hdl constraints]
set orderby [$hdl orderby]
#puts $clist
set W [list]
set U [list]
@@ -287,12 +296,17 @@ proc vtab_command {method args} {
}
xBestIndex {
set clist [lindex $args 0]
set hdl [lindex $args 0]
set clist [$hdl constraints]
set orderby [$hdl orderby]
lappend ::bestindex_calls $clist
set ret "cost 1000000 idxnum 555"
for {set i 0} {$i < [llength $clist]} {incr i} {
array set C [lindex $clist $i]
if {$C(usable)} { lappend ret use $i }
if {$C(usable)} {
lappend ret use $i
}
}
return $ret
}

View File

@@ -47,7 +47,10 @@ proc vtab_cmd {tbl cols method args} {
return "CREATE TABLE $tbl ([join $cols ,])"
}
xBestIndex {
foreach {clist orderby mask} $args {}
set hdl [lindex $args 0]
set clist [$hdl constraints]
set orderby [$hdl orderby]
set mask [$hdl mask]
set cons [list]
set used [list]

View File

@@ -34,7 +34,10 @@ proc vtab_cmd {bOmit method args} {
}
xBestIndex {
foreach {clist orderby mask} $args {}
set hdl [lindex $args 0]
set clist [$hdl constraints]
set orderby [$hdl orderby]
set mask [$hdl mask]
set ret [list]
set use use

View File

@@ -48,7 +48,10 @@ proc vtab_cmd {param method args} {
}
xBestIndex {
foreach {clist orderby mask} $args {}
set hdl [lindex $args 0]
set clist [$hdl constraints]
set orderby [$hdl orderby]
set mask [$hdl mask]
set ret [list]
@@ -135,7 +138,11 @@ proc vtab_command {method args} {
}
xBestIndex {
set clist [lindex $args 0]
set hdl [lindex $args 0]
set clist [$hdl constraints]
set orderby [$hdl orderby]
set mask [$hdl mask]
if {[llength $clist]!=1} { error "unexpected constraint list" }
catch { array unset C }
array set C [lindex $clist 0]

View File

@@ -14,7 +14,7 @@
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix bestindex4
set testprefix bestindex5
ifcapable !vtab {
finish_test
@@ -44,7 +44,10 @@ proc vtab_cmd {method args} {
}
xBestIndex {
foreach {clist orderby mask} $args {}
set hdl [lindex $args 0]
set clist [$hdl constraints]
set orderby [$hdl orderby]
set mask [$hdl mask]
set cost 1000000.0
set ret [list]

View File

@@ -28,7 +28,11 @@ proc vtab_command {src method args} {
}
xBestIndex {
set clist [lindex $args 0]
set hdl [lindex $args 0]
set clist [$hdl constraints]
set orderby [$hdl orderby]
set mask [$hdl mask]
set wlist 1
set iCons 0

View File

@@ -28,7 +28,11 @@ proc vtab_command {src method args} {
}
xBestIndex {
set clist [lindex $args 0]
set hdl [lindex $args 0]
set clist [$hdl constraints]
set orderby [$hdl orderby]
set mask [$hdl mask]
set iCons 0
set ret [list]
foreach cons $clist {

463
test/bestindex8.test Normal file
View File

@@ -0,0 +1,463 @@
# 2020-01-29
#
# 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.
#
#***********************************************************************
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix bestindex8
ifcapable !vtab {
finish_test
return
}
register_tcl_module db
proc vtab_command {src method args} {
switch -- $method {
xConnect {
return "CREATE TABLE xxx(a, b)"
}
xBestIndex {
set hdl [lindex $args 0]
set clist [$hdl constraints]
set orderby [$hdl orderby]
lappend ::lBestIndexDistinct [$hdl distinct]
#puts "ORDERBY: $orderby"
set iCons 0
set ret [list]
foreach cons $clist {
catch { array unset C }
array set C $cons
if {$C(usable)} {
lappend ret use $iCons
}
incr iCons
}
if {$orderby=="{column 0 desc 0} {column 1 desc 0}"
|| $orderby=="{column 0 desc 0}"
} {
lappend ret orderby 1
lappend ret idxnum 1
set ::lOrderByConsumed 1
}
return $ret
}
xFilter {
set idxnum [lindex $args 0]
if {$idxnum} {
return [list sql "SELECT rowid, a, b FROM $src order by 2, 3"]
}
return [list sql "SELECT rowid, a, b FROM $src"]
}
}
return {}
}
do_execsql_test 1.0 {
CREATE TABLE t1(a, b);
CREATE INDEX i1 ON t1(a, b);
INSERT INTO t1 VALUES('a', 'b'), ('c', 'd');
INSERT INTO t1 VALUES('a', 'b'), ('c', 'd');
CREATE VIRTUAL TABLE vt1 USING tcl(vtab_command t1);
CREATE TABLE t0(c0);
INSERT INTO t0(c0) VALUES (1), (0);
}
foreach {tn sql bDistinct idxinsert bConsumed res} {
1 "SELECT a, b FROM vt1" 0 0 0 {a b c d a b c d}
2 "SELECT DISTINCT a, b FROM vt1" 2 1 1 {a b c d}
3 "SELECT DISTINCT a FROM vt1" 2 1 1 {a c}
4 "SELECT DISTINCT b FROM vt1" 2 1 0 {b d}
5 "SELECT DISTINCT b FROM vt1 ORDER BY a" 0 1 1 {b d}
6 "SELECT DISTINCT t0.c0 FROM vt1, t0 ORDER BY vt1.a" 0 1 1 {1 0}
7 "SELECT DISTINCT a, b FROM vt1 ORDER BY a, b" 1 0 1 {a b c d}
8 "SELECT DISTINCT a, b FROM vt1 ORDER BY a" 0 1 1 {a b c d}
9 "SELECT DISTINCT a FROM vt1 ORDER BY a, b" 0 1 1 {a c}
10 "SELECT DISTINCT a, b FROM vt1 WHERE b='b'" 2 1 1 {a b}
11 "SELECT DISTINCT a, b FROM vt1 WHERE +b='b'" 2 1 1 {a b}
} {
set ::lBestIndexDistinct ""
set ::lOrderByConsumed 0
do_execsql_test 1.$tn.1 $sql $res
do_test 1.$tn.2 {
set ::lBestIndexDistinct
} $bDistinct
do_test 1.$tn.3 {
expr {[lsearch [execsql "explain $sql"] IdxInsert]>=0}
} $idxinsert
do_test 1.$tn.4 {
set ::lOrderByConsumed
} $bConsumed
}
#-------------------------------------------------------------------------
reset_db
register_tcl_module db
proc vtab_command {src method args} {
switch -- $method {
xConnect {
return "CREATE TABLE xxx(a, b)"
}
xBestIndex {
set hdl [lindex $args 0]
set ret [list]
set iCons 0
foreach cons [$hdl constraints] {
array set C $cons
if {($C(op)=="limit" || $C(op)=="offset") && $C(usable)} {
lappend ret use $iCons
}
incr iCons
}
return $ret
}
xFilter {
lappend ::lFilterArgs [lindex $args 2]
return [list sql "SELECT rowid, a, b FROM $src"]
}
}
return {}
}
do_execsql_test 2.0 {
CREATE TABLE t1(a, b);
CREATE INDEX i1 ON t1(a, b);
CREATE VIRTUAL TABLE vt1 USING tcl(vtab_command t1);
}
do_test 2.1 {
set ::lFilterArgs [list]
execsql { SELECT * FROM vt1 LIMIT 10 }
set ::lFilterArgs
} {10}
do_test 2.2 {
set ::lFilterArgs [list]
execsql { SELECT * FROM vt1 LIMIT 5 OFFSET 50 }
set ::lFilterArgs
} {{5 50}}
do_test 2.3 {
set ::lFilterArgs [list]
execsql { SELECT * FROM vt1 ORDER BY a, b LIMIT 1 OFFSET 1 }
set ::lFilterArgs
} {{1 1}}
do_test 2.4 {
set ::lFilterArgs [list]
execsql { SELECT * FROM vt1 ORDER BY a, +b LIMIT 1 OFFSET 1 }
set ::lFilterArgs
} {{}}
#-------------------------------------------------------------------------
reset_db
register_tcl_module db
proc vtab_command {src method args} {
switch -- $method {
xConnect {
return "CREATE TABLE xxx(a, b)"
}
xBestIndex {
set hdl [lindex $args 0]
set lCons [$hdl constraints]
set ret [list]
for {set i 0} {$i < [llength $lCons]} {incr i} {
array set C [lindex $lCons $i]
if {$C(usable)} {
lappend ret use $i
$hdl in $i 1
}
}
return $ret
}
xFilter {
set lArg [lindex $args 2]
lappend ::lFilterArg {*}$lArg
return [list sql "SELECT rowid, a, b FROM $src"]
}
}
return {}
}
do_execsql_test 3.0 {
CREATE TABLE t1(a, b);
CREATE INDEX i1 ON t1(a, b);
CREATE VIRTUAL TABLE vt1 USING tcl(vtab_command t1);
}
foreach {tn sql lfa} {
1 "SELECT * FROM vt1 WHERE b IN (10, 20, 30)" {{10 20 30}}
2 "SELECT * FROM vt1 WHERE b IN ('abc', 'def')" {{abc def}}
3 "SELECT * FROM vt1 WHERE a IS NULL AND b IN ('abc', 'def')" {{} {abc def}}
4 "SELECT * FROM vt1 WHERE a IN (1,2,3) AND b IN ('abc', 'def')"
{{1 2 3} {abc def}}
5 "SELECT * FROM vt1
WHERE a IN (SELECT 1 UNION SELECT 2) AND b IN ('abc', 'def')"
{{1 2} {abc def}}
6 "SELECT * FROM vt1
WHERE b IN ('abc', 'def') AND a IN (SELECT 1 UNION SELECT 2)"
{{abc def} {1 2}}
} {
do_test 3.$tn {
set ::lFilterArg [list]
execsql $sql
set ::lFilterArg
} $lfa
}
#explain_i { SELECT * FROM vt1 WHERE b IN (10, 20, 30) }
#-------------------------------------------------------------------------
reset_db
register_tcl_module db
proc vtab_command {src method args} {
switch -- $method {
xConnect {
return "CREATE TABLE xxx(a, b, c)"
}
xBestIndex {
set hdl [lindex $args 0]
set lCons [$hdl constraints]
set ret [list]
for {set i 0} {$i < [llength $lCons]} {incr i} {
lappend ::lBestIndexRhs [$hdl rhs_value $i -]
}
return $ret
}
xFilter {
return [list sql "SELECT rowid, a, b, c FROM $src"]
}
}
return {}
}
do_execsql_test 4.0 {
CREATE TABLE t1(a, b, c);
CREATE VIRTUAL TABLE vt1 USING tcl(vtab_command t1);
}
foreach {tn sql lbir} {
1 "SELECT * FROM vt1 WHERE b = 10" {10}
2 "SELECT * FROM vt1 WHERE a = 'abc' AND b < 30" {abc 30}
3 "SELECT * FROM vt1 WHERE a = 'abc' AND b < 30+2" {abc -}
4 "SELECT * FROM vt1 WHERE a IN (1,2,3) AND b < 30+2" {- -}
5 "SELECT * FROM vt1 WHERE a IS 111 AND b < 30+2" {111 -}
} {
do_test 4.$tn {
set ::lBestIndexRhs [list]
execsql $sql
set ::lBestIndexRhs
} $lbir
}
#-------------------------------------------------------------------------
reset_db
db cache size 0
register_tcl_module db
set ::vtab_handle_in 1
proc vtab_command {src method args} {
switch -- $method {
xConnect {
return "CREATE TABLE xxx(a, b, c)"
}
xBestIndex {
set lCols [list a b c]
set hdl [lindex $args 0]
set lCons [$hdl constraints]
set lOrder [$hdl order]
set L ""
set O ""
set W [list]
set a 0
for {set i 0} {$i < [llength $lCons]} {incr i} {
array set C [lindex $lCons $i]
if {$C(usable)} {
if { $C(op)=="eq" } {
set bIn 0
if {$::vtab_handle_in} { set bIn [$hdl in $i 1] }
if {$bIn} {
lappend W "[lindex $lCols $C(column)] IN (%I$a%)"
} else {
lappend W "[lindex $lCols $C(column)] = %$a%"
}
lappend ret omit $i
}
if { $C(op)=="limit" } { set L " LIMIT %$a%" ; lappend ret use $i }
if { $C(op)=="offset" } { set O " OFFSET %$a%" ; lappend ret use $i }
incr a
}
}
set order ""
set selectlist "rowid, a, b, c"
if {[llength $lOrder]} {
array set sl [list]
set lO [list]
foreach s $lOrder {
array set C $s
set ad ""
if {$C(desc)} { set ad " DESC" }
lappend lO "[lindex $lCols $C(column)]$ad"
set sl($C(column)) 1
}
if {[$hdl distinct]==2} {
set selectlist "DISTINCT 0"
foreach i {0 1 2} {
if {[info exists sl($i)]} {
append selectlist ", [lindex $lCols $i]"
} else {
append selectlist ", 0"
}
}
} else {
set order " ORDER BY [join $lO ,]"
}
}
set where ""
if {[llength $W]} { set where " WHERE [join $W { AND }]" }
set sql "SELECT $selectlist FROM $src$where$order$L$O"
lappend ret idxStr $sql
return $ret
}
xFilter {
foreach {idxnum idxstr lArg} $args {}
set ii 0
set sql $idxstr
foreach a $lArg {
set sql [string map [list %$ii% $a] $sql]
set sql [string map [list %I$ii% [join $a ,]] $sql]
incr ii
}
lappend ::lFilterSql $sql
if {[regexp {OFFSET (.*)$} $sql -> off]} {
set real_sql "
WITH c(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM c WHERE i<$off )
SELECT 0,0,0,0 FROM c
UNION ALL SELECT * FROM (
$sql
)
"
} else {
set real_sql $sql
}
return [list sql $real_sql]
}
}
return {}
}
do_execsql_test 5.0 {
CREATE TABLE t1(a, b, c);
CREATE VIRTUAL TABLE vt1 USING tcl(vtab_command t1);
INSERT INTO t1 VALUES(1, 2, 3);
INSERT INTO t1 VALUES(2, 3, 4);
INSERT INTO t1 VALUES(3, 4, 5);
INSERT INTO t1 VALUES(1, 5, 6);
INSERT INTO t1 VALUES(2, 6, 7);
INSERT INTO t1 VALUES(3, 7, 8);
INSERT INTO t1 VALUES(1, 8, 9);
INSERT INTO t1 VALUES(2, 9, 0);
}
proc do_vtab_test {tn sql vtsql {res {}}} {
set ::lFilterSql [list]
uplevel [list do_execsql_test $tn.1 $sql $res]
uplevel [list do_test $tn.2 {set ::lFilterSql} [list {*}$vtsql]]
}
do_vtab_test 5.1.1 {
SELECT DISTINCT a FROM vt1
} {
{SELECT DISTINCT 0, a, 0, 0 FROM t1}
} {1 2 3}
do_vtab_test 5.1.2 {
SELECT DISTINCT a FROM vt1 ORDER BY a
} {
{SELECT rowid, a, b, c FROM t1 ORDER BY a}
} {1 2 3}
do_vtab_test 5.1.3 {
SELECT DISTINCT a FROM vt1 WHERE c IN (4,5,6,7,8)
} {
{SELECT DISTINCT 0, a, 0, 0 FROM t1 WHERE c IN (4,5,6,7,8)}
} {2 3 1}
set ::vtab_handle_in 0
do_vtab_test 5.1.4 {
SELECT DISTINCT a FROM vt1 WHERE c IN (4,5,6,7,8)
} {
{SELECT DISTINCT 0, a, 0, 0 FROM t1 WHERE c = 4}
{SELECT DISTINCT 0, a, 0, 0 FROM t1 WHERE c = 5}
{SELECT DISTINCT 0, a, 0, 0 FROM t1 WHERE c = 6}
{SELECT DISTINCT 0, a, 0, 0 FROM t1 WHERE c = 7}
{SELECT DISTINCT 0, a, 0, 0 FROM t1 WHERE c = 8}
} {2 3 1}
set ::vtab_handle_in 1
do_vtab_test 5.1.5a {
SELECT a, b, c FROM vt1 WHERE c IN (4,5,6,7,8) LIMIT 2 OFFSET 2
} {
{SELECT rowid, a, b, c FROM t1 WHERE c IN (4,5,6,7,8) LIMIT 2 OFFSET 2}
} {1 5 6 2 6 7}
set ::vtab_handle_in 0
do_vtab_test 5.1.5b {
SELECT a, b, c FROM vt1 WHERE c IN (4,5,6,7,8) LIMIT 2 OFFSET 2
} {
{SELECT rowid, a, b, c FROM t1 WHERE c = 4}
{SELECT rowid, a, b, c FROM t1 WHERE c = 5}
{SELECT rowid, a, b, c FROM t1 WHERE c = 6}
{SELECT rowid, a, b, c FROM t1 WHERE c = 7}
} {1 5 6 2 6 7}
set ::vtab_handle_in 1
finish_test

149
test/date3.test Normal file
View 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

View File

@@ -328,4 +328,18 @@ do_execsql_test 8.1 {
2 10 2
}
# 2022-01-31 dbsqlfuzz 787d9bd73164c6f0c85469e2e48b2aff19af6938
#
reset_db
do_execsql_test 9.1 {
CREATE TABLE t1(a ,b FLOAT);
INSERT INTO t1 VALUES(1,1);
CREATE INDEX t1x1 ON t1(a,b,a,a,a,a,a,a,a,a,a,b);
ANALYZE sqlite_schema;
INSERT INTO sqlite_stat1 VALUES('t1','t1x1','648 324 81 81 81 81 81 81 81081 81 81 81');
ANALYZE sqlite_schema;
SELECT a FROM (SELECT a FROM t1 NATURAL LEFT JOIN t1) NATURAL LEFT JOIN t1 WHERE (rowid,1)<=(5,0);
} {1}
finish_test

View File

@@ -15,11 +15,6 @@
set testdir [file dirname $argv0]
source $testdir/tester.tcl
ifcapable !json1 {
finish_test
return
}
do_execsql_test json101-1.1.00 {
SELECT json_array(1,2.5,null,'hello');
} {[1,2.5,null,"hello"]}
@@ -846,5 +841,13 @@ do_execsql_test json-16.30 {
SELECT unicode(json_extract('"\uD834\uDD1E"','$'));
} {119070}
# 2022-01-30 dbsqlfuzz 4678cf825d27f87c9b8343720121e12cf944b71a
do_execsql_test json-17.1 {
DROP TABLE IF EXISTS t1;
DROP TABLE IF EXISTS t2;
CREATE TABLE t1(a,b,c);
CREATE TABLE t2(d);
SELECT * FROM t1 LEFT JOIN t2 ON (SELECT b FROM json_each ORDER BY 1);
} {}
finish_test

View File

@@ -18,11 +18,6 @@
set testdir [file dirname $argv0]
source $testdir/tester.tcl
ifcapable !json1 {
finish_test
return
}
do_execsql_test json102-100 {
SELECT json_object('ex','[52,3.14159]');
} {{{"ex":"[52,3.14159]"}}}

View File

@@ -14,11 +14,6 @@
set testdir [file dirname $argv0]
source $testdir/tester.tcl
ifcapable !json1 {
finish_test
return
}
do_execsql_test json103-100 {
CREATE TABLE t1(a,b,c);
WITH RECURSIVE c(x) AS (VALUES(1) UNION SELECT x+1 FROM c WHERE x<100)

View File

@@ -15,11 +15,6 @@ set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix json104
ifcapable !json1 {
finish_test
return
}
# This is the example from pages 2 and 3 of RFC-7396
do_execsql_test json104-100 {
SELECT json_patch('{

View File

@@ -15,11 +15,6 @@ set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix json104
ifcapable !json1 {
finish_test
return
}
# This is the example from pages 2 and 3 of RFC-7396
db eval {
CREATE TABLE t1(j);

View File

@@ -708,5 +708,23 @@ do_execsql_test 31.2 {
SELECT * FROM t1 LEFT JOIN t2 ON b=NULL WHERE (c,d)==(SELECT 123, 456+a);
} {}
# 2022-02-03 dbsqlfuzz 80a9fade844b4fb43564efc972bcb2c68270f5d1
reset_db
do_execsql_test 32.1 {
CREATE TABLE t1(a INTEGER PRIMARY KEY, b INT, c INT);
CREATE TABLE t2(d INTEGER PRIMARY KEY);
INSERT INTO t1(a,b,c) VALUES(500,654,456);
INSERT INTO t1(a,b,c) VALUES(501,655,456);
INSERT INTO t1(a,b,c) VALUES(502,654,122);
INSERT INTO t1(a,b,c) VALUES(503,654,221);
INSERT INTO t1(a,b,c) VALUES(601,654,122);
INSERT INTO t2(d) VALUES(456);
INSERT INTO t2(d) VALUES(122);
SELECT a FROM (
SELECT t1.a FROM t2, t1
WHERE (987, t1.b) = ( SELECT 987, 654 ) AND t2.d=t1.c
) AS t3
WHERE a=1234 OR a<=567;
} {500 502}
finish_test

View File

@@ -46,7 +46,9 @@ proc vtab_command {method args} {
set OP(glob) GLOB
set OP(regexp) REGEXP
set clist [lindex $args 0]
set hdl [lindex $args 0]
set clist [$hdl constraints]
set ret [list]
set elist [list]
set i 0

View File

@@ -205,10 +205,10 @@ do_test shell1-2.2.4 {
} {0 {}}
do_test shell1-2.2.5 {
catchcmd "test.db" ".mode \"insert FOO"
} {1 {Error: mode should be one of: ascii box column csv html insert json line list markdown quote table tabs tcl}}
} {1 {Error: mode should be one of: ascii box column csv html insert json line list markdown qbox quote table tabs tcl}}
do_test shell1-2.2.6 {
catchcmd "test.db" ".mode \'insert FOO"
} {1 {Error: mode should be one of: ascii box column csv html insert json line list markdown quote table tabs tcl}}
} {1 {Error: mode should be one of: ascii box column csv html insert json line list markdown qbox quote table tabs tcl}}
# check multiple tokens, and quoted tokens
do_test shell1-2.3.1 {
@@ -236,7 +236,7 @@ do_test shell1-2.3.7 {
# check quoted args are unquoted
do_test shell1-2.4.1 {
catchcmd "test.db" ".mode FOO"
} {1 {Error: mode should be one of: ascii box column csv html insert json line list markdown quote table tabs tcl}}
} {1 {Error: mode should be one of: ascii box column csv html insert json line list markdown qbox quote table tabs tcl}}
do_test shell1-2.4.2 {
catchcmd "test.db" ".mode csv"
} {0 {}}
@@ -437,7 +437,7 @@ do_test shell1-3.13.1 {
} {0 {current output mode: list}}
do_test shell1-3.13.2 {
catchcmd "test.db" ".mode FOO"
} {1 {Error: mode should be one of: ascii box column csv html insert json line list markdown quote table tabs tcl}}
} {1 {Error: mode should be one of: ascii box column csv html insert json line list markdown qbox quote table tabs tcl}}
do_test shell1-3.13.3 {
catchcmd "test.db" ".mode csv"
} {0 {}}
@@ -467,17 +467,6 @@ do_test shell1-3.13.11 {
catchcmd "test.db" ".mode tcl BAD"
} {0 {}}
# don't allow partial mode type matches
do_test shell1-3.13.12 {
catchcmd "test.db" ".mode l"
} {1 {Error: mode should be one of: ascii box column csv html insert json line list markdown quote table tabs tcl}}
do_test shell1-3.13.13 {
catchcmd "test.db" ".mode li"
} {1 {Error: mode should be one of: ascii box column csv html insert json line list markdown quote table tabs tcl}}
do_test shell1-3.13.14 {
catchcmd "test.db" ".mode lin"
} {0 {}}
# .nullvalue STRING Print STRING in place of NULL values
do_test shell1-3.14.1 {
catchcmd "test.db" ".nullvalue"