/ Check-in [4e1bb41f]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Expand the expressions tested by fuzz.test. Fix for (CAST zeroblob() AS text). (CVS 3983)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 4e1bb41f302c13095aa9c638e59ae11417f49682
User & Date: danielk1977 2007-05-11 10:10:33
Context
2007-05-11
12:30
Avoid multiple storage class specifiers ("static extern") in the amalagmation. (CVS 3984) check-in: 2f70159b user: drh tags: trunk
10:10
Expand the expressions tested by fuzz.test. Fix for (CAST zeroblob() AS text). (CVS 3983) check-in: 4e1bb41f user: danielk1977 tags: trunk
07:08
Fix a problem with inserting zeroblob() into an indexed column. (CVS 3982) check-in: ccef5d2d user: danielk1977 tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/vdbe.c.

    39     39   **
    40     40   ** Various scripts scan this source file in order to generate HTML
    41     41   ** documentation, headers files, or other derived files.  The formatting
    42     42   ** of the code in this file is, therefore, important.  See other comments
    43     43   ** in this file for details.  If in doubt, do not deviate from existing
    44     44   ** commenting and indentation practices when changing or adding code.
    45     45   **
    46         -** $Id: vdbe.c,v 1.616 2007/05/11 07:08:28 danielk1977 Exp $
           46  +** $Id: vdbe.c,v 1.617 2007/05/11 10:10:33 danielk1977 Exp $
    47     47   */
    48     48   #include "sqliteInt.h"
    49     49   #include "os.h"
    50     50   #include <ctype.h>
    51     51   #include <math.h>
    52     52   #include "vdbeInt.h"
    53     53   
