1# 2007 May 02 2# 3# The author disclaims copyright to this source code. In place of 4# a legal notice, here is a blessing: 5# 6# May you do good and not evil. 7# May you find forgiveness for yourself and forgive others. 8# May you share freely, never taking more than you give. 9# 10#*********************************************************************** 11# This file implements regression tests for SQLite library. The 12# focus of this file is testing of the zero-filled blob functionality 13# including the sqlite3_bind_zeroblob(), sqlite3_result_zeroblob(), 14# and the built-in zeroblob() SQL function. 15# 16# $Id: zeroblob.test,v 1.14 2009/07/14 02:33:02 drh Exp $ 17 18set testdir [file dirname $argv0] 19source $testdir/tester.tcl 20 21ifcapable !incrblob { 22 finish_test 23 return 24} 25 26# When zeroblob() is used for the last field of a column, then the 27# content of the zeroblob is never instantiated on the VDBE stack. 28# But it does get inserted into the database correctly. 29# 30db eval {PRAGMA cache_size=10} 31sqlite3_memory_highwater 1 32unset -nocomplain memused 33set memused [sqlite3_memory_used] 34do_test zeroblob-1.1 { 35 execsql { 36 CREATE TABLE t1(a,b,c,d); 37 } 38 set ::sqlite3_max_blobsize 0 39 execsql { 40 INSERT INTO t1 VALUES(2,3,4,zeroblob(1000000)); 41 } 42 set ::sqlite3_max_blobsize 43} {10} 44do_test zeroblob-1.1.1 { 45 expr {[sqlite3_memory_highwater]<$::memused+25000} 46} {1} 47do_test zeroblob-1.2 { 48 execsql { 49 SELECT length(d) FROM t1 50 } 51} {1000000} 52 53# If a non-NULL column follows the zeroblob, then the content of 54# the zeroblob must be instantiated. 55# 56do_test zeroblob-1.3 { 57 set ::sqlite3_max_blobsize 0 58 execsql { 59 INSERT INTO t1 VALUES(3,4,zeroblob(10000),5); 60 } 61 set ::sqlite3_max_blobsize 62} {10010} 63do_test zeroblob-1.4 { 64 execsql { 65 SELECT length(c), length(d) FROM t1 66 } 67} {1 1000000 10000 1} 68 69# Multiple zeroblobs can appear at the end of record. No instantiation 70# of the blob content occurs on the stack. 71# 72do_test zeroblob-1.5 { 73 set ::sqlite3_max_blobsize 0 74 execsql { 75 INSERT INTO t1 VALUES(4,5,zeroblob(10000),zeroblob(10000)); 76 } 77 set ::sqlite3_max_blobsize 78} {11} 79do_test zeroblob-1.6 { 80 execsql { 81 SELECT length(c), length(d) FROM t1 82 } 83} {1 1000000 10000 1 10000 10000} 84 85# NULLs can follow the zeroblob() or be intermixed with zeroblobs and 86# no instantiation of the zeroblobs occurs on the stack. 87# 88do_test zeroblob-1.7 { 89 set ::sqlite3_max_blobsize 0 90 execsql { 91 INSERT INTO t1 VALUES(5,zeroblob(10000),NULL,zeroblob(10000)); 92 } 93 set ::sqlite3_max_blobsize 94} {10} 95do_test zeroblob-1.8 { 96 execsql { 97 SELECT length(b), length(d) FROM t1 WHERE a=5 98 } 99} {10000 10000} 100 101# Comparisons against zeroblobs work. 102# 103do_test zeroblob-2.1 { 104 execsql { 105 SELECT a FROM t1 WHERE b=zeroblob(10000) 106 } 107} {5} 108 109# Comparisons against zeroblobs work even when indexed. 110# 111do_test zeroblob-2.2 { 112 execsql { 113 CREATE INDEX i1_1 ON t1(b); 114 SELECT a FROM t1 WHERE b=zeroblob(10000); 115 } 116} {5} 117 118# DISTINCT works for zeroblobs 119# 120ifcapable bloblit&&subquery&&compound { 121 do_test zeroblob-3.1 { 122 execsql { 123 SELECT count(DISTINCT a) FROM ( 124 SELECT x'00000000000000000000' AS a 125 UNION ALL 126 SELECT zeroblob(10) AS a 127 ) 128 } 129 } {1} 130} 131 132# Concatentation works with zeroblob 133# 134ifcapable bloblit { 135 do_test zeroblob-4.1 { 136 execsql { 137 SELECT hex(zeroblob(2) || x'61') 138 } 139 } {000061} 140} 141 142# Check various CAST(...) operations on zeroblob. 143# 144do_test zeroblob-5.1 { 145 execsql { 146 SELECT CAST (zeroblob(100) AS REAL); 147 } 148} {0.0} 149do_test zeroblob-5.2 { 150 execsql { 151 SELECT CAST (zeroblob(100) AS INTEGER); 152 } 153} {0} 154do_test zeroblob-5.3 { 155 execsql { 156 SELECT CAST (zeroblob(100) AS TEXT); 157 } 158} {{}} 159do_test zeroblob-5.4 { 160 execsql { 161 SELECT CAST(zeroblob(100) AS BLOB); 162 } 163} [execsql {SELECT zeroblob(100)}] 164 165 166# Check for malicious use of zeroblob. Make sure nothing crashes. 167# 168do_test zeroblob-6.1.1 { 169 execsql {select zeroblob(-1)} 170} {{}} 171do_test zeroblob-6.1.2 { 172 execsql {select zeroblob(-10)} 173} {{}} 174do_test zeroblob-6.1.3 { 175 execsql {select zeroblob(-100)} 176} {{}} 177do_test zeroblob-6.2 { 178 execsql {select length(zeroblob(-1))} 179} {0} 180do_test zeroblob-6.3 { 181 execsql {select zeroblob(-1)|1} 182} {1} 183do_test zeroblob-6.4 { 184 catchsql {select length(zeroblob(2147483648))} 185} {1 {string or blob too big}} 186do_test zeroblob-6.5 { 187 catchsql {select zeroblob(2147483648)} 188} {1 {string or blob too big}} 189do_test zeroblob-6.6 { 190 execsql {select hex(zeroblob(-1))} 191} {{}} 192do_test zeroblob-6.7 { 193 execsql {select typeof(zeroblob(-1))} 194} {blob} 195 196# Test bind_zeroblob() 197# 198sqlite3_memory_highwater 1 199unset -nocomplain memused 200set memused [sqlite3_memory_used] 201do_test zeroblob-7.1 { 202 set ::STMT [sqlite3_prepare $::DB "SELECT length(?)" -1 DUMMY] 203 set ::sqlite3_max_blobsize 0 204 sqlite3_bind_zeroblob $::STMT 1 450000 205 sqlite3_step $::STMT 206} {SQLITE_ROW} 207do_test zeroblob-7.2 { 208 sqlite3_column_int $::STMT 0 209} {450000} 210do_test zeroblob-7.3 { 211 sqlite3_finalize $::STMT 212} {SQLITE_OK} 213do_test zeroblob-7.4 { 214 set ::sqlite3_max_blobsize 215} {0} 216do_test zeroblob-7.5 { 217 expr {[sqlite3_memory_highwater]<$::memused+10000} 218} {1} 219 220# Test that MakeRecord can handle a value with some real content 221# and a zero-blob tail. 222# 223do_test zeroblob-8.1 { 224 llength [execsql { 225 SELECT 'hello' AS a, zeroblob(10) as b from t1 ORDER BY a, b; 226 }] 227} {8} 228 229 230# Ticket #3965 231# zeroblobs on either size of an IN operator 232# 233do_test zeroblob-9.1 { 234 db eval {SELECT x'0000' IN (x'000000')} 235} {0} 236do_test zeroblob-9.2 { 237 db eval {SELECT x'0000' IN (x'0000')} 238} {1} 239do_test zeroblob-9.3 { 240 db eval {SELECT zeroblob(2) IN (x'000000')} 241} {0} 242do_test zeroblob-9.4 { 243 db eval {SELECT zeroblob(2) IN (x'0000')} 244} {1} 245do_test zeroblob-9.5 { 246 db eval {SELECT x'0000' IN (zeroblob(3))} 247} {0} 248do_test zeroblob-9.6 { 249 db eval {SELECT x'0000' IN (zeroblob(2))} 250} {1} 251do_test zeroblob-9.7 { 252 db eval {SELECT zeroblob(2) IN (zeroblob(3))} 253} {0} 254do_test zeroblob-9.8 { 255 db eval {SELECT zeroblob(2) IN (zeroblob(2))} 256} {1} 257 258 259finish_test 260