Expand the expressions tested by fuzz.test. Fix for (CAST zeroblob() AS text). (CVS 3983)

FossilOrigin-Name: 4e1bb41f302c13095aa9c638e59ae11417f49682
This commit is contained in:
danielk1977 2007-05-11 10:10:33 +00:00
parent d908f5ab7f
commit bcfc4bc769
5 changed files with 159 additions and 61 deletions

View File

@ -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

View File

@ -1 +1 @@
ccef5d2daaa5a88dd3f23666f022296ef42f9d73
4e1bb41f302c13095aa9c638e59ae11417f49682

View File

@ -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;

View File

@ -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;
}

View File

@ -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 <testname> ?<options>?
#
# -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