/ Hex Artifact Content
Login

Artifact 2b1a579be557ab8ac54a51b39caa4aa8043cc4ad:


0000: 23 20 32 30 30 39 20 44 65 63 65 6d 62 65 72 20  # 2009 December 
0010: 30 33 0a 23 0a 23 20 20 20 20 4d 61 79 20 79 6f  03.#.#    May yo
0020: 75 20 64 6f 20 67 6f 6f 64 20 61 6e 64 20 6e 6f  u do good and no
0030: 74 20 65 76 69 6c 2e 0a 23 20 20 20 20 4d 61 79  t evil..#    May
0040: 20 79 6f 75 20 66 69 6e 64 20 66 6f 72 67 69 76   you find forgiv
0050: 65 6e 65 73 73 20 66 6f 72 20 79 6f 75 72 73 65  eness for yourse
0060: 6c 66 20 61 6e 64 20 66 6f 72 67 69 76 65 20 6f  lf and forgive o
0070: 74 68 65 72 73 2e 0a 23 20 20 20 20 4d 61 79 20  thers..#    May 
0080: 79 6f 75 20 73 68 61 72 65 20 66 72 65 65 6c 79  you share freely
0090: 2c 20 6e 65 76 65 72 20 74 61 6b 69 6e 67 20 6d  , never taking m
00a0: 6f 72 65 20 74 68 61 6e 20 79 6f 75 20 67 69 76  ore than you giv
00b0: 65 2e 0a 23 0a 23 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  e..#.#**********
00c0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
00d0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
00e0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
00f0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 0a 23 0a  *************.#.
0100: 23 20 42 72 75 74 65 20 66 6f 72 63 65 20 28 72  # Brute force (r
0110: 61 6e 64 6f 6d 20 64 61 74 61 29 20 74 65 73 74  andom data) test
0120: 73 20 66 6f 72 20 46 54 53 33 2e 0a 23 0a 0a 23  s for FTS3..#..#
0130: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
0140: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
0150: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
0160: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
0170: 2d 2d 2d 2d 2d 2d 2d 2d 2d 0a 23 0a 23 20 54 68  ---------.#.# Th
0180: 65 20 46 54 53 33 20 74 65 73 74 73 20 69 6d 70  e FTS3 tests imp
0190: 6c 65 6d 65 6e 74 65 64 20 69 6e 20 74 68 69 73  lemented in this
01a0: 20 66 69 6c 65 20 66 6f 63 75 73 20 6f 6e 20 74   file focus on t
01b0: 65 73 74 69 6e 67 20 74 68 61 74 20 46 54 53 33  esting that FTS3
01c0: 0a 23 20 72 65 74 75 72 6e 73 20 74 68 65 20 63  .# returns the c
01d0: 6f 72 72 65 63 74 20 73 65 74 20 6f 66 20 64 6f  orrect set of do
01e0: 63 75 6d 65 6e 74 73 20 66 6f 72 20 76 61 72 69  cuments for vari
01f0: 6f 75 73 20 74 79 70 65 73 20 6f 66 20 66 75 6c  ous types of ful
0200: 6c 2d 74 65 78 74 0a 23 20 71 75 65 72 79 2e 20  l-text.# query. 
0210: 54 68 69 73 20 69 73 20 64 6f 6e 65 20 75 73 69  This is done usi
0220: 6e 67 20 70 73 65 75 64 6f 2d 72 61 6e 64 6f 6d  ng pseudo-random
0230: 6c 79 20 67 65 6e 65 72 61 74 65 64 20 64 61 74  ly generated dat
0240: 61 20 61 6e 64 20 71 75 65 72 69 65 73 2e 0a 23  a and queries..#
0250: 20 54 68 65 20 65 78 70 65 63 74 65 64 20 72 65   The expected re
0260: 73 75 6c 74 20 6f 66 20 65 61 63 68 20 71 75 65  sult of each que
0270: 72 79 20 69 73 20 63 61 6c 63 75 6c 61 74 65 64  ry is calculated
0280: 20 75 73 69 6e 67 20 54 63 6c 20 63 6f 64 65 2e   using Tcl code.
0290: 0a 23 0a 23 20 20 20 31 2e 20 54 68 65 20 64 61  .#.#   1. The da
02a0: 74 61 62 61 73 65 20 69 73 20 69 6e 69 74 69 61  tabase is initia
02b0: 6c 69 7a 65 64 20 74 6f 20 63 6f 6e 74 61 69 6e  lized to contain
02c0: 20 61 20 73 69 6e 67 6c 65 20 74 61 62 6c 65 20   a single table 
02d0: 77 69 74 68 20 74 68 72 65 65 0a 23 20 20 20 20  with three.#    
02e0: 20 20 63 6f 6c 75 6d 6e 73 2e 20 31 30 30 20 72    columns. 100 r
02f0: 6f 77 73 20 61 72 65 20 69 6e 73 65 72 74 65 64  ows are inserted
0300: 20 69 6e 74 6f 20 74 68 65 20 74 61 62 6c 65 2e   into the table.
0310: 20 45 61 63 68 20 6f 66 20 74 68 65 20 74 68 72   Each of the thr
0320: 65 65 0a 23 20 20 20 20 20 20 76 61 6c 75 65 73  ee.#      values
0330: 20 69 6e 20 65 61 63 68 20 72 6f 77 20 69 73 20   in each row is 
0340: 61 20 64 6f 63 75 6d 65 6e 74 20 63 6f 6e 73 69  a document consi
0350: 73 74 69 6e 67 20 6f 66 20 62 65 74 77 65 65 6e  sting of between
0360: 20 30 20 61 6e 64 20 31 30 30 0a 23 20 20 20 20   0 and 100.#    
0370: 20 20 74 65 72 6d 73 2e 20 54 65 72 6d 73 20 61    terms. Terms a
0380: 72 65 20 73 65 6c 65 63 74 65 64 20 66 72 6f 6d  re selected from
0390: 20 61 20 76 6f 63 61 62 75 6c 61 72 79 20 6f 66   a vocabulary of
03a0: 20 24 47 28 6e 56 6f 63 61 62 29 20 74 65 72 6d   $G(nVocab) term
03b0: 73 2e 0a 23 0a 23 20 20 20 32 2e 20 54 68 65 20  s..#.#   2. The 
03c0: 66 6f 6c 6c 6f 77 69 6e 67 20 69 73 20 70 65 72  following is per
03d0: 66 6f 72 6d 65 64 20 31 30 30 20 74 69 6d 65 73  formed 100 times
03e0: 3a 0a 23 0a 23 20 20 20 20 20 20 61 2e 20 41 20  :.#.#      a. A 
03f0: 72 6f 77 20 69 73 20 69 6e 73 65 72 74 65 64 20  row is inserted 
0400: 69 6e 74 6f 20 74 68 65 20 64 61 74 61 62 61 73  into the databas
0410: 65 2e 20 54 68 65 20 72 6f 77 20 63 6f 6e 74 65  e. The row conte
0420: 6e 74 73 20 61 72 65 20 0a 23 20 20 20 20 20 20  nts are .#      
0430: 20 20 20 67 65 6e 65 72 61 74 65 64 20 61 73 20     generated as 
0440: 69 6e 20 73 74 65 70 20 31 2e 20 54 68 65 20 64  in step 1. The d
0450: 6f 63 69 64 20 69 73 20 61 20 70 73 65 75 64 6f  ocid is a pseudo
0460: 2d 72 61 6e 64 6f 6d 6c 79 20 73 65 6c 65 63 74  -randomly select
0470: 65 64 0a 23 20 20 20 20 20 20 20 20 20 76 61 6c  ed.#         val
0480: 75 65 20 62 65 74 77 65 65 6e 20 30 20 61 6e 64  ue between 0 and
0490: 20 31 30 30 30 30 30 30 2e 0a 23 20 0a 23 20 20   1000000..# .#  
04a0: 20 20 20 20 62 2e 20 41 20 70 73 75 65 64 6f 2d      b. A psuedo-
04b0: 72 61 6e 64 6f 6d 6c 79 20 73 65 6c 65 63 74 65  randomly selecte
04c0: 64 20 72 6f 77 20 69 73 20 75 70 64 61 74 65 64  d row is updated
04d0: 2e 20 4f 6e 65 20 6f 66 20 69 74 73 20 63 6f 6c  . One of its col
04e0: 75 6d 6e 73 20 69 73 0a 23 20 20 20 20 20 20 20  umns is.#       
04f0: 20 20 73 65 74 20 74 6f 20 63 6f 6e 74 61 69 6e    set to contain
0500: 20 61 20 6e 65 77 20 64 6f 63 75 6d 65 6e 74 20   a new document 
0510: 67 65 6e 65 72 61 74 65 64 20 69 6e 20 74 68 65  generated in the
0520: 20 73 61 6d 65 20 77 61 79 20 61 73 20 74 68 65   same way as the
0530: 0a 23 20 20 20 20 20 20 20 20 20 64 6f 63 75 6d  .#         docum
0540: 65 6e 74 73 20 69 6e 20 73 74 65 70 20 31 2e 0a  ents in step 1..
0550: 23 20 0a 23 20 20 20 20 20 20 63 2e 20 41 20 70  # .#      c. A p
0560: 73 75 65 64 6f 2d 72 61 6e 64 6f 6d 6c 79 20 73  suedo-randomly s
0570: 65 6c 65 63 74 65 64 20 72 6f 77 20 69 73 20 64  elected row is d
0580: 65 6c 65 74 65 64 2e 0a 23 20 0a 23 20 20 20 20  eleted..# .#    
0590: 20 20 64 2e 20 46 6f 72 20 65 61 63 68 20 6f 66    d. For each of
05a0: 20 73 65 76 65 72 61 6c 20 74 79 70 65 73 20 6f   several types o
05b0: 66 20 66 74 73 33 20 71 75 65 72 69 65 73 2c 20  f fts3 queries, 
05c0: 31 30 20 53 45 4c 45 43 54 20 71 75 65 72 69 65  10 SELECT querie
05d0: 73 0a 23 20 20 20 20 20 20 20 20 20 6f 66 20 74  s.#         of t
05e0: 68 65 20 66 6f 72 6d 3a 0a 23 20 0a 23 20 20 20  he form:.# .#   
05f0: 20 20 20 20 20 20 20 20 53 45 4c 45 43 54 20 64          SELECT d
0600: 6f 63 69 64 20 46 52 4f 4d 20 3c 74 62 6c 3e 20  ocid FROM <tbl> 
0610: 57 48 45 52 45 20 3c 74 62 6c 3e 20 4d 41 54 43  WHERE <tbl> MATC
0620: 48 20 27 3c 71 75 65 72 79 3e 27 0a 23 20 0a 23  H '<query>'.# .#
0630: 20 20 20 20 20 20 20 20 20 61 72 65 20 65 76 61           are eva
0640: 6c 75 61 74 65 64 2e 20 54 68 65 20 72 65 73 75  luated. The resu
0650: 6c 74 73 20 61 72 65 20 63 6f 6d 70 61 72 65 64  lts are compared
0660: 20 74 6f 20 74 68 6f 73 65 20 63 61 6c 63 75 6c   to those calcul
0670: 61 74 65 64 20 62 79 0a 23 20 20 20 20 20 20 20  ated by.#       
0680: 20 20 54 63 6c 20 63 6f 64 65 20 69 6e 20 74 68    Tcl code in th
0690: 69 73 20 66 69 6c 65 2e 20 54 68 65 20 70 61 74  is file. The pat
06a0: 74 65 72 6e 73 20 75 73 65 64 20 66 6f 72 20 74  terns used for t
06b0: 68 65 20 64 69 66 66 65 72 65 6e 74 20 71 75 65  he different que
06c0: 72 79 0a 23 20 20 20 20 20 20 20 20 20 74 79 70  ry.#         typ
06d0: 65 73 20 61 72 65 3a 0a 23 20 0a 23 20 20 20 20  es are:.# .#    
06e0: 20 20 20 20 20 20 20 31 2e 20 20 71 75 65 72 79         1.  query
06f0: 20 3d 20 3c 74 65 72 6d 3e 0a 23 20 20 20 20 20   = <term>.#     
0700: 20 20 20 20 20 20 32 2e 20 20 71 75 65 72 79 20        2.  query 
0710: 3d 20 3c 70 72 65 66 69 78 3e 0a 23 20 20 20 20  = <prefix>.#    
0720: 20 20 20 20 20 20 20 33 2e 20 20 71 75 65 72 79         3.  query
0730: 20 3d 20 22 3c 74 65 72 6d 3e 20 3c 74 65 72 6d   = "<term> <term
0740: 3e 22 0a 23 20 20 20 20 20 20 20 20 20 20 20 34  >".#           4
0750: 2e 20 20 71 75 65 72 79 20 3d 20 22 3c 74 65 72  .  query = "<ter
0760: 6d 3e 20 3c 74 65 72 6d 3e 20 3c 74 65 72 6d 3e  m> <term> <term>
0770: 22 0a 23 20 20 20 20 20 20 20 20 20 20 20 35 2e  ".#           5.
0780: 20 20 71 75 65 72 79 20 3d 20 22 3c 70 72 65 66    query = "<pref
0790: 69 78 3e 20 3c 70 72 65 66 69 78 3e 20 3c 70 72  ix> <prefix> <pr
07a0: 65 66 69 78 3e 22 0a 23 20 20 20 20 20 20 20 20  efix>".#        
07b0: 20 20 20 36 2e 20 20 71 75 65 72 79 20 3d 20 3c     6.  query = <
07c0: 74 65 72 6d 3e 20 4e 45 41 52 20 3c 74 65 72 6d  term> NEAR <term
07d0: 3e 0a 23 20 20 20 20 20 20 20 20 20 20 20 37 2e  >.#           7.
07e0: 20 20 71 75 65 72 79 20 3d 20 3c 74 65 72 6d 3e    query = <term>
07f0: 20 4e 45 41 52 2f 31 31 20 3c 74 65 72 6d 3e 20   NEAR/11 <term> 
0800: 4e 45 41 52 2f 31 31 20 3c 74 65 72 6d 3e 0a 23  NEAR/11 <term>.#
0810: 20 20 20 20 20 20 20 20 20 20 20 38 2e 20 20 71             8.  q
0820: 75 65 72 79 20 3d 20 3c 74 65 72 6d 3e 20 4f 52  uery = <term> OR
0830: 20 3c 74 65 72 6d 3e 0a 23 20 20 20 20 20 20 20   <term>.#       
0840: 20 20 20 20 39 2e 20 20 71 75 65 72 79 20 3d 20      9.  query = 
0850: 3c 74 65 72 6d 3e 20 4e 4f 54 20 3c 74 65 72 6d  <term> NOT <term
0860: 3e 0a 23 20 20 20 20 20 20 20 20 20 20 20 31 30  >.#           10
0870: 2e 20 71 75 65 72 79 20 3d 20 3c 74 65 72 6d 3e  . query = <term>
0880: 20 41 4e 44 20 3c 74 65 72 6d 3e 0a 23 20 20 20   AND <term>.#   
0890: 20 20 20 20 20 20 20 20 31 31 2e 20 71 75 65 72          11. quer
08a0: 79 20 3d 20 3c 74 65 72 6d 3e 20 4e 45 41 52 20  y = <term> NEAR 
08b0: 3c 74 65 72 6d 3e 20 4f 52 20 3c 74 65 72 6d 3e  <term> OR <term>
08c0: 20 4e 45 41 52 20 3c 74 65 72 6d 3e 0a 23 20 20   NEAR <term>.#  
08d0: 20 20 20 20 20 20 20 20 20 31 32 2e 20 71 75 65           12. que
08e0: 72 79 20 3d 20 3c 74 65 72 6d 3e 20 4e 45 41 52  ry = <term> NEAR
08f0: 20 3c 74 65 72 6d 3e 20 4e 4f 54 20 3c 74 65 72   <term> NOT <ter
0900: 6d 3e 20 4e 45 41 52 20 3c 74 65 72 6d 3e 0a 23  m> NEAR <term>.#
0910: 20 20 20 20 20 20 20 20 20 20 20 31 33 2e 20 71             13. q
0920: 75 65 72 79 20 3d 20 3c 74 65 72 6d 3e 20 4e 45  uery = <term> NE
0930: 41 52 20 3c 74 65 72 6d 3e 20 41 4e 44 20 3c 74  AR <term> AND <t
0940: 65 72 6d 3e 20 4e 45 41 52 20 3c 74 65 72 6d 3e  erm> NEAR <term>
0950: 0a 23 20 0a 23 20 20 20 20 20 20 20 20 20 77 68  .# .#         wh
0960: 65 72 65 20 3c 74 65 72 6d 3e 20 69 73 20 61 20  ere <term> is a 
0970: 74 65 72 6d 20 70 73 75 65 64 6f 2d 72 61 6e 64  term psuedo-rand
0980: 6f 6d 6c 79 20 73 65 6c 65 63 74 65 64 20 66 72  omly selected fr
0990: 6f 6d 20 74 68 65 20 76 6f 63 61 62 75 6c 61 72  om the vocabular
09a0: 79 0a 23 20 20 20 20 20 20 20 20 20 61 6e 64 20  y.#         and 
09b0: 70 72 65 66 69 78 20 69 73 20 74 68 65 20 66 69  prefix is the fi
09c0: 72 73 74 20 32 20 63 68 61 72 61 63 74 65 72 73  rst 2 characters
09d0: 20 6f 66 20 73 75 63 68 20 61 20 74 65 72 6d 20   of such a term 
09e0: 66 6f 6c 6c 6f 77 65 64 20 62 79 0a 23 20 20 20  followed by.#   
09f0: 20 20 20 20 20 20 61 20 22 2a 22 20 63 68 61 72        a "*" char
0a00: 61 63 74 65 72 2e 0a 23 20 20 20 20 20 0a 23 20  acter..#     .# 
0a10: 20 20 20 20 20 45 76 65 72 79 20 73 65 63 6f 6e       Every secon
0a20: 64 20 69 74 65 72 61 74 69 6f 6e 2c 20 73 74 65  d iteration, ste
0a30: 70 73 20 28 61 29 20 74 68 72 6f 75 67 68 20 28  ps (a) through (
0a40: 64 29 20 61 62 6f 76 65 20 61 72 65 20 70 65 72  d) above are per
0a50: 66 6f 72 6d 65 64 0a 23 20 20 20 20 20 20 77 69  formed.#      wi
0a60: 74 68 69 6e 20 61 20 73 69 6e 67 6c 65 20 74 72  thin a single tr
0a70: 61 6e 73 61 63 74 69 6f 6e 2e 20 54 68 69 73 20  ansaction. This 
0a80: 66 6f 72 63 65 73 20 74 68 65 20 71 75 65 72 69  forces the queri
0a90: 65 73 20 69 6e 20 28 64 29 20 74 6f 0a 23 20 20  es in (d) to.#  
0aa0: 20 20 20 20 72 65 61 64 20 64 61 74 61 20 66 72      read data fr
0ab0: 6f 6d 20 62 6f 74 68 20 74 68 65 20 64 61 74 61  om both the data
0ac0: 62 61 73 65 20 61 6e 64 20 74 68 65 20 69 6e 2d  base and the in-
0ad0: 6d 65 6d 6f 72 79 20 68 61 73 68 20 74 61 62 6c  memory hash tabl
0ae0: 65 0a 23 20 20 20 20 20 20 74 68 61 74 20 63 61  e.#      that ca
0af0: 63 68 65 73 20 74 68 65 20 66 75 6c 6c 2d 74 65  ches the full-te
0b00: 78 74 20 69 6e 64 65 78 20 65 6e 74 72 69 65 73  xt index entries
0b10: 20 63 72 65 61 74 65 64 20 62 79 20 73 74 65 70   created by step
0b20: 73 20 28 61 29 2c 20 28 62 29 0a 23 20 20 20 20  s (a), (b).#    
0b30: 20 20 61 6e 64 20 28 63 29 20 75 6e 74 69 6c 20    and (c) until 
0b40: 74 68 65 20 74 72 61 6e 73 61 63 74 69 6f 6e 20  the transaction 
0b50: 69 73 20 63 6f 6d 6d 69 74 74 65 64 2e 0a 23 0a  is committed..#.
0b60: 23 20 54 68 65 20 70 72 6f 63 65 64 75 72 65 20  # The procedure 
0b70: 61 62 6f 76 65 20 69 73 20 72 75 6e 20 35 20 74  above is run 5 t
0b80: 69 6d 65 73 2c 20 75 73 69 6e 67 20 61 64 76 69  imes, using advi
0b90: 73 6f 72 79 20 66 74 73 33 20 6e 6f 64 65 20 73  sory fts3 node s
0ba0: 69 7a 65 73 20 6f 66 20 35 30 2c 0a 23 20 35 30  izes of 50,.# 50
0bb0: 30 2c 20 31 30 30 30 20 61 6e 64 20 32 30 30 30  0, 1000 and 2000
0bc0: 20 62 79 74 65 73 2e 0a 23 0a 23 20 41 66 74 65   bytes..#.# Afte
0bd0: 72 20 74 68 65 20 74 65 73 74 20 75 73 69 6e 67  r the test using
0be0: 20 61 6e 20 61 64 76 69 73 6f 72 79 20 6e 6f 64   an advisory nod
0bf0: 65 2d 73 69 7a 65 20 6f 66 20 35 30 2c 20 61 6e  e-size of 50, an
0c00: 20 4f 4f 4d 20 74 65 73 74 20 69 73 20 72 75 6e   OOM test is run
0c10: 20 75 73 69 6e 67 0a 23 20 74 68 65 20 64 61 74   using.# the dat
0c20: 61 62 61 73 65 2e 20 54 68 69 73 20 74 65 73 74  abase. This test
0c30: 20 69 73 20 73 69 6d 69 6c 61 72 20 74 6f 20 73   is similar to s
0c40: 74 65 70 20 28 64 29 20 61 62 6f 76 65 2c 20 65  tep (d) above, e
0c50: 78 63 65 70 74 20 74 68 61 74 20 69 74 20 74 65  xcept that it te
0c60: 73 74 73 0a 23 20 74 68 65 20 65 66 66 65 63 74  sts.# the effect
0c70: 73 20 6f 66 20 74 72 61 6e 73 69 65 6e 74 20 61  s of transient a
0c80: 6e 64 20 70 65 72 73 69 73 74 65 6e 74 20 4f 4f  nd persistent OO
0c90: 4d 20 63 6f 6e 64 69 74 69 6f 6e 73 20 65 6e 63  M conditions enc
0ca0: 6f 75 6e 74 65 72 65 64 20 77 68 69 6c 65 0a 23  ountered while.#
0cb0: 20 65 78 65 63 75 74 69 6e 67 20 65 61 63 68 20   executing each 
0cc0: 71 75 65 72 79 2e 0a 23 0a 0a 73 65 74 20 74 65  query..#..set te
0cd0: 73 74 64 69 72 20 5b 66 69 6c 65 20 64 69 72 6e  stdir [file dirn
0ce0: 61 6d 65 20 24 61 72 67 76 30 5d 0a 73 6f 75 72  ame $argv0].sour
0cf0: 63 65 20 24 74 65 73 74 64 69 72 2f 74 65 73 74  ce $testdir/test
0d00: 65 72 2e 74 63 6c 0a 0a 23 20 49 66 20 74 68 69  er.tcl..# If thi
0d10: 73 20 62 75 69 6c 64 20 64 6f 65 73 20 6e 6f 74  s build does not
0d20: 20 69 6e 63 6c 75 64 65 20 46 54 53 33 2c 20 73   include FTS3, s
0d30: 6b 69 70 20 74 68 65 20 74 65 73 74 73 20 69 6e  kip the tests in
0d40: 20 74 68 69 73 20 66 69 6c 65 2e 0a 23 0a 69 66   this file..#.if
0d50: 63 61 70 61 62 6c 65 20 21 66 74 73 33 20 7b 20  capable !fts3 { 
0d60: 66 69 6e 69 73 68 5f 74 65 73 74 20 3b 20 72 65  finish_test ; re
0d70: 74 75 72 6e 20 7d 0a 73 6f 75 72 63 65 20 24 74  turn }.source $t
0d80: 65 73 74 64 69 72 2f 66 74 73 33 5f 63 6f 6d 6d  estdir/fts3_comm
0d90: 6f 6e 2e 74 63 6c 0a 73 6f 75 72 63 65 20 24 74  on.tcl.source $t
0da0: 65 73 74 64 69 72 2f 6d 61 6c 6c 6f 63 5f 63 6f  estdir/malloc_co
0db0: 6d 6d 6f 6e 2e 74 63 6c 0a 0a 73 65 74 20 47 28  mmon.tcl..set G(
0dc0: 6e 56 6f 63 61 62 29 20 31 30 30 0a 0a 73 65 74  nVocab) 100..set
0dd0: 20 6e 56 6f 63 61 62 20 31 30 30 0a 73 65 74 20   nVocab 100.set 
0de0: 6c 56 6f 63 61 62 20 5b 6c 69 73 74 5d 0a 0a 65  lVocab [list]..e
0df0: 78 70 72 20 73 72 61 6e 64 28 30 29 0a 0a 23 20  xpr srand(0)..# 
0e00: 47 65 6e 65 72 61 74 65 20 61 20 76 6f 63 61 62  Generate a vocab
0e10: 75 6c 61 72 79 20 6f 66 20 6e 56 6f 63 61 62 20  ulary of nVocab 
0e20: 77 6f 72 64 73 2e 20 45 61 63 68 20 77 6f 72 64  words. Each word
0e30: 20 69 73 20 33 20 63 68 61 72 61 63 74 65 72 73   is 3 characters
0e40: 20 6c 6f 6e 67 2e 0a 23 0a 73 65 74 20 6c 43 68   long..#.set lCh
0e50: 61 72 20 7b 61 20 62 20 63 20 64 20 65 20 66 20  ar {a b c d e f 
0e60: 67 20 68 20 69 20 6a 20 6b 20 6c 20 6d 20 6e 20  g h i j k l m n 
0e70: 6f 20 70 20 71 20 72 20 73 20 74 20 75 20 76 20  o p q r s t u v 
0e80: 77 20 78 20 79 20 7a 7d 0a 66 6f 72 20 7b 73 65  w x y z}.for {se
0e90: 74 20 69 20 30 7d 20 7b 24 69 20 3c 20 24 6e 56  t i 0} {$i < $nV
0ea0: 6f 63 61 62 7d 20 7b 69 6e 63 72 20 69 7d 20 7b  ocab} {incr i} {
0eb0: 0a 20 20 73 65 74 20 6c 65 6e 20 5b 65 78 70 72  .  set len [expr
0ec0: 20 69 6e 74 28 72 61 6e 64 28 29 2a 33 29 2b 32   int(rand()*3)+2
0ed0: 5d 0a 20 20 73 65 74 20 20 20 20 77 6f 72 64 20  ].  set    word 
0ee0: 5b 6c 69 6e 64 65 78 20 24 6c 43 68 61 72 20 5b  [lindex $lChar [
0ef0: 65 78 70 72 20 69 6e 74 28 72 61 6e 64 28 29 2a  expr int(rand()*
0f00: 32 36 29 5d 5d 0a 20 20 61 70 70 65 6e 64 20 77  26)]].  append w
0f10: 6f 72 64 20 5b 6c 69 6e 64 65 78 20 24 6c 43 68  ord [lindex $lCh
0f20: 61 72 20 5b 65 78 70 72 20 69 6e 74 28 72 61 6e  ar [expr int(ran
0f30: 64 28 29 2a 32 36 29 5d 5d 0a 20 20 69 66 20 7b  d()*26)]].  if {
0f40: 24 6c 65 6e 3e 32 7d 20 7b 20 61 70 70 65 6e 64  $len>2} { append
0f50: 20 77 6f 72 64 20 5b 6c 69 6e 64 65 78 20 24 6c   word [lindex $l
0f60: 43 68 61 72 20 5b 65 78 70 72 20 69 6e 74 28 72  Char [expr int(r
0f70: 61 6e 64 28 29 2a 32 36 29 5d 5d 20 7d 0a 20 20  and()*26)]] }.  
0f80: 69 66 20 7b 24 6c 65 6e 3e 33 7d 20 7b 20 61 70  if {$len>3} { ap
0f90: 70 65 6e 64 20 77 6f 72 64 20 5b 6c 69 6e 64 65  pend word [linde
0fa0: 78 20 24 6c 43 68 61 72 20 5b 65 78 70 72 20 69  x $lChar [expr i
0fb0: 6e 74 28 72 61 6e 64 28 29 2a 32 36 29 5d 5d 20  nt(rand()*26)]] 
0fc0: 7d 0a 20 20 6c 61 70 70 65 6e 64 20 6c 56 6f 63  }.  lappend lVoc
0fd0: 61 62 20 24 77 6f 72 64 0a 7d 0a 0a 70 72 6f 63  ab $word.}..proc
0fe0: 20 72 61 6e 64 6f 6d 5f 74 65 72 6d 20 7b 7d 20   random_term {} 
0ff0: 7b 0a 20 20 6c 69 6e 64 65 78 20 24 3a 3a 6c 56  {.  lindex $::lV
1000: 6f 63 61 62 20 5b 65 78 70 72 20 7b 69 6e 74 28  ocab [expr {int(
1010: 72 61 6e 64 28 29 2a 24 3a 3a 6e 56 6f 63 61 62  rand()*$::nVocab
1020: 29 7d 5d 0a 7d 0a 0a 23 20 52 65 74 75 72 6e 20  )}].}..# Return 
1030: 61 20 64 6f 63 75 6d 65 6e 74 20 63 6f 6e 73 69  a document consi
1040: 73 74 69 6e 67 20 6f 66 20 24 6e 57 6f 72 64 20  sting of $nWord 
1050: 61 72 62 69 74 72 61 72 69 6c 79 20 73 65 6c 65  arbitrarily sele
1060: 63 74 65 64 20 74 65 72 6d 73 0a 23 20 66 72 6f  cted terms.# fro
1070: 6d 20 74 68 65 20 24 3a 3a 6c 56 6f 63 61 62 20  m the $::lVocab 
1080: 6c 69 73 74 2e 0a 23 0a 70 72 6f 63 20 67 65 6e  list..#.proc gen
1090: 65 72 61 74 65 5f 64 6f 63 20 7b 6e 57 6f 72 64  erate_doc {nWord
10a0: 7d 20 7b 0a 20 20 73 65 74 20 64 6f 63 20 5b 6c  } {.  set doc [l
10b0: 69 73 74 5d 0a 20 20 66 6f 72 20 7b 73 65 74 20  ist].  for {set 
10c0: 69 20 30 7d 20 7b 24 69 20 3c 20 24 6e 57 6f 72  i 0} {$i < $nWor
10d0: 64 7d 20 7b 69 6e 63 72 20 69 7d 20 7b 0a 20 20  d} {incr i} {.  
10e0: 20 20 6c 61 70 70 65 6e 64 20 64 6f 63 20 5b 72    lappend doc [r
10f0: 61 6e 64 6f 6d 5f 74 65 72 6d 5d 0a 20 20 7d 0a  andom_term].  }.
1100: 20 20 72 65 74 75 72 6e 20 24 64 6f 63 0a 7d 0a    return $doc.}.
1110: 0a 0a 0a 23 20 50 72 69 6d 69 74 69 76 65 73 20  ...# Primitives 
1120: 74 6f 20 75 70 64 61 74 65 20 74 68 65 20 74 61  to update the ta
1130: 62 6c 65 2e 0a 23 0a 75 6e 73 65 74 20 2d 6e 6f  ble..#.unset -no
1140: 63 6f 6d 70 6c 61 69 6e 20 74 31 0a 70 72 6f 63  complain t1.proc
1150: 20 69 6e 73 65 72 74 5f 72 6f 77 20 7b 72 6f 77   insert_row {row
1160: 69 64 7d 20 7b 0a 20 20 73 65 74 20 61 20 5b 67  id} {.  set a [g
1170: 65 6e 65 72 61 74 65 5f 64 6f 63 20 5b 65 78 70  enerate_doc [exp
1180: 72 20 69 6e 74 28 28 72 61 6e 64 28 29 2a 31 30  r int((rand()*10
1190: 30 29 29 5d 5d 0a 20 20 73 65 74 20 62 20 5b 67  0))]].  set b [g
11a0: 65 6e 65 72 61 74 65 5f 64 6f 63 20 5b 65 78 70  enerate_doc [exp
11b0: 72 20 69 6e 74 28 28 72 61 6e 64 28 29 2a 31 30  r int((rand()*10
11c0: 30 29 29 5d 5d 0a 20 20 73 65 74 20 63 20 5b 67  0))]].  set c [g
11d0: 65 6e 65 72 61 74 65 5f 64 6f 63 20 5b 65 78 70  enerate_doc [exp
11e0: 72 20 69 6e 74 28 28 72 61 6e 64 28 29 2a 31 30  r int((rand()*10
11f0: 30 29 29 5d 5d 0a 20 20 65 78 65 63 73 71 6c 20  0))]].  execsql 
1200: 7b 20 49 4e 53 45 52 54 20 49 4e 54 4f 20 74 31  { INSERT INTO t1
1210: 28 64 6f 63 69 64 2c 20 61 2c 20 62 2c 20 63 29  (docid, a, b, c)
1220: 20 56 41 4c 55 45 53 28 24 72 6f 77 69 64 2c 20   VALUES($rowid, 
1230: 24 61 2c 20 24 62 2c 20 24 63 29 20 7d 0a 20 20  $a, $b, $c) }.  
1240: 73 65 74 20 3a 3a 74 31 28 24 72 6f 77 69 64 29  set ::t1($rowid)
1250: 20 5b 6c 69 73 74 20 24 61 20 24 62 20 24 63 5d   [list $a $b $c]
1260: 0a 7d 0a 70 72 6f 63 20 64 65 6c 65 74 65 5f 72  .}.proc delete_r
1270: 6f 77 20 7b 72 6f 77 69 64 7d 20 7b 0a 20 20 65  ow {rowid} {.  e
1280: 78 65 63 73 71 6c 20 7b 20 44 45 4c 45 54 45 20  xecsql { DELETE 
1290: 46 52 4f 4d 20 74 31 20 57 48 45 52 45 20 72 6f  FROM t1 WHERE ro
12a0: 77 69 64 20 3d 20 24 72 6f 77 69 64 20 7d 0a 20  wid = $rowid }. 
12b0: 20 63 61 74 63 68 20 7b 75 6e 73 65 74 20 3a 3a   catch {unset ::
12c0: 74 31 28 24 72 6f 77 69 64 29 7d 0a 7d 0a 70 72  t1($rowid)}.}.pr
12d0: 6f 63 20 75 70 64 61 74 65 5f 72 6f 77 20 7b 72  oc update_row {r
12e0: 6f 77 69 64 7d 20 7b 0a 20 20 73 65 74 20 63 6f  owid} {.  set co
12f0: 6c 73 20 7b 61 20 62 20 63 7d 0a 20 20 73 65 74  ls {a b c}.  set
1300: 20 69 43 6f 6c 20 5b 65 78 70 72 20 69 6e 74 28   iCol [expr int(
1310: 72 61 6e 64 28 29 2a 33 29 5d 0a 20 20 73 65 74  rand()*3)].  set
1320: 20 64 6f 63 20 20 5b 67 65 6e 65 72 61 74 65 5f   doc  [generate_
1330: 64 6f 63 20 5b 65 78 70 72 20 69 6e 74 28 28 72  doc [expr int((r
1340: 61 6e 64 28 29 2a 31 30 30 29 29 5d 5d 0a 20 20  and()*100))]].  
1350: 6c 73 65 74 20 3a 3a 74 31 28 24 72 6f 77 69 64  lset ::t1($rowid
1360: 29 20 24 69 43 6f 6c 20 24 64 6f 63 0a 20 20 65  ) $iCol $doc.  e
1370: 78 65 63 73 71 6c 20 22 55 50 44 41 54 45 20 74  xecsql "UPDATE t
1380: 31 20 53 45 54 20 5b 6c 69 6e 64 65 78 20 24 63  1 SET [lindex $c
1390: 6f 6c 73 20 24 69 43 6f 6c 5d 20 3d 20 5c 24 64  ols $iCol] = \$d
13a0: 6f 63 20 57 48 45 52 45 20 72 6f 77 69 64 20 3d  oc WHERE rowid =
13b0: 20 5c 24 72 6f 77 69 64 22 0a 7d 0a 0a 70 72 6f   \$rowid".}..pro
13c0: 63 20 73 69 6d 70 6c 65 5f 70 68 72 61 73 65 20  c simple_phrase 
13d0: 7b 7a 50 72 65 66 69 78 7d 20 7b 0a 20 20 73 65  {zPrefix} {.  se
13e0: 74 20 72 65 74 20 5b 6c 69 73 74 5d 0a 0a 20 20  t ret [list]..  
13f0: 73 65 74 20 72 65 67 20 5b 73 74 72 69 6e 67 20  set reg [string 
1400: 6d 61 70 20 7b 2a 20 7b 5b 5e 20 5d 2a 7d 7d 20  map {* {[^ ]*}} 
1410: 24 7a 50 72 65 66 69 78 5d 0a 20 20 73 65 74 20  $zPrefix].  set 
1420: 72 65 67 20 22 20 24 72 65 67 20 22 0a 0a 20 20  reg " $reg "..  
1430: 66 6f 72 65 61 63 68 20 6b 65 79 20 5b 6c 73 6f  foreach key [lso
1440: 72 74 20 2d 69 6e 74 65 67 65 72 20 5b 61 72 72  rt -integer [arr
1450: 61 79 20 6e 61 6d 65 73 20 3a 3a 74 31 5d 5d 20  ay names ::t1]] 
1460: 7b 0a 20 20 20 20 73 65 74 20 76 61 6c 75 65 20  {.    set value 
1470: 24 3a 3a 74 31 28 24 6b 65 79 29 0a 20 20 20 20  $::t1($key).    
1480: 73 65 74 20 63 6e 74 20 5b 6c 69 73 74 5d 0a 20  set cnt [list]. 
1490: 20 20 20 66 6f 72 65 61 63 68 20 63 6f 6c 20 24     foreach col $
14a0: 76 61 6c 75 65 20 7b 0a 20 20 20 20 20 20 69 66  value {.      if
14b0: 20 7b 5b 72 65 67 65 78 70 20 24 72 65 67 20 22   {[regexp $reg "
14c0: 20 24 63 6f 6c 20 22 5d 7d 20 7b 20 6c 61 70 70   $col "]} { lapp
14d0: 65 6e 64 20 72 65 74 20 24 6b 65 79 20 3b 20 62  end ret $key ; b
14e0: 72 65 61 6b 20 7d 0a 20 20 20 20 7d 0a 20 20 7d  reak }.    }.  }
14f0: 0a 0a 20 20 23 6c 73 6f 72 74 20 2d 75 6e 69 71  ..  #lsort -uniq
1500: 20 2d 69 6e 74 65 67 65 72 20 24 72 65 74 0a 20   -integer $ret. 
1510: 20 73 65 74 20 72 65 74 0a 7d 0a 0a 23 20 54 68   set ret.}..# Th
1520: 69 73 20 5b 70 72 6f 63 5d 20 69 73 20 75 73 65  is [proc] is use
1530: 64 20 74 6f 20 74 65 73 74 20 74 68 65 20 46 54  d to test the FT
1540: 53 33 20 6d 61 74 63 68 69 6e 66 6f 28 29 20 66  S3 matchinfo() f
1550: 75 6e 63 74 69 6f 6e 2e 0a 23 20 0a 70 72 6f 63  unction..# .proc
1560: 20 73 69 6d 70 6c 65 5f 74 6f 6b 65 6e 5f 6d 61   simple_token_ma
1570: 74 63 68 69 6e 66 6f 20 7b 7a 54 6f 6b 65 6e 7d  tchinfo {zToken}
1580: 20 7b 0a 0a 20 20 73 65 74 20 6e 44 6f 63 28 30   {..  set nDoc(0
1590: 29 20 30 0a 20 20 73 65 74 20 6e 44 6f 63 28 31  ) 0.  set nDoc(1
15a0: 29 20 30 0a 20 20 73 65 74 20 6e 44 6f 63 28 32  ) 0.  set nDoc(2
15b0: 29 20 30 0a 20 20 73 65 74 20 6e 48 69 74 28 30  ) 0.  set nHit(0
15c0: 29 20 30 0a 20 20 73 65 74 20 6e 48 69 74 28 31  ) 0.  set nHit(1
15d0: 29 20 30 0a 20 20 73 65 74 20 6e 48 69 74 28 32  ) 0.  set nHit(2
15e0: 29 20 30 0a 0a 0a 20 20 66 6f 72 65 61 63 68 20  ) 0...  foreach 
15f0: 6b 65 79 20 5b 61 72 72 61 79 20 6e 61 6d 65 73  key [array names
1600: 20 3a 3a 74 31 5d 20 7b 0a 20 20 20 20 73 65 74   ::t1] {.    set
1610: 20 76 61 6c 75 65 20 24 3a 3a 74 31 28 24 6b 65   value $::t1($ke
1620: 79 29 0a 20 20 20 20 73 65 74 20 61 28 24 6b 65  y).    set a($ke
1630: 79 29 20 5b 6c 69 73 74 5d 0a 20 20 20 20 66 6f  y) [list].    fo
1640: 72 65 61 63 68 20 69 20 7b 30 20 31 20 32 7d 20  reach i {0 1 2} 
1650: 63 6f 6c 20 24 76 61 6c 75 65 20 7b 0a 20 20 20  col $value {.   
1660: 20 20 20 73 65 74 20 68 69 74 20 5b 6c 6c 65 6e     set hit [llen
1670: 67 74 68 20 5b 6c 73 65 61 72 63 68 20 2d 61 6c  gth [lsearch -al
1680: 6c 20 24 63 6f 6c 20 24 7a 54 6f 6b 65 6e 5d 5d  l $col $zToken]]
1690: 0a 20 20 20 20 20 20 6c 61 70 70 65 6e 64 20 61  .      lappend a
16a0: 28 24 6b 65 79 29 20 24 68 69 74 0a 20 20 20 20  ($key) $hit.    
16b0: 20 20 69 6e 63 72 20 6e 48 69 74 28 24 69 29 20    incr nHit($i) 
16c0: 24 68 69 74 0a 20 20 20 20 20 20 69 66 20 7b 24  $hit.      if {$
16d0: 68 69 74 3e 30 7d 20 7b 20 69 6e 63 72 20 6e 44  hit>0} { incr nD
16e0: 6f 63 28 24 69 29 20 7d 0a 20 20 20 20 7d 0a 20  oc($i) }.    }. 
16f0: 20 7d 0a 0a 20 20 73 65 74 20 72 65 74 20 5b 6c   }..  set ret [l
1700: 69 73 74 5d 0a 20 20 66 6f 72 65 61 63 68 20 64  ist].  foreach d
1710: 6f 63 69 64 20 5b 6c 73 6f 72 74 20 2d 69 6e 74  ocid [lsort -int
1720: 65 67 65 72 20 5b 61 72 72 61 79 20 6e 61 6d 65  eger [array name
1730: 73 20 61 5d 5d 20 7b 0a 20 20 20 20 69 66 20 7b  s a]] {.    if {
1740: 20 5b 6c 69 6e 64 65 78 20 5b 6c 73 6f 72 74 20   [lindex [lsort 
1750: 2d 69 6e 74 65 67 65 72 20 24 61 28 24 64 6f 63  -integer $a($doc
1760: 69 64 29 5d 20 65 6e 64 5d 20 7d 20 7b 0a 20 20  id)] end] } {.  
1770: 20 20 20 20 73 65 74 20 6d 61 74 63 68 69 6e 66      set matchinf
1780: 6f 20 5b 6c 69 73 74 20 31 20 33 5d 0a 20 20 20  o [list 1 3].   
1790: 20 20 20 66 6f 72 65 61 63 68 20 69 20 7b 30 20     foreach i {0 
17a0: 31 20 32 7d 20 68 69 74 20 24 61 28 24 64 6f 63  1 2} hit $a($doc
17b0: 69 64 29 20 7b 0a 20 20 20 20 20 20 20 20 6c 61  id) {.        la
17c0: 70 70 65 6e 64 20 6d 61 74 63 68 69 6e 66 6f 20  ppend matchinfo 
17d0: 24 68 69 74 20 24 6e 48 69 74 28 24 69 29 20 24  $hit $nHit($i) $
17e0: 6e 44 6f 63 28 24 69 29 0a 20 20 20 20 20 20 7d  nDoc($i).      }
17f0: 0a 20 20 20 20 20 20 6c 61 70 70 65 6e 64 20 72  .      lappend r
1800: 65 74 20 24 64 6f 63 69 64 20 24 6d 61 74 63 68  et $docid $match
1810: 69 6e 66 6f 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a  info.    }.  }..
1820: 20 20 73 65 74 20 72 65 74 0a 7d 20 0a 0a 70 72    set ret.} ..pr
1830: 6f 63 20 73 69 6d 70 6c 65 5f 6e 65 61 72 20 7b  oc simple_near {
1840: 74 65 72 6d 6c 69 73 74 20 6e 4e 65 61 72 7d 20  termlist nNear} 
1850: 7b 0a 20 20 73 65 74 20 72 65 74 20 5b 6c 69 73  {.  set ret [lis
1860: 74 5d 0a 0a 20 20 66 6f 72 65 61 63 68 20 7b 6b  t]..  foreach {k
1870: 65 79 20 76 61 6c 75 65 7d 20 5b 61 72 72 61 79  ey value} [array
1880: 20 67 65 74 20 3a 3a 74 31 5d 20 7b 0a 20 20 20   get ::t1] {.   
1890: 20 66 6f 72 65 61 63 68 20 76 20 24 76 61 6c 75   foreach v $valu
18a0: 65 20 7b 0a 0a 20 20 20 20 20 20 73 65 74 20 6c  e {..      set l
18b0: 20 5b 6c 73 65 61 72 63 68 20 2d 65 78 61 63 74   [lsearch -exact
18c0: 20 2d 61 6c 6c 20 24 76 20 5b 6c 69 6e 64 65 78   -all $v [lindex
18d0: 20 24 74 65 72 6d 6c 69 73 74 20 30 5d 5d 0a 20   $termlist 0]]. 
18e0: 20 20 20 20 20 66 6f 72 65 61 63 68 20 54 20 5b       foreach T [
18f0: 6c 72 61 6e 67 65 20 24 74 65 72 6d 6c 69 73 74  lrange $termlist
1900: 20 31 20 65 6e 64 5d 20 7b 0a 20 20 20 20 20 20   1 end] {.      
1910: 20 20 73 65 74 20 6c 32 20 5b 6c 69 73 74 5d 0a    set l2 [list].
1920: 20 20 20 20 20 20 20 20 66 6f 72 65 61 63 68 20          foreach 
1930: 69 20 24 6c 20 7b 0a 20 20 20 20 20 20 20 20 20  i $l {.         
1940: 20 73 65 74 20 69 53 74 61 72 74 20 5b 65 78 70   set iStart [exp
1950: 72 20 24 69 20 2d 20 24 6e 4e 65 61 72 20 2d 20  r $i - $nNear - 
1960: 31 5d 0a 20 20 20 20 20 20 20 20 20 20 73 65 74  1].          set
1970: 20 69 45 6e 64 20 5b 65 78 70 72 20 24 69 20 2b   iEnd [expr $i +
1980: 20 24 6e 4e 65 61 72 20 2b 20 31 5d 0a 20 20 20   $nNear + 1].   
1990: 20 20 20 20 20 20 20 69 66 20 7b 24 69 53 74 61         if {$iSta
19a0: 72 74 20 3c 20 30 7d 20 7b 73 65 74 20 69 53 74  rt < 0} {set iSt
19b0: 61 72 74 20 30 7d 0a 20 20 20 20 20 20 20 20 20  art 0}.         
19c0: 20 66 6f 72 65 61 63 68 20 69 32 20 5b 6c 73 65   foreach i2 [lse
19d0: 61 72 63 68 20 2d 65 78 61 63 74 20 2d 61 6c 6c  arch -exact -all
19e0: 20 5b 6c 72 61 6e 67 65 20 24 76 20 24 69 53 74   [lrange $v $iSt
19f0: 61 72 74 20 24 69 45 6e 64 5d 20 24 54 5d 20 7b  art $iEnd] $T] {
1a00: 0a 20 20 20 20 20 20 20 20 20 20 20 20 69 6e 63  .            inc
1a10: 72 20 69 32 20 24 69 53 74 61 72 74 0a 20 20 20  r i2 $iStart.   
1a20: 20 20 20 20 20 20 20 20 20 69 66 20 7b 24 69 32           if {$i2
1a30: 20 21 3d 20 24 69 7d 20 7b 20 6c 61 70 70 65 6e   != $i} { lappen
1a40: 64 20 6c 32 20 24 69 32 20 7d 20 0a 20 20 20 20  d l2 $i2 } .    
1a50: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20        }.        
1a60: 7d 0a 20 20 20 20 20 20 20 20 73 65 74 20 6c 20  }.        set l 
1a70: 5b 6c 73 6f 72 74 20 2d 75 6e 69 71 20 2d 69 6e  [lsort -uniq -in
1a80: 74 65 67 65 72 20 24 6c 32 5d 0a 20 20 20 20 20  teger $l2].     
1a90: 20 7d 0a 0a 20 20 20 20 20 20 69 66 20 7b 5b 6c   }..      if {[l
1aa0: 6c 65 6e 67 74 68 20 24 6c 5d 7d 20 7b 0a 23 70  length $l]} {.#p
1ab0: 75 74 73 20 22 4d 41 54 43 48 28 24 6b 65 79 29  uts "MATCH($key)
1ac0: 3a 20 24 76 22 0a 20 20 20 20 20 20 20 20 6c 61  : $v".        la
1ad0: 70 70 65 6e 64 20 72 65 74 20 24 6b 65 79 0a 20  ppend ret $key. 
1ae0: 20 20 20 20 20 7d 20 0a 20 20 20 20 7d 0a 20 20       } .    }.  
1af0: 7d 0a 0a 20 20 6c 73 6f 72 74 20 2d 75 6e 69 71  }..  lsort -uniq
1b00: 75 65 20 2d 69 6e 74 65 67 65 72 20 24 72 65 74  ue -integer $ret
1b10: 0a 7d 0a 0a 23 20 54 68 65 20 66 6f 6c 6c 6f 77  .}..# The follow
1b20: 69 6e 67 20 74 68 72 65 65 20 70 72 6f 63 73 3a  ing three procs:
1b30: 0a 23 20 0a 23 20 20 20 73 65 74 75 70 5f 6e 6f  .# .#   setup_no
1b40: 74 20 41 20 42 0a 23 20 20 20 73 65 74 75 70 5f  t A B.#   setup_
1b50: 6f 72 20 20 41 20 42 0a 23 20 20 20 73 65 74 75  or  A B.#   setu
1b60: 70 5f 61 6e 64 20 41 20 42 0a 23 0a 23 20 65 61  p_and A B.#.# ea
1b70: 63 68 20 74 61 6b 65 20 74 77 6f 20 61 72 67 75  ch take two argu
1b80: 6d 65 6e 74 73 2e 20 42 6f 74 68 20 61 72 67 75  ments. Both argu
1b90: 6d 65 6e 74 73 20 6d 75 73 74 20 62 65 20 6c 69  ments must be li
1ba0: 73 74 73 20 6f 66 20 69 6e 74 65 67 65 72 20 76  sts of integer v
1bb0: 61 6c 75 65 73 0a 23 20 73 6f 72 74 65 64 20 62  alues.# sorted b
1bc0: 79 20 76 61 6c 75 65 2e 20 54 68 65 20 72 65 74  y value. The ret
1bd0: 75 72 6e 20 76 61 6c 75 65 20 69 73 20 74 68 65  urn value is the
1be0: 20 6c 69 73 74 20 70 72 6f 64 75 63 65 64 20 62   list produced b
1bf0: 79 20 65 76 61 6c 75 61 74 69 6e 67 0a 23 20 74  y evaluating.# t
1c00: 68 65 20 65 71 75 69 76 61 6c 65 6e 74 20 6f 66  he equivalent of
1c10: 20 22 41 20 6f 70 20 42 22 2c 20 77 68 65 72 65   "A op B", where
1c20: 20 6f 70 20 69 73 20 74 68 65 20 46 54 53 33 20   op is the FTS3 
1c30: 6f 70 65 72 61 74 6f 72 20 4e 4f 54 2c 20 4f 52  operator NOT, OR
1c40: 20 6f 72 0a 23 20 41 4e 44 2e 0a 23 0a 70 72 6f   or.# AND..#.pro
1c50: 63 20 73 65 74 6f 70 5f 6e 6f 74 20 7b 41 20 42  c setop_not {A B
1c60: 7d 20 7b 0a 20 20 66 6f 72 65 61 63 68 20 62 20  } {.  foreach b 
1c70: 24 42 20 7b 20 73 65 74 20 6e 28 24 62 29 20 7b  $B { set n($b) {
1c80: 7d 20 7d 0a 20 20 73 65 74 20 72 65 74 20 5b 6c  } }.  set ret [l
1c90: 69 73 74 5d 0a 20 20 66 6f 72 65 61 63 68 20 61  ist].  foreach a
1ca0: 20 24 41 20 7b 20 69 66 20 7b 21 5b 69 6e 66 6f   $A { if {![info
1cb0: 20 65 78 69 73 74 73 20 6e 28 24 61 29 5d 7d 20   exists n($a)]} 
1cc0: 7b 6c 61 70 70 65 6e 64 20 72 65 74 20 24 61 7d  {lappend ret $a}
1cd0: 20 7d 0a 20 20 72 65 74 75 72 6e 20 24 72 65 74   }.  return $ret
1ce0: 0a 7d 0a 70 72 6f 63 20 73 65 74 6f 70 5f 6f 72  .}.proc setop_or
1cf0: 20 7b 41 20 42 7d 20 7b 0a 20 20 6c 73 6f 72 74   {A B} {.  lsort
1d00: 20 2d 69 6e 74 65 67 65 72 20 2d 75 6e 69 71 20   -integer -uniq 
1d10: 5b 63 6f 6e 63 61 74 20 24 41 20 24 42 5d 0a 7d  [concat $A $B].}
1d20: 0a 70 72 6f 63 20 73 65 74 6f 70 5f 61 6e 64 20  .proc setop_and 
1d30: 7b 41 20 42 7d 20 7b 0a 20 20 66 6f 72 65 61 63  {A B} {.  foreac
1d40: 68 20 62 20 24 42 20 7b 20 73 65 74 20 6e 28 24  h b $B { set n($
1d50: 62 29 20 7b 7d 20 7d 0a 20 20 73 65 74 20 72 65  b) {} }.  set re
1d60: 74 20 5b 6c 69 73 74 5d 0a 20 20 66 6f 72 65 61  t [list].  forea
1d70: 63 68 20 61 20 24 41 20 7b 20 69 66 20 7b 5b 69  ch a $A { if {[i
1d80: 6e 66 6f 20 65 78 69 73 74 73 20 6e 28 24 61 29  nfo exists n($a)
1d90: 5d 7d 20 7b 6c 61 70 70 65 6e 64 20 72 65 74 20  ]} {lappend ret 
1da0: 24 61 7d 20 7d 0a 20 20 72 65 74 75 72 6e 20 24  $a} }.  return $
1db0: 72 65 74 0a 7d 0a 0a 70 72 6f 63 20 6d 69 74 20  ret.}..proc mit 
1dc0: 7b 62 6c 6f 62 7d 20 7b 0a 20 20 73 65 74 20 73  {blob} {.  set s
1dd0: 63 61 6e 28 6c 69 74 74 6c 65 45 6e 64 69 61 6e  can(littleEndian
1de0: 29 20 69 2a 0a 20 20 73 65 74 20 73 63 61 6e 28  ) i*.  set scan(
1df0: 62 69 67 45 6e 64 69 61 6e 29 20 49 2a 0a 20 20  bigEndian) I*.  
1e00: 62 69 6e 61 72 79 20 73 63 61 6e 20 24 62 6c 6f  binary scan $blo
1e10: 62 20 24 73 63 61 6e 28 24 3a 3a 74 63 6c 5f 70  b $scan($::tcl_p
1e20: 6c 61 74 66 6f 72 6d 28 62 79 74 65 4f 72 64 65  latform(byteOrde
1e30: 72 29 29 20 72 0a 20 20 72 65 74 75 72 6e 20 24  r)) r.  return $
1e40: 72 0a 7d 0a 64 62 20 66 75 6e 63 20 6d 69 74 20  r.}.db func mit 
1e50: 6d 69 74 0a 0a 73 65 74 20 73 71 6c 69 74 65 5f  mit..set sqlite_
1e60: 66 74 73 33 5f 65 6e 61 62 6c 65 5f 70 61 72 65  fts3_enable_pare
1e70: 6e 74 68 65 73 65 73 20 31 0a 0a 66 6f 72 65 61  ntheses 1..forea
1e80: 63 68 20 6e 6f 64 65 73 69 7a 65 20 7b 35 30 20  ch nodesize {50 
1e90: 35 30 30 20 31 30 30 30 20 32 30 30 30 7d 20 7b  500 1000 2000} {
1ea0: 0a 20 20 63 61 74 63 68 20 7b 20 61 72 72 61 79  .  catch { array
1eb0: 20 75 6e 73 65 74 20 3a 3a 74 31 20 7d 0a 0a 20   unset ::t1 }.. 
1ec0: 20 23 20 43 72 65 61 74 65 20 74 68 65 20 46 54   # Create the FT
1ed0: 53 33 20 74 61 62 6c 65 2e 20 50 6f 70 75 6c 61  S3 table. Popula
1ee0: 74 65 20 69 74 20 28 61 6e 64 20 74 68 65 20 54  te it (and the T
1ef0: 63 6c 20 61 72 72 61 79 29 20 77 69 74 68 20 31  cl array) with 1
1f00: 30 30 20 72 6f 77 73 2e 0a 20 20 23 0a 20 20 64  00 rows..  #.  d
1f10: 62 20 74 72 61 6e 73 61 63 74 69 6f 6e 20 7b 0a  b transaction {.
1f20: 20 20 20 20 63 61 74 63 68 73 71 6c 20 7b 20 44      catchsql { D
1f30: 52 4f 50 20 54 41 42 4c 45 20 74 31 20 7d 0a 20  ROP TABLE t1 }. 
1f40: 20 20 20 65 78 65 63 73 71 6c 20 22 43 52 45 41     execsql "CREA
1f50: 54 45 20 56 49 52 54 55 41 4c 20 54 41 42 4c 45  TE VIRTUAL TABLE
1f60: 20 74 31 20 55 53 49 4e 47 20 66 74 73 33 28 61   t1 USING fts3(a
1f70: 2c 20 62 2c 20 63 29 22 0a 20 20 20 20 65 78 65  , b, c)".    exe
1f80: 63 73 71 6c 20 22 49 4e 53 45 52 54 20 49 4e 54  csql "INSERT INT
1f90: 4f 20 74 31 28 74 31 29 20 56 41 4c 55 45 53 28  O t1(t1) VALUES(
1fa0: 27 6e 6f 64 65 73 69 7a 65 3d 24 6e 6f 64 65 73  'nodesize=$nodes
1fb0: 69 7a 65 27 29 22 0a 20 20 20 20 66 6f 72 20 7b  ize')".    for {
1fc0: 73 65 74 20 69 20 30 7d 20 7b 24 69 20 3c 20 31  set i 0} {$i < 1
1fd0: 30 30 7d 20 7b 69 6e 63 72 20 69 7d 20 7b 20 69  00} {incr i} { i
1fe0: 6e 73 65 72 74 5f 72 6f 77 20 24 69 20 7d 0a 20  nsert_row $i }. 
1ff0: 20 7d 0a 20 20 0a 20 20 66 6f 72 20 7b 73 65 74   }.  .  for {set
2000: 20 69 54 65 73 74 20 31 7d 20 7b 24 69 54 65 73   iTest 1} {$iTes
2010: 74 20 3c 3d 20 31 30 30 7d 20 7b 69 6e 63 72 20  t <= 100} {incr 
2020: 69 54 65 73 74 7d 20 7b 0a 20 20 20 20 63 61 74  iTest} {.    cat
2030: 63 68 73 71 6c 20 43 4f 4d 4d 49 54 0a 0a 20 20  chsql COMMIT..  
2040: 20 20 73 65 74 20 44 4f 5f 4d 41 4c 4c 4f 43 5f    set DO_MALLOC_
2050: 54 45 53 54 20 30 0a 20 20 20 20 73 65 74 20 6e  TEST 0.    set n
2060: 52 65 70 20 31 30 0a 20 20 20 20 69 66 20 7b 24  Rep 10.    if {$
2070: 69 54 65 73 74 3d 3d 31 30 30 20 26 26 20 24 6e  iTest==100 && $n
2080: 6f 64 65 73 69 7a 65 3d 3d 35 30 7d 20 7b 20 0a  odesize==50} { .
2090: 20 20 20 20 20 20 73 65 74 20 44 4f 5f 4d 41 4c        set DO_MAL
20a0: 4c 4f 43 5f 54 45 53 54 20 31 20 0a 20 20 20 20  LOC_TEST 1 .    
20b0: 20 20 73 65 74 20 6e 52 65 70 20 32 0a 20 20 20    set nRep 2.   
20c0: 20 7d 0a 20 20 0a 20 20 20 20 23 20 44 65 6c 65   }.  .    # Dele
20d0: 74 65 20 6f 6e 65 20 72 6f 77 2c 20 75 70 64 61  te one row, upda
20e0: 74 65 20 6f 6e 65 20 72 6f 77 20 61 6e 64 20 69  te one row and i
20f0: 6e 73 65 72 74 20 6f 6e 65 20 72 6f 77 2e 0a 20  nsert one row.. 
2100: 20 20 20 23 0a 20 20 20 20 73 65 74 20 72 6f 77     #.    set row
2110: 73 20 5b 61 72 72 61 79 20 6e 61 6d 65 73 20 3a  s [array names :
2120: 3a 74 31 5d 0a 20 20 20 20 73 65 74 20 6e 52 6f  :t1].    set nRo
2130: 77 20 5b 6c 6c 65 6e 67 74 68 20 24 72 6f 77 73  w [llength $rows
2140: 5d 0a 20 20 20 20 73 65 74 20 69 55 70 64 61 74  ].    set iUpdat
2150: 65 20 5b 6c 69 6e 64 65 78 20 24 72 6f 77 73 20  e [lindex $rows 
2160: 5b 65 78 70 72 20 7b 69 6e 74 28 72 61 6e 64 28  [expr {int(rand(
2170: 29 2a 24 6e 52 6f 77 29 7d 5d 5d 0a 20 20 20 20  )*$nRow)}]].    
2180: 73 65 74 20 69 44 65 6c 65 74 65 20 24 69 55 70  set iDelete $iUp
2190: 64 61 74 65 0a 20 20 20 20 77 68 69 6c 65 20 7b  date.    while {
21a0: 24 69 44 65 6c 65 74 65 20 3d 3d 20 24 69 55 70  $iDelete == $iUp
21b0: 64 61 74 65 7d 20 7b 0a 20 20 20 20 20 20 73 65  date} {.      se
21c0: 74 20 69 44 65 6c 65 74 65 20 5b 6c 69 6e 64 65  t iDelete [linde
21d0: 78 20 24 72 6f 77 73 20 5b 65 78 70 72 20 7b 69  x $rows [expr {i
21e0: 6e 74 28 72 61 6e 64 28 29 2a 24 6e 52 6f 77 29  nt(rand()*$nRow)
21f0: 7d 5d 5d 0a 20 20 20 20 7d 0a 20 20 20 20 73 65  }]].    }.    se
2200: 74 20 69 49 6e 73 65 72 74 20 24 69 55 70 64 61  t iInsert $iUpda
2210: 74 65 0a 20 20 20 20 77 68 69 6c 65 20 7b 5b 69  te.    while {[i
2220: 6e 66 6f 20 65 78 69 73 74 73 20 3a 3a 74 31 28  nfo exists ::t1(
2230: 24 69 49 6e 73 65 72 74 29 5d 7d 20 7b 0a 20 20  $iInsert)]} {.  
2240: 20 20 20 20 73 65 74 20 69 49 6e 73 65 72 74 20      set iInsert 
2250: 5b 65 78 70 72 20 7b 69 6e 74 28 72 61 6e 64 28  [expr {int(rand(
2260: 29 2a 31 30 30 30 30 30 30 29 7d 5d 0a 20 20 20  )*1000000)}].   
2270: 20 7d 0a 20 20 20 20 65 78 65 63 73 71 6c 20 42   }.    execsql B
2280: 45 47 49 4e 0a 20 20 20 20 20 20 69 6e 73 65 72  EGIN.      inser
2290: 74 5f 72 6f 77 20 24 69 49 6e 73 65 72 74 0a 20  t_row $iInsert. 
22a0: 20 20 20 20 20 75 70 64 61 74 65 5f 72 6f 77 20       update_row 
22b0: 24 69 55 70 64 61 74 65 0a 20 20 20 20 20 20 64  $iUpdate.      d
22c0: 65 6c 65 74 65 5f 72 6f 77 20 24 69 44 65 6c 65  elete_row $iDele
22d0: 74 65 0a 20 20 20 20 69 66 20 7b 30 3d 3d 28 24  te.    if {0==($
22e0: 69 54 65 73 74 25 32 29 7d 20 7b 20 65 78 65 63  iTest%2)} { exec
22f0: 73 71 6c 20 43 4f 4d 4d 49 54 20 7d 0a 0a 20 20  sql COMMIT }..  
2300: 20 20 69 66 20 7b 30 3d 3d 28 24 69 54 65 73 74    if {0==($iTest
2310: 25 32 29 7d 20 7b 20 0a 20 20 20 20 20 20 64 6f  %2)} { .      do
2320: 5f 74 65 73 74 20 66 74 73 33 72 6e 64 2d 31 2e  _test fts3rnd-1.
2330: 24 6e 6f 64 65 73 69 7a 65 2e 24 69 54 65 73 74  $nodesize.$iTest
2340: 2e 30 20 7b 20 66 74 73 33 5f 69 6e 74 65 67 72  .0 { fts3_integr
2350: 69 74 79 5f 63 68 65 63 6b 20 74 31 20 7d 20 6f  ity_check t1 } o
2360: 6b 20 0a 20 20 20 20 7d 0a 0a 20 20 20 20 23 20  k .    }..    # 
2370: 50 69 63 6b 20 31 30 20 74 65 72 6d 73 20 66 72  Pick 10 terms fr
2380: 6f 6d 20 74 68 65 20 76 6f 63 61 62 75 6c 61 72  om the vocabular
2390: 79 2e 20 43 68 65 63 6b 20 74 68 61 74 20 74 68  y. Check that th
23a0: 65 20 72 65 73 75 6c 74 73 20 6f 66 20 71 75 65  e results of que
23b0: 72 79 69 6e 67 0a 20 20 20 20 23 20 74 68 65 20  rying.    # the 
23c0: 64 61 74 61 62 61 73 65 20 66 6f 72 20 74 68 65  database for the
23d0: 20 73 65 74 20 6f 66 20 64 6f 63 75 6d 65 6e 74   set of document
23e0: 73 20 63 6f 6e 74 61 69 6e 69 6e 67 20 65 61 63  s containing eac
23f0: 68 20 6f 66 20 74 68 65 73 65 20 74 65 72 6d 73  h of these terms
2400: 0a 20 20 20 20 23 20 69 73 20 74 68 65 20 73 61  .    # is the sa
2410: 6d 65 20 61 73 20 74 68 65 20 72 65 73 75 6c 74  me as the result
2420: 20 6f 62 74 61 69 6e 65 64 20 62 79 20 73 63 61   obtained by sca
2430: 6e 6e 69 6e 67 20 74 68 65 20 63 6f 6e 74 65 6e  nning the conten
2440: 74 73 20 6f 66 20 74 68 65 20 54 63 6c 20 0a 20  ts of the Tcl . 
2450: 20 20 20 23 20 61 72 72 61 79 20 66 6f 72 20 65     # array for e
2460: 61 63 68 20 74 65 72 6d 2e 0a 20 20 20 20 23 0a  ach term..    #.
2470: 20 20 20 20 66 6f 72 20 7b 73 65 74 20 69 20 30      for {set i 0
2480: 7d 20 7b 24 69 20 3c 20 31 30 7d 20 7b 69 6e 63  } {$i < 10} {inc
2490: 72 20 69 7d 20 7b 0a 20 20 20 20 20 20 73 65 74  r i} {.      set
24a0: 20 74 65 72 6d 20 5b 72 61 6e 64 6f 6d 5f 74 65   term [random_te
24b0: 72 6d 5d 0a 20 20 20 20 20 20 64 6f 5f 73 65 6c  rm].      do_sel
24c0: 65 63 74 5f 74 65 73 74 20 66 74 73 33 72 6e 64  ect_test fts3rnd
24d0: 2d 31 2e 24 6e 6f 64 65 73 69 7a 65 2e 24 69 54  -1.$nodesize.$iT
24e0: 65 73 74 2e 31 2e 24 69 20 7b 0a 20 20 20 20 20  est.1.$i {.     
24f0: 20 20 20 53 45 4c 45 43 54 20 64 6f 63 69 64 2c     SELECT docid,
2500: 20 6d 69 74 28 6d 61 74 63 68 69 6e 66 6f 28 74   mit(matchinfo(t
2510: 31 29 29 20 46 52 4f 4d 20 74 31 20 57 48 45 52  1)) FROM t1 WHER
2520: 45 20 74 31 20 4d 41 54 43 48 20 24 74 65 72 6d  E t1 MATCH $term
2530: 0a 20 20 20 20 20 20 7d 20 5b 73 69 6d 70 6c 65  .      } [simple
2540: 5f 74 6f 6b 65 6e 5f 6d 61 74 63 68 69 6e 66 6f  _token_matchinfo
2550: 20 24 74 65 72 6d 5d 0a 20 20 20 20 7d 0a 0a 20   $term].    }.. 
2560: 20 20 20 23 20 54 68 69 73 20 74 69 6d 65 2c 20     # This time, 
2570: 75 73 65 20 74 68 65 20 66 69 72 73 74 20 74 77  use the first tw
2580: 6f 20 63 68 61 72 61 63 74 65 72 73 20 6f 66 20  o characters of 
2590: 65 61 63 68 20 74 65 72 6d 20 61 73 20 61 20 74  each term as a t
25a0: 65 72 6d 20 70 72 65 66 69 78 0a 20 20 20 20 23  erm prefix.    #
25b0: 20 74 6f 20 71 75 65 72 79 20 66 6f 72 2e 20 54   to query for. T
25c0: 65 73 74 20 74 68 61 74 20 71 75 65 72 79 69 6e  est that queryin
25d0: 67 20 74 68 65 20 54 63 6c 20 61 72 72 61 79 20  g the Tcl array 
25e0: 70 72 6f 64 75 63 65 73 20 74 68 65 20 73 61 6d  produces the sam
25f0: 65 20 72 65 73 75 6c 74 73 0a 20 20 20 20 23 20  e results.    # 
2600: 61 73 20 71 75 65 72 79 69 6e 67 20 74 68 65 20  as querying the 
2610: 46 54 53 33 20 74 61 62 6c 65 20 66 6f 72 20 74  FTS3 table for t
2620: 68 65 20 70 72 65 66 69 78 2e 0a 20 20 20 20 23  he prefix..    #
2630: 0a 20 20 20 20 66 6f 72 20 7b 73 65 74 20 69 20  .    for {set i 
2640: 30 7d 20 7b 24 69 20 3c 20 24 6e 52 65 70 7d 20  0} {$i < $nRep} 
2650: 7b 69 6e 63 72 20 69 7d 20 7b 0a 20 20 20 20 20  {incr i} {.     
2660: 20 73 65 74 20 70 72 65 66 69 78 20 5b 73 74 72   set prefix [str
2670: 69 6e 67 20 72 61 6e 67 65 20 5b 72 61 6e 64 6f  ing range [rando
2680: 6d 5f 74 65 72 6d 5d 20 30 20 65 6e 64 2d 31 5d  m_term] 0 end-1]
2690: 0a 20 20 20 20 20 20 73 65 74 20 6d 61 74 63 68  .      set match
26a0: 20 22 24 7b 70 72 65 66 69 78 7d 2a 22 0a 20 20   "${prefix}*".  
26b0: 20 20 20 20 64 6f 5f 73 65 6c 65 63 74 5f 74 65      do_select_te
26c0: 73 74 20 66 74 73 33 72 6e 64 2d 31 2e 24 6e 6f  st fts3rnd-1.$no
26d0: 64 65 73 69 7a 65 2e 24 69 54 65 73 74 2e 32 2e  desize.$iTest.2.
26e0: 24 69 20 7b 0a 20 20 20 20 20 20 20 20 53 45 4c  $i {.        SEL
26f0: 45 43 54 20 64 6f 63 69 64 20 46 52 4f 4d 20 74  ECT docid FROM t
2700: 31 20 57 48 45 52 45 20 74 31 20 4d 41 54 43 48  1 WHERE t1 MATCH
2710: 20 24 6d 61 74 63 68 0a 20 20 20 20 20 20 7d 20   $match.      } 
2720: 5b 73 69 6d 70 6c 65 5f 70 68 72 61 73 65 20 24  [simple_phrase $
2730: 6d 61 74 63 68 5d 0a 20 20 20 20 7d 0a 0a 20 20  match].    }..  
2740: 20 20 23 20 53 69 6d 69 6c 61 72 20 74 6f 20 74    # Similar to t
2750: 68 65 20 61 62 6f 76 65 2c 20 65 78 63 65 70 74  he above, except
2760: 20 66 6f 72 20 70 68 72 61 73 65 20 71 75 65 72   for phrase quer
2770: 69 65 73 2e 0a 20 20 20 20 23 0a 20 20 20 20 66  ies..    #.    f
2780: 6f 72 20 7b 73 65 74 20 69 20 30 7d 20 7b 24 69  or {set i 0} {$i
2790: 20 3c 20 24 6e 52 65 70 7d 20 7b 69 6e 63 72 20   < $nRep} {incr 
27a0: 69 7d 20 7b 0a 20 20 20 20 20 20 73 65 74 20 74  i} {.      set t
27b0: 65 72 6d 20 5b 6c 69 73 74 20 5b 72 61 6e 64 6f  erm [list [rando
27c0: 6d 5f 74 65 72 6d 5d 20 5b 72 61 6e 64 6f 6d 5f  m_term] [random_
27d0: 74 65 72 6d 5d 5d 0a 20 20 20 20 20 20 73 65 74  term]].      set
27e0: 20 6d 61 74 63 68 20 22 5c 22 24 74 65 72 6d 5c   match "\"$term\
27f0: 22 22 0a 20 20 20 20 20 20 64 6f 5f 73 65 6c 65  "".      do_sele
2800: 63 74 5f 74 65 73 74 20 66 74 73 33 72 6e 64 2d  ct_test fts3rnd-
2810: 31 2e 24 6e 6f 64 65 73 69 7a 65 2e 24 69 54 65  1.$nodesize.$iTe
2820: 73 74 2e 33 2e 24 69 20 7b 0a 20 20 20 20 20 20  st.3.$i {.      
2830: 20 20 53 45 4c 45 43 54 20 64 6f 63 69 64 20 46    SELECT docid F
2840: 52 4f 4d 20 74 31 20 57 48 45 52 45 20 74 31 20  ROM t1 WHERE t1 
2850: 4d 41 54 43 48 20 24 6d 61 74 63 68 0a 20 20 20  MATCH $match.   
2860: 20 20 20 7d 20 5b 73 69 6d 70 6c 65 5f 70 68 72     } [simple_phr
2870: 61 73 65 20 24 74 65 72 6d 5d 0a 20 20 20 20 7d  ase $term].    }
2880: 0a 0a 20 20 20 20 23 20 54 68 72 65 65 20 77 6f  ..    # Three wo
2890: 72 64 20 70 68 72 61 73 65 73 2e 0a 20 20 20 20  rd phrases..    
28a0: 23 0a 20 20 20 20 66 6f 72 20 7b 73 65 74 20 69  #.    for {set i
28b0: 20 30 7d 20 7b 24 69 20 3c 20 24 6e 52 65 70 7d   0} {$i < $nRep}
28c0: 20 7b 69 6e 63 72 20 69 7d 20 7b 0a 20 20 20 20   {incr i} {.    
28d0: 20 20 73 65 74 20 74 65 72 6d 20 5b 6c 69 73 74    set term [list
28e0: 20 5b 72 61 6e 64 6f 6d 5f 74 65 72 6d 5d 20 5b   [random_term] [
28f0: 72 61 6e 64 6f 6d 5f 74 65 72 6d 5d 20 5b 72 61  random_term] [ra
2900: 6e 64 6f 6d 5f 74 65 72 6d 5d 5d 0a 20 20 20 20  ndom_term]].    
2910: 20 20 73 65 74 20 6d 61 74 63 68 20 22 5c 22 24    set match "\"$
2920: 74 65 72 6d 5c 22 22 0a 20 20 20 20 20 20 64 6f  term\"".      do
2930: 5f 73 65 6c 65 63 74 5f 74 65 73 74 20 66 74 73  _select_test fts
2940: 33 72 6e 64 2d 31 2e 24 6e 6f 64 65 73 69 7a 65  3rnd-1.$nodesize
2950: 2e 24 69 54 65 73 74 2e 34 2e 24 69 20 7b 0a 20  .$iTest.4.$i {. 
2960: 20 20 20 20 20 20 20 53 45 4c 45 43 54 20 64 6f         SELECT do
2970: 63 69 64 20 46 52 4f 4d 20 74 31 20 57 48 45 52  cid FROM t1 WHER
2980: 45 20 74 31 20 4d 41 54 43 48 20 24 6d 61 74 63  E t1 MATCH $matc
2990: 68 0a 20 20 20 20 20 20 7d 20 5b 73 69 6d 70 6c  h.      } [simpl
29a0: 65 5f 70 68 72 61 73 65 20 24 74 65 72 6d 5d 0a  e_phrase $term].
29b0: 20 20 20 20 7d 0a 0a 20 20 20 20 23 20 54 68 72      }..    # Thr
29c0: 65 65 20 77 6f 72 64 20 70 68 72 61 73 65 73 20  ee word phrases 
29d0: 6d 61 64 65 20 75 70 20 6f 66 20 74 65 72 6d 2d  made up of term-
29e0: 70 72 65 66 69 78 65 73 2e 0a 20 20 20 20 23 0a  prefixes..    #.
29f0: 20 20 20 20 66 6f 72 20 7b 73 65 74 20 69 20 30      for {set i 0
2a00: 7d 20 7b 24 69 20 3c 20 24 6e 52 65 70 7d 20 7b  } {$i < $nRep} {
2a10: 69 6e 63 72 20 69 7d 20 7b 0a 20 20 20 20 20 20  incr i} {.      
2a20: 73 65 74 20 20 20 20 71 75 65 72 79 20 22 5b 73  set    query "[s
2a30: 74 72 69 6e 67 20 72 61 6e 67 65 20 5b 72 61 6e  tring range [ran
2a40: 64 6f 6d 5f 74 65 72 6d 5d 20 30 20 65 6e 64 2d  dom_term] 0 end-
2a50: 31 5d 2a 20 22 0a 20 20 20 20 20 20 61 70 70 65  1]* ".      appe
2a60: 6e 64 20 71 75 65 72 79 20 22 5b 73 74 72 69 6e  nd query "[strin
2a70: 67 20 72 61 6e 67 65 20 5b 72 61 6e 64 6f 6d 5f  g range [random_
2a80: 74 65 72 6d 5d 20 30 20 65 6e 64 2d 31 5d 2a 20  term] 0 end-1]* 
2a90: 22 0a 20 20 20 20 20 20 61 70 70 65 6e 64 20 71  ".      append q
2aa0: 75 65 72 79 20 22 5b 73 74 72 69 6e 67 20 72 61  uery "[string ra
2ab0: 6e 67 65 20 5b 72 61 6e 64 6f 6d 5f 74 65 72 6d  nge [random_term
2ac0: 5d 20 30 20 65 6e 64 2d 31 5d 2a 22 0a 0a 20 20  ] 0 end-1]*"..  
2ad0: 20 20 20 20 73 65 74 20 6d 61 74 63 68 20 22 5c      set match "\
2ae0: 22 24 71 75 65 72 79 5c 22 22 0a 20 20 20 20 20  "$query\"".     
2af0: 20 64 6f 5f 73 65 6c 65 63 74 5f 74 65 73 74 20   do_select_test 
2b00: 66 74 73 33 72 6e 64 2d 31 2e 24 6e 6f 64 65 73  fts3rnd-1.$nodes
2b10: 69 7a 65 2e 24 69 54 65 73 74 2e 35 2e 24 69 20  ize.$iTest.5.$i 
2b20: 7b 0a 20 20 20 20 20 20 20 20 53 45 4c 45 43 54  {.        SELECT
2b30: 20 64 6f 63 69 64 20 46 52 4f 4d 20 74 31 20 57   docid FROM t1 W
2b40: 48 45 52 45 20 74 31 20 4d 41 54 43 48 20 24 6d  HERE t1 MATCH $m
2b50: 61 74 63 68 0a 20 20 20 20 20 20 7d 20 5b 73 69  atch.      } [si
2b60: 6d 70 6c 65 5f 70 68 72 61 73 65 20 24 71 75 65  mple_phrase $que
2b70: 72 79 5d 0a 20 20 20 20 7d 0a 0a 20 20 20 20 23  ry].    }..    #
2b80: 20 41 20 4e 45 41 52 20 71 75 65 72 79 20 77 69   A NEAR query wi
2b90: 74 68 20 74 65 72 6d 73 20 61 73 20 74 68 65 20  th terms as the 
2ba0: 61 72 67 75 6d 65 6e 74 73 2e 0a 20 20 20 20 23  arguments..    #
2bb0: 0a 20 20 20 20 66 6f 72 20 7b 73 65 74 20 69 20  .    for {set i 
2bc0: 30 7d 20 7b 24 69 20 3c 20 24 6e 52 65 70 7d 20  0} {$i < $nRep} 
2bd0: 7b 69 6e 63 72 20 69 7d 20 7b 0a 20 20 20 20 20  {incr i} {.     
2be0: 20 73 65 74 20 74 65 72 6d 73 20 5b 6c 69 73 74   set terms [list
2bf0: 20 5b 72 61 6e 64 6f 6d 5f 74 65 72 6d 5d 20 5b   [random_term] [
2c00: 72 61 6e 64 6f 6d 5f 74 65 72 6d 5d 5d 0a 20 20  random_term]].  
2c10: 20 20 20 20 73 65 74 20 6d 61 74 63 68 20 5b 6a      set match [j
2c20: 6f 69 6e 20 24 74 65 72 6d 73 20 22 20 4e 45 41  oin $terms " NEA
2c30: 52 20 22 5d 0a 20 20 20 20 20 20 64 6f 5f 73 65  R "].      do_se
2c40: 6c 65 63 74 5f 74 65 73 74 20 66 74 73 33 72 6e  lect_test fts3rn
2c50: 64 2d 31 2e 24 6e 6f 64 65 73 69 7a 65 2e 24 69  d-1.$nodesize.$i
2c60: 54 65 73 74 2e 36 2e 24 69 20 7b 0a 20 20 20 20  Test.6.$i {.    
2c70: 20 20 20 20 53 45 4c 45 43 54 20 64 6f 63 69 64      SELECT docid
2c80: 20 46 52 4f 4d 20 74 31 20 57 48 45 52 45 20 74   FROM t1 WHERE t
2c90: 31 20 4d 41 54 43 48 20 24 6d 61 74 63 68 20 0a  1 MATCH $match .
2ca0: 20 20 20 20 20 20 7d 20 5b 73 69 6d 70 6c 65 5f        } [simple_
2cb0: 6e 65 61 72 20 24 74 65 72 6d 73 20 31 30 5d 0a  near $terms 10].
2cc0: 20 20 20 20 7d 0a 0a 20 20 20 20 23 20 41 20 33      }..    # A 3
2cd0: 2d 77 61 79 20 4e 45 41 52 20 71 75 65 72 79 20  -way NEAR query 
2ce0: 77 69 74 68 20 74 65 72 6d 73 20 61 73 20 74 68  with terms as th
2cf0: 65 20 61 72 67 75 6d 65 6e 74 73 2e 0a 20 20 20  e arguments..   
2d00: 20 23 0a 20 20 20 20 66 6f 72 20 7b 73 65 74 20   #.    for {set 
2d10: 69 20 30 7d 20 7b 24 69 20 3c 20 24 6e 52 65 70  i 0} {$i < $nRep
2d20: 7d 20 7b 69 6e 63 72 20 69 7d 20 7b 0a 20 20 20  } {incr i} {.   
2d30: 20 20 20 73 65 74 20 74 65 72 6d 73 20 5b 6c 69     set terms [li
2d40: 73 74 20 5b 72 61 6e 64 6f 6d 5f 74 65 72 6d 5d  st [random_term]
2d50: 20 5b 72 61 6e 64 6f 6d 5f 74 65 72 6d 5d 20 5b   [random_term] [
2d60: 72 61 6e 64 6f 6d 5f 74 65 72 6d 5d 5d 0a 20 20  random_term]].  
2d70: 20 20 20 20 73 65 74 20 6e 4e 65 61 72 20 31 31      set nNear 11
2d80: 0a 20 20 20 20 20 20 73 65 74 20 6d 61 74 63 68  .      set match
2d90: 20 5b 6a 6f 69 6e 20 24 74 65 72 6d 73 20 22 20   [join $terms " 
2da0: 4e 45 41 52 2f 24 6e 4e 65 61 72 20 22 5d 0a 20  NEAR/$nNear "]. 
2db0: 20 20 20 20 20 64 6f 5f 73 65 6c 65 63 74 5f 74       do_select_t
2dc0: 65 73 74 20 66 74 73 33 72 6e 64 2d 31 2e 24 6e  est fts3rnd-1.$n
2dd0: 6f 64 65 73 69 7a 65 2e 24 69 54 65 73 74 2e 37  odesize.$iTest.7
2de0: 2e 24 69 20 7b 0a 20 20 20 20 20 20 20 20 53 45  .$i {.        SE
2df0: 4c 45 43 54 20 64 6f 63 69 64 20 46 52 4f 4d 20  LECT docid FROM 
2e00: 74 31 20 57 48 45 52 45 20 74 31 20 4d 41 54 43  t1 WHERE t1 MATC
2e10: 48 20 24 6d 61 74 63 68 0a 20 20 20 20 20 20 7d  H $match.      }
2e20: 20 5b 73 69 6d 70 6c 65 5f 6e 65 61 72 20 24 74   [simple_near $t
2e30: 65 72 6d 73 20 24 6e 4e 65 61 72 5d 0a 20 20 20  erms $nNear].   
2e40: 20 7d 0a 20 20 20 20 0a 20 20 20 20 23 20 53 65   }.    .    # Se
2e50: 74 20 6f 70 65 72 61 74 69 6f 6e 73 20 6f 6e 20  t operations on 
2e60: 73 69 6d 70 6c 65 20 74 65 72 6d 20 71 75 65 72  simple term quer
2e70: 69 65 73 2e 0a 20 20 20 20 23 0a 20 20 20 20 66  ies..    #.    f
2e80: 6f 72 65 61 63 68 20 7b 74 6e 20 6f 70 20 70 72  oreach {tn op pr
2e90: 6f 63 7d 20 7b 0a 20 20 20 20 20 20 38 20 20 4f  oc} {.      8  O
2ea0: 52 20 20 73 65 74 6f 70 5f 6f 72 0a 20 20 20 20  R  setop_or.    
2eb0: 20 20 39 20 20 4e 4f 54 20 73 65 74 6f 70 5f 6e    9  NOT setop_n
2ec0: 6f 74 0a 20 20 20 20 20 20 31 30 20 41 4e 44 20  ot.      10 AND 
2ed0: 73 65 74 6f 70 5f 61 6e 64 0a 20 20 20 20 7d 20  setop_and.    } 
2ee0: 7b 0a 20 20 20 20 20 20 66 6f 72 20 7b 73 65 74  {.      for {set
2ef0: 20 69 20 30 7d 20 7b 24 69 20 3c 20 24 6e 52 65   i 0} {$i < $nRe
2f00: 70 7d 20 7b 69 6e 63 72 20 69 7d 20 7b 0a 20 20  p} {incr i} {.  
2f10: 20 20 20 20 20 20 73 65 74 20 74 65 72 6d 31 20        set term1 
2f20: 5b 72 61 6e 64 6f 6d 5f 74 65 72 6d 5d 0a 20 20  [random_term].  
2f30: 20 20 20 20 20 20 73 65 74 20 74 65 72 6d 32 20        set term2 
2f40: 5b 72 61 6e 64 6f 6d 5f 74 65 72 6d 5d 0a 20 20  [random_term].  
2f50: 20 20 20 20 20 20 73 65 74 20 6d 61 74 63 68 20        set match 
2f60: 22 24 74 65 72 6d 31 20 24 6f 70 20 24 74 65 72  "$term1 $op $ter
2f70: 6d 32 22 0a 20 20 20 20 20 20 20 20 64 6f 5f 73  m2".        do_s
2f80: 65 6c 65 63 74 5f 74 65 73 74 20 66 74 73 33 72  elect_test fts3r
2f90: 6e 64 2d 31 2e 24 6e 6f 64 65 73 69 7a 65 2e 24  nd-1.$nodesize.$
2fa0: 69 54 65 73 74 2e 24 74 6e 2e 24 69 20 7b 0a 20  iTest.$tn.$i {. 
2fb0: 20 20 20 20 20 20 20 20 20 53 45 4c 45 43 54 20           SELECT 
2fc0: 64 6f 63 69 64 20 46 52 4f 4d 20 74 31 20 57 48  docid FROM t1 WH
2fd0: 45 52 45 20 74 31 20 4d 41 54 43 48 20 24 6d 61  ERE t1 MATCH $ma
2fe0: 74 63 68 0a 20 20 20 20 20 20 20 20 7d 20 5b 24  tch.        } [$
2ff0: 70 72 6f 63 20 5b 73 69 6d 70 6c 65 5f 70 68 72  proc [simple_phr
3000: 61 73 65 20 24 74 65 72 6d 31 5d 20 5b 73 69 6d  ase $term1] [sim
3010: 70 6c 65 5f 70 68 72 61 73 65 20 24 74 65 72 6d  ple_phrase $term
3020: 32 5d 5d 0a 20 20 20 20 20 20 7d 0a 20 20 20 20  2]].      }.    
3030: 7d 0a 20 0a 20 20 20 20 23 20 53 65 74 20 6f 70  }. .    # Set op
3040: 65 72 61 74 69 6f 6e 73 20 6f 6e 20 4e 45 41 52  erations on NEAR
3050: 20 71 75 65 72 69 65 73 2e 0a 20 20 20 20 23 0a   queries..    #.
3060: 20 20 20 20 66 6f 72 65 61 63 68 20 7b 74 6e 20      foreach {tn 
3070: 6f 70 20 70 72 6f 63 7d 20 7b 0a 20 20 20 20 20  op proc} {.     
3080: 20 38 20 20 4f 52 20 20 73 65 74 6f 70 5f 6f 72   8  OR  setop_or
3090: 0a 20 20 20 20 20 20 39 20 20 4e 4f 54 20 73 65  .      9  NOT se
30a0: 74 6f 70 5f 6e 6f 74 0a 20 20 20 20 20 20 31 30  top_not.      10
30b0: 20 41 4e 44 20 73 65 74 6f 70 5f 61 6e 64 0a 20   AND setop_and. 
30c0: 20 20 20 7d 20 7b 0a 20 20 20 20 20 20 66 6f 72     } {.      for
30d0: 20 7b 73 65 74 20 69 20 30 7d 20 7b 24 69 20 3c   {set i 0} {$i <
30e0: 20 24 6e 52 65 70 7d 20 7b 69 6e 63 72 20 69 7d   $nRep} {incr i}
30f0: 20 7b 0a 20 20 20 20 20 20 20 20 73 65 74 20 74   {.        set t
3100: 65 72 6d 31 20 5b 72 61 6e 64 6f 6d 5f 74 65 72  erm1 [random_ter
3110: 6d 5d 0a 20 20 20 20 20 20 20 20 73 65 74 20 74  m].        set t
3120: 65 72 6d 32 20 5b 72 61 6e 64 6f 6d 5f 74 65 72  erm2 [random_ter
3130: 6d 5d 0a 20 20 20 20 20 20 20 20 73 65 74 20 74  m].        set t
3140: 65 72 6d 33 20 5b 72 61 6e 64 6f 6d 5f 74 65 72  erm3 [random_ter
3150: 6d 5d 0a 20 20 20 20 20 20 20 20 73 65 74 20 74  m].        set t
3160: 65 72 6d 34 20 5b 72 61 6e 64 6f 6d 5f 74 65 72  erm4 [random_ter
3170: 6d 5d 0a 20 20 20 20 20 20 20 20 73 65 74 20 6d  m].        set m
3180: 61 74 63 68 20 22 24 74 65 72 6d 31 20 4e 45 41  atch "$term1 NEA
3190: 52 20 24 74 65 72 6d 32 20 24 6f 70 20 24 74 65  R $term2 $op $te
31a0: 72 6d 33 20 4e 45 41 52 20 24 74 65 72 6d 34 22  rm3 NEAR $term4"
31b0: 0a 20 20 20 20 20 20 20 20 64 6f 5f 73 65 6c 65  .        do_sele
31c0: 63 74 5f 74 65 73 74 20 66 74 73 33 72 6e 64 2d  ct_test fts3rnd-
31d0: 31 2e 24 6e 6f 64 65 73 69 7a 65 2e 24 69 54 65  1.$nodesize.$iTe
31e0: 73 74 2e 24 74 6e 2e 24 69 20 7b 0a 20 20 20 20  st.$tn.$i {.    
31f0: 20 20 20 20 20 20 53 45 4c 45 43 54 20 64 6f 63        SELECT doc
3200: 69 64 20 46 52 4f 4d 20 74 31 20 57 48 45 52 45  id FROM t1 WHERE
3210: 20 74 31 20 4d 41 54 43 48 20 24 6d 61 74 63 68   t1 MATCH $match
3220: 0a 20 20 20 20 20 20 20 20 7d 20 5b 24 70 72 6f  .        } [$pro
3230: 63 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  c               
3240: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3250: 20 20 20 5c 0a 20 20 20 20 20 20 20 20 20 20 20     \.           
3260: 20 5b 73 69 6d 70 6c 65 5f 6e 65 61 72 20 5b 6c   [simple_near [l
3270: 69 73 74 20 24 74 65 72 6d 31 20 24 74 65 72 6d  ist $term1 $term
3280: 32 5d 20 31 30 5d 20 5c 0a 20 20 20 20 20 20 20  2] 10] \.       
3290: 20 20 20 20 20 5b 73 69 6d 70 6c 65 5f 6e 65 61       [simple_nea
32a0: 72 20 5b 6c 69 73 74 20 24 74 65 72 6d 33 20 24  r [list $term3 $
32b0: 74 65 72 6d 34 5d 20 31 30 5d 0a 20 20 20 20 20  term4] 10].     
32c0: 20 20 20 20 20 5d 0a 20 20 20 20 20 20 7d 0a 20       ].      }. 
32d0: 20 20 20 7d 0a 0a 20 20 20 20 63 61 74 63 68 73     }..    catchs
32e0: 71 6c 20 43 4f 4d 4d 49 54 0a 20 20 7d 0a 7d 0a  ql COMMIT.  }.}.
32f0: 0a 66 69 6e 69 73 68 5f 74 65 73 74 0a           .finish_test.