/ Hex Artifact Content
Login

Artifact 3efba544818662a02e8e5ebd73d57cff6182b2dd:


0000: 2f 2a 0a 2a 2a 20 32 30 31 34 20 4a 75 6e 20 30  /*.** 2014 Jun 0
0010: 39 0a 2a 2a 0a 2a 2a 20 54 68 65 20 61 75 74 68  9.**.** The auth
0020: 6f 72 20 64 69 73 63 6c 61 69 6d 73 20 63 6f 70  or disclaims cop
0030: 79 72 69 67 68 74 20 74 6f 20 74 68 69 73 20 73  yright to this s
0040: 6f 75 72 63 65 20 63 6f 64 65 2e 20 20 49 6e 20  ource code.  In 
0050: 70 6c 61 63 65 20 6f 66 0a 2a 2a 20 61 20 6c 65  place of.** a le
0060: 67 61 6c 20 6e 6f 74 69 63 65 2c 20 68 65 72 65  gal notice, here
0070: 20 69 73 20 61 20 62 6c 65 73 73 69 6e 67 3a 0a   is a blessing:.
0080: 2a 2a 0a 2a 2a 20 20 20 20 4d 61 79 20 79 6f 75  **.**    May you
0090: 20 64 6f 20 67 6f 6f 64 20 61 6e 64 20 6e 6f 74   do good and not
00a0: 20 65 76 69 6c 2e 0a 2a 2a 20 20 20 20 4d 61 79   evil..**    May
00b0: 20 79 6f 75 20 66 69 6e 64 20 66 6f 72 67 69 76   you find forgiv
00c0: 65 6e 65 73 73 20 66 6f 72 20 79 6f 75 72 73 65  eness for yourse
00d0: 6c 66 20 61 6e 64 20 66 6f 72 67 69 76 65 20 6f  lf and forgive o
00e0: 74 68 65 72 73 2e 0a 2a 2a 20 20 20 20 4d 61 79  thers..**    May
00f0: 20 79 6f 75 20 73 68 61 72 65 20 66 72 65 65 6c   you share freel
0100: 79 2c 20 6e 65 76 65 72 20 74 61 6b 69 6e 67 20  y, never taking 
0110: 6d 6f 72 65 20 74 68 61 6e 20 79 6f 75 20 67 69  more than you gi
0120: 76 65 2e 0a 2a 2a 0a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ve..**.*********
0130: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0140: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0150: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0160: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0170: 2a 2a 2a 2a 2a 0a 2a 2a 0a 2a 2a 20 54 68 69 73  *****.**.** This
0180: 20 69 73 20 61 6e 20 53 51 4c 69 74 65 20 6d 6f   is an SQLite mo
0190: 64 75 6c 65 20 69 6d 70 6c 65 6d 65 6e 74 69 6e  dule implementin
01a0: 67 20 66 75 6c 6c 2d 74 65 78 74 20 73 65 61 72  g full-text sear
01b0: 63 68 2e 0a 2a 2f 0a 0a 23 69 6e 63 6c 75 64 65  ch..*/..#include
01c0: 20 22 66 74 73 35 49 6e 74 2e 68 22 0a 0a 74 79   "fts5Int.h"..ty
01d0: 70 65 64 65 66 20 73 74 72 75 63 74 20 46 74 73  pedef struct Fts
01e0: 35 54 61 62 6c 65 20 46 74 73 35 54 61 62 6c 65  5Table Fts5Table
01f0: 3b 0a 74 79 70 65 64 65 66 20 73 74 72 75 63 74  ;.typedef struct
0200: 20 46 74 73 35 43 75 72 73 6f 72 20 46 74 73 35   Fts5Cursor Fts5
0210: 43 75 72 73 6f 72 3b 0a 0a 73 74 72 75 63 74 20  Cursor;..struct 
0220: 46 74 73 35 54 61 62 6c 65 20 7b 0a 20 20 73 71  Fts5Table {.  sq
0230: 6c 69 74 65 33 5f 76 74 61 62 20 62 61 73 65 3b  lite3_vtab base;
0240: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
0250: 20 42 61 73 65 20 63 6c 61 73 73 20 75 73 65 64   Base class used
0260: 20 62 79 20 53 51 4c 69 74 65 20 63 6f 72 65 20   by SQLite core 
0270: 2a 2f 0a 20 20 46 74 73 35 43 6f 6e 66 69 67 20  */.  Fts5Config 
0280: 2a 70 43 6f 6e 66 69 67 3b 20 20 20 20 20 20 20  *pConfig;       
0290: 20 20 20 20 20 2f 2a 20 56 69 72 74 75 61 6c 20       /* Virtual 
02a0: 74 61 62 6c 65 20 63 6f 6e 66 69 67 75 72 61 74  table configurat
02b0: 69 6f 6e 20 2a 2f 0a 20 20 46 74 73 35 49 6e 64  ion */.  Fts5Ind
02c0: 65 78 20 2a 70 49 6e 64 65 78 3b 20 20 20 20 20  ex *pIndex;     
02d0: 20 20 20 20 20 20 20 20 20 2f 2a 20 46 75 6c 6c           /* Full
02e0: 2d 74 65 78 74 20 69 6e 64 65 78 20 2a 2f 0a 20  -text index */. 
02f0: 20 46 74 73 35 53 74 6f 72 61 67 65 20 2a 70 53   Fts5Storage *pS
0300: 74 6f 72 61 67 65 3b 20 20 20 20 20 20 20 20 20  torage;         
0310: 20 2f 2a 20 44 6f 63 75 6d 65 6e 74 20 73 74 6f   /* Document sto
0320: 72 65 20 2a 2f 0a 7d 3b 0a 0a 73 74 72 75 63 74  re */.};..struct
0330: 20 46 74 73 35 43 75 72 73 6f 72 20 7b 0a 20 20   Fts5Cursor {.  
0340: 73 71 6c 69 74 65 33 5f 76 74 61 62 5f 63 75 72  sqlite3_vtab_cur
0350: 73 6f 72 20 62 61 73 65 3b 20 20 20 20 20 20 20  sor base;       
0360: 2f 2a 20 42 61 73 65 20 63 6c 61 73 73 20 75 73  /* Base class us
0370: 65 64 20 62 79 20 53 51 4c 69 74 65 20 63 6f 72  ed by SQLite cor
0380: 65 20 2a 2f 0a 20 20 69 6e 74 20 69 64 78 4e 75  e */.  int idxNu
0390: 6d 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  m;              
03a0: 20 20 20 20 20 20 20 2f 2a 20 69 64 78 4e 75 6d         /* idxNum
03b0: 20 70 61 73 73 65 64 20 74 6f 20 78 46 69 6c 74   passed to xFilt
03c0: 65 72 28 29 20 2a 2f 0a 20 20 73 71 6c 69 74 65  er() */.  sqlite
03d0: 33 5f 73 74 6d 74 20 2a 70 53 74 6d 74 3b 20 20  3_stmt *pStmt;  
03e0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 74 61            /* Sta
03f0: 74 65 6d 65 6e 74 20 75 73 65 64 20 74 6f 20 72  tement used to r
0400: 65 61 64 20 25 5f 63 6f 6e 74 65 6e 74 20 2a 2f  ead %_content */
0410: 0a 20 20 69 6e 74 20 62 45 6f 66 3b 20 20 20 20  .  int bEof;    
0420: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0430: 20 20 20 2f 2a 20 54 72 75 65 20 61 74 20 45 4f     /* True at EO
0440: 46 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 43  F */.};../*.** C
0450: 6c 6f 73 65 20 61 20 76 69 72 74 75 61 6c 20 74  lose a virtual t
0460: 61 62 6c 65 20 68 61 6e 64 6c 65 20 6f 70 65 6e  able handle open
0470: 65 64 20 62 79 20 66 74 73 35 49 6e 69 74 56 74  ed by fts5InitVt
0480: 61 62 28 29 2e 20 49 66 20 74 68 65 20 62 44 65  ab(). If the bDe
0490: 73 74 72 6f 79 0a 2a 2a 20 61 72 67 75 6d 65 6e  stroy.** argumen
04a0: 74 20 69 73 20 6e 6f 6e 2d 7a 65 72 6f 2c 20 61  t is non-zero, a
04b0: 74 74 65 6d 70 74 20 64 65 6c 65 74 65 20 74 68  ttempt delete th
04c0: 65 20 73 68 61 64 6f 77 20 74 61 62 6c 65 73 20  e shadow tables 
04d0: 66 72 6f 6d 20 74 65 68 20 64 61 74 61 62 61 73  from teh databas
04e0: 65 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  e.*/.static int 
04f0: 66 74 73 35 46 72 65 65 56 74 61 62 28 46 74 73  fts5FreeVtab(Fts
0500: 35 54 61 62 6c 65 20 2a 70 54 61 62 2c 20 69 6e  5Table *pTab, in
0510: 74 20 62 44 65 73 74 72 6f 79 29 7b 0a 20 20 69  t bDestroy){.  i
0520: 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f  nt rc = SQLITE_O
0530: 4b 3b 0a 20 20 69 66 28 20 70 54 61 62 20 29 7b  K;.  if( pTab ){
0540: 0a 20 20 20 20 69 6e 74 20 72 63 32 3b 0a 20 20  .    int rc2;.  
0550: 20 20 72 63 32 20 3d 20 73 71 6c 69 74 65 33 46    rc2 = sqlite3F
0560: 74 73 35 49 6e 64 65 78 43 6c 6f 73 65 28 70 54  ts5IndexClose(pT
0570: 61 62 2d 3e 70 49 6e 64 65 78 2c 20 62 44 65 73  ab->pIndex, bDes
0580: 74 72 6f 79 29 3b 0a 20 20 20 20 69 66 28 20 72  troy);.    if( r
0590: 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72  c==SQLITE_OK ) r
05a0: 63 20 3d 20 72 63 32 3b 0a 20 20 20 20 72 63 32  c = rc2;.    rc2
05b0: 20 3d 20 73 71 6c 69 74 65 33 46 74 73 35 53 74   = sqlite3Fts5St
05c0: 6f 72 61 67 65 43 6c 6f 73 65 28 70 54 61 62 2d  orageClose(pTab-
05d0: 3e 70 53 74 6f 72 61 67 65 2c 20 62 44 65 73 74  >pStorage, bDest
05e0: 72 6f 79 29 3b 0a 20 20 20 20 69 66 28 20 72 63  roy);.    if( rc
05f0: 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72 63  ==SQLITE_OK ) rc
0600: 20 3d 20 72 63 32 3b 0a 20 20 20 20 73 71 6c 69   = rc2;.    sqli
0610: 74 65 33 46 74 73 35 43 6f 6e 66 69 67 46 72 65  te3Fts5ConfigFre
0620: 65 28 70 54 61 62 2d 3e 70 43 6f 6e 66 69 67 29  e(pTab->pConfig)
0630: 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72  ;.    sqlite3_fr
0640: 65 65 28 70 54 61 62 29 3b 0a 20 20 7d 0a 20 20  ee(pTab);.  }.  
0650: 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a  return rc;.}../*
0660: 0a 2a 2a 20 54 68 65 20 78 44 69 73 63 6f 6e 6e  .** The xDisconn
0670: 65 63 74 28 29 20 76 69 72 74 75 61 6c 20 74 61  ect() virtual ta
0680: 62 6c 65 20 6d 65 74 68 6f 64 2e 0a 2a 2f 0a 73  ble method..*/.s
0690: 74 61 74 69 63 20 69 6e 74 20 66 74 73 35 44 69  tatic int fts5Di
06a0: 73 63 6f 6e 6e 65 63 74 4d 65 74 68 6f 64 28 73  sconnectMethod(s
06b0: 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 70 56 74  qlite3_vtab *pVt
06c0: 61 62 29 7b 0a 20 20 72 65 74 75 72 6e 20 66 74  ab){.  return ft
06d0: 73 35 46 72 65 65 56 74 61 62 28 28 46 74 73 35  s5FreeVtab((Fts5
06e0: 54 61 62 6c 65 2a 29 70 56 74 61 62 2c 20 30 29  Table*)pVtab, 0)
06f0: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 65 20 78  ;.}../*.** The x
0700: 44 65 73 74 72 6f 79 28 29 20 76 69 72 74 75 61  Destroy() virtua
0710: 6c 20 74 61 62 6c 65 20 6d 65 74 68 6f 64 2e 0a  l table method..
0720: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 66 74  */.static int ft
0730: 73 35 44 65 73 74 72 6f 79 4d 65 74 68 6f 64 28  s5DestroyMethod(
0740: 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 70 56  sqlite3_vtab *pV
0750: 74 61 62 29 7b 0a 20 20 72 65 74 75 72 6e 20 66  tab){.  return f
0760: 74 73 35 46 72 65 65 56 74 61 62 28 28 46 74 73  ts5FreeVtab((Fts
0770: 35 54 61 62 6c 65 2a 29 70 56 74 61 62 2c 20 31  5Table*)pVtab, 1
0780: 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73  );.}../*.** This
0790: 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 74 68 65   function is the
07a0: 20 69 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20   implementation 
07b0: 6f 66 20 62 6f 74 68 20 74 68 65 20 78 43 6f 6e  of both the xCon
07c0: 6e 65 63 74 20 61 6e 64 20 78 43 72 65 61 74 65  nect and xCreate
07d0: 0a 2a 2a 20 6d 65 74 68 6f 64 73 20 6f 66 20 74  .** methods of t
07e0: 68 65 20 46 54 53 33 20 76 69 72 74 75 61 6c 20  he FTS3 virtual 
07f0: 74 61 62 6c 65 2e 0a 2a 2a 0a 2a 2a 20 54 68 65  table..**.** The
0800: 20 61 72 67 76 5b 5d 20 61 72 72 61 79 20 63 6f   argv[] array co
0810: 6e 74 61 69 6e 73 20 74 68 65 20 66 6f 6c 6c 6f  ntains the follo
0820: 77 69 6e 67 3a 0a 2a 2a 0a 2a 2a 20 20 20 61 72  wing:.**.**   ar
0830: 67 76 5b 30 5d 20 20 20 2d 3e 20 6d 6f 64 75 6c  gv[0]   -> modul
0840: 65 20 6e 61 6d 65 20 20 28 22 66 74 73 35 22 29  e name  ("fts5")
0850: 0a 2a 2a 20 20 20 61 72 67 76 5b 31 5d 20 20 20  .**   argv[1]   
0860: 2d 3e 20 64 61 74 61 62 61 73 65 20 6e 61 6d 65  -> database name
0870: 0a 2a 2a 20 20 20 61 72 67 76 5b 32 5d 20 20 20  .**   argv[2]   
0880: 2d 3e 20 74 61 62 6c 65 20 6e 61 6d 65 0a 2a 2a  -> table name.**
0890: 20 20 20 61 72 67 76 5b 2e 2e 2e 5d 20 2d 3e 20     argv[...] -> 
08a0: 22 63 6f 6c 75 6d 6e 20 6e 61 6d 65 22 20 61 6e  "column name" an
08b0: 64 20 6f 74 68 65 72 20 6d 6f 64 75 6c 65 20 61  d other module a
08c0: 72 67 75 6d 65 6e 74 20 66 69 65 6c 64 73 2e 0a  rgument fields..
08d0: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 66 74  */.static int ft
08e0: 73 35 49 6e 69 74 56 74 61 62 28 0a 20 20 69 6e  s5InitVtab(.  in
08f0: 74 20 62 43 72 65 61 74 65 2c 20 20 20 20 20 20  t bCreate,      
0900: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
0910: 20 54 72 75 65 20 66 6f 72 20 78 43 72 65 61 74   True for xCreat
0920: 65 2c 20 66 61 6c 73 65 20 66 6f 72 20 78 43 6f  e, false for xCo
0930: 6e 6e 65 63 74 20 2a 2f 0a 20 20 73 71 6c 69 74  nnect */.  sqlit
0940: 65 33 20 2a 64 62 2c 20 20 20 20 20 20 20 20 20  e3 *db,         
0950: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 68             /* Th
0960: 65 20 53 51 4c 69 74 65 20 64 61 74 61 62 61 73  e SQLite databas
0970: 65 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 2a 2f 0a  e connection */.
0980: 20 20 76 6f 69 64 20 2a 70 41 75 78 2c 20 20 20    void *pAux,   
0990: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
09a0: 20 20 2f 2a 20 48 61 73 68 20 74 61 62 6c 65 20    /* Hash table 
09b0: 63 6f 6e 74 61 69 6e 69 6e 67 20 74 6f 6b 65 6e  containing token
09c0: 69 7a 65 72 73 20 2a 2f 0a 20 20 69 6e 74 20 61  izers */.  int a
09d0: 72 67 63 2c 20 20 20 20 20 20 20 20 20 20 20 20  rgc,            
09e0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75             /* Nu
09f0: 6d 62 65 72 20 6f 66 20 65 6c 65 6d 65 6e 74 73  mber of elements
0a00: 20 69 6e 20 61 72 67 76 20 61 72 72 61 79 20 2a   in argv array *
0a10: 2f 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a  /.  const char *
0a20: 20 63 6f 6e 73 74 20 2a 61 72 67 76 2c 20 20 20   const *argv,   
0a30: 20 20 20 20 2f 2a 20 78 43 72 65 61 74 65 2f 78      /* xCreate/x
0a40: 43 6f 6e 6e 65 63 74 20 61 72 67 75 6d 65 6e 74  Connect argument
0a50: 20 61 72 72 61 79 20 2a 2f 0a 20 20 73 71 6c 69   array */.  sqli
0a60: 74 65 33 5f 76 74 61 62 20 2a 2a 70 70 56 54 61  te3_vtab **ppVTa
0a70: 62 2c 20 20 20 20 20 20 20 20 20 20 2f 2a 20 57  b,          /* W
0a80: 72 69 74 65 20 74 68 65 20 72 65 73 75 6c 74 69  rite the resulti
0a90: 6e 67 20 76 74 61 62 20 73 74 72 75 63 74 75 72  ng vtab structur
0aa0: 65 20 68 65 72 65 20 2a 2f 0a 20 20 63 68 61 72  e here */.  char
0ab0: 20 2a 2a 70 7a 45 72 72 20 20 20 20 20 20 20 20   **pzErr        
0ac0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 57              /* W
0ad0: 72 69 74 65 20 61 6e 79 20 65 72 72 6f 72 20 6d  rite any error m
0ae0: 65 73 73 61 67 65 20 68 65 72 65 20 2a 2f 0a 29  essage here */.)
0af0: 7b 0a 20 20 69 6e 74 20 72 63 3b 20 20 20 20 20  {.  int rc;     
0b00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0b10: 20 20 20 20 2f 2a 20 52 65 74 75 72 6e 20 63 6f      /* Return co
0b20: 64 65 20 2a 2f 0a 20 20 46 74 73 35 43 6f 6e 66  de */.  Fts5Conf
0b30: 69 67 20 2a 70 43 6f 6e 66 69 67 3b 20 20 20 20  ig *pConfig;    
0b40: 20 20 20 20 20 20 20 20 2f 2a 20 52 65 73 75 6c          /* Resul
0b50: 74 73 20 6f 66 20 70 61 72 73 69 6e 67 20 61 72  ts of parsing ar
0b60: 67 63 2f 61 72 67 76 20 2a 2f 0a 20 20 46 74 73  gc/argv */.  Fts
0b70: 35 54 61 62 6c 65 20 2a 70 54 61 62 20 3d 20 30  5Table *pTab = 0
0b80: 3b 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20  ;            /* 
0b90: 4e 65 77 20 76 69 72 74 75 61 6c 20 74 61 62 6c  New virtual tabl
0ba0: 65 20 6f 62 6a 65 63 74 20 2a 2f 0a 0a 20 20 2f  e object */..  /
0bb0: 2a 20 50 61 72 73 65 20 74 68 65 20 61 72 67 75  * Parse the argu
0bc0: 6d 65 6e 74 73 20 2a 2f 0a 20 20 72 63 20 3d 20  ments */.  rc = 
0bd0: 73 71 6c 69 74 65 33 46 74 73 35 43 6f 6e 66 69  sqlite3Fts5Confi
0be0: 67 50 61 72 73 65 28 64 62 2c 20 61 72 67 63 2c  gParse(db, argc,
0bf0: 20 28 63 6f 6e 73 74 20 63 68 61 72 2a 2a 29 61   (const char**)a
0c00: 72 67 76 2c 20 26 70 43 6f 6e 66 69 67 2c 20 70  rgv, &pConfig, p
0c10: 7a 45 72 72 29 3b 0a 20 20 61 73 73 65 72 74 28  zErr);.  assert(
0c20: 20 28 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20   (rc==SQLITE_OK 
0c30: 26 26 20 2a 70 7a 45 72 72 3d 3d 30 29 20 7c 7c  && *pzErr==0) ||
0c40: 20 70 43 6f 6e 66 69 67 3d 3d 30 20 29 3b 0a 0a   pConfig==0 );..
0c50: 20 20 2f 2a 20 41 6c 6c 6f 63 61 74 65 20 74 68    /* Allocate th
0c60: 65 20 6e 65 77 20 76 74 61 62 20 6f 62 6a 65 63  e new vtab objec
0c70: 74 20 2a 2f 0a 20 20 69 66 28 20 72 63 3d 3d 53  t */.  if( rc==S
0c80: 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
0c90: 70 54 61 62 20 3d 20 28 46 74 73 35 54 61 62 6c  pTab = (Fts5Tabl
0ca0: 65 2a 29 73 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f  e*)sqlite3_mallo
0cb0: 63 28 73 69 7a 65 6f 66 28 46 74 73 35 54 61 62  c(sizeof(Fts5Tab
0cc0: 6c 65 29 29 3b 0a 20 20 20 20 69 66 28 20 70 54  le));.    if( pT
0cd0: 61 62 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 72  ab==0 ){.      r
0ce0: 63 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d  c = SQLITE_NOMEM
0cf0: 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20  ;.    }else{.   
0d00: 20 20 20 6d 65 6d 73 65 74 28 70 54 61 62 2c 20     memset(pTab, 
0d10: 30 2c 20 73 69 7a 65 6f 66 28 46 74 73 35 54 61  0, sizeof(Fts5Ta
0d20: 62 6c 65 29 29 3b 0a 20 20 20 20 20 20 70 54 61  ble));.      pTa
0d30: 62 2d 3e 70 43 6f 6e 66 69 67 20 3d 20 70 43 6f  b->pConfig = pCo
0d40: 6e 66 69 67 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a  nfig;.    }.  }.
0d50: 0a 20 20 2f 2a 20 4f 70 65 6e 20 74 68 65 20 69  .  /* Open the i
0d60: 6e 64 65 78 20 73 75 62 2d 73 79 73 74 65 6d 20  ndex sub-system 
0d70: 2a 2f 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c  */.  if( rc==SQL
0d80: 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 72 63  ITE_OK ){.    rc
0d90: 20 3d 20 73 71 6c 69 74 65 33 46 74 73 35 49 6e   = sqlite3Fts5In
0da0: 64 65 78 4f 70 65 6e 28 70 43 6f 6e 66 69 67 2c  dexOpen(pConfig,
0db0: 20 62 43 72 65 61 74 65 2c 20 26 70 54 61 62 2d   bCreate, &pTab-
0dc0: 3e 70 49 6e 64 65 78 2c 20 70 7a 45 72 72 29 3b  >pIndex, pzErr);
0dd0: 0a 20 20 7d 0a 0a 20 20 2f 2a 20 4f 70 65 6e 20  .  }..  /* Open 
0de0: 74 68 65 20 73 74 6f 72 61 67 65 20 73 75 62 2d  the storage sub-
0df0: 73 79 73 74 65 6d 20 2a 2f 0a 20 20 69 66 28 20  system */.  if( 
0e00: 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc==SQLITE_OK ){
0e10: 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65  .    rc = sqlite
0e20: 33 46 74 73 35 53 74 6f 72 61 67 65 4f 70 65 6e  3Fts5StorageOpen
0e30: 28 0a 20 20 20 20 20 20 20 20 70 43 6f 6e 66 69  (.        pConfi
0e40: 67 2c 20 70 54 61 62 2d 3e 70 49 6e 64 65 78 2c  g, pTab->pIndex,
0e50: 20 62 43 72 65 61 74 65 2c 20 26 70 54 61 62 2d   bCreate, &pTab-
0e60: 3e 70 53 74 6f 72 61 67 65 2c 20 70 7a 45 72 72  >pStorage, pzErr
0e70: 0a 20 20 20 20 29 3b 0a 20 20 7d 0a 0a 20 20 2f  .    );.  }..  /
0e80: 2a 20 43 61 6c 6c 20 73 71 6c 69 74 65 33 5f 64  * Call sqlite3_d
0e90: 65 63 6c 61 72 65 5f 76 74 61 62 28 29 20 2a 2f  eclare_vtab() */
0ea0: 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54  .  if( rc==SQLIT
0eb0: 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 72 63 20 3d  E_OK ){.    rc =
0ec0: 20 73 71 6c 69 74 65 33 46 74 73 35 43 6f 6e 66   sqlite3Fts5Conf
0ed0: 69 67 44 65 63 6c 61 72 65 56 74 61 62 28 70 43  igDeclareVtab(pC
0ee0: 6f 6e 66 69 67 29 3b 0a 20 20 7d 0a 0a 20 20 69  onfig);.  }..  i
0ef0: 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc!=SQLITE_OK
0f00: 20 29 7b 0a 20 20 20 20 66 74 73 35 46 72 65 65   ){.    fts5Free
0f10: 56 74 61 62 28 70 54 61 62 2c 20 30 29 3b 0a 20  Vtab(pTab, 0);. 
0f20: 20 20 20 70 54 61 62 20 3d 20 30 3b 0a 20 20 7d     pTab = 0;.  }
0f30: 0a 20 20 2a 70 70 56 54 61 62 20 3d 20 28 73 71  .  *ppVTab = (sq
0f40: 6c 69 74 65 33 5f 76 74 61 62 2a 29 70 54 61 62  lite3_vtab*)pTab
0f50: 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d  ;.  return rc;.}
0f60: 0a 0a 2f 2a 0a 2a 2a 20 54 68 65 20 78 43 6f 6e  ../*.** The xCon
0f70: 6e 65 63 74 28 29 20 61 6e 64 20 78 43 72 65 61  nect() and xCrea
0f80: 74 65 28 29 20 6d 65 74 68 6f 64 73 20 66 6f 72  te() methods for
0f90: 20 74 68 65 20 76 69 72 74 75 61 6c 20 74 61 62   the virtual tab
0fa0: 6c 65 2e 20 41 6c 6c 20 74 68 65 0a 2a 2a 20 77  le. All the.** w
0fb0: 6f 72 6b 20 69 73 20 64 6f 6e 65 20 69 6e 20 66  ork is done in f
0fc0: 75 6e 63 74 69 6f 6e 20 66 74 73 35 49 6e 69 74  unction fts5Init
0fd0: 56 74 61 62 28 29 2e 0a 2a 2f 0a 73 74 61 74 69  Vtab()..*/.stati
0fe0: 63 20 69 6e 74 20 66 74 73 35 43 6f 6e 6e 65 63  c int fts5Connec
0ff0: 74 4d 65 74 68 6f 64 28 0a 20 20 73 71 6c 69 74  tMethod(.  sqlit
1000: 65 33 20 2a 64 62 2c 20 20 20 20 20 20 20 20 20  e3 *db,         
1010: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 44 61             /* Da
1020: 74 61 62 61 73 65 20 63 6f 6e 6e 65 63 74 69 6f  tabase connectio
1030: 6e 20 2a 2f 0a 20 20 76 6f 69 64 20 2a 70 41 75  n */.  void *pAu
1040: 78 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  x,              
1050: 20 20 20 20 20 20 20 2f 2a 20 50 6f 69 6e 74 65         /* Pointe
1060: 72 20 74 6f 20 74 6f 6b 65 6e 69 7a 65 72 20 68  r to tokenizer h
1070: 61 73 68 20 74 61 62 6c 65 20 2a 2f 0a 20 20 69  ash table */.  i
1080: 6e 74 20 61 72 67 63 2c 20 20 20 20 20 20 20 20  nt argc,        
1090: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
10a0: 2a 20 4e 75 6d 62 65 72 20 6f 66 20 65 6c 65 6d  * Number of elem
10b0: 65 6e 74 73 20 69 6e 20 61 72 67 76 20 61 72 72  ents in argv arr
10c0: 61 79 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68  ay */.  const ch
10d0: 61 72 20 2a 20 63 6f 6e 73 74 20 2a 61 72 67 76  ar * const *argv
10e0: 2c 20 20 20 20 20 20 20 2f 2a 20 78 43 72 65 61  ,       /* xCrea
10f0: 74 65 2f 78 43 6f 6e 6e 65 63 74 20 61 72 67 75  te/xConnect argu
1100: 6d 65 6e 74 20 61 72 72 61 79 20 2a 2f 0a 20 20  ment array */.  
1110: 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 2a 70  sqlite3_vtab **p
1120: 70 56 74 61 62 2c 20 20 20 20 20 20 20 20 20 20  pVtab,          
1130: 2f 2a 20 4f 55 54 3a 20 4e 65 77 20 73 71 6c 69  /* OUT: New sqli
1140: 74 65 33 5f 76 74 61 62 20 6f 62 6a 65 63 74 20  te3_vtab object 
1150: 2a 2f 0a 20 20 63 68 61 72 20 2a 2a 70 7a 45 72  */.  char **pzEr
1160: 72 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  r               
1170: 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 73 71 6c       /* OUT: sql
1180: 69 74 65 33 5f 6d 61 6c 6c 6f 63 27 64 20 65 72  ite3_malloc'd er
1190: 72 6f 72 20 6d 65 73 73 61 67 65 20 2a 2f 0a 29  ror message */.)
11a0: 7b 0a 20 20 72 65 74 75 72 6e 20 66 74 73 35 49  {.  return fts5I
11b0: 6e 69 74 56 74 61 62 28 30 2c 20 64 62 2c 20 70  nitVtab(0, db, p
11c0: 41 75 78 2c 20 61 72 67 63 2c 20 61 72 67 76 2c  Aux, argc, argv,
11d0: 20 70 70 56 74 61 62 2c 20 70 7a 45 72 72 29 3b   ppVtab, pzErr);
11e0: 0a 7d 0a 73 74 61 74 69 63 20 69 6e 74 20 66 74  .}.static int ft
11f0: 73 35 43 72 65 61 74 65 4d 65 74 68 6f 64 28 0a  s5CreateMethod(.
1200: 20 20 73 71 6c 69 74 65 33 20 2a 64 62 2c 20 20    sqlite3 *db,  
1210: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1220: 20 20 2f 2a 20 44 61 74 61 62 61 73 65 20 63 6f    /* Database co
1230: 6e 6e 65 63 74 69 6f 6e 20 2a 2f 0a 20 20 76 6f  nnection */.  vo
1240: 69 64 20 2a 70 41 75 78 2c 20 20 20 20 20 20 20  id *pAux,       
1250: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
1260: 20 50 6f 69 6e 74 65 72 20 74 6f 20 74 6f 6b 65   Pointer to toke
1270: 6e 69 7a 65 72 20 68 61 73 68 20 74 61 62 6c 65  nizer hash table
1280: 20 2a 2f 0a 20 20 69 6e 74 20 61 72 67 63 2c 20   */.  int argc, 
1290: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
12a0: 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20        /* Number 
12b0: 6f 66 20 65 6c 65 6d 65 6e 74 73 20 69 6e 20 61  of elements in a
12c0: 72 67 76 20 61 72 72 61 79 20 2a 2f 0a 20 20 63  rgv array */.  c
12d0: 6f 6e 73 74 20 63 68 61 72 20 2a 20 63 6f 6e 73  onst char * cons
12e0: 74 20 2a 61 72 67 76 2c 20 20 20 20 20 20 20 2f  t *argv,       /
12f0: 2a 20 78 43 72 65 61 74 65 2f 78 43 6f 6e 6e 65  * xCreate/xConne
1300: 63 74 20 61 72 67 75 6d 65 6e 74 20 61 72 72 61  ct argument arra
1310: 79 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 76  y */.  sqlite3_v
1320: 74 61 62 20 2a 2a 70 70 56 74 61 62 2c 20 20 20  tab **ppVtab,   
1330: 20 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 4e         /* OUT: N
1340: 65 77 20 73 71 6c 69 74 65 33 5f 76 74 61 62 20  ew sqlite3_vtab 
1350: 6f 62 6a 65 63 74 20 2a 2f 0a 20 20 63 68 61 72  object */.  char
1360: 20 2a 2a 70 7a 45 72 72 20 20 20 20 20 20 20 20   **pzErr        
1370: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f              /* O
1380: 55 54 3a 20 73 71 6c 69 74 65 33 5f 6d 61 6c 6c  UT: sqlite3_mall
1390: 6f 63 27 64 20 65 72 72 6f 72 20 6d 65 73 73 61  oc'd error messa
13a0: 67 65 20 2a 2f 0a 29 7b 0a 20 20 72 65 74 75 72  ge */.){.  retur
13b0: 6e 20 66 74 73 35 49 6e 69 74 56 74 61 62 28 31  n fts5InitVtab(1
13c0: 2c 20 64 62 2c 20 70 41 75 78 2c 20 61 72 67 63  , db, pAux, argc
13d0: 2c 20 61 72 67 76 2c 20 70 70 56 74 61 62 2c 20  , argv, ppVtab, 
13e0: 70 7a 45 72 72 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  pzErr);.}../*.**
13f0: 20 54 68 65 20 74 68 72 65 65 20 71 75 65 72 79   The three query
1400: 20 70 6c 61 6e 73 20 78 42 65 73 74 49 6e 64 65   plans xBestInde
1410: 78 20 6d 61 79 20 63 68 6f 6f 73 65 20 62 65 74  x may choose bet
1420: 77 65 65 6e 2e 0a 2a 2f 0a 23 64 65 66 69 6e 65  ween..*/.#define
1430: 20 46 54 53 35 5f 50 4c 41 4e 5f 53 43 41 4e 20   FTS5_PLAN_SCAN 
1440: 20 20 20 31 20 20 20 20 20 20 20 2f 2a 20 4e 6f     1       /* No
1450: 20 75 73 61 62 6c 65 20 63 6f 6e 73 74 72 61 69   usable constrai
1460: 6e 74 20 2a 2f 0a 23 64 65 66 69 6e 65 20 46 54  nt */.#define FT
1470: 53 35 5f 50 4c 41 4e 5f 4d 41 54 43 48 20 20 20  S5_PLAN_MATCH   
1480: 32 20 20 20 20 20 20 20 2f 2a 20 28 3c 74 62 6c  2       /* (<tbl
1490: 3e 20 4d 41 54 43 48 20 3f 29 20 2a 2f 0a 23 64  > MATCH ?) */.#d
14a0: 65 66 69 6e 65 20 46 54 53 35 5f 50 4c 41 4e 5f  efine FTS5_PLAN_
14b0: 52 4f 57 49 44 20 20 20 33 20 20 20 20 20 20 20  ROWID   3       
14c0: 2f 2a 20 28 72 6f 77 69 64 20 3d 20 3f 29 20 2a  /* (rowid = ?) *
14d0: 2f 0a 0a 23 64 65 66 69 6e 65 20 46 54 53 35 5f  /..#define FTS5_
14e0: 50 4c 41 4e 28 69 64 78 4e 75 6d 29 20 28 28 69  PLAN(idxNum) ((i
14f0: 64 78 4e 75 6d 29 20 26 20 30 78 37 29 0a 0a 23  dxNum) & 0x7)..#
1500: 64 65 66 69 6e 65 20 46 54 53 35 5f 4f 52 44 45  define FTS5_ORDE
1510: 52 5f 44 45 53 43 20 20 20 38 20 20 20 20 20 20  R_DESC   8      
1520: 20 2f 2a 20 4f 52 44 45 52 20 42 59 20 72 6f 77   /* ORDER BY row
1530: 69 64 20 44 45 53 43 20 2a 2f 0a 23 64 65 66 69  id DESC */.#defi
1540: 6e 65 20 46 54 53 35 5f 4f 52 44 45 52 5f 41 53  ne FTS5_ORDER_AS
1550: 43 20 20 20 31 36 20 20 20 20 20 20 20 2f 2a 20  C   16       /* 
1560: 4f 52 44 45 52 20 42 59 20 72 6f 77 69 64 20 41  ORDER BY rowid A
1570: 53 43 20 2a 2f 0a 0a 0a 73 74 61 74 69 63 20 69  SC */...static i
1580: 6e 74 20 66 74 73 35 46 69 6e 64 43 6f 6e 73 74  nt fts5FindConst
1590: 72 61 69 6e 74 28 73 71 6c 69 74 65 33 5f 69 6e  raint(sqlite3_in
15a0: 64 65 78 5f 69 6e 66 6f 20 2a 70 49 6e 66 6f 2c  dex_info *pInfo,
15b0: 20 69 6e 74 20 65 4f 70 2c 20 69 6e 74 20 69 43   int eOp, int iC
15c0: 6f 6c 29 7b 0a 20 20 69 6e 74 20 69 3b 0a 0a 20  ol){.  int i;.. 
15d0: 20 66 6f 72 28 69 3d 30 3b 20 69 3c 70 49 6e 66   for(i=0; i<pInf
15e0: 6f 2d 3e 6e 43 6f 6e 73 74 72 61 69 6e 74 3b 20  o->nConstraint; 
15f0: 69 2b 2b 29 7b 0a 20 20 20 20 73 74 72 75 63 74  i++){.    struct
1600: 20 73 71 6c 69 74 65 33 5f 69 6e 64 65 78 5f 63   sqlite3_index_c
1610: 6f 6e 73 74 72 61 69 6e 74 20 2a 70 20 3d 20 26  onstraint *p = &
1620: 70 49 6e 66 6f 2d 3e 61 43 6f 6e 73 74 72 61 69  pInfo->aConstrai
1630: 6e 74 5b 69 5d 3b 0a 20 20 20 20 69 66 28 20 70  nt[i];.    if( p
1640: 2d 3e 75 73 61 62 6c 65 20 26 26 20 70 2d 3e 69  ->usable && p->i
1650: 43 6f 6c 75 6d 6e 3d 3d 69 43 6f 6c 20 26 26 20  Column==iCol && 
1660: 70 2d 3e 6f 70 3d 3d 65 4f 70 20 29 20 72 65 74  p->op==eOp ) ret
1670: 75 72 6e 20 69 3b 0a 20 20 7d 0a 0a 20 20 72 65  urn i;.  }..  re
1680: 74 75 72 6e 20 2d 31 3b 0a 7d 0a 0a 2f 2a 20 0a  turn -1;.}../* .
1690: 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74 61 74 69 6f  ** Implementatio
16a0: 6e 20 6f 66 20 74 68 65 20 78 42 65 73 74 49 6e  n of the xBestIn
16b0: 64 65 78 20 6d 65 74 68 6f 64 20 66 6f 72 20 46  dex method for F
16c0: 54 53 35 20 74 61 62 6c 65 73 2e 20 54 68 65 72  TS5 tables. Ther
16d0: 65 0a 2a 2a 20 61 72 65 20 74 68 72 65 65 20 70  e.** are three p
16e0: 6f 73 73 69 62 6c 65 20 73 74 72 61 74 65 67 69  ossible strategi
16f0: 65 73 2c 20 69 6e 20 6f 72 64 65 72 20 6f 66 20  es, in order of 
1700: 70 72 65 66 65 72 65 6e 63 65 3a 0a 2a 2a 0a 2a  preference:.**.*
1710: 2a 20 20 20 31 2e 20 46 75 6c 6c 2d 74 65 78 74  *   1. Full-text
1720: 20 73 65 61 72 63 68 20 75 73 69 6e 67 20 61 20   search using a 
1730: 4d 41 54 43 48 20 6f 70 65 72 61 74 6f 72 2e 0a  MATCH operator..
1740: 2a 2a 20 20 20 32 2e 20 41 20 62 79 2d 72 6f 77  **   2. A by-row
1750: 69 64 20 6c 6f 6f 6b 75 70 2e 0a 2a 2a 20 20 20  id lookup..**   
1760: 33 2e 20 41 20 66 75 6c 6c 2d 74 61 62 6c 65 20  3. A full-table 
1770: 73 63 61 6e 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  scan..*/.static 
1780: 69 6e 74 20 66 74 73 35 42 65 73 74 49 6e 64 65  int fts5BestInde
1790: 78 4d 65 74 68 6f 64 28 73 71 6c 69 74 65 33 5f  xMethod(sqlite3_
17a0: 76 74 61 62 20 2a 70 56 54 61 62 2c 20 73 71 6c  vtab *pVTab, sql
17b0: 69 74 65 33 5f 69 6e 64 65 78 5f 69 6e 66 6f 20  ite3_index_info 
17c0: 2a 70 49 6e 66 6f 29 7b 0a 20 20 46 74 73 35 54  *pInfo){.  Fts5T
17d0: 61 62 6c 65 20 2a 70 54 61 62 20 3d 20 28 46 74  able *pTab = (Ft
17e0: 73 35 54 61 62 6c 65 2a 29 70 56 54 61 62 3b 0a  s5Table*)pVTab;.
17f0: 20 20 46 74 73 35 43 6f 6e 66 69 67 20 2a 70 43    Fts5Config *pC
1800: 6f 6e 66 69 67 20 3d 20 70 54 61 62 2d 3e 70 43  onfig = pTab->pC
1810: 6f 6e 66 69 67 3b 0a 20 20 69 6e 74 20 69 43 6f  onfig;.  int iCo
1820: 6e 73 3b 0a 20 20 69 6e 74 20 65 50 6c 61 6e 20  ns;.  int ePlan 
1830: 3d 20 46 54 53 35 5f 50 4c 41 4e 5f 53 43 41 4e  = FTS5_PLAN_SCAN
1840: 3b 0a 0a 20 20 69 43 6f 6e 73 20 3d 20 66 74 73  ;..  iCons = fts
1850: 35 46 69 6e 64 43 6f 6e 73 74 72 61 69 6e 74 28  5FindConstraint(
1860: 70 49 6e 66 6f 2c 53 51 4c 49 54 45 5f 49 4e 44  pInfo,SQLITE_IND
1870: 45 58 5f 43 4f 4e 53 54 52 41 49 4e 54 5f 4d 41  EX_CONSTRAINT_MA
1880: 54 43 48 2c 70 43 6f 6e 66 69 67 2d 3e 6e 43 6f  TCH,pConfig->nCo
1890: 6c 29 3b 0a 20 20 69 66 28 20 69 43 6f 6e 73 3e  l);.  if( iCons>
18a0: 3d 30 20 29 7b 0a 20 20 20 20 65 50 6c 61 6e 20  =0 ){.    ePlan 
18b0: 3d 20 46 54 53 35 5f 50 4c 41 4e 5f 4d 41 54 43  = FTS5_PLAN_MATC
18c0: 48 3b 0a 20 20 20 20 70 49 6e 66 6f 2d 3e 65 73  H;.    pInfo->es
18d0: 74 69 6d 61 74 65 64 43 6f 73 74 20 3d 20 31 2e  timatedCost = 1.
18e0: 30 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  0;.  }else{.    
18f0: 69 43 6f 6e 73 20 3d 20 66 74 73 35 46 69 6e 64  iCons = fts5Find
1900: 43 6f 6e 73 74 72 61 69 6e 74 28 70 49 6e 66 6f  Constraint(pInfo
1910: 2c 20 53 51 4c 49 54 45 5f 49 4e 44 45 58 5f 43  , SQLITE_INDEX_C
1920: 4f 4e 53 54 52 41 49 4e 54 5f 45 51 2c 20 2d 31  ONSTRAINT_EQ, -1
1930: 29 3b 0a 20 20 20 20 69 66 28 20 69 43 6f 6e 73  );.    if( iCons
1940: 3e 3d 30 20 29 7b 0a 20 20 20 20 20 20 65 50 6c  >=0 ){.      ePl
1950: 61 6e 20 3d 20 46 54 53 35 5f 50 4c 41 4e 5f 52  an = FTS5_PLAN_R
1960: 4f 57 49 44 3b 0a 20 20 20 20 20 20 70 49 6e 66  OWID;.      pInf
1970: 6f 2d 3e 65 73 74 69 6d 61 74 65 64 43 6f 73 74  o->estimatedCost
1980: 20 3d 20 32 2e 30 3b 0a 20 20 20 20 7d 0a 20 20   = 2.0;.    }.  
1990: 7d 0a 0a 20 20 69 66 28 20 69 43 6f 6e 73 3e 3d  }..  if( iCons>=
19a0: 30 20 29 7b 0a 20 20 20 20 70 49 6e 66 6f 2d 3e  0 ){.    pInfo->
19b0: 61 43 6f 6e 73 74 72 61 69 6e 74 55 73 61 67 65  aConstraintUsage
19c0: 5b 69 43 6f 6e 73 5d 2e 61 72 67 76 49 6e 64 65  [iCons].argvInde
19d0: 78 20 3d 20 31 3b 0a 20 20 20 20 70 49 6e 66 6f  x = 1;.    pInfo
19e0: 2d 3e 61 43 6f 6e 73 74 72 61 69 6e 74 55 73 61  ->aConstraintUsa
19f0: 67 65 5b 69 43 6f 6e 73 5d 2e 6f 6d 69 74 20 3d  ge[iCons].omit =
1a00: 20 31 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20   1;.  }else{.   
1a10: 20 70 49 6e 66 6f 2d 3e 65 73 74 69 6d 61 74 65   pInfo->estimate
1a20: 64 43 6f 73 74 20 3d 20 31 30 30 30 30 30 30 30  dCost = 10000000
1a30: 2e 30 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 70  .0;.  }..  if( p
1a40: 49 6e 66 6f 2d 3e 6e 4f 72 64 65 72 42 79 3d 3d  Info->nOrderBy==
1a50: 31 20 26 26 20 70 49 6e 66 6f 2d 3e 61 4f 72 64  1 && pInfo->aOrd
1a60: 65 72 42 79 5b 30 5d 2e 69 43 6f 6c 75 6d 6e 3c  erBy[0].iColumn<
1a70: 30 20 29 7b 0a 20 20 20 20 70 49 6e 66 6f 2d 3e  0 ){.    pInfo->
1a80: 6f 72 64 65 72 42 79 43 6f 6e 73 75 6d 65 64 20  orderByConsumed 
1a90: 3d 20 31 3b 0a 20 20 20 20 65 50 6c 61 6e 20 7c  = 1;.    ePlan |
1aa0: 3d 20 70 49 6e 66 6f 2d 3e 61 4f 72 64 65 72 42  = pInfo->aOrderB
1ab0: 79 5b 30 5d 2e 64 65 73 63 20 3f 20 46 54 53 35  y[0].desc ? FTS5
1ac0: 5f 4f 52 44 45 52 5f 44 45 53 43 20 3a 20 46 54  _ORDER_DESC : FT
1ad0: 53 35 5f 4f 52 44 45 52 5f 41 53 43 3b 0a 20 20  S5_ORDER_ASC;.  
1ae0: 7d 0a 20 20 20 0a 20 20 70 49 6e 66 6f 2d 3e 69  }.   .  pInfo->i
1af0: 64 78 4e 75 6d 20 3d 20 65 50 6c 61 6e 3b 0a 20  dxNum = ePlan;. 
1b00: 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f   return SQLITE_O
1b10: 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c  K;.}../*.** Impl
1b20: 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66 20 78 4f  ementation of xO
1b30: 70 65 6e 20 6d 65 74 68 6f 64 2e 0a 2a 2f 0a 73  pen method..*/.s
1b40: 74 61 74 69 63 20 69 6e 74 20 66 74 73 35 4f 70  tatic int fts5Op
1b50: 65 6e 4d 65 74 68 6f 64 28 73 71 6c 69 74 65 33  enMethod(sqlite3
1b60: 5f 76 74 61 62 20 2a 70 56 54 61 62 2c 20 73 71  _vtab *pVTab, sq
1b70: 6c 69 74 65 33 5f 76 74 61 62 5f 63 75 72 73 6f  lite3_vtab_curso
1b80: 72 20 2a 2a 70 70 43 73 72 29 7b 0a 20 20 46 74  r **ppCsr){.  Ft
1b90: 73 35 43 75 72 73 6f 72 20 2a 70 43 73 72 3b 0a  s5Cursor *pCsr;.
1ba0: 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54    int rc = SQLIT
1bb0: 45 5f 4f 4b 3b 0a 20 20 70 43 73 72 20 3d 20 28  E_OK;.  pCsr = (
1bc0: 46 74 73 35 43 75 72 73 6f 72 2a 29 73 71 6c 69  Fts5Cursor*)sqli
1bd0: 74 65 33 5f 6d 61 6c 6c 6f 63 28 73 69 7a 65 6f  te3_malloc(sizeo
1be0: 66 28 46 74 73 35 43 75 72 73 6f 72 29 29 3b 0a  f(Fts5Cursor));.
1bf0: 20 20 69 66 28 20 70 43 73 72 20 29 7b 0a 20 20    if( pCsr ){.  
1c00: 20 20 6d 65 6d 73 65 74 28 70 43 73 72 2c 20 30    memset(pCsr, 0
1c10: 2c 20 73 69 7a 65 6f 66 28 46 74 73 35 43 75 72  , sizeof(Fts5Cur
1c20: 73 6f 72 29 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a  sor));.  }else{.
1c30: 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f      rc = SQLITE_
1c40: 4e 4f 4d 45 4d 3b 0a 20 20 7d 0a 20 20 2a 70 70  NOMEM;.  }.  *pp
1c50: 43 73 72 20 3d 20 28 73 71 6c 69 74 65 33 5f 76  Csr = (sqlite3_v
1c60: 74 61 62 5f 63 75 72 73 6f 72 2a 29 70 43 73 72  tab_cursor*)pCsr
1c70: 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d  ;.  return rc;.}
1c80: 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 66 74 73  ..static int fts
1c90: 35 53 74 6d 74 54 79 70 65 28 69 6e 74 20 69 64  5StmtType(int id
1ca0: 78 4e 75 6d 29 7b 0a 20 20 69 66 28 20 46 54 53  xNum){.  if( FTS
1cb0: 35 5f 50 4c 41 4e 28 69 64 78 4e 75 6d 29 3d 3d  5_PLAN(idxNum)==
1cc0: 46 54 53 35 5f 50 4c 41 4e 5f 53 43 41 4e 20 29  FTS5_PLAN_SCAN )
1cd0: 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 28 69 64  {.    return (id
1ce0: 78 4e 75 6d 26 46 54 53 35 5f 4f 52 44 45 52 5f  xNum&FTS5_ORDER_
1cf0: 41 53 43 29 20 3f 20 46 54 53 35 5f 53 54 4d 54  ASC) ? FTS5_STMT
1d00: 5f 53 43 41 4e 5f 41 53 43 20 3a 20 46 54 53 35  _SCAN_ASC : FTS5
1d10: 5f 53 54 4d 54 5f 53 43 41 4e 5f 44 45 53 43 3b  _STMT_SCAN_DESC;
1d20: 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 46 54  .  }.  return FT
1d30: 53 35 5f 53 54 4d 54 5f 4c 4f 4f 4b 55 50 3b 0a  S5_STMT_LOOKUP;.
1d40: 7d 0a 0a 2f 2a 0a 2a 2a 20 43 6c 6f 73 65 20 74  }../*.** Close t
1d50: 68 65 20 63 75 72 73 6f 72 2e 20 20 46 6f 72 20  he cursor.  For 
1d60: 61 64 64 69 74 69 6f 6e 61 6c 20 69 6e 66 6f 72  additional infor
1d70: 6d 61 74 69 6f 6e 20 73 65 65 20 74 68 65 20 64  mation see the d
1d80: 6f 63 75 6d 65 6e 74 61 74 69 6f 6e 0a 2a 2a 20  ocumentation.** 
1d90: 6f 6e 20 74 68 65 20 78 43 6c 6f 73 65 20 6d 65  on the xClose me
1da0: 74 68 6f 64 20 6f 66 20 74 68 65 20 76 69 72 74  thod of the virt
1db0: 75 61 6c 20 74 61 62 6c 65 20 69 6e 74 65 72 66  ual table interf
1dc0: 61 63 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  ace..*/.static i
1dd0: 6e 74 20 66 74 73 35 43 6c 6f 73 65 4d 65 74 68  nt fts5CloseMeth
1de0: 6f 64 28 73 71 6c 69 74 65 33 5f 76 74 61 62 5f  od(sqlite3_vtab_
1df0: 63 75 72 73 6f 72 20 2a 70 43 75 72 73 6f 72 29  cursor *pCursor)
1e00: 7b 0a 20 20 46 74 73 35 54 61 62 6c 65 20 2a 70  {.  Fts5Table *p
1e10: 54 61 62 20 3d 20 28 46 74 73 35 54 61 62 6c 65  Tab = (Fts5Table
1e20: 2a 29 28 70 43 75 72 73 6f 72 2d 3e 70 56 74 61  *)(pCursor->pVta
1e30: 62 29 3b 0a 20 20 46 74 73 35 43 75 72 73 6f 72  b);.  Fts5Cursor
1e40: 20 2a 70 43 73 72 20 3d 20 28 46 74 73 35 43 75   *pCsr = (Fts5Cu
1e50: 72 73 6f 72 2a 29 70 43 75 72 73 6f 72 3b 0a 20  rsor*)pCursor;. 
1e60: 20 69 66 28 20 70 43 73 72 2d 3e 70 53 74 6d 74   if( pCsr->pStmt
1e70: 20 29 7b 0a 20 20 20 20 69 6e 74 20 65 53 74 6d   ){.    int eStm
1e80: 74 20 3d 20 66 74 73 35 53 74 6d 74 54 79 70 65  t = fts5StmtType
1e90: 28 70 43 73 72 2d 3e 69 64 78 4e 75 6d 29 3b 0a  (pCsr->idxNum);.
1ea0: 20 20 20 20 73 71 6c 69 74 65 33 46 74 73 35 53      sqlite3Fts5S
1eb0: 74 6f 72 61 67 65 53 74 6d 74 52 65 6c 65 61 73  torageStmtReleas
1ec0: 65 28 70 54 61 62 2d 3e 70 53 74 6f 72 61 67 65  e(pTab->pStorage
1ed0: 2c 20 65 53 74 6d 74 2c 20 70 43 73 72 2d 3e 70  , eStmt, pCsr->p
1ee0: 53 74 6d 74 29 3b 0a 20 20 7d 0a 20 20 73 71 6c  Stmt);.  }.  sql
1ef0: 69 74 65 33 5f 66 72 65 65 28 70 43 73 72 29 3b  ite3_free(pCsr);
1f00: 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45  .  return SQLITE
1f10: 5f 4f 4b 3b 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 41  _OK;.}.../*.** A
1f20: 64 76 61 6e 63 65 20 74 68 65 20 63 75 72 73 6f  dvance the curso
1f30: 72 20 74 6f 20 74 68 65 20 6e 65 78 74 20 72 6f  r to the next ro
1f40: 77 20 69 6e 20 74 68 65 20 74 61 62 6c 65 20 74  w in the table t
1f50: 68 61 74 20 6d 61 74 63 68 65 73 20 74 68 65 20  hat matches the 
1f60: 0a 2a 2a 20 73 65 61 72 63 68 20 63 72 69 74 65  .** search crite
1f70: 72 69 61 2e 0a 2a 2a 0a 2a 2a 20 52 65 74 75 72  ria..**.** Retur
1f80: 6e 20 53 51 4c 49 54 45 5f 4f 4b 20 69 66 20 6e  n SQLITE_OK if n
1f90: 6f 74 68 69 6e 67 20 67 6f 65 73 20 77 72 6f 6e  othing goes wron
1fa0: 67 2e 20 20 53 51 4c 49 54 45 5f 4f 4b 20 69 73  g.  SQLITE_OK is
1fb0: 20 72 65 74 75 72 6e 65 64 0a 2a 2a 20 65 76 65   returned.** eve
1fc0: 6e 20 69 66 20 77 65 20 72 65 61 63 68 20 65 6e  n if we reach en
1fd0: 64 2d 6f 66 2d 66 69 6c 65 2e 20 20 54 68 65 20  d-of-file.  The 
1fe0: 66 74 73 35 45 6f 66 4d 65 74 68 6f 64 28 29 20  fts5EofMethod() 
1ff0: 77 69 6c 6c 20 62 65 20 63 61 6c 6c 65 64 0a 2a  will be called.*
2000: 2a 20 73 75 62 73 65 71 75 65 6e 74 6c 79 20 74  * subsequently t
2010: 6f 20 64 65 74 65 72 6d 69 6e 65 20 77 68 65 74  o determine whet
2020: 68 65 72 20 6f 72 20 6e 6f 74 20 61 6e 20 45 4f  her or not an EO
2030: 46 20 77 61 73 20 68 69 74 2e 0a 2a 2f 0a 73 74  F was hit..*/.st
2040: 61 74 69 63 20 69 6e 74 20 66 74 73 35 4e 65 78  atic int fts5Nex
2050: 74 4d 65 74 68 6f 64 28 73 71 6c 69 74 65 33 5f  tMethod(sqlite3_
2060: 76 74 61 62 5f 63 75 72 73 6f 72 20 2a 70 43 75  vtab_cursor *pCu
2070: 72 73 6f 72 29 7b 0a 20 20 46 74 73 35 43 75 72  rsor){.  Fts5Cur
2080: 73 6f 72 20 2a 70 43 73 72 20 3d 20 28 46 74 73  sor *pCsr = (Fts
2090: 35 43 75 72 73 6f 72 2a 29 70 43 75 72 73 6f 72  5Cursor*)pCursor
20a0: 3b 0a 20 20 69 6e 74 20 65 50 6c 61 6e 20 3d 20  ;.  int ePlan = 
20b0: 46 54 53 35 5f 50 4c 41 4e 28 70 43 73 72 2d 3e  FTS5_PLAN(pCsr->
20c0: 69 64 78 4e 75 6d 29 3b 0a 20 20 69 6e 74 20 72  idxNum);.  int r
20d0: 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 0a  c = SQLITE_OK;..
20e0: 20 20 61 73 73 65 72 74 28 20 65 50 6c 61 6e 21    assert( ePlan!
20f0: 3d 46 54 53 35 5f 50 4c 41 4e 5f 4d 41 54 43 48  =FTS5_PLAN_MATCH
2100: 20 29 3b 0a 20 20 69 66 28 20 65 50 6c 61 6e 21   );.  if( ePlan!
2110: 3d 46 54 53 35 5f 50 4c 41 4e 5f 4d 41 54 43 48  =FTS5_PLAN_MATCH
2120: 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 73 71 6c   ){.    rc = sql
2130: 69 74 65 33 5f 73 74 65 70 28 70 43 73 72 2d 3e  ite3_step(pCsr->
2140: 70 53 74 6d 74 29 3b 0a 20 20 20 20 69 66 28 20  pStmt);.    if( 
2150: 72 63 21 3d 53 51 4c 49 54 45 5f 52 4f 57 20 29  rc!=SQLITE_ROW )
2160: 7b 0a 20 20 20 20 20 20 70 43 73 72 2d 3e 62 45  {.      pCsr->bE
2170: 6f 66 20 3d 20 31 3b 0a 20 20 20 20 20 20 72 63  of = 1;.      rc
2180: 20 3d 20 73 71 6c 69 74 65 33 5f 72 65 73 65 74   = sqlite3_reset
2190: 28 70 43 73 72 2d 3e 70 53 74 6d 74 29 3b 0a 20  (pCsr->pStmt);. 
21a0: 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20     }else{.      
21b0: 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a  rc = SQLITE_OK;.
21c0: 20 20 20 20 7d 0a 20 20 7d 0a 20 20 0a 20 20 72      }.  }.  .  r
21d0: 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a  eturn rc;.}../*.
21e0: 2a 2a 20 54 68 69 73 20 69 73 20 74 68 65 20 78  ** This is the x
21f0: 46 69 6c 74 65 72 20 69 6e 74 65 72 66 61 63 65  Filter interface
2200: 20 66 6f 72 20 74 68 65 20 76 69 72 74 75 61 6c   for the virtual
2210: 20 74 61 62 6c 65 2e 20 20 53 65 65 0a 2a 2a 20   table.  See.** 
2220: 74 68 65 20 76 69 72 74 75 61 6c 20 74 61 62 6c  the virtual tabl
2230: 65 20 78 46 69 6c 74 65 72 20 6d 65 74 68 6f 64  e xFilter method
2240: 20 64 6f 63 75 6d 65 6e 74 61 74 69 6f 6e 20 66   documentation f
2250: 6f 72 20 61 64 64 69 74 69 6f 6e 61 6c 0a 2a 2a  or additional.**
2260: 20 69 6e 66 6f 72 6d 61 74 69 6f 6e 2e 0a 2a 2f   information..*/
2270: 0a 73 74 61 74 69 63 20 69 6e 74 20 66 74 73 35  .static int fts5
2280: 46 69 6c 74 65 72 4d 65 74 68 6f 64 28 0a 20 20  FilterMethod(.  
2290: 73 71 6c 69 74 65 33 5f 76 74 61 62 5f 63 75 72  sqlite3_vtab_cur
22a0: 73 6f 72 20 2a 70 43 75 72 73 6f 72 2c 20 20 20  sor *pCursor,   
22b0: 2f 2a 20 54 68 65 20 63 75 72 73 6f 72 20 75 73  /* The cursor us
22c0: 65 64 20 66 6f 72 20 74 68 69 73 20 71 75 65 72  ed for this quer
22d0: 79 20 2a 2f 0a 20 20 69 6e 74 20 69 64 78 4e 75  y */.  int idxNu
22e0: 6d 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  m,              
22f0: 20 20 20 20 20 20 20 2f 2a 20 53 74 72 61 74 65         /* Strate
2300: 67 79 20 69 6e 64 65 78 20 2a 2f 0a 20 20 63 6f  gy index */.  co
2310: 6e 73 74 20 63 68 61 72 20 2a 69 64 78 53 74 72  nst char *idxStr
2320: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a  ,             /*
2330: 20 55 6e 75 73 65 64 20 2a 2f 0a 20 20 69 6e 74   Unused */.  int
2340: 20 6e 56 61 6c 2c 20 20 20 20 20 20 20 20 20 20   nVal,          
2350: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
2360: 4e 75 6d 62 65 72 20 6f 66 20 65 6c 65 6d 65 6e  Number of elemen
2370: 74 73 20 69 6e 20 61 70 56 61 6c 20 2a 2f 0a 20  ts in apVal */. 
2380: 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 20 2a   sqlite3_value *
2390: 2a 61 70 56 61 6c 20 20 20 20 20 20 20 20 20 20  *apVal          
23a0: 20 2f 2a 20 41 72 67 75 6d 65 6e 74 73 20 66 6f   /* Arguments fo
23b0: 72 20 74 68 65 20 69 6e 64 65 78 69 6e 67 20 73  r the indexing s
23c0: 63 68 65 6d 65 20 2a 2f 0a 29 7b 0a 20 20 46 74  cheme */.){.  Ft
23d0: 73 35 54 61 62 6c 65 20 2a 70 54 61 62 20 3d 20  s5Table *pTab = 
23e0: 28 46 74 73 35 54 61 62 6c 65 2a 29 28 70 43 75  (Fts5Table*)(pCu
23f0: 72 73 6f 72 2d 3e 70 56 74 61 62 29 3b 0a 20 20  rsor->pVtab);.  
2400: 46 74 73 35 43 75 72 73 6f 72 20 2a 70 43 73 72  Fts5Cursor *pCsr
2410: 20 3d 20 28 46 74 73 35 43 75 72 73 6f 72 2a 29   = (Fts5Cursor*)
2420: 70 43 75 72 73 6f 72 3b 0a 20 20 69 6e 74 20 72  pCursor;.  int r
2430: 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20  c = SQLITE_OK;. 
2440: 20 69 6e 74 20 65 50 6c 61 6e 20 3d 20 46 54 53   int ePlan = FTS
2450: 35 5f 50 4c 41 4e 28 69 64 78 4e 75 6d 29 3b 0a  5_PLAN(idxNum);.
2460: 20 20 69 6e 74 20 65 53 74 6d 74 20 3d 20 66 74    int eStmt = ft
2470: 73 35 53 74 6d 74 54 79 70 65 28 69 64 78 4e 75  s5StmtType(idxNu
2480: 6d 29 3b 0a 0a 20 20 61 73 73 65 72 74 28 20 65  m);..  assert( e
2490: 50 6c 61 6e 21 3d 46 54 53 35 5f 50 4c 41 4e 5f  Plan!=FTS5_PLAN_
24a0: 4d 41 54 43 48 20 29 3b 0a 20 20 6d 65 6d 73 65  MATCH );.  memse
24b0: 74 28 26 70 43 75 72 73 6f 72 5b 31 5d 2c 20 30  t(&pCursor[1], 0
24c0: 2c 20 73 69 7a 65 6f 66 28 46 74 73 35 43 75 72  , sizeof(Fts5Cur
24d0: 73 6f 72 29 20 2d 20 73 69 7a 65 6f 66 28 73 71  sor) - sizeof(sq
24e0: 6c 69 74 65 33 5f 76 74 61 62 5f 63 75 72 73 6f  lite3_vtab_curso
24f0: 72 29 29 3b 0a 20 20 70 43 73 72 2d 3e 69 64 78  r));.  pCsr->idx
2500: 4e 75 6d 20 3d 20 69 64 78 4e 75 6d 3b 0a 0a 20  Num = idxNum;.. 
2510: 20 72 63 20 3d 20 73 71 6c 69 74 65 33 46 74 73   rc = sqlite3Fts
2520: 35 53 74 6f 72 61 67 65 53 74 6d 74 28 70 54 61  5StorageStmt(pTa
2530: 62 2d 3e 70 53 74 6f 72 61 67 65 2c 20 65 53 74  b->pStorage, eSt
2540: 6d 74 2c 20 26 70 43 73 72 2d 3e 70 53 74 6d 74  mt, &pCsr->pStmt
2550: 29 3b 0a 20 20 69 66 28 20 65 50 6c 61 6e 3d 3d  );.  if( ePlan==
2560: 46 54 53 35 5f 50 4c 41 4e 5f 52 4f 57 49 44 20  FTS5_PLAN_ROWID 
2570: 29 7b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 62  ){.    sqlite3_b
2580: 69 6e 64 5f 76 61 6c 75 65 28 70 43 73 72 2d 3e  ind_value(pCsr->
2590: 70 53 74 6d 74 2c 20 31 2c 20 61 70 56 61 6c 5b  pStmt, 1, apVal[
25a0: 30 5d 29 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20  0]);.  }..  if( 
25b0: 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc==SQLITE_OK ){
25c0: 0a 20 20 20 20 72 63 20 3d 20 66 74 73 35 4e 65  .    rc = fts5Ne
25d0: 78 74 4d 65 74 68 6f 64 28 70 43 75 72 73 6f 72  xtMethod(pCursor
25e0: 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20  );.  }.  return 
25f0: 72 63 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 54 68  rc;.}../* .** Th
2600: 69 73 20 69 73 20 74 68 65 20 78 45 6f 66 20 6d  is is the xEof m
2610: 65 74 68 6f 64 20 6f 66 20 74 68 65 20 76 69 72  ethod of the vir
2620: 74 75 61 6c 20 74 61 62 6c 65 2e 20 53 51 4c 69  tual table. SQLi
2630: 74 65 20 63 61 6c 6c 73 20 74 68 69 73 20 0a 2a  te calls this .*
2640: 2a 20 72 6f 75 74 69 6e 65 20 74 6f 20 66 69 6e  * routine to fin
2650: 64 20 6f 75 74 20 69 66 20 69 74 20 68 61 73 20  d out if it has 
2660: 72 65 61 63 68 65 64 20 74 68 65 20 65 6e 64 20  reached the end 
2670: 6f 66 20 61 20 72 65 73 75 6c 74 20 73 65 74 2e  of a result set.
2680: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 66  .*/.static int f
2690: 74 73 35 45 6f 66 4d 65 74 68 6f 64 28 73 71 6c  ts5EofMethod(sql
26a0: 69 74 65 33 5f 76 74 61 62 5f 63 75 72 73 6f 72  ite3_vtab_cursor
26b0: 20 2a 70 43 75 72 73 6f 72 29 7b 0a 20 20 46 74   *pCursor){.  Ft
26c0: 73 35 43 75 72 73 6f 72 20 2a 70 43 73 72 20 3d  s5Cursor *pCsr =
26d0: 20 28 46 74 73 35 43 75 72 73 6f 72 2a 29 70 43   (Fts5Cursor*)pC
26e0: 75 72 73 6f 72 3b 0a 20 20 72 65 74 75 72 6e 20  ursor;.  return 
26f0: 70 43 73 72 2d 3e 62 45 6f 66 3b 0a 7d 0a 0a 2f  pCsr->bEof;.}../
2700: 2a 20 0a 2a 2a 20 54 68 69 73 20 69 73 20 74 68  * .** This is th
2710: 65 20 78 52 6f 77 69 64 20 6d 65 74 68 6f 64 2e  e xRowid method.
2720: 20 54 68 65 20 53 51 4c 69 74 65 20 63 6f 72 65   The SQLite core
2730: 20 63 61 6c 6c 73 20 74 68 69 73 20 72 6f 75 74   calls this rout
2740: 69 6e 65 20 74 6f 0a 2a 2a 20 72 65 74 72 69 65  ine to.** retrie
2750: 76 65 20 74 68 65 20 72 6f 77 69 64 20 66 6f 72  ve the rowid for
2760: 20 74 68 65 20 63 75 72 72 65 6e 74 20 72 6f 77   the current row
2770: 20 6f 66 20 74 68 65 20 72 65 73 75 6c 74 20 73   of the result s
2780: 65 74 2e 20 66 74 73 35 0a 2a 2a 20 65 78 70 6f  et. fts5.** expo
2790: 73 65 73 20 25 5f 63 6f 6e 74 65 6e 74 2e 64 6f  ses %_content.do
27a0: 63 69 64 20 61 73 20 74 68 65 20 72 6f 77 69 64  cid as the rowid
27b0: 20 66 6f 72 20 74 68 65 20 76 69 72 74 75 61 6c   for the virtual
27c0: 20 74 61 62 6c 65 2e 20 54 68 65 0a 2a 2a 20 72   table. The.** r
27d0: 6f 77 69 64 20 73 68 6f 75 6c 64 20 62 65 20 77  owid should be w
27e0: 72 69 74 74 65 6e 20 74 6f 20 2a 70 52 6f 77 69  ritten to *pRowi
27f0: 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  d..*/.static int
2800: 20 66 74 73 35 52 6f 77 69 64 4d 65 74 68 6f 64   fts5RowidMethod
2810: 28 73 71 6c 69 74 65 33 5f 76 74 61 62 5f 63 75  (sqlite3_vtab_cu
2820: 72 73 6f 72 20 2a 70 43 75 72 73 6f 72 2c 20 73  rsor *pCursor, s
2830: 71 6c 69 74 65 5f 69 6e 74 36 34 20 2a 70 52 6f  qlite_int64 *pRo
2840: 77 69 64 29 7b 0a 20 20 46 74 73 35 43 75 72 73  wid){.  Fts5Curs
2850: 6f 72 20 2a 70 43 73 72 20 3d 20 28 46 74 73 35  or *pCsr = (Fts5
2860: 43 75 72 73 6f 72 2a 29 70 43 75 72 73 6f 72 3b  Cursor*)pCursor;
2870: 0a 20 20 69 6e 74 20 65 50 6c 61 6e 20 3d 20 46  .  int ePlan = F
2880: 54 53 35 5f 50 4c 41 4e 28 70 43 73 72 2d 3e 69  TS5_PLAN(pCsr->i
2890: 64 78 4e 75 6d 29 3b 0a 20 20 0a 20 20 61 73 73  dxNum);.  .  ass
28a0: 65 72 74 28 20 70 43 73 72 2d 3e 62 45 6f 66 3d  ert( pCsr->bEof=
28b0: 3d 30 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20  =0 );.  assert( 
28c0: 65 50 6c 61 6e 21 3d 46 54 53 35 5f 50 4c 41 4e  ePlan!=FTS5_PLAN
28d0: 5f 4d 41 54 43 48 20 29 3b 0a 0a 20 20 69 66 28  _MATCH );..  if(
28e0: 20 65 50 6c 61 6e 21 3d 46 54 53 35 5f 50 4c 41   ePlan!=FTS5_PLA
28f0: 4e 5f 4d 41 54 43 48 20 29 7b 0a 20 20 20 20 2a  N_MATCH ){.    *
2900: 70 52 6f 77 69 64 20 3d 20 73 71 6c 69 74 65 33  pRowid = sqlite3
2910: 5f 63 6f 6c 75 6d 6e 5f 69 6e 74 36 34 28 70 43  _column_int64(pC
2920: 73 72 2d 3e 70 53 74 6d 74 2c 20 30 29 3b 0a 20  sr->pStmt, 0);. 
2930: 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 53 51 4c   }..  return SQL
2940: 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 20 0a 2a  ITE_OK;.}../* .*
2950: 2a 20 54 68 69 73 20 69 73 20 74 68 65 20 78 43  * This is the xC
2960: 6f 6c 75 6d 6e 20 6d 65 74 68 6f 64 2c 20 63 61  olumn method, ca
2970: 6c 6c 65 64 20 62 79 20 53 51 4c 69 74 65 20 74  lled by SQLite t
2980: 6f 20 72 65 71 75 65 73 74 20 61 20 76 61 6c 75  o request a valu
2990: 65 20 66 72 6f 6d 0a 2a 2a 20 74 68 65 20 72 6f  e from.** the ro
29a0: 77 20 74 68 61 74 20 74 68 65 20 73 75 70 70 6c  w that the suppl
29b0: 69 65 64 20 63 75 72 73 6f 72 20 63 75 72 72 65  ied cursor curre
29c0: 6e 74 6c 79 20 70 6f 69 6e 74 73 20 74 6f 2e 0a  ntly points to..
29d0: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 66 74  */.static int ft
29e0: 73 35 43 6f 6c 75 6d 6e 4d 65 74 68 6f 64 28 0a  s5ColumnMethod(.
29f0: 20 20 73 71 6c 69 74 65 33 5f 76 74 61 62 5f 63    sqlite3_vtab_c
2a00: 75 72 73 6f 72 20 2a 70 43 75 72 73 6f 72 2c 20  ursor *pCursor, 
2a10: 20 20 2f 2a 20 43 75 72 73 6f 72 20 74 6f 20 72    /* Cursor to r
2a20: 65 74 72 69 65 76 65 20 76 61 6c 75 65 20 66 72  etrieve value fr
2a30: 6f 6d 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f  om */.  sqlite3_
2a40: 63 6f 6e 74 65 78 74 20 2a 70 43 74 78 2c 20 20  context *pCtx,  
2a50: 20 20 20 20 20 20 20 20 2f 2a 20 43 6f 6e 74 65          /* Conte
2a60: 78 74 20 66 6f 72 20 73 71 6c 69 74 65 33 5f 72  xt for sqlite3_r
2a70: 65 73 75 6c 74 5f 78 78 78 28 29 20 63 61 6c 6c  esult_xxx() call
2a80: 73 20 2a 2f 0a 20 20 69 6e 74 20 69 43 6f 6c 20  s */.  int iCol 
2a90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2aa0: 20 20 20 20 20 20 20 2f 2a 20 49 6e 64 65 78 20         /* Index 
2ab0: 6f 66 20 63 6f 6c 75 6d 6e 20 74 6f 20 72 65 61  of column to rea
2ac0: 64 20 76 61 6c 75 65 20 66 72 6f 6d 20 2a 2f 0a  d value from */.
2ad0: 29 7b 0a 20 20 46 74 73 35 43 75 72 73 6f 72 20  ){.  Fts5Cursor 
2ae0: 2a 70 43 73 72 20 3d 20 28 46 74 73 35 43 75 72  *pCsr = (Fts5Cur
2af0: 73 6f 72 2a 29 70 43 75 72 73 6f 72 3b 0a 20 20  sor*)pCursor;.  
2b00: 69 6e 74 20 65 50 6c 61 6e 20 3d 20 46 54 53 35  int ePlan = FTS5
2b10: 5f 50 4c 41 4e 28 70 43 73 72 2d 3e 69 64 78 4e  _PLAN(pCsr->idxN
2b20: 75 6d 29 3b 0a 20 20 0a 20 20 61 73 73 65 72 74  um);.  .  assert
2b30: 28 20 70 43 73 72 2d 3e 62 45 6f 66 3d 3d 30 20  ( pCsr->bEof==0 
2b40: 29 3b 0a 20 20 61 73 73 65 72 74 28 20 65 50 6c  );.  assert( ePl
2b50: 61 6e 21 3d 46 54 53 35 5f 50 4c 41 4e 5f 4d 41  an!=FTS5_PLAN_MA
2b60: 54 43 48 20 29 3b 0a 20 20 69 66 28 20 65 50 6c  TCH );.  if( ePl
2b70: 61 6e 21 3d 46 54 53 35 5f 50 4c 41 4e 5f 4d 41  an!=FTS5_PLAN_MA
2b80: 54 43 48 20 29 7b 0a 20 20 20 20 73 71 6c 69 74  TCH ){.    sqlit
2b90: 65 33 5f 72 65 73 75 6c 74 5f 76 61 6c 75 65 28  e3_result_value(
2ba0: 70 43 74 78 2c 20 73 71 6c 69 74 65 33 5f 63 6f  pCtx, sqlite3_co
2bb0: 6c 75 6d 6e 5f 76 61 6c 75 65 28 70 43 73 72 2d  lumn_value(pCsr-
2bc0: 3e 70 53 74 6d 74 2c 20 69 43 6f 6c 2b 31 29 29  >pStmt, iCol+1))
2bd0: 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 53  ;.  }.  return S
2be0: 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a  QLITE_OK;.}../*.
2bf0: 2a 2a 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e  ** This function
2c00: 20 69 73 20 63 61 6c 6c 65 64 20 74 6f 20 68 61   is called to ha
2c10: 6e 64 6c 65 20 61 6e 20 46 54 53 20 49 4e 53 45  ndle an FTS INSE
2c20: 52 54 20 63 6f 6d 6d 61 6e 64 2e 20 49 6e 20 6f  RT command. In o
2c30: 74 68 65 72 20 77 6f 72 64 73 2c 0a 2a 2a 20 61  ther words,.** a
2c40: 6e 20 49 4e 53 45 52 54 20 73 74 61 74 65 6d 65  n INSERT stateme
2c50: 6e 74 20 6f 66 20 74 68 65 20 66 6f 72 6d 3a 0a  nt of the form:.
2c60: 2a 2a 0a 2a 2a 20 20 20 20 20 49 4e 53 45 52 54  **.**     INSERT
2c70: 20 49 4e 54 4f 20 66 74 73 28 66 74 73 29 20 56   INTO fts(fts) V
2c80: 41 4c 55 45 53 28 24 70 56 61 6c 29 0a 2a 2a 0a  ALUES($pVal).**.
2c90: 2a 2a 20 41 72 67 75 6d 65 6e 74 20 70 56 61 6c  ** Argument pVal
2ca0: 20 69 73 20 74 68 65 20 76 61 6c 75 65 20 61 73   is the value as
2cb0: 73 69 67 6e 65 64 20 74 6f 20 63 6f 6c 75 6d 6e  signed to column
2cc0: 20 22 66 74 73 22 20 62 79 20 74 68 65 20 49 4e   "fts" by the IN
2cd0: 53 45 52 54 20 0a 2a 2a 20 73 74 61 74 65 6d 65  SERT .** stateme
2ce0: 6e 74 2e 20 54 68 69 73 20 66 75 6e 63 74 69 6f  nt. This functio
2cf0: 6e 20 72 65 74 75 72 6e 73 20 53 51 4c 49 54 45  n returns SQLITE
2d00: 5f 4f 4b 20 69 66 20 73 75 63 63 65 73 73 66 75  _OK if successfu
2d10: 6c 2c 20 6f 72 20 61 6e 20 53 51 4c 69 74 65 0a  l, or an SQLite.
2d20: 2a 2a 20 65 72 72 6f 72 20 63 6f 64 65 20 69 66  ** error code if
2d30: 20 61 6e 20 65 72 72 6f 72 20 6f 63 63 75 72 73   an error occurs
2d40: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
2d50: 66 74 73 35 53 70 65 63 69 61 6c 43 6f 6d 6d 61  fts5SpecialComma
2d60: 6e 64 28 46 74 73 35 54 61 62 6c 65 20 2a 70 54  nd(Fts5Table *pT
2d70: 61 62 2c 20 73 71 6c 69 74 65 33 5f 76 61 6c 75  ab, sqlite3_valu
2d80: 65 20 2a 70 56 61 6c 29 7b 0a 20 20 63 6f 6e 73  e *pVal){.  cons
2d90: 74 20 63 68 61 72 20 2a 7a 20 3d 20 28 63 6f 6e  t char *z = (con
2da0: 73 74 20 63 68 61 72 2a 29 73 71 6c 69 74 65 33  st char*)sqlite3
2db0: 5f 76 61 6c 75 65 5f 74 65 78 74 28 70 56 61 6c  _value_text(pVal
2dc0: 29 3b 0a 20 20 69 6e 74 20 6e 20 3d 20 73 71 6c  );.  int n = sql
2dd0: 69 74 65 33 5f 76 61 6c 75 65 5f 62 79 74 65 73  ite3_value_bytes
2de0: 28 70 56 61 6c 29 3b 0a 20 20 69 6e 74 20 72 63  (pVal);.  int rc
2df0: 20 3d 20 53 51 4c 49 54 45 5f 45 52 52 4f 52 3b   = SQLITE_ERROR;
2e00: 0a 0a 20 20 69 66 28 20 30 3d 3d 73 71 6c 69 74  ..  if( 0==sqlit
2e10: 65 33 5f 73 74 72 69 63 6d 70 28 22 69 6e 74 65  e3_stricmp("inte
2e20: 67 72 69 74 79 2d 63 68 65 63 6b 22 2c 20 7a 29  grity-check", z)
2e30: 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 73 71 6c   ){.    rc = sql
2e40: 69 74 65 33 46 74 73 35 53 74 6f 72 61 67 65 49  ite3Fts5StorageI
2e50: 6e 74 65 67 72 69 74 79 28 70 54 61 62 2d 3e 70  ntegrity(pTab->p
2e60: 53 74 6f 72 61 67 65 29 3b 0a 20 20 7d 65 6c 73  Storage);.  }els
2e70: 65 0a 0a 20 20 69 66 28 20 6e 3e 35 20 26 26 20  e..  if( n>5 && 
2e80: 30 3d 3d 73 71 6c 69 74 65 33 5f 73 74 72 6e 69  0==sqlite3_strni
2e90: 63 6d 70 28 22 70 67 73 7a 3d 22 2c 20 7a 2c 20  cmp("pgsz=", z, 
2ea0: 35 29 20 29 7b 0a 20 20 20 20 69 6e 74 20 70 67  5) ){.    int pg
2eb0: 73 7a 20 3d 20 61 74 6f 69 28 26 7a 5b 35 5d 29  sz = atoi(&z[5])
2ec0: 3b 0a 20 20 20 20 69 66 28 20 70 67 73 7a 3c 33  ;.    if( pgsz<3
2ed0: 32 20 29 20 70 67 73 7a 20 3d 20 33 32 3b 0a 20  2 ) pgsz = 32;. 
2ee0: 20 20 20 73 71 6c 69 74 65 33 46 74 73 35 49 6e     sqlite3Fts5In
2ef0: 64 65 78 50 67 73 7a 28 70 54 61 62 2d 3e 70 49  dexPgsz(pTab->pI
2f00: 6e 64 65 78 2c 20 70 67 73 7a 29 3b 0a 20 20 20  ndex, pgsz);.   
2f10: 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b   rc = SQLITE_OK;
2f20: 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 72  .  }..  return r
2f30: 63 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 54 68 69  c;.}../* .** Thi
2f40: 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 74 68  s function is th
2f50: 65 20 69 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e  e implementation
2f60: 20 6f 66 20 74 68 65 20 78 55 70 64 61 74 65 20   of the xUpdate 
2f70: 63 61 6c 6c 62 61 63 6b 20 75 73 65 64 20 62 79  callback used by
2f80: 20 0a 2a 2a 20 46 54 53 33 20 76 69 72 74 75 61   .** FTS3 virtua
2f90: 6c 20 74 61 62 6c 65 73 2e 20 49 74 20 69 73 20  l tables. It is 
2fa0: 69 6e 76 6f 6b 65 64 20 62 79 20 53 51 4c 69 74  invoked by SQLit
2fb0: 65 20 65 61 63 68 20 74 69 6d 65 20 61 20 72 6f  e each time a ro
2fc0: 77 20 69 73 20 74 6f 20 62 65 0a 2a 2a 20 69 6e  w is to be.** in
2fd0: 73 65 72 74 65 64 2c 20 75 70 64 61 74 65 64 20  serted, updated 
2fe0: 6f 72 20 64 65 6c 65 74 65 64 2e 0a 2a 2f 0a 73  or deleted..*/.s
2ff0: 74 61 74 69 63 20 69 6e 74 20 66 74 73 35 55 70  tatic int fts5Up
3000: 64 61 74 65 4d 65 74 68 6f 64 28 0a 20 20 73 71  dateMethod(.  sq
3010: 6c 69 74 65 33 5f 76 74 61 62 20 2a 70 56 74 61  lite3_vtab *pVta
3020: 62 2c 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a  b,            /*
3030: 20 56 69 72 74 75 61 6c 20 74 61 62 6c 65 20 68   Virtual table h
3040: 61 6e 64 6c 65 20 2a 2f 0a 20 20 69 6e 74 20 6e  andle */.  int n
3050: 41 72 67 2c 20 20 20 20 20 20 20 20 20 20 20 20  Arg,            
3060: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 69             /* Si
3070: 7a 65 20 6f 66 20 61 72 67 75 6d 65 6e 74 20 61  ze of argument a
3080: 72 72 61 79 20 2a 2f 0a 20 20 73 71 6c 69 74 65  rray */.  sqlite
3090: 33 5f 76 61 6c 75 65 20 2a 2a 61 70 56 61 6c 2c  3_value **apVal,
30a0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 41 72 72            /* Arr
30b0: 61 79 20 6f 66 20 61 72 67 75 6d 65 6e 74 73 20  ay of arguments 
30c0: 2a 2f 0a 20 20 73 71 6c 69 74 65 5f 69 6e 74 36  */.  sqlite_int6
30d0: 34 20 2a 70 52 6f 77 69 64 20 20 20 20 20 20 20  4 *pRowid       
30e0: 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 54 68 65       /* OUT: The
30f0: 20 61 66 66 65 63 74 65 64 20 28 6f 72 20 65 66   affected (or ef
3100: 66 65 63 74 65 64 29 20 72 6f 77 69 64 20 2a 2f  fected) rowid */
3110: 0a 29 7b 0a 20 20 46 74 73 35 54 61 62 6c 65 20  .){.  Fts5Table 
3120: 2a 70 54 61 62 20 3d 20 28 46 74 73 35 54 61 62  *pTab = (Fts5Tab
3130: 6c 65 2a 29 70 56 74 61 62 3b 0a 20 20 46 74 73  le*)pVtab;.  Fts
3140: 35 43 6f 6e 66 69 67 20 2a 70 43 6f 6e 66 69 67  5Config *pConfig
3150: 20 3d 20 70 54 61 62 2d 3e 70 43 6f 6e 66 69 67   = pTab->pConfig
3160: 3b 0a 20 20 69 6e 74 20 65 54 79 70 65 30 3b 20  ;.  int eType0; 
3170: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3180: 20 20 20 20 2f 2a 20 76 61 6c 75 65 5f 74 79 70      /* value_typ
3190: 65 28 29 20 6f 66 20 61 70 56 61 6c 5b 30 5d 20  e() of apVal[0] 
31a0: 2a 2f 0a 20 20 69 6e 74 20 65 43 6f 6e 66 6c 69  */.  int eConfli
31b0: 63 74 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  ct;             
31c0: 20 20 20 20 20 2f 2a 20 4f 4e 20 43 4f 4e 46 4c       /* ON CONFL
31d0: 49 43 54 20 66 6f 72 20 74 68 69 73 20 44 4d 4c  ICT for this DML
31e0: 20 2a 2f 0a 20 20 69 6e 74 20 72 63 20 3d 20 53   */.  int rc = S
31f0: 51 4c 49 54 45 5f 4f 4b 3b 20 20 20 20 20 20 20  QLITE_OK;       
3200: 20 20 20 20 20 20 2f 2a 20 52 65 74 75 72 6e 20        /* Return 
3210: 63 6f 64 65 20 2a 2f 0a 0a 20 20 61 73 73 65 72  code */..  asser
3220: 74 28 20 6e 41 72 67 3d 3d 31 20 7c 7c 20 6e 41  t( nArg==1 || nA
3230: 72 67 3d 3d 28 32 20 2b 20 70 43 6f 6e 66 69 67  rg==(2 + pConfig
3240: 2d 3e 6e 43 6f 6c 20 2b 20 31 29 20 29 3b 0a 0a  ->nCol + 1) );..
3250: 20 20 69 66 28 20 53 51 4c 49 54 45 5f 4e 55 4c    if( SQLITE_NUL
3260: 4c 21 3d 73 71 6c 69 74 65 33 5f 76 61 6c 75 65  L!=sqlite3_value
3270: 5f 74 79 70 65 28 61 70 56 61 6c 5b 32 20 2b 20  _type(apVal[2 + 
3280: 70 43 6f 6e 66 69 67 2d 3e 6e 43 6f 6c 5d 29 20  pConfig->nCol]) 
3290: 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 66 74  ){.    return ft
32a0: 73 35 53 70 65 63 69 61 6c 43 6f 6d 6d 61 6e 64  s5SpecialCommand
32b0: 28 70 54 61 62 2c 20 61 70 56 61 6c 5b 32 20 2b  (pTab, apVal[2 +
32c0: 20 70 43 6f 6e 66 69 67 2d 3e 6e 43 6f 6c 5d 29   pConfig->nCol])
32d0: 3b 0a 20 20 7d 0a 0a 20 20 65 54 79 70 65 30 20  ;.  }..  eType0 
32e0: 3d 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f  = sqlite3_value_
32f0: 74 79 70 65 28 61 70 56 61 6c 5b 30 5d 29 3b 0a  type(apVal[0]);.
3300: 20 20 65 43 6f 6e 66 6c 69 63 74 20 3d 20 73 71    eConflict = sq
3310: 6c 69 74 65 33 5f 76 74 61 62 5f 6f 6e 5f 63 6f  lite3_vtab_on_co
3320: 6e 66 6c 69 63 74 28 70 43 6f 6e 66 69 67 2d 3e  nflict(pConfig->
3330: 64 62 29 3b 0a 0a 20 20 61 73 73 65 72 74 28 20  db);..  assert( 
3340: 65 54 79 70 65 30 3d 3d 53 51 4c 49 54 45 5f 49  eType0==SQLITE_I
3350: 4e 54 45 47 45 52 20 7c 7c 20 65 54 79 70 65 30  NTEGER || eType0
3360: 3d 3d 53 51 4c 49 54 45 5f 4e 55 4c 4c 20 29 3b  ==SQLITE_NULL );
3370: 0a 20 20 69 66 28 20 65 54 79 70 65 30 3d 3d 53  .  if( eType0==S
3380: 51 4c 49 54 45 5f 49 4e 54 45 47 45 52 20 29 7b  QLITE_INTEGER ){
3390: 0a 20 20 20 20 69 36 34 20 69 44 65 6c 20 3d 20  .    i64 iDel = 
33a0: 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 69 6e  sqlite3_value_in
33b0: 74 36 34 28 61 70 56 61 6c 5b 30 5d 29 3b 20 20  t64(apVal[0]);  
33c0: 20 20 2f 2a 20 52 6f 77 69 64 20 74 6f 20 64 65    /* Rowid to de
33d0: 6c 65 74 65 20 2a 2f 0a 20 20 20 20 72 63 20 3d  lete */.    rc =
33e0: 20 73 71 6c 69 74 65 33 46 74 73 35 53 74 6f 72   sqlite3Fts5Stor
33f0: 61 67 65 44 65 6c 65 74 65 28 70 54 61 62 2d 3e  ageDelete(pTab->
3400: 70 53 74 6f 72 61 67 65 2c 20 69 44 65 6c 29 3b  pStorage, iDel);
3410: 0a 20 20 7d 0a 0a 20 20 69 66 28 20 72 63 3d 3d  .  }..  if( rc==
3420: 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20 6e 41 72  SQLITE_OK && nAr
3430: 67 3e 31 20 29 7b 0a 20 20 20 20 72 63 20 3d 20  g>1 ){.    rc = 
3440: 73 71 6c 69 74 65 33 46 74 73 35 53 74 6f 72 61  sqlite3Fts5Stora
3450: 67 65 49 6e 73 65 72 74 28 70 54 61 62 2d 3e 70  geInsert(pTab->p
3460: 53 74 6f 72 61 67 65 2c 20 61 70 56 61 6c 2c 20  Storage, apVal, 
3470: 65 43 6f 6e 66 6c 69 63 74 2c 20 70 52 6f 77 69  eConflict, pRowi
3480: 64 29 3b 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72  d);.  }..  retur
3490: 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49  n rc;.}../*.** I
34a0: 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66  mplementation of
34b0: 20 78 53 79 6e 63 28 29 20 6d 65 74 68 6f 64 2e   xSync() method.
34c0: 20 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20   .*/.static int 
34d0: 66 74 73 35 53 79 6e 63 4d 65 74 68 6f 64 28 73  fts5SyncMethod(s
34e0: 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 70 56 74  qlite3_vtab *pVt
34f0: 61 62 29 7b 0a 20 20 69 6e 74 20 72 63 3b 0a 20  ab){.  int rc;. 
3500: 20 46 74 73 35 54 61 62 6c 65 20 2a 70 54 61 62   Fts5Table *pTab
3510: 20 3d 20 28 46 74 73 35 54 61 62 6c 65 2a 29 70   = (Fts5Table*)p
3520: 56 74 61 62 3b 0a 20 20 72 63 20 3d 20 73 71 6c  Vtab;.  rc = sql
3530: 69 74 65 33 46 74 73 35 49 6e 64 65 78 53 79 6e  ite3Fts5IndexSyn
3540: 63 28 70 54 61 62 2d 3e 70 49 6e 64 65 78 29 3b  c(pTab->pIndex);
3550: 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a  .  return rc;.}.
3560: 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74  ./*.** Implement
3570: 61 74 69 6f 6e 20 6f 66 20 78 42 65 67 69 6e 28  ation of xBegin(
3580: 29 20 6d 65 74 68 6f 64 2e 20 0a 2a 2f 0a 73 74  ) method. .*/.st
3590: 61 74 69 63 20 69 6e 74 20 66 74 73 35 42 65 67  atic int fts5Beg
35a0: 69 6e 4d 65 74 68 6f 64 28 73 71 6c 69 74 65 33  inMethod(sqlite3
35b0: 5f 76 74 61 62 20 2a 70 56 74 61 62 29 7b 0a 20  _vtab *pVtab){. 
35c0: 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f   return SQLITE_O
35d0: 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c  K;.}../*.** Impl
35e0: 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66 20 78 43  ementation of xC
35f0: 6f 6d 6d 69 74 28 29 20 6d 65 74 68 6f 64 2e 20  ommit() method. 
3600: 54 68 69 73 20 69 73 20 61 20 6e 6f 2d 6f 70 2e  This is a no-op.
3610: 20 54 68 65 20 63 6f 6e 74 65 6e 74 73 20 6f 66   The contents of
3620: 0a 2a 2a 20 74 68 65 20 70 65 6e 64 69 6e 67 2d  .** the pending-
3630: 74 65 72 6d 73 20 68 61 73 68 2d 74 61 62 6c 65  terms hash-table
3640: 20 68 61 76 65 20 61 6c 72 65 61 64 79 20 62 65   have already be
3650: 65 6e 20 66 6c 75 73 68 65 64 20 69 6e 74 6f 20  en flushed into 
3660: 74 68 65 20 64 61 74 61 62 61 73 65 0a 2a 2a 20  the database.** 
3670: 62 79 20 66 74 73 35 53 79 6e 63 4d 65 74 68 6f  by fts5SyncMetho
3680: 64 28 29 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  d()..*/.static i
3690: 6e 74 20 66 74 73 35 43 6f 6d 6d 69 74 4d 65 74  nt fts5CommitMet
36a0: 68 6f 64 28 73 71 6c 69 74 65 33 5f 76 74 61 62  hod(sqlite3_vtab
36b0: 20 2a 70 56 74 61 62 29 7b 0a 20 20 72 65 74 75   *pVtab){.  retu
36c0: 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a  rn SQLITE_OK;.}.
36d0: 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74  ./*.** Implement
36e0: 61 74 69 6f 6e 20 6f 66 20 78 52 6f 6c 6c 62 61  ation of xRollba
36f0: 63 6b 28 29 2e 20 44 69 73 63 61 72 64 20 74 68  ck(). Discard th
3700: 65 20 63 6f 6e 74 65 6e 74 73 20 6f 66 20 74 68  e contents of th
3710: 65 20 70 65 6e 64 69 6e 67 2d 74 65 72 6d 73 0a  e pending-terms.
3720: 2a 2a 20 68 61 73 68 2d 74 61 62 6c 65 2e 20 41  ** hash-table. A
3730: 6e 79 20 63 68 61 6e 67 65 73 20 6d 61 64 65 20  ny changes made 
3740: 74 6f 20 74 68 65 20 64 61 74 61 62 61 73 65 20  to the database 
3750: 61 72 65 20 72 65 76 65 72 74 65 64 20 62 79 20  are reverted by 
3760: 53 51 4c 69 74 65 2e 0a 2a 2f 0a 73 74 61 74 69  SQLite..*/.stati
3770: 63 20 69 6e 74 20 66 74 73 35 52 6f 6c 6c 62 61  c int fts5Rollba
3780: 63 6b 4d 65 74 68 6f 64 28 73 71 6c 69 74 65 33  ckMethod(sqlite3
3790: 5f 76 74 61 62 20 2a 70 56 74 61 62 29 7b 0a 20  _vtab *pVtab){. 
37a0: 20 46 74 73 35 54 61 62 6c 65 20 2a 70 54 61 62   Fts5Table *pTab
37b0: 20 3d 20 28 46 74 73 35 54 61 62 6c 65 2a 29 70   = (Fts5Table*)p
37c0: 56 74 61 62 3b 0a 20 20 69 6e 74 20 72 63 3b 0a  Vtab;.  int rc;.
37d0: 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 46 74    rc = sqlite3Ft
37e0: 73 35 49 6e 64 65 78 52 6f 6c 6c 62 61 63 6b 28  s5IndexRollback(
37f0: 70 54 61 62 2d 3e 70 49 6e 64 65 78 29 3b 0a 20  pTab->pIndex);. 
3800: 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f   return rc;.}../
3810: 2a 0a 2a 2a 20 54 68 69 73 20 72 6f 75 74 69 6e  *.** This routin
3820: 65 20 69 6d 70 6c 65 6d 65 6e 74 73 20 74 68 65  e implements the
3830: 20 78 46 69 6e 64 46 75 6e 63 74 69 6f 6e 20 6d   xFindFunction m
3840: 65 74 68 6f 64 20 66 6f 72 20 74 68 65 20 46 54  ethod for the FT
3850: 53 33 0a 2a 2a 20 76 69 72 74 75 61 6c 20 74 61  S3.** virtual ta
3860: 62 6c 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  ble..*/.static i
3870: 6e 74 20 66 74 73 35 46 69 6e 64 46 75 6e 63 74  nt fts5FindFunct
3880: 69 6f 6e 4d 65 74 68 6f 64 28 0a 20 20 73 71 6c  ionMethod(.  sql
3890: 69 74 65 33 5f 76 74 61 62 20 2a 70 56 74 61 62  ite3_vtab *pVtab
38a0: 2c 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20  ,            /* 
38b0: 56 69 72 74 75 61 6c 20 74 61 62 6c 65 20 68 61  Virtual table ha
38c0: 6e 64 6c 65 20 2a 2f 0a 20 20 69 6e 74 20 6e 41  ndle */.  int nA
38d0: 72 67 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  rg,             
38e0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d            /* Num
38f0: 62 65 72 20 6f 66 20 53 51 4c 20 66 75 6e 63 74  ber of SQL funct
3900: 69 6f 6e 20 61 72 67 75 6d 65 6e 74 73 20 2a 2f  ion arguments */
3910: 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a  .  const char *z
3920: 4e 61 6d 65 2c 20 20 20 20 20 20 20 20 20 20 20  Name,           
3930: 20 20 20 2f 2a 20 4e 61 6d 65 20 6f 66 20 53 51     /* Name of SQ
3940: 4c 20 66 75 6e 63 74 69 6f 6e 20 2a 2f 0a 20 20  L function */.  
3950: 76 6f 69 64 20 28 2a 2a 70 78 46 75 6e 63 29 28  void (**pxFunc)(
3960: 73 71 6c 69 74 65 33 5f 63 6f 6e 74 65 78 74 2a  sqlite3_context*
3970: 2c 69 6e 74 2c 73 71 6c 69 74 65 33 5f 76 61 6c  ,int,sqlite3_val
3980: 75 65 2a 2a 29 2c 20 2f 2a 20 4f 55 54 3a 20 52  ue**), /* OUT: R
3990: 65 73 75 6c 74 20 2a 2f 0a 20 20 76 6f 69 64 20  esult */.  void 
39a0: 2a 2a 70 70 41 72 67 20 20 20 20 20 20 20 20 20  **ppArg         
39b0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 55 6e             /* Un
39c0: 75 73 65 64 20 2a 2f 0a 29 7b 0a 20 20 2f 2a 20  used */.){.  /* 
39d0: 4e 6f 20 66 75 6e 63 74 69 6f 6e 20 6f 66 20 74  No function of t
39e0: 68 65 20 73 70 65 63 69 66 69 65 64 20 6e 61 6d  he specified nam
39f0: 65 20 77 61 73 20 66 6f 75 6e 64 2e 20 52 65 74  e was found. Ret
3a00: 75 72 6e 20 30 2e 20 2a 2f 0a 20 20 72 65 74 75  urn 0. */.  retu
3a10: 72 6e 20 30 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49  rn 0;.}../*.** I
3a20: 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66  mplementation of
3a30: 20 46 54 53 33 20 78 52 65 6e 61 6d 65 20 6d 65   FTS3 xRename me
3a40: 74 68 6f 64 2e 20 52 65 6e 61 6d 65 20 61 6e 20  thod. Rename an 
3a50: 66 74 73 35 20 74 61 62 6c 65 2e 0a 2a 2f 0a 73  fts5 table..*/.s
3a60: 74 61 74 69 63 20 69 6e 74 20 66 74 73 35 52 65  tatic int fts5Re
3a70: 6e 61 6d 65 4d 65 74 68 6f 64 28 0a 20 20 73 71  nameMethod(.  sq
3a80: 6c 69 74 65 33 5f 76 74 61 62 20 2a 70 56 74 61  lite3_vtab *pVta
3a90: 62 2c 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a  b,            /*
3aa0: 20 56 69 72 74 75 61 6c 20 74 61 62 6c 65 20 68   Virtual table h
3ab0: 61 6e 64 6c 65 20 2a 2f 0a 20 20 63 6f 6e 73 74  andle */.  const
3ac0: 20 63 68 61 72 20 2a 7a 4e 61 6d 65 20 20 20 20   char *zName    
3ad0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 65             /* Ne
3ae0: 77 20 6e 61 6d 65 20 6f 66 20 74 61 62 6c 65 20  w name of table 
3af0: 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d  */.){.  int rc =
3b00: 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 72 65   SQLITE_OK;.  re
3b10: 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a  turn rc;.}../*.*
3b20: 2a 20 54 68 65 20 78 53 61 76 65 70 6f 69 6e 74  * The xSavepoint
3b30: 28 29 20 6d 65 74 68 6f 64 2e 0a 2a 2a 0a 2a 2a  () method..**.**
3b40: 20 46 6c 75 73 68 20 74 68 65 20 63 6f 6e 74 65   Flush the conte
3b50: 6e 74 73 20 6f 66 20 74 68 65 20 70 65 6e 64 69  nts of the pendi
3b60: 6e 67 2d 74 65 72 6d 73 20 74 61 62 6c 65 20 74  ng-terms table t
3b70: 6f 20 64 69 73 6b 2e 0a 2a 2f 0a 73 74 61 74 69  o disk..*/.stati
3b80: 63 20 69 6e 74 20 66 74 73 35 53 61 76 65 70 6f  c int fts5Savepo
3b90: 69 6e 74 4d 65 74 68 6f 64 28 73 71 6c 69 74 65  intMethod(sqlite
3ba0: 33 5f 76 74 61 62 20 2a 70 56 74 61 62 2c 20 69  3_vtab *pVtab, i
3bb0: 6e 74 20 69 53 61 76 65 70 6f 69 6e 74 29 7b 0a  nt iSavepoint){.
3bc0: 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54    int rc = SQLIT
3bd0: 45 5f 4f 4b 3b 0a 20 20 72 65 74 75 72 6e 20 72  E_OK;.  return r
3be0: 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 65 20  c;.}../*.** The 
3bf0: 78 52 65 6c 65 61 73 65 28 29 20 6d 65 74 68 6f  xRelease() metho
3c00: 64 2e 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20 69 73  d..**.** This is
3c10: 20 61 20 6e 6f 2d 6f 70 2e 0a 2a 2f 0a 73 74 61   a no-op..*/.sta
3c20: 74 69 63 20 69 6e 74 20 66 74 73 35 52 65 6c 65  tic int fts5Rele
3c30: 61 73 65 4d 65 74 68 6f 64 28 73 71 6c 69 74 65  aseMethod(sqlite
3c40: 33 5f 76 74 61 62 20 2a 70 56 74 61 62 2c 20 69  3_vtab *pVtab, i
3c50: 6e 74 20 69 53 61 76 65 70 6f 69 6e 74 29 7b 0a  nt iSavepoint){.
3c60: 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f    return SQLITE_
3c70: 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 65  OK;.}../*.** The
3c80: 20 78 52 6f 6c 6c 62 61 63 6b 54 6f 28 29 20 6d   xRollbackTo() m
3c90: 65 74 68 6f 64 2e 0a 2a 2a 0a 2a 2a 20 44 69 73  ethod..**.** Dis
3ca0: 63 61 72 64 20 74 68 65 20 63 6f 6e 74 65 6e 74  card the content
3cb0: 73 20 6f 66 20 74 68 65 20 70 65 6e 64 69 6e 67  s of the pending
3cc0: 20 74 65 72 6d 73 20 74 61 62 6c 65 2e 0a 2a 2f   terms table..*/
3cd0: 0a 73 74 61 74 69 63 20 69 6e 74 20 66 74 73 35  .static int fts5
3ce0: 52 6f 6c 6c 62 61 63 6b 54 6f 4d 65 74 68 6f 64  RollbackToMethod
3cf0: 28 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 70  (sqlite3_vtab *p
3d00: 56 74 61 62 2c 20 69 6e 74 20 69 53 61 76 65 70  Vtab, int iSavep
3d10: 6f 69 6e 74 29 7b 0a 20 20 72 65 74 75 72 6e 20  oint){.  return 
3d20: 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 73 74  SQLITE_OK;.}..st
3d30: 61 74 69 63 20 63 6f 6e 73 74 20 73 71 6c 69 74  atic const sqlit
3d40: 65 33 5f 6d 6f 64 75 6c 65 20 66 74 73 35 4d 6f  e3_module fts5Mo
3d50: 64 75 6c 65 20 3d 20 7b 0a 20 20 2f 2a 20 69 56  dule = {.  /* iV
3d60: 65 72 73 69 6f 6e 20 20 20 20 20 20 2a 2f 20 32  ersion      */ 2
3d70: 2c 0a 20 20 2f 2a 20 78 43 72 65 61 74 65 20 20  ,.  /* xCreate  
3d80: 20 20 20 20 20 2a 2f 20 66 74 73 35 43 72 65 61       */ fts5Crea
3d90: 74 65 4d 65 74 68 6f 64 2c 0a 20 20 2f 2a 20 78  teMethod,.  /* x
3da0: 43 6f 6e 6e 65 63 74 20 20 20 20 20 20 2a 2f 20  Connect      */ 
3db0: 66 74 73 35 43 6f 6e 6e 65 63 74 4d 65 74 68 6f  fts5ConnectMetho
3dc0: 64 2c 0a 20 20 2f 2a 20 78 42 65 73 74 49 6e 64  d,.  /* xBestInd
3dd0: 65 78 20 20 20 20 2a 2f 20 66 74 73 35 42 65 73  ex    */ fts5Bes
3de0: 74 49 6e 64 65 78 4d 65 74 68 6f 64 2c 0a 20 20  tIndexMethod,.  
3df0: 2f 2a 20 78 44 69 73 63 6f 6e 6e 65 63 74 20 20  /* xDisconnect  
3e00: 20 2a 2f 20 66 74 73 35 44 69 73 63 6f 6e 6e 65   */ fts5Disconne
3e10: 63 74 4d 65 74 68 6f 64 2c 0a 20 20 2f 2a 20 78  ctMethod,.  /* x
3e20: 44 65 73 74 72 6f 79 20 20 20 20 20 20 2a 2f 20  Destroy      */ 
3e30: 66 74 73 35 44 65 73 74 72 6f 79 4d 65 74 68 6f  fts5DestroyMetho
3e40: 64 2c 0a 20 20 2f 2a 20 78 4f 70 65 6e 20 20 20  d,.  /* xOpen   
3e50: 20 20 20 20 20 20 2a 2f 20 66 74 73 35 4f 70 65        */ fts5Ope
3e60: 6e 4d 65 74 68 6f 64 2c 0a 20 20 2f 2a 20 78 43  nMethod,.  /* xC
3e70: 6c 6f 73 65 20 20 20 20 20 20 20 20 2a 2f 20 66  lose        */ f
3e80: 74 73 35 43 6c 6f 73 65 4d 65 74 68 6f 64 2c 0a  ts5CloseMethod,.
3e90: 20 20 2f 2a 20 78 46 69 6c 74 65 72 20 20 20 20    /* xFilter    
3ea0: 20 20 20 2a 2f 20 66 74 73 35 46 69 6c 74 65 72     */ fts5Filter
3eb0: 4d 65 74 68 6f 64 2c 0a 20 20 2f 2a 20 78 4e 65  Method,.  /* xNe
3ec0: 78 74 20 20 20 20 20 20 20 20 20 2a 2f 20 66 74  xt         */ ft
3ed0: 73 35 4e 65 78 74 4d 65 74 68 6f 64 2c 0a 20 20  s5NextMethod,.  
3ee0: 2f 2a 20 78 45 6f 66 20 20 20 20 20 20 20 20 20  /* xEof         
3ef0: 20 2a 2f 20 66 74 73 35 45 6f 66 4d 65 74 68 6f   */ fts5EofMetho
3f00: 64 2c 0a 20 20 2f 2a 20 78 43 6f 6c 75 6d 6e 20  d,.  /* xColumn 
3f10: 20 20 20 20 20 20 2a 2f 20 66 74 73 35 43 6f 6c        */ fts5Col
3f20: 75 6d 6e 4d 65 74 68 6f 64 2c 0a 20 20 2f 2a 20  umnMethod,.  /* 
3f30: 78 52 6f 77 69 64 20 20 20 20 20 20 20 20 2a 2f  xRowid        */
3f40: 20 66 74 73 35 52 6f 77 69 64 4d 65 74 68 6f 64   fts5RowidMethod
3f50: 2c 0a 20 20 2f 2a 20 78 55 70 64 61 74 65 20 20  ,.  /* xUpdate  
3f60: 20 20 20 20 20 2a 2f 20 66 74 73 35 55 70 64 61       */ fts5Upda
3f70: 74 65 4d 65 74 68 6f 64 2c 0a 20 20 2f 2a 20 78  teMethod,.  /* x
3f80: 42 65 67 69 6e 20 20 20 20 20 20 20 20 2a 2f 20  Begin        */ 
3f90: 66 74 73 35 42 65 67 69 6e 4d 65 74 68 6f 64 2c  fts5BeginMethod,
3fa0: 0a 20 20 2f 2a 20 78 53 79 6e 63 20 20 20 20 20  .  /* xSync     
3fb0: 20 20 20 20 2a 2f 20 66 74 73 35 53 79 6e 63 4d      */ fts5SyncM
3fc0: 65 74 68 6f 64 2c 0a 20 20 2f 2a 20 78 43 6f 6d  ethod,.  /* xCom
3fd0: 6d 69 74 20 20 20 20 20 20 20 2a 2f 20 66 74 73  mit       */ fts
3fe0: 35 43 6f 6d 6d 69 74 4d 65 74 68 6f 64 2c 0a 20  5CommitMethod,. 
3ff0: 20 2f 2a 20 78 52 6f 6c 6c 62 61 63 6b 20 20 20   /* xRollback   
4000: 20 20 2a 2f 20 66 74 73 35 52 6f 6c 6c 62 61 63    */ fts5Rollbac
4010: 6b 4d 65 74 68 6f 64 2c 0a 20 20 2f 2a 20 78 46  kMethod,.  /* xF
4020: 69 6e 64 46 75 6e 63 74 69 6f 6e 20 2a 2f 20 66  indFunction */ f
4030: 74 73 35 46 69 6e 64 46 75 6e 63 74 69 6f 6e 4d  ts5FindFunctionM
4040: 65 74 68 6f 64 2c 0a 20 20 2f 2a 20 78 52 65 6e  ethod,.  /* xRen
4050: 61 6d 65 20 20 20 20 20 20 20 2a 2f 20 66 74 73  ame       */ fts
4060: 35 52 65 6e 61 6d 65 4d 65 74 68 6f 64 2c 0a 20  5RenameMethod,. 
4070: 20 2f 2a 20 78 53 61 76 65 70 6f 69 6e 74 20 20   /* xSavepoint  
4080: 20 20 2a 2f 20 66 74 73 35 53 61 76 65 70 6f 69    */ fts5Savepoi
4090: 6e 74 4d 65 74 68 6f 64 2c 0a 20 20 2f 2a 20 78  ntMethod,.  /* x
40a0: 52 65 6c 65 61 73 65 20 20 20 20 20 20 2a 2f 20  Release      */ 
40b0: 66 74 73 35 52 65 6c 65 61 73 65 4d 65 74 68 6f  fts5ReleaseMetho
40c0: 64 2c 0a 20 20 2f 2a 20 78 52 6f 6c 6c 62 61 63  d,.  /* xRollbac
40d0: 6b 54 6f 20 20 20 2a 2f 20 66 74 73 35 52 6f 6c  kTo   */ fts5Rol
40e0: 6c 62 61 63 6b 54 6f 4d 65 74 68 6f 64 2c 0a 7d  lbackToMethod,.}
40f0: 3b 0a 0a 69 6e 74 20 73 71 6c 69 74 65 33 46 74  ;..int sqlite3Ft
4100: 73 35 49 6e 69 74 28 73 71 6c 69 74 65 33 20 2a  s5Init(sqlite3 *
4110: 64 62 29 7b 0a 20 20 69 6e 74 20 72 63 3b 0a 20  db){.  int rc;. 
4120: 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 63 72   rc = sqlite3_cr
4130: 65 61 74 65 5f 6d 6f 64 75 6c 65 5f 76 32 28 64  eate_module_v2(d
4140: 62 2c 20 22 66 74 73 35 22 2c 20 26 66 74 73 35  b, "fts5", &fts5
4150: 4d 6f 64 75 6c 65 2c 20 30 2c 20 30 29 3b 0a 20  Module, 0, 0);. 
4160: 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
4170: 4f 4b 20 29 20 72 63 20 3d 20 73 71 6c 69 74 65  OK ) rc = sqlite
4180: 33 46 74 73 35 49 6e 64 65 78 49 6e 69 74 28 64  3Fts5IndexInit(d
4190: 62 29 3b 0a 20 20 69 66 28 20 72 63 3d 3d 53 51  b);.  if( rc==SQ
41a0: 4c 49 54 45 5f 4f 4b 20 29 20 72 63 20 3d 20 73  LITE_OK ) rc = s
41b0: 71 6c 69 74 65 33 46 74 73 35 45 78 70 72 49 6e  qlite3Fts5ExprIn
41c0: 69 74 28 64 62 29 3b 0a 20 20 72 65 74 75 72 6e  it(db);.  return
41d0: 20 72 63 3b 0a 7d 0a 0a                           rc;.}..