From bcfc4bc76996d6be3822f06295f639a9ad177152 Mon Sep 17 00:00:00 2001 From: danielk1977 Date: Fri, 11 May 2007 10:10:33 +0000 Subject: [PATCH] Expand the expressions tested by fuzz.test. Fix for (CAST zeroblob() AS text). (CVS 3983) FossilOrigin-Name: 4e1bb41f302c13095aa9c638e59ae11417f49682 --- manifest | 16 ++-- manifest.uuid | 2 +- src/vdbe.c | 3 +- src/vdbemem.c | 4 +- test/fuzz.test | 195 ++++++++++++++++++++++++++++++++++++------------- 5 files changed, 159 insertions(+), 61 deletions(-) diff --git a/manifest b/manifest index ab2aa5b3cd..cc62788805 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sproblem\swith\sinserting\szeroblob()\sinto\san\sindexed\scolumn.\s(CVS\s3982) -D 2007-05-11T07:08:28 +C Expand\sthe\sexpressions\stested\sby\sfuzz.test.\sFix\sfor\s(CAST\szeroblob()\sAS\stext).\s(CVS\s3983) +D 2007-05-11T10:10:33 F Makefile.in 87b200ad9970907f76df734d29dff3d294c10935 F Makefile.linux-gcc 2d8574d1ba75f129aba2019f0b959db380a90935 F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028 @@ -132,14 +132,14 @@ F src/update.c 3359041db390a8f856d67272f299600e2104f350 F src/utf.c be7c64eed83fa3c01e0c42905e1c311dcd1be704 F src/util.c 4f6bbcec2b2b1884d652b82c9f8949ede4618d68 F src/vacuum.c 8bd895d29e7074e78d4e80f948e35ddc9cf2beef -F src/vdbe.c d1be8d8605608b6d7d925d40e1eb96e30d646fbc +F src/vdbe.c 8dcd02c2ee383db5bd09488436322e0fee1b78dd F src/vdbe.h 001c5b257567c1d3de7feb2203aac71d0d7b16a3 F src/vdbeInt.h bddb7931fc1216fda6f6720e18d2a9b1e0f8fc96 F src/vdbeapi.c 3ca7808c67a10b5c20150108b431d520d141e93e F src/vdbeaux.c 62011e2ccf5fa9b3dcc7fa6ff5f0e0638d324a70 F src/vdbeblob.c 96f3572fdc45eda5be06e6372b612bc30742d9f0 F src/vdbefifo.c 3ca8049c561d5d67cbcb94dc909ae9bb68c0bf8f -F src/vdbemem.c 0fb40f9255ebaa53af0281a6df2bcf5001313081 +F src/vdbemem.c 01237a4844106b9da838fc313bf1f86ddc6b0679 F src/vtab.c c5ebebf615b2f29499fbe97a584c4bb342632aa0 F src/where.c f3920748cc650fc25ac916215500bdb90dee568e F tclinstaller.tcl 4356d9d94d2b5ed5e68f9f0c80c4df3048dd7617 @@ -248,7 +248,7 @@ F test/fts2l.test 4c53c89ce3919003765ff4fd8d98ecf724d97dd3 F test/fts2m.test 4b30142ead6f3ed076e880a2a464064c5ad58c51 F test/fts2n.test a70357e72742681eaebfdbe9007b87ff3b771638 F test/func.test bf30bac1c5ce10448ab739994268cf18f8b3fa30 -F test/fuzz.test 1015e6a1452e14d36797977923593a938ba35d2f +F test/fuzz.test e939852bfd1d2db7264d6a55ed9b17834a535728 F test/fuzz2.test fdbea571808441c12c91e9cd038eb77b4692d42b F test/hook.test 7e7645fd9a033f79cce8fdff151e32715e7ec50a F test/icu.test e6bfae7f625c88fd14df6f540fe835bdfc1e4329 @@ -488,7 +488,7 @@ F www/tclsqlite.tcl bb0d1357328a42b1993d78573e587c6dcbc964b9 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0 F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5 -P d12a8924c6083cdff14990b4fd036ca386c2e34a -R 680b3290f2d024e3ae05a79ad5b14302 +P ccef5d2daaa5a88dd3f23666f022296ef42f9d73 +R af6f63d05d6d29341c60b7b7ec2a00e4 U danielk1977 -Z 9cd69253fcac83ce88c7739ef57267d1 +Z 67a8793031136a10487c9d10c7303799 diff --git a/manifest.uuid b/manifest.uuid index a904b22361..67ef151dd1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ccef5d2daaa5a88dd3f23666f022296ef42f9d73 \ No newline at end of file +4e1bb41f302c13095aa9c638e59ae11417f49682 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index ef474365a8..3171a10f18 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -43,7 +43,7 @@ ** in this file for details. If in doubt, do not deviate from existing ** commenting and indentation practices when changing or adding code. ** -** $Id: vdbe.c,v 1.616 2007/05/11 07:08:28 danielk1977 Exp $ +** $Id: vdbe.c,v 1.617 2007/05/11 10:10:33 danielk1977 Exp $ */ #include "sqliteInt.h" #include "os.h" @@ -1470,6 +1470,7 @@ case OP_ToText: { /* same as TK_TO_TEXT, no-push */ assert( MEM_Str==(MEM_Blob>>3) ); pTos->flags |= (pTos->flags&MEM_Blob)>>3; applyAffinity(pTos, SQLITE_AFF_TEXT, encoding); + rc = sqlite3VdbeMemExpandBlob(pTos); assert( pTos->flags & MEM_Str ); pTos->flags &= ~(MEM_Int|MEM_Real|MEM_Blob); break; diff --git a/src/vdbemem.c b/src/vdbemem.c index 259ef126b2..668eb2b546 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -102,8 +102,8 @@ int sqlite3VdbeMemExpandBlob(Mem *pMem){ pMem->z = pNew; pMem->n += pMem->u.i; pMem->u.i = 0; - pMem->flags &= ~(MEM_Zero|MEM_Static|MEM_Ephem|MEM_Short); - pMem->flags |= (MEM_Term|MEM_Dyn); + pMem->flags &= ~(MEM_Zero|MEM_Static|MEM_Ephem|MEM_Short|MEM_Term); + pMem->flags |= MEM_Dyn; } return SQLITE_OK; } diff --git a/test/fuzz.test b/test/fuzz.test index 4cc9620971..b4e27b2faf 100644 --- a/test/fuzz.test +++ b/test/fuzz.test @@ -13,7 +13,7 @@ # (a.k.a. "fuzz") and sending it into the parser to try to generate # errors. # -# $Id: fuzz.test,v 1.5 2007/05/11 07:08:29 danielk1977 Exp $ +# $Id: fuzz.test,v 1.6 2007/05/11 10:10:33 danielk1977 Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl @@ -21,9 +21,20 @@ source $testdir/tester.tcl proc fuzz {TemplateList} { set n [llength $TemplateList] set i [expr {int(rand()*$n)}] - return [subst -novar [lindex $TemplateList $i]] + return [uplevel 1 subst -novar [list [lindex $TemplateList $i]]] } +# Fuzzy generation primitives: +# +# Literal +# UnaryOp +# BinaryOp +# Expr +# Table +# Select +# Insert +# + # Returns a string representing an SQL literal. # proc Literal {} { @@ -39,55 +50,83 @@ proc Literal {} { fuzz $TemplateList } +# Returns a string containing an SQL unary operator (e.g. "+" or "NOT"). +# proc UnaryOp {} { - set TemplateList {+ - NOT} + set TemplateList {+ - NOT ~} fuzz $TemplateList } +# Returns a string containing an SQL binary operator (e.g. "*" or "/"). +# proc BinaryOp {} { - set TemplateList {+ - % * / AND OR LIKE GLOB} + set TemplateList { + || * / % + - << >> & | < <= > >= = == != <> AND OR + LIKE GLOB {NOT LIKE} + } fuzz $TemplateList } +# Return the complete text of an SQL expression. +# set ::ExprDepth 0 -proc Expr {} { +proc Expr { {c {}} } { incr ::ExprDepth - set TemplateList {[Literal]} - if {$::ExprDepth < 100} { + set TemplateList [concat $c {[Literal]}] + if {$::ExprDepth < 25} { lappend TemplateList \ - {[Expr] [BinaryOp] [Expr]} \ - {[UnaryOp] [Expr]} + {[Expr $c] [BinaryOp] [Expr $c]} \ + {[UnaryOp] [Expr $c]} \ + {[Expr $c] ISNULL} \ + {[Expr $c] NOTNULL} \ + {CAST([Expr $c] AS blob)} \ + {CAST([Expr $c] AS text)} \ + {CAST([Expr $c] AS integer)} \ + {CAST([Expr $c] AS real)} \ + {CASE WHEN [Expr $c] THEN [Expr $c] ELSE [Expr $c] END} \ + {[Literal]} {[Literal]} {[Literal]} } if {$::SelectDepth < 10} { - lappend TemplateList {([Select 1])} + lappend TemplateList \ + {([Select 1])} \ + {[Expr $c] IN ([Select 1])} \ + {[Expr $c] NOT IN ([Select 1])} \ + {EXISTS ([Select 1])} \ } set res [fuzz $TemplateList] incr ::ExprDepth -1 return $res } +# Return a valid table name. +# set ::TableList [list] proc Table {} { set TemplateList [concat sqlite_master $::TableList] fuzz $TemplateList } +# Return a SELECT statement. +# set ::SelectDepth 0 proc Select {{isExpr 0}} { incr ::SelectDepth set TemplateList { {SELECT [Expr]} + {SELECT [Literal]} } if {$::SelectDepth < 5} { lappend TemplateList \ {SELECT [Expr] FROM ([Select])} \ - {SELECT [Expr] FROM [Table]} + {SELECT [Expr] FROM [Table]} \ if {0 == $isExpr} { lappend TemplateList \ {SELECT [Expr], [Expr] FROM ([Select]) ORDER BY [Expr]} \ {SELECT * FROM ([Select]) ORDER BY [Expr]} \ + {SELECT * FROM [Table]} \ + {SELECT * FROM [Table] WHERE [Expr]} \ } } set res [fuzz $TemplateList] @@ -95,8 +134,58 @@ proc Select {{isExpr 0}} { set res } +# Generate and return a fuzzy INSERT statement. +# +proc Insert {} { + set TemplateList { + {INSERT INTO [Table] VALUES([Expr], [Expr], [Expr]);} + {INSERT INTO [Table] VALUES([Expr], [Expr], [Expr], [Expr]);} + {INSERT INTO [Table] VALUES([Expr], [Expr]);} + } + fuzz $TemplateList +} + ######################################################################## +set ::log [open fuzzy.log w] + +# +# Usage: do_fuzzy_test ?? +# +# -template +# -errorlist +# +proc do_fuzzy_test {testname args} { + set ::fuzzyopts(-errorlist) [list] + array set ::fuzzyopts $args + lappend ::fuzzyopts(-errorlist) {parser stack overflow} {ORDER BY column} + + for {set ii 0} {$ii < 2000} {incr ii} { + do_test ${testname}.$ii { + set ::sql [subst $::fuzzyopts(-template)] + puts $::log $::sql + flush $::log + set rc [catch {execsql $::sql} msg] + set e 1 + if {$rc} { + set e 0 + foreach error $::fuzzyopts(-errorlist) { + if {0 == [string first $error $msg]} { + set e 1 + break + } + } + } + if {$e == 0} { + puts "" + puts $::sql + puts $msg + } + set e + } {1} + } +} + #---------------------------------------------------------------- # These tests caused errors that were first caught by the tests # in this file. They are still here. @@ -141,56 +230,64 @@ do_test fuzz-1.7 { } } [execsql {SELECT zeroblob(1000)}] +do_test fuzz-1.8 { + execsql { + SELECT CAST(zeroblob(1000) AS text); + } +} {{}} + #---------------------------------------------------------------- # Test some fuzzily generated expressions. # -for {set ii 0} {$ii < 2000} {incr ii} { - do_test fuzz-2.1.$ii { - set ::expr [Expr] - set rc [catch {execsql "SELECT $::expr"} msg] - set e [expr { - $rc == 0 || - $msg eq "parser stack overflow" || - 0 == [string first "ORDER BY column number" $msg] - }] - if {$e == 0} { - puts "" - puts "SELECT $::expr" - puts $msg - } - set e - } {1} -} +do_fuzzy_test fuzz-2 -template { SELECT [Expr] } do_test fuzz-3.1 { execsql { CREATE TABLE abc(a, b, c); - CREATE TABLE def(d, e, f); - CREATE TABLE ghi(g, h, i); + CREATE TABLE def(a, b, c); + CREATE TABLE ghi(a, b, c); } } {} -set ::TableList [list abc def ghi] +set ::TableList [list abc def ghi] +set ::ColumnList [list a b c] #---------------------------------------------------------------- # Test some fuzzily generated SELECT statements. # -for {set ii 0} {$ii < 2000} {incr ii} { - do_test fuzz-2.2.$ii { - set ::select [Select] - set rc [catch {execsql $::select} msg] - set e [expr {$rc == 0 || $msg eq "parser stack overflow"}] - set e [expr { - $rc == 0 || - $msg eq "parser stack overflow" || - 0 == [string first "ORDER BY column number" $msg] - }] - if {$e == 0} { - puts "" - puts $::select - puts $msg - } - set e - } {1} -} +do_fuzzy_test fuzz-3.2 -template {[Select]} +#---------------------------------------------------------------- +# Insert a small amount of data into the database and then run +# some more generated SELECT statements. +# +do_test fuzz-4.1 { + execsql { + INSERT INTO abc VALUES(1, 2, 3); + INSERT INTO abc VALUES(4, 5, 6); + INSERT INTO abc VALUES(7, 8, 9); + INSERT INTO def VALUES(1, 2, 3); + INSERT INTO def VALUES(4, 5, 6); + INSERT INTO def VALUES(7, 8, 9); + INSERT INTO ghi VALUES(1, 2, 3); + INSERT INTO ghi VALUES(4, 5, 6); + INSERT INTO ghi VALUES(7, 8, 9); + CREATE INDEX abc_i ON abc(a, b, c); + CREATE INDEX def_i ON def(c, a, b); + CREATE INDEX ghi_i ON ghi(b, c, a); + } +} {} +do_fuzzy_test fuzz-4.2 -template {[Select]} + +#---------------------------------------------------------------- +# Test some fuzzy INSERT statements: +# +do_test fuzz-5.1 {execsql BEGIN} {} +do_fuzzy_test fuzz-5.2 -template {[Insert]} -errorlist table +integrity_check fuzz-5.2.integrity +do_test fuzz-5.3 {execsql COMMIT} {} +integrity_check fuzz-5.4.integrity + +do_fuzzy_test fuzz-6.1 -template {[Select]} + +close $::log finish_test