/ Hex Artifact Content
Login

Artifact 50a9ef2d38dabfa371f8c1904097d493271e63d58ccb0e9b79a4fa4a94e66660:


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 36 34 28 20 73 69 7a 65 6f 66  malloc64( sizeof
53e0: 28 2a 70 52 75 6c 65 29 20 2b 20 6e 46 72 6f 6d  (*pRule) + nFrom
53f0: 20 2b 20 6e 54 6f 20 29 3b 0a 20 20 20 20 69 66   + nTo );.    if
5400: 28 20 70 52 75 6c 65 3d 3d 30 20 29 7b 0a 20 20  ( pRule==0 ){.  
5410: 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f      rc = SQLITE_
5420: 4e 4f 4d 45 4d 3b 0a 20 20 20 20 7d 65 6c 73 65  NOMEM;.    }else
5430: 7b 0a 20 20 20 20 20 20 6d 65 6d 73 65 74 28 70  {.      memset(p
5440: 52 75 6c 65 2c 20 30 2c 20 73 69 7a 65 6f 66 28  Rule, 0, sizeof(
5450: 2a 70 52 75 6c 65 29 29 3b 0a 20 20 20 20 20 20  *pRule));.      
5460: 70 52 75 6c 65 2d 3e 7a 46 72 6f 6d 20 3d 20 26  pRule->zFrom = &
5470: 70 52 75 6c 65 2d 3e 7a 54 6f 5b 6e 54 6f 2b 31  pRule->zTo[nTo+1
5480: 5d 3b 0a 20 20 20 20 20 20 70 52 75 6c 65 2d 3e  ];.      pRule->
5490: 6e 46 72 6f 6d 20 3d 20 28 61 6d 61 74 63 68 5f  nFrom = (amatch_
54a0: 6c 65 6e 29 6e 46 72 6f 6d 3b 0a 20 20 20 20 20  len)nFrom;.     
54b0: 20 6d 65 6d 63 70 79 28 70 52 75 6c 65 2d 3e 7a   memcpy(pRule->z
54c0: 46 72 6f 6d 2c 20 7a 46 72 6f 6d 2c 20 6e 46 72  From, zFrom, nFr
54d0: 6f 6d 2b 31 29 3b 0a 20 20 20 20 20 20 6d 65 6d  om+1);.      mem
54e0: 63 70 79 28 70 52 75 6c 65 2d 3e 7a 54 6f 2c 20  cpy(pRule->zTo, 
54f0: 7a 54 6f 2c 20 6e 54 6f 2b 31 29 3b 0a 20 20 20  zTo, nTo+1);.   
5500: 20 20 20 70 52 75 6c 65 2d 3e 6e 54 6f 20 3d 20     pRule->nTo = 
5510: 28 61 6d 61 74 63 68 5f 6c 65 6e 29 6e 54 6f 3b  (amatch_len)nTo;
5520: 0a 20 20 20 20 20 20 70 52 75 6c 65 2d 3e 72 43  .      pRule->rC
5530: 6f 73 74 20 3d 20 72 43 6f 73 74 3b 0a 20 20 20  ost = rCost;.   
5540: 20 20 20 70 52 75 6c 65 2d 3e 69 4c 61 6e 67 20     pRule->iLang 
5550: 3d 20 28 69 6e 74 29 69 4c 61 6e 67 3b 0a 20 20  = (int)iLang;.  
5560: 20 20 7d 0a 20 20 7d 0a 0a 20 20 2a 70 70 52 75    }.  }..  *ppRu
5570: 6c 65 20 3d 20 70 52 75 6c 65 3b 0a 20 20 72 65  le = pRule;.  re
5580: 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a  turn rc;.}../*.*
5590: 2a 20 46 72 65 65 20 61 6c 6c 20 74 68 65 20 63  * Free all the c
55a0: 6f 6e 74 65 6e 74 20 69 6e 20 74 68 65 20 65 64  ontent in the ed
55b0: 69 74 2d 63 6f 73 74 2d 74 61 62 6c 65 0a 2a 2f  it-cost-table.*/
55c0: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 61 6d 61  .static void ama
55d0: 74 63 68 46 72 65 65 52 75 6c 65 73 28 61 6d 61  tchFreeRules(ama
55e0: 74 63 68 5f 76 74 61 62 20 2a 70 29 7b 0a 20 20  tch_vtab *p){.  
55f0: 77 68 69 6c 65 28 20 70 2d 3e 70 52 75 6c 65 20  while( p->pRule 
5600: 29 7b 0a 20 20 20 20 61 6d 61 74 63 68 5f 72 75  ){.    amatch_ru
5610: 6c 65 20 2a 70 52 75 6c 65 20 3d 20 70 2d 3e 70  le *pRule = p->p
5620: 52 75 6c 65 3b 0a 20 20 20 20 70 2d 3e 70 52 75  Rule;.    p->pRu
5630: 6c 65 20 3d 20 70 52 75 6c 65 2d 3e 70 4e 65 78  le = pRule->pNex
5640: 74 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 66  t;.    sqlite3_f
5650: 72 65 65 28 70 52 75 6c 65 29 3b 0a 20 20 7d 0a  ree(pRule);.  }.
5660: 20 20 70 2d 3e 70 52 75 6c 65 20 3d 20 30 3b 0a    p->pRule = 0;.
5670: 7d 0a 0a 2f 2a 0a 2a 2a 20 4c 6f 61 64 20 74 68  }../*.** Load th
5680: 65 20 63 6f 6e 74 65 6e 74 20 6f 66 20 74 68 65  e content of the
5690: 20 61 6d 61 74 63 68 20 64 61 74 61 20 74 61 62   amatch data tab
56a0: 6c 65 20 69 6e 74 6f 20 6d 65 6d 6f 72 79 2e 0a  le into memory..
56b0: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 61 6d  */.static int am
56c0: 61 74 63 68 4c 6f 61 64 52 75 6c 65 73 28 0a 20  atchLoadRules(. 
56d0: 20 73 71 6c 69 74 65 33 20 2a 64 62 2c 20 20 20   sqlite3 *db,   
56e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
56f0: 20 2f 2a 20 44 61 74 61 62 61 73 65 20 68 61 6e   /* Database han
5700: 64 6c 65 20 2a 2f 0a 20 20 61 6d 61 74 63 68 5f  dle */.  amatch_
5710: 76 74 61 62 20 2a 70 2c 20 20 20 20 20 20 20 20  vtab *p,        
5720: 20 20 20 20 20 20 20 20 20 2f 2a 20 56 69 72 74           /* Virt
5730: 75 61 6c 20 61 6d 61 74 63 68 20 74 61 62 6c 65  ual amatch table
5740: 20 74 6f 20 63 6f 6e 66 69 67 75 72 65 20 2a 2f   to configure */
5750: 0a 20 20 63 68 61 72 20 2a 2a 70 7a 45 72 72 20  .  char **pzErr 
5760: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5770: 20 20 20 2f 2a 20 4f 55 54 3a 20 45 72 72 6f 72     /* OUT: Error
5780: 20 6d 65 73 73 61 67 65 20 2a 2f 0a 29 7b 0a 20   message */.){. 
5790: 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45   int rc = SQLITE
57a0: 5f 4f 4b 3b 20 20 20 20 20 20 20 20 20 20 20 20  _OK;            
57b0: 20 2f 2a 20 52 65 74 75 72 6e 20 63 6f 64 65 20   /* Return code 
57c0: 2a 2f 0a 20 20 63 68 61 72 20 2a 7a 53 71 6c 3b  */.  char *zSql;
57d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
57e0: 20 20 20 20 20 2f 2a 20 53 45 4c 45 43 54 20 75       /* SELECT u
57f0: 73 65 64 20 74 6f 20 72 65 61 64 20 66 72 6f 6d  sed to read from
5800: 20 72 75 6c 65 73 20 74 61 62 6c 65 20 2a 2f 0a   rules table */.
5810: 20 20 61 6d 61 74 63 68 5f 72 75 6c 65 20 2a 70    amatch_rule *p
5820: 48 65 61 64 20 3d 20 30 3b 0a 0a 20 20 7a 53 71  Head = 0;..  zSq
5830: 6c 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72 69  l = sqlite3_mpri
5840: 6e 74 66 28 22 53 45 4c 45 43 54 20 2a 20 46 52  ntf("SELECT * FR
5850: 4f 4d 20 25 51 2e 25 51 22 2c 20 70 2d 3e 7a 44  OM %Q.%Q", p->zD
5860: 62 2c 20 70 2d 3e 7a 43 6f 73 74 54 61 62 29 3b  b, p->zCostTab);
5870: 0a 20 20 69 66 28 20 7a 53 71 6c 3d 3d 30 20 29  .  if( zSql==0 )
5880: 7b 0a 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54  {.    rc = SQLIT
5890: 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 7d 65 6c 73 65  E_NOMEM;.  }else
58a0: 7b 0a 20 20 20 20 69 6e 74 20 72 63 32 3b 20 20  {.    int rc2;  
58b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
58c0: 20 20 20 20 2f 2a 20 66 69 6e 61 6c 69 7a 65 28      /* finalize(
58d0: 29 20 72 65 74 75 72 6e 20 63 6f 64 65 20 2a 2f  ) return code */
58e0: 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 73 74 6d  .    sqlite3_stm
58f0: 74 20 2a 70 53 74 6d 74 20 3d 20 30 3b 0a 20 20  t *pStmt = 0;.  
5900: 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 70    rc = sqlite3_p
5910: 72 65 70 61 72 65 5f 76 32 28 64 62 2c 20 7a 53  repare_v2(db, zS
5920: 71 6c 2c 20 2d 31 2c 20 26 70 53 74 6d 74 2c 20  ql, -1, &pStmt, 
5930: 30 29 3b 0a 20 20 20 20 69 66 28 20 72 63 21 3d  0);.    if( rc!=
5940: 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20  SQLITE_OK ){.   
5950: 20 20 20 2a 70 7a 45 72 72 20 3d 20 73 71 6c 69     *pzErr = sqli
5960: 74 65 33 5f 6d 70 72 69 6e 74 66 28 22 25 73 3a  te3_mprintf("%s:
5970: 20 25 73 22 2c 20 70 2d 3e 7a 43 6c 61 73 73 4e   %s", p->zClassN
5980: 61 6d 65 2c 20 73 71 6c 69 74 65 33 5f 65 72 72  ame, sqlite3_err
5990: 6d 73 67 28 64 62 29 29 3b 0a 20 20 20 20 7d 65  msg(db));.    }e
59a0: 6c 73 65 20 69 66 28 20 73 71 6c 69 74 65 33 5f  lse if( sqlite3_
59b0: 63 6f 6c 75 6d 6e 5f 63 6f 75 6e 74 28 70 53 74  column_count(pSt
59c0: 6d 74 29 21 3d 34 20 29 7b 0a 20 20 20 20 20 20  mt)!=4 ){.      
59d0: 2a 70 7a 45 72 72 20 3d 20 73 71 6c 69 74 65 33  *pzErr = sqlite3
59e0: 5f 6d 70 72 69 6e 74 66 28 22 25 73 3a 20 25 73  _mprintf("%s: %s
59f0: 20 68 61 73 20 25 64 20 63 6f 6c 75 6d 6e 73 2c   has %d columns,
5a00: 20 65 78 70 65 63 74 65 64 20 34 22 2c 0a 20 20   expected 4",.  
5a10: 20 20 20 20 20 20 20 20 70 2d 3e 7a 43 6c 61 73          p->zClas
5a20: 73 4e 61 6d 65 2c 20 70 2d 3e 7a 43 6f 73 74 54  sName, p->zCostT
5a30: 61 62 2c 20 73 71 6c 69 74 65 33 5f 63 6f 6c 75  ab, sqlite3_colu
5a40: 6d 6e 5f 63 6f 75 6e 74 28 70 53 74 6d 74 29 0a  mn_count(pStmt).
5a50: 20 20 20 20 20 20 29 3b 0a 20 20 20 20 20 20 72        );.      r
5a60: 63 20 3d 20 53 51 4c 49 54 45 5f 45 52 52 4f 52  c = SQLITE_ERROR
5a70: 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20  ;.    }else{.   
5a80: 20 20 20 77 68 69 6c 65 28 20 72 63 3d 3d 53 51     while( rc==SQ
5a90: 4c 49 54 45 5f 4f 4b 20 26 26 20 53 51 4c 49 54  LITE_OK && SQLIT
5aa0: 45 5f 52 4f 57 3d 3d 73 71 6c 69 74 65 33 5f 73  E_ROW==sqlite3_s
5ab0: 74 65 70 28 70 53 74 6d 74 29 20 29 7b 0a 20 20  tep(pStmt) ){.  
5ac0: 20 20 20 20 20 20 61 6d 61 74 63 68 5f 72 75 6c        amatch_rul
5ad0: 65 20 2a 70 52 75 6c 65 20 3d 20 30 3b 0a 20 20  e *pRule = 0;.  
5ae0: 20 20 20 20 20 20 72 63 20 3d 20 61 6d 61 74 63        rc = amatc
5af0: 68 4c 6f 61 64 4f 6e 65 52 75 6c 65 28 70 2c 20  hLoadOneRule(p, 
5b00: 70 53 74 6d 74 2c 20 26 70 52 75 6c 65 2c 20 70  pStmt, &pRule, p
5b10: 7a 45 72 72 29 3b 0a 20 20 20 20 20 20 20 20 69  zErr);.        i
5b20: 66 28 20 70 52 75 6c 65 20 29 7b 0a 20 20 20 20  f( pRule ){.    
5b30: 20 20 20 20 20 20 70 52 75 6c 65 2d 3e 70 4e 65        pRule->pNe
5b40: 78 74 20 3d 20 70 48 65 61 64 3b 0a 20 20 20 20  xt = pHead;.    
5b50: 20 20 20 20 20 20 70 48 65 61 64 20 3d 20 70 52        pHead = pR
5b60: 75 6c 65 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20  ule;.        }. 
5b70: 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 20       }.    }.   
5b80: 20 72 63 32 20 3d 20 73 71 6c 69 74 65 33 5f 66   rc2 = sqlite3_f
5b90: 69 6e 61 6c 69 7a 65 28 70 53 74 6d 74 29 3b 0a  inalize(pStmt);.
5ba0: 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49      if( rc==SQLI
5bb0: 54 45 5f 4f 4b 20 29 20 72 63 20 3d 20 72 63 32  TE_OK ) rc = rc2
5bc0: 3b 0a 20 20 7d 0a 20 20 73 71 6c 69 74 65 33 5f  ;.  }.  sqlite3_
5bd0: 66 72 65 65 28 7a 53 71 6c 29 3b 0a 0a 20 20 2f  free(zSql);..  /
5be0: 2a 20 41 6c 6c 20 72 75 6c 65 73 20 61 72 65 20  * All rules are 
5bf0: 6e 6f 77 20 69 6e 20 61 20 73 69 6e 67 6c 79 20  now in a singly 
5c00: 6c 69 6e 6b 65 64 20 6c 69 73 74 20 73 74 61 72  linked list star
5c10: 74 69 6e 67 20 61 74 20 70 48 65 61 64 2e 20 54  ting at pHead. T
5c20: 68 69 73 0a 20 20 2a 2a 20 62 6c 6f 63 6b 20 73  his.  ** block s
5c30: 6f 72 74 73 20 74 68 65 6d 20 62 79 20 63 6f 73  orts them by cos
5c40: 74 20 61 6e 64 20 74 68 65 6e 20 73 65 74 73 20  t and then sets 
5c50: 61 6d 61 74 63 68 5f 76 74 61 62 2e 70 52 75 6c  amatch_vtab.pRul
5c60: 65 20 74 6f 20 70 6f 69 6e 74 20 74 6f 20 0a 20  e to point to . 
5c70: 20 2a 2a 20 70 6f 69 6e 74 20 74 6f 20 74 68 65   ** point to the
5c80: 20 68 65 61 64 20 6f 66 20 74 68 65 20 73 6f 72   head of the sor
5c90: 74 65 64 20 6c 69 73 74 2e 0a 20 20 2a 2f 0a 20  ted list..  */. 
5ca0: 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
5cb0: 4f 4b 20 29 7b 0a 20 20 20 20 75 6e 73 69 67 6e  OK ){.    unsign
5cc0: 65 64 20 69 6e 74 20 69 3b 0a 20 20 20 20 61 6d  ed int i;.    am
5cd0: 61 74 63 68 5f 72 75 6c 65 20 2a 70 58 3b 0a 20  atch_rule *pX;. 
5ce0: 20 20 20 61 6d 61 74 63 68 5f 72 75 6c 65 20 2a     amatch_rule *
5cf0: 61 5b 31 35 5d 3b 0a 20 20 20 20 66 6f 72 28 69  a[15];.    for(i
5d00: 3d 30 3b 20 69 3c 73 69 7a 65 6f 66 28 61 29 2f  =0; i<sizeof(a)/
5d10: 73 69 7a 65 6f 66 28 61 5b 30 5d 29 3b 20 69 2b  sizeof(a[0]); i+
5d20: 2b 29 20 61 5b 69 5d 20 3d 20 30 3b 0a 20 20 20  +) a[i] = 0;.   
5d30: 20 77 68 69 6c 65 28 20 28 70 58 20 3d 20 70 48   while( (pX = pH
5d40: 65 61 64 29 21 3d 30 20 29 7b 0a 20 20 20 20 20  ead)!=0 ){.     
5d50: 20 70 48 65 61 64 20 3d 20 70 58 2d 3e 70 4e 65   pHead = pX->pNe
5d60: 78 74 3b 0a 20 20 20 20 20 20 70 58 2d 3e 70 4e  xt;.      pX->pN
5d70: 65 78 74 20 3d 20 30 3b 0a 20 20 20 20 20 20 66  ext = 0;.      f
5d80: 6f 72 28 69 3d 30 3b 20 61 5b 69 5d 20 26 26 20  or(i=0; a[i] && 
5d90: 69 3c 73 69 7a 65 6f 66 28 61 29 2f 73 69 7a 65  i<sizeof(a)/size
5da0: 6f 66 28 61 5b 30 5d 29 2d 31 3b 20 69 2b 2b 29  of(a[0])-1; i++)
5db0: 7b 0a 20 20 20 20 20 20 20 20 70 58 20 3d 20 61  {.        pX = a
5dc0: 6d 61 74 63 68 4d 65 72 67 65 52 75 6c 65 73 28  matchMergeRules(
5dd0: 61 5b 69 5d 2c 20 70 58 29 3b 0a 20 20 20 20 20  a[i], pX);.     
5de0: 20 20 20 61 5b 69 5d 20 3d 20 30 3b 0a 20 20 20     a[i] = 0;.   
5df0: 20 20 20 7d 0a 20 20 20 20 20 20 61 5b 69 5d 20     }.      a[i] 
5e00: 3d 20 61 6d 61 74 63 68 4d 65 72 67 65 52 75 6c  = amatchMergeRul
5e10: 65 73 28 61 5b 69 5d 2c 20 70 58 29 3b 0a 20 20  es(a[i], pX);.  
5e20: 20 20 7d 0a 20 20 20 20 66 6f 72 28 70 58 3d 61    }.    for(pX=a
5e30: 5b 30 5d 2c 20 69 3d 31 3b 20 69 3c 73 69 7a 65  [0], i=1; i<size
5e40: 6f 66 28 61 29 2f 73 69 7a 65 6f 66 28 61 5b 30  of(a)/sizeof(a[0
5e50: 5d 29 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20  ]); i++){.      
5e60: 70 58 20 3d 20 61 6d 61 74 63 68 4d 65 72 67 65  pX = amatchMerge
5e70: 52 75 6c 65 73 28 61 5b 69 5d 2c 20 70 58 29 3b  Rules(a[i], pX);
5e80: 0a 20 20 20 20 7d 0a 20 20 20 20 70 2d 3e 70 52  .    }.    p->pR
5e90: 75 6c 65 20 3d 20 61 6d 61 74 63 68 4d 65 72 67  ule = amatchMerg
5ea0: 65 52 75 6c 65 73 28 70 2d 3e 70 52 75 6c 65 2c  eRules(p->pRule,
5eb0: 20 70 58 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20   pX);.  }else{. 
5ec0: 20 20 20 2f 2a 20 41 6e 20 65 72 72 6f 72 20 68     /* An error h
5ed0: 61 73 20 6f 63 63 75 72 72 65 64 2e 20 53 65 74  as occurred. Set
5ee0: 74 69 6e 67 20 70 2d 3e 70 52 75 6c 65 20 74 6f  ting p->pRule to
5ef0: 20 70 6f 69 6e 74 20 74 6f 20 74 68 65 20 68 65   point to the he
5f00: 61 64 20 6f 66 20 74 68 65 0a 20 20 20 20 2a 2a  ad of the.    **
5f10: 20 61 6c 6c 6f 63 61 74 65 64 20 6c 69 73 74 20   allocated list 
5f20: 65 6e 73 75 72 65 73 20 74 68 61 74 20 74 68 65  ensures that the
5f30: 20 6c 69 73 74 20 77 69 6c 6c 20 62 65 20 63 6c   list will be cl
5f40: 65 61 6e 65 64 20 75 70 20 69 6e 20 74 68 69 73  eaned up in this
5f50: 20 63 61 73 65 2e 0a 20 20 20 20 2a 2f 0a 20 20   case..    */.  
5f60: 20 20 61 73 73 65 72 74 28 20 70 2d 3e 70 52 75    assert( p->pRu
5f70: 6c 65 3d 3d 30 20 29 3b 0a 20 20 20 20 70 2d 3e  le==0 );.    p->
5f80: 70 52 75 6c 65 20 3d 20 70 48 65 61 64 3b 0a 20  pRule = pHead;. 
5f90: 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b   }..  return rc;
5fa0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 66  .}../*.** This f
5fb0: 75 6e 63 74 69 6f 6e 20 63 6f 6e 76 65 72 74 73  unction converts
5fc0: 20 61 6e 20 53 51 4c 20 71 75 6f 74 65 64 20 73   an SQL quoted s
5fd0: 74 72 69 6e 67 20 69 6e 74 6f 20 61 6e 20 75 6e  tring into an un
5fe0: 71 75 6f 74 65 64 20 73 74 72 69 6e 67 0a 2a 2a  quoted string.**
5ff0: 20 61 6e 64 20 72 65 74 75 72 6e 73 20 61 20 70   and returns a p
6000: 6f 69 6e 74 65 72 20 74 6f 20 61 20 62 75 66 66  ointer to a buff
6010: 65 72 20 61 6c 6c 6f 63 61 74 65 64 20 75 73 69  er allocated usi
6020: 6e 67 20 73 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f  ng sqlite3_mallo
6030: 63 28 29 20 0a 2a 2a 20 63 6f 6e 74 61 69 6e 69  c() .** containi
6040: 6e 67 20 74 68 65 20 72 65 73 75 6c 74 2e 20 54  ng the result. T
6050: 68 65 20 63 61 6c 6c 65 72 20 73 68 6f 75 6c 64  he caller should
6060: 20 65 76 65 6e 74 75 61 6c 6c 79 20 66 72 65 65   eventually free
6070: 20 74 68 69 73 20 62 75 66 66 65 72 0a 2a 2a 20   this buffer.** 
6080: 75 73 69 6e 67 20 73 71 6c 69 74 65 33 5f 66 72  using sqlite3_fr
6090: 65 65 2e 0a 2a 2a 0a 2a 2a 20 45 78 61 6d 70 6c  ee..**.** Exampl
60a0: 65 73 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20 22 61  es:.**.**     "a
60b0: 62 63 22 20 20 20 62 65 63 6f 6d 65 73 20 20 20  bc"   becomes   
60c0: 61 62 63 0a 2a 2a 20 20 20 20 20 27 78 79 7a 27  abc.**     'xyz'
60d0: 20 20 20 62 65 63 6f 6d 65 73 20 20 20 78 79 7a     becomes   xyz
60e0: 0a 2a 2a 20 20 20 20 20 5b 70 71 72 5d 20 20 20  .**     [pqr]   
60f0: 62 65 63 6f 6d 65 73 20 20 20 70 71 72 0a 2a 2a  becomes   pqr.**
6100: 20 20 20 20 20 60 6d 6e 6f 60 20 20 20 62 65 63       `mno`   bec
6110: 6f 6d 65 73 20 20 20 6d 6e 6f 0a 2a 2f 0a 73 74  omes   mno.*/.st
6120: 61 74 69 63 20 63 68 61 72 20 2a 61 6d 61 74 63  atic char *amatc
6130: 68 44 65 71 75 6f 74 65 28 63 6f 6e 73 74 20 63  hDequote(const c
6140: 68 61 72 20 2a 7a 49 6e 29 7b 0a 20 20 73 71 6c  har *zIn){.  sql
6150: 69 74 65 33 5f 69 6e 74 36 34 20 6e 49 6e 3b 20  ite3_int64 nIn; 
6160: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
6170: 53 69 7a 65 20 6f 66 20 69 6e 70 75 74 20 73 74  Size of input st
6180: 72 69 6e 67 2c 20 69 6e 20 62 79 74 65 73 20 2a  ring, in bytes *
6190: 2f 0a 20 20 63 68 61 72 20 2a 7a 4f 75 74 3b 20  /.  char *zOut; 
61a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
61b0: 20 20 20 20 2f 2a 20 4f 75 74 70 75 74 20 28 64      /* Output (d
61c0: 65 71 75 6f 74 65 64 29 20 73 74 72 69 6e 67 20  equoted) string 
61d0: 2a 2f 0a 0a 20 20 6e 49 6e 20 3d 20 73 74 72 6c  */..  nIn = strl
61e0: 65 6e 28 7a 49 6e 29 3b 0a 20 20 7a 4f 75 74 20  en(zIn);.  zOut 
61f0: 3d 20 73 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63  = sqlite3_malloc
6200: 36 34 28 6e 49 6e 2b 31 29 3b 0a 20 20 69 66 28  64(nIn+1);.  if(
6210: 20 7a 4f 75 74 20 29 7b 0a 20 20 20 20 63 68 61   zOut ){.    cha
6220: 72 20 71 20 3d 20 7a 49 6e 5b 30 5d 3b 20 20 20  r q = zIn[0];   
6230: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 51 75             /* Qu
6240: 6f 74 65 20 63 68 61 72 61 63 74 65 72 20 28 69  ote character (i
6250: 66 20 61 6e 79 20 29 20 2a 2f 0a 0a 20 20 20 20  f any ) */..    
6260: 69 66 28 20 71 21 3d 27 5b 27 20 26 26 20 71 21  if( q!='[' && q!
6270: 3d 20 27 5c 27 27 20 26 26 20 71 21 3d 27 22 27  = '\'' && q!='"'
6280: 20 26 26 20 71 21 3d 27 60 27 20 29 7b 0a 20 20   && q!='`' ){.  
6290: 20 20 20 20 6d 65 6d 63 70 79 28 7a 4f 75 74 2c      memcpy(zOut,
62a0: 20 7a 49 6e 2c 20 28 73 69 7a 65 5f 74 29 28 6e   zIn, (size_t)(n
62b0: 49 6e 2b 31 29 29 3b 0a 20 20 20 20 7d 65 6c 73  In+1));.    }els
62c0: 65 7b 0a 20 20 20 20 20 20 69 6e 74 20 69 4f 75  e{.      int iOu
62d0: 74 20 3d 20 30 3b 20 20 20 20 20 20 20 20 20 20  t = 0;          
62e0: 20 20 20 20 20 2f 2a 20 49 6e 64 65 78 20 6f 66       /* Index of
62f0: 20 6e 65 78 74 20 62 79 74 65 20 74 6f 20 77 72   next byte to wr
6300: 69 74 65 20 74 6f 20 6f 75 74 70 75 74 20 2a 2f  ite to output */
6310: 0a 20 20 20 20 20 20 69 6e 74 20 69 49 6e 3b 20  .      int iIn; 
6320: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6330: 20 20 20 2f 2a 20 49 6e 64 65 78 20 6f 66 20 6e     /* Index of n
6340: 65 78 74 20 62 79 74 65 20 74 6f 20 72 65 61 64  ext byte to read
6350: 20 66 72 6f 6d 20 69 6e 70 75 74 20 2a 2f 0a 0a   from input */..
6360: 20 20 20 20 20 20 69 66 28 20 71 3d 3d 27 5b 27        if( q=='['
6370: 20 29 20 71 20 3d 20 27 5d 27 3b 0a 20 20 20 20   ) q = ']';.    
6380: 20 20 66 6f 72 28 69 49 6e 3d 31 3b 20 69 49 6e    for(iIn=1; iIn
6390: 3c 6e 49 6e 3b 20 69 49 6e 2b 2b 29 7b 0a 20 20  <nIn; iIn++){.  
63a0: 20 20 20 20 20 20 69 66 28 20 7a 49 6e 5b 69 49        if( zIn[iI
63b0: 6e 5d 3d 3d 71 20 29 20 69 49 6e 2b 2b 3b 0a 20  n]==q ) iIn++;. 
63c0: 20 20 20 20 20 20 20 7a 4f 75 74 5b 69 4f 75 74         zOut[iOut
63d0: 2b 2b 5d 20 3d 20 7a 49 6e 5b 69 49 6e 5d 3b 0a  ++] = zIn[iIn];.
63e0: 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20        }.    }.  
63f0: 20 20 61 73 73 65 72 74 28 20 28 69 6e 74 29 73    assert( (int)s
6400: 74 72 6c 65 6e 28 7a 4f 75 74 29 3c 3d 6e 49 6e  trlen(zOut)<=nIn
6410: 20 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e   );.  }.  return
6420: 20 7a 4f 75 74 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20   zOut;.}../*.** 
6430: 44 65 61 6c 6c 6f 63 61 74 65 20 74 68 65 20 70  Deallocate the p
6440: 56 43 68 65 63 6b 20 70 72 65 70 61 72 65 64 20  VCheck prepared 
6450: 73 74 61 74 65 6d 65 6e 74 2e 0a 2a 2f 0a 73 74  statement..*/.st
6460: 61 74 69 63 20 76 6f 69 64 20 61 6d 61 74 63 68  atic void amatch
6470: 56 43 68 65 63 6b 43 6c 65 61 72 28 61 6d 61 74  VCheckClear(amat
6480: 63 68 5f 76 74 61 62 20 2a 70 29 7b 0a 20 20 69  ch_vtab *p){.  i
6490: 66 28 20 70 2d 3e 70 56 43 68 65 63 6b 20 29 7b  f( p->pVCheck ){
64a0: 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 66 69 6e  .    sqlite3_fin
64b0: 61 6c 69 7a 65 28 70 2d 3e 70 56 43 68 65 63 6b  alize(p->pVCheck
64c0: 29 3b 0a 20 20 20 20 70 2d 3e 70 56 43 68 65 63  );.    p->pVChec
64d0: 6b 20 3d 20 30 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a  k = 0;.  }.}../*
64e0: 0a 2a 2a 20 44 65 61 6c 6c 6f 63 61 74 65 20 61  .** Deallocate a
64f0: 6e 20 61 6d 61 74 63 68 5f 76 74 61 62 20 6f 62  n amatch_vtab ob
6500: 6a 65 63 74 0a 2a 2f 0a 73 74 61 74 69 63 20 76  ject.*/.static v
6510: 6f 69 64 20 61 6d 61 74 63 68 46 72 65 65 28 61  oid amatchFree(a
6520: 6d 61 74 63 68 5f 76 74 61 62 20 2a 70 29 7b 0a  match_vtab *p){.
6530: 20 20 69 66 28 20 70 20 29 7b 0a 20 20 20 20 61    if( p ){.    a
6540: 6d 61 74 63 68 46 72 65 65 52 75 6c 65 73 28 70  matchFreeRules(p
6550: 29 3b 0a 20 20 20 20 61 6d 61 74 63 68 56 43 68  );.    amatchVCh
6560: 65 63 6b 43 6c 65 61 72 28 70 29 3b 0a 20 20 20  eckClear(p);.   
6570: 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70 2d   sqlite3_free(p-
6580: 3e 7a 43 6c 61 73 73 4e 61 6d 65 29 3b 0a 20 20  >zClassName);.  
6590: 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70    sqlite3_free(p
65a0: 2d 3e 7a 44 62 29 3b 0a 20 20 20 20 73 71 6c 69  ->zDb);.    sqli
65b0: 74 65 33 5f 66 72 65 65 28 70 2d 3e 7a 43 6f 73  te3_free(p->zCos
65c0: 74 54 61 62 29 3b 0a 20 20 20 20 73 71 6c 69 74  tTab);.    sqlit
65d0: 65 33 5f 66 72 65 65 28 70 2d 3e 7a 56 6f 63 61  e3_free(p->zVoca
65e0: 62 54 61 62 29 3b 0a 20 20 20 20 73 71 6c 69 74  bTab);.    sqlit
65f0: 65 33 5f 66 72 65 65 28 70 2d 3e 7a 56 6f 63 61  e3_free(p->zVoca
6600: 62 57 6f 72 64 29 3b 0a 20 20 20 20 73 71 6c 69  bWord);.    sqli
6610: 74 65 33 5f 66 72 65 65 28 70 2d 3e 7a 56 6f 63  te3_free(p->zVoc
6620: 61 62 4c 61 6e 67 29 3b 0a 20 20 20 20 73 71 6c  abLang);.    sql
6630: 69 74 65 33 5f 66 72 65 65 28 70 2d 3e 7a 53 65  ite3_free(p->zSe
6640: 6c 66 29 3b 0a 20 20 20 20 6d 65 6d 73 65 74 28  lf);.    memset(
6650: 70 2c 20 30 2c 20 73 69 7a 65 6f 66 28 2a 70 29  p, 0, sizeof(*p)
6660: 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 66  );.    sqlite3_f
6670: 72 65 65 28 70 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f  ree(p);.  }.}../
6680: 2a 0a 2a 2a 20 78 44 69 73 63 6f 6e 6e 65 63 74  *.** xDisconnect
6690: 2f 78 44 65 73 74 72 6f 79 20 6d 65 74 68 6f 64  /xDestroy method
66a0: 20 66 6f 72 20 74 68 65 20 61 6d 61 74 63 68 20   for the amatch 
66b0: 6d 6f 64 75 6c 65 2e 0a 2a 2f 0a 73 74 61 74 69  module..*/.stati
66c0: 63 20 69 6e 74 20 61 6d 61 74 63 68 44 69 73 63  c int amatchDisc
66d0: 6f 6e 6e 65 63 74 28 73 71 6c 69 74 65 33 5f 76  onnect(sqlite3_v
66e0: 74 61 62 20 2a 70 56 74 61 62 29 7b 0a 20 20 61  tab *pVtab){.  a
66f0: 6d 61 74 63 68 5f 76 74 61 62 20 2a 70 20 3d 20  match_vtab *p = 
6700: 28 61 6d 61 74 63 68 5f 76 74 61 62 2a 29 70 56  (amatch_vtab*)pV
6710: 74 61 62 3b 0a 20 20 61 73 73 65 72 74 28 20 70  tab;.  assert( p
6720: 2d 3e 6e 43 75 72 73 6f 72 3d 3d 30 20 29 3b 0a  ->nCursor==0 );.
6730: 20 20 61 6d 61 74 63 68 46 72 65 65 28 70 29 3b    amatchFree(p);
6740: 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45  .  return SQLITE
6750: 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 68  _OK;.}../*.** Ch
6760: 65 63 6b 20 74 6f 20 73 65 65 20 69 66 20 74 68  eck to see if th
6770: 65 20 61 72 67 75 6d 65 6e 74 20 69 73 20 6f 66  e argument is of
6780: 20 74 68 65 20 66 6f 72 6d 3a 0a 2a 2a 0a 2a 2a   the form:.**.**
6790: 20 20 20 20 20 20 20 4b 45 59 20 3d 20 56 41 4c         KEY = VAL
67a0: 55 45 0a 2a 2a 0a 2a 2a 20 49 66 20 69 74 20 69  UE.**.** If it i
67b0: 73 2c 20 72 65 74 75 72 6e 20 61 20 70 6f 69 6e  s, return a poin
67c0: 74 65 72 20 74 6f 20 74 68 65 20 66 69 72 73 74  ter to the first
67d0: 20 63 68 61 72 61 63 74 65 72 20 6f 66 20 56 41   character of VA
67e0: 4c 55 45 2e 0a 2a 2a 20 49 66 20 6e 6f 74 2c 20  LUE..** If not, 
67f0: 72 65 74 75 72 6e 20 4e 55 4c 4c 2e 20 20 53 70  return NULL.  Sp
6800: 61 63 65 73 20 61 72 6f 75 6e 64 20 74 68 65 20  aces around the 
6810: 3d 20 61 72 65 20 69 67 6e 6f 72 65 64 2e 0a 2a  = are ignored..*
6820: 2f 0a 73 74 61 74 69 63 20 63 6f 6e 73 74 20 63  /.static const c
6830: 68 61 72 20 2a 61 6d 61 74 63 68 56 61 6c 75 65  har *amatchValue
6840: 4f 66 4b 65 79 28 63 6f 6e 73 74 20 63 68 61 72  OfKey(const char
6850: 20 2a 7a 4b 65 79 2c 20 63 6f 6e 73 74 20 63 68   *zKey, const ch
6860: 61 72 20 2a 7a 53 74 72 29 7b 0a 20 20 69 6e 74  ar *zStr){.  int
6870: 20 6e 4b 65 79 20 3d 20 28 69 6e 74 29 73 74 72   nKey = (int)str
6880: 6c 65 6e 28 7a 4b 65 79 29 3b 0a 20 20 69 6e 74  len(zKey);.  int
6890: 20 6e 53 74 72 20 3d 20 28 69 6e 74 29 73 74 72   nStr = (int)str
68a0: 6c 65 6e 28 7a 53 74 72 29 3b 0a 20 20 69 6e 74  len(zStr);.  int
68b0: 20 69 3b 0a 20 20 69 66 28 20 6e 53 74 72 3c 6e   i;.  if( nStr<n
68c0: 4b 65 79 2b 31 20 29 20 72 65 74 75 72 6e 20 30  Key+1 ) return 0
68d0: 3b 0a 20 20 69 66 28 20 6d 65 6d 63 6d 70 28 7a  ;.  if( memcmp(z
68e0: 53 74 72 2c 20 7a 4b 65 79 2c 20 6e 4b 65 79 29  Str, zKey, nKey)
68f0: 21 3d 30 20 29 20 72 65 74 75 72 6e 20 30 3b 0a  !=0 ) return 0;.
6900: 20 20 66 6f 72 28 69 3d 6e 4b 65 79 3b 20 69 73    for(i=nKey; is
6910: 73 70 61 63 65 28 28 75 6e 73 69 67 6e 65 64 20  space((unsigned 
6920: 63 68 61 72 29 7a 53 74 72 5b 69 5d 29 3b 20 69  char)zStr[i]); i
6930: 2b 2b 29 7b 7d 0a 20 20 69 66 28 20 7a 53 74 72  ++){}.  if( zStr
6940: 5b 69 5d 21 3d 27 3d 27 20 29 20 72 65 74 75 72  [i]!='=' ) retur
6950: 6e 20 30 3b 0a 20 20 69 2b 2b 3b 0a 20 20 77 68  n 0;.  i++;.  wh
6960: 69 6c 65 28 20 69 73 73 70 61 63 65 28 28 75 6e  ile( isspace((un
6970: 73 69 67 6e 65 64 20 63 68 61 72 29 7a 53 74 72  signed char)zStr
6980: 5b 69 5d 29 20 29 7b 20 69 2b 2b 3b 20 7d 0a 20  [i]) ){ i++; }. 
6990: 20 72 65 74 75 72 6e 20 7a 53 74 72 2b 69 3b 0a   return zStr+i;.
69a0: 7d 0a 0a 2f 2a 0a 2a 2a 20 78 43 6f 6e 6e 65 63  }../*.** xConnec
69b0: 74 2f 78 43 72 65 61 74 65 20 6d 65 74 68 6f 64  t/xCreate method
69c0: 20 66 6f 72 20 74 68 65 20 61 6d 61 74 63 68 20   for the amatch 
69d0: 6d 6f 64 75 6c 65 2e 20 41 72 67 75 6d 65 6e 74  module. Argument
69e0: 73 20 61 72 65 3a 0a 2a 2a 0a 2a 2a 20 20 20 61  s are:.**.**   a
69f0: 72 67 76 5b 30 5d 20 20 20 20 2d 3e 20 6d 6f 64  rgv[0]    -> mod
6a00: 75 6c 65 20 6e 61 6d 65 20 20 28 22 61 70 70 72  ule name  ("appr
6a10: 6f 78 69 6d 61 74 65 5f 6d 61 74 63 68 22 29 0a  oximate_match").
6a20: 2a 2a 20 20 20 61 72 67 76 5b 31 5d 20 20 20 20  **   argv[1]    
6a30: 2d 3e 20 64 61 74 61 62 61 73 65 20 6e 61 6d 65  -> database name
6a40: 0a 2a 2a 20 20 20 61 72 67 76 5b 32 5d 20 20 20  .**   argv[2]   
6a50: 20 2d 3e 20 74 61 62 6c 65 20 6e 61 6d 65 0a 2a   -> table name.*
6a60: 2a 20 20 20 61 72 67 76 5b 33 2e 2e 2e 5d 20 2d  *   argv[3...] -
6a70: 3e 20 61 72 67 75 6d 65 6e 74 73 0a 2a 2f 0a 73  > arguments.*/.s
6a80: 74 61 74 69 63 20 69 6e 74 20 61 6d 61 74 63 68  tatic int amatch
6a90: 43 6f 6e 6e 65 63 74 28 0a 20 20 73 71 6c 69 74  Connect(.  sqlit
6aa0: 65 33 20 2a 64 62 2c 0a 20 20 76 6f 69 64 20 2a  e3 *db,.  void *
6ab0: 70 41 75 78 2c 0a 20 20 69 6e 74 20 61 72 67 63  pAux,.  int argc
6ac0: 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 63 6f  , const char *co
6ad0: 6e 73 74 2a 61 72 67 76 2c 0a 20 20 73 71 6c 69  nst*argv,.  sqli
6ae0: 74 65 33 5f 76 74 61 62 20 2a 2a 70 70 56 74 61  te3_vtab **ppVta
6af0: 62 2c 0a 20 20 63 68 61 72 20 2a 2a 70 7a 45 72  b,.  char **pzEr
6b00: 72 0a 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20  r.){.  int rc = 
6b10: 53 51 4c 49 54 45 5f 4f 4b 3b 20 20 20 20 20 20  SQLITE_OK;      
6b20: 20 20 20 20 20 20 20 2f 2a 20 52 65 74 75 72 6e         /* Return
6b30: 20 63 6f 64 65 20 2a 2f 0a 20 20 61 6d 61 74 63   code */.  amatc
6b40: 68 5f 76 74 61 62 20 2a 70 4e 65 77 20 3d 20 30  h_vtab *pNew = 0
6b50: 3b 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 65  ;          /* Ne
6b60: 77 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65 20  w virtual table 
6b70: 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20  */.  const char 
6b80: 2a 7a 4d 6f 64 75 6c 65 20 3d 20 61 72 67 76 5b  *zModule = argv[
6b90: 30 5d 3b 0a 20 20 63 6f 6e 73 74 20 63 68 61 72  0];.  const char
6ba0: 20 2a 7a 44 62 20 3d 20 61 72 67 76 5b 31 5d 3b   *zDb = argv[1];
6bb0: 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a  .  const char *z
6bc0: 56 61 6c 3b 0a 20 20 69 6e 74 20 69 3b 0a 0a 20  Val;.  int i;.. 
6bd0: 20 28 76 6f 69 64 29 70 41 75 78 3b 0a 20 20 2a   (void)pAux;.  *
6be0: 70 70 56 74 61 62 20 3d 20 30 3b 0a 20 20 70 4e  ppVtab = 0;.  pN
6bf0: 65 77 20 3d 20 73 71 6c 69 74 65 33 5f 6d 61 6c  ew = sqlite3_mal
6c00: 6c 6f 63 28 20 73 69 7a 65 6f 66 28 2a 70 4e 65  loc( sizeof(*pNe
6c10: 77 29 20 29 3b 0a 20 20 69 66 28 20 70 4e 65 77  w) );.  if( pNew
6c20: 3d 3d 30 20 29 20 72 65 74 75 72 6e 20 53 51 4c  ==0 ) return SQL
6c30: 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 72 63 20  ITE_NOMEM;.  rc 
6c40: 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a  = SQLITE_NOMEM;.
6c50: 20 20 6d 65 6d 73 65 74 28 70 4e 65 77 2c 20 30    memset(pNew, 0
6c60: 2c 20 73 69 7a 65 6f 66 28 2a 70 4e 65 77 29 29  , sizeof(*pNew))
6c70: 3b 0a 20 20 70 4e 65 77 2d 3e 64 62 20 3d 20 64  ;.  pNew->db = d
6c80: 62 3b 0a 20 20 70 4e 65 77 2d 3e 7a 43 6c 61 73  b;.  pNew->zClas
6c90: 73 4e 61 6d 65 20 3d 20 73 71 6c 69 74 65 33 5f  sName = sqlite3_
6ca0: 6d 70 72 69 6e 74 66 28 22 25 73 22 2c 20 7a 4d  mprintf("%s", zM
6cb0: 6f 64 75 6c 65 29 3b 0a 20 20 69 66 28 20 70 4e  odule);.  if( pN
6cc0: 65 77 2d 3e 7a 43 6c 61 73 73 4e 61 6d 65 3d 3d  ew->zClassName==
6cd0: 30 20 29 20 67 6f 74 6f 20 61 6d 61 74 63 68 43  0 ) goto amatchC
6ce0: 6f 6e 6e 65 63 74 45 72 72 6f 72 3b 0a 20 20 70  onnectError;.  p
6cf0: 4e 65 77 2d 3e 7a 44 62 20 3d 20 73 71 6c 69 74  New->zDb = sqlit
6d00: 65 33 5f 6d 70 72 69 6e 74 66 28 22 25 73 22 2c  e3_mprintf("%s",
6d10: 20 7a 44 62 29 3b 0a 20 20 69 66 28 20 70 4e 65   zDb);.  if( pNe
6d20: 77 2d 3e 7a 44 62 3d 3d 30 20 29 20 67 6f 74 6f  w->zDb==0 ) goto
6d30: 20 61 6d 61 74 63 68 43 6f 6e 6e 65 63 74 45 72   amatchConnectEr
6d40: 72 6f 72 3b 0a 20 20 70 4e 65 77 2d 3e 7a 53 65  ror;.  pNew->zSe
6d50: 6c 66 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72  lf = sqlite3_mpr
6d60: 69 6e 74 66 28 22 25 73 22 2c 20 61 72 67 76 5b  intf("%s", argv[
6d70: 32 5d 29 3b 0a 20 20 69 66 28 20 70 4e 65 77 2d  2]);.  if( pNew-
6d80: 3e 7a 53 65 6c 66 3d 3d 30 20 29 20 67 6f 74 6f  >zSelf==0 ) goto
6d90: 20 61 6d 61 74 63 68 43 6f 6e 6e 65 63 74 45 72   amatchConnectEr
6da0: 72 6f 72 3b 0a 20 20 66 6f 72 28 69 3d 33 3b 20  ror;.  for(i=3; 
6db0: 69 3c 61 72 67 63 3b 20 69 2b 2b 29 7b 0a 20 20  i<argc; i++){.  
6dc0: 20 20 7a 56 61 6c 20 3d 20 61 6d 61 74 63 68 56    zVal = amatchV
6dd0: 61 6c 75 65 4f 66 4b 65 79 28 22 76 6f 63 61 62  alueOfKey("vocab
6de0: 75 6c 61 72 79 5f 74 61 62 6c 65 22 2c 20 61 72  ulary_table", ar
6df0: 67 76 5b 69 5d 29 3b 0a 20 20 20 20 69 66 28 20  gv[i]);.    if( 
6e00: 7a 56 61 6c 20 29 7b 0a 20 20 20 20 20 20 73 71  zVal ){.      sq
6e10: 6c 69 74 65 33 5f 66 72 65 65 28 70 4e 65 77 2d  lite3_free(pNew-
6e20: 3e 7a 56 6f 63 61 62 54 61 62 29 3b 0a 20 20 20  >zVocabTab);.   
6e30: 20 20 20 70 4e 65 77 2d 3e 7a 56 6f 63 61 62 54     pNew->zVocabT
6e40: 61 62 20 3d 20 61 6d 61 74 63 68 44 65 71 75 6f  ab = amatchDequo
6e50: 74 65 28 7a 56 61 6c 29 3b 0a 20 20 20 20 20 20  te(zVal);.      
6e60: 69 66 28 20 70 4e 65 77 2d 3e 7a 56 6f 63 61 62  if( pNew->zVocab
6e70: 54 61 62 3d 3d 30 20 29 20 67 6f 74 6f 20 61 6d  Tab==0 ) goto am
6e80: 61 74 63 68 43 6f 6e 6e 65 63 74 45 72 72 6f 72  atchConnectError
6e90: 3b 0a 20 20 20 20 20 20 63 6f 6e 74 69 6e 75 65  ;.      continue
6ea0: 3b 0a 20 20 20 20 7d 0a 20 20 20 20 7a 56 61 6c  ;.    }.    zVal
6eb0: 20 3d 20 61 6d 61 74 63 68 56 61 6c 75 65 4f 66   = amatchValueOf
6ec0: 4b 65 79 28 22 76 6f 63 61 62 75 6c 61 72 79 5f  Key("vocabulary_
6ed0: 77 6f 72 64 22 2c 20 61 72 67 76 5b 69 5d 29 3b  word", argv[i]);
6ee0: 0a 20 20 20 20 69 66 28 20 7a 56 61 6c 20 29 7b  .    if( zVal ){
6ef0: 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 66  .      sqlite3_f
6f00: 72 65 65 28 70 4e 65 77 2d 3e 7a 56 6f 63 61 62  ree(pNew->zVocab
6f10: 57 6f 72 64 29 3b 0a 20 20 20 20 20 20 70 4e 65  Word);.      pNe
6f20: 77 2d 3e 7a 56 6f 63 61 62 57 6f 72 64 20 3d 20  w->zVocabWord = 
6f30: 61 6d 61 74 63 68 44 65 71 75 6f 74 65 28 7a 56  amatchDequote(zV
6f40: 61 6c 29 3b 0a 20 20 20 20 20 20 69 66 28 20 70  al);.      if( p
6f50: 4e 65 77 2d 3e 7a 56 6f 63 61 62 57 6f 72 64 3d  New->zVocabWord=
6f60: 3d 30 20 29 20 67 6f 74 6f 20 61 6d 61 74 63 68  =0 ) goto amatch
6f70: 43 6f 6e 6e 65 63 74 45 72 72 6f 72 3b 0a 20 20  ConnectError;.  
6f80: 20 20 20 20 63 6f 6e 74 69 6e 75 65 3b 0a 20 20      continue;.  
6f90: 20 20 7d 0a 20 20 20 20 7a 56 61 6c 20 3d 20 61    }.    zVal = a
6fa0: 6d 61 74 63 68 56 61 6c 75 65 4f 66 4b 65 79 28  matchValueOfKey(
6fb0: 22 76 6f 63 61 62 75 6c 61 72 79 5f 6c 61 6e 67  "vocabulary_lang
6fc0: 75 61 67 65 22 2c 20 61 72 67 76 5b 69 5d 29 3b  uage", argv[i]);
6fd0: 0a 20 20 20 20 69 66 28 20 7a 56 61 6c 20 29 7b  .    if( zVal ){
6fe0: 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 66  .      sqlite3_f
6ff0: 72 65 65 28 70 4e 65 77 2d 3e 7a 56 6f 63 61 62  ree(pNew->zVocab
7000: 4c 61 6e 67 29 3b 0a 20 20 20 20 20 20 70 4e 65  Lang);.      pNe
7010: 77 2d 3e 7a 56 6f 63 61 62 4c 61 6e 67 20 3d 20  w->zVocabLang = 
7020: 61 6d 61 74 63 68 44 65 71 75 6f 74 65 28 7a 56  amatchDequote(zV
7030: 61 6c 29 3b 0a 20 20 20 20 20 20 69 66 28 20 70  al);.      if( p
7040: 4e 65 77 2d 3e 7a 56 6f 63 61 62 4c 61 6e 67 3d  New->zVocabLang=
7050: 3d 30 20 29 20 67 6f 74 6f 20 61 6d 61 74 63 68  =0 ) goto amatch
7060: 43 6f 6e 6e 65 63 74 45 72 72 6f 72 3b 0a 20 20  ConnectError;.  
7070: 20 20 20 20 63 6f 6e 74 69 6e 75 65 3b 0a 20 20      continue;.  
7080: 20 20 7d 0a 20 20 20 20 7a 56 61 6c 20 3d 20 61    }.    zVal = a
7090: 6d 61 74 63 68 56 61 6c 75 65 4f 66 4b 65 79 28  matchValueOfKey(
70a0: 22 65 64 69 74 5f 64 69 73 74 61 6e 63 65 73 22  "edit_distances"
70b0: 2c 20 61 72 67 76 5b 69 5d 29 3b 0a 20 20 20 20  , argv[i]);.    
70c0: 69 66 28 20 7a 56 61 6c 20 29 7b 0a 20 20 20 20  if( zVal ){.    
70d0: 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70    sqlite3_free(p
70e0: 4e 65 77 2d 3e 7a 43 6f 73 74 54 61 62 29 3b 0a  New->zCostTab);.
70f0: 20 20 20 20 20 20 70 4e 65 77 2d 3e 7a 43 6f 73        pNew->zCos
7100: 74 54 61 62 20 3d 20 61 6d 61 74 63 68 44 65 71  tTab = amatchDeq
7110: 75 6f 74 65 28 7a 56 61 6c 29 3b 0a 20 20 20 20  uote(zVal);.    
7120: 20 20 69 66 28 20 70 4e 65 77 2d 3e 7a 43 6f 73    if( pNew->zCos
7130: 74 54 61 62 3d 3d 30 20 29 20 67 6f 74 6f 20 61  tTab==0 ) goto a
7140: 6d 61 74 63 68 43 6f 6e 6e 65 63 74 45 72 72 6f  matchConnectErro
7150: 72 3b 0a 20 20 20 20 20 20 63 6f 6e 74 69 6e 75  r;.      continu
7160: 65 3b 0a 20 20 20 20 7d 0a 20 20 20 20 2a 70 7a  e;.    }.    *pz
7170: 45 72 72 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70  Err = sqlite3_mp
7180: 72 69 6e 74 66 28 22 75 6e 72 65 63 6f 67 6e 69  rintf("unrecogni
7190: 7a 65 64 20 61 72 67 75 6d 65 6e 74 3a 20 5b 25  zed argument: [%
71a0: 73 5d 5c 6e 22 2c 20 61 72 67 76 5b 69 5d 29 3b  s]\n", argv[i]);
71b0: 0a 20 20 20 20 61 6d 61 74 63 68 46 72 65 65 28  .    amatchFree(
71c0: 70 4e 65 77 29 3b 0a 20 20 20 20 2a 70 70 56 74  pNew);.    *ppVt
71d0: 61 62 20 3d 20 30 3b 0a 20 20 20 20 72 65 74 75  ab = 0;.    retu
71e0: 72 6e 20 53 51 4c 49 54 45 5f 45 52 52 4f 52 3b  rn SQLITE_ERROR;
71f0: 0a 20 20 7d 0a 20 20 72 63 20 3d 20 53 51 4c 49  .  }.  rc = SQLI
7200: 54 45 5f 4f 4b 3b 0a 20 20 69 66 28 20 70 4e 65  TE_OK;.  if( pNe
7210: 77 2d 3e 7a 43 6f 73 74 54 61 62 3d 3d 30 20 29  w->zCostTab==0 )
7220: 7b 0a 20 20 20 20 2a 70 7a 45 72 72 20 3d 20 73  {.    *pzErr = s
7230: 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 22  qlite3_mprintf("
7240: 6e 6f 20 65 64 69 74 5f 64 69 73 74 61 6e 63 65  no edit_distance
7250: 73 20 74 61 62 6c 65 20 73 70 65 63 69 66 69 65  s table specifie
7260: 64 22 29 3b 0a 20 20 20 20 72 63 20 3d 20 53 51  d");.    rc = SQ
7270: 4c 49 54 45 5f 45 52 52 4f 52 3b 0a 20 20 7d 65  LITE_ERROR;.  }e
7280: 6c 73 65 7b 0a 20 20 20 20 72 63 20 3d 20 61 6d  lse{.    rc = am
7290: 61 74 63 68 4c 6f 61 64 52 75 6c 65 73 28 64 62  atchLoadRules(db
72a0: 2c 20 70 4e 65 77 2c 20 70 7a 45 72 72 29 3b 0a  , pNew, pzErr);.
72b0: 20 20 7d 0a 20 20 69 66 28 20 72 63 3d 3d 53 51    }.  if( rc==SQ
72c0: 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 72  LITE_OK ){.    r
72d0: 63 20 3d 20 73 71 6c 69 74 65 33 5f 64 65 63 6c  c = sqlite3_decl
72e0: 61 72 65 5f 76 74 61 62 28 64 62 2c 0a 20 20 20  are_vtab(db,.   
72f0: 20 20 20 20 20 20 20 20 22 43 52 45 41 54 45 20          "CREATE 
7300: 54 41 42 4c 45 20 78 28 77 6f 72 64 2c 64 69 73  TABLE x(word,dis
7310: 74 61 6e 63 65 2c 6c 61 6e 67 75 61 67 65 2c 22  tance,language,"
7320: 0a 20 20 20 20 20 20 20 20 20 20 20 22 63 6f 6d  .           "com
7330: 6d 61 6e 64 20 48 49 44 44 45 4e 2c 6e 77 6f 72  mand HIDDEN,nwor
7340: 64 20 48 49 44 44 45 4e 29 22 0a 20 20 20 20 20  d HIDDEN)".     
7350: 20 20 20 20 29 3b 0a 23 64 65 66 69 6e 65 20 41      );.#define A
7360: 4d 41 54 43 48 5f 43 4f 4c 5f 57 4f 52 44 20 20  MATCH_COL_WORD  
7370: 20 20 20 20 20 30 0a 23 64 65 66 69 6e 65 20 41       0.#define A
7380: 4d 41 54 43 48 5f 43 4f 4c 5f 44 49 53 54 41 4e  MATCH_COL_DISTAN
7390: 43 45 20 20 20 31 0a 23 64 65 66 69 6e 65 20 41  CE   1.#define A
73a0: 4d 41 54 43 48 5f 43 4f 4c 5f 4c 41 4e 47 55 41  MATCH_COL_LANGUA
73b0: 47 45 20 20 20 32 0a 23 64 65 66 69 6e 65 20 41  GE   2.#define A
73c0: 4d 41 54 43 48 5f 43 4f 4c 5f 43 4f 4d 4d 41 4e  MATCH_COL_COMMAN
73d0: 44 20 20 20 20 33 0a 23 64 65 66 69 6e 65 20 41  D    3.#define A
73e0: 4d 41 54 43 48 5f 43 4f 4c 5f 4e 57 4f 52 44 20  MATCH_COL_NWORD 
73f0: 20 20 20 20 20 34 0a 20 20 7d 0a 20 20 69 66 28       4.  }.  if(
7400: 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc!=SQLITE_OK )
7410: 7b 0a 20 20 20 20 61 6d 61 74 63 68 46 72 65 65  {.    amatchFree
7420: 28 70 4e 65 77 29 3b 0a 20 20 7d 0a 20 20 2a 70  (pNew);.  }.  *p
7430: 70 56 74 61 62 20 3d 20 26 70 4e 65 77 2d 3e 62  pVtab = &pNew->b
7440: 61 73 65 3b 0a 20 20 72 65 74 75 72 6e 20 72 63  ase;.  return rc
7450: 3b 0a 0a 61 6d 61 74 63 68 43 6f 6e 6e 65 63 74  ;..amatchConnect
7460: 45 72 72 6f 72 3a 0a 20 20 61 6d 61 74 63 68 46  Error:.  amatchF
7470: 72 65 65 28 70 4e 65 77 29 3b 0a 20 20 72 65 74  ree(pNew);.  ret
7480: 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  urn rc;.}../*.**
7490: 20 4f 70 65 6e 20 61 20 6e 65 77 20 61 6d 61 74   Open a new amat
74a0: 63 68 20 63 75 72 73 6f 72 2e 0a 2a 2f 0a 73 74  ch cursor..*/.st
74b0: 61 74 69 63 20 69 6e 74 20 61 6d 61 74 63 68 4f  atic int amatchO
74c0: 70 65 6e 28 73 71 6c 69 74 65 33 5f 76 74 61 62  pen(sqlite3_vtab
74d0: 20 2a 70 56 54 61 62 2c 20 73 71 6c 69 74 65 33   *pVTab, sqlite3
74e0: 5f 76 74 61 62 5f 63 75 72 73 6f 72 20 2a 2a 70  _vtab_cursor **p
74f0: 70 43 75 72 73 6f 72 29 7b 0a 20 20 61 6d 61 74  pCursor){.  amat
7500: 63 68 5f 76 74 61 62 20 2a 70 20 3d 20 28 61 6d  ch_vtab *p = (am
7510: 61 74 63 68 5f 76 74 61 62 2a 29 70 56 54 61 62  atch_vtab*)pVTab
7520: 3b 0a 20 20 61 6d 61 74 63 68 5f 63 75 72 73 6f  ;.  amatch_curso
7530: 72 20 2a 70 43 75 72 3b 0a 20 20 70 43 75 72 20  r *pCur;.  pCur 
7540: 3d 20 73 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63  = sqlite3_malloc
7550: 28 20 73 69 7a 65 6f 66 28 2a 70 43 75 72 29 20  ( sizeof(*pCur) 
7560: 29 3b 0a 20 20 69 66 28 20 70 43 75 72 3d 3d 30  );.  if( pCur==0
7570: 20 29 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45   ) return SQLITE
7580: 5f 4e 4f 4d 45 4d 3b 0a 20 20 6d 65 6d 73 65 74  _NOMEM;.  memset
7590: 28 70 43 75 72 2c 20 30 2c 20 73 69 7a 65 6f 66  (pCur, 0, sizeof
75a0: 28 2a 70 43 75 72 29 29 3b 0a 20 20 70 43 75 72  (*pCur));.  pCur
75b0: 2d 3e 70 56 74 61 62 20 3d 20 70 3b 0a 20 20 2a  ->pVtab = p;.  *
75c0: 70 70 43 75 72 73 6f 72 20 3d 20 26 70 43 75 72  ppCursor = &pCur
75d0: 2d 3e 62 61 73 65 3b 0a 20 20 70 2d 3e 6e 43 75  ->base;.  p->nCu
75e0: 72 73 6f 72 2b 2b 3b 0a 20 20 72 65 74 75 72 6e  rsor++;.  return
75f0: 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f   SQLITE_OK;.}../
7600: 2a 0a 2a 2a 20 46 72 65 65 20 75 70 20 61 6c 6c  *.** Free up all
7610: 20 74 68 65 20 6d 65 6d 6f 72 79 20 61 6c 6c 6f   the memory allo
7620: 63 61 74 65 64 20 62 79 20 61 20 63 75 72 73 6f  cated by a curso
7630: 72 2e 20 20 53 65 74 20 69 74 20 72 4c 69 6d 69  r.  Set it rLimi
7640: 74 20 74 6f 20 30 0a 2a 2a 20 74 6f 20 69 6e 64  t to 0.** to ind
7650: 69 63 61 74 65 20 74 68 61 74 20 69 74 20 69 73  icate that it is
7660: 20 61 74 20 45 4f 46 2e 0a 2a 2f 0a 73 74 61 74   at EOF..*/.stat
7670: 69 63 20 76 6f 69 64 20 61 6d 61 74 63 68 43 6c  ic void amatchCl
7680: 65 61 72 43 75 72 73 6f 72 28 61 6d 61 74 63 68  earCursor(amatch
7690: 5f 63 75 72 73 6f 72 20 2a 70 43 75 72 29 7b 0a  _cursor *pCur){.
76a0: 20 20 61 6d 61 74 63 68 5f 77 6f 72 64 20 2a 70    amatch_word *p
76b0: 57 6f 72 64 2c 20 2a 70 4e 65 78 74 57 6f 72 64  Word, *pNextWord
76c0: 3b 0a 20 20 66 6f 72 28 70 57 6f 72 64 3d 70 43  ;.  for(pWord=pC
76d0: 75 72 2d 3e 70 41 6c 6c 57 6f 72 64 73 3b 20 70  ur->pAllWords; p
76e0: 57 6f 72 64 3b 20 70 57 6f 72 64 3d 70 4e 65 78  Word; pWord=pNex
76f0: 74 57 6f 72 64 29 7b 0a 20 20 20 20 70 4e 65 78  tWord){.    pNex
7700: 74 57 6f 72 64 20 3d 20 70 57 6f 72 64 2d 3e 70  tWord = pWord->p
7710: 4e 65 78 74 3b 0a 20 20 20 20 73 71 6c 69 74 65  Next;.    sqlite
7720: 33 5f 66 72 65 65 28 70 57 6f 72 64 29 3b 0a 20  3_free(pWord);. 
7730: 20 7d 0a 20 20 70 43 75 72 2d 3e 70 41 6c 6c 57   }.  pCur->pAllW
7740: 6f 72 64 73 20 3d 20 30 3b 0a 20 20 73 71 6c 69  ords = 0;.  sqli
7750: 74 65 33 5f 66 72 65 65 28 70 43 75 72 2d 3e 7a  te3_free(pCur->z
7760: 49 6e 70 75 74 29 3b 0a 20 20 70 43 75 72 2d 3e  Input);.  pCur->
7770: 7a 49 6e 70 75 74 20 3d 20 30 3b 0a 20 20 73 71  zInput = 0;.  sq
7780: 6c 69 74 65 33 5f 66 72 65 65 28 70 43 75 72 2d  lite3_free(pCur-
7790: 3e 7a 42 75 66 29 3b 0a 20 20 70 43 75 72 2d 3e  >zBuf);.  pCur->
77a0: 7a 42 75 66 20 3d 20 30 3b 0a 20 20 70 43 75 72  zBuf = 0;.  pCur
77b0: 2d 3e 6e 42 75 66 20 3d 20 30 3b 0a 20 20 70 43  ->nBuf = 0;.  pC
77c0: 75 72 2d 3e 70 43 6f 73 74 20 3d 20 30 3b 0a 20  ur->pCost = 0;. 
77d0: 20 70 43 75 72 2d 3e 70 57 6f 72 64 20 3d 20 30   pCur->pWord = 0
77e0: 3b 0a 20 20 70 43 75 72 2d 3e 70 43 75 72 72 65  ;.  pCur->pCurre
77f0: 6e 74 20 3d 20 30 3b 0a 20 20 70 43 75 72 2d 3e  nt = 0;.  pCur->
7800: 72 4c 69 6d 69 74 20 3d 20 31 30 30 30 30 30 30  rLimit = 1000000
7810: 3b 0a 20 20 70 43 75 72 2d 3e 69 4c 61 6e 67 20  ;.  pCur->iLang 
7820: 3d 20 30 3b 0a 20 20 70 43 75 72 2d 3e 6e 57 6f  = 0;.  pCur->nWo
7830: 72 64 20 3d 20 30 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  rd = 0;.}../*.**
7840: 20 43 6c 6f 73 65 20 61 20 61 6d 61 74 63 68 20   Close a amatch 
7850: 63 75 72 73 6f 72 2e 0a 2a 2f 0a 73 74 61 74 69  cursor..*/.stati
7860: 63 20 69 6e 74 20 61 6d 61 74 63 68 43 6c 6f 73  c int amatchClos
7870: 65 28 73 71 6c 69 74 65 33 5f 76 74 61 62 5f 63  e(sqlite3_vtab_c
7880: 75 72 73 6f 72 20 2a 63 75 72 29 7b 0a 20 20 61  ursor *cur){.  a
7890: 6d 61 74 63 68 5f 63 75 72 73 6f 72 20 2a 70 43  match_cursor *pC
78a0: 75 72 20 3d 20 28 61 6d 61 74 63 68 5f 63 75 72  ur = (amatch_cur
78b0: 73 6f 72 20 2a 29 63 75 72 3b 0a 20 20 61 6d 61  sor *)cur;.  ama
78c0: 74 63 68 43 6c 65 61 72 43 75 72 73 6f 72 28 70  tchClearCursor(p
78d0: 43 75 72 29 3b 0a 20 20 70 43 75 72 2d 3e 70 56  Cur);.  pCur->pV
78e0: 74 61 62 2d 3e 6e 43 75 72 73 6f 72 2d 2d 3b 0a  tab->nCursor--;.
78f0: 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70    sqlite3_free(p
7900: 43 75 72 29 3b 0a 20 20 72 65 74 75 72 6e 20 53  Cur);.  return S
7910: 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a  QLITE_OK;.}../*.
7920: 2a 2a 20 52 65 6e 64 65 72 20 61 20 32 34 2d 62  ** Render a 24-b
7930: 69 74 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 65  it unsigned inte
7940: 67 65 72 20 61 73 20 61 20 34 2d 62 79 74 65 20  ger as a 4-byte 
7950: 62 61 73 65 2d 36 34 20 6e 75 6d 62 65 72 2e 0a  base-64 number..
7960: 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 61  */.static void a
7970: 6d 61 74 63 68 45 6e 63 6f 64 65 49 6e 74 28 69  matchEncodeInt(i
7980: 6e 74 20 78 2c 20 63 68 61 72 20 2a 7a 29 7b 0a  nt x, char *z){.
7990: 20 20 73 74 61 74 69 63 20 63 6f 6e 73 74 20 63    static const c
79a0: 68 61 72 20 61 5b 5d 20 3d 20 0a 20 20 20 20 22  har a[] = .    "
79b0: 30 31 32 33 34 35 36 37 38 39 22 0a 20 20 20 20  0123456789".    
79c0: 22 41 42 43 44 45 46 47 48 49 4a 22 0a 20 20 20  "ABCDEFGHIJ".   
79d0: 20 22 4b 4c 4d 4e 4f 50 51 52 53 54 22 0a 20 20   "KLMNOPQRST".  
79e0: 20 20 22 55 56 57 58 59 5a 5e 61 62 63 22 0a 20    "UVWXYZ^abc". 
79f0: 20 20 20 22 64 65 66 67 68 69 6a 6b 6c 6d 22 0a     "defghijklm".
7a00: 20 20 20 20 22 6e 6f 70 71 72 73 74 75 76 77 22      "nopqrstuvw"
7a10: 0a 20 20 20 20 22 78 79 7a 7e 22 3b 0a 20 20 7a  .    "xyz~";.  z
7a20: 5b 30 5d 20 3d 20 61 5b 28 78 3e 3e 31 38 29 26  [0] = a[(x>>18)&
7a30: 30 78 33 66 5d 3b 0a 20 20 7a 5b 31 5d 20 3d 20  0x3f];.  z[1] = 
7a40: 61 5b 28 78 3e 3e 31 32 29 26 30 78 33 66 5d 3b  a[(x>>12)&0x3f];
7a50: 0a 20 20 7a 5b 32 5d 20 3d 20 61 5b 28 78 3e 3e  .  z[2] = a[(x>>
7a60: 36 29 26 30 78 33 66 5d 3b 0a 20 20 7a 5b 33 5d  6)&0x3f];.  z[3]
7a70: 20 3d 20 61 5b 78 26 30 78 33 66 5d 3b 0a 7d 0a   = a[x&0x3f];.}.
7a80: 0a 2f 2a 0a 2a 2a 20 57 72 69 74 65 20 74 68 65  ./*.** Write the
7a90: 20 7a 43 6f 73 74 5b 5d 20 66 69 65 6c 64 20 66   zCost[] field f
7aa0: 6f 72 20 61 20 61 6d 61 74 63 68 5f 77 6f 72 64  or a amatch_word
7ab0: 20 6f 62 6a 65 63 74 0a 2a 2f 0a 73 74 61 74 69   object.*/.stati
7ac0: 63 20 76 6f 69 64 20 61 6d 61 74 63 68 57 72 69  c void amatchWri
7ad0: 74 65 43 6f 73 74 28 61 6d 61 74 63 68 5f 77 6f  teCost(amatch_wo
7ae0: 72 64 20 2a 70 57 6f 72 64 29 7b 0a 20 20 61 6d  rd *pWord){.  am
7af0: 61 74 63 68 45 6e 63 6f 64 65 49 6e 74 28 70 57  atchEncodeInt(pW
7b00: 6f 72 64 2d 3e 72 43 6f 73 74 2c 20 70 57 6f 72  ord->rCost, pWor
7b10: 64 2d 3e 7a 43 6f 73 74 29 3b 0a 20 20 61 6d 61  d->zCost);.  ama
7b20: 74 63 68 45 6e 63 6f 64 65 49 6e 74 28 70 57 6f  tchEncodeInt(pWo
7b30: 72 64 2d 3e 69 53 65 71 2c 20 70 57 6f 72 64 2d  rd->iSeq, pWord-
7b40: 3e 7a 43 6f 73 74 2b 34 29 3b 0a 20 20 70 57 6f  >zCost+4);.  pWo
7b50: 72 64 2d 3e 7a 43 6f 73 74 5b 38 5d 20 3d 20 30  rd->zCost[8] = 0
7b60: 3b 0a 7d 0a 0a 2f 2a 20 43 69 72 63 75 6d 76 65  ;.}../* Circumve
7b70: 6e 74 20 63 6f 6d 70 69 6c 65 72 20 77 61 72 6e  nt compiler warn
7b80: 69 6e 67 73 20 61 62 6f 75 74 20 74 68 65 20 75  ings about the u
7b90: 73 65 20 6f 66 20 73 74 72 63 70 79 28 29 20 62  se of strcpy() b
7ba0: 79 20 73 75 70 70 6c 79 69 6e 67 0a 2a 2a 20 6f  y supplying.** o
7bb0: 75 72 20 6f 77 6e 20 69 6d 70 6c 65 6d 65 6e 74  ur own implement
7bc0: 61 74 69 6f 6e 2e 0a 2a 2f 0a 73 74 61 74 69 63  ation..*/.static
7bd0: 20 76 6f 69 64 20 61 6d 61 74 63 68 53 74 72 63   void amatchStrc
7be0: 70 79 28 63 68 61 72 20 2a 64 65 73 74 2c 20 63  py(char *dest, c
7bf0: 6f 6e 73 74 20 63 68 61 72 20 2a 73 72 63 29 7b  onst char *src){
7c00: 0a 20 20 77 68 69 6c 65 28 20 28 2a 28 64 65 73  .  while( (*(des
7c10: 74 2b 2b 29 20 3d 20 2a 28 73 72 63 2b 2b 29 29  t++) = *(src++))
7c20: 21 3d 30 20 29 7b 7d 0a 7d 0a 73 74 61 74 69 63  !=0 ){}.}.static
7c30: 20 76 6f 69 64 20 61 6d 61 74 63 68 53 74 72 63   void amatchStrc
7c40: 61 74 28 63 68 61 72 20 2a 64 65 73 74 2c 20 63  at(char *dest, c
7c50: 6f 6e 73 74 20 63 68 61 72 20 2a 73 72 63 29 7b  onst char *src){
7c60: 0a 20 20 77 68 69 6c 65 28 20 2a 64 65 73 74 20  .  while( *dest 
7c70: 29 20 64 65 73 74 2b 2b 3b 0a 20 20 61 6d 61 74  ) dest++;.  amat
7c80: 63 68 53 74 72 63 70 79 28 64 65 73 74 2c 20 73  chStrcpy(dest, s
7c90: 72 63 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41 64  rc);.}../*.** Ad
7ca0: 64 20 61 20 6e 65 77 20 61 6d 61 74 63 68 5f 77  d a new amatch_w
7cb0: 6f 72 64 20 6f 62 6a 65 63 74 20 74 6f 20 74 68  ord object to th
7cc0: 65 20 71 75 65 75 65 2e 0a 2a 2a 0a 2a 2a 20 49  e queue..**.** I
7cd0: 66 20 61 20 70 72 69 6f 72 20 61 6d 61 74 63 68  f a prior amatch
7ce0: 5f 77 6f 72 64 20 6f 62 6a 65 63 74 20 77 69 74  _word object wit
7cf0: 68 20 74 68 65 20 73 61 6d 65 20 7a 57 6f 72 64  h the same zWord
7d00: 2c 20 61 6e 64 20 6e 4d 61 74 63 68 0a 2a 2a 20  , and nMatch.** 
7d10: 61 6c 72 65 61 64 79 20 65 78 69 73 74 73 2c 20  already exists, 
7d20: 75 70 64 61 74 65 20 69 74 73 20 72 43 6f 73 74  update its rCost
7d30: 20 28 69 66 20 74 68 65 20 6e 65 77 20 72 43 6f   (if the new rCo
7d40: 73 74 20 69 73 20 6c 65 73 73 29 20 62 75 74 0a  st is less) but.
7d50: 2a 2a 20 6f 74 68 65 72 77 69 73 65 20 6c 65 61  ** otherwise lea
7d60: 76 65 20 69 74 20 75 6e 63 68 61 6e 67 65 64 2e  ve it unchanged.
7d70: 20 20 44 6f 20 6e 6f 74 20 61 64 64 20 61 20 64    Do not add a d
7d80: 75 70 6c 69 63 61 74 65 2e 0a 2a 2a 0a 2a 2a 20  uplicate..**.** 
7d90: 44 6f 20 6e 6f 74 68 69 6e 67 20 69 66 20 74 68  Do nothing if th
7da0: 65 20 63 6f 73 74 20 65 78 63 65 65 64 73 20 74  e cost exceeds t
7db0: 68 72 65 73 68 6f 6c 64 2e 0a 2a 2f 0a 73 74 61  hreshold..*/.sta
7dc0: 74 69 63 20 76 6f 69 64 20 61 6d 61 74 63 68 41  tic void amatchA
7dd0: 64 64 57 6f 72 64 28 0a 20 20 61 6d 61 74 63 68  ddWord(.  amatch
7de0: 5f 63 75 72 73 6f 72 20 2a 70 43 75 72 2c 0a 20  _cursor *pCur,. 
7df0: 20 61 6d 61 74 63 68 5f 63 6f 73 74 20 72 43 6f   amatch_cost rCo
7e00: 73 74 2c 0a 20 20 69 6e 74 20 6e 4d 61 74 63 68  st,.  int nMatch
7e10: 2c 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a  ,.  const char *
7e20: 7a 57 6f 72 64 42 61 73 65 2c 0a 20 20 63 6f 6e  zWordBase,.  con
7e30: 73 74 20 63 68 61 72 20 2a 7a 57 6f 72 64 54 61  st char *zWordTa
7e40: 69 6c 0a 29 7b 0a 20 20 61 6d 61 74 63 68 5f 77  il.){.  amatch_w
7e50: 6f 72 64 20 2a 70 57 6f 72 64 3b 0a 20 20 61 6d  ord *pWord;.  am
7e60: 61 74 63 68 5f 61 76 6c 20 2a 70 4e 6f 64 65 3b  atch_avl *pNode;
7e70: 0a 20 20 61 6d 61 74 63 68 5f 61 76 6c 20 2a 70  .  amatch_avl *p
7e80: 4f 74 68 65 72 3b 0a 20 20 69 6e 74 20 6e 42 61  Other;.  int nBa
7e90: 73 65 2c 20 6e 54 61 69 6c 3b 0a 20 20 63 68 61  se, nTail;.  cha
7ea0: 72 20 7a 42 75 66 5b 34 5d 3b 0a 20 20 0a 20 20  r zBuf[4];.  .  
7eb0: 69 66 28 20 72 43 6f 73 74 3e 70 43 75 72 2d 3e  if( rCost>pCur->
7ec0: 72 4c 69 6d 69 74 20 29 7b 0a 20 20 20 20 72 65  rLimit ){.    re
7ed0: 74 75 72 6e 3b 0a 20 20 7d 0a 20 20 6e 42 61 73  turn;.  }.  nBas
7ee0: 65 20 3d 20 28 69 6e 74 29 73 74 72 6c 65 6e 28  e = (int)strlen(
7ef0: 7a 57 6f 72 64 42 61 73 65 29 3b 0a 20 20 6e 54  zWordBase);.  nT
7f00: 61 69 6c 20 3d 20 28 69 6e 74 29 73 74 72 6c 65  ail = (int)strle
7f10: 6e 28 7a 57 6f 72 64 54 61 69 6c 29 3b 0a 20 20  n(zWordTail);.  
7f20: 69 66 28 20 6e 42 61 73 65 2b 6e 54 61 69 6c 2b  if( nBase+nTail+
7f30: 33 3e 70 43 75 72 2d 3e 6e 42 75 66 20 29 7b 0a  3>pCur->nBuf ){.
7f40: 20 20 20 20 70 43 75 72 2d 3e 6e 42 75 66 20 3d      pCur->nBuf =
7f50: 20 6e 42 61 73 65 2b 6e 54 61 69 6c 2b 31 30 30   nBase+nTail+100
7f60: 3b 0a 20 20 20 20 70 43 75 72 2d 3e 7a 42 75 66  ;.    pCur->zBuf
7f70: 20 3d 20 73 71 6c 69 74 65 33 5f 72 65 61 6c 6c   = sqlite3_reall
7f80: 6f 63 28 70 43 75 72 2d 3e 7a 42 75 66 2c 20 70  oc(pCur->zBuf, p
7f90: 43 75 72 2d 3e 6e 42 75 66 29 3b 0a 20 20 20 20  Cur->nBuf);.    
7fa0: 69 66 28 20 70 43 75 72 2d 3e 7a 42 75 66 3d 3d  if( pCur->zBuf==
7fb0: 30 20 29 7b 0a 20 20 20 20 20 20 70 43 75 72 2d  0 ){.      pCur-
7fc0: 3e 6e 42 75 66 20 3d 20 30 3b 0a 20 20 20 20 20  >nBuf = 0;.     
7fd0: 20 72 65 74 75 72 6e 3b 0a 20 20 20 20 7d 0a 20   return;.    }. 
7fe0: 20 7d 0a 20 20 61 6d 61 74 63 68 45 6e 63 6f 64   }.  amatchEncod
7ff0: 65 49 6e 74 28 6e 4d 61 74 63 68 2c 20 7a 42 75  eInt(nMatch, zBu
8000: 66 29 3b 0a 20 20 6d 65 6d 63 70 79 28 70 43 75  f);.  memcpy(pCu
8010: 72 2d 3e 7a 42 75 66 2c 20 7a 42 75 66 2b 32 2c  r->zBuf, zBuf+2,
8020: 20 32 29 3b 0a 20 20 6d 65 6d 63 70 79 28 70 43   2);.  memcpy(pC
8030: 75 72 2d 3e 7a 42 75 66 2b 32 2c 20 7a 57 6f 72  ur->zBuf+2, zWor
8040: 64 42 61 73 65 2c 20 6e 42 61 73 65 29 3b 0a 20  dBase, nBase);. 
8050: 20 6d 65 6d 63 70 79 28 70 43 75 72 2d 3e 7a 42   memcpy(pCur->zB
8060: 75 66 2b 32 2b 6e 42 61 73 65 2c 20 7a 57 6f 72  uf+2+nBase, zWor
8070: 64 54 61 69 6c 2c 20 6e 54 61 69 6c 2b 31 29 3b  dTail, nTail+1);
8080: 0a 20 20 70 4e 6f 64 65 20 3d 20 61 6d 61 74 63  .  pNode = amatc
8090: 68 41 76 6c 53 65 61 72 63 68 28 70 43 75 72 2d  hAvlSearch(pCur-
80a0: 3e 70 57 6f 72 64 2c 20 70 43 75 72 2d 3e 7a 42  >pWord, pCur->zB
80b0: 75 66 29 3b 0a 20 20 69 66 28 20 70 4e 6f 64 65  uf);.  if( pNode
80c0: 20 29 7b 0a 20 20 20 20 70 57 6f 72 64 20 3d 20   ){.    pWord = 
80d0: 70 4e 6f 64 65 2d 3e 70 57 6f 72 64 3b 0a 20 20  pNode->pWord;.  
80e0: 20 20 69 66 28 20 70 57 6f 72 64 2d 3e 72 43 6f    if( pWord->rCo
80f0: 73 74 3e 72 43 6f 73 74 20 29 7b 0a 23 69 66 64  st>rCost ){.#ifd
8100: 65 66 20 41 4d 41 54 43 48 5f 54 52 41 43 45 5f  ef AMATCH_TRACE_
8110: 31 0a 20 20 20 20 20 20 70 72 69 6e 74 66 28 22  1.      printf("
8120: 55 50 44 41 54 45 20 5b 25 73 5d 5b 25 2e 2a 73  UPDATE [%s][%.*s
8130: 5e 25 73 5d 20 25 64 20 28 5c 22 25 73 5c 22 20  ^%s] %d (\"%s\" 
8140: 5c 22 25 73 5c 22 29 5c 6e 22 2c 0a 20 20 20 20  \"%s\")\n",.    
8150: 20 20 20 20 20 20 20 20 20 70 57 6f 72 64 2d 3e           pWord->
8160: 7a 57 6f 72 64 2b 32 2c 20 70 57 6f 72 64 2d 3e  zWord+2, pWord->
8170: 6e 4d 61 74 63 68 2c 20 70 43 75 72 2d 3e 7a 49  nMatch, pCur->zI
8180: 6e 70 75 74 2c 20 70 43 75 72 2d 3e 7a 49 6e 70  nput, pCur->zInp
8190: 75 74 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20  ut,.            
81a0: 20 70 57 6f 72 64 2d 3e 72 43 6f 73 74 2c 20 70   pWord->rCost, p
81b0: 57 6f 72 64 2d 3e 7a 57 6f 72 64 2c 20 70 57 6f  Word->zWord, pWo
81c0: 72 64 2d 3e 7a 43 6f 73 74 29 3b 0a 23 65 6e 64  rd->zCost);.#end
81d0: 69 66 0a 20 20 20 20 20 20 61 6d 61 74 63 68 41  if.      amatchA
81e0: 76 6c 52 65 6d 6f 76 65 28 26 70 43 75 72 2d 3e  vlRemove(&pCur->
81f0: 70 43 6f 73 74 2c 20 26 70 57 6f 72 64 2d 3e 73  pCost, &pWord->s
8200: 43 6f 73 74 29 3b 0a 20 20 20 20 20 20 70 57 6f  Cost);.      pWo
8210: 72 64 2d 3e 72 43 6f 73 74 20 3d 20 72 43 6f 73  rd->rCost = rCos
8220: 74 3b 0a 20 20 20 20 20 20 61 6d 61 74 63 68 57  t;.      amatchW
8230: 72 69 74 65 43 6f 73 74 28 70 57 6f 72 64 29 3b  riteCost(pWord);
8240: 0a 23 69 66 64 65 66 20 41 4d 41 54 43 48 5f 54  .#ifdef AMATCH_T
8250: 52 41 43 45 5f 31 0a 20 20 20 20 20 20 70 72 69  RACE_1.      pri
8260: 6e 74 66 28 22 20 20 2d 2d 2d 3e 20 25 64 20 28  ntf("  ---> %d (
8270: 5c 22 25 73 5c 22 20 5c 22 25 73 5c 22 29 5c 6e  \"%s\" \"%s\")\n
8280: 22 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  ",.             
8290: 70 57 6f 72 64 2d 3e 72 43 6f 73 74 2c 20 70 57  pWord->rCost, pW
82a0: 6f 72 64 2d 3e 7a 57 6f 72 64 2c 20 70 57 6f 72  ord->zWord, pWor
82b0: 64 2d 3e 7a 43 6f 73 74 29 3b 0a 23 65 6e 64 69  d->zCost);.#endi
82c0: 66 0a 20 20 20 20 20 20 70 4f 74 68 65 72 20 3d  f.      pOther =
82d0: 20 61 6d 61 74 63 68 41 76 6c 49 6e 73 65 72 74   amatchAvlInsert
82e0: 28 26 70 43 75 72 2d 3e 70 43 6f 73 74 2c 20 26  (&pCur->pCost, &
82f0: 70 57 6f 72 64 2d 3e 73 43 6f 73 74 29 3b 0a 20  pWord->sCost);. 
8300: 20 20 20 20 20 61 73 73 65 72 74 28 20 70 4f 74       assert( pOt
8310: 68 65 72 3d 3d 30 20 29 3b 20 28 76 6f 69 64 29  her==0 ); (void)
8320: 70 4f 74 68 65 72 3b 0a 20 20 20 20 7d 0a 20 20  pOther;.    }.  
8330: 20 20 72 65 74 75 72 6e 3b 0a 20 20 7d 0a 20 20    return;.  }.  
8340: 70 57 6f 72 64 20 3d 20 73 71 6c 69 74 65 33 5f  pWord = sqlite3_
8350: 6d 61 6c 6c 6f 63 36 34 28 20 73 69 7a 65 6f 66  malloc64( sizeof
8360: 28 2a 70 57 6f 72 64 29 20 2b 20 6e 42 61 73 65  (*pWord) + nBase
8370: 20 2b 20 6e 54 61 69 6c 20 2d 20 31 20 29 3b 0a   + nTail - 1 );.
8380: 20 20 69 66 28 20 70 57 6f 72 64 3d 3d 30 20 29    if( pWord==0 )
8390: 20 72 65 74 75 72 6e 3b 0a 20 20 6d 65 6d 73 65   return;.  memse
83a0: 74 28 70 57 6f 72 64 2c 20 30 2c 20 73 69 7a 65  t(pWord, 0, size
83b0: 6f 66 28 2a 70 57 6f 72 64 29 29 3b 0a 20 20 70  of(*pWord));.  p
83c0: 57 6f 72 64 2d 3e 72 43 6f 73 74 20 3d 20 72 43  Word->rCost = rC
83d0: 6f 73 74 3b 0a 20 20 70 57 6f 72 64 2d 3e 69 53  ost;.  pWord->iS
83e0: 65 71 20 3d 20 70 43 75 72 2d 3e 6e 57 6f 72 64  eq = pCur->nWord
83f0: 2b 2b 3b 0a 20 20 61 6d 61 74 63 68 57 72 69 74  ++;.  amatchWrit
8400: 65 43 6f 73 74 28 70 57 6f 72 64 29 3b 0a 20 20  eCost(pWord);.  
8410: 70 57 6f 72 64 2d 3e 6e 4d 61 74 63 68 20 3d 20  pWord->nMatch = 
8420: 28 73 68 6f 72 74 29 6e 4d 61 74 63 68 3b 0a 20  (short)nMatch;. 
8430: 20 70 57 6f 72 64 2d 3e 70 4e 65 78 74 20 3d 20   pWord->pNext = 
8440: 70 43 75 72 2d 3e 70 41 6c 6c 57 6f 72 64 73 3b  pCur->pAllWords;
8450: 0a 20 20 70 43 75 72 2d 3e 70 41 6c 6c 57 6f 72  .  pCur->pAllWor
8460: 64 73 20 3d 20 70 57 6f 72 64 3b 0a 20 20 70 57  ds = pWord;.  pW
8470: 6f 72 64 2d 3e 73 43 6f 73 74 2e 7a 4b 65 79 20  ord->sCost.zKey 
8480: 3d 20 70 57 6f 72 64 2d 3e 7a 43 6f 73 74 3b 0a  = pWord->zCost;.
8490: 20 20 70 57 6f 72 64 2d 3e 73 43 6f 73 74 2e 70    pWord->sCost.p
84a0: 57 6f 72 64 20 3d 20 70 57 6f 72 64 3b 0a 20 20  Word = pWord;.  
84b0: 70 4f 74 68 65 72 20 3d 20 61 6d 61 74 63 68 41  pOther = amatchA
84c0: 76 6c 49 6e 73 65 72 74 28 26 70 43 75 72 2d 3e  vlInsert(&pCur->
84d0: 70 43 6f 73 74 2c 20 26 70 57 6f 72 64 2d 3e 73  pCost, &pWord->s
84e0: 43 6f 73 74 29 3b 0a 20 20 61 73 73 65 72 74 28  Cost);.  assert(
84f0: 20 70 4f 74 68 65 72 3d 3d 30 20 29 3b 20 28 76   pOther==0 ); (v
8500: 6f 69 64 29 70 4f 74 68 65 72 3b 0a 20 20 70 57  oid)pOther;.  pW
8510: 6f 72 64 2d 3e 73 57 6f 72 64 2e 7a 4b 65 79 20  ord->sWord.zKey 
8520: 3d 20 70 57 6f 72 64 2d 3e 7a 57 6f 72 64 3b 0a  = pWord->zWord;.
8530: 20 20 70 57 6f 72 64 2d 3e 73 57 6f 72 64 2e 70    pWord->sWord.p
8540: 57 6f 72 64 20 3d 20 70 57 6f 72 64 3b 0a 20 20  Word = pWord;.  
8550: 61 6d 61 74 63 68 53 74 72 63 70 79 28 70 57 6f  amatchStrcpy(pWo
8560: 72 64 2d 3e 7a 57 6f 72 64 2c 20 70 43 75 72 2d  rd->zWord, pCur-
8570: 3e 7a 42 75 66 29 3b 0a 20 20 70 4f 74 68 65 72  >zBuf);.  pOther
8580: 20 3d 20 61 6d 61 74 63 68 41 76 6c 49 6e 73 65   = amatchAvlInse
8590: 72 74 28 26 70 43 75 72 2d 3e 70 57 6f 72 64 2c  rt(&pCur->pWord,
85a0: 20 26 70 57 6f 72 64 2d 3e 73 57 6f 72 64 29 3b   &pWord->sWord);
85b0: 0a 20 20 61 73 73 65 72 74 28 20 70 4f 74 68 65  .  assert( pOthe
85c0: 72 3d 3d 30 20 29 3b 20 28 76 6f 69 64 29 70 4f  r==0 ); (void)pO
85d0: 74 68 65 72 3b 0a 23 69 66 64 65 66 20 41 4d 41  ther;.#ifdef AMA
85e0: 54 43 48 5f 54 52 41 43 45 5f 31 0a 20 20 70 72  TCH_TRACE_1.  pr
85f0: 69 6e 74 66 28 22 49 4e 53 45 52 54 20 5b 25 73  intf("INSERT [%s
8600: 5d 5b 25 2e 2a 73 5e 25 73 5d 20 25 64 20 28 5c  ][%.*s^%s] %d (\
8610: 22 25 73 5c 22 20 5c 22 25 73 5c 22 29 5c 6e 22  "%s\" \"%s\")\n"
8620: 2c 20 70 57 6f 72 64 2d 3e 7a 57 6f 72 64 2b 32  , pWord->zWord+2
8630: 2c 0a 20 20 20 20 20 20 20 70 57 6f 72 64 2d 3e  ,.       pWord->
8640: 6e 4d 61 74 63 68 2c 20 70 43 75 72 2d 3e 7a 49  nMatch, pCur->zI
8650: 6e 70 75 74 2c 20 70 43 75 72 2d 3e 7a 49 6e 70  nput, pCur->zInp
8660: 75 74 2b 70 57 6f 72 64 2d 3e 6e 4d 61 74 63 68  ut+pWord->nMatch
8670: 2c 20 72 43 6f 73 74 2c 0a 20 20 20 20 20 20 20  , rCost,.       
8680: 70 57 6f 72 64 2d 3e 7a 57 6f 72 64 2c 20 70 57  pWord->zWord, pW
8690: 6f 72 64 2d 3e 7a 43 6f 73 74 29 3b 0a 23 65 6e  ord->zCost);.#en
86a0: 64 69 66 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 41 64  dif.}.../*.** Ad
86b0: 76 61 6e 63 65 20 61 20 63 75 72 73 6f 72 20 74  vance a cursor t
86c0: 6f 20 69 74 73 20 6e 65 78 74 20 72 6f 77 20 6f  o its next row o
86d0: 66 20 6f 75 74 70 75 74 0a 2a 2f 0a 73 74 61 74  f output.*/.stat
86e0: 69 63 20 69 6e 74 20 61 6d 61 74 63 68 4e 65 78  ic int amatchNex
86f0: 74 28 73 71 6c 69 74 65 33 5f 76 74 61 62 5f 63  t(sqlite3_vtab_c
8700: 75 72 73 6f 72 20 2a 63 75 72 29 7b 0a 20 20 61  ursor *cur){.  a
8710: 6d 61 74 63 68 5f 63 75 72 73 6f 72 20 2a 70 43  match_cursor *pC
8720: 75 72 20 3d 20 28 61 6d 61 74 63 68 5f 63 75 72  ur = (amatch_cur
8730: 73 6f 72 2a 29 63 75 72 3b 0a 20 20 61 6d 61 74  sor*)cur;.  amat
8740: 63 68 5f 77 6f 72 64 20 2a 70 57 6f 72 64 20 3d  ch_word *pWord =
8750: 20 30 3b 0a 20 20 61 6d 61 74 63 68 5f 61 76 6c   0;.  amatch_avl
8760: 20 2a 70 4e 6f 64 65 3b 0a 20 20 69 6e 74 20 69   *pNode;.  int i
8770: 73 4d 61 74 63 68 20 3d 20 30 3b 0a 20 20 61 6d  sMatch = 0;.  am
8780: 61 74 63 68 5f 76 74 61 62 20 2a 70 20 3d 20 70  atch_vtab *p = p
8790: 43 75 72 2d 3e 70 56 74 61 62 3b 0a 20 20 69 6e  Cur->pVtab;.  in
87a0: 74 20 6e 57 6f 72 64 3b 0a 20 20 69 6e 74 20 72  t nWord;.  int r
87b0: 63 3b 0a 20 20 69 6e 74 20 69 3b 0a 20 20 63 6f  c;.  int i;.  co
87c0: 6e 73 74 20 63 68 61 72 20 2a 7a 57 3b 0a 20 20  nst char *zW;.  
87d0: 61 6d 61 74 63 68 5f 72 75 6c 65 20 2a 70 52 75  amatch_rule *pRu
87e0: 6c 65 3b 0a 20 20 63 68 61 72 20 2a 7a 42 75 66  le;.  char *zBuf
87f0: 20 3d 20 30 3b 0a 20 20 63 68 61 72 20 6e 42 75   = 0;.  char nBu
8800: 66 20 3d 20 30 3b 0a 20 20 63 68 61 72 20 7a 4e  f = 0;.  char zN
8810: 65 78 74 5b 38 5d 3b 0a 20 20 63 68 61 72 20 7a  ext[8];.  char z
8820: 4e 65 78 74 49 6e 5b 38 5d 3b 0a 20 20 69 6e 74  NextIn[8];.  int
8830: 20 6e 4e 65 78 74 49 6e 3b 0a 0a 20 20 69 66 28   nNextIn;..  if(
8840: 20 70 2d 3e 70 56 43 68 65 63 6b 3d 3d 30 20 29   p->pVCheck==0 )
8850: 7b 0a 20 20 20 20 63 68 61 72 20 2a 7a 53 71 6c  {.    char *zSql
8860: 3b 0a 20 20 20 20 69 66 28 20 70 2d 3e 7a 56 6f  ;.    if( p->zVo
8870: 63 61 62 4c 61 6e 67 20 26 26 20 70 2d 3e 7a 56  cabLang && p->zV
8880: 6f 63 61 62 4c 61 6e 67 5b 30 5d 20 29 7b 0a 20  ocabLang[0] ){. 
8890: 20 20 20 20 20 7a 53 71 6c 20 3d 20 73 71 6c 69       zSql = sqli
88a0: 74 65 33 5f 6d 70 72 69 6e 74 66 28 0a 20 20 20  te3_mprintf(.   
88b0: 20 20 20 20 20 20 20 22 53 45 4c 45 43 54 20 5c         "SELECT \
88c0: 22 25 77 5c 22 20 46 52 4f 4d 20 5c 22 25 77 5c  "%w\" FROM \"%w\
88d0: 22 22 2c 0a 20 20 20 20 20 20 20 20 20 20 22 20  "",.          " 
88e0: 57 48 45 52 45 20 5c 22 25 77 5c 22 3e 3d 3f 31  WHERE \"%w\">=?1
88f0: 20 41 4e 44 20 5c 22 25 77 5c 22 3d 3f 32 22 0a   AND \"%w\"=?2".
8900: 20 20 20 20 20 20 20 20 20 20 22 20 4f 52 44 45            " ORDE
8910: 52 20 42 59 20 31 22 2c 0a 20 20 20 20 20 20 20  R BY 1",.       
8920: 20 20 20 70 2d 3e 7a 56 6f 63 61 62 57 6f 72 64     p->zVocabWord
8930: 2c 20 70 2d 3e 7a 56 6f 63 61 62 54 61 62 2c 0a  , p->zVocabTab,.
8940: 20 20 20 20 20 20 20 20 20 20 70 2d 3e 7a 56 6f            p->zVo
8950: 63 61 62 57 6f 72 64 2c 20 70 2d 3e 7a 56 6f 63  cabWord, p->zVoc
8960: 61 62 4c 61 6e 67 0a 20 20 20 20 20 20 29 3b 0a  abLang.      );.
8970: 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20      }else{.     
8980: 20 7a 53 71 6c 20 3d 20 73 71 6c 69 74 65 33 5f   zSql = sqlite3_
8990: 6d 70 72 69 6e 74 66 28 0a 20 20 20 20 20 20 20  mprintf(.       
89a0: 20 20 20 22 53 45 4c 45 43 54 20 5c 22 25 77 5c     "SELECT \"%w\
89b0: 22 20 46 52 4f 4d 20 5c 22 25 77 5c 22 22 0a 20  " FROM \"%w\"". 
89c0: 20 20 20 20 20 20 20 20 20 22 20 57 48 45 52 45           " WHERE
89d0: 20 5c 22 25 77 5c 22 3e 3d 3f 31 22 0a 20 20 20   \"%w\">=?1".   
89e0: 20 20 20 20 20 20 20 22 20 4f 52 44 45 52 20 42         " ORDER B
89f0: 59 20 31 22 2c 0a 20 20 20 20 20 20 20 20 20 20  Y 1",.          
8a00: 70 2d 3e 7a 56 6f 63 61 62 57 6f 72 64 2c 20 70  p->zVocabWord, p
8a10: 2d 3e 7a 56 6f 63 61 62 54 61 62 2c 0a 20 20 20  ->zVocabTab,.   
8a20: 20 20 20 20 20 20 20 70 2d 3e 7a 56 6f 63 61 62         p->zVocab
8a30: 57 6f 72 64 0a 20 20 20 20 20 20 29 3b 0a 20 20  Word.      );.  
8a40: 20 20 7d 0a 20 20 20 20 72 63 20 3d 20 73 71 6c    }.    rc = sql
8a50: 69 74 65 33 5f 70 72 65 70 61 72 65 5f 76 32 28  ite3_prepare_v2(
8a60: 70 2d 3e 64 62 2c 20 7a 53 71 6c 2c 20 2d 31 2c  p->db, zSql, -1,
8a70: 20 26 70 2d 3e 70 56 43 68 65 63 6b 2c 20 30 29   &p->pVCheck, 0)
8a80: 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72  ;.    sqlite3_fr
8a90: 65 65 28 7a 53 71 6c 29 3b 0a 20 20 20 20 69 66  ee(zSql);.    if
8aa0: 28 20 72 63 20 29 20 72 65 74 75 72 6e 20 72 63  ( rc ) return rc
8ab0: 3b 0a 20 20 7d 0a 20 20 73 71 6c 69 74 65 33 5f  ;.  }.  sqlite3_
8ac0: 62 69 6e 64 5f 69 6e 74 28 70 2d 3e 70 56 43 68  bind_int(p->pVCh
8ad0: 65 63 6b 2c 20 32 2c 20 70 43 75 72 2d 3e 69 4c  eck, 2, pCur->iL
8ae0: 61 6e 67 29 3b 0a 0a 20 20 64 6f 7b 0a 20 20 20  ang);..  do{.   
8af0: 20 70 4e 6f 64 65 20 3d 20 61 6d 61 74 63 68 41   pNode = amatchA
8b00: 76 6c 46 69 72 73 74 28 70 43 75 72 2d 3e 70 43  vlFirst(pCur->pC
8b10: 6f 73 74 29 3b 0a 20 20 20 20 69 66 28 20 70 4e  ost);.    if( pN
8b20: 6f 64 65 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20  ode==0 ){.      
8b30: 70 57 6f 72 64 20 3d 20 30 3b 0a 20 20 20 20 20  pWord = 0;.     
8b40: 20 62 72 65 61 6b 3b 0a 20 20 20 20 7d 0a 20 20   break;.    }.  
8b50: 20 20 70 57 6f 72 64 20 3d 20 70 4e 6f 64 65 2d    pWord = pNode-
8b60: 3e 70 57 6f 72 64 3b 0a 20 20 20 20 61 6d 61 74  >pWord;.    amat
8b70: 63 68 41 76 6c 52 65 6d 6f 76 65 28 26 70 43 75  chAvlRemove(&pCu
8b80: 72 2d 3e 70 43 6f 73 74 2c 20 26 70 57 6f 72 64  r->pCost, &pWord
8b90: 2d 3e 73 43 6f 73 74 29 3b 0a 0a 23 69 66 64 65  ->sCost);..#ifde
8ba0: 66 20 41 4d 41 54 43 48 5f 54 52 41 43 45 5f 31  f AMATCH_TRACE_1
8bb0: 0a 20 20 20 20 70 72 69 6e 74 66 28 22 50 52 4f  .    printf("PRO
8bc0: 43 45 53 53 20 5b 25 73 5d 5b 25 2e 2a 73 5e 25  CESS [%s][%.*s^%
8bd0: 73 5d 20 25 64 20 28 5c 22 25 73 5c 22 20 5c 22  s] %d (\"%s\" \"
8be0: 25 73 5c 22 29 5c 6e 22 2c 0a 20 20 20 20 20 20  %s\")\n",.      
8bf0: 20 70 57 6f 72 64 2d 3e 7a 57 6f 72 64 2b 32 2c   pWord->zWord+2,
8c00: 20 70 57 6f 72 64 2d 3e 6e 4d 61 74 63 68 2c 20   pWord->nMatch, 
8c10: 70 43 75 72 2d 3e 7a 49 6e 70 75 74 2c 20 70 43  pCur->zInput, pC
8c20: 75 72 2d 3e 7a 49 6e 70 75 74 2b 70 57 6f 72 64  ur->zInput+pWord
8c30: 2d 3e 6e 4d 61 74 63 68 2c 0a 20 20 20 20 20 20  ->nMatch,.      
8c40: 20 70 57 6f 72 64 2d 3e 72 43 6f 73 74 2c 20 70   pWord->rCost, p
8c50: 57 6f 72 64 2d 3e 7a 57 6f 72 64 2c 20 70 57 6f  Word->zWord, pWo
8c60: 72 64 2d 3e 7a 43 6f 73 74 29 3b 0a 23 65 6e 64  rd->zCost);.#end
8c70: 69 66 0a 20 20 20 20 6e 57 6f 72 64 20 3d 20 28  if.    nWord = (
8c80: 69 6e 74 29 73 74 72 6c 65 6e 28 70 57 6f 72 64  int)strlen(pWord
8c90: 2d 3e 7a 57 6f 72 64 2b 32 29 3b 0a 20 20 20 20  ->zWord+2);.    
8ca0: 69 66 28 20 6e 57 6f 72 64 2b 32 30 3e 6e 42 75  if( nWord+20>nBu
8cb0: 66 20 29 7b 0a 20 20 20 20 20 20 6e 42 75 66 20  f ){.      nBuf 
8cc0: 3d 20 28 63 68 61 72 29 28 6e 57 6f 72 64 2b 31  = (char)(nWord+1
8cd0: 30 30 29 3b 0a 20 20 20 20 20 20 7a 42 75 66 20  00);.      zBuf 
8ce0: 3d 20 73 71 6c 69 74 65 33 5f 72 65 61 6c 6c 6f  = sqlite3_reallo
8cf0: 63 28 7a 42 75 66 2c 20 6e 42 75 66 29 3b 0a 20  c(zBuf, nBuf);. 
8d00: 20 20 20 20 20 69 66 28 20 7a 42 75 66 3d 3d 30       if( zBuf==0
8d10: 20 29 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45   ) return SQLITE
8d20: 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 7d 0a 20 20  _NOMEM;.    }.  
8d30: 20 20 61 6d 61 74 63 68 53 74 72 63 70 79 28 7a    amatchStrcpy(z
8d40: 42 75 66 2c 20 70 57 6f 72 64 2d 3e 7a 57 6f 72  Buf, pWord->zWor
8d50: 64 2b 32 29 3b 0a 20 20 20 20 7a 4e 65 78 74 5b  d+2);.    zNext[
8d60: 30 5d 20 3d 20 30 3b 0a 20 20 20 20 7a 4e 65 78  0] = 0;.    zNex
8d70: 74 49 6e 5b 30 5d 20 3d 20 70 43 75 72 2d 3e 7a  tIn[0] = pCur->z
8d80: 49 6e 70 75 74 5b 70 57 6f 72 64 2d 3e 6e 4d 61  Input[pWord->nMa
8d90: 74 63 68 5d 3b 0a 20 20 20 20 69 66 28 20 7a 4e  tch];.    if( zN
8da0: 65 78 74 49 6e 5b 30 5d 20 29 7b 0a 20 20 20 20  extIn[0] ){.    
8db0: 20 20 66 6f 72 28 69 3d 31 3b 20 69 3c 3d 34 20    for(i=1; i<=4 
8dc0: 26 26 20 28 70 43 75 72 2d 3e 7a 49 6e 70 75 74  && (pCur->zInput
8dd0: 5b 70 57 6f 72 64 2d 3e 6e 4d 61 74 63 68 2b 69  [pWord->nMatch+i
8de0: 5d 26 30 78 63 30 29 3d 3d 30 78 38 30 3b 20 69  ]&0xc0)==0x80; i
8df0: 2b 2b 29 7b 0a 20 20 20 20 20 20 20 20 7a 4e 65  ++){.        zNe
8e00: 78 74 49 6e 5b 69 5d 20 3d 20 70 43 75 72 2d 3e  xtIn[i] = pCur->
8e10: 7a 49 6e 70 75 74 5b 70 57 6f 72 64 2d 3e 6e 4d  zInput[pWord->nM
8e20: 61 74 63 68 2b 69 5d 3b 0a 20 20 20 20 20 20 7d  atch+i];.      }
8e30: 0a 20 20 20 20 20 20 7a 4e 65 78 74 49 6e 5b 69  .      zNextIn[i
8e40: 5d 20 3d 20 30 3b 0a 20 20 20 20 20 20 6e 4e 65  ] = 0;.      nNe
8e50: 78 74 49 6e 20 3d 20 69 3b 0a 20 20 20 20 7d 65  xtIn = i;.    }e
8e60: 6c 73 65 7b 0a 20 20 20 20 20 20 6e 4e 65 78 74  lse{.      nNext
8e70: 49 6e 20 3d 20 30 3b 0a 20 20 20 20 7d 0a 0a 20  In = 0;.    }.. 
8e80: 20 20 20 69 66 28 20 7a 4e 65 78 74 49 6e 5b 30     if( zNextIn[0
8e90: 5d 20 26 26 20 7a 4e 65 78 74 49 6e 5b 30 5d 21  ] && zNextIn[0]!
8ea0: 3d 27 2a 27 20 29 7b 0a 20 20 20 20 20 20 73 71  ='*' ){.      sq
8eb0: 6c 69 74 65 33 5f 72 65 73 65 74 28 70 2d 3e 70  lite3_reset(p->p
8ec0: 56 43 68 65 63 6b 29 3b 0a 20 20 20 20 20 20 61  VCheck);.      a
8ed0: 6d 61 74 63 68 53 74 72 63 61 74 28 7a 42 75 66  matchStrcat(zBuf
8ee0: 2c 20 7a 4e 65 78 74 49 6e 29 3b 0a 20 20 20 20  , zNextIn);.    
8ef0: 20 20 73 71 6c 69 74 65 33 5f 62 69 6e 64 5f 74    sqlite3_bind_t
8f00: 65 78 74 28 70 2d 3e 70 56 43 68 65 63 6b 2c 20  ext(p->pVCheck, 
8f10: 31 2c 20 7a 42 75 66 2c 20 6e 57 6f 72 64 2b 6e  1, zBuf, nWord+n
8f20: 4e 65 78 74 49 6e 2c 20 53 51 4c 49 54 45 5f 53  NextIn, SQLITE_S
8f30: 54 41 54 49 43 29 3b 0a 20 20 20 20 20 20 72 63  TATIC);.      rc
8f40: 20 3d 20 73 71 6c 69 74 65 33 5f 73 74 65 70 28   = sqlite3_step(
8f50: 70 2d 3e 70 56 43 68 65 63 6b 29 3b 0a 20 20 20  p->pVCheck);.   
8f60: 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54     if( rc==SQLIT
8f70: 45 5f 52 4f 57 20 29 7b 0a 20 20 20 20 20 20 20  E_ROW ){.       
8f80: 20 7a 57 20 3d 20 28 63 6f 6e 73 74 20 63 68 61   zW = (const cha
8f90: 72 2a 29 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d  r*)sqlite3_colum
8fa0: 6e 5f 74 65 78 74 28 70 2d 3e 70 56 43 68 65 63  n_text(p->pVChec
8fb0: 6b 2c 20 30 29 3b 0a 20 20 20 20 20 20 20 20 69  k, 0);.        i
8fc0: 66 28 20 73 74 72 6e 63 6d 70 28 7a 42 75 66 2c  f( strncmp(zBuf,
8fd0: 20 7a 57 2c 20 6e 57 6f 72 64 2b 6e 4e 65 78 74   zW, nWord+nNext
8fe0: 49 6e 29 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20  In)==0 ){.      
8ff0: 20 20 20 20 61 6d 61 74 63 68 41 64 64 57 6f 72      amatchAddWor
9000: 64 28 70 43 75 72 2c 20 70 57 6f 72 64 2d 3e 72  d(pCur, pWord->r
9010: 43 6f 73 74 2c 20 70 57 6f 72 64 2d 3e 6e 4d 61  Cost, pWord->nMa
9020: 74 63 68 2b 6e 4e 65 78 74 49 6e 2c 20 7a 42 75  tch+nNextIn, zBu
9030: 66 2c 20 22 22 29 3b 0a 20 20 20 20 20 20 20 20  f, "");.        
9040: 7d 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20  }.      }.      
9050: 7a 42 75 66 5b 6e 57 6f 72 64 5d 20 3d 20 30 3b  zBuf[nWord] = 0;
9060: 0a 20 20 20 20 7d 0a 0a 20 20 20 20 77 68 69 6c  .    }..    whil
9070: 65 28 20 31 20 29 7b 0a 20 20 20 20 20 20 61 6d  e( 1 ){.      am
9080: 61 74 63 68 53 74 72 63 70 79 28 7a 42 75 66 2b  atchStrcpy(zBuf+
9090: 6e 57 6f 72 64 2c 20 7a 4e 65 78 74 29 3b 0a 20  nWord, zNext);. 
90a0: 20 20 20 20 20 73 71 6c 69 74 65 33 5f 72 65 73       sqlite3_res
90b0: 65 74 28 70 2d 3e 70 56 43 68 65 63 6b 29 3b 0a  et(p->pVCheck);.
90c0: 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 62 69        sqlite3_bi
90d0: 6e 64 5f 74 65 78 74 28 70 2d 3e 70 56 43 68 65  nd_text(p->pVChe
90e0: 63 6b 2c 20 31 2c 20 7a 42 75 66 2c 20 2d 31 2c  ck, 1, zBuf, -1,
90f0: 20 53 51 4c 49 54 45 5f 54 52 41 4e 53 49 45 4e   SQLITE_TRANSIEN
9100: 54 29 3b 0a 20 20 20 20 20 20 72 63 20 3d 20 73  T);.      rc = s
9110: 71 6c 69 74 65 33 5f 73 74 65 70 28 70 2d 3e 70  qlite3_step(p->p
9120: 56 43 68 65 63 6b 29 3b 0a 20 20 20 20 20 20 69  VCheck);.      i
9130: 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 52 4f  f( rc!=SQLITE_RO
9140: 57 20 29 20 62 72 65 61 6b 3b 0a 20 20 20 20 20  W ) break;.     
9150: 20 7a 57 20 3d 20 28 63 6f 6e 73 74 20 63 68 61   zW = (const cha
9160: 72 2a 29 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d  r*)sqlite3_colum
9170: 6e 5f 74 65 78 74 28 70 2d 3e 70 56 43 68 65 63  n_text(p->pVChec
9180: 6b 2c 20 30 29 3b 0a 20 20 20 20 20 20 61 6d 61  k, 0);.      ama
9190: 74 63 68 53 74 72 63 70 79 28 7a 42 75 66 2b 6e  tchStrcpy(zBuf+n
91a0: 57 6f 72 64 2c 20 7a 4e 65 78 74 29 3b 0a 20 20  Word, zNext);.  
91b0: 20 20 20 20 69 66 28 20 73 74 72 6e 63 6d 70 28      if( strncmp(
91c0: 7a 57 2c 20 7a 42 75 66 2c 20 6e 57 6f 72 64 29  zW, zBuf, nWord)
91d0: 21 3d 30 20 29 20 62 72 65 61 6b 3b 0a 20 20 20  !=0 ) break;.   
91e0: 20 20 20 69 66 28 20 28 7a 4e 65 78 74 49 6e 5b     if( (zNextIn[
91f0: 30 5d 3d 3d 27 2a 27 20 26 26 20 7a 4e 65 78 74  0]=='*' && zNext
9200: 49 6e 5b 31 5d 3d 3d 30 29 0a 20 20 20 20 20 20  In[1]==0).      
9210: 20 7c 7c 20 28 7a 4e 65 78 74 49 6e 5b 30 5d 3d   || (zNextIn[0]=
9220: 3d 30 20 26 26 20 7a 57 5b 6e 57 6f 72 64 5d 3d  =0 && zW[nWord]=
9230: 3d 30 29 0a 20 20 20 20 20 20 29 7b 0a 20 20 20  =0).      ){.   
9240: 20 20 20 20 20 69 73 4d 61 74 63 68 20 3d 20 31       isMatch = 1
9250: 3b 0a 20 20 20 20 20 20 20 20 7a 4e 65 78 74 49  ;.        zNextI
9260: 6e 5b 30 5d 20 3d 20 30 3b 0a 20 20 20 20 20 20  n[0] = 0;.      
9270: 20 20 6e 4e 65 78 74 49 6e 20 3d 20 30 3b 0a 20    nNextIn = 0;. 
9280: 20 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20         break;.  
9290: 20 20 20 20 7d 0a 20 20 20 20 20 20 7a 4e 65 78      }.      zNex
92a0: 74 5b 30 5d 20 3d 20 7a 57 5b 6e 57 6f 72 64 5d  t[0] = zW[nWord]
92b0: 3b 0a 20 20 20 20 20 20 66 6f 72 28 69 3d 31 3b  ;.      for(i=1;
92c0: 20 69 3c 3d 34 20 26 26 20 28 7a 57 5b 6e 57 6f   i<=4 && (zW[nWo
92d0: 72 64 2b 69 5d 26 30 78 63 30 29 3d 3d 30 78 38  rd+i]&0xc0)==0x8
92e0: 30 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20 20  0; i++){.       
92f0: 20 7a 4e 65 78 74 5b 69 5d 20 3d 20 7a 57 5b 6e   zNext[i] = zW[n
9300: 57 6f 72 64 2b 69 5d 3b 0a 20 20 20 20 20 20 7d  Word+i];.      }
9310: 0a 20 20 20 20 20 20 7a 4e 65 78 74 5b 69 5d 20  .      zNext[i] 
9320: 3d 20 30 3b 0a 20 20 20 20 20 20 7a 42 75 66 5b  = 0;.      zBuf[
9330: 6e 57 6f 72 64 5d 20 3d 20 30 3b 0a 20 20 20 20  nWord] = 0;.    
9340: 20 20 69 66 28 20 70 2d 3e 72 49 6e 73 3e 30 20    if( p->rIns>0 
9350: 29 7b 0a 20 20 20 20 20 20 20 20 61 6d 61 74 63  ){.        amatc
9360: 68 41 64 64 57 6f 72 64 28 70 43 75 72 2c 20 70  hAddWord(pCur, p
9370: 57 6f 72 64 2d 3e 72 43 6f 73 74 2b 70 2d 3e 72  Word->rCost+p->r
9380: 49 6e 73 2c 20 70 57 6f 72 64 2d 3e 6e 4d 61 74  Ins, pWord->nMat
9390: 63 68 2c 20 0a 20 20 20 20 20 20 20 20 20 20 20  ch, .           
93a0: 20 20 20 20 20 20 20 20 20 20 20 7a 42 75 66 2c             zBuf,
93b0: 20 7a 4e 65 78 74 29 3b 0a 20 20 20 20 20 20 7d   zNext);.      }
93c0: 0a 20 20 20 20 20 20 69 66 28 20 70 2d 3e 72 53  .      if( p->rS
93d0: 75 62 3e 30 20 29 7b 0a 20 20 20 20 20 20 20 20  ub>0 ){.        
93e0: 61 6d 61 74 63 68 41 64 64 57 6f 72 64 28 70 43  amatchAddWord(pC
93f0: 75 72 2c 20 70 57 6f 72 64 2d 3e 72 43 6f 73 74  ur, pWord->rCost
9400: 2b 70 2d 3e 72 53 75 62 2c 20 70 57 6f 72 64 2d  +p->rSub, pWord-
9410: 3e 6e 4d 61 74 63 68 2b 6e 4e 65 78 74 49 6e 2c  >nMatch+nNextIn,
9420: 20 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20   .              
9430: 20 20 20 20 20 20 20 20 7a 42 75 66 2c 20 7a 4e          zBuf, zN
9440: 65 78 74 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20  ext);.      }.  
9450: 20 20 20 20 69 66 28 20 70 2d 3e 72 49 6e 73 3c      if( p->rIns<
9460: 30 20 26 26 20 70 2d 3e 72 53 75 62 3c 30 20 29  0 && p->rSub<0 )
9470: 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 7a 4e   break;.      zN
9480: 65 78 74 5b 69 2d 31 5d 2b 2b 3b 20 20 2f 2a 20  ext[i-1]++;  /* 
9490: 46 49 58 20 4d 45 20 2a 2f 0a 20 20 20 20 7d 0a  FIX ME */.    }.
94a0: 20 20 20 20 73 71 6c 69 74 65 33 5f 72 65 73 65      sqlite3_rese
94b0: 74 28 70 2d 3e 70 56 43 68 65 63 6b 29 3b 0a 0a  t(p->pVCheck);..
94c0: 20 20 20 20 69 66 28 20 70 2d 3e 72 44 65 6c 3e      if( p->rDel>
94d0: 30 20 29 7b 0a 20 20 20 20 20 20 7a 42 75 66 5b  0 ){.      zBuf[
94e0: 6e 57 6f 72 64 5d 20 3d 20 30 3b 0a 20 20 20 20  nWord] = 0;.    
94f0: 20 20 61 6d 61 74 63 68 41 64 64 57 6f 72 64 28    amatchAddWord(
9500: 70 43 75 72 2c 20 70 57 6f 72 64 2d 3e 72 43 6f  pCur, pWord->rCo
9510: 73 74 2b 70 2d 3e 72 44 65 6c 2c 20 70 57 6f 72  st+p->rDel, pWor
9520: 64 2d 3e 6e 4d 61 74 63 68 2b 6e 4e 65 78 74 49  d->nMatch+nNextI
9530: 6e 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  n,.             
9540: 20 20 20 20 20 20 20 7a 42 75 66 2c 20 22 22 29         zBuf, "")
9550: 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 66 6f 72  ;.    }..    for
9560: 28 70 52 75 6c 65 3d 70 2d 3e 70 52 75 6c 65 3b  (pRule=p->pRule;
9570: 20 70 52 75 6c 65 3b 20 70 52 75 6c 65 3d 70 52   pRule; pRule=pR
9580: 75 6c 65 2d 3e 70 4e 65 78 74 29 7b 0a 20 20 20  ule->pNext){.   
9590: 20 20 20 69 66 28 20 70 52 75 6c 65 2d 3e 69 4c     if( pRule->iL
95a0: 61 6e 67 21 3d 70 43 75 72 2d 3e 69 4c 61 6e 67  ang!=pCur->iLang
95b0: 20 29 20 63 6f 6e 74 69 6e 75 65 3b 0a 20 20 20   ) continue;.   
95c0: 20 20 20 69 66 28 20 73 74 72 6e 63 6d 70 28 70     if( strncmp(p
95d0: 52 75 6c 65 2d 3e 7a 46 72 6f 6d 2c 20 70 43 75  Rule->zFrom, pCu
95e0: 72 2d 3e 7a 49 6e 70 75 74 2b 70 57 6f 72 64 2d  r->zInput+pWord-
95f0: 3e 6e 4d 61 74 63 68 2c 20 70 52 75 6c 65 2d 3e  >nMatch, pRule->
9600: 6e 46 72 6f 6d 29 3d 3d 30 20 29 7b 0a 20 20 20  nFrom)==0 ){.   
9610: 20 20 20 20 20 61 6d 61 74 63 68 41 64 64 57 6f       amatchAddWo
9620: 72 64 28 70 43 75 72 2c 20 70 57 6f 72 64 2d 3e  rd(pCur, pWord->
9630: 72 43 6f 73 74 2b 70 52 75 6c 65 2d 3e 72 43 6f  rCost+pRule->rCo
9640: 73 74 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20  st,.            
9650: 20 20 20 20 20 20 20 20 20 20 70 57 6f 72 64 2d            pWord-
9660: 3e 6e 4d 61 74 63 68 2b 70 52 75 6c 65 2d 3e 6e  >nMatch+pRule->n
9670: 46 72 6f 6d 2c 20 70 57 6f 72 64 2d 3e 7a 57 6f  From, pWord->zWo
9680: 72 64 2b 32 2c 20 70 52 75 6c 65 2d 3e 7a 54 6f  rd+2, pRule->zTo
9690: 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d  );.      }.    }
96a0: 0a 20 20 7d 77 68 69 6c 65 28 20 21 69 73 4d 61  .  }while( !isMa
96b0: 74 63 68 20 29 3b 0a 20 20 70 43 75 72 2d 3e 70  tch );.  pCur->p
96c0: 43 75 72 72 65 6e 74 20 3d 20 70 57 6f 72 64 3b  Current = pWord;
96d0: 0a 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28  .  sqlite3_free(
96e0: 7a 42 75 66 29 3b 0a 20 20 72 65 74 75 72 6e 20  zBuf);.  return 
96f0: 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a  SQLITE_OK;.}../*
9700: 0a 2a 2a 20 43 61 6c 6c 65 64 20 74 6f 20 22 72  .** Called to "r
9710: 65 77 69 6e 64 22 20 61 20 63 75 72 73 6f 72 20  ewind" a cursor 
9720: 62 61 63 6b 20 74 6f 20 74 68 65 20 62 65 67 69  back to the begi
9730: 6e 6e 69 6e 67 20 73 6f 20 74 68 61 74 0a 2a 2a  nning so that.**
9740: 20 69 74 20 73 74 61 72 74 73 20 69 74 73 20 6f   it starts its o
9750: 75 74 70 75 74 20 6f 76 65 72 20 61 67 61 69 6e  utput over again
9760: 2e 20 20 41 6c 77 61 79 73 20 63 61 6c 6c 65 64  .  Always called
9770: 20 61 74 20 6c 65 61 73 74 20 6f 6e 63 65 0a 2a   at least once.*
9780: 2a 20 70 72 69 6f 72 20 74 6f 20 61 6e 79 20 61  * prior to any a
9790: 6d 61 74 63 68 43 6f 6c 75 6d 6e 2c 20 61 6d 61  matchColumn, ama
97a0: 74 63 68 52 6f 77 69 64 2c 20 6f 72 20 61 6d 61  tchRowid, or ama
97b0: 74 63 68 45 6f 66 20 63 61 6c 6c 2e 0a 2a 2f 0a  tchEof call..*/.
97c0: 73 74 61 74 69 63 20 69 6e 74 20 61 6d 61 74 63  static int amatc
97d0: 68 46 69 6c 74 65 72 28 0a 20 20 73 71 6c 69 74  hFilter(.  sqlit
97e0: 65 33 5f 76 74 61 62 5f 63 75 72 73 6f 72 20 2a  e3_vtab_cursor *
97f0: 70 56 74 61 62 43 75 72 73 6f 72 2c 20 0a 20 20  pVtabCursor, .  
9800: 69 6e 74 20 69 64 78 4e 75 6d 2c 20 63 6f 6e 73  int idxNum, cons
9810: 74 20 63 68 61 72 20 2a 69 64 78 53 74 72 2c 0a  t char *idxStr,.
9820: 20 20 69 6e 74 20 61 72 67 63 2c 20 73 71 6c 69    int argc, sqli
9830: 74 65 33 5f 76 61 6c 75 65 20 2a 2a 61 72 67 76  te3_value **argv
9840: 0a 29 7b 0a 20 20 61 6d 61 74 63 68 5f 63 75 72  .){.  amatch_cur
9850: 73 6f 72 20 2a 70 43 75 72 20 3d 20 28 61 6d 61  sor *pCur = (ama
9860: 74 63 68 5f 63 75 72 73 6f 72 20 2a 29 70 56 74  tch_cursor *)pVt
9870: 61 62 43 75 72 73 6f 72 3b 0a 20 20 63 6f 6e 73  abCursor;.  cons
9880: 74 20 63 68 61 72 20 2a 7a 57 6f 72 64 20 3d 20  t char *zWord = 
9890: 22 2a 22 3b 0a 20 20 69 6e 74 20 69 64 78 3b 0a  "*";.  int idx;.
98a0: 0a 20 20 61 6d 61 74 63 68 43 6c 65 61 72 43 75  .  amatchClearCu
98b0: 72 73 6f 72 28 70 43 75 72 29 3b 0a 20 20 69 64  rsor(pCur);.  id
98c0: 78 20 3d 20 30 3b 0a 20 20 69 66 28 20 69 64 78  x = 0;.  if( idx
98d0: 4e 75 6d 20 26 20 31 20 29 7b 0a 20 20 20 20 7a  Num & 1 ){.    z
98e0: 57 6f 72 64 20 3d 20 28 63 6f 6e 73 74 20 63 68  Word = (const ch
98f0: 61 72 2a 29 73 71 6c 69 74 65 33 5f 76 61 6c 75  ar*)sqlite3_valu
9900: 65 5f 74 65 78 74 28 61 72 67 76 5b 30 5d 29 3b  e_text(argv[0]);
9910: 0a 20 20 20 20 69 64 78 2b 2b 3b 0a 20 20 7d 0a  .    idx++;.  }.
9920: 20 20 69 66 28 20 69 64 78 4e 75 6d 20 26 20 32    if( idxNum & 2
9930: 20 29 7b 0a 20 20 20 20 70 43 75 72 2d 3e 72 4c   ){.    pCur->rL
9940: 69 6d 69 74 20 3d 20 28 61 6d 61 74 63 68 5f 63  imit = (amatch_c
9950: 6f 73 74 29 73 71 6c 69 74 65 33 5f 76 61 6c 75  ost)sqlite3_valu
9960: 65 5f 69 6e 74 28 61 72 67 76 5b 69 64 78 5d 29  e_int(argv[idx])
9970: 3b 0a 20 20 20 20 69 64 78 2b 2b 3b 0a 20 20 7d  ;.    idx++;.  }
9980: 0a 20 20 69 66 28 20 69 64 78 4e 75 6d 20 26 20  .  if( idxNum & 
9990: 34 20 29 7b 0a 20 20 20 20 70 43 75 72 2d 3e 69  4 ){.    pCur->i
99a0: 4c 61 6e 67 20 3d 20 28 61 6d 61 74 63 68 5f 63  Lang = (amatch_c
99b0: 6f 73 74 29 73 71 6c 69 74 65 33 5f 76 61 6c 75  ost)sqlite3_valu
99c0: 65 5f 69 6e 74 28 61 72 67 76 5b 69 64 78 5d 29  e_int(argv[idx])
99d0: 3b 0a 20 20 20 20 69 64 78 2b 2b 3b 0a 20 20 7d  ;.    idx++;.  }
99e0: 0a 20 20 70 43 75 72 2d 3e 7a 49 6e 70 75 74 20  .  pCur->zInput 
99f0: 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74  = sqlite3_mprint
9a00: 66 28 22 25 73 22 2c 20 7a 57 6f 72 64 29 3b 0a  f("%s", zWord);.
9a10: 20 20 69 66 28 20 70 43 75 72 2d 3e 7a 49 6e 70    if( pCur->zInp
9a20: 75 74 3d 3d 30 20 29 20 72 65 74 75 72 6e 20 53  ut==0 ) return S
9a30: 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 61  QLITE_NOMEM;.  a
9a40: 6d 61 74 63 68 41 64 64 57 6f 72 64 28 70 43 75  matchAddWord(pCu
9a50: 72 2c 20 30 2c 20 30 2c 20 22 22 2c 20 22 22 29  r, 0, 0, "", "")
9a60: 3b 0a 20 20 61 6d 61 74 63 68 4e 65 78 74 28 70  ;.  amatchNext(p
9a70: 56 74 61 62 43 75 72 73 6f 72 29 3b 0a 0a 20 20  VtabCursor);..  
9a80: 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b  return SQLITE_OK
9a90: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 4f 6e 6c 79 20  ;.}../*.** Only 
9aa0: 74 68 65 20 77 6f 72 64 20 61 6e 64 20 64 69 73  the word and dis
9ab0: 74 61 6e 63 65 20 63 6f 6c 75 6d 6e 73 20 68 61  tance columns ha
9ac0: 76 65 20 76 61 6c 75 65 73 2e 20 20 41 6c 6c 20  ve values.  All 
9ad0: 6f 74 68 65 72 20 63 6f 6c 75 6d 6e 73 0a 2a 2a  other columns.**
9ae0: 20 72 65 74 75 72 6e 20 4e 55 4c 4c 0a 2a 2f 0a   return NULL.*/.
9af0: 73 74 61 74 69 63 20 69 6e 74 20 61 6d 61 74 63  static int amatc
9b00: 68 43 6f 6c 75 6d 6e 28 73 71 6c 69 74 65 33 5f  hColumn(sqlite3_
9b10: 76 74 61 62 5f 63 75 72 73 6f 72 20 2a 63 75 72  vtab_cursor *cur
9b20: 2c 20 73 71 6c 69 74 65 33 5f 63 6f 6e 74 65 78  , sqlite3_contex
9b30: 74 20 2a 63 74 78 2c 20 69 6e 74 20 69 29 7b 0a  t *ctx, int i){.
9b40: 20 20 61 6d 61 74 63 68 5f 63 75 72 73 6f 72 20    amatch_cursor 
9b50: 2a 70 43 75 72 20 3d 20 28 61 6d 61 74 63 68 5f  *pCur = (amatch_
9b60: 63 75 72 73 6f 72 2a 29 63 75 72 3b 0a 20 20 73  cursor*)cur;.  s
9b70: 77 69 74 63 68 28 20 69 20 29 7b 0a 20 20 20 20  witch( i ){.    
9b80: 63 61 73 65 20 41 4d 41 54 43 48 5f 43 4f 4c 5f  case AMATCH_COL_
9b90: 57 4f 52 44 3a 20 7b 0a 20 20 20 20 20 20 73 71  WORD: {.      sq
9ba0: 6c 69 74 65 33 5f 72 65 73 75 6c 74 5f 74 65 78  lite3_result_tex
9bb0: 74 28 63 74 78 2c 20 70 43 75 72 2d 3e 70 43 75  t(ctx, pCur->pCu
9bc0: 72 72 65 6e 74 2d 3e 7a 57 6f 72 64 2b 32 2c 20  rrent->zWord+2, 
9bd0: 2d 31 2c 20 53 51 4c 49 54 45 5f 53 54 41 54 49  -1, SQLITE_STATI
9be0: 43 29 3b 0a 20 20 20 20 20 20 62 72 65 61 6b 3b  C);.      break;
9bf0: 0a 20 20 20 20 7d 0a 20 20 20 20 63 61 73 65 20  .    }.    case 
9c00: 41 4d 41 54 43 48 5f 43 4f 4c 5f 44 49 53 54 41  AMATCH_COL_DISTA
9c10: 4e 43 45 3a 20 7b 0a 20 20 20 20 20 20 73 71 6c  NCE: {.      sql
9c20: 69 74 65 33 5f 72 65 73 75 6c 74 5f 69 6e 74 28  ite3_result_int(
9c30: 63 74 78 2c 20 70 43 75 72 2d 3e 70 43 75 72 72  ctx, pCur->pCurr
9c40: 65 6e 74 2d 3e 72 43 6f 73 74 29 3b 0a 20 20 20  ent->rCost);.   
9c50: 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 7d 0a     break;.    }.
9c60: 20 20 20 20 63 61 73 65 20 41 4d 41 54 43 48 5f      case AMATCH_
9c70: 43 4f 4c 5f 4c 41 4e 47 55 41 47 45 3a 20 7b 0a  COL_LANGUAGE: {.
9c80: 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 72 65        sqlite3_re
9c90: 73 75 6c 74 5f 69 6e 74 28 63 74 78 2c 20 70 43  sult_int(ctx, pC
9ca0: 75 72 2d 3e 69 4c 61 6e 67 29 3b 0a 20 20 20 20  ur->iLang);.    
9cb0: 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 7d 0a 20    break;.    }. 
9cc0: 20 20 20 63 61 73 65 20 41 4d 41 54 43 48 5f 43     case AMATCH_C
9cd0: 4f 4c 5f 4e 57 4f 52 44 3a 20 7b 0a 20 20 20 20  OL_NWORD: {.    
9ce0: 20 20 73 71 6c 69 74 65 33 5f 72 65 73 75 6c 74    sqlite3_result
9cf0: 5f 69 6e 74 28 63 74 78 2c 20 70 43 75 72 2d 3e  _int(ctx, pCur->
9d00: 6e 57 6f 72 64 29 3b 0a 20 20 20 20 20 20 62 72  nWord);.      br
9d10: 65 61 6b 3b 0a 20 20 20 20 7d 0a 20 20 20 20 64  eak;.    }.    d
9d20: 65 66 61 75 6c 74 3a 20 7b 0a 20 20 20 20 20 20  efault: {.      
9d30: 73 71 6c 69 74 65 33 5f 72 65 73 75 6c 74 5f 6e  sqlite3_result_n
9d40: 75 6c 6c 28 63 74 78 29 3b 0a 20 20 20 20 20 20  ull(ctx);.      
9d50: 62 72 65 61 6b 3b 0a 20 20 20 20 7d 0a 20 20 7d  break;.    }.  }
9d60: 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45  .  return SQLITE
9d70: 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68  _OK;.}../*.** Th
9d80: 65 20 72 6f 77 69 64 2e 0a 2a 2f 0a 73 74 61 74  e rowid..*/.stat
9d90: 69 63 20 69 6e 74 20 61 6d 61 74 63 68 52 6f 77  ic int amatchRow
9da0: 69 64 28 73 71 6c 69 74 65 33 5f 76 74 61 62 5f  id(sqlite3_vtab_
9db0: 63 75 72 73 6f 72 20 2a 63 75 72 2c 20 73 71 6c  cursor *cur, sql
9dc0: 69 74 65 5f 69 6e 74 36 34 20 2a 70 52 6f 77 69  ite_int64 *pRowi
9dd0: 64 29 7b 0a 20 20 61 6d 61 74 63 68 5f 63 75 72  d){.  amatch_cur
9de0: 73 6f 72 20 2a 70 43 75 72 20 3d 20 28 61 6d 61  sor *pCur = (ama
9df0: 74 63 68 5f 63 75 72 73 6f 72 2a 29 63 75 72 3b  tch_cursor*)cur;
9e00: 0a 20 20 2a 70 52 6f 77 69 64 20 3d 20 70 43 75  .  *pRowid = pCu
9e10: 72 2d 3e 69 52 6f 77 69 64 3b 0a 20 20 72 65 74  r->iRowid;.  ret
9e20: 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d  urn SQLITE_OK;.}
9e30: 0a 0a 2f 2a 0a 2a 2a 20 45 4f 46 20 69 6e 64 69  ../*.** EOF indi
9e40: 63 61 74 6f 72 0a 2a 2f 0a 73 74 61 74 69 63 20  cator.*/.static 
9e50: 69 6e 74 20 61 6d 61 74 63 68 45 6f 66 28 73 71  int amatchEof(sq
9e60: 6c 69 74 65 33 5f 76 74 61 62 5f 63 75 72 73 6f  lite3_vtab_curso
9e70: 72 20 2a 63 75 72 29 7b 0a 20 20 61 6d 61 74 63  r *cur){.  amatc
9e80: 68 5f 63 75 72 73 6f 72 20 2a 70 43 75 72 20 3d  h_cursor *pCur =
9e90: 20 28 61 6d 61 74 63 68 5f 63 75 72 73 6f 72 2a   (amatch_cursor*
9ea0: 29 63 75 72 3b 0a 20 20 72 65 74 75 72 6e 20 70  )cur;.  return p
9eb0: 43 75 72 2d 3e 70 43 75 72 72 65 6e 74 3d 3d 30  Cur->pCurrent==0
9ec0: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 53 65 61 72 63  ;.}../*.** Searc
9ed0: 68 20 66 6f 72 20 74 65 72 6d 73 20 6f 66 20 74  h for terms of t
9ee0: 68 65 73 65 20 66 6f 72 6d 73 3a 0a 2a 2a 0a 2a  hese forms:.**.*
9ef0: 2a 20 20 20 28 41 29 20 20 20 20 77 6f 72 64 20  *   (A)    word 
9f00: 4d 41 54 43 48 20 24 73 74 72 0a 2a 2a 20 20 20  MATCH $str.**   
9f10: 28 42 31 29 20 20 20 64 69 73 74 61 6e 63 65 20  (B1)   distance 
9f20: 3c 20 24 76 61 6c 75 65 0a 2a 2a 20 20 20 28 42  < $value.**   (B
9f30: 32 29 20 20 20 64 69 73 74 61 6e 63 65 20 3c 3d  2)   distance <=
9f40: 20 24 76 61 6c 75 65 0a 2a 2a 20 20 20 28 43 29   $value.**   (C)
9f50: 20 20 20 20 6c 61 6e 67 75 61 67 65 20 3d 3d 20      language == 
9f60: 24 6c 61 6e 67 75 61 67 65 0a 2a 2a 0a 2a 2a 20  $language.**.** 
9f70: 54 68 65 20 64 69 73 74 61 6e 63 65 3c 20 61 6e  The distance< an
9f80: 64 20 64 69 73 74 61 6e 63 65 3c 3d 20 61 72 65  d distance<= are
9f90: 20 62 6f 74 68 20 74 72 65 61 74 65 64 20 61 73   both treated as
9fa0: 20 64 69 73 74 61 6e 63 65 3c 3d 2e 0a 2a 2a 20   distance<=..** 
9fb0: 54 68 65 20 71 75 65 72 79 20 70 6c 61 6e 20 6e  The query plan n
9fc0: 75 6d 62 65 72 20 69 73 20 61 20 62 69 74 20 76  umber is a bit v
9fd0: 65 63 74 6f 72 3a 0a 2a 2a 0a 2a 2a 20 20 20 62  ector:.**.**   b
9fe0: 69 74 20 31 3a 20 20 20 54 65 72 6d 20 6f 66 20  it 1:   Term of 
9ff0: 74 68 65 20 66 6f 72 6d 20 28 41 29 20 66 6f 75  the form (A) fou
a000: 6e 64 0a 2a 2a 20 20 20 62 69 74 20 32 3a 20 20  nd.**   bit 2:  
a010: 20 54 65 72 6d 20 6c 69 6b 65 20 28 42 31 29 20   Term like (B1) 
a020: 6f 72 20 28 42 32 29 20 66 6f 75 6e 64 0a 2a 2a  or (B2) found.**
a030: 20 20 20 62 69 74 20 33 3a 20 20 20 54 65 72 6d     bit 3:   Term
a040: 20 6c 69 6b 65 20 28 43 29 20 66 6f 75 6e 64 0a   like (C) found.
a050: 2a 2a 0a 2a 2a 20 49 66 20 62 69 74 2d 31 20 69  **.** If bit-1 i
a060: 73 20 73 65 74 2c 20 24 73 74 72 20 69 73 20 61  s set, $str is a
a070: 6c 77 61 79 73 20 69 6e 20 66 69 6c 74 65 72 2e  lways in filter.
a080: 61 72 67 76 5b 30 5d 2e 20 20 49 66 20 62 69 74  argv[0].  If bit
a090: 2d 32 20 69 73 20 73 65 74 0a 2a 2a 20 74 68 65  -2 is set.** the
a0a0: 6e 20 24 76 61 6c 75 65 20 69 73 20 69 6e 20 66  n $value is in f
a0b0: 69 6c 74 65 72 2e 61 72 67 76 5b 30 5d 20 69 66  ilter.argv[0] if
a0c0: 20 62 69 74 2d 31 20 69 73 20 63 6c 65 61 72 20   bit-1 is clear 
a0d0: 61 6e 64 20 69 73 20 69 6e 20 0a 2a 2a 20 66 69  and is in .** fi
a0e0: 6c 74 65 72 2e 61 72 67 76 5b 31 5d 20 69 66 20  lter.argv[1] if 
a0f0: 62 69 74 2d 31 20 69 73 20 73 65 74 2e 20 20 49  bit-1 is set.  I
a100: 66 20 62 69 74 2d 33 20 69 73 20 73 65 74 2c 20  f bit-3 is set, 
a110: 74 68 65 6e 20 24 72 75 6c 65 69 64 20 69 73 0a  then $ruleid is.
a120: 2a 2a 20 69 6e 20 66 69 6c 74 65 72 2e 61 72 67  ** in filter.arg
a130: 76 5b 30 5d 20 69 66 20 62 69 74 2d 31 20 61 6e  v[0] if bit-1 an
a140: 64 20 62 69 74 2d 32 20 61 72 65 20 62 6f 74 68  d bit-2 are both
a150: 20 7a 65 72 6f 2c 20 69 73 20 69 6e 0a 2a 2a 20   zero, is in.** 
a160: 66 69 6c 74 65 72 2e 61 72 67 76 5b 31 5d 20 69  filter.argv[1] i
a170: 66 20 65 78 61 63 74 6c 79 20 6f 6e 65 20 6f 66  f exactly one of
a180: 20 62 69 74 2d 31 20 61 6e 64 20 62 69 74 2d 32   bit-1 and bit-2
a190: 20 61 72 65 20 73 65 74 2c 20 61 6e 64 20 69 73   are set, and is
a1a0: 20 69 6e 0a 2a 2a 20 66 69 6c 74 65 72 2e 61 72   in.** filter.ar
a1b0: 67 76 5b 32 5d 20 69 66 20 62 6f 74 68 20 62 69  gv[2] if both bi
a1c0: 74 2d 31 20 61 6e 64 20 62 69 74 2d 32 20 61 72  t-1 and bit-2 ar
a1d0: 65 20 73 65 74 2e 0a 2a 2f 0a 73 74 61 74 69 63  e set..*/.static
a1e0: 20 69 6e 74 20 61 6d 61 74 63 68 42 65 73 74 49   int amatchBestI
a1f0: 6e 64 65 78 28 0a 20 20 73 71 6c 69 74 65 33 5f  ndex(.  sqlite3_
a200: 76 74 61 62 20 2a 74 61 62 2c 0a 20 20 73 71 6c  vtab *tab,.  sql
a210: 69 74 65 33 5f 69 6e 64 65 78 5f 69 6e 66 6f 20  ite3_index_info 
a220: 2a 70 49 64 78 49 6e 66 6f 0a 29 7b 0a 20 20 69  *pIdxInfo.){.  i
a230: 6e 74 20 69 50 6c 61 6e 20 3d 20 30 3b 0a 20 20  nt iPlan = 0;.  
a240: 69 6e 74 20 69 44 69 73 74 54 65 72 6d 20 3d 20  int iDistTerm = 
a250: 2d 31 3b 0a 20 20 69 6e 74 20 69 4c 61 6e 67 54  -1;.  int iLangT
a260: 65 72 6d 20 3d 20 2d 31 3b 0a 20 20 69 6e 74 20  erm = -1;.  int 
a270: 69 3b 0a 20 20 63 6f 6e 73 74 20 73 74 72 75 63  i;.  const struc
a280: 74 20 73 71 6c 69 74 65 33 5f 69 6e 64 65 78 5f  t sqlite3_index_
a290: 63 6f 6e 73 74 72 61 69 6e 74 20 2a 70 43 6f 6e  constraint *pCon
a2a0: 73 74 72 61 69 6e 74 3b 0a 0a 20 20 28 76 6f 69  straint;..  (voi
a2b0: 64 29 74 61 62 3b 0a 20 20 70 43 6f 6e 73 74 72  d)tab;.  pConstr
a2c0: 61 69 6e 74 20 3d 20 70 49 64 78 49 6e 66 6f 2d  aint = pIdxInfo-
a2d0: 3e 61 43 6f 6e 73 74 72 61 69 6e 74 3b 0a 20 20  >aConstraint;.  
a2e0: 66 6f 72 28 69 3d 30 3b 20 69 3c 70 49 64 78 49  for(i=0; i<pIdxI
a2f0: 6e 66 6f 2d 3e 6e 43 6f 6e 73 74 72 61 69 6e 74  nfo->nConstraint
a300: 3b 20 69 2b 2b 2c 20 70 43 6f 6e 73 74 72 61 69  ; i++, pConstrai
a310: 6e 74 2b 2b 29 7b 0a 20 20 20 20 69 66 28 20 70  nt++){.    if( p
a320: 43 6f 6e 73 74 72 61 69 6e 74 2d 3e 75 73 61 62  Constraint->usab
a330: 6c 65 3d 3d 30 20 29 20 63 6f 6e 74 69 6e 75 65  le==0 ) continue
a340: 3b 0a 20 20 20 20 69 66 28 20 28 69 50 6c 61 6e  ;.    if( (iPlan
a350: 20 26 20 31 29 3d 3d 30 20 0a 20 20 20 20 20 26   & 1)==0 .     &
a360: 26 20 70 43 6f 6e 73 74 72 61 69 6e 74 2d 3e 69  & pConstraint->i
a370: 43 6f 6c 75 6d 6e 3d 3d 30 0a 20 20 20 20 20 26  Column==0.     &
a380: 26 20 70 43 6f 6e 73 74 72 61 69 6e 74 2d 3e 6f  & pConstraint->o
a390: 70 3d 3d 53 51 4c 49 54 45 5f 49 4e 44 45 58 5f  p==SQLITE_INDEX_
a3a0: 43 4f 4e 53 54 52 41 49 4e 54 5f 4d 41 54 43 48  CONSTRAINT_MATCH
a3b0: 0a 20 20 20 20 29 7b 0a 20 20 20 20 20 20 69 50  .    ){.      iP
a3c0: 6c 61 6e 20 7c 3d 20 31 3b 0a 20 20 20 20 20 20  lan |= 1;.      
a3d0: 70 49 64 78 49 6e 66 6f 2d 3e 61 43 6f 6e 73 74  pIdxInfo->aConst
a3e0: 72 61 69 6e 74 55 73 61 67 65 5b 69 5d 2e 61 72  raintUsage[i].ar
a3f0: 67 76 49 6e 64 65 78 20 3d 20 31 3b 0a 20 20 20  gvIndex = 1;.   
a400: 20 20 20 70 49 64 78 49 6e 66 6f 2d 3e 61 43 6f     pIdxInfo->aCo
a410: 6e 73 74 72 61 69 6e 74 55 73 61 67 65 5b 69 5d  nstraintUsage[i]
a420: 2e 6f 6d 69 74 20 3d 20 31 3b 0a 20 20 20 20 7d  .omit = 1;.    }
a430: 0a 20 20 20 20 69 66 28 20 28 69 50 6c 61 6e 20  .    if( (iPlan 
a440: 26 20 32 29 3d 3d 30 0a 20 20 20 20 20 26 26 20  & 2)==0.     && 
a450: 70 43 6f 6e 73 74 72 61 69 6e 74 2d 3e 69 43 6f  pConstraint->iCo
a460: 6c 75 6d 6e 3d 3d 31 0a 20 20 20 20 20 26 26 20  lumn==1.     && 
a470: 28 70 43 6f 6e 73 74 72 61 69 6e 74 2d 3e 6f 70  (pConstraint->op
a480: 3d 3d 53 51 4c 49 54 45 5f 49 4e 44 45 58 5f 43  ==SQLITE_INDEX_C
a490: 4f 4e 53 54 52 41 49 4e 54 5f 4c 54 0a 20 20 20  ONSTRAINT_LT.   
a4a0: 20 20 20 20 20 20 20 20 7c 7c 20 70 43 6f 6e 73          || pCons
a4b0: 74 72 61 69 6e 74 2d 3e 6f 70 3d 3d 53 51 4c 49  traint->op==SQLI
a4c0: 54 45 5f 49 4e 44 45 58 5f 43 4f 4e 53 54 52 41  TE_INDEX_CONSTRA
a4d0: 49 4e 54 5f 4c 45 29 0a 20 20 20 20 29 7b 0a 20  INT_LE).    ){. 
a4e0: 20 20 20 20 20 69 50 6c 61 6e 20 7c 3d 20 32 3b       iPlan |= 2;
a4f0: 0a 20 20 20 20 20 20 69 44 69 73 74 54 65 72 6d  .      iDistTerm
a500: 20 3d 20 69 3b 0a 20 20 20 20 7d 0a 20 20 20 20   = i;.    }.    
a510: 69 66 28 20 28 69 50 6c 61 6e 20 26 20 34 29 3d  if( (iPlan & 4)=
a520: 3d 30 0a 20 20 20 20 20 26 26 20 70 43 6f 6e 73  =0.     && pCons
a530: 74 72 61 69 6e 74 2d 3e 69 43 6f 6c 75 6d 6e 3d  traint->iColumn=
a540: 3d 32 0a 20 20 20 20 20 26 26 20 70 43 6f 6e 73  =2.     && pCons
a550: 74 72 61 69 6e 74 2d 3e 6f 70 3d 3d 53 51 4c 49  traint->op==SQLI
a560: 54 45 5f 49 4e 44 45 58 5f 43 4f 4e 53 54 52 41  TE_INDEX_CONSTRA
a570: 49 4e 54 5f 45 51 0a 20 20 20 20 29 7b 0a 20 20  INT_EQ.    ){.  
a580: 20 20 20 20 69 50 6c 61 6e 20 7c 3d 20 34 3b 0a      iPlan |= 4;.
a590: 20 20 20 20 20 20 70 49 64 78 49 6e 66 6f 2d 3e        pIdxInfo->
a5a0: 61 43 6f 6e 73 74 72 61 69 6e 74 55 73 61 67 65  aConstraintUsage
a5b0: 5b 69 5d 2e 6f 6d 69 74 20 3d 20 31 3b 0a 20 20  [i].omit = 1;.  
a5c0: 20 20 20 20 69 4c 61 6e 67 54 65 72 6d 20 3d 20      iLangTerm = 
a5d0: 69 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 69  i;.    }.  }.  i
a5e0: 66 28 20 69 50 6c 61 6e 20 26 20 32 20 29 7b 0a  f( iPlan & 2 ){.
a5f0: 20 20 20 20 70 49 64 78 49 6e 66 6f 2d 3e 61 43      pIdxInfo->aC
a600: 6f 6e 73 74 72 61 69 6e 74 55 73 61 67 65 5b 69  onstraintUsage[i
a610: 44 69 73 74 54 65 72 6d 5d 2e 61 72 67 76 49 6e  DistTerm].argvIn
a620: 64 65 78 20 3d 20 31 2b 28 28 69 50 6c 61 6e 26  dex = 1+((iPlan&
a630: 31 29 21 3d 30 29 3b 0a 20 20 7d 0a 20 20 69 66  1)!=0);.  }.  if
a640: 28 20 69 50 6c 61 6e 20 26 20 34 20 29 7b 0a 20  ( iPlan & 4 ){. 
a650: 20 20 20 69 6e 74 20 69 64 78 20 3d 20 31 3b 0a     int idx = 1;.
a660: 20 20 20 20 69 66 28 20 69 50 6c 61 6e 20 26 20      if( iPlan & 
a670: 31 20 29 20 69 64 78 2b 2b 3b 0a 20 20 20 20 69  1 ) idx++;.    i
a680: 66 28 20 69 50 6c 61 6e 20 26 20 32 20 29 20 69  f( iPlan & 2 ) i
a690: 64 78 2b 2b 3b 0a 20 20 20 20 70 49 64 78 49 6e  dx++;.    pIdxIn
a6a0: 66 6f 2d 3e 61 43 6f 6e 73 74 72 61 69 6e 74 55  fo->aConstraintU
a6b0: 73 61 67 65 5b 69 4c 61 6e 67 54 65 72 6d 5d 2e  sage[iLangTerm].
a6c0: 61 72 67 76 49 6e 64 65 78 20 3d 20 69 64 78 3b  argvIndex = idx;
a6d0: 0a 20 20 7d 0a 20 20 70 49 64 78 49 6e 66 6f 2d  .  }.  pIdxInfo-
a6e0: 3e 69 64 78 4e 75 6d 20 3d 20 69 50 6c 61 6e 3b  >idxNum = iPlan;
a6f0: 0a 20 20 69 66 28 20 70 49 64 78 49 6e 66 6f 2d  .  if( pIdxInfo-
a700: 3e 6e 4f 72 64 65 72 42 79 3d 3d 31 0a 20 20 20  >nOrderBy==1.   
a710: 26 26 20 70 49 64 78 49 6e 66 6f 2d 3e 61 4f 72  && pIdxInfo->aOr
a720: 64 65 72 42 79 5b 30 5d 2e 69 43 6f 6c 75 6d 6e  derBy[0].iColumn
a730: 3d 3d 31 0a 20 20 20 26 26 20 70 49 64 78 49 6e  ==1.   && pIdxIn
a740: 66 6f 2d 3e 61 4f 72 64 65 72 42 79 5b 30 5d 2e  fo->aOrderBy[0].
a750: 64 65 73 63 3d 3d 30 0a 20 20 29 7b 0a 20 20 20  desc==0.  ){.   
a760: 20 70 49 64 78 49 6e 66 6f 2d 3e 6f 72 64 65 72   pIdxInfo->order
a770: 42 79 43 6f 6e 73 75 6d 65 64 20 3d 20 31 3b 0a  ByConsumed = 1;.
a780: 20 20 7d 0a 20 20 70 49 64 78 49 6e 66 6f 2d 3e    }.  pIdxInfo->
a790: 65 73 74 69 6d 61 74 65 64 43 6f 73 74 20 3d 20  estimatedCost = 
a7a0: 28 64 6f 75 62 6c 65 29 31 30 30 30 30 3b 0a 20  (double)10000;. 
a7b0: 20 20 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49    .  return SQLI
a7c0: 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  TE_OK;.}../*.** 
a7d0: 54 68 65 20 78 55 70 64 61 74 65 28 29 20 6d 65  The xUpdate() me
a7e0: 74 68 6f 64 2e 20 20 0a 2a 2a 0a 2a 2a 20 54 68  thod.  .**.** Th
a7f0: 69 73 20 69 6d 70 6c 65 6d 65 6e 74 61 74 69 6f  is implementatio
a800: 6e 20 64 69 73 61 6c 6c 6f 77 73 20 44 45 4c 45  n disallows DELE
a810: 54 45 20 61 6e 64 20 55 50 44 41 54 45 2e 20 20  TE and UPDATE.  
a820: 54 68 65 20 6f 6e 6c 79 20 74 68 69 6e 67 0a 2a  The only thing.*
a830: 2a 20 61 6c 6c 6f 77 65 64 20 69 73 20 49 4e 53  * allowed is INS
a840: 45 52 54 20 69 6e 74 6f 20 74 68 65 20 22 63 6f  ERT into the "co
a850: 6d 6d 61 6e 64 22 20 63 6f 6c 75 6d 6e 2e 0a 2a  mmand" column..*
a860: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 61 6d 61  /.static int ama
a870: 74 63 68 55 70 64 61 74 65 28 0a 20 20 73 71 6c  tchUpdate(.  sql
a880: 69 74 65 33 5f 76 74 61 62 20 2a 70 56 54 61 62  ite3_vtab *pVTab
a890: 2c 0a 20 20 69 6e 74 20 61 72 67 63 2c 0a 20 20  ,.  int argc,.  
a8a0: 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 20 2a 2a  sqlite3_value **
a8b0: 61 72 67 76 2c 0a 20 20 73 71 6c 69 74 65 5f 69  argv,.  sqlite_i
a8c0: 6e 74 36 34 20 2a 70 52 6f 77 69 64 0a 29 7b 0a  nt64 *pRowid.){.
a8d0: 20 20 61 6d 61 74 63 68 5f 76 74 61 62 20 2a 70    amatch_vtab *p
a8e0: 20 3d 20 28 61 6d 61 74 63 68 5f 76 74 61 62 2a   = (amatch_vtab*
a8f0: 29 70 56 54 61 62 3b 0a 20 20 63 6f 6e 73 74 20  )pVTab;.  const 
a900: 75 6e 73 69 67 6e 65 64 20 63 68 61 72 20 2a 7a  unsigned char *z
a910: 43 6d 64 3b 0a 20 20 28 76 6f 69 64 29 70 52 6f  Cmd;.  (void)pRo
a920: 77 69 64 3b 0a 20 20 69 66 28 20 61 72 67 63 3d  wid;.  if( argc=
a930: 3d 31 20 29 7b 0a 20 20 20 20 70 56 54 61 62 2d  =1 ){.    pVTab-
a940: 3e 7a 45 72 72 4d 73 67 20 3d 20 73 71 6c 69 74  >zErrMsg = sqlit
a950: 65 33 5f 6d 70 72 69 6e 74 66 28 22 44 45 4c 45  e3_mprintf("DELE
a960: 54 45 20 66 72 6f 6d 20 25 73 20 69 73 20 6e 6f  TE from %s is no
a970: 74 20 61 6c 6c 6f 77 65 64 22 2c 20 0a 20 20 20  t allowed", .   
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 20 20 20 20 20 20 20 20                  
a9a0: 20 20 20 70 2d 3e 7a 53 65 6c 66 29 3b 0a 20 20     p->zSelf);.  
a9b0: 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f    return SQLITE_
a9c0: 45 52 52 4f 52 3b 0a 20 20 7d 0a 20 20 69 66 28  ERROR;.  }.  if(
a9d0: 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 74   sqlite3_value_t
a9e0: 79 70 65 28 61 72 67 76 5b 30 5d 29 21 3d 53 51  ype(argv[0])!=SQ
a9f0: 4c 49 54 45 5f 4e 55 4c 4c 20 29 7b 0a 20 20 20  LITE_NULL ){.   
aa00: 20 70 56 54 61 62 2d 3e 7a 45 72 72 4d 73 67 20   pVTab->zErrMsg 
aa10: 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74  = sqlite3_mprint
aa20: 66 28 22 55 50 44 41 54 45 20 6f 66 20 25 73 20  f("UPDATE of %s 
aa30: 69 73 20 6e 6f 74 20 61 6c 6c 6f 77 65 64 22 2c  is not allowed",
aa40: 20 0a 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 20 20 20                  
aa60: 20 20 20 20 20 20 20 20 70 2d 3e 7a 53 65 6c 66          p->zSelf
aa70: 29 3b 0a 20 20 20 20 72 65 74 75 72 6e 20 53 51  );.    return SQ
aa80: 4c 49 54 45 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a  LITE_ERROR;.  }.
aa90: 20 20 69 66 28 20 73 71 6c 69 74 65 33 5f 76 61    if( sqlite3_va
aaa0: 6c 75 65 5f 74 79 70 65 28 61 72 67 76 5b 32 2b  lue_type(argv[2+
aab0: 41 4d 41 54 43 48 5f 43 4f 4c 5f 57 4f 52 44 5d  AMATCH_COL_WORD]
aac0: 29 21 3d 53 51 4c 49 54 45 5f 4e 55 4c 4c 0a 20  )!=SQLITE_NULL. 
aad0: 20 20 7c 7c 20 73 71 6c 69 74 65 33 5f 76 61 6c    || sqlite3_val
aae0: 75 65 5f 74 79 70 65 28 61 72 67 76 5b 32 2b 41  ue_type(argv[2+A
aaf0: 4d 41 54 43 48 5f 43 4f 4c 5f 44 49 53 54 41 4e  MATCH_COL_DISTAN
ab00: 43 45 5d 29 21 3d 53 51 4c 49 54 45 5f 4e 55 4c  CE])!=SQLITE_NUL
ab10: 4c 0a 20 20 20 7c 7c 20 73 71 6c 69 74 65 33 5f  L.   || sqlite3_
ab20: 76 61 6c 75 65 5f 74 79 70 65 28 61 72 67 76 5b  value_type(argv[
ab30: 32 2b 41 4d 41 54 43 48 5f 43 4f 4c 5f 4c 41 4e  2+AMATCH_COL_LAN
ab40: 47 55 41 47 45 5d 29 21 3d 53 51 4c 49 54 45 5f  GUAGE])!=SQLITE_
ab50: 4e 55 4c 4c 0a 20 20 29 7b 0a 20 20 20 20 70 56  NULL.  ){.    pV
ab60: 54 61 62 2d 3e 7a 45 72 72 4d 73 67 20 3d 20 73  Tab->zErrMsg = s
ab70: 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 0a  qlite3_mprintf(.
ab80: 20 20 20 20 20 20 20 20 20 20 20 20 22 49 4e 53              "INS
ab90: 45 52 54 20 49 4e 54 4f 20 25 73 20 61 6c 6c 6f  ERT INTO %s allo
aba0: 77 65 64 20 66 6f 72 20 63 6f 6c 75 6d 6e 20 5b  wed for column [
abb0: 63 6f 6d 6d 61 6e 64 5d 20 6f 6e 6c 79 22 2c 20  command] only", 
abc0: 70 2d 3e 7a 53 65 6c 66 29 3b 0a 20 20 20 20 72  p->zSelf);.    r
abd0: 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 45 52 52  eturn SQLITE_ERR
abe0: 4f 52 3b 0a 20 20 7d 0a 20 20 7a 43 6d 64 20 3d  OR;.  }.  zCmd =
abf0: 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 74   sqlite3_value_t
ac00: 65 78 74 28 61 72 67 76 5b 32 2b 41 4d 41 54 43  ext(argv[2+AMATC
ac10: 48 5f 43 4f 4c 5f 43 4f 4d 4d 41 4e 44 5d 29 3b  H_COL_COMMAND]);
ac20: 0a 20 20 69 66 28 20 7a 43 6d 64 3d 3d 30 20 29  .  if( zCmd==0 )
ac30: 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f   return SQLITE_O
ac40: 4b 3b 0a 20 20 0a 20 20 72 65 74 75 72 6e 20 53  K;.  .  return S
ac50: 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a  QLITE_OK;.}../*.
ac60: 2a 2a 20 41 20 76 69 72 74 75 61 6c 20 74 61 62  ** A virtual tab
ac70: 6c 65 20 6d 6f 64 75 6c 65 20 74 68 61 74 20 69  le module that i
ac80: 6d 70 6c 65 6d 65 6e 74 73 20 74 68 65 20 22 61  mplements the "a
ac90: 70 70 72 6f 78 69 6d 61 74 65 5f 6d 61 74 63 68  pproximate_match
aca0: 22 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 73 71 6c  "..*/.static sql
acb0: 69 74 65 33 5f 6d 6f 64 75 6c 65 20 61 6d 61 74  ite3_module amat
acc0: 63 68 4d 6f 64 75 6c 65 20 3d 20 7b 0a 20 20 30  chModule = {.  0
acd0: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
ace0: 20 20 20 20 20 20 20 2f 2a 20 69 56 65 72 73 69         /* iVersi
acf0: 6f 6e 20 2a 2f 0a 20 20 61 6d 61 74 63 68 43 6f  on */.  amatchCo
ad00: 6e 6e 65 63 74 2c 20 20 20 20 20 20 20 20 20 20  nnect,          
ad10: 2f 2a 20 78 43 72 65 61 74 65 20 2a 2f 0a 20 20  /* xCreate */.  
ad20: 61 6d 61 74 63 68 43 6f 6e 6e 65 63 74 2c 20 20  amatchConnect,  
ad30: 20 20 20 20 20 20 20 20 2f 2a 20 78 43 6f 6e 6e          /* xConn
ad40: 65 63 74 20 2a 2f 0a 20 20 61 6d 61 74 63 68 42  ect */.  amatchB
ad50: 65 73 74 49 6e 64 65 78 2c 20 20 20 20 20 20 20  estIndex,       
ad60: 20 2f 2a 20 78 42 65 73 74 49 6e 64 65 78 20 2a   /* xBestIndex *
ad70: 2f 0a 20 20 61 6d 61 74 63 68 44 69 73 63 6f 6e  /.  amatchDiscon
ad80: 6e 65 63 74 2c 20 20 20 20 20 20 20 2f 2a 20 78  nect,       /* x
ad90: 44 69 73 63 6f 6e 6e 65 63 74 20 2a 2f 0a 20 20  Disconnect */.  
ada0: 61 6d 61 74 63 68 44 69 73 63 6f 6e 6e 65 63 74  amatchDisconnect
adb0: 2c 20 20 20 20 20 20 20 2f 2a 20 78 44 65 73 74  ,       /* xDest
adc0: 72 6f 79 20 2a 2f 0a 20 20 61 6d 61 74 63 68 4f  roy */.  amatchO
add0: 70 65 6e 2c 20 20 20 20 20 20 20 20 20 20 20 20  pen,            
ade0: 20 2f 2a 20 78 4f 70 65 6e 20 2d 20 6f 70 65 6e   /* xOpen - open
adf0: 20 61 20 63 75 72 73 6f 72 20 2a 2f 0a 20 20 61   a cursor */.  a
ae00: 6d 61 74 63 68 43 6c 6f 73 65 2c 20 20 20 20 20  matchClose,     
ae10: 20 20 20 20 20 20 20 2f 2a 20 78 43 6c 6f 73 65         /* xClose
ae20: 20 2d 20 63 6c 6f 73 65 20 61 20 63 75 72 73 6f   - close a curso
ae30: 72 20 2a 2f 0a 20 20 61 6d 61 74 63 68 46 69 6c  r */.  amatchFil
ae40: 74 65 72 2c 20 20 20 20 20 20 20 20 20 20 20 2f  ter,           /
ae50: 2a 20 78 46 69 6c 74 65 72 20 2d 20 63 6f 6e 66  * xFilter - conf
ae60: 69 67 75 72 65 20 73 63 61 6e 20 63 6f 6e 73 74  igure scan const
ae70: 72 61 69 6e 74 73 20 2a 2f 0a 20 20 61 6d 61 74  raints */.  amat
ae80: 63 68 4e 65 78 74 2c 20 20 20 20 20 20 20 20 20  chNext,         
ae90: 20 20 20 20 2f 2a 20 78 4e 65 78 74 20 2d 20 61      /* xNext - a
aea0: 64 76 61 6e 63 65 20 61 20 63 75 72 73 6f 72 20  dvance a cursor 
aeb0: 2a 2f 0a 20 20 61 6d 61 74 63 68 45 6f 66 2c 20  */.  amatchEof, 
aec0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
aed0: 78 45 6f 66 20 2d 20 63 68 65 63 6b 20 66 6f 72  xEof - check for
aee0: 20 65 6e 64 20 6f 66 20 73 63 61 6e 20 2a 2f 0a   end of scan */.
aef0: 20 20 61 6d 61 74 63 68 43 6f 6c 75 6d 6e 2c 20    amatchColumn, 
af00: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 43 6f            /* xCo
af10: 6c 75 6d 6e 20 2d 20 72 65 61 64 20 64 61 74 61  lumn - read data
af20: 20 2a 2f 0a 20 20 61 6d 61 74 63 68 52 6f 77 69   */.  amatchRowi
af30: 64 2c 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a  d,            /*
af40: 20 78 52 6f 77 69 64 20 2d 20 72 65 61 64 20 64   xRowid - read d
af50: 61 74 61 20 2a 2f 0a 20 20 61 6d 61 74 63 68 55  ata */.  amatchU
af60: 70 64 61 74 65 2c 20 20 20 20 20 20 20 20 20 20  pdate,          
af70: 20 2f 2a 20 78 55 70 64 61 74 65 20 2a 2f 0a 20   /* xUpdate */. 
af80: 20 30 2c 20 20 20 20 20 20 20 20 20 20 20 20 20   0,             
af90: 20 20 20 20 20 20 20 20 20 2f 2a 20 78 42 65 67           /* xBeg
afa0: 69 6e 20 2a 2f 0a 20 20 30 2c 20 20 20 20 20 20  in */.  0,      
afb0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
afc0: 2f 2a 20 78 53 79 6e 63 20 2a 2f 0a 20 20 30 2c  /* xSync */.  0,
afd0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
afe0: 20 20 20 20 20 20 2f 2a 20 78 43 6f 6d 6d 69 74        /* xCommit
aff0: 20 2a 2f 0a 20 20 30 2c 20 20 20 20 20 20 20 20   */.  0,        
b000: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
b010: 20 78 52 6f 6c 6c 62 61 63 6b 20 2a 2f 0a 20 20   xRollback */.  
b020: 30 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  0,              
b030: 20 20 20 20 20 20 20 20 2f 2a 20 78 46 69 6e 64          /* xFind
b040: 4d 65 74 68 6f 64 20 2a 2f 0a 20 20 30 2c 20 20  Method */.  0,  
b050: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
b060: 20 20 20 20 2f 2a 20 78 52 65 6e 61 6d 65 20 2a      /* xRename *
b070: 2f 0a 20 20 30 2c 20 20 20 20 20 20 20 20 20 20  /.  0,          
b080: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78              /* x
b090: 53 61 76 65 70 6f 69 6e 74 20 2a 2f 0a 20 20 30  Savepoint */.  0
b0a0: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
b0b0: 20 20 20 20 20 20 20 2f 2a 20 78 52 65 6c 65 61         /* xRelea
b0c0: 73 65 20 2a 2f 0a 20 20 30 2c 20 20 20 20 20 20  se */.  0,      
b0d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
b0e0: 2f 2a 20 78 52 6f 6c 6c 62 61 63 6b 54 6f 20 2a  /* xRollbackTo *
b0f0: 2f 0a 20 20 30 20 20 20 20 20 20 20 20 20 20 20  /.  0           
b100: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78              /* x
b110: 53 68 61 64 6f 77 4e 61 6d 65 20 2a 2f 0a 7d 3b  ShadowName */.};
b120: 0a 0a 23 65 6e 64 69 66 20 2f 2a 20 53 51 4c 49  ..#endif /* SQLI
b130: 54 45 5f 4f 4d 49 54 5f 56 49 52 54 55 41 4c 54  TE_OMIT_VIRTUALT
b140: 41 42 4c 45 20 2a 2f 0a 0a 2f 2a 0a 2a 2a 20 52  ABLE */../*.** R
b150: 65 67 69 73 74 65 72 20 74 68 65 20 61 6d 61 74  egister the amat
b160: 63 68 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65  ch virtual table
b170: 0a 2a 2f 0a 23 69 66 64 65 66 20 5f 57 49 4e 33  .*/.#ifdef _WIN3
b180: 32 0a 5f 5f 64 65 63 6c 73 70 65 63 28 64 6c 6c  2.__declspec(dll
b190: 65 78 70 6f 72 74 29 0a 23 65 6e 64 69 66 0a 69  export).#endif.i
b1a0: 6e 74 20 73 71 6c 69 74 65 33 5f 61 6d 61 74 63  nt sqlite3_amatc
b1b0: 68 5f 69 6e 69 74 28 0a 20 20 73 71 6c 69 74 65  h_init(.  sqlite
b1c0: 33 20 2a 64 62 2c 20 0a 20 20 63 68 61 72 20 2a  3 *db, .  char *
b1d0: 2a 70 7a 45 72 72 4d 73 67 2c 20 0a 20 20 63 6f  *pzErrMsg, .  co
b1e0: 6e 73 74 20 73 71 6c 69 74 65 33 5f 61 70 69 5f  nst sqlite3_api_
b1f0: 72 6f 75 74 69 6e 65 73 20 2a 70 41 70 69 0a 29  routines *pApi.)
b200: 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c  {.  int rc = SQL
b210: 49 54 45 5f 4f 4b 3b 0a 20 20 53 51 4c 49 54 45  ITE_OK;.  SQLITE
b220: 5f 45 58 54 45 4e 53 49 4f 4e 5f 49 4e 49 54 32  _EXTENSION_INIT2
b230: 28 70 41 70 69 29 3b 0a 20 20 28 76 6f 69 64 29  (pApi);.  (void)
b240: 70 7a 45 72 72 4d 73 67 3b 20 20 2f 2a 20 4e 6f  pzErrMsg;  /* No
b250: 74 20 75 73 65 64 20 2a 2f 0a 23 69 66 6e 64 65  t used */.#ifnde
b260: 66 20 53 51 4c 49 54 45 5f 4f 4d 49 54 5f 56 49  f SQLITE_OMIT_VI
b270: 52 54 55 41 4c 54 41 42 4c 45 0a 20 20 72 63 20  RTUALTABLE.  rc 
b280: 3d 20 73 71 6c 69 74 65 33 5f 63 72 65 61 74 65  = sqlite3_create
b290: 5f 6d 6f 64 75 6c 65 28 64 62 2c 20 22 61 70 70  _module(db, "app
b2a0: 72 6f 78 69 6d 61 74 65 5f 6d 61 74 63 68 22 2c  roximate_match",
b2b0: 20 26 61 6d 61 74 63 68 4d 6f 64 75 6c 65 2c 20   &amatchModule, 
b2c0: 30 29 3b 0a 23 65 6e 64 69 66 20 2f 2a 20 53 51  0);.#endif /* SQ
b2d0: 4c 49 54 45 5f 4f 4d 49 54 5f 56 49 52 54 55 41  LITE_OMIT_VIRTUA
b2e0: 4c 54 41 42 4c 45 20 2a 2f 0a 20 20 72 65 74 75  LTABLE */.  retu
b2f0: 72 6e 20 72 63 3b 0a 7d 0a                       rn rc;.}.