blob: 19e9c1cb38b69763acdf28942f48d594ecb6b6b1 [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#
danielk197715d79822007-05-15 07:00:34 +000022# $Id: fuzz.test,v 1.11 2007/05/15 07:00:34 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 +000027set ::REPEATS 5000
danielk197715d79822007-05-15 07:00:34 +000028if {[info exists $::ISQUICK]} {
29 if {$::ISQUICK} { set ::REPEATS 20 }
30}
danielk19771f7c83e2007-05-11 16:58:03 +000031
danielk1977def0fec2007-05-10 15:37:52 +000032proc fuzz {TemplateList} {
33 set n [llength $TemplateList]
34 set i [expr {int(rand()*$n)}]
danielk19771e4eaeb2007-05-14 14:04:59 +000035 set r [uplevel 1 subst -novar [list [lindex $TemplateList $i]]]
36
37 string map {"\n" " "} $r
danielk1977def0fec2007-05-10 15:37:52 +000038}
39
danielk1977bcfc4bc2007-05-11 10:10:33 +000040# Fuzzy generation primitives:
41#
42# Literal
43# UnaryOp
44# BinaryOp
45# Expr
46# Table
47# Select
48# Insert
49#
50
danielk1977f75232f2007-05-10 17:32:48 +000051# Returns a string representing an SQL literal.
52#
53proc Literal {} {
danielk1977def0fec2007-05-10 15:37:52 +000054 set TemplateList {
55 456 0 -456 1 -1
56 2147483648 2147483647 2147483649 -2147483647 -2147483648 -2147483649
57 'The' 'first' 'experiments' 'in' 'hardware' 'fault' 'injection'
58 zeroblob(1000)
59 NULL
60 56.1 -56.1
61 123456789.1234567899
62 }
63 fuzz $TemplateList
64}
65
danielk1977bcfc4bc2007-05-11 10:10:33 +000066# Returns a string containing an SQL unary operator (e.g. "+" or "NOT").
67#
danielk1977def0fec2007-05-10 15:37:52 +000068proc UnaryOp {} {
danielk1977bcfc4bc2007-05-11 10:10:33 +000069 set TemplateList {+ - NOT ~}
danielk1977def0fec2007-05-10 15:37:52 +000070 fuzz $TemplateList
71}
72
danielk1977bcfc4bc2007-05-11 10:10:33 +000073# Returns a string containing an SQL binary operator (e.g. "*" or "/").
74#
danielk1977def0fec2007-05-10 15:37:52 +000075proc BinaryOp {} {
danielk1977bcfc4bc2007-05-11 10:10:33 +000076 set TemplateList {
77 || * / % + - << >> & | < <= > >= = == != <> AND OR
78 LIKE GLOB {NOT LIKE}
79 }
danielk1977def0fec2007-05-10 15:37:52 +000080 fuzz $TemplateList
81}
82
danielk1977bcfc4bc2007-05-11 10:10:33 +000083# Return the complete text of an SQL expression.
84#
danielk1977def0fec2007-05-10 15:37:52 +000085set ::ExprDepth 0
danielk1977bcfc4bc2007-05-11 10:10:33 +000086proc Expr { {c {}} } {
danielk1977def0fec2007-05-10 15:37:52 +000087 incr ::ExprDepth
88
danielk19771e4eaeb2007-05-14 14:04:59 +000089 set TemplateList [concat $c $c $c {[Literal]}]
90 if {$::ExprDepth < 3} {
danielk1977def0fec2007-05-10 15:37:52 +000091 lappend TemplateList \
danielk19771e4eaeb2007-05-14 14:04:59 +000092 {[Expr $c] [BinaryOp] [Expr $c]} \
93 {[UnaryOp] [Expr $c]} \
94 {[Expr $c] ISNULL} \
95 {[Expr $c] NOTNULL} \
96 {CAST([Expr $c] AS blob)} \
97 {CAST([Expr $c] AS text)} \
98 {CAST([Expr $c] AS integer)} \
99 {CAST([Expr $c] AS real)} \
100 {abs([Expr])} \
101 {coalesce([Expr], [Expr])} \
102 {hex([Expr])} \
103 {length([Expr])} \
104 {lower([Expr])} \
105 {upper([Expr])} \
106 {quote([Expr])} \
107 {random()} \
108 {randomblob(min(max([Expr],1), 500))} \
109 {typeof([Expr])} \
110 {substr([Expr],[Expr],[Expr])} \
danielk1977bcfc4bc2007-05-11 10:10:33 +0000111 {CASE WHEN [Expr $c] THEN [Expr $c] ELSE [Expr $c] END} \
danielk19771e4eaeb2007-05-14 14:04:59 +0000112 {[Literal]} {[Literal]} {[Literal]} \
113 {[Literal]} {[Literal]} {[Literal]} \
114 {[Literal]} {[Literal]} {[Literal]} \
danielk1977bcfc4bc2007-05-11 10:10:33 +0000115 {[Literal]} {[Literal]} {[Literal]}
danielk1977def0fec2007-05-10 15:37:52 +0000116 }
danielk1977fa2bb6d2007-05-14 15:49:43 +0000117 if {$::SelectDepth < 4} {
danielk1977bcfc4bc2007-05-11 10:10:33 +0000118 lappend TemplateList \
119 {([Select 1])} \
120 {[Expr $c] IN ([Select 1])} \
121 {[Expr $c] NOT IN ([Select 1])} \
122 {EXISTS ([Select 1])} \
danielk1977def0fec2007-05-10 15:37:52 +0000123 }
124 set res [fuzz $TemplateList]
125 incr ::ExprDepth -1
126 return $res
127}
128
danielk1977bcfc4bc2007-05-11 10:10:33 +0000129# Return a valid table name.
130#
danielk1977f75232f2007-05-10 17:32:48 +0000131set ::TableList [list]
132proc Table {} {
133 set TemplateList [concat sqlite_master $::TableList]
134 fuzz $TemplateList
135}
136
danielk19771e4eaeb2007-05-14 14:04:59 +0000137# Return one of:
danielk1977bcfc4bc2007-05-11 10:10:33 +0000138#
danielk19771e4eaeb2007-05-14 14:04:59 +0000139# "SELECT DISTINCT", "SELECT ALL" or "SELECT"
140#
141proc SelectKw {} {
142 set TemplateList {
143 "SELECT DISTINCT"
144 "SELECT ALL"
145 "SELECT"
146 }
147 fuzz $TemplateList
148}
149
150# Return a result set for a SELECT statement.
151#
152proc ResultSet {{nRes 0} {c ""}} {
153 if {$nRes == 0} {
154 set nRes [expr {rand()*2 + 1}]
155 }
156
157 set aRes [list]
158 for {set ii 0} {$ii < $nRes} {incr ii} {
159 lappend aRes [Expr $c]
160 }
161
162 join $aRes ", "
163}
164
danielk1977def0fec2007-05-10 15:37:52 +0000165set ::SelectDepth 0
danielk19771f7c83e2007-05-11 16:58:03 +0000166set ::ColumnList [list]
danielk19771e4eaeb2007-05-14 14:04:59 +0000167proc SimpleSelect {{nRes 0}} {
danielk1977f75232f2007-05-10 17:32:48 +0000168
danielk19771e4eaeb2007-05-14 14:04:59 +0000169 set TemplateList {
170 {[SelectKw] [ResultSet $nRes]}
171 }
172
173 # The ::SelectDepth variable contains the number of ancestor SELECT
174 # statements (i.e. for a top level SELECT it is set to 0, for a
175 # sub-select 1, for a sub-select of a sub-select 2 etc.).
176 #
177 # If this is already greater than 3, do not generate a complicated
178 # SELECT statement. This tends to cause parser stack overflow (too
179 # boring to bother with).
180 #
181 if {$::SelectDepth < 4} {
182 lappend TemplateList \
183 {[SelectKw] [ResultSet $nRes $::ColumnList] FROM ([Select])} \
danielk197715d79822007-05-15 07:00:34 +0000184 {[SelectKw] [ResultSet $nRes] FROM ([Select])} \
185 {[SelectKw] [ResultSet $nRes $::ColumnList] FROM [Table]} \
danielk19771e4eaeb2007-05-14 14:04:59 +0000186 {
187 [SelectKw] [ResultSet $nRes $::ColumnList]
188 FROM ([Select])
189 GROUP BY [Expr]
190 HAVING [Expr]
191 } \
192
193 if {0 == $nRes} {
danielk197715d79822007-05-15 07:00:34 +0000194 lappend TemplateList \
195 {[SelectKw] * FROM ([Select])} \
196 {[SelectKw] * FROM [Table]} \
197 {[SelectKw] * FROM [Table] WHERE [Expr $::ColumnList]} \
danielk19771e4eaeb2007-05-14 14:04:59 +0000198 {
199 [SelectKw] *
200 FROM [Table],[Table] AS t2
201 WHERE [Expr $::ColumnList]
danielk1977fa2bb6d2007-05-14 15:49:43 +0000202 } {
203 [SelectKw] *
204 FROM [Table] LEFT OUTER JOIN [Table] AS t2
205 ON [Expr $::ColumnList]
206 WHERE [Expr $::ColumnList]
207 }
danielk1977f75232f2007-05-10 17:32:48 +0000208 }
209 }
danielk19771e4eaeb2007-05-14 14:04:59 +0000210
211 fuzz $TemplateList
212}
213
214# Return a SELECT statement.
215#
216# If boolean parameter $isExpr is set to true, make sure the
217# returned SELECT statement returns a single column of data.
218#
219proc Select {{nMulti 0}} {
220 set TemplateList {
221 {[SimpleSelect $nMulti]} {[SimpleSelect $nMulti]} {[SimpleSelect $nMulti]}
222 {[SimpleSelect $nMulti]} {[SimpleSelect $nMulti]} {[SimpleSelect $nMulti]}
223 {[SimpleSelect $nMulti]} {[SimpleSelect $nMulti]} {[SimpleSelect $nMulti]}
224 {[SimpleSelect $nMulti]} {[SimpleSelect $nMulti]} {[SimpleSelect $nMulti]}
danielk1977fa2bb6d2007-05-14 15:49:43 +0000225 {[SimpleSelect $nMulti] ORDER BY [Expr] DESC}
226 {[SimpleSelect $nMulti] ORDER BY [Expr] ASC}
227 {[SimpleSelect $nMulti] ORDER BY [Expr] ASC, [Expr] DESC}
danielk19771e4eaeb2007-05-14 14:04:59 +0000228 {[SimpleSelect $nMulti] ORDER BY [Expr] LIMIT [Expr] OFFSET [Expr]}
229 }
230
231 if {$::SelectDepth < 4} {
232 if {$nMulti == 0} {
233 set nMulti [expr {(rand()*2)+1}]
234 }
235 lappend TemplateList \
236 {[SimpleSelect $nMulti] UNION [Select $nMulti]} \
237 {[SimpleSelect $nMulti] UNION ALL [Select $nMulti]} \
238 {[SimpleSelect $nMulti] EXCEPT [Select $nMulti]} \
239 {[SimpleSelect $nMulti] INTERSECT [Select $nMulti]}
240 }
241
242 incr ::SelectDepth
danielk1977def0fec2007-05-10 15:37:52 +0000243 set res [fuzz $TemplateList]
244 incr ::SelectDepth -1
245 set res
246}
247
danielk1977bcfc4bc2007-05-11 10:10:33 +0000248# Generate and return a fuzzy INSERT statement.
249#
250proc Insert {} {
251 set TemplateList {
252 {INSERT INTO [Table] VALUES([Expr], [Expr], [Expr]);}
253 {INSERT INTO [Table] VALUES([Expr], [Expr], [Expr], [Expr]);}
254 {INSERT INTO [Table] VALUES([Expr], [Expr]);}
255 }
256 fuzz $TemplateList
257}
258
danielk19771f7c83e2007-05-11 16:58:03 +0000259proc Column {} {
260 fuzz $::ColumnList
261}
262
263# Generate and return a fuzzy UPDATE statement.
264#
265proc Update {} {
266 set TemplateList {
267 {UPDATE [Table]
268 SET [Column] = [Expr $::ColumnList]
269 WHERE [Expr $::ColumnList]}
270 }
271 fuzz $TemplateList
272}
273
274proc Delete {} {
275 set TemplateList {
276 {DELETE FROM [Table] WHERE [Expr $::ColumnList]}
277 }
278 fuzz $TemplateList
279}
280
281proc Statement {} {
282 set TemplateList {
283 {[Update]}
284 {[Insert]}
285 {[Select]}
286 {[Delete]}
287 }
288 fuzz $TemplateList
289}
290
danielk19771e4eaeb2007-05-14 14:04:59 +0000291# Return an identifier. This just chooses randomly from a fixed set
292# of strings.
293proc Identifier {} {
294 set TemplateList {
295 This just chooses randomly a fixed
danielk1977fa2bb6d2007-05-14 15:49:43 +0000296 We would also thank the developers
297 for their analysis Samba
danielk19771e4eaeb2007-05-14 14:04:59 +0000298 }
danielk19771e4eaeb2007-05-14 14:04:59 +0000299 fuzz $TemplateList
300}
301
302proc Check {} {
danielk1977fa2bb6d2007-05-14 15:49:43 +0000303 # Use a large value for $::SelectDepth, because sub-selects are
304 # not allowed in expressions used by CHECK constraints.
305 #
danielk19771e4eaeb2007-05-14 14:04:59 +0000306 set sd $::SelectDepth
307 set ::SelectDepth 500
308 set TemplateList {
309 {}
310 {CHECK ([Expr])}
311 }
312 set res [fuzz $TemplateList]
313 set ::SelectDepth $sd
314 set res
315}
316
317proc Coltype {} {
318 set TemplateList {
319 {INTEGER PRIMARY KEY}
320 {VARCHAR [Check]}
321 {PRIMARY KEY}
322 }
323 fuzz $TemplateList
324}
325
danielk197715d79822007-05-15 07:00:34 +0000326proc DropTable {} {
327 set TemplateList {
328 {DROP TABLE IF EXISTS [Identifier]}
329 }
330 fuzz $TemplateList
331}
332
333proc CreateView {} {
334 set TemplateList {
335 {CREATE VIEW [Identifier] AS [Select]}
336 }
337 fuzz $TemplateList
338}
339proc DropView {} {
340 set TemplateList {
341 {DROP VIEW IF EXISTS [Identifier]}
342 }
343 fuzz $TemplateList
344}
345
danielk19771e4eaeb2007-05-14 14:04:59 +0000346proc CreateTable {} {
347 set TemplateList {
348 {CREATE TABLE [Identifier]([Identifier] [Coltype], [Identifier] [Coltype])}
349 {CREATE TEMP TABLE [Identifier]([Identifier] [Coltype])}
350 }
351 fuzz $TemplateList
352}
353
danielk197715d79822007-05-15 07:00:34 +0000354proc CreateOrDropTableOrView {} {
355 set TemplateList {
356 {[CreateTable]}
357 {[DropTable]}
358 {[CreateView]}
359 {[DropView]}
360 }
361 fuzz $TemplateList
362}
363
danielk1977f75232f2007-05-10 17:32:48 +0000364########################################################################
365
danielk1977bcfc4bc2007-05-11 10:10:33 +0000366set ::log [open fuzzy.log w]
367
danielk19771e4eaeb2007-05-14 14:04:59 +0000368#
danielk1977bcfc4bc2007-05-11 10:10:33 +0000369# Usage: do_fuzzy_test <testname> ?<options>?
370#
371# -template
372# -errorlist
danielk19771e4eaeb2007-05-14 14:04:59 +0000373# -repeats
danielk1977bcfc4bc2007-05-11 10:10:33 +0000374#
375proc do_fuzzy_test {testname args} {
376 set ::fuzzyopts(-errorlist) [list]
danielk19771e4eaeb2007-05-14 14:04:59 +0000377 set ::fuzzyopts(-repeats) $::REPEATS
danielk1977bcfc4bc2007-05-11 10:10:33 +0000378 array set ::fuzzyopts $args
danielk1977bcfc4bc2007-05-11 10:10:33 +0000379
danielk19771e4eaeb2007-05-14 14:04:59 +0000380 lappend ::fuzzyopts(-errorlist) {parser stack overflow}
381 lappend ::fuzzyopts(-errorlist) {ORDER BY}
382 lappend ::fuzzyopts(-errorlist) {GROUP BY}
383 lappend ::fuzzyopts(-errorlist) {datatype mismatch}
384
385 for {set ii 0} {$ii < $::fuzzyopts(-repeats)} {incr ii} {
danielk1977bcfc4bc2007-05-11 10:10:33 +0000386 do_test ${testname}.$ii {
387 set ::sql [subst $::fuzzyopts(-template)]
388 puts $::log $::sql
389 flush $::log
390 set rc [catch {execsql $::sql} msg]
391 set e 1
392 if {$rc} {
393 set e 0
394 foreach error $::fuzzyopts(-errorlist) {
395 if {0 == [string first $error $msg]} {
396 set e 1
397 break
398 }
399 }
400 }
401 if {$e == 0} {
402 puts ""
403 puts $::sql
404 puts $msg
405 }
406 set e
407 } {1}
408 }
409}
410
danielk1977f75232f2007-05-10 17:32:48 +0000411#----------------------------------------------------------------
412# These tests caused errors that were first caught by the tests
413# in this file. They are still here.
danielk1977def0fec2007-05-10 15:37:52 +0000414do_test fuzz-1.1 {
415 execsql {
416 SELECT 'abc' LIKE X'ABCD';
417 }
418} {0}
419do_test fuzz-1.2 {
420 execsql {
421 SELECT 'abc' LIKE zeroblob(10);
422 }
423} {0}
424do_test fuzz-1.3 {
425 execsql {
426 SELECT zeroblob(10) LIKE 'abc';
427 }
428} {0}
429do_test fuzz-1.4 {
430 execsql {
431 SELECT (- -21) % NOT (456 LIKE zeroblob(10));
432 }
433} {0}
danielk1977f75232f2007-05-10 17:32:48 +0000434do_test fuzz-1.5 {
435 execsql {
436 SELECT (SELECT (
437 SELECT (SELECT -2147483648) FROM (SELECT 1) ORDER BY 1
438 ))
danielk1977def0fec2007-05-10 15:37:52 +0000439 }
danielk1977f75232f2007-05-10 17:32:48 +0000440} {-2147483648}
441do_test fuzz-1.6 {
442 execsql {
443 SELECT 'abc', zeroblob(1) FROM (SELECT 1) ORDER BY 1
444 }
445} [execsql {SELECT 'abc', zeroblob(1)}]
446
447do_test fuzz-1.7 {
448 execsql {
danielk1977d908f5a2007-05-11 07:08:28 +0000449 SELECT ( SELECT zeroblob(1000) FROM (
450 SELECT * FROM (SELECT 'first') ORDER BY NOT 'in')
danielk1977639f45f2007-05-10 17:38:57 +0000451 )
danielk1977f75232f2007-05-10 17:32:48 +0000452 }
danielk1977d908f5a2007-05-11 07:08:28 +0000453} [execsql {SELECT zeroblob(1000)}]
danielk1977def0fec2007-05-10 15:37:52 +0000454
danielk1977bcfc4bc2007-05-11 10:10:33 +0000455do_test fuzz-1.8 {
danielk19771f7c83e2007-05-11 16:58:03 +0000456 # Problems with opcode OP_ToText (did not account for MEM_Zero).
457 # Also MemExpandBlob() was marking expanded blobs as nul-terminated.
458 # They are not.
danielk1977bcfc4bc2007-05-11 10:10:33 +0000459 execsql {
460 SELECT CAST(zeroblob(1000) AS text);
461 }
462} {{}}
463
danielk19771f7c83e2007-05-11 16:58:03 +0000464do_test fuzz-1.9 {
465 # This was causing a NULL pointer dereference of Expr.pList.
466 execsql {
467 SELECT 1 FROM (SELECT * FROM sqlite_master WHERE random())
468 }
469} {}
470
471do_test fuzz-1.10 {
472 # Bug in calculation of Parse.ckOffset causing an assert()
473 # to fail. Probably harmless.
474 execsql {
475 SELECT coalesce(1, substr( 1, 2, length('in' IN (SELECT 1))))
476 }
477} {1}
478
danielk19771e4eaeb2007-05-14 14:04:59 +0000479do_test fuzz-1.11 {
480 # The literals (A, B, C, D) are not important, they are just used
481 # to make the EXPLAIN output easier to read.
482 #
483 # The problem here is that the EXISTS(...) expression leaves an
484 # extra value on the VDBE stack. This is confusing the parent and
485 # leads to an assert() failure when OP_Insert encounters an integer
486 # when it expects a record blob.
487 #
488 # Update: Any query with (LIMIT 0) was leaking stack.
489 #
490 execsql {
491 SELECT 'A' FROM (SELECT 'B') ORDER BY EXISTS (
492 SELECT 'C' FROM (SELECT 'D' LIMIT 0)
493 )
494 }
495} {A}
496
danielk1977fa2bb6d2007-05-14 15:49:43 +0000497do_test fuzz-1.12.1 {
498 # Create a table with a single row.
499 execsql {
500 CREATE TABLE abc(b);
501 INSERT INTO abc VALUES('ABCDE');
502 }
503
504 # The following query was crashing. The later subquery (in the FROM)
505 # clause was flattened into the parent, but the code was not repairng
506 # the "b" reference in the other sub-query. When the query was executed,
507 # that "b" refered to a non-existant vdbe table-cursor.
508 #
509 execsql {
510 SELECT 1 IN ( SELECT b UNION SELECT 1 ) FROM (SELECT b FROM abc);
511 }
512} {1}
513do_test fuzz-1.12.2 {
514 # Clean up after the previous query.
515 execsql {
516 DROP TABLE abc;
517 }
518} {}
519
danielk1977a670b222007-05-14 16:50:48 +0000520
521do_test fuzz-1.13 {
522 # The problem here was that when there were more expressions in
523 # the ORDER BY list than the result-set list. The temporary b-tree
524 # used for sorting was being misconfigured in this case.
525 #
526 execsql {
527 SELECT 'abcd' UNION SELECT 'efgh' ORDER BY 1 ASC, 1 ASC;
528 }
529} {abcd efgh}
530
danielk197715d79822007-05-15 07:00:34 +0000531do_test fuzz-1.14.1 {
532 execsql {
533 CREATE TABLE abc(a, b, c);
534 INSERT INTO abc VALUES(123, 456, 789);
535 }
536
537 # The [a] reference in the sub-select was causing a problem. Because
538 # the internal walkSelectExpr() function was not considering compound
539 # SELECT operators.
540 execsql {
541 SELECT 1 FROM abc
542 GROUP BY c HAVING EXISTS (SELECT a UNION SELECT 123);
543 }
544} {1}
545do_test fuzz-1.14.2 {
546 execsql {
547 DROP TABLE abc;
548 }
549} {}
550
danielk1977f75232f2007-05-10 17:32:48 +0000551#----------------------------------------------------------------
552# Test some fuzzily generated expressions.
553#
danielk1977bcfc4bc2007-05-11 10:10:33 +0000554do_fuzzy_test fuzz-2 -template { SELECT [Expr] }
danielk1977f75232f2007-05-10 17:32:48 +0000555
556do_test fuzz-3.1 {
557 execsql {
558 CREATE TABLE abc(a, b, c);
danielk1977bcfc4bc2007-05-11 10:10:33 +0000559 CREATE TABLE def(a, b, c);
560 CREATE TABLE ghi(a, b, c);
danielk1977f75232f2007-05-10 17:32:48 +0000561 }
562} {}
danielk1977bcfc4bc2007-05-11 10:10:33 +0000563set ::TableList [list abc def ghi]
danielk1977f75232f2007-05-10 17:32:48 +0000564
565#----------------------------------------------------------------
566# Test some fuzzily generated SELECT statements.
567#
danielk1977bcfc4bc2007-05-11 10:10:33 +0000568do_fuzzy_test fuzz-3.2 -template {[Select]}
danielk1977f75232f2007-05-10 17:32:48 +0000569
danielk1977bcfc4bc2007-05-11 10:10:33 +0000570#----------------------------------------------------------------
571# Insert a small amount of data into the database and then run
572# some more generated SELECT statements.
573#
574do_test fuzz-4.1 {
575 execsql {
576 INSERT INTO abc VALUES(1, 2, 3);
577 INSERT INTO abc VALUES(4, 5, 6);
578 INSERT INTO abc VALUES(7, 8, 9);
579 INSERT INTO def VALUES(1, 2, 3);
580 INSERT INTO def VALUES(4, 5, 6);
581 INSERT INTO def VALUES(7, 8, 9);
582 INSERT INTO ghi VALUES(1, 2, 3);
583 INSERT INTO ghi VALUES(4, 5, 6);
584 INSERT INTO ghi VALUES(7, 8, 9);
585 CREATE INDEX abc_i ON abc(a, b, c);
586 CREATE INDEX def_i ON def(c, a, b);
587 CREATE INDEX ghi_i ON ghi(b, c, a);
588 }
589} {}
590do_fuzzy_test fuzz-4.2 -template {[Select]}
591
592#----------------------------------------------------------------
593# Test some fuzzy INSERT statements:
594#
595do_test fuzz-5.1 {execsql BEGIN} {}
596do_fuzzy_test fuzz-5.2 -template {[Insert]} -errorlist table
597integrity_check fuzz-5.2.integrity
598do_test fuzz-5.3 {execsql COMMIT} {}
599integrity_check fuzz-5.4.integrity
600
danielk19771f7c83e2007-05-11 16:58:03 +0000601#----------------------------------------------------------------
danielk19771e4eaeb2007-05-14 14:04:59 +0000602# Now that there is data in the database, run some more SELECT
danielk19771f7c83e2007-05-11 16:58:03 +0000603# statements
604#
605set ::ColumnList [list a b c]
606set E {{no such col} {ambiguous column name}}
607do_fuzzy_test fuzz-6.1 -template {[Select]} -errorlist $E
608
609#----------------------------------------------------------------
610# Run some SELECTs, INSERTs, UPDATEs and DELETEs in a transaction.
611#
612set E {{no such col} {ambiguous column name} {table}}
613do_test fuzz-7.1 {execsql BEGIN} {}
614do_fuzzy_test fuzz-7.2 -template {[Statement]} -errorlist $E
615integrity_check fuzz-7.3.integrity
616do_test fuzz-7.4 {execsql COMMIT} {}
617integrity_check fuzz-7.5.integrity
danielk1977bcfc4bc2007-05-11 10:10:33 +0000618
danielk19771e4eaeb2007-05-14 14:04:59 +0000619#----------------------------------------------------------------
danielk197715d79822007-05-15 07:00:34 +0000620# Many CREATE and DROP TABLE statements:
danielk19771e4eaeb2007-05-14 14:04:59 +0000621#
danielk197715d79822007-05-15 07:00:34 +0000622set E [list table duplicate {no such col} {ambiguous column name}]
623do_fuzzy_test fuzz-8.1 -template {[CreateOrDropTableOrView]} -errorlist $E
danielk19771e4eaeb2007-05-14 14:04:59 +0000624
danielk1977bcfc4bc2007-05-11 10:10:33 +0000625close $::log
danielk1977def0fec2007-05-10 15:37:52 +0000626finish_test