/ Hex Artifact Content
Login

Artifact c0a6a807a553eaa220bf69fca0353cd1587a3bfb3d2224fa425e3e6efcacc98a:


0000: 2f 2a 0a 2a 2a 20 32 30 31 33 2d 30 33 2d 31 34  /*.** 2013-03-14
0010: 0a 2a 2a 0a 2a 2a 20 54 68 65 20 61 75 74 68 6f  .**.** The autho
0020: 72 20 64 69 73 63 6c 61 69 6d 73 20 63 6f 70 79  r disclaims copy
0030: 72 69 67 68 74 20 74 6f 20 74 68 69 73 20 73 6f  right to this so
0040: 75 72 63 65 20 63 6f 64 65 2e 20 20 49 6e 20 70  urce code.  In p
0050: 6c 61 63 65 20 6f 66 0a 2a 2a 20 61 20 6c 65 67  lace of.** a leg
0060: 61 6c 20 6e 6f 74 69 63 65 2c 20 68 65 72 65 20  al notice, here 
0070: 69 73 20 61 20 62 6c 65 73 73 69 6e 67 3a 0a 2a  is a blessing:.*
0080: 2a 0a 2a 2a 20 20 20 20 4d 61 79 20 79 6f 75 20  *.**    May you 
0090: 64 6f 20 67 6f 6f 64 20 61 6e 64 20 6e 6f 74 20  do good and not 
00a0: 65 76 69 6c 2e 0a 2a 2a 20 20 20 20 4d 61 79 20  evil..**    May 
00b0: 79 6f 75 20 66 69 6e 64 20 66 6f 72 67 69 76 65  you find forgive
00c0: 6e 65 73 73 20 66 6f 72 20 79 6f 75 72 73 65 6c  ness for yoursel
00d0: 66 20 61 6e 64 20 66 6f 72 67 69 76 65 20 6f 74  f and forgive ot
00e0: 68 65 72 73 2e 0a 2a 2a 20 20 20 20 4d 61 79 20  hers..**    May 
00f0: 79 6f 75 20 73 68 61 72 65 20 66 72 65 65 6c 79  you share freely
0100: 2c 20 6e 65 76 65 72 20 74 61 6b 69 6e 67 20 6d  , never taking m
0110: 6f 72 65 20 74 68 61 6e 20 79 6f 75 20 67 69 76  ore than you giv
0120: 65 2e 0a 2a 2a 0a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  e..**.**********
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 0a  ***************.
0170: 2a 2a 0a 2a 2a 20 54 68 69 73 20 66 69 6c 65 20  **.** This file 
0180: 63 6f 6e 74 61 69 6e 73 20 63 6f 64 65 20 66 6f  contains code fo
0190: 72 20 61 20 64 65 6d 6f 6e 73 74 72 61 74 69 6f  r a demonstratio
01a0: 6e 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65 20  n virtual table 
01b0: 74 68 61 74 20 66 69 6e 64 73 0a 2a 2a 20 22 61  that finds.** "a
01c0: 70 70 72 6f 78 69 6d 61 74 65 20 6d 61 74 63 68  pproximate match
01d0: 65 73 22 20 2d 20 73 74 72 69 6e 67 73 20 66 72  es" - strings fr
01e0: 6f 6d 20 61 20 66 69 6e 69 74 65 20 73 65 74 20  om a finite set 
01f0: 74 68 61 74 20 61 72 65 20 6e 65 61 72 6c 79 20  that are nearly 
0200: 74 68 65 0a 2a 2a 20 73 61 6d 65 20 61 73 20 61  the.** same as a
0210: 20 73 69 6e 67 6c 65 20 69 6e 70 75 74 20 73 74   single input st
0220: 72 69 6e 67 2e 20 20 54 68 65 20 76 69 72 74 75  ring.  The virtu
0230: 61 6c 20 74 61 62 6c 65 20 69 73 20 63 61 6c 6c  al table is call
0240: 65 64 20 22 61 6d 61 74 63 68 22 2e 0a 2a 2a 0a  ed "amatch"..**.
0250: 2a 2a 20 41 20 61 6d 61 74 63 68 20 76 69 72 74  ** A amatch virt
0260: 75 61 6c 20 74 61 62 6c 65 20 69 73 20 63 72 65  ual table is cre
0270: 61 74 65 64 20 6c 69 6b 65 20 74 68 69 73 3a 0a  ated like this:.
0280: 2a 2a 0a 2a 2a 20 20 20 20 20 43 52 45 41 54 45  **.**     CREATE
0290: 20 56 49 52 54 55 41 4c 20 54 41 42 4c 45 20 66   VIRTUAL TABLE f
02a0: 20 55 53 49 4e 47 20 61 70 70 72 6f 78 69 6d 61   USING approxima
02b0: 74 65 5f 6d 61 74 63 68 28 0a 2a 2a 20 20 20 20  te_match(.**    
02c0: 20 20 20 20 76 6f 63 61 62 75 6c 61 72 79 5f 74      vocabulary_t
02d0: 61 62 6c 65 3d 3c 74 61 62 6c 65 6e 61 6d 65 3e  able=<tablename>
02e0: 2c 20 20 20 20 20 20 2d 2d 20 56 0a 2a 2a 20 20  ,      -- V.**  
02f0: 20 20 20 20 20 20 76 6f 63 61 62 75 6c 61 72 79        vocabulary
0300: 5f 77 6f 72 64 3d 3c 63 6f 6c 75 6d 6e 6e 61 6d  _word=<columnnam
0310: 65 3e 2c 20 20 20 20 20 20 2d 2d 20 57 0a 2a 2a  e>,      -- W.**
0320: 20 20 20 20 20 20 20 20 76 6f 63 61 62 75 6c 61          vocabula
0330: 72 79 5f 6c 61 6e 67 75 61 67 65 3d 3c 63 6f 6c  ry_language=<col
0340: 75 6d 6e 6e 61 6d 65 3e 2c 20 20 2d 2d 20 4c 0a  umnname>,  -- L.
0350: 2a 2a 20 20 20 20 20 20 20 20 65 64 69 74 5f 64  **        edit_d
0360: 69 73 74 61 6e 63 65 73 3d 3c 65 64 69 74 2d 63  istances=<edit-c
0370: 6f 73 74 2d 74 61 62 6c 65 3e 0a 2a 2a 20 20 20  ost-table>.**   
0380: 20 20 29 3b 0a 2a 2a 0a 2a 2a 20 57 68 65 6e 20    );.**.** When 
0390: 69 74 20 69 73 20 63 72 65 61 74 65 64 2c 20 74  it is created, t
03a0: 68 65 20 6e 65 77 20 61 6d 61 74 63 68 20 74 61  he new amatch ta
03b0: 62 6c 65 20 6d 75 73 74 20 62 65 20 73 75 70 70  ble must be supp
03c0: 6c 69 65 64 20 77 69 74 68 20 74 68 65 0a 2a 2a  lied with the.**
03d0: 20 74 68 65 20 6e 61 6d 65 20 6f 66 20 61 20 74   the name of a t
03e0: 61 62 6c 65 20 56 20 61 6e 64 20 63 6f 6c 75 6d  able V and colum
03f0: 6e 73 20 56 2e 57 20 61 6e 64 20 56 2e 4c 20 73  ns V.W and V.L s
0400: 75 63 68 20 74 68 61 74 20 0a 2a 2a 0a 2a 2a 20  uch that .**.** 
0410: 20 20 20 20 53 45 4c 45 43 54 20 57 20 46 52 4f      SELECT W FRO
0420: 4d 20 56 20 57 48 45 52 45 20 4c 3d 24 6c 61 6e  M V WHERE L=$lan
0430: 67 75 61 67 65 0a 2a 2a 0a 2a 2a 20 72 65 74 75  guage.**.** retu
0440: 72 6e 73 20 74 68 65 20 61 6c 6c 6f 77 65 64 20  rns the allowed 
0450: 76 6f 63 61 62 75 6c 61 72 79 20 66 6f 72 20 74  vocabulary for t
0460: 68 65 20 6d 61 74 63 68 2e 20 20 49 66 20 74 68  he match.  If th
0470: 65 20 22 76 6f 63 61 62 75 6c 61 72 79 5f 6c 61  e "vocabulary_la
0480: 6e 67 75 61 67 65 22 0a 2a 2a 20 6f 72 20 4c 20  nguage".** or L 
0490: 63 6f 6c 75 6d 6e 6e 61 6d 65 20 69 73 20 6c 65  columnname is le
04a0: 66 74 20 75 6e 73 70 65 63 69 66 69 65 64 20 6f  ft unspecified o
04b0: 72 20 69 73 20 61 6e 20 65 6d 70 74 79 20 73 74  r is an empty st
04c0: 72 69 6e 67 2c 20 74 68 65 6e 20 6e 6f 0a 2a 2a  ring, then no.**
04d0: 20 66 69 6c 74 65 72 69 6e 67 20 6f 66 20 74 68   filtering of th
04e0: 65 20 76 6f 63 61 62 75 6c 61 72 79 20 62 79 20  e vocabulary by 
04f0: 6c 61 6e 67 75 61 67 65 20 69 73 20 70 65 72 66  language is perf
0500: 6f 72 6d 65 64 2e 20 0a 2a 2a 0a 2a 2a 20 46 6f  ormed. .**.** Fo
0510: 72 20 65 66 66 69 63 69 65 6e 63 79 2c 20 69 74  r efficiency, it
0520: 20 69 73 20 65 73 73 65 6e 74 69 61 6c 20 74 68   is essential th
0530: 61 74 20 74 68 65 20 76 6f 63 61 62 75 6c 61 72  at the vocabular
0540: 79 20 74 61 62 6c 65 20 62 65 20 69 6e 64 65 78  y table be index
0550: 65 64 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20 43 52  ed:.**.**     CR
0560: 45 41 54 45 20 76 6f 63 61 62 5f 69 6e 64 65 78  EATE vocab_index
0570: 20 4f 4e 20 56 28 57 29 0a 2a 2a 0a 2a 2a 20 41   ON V(W).**.** A
0580: 20 73 65 70 61 72 61 74 65 20 65 64 69 74 2d 63   separate edit-c
0590: 6f 73 74 2d 74 61 62 6c 65 20 70 72 6f 76 69 64  ost-table provid
05a0: 65 73 20 73 63 6f 72 69 6e 67 20 69 6e 66 6f 72  es scoring infor
05b0: 6d 61 74 69 6f 6e 20 74 68 61 74 20 64 65 66 69  mation that defi
05c0: 6e 65 73 20 0a 2a 2a 20 77 68 61 74 20 69 74 20  nes .** what it 
05d0: 6d 65 61 6e 73 20 66 6f 72 20 6f 6e 65 20 73 74  means for one st
05e0: 72 69 6e 67 20 74 6f 20 62 65 20 22 63 6c 6f 73  ring to be "clos
05f0: 65 22 20 74 6f 20 61 6e 6f 74 68 65 72 2e 0a 2a  e" to another..*
0600: 2a 0a 2a 2a 20 54 68 65 20 65 64 69 74 2d 63 6f  *.** The edit-co
0610: 73 74 2d 74 61 62 6c 65 20 6d 75 73 74 20 63 6f  st-table must co
0620: 6e 74 61 69 6e 20 65 78 61 63 74 6c 79 20 66 6f  ntain exactly fo
0630: 75 72 20 63 6f 6c 75 6d 6e 73 20 28 6d 6f 72 65  ur columns (more
0640: 20 70 72 65 63 69 73 65 6c 79 2c 0a 2a 2a 20 74   precisely,.** t
0650: 68 65 20 73 74 61 74 65 6d 65 6e 74 20 22 53 45  he statement "SE
0660: 4c 45 43 54 20 2a 20 46 52 4f 4d 20 3c 65 64 69  LECT * FROM <edi
0670: 74 2d 63 6f 73 74 2d 74 61 62 6c 65 3e 22 20 6d  t-cost-table>" m
0680: 75 73 74 20 72 65 74 75 72 6e 20 72 65 63 6f 72  ust return recor
0690: 64 73 0a 2a 2a 20 74 68 61 74 20 63 6f 6e 73 69  ds.** that consi
06a0: 73 74 20 6f 66 20 66 6f 75 72 20 63 6f 6c 75 6d  st of four colum
06b0: 6e 73 29 2e 20 49 74 20 64 6f 65 73 20 6e 6f 74  ns). It does not
06c0: 20 6d 61 74 74 65 72 20 77 68 61 74 20 74 68 65   matter what the
06d0: 20 63 6f 6c 75 6d 6e 73 20 61 72 65 0a 2a 2a 20   columns are.** 
06e0: 6e 61 6d 65 64 2e 20 0a 2a 2a 0a 2a 2a 20 45 61  named. .**.** Ea
06f0: 63 68 20 72 6f 77 20 69 6e 20 74 68 65 20 65 64  ch row in the ed
0700: 69 74 2d 63 6f 73 74 2d 74 61 62 6c 65 20 72 65  it-cost-table re
0710: 70 72 65 73 65 6e 74 73 20 61 20 73 69 6e 67 6c  presents a singl
0720: 65 20 63 68 61 72 61 63 74 65 72 0a 2a 2a 20 74  e character.** t
0730: 72 61 6e 73 66 6f 72 6d 61 74 69 6f 6e 20 67 6f  ransformation go
0740: 69 6e 67 20 66 72 6f 6d 20 75 73 65 72 20 69 6e  ing from user in
0750: 70 75 74 20 74 6f 20 74 68 65 20 76 6f 63 61 62  put to the vocab
0760: 75 6c 61 72 79 2e 20 54 68 65 20 6c 65 66 74 6d  ulary. The leftm
0770: 6f 73 74 20 0a 2a 2a 20 63 6f 6c 75 6d 6e 20 6f  ost .** column o
0780: 66 20 74 68 65 20 72 6f 77 20 28 63 6f 6c 75 6d  f the row (colum
0790: 6e 20 30 29 20 63 6f 6e 74 61 69 6e 73 20 61 6e  n 0) contains an
07a0: 20 69 6e 74 65 67 65 72 20 69 64 65 6e 74 69 66   integer identif
07b0: 69 65 72 20 6f 66 20 74 68 65 0a 2a 2a 20 6c 61  ier of the.** la
07c0: 6e 67 75 61 67 65 20 74 6f 20 77 68 69 63 68 20  nguage to which 
07d0: 74 68 65 20 74 72 61 6e 73 66 6f 72 6d 61 74 69  the transformati
07e0: 6f 6e 20 72 75 6c 65 20 62 65 6c 6f 6e 67 73 20  on rule belongs 
07f0: 28 73 65 65 20 22 4d 55 4c 54 49 50 4c 45 20 4c  (see "MULTIPLE L
0800: 41 4e 47 55 41 47 45 53 22 0a 2a 2a 20 62 65 6c  ANGUAGES".** bel
0810: 6f 77 29 2e 20 54 68 65 20 73 65 63 6f 6e 64 20  ow). The second 
0820: 63 6f 6c 75 6d 6e 20 6f 66 20 74 68 65 20 72 6f  column of the ro
0830: 77 20 28 63 6f 6c 75 6d 6e 20 31 29 20 63 6f 6e  w (column 1) con
0840: 74 61 69 6e 73 20 74 68 65 20 69 6e 70 75 74 0a  tains the input.
0850: 2a 2a 20 63 68 61 72 61 63 74 65 72 20 6f 72 20  ** character or 
0860: 63 68 61 72 61 63 74 65 72 73 20 2d 20 74 68 65  characters - the
0870: 20 63 68 61 72 61 63 74 65 72 73 20 6f 66 20 75   characters of u
0880: 73 65 72 20 69 6e 70 75 74 2e 20 54 68 65 20 74  ser input. The t
0890: 68 69 72 64 20 0a 2a 2a 20 63 6f 6c 75 6d 6e 20  hird .** column 
08a0: 63 6f 6e 74 61 69 6e 73 20 63 68 61 72 61 63 74  contains charact
08b0: 65 72 73 20 61 73 20 74 68 65 79 20 61 70 70 65  ers as they appe
08c0: 61 72 20 69 6e 20 74 68 65 20 76 6f 63 61 62 75  ar in the vocabu
08d0: 6c 61 72 79 20 74 61 62 6c 65 2e 0a 2a 2a 20 41  lary table..** A
08e0: 6e 64 20 74 68 65 20 66 6f 75 72 74 68 20 63 6f  nd the fourth co
08f0: 6c 75 6d 6e 20 63 6f 6e 74 61 69 6e 73 20 74 68  lumn contains th
0900: 65 20 69 6e 74 65 67 65 72 20 63 6f 73 74 20 6f  e integer cost o
0910: 66 20 6d 61 6b 69 6e 67 20 74 68 65 0a 2a 2a 20  f making the.** 
0920: 74 72 61 6e 73 66 6f 72 6d 61 74 69 6f 6e 2e 20  transformation. 
0930: 46 6f 72 20 65 78 61 6d 70 6c 65 3a 0a 2a 2a 0a  For example:.**.
0940: 2a 2a 20 20 20 20 43 52 45 41 54 45 20 54 41 42  **    CREATE TAB
0950: 4c 45 20 66 5f 64 61 74 61 28 69 4c 61 6e 67 2c  LE f_data(iLang,
0960: 20 63 46 72 6f 6d 2c 20 63 54 6f 2c 20 43 6f 73   cFrom, cTo, Cos
0970: 74 29 3b 0a 2a 2a 20 20 20 20 49 4e 53 45 52 54  t);.**    INSERT
0980: 20 49 4e 54 4f 20 66 5f 64 61 74 61 28 69 4c 61   INTO f_data(iLa
0990: 6e 67 2c 20 63 46 72 6f 6d 2c 20 63 54 6f 2c 20  ng, cFrom, cTo, 
09a0: 43 6f 73 74 29 20 56 41 4c 55 45 53 28 30 2c 20  Cost) VALUES(0, 
09b0: 27 27 2c 20 27 61 27 2c 20 31 30 30 29 3b 0a 2a  '', 'a', 100);.*
09c0: 2a 20 20 20 20 49 4e 53 45 52 54 20 49 4e 54 4f  *    INSERT INTO
09d0: 20 66 5f 64 61 74 61 28 69 4c 61 6e 67 2c 20 63   f_data(iLang, c
09e0: 46 72 6f 6d 2c 20 63 54 6f 2c 20 43 6f 73 74 29  From, cTo, Cost)
09f0: 20 56 41 4c 55 45 53 28 30 2c 20 27 62 27 2c 20   VALUES(0, 'b', 
0a00: 27 27 2c 20 38 37 29 3b 0a 2a 2a 20 20 20 20 49  '', 87);.**    I
0a10: 4e 53 45 52 54 20 49 4e 54 4f 20 66 5f 64 61 74  NSERT INTO f_dat
0a20: 61 28 69 4c 61 6e 67 2c 20 63 46 72 6f 6d 2c 20  a(iLang, cFrom, 
0a30: 63 54 6f 2c 20 43 6f 73 74 29 20 56 41 4c 55 45  cTo, Cost) VALUE
0a40: 53 28 30 2c 20 27 6f 27 2c 20 27 6f 65 27 2c 20  S(0, 'o', 'oe', 
0a50: 33 38 29 3b 0a 2a 2a 20 20 20 20 49 4e 53 45 52  38);.**    INSER
0a60: 54 20 49 4e 54 4f 20 66 5f 64 61 74 61 28 69 4c  T INTO f_data(iL
0a70: 61 6e 67 2c 20 63 46 72 6f 6d 2c 20 63 54 6f 2c  ang, cFrom, cTo,
0a80: 20 43 6f 73 74 29 20 56 41 4c 55 45 53 28 30 2c   Cost) VALUES(0,
0a90: 20 27 6f 65 27 2c 20 27 6f 27 2c 20 34 30 29 3b   'oe', 'o', 40);
0aa0: 0a 2a 2a 0a 2a 2a 20 54 68 65 20 66 69 72 73 74  .**.** The first
0ab0: 20 72 6f 77 20 69 6e 73 65 72 74 65 64 20 69 6e   row inserted in
0ac0: 74 6f 20 74 68 65 20 65 64 69 74 2d 63 6f 73 74  to the edit-cost
0ad0: 2d 74 61 62 6c 65 20 62 79 20 74 68 65 20 53 51  -table by the SQ
0ae0: 4c 20 73 63 72 69 70 74 0a 2a 2a 20 61 62 6f 76  L script.** abov
0af0: 65 20 69 6e 64 69 63 61 74 65 73 20 74 68 61 74  e indicates that
0b00: 20 74 68 65 20 63 6f 73 74 20 6f 66 20 68 61 76   the cost of hav
0b10: 69 6e 67 20 61 6e 20 65 78 74 72 61 20 27 61 27  ing an extra 'a'
0b20: 20 69 6e 20 74 68 65 20 76 6f 63 61 62 75 6c 61   in the vocabula
0b30: 72 79 0a 2a 2a 20 74 61 62 6c 65 20 74 68 61 74  ry.** table that
0b40: 20 69 73 20 6d 69 73 73 69 6e 67 20 69 6e 20 74   is missing in t
0b50: 68 65 20 75 73 65 72 20 69 6e 70 75 74 20 31 30  he user input 10
0b60: 30 2e 20 20 28 41 6c 6c 20 63 6f 73 74 73 20 61  0.  (All costs a
0b70: 72 65 20 69 6e 74 65 67 65 72 73 2e 0a 2a 2a 20  re integers..** 
0b80: 4f 76 65 72 61 6c 6c 20 63 6f 73 74 20 6d 75 73  Overall cost mus
0b90: 74 20 6e 6f 74 20 65 78 63 65 65 64 20 31 36 37  t not exceed 167
0ba0: 37 37 32 31 36 2e 29 20 20 54 68 65 20 73 65 63  77216.)  The sec
0bb0: 6f 6e 64 20 49 4e 53 45 52 54 20 73 74 61 74 65  ond INSERT state
0bc0: 6d 65 6e 74 20 0a 2a 2a 20 63 72 65 61 74 65 73  ment .** creates
0bd0: 20 61 20 72 75 6c 65 20 73 61 79 69 6e 67 20 74   a rule saying t
0be0: 68 61 74 20 74 68 65 20 63 6f 73 74 20 6f 66 20  hat the cost of 
0bf0: 68 61 76 69 6e 67 20 61 20 73 69 6e 67 6c 65 20  having a single 
0c00: 6c 65 74 74 65 72 20 27 62 27 20 69 6e 0a 2a 2a  letter 'b' in.**
0c10: 20 75 73 65 72 20 69 6e 70 75 74 20 77 68 69 63   user input whic
0c20: 68 20 69 73 20 6d 69 73 73 69 6e 67 20 69 6e 20  h is missing in 
0c30: 74 68 65 20 76 6f 63 61 62 75 6c 61 72 79 20 74  the vocabulary t
0c40: 61 62 6c 65 20 69 73 20 38 37 2e 20 20 54 68 65  able is 87.  The
0c50: 20 74 68 69 72 64 0a 2a 2a 20 49 4e 53 45 52 54   third.** INSERT
0c60: 20 73 74 61 74 65 6d 65 6e 74 20 6d 65 61 6e 20   statement mean 
0c70: 74 68 61 74 20 74 68 65 20 63 6f 73 74 20 6f 66  that the cost of
0c80: 20 6d 61 74 63 68 69 6e 67 20 61 6e 20 27 6f 27   matching an 'o'
0c90: 20 69 6e 20 75 73 65 72 20 69 6e 70 75 74 20 0a   in user input .
0ca0: 2a 2a 20 61 67 61 69 6e 73 74 20 61 6e 20 27 6f  ** against an 'o
0cb0: 65 27 20 69 6e 20 74 68 65 20 76 6f 63 61 62 75  e' in the vocabu
0cc0: 6c 61 72 79 20 74 61 62 6c 65 20 69 73 20 33 38  lary table is 38
0cd0: 2e 20 20 41 6e 64 20 73 6f 20 66 6f 72 74 68 2e  .  And so forth.
0ce0: 0a 2a 2a 0a 2a 2a 20 54 68 65 20 66 6f 6c 6c 6f  .**.** The follo
0cf0: 77 69 6e 67 20 72 75 6c 65 73 20 61 72 65 20 73  wing rules are s
0d00: 70 65 63 69 61 6c 3a 0a 2a 2a 0a 2a 2a 20 20 20  pecial:.**.**   
0d10: 20 49 4e 53 45 52 54 20 49 4e 54 4f 20 66 5f 64   INSERT INTO f_d
0d20: 61 74 61 28 69 4c 61 6e 67 2c 20 63 46 72 6f 6d  ata(iLang, cFrom
0d30: 2c 20 63 54 6f 2c 20 43 6f 73 74 29 20 56 41 4c  , cTo, Cost) VAL
0d40: 55 45 53 28 30 2c 20 27 3f 27 2c 20 27 27 2c 20  UES(0, '?', '', 
0d50: 39 37 29 3b 0a 2a 2a 20 20 20 20 49 4e 53 45 52  97);.**    INSER
0d60: 54 20 49 4e 54 4f 20 66 5f 64 61 74 61 28 69 4c  T INTO f_data(iL
0d70: 61 6e 67 2c 20 63 46 72 6f 6d 2c 20 63 54 6f 2c  ang, cFrom, cTo,
0d80: 20 43 6f 73 74 29 20 56 41 4c 55 45 53 28 30 2c   Cost) VALUES(0,
0d90: 20 27 27 2c 20 27 3f 27 2c 20 39 38 29 3b 0a 2a   '', '?', 98);.*
0da0: 2a 20 20 20 20 49 4e 53 45 52 54 20 49 4e 54 4f  *    INSERT INTO
0db0: 20 66 5f 64 61 74 61 28 69 4c 61 6e 67 2c 20 63   f_data(iLang, c
0dc0: 46 72 6f 6d 2c 20 63 54 6f 2c 20 43 6f 73 74 29  From, cTo, Cost)
0dd0: 20 56 41 4c 55 45 53 28 30 2c 20 27 3f 27 2c 20   VALUES(0, '?', 
0de0: 27 3f 27 2c 20 39 39 29 3b 0a 2a 2a 0a 2a 2a 20  '?', 99);.**.** 
0df0: 54 68 65 20 27 3f 27 20 74 6f 20 27 27 20 72 75  The '?' to '' ru
0e00: 6c 65 20 69 73 20 74 68 65 20 63 6f 73 74 20 6f  le is the cost o
0e10: 66 20 68 61 76 69 6e 67 20 61 6e 79 20 73 69 6e  f having any sin
0e20: 67 6c 65 20 63 68 61 72 61 63 74 65 72 20 69 6e  gle character in
0e30: 20 74 68 65 20 69 6e 70 75 74 0a 2a 2a 20 74 68   the input.** th
0e40: 61 74 20 69 73 20 6e 6f 74 20 66 6f 75 6e 64 20  at is not found 
0e50: 69 6e 20 74 68 65 20 76 6f 63 61 62 75 6c 61 72  in the vocabular
0e60: 2e 20 20 54 68 65 20 27 27 20 74 6f 20 27 3f 27  .  The '' to '?'
0e70: 20 72 75 6c 65 20 69 73 20 74 68 65 20 63 6f 73   rule is the cos
0e80: 74 20 6f 66 0a 2a 2a 20 68 61 76 69 6e 67 20 61  t of.** having a
0e90: 20 63 68 61 72 61 63 74 65 72 20 69 6e 20 74 68   character in th
0ea0: 65 20 76 6f 63 61 62 75 6c 61 72 79 20 74 61 62  e vocabulary tab
0eb0: 6c 65 20 74 68 61 74 20 69 73 20 6d 69 73 73 69  le that is missi
0ec0: 6e 67 20 66 72 6f 6d 20 69 6e 70 75 74 2e 0a 2a  ng from input..*
0ed0: 2a 20 41 6e 64 20 74 68 65 20 27 3f 27 20 74 6f  * And the '?' to
0ee0: 20 27 3f 27 20 72 75 6c 65 20 69 73 20 74 68 65   '?' rule is the
0ef0: 20 63 6f 73 74 20 6f 66 20 64 6f 69 6e 67 20 61   cost of doing a
0f00: 6e 20 61 72 62 69 74 72 61 72 79 20 63 68 61 72  n arbitrary char
0f10: 61 63 74 65 72 0a 2a 2a 20 73 75 62 73 74 69 74  acter.** substit
0f20: 75 74 69 6f 6e 2e 20 20 54 68 65 73 65 20 74 68  ution.  These th
0f30: 72 65 65 20 67 65 6e 65 72 69 63 20 72 75 6c 65  ree generic rule
0f40: 73 20 61 70 70 6c 79 20 61 63 72 6f 73 73 20 61  s apply across a
0f50: 6c 6c 20 6c 61 6e 67 75 61 67 65 73 2e 0a 2a 2a  ll languages..**
0f60: 20 49 6e 20 6f 74 68 65 72 20 77 6f 72 64 73 2c   In other words,
0f70: 20 74 68 65 20 69 4c 61 6e 67 20 66 69 65 6c 64   the iLang field
0f80: 20 69 73 20 69 67 6e 6f 72 65 64 20 66 6f 72 20   is ignored for 
0f90: 74 68 65 20 67 65 6e 65 72 69 63 20 73 75 62 73  the generic subs
0fa0: 74 69 74 75 74 69 6f 6e 0a 2a 2a 20 72 75 6c 65  titution.** rule
0fb0: 73 2e 20 20 49 66 20 6d 6f 72 65 20 74 68 61 6e  s.  If more than
0fc0: 20 6f 6e 65 20 63 6f 73 74 20 69 73 20 67 69 76   one cost is giv
0fd0: 65 6e 20 66 6f 72 20 61 20 67 65 6e 65 72 69 63  en for a generic
0fe0: 20 73 75 62 73 74 69 74 75 74 69 6f 6e 20 72 75   substitution ru
0ff0: 6c 65 2c 0a 2a 2a 20 74 68 65 6e 20 74 68 65 20  le,.** then the 
1000: 6c 6f 77 65 73 74 20 63 6f 73 74 20 69 73 20 75  lowest cost is u
1010: 73 65 64 2e 0a 2a 2a 0a 2a 2a 20 4f 6e 63 65 20  sed..**.** Once 
1020: 69 74 20 68 61 73 20 62 65 65 6e 20 63 72 65 61  it has been crea
1030: 74 65 64 2c 20 74 68 65 20 61 6d 61 74 63 68 20  ted, the amatch 
1040: 76 69 72 74 75 61 6c 20 74 61 62 6c 65 20 63 61  virtual table ca
1050: 6e 20 62 65 20 71 75 65 72 69 65 64 0a 2a 2a 20  n be queried.** 
1060: 61 73 20 66 6f 6c 6c 6f 77 73 3a 0a 2a 2a 0a 2a  as follows:.**.*
1070: 2a 20 20 20 20 53 45 4c 45 43 54 20 77 6f 72 64  *    SELECT word
1080: 2c 20 64 69 73 74 61 6e 63 65 20 46 52 4f 4d 20  , distance FROM 
1090: 66 0a 2a 2a 20 20 20 20 20 57 48 45 52 45 20 77  f.**     WHERE w
10a0: 6f 72 64 20 4d 41 54 43 48 20 27 61 62 63 64 65  ord MATCH 'abcde
10b0: 66 67 27 0a 2a 2a 20 20 20 20 20 20 20 41 4e 44  fg'.**       AND
10c0: 20 64 69 73 74 61 6e 63 65 3c 32 30 30 3b 0a 2a   distance<200;.*
10d0: 2a 0a 2a 2a 20 54 68 69 73 20 71 75 65 72 79 20  *.** This query 
10e0: 6f 75 74 70 75 74 73 20 74 68 65 20 73 74 72 69  outputs the stri
10f0: 6e 67 73 20 63 6f 6e 74 61 69 6e 65 64 20 69 6e  ngs contained in
1100: 20 74 68 65 20 54 28 46 29 20 66 69 65 6c 64 20   the T(F) field 
1110: 74 68 61 74 0a 2a 2a 20 61 72 65 20 63 6c 6f 73  that.** are clos
1120: 65 20 74 6f 20 22 61 62 63 64 65 66 67 22 20 61  e to "abcdefg" a
1130: 6e 64 20 69 6e 20 6f 72 64 65 72 20 6f 66 20 69  nd in order of i
1140: 6e 63 72 65 61 73 69 6e 67 20 64 69 73 74 61 6e  ncreasing distan
1150: 63 65 2e 20 20 4e 6f 20 73 74 72 69 6e 67 0a 2a  ce.  No string.*
1160: 2a 20 69 73 20 6f 75 74 70 75 74 20 6d 6f 72 65  * is output more
1170: 20 74 68 61 6e 20 6f 6e 63 65 2e 20 20 49 66 20   than once.  If 
1180: 74 68 65 72 65 20 61 72 65 20 6d 75 6c 74 69 70  there are multip
1190: 6c 65 20 77 61 79 73 20 74 6f 20 74 72 61 6e 73  le ways to trans
11a0: 66 6f 72 6d 20 74 68 65 0a 2a 2a 20 74 61 72 67  form the.** targ
11b0: 65 74 20 73 74 72 69 6e 67 20 28 22 61 62 63 64  et string ("abcd
11c0: 65 66 67 22 29 20 69 6e 74 6f 20 61 20 73 74 72  efg") into a str
11d0: 69 6e 67 20 69 6e 20 74 68 65 20 76 6f 63 61 62  ing in the vocab
11e0: 75 6c 61 72 79 20 74 61 62 6c 65 20 74 68 65 6e  ulary table then
11f0: 0a 2a 2a 20 74 68 65 20 6c 6f 77 65 73 74 20 63  .** the lowest c
1200: 6f 73 74 20 74 72 61 6e 73 66 6f 72 6d 20 69 73  ost transform is
1210: 20 74 68 65 20 6f 6e 65 20 74 68 61 74 20 69 73   the one that is
1220: 20 72 65 74 75 72 6e 65 64 2e 20 20 49 6e 20 74   returned.  In t
1230: 68 69 73 20 65 78 61 6d 70 6c 65 2c 0a 2a 2a 20  his example,.** 
1240: 74 68 65 20 73 65 61 72 63 68 20 69 73 20 6c 69  the search is li
1250: 6d 69 74 65 64 20 74 6f 20 73 74 72 69 6e 67 73  mited to strings
1260: 20 77 69 74 68 20 61 20 74 6f 74 61 6c 20 64 69   with a total di
1270: 73 74 61 6e 63 65 20 6f 66 20 6c 65 73 73 20 74  stance of less t
1280: 68 61 6e 20 32 30 30 2e 0a 2a 2a 0a 2a 2a 20 46  han 200..**.** F
1290: 6f 72 20 65 66 66 69 63 69 65 6e 63 79 2c 20 69  or efficiency, i
12a0: 74 20 69 73 20 69 6d 70 6f 72 74 61 6e 74 20 74  t is important t
12b0: 6f 20 70 75 74 20 74 69 67 68 74 20 62 6f 75 6e  o put tight boun
12c0: 64 73 20 6f 6e 20 74 68 65 20 64 69 73 74 61 6e  ds on the distan
12d0: 63 65 2e 0a 2a 2a 20 54 68 65 20 74 69 6d 65 20  ce..** The time 
12e0: 61 6e 64 20 6d 65 6d 6f 72 79 20 73 70 61 63 65  and memory space
12f0: 20 6e 65 65 64 65 64 20 74 6f 20 70 65 72 66 6f   needed to perfo
1300: 72 6d 20 74 68 69 73 20 71 75 65 72 79 20 69 73  rm this query is
1310: 20 65 78 70 6f 6e 65 6e 74 69 61 6c 0a 2a 2a 20   exponential.** 
1320: 69 6e 20 74 68 65 20 6d 61 78 69 6d 75 6d 20 64  in the maximum d
1330: 69 73 74 61 6e 63 65 2e 20 20 41 20 67 6f 6f 64  istance.  A good
1340: 20 72 75 6c 65 20 6f 66 20 74 68 75 6d 62 20 69   rule of thumb i
1350: 73 20 74 6f 20 6c 69 6d 69 74 20 74 68 65 20 64  s to limit the d
1360: 69 73 74 61 6e 63 65 0a 2a 2a 20 74 6f 20 6e 6f  istance.** to no
1370: 20 6d 6f 72 65 20 74 68 61 6e 20 31 2e 35 20 6f   more than 1.5 o
1380: 72 20 32 20 74 69 6d 65 73 20 74 68 65 20 6d 61  r 2 times the ma
1390: 78 69 6d 75 6d 20 63 6f 73 74 20 6f 66 20 61 6e  ximum cost of an
13a0: 79 20 72 75 6c 65 20 69 6e 20 74 68 65 0a 2a 2a  y rule in the.**
13b0: 20 65 64 69 74 2d 63 6f 73 74 2d 74 61 62 6c 65   edit-cost-table
13c0: 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 61 6d 61 74  ..**.** The amat
13d0: 63 68 20 69 73 20 61 20 72 65 61 64 2d 6f 6e 6c  ch is a read-onl
13e0: 79 20 74 61 62 6c 65 2e 20 20 41 6e 79 20 61 74  y table.  Any at
13f0: 74 65 6d 70 74 20 74 6f 20 44 45 4c 45 54 45 2c  tempt to DELETE,
1400: 20 49 4e 53 45 52 54 2c 20 6f 72 0a 2a 2a 20 55   INSERT, or.** U
1410: 50 44 41 54 45 20 6f 6e 20 61 20 61 6d 61 74 63  PDATE on a amatc
1420: 68 20 74 61 62 6c 65 20 77 69 6c 6c 20 74 68 72  h table will thr
1430: 6f 77 20 61 6e 20 65 72 72 6f 72 2e 0a 2a 2a 0a  ow an error..**.
1440: 2a 2a 20 49 74 20 69 73 20 69 6d 70 6f 72 74 61  ** It is importa
1450: 6e 74 20 74 6f 20 70 75 74 20 73 6f 6d 65 20 6b  nt to put some k
1460: 69 6e 64 20 6f 66 20 61 20 6c 69 6d 69 74 20 6f  ind of a limit o
1470: 6e 20 74 68 65 20 61 6d 61 74 63 68 20 6f 75 74  n the amatch out
1480: 70 75 74 2e 20 20 54 68 69 73 0a 2a 2a 20 63 61  put.  This.** ca
1490: 6e 20 62 65 20 65 69 74 68 65 72 20 69 6e 20 74  n be either in t
14a0: 68 65 20 66 6f 72 6d 20 6f 66 20 61 20 4c 49 4d  he form of a LIM
14b0: 49 54 20 63 6c 61 75 73 65 20 61 74 20 74 68 65  IT clause at the
14c0: 20 65 6e 64 20 6f 66 20 74 68 65 20 71 75 65 72   end of the quer
14d0: 79 2c 0a 2a 2a 20 6f 72 20 62 65 74 74 65 72 2c  y,.** or better,
14e0: 20 61 20 22 64 69 73 74 61 6e 63 65 3c 4e 4e 4e   a "distance<NNN
14f0: 22 20 63 6f 6e 73 74 72 61 69 6e 74 20 77 68 65  " constraint whe
1500: 72 65 20 4e 4e 4e 20 69 73 20 73 6f 6d 65 20 6e  re NNN is some n
1510: 75 6d 62 65 72 2e 20 20 54 68 65 0a 2a 2a 20 72  umber.  The.** r
1520: 75 6e 6e 69 6e 67 20 74 69 6d 65 20 61 6e 64 20  unning time and 
1530: 6d 65 6d 6f 72 79 20 72 65 71 75 69 72 65 6d 65  memory requireme
1540: 6e 74 20 69 73 20 65 78 70 6f 6e 65 6e 74 69 61  nt is exponentia
1550: 6c 20 69 6e 20 74 68 65 20 76 61 6c 75 65 20 6f  l in the value o
1560: 66 20 4e 4e 4e 20 0a 2a 2a 20 73 6f 20 79 6f 75  f NNN .** so you
1570: 20 77 61 6e 74 20 74 6f 20 6d 61 6b 65 20 73 75   want to make su
1580: 72 65 20 74 68 61 74 20 4e 4e 4e 20 69 73 20 6e  re that NNN is n
1590: 6f 74 20 74 6f 6f 20 62 69 67 2e 20 20 41 20 76  ot too big.  A v
15a0: 61 6c 75 65 20 6f 66 20 4e 4e 4e 20 74 68 61 74  alue of NNN that
15b0: 0a 2a 2a 20 69 73 20 61 62 6f 75 74 20 74 77 69  .** is about twi
15c0: 63 65 20 74 68 65 20 61 76 65 72 61 67 65 20 74  ce the average t
15d0: 72 61 6e 73 66 6f 72 6d 61 74 69 6f 6e 20 63 6f  ransformation co
15e0: 73 74 20 73 65 65 6d 73 20 74 6f 20 67 69 76 65  st seems to give
15f0: 20 67 6f 6f 64 20 72 65 73 75 6c 74 73 2e 0a 2a   good results..*
1600: 2a 0a 2a 2a 20 54 68 65 20 61 6d 61 74 63 68 20  *.** The amatch 
1610: 74 61 62 6c 65 20 63 61 6e 20 62 65 20 75 73 65  table can be use
1620: 66 75 6c 20 66 6f 72 20 74 61 73 6b 73 20 73 75  ful for tasks su
1630: 63 68 20 61 73 20 73 70 65 6c 6c 69 6e 67 20 63  ch as spelling c
1640: 6f 72 72 65 63 74 69 6f 6e 2e 0a 2a 2a 20 53 75  orrection..** Su
1650: 70 70 6f 73 65 20 61 6c 6c 20 61 6c 6c 6f 77 65  ppose all allowe
1660: 64 20 77 6f 72 64 73 20 61 72 65 20 69 6e 20 74  d words are in t
1670: 61 62 6c 65 20 76 6f 63 61 62 75 6c 61 72 79 28  able vocabulary(
1680: 77 29 2e 20 20 54 68 65 6e 20 6f 6e 65 20 77 6f  w).  Then one wo
1690: 75 6c 64 20 63 72 65 61 74 65 0a 2a 2a 20 61 6e  uld create.** an
16a0: 20 61 6d 61 74 63 68 20 76 69 72 74 75 61 6c 20   amatch virtual 
16b0: 74 61 62 6c 65 20 6c 69 6b 65 20 74 68 69 73 3a  table like this:
16c0: 0a 2a 2a 0a 2a 2a 20 20 20 43 52 45 41 54 45 20  .**.**   CREATE 
16d0: 56 49 52 54 55 41 4c 20 54 41 42 4c 45 20 65 78  VIRTUAL TABLE ex
16e0: 31 20 55 53 49 4e 47 20 61 6d 61 74 63 68 28 0a  1 USING amatch(.
16f0: 2a 2a 20 20 20 20 20 20 20 76 6f 63 61 62 74 61  **       vocabta
1700: 62 6c 65 3d 76 6f 63 61 62 75 6c 61 72 79 2c 0a  ble=vocabulary,.
1710: 2a 2a 20 20 20 20 20 20 20 76 6f 63 61 62 63 6f  **       vocabco
1720: 6c 75 6d 6e 3d 77 2c 0a 2a 2a 20 20 20 20 20 20  lumn=w,.**      
1730: 20 65 64 69 74 5f 64 69 73 74 61 6e 63 65 73 3d   edit_distances=
1740: 65 63 31 0a 2a 2a 20 20 20 29 3b 0a 2a 2a 0a 2a  ec1.**   );.**.*
1750: 2a 20 54 68 65 6e 20 67 69 76 65 6e 20 61 6e 20  * Then given an 
1760: 69 6e 70 75 74 20 77 6f 72 64 20 24 77 6f 72 64  input word $word
1770: 2c 20 6c 6f 6f 6b 20 75 70 20 63 6c 6f 73 65 20  , look up close 
1780: 73 70 65 6c 6c 69 6e 67 73 20 74 68 69 73 20 77  spellings this w
1790: 61 79 3a 0a 2a 2a 0a 2a 2a 20 20 20 53 45 4c 45  ay:.**.**   SELE
17a0: 43 54 20 77 6f 72 64 2c 20 64 69 73 74 61 6e 63  CT word, distanc
17b0: 65 20 46 52 4f 4d 20 65 78 31 0a 2a 2a 20 20 20  e FROM ex1.**   
17c0: 20 57 48 45 52 45 20 77 6f 72 64 20 4d 41 54 43   WHERE word MATC
17d0: 48 20 24 77 6f 72 64 20 41 4e 44 20 64 69 73 74  H $word AND dist
17e0: 61 6e 63 65 3c 32 30 30 3b 0a 2a 2a 0a 2a 2a 20  ance<200;.**.** 
17f0: 4d 55 4c 54 49 50 4c 45 20 4c 41 4e 47 55 41 47  MULTIPLE LANGUAG
1800: 45 53 0a 2a 2a 0a 2a 2a 20 4e 6f 72 6d 61 6c 6c  ES.**.** Normall
1810: 79 2c 20 74 68 65 20 22 69 4c 61 6e 67 22 20 76  y, the "iLang" v
1820: 61 6c 75 65 20 61 73 73 6f 63 69 61 74 65 64 20  alue associated 
1830: 77 69 74 68 20 61 6c 6c 20 63 68 61 72 61 63 74  with all charact
1840: 65 72 20 74 72 61 6e 73 66 6f 72 6d 61 74 69 6f  er transformatio
1850: 6e 73 0a 2a 2a 20 69 6e 20 74 68 65 20 65 64 69  ns.** in the edi
1860: 74 2d 63 6f 73 74 2d 74 61 62 6c 65 20 69 73 20  t-cost-table is 
1870: 7a 65 72 6f 2e 20 48 6f 77 65 76 65 72 2c 20 69  zero. However, i
1880: 66 20 72 65 71 75 69 72 65 64 2c 20 74 68 65 20  f required, the 
1890: 61 6d 61 74 63 68 20 0a 2a 2a 20 76 69 72 74 75  amatch .** virtu
18a0: 61 6c 20 74 61 62 6c 65 20 61 6c 6c 6f 77 73 20  al table allows 
18b0: 6d 75 6c 74 69 70 6c 65 20 6c 61 6e 67 75 61 67  multiple languag
18c0: 65 73 20 74 6f 20 62 65 20 64 65 66 69 6e 65 64  es to be defined
18d0: 2e 20 45 61 63 68 20 71 75 65 72 79 20 75 73 65  . Each query use
18e0: 73 20 0a 2a 2a 20 6f 6e 6c 79 20 61 20 73 69 6e  s .** only a sin
18f0: 67 6c 65 20 69 4c 61 6e 67 20 76 61 6c 75 65 2e  gle iLang value.
1900: 20 20 20 54 68 69 73 20 61 6c 6c 6f 77 73 2c 20     This allows, 
1910: 66 6f 72 20 65 78 61 6d 70 6c 65 2c 20 61 20 73  for example, a s
1920: 69 6e 67 6c 65 20 0a 2a 2a 20 61 6d 61 74 63 68  ingle .** amatch
1930: 20 74 61 62 6c 65 20 74 6f 20 73 75 70 70 6f 72   table to suppor
1940: 74 20 6d 75 6c 74 69 70 6c 65 20 6c 61 6e 67 75  t multiple langu
1950: 61 67 65 73 2e 0a 2a 2a 0a 2a 2a 20 42 79 20 64  ages..**.** By d
1960: 65 66 61 75 6c 74 2c 20 6f 6e 6c 79 20 74 68 65  efault, only the
1970: 20 72 75 6c 65 73 20 77 69 74 68 20 69 4c 61 6e   rules with iLan
1980: 67 3d 30 20 61 72 65 20 75 73 65 64 2e 20 54 6f  g=0 are used. To
1990: 20 73 70 65 63 69 66 79 20 61 6e 20 0a 2a 2a 20   specify an .** 
19a0: 61 6c 74 65 72 6e 61 74 69 76 65 20 6c 61 6e 67  alternative lang
19b0: 75 61 67 65 2c 20 61 20 22 6c 61 6e 67 75 61 67  uage, a "languag
19c0: 65 20 3d 20 3f 22 20 65 78 70 72 65 73 73 69 6f  e = ?" expressio
19d0: 6e 20 6d 75 73 74 20 62 65 20 61 64 64 65 64 20  n must be added 
19e0: 74 6f 20 74 68 65 0a 2a 2a 20 57 48 45 52 45 20  to the.** WHERE 
19f0: 63 6c 61 75 73 65 20 6f 66 20 61 20 53 45 4c 45  clause of a SELE
1a00: 43 54 2c 20 77 68 65 72 65 20 3f 20 69 73 20 74  CT, where ? is t
1a10: 68 65 20 69 6e 74 65 67 65 72 20 69 64 65 6e 74  he integer ident
1a20: 69 66 69 65 72 20 6f 66 20 74 68 65 20 64 65 73  ifier of the des
1a30: 69 72 65 64 20 0a 2a 2a 20 6c 61 6e 67 75 61 67  ired .** languag
1a40: 65 2e 20 46 6f 72 20 65 78 61 6d 70 6c 65 3a 0a  e. For example:.
1a50: 2a 2a 0a 2a 2a 20 20 20 53 45 4c 45 43 54 20 77  **.**   SELECT w
1a60: 6f 72 64 2c 20 64 69 73 74 61 6e 63 65 20 46 52  ord, distance FR
1a70: 4f 4d 20 65 78 31 0a 2a 2a 20 20 20 20 57 48 45  OM ex1.**    WHE
1a80: 52 45 20 77 6f 72 64 20 4d 41 54 43 48 20 24 77  RE word MATCH $w
1a90: 6f 72 64 0a 2a 2a 20 20 20 20 20 20 41 4e 44 20  ord.**      AND 
1aa0: 64 69 73 74 61 6e 63 65 3c 3d 32 30 30 0a 2a 2a  distance<=200.**
1ab0: 20 20 20 20 20 20 41 4e 44 20 6c 61 6e 67 75 61        AND langua
1ac0: 67 65 3d 31 20 2d 2d 20 53 70 65 63 69 66 79 20  ge=1 -- Specify 
1ad0: 75 73 65 20 6c 61 6e 67 75 61 67 65 20 31 20 69  use language 1 i
1ae0: 6e 73 74 65 61 64 20 6f 66 20 30 0a 2a 2a 0a 2a  nstead of 0.**.*
1af0: 2a 20 49 66 20 6e 6f 20 22 6c 61 6e 67 75 61 67  * If no "languag
1b00: 65 20 3d 20 3f 22 20 63 6f 6e 73 74 72 61 69 6e  e = ?" constrain
1b10: 74 20 69 73 20 73 70 65 63 69 66 69 65 64 20 69  t is specified i
1b20: 6e 20 74 68 65 20 57 48 45 52 45 20 63 6c 61 75  n the WHERE clau
1b30: 73 65 2c 20 6c 61 6e 67 75 61 67 65 0a 2a 2a 20  se, language.** 
1b40: 30 20 69 73 20 75 73 65 64 2e 0a 2a 2a 0a 2a 2a  0 is used..**.**
1b50: 20 4c 49 4d 49 54 53 0a 2a 2a 0a 2a 2a 20 54 68   LIMITS.**.** Th
1b60: 65 20 6d 61 78 69 6d 75 6d 20 6c 61 6e 67 75 61  e maximum langua
1b70: 67 65 20 6e 75 6d 62 65 72 20 69 73 20 32 31 34  ge number is 214
1b80: 37 34 38 33 36 34 37 2e 20 20 54 68 65 20 6d 61  7483647.  The ma
1b90: 78 69 6d 75 6d 20 6c 65 6e 67 74 68 20 6f 66 20  ximum length of 
1ba0: 65 69 74 68 65 72 0a 2a 2a 20 6f 66 20 74 68 65  either.** of the
1bb0: 20 73 74 72 69 6e 67 73 20 69 6e 20 74 68 65 20   strings in the 
1bc0: 73 65 63 6f 6e 64 20 6f 72 20 74 68 69 72 64 20  second or third 
1bd0: 63 6f 6c 75 6d 6e 20 6f 66 20 74 68 65 20 61 6d  column of the am
1be0: 61 74 63 68 20 64 61 74 61 20 74 61 62 6c 65 0a  atch data table.
1bf0: 2a 2a 20 69 73 20 35 30 20 62 79 74 65 73 2e 20  ** is 50 bytes. 
1c00: 20 54 68 65 20 6d 61 78 69 6d 75 6d 20 63 6f 73   The maximum cos
1c10: 74 20 6f 6e 20 61 20 72 75 6c 65 20 69 73 20 31  t on a rule is 1
1c20: 30 30 30 2e 0a 2a 2f 0a 23 69 6e 63 6c 75 64 65  000..*/.#include
1c30: 20 22 73 71 6c 69 74 65 33 65 78 74 2e 68 22 0a   "sqlite3ext.h".
1c40: 53 51 4c 49 54 45 5f 45 58 54 45 4e 53 49 4f 4e  SQLITE_EXTENSION
1c50: 5f 49 4e 49 54 31 0a 23 69 6e 63 6c 75 64 65 20  _INIT1.#include 
1c60: 3c 73 74 64 6c 69 62 2e 68 3e 0a 23 69 6e 63 6c  <stdlib.h>.#incl
1c70: 75 64 65 20 3c 73 74 72 69 6e 67 2e 68 3e 0a 23  ude <string.h>.#
1c80: 69 6e 63 6c 75 64 65 20 3c 61 73 73 65 72 74 2e  include <assert.
1c90: 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 73 74 64  h>.#include <std
1ca0: 69 6f 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c  io.h>.#include <
1cb0: 63 74 79 70 65 2e 68 3e 0a 0a 23 69 66 6e 64 65  ctype.h>..#ifnde
1cc0: 66 20 53 51 4c 49 54 45 5f 4f 4d 49 54 5f 56 49  f SQLITE_OMIT_VI
1cd0: 52 54 55 41 4c 54 41 42 4c 45 0a 0a 2f 2a 0a 2a  RTUALTABLE../*.*
1ce0: 2a 20 46 6f 72 77 61 72 64 20 64 65 63 6c 61 72  * Forward declar
1cf0: 61 74 69 6f 6e 20 6f 66 20 6f 62 6a 65 63 74 73  ation of objects
1d00: 20 75 73 65 64 20 62 79 20 74 68 69 73 20 69 6d   used by this im
1d10: 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 0a 2a 2f 0a  plementation.*/.
1d20: 74 79 70 65 64 65 66 20 73 74 72 75 63 74 20 61  typedef struct a
1d30: 6d 61 74 63 68 5f 76 74 61 62 20 61 6d 61 74 63  match_vtab amatc
1d40: 68 5f 76 74 61 62 3b 0a 74 79 70 65 64 65 66 20  h_vtab;.typedef 
1d50: 73 74 72 75 63 74 20 61 6d 61 74 63 68 5f 63 75  struct amatch_cu
1d60: 72 73 6f 72 20 61 6d 61 74 63 68 5f 63 75 72 73  rsor amatch_curs
1d70: 6f 72 3b 0a 74 79 70 65 64 65 66 20 73 74 72 75  or;.typedef stru
1d80: 63 74 20 61 6d 61 74 63 68 5f 72 75 6c 65 20 61  ct amatch_rule a
1d90: 6d 61 74 63 68 5f 72 75 6c 65 3b 0a 74 79 70 65  match_rule;.type
1da0: 64 65 66 20 73 74 72 75 63 74 20 61 6d 61 74 63  def struct amatc
1db0: 68 5f 77 6f 72 64 20 61 6d 61 74 63 68 5f 77 6f  h_word amatch_wo
1dc0: 72 64 3b 0a 74 79 70 65 64 65 66 20 73 74 72 75  rd;.typedef stru
1dd0: 63 74 20 61 6d 61 74 63 68 5f 61 76 6c 20 61 6d  ct amatch_avl am
1de0: 61 74 63 68 5f 61 76 6c 3b 0a 0a 0a 2f 2a 2a 2a  atch_avl;.../***
1df0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
1e00: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
1e10: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
1e20: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
1e30: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 0a 2a 2a 20 41 56  **********.** AV
1e40: 4c 20 54 72 65 65 20 69 6d 70 6c 65 6d 65 6e 74  L Tree implement
1e50: 61 74 69 6f 6e 0a 2a 2f 0a 2f 2a 0a 2a 2a 20 4f  ation.*/./*.** O
1e60: 62 6a 65 63 74 73 20 74 68 61 74 20 77 61 6e 74  bjects that want
1e70: 20 74 6f 20 62 65 20 6d 65 6d 62 65 72 73 20 6f   to be members o
1e80: 66 20 74 68 65 20 41 56 4c 20 74 72 65 65 20 73  f the AVL tree s
1e90: 68 6f 75 6c 64 20 65 6d 62 65 64 64 65 64 20 61  hould embedded a
1ea0: 6e 0a 2a 2a 20 69 6e 73 74 61 6e 63 65 20 6f 66  n.** instance of
1eb0: 20 74 68 69 73 20 73 74 72 75 63 74 75 72 65 2e   this structure.
1ec0: 0a 2a 2f 0a 73 74 72 75 63 74 20 61 6d 61 74 63  .*/.struct amatc
1ed0: 68 5f 61 76 6c 20 7b 0a 20 20 61 6d 61 74 63 68  h_avl {.  amatch
1ee0: 5f 77 6f 72 64 20 2a 70 57 6f 72 64 3b 20 20 20  _word *pWord;   
1ef0: 2f 2a 20 50 6f 69 6e 74 73 20 74 6f 20 74 68 65  /* Points to the
1f00: 20 6f 62 6a 65 63 74 20 62 65 69 6e 67 20 73 74   object being st
1f10: 6f 72 65 64 20 69 6e 20 74 68 65 20 74 72 65 65  ored in the tree
1f20: 20 2a 2f 0a 20 20 63 68 61 72 20 2a 7a 4b 65 79   */.  char *zKey
1f30: 3b 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4b  ;           /* K
1f40: 65 79 2e 20 20 7a 65 72 6f 2d 74 65 72 6d 69 6e  ey.  zero-termin
1f50: 61 74 65 64 20 73 74 72 69 6e 67 2e 20 20 4d 75  ated string.  Mu
1f60: 73 74 20 62 65 20 75 6e 69 71 75 65 20 2a 2f 0a  st be unique */.
1f70: 20 20 61 6d 61 74 63 68 5f 61 76 6c 20 2a 70 42    amatch_avl *pB
1f80: 65 66 6f 72 65 3b 20 20 2f 2a 20 4f 74 68 65 72  efore;  /* Other
1f90: 20 65 6c 65 6d 65 6e 74 73 20 6c 65 73 73 20 74   elements less t
1fa0: 68 61 6e 20 7a 4b 65 79 20 2a 2f 0a 20 20 61 6d  han zKey */.  am
1fb0: 61 74 63 68 5f 61 76 6c 20 2a 70 41 66 74 65 72  atch_avl *pAfter
1fc0: 3b 20 20 20 2f 2a 20 4f 74 68 65 72 20 65 6c 65  ;   /* Other ele
1fd0: 6d 65 6e 74 73 20 67 72 65 61 74 65 72 20 74 68  ments greater th
1fe0: 61 6e 20 7a 4b 65 79 20 2a 2f 0a 20 20 61 6d 61  an zKey */.  ama
1ff0: 74 63 68 5f 61 76 6c 20 2a 70 55 70 3b 20 20 20  tch_avl *pUp;   
2000: 20 20 20 2f 2a 20 50 61 72 65 6e 74 20 65 6c 65     /* Parent ele
2010: 6d 65 6e 74 20 2a 2f 0a 20 20 73 68 6f 72 74 20  ment */.  short 
2020: 69 6e 74 20 68 65 69 67 68 74 3b 20 20 20 20 20  int height;     
2030: 2f 2a 20 48 65 69 67 68 74 20 6f 66 20 74 68 69  /* Height of thi
2040: 73 20 6e 6f 64 65 2e 20 20 4c 65 61 66 3d 3d 31  s node.  Leaf==1
2050: 20 2a 2f 0a 20 20 73 68 6f 72 74 20 69 6e 74 20   */.  short int 
2060: 69 6d 62 61 6c 61 6e 63 65 3b 20 20 2f 2a 20 48  imbalance;  /* H
2070: 65 69 67 68 74 20 64 69 66 66 65 72 65 6e 63 65  eight difference
2080: 20 62 65 74 77 65 65 6e 20 70 42 65 66 6f 72 65   between pBefore
2090: 20 61 6e 64 20 70 41 66 74 65 72 20 2a 2f 0a 7d   and pAfter */.}
20a0: 3b 0a 0a 2f 2a 20 52 65 63 6f 6d 70 75 74 65 20  ;../* Recompute 
20b0: 74 68 65 20 61 6d 61 74 63 68 5f 61 76 6c 2e 68  the amatch_avl.h
20c0: 65 69 67 68 74 20 61 6e 64 20 61 6d 61 74 63 68  eight and amatch
20d0: 5f 61 76 6c 2e 69 6d 62 61 6c 61 6e 63 65 20 66  _avl.imbalance f
20e0: 69 65 6c 64 73 20 66 6f 72 20 70 2e 0a 2a 2a 20  ields for p..** 
20f0: 41 73 73 75 6d 65 20 74 68 61 74 20 74 68 65 20  Assume that the 
2100: 63 68 69 6c 64 72 65 6e 20 6f 66 20 70 20 68 61  children of p ha
2110: 76 65 20 63 6f 72 72 65 63 74 20 68 65 69 67 68  ve correct heigh
2120: 74 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f  ts..*/.static vo
2130: 69 64 20 61 6d 61 74 63 68 41 76 6c 52 65 63 6f  id amatchAvlReco
2140: 6d 70 75 74 65 48 65 69 67 68 74 28 61 6d 61 74  mputeHeight(amat
2150: 63 68 5f 61 76 6c 20 2a 70 29 7b 0a 20 20 73 68  ch_avl *p){.  sh
2160: 6f 72 74 20 69 6e 74 20 68 42 65 66 6f 72 65 20  ort int hBefore 
2170: 3d 20 70 2d 3e 70 42 65 66 6f 72 65 20 3f 20 70  = p->pBefore ? p
2180: 2d 3e 70 42 65 66 6f 72 65 2d 3e 68 65 69 67 68  ->pBefore->heigh
2190: 74 20 3a 20 30 3b 0a 20 20 73 68 6f 72 74 20 69  t : 0;.  short i
21a0: 6e 74 20 68 41 66 74 65 72 20 3d 20 70 2d 3e 70  nt hAfter = p->p
21b0: 41 66 74 65 72 20 3f 20 70 2d 3e 70 41 66 74 65  After ? p->pAfte
21c0: 72 2d 3e 68 65 69 67 68 74 20 3a 20 30 3b 0a 20  r->height : 0;. 
21d0: 20 70 2d 3e 69 6d 62 61 6c 61 6e 63 65 20 3d 20   p->imbalance = 
21e0: 68 42 65 66 6f 72 65 20 2d 20 68 41 66 74 65 72  hBefore - hAfter
21f0: 3b 20 20 2f 2a 20 2d 3a 20 70 41 66 74 65 72 20  ;  /* -: pAfter 
2200: 68 69 67 68 65 72 2e 20 20 2b 3a 20 70 42 65 66  higher.  +: pBef
2210: 6f 72 65 20 68 69 67 68 65 72 20 2a 2f 0a 20 20  ore higher */.  
2220: 70 2d 3e 68 65 69 67 68 74 20 3d 20 28 68 42 65  p->height = (hBe
2230: 66 6f 72 65 3e 68 41 66 74 65 72 20 3f 20 68 42  fore>hAfter ? hB
2240: 65 66 6f 72 65 20 3a 20 68 41 66 74 65 72 29 2b  efore : hAfter)+
2250: 31 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 20 20 20 20  1;.}../*.**     
2260: 50 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  P               
2270: 20 42 0a 2a 2a 20 20 20 20 2f 20 5c 20 20 20 20   B.**    / \    
2280: 20 20 20 20 20 20 20 20 20 20 2f 20 5c 0a 2a 2a            / \.**
2290: 20 20 20 42 20 20 20 5a 20 20 20 20 3d 3d 3e 20     B   Z    ==> 
22a0: 20 20 20 20 58 20 20 20 50 0a 2a 2a 20 20 2f 20      X   P.**  / 
22b0: 5c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  \               
22c0: 20 20 20 2f 20 5c 0a 2a 2a 20 58 20 20 20 59 20     / \.** X   Y 
22d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 59                 Y
22e0: 20 20 20 5a 0a 2a 2a 0a 2a 2f 0a 73 74 61 74 69     Z.**.*/.stati
22f0: 63 20 61 6d 61 74 63 68 5f 61 76 6c 20 2a 61 6d  c amatch_avl *am
2300: 61 74 63 68 41 76 6c 52 6f 74 61 74 65 42 65 66  atchAvlRotateBef
2310: 6f 72 65 28 61 6d 61 74 63 68 5f 61 76 6c 20 2a  ore(amatch_avl *
2320: 70 50 29 7b 0a 20 20 61 6d 61 74 63 68 5f 61 76  pP){.  amatch_av
2330: 6c 20 2a 70 42 20 3d 20 70 50 2d 3e 70 42 65 66  l *pB = pP->pBef
2340: 6f 72 65 3b 0a 20 20 61 6d 61 74 63 68 5f 61 76  ore;.  amatch_av
2350: 6c 20 2a 70 59 20 3d 20 70 42 2d 3e 70 41 66 74  l *pY = pB->pAft
2360: 65 72 3b 0a 20 20 70 42 2d 3e 70 55 70 20 3d 20  er;.  pB->pUp = 
2370: 70 50 2d 3e 70 55 70 3b 0a 20 20 70 42 2d 3e 70  pP->pUp;.  pB->p
2380: 41 66 74 65 72 20 3d 20 70 50 3b 0a 20 20 70 50  After = pP;.  pP
2390: 2d 3e 70 55 70 20 3d 20 70 42 3b 0a 20 20 70 50  ->pUp = pB;.  pP
23a0: 2d 3e 70 42 65 66 6f 72 65 20 3d 20 70 59 3b 0a  ->pBefore = pY;.
23b0: 20 20 69 66 28 20 70 59 20 29 20 70 59 2d 3e 70    if( pY ) pY->p
23c0: 55 70 20 3d 20 70 50 3b 0a 20 20 61 6d 61 74 63  Up = pP;.  amatc
23d0: 68 41 76 6c 52 65 63 6f 6d 70 75 74 65 48 65 69  hAvlRecomputeHei
23e0: 67 68 74 28 70 50 29 3b 0a 20 20 61 6d 61 74 63  ght(pP);.  amatc
23f0: 68 41 76 6c 52 65 63 6f 6d 70 75 74 65 48 65 69  hAvlRecomputeHei
2400: 67 68 74 28 70 42 29 3b 0a 20 20 72 65 74 75 72  ght(pB);.  retur
2410: 6e 20 70 42 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 20  n pB;.}../*.**  
2420: 20 20 20 50 20 20 20 20 20 20 20 20 20 20 20 20     P            
2430: 20 20 20 20 41 0a 2a 2a 20 20 20 20 2f 20 5c 20      A.**    / \ 
2440: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 20 5c               / \
2450: 0a 2a 2a 20 20 20 58 20 20 20 41 20 20 20 20 3d  .**   X   A    =
2460: 3d 3e 20 20 20 20 20 50 20 20 20 5a 0a 2a 2a 20  =>     P   Z.** 
2470: 20 20 20 20 20 2f 20 5c 20 20 20 20 20 20 20 20       / \        
2480: 20 20 2f 20 5c 0a 2a 2a 20 20 20 20 20 59 20 20    / \.**     Y  
2490: 20 5a 20 20 20 20 20 20 20 20 58 20 20 20 59 0a   Z        X   Y.
24a0: 2a 2a 0a 2a 2f 0a 73 74 61 74 69 63 20 61 6d 61  **.*/.static ama
24b0: 74 63 68 5f 61 76 6c 20 2a 61 6d 61 74 63 68 41  tch_avl *amatchA
24c0: 76 6c 52 6f 74 61 74 65 41 66 74 65 72 28 61 6d  vlRotateAfter(am
24d0: 61 74 63 68 5f 61 76 6c 20 2a 70 50 29 7b 0a 20  atch_avl *pP){. 
24e0: 20 61 6d 61 74 63 68 5f 61 76 6c 20 2a 70 41 20   amatch_avl *pA 
24f0: 3d 20 70 50 2d 3e 70 41 66 74 65 72 3b 0a 20 20  = pP->pAfter;.  
2500: 61 6d 61 74 63 68 5f 61 76 6c 20 2a 70 59 20 3d  amatch_avl *pY =
2510: 20 70 41 2d 3e 70 42 65 66 6f 72 65 3b 0a 20 20   pA->pBefore;.  
2520: 70 41 2d 3e 70 55 70 20 3d 20 70 50 2d 3e 70 55  pA->pUp = pP->pU
2530: 70 3b 0a 20 20 70 41 2d 3e 70 42 65 66 6f 72 65  p;.  pA->pBefore
2540: 20 3d 20 70 50 3b 0a 20 20 70 50 2d 3e 70 55 70   = pP;.  pP->pUp
2550: 20 3d 20 70 41 3b 0a 20 20 70 50 2d 3e 70 41 66   = pA;.  pP->pAf
2560: 74 65 72 20 3d 20 70 59 3b 0a 20 20 69 66 28 20  ter = pY;.  if( 
2570: 70 59 20 29 20 70 59 2d 3e 70 55 70 20 3d 20 70  pY ) pY->pUp = p
2580: 50 3b 0a 20 20 61 6d 61 74 63 68 41 76 6c 52 65  P;.  amatchAvlRe
2590: 63 6f 6d 70 75 74 65 48 65 69 67 68 74 28 70 50  computeHeight(pP
25a0: 29 3b 0a 20 20 61 6d 61 74 63 68 41 76 6c 52 65  );.  amatchAvlRe
25b0: 63 6f 6d 70 75 74 65 48 65 69 67 68 74 28 70 41  computeHeight(pA
25c0: 29 3b 0a 20 20 72 65 74 75 72 6e 20 70 41 3b 0a  );.  return pA;.
25d0: 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20  }../*.** Return 
25e0: 61 20 70 6f 69 6e 74 65 72 20 74 6f 20 74 68 65  a pointer to the
25f0: 20 70 42 65 66 6f 72 65 20 6f 72 20 70 41 66 74   pBefore or pAft
2600: 65 72 20 70 6f 69 6e 74 65 72 20 69 6e 20 74 68  er pointer in th
2610: 65 20 70 61 72 65 6e 74 0a 2a 2a 20 6f 66 20 70  e parent.** of p
2620: 20 74 68 61 74 20 70 6f 69 6e 74 73 20 74 6f 20   that points to 
2630: 70 2e 20 20 4f 72 20 69 66 20 70 20 69 73 20 74  p.  Or if p is t
2640: 68 65 20 72 6f 6f 74 20 6e 6f 64 65 2c 20 72 65  he root node, re
2650: 74 75 72 6e 20 70 70 2e 0a 2a 2f 0a 73 74 61 74  turn pp..*/.stat
2660: 69 63 20 61 6d 61 74 63 68 5f 61 76 6c 20 2a 2a  ic amatch_avl **
2670: 61 6d 61 74 63 68 41 76 6c 46 72 6f 6d 50 74 72  amatchAvlFromPtr
2680: 28 61 6d 61 74 63 68 5f 61 76 6c 20 2a 70 2c 20  (amatch_avl *p, 
2690: 61 6d 61 74 63 68 5f 61 76 6c 20 2a 2a 70 70 29  amatch_avl **pp)
26a0: 7b 0a 20 20 61 6d 61 74 63 68 5f 61 76 6c 20 2a  {.  amatch_avl *
26b0: 70 55 70 20 3d 20 70 2d 3e 70 55 70 3b 0a 20 20  pUp = p->pUp;.  
26c0: 69 66 28 20 70 55 70 3d 3d 30 20 29 20 72 65 74  if( pUp==0 ) ret
26d0: 75 72 6e 20 70 70 3b 0a 20 20 69 66 28 20 70 55  urn pp;.  if( pU
26e0: 70 2d 3e 70 41 66 74 65 72 3d 3d 70 20 29 20 72  p->pAfter==p ) r
26f0: 65 74 75 72 6e 20 26 70 55 70 2d 3e 70 41 66 74  eturn &pUp->pAft
2700: 65 72 3b 0a 20 20 72 65 74 75 72 6e 20 26 70 55  er;.  return &pU
2710: 70 2d 3e 70 42 65 66 6f 72 65 3b 0a 7d 0a 0a 2f  p->pBefore;.}../
2720: 2a 0a 2a 2a 20 52 65 62 61 6c 61 6e 63 65 20 61  *.** Rebalance a
2730: 6c 6c 20 6e 6f 64 65 73 20 73 74 61 72 74 69 6e  ll nodes startin
2740: 67 20 77 69 74 68 20 70 20 61 6e 64 20 77 6f 72  g with p and wor
2750: 6b 69 6e 67 20 75 70 20 74 6f 20 74 68 65 20 72  king up to the r
2760: 6f 6f 74 2e 0a 2a 2a 20 52 65 74 75 72 6e 20 74  oot..** Return t
2770: 68 65 20 6e 65 77 20 72 6f 6f 74 2e 0a 2a 2f 0a  he new root..*/.
2780: 73 74 61 74 69 63 20 61 6d 61 74 63 68 5f 61 76  static amatch_av
2790: 6c 20 2a 61 6d 61 74 63 68 41 76 6c 42 61 6c 61  l *amatchAvlBala
27a0: 6e 63 65 28 61 6d 61 74 63 68 5f 61 76 6c 20 2a  nce(amatch_avl *
27b0: 70 29 7b 0a 20 20 61 6d 61 74 63 68 5f 61 76 6c  p){.  amatch_avl
27c0: 20 2a 70 54 6f 70 20 3d 20 70 3b 0a 20 20 61 6d   *pTop = p;.  am
27d0: 61 74 63 68 5f 61 76 6c 20 2a 2a 70 70 3b 0a 20  atch_avl **pp;. 
27e0: 20 77 68 69 6c 65 28 20 70 20 29 7b 0a 20 20 20   while( p ){.   
27f0: 20 61 6d 61 74 63 68 41 76 6c 52 65 63 6f 6d 70   amatchAvlRecomp
2800: 75 74 65 48 65 69 67 68 74 28 70 29 3b 0a 20 20  uteHeight(p);.  
2810: 20 20 69 66 28 20 70 2d 3e 69 6d 62 61 6c 61 6e    if( p->imbalan
2820: 63 65 3e 3d 32 20 29 7b 0a 20 20 20 20 20 20 61  ce>=2 ){.      a
2830: 6d 61 74 63 68 5f 61 76 6c 20 2a 70 42 20 3d 20  match_avl *pB = 
2840: 70 2d 3e 70 42 65 66 6f 72 65 3b 0a 20 20 20 20  p->pBefore;.    
2850: 20 20 69 66 28 20 70 42 2d 3e 69 6d 62 61 6c 61    if( pB->imbala
2860: 6e 63 65 3c 30 20 29 20 70 2d 3e 70 42 65 66 6f  nce<0 ) p->pBefo
2870: 72 65 20 3d 20 61 6d 61 74 63 68 41 76 6c 52 6f  re = amatchAvlRo
2880: 74 61 74 65 41 66 74 65 72 28 70 42 29 3b 0a 20  tateAfter(pB);. 
2890: 20 20 20 20 20 70 70 20 3d 20 61 6d 61 74 63 68       pp = amatch
28a0: 41 76 6c 46 72 6f 6d 50 74 72 28 70 2c 26 70 29  AvlFromPtr(p,&p)
28b0: 3b 0a 20 20 20 20 20 20 70 20 3d 20 2a 70 70 20  ;.      p = *pp 
28c0: 3d 20 61 6d 61 74 63 68 41 76 6c 52 6f 74 61 74  = amatchAvlRotat
28d0: 65 42 65 66 6f 72 65 28 70 29 3b 0a 20 20 20 20  eBefore(p);.    
28e0: 7d 65 6c 73 65 20 69 66 28 20 70 2d 3e 69 6d 62  }else if( p->imb
28f0: 61 6c 61 6e 63 65 3c 3d 28 2d 32 29 20 29 7b 0a  alance<=(-2) ){.
2900: 20 20 20 20 20 20 61 6d 61 74 63 68 5f 61 76 6c        amatch_avl
2910: 20 2a 70 41 20 3d 20 70 2d 3e 70 41 66 74 65 72   *pA = p->pAfter
2920: 3b 0a 20 20 20 20 20 20 69 66 28 20 70 41 2d 3e  ;.      if( pA->
2930: 69 6d 62 61 6c 61 6e 63 65 3e 30 20 29 20 70 2d  imbalance>0 ) p-
2940: 3e 70 41 66 74 65 72 20 3d 20 61 6d 61 74 63 68  >pAfter = amatch
2950: 41 76 6c 52 6f 74 61 74 65 42 65 66 6f 72 65 28  AvlRotateBefore(
2960: 70 41 29 3b 0a 20 20 20 20 20 20 70 70 20 3d 20  pA);.      pp = 
2970: 61 6d 61 74 63 68 41 76 6c 46 72 6f 6d 50 74 72  amatchAvlFromPtr
2980: 28 70 2c 26 70 29 3b 0a 20 20 20 20 20 20 70 20  (p,&p);.      p 
2990: 3d 20 2a 70 70 20 3d 20 61 6d 61 74 63 68 41 76  = *pp = amatchAv
29a0: 6c 52 6f 74 61 74 65 41 66 74 65 72 28 70 29 3b  lRotateAfter(p);
29b0: 0a 20 20 20 20 7d 0a 20 20 20 20 70 54 6f 70 20  .    }.    pTop 
29c0: 3d 20 70 3b 0a 20 20 20 20 70 20 3d 20 70 2d 3e  = p;.    p = p->
29d0: 70 55 70 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72  pUp;.  }.  retur
29e0: 6e 20 70 54 6f 70 3b 0a 7d 0a 0a 2f 2a 20 53 65  n pTop;.}../* Se
29f0: 61 72 63 68 20 74 68 65 20 74 72 65 65 20 72 6f  arch the tree ro
2a00: 6f 74 65 64 20 61 74 20 70 20 66 6f 72 20 61 6e  oted at p for an
2a10: 20 65 6e 74 72 79 20 77 69 74 68 20 7a 4b 65 79   entry with zKey
2a20: 2e 20 20 52 65 74 75 72 6e 20 61 20 70 6f 69 6e  .  Return a poin
2a30: 74 65 72 0a 2a 2a 20 74 6f 20 74 68 65 20 65 6e  ter.** to the en
2a40: 74 72 79 20 6f 72 20 72 65 74 75 72 6e 20 4e 55  try or return NU
2a50: 4c 4c 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 61 6d  LL..*/.static am
2a60: 61 74 63 68 5f 61 76 6c 20 2a 61 6d 61 74 63 68  atch_avl *amatch
2a70: 41 76 6c 53 65 61 72 63 68 28 61 6d 61 74 63 68  AvlSearch(amatch
2a80: 5f 61 76 6c 20 2a 70 2c 20 63 6f 6e 73 74 20 63  _avl *p, const c
2a90: 68 61 72 20 2a 7a 4b 65 79 29 7b 0a 20 20 69 6e  har *zKey){.  in
2aa0: 74 20 63 3b 0a 20 20 77 68 69 6c 65 28 20 70 20  t c;.  while( p 
2ab0: 26 26 20 28 63 20 3d 20 73 74 72 63 6d 70 28 7a  && (c = strcmp(z
2ac0: 4b 65 79 2c 20 70 2d 3e 7a 4b 65 79 29 29 21 3d  Key, p->zKey))!=
2ad0: 30 20 29 7b 0a 20 20 20 20 70 20 3d 20 28 63 3c  0 ){.    p = (c<
2ae0: 30 29 20 3f 20 70 2d 3e 70 42 65 66 6f 72 65 20  0) ? p->pBefore 
2af0: 3a 20 70 2d 3e 70 41 66 74 65 72 3b 0a 20 20 7d  : p->pAfter;.  }
2b00: 0a 20 20 72 65 74 75 72 6e 20 70 3b 0a 7d 0a 0a  .  return p;.}..
2b10: 2f 2a 20 46 69 6e 64 20 74 68 65 20 66 69 72 73  /* Find the firs
2b20: 74 20 6e 6f 64 65 20 28 74 68 65 20 6f 6e 65 20  t node (the one 
2b30: 77 69 74 68 20 74 68 65 20 73 6d 61 6c 6c 65 73  with the smalles
2b40: 74 20 6b 65 79 29 2e 0a 2a 2f 0a 73 74 61 74 69  t key)..*/.stati
2b50: 63 20 61 6d 61 74 63 68 5f 61 76 6c 20 2a 61 6d  c amatch_avl *am
2b60: 61 74 63 68 41 76 6c 46 69 72 73 74 28 61 6d 61  atchAvlFirst(ama
2b70: 74 63 68 5f 61 76 6c 20 2a 70 29 7b 0a 20 20 69  tch_avl *p){.  i
2b80: 66 28 20 70 20 29 20 77 68 69 6c 65 28 20 70 2d  f( p ) while( p-
2b90: 3e 70 42 65 66 6f 72 65 20 29 20 70 20 3d 20 70  >pBefore ) p = p
2ba0: 2d 3e 70 42 65 66 6f 72 65 3b 0a 20 20 72 65 74  ->pBefore;.  ret
2bb0: 75 72 6e 20 70 3b 0a 7d 0a 0a 23 69 66 20 30 20  urn p;.}..#if 0 
2bc0: 2f 2a 20 4e 4f 54 20 55 53 45 44 20 2a 2f 0a 2f  /* NOT USED */./
2bd0: 2a 20 52 65 74 75 72 6e 20 74 68 65 20 6e 6f 64  * Return the nod
2be0: 65 20 77 69 74 68 20 74 68 65 20 6e 65 78 74 20  e with the next 
2bf0: 6c 61 72 67 65 72 20 6b 65 79 20 61 66 74 65 72  larger key after
2c00: 20 70 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 61 6d   p..*/.static am
2c10: 61 74 63 68 5f 61 76 6c 20 2a 61 6d 61 74 63 68  atch_avl *amatch
2c20: 41 76 6c 4e 65 78 74 28 61 6d 61 74 63 68 5f 61  AvlNext(amatch_a
2c30: 76 6c 20 2a 70 29 7b 0a 20 20 61 6d 61 74 63 68  vl *p){.  amatch
2c40: 5f 61 76 6c 20 2a 70 50 72 65 76 20 3d 20 30 3b  _avl *pPrev = 0;
2c50: 0a 20 20 77 68 69 6c 65 28 20 70 20 26 26 20 70  .  while( p && p
2c60: 2d 3e 70 41 66 74 65 72 3d 3d 70 50 72 65 76 20  ->pAfter==pPrev 
2c70: 29 7b 0a 20 20 20 20 70 50 72 65 76 20 3d 20 70  ){.    pPrev = p
2c80: 3b 0a 20 20 20 20 70 20 3d 20 70 2d 3e 70 55 70  ;.    p = p->pUp
2c90: 3b 0a 20 20 7d 0a 20 20 69 66 28 20 70 20 26 26  ;.  }.  if( p &&
2ca0: 20 70 50 72 65 76 3d 3d 30 20 29 7b 0a 20 20 20   pPrev==0 ){.   
2cb0: 20 70 20 3d 20 61 6d 61 74 63 68 41 76 6c 46 69   p = amatchAvlFi
2cc0: 72 73 74 28 70 2d 3e 70 41 66 74 65 72 29 3b 0a  rst(p->pAfter);.
2cd0: 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 70 3b 0a    }.  return p;.
2ce0: 7d 0a 23 65 6e 64 69 66 0a 0a 23 69 66 20 30 20  }.#endif..#if 0 
2cf0: 2f 2a 20 4e 4f 54 20 55 53 45 44 20 2a 2f 0a 2f  /* NOT USED */./
2d00: 2a 20 56 65 72 69 66 79 20 41 56 4c 20 74 72 65  * Verify AVL tre
2d10: 65 20 69 6e 74 65 67 72 69 74 79 0a 2a 2f 0a 73  e integrity.*/.s
2d20: 74 61 74 69 63 20 69 6e 74 20 61 6d 61 74 63 68  tatic int amatch
2d30: 41 76 6c 49 6e 74 65 67 72 69 74 79 28 61 6d 61  AvlIntegrity(ama
2d40: 74 63 68 5f 61 76 6c 20 2a 70 48 65 61 64 29 7b  tch_avl *pHead){
2d50: 0a 20 20 61 6d 61 74 63 68 5f 61 76 6c 20 2a 70  .  amatch_avl *p
2d60: 3b 0a 20 20 69 66 28 20 70 48 65 61 64 3d 3d 30  ;.  if( pHead==0
2d70: 20 29 20 72 65 74 75 72 6e 20 31 3b 0a 20 20 69   ) return 1;.  i
2d80: 66 28 20 28 70 20 3d 20 70 48 65 61 64 2d 3e 70  f( (p = pHead->p
2d90: 42 65 66 6f 72 65 29 21 3d 30 20 29 7b 0a 20 20  Before)!=0 ){.  
2da0: 20 20 61 73 73 65 72 74 28 20 70 2d 3e 70 55 70    assert( p->pUp
2db0: 3d 3d 70 48 65 61 64 20 29 3b 0a 20 20 20 20 61  ==pHead );.    a
2dc0: 73 73 65 72 74 28 20 61 6d 61 74 63 68 41 76 6c  ssert( amatchAvl
2dd0: 49 6e 74 65 67 72 69 74 79 28 70 29 20 29 3b 0a  Integrity(p) );.
2de0: 20 20 20 20 61 73 73 65 72 74 28 20 73 74 72 63      assert( strc
2df0: 6d 70 28 70 2d 3e 7a 4b 65 79 2c 20 70 48 65 61  mp(p->zKey, pHea
2e00: 64 2d 3e 7a 4b 65 79 29 3c 30 20 29 3b 0a 20 20  d->zKey)<0 );.  
2e10: 20 20 77 68 69 6c 65 28 20 70 2d 3e 70 41 66 74    while( p->pAft
2e20: 65 72 20 29 20 70 20 3d 20 70 2d 3e 70 41 66 74  er ) p = p->pAft
2e30: 65 72 3b 0a 20 20 20 20 61 73 73 65 72 74 28 20  er;.    assert( 
2e40: 73 74 72 63 6d 70 28 70 2d 3e 7a 4b 65 79 2c 20  strcmp(p->zKey, 
2e50: 70 48 65 61 64 2d 3e 7a 4b 65 79 29 3c 30 20 29  pHead->zKey)<0 )
2e60: 3b 0a 20 20 7d 0a 20 20 69 66 28 20 28 70 20 3d  ;.  }.  if( (p =
2e70: 20 70 48 65 61 64 2d 3e 70 41 66 74 65 72 29 21   pHead->pAfter)!
2e80: 3d 30 20 29 7b 0a 20 20 20 20 61 73 73 65 72 74  =0 ){.    assert
2e90: 28 20 70 2d 3e 70 55 70 3d 3d 70 48 65 61 64 20  ( p->pUp==pHead 
2ea0: 29 3b 0a 20 20 20 20 61 73 73 65 72 74 28 20 61  );.    assert( a
2eb0: 6d 61 74 63 68 41 76 6c 49 6e 74 65 67 72 69 74  matchAvlIntegrit
2ec0: 79 28 70 29 20 29 3b 0a 20 20 20 20 61 73 73 65  y(p) );.    asse
2ed0: 72 74 28 20 73 74 72 63 6d 70 28 70 2d 3e 7a 4b  rt( strcmp(p->zK
2ee0: 65 79 2c 20 70 48 65 61 64 2d 3e 7a 4b 65 79 29  ey, pHead->zKey)
2ef0: 3e 30 20 29 3b 0a 20 20 20 20 70 20 3d 20 61 6d  >0 );.    p = am
2f00: 61 74 63 68 41 76 6c 46 69 72 73 74 28 70 29 3b  atchAvlFirst(p);
2f10: 0a 20 20 20 20 61 73 73 65 72 74 28 20 73 74 72  .    assert( str
2f20: 63 6d 70 28 70 2d 3e 7a 4b 65 79 2c 20 70 48 65  cmp(p->zKey, pHe
2f30: 61 64 2d 3e 7a 4b 65 79 29 3e 30 20 29 3b 0a 20  ad->zKey)>0 );. 
2f40: 20 7d 0a 20 20 72 65 74 75 72 6e 20 31 3b 0a 7d   }.  return 1;.}
2f50: 0a 73 74 61 74 69 63 20 69 6e 74 20 61 6d 61 74  .static int amat
2f60: 63 68 41 76 6c 49 6e 74 65 67 72 69 74 79 32 28  chAvlIntegrity2(
2f70: 61 6d 61 74 63 68 5f 61 76 6c 20 2a 70 48 65 61  amatch_avl *pHea
2f80: 64 29 7b 0a 20 20 61 6d 61 74 63 68 5f 61 76 6c  d){.  amatch_avl
2f90: 20 2a 70 2c 20 2a 70 4e 65 78 74 3b 0a 20 20 66   *p, *pNext;.  f
2fa0: 6f 72 28 70 3d 61 6d 61 74 63 68 41 76 6c 46 69  or(p=amatchAvlFi
2fb0: 72 73 74 28 70 48 65 61 64 29 3b 20 70 3b 20 70  rst(pHead); p; p
2fc0: 3d 70 4e 65 78 74 29 7b 0a 20 20 20 20 70 4e 65  =pNext){.    pNe
2fd0: 78 74 20 3d 20 61 6d 61 74 63 68 41 76 6c 4e 65  xt = amatchAvlNe
2fe0: 78 74 28 70 29 3b 0a 20 20 20 20 69 66 28 20 70  xt(p);.    if( p
2ff0: 4e 65 78 74 3d 3d 30 20 29 20 62 72 65 61 6b 3b  Next==0 ) break;
3000: 0a 20 20 20 20 61 73 73 65 72 74 28 20 73 74 72  .    assert( str
3010: 63 6d 70 28 70 2d 3e 7a 4b 65 79 2c 20 70 4e 65  cmp(p->zKey, pNe
3020: 78 74 2d 3e 7a 4b 65 79 29 3c 30 20 29 3b 0a 20  xt->zKey)<0 );. 
3030: 20 7d 0a 20 20 72 65 74 75 72 6e 20 31 3b 0a 7d   }.  return 1;.}
3040: 0a 23 65 6e 64 69 66 0a 0a 2f 2a 20 49 6e 73 65  .#endif../* Inse
3050: 72 74 20 61 20 6e 65 77 20 6e 6f 64 65 20 70 4e  rt a new node pN
3060: 65 77 2e 20 20 52 65 74 75 72 6e 20 4e 55 4c 4c  ew.  Return NULL
3070: 20 6f 6e 20 73 75 63 63 65 73 73 2e 20 20 49 66   on success.  If
3080: 20 74 68 65 20 6b 65 79 20 69 73 20 6e 6f 74 0a   the key is not.
3090: 2a 2a 20 75 6e 69 71 75 65 2c 20 74 68 65 6e 20  ** unique, then 
30a0: 64 6f 20 6e 6f 74 20 70 65 72 66 6f 72 6d 20 74  do not perform t
30b0: 68 65 20 69 6e 73 65 72 74 20 62 75 74 20 69 6e  he insert but in
30c0: 73 74 65 61 64 20 6c 65 61 76 65 20 70 4e 65 77  stead leave pNew
30d0: 20 75 6e 63 68 61 6e 67 65 64 0a 2a 2a 20 61 6e   unchanged.** an
30e0: 64 20 72 65 74 75 72 6e 20 61 20 70 6f 69 6e 74  d return a point
30f0: 65 72 20 74 6f 20 61 6e 20 65 78 69 73 74 69 6e  er to an existin
3100: 67 20 6e 6f 64 65 20 77 69 74 68 20 74 68 65 20  g node with the 
3110: 73 61 6d 65 20 6b 65 79 2e 0a 2a 2f 0a 73 74 61  same key..*/.sta
3120: 74 69 63 20 61 6d 61 74 63 68 5f 61 76 6c 20 2a  tic amatch_avl *
3130: 61 6d 61 74 63 68 41 76 6c 49 6e 73 65 72 74 28  amatchAvlInsert(
3140: 61 6d 61 74 63 68 5f 61 76 6c 20 2a 2a 70 70 48  amatch_avl **ppH
3150: 65 61 64 2c 20 61 6d 61 74 63 68 5f 61 76 6c 20  ead, amatch_avl 
3160: 2a 70 4e 65 77 29 7b 0a 20 20 69 6e 74 20 63 3b  *pNew){.  int c;
3170: 0a 20 20 61 6d 61 74 63 68 5f 61 76 6c 20 2a 70  .  amatch_avl *p
3180: 20 3d 20 2a 70 70 48 65 61 64 3b 0a 20 20 69 66   = *ppHead;.  if
3190: 28 20 70 3d 3d 30 20 29 7b 0a 20 20 20 20 70 20  ( p==0 ){.    p 
31a0: 3d 20 70 4e 65 77 3b 0a 20 20 20 20 70 4e 65 77  = pNew;.    pNew
31b0: 2d 3e 70 55 70 20 3d 20 30 3b 0a 20 20 7d 65 6c  ->pUp = 0;.  }el
31c0: 73 65 7b 0a 20 20 20 20 77 68 69 6c 65 28 20 70  se{.    while( p
31d0: 20 29 7b 0a 20 20 20 20 20 20 63 20 3d 20 73 74   ){.      c = st
31e0: 72 63 6d 70 28 70 4e 65 77 2d 3e 7a 4b 65 79 2c  rcmp(pNew->zKey,
31f0: 20 70 2d 3e 7a 4b 65 79 29 3b 0a 20 20 20 20 20   p->zKey);.     
3200: 20 69 66 28 20 63 3c 30 20 29 7b 0a 20 20 20 20   if( c<0 ){.    
3210: 20 20 20 20 69 66 28 20 70 2d 3e 70 42 65 66 6f      if( p->pBefo
3220: 72 65 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20  re ){.          
3230: 70 20 3d 20 70 2d 3e 70 42 65 66 6f 72 65 3b 0a  p = p->pBefore;.
3240: 20 20 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20          }else{. 
3250: 20 20 20 20 20 20 20 20 20 70 2d 3e 70 42 65 66           p->pBef
3260: 6f 72 65 20 3d 20 70 4e 65 77 3b 0a 20 20 20 20  ore = pNew;.    
3270: 20 20 20 20 20 20 70 4e 65 77 2d 3e 70 55 70 20        pNew->pUp 
3280: 3d 20 70 3b 0a 20 20 20 20 20 20 20 20 20 20 62  = p;.          b
3290: 72 65 61 6b 3b 0a 20 20 20 20 20 20 20 20 7d 0a  reak;.        }.
32a0: 20 20 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20        }else if( 
32b0: 63 3e 30 20 29 7b 0a 20 20 20 20 20 20 20 20 69  c>0 ){.        i
32c0: 66 28 20 70 2d 3e 70 41 66 74 65 72 20 29 7b 0a  f( p->pAfter ){.
32d0: 20 20 20 20 20 20 20 20 20 20 70 20 3d 20 70 2d            p = p-
32e0: 3e 70 41 66 74 65 72 3b 0a 20 20 20 20 20 20 20  >pAfter;.       
32f0: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20   }else{.        
3300: 20 20 70 2d 3e 70 41 66 74 65 72 20 3d 20 70 4e    p->pAfter = pN
3310: 65 77 3b 0a 20 20 20 20 20 20 20 20 20 20 70 4e  ew;.          pN
3320: 65 77 2d 3e 70 55 70 20 3d 20 70 3b 0a 20 20 20  ew->pUp = p;.   
3330: 20 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20         break;.  
3340: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7d 65        }.      }e
3350: 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 72 65 74  lse{.        ret
3360: 75 72 6e 20 70 3b 0a 20 20 20 20 20 20 7d 0a 20  urn p;.      }. 
3370: 20 20 20 7d 0a 20 20 7d 0a 20 20 70 4e 65 77 2d     }.  }.  pNew-
3380: 3e 70 42 65 66 6f 72 65 20 3d 20 30 3b 0a 20 20  >pBefore = 0;.  
3390: 70 4e 65 77 2d 3e 70 41 66 74 65 72 20 3d 20 30  pNew->pAfter = 0
33a0: 3b 0a 20 20 70 4e 65 77 2d 3e 68 65 69 67 68 74  ;.  pNew->height
33b0: 20 3d 20 31 3b 0a 20 20 70 4e 65 77 2d 3e 69 6d   = 1;.  pNew->im
33c0: 62 61 6c 61 6e 63 65 20 3d 20 30 3b 0a 20 20 2a  balance = 0;.  *
33d0: 70 70 48 65 61 64 20 3d 20 61 6d 61 74 63 68 41  ppHead = amatchA
33e0: 76 6c 42 61 6c 61 6e 63 65 28 70 29 3b 0a 20 20  vlBalance(p);.  
33f0: 2f 2a 20 61 73 73 65 72 74 28 20 61 6d 61 74 63  /* assert( amatc
3400: 68 41 76 6c 49 6e 74 65 67 72 69 74 79 28 2a 70  hAvlIntegrity(*p
3410: 70 48 65 61 64 29 20 29 3b 20 2a 2f 0a 20 20 2f  pHead) ); */.  /
3420: 2a 20 61 73 73 65 72 74 28 20 61 6d 61 74 63 68  * assert( amatch
3430: 41 76 6c 49 6e 74 65 67 72 69 74 79 32 28 2a 70  AvlIntegrity2(*p
3440: 70 48 65 61 64 29 20 29 3b 20 2a 2f 0a 20 20 72  pHead) ); */.  r
3450: 65 74 75 72 6e 20 30 3b 0a 7d 0a 0a 2f 2a 20 52  eturn 0;.}../* R
3460: 65 6d 6f 76 65 20 6e 6f 64 65 20 70 4f 6c 64 20  emove node pOld 
3470: 66 72 6f 6d 20 74 68 65 20 74 72 65 65 2e 20 20  from the tree.  
3480: 70 4f 6c 64 20 6d 75 73 74 20 62 65 20 61 6e 20  pOld must be an 
3490: 65 6c 65 6d 65 6e 74 20 6f 66 20 74 68 65 20 74  element of the t
34a0: 72 65 65 20 6f 72 0a 2a 2a 20 74 68 65 20 41 56  ree or.** the AV
34b0: 4c 20 74 72 65 65 20 77 69 6c 6c 20 62 65 63 6f  L tree will beco
34c0: 6d 65 20 63 6f 72 72 75 70 74 2e 0a 2a 2f 0a 73  me corrupt..*/.s
34d0: 74 61 74 69 63 20 76 6f 69 64 20 61 6d 61 74 63  tatic void amatc
34e0: 68 41 76 6c 52 65 6d 6f 76 65 28 61 6d 61 74 63  hAvlRemove(amatc
34f0: 68 5f 61 76 6c 20 2a 2a 70 70 48 65 61 64 2c 20  h_avl **ppHead, 
3500: 61 6d 61 74 63 68 5f 61 76 6c 20 2a 70 4f 6c 64  amatch_avl *pOld
3510: 29 7b 0a 20 20 61 6d 61 74 63 68 5f 61 76 6c 20  ){.  amatch_avl 
3520: 2a 2a 70 70 50 61 72 65 6e 74 3b 0a 20 20 61 6d  **ppParent;.  am
3530: 61 74 63 68 5f 61 76 6c 20 2a 70 42 61 6c 61 6e  atch_avl *pBalan
3540: 63 65 20 3d 20 30 3b 0a 20 20 2f 2a 20 61 73 73  ce = 0;.  /* ass
3550: 65 72 74 28 20 61 6d 61 74 63 68 41 76 6c 53 65  ert( amatchAvlSe
3560: 61 72 63 68 28 2a 70 70 48 65 61 64 2c 20 70 4f  arch(*ppHead, pO
3570: 6c 64 2d 3e 7a 4b 65 79 29 3d 3d 70 4f 6c 64 20  ld->zKey)==pOld 
3580: 29 3b 20 2a 2f 0a 20 20 70 70 50 61 72 65 6e 74  ); */.  ppParent
3590: 20 3d 20 61 6d 61 74 63 68 41 76 6c 46 72 6f 6d   = amatchAvlFrom
35a0: 50 74 72 28 70 4f 6c 64 2c 20 70 70 48 65 61 64  Ptr(pOld, ppHead
35b0: 29 3b 0a 20 20 69 66 28 20 70 4f 6c 64 2d 3e 70  );.  if( pOld->p
35c0: 42 65 66 6f 72 65 3d 3d 30 20 26 26 20 70 4f 6c  Before==0 && pOl
35d0: 64 2d 3e 70 41 66 74 65 72 3d 3d 30 20 29 7b 0a  d->pAfter==0 ){.
35e0: 20 20 20 20 2a 70 70 50 61 72 65 6e 74 20 3d 20      *ppParent = 
35f0: 30 3b 0a 20 20 20 20 70 42 61 6c 61 6e 63 65 20  0;.    pBalance 
3600: 3d 20 70 4f 6c 64 2d 3e 70 55 70 3b 0a 20 20 7d  = pOld->pUp;.  }
3610: 65 6c 73 65 20 69 66 28 20 70 4f 6c 64 2d 3e 70  else if( pOld->p
3620: 42 65 66 6f 72 65 20 26 26 20 70 4f 6c 64 2d 3e  Before && pOld->
3630: 70 41 66 74 65 72 20 29 7b 0a 20 20 20 20 61 6d  pAfter ){.    am
3640: 61 74 63 68 5f 61 76 6c 20 2a 70 58 2c 20 2a 70  atch_avl *pX, *p
3650: 59 3b 0a 20 20 20 20 70 58 20 3d 20 61 6d 61 74  Y;.    pX = amat
3660: 63 68 41 76 6c 46 69 72 73 74 28 70 4f 6c 64 2d  chAvlFirst(pOld-
3670: 3e 70 41 66 74 65 72 29 3b 0a 20 20 20 20 2a 61  >pAfter);.    *a
3680: 6d 61 74 63 68 41 76 6c 46 72 6f 6d 50 74 72 28  matchAvlFromPtr(
3690: 70 58 2c 20 30 29 20 3d 20 70 58 2d 3e 70 41 66  pX, 0) = pX->pAf
36a0: 74 65 72 3b 0a 20 20 20 20 69 66 28 20 70 58 2d  ter;.    if( pX-
36b0: 3e 70 41 66 74 65 72 20 29 20 70 58 2d 3e 70 41  >pAfter ) pX->pA
36c0: 66 74 65 72 2d 3e 70 55 70 20 3d 20 70 58 2d 3e  fter->pUp = pX->
36d0: 70 55 70 3b 0a 20 20 20 20 70 42 61 6c 61 6e 63  pUp;.    pBalanc
36e0: 65 20 3d 20 70 58 2d 3e 70 55 70 3b 0a 20 20 20  e = pX->pUp;.   
36f0: 20 70 58 2d 3e 70 41 66 74 65 72 20 3d 20 70 4f   pX->pAfter = pO
3700: 6c 64 2d 3e 70 41 66 74 65 72 3b 0a 20 20 20 20  ld->pAfter;.    
3710: 69 66 28 20 70 58 2d 3e 70 41 66 74 65 72 20 29  if( pX->pAfter )
3720: 7b 0a 20 20 20 20 20 20 70 58 2d 3e 70 41 66 74  {.      pX->pAft
3730: 65 72 2d 3e 70 55 70 20 3d 20 70 58 3b 0a 20 20  er->pUp = pX;.  
3740: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 61    }else{.      a
3750: 73 73 65 72 74 28 20 70 42 61 6c 61 6e 63 65 3d  ssert( pBalance=
3760: 3d 70 4f 6c 64 20 29 3b 0a 20 20 20 20 20 20 70  =pOld );.      p
3770: 42 61 6c 61 6e 63 65 20 3d 20 70 58 3b 0a 20 20  Balance = pX;.  
3780: 20 20 7d 0a 20 20 20 20 70 58 2d 3e 70 42 65 66    }.    pX->pBef
3790: 6f 72 65 20 3d 20 70 59 20 3d 20 70 4f 6c 64 2d  ore = pY = pOld-
37a0: 3e 70 42 65 66 6f 72 65 3b 0a 20 20 20 20 69 66  >pBefore;.    if
37b0: 28 20 70 59 20 29 20 70 59 2d 3e 70 55 70 20 3d  ( pY ) pY->pUp =
37c0: 20 70 58 3b 0a 20 20 20 20 70 58 2d 3e 70 55 70   pX;.    pX->pUp
37d0: 20 3d 20 70 4f 6c 64 2d 3e 70 55 70 3b 0a 20 20   = pOld->pUp;.  
37e0: 20 20 2a 70 70 50 61 72 65 6e 74 20 3d 20 70 58    *ppParent = pX
37f0: 3b 0a 20 20 7d 65 6c 73 65 20 69 66 28 20 70 4f  ;.  }else if( pO
3800: 6c 64 2d 3e 70 42 65 66 6f 72 65 3d 3d 30 20 29  ld->pBefore==0 )
3810: 7b 0a 20 20 20 20 2a 70 70 50 61 72 65 6e 74 20  {.    *ppParent 
3820: 3d 20 70 42 61 6c 61 6e 63 65 20 3d 20 70 4f 6c  = pBalance = pOl
3830: 64 2d 3e 70 41 66 74 65 72 3b 0a 20 20 20 20 70  d->pAfter;.    p
3840: 42 61 6c 61 6e 63 65 2d 3e 70 55 70 20 3d 20 70  Balance->pUp = p
3850: 4f 6c 64 2d 3e 70 55 70 3b 0a 20 20 7d 65 6c 73  Old->pUp;.  }els
3860: 65 20 69 66 28 20 70 4f 6c 64 2d 3e 70 41 66 74  e if( pOld->pAft
3870: 65 72 3d 3d 30 20 29 7b 0a 20 20 20 20 2a 70 70  er==0 ){.    *pp
3880: 50 61 72 65 6e 74 20 3d 20 70 42 61 6c 61 6e 63  Parent = pBalanc
3890: 65 20 3d 20 70 4f 6c 64 2d 3e 70 42 65 66 6f 72  e = pOld->pBefor
38a0: 65 3b 0a 20 20 20 20 70 42 61 6c 61 6e 63 65 2d  e;.    pBalance-
38b0: 3e 70 55 70 20 3d 20 70 4f 6c 64 2d 3e 70 55 70  >pUp = pOld->pUp
38c0: 3b 0a 20 20 7d 0a 20 20 2a 70 70 48 65 61 64 20  ;.  }.  *ppHead 
38d0: 3d 20 61 6d 61 74 63 68 41 76 6c 42 61 6c 61 6e  = amatchAvlBalan
38e0: 63 65 28 70 42 61 6c 61 6e 63 65 29 3b 0a 20 20  ce(pBalance);.  
38f0: 70 4f 6c 64 2d 3e 70 55 70 20 3d 20 30 3b 0a 20  pOld->pUp = 0;. 
3900: 20 70 4f 6c 64 2d 3e 70 42 65 66 6f 72 65 20 3d   pOld->pBefore =
3910: 20 30 3b 0a 20 20 70 4f 6c 64 2d 3e 70 41 66 74   0;.  pOld->pAft
3920: 65 72 20 3d 20 30 3b 0a 20 20 2f 2a 20 61 73 73  er = 0;.  /* ass
3930: 65 72 74 28 20 61 6d 61 74 63 68 41 76 6c 49 6e  ert( amatchAvlIn
3940: 74 65 67 72 69 74 79 28 2a 70 70 48 65 61 64 29  tegrity(*ppHead)
3950: 20 29 3b 20 2a 2f 0a 20 20 2f 2a 20 61 73 73 65   ); */.  /* asse
3960: 72 74 28 20 61 6d 61 74 63 68 41 76 6c 49 6e 74  rt( amatchAvlInt
3970: 65 67 72 69 74 79 32 28 2a 70 70 48 65 61 64 29  egrity2(*ppHead)
3980: 20 29 3b 20 2a 2f 0a 7d 0a 2f 2a 0a 2a 2a 20 45   ); */.}./*.** E
3990: 6e 64 20 6f 66 20 74 68 65 20 41 56 4c 20 54 72  nd of the AVL Tr
39a0: 65 65 20 69 6d 70 6c 65 6d 65 6e 74 61 74 69 6f  ee implementatio
39b0: 6e 0a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  n.**************
39c0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
39d0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
39e0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
39f0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
3a00: 2f 0a 0a 0a 2f 2a 0a 2a 2a 20 56 61 72 69 6f 75  /.../*.** Variou
3a10: 73 20 74 79 70 65 73 2e 0a 2a 2a 0a 2a 2a 20 61  s types..**.** a
3a20: 6d 61 74 63 68 5f 63 6f 73 74 20 69 73 20 74 68  match_cost is th
3a30: 65 20 22 63 6f 73 74 22 20 6f 66 20 61 6e 20 65  e "cost" of an e
3a40: 64 69 74 20 6f 70 65 72 61 74 69 6f 6e 2e 0a 2a  dit operation..*
3a50: 2a 0a 2a 2a 20 61 6d 61 74 63 68 5f 6c 65 6e 20  *.** amatch_len 
3a60: 69 73 20 74 68 65 20 6c 65 6e 67 74 68 20 6f 66  is the length of
3a70: 20 61 20 6d 61 74 63 68 69 6e 67 20 73 74 72 69   a matching stri
3a80: 6e 67 2e 20 20 0a 2a 2a 0a 2a 2a 20 61 6d 61 74  ng.  .**.** amat
3a90: 63 68 5f 6c 61 6e 67 69 64 20 69 73 20 61 6e 20  ch_langid is an 
3aa0: 72 75 6c 65 73 65 74 20 69 64 65 6e 74 69 66 69  ruleset identifi
3ab0: 65 72 2e 0a 2a 2f 0a 74 79 70 65 64 65 66 20 69  er..*/.typedef i
3ac0: 6e 74 20 61 6d 61 74 63 68 5f 63 6f 73 74 3b 0a  nt amatch_cost;.
3ad0: 74 79 70 65 64 65 66 20 73 69 67 6e 65 64 20 63  typedef signed c
3ae0: 68 61 72 20 61 6d 61 74 63 68 5f 6c 65 6e 3b 0a  har amatch_len;.
3af0: 74 79 70 65 64 65 66 20 69 6e 74 20 61 6d 61 74  typedef int amat
3b00: 63 68 5f 6c 61 6e 67 69 64 3b 0a 0a 2f 2a 0a 2a  ch_langid;../*.*
3b10: 2a 20 4c 69 6d 69 74 73 0a 2a 2f 0a 23 64 65 66  * Limits.*/.#def
3b20: 69 6e 65 20 41 4d 41 54 43 48 5f 4d 58 5f 4c 45  ine AMATCH_MX_LE
3b30: 4e 47 54 48 20 20 20 20 20 20 20 20 20 20 35 30  NGTH          50
3b40: 20 20 2f 2a 20 4d 61 78 69 6d 75 6d 20 6c 65 6e    /* Maximum len
3b50: 67 74 68 20 6f 66 20 61 20 72 75 6c 65 20 73 74  gth of a rule st
3b60: 72 69 6e 67 20 2a 2f 0a 23 64 65 66 69 6e 65 20  ring */.#define 
3b70: 41 4d 41 54 43 48 5f 4d 58 5f 4c 41 4e 47 49 44  AMATCH_MX_LANGID
3b80: 20 20 32 31 34 37 34 38 33 36 34 37 20 20 2f 2a    2147483647  /*
3b90: 20 4d 61 78 69 6d 75 6d 20 72 75 6c 65 20 49 44   Maximum rule ID
3ba0: 20 2a 2f 0a 23 64 65 66 69 6e 65 20 41 4d 41 54   */.#define AMAT
3bb0: 43 48 5f 4d 58 5f 43 4f 53 54 20 20 20 20 20 20  CH_MX_COST      
3bc0: 20 20 20 20 31 30 30 30 20 20 2f 2a 20 4d 61 78      1000  /* Max
3bd0: 69 6d 75 6d 20 73 69 6e 67 6c 65 2d 72 75 6c 65  imum single-rule
3be0: 20 63 6f 73 74 20 2a 2f 0a 0a 2f 2a 0a 2a 2a 20   cost */../*.** 
3bf0: 41 20 6d 61 74 63 68 20 6f 72 20 70 61 72 74 69  A match or parti
3c00: 61 6c 20 6d 61 74 63 68 0a 2a 2f 0a 73 74 72 75  al match.*/.stru
3c10: 63 74 20 61 6d 61 74 63 68 5f 77 6f 72 64 20 7b  ct amatch_word {
3c20: 0a 20 20 61 6d 61 74 63 68 5f 77 6f 72 64 20 2a  .  amatch_word *
3c30: 70 4e 65 78 74 3b 20 20 20 2f 2a 20 4e 65 78 74  pNext;   /* Next
3c40: 20 6f 6e 20 61 20 6c 69 73 74 20 6f 66 20 61 6c   on a list of al
3c50: 6c 20 61 6d 61 74 63 68 5f 77 6f 72 64 73 20 2a  l amatch_words *
3c60: 2f 0a 20 20 61 6d 61 74 63 68 5f 61 76 6c 20 73  /.  amatch_avl s
3c70: 43 6f 73 74 3b 20 20 20 20 20 2f 2a 20 4c 69 6e  Cost;     /* Lin
3c80: 6b 61 67 65 20 6f 66 20 74 68 69 73 20 6e 6f 64  kage of this nod
3c90: 65 20 69 6e 74 6f 20 74 68 65 20 63 6f 73 74 20  e into the cost 
3ca0: 74 72 65 65 20 2a 2f 0a 20 20 61 6d 61 74 63 68  tree */.  amatch
3cb0: 5f 61 76 6c 20 73 57 6f 72 64 3b 20 20 20 20 20  _avl sWord;     
3cc0: 2f 2a 20 4c 69 6e 6b 61 67 65 20 6f 66 20 74 68  /* Linkage of th
3cd0: 69 73 20 6e 6f 64 65 20 69 6e 74 6f 20 74 68 65  is node into the
3ce0: 20 77 6f 72 64 20 74 72 65 65 20 2a 2f 0a 20 20   word tree */.  
3cf0: 61 6d 61 74 63 68 5f 63 6f 73 74 20 72 43 6f 73  amatch_cost rCos
3d00: 74 3b 20 20 20 20 2f 2a 20 43 6f 73 74 20 6f 66  t;    /* Cost of
3d10: 20 74 68 65 20 6d 61 74 63 68 20 73 6f 20 66 61   the match so fa
3d20: 72 20 2a 2f 0a 20 20 69 6e 74 20 69 53 65 71 3b  r */.  int iSeq;
3d30: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
3d40: 53 65 71 75 65 6e 63 65 20 6e 75 6d 62 65 72 20  Sequence number 
3d50: 2a 2f 0a 20 20 63 68 61 72 20 7a 43 6f 73 74 5b  */.  char zCost[
3d60: 31 30 5d 3b 20 20 20 20 20 20 20 2f 2a 20 43 6f  10];       /* Co
3d70: 73 74 20 6b 65 79 20 28 74 65 78 74 20 72 65 6e  st key (text ren
3d80: 64 65 72 69 6e 67 20 6f 66 20 72 43 6f 73 74 29  dering of rCost)
3d90: 20 2a 2f 0a 20 20 73 68 6f 72 74 20 69 6e 74 20   */.  short int 
3da0: 6e 4d 61 74 63 68 3b 20 20 20 20 20 2f 2a 20 49  nMatch;     /* I
3db0: 6e 70 75 74 20 63 68 61 72 61 63 74 65 72 73 20  nput characters 
3dc0: 6d 61 74 63 68 65 64 20 2a 2f 0a 20 20 63 68 61  matched */.  cha
3dd0: 72 20 7a 57 6f 72 64 5b 34 5d 3b 20 20 20 20 20  r zWord[4];     
3de0: 20 20 20 2f 2a 20 54 65 78 74 20 6f 66 20 74 68     /* Text of th
3df0: 65 20 77 6f 72 64 2e 20 20 45 78 74 72 61 20 73  e word.  Extra s
3e00: 70 61 63 65 20 61 70 70 65 6e 64 65 64 20 61 73  pace appended as
3e10: 20 6e 65 65 64 65 64 20 2a 2f 0a 7d 3b 0a 0a 2f   needed */.};../
3e20: 2a 0a 2a 2a 20 45 61 63 68 20 74 72 61 6e 73 66  *.** Each transf
3e30: 6f 72 6d 61 74 69 6f 6e 20 72 75 6c 65 20 69 73  ormation rule is
3e40: 20 73 74 6f 72 65 64 20 61 73 20 61 6e 20 69 6e   stored as an in
3e50: 73 74 61 6e 63 65 20 6f 66 20 74 68 69 73 20 6f  stance of this o
3e60: 62 6a 65 63 74 2e 0a 2a 2a 20 41 6c 6c 20 72 75  bject..** All ru
3e70: 6c 65 73 20 61 72 65 20 6b 65 70 74 20 6f 6e 20  les are kept on 
3e80: 61 20 6c 69 6e 6b 65 64 20 6c 69 73 74 20 73 6f  a linked list so
3e90: 72 74 65 64 20 62 79 20 72 43 6f 73 74 2e 0a 2a  rted by rCost..*
3ea0: 2f 0a 73 74 72 75 63 74 20 61 6d 61 74 63 68 5f  /.struct amatch_
3eb0: 72 75 6c 65 20 7b 0a 20 20 61 6d 61 74 63 68 5f  rule {.  amatch_
3ec0: 72 75 6c 65 20 2a 70 4e 65 78 74 3b 20 20 20 20  rule *pNext;    
3ed0: 20 20 2f 2a 20 4e 65 78 74 20 72 75 6c 65 20 69    /* Next rule i
3ee0: 6e 20 6f 72 64 65 72 20 6f 66 20 69 6e 63 72 65  n order of incre
3ef0: 61 73 69 6e 67 20 72 43 6f 73 74 20 2a 2f 0a 20  asing rCost */. 
3f00: 20 63 68 61 72 20 2a 7a 46 72 6f 6d 3b 20 20 20   char *zFrom;   
3f10: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 72 61            /* Tra
3f20: 6e 73 66 6f 72 6d 20 66 72 6f 6d 20 28 61 20 73  nsform from (a s
3f30: 74 72 69 6e 67 20 66 72 6f 6d 20 75 73 65 72 20  tring from user 
3f40: 69 6e 70 75 74 29 20 2a 2f 0a 20 20 61 6d 61 74  input) */.  amat
3f50: 63 68 5f 63 6f 73 74 20 72 43 6f 73 74 3b 20 20  ch_cost rCost;  
3f60: 20 20 20 20 20 2f 2a 20 43 6f 73 74 20 6f 66 20       /* Cost of 
3f70: 74 68 69 73 20 74 72 61 6e 73 66 6f 72 6d 61 74  this transformat
3f80: 69 6f 6e 20 2a 2f 0a 20 20 61 6d 61 74 63 68 5f  ion */.  amatch_
3f90: 6c 61 6e 67 69 64 20 69 4c 61 6e 67 3b 20 20 20  langid iLang;   
3fa0: 20 20 2f 2a 20 54 68 65 20 6c 61 6e 67 61 75 67    /* The langaug
3fb0: 65 20 74 6f 20 77 68 69 63 68 20 74 68 69 73 20  e to which this 
3fc0: 72 75 6c 65 20 62 65 6c 6f 6e 67 73 20 2a 2f 0a  rule belongs */.
3fd0: 20 20 61 6d 61 74 63 68 5f 6c 65 6e 20 6e 46 72    amatch_len nFr
3fe0: 6f 6d 2c 20 6e 54 6f 3b 20 20 20 2f 2a 20 4c 65  om, nTo;   /* Le
3ff0: 6e 67 74 68 20 6f 66 20 74 68 65 20 7a 46 72 6f  ngth of the zFro
4000: 6d 20 61 6e 64 20 7a 54 6f 20 73 74 72 69 6e 67  m and zTo string
4010: 73 20 2a 2f 0a 20 20 63 68 61 72 20 7a 54 6f 5b  s */.  char zTo[
4020: 34 5d 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  4];             
4030: 2f 2a 20 54 72 61 6e 66 6f 72 6d 20 74 6f 20 56  /* Tranform to V
4040: 2e 57 20 76 61 6c 75 65 20 28 65 78 74 72 61 20  .W value (extra 
4050: 73 70 61 63 65 20 61 70 70 65 6e 64 65 64 29 20  space appended) 
4060: 2a 2f 0a 7d 3b 0a 0a 2f 2a 20 0a 2a 2a 20 41 20  */.};../* .** A 
4070: 61 6d 61 74 63 68 20 76 69 72 74 75 61 6c 2d 74  amatch virtual-t
4080: 61 62 6c 65 20 6f 62 6a 65 63 74 20 0a 2a 2f 0a  able object .*/.
4090: 73 74 72 75 63 74 20 61 6d 61 74 63 68 5f 76 74  struct amatch_vt
40a0: 61 62 20 7b 0a 20 20 73 71 6c 69 74 65 33 5f 76  ab {.  sqlite3_v
40b0: 74 61 62 20 62 61 73 65 3b 20 20 20 20 20 20 20  tab base;       
40c0: 20 20 2f 2a 20 42 61 73 65 20 63 6c 61 73 73 20    /* Base class 
40d0: 2d 20 6d 75 73 74 20 62 65 20 66 69 72 73 74 20  - must be first 
40e0: 2a 2f 0a 20 20 63 68 61 72 20 2a 7a 43 6c 61 73  */.  char *zClas
40f0: 73 4e 61 6d 65 3b 20 20 20 20 20 20 20 20 20 20  sName;          
4100: 2f 2a 20 4e 61 6d 65 20 6f 66 20 74 68 69 73 20  /* Name of this 
4110: 63 6c 61 73 73 2e 20 20 44 65 66 61 75 6c 74 3a  class.  Default:
4120: 20 22 61 6d 61 74 63 68 22 20 2a 2f 0a 20 20 63   "amatch" */.  c
4130: 68 61 72 20 2a 7a 44 62 3b 20 20 20 20 20 20 20  har *zDb;       
4140: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 61 6d            /* Nam
4150: 65 20 6f 66 20 64 61 74 61 62 61 73 65 2e 20 20  e of database.  
4160: 28 65 78 3a 20 22 6d 61 69 6e 22 29 20 2a 2f 0a  (ex: "main") */.
4170: 20 20 63 68 61 72 20 2a 7a 53 65 6c 66 3b 20 20    char *zSelf;  
4180: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
4190: 4e 61 6d 65 20 6f 66 20 74 68 69 73 20 76 69 72  Name of this vir
41a0: 74 75 61 6c 20 74 61 62 6c 65 20 2a 2f 0a 20 20  tual table */.  
41b0: 63 68 61 72 20 2a 7a 43 6f 73 74 54 61 62 3b 20  char *zCostTab; 
41c0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 61             /* Na
41d0: 6d 65 20 6f 66 20 65 64 69 74 2d 63 6f 73 74 2d  me of edit-cost-
41e0: 74 61 62 6c 65 20 2a 2f 0a 20 20 63 68 61 72 20  table */.  char 
41f0: 2a 7a 56 6f 63 61 62 54 61 62 3b 20 20 20 20 20  *zVocabTab;     
4200: 20 20 20 20 20 20 2f 2a 20 4e 61 6d 65 20 6f 66        /* Name of
4210: 20 76 6f 63 61 62 75 6c 61 72 79 20 74 61 62 6c   vocabulary tabl
4220: 65 20 2a 2f 0a 20 20 63 68 61 72 20 2a 7a 56 6f  e */.  char *zVo
4230: 63 61 62 57 6f 72 64 3b 20 20 20 20 20 20 20 20  cabWord;        
4240: 20 20 2f 2a 20 4e 61 6d 65 20 6f 66 20 76 6f 63    /* Name of voc
4250: 61 62 75 6c 61 72 79 20 74 61 62 6c 65 20 77 6f  abulary table wo
4260: 72 64 20 63 6f 6c 75 6d 6e 20 2a 2f 0a 20 20 63  rd column */.  c
4270: 68 61 72 20 2a 7a 56 6f 63 61 62 4c 61 6e 67 3b  har *zVocabLang;
4280: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 61 6d            /* Nam
4290: 65 20 6f 66 20 76 6f 63 61 62 75 6c 61 72 79 20  e of vocabulary 
42a0: 74 61 62 6c 65 20 6c 61 6e 67 75 61 67 65 20 63  table language c
42b0: 6f 6c 75 6d 6e 20 2a 2f 0a 20 20 61 6d 61 74 63  olumn */.  amatc
42c0: 68 5f 72 75 6c 65 20 2a 70 52 75 6c 65 3b 20 20  h_rule *pRule;  
42d0: 20 20 20 20 20 20 2f 2a 20 41 6c 6c 20 61 63 74        /* All act
42e0: 69 76 65 20 72 75 6c 65 73 20 69 6e 20 74 68 69  ive rules in thi
42f0: 73 20 61 6d 61 74 63 68 20 2a 2f 0a 20 20 61 6d  s amatch */.  am
4300: 61 74 63 68 5f 63 6f 73 74 20 72 49 6e 73 3b 20  atch_cost rIns; 
4310: 20 20 20 20 20 20 20 20 20 2f 2a 20 47 65 6e 65           /* Gene
4320: 72 69 63 20 69 6e 73 65 72 74 69 6f 6e 20 63 6f  ric insertion co
4330: 73 74 20 20 27 27 20 2d 3e 20 3f 20 2a 2f 0a 20  st  '' -> ? */. 
4340: 20 61 6d 61 74 63 68 5f 63 6f 73 74 20 72 44 65   amatch_cost rDe
4350: 6c 3b 20 20 20 20 20 20 20 20 20 20 2f 2a 20 47  l;          /* G
4360: 65 6e 65 72 69 63 20 64 65 6c 65 74 69 6f 6e 20  eneric deletion 
4370: 63 6f 73 74 20 20 3f 20 2d 3e 20 27 27 20 2a 2f  cost  ? -> '' */
4380: 0a 20 20 61 6d 61 74 63 68 5f 63 6f 73 74 20 72  .  amatch_cost r
4390: 53 75 62 3b 20 20 20 20 20 20 20 20 20 20 2f 2a  Sub;          /*
43a0: 20 47 65 6e 65 72 69 63 20 73 75 62 73 74 69 74   Generic substit
43b0: 75 74 69 6f 6e 20 63 6f 73 74 20 3f 20 2d 3e 20  ution cost ? -> 
43c0: 3f 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 20 2a  ? */.  sqlite3 *
43d0: 64 62 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  db;             
43e0: 20 20 2f 2a 20 54 68 65 20 64 61 74 61 62 61 73    /* The databas
43f0: 65 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 2a 2f 0a  e connection */.
4400: 20 20 73 71 6c 69 74 65 33 5f 73 74 6d 74 20 2a    sqlite3_stmt *
4410: 70 56 43 68 65 63 6b 3b 20 20 20 20 20 2f 2a 20  pVCheck;     /* 
4420: 51 75 65 72 79 20 74 6f 20 63 68 65 63 6b 20 7a  Query to check z
4430: 56 6f 63 61 62 54 61 62 20 2a 2f 0a 20 20 69 6e  VocabTab */.  in
4440: 74 20 6e 43 75 72 73 6f 72 3b 20 20 20 20 20 20  t nCursor;      
4450: 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62           /* Numb
4460: 65 72 20 6f 66 20 61 63 74 69 76 65 20 63 75 72  er of active cur
4470: 73 6f 72 73 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 20 41  sors */.};../* A
4480: 20 61 6d 61 74 63 68 20 63 75 72 73 6f 72 20 6f   amatch cursor o
4490: 62 6a 65 63 74 20 2a 2f 0a 73 74 72 75 63 74 20  bject */.struct 
44a0: 61 6d 61 74 63 68 5f 63 75 72 73 6f 72 20 7b 0a  amatch_cursor {.
44b0: 20 20 73 71 6c 69 74 65 33 5f 76 74 61 62 5f 63    sqlite3_vtab_c
44c0: 75 72 73 6f 72 20 62 61 73 65 3b 20 20 2f 2a 20  ursor base;  /* 
44d0: 42 61 73 65 20 63 6c 61 73 73 20 2d 20 6d 75 73  Base class - mus
44e0: 74 20 62 65 20 66 69 72 73 74 20 2a 2f 0a 20 20  t be first */.  
44f0: 73 71 6c 69 74 65 33 5f 69 6e 74 36 34 20 69 52  sqlite3_int64 iR
4500: 6f 77 69 64 3b 20 20 20 20 20 20 2f 2a 20 54 68  owid;      /* Th
4510: 65 20 72 6f 77 69 64 20 6f 66 20 74 68 65 20 63  e rowid of the c
4520: 75 72 72 65 6e 74 20 77 6f 72 64 20 2a 2f 0a 20  urrent word */. 
4530: 20 61 6d 61 74 63 68 5f 6c 61 6e 67 69 64 20 69   amatch_langid i
4540: 4c 61 6e 67 3b 20 20 20 20 20 20 20 2f 2a 20 55  Lang;       /* U
4550: 73 65 20 74 68 69 73 20 6c 61 6e 67 75 61 67 65  se this language
4560: 20 49 44 20 2a 2f 0a 20 20 61 6d 61 74 63 68 5f   ID */.  amatch_
4570: 63 6f 73 74 20 72 4c 69 6d 69 74 3b 20 20 20 20  cost rLimit;    
4580: 20 20 20 20 2f 2a 20 4d 61 78 69 6d 75 6d 20 63      /* Maximum c
4590: 6f 73 74 20 6f 66 20 61 6e 79 20 74 65 72 6d 20  ost of any term 
45a0: 2a 2f 0a 20 20 69 6e 74 20 6e 42 75 66 3b 20 20  */.  int nBuf;  
45b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
45c0: 2f 2a 20 53 70 61 63 65 20 61 6c 6c 6f 63 61 74  /* Space allocat
45d0: 65 64 20 66 6f 72 20 7a 42 75 66 20 2a 2f 0a 20  ed for zBuf */. 
45e0: 20 69 6e 74 20 6f 6f 6d 45 72 72 3b 20 20 20 20   int oomErr;    
45f0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54              /* T
4600: 72 75 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 61 6e  rue following an
4610: 20 4f 4f 4d 20 65 72 72 6f 72 20 2a 2f 0a 20 20   OOM error */.  
4620: 69 6e 74 20 6e 57 6f 72 64 3b 20 20 20 20 20 20  int nWord;      
4630: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75             /* Nu
4640: 6d 62 65 72 20 6f 66 20 61 6d 61 74 63 68 5f 77  mber of amatch_w
4650: 6f 72 64 20 6f 62 6a 65 63 74 73 20 2a 2f 0a 20  ord objects */. 
4660: 20 63 68 61 72 20 2a 7a 42 75 66 3b 20 20 20 20   char *zBuf;    
4670: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54              /* T
4680: 65 6d 70 2d 75 73 65 20 62 75 66 66 65 72 20 73  emp-use buffer s
4690: 70 61 63 65 20 2a 2f 0a 20 20 63 68 61 72 20 2a  pace */.  char *
46a0: 7a 49 6e 70 75 74 3b 20 20 20 20 20 20 20 20 20  zInput;         
46b0: 20 20 20 20 20 2f 2a 20 49 6e 70 75 74 20 77 6f       /* Input wo
46c0: 72 64 20 74 6f 20 6d 61 74 63 68 20 61 67 61 69  rd to match agai
46d0: 6e 73 74 20 2a 2f 0a 20 20 61 6d 61 74 63 68 5f  nst */.  amatch_
46e0: 76 74 61 62 20 2a 70 56 74 61 62 3b 20 20 20 20  vtab *pVtab;    
46f0: 20 20 20 20 2f 2a 20 54 68 65 20 76 69 72 74 75      /* The virtu
4700: 61 6c 20 74 61 62 6c 65 20 74 68 69 73 20 63 75  al table this cu
4710: 72 73 6f 72 20 62 65 6c 6f 6e 67 73 20 74 6f 20  rsor belongs to 
4720: 2a 2f 0a 20 20 61 6d 61 74 63 68 5f 77 6f 72 64  */.  amatch_word
4730: 20 2a 70 41 6c 6c 57 6f 72 64 73 3b 20 20 20 20   *pAllWords;    
4740: 2f 2a 20 4c 69 73 74 20 6f 66 20 61 6c 6c 20 61  /* List of all a
4750: 6d 61 74 63 68 5f 77 6f 72 64 20 6f 62 6a 65 63  match_word objec
4760: 74 73 20 2a 2f 0a 20 20 61 6d 61 74 63 68 5f 77  ts */.  amatch_w
4770: 6f 72 64 20 2a 70 43 75 72 72 65 6e 74 3b 20 20  ord *pCurrent;  
4780: 20 20 20 2f 2a 20 4d 6f 73 74 20 72 65 63 65 6e     /* Most recen
4790: 74 20 73 6f 6c 75 74 69 6f 6e 20 2a 2f 0a 20 20  t solution */.  
47a0: 61 6d 61 74 63 68 5f 61 76 6c 20 2a 70 43 6f 73  amatch_avl *pCos
47b0: 74 3b 20 20 20 20 20 20 20 20 20 2f 2a 20 61 6d  t;         /* am
47c0: 61 74 63 68 5f 77 6f 72 64 20 6f 62 6a 65 63 74  atch_word object
47d0: 73 20 6b 65 79 65 64 20 62 79 20 69 43 6f 73 74  s keyed by iCost
47e0: 20 2a 2f 0a 20 20 61 6d 61 74 63 68 5f 61 76 6c   */.  amatch_avl
47f0: 20 2a 70 57 6f 72 64 3b 20 20 20 20 20 20 20 20   *pWord;        
4800: 20 2f 2a 20 61 6d 61 74 63 68 5f 77 6f 72 64 20   /* amatch_word 
4810: 6f 62 6a 65 63 74 73 20 6b 65 79 65 64 20 62 79  objects keyed by
4820: 20 7a 57 6f 72 64 20 2a 2f 0a 7d 3b 0a 0a 2f 2a   zWord */.};../*
4830: 0a 2a 2a 20 54 68 65 20 74 77 6f 20 69 6e 70 75  .** The two inpu
4840: 74 20 72 75 6c 65 20 6c 69 73 74 73 20 61 72 65  t rule lists are
4850: 20 62 6f 74 68 20 73 6f 72 74 65 64 20 69 6e 20   both sorted in 
4860: 6f 72 64 65 72 20 6f 66 20 69 6e 63 72 65 61 73  order of increas
4870: 69 6e 67 0a 2a 2a 20 63 6f 73 74 2e 20 20 4d 65  ing.** cost.  Me
4880: 72 67 65 20 74 68 65 6d 20 74 6f 67 65 74 68 65  rge them togethe
4890: 72 20 69 6e 74 6f 20 61 20 73 69 6e 67 6c 65 20  r into a single 
48a0: 6c 69 73 74 2c 20 73 6f 72 74 65 64 20 62 79 20  list, sorted by 
48b0: 63 6f 73 74 2c 20 61 6e 64 0a 2a 2a 20 72 65 74  cost, and.** ret
48c0: 75 72 6e 20 61 20 70 6f 69 6e 74 65 72 20 74 6f  urn a pointer to
48d0: 20 74 68 65 20 68 65 61 64 20 6f 66 20 74 68 61   the head of tha
48e0: 74 20 6c 69 73 74 2e 0a 2a 2f 0a 73 74 61 74 69  t list..*/.stati
48f0: 63 20 61 6d 61 74 63 68 5f 72 75 6c 65 20 2a 61  c amatch_rule *a
4900: 6d 61 74 63 68 4d 65 72 67 65 52 75 6c 65 73 28  matchMergeRules(
4910: 61 6d 61 74 63 68 5f 72 75 6c 65 20 2a 70 41 2c  amatch_rule *pA,
4920: 20 61 6d 61 74 63 68 5f 72 75 6c 65 20 2a 70 42   amatch_rule *pB
4930: 29 7b 0a 20 20 61 6d 61 74 63 68 5f 72 75 6c 65  ){.  amatch_rule
4940: 20 68 65 61 64 3b 0a 20 20 61 6d 61 74 63 68 5f   head;.  amatch_
4950: 72 75 6c 65 20 2a 70 54 61 69 6c 3b 0a 0a 20 20  rule *pTail;..  
4960: 70 54 61 69 6c 20 3d 20 20 26 68 65 61 64 3b 0a  pTail =  &head;.
4970: 20 20 77 68 69 6c 65 28 20 70 41 20 26 26 20 70    while( pA && p
4980: 42 20 29 7b 0a 20 20 20 20 69 66 28 20 70 41 2d  B ){.    if( pA-
4990: 3e 72 43 6f 73 74 3c 3d 70 42 2d 3e 72 43 6f 73  >rCost<=pB->rCos
49a0: 74 20 29 7b 0a 20 20 20 20 20 20 70 54 61 69 6c  t ){.      pTail
49b0: 2d 3e 70 4e 65 78 74 20 3d 20 70 41 3b 0a 20 20  ->pNext = pA;.  
49c0: 20 20 20 20 70 54 61 69 6c 20 3d 20 70 41 3b 0a      pTail = pA;.
49d0: 20 20 20 20 20 20 70 41 20 3d 20 70 41 2d 3e 70        pA = pA->p
49e0: 4e 65 78 74 3b 0a 20 20 20 20 7d 65 6c 73 65 7b  Next;.    }else{
49f0: 0a 20 20 20 20 20 20 70 54 61 69 6c 2d 3e 70 4e  .      pTail->pN
4a00: 65 78 74 20 3d 20 70 42 3b 0a 20 20 20 20 20 20  ext = pB;.      
4a10: 70 54 61 69 6c 20 3d 20 70 42 3b 0a 20 20 20 20  pTail = pB;.    
4a20: 20 20 70 42 20 3d 20 70 42 2d 3e 70 4e 65 78 74    pB = pB->pNext
4a30: 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 69 66  ;.    }.  }.  if
4a40: 28 20 70 41 3d 3d 30 20 29 7b 0a 20 20 20 20 70  ( pA==0 ){.    p
4a50: 54 61 69 6c 2d 3e 70 4e 65 78 74 20 3d 20 70 42  Tail->pNext = pB
4a60: 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 70  ;.  }else{.    p
4a70: 54 61 69 6c 2d 3e 70 4e 65 78 74 20 3d 20 70 41  Tail->pNext = pA
4a80: 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 68  ;.  }.  return h
4a90: 65 61 64 2e 70 4e 65 78 74 3b 0a 7d 0a 0a 2f 2a  ead.pNext;.}../*
4aa0: 0a 2a 2a 20 53 74 61 74 65 6d 65 6e 74 20 70 53  .** Statement pS
4ab0: 74 6d 74 20 63 75 72 72 65 6e 74 6c 79 20 70 6f  tmt currently po
4ac0: 69 6e 74 73 20 74 6f 20 61 20 72 6f 77 20 69 6e  ints to a row in
4ad0: 20 74 68 65 20 61 6d 61 74 63 68 20 64 61 74 61   the amatch data
4ae0: 20 74 61 62 6c 65 2e 20 54 68 69 73 0a 2a 2a 20   table. This.** 
4af0: 66 75 6e 63 74 69 6f 6e 20 61 6c 6c 6f 63 61 74  function allocat
4b00: 65 73 20 61 6e 64 20 70 6f 70 75 6c 61 74 65 73  es and populates
4b10: 20 61 20 61 6d 61 74 63 68 5f 72 75 6c 65 20 73   a amatch_rule s
4b20: 74 72 75 63 74 75 72 65 20 61 63 63 6f 72 64 69  tructure accordi
4b30: 6e 67 20 74 6f 0a 2a 2a 20 74 68 65 20 63 6f 6e  ng to.** the con
4b40: 74 65 6e 74 20 6f 66 20 74 68 65 20 72 6f 77 2e  tent of the row.
4b50: 0a 2a 2a 0a 2a 2a 20 49 66 20 73 75 63 63 65 73  .**.** If succes
4b60: 73 66 75 6c 2c 20 2a 70 70 52 75 6c 65 20 69 73  sful, *ppRule is
4b70: 20 73 65 74 20 74 6f 20 70 6f 69 6e 74 20 74 6f   set to point to
4b80: 20 74 68 65 20 6e 65 77 20 6f 62 6a 65 63 74 20   the new object 
4b90: 61 6e 64 20 53 51 4c 49 54 45 5f 4f 4b 0a 2a 2a  and SQLITE_OK.**
4ba0: 20 69 73 20 72 65 74 75 72 6e 65 64 2e 20 4f 74   is returned. Ot
4bb0: 68 65 72 77 69 73 65 2c 20 2a 70 70 52 75 6c 65  herwise, *ppRule
4bc0: 20 69 73 20 7a 65 72 6f 65 64 2c 20 2a 70 7a 45   is zeroed, *pzE
4bd0: 72 72 20 6d 61 79 20 62 65 20 73 65 74 20 74 6f  rr may be set to
4be0: 20 70 6f 69 6e 74 0a 2a 2a 20 74 6f 20 61 6e 20   point.** to an 
4bf0: 65 72 72 6f 72 20 6d 65 73 73 61 67 65 20 61 6e  error message an
4c00: 64 20 61 6e 20 53 51 4c 69 74 65 20 65 72 72 6f  d an SQLite erro
4c10: 72 20 63 6f 64 65 20 72 65 74 75 72 6e 65 64 2e  r code returned.
4c20: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 61  .*/.static int a
4c30: 6d 61 74 63 68 4c 6f 61 64 4f 6e 65 52 75 6c 65  matchLoadOneRule
4c40: 28 0a 20 20 61 6d 61 74 63 68 5f 76 74 61 62 20  (.  amatch_vtab 
4c50: 2a 70 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  *p,             
4c60: 20 20 20 20 2f 2a 20 46 75 7a 7a 65 72 20 76 69      /* Fuzzer vi
4c70: 72 74 75 61 6c 20 74 61 62 6c 65 20 68 61 6e 64  rtual table hand
4c80: 6c 65 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f  le */.  sqlite3_
4c90: 73 74 6d 74 20 2a 70 53 74 6d 74 2c 20 20 20 20  stmt *pStmt,    
4ca0: 20 20 20 20 20 20 20 20 2f 2a 20 42 61 73 65 20          /* Base 
4cb0: 72 75 6c 65 20 6f 6e 20 73 74 61 74 65 6d 65 6e  rule on statemen
4cc0: 74 73 20 63 75 72 72 65 6e 74 20 72 6f 77 20 2a  ts current row *
4cd0: 2f 0a 20 20 61 6d 61 74 63 68 5f 72 75 6c 65 20  /.  amatch_rule 
4ce0: 2a 2a 70 70 52 75 6c 65 2c 20 20 20 20 20 20 20  **ppRule,       
4cf0: 20 20 20 20 2f 2a 20 4f 55 54 3a 20 4e 65 77 20      /* OUT: New 
4d00: 72 75 6c 65 20 6f 62 6a 65 63 74 20 2a 2f 0a 20  rule object */. 
4d10: 20 63 68 61 72 20 2a 2a 70 7a 45 72 72 20 20 20   char **pzErr   
4d20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4d30: 20 2f 2a 20 4f 55 54 3a 20 45 72 72 6f 72 20 6d   /* OUT: Error m
4d40: 65 73 73 61 67 65 20 2a 2f 0a 29 7b 0a 20 20 73  essage */.){.  s
4d50: 71 6c 69 74 65 33 5f 69 6e 74 36 34 20 69 4c 61  qlite3_int64 iLa
4d60: 6e 67 20 3d 20 73 71 6c 69 74 65 33 5f 63 6f 6c  ng = sqlite3_col
4d70: 75 6d 6e 5f 69 6e 74 36 34 28 70 53 74 6d 74 2c  umn_int64(pStmt,
4d80: 20 30 29 3b 0a 20 20 63 6f 6e 73 74 20 63 68 61   0);.  const cha
4d90: 72 20 2a 7a 46 72 6f 6d 20 3d 20 28 63 6f 6e 73  r *zFrom = (cons
4da0: 74 20 63 68 61 72 20 2a 29 73 71 6c 69 74 65 33  t char *)sqlite3
4db0: 5f 63 6f 6c 75 6d 6e 5f 74 65 78 74 28 70 53 74  _column_text(pSt
4dc0: 6d 74 2c 20 31 29 3b 0a 20 20 63 6f 6e 73 74 20  mt, 1);.  const 
4dd0: 63 68 61 72 20 2a 7a 54 6f 20 3d 20 28 63 6f 6e  char *zTo = (con
4de0: 73 74 20 63 68 61 72 20 2a 29 73 71 6c 69 74 65  st char *)sqlite
4df0: 33 5f 63 6f 6c 75 6d 6e 5f 74 65 78 74 28 70 53  3_column_text(pS
4e00: 74 6d 74 2c 20 32 29 3b 0a 20 20 61 6d 61 74 63  tmt, 2);.  amatc
4e10: 68 5f 63 6f 73 74 20 72 43 6f 73 74 20 3d 20 73  h_cost rCost = s
4e20: 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 69 6e  qlite3_column_in
4e30: 74 28 70 53 74 6d 74 2c 20 33 29 3b 0a 0a 20 20  t(pStmt, 3);..  
4e40: 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f  int rc = SQLITE_
4e50: 4f 4b 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  OK;             
4e60: 2f 2a 20 52 65 74 75 72 6e 20 63 6f 64 65 20 2a  /* Return code *
4e70: 2f 0a 20 20 69 6e 74 20 6e 46 72 6f 6d 3b 20 20  /.  int nFrom;  
4e80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4e90: 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20 73      /* Size of s
4ea0: 74 72 69 6e 67 20 7a 46 72 6f 6d 2c 20 69 6e 20  tring zFrom, in 
4eb0: 62 79 74 65 73 20 2a 2f 0a 20 20 69 6e 74 20 6e  bytes */.  int n
4ec0: 54 6f 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  To;             
4ed0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 69             /* Si
4ee0: 7a 65 20 6f 66 20 73 74 72 69 6e 67 20 7a 54 6f  ze of string zTo
4ef0: 2c 20 69 6e 20 62 79 74 65 73 20 2a 2f 0a 20 20  , in bytes */.  
4f00: 61 6d 61 74 63 68 5f 72 75 6c 65 20 2a 70 52 75  amatch_rule *pRu
4f10: 6c 65 20 3d 20 30 3b 20 20 20 20 20 20 20 20 20  le = 0;         
4f20: 2f 2a 20 4e 65 77 20 72 75 6c 65 20 6f 62 6a 65  /* New rule obje
4f30: 63 74 20 74 6f 20 72 65 74 75 72 6e 20 2a 2f 0a  ct to return */.
4f40: 0a 20 20 69 66 28 20 7a 46 72 6f 6d 3d 3d 30 20  .  if( zFrom==0 
4f50: 29 20 7a 46 72 6f 6d 20 3d 20 22 22 3b 0a 20 20  ) zFrom = "";.  
4f60: 69 66 28 20 7a 54 6f 3d 3d 30 20 29 20 7a 54 6f  if( zTo==0 ) zTo
4f70: 20 3d 20 22 22 3b 0a 20 20 6e 46 72 6f 6d 20 3d   = "";.  nFrom =
4f80: 20 28 69 6e 74 29 73 74 72 6c 65 6e 28 7a 46 72   (int)strlen(zFr
4f90: 6f 6d 29 3b 0a 20 20 6e 54 6f 20 3d 20 28 69 6e  om);.  nTo = (in
4fa0: 74 29 73 74 72 6c 65 6e 28 7a 54 6f 29 3b 0a 0a  t)strlen(zTo);..
4fb0: 20 20 2f 2a 20 53 69 6c 65 6e 74 6c 79 20 69 67    /* Silently ig
4fc0: 6e 6f 72 65 20 6e 75 6c 6c 20 74 72 61 6e 73 66  nore null transf
4fd0: 6f 72 6d 61 74 69 6f 6e 73 20 2a 2f 0a 20 20 69  ormations */.  i
4fe0: 66 28 20 73 74 72 63 6d 70 28 7a 46 72 6f 6d 2c  f( strcmp(zFrom,
4ff0: 20 7a 54 6f 29 3d 3d 30 20 29 7b 0a 20 20 20 20   zTo)==0 ){.    
5000: 69 66 28 20 7a 46 72 6f 6d 5b 30 5d 3d 3d 27 3f  if( zFrom[0]=='?
5010: 27 20 26 26 20 7a 46 72 6f 6d 5b 31 5d 3d 3d 30  ' && zFrom[1]==0
5020: 20 29 7b 0a 20 20 20 20 20 20 69 66 28 20 70 2d   ){.      if( p-
5030: 3e 72 53 75 62 3d 3d 30 20 7c 7c 20 70 2d 3e 72  >rSub==0 || p->r
5040: 53 75 62 3e 72 43 6f 73 74 20 29 20 70 2d 3e 72  Sub>rCost ) p->r
5050: 53 75 62 20 3d 20 72 43 6f 73 74 3b 0a 20 20 20  Sub = rCost;.   
5060: 20 7d 0a 20 20 20 20 2a 70 70 52 75 6c 65 20 3d   }.    *ppRule =
5070: 20 30 3b 0a 20 20 20 20 72 65 74 75 72 6e 20 53   0;.    return S
5080: 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 7d 0a 0a 20  QLITE_OK;.  }.. 
5090: 20 69 66 28 20 72 43 6f 73 74 3c 3d 30 20 7c 7c   if( rCost<=0 ||
50a0: 20 72 43 6f 73 74 3e 41 4d 41 54 43 48 5f 4d 58   rCost>AMATCH_MX
50b0: 5f 43 4f 53 54 20 29 7b 0a 20 20 20 20 2a 70 7a  _COST ){.    *pz
50c0: 45 72 72 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70  Err = sqlite3_mp
50d0: 72 69 6e 74 66 28 22 25 73 3a 20 63 6f 73 74 20  rintf("%s: cost 
50e0: 6d 75 73 74 20 62 65 20 62 65 74 77 65 65 6e 20  must be between 
50f0: 31 20 61 6e 64 20 25 64 22 2c 20 0a 20 20 20 20  1 and %d", .    
5100: 20 20 20 20 70 2d 3e 7a 43 6c 61 73 73 4e 61 6d      p->zClassNam
5110: 65 2c 20 41 4d 41 54 43 48 5f 4d 58 5f 43 4f 53  e, AMATCH_MX_COS
5120: 54 0a 20 20 20 20 29 3b 0a 20 20 20 20 72 63 20  T.    );.    rc 
5130: 3d 20 53 51 4c 49 54 45 5f 45 52 52 4f 52 3b 0a  = SQLITE_ERROR;.
5140: 20 20 7d 65 6c 73 65 0a 20 20 69 66 28 20 6e 46    }else.  if( nF
5150: 72 6f 6d 3e 41 4d 41 54 43 48 5f 4d 58 5f 4c 45  rom>AMATCH_MX_LE
5160: 4e 47 54 48 20 7c 7c 20 6e 54 6f 3e 41 4d 41 54  NGTH || nTo>AMAT
5170: 43 48 5f 4d 58 5f 4c 45 4e 47 54 48 20 29 7b 0a  CH_MX_LENGTH ){.
5180: 20 20 20 20 2a 70 7a 45 72 72 20 3d 20 73 71 6c      *pzErr = sql
5190: 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 22 25 73  ite3_mprintf("%s
51a0: 3a 20 6d 61 78 69 6d 75 6d 20 73 74 72 69 6e 67  : maximum string
51b0: 20 6c 65 6e 67 74 68 20 69 73 20 25 64 22 2c 20   length is %d", 
51c0: 0a 20 20 20 20 20 20 20 20 70 2d 3e 7a 43 6c 61  .        p->zCla
51d0: 73 73 4e 61 6d 65 2c 20 41 4d 41 54 43 48 5f 4d  ssName, AMATCH_M
51e0: 58 5f 4c 45 4e 47 54 48 0a 20 20 20 20 29 3b 0a  X_LENGTH.    );.
51f0: 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f      rc = SQLITE_
5200: 45 52 52 4f 52 3b 20 20 20 20 0a 20 20 7d 65 6c  ERROR;    .  }el
5210: 73 65 0a 20 20 69 66 28 20 69 4c 61 6e 67 3c 30  se.  if( iLang<0
5220: 20 7c 7c 20 69 4c 61 6e 67 3e 41 4d 41 54 43 48   || iLang>AMATCH
5230: 5f 4d 58 5f 4c 41 4e 47 49 44 20 29 7b 0a 20 20  _MX_LANGID ){.  
5240: 20 20 2a 70 7a 45 72 72 20 3d 20 73 71 6c 69 74    *pzErr = sqlit
5250: 65 33 5f 6d 70 72 69 6e 74 66 28 22 25 73 3a 20  e3_mprintf("%s: 
5260: 69 4c 61 6e 67 20 6d 75 73 74 20 62 65 20 62 65  iLang must be be
5270: 74 77 65 65 6e 20 30 20 61 6e 64 20 25 64 22 2c  tween 0 and %d",
5280: 20 0a 20 20 20 20 20 20 20 20 70 2d 3e 7a 43 6c   .        p->zCl
5290: 61 73 73 4e 61 6d 65 2c 20 41 4d 41 54 43 48 5f  assName, AMATCH_
52a0: 4d 58 5f 4c 41 4e 47 49 44 0a 20 20 20 20 29 3b  MX_LANGID.    );
52b0: 0a 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45  .    rc = SQLITE
52c0: 5f 45 52 52 4f 52 3b 20 20 20 20 0a 20 20 7d 65  _ERROR;    .  }e
52d0: 6c 73 65 0a 20 20 69 66 28 20 73 74 72 63 6d 70  lse.  if( strcmp
52e0: 28 7a 46 72 6f 6d 2c 22 22 29 3d 3d 30 20 26 26  (zFrom,"")==0 &&
52f0: 20 73 74 72 63 6d 70 28 7a 54 6f 2c 22 3f 22 29   strcmp(zTo,"?")
5300: 3d 3d 30 20 29 7b 0a 20 20 20 20 69 66 28 20 70  ==0 ){.    if( p
5310: 2d 3e 72 49 6e 73 3d 3d 30 20 7c 7c 20 70 2d 3e  ->rIns==0 || p->
5320: 72 49 6e 73 3e 72 43 6f 73 74 20 29 20 70 2d 3e  rIns>rCost ) p->
5330: 72 49 6e 73 20 3d 20 72 43 6f 73 74 3b 0a 20 20  rIns = rCost;.  
5340: 7d 65 6c 73 65 0a 20 20 69 66 28 20 73 74 72 63  }else.  if( strc
5350: 6d 70 28 7a 46 72 6f 6d 2c 22 3f 22 29 3d 3d 30  mp(zFrom,"?")==0
5360: 20 26 26 20 73 74 72 63 6d 70 28 7a 54 6f 2c 22   && strcmp(zTo,"
5370: 22 29 3d 3d 30 20 29 7b 0a 20 20 20 20 69 66 28  ")==0 ){.    if(
5380: 20 70 2d 3e 72 44 65 6c 3d 3d 30 20 7c 7c 20 70   p->rDel==0 || p
5390: 2d 3e 72 44 65 6c 3e 72 43 6f 73 74 20 29 20 70  ->rDel>rCost ) p
53a0: 2d 3e 72 44 65 6c 20 3d 20 72 43 6f 73 74 3b 0a  ->rDel = rCost;.
53b0: 20 20 7d 65 6c 73 65 0a 20 20 7b 0a 20 20 20 20    }else.  {.    
53c0: 70 52 75 6c 65 20 3d 20 73 71 6c 69 74 65 33 5f  pRule = sqlite3_
53d0: 6d 61 6c 6c 6f 63 28 20 73 69 7a 65 6f 66 28 2a  malloc( sizeof(*
53e0: 70 52 75 6c 65 29 20 2b 20 6e 46 72 6f 6d 20 2b  pRule) + nFrom +
53f0: 20 6e 54 6f 20 29 3b 0a 20 20 20 20 69 66 28 20   nTo );.    if( 
5400: 70 52 75 6c 65 3d 3d 30 20 29 7b 0a 20 20 20 20  pRule==0 ){.    
5410: 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4e 4f    rc = SQLITE_NO
5420: 4d 45 4d 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a  MEM;.    }else{.
5430: 20 20 20 20 20 20 6d 65 6d 73 65 74 28 70 52 75        memset(pRu
5440: 6c 65 2c 20 30 2c 20 73 69 7a 65 6f 66 28 2a 70  le, 0, sizeof(*p
5450: 52 75 6c 65 29 29 3b 0a 20 20 20 20 20 20 70 52  Rule));.      pR
5460: 75 6c 65 2d 3e 7a 46 72 6f 6d 20 3d 20 26 70 52  ule->zFrom = &pR
5470: 75 6c 65 2d 3e 7a 54 6f 5b 6e 54 6f 2b 31 5d 3b  ule->zTo[nTo+1];
5480: 0a 20 20 20 20 20 20 70 52 75 6c 65 2d 3e 6e 46  .      pRule->nF
5490: 72 6f 6d 20 3d 20 28 61 6d 61 74 63 68 5f 6c 65  rom = (amatch_le
54a0: 6e 29 6e 46 72 6f 6d 3b 0a 20 20 20 20 20 20 6d  n)nFrom;.      m
54b0: 65 6d 63 70 79 28 70 52 75 6c 65 2d 3e 7a 46 72  emcpy(pRule->zFr
54c0: 6f 6d 2c 20 7a 46 72 6f 6d 2c 20 6e 46 72 6f 6d  om, zFrom, nFrom
54d0: 2b 31 29 3b 0a 20 20 20 20 20 20 6d 65 6d 63 70  +1);.      memcp
54e0: 79 28 70 52 75 6c 65 2d 3e 7a 54 6f 2c 20 7a 54  y(pRule->zTo, zT
54f0: 6f 2c 20 6e 54 6f 2b 31 29 3b 0a 20 20 20 20 20  o, nTo+1);.     
5500: 20 70 52 75 6c 65 2d 3e 6e 54 6f 20 3d 20 28 61   pRule->nTo = (a
5510: 6d 61 74 63 68 5f 6c 65 6e 29 6e 54 6f 3b 0a 20  match_len)nTo;. 
5520: 20 20 20 20 20 70 52 75 6c 65 2d 3e 72 43 6f 73       pRule->rCos
5530: 74 20 3d 20 72 43 6f 73 74 3b 0a 20 20 20 20 20  t = rCost;.     
5540: 20 70 52 75 6c 65 2d 3e 69 4c 61 6e 67 20 3d 20   pRule->iLang = 
5550: 28 69 6e 74 29 69 4c 61 6e 67 3b 0a 20 20 20 20  (int)iLang;.    
5560: 7d 0a 20 20 7d 0a 0a 20 20 2a 70 70 52 75 6c 65  }.  }..  *ppRule
5570: 20 3d 20 70 52 75 6c 65 3b 0a 20 20 72 65 74 75   = pRule;.  retu
5580: 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  rn rc;.}../*.** 
5590: 46 72 65 65 20 61 6c 6c 20 74 68 65 20 63 6f 6e  Free all the con
55a0: 74 65 6e 74 20 69 6e 20 74 68 65 20 65 64 69 74  tent in the edit
55b0: 2d 63 6f 73 74 2d 74 61 62 6c 65 0a 2a 2f 0a 73  -cost-table.*/.s
55c0: 74 61 74 69 63 20 76 6f 69 64 20 61 6d 61 74 63  tatic void amatc
55d0: 68 46 72 65 65 52 75 6c 65 73 28 61 6d 61 74 63  hFreeRules(amatc
55e0: 68 5f 76 74 61 62 20 2a 70 29 7b 0a 20 20 77 68  h_vtab *p){.  wh
55f0: 69 6c 65 28 20 70 2d 3e 70 52 75 6c 65 20 29 7b  ile( p->pRule ){
5600: 0a 20 20 20 20 61 6d 61 74 63 68 5f 72 75 6c 65  .    amatch_rule
5610: 20 2a 70 52 75 6c 65 20 3d 20 70 2d 3e 70 52 75   *pRule = p->pRu
5620: 6c 65 3b 0a 20 20 20 20 70 2d 3e 70 52 75 6c 65  le;.    p->pRule
5630: 20 3d 20 70 52 75 6c 65 2d 3e 70 4e 65 78 74 3b   = pRule->pNext;
5640: 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65  .    sqlite3_fre
5650: 65 28 70 52 75 6c 65 29 3b 0a 20 20 7d 0a 20 20  e(pRule);.  }.  
5660: 70 2d 3e 70 52 75 6c 65 20 3d 20 30 3b 0a 7d 0a  p->pRule = 0;.}.
5670: 0a 2f 2a 0a 2a 2a 20 4c 6f 61 64 20 74 68 65 20  ./*.** Load the 
5680: 63 6f 6e 74 65 6e 74 20 6f 66 20 74 68 65 20 61  content of the a
5690: 6d 61 74 63 68 20 64 61 74 61 20 74 61 62 6c 65  match data table
56a0: 20 69 6e 74 6f 20 6d 65 6d 6f 72 79 2e 0a 2a 2f   into memory..*/
56b0: 0a 73 74 61 74 69 63 20 69 6e 74 20 61 6d 61 74  .static int amat
56c0: 63 68 4c 6f 61 64 52 75 6c 65 73 28 0a 20 20 73  chLoadRules(.  s
56d0: 71 6c 69 74 65 33 20 2a 64 62 2c 20 20 20 20 20  qlite3 *db,     
56e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
56f0: 2a 20 44 61 74 61 62 61 73 65 20 68 61 6e 64 6c  * Database handl
5700: 65 20 2a 2f 0a 20 20 61 6d 61 74 63 68 5f 76 74  e */.  amatch_vt
5710: 61 62 20 2a 70 2c 20 20 20 20 20 20 20 20 20 20  ab *p,          
5720: 20 20 20 20 20 20 20 2f 2a 20 56 69 72 74 75 61         /* Virtua
5730: 6c 20 61 6d 61 74 63 68 20 74 61 62 6c 65 20 74  l amatch table t
5740: 6f 20 63 6f 6e 66 69 67 75 72 65 20 2a 2f 0a 20  o configure */. 
5750: 20 63 68 61 72 20 2a 2a 70 7a 45 72 72 20 20 20   char **pzErr   
5760: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5770: 20 2f 2a 20 4f 55 54 3a 20 45 72 72 6f 72 20 6d   /* OUT: Error m
5780: 65 73 73 61 67 65 20 2a 2f 0a 29 7b 0a 20 20 69  essage */.){.  i
5790: 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f  nt rc = SQLITE_O
57a0: 4b 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 2f  K;             /
57b0: 2a 20 52 65 74 75 72 6e 20 63 6f 64 65 20 2a 2f  * Return code */
57c0: 0a 20 20 63 68 61 72 20 2a 7a 53 71 6c 3b 20 20  .  char *zSql;  
57d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
57e0: 20 20 20 2f 2a 20 53 45 4c 45 43 54 20 75 73 65     /* SELECT use
57f0: 64 20 74 6f 20 72 65 61 64 20 66 72 6f 6d 20 72  d to read from r
5800: 75 6c 65 73 20 74 61 62 6c 65 20 2a 2f 0a 20 20  ules table */.  
5810: 61 6d 61 74 63 68 5f 72 75 6c 65 20 2a 70 48 65  amatch_rule *pHe
5820: 61 64 20 3d 20 30 3b 0a 0a 20 20 7a 53 71 6c 20  ad = 0;..  zSql 
5830: 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74  = sqlite3_mprint
5840: 66 28 22 53 45 4c 45 43 54 20 2a 20 46 52 4f 4d  f("SELECT * FROM
5850: 20 25 51 2e 25 51 22 2c 20 70 2d 3e 7a 44 62 2c   %Q.%Q", p->zDb,
5860: 20 70 2d 3e 7a 43 6f 73 74 54 61 62 29 3b 0a 20   p->zCostTab);. 
5870: 20 69 66 28 20 7a 53 71 6c 3d 3d 30 20 29 7b 0a   if( zSql==0 ){.
5880: 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f      rc = SQLITE_
5890: 4e 4f 4d 45 4d 3b 0a 20 20 7d 65 6c 73 65 7b 0a  NOMEM;.  }else{.
58a0: 20 20 20 20 69 6e 74 20 72 63 32 3b 20 20 20 20      int rc2;    
58b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
58c0: 20 20 2f 2a 20 66 69 6e 61 6c 69 7a 65 28 29 20    /* finalize() 
58d0: 72 65 74 75 72 6e 20 63 6f 64 65 20 2a 2f 0a 20  return code */. 
58e0: 20 20 20 73 71 6c 69 74 65 33 5f 73 74 6d 74 20     sqlite3_stmt 
58f0: 2a 70 53 74 6d 74 20 3d 20 30 3b 0a 20 20 20 20  *pStmt = 0;.    
5900: 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 70 72 65  rc = sqlite3_pre
5910: 70 61 72 65 5f 76 32 28 64 62 2c 20 7a 53 71 6c  pare_v2(db, zSql
5920: 2c 20 2d 31 2c 20 26 70 53 74 6d 74 2c 20 30 29  , -1, &pStmt, 0)
5930: 3b 0a 20 20 20 20 69 66 28 20 72 63 21 3d 53 51  ;.    if( rc!=SQ
5940: 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20  LITE_OK ){.     
5950: 20 2a 70 7a 45 72 72 20 3d 20 73 71 6c 69 74 65   *pzErr = sqlite
5960: 33 5f 6d 70 72 69 6e 74 66 28 22 25 73 3a 20 25  3_mprintf("%s: %
5970: 73 22 2c 20 70 2d 3e 7a 43 6c 61 73 73 4e 61 6d  s", p->zClassNam
5980: 65 2c 20 73 71 6c 69 74 65 33 5f 65 72 72 6d 73  e, sqlite3_errms
5990: 67 28 64 62 29 29 3b 0a 20 20 20 20 7d 65 6c 73  g(db));.    }els
59a0: 65 20 69 66 28 20 73 71 6c 69 74 65 33 5f 63 6f  e if( sqlite3_co
59b0: 6c 75 6d 6e 5f 63 6f 75 6e 74 28 70 53 74 6d 74  lumn_count(pStmt
59c0: 29 21 3d 34 20 29 7b 0a 20 20 20 20 20 20 2a 70  )!=4 ){.      *p
59d0: 7a 45 72 72 20 3d 20 73 71 6c 69 74 65 33 5f 6d  zErr = sqlite3_m
59e0: 70 72 69 6e 74 66 28 22 25 73 3a 20 25 73 20 68  printf("%s: %s h
59f0: 61 73 20 25 64 20 63 6f 6c 75 6d 6e 73 2c 20 65  as %d columns, e
5a00: 78 70 65 63 74 65 64 20 34 22 2c 0a 20 20 20 20  xpected 4",.    
5a10: 20 20 20 20 20 20 70 2d 3e 7a 43 6c 61 73 73 4e        p->zClassN
5a20: 61 6d 65 2c 20 70 2d 3e 7a 43 6f 73 74 54 61 62  ame, p->zCostTab
5a30: 2c 20 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e  , sqlite3_column
5a40: 5f 63 6f 75 6e 74 28 70 53 74 6d 74 29 0a 20 20  _count(pStmt).  
5a50: 20 20 20 20 29 3b 0a 20 20 20 20 20 20 72 63 20      );.      rc 
5a60: 3d 20 53 51 4c 49 54 45 5f 45 52 52 4f 52 3b 0a  = SQLITE_ERROR;.
5a70: 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20      }else{.     
5a80: 20 77 68 69 6c 65 28 20 72 63 3d 3d 53 51 4c 49   while( rc==SQLI
5a90: 54 45 5f 4f 4b 20 26 26 20 53 51 4c 49 54 45 5f  TE_OK && SQLITE_
5aa0: 52 4f 57 3d 3d 73 71 6c 69 74 65 33 5f 73 74 65  ROW==sqlite3_ste
5ab0: 70 28 70 53 74 6d 74 29 20 29 7b 0a 20 20 20 20  p(pStmt) ){.    
5ac0: 20 20 20 20 61 6d 61 74 63 68 5f 72 75 6c 65 20      amatch_rule 
5ad0: 2a 70 52 75 6c 65 20 3d 20 30 3b 0a 20 20 20 20  *pRule = 0;.    
5ae0: 20 20 20 20 72 63 20 3d 20 61 6d 61 74 63 68 4c      rc = amatchL
5af0: 6f 61 64 4f 6e 65 52 75 6c 65 28 70 2c 20 70 53  oadOneRule(p, pS
5b00: 74 6d 74 2c 20 26 70 52 75 6c 65 2c 20 70 7a 45  tmt, &pRule, pzE
5b10: 72 72 29 3b 0a 20 20 20 20 20 20 20 20 69 66 28  rr);.        if(
5b20: 20 70 52 75 6c 65 20 29 7b 0a 20 20 20 20 20 20   pRule ){.      
5b30: 20 20 20 20 70 52 75 6c 65 2d 3e 70 4e 65 78 74      pRule->pNext
5b40: 20 3d 20 70 48 65 61 64 3b 0a 20 20 20 20 20 20   = pHead;.      
5b50: 20 20 20 20 70 48 65 61 64 20 3d 20 70 52 75 6c      pHead = pRul
5b60: 65 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20  e;.        }.   
5b70: 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 20 20 72     }.    }.    r
5b80: 63 32 20 3d 20 73 71 6c 69 74 65 33 5f 66 69 6e  c2 = sqlite3_fin
5b90: 61 6c 69 7a 65 28 70 53 74 6d 74 29 3b 0a 20 20  alize(pStmt);.  
5ba0: 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
5bb0: 5f 4f 4b 20 29 20 72 63 20 3d 20 72 63 32 3b 0a  _OK ) rc = rc2;.
5bc0: 20 20 7d 0a 20 20 73 71 6c 69 74 65 33 5f 66 72    }.  sqlite3_fr
5bd0: 65 65 28 7a 53 71 6c 29 3b 0a 0a 20 20 2f 2a 20  ee(zSql);..  /* 
5be0: 41 6c 6c 20 72 75 6c 65 73 20 61 72 65 20 6e 6f  All rules are no
5bf0: 77 20 69 6e 20 61 20 73 69 6e 67 6c 79 20 6c 69  w in a singly li
5c00: 6e 6b 65 64 20 6c 69 73 74 20 73 74 61 72 74 69  nked list starti
5c10: 6e 67 20 61 74 20 70 48 65 61 64 2e 20 54 68 69  ng at pHead. Thi
5c20: 73 0a 20 20 2a 2a 20 62 6c 6f 63 6b 20 73 6f 72  s.  ** block sor
5c30: 74 73 20 74 68 65 6d 20 62 79 20 63 6f 73 74 20  ts them by cost 
5c40: 61 6e 64 20 74 68 65 6e 20 73 65 74 73 20 61 6d  and then sets am
5c50: 61 74 63 68 5f 76 74 61 62 2e 70 52 75 6c 65 20  atch_vtab.pRule 
5c60: 74 6f 20 70 6f 69 6e 74 20 74 6f 20 0a 20 20 2a  to point to .  *
5c70: 2a 20 70 6f 69 6e 74 20 74 6f 20 74 68 65 20 68  * point to the h
5c80: 65 61 64 20 6f 66 20 74 68 65 20 73 6f 72 74 65  ead of the sorte
5c90: 64 20 6c 69 73 74 2e 0a 20 20 2a 2f 0a 20 20 69  d list..  */.  i
5ca0: 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc==SQLITE_OK
5cb0: 20 29 7b 0a 20 20 20 20 75 6e 73 69 67 6e 65 64   ){.    unsigned
5cc0: 20 69 6e 74 20 69 3b 0a 20 20 20 20 61 6d 61 74   int i;.    amat
5cd0: 63 68 5f 72 75 6c 65 20 2a 70 58 3b 0a 20 20 20  ch_rule *pX;.   
5ce0: 20 61 6d 61 74 63 68 5f 72 75 6c 65 20 2a 61 5b   amatch_rule *a[
5cf0: 31 35 5d 3b 0a 20 20 20 20 66 6f 72 28 69 3d 30  15];.    for(i=0
5d00: 3b 20 69 3c 73 69 7a 65 6f 66 28 61 29 2f 73 69  ; i<sizeof(a)/si
5d10: 7a 65 6f 66 28 61 5b 30 5d 29 3b 20 69 2b 2b 29  zeof(a[0]); i++)
5d20: 20 61 5b 69 5d 20 3d 20 30 3b 0a 20 20 20 20 77   a[i] = 0;.    w
5d30: 68 69 6c 65 28 20 28 70 58 20 3d 20 70 48 65 61  hile( (pX = pHea
5d40: 64 29 21 3d 30 20 29 7b 0a 20 20 20 20 20 20 70  d)!=0 ){.      p
5d50: 48 65 61 64 20 3d 20 70 58 2d 3e 70 4e 65 78 74  Head = pX->pNext
5d60: 3b 0a 20 20 20 20 20 20 70 58 2d 3e 70 4e 65 78  ;.      pX->pNex
5d70: 74 20 3d 20 30 3b 0a 20 20 20 20 20 20 66 6f 72  t = 0;.      for
5d80: 28 69 3d 30 3b 20 61 5b 69 5d 20 26 26 20 69 3c  (i=0; a[i] && i<
5d90: 73 69 7a 65 6f 66 28 61 29 2f 73 69 7a 65 6f 66  sizeof(a)/sizeof
5da0: 28 61 5b 30 5d 29 2d 31 3b 20 69 2b 2b 29 7b 0a  (a[0])-1; i++){.
5db0: 20 20 20 20 20 20 20 20 70 58 20 3d 20 61 6d 61          pX = ama
5dc0: 74 63 68 4d 65 72 67 65 52 75 6c 65 73 28 61 5b  tchMergeRules(a[
5dd0: 69 5d 2c 20 70 58 29 3b 0a 20 20 20 20 20 20 20  i], pX);.       
5de0: 20 61 5b 69 5d 20 3d 20 30 3b 0a 20 20 20 20 20   a[i] = 0;.     
5df0: 20 7d 0a 20 20 20 20 20 20 61 5b 69 5d 20 3d 20   }.      a[i] = 
5e00: 61 6d 61 74 63 68 4d 65 72 67 65 52 75 6c 65 73  amatchMergeRules
5e10: 28 61 5b 69 5d 2c 20 70 58 29 3b 0a 20 20 20 20  (a[i], pX);.    
5e20: 7d 0a 20 20 20 20 66 6f 72 28 70 58 3d 61 5b 30  }.    for(pX=a[0
5e30: 5d 2c 20 69 3d 31 3b 20 69 3c 73 69 7a 65 6f 66  ], i=1; i<sizeof
5e40: 28 61 29 2f 73 69 7a 65 6f 66 28 61 5b 30 5d 29  (a)/sizeof(a[0])
5e50: 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20 70 58  ; i++){.      pX
5e60: 20 3d 20 61 6d 61 74 63 68 4d 65 72 67 65 52 75   = amatchMergeRu
5e70: 6c 65 73 28 61 5b 69 5d 2c 20 70 58 29 3b 0a 20  les(a[i], pX);. 
5e80: 20 20 20 7d 0a 20 20 20 20 70 2d 3e 70 52 75 6c     }.    p->pRul
5e90: 65 20 3d 20 61 6d 61 74 63 68 4d 65 72 67 65 52  e = amatchMergeR
5ea0: 75 6c 65 73 28 70 2d 3e 70 52 75 6c 65 2c 20 70  ules(p->pRule, p
5eb0: 58 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20  X);.  }else{.   
5ec0: 20 2f 2a 20 41 6e 20 65 72 72 6f 72 20 68 61 73   /* An error has
5ed0: 20 6f 63 63 75 72 72 65 64 2e 20 53 65 74 74 69   occurred. Setti
5ee0: 6e 67 20 70 2d 3e 70 52 75 6c 65 20 74 6f 20 70  ng p->pRule to p
5ef0: 6f 69 6e 74 20 74 6f 20 74 68 65 20 68 65 61 64  oint to the head
5f00: 20 6f 66 20 74 68 65 0a 20 20 20 20 2a 2a 20 61   of the.    ** a
5f10: 6c 6c 6f 63 61 74 65 64 20 6c 69 73 74 20 65 6e  llocated list en
5f20: 73 75 72 65 73 20 74 68 61 74 20 74 68 65 20 6c  sures that the l
5f30: 69 73 74 20 77 69 6c 6c 20 62 65 20 63 6c 65 61  ist will be clea
5f40: 6e 65 64 20 75 70 20 69 6e 20 74 68 69 73 20 63  ned up in this c
5f50: 61 73 65 2e 0a 20 20 20 20 2a 2f 0a 20 20 20 20  ase..    */.    
5f60: 61 73 73 65 72 74 28 20 70 2d 3e 70 52 75 6c 65  assert( p->pRule
5f70: 3d 3d 30 20 29 3b 0a 20 20 20 20 70 2d 3e 70 52  ==0 );.    p->pR
5f80: 75 6c 65 20 3d 20 70 48 65 61 64 3b 0a 20 20 7d  ule = pHead;.  }
5f90: 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d  ..  return rc;.}
5fa0: 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e  ../*.** This fun
5fb0: 63 74 69 6f 6e 20 63 6f 6e 76 65 72 74 73 20 61  ction converts a
5fc0: 6e 20 53 51 4c 20 71 75 6f 74 65 64 20 73 74 72  n SQL quoted str
5fd0: 69 6e 67 20 69 6e 74 6f 20 61 6e 20 75 6e 71 75  ing into an unqu
5fe0: 6f 74 65 64 20 73 74 72 69 6e 67 0a 2a 2a 20 61  oted string.** a
5ff0: 6e 64 20 72 65 74 75 72 6e 73 20 61 20 70 6f 69  nd returns a poi
6000: 6e 74 65 72 20 74 6f 20 61 20 62 75 66 66 65 72  nter to a buffer
6010: 20 61 6c 6c 6f 63 61 74 65 64 20 75 73 69 6e 67   allocated using
6020: 20 73 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63 28   sqlite3_malloc(
6030: 29 20 0a 2a 2a 20 63 6f 6e 74 61 69 6e 69 6e 67  ) .** containing
6040: 20 74 68 65 20 72 65 73 75 6c 74 2e 20 54 68 65   the result. The
6050: 20 63 61 6c 6c 65 72 20 73 68 6f 75 6c 64 20 65   caller should e
6060: 76 65 6e 74 75 61 6c 6c 79 20 66 72 65 65 20 74  ventually free t
6070: 68 69 73 20 62 75 66 66 65 72 0a 2a 2a 20 75 73  his buffer.** us
6080: 69 6e 67 20 73 71 6c 69 74 65 33 5f 66 72 65 65  ing sqlite3_free
6090: 2e 0a 2a 2a 0a 2a 2a 20 45 78 61 6d 70 6c 65 73  ..**.** Examples
60a0: 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20 22 61 62 63  :.**.**     "abc
60b0: 22 20 20 20 62 65 63 6f 6d 65 73 20 20 20 61 62  "   becomes   ab
60c0: 63 0a 2a 2a 20 20 20 20 20 27 78 79 7a 27 20 20  c.**     'xyz'  
60d0: 20 62 65 63 6f 6d 65 73 20 20 20 78 79 7a 0a 2a   becomes   xyz.*
60e0: 2a 20 20 20 20 20 5b 70 71 72 5d 20 20 20 62 65  *     [pqr]   be
60f0: 63 6f 6d 65 73 20 20 20 70 71 72 0a 2a 2a 20 20  comes   pqr.**  
6100: 20 20 20 60 6d 6e 6f 60 20 20 20 62 65 63 6f 6d     `mno`   becom
6110: 65 73 20 20 20 6d 6e 6f 0a 2a 2f 0a 73 74 61 74  es   mno.*/.stat
6120: 69 63 20 63 68 61 72 20 2a 61 6d 61 74 63 68 44  ic char *amatchD
6130: 65 71 75 6f 74 65 28 63 6f 6e 73 74 20 63 68 61  equote(const cha
6140: 72 20 2a 7a 49 6e 29 7b 0a 20 20 69 6e 74 20 6e  r *zIn){.  int n
6150: 49 6e 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  In;             
6160: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 69             /* Si
6170: 7a 65 20 6f 66 20 69 6e 70 75 74 20 73 74 72 69  ze of input stri
6180: 6e 67 2c 20 69 6e 20 62 79 74 65 73 20 2a 2f 0a  ng, in bytes */.
6190: 20 20 63 68 61 72 20 2a 7a 4f 75 74 3b 20 20 20    char *zOut;   
61a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
61b0: 20 20 2f 2a 20 4f 75 74 70 75 74 20 28 64 65 71    /* Output (deq
61c0: 75 6f 74 65 64 29 20 73 74 72 69 6e 67 20 2a 2f  uoted) string */
61d0: 0a 0a 20 20 6e 49 6e 20 3d 20 28 69 6e 74 29 73  ..  nIn = (int)s
61e0: 74 72 6c 65 6e 28 7a 49 6e 29 3b 0a 20 20 7a 4f  trlen(zIn);.  zO
61f0: 75 74 20 3d 20 73 71 6c 69 74 65 33 5f 6d 61 6c  ut = sqlite3_mal
6200: 6c 6f 63 28 6e 49 6e 2b 31 29 3b 0a 20 20 69 66  loc(nIn+1);.  if
6210: 28 20 7a 4f 75 74 20 29 7b 0a 20 20 20 20 63 68  ( zOut ){.    ch
6220: 61 72 20 71 20 3d 20 7a 49 6e 5b 30 5d 3b 20 20  ar q = zIn[0];  
6230: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 51              /* Q
6240: 75 6f 74 65 20 63 68 61 72 61 63 74 65 72 20 28  uote character (
6250: 69 66 20 61 6e 79 20 29 20 2a 2f 0a 0a 20 20 20  if any ) */..   
6260: 20 69 66 28 20 71 21 3d 27 5b 27 20 26 26 20 71   if( q!='[' && q
6270: 21 3d 20 27 5c 27 27 20 26 26 20 71 21 3d 27 22  != '\'' && q!='"
6280: 27 20 26 26 20 71 21 3d 27 60 27 20 29 7b 0a 20  ' && q!='`' ){. 
6290: 20 20 20 20 20 6d 65 6d 63 70 79 28 7a 4f 75 74       memcpy(zOut
62a0: 2c 20 7a 49 6e 2c 20 6e 49 6e 2b 31 29 3b 0a 20  , zIn, nIn+1);. 
62b0: 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20     }else{.      
62c0: 69 6e 74 20 69 4f 75 74 20 3d 20 30 3b 20 20 20  int iOut = 0;   
62d0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 49              /* I
62e0: 6e 64 65 78 20 6f 66 20 6e 65 78 74 20 62 79 74  ndex of next byt
62f0: 65 20 74 6f 20 77 72 69 74 65 20 74 6f 20 6f 75  e to write to ou
6300: 74 70 75 74 20 2a 2f 0a 20 20 20 20 20 20 69 6e  tput */.      in
6310: 74 20 69 49 6e 3b 20 20 20 20 20 20 20 20 20 20  t iIn;          
6320: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 49 6e 64            /* Ind
6330: 65 78 20 6f 66 20 6e 65 78 74 20 62 79 74 65 20  ex of next byte 
6340: 74 6f 20 72 65 61 64 20 66 72 6f 6d 20 69 6e 70  to read from inp
6350: 75 74 20 2a 2f 0a 0a 20 20 20 20 20 20 69 66 28  ut */..      if(
6360: 20 71 3d 3d 27 5b 27 20 29 20 71 20 3d 20 27 5d   q=='[' ) q = ']
6370: 27 3b 0a 20 20 20 20 20 20 66 6f 72 28 69 49 6e  ';.      for(iIn
6380: 3d 31 3b 20 69 49 6e 3c 6e 49 6e 3b 20 69 49 6e  =1; iIn<nIn; iIn
6390: 2b 2b 29 7b 0a 20 20 20 20 20 20 20 20 69 66 28  ++){.        if(
63a0: 20 7a 49 6e 5b 69 49 6e 5d 3d 3d 71 20 29 20 69   zIn[iIn]==q ) i
63b0: 49 6e 2b 2b 3b 0a 20 20 20 20 20 20 20 20 7a 4f  In++;.        zO
63c0: 75 74 5b 69 4f 75 74 2b 2b 5d 20 3d 20 7a 49 6e  ut[iOut++] = zIn
63d0: 5b 69 49 6e 5d 3b 0a 20 20 20 20 20 20 7d 0a 20  [iIn];.      }. 
63e0: 20 20 20 7d 0a 20 20 20 20 61 73 73 65 72 74 28     }.    assert(
63f0: 20 28 69 6e 74 29 73 74 72 6c 65 6e 28 7a 4f 75   (int)strlen(zOu
6400: 74 29 3c 3d 6e 49 6e 20 29 3b 0a 20 20 7d 0a 20  t)<=nIn );.  }. 
6410: 20 72 65 74 75 72 6e 20 7a 4f 75 74 3b 0a 7d 0a   return zOut;.}.
6420: 0a 2f 2a 0a 2a 2a 20 44 65 61 6c 6c 6f 63 61 74  ./*.** Deallocat
6430: 65 20 74 68 65 20 70 56 43 68 65 63 6b 20 70 72  e the pVCheck pr
6440: 65 70 61 72 65 64 20 73 74 61 74 65 6d 65 6e 74  epared statement
6450: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64  ..*/.static void
6460: 20 61 6d 61 74 63 68 56 43 68 65 63 6b 43 6c 65   amatchVCheckCle
6470: 61 72 28 61 6d 61 74 63 68 5f 76 74 61 62 20 2a  ar(amatch_vtab *
6480: 70 29 7b 0a 20 20 69 66 28 20 70 2d 3e 70 56 43  p){.  if( p->pVC
6490: 68 65 63 6b 20 29 7b 0a 20 20 20 20 73 71 6c 69  heck ){.    sqli
64a0: 74 65 33 5f 66 69 6e 61 6c 69 7a 65 28 70 2d 3e  te3_finalize(p->
64b0: 70 56 43 68 65 63 6b 29 3b 0a 20 20 20 20 70 2d  pVCheck);.    p-
64c0: 3e 70 56 43 68 65 63 6b 20 3d 20 30 3b 0a 20 20  >pVCheck = 0;.  
64d0: 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 44 65 61 6c 6c  }.}../*.** Deall
64e0: 6f 63 61 74 65 20 61 6e 20 61 6d 61 74 63 68 5f  ocate an amatch_
64f0: 76 74 61 62 20 6f 62 6a 65 63 74 0a 2a 2f 0a 73  vtab object.*/.s
6500: 74 61 74 69 63 20 76 6f 69 64 20 61 6d 61 74 63  tatic void amatc
6510: 68 46 72 65 65 28 61 6d 61 74 63 68 5f 76 74 61  hFree(amatch_vta
6520: 62 20 2a 70 29 7b 0a 20 20 69 66 28 20 70 20 29  b *p){.  if( p )
6530: 7b 0a 20 20 20 20 61 6d 61 74 63 68 46 72 65 65  {.    amatchFree
6540: 52 75 6c 65 73 28 70 29 3b 0a 20 20 20 20 61 6d  Rules(p);.    am
6550: 61 74 63 68 56 43 68 65 63 6b 43 6c 65 61 72 28  atchVCheckClear(
6560: 70 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f  p);.    sqlite3_
6570: 66 72 65 65 28 70 2d 3e 7a 43 6c 61 73 73 4e 61  free(p->zClassNa
6580: 6d 65 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33  me);.    sqlite3
6590: 5f 66 72 65 65 28 70 2d 3e 7a 44 62 29 3b 0a 20  _free(p->zDb);. 
65a0: 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28     sqlite3_free(
65b0: 70 2d 3e 7a 43 6f 73 74 54 61 62 29 3b 0a 20 20  p->zCostTab);.  
65c0: 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70    sqlite3_free(p
65d0: 2d 3e 7a 56 6f 63 61 62 54 61 62 29 3b 0a 20 20  ->zVocabTab);.  
65e0: 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70    sqlite3_free(p
65f0: 2d 3e 7a 56 6f 63 61 62 57 6f 72 64 29 3b 0a 20  ->zVocabWord);. 
6600: 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28     sqlite3_free(
6610: 70 2d 3e 7a 56 6f 63 61 62 4c 61 6e 67 29 3b 0a  p->zVocabLang);.
6620: 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65      sqlite3_free
6630: 28 70 2d 3e 7a 53 65 6c 66 29 3b 0a 20 20 20 20  (p->zSelf);.    
6640: 6d 65 6d 73 65 74 28 70 2c 20 30 2c 20 73 69 7a  memset(p, 0, siz
6650: 65 6f 66 28 2a 70 29 29 3b 0a 20 20 20 20 73 71  eof(*p));.    sq
6660: 6c 69 74 65 33 5f 66 72 65 65 28 70 29 3b 0a 20  lite3_free(p);. 
6670: 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 78 44 69 73   }.}../*.** xDis
6680: 63 6f 6e 6e 65 63 74 2f 78 44 65 73 74 72 6f 79  connect/xDestroy
6690: 20 6d 65 74 68 6f 64 20 66 6f 72 20 74 68 65 20   method for the 
66a0: 61 6d 61 74 63 68 20 6d 6f 64 75 6c 65 2e 0a 2a  amatch module..*
66b0: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 61 6d 61  /.static int ama
66c0: 74 63 68 44 69 73 63 6f 6e 6e 65 63 74 28 73 71  tchDisconnect(sq
66d0: 6c 69 74 65 33 5f 76 74 61 62 20 2a 70 56 74 61  lite3_vtab *pVta
66e0: 62 29 7b 0a 20 20 61 6d 61 74 63 68 5f 76 74 61  b){.  amatch_vta
66f0: 62 20 2a 70 20 3d 20 28 61 6d 61 74 63 68 5f 76  b *p = (amatch_v
6700: 74 61 62 2a 29 70 56 74 61 62 3b 0a 20 20 61 73  tab*)pVtab;.  as
6710: 73 65 72 74 28 20 70 2d 3e 6e 43 75 72 73 6f 72  sert( p->nCursor
6720: 3d 3d 30 20 29 3b 0a 20 20 61 6d 61 74 63 68 46  ==0 );.  amatchF
6730: 72 65 65 28 70 29 3b 0a 20 20 72 65 74 75 72 6e  ree(p);.  return
6740: 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f   SQLITE_OK;.}../
6750: 2a 0a 2a 2a 20 43 68 65 63 6b 20 74 6f 20 73 65  *.** Check to se
6760: 65 20 69 66 20 74 68 65 20 61 72 67 75 6d 65 6e  e if the argumen
6770: 74 20 69 73 20 6f 66 20 74 68 65 20 66 6f 72 6d  t is of the form
6780: 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20 20 20 4b 45  :.**.**       KE
6790: 59 20 3d 20 56 41 4c 55 45 0a 2a 2a 0a 2a 2a 20  Y = VALUE.**.** 
67a0: 49 66 20 69 74 20 69 73 2c 20 72 65 74 75 72 6e  If it is, return
67b0: 20 61 20 70 6f 69 6e 74 65 72 20 74 6f 20 74 68   a pointer to th
67c0: 65 20 66 69 72 73 74 20 63 68 61 72 61 63 74 65  e first characte
67d0: 72 20 6f 66 20 56 41 4c 55 45 2e 0a 2a 2a 20 49  r of VALUE..** I
67e0: 66 20 6e 6f 74 2c 20 72 65 74 75 72 6e 20 4e 55  f not, return NU
67f0: 4c 4c 2e 20 20 53 70 61 63 65 73 20 61 72 6f 75  LL.  Spaces arou
6800: 6e 64 20 74 68 65 20 3d 20 61 72 65 20 69 67 6e  nd the = are ign
6810: 6f 72 65 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  ored..*/.static 
6820: 63 6f 6e 73 74 20 63 68 61 72 20 2a 61 6d 61 74  const char *amat
6830: 63 68 56 61 6c 75 65 4f 66 4b 65 79 28 63 6f 6e  chValueOfKey(con
6840: 73 74 20 63 68 61 72 20 2a 7a 4b 65 79 2c 20 63  st char *zKey, c
6850: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 53 74 72 29  onst char *zStr)
6860: 7b 0a 20 20 69 6e 74 20 6e 4b 65 79 20 3d 20 28  {.  int nKey = (
6870: 69 6e 74 29 73 74 72 6c 65 6e 28 7a 4b 65 79 29  int)strlen(zKey)
6880: 3b 0a 20 20 69 6e 74 20 6e 53 74 72 20 3d 20 28  ;.  int nStr = (
6890: 69 6e 74 29 73 74 72 6c 65 6e 28 7a 53 74 72 29  int)strlen(zStr)
68a0: 3b 0a 20 20 69 6e 74 20 69 3b 0a 20 20 69 66 28  ;.  int i;.  if(
68b0: 20 6e 53 74 72 3c 6e 4b 65 79 2b 31 20 29 20 72   nStr<nKey+1 ) r
68c0: 65 74 75 72 6e 20 30 3b 0a 20 20 69 66 28 20 6d  eturn 0;.  if( m
68d0: 65 6d 63 6d 70 28 7a 53 74 72 2c 20 7a 4b 65 79  emcmp(zStr, zKey
68e0: 2c 20 6e 4b 65 79 29 21 3d 30 20 29 20 72 65 74  , nKey)!=0 ) ret
68f0: 75 72 6e 20 30 3b 0a 20 20 66 6f 72 28 69 3d 6e  urn 0;.  for(i=n
6900: 4b 65 79 3b 20 69 73 73 70 61 63 65 28 28 75 6e  Key; isspace((un
6910: 73 69 67 6e 65 64 20 63 68 61 72 29 7a 53 74 72  signed char)zStr
6920: 5b 69 5d 29 3b 20 69 2b 2b 29 7b 7d 0a 20 20 69  [i]); i++){}.  i
6930: 66 28 20 7a 53 74 72 5b 69 5d 21 3d 27 3d 27 20  f( zStr[i]!='=' 
6940: 29 20 72 65 74 75 72 6e 20 30 3b 0a 20 20 69 2b  ) return 0;.  i+
6950: 2b 3b 0a 20 20 77 68 69 6c 65 28 20 69 73 73 70  +;.  while( issp
6960: 61 63 65 28 28 75 6e 73 69 67 6e 65 64 20 63 68  ace((unsigned ch
6970: 61 72 29 7a 53 74 72 5b 69 5d 29 20 29 7b 20 69  ar)zStr[i]) ){ i
6980: 2b 2b 3b 20 7d 0a 20 20 72 65 74 75 72 6e 20 7a  ++; }.  return z
6990: 53 74 72 2b 69 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  Str+i;.}../*.** 
69a0: 78 43 6f 6e 6e 65 63 74 2f 78 43 72 65 61 74 65  xConnect/xCreate
69b0: 20 6d 65 74 68 6f 64 20 66 6f 72 20 74 68 65 20   method for the 
69c0: 61 6d 61 74 63 68 20 6d 6f 64 75 6c 65 2e 20 41  amatch module. A
69d0: 72 67 75 6d 65 6e 74 73 20 61 72 65 3a 0a 2a 2a  rguments are:.**
69e0: 0a 2a 2a 20 20 20 61 72 67 76 5b 30 5d 20 20 20  .**   argv[0]   
69f0: 20 2d 3e 20 6d 6f 64 75 6c 65 20 6e 61 6d 65 20   -> module name 
6a00: 20 28 22 61 70 70 72 6f 78 69 6d 61 74 65 5f 6d   ("approximate_m
6a10: 61 74 63 68 22 29 0a 2a 2a 20 20 20 61 72 67 76  atch").**   argv
6a20: 5b 31 5d 20 20 20 20 2d 3e 20 64 61 74 61 62 61  [1]    -> databa
6a30: 73 65 20 6e 61 6d 65 0a 2a 2a 20 20 20 61 72 67  se name.**   arg
6a40: 76 5b 32 5d 20 20 20 20 2d 3e 20 74 61 62 6c 65  v[2]    -> table
6a50: 20 6e 61 6d 65 0a 2a 2a 20 20 20 61 72 67 76 5b   name.**   argv[
6a60: 33 2e 2e 2e 5d 20 2d 3e 20 61 72 67 75 6d 65 6e  3...] -> argumen
6a70: 74 73 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  ts.*/.static int
6a80: 20 61 6d 61 74 63 68 43 6f 6e 6e 65 63 74 28 0a   amatchConnect(.
6a90: 20 20 73 71 6c 69 74 65 33 20 2a 64 62 2c 0a 20    sqlite3 *db,. 
6aa0: 20 76 6f 69 64 20 2a 70 41 75 78 2c 0a 20 20 69   void *pAux,.  i
6ab0: 6e 74 20 61 72 67 63 2c 20 63 6f 6e 73 74 20 63  nt argc, const c
6ac0: 68 61 72 20 2a 63 6f 6e 73 74 2a 61 72 67 76 2c  har *const*argv,
6ad0: 0a 20 20 73 71 6c 69 74 65 33 5f 76 74 61 62 20  .  sqlite3_vtab 
6ae0: 2a 2a 70 70 56 74 61 62 2c 0a 20 20 63 68 61 72  **ppVtab,.  char
6af0: 20 2a 2a 70 7a 45 72 72 0a 29 7b 0a 20 20 69 6e   **pzErr.){.  in
6b00: 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b  t rc = SQLITE_OK
6b10: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a  ;             /*
6b20: 20 52 65 74 75 72 6e 20 63 6f 64 65 20 2a 2f 0a   Return code */.
6b30: 20 20 61 6d 61 74 63 68 5f 76 74 61 62 20 2a 70    amatch_vtab *p
6b40: 4e 65 77 20 3d 20 30 3b 20 20 20 20 20 20 20 20  New = 0;        
6b50: 20 20 2f 2a 20 4e 65 77 20 76 69 72 74 75 61 6c    /* New virtual
6b60: 20 74 61 62 6c 65 20 2a 2f 0a 20 20 63 6f 6e 73   table */.  cons
6b70: 74 20 63 68 61 72 20 2a 7a 4d 6f 64 75 6c 65 20  t char *zModule 
6b80: 3d 20 61 72 67 76 5b 30 5d 3b 0a 20 20 63 6f 6e  = argv[0];.  con
6b90: 73 74 20 63 68 61 72 20 2a 7a 44 62 20 3d 20 61  st char *zDb = a
6ba0: 72 67 76 5b 31 5d 3b 0a 20 20 63 6f 6e 73 74 20  rgv[1];.  const 
6bb0: 63 68 61 72 20 2a 7a 56 61 6c 3b 0a 20 20 69 6e  char *zVal;.  in
6bc0: 74 20 69 3b 0a 0a 20 20 28 76 6f 69 64 29 70 41  t i;..  (void)pA
6bd0: 75 78 3b 0a 20 20 2a 70 70 56 74 61 62 20 3d 20  ux;.  *ppVtab = 
6be0: 30 3b 0a 20 20 70 4e 65 77 20 3d 20 73 71 6c 69  0;.  pNew = sqli
6bf0: 74 65 33 5f 6d 61 6c 6c 6f 63 28 20 73 69 7a 65  te3_malloc( size
6c00: 6f 66 28 2a 70 4e 65 77 29 20 29 3b 0a 20 20 69  of(*pNew) );.  i
6c10: 66 28 20 70 4e 65 77 3d 3d 30 20 29 20 72 65 74  f( pNew==0 ) ret
6c20: 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d  urn SQLITE_NOMEM
6c30: 3b 0a 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f  ;.  rc = SQLITE_
6c40: 4e 4f 4d 45 4d 3b 0a 20 20 6d 65 6d 73 65 74 28  NOMEM;.  memset(
6c50: 70 4e 65 77 2c 20 30 2c 20 73 69 7a 65 6f 66 28  pNew, 0, sizeof(
6c60: 2a 70 4e 65 77 29 29 3b 0a 20 20 70 4e 65 77 2d  *pNew));.  pNew-
6c70: 3e 64 62 20 3d 20 64 62 3b 0a 20 20 70 4e 65 77  >db = db;.  pNew
6c80: 2d 3e 7a 43 6c 61 73 73 4e 61 6d 65 20 3d 20 73  ->zClassName = s
6c90: 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 22  qlite3_mprintf("
6ca0: 25 73 22 2c 20 7a 4d 6f 64 75 6c 65 29 3b 0a 20  %s", zModule);. 
6cb0: 20 69 66 28 20 70 4e 65 77 2d 3e 7a 43 6c 61 73   if( pNew->zClas
6cc0: 73 4e 61 6d 65 3d 3d 30 20 29 20 67 6f 74 6f 20  sName==0 ) goto 
6cd0: 61 6d 61 74 63 68 43 6f 6e 6e 65 63 74 45 72 72  amatchConnectErr
6ce0: 6f 72 3b 0a 20 20 70 4e 65 77 2d 3e 7a 44 62 20  or;.  pNew->zDb 
6cf0: 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74  = sqlite3_mprint
6d00: 66 28 22 25 73 22 2c 20 7a 44 62 29 3b 0a 20 20  f("%s", zDb);.  
6d10: 69 66 28 20 70 4e 65 77 2d 3e 7a 44 62 3d 3d 30  if( pNew->zDb==0
6d20: 20 29 20 67 6f 74 6f 20 61 6d 61 74 63 68 43 6f   ) goto amatchCo
6d30: 6e 6e 65 63 74 45 72 72 6f 72 3b 0a 20 20 70 4e  nnectError;.  pN
6d40: 65 77 2d 3e 7a 53 65 6c 66 20 3d 20 73 71 6c 69  ew->zSelf = sqli
6d50: 74 65 33 5f 6d 70 72 69 6e 74 66 28 22 25 73 22  te3_mprintf("%s"
6d60: 2c 20 61 72 67 76 5b 32 5d 29 3b 0a 20 20 69 66  , argv[2]);.  if
6d70: 28 20 70 4e 65 77 2d 3e 7a 53 65 6c 66 3d 3d 30  ( pNew->zSelf==0
6d80: 20 29 20 67 6f 74 6f 20 61 6d 61 74 63 68 43 6f   ) goto amatchCo
6d90: 6e 6e 65 63 74 45 72 72 6f 72 3b 0a 20 20 66 6f  nnectError;.  fo
6da0: 72 28 69 3d 33 3b 20 69 3c 61 72 67 63 3b 20 69  r(i=3; i<argc; i
6db0: 2b 2b 29 7b 0a 20 20 20 20 7a 56 61 6c 20 3d 20  ++){.    zVal = 
6dc0: 61 6d 61 74 63 68 56 61 6c 75 65 4f 66 4b 65 79  amatchValueOfKey
6dd0: 28 22 76 6f 63 61 62 75 6c 61 72 79 5f 74 61 62  ("vocabulary_tab
6de0: 6c 65 22 2c 20 61 72 67 76 5b 69 5d 29 3b 0a 20  le", argv[i]);. 
6df0: 20 20 20 69 66 28 20 7a 56 61 6c 20 29 7b 0a 20     if( zVal ){. 
6e00: 20 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65       sqlite3_fre
6e10: 65 28 70 4e 65 77 2d 3e 7a 56 6f 63 61 62 54 61  e(pNew->zVocabTa
6e20: 62 29 3b 0a 20 20 20 20 20 20 70 4e 65 77 2d 3e  b);.      pNew->
6e30: 7a 56 6f 63 61 62 54 61 62 20 3d 20 61 6d 61 74  zVocabTab = amat
6e40: 63 68 44 65 71 75 6f 74 65 28 7a 56 61 6c 29 3b  chDequote(zVal);
6e50: 0a 20 20 20 20 20 20 69 66 28 20 70 4e 65 77 2d  .      if( pNew-
6e60: 3e 7a 56 6f 63 61 62 54 61 62 3d 3d 30 20 29 20  >zVocabTab==0 ) 
6e70: 67 6f 74 6f 20 61 6d 61 74 63 68 43 6f 6e 6e 65  goto amatchConne
6e80: 63 74 45 72 72 6f 72 3b 0a 20 20 20 20 20 20 63  ctError;.      c
6e90: 6f 6e 74 69 6e 75 65 3b 0a 20 20 20 20 7d 0a 20  ontinue;.    }. 
6ea0: 20 20 20 7a 56 61 6c 20 3d 20 61 6d 61 74 63 68     zVal = amatch
6eb0: 56 61 6c 75 65 4f 66 4b 65 79 28 22 76 6f 63 61  ValueOfKey("voca
6ec0: 62 75 6c 61 72 79 5f 77 6f 72 64 22 2c 20 61 72  bulary_word", ar
6ed0: 67 76 5b 69 5d 29 3b 0a 20 20 20 20 69 66 28 20  gv[i]);.    if( 
6ee0: 7a 56 61 6c 20 29 7b 0a 20 20 20 20 20 20 73 71  zVal ){.      sq
6ef0: 6c 69 74 65 33 5f 66 72 65 65 28 70 4e 65 77 2d  lite3_free(pNew-
6f00: 3e 7a 56 6f 63 61 62 57 6f 72 64 29 3b 0a 20 20  >zVocabWord);.  
6f10: 20 20 20 20 70 4e 65 77 2d 3e 7a 56 6f 63 61 62      pNew->zVocab
6f20: 57 6f 72 64 20 3d 20 61 6d 61 74 63 68 44 65 71  Word = amatchDeq
6f30: 75 6f 74 65 28 7a 56 61 6c 29 3b 0a 20 20 20 20  uote(zVal);.    
6f40: 20 20 69 66 28 20 70 4e 65 77 2d 3e 7a 56 6f 63    if( pNew->zVoc
6f50: 61 62 57 6f 72 64 3d 3d 30 20 29 20 67 6f 74 6f  abWord==0 ) goto
6f60: 20 61 6d 61 74 63 68 43 6f 6e 6e 65 63 74 45 72   amatchConnectEr
6f70: 72 6f 72 3b 0a 20 20 20 20 20 20 63 6f 6e 74 69  ror;.      conti
6f80: 6e 75 65 3b 0a 20 20 20 20 7d 0a 20 20 20 20 7a  nue;.    }.    z
6f90: 56 61 6c 20 3d 20 61 6d 61 74 63 68 56 61 6c 75  Val = amatchValu
6fa0: 65 4f 66 4b 65 79 28 22 76 6f 63 61 62 75 6c 61  eOfKey("vocabula
6fb0: 72 79 5f 6c 61 6e 67 75 61 67 65 22 2c 20 61 72  ry_language", ar
6fc0: 67 76 5b 69 5d 29 3b 0a 20 20 20 20 69 66 28 20  gv[i]);.    if( 
6fd0: 7a 56 61 6c 20 29 7b 0a 20 20 20 20 20 20 73 71  zVal ){.      sq
6fe0: 6c 69 74 65 33 5f 66 72 65 65 28 70 4e 65 77 2d  lite3_free(pNew-
6ff0: 3e 7a 56 6f 63 61 62 4c 61 6e 67 29 3b 0a 20 20  >zVocabLang);.  
7000: 20 20 20 20 70 4e 65 77 2d 3e 7a 56 6f 63 61 62      pNew->zVocab
7010: 4c 61 6e 67 20 3d 20 61 6d 61 74 63 68 44 65 71  Lang = amatchDeq
7020: 75 6f 74 65 28 7a 56 61 6c 29 3b 0a 20 20 20 20  uote(zVal);.    
7030: 20 20 69 66 28 20 70 4e 65 77 2d 3e 7a 56 6f 63    if( pNew->zVoc
7040: 61 62 4c 61 6e 67 3d 3d 30 20 29 20 67 6f 74 6f  abLang==0 ) goto
7050: 20 61 6d 61 74 63 68 43 6f 6e 6e 65 63 74 45 72   amatchConnectEr
7060: 72 6f 72 3b 0a 20 20 20 20 20 20 63 6f 6e 74 69  ror;.      conti
7070: 6e 75 65 3b 0a 20 20 20 20 7d 0a 20 20 20 20 7a  nue;.    }.    z
7080: 56 61 6c 20 3d 20 61 6d 61 74 63 68 56 61 6c 75  Val = amatchValu
7090: 65 4f 66 4b 65 79 28 22 65 64 69 74 5f 64 69 73  eOfKey("edit_dis
70a0: 74 61 6e 63 65 73 22 2c 20 61 72 67 76 5b 69 5d  tances", argv[i]
70b0: 29 3b 0a 20 20 20 20 69 66 28 20 7a 56 61 6c 20  );.    if( zVal 
70c0: 29 7b 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33  ){.      sqlite3
70d0: 5f 66 72 65 65 28 70 4e 65 77 2d 3e 7a 43 6f 73  _free(pNew->zCos
70e0: 74 54 61 62 29 3b 0a 20 20 20 20 20 20 70 4e 65  tTab);.      pNe
70f0: 77 2d 3e 7a 43 6f 73 74 54 61 62 20 3d 20 61 6d  w->zCostTab = am
7100: 61 74 63 68 44 65 71 75 6f 74 65 28 7a 56 61 6c  atchDequote(zVal
7110: 29 3b 0a 20 20 20 20 20 20 69 66 28 20 70 4e 65  );.      if( pNe
7120: 77 2d 3e 7a 43 6f 73 74 54 61 62 3d 3d 30 20 29  w->zCostTab==0 )
7130: 20 67 6f 74 6f 20 61 6d 61 74 63 68 43 6f 6e 6e   goto amatchConn
7140: 65 63 74 45 72 72 6f 72 3b 0a 20 20 20 20 20 20  ectError;.      
7150: 63 6f 6e 74 69 6e 75 65 3b 0a 20 20 20 20 7d 0a  continue;.    }.
7160: 20 20 20 20 2a 70 7a 45 72 72 20 3d 20 73 71 6c      *pzErr = sql
7170: 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 22 75 6e  ite3_mprintf("un
7180: 72 65 63 6f 67 6e 69 7a 65 64 20 61 72 67 75 6d  recognized argum
7190: 65 6e 74 3a 20 5b 25 73 5d 5c 6e 22 2c 20 61 72  ent: [%s]\n", ar
71a0: 67 76 5b 69 5d 29 3b 0a 20 20 20 20 61 6d 61 74  gv[i]);.    amat
71b0: 63 68 46 72 65 65 28 70 4e 65 77 29 3b 0a 20 20  chFree(pNew);.  
71c0: 20 20 2a 70 70 56 74 61 62 20 3d 20 30 3b 0a 20    *ppVtab = 0;. 
71d0: 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45     return SQLITE
71e0: 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a 20 20 72 63  _ERROR;.  }.  rc
71f0: 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20   = SQLITE_OK;.  
7200: 69 66 28 20 70 4e 65 77 2d 3e 7a 43 6f 73 74 54  if( pNew->zCostT
7210: 61 62 3d 3d 30 20 29 7b 0a 20 20 20 20 2a 70 7a  ab==0 ){.    *pz
7220: 45 72 72 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70  Err = sqlite3_mp
7230: 72 69 6e 74 66 28 22 6e 6f 20 65 64 69 74 5f 64  rintf("no edit_d
7240: 69 73 74 61 6e 63 65 73 20 74 61 62 6c 65 20 73  istances table s
7250: 70 65 63 69 66 69 65 64 22 29 3b 0a 20 20 20 20  pecified");.    
7260: 72 63 20 3d 20 53 51 4c 49 54 45 5f 45 52 52 4f  rc = SQLITE_ERRO
7270: 52 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  R;.  }else{.    
7280: 72 63 20 3d 20 61 6d 61 74 63 68 4c 6f 61 64 52  rc = amatchLoadR
7290: 75 6c 65 73 28 64 62 2c 20 70 4e 65 77 2c 20 70  ules(db, pNew, p
72a0: 7a 45 72 72 29 3b 0a 20 20 7d 0a 20 20 69 66 28  zErr);.  }.  if(
72b0: 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc==SQLITE_OK )
72c0: 7b 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74  {.    rc = sqlit
72d0: 65 33 5f 64 65 63 6c 61 72 65 5f 76 74 61 62 28  e3_declare_vtab(
72e0: 64 62 2c 0a 20 20 20 20 20 20 20 20 20 20 20 22  db,.           "
72f0: 43 52 45 41 54 45 20 54 41 42 4c 45 20 78 28 77  CREATE TABLE x(w
7300: 6f 72 64 2c 64 69 73 74 61 6e 63 65 2c 6c 61 6e  ord,distance,lan
7310: 67 75 61 67 65 2c 22 0a 20 20 20 20 20 20 20 20  guage,".        
7320: 20 20 20 22 63 6f 6d 6d 61 6e 64 20 48 49 44 44     "command HIDD
7330: 45 4e 2c 6e 77 6f 72 64 20 48 49 44 44 45 4e 29  EN,nword HIDDEN)
7340: 22 0a 20 20 20 20 20 20 20 20 20 29 3b 0a 23 64  ".         );.#d
7350: 65 66 69 6e 65 20 41 4d 41 54 43 48 5f 43 4f 4c  efine AMATCH_COL
7360: 5f 57 4f 52 44 20 20 20 20 20 20 20 30 0a 23 64  _WORD       0.#d
7370: 65 66 69 6e 65 20 41 4d 41 54 43 48 5f 43 4f 4c  efine AMATCH_COL
7380: 5f 44 49 53 54 41 4e 43 45 20 20 20 31 0a 23 64  _DISTANCE   1.#d
7390: 65 66 69 6e 65 20 41 4d 41 54 43 48 5f 43 4f 4c  efine AMATCH_COL
73a0: 5f 4c 41 4e 47 55 41 47 45 20 20 20 32 0a 23 64  _LANGUAGE   2.#d
73b0: 65 66 69 6e 65 20 41 4d 41 54 43 48 5f 43 4f 4c  efine AMATCH_COL
73c0: 5f 43 4f 4d 4d 41 4e 44 20 20 20 20 33 0a 23 64  _COMMAND    3.#d
73d0: 65 66 69 6e 65 20 41 4d 41 54 43 48 5f 43 4f 4c  efine AMATCH_COL
73e0: 5f 4e 57 4f 52 44 20 20 20 20 20 20 34 0a 20 20  _NWORD      4.  
73f0: 7d 0a 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49  }.  if( rc!=SQLI
7400: 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 61 6d 61  TE_OK ){.    ama
7410: 74 63 68 46 72 65 65 28 70 4e 65 77 29 3b 0a 20  tchFree(pNew);. 
7420: 20 7d 0a 20 20 2a 70 70 56 74 61 62 20 3d 20 26   }.  *ppVtab = &
7430: 70 4e 65 77 2d 3e 62 61 73 65 3b 0a 20 20 72 65  pNew->base;.  re
7440: 74 75 72 6e 20 72 63 3b 0a 0a 61 6d 61 74 63 68  turn rc;..amatch
7450: 43 6f 6e 6e 65 63 74 45 72 72 6f 72 3a 0a 20 20  ConnectError:.  
7460: 61 6d 61 74 63 68 46 72 65 65 28 70 4e 65 77 29  amatchFree(pNew)
7470: 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d  ;.  return rc;.}
7480: 0a 0a 2f 2a 0a 2a 2a 20 4f 70 65 6e 20 61 20 6e  ../*.** Open a n
7490: 65 77 20 61 6d 61 74 63 68 20 63 75 72 73 6f 72  ew amatch cursor
74a0: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
74b0: 61 6d 61 74 63 68 4f 70 65 6e 28 73 71 6c 69 74  amatchOpen(sqlit
74c0: 65 33 5f 76 74 61 62 20 2a 70 56 54 61 62 2c 20  e3_vtab *pVTab, 
74d0: 73 71 6c 69 74 65 33 5f 76 74 61 62 5f 63 75 72  sqlite3_vtab_cur
74e0: 73 6f 72 20 2a 2a 70 70 43 75 72 73 6f 72 29 7b  sor **ppCursor){
74f0: 0a 20 20 61 6d 61 74 63 68 5f 76 74 61 62 20 2a  .  amatch_vtab *
7500: 70 20 3d 20 28 61 6d 61 74 63 68 5f 76 74 61 62  p = (amatch_vtab
7510: 2a 29 70 56 54 61 62 3b 0a 20 20 61 6d 61 74 63  *)pVTab;.  amatc
7520: 68 5f 63 75 72 73 6f 72 20 2a 70 43 75 72 3b 0a  h_cursor *pCur;.
7530: 20 20 70 43 75 72 20 3d 20 73 71 6c 69 74 65 33    pCur = sqlite3
7540: 5f 6d 61 6c 6c 6f 63 28 20 73 69 7a 65 6f 66 28  _malloc( sizeof(
7550: 2a 70 43 75 72 29 20 29 3b 0a 20 20 69 66 28 20  *pCur) );.  if( 
7560: 70 43 75 72 3d 3d 30 20 29 20 72 65 74 75 72 6e  pCur==0 ) return
7570: 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20   SQLITE_NOMEM;. 
7580: 20 6d 65 6d 73 65 74 28 70 43 75 72 2c 20 30 2c   memset(pCur, 0,
7590: 20 73 69 7a 65 6f 66 28 2a 70 43 75 72 29 29 3b   sizeof(*pCur));
75a0: 0a 20 20 70 43 75 72 2d 3e 70 56 74 61 62 20 3d  .  pCur->pVtab =
75b0: 20 70 3b 0a 20 20 2a 70 70 43 75 72 73 6f 72 20   p;.  *ppCursor 
75c0: 3d 20 26 70 43 75 72 2d 3e 62 61 73 65 3b 0a 20  = &pCur->base;. 
75d0: 20 70 2d 3e 6e 43 75 72 73 6f 72 2b 2b 3b 0a 20   p->nCursor++;. 
75e0: 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f   return SQLITE_O
75f0: 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 46 72 65 65  K;.}../*.** Free
7600: 20 75 70 20 61 6c 6c 20 74 68 65 20 6d 65 6d 6f   up all the memo
7610: 72 79 20 61 6c 6c 6f 63 61 74 65 64 20 62 79 20  ry allocated by 
7620: 61 20 63 75 72 73 6f 72 2e 20 20 53 65 74 20 69  a cursor.  Set i
7630: 74 20 72 4c 69 6d 69 74 20 74 6f 20 30 0a 2a 2a  t rLimit to 0.**
7640: 20 74 6f 20 69 6e 64 69 63 61 74 65 20 74 68 61   to indicate tha
7650: 74 20 69 74 20 69 73 20 61 74 20 45 4f 46 2e 0a  t it is at EOF..
7660: 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 61  */.static void a
7670: 6d 61 74 63 68 43 6c 65 61 72 43 75 72 73 6f 72  matchClearCursor
7680: 28 61 6d 61 74 63 68 5f 63 75 72 73 6f 72 20 2a  (amatch_cursor *
7690: 70 43 75 72 29 7b 0a 20 20 61 6d 61 74 63 68 5f  pCur){.  amatch_
76a0: 77 6f 72 64 20 2a 70 57 6f 72 64 2c 20 2a 70 4e  word *pWord, *pN
76b0: 65 78 74 57 6f 72 64 3b 0a 20 20 66 6f 72 28 70  extWord;.  for(p
76c0: 57 6f 72 64 3d 70 43 75 72 2d 3e 70 41 6c 6c 57  Word=pCur->pAllW
76d0: 6f 72 64 73 3b 20 70 57 6f 72 64 3b 20 70 57 6f  ords; pWord; pWo
76e0: 72 64 3d 70 4e 65 78 74 57 6f 72 64 29 7b 0a 20  rd=pNextWord){. 
76f0: 20 20 20 70 4e 65 78 74 57 6f 72 64 20 3d 20 70     pNextWord = p
7700: 57 6f 72 64 2d 3e 70 4e 65 78 74 3b 0a 20 20 20  Word->pNext;.   
7710: 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70 57   sqlite3_free(pW
7720: 6f 72 64 29 3b 0a 20 20 7d 0a 20 20 70 43 75 72  ord);.  }.  pCur
7730: 2d 3e 70 41 6c 6c 57 6f 72 64 73 20 3d 20 30 3b  ->pAllWords = 0;
7740: 0a 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28  .  sqlite3_free(
7750: 70 43 75 72 2d 3e 7a 49 6e 70 75 74 29 3b 0a 20  pCur->zInput);. 
7760: 20 70 43 75 72 2d 3e 7a 49 6e 70 75 74 20 3d 20   pCur->zInput = 
7770: 30 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66 72 65  0;.  sqlite3_fre
7780: 65 28 70 43 75 72 2d 3e 7a 42 75 66 29 3b 0a 20  e(pCur->zBuf);. 
7790: 20 70 43 75 72 2d 3e 7a 42 75 66 20 3d 20 30 3b   pCur->zBuf = 0;
77a0: 0a 20 20 70 43 75 72 2d 3e 6e 42 75 66 20 3d 20  .  pCur->nBuf = 
77b0: 30 3b 0a 20 20 70 43 75 72 2d 3e 70 43 6f 73 74  0;.  pCur->pCost
77c0: 20 3d 20 30 3b 0a 20 20 70 43 75 72 2d 3e 70 57   = 0;.  pCur->pW
77d0: 6f 72 64 20 3d 20 30 3b 0a 20 20 70 43 75 72 2d  ord = 0;.  pCur-
77e0: 3e 70 43 75 72 72 65 6e 74 20 3d 20 30 3b 0a 20  >pCurrent = 0;. 
77f0: 20 70 43 75 72 2d 3e 72 4c 69 6d 69 74 20 3d 20   pCur->rLimit = 
7800: 31 30 30 30 30 30 30 3b 0a 20 20 70 43 75 72 2d  1000000;.  pCur-
7810: 3e 69 4c 61 6e 67 20 3d 20 30 3b 0a 20 20 70 43  >iLang = 0;.  pC
7820: 75 72 2d 3e 6e 57 6f 72 64 20 3d 20 30 3b 0a 7d  ur->nWord = 0;.}
7830: 0a 0a 2f 2a 0a 2a 2a 20 43 6c 6f 73 65 20 61 20  ../*.** Close a 
7840: 61 6d 61 74 63 68 20 63 75 72 73 6f 72 2e 0a 2a  amatch cursor..*
7850: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 61 6d 61  /.static int ama
7860: 74 63 68 43 6c 6f 73 65 28 73 71 6c 69 74 65 33  tchClose(sqlite3
7870: 5f 76 74 61 62 5f 63 75 72 73 6f 72 20 2a 63 75  _vtab_cursor *cu
7880: 72 29 7b 0a 20 20 61 6d 61 74 63 68 5f 63 75 72  r){.  amatch_cur
7890: 73 6f 72 20 2a 70 43 75 72 20 3d 20 28 61 6d 61  sor *pCur = (ama
78a0: 74 63 68 5f 63 75 72 73 6f 72 20 2a 29 63 75 72  tch_cursor *)cur
78b0: 3b 0a 20 20 61 6d 61 74 63 68 43 6c 65 61 72 43  ;.  amatchClearC
78c0: 75 72 73 6f 72 28 70 43 75 72 29 3b 0a 20 20 70  ursor(pCur);.  p
78d0: 43 75 72 2d 3e 70 56 74 61 62 2d 3e 6e 43 75 72  Cur->pVtab->nCur
78e0: 73 6f 72 2d 2d 3b 0a 20 20 73 71 6c 69 74 65 33  sor--;.  sqlite3
78f0: 5f 66 72 65 65 28 70 43 75 72 29 3b 0a 20 20 72  _free(pCur);.  r
7900: 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b  eturn SQLITE_OK;
7910: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 6e 64 65 72  .}../*.** Render
7920: 20 61 20 32 34 2d 62 69 74 20 75 6e 73 69 67 6e   a 24-bit unsign
7930: 65 64 20 69 6e 74 65 67 65 72 20 61 73 20 61 20  ed integer as a 
7940: 34 2d 62 79 74 65 20 62 61 73 65 2d 36 34 20 6e  4-byte base-64 n
7950: 75 6d 62 65 72 2e 0a 2a 2f 0a 73 74 61 74 69 63  umber..*/.static
7960: 20 76 6f 69 64 20 61 6d 61 74 63 68 45 6e 63 6f   void amatchEnco
7970: 64 65 49 6e 74 28 69 6e 74 20 78 2c 20 63 68 61  deInt(int x, cha
7980: 72 20 2a 7a 29 7b 0a 20 20 73 74 61 74 69 63 20  r *z){.  static 
7990: 63 6f 6e 73 74 20 63 68 61 72 20 61 5b 5d 20 3d  const char a[] =
79a0: 20 0a 20 20 20 20 22 30 31 32 33 34 35 36 37 38   .    "012345678
79b0: 39 22 0a 20 20 20 20 22 41 42 43 44 45 46 47 48  9".    "ABCDEFGH
79c0: 49 4a 22 0a 20 20 20 20 22 4b 4c 4d 4e 4f 50 51  IJ".    "KLMNOPQ
79d0: 52 53 54 22 0a 20 20 20 20 22 55 56 57 58 59 5a  RST".    "UVWXYZ
79e0: 5e 61 62 63 22 0a 20 20 20 20 22 64 65 66 67 68  ^abc".    "defgh
79f0: 69 6a 6b 6c 6d 22 0a 20 20 20 20 22 6e 6f 70 71  ijklm".    "nopq
7a00: 72 73 74 75 76 77 22 0a 20 20 20 20 22 78 79 7a  rstuvw".    "xyz
7a10: 7e 22 3b 0a 20 20 7a 5b 30 5d 20 3d 20 61 5b 28  ~";.  z[0] = a[(
7a20: 78 3e 3e 31 38 29 26 30 78 33 66 5d 3b 0a 20 20  x>>18)&0x3f];.  
7a30: 7a 5b 31 5d 20 3d 20 61 5b 28 78 3e 3e 31 32 29  z[1] = a[(x>>12)
7a40: 26 30 78 33 66 5d 3b 0a 20 20 7a 5b 32 5d 20 3d  &0x3f];.  z[2] =
7a50: 20 61 5b 28 78 3e 3e 36 29 26 30 78 33 66 5d 3b   a[(x>>6)&0x3f];
7a60: 0a 20 20 7a 5b 33 5d 20 3d 20 61 5b 78 26 30 78  .  z[3] = a[x&0x
7a70: 33 66 5d 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 57 72  3f];.}../*.** Wr
7a80: 69 74 65 20 74 68 65 20 7a 43 6f 73 74 5b 5d 20  ite the zCost[] 
7a90: 66 69 65 6c 64 20 66 6f 72 20 61 20 61 6d 61 74  field for a amat
7aa0: 63 68 5f 77 6f 72 64 20 6f 62 6a 65 63 74 0a 2a  ch_word object.*
7ab0: 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 61 6d  /.static void am
7ac0: 61 74 63 68 57 72 69 74 65 43 6f 73 74 28 61 6d  atchWriteCost(am
7ad0: 61 74 63 68 5f 77 6f 72 64 20 2a 70 57 6f 72 64  atch_word *pWord
7ae0: 29 7b 0a 20 20 61 6d 61 74 63 68 45 6e 63 6f 64  ){.  amatchEncod
7af0: 65 49 6e 74 28 70 57 6f 72 64 2d 3e 72 43 6f 73  eInt(pWord->rCos
7b00: 74 2c 20 70 57 6f 72 64 2d 3e 7a 43 6f 73 74 29  t, pWord->zCost)
7b10: 3b 0a 20 20 61 6d 61 74 63 68 45 6e 63 6f 64 65  ;.  amatchEncode
7b20: 49 6e 74 28 70 57 6f 72 64 2d 3e 69 53 65 71 2c  Int(pWord->iSeq,
7b30: 20 70 57 6f 72 64 2d 3e 7a 43 6f 73 74 2b 34 29   pWord->zCost+4)
7b40: 3b 0a 20 20 70 57 6f 72 64 2d 3e 7a 43 6f 73 74  ;.  pWord->zCost
7b50: 5b 38 5d 20 3d 20 30 3b 0a 7d 0a 0a 2f 2a 20 43  [8] = 0;.}../* C
7b60: 69 72 63 75 6d 76 65 6e 74 20 63 6f 6d 70 69 6c  ircumvent compil
7b70: 65 72 20 77 61 72 6e 69 6e 67 73 20 61 62 6f 75  er warnings abou
7b80: 74 20 74 68 65 20 75 73 65 20 6f 66 20 73 74 72  t the use of str
7b90: 63 70 79 28 29 20 62 79 20 73 75 70 70 6c 79 69  cpy() by supplyi
7ba0: 6e 67 0a 2a 2a 20 6f 75 72 20 6f 77 6e 20 69 6d  ng.** our own im
7bb0: 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 2e 0a 2a 2f  plementation..*/
7bc0: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 61 6d 61  .static void ama
7bd0: 74 63 68 53 74 72 63 70 79 28 63 68 61 72 20 2a  tchStrcpy(char *
7be0: 64 65 73 74 2c 20 63 6f 6e 73 74 20 63 68 61 72  dest, const char
7bf0: 20 2a 73 72 63 29 7b 0a 20 20 77 68 69 6c 65 28   *src){.  while(
7c00: 20 28 2a 28 64 65 73 74 2b 2b 29 20 3d 20 2a 28   (*(dest++) = *(
7c10: 73 72 63 2b 2b 29 29 21 3d 30 20 29 7b 7d 0a 7d  src++))!=0 ){}.}
7c20: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 61 6d 61  .static void ama
7c30: 74 63 68 53 74 72 63 61 74 28 63 68 61 72 20 2a  tchStrcat(char *
7c40: 64 65 73 74 2c 20 63 6f 6e 73 74 20 63 68 61 72  dest, const char
7c50: 20 2a 73 72 63 29 7b 0a 20 20 77 68 69 6c 65 28   *src){.  while(
7c60: 20 2a 64 65 73 74 20 29 20 64 65 73 74 2b 2b 3b   *dest ) dest++;
7c70: 0a 20 20 61 6d 61 74 63 68 53 74 72 63 70 79 28  .  amatchStrcpy(
7c80: 64 65 73 74 2c 20 73 72 63 29 3b 0a 7d 0a 0a 2f  dest, src);.}../
7c90: 2a 0a 2a 2a 20 41 64 64 20 61 20 6e 65 77 20 61  *.** Add a new a
7ca0: 6d 61 74 63 68 5f 77 6f 72 64 20 6f 62 6a 65 63  match_word objec
7cb0: 74 20 74 6f 20 74 68 65 20 71 75 65 75 65 2e 0a  t to the queue..
7cc0: 2a 2a 0a 2a 2a 20 49 66 20 61 20 70 72 69 6f 72  **.** If a prior
7cd0: 20 61 6d 61 74 63 68 5f 77 6f 72 64 20 6f 62 6a   amatch_word obj
7ce0: 65 63 74 20 77 69 74 68 20 74 68 65 20 73 61 6d  ect with the sam
7cf0: 65 20 7a 57 6f 72 64 2c 20 61 6e 64 20 6e 4d 61  e zWord, and nMa
7d00: 74 63 68 0a 2a 2a 20 61 6c 72 65 61 64 79 20 65  tch.** already e
7d10: 78 69 73 74 73 2c 20 75 70 64 61 74 65 20 69 74  xists, update it
7d20: 73 20 72 43 6f 73 74 20 28 69 66 20 74 68 65 20  s rCost (if the 
7d30: 6e 65 77 20 72 43 6f 73 74 20 69 73 20 6c 65 73  new rCost is les
7d40: 73 29 20 62 75 74 0a 2a 2a 20 6f 74 68 65 72 77  s) but.** otherw
7d50: 69 73 65 20 6c 65 61 76 65 20 69 74 20 75 6e 63  ise leave it unc
7d60: 68 61 6e 67 65 64 2e 20 20 44 6f 20 6e 6f 74 20  hanged.  Do not 
7d70: 61 64 64 20 61 20 64 75 70 6c 69 63 61 74 65 2e  add a duplicate.
7d80: 0a 2a 2a 0a 2a 2a 20 44 6f 20 6e 6f 74 68 69 6e  .**.** Do nothin
7d90: 67 20 69 66 20 74 68 65 20 63 6f 73 74 20 65 78  g if the cost ex
7da0: 63 65 65 64 73 20 74 68 72 65 73 68 6f 6c 64 2e  ceeds threshold.
7db0: 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20  .*/.static void 
7dc0: 61 6d 61 74 63 68 41 64 64 57 6f 72 64 28 0a 20  amatchAddWord(. 
7dd0: 20 61 6d 61 74 63 68 5f 63 75 72 73 6f 72 20 2a   amatch_cursor *
7de0: 70 43 75 72 2c 0a 20 20 61 6d 61 74 63 68 5f 63  pCur,.  amatch_c
7df0: 6f 73 74 20 72 43 6f 73 74 2c 0a 20 20 69 6e 74  ost rCost,.  int
7e00: 20 6e 4d 61 74 63 68 2c 0a 20 20 63 6f 6e 73 74   nMatch,.  const
7e10: 20 63 68 61 72 20 2a 7a 57 6f 72 64 42 61 73 65   char *zWordBase
7e20: 2c 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a  ,.  const char *
7e30: 7a 57 6f 72 64 54 61 69 6c 0a 29 7b 0a 20 20 61  zWordTail.){.  a
7e40: 6d 61 74 63 68 5f 77 6f 72 64 20 2a 70 57 6f 72  match_word *pWor
7e50: 64 3b 0a 20 20 61 6d 61 74 63 68 5f 61 76 6c 20  d;.  amatch_avl 
7e60: 2a 70 4e 6f 64 65 3b 0a 20 20 61 6d 61 74 63 68  *pNode;.  amatch
7e70: 5f 61 76 6c 20 2a 70 4f 74 68 65 72 3b 0a 20 20  _avl *pOther;.  
7e80: 69 6e 74 20 6e 42 61 73 65 2c 20 6e 54 61 69 6c  int nBase, nTail
7e90: 3b 0a 20 20 63 68 61 72 20 7a 42 75 66 5b 34 5d  ;.  char zBuf[4]
7ea0: 3b 0a 20 20 0a 20 20 69 66 28 20 72 43 6f 73 74  ;.  .  if( rCost
7eb0: 3e 70 43 75 72 2d 3e 72 4c 69 6d 69 74 20 29 7b  >pCur->rLimit ){
7ec0: 0a 20 20 20 20 72 65 74 75 72 6e 3b 0a 20 20 7d  .    return;.  }
7ed0: 0a 20 20 6e 42 61 73 65 20 3d 20 28 69 6e 74 29  .  nBase = (int)
7ee0: 73 74 72 6c 65 6e 28 7a 57 6f 72 64 42 61 73 65  strlen(zWordBase
7ef0: 29 3b 0a 20 20 6e 54 61 69 6c 20 3d 20 28 69 6e  );.  nTail = (in
7f00: 74 29 73 74 72 6c 65 6e 28 7a 57 6f 72 64 54 61  t)strlen(zWordTa
7f10: 69 6c 29 3b 0a 20 20 69 66 28 20 6e 42 61 73 65  il);.  if( nBase
7f20: 2b 6e 54 61 69 6c 2b 33 3e 70 43 75 72 2d 3e 6e  +nTail+3>pCur->n
7f30: 42 75 66 20 29 7b 0a 20 20 20 20 70 43 75 72 2d  Buf ){.    pCur-
7f40: 3e 6e 42 75 66 20 3d 20 6e 42 61 73 65 2b 6e 54  >nBuf = nBase+nT
7f50: 61 69 6c 2b 31 30 30 3b 0a 20 20 20 20 70 43 75  ail+100;.    pCu
7f60: 72 2d 3e 7a 42 75 66 20 3d 20 73 71 6c 69 74 65  r->zBuf = sqlite
7f70: 33 5f 72 65 61 6c 6c 6f 63 28 70 43 75 72 2d 3e  3_realloc(pCur->
7f80: 7a 42 75 66 2c 20 70 43 75 72 2d 3e 6e 42 75 66  zBuf, pCur->nBuf
7f90: 29 3b 0a 20 20 20 20 69 66 28 20 70 43 75 72 2d  );.    if( pCur-
7fa0: 3e 7a 42 75 66 3d 3d 30 20 29 7b 0a 20 20 20 20  >zBuf==0 ){.    
7fb0: 20 20 70 43 75 72 2d 3e 6e 42 75 66 20 3d 20 30    pCur->nBuf = 0
7fc0: 3b 0a 20 20 20 20 20 20 72 65 74 75 72 6e 3b 0a  ;.      return;.
7fd0: 20 20 20 20 7d 0a 20 20 7d 0a 20 20 61 6d 61 74      }.  }.  amat
7fe0: 63 68 45 6e 63 6f 64 65 49 6e 74 28 6e 4d 61 74  chEncodeInt(nMat
7ff0: 63 68 2c 20 7a 42 75 66 29 3b 0a 20 20 6d 65 6d  ch, zBuf);.  mem
8000: 63 70 79 28 70 43 75 72 2d 3e 7a 42 75 66 2c 20  cpy(pCur->zBuf, 
8010: 7a 42 75 66 2b 32 2c 20 32 29 3b 0a 20 20 6d 65  zBuf+2, 2);.  me
8020: 6d 63 70 79 28 70 43 75 72 2d 3e 7a 42 75 66 2b  mcpy(pCur->zBuf+
8030: 32 2c 20 7a 57 6f 72 64 42 61 73 65 2c 20 6e 42  2, zWordBase, nB
8040: 61 73 65 29 3b 0a 20 20 6d 65 6d 63 70 79 28 70  ase);.  memcpy(p
8050: 43 75 72 2d 3e 7a 42 75 66 2b 32 2b 6e 42 61 73  Cur->zBuf+2+nBas
8060: 65 2c 20 7a 57 6f 72 64 54 61 69 6c 2c 20 6e 54  e, zWordTail, nT
8070: 61 69 6c 2b 31 29 3b 0a 20 20 70 4e 6f 64 65 20  ail+1);.  pNode 
8080: 3d 20 61 6d 61 74 63 68 41 76 6c 53 65 61 72 63  = amatchAvlSearc
8090: 68 28 70 43 75 72 2d 3e 70 57 6f 72 64 2c 20 70  h(pCur->pWord, p
80a0: 43 75 72 2d 3e 7a 42 75 66 29 3b 0a 20 20 69 66  Cur->zBuf);.  if
80b0: 28 20 70 4e 6f 64 65 20 29 7b 0a 20 20 20 20 70  ( pNode ){.    p
80c0: 57 6f 72 64 20 3d 20 70 4e 6f 64 65 2d 3e 70 57  Word = pNode->pW
80d0: 6f 72 64 3b 0a 20 20 20 20 69 66 28 20 70 57 6f  ord;.    if( pWo
80e0: 72 64 2d 3e 72 43 6f 73 74 3e 72 43 6f 73 74 20  rd->rCost>rCost 
80f0: 29 7b 0a 23 69 66 64 65 66 20 41 4d 41 54 43 48  ){.#ifdef AMATCH
8100: 5f 54 52 41 43 45 5f 31 0a 20 20 20 20 20 20 70  _TRACE_1.      p
8110: 72 69 6e 74 66 28 22 55 50 44 41 54 45 20 5b 25  rintf("UPDATE [%
8120: 73 5d 5b 25 2e 2a 73 5e 25 73 5d 20 25 64 20 28  s][%.*s^%s] %d (
8130: 5c 22 25 73 5c 22 20 5c 22 25 73 5c 22 29 5c 6e  \"%s\" \"%s\")\n
8140: 22 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  ",.             
8150: 70 57 6f 72 64 2d 3e 7a 57 6f 72 64 2b 32 2c 20  pWord->zWord+2, 
8160: 70 57 6f 72 64 2d 3e 6e 4d 61 74 63 68 2c 20 70  pWord->nMatch, p
8170: 43 75 72 2d 3e 7a 49 6e 70 75 74 2c 20 70 43 75  Cur->zInput, pCu
8180: 72 2d 3e 7a 49 6e 70 75 74 2c 0a 20 20 20 20 20  r->zInput,.     
8190: 20 20 20 20 20 20 20 20 70 57 6f 72 64 2d 3e 72          pWord->r
81a0: 43 6f 73 74 2c 20 70 57 6f 72 64 2d 3e 7a 57 6f  Cost, pWord->zWo
81b0: 72 64 2c 20 70 57 6f 72 64 2d 3e 7a 43 6f 73 74  rd, pWord->zCost
81c0: 29 3b 0a 23 65 6e 64 69 66 0a 20 20 20 20 20 20  );.#endif.      
81d0: 61 6d 61 74 63 68 41 76 6c 52 65 6d 6f 76 65 28  amatchAvlRemove(
81e0: 26 70 43 75 72 2d 3e 70 43 6f 73 74 2c 20 26 70  &pCur->pCost, &p
81f0: 57 6f 72 64 2d 3e 73 43 6f 73 74 29 3b 0a 20 20  Word->sCost);.  
8200: 20 20 20 20 70 57 6f 72 64 2d 3e 72 43 6f 73 74      pWord->rCost
8210: 20 3d 20 72 43 6f 73 74 3b 0a 20 20 20 20 20 20   = rCost;.      
8220: 61 6d 61 74 63 68 57 72 69 74 65 43 6f 73 74 28  amatchWriteCost(
8230: 70 57 6f 72 64 29 3b 0a 23 69 66 64 65 66 20 41  pWord);.#ifdef A
8240: 4d 41 54 43 48 5f 54 52 41 43 45 5f 31 0a 20 20  MATCH_TRACE_1.  
8250: 20 20 20 20 70 72 69 6e 74 66 28 22 20 20 2d 2d      printf("  --
8260: 2d 3e 20 25 64 20 28 5c 22 25 73 5c 22 20 5c 22  -> %d (\"%s\" \"
8270: 25 73 5c 22 29 5c 6e 22 2c 0a 20 20 20 20 20 20  %s\")\n",.      
8280: 20 20 20 20 20 20 20 70 57 6f 72 64 2d 3e 72 43         pWord->rC
8290: 6f 73 74 2c 20 70 57 6f 72 64 2d 3e 7a 57 6f 72  ost, pWord->zWor
82a0: 64 2c 20 70 57 6f 72 64 2d 3e 7a 43 6f 73 74 29  d, pWord->zCost)
82b0: 3b 0a 23 65 6e 64 69 66 0a 20 20 20 20 20 20 70  ;.#endif.      p
82c0: 4f 74 68 65 72 20 3d 20 61 6d 61 74 63 68 41 76  Other = amatchAv
82d0: 6c 49 6e 73 65 72 74 28 26 70 43 75 72 2d 3e 70  lInsert(&pCur->p
82e0: 43 6f 73 74 2c 20 26 70 57 6f 72 64 2d 3e 73 43  Cost, &pWord->sC
82f0: 6f 73 74 29 3b 0a 20 20 20 20 20 20 61 73 73 65  ost);.      asse
8300: 72 74 28 20 70 4f 74 68 65 72 3d 3d 30 20 29 3b  rt( pOther==0 );
8310: 20 28 76 6f 69 64 29 70 4f 74 68 65 72 3b 0a 20   (void)pOther;. 
8320: 20 20 20 7d 0a 20 20 20 20 72 65 74 75 72 6e 3b     }.    return;
8330: 0a 20 20 7d 0a 20 20 70 57 6f 72 64 20 3d 20 73  .  }.  pWord = s
8340: 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63 28 20 73  qlite3_malloc( s
8350: 69 7a 65 6f 66 28 2a 70 57 6f 72 64 29 20 2b 20  izeof(*pWord) + 
8360: 6e 42 61 73 65 20 2b 20 6e 54 61 69 6c 20 2d 20  nBase + nTail - 
8370: 31 20 29 3b 0a 20 20 69 66 28 20 70 57 6f 72 64  1 );.  if( pWord
8380: 3d 3d 30 20 29 20 72 65 74 75 72 6e 3b 0a 20 20  ==0 ) return;.  
8390: 6d 65 6d 73 65 74 28 70 57 6f 72 64 2c 20 30 2c  memset(pWord, 0,
83a0: 20 73 69 7a 65 6f 66 28 2a 70 57 6f 72 64 29 29   sizeof(*pWord))
83b0: 3b 0a 20 20 70 57 6f 72 64 2d 3e 72 43 6f 73 74  ;.  pWord->rCost
83c0: 20 3d 20 72 43 6f 73 74 3b 0a 20 20 70 57 6f 72   = rCost;.  pWor
83d0: 64 2d 3e 69 53 65 71 20 3d 20 70 43 75 72 2d 3e  d->iSeq = pCur->
83e0: 6e 57 6f 72 64 2b 2b 3b 0a 20 20 61 6d 61 74 63  nWord++;.  amatc
83f0: 68 57 72 69 74 65 43 6f 73 74 28 70 57 6f 72 64  hWriteCost(pWord
8400: 29 3b 0a 20 20 70 57 6f 72 64 2d 3e 6e 4d 61 74  );.  pWord->nMat
8410: 63 68 20 3d 20 28 73 68 6f 72 74 29 6e 4d 61 74  ch = (short)nMat
8420: 63 68 3b 0a 20 20 70 57 6f 72 64 2d 3e 70 4e 65  ch;.  pWord->pNe
8430: 78 74 20 3d 20 70 43 75 72 2d 3e 70 41 6c 6c 57  xt = pCur->pAllW
8440: 6f 72 64 73 3b 0a 20 20 70 43 75 72 2d 3e 70 41  ords;.  pCur->pA
8450: 6c 6c 57 6f 72 64 73 20 3d 20 70 57 6f 72 64 3b  llWords = pWord;
8460: 0a 20 20 70 57 6f 72 64 2d 3e 73 43 6f 73 74 2e  .  pWord->sCost.
8470: 7a 4b 65 79 20 3d 20 70 57 6f 72 64 2d 3e 7a 43  zKey = pWord->zC
8480: 6f 73 74 3b 0a 20 20 70 57 6f 72 64 2d 3e 73 43  ost;.  pWord->sC
8490: 6f 73 74 2e 70 57 6f 72 64 20 3d 20 70 57 6f 72  ost.pWord = pWor
84a0: 64 3b 0a 20 20 70 4f 74 68 65 72 20 3d 20 61 6d  d;.  pOther = am
84b0: 61 74 63 68 41 76 6c 49 6e 73 65 72 74 28 26 70  atchAvlInsert(&p
84c0: 43 75 72 2d 3e 70 43 6f 73 74 2c 20 26 70 57 6f  Cur->pCost, &pWo
84d0: 72 64 2d 3e 73 43 6f 73 74 29 3b 0a 20 20 61 73  rd->sCost);.  as
84e0: 73 65 72 74 28 20 70 4f 74 68 65 72 3d 3d 30 20  sert( pOther==0 
84f0: 29 3b 20 28 76 6f 69 64 29 70 4f 74 68 65 72 3b  ); (void)pOther;
8500: 0a 20 20 70 57 6f 72 64 2d 3e 73 57 6f 72 64 2e  .  pWord->sWord.
8510: 7a 4b 65 79 20 3d 20 70 57 6f 72 64 2d 3e 7a 57  zKey = pWord->zW
8520: 6f 72 64 3b 0a 20 20 70 57 6f 72 64 2d 3e 73 57  ord;.  pWord->sW
8530: 6f 72 64 2e 70 57 6f 72 64 20 3d 20 70 57 6f 72  ord.pWord = pWor
8540: 64 3b 0a 20 20 61 6d 61 74 63 68 53 74 72 63 70  d;.  amatchStrcp
8550: 79 28 70 57 6f 72 64 2d 3e 7a 57 6f 72 64 2c 20  y(pWord->zWord, 
8560: 70 43 75 72 2d 3e 7a 42 75 66 29 3b 0a 20 20 70  pCur->zBuf);.  p
8570: 4f 74 68 65 72 20 3d 20 61 6d 61 74 63 68 41 76  Other = amatchAv
8580: 6c 49 6e 73 65 72 74 28 26 70 43 75 72 2d 3e 70  lInsert(&pCur->p
8590: 57 6f 72 64 2c 20 26 70 57 6f 72 64 2d 3e 73 57  Word, &pWord->sW
85a0: 6f 72 64 29 3b 0a 20 20 61 73 73 65 72 74 28 20  ord);.  assert( 
85b0: 70 4f 74 68 65 72 3d 3d 30 20 29 3b 20 28 76 6f  pOther==0 ); (vo
85c0: 69 64 29 70 4f 74 68 65 72 3b 0a 23 69 66 64 65  id)pOther;.#ifde
85d0: 66 20 41 4d 41 54 43 48 5f 54 52 41 43 45 5f 31  f AMATCH_TRACE_1
85e0: 0a 20 20 70 72 69 6e 74 66 28 22 49 4e 53 45 52  .  printf("INSER
85f0: 54 20 5b 25 73 5d 5b 25 2e 2a 73 5e 25 73 5d 20  T [%s][%.*s^%s] 
8600: 25 64 20 28 5c 22 25 73 5c 22 20 5c 22 25 73 5c  %d (\"%s\" \"%s\
8610: 22 29 5c 6e 22 2c 20 70 57 6f 72 64 2d 3e 7a 57  ")\n", pWord->zW
8620: 6f 72 64 2b 32 2c 0a 20 20 20 20 20 20 20 70 57  ord+2,.       pW
8630: 6f 72 64 2d 3e 6e 4d 61 74 63 68 2c 20 70 43 75  ord->nMatch, pCu
8640: 72 2d 3e 7a 49 6e 70 75 74 2c 20 70 43 75 72 2d  r->zInput, pCur-
8650: 3e 7a 49 6e 70 75 74 2b 70 57 6f 72 64 2d 3e 6e  >zInput+pWord->n
8660: 4d 61 74 63 68 2c 20 72 43 6f 73 74 2c 0a 20 20  Match, rCost,.  
8670: 20 20 20 20 20 70 57 6f 72 64 2d 3e 7a 57 6f 72       pWord->zWor
8680: 64 2c 20 70 57 6f 72 64 2d 3e 7a 43 6f 73 74 29  d, pWord->zCost)
8690: 3b 0a 23 65 6e 64 69 66 0a 7d 0a 0a 0a 2f 2a 0a  ;.#endif.}.../*.
86a0: 2a 2a 20 41 64 76 61 6e 63 65 20 61 20 63 75 72  ** Advance a cur
86b0: 73 6f 72 20 74 6f 20 69 74 73 20 6e 65 78 74 20  sor to its next 
86c0: 72 6f 77 20 6f 66 20 6f 75 74 70 75 74 0a 2a 2f  row of output.*/
86d0: 0a 73 74 61 74 69 63 20 69 6e 74 20 61 6d 61 74  .static int amat
86e0: 63 68 4e 65 78 74 28 73 71 6c 69 74 65 33 5f 76  chNext(sqlite3_v
86f0: 74 61 62 5f 63 75 72 73 6f 72 20 2a 63 75 72 29  tab_cursor *cur)
8700: 7b 0a 20 20 61 6d 61 74 63 68 5f 63 75 72 73 6f  {.  amatch_curso
8710: 72 20 2a 70 43 75 72 20 3d 20 28 61 6d 61 74 63  r *pCur = (amatc
8720: 68 5f 63 75 72 73 6f 72 2a 29 63 75 72 3b 0a 20  h_cursor*)cur;. 
8730: 20 61 6d 61 74 63 68 5f 77 6f 72 64 20 2a 70 57   amatch_word *pW
8740: 6f 72 64 20 3d 20 30 3b 0a 20 20 61 6d 61 74 63  ord = 0;.  amatc
8750: 68 5f 61 76 6c 20 2a 70 4e 6f 64 65 3b 0a 20 20  h_avl *pNode;.  
8760: 69 6e 74 20 69 73 4d 61 74 63 68 20 3d 20 30 3b  int isMatch = 0;
8770: 0a 20 20 61 6d 61 74 63 68 5f 76 74 61 62 20 2a  .  amatch_vtab *
8780: 70 20 3d 20 70 43 75 72 2d 3e 70 56 74 61 62 3b  p = pCur->pVtab;
8790: 0a 20 20 69 6e 74 20 6e 57 6f 72 64 3b 0a 20 20  .  int nWord;.  
87a0: 69 6e 74 20 72 63 3b 0a 20 20 69 6e 74 20 69 3b  int rc;.  int i;
87b0: 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a  .  const char *z
87c0: 57 3b 0a 20 20 61 6d 61 74 63 68 5f 72 75 6c 65  W;.  amatch_rule
87d0: 20 2a 70 52 75 6c 65 3b 0a 20 20 63 68 61 72 20   *pRule;.  char 
87e0: 2a 7a 42 75 66 20 3d 20 30 3b 0a 20 20 63 68 61  *zBuf = 0;.  cha
87f0: 72 20 6e 42 75 66 20 3d 20 30 3b 0a 20 20 63 68  r nBuf = 0;.  ch
8800: 61 72 20 7a 4e 65 78 74 5b 38 5d 3b 0a 20 20 63  ar zNext[8];.  c
8810: 68 61 72 20 7a 4e 65 78 74 49 6e 5b 38 5d 3b 0a  har zNextIn[8];.
8820: 20 20 69 6e 74 20 6e 4e 65 78 74 49 6e 3b 0a 0a    int nNextIn;..
8830: 20 20 69 66 28 20 70 2d 3e 70 56 43 68 65 63 6b    if( p->pVCheck
8840: 3d 3d 30 20 29 7b 0a 20 20 20 20 63 68 61 72 20  ==0 ){.    char 
8850: 2a 7a 53 71 6c 3b 0a 20 20 20 20 69 66 28 20 70  *zSql;.    if( p
8860: 2d 3e 7a 56 6f 63 61 62 4c 61 6e 67 20 26 26 20  ->zVocabLang && 
8870: 70 2d 3e 7a 56 6f 63 61 62 4c 61 6e 67 5b 30 5d  p->zVocabLang[0]
8880: 20 29 7b 0a 20 20 20 20 20 20 7a 53 71 6c 20 3d   ){.      zSql =
8890: 20 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66   sqlite3_mprintf
88a0: 28 0a 20 20 20 20 20 20 20 20 20 20 22 53 45 4c  (.          "SEL
88b0: 45 43 54 20 5c 22 25 77 5c 22 20 46 52 4f 4d 20  ECT \"%w\" FROM 
88c0: 5c 22 25 77 5c 22 22 2c 0a 20 20 20 20 20 20 20  \"%w\"",.       
88d0: 20 20 20 22 20 57 48 45 52 45 20 5c 22 25 77 5c     " WHERE \"%w\
88e0: 22 3e 3d 3f 31 20 41 4e 44 20 5c 22 25 77 5c 22  ">=?1 AND \"%w\"
88f0: 3d 3f 32 22 0a 20 20 20 20 20 20 20 20 20 20 22  =?2".          "
8900: 20 4f 52 44 45 52 20 42 59 20 31 22 2c 0a 20 20   ORDER BY 1",.  
8910: 20 20 20 20 20 20 20 20 70 2d 3e 7a 56 6f 63 61          p->zVoca
8920: 62 57 6f 72 64 2c 20 70 2d 3e 7a 56 6f 63 61 62  bWord, p->zVocab
8930: 54 61 62 2c 0a 20 20 20 20 20 20 20 20 20 20 70  Tab,.          p
8940: 2d 3e 7a 56 6f 63 61 62 57 6f 72 64 2c 20 70 2d  ->zVocabWord, p-
8950: 3e 7a 56 6f 63 61 62 4c 61 6e 67 0a 20 20 20 20  >zVocabLang.    
8960: 20 20 29 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a    );.    }else{.
8970: 20 20 20 20 20 20 7a 53 71 6c 20 3d 20 73 71 6c        zSql = sql
8980: 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 0a 20 20  ite3_mprintf(.  
8990: 20 20 20 20 20 20 20 20 22 53 45 4c 45 43 54 20          "SELECT 
89a0: 5c 22 25 77 5c 22 20 46 52 4f 4d 20 5c 22 25 77  \"%w\" FROM \"%w
89b0: 5c 22 22 0a 20 20 20 20 20 20 20 20 20 20 22 20  \"".          " 
89c0: 57 48 45 52 45 20 5c 22 25 77 5c 22 3e 3d 3f 31  WHERE \"%w\">=?1
89d0: 22 0a 20 20 20 20 20 20 20 20 20 20 22 20 4f 52  ".          " OR
89e0: 44 45 52 20 42 59 20 31 22 2c 0a 20 20 20 20 20  DER BY 1",.     
89f0: 20 20 20 20 20 70 2d 3e 7a 56 6f 63 61 62 57 6f       p->zVocabWo
8a00: 72 64 2c 20 70 2d 3e 7a 56 6f 63 61 62 54 61 62  rd, p->zVocabTab
8a10: 2c 0a 20 20 20 20 20 20 20 20 20 20 70 2d 3e 7a  ,.          p->z
8a20: 56 6f 63 61 62 57 6f 72 64 0a 20 20 20 20 20 20  VocabWord.      
8a30: 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 72 63 20  );.    }.    rc 
8a40: 3d 20 73 71 6c 69 74 65 33 5f 70 72 65 70 61 72  = sqlite3_prepar
8a50: 65 5f 76 32 28 70 2d 3e 64 62 2c 20 7a 53 71 6c  e_v2(p->db, zSql
8a60: 2c 20 2d 31 2c 20 26 70 2d 3e 70 56 43 68 65 63  , -1, &p->pVChec
8a70: 6b 2c 20 30 29 3b 0a 20 20 20 20 73 71 6c 69 74  k, 0);.    sqlit
8a80: 65 33 5f 66 72 65 65 28 7a 53 71 6c 29 3b 0a 20  e3_free(zSql);. 
8a90: 20 20 20 69 66 28 20 72 63 20 29 20 72 65 74 75     if( rc ) retu
8aa0: 72 6e 20 72 63 3b 0a 20 20 7d 0a 20 20 73 71 6c  rn rc;.  }.  sql
8ab0: 69 74 65 33 5f 62 69 6e 64 5f 69 6e 74 28 70 2d  ite3_bind_int(p-
8ac0: 3e 70 56 43 68 65 63 6b 2c 20 32 2c 20 70 43 75  >pVCheck, 2, pCu
8ad0: 72 2d 3e 69 4c 61 6e 67 29 3b 0a 0a 20 20 64 6f  r->iLang);..  do
8ae0: 7b 0a 20 20 20 20 70 4e 6f 64 65 20 3d 20 61 6d  {.    pNode = am
8af0: 61 74 63 68 41 76 6c 46 69 72 73 74 28 70 43 75  atchAvlFirst(pCu
8b00: 72 2d 3e 70 43 6f 73 74 29 3b 0a 20 20 20 20 69  r->pCost);.    i
8b10: 66 28 20 70 4e 6f 64 65 3d 3d 30 20 29 7b 0a 20  f( pNode==0 ){. 
8b20: 20 20 20 20 20 70 57 6f 72 64 20 3d 20 30 3b 0a       pWord = 0;.
8b30: 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20        break;.   
8b40: 20 7d 0a 20 20 20 20 70 57 6f 72 64 20 3d 20 70   }.    pWord = p
8b50: 4e 6f 64 65 2d 3e 70 57 6f 72 64 3b 0a 20 20 20  Node->pWord;.   
8b60: 20 61 6d 61 74 63 68 41 76 6c 52 65 6d 6f 76 65   amatchAvlRemove
8b70: 28 26 70 43 75 72 2d 3e 70 43 6f 73 74 2c 20 26  (&pCur->pCost, &
8b80: 70 57 6f 72 64 2d 3e 73 43 6f 73 74 29 3b 0a 0a  pWord->sCost);..
8b90: 23 69 66 64 65 66 20 41 4d 41 54 43 48 5f 54 52  #ifdef AMATCH_TR
8ba0: 41 43 45 5f 31 0a 20 20 20 20 70 72 69 6e 74 66  ACE_1.    printf
8bb0: 28 22 50 52 4f 43 45 53 53 20 5b 25 73 5d 5b 25  ("PROCESS [%s][%
8bc0: 2e 2a 73 5e 25 73 5d 20 25 64 20 28 5c 22 25 73  .*s^%s] %d (\"%s
8bd0: 5c 22 20 5c 22 25 73 5c 22 29 5c 6e 22 2c 0a 20  \" \"%s\")\n",. 
8be0: 20 20 20 20 20 20 70 57 6f 72 64 2d 3e 7a 57 6f        pWord->zWo
8bf0: 72 64 2b 32 2c 20 70 57 6f 72 64 2d 3e 6e 4d 61  rd+2, pWord->nMa
8c00: 74 63 68 2c 20 70 43 75 72 2d 3e 7a 49 6e 70 75  tch, pCur->zInpu
8c10: 74 2c 20 70 43 75 72 2d 3e 7a 49 6e 70 75 74 2b  t, pCur->zInput+
8c20: 70 57 6f 72 64 2d 3e 6e 4d 61 74 63 68 2c 0a 20  pWord->nMatch,. 
8c30: 20 20 20 20 20 20 70 57 6f 72 64 2d 3e 72 43 6f        pWord->rCo
8c40: 73 74 2c 20 70 57 6f 72 64 2d 3e 7a 57 6f 72 64  st, pWord->zWord
8c50: 2c 20 70 57 6f 72 64 2d 3e 7a 43 6f 73 74 29 3b  , pWord->zCost);
8c60: 0a 23 65 6e 64 69 66 0a 20 20 20 20 6e 57 6f 72  .#endif.    nWor
8c70: 64 20 3d 20 28 69 6e 74 29 73 74 72 6c 65 6e 28  d = (int)strlen(
8c80: 70 57 6f 72 64 2d 3e 7a 57 6f 72 64 2b 32 29 3b  pWord->zWord+2);
8c90: 0a 20 20 20 20 69 66 28 20 6e 57 6f 72 64 2b 32  .    if( nWord+2
8ca0: 30 3e 6e 42 75 66 20 29 7b 0a 20 20 20 20 20 20  0>nBuf ){.      
8cb0: 6e 42 75 66 20 3d 20 28 63 68 61 72 29 28 6e 57  nBuf = (char)(nW
8cc0: 6f 72 64 2b 31 30 30 29 3b 0a 20 20 20 20 20 20  ord+100);.      
8cd0: 7a 42 75 66 20 3d 20 73 71 6c 69 74 65 33 5f 72  zBuf = sqlite3_r
8ce0: 65 61 6c 6c 6f 63 28 7a 42 75 66 2c 20 6e 42 75  ealloc(zBuf, nBu
8cf0: 66 29 3b 0a 20 20 20 20 20 20 69 66 28 20 7a 42  f);.      if( zB
8d00: 75 66 3d 3d 30 20 29 20 72 65 74 75 72 6e 20 53  uf==0 ) return S
8d10: 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20  QLITE_NOMEM;.   
8d20: 20 7d 0a 20 20 20 20 61 6d 61 74 63 68 53 74 72   }.    amatchStr
8d30: 63 70 79 28 7a 42 75 66 2c 20 70 57 6f 72 64 2d  cpy(zBuf, pWord-
8d40: 3e 7a 57 6f 72 64 2b 32 29 3b 0a 20 20 20 20 7a  >zWord+2);.    z
8d50: 4e 65 78 74 5b 30 5d 20 3d 20 30 3b 0a 20 20 20  Next[0] = 0;.   
8d60: 20 7a 4e 65 78 74 49 6e 5b 30 5d 20 3d 20 70 43   zNextIn[0] = pC
8d70: 75 72 2d 3e 7a 49 6e 70 75 74 5b 70 57 6f 72 64  ur->zInput[pWord
8d80: 2d 3e 6e 4d 61 74 63 68 5d 3b 0a 20 20 20 20 69  ->nMatch];.    i
8d90: 66 28 20 7a 4e 65 78 74 49 6e 5b 30 5d 20 29 7b  f( zNextIn[0] ){
8da0: 0a 20 20 20 20 20 20 66 6f 72 28 69 3d 31 3b 20  .      for(i=1; 
8db0: 69 3c 3d 34 20 26 26 20 28 70 43 75 72 2d 3e 7a  i<=4 && (pCur->z
8dc0: 49 6e 70 75 74 5b 70 57 6f 72 64 2d 3e 6e 4d 61  Input[pWord->nMa
8dd0: 74 63 68 2b 69 5d 26 30 78 63 30 29 3d 3d 30 78  tch+i]&0xc0)==0x
8de0: 38 30 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20  80; i++){.      
8df0: 20 20 7a 4e 65 78 74 49 6e 5b 69 5d 20 3d 20 70    zNextIn[i] = p
8e00: 43 75 72 2d 3e 7a 49 6e 70 75 74 5b 70 57 6f 72  Cur->zInput[pWor
8e10: 64 2d 3e 6e 4d 61 74 63 68 2b 69 5d 3b 0a 20 20  d->nMatch+i];.  
8e20: 20 20 20 20 7d 0a 20 20 20 20 20 20 7a 4e 65 78      }.      zNex
8e30: 74 49 6e 5b 69 5d 20 3d 20 30 3b 0a 20 20 20 20  tIn[i] = 0;.    
8e40: 20 20 6e 4e 65 78 74 49 6e 20 3d 20 69 3b 0a 20    nNextIn = i;. 
8e50: 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20     }else{.      
8e60: 6e 4e 65 78 74 49 6e 20 3d 20 30 3b 0a 20 20 20  nNextIn = 0;.   
8e70: 20 7d 0a 0a 20 20 20 20 69 66 28 20 7a 4e 65 78   }..    if( zNex
8e80: 74 49 6e 5b 30 5d 20 26 26 20 7a 4e 65 78 74 49  tIn[0] && zNextI
8e90: 6e 5b 30 5d 21 3d 27 2a 27 20 29 7b 0a 20 20 20  n[0]!='*' ){.   
8ea0: 20 20 20 73 71 6c 69 74 65 33 5f 72 65 73 65 74     sqlite3_reset
8eb0: 28 70 2d 3e 70 56 43 68 65 63 6b 29 3b 0a 20 20  (p->pVCheck);.  
8ec0: 20 20 20 20 61 6d 61 74 63 68 53 74 72 63 61 74      amatchStrcat
8ed0: 28 7a 42 75 66 2c 20 7a 4e 65 78 74 49 6e 29 3b  (zBuf, zNextIn);
8ee0: 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 62  .      sqlite3_b
8ef0: 69 6e 64 5f 74 65 78 74 28 70 2d 3e 70 56 43 68  ind_text(p->pVCh
8f00: 65 63 6b 2c 20 31 2c 20 7a 42 75 66 2c 20 6e 57  eck, 1, zBuf, nW
8f10: 6f 72 64 2b 6e 4e 65 78 74 49 6e 2c 20 53 51 4c  ord+nNextIn, SQL
8f20: 49 54 45 5f 53 54 41 54 49 43 29 3b 0a 20 20 20  ITE_STATIC);.   
8f30: 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f     rc = sqlite3_
8f40: 73 74 65 70 28 70 2d 3e 70 56 43 68 65 63 6b 29  step(p->pVCheck)
8f50: 3b 0a 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d  ;.      if( rc==
8f60: 53 51 4c 49 54 45 5f 52 4f 57 20 29 7b 0a 20 20  SQLITE_ROW ){.  
8f70: 20 20 20 20 20 20 7a 57 20 3d 20 28 63 6f 6e 73        zW = (cons
8f80: 74 20 63 68 61 72 2a 29 73 71 6c 69 74 65 33 5f  t char*)sqlite3_
8f90: 63 6f 6c 75 6d 6e 5f 74 65 78 74 28 70 2d 3e 70  column_text(p->p
8fa0: 56 43 68 65 63 6b 2c 20 30 29 3b 0a 20 20 20 20  VCheck, 0);.    
8fb0: 20 20 20 20 69 66 28 20 73 74 72 6e 63 6d 70 28      if( strncmp(
8fc0: 7a 42 75 66 2c 20 7a 57 2c 20 6e 57 6f 72 64 2b  zBuf, zW, nWord+
8fd0: 6e 4e 65 78 74 49 6e 29 3d 3d 30 20 29 7b 0a 20  nNextIn)==0 ){. 
8fe0: 20 20 20 20 20 20 20 20 20 61 6d 61 74 63 68 41           amatchA
8ff0: 64 64 57 6f 72 64 28 70 43 75 72 2c 20 70 57 6f  ddWord(pCur, pWo
9000: 72 64 2d 3e 72 43 6f 73 74 2c 20 70 57 6f 72 64  rd->rCost, pWord
9010: 2d 3e 6e 4d 61 74 63 68 2b 6e 4e 65 78 74 49 6e  ->nMatch+nNextIn
9020: 2c 20 7a 42 75 66 2c 20 22 22 29 3b 0a 20 20 20  , zBuf, "");.   
9030: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7d 0a 20       }.      }. 
9040: 20 20 20 20 20 7a 42 75 66 5b 6e 57 6f 72 64 5d       zBuf[nWord]
9050: 20 3d 20 30 3b 0a 20 20 20 20 7d 0a 0a 20 20 20   = 0;.    }..   
9060: 20 77 68 69 6c 65 28 20 31 20 29 7b 0a 20 20 20   while( 1 ){.   
9070: 20 20 20 61 6d 61 74 63 68 53 74 72 63 70 79 28     amatchStrcpy(
9080: 7a 42 75 66 2b 6e 57 6f 72 64 2c 20 7a 4e 65 78  zBuf+nWord, zNex
9090: 74 29 3b 0a 20 20 20 20 20 20 73 71 6c 69 74 65  t);.      sqlite
90a0: 33 5f 72 65 73 65 74 28 70 2d 3e 70 56 43 68 65  3_reset(p->pVChe
90b0: 63 6b 29 3b 0a 20 20 20 20 20 20 73 71 6c 69 74  ck);.      sqlit
90c0: 65 33 5f 62 69 6e 64 5f 74 65 78 74 28 70 2d 3e  e3_bind_text(p->
90d0: 70 56 43 68 65 63 6b 2c 20 31 2c 20 7a 42 75 66  pVCheck, 1, zBuf
90e0: 2c 20 2d 31 2c 20 53 51 4c 49 54 45 5f 54 52 41  , -1, SQLITE_TRA
90f0: 4e 53 49 45 4e 54 29 3b 0a 20 20 20 20 20 20 72  NSIENT);.      r
9100: 63 20 3d 20 73 71 6c 69 74 65 33 5f 73 74 65 70  c = sqlite3_step
9110: 28 70 2d 3e 70 56 43 68 65 63 6b 29 3b 0a 20 20  (p->pVCheck);.  
9120: 20 20 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49      if( rc!=SQLI
9130: 54 45 5f 52 4f 57 20 29 20 62 72 65 61 6b 3b 0a  TE_ROW ) break;.
9140: 20 20 20 20 20 20 7a 57 20 3d 20 28 63 6f 6e 73        zW = (cons
9150: 74 20 63 68 61 72 2a 29 73 71 6c 69 74 65 33 5f  t char*)sqlite3_
9160: 63 6f 6c 75 6d 6e 5f 74 65 78 74 28 70 2d 3e 70  column_text(p->p
9170: 56 43 68 65 63 6b 2c 20 30 29 3b 0a 20 20 20 20  VCheck, 0);.    
9180: 20 20 61 6d 61 74 63 68 53 74 72 63 70 79 28 7a    amatchStrcpy(z
9190: 42 75 66 2b 6e 57 6f 72 64 2c 20 7a 4e 65 78 74  Buf+nWord, zNext
91a0: 29 3b 0a 20 20 20 20 20 20 69 66 28 20 73 74 72  );.      if( str
91b0: 6e 63 6d 70 28 7a 57 2c 20 7a 42 75 66 2c 20 6e  ncmp(zW, zBuf, n
91c0: 57 6f 72 64 29 21 3d 30 20 29 20 62 72 65 61 6b  Word)!=0 ) break
91d0: 3b 0a 20 20 20 20 20 20 69 66 28 20 28 7a 4e 65  ;.      if( (zNe
91e0: 78 74 49 6e 5b 30 5d 3d 3d 27 2a 27 20 26 26 20  xtIn[0]=='*' && 
91f0: 7a 4e 65 78 74 49 6e 5b 31 5d 3d 3d 30 29 0a 20  zNextIn[1]==0). 
9200: 20 20 20 20 20 20 7c 7c 20 28 7a 4e 65 78 74 49        || (zNextI
9210: 6e 5b 30 5d 3d 3d 30 20 26 26 20 7a 57 5b 6e 57  n[0]==0 && zW[nW
9220: 6f 72 64 5d 3d 3d 30 29 0a 20 20 20 20 20 20 29  ord]==0).      )
9230: 7b 0a 20 20 20 20 20 20 20 20 69 73 4d 61 74 63  {.        isMatc
9240: 68 20 3d 20 31 3b 0a 20 20 20 20 20 20 20 20 7a  h = 1;.        z
9250: 4e 65 78 74 49 6e 5b 30 5d 20 3d 20 30 3b 0a 20  NextIn[0] = 0;. 
9260: 20 20 20 20 20 20 20 6e 4e 65 78 74 49 6e 20 3d         nNextIn =
9270: 20 30 3b 0a 20 20 20 20 20 20 20 20 62 72 65 61   0;.        brea
9280: 6b 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20  k;.      }.     
9290: 20 7a 4e 65 78 74 5b 30 5d 20 3d 20 7a 57 5b 6e   zNext[0] = zW[n
92a0: 57 6f 72 64 5d 3b 0a 20 20 20 20 20 20 66 6f 72  Word];.      for
92b0: 28 69 3d 31 3b 20 69 3c 3d 34 20 26 26 20 28 7a  (i=1; i<=4 && (z
92c0: 57 5b 6e 57 6f 72 64 2b 69 5d 26 30 78 63 30 29  W[nWord+i]&0xc0)
92d0: 3d 3d 30 78 38 30 3b 20 69 2b 2b 29 7b 0a 20 20  ==0x80; i++){.  
92e0: 20 20 20 20 20 20 7a 4e 65 78 74 5b 69 5d 20 3d        zNext[i] =
92f0: 20 7a 57 5b 6e 57 6f 72 64 2b 69 5d 3b 0a 20 20   zW[nWord+i];.  
9300: 20 20 20 20 7d 0a 20 20 20 20 20 20 7a 4e 65 78      }.      zNex
9310: 74 5b 69 5d 20 3d 20 30 3b 0a 20 20 20 20 20 20  t[i] = 0;.      
9320: 7a 42 75 66 5b 6e 57 6f 72 64 5d 20 3d 20 30 3b  zBuf[nWord] = 0;
9330: 0a 20 20 20 20 20 20 69 66 28 20 70 2d 3e 72 49  .      if( p->rI
9340: 6e 73 3e 30 20 29 7b 0a 20 20 20 20 20 20 20 20  ns>0 ){.        
9350: 61 6d 61 74 63 68 41 64 64 57 6f 72 64 28 70 43  amatchAddWord(pC
9360: 75 72 2c 20 70 57 6f 72 64 2d 3e 72 43 6f 73 74  ur, pWord->rCost
9370: 2b 70 2d 3e 72 49 6e 73 2c 20 70 57 6f 72 64 2d  +p->rIns, pWord-
9380: 3e 6e 4d 61 74 63 68 2c 20 0a 20 20 20 20 20 20  >nMatch, .      
9390: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
93a0: 7a 42 75 66 2c 20 7a 4e 65 78 74 29 3b 0a 20 20  zBuf, zNext);.  
93b0: 20 20 20 20 7d 0a 20 20 20 20 20 20 69 66 28 20      }.      if( 
93c0: 70 2d 3e 72 53 75 62 3e 30 20 29 7b 0a 20 20 20  p->rSub>0 ){.   
93d0: 20 20 20 20 20 61 6d 61 74 63 68 41 64 64 57 6f       amatchAddWo
93e0: 72 64 28 70 43 75 72 2c 20 70 57 6f 72 64 2d 3e  rd(pCur, pWord->
93f0: 72 43 6f 73 74 2b 70 2d 3e 72 53 75 62 2c 20 70  rCost+p->rSub, p
9400: 57 6f 72 64 2d 3e 6e 4d 61 74 63 68 2b 6e 4e 65  Word->nMatch+nNe
9410: 78 74 49 6e 2c 20 0a 20 20 20 20 20 20 20 20 20  xtIn, .         
9420: 20 20 20 20 20 20 20 20 20 20 20 20 20 7a 42 75               zBu
9430: 66 2c 20 7a 4e 65 78 74 29 3b 0a 20 20 20 20 20  f, zNext);.     
9440: 20 7d 0a 20 20 20 20 20 20 69 66 28 20 70 2d 3e   }.      if( p->
9450: 72 49 6e 73 3c 30 20 26 26 20 70 2d 3e 72 53 75  rIns<0 && p->rSu
9460: 62 3c 30 20 29 20 62 72 65 61 6b 3b 0a 20 20 20  b<0 ) break;.   
9470: 20 20 20 7a 4e 65 78 74 5b 69 2d 31 5d 2b 2b 3b     zNext[i-1]++;
9480: 20 20 2f 2a 20 46 49 58 20 4d 45 20 2a 2f 0a 20    /* FIX ME */. 
9490: 20 20 20 7d 0a 20 20 20 20 73 71 6c 69 74 65 33     }.    sqlite3
94a0: 5f 72 65 73 65 74 28 70 2d 3e 70 56 43 68 65 63  _reset(p->pVChec
94b0: 6b 29 3b 0a 0a 20 20 20 20 69 66 28 20 70 2d 3e  k);..    if( p->
94c0: 72 44 65 6c 3e 30 20 29 7b 0a 20 20 20 20 20 20  rDel>0 ){.      
94d0: 7a 42 75 66 5b 6e 57 6f 72 64 5d 20 3d 20 30 3b  zBuf[nWord] = 0;
94e0: 0a 20 20 20 20 20 20 61 6d 61 74 63 68 41 64 64  .      amatchAdd
94f0: 57 6f 72 64 28 70 43 75 72 2c 20 70 57 6f 72 64  Word(pCur, pWord
9500: 2d 3e 72 43 6f 73 74 2b 70 2d 3e 72 44 65 6c 2c  ->rCost+p->rDel,
9510: 20 70 57 6f 72 64 2d 3e 6e 4d 61 74 63 68 2b 6e   pWord->nMatch+n
9520: 4e 65 78 74 49 6e 2c 0a 20 20 20 20 20 20 20 20  NextIn,.        
9530: 20 20 20 20 20 20 20 20 20 20 20 20 7a 42 75 66              zBuf
9540: 2c 20 22 22 29 3b 0a 20 20 20 20 7d 0a 0a 20 20  , "");.    }..  
9550: 20 20 66 6f 72 28 70 52 75 6c 65 3d 70 2d 3e 70    for(pRule=p->p
9560: 52 75 6c 65 3b 20 70 52 75 6c 65 3b 20 70 52 75  Rule; pRule; pRu
9570: 6c 65 3d 70 52 75 6c 65 2d 3e 70 4e 65 78 74 29  le=pRule->pNext)
9580: 7b 0a 20 20 20 20 20 20 69 66 28 20 70 52 75 6c  {.      if( pRul
9590: 65 2d 3e 69 4c 61 6e 67 21 3d 70 43 75 72 2d 3e  e->iLang!=pCur->
95a0: 69 4c 61 6e 67 20 29 20 63 6f 6e 74 69 6e 75 65  iLang ) continue
95b0: 3b 0a 20 20 20 20 20 20 69 66 28 20 73 74 72 6e  ;.      if( strn
95c0: 63 6d 70 28 70 52 75 6c 65 2d 3e 7a 46 72 6f 6d  cmp(pRule->zFrom
95d0: 2c 20 70 43 75 72 2d 3e 7a 49 6e 70 75 74 2b 70  , pCur->zInput+p
95e0: 57 6f 72 64 2d 3e 6e 4d 61 74 63 68 2c 20 70 52  Word->nMatch, pR
95f0: 75 6c 65 2d 3e 6e 46 72 6f 6d 29 3d 3d 30 20 29  ule->nFrom)==0 )
9600: 7b 0a 20 20 20 20 20 20 20 20 61 6d 61 74 63 68  {.        amatch
9610: 41 64 64 57 6f 72 64 28 70 43 75 72 2c 20 70 57  AddWord(pCur, pW
9620: 6f 72 64 2d 3e 72 43 6f 73 74 2b 70 52 75 6c 65  ord->rCost+pRule
9630: 2d 3e 72 43 6f 73 74 2c 0a 20 20 20 20 20 20 20  ->rCost,.       
9640: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 70                 p
9650: 57 6f 72 64 2d 3e 6e 4d 61 74 63 68 2b 70 52 75  Word->nMatch+pRu
9660: 6c 65 2d 3e 6e 46 72 6f 6d 2c 20 70 57 6f 72 64  le->nFrom, pWord
9670: 2d 3e 7a 57 6f 72 64 2b 32 2c 20 70 52 75 6c 65  ->zWord+2, pRule
9680: 2d 3e 7a 54 6f 29 3b 0a 20 20 20 20 20 20 7d 0a  ->zTo);.      }.
9690: 20 20 20 20 7d 0a 20 20 7d 77 68 69 6c 65 28 20      }.  }while( 
96a0: 21 69 73 4d 61 74 63 68 20 29 3b 0a 20 20 70 43  !isMatch );.  pC
96b0: 75 72 2d 3e 70 43 75 72 72 65 6e 74 20 3d 20 70  ur->pCurrent = p
96c0: 57 6f 72 64 3b 0a 20 20 73 71 6c 69 74 65 33 5f  Word;.  sqlite3_
96d0: 66 72 65 65 28 7a 42 75 66 29 3b 0a 20 20 72 65  free(zBuf);.  re
96e0: 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a  turn SQLITE_OK;.
96f0: 7d 0a 0a 2f 2a 0a 2a 2a 20 43 61 6c 6c 65 64 20  }../*.** Called 
9700: 74 6f 20 22 72 65 77 69 6e 64 22 20 61 20 63 75  to "rewind" a cu
9710: 72 73 6f 72 20 62 61 63 6b 20 74 6f 20 74 68 65  rsor back to the
9720: 20 62 65 67 69 6e 6e 69 6e 67 20 73 6f 20 74 68   beginning so th
9730: 61 74 0a 2a 2a 20 69 74 20 73 74 61 72 74 73 20  at.** it starts 
9740: 69 74 73 20 6f 75 74 70 75 74 20 6f 76 65 72 20  its output over 
9750: 61 67 61 69 6e 2e 20 20 41 6c 77 61 79 73 20 63  again.  Always c
9760: 61 6c 6c 65 64 20 61 74 20 6c 65 61 73 74 20 6f  alled at least o
9770: 6e 63 65 0a 2a 2a 20 70 72 69 6f 72 20 74 6f 20  nce.** prior to 
9780: 61 6e 79 20 61 6d 61 74 63 68 43 6f 6c 75 6d 6e  any amatchColumn
9790: 2c 20 61 6d 61 74 63 68 52 6f 77 69 64 2c 20 6f  , amatchRowid, o
97a0: 72 20 61 6d 61 74 63 68 45 6f 66 20 63 61 6c 6c  r amatchEof call
97b0: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
97c0: 61 6d 61 74 63 68 46 69 6c 74 65 72 28 0a 20 20  amatchFilter(.  
97d0: 73 71 6c 69 74 65 33 5f 76 74 61 62 5f 63 75 72  sqlite3_vtab_cur
97e0: 73 6f 72 20 2a 70 56 74 61 62 43 75 72 73 6f 72  sor *pVtabCursor
97f0: 2c 20 0a 20 20 69 6e 74 20 69 64 78 4e 75 6d 2c  , .  int idxNum,
9800: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 69 64 78   const char *idx
9810: 53 74 72 2c 0a 20 20 69 6e 74 20 61 72 67 63 2c  Str,.  int argc,
9820: 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 20 2a   sqlite3_value *
9830: 2a 61 72 67 76 0a 29 7b 0a 20 20 61 6d 61 74 63  *argv.){.  amatc
9840: 68 5f 63 75 72 73 6f 72 20 2a 70 43 75 72 20 3d  h_cursor *pCur =
9850: 20 28 61 6d 61 74 63 68 5f 63 75 72 73 6f 72 20   (amatch_cursor 
9860: 2a 29 70 56 74 61 62 43 75 72 73 6f 72 3b 0a 20  *)pVtabCursor;. 
9870: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 57 6f   const char *zWo
9880: 72 64 20 3d 20 22 2a 22 3b 0a 20 20 69 6e 74 20  rd = "*";.  int 
9890: 69 64 78 3b 0a 0a 20 20 61 6d 61 74 63 68 43 6c  idx;..  amatchCl
98a0: 65 61 72 43 75 72 73 6f 72 28 70 43 75 72 29 3b  earCursor(pCur);
98b0: 0a 20 20 69 64 78 20 3d 20 30 3b 0a 20 20 69 66  .  idx = 0;.  if
98c0: 28 20 69 64 78 4e 75 6d 20 26 20 31 20 29 7b 0a  ( idxNum & 1 ){.
98d0: 20 20 20 20 7a 57 6f 72 64 20 3d 20 28 63 6f 6e      zWord = (con
98e0: 73 74 20 63 68 61 72 2a 29 73 71 6c 69 74 65 33  st char*)sqlite3
98f0: 5f 76 61 6c 75 65 5f 74 65 78 74 28 61 72 67 76  _value_text(argv
9900: 5b 30 5d 29 3b 0a 20 20 20 20 69 64 78 2b 2b 3b  [0]);.    idx++;
9910: 0a 20 20 7d 0a 20 20 69 66 28 20 69 64 78 4e 75  .  }.  if( idxNu
9920: 6d 20 26 20 32 20 29 7b 0a 20 20 20 20 70 43 75  m & 2 ){.    pCu
9930: 72 2d 3e 72 4c 69 6d 69 74 20 3d 20 28 61 6d 61  r->rLimit = (ama
9940: 74 63 68 5f 63 6f 73 74 29 73 71 6c 69 74 65 33  tch_cost)sqlite3
9950: 5f 76 61 6c 75 65 5f 69 6e 74 28 61 72 67 76 5b  _value_int(argv[
9960: 69 64 78 5d 29 3b 0a 20 20 20 20 69 64 78 2b 2b  idx]);.    idx++
9970: 3b 0a 20 20 7d 0a 20 20 69 66 28 20 69 64 78 4e  ;.  }.  if( idxN
9980: 75 6d 20 26 20 34 20 29 7b 0a 20 20 20 20 70 43  um & 4 ){.    pC
9990: 75 72 2d 3e 69 4c 61 6e 67 20 3d 20 28 61 6d 61  ur->iLang = (ama
99a0: 74 63 68 5f 63 6f 73 74 29 73 71 6c 69 74 65 33  tch_cost)sqlite3
99b0: 5f 76 61 6c 75 65 5f 69 6e 74 28 61 72 67 76 5b  _value_int(argv[
99c0: 69 64 78 5d 29 3b 0a 20 20 20 20 69 64 78 2b 2b  idx]);.    idx++
99d0: 3b 0a 20 20 7d 0a 20 20 70 43 75 72 2d 3e 7a 49  ;.  }.  pCur->zI
99e0: 6e 70 75 74 20 3d 20 73 71 6c 69 74 65 33 5f 6d  nput = sqlite3_m
99f0: 70 72 69 6e 74 66 28 22 25 73 22 2c 20 7a 57 6f  printf("%s", zWo
9a00: 72 64 29 3b 0a 20 20 69 66 28 20 70 43 75 72 2d  rd);.  if( pCur-
9a10: 3e 7a 49 6e 70 75 74 3d 3d 30 20 29 20 72 65 74  >zInput==0 ) ret
9a20: 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d  urn SQLITE_NOMEM
9a30: 3b 0a 20 20 61 6d 61 74 63 68 41 64 64 57 6f 72  ;.  amatchAddWor
9a40: 64 28 70 43 75 72 2c 20 30 2c 20 30 2c 20 22 22  d(pCur, 0, 0, ""
9a50: 2c 20 22 22 29 3b 0a 20 20 61 6d 61 74 63 68 4e  , "");.  amatchN
9a60: 65 78 74 28 70 56 74 61 62 43 75 72 73 6f 72 29  ext(pVtabCursor)
9a70: 3b 0a 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49  ;..  return SQLI
9a80: 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  TE_OK;.}../*.** 
9a90: 4f 6e 6c 79 20 74 68 65 20 77 6f 72 64 20 61 6e  Only the word an
9aa0: 64 20 64 69 73 74 61 6e 63 65 20 63 6f 6c 75 6d  d distance colum
9ab0: 6e 73 20 68 61 76 65 20 76 61 6c 75 65 73 2e 20  ns have values. 
9ac0: 20 41 6c 6c 20 6f 74 68 65 72 20 63 6f 6c 75 6d   All other colum
9ad0: 6e 73 0a 2a 2a 20 72 65 74 75 72 6e 20 4e 55 4c  ns.** return NUL
9ae0: 4c 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  L.*/.static int 
9af0: 61 6d 61 74 63 68 43 6f 6c 75 6d 6e 28 73 71 6c  amatchColumn(sql
9b00: 69 74 65 33 5f 76 74 61 62 5f 63 75 72 73 6f 72  ite3_vtab_cursor
9b10: 20 2a 63 75 72 2c 20 73 71 6c 69 74 65 33 5f 63   *cur, sqlite3_c
9b20: 6f 6e 74 65 78 74 20 2a 63 74 78 2c 20 69 6e 74  ontext *ctx, int
9b30: 20 69 29 7b 0a 20 20 61 6d 61 74 63 68 5f 63 75   i){.  amatch_cu
9b40: 72 73 6f 72 20 2a 70 43 75 72 20 3d 20 28 61 6d  rsor *pCur = (am
9b50: 61 74 63 68 5f 63 75 72 73 6f 72 2a 29 63 75 72  atch_cursor*)cur
9b60: 3b 0a 20 20 73 77 69 74 63 68 28 20 69 20 29 7b  ;.  switch( i ){
9b70: 0a 20 20 20 20 63 61 73 65 20 41 4d 41 54 43 48  .    case AMATCH
9b80: 5f 43 4f 4c 5f 57 4f 52 44 3a 20 7b 0a 20 20 20  _COL_WORD: {.   
9b90: 20 20 20 73 71 6c 69 74 65 33 5f 72 65 73 75 6c     sqlite3_resul
9ba0: 74 5f 74 65 78 74 28 63 74 78 2c 20 70 43 75 72  t_text(ctx, pCur
9bb0: 2d 3e 70 43 75 72 72 65 6e 74 2d 3e 7a 57 6f 72  ->pCurrent->zWor
9bc0: 64 2b 32 2c 20 2d 31 2c 20 53 51 4c 49 54 45 5f  d+2, -1, SQLITE_
9bd0: 53 54 41 54 49 43 29 3b 0a 20 20 20 20 20 20 62  STATIC);.      b
9be0: 72 65 61 6b 3b 0a 20 20 20 20 7d 0a 20 20 20 20  reak;.    }.    
9bf0: 63 61 73 65 20 41 4d 41 54 43 48 5f 43 4f 4c 5f  case AMATCH_COL_
9c00: 44 49 53 54 41 4e 43 45 3a 20 7b 0a 20 20 20 20  DISTANCE: {.    
9c10: 20 20 73 71 6c 69 74 65 33 5f 72 65 73 75 6c 74    sqlite3_result
9c20: 5f 69 6e 74 28 63 74 78 2c 20 70 43 75 72 2d 3e  _int(ctx, pCur->
9c30: 70 43 75 72 72 65 6e 74 2d 3e 72 43 6f 73 74 29  pCurrent->rCost)
9c40: 3b 0a 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20  ;.      break;. 
9c50: 20 20 20 7d 0a 20 20 20 20 63 61 73 65 20 41 4d     }.    case AM
9c60: 41 54 43 48 5f 43 4f 4c 5f 4c 41 4e 47 55 41 47  ATCH_COL_LANGUAG
9c70: 45 3a 20 7b 0a 20 20 20 20 20 20 73 71 6c 69 74  E: {.      sqlit
9c80: 65 33 5f 72 65 73 75 6c 74 5f 69 6e 74 28 63 74  e3_result_int(ct
9c90: 78 2c 20 70 43 75 72 2d 3e 69 4c 61 6e 67 29 3b  x, pCur->iLang);
9ca0: 0a 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20  .      break;.  
9cb0: 20 20 7d 0a 20 20 20 20 63 61 73 65 20 41 4d 41    }.    case AMA
9cc0: 54 43 48 5f 43 4f 4c 5f 4e 57 4f 52 44 3a 20 7b  TCH_COL_NWORD: {
9cd0: 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 72  .      sqlite3_r
9ce0: 65 73 75 6c 74 5f 69 6e 74 28 63 74 78 2c 20 70  esult_int(ctx, p
9cf0: 43 75 72 2d 3e 6e 57 6f 72 64 29 3b 0a 20 20 20  Cur->nWord);.   
9d00: 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 7d 0a     break;.    }.
9d10: 20 20 20 20 64 65 66 61 75 6c 74 3a 20 7b 0a 20      default: {. 
9d20: 20 20 20 20 20 73 71 6c 69 74 65 33 5f 72 65 73       sqlite3_res
9d30: 75 6c 74 5f 6e 75 6c 6c 28 63 74 78 29 3b 0a 20  ult_null(ctx);. 
9d40: 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20       break;.    
9d50: 7d 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 53  }.  }.  return S
9d60: 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a  QLITE_OK;.}../*.
9d70: 2a 2a 20 54 68 65 20 72 6f 77 69 64 2e 0a 2a 2f  ** The rowid..*/
9d80: 0a 73 74 61 74 69 63 20 69 6e 74 20 61 6d 61 74  .static int amat
9d90: 63 68 52 6f 77 69 64 28 73 71 6c 69 74 65 33 5f  chRowid(sqlite3_
9da0: 76 74 61 62 5f 63 75 72 73 6f 72 20 2a 63 75 72  vtab_cursor *cur
9db0: 2c 20 73 71 6c 69 74 65 5f 69 6e 74 36 34 20 2a  , sqlite_int64 *
9dc0: 70 52 6f 77 69 64 29 7b 0a 20 20 61 6d 61 74 63  pRowid){.  amatc
9dd0: 68 5f 63 75 72 73 6f 72 20 2a 70 43 75 72 20 3d  h_cursor *pCur =
9de0: 20 28 61 6d 61 74 63 68 5f 63 75 72 73 6f 72 2a   (amatch_cursor*
9df0: 29 63 75 72 3b 0a 20 20 2a 70 52 6f 77 69 64 20  )cur;.  *pRowid 
9e00: 3d 20 70 43 75 72 2d 3e 69 52 6f 77 69 64 3b 0a  = pCur->iRowid;.
9e10: 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f    return SQLITE_
9e20: 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 45 4f 46  OK;.}../*.** EOF
9e30: 20 69 6e 64 69 63 61 74 6f 72 0a 2a 2f 0a 73 74   indicator.*/.st
9e40: 61 74 69 63 20 69 6e 74 20 61 6d 61 74 63 68 45  atic int amatchE
9e50: 6f 66 28 73 71 6c 69 74 65 33 5f 76 74 61 62 5f  of(sqlite3_vtab_
9e60: 63 75 72 73 6f 72 20 2a 63 75 72 29 7b 0a 20 20  cursor *cur){.  
9e70: 61 6d 61 74 63 68 5f 63 75 72 73 6f 72 20 2a 70  amatch_cursor *p
9e80: 43 75 72 20 3d 20 28 61 6d 61 74 63 68 5f 63 75  Cur = (amatch_cu
9e90: 72 73 6f 72 2a 29 63 75 72 3b 0a 20 20 72 65 74  rsor*)cur;.  ret
9ea0: 75 72 6e 20 70 43 75 72 2d 3e 70 43 75 72 72 65  urn pCur->pCurre
9eb0: 6e 74 3d 3d 30 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  nt==0;.}../*.** 
9ec0: 53 65 61 72 63 68 20 66 6f 72 20 74 65 72 6d 73  Search for terms
9ed0: 20 6f 66 20 74 68 65 73 65 20 66 6f 72 6d 73 3a   of these forms:
9ee0: 0a 2a 2a 0a 2a 2a 20 20 20 28 41 29 20 20 20 20  .**.**   (A)    
9ef0: 77 6f 72 64 20 4d 41 54 43 48 20 24 73 74 72 0a  word MATCH $str.
9f00: 2a 2a 20 20 20 28 42 31 29 20 20 20 64 69 73 74  **   (B1)   dist
9f10: 61 6e 63 65 20 3c 20 24 76 61 6c 75 65 0a 2a 2a  ance < $value.**
9f20: 20 20 20 28 42 32 29 20 20 20 64 69 73 74 61 6e     (B2)   distan
9f30: 63 65 20 3c 3d 20 24 76 61 6c 75 65 0a 2a 2a 20  ce <= $value.** 
9f40: 20 20 28 43 29 20 20 20 20 6c 61 6e 67 75 61 67    (C)    languag
9f50: 65 20 3d 3d 20 24 6c 61 6e 67 75 61 67 65 0a 2a  e == $language.*
9f60: 2a 0a 2a 2a 20 54 68 65 20 64 69 73 74 61 6e 63  *.** The distanc
9f70: 65 3c 20 61 6e 64 20 64 69 73 74 61 6e 63 65 3c  e< and distance<
9f80: 3d 20 61 72 65 20 62 6f 74 68 20 74 72 65 61 74  = are both treat
9f90: 65 64 20 61 73 20 64 69 73 74 61 6e 63 65 3c 3d  ed as distance<=
9fa0: 2e 0a 2a 2a 20 54 68 65 20 71 75 65 72 79 20 70  ..** The query p
9fb0: 6c 61 6e 20 6e 75 6d 62 65 72 20 69 73 20 61 20  lan number is a 
9fc0: 62 69 74 20 76 65 63 74 6f 72 3a 0a 2a 2a 0a 2a  bit vector:.**.*
9fd0: 2a 20 20 20 62 69 74 20 31 3a 20 20 20 54 65 72  *   bit 1:   Ter
9fe0: 6d 20 6f 66 20 74 68 65 20 66 6f 72 6d 20 28 41  m of the form (A
9ff0: 29 20 66 6f 75 6e 64 0a 2a 2a 20 20 20 62 69 74  ) found.**   bit
a000: 20 32 3a 20 20 20 54 65 72 6d 20 6c 69 6b 65 20   2:   Term like 
a010: 28 42 31 29 20 6f 72 20 28 42 32 29 20 66 6f 75  (B1) or (B2) fou
a020: 6e 64 0a 2a 2a 20 20 20 62 69 74 20 33 3a 20 20  nd.**   bit 3:  
a030: 20 54 65 72 6d 20 6c 69 6b 65 20 28 43 29 20 66   Term like (C) f
a040: 6f 75 6e 64 0a 2a 2a 0a 2a 2a 20 49 66 20 62 69  ound.**.** If bi
a050: 74 2d 31 20 69 73 20 73 65 74 2c 20 24 73 74 72  t-1 is set, $str
a060: 20 69 73 20 61 6c 77 61 79 73 20 69 6e 20 66 69   is always in fi
a070: 6c 74 65 72 2e 61 72 67 76 5b 30 5d 2e 20 20 49  lter.argv[0].  I
a080: 66 20 62 69 74 2d 32 20 69 73 20 73 65 74 0a 2a  f bit-2 is set.*
a090: 2a 20 74 68 65 6e 20 24 76 61 6c 75 65 20 69 73  * then $value is
a0a0: 20 69 6e 20 66 69 6c 74 65 72 2e 61 72 67 76 5b   in filter.argv[
a0b0: 30 5d 20 69 66 20 62 69 74 2d 31 20 69 73 20 63  0] if bit-1 is c
a0c0: 6c 65 61 72 20 61 6e 64 20 69 73 20 69 6e 20 0a  lear and is in .
a0d0: 2a 2a 20 66 69 6c 74 65 72 2e 61 72 67 76 5b 31  ** filter.argv[1
a0e0: 5d 20 69 66 20 62 69 74 2d 31 20 69 73 20 73 65  ] if bit-1 is se
a0f0: 74 2e 20 20 49 66 20 62 69 74 2d 33 20 69 73 20  t.  If bit-3 is 
a100: 73 65 74 2c 20 74 68 65 6e 20 24 72 75 6c 65 69  set, then $rulei
a110: 64 20 69 73 0a 2a 2a 20 69 6e 20 66 69 6c 74 65  d is.** in filte
a120: 72 2e 61 72 67 76 5b 30 5d 20 69 66 20 62 69 74  r.argv[0] if bit
a130: 2d 31 20 61 6e 64 20 62 69 74 2d 32 20 61 72 65  -1 and bit-2 are
a140: 20 62 6f 74 68 20 7a 65 72 6f 2c 20 69 73 20 69   both zero, is i
a150: 6e 0a 2a 2a 20 66 69 6c 74 65 72 2e 61 72 67 76  n.** filter.argv
a160: 5b 31 5d 20 69 66 20 65 78 61 63 74 6c 79 20 6f  [1] if exactly o
a170: 6e 65 20 6f 66 20 62 69 74 2d 31 20 61 6e 64 20  ne of bit-1 and 
a180: 62 69 74 2d 32 20 61 72 65 20 73 65 74 2c 20 61  bit-2 are set, a
a190: 6e 64 20 69 73 20 69 6e 0a 2a 2a 20 66 69 6c 74  nd is in.** filt
a1a0: 65 72 2e 61 72 67 76 5b 32 5d 20 69 66 20 62 6f  er.argv[2] if bo
a1b0: 74 68 20 62 69 74 2d 31 20 61 6e 64 20 62 69 74  th bit-1 and bit
a1c0: 2d 32 20 61 72 65 20 73 65 74 2e 0a 2a 2f 0a 73  -2 are set..*/.s
a1d0: 74 61 74 69 63 20 69 6e 74 20 61 6d 61 74 63 68  tatic int amatch
a1e0: 42 65 73 74 49 6e 64 65 78 28 0a 20 20 73 71 6c  BestIndex(.  sql
a1f0: 69 74 65 33 5f 76 74 61 62 20 2a 74 61 62 2c 0a  ite3_vtab *tab,.
a200: 20 20 73 71 6c 69 74 65 33 5f 69 6e 64 65 78 5f    sqlite3_index_
a210: 69 6e 66 6f 20 2a 70 49 64 78 49 6e 66 6f 0a 29  info *pIdxInfo.)
a220: 7b 0a 20 20 69 6e 74 20 69 50 6c 61 6e 20 3d 20  {.  int iPlan = 
a230: 30 3b 0a 20 20 69 6e 74 20 69 44 69 73 74 54 65  0;.  int iDistTe
a240: 72 6d 20 3d 20 2d 31 3b 0a 20 20 69 6e 74 20 69  rm = -1;.  int i
a250: 4c 61 6e 67 54 65 72 6d 20 3d 20 2d 31 3b 0a 20  LangTerm = -1;. 
a260: 20 69 6e 74 20 69 3b 0a 20 20 63 6f 6e 73 74 20   int i;.  const 
a270: 73 74 72 75 63 74 20 73 71 6c 69 74 65 33 5f 69  struct sqlite3_i
a280: 6e 64 65 78 5f 63 6f 6e 73 74 72 61 69 6e 74 20  ndex_constraint 
a290: 2a 70 43 6f 6e 73 74 72 61 69 6e 74 3b 0a 0a 20  *pConstraint;.. 
a2a0: 20 28 76 6f 69 64 29 74 61 62 3b 0a 20 20 70 43   (void)tab;.  pC
a2b0: 6f 6e 73 74 72 61 69 6e 74 20 3d 20 70 49 64 78  onstraint = pIdx
a2c0: 49 6e 66 6f 2d 3e 61 43 6f 6e 73 74 72 61 69 6e  Info->aConstrain
a2d0: 74 3b 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c  t;.  for(i=0; i<
a2e0: 70 49 64 78 49 6e 66 6f 2d 3e 6e 43 6f 6e 73 74  pIdxInfo->nConst
a2f0: 72 61 69 6e 74 3b 20 69 2b 2b 2c 20 70 43 6f 6e  raint; i++, pCon
a300: 73 74 72 61 69 6e 74 2b 2b 29 7b 0a 20 20 20 20  straint++){.    
a310: 69 66 28 20 70 43 6f 6e 73 74 72 61 69 6e 74 2d  if( pConstraint-
a320: 3e 75 73 61 62 6c 65 3d 3d 30 20 29 20 63 6f 6e  >usable==0 ) con
a330: 74 69 6e 75 65 3b 0a 20 20 20 20 69 66 28 20 28  tinue;.    if( (
a340: 69 50 6c 61 6e 20 26 20 31 29 3d 3d 30 20 0a 20  iPlan & 1)==0 . 
a350: 20 20 20 20 26 26 20 70 43 6f 6e 73 74 72 61 69      && pConstrai
a360: 6e 74 2d 3e 69 43 6f 6c 75 6d 6e 3d 3d 30 0a 20  nt->iColumn==0. 
a370: 20 20 20 20 26 26 20 70 43 6f 6e 73 74 72 61 69      && pConstrai
a380: 6e 74 2d 3e 6f 70 3d 3d 53 51 4c 49 54 45 5f 49  nt->op==SQLITE_I
a390: 4e 44 45 58 5f 43 4f 4e 53 54 52 41 49 4e 54 5f  NDEX_CONSTRAINT_
a3a0: 4d 41 54 43 48 0a 20 20 20 20 29 7b 0a 20 20 20  MATCH.    ){.   
a3b0: 20 20 20 69 50 6c 61 6e 20 7c 3d 20 31 3b 0a 20     iPlan |= 1;. 
a3c0: 20 20 20 20 20 70 49 64 78 49 6e 66 6f 2d 3e 61       pIdxInfo->a
a3d0: 43 6f 6e 73 74 72 61 69 6e 74 55 73 61 67 65 5b  ConstraintUsage[
a3e0: 69 5d 2e 61 72 67 76 49 6e 64 65 78 20 3d 20 31  i].argvIndex = 1
a3f0: 3b 0a 20 20 20 20 20 20 70 49 64 78 49 6e 66 6f  ;.      pIdxInfo
a400: 2d 3e 61 43 6f 6e 73 74 72 61 69 6e 74 55 73 61  ->aConstraintUsa
a410: 67 65 5b 69 5d 2e 6f 6d 69 74 20 3d 20 31 3b 0a  ge[i].omit = 1;.
a420: 20 20 20 20 7d 0a 20 20 20 20 69 66 28 20 28 69      }.    if( (i
a430: 50 6c 61 6e 20 26 20 32 29 3d 3d 30 0a 20 20 20  Plan & 2)==0.   
a440: 20 20 26 26 20 70 43 6f 6e 73 74 72 61 69 6e 74    && pConstraint
a450: 2d 3e 69 43 6f 6c 75 6d 6e 3d 3d 31 0a 20 20 20  ->iColumn==1.   
a460: 20 20 26 26 20 28 70 43 6f 6e 73 74 72 61 69 6e    && (pConstrain
a470: 74 2d 3e 6f 70 3d 3d 53 51 4c 49 54 45 5f 49 4e  t->op==SQLITE_IN
a480: 44 45 58 5f 43 4f 4e 53 54 52 41 49 4e 54 5f 4c  DEX_CONSTRAINT_L
a490: 54 0a 20 20 20 20 20 20 20 20 20 20 20 7c 7c 20  T.           || 
a4a0: 70 43 6f 6e 73 74 72 61 69 6e 74 2d 3e 6f 70 3d  pConstraint->op=
a4b0: 3d 53 51 4c 49 54 45 5f 49 4e 44 45 58 5f 43 4f  =SQLITE_INDEX_CO
a4c0: 4e 53 54 52 41 49 4e 54 5f 4c 45 29 0a 20 20 20  NSTRAINT_LE).   
a4d0: 20 29 7b 0a 20 20 20 20 20 20 69 50 6c 61 6e 20   ){.      iPlan 
a4e0: 7c 3d 20 32 3b 0a 20 20 20 20 20 20 69 44 69 73  |= 2;.      iDis
a4f0: 74 54 65 72 6d 20 3d 20 69 3b 0a 20 20 20 20 7d  tTerm = i;.    }
a500: 0a 20 20 20 20 69 66 28 20 28 69 50 6c 61 6e 20  .    if( (iPlan 
a510: 26 20 34 29 3d 3d 30 0a 20 20 20 20 20 26 26 20  & 4)==0.     && 
a520: 70 43 6f 6e 73 74 72 61 69 6e 74 2d 3e 69 43 6f  pConstraint->iCo
a530: 6c 75 6d 6e 3d 3d 32 0a 20 20 20 20 20 26 26 20  lumn==2.     && 
a540: 70 43 6f 6e 73 74 72 61 69 6e 74 2d 3e 6f 70 3d  pConstraint->op=
a550: 3d 53 51 4c 49 54 45 5f 49 4e 44 45 58 5f 43 4f  =SQLITE_INDEX_CO
a560: 4e 53 54 52 41 49 4e 54 5f 45 51 0a 20 20 20 20  NSTRAINT_EQ.    
a570: 29 7b 0a 20 20 20 20 20 20 69 50 6c 61 6e 20 7c  ){.      iPlan |
a580: 3d 20 34 3b 0a 20 20 20 20 20 20 70 49 64 78 49  = 4;.      pIdxI
a590: 6e 66 6f 2d 3e 61 43 6f 6e 73 74 72 61 69 6e 74  nfo->aConstraint
a5a0: 55 73 61 67 65 5b 69 5d 2e 6f 6d 69 74 20 3d 20  Usage[i].omit = 
a5b0: 31 3b 0a 20 20 20 20 20 20 69 4c 61 6e 67 54 65  1;.      iLangTe
a5c0: 72 6d 20 3d 20 69 3b 0a 20 20 20 20 7d 0a 20 20  rm = i;.    }.  
a5d0: 7d 0a 20 20 69 66 28 20 69 50 6c 61 6e 20 26 20  }.  if( iPlan & 
a5e0: 32 20 29 7b 0a 20 20 20 20 70 49 64 78 49 6e 66  2 ){.    pIdxInf
a5f0: 6f 2d 3e 61 43 6f 6e 73 74 72 61 69 6e 74 55 73  o->aConstraintUs
a600: 61 67 65 5b 69 44 69 73 74 54 65 72 6d 5d 2e 61  age[iDistTerm].a
a610: 72 67 76 49 6e 64 65 78 20 3d 20 31 2b 28 28 69  rgvIndex = 1+((i
a620: 50 6c 61 6e 26 31 29 21 3d 30 29 3b 0a 20 20 7d  Plan&1)!=0);.  }
a630: 0a 20 20 69 66 28 20 69 50 6c 61 6e 20 26 20 34  .  if( iPlan & 4
a640: 20 29 7b 0a 20 20 20 20 69 6e 74 20 69 64 78 20   ){.    int idx 
a650: 3d 20 31 3b 0a 20 20 20 20 69 66 28 20 69 50 6c  = 1;.    if( iPl
a660: 61 6e 20 26 20 31 20 29 20 69 64 78 2b 2b 3b 0a  an & 1 ) idx++;.
a670: 20 20 20 20 69 66 28 20 69 50 6c 61 6e 20 26 20      if( iPlan & 
a680: 32 20 29 20 69 64 78 2b 2b 3b 0a 20 20 20 20 70  2 ) idx++;.    p
a690: 49 64 78 49 6e 66 6f 2d 3e 61 43 6f 6e 73 74 72  IdxInfo->aConstr
a6a0: 61 69 6e 74 55 73 61 67 65 5b 69 4c 61 6e 67 54  aintUsage[iLangT
a6b0: 65 72 6d 5d 2e 61 72 67 76 49 6e 64 65 78 20 3d  erm].argvIndex =
a6c0: 20 69 64 78 3b 0a 20 20 7d 0a 20 20 70 49 64 78   idx;.  }.  pIdx
a6d0: 49 6e 66 6f 2d 3e 69 64 78 4e 75 6d 20 3d 20 69  Info->idxNum = i
a6e0: 50 6c 61 6e 3b 0a 20 20 69 66 28 20 70 49 64 78  Plan;.  if( pIdx
a6f0: 49 6e 66 6f 2d 3e 6e 4f 72 64 65 72 42 79 3d 3d  Info->nOrderBy==
a700: 31 0a 20 20 20 26 26 20 70 49 64 78 49 6e 66 6f  1.   && pIdxInfo
a710: 2d 3e 61 4f 72 64 65 72 42 79 5b 30 5d 2e 69 43  ->aOrderBy[0].iC
a720: 6f 6c 75 6d 6e 3d 3d 31 0a 20 20 20 26 26 20 70  olumn==1.   && p
a730: 49 64 78 49 6e 66 6f 2d 3e 61 4f 72 64 65 72 42  IdxInfo->aOrderB
a740: 79 5b 30 5d 2e 64 65 73 63 3d 3d 30 0a 20 20 29  y[0].desc==0.  )
a750: 7b 0a 20 20 20 20 70 49 64 78 49 6e 66 6f 2d 3e  {.    pIdxInfo->
a760: 6f 72 64 65 72 42 79 43 6f 6e 73 75 6d 65 64 20  orderByConsumed 
a770: 3d 20 31 3b 0a 20 20 7d 0a 20 20 70 49 64 78 49  = 1;.  }.  pIdxI
a780: 6e 66 6f 2d 3e 65 73 74 69 6d 61 74 65 64 43 6f  nfo->estimatedCo
a790: 73 74 20 3d 20 28 64 6f 75 62 6c 65 29 31 30 30  st = (double)100
a7a0: 30 30 3b 0a 20 20 20 0a 20 20 72 65 74 75 72 6e  00;.   .  return
a7b0: 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f   SQLITE_OK;.}../
a7c0: 2a 0a 2a 2a 20 54 68 65 20 78 55 70 64 61 74 65  *.** The xUpdate
a7d0: 28 29 20 6d 65 74 68 6f 64 2e 20 20 0a 2a 2a 0a  () method.  .**.
a7e0: 2a 2a 20 54 68 69 73 20 69 6d 70 6c 65 6d 65 6e  ** This implemen
a7f0: 74 61 74 69 6f 6e 20 64 69 73 61 6c 6c 6f 77 73  tation disallows
a800: 20 44 45 4c 45 54 45 20 61 6e 64 20 55 50 44 41   DELETE and UPDA
a810: 54 45 2e 20 20 54 68 65 20 6f 6e 6c 79 20 74 68  TE.  The only th
a820: 69 6e 67 0a 2a 2a 20 61 6c 6c 6f 77 65 64 20 69  ing.** allowed i
a830: 73 20 49 4e 53 45 52 54 20 69 6e 74 6f 20 74 68  s INSERT into th
a840: 65 20 22 63 6f 6d 6d 61 6e 64 22 20 63 6f 6c 75  e "command" colu
a850: 6d 6e 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  mn..*/.static in
a860: 74 20 61 6d 61 74 63 68 55 70 64 61 74 65 28 0a  t amatchUpdate(.
a870: 20 20 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a    sqlite3_vtab *
a880: 70 56 54 61 62 2c 0a 20 20 69 6e 74 20 61 72 67  pVTab,.  int arg
a890: 63 2c 0a 20 20 73 71 6c 69 74 65 33 5f 76 61 6c  c,.  sqlite3_val
a8a0: 75 65 20 2a 2a 61 72 67 76 2c 0a 20 20 73 71 6c  ue **argv,.  sql
a8b0: 69 74 65 5f 69 6e 74 36 34 20 2a 70 52 6f 77 69  ite_int64 *pRowi
a8c0: 64 0a 29 7b 0a 20 20 61 6d 61 74 63 68 5f 76 74  d.){.  amatch_vt
a8d0: 61 62 20 2a 70 20 3d 20 28 61 6d 61 74 63 68 5f  ab *p = (amatch_
a8e0: 76 74 61 62 2a 29 70 56 54 61 62 3b 0a 20 20 63  vtab*)pVTab;.  c
a8f0: 6f 6e 73 74 20 75 6e 73 69 67 6e 65 64 20 63 68  onst unsigned ch
a900: 61 72 20 2a 7a 43 6d 64 3b 0a 20 20 28 76 6f 69  ar *zCmd;.  (voi
a910: 64 29 70 52 6f 77 69 64 3b 0a 20 20 69 66 28 20  d)pRowid;.  if( 
a920: 61 72 67 63 3d 3d 31 20 29 7b 0a 20 20 20 20 70  argc==1 ){.    p
a930: 56 54 61 62 2d 3e 7a 45 72 72 4d 73 67 20 3d 20  VTab->zErrMsg = 
a940: 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28  sqlite3_mprintf(
a950: 22 44 45 4c 45 54 45 20 66 72 6f 6d 20 25 73 20  "DELETE from %s 
a960: 69 73 20 6e 6f 74 20 61 6c 6c 6f 77 65 64 22 2c  is not allowed",
a970: 20 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20   .              
a980: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
a990: 20 20 20 20 20 20 20 20 70 2d 3e 7a 53 65 6c 66          p->zSelf
a9a0: 29 3b 0a 20 20 20 20 72 65 74 75 72 6e 20 53 51  );.    return SQ
a9b0: 4c 49 54 45 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a  LITE_ERROR;.  }.
a9c0: 20 20 69 66 28 20 73 71 6c 69 74 65 33 5f 76 61    if( sqlite3_va
a9d0: 6c 75 65 5f 74 79 70 65 28 61 72 67 76 5b 30 5d  lue_type(argv[0]
a9e0: 29 21 3d 53 51 4c 49 54 45 5f 4e 55 4c 4c 20 29  )!=SQLITE_NULL )
a9f0: 7b 0a 20 20 20 20 70 56 54 61 62 2d 3e 7a 45 72  {.    pVTab->zEr
aa00: 72 4d 73 67 20 3d 20 73 71 6c 69 74 65 33 5f 6d  rMsg = sqlite3_m
aa10: 70 72 69 6e 74 66 28 22 55 50 44 41 54 45 20 6f  printf("UPDATE o
aa20: 66 20 25 73 20 69 73 20 6e 6f 74 20 61 6c 6c 6f  f %s is not allo
aa30: 77 65 64 22 2c 20 0a 20 20 20 20 20 20 20 20 20  wed", .         
aa40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
aa50: 20 20 20 20 20 20 20 20 20 20 20 20 20 70 2d 3e               p->
aa60: 7a 53 65 6c 66 29 3b 0a 20 20 20 20 72 65 74 75  zSelf);.    retu
aa70: 72 6e 20 53 51 4c 49 54 45 5f 45 52 52 4f 52 3b  rn SQLITE_ERROR;
aa80: 0a 20 20 7d 0a 20 20 69 66 28 20 73 71 6c 69 74  .  }.  if( sqlit
aa90: 65 33 5f 76 61 6c 75 65 5f 74 79 70 65 28 61 72  e3_value_type(ar
aaa0: 67 76 5b 32 2b 41 4d 41 54 43 48 5f 43 4f 4c 5f  gv[2+AMATCH_COL_
aab0: 57 4f 52 44 5d 29 21 3d 53 51 4c 49 54 45 5f 4e  WORD])!=SQLITE_N
aac0: 55 4c 4c 0a 20 20 20 7c 7c 20 73 71 6c 69 74 65  ULL.   || sqlite
aad0: 33 5f 76 61 6c 75 65 5f 74 79 70 65 28 61 72 67  3_value_type(arg
aae0: 76 5b 32 2b 41 4d 41 54 43 48 5f 43 4f 4c 5f 44  v[2+AMATCH_COL_D
aaf0: 49 53 54 41 4e 43 45 5d 29 21 3d 53 51 4c 49 54  ISTANCE])!=SQLIT
ab00: 45 5f 4e 55 4c 4c 0a 20 20 20 7c 7c 20 73 71 6c  E_NULL.   || sql
ab10: 69 74 65 33 5f 76 61 6c 75 65 5f 74 79 70 65 28  ite3_value_type(
ab20: 61 72 67 76 5b 32 2b 41 4d 41 54 43 48 5f 43 4f  argv[2+AMATCH_CO
ab30: 4c 5f 4c 41 4e 47 55 41 47 45 5d 29 21 3d 53 51  L_LANGUAGE])!=SQ
ab40: 4c 49 54 45 5f 4e 55 4c 4c 0a 20 20 29 7b 0a 20  LITE_NULL.  ){. 
ab50: 20 20 20 70 56 54 61 62 2d 3e 7a 45 72 72 4d 73     pVTab->zErrMs
ab60: 67 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72 69  g = sqlite3_mpri
ab70: 6e 74 66 28 0a 20 20 20 20 20 20 20 20 20 20 20  ntf(.           
ab80: 20 22 49 4e 53 45 52 54 20 49 4e 54 4f 20 25 73   "INSERT INTO %s
ab90: 20 61 6c 6c 6f 77 65 64 20 66 6f 72 20 63 6f 6c   allowed for col
aba0: 75 6d 6e 20 5b 63 6f 6d 6d 61 6e 64 5d 20 6f 6e  umn [command] on
abb0: 6c 79 22 2c 20 70 2d 3e 7a 53 65 6c 66 29 3b 0a  ly", p->zSelf);.
abc0: 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54      return SQLIT
abd0: 45 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a 20 20 7a  E_ERROR;.  }.  z
abe0: 43 6d 64 20 3d 20 73 71 6c 69 74 65 33 5f 76 61  Cmd = sqlite3_va
abf0: 6c 75 65 5f 74 65 78 74 28 61 72 67 76 5b 32 2b  lue_text(argv[2+
ac00: 41 4d 41 54 43 48 5f 43 4f 4c 5f 43 4f 4d 4d 41  AMATCH_COL_COMMA
ac10: 4e 44 5d 29 3b 0a 20 20 69 66 28 20 7a 43 6d 64  ND]);.  if( zCmd
ac20: 3d 3d 30 20 29 20 72 65 74 75 72 6e 20 53 51 4c  ==0 ) return SQL
ac30: 49 54 45 5f 4f 4b 3b 0a 20 20 0a 20 20 72 65 74  ITE_OK;.  .  ret
ac40: 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d  urn SQLITE_OK;.}
ac50: 0a 0a 2f 2a 0a 2a 2a 20 41 20 76 69 72 74 75 61  ../*.** A virtua
ac60: 6c 20 74 61 62 6c 65 20 6d 6f 64 75 6c 65 20 74  l table module t
ac70: 68 61 74 20 69 6d 70 6c 65 6d 65 6e 74 73 20 74  hat implements t
ac80: 68 65 20 22 61 70 70 72 6f 78 69 6d 61 74 65 5f  he "approximate_
ac90: 6d 61 74 63 68 22 2e 0a 2a 2f 0a 73 74 61 74 69  match"..*/.stati
aca0: 63 20 73 71 6c 69 74 65 33 5f 6d 6f 64 75 6c 65  c sqlite3_module
acb0: 20 61 6d 61 74 63 68 4d 6f 64 75 6c 65 20 3d 20   amatchModule = 
acc0: 7b 0a 20 20 30 2c 20 20 20 20 20 20 20 20 20 20  {.  0,          
acd0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 69              /* i
ace0: 56 65 72 73 69 6f 6e 20 2a 2f 0a 20 20 61 6d 61  Version */.  ama
acf0: 74 63 68 43 6f 6e 6e 65 63 74 2c 20 20 20 20 20  tchConnect,     
ad00: 20 20 20 20 20 2f 2a 20 78 43 72 65 61 74 65 20       /* xCreate 
ad10: 2a 2f 0a 20 20 61 6d 61 74 63 68 43 6f 6e 6e 65  */.  amatchConne
ad20: 63 74 2c 20 20 20 20 20 20 20 20 20 20 2f 2a 20  ct,          /* 
ad30: 78 43 6f 6e 6e 65 63 74 20 2a 2f 0a 20 20 61 6d  xConnect */.  am
ad40: 61 74 63 68 42 65 73 74 49 6e 64 65 78 2c 20 20  atchBestIndex,  
ad50: 20 20 20 20 20 20 2f 2a 20 78 42 65 73 74 49 6e        /* xBestIn
ad60: 64 65 78 20 2a 2f 0a 20 20 61 6d 61 74 63 68 44  dex */.  amatchD
ad70: 69 73 63 6f 6e 6e 65 63 74 2c 20 20 20 20 20 20  isconnect,      
ad80: 20 2f 2a 20 78 44 69 73 63 6f 6e 6e 65 63 74 20   /* xDisconnect 
ad90: 2a 2f 0a 20 20 61 6d 61 74 63 68 44 69 73 63 6f  */.  amatchDisco
ada0: 6e 6e 65 63 74 2c 20 20 20 20 20 20 20 2f 2a 20  nnect,       /* 
adb0: 78 44 65 73 74 72 6f 79 20 2a 2f 0a 20 20 61 6d  xDestroy */.  am
adc0: 61 74 63 68 4f 70 65 6e 2c 20 20 20 20 20 20 20  atchOpen,       
add0: 20 20 20 20 20 20 2f 2a 20 78 4f 70 65 6e 20 2d        /* xOpen -
ade0: 20 6f 70 65 6e 20 61 20 63 75 72 73 6f 72 20 2a   open a cursor *
adf0: 2f 0a 20 20 61 6d 61 74 63 68 43 6c 6f 73 65 2c  /.  amatchClose,
ae00: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78              /* x
ae10: 43 6c 6f 73 65 20 2d 20 63 6c 6f 73 65 20 61 20  Close - close a 
ae20: 63 75 72 73 6f 72 20 2a 2f 0a 20 20 61 6d 61 74  cursor */.  amat
ae30: 63 68 46 69 6c 74 65 72 2c 20 20 20 20 20 20 20  chFilter,       
ae40: 20 20 20 20 2f 2a 20 78 46 69 6c 74 65 72 20 2d      /* xFilter -
ae50: 20 63 6f 6e 66 69 67 75 72 65 20 73 63 61 6e 20   configure scan 
ae60: 63 6f 6e 73 74 72 61 69 6e 74 73 20 2a 2f 0a 20  constraints */. 
ae70: 20 61 6d 61 74 63 68 4e 65 78 74 2c 20 20 20 20   amatchNext,    
ae80: 20 20 20 20 20 20 20 20 20 2f 2a 20 78 4e 65 78           /* xNex
ae90: 74 20 2d 20 61 64 76 61 6e 63 65 20 61 20 63 75  t - advance a cu
aea0: 72 73 6f 72 20 2a 2f 0a 20 20 61 6d 61 74 63 68  rsor */.  amatch
aeb0: 45 6f 66 2c 20 20 20 20 20 20 20 20 20 20 20 20  Eof,            
aec0: 20 20 2f 2a 20 78 45 6f 66 20 2d 20 63 68 65 63    /* xEof - chec
aed0: 6b 20 66 6f 72 20 65 6e 64 20 6f 66 20 73 63 61  k for end of sca
aee0: 6e 20 2a 2f 0a 20 20 61 6d 61 74 63 68 43 6f 6c  n */.  amatchCol
aef0: 75 6d 6e 2c 20 20 20 20 20 20 20 20 20 20 20 2f  umn,           /
af00: 2a 20 78 43 6f 6c 75 6d 6e 20 2d 20 72 65 61 64  * xColumn - read
af10: 20 64 61 74 61 20 2a 2f 0a 20 20 61 6d 61 74 63   data */.  amatc
af20: 68 52 6f 77 69 64 2c 20 20 20 20 20 20 20 20 20  hRowid,         
af30: 20 20 20 2f 2a 20 78 52 6f 77 69 64 20 2d 20 72     /* xRowid - r
af40: 65 61 64 20 64 61 74 61 20 2a 2f 0a 20 20 61 6d  ead data */.  am
af50: 61 74 63 68 55 70 64 61 74 65 2c 20 20 20 20 20  atchUpdate,     
af60: 20 20 20 20 20 20 2f 2a 20 78 55 70 64 61 74 65        /* xUpdate
af70: 20 2a 2f 0a 20 20 30 2c 20 20 20 20 20 20 20 20   */.  0,        
af80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
af90: 20 78 42 65 67 69 6e 20 2a 2f 0a 20 20 30 2c 20   xBegin */.  0, 
afa0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
afb0: 20 20 20 20 20 2f 2a 20 78 53 79 6e 63 20 2a 2f       /* xSync */
afc0: 0a 20 20 30 2c 20 20 20 20 20 20 20 20 20 20 20  .  0,           
afd0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 43             /* xC
afe0: 6f 6d 6d 69 74 20 2a 2f 0a 20 20 30 2c 20 20 20  ommit */.  0,   
aff0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
b000: 20 20 20 2f 2a 20 78 52 6f 6c 6c 62 61 63 6b 20     /* xRollback 
b010: 2a 2f 0a 20 20 30 2c 20 20 20 20 20 20 20 20 20  */.  0,         
b020: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
b030: 78 46 69 6e 64 4d 65 74 68 6f 64 20 2a 2f 0a 20  xFindMethod */. 
b040: 20 30 2c 20 20 20 20 20 20 20 20 20 20 20 20 20   0,             
b050: 20 20 20 20 20 20 20 20 20 2f 2a 20 78 52 65 6e           /* xRen
b060: 61 6d 65 20 2a 2f 0a 20 20 30 2c 20 20 20 20 20  ame */.  0,     
b070: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
b080: 20 2f 2a 20 78 53 61 76 65 70 6f 69 6e 74 20 2a   /* xSavepoint *
b090: 2f 0a 20 20 30 2c 20 20 20 20 20 20 20 20 20 20  /.  0,          
b0a0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78              /* x
b0b0: 52 65 6c 65 61 73 65 20 2a 2f 0a 20 20 30 2c 20  Release */.  0, 
b0c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
b0d0: 20 20 20 20 20 2f 2a 20 78 52 6f 6c 6c 62 61 63       /* xRollbac
b0e0: 6b 54 6f 20 2a 2f 0a 20 20 30 20 20 20 20 20 20  kTo */.  0      
b0f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
b100: 20 2f 2a 20 78 53 68 61 64 6f 77 4e 61 6d 65 20   /* xShadowName 
b110: 2a 2f 0a 7d 3b 0a 0a 23 65 6e 64 69 66 20 2f 2a  */.};..#endif /*
b120: 20 53 51 4c 49 54 45 5f 4f 4d 49 54 5f 56 49 52   SQLITE_OMIT_VIR
b130: 54 55 41 4c 54 41 42 4c 45 20 2a 2f 0a 0a 2f 2a  TUALTABLE */../*
b140: 0a 2a 2a 20 52 65 67 69 73 74 65 72 20 74 68 65  .** Register the
b150: 20 61 6d 61 74 63 68 20 76 69 72 74 75 61 6c 20   amatch virtual 
b160: 74 61 62 6c 65 0a 2a 2f 0a 23 69 66 64 65 66 20  table.*/.#ifdef 
b170: 5f 57 49 4e 33 32 0a 5f 5f 64 65 63 6c 73 70 65  _WIN32.__declspe
b180: 63 28 64 6c 6c 65 78 70 6f 72 74 29 0a 23 65 6e  c(dllexport).#en
b190: 64 69 66 0a 69 6e 74 20 73 71 6c 69 74 65 33 5f  dif.int sqlite3_
b1a0: 61 6d 61 74 63 68 5f 69 6e 69 74 28 0a 20 20 73  amatch_init(.  s
b1b0: 71 6c 69 74 65 33 20 2a 64 62 2c 20 0a 20 20 63  qlite3 *db, .  c
b1c0: 68 61 72 20 2a 2a 70 7a 45 72 72 4d 73 67 2c 20  har **pzErrMsg, 
b1d0: 0a 20 20 63 6f 6e 73 74 20 73 71 6c 69 74 65 33  .  const sqlite3
b1e0: 5f 61 70 69 5f 72 6f 75 74 69 6e 65 73 20 2a 70  _api_routines *p
b1f0: 41 70 69 0a 29 7b 0a 20 20 69 6e 74 20 72 63 20  Api.){.  int rc 
b200: 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 53  = SQLITE_OK;.  S
b210: 51 4c 49 54 45 5f 45 58 54 45 4e 53 49 4f 4e 5f  QLITE_EXTENSION_
b220: 49 4e 49 54 32 28 70 41 70 69 29 3b 0a 20 20 28  INIT2(pApi);.  (
b230: 76 6f 69 64 29 70 7a 45 72 72 4d 73 67 3b 20 20  void)pzErrMsg;  
b240: 2f 2a 20 4e 6f 74 20 75 73 65 64 20 2a 2f 0a 23  /* Not used */.#
b250: 69 66 6e 64 65 66 20 53 51 4c 49 54 45 5f 4f 4d  ifndef SQLITE_OM
b260: 49 54 5f 56 49 52 54 55 41 4c 54 41 42 4c 45 0a  IT_VIRTUALTABLE.
b270: 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 63    rc = sqlite3_c
b280: 72 65 61 74 65 5f 6d 6f 64 75 6c 65 28 64 62 2c  reate_module(db,
b290: 20 22 61 70 70 72 6f 78 69 6d 61 74 65 5f 6d 61   "approximate_ma
b2a0: 74 63 68 22 2c 20 26 61 6d 61 74 63 68 4d 6f 64  tch", &amatchMod
b2b0: 75 6c 65 2c 20 30 29 3b 0a 23 65 6e 64 69 66 20  ule, 0);.#endif 
b2c0: 2f 2a 20 53 51 4c 49 54 45 5f 4f 4d 49 54 5f 56  /* SQLITE_OMIT_V
b2d0: 49 52 54 55 41 4c 54 41 42 4c 45 20 2a 2f 0a 20  IRTUALTABLE */. 
b2e0: 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a         return rc;.}.