Home | History | Annotate | Download | only in test
      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