blob: a9792827c73deef60a6c6540085a9d6697819982 [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#
danielk1977639f45f2007-05-10 17:38:57 +000015# $Id: fuzz.test,v 1.3 2007/05/10 17:38:57 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 {
danielk1977639f45f2007-05-10 17:38:57 +0000137 SELECT (
138 SELECT zeroblob(1000) FROM (
139 SELECT * FROM (SELECT 'first') ORDER BY NOT 'in'
140 )
141 )
danielk1977f75232f2007-05-10 17:32:48 +0000142 }
danielk1977def0fec2007-05-10 15:37:52 +0000143} {}
144
danielk1977f75232f2007-05-10 17:32:48 +0000145#----------------------------------------------------------------
146# Test some fuzzily generated expressions.
147#
148for {set ii 0} {$ii < 2000} {incr ii} {
149 do_test fuzz-2.1.$ii {
150 set ::expr [Expr]
151 set rc [catch {execsql "SELECT $::expr"} msg]
152 set e [expr {
153 $rc == 0 ||
154 $msg eq "parser stack overflow" ||
155 0 == [string first "ORDER BY column number" $msg]
156 }]
157 if {$e == 0} {
158 puts ""
159 puts "SELECT $::expr"
160 puts $msg
161 }
162 set e
163 } {1}
164}
165
166do_test fuzz-3.1 {
167 execsql {
168 CREATE TABLE abc(a, b, c);
169 CREATE TABLE def(d, e, f);
170 CREATE TABLE ghi(g, h, i);
171 }
172} {}
173set ::TableList [list abc def ghi]
174
175#----------------------------------------------------------------
176# Test some fuzzily generated SELECT statements.
177#
178for {set ii 0} {$ii < 2000} {incr ii} {
179 do_test fuzz-2.2.$ii {
180 set ::select [Select]
181 set rc [catch {execsql $::select} msg]
182 set e [expr {$rc == 0 || $msg eq "parser stack overflow"}]
183 set e [expr {
184 $rc == 0 ||
185 $msg eq "parser stack overflow" ||
186 0 == [string first "ORDER BY column number" $msg]
187 }]
188 if {$e == 0} {
189 puts ""
190 puts $::select
191 puts $msg
192 }
193 set e
194 } {1}
195}
196
danielk1977def0fec2007-05-10 15:37:52 +0000197finish_test
198