xref: /sqlite-3.40.0/test/zeroblob.test (revision a32536b4)
1fdf972a9Sdrh# 2007 May 02
2fdf972a9Sdrh#
3fdf972a9Sdrh# The author disclaims copyright to this source code.  In place of
4fdf972a9Sdrh# a legal notice, here is a blessing:
5fdf972a9Sdrh#
6fdf972a9Sdrh#    May you do good and not evil.
7fdf972a9Sdrh#    May you find forgiveness for yourself and forgive others.
8fdf972a9Sdrh#    May you share freely, never taking more than you give.
9fdf972a9Sdrh#
10fdf972a9Sdrh#***********************************************************************
11fdf972a9Sdrh# This file implements regression tests for SQLite library.  The
12fdf972a9Sdrh# focus of this file is testing of the zero-filled blob functionality
13fdf972a9Sdrh# including the sqlite3_bind_zeroblob(), sqlite3_result_zeroblob(),
14fdf972a9Sdrh# and the built-in zeroblob() SQL function.
15fdf972a9Sdrh#
166be240e5Sdrh# $Id: zeroblob.test,v 1.14 2009/07/14 02:33:02 drh Exp $
17fdf972a9Sdrh
18fdf972a9Sdrhset testdir [file dirname $argv0]
19fdf972a9Sdrhsource $testdir/tester.tcl
20a4d5ae8fSdanset testprefix zeroblob
21fdf972a9Sdrh
22*a32536b4Sdan# ifcapable !incrblob { finish_test return }
23f12737daSdanielk1977
2403bc525aSdantest_set_config_pagecache 0 0
2503bc525aSdan
26ae7e151aSdrh# When zeroblob() is used for the last field of a column, then the
27ae7e151aSdrh# content of the zeroblob is never instantiated on the VDBE stack.
28ae7e151aSdrh# But it does get inserted into the database correctly.
29fdf972a9Sdrh#
30655194d6Sdrhdb eval {PRAGMA cache_size=10}
3140257ffdSdrhsqlite3_memory_highwater 1
32655194d6Sdrhunset -nocomplain memused
33655194d6Sdrhset memused [sqlite3_memory_used]
34fdf972a9Sdrhdo_test zeroblob-1.1 {
35fdf972a9Sdrh  execsql {
36fdf972a9Sdrh    CREATE TABLE t1(a,b,c,d);
37fdf972a9Sdrh  }
38ae7e151aSdrh  set ::sqlite3_max_blobsize 0
39ae7e151aSdrh  execsql {
40655194d6Sdrh    INSERT INTO t1 VALUES(2,3,4,zeroblob(1000000));
41ae7e151aSdrh  }
42*a32536b4Sdan} {}
43*a32536b4Sdan
44*a32536b4Sdanifcapable incrblob {
45*a32536b4Sdan  do_test zeroblob-1.1.1 {
46ae7e151aSdrh    set ::sqlite3_max_blobsize
47ae7e151aSdrh  } {10}
48*a32536b4Sdan  do_test zeroblob-1.1.2 {
4953e66c3cSdrh    expr {[sqlite3_memory_highwater]<$::memused+35000}
50655194d6Sdrh  } {1}
51*a32536b4Sdan}
52*a32536b4Sdan
53fdf972a9Sdrhdo_test zeroblob-1.2 {
54fdf972a9Sdrh  execsql {
55fdf972a9Sdrh    SELECT length(d) FROM t1
56fdf972a9Sdrh  }
57655194d6Sdrh} {1000000}
58ae7e151aSdrh
59ae7e151aSdrh# If a non-NULL column follows the zeroblob, then the content of
60ae7e151aSdrh# the zeroblob must be instantiated.
61ae7e151aSdrh#
62fdf972a9Sdrhdo_test zeroblob-1.3 {
63ae7e151aSdrh  set ::sqlite3_max_blobsize 0
64fdf972a9Sdrh  execsql {
65ae7e151aSdrh    INSERT INTO t1 VALUES(3,4,zeroblob(10000),5);
66fdf972a9Sdrh  }
67ae7e151aSdrh  set ::sqlite3_max_blobsize
68ae7e151aSdrh} {10010}
69fdf972a9Sdrhdo_test zeroblob-1.4 {
70fdf972a9Sdrh  execsql {
71fdf972a9Sdrh    SELECT length(c), length(d) FROM t1
72fdf972a9Sdrh  }
73655194d6Sdrh} {1 1000000 10000 1}
74ae7e151aSdrh
75ae7e151aSdrh# Multiple zeroblobs can appear at the end of record.  No instantiation
76ae7e151aSdrh# of the blob content occurs on the stack.
77ae7e151aSdrh#
78fdf972a9Sdrhdo_test zeroblob-1.5 {
79ae7e151aSdrh  set ::sqlite3_max_blobsize 0
80fdf972a9Sdrh  execsql {
81ae7e151aSdrh    INSERT INTO t1 VALUES(4,5,zeroblob(10000),zeroblob(10000));
82fdf972a9Sdrh  }
83*a32536b4Sdan} {}
84*a32536b4Sdanifcapable incrblob {
85*a32536b4Sdan  do_test zeroblob-1.5.1 {
86ae7e151aSdrh    set ::sqlite3_max_blobsize
87ae7e151aSdrh  } {11}
88*a32536b4Sdan}
89fdf972a9Sdrhdo_test zeroblob-1.6 {
90fdf972a9Sdrh  execsql {
91fdf972a9Sdrh    SELECT length(c), length(d) FROM t1
92fdf972a9Sdrh  }
93655194d6Sdrh} {1 1000000 10000 1 10000 10000}
94fdf972a9Sdrh
95ae7e151aSdrh# NULLs can follow the zeroblob() or be intermixed with zeroblobs and
96ae7e151aSdrh# no instantiation of the zeroblobs occurs on the stack.
97ae7e151aSdrh#
98ae7e151aSdrhdo_test zeroblob-1.7 {
99ae7e151aSdrh  set ::sqlite3_max_blobsize 0
100ae7e151aSdrh  execsql {
101ae7e151aSdrh    INSERT INTO t1 VALUES(5,zeroblob(10000),NULL,zeroblob(10000));
102ae7e151aSdrh  }
103*a32536b4Sdan} {}
104*a32536b4Sdanifcapable incrblob {
105*a32536b4Sdan  do_test zeroblob-1.7.1 {
106ae7e151aSdrh    set ::sqlite3_max_blobsize
107ae7e151aSdrh  } {10}
108*a32536b4Sdan}
109ae7e151aSdrhdo_test zeroblob-1.8 {
110ae7e151aSdrh  execsql {
111ae7e151aSdrh    SELECT length(b), length(d) FROM t1 WHERE a=5
112ae7e151aSdrh  }
113ae7e151aSdrh} {10000 10000}
114ae7e151aSdrh
115ae7e151aSdrh# Comparisons against zeroblobs work.
116ae7e151aSdrh#
117ae7e151aSdrhdo_test zeroblob-2.1 {
118ae7e151aSdrh  execsql {
119ae7e151aSdrh    SELECT a FROM t1 WHERE b=zeroblob(10000)
120ae7e151aSdrh  }
121ae7e151aSdrh} {5}
122ae7e151aSdrh
123ae7e151aSdrh# Comparisons against zeroblobs work even when indexed.
124ae7e151aSdrh#
125ae7e151aSdrhdo_test zeroblob-2.2 {
126ae7e151aSdrh  execsql {
127ae7e151aSdrh    CREATE INDEX i1_1 ON t1(b);
128ae7e151aSdrh    SELECT a FROM t1 WHERE b=zeroblob(10000);
129ae7e151aSdrh  }
130ae7e151aSdrh} {5}
131ae7e151aSdrh
132ae7e151aSdrh# DISTINCT works for zeroblobs
133ae7e151aSdrh#
1344152e677Sdanielk1977ifcapable bloblit&&subquery&&compound {
135ae7e151aSdrh  do_test zeroblob-3.1 {
136ae7e151aSdrh    execsql {
137ae7e151aSdrh      SELECT count(DISTINCT a) FROM (
138ae7e151aSdrh        SELECT x'00000000000000000000' AS a
139ae7e151aSdrh        UNION ALL
140ae7e151aSdrh        SELECT zeroblob(10) AS a
141ae7e151aSdrh      )
142ae7e151aSdrh    }
143ae7e151aSdrh  } {1}
1444152e677Sdanielk1977}
145ae7e151aSdrh
14650027d1cSdrh# Concatentation works with zeroblob
14750027d1cSdrh#
1484152e677Sdanielk1977ifcapable bloblit {
14950027d1cSdrh  do_test zeroblob-4.1 {
15050027d1cSdrh    execsql {
15150027d1cSdrh      SELECT hex(zeroblob(2) || x'61')
15250027d1cSdrh    }
15350027d1cSdrh  } {000061}
1544152e677Sdanielk1977}
15550027d1cSdrh
1566b28f053Sdanielk1977# Check various CAST(...) operations on zeroblob.
1576b28f053Sdanielk1977#
1586b28f053Sdanielk1977do_test zeroblob-5.1 {
1596b28f053Sdanielk1977  execsql {
1606b28f053Sdanielk1977    SELECT CAST (zeroblob(100) AS REAL);
1616b28f053Sdanielk1977  }
1626b28f053Sdanielk1977} {0.0}
1636b28f053Sdanielk1977do_test zeroblob-5.2 {
1646b28f053Sdanielk1977  execsql {
1656b28f053Sdanielk1977    SELECT CAST (zeroblob(100) AS INTEGER);
1666b28f053Sdanielk1977  }
1676b28f053Sdanielk1977} {0}
1686b28f053Sdanielk1977do_test zeroblob-5.3 {
1696b28f053Sdanielk1977  execsql {
1706b28f053Sdanielk1977    SELECT CAST (zeroblob(100) AS TEXT);
1716b28f053Sdanielk1977  }
1726b28f053Sdanielk1977} {{}}
1736b28f053Sdanielk1977do_test zeroblob-5.4 {
1746b28f053Sdanielk1977  execsql {
1756b28f053Sdanielk1977    SELECT CAST(zeroblob(100) AS BLOB);
1766b28f053Sdanielk1977  }
1776b28f053Sdanielk1977} [execsql {SELECT zeroblob(100)}]
1786b28f053Sdanielk1977
179ae7e151aSdrh
18098640a3fSdrh# Check for malicious use of zeroblob.  Make sure nothing crashes.
18198640a3fSdrh#
18298640a3fSdrhdo_test zeroblob-6.1.1 {
18398640a3fSdrh  execsql {select zeroblob(-1)}
18498640a3fSdrh} {{}}
18598640a3fSdrhdo_test zeroblob-6.1.2 {
18698640a3fSdrh  execsql {select zeroblob(-10)}
18798640a3fSdrh} {{}}
18898640a3fSdrhdo_test zeroblob-6.1.3 {
18998640a3fSdrh  execsql {select zeroblob(-100)}
19098640a3fSdrh} {{}}
19198640a3fSdrhdo_test zeroblob-6.2 {
19298640a3fSdrh  execsql {select length(zeroblob(-1))}
19398640a3fSdrh} {0}
19498640a3fSdrhdo_test zeroblob-6.3 {
19598640a3fSdrh  execsql {select zeroblob(-1)|1}
19698640a3fSdrh} {1}
19798640a3fSdrhdo_test zeroblob-6.4 {
19898640a3fSdrh  catchsql {select length(zeroblob(2147483648))}
19998640a3fSdrh} {1 {string or blob too big}}
20098640a3fSdrhdo_test zeroblob-6.5 {
20198640a3fSdrh  catchsql {select zeroblob(2147483648)}
20298640a3fSdrh} {1 {string or blob too big}}
203c0b3abb2Sdrhdo_test zeroblob-6.6 {
204c0b3abb2Sdrh  execsql {select hex(zeroblob(-1))}
205c0b3abb2Sdrh} {{}}
206c0b3abb2Sdrhdo_test zeroblob-6.7 {
207c0b3abb2Sdrh  execsql {select typeof(zeroblob(-1))}
208c0b3abb2Sdrh} {blob}
20998640a3fSdrh
21028c66307Sdanielk1977# Test bind_zeroblob()
21128c66307Sdanielk1977#
212c91d86c9Sdrhsqlite3_memory_highwater 1
213c91d86c9Sdrhunset -nocomplain memused
214c91d86c9Sdrhset memused [sqlite3_memory_used]
21528c66307Sdanielk1977do_test zeroblob-7.1 {
21628c66307Sdanielk1977  set ::STMT [sqlite3_prepare $::DB "SELECT length(?)" -1 DUMMY]
217c91d86c9Sdrh  set ::sqlite3_max_blobsize 0
218c91d86c9Sdrh  sqlite3_bind_zeroblob $::STMT 1 450000
21928c66307Sdanielk1977  sqlite3_step $::STMT
22028c66307Sdanielk1977} {SQLITE_ROW}
22128c66307Sdanielk1977do_test zeroblob-7.2 {
22228c66307Sdanielk1977  sqlite3_column_int $::STMT 0
223c91d86c9Sdrh} {450000}
22428c66307Sdanielk1977do_test zeroblob-7.3 {
22528c66307Sdanielk1977  sqlite3_finalize $::STMT
22628c66307Sdanielk1977} {SQLITE_OK}
227*a32536b4Sdanifcapable incrblob {
228c91d86c9Sdrh  do_test zeroblob-7.4 {
229c91d86c9Sdrh    set ::sqlite3_max_blobsize
230c91d86c9Sdrh  } {0}
231c91d86c9Sdrh  do_test zeroblob-7.5 {
232c91d86c9Sdrh    expr {[sqlite3_memory_highwater]<$::memused+10000}
233c91d86c9Sdrh  } {1}
234*a32536b4Sdan}
23528c66307Sdanielk1977
236843e65f2Sdanielk1977# Test that MakeRecord can handle a value with some real content
237843e65f2Sdanielk1977# and a zero-blob tail.
238843e65f2Sdanielk1977#
239843e65f2Sdanielk1977do_test zeroblob-8.1 {
240843e65f2Sdanielk1977  llength [execsql {
241843e65f2Sdanielk1977    SELECT 'hello' AS a, zeroblob(10) as b from t1 ORDER BY a, b;
242843e65f2Sdanielk1977  }]
243843e65f2Sdanielk1977} {8}
244843e65f2Sdanielk1977
245843e65f2Sdanielk1977
2466be240e5Sdrh# Ticket #3965
2476be240e5Sdrh# zeroblobs on either size of an IN operator
2486be240e5Sdrh#
2496be240e5Sdrhdo_test zeroblob-9.1 {
2506be240e5Sdrh  db eval {SELECT x'0000' IN (x'000000')}
2516be240e5Sdrh} {0}
2526be240e5Sdrhdo_test zeroblob-9.2 {
2536be240e5Sdrh  db eval {SELECT x'0000' IN (x'0000')}
2546be240e5Sdrh} {1}
2556be240e5Sdrhdo_test zeroblob-9.3 {
2566be240e5Sdrh  db eval {SELECT zeroblob(2) IN (x'000000')}
2576be240e5Sdrh} {0}
2586be240e5Sdrhdo_test zeroblob-9.4 {
2596be240e5Sdrh  db eval {SELECT zeroblob(2) IN (x'0000')}
2606be240e5Sdrh} {1}
2616be240e5Sdrhdo_test zeroblob-9.5 {
2626be240e5Sdrh  db eval {SELECT x'0000' IN (zeroblob(3))}
2636be240e5Sdrh} {0}
2646be240e5Sdrhdo_test zeroblob-9.6 {
2656be240e5Sdrh  db eval {SELECT x'0000' IN (zeroblob(2))}
2666be240e5Sdrh} {1}
2676be240e5Sdrhdo_test zeroblob-9.7 {
2686be240e5Sdrh  db eval {SELECT zeroblob(2) IN (zeroblob(3))}
2696be240e5Sdrh} {0}
2706be240e5Sdrhdo_test zeroblob-9.8 {
2716be240e5Sdrh  db eval {SELECT zeroblob(2) IN (zeroblob(2))}
2726be240e5Sdrh} {1}
2736be240e5Sdrh
2744a33507fSdrh# Oversized zeroblob records
2754a33507fSdrh#
2764a33507fSdrhdo_test zeroblob-10.1 {
2774a33507fSdrh  db eval {
2784a33507fSdrh    CREATE TABLE t10(a,b,c);
2794a33507fSdrh  }
2804a33507fSdrh  catchsql {INSERT INTO t10 VALUES(zeroblob(1e9),zeroblob(1e9),zeroblob(1e9))}
2814a33507fSdrh} {1 {string or blob too big}}
2824a33507fSdrh
283a4d5ae8fSdan#-------------------------------------------------------------------------
28480c03022Sdan# Test the zeroblob() function on its own with negative or oversized
28580c03022Sdan# arguments.
28680c03022Sdan#
287a4d5ae8fSdando_execsql_test 11.0 {
288a4d5ae8fSdan  SELECT length(zeroblob(-1444444444444444));
289a4d5ae8fSdan} {0}
290a4d5ae8fSdando_catchsql_test 11.1 {
291c6edb3acSdrh  SELECT zeroblob(5000 * 1024 * 1024);
292a4d5ae8fSdan} {1 {string or blob too big}}
293a4d5ae8fSdando_catchsql_test 11.2 {
294c6edb3acSdrh  SELECT quote(zeroblob(5000 * 1024 * 1024));
295a4d5ae8fSdan} {1 {string or blob too big}}
296a4d5ae8fSdando_catchsql_test 11.3 {
297a4d5ae8fSdan  SELECT quote(zeroblob(-1444444444444444));
298a4d5ae8fSdan} {0 X''}
299a4d5ae8fSdando_catchsql_test 11.4 {
300a4d5ae8fSdan  SELECT quote(test_zeroblob(-1));
301a4d5ae8fSdan} {0 X''}
3026be240e5Sdrh
30380c03022Sdan#-------------------------------------------------------------------------
30480c03022Sdan# Test the sqlite3_bind_zeroblob64() API.
30580c03022Sdan#
30680c03022Sdanproc bind_and_run {stmt nZero} {
30780c03022Sdan  sqlite3_bind_zeroblob64 $stmt 1 $nZero
30880c03022Sdan  sqlite3_step $stmt
30980c03022Sdan  set ret [sqlite3_column_int $stmt 0]
31080c03022Sdan  sqlite3_reset $stmt
31180c03022Sdan  set ret
31280c03022Sdan}
31380c03022Sdanset stmt [sqlite3_prepare db "SELECT length(?)" -1 dummy]
31480c03022Sdan
31580c03022Sdando_test 12.1 { bind_and_run $stmt 40 } 40
31680c03022Sdando_test 12.2 { bind_and_run $stmt  0 }  0
31780c03022Sdando_test 12.3 { bind_and_run $stmt 1000 } 1000
31880c03022Sdan
31980c03022Sdando_test 12.4 {
320c6edb3acSdrh  list [catch { bind_and_run $stmt [expr 5000 * 1024 * 1024] } msg] $msg
32180c03022Sdan} {1 SQLITE_TOOBIG}
32280c03022Sdando_test 12.5 {
32380c03022Sdan  sqlite3_step $stmt
32480c03022Sdan  set ret [sqlite3_column_int $stmt 0]
32580c03022Sdan  sqlite3_reset $stmt
32680c03022Sdan  set ret
32780c03022Sdan} {1000}
32880c03022Sdan
32980c03022Sdansqlite3_finalize $stmt
33080c03022Sdan
3310814acd9Sdrh# 2019-01-25 https://sqlite.org/src/tktview/bb4bdb9f7f654b0bb9f34cfbac
3320814acd9Sdrh# Zeroblob truncated by an index on expression
3330814acd9Sdrh#
3340814acd9Sdrhdo_execsql_test 13.100 {
3350814acd9Sdrh  DROP TABLE IF EXISTS t1;
3360814acd9Sdrh  CREATE TABLE t1(a,b,c);
3370814acd9Sdrh  CREATE INDEX t1bbc ON t1(b, b+c);
3380814acd9Sdrh  INSERT INTO t1(a,b,c) VALUES(1,zeroblob(8),3);
3390814acd9Sdrh  SELECT a, quote(b), length(b), c FROM t1;
3400814acd9Sdrh} {1 X'0000000000000000' 8 3}
3410814acd9Sdrh
34203bc525aSdantest_restore_config_pagecache
343fdf972a9Sdrhfinish_test
344