blob: c21387bd266209ecc14fd51a193343befe40478f [file] [log] [blame]
danielk1977def0fec2007-05-10 15:37:52 +00001
2# 2001 September 15
3#
4# The author disclaims copyright to this source code. In place of
5# a legal notice, here is a blessing:
6#
7# May you do good and not evil.
8# May you find forgiveness for yourself and forgive others.
9# May you share freely, never taking more than you give.
10#
11#***********************************************************************
12# This file implements regression tests for SQLite library. The
13# focus of this file is testing the SELECT statement.
14#
danielk1977f75232f2007-05-10 17:32:48 +000015# $Id: fuzz.test,v 1.2 2007/05/10 17:32:48 danielk1977 Exp $
danielk1977def0fec2007-05-10 15:37:52 +000016
17set testdir [file dirname $argv0]
18source $testdir/tester.tcl
19
20proc fuzz {TemplateList} {
21 set n [llength $TemplateList]
22 set i [expr {int(rand()*$n)}]
23 return [subst -novar [lindex $TemplateList $i]]
24}
25
danielk1977f75232f2007-05-10 17:32:48 +000026# Returns a string representing an SQL literal.
27#
28proc Literal {} {
danielk1977def0fec2007-05-10 15:37:52 +000029 set TemplateList {
30 456 0 -456 1 -1
31 2147483648 2147483647 2147483649 -2147483647 -2147483648 -2147483649
32 'The' 'first' 'experiments' 'in' 'hardware' 'fault' 'injection'
33 zeroblob(1000)
34 NULL
35 56.1 -56.1
36 123456789.1234567899
37 }
38 fuzz $TemplateList
39}
40
41proc UnaryOp {} {
42 set TemplateList {+ - NOT}
43 fuzz $TemplateList
44}
45
46proc BinaryOp {} {
47 set TemplateList {+ - % * / AND OR LIKE GLOB}
48 fuzz $TemplateList
49}
50
51set ::ExprDepth 0
52proc Expr {} {
53 incr ::ExprDepth
54
danielk1977f75232f2007-05-10 17:32:48 +000055 set TemplateList {[Literal]}
danielk1977def0fec2007-05-10 15:37:52 +000056 if {$::ExprDepth < 100} {
57 lappend TemplateList \
58 {[Expr] [BinaryOp] [Expr]} \
danielk1977f75232f2007-05-10 17:32:48 +000059 {[UnaryOp] [Expr]}
danielk1977def0fec2007-05-10 15:37:52 +000060 }
61 if {$::SelectDepth < 10} {
danielk1977f75232f2007-05-10 17:32:48 +000062 lappend TemplateList {([Select 1])}
danielk1977def0fec2007-05-10 15:37:52 +000063 }
64 set res [fuzz $TemplateList]
65 incr ::ExprDepth -1
66 return $res
67}
68
danielk1977f75232f2007-05-10 17:32:48 +000069set ::TableList [list]
70proc Table {} {
71 set TemplateList [concat sqlite_master $::TableList]
72 fuzz $TemplateList
73}
74
danielk1977def0fec2007-05-10 15:37:52 +000075set ::SelectDepth 0
danielk1977f75232f2007-05-10 17:32:48 +000076proc Select {{isExpr 0}} {
danielk1977def0fec2007-05-10 15:37:52 +000077 incr ::SelectDepth
78 set TemplateList {
79 {SELECT [Expr]}
80 }
danielk1977f75232f2007-05-10 17:32:48 +000081 if {$::SelectDepth < 5} {
82 lappend TemplateList \
83 {SELECT [Expr] FROM ([Select])} \
84 {SELECT [Expr] FROM [Table]}
85
86 if {0 == $isExpr} {
87 lappend TemplateList \
88 {SELECT [Expr], [Expr] FROM ([Select]) ORDER BY [Expr]} \
89 {SELECT * FROM ([Select]) ORDER BY [Expr]} \
90 }
91 }
danielk1977def0fec2007-05-10 15:37:52 +000092 set res [fuzz $TemplateList]
93 incr ::SelectDepth -1
94 set res
95}
96
danielk1977f75232f2007-05-10 17:32:48 +000097########################################################################
98
99#----------------------------------------------------------------
100# These tests caused errors that were first caught by the tests
101# in this file. They are still here.
danielk1977def0fec2007-05-10 15:37:52 +0000102do_test fuzz-1.1 {
103 execsql {
104 SELECT 'abc' LIKE X'ABCD';
105 }
106} {0}
107do_test fuzz-1.2 {
108 execsql {
109 SELECT 'abc' LIKE zeroblob(10);
110 }
111} {0}
112do_test fuzz-1.3 {
113 execsql {
114 SELECT zeroblob(10) LIKE 'abc';
115 }
116} {0}
117do_test fuzz-1.4 {
118 execsql {
119 SELECT (- -21) % NOT (456 LIKE zeroblob(10));
120 }
121} {0}
danielk1977f75232f2007-05-10 17:32:48 +0000122do_test fuzz-1.5 {
123 execsql {
124 SELECT (SELECT (
125 SELECT (SELECT -2147483648) FROM (SELECT 1) ORDER BY 1
126 ))
danielk1977def0fec2007-05-10 15:37:52 +0000127 }
danielk1977f75232f2007-05-10 17:32:48 +0000128} {-2147483648}
129do_test fuzz-1.6 {
130 execsql {
131 SELECT 'abc', zeroblob(1) FROM (SELECT 1) ORDER BY 1
132 }
133} [execsql {SELECT 'abc', zeroblob(1)}]
134
135do_test fuzz-1.7 {
136 execsql {
137SELECT + (SELECT (SELECT 'fault' / + -2147483648 % - 123456789.1234567899 * (SELECT 'experiments' OR NOT 'first' / 'hardware' FROM (SELECT 2147483647, + (SELECT 'injection') FROM (SELECT 2147483649) ORDER BY + NULL AND (SELECT 'hardware') GLOB 2147483648))) FROM (SELECT * FROM (SELECT (SELECT (SELECT + (SELECT 456 * -2147483648)) LIKE (SELECT (SELECT (SELECT 'fault') - -56.1)) AND -2147483648) FROM (SELECT * FROM (SELECT 2147483648) ORDER BY (SELECT 56.1))) ORDER BY zeroblob(1))
138 }
danielk1977def0fec2007-05-10 15:37:52 +0000139} {}
140
danielk1977f75232f2007-05-10 17:32:48 +0000141#----------------------------------------------------------------
142# Test some fuzzily generated expressions.
143#
144for {set ii 0} {$ii < 2000} {incr ii} {
145 do_test fuzz-2.1.$ii {
146 set ::expr [Expr]
147 set rc [catch {execsql "SELECT $::expr"} msg]
148 set e [expr {
149 $rc == 0 ||
150 $msg eq "parser stack overflow" ||
151 0 == [string first "ORDER BY column number" $msg]
152 }]
153 if {$e == 0} {
154 puts ""
155 puts "SELECT $::expr"
156 puts $msg
157 }
158 set e
159 } {1}
160}
161
162do_test fuzz-3.1 {
163 execsql {
164 CREATE TABLE abc(a, b, c);
165 CREATE TABLE def(d, e, f);
166 CREATE TABLE ghi(g, h, i);
167 }
168} {}
169set ::TableList [list abc def ghi]
170
171#----------------------------------------------------------------
172# Test some fuzzily generated SELECT statements.
173#
174for {set ii 0} {$ii < 2000} {incr ii} {
175 do_test fuzz-2.2.$ii {
176 set ::select [Select]
177 set rc [catch {execsql $::select} msg]
178 set e [expr {$rc == 0 || $msg eq "parser stack overflow"}]
179 set e [expr {
180 $rc == 0 ||
181 $msg eq "parser stack overflow" ||
182 0 == [string first "ORDER BY column number" $msg]
183 }]
184 if {$e == 0} {
185 puts ""
186 puts $::select
187 puts $msg
188 }
189 set e
190 } {1}
191}
192
danielk1977def0fec2007-05-10 15:37:52 +0000193finish_test
194