/ Hex Artifact Content
Login

Artifact b09d2f47bc3ae1485100b323479c5d785d4f6e4b:


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 0a 2f 2a 0a 2a 2a 20 45 61 63 68 20  m;.../*.** Each 
0390: 74 72 61 6e 73 66 6f 72 6d 61 74 69 6f 6e 20 72  transformation r
03a0: 75 6c 65 20 69 73 20 73 74 6f 72 65 64 20 61 73  ule is stored as
03b0: 20 61 6e 20 69 6e 73 74 61 6e 63 65 20 6f 66 20   an instance of 
03c0: 74 68 69 73 20 6f 62 6a 65 63 74 2e 0a 2a 2a 20  this object..** 
03d0: 41 6c 6c 20 72 75 6c 65 73 20 61 72 65 20 6b 65  All rules are ke
03e0: 70 74 20 6f 6e 20 61 20 6c 69 6e 6b 65 64 20 6c  pt on a linked l
03f0: 69 73 74 20 73 6f 72 74 65 64 20 62 79 20 72 43  ist sorted by rC
0400: 6f 73 74 2e 0a 2a 2f 0a 73 74 72 75 63 74 20 66  ost..*/.struct f
0410: 75 7a 7a 65 72 5f 72 75 6c 65 20 7b 0a 20 20 66  uzzer_rule {.  f
0420: 75 7a 7a 65 72 5f 72 75 6c 65 20 2a 70 4e 65 78  uzzer_rule *pNex
0430: 74 3b 20 20 20 2f 2a 20 4e 65 78 74 20 72 75 6c  t;   /* Next rul
0440: 65 20 69 6e 20 6f 72 64 65 72 20 6f 66 20 69 6e  e in order of in
0450: 63 72 65 61 73 69 6e 67 20 72 43 6f 73 74 20 2a  creasing rCost *
0460: 2f 0a 20 20 66 6c 6f 61 74 20 72 43 6f 73 74 3b  /.  float rCost;
0470: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43 6f 73            /* Cos
0480: 74 20 6f 66 20 74 68 69 73 20 74 72 61 6e 73 66  t of this transf
0490: 6f 72 6d 61 74 69 6f 6e 20 2a 2f 0a 20 20 63 68  ormation */.  ch
04a0: 61 72 20 2a 7a 46 72 6f 6d 3b 20 20 20 20 20 20  ar *zFrom;      
04b0: 20 20 20 20 2f 2a 20 54 72 61 6e 73 66 6f 72 6d      /* Transform
04c0: 20 66 72 6f 6d 20 2a 2f 0a 20 20 63 68 61 72 20   from */.  char 
04d0: 7a 54 6f 5b 34 5d 3b 20 20 20 20 20 20 20 20 20  zTo[4];         
04e0: 20 2f 2a 20 54 72 61 6e 73 66 6f 72 6d 20 74 6f   /* Transform to
04f0: 20 28 65 78 74 72 61 20 73 70 61 63 65 20 61 70   (extra space ap
0500: 70 65 6e 64 65 64 29 20 2a 2f 0a 7d 3b 0a 0a 2f  pended) */.};../
0510: 2a 0a 2a 2a 20 57 68 65 6e 20 67 65 6e 65 72 61  *.** When genera
0520: 74 69 6e 67 20 66 75 7a 7a 65 64 20 77 6f 72 64  ting fuzzed word
0530: 73 2c 20 77 65 20 68 61 76 65 20 74 6f 20 72 65  s, we have to re
0540: 6d 65 6d 62 65 72 20 61 6c 6c 20 70 72 65 76 69  member all previ
0550: 6f 75 73 6c 79 0a 2a 2a 20 67 65 6e 65 72 61 74  ously.** generat
0560: 65 64 20 74 65 72 6d 73 20 69 6e 20 6f 72 64 65  ed terms in orde
0570: 72 20 74 6f 20 73 75 70 70 72 65 73 73 20 64 75  r to suppress du
0580: 70 6c 69 63 61 74 65 73 2e 20 20 45 61 63 68 20  plicates.  Each 
0590: 70 72 65 76 69 6f 75 73 6c 79 0a 2a 2a 20 67 65  previously.** ge
05a0: 6e 65 72 61 74 65 64 20 74 65 72 6d 20 69 73 20  nerated term is 
05b0: 61 6e 20 69 6e 73 74 61 6e 63 65 20 6f 66 20 74  an instance of t
05c0: 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 73 74 72  he following str
05d0: 75 63 74 75 72 65 2e 0a 2a 2f 0a 73 74 72 75 63  ucture..*/.struc
05e0: 74 20 66 75 7a 7a 65 72 5f 73 65 65 6e 20 7b 0a  t fuzzer_seen {.
05f0: 20 20 66 75 7a 7a 65 72 5f 73 65 65 6e 20 2a 70    fuzzer_seen *p
0600: 4e 65 78 74 3b 20 20 20 20 2f 2a 20 4e 65 78 74  Next;    /* Next
0610: 20 77 69 74 68 20 74 68 65 20 73 61 6d 65 20 68   with the same h
0620: 61 73 68 20 2a 2f 0a 20 20 63 68 61 72 20 7a 57  ash */.  char zW
0630: 6f 72 64 5b 34 5d 3b 20 20 20 20 20 20 20 20 20  ord[4];         
0640: 2f 2a 20 54 68 65 20 67 65 6e 65 72 61 74 65 64  /* The generated
0650: 20 74 65 72 6d 2e 20 2a 2f 0a 7d 3b 0a 0a 2f 2a   term. */.};../*
0660: 0a 2a 2a 20 41 20 73 74 65 6d 20 6f 62 6a 65 63  .** A stem objec
0670: 74 20 69 73 20 75 73 65 64 20 74 6f 20 67 65 6e  t is used to gen
0680: 65 72 61 74 65 20 76 61 72 69 61 6e 74 73 2e 20  erate variants. 
0690: 20 0a 2a 2f 0a 73 74 72 75 63 74 20 66 75 7a 7a   .*/.struct fuzz
06a0: 65 72 5f 73 74 65 6d 20 7b 0a 20 20 63 68 61 72  er_stem {.  char
06b0: 20 2a 7a 42 61 73 69 73 3b 20 20 20 20 20 20 20   *zBasis;       
06c0: 20 20 20 20 2f 2a 20 57 6f 72 64 20 62 65 69 6e      /* Word bein
06d0: 67 20 66 75 7a 7a 65 64 20 2a 2f 0a 20 20 66 75  g fuzzed */.  fu
06e0: 7a 7a 65 72 5f 72 75 6c 65 20 2a 70 52 75 6c 65  zzer_rule *pRule
06f0: 3b 20 20 20 20 20 2f 2a 20 4e 65 78 74 20 72 75  ;     /* Next ru
0700: 6c 65 20 74 6f 20 61 70 70 6c 79 20 2a 2f 0a 20  le to apply */. 
0710: 20 69 6e 74 20 6e 3b 20 20 20 20 20 20 20 20 20   int n;         
0720: 20 20 20 20 20 20 20 20 20 2f 2a 20 41 70 70 6c           /* Appl
0730: 79 20 72 75 6c 65 20 61 74 20 74 68 69 73 20 63  y rule at this c
0740: 68 61 72 61 63 74 65 72 20 6f 66 66 73 65 74 20  haracter offset 
0750: 2a 2f 0a 20 20 66 6c 6f 61 74 20 72 42 61 73 65  */.  float rBase
0760: 43 6f 73 74 3b 20 20 20 20 20 20 20 20 2f 2a 20  Cost;        /* 
0770: 42 61 73 65 20 63 6f 73 74 20 6f 66 20 67 65 74  Base cost of get
0780: 74 69 6e 67 20 74 6f 20 7a 42 61 73 69 73 20 2a  ting to zBasis *
0790: 2f 0a 20 20 66 6c 6f 61 74 20 72 43 6f 73 74 3b  /.  float rCost;
07a0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 72              /* r
07b0: 42 61 73 65 43 6f 73 74 20 2b 20 63 6f 73 74 20  BaseCost + cost 
07c0: 6f 66 20 61 70 70 6c 79 69 6e 67 20 70 52 75 6c  of applying pRul
07d0: 65 20 61 74 20 6e 20 2a 2f 0a 20 20 66 75 7a 7a  e at n */.  fuzz
07e0: 65 72 5f 73 74 65 6d 20 2a 70 4e 65 78 74 3b 20  er_stem *pNext; 
07f0: 20 20 20 20 2f 2a 20 4e 65 78 74 20 73 74 65 6d      /* Next stem
0800: 20 69 6e 20 72 43 6f 73 74 20 6f 72 64 65 72 20   in rCost order 
0810: 2a 2f 0a 7d 3b 0a 0a 2f 2a 20 0a 2a 2a 20 41 20  */.};../* .** A 
0820: 66 75 7a 7a 65 72 20 76 69 72 74 75 61 6c 2d 74  fuzzer virtual-t
0830: 61 62 6c 65 20 6f 62 6a 65 63 74 20 0a 2a 2f 0a  able object .*/.
0840: 73 74 72 75 63 74 20 66 75 7a 7a 65 72 5f 76 74  struct fuzzer_vt
0850: 61 62 20 7b 0a 20 20 73 71 6c 69 74 65 33 5f 76  ab {.  sqlite3_v
0860: 74 61 62 20 62 61 73 65 3b 20 20 20 20 20 20 20  tab base;       
0870: 20 20 2f 2a 20 42 61 73 65 20 63 6c 61 73 73 20    /* Base class 
0880: 2d 20 6d 75 73 74 20 62 65 20 66 69 72 73 74 20  - must be first 
0890: 2a 2f 0a 20 20 63 68 61 72 20 2a 7a 43 6c 61 73  */.  char *zClas
08a0: 73 4e 61 6d 65 3b 20 20 20 20 20 20 20 20 20 20  sName;          
08b0: 2f 2a 20 4e 61 6d 65 20 6f 66 20 74 68 69 73 20  /* Name of this 
08c0: 63 6c 61 73 73 2e 20 20 44 65 66 61 75 6c 74 3a  class.  Default:
08d0: 20 22 66 75 7a 7a 65 72 22 20 2a 2f 0a 20 20 66   "fuzzer" */.  f
08e0: 75 7a 7a 65 72 5f 72 75 6c 65 20 2a 70 52 75 6c  uzzer_rule *pRul
08f0: 65 3b 20 20 20 20 20 20 20 20 2f 2a 20 41 6c 6c  e;        /* All
0900: 20 61 63 74 69 76 65 20 72 75 6c 65 73 20 69 6e   active rules in
0910: 20 74 68 69 73 20 66 75 7a 7a 65 72 20 2a 2f 0a   this fuzzer */.
0920: 20 20 66 75 7a 7a 65 72 5f 72 75 6c 65 20 2a 70    fuzzer_rule *p
0930: 4e 65 77 52 75 6c 65 3b 20 20 20 20 20 2f 2a 20  NewRule;     /* 
0940: 4e 65 77 20 72 75 6c 65 73 20 74 6f 20 61 64 64  New rules to add
0950: 20 77 68 65 6e 20 6c 61 73 74 20 63 75 72 73 6f   when last curso
0960: 72 20 65 78 70 69 72 65 73 20 2a 2f 0a 20 20 69  r expires */.  i
0970: 6e 74 20 6e 43 75 72 73 6f 72 3b 20 20 20 20 20  nt nCursor;     
0980: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d            /* Num
0990: 62 65 72 20 6f 66 20 61 63 74 69 76 65 20 63 75  ber of active cu
09a0: 72 73 6f 72 73 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 20  rsors */.};../* 
09b0: 41 20 66 75 7a 7a 65 72 20 63 75 72 73 6f 72 20  A fuzzer cursor 
09c0: 6f 62 6a 65 63 74 20 2a 2f 0a 73 74 72 75 63 74  object */.struct
09d0: 20 66 75 7a 7a 65 72 5f 63 75 72 73 6f 72 20 7b   fuzzer_cursor {
09e0: 0a 20 20 73 71 6c 69 74 65 33 5f 76 74 61 62 5f  .  sqlite3_vtab_
09f0: 63 75 72 73 6f 72 20 62 61 73 65 3b 20 20 2f 2a  cursor base;  /*
0a00: 20 42 61 73 65 20 63 6c 61 73 73 20 2d 20 6d 75   Base class - mu
0a10: 73 74 20 62 65 20 66 69 72 73 74 20 2a 2f 0a 20  st be first */. 
0a20: 20 66 6c 6f 61 74 20 72 4d 61 78 3b 20 20 20 20   float rMax;    
0a30: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4d              /* M
0a40: 61 78 69 6d 75 6d 20 63 6f 73 74 20 6f 66 20 61  aximum cost of a
0a50: 6e 79 20 74 65 72 6d 20 2a 2f 0a 20 20 66 75 7a  ny term */.  fuz
0a60: 7a 65 72 5f 73 74 65 6d 20 2a 70 53 74 65 6d 3b  zer_stem *pStem;
0a70: 20 20 20 20 20 20 20 20 2f 2a 20 53 6f 72 74 65          /* Sorte
0a80: 64 20 6c 69 73 74 20 6f 66 20 73 74 65 6d 73 20  d list of stems 
0a90: 66 6f 72 20 67 65 6e 65 72 61 74 69 6e 67 20 6e  for generating n
0aa0: 65 77 20 74 65 72 6d 73 20 2a 2f 0a 20 20 69 6e  ew terms */.  in
0ab0: 74 20 6e 53 65 65 6e 3b 20 20 20 20 20 20 20 20  t nSeen;        
0ac0: 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62           /* Numb
0ad0: 65 72 20 6f 66 20 74 65 72 6d 73 20 61 6c 72 65  er of terms alre
0ae0: 61 64 79 20 67 65 6e 65 72 61 74 65 64 20 2a 2f  ady generated */
0af0: 0a 20 20 69 6e 74 20 6e 48 61 73 68 3b 20 20 20  .  int nHash;   
0b00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
0b10: 20 4e 75 6d 62 65 72 20 6f 66 20 73 6c 6f 74 73   Number of slots
0b20: 20 69 6e 20 61 70 48 61 73 68 20 2a 2f 0a 20 20   in apHash */.  
0b30: 66 75 7a 7a 65 72 5f 73 65 65 6e 20 2a 2a 61 70  fuzzer_seen **ap
0b40: 48 61 73 68 3b 20 20 20 20 20 20 2f 2a 20 48 61  Hash;      /* Ha
0b50: 73 68 20 74 61 62 6c 65 20 6f 66 20 70 72 65 76  sh table of prev
0b60: 69 6f 75 73 6c 79 20 67 65 6e 65 72 61 74 65 64  iously generated
0b70: 20 74 65 72 6d 73 20 2a 2f 0a 7d 3b 0a 0a 2f 2a   terms */.};../*
0b80: 20 4d 65 74 68 6f 64 73 20 66 6f 72 20 74 68 65   Methods for the
0b90: 20 66 75 7a 7a 65 72 20 6d 6f 64 75 6c 65 20 2a   fuzzer module *
0ba0: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 66 75 7a  /.static int fuz
0bb0: 7a 65 72 43 6f 6e 6e 65 63 74 28 0a 20 20 73 71  zerConnect(.  sq
0bc0: 6c 69 74 65 33 20 2a 64 62 2c 0a 20 20 76 6f 69  lite3 *db,.  voi
0bd0: 64 20 2a 70 41 75 78 2c 0a 20 20 69 6e 74 20 61  d *pAux,.  int a
0be0: 72 67 63 2c 20 63 6f 6e 73 74 20 63 68 61 72 20  rgc, const char 
0bf0: 2a 63 6f 6e 73 74 2a 61 72 67 76 2c 0a 20 20 73  *const*argv,.  s
0c00: 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 2a 70 70  qlite3_vtab **pp
0c10: 56 74 61 62 2c 0a 20 20 63 68 61 72 20 2a 2a 70  Vtab,.  char **p
0c20: 7a 45 72 72 0a 29 7b 0a 20 20 66 75 7a 7a 65 72  zErr.){.  fuzzer
0c30: 5f 76 74 61 62 20 2a 70 4e 65 77 3b 0a 20 20 63  _vtab *pNew;.  c
0c40: 68 61 72 20 2a 7a 53 71 6c 3b 0a 20 20 69 6e 74  har *zSql;.  int
0c50: 20 6e 3b 0a 20 20 69 66 28 20 73 74 72 63 6d 70   n;.  if( strcmp
0c60: 28 61 72 67 76 5b 31 5d 2c 22 74 65 6d 70 22 29  (argv[1],"temp")
0c70: 21 3d 30 20 29 7b 0a 20 20 20 20 2a 70 7a 45 72  !=0 ){.    *pzEr
0c80: 72 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72 69  r = sqlite3_mpri
0c90: 6e 74 66 28 22 25 73 20 76 69 72 74 75 61 6c 20  ntf("%s virtual 
0ca0: 74 61 62 6c 65 73 20 6d 75 73 74 20 62 65 20 54  tables must be T
0cb0: 45 4d 50 22 2c 20 61 72 67 76 5b 30 5d 29 3b 0a  EMP", argv[0]);.
0cc0: 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54      return SQLIT
0cd0: 45 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a 20 20 6e  E_ERROR;.  }.  n
0ce0: 20 3d 20 73 74 72 6c 65 6e 28 61 72 67 76 5b 30   = strlen(argv[0
0cf0: 5d 29 20 2b 20 31 3b 0a 20 20 70 4e 65 77 20 3d  ]) + 1;.  pNew =
0d00: 20 73 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63 28   sqlite3_malloc(
0d10: 20 73 69 7a 65 6f 66 28 2a 70 4e 65 77 29 20 2b   sizeof(*pNew) +
0d20: 20 6e 20 29 3b 0a 20 20 69 66 28 20 70 4e 65 77   n );.  if( pNew
0d30: 3d 3d 30 20 29 20 72 65 74 75 72 6e 20 53 51 4c  ==0 ) return SQL
0d40: 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 70 4e 65  ITE_NOMEM;.  pNe
0d50: 77 2d 3e 7a 43 6c 61 73 73 4e 61 6d 65 20 3d 20  w->zClassName = 
0d60: 28 63 68 61 72 2a 29 26 70 4e 65 77 5b 31 5d 3b  (char*)&pNew[1];
0d70: 0a 20 20 6d 65 6d 63 70 79 28 70 4e 65 77 2d 3e  .  memcpy(pNew->
0d80: 7a 43 6c 61 73 73 4e 61 6d 65 2c 20 61 72 67 76  zClassName, argv
0d90: 5b 30 5d 2c 20 6e 29 3b 0a 20 20 7a 53 71 6c 20  [0], n);.  zSql 
0da0: 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74  = sqlite3_mprint
0db0: 66 28 0a 20 20 20 20 20 22 43 52 45 41 54 45 20  f(.     "CREATE 
0dc0: 54 41 42 4c 45 20 78 28 77 6f 72 64 2c 20 64 69  TABLE x(word, di
0dd0: 73 74 61 6e 63 65 2c 20 63 46 72 6f 6d 2c 20 63  stance, cFrom, c
0de0: 54 6f 2c 20 63 6f 73 74 2c 20 5c 22 25 77 5c 22  To, cost, \"%w\"
0df0: 20 48 49 44 44 45 4e 29 22 2c 0a 20 20 20 20 20   HIDDEN)",.     
0e00: 61 72 67 76 5b 32 5d 0a 20 20 29 3b 0a 20 20 73  argv[2].  );.  s
0e10: 71 6c 69 74 65 33 5f 64 65 63 6c 61 72 65 5f 76  qlite3_declare_v
0e20: 74 61 62 28 64 62 2c 20 7a 53 71 6c 29 3b 0a 20  tab(db, zSql);. 
0e30: 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 7a 53   sqlite3_free(zS
0e40: 71 6c 29 3b 0a 20 20 6d 65 6d 73 65 74 28 70 4e  ql);.  memset(pN
0e50: 65 77 2c 20 30 2c 20 73 69 7a 65 6f 66 28 2a 70  ew, 0, sizeof(*p
0e60: 4e 65 77 29 29 3b 0a 20 20 2a 70 70 56 74 61 62  New));.  *ppVtab
0e70: 20 3d 20 26 70 4e 65 77 2d 3e 62 61 73 65 3b 0a   = &pNew->base;.
0e80: 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f    return SQLITE_
0e90: 4f 4b 3b 0a 7d 0a 2f 2a 20 4e 6f 74 65 20 74 68  OK;.}./* Note th
0ea0: 61 74 20 66 6f 72 20 74 68 69 73 20 76 69 72 74  at for this virt
0eb0: 75 61 6c 20 74 61 62 6c 65 2c 20 74 68 65 20 78  ual table, the x
0ec0: 43 72 65 61 74 65 20 61 6e 64 20 78 43 6f 6e 6e  Create and xConn
0ed0: 65 63 74 0a 2a 2a 20 6d 65 74 68 6f 64 73 20 61  ect.** methods a
0ee0: 72 65 20 69 64 65 6e 74 69 63 61 6c 2e 20 2a 2f  re identical. */
0ef0: 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 66 75 7a  ..static int fuz
0f00: 7a 65 72 44 69 73 63 6f 6e 6e 65 63 74 28 73 71  zerDisconnect(sq
0f10: 6c 69 74 65 33 5f 76 74 61 62 20 2a 70 56 74 61  lite3_vtab *pVta
0f20: 62 29 7b 0a 20 20 66 75 7a 7a 65 72 5f 76 74 61  b){.  fuzzer_vta
0f30: 62 20 2a 70 20 3d 20 28 66 75 7a 7a 65 72 5f 76  b *p = (fuzzer_v
0f40: 74 61 62 2a 29 70 56 74 61 62 3b 0a 20 20 61 73  tab*)pVtab;.  as
0f50: 73 65 72 74 28 20 70 2d 3e 6e 43 75 72 73 6f 72  sert( p->nCursor
0f60: 3d 3d 30 20 29 3b 0a 20 20 64 6f 7b 0a 20 20 20  ==0 );.  do{.   
0f70: 20 77 68 69 6c 65 28 20 70 2d 3e 70 52 75 6c 65   while( p->pRule
0f80: 20 29 7b 0a 20 20 20 20 20 20 66 75 7a 7a 65 72   ){.      fuzzer
0f90: 5f 72 75 6c 65 20 2a 70 52 75 6c 65 20 3d 20 70  _rule *pRule = p
0fa0: 2d 3e 70 52 75 6c 65 3b 0a 20 20 20 20 20 20 70  ->pRule;.      p
0fb0: 2d 3e 70 52 75 6c 65 20 3d 20 70 52 75 6c 65 2d  ->pRule = pRule-
0fc0: 3e 70 4e 65 78 74 3b 0a 20 20 20 20 20 20 73 71  >pNext;.      sq
0fd0: 6c 69 74 65 33 5f 66 72 65 65 28 70 52 75 6c 65  lite3_free(pRule
0fe0: 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 70 2d 3e  );.    }.    p->
0ff0: 70 52 75 6c 65 20 3d 20 70 2d 3e 70 4e 65 77 52  pRule = p->pNewR
1000: 75 6c 65 3b 0a 20 20 20 20 70 2d 3e 70 4e 65 77  ule;.    p->pNew
1010: 52 75 6c 65 20 3d 20 30 3b 0a 20 20 7d 77 68 69  Rule = 0;.  }whi
1020: 6c 65 28 20 70 2d 3e 70 52 75 6c 65 20 29 3b 0a  le( p->pRule );.
1030: 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70    sqlite3_free(p
1040: 29 3b 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49  );.  return SQLI
1050: 54 45 5f 4f 4b 3b 0a 7d 0a 2f 2a 20 54 68 65 20  TE_OK;.}./* The 
1060: 78 44 69 73 63 6f 6e 6e 65 63 74 20 61 6e 64 20  xDisconnect and 
1070: 78 44 65 73 74 72 6f 79 20 6d 65 74 68 6f 64 73  xDestroy methods
1080: 20 61 72 65 20 61 6c 73 6f 20 74 68 65 20 73 61   are also the sa
1090: 6d 65 20 2a 2f 0a 0a 2f 2a 0a 2a 2a 20 54 68 65  me */../*.** The
10a0: 20 74 77 6f 20 69 6e 70 75 74 20 72 75 6c 65 20   two input rule 
10b0: 6c 69 73 74 73 20 61 72 65 20 62 6f 74 68 20 73  lists are both s
10c0: 6f 72 74 65 64 20 69 6e 20 6f 72 64 65 72 20 6f  orted in order o
10d0: 66 20 69 6e 63 72 65 61 73 69 6e 67 0a 2a 2a 20  f increasing.** 
10e0: 63 6f 73 74 2e 20 20 4d 65 72 67 65 20 74 68 65  cost.  Merge the
10f0: 6d 20 74 6f 67 65 74 68 65 72 20 69 6e 74 6f 20  m together into 
1100: 61 20 73 69 6e 67 6c 65 20 6c 69 73 74 2c 20 73  a single list, s
1110: 6f 72 74 65 64 20 62 79 20 63 6f 73 74 2c 20 61  orted by cost, a
1120: 6e 64 0a 2a 2a 20 72 65 74 75 72 6e 20 61 20 70  nd.** return a p
1130: 6f 69 6e 74 65 72 20 74 6f 20 74 68 65 20 68 65  ointer to the he
1140: 61 64 20 6f 66 20 74 68 61 74 20 6c 69 73 74 2e  ad of that list.
1150: 0a 2a 2f 0a 73 74 61 74 69 63 20 66 75 7a 7a 65  .*/.static fuzze
1160: 72 5f 72 75 6c 65 20 2a 66 75 7a 7a 65 72 4d 65  r_rule *fuzzerMe
1170: 72 67 65 52 75 6c 65 73 28 66 75 7a 7a 65 72 5f  rgeRules(fuzzer_
1180: 72 75 6c 65 20 2a 70 41 2c 20 66 75 7a 7a 65 72  rule *pA, fuzzer
1190: 5f 72 75 6c 65 20 2a 70 42 29 7b 0a 20 20 66 75  _rule *pB){.  fu
11a0: 7a 7a 65 72 5f 72 75 6c 65 20 68 65 61 64 3b 0a  zzer_rule head;.
11b0: 20 20 66 75 7a 7a 65 72 5f 72 75 6c 65 20 2a 70    fuzzer_rule *p
11c0: 54 61 69 6c 3b 0a 0a 20 20 70 54 61 69 6c 20 3d  Tail;..  pTail =
11d0: 20 20 26 68 65 61 64 3b 0a 20 20 77 68 69 6c 65    &head;.  while
11e0: 28 20 70 41 20 26 26 20 70 42 20 29 7b 0a 20 20  ( pA && pB ){.  
11f0: 20 20 69 66 28 20 70 41 2d 3e 72 43 6f 73 74 3c    if( pA->rCost<
1200: 3d 70 42 2d 3e 72 43 6f 73 74 20 29 7b 0a 20 20  =pB->rCost ){.  
1210: 20 20 20 20 70 54 61 69 6c 2d 3e 70 4e 65 78 74      pTail->pNext
1220: 20 3d 20 70 41 3b 0a 20 20 20 20 20 20 70 54 61   = pA;.      pTa
1230: 69 6c 20 3d 20 70 41 3b 0a 20 20 20 20 20 20 70  il = pA;.      p
1240: 41 20 3d 20 70 41 2d 3e 70 4e 65 78 74 3b 0a 20  A = pA->pNext;. 
1250: 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20     }else{.      
1260: 70 54 61 69 6c 2d 3e 70 4e 65 78 74 20 3d 20 70  pTail->pNext = p
1270: 42 3b 0a 20 20 20 20 20 20 70 54 61 69 6c 20 3d  B;.      pTail =
1280: 20 70 42 3b 0a 20 20 20 20 20 20 70 42 20 3d 20   pB;.      pB = 
1290: 70 42 2d 3e 70 4e 65 78 74 3b 0a 20 20 20 20 7d  pB->pNext;.    }
12a0: 0a 20 20 7d 0a 20 20 69 66 28 20 70 41 3d 3d 30  .  }.  if( pA==0
12b0: 20 29 7b 0a 20 20 20 20 70 54 61 69 6c 2d 3e 70   ){.    pTail->p
12c0: 4e 65 78 74 20 3d 20 70 42 3b 0a 20 20 7d 65 6c  Next = pB;.  }el
12d0: 73 65 7b 0a 20 20 20 20 70 54 61 69 6c 2d 3e 70  se{.    pTail->p
12e0: 4e 65 78 74 20 3d 20 70 41 3b 0a 20 20 7d 0a 20  Next = pA;.  }. 
12f0: 20 72 65 74 75 72 6e 20 68 65 61 64 2e 70 4e 65   return head.pNe
1300: 78 74 3b 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 4f 70  xt;.}.../*.** Op
1310: 65 6e 20 61 20 6e 65 77 20 66 75 7a 7a 65 72 20  en a new fuzzer 
1320: 63 75 72 73 6f 72 2e 0a 2a 2f 0a 73 74 61 74 69  cursor..*/.stati
1330: 63 20 69 6e 74 20 66 75 7a 7a 65 72 4f 70 65 6e  c int fuzzerOpen
1340: 28 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 70  (sqlite3_vtab *p
1350: 56 54 61 62 2c 20 73 71 6c 69 74 65 33 5f 76 74  VTab, sqlite3_vt
1360: 61 62 5f 63 75 72 73 6f 72 20 2a 2a 70 70 43 75  ab_cursor **ppCu
1370: 72 73 6f 72 29 7b 0a 20 20 66 75 7a 7a 65 72 5f  rsor){.  fuzzer_
1380: 76 74 61 62 20 2a 70 20 3d 20 28 66 75 7a 7a 65  vtab *p = (fuzze
1390: 72 5f 76 74 61 62 2a 29 70 56 54 61 62 3b 0a 20  r_vtab*)pVTab;. 
13a0: 20 66 75 7a 7a 65 72 5f 63 75 72 73 6f 72 20 2a   fuzzer_cursor *
13b0: 70 43 75 72 3b 0a 20 20 70 43 75 72 20 3d 20 73  pCur;.  pCur = s
13c0: 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63 28 20 73  qlite3_malloc( s
13d0: 69 7a 65 6f 66 28 2a 70 43 75 72 29 20 29 3b 0a  izeof(*pCur) );.
13e0: 20 20 69 66 28 20 70 43 75 72 3d 3d 30 20 29 20    if( pCur==0 ) 
13f0: 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f  return SQLITE_NO
1400: 4d 45 4d 3b 0a 20 20 6d 65 6d 73 65 74 28 70 43  MEM;.  memset(pC
1410: 75 72 2c 20 30 2c 20 73 69 7a 65 6f 66 28 2a 70  ur, 0, sizeof(*p
1420: 43 75 72 29 29 3b 0a 20 20 2a 70 70 43 75 72 73  Cur));.  *ppCurs
1430: 6f 72 20 3d 20 26 70 43 75 72 2d 3e 62 61 73 65  or = &pCur->base
1440: 3b 0a 20 20 69 66 28 20 70 2d 3e 6e 43 75 72 73  ;.  if( p->nCurs
1450: 6f 72 3d 3d 30 20 26 26 20 70 2d 3e 70 4e 65 77  or==0 && p->pNew
1460: 52 75 6c 65 20 29 7b 0a 20 20 20 20 75 6e 73 69  Rule ){.    unsi
1470: 67 6e 65 64 20 69 6e 74 20 69 3b 0a 20 20 20 20  gned int i;.    
1480: 66 75 7a 7a 65 72 5f 72 75 6c 65 20 2a 70 58 3b  fuzzer_rule *pX;
1490: 0a 20 20 20 20 66 75 7a 7a 65 72 5f 72 75 6c 65  .    fuzzer_rule
14a0: 20 2a 61 5b 31 35 5d 3b 0a 20 20 20 20 66 6f 72   *a[15];.    for
14b0: 28 69 3d 30 3b 20 69 3c 73 69 7a 65 6f 66 28 61  (i=0; i<sizeof(a
14c0: 29 2f 73 69 7a 65 6f 66 28 61 5b 30 5d 29 3b 20  )/sizeof(a[0]); 
14d0: 69 2b 2b 29 20 61 5b 69 5d 20 3d 20 30 3b 0a 20  i++) a[i] = 0;. 
14e0: 20 20 20 77 68 69 6c 65 28 20 28 70 58 20 3d 20     while( (pX = 
14f0: 70 2d 3e 70 4e 65 77 52 75 6c 65 29 21 3d 30 20  p->pNewRule)!=0 
1500: 29 7b 0a 20 20 20 20 20 20 70 2d 3e 70 4e 65 77  ){.      p->pNew
1510: 52 75 6c 65 20 3d 20 70 58 2d 3e 70 4e 65 78 74  Rule = pX->pNext
1520: 3b 0a 20 20 20 20 20 20 70 58 2d 3e 70 4e 65 78  ;.      pX->pNex
1530: 74 20 3d 20 30 3b 0a 20 20 20 20 20 20 66 6f 72  t = 0;.      for
1540: 28 69 3d 30 3b 20 61 5b 69 5d 20 26 26 20 69 3c  (i=0; a[i] && i<
1550: 73 69 7a 65 6f 66 28 61 29 2f 73 69 7a 65 6f 66  sizeof(a)/sizeof
1560: 28 61 5b 30 5d 29 2d 31 3b 20 69 2b 2b 29 7b 0a  (a[0])-1; i++){.
1570: 20 20 20 20 20 20 20 20 70 58 20 3d 20 66 75 7a          pX = fuz
1580: 7a 65 72 4d 65 72 67 65 52 75 6c 65 73 28 61 5b  zerMergeRules(a[
1590: 69 5d 2c 20 70 58 29 3b 0a 20 20 20 20 20 20 20  i], pX);.       
15a0: 20 61 5b 69 5d 20 3d 20 30 3b 0a 20 20 20 20 20   a[i] = 0;.     
15b0: 20 7d 0a 20 20 20 20 20 20 61 5b 69 5d 20 3d 20   }.      a[i] = 
15c0: 66 75 7a 7a 65 72 4d 65 72 67 65 52 75 6c 65 73  fuzzerMergeRules
15d0: 28 61 5b 69 5d 2c 20 70 58 29 3b 0a 20 20 20 20  (a[i], pX);.    
15e0: 7d 0a 20 20 20 20 66 6f 72 28 70 58 3d 61 5b 30  }.    for(pX=a[0
15f0: 5d 2c 20 69 3d 31 3b 20 69 3c 73 69 7a 65 6f 66  ], i=1; i<sizeof
1600: 28 61 29 2f 73 69 7a 65 6f 66 28 61 5b 30 5d 29  (a)/sizeof(a[0])
1610: 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20 70 58  ; i++){.      pX
1620: 20 3d 20 66 75 7a 7a 65 72 4d 65 72 67 65 52 75   = fuzzerMergeRu
1630: 6c 65 73 28 61 5b 69 5d 2c 20 70 58 29 3b 0a 20  les(a[i], pX);. 
1640: 20 20 20 7d 0a 20 20 20 20 70 2d 3e 70 52 75 6c     }.    p->pRul
1650: 65 20 3d 20 66 75 7a 7a 65 72 4d 65 72 67 65 52  e = fuzzerMergeR
1660: 75 6c 65 73 28 70 2d 3e 70 52 75 6c 65 2c 20 70  ules(p->pRule, p
1670: 58 29 3b 0a 20 20 7d 0a 20 20 20 0a 20 20 72 65  X);.  }.   .  re
1680: 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a  turn SQLITE_OK;.
1690: 7d 0a 0a 2f 2a 0a 2a 2a 20 43 6c 6f 73 65 20 61  }../*.** Close a
16a0: 20 66 75 7a 7a 65 72 20 63 75 72 73 6f 72 2e 0a   fuzzer cursor..
16b0: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 66 75  */.static int fu
16c0: 7a 7a 65 72 43 6c 6f 73 65 28 73 71 6c 69 74 65  zzerClose(sqlite
16d0: 33 5f 76 74 61 62 5f 63 75 72 73 6f 72 20 2a 63  3_vtab_cursor *c
16e0: 75 72 29 7b 0a 20 20 66 75 7a 7a 65 72 5f 63 75  ur){.  fuzzer_cu
16f0: 72 73 6f 72 20 2a 70 43 75 72 20 3d 20 28 66 75  rsor *pCur = (fu
1700: 7a 7a 65 72 5f 63 75 72 73 6f 72 20 2a 29 63 75  zzer_cursor *)cu
1710: 72 3b 0a 20 20 69 6e 74 20 69 3b 0a 20 20 66 6f  r;.  int i;.  fo
1720: 72 28 69 3d 30 3b 20 69 3c 70 43 75 72 2d 3e 6e  r(i=0; i<pCur->n
1730: 48 61 73 68 3b 20 69 2b 2b 29 7b 0a 20 20 20 20  Hash; i++){.    
1740: 66 75 7a 7a 65 72 5f 73 65 65 6e 20 2a 70 53 65  fuzzer_seen *pSe
1750: 65 6e 20 3d 20 70 43 75 72 2d 3e 61 70 48 61 73  en = pCur->apHas
1760: 68 5b 69 5d 3b 0a 20 20 20 20 77 68 69 6c 65 28  h[i];.    while(
1770: 20 70 53 65 65 6e 20 29 7b 0a 20 20 20 20 20 20   pSeen ){.      
1780: 66 75 7a 7a 65 72 5f 73 65 65 6e 20 2a 70 4e 65  fuzzer_seen *pNe
1790: 78 74 20 3d 20 70 53 65 65 6e 2d 3e 70 4e 65 78  xt = pSeen->pNex
17a0: 74 3b 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33  t;.      sqlite3
17b0: 5f 66 72 65 65 28 70 53 65 65 6e 29 3b 0a 20 20  _free(pSeen);.  
17c0: 20 20 20 20 70 53 65 65 6e 20 3d 20 70 4e 65 78      pSeen = pNex
17d0: 74 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 73  t;.    }.  }.  s
17e0: 71 6c 69 74 65 33 5f 66 72 65 65 28 70 43 75 72  qlite3_free(pCur
17f0: 2d 3e 61 70 48 61 73 68 29 3b 0a 20 20 77 68 69  ->apHash);.  whi
1800: 6c 65 28 20 70 43 75 72 2d 3e 70 53 74 65 6d 20  le( pCur->pStem 
1810: 29 7b 0a 20 20 20 20 66 75 7a 7a 65 72 5f 73 74  ){.    fuzzer_st
1820: 65 6d 20 2a 70 53 74 65 6d 20 3d 20 70 43 75 72  em *pStem = pCur
1830: 2d 3e 70 53 74 65 6d 3b 0a 20 20 20 20 70 43 75  ->pStem;.    pCu
1840: 72 2d 3e 70 53 74 65 6d 20 3d 20 70 53 74 65 6d  r->pStem = pStem
1850: 2d 3e 70 4e 65 78 74 3b 0a 20 20 20 20 73 71 6c  ->pNext;.    sql
1860: 69 74 65 33 5f 66 72 65 65 28 70 53 74 65 6d 29  ite3_free(pStem)
1870: 3b 0a 20 20 7d 0a 20 20 73 71 6c 69 74 65 33 5f  ;.  }.  sqlite3_
1880: 66 72 65 65 28 70 43 75 72 29 3b 0a 20 20 72 65  free(pCur);.  re
1890: 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a  turn SQLITE_OK;.
18a0: 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 66 75  }..static int fu
18b0: 7a 7a 65 72 4e 65 78 74 28 73 71 6c 69 74 65 33  zzerNext(sqlite3
18c0: 5f 76 74 61 62 5f 63 75 72 73 6f 72 20 2a 63 75  _vtab_cursor *cu
18d0: 72 29 7b 0a 20 20 72 65 74 75 72 6e 20 30 3b 0a  r){.  return 0;.
18e0: 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 66 75  }..static int fu
18f0: 7a 7a 65 72 46 69 6c 74 65 72 28 0a 20 20 73 71  zzerFilter(.  sq
1900: 6c 69 74 65 33 5f 76 74 61 62 5f 63 75 72 73 6f  lite3_vtab_curso
1910: 72 20 2a 70 56 74 61 62 43 75 72 73 6f 72 2c 20  r *pVtabCursor, 
1920: 0a 20 20 69 6e 74 20 69 64 78 4e 75 6d 2c 20 63  .  int idxNum, c
1930: 6f 6e 73 74 20 63 68 61 72 20 2a 69 64 78 53 74  onst char *idxSt
1940: 72 2c 0a 20 20 69 6e 74 20 61 72 67 63 2c 20 73  r,.  int argc, s
1950: 71 6c 69 74 65 33 5f 76 61 6c 75 65 20 2a 2a 61  qlite3_value **a
1960: 72 67 76 0a 29 7b 0a 20 20 66 75 7a 7a 65 72 5f  rgv.){.  fuzzer_
1970: 63 75 72 73 6f 72 20 2a 70 43 75 72 20 3d 20 28  cursor *pCur = (
1980: 66 75 7a 7a 65 72 5f 63 75 72 73 6f 72 20 2a 29  fuzzer_cursor *)
1990: 70 56 74 61 62 43 75 72 73 6f 72 3b 0a 20 20 72  pVtabCursor;.  r
19a0: 65 74 75 72 6e 20 66 75 7a 7a 65 72 4e 65 78 74  eturn fuzzerNext
19b0: 28 70 56 74 61 62 43 75 72 73 6f 72 29 3b 0a 7d  (pVtabCursor);.}
19c0: 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 66 75 7a  ..static int fuz
19d0: 7a 65 72 43 6f 6c 75 6d 6e 28 73 71 6c 69 74 65  zerColumn(sqlite
19e0: 33 5f 76 74 61 62 5f 63 75 72 73 6f 72 20 2a 63  3_vtab_cursor *c
19f0: 75 72 2c 20 73 71 6c 69 74 65 33 5f 63 6f 6e 74  ur, sqlite3_cont
1a00: 65 78 74 20 2a 63 74 78 2c 20 69 6e 74 20 69 29  ext *ctx, int i)
1a10: 7b 0a 20 20 66 75 7a 7a 65 72 5f 63 75 72 73 6f  {.  fuzzer_curso
1a20: 72 20 2a 70 43 75 72 20 3d 20 28 66 75 7a 7a 65  r *pCur = (fuzze
1a30: 72 5f 63 75 72 73 6f 72 2a 29 63 75 72 3b 0a 20  r_cursor*)cur;. 
1a40: 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f   return SQLITE_O
1a50: 4b 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74  K;.}..static int
1a60: 20 66 75 7a 7a 65 72 52 6f 77 69 64 28 73 71 6c   fuzzerRowid(sql
1a70: 69 74 65 33 5f 76 74 61 62 5f 63 75 72 73 6f 72  ite3_vtab_cursor
1a80: 20 2a 63 75 72 2c 20 73 71 6c 69 74 65 5f 69 6e   *cur, sqlite_in
1a90: 74 36 34 20 2a 70 52 6f 77 69 64 29 7b 0a 20 20  t64 *pRowid){.  
1aa0: 2a 70 52 6f 77 69 64 20 3d 20 30 3b 0a 20 20 72  *pRowid = 0;.  r
1ab0: 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b  eturn SQLITE_OK;
1ac0: 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 66  .}..static int f
1ad0: 75 7a 7a 65 72 45 6f 66 28 73 71 6c 69 74 65 33  uzzerEof(sqlite3
1ae0: 5f 76 74 61 62 5f 63 75 72 73 6f 72 20 2a 63 75  _vtab_cursor *cu
1af0: 72 29 7b 0a 20 20 66 75 7a 7a 65 72 5f 63 75 72  r){.  fuzzer_cur
1b00: 73 6f 72 20 2a 70 43 75 72 20 3d 20 28 66 75 7a  sor *pCur = (fuz
1b10: 7a 65 72 5f 63 75 72 73 6f 72 2a 29 63 75 72 3b  zer_cursor*)cur;
1b20: 0a 20 20 72 65 74 75 72 6e 20 31 3b 0a 7d 0a 0a  .  return 1;.}..
1b30: 73 74 61 74 69 63 20 69 6e 74 20 66 75 7a 7a 65  static int fuzze
1b40: 72 42 65 73 74 49 6e 64 65 78 28 73 71 6c 69 74  rBestIndex(sqlit
1b50: 65 33 5f 76 74 61 62 20 2a 74 61 62 2c 20 73 71  e3_vtab *tab, sq
1b60: 6c 69 74 65 33 5f 69 6e 64 65 78 5f 69 6e 66 6f  lite3_index_info
1b70: 20 2a 70 49 64 78 49 6e 66 6f 29 7b 0a 0a 20 20   *pIdxInfo){..  
1b80: 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b  return SQLITE_OK
1b90: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 44 69 73 61 6c  ;.}../*.** Disal
1ba0: 6c 6f 77 20 61 6c 6c 20 61 74 74 65 6d 70 74 73  low all attempts
1bb0: 20 74 6f 20 44 45 4c 45 54 45 20 6f 72 20 55 50   to DELETE or UP
1bc0: 44 41 54 45 2e 20 20 4f 6e 6c 79 20 49 4e 53 45  DATE.  Only INSE
1bd0: 52 54 73 20 61 72 65 20 61 6c 6c 6f 77 65 64 2e  RTs are allowed.
1be0: 0a 2a 2a 0a 2a 2a 20 4f 6e 20 61 6e 20 69 6e 73  .**.** On an ins
1bf0: 65 72 74 2c 20 74 68 65 20 63 46 72 6f 6d 2c 20  ert, the cFrom, 
1c00: 63 54 6f 2c 20 61 6e 64 20 63 6f 73 74 20 63 6f  cTo, and cost co
1c10: 6c 75 6d 6e 73 20 61 72 65 20 75 73 65 64 20 74  lumns are used t
1c20: 6f 20 63 6f 6e 73 74 72 75 63 74 0a 2a 2a 20 61  o construct.** a
1c30: 20 6e 65 77 20 72 75 6c 65 2e 20 20 20 41 6c 6c   new rule.   All
1c40: 20 6f 74 68 65 72 20 63 6f 6c 75 6d 6e 73 20 61   other columns a
1c50: 72 65 20 69 67 6e 6f 72 65 64 2e 20 20 54 68 65  re ignored.  The
1c60: 20 72 75 6c 65 20 69 73 20 69 67 6e 6f 72 65 64   rule is ignored
1c70: 0a 2a 2a 20 69 66 20 63 46 72 6f 6d 20 61 6e 64  .** if cFrom and
1c80: 20 63 54 6f 20 61 72 65 20 69 64 65 6e 74 69 63   cTo are identic
1c90: 61 6c 2e 20 20 41 20 4e 55 4c 4c 20 76 61 6c 75  al.  A NULL valu
1ca0: 65 20 66 6f 72 20 63 46 72 6f 6d 20 6f 72 20 63  e for cFrom or c
1cb0: 54 6f 20 69 73 0a 2a 2a 20 69 6e 74 65 72 70 72  To is.** interpr
1cc0: 65 74 65 64 20 61 73 20 61 6e 20 65 6d 70 74 79  eted as an empty
1cd0: 20 73 74 72 69 6e 67 2e 20 20 54 68 65 20 63 6f   string.  The co
1ce0: 73 74 20 6d 75 73 74 20 62 65 20 70 6f 73 69 74  st must be posit
1cf0: 69 76 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  ive..*/.static i
1d00: 6e 74 20 66 75 7a 7a 65 72 55 70 64 61 74 65 28  nt fuzzerUpdate(
1d10: 0a 20 20 73 71 6c 69 74 65 33 5f 76 74 61 62 20  .  sqlite3_vtab 
1d20: 2a 70 56 54 61 62 2c 0a 20 20 69 6e 74 20 61 72  *pVTab,.  int ar
1d30: 67 63 2c 0a 20 20 73 71 6c 69 74 65 33 5f 76 61  gc,.  sqlite3_va
1d40: 6c 75 65 20 2a 2a 61 72 67 76 2c 0a 20 20 73 71  lue **argv,.  sq
1d50: 6c 69 74 65 5f 69 6e 74 36 34 20 2a 70 52 6f 77  lite_int64 *pRow
1d60: 69 64 0a 29 7b 0a 20 20 66 75 7a 7a 65 72 5f 76  id.){.  fuzzer_v
1d70: 74 61 62 20 2a 70 20 3d 20 28 66 75 7a 7a 65 72  tab *p = (fuzzer
1d80: 5f 76 74 61 62 2a 29 70 56 54 61 62 3b 0a 20 20  _vtab*)pVTab;.  
1d90: 66 75 7a 7a 65 72 5f 72 75 6c 65 20 2a 70 52 75  fuzzer_rule *pRu
1da0: 6c 65 3b 0a 20 20 63 6f 6e 73 74 20 63 68 61 72  le;.  const char
1db0: 20 2a 7a 46 72 6f 6d 3b 0a 20 20 69 6e 74 20 6e   *zFrom;.  int n
1dc0: 46 72 6f 6d 3b 0a 20 20 63 6f 6e 73 74 20 63 68  From;.  const ch
1dd0: 61 72 20 2a 7a 54 6f 3b 0a 20 20 69 6e 74 20 6e  ar *zTo;.  int n
1de0: 54 6f 3b 0a 20 20 66 6c 6f 61 74 20 72 43 6f 73  To;.  float rCos
1df0: 74 3b 0a 20 20 69 66 28 20 61 72 67 63 21 3d 38  t;.  if( argc!=8
1e00: 20 29 7b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f   ){.    sqlite3_
1e10: 66 72 65 65 28 70 56 54 61 62 2d 3e 7a 45 72 72  free(pVTab->zErr
1e20: 4d 73 67 29 3b 0a 20 20 20 20 70 56 54 61 62 2d  Msg);.    pVTab-
1e30: 3e 7a 45 72 72 4d 73 67 20 3d 20 73 71 6c 69 74  >zErrMsg = sqlit
1e40: 65 33 5f 6d 70 72 69 6e 74 66 28 22 63 61 6e 6e  e3_mprintf("cann
1e50: 6f 74 20 64 65 6c 65 74 65 20 66 72 6f 6d 20 61  ot delete from a
1e60: 20 25 73 20 76 69 72 74 75 61 6c 20 74 61 62 6c   %s virtual tabl
1e70: 65 22 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20  e",.            
1e80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1e90: 20 20 20 20 20 20 20 20 20 70 2d 3e 7a 43 6c 61           p->zCla
1ea0: 73 73 4e 61 6d 65 29 3b 0a 20 20 20 20 72 65 74  ssName);.    ret
1eb0: 75 72 6e 20 53 51 4c 49 54 45 5f 43 4f 4e 53 54  urn SQLITE_CONST
1ec0: 52 41 49 4e 54 3b 0a 20 20 7d 0a 20 20 69 66 28  RAINT;.  }.  if(
1ed0: 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 74   sqlite3_value_t
1ee0: 79 70 65 28 61 72 67 76 5b 30 5d 29 21 3d 53 51  ype(argv[0])!=SQ
1ef0: 4c 49 54 45 5f 4e 55 4c 4c 20 29 7b 0a 20 20 20  LITE_NULL ){.   
1f00: 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70 56   sqlite3_free(pV
1f10: 54 61 62 2d 3e 7a 45 72 72 4d 73 67 29 3b 0a 20  Tab->zErrMsg);. 
1f20: 20 20 20 70 56 54 61 62 2d 3e 7a 45 72 72 4d 73     pVTab->zErrMs
1f30: 67 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72 69  g = sqlite3_mpri
1f40: 6e 74 66 28 22 63 61 6e 6e 6f 74 20 75 70 64 61  ntf("cannot upda
1f50: 74 65 20 61 20 25 73 20 76 69 72 74 75 61 6c 20  te a %s virtual 
1f60: 74 61 62 6c 65 22 2c 0a 20 20 20 20 20 20 20 20  table",.        
1f70: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1f80: 20 20 20 20 20 20 20 20 20 20 20 20 20 70 2d 3e               p->
1f90: 7a 43 6c 61 73 73 4e 61 6d 65 29 3b 0a 20 20 20  zClassName);.   
1fa0: 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 43   return SQLITE_C
1fb0: 4f 4e 53 54 52 41 49 4e 54 3b 0a 20 20 7d 0a 20  ONSTRAINT;.  }. 
1fc0: 20 7a 46 72 6f 6d 20 3d 20 28 63 68 61 72 2a 29   zFrom = (char*)
1fd0: 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 74 65  sqlite3_value_te
1fe0: 78 74 28 61 72 67 76 5b 34 5d 29 3b 0a 20 20 69  xt(argv[4]);.  i
1ff0: 66 28 20 7a 46 72 6f 6d 3d 3d 30 20 29 20 7a 46  f( zFrom==0 ) zF
2000: 72 6f 6d 20 3d 20 22 22 3b 0a 20 20 7a 54 6f 20  rom = "";.  zTo 
2010: 3d 20 28 63 68 61 72 2a 29 73 71 6c 69 74 65 33  = (char*)sqlite3
2020: 5f 76 61 6c 75 65 5f 74 65 78 74 28 61 72 67 76  _value_text(argv
2030: 5b 35 5d 29 3b 0a 20 20 69 66 28 20 7a 54 6f 3d  [5]);.  if( zTo=
2040: 3d 30 20 29 20 7a 54 6f 20 3d 20 22 22 3b 0a 20  =0 ) zTo = "";. 
2050: 20 69 66 28 20 73 74 72 63 6d 70 28 7a 46 72 6f   if( strcmp(zFro
2060: 6d 2c 7a 54 6f 29 3d 3d 30 20 29 7b 0a 20 20 20  m,zTo)==0 ){.   
2070: 20 2f 2a 20 53 69 6c 65 6e 74 6c 79 20 69 67 6e   /* Silently ign
2080: 6f 72 65 20 6e 75 6c 6c 20 74 72 61 6e 73 66 6f  ore null transfo
2090: 72 6d 61 74 69 6f 6e 73 20 2a 2f 0a 20 20 20 20  rmations */.    
20a0: 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b  return SQLITE_OK
20b0: 3b 0a 20 20 7d 0a 20 20 72 43 6f 73 74 20 3d 20  ;.  }.  rCost = 
20c0: 28 66 6c 6f 61 74 29 73 71 6c 69 74 65 33 5f 76  (float)sqlite3_v
20d0: 61 6c 75 65 5f 64 6f 75 62 6c 65 28 61 72 67 76  alue_double(argv
20e0: 5b 36 5d 29 3b 0a 20 20 69 66 28 20 72 43 6f 73  [6]);.  if( rCos
20f0: 74 3c 3d 30 20 29 7b 0a 20 20 20 20 73 71 6c 69  t<=0 ){.    sqli
2100: 74 65 33 5f 66 72 65 65 28 70 56 54 61 62 2d 3e  te3_free(pVTab->
2110: 7a 45 72 72 4d 73 67 29 3b 0a 20 20 20 20 70 56  zErrMsg);.    pV
2120: 54 61 62 2d 3e 7a 45 72 72 4d 73 67 20 3d 20 73  Tab->zErrMsg = s
2130: 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 22  qlite3_mprintf("
2140: 63 6f 73 74 20 6d 75 73 74 20 62 65 20 70 6f 73  cost must be pos
2150: 69 74 69 76 65 22 29 3b 0a 20 20 20 20 72 65 74  itive");.    ret
2160: 75 72 6e 20 53 51 4c 49 54 45 5f 43 4f 4e 53 54  urn SQLITE_CONST
2170: 52 41 49 4e 54 3b 20 20 20 20 0a 20 20 7d 0a 20  RAINT;    .  }. 
2180: 20 6e 46 72 6f 6d 20 3d 20 73 74 72 6c 65 6e 28   nFrom = strlen(
2190: 7a 46 72 6f 6d 29 2b 31 3b 0a 20 20 6e 54 6f 20  zFrom)+1;.  nTo 
21a0: 3d 20 73 74 72 6c 65 6e 28 7a 54 6f 29 2b 31 3b  = strlen(zTo)+1;
21b0: 0a 20 20 69 66 28 20 6e 54 6f 3c 34 20 29 20 6e  .  if( nTo<4 ) n
21c0: 54 6f 20 3d 20 34 3b 0a 20 20 70 52 75 6c 65 20  To = 4;.  pRule 
21d0: 3d 20 73 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63  = sqlite3_malloc
21e0: 28 20 73 69 7a 65 6f 66 28 2a 70 52 75 6c 65 29  ( sizeof(*pRule)
21f0: 20 2b 20 6e 46 72 6f 6d 20 2b 20 6e 54 6f 20 2d   + nFrom + nTo -
2200: 20 34 20 29 3b 0a 20 20 69 66 28 20 70 52 75 6c   4 );.  if( pRul
2210: 65 3d 3d 30 20 29 7b 0a 20 20 20 20 72 65 74 75  e==0 ){.    retu
2220: 72 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b  rn SQLITE_NOMEM;
2230: 0a 20 20 7d 0a 20 20 70 52 75 6c 65 2d 3e 7a 46  .  }.  pRule->zF
2240: 72 6f 6d 20 3d 20 26 70 52 75 6c 65 2d 3e 7a 54  rom = &pRule->zT
2250: 6f 5b 6e 54 6f 5d 3b 0a 20 20 6d 65 6d 63 70 79  o[nTo];.  memcpy
2260: 28 70 52 75 6c 65 2d 3e 7a 46 72 6f 6d 2c 20 7a  (pRule->zFrom, z
2270: 46 72 6f 6d 2c 20 6e 46 72 6f 6d 29 3b 0a 20 20  From, nFrom);.  
2280: 6d 65 6d 63 70 79 28 70 52 75 6c 65 2d 3e 7a 54  memcpy(pRule->zT
2290: 6f 2c 20 7a 54 6f 2c 20 6e 54 6f 29 3b 0a 20 20  o, zTo, nTo);.  
22a0: 70 52 75 6c 65 2d 3e 72 43 6f 73 74 20 3d 20 72  pRule->rCost = r
22b0: 43 6f 73 74 3b 0a 20 20 70 52 75 6c 65 2d 3e 70  Cost;.  pRule->p
22c0: 4e 65 78 74 20 3d 20 70 2d 3e 70 4e 65 77 52 75  Next = p->pNewRu
22d0: 6c 65 3b 0a 20 20 70 2d 3e 70 4e 65 77 52 75 6c  le;.  p->pNewRul
22e0: 65 20 3d 20 70 52 75 6c 65 3b 0a 20 20 72 65 74  e = pRule;.  ret
22f0: 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d  urn SQLITE_OK;.}
2300: 0a 0a 2f 2a 0a 2a 2a 20 41 20 76 69 72 74 75 61  ../*.** A virtua
2310: 6c 20 74 61 62 6c 65 20 6d 6f 64 75 6c 65 20 74  l table module t
2320: 68 61 74 20 70 72 6f 76 69 64 65 73 20 72 65 61  hat provides rea
2330: 64 2d 6f 6e 6c 79 20 61 63 63 65 73 73 20 74 6f  d-only access to
2340: 20 61 0a 2a 2a 20 54 63 6c 20 67 6c 6f 62 61 6c   a.** Tcl global
2350: 20 76 61 72 69 61 62 6c 65 20 6e 61 6d 65 73 70   variable namesp
2360: 61 63 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 73  ace..*/.static s
2370: 71 6c 69 74 65 33 5f 6d 6f 64 75 6c 65 20 66 75  qlite3_module fu
2380: 7a 7a 65 72 4d 6f 64 75 6c 65 20 3d 20 7b 0a 20  zzerModule = {. 
2390: 20 30 2c 20 20 20 20 20 20 20 20 20 20 20 20 20   0,             
23a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
23b0: 20 69 56 65 72 73 69 6f 6e 20 2a 2f 0a 20 20 66   iVersion */.  f
23c0: 75 7a 7a 65 72 43 6f 6e 6e 65 63 74 2c 0a 20 20  uzzerConnect,.  
23d0: 66 75 7a 7a 65 72 43 6f 6e 6e 65 63 74 2c 0a 20  fuzzerConnect,. 
23e0: 20 66 75 7a 7a 65 72 42 65 73 74 49 6e 64 65 78   fuzzerBestIndex
23f0: 2c 0a 20 20 66 75 7a 7a 65 72 44 69 73 63 6f 6e  ,.  fuzzerDiscon
2400: 6e 65 63 74 2c 20 0a 20 20 66 75 7a 7a 65 72 44  nect, .  fuzzerD
2410: 69 73 63 6f 6e 6e 65 63 74 2c 0a 20 20 66 75 7a  isconnect,.  fuz
2420: 7a 65 72 4f 70 65 6e 2c 20 20 20 20 20 20 20 20  zerOpen,        
2430: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 4f 70            /* xOp
2440: 65 6e 20 2d 20 6f 70 65 6e 20 61 20 63 75 72 73  en - open a curs
2450: 6f 72 20 2a 2f 0a 20 20 66 75 7a 7a 65 72 43 6c  or */.  fuzzerCl
2460: 6f 73 65 2c 20 20 20 20 20 20 20 20 20 20 20 20  ose,            
2470: 20 20 20 20 20 2f 2a 20 78 43 6c 6f 73 65 20 2d       /* xClose -
2480: 20 63 6c 6f 73 65 20 61 20 63 75 72 73 6f 72 20   close a cursor 
2490: 2a 2f 0a 20 20 66 75 7a 7a 65 72 46 69 6c 74 65  */.  fuzzerFilte
24a0: 72 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  r,              
24b0: 20 20 2f 2a 20 78 46 69 6c 74 65 72 20 2d 20 63    /* xFilter - c
24c0: 6f 6e 66 69 67 75 72 65 20 73 63 61 6e 20 63 6f  onfigure scan co
24d0: 6e 73 74 72 61 69 6e 74 73 20 2a 2f 0a 20 20 66  nstraints */.  f
24e0: 75 7a 7a 65 72 4e 65 78 74 2c 20 20 20 20 20 20  uzzerNext,      
24f0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78              /* x
2500: 4e 65 78 74 20 2d 20 61 64 76 61 6e 63 65 20 61  Next - advance a
2510: 20 63 75 72 73 6f 72 20 2a 2f 0a 20 20 66 75 7a   cursor */.  fuz
2520: 7a 65 72 45 6f 66 2c 20 20 20 20 20 20 20 20 20  zerEof,         
2530: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 45 6f            /* xEo
2540: 66 20 2d 20 63 68 65 63 6b 20 66 6f 72 20 65 6e  f - check for en
2550: 64 20 6f 66 20 73 63 61 6e 20 2a 2f 0a 20 20 66  d of scan */.  f
2560: 75 7a 7a 65 72 43 6f 6c 75 6d 6e 2c 20 20 20 20  uzzerColumn,    
2570: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78              /* x
2580: 43 6f 6c 75 6d 6e 20 2d 20 72 65 61 64 20 64 61  Column - read da
2590: 74 61 20 2a 2f 0a 20 20 66 75 7a 7a 65 72 52 6f  ta */.  fuzzerRo
25a0: 77 69 64 2c 20 20 20 20 20 20 20 20 20 20 20 20  wid,            
25b0: 20 20 20 20 20 2f 2a 20 78 52 6f 77 69 64 20 2d       /* xRowid -
25c0: 20 72 65 61 64 20 64 61 74 61 20 2a 2f 0a 20 20   read data */.  
25d0: 66 75 7a 7a 65 72 55 70 64 61 74 65 2c 20 20 20  fuzzerUpdate,   
25e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
25f0: 78 55 70 64 61 74 65 20 2d 20 49 4e 53 45 52 54  xUpdate - INSERT
2600: 20 2a 2f 0a 20 20 30 2c 20 20 20 20 20 20 20 20   */.  0,        
2610: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2620: 20 20 20 2f 2a 20 78 42 65 67 69 6e 20 2a 2f 0a     /* xBegin */.
2630: 20 20 30 2c 20 20 20 20 20 20 20 20 20 20 20 20    0,            
2640: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
2650: 2a 20 78 53 79 6e 63 20 2a 2f 0a 20 20 30 2c 20  * xSync */.  0, 
2660: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2670: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 43 6f            /* xCo
2680: 6d 6d 69 74 20 2a 2f 0a 20 20 30 2c 20 20 20 20  mmit */.  0,    
2690: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
26a0: 20 20 20 20 20 20 20 2f 2a 20 78 52 6f 6c 6c 62         /* xRollb
26b0: 61 63 6b 20 2a 2f 0a 20 20 30 2c 20 20 20 20 20  ack */.  0,     
26c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
26d0: 20 20 20 20 20 20 2f 2a 20 78 46 69 6e 64 4d 65        /* xFindMe
26e0: 74 68 6f 64 20 2a 2f 0a 20 20 30 2c 20 20 20 20  thod */.  0,    
26f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2700: 20 20 20 20 20 20 20 2f 2a 20 78 52 65 6e 61 6d         /* xRenam
2710: 65 20 2a 2f 0a 7d 3b 0a 0a 23 65 6e 64 69 66 20  e */.};..#endif 
2720: 2f 2a 20 53 51 4c 49 54 45 5f 4f 4d 49 54 5f 56  /* SQLITE_OMIT_V
2730: 49 52 54 55 41 4c 54 41 42 4c 45 20 2a 2f 0a 0a  IRTUALTABLE */..
2740: 0a 2f 2a 0a 2a 2a 20 52 65 67 69 73 74 65 72 20  ./*.** Register 
2750: 74 68 65 20 66 75 7a 7a 65 72 20 76 69 72 74 75  the fuzzer virtu
2760: 61 6c 20 74 61 62 6c 65 0a 2a 2f 0a 69 6e 74 20  al table.*/.int 
2770: 66 75 7a 7a 65 72 5f 72 65 67 69 73 74 65 72 28  fuzzer_register(
2780: 73 71 6c 69 74 65 33 20 2a 64 62 29 7b 0a 20 20  sqlite3 *db){.  
2790: 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f  int rc = SQLITE_
27a0: 4f 4b 3b 0a 23 69 66 6e 64 65 66 20 53 51 4c 49  OK;.#ifndef SQLI
27b0: 54 45 5f 4f 4d 49 54 5f 56 49 52 54 55 41 4c 54  TE_OMIT_VIRTUALT
27c0: 41 42 4c 45 0a 20 20 72 63 20 3d 20 73 71 6c 69  ABLE.  rc = sqli
27d0: 74 65 33 5f 63 72 65 61 74 65 5f 6d 6f 64 75 6c  te3_create_modul
27e0: 65 28 64 62 2c 20 22 66 75 7a 7a 65 72 22 2c 20  e(db, "fuzzer", 
27f0: 26 66 75 7a 7a 65 72 4d 6f 64 75 6c 65 2c 20 30  &fuzzerModule, 0
2800: 29 3b 0a 23 65 6e 64 69 66 0a 20 20 72 65 74 75  );.#endif.  retu
2810: 72 6e 20 72 63 3b 0a 7d 0a 0a 23 69 66 64 65 66  rn rc;.}..#ifdef
2820: 20 53 51 4c 49 54 45 5f 54 45 53 54 0a 23 69 6e   SQLITE_TEST.#in
2830: 63 6c 75 64 65 20 3c 74 63 6c 2e 68 3e 0a 2f 2a  clude <tcl.h>./*
2840: 0a 2a 2a 20 44 65 63 6f 64 65 20 61 20 70 6f 69  .** Decode a poi
2850: 6e 74 65 72 20 74 6f 20 61 6e 20 73 71 6c 69 74  nter to an sqlit
2860: 65 33 20 6f 62 6a 65 63 74 2e 0a 2a 2f 0a 65 78  e3 object..*/.ex
2870: 74 65 72 6e 20 69 6e 74 20 67 65 74 44 62 50 6f  tern int getDbPo
2880: 69 6e 74 65 72 28 54 63 6c 5f 49 6e 74 65 72 70  inter(Tcl_Interp
2890: 20 2a 69 6e 74 65 72 70 2c 20 63 6f 6e 73 74 20   *interp, const 
28a0: 63 68 61 72 20 2a 7a 41 2c 20 73 71 6c 69 74 65  char *zA, sqlite
28b0: 33 20 2a 2a 70 70 44 62 29 3b 0a 0a 2f 2a 0a 2a  3 **ppDb);../*.*
28c0: 2a 20 52 65 67 69 73 74 65 72 20 74 68 65 20 65  * Register the e
28d0: 63 68 6f 20 76 69 72 74 75 61 6c 20 74 61 62 6c  cho virtual tabl
28e0: 65 20 6d 6f 64 75 6c 65 2e 0a 2a 2f 0a 73 74 61  e module..*/.sta
28f0: 74 69 63 20 69 6e 74 20 72 65 67 69 73 74 65 72  tic int register
2900: 5f 66 75 7a 7a 65 72 5f 6d 6f 64 75 6c 65 28 0a  _fuzzer_module(.
2910: 20 20 43 6c 69 65 6e 74 44 61 74 61 20 63 6c 69    ClientData cli
2920: 65 6e 74 44 61 74 61 2c 20 2f 2a 20 50 6f 69 6e  entData, /* Poin
2930: 74 65 72 20 74 6f 20 73 71 6c 69 74 65 33 5f 65  ter to sqlite3_e
2940: 6e 61 62 6c 65 5f 58 58 58 20 66 75 6e 63 74 69  nable_XXX functi
2950: 6f 6e 20 2a 2f 0a 20 20 54 63 6c 5f 49 6e 74 65  on */.  Tcl_Inte
2960: 72 70 20 2a 69 6e 74 65 72 70 2c 20 20 20 20 2f  rp *interp,    /
2970: 2a 20 54 68 65 20 54 43 4c 20 69 6e 74 65 72 70  * The TCL interp
2980: 72 65 74 65 72 20 74 68 61 74 20 69 6e 76 6f 6b  reter that invok
2990: 65 64 20 74 68 69 73 20 63 6f 6d 6d 61 6e 64 20  ed this command 
29a0: 2a 2f 0a 20 20 69 6e 74 20 6f 62 6a 63 2c 20 20  */.  int objc,  
29b0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e              /* N
29c0: 75 6d 62 65 72 20 6f 66 20 61 72 67 75 6d 65 6e  umber of argumen
29d0: 74 73 20 2a 2f 0a 20 20 54 63 6c 5f 4f 62 6a 20  ts */.  Tcl_Obj 
29e0: 2a 43 4f 4e 53 54 20 6f 62 6a 76 5b 5d 20 20 2f  *CONST objv[]  /
29f0: 2a 20 43 6f 6d 6d 61 6e 64 20 61 72 67 75 6d 65  * Command argume
2a00: 6e 74 73 20 2a 2f 0a 29 7b 0a 20 20 73 71 6c 69  nts */.){.  sqli
2a10: 74 65 33 20 2a 64 62 3b 0a 20 20 69 66 28 20 6f  te3 *db;.  if( o
2a20: 62 6a 63 21 3d 32 20 29 7b 0a 20 20 20 20 54 63  bjc!=2 ){.    Tc
2a30: 6c 5f 57 72 6f 6e 67 4e 75 6d 41 72 67 73 28 69  l_WrongNumArgs(i
2a40: 6e 74 65 72 70 2c 20 31 2c 20 6f 62 6a 76 2c 20  nterp, 1, objv, 
2a50: 22 44 42 22 29 3b 0a 20 20 20 20 72 65 74 75 72  "DB");.    retur
2a60: 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 7d  n TCL_ERROR;.  }
2a70: 0a 20 20 69 66 28 20 67 65 74 44 62 50 6f 69 6e  .  if( getDbPoin
2a80: 74 65 72 28 69 6e 74 65 72 70 2c 20 54 63 6c 5f  ter(interp, Tcl_
2a90: 47 65 74 53 74 72 69 6e 67 28 6f 62 6a 76 5b 31  GetString(objv[1
2aa0: 5d 29 2c 20 26 64 62 29 20 29 20 72 65 74 75 72  ]), &db) ) retur
2ab0: 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 66  n TCL_ERROR;.  f
2ac0: 75 7a 7a 65 72 5f 72 65 67 69 73 74 65 72 28 64  uzzer_register(d
2ad0: 62 29 3b 0a 20 20 72 65 74 75 72 6e 20 54 43 4c  b);.  return TCL
2ae0: 5f 4f 4b 3b 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 52  _OK;.}.../*.** R
2af0: 65 67 69 73 74 65 72 20 63 6f 6d 6d 61 6e 64 73  egister commands
2b00: 20 77 69 74 68 20 74 68 65 20 54 43 4c 20 69 6e   with the TCL in
2b10: 74 65 72 70 72 65 74 65 72 2e 0a 2a 2f 0a 69 6e  terpreter..*/.in
2b20: 74 20 53 71 6c 69 74 65 74 65 73 74 66 75 7a 7a  t Sqlitetestfuzz
2b30: 65 72 5f 49 6e 69 74 28 54 63 6c 5f 49 6e 74 65  er_Init(Tcl_Inte
2b40: 72 70 20 2a 69 6e 74 65 72 70 29 7b 0a 20 20 73  rp *interp){.  s
2b50: 74 61 74 69 63 20 73 74 72 75 63 74 20 7b 0a 20  tatic struct {. 
2b60: 20 20 20 20 63 68 61 72 20 2a 7a 4e 61 6d 65 3b      char *zName;
2b70: 0a 20 20 20 20 20 54 63 6c 5f 4f 62 6a 43 6d 64  .     Tcl_ObjCmd
2b80: 50 72 6f 63 20 2a 78 50 72 6f 63 3b 0a 20 20 20  Proc *xProc;.   
2b90: 20 20 76 6f 69 64 20 2a 63 6c 69 65 6e 74 44 61    void *clientDa
2ba0: 74 61 3b 0a 20 20 7d 20 61 4f 62 6a 43 6d 64 5b  ta;.  } aObjCmd[
2bb0: 5d 20 3d 20 7b 0a 20 20 20 20 20 7b 20 22 72 65  ] = {.     { "re
2bc0: 67 69 73 74 65 72 5f 66 75 7a 7a 65 72 5f 6d 6f  gister_fuzzer_mo
2bd0: 64 75 6c 65 22 2c 20 20 20 72 65 67 69 73 74 65  dule",   registe
2be0: 72 5f 66 75 7a 7a 65 72 5f 6d 6f 64 75 6c 65 2c  r_fuzzer_module,
2bf0: 20 30 20 7d 2c 0a 20 20 7d 3b 0a 20 20 69 6e 74   0 },.  };.  int
2c00: 20 69 3b 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69   i;.  for(i=0; i
2c10: 3c 73 69 7a 65 6f 66 28 61 4f 62 6a 43 6d 64 29  <sizeof(aObjCmd)
2c20: 2f 73 69 7a 65 6f 66 28 61 4f 62 6a 43 6d 64 5b  /sizeof(aObjCmd[
2c30: 30 5d 29 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 54  0]); i++){.    T
2c40: 63 6c 5f 43 72 65 61 74 65 4f 62 6a 43 6f 6d 6d  cl_CreateObjComm
2c50: 61 6e 64 28 69 6e 74 65 72 70 2c 20 61 4f 62 6a  and(interp, aObj
2c60: 43 6d 64 5b 69 5d 2e 7a 4e 61 6d 65 2c 20 0a 20  Cmd[i].zName, . 
2c70: 20 20 20 20 20 20 20 61 4f 62 6a 43 6d 64 5b 69         aObjCmd[i
2c80: 5d 2e 78 50 72 6f 63 2c 20 61 4f 62 6a 43 6d 64  ].xProc, aObjCmd
2c90: 5b 69 5d 2e 63 6c 69 65 6e 74 44 61 74 61 2c 20  [i].clientData, 
2ca0: 30 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e  0);.  }.  return
2cb0: 20 54 43 4c 5f 4f 4b 3b 0a 7d 0a 0a 23 65 6e 64   TCL_OK;.}..#end
2cc0: 69 66 20 2f 2a 20 53 51 4c 49 54 45 5f 54 45 53  if /* SQLITE_TES
2cd0: 54 20 2a 2f 0a                                   T */.