15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# 2007 May 10 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# The author disclaims copyright to this source code. In place of 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# a legal notice, here is a blessing: 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# May you do good and not evil. 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# May you find forgiveness for yourself and forgive others. 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# May you share freely, never taking more than you give. 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#*********************************************************************** 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# $Id: fuzz_common.tcl,v 1.2 2009/01/05 19:36:30 drh Exp $ 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)proc fuzz {TemplateList} { 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) set n [llength $TemplateList] 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) set i [expr {int(rand()*$n)}] 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) set r [uplevel 1 subst -novar [list [lindex $TemplateList $i]]] 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string map {"\n" " "} $r 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Fuzzy generation primitives: 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Literal 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# UnaryOp 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# BinaryOp 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Expr 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Table 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Select 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Insert 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Returns a string representing an SQL literal. 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)proc Literal {} { 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) set TemplateList { 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 456 0 -456 1 -1 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2147483648 2147483647 2147483649 -2147483647 -2147483648 -2147483649 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 'The' 'first' 'experiments' 'in' 'hardware' 'fault' 'injection' 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) zeroblob(1000) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 56.1 -56.1 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 123456789.1234567899 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fuzz $TemplateList 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Returns a string containing an SQL unary operator (e.g. "+" or "NOT"). 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)proc UnaryOp {} { 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) set TemplateList {+ - NOT ~} 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fuzz $TemplateList 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Returns a string containing an SQL binary operator (e.g. "*" or "/"). 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)proc BinaryOp {} { 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) set TemplateList { 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) || * / % + - << >> & | < <= > >= = == != <> AND OR 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LIKE GLOB {NOT LIKE} 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fuzz $TemplateList 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Return the complete text of an SQL expression. 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)set ::ExprDepth 0 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)proc Expr { {c {}} } { 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) incr ::ExprDepth 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) set TemplateList [concat $c $c $c {[Literal]}] 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if {$::ExprDepth < 3} { 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lappend TemplateList \ 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {[Expr $c] [BinaryOp] [Expr $c]} \ 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {[UnaryOp] [Expr $c]} \ 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {[Expr $c] ISNULL} \ 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {[Expr $c] NOTNULL} \ 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {CAST([Expr $c] AS blob)} \ 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {CAST([Expr $c] AS text)} \ 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {CAST([Expr $c] AS integer)} \ 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {CAST([Expr $c] AS real)} \ 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {abs([Expr])} \ 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {coalesce([Expr], [Expr])} \ 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {hex([Expr])} \ 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {length([Expr])} \ 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {lower([Expr])} \ 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {upper([Expr])} \ 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {quote([Expr])} \ 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {random()} \ 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {randomblob(min(max([Expr],1), 500))} \ 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {typeof([Expr])} \ 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {substr([Expr],[Expr],[Expr])} \ 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {CASE WHEN [Expr $c] THEN [Expr $c] ELSE [Expr $c] END} \ 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {[Literal]} {[Literal]} {[Literal]} \ 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {[Literal]} {[Literal]} {[Literal]} \ 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {[Literal]} {[Literal]} {[Literal]} \ 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {[Literal]} {[Literal]} {[Literal]} 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if {$::SelectDepth < 4} { 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lappend TemplateList \ 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {([Select 1])} \ 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {[Expr $c] IN ([Select 1])} \ 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {[Expr $c] NOT IN ([Select 1])} \ 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {EXISTS ([Select 1])} \ 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) set res [fuzz $TemplateList] 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) incr ::ExprDepth -1 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return $res 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Return a valid table name. 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)set ::TableList [list] 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)proc Table {} { 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) set TemplateList [concat sqlite_master $::TableList] 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fuzz $TemplateList 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Return one of: 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# "SELECT DISTINCT", "SELECT ALL" or "SELECT" 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)proc SelectKw {} { 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) set TemplateList { 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "SELECT DISTINCT" 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "SELECT ALL" 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "SELECT" 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fuzz $TemplateList 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Return a result set for a SELECT statement. 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)proc ResultSet {{nRes 0} {c ""}} { 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if {$nRes == 0} { 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) set nRes [expr {rand()*2 + 1}] 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) set aRes [list] 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for {set ii 0} {$ii < $nRes} {incr ii} { 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lappend aRes [Expr $c] 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) join $aRes ", " 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)set ::SelectDepth 0 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)set ::ColumnList [list] 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)proc SimpleSelect {{nRes 0}} { 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) set TemplateList { 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {[SelectKw] [ResultSet $nRes]} 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # The ::SelectDepth variable contains the number of ancestor SELECT 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # statements (i.e. for a top level SELECT it is set to 0, for a 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # sub-select 1, for a sub-select of a sub-select 2 etc.). 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # If this is already greater than 3, do not generate a complicated 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # SELECT statement. This tends to cause parser stack overflow (too 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # boring to bother with). 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if {$::SelectDepth < 4} { 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lappend TemplateList \ 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {[SelectKw] [ResultSet $nRes $::ColumnList] FROM ([Select])} \ 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {[SelectKw] [ResultSet $nRes] FROM ([Select])} \ 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {[SelectKw] [ResultSet $nRes $::ColumnList] FROM [Table]} \ 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) [SelectKw] [ResultSet $nRes $::ColumnList] 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM ([Select]) 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GROUP BY [Expr] 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HAVING [Expr] 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } \ 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if {0 == $nRes} { 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lappend TemplateList \ 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {[SelectKw] * FROM ([Select])} \ 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {[SelectKw] * FROM [Table]} \ 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {[SelectKw] * FROM [Table] WHERE [Expr $::ColumnList]} \ 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) [SelectKw] * 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM [Table],[Table] AS t2 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WHERE [Expr $::ColumnList] 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } { 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) [SelectKw] * 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM [Table] LEFT OUTER JOIN [Table] AS t2 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ON [Expr $::ColumnList] 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WHERE [Expr $::ColumnList] 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fuzz $TemplateList 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Return a SELECT statement. 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# If boolean parameter $isExpr is set to true, make sure the 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# returned SELECT statement returns a single column of data. 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)proc Select {{nMulti 0}} { 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) set TemplateList { 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {[SimpleSelect $nMulti]} {[SimpleSelect $nMulti]} {[SimpleSelect $nMulti]} 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {[SimpleSelect $nMulti]} {[SimpleSelect $nMulti]} {[SimpleSelect $nMulti]} 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {[SimpleSelect $nMulti]} {[SimpleSelect $nMulti]} {[SimpleSelect $nMulti]} 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {[SimpleSelect $nMulti]} {[SimpleSelect $nMulti]} {[SimpleSelect $nMulti]} 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {[SimpleSelect $nMulti] ORDER BY [Expr] DESC} 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {[SimpleSelect $nMulti] ORDER BY [Expr] ASC} 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {[SimpleSelect $nMulti] ORDER BY [Expr] ASC, [Expr] DESC} 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {[SimpleSelect $nMulti] ORDER BY [Expr] LIMIT [Expr] OFFSET [Expr]} 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if {$::SelectDepth < 4} { 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if {$nMulti == 0} { 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) set nMulti [expr {(rand()*2)+1}] 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lappend TemplateList \ 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {[SimpleSelect $nMulti] UNION [Select $nMulti]} \ 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {[SimpleSelect $nMulti] UNION ALL [Select $nMulti]} \ 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {[SimpleSelect $nMulti] EXCEPT [Select $nMulti]} \ 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {[SimpleSelect $nMulti] INTERSECT [Select $nMulti]} 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) incr ::SelectDepth 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) set res [fuzz $TemplateList] 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) incr ::SelectDepth -1 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) set res 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Generate and return a fuzzy INSERT statement. 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)proc Insert {} { 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) set TemplateList { 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {INSERT INTO [Table] VALUES([Expr], [Expr], [Expr]);} 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {INSERT INTO [Table] VALUES([Expr], [Expr], [Expr], [Expr]);} 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {INSERT INTO [Table] VALUES([Expr], [Expr]);} 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fuzz $TemplateList 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)proc Column {} { 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fuzz $::ColumnList 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Generate and return a fuzzy UPDATE statement. 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)proc Update {} { 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) set TemplateList { 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {UPDATE [Table] 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SET [Column] = [Expr $::ColumnList] 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WHERE [Expr $::ColumnList]} 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fuzz $TemplateList 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)proc Delete {} { 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) set TemplateList { 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {DELETE FROM [Table] WHERE [Expr $::ColumnList]} 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fuzz $TemplateList 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)proc Statement {} { 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) set TemplateList { 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {[Update]} 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {[Insert]} 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {[Select]} 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {[Delete]} 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fuzz $TemplateList 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Return an identifier. This just chooses randomly from a fixed set 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# of strings. 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)proc Identifier {} { 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) set TemplateList { 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) This just chooses randomly a fixed 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) We would also thank the developers 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for their analysis Samba 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fuzz $TemplateList 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)proc Check {} { 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # Use a large value for $::SelectDepth, because sub-selects are 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # not allowed in expressions used by CHECK constraints. 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) # 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) set sd $::SelectDepth 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) set ::SelectDepth 500 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) set TemplateList { 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {} 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {CHECK ([Expr])} 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) set res [fuzz $TemplateList] 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) set ::SelectDepth $sd 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) set res 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)proc Coltype {} { 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) set TemplateList { 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {INTEGER PRIMARY KEY} 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {VARCHAR [Check]} 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {PRIMARY KEY} 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fuzz $TemplateList 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)proc DropTable {} { 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) set TemplateList { 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {DROP TABLE IF EXISTS [Identifier]} 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fuzz $TemplateList 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)proc CreateView {} { 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) set TemplateList { 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {CREATE VIEW [Identifier] AS [Select]} 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fuzz $TemplateList 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)proc DropView {} { 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) set TemplateList { 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {DROP VIEW IF EXISTS [Identifier]} 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fuzz $TemplateList 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)proc CreateTable {} { 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) set TemplateList { 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {CREATE TABLE [Identifier]([Identifier] [Coltype], [Identifier] [Coltype])} 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {CREATE TEMP TABLE [Identifier]([Identifier] [Coltype])} 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fuzz $TemplateList 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)proc CreateOrDropTableOrView {} { 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) set TemplateList { 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {[CreateTable]} 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {[DropTable]} 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {[CreateView]} 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {[DropView]} 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fuzz $TemplateList 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)######################################################################## 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)set ::log [open fuzzy.log w] 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Usage: do_fuzzy_test <testname> ?<options>? 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# -template 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# -errorlist 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# -repeats 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)proc do_fuzzy_test {testname args} { 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) set ::fuzzyopts(-errorlist) [list] 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) set ::fuzzyopts(-repeats) $::REPEATS 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) array set ::fuzzyopts $args 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lappend ::fuzzyopts(-errorlist) {parser stack overflow} 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lappend ::fuzzyopts(-errorlist) {ORDER BY} 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lappend ::fuzzyopts(-errorlist) {GROUP BY} 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lappend ::fuzzyopts(-errorlist) {datatype mismatch} 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for {set ii 0} {$ii < $::fuzzyopts(-repeats)} {incr ii} { 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) do_test ${testname}.$ii { 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) set ::sql [subst $::fuzzyopts(-template)] 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) puts $::log $::sql 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) flush $::log 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) set rc [catch {execsql $::sql} msg] 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) set e 1 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if {$rc} { 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) set e 0 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) foreach error $::fuzzyopts(-errorlist) { 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if {[string first $error $msg]>=0} { 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) set e 1 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if {$e == 0} { 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) puts "" 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) puts $::sql 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) puts $msg 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) set e 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } {1} 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 392