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 18 set testdir [file dirname $argv0] 19 source $testdir/tester.tcl 20 21 ifcapable !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 # 30 db eval {PRAGMA cache_size=10} 31 sqlite3_memory_highwater 1 32 unset -nocomplain memused 33 set memused [sqlite3_memory_used] 34 do_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} 44 do_test zeroblob-1.1.1 { 45 expr {[sqlite3_memory_highwater]<$::memused+25000} 46 } {1} 47 do_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 # 56 do_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} 63 do_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 # 72 do_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} 79 do_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 # 88 do_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} 95 do_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 # 103 do_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 # 111 do_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 # 120 ifcapable 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 # 134 ifcapable 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 # 144 do_test zeroblob-5.1 { 145 execsql { 146 SELECT CAST (zeroblob(100) AS REAL); 147 } 148 } {0.0} 149 do_test zeroblob-5.2 { 150 execsql { 151 SELECT CAST (zeroblob(100) AS INTEGER); 152 } 153 } {0} 154 do_test zeroblob-5.3 { 155 execsql { 156 SELECT CAST (zeroblob(100) AS TEXT); 157 } 158 } {{}} 159 do_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 # 168 do_test zeroblob-6.1.1 { 169 execsql {select zeroblob(-1)} 170 } {{}} 171 do_test zeroblob-6.1.2 { 172 execsql {select zeroblob(-10)} 173 } {{}} 174 do_test zeroblob-6.1.3 { 175 execsql {select zeroblob(-100)} 176 } {{}} 177 do_test zeroblob-6.2 { 178 execsql {select length(zeroblob(-1))} 179 } {0} 180 do_test zeroblob-6.3 { 181 execsql {select zeroblob(-1)|1} 182 } {1} 183 do_test zeroblob-6.4 { 184 catchsql {select length(zeroblob(2147483648))} 185 } {1 {string or blob too big}} 186 do_test zeroblob-6.5 { 187 catchsql {select zeroblob(2147483648)} 188 } {1 {string or blob too big}} 189 do_test zeroblob-6.6 { 190 execsql {select hex(zeroblob(-1))} 191 } {{}} 192 do_test zeroblob-6.7 { 193 execsql {select typeof(zeroblob(-1))} 194 } {blob} 195 196 # Test bind_zeroblob() 197 # 198 sqlite3_memory_highwater 1 199 unset -nocomplain memused 200 set memused [sqlite3_memory_used] 201 do_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} 207 do_test zeroblob-7.2 { 208 sqlite3_column_int $::STMT 0 209 } {450000} 210 do_test zeroblob-7.3 { 211 sqlite3_finalize $::STMT 212 } {SQLITE_OK} 213 do_test zeroblob-7.4 { 214 set ::sqlite3_max_blobsize 215 } {0} 216 do_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 # 223 do_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 # 233 do_test zeroblob-9.1 { 234 db eval {SELECT x'0000' IN (x'000000')} 235 } {0} 236 do_test zeroblob-9.2 { 237 db eval {SELECT x'0000' IN (x'0000')} 238 } {1} 239 do_test zeroblob-9.3 { 240 db eval {SELECT zeroblob(2) IN (x'000000')} 241 } {0} 242 do_test zeroblob-9.4 { 243 db eval {SELECT zeroblob(2) IN (x'0000')} 244 } {1} 245 do_test zeroblob-9.5 { 246 db eval {SELECT x'0000' IN (zeroblob(3))} 247 } {0} 248 do_test zeroblob-9.6 { 249 db eval {SELECT x'0000' IN (zeroblob(2))} 250 } {1} 251 do_test zeroblob-9.7 { 252 db eval {SELECT zeroblob(2) IN (zeroblob(3))} 253 } {0} 254 do_test zeroblob-9.8 { 255 db eval {SELECT zeroblob(2) IN (zeroblob(2))} 256 } {1} 257 258 259 finish_test 260