................................................................................
  1466   1466   */
  1467   1467   case OP_ToText: {                  /* same as TK_TO_TEXT, no-push */
  1468   1468     assert( pTos>=p->aStack );
  1469   1469     if( pTos->flags & MEM_Null ) break;
  1470   1470     assert( MEM_Str==(MEM_Blob>>3) );
  1471   1471     pTos->flags |= (pTos->flags&MEM_Blob)>>3;
  1472   1472     applyAffinity(pTos, SQLITE_AFF_TEXT, encoding);
         1473  +  rc = sqlite3VdbeMemExpandBlob(pTos);
  1473   1474     assert( pTos->flags & MEM_Str );
  1474   1475     pTos->flags &= ~(MEM_Int|MEM_Real|MEM_Blob);
  1475   1476     break;
  1476   1477   }
  1477   1478   
  1478   1479   /* Opcode: ToBlob * * *
  1479   1480   **

Changes to src/vdbemem.c.

    98     98       }
    99     99       memcpy(pNew, pMem->z, pMem->n);
   100    100       memset(&pNew[pMem->n], 0, pMem->u.i);
   101    101       sqlite3VdbeMemRelease(pMem);
   102    102       pMem->z = pNew;
   103    103       pMem->n += pMem->u.i;
   104    104       pMem->u.i = 0;
   105         -    pMem->flags &= ~(MEM_Zero|MEM_Static|MEM_Ephem|MEM_Short);
   106         -    pMem->flags |= (MEM_Term|MEM_Dyn);
          105  +    pMem->flags &= ~(MEM_Zero|MEM_Static|MEM_Ephem|MEM_Short|MEM_Term);
          106  +    pMem->flags |= MEM_Dyn;
   107    107     }
   108    108     return SQLITE_OK;
   109    109   }
   110    110   
   111    111   
   112    112   /*
   113    113   ** Make the given Mem object either MEM_Short or MEM_Dyn so that bytes

Changes to test/fuzz.test.

     9      9   #
    10     10   #***********************************************************************
    11     11   # This file implements regression tests for SQLite library.  The
    12     12   # focus of this file is generating semi-random strings of SQL
    13     13   # (a.k.a. "fuzz") and sending it into the parser to try to generate
    14     14   # errors.
    15     15   #
    16         -# $Id: fuzz.test,v 1.5 2007/05/11 07:08:29 danielk1977 Exp $
           16  +# $Id: fuzz.test,v 1.6 2007/05/11 10:10:33 danielk1977 Exp $
    17     17   
    18     18   set testdir [file dirname $argv0]
    19     19   source $testdir/tester.tcl
    20     20   
    21     21   proc fuzz {TemplateList} {
    22     22     set n [llength $TemplateList]
    23     23     set i [expr {int(rand()*$n)}]
    24         -  return [subst -novar [lindex $TemplateList $i]]
           24  +  return [uplevel 1 subst -novar [list [lindex $TemplateList $i]]]
    25     25   }
           26  +
           27  +# Fuzzy generation primitives:
           28  +#
           29  +#     Literal
           30  +#     UnaryOp
           31  +#     BinaryOp
           32  +#     Expr
           33  +#     Table
           34  +#     Select
           35  +#     Insert
           36  +#
    26     37   
    27     38   # Returns a string representing an SQL literal.
    28     39   #
    29     40   proc Literal {} {
    30     41     set TemplateList {
    31     42       456 0 -456 1 -1 
    32     43       2147483648 2147483647 2147483649 -2147483647 -2147483648 -2147483649
................................................................................
    35     46       NULL
    36     47       56.1 -56.1
    37     48       123456789.1234567899
    38     49     }
    39     50     fuzz $TemplateList
    40     51   }
    41     52   
           53  +# Returns a string containing an SQL unary operator (e.g. "+" or "NOT").
           54  +#
    42     55   proc UnaryOp {} {
    43         -  set TemplateList {+ - NOT}
           56  +  set TemplateList {+ - NOT ~}
    44     57     fuzz $TemplateList
    45     58   }
    46     59   
           60  +# Returns a string containing an SQL binary operator (e.g. "*" or "/").
           61  +#
    47     62   proc BinaryOp {} {
    48         -  set TemplateList {+ - % * / AND OR LIKE GLOB}
           63  +  set TemplateList {
           64  +    || * / % + - << >> & | < <= > >= = == != <> AND OR
           65  +    LIKE GLOB {NOT LIKE}
           66  +  }
    49     67     fuzz $TemplateList
    50     68   }
    51     69   
           70  +# Return the complete text of an SQL expression.
           71  +#
    52     72   set ::ExprDepth 0
    53         -proc Expr {} {
           73  +proc Expr { {c {}} } {
    54     74     incr ::ExprDepth
    55     75   
    56         -  set TemplateList {[Literal]}
    57         -  if {$::ExprDepth < 100} {
           76  +  set TemplateList [concat $c {[Literal]}]
           77  +  if {$::ExprDepth < 25} {
    58     78       lappend TemplateList \
    59         -      {[Expr] [BinaryOp] [Expr]}   \
    60         -      {[UnaryOp] [Expr]}
           79  +      {[Expr $c] [BinaryOp] [Expr $c]} \
           80  +      {[UnaryOp] [Expr $c]}            \
           81  +      {[Expr $c] ISNULL}               \
           82  +      {[Expr $c] NOTNULL}              \
           83  +      {CAST([Expr $c] AS blob)}        \
           84  +      {CAST([Expr $c] AS text)}        \
           85  +      {CAST([Expr $c] AS integer)}     \
           86  +      {CAST([Expr $c] AS real)}        \
           87  +      {CASE WHEN [Expr $c] THEN [Expr $c] ELSE [Expr $c] END}       \
           88  +      {[Literal]} {[Literal]} {[Literal]}
    61     89     }
    62     90     if {$::SelectDepth < 10} {
    63         -    lappend TemplateList {([Select 1])}
           91  +    lappend TemplateList \
           92  +      {([Select 1])}                       \
           93  +      {[Expr $c] IN ([Select 1])}          \
           94  +      {[Expr $c] NOT IN ([Select 1])}      \
           95  +      {EXISTS ([Select 1])}                \
    64     96     } 
    65     97     set res [fuzz $TemplateList]
    66     98     incr ::ExprDepth -1
    67     99     return $res
    68    100   }
    69    101   
          102  +# Return a valid table name.
          103  +#
    70    104   set ::TableList [list]
    71    105   proc Table {} {
    72    106     set TemplateList [concat sqlite_master $::TableList]
    73    107     fuzz $TemplateList
    74    108   }
    75    109   
          110  +# Return a SELECT statement.
          111  +#
    76    112   set ::SelectDepth 0
    77    113   proc Select {{isExpr 0}} {
    78    114     incr ::SelectDepth
    79    115     set TemplateList {
    80    116         {SELECT [Expr]}
          117  +      {SELECT [Literal]}
    81    118     }
    82    119     if {$::SelectDepth < 5} {
    83    120       lappend TemplateList \
    84    121           {SELECT [Expr] FROM ([Select])}                \
    85         -        {SELECT [Expr] FROM [Table]}                  
          122  +        {SELECT [Expr] FROM [Table]}                   \
    86    123   
    87    124       if {0 == $isExpr} {
    88    125         lappend TemplateList                                         \
    89    126             {SELECT [Expr], [Expr] FROM ([Select]) ORDER BY [Expr]}  \
    90    127             {SELECT * FROM ([Select]) ORDER BY [Expr]}               \
          128  +          {SELECT * FROM [Table]}                                  \
          129  +          {SELECT * FROM [Table] WHERE [Expr]}                     \
    91    130       }
    92    131     } 
    93    132     set res [fuzz $TemplateList]
    94    133     incr ::SelectDepth -1
    95    134     set res
    96    135   }
          136  +
          137  +# Generate and return a fuzzy INSERT statement.
          138  +#
          139  +proc Insert {} {
          140  +  set TemplateList {
          141  +      {INSERT INTO [Table] VALUES([Expr], [Expr], [Expr]);}
          142  +      {INSERT INTO [Table] VALUES([Expr], [Expr], [Expr], [Expr]);}
          143  +      {INSERT INTO [Table] VALUES([Expr], [Expr]);}
          144  +  }
          145  +  fuzz $TemplateList
          146  +}
    97    147   
    98    148   ########################################################################
          149  +
          150  +set ::log [open fuzzy.log w]
          151  +
          152  +# 
          153  +# Usage: do_fuzzy_test <testname> ?<options>?
          154  +# 
          155  +#     -template
          156  +#     -errorlist
          157  +#     
          158  +proc do_fuzzy_test {testname args} {
          159  +  set ::fuzzyopts(-errorlist) [list]
          160  +  array set ::fuzzyopts $args
          161  +  lappend ::fuzzyopts(-errorlist) {parser stack overflow} {ORDER BY column}
          162  +
          163  +  for {set ii 0} {$ii < 2000} {incr ii} {
          164  +    do_test ${testname}.$ii {
          165  +      set ::sql [subst $::fuzzyopts(-template)]
          166  +      puts $::log $::sql
          167  +      flush $::log
          168  +      set rc [catch {execsql $::sql} msg]
          169  +      set e 1
          170  +      if {$rc} {
          171  +        set e 0
          172  +        foreach error $::fuzzyopts(-errorlist) {
          173  +          if {0 == [string first $error $msg]} {
          174  +            set e 1
          175  +            break
          176  +          }
          177  +        }
          178  +      }
          179  +      if {$e == 0} {
          180  +        puts ""
          181  +        puts $::sql
          182  +        puts $msg
          183  +      }
          184  +      set e
          185  +    } {1}
          186  +  }
          187  +}
    99    188   
   100    189   #----------------------------------------------------------------
   101    190   # These tests caused errors that were first caught by the tests
   102    191   # in this file. They are still here.
   103    192   do_test fuzz-1.1 {
   104    193     execsql {
   105    194       SELECT 'abc' LIKE X'ABCD';
................................................................................
   136    225   do_test fuzz-1.7 {
   137    226     execsql {
   138    227       SELECT ( SELECT zeroblob(1000) FROM ( 
   139    228         SELECT * FROM (SELECT 'first') ORDER BY NOT 'in') 
   140    229       )
   141    230     }
   142    231   } [execsql {SELECT zeroblob(1000)}]
          232  +
          233  +do_test fuzz-1.8 {
          234  +  execsql {
          235  +    SELECT CAST(zeroblob(1000) AS text);
          236  +  }
          237  +} {{}}
   143    238   
   144    239   #----------------------------------------------------------------
   145    240   # Test some fuzzily generated expressions.
   146    241   #
   147         -for {set ii 0} {$ii < 2000} {incr ii} {
   148         -  do_test fuzz-2.1.$ii {
   149         -    set ::expr [Expr]
   150         -    set rc [catch {execsql "SELECT $::expr"} msg]
   151         -    set e [expr {
   152         -      $rc == 0 || 
   153         -      $msg eq "parser stack overflow" ||
   154         -      0 == [string first "ORDER BY column number" $msg]
   155         -    }]
   156         -    if {$e == 0} {
   157         -      puts ""
   158         -      puts "SELECT $::expr"
   159         -      puts $msg
   160         -    }
   161         -    set e
   162         -  } {1}
   163         -} 
          242  +do_fuzzy_test fuzz-2 -template  { SELECT [Expr] }
   164    243   
   165    244   do_test fuzz-3.1 {
   166    245     execsql {
   167    246       CREATE TABLE abc(a, b, c);
   168         -    CREATE TABLE def(d, e, f);
   169         -    CREATE TABLE ghi(g, h, i);
          247  +    CREATE TABLE def(a, b, c);
          248  +    CREATE TABLE ghi(a, b, c);
   170    249     }
   171    250   } {}
   172         -set ::TableList [list abc def ghi]
          251  +set ::TableList  [list abc def ghi]
          252  +set ::ColumnList [list a b c]
   173    253   
   174    254   #----------------------------------------------------------------
   175    255   # Test some fuzzily generated SELECT statements.
   176    256   #
   177         -for {set ii 0} {$ii < 2000} {incr ii} {
   178         -  do_test fuzz-2.2.$ii {
   179         -    set ::select [Select]
   180         -    set rc [catch {execsql $::select} msg]
   181         -    set e [expr {$rc == 0 || $msg eq "parser stack overflow"}]
   182         -    set e [expr {
   183         -      $rc == 0 || 
   184         -      $msg eq "parser stack overflow" ||
   185         -      0 == [string first "ORDER BY column number" $msg]
   186         -    }]
   187         -    if {$e == 0} {
   188         -      puts ""
   189         -      puts $::select
   190         -      puts $msg
   191         -    }
   192         -    set e
   193         -  } {1}
   194         -} 
          257  +do_fuzzy_test fuzz-3.2 -template  {[Select]}
          258  +
          259  +#----------------------------------------------------------------
          260  +# Insert a small amount of data into the database and then run 
          261  +# some more generated SELECT statements.
          262  +#
          263  +do_test fuzz-4.1 {
          264  +  execsql {
          265  +    INSERT INTO abc VALUES(1, 2, 3);
          266  +    INSERT INTO abc VALUES(4, 5, 6);
          267  +    INSERT INTO abc VALUES(7, 8, 9);
          268  +    INSERT INTO def VALUES(1, 2, 3);
          269  +    INSERT INTO def VALUES(4, 5, 6);
          270  +    INSERT INTO def VALUES(7, 8, 9);
          271  +    INSERT INTO ghi VALUES(1, 2, 3);
          272  +    INSERT INTO ghi VALUES(4, 5, 6);
          273  +    INSERT INTO ghi VALUES(7, 8, 9);
          274  +    CREATE INDEX abc_i ON abc(a, b, c);
          275  +    CREATE INDEX def_i ON def(c, a, b);
          276  +    CREATE INDEX ghi_i ON ghi(b, c, a);
          277  +  }
          278  +} {}
          279  +do_fuzzy_test fuzz-4.2 -template {[Select]}
          280  +
          281  +#----------------------------------------------------------------
          282  +# Test some fuzzy INSERT statements:
          283  +#
          284  +do_test         fuzz-5.1 {execsql BEGIN} {}
          285  +do_fuzzy_test   fuzz-5.2 -template  {[Insert]} -errorlist table
          286  +integrity_check fuzz-5.2.integrity
          287  +do_test         fuzz-5.3 {execsql COMMIT} {}
          288  +integrity_check fuzz-5.4.integrity
          289  +
          290  +do_fuzzy_test fuzz-6.1 -template {[Select]}
   195    291   
          292  +close $::log
   196    293   finish_test