blob: 439490cd7613844e5eff1357a5d7574700498a1d [file] [log] [blame]
drhdb83f822007-05-11 00:20:08 +00001# 2007 May 10
danielk1977def0fec2007-05-10 15:37:52 +00002#
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
drhdb83f822007-05-11 00:20:08 +000012# focus of this file is generating semi-random strings of SQL
danielk19771e4eaeb2007-05-14 14:04:59 +000013# (a.k.a. "fuzz") and sending it into the parser to try to
14# generate errors.
danielk1977def0fec2007-05-10 15:37:52 +000015#
danielk19771e4eaeb2007-05-14 14:04:59 +000016# The tests in this file are really about testing fuzzily generated
17# SQL parse-trees. The majority of the fuzzily generated SQL is
18# valid as far as the parser is concerned.
19#
20# The most complicated trees are for SELECT statements.
21#
danielk1977fa2bb6d2007-05-14 15:49:43 +000022# $Id: fuzz.test,v 1.9 2007/05/14 15:49:44 danielk1977 Exp $
danielk1977def0fec2007-05-10 15:37:52 +000023
24set testdir [file dirname $argv0]
25source $testdir/tester.tcl
26
danielk1977fa2bb6d2007-05-14 15:49:43 +000027# set ::REPEATS 20
28set ::REPEATS 5000
danielk19771f7c83e2007-05-11 16:58:03 +000029
danielk1977def0fec2007-05-10 15:37:52 +000030proc fuzz {TemplateList} {
31 set n [llength $TemplateList]
32 set i [expr {int(rand()*$n)}]
danielk19771e4eaeb2007-05-14 14:04:59 +000033 set r [uplevel 1 subst -novar [list [lindex $TemplateList $i]]]
34
35 string map {"\n" " "} $r
danielk1977def0fec2007-05-10 15:37:52 +000036}
37
danielk1977bcfc4bc2007-05-11 10:10:33 +000038# Fuzzy generation primitives:
39#
40# Literal
41# UnaryOp
42# BinaryOp
43# Expr
44# Table
45# Select
46# Insert
47#
48
danielk1977f75232f2007-05-10 17:32:48 +000049# Returns a string representing an SQL literal.
50#
51proc Literal {} {
danielk1977def0fec2007-05-10 15:37:52 +000052 set TemplateList {
53 456 0 -456 1 -1
54 2147483648 2147483647 2147483649 -2147483647 -2147483648 -2147483649
55 'The' 'first' 'experiments' 'in' 'hardware' 'fault' 'injection'
56 zeroblob(1000)
57 NULL
58 56.1 -56.1
59 123456789.1234567899
60 }
61 fuzz $TemplateList
62}
63
danielk1977bcfc4bc2007-05-11 10:10:33 +000064# Returns a string containing an SQL unary operator (e.g. "+" or "NOT").
65#
danielk1977def0fec2007-05-10 15:37:52 +000066proc UnaryOp {} {
danielk1977bcfc4bc2007-05-11 10:10:33 +000067 set TemplateList {+ - NOT ~}
danielk1977def0fec2007-05-10 15:37:52 +000068 fuzz $TemplateList
69}
70
danielk1977bcfc4bc2007-05-11 10:10:33 +000071# Returns a string containing an SQL binary operator (e.g. "*" or "/").
72#
danielk1977def0fec2007-05-10 15:37:52 +000073proc BinaryOp {} {
danielk1977bcfc4bc2007-05-11 10:10:33 +000074 set TemplateList {
75 || * / % + - << >> & | < <= > >= = == != <> AND OR
76 LIKE GLOB {NOT LIKE}
77 }
danielk1977def0fec2007-05-10 15:37:52 +000078 fuzz $TemplateList
79}
80
danielk1977bcfc4bc2007-05-11 10:10:33 +000081# Return the complete text of an SQL expression.
82#
danielk1977def0fec2007-05-10 15:37:52 +000083set ::ExprDepth 0
danielk1977bcfc4bc2007-05-11 10:10:33 +000084proc Expr { {c {}} } {
danielk1977def0fec2007-05-10 15:37:52 +000085 incr ::ExprDepth
86
danielk19771e4eaeb2007-05-14 14:04:59 +000087 set TemplateList [concat $c $c $c {[Literal]}]
88 if {$::ExprDepth < 3} {
danielk1977def0fec2007-05-10 15:37:52 +000089 lappend TemplateList \
danielk19771e4eaeb2007-05-14 14:04:59 +000090 {[Expr $c] [BinaryOp] [Expr $c]} \
91 {[UnaryOp] [Expr $c]} \
92 {[Expr $c] ISNULL} \
93 {[Expr $c] NOTNULL} \
94 {CAST([Expr $c] AS blob)} \
95 {CAST([Expr $c] AS text)} \
96 {CAST([Expr $c] AS integer)} \
97 {CAST([Expr $c] AS real)} \
98 {abs([Expr])} \
99 {coalesce([Expr], [Expr])} \
100 {hex([Expr])} \
101 {length([Expr])} \
102 {lower([Expr])} \
103 {upper([Expr])} \
104 {quote([Expr])} \
105 {random()} \
106 {randomblob(min(max([Expr],1), 500))} \
107 {typeof([Expr])} \
108 {substr([Expr],[Expr],[Expr])} \
danielk1977bcfc4bc2007-05-11 10:10:33 +0000109 {CASE WHEN [Expr $c] THEN [Expr $c] ELSE [Expr $c] END} \
danielk19771e4eaeb2007-05-14 14:04:59 +0000110 {[Literal]} {[Literal]} {[Literal]} \
111 {[Literal]} {[Literal]} {[Literal]} \
112 {[Literal]} {[Literal]} {[Literal]} \
danielk1977bcfc4bc2007-05-11 10:10:33 +0000113 {[Literal]} {[Literal]} {[Literal]}
danielk1977def0fec2007-05-10 15:37:52 +0000114 }
danielk1977fa2bb6d2007-05-14 15:49:43 +0000115 if {$::SelectDepth < 4} {
danielk1977bcfc4bc2007-05-11 10:10:33 +0000116 lappend TemplateList \
117 {([Select 1])} \
118 {[Expr $c] IN ([Select 1])} \
119 {[Expr $c] NOT IN ([Select 1])} \
120 {EXISTS ([Select 1])} \
danielk1977def0fec2007-05-10 15:37:52 +0000121 }
122 set res [fuzz $TemplateList]
123 incr ::ExprDepth -1
124 return $res
125}
126
danielk1977bcfc4bc2007-05-11 10:10:33 +0000127# Return a valid table name.
128#
danielk1977f75232f2007-05-10 17:32:48 +0000129set ::TableList [list]
130proc Table {} {
131 set TemplateList [concat sqlite_master $::TableList]
132 fuzz $TemplateList
133}
134
danielk19771e4eaeb2007-05-14 14:04:59 +0000135# Return one of:
danielk1977bcfc4bc2007-05-11 10:10:33 +0000136#
danielk19771e4eaeb2007-05-14 14:04:59 +0000137# "SELECT DISTINCT", "SELECT ALL" or "SELECT"
138#
139proc SelectKw {} {
140 set TemplateList {
141 "SELECT DISTINCT"
142 "SELECT ALL"
143 "SELECT"
144 }
145 fuzz $TemplateList
146}
147
148# Return a result set for a SELECT statement.
149#
150proc ResultSet {{nRes 0} {c ""}} {
151 if {$nRes == 0} {
152 set nRes [expr {rand()*2 + 1}]
153 }
154
155 set aRes [list]
156 for {set ii 0} {$ii < $nRes} {incr ii} {
157 lappend aRes [Expr $c]
158 }
159
160 join $aRes ", "
161}
162
danielk1977def0fec2007-05-10 15:37:52 +0000163set ::SelectDepth 0
danielk19771f7c83e2007-05-11 16:58:03 +0000164set ::ColumnList [list]
danielk19771e4eaeb2007-05-14 14:04:59 +0000165proc SimpleSelect {{nRes 0}} {
danielk1977f75232f2007-05-10 17:32:48 +0000166
danielk19771e4eaeb2007-05-14 14:04:59 +0000167 set TemplateList {
168 {[SelectKw] [ResultSet $nRes]}
169 }
170
171 # The ::SelectDepth variable contains the number of ancestor SELECT
172 # statements (i.e. for a top level SELECT it is set to 0, for a
173 # sub-select 1, for a sub-select of a sub-select 2 etc.).
174 #
175 # If this is already greater than 3, do not generate a complicated
176 # SELECT statement. This tends to cause parser stack overflow (too
177 # boring to bother with).
178 #
179 if {$::SelectDepth < 4} {
180 lappend TemplateList \
181 {[SelectKw] [ResultSet $nRes $::ColumnList] FROM ([Select])} \
182 {[SelectKw] [ResultSet $nRes] FROM ([Select])} \
183 {[SelectKw] [ResultSet $nRes $::ColumnList] FROM [Table]} \
184 {
185 [SelectKw] [ResultSet $nRes $::ColumnList]
186 FROM ([Select])
187 GROUP BY [Expr]
188 HAVING [Expr]
189 } \
190
191 if {0 == $nRes} {
192 lappend TemplateList \
193 {[SelectKw] * FROM ([Select])} \
194 {[SelectKw] * FROM [Table]} \
195 {[SelectKw] * FROM [Table] WHERE [Expr $::ColumnList]} \
196 {
197 [SelectKw] *
198 FROM [Table],[Table] AS t2
199 WHERE [Expr $::ColumnList]
danielk1977fa2bb6d2007-05-14 15:49:43 +0000200 } {
201 [SelectKw] *
202 FROM [Table] LEFT OUTER JOIN [Table] AS t2
203 ON [Expr $::ColumnList]
204 WHERE [Expr $::ColumnList]
205 }
danielk1977f75232f2007-05-10 17:32:48 +0000206 }
207 }
danielk19771e4eaeb2007-05-14 14:04:59 +0000208
209 fuzz $TemplateList
210}
211
212# Return a SELECT statement.
213#
214# If boolean parameter $isExpr is set to true, make sure the
215# returned SELECT statement returns a single column of data.
216#
217proc Select {{nMulti 0}} {
218 set TemplateList {
219 {[SimpleSelect $nMulti]} {[SimpleSelect $nMulti]} {[SimpleSelect $nMulti]}
220 {[SimpleSelect $nMulti]} {[SimpleSelect $nMulti]} {[SimpleSelect $nMulti]}
221 {[SimpleSelect $nMulti]} {[SimpleSelect $nMulti]} {[SimpleSelect $nMulti]}
222 {[SimpleSelect $nMulti]} {[SimpleSelect $nMulti]} {[SimpleSelect $nMulti]}
danielk1977fa2bb6d2007-05-14 15:49:43 +0000223 {[SimpleSelect $nMulti] ORDER BY [Expr] DESC}
224 {[SimpleSelect $nMulti] ORDER BY [Expr] ASC}
225 {[SimpleSelect $nMulti] ORDER BY [Expr] ASC, [Expr] DESC}
danielk19771e4eaeb2007-05-14 14:04:59 +0000226 {[SimpleSelect $nMulti] ORDER BY [Expr] LIMIT [Expr] OFFSET [Expr]}
227 }
228
229 if {$::SelectDepth < 4} {
230 if {$nMulti == 0} {
231 set nMulti [expr {(rand()*2)+1}]
232 }
233 lappend TemplateList \
234 {[SimpleSelect $nMulti] UNION [Select $nMulti]} \
235 {[SimpleSelect $nMulti] UNION ALL [Select $nMulti]} \
236 {[SimpleSelect $nMulti] EXCEPT [Select $nMulti]} \
237 {[SimpleSelect $nMulti] INTERSECT [Select $nMulti]}
238 }
239
240 incr ::SelectDepth
danielk1977def0fec2007-05-10 15:37:52 +0000241 set res [fuzz $TemplateList]
242 incr ::SelectDepth -1
243 set res
244}
245
danielk1977bcfc4bc2007-05-11 10:10:33 +0000246# Generate and return a fuzzy INSERT statement.
247#
248proc Insert {} {
249 set TemplateList {
250 {INSERT INTO [Table] VALUES([Expr], [Expr], [Expr]);}
251 {INSERT INTO [Table] VALUES([Expr], [Expr], [Expr], [Expr]);}
252 {INSERT INTO [Table] VALUES([Expr], [Expr]);}
253 }
254 fuzz $TemplateList
255}
256
danielk19771f7c83e2007-05-11 16:58:03 +0000257proc Column {} {
258 fuzz $::ColumnList
259}
260
261# Generate and return a fuzzy UPDATE statement.
262#
263proc Update {} {
264 set TemplateList {
265 {UPDATE [Table]
266 SET [Column] = [Expr $::ColumnList]
267 WHERE [Expr $::ColumnList]}
268 }
269 fuzz $TemplateList
270}
271
272proc Delete {} {
273 set TemplateList {
274 {DELETE FROM [Table] WHERE [Expr $::ColumnList]}
275 }
276 fuzz $TemplateList
277}
278
279proc Statement {} {
280 set TemplateList {
281 {[Update]}
282 {[Insert]}
283 {[Select]}
284 {[Delete]}
285 }
286 fuzz $TemplateList
287}
288
danielk19771e4eaeb2007-05-14 14:04:59 +0000289# Return an identifier. This just chooses randomly from a fixed set
290# of strings.
291proc Identifier {} {
292 set TemplateList {
293 This just chooses randomly a fixed
danielk1977fa2bb6d2007-05-14 15:49:43 +0000294 We would also thank the developers
295 for their analysis Samba
danielk19771e4eaeb2007-05-14 14:04:59 +0000296 }
danielk19771e4eaeb2007-05-14 14:04:59 +0000297 fuzz $TemplateList
298}
299
300proc Check {} {
danielk1977fa2bb6d2007-05-14 15:49:43 +0000301 # Use a large value for $::SelectDepth, because sub-selects are
302 # not allowed in expressions used by CHECK constraints.
303 #
danielk19771e4eaeb2007-05-14 14:04:59 +0000304 set sd $::SelectDepth
305 set ::SelectDepth 500
306 set TemplateList {
307 {}
308 {CHECK ([Expr])}
309 }
310 set res [fuzz $TemplateList]
311 set ::SelectDepth $sd
312 set res
313}
314
315proc Coltype {} {
316 set TemplateList {
317 {INTEGER PRIMARY KEY}
318 {VARCHAR [Check]}
319 {PRIMARY KEY}
320 }
321 fuzz $TemplateList
322}
323
324proc CreateTable {} {
325 set TemplateList {
326 {CREATE TABLE [Identifier]([Identifier] [Coltype], [Identifier] [Coltype])}
327 {CREATE TEMP TABLE [Identifier]([Identifier] [Coltype])}
328 }
329 fuzz $TemplateList
330}
331
danielk1977f75232f2007-05-10 17:32:48 +0000332########################################################################
333
danielk1977bcfc4bc2007-05-11 10:10:33 +0000334set ::log [open fuzzy.log w]
335
danielk19771e4eaeb2007-05-14 14:04:59 +0000336#
danielk1977bcfc4bc2007-05-11 10:10:33 +0000337# Usage: do_fuzzy_test <testname> ?<options>?
338#
339# -template
340# -errorlist
danielk19771e4eaeb2007-05-14 14:04:59 +0000341# -repeats
danielk1977bcfc4bc2007-05-11 10:10:33 +0000342#
343proc do_fuzzy_test {testname args} {
344 set ::fuzzyopts(-errorlist) [list]
danielk19771e4eaeb2007-05-14 14:04:59 +0000345 set ::fuzzyopts(-repeats) $::REPEATS
danielk1977bcfc4bc2007-05-11 10:10:33 +0000346 array set ::fuzzyopts $args
danielk1977bcfc4bc2007-05-11 10:10:33 +0000347
danielk19771e4eaeb2007-05-14 14:04:59 +0000348 lappend ::fuzzyopts(-errorlist) {parser stack overflow}
349 lappend ::fuzzyopts(-errorlist) {ORDER BY}
350 lappend ::fuzzyopts(-errorlist) {GROUP BY}
351 lappend ::fuzzyopts(-errorlist) {datatype mismatch}
352
353 for {set ii 0} {$ii < $::fuzzyopts(-repeats)} {incr ii} {
danielk1977bcfc4bc2007-05-11 10:10:33 +0000354 do_test ${testname}.$ii {
355 set ::sql [subst $::fuzzyopts(-template)]
356 puts $::log $::sql
357 flush $::log
358 set rc [catch {execsql $::sql} msg]
359 set e 1
360 if {$rc} {
361 set e 0
362 foreach error $::fuzzyopts(-errorlist) {
363 if {0 == [string first $error $msg]} {
364 set e 1
365 break
366 }
367 }
368 }
369 if {$e == 0} {
370 puts ""
371 puts $::sql
372 puts $msg
373 }
374 set e
375 } {1}
376 }
377}
378
danielk1977f75232f2007-05-10 17:32:48 +0000379#----------------------------------------------------------------
380# These tests caused errors that were first caught by the tests
381# in this file. They are still here.
danielk1977def0fec2007-05-10 15:37:52 +0000382do_test fuzz-1.1 {
383 execsql {
384 SELECT 'abc' LIKE X'ABCD';
385 }
386} {0}
387do_test fuzz-1.2 {
388 execsql {
389 SELECT 'abc' LIKE zeroblob(10);
390 }
391} {0}
392do_test fuzz-1.3 {
393 execsql {
394 SELECT zeroblob(10) LIKE 'abc';
395 }
396} {0}
397do_test fuzz-1.4 {
398 execsql {
399 SELECT (- -21) % NOT (456 LIKE zeroblob(10));
400 }
401} {0}
danielk1977f75232f2007-05-10 17:32:48 +0000402do_test fuzz-1.5 {
403 execsql {
404 SELECT (SELECT (
405 SELECT (SELECT -2147483648) FROM (SELECT 1) ORDER BY 1
406 ))
danielk1977def0fec2007-05-10 15:37:52 +0000407 }
danielk1977f75232f2007-05-10 17:32:48 +0000408} {-2147483648}
409do_test fuzz-1.6 {
410 execsql {
411 SELECT 'abc', zeroblob(1) FROM (SELECT 1) ORDER BY 1
412 }
413} [execsql {SELECT 'abc', zeroblob(1)}]
414
415do_test fuzz-1.7 {
416 execsql {
danielk1977d908f5a2007-05-11 07:08:28 +0000417 SELECT ( SELECT zeroblob(1000) FROM (
418 SELECT * FROM (SELECT 'first') ORDER BY NOT 'in')
danielk1977639f45f2007-05-10 17:38:57 +0000419 )
danielk1977f75232f2007-05-10 17:32:48 +0000420 }
danielk1977d908f5a2007-05-11 07:08:28 +0000421} [execsql {SELECT zeroblob(1000)}]
danielk1977def0fec2007-05-10 15:37:52 +0000422
danielk1977bcfc4bc2007-05-11 10:10:33 +0000423do_test fuzz-1.8 {
danielk19771f7c83e2007-05-11 16:58:03 +0000424 # Problems with opcode OP_ToText (did not account for MEM_Zero).
425 # Also MemExpandBlob() was marking expanded blobs as nul-terminated.
426 # They are not.
danielk1977bcfc4bc2007-05-11 10:10:33 +0000427 execsql {
428 SELECT CAST(zeroblob(1000) AS text);
429 }
430} {{}}
431
danielk19771f7c83e2007-05-11 16:58:03 +0000432do_test fuzz-1.9 {
433 # This was causing a NULL pointer dereference of Expr.pList.
434 execsql {
435 SELECT 1 FROM (SELECT * FROM sqlite_master WHERE random())
436 }
437} {}
438
439do_test fuzz-1.10 {
440 # Bug in calculation of Parse.ckOffset causing an assert()
441 # to fail. Probably harmless.
442 execsql {
443 SELECT coalesce(1, substr( 1, 2, length('in' IN (SELECT 1))))
444 }
445} {1}
446
danielk19771e4eaeb2007-05-14 14:04:59 +0000447do_test fuzz-1.11 {
448 # The literals (A, B, C, D) are not important, they are just used
449 # to make the EXPLAIN output easier to read.
450 #
451 # The problem here is that the EXISTS(...) expression leaves an
452 # extra value on the VDBE stack. This is confusing the parent and
453 # leads to an assert() failure when OP_Insert encounters an integer
454 # when it expects a record blob.
455 #
456 # Update: Any query with (LIMIT 0) was leaking stack.
457 #
458 execsql {
459 SELECT 'A' FROM (SELECT 'B') ORDER BY EXISTS (
460 SELECT 'C' FROM (SELECT 'D' LIMIT 0)
461 )
462 }
463} {A}
464
danielk1977fa2bb6d2007-05-14 15:49:43 +0000465do_test fuzz-1.12.1 {
466 # Create a table with a single row.
467 execsql {
468 CREATE TABLE abc(b);
469 INSERT INTO abc VALUES('ABCDE');
470 }
471
472 # The following query was crashing. The later subquery (in the FROM)
473 # clause was flattened into the parent, but the code was not repairng
474 # the "b" reference in the other sub-query. When the query was executed,
475 # that "b" refered to a non-existant vdbe table-cursor.
476 #
477 execsql {
478 SELECT 1 IN ( SELECT b UNION SELECT 1 ) FROM (SELECT b FROM abc);
479 }
480} {1}
481do_test fuzz-1.12.2 {
482 # Clean up after the previous query.
483 execsql {
484 DROP TABLE abc;
485 }
486} {}
487
danielk1977f75232f2007-05-10 17:32:48 +0000488#----------------------------------------------------------------
489# Test some fuzzily generated expressions.
490#
danielk1977bcfc4bc2007-05-11 10:10:33 +0000491do_fuzzy_test fuzz-2 -template { SELECT [Expr] }
danielk1977f75232f2007-05-10 17:32:48 +0000492
493do_test fuzz-3.1 {
494 execsql {
495 CREATE TABLE abc(a, b, c);
danielk1977bcfc4bc2007-05-11 10:10:33 +0000496 CREATE TABLE def(a, b, c);
497 CREATE TABLE ghi(a, b, c);
danielk1977f75232f2007-05-10 17:32:48 +0000498 }
499} {}
danielk1977bcfc4bc2007-05-11 10:10:33 +0000500set ::TableList [list abc def ghi]
danielk1977f75232f2007-05-10 17:32:48 +0000501
502#----------------------------------------------------------------
503# Test some fuzzily generated SELECT statements.
504#
danielk1977bcfc4bc2007-05-11 10:10:33 +0000505do_fuzzy_test fuzz-3.2 -template {[Select]}
danielk1977f75232f2007-05-10 17:32:48 +0000506
danielk1977bcfc4bc2007-05-11 10:10:33 +0000507#----------------------------------------------------------------
508# Insert a small amount of data into the database and then run
509# some more generated SELECT statements.
510#
511do_test fuzz-4.1 {
512 execsql {
513 INSERT INTO abc VALUES(1, 2, 3);
514 INSERT INTO abc VALUES(4, 5, 6);
515 INSERT INTO abc VALUES(7, 8, 9);
516 INSERT INTO def VALUES(1, 2, 3);
517 INSERT INTO def VALUES(4, 5, 6);
518 INSERT INTO def VALUES(7, 8, 9);
519 INSERT INTO ghi VALUES(1, 2, 3);
520 INSERT INTO ghi VALUES(4, 5, 6);
521 INSERT INTO ghi VALUES(7, 8, 9);
522 CREATE INDEX abc_i ON abc(a, b, c);
523 CREATE INDEX def_i ON def(c, a, b);
524 CREATE INDEX ghi_i ON ghi(b, c, a);
525 }
526} {}
527do_fuzzy_test fuzz-4.2 -template {[Select]}
528
529#----------------------------------------------------------------
530# Test some fuzzy INSERT statements:
531#
532do_test fuzz-5.1 {execsql BEGIN} {}
533do_fuzzy_test fuzz-5.2 -template {[Insert]} -errorlist table
534integrity_check fuzz-5.2.integrity
535do_test fuzz-5.3 {execsql COMMIT} {}
536integrity_check fuzz-5.4.integrity
537
danielk19771f7c83e2007-05-11 16:58:03 +0000538#----------------------------------------------------------------
danielk19771e4eaeb2007-05-14 14:04:59 +0000539# Now that there is data in the database, run some more SELECT
danielk19771f7c83e2007-05-11 16:58:03 +0000540# statements
541#
542set ::ColumnList [list a b c]
543set E {{no such col} {ambiguous column name}}
544do_fuzzy_test fuzz-6.1 -template {[Select]} -errorlist $E
545
546#----------------------------------------------------------------
547# Run some SELECTs, INSERTs, UPDATEs and DELETEs in a transaction.
548#
549set E {{no such col} {ambiguous column name} {table}}
550do_test fuzz-7.1 {execsql BEGIN} {}
551do_fuzzy_test fuzz-7.2 -template {[Statement]} -errorlist $E
552integrity_check fuzz-7.3.integrity
553do_test fuzz-7.4 {execsql COMMIT} {}
554integrity_check fuzz-7.5.integrity
danielk1977bcfc4bc2007-05-11 10:10:33 +0000555
danielk19771e4eaeb2007-05-14 14:04:59 +0000556#----------------------------------------------------------------
557# Many CREATE TABLE statements:
558#
559do_fuzzy_test fuzz-8.1 -template {[CreateTable]} \
560 -errorlist {table duplicate} -repeats 1000
561
danielk1977bcfc4bc2007-05-11 10:10:33 +0000562close $::log
danielk1977def0fec2007-05-10 15:37:52 +0000563finish_test