/ Hex Artifact Content
Login

Artifact 133c830fdd4342b687910a04cf8e617e0f5f0e5f:


0000: 2f 2a 0a 2a 2a 20 32 30 31 31 20 4d 61 72 63 68  /*.** 2011 March
0010: 20 32 34 0a 2a 2a 0a 2a 2a 20 54 68 65 20 61 75   24.**.** The au
0020: 74 68 6f 72 20 64 69 73 63 6c 61 69 6d 73 20 63  thor disclaims c
0030: 6f 70 79 72 69 67 68 74 20 74 6f 20 74 68 69 73  opyright to this
0040: 20 73 6f 75 72 63 65 20 63 6f 64 65 2e 20 20 49   source code.  I
0050: 6e 20 70 6c 61 63 65 20 6f 66 0a 2a 2a 20 61 20  n place of.** a 
0060: 6c 65 67 61 6c 20 6e 6f 74 69 63 65 2c 20 68 65  legal notice, he
0070: 72 65 20 69 73 20 61 20 62 6c 65 73 73 69 6e 67  re is a blessing
0080: 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 4d 61 79 20 79  :.**.**    May y
0090: 6f 75 20 64 6f 20 67 6f 6f 64 20 61 6e 64 20 6e  ou do good and n
00a0: 6f 74 20 65 76 69 6c 2e 0a 2a 2a 20 20 20 20 4d  ot evil..**    M
00b0: 61 79 20 79 6f 75 20 66 69 6e 64 20 66 6f 72 67  ay you find forg
00c0: 69 76 65 6e 65 73 73 20 66 6f 72 20 79 6f 75 72  iveness for your
00d0: 73 65 6c 66 20 61 6e 64 20 66 6f 72 67 69 76 65  self and forgive
00e0: 20 6f 74 68 65 72 73 2e 0a 2a 2a 20 20 20 20 4d   others..**    M
00f0: 61 79 20 79 6f 75 20 73 68 61 72 65 20 66 72 65  ay you share fre
0100: 65 6c 79 2c 20 6e 65 76 65 72 20 74 61 6b 69 6e  ely, never takin
0110: 67 20 6d 6f 72 65 20 74 68 61 6e 20 79 6f 75 20  g more than you 
0120: 67 69 76 65 2e 0a 2a 2a 0a 2a 2a 2a 2a 2a 2a 2a  give..**.*******
0130: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0140: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0150: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0160: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0170: 2a 2a 0a 2a 2a 0a 2a 2a 20 43 6f 64 65 20 66 6f  **.**.** Code fo
0180: 72 20 64 65 6d 6f 6e 73 74 61 72 74 69 6f 6e 20  r demonstartion 
0190: 76 69 72 74 75 61 6c 20 74 61 62 6c 65 20 74 68  virtual table th
01a0: 61 74 20 67 65 6e 65 72 61 74 65 73 20 76 61 72  at generates var
01b0: 69 61 74 69 6f 6e 73 0a 2a 2a 20 6f 6e 20 61 6e  iations.** on an
01c0: 20 69 6e 70 75 74 20 77 6f 72 64 20 61 74 20 69   input word at i
01d0: 6e 63 72 65 61 73 69 6e 67 20 65 64 69 74 20 64  ncreasing edit d
01e0: 69 73 74 61 6e 63 65 73 20 66 72 6f 6d 20 74 68  istances from th
01f0: 65 20 6f 72 69 67 69 6e 61 6c 2e 0a 2a 2f 0a 23  e original..*/.#
0200: 69 6e 63 6c 75 64 65 20 22 73 71 6c 69 74 65 33  include "sqlite3
0210: 2e 68 22 0a 23 69 6e 63 6c 75 64 65 20 3c 73 74  .h".#include <st
0220: 64 6c 69 62 2e 68 3e 0a 23 69 6e 63 6c 75 64 65  dlib.h>.#include
0230: 20 3c 73 74 72 69 6e 67 2e 68 3e 0a 23 69 6e 63   <string.h>.#inc
0240: 6c 75 64 65 20 3c 61 73 73 65 72 74 2e 68 3e 0a  lude <assert.h>.
0250: 0a 23 69 66 6e 64 65 66 20 53 51 4c 49 54 45 5f  .#ifndef SQLITE_
0260: 4f 4d 49 54 5f 56 49 52 54 55 41 4c 54 41 42 4c  OMIT_VIRTUALTABL
0270: 45 0a 0a 2f 2a 0a 2a 2a 20 46 6f 72 77 61 72 64  E../*.** Forward
0280: 20 64 65 63 6c 61 72 61 74 69 6f 6e 20 6f 66 20   declaration of 
0290: 6f 62 6a 65 63 74 73 20 75 73 65 64 20 62 79 20  objects used by 
02a0: 74 68 69 73 20 69 6d 70 6c 65 6d 65 6e 74 61 74  this implementat
02b0: 69 6f 6e 0a 2a 2f 0a 74 79 70 65 64 65 66 20 73  ion.*/.typedef s
02c0: 74 72 75 63 74 20 66 75 7a 7a 65 72 5f 76 74 61  truct fuzzer_vta
02d0: 62 20 66 75 7a 7a 65 72 5f 76 74 61 62 3b 0a 74  b fuzzer_vtab;.t
02e0: 79 70 65 64 65 66 20 73 74 72 75 63 74 20 66 75  ypedef struct fu
02f0: 7a 7a 65 72 5f 63 75 72 73 6f 72 20 66 75 7a 7a  zzer_cursor fuzz
0300: 65 72 5f 63 75 72 73 6f 72 3b 0a 74 79 70 65 64  er_cursor;.typed
0310: 65 66 20 73 74 72 75 63 74 20 66 75 7a 7a 65 72  ef struct fuzzer
0320: 5f 72 75 6c 65 20 66 75 7a 7a 65 72 5f 72 75 6c  _rule fuzzer_rul
0330: 65 3b 0a 74 79 70 65 64 65 66 20 73 74 72 75 63  e;.typedef struc
0340: 74 20 66 75 7a 7a 65 72 5f 73 65 65 6e 20 66 75  t fuzzer_seen fu
0350: 7a 7a 65 72 5f 73 65 65 6e 3b 0a 74 79 70 65 64  zzer_seen;.typed
0360: 65 66 20 73 74 72 75 63 74 20 66 75 7a 7a 65 72  ef struct fuzzer
0370: 5f 73 74 65 6d 20 66 75 7a 7a 65 72 5f 73 74 65  _stem fuzzer_ste
0380: 6d 3b 0a 0a 2f 2a 0a 2a 2a 20 54 79 70 65 20 6f  m;../*.** Type o
0390: 66 20 74 68 65 20 22 63 6f 73 74 22 20 6f 66 20  f the "cost" of 
03a0: 61 6e 20 65 64 69 74 20 6f 70 65 72 61 74 69 6f  an edit operatio
03b0: 6e 2e 20 20 4d 69 67 68 74 20 62 65 20 63 68 61  n.  Might be cha
03c0: 6e 67 65 64 20 74 6f 0a 2a 2a 20 22 66 6c 6f 61  nged to.** "floa
03d0: 74 22 20 6f 72 20 22 64 6f 75 62 6c 65 22 20 6f  t" or "double" o
03e0: 72 20 22 73 71 6c 69 74 65 33 5f 69 6e 74 36 34  r "sqlite3_int64
03f0: 22 20 69 6e 20 74 68 65 20 66 75 74 75 72 65 2e  " in the future.
0400: 0a 2a 2f 0a 74 79 70 65 64 65 66 20 69 6e 74 20  .*/.typedef int 
0410: 66 75 7a 7a 65 72 5f 63 6f 73 74 3b 0a 0a 0a 2f  fuzzer_cost;.../
0420: 2a 0a 2a 2a 20 45 61 63 68 20 74 72 61 6e 73 66  *.** Each transf
0430: 6f 72 6d 61 74 69 6f 6e 20 72 75 6c 65 20 69 73  ormation rule is
0440: 20 73 74 6f 72 65 64 20 61 73 20 61 6e 20 69 6e   stored as an in
0450: 73 74 61 6e 63 65 20 6f 66 20 74 68 69 73 20 6f  stance of this o
0460: 62 6a 65 63 74 2e 0a 2a 2a 20 41 6c 6c 20 72 75  bject..** All ru
0470: 6c 65 73 20 61 72 65 20 6b 65 70 74 20 6f 6e 20  les are kept on 
0480: 61 20 6c 69 6e 6b 65 64 20 6c 69 73 74 20 73 6f  a linked list so
0490: 72 74 65 64 20 62 79 20 72 43 6f 73 74 2e 0a 2a  rted by rCost..*
04a0: 2f 0a 73 74 72 75 63 74 20 66 75 7a 7a 65 72 5f  /.struct fuzzer_
04b0: 72 75 6c 65 20 7b 0a 20 20 66 75 7a 7a 65 72 5f  rule {.  fuzzer_
04c0: 72 75 6c 65 20 2a 70 4e 65 78 74 3b 20 20 20 20  rule *pNext;    
04d0: 20 20 20 20 2f 2a 20 4e 65 78 74 20 72 75 6c 65      /* Next rule
04e0: 20 69 6e 20 6f 72 64 65 72 20 6f 66 20 69 6e 63   in order of inc
04f0: 72 65 61 73 69 6e 67 20 72 43 6f 73 74 20 2a 2f  reasing rCost */
0500: 0a 20 20 66 75 7a 7a 65 72 5f 63 6f 73 74 20 72  .  fuzzer_cost r
0510: 43 6f 73 74 3b 20 20 20 20 20 20 20 20 20 2f 2a  Cost;         /*
0520: 20 43 6f 73 74 20 6f 66 20 74 68 69 73 20 74 72   Cost of this tr
0530: 61 6e 73 66 6f 72 6d 61 74 69 6f 6e 20 2a 2f 0a  ansformation */.
0540: 20 20 69 6e 74 20 6e 46 72 6f 6d 2c 20 6e 54 6f    int nFrom, nTo
0550: 3b 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20  ;            /* 
0560: 4c 65 6e 67 74 68 20 6f 66 20 74 68 65 20 7a 46  Length of the zF
0570: 72 6f 6d 20 61 6e 64 20 7a 54 6f 20 73 74 72 69  rom and zTo stri
0580: 6e 67 73 20 2a 2f 0a 20 20 63 68 61 72 20 2a 7a  ngs */.  char *z
0590: 46 72 6f 6d 3b 20 20 20 20 20 20 20 20 20 20 20  From;           
05a0: 20 20 20 20 2f 2a 20 54 72 61 6e 73 66 6f 72 6d      /* Transform
05b0: 20 66 72 6f 6d 20 2a 2f 0a 20 20 63 68 61 72 20   from */.  char 
05c0: 7a 54 6f 5b 34 5d 3b 20 20 20 20 20 20 20 20 20  zTo[4];         
05d0: 20 20 20 20 20 20 2f 2a 20 54 72 61 6e 73 66 6f        /* Transfo
05e0: 72 6d 20 74 6f 20 28 65 78 74 72 61 20 73 70 61  rm to (extra spa
05f0: 63 65 20 61 70 70 65 6e 64 65 64 29 20 2a 2f 0a  ce appended) */.
0600: 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 41 20 73 74 65 6d  };../*.** A stem
0610: 20 6f 62 6a 65 63 74 20 69 73 20 75 73 65 64 20   object is used 
0620: 74 6f 20 67 65 6e 65 72 61 74 65 20 76 61 72 69  to generate vari
0630: 61 6e 74 73 2e 20 20 0a 2a 2f 0a 73 74 72 75 63  ants.  .*/.struc
0640: 74 20 66 75 7a 7a 65 72 5f 73 74 65 6d 20 7b 0a  t fuzzer_stem {.
0650: 20 20 63 68 61 72 20 2a 7a 42 61 73 69 73 3b 20    char *zBasis; 
0660: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
0670: 57 6f 72 64 20 62 65 69 6e 67 20 66 75 7a 7a 65  Word being fuzze
0680: 64 20 2a 2f 0a 20 20 69 6e 74 20 6e 42 61 73 69  d */.  int nBasi
0690: 73 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  s;              
06a0: 20 20 2f 2a 20 4c 65 6e 67 74 68 20 6f 66 20 74    /* Length of t
06b0: 68 65 20 7a 42 61 73 69 73 20 73 74 72 69 6e 67  he zBasis string
06c0: 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 66 75 7a 7a   */.  const fuzz
06d0: 65 72 5f 72 75 6c 65 20 2a 70 52 75 6c 65 3b 20  er_rule *pRule; 
06e0: 20 2f 2a 20 43 75 72 72 65 6e 74 20 72 75 6c 65   /* Current rule
06f0: 20 74 6f 20 61 70 70 6c 79 20 2a 2f 0a 20 20 69   to apply */.  i
0700: 6e 74 20 6e 3b 20 20 20 20 20 20 20 20 20 20 20  nt n;           
0710: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 41 70 70            /* App
0720: 6c 79 20 70 52 75 6c 65 20 61 74 20 74 68 69 73  ly pRule at this
0730: 20 63 68 61 72 61 63 74 65 72 20 6f 66 66 73 65   character offse
0740: 74 20 2a 2f 0a 20 20 66 75 7a 7a 65 72 5f 63 6f  t */.  fuzzer_co
0750: 73 74 20 72 42 61 73 65 43 6f 73 74 3b 20 20 20  st rBaseCost;   
0760: 20 20 2f 2a 20 42 61 73 65 20 63 6f 73 74 20 6f    /* Base cost o
0770: 66 20 67 65 74 74 69 6e 67 20 74 6f 20 7a 42 61  f getting to zBa
0780: 73 69 73 20 2a 2f 0a 20 20 66 75 7a 7a 65 72 5f  sis */.  fuzzer_
0790: 73 74 65 6d 20 2a 70 4e 65 78 74 3b 20 20 20 20  stem *pNext;    
07a0: 20 20 20 20 2f 2a 20 4e 65 78 74 20 73 74 65 6d      /* Next stem
07b0: 20 69 6e 20 72 43 6f 73 74 20 6f 72 64 65 72 20   in rCost order 
07c0: 2a 2f 0a 20 20 66 75 7a 7a 65 72 5f 73 74 65 6d  */.  fuzzer_stem
07d0: 20 2a 70 48 61 73 68 3b 20 20 20 20 20 20 20 20   *pHash;        
07e0: 2f 2a 20 4e 65 78 74 20 73 74 65 6d 20 77 69 74  /* Next stem wit
07f0: 68 20 73 61 6d 65 20 68 61 73 68 20 6f 6e 20 7a  h same hash on z
0800: 42 61 73 69 73 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 20  Basis */.};../* 
0810: 0a 2a 2a 20 41 20 66 75 7a 7a 65 72 20 76 69 72  .** A fuzzer vir
0820: 74 75 61 6c 2d 74 61 62 6c 65 20 6f 62 6a 65 63  tual-table objec
0830: 74 20 0a 2a 2f 0a 73 74 72 75 63 74 20 66 75 7a  t .*/.struct fuz
0840: 7a 65 72 5f 76 74 61 62 20 7b 0a 20 20 73 71 6c  zer_vtab {.  sql
0850: 69 74 65 33 5f 76 74 61 62 20 62 61 73 65 3b 20  ite3_vtab base; 
0860: 20 20 20 20 20 20 20 20 2f 2a 20 42 61 73 65 20          /* Base 
0870: 63 6c 61 73 73 20 2d 20 6d 75 73 74 20 62 65 20  class - must be 
0880: 66 69 72 73 74 20 2a 2f 0a 20 20 63 68 61 72 20  first */.  char 
0890: 2a 7a 43 6c 61 73 73 4e 61 6d 65 3b 20 20 20 20  *zClassName;    
08a0: 20 20 20 20 20 20 2f 2a 20 4e 61 6d 65 20 6f 66        /* Name of
08b0: 20 74 68 69 73 20 63 6c 61 73 73 2e 20 20 44 65   this class.  De
08c0: 66 61 75 6c 74 3a 20 22 66 75 7a 7a 65 72 22 20  fault: "fuzzer" 
08d0: 2a 2f 0a 20 20 66 75 7a 7a 65 72 5f 72 75 6c 65  */.  fuzzer_rule
08e0: 20 2a 70 52 75 6c 65 3b 20 20 20 20 20 20 20 20   *pRule;        
08f0: 2f 2a 20 41 6c 6c 20 61 63 74 69 76 65 20 72 75  /* All active ru
0900: 6c 65 73 20 69 6e 20 74 68 69 73 20 66 75 7a 7a  les in this fuzz
0910: 65 72 20 2a 2f 0a 20 20 66 75 7a 7a 65 72 5f 72  er */.  fuzzer_r
0920: 75 6c 65 20 2a 70 4e 65 77 52 75 6c 65 3b 20 20  ule *pNewRule;  
0930: 20 20 20 2f 2a 20 4e 65 77 20 72 75 6c 65 73 20     /* New rules 
0940: 74 6f 20 61 64 64 20 77 68 65 6e 20 6c 61 73 74  to add when last
0950: 20 63 75 72 73 6f 72 20 65 78 70 69 72 65 73 20   cursor expires 
0960: 2a 2f 0a 20 20 69 6e 74 20 6e 43 75 72 73 6f 72  */.  int nCursor
0970: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
0980: 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 61 63 74  /* Number of act
0990: 69 76 65 20 63 75 72 73 6f 72 73 20 2a 2f 0a 7d  ive cursors */.}
09a0: 3b 0a 0a 23 64 65 66 69 6e 65 20 46 55 5a 5a 45  ;..#define FUZZE
09b0: 52 5f 48 41 53 48 20 20 34 30 30 31 20 20 20 20  R_HASH  4001    
09c0: 2f 2a 20 48 61 73 68 20 74 61 62 6c 65 20 73 69  /* Hash table si
09d0: 7a 65 20 2a 2f 0a 0a 2f 2a 20 41 20 66 75 7a 7a  ze */../* A fuzz
09e0: 65 72 20 63 75 72 73 6f 72 20 6f 62 6a 65 63 74  er cursor object
09f0: 20 2a 2f 0a 73 74 72 75 63 74 20 66 75 7a 7a 65   */.struct fuzze
0a00: 72 5f 63 75 72 73 6f 72 20 7b 0a 20 20 73 71 6c  r_cursor {.  sql
0a10: 69 74 65 33 5f 76 74 61 62 5f 63 75 72 73 6f 72  ite3_vtab_cursor
0a20: 20 62 61 73 65 3b 20 20 2f 2a 20 42 61 73 65 20   base;  /* Base 
0a30: 63 6c 61 73 73 20 2d 20 6d 75 73 74 20 62 65 20  class - must be 
0a40: 66 69 72 73 74 20 2a 2f 0a 20 20 66 75 7a 7a 65  first */.  fuzze
0a50: 72 5f 76 74 61 62 20 2a 70 56 74 61 62 3b 20 20  r_vtab *pVtab;  
0a60: 20 20 20 20 20 20 2f 2a 20 54 68 65 20 76 69 72        /* The vir
0a70: 74 75 61 6c 20 74 61 62 6c 65 20 74 68 69 73 20  tual table this 
0a80: 63 75 72 73 6f 72 20 62 65 6c 6f 6e 67 73 20 74  cursor belongs t
0a90: 6f 20 2a 2f 0a 20 20 66 75 7a 7a 65 72 5f 63 6f  o */.  fuzzer_co
0aa0: 73 74 20 72 4c 69 6d 69 74 3b 20 20 20 20 20 20  st rLimit;      
0ab0: 20 20 2f 2a 20 4d 61 78 69 6d 75 6d 20 63 6f 73    /* Maximum cos
0ac0: 74 20 6f 66 20 61 6e 79 20 74 65 72 6d 20 2a 2f  t of any term */
0ad0: 0a 20 20 66 75 7a 7a 65 72 5f 73 74 65 6d 20 2a  .  fuzzer_stem *
0ae0: 70 53 74 65 6d 3b 20 20 20 20 20 20 20 20 2f 2a  pStem;        /*
0af0: 20 53 6f 72 74 65 64 20 6c 69 73 74 20 6f 66 20   Sorted list of 
0b00: 73 74 65 6d 73 20 66 6f 72 20 67 65 6e 65 72 61  stems for genera
0b10: 74 69 6e 67 20 6e 65 77 20 74 65 72 6d 73 20 2a  ting new terms *
0b20: 2f 0a 20 20 66 75 7a 7a 65 72 5f 73 74 65 6d 20  /.  fuzzer_stem 
0b30: 2a 70 44 6f 6e 65 3b 20 20 20 20 20 20 20 20 2f  *pDone;        /
0b40: 2a 20 53 74 65 6d 73 20 61 6c 72 65 61 64 79 20  * Stems already 
0b50: 70 72 6f 63 65 73 73 65 64 20 74 6f 20 63 6f 6d  processed to com
0b60: 70 6c 65 74 69 6f 6e 20 2a 2f 0a 20 20 63 68 61  pletion */.  cha
0b70: 72 20 2a 7a 42 75 66 3b 20 20 20 20 20 20 20 20  r *zBuf;        
0b80: 20 20 20 20 20 20 20 20 2f 2a 20 54 65 6d 70 6f          /* Tempo
0b90: 72 61 72 79 20 75 73 65 20 62 75 66 66 65 72 20  rary use buffer 
0ba0: 2a 2f 0a 20 20 69 6e 74 20 6e 42 75 66 3b 20 20  */.  int nBuf;  
0bb0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0bc0: 2f 2a 20 42 79 74 65 73 20 61 6c 6c 6f 63 61 74  /* Bytes allocat
0bd0: 65 64 20 66 6f 72 20 7a 42 75 66 20 2a 2f 0a 20  ed for zBuf */. 
0be0: 20 66 75 7a 7a 65 72 5f 73 74 65 6d 20 2a 61 70   fuzzer_stem *ap
0bf0: 48 61 73 68 5b 46 55 5a 5a 45 52 5f 48 41 53 48  Hash[FUZZER_HASH
0c00: 5d 3b 20 2f 2a 20 48 61 73 68 20 6f 66 20 70 72  ]; /* Hash of pr
0c10: 65 76 69 6f 75 73 6c 79 20 67 65 6e 65 72 61 74  eviously generat
0c20: 65 64 20 74 65 72 6d 73 20 2a 2f 0a 7d 3b 0a 0a  ed terms */.};..
0c30: 2f 2a 20 4d 65 74 68 6f 64 73 20 66 6f 72 20 74  /* Methods for t
0c40: 68 65 20 66 75 7a 7a 65 72 20 6d 6f 64 75 6c 65  he fuzzer module
0c50: 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 66   */.static int f
0c60: 75 7a 7a 65 72 43 6f 6e 6e 65 63 74 28 0a 20 20  uzzerConnect(.  
0c70: 73 71 6c 69 74 65 33 20 2a 64 62 2c 0a 20 20 76  sqlite3 *db,.  v
0c80: 6f 69 64 20 2a 70 41 75 78 2c 0a 20 20 69 6e 74  oid *pAux,.  int
0c90: 20 61 72 67 63 2c 20 63 6f 6e 73 74 20 63 68 61   argc, const cha
0ca0: 72 20 2a 63 6f 6e 73 74 2a 61 72 67 76 2c 0a 20  r *const*argv,. 
0cb0: 20 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 2a   sqlite3_vtab **
0cc0: 70 70 56 74 61 62 2c 0a 20 20 63 68 61 72 20 2a  ppVtab,.  char *
0cd0: 2a 70 7a 45 72 72 0a 29 7b 0a 20 20 66 75 7a 7a  *pzErr.){.  fuzz
0ce0: 65 72 5f 76 74 61 62 20 2a 70 4e 65 77 3b 0a 20  er_vtab *pNew;. 
0cf0: 20 69 6e 74 20 6e 3b 0a 20 20 69 66 28 20 73 74   int n;.  if( st
0d00: 72 63 6d 70 28 61 72 67 76 5b 31 5d 2c 22 74 65  rcmp(argv[1],"te
0d10: 6d 70 22 29 21 3d 30 20 29 7b 0a 20 20 20 20 2a  mp")!=0 ){.    *
0d20: 70 7a 45 72 72 20 3d 20 73 71 6c 69 74 65 33 5f  pzErr = sqlite3_
0d30: 6d 70 72 69 6e 74 66 28 22 25 73 20 76 69 72 74  mprintf("%s virt
0d40: 75 61 6c 20 74 61 62 6c 65 73 20 6d 75 73 74 20  ual tables must 
0d50: 62 65 20 54 45 4d 50 22 2c 20 61 72 67 76 5b 30  be TEMP", argv[0
0d60: 5d 29 3b 0a 20 20 20 20 72 65 74 75 72 6e 20 53  ]);.    return S
0d70: 51 4c 49 54 45 5f 45 52 52 4f 52 3b 0a 20 20 7d  QLITE_ERROR;.  }
0d80: 0a 20 20 6e 20 3d 20 73 74 72 6c 65 6e 28 61 72  .  n = strlen(ar
0d90: 67 76 5b 30 5d 29 20 2b 20 31 3b 0a 20 20 70 4e  gv[0]) + 1;.  pN
0da0: 65 77 20 3d 20 73 71 6c 69 74 65 33 5f 6d 61 6c  ew = sqlite3_mal
0db0: 6c 6f 63 28 20 73 69 7a 65 6f 66 28 2a 70 4e 65  loc( sizeof(*pNe
0dc0: 77 29 20 2b 20 6e 20 29 3b 0a 20 20 69 66 28 20  w) + n );.  if( 
0dd0: 70 4e 65 77 3d 3d 30 20 29 20 72 65 74 75 72 6e  pNew==0 ) return
0de0: 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20   SQLITE_NOMEM;. 
0df0: 20 70 4e 65 77 2d 3e 7a 43 6c 61 73 73 4e 61 6d   pNew->zClassNam
0e00: 65 20 3d 20 28 63 68 61 72 2a 29 26 70 4e 65 77  e = (char*)&pNew
0e10: 5b 31 5d 3b 0a 20 20 6d 65 6d 63 70 79 28 70 4e  [1];.  memcpy(pN
0e20: 65 77 2d 3e 7a 43 6c 61 73 73 4e 61 6d 65 2c 20  ew->zClassName, 
0e30: 61 72 67 76 5b 30 5d 2c 20 6e 29 3b 0a 20 20 73  argv[0], n);.  s
0e40: 71 6c 69 74 65 33 5f 64 65 63 6c 61 72 65 5f 76  qlite3_declare_v
0e50: 74 61 62 28 64 62 2c 20 22 43 52 45 41 54 45 20  tab(db, "CREATE 
0e60: 54 41 42 4c 45 20 78 28 77 6f 72 64 2c 64 69 73  TABLE x(word,dis
0e70: 74 61 6e 63 65 2c 63 46 72 6f 6d 2c 63 54 6f 2c  tance,cFrom,cTo,
0e80: 63 6f 73 74 29 22 29 3b 0a 20 20 6d 65 6d 73 65  cost)");.  memse
0e90: 74 28 70 4e 65 77 2c 20 30 2c 20 73 69 7a 65 6f  t(pNew, 0, sizeo
0ea0: 66 28 2a 70 4e 65 77 29 29 3b 0a 20 20 2a 70 70  f(*pNew));.  *pp
0eb0: 56 74 61 62 20 3d 20 26 70 4e 65 77 2d 3e 62 61  Vtab = &pNew->ba
0ec0: 73 65 3b 0a 20 20 72 65 74 75 72 6e 20 53 51 4c  se;.  return SQL
0ed0: 49 54 45 5f 4f 4b 3b 0a 7d 0a 2f 2a 20 4e 6f 74  ITE_OK;.}./* Not
0ee0: 65 20 74 68 61 74 20 66 6f 72 20 74 68 69 73 20  e that for this 
0ef0: 76 69 72 74 75 61 6c 20 74 61 62 6c 65 2c 20 74  virtual table, t
0f00: 68 65 20 78 43 72 65 61 74 65 20 61 6e 64 20 78  he xCreate and x
0f10: 43 6f 6e 6e 65 63 74 0a 2a 2a 20 6d 65 74 68 6f  Connect.** metho
0f20: 64 73 20 61 72 65 20 69 64 65 6e 74 69 63 61 6c  ds are identical
0f30: 2e 20 2a 2f 0a 0a 73 74 61 74 69 63 20 69 6e 74  . */..static int
0f40: 20 66 75 7a 7a 65 72 44 69 73 63 6f 6e 6e 65 63   fuzzerDisconnec
0f50: 74 28 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a  t(sqlite3_vtab *
0f60: 70 56 74 61 62 29 7b 0a 20 20 66 75 7a 7a 65 72  pVtab){.  fuzzer
0f70: 5f 76 74 61 62 20 2a 70 20 3d 20 28 66 75 7a 7a  _vtab *p = (fuzz
0f80: 65 72 5f 76 74 61 62 2a 29 70 56 74 61 62 3b 0a  er_vtab*)pVtab;.
0f90: 20 20 61 73 73 65 72 74 28 20 70 2d 3e 6e 43 75    assert( p->nCu
0fa0: 72 73 6f 72 3d 3d 30 20 29 3b 0a 20 20 64 6f 7b  rsor==0 );.  do{
0fb0: 0a 20 20 20 20 77 68 69 6c 65 28 20 70 2d 3e 70  .    while( p->p
0fc0: 52 75 6c 65 20 29 7b 0a 20 20 20 20 20 20 66 75  Rule ){.      fu
0fd0: 7a 7a 65 72 5f 72 75 6c 65 20 2a 70 52 75 6c 65  zzer_rule *pRule
0fe0: 20 3d 20 70 2d 3e 70 52 75 6c 65 3b 0a 20 20 20   = p->pRule;.   
0ff0: 20 20 20 70 2d 3e 70 52 75 6c 65 20 3d 20 70 52     p->pRule = pR
1000: 75 6c 65 2d 3e 70 4e 65 78 74 3b 0a 20 20 20 20  ule->pNext;.    
1010: 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70    sqlite3_free(p
1020: 52 75 6c 65 29 3b 0a 20 20 20 20 7d 0a 20 20 20  Rule);.    }.   
1030: 20 70 2d 3e 70 52 75 6c 65 20 3d 20 70 2d 3e 70   p->pRule = p->p
1040: 4e 65 77 52 75 6c 65 3b 0a 20 20 20 20 70 2d 3e  NewRule;.    p->
1050: 70 4e 65 77 52 75 6c 65 20 3d 20 30 3b 0a 20 20  pNewRule = 0;.  
1060: 7d 77 68 69 6c 65 28 20 70 2d 3e 70 52 75 6c 65  }while( p->pRule
1070: 20 29 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66 72   );.  sqlite3_fr
1080: 65 65 28 70 29 3b 0a 20 20 72 65 74 75 72 6e 20  ee(p);.  return 
1090: 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 2f 2a 20  SQLITE_OK;.}./* 
10a0: 54 68 65 20 78 44 69 73 63 6f 6e 6e 65 63 74 20  The xDisconnect 
10b0: 61 6e 64 20 78 44 65 73 74 72 6f 79 20 6d 65 74  and xDestroy met
10c0: 68 6f 64 73 20 61 72 65 20 61 6c 73 6f 20 74 68  hods are also th
10d0: 65 20 73 61 6d 65 20 2a 2f 0a 0a 2f 2a 0a 2a 2a  e same */../*.**
10e0: 20 54 68 65 20 74 77 6f 20 69 6e 70 75 74 20 72   The two input r
10f0: 75 6c 65 20 6c 69 73 74 73 20 61 72 65 20 62 6f  ule lists are bo
1100: 74 68 20 73 6f 72 74 65 64 20 69 6e 20 6f 72 64  th sorted in ord
1110: 65 72 20 6f 66 20 69 6e 63 72 65 61 73 69 6e 67  er of increasing
1120: 0a 2a 2a 20 63 6f 73 74 2e 20 20 4d 65 72 67 65  .** cost.  Merge
1130: 20 74 68 65 6d 20 74 6f 67 65 74 68 65 72 20 69   them together i
1140: 6e 74 6f 20 61 20 73 69 6e 67 6c 65 20 6c 69 73  nto a single lis
1150: 74 2c 20 73 6f 72 74 65 64 20 62 79 20 63 6f 73  t, sorted by cos
1160: 74 2c 20 61 6e 64 0a 2a 2a 20 72 65 74 75 72 6e  t, and.** return
1170: 20 61 20 70 6f 69 6e 74 65 72 20 74 6f 20 74 68   a pointer to th
1180: 65 20 68 65 61 64 20 6f 66 20 74 68 61 74 20 6c  e head of that l
1190: 69 73 74 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 66  ist..*/.static f
11a0: 75 7a 7a 65 72 5f 72 75 6c 65 20 2a 66 75 7a 7a  uzzer_rule *fuzz
11b0: 65 72 4d 65 72 67 65 52 75 6c 65 73 28 66 75 7a  erMergeRules(fuz
11c0: 7a 65 72 5f 72 75 6c 65 20 2a 70 41 2c 20 66 75  zer_rule *pA, fu
11d0: 7a 7a 65 72 5f 72 75 6c 65 20 2a 70 42 29 7b 0a  zzer_rule *pB){.
11e0: 20 20 66 75 7a 7a 65 72 5f 72 75 6c 65 20 68 65    fuzzer_rule he
11f0: 61 64 3b 0a 20 20 66 75 7a 7a 65 72 5f 72 75 6c  ad;.  fuzzer_rul
1200: 65 20 2a 70 54 61 69 6c 3b 0a 0a 20 20 70 54 61  e *pTail;..  pTa
1210: 69 6c 20 3d 20 20 26 68 65 61 64 3b 0a 20 20 77  il =  &head;.  w
1220: 68 69 6c 65 28 20 70 41 20 26 26 20 70 42 20 29  hile( pA && pB )
1230: 7b 0a 20 20 20 20 69 66 28 20 70 41 2d 3e 72 43  {.    if( pA->rC
1240: 6f 73 74 3c 3d 70 42 2d 3e 72 43 6f 73 74 20 29  ost<=pB->rCost )
1250: 7b 0a 20 20 20 20 20 20 70 54 61 69 6c 2d 3e 70  {.      pTail->p
1260: 4e 65 78 74 20 3d 20 70 41 3b 0a 20 20 20 20 20  Next = pA;.     
1270: 20 70 54 61 69 6c 20 3d 20 70 41 3b 0a 20 20 20   pTail = pA;.   
1280: 20 20 20 70 41 20 3d 20 70 41 2d 3e 70 4e 65 78     pA = pA->pNex
1290: 74 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20  t;.    }else{.  
12a0: 20 20 20 20 70 54 61 69 6c 2d 3e 70 4e 65 78 74      pTail->pNext
12b0: 20 3d 20 70 42 3b 0a 20 20 20 20 20 20 70 54 61   = pB;.      pTa
12c0: 69 6c 20 3d 20 70 42 3b 0a 20 20 20 20 20 20 70  il = pB;.      p
12d0: 42 20 3d 20 70 42 2d 3e 70 4e 65 78 74 3b 0a 20  B = pB->pNext;. 
12e0: 20 20 20 7d 0a 20 20 7d 0a 20 20 69 66 28 20 70     }.  }.  if( p
12f0: 41 3d 3d 30 20 29 7b 0a 20 20 20 20 70 54 61 69  A==0 ){.    pTai
1300: 6c 2d 3e 70 4e 65 78 74 20 3d 20 70 42 3b 0a 20  l->pNext = pB;. 
1310: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 70 54 61 69   }else{.    pTai
1320: 6c 2d 3e 70 4e 65 78 74 20 3d 20 70 41 3b 0a 20  l->pNext = pA;. 
1330: 20 7d 0a 20 20 72 65 74 75 72 6e 20 68 65 61 64   }.  return head
1340: 2e 70 4e 65 78 74 3b 0a 7d 0a 0a 0a 2f 2a 0a 2a  .pNext;.}.../*.*
1350: 2a 20 4f 70 65 6e 20 61 20 6e 65 77 20 66 75 7a  * Open a new fuz
1360: 7a 65 72 20 63 75 72 73 6f 72 2e 0a 2a 2f 0a 73  zer cursor..*/.s
1370: 74 61 74 69 63 20 69 6e 74 20 66 75 7a 7a 65 72  tatic int fuzzer
1380: 4f 70 65 6e 28 73 71 6c 69 74 65 33 5f 76 74 61  Open(sqlite3_vta
1390: 62 20 2a 70 56 54 61 62 2c 20 73 71 6c 69 74 65  b *pVTab, sqlite
13a0: 33 5f 76 74 61 62 5f 63 75 72 73 6f 72 20 2a 2a  3_vtab_cursor **
13b0: 70 70 43 75 72 73 6f 72 29 7b 0a 20 20 66 75 7a  ppCursor){.  fuz
13c0: 7a 65 72 5f 76 74 61 62 20 2a 70 20 3d 20 28 66  zer_vtab *p = (f
13d0: 75 7a 7a 65 72 5f 76 74 61 62 2a 29 70 56 54 61  uzzer_vtab*)pVTa
13e0: 62 3b 0a 20 20 66 75 7a 7a 65 72 5f 63 75 72 73  b;.  fuzzer_curs
13f0: 6f 72 20 2a 70 43 75 72 3b 0a 20 20 70 43 75 72  or *pCur;.  pCur
1400: 20 3d 20 73 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f   = sqlite3_mallo
1410: 63 28 20 73 69 7a 65 6f 66 28 2a 70 43 75 72 29  c( sizeof(*pCur)
1420: 20 29 3b 0a 20 20 69 66 28 20 70 43 75 72 3d 3d   );.  if( pCur==
1430: 30 20 29 20 72 65 74 75 72 6e 20 53 51 4c 49 54  0 ) return SQLIT
1440: 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 6d 65 6d 73 65  E_NOMEM;.  memse
1450: 74 28 70 43 75 72 2c 20 30 2c 20 73 69 7a 65 6f  t(pCur, 0, sizeo
1460: 66 28 2a 70 43 75 72 29 29 3b 0a 20 20 70 43 75  f(*pCur));.  pCu
1470: 72 2d 3e 70 56 74 61 62 20 3d 20 70 3b 0a 20 20  r->pVtab = p;.  
1480: 2a 70 70 43 75 72 73 6f 72 20 3d 20 26 70 43 75  *ppCursor = &pCu
1490: 72 2d 3e 62 61 73 65 3b 0a 20 20 70 2d 3e 6e 43  r->base;.  p->nC
14a0: 75 72 73 6f 72 2b 2b 3b 0a 20 20 69 66 28 20 70  ursor++;.  if( p
14b0: 2d 3e 6e 43 75 72 73 6f 72 3d 3d 30 20 26 26 20  ->nCursor==0 && 
14c0: 70 2d 3e 70 4e 65 77 52 75 6c 65 20 29 7b 0a 20  p->pNewRule ){. 
14d0: 20 20 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20     unsigned int 
14e0: 69 3b 0a 20 20 20 20 66 75 7a 7a 65 72 5f 72 75  i;.    fuzzer_ru
14f0: 6c 65 20 2a 70 58 3b 0a 20 20 20 20 66 75 7a 7a  le *pX;.    fuzz
1500: 65 72 5f 72 75 6c 65 20 2a 61 5b 31 35 5d 3b 0a  er_rule *a[15];.
1510: 20 20 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 73      for(i=0; i<s
1520: 69 7a 65 6f 66 28 61 29 2f 73 69 7a 65 6f 66 28  izeof(a)/sizeof(
1530: 61 5b 30 5d 29 3b 20 69 2b 2b 29 20 61 5b 69 5d  a[0]); i++) a[i]
1540: 20 3d 20 30 3b 0a 20 20 20 20 77 68 69 6c 65 28   = 0;.    while(
1550: 20 28 70 58 20 3d 20 70 2d 3e 70 4e 65 77 52 75   (pX = p->pNewRu
1560: 6c 65 29 21 3d 30 20 29 7b 0a 20 20 20 20 20 20  le)!=0 ){.      
1570: 70 2d 3e 70 4e 65 77 52 75 6c 65 20 3d 20 70 58  p->pNewRule = pX
1580: 2d 3e 70 4e 65 78 74 3b 0a 20 20 20 20 20 20 70  ->pNext;.      p
1590: 58 2d 3e 70 4e 65 78 74 20 3d 20 30 3b 0a 20 20  X->pNext = 0;.  
15a0: 20 20 20 20 66 6f 72 28 69 3d 30 3b 20 61 5b 69      for(i=0; a[i
15b0: 5d 20 26 26 20 69 3c 73 69 7a 65 6f 66 28 61 29  ] && i<sizeof(a)
15c0: 2f 73 69 7a 65 6f 66 28 61 5b 30 5d 29 2d 31 3b  /sizeof(a[0])-1;
15d0: 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20 20 20 70   i++){.        p
15e0: 58 20 3d 20 66 75 7a 7a 65 72 4d 65 72 67 65 52  X = fuzzerMergeR
15f0: 75 6c 65 73 28 61 5b 69 5d 2c 20 70 58 29 3b 0a  ules(a[i], pX);.
1600: 20 20 20 20 20 20 20 20 61 5b 69 5d 20 3d 20 30          a[i] = 0
1610: 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20  ;.      }.      
1620: 61 5b 69 5d 20 3d 20 66 75 7a 7a 65 72 4d 65 72  a[i] = fuzzerMer
1630: 67 65 52 75 6c 65 73 28 61 5b 69 5d 2c 20 70 58  geRules(a[i], pX
1640: 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 66 6f 72  );.    }.    for
1650: 28 70 58 3d 61 5b 30 5d 2c 20 69 3d 31 3b 20 69  (pX=a[0], i=1; i
1660: 3c 73 69 7a 65 6f 66 28 61 29 2f 73 69 7a 65 6f  <sizeof(a)/sizeo
1670: 66 28 61 5b 30 5d 29 3b 20 69 2b 2b 29 7b 0a 20  f(a[0]); i++){. 
1680: 20 20 20 20 20 70 58 20 3d 20 66 75 7a 7a 65 72       pX = fuzzer
1690: 4d 65 72 67 65 52 75 6c 65 73 28 61 5b 69 5d 2c  MergeRules(a[i],
16a0: 20 70 58 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20   pX);.    }.    
16b0: 70 2d 3e 70 52 75 6c 65 20 3d 20 66 75 7a 7a 65  p->pRule = fuzze
16c0: 72 4d 65 72 67 65 52 75 6c 65 73 28 70 2d 3e 70  rMergeRules(p->p
16d0: 52 75 6c 65 2c 20 70 58 29 3b 0a 20 20 7d 0a 20  Rule, pX);.  }. 
16e0: 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f   return SQLITE_O
16f0: 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 46 72 65 65  K;.}../*.** Free
1700: 20 75 70 20 61 6c 6c 20 74 68 65 20 6d 65 6d 6f   up all the memo
1710: 72 79 20 61 6c 6c 6f 63 61 74 65 64 20 62 79 20  ry allocated by 
1720: 61 20 63 75 72 73 6f 72 2e 20 20 53 65 74 20 69  a cursor.  Set i
1730: 74 20 72 4c 69 6d 69 74 20 74 6f 20 30 0a 2a 2a  t rLimit to 0.**
1740: 20 74 6f 20 69 6e 64 69 63 61 74 65 20 74 68 61   to indicate tha
1750: 74 20 69 74 20 69 73 20 61 74 20 45 4f 46 2e 0a  t it is at EOF..
1760: 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 66  */.static void f
1770: 75 7a 7a 65 72 43 6c 65 61 72 43 75 72 73 6f 72  uzzerClearCursor
1780: 28 66 75 7a 7a 65 72 5f 63 75 72 73 6f 72 20 2a  (fuzzer_cursor *
1790: 70 43 75 72 2c 20 69 6e 74 20 63 6c 65 61 72 48  pCur, int clearH
17a0: 61 73 68 29 7b 0a 20 20 69 66 28 20 70 43 75 72  ash){.  if( pCur
17b0: 2d 3e 70 53 74 65 6d 3d 3d 30 20 26 26 20 70 43  ->pStem==0 && pC
17c0: 75 72 2d 3e 70 44 6f 6e 65 3d 3d 30 20 29 20 63  ur->pDone==0 ) c
17d0: 6c 65 61 72 48 61 73 68 20 3d 20 30 3b 0a 20 20  learHash = 0;.  
17e0: 64 6f 7b 0a 20 20 20 20 77 68 69 6c 65 28 20 70  do{.    while( p
17f0: 43 75 72 2d 3e 70 53 74 65 6d 20 29 7b 0a 20 20  Cur->pStem ){.  
1800: 20 20 20 20 66 75 7a 7a 65 72 5f 73 74 65 6d 20      fuzzer_stem 
1810: 2a 70 53 74 65 6d 20 3d 20 70 43 75 72 2d 3e 70  *pStem = pCur->p
1820: 53 74 65 6d 3b 0a 20 20 20 20 20 20 70 43 75 72  Stem;.      pCur
1830: 2d 3e 70 53 74 65 6d 20 3d 20 70 53 74 65 6d 2d  ->pStem = pStem-
1840: 3e 70 4e 65 78 74 3b 0a 20 20 20 20 20 20 73 71  >pNext;.      sq
1850: 6c 69 74 65 33 5f 66 72 65 65 28 70 53 74 65 6d  lite3_free(pStem
1860: 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 70 43 75  );.    }.    pCu
1870: 72 2d 3e 70 53 74 65 6d 20 3d 20 70 43 75 72 2d  r->pStem = pCur-
1880: 3e 70 44 6f 6e 65 3b 0a 20 20 20 20 70 43 75 72  >pDone;.    pCur
1890: 2d 3e 70 44 6f 6e 65 20 3d 20 30 3b 0a 20 20 7d  ->pDone = 0;.  }
18a0: 77 68 69 6c 65 28 20 70 43 75 72 2d 3e 70 53 74  while( pCur->pSt
18b0: 65 6d 20 29 3b 0a 20 20 70 43 75 72 2d 3e 72 4c  em );.  pCur->rL
18c0: 69 6d 69 74 20 3d 20 28 66 75 7a 7a 65 72 5f 63  imit = (fuzzer_c
18d0: 6f 73 74 29 30 3b 0a 20 20 69 66 28 20 63 6c 65  ost)0;.  if( cle
18e0: 61 72 48 61 73 68 20 29 20 6d 65 6d 73 65 74 28  arHash ) memset(
18f0: 70 43 75 72 2d 3e 61 70 48 61 73 68 2c 20 30 2c  pCur->apHash, 0,
1900: 20 73 69 7a 65 6f 66 28 70 43 75 72 2d 3e 61 70   sizeof(pCur->ap
1910: 48 61 73 68 29 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  Hash));.}../*.**
1920: 20 43 6c 6f 73 65 20 61 20 66 75 7a 7a 65 72 20   Close a fuzzer 
1930: 63 75 72 73 6f 72 2e 0a 2a 2f 0a 73 74 61 74 69  cursor..*/.stati
1940: 63 20 69 6e 74 20 66 75 7a 7a 65 72 43 6c 6f 73  c int fuzzerClos
1950: 65 28 73 71 6c 69 74 65 33 5f 76 74 61 62 5f 63  e(sqlite3_vtab_c
1960: 75 72 73 6f 72 20 2a 63 75 72 29 7b 0a 20 20 66  ursor *cur){.  f
1970: 75 7a 7a 65 72 5f 63 75 72 73 6f 72 20 2a 70 43  uzzer_cursor *pC
1980: 75 72 20 3d 20 28 66 75 7a 7a 65 72 5f 63 75 72  ur = (fuzzer_cur
1990: 73 6f 72 20 2a 29 63 75 72 3b 0a 20 20 66 75 7a  sor *)cur;.  fuz
19a0: 7a 65 72 43 6c 65 61 72 43 75 72 73 6f 72 28 70  zerClearCursor(p
19b0: 43 75 72 2c 20 30 29 3b 0a 20 20 73 71 6c 69 74  Cur, 0);.  sqlit
19c0: 65 33 5f 66 72 65 65 28 70 43 75 72 2d 3e 7a 42  e3_free(pCur->zB
19d0: 75 66 29 3b 0a 20 20 70 43 75 72 2d 3e 70 56 74  uf);.  pCur->pVt
19e0: 61 62 2d 3e 6e 43 75 72 73 6f 72 2d 2d 3b 0a 20  ab->nCursor--;. 
19f0: 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f   return SQLITE_O
1a00: 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 6f 6d 70  K;.}../*.** Comp
1a10: 75 74 65 20 74 68 65 20 63 75 72 72 65 6e 74 20  ute the current 
1a20: 6f 75 74 70 75 74 20 74 65 72 6d 20 66 6f 72 20  output term for 
1a30: 61 20 66 75 7a 7a 65 72 5f 73 74 65 6d 2e 0a 2a  a fuzzer_stem..*
1a40: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 66 75 7a  /.static int fuz
1a50: 7a 65 72 43 6f 6d 70 75 74 65 57 6f 72 64 28 0a  zerComputeWord(.
1a60: 20 20 66 75 7a 7a 65 72 5f 63 75 72 73 6f 72 20    fuzzer_cursor 
1a70: 2a 70 43 75 72 2c 0a 20 20 66 75 7a 7a 65 72 5f  *pCur,.  fuzzer_
1a80: 73 74 65 6d 20 2a 70 53 74 65 6d 0a 29 7b 0a 20  stem *pStem.){. 
1a90: 20 63 6f 6e 73 74 20 66 75 7a 7a 65 72 5f 72 75   const fuzzer_ru
1aa0: 6c 65 20 2a 70 52 75 6c 65 20 3d 20 70 53 74 65  le *pRule = pSte
1ab0: 6d 2d 3e 70 52 75 6c 65 3b 0a 20 20 69 6e 74 20  m->pRule;.  int 
1ac0: 6e 3b 0a 0a 20 20 6e 20 3d 20 70 53 74 65 6d 2d  n;..  n = pStem-
1ad0: 3e 6e 42 61 73 69 73 3b 0a 20 20 69 66 28 20 70  >nBasis;.  if( p
1ae0: 53 74 65 6d 2d 3e 6e 3e 3d 30 20 29 20 6e 20 2b  Stem->n>=0 ) n +
1af0: 3d 20 70 52 75 6c 65 2d 3e 6e 54 6f 20 2d 20 70  = pRule->nTo - p
1b00: 52 75 6c 65 2d 3e 6e 46 72 6f 6d 3b 0a 20 20 69  Rule->nFrom;.  i
1b10: 66 28 20 70 43 75 72 2d 3e 6e 42 75 66 3c 6e 2b  f( pCur->nBuf<n+
1b20: 31 20 29 7b 0a 20 20 20 20 70 43 75 72 2d 3e 7a  1 ){.    pCur->z
1b30: 42 75 66 20 3d 20 73 71 6c 69 74 65 33 5f 72 65  Buf = sqlite3_re
1b40: 61 6c 6c 6f 63 28 70 43 75 72 2d 3e 7a 42 75 66  alloc(pCur->zBuf
1b50: 2c 20 6e 2b 31 30 30 29 3b 0a 20 20 20 20 69 66  , n+100);.    if
1b60: 28 20 70 43 75 72 2d 3e 7a 42 75 66 3d 3d 30 20  ( pCur->zBuf==0 
1b70: 29 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f  ) return SQLITE_
1b80: 4e 4f 4d 45 4d 3b 0a 20 20 20 20 70 43 75 72 2d  NOMEM;.    pCur-
1b90: 3e 6e 42 75 66 20 3d 20 6e 2b 31 30 30 3b 0a 20  >nBuf = n+100;. 
1ba0: 20 7d 0a 20 20 6e 20 3d 20 70 53 74 65 6d 2d 3e   }.  n = pStem->
1bb0: 6e 3b 0a 20 20 69 66 28 20 6e 3c 30 20 29 7b 0a  n;.  if( n<0 ){.
1bc0: 20 20 20 20 6d 65 6d 63 70 79 28 70 43 75 72 2d      memcpy(pCur-
1bd0: 3e 7a 42 75 66 2c 20 70 53 74 65 6d 2d 3e 7a 42  >zBuf, pStem->zB
1be0: 61 73 69 73 2c 20 70 53 74 65 6d 2d 3e 6e 42 61  asis, pStem->nBa
1bf0: 73 69 73 2b 31 29 3b 0a 20 20 7d 65 6c 73 65 7b  sis+1);.  }else{
1c00: 0a 20 20 20 20 6d 65 6d 63 70 79 28 70 43 75 72  .    memcpy(pCur
1c10: 2d 3e 7a 42 75 66 2c 20 70 53 74 65 6d 2d 3e 7a  ->zBuf, pStem->z
1c20: 42 61 73 69 73 2c 20 6e 29 3b 0a 20 20 20 20 6d  Basis, n);.    m
1c30: 65 6d 63 70 79 28 26 70 43 75 72 2d 3e 7a 42 75  emcpy(&pCur->zBu
1c40: 66 5b 6e 5d 2c 20 70 52 75 6c 65 2d 3e 7a 54 6f  f[n], pRule->zTo
1c50: 2c 20 70 52 75 6c 65 2d 3e 6e 54 6f 29 3b 0a 20  , pRule->nTo);. 
1c60: 20 20 20 6d 65 6d 63 70 79 28 26 70 43 75 72 2d     memcpy(&pCur-
1c70: 3e 7a 42 75 66 5b 6e 2b 70 52 75 6c 65 2d 3e 6e  >zBuf[n+pRule->n
1c80: 54 6f 5d 2c 20 26 70 53 74 65 6d 2d 3e 7a 42 61  To], &pStem->zBa
1c90: 73 69 73 5b 6e 2b 70 52 75 6c 65 2d 3e 6e 46 72  sis[n+pRule->nFr
1ca0: 6f 6d 5d 2c 20 0a 20 20 20 20 20 20 20 20 20 20  om], .          
1cb0: 20 70 53 74 65 6d 2d 3e 6e 42 61 73 69 73 2d 6e   pStem->nBasis-n
1cc0: 2d 70 52 75 6c 65 2d 3e 6e 46 72 6f 6d 2b 31 29  -pRule->nFrom+1)
1cd0: 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 53  ;.  }.  return S
1ce0: 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 0a 2f 2a  QLITE_OK;.}.../*
1cf0: 0a 2a 2a 20 43 6f 6d 70 75 74 65 20 61 20 68 61  .** Compute a ha
1d00: 73 68 20 6f 6e 20 7a 42 61 73 69 73 2e 0a 2a 2f  sh on zBasis..*/
1d10: 0a 73 74 61 74 69 63 20 75 6e 73 69 67 6e 65 64  .static unsigned
1d20: 20 69 6e 74 20 66 75 7a 7a 65 72 48 61 73 68 28   int fuzzerHash(
1d30: 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 29 7b 0a  const char *z){.
1d40: 20 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 68    unsigned int h
1d50: 20 3d 20 30 3b 0a 20 20 77 68 69 6c 65 28 20 2a   = 0;.  while( *
1d60: 7a 20 29 7b 20 68 20 3d 20 28 68 3c 3c 33 29 20  z ){ h = (h<<3) 
1d70: 5e 20 28 68 3e 3e 32 39 29 20 5e 20 2a 28 7a 2b  ^ (h>>29) ^ *(z+
1d80: 2b 29 3b 20 7d 0a 20 20 72 65 74 75 72 6e 20 68  +); }.  return h
1d90: 25 31 30 30 30 37 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  %10007;.}../*.**
1da0: 20 43 75 72 72 65 6e 74 20 63 6f 73 74 20 6f 66   Current cost of
1db0: 20 61 20 73 74 65 6d 0a 2a 2f 0a 73 74 61 74 69   a stem.*/.stati
1dc0: 63 20 66 75 7a 7a 65 72 5f 63 6f 73 74 20 66 75  c fuzzer_cost fu
1dd0: 7a 7a 65 72 43 6f 73 74 28 66 75 7a 7a 65 72 5f  zzerCost(fuzzer_
1de0: 73 74 65 6d 20 2a 70 53 74 65 6d 29 7b 0a 20 20  stem *pStem){.  
1df0: 72 65 74 75 72 6e 20 70 53 74 65 6d 2d 3e 72 42  return pStem->rB
1e00: 61 73 65 43 6f 73 74 20 2b 20 70 53 74 65 6d 2d  aseCost + pStem-
1e10: 3e 70 52 75 6c 65 2d 3e 72 43 6f 73 74 3b 0a 7d  >pRule->rCost;.}
1e20: 0a 0a 2f 2a 0a 2a 2a 20 41 64 76 61 6e 63 65 20  ../*.** Advance 
1e30: 61 20 66 75 7a 7a 65 72 5f 73 74 65 6d 20 74 6f  a fuzzer_stem to
1e40: 20 69 74 73 20 6e 65 78 74 20 76 61 6c 75 65 2e   its next value.
1e50: 20 20 20 52 65 74 75 72 6e 20 30 20 69 66 20 74     Return 0 if t
1e60: 68 65 72 65 20 61 72 65 0a 2a 2a 20 6e 6f 20 6d  here are.** no m
1e70: 6f 72 65 20 76 61 6c 75 65 73 20 74 68 61 74 20  ore values that 
1e80: 63 61 6e 20 62 65 20 67 65 6e 65 72 61 74 65 64  can be generated
1e90: 20 62 79 20 74 68 69 73 20 66 75 7a 7a 65 72 5f   by this fuzzer_
1ea0: 73 74 65 6d 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  stem..*/.static 
1eb0: 69 6e 74 20 66 75 7a 7a 65 72 41 64 76 61 6e 63  int fuzzerAdvanc
1ec0: 65 28 66 75 7a 7a 65 72 5f 63 75 72 73 6f 72 20  e(fuzzer_cursor 
1ed0: 2a 70 43 75 72 2c 20 66 75 7a 7a 65 72 5f 73 74  *pCur, fuzzer_st
1ee0: 65 6d 20 2a 70 53 74 65 6d 29 7b 0a 20 20 63 6f  em *pStem){.  co
1ef0: 6e 73 74 20 66 75 7a 7a 65 72 5f 72 75 6c 65 20  nst fuzzer_rule 
1f00: 2a 70 52 75 6c 65 3b 0a 20 20 77 68 69 6c 65 28  *pRule;.  while(
1f10: 20 28 70 52 75 6c 65 20 3d 20 70 53 74 65 6d 2d   (pRule = pStem-
1f20: 3e 70 52 75 6c 65 29 21 3d 30 20 29 7b 0a 20 20  >pRule)!=0 ){.  
1f30: 20 20 77 68 69 6c 65 28 20 70 53 74 65 6d 2d 3e    while( pStem->
1f40: 6e 20 3c 20 70 53 74 65 6d 2d 3e 6e 42 61 73 69  n < pStem->nBasi
1f50: 73 20 2d 20 70 52 75 6c 65 2d 3e 6e 46 72 6f 6d  s - pRule->nFrom
1f60: 20 29 7b 0a 20 20 20 20 20 20 70 53 74 65 6d 2d   ){.      pStem-
1f70: 3e 6e 2b 2b 3b 0a 20 20 20 20 20 20 69 66 28 20  >n++;.      if( 
1f80: 70 52 75 6c 65 2d 3e 6e 46 72 6f 6d 3d 3d 30 0a  pRule->nFrom==0.
1f90: 20 20 20 20 20 20 20 7c 7c 20 6d 65 6d 63 6d 70         || memcmp
1fa0: 28 26 70 53 74 65 6d 2d 3e 7a 42 61 73 69 73 5b  (&pStem->zBasis[
1fb0: 70 53 74 65 6d 2d 3e 6e 5d 2c 20 70 52 75 6c 65  pStem->n], pRule
1fc0: 2d 3e 7a 46 72 6f 6d 2c 20 70 52 75 6c 65 2d 3e  ->zFrom, pRule->
1fd0: 6e 46 72 6f 6d 29 3d 3d 30 0a 20 20 20 20 20 20  nFrom)==0.      
1fe0: 29 7b 0a 20 20 20 20 20 20 20 20 2f 2a 20 46 6f  ){.        /* Fo
1ff0: 75 6e 64 20 61 20 72 65 77 72 69 74 65 20 63 61  und a rewrite ca
2000: 73 65 2e 20 20 4d 61 6b 65 20 73 75 72 65 20 69  se.  Make sure i
2010: 74 20 69 73 20 6e 6f 74 20 61 20 64 75 70 6c 69  t is not a dupli
2020: 63 61 74 65 20 2a 2f 0a 20 20 20 20 20 20 20 20  cate */.        
2030: 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 68 3b 0a  unsigned int h;.
2040: 20 20 20 20 20 20 20 20 66 75 7a 7a 65 72 5f 73          fuzzer_s
2050: 74 65 6d 20 2a 70 4c 6f 6f 6b 75 70 3b 0a 0a 20  tem *pLookup;.. 
2060: 20 20 20 20 20 20 20 66 75 7a 7a 65 72 43 6f 6d         fuzzerCom
2070: 70 75 74 65 57 6f 72 64 28 70 43 75 72 2c 20 70  puteWord(pCur, p
2080: 53 74 65 6d 29 3b 0a 20 20 20 20 20 20 20 20 68  Stem);.        h
2090: 20 3d 20 66 75 7a 7a 65 72 48 61 73 68 28 70 43   = fuzzerHash(pC
20a0: 75 72 2d 3e 7a 42 75 66 29 3b 0a 20 20 20 20 20  ur->zBuf);.     
20b0: 20 20 20 70 4c 6f 6f 6b 75 70 20 3d 20 70 43 75     pLookup = pCu
20c0: 72 2d 3e 61 70 48 61 73 68 5b 68 5d 3b 0a 20 20  r->apHash[h];.  
20d0: 20 20 20 20 20 20 77 68 69 6c 65 28 20 70 4c 6f        while( pLo
20e0: 6f 6b 75 70 20 26 26 20 73 74 72 63 6d 70 28 70  okup && strcmp(p
20f0: 4c 6f 6f 6b 75 70 2d 3e 7a 42 61 73 69 73 2c 20  Lookup->zBasis, 
2100: 70 43 75 72 2d 3e 7a 42 75 66 29 21 3d 30 20 29  pCur->zBuf)!=0 )
2110: 7b 0a 20 20 20 20 20 20 20 20 20 20 70 4c 6f 6f  {.          pLoo
2120: 6b 75 70 20 3d 20 70 4c 6f 6f 6b 75 70 2d 3e 70  kup = pLookup->p
2130: 48 61 73 68 3b 0a 20 20 20 20 20 20 20 20 7d 0a  Hash;.        }.
2140: 20 20 20 20 20 20 20 20 69 66 28 20 70 4c 6f 6f          if( pLoo
2150: 6b 75 70 3d 3d 30 20 29 20 72 65 74 75 72 6e 20  kup==0 ) return 
2160: 31 3b 20 20 2f 2a 20 41 20 6e 65 77 20 6f 75 74  1;  /* A new out
2170: 70 75 74 20 69 73 20 66 6f 75 6e 64 2e 20 2a 2f  put is found. */
2180: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20  .      }.    }. 
2190: 20 20 20 70 53 74 65 6d 2d 3e 6e 20 3d 20 2d 31     pStem->n = -1
21a0: 3b 0a 20 20 20 20 70 53 74 65 6d 2d 3e 70 52 75  ;.    pStem->pRu
21b0: 6c 65 20 3d 20 70 52 75 6c 65 2d 3e 70 4e 65 78  le = pRule->pNex
21c0: 74 3b 0a 20 20 20 20 69 66 28 20 66 75 7a 7a 65  t;.    if( fuzze
21d0: 72 43 6f 73 74 28 70 53 74 65 6d 29 3e 70 43 75  rCost(pStem)>pCu
21e0: 72 2d 3e 72 4c 69 6d 69 74 20 29 20 70 53 74 65  r->rLimit ) pSte
21f0: 6d 2d 3e 70 52 75 6c 65 20 3d 20 30 3b 0a 20 20  m->pRule = 0;.  
2200: 7d 0a 20 20 72 65 74 75 72 6e 20 30 3b 0a 7d 0a  }.  return 0;.}.
2210: 0a 2f 2a 0a 2a 2a 20 49 6e 73 65 72 74 20 70 4e  ./*.** Insert pN
2220: 65 77 20 69 6e 74 6f 20 74 68 65 20 6c 69 73 74  ew into the list
2230: 20 61 74 20 70 4c 69 73 74 2e 20 20 52 65 74 75   at pList.  Retu
2240: 72 6e 20 61 20 70 6f 69 6e 74 65 72 20 74 6f 20  rn a pointer to 
2250: 74 68 65 20 6e 65 77 0a 2a 2a 20 6c 69 73 74 2e  the new.** list.
2260: 20 20 54 68 65 20 69 6e 73 65 72 74 20 69 73 20    The insert is 
2270: 64 6f 6e 65 20 73 75 63 68 20 74 68 65 20 70 4e  done such the pN
2280: 65 77 20 69 73 20 69 6e 20 74 68 65 20 63 6f 72  ew is in the cor
2290: 72 65 63 74 20 6f 72 64 65 72 0a 2a 2a 20 61 63  rect order.** ac
22a0: 63 6f 72 64 69 6e 67 20 74 6f 20 66 75 7a 7a 65  cording to fuzze
22b0: 72 5f 73 74 65 6d 2e 7a 42 61 73 65 43 6f 73 74  r_stem.zBaseCost
22c0: 2b 66 75 7a 7a 65 72 5f 73 74 65 6d 2e 70 52 75  +fuzzer_stem.pRu
22d0: 6c 65 2d 3e 72 43 6f 73 74 2e 0a 2a 2f 0a 73 74  le->rCost..*/.st
22e0: 61 74 69 63 20 66 75 7a 7a 65 72 5f 73 74 65 6d  atic fuzzer_stem
22f0: 20 2a 66 75 7a 7a 65 72 49 6e 73 65 72 74 28 66   *fuzzerInsert(f
2300: 75 7a 7a 65 72 5f 73 74 65 6d 20 2a 70 4c 69 73  uzzer_stem *pLis
2310: 74 2c 20 66 75 7a 7a 65 72 5f 73 74 65 6d 20 2a  t, fuzzer_stem *
2320: 70 4e 65 77 29 7b 0a 20 20 66 75 7a 7a 65 72 5f  pNew){.  fuzzer_
2330: 63 6f 73 74 20 63 31 3b 0a 0a 20 20 63 31 20 3d  cost c1;..  c1 =
2340: 20 66 75 7a 7a 65 72 43 6f 73 74 28 70 4e 65 77   fuzzerCost(pNew
2350: 29 3b 0a 20 20 69 66 28 20 63 31 20 3c 3d 20 66  );.  if( c1 <= f
2360: 75 7a 7a 65 72 43 6f 73 74 28 70 4c 69 73 74 29  uzzerCost(pList)
2370: 20 29 7b 0a 20 20 20 20 70 4e 65 77 2d 3e 70 4e   ){.    pNew->pN
2380: 65 78 74 20 3d 20 70 4c 69 73 74 3b 0a 20 20 20  ext = pList;.   
2390: 20 72 65 74 75 72 6e 20 70 4e 65 77 3b 0a 20 20   return pNew;.  
23a0: 7d 65 6c 73 65 7b 0a 20 20 20 20 66 75 7a 7a 65  }else{.    fuzze
23b0: 72 5f 73 74 65 6d 20 2a 70 50 72 65 76 3b 0a 20  r_stem *pPrev;. 
23c0: 20 20 20 70 50 72 65 76 20 3d 20 70 4c 69 73 74     pPrev = pList
23d0: 3b 0a 20 20 20 20 77 68 69 6c 65 28 20 70 50 72  ;.    while( pPr
23e0: 65 76 2d 3e 70 4e 65 78 74 20 26 26 20 66 75 7a  ev->pNext && fuz
23f0: 7a 65 72 43 6f 73 74 28 70 50 72 65 76 2d 3e 70  zerCost(pPrev->p
2400: 4e 65 78 74 29 3c 63 31 20 29 7b 0a 20 20 20 20  Next)<c1 ){.    
2410: 20 20 70 50 72 65 76 20 3d 20 70 50 72 65 76 2d    pPrev = pPrev-
2420: 3e 70 4e 65 78 74 3b 0a 20 20 20 20 7d 0a 20 20  >pNext;.    }.  
2430: 20 20 70 4e 65 77 2d 3e 70 4e 65 78 74 20 3d 20    pNew->pNext = 
2440: 70 50 72 65 76 2d 3e 70 4e 65 78 74 3b 0a 20 20  pPrev->pNext;.  
2450: 20 20 70 50 72 65 76 2d 3e 70 4e 65 78 74 20 3d    pPrev->pNext =
2460: 20 70 4e 65 77 3b 0a 20 20 20 20 72 65 74 75 72   pNew;.    retur
2470: 6e 20 70 4c 69 73 74 3b 0a 20 20 7d 0a 7d 0a 0a  n pList;.  }.}..
2480: 2f 2a 0a 2a 2a 20 41 6c 6c 6f 63 61 74 65 20 61  /*.** Allocate a
2490: 20 6e 65 77 20 66 75 7a 7a 65 72 5f 73 74 65 6d   new fuzzer_stem
24a0: 2e 20 20 41 64 64 20 69 74 20 74 6f 20 74 68 65  .  Add it to the
24b0: 20 68 61 73 68 20 74 61 62 6c 65 20 62 75 74 20   hash table but 
24c0: 64 6f 20 6e 6f 74 0a 2a 2a 20 6c 69 6e 6b 20 69  do not.** link i
24d0: 74 20 69 6e 74 6f 20 65 69 74 68 65 72 20 74 68  t into either th
24e0: 65 20 70 43 75 72 2d 3e 70 53 74 65 6d 20 6f 72  e pCur->pStem or
24f0: 20 70 43 75 72 2d 3e 70 44 6f 6e 65 20 6c 69 73   pCur->pDone lis
2500: 74 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 66 75  ts..*/.static fu
2510: 7a 7a 65 72 5f 73 74 65 6d 20 2a 66 75 7a 7a 65  zzer_stem *fuzze
2520: 72 4e 65 77 53 74 65 6d 28 0a 20 20 66 75 7a 7a  rNewStem(.  fuzz
2530: 65 72 5f 63 75 72 73 6f 72 20 2a 70 43 75 72 2c  er_cursor *pCur,
2540: 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a  .  const char *z
2550: 57 6f 72 64 2c 0a 20 20 66 75 7a 7a 65 72 5f 63  Word,.  fuzzer_c
2560: 6f 73 74 20 72 42 61 73 65 43 6f 73 74 0a 29 7b  ost rBaseCost.){
2570: 0a 20 20 66 75 7a 7a 65 72 5f 73 74 65 6d 20 2a  .  fuzzer_stem *
2580: 70 4e 65 77 3b 0a 20 20 75 6e 73 69 67 6e 65 64  pNew;.  unsigned
2590: 20 69 6e 74 20 68 3b 0a 0a 20 20 70 4e 65 77 20   int h;..  pNew 
25a0: 3d 20 73 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63  = sqlite3_malloc
25b0: 28 20 73 69 7a 65 6f 66 28 2a 70 4e 65 77 29 20  ( sizeof(*pNew) 
25c0: 2b 20 73 74 72 6c 65 6e 28 7a 57 6f 72 64 29 20  + strlen(zWord) 
25d0: 2b 20 31 20 29 3b 0a 20 20 69 66 28 20 70 4e 65  + 1 );.  if( pNe
25e0: 77 3d 3d 30 20 29 20 72 65 74 75 72 6e 20 30 3b  w==0 ) return 0;
25f0: 0a 20 20 6d 65 6d 73 65 74 28 70 4e 65 77 2c 20  .  memset(pNew, 
2600: 30 2c 20 73 69 7a 65 6f 66 28 2a 70 4e 65 77 29  0, sizeof(*pNew)
2610: 29 3b 0a 20 20 70 4e 65 77 2d 3e 7a 42 61 73 69  );.  pNew->zBasi
2620: 73 20 3d 20 28 63 68 61 72 2a 29 26 70 4e 65 77  s = (char*)&pNew
2630: 5b 31 5d 3b 0a 20 20 70 4e 65 77 2d 3e 6e 42 61  [1];.  pNew->nBa
2640: 73 69 73 20 3d 20 73 74 72 6c 65 6e 28 7a 57 6f  sis = strlen(zWo
2650: 72 64 29 3b 0a 20 20 6d 65 6d 63 70 79 28 70 4e  rd);.  memcpy(pN
2660: 65 77 2d 3e 7a 42 61 73 69 73 2c 20 7a 57 6f 72  ew->zBasis, zWor
2670: 64 2c 20 70 4e 65 77 2d 3e 6e 42 61 73 69 73 2b  d, pNew->nBasis+
2680: 31 29 3b 0a 20 20 70 4e 65 77 2d 3e 70 52 75 6c  1);.  pNew->pRul
2690: 65 20 3d 20 70 43 75 72 2d 3e 70 56 74 61 62 2d  e = pCur->pVtab-
26a0: 3e 70 52 75 6c 65 3b 0a 20 20 70 4e 65 77 2d 3e  >pRule;.  pNew->
26b0: 6e 20 3d 20 2d 31 3b 0a 20 20 70 4e 65 77 2d 3e  n = -1;.  pNew->
26c0: 72 42 61 73 65 43 6f 73 74 20 3d 20 72 42 61 73  rBaseCost = rBas
26d0: 65 43 6f 73 74 3b 0a 20 20 68 20 3d 20 66 75 7a  eCost;.  h = fuz
26e0: 7a 65 72 48 61 73 68 28 70 4e 65 77 2d 3e 7a 42  zerHash(pNew->zB
26f0: 61 73 69 73 29 3b 0a 20 20 70 4e 65 77 2d 3e 70  asis);.  pNew->p
2700: 48 61 73 68 20 3d 20 70 43 75 72 2d 3e 61 70 48  Hash = pCur->apH
2710: 61 73 68 5b 68 5d 3b 0a 20 20 70 43 75 72 2d 3e  ash[h];.  pCur->
2720: 61 70 48 61 73 68 5b 68 5d 20 3d 20 70 4e 65 77  apHash[h] = pNew
2730: 3b 0a 20 20 72 65 74 75 72 6e 20 70 4e 65 77 3b  ;.  return pNew;
2740: 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 41 64 76 61 6e  .}.../*.** Advan
2750: 63 65 20 61 20 63 75 72 73 6f 72 20 74 6f 20 69  ce a cursor to i
2760: 74 73 20 6e 65 78 74 20 72 6f 77 20 6f 66 20 6f  ts next row of o
2770: 75 74 70 75 74 0a 2a 2f 0a 73 74 61 74 69 63 20  utput.*/.static 
2780: 69 6e 74 20 66 75 7a 7a 65 72 4e 65 78 74 28 73  int fuzzerNext(s
2790: 71 6c 69 74 65 33 5f 76 74 61 62 5f 63 75 72 73  qlite3_vtab_curs
27a0: 6f 72 20 2a 63 75 72 29 7b 0a 20 20 66 75 7a 7a  or *cur){.  fuzz
27b0: 65 72 5f 63 75 72 73 6f 72 20 2a 70 43 75 72 20  er_cursor *pCur 
27c0: 3d 20 28 66 75 7a 7a 65 72 5f 63 75 72 73 6f 72  = (fuzzer_cursor
27d0: 2a 29 70 43 75 72 3b 0a 20 20 66 75 7a 7a 65 72  *)pCur;.  fuzzer
27e0: 5f 73 74 65 6d 20 2a 70 53 74 65 6d 2c 20 2a 70  _stem *pStem, *p
27f0: 4e 65 77 3b 0a 0a 20 20 2f 2a 20 55 73 65 20 74  New;..  /* Use t
2800: 68 65 20 65 6c 65 6d 65 6e 74 20 74 68 65 20 63  he element the c
2810: 75 72 73 6f 72 20 69 73 20 63 75 72 72 65 6e 74  ursor is current
2820: 6c 79 20 70 6f 69 6e 74 20 74 6f 20 74 6f 20 63  ly point to to c
2830: 72 65 61 74 65 0a 20 20 2a 2a 20 61 20 6e 65 77  reate.  ** a new
2840: 20 73 74 65 6d 20 61 6e 64 20 69 6e 73 65 72 74   stem and insert
2850: 20 74 68 65 20 6e 65 77 20 73 74 65 6d 20 69 6e   the new stem in
2860: 74 6f 20 74 68 65 20 70 72 69 6f 72 69 74 79 20  to the priority 
2870: 71 75 65 75 65 2e 0a 20 20 2a 2f 0a 20 20 66 75  queue..  */.  fu
2880: 7a 7a 65 72 43 6f 6d 70 75 74 65 57 6f 72 64 28  zzerComputeWord(
2890: 70 43 75 72 2c 20 70 43 75 72 2d 3e 70 53 74 65  pCur, pCur->pSte
28a0: 6d 29 3b 0a 20 20 70 4e 65 77 20 3d 20 66 75 7a  m);.  pNew = fuz
28b0: 7a 65 72 4e 65 77 53 74 65 6d 28 70 43 75 72 2c  zerNewStem(pCur,
28c0: 20 70 43 75 72 2d 3e 7a 42 75 66 2c 20 66 75 7a   pCur->zBuf, fuz
28d0: 7a 65 72 43 6f 73 74 28 70 43 75 72 2d 3e 70 53  zerCost(pCur->pS
28e0: 74 65 6d 29 29 3b 0a 20 20 69 66 28 20 70 4e 65  tem));.  if( pNe
28f0: 77 20 29 7b 0a 20 20 20 20 69 66 28 20 66 75 7a  w ){.    if( fuz
2900: 7a 65 72 41 64 76 61 6e 63 65 28 70 43 75 72 2c  zerAdvance(pCur,
2910: 20 70 4e 65 77 29 3d 3d 30 20 29 7b 0a 20 20 20   pNew)==0 ){.   
2920: 20 20 20 70 4e 65 77 2d 3e 70 4e 65 78 74 20 3d     pNew->pNext =
2930: 20 70 43 75 72 2d 3e 70 44 6f 6e 65 3b 0a 20 20   pCur->pDone;.  
2940: 20 20 20 20 70 43 75 72 2d 3e 70 44 6f 6e 65 20      pCur->pDone 
2950: 3d 20 70 4e 65 77 3b 0a 20 20 20 20 7d 65 6c 73  = pNew;.    }els
2960: 65 7b 0a 20 20 20 20 20 20 70 43 75 72 2d 3e 70  e{.      pCur->p
2970: 53 74 65 6d 20 3d 20 66 75 7a 7a 65 72 49 6e 73  Stem = fuzzerIns
2980: 65 72 74 28 70 43 75 72 2d 3e 70 53 74 65 6d 2c  ert(pCur->pStem,
2990: 20 70 4e 65 77 29 3b 0a 20 20 20 20 7d 0a 20 20   pNew);.    }.  
29a0: 7d 0a 0a 20 20 2f 2a 20 41 64 6a 75 73 74 20 74  }..  /* Adjust t
29b0: 68 65 20 70 72 69 6f 72 69 74 79 20 71 75 65 75  he priority queu
29c0: 65 20 73 6f 20 74 68 61 74 20 74 68 65 20 66 69  e so that the fi
29d0: 72 73 74 20 65 6c 65 6d 65 6e 74 20 6f 66 20 74  rst element of t
29e0: 68 65 0a 20 20 2a 2a 20 73 74 65 6d 20 6c 69 73  he.  ** stem lis
29f0: 74 20 69 73 20 74 68 65 20 6e 65 78 74 20 6c 6f  t is the next lo
2a00: 77 65 73 74 20 63 6f 73 74 20 77 6f 72 64 2e 0a  west cost word..
2a10: 20 20 2a 2f 0a 20 20 77 68 69 6c 65 28 20 28 70    */.  while( (p
2a20: 53 74 65 6d 20 3d 20 70 43 75 72 2d 3e 70 53 74  Stem = pCur->pSt
2a30: 65 6d 29 21 3d 30 20 29 7b 0a 20 20 20 20 69 66  em)!=0 ){.    if
2a40: 28 20 66 75 7a 7a 65 72 41 64 76 61 6e 63 65 28  ( fuzzerAdvance(
2a50: 70 43 75 72 2c 20 70 53 74 65 6d 29 20 29 7b 0a  pCur, pStem) ){.
2a60: 20 20 20 20 20 20 70 43 75 72 2d 3e 70 53 74 65        pCur->pSte
2a70: 6d 20 3d 20 66 75 7a 7a 65 72 49 6e 73 65 72 74  m = fuzzerInsert
2a80: 28 70 53 74 65 6d 2d 3e 70 4e 65 78 74 2c 20 70  (pStem->pNext, p
2a90: 53 74 65 6d 29 3b 0a 20 20 20 20 20 20 72 65 74  Stem);.      ret
2aa0: 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 20 20  urn SQLITE_OK;  
2ab0: 2f 2a 20 4e 65 77 20 77 6f 72 64 20 66 6f 75 6e  /* New word foun
2ac0: 64 20 2a 2f 0a 20 20 20 20 7d 0a 20 20 20 20 70  d */.    }.    p
2ad0: 43 75 72 2d 3e 70 53 74 65 6d 20 3d 20 70 53 74  Cur->pStem = pSt
2ae0: 65 6d 2d 3e 70 4e 65 78 74 3b 0a 20 20 20 20 70  em->pNext;.    p
2af0: 53 74 65 6d 2d 3e 70 4e 65 78 74 20 3d 20 70 43  Stem->pNext = pC
2b00: 75 72 2d 3e 70 44 6f 6e 65 3b 0a 20 20 20 20 70  ur->pDone;.    p
2b10: 43 75 72 2d 3e 70 44 6f 6e 65 20 3d 20 70 53 74  Cur->pDone = pSt
2b20: 65 6d 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 52 65  em;.  }..  /* Re
2b30: 61 63 68 20 74 68 69 73 20 70 6f 69 6e 74 20 6f  ach this point o
2b40: 6e 6c 79 20 69 66 20 71 75 65 75 65 20 68 61 73  nly if queue has
2b50: 20 62 65 65 6e 20 65 78 68 61 75 73 74 65 64 20   been exhausted 
2b60: 61 6e 64 20 74 68 65 72 65 20 69 73 0a 20 20 2a  and there is.  *
2b70: 2a 20 6e 6f 74 68 69 6e 67 20 6c 65 66 74 20 74  * nothing left t
2b80: 6f 20 62 65 20 6f 75 74 70 75 74 2e 20 2a 2f 0a  o be output. */.
2b90: 20 20 70 43 75 72 2d 3e 72 4c 69 6d 69 74 20 3d    pCur->rLimit =
2ba0: 20 28 66 75 7a 7a 65 72 5f 63 6f 73 74 29 30 3b   (fuzzer_cost)0;
2bb0: 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45  .  return SQLITE
2bc0: 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 61  _OK;.}../*.** Ca
2bd0: 6c 6c 65 64 20 74 6f 20 22 72 65 77 69 6e 64 22  lled to "rewind"
2be0: 20 61 20 63 75 72 73 6f 72 20 62 61 63 6b 20 74   a cursor back t
2bf0: 6f 20 74 68 65 20 62 65 67 69 6e 6e 69 6e 67 20  o the beginning 
2c00: 73 6f 20 74 68 61 74 0a 2a 2a 20 69 74 20 73 74  so that.** it st
2c10: 61 72 74 73 20 69 74 73 20 6f 75 74 70 75 74 20  arts its output 
2c20: 6f 76 65 72 20 61 67 61 69 6e 2e 20 20 41 6c 77  over again.  Alw
2c30: 61 79 73 20 63 61 6c 6c 65 64 20 61 74 20 6c 65  ays called at le
2c40: 61 73 74 20 6f 6e 63 65 0a 2a 2a 20 70 72 69 6f  ast once.** prio
2c50: 72 20 74 6f 20 61 6e 79 20 66 75 7a 7a 65 72 43  r to any fuzzerC
2c60: 6f 6c 75 6d 6e 2c 20 66 75 7a 7a 65 72 52 6f 77  olumn, fuzzerRow
2c70: 69 64 2c 20 6f 72 20 66 75 7a 7a 65 72 45 6f 66  id, or fuzzerEof
2c80: 20 63 61 6c 6c 2e 0a 2a 2f 0a 73 74 61 74 69 63   call..*/.static
2c90: 20 69 6e 74 20 66 75 7a 7a 65 72 46 69 6c 74 65   int fuzzerFilte
2ca0: 72 28 0a 20 20 73 71 6c 69 74 65 33 5f 76 74 61  r(.  sqlite3_vta
2cb0: 62 5f 63 75 72 73 6f 72 20 2a 70 56 74 61 62 43  b_cursor *pVtabC
2cc0: 75 72 73 6f 72 2c 20 0a 20 20 69 6e 74 20 69 64  ursor, .  int id
2cd0: 78 4e 75 6d 2c 20 63 6f 6e 73 74 20 63 68 61 72  xNum, const char
2ce0: 20 2a 69 64 78 53 74 72 2c 0a 20 20 69 6e 74 20   *idxStr,.  int 
2cf0: 61 72 67 63 2c 20 73 71 6c 69 74 65 33 5f 76 61  argc, sqlite3_va
2d00: 6c 75 65 20 2a 2a 61 72 67 76 0a 29 7b 0a 20 20  lue **argv.){.  
2d10: 66 75 7a 7a 65 72 5f 63 75 72 73 6f 72 20 2a 70  fuzzer_cursor *p
2d20: 43 75 72 20 3d 20 28 66 75 7a 7a 65 72 5f 63 75  Cur = (fuzzer_cu
2d30: 72 73 6f 72 20 2a 29 70 56 74 61 62 43 75 72 73  rsor *)pVtabCurs
2d40: 6f 72 3b 0a 20 20 63 6f 6e 73 74 20 63 68 61 72  or;.  const char
2d50: 20 2a 7a 57 6f 72 64 20 3d 20 30 3b 0a 20 20 70   *zWord = 0;.  p
2d60: 43 75 72 2d 3e 72 4c 69 6d 69 74 20 3d 20 32 31  Cur->rLimit = 21
2d70: 34 37 34 38 33 36 34 37 3b 0a 0a 20 20 66 75 7a  47483647;..  fuz
2d80: 7a 65 72 43 6c 65 61 72 43 75 72 73 6f 72 28 70  zerClearCursor(p
2d90: 43 75 72 2c 20 31 29 3b 0a 20 20 69 66 28 20 69  Cur, 1);.  if( i
2da0: 64 78 4e 75 6d 3d 3d 31 20 29 7b 0a 20 20 20 20  dxNum==1 ){.    
2db0: 7a 57 6f 72 64 20 3d 20 28 63 6f 6e 73 74 20 63  zWord = (const c
2dc0: 68 61 72 2a 29 73 71 6c 69 74 65 33 5f 76 61 6c  har*)sqlite3_val
2dd0: 75 65 5f 74 65 78 74 28 61 72 67 76 5b 30 5d 29  ue_text(argv[0])
2de0: 3b 0a 20 20 7d 65 6c 73 65 20 69 66 28 20 69 64  ;.  }else if( id
2df0: 78 4e 75 6d 3d 3d 32 20 29 7b 0a 20 20 20 20 70  xNum==2 ){.    p
2e00: 43 75 72 2d 3e 72 4c 69 6d 69 74 20 3d 20 28 66  Cur->rLimit = (f
2e10: 75 7a 7a 65 72 5f 63 6f 73 74 29 73 71 6c 69 74  uzzer_cost)sqlit
2e20: 65 33 5f 76 61 6c 75 65 5f 69 6e 74 28 61 72 67  e3_value_int(arg
2e30: 76 5b 30 5d 29 3b 0a 20 20 7d 65 6c 73 65 20 69  v[0]);.  }else i
2e40: 66 28 20 69 64 78 4e 75 6d 3d 3d 33 20 29 7b 0a  f( idxNum==3 ){.
2e50: 20 20 20 20 7a 57 6f 72 64 20 3d 20 28 63 6f 6e      zWord = (con
2e60: 73 74 20 63 68 61 72 2a 29 73 71 6c 69 74 65 33  st char*)sqlite3
2e70: 5f 76 61 6c 75 65 5f 74 65 78 74 28 61 72 67 76  _value_text(argv
2e80: 5b 30 5d 29 3b 0a 20 20 20 20 70 43 75 72 2d 3e  [0]);.    pCur->
2e90: 72 4c 69 6d 69 74 20 3d 20 28 66 75 7a 7a 65 72  rLimit = (fuzzer
2ea0: 5f 63 6f 73 74 29 73 71 6c 69 74 65 33 5f 76 61  _cost)sqlite3_va
2eb0: 6c 75 65 5f 69 6e 74 28 61 72 67 76 5b 31 5d 29  lue_int(argv[1])
2ec0: 3b 0a 20 20 7d 0a 20 20 69 66 28 20 7a 57 6f 72  ;.  }.  if( zWor
2ed0: 64 3d 3d 30 20 29 20 7a 57 6f 72 64 20 3d 20 22  d==0 ) zWord = "
2ee0: 22 3b 0a 20 20 70 43 75 72 2d 3e 70 53 74 65 6d  ";.  pCur->pStem
2ef0: 20 3d 20 66 75 7a 7a 65 72 4e 65 77 53 74 65 6d   = fuzzerNewStem
2f00: 28 70 43 75 72 2c 20 7a 57 6f 72 64 2c 20 28 66  (pCur, zWord, (f
2f10: 75 7a 7a 65 72 5f 63 6f 73 74 29 30 29 3b 0a 20  uzzer_cost)0);. 
2f20: 20 69 66 28 20 70 43 75 72 2d 3e 70 53 74 65 6d   if( pCur->pStem
2f30: 3d 3d 30 20 29 20 72 65 74 75 72 6e 20 53 51 4c  ==0 ) return SQL
2f40: 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 72 65 74  ITE_NOMEM;.  ret
2f50: 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d  urn SQLITE_OK;.}
2f60: 0a 0a 2f 2a 0a 2a 2a 20 4f 6e 6c 79 20 74 68 65  ../*.** Only the
2f70: 20 77 6f 72 64 20 61 6e 64 20 64 69 73 74 61 6e   word and distan
2f80: 63 65 20 63 6f 6c 75 6d 6e 73 20 68 61 76 65 20  ce columns have 
2f90: 76 61 6c 75 65 73 2e 20 20 41 6c 6c 20 6f 74 68  values.  All oth
2fa0: 65 72 20 63 6f 6c 75 6d 6e 73 0a 2a 2a 20 72 65  er columns.** re
2fb0: 74 75 72 6e 20 4e 55 4c 4c 0a 2a 2f 0a 73 74 61  turn NULL.*/.sta
2fc0: 74 69 63 20 69 6e 74 20 66 75 7a 7a 65 72 43 6f  tic int fuzzerCo
2fd0: 6c 75 6d 6e 28 73 71 6c 69 74 65 33 5f 76 74 61  lumn(sqlite3_vta
2fe0: 62 5f 63 75 72 73 6f 72 20 2a 63 75 72 2c 20 73  b_cursor *cur, s
2ff0: 71 6c 69 74 65 33 5f 63 6f 6e 74 65 78 74 20 2a  qlite3_context *
3000: 63 74 78 2c 20 69 6e 74 20 69 29 7b 0a 20 20 66  ctx, int i){.  f
3010: 75 7a 7a 65 72 5f 63 75 72 73 6f 72 20 2a 70 43  uzzer_cursor *pC
3020: 75 72 20 3d 20 28 66 75 7a 7a 65 72 5f 63 75 72  ur = (fuzzer_cur
3030: 73 6f 72 2a 29 63 75 72 3b 0a 20 20 69 66 28 20  sor*)cur;.  if( 
3040: 69 3d 3d 30 20 29 7b 0a 20 20 20 20 2f 2a 20 74  i==0 ){.    /* t
3050: 68 65 20 22 77 6f 72 64 22 20 63 6f 6c 75 6d 6e  he "word" column
3060: 20 2a 2f 0a 20 20 20 20 69 66 28 20 66 75 7a 7a   */.    if( fuzz
3070: 65 72 43 6f 6d 70 75 74 65 57 6f 72 64 28 70 43  erComputeWord(pC
3080: 75 72 2c 20 70 43 75 72 2d 3e 70 53 74 65 6d 29  ur, pCur->pStem)
3090: 3d 3d 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 20 29  ==SQLITE_NOMEM )
30a0: 7b 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20 53  {.      return S
30b0: 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20  QLITE_NOMEM;.   
30c0: 20 7d 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 72   }.    sqlite3_r
30d0: 65 73 75 6c 74 5f 74 65 78 74 28 63 74 78 2c 20  esult_text(ctx, 
30e0: 70 43 75 72 2d 3e 7a 42 75 66 2c 20 2d 31 2c 20  pCur->zBuf, -1, 
30f0: 53 51 4c 49 54 45 5f 54 52 41 4e 53 49 45 4e 54  SQLITE_TRANSIENT
3100: 29 3b 0a 20 20 7d 65 6c 73 65 20 69 66 28 20 69  );.  }else if( i
3110: 3d 3d 31 20 29 7b 0a 20 20 20 20 2f 2a 20 74 68  ==1 ){.    /* th
3120: 65 20 22 64 69 73 74 61 6e 63 65 22 20 63 6f 6c  e "distance" col
3130: 75 6d 6e 20 2a 2f 0a 20 20 20 20 73 71 6c 69 74  umn */.    sqlit
3140: 65 33 5f 72 65 73 75 6c 74 5f 69 6e 74 28 63 74  e3_result_int(ct
3150: 78 2c 20 66 75 7a 7a 65 72 43 6f 73 74 28 70 43  x, fuzzerCost(pC
3160: 75 72 2d 3e 70 53 74 65 6d 29 29 3b 0a 20 20 7d  ur->pStem));.  }
3170: 65 6c 73 65 7b 0a 20 20 20 20 2f 2a 20 41 6c 6c  else{.    /* All
3180: 20 6f 74 68 65 72 20 63 6f 6c 75 6d 6e 73 20 61   other columns a
3190: 72 65 20 4e 55 4c 4c 20 2a 2f 0a 20 20 20 20 73  re NULL */.    s
31a0: 71 6c 69 74 65 33 5f 72 65 73 75 6c 74 5f 6e 75  qlite3_result_nu
31b0: 6c 6c 28 63 74 78 29 3b 0a 20 20 7d 0a 20 20 72  ll(ctx);.  }.  r
31c0: 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b  eturn SQLITE_OK;
31d0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 65 20 72 6f  .}../*.** The ro
31e0: 77 69 64 20 69 73 20 61 6c 77 61 79 73 20 30 0a  wid is always 0.
31f0: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 66 75  */.static int fu
3200: 7a 7a 65 72 52 6f 77 69 64 28 73 71 6c 69 74 65  zzerRowid(sqlite
3210: 33 5f 76 74 61 62 5f 63 75 72 73 6f 72 20 2a 63  3_vtab_cursor *c
3220: 75 72 2c 20 73 71 6c 69 74 65 5f 69 6e 74 36 34  ur, sqlite_int64
3230: 20 2a 70 52 6f 77 69 64 29 7b 0a 20 20 2a 70 52   *pRowid){.  *pR
3240: 6f 77 69 64 20 3d 20 30 3b 20 20 2f 2a 20 54 68  owid = 0;  /* Th
3250: 65 20 72 6f 77 69 64 20 69 73 20 61 6c 77 61 79  e rowid is alway
3260: 73 20 30 20 2a 2f 0a 20 20 72 65 74 75 72 6e 20  s 0 */.  return 
3270: 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a  SQLITE_OK;.}../*
3280: 0a 2a 2a 20 57 68 65 6e 20 74 68 65 20 66 75 7a  .** When the fuz
3290: 7a 65 72 5f 63 75 72 73 6f 72 2e 72 4c 69 6d 69  zer_cursor.rLimi
32a0: 74 20 76 61 6c 75 65 20 69 73 20 30 20 6f 72 20  t value is 0 or 
32b0: 6c 65 73 73 2c 20 74 68 61 74 20 69 73 20 61 20  less, that is a 
32c0: 73 69 67 6e 61 6c 0a 2a 2a 20 74 68 61 74 20 74  signal.** that t
32d0: 68 65 20 63 75 72 73 6f 72 20 68 61 73 20 6e 6f  he cursor has no
32e0: 74 68 69 6e 67 20 6d 6f 72 65 20 74 6f 20 6f 75  thing more to ou
32f0: 74 70 75 74 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  tput..*/.static 
3300: 69 6e 74 20 66 75 7a 7a 65 72 45 6f 66 28 73 71  int fuzzerEof(sq
3310: 6c 69 74 65 33 5f 76 74 61 62 5f 63 75 72 73 6f  lite3_vtab_curso
3320: 72 20 2a 63 75 72 29 7b 0a 20 20 66 75 7a 7a 65  r *cur){.  fuzze
3330: 72 5f 63 75 72 73 6f 72 20 2a 70 43 75 72 20 3d  r_cursor *pCur =
3340: 20 28 66 75 7a 7a 65 72 5f 63 75 72 73 6f 72 2a   (fuzzer_cursor*
3350: 29 63 75 72 3b 0a 20 20 72 65 74 75 72 6e 20 70  )cur;.  return p
3360: 43 75 72 2d 3e 72 4c 69 6d 69 74 3c 3d 28 66 75  Cur->rLimit<=(fu
3370: 7a 7a 65 72 5f 63 6f 73 74 29 30 3b 0a 7d 0a 0a  zzer_cost)0;.}..
3380: 2f 2a 0a 2a 2a 20 53 65 61 72 63 68 20 66 6f 72  /*.** Search for
3390: 20 74 65 72 6d 73 20 6f 66 20 74 68 65 73 65 20   terms of these 
33a0: 66 6f 72 6d 73 3a 0a 2a 2a 0a 2a 2a 20 20 20 20  forms:.**.**    
33b0: 20 20 20 77 6f 72 64 20 4d 41 54 43 48 20 24 73     word MATCH $s
33c0: 74 72 0a 2a 2a 20 20 20 20 20 20 20 64 69 73 74  tr.**       dist
33d0: 61 6e 63 65 20 3c 20 24 76 61 6c 75 65 0a 2a 2a  ance < $value.**
33e0: 20 20 20 20 20 20 20 64 69 73 74 61 6e 63 65 20         distance 
33f0: 3c 3d 20 24 76 61 6c 75 65 0a 2a 2a 0a 2a 2a 20  <= $value.**.** 
3400: 54 68 65 20 64 69 73 74 61 6e 63 65 3c 20 61 6e  The distance< an
3410: 64 20 64 69 73 74 61 6e 63 65 3c 3d 20 61 72 65  d distance<= are
3420: 20 62 6f 74 68 20 74 72 65 61 74 65 64 20 61 73   both treated as
3430: 20 64 69 73 74 61 6e 63 65 3c 3d 2e 0a 2a 2a 20   distance<=..** 
3440: 54 68 65 20 71 75 65 72 79 20 70 6c 61 6e 20 6e  The query plan n
3450: 75 6d 62 65 72 20 69 73 20 61 73 20 66 6f 6c 6c  umber is as foll
3460: 6f 77 73 3a 0a 2a 2a 0a 2a 2a 20 20 20 30 3a 20  ows:.**.**   0: 
3470: 20 20 20 4e 6f 6e 65 20 6f 66 20 74 68 65 20 74     None of the t
3480: 65 72 6d 73 20 61 62 6f 76 65 20 61 72 65 20 66  erms above are f
3490: 6f 75 6e 64 0a 2a 2a 20 20 20 31 3a 20 20 20 20  ound.**   1:    
34a0: 54 68 65 72 65 20 69 73 20 61 20 22 77 6f 72 64  There is a "word
34b0: 20 4d 41 54 43 48 22 20 74 65 72 6d 20 77 69 74   MATCH" term wit
34c0: 68 20 24 73 74 72 20 69 6e 20 66 69 6c 74 65 72  h $str in filter
34d0: 2e 61 72 67 76 5b 30 5d 2e 0a 2a 2a 20 20 20 32  .argv[0]..**   2
34e0: 3a 20 20 20 20 54 68 65 72 65 20 69 73 20 61 20  :    There is a 
34f0: 22 64 69 73 74 61 6e 63 65 3c 22 20 74 65 72 6d  "distance<" term
3500: 20 77 69 74 68 20 24 76 61 6c 75 65 20 69 6e 20   with $value in 
3510: 66 69 6c 74 65 72 2e 61 72 67 76 5b 30 5d 2e 0a  filter.argv[0]..
3520: 2a 2a 20 20 20 33 3a 20 20 20 20 42 6f 74 68 20  **   3:    Both 
3530: 22 77 6f 72 64 20 4d 41 54 43 48 22 20 61 6e 64  "word MATCH" and
3540: 20 22 64 69 73 74 61 6e 63 65 3c 22 20 77 69 74   "distance<" wit
3550: 68 20 24 73 74 72 20 69 6e 20 61 72 67 76 5b 30  h $str in argv[0
3560: 5d 20 61 6e 64 0a 2a 2a 20 20 20 20 20 20 20 20  ] and.**        
3570: 20 24 76 61 6c 75 65 20 69 6e 20 61 72 67 76 5b   $value in argv[
3580: 31 5d 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  1]..*/.static in
3590: 74 20 66 75 7a 7a 65 72 42 65 73 74 49 6e 64 65  t fuzzerBestInde
35a0: 78 28 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a  x(sqlite3_vtab *
35b0: 74 61 62 2c 20 73 71 6c 69 74 65 33 5f 69 6e 64  tab, sqlite3_ind
35c0: 65 78 5f 69 6e 66 6f 20 2a 70 49 64 78 49 6e 66  ex_info *pIdxInf
35d0: 6f 29 7b 0a 20 20 69 6e 74 20 69 50 6c 61 6e 20  o){.  int iPlan 
35e0: 3d 20 30 3b 0a 20 20 69 6e 74 20 69 44 69 73 74  = 0;.  int iDist
35f0: 54 65 72 6d 20 3d 20 2d 31 3b 0a 20 20 69 6e 74  Term = -1;.  int
3600: 20 69 3b 0a 20 20 63 6f 6e 73 74 20 73 74 72 75   i;.  const stru
3610: 63 74 20 73 71 6c 69 74 65 33 5f 69 6e 64 65 78  ct sqlite3_index
3620: 5f 63 6f 6e 73 74 72 61 69 6e 74 20 2a 70 43 6f  _constraint *pCo
3630: 6e 73 74 72 61 69 6e 74 3b 0a 20 20 70 43 6f 6e  nstraint;.  pCon
3640: 73 74 72 61 69 6e 74 20 3d 20 70 49 64 78 49 6e  straint = pIdxIn
3650: 66 6f 2d 3e 61 43 6f 6e 73 74 72 61 69 6e 74 3b  fo->aConstraint;
3660: 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 70 49  .  for(i=0; i<pI
3670: 64 78 49 6e 66 6f 2d 3e 6e 43 6f 6e 73 74 72 61  dxInfo->nConstra
3680: 69 6e 74 3b 20 69 2b 2b 2c 20 70 43 6f 6e 73 74  int; i++, pConst
3690: 72 61 69 6e 74 2b 2b 29 7b 0a 20 20 20 20 69 66  raint++){.    if
36a0: 28 20 70 43 6f 6e 73 74 72 61 69 6e 74 2d 3e 75  ( pConstraint->u
36b0: 73 61 62 6c 65 3d 3d 30 20 29 20 63 6f 6e 74 69  sable==0 ) conti
36c0: 6e 75 65 3b 0a 20 20 20 20 69 66 28 20 28 69 50  nue;.    if( (iP
36d0: 6c 61 6e 20 26 20 31 29 3d 3d 30 20 0a 20 20 20  lan & 1)==0 .   
36e0: 20 20 26 26 20 70 43 6f 6e 73 74 72 61 69 6e 74    && pConstraint
36f0: 2d 3e 69 43 6f 6c 75 6d 6e 3d 3d 30 0a 20 20 20  ->iColumn==0.   
3700: 20 20 26 26 20 70 43 6f 6e 73 74 72 61 69 6e 74    && pConstraint
3710: 2d 3e 6f 70 3d 3d 53 51 4c 49 54 45 5f 49 4e 44  ->op==SQLITE_IND
3720: 45 58 5f 43 4f 4e 53 54 52 41 49 4e 54 5f 4d 41  EX_CONSTRAINT_MA
3730: 54 43 48 0a 20 20 20 20 29 7b 0a 20 20 20 20 20  TCH.    ){.     
3740: 20 69 50 6c 61 6e 20 7c 3d 20 31 3b 0a 20 20 20   iPlan |= 1;.   
3750: 20 20 20 70 49 64 78 49 6e 66 6f 2d 3e 61 43 6f     pIdxInfo->aCo
3760: 6e 73 74 72 61 69 6e 74 55 73 61 67 65 5b 69 5d  nstraintUsage[i]
3770: 2e 61 72 67 76 49 6e 64 65 78 20 3d 20 31 3b 0a  .argvIndex = 1;.
3780: 20 20 20 20 20 20 70 49 64 78 49 6e 66 6f 2d 3e        pIdxInfo->
3790: 61 43 6f 6e 73 74 72 61 69 6e 74 55 73 61 67 65  aConstraintUsage
37a0: 5b 69 5d 2e 6f 6d 69 74 20 3d 20 31 3b 0a 20 20  [i].omit = 1;.  
37b0: 20 20 7d 0a 20 20 20 20 69 66 28 20 28 69 50 6c    }.    if( (iPl
37c0: 61 6e 20 26 20 32 29 3d 3d 30 0a 20 20 20 20 20  an & 2)==0.     
37d0: 26 26 20 70 43 6f 6e 73 74 72 61 69 6e 74 2d 3e  && pConstraint->
37e0: 69 43 6f 6c 75 6d 6e 3d 3d 31 0a 20 20 20 20 20  iColumn==1.     
37f0: 26 26 20 28 70 43 6f 6e 73 74 72 61 69 6e 74 2d  && (pConstraint-
3800: 3e 6f 70 3d 3d 53 51 4c 49 54 45 5f 49 4e 44 45  >op==SQLITE_INDE
3810: 58 5f 43 4f 4e 53 54 52 41 49 4e 54 5f 4c 54 0a  X_CONSTRAINT_LT.
3820: 20 20 20 20 20 20 20 20 20 20 20 7c 7c 20 70 43             || pC
3830: 6f 6e 73 74 72 61 69 6e 74 2d 3e 6f 70 3d 3d 53  onstraint->op==S
3840: 51 4c 49 54 45 5f 49 4e 44 45 58 5f 43 4f 4e 53  QLITE_INDEX_CONS
3850: 54 52 41 49 4e 54 5f 4c 45 29 0a 20 20 20 20 29  TRAINT_LE).    )
3860: 7b 0a 20 20 20 20 20 20 69 50 6c 61 6e 20 7c 3d  {.      iPlan |=
3870: 20 32 3b 0a 20 20 20 20 20 20 69 44 69 73 74 54   2;.      iDistT
3880: 65 72 6d 20 3d 20 69 3b 0a 20 20 20 20 7d 0a 20  erm = i;.    }. 
3890: 20 7d 0a 20 20 69 66 28 20 69 50 6c 61 6e 3d 3d   }.  if( iPlan==
38a0: 32 20 29 7b 0a 20 20 20 20 70 49 64 78 49 6e 66  2 ){.    pIdxInf
38b0: 6f 2d 3e 61 43 6f 6e 73 74 72 61 69 6e 74 55 73  o->aConstraintUs
38c0: 61 67 65 5b 69 44 69 73 74 54 65 72 6d 5d 2e 61  age[iDistTerm].a
38d0: 72 67 76 49 6e 64 65 78 20 3d 20 31 3b 0a 20 20  rgvIndex = 1;.  
38e0: 7d 65 6c 73 65 20 69 66 28 20 69 50 6c 61 6e 3d  }else if( iPlan=
38f0: 3d 33 20 29 7b 0a 20 20 20 20 70 49 64 78 49 6e  =3 ){.    pIdxIn
3900: 66 6f 2d 3e 61 43 6f 6e 73 74 72 61 69 6e 74 55  fo->aConstraintU
3910: 73 61 67 65 5b 69 44 69 73 74 54 65 72 6d 5d 2e  sage[iDistTerm].
3920: 61 72 67 76 49 6e 64 65 78 20 3d 20 32 3b 0a 20  argvIndex = 2;. 
3930: 20 7d 0a 20 20 70 49 64 78 49 6e 66 6f 2d 3e 69   }.  pIdxInfo->i
3940: 64 78 4e 75 6d 20 3d 20 69 50 6c 61 6e 3b 0a 20  dxNum = iPlan;. 
3950: 20 69 66 28 20 70 49 64 78 49 6e 66 6f 2d 3e 6e   if( pIdxInfo->n
3960: 4f 72 64 65 72 42 79 3d 3d 31 0a 20 20 20 26 26  OrderBy==1.   &&
3970: 20 70 49 64 78 49 6e 66 6f 2d 3e 61 4f 72 64 65   pIdxInfo->aOrde
3980: 72 42 79 5b 30 5d 2e 69 43 6f 6c 75 6d 6e 3d 3d  rBy[0].iColumn==
3990: 31 0a 20 20 20 26 26 20 70 49 64 78 49 6e 66 6f  1.   && pIdxInfo
39a0: 2d 3e 61 4f 72 64 65 72 42 79 5b 30 5d 2e 64 65  ->aOrderBy[0].de
39b0: 73 63 3d 3d 30 0a 20 20 29 7b 0a 20 20 20 20 70  sc==0.  ){.    p
39c0: 49 64 78 49 6e 66 6f 2d 3e 6f 72 64 65 72 42 79  IdxInfo->orderBy
39d0: 43 6f 6e 73 75 6d 65 64 20 3d 20 31 3b 0a 20 20  Consumed = 1;.  
39e0: 7d 0a 20 20 70 49 64 78 49 6e 66 6f 2d 3e 65 73  }.  pIdxInfo->es
39f0: 74 69 6d 61 74 65 64 43 6f 73 74 20 3d 20 28 64  timatedCost = (d
3a00: 6f 75 62 6c 65 29 31 30 30 30 30 3b 0a 20 20 20  ouble)10000;.   
3a10: 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45  .  return SQLITE
3a20: 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 44 69  _OK;.}../*.** Di
3a30: 73 61 6c 6c 6f 77 20 61 6c 6c 20 61 74 74 65 6d  sallow all attem
3a40: 70 74 73 20 74 6f 20 44 45 4c 45 54 45 20 6f 72  pts to DELETE or
3a50: 20 55 50 44 41 54 45 2e 20 20 4f 6e 6c 79 20 49   UPDATE.  Only I
3a60: 4e 53 45 52 54 73 20 61 72 65 20 61 6c 6c 6f 77  NSERTs are allow
3a70: 65 64 2e 0a 2a 2a 0a 2a 2a 20 4f 6e 20 61 6e 20  ed..**.** On an 
3a80: 69 6e 73 65 72 74 2c 20 74 68 65 20 63 46 72 6f  insert, the cFro
3a90: 6d 2c 20 63 54 6f 2c 20 61 6e 64 20 63 6f 73 74  m, cTo, and cost
3aa0: 20 63 6f 6c 75 6d 6e 73 20 61 72 65 20 75 73 65   columns are use
3ab0: 64 20 74 6f 20 63 6f 6e 73 74 72 75 63 74 0a 2a  d to construct.*
3ac0: 2a 20 61 20 6e 65 77 20 72 75 6c 65 2e 20 20 20  * a new rule.   
3ad0: 41 6c 6c 20 6f 74 68 65 72 20 63 6f 6c 75 6d 6e  All other column
3ae0: 73 20 61 72 65 20 69 67 6e 6f 72 65 64 2e 20 20  s are ignored.  
3af0: 54 68 65 20 72 75 6c 65 20 69 73 20 69 67 6e 6f  The rule is igno
3b00: 72 65 64 0a 2a 2a 20 69 66 20 63 46 72 6f 6d 20  red.** if cFrom 
3b10: 61 6e 64 20 63 54 6f 20 61 72 65 20 69 64 65 6e  and cTo are iden
3b20: 74 69 63 61 6c 2e 20 20 41 20 4e 55 4c 4c 20 76  tical.  A NULL v
3b30: 61 6c 75 65 20 66 6f 72 20 63 46 72 6f 6d 20 6f  alue for cFrom o
3b40: 72 20 63 54 6f 20 69 73 0a 2a 2a 20 69 6e 74 65  r cTo is.** inte
3b50: 72 70 72 65 74 65 64 20 61 73 20 61 6e 20 65 6d  rpreted as an em
3b60: 70 74 79 20 73 74 72 69 6e 67 2e 20 20 54 68 65  pty string.  The
3b70: 20 63 6f 73 74 20 6d 75 73 74 20 62 65 20 70 6f   cost must be po
3b80: 73 69 74 69 76 65 2e 0a 2a 2f 0a 73 74 61 74 69  sitive..*/.stati
3b90: 63 20 69 6e 74 20 66 75 7a 7a 65 72 55 70 64 61  c int fuzzerUpda
3ba0: 74 65 28 0a 20 20 73 71 6c 69 74 65 33 5f 76 74  te(.  sqlite3_vt
3bb0: 61 62 20 2a 70 56 54 61 62 2c 0a 20 20 69 6e 74  ab *pVTab,.  int
3bc0: 20 61 72 67 63 2c 0a 20 20 73 71 6c 69 74 65 33   argc,.  sqlite3
3bd0: 5f 76 61 6c 75 65 20 2a 2a 61 72 67 76 2c 0a 20  _value **argv,. 
3be0: 20 73 71 6c 69 74 65 5f 69 6e 74 36 34 20 2a 70   sqlite_int64 *p
3bf0: 52 6f 77 69 64 0a 29 7b 0a 20 20 66 75 7a 7a 65  Rowid.){.  fuzze
3c00: 72 5f 76 74 61 62 20 2a 70 20 3d 20 28 66 75 7a  r_vtab *p = (fuz
3c10: 7a 65 72 5f 76 74 61 62 2a 29 70 56 54 61 62 3b  zer_vtab*)pVTab;
3c20: 0a 20 20 66 75 7a 7a 65 72 5f 72 75 6c 65 20 2a  .  fuzzer_rule *
3c30: 70 52 75 6c 65 3b 0a 20 20 63 6f 6e 73 74 20 63  pRule;.  const c
3c40: 68 61 72 20 2a 7a 46 72 6f 6d 3b 0a 20 20 69 6e  har *zFrom;.  in
3c50: 74 20 6e 46 72 6f 6d 3b 0a 20 20 63 6f 6e 73 74  t nFrom;.  const
3c60: 20 63 68 61 72 20 2a 7a 54 6f 3b 0a 20 20 69 6e   char *zTo;.  in
3c70: 74 20 6e 54 6f 3b 0a 20 20 66 75 7a 7a 65 72 5f  t nTo;.  fuzzer_
3c80: 63 6f 73 74 20 72 43 6f 73 74 3b 0a 20 20 69 66  cost rCost;.  if
3c90: 28 20 61 72 67 63 21 3d 37 20 29 7b 0a 20 20 20  ( argc!=7 ){.   
3ca0: 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70 56   sqlite3_free(pV
3cb0: 54 61 62 2d 3e 7a 45 72 72 4d 73 67 29 3b 0a 20  Tab->zErrMsg);. 
3cc0: 20 20 20 70 56 54 61 62 2d 3e 7a 45 72 72 4d 73     pVTab->zErrMs
3cd0: 67 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72 69  g = sqlite3_mpri
3ce0: 6e 74 66 28 22 63 61 6e 6e 6f 74 20 64 65 6c 65  ntf("cannot dele
3cf0: 74 65 20 66 72 6f 6d 20 61 20 25 73 20 76 69 72  te from a %s vir
3d00: 74 75 61 6c 20 74 61 62 6c 65 22 2c 0a 20 20 20  tual table",.   
3d10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3d20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3d30: 20 20 70 2d 3e 7a 43 6c 61 73 73 4e 61 6d 65 29    p->zClassName)
3d40: 3b 0a 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c  ;.    return SQL
3d50: 49 54 45 5f 43 4f 4e 53 54 52 41 49 4e 54 3b 0a  ITE_CONSTRAINT;.
3d60: 20 20 7d 0a 20 20 69 66 28 20 73 71 6c 69 74 65    }.  if( sqlite
3d70: 33 5f 76 61 6c 75 65 5f 74 79 70 65 28 61 72 67  3_value_type(arg
3d80: 76 5b 30 5d 29 21 3d 53 51 4c 49 54 45 5f 4e 55  v[0])!=SQLITE_NU
3d90: 4c 4c 20 29 7b 0a 20 20 20 20 73 71 6c 69 74 65  LL ){.    sqlite
3da0: 33 5f 66 72 65 65 28 70 56 54 61 62 2d 3e 7a 45  3_free(pVTab->zE
3db0: 72 72 4d 73 67 29 3b 0a 20 20 20 20 70 56 54 61  rrMsg);.    pVTa
3dc0: 62 2d 3e 7a 45 72 72 4d 73 67 20 3d 20 73 71 6c  b->zErrMsg = sql
3dd0: 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 22 63 61  ite3_mprintf("ca
3de0: 6e 6e 6f 74 20 75 70 64 61 74 65 20 61 20 25 73  nnot update a %s
3df0: 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65 22 2c   virtual table",
3e00: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
3e10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3e20: 20 20 20 20 20 20 70 2d 3e 7a 43 6c 61 73 73 4e        p->zClassN
3e30: 61 6d 65 29 3b 0a 20 20 20 20 72 65 74 75 72 6e  ame);.    return
3e40: 20 53 51 4c 49 54 45 5f 43 4f 4e 53 54 52 41 49   SQLITE_CONSTRAI
3e50: 4e 54 3b 0a 20 20 7d 0a 20 20 7a 46 72 6f 6d 20  NT;.  }.  zFrom 
3e60: 3d 20 28 63 68 61 72 2a 29 73 71 6c 69 74 65 33  = (char*)sqlite3
3e70: 5f 76 61 6c 75 65 5f 74 65 78 74 28 61 72 67 76  _value_text(argv
3e80: 5b 34 5d 29 3b 0a 20 20 69 66 28 20 7a 46 72 6f  [4]);.  if( zFro
3e90: 6d 3d 3d 30 20 29 20 7a 46 72 6f 6d 20 3d 20 22  m==0 ) zFrom = "
3ea0: 22 3b 0a 20 20 7a 54 6f 20 3d 20 28 63 68 61 72  ";.  zTo = (char
3eb0: 2a 29 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f  *)sqlite3_value_
3ec0: 74 65 78 74 28 61 72 67 76 5b 35 5d 29 3b 0a 20  text(argv[5]);. 
3ed0: 20 69 66 28 20 7a 54 6f 3d 3d 30 20 29 20 7a 54   if( zTo==0 ) zT
3ee0: 6f 20 3d 20 22 22 3b 0a 20 20 69 66 28 20 73 74  o = "";.  if( st
3ef0: 72 63 6d 70 28 7a 46 72 6f 6d 2c 7a 54 6f 29 3d  rcmp(zFrom,zTo)=
3f00: 3d 30 20 29 7b 0a 20 20 20 20 2f 2a 20 53 69 6c  =0 ){.    /* Sil
3f10: 65 6e 74 6c 79 20 69 67 6e 6f 72 65 20 6e 75 6c  ently ignore nul
3f20: 6c 20 74 72 61 6e 73 66 6f 72 6d 61 74 69 6f 6e  l transformation
3f30: 73 20 2a 2f 0a 20 20 20 20 72 65 74 75 72 6e 20  s */.    return 
3f40: 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 7d 0a 20  SQLITE_OK;.  }. 
3f50: 20 72 43 6f 73 74 20 3d 20 73 71 6c 69 74 65 33   rCost = sqlite3
3f60: 5f 76 61 6c 75 65 5f 69 6e 74 28 61 72 67 76 5b  _value_int(argv[
3f70: 36 5d 29 3b 0a 20 20 69 66 28 20 72 43 6f 73 74  6]);.  if( rCost
3f80: 3c 3d 30 20 29 7b 0a 20 20 20 20 73 71 6c 69 74  <=0 ){.    sqlit
3f90: 65 33 5f 66 72 65 65 28 70 56 54 61 62 2d 3e 7a  e3_free(pVTab->z
3fa0: 45 72 72 4d 73 67 29 3b 0a 20 20 20 20 70 56 54  ErrMsg);.    pVT
3fb0: 61 62 2d 3e 7a 45 72 72 4d 73 67 20 3d 20 73 71  ab->zErrMsg = sq
3fc0: 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 22 63  lite3_mprintf("c
3fd0: 6f 73 74 20 6d 75 73 74 20 62 65 20 70 6f 73 69  ost must be posi
3fe0: 74 69 76 65 22 29 3b 0a 20 20 20 20 72 65 74 75  tive");.    retu
3ff0: 72 6e 20 53 51 4c 49 54 45 5f 43 4f 4e 53 54 52  rn SQLITE_CONSTR
4000: 41 49 4e 54 3b 20 20 20 20 0a 20 20 7d 0a 20 20  AINT;    .  }.  
4010: 6e 46 72 6f 6d 20 3d 20 73 74 72 6c 65 6e 28 7a  nFrom = strlen(z
4020: 46 72 6f 6d 29 2b 31 3b 0a 20 20 6e 54 6f 20 3d  From)+1;.  nTo =
4030: 20 73 74 72 6c 65 6e 28 7a 54 6f 29 2b 31 3b 0a   strlen(zTo)+1;.
4040: 20 20 69 66 28 20 6e 54 6f 3c 34 20 29 20 6e 54    if( nTo<4 ) nT
4050: 6f 20 3d 20 34 3b 0a 20 20 70 52 75 6c 65 20 3d  o = 4;.  pRule =
4060: 20 73 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63 28   sqlite3_malloc(
4070: 20 73 69 7a 65 6f 66 28 2a 70 52 75 6c 65 29 20   sizeof(*pRule) 
4080: 2b 20 6e 46 72 6f 6d 20 2b 20 6e 54 6f 20 2d 20  + nFrom + nTo - 
4090: 34 20 29 3b 0a 20 20 69 66 28 20 70 52 75 6c 65  4 );.  if( pRule
40a0: 3d 3d 30 20 29 7b 0a 20 20 20 20 72 65 74 75 72  ==0 ){.    retur
40b0: 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a  n SQLITE_NOMEM;.
40c0: 20 20 7d 0a 20 20 70 52 75 6c 65 2d 3e 7a 46 72    }.  pRule->zFr
40d0: 6f 6d 20 3d 20 26 70 52 75 6c 65 2d 3e 7a 54 6f  om = &pRule->zTo
40e0: 5b 6e 54 6f 5d 3b 0a 20 20 70 52 75 6c 65 2d 3e  [nTo];.  pRule->
40f0: 6e 46 72 6f 6d 20 3d 20 6e 46 72 6f 6d 3b 0a 20  nFrom = nFrom;. 
4100: 20 6d 65 6d 63 70 79 28 70 52 75 6c 65 2d 3e 7a   memcpy(pRule->z
4110: 46 72 6f 6d 2c 20 7a 46 72 6f 6d 2c 20 6e 46 72  From, zFrom, nFr
4120: 6f 6d 29 3b 0a 20 20 6d 65 6d 63 70 79 28 70 52  om);.  memcpy(pR
4130: 75 6c 65 2d 3e 7a 54 6f 2c 20 7a 54 6f 2c 20 6e  ule->zTo, zTo, n
4140: 54 6f 29 3b 0a 20 20 70 52 75 6c 65 2d 3e 6e 54  To);.  pRule->nT
4150: 6f 20 3d 20 6e 54 6f 3b 0a 20 20 70 52 75 6c 65  o = nTo;.  pRule
4160: 2d 3e 72 43 6f 73 74 20 3d 20 72 43 6f 73 74 3b  ->rCost = rCost;
4170: 0a 20 20 70 52 75 6c 65 2d 3e 70 4e 65 78 74 20  .  pRule->pNext 
4180: 3d 20 70 2d 3e 70 4e 65 77 52 75 6c 65 3b 0a 20  = p->pNewRule;. 
4190: 20 70 2d 3e 70 4e 65 77 52 75 6c 65 20 3d 20 70   p->pNewRule = p
41a0: 52 75 6c 65 3b 0a 20 20 72 65 74 75 72 6e 20 53  Rule;.  return S
41b0: 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a  QLITE_OK;.}../*.
41c0: 2a 2a 20 41 20 76 69 72 74 75 61 6c 20 74 61 62  ** A virtual tab
41d0: 6c 65 20 6d 6f 64 75 6c 65 20 74 68 61 74 20 70  le module that p
41e0: 72 6f 76 69 64 65 73 20 72 65 61 64 2d 6f 6e 6c  rovides read-onl
41f0: 79 20 61 63 63 65 73 73 20 74 6f 20 61 0a 2a 2a  y access to a.**
4200: 20 54 63 6c 20 67 6c 6f 62 61 6c 20 76 61 72 69   Tcl global vari
4210: 61 62 6c 65 20 6e 61 6d 65 73 70 61 63 65 2e 0a  able namespace..
4220: 2a 2f 0a 73 74 61 74 69 63 20 73 71 6c 69 74 65  */.static sqlite
4230: 33 5f 6d 6f 64 75 6c 65 20 66 75 7a 7a 65 72 4d  3_module fuzzerM
4240: 6f 64 75 6c 65 20 3d 20 7b 0a 20 20 30 2c 20 20  odule = {.  0,  
4250: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4260: 20 20 20 20 20 20 20 20 20 2f 2a 20 69 56 65 72           /* iVer
4270: 73 69 6f 6e 20 2a 2f 0a 20 20 66 75 7a 7a 65 72  sion */.  fuzzer
4280: 43 6f 6e 6e 65 63 74 2c 0a 20 20 66 75 7a 7a 65  Connect,.  fuzze
4290: 72 43 6f 6e 6e 65 63 74 2c 0a 20 20 66 75 7a 7a  rConnect,.  fuzz
42a0: 65 72 42 65 73 74 49 6e 64 65 78 2c 0a 20 20 66  erBestIndex,.  f
42b0: 75 7a 7a 65 72 44 69 73 63 6f 6e 6e 65 63 74 2c  uzzerDisconnect,
42c0: 20 0a 20 20 66 75 7a 7a 65 72 44 69 73 63 6f 6e   .  fuzzerDiscon
42d0: 6e 65 63 74 2c 0a 20 20 66 75 7a 7a 65 72 4f 70  nect,.  fuzzerOp
42e0: 65 6e 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  en,             
42f0: 20 20 20 20 20 2f 2a 20 78 4f 70 65 6e 20 2d 20       /* xOpen - 
4300: 6f 70 65 6e 20 61 20 63 75 72 73 6f 72 20 2a 2f  open a cursor */
4310: 0a 20 20 66 75 7a 7a 65 72 43 6c 6f 73 65 2c 20  .  fuzzerClose, 
4320: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4330: 2f 2a 20 78 43 6c 6f 73 65 20 2d 20 63 6c 6f 73  /* xClose - clos
4340: 65 20 61 20 63 75 72 73 6f 72 20 2a 2f 0a 20 20  e a cursor */.  
4350: 66 75 7a 7a 65 72 46 69 6c 74 65 72 2c 20 20 20  fuzzerFilter,   
4360: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
4370: 78 46 69 6c 74 65 72 20 2d 20 63 6f 6e 66 69 67  xFilter - config
4380: 75 72 65 20 73 63 61 6e 20 63 6f 6e 73 74 72 61  ure scan constra
4390: 69 6e 74 73 20 2a 2f 0a 20 20 66 75 7a 7a 65 72  ints */.  fuzzer
43a0: 4e 65 78 74 2c 20 20 20 20 20 20 20 20 20 20 20  Next,           
43b0: 20 20 20 20 20 20 20 2f 2a 20 78 4e 65 78 74 20         /* xNext 
43c0: 2d 20 61 64 76 61 6e 63 65 20 61 20 63 75 72 73  - advance a curs
43d0: 6f 72 20 2a 2f 0a 20 20 66 75 7a 7a 65 72 45 6f  or */.  fuzzerEo
43e0: 66 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  f,              
43f0: 20 20 20 20 20 2f 2a 20 78 45 6f 66 20 2d 20 63       /* xEof - c
4400: 68 65 63 6b 20 66 6f 72 20 65 6e 64 20 6f 66 20  heck for end of 
4410: 73 63 61 6e 20 2a 2f 0a 20 20 66 75 7a 7a 65 72  scan */.  fuzzer
4420: 43 6f 6c 75 6d 6e 2c 20 20 20 20 20 20 20 20 20  Column,         
4430: 20 20 20 20 20 20 20 2f 2a 20 78 43 6f 6c 75 6d         /* xColum
4440: 6e 20 2d 20 72 65 61 64 20 64 61 74 61 20 2a 2f  n - read data */
4450: 0a 20 20 66 75 7a 7a 65 72 52 6f 77 69 64 2c 20  .  fuzzerRowid, 
4460: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4470: 2f 2a 20 78 52 6f 77 69 64 20 2d 20 72 65 61 64  /* xRowid - read
4480: 20 64 61 74 61 20 2a 2f 0a 20 20 66 75 7a 7a 65   data */.  fuzze
4490: 72 55 70 64 61 74 65 2c 20 20 20 20 20 20 20 20  rUpdate,        
44a0: 20 20 20 20 20 20 20 20 2f 2a 20 78 55 70 64 61          /* xUpda
44b0: 74 65 20 2d 20 49 4e 53 45 52 54 20 2a 2f 0a 20  te - INSERT */. 
44c0: 20 30 2c 20 20 20 20 20 20 20 20 20 20 20 20 20   0,             
44d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
44e0: 20 78 42 65 67 69 6e 20 2a 2f 0a 20 20 30 2c 20   xBegin */.  0, 
44f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4500: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 53 79            /* xSy
4510: 6e 63 20 2a 2f 0a 20 20 30 2c 20 20 20 20 20 20  nc */.  0,      
4520: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4530: 20 20 20 20 20 2f 2a 20 78 43 6f 6d 6d 69 74 20       /* xCommit 
4540: 2a 2f 0a 20 20 30 2c 20 20 20 20 20 20 20 20 20  */.  0,         
4550: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4560: 20 20 2f 2a 20 78 52 6f 6c 6c 62 61 63 6b 20 2a    /* xRollback *
4570: 2f 0a 20 20 30 2c 20 20 20 20 20 20 20 20 20 20  /.  0,          
4580: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4590: 20 2f 2a 20 78 46 69 6e 64 4d 65 74 68 6f 64 20   /* xFindMethod 
45a0: 2a 2f 0a 20 20 30 2c 20 20 20 20 20 20 20 20 20  */.  0,         
45b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
45c0: 20 20 2f 2a 20 78 52 65 6e 61 6d 65 20 2a 2f 0a    /* xRename */.
45d0: 7d 3b 0a 0a 23 65 6e 64 69 66 20 2f 2a 20 53 51  };..#endif /* SQ
45e0: 4c 49 54 45 5f 4f 4d 49 54 5f 56 49 52 54 55 41  LITE_OMIT_VIRTUA
45f0: 4c 54 41 42 4c 45 20 2a 2f 0a 0a 0a 2f 2a 0a 2a  LTABLE */.../*.*
4600: 2a 20 52 65 67 69 73 74 65 72 20 74 68 65 20 66  * Register the f
4610: 75 7a 7a 65 72 20 76 69 72 74 75 61 6c 20 74 61  uzzer virtual ta
4620: 62 6c 65 0a 2a 2f 0a 69 6e 74 20 66 75 7a 7a 65  ble.*/.int fuzze
4630: 72 5f 72 65 67 69 73 74 65 72 28 73 71 6c 69 74  r_register(sqlit
4640: 65 33 20 2a 64 62 29 7b 0a 20 20 69 6e 74 20 72  e3 *db){.  int r
4650: 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 23  c = SQLITE_OK;.#
4660: 69 66 6e 64 65 66 20 53 51 4c 49 54 45 5f 4f 4d  ifndef SQLITE_OM
4670: 49 54 5f 56 49 52 54 55 41 4c 54 41 42 4c 45 0a  IT_VIRTUALTABLE.
4680: 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 63    rc = sqlite3_c
4690: 72 65 61 74 65 5f 6d 6f 64 75 6c 65 28 64 62 2c  reate_module(db,
46a0: 20 22 66 75 7a 7a 65 72 22 2c 20 26 66 75 7a 7a   "fuzzer", &fuzz
46b0: 65 72 4d 6f 64 75 6c 65 2c 20 30 29 3b 0a 23 65  erModule, 0);.#e
46c0: 6e 64 69 66 0a 20 20 72 65 74 75 72 6e 20 72 63  ndif.  return rc
46d0: 3b 0a 7d 0a 0a 23 69 66 64 65 66 20 53 51 4c 49  ;.}..#ifdef SQLI
46e0: 54 45 5f 54 45 53 54 0a 23 69 6e 63 6c 75 64 65  TE_TEST.#include
46f0: 20 3c 74 63 6c 2e 68 3e 0a 2f 2a 0a 2a 2a 20 44   <tcl.h>./*.** D
4700: 65 63 6f 64 65 20 61 20 70 6f 69 6e 74 65 72 20  ecode a pointer 
4710: 74 6f 20 61 6e 20 73 71 6c 69 74 65 33 20 6f 62  to an sqlite3 ob
4720: 6a 65 63 74 2e 0a 2a 2f 0a 65 78 74 65 72 6e 20  ject..*/.extern 
4730: 69 6e 74 20 67 65 74 44 62 50 6f 69 6e 74 65 72  int getDbPointer
4740: 28 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74  (Tcl_Interp *int
4750: 65 72 70 2c 20 63 6f 6e 73 74 20 63 68 61 72 20  erp, const char 
4760: 2a 7a 41 2c 20 73 71 6c 69 74 65 33 20 2a 2a 70  *zA, sqlite3 **p
4770: 70 44 62 29 3b 0a 0a 2f 2a 0a 2a 2a 20 52 65 67  pDb);../*.** Reg
4780: 69 73 74 65 72 20 74 68 65 20 65 63 68 6f 20 76  ister the echo v
4790: 69 72 74 75 61 6c 20 74 61 62 6c 65 20 6d 6f 64  irtual table mod
47a0: 75 6c 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  ule..*/.static i
47b0: 6e 74 20 72 65 67 69 73 74 65 72 5f 66 75 7a 7a  nt register_fuzz
47c0: 65 72 5f 6d 6f 64 75 6c 65 28 0a 20 20 43 6c 69  er_module(.  Cli
47d0: 65 6e 74 44 61 74 61 20 63 6c 69 65 6e 74 44 61  entData clientDa
47e0: 74 61 2c 20 2f 2a 20 50 6f 69 6e 74 65 72 20 74  ta, /* Pointer t
47f0: 6f 20 73 71 6c 69 74 65 33 5f 65 6e 61 62 6c 65  o sqlite3_enable
4800: 5f 58 58 58 20 66 75 6e 63 74 69 6f 6e 20 2a 2f  _XXX function */
4810: 0a 20 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69  .  Tcl_Interp *i
4820: 6e 74 65 72 70 2c 20 20 20 20 2f 2a 20 54 68 65  nterp,    /* The
4830: 20 54 43 4c 20 69 6e 74 65 72 70 72 65 74 65 72   TCL interpreter
4840: 20 74 68 61 74 20 69 6e 76 6f 6b 65 64 20 74 68   that invoked th
4850: 69 73 20 63 6f 6d 6d 61 6e 64 20 2a 2f 0a 20 20  is command */.  
4860: 69 6e 74 20 6f 62 6a 63 2c 20 20 20 20 20 20 20  int objc,       
4870: 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72         /* Number
4880: 20 6f 66 20 61 72 67 75 6d 65 6e 74 73 20 2a 2f   of arguments */
4890: 0a 20 20 54 63 6c 5f 4f 62 6a 20 2a 43 4f 4e 53  .  Tcl_Obj *CONS
48a0: 54 20 6f 62 6a 76 5b 5d 20 20 2f 2a 20 43 6f 6d  T objv[]  /* Com
48b0: 6d 61 6e 64 20 61 72 67 75 6d 65 6e 74 73 20 2a  mand arguments *
48c0: 2f 0a 29 7b 0a 20 20 73 71 6c 69 74 65 33 20 2a  /.){.  sqlite3 *
48d0: 64 62 3b 0a 20 20 69 66 28 20 6f 62 6a 63 21 3d  db;.  if( objc!=
48e0: 32 20 29 7b 0a 20 20 20 20 54 63 6c 5f 57 72 6f  2 ){.    Tcl_Wro
48f0: 6e 67 4e 75 6d 41 72 67 73 28 69 6e 74 65 72 70  ngNumArgs(interp
4900: 2c 20 31 2c 20 6f 62 6a 76 2c 20 22 44 42 22 29  , 1, objv, "DB")
4910: 3b 0a 20 20 20 20 72 65 74 75 72 6e 20 54 43 4c  ;.    return TCL
4920: 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a 20 20 69 66  _ERROR;.  }.  if
4930: 28 20 67 65 74 44 62 50 6f 69 6e 74 65 72 28 69  ( getDbPointer(i
4940: 6e 74 65 72 70 2c 20 54 63 6c 5f 47 65 74 53 74  nterp, Tcl_GetSt
4950: 72 69 6e 67 28 6f 62 6a 76 5b 31 5d 29 2c 20 26  ring(objv[1]), &
4960: 64 62 29 20 29 20 72 65 74 75 72 6e 20 54 43 4c  db) ) return TCL
4970: 5f 45 52 52 4f 52 3b 0a 20 20 66 75 7a 7a 65 72  _ERROR;.  fuzzer
4980: 5f 72 65 67 69 73 74 65 72 28 64 62 29 3b 0a 20  _register(db);. 
4990: 20 72 65 74 75 72 6e 20 54 43 4c 5f 4f 4b 3b 0a   return TCL_OK;.
49a0: 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 52 65 67 69 73 74  }.../*.** Regist
49b0: 65 72 20 63 6f 6d 6d 61 6e 64 73 20 77 69 74 68  er commands with
49c0: 20 74 68 65 20 54 43 4c 20 69 6e 74 65 72 70 72   the TCL interpr
49d0: 65 74 65 72 2e 0a 2a 2f 0a 69 6e 74 20 53 71 6c  eter..*/.int Sql
49e0: 69 74 65 74 65 73 74 66 75 7a 7a 65 72 5f 49 6e  itetestfuzzer_In
49f0: 69 74 28 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69  it(Tcl_Interp *i
4a00: 6e 74 65 72 70 29 7b 0a 20 20 73 74 61 74 69 63  nterp){.  static
4a10: 20 73 74 72 75 63 74 20 7b 0a 20 20 20 20 20 63   struct {.     c
4a20: 68 61 72 20 2a 7a 4e 61 6d 65 3b 0a 20 20 20 20  har *zName;.    
4a30: 20 54 63 6c 5f 4f 62 6a 43 6d 64 50 72 6f 63 20   Tcl_ObjCmdProc 
4a40: 2a 78 50 72 6f 63 3b 0a 20 20 20 20 20 76 6f 69  *xProc;.     voi
4a50: 64 20 2a 63 6c 69 65 6e 74 44 61 74 61 3b 0a 20  d *clientData;. 
4a60: 20 7d 20 61 4f 62 6a 43 6d 64 5b 5d 20 3d 20 7b   } aObjCmd[] = {
4a70: 0a 20 20 20 20 20 7b 20 22 72 65 67 69 73 74 65  .     { "registe
4a80: 72 5f 66 75 7a 7a 65 72 5f 6d 6f 64 75 6c 65 22  r_fuzzer_module"
4a90: 2c 20 20 20 72 65 67 69 73 74 65 72 5f 66 75 7a  ,   register_fuz
4aa0: 7a 65 72 5f 6d 6f 64 75 6c 65 2c 20 30 20 7d 2c  zer_module, 0 },
4ab0: 0a 20 20 7d 3b 0a 20 20 69 6e 74 20 69 3b 0a 20  .  };.  int i;. 
4ac0: 20 66 6f 72 28 69 3d 30 3b 20 69 3c 73 69 7a 65   for(i=0; i<size
4ad0: 6f 66 28 61 4f 62 6a 43 6d 64 29 2f 73 69 7a 65  of(aObjCmd)/size
4ae0: 6f 66 28 61 4f 62 6a 43 6d 64 5b 30 5d 29 3b 20  of(aObjCmd[0]); 
4af0: 69 2b 2b 29 7b 0a 20 20 20 20 54 63 6c 5f 43 72  i++){.    Tcl_Cr
4b00: 65 61 74 65 4f 62 6a 43 6f 6d 6d 61 6e 64 28 69  eateObjCommand(i
4b10: 6e 74 65 72 70 2c 20 61 4f 62 6a 43 6d 64 5b 69  nterp, aObjCmd[i
4b20: 5d 2e 7a 4e 61 6d 65 2c 20 0a 20 20 20 20 20 20  ].zName, .      
4b30: 20 20 61 4f 62 6a 43 6d 64 5b 69 5d 2e 78 50 72    aObjCmd[i].xPr
4b40: 6f 63 2c 20 61 4f 62 6a 43 6d 64 5b 69 5d 2e 63  oc, aObjCmd[i].c
4b50: 6c 69 65 6e 74 44 61 74 61 2c 20 30 29 3b 0a 20  lientData, 0);. 
4b60: 20 7d 0a 20 20 72 65 74 75 72 6e 20 54 43 4c 5f   }.  return TCL_
4b70: 4f 4b 3b 0a 7d 0a 0a 23 65 6e 64 69 66 20 2f 2a  OK;.}..#endif /*
4b80: 20 53 51 4c 49 54 45 5f 54 45 53 54 20 2a 2f 0a   SQLITE_TEST */.