/ Hex Artifact Content
Login

Artifact 57e3f2b1a612961a27c944d6b8821028ec5fdb541d7e6b841785003ac3b0b43a:


0000: 2f 2a 0a 2a 2a 20 32 30 31 34 20 4d 61 79 20 33  /*.** 2014 May 3
0010: 31 0a 2a 2a 0a 2a 2a 20 54 68 65 20 61 75 74 68  1.**.** 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 2f 0a 0a 0a 0a 23  *****.**.*/....#
0180: 69 6e 63 6c 75 64 65 20 22 66 74 73 35 49 6e 74  include "fts5Int
0190: 2e 68 22 0a 0a 73 74 72 75 63 74 20 46 74 73 35  .h"..struct Fts5
01a0: 53 74 6f 72 61 67 65 20 7b 0a 20 20 46 74 73 35  Storage {.  Fts5
01b0: 43 6f 6e 66 69 67 20 2a 70 43 6f 6e 66 69 67 3b  Config *pConfig;
01c0: 0a 20 20 46 74 73 35 49 6e 64 65 78 20 2a 70 49  .  Fts5Index *pI
01d0: 6e 64 65 78 3b 0a 20 20 69 6e 74 20 62 54 6f 74  ndex;.  int bTot
01e0: 61 6c 73 56 61 6c 69 64 3b 20 20 20 20 20 20 20  alsValid;       
01f0: 20 20 20 20 20 20 20 20 2f 2a 20 54 72 75 65 20          /* True 
0200: 69 66 20 6e 54 6f 74 61 6c 52 6f 77 2f 61 54 6f  if nTotalRow/aTo
0210: 74 61 6c 53 69 7a 65 5b 5d 20 61 72 65 20 76 61  talSize[] are va
0220: 6c 69 64 20 2a 2f 0a 20 20 69 36 34 20 6e 54 6f  lid */.  i64 nTo
0230: 74 61 6c 52 6f 77 3b 20 20 20 20 20 20 20 20 20  talRow;         
0240: 20 20 20 20 20 20 20 20 20 2f 2a 20 54 6f 74 61           /* Tota
0250: 6c 20 6e 75 6d 62 65 72 20 6f 66 20 72 6f 77 73  l number of rows
0260: 20 69 6e 20 46 54 53 20 74 61 62 6c 65 20 2a 2f   in FTS table */
0270: 0a 20 20 69 36 34 20 2a 61 54 6f 74 61 6c 53 69  .  i64 *aTotalSi
0280: 7a 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  ze;             
0290: 20 20 20 2f 2a 20 54 6f 74 61 6c 20 73 69 7a 65     /* Total size
02a0: 73 20 6f 66 20 65 61 63 68 20 63 6f 6c 75 6d 6e  s of each column
02b0: 20 2a 2f 20 0a 20 20 73 71 6c 69 74 65 33 5f 73   */ .  sqlite3_s
02c0: 74 6d 74 20 2a 61 53 74 6d 74 5b 31 31 5d 3b 0a  tmt *aStmt[11];.
02d0: 7d 3b 0a 0a 0a 23 69 66 20 46 54 53 35 5f 53 54  };...#if FTS5_ST
02e0: 4d 54 5f 53 43 41 4e 5f 41 53 43 21 3d 30 20 0a  MT_SCAN_ASC!=0 .
02f0: 23 20 65 72 72 6f 72 20 22 46 54 53 35 5f 53 54  # error "FTS5_ST
0300: 4d 54 5f 53 43 41 4e 5f 41 53 43 20 6d 69 73 6d  MT_SCAN_ASC mism
0310: 61 74 63 68 22 20 0a 23 65 6e 64 69 66 0a 23 69  atch" .#endif.#i
0320: 66 20 46 54 53 35 5f 53 54 4d 54 5f 53 43 41 4e  f FTS5_STMT_SCAN
0330: 5f 44 45 53 43 21 3d 31 20 0a 23 20 65 72 72 6f  _DESC!=1 .# erro
0340: 72 20 22 46 54 53 35 5f 53 54 4d 54 5f 53 43 41  r "FTS5_STMT_SCA
0350: 4e 5f 44 45 53 43 20 6d 69 73 6d 61 74 63 68 22  N_DESC mismatch"
0360: 20 0a 23 65 6e 64 69 66 0a 23 69 66 20 46 54 53   .#endif.#if FTS
0370: 35 5f 53 54 4d 54 5f 4c 4f 4f 4b 55 50 21 3d 32  5_STMT_LOOKUP!=2
0380: 0a 23 20 65 72 72 6f 72 20 22 46 54 53 35 5f 53  .# error "FTS5_S
0390: 54 4d 54 5f 4c 4f 4f 4b 55 50 20 6d 69 73 6d 61  TMT_LOOKUP misma
03a0: 74 63 68 22 20 0a 23 65 6e 64 69 66 0a 0a 23 64  tch" .#endif..#d
03b0: 65 66 69 6e 65 20 46 54 53 35 5f 53 54 4d 54 5f  efine FTS5_STMT_
03c0: 49 4e 53 45 52 54 5f 43 4f 4e 54 45 4e 54 20 20  INSERT_CONTENT  
03d0: 33 0a 23 64 65 66 69 6e 65 20 46 54 53 35 5f 53  3.#define FTS5_S
03e0: 54 4d 54 5f 52 45 50 4c 41 43 45 5f 43 4f 4e 54  TMT_REPLACE_CONT
03f0: 45 4e 54 20 34 0a 23 64 65 66 69 6e 65 20 46 54  ENT 4.#define FT
0400: 53 35 5f 53 54 4d 54 5f 44 45 4c 45 54 45 5f 43  S5_STMT_DELETE_C
0410: 4f 4e 54 45 4e 54 20 20 35 0a 23 64 65 66 69 6e  ONTENT  5.#defin
0420: 65 20 46 54 53 35 5f 53 54 4d 54 5f 52 45 50 4c  e FTS5_STMT_REPL
0430: 41 43 45 5f 44 4f 43 53 49 5a 45 20 20 36 0a 23  ACE_DOCSIZE  6.#
0440: 64 65 66 69 6e 65 20 46 54 53 35 5f 53 54 4d 54  define FTS5_STMT
0450: 5f 44 45 4c 45 54 45 5f 44 4f 43 53 49 5a 45 20  _DELETE_DOCSIZE 
0460: 20 37 0a 23 64 65 66 69 6e 65 20 46 54 53 35 5f   7.#define FTS5_
0470: 53 54 4d 54 5f 4c 4f 4f 4b 55 50 5f 44 4f 43 53  STMT_LOOKUP_DOCS
0480: 49 5a 45 20 20 38 0a 23 64 65 66 69 6e 65 20 46  IZE  8.#define F
0490: 54 53 35 5f 53 54 4d 54 5f 52 45 50 4c 41 43 45  TS5_STMT_REPLACE
04a0: 5f 43 4f 4e 46 49 47 20 39 0a 23 64 65 66 69 6e  _CONFIG 9.#defin
04b0: 65 20 46 54 53 35 5f 53 54 4d 54 5f 53 43 41 4e  e FTS5_STMT_SCAN
04c0: 20 31 30 0a 0a 2f 2a 0a 2a 2a 20 50 72 65 70 61   10../*.** Prepa
04d0: 72 65 20 74 68 65 20 74 77 6f 20 69 6e 73 65 72  re the two inser
04e0: 74 20 73 74 61 74 65 6d 65 6e 74 73 20 2d 20 46  t statements - F
04f0: 74 73 35 53 74 6f 72 61 67 65 2e 70 49 6e 73 65  ts5Storage.pInse
0500: 72 74 43 6f 6e 74 65 6e 74 20 61 6e 64 0a 2a 2a  rtContent and.**
0510: 20 46 74 73 35 53 74 6f 72 61 67 65 2e 70 49 6e   Fts5Storage.pIn
0520: 73 65 72 74 44 6f 63 73 69 7a 65 20 2d 20 69 66  sertDocsize - if
0530: 20 74 68 65 79 20 68 61 76 65 20 6e 6f 74 20 61   they have not a
0540: 6c 72 65 61 64 79 20 62 65 65 6e 20 70 72 65 70  lready been prep
0550: 61 72 65 64 2e 0a 2a 2a 20 52 65 74 75 72 6e 20  ared..** Return 
0560: 53 51 4c 49 54 45 5f 4f 4b 20 69 66 20 73 75 63  SQLITE_OK if suc
0570: 63 65 73 73 66 75 6c 2c 20 6f 72 20 61 6e 20 53  cessful, or an S
0580: 51 4c 69 74 65 20 65 72 72 6f 72 20 63 6f 64 65  QLite error code
0590: 20 69 66 20 61 6e 20 65 72 72 6f 72 0a 2a 2a 20   if an error.** 
05a0: 6f 63 63 75 72 73 2e 0a 2a 2f 0a 73 74 61 74 69  occurs..*/.stati
05b0: 63 20 69 6e 74 20 66 74 73 35 53 74 6f 72 61 67  c int fts5Storag
05c0: 65 47 65 74 53 74 6d 74 28 0a 20 20 46 74 73 35  eGetStmt(.  Fts5
05d0: 53 74 6f 72 61 67 65 20 2a 70 2c 20 20 20 20 20  Storage *p,     
05e0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53              /* S
05f0: 74 6f 72 61 67 65 20 68 61 6e 64 6c 65 20 2a 2f  torage handle */
0600: 0a 20 20 69 6e 74 20 65 53 74 6d 74 2c 20 20 20  .  int eStmt,   
0610: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0620: 20 20 20 2f 2a 20 46 54 53 35 5f 53 54 4d 54 5f     /* FTS5_STMT_
0630: 58 58 58 20 63 6f 6e 73 74 61 6e 74 20 2a 2f 0a  XXX constant */.
0640: 20 20 73 71 6c 69 74 65 33 5f 73 74 6d 74 20 2a    sqlite3_stmt *
0650: 2a 70 70 53 74 6d 74 2c 20 20 20 20 20 20 20 20  *ppStmt,        
0660: 20 20 2f 2a 20 4f 55 54 3a 20 50 72 65 70 61 72    /* OUT: Prepar
0670: 65 64 20 73 74 61 74 65 6d 65 6e 74 20 68 61 6e  ed statement han
0680: 64 6c 65 20 2a 2f 0a 20 20 63 68 61 72 20 2a 2a  dle */.  char **
0690: 70 7a 45 72 72 4d 73 67 20 20 20 20 20 20 20 20  pzErrMsg        
06a0: 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a           /* OUT:
06b0: 20 45 72 72 6f 72 20 6d 65 73 73 61 67 65 20 28   Error message (
06c0: 69 66 20 61 6e 79 29 20 2a 2f 0a 29 7b 0a 20 20  if any) */.){.  
06d0: 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f  int rc = SQLITE_
06e0: 4f 4b 3b 0a 0a 20 20 2f 2a 20 49 66 20 74 68 65  OK;..  /* If the
06f0: 72 65 20 69 73 20 6e 6f 20 25 5f 64 6f 63 73 69  re is no %_docsi
0700: 7a 65 20 74 61 62 6c 65 2c 20 74 68 65 72 65 20  ze table, there 
0710: 73 68 6f 75 6c 64 20 62 65 20 6e 6f 20 72 65 71  should be no req
0720: 75 65 73 74 73 20 66 6f 72 20 0a 20 20 2a 2a 20  uests for .  ** 
0730: 73 74 61 74 65 6d 65 6e 74 73 20 74 6f 20 6f 70  statements to op
0740: 65 72 61 74 65 20 6f 6e 20 69 74 2e 20 20 2a 2f  erate on it.  */
0750: 0a 20 20 61 73 73 65 72 74 28 20 70 2d 3e 70 43  .  assert( p->pC
0760: 6f 6e 66 69 67 2d 3e 62 43 6f 6c 75 6d 6e 73 69  onfig->bColumnsi
0770: 7a 65 20 7c 7c 20 28 0a 20 20 20 20 20 20 20 20  ze || (.        
0780: 65 53 74 6d 74 21 3d 46 54 53 35 5f 53 54 4d 54  eStmt!=FTS5_STMT
0790: 5f 52 45 50 4c 41 43 45 5f 44 4f 43 53 49 5a 45  _REPLACE_DOCSIZE
07a0: 20 0a 20 20 20 20 20 26 26 20 65 53 74 6d 74 21   .     && eStmt!
07b0: 3d 46 54 53 35 5f 53 54 4d 54 5f 44 45 4c 45 54  =FTS5_STMT_DELET
07c0: 45 5f 44 4f 43 53 49 5a 45 20 0a 20 20 20 20 20  E_DOCSIZE .     
07d0: 26 26 20 65 53 74 6d 74 21 3d 46 54 53 35 5f 53  && eStmt!=FTS5_S
07e0: 54 4d 54 5f 4c 4f 4f 4b 55 50 5f 44 4f 43 53 49  TMT_LOOKUP_DOCSI
07f0: 5a 45 20 0a 20 20 29 29 3b 0a 0a 20 20 61 73 73  ZE .  ));..  ass
0800: 65 72 74 28 20 65 53 74 6d 74 3e 3d 30 20 26 26  ert( eStmt>=0 &&
0810: 20 65 53 74 6d 74 3c 41 72 72 61 79 53 69 7a 65   eStmt<ArraySize
0820: 28 70 2d 3e 61 53 74 6d 74 29 20 29 3b 0a 20 20  (p->aStmt) );.  
0830: 69 66 28 20 70 2d 3e 61 53 74 6d 74 5b 65 53 74  if( p->aStmt[eSt
0840: 6d 74 5d 3d 3d 30 20 29 7b 0a 20 20 20 20 63 6f  mt]==0 ){.    co
0850: 6e 73 74 20 63 68 61 72 20 2a 61 7a 53 74 6d 74  nst char *azStmt
0860: 5b 5d 20 3d 20 7b 0a 20 20 20 20 20 20 22 53 45  [] = {.      "SE
0870: 4c 45 43 54 20 25 73 20 46 52 4f 4d 20 25 73 20  LECT %s FROM %s 
0880: 54 20 57 48 45 52 45 20 54 2e 25 51 20 3e 3d 20  T WHERE T.%Q >= 
0890: 3f 20 41 4e 44 20 54 2e 25 51 20 3c 3d 20 3f 20  ? AND T.%Q <= ? 
08a0: 4f 52 44 45 52 20 42 59 20 54 2e 25 51 20 41 53  ORDER BY T.%Q AS
08b0: 43 22 2c 0a 20 20 20 20 20 20 22 53 45 4c 45 43  C",.      "SELEC
08c0: 54 20 25 73 20 46 52 4f 4d 20 25 73 20 54 20 57  T %s FROM %s T W
08d0: 48 45 52 45 20 54 2e 25 51 20 3c 3d 20 3f 20 41  HERE T.%Q <= ? A
08e0: 4e 44 20 54 2e 25 51 20 3e 3d 20 3f 20 4f 52 44  ND T.%Q >= ? ORD
08f0: 45 52 20 42 59 20 54 2e 25 51 20 44 45 53 43 22  ER BY T.%Q DESC"
0900: 2c 0a 20 20 20 20 20 20 22 53 45 4c 45 43 54 20  ,.      "SELECT 
0910: 25 73 20 46 52 4f 4d 20 25 73 20 54 20 57 48 45  %s FROM %s T WHE
0920: 52 45 20 54 2e 25 51 3d 3f 22 2c 20 20 20 20 20  RE T.%Q=?",     
0930: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4c 4f 4f            /* LOO
0940: 4b 55 50 20 20 2a 2f 0a 0a 20 20 20 20 20 20 22  KUP  */..      "
0950: 49 4e 53 45 52 54 20 49 4e 54 4f 20 25 51 2e 27  INSERT INTO %Q.'
0960: 25 71 5f 63 6f 6e 74 65 6e 74 27 20 56 41 4c 55  %q_content' VALU
0970: 45 53 28 25 73 29 22 2c 20 20 20 20 20 20 20 20  ES(%s)",        
0980: 20 2f 2a 20 49 4e 53 45 52 54 5f 43 4f 4e 54 45   /* INSERT_CONTE
0990: 4e 54 20 20 2a 2f 0a 20 20 20 20 20 20 22 52 45  NT  */.      "RE
09a0: 50 4c 41 43 45 20 49 4e 54 4f 20 25 51 2e 27 25  PLACE INTO %Q.'%
09b0: 71 5f 63 6f 6e 74 65 6e 74 27 20 56 41 4c 55 45  q_content' VALUE
09c0: 53 28 25 73 29 22 2c 20 20 20 20 20 20 20 20 2f  S(%s)",        /
09d0: 2a 20 52 45 50 4c 41 43 45 5f 43 4f 4e 54 45 4e  * REPLACE_CONTEN
09e0: 54 20 2a 2f 0a 20 20 20 20 20 20 22 44 45 4c 45  T */.      "DELE
09f0: 54 45 20 46 52 4f 4d 20 25 51 2e 27 25 71 5f 63  TE FROM %Q.'%q_c
0a00: 6f 6e 74 65 6e 74 27 20 57 48 45 52 45 20 69 64  ontent' WHERE id
0a10: 3d 3f 22 2c 20 20 20 20 20 20 20 20 20 2f 2a 20  =?",         /* 
0a20: 44 45 4c 45 54 45 5f 43 4f 4e 54 45 4e 54 20 20  DELETE_CONTENT  
0a30: 2a 2f 0a 20 20 20 20 20 20 22 52 45 50 4c 41 43  */.      "REPLAC
0a40: 45 20 49 4e 54 4f 20 25 51 2e 27 25 71 5f 64 6f  E INTO %Q.'%q_do
0a50: 63 73 69 7a 65 27 20 56 41 4c 55 45 53 28 3f 2c  csize' VALUES(?,
0a60: 3f 29 22 2c 20 20 20 20 20 20 20 2f 2a 20 52 45  ?)",       /* RE
0a70: 50 4c 41 43 45 5f 44 4f 43 53 49 5a 45 20 20 2a  PLACE_DOCSIZE  *
0a80: 2f 0a 20 20 20 20 20 20 22 44 45 4c 45 54 45 20  /.      "DELETE 
0a90: 46 52 4f 4d 20 25 51 2e 27 25 71 5f 64 6f 63 73  FROM %Q.'%q_docs
0aa0: 69 7a 65 27 20 57 48 45 52 45 20 69 64 3d 3f 22  ize' WHERE id=?"
0ab0: 2c 20 20 20 20 20 20 20 20 20 2f 2a 20 44 45 4c  ,         /* DEL
0ac0: 45 54 45 5f 44 4f 43 53 49 5a 45 20 20 2a 2f 0a  ETE_DOCSIZE  */.
0ad0: 0a 20 20 20 20 20 20 22 53 45 4c 45 43 54 20 73  .      "SELECT s
0ae0: 7a 20 46 52 4f 4d 20 25 51 2e 27 25 71 5f 64 6f  z FROM %Q.'%q_do
0af0: 63 73 69 7a 65 27 20 57 48 45 52 45 20 69 64 3d  csize' WHERE id=
0b00: 3f 22 2c 20 20 20 20 20 20 2f 2a 20 4c 4f 4f 4b  ?",      /* LOOK
0b10: 55 50 5f 44 4f 43 53 49 5a 45 20 20 2a 2f 0a 0a  UP_DOCSIZE  */..
0b20: 20 20 20 20 20 20 22 52 45 50 4c 41 43 45 20 49        "REPLACE I
0b30: 4e 54 4f 20 25 51 2e 27 25 71 5f 63 6f 6e 66 69  NTO %Q.'%q_confi
0b40: 67 27 20 56 41 4c 55 45 53 28 3f 2c 3f 29 22 2c  g' VALUES(?,?)",
0b50: 20 20 20 20 20 20 20 20 2f 2a 20 52 45 50 4c 41          /* REPLA
0b60: 43 45 5f 43 4f 4e 46 49 47 20 2a 2f 0a 20 20 20  CE_CONFIG */.   
0b70: 20 20 20 22 53 45 4c 45 43 54 20 25 73 20 46 52     "SELECT %s FR
0b80: 4f 4d 20 25 73 20 41 53 20 54 22 2c 20 20 20 20  OM %s AS T",    
0b90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0ba0: 20 20 20 20 20 2f 2a 20 53 43 41 4e 20 2a 2f 0a       /* SCAN */.
0bb0: 20 20 20 20 7d 3b 0a 20 20 20 20 46 74 73 35 43      };.    Fts5C
0bc0: 6f 6e 66 69 67 20 2a 70 43 20 3d 20 70 2d 3e 70  onfig *pC = p->p
0bd0: 43 6f 6e 66 69 67 3b 0a 20 20 20 20 63 68 61 72  Config;.    char
0be0: 20 2a 7a 53 71 6c 20 3d 20 30 3b 0a 0a 20 20 20   *zSql = 0;..   
0bf0: 20 73 77 69 74 63 68 28 20 65 53 74 6d 74 20 29   switch( eStmt )
0c00: 7b 0a 20 20 20 20 20 20 63 61 73 65 20 46 54 53  {.      case FTS
0c10: 35 5f 53 54 4d 54 5f 53 43 41 4e 3a 0a 20 20 20  5_STMT_SCAN:.   
0c20: 20 20 20 20 20 7a 53 71 6c 20 3d 20 73 71 6c 69       zSql = sqli
0c30: 74 65 33 5f 6d 70 72 69 6e 74 66 28 61 7a 53 74  te3_mprintf(azSt
0c40: 6d 74 5b 65 53 74 6d 74 5d 2c 20 0a 20 20 20 20  mt[eStmt], .    
0c50: 20 20 20 20 20 20 20 20 70 43 2d 3e 7a 43 6f 6e          pC->zCon
0c60: 74 65 6e 74 45 78 70 72 6c 69 73 74 2c 20 70 43  tentExprlist, pC
0c70: 2d 3e 7a 43 6f 6e 74 65 6e 74 0a 20 20 20 20 20  ->zContent.     
0c80: 20 20 20 29 3b 0a 20 20 20 20 20 20 20 20 62 72     );.        br
0c90: 65 61 6b 3b 0a 0a 20 20 20 20 20 20 63 61 73 65  eak;..      case
0ca0: 20 46 54 53 35 5f 53 54 4d 54 5f 53 43 41 4e 5f   FTS5_STMT_SCAN_
0cb0: 41 53 43 3a 0a 20 20 20 20 20 20 63 61 73 65 20  ASC:.      case 
0cc0: 46 54 53 35 5f 53 54 4d 54 5f 53 43 41 4e 5f 44  FTS5_STMT_SCAN_D
0cd0: 45 53 43 3a 0a 20 20 20 20 20 20 20 20 7a 53 71  ESC:.        zSq
0ce0: 6c 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72 69  l = sqlite3_mpri
0cf0: 6e 74 66 28 61 7a 53 74 6d 74 5b 65 53 74 6d 74  ntf(azStmt[eStmt
0d00: 5d 2c 20 70 43 2d 3e 7a 43 6f 6e 74 65 6e 74 45  ], pC->zContentE
0d10: 78 70 72 6c 69 73 74 2c 20 0a 20 20 20 20 20 20  xprlist, .      
0d20: 20 20 20 20 20 20 70 43 2d 3e 7a 43 6f 6e 74 65        pC->zConte
0d30: 6e 74 2c 20 70 43 2d 3e 7a 43 6f 6e 74 65 6e 74  nt, pC->zContent
0d40: 52 6f 77 69 64 2c 20 70 43 2d 3e 7a 43 6f 6e 74  Rowid, pC->zCont
0d50: 65 6e 74 52 6f 77 69 64 2c 0a 20 20 20 20 20 20  entRowid,.      
0d60: 20 20 20 20 20 20 70 43 2d 3e 7a 43 6f 6e 74 65        pC->zConte
0d70: 6e 74 52 6f 77 69 64 0a 20 20 20 20 20 20 20 20  ntRowid.        
0d80: 29 3b 0a 20 20 20 20 20 20 20 20 62 72 65 61 6b  );.        break
0d90: 3b 0a 0a 20 20 20 20 20 20 63 61 73 65 20 46 54  ;..      case FT
0da0: 53 35 5f 53 54 4d 54 5f 4c 4f 4f 4b 55 50 3a 0a  S5_STMT_LOOKUP:.
0db0: 20 20 20 20 20 20 20 20 7a 53 71 6c 20 3d 20 73          zSql = s
0dc0: 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 61  qlite3_mprintf(a
0dd0: 7a 53 74 6d 74 5b 65 53 74 6d 74 5d 2c 20 0a 20  zStmt[eStmt], . 
0de0: 20 20 20 20 20 20 20 20 20 20 20 70 43 2d 3e 7a             pC->z
0df0: 43 6f 6e 74 65 6e 74 45 78 70 72 6c 69 73 74 2c  ContentExprlist,
0e00: 20 70 43 2d 3e 7a 43 6f 6e 74 65 6e 74 2c 20 70   pC->zContent, p
0e10: 43 2d 3e 7a 43 6f 6e 74 65 6e 74 52 6f 77 69 64  C->zContentRowid
0e20: 0a 20 20 20 20 20 20 20 20 29 3b 0a 20 20 20 20  .        );.    
0e30: 20 20 20 20 62 72 65 61 6b 3b 0a 0a 20 20 20 20      break;..    
0e40: 20 20 63 61 73 65 20 46 54 53 35 5f 53 54 4d 54    case FTS5_STMT
0e50: 5f 49 4e 53 45 52 54 5f 43 4f 4e 54 45 4e 54 3a  _INSERT_CONTENT:
0e60: 20 0a 20 20 20 20 20 20 63 61 73 65 20 46 54 53   .      case FTS
0e70: 35 5f 53 54 4d 54 5f 52 45 50 4c 41 43 45 5f 43  5_STMT_REPLACE_C
0e80: 4f 4e 54 45 4e 54 3a 20 7b 0a 20 20 20 20 20 20  ONTENT: {.      
0e90: 20 20 69 6e 74 20 6e 43 6f 6c 20 3d 20 70 43 2d    int nCol = pC-
0ea0: 3e 6e 43 6f 6c 20 2b 20 31 3b 0a 20 20 20 20 20  >nCol + 1;.     
0eb0: 20 20 20 63 68 61 72 20 2a 7a 42 69 6e 64 3b 0a     char *zBind;.
0ec0: 20 20 20 20 20 20 20 20 69 6e 74 20 69 3b 0a 0a          int i;..
0ed0: 20 20 20 20 20 20 20 20 7a 42 69 6e 64 20 3d 20          zBind = 
0ee0: 73 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63 36 34  sqlite3_malloc64
0ef0: 28 31 20 2b 20 6e 43 6f 6c 2a 32 29 3b 0a 20 20  (1 + nCol*2);.  
0f00: 20 20 20 20 20 20 69 66 28 20 7a 42 69 6e 64 20        if( zBind 
0f10: 29 7b 0a 20 20 20 20 20 20 20 20 20 20 66 6f 72  ){.          for
0f20: 28 69 3d 30 3b 20 69 3c 6e 43 6f 6c 3b 20 69 2b  (i=0; i<nCol; i+
0f30: 2b 29 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20  +){.            
0f40: 7a 42 69 6e 64 5b 69 2a 32 5d 20 3d 20 27 3f 27  zBind[i*2] = '?'
0f50: 3b 0a 20 20 20 20 20 20 20 20 20 20 20 20 7a 42  ;.            zB
0f60: 69 6e 64 5b 69 2a 32 20 2b 20 31 5d 20 3d 20 27  ind[i*2 + 1] = '
0f70: 2c 27 3b 0a 20 20 20 20 20 20 20 20 20 20 7d 0a  ,';.          }.
0f80: 20 20 20 20 20 20 20 20 20 20 7a 42 69 6e 64 5b            zBind[
0f90: 69 2a 32 2d 31 5d 20 3d 20 27 5c 30 27 3b 0a 20  i*2-1] = '\0';. 
0fa0: 20 20 20 20 20 20 20 20 20 7a 53 71 6c 20 3d 20           zSql = 
0fb0: 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28  sqlite3_mprintf(
0fc0: 61 7a 53 74 6d 74 5b 65 53 74 6d 74 5d 2c 20 70  azStmt[eStmt], p
0fd0: 43 2d 3e 7a 44 62 2c 20 70 43 2d 3e 7a 4e 61 6d  C->zDb, pC->zNam
0fe0: 65 2c 20 7a 42 69 6e 64 29 3b 0a 20 20 20 20 20  e, zBind);.     
0ff0: 20 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65       sqlite3_fre
1000: 65 28 7a 42 69 6e 64 29 3b 0a 20 20 20 20 20 20  e(zBind);.      
1010: 20 20 7d 0a 20 20 20 20 20 20 20 20 62 72 65 61    }.        brea
1020: 6b 3b 0a 20 20 20 20 20 20 7d 0a 0a 20 20 20 20  k;.      }..    
1030: 20 20 64 65 66 61 75 6c 74 3a 0a 20 20 20 20 20    default:.     
1040: 20 20 20 7a 53 71 6c 20 3d 20 73 71 6c 69 74 65     zSql = sqlite
1050: 33 5f 6d 70 72 69 6e 74 66 28 61 7a 53 74 6d 74  3_mprintf(azStmt
1060: 5b 65 53 74 6d 74 5d 2c 20 70 43 2d 3e 7a 44 62  [eStmt], pC->zDb
1070: 2c 20 70 43 2d 3e 7a 4e 61 6d 65 29 3b 0a 20 20  , pC->zName);.  
1080: 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20        break;.   
1090: 20 7d 0a 0a 20 20 20 20 69 66 28 20 7a 53 71 6c   }..    if( zSql
10a0: 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 72 63 20  ==0 ){.      rc 
10b0: 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a  = SQLITE_NOMEM;.
10c0: 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20      }else{.     
10d0: 20 69 6e 74 20 66 20 3d 20 53 51 4c 49 54 45 5f   int f = SQLITE_
10e0: 50 52 45 50 41 52 45 5f 50 45 52 53 49 53 54 45  PREPARE_PERSISTE
10f0: 4e 54 3b 0a 20 20 20 20 20 20 69 66 28 20 65 53  NT;.      if( eS
1100: 74 6d 74 3e 46 54 53 35 5f 53 54 4d 54 5f 4c 4f  tmt>FTS5_STMT_LO
1110: 4f 4b 55 50 20 29 20 66 20 7c 3d 20 53 51 4c 49  OKUP ) f |= SQLI
1120: 54 45 5f 50 52 45 50 41 52 45 5f 4e 4f 5f 56 54  TE_PREPARE_NO_VT
1130: 41 42 3b 0a 20 20 20 20 20 20 72 63 20 3d 20 73  AB;.      rc = s
1140: 71 6c 69 74 65 33 5f 70 72 65 70 61 72 65 5f 76  qlite3_prepare_v
1150: 33 28 70 43 2d 3e 64 62 2c 20 7a 53 71 6c 2c 20  3(pC->db, zSql, 
1160: 2d 31 2c 20 66 2c 20 26 70 2d 3e 61 53 74 6d 74  -1, f, &p->aStmt
1170: 5b 65 53 74 6d 74 5d 2c 20 30 29 3b 0a 20 20 20  [eStmt], 0);.   
1180: 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28     sqlite3_free(
1190: 7a 53 71 6c 29 3b 0a 20 20 20 20 20 20 69 66 28  zSql);.      if(
11a0: 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 26   rc!=SQLITE_OK &
11b0: 26 20 70 7a 45 72 72 4d 73 67 20 29 7b 0a 20 20  & pzErrMsg ){.  
11c0: 20 20 20 20 20 20 2a 70 7a 45 72 72 4d 73 67 20        *pzErrMsg 
11d0: 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74  = sqlite3_mprint
11e0: 66 28 22 25 73 22 2c 20 73 71 6c 69 74 65 33 5f  f("%s", sqlite3_
11f0: 65 72 72 6d 73 67 28 70 43 2d 3e 64 62 29 29 3b  errmsg(pC->db));
1200: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20  .      }.    }. 
1210: 20 7d 0a 0a 20 20 2a 70 70 53 74 6d 74 20 3d 20   }..  *ppStmt = 
1220: 70 2d 3e 61 53 74 6d 74 5b 65 53 74 6d 74 5d 3b  p->aStmt[eStmt];
1230: 0a 20 20 73 71 6c 69 74 65 33 5f 72 65 73 65 74  .  sqlite3_reset
1240: 28 2a 70 70 53 74 6d 74 29 3b 0a 20 20 72 65 74  (*ppStmt);.  ret
1250: 75 72 6e 20 72 63 3b 0a 7d 0a 0a 0a 73 74 61 74  urn rc;.}...stat
1260: 69 63 20 69 6e 74 20 66 74 73 35 45 78 65 63 50  ic int fts5ExecP
1270: 72 69 6e 74 66 28 0a 20 20 73 71 6c 69 74 65 33  rintf(.  sqlite3
1280: 20 2a 64 62 2c 0a 20 20 63 68 61 72 20 2a 2a 70   *db,.  char **p
1290: 7a 45 72 72 2c 0a 20 20 63 6f 6e 73 74 20 63 68  zErr,.  const ch
12a0: 61 72 20 2a 7a 46 6f 72 6d 61 74 2c 0a 20 20 2e  ar *zFormat,.  .
12b0: 2e 2e 0a 29 7b 0a 20 20 69 6e 74 20 72 63 3b 0a  ...){.  int rc;.
12c0: 20 20 76 61 5f 6c 69 73 74 20 61 70 3b 20 20 20    va_list ap;   
12d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
12e0: 20 20 2f 2a 20 2e 2e 2e 20 70 72 69 6e 74 66 20    /* ... printf 
12f0: 61 72 67 75 6d 65 6e 74 73 20 2a 2f 0a 20 20 63  arguments */.  c
1300: 68 61 72 20 2a 7a 53 71 6c 3b 0a 0a 20 20 76 61  har *zSql;..  va
1310: 5f 73 74 61 72 74 28 61 70 2c 20 7a 46 6f 72 6d  _start(ap, zForm
1320: 61 74 29 3b 0a 20 20 7a 53 71 6c 20 3d 20 73 71  at);.  zSql = sq
1330: 6c 69 74 65 33 5f 76 6d 70 72 69 6e 74 66 28 7a  lite3_vmprintf(z
1340: 46 6f 72 6d 61 74 2c 20 61 70 29 3b 0a 0a 20 20  Format, ap);..  
1350: 69 66 28 20 7a 53 71 6c 3d 3d 30 20 29 7b 0a 20  if( zSql==0 ){. 
1360: 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4e     rc = SQLITE_N
1370: 4f 4d 45 4d 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20  OMEM;.  }else{. 
1380: 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f     rc = sqlite3_
1390: 65 78 65 63 28 64 62 2c 20 7a 53 71 6c 2c 20 30  exec(db, zSql, 0
13a0: 2c 20 30 2c 20 70 7a 45 72 72 29 3b 0a 20 20 20  , 0, pzErr);.   
13b0: 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 7a 53   sqlite3_free(zS
13c0: 71 6c 29 3b 0a 20 20 7d 0a 0a 20 20 76 61 5f 65  ql);.  }..  va_e
13d0: 6e 64 28 61 70 29 3b 0a 20 20 72 65 74 75 72 6e  nd(ap);.  return
13e0: 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 44 72   rc;.}../*.** Dr
13f0: 6f 70 20 61 6c 6c 20 73 68 61 64 6f 77 20 74 61  op all shadow ta
1400: 62 6c 65 73 2e 20 52 65 74 75 72 6e 20 53 51 4c  bles. Return SQL
1410: 49 54 45 5f 4f 4b 20 69 66 20 73 75 63 63 65 73  ITE_OK if succes
1420: 73 66 75 6c 20 6f 72 20 61 6e 20 53 51 4c 69 74  sful or an SQLit
1430: 65 20 65 72 72 6f 72 0a 2a 2a 20 63 6f 64 65 20  e error.** code 
1440: 6f 74 68 65 72 77 69 73 65 2e 0a 2a 2f 0a 69 6e  otherwise..*/.in
1450: 74 20 73 71 6c 69 74 65 33 46 74 73 35 44 72 6f  t sqlite3Fts5Dro
1460: 70 41 6c 6c 28 46 74 73 35 43 6f 6e 66 69 67 20  pAll(Fts5Config 
1470: 2a 70 43 6f 6e 66 69 67 29 7b 0a 20 20 69 6e 74  *pConfig){.  int
1480: 20 72 63 20 3d 20 66 74 73 35 45 78 65 63 50 72   rc = fts5ExecPr
1490: 69 6e 74 66 28 70 43 6f 6e 66 69 67 2d 3e 64 62  intf(pConfig->db
14a0: 2c 20 30 2c 20 0a 20 20 20 20 20 20 22 44 52 4f  , 0, .      "DRO
14b0: 50 20 54 41 42 4c 45 20 49 46 20 45 58 49 53 54  P TABLE IF EXIST
14c0: 53 20 25 51 2e 27 25 71 5f 64 61 74 61 27 3b 22  S %Q.'%q_data';"
14d0: 0a 20 20 20 20 20 20 22 44 52 4f 50 20 54 41 42  .      "DROP TAB
14e0: 4c 45 20 49 46 20 45 58 49 53 54 53 20 25 51 2e  LE IF EXISTS %Q.
14f0: 27 25 71 5f 69 64 78 27 3b 22 0a 20 20 20 20 20  '%q_idx';".     
1500: 20 22 44 52 4f 50 20 54 41 42 4c 45 20 49 46 20   "DROP TABLE IF 
1510: 45 58 49 53 54 53 20 25 51 2e 27 25 71 5f 63 6f  EXISTS %Q.'%q_co
1520: 6e 66 69 67 27 3b 22 2c 0a 20 20 20 20 20 20 70  nfig';",.      p
1530: 43 6f 6e 66 69 67 2d 3e 7a 44 62 2c 20 70 43 6f  Config->zDb, pCo
1540: 6e 66 69 67 2d 3e 7a 4e 61 6d 65 2c 0a 20 20 20  nfig->zName,.   
1550: 20 20 20 70 43 6f 6e 66 69 67 2d 3e 7a 44 62 2c     pConfig->zDb,
1560: 20 70 43 6f 6e 66 69 67 2d 3e 7a 4e 61 6d 65 2c   pConfig->zName,
1570: 0a 20 20 20 20 20 20 70 43 6f 6e 66 69 67 2d 3e  .      pConfig->
1580: 7a 44 62 2c 20 70 43 6f 6e 66 69 67 2d 3e 7a 4e  zDb, pConfig->zN
1590: 61 6d 65 0a 20 20 29 3b 0a 20 20 69 66 28 20 72  ame.  );.  if( r
15a0: 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20  c==SQLITE_OK && 
15b0: 70 43 6f 6e 66 69 67 2d 3e 62 43 6f 6c 75 6d 6e  pConfig->bColumn
15c0: 73 69 7a 65 20 29 7b 0a 20 20 20 20 72 63 20 3d  size ){.    rc =
15d0: 20 66 74 73 35 45 78 65 63 50 72 69 6e 74 66 28   fts5ExecPrintf(
15e0: 70 43 6f 6e 66 69 67 2d 3e 64 62 2c 20 30 2c 20  pConfig->db, 0, 
15f0: 0a 20 20 20 20 20 20 20 20 22 44 52 4f 50 20 54  .        "DROP T
1600: 41 42 4c 45 20 49 46 20 45 58 49 53 54 53 20 25  ABLE IF EXISTS %
1610: 51 2e 27 25 71 5f 64 6f 63 73 69 7a 65 27 3b 22  Q.'%q_docsize';"
1620: 2c 0a 20 20 20 20 20 20 20 20 70 43 6f 6e 66 69  ,.        pConfi
1630: 67 2d 3e 7a 44 62 2c 20 70 43 6f 6e 66 69 67 2d  g->zDb, pConfig-
1640: 3e 7a 4e 61 6d 65 0a 20 20 20 20 29 3b 0a 20 20  >zName.    );.  
1650: 7d 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49  }.  if( rc==SQLI
1660: 54 45 5f 4f 4b 20 26 26 20 70 43 6f 6e 66 69 67  TE_OK && pConfig
1670: 2d 3e 65 43 6f 6e 74 65 6e 74 3d 3d 46 54 53 35  ->eContent==FTS5
1680: 5f 43 4f 4e 54 45 4e 54 5f 4e 4f 52 4d 41 4c 20  _CONTENT_NORMAL 
1690: 29 7b 0a 20 20 20 20 72 63 20 3d 20 66 74 73 35  ){.    rc = fts5
16a0: 45 78 65 63 50 72 69 6e 74 66 28 70 43 6f 6e 66  ExecPrintf(pConf
16b0: 69 67 2d 3e 64 62 2c 20 30 2c 20 0a 20 20 20 20  ig->db, 0, .    
16c0: 20 20 20 20 22 44 52 4f 50 20 54 41 42 4c 45 20      "DROP TABLE 
16d0: 49 46 20 45 58 49 53 54 53 20 25 51 2e 27 25 71  IF EXISTS %Q.'%q
16e0: 5f 63 6f 6e 74 65 6e 74 27 3b 22 2c 0a 20 20 20  _content';",.   
16f0: 20 20 20 20 20 70 43 6f 6e 66 69 67 2d 3e 7a 44       pConfig->zD
1700: 62 2c 20 70 43 6f 6e 66 69 67 2d 3e 7a 4e 61 6d  b, pConfig->zNam
1710: 65 0a 20 20 20 20 29 3b 0a 20 20 7d 0a 20 20 72  e.    );.  }.  r
1720: 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 73 74 61  eturn rc;.}..sta
1730: 74 69 63 20 76 6f 69 64 20 66 74 73 35 53 74 6f  tic void fts5Sto
1740: 72 61 67 65 52 65 6e 61 6d 65 4f 6e 65 28 0a 20  rageRenameOne(. 
1750: 20 46 74 73 35 43 6f 6e 66 69 67 20 2a 70 43 6f   Fts5Config *pCo
1760: 6e 66 69 67 2c 20 20 20 20 20 20 20 20 20 20 20  nfig,           
1770: 20 2f 2a 20 43 75 72 72 65 6e 74 20 46 54 53 35   /* Current FTS5
1780: 20 63 6f 6e 66 69 67 75 72 61 74 69 6f 6e 20 2a   configuration *
1790: 2f 0a 20 20 69 6e 74 20 2a 70 52 63 2c 20 20 20  /.  int *pRc,   
17a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
17b0: 20 20 20 20 2f 2a 20 49 4e 2f 4f 55 54 3a 20 45      /* IN/OUT: E
17c0: 72 72 6f 72 20 63 6f 64 65 20 2a 2f 0a 20 20 63  rror code */.  c
17d0: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 54 61 69 6c  onst char *zTail
17e0: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f  ,              /
17f0: 2a 20 54 61 69 6c 20 6f 66 20 74 61 62 6c 65 20  * Tail of table 
1800: 6e 61 6d 65 20 65 2e 67 2e 20 22 64 61 74 61 22  name e.g. "data"
1810: 2c 20 22 63 6f 6e 66 69 67 22 20 2a 2f 0a 20 20  , "config" */.  
1820: 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 4e 61 6d  const char *zNam
1830: 65 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  e               
1840: 2f 2a 20 4e 65 77 20 6e 61 6d 65 20 6f 66 20 46  /* New name of F
1850: 54 53 35 20 74 61 62 6c 65 20 2a 2f 0a 29 7b 0a  TS5 table */.){.
1860: 20 20 69 66 28 20 2a 70 52 63 3d 3d 53 51 4c 49    if( *pRc==SQLI
1870: 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 2a 70 52  TE_OK ){.    *pR
1880: 63 20 3d 20 66 74 73 35 45 78 65 63 50 72 69 6e  c = fts5ExecPrin
1890: 74 66 28 70 43 6f 6e 66 69 67 2d 3e 64 62 2c 20  tf(pConfig->db, 
18a0: 30 2c 20 0a 20 20 20 20 20 20 20 20 22 41 4c 54  0, .        "ALT
18b0: 45 52 20 54 41 42 4c 45 20 25 51 2e 27 25 71 5f  ER TABLE %Q.'%q_
18c0: 25 73 27 20 52 45 4e 41 4d 45 20 54 4f 20 27 25  %s' RENAME TO '%
18d0: 71 5f 25 73 27 3b 22 2c 0a 20 20 20 20 20 20 20  q_%s';",.       
18e0: 20 70 43 6f 6e 66 69 67 2d 3e 7a 44 62 2c 20 70   pConfig->zDb, p
18f0: 43 6f 6e 66 69 67 2d 3e 7a 4e 61 6d 65 2c 20 7a  Config->zName, z
1900: 54 61 69 6c 2c 20 7a 4e 61 6d 65 2c 20 7a 54 61  Tail, zName, zTa
1910: 69 6c 0a 20 20 20 20 29 3b 0a 20 20 7d 0a 7d 0a  il.    );.  }.}.
1920: 0a 69 6e 74 20 73 71 6c 69 74 65 33 46 74 73 35  .int sqlite3Fts5
1930: 53 74 6f 72 61 67 65 52 65 6e 61 6d 65 28 46 74  StorageRename(Ft
1940: 73 35 53 74 6f 72 61 67 65 20 2a 70 53 74 6f 72  s5Storage *pStor
1950: 61 67 65 2c 20 63 6f 6e 73 74 20 63 68 61 72 20  age, const char 
1960: 2a 7a 4e 61 6d 65 29 7b 0a 20 20 46 74 73 35 43  *zName){.  Fts5C
1970: 6f 6e 66 69 67 20 2a 70 43 6f 6e 66 69 67 20 3d  onfig *pConfig =
1980: 20 70 53 74 6f 72 61 67 65 2d 3e 70 43 6f 6e 66   pStorage->pConf
1990: 69 67 3b 0a 20 20 69 6e 74 20 72 63 20 3d 20 73  ig;.  int rc = s
19a0: 71 6c 69 74 65 33 46 74 73 35 53 74 6f 72 61 67  qlite3Fts5Storag
19b0: 65 53 79 6e 63 28 70 53 74 6f 72 61 67 65 29 3b  eSync(pStorage);
19c0: 0a 0a 20 20 66 74 73 35 53 74 6f 72 61 67 65 52  ..  fts5StorageR
19d0: 65 6e 61 6d 65 4f 6e 65 28 70 43 6f 6e 66 69 67  enameOne(pConfig
19e0: 2c 20 26 72 63 2c 20 22 64 61 74 61 22 2c 20 7a  , &rc, "data", z
19f0: 4e 61 6d 65 29 3b 0a 20 20 66 74 73 35 53 74 6f  Name);.  fts5Sto
1a00: 72 61 67 65 52 65 6e 61 6d 65 4f 6e 65 28 70 43  rageRenameOne(pC
1a10: 6f 6e 66 69 67 2c 20 26 72 63 2c 20 22 69 64 78  onfig, &rc, "idx
1a20: 22 2c 20 7a 4e 61 6d 65 29 3b 0a 20 20 66 74 73  ", zName);.  fts
1a30: 35 53 74 6f 72 61 67 65 52 65 6e 61 6d 65 4f 6e  5StorageRenameOn
1a40: 65 28 70 43 6f 6e 66 69 67 2c 20 26 72 63 2c 20  e(pConfig, &rc, 
1a50: 22 63 6f 6e 66 69 67 22 2c 20 7a 4e 61 6d 65 29  "config", zName)
1a60: 3b 0a 20 20 69 66 28 20 70 43 6f 6e 66 69 67 2d  ;.  if( pConfig-
1a70: 3e 62 43 6f 6c 75 6d 6e 73 69 7a 65 20 29 7b 0a  >bColumnsize ){.
1a80: 20 20 20 20 66 74 73 35 53 74 6f 72 61 67 65 52      fts5StorageR
1a90: 65 6e 61 6d 65 4f 6e 65 28 70 43 6f 6e 66 69 67  enameOne(pConfig
1aa0: 2c 20 26 72 63 2c 20 22 64 6f 63 73 69 7a 65 22  , &rc, "docsize"
1ab0: 2c 20 7a 4e 61 6d 65 29 3b 0a 20 20 7d 0a 20 20  , zName);.  }.  
1ac0: 69 66 28 20 70 43 6f 6e 66 69 67 2d 3e 65 43 6f  if( pConfig->eCo
1ad0: 6e 74 65 6e 74 3d 3d 46 54 53 35 5f 43 4f 4e 54  ntent==FTS5_CONT
1ae0: 45 4e 54 5f 4e 4f 52 4d 41 4c 20 29 7b 0a 20 20  ENT_NORMAL ){.  
1af0: 20 20 66 74 73 35 53 74 6f 72 61 67 65 52 65 6e    fts5StorageRen
1b00: 61 6d 65 4f 6e 65 28 70 43 6f 6e 66 69 67 2c 20  ameOne(pConfig, 
1b10: 26 72 63 2c 20 22 63 6f 6e 74 65 6e 74 22 2c 20  &rc, "content", 
1b20: 7a 4e 61 6d 65 29 3b 0a 20 20 7d 0a 20 20 72 65  zName);.  }.  re
1b30: 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a  turn rc;.}../*.*
1b40: 2a 20 43 72 65 61 74 65 20 74 68 65 20 73 68 61  * Create the sha
1b50: 64 6f 77 20 74 61 62 6c 65 20 6e 61 6d 65 64 20  dow table named 
1b60: 7a 50 6f 73 74 2c 20 77 69 74 68 20 64 65 66 69  zPost, with defi
1b70: 6e 69 74 69 6f 6e 20 7a 44 65 66 6e 2e 20 52 65  nition zDefn. Re
1b80: 74 75 72 6e 0a 2a 2a 20 53 51 4c 49 54 45 5f 4f  turn.** SQLITE_O
1b90: 4b 20 69 66 20 73 75 63 63 65 73 73 66 75 6c 2c  K if successful,
1ba0: 20 6f 72 20 61 6e 20 53 51 4c 69 74 65 20 65 72   or an SQLite er
1bb0: 72 6f 72 20 63 6f 64 65 20 6f 74 68 65 72 77 69  ror code otherwi
1bc0: 73 65 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74  se..*/.int sqlit
1bd0: 65 33 46 74 73 35 43 72 65 61 74 65 54 61 62 6c  e3Fts5CreateTabl
1be0: 65 28 0a 20 20 46 74 73 35 43 6f 6e 66 69 67 20  e(.  Fts5Config 
1bf0: 2a 70 43 6f 6e 66 69 67 2c 20 20 20 20 20 20 20  *pConfig,       
1c00: 20 20 20 20 20 2f 2a 20 46 54 53 35 20 63 6f 6e       /* FTS5 con
1c10: 66 69 67 75 72 61 74 69 6f 6e 20 2a 2f 0a 20 20  figuration */.  
1c20: 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 50 6f 73  const char *zPos
1c30: 74 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  t,              
1c40: 2f 2a 20 53 68 61 64 6f 77 20 74 61 62 6c 65 20  /* Shadow table 
1c50: 74 6f 20 63 72 65 61 74 65 20 28 65 2e 67 2e 20  to create (e.g. 
1c60: 22 63 6f 6e 74 65 6e 74 22 29 20 2a 2f 0a 20 20  "content") */.  
1c70: 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 44 65 66  const char *zDef
1c80: 6e 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  n,              
1c90: 2f 2a 20 43 6f 6c 75 6d 6e 73 20 65 74 63 2e 20  /* Columns etc. 
1ca0: 66 6f 72 20 73 68 61 64 6f 77 20 74 61 62 6c 65  for shadow table
1cb0: 20 2a 2f 0a 20 20 69 6e 74 20 62 57 69 74 68 6f   */.  int bWitho
1cc0: 75 74 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  ut,             
1cd0: 20 20 20 20 20 20 2f 2a 20 54 72 75 65 20 66 6f        /* True fo
1ce0: 72 20 77 69 74 68 6f 75 74 20 72 6f 77 69 64 20  r without rowid 
1cf0: 2a 2f 0a 20 20 63 68 61 72 20 2a 2a 70 7a 45 72  */.  char **pzEr
1d00: 72 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  r               
1d10: 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 45 72 72       /* OUT: Err
1d20: 6f 72 20 6d 65 73 73 61 67 65 20 2a 2f 0a 29 7b  or message */.){
1d30: 0a 20 20 69 6e 74 20 72 63 3b 0a 20 20 63 68 61  .  int rc;.  cha
1d40: 72 20 2a 7a 45 72 72 20 3d 20 30 3b 0a 0a 20 20  r *zErr = 0;..  
1d50: 72 63 20 3d 20 66 74 73 35 45 78 65 63 50 72 69  rc = fts5ExecPri
1d60: 6e 74 66 28 70 43 6f 6e 66 69 67 2d 3e 64 62 2c  ntf(pConfig->db,
1d70: 20 26 7a 45 72 72 2c 20 22 43 52 45 41 54 45 20   &zErr, "CREATE 
1d80: 54 41 42 4c 45 20 25 51 2e 27 25 71 5f 25 71 27  TABLE %Q.'%q_%q'
1d90: 28 25 73 29 25 73 22 2c 0a 20 20 20 20 20 20 70  (%s)%s",.      p
1da0: 43 6f 6e 66 69 67 2d 3e 7a 44 62 2c 20 70 43 6f  Config->zDb, pCo
1db0: 6e 66 69 67 2d 3e 7a 4e 61 6d 65 2c 20 7a 50 6f  nfig->zName, zPo
1dc0: 73 74 2c 20 7a 44 65 66 6e 2c 20 0a 23 69 66 6e  st, zDefn, .#ifn
1dd0: 64 65 66 20 53 51 4c 49 54 45 5f 46 54 53 35 5f  def SQLITE_FTS5_
1de0: 4e 4f 5f 57 49 54 48 4f 55 54 5f 52 4f 57 49 44  NO_WITHOUT_ROWID
1df0: 0a 20 20 20 20 20 20 62 57 69 74 68 6f 75 74 3f  .      bWithout?
1e00: 22 20 57 49 54 48 4f 55 54 20 52 4f 57 49 44 22  " WITHOUT ROWID"
1e10: 3a 0a 23 65 6e 64 69 66 0a 20 20 20 20 20 20 22  :.#endif.      "
1e20: 22 0a 20 20 29 3b 0a 20 20 69 66 28 20 7a 45 72  ".  );.  if( zEr
1e30: 72 20 29 7b 0a 20 20 20 20 2a 70 7a 45 72 72 20  r ){.    *pzErr 
1e40: 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74  = sqlite3_mprint
1e50: 66 28 0a 20 20 20 20 20 20 20 20 22 66 74 73 35  f(.        "fts5
1e60: 3a 20 65 72 72 6f 72 20 63 72 65 61 74 69 6e 67  : error creating
1e70: 20 73 68 61 64 6f 77 20 74 61 62 6c 65 20 25 71   shadow table %q
1e80: 5f 25 73 3a 20 25 73 22 2c 20 0a 20 20 20 20 20  _%s: %s", .     
1e90: 20 20 20 70 43 6f 6e 66 69 67 2d 3e 7a 4e 61 6d     pConfig->zNam
1ea0: 65 2c 20 7a 50 6f 73 74 2c 20 7a 45 72 72 0a 20  e, zPost, zErr. 
1eb0: 20 20 20 29 3b 0a 20 20 20 20 73 71 6c 69 74 65     );.    sqlite
1ec0: 33 5f 66 72 65 65 28 7a 45 72 72 29 3b 0a 20 20  3_free(zErr);.  
1ed0: 7d 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a  }..  return rc;.
1ee0: 7d 0a 0a 2f 2a 0a 2a 2a 20 4f 70 65 6e 20 61 20  }../*.** Open a 
1ef0: 6e 65 77 20 46 74 73 35 49 6e 64 65 78 20 68 61  new Fts5Index ha
1f00: 6e 64 6c 65 2e 20 49 66 20 74 68 65 20 62 43 72  ndle. If the bCr
1f10: 65 61 74 65 20 61 72 67 75 6d 65 6e 74 20 69 73  eate argument is
1f20: 20 74 72 75 65 2c 20 63 72 65 61 74 65 0a 2a 2a   true, create.**
1f30: 20 61 6e 64 20 69 6e 69 74 69 61 6c 69 7a 65 20   and initialize 
1f40: 74 68 65 20 75 6e 64 65 72 6c 79 69 6e 67 20 74  the underlying t
1f50: 61 62 6c 65 73 20 0a 2a 2a 0a 2a 2a 20 49 66 20  ables .**.** If 
1f60: 73 75 63 63 65 73 73 66 75 6c 2c 20 73 65 74 20  successful, set 
1f70: 2a 70 70 20 74 6f 20 70 6f 69 6e 74 20 74 6f 20  *pp to point to 
1f80: 74 68 65 20 6e 65 77 20 6f 62 6a 65 63 74 20 61  the new object a
1f90: 6e 64 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45  nd return SQLITE
1fa0: 5f 4f 4b 2e 0a 2a 2a 20 4f 74 68 65 72 77 69 73  _OK..** Otherwis
1fb0: 65 2c 20 73 65 74 20 2a 70 70 20 74 6f 20 4e 55  e, set *pp to NU
1fc0: 4c 4c 20 61 6e 64 20 72 65 74 75 72 6e 20 61 6e  LL and return an
1fd0: 20 53 51 4c 69 74 65 20 65 72 72 6f 72 20 63 6f   SQLite error co
1fe0: 64 65 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74  de..*/.int sqlit
1ff0: 65 33 46 74 73 35 53 74 6f 72 61 67 65 4f 70 65  e3Fts5StorageOpe
2000: 6e 28 0a 20 20 46 74 73 35 43 6f 6e 66 69 67 20  n(.  Fts5Config 
2010: 2a 70 43 6f 6e 66 69 67 2c 20 0a 20 20 46 74 73  *pConfig, .  Fts
2020: 35 49 6e 64 65 78 20 2a 70 49 6e 64 65 78 2c 20  5Index *pIndex, 
2030: 0a 20 20 69 6e 74 20 62 43 72 65 61 74 65 2c 20  .  int bCreate, 
2040: 0a 20 20 46 74 73 35 53 74 6f 72 61 67 65 20 2a  .  Fts5Storage *
2050: 2a 70 70 2c 0a 20 20 63 68 61 72 20 2a 2a 70 7a  *pp,.  char **pz
2060: 45 72 72 20 20 20 20 20 20 20 20 20 20 20 20 20  Err             
2070: 20 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a 20 45         /* OUT: E
2080: 72 72 6f 72 20 6d 65 73 73 61 67 65 20 2a 2f 0a  rror message */.
2090: 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51  ){.  int rc = SQ
20a0: 4c 49 54 45 5f 4f 4b 3b 0a 20 20 46 74 73 35 53  LITE_OK;.  Fts5S
20b0: 74 6f 72 61 67 65 20 2a 70 3b 20 20 20 20 20 20  torage *p;      
20c0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 65             /* Ne
20d0: 77 20 6f 62 6a 65 63 74 20 2a 2f 0a 20 20 73 71  w object */.  sq
20e0: 6c 69 74 65 33 5f 69 6e 74 36 34 20 6e 42 79 74  lite3_int64 nByt
20f0: 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a  e;            /*
2100: 20 42 79 74 65 73 20 6f 66 20 73 70 61 63 65 20   Bytes of space 
2110: 74 6f 20 61 6c 6c 6f 63 61 74 65 20 2a 2f 0a 0a  to allocate */..
2120: 20 20 6e 42 79 74 65 20 3d 20 73 69 7a 65 6f 66    nByte = sizeof
2130: 28 46 74 73 35 53 74 6f 72 61 67 65 29 20 20 20  (Fts5Storage)   
2140: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46              /* F
2150: 74 73 35 53 74 6f 72 61 67 65 20 6f 62 6a 65 63  ts5Storage objec
2160: 74 20 2a 2f 0a 20 20 20 20 20 20 20 20 2b 20 70  t */.        + p
2170: 43 6f 6e 66 69 67 2d 3e 6e 43 6f 6c 20 2a 20 73  Config->nCol * s
2180: 69 7a 65 6f 66 28 69 36 34 29 3b 20 20 20 20 20  izeof(i64);     
2190: 20 2f 2a 20 46 74 73 35 53 74 6f 72 61 67 65 2e   /* Fts5Storage.
21a0: 61 54 6f 74 61 6c 53 69 7a 65 5b 5d 20 2a 2f 0a  aTotalSize[] */.
21b0: 20 20 2a 70 70 20 3d 20 70 20 3d 20 28 46 74 73    *pp = p = (Fts
21c0: 35 53 74 6f 72 61 67 65 2a 29 73 71 6c 69 74 65  5Storage*)sqlite
21d0: 33 5f 6d 61 6c 6c 6f 63 36 34 28 6e 42 79 74 65  3_malloc64(nByte
21e0: 29 3b 0a 20 20 69 66 28 20 21 70 20 29 20 72 65  );.  if( !p ) re
21f0: 74 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45  turn SQLITE_NOME
2200: 4d 3b 0a 0a 20 20 6d 65 6d 73 65 74 28 70 2c 20  M;..  memset(p, 
2210: 30 2c 20 6e 42 79 74 65 29 3b 0a 20 20 70 2d 3e  0, nByte);.  p->
2220: 61 54 6f 74 61 6c 53 69 7a 65 20 3d 20 28 69 36  aTotalSize = (i6
2230: 34 2a 29 26 70 5b 31 5d 3b 0a 20 20 70 2d 3e 70  4*)&p[1];.  p->p
2240: 43 6f 6e 66 69 67 20 3d 20 70 43 6f 6e 66 69 67  Config = pConfig
2250: 3b 0a 20 20 70 2d 3e 70 49 6e 64 65 78 20 3d 20  ;.  p->pIndex = 
2260: 70 49 6e 64 65 78 3b 0a 0a 20 20 69 66 28 20 62  pIndex;..  if( b
2270: 43 72 65 61 74 65 20 29 7b 0a 20 20 20 20 69 66  Create ){.    if
2280: 28 20 70 43 6f 6e 66 69 67 2d 3e 65 43 6f 6e 74  ( pConfig->eCont
2290: 65 6e 74 3d 3d 46 54 53 35 5f 43 4f 4e 54 45 4e  ent==FTS5_CONTEN
22a0: 54 5f 4e 4f 52 4d 41 4c 20 29 7b 0a 20 20 20 20  T_NORMAL ){.    
22b0: 20 20 69 6e 74 20 6e 44 65 66 6e 20 3d 20 33 32    int nDefn = 32
22c0: 20 2b 20 70 43 6f 6e 66 69 67 2d 3e 6e 43 6f 6c   + pConfig->nCol
22d0: 2a 31 30 3b 0a 20 20 20 20 20 20 63 68 61 72 20  *10;.      char 
22e0: 2a 7a 44 65 66 6e 20 3d 20 73 71 6c 69 74 65 33  *zDefn = sqlite3
22f0: 5f 6d 61 6c 6c 6f 63 36 34 28 33 32 20 2b 20 28  _malloc64(32 + (
2300: 73 71 6c 69 74 65 33 5f 69 6e 74 36 34 29 70 43  sqlite3_int64)pC
2310: 6f 6e 66 69 67 2d 3e 6e 43 6f 6c 20 2a 20 31 30  onfig->nCol * 10
2320: 29 3b 0a 20 20 20 20 20 20 69 66 28 20 7a 44 65  );.      if( zDe
2330: 66 6e 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 20  fn==0 ){.       
2340: 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d   rc = SQLITE_NOM
2350: 45 4d 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65 7b  EM;.      }else{
2360: 0a 20 20 20 20 20 20 20 20 69 6e 74 20 69 3b 0a  .        int i;.
2370: 20 20 20 20 20 20 20 20 69 6e 74 20 69 4f 66 66          int iOff
2380: 3b 0a 20 20 20 20 20 20 20 20 73 71 6c 69 74 65  ;.        sqlite
2390: 33 5f 73 6e 70 72 69 6e 74 66 28 6e 44 65 66 6e  3_snprintf(nDefn
23a0: 2c 20 7a 44 65 66 6e 2c 20 22 69 64 20 49 4e 54  , zDefn, "id INT
23b0: 45 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59  EGER PRIMARY KEY
23c0: 22 29 3b 0a 20 20 20 20 20 20 20 20 69 4f 66 66  ");.        iOff
23d0: 20 3d 20 28 69 6e 74 29 73 74 72 6c 65 6e 28 7a   = (int)strlen(z
23e0: 44 65 66 6e 29 3b 0a 20 20 20 20 20 20 20 20 66  Defn);.        f
23f0: 6f 72 28 69 3d 30 3b 20 69 3c 70 43 6f 6e 66 69  or(i=0; i<pConfi
2400: 67 2d 3e 6e 43 6f 6c 3b 20 69 2b 2b 29 7b 0a 20  g->nCol; i++){. 
2410: 20 20 20 20 20 20 20 20 20 73 71 6c 69 74 65 33           sqlite3
2420: 5f 73 6e 70 72 69 6e 74 66 28 6e 44 65 66 6e 2d  _snprintf(nDefn-
2430: 69 4f 66 66 2c 20 26 7a 44 65 66 6e 5b 69 4f 66  iOff, &zDefn[iOf
2440: 66 5d 2c 20 22 2c 20 63 25 64 22 2c 20 69 29 3b  f], ", c%d", i);
2450: 0a 20 20 20 20 20 20 20 20 20 20 69 4f 66 66 20  .          iOff 
2460: 2b 3d 20 28 69 6e 74 29 73 74 72 6c 65 6e 28 26  += (int)strlen(&
2470: 7a 44 65 66 6e 5b 69 4f 66 66 5d 29 3b 0a 20 20  zDefn[iOff]);.  
2480: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20        }.        
2490: 72 63 20 3d 20 73 71 6c 69 74 65 33 46 74 73 35  rc = sqlite3Fts5
24a0: 43 72 65 61 74 65 54 61 62 6c 65 28 70 43 6f 6e  CreateTable(pCon
24b0: 66 69 67 2c 20 22 63 6f 6e 74 65 6e 74 22 2c 20  fig, "content", 
24c0: 7a 44 65 66 6e 2c 20 30 2c 20 70 7a 45 72 72 29  zDefn, 0, pzErr)
24d0: 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20  ;.      }.      
24e0: 73 71 6c 69 74 65 33 5f 66 72 65 65 28 7a 44 65  sqlite3_free(zDe
24f0: 66 6e 29 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20  fn);.    }..    
2500: 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  if( rc==SQLITE_O
2510: 4b 20 26 26 20 70 43 6f 6e 66 69 67 2d 3e 62 43  K && pConfig->bC
2520: 6f 6c 75 6d 6e 73 69 7a 65 20 29 7b 0a 20 20 20  olumnsize ){.   
2530: 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 46     rc = sqlite3F
2540: 74 73 35 43 72 65 61 74 65 54 61 62 6c 65 28 0a  ts5CreateTable(.
2550: 20 20 20 20 20 20 20 20 20 20 70 43 6f 6e 66 69            pConfi
2560: 67 2c 20 22 64 6f 63 73 69 7a 65 22 2c 20 22 69  g, "docsize", "i
2570: 64 20 49 4e 54 45 47 45 52 20 50 52 49 4d 41 52  d INTEGER PRIMAR
2580: 59 20 4b 45 59 2c 20 73 7a 20 42 4c 4f 42 22 2c  Y KEY, sz BLOB",
2590: 20 30 2c 20 70 7a 45 72 72 0a 20 20 20 20 20 20   0, pzErr.      
25a0: 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 28  );.    }.    if(
25b0: 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc==SQLITE_OK )
25c0: 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 73 71 6c  {.      rc = sql
25d0: 69 74 65 33 46 74 73 35 43 72 65 61 74 65 54 61  ite3Fts5CreateTa
25e0: 62 6c 65 28 0a 20 20 20 20 20 20 20 20 20 20 70  ble(.          p
25f0: 43 6f 6e 66 69 67 2c 20 22 63 6f 6e 66 69 67 22  Config, "config"
2600: 2c 20 22 6b 20 50 52 49 4d 41 52 59 20 4b 45 59  , "k PRIMARY KEY
2610: 2c 20 76 22 2c 20 31 2c 20 70 7a 45 72 72 0a 20  , v", 1, pzErr. 
2620: 20 20 20 20 20 29 3b 0a 20 20 20 20 7d 0a 20 20       );.    }.  
2630: 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
2640: 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 72 63 20  _OK ){.      rc 
2650: 3d 20 73 71 6c 69 74 65 33 46 74 73 35 53 74 6f  = sqlite3Fts5Sto
2660: 72 61 67 65 43 6f 6e 66 69 67 56 61 6c 75 65 28  rageConfigValue(
2670: 70 2c 20 22 76 65 72 73 69 6f 6e 22 2c 20 30 2c  p, "version", 0,
2680: 20 46 54 53 35 5f 43 55 52 52 45 4e 54 5f 56 45   FTS5_CURRENT_VE
2690: 52 53 49 4f 4e 29 3b 0a 20 20 20 20 7d 0a 20 20  RSION);.    }.  
26a0: 7d 0a 0a 20 20 69 66 28 20 72 63 20 29 7b 0a 20  }..  if( rc ){. 
26b0: 20 20 20 73 71 6c 69 74 65 33 46 74 73 35 53 74     sqlite3Fts5St
26c0: 6f 72 61 67 65 43 6c 6f 73 65 28 70 29 3b 0a 20  orageClose(p);. 
26d0: 20 20 20 2a 70 70 20 3d 20 30 3b 0a 20 20 7d 0a     *pp = 0;.  }.
26e0: 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a    return rc;.}..
26f0: 2f 2a 0a 2a 2a 20 43 6c 6f 73 65 20 61 20 68 61  /*.** Close a ha
2700: 6e 64 6c 65 20 6f 70 65 6e 65 64 20 62 79 20 61  ndle opened by a
2710: 6e 20 65 61 72 6c 69 65 72 20 63 61 6c 6c 20 74  n earlier call t
2720: 6f 20 73 71 6c 69 74 65 33 46 74 73 35 53 74 6f  o sqlite3Fts5Sto
2730: 72 61 67 65 4f 70 65 6e 28 29 2e 0a 2a 2f 0a 69  rageOpen()..*/.i
2740: 6e 74 20 73 71 6c 69 74 65 33 46 74 73 35 53 74  nt sqlite3Fts5St
2750: 6f 72 61 67 65 43 6c 6f 73 65 28 46 74 73 35 53  orageClose(Fts5S
2760: 74 6f 72 61 67 65 20 2a 70 29 7b 0a 20 20 69 6e  torage *p){.  in
2770: 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b  t rc = SQLITE_OK
2780: 3b 0a 20 20 69 66 28 20 70 20 29 7b 0a 20 20 20  ;.  if( p ){.   
2790: 20 69 6e 74 20 69 3b 0a 0a 20 20 20 20 2f 2a 20   int i;..    /* 
27a0: 46 69 6e 61 6c 69 7a 65 20 61 6c 6c 20 53 51 4c  Finalize all SQL
27b0: 20 73 74 61 74 65 6d 65 6e 74 73 20 2a 2f 0a 20   statements */. 
27c0: 20 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 41 72     for(i=0; i<Ar
27d0: 72 61 79 53 69 7a 65 28 70 2d 3e 61 53 74 6d 74  raySize(p->aStmt
27e0: 29 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20 73  ); i++){.      s
27f0: 71 6c 69 74 65 33 5f 66 69 6e 61 6c 69 7a 65 28  qlite3_finalize(
2800: 70 2d 3e 61 53 74 6d 74 5b 69 5d 29 3b 0a 20 20  p->aStmt[i]);.  
2810: 20 20 7d 0a 0a 20 20 20 20 73 71 6c 69 74 65 33    }..    sqlite3
2820: 5f 66 72 65 65 28 70 29 3b 0a 20 20 7d 0a 20 20  _free(p);.  }.  
2830: 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 74 79  return rc;.}..ty
2840: 70 65 64 65 66 20 73 74 72 75 63 74 20 46 74 73  pedef struct Fts
2850: 35 49 6e 73 65 72 74 43 74 78 20 46 74 73 35 49  5InsertCtx Fts5I
2860: 6e 73 65 72 74 43 74 78 3b 0a 73 74 72 75 63 74  nsertCtx;.struct
2870: 20 46 74 73 35 49 6e 73 65 72 74 43 74 78 20 7b   Fts5InsertCtx {
2880: 0a 20 20 46 74 73 35 53 74 6f 72 61 67 65 20 2a  .  Fts5Storage *
2890: 70 53 74 6f 72 61 67 65 3b 0a 20 20 69 6e 74 20  pStorage;.  int 
28a0: 69 43 6f 6c 3b 0a 20 20 69 6e 74 20 73 7a 43 6f  iCol;.  int szCo
28b0: 6c 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  l;              
28c0: 20 20 20 20 20 20 20 20 2f 2a 20 53 69 7a 65 20          /* Size 
28d0: 6f 66 20 63 6f 6c 75 6d 6e 20 76 61 6c 75 65 20  of column value 
28e0: 69 6e 20 74 6f 6b 65 6e 73 20 2a 2f 0a 7d 3b 0a  in tokens */.};.
28f0: 0a 2f 2a 0a 2a 2a 20 54 6f 6b 65 6e 69 7a 61 74  ./*.** Tokenizat
2900: 69 6f 6e 20 63 61 6c 6c 62 61 63 6b 20 75 73 65  ion callback use
2910: 64 20 77 68 65 6e 20 69 6e 73 65 72 74 69 6e 67  d when inserting
2920: 20 74 6f 6b 65 6e 73 20 69 6e 74 6f 20 74 68 65   tokens into the
2930: 20 46 54 53 20 69 6e 64 65 78 2e 0a 2a 2f 0a 73   FTS index..*/.s
2940: 74 61 74 69 63 20 69 6e 74 20 66 74 73 35 53 74  tatic int fts5St
2950: 6f 72 61 67 65 49 6e 73 65 72 74 43 61 6c 6c 62  orageInsertCallb
2960: 61 63 6b 28 0a 20 20 76 6f 69 64 20 2a 70 43 6f  ack(.  void *pCo
2970: 6e 74 65 78 74 2c 20 20 20 20 20 20 20 20 20 20  ntext,          
2980: 20 20 20 20 20 20 20 2f 2a 20 50 6f 69 6e 74 65         /* Pointe
2990: 72 20 74 6f 20 46 74 73 35 49 6e 73 65 72 74 43  r to Fts5InsertC
29a0: 74 78 20 6f 62 6a 65 63 74 20 2a 2f 0a 20 20 69  tx object */.  i
29b0: 6e 74 20 74 66 6c 61 67 73 2c 0a 20 20 63 6f 6e  nt tflags,.  con
29c0: 73 74 20 63 68 61 72 20 2a 70 54 6f 6b 65 6e 2c  st char *pToken,
29d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
29e0: 42 75 66 66 65 72 20 63 6f 6e 74 61 69 6e 69 6e  Buffer containin
29f0: 67 20 74 6f 6b 65 6e 20 2a 2f 0a 20 20 69 6e 74  g token */.  int
2a00: 20 6e 54 6f 6b 65 6e 2c 20 20 20 20 20 20 20 20   nToken,        
2a10: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
2a20: 53 69 7a 65 20 6f 66 20 74 6f 6b 65 6e 20 69 6e  Size of token in
2a30: 20 62 79 74 65 73 20 2a 2f 0a 20 20 69 6e 74 20   bytes */.  int 
2a40: 69 55 6e 75 73 65 64 31 2c 20 20 20 20 20 20 20  iUnused1,       
2a50: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53              /* S
2a60: 74 61 72 74 20 6f 66 66 73 65 74 20 6f 66 20 74  tart offset of t
2a70: 6f 6b 65 6e 20 2a 2f 0a 20 20 69 6e 74 20 69 55  oken */.  int iU
2a80: 6e 75 73 65 64 32 20 20 20 20 20 20 20 20 20 20  nused2          
2a90: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 45 6e 64            /* End
2aa0: 20 6f 66 66 73 65 74 20 6f 66 20 74 6f 6b 65 6e   offset of token
2ab0: 20 2a 2f 0a 29 7b 0a 20 20 46 74 73 35 49 6e 73   */.){.  Fts5Ins
2ac0: 65 72 74 43 74 78 20 2a 70 43 74 78 20 3d 20 28  ertCtx *pCtx = (
2ad0: 46 74 73 35 49 6e 73 65 72 74 43 74 78 2a 29 70  Fts5InsertCtx*)p
2ae0: 43 6f 6e 74 65 78 74 3b 0a 20 20 46 74 73 35 49  Context;.  Fts5I
2af0: 6e 64 65 78 20 2a 70 49 64 78 20 3d 20 70 43 74  ndex *pIdx = pCt
2b00: 78 2d 3e 70 53 74 6f 72 61 67 65 2d 3e 70 49 6e  x->pStorage->pIn
2b10: 64 65 78 3b 0a 20 20 55 4e 55 53 45 44 5f 50 41  dex;.  UNUSED_PA
2b20: 52 41 4d 32 28 69 55 6e 75 73 65 64 31 2c 20 69  RAM2(iUnused1, i
2b30: 55 6e 75 73 65 64 32 29 3b 0a 20 20 69 66 28 20  Unused2);.  if( 
2b40: 6e 54 6f 6b 65 6e 3e 46 54 53 35 5f 4d 41 58 5f  nToken>FTS5_MAX_
2b50: 54 4f 4b 45 4e 5f 53 49 5a 45 20 29 20 6e 54 6f  TOKEN_SIZE ) nTo
2b60: 6b 65 6e 20 3d 20 46 54 53 35 5f 4d 41 58 5f 54  ken = FTS5_MAX_T
2b70: 4f 4b 45 4e 5f 53 49 5a 45 3b 0a 20 20 69 66 28  OKEN_SIZE;.  if(
2b80: 20 28 74 66 6c 61 67 73 20 26 20 46 54 53 35 5f   (tflags & FTS5_
2b90: 54 4f 4b 45 4e 5f 43 4f 4c 4f 43 41 54 45 44 29  TOKEN_COLOCATED)
2ba0: 3d 3d 30 20 7c 7c 20 70 43 74 78 2d 3e 73 7a 43  ==0 || pCtx->szC
2bb0: 6f 6c 3d 3d 30 20 29 7b 0a 20 20 20 20 70 43 74  ol==0 ){.    pCt
2bc0: 78 2d 3e 73 7a 43 6f 6c 2b 2b 3b 0a 20 20 7d 0a  x->szCol++;.  }.
2bd0: 20 20 72 65 74 75 72 6e 20 73 71 6c 69 74 65 33    return sqlite3
2be0: 46 74 73 35 49 6e 64 65 78 57 72 69 74 65 28 70  Fts5IndexWrite(p
2bf0: 49 64 78 2c 20 70 43 74 78 2d 3e 69 43 6f 6c 2c  Idx, pCtx->iCol,
2c00: 20 70 43 74 78 2d 3e 73 7a 43 6f 6c 2d 31 2c 20   pCtx->szCol-1, 
2c10: 70 54 6f 6b 65 6e 2c 20 6e 54 6f 6b 65 6e 29 3b  pToken, nToken);
2c20: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 66 20 61 20 72  .}../*.** If a r
2c30: 6f 77 20 77 69 74 68 20 72 6f 77 69 64 20 69 44  ow with rowid iD
2c40: 65 6c 20 69 73 20 70 72 65 73 65 6e 74 20 69 6e  el is present in
2c50: 20 74 68 65 20 25 5f 63 6f 6e 74 65 6e 74 20 74   the %_content t
2c60: 61 62 6c 65 2c 20 61 64 64 20 74 68 65 0a 2a 2a  able, add the.**
2c70: 20 64 65 6c 65 74 65 2d 6d 61 72 6b 65 72 73 20   delete-markers 
2c80: 74 6f 20 74 68 65 20 46 54 53 20 69 6e 64 65 78  to the FTS index
2c90: 20 6e 65 63 65 73 73 61 72 79 20 74 6f 20 64 65   necessary to de
2ca0: 6c 65 74 65 20 69 74 2e 20 44 6f 20 6e 6f 74 20  lete it. Do not 
2cb0: 61 63 74 75 61 6c 6c 79 0a 2a 2a 20 72 65 6d 6f  actually.** remo
2cc0: 76 65 20 74 68 65 20 25 5f 63 6f 6e 74 65 6e 74  ve the %_content
2cd0: 20 72 6f 77 20 61 74 20 74 68 69 73 20 74 69 6d   row at this tim
2ce0: 65 20 74 68 6f 75 67 68 2e 0a 2a 2f 0a 73 74 61  e though..*/.sta
2cf0: 74 69 63 20 69 6e 74 20 66 74 73 35 53 74 6f 72  tic int fts5Stor
2d00: 61 67 65 44 65 6c 65 74 65 46 72 6f 6d 49 6e 64  ageDeleteFromInd
2d10: 65 78 28 0a 20 20 46 74 73 35 53 74 6f 72 61 67  ex(.  Fts5Storag
2d20: 65 20 2a 70 2c 20 0a 20 20 69 36 34 20 69 44 65  e *p, .  i64 iDe
2d30: 6c 2c 20 0a 20 20 73 71 6c 69 74 65 33 5f 76 61  l, .  sqlite3_va
2d40: 6c 75 65 20 2a 2a 61 70 56 61 6c 0a 29 7b 0a 20  lue **apVal.){. 
2d50: 20 46 74 73 35 43 6f 6e 66 69 67 20 2a 70 43 6f   Fts5Config *pCo
2d60: 6e 66 69 67 20 3d 20 70 2d 3e 70 43 6f 6e 66 69  nfig = p->pConfi
2d70: 67 3b 0a 20 20 73 71 6c 69 74 65 33 5f 73 74 6d  g;.  sqlite3_stm
2d80: 74 20 2a 70 53 65 65 6b 20 3d 20 30 3b 20 20 20  t *pSeek = 0;   
2d90: 20 20 20 20 20 2f 2a 20 53 45 4c 45 43 54 20 74       /* SELECT t
2da0: 6f 20 72 65 61 64 20 72 6f 77 20 69 44 65 6c 20  o read row iDel 
2db0: 66 72 6f 6d 20 25 5f 64 61 74 61 20 2a 2f 0a 20  from %_data */. 
2dc0: 20 69 6e 74 20 72 63 3b 20 20 20 20 20 20 20 20   int rc;        
2dd0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2de0: 20 2f 2a 20 52 65 74 75 72 6e 20 63 6f 64 65 20   /* Return code 
2df0: 2a 2f 0a 20 20 69 6e 74 20 72 63 32 3b 20 20 20  */.  int rc2;   
2e00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2e10: 20 20 20 20 20 2f 2a 20 73 71 6c 69 74 65 33 5f       /* sqlite3_
2e20: 72 65 73 65 74 28 29 20 72 65 74 75 72 6e 20 63  reset() return c
2e30: 6f 64 65 20 2a 2f 0a 20 20 69 6e 74 20 69 43 6f  ode */.  int iCo
2e40: 6c 3b 0a 20 20 46 74 73 35 49 6e 73 65 72 74 43  l;.  Fts5InsertC
2e50: 74 78 20 63 74 78 3b 0a 0a 20 20 69 66 28 20 61  tx ctx;..  if( a
2e60: 70 56 61 6c 3d 3d 30 20 29 7b 0a 20 20 20 20 72  pVal==0 ){.    r
2e70: 63 20 3d 20 66 74 73 35 53 74 6f 72 61 67 65 47  c = fts5StorageG
2e80: 65 74 53 74 6d 74 28 70 2c 20 46 54 53 35 5f 53  etStmt(p, FTS5_S
2e90: 54 4d 54 5f 4c 4f 4f 4b 55 50 2c 20 26 70 53 65  TMT_LOOKUP, &pSe
2ea0: 65 6b 2c 20 30 29 3b 0a 20 20 20 20 69 66 28 20  ek, 0);.    if( 
2eb0: 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20  rc!=SQLITE_OK ) 
2ec0: 72 65 74 75 72 6e 20 72 63 3b 0a 20 20 20 20 73  return rc;.    s
2ed0: 71 6c 69 74 65 33 5f 62 69 6e 64 5f 69 6e 74 36  qlite3_bind_int6
2ee0: 34 28 70 53 65 65 6b 2c 20 31 2c 20 69 44 65 6c  4(pSeek, 1, iDel
2ef0: 29 3b 0a 20 20 20 20 69 66 28 20 73 71 6c 69 74  );.    if( sqlit
2f00: 65 33 5f 73 74 65 70 28 70 53 65 65 6b 29 21 3d  e3_step(pSeek)!=
2f10: 53 51 4c 49 54 45 5f 52 4f 57 20 29 7b 0a 20 20  SQLITE_ROW ){.  
2f20: 20 20 20 20 72 65 74 75 72 6e 20 73 71 6c 69 74      return sqlit
2f30: 65 33 5f 72 65 73 65 74 28 70 53 65 65 6b 29 3b  e3_reset(pSeek);
2f40: 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 63 74  .    }.  }..  ct
2f50: 78 2e 70 53 74 6f 72 61 67 65 20 3d 20 70 3b 0a  x.pStorage = p;.
2f60: 20 20 63 74 78 2e 69 43 6f 6c 20 3d 20 2d 31 3b    ctx.iCol = -1;
2f70: 0a 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 46  .  rc = sqlite3F
2f80: 74 73 35 49 6e 64 65 78 42 65 67 69 6e 57 72 69  ts5IndexBeginWri
2f90: 74 65 28 70 2d 3e 70 49 6e 64 65 78 2c 20 31 2c  te(p->pIndex, 1,
2fa0: 20 69 44 65 6c 29 3b 0a 20 20 66 6f 72 28 69 43   iDel);.  for(iC
2fb0: 6f 6c 3d 31 3b 20 72 63 3d 3d 53 51 4c 49 54 45  ol=1; rc==SQLITE
2fc0: 5f 4f 4b 20 26 26 20 69 43 6f 6c 3c 3d 70 43 6f  _OK && iCol<=pCo
2fd0: 6e 66 69 67 2d 3e 6e 43 6f 6c 3b 20 69 43 6f 6c  nfig->nCol; iCol
2fe0: 2b 2b 29 7b 0a 20 20 20 20 69 66 28 20 70 43 6f  ++){.    if( pCo
2ff0: 6e 66 69 67 2d 3e 61 62 55 6e 69 6e 64 65 78 65  nfig->abUnindexe
3000: 64 5b 69 43 6f 6c 2d 31 5d 3d 3d 30 20 29 7b 0a  d[iCol-1]==0 ){.
3010: 20 20 20 20 20 20 63 6f 6e 73 74 20 63 68 61 72        const char
3020: 20 2a 7a 54 65 78 74 3b 0a 20 20 20 20 20 20 69   *zText;.      i
3030: 6e 74 20 6e 54 65 78 74 3b 0a 20 20 20 20 20 20  nt nText;.      
3040: 69 66 28 20 70 53 65 65 6b 20 29 7b 0a 20 20 20  if( pSeek ){.   
3050: 20 20 20 20 20 7a 54 65 78 74 20 3d 20 28 63 6f       zText = (co
3060: 6e 73 74 20 63 68 61 72 2a 29 73 71 6c 69 74 65  nst char*)sqlite
3070: 33 5f 63 6f 6c 75 6d 6e 5f 74 65 78 74 28 70 53  3_column_text(pS
3080: 65 65 6b 2c 20 69 43 6f 6c 29 3b 0a 20 20 20 20  eek, iCol);.    
3090: 20 20 20 20 6e 54 65 78 74 20 3d 20 73 71 6c 69      nText = sqli
30a0: 74 65 33 5f 63 6f 6c 75 6d 6e 5f 62 79 74 65 73  te3_column_bytes
30b0: 28 70 53 65 65 6b 2c 20 69 43 6f 6c 29 3b 0a 20  (pSeek, iCol);. 
30c0: 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20       }else{.    
30d0: 20 20 20 20 7a 54 65 78 74 20 3d 20 28 63 6f 6e      zText = (con
30e0: 73 74 20 63 68 61 72 2a 29 73 71 6c 69 74 65 33  st char*)sqlite3
30f0: 5f 76 61 6c 75 65 5f 74 65 78 74 28 61 70 56 61  _value_text(apVa
3100: 6c 5b 69 43 6f 6c 2d 31 5d 29 3b 0a 20 20 20 20  l[iCol-1]);.    
3110: 20 20 20 20 6e 54 65 78 74 20 3d 20 73 71 6c 69      nText = sqli
3120: 74 65 33 5f 76 61 6c 75 65 5f 62 79 74 65 73 28  te3_value_bytes(
3130: 61 70 56 61 6c 5b 69 43 6f 6c 2d 31 5d 29 3b 0a  apVal[iCol-1]);.
3140: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 63 74        }.      ct
3150: 78 2e 73 7a 43 6f 6c 20 3d 20 30 3b 0a 20 20 20  x.szCol = 0;.   
3160: 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 46     rc = sqlite3F
3170: 74 73 35 54 6f 6b 65 6e 69 7a 65 28 70 43 6f 6e  ts5Tokenize(pCon
3180: 66 69 67 2c 20 46 54 53 35 5f 54 4f 4b 45 4e 49  fig, FTS5_TOKENI
3190: 5a 45 5f 44 4f 43 55 4d 45 4e 54 2c 20 0a 20 20  ZE_DOCUMENT, .  
31a0: 20 20 20 20 20 20 20 20 7a 54 65 78 74 2c 20 6e          zText, n
31b0: 54 65 78 74 2c 20 28 76 6f 69 64 2a 29 26 63 74  Text, (void*)&ct
31c0: 78 2c 20 66 74 73 35 53 74 6f 72 61 67 65 49 6e  x, fts5StorageIn
31d0: 73 65 72 74 43 61 6c 6c 62 61 63 6b 0a 20 20 20  sertCallback.   
31e0: 20 20 20 29 3b 0a 20 20 20 20 20 20 70 2d 3e 61     );.      p->a
31f0: 54 6f 74 61 6c 53 69 7a 65 5b 69 43 6f 6c 2d 31  TotalSize[iCol-1
3200: 5d 20 2d 3d 20 28 69 36 34 29 63 74 78 2e 73 7a  ] -= (i64)ctx.sz
3210: 43 6f 6c 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20  Col;.    }.  }. 
3220: 20 70 2d 3e 6e 54 6f 74 61 6c 52 6f 77 2d 2d 3b   p->nTotalRow--;
3230: 0a 0a 20 20 72 63 32 20 3d 20 73 71 6c 69 74 65  ..  rc2 = sqlite
3240: 33 5f 72 65 73 65 74 28 70 53 65 65 6b 29 3b 0a  3_reset(pSeek);.
3250: 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
3260: 5f 4f 4b 20 29 20 72 63 20 3d 20 72 63 32 3b 0a  _OK ) rc = rc2;.
3270: 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a    return rc;.}..
3280: 0a 2f 2a 0a 2a 2a 20 49 6e 73 65 72 74 20 61 20  ./*.** Insert a 
3290: 72 65 63 6f 72 64 20 69 6e 74 6f 20 74 68 65 20  record into the 
32a0: 25 5f 64 6f 63 73 69 7a 65 20 74 61 62 6c 65 2e  %_docsize table.
32b0: 20 53 70 65 63 69 66 69 63 61 6c 6c 79 2c 20 64   Specifically, d
32c0: 6f 3a 0a 2a 2a 0a 2a 2a 20 20 20 49 4e 53 45 52  o:.**.**   INSER
32d0: 54 20 4f 52 20 52 45 50 4c 41 43 45 20 49 4e 54  T OR REPLACE INT
32e0: 4f 20 25 5f 64 6f 63 73 69 7a 65 28 69 64 2c 20  O %_docsize(id, 
32f0: 73 7a 29 20 56 41 4c 55 45 53 28 69 52 6f 77 69  sz) VALUES(iRowi
3300: 64 2c 20 70 42 75 66 29 3b 0a 2a 2a 0a 2a 2a 20  d, pBuf);.**.** 
3310: 49 66 20 74 68 65 72 65 20 69 73 20 6e 6f 20 25  If there is no %
3320: 5f 64 6f 63 73 69 7a 65 20 74 61 62 6c 65 20 28  _docsize table (
3330: 61 73 20 68 61 70 70 65 6e 73 20 69 66 20 74 68  as happens if th
3340: 65 20 63 6f 6c 75 6d 6e 73 69 7a 65 3d 30 20 6f  e columnsize=0 o
3350: 70 74 69 6f 6e 0a 2a 2a 20 69 73 20 73 70 65 63  ption.** is spec
3360: 69 66 69 65 64 20 77 68 65 6e 20 74 68 65 20 46  ified when the F
3370: 54 53 35 20 74 61 62 6c 65 20 69 73 20 63 72 65  TS5 table is cre
3380: 61 74 65 64 29 2c 20 74 68 69 73 20 66 75 6e 63  ated), this func
3390: 74 69 6f 6e 20 69 73 20 61 20 6e 6f 2d 6f 70 2e  tion is a no-op.
33a0: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 66  .*/.static int f
33b0: 74 73 35 53 74 6f 72 61 67 65 49 6e 73 65 72 74  ts5StorageInsert
33c0: 44 6f 63 73 69 7a 65 28 0a 20 20 46 74 73 35 53  Docsize(.  Fts5S
33d0: 74 6f 72 61 67 65 20 2a 70 2c 20 20 20 20 20 20  torage *p,      
33e0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 74             /* St
33f0: 6f 72 61 67 65 20 6d 6f 64 75 6c 65 20 74 6f 20  orage module to 
3400: 77 72 69 74 65 20 74 6f 20 2a 2f 0a 20 20 69 36  write to */.  i6
3410: 34 20 69 52 6f 77 69 64 2c 20 20 20 20 20 20 20  4 iRowid,       
3420: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
3430: 20 69 64 20 76 61 6c 75 65 20 2a 2f 0a 20 20 46   id value */.  F
3440: 74 73 35 42 75 66 66 65 72 20 2a 70 42 75 66 20  ts5Buffer *pBuf 
3450: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
3460: 2a 20 73 7a 20 76 61 6c 75 65 20 2a 2f 0a 29 7b  * sz value */.){
3470: 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49  .  int rc = SQLI
3480: 54 45 5f 4f 4b 3b 0a 20 20 69 66 28 20 70 2d 3e  TE_OK;.  if( p->
3490: 70 43 6f 6e 66 69 67 2d 3e 62 43 6f 6c 75 6d 6e  pConfig->bColumn
34a0: 73 69 7a 65 20 29 7b 0a 20 20 20 20 73 71 6c 69  size ){.    sqli
34b0: 74 65 33 5f 73 74 6d 74 20 2a 70 52 65 70 6c 61  te3_stmt *pRepla
34c0: 63 65 20 3d 20 30 3b 0a 20 20 20 20 72 63 20 3d  ce = 0;.    rc =
34d0: 20 66 74 73 35 53 74 6f 72 61 67 65 47 65 74 53   fts5StorageGetS
34e0: 74 6d 74 28 70 2c 20 46 54 53 35 5f 53 54 4d 54  tmt(p, FTS5_STMT
34f0: 5f 52 45 50 4c 41 43 45 5f 44 4f 43 53 49 5a 45  _REPLACE_DOCSIZE
3500: 2c 20 26 70 52 65 70 6c 61 63 65 2c 20 30 29 3b  , &pReplace, 0);
3510: 0a 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c  .    if( rc==SQL
3520: 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20  ITE_OK ){.      
3530: 73 71 6c 69 74 65 33 5f 62 69 6e 64 5f 69 6e 74  sqlite3_bind_int
3540: 36 34 28 70 52 65 70 6c 61 63 65 2c 20 31 2c 20  64(pReplace, 1, 
3550: 69 52 6f 77 69 64 29 3b 0a 20 20 20 20 20 20 73  iRowid);.      s
3560: 71 6c 69 74 65 33 5f 62 69 6e 64 5f 62 6c 6f 62  qlite3_bind_blob
3570: 28 70 52 65 70 6c 61 63 65 2c 20 32 2c 20 70 42  (pReplace, 2, pB
3580: 75 66 2d 3e 70 2c 20 70 42 75 66 2d 3e 6e 2c 20  uf->p, pBuf->n, 
3590: 53 51 4c 49 54 45 5f 53 54 41 54 49 43 29 3b 0a  SQLITE_STATIC);.
35a0: 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 73 74        sqlite3_st
35b0: 65 70 28 70 52 65 70 6c 61 63 65 29 3b 0a 20 20  ep(pReplace);.  
35c0: 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33      rc = sqlite3
35d0: 5f 72 65 73 65 74 28 70 52 65 70 6c 61 63 65 29  _reset(pReplace)
35e0: 3b 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f  ;.      sqlite3_
35f0: 62 69 6e 64 5f 6e 75 6c 6c 28 70 52 65 70 6c 61  bind_null(pRepla
3600: 63 65 2c 20 32 29 3b 0a 20 20 20 20 7d 0a 20 20  ce, 2);.    }.  
3610: 7d 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d  }.  return rc;.}
3620: 0a 0a 2f 2a 0a 2a 2a 20 4c 6f 61 64 20 74 68 65  ../*.** Load the
3630: 20 63 6f 6e 74 65 6e 74 73 20 6f 66 20 74 68 65   contents of the
3640: 20 22 61 76 65 72 61 67 65 73 22 20 72 65 63 6f   "averages" reco
3650: 72 64 20 66 72 6f 6d 20 64 69 73 6b 20 69 6e 74  rd from disk int
3660: 6f 20 74 68 65 20 0a 2a 2a 20 70 2d 3e 6e 54 6f  o the .** p->nTo
3670: 74 61 6c 52 6f 77 20 61 6e 64 20 70 2d 3e 61 54  talRow and p->aT
3680: 6f 74 61 6c 53 69 7a 65 5b 5d 20 76 61 72 69 61  otalSize[] varia
3690: 62 6c 65 73 2e 20 49 66 20 73 75 63 63 65 73 73  bles. If success
36a0: 66 75 6c 2c 20 61 6e 64 20 69 66 0a 2a 2a 20 61  ful, and if.** a
36b0: 72 67 75 6d 65 6e 74 20 62 43 61 63 68 65 20 69  rgument bCache i
36c0: 73 20 74 72 75 65 2c 20 73 65 74 20 74 68 65 20  s true, set the 
36d0: 70 2d 3e 62 54 6f 74 61 6c 73 56 61 6c 69 64 20  p->bTotalsValid 
36e0: 66 6c 61 67 20 74 6f 20 69 6e 64 69 63 61 74 65  flag to indicate
36f0: 0a 2a 2a 20 74 68 61 74 20 74 68 65 20 63 6f 6e  .** that the con
3700: 74 65 6e 74 73 20 6f 66 20 61 54 6f 74 61 6c 53  tents of aTotalS
3710: 69 7a 65 5b 5d 20 61 6e 64 20 6e 54 6f 74 61 6c  ize[] and nTotal
3720: 52 6f 77 20 61 72 65 20 76 61 6c 69 64 20 75 6e  Row are valid un
3730: 74 69 6c 0a 2a 2a 20 66 75 72 74 68 65 72 20 6e  til.** further n
3740: 6f 74 69 63 65 2e 0a 2a 2a 0a 2a 2a 20 52 65 74  otice..**.** Ret
3750: 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 20 69 66  urn SQLITE_OK if
3760: 20 73 75 63 63 65 73 73 66 75 6c 2c 20 6f 72 20   successful, or 
3770: 61 6e 20 53 51 4c 69 74 65 20 65 72 72 6f 72 20  an SQLite error 
3780: 63 6f 64 65 20 69 66 20 61 6e 20 65 72 72 6f 72  code if an error
3790: 0a 2a 2a 20 6f 63 63 75 72 73 2e 0a 2a 2f 0a 73  .** occurs..*/.s
37a0: 74 61 74 69 63 20 69 6e 74 20 66 74 73 35 53 74  tatic int fts5St
37b0: 6f 72 61 67 65 4c 6f 61 64 54 6f 74 61 6c 73 28  orageLoadTotals(
37c0: 46 74 73 35 53 74 6f 72 61 67 65 20 2a 70 2c 20  Fts5Storage *p, 
37d0: 69 6e 74 20 62 43 61 63 68 65 29 7b 0a 20 20 69  int bCache){.  i
37e0: 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f  nt rc = SQLITE_O
37f0: 4b 3b 0a 20 20 69 66 28 20 70 2d 3e 62 54 6f 74  K;.  if( p->bTot
3800: 61 6c 73 56 61 6c 69 64 3d 3d 30 20 29 7b 0a 20  alsValid==0 ){. 
3810: 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 46     rc = sqlite3F
3820: 74 73 35 49 6e 64 65 78 47 65 74 41 76 65 72 61  ts5IndexGetAvera
3830: 67 65 73 28 70 2d 3e 70 49 6e 64 65 78 2c 20 26  ges(p->pIndex, &
3840: 70 2d 3e 6e 54 6f 74 61 6c 52 6f 77 2c 20 70 2d  p->nTotalRow, p-
3850: 3e 61 54 6f 74 61 6c 53 69 7a 65 29 3b 0a 20 20  >aTotalSize);.  
3860: 20 20 70 2d 3e 62 54 6f 74 61 6c 73 56 61 6c 69    p->bTotalsVali
3870: 64 20 3d 20 62 43 61 63 68 65 3b 0a 20 20 7d 0a  d = bCache;.  }.
3880: 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a    return rc;.}..
3890: 2f 2a 0a 2a 2a 20 53 74 6f 72 65 20 74 68 65 20  /*.** Store the 
38a0: 63 75 72 72 65 6e 74 20 63 6f 6e 74 65 6e 74 73  current contents
38b0: 20 6f 66 20 74 68 65 20 70 2d 3e 6e 54 6f 74 61   of the p->nTota
38c0: 6c 52 6f 77 20 61 6e 64 20 70 2d 3e 61 54 6f 74  lRow and p->aTot
38d0: 61 6c 53 69 7a 65 5b 5d 20 0a 2a 2a 20 76 61 72  alSize[] .** var
38e0: 69 61 62 6c 65 73 20 69 6e 20 74 68 65 20 22 61  iables in the "a
38f0: 76 65 72 61 67 65 73 22 20 72 65 63 6f 72 64 20  verages" record 
3900: 6f 6e 20 64 69 73 6b 2e 0a 2a 2a 0a 2a 2a 20 52  on disk..**.** R
3910: 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 20  eturn SQLITE_OK 
3920: 69 66 20 73 75 63 63 65 73 73 66 75 6c 2c 20 6f  if successful, o
3930: 72 20 61 6e 20 53 51 4c 69 74 65 20 65 72 72 6f  r an SQLite erro
3940: 72 20 63 6f 64 65 20 69 66 20 61 6e 20 65 72 72  r code if an err
3950: 6f 72 0a 2a 2a 20 6f 63 63 75 72 73 2e 0a 2a 2f  or.** occurs..*/
3960: 0a 73 74 61 74 69 63 20 69 6e 74 20 66 74 73 35  .static int fts5
3970: 53 74 6f 72 61 67 65 53 61 76 65 54 6f 74 61 6c  StorageSaveTotal
3980: 73 28 46 74 73 35 53 74 6f 72 61 67 65 20 2a 70  s(Fts5Storage *p
3990: 29 7b 0a 20 20 69 6e 74 20 6e 43 6f 6c 20 3d 20  ){.  int nCol = 
39a0: 70 2d 3e 70 43 6f 6e 66 69 67 2d 3e 6e 43 6f 6c  p->pConfig->nCol
39b0: 3b 0a 20 20 69 6e 74 20 69 3b 0a 20 20 46 74 73  ;.  int i;.  Fts
39c0: 35 42 75 66 66 65 72 20 62 75 66 3b 0a 20 20 69  5Buffer buf;.  i
39d0: 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f  nt rc = SQLITE_O
39e0: 4b 3b 0a 20 20 6d 65 6d 73 65 74 28 26 62 75 66  K;.  memset(&buf
39f0: 2c 20 30 2c 20 73 69 7a 65 6f 66 28 62 75 66 29  , 0, sizeof(buf)
3a00: 29 3b 0a 0a 20 20 73 71 6c 69 74 65 33 46 74 73  );..  sqlite3Fts
3a10: 35 42 75 66 66 65 72 41 70 70 65 6e 64 56 61 72  5BufferAppendVar
3a20: 69 6e 74 28 26 72 63 2c 20 26 62 75 66 2c 20 70  int(&rc, &buf, p
3a30: 2d 3e 6e 54 6f 74 61 6c 52 6f 77 29 3b 0a 20 20  ->nTotalRow);.  
3a40: 66 6f 72 28 69 3d 30 3b 20 69 3c 6e 43 6f 6c 3b  for(i=0; i<nCol;
3a50: 20 69 2b 2b 29 7b 0a 20 20 20 20 73 71 6c 69 74   i++){.    sqlit
3a60: 65 33 46 74 73 35 42 75 66 66 65 72 41 70 70 65  e3Fts5BufferAppe
3a70: 6e 64 56 61 72 69 6e 74 28 26 72 63 2c 20 26 62  ndVarint(&rc, &b
3a80: 75 66 2c 20 70 2d 3e 61 54 6f 74 61 6c 53 69 7a  uf, p->aTotalSiz
3a90: 65 5b 69 5d 29 3b 0a 20 20 7d 0a 20 20 69 66 28  e[i]);.  }.  if(
3aa0: 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc==SQLITE_OK )
3ab0: 7b 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74  {.    rc = sqlit
3ac0: 65 33 46 74 73 35 49 6e 64 65 78 53 65 74 41 76  e3Fts5IndexSetAv
3ad0: 65 72 61 67 65 73 28 70 2d 3e 70 49 6e 64 65 78  erages(p->pIndex
3ae0: 2c 20 62 75 66 2e 70 2c 20 62 75 66 2e 6e 29 3b  , buf.p, buf.n);
3af0: 0a 20 20 7d 0a 20 20 73 71 6c 69 74 65 33 5f 66  .  }.  sqlite3_f
3b00: 72 65 65 28 62 75 66 2e 70 29 3b 0a 0a 20 20 72  ree(buf.p);..  r
3b10: 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a  eturn rc;.}../*.
3b20: 2a 2a 20 52 65 6d 6f 76 65 20 61 20 72 6f 77 20  ** Remove a row 
3b30: 66 72 6f 6d 20 74 68 65 20 46 54 53 20 74 61 62  from the FTS tab
3b40: 6c 65 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74  le..*/.int sqlit
3b50: 65 33 46 74 73 35 53 74 6f 72 61 67 65 44 65 6c  e3Fts5StorageDel
3b60: 65 74 65 28 46 74 73 35 53 74 6f 72 61 67 65 20  ete(Fts5Storage 
3b70: 2a 70 2c 20 69 36 34 20 69 44 65 6c 2c 20 73 71  *p, i64 iDel, sq
3b80: 6c 69 74 65 33 5f 76 61 6c 75 65 20 2a 2a 61 70  lite3_value **ap
3b90: 56 61 6c 29 7b 0a 20 20 46 74 73 35 43 6f 6e 66  Val){.  Fts5Conf
3ba0: 69 67 20 2a 70 43 6f 6e 66 69 67 20 3d 20 70 2d  ig *pConfig = p-
3bb0: 3e 70 43 6f 6e 66 69 67 3b 0a 20 20 69 6e 74 20  >pConfig;.  int 
3bc0: 72 63 3b 0a 20 20 73 71 6c 69 74 65 33 5f 73 74  rc;.  sqlite3_st
3bd0: 6d 74 20 2a 70 44 65 6c 20 3d 20 30 3b 0a 0a 20  mt *pDel = 0;.. 
3be0: 20 61 73 73 65 72 74 28 20 70 43 6f 6e 66 69 67   assert( pConfig
3bf0: 2d 3e 65 43 6f 6e 74 65 6e 74 21 3d 46 54 53 35  ->eContent!=FTS5
3c00: 5f 43 4f 4e 54 45 4e 54 5f 4e 4f 52 4d 41 4c 20  _CONTENT_NORMAL 
3c10: 7c 7c 20 61 70 56 61 6c 3d 3d 30 20 29 3b 0a 20  || apVal==0 );. 
3c20: 20 72 63 20 3d 20 66 74 73 35 53 74 6f 72 61 67   rc = fts5Storag
3c30: 65 4c 6f 61 64 54 6f 74 61 6c 73 28 70 2c 20 31  eLoadTotals(p, 1
3c40: 29 3b 0a 0a 20 20 2f 2a 20 44 65 6c 65 74 65 20  );..  /* Delete 
3c50: 74 68 65 20 69 6e 64 65 78 20 72 65 63 6f 72 64  the index record
3c60: 73 20 2a 2f 0a 20 20 69 66 28 20 72 63 3d 3d 53  s */.  if( rc==S
3c70: 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
3c80: 72 63 20 3d 20 66 74 73 35 53 74 6f 72 61 67 65  rc = fts5Storage
3c90: 44 65 6c 65 74 65 46 72 6f 6d 49 6e 64 65 78 28  DeleteFromIndex(
3ca0: 70 2c 20 69 44 65 6c 2c 20 61 70 56 61 6c 29 3b  p, iDel, apVal);
3cb0: 0a 20 20 7d 0a 0a 20 20 2f 2a 20 44 65 6c 65 74  .  }..  /* Delet
3cc0: 65 20 74 68 65 20 25 5f 64 6f 63 73 69 7a 65 20  e the %_docsize 
3cd0: 72 65 63 6f 72 64 20 2a 2f 0a 20 20 69 66 28 20  record */.  if( 
3ce0: 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26  rc==SQLITE_OK &&
3cf0: 20 70 43 6f 6e 66 69 67 2d 3e 62 43 6f 6c 75 6d   pConfig->bColum
3d00: 6e 73 69 7a 65 20 29 7b 0a 20 20 20 20 72 63 20  nsize ){.    rc 
3d10: 3d 20 66 74 73 35 53 74 6f 72 61 67 65 47 65 74  = fts5StorageGet
3d20: 53 74 6d 74 28 70 2c 20 46 54 53 35 5f 53 54 4d  Stmt(p, FTS5_STM
3d30: 54 5f 44 45 4c 45 54 45 5f 44 4f 43 53 49 5a 45  T_DELETE_DOCSIZE
3d40: 2c 20 26 70 44 65 6c 2c 20 30 29 3b 0a 20 20 20  , &pDel, 0);.   
3d50: 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
3d60: 4f 4b 20 29 7b 0a 20 20 20 20 20 20 73 71 6c 69  OK ){.      sqli
3d70: 74 65 33 5f 62 69 6e 64 5f 69 6e 74 36 34 28 70  te3_bind_int64(p
3d80: 44 65 6c 2c 20 31 2c 20 69 44 65 6c 29 3b 0a 20  Del, 1, iDel);. 
3d90: 20 20 20 20 20 73 71 6c 69 74 65 33 5f 73 74 65       sqlite3_ste
3da0: 70 28 70 44 65 6c 29 3b 0a 20 20 20 20 20 20 72  p(pDel);.      r
3db0: 63 20 3d 20 73 71 6c 69 74 65 33 5f 72 65 73 65  c = sqlite3_rese
3dc0: 74 28 70 44 65 6c 29 3b 0a 20 20 20 20 7d 0a 20  t(pDel);.    }. 
3dd0: 20 7d 0a 0a 20 20 2f 2a 20 44 65 6c 65 74 65 20   }..  /* Delete 
3de0: 74 68 65 20 25 5f 63 6f 6e 74 65 6e 74 20 72 65  the %_content re
3df0: 63 6f 72 64 20 2a 2f 0a 20 20 69 66 28 20 70 43  cord */.  if( pC
3e00: 6f 6e 66 69 67 2d 3e 65 43 6f 6e 74 65 6e 74 3d  onfig->eContent=
3e10: 3d 46 54 53 35 5f 43 4f 4e 54 45 4e 54 5f 4e 4f  =FTS5_CONTENT_NO
3e20: 52 4d 41 4c 20 29 7b 0a 20 20 20 20 69 66 28 20  RMAL ){.    if( 
3e30: 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc==SQLITE_OK ){
3e40: 0a 20 20 20 20 20 20 72 63 20 3d 20 66 74 73 35  .      rc = fts5
3e50: 53 74 6f 72 61 67 65 47 65 74 53 74 6d 74 28 70  StorageGetStmt(p
3e60: 2c 20 46 54 53 35 5f 53 54 4d 54 5f 44 45 4c 45  , FTS5_STMT_DELE
3e70: 54 45 5f 43 4f 4e 54 45 4e 54 2c 20 26 70 44 65  TE_CONTENT, &pDe
3e80: 6c 2c 20 30 29 3b 0a 20 20 20 20 7d 0a 20 20 20  l, 0);.    }.   
3e90: 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
3ea0: 4f 4b 20 29 7b 0a 20 20 20 20 20 20 73 71 6c 69  OK ){.      sqli
3eb0: 74 65 33 5f 62 69 6e 64 5f 69 6e 74 36 34 28 70  te3_bind_int64(p
3ec0: 44 65 6c 2c 20 31 2c 20 69 44 65 6c 29 3b 0a 20  Del, 1, iDel);. 
3ed0: 20 20 20 20 20 73 71 6c 69 74 65 33 5f 73 74 65       sqlite3_ste
3ee0: 70 28 70 44 65 6c 29 3b 0a 20 20 20 20 20 20 72  p(pDel);.      r
3ef0: 63 20 3d 20 73 71 6c 69 74 65 33 5f 72 65 73 65  c = sqlite3_rese
3f00: 74 28 70 44 65 6c 29 3b 0a 20 20 20 20 7d 0a 20  t(pDel);.    }. 
3f10: 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b   }..  return rc;
3f20: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 44 65 6c 65 74 65  .}../*.** Delete
3f30: 20 61 6c 6c 20 65 6e 74 72 69 65 73 20 69 6e 20   all entries in 
3f40: 74 68 65 20 46 54 53 35 20 69 6e 64 65 78 2e 0a  the FTS5 index..
3f50: 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 46 74  */.int sqlite3Ft
3f60: 73 35 53 74 6f 72 61 67 65 44 65 6c 65 74 65 41  s5StorageDeleteA
3f70: 6c 6c 28 46 74 73 35 53 74 6f 72 61 67 65 20 2a  ll(Fts5Storage *
3f80: 70 29 7b 0a 20 20 46 74 73 35 43 6f 6e 66 69 67  p){.  Fts5Config
3f90: 20 2a 70 43 6f 6e 66 69 67 20 3d 20 70 2d 3e 70   *pConfig = p->p
3fa0: 43 6f 6e 66 69 67 3b 0a 20 20 69 6e 74 20 72 63  Config;.  int rc
3fb0: 3b 0a 0a 20 20 2f 2a 20 44 65 6c 65 74 65 20 74  ;..  /* Delete t
3fc0: 68 65 20 63 6f 6e 74 65 6e 74 73 20 6f 66 20 74  he contents of t
3fd0: 68 65 20 25 5f 64 61 74 61 20 61 6e 64 20 25 5f  he %_data and %_
3fe0: 64 6f 63 73 69 7a 65 20 74 61 62 6c 65 73 2e 20  docsize tables. 
3ff0: 2a 2f 0a 20 20 72 63 20 3d 20 66 74 73 35 45 78  */.  rc = fts5Ex
4000: 65 63 50 72 69 6e 74 66 28 70 43 6f 6e 66 69 67  ecPrintf(pConfig
4010: 2d 3e 64 62 2c 20 30 2c 0a 20 20 20 20 20 20 22  ->db, 0,.      "
4020: 44 45 4c 45 54 45 20 46 52 4f 4d 20 25 51 2e 27  DELETE FROM %Q.'
4030: 25 71 5f 64 61 74 61 27 3b 22 20 0a 20 20 20 20  %q_data';" .    
4040: 20 20 22 44 45 4c 45 54 45 20 46 52 4f 4d 20 25    "DELETE FROM %
4050: 51 2e 27 25 71 5f 69 64 78 27 3b 22 2c 0a 20 20  Q.'%q_idx';",.  
4060: 20 20 20 20 70 43 6f 6e 66 69 67 2d 3e 7a 44 62      pConfig->zDb
4070: 2c 20 70 43 6f 6e 66 69 67 2d 3e 7a 4e 61 6d 65  , pConfig->zName
4080: 2c 0a 20 20 20 20 20 20 70 43 6f 6e 66 69 67 2d  ,.      pConfig-
4090: 3e 7a 44 62 2c 20 70 43 6f 6e 66 69 67 2d 3e 7a  >zDb, pConfig->z
40a0: 4e 61 6d 65 0a 20 20 29 3b 0a 20 20 69 66 28 20  Name.  );.  if( 
40b0: 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26  rc==SQLITE_OK &&
40c0: 20 70 43 6f 6e 66 69 67 2d 3e 62 43 6f 6c 75 6d   pConfig->bColum
40d0: 6e 73 69 7a 65 20 29 7b 0a 20 20 20 20 72 63 20  nsize ){.    rc 
40e0: 3d 20 66 74 73 35 45 78 65 63 50 72 69 6e 74 66  = fts5ExecPrintf
40f0: 28 70 43 6f 6e 66 69 67 2d 3e 64 62 2c 20 30 2c  (pConfig->db, 0,
4100: 0a 20 20 20 20 20 20 20 20 22 44 45 4c 45 54 45  .        "DELETE
4110: 20 46 52 4f 4d 20 25 51 2e 27 25 71 5f 64 6f 63   FROM %Q.'%q_doc
4120: 73 69 7a 65 27 3b 22 2c 0a 20 20 20 20 20 20 20  size';",.       
4130: 20 70 43 6f 6e 66 69 67 2d 3e 7a 44 62 2c 20 70   pConfig->zDb, p
4140: 43 6f 6e 66 69 67 2d 3e 7a 4e 61 6d 65 0a 20 20  Config->zName.  
4150: 20 20 29 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 52    );.  }..  /* R
4160: 65 69 6e 69 74 69 61 6c 69 7a 65 20 74 68 65 20  einitialize the 
4170: 25 5f 64 61 74 61 20 74 61 62 6c 65 2e 20 54 68  %_data table. Th
4180: 69 73 20 63 61 6c 6c 20 63 72 65 61 74 65 73 20  is call creates 
4190: 74 68 65 20 69 6e 69 74 69 61 6c 20 73 74 72 75  the initial stru
41a0: 63 74 75 72 65 0a 20 20 2a 2a 20 61 6e 64 20 61  cture.  ** and a
41b0: 76 65 72 61 67 65 73 20 72 65 63 6f 72 64 73 2e  verages records.
41c0: 20 20 2a 2f 0a 20 20 69 66 28 20 72 63 3d 3d 53    */.  if( rc==S
41d0: 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
41e0: 72 63 20 3d 20 73 71 6c 69 74 65 33 46 74 73 35  rc = sqlite3Fts5
41f0: 49 6e 64 65 78 52 65 69 6e 69 74 28 70 2d 3e 70  IndexReinit(p->p
4200: 49 6e 64 65 78 29 3b 0a 20 20 7d 0a 20 20 69 66  Index);.  }.  if
4210: 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
4220: 29 7b 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69  ){.    rc = sqli
4230: 74 65 33 46 74 73 35 53 74 6f 72 61 67 65 43 6f  te3Fts5StorageCo
4240: 6e 66 69 67 56 61 6c 75 65 28 70 2c 20 22 76 65  nfigValue(p, "ve
4250: 72 73 69 6f 6e 22 2c 20 30 2c 20 46 54 53 35 5f  rsion", 0, FTS5_
4260: 43 55 52 52 45 4e 54 5f 56 45 52 53 49 4f 4e 29  CURRENT_VERSION)
4270: 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 72  ;.  }.  return r
4280: 63 3b 0a 7d 0a 0a 69 6e 74 20 73 71 6c 69 74 65  c;.}..int sqlite
4290: 33 46 74 73 35 53 74 6f 72 61 67 65 52 65 62 75  3Fts5StorageRebu
42a0: 69 6c 64 28 46 74 73 35 53 74 6f 72 61 67 65 20  ild(Fts5Storage 
42b0: 2a 70 29 7b 0a 20 20 46 74 73 35 42 75 66 66 65  *p){.  Fts5Buffe
42c0: 72 20 62 75 66 20 3d 20 7b 30 2c 30 2c 30 7d 3b  r buf = {0,0,0};
42d0: 0a 20 20 46 74 73 35 43 6f 6e 66 69 67 20 2a 70  .  Fts5Config *p
42e0: 43 6f 6e 66 69 67 20 3d 20 70 2d 3e 70 43 6f 6e  Config = p->pCon
42f0: 66 69 67 3b 0a 20 20 73 71 6c 69 74 65 33 5f 73  fig;.  sqlite3_s
4300: 74 6d 74 20 2a 70 53 63 61 6e 20 3d 20 30 3b 0a  tmt *pScan = 0;.
4310: 20 20 46 74 73 35 49 6e 73 65 72 74 43 74 78 20    Fts5InsertCtx 
4320: 63 74 78 3b 0a 20 20 69 6e 74 20 72 63 2c 20 72  ctx;.  int rc, r
4330: 63 32 3b 0a 0a 20 20 6d 65 6d 73 65 74 28 26 63  c2;..  memset(&c
4340: 74 78 2c 20 30 2c 20 73 69 7a 65 6f 66 28 46 74  tx, 0, sizeof(Ft
4350: 73 35 49 6e 73 65 72 74 43 74 78 29 29 3b 0a 20  s5InsertCtx));. 
4360: 20 63 74 78 2e 70 53 74 6f 72 61 67 65 20 3d 20   ctx.pStorage = 
4370: 70 3b 0a 20 20 72 63 20 3d 20 73 71 6c 69 74 65  p;.  rc = sqlite
4380: 33 46 74 73 35 53 74 6f 72 61 67 65 44 65 6c 65  3Fts5StorageDele
4390: 74 65 41 6c 6c 28 70 29 3b 0a 20 20 69 66 28 20  teAll(p);.  if( 
43a0: 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc==SQLITE_OK ){
43b0: 0a 20 20 20 20 72 63 20 3d 20 66 74 73 35 53 74  .    rc = fts5St
43c0: 6f 72 61 67 65 4c 6f 61 64 54 6f 74 61 6c 73 28  orageLoadTotals(
43d0: 70 2c 20 31 29 3b 0a 20 20 7d 0a 0a 20 20 69 66  p, 1);.  }..  if
43e0: 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
43f0: 29 7b 0a 20 20 20 20 72 63 20 3d 20 66 74 73 35  ){.    rc = fts5
4400: 53 74 6f 72 61 67 65 47 65 74 53 74 6d 74 28 70  StorageGetStmt(p
4410: 2c 20 46 54 53 35 5f 53 54 4d 54 5f 53 43 41 4e  , FTS5_STMT_SCAN
4420: 2c 20 26 70 53 63 61 6e 2c 20 30 29 3b 0a 20 20  , &pScan, 0);.  
4430: 7d 0a 0a 20 20 77 68 69 6c 65 28 20 72 63 3d 3d  }..  while( rc==
4440: 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20 53 51 4c  SQLITE_OK && SQL
4450: 49 54 45 5f 52 4f 57 3d 3d 73 71 6c 69 74 65 33  ITE_ROW==sqlite3
4460: 5f 73 74 65 70 28 70 53 63 61 6e 29 20 29 7b 0a  _step(pScan) ){.
4470: 20 20 20 20 69 36 34 20 69 52 6f 77 69 64 20 3d      i64 iRowid =
4480: 20 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f   sqlite3_column_
4490: 69 6e 74 36 34 28 70 53 63 61 6e 2c 20 30 29 3b  int64(pScan, 0);
44a0: 0a 0a 20 20 20 20 73 71 6c 69 74 65 33 46 74 73  ..    sqlite3Fts
44b0: 35 42 75 66 66 65 72 5a 65 72 6f 28 26 62 75 66  5BufferZero(&buf
44c0: 29 3b 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69  );.    rc = sqli
44d0: 74 65 33 46 74 73 35 49 6e 64 65 78 42 65 67 69  te3Fts5IndexBegi
44e0: 6e 57 72 69 74 65 28 70 2d 3e 70 49 6e 64 65 78  nWrite(p->pIndex
44f0: 2c 20 30 2c 20 69 52 6f 77 69 64 29 3b 0a 20 20  , 0, iRowid);.  
4500: 20 20 66 6f 72 28 63 74 78 2e 69 43 6f 6c 3d 30    for(ctx.iCol=0
4510: 3b 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ; rc==SQLITE_OK 
4520: 26 26 20 63 74 78 2e 69 43 6f 6c 3c 70 43 6f 6e  && ctx.iCol<pCon
4530: 66 69 67 2d 3e 6e 43 6f 6c 3b 20 63 74 78 2e 69  fig->nCol; ctx.i
4540: 43 6f 6c 2b 2b 29 7b 0a 20 20 20 20 20 20 63 74  Col++){.      ct
4550: 78 2e 73 7a 43 6f 6c 20 3d 20 30 3b 0a 20 20 20  x.szCol = 0;.   
4560: 20 20 20 69 66 28 20 70 43 6f 6e 66 69 67 2d 3e     if( pConfig->
4570: 61 62 55 6e 69 6e 64 65 78 65 64 5b 63 74 78 2e  abUnindexed[ctx.
4580: 69 43 6f 6c 5d 3d 3d 30 20 29 7b 0a 20 20 20 20  iCol]==0 ){.    
4590: 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33      rc = sqlite3
45a0: 46 74 73 35 54 6f 6b 65 6e 69 7a 65 28 70 43 6f  Fts5Tokenize(pCo
45b0: 6e 66 69 67 2c 20 0a 20 20 20 20 20 20 20 20 20  nfig, .         
45c0: 20 20 20 46 54 53 35 5f 54 4f 4b 45 4e 49 5a 45     FTS5_TOKENIZE
45d0: 5f 44 4f 43 55 4d 45 4e 54 2c 0a 20 20 20 20 20  _DOCUMENT,.     
45e0: 20 20 20 20 20 20 20 28 63 6f 6e 73 74 20 63 68         (const ch
45f0: 61 72 2a 29 73 71 6c 69 74 65 33 5f 63 6f 6c 75  ar*)sqlite3_colu
4600: 6d 6e 5f 74 65 78 74 28 70 53 63 61 6e 2c 20 63  mn_text(pScan, c
4610: 74 78 2e 69 43 6f 6c 2b 31 29 2c 0a 20 20 20 20  tx.iCol+1),.    
4620: 20 20 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f          sqlite3_
4630: 63 6f 6c 75 6d 6e 5f 62 79 74 65 73 28 70 53 63  column_bytes(pSc
4640: 61 6e 2c 20 63 74 78 2e 69 43 6f 6c 2b 31 29 2c  an, ctx.iCol+1),
4650: 0a 20 20 20 20 20 20 20 20 20 20 20 20 28 76 6f  .            (vo
4660: 69 64 2a 29 26 63 74 78 2c 0a 20 20 20 20 20 20  id*)&ctx,.      
4670: 20 20 20 20 20 20 66 74 73 35 53 74 6f 72 61 67        fts5Storag
4680: 65 49 6e 73 65 72 74 43 61 6c 6c 62 61 63 6b 0a  eInsertCallback.
4690: 20 20 20 20 20 20 20 20 29 3b 0a 20 20 20 20 20          );.     
46a0: 20 7d 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33   }.      sqlite3
46b0: 46 74 73 35 42 75 66 66 65 72 41 70 70 65 6e 64  Fts5BufferAppend
46c0: 56 61 72 69 6e 74 28 26 72 63 2c 20 26 62 75 66  Varint(&rc, &buf
46d0: 2c 20 63 74 78 2e 73 7a 43 6f 6c 29 3b 0a 20 20  , ctx.szCol);.  
46e0: 20 20 20 20 70 2d 3e 61 54 6f 74 61 6c 53 69 7a      p->aTotalSiz
46f0: 65 5b 63 74 78 2e 69 43 6f 6c 5d 20 2b 3d 20 28  e[ctx.iCol] += (
4700: 69 36 34 29 63 74 78 2e 73 7a 43 6f 6c 3b 0a 20  i64)ctx.szCol;. 
4710: 20 20 20 7d 0a 20 20 20 20 70 2d 3e 6e 54 6f 74     }.    p->nTot
4720: 61 6c 52 6f 77 2b 2b 3b 0a 0a 20 20 20 20 69 66  alRow++;..    if
4730: 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
4740: 29 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 66 74  ){.      rc = ft
4750: 73 35 53 74 6f 72 61 67 65 49 6e 73 65 72 74 44  s5StorageInsertD
4760: 6f 63 73 69 7a 65 28 70 2c 20 69 52 6f 77 69 64  ocsize(p, iRowid
4770: 2c 20 26 62 75 66 29 3b 0a 20 20 20 20 7d 0a 20  , &buf);.    }. 
4780: 20 7d 0a 20 20 73 71 6c 69 74 65 33 5f 66 72 65   }.  sqlite3_fre
4790: 65 28 62 75 66 2e 70 29 3b 0a 20 20 72 63 32 20  e(buf.p);.  rc2 
47a0: 3d 20 73 71 6c 69 74 65 33 5f 72 65 73 65 74 28  = sqlite3_reset(
47b0: 70 53 63 61 6e 29 3b 0a 20 20 69 66 28 20 72 63  pScan);.  if( rc
47c0: 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72 63  ==SQLITE_OK ) rc
47d0: 20 3d 20 72 63 32 3b 0a 0a 20 20 2f 2a 20 57 72   = rc2;..  /* Wr
47e0: 69 74 65 20 74 68 65 20 61 76 65 72 61 67 65 73  ite the averages
47f0: 20 72 65 63 6f 72 64 20 2a 2f 0a 20 20 69 66 28   record */.  if(
4800: 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc==SQLITE_OK )
4810: 7b 0a 20 20 20 20 72 63 20 3d 20 66 74 73 35 53  {.    rc = fts5S
4820: 74 6f 72 61 67 65 53 61 76 65 54 6f 74 61 6c 73  torageSaveTotals
4830: 28 70 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72  (p);.  }.  retur
4840: 6e 20 72 63 3b 0a 7d 0a 0a 69 6e 74 20 73 71 6c  n rc;.}..int sql
4850: 69 74 65 33 46 74 73 35 53 74 6f 72 61 67 65 4f  ite3Fts5StorageO
4860: 70 74 69 6d 69 7a 65 28 46 74 73 35 53 74 6f 72  ptimize(Fts5Stor
4870: 61 67 65 20 2a 70 29 7b 0a 20 20 72 65 74 75 72  age *p){.  retur
4880: 6e 20 73 71 6c 69 74 65 33 46 74 73 35 49 6e 64  n sqlite3Fts5Ind
4890: 65 78 4f 70 74 69 6d 69 7a 65 28 70 2d 3e 70 49  exOptimize(p->pI
48a0: 6e 64 65 78 29 3b 0a 7d 0a 0a 69 6e 74 20 73 71  ndex);.}..int sq
48b0: 6c 69 74 65 33 46 74 73 35 53 74 6f 72 61 67 65  lite3Fts5Storage
48c0: 4d 65 72 67 65 28 46 74 73 35 53 74 6f 72 61 67  Merge(Fts5Storag
48d0: 65 20 2a 70 2c 20 69 6e 74 20 6e 4d 65 72 67 65  e *p, int nMerge
48e0: 29 7b 0a 20 20 72 65 74 75 72 6e 20 73 71 6c 69  ){.  return sqli
48f0: 74 65 33 46 74 73 35 49 6e 64 65 78 4d 65 72 67  te3Fts5IndexMerg
4900: 65 28 70 2d 3e 70 49 6e 64 65 78 2c 20 6e 4d 65  e(p->pIndex, nMe
4910: 72 67 65 29 3b 0a 7d 0a 0a 69 6e 74 20 73 71 6c  rge);.}..int sql
4920: 69 74 65 33 46 74 73 35 53 74 6f 72 61 67 65 52  ite3Fts5StorageR
4930: 65 73 65 74 28 46 74 73 35 53 74 6f 72 61 67 65  eset(Fts5Storage
4940: 20 2a 70 29 7b 0a 20 20 72 65 74 75 72 6e 20 73   *p){.  return s
4950: 71 6c 69 74 65 33 46 74 73 35 49 6e 64 65 78 52  qlite3Fts5IndexR
4960: 65 73 65 74 28 70 2d 3e 70 49 6e 64 65 78 29 3b  eset(p->pIndex);
4970: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41 6c 6c 6f 63 61  .}../*.** Alloca
4980: 74 65 20 61 20 6e 65 77 20 72 6f 77 69 64 2e 20  te a new rowid. 
4990: 54 68 69 73 20 69 73 20 75 73 65 64 20 66 6f 72  This is used for
49a0: 20 22 65 78 74 65 72 6e 61 6c 20 63 6f 6e 74 65   "external conte
49b0: 6e 74 22 20 74 61 62 6c 65 73 20 77 68 65 6e 0a  nt" tables when.
49c0: 2a 2a 20 61 20 4e 55 4c 4c 20 76 61 6c 75 65 20  ** a NULL value 
49d0: 69 73 20 69 6e 73 65 72 74 65 64 20 69 6e 74 6f  is inserted into
49e0: 20 74 68 65 20 72 6f 77 69 64 20 63 6f 6c 75 6d   the rowid colum
49f0: 6e 2e 20 54 68 65 20 6e 65 77 20 72 6f 77 69 64  n. The new rowid
4a00: 20 69 73 20 61 6c 6c 6f 63 61 74 65 64 0a 2a 2a   is allocated.**
4a10: 20 62 79 20 69 6e 73 65 72 74 69 6e 67 20 61 20   by inserting a 
4a20: 64 75 6d 6d 79 20 72 6f 77 20 69 6e 74 6f 20 74  dummy row into t
4a30: 68 65 20 25 5f 64 6f 63 73 69 7a 65 20 74 61 62  he %_docsize tab
4a40: 6c 65 2e 20 54 68 65 20 64 75 6d 6d 79 20 77 69  le. The dummy wi
4a50: 6c 6c 20 62 65 0a 2a 2a 20 6f 76 65 72 77 72 69  ll be.** overwri
4a60: 74 74 65 6e 20 6c 61 74 65 72 2e 0a 2a 2a 0a 2a  tten later..**.*
4a70: 2a 20 49 66 20 74 68 65 20 25 5f 64 6f 63 73 69  * If the %_docsi
4a80: 7a 65 20 74 61 62 6c 65 20 64 6f 65 73 20 6e 6f  ze table does no
4a90: 74 20 65 78 69 73 74 2c 20 53 51 4c 49 54 45 5f  t exist, SQLITE_
4aa0: 4d 49 53 4d 41 54 43 48 20 69 73 20 72 65 74 75  MISMATCH is retu
4ab0: 72 6e 65 64 2e 20 49 6e 0a 2a 2a 20 74 68 69 73  rned. In.** this
4ac0: 20 63 61 73 65 20 74 68 65 20 75 73 65 72 20 69   case the user i
4ad0: 73 20 72 65 71 75 69 72 65 64 20 74 6f 20 70 72  s required to pr
4ae0: 6f 76 69 64 65 20 61 20 72 6f 77 69 64 20 65 78  ovide a rowid ex
4af0: 70 6c 69 63 69 74 6c 79 2e 0a 2a 2f 0a 73 74 61  plicitly..*/.sta
4b00: 74 69 63 20 69 6e 74 20 66 74 73 35 53 74 6f 72  tic int fts5Stor
4b10: 61 67 65 4e 65 77 52 6f 77 69 64 28 46 74 73 35  ageNewRowid(Fts5
4b20: 53 74 6f 72 61 67 65 20 2a 70 2c 20 69 36 34 20  Storage *p, i64 
4b30: 2a 70 69 52 6f 77 69 64 29 7b 0a 20 20 69 6e 74  *piRowid){.  int
4b40: 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4d 49 53   rc = SQLITE_MIS
4b50: 4d 41 54 43 48 3b 0a 20 20 69 66 28 20 70 2d 3e  MATCH;.  if( p->
4b60: 70 43 6f 6e 66 69 67 2d 3e 62 43 6f 6c 75 6d 6e  pConfig->bColumn
4b70: 73 69 7a 65 20 29 7b 0a 20 20 20 20 73 71 6c 69  size ){.    sqli
4b80: 74 65 33 5f 73 74 6d 74 20 2a 70 52 65 70 6c 61  te3_stmt *pRepla
4b90: 63 65 20 3d 20 30 3b 0a 20 20 20 20 72 63 20 3d  ce = 0;.    rc =
4ba0: 20 66 74 73 35 53 74 6f 72 61 67 65 47 65 74 53   fts5StorageGetS
4bb0: 74 6d 74 28 70 2c 20 46 54 53 35 5f 53 54 4d 54  tmt(p, FTS5_STMT
4bc0: 5f 52 45 50 4c 41 43 45 5f 44 4f 43 53 49 5a 45  _REPLACE_DOCSIZE
4bd0: 2c 20 26 70 52 65 70 6c 61 63 65 2c 20 30 29 3b  , &pReplace, 0);
4be0: 0a 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c  .    if( rc==SQL
4bf0: 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20  ITE_OK ){.      
4c00: 73 71 6c 69 74 65 33 5f 62 69 6e 64 5f 6e 75 6c  sqlite3_bind_nul
4c10: 6c 28 70 52 65 70 6c 61 63 65 2c 20 31 29 3b 0a  l(pReplace, 1);.
4c20: 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 62 69        sqlite3_bi
4c30: 6e 64 5f 6e 75 6c 6c 28 70 52 65 70 6c 61 63 65  nd_null(pReplace
4c40: 2c 20 32 29 3b 0a 20 20 20 20 20 20 73 71 6c 69  , 2);.      sqli
4c50: 74 65 33 5f 73 74 65 70 28 70 52 65 70 6c 61 63  te3_step(pReplac
4c60: 65 29 3b 0a 20 20 20 20 20 20 72 63 20 3d 20 73  e);.      rc = s
4c70: 71 6c 69 74 65 33 5f 72 65 73 65 74 28 70 52 65  qlite3_reset(pRe
4c80: 70 6c 61 63 65 29 3b 0a 20 20 20 20 7d 0a 20 20  place);.    }.  
4c90: 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
4ca0: 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 2a 70 69  _OK ){.      *pi
4cb0: 52 6f 77 69 64 20 3d 20 73 71 6c 69 74 65 33 5f  Rowid = sqlite3_
4cc0: 6c 61 73 74 5f 69 6e 73 65 72 74 5f 72 6f 77 69  last_insert_rowi
4cd0: 64 28 70 2d 3e 70 43 6f 6e 66 69 67 2d 3e 64 62  d(p->pConfig->db
4ce0: 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 72  );.    }.  }.  r
4cf0: 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a  eturn rc;.}../*.
4d00: 2a 2a 20 49 6e 73 65 72 74 20 61 20 6e 65 77 20  ** Insert a new 
4d10: 72 6f 77 20 69 6e 74 6f 20 74 68 65 20 46 54 53  row into the FTS
4d20: 20 63 6f 6e 74 65 6e 74 20 74 61 62 6c 65 2e 0a   content table..
4d30: 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 46 74  */.int sqlite3Ft
4d40: 73 35 53 74 6f 72 61 67 65 43 6f 6e 74 65 6e 74  s5StorageContent
4d50: 49 6e 73 65 72 74 28 0a 20 20 46 74 73 35 53 74  Insert(.  Fts5St
4d60: 6f 72 61 67 65 20 2a 70 2c 20 0a 20 20 73 71 6c  orage *p, .  sql
4d70: 69 74 65 33 5f 76 61 6c 75 65 20 2a 2a 61 70 56  ite3_value **apV
4d80: 61 6c 2c 20 0a 20 20 69 36 34 20 2a 70 69 52 6f  al, .  i64 *piRo
4d90: 77 69 64 0a 29 7b 0a 20 20 46 74 73 35 43 6f 6e  wid.){.  Fts5Con
4da0: 66 69 67 20 2a 70 43 6f 6e 66 69 67 20 3d 20 70  fig *pConfig = p
4db0: 2d 3e 70 43 6f 6e 66 69 67 3b 0a 20 20 69 6e 74  ->pConfig;.  int
4dc0: 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b   rc = SQLITE_OK;
4dd0: 0a 0a 20 20 2f 2a 20 49 6e 73 65 72 74 20 74 68  ..  /* Insert th
4de0: 65 20 6e 65 77 20 72 6f 77 20 69 6e 74 6f 20 74  e new row into t
4df0: 68 65 20 25 5f 63 6f 6e 74 65 6e 74 20 74 61 62  he %_content tab
4e00: 6c 65 2e 20 2a 2f 0a 20 20 69 66 28 20 70 43 6f  le. */.  if( pCo
4e10: 6e 66 69 67 2d 3e 65 43 6f 6e 74 65 6e 74 21 3d  nfig->eContent!=
4e20: 46 54 53 35 5f 43 4f 4e 54 45 4e 54 5f 4e 4f 52  FTS5_CONTENT_NOR
4e30: 4d 41 4c 20 29 7b 0a 20 20 20 20 69 66 28 20 73  MAL ){.    if( s
4e40: 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 74 79 70  qlite3_value_typ
4e50: 65 28 61 70 56 61 6c 5b 31 5d 29 3d 3d 53 51 4c  e(apVal[1])==SQL
4e60: 49 54 45 5f 49 4e 54 45 47 45 52 20 29 7b 0a 20  ITE_INTEGER ){. 
4e70: 20 20 20 20 20 2a 70 69 52 6f 77 69 64 20 3d 20       *piRowid = 
4e80: 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 69 6e  sqlite3_value_in
4e90: 74 36 34 28 61 70 56 61 6c 5b 31 5d 29 3b 0a 20  t64(apVal[1]);. 
4ea0: 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20     }else{.      
4eb0: 72 63 20 3d 20 66 74 73 35 53 74 6f 72 61 67 65  rc = fts5Storage
4ec0: 4e 65 77 52 6f 77 69 64 28 70 2c 20 70 69 52 6f  NewRowid(p, piRo
4ed0: 77 69 64 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 65  wid);.    }.  }e
4ee0: 6c 73 65 7b 0a 20 20 20 20 73 71 6c 69 74 65 33  lse{.    sqlite3
4ef0: 5f 73 74 6d 74 20 2a 70 49 6e 73 65 72 74 20 3d  _stmt *pInsert =
4f00: 20 30 3b 20 20 20 20 2f 2a 20 53 74 61 74 65 6d   0;    /* Statem
4f10: 65 6e 74 20 74 6f 20 77 72 69 74 65 20 25 5f 63  ent to write %_c
4f20: 6f 6e 74 65 6e 74 20 74 61 62 6c 65 20 2a 2f 0a  ontent table */.
4f30: 20 20 20 20 69 6e 74 20 69 3b 20 20 20 20 20 20      int i;      
4f40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4f50: 20 20 2f 2a 20 43 6f 75 6e 74 65 72 20 76 61 72    /* Counter var
4f60: 69 61 62 6c 65 20 2a 2f 0a 20 20 20 20 72 63 20  iable */.    rc 
4f70: 3d 20 66 74 73 35 53 74 6f 72 61 67 65 47 65 74  = fts5StorageGet
4f80: 53 74 6d 74 28 70 2c 20 46 54 53 35 5f 53 54 4d  Stmt(p, FTS5_STM
4f90: 54 5f 49 4e 53 45 52 54 5f 43 4f 4e 54 45 4e 54  T_INSERT_CONTENT
4fa0: 2c 20 26 70 49 6e 73 65 72 74 2c 20 30 29 3b 0a  , &pInsert, 0);.
4fb0: 20 20 20 20 66 6f 72 28 69 3d 31 3b 20 72 63 3d      for(i=1; rc=
4fc0: 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20 69 3c  =SQLITE_OK && i<
4fd0: 3d 70 43 6f 6e 66 69 67 2d 3e 6e 43 6f 6c 2b 31  =pConfig->nCol+1
4fe0: 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20 72 63  ; i++){.      rc
4ff0: 20 3d 20 73 71 6c 69 74 65 33 5f 62 69 6e 64 5f   = sqlite3_bind_
5000: 76 61 6c 75 65 28 70 49 6e 73 65 72 74 2c 20 69  value(pInsert, i
5010: 2c 20 61 70 56 61 6c 5b 69 5d 29 3b 0a 20 20 20  , apVal[i]);.   
5020: 20 7d 0a 20 20 20 20 69 66 28 20 72 63 3d 3d 53   }.    if( rc==S
5030: 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
5040: 20 20 73 71 6c 69 74 65 33 5f 73 74 65 70 28 70    sqlite3_step(p
5050: 49 6e 73 65 72 74 29 3b 0a 20 20 20 20 20 20 72  Insert);.      r
5060: 63 20 3d 20 73 71 6c 69 74 65 33 5f 72 65 73 65  c = sqlite3_rese
5070: 74 28 70 49 6e 73 65 72 74 29 3b 0a 20 20 20 20  t(pInsert);.    
5080: 7d 0a 20 20 20 20 2a 70 69 52 6f 77 69 64 20 3d  }.    *piRowid =
5090: 20 73 71 6c 69 74 65 33 5f 6c 61 73 74 5f 69 6e   sqlite3_last_in
50a0: 73 65 72 74 5f 72 6f 77 69 64 28 70 43 6f 6e 66  sert_rowid(pConf
50b0: 69 67 2d 3e 64 62 29 3b 0a 20 20 7d 0a 0a 20 20  ig->db);.  }..  
50c0: 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a  return rc;.}../*
50d0: 0a 2a 2a 20 49 6e 73 65 72 74 20 6e 65 77 20 65  .** Insert new e
50e0: 6e 74 72 69 65 73 20 69 6e 74 6f 20 74 68 65 20  ntries into the 
50f0: 46 54 53 20 69 6e 64 65 78 20 61 6e 64 20 25 5f  FTS index and %_
5100: 64 6f 63 73 69 7a 65 20 74 61 62 6c 65 2e 0a 2a  docsize table..*
5110: 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 46 74 73  /.int sqlite3Fts
5120: 35 53 74 6f 72 61 67 65 49 6e 64 65 78 49 6e 73  5StorageIndexIns
5130: 65 72 74 28 0a 20 20 46 74 73 35 53 74 6f 72 61  ert(.  Fts5Stora
5140: 67 65 20 2a 70 2c 20 0a 20 20 73 71 6c 69 74 65  ge *p, .  sqlite
5150: 33 5f 76 61 6c 75 65 20 2a 2a 61 70 56 61 6c 2c  3_value **apVal,
5160: 20 0a 20 20 69 36 34 20 69 52 6f 77 69 64 0a 29   .  i64 iRowid.)
5170: 7b 0a 20 20 46 74 73 35 43 6f 6e 66 69 67 20 2a  {.  Fts5Config *
5180: 70 43 6f 6e 66 69 67 20 3d 20 70 2d 3e 70 43 6f  pConfig = p->pCo
5190: 6e 66 69 67 3b 0a 20 20 69 6e 74 20 72 63 20 3d  nfig;.  int rc =
51a0: 20 53 51 4c 49 54 45 5f 4f 4b 3b 20 20 20 20 20   SQLITE_OK;     
51b0: 20 20 20 20 20 20 20 20 2f 2a 20 52 65 74 75 72          /* Retur
51c0: 6e 20 63 6f 64 65 20 2a 2f 0a 20 20 46 74 73 35  n code */.  Fts5
51d0: 49 6e 73 65 72 74 43 74 78 20 63 74 78 3b 20 20  InsertCtx ctx;  
51e0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54              /* T
51f0: 6f 6b 65 6e 69 7a 61 74 69 6f 6e 20 63 61 6c 6c  okenization call
5200: 62 61 63 6b 20 63 6f 6e 74 65 78 74 20 6f 62 6a  back context obj
5210: 65 63 74 20 2a 2f 0a 20 20 46 74 73 35 42 75 66  ect */.  Fts5Buf
5220: 66 65 72 20 62 75 66 3b 20 20 20 20 20 20 20 20  fer buf;        
5230: 20 20 20 20 20 20 20 20 20 2f 2a 20 42 75 66 66           /* Buff
5240: 65 72 20 75 73 65 64 20 74 6f 20 62 75 69 6c 64  er used to build
5250: 20 75 70 20 25 5f 64 6f 63 73 69 7a 65 20 62 6c   up %_docsize bl
5260: 6f 62 20 2a 2f 0a 0a 20 20 6d 65 6d 73 65 74 28  ob */..  memset(
5270: 26 62 75 66 2c 20 30 2c 20 73 69 7a 65 6f 66 28  &buf, 0, sizeof(
5280: 46 74 73 35 42 75 66 66 65 72 29 29 3b 0a 20 20  Fts5Buffer));.  
5290: 63 74 78 2e 70 53 74 6f 72 61 67 65 20 3d 20 70  ctx.pStorage = p
52a0: 3b 0a 20 20 72 63 20 3d 20 66 74 73 35 53 74 6f  ;.  rc = fts5Sto
52b0: 72 61 67 65 4c 6f 61 64 54 6f 74 61 6c 73 28 70  rageLoadTotals(p
52c0: 2c 20 31 29 3b 0a 0a 20 20 69 66 28 20 72 63 3d  , 1);..  if( rc=
52d0: 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20  =SQLITE_OK ){.  
52e0: 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 46 74    rc = sqlite3Ft
52f0: 73 35 49 6e 64 65 78 42 65 67 69 6e 57 72 69 74  s5IndexBeginWrit
5300: 65 28 70 2d 3e 70 49 6e 64 65 78 2c 20 30 2c 20  e(p->pIndex, 0, 
5310: 69 52 6f 77 69 64 29 3b 0a 20 20 7d 0a 20 20 66  iRowid);.  }.  f
5320: 6f 72 28 63 74 78 2e 69 43 6f 6c 3d 30 3b 20 72  or(ctx.iCol=0; r
5330: 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20  c==SQLITE_OK && 
5340: 63 74 78 2e 69 43 6f 6c 3c 70 43 6f 6e 66 69 67  ctx.iCol<pConfig
5350: 2d 3e 6e 43 6f 6c 3b 20 63 74 78 2e 69 43 6f 6c  ->nCol; ctx.iCol
5360: 2b 2b 29 7b 0a 20 20 20 20 63 74 78 2e 73 7a 43  ++){.    ctx.szC
5370: 6f 6c 20 3d 20 30 3b 0a 20 20 20 20 69 66 28 20  ol = 0;.    if( 
5380: 70 43 6f 6e 66 69 67 2d 3e 61 62 55 6e 69 6e 64  pConfig->abUnind
5390: 65 78 65 64 5b 63 74 78 2e 69 43 6f 6c 5d 3d 3d  exed[ctx.iCol]==
53a0: 30 20 29 7b 0a 20 20 20 20 20 20 72 63 20 3d 20  0 ){.      rc = 
53b0: 73 71 6c 69 74 65 33 46 74 73 35 54 6f 6b 65 6e  sqlite3Fts5Token
53c0: 69 7a 65 28 70 43 6f 6e 66 69 67 2c 20 0a 20 20  ize(pConfig, .  
53d0: 20 20 20 20 20 20 20 20 46 54 53 35 5f 54 4f 4b          FTS5_TOK
53e0: 45 4e 49 5a 45 5f 44 4f 43 55 4d 45 4e 54 2c 0a  ENIZE_DOCUMENT,.
53f0: 20 20 20 20 20 20 20 20 20 20 28 63 6f 6e 73 74            (const
5400: 20 63 68 61 72 2a 29 73 71 6c 69 74 65 33 5f 76   char*)sqlite3_v
5410: 61 6c 75 65 5f 74 65 78 74 28 61 70 56 61 6c 5b  alue_text(apVal[
5420: 63 74 78 2e 69 43 6f 6c 2b 32 5d 29 2c 0a 20 20  ctx.iCol+2]),.  
5430: 20 20 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f          sqlite3_
5440: 76 61 6c 75 65 5f 62 79 74 65 73 28 61 70 56 61  value_bytes(apVa
5450: 6c 5b 63 74 78 2e 69 43 6f 6c 2b 32 5d 29 2c 0a  l[ctx.iCol+2]),.
5460: 20 20 20 20 20 20 20 20 20 20 28 76 6f 69 64 2a            (void*
5470: 29 26 63 74 78 2c 0a 20 20 20 20 20 20 20 20 20  )&ctx,.         
5480: 20 66 74 73 35 53 74 6f 72 61 67 65 49 6e 73 65   fts5StorageInse
5490: 72 74 43 61 6c 6c 62 61 63 6b 0a 20 20 20 20 20  rtCallback.     
54a0: 20 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 73 71   );.    }.    sq
54b0: 6c 69 74 65 33 46 74 73 35 42 75 66 66 65 72 41  lite3Fts5BufferA
54c0: 70 70 65 6e 64 56 61 72 69 6e 74 28 26 72 63 2c  ppendVarint(&rc,
54d0: 20 26 62 75 66 2c 20 63 74 78 2e 73 7a 43 6f 6c   &buf, ctx.szCol
54e0: 29 3b 0a 20 20 20 20 70 2d 3e 61 54 6f 74 61 6c  );.    p->aTotal
54f0: 53 69 7a 65 5b 63 74 78 2e 69 43 6f 6c 5d 20 2b  Size[ctx.iCol] +
5500: 3d 20 28 69 36 34 29 63 74 78 2e 73 7a 43 6f 6c  = (i64)ctx.szCol
5510: 3b 0a 20 20 7d 0a 20 20 70 2d 3e 6e 54 6f 74 61  ;.  }.  p->nTota
5520: 6c 52 6f 77 2b 2b 3b 0a 0a 20 20 2f 2a 20 57 72  lRow++;..  /* Wr
5530: 69 74 65 20 74 68 65 20 25 5f 64 6f 63 73 69 7a  ite the %_docsiz
5540: 65 20 72 65 63 6f 72 64 20 2a 2f 0a 20 20 69 66  e record */.  if
5550: 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
5560: 29 7b 0a 20 20 20 20 72 63 20 3d 20 66 74 73 35  ){.    rc = fts5
5570: 53 74 6f 72 61 67 65 49 6e 73 65 72 74 44 6f 63  StorageInsertDoc
5580: 73 69 7a 65 28 70 2c 20 69 52 6f 77 69 64 2c 20  size(p, iRowid, 
5590: 26 62 75 66 29 3b 0a 20 20 7d 0a 20 20 73 71 6c  &buf);.  }.  sql
55a0: 69 74 65 33 5f 66 72 65 65 28 62 75 66 2e 70 29  ite3_free(buf.p)
55b0: 3b 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a  ;..  return rc;.
55c0: 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 66 74  }..static int ft
55d0: 73 35 53 74 6f 72 61 67 65 43 6f 75 6e 74 28 46  s5StorageCount(F
55e0: 74 73 35 53 74 6f 72 61 67 65 20 2a 70 2c 20 63  ts5Storage *p, c
55f0: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 53 75 66 66  onst char *zSuff
5600: 69 78 2c 20 69 36 34 20 2a 70 6e 52 6f 77 29 7b  ix, i64 *pnRow){
5610: 0a 20 20 46 74 73 35 43 6f 6e 66 69 67 20 2a 70  .  Fts5Config *p
5620: 43 6f 6e 66 69 67 20 3d 20 70 2d 3e 70 43 6f 6e  Config = p->pCon
5630: 66 69 67 3b 0a 20 20 63 68 61 72 20 2a 7a 53 71  fig;.  char *zSq
5640: 6c 3b 0a 20 20 69 6e 74 20 72 63 3b 0a 0a 20 20  l;.  int rc;..  
5650: 7a 53 71 6c 20 3d 20 73 71 6c 69 74 65 33 5f 6d  zSql = sqlite3_m
5660: 70 72 69 6e 74 66 28 22 53 45 4c 45 43 54 20 63  printf("SELECT c
5670: 6f 75 6e 74 28 2a 29 20 46 52 4f 4d 20 25 51 2e  ount(*) FROM %Q.
5680: 27 25 71 5f 25 73 27 22 2c 20 0a 20 20 20 20 20  '%q_%s'", .     
5690: 20 70 43 6f 6e 66 69 67 2d 3e 7a 44 62 2c 20 70   pConfig->zDb, p
56a0: 43 6f 6e 66 69 67 2d 3e 7a 4e 61 6d 65 2c 20 7a  Config->zName, z
56b0: 53 75 66 66 69 78 0a 20 20 29 3b 0a 20 20 69 66  Suffix.  );.  if
56c0: 28 20 7a 53 71 6c 3d 3d 30 20 29 7b 0a 20 20 20  ( zSql==0 ){.   
56d0: 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d   rc = SQLITE_NOM
56e0: 45 4d 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20  EM;.  }else{.   
56f0: 20 73 71 6c 69 74 65 33 5f 73 74 6d 74 20 2a 70   sqlite3_stmt *p
5700: 43 6e 74 20 3d 20 30 3b 0a 20 20 20 20 72 63 20  Cnt = 0;.    rc 
5710: 3d 20 73 71 6c 69 74 65 33 5f 70 72 65 70 61 72  = sqlite3_prepar
5720: 65 5f 76 32 28 70 43 6f 6e 66 69 67 2d 3e 64 62  e_v2(pConfig->db
5730: 2c 20 7a 53 71 6c 2c 20 2d 31 2c 20 26 70 43 6e  , zSql, -1, &pCn
5740: 74 2c 20 30 29 3b 0a 20 20 20 20 69 66 28 20 72  t, 0);.    if( r
5750: 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a  c==SQLITE_OK ){.
5760: 20 20 20 20 20 20 69 66 28 20 53 51 4c 49 54 45        if( SQLITE
5770: 5f 52 4f 57 3d 3d 73 71 6c 69 74 65 33 5f 73 74  _ROW==sqlite3_st
5780: 65 70 28 70 43 6e 74 29 20 29 7b 0a 20 20 20 20  ep(pCnt) ){.    
5790: 20 20 20 20 2a 70 6e 52 6f 77 20 3d 20 73 71 6c      *pnRow = sql
57a0: 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 69 6e 74 36  ite3_column_int6
57b0: 34 28 70 43 6e 74 2c 20 30 29 3b 0a 20 20 20 20  4(pCnt, 0);.    
57c0: 20 20 7d 0a 20 20 20 20 20 20 72 63 20 3d 20 73    }.      rc = s
57d0: 71 6c 69 74 65 33 5f 66 69 6e 61 6c 69 7a 65 28  qlite3_finalize(
57e0: 70 43 6e 74 29 3b 0a 20 20 20 20 7d 0a 20 20 7d  pCnt);.    }.  }
57f0: 0a 0a 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65  ..  sqlite3_free
5800: 28 7a 53 71 6c 29 3b 0a 20 20 72 65 74 75 72 6e  (zSql);.  return
5810: 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 6f   rc;.}../*.** Co
5820: 6e 74 65 78 74 20 6f 62 6a 65 63 74 20 75 73 65  ntext object use
5830: 64 20 62 79 20 73 71 6c 69 74 65 33 46 74 73 35  d by sqlite3Fts5
5840: 53 74 6f 72 61 67 65 49 6e 74 65 67 72 69 74 79  StorageIntegrity
5850: 28 29 2e 0a 2a 2f 0a 74 79 70 65 64 65 66 20 73  ()..*/.typedef s
5860: 74 72 75 63 74 20 46 74 73 35 49 6e 74 65 67 72  truct Fts5Integr
5870: 69 74 79 43 74 78 20 46 74 73 35 49 6e 74 65 67  ityCtx Fts5Integ
5880: 72 69 74 79 43 74 78 3b 0a 73 74 72 75 63 74 20  rityCtx;.struct 
5890: 46 74 73 35 49 6e 74 65 67 72 69 74 79 43 74 78  Fts5IntegrityCtx
58a0: 20 7b 0a 20 20 69 36 34 20 69 52 6f 77 69 64 3b   {.  i64 iRowid;
58b0: 0a 20 20 69 6e 74 20 69 43 6f 6c 3b 0a 20 20 69  .  int iCol;.  i
58c0: 6e 74 20 73 7a 43 6f 6c 3b 0a 20 20 75 36 34 20  nt szCol;.  u64 
58d0: 63 6b 73 75 6d 3b 0a 20 20 46 74 73 35 54 65 72  cksum;.  Fts5Ter
58e0: 6d 73 65 74 20 2a 70 54 65 72 6d 73 65 74 3b 0a  mset *pTermset;.
58f0: 20 20 46 74 73 35 43 6f 6e 66 69 67 20 2a 70 43    Fts5Config *pC
5900: 6f 6e 66 69 67 3b 0a 7d 3b 0a 0a 0a 2f 2a 0a 2a  onfig;.};.../*.*
5910: 2a 20 54 6f 6b 65 6e 69 7a 61 74 69 6f 6e 20 63  * Tokenization c
5920: 61 6c 6c 62 61 63 6b 20 75 73 65 64 20 62 79 20  allback used by 
5930: 69 6e 74 65 67 72 69 74 79 20 63 68 65 63 6b 2e  integrity check.
5940: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 66  .*/.static int f
5950: 74 73 35 53 74 6f 72 61 67 65 49 6e 74 65 67 72  ts5StorageIntegr
5960: 69 74 79 43 61 6c 6c 62 61 63 6b 28 0a 20 20 76  ityCallback(.  v
5970: 6f 69 64 20 2a 70 43 6f 6e 74 65 78 74 2c 20 20  oid *pContext,  
5980: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
5990: 2a 20 50 6f 69 6e 74 65 72 20 74 6f 20 46 74 73  * Pointer to Fts
59a0: 35 49 6e 74 65 67 72 69 74 79 43 74 78 20 6f 62  5IntegrityCtx ob
59b0: 6a 65 63 74 20 2a 2f 0a 20 20 69 6e 74 20 74 66  ject */.  int tf
59c0: 6c 61 67 73 2c 0a 20 20 63 6f 6e 73 74 20 63 68  lags,.  const ch
59d0: 61 72 20 2a 70 54 6f 6b 65 6e 2c 20 20 20 20 20  ar *pToken,     
59e0: 20 20 20 20 20 20 20 20 2f 2a 20 42 75 66 66 65          /* Buffe
59f0: 72 20 63 6f 6e 74 61 69 6e 69 6e 67 20 74 6f 6b  r containing tok
5a00: 65 6e 20 2a 2f 0a 20 20 69 6e 74 20 6e 54 6f 6b  en */.  int nTok
5a10: 65 6e 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  en,             
5a20: 20 20 20 20 20 20 20 20 2f 2a 20 53 69 7a 65 20          /* Size 
5a30: 6f 66 20 74 6f 6b 65 6e 20 69 6e 20 62 79 74 65  of token in byte
5a40: 73 20 2a 2f 0a 20 20 69 6e 74 20 69 55 6e 75 73  s */.  int iUnus
5a50: 65 64 31 2c 20 20 20 20 20 20 20 20 20 20 20 20  ed1,            
5a60: 20 20 20 20 20 20 20 2f 2a 20 53 74 61 72 74 20         /* Start 
5a70: 6f 66 66 73 65 74 20 6f 66 20 74 6f 6b 65 6e 20  offset of token 
5a80: 2a 2f 0a 20 20 69 6e 74 20 69 55 6e 75 73 65 64  */.  int iUnused
5a90: 32 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  2               
5aa0: 20 20 20 20 20 2f 2a 20 45 6e 64 20 6f 66 66 73       /* End offs
5ab0: 65 74 20 6f 66 20 74 6f 6b 65 6e 20 2a 2f 0a 29  et of token */.)
5ac0: 7b 0a 20 20 46 74 73 35 49 6e 74 65 67 72 69 74  {.  Fts5Integrit
5ad0: 79 43 74 78 20 2a 70 43 74 78 20 3d 20 28 46 74  yCtx *pCtx = (Ft
5ae0: 73 35 49 6e 74 65 67 72 69 74 79 43 74 78 2a 29  s5IntegrityCtx*)
5af0: 70 43 6f 6e 74 65 78 74 3b 0a 20 20 46 74 73 35  pContext;.  Fts5
5b00: 54 65 72 6d 73 65 74 20 2a 70 54 65 72 6d 73 65  Termset *pTermse
5b10: 74 20 3d 20 70 43 74 78 2d 3e 70 54 65 72 6d 73  t = pCtx->pTerms
5b20: 65 74 3b 0a 20 20 69 6e 74 20 62 50 72 65 73 65  et;.  int bPrese
5b30: 6e 74 3b 0a 20 20 69 6e 74 20 69 69 3b 0a 20 20  nt;.  int ii;.  
5b40: 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f  int rc = SQLITE_
5b50: 4f 4b 3b 0a 20 20 69 6e 74 20 69 50 6f 73 3b 0a  OK;.  int iPos;.
5b60: 20 20 69 6e 74 20 69 43 6f 6c 3b 0a 0a 20 20 55    int iCol;..  U
5b70: 4e 55 53 45 44 5f 50 41 52 41 4d 32 28 69 55 6e  NUSED_PARAM2(iUn
5b80: 75 73 65 64 31 2c 20 69 55 6e 75 73 65 64 32 29  used1, iUnused2)
5b90: 3b 0a 20 20 69 66 28 20 6e 54 6f 6b 65 6e 3e 46  ;.  if( nToken>F
5ba0: 54 53 35 5f 4d 41 58 5f 54 4f 4b 45 4e 5f 53 49  TS5_MAX_TOKEN_SI
5bb0: 5a 45 20 29 20 6e 54 6f 6b 65 6e 20 3d 20 46 54  ZE ) nToken = FT
5bc0: 53 35 5f 4d 41 58 5f 54 4f 4b 45 4e 5f 53 49 5a  S5_MAX_TOKEN_SIZ
5bd0: 45 3b 0a 0a 20 20 69 66 28 20 28 74 66 6c 61 67  E;..  if( (tflag
5be0: 73 20 26 20 46 54 53 35 5f 54 4f 4b 45 4e 5f 43  s & FTS5_TOKEN_C
5bf0: 4f 4c 4f 43 41 54 45 44 29 3d 3d 30 20 7c 7c 20  OLOCATED)==0 || 
5c00: 70 43 74 78 2d 3e 73 7a 43 6f 6c 3d 3d 30 20 29  pCtx->szCol==0 )
5c10: 7b 0a 20 20 20 20 70 43 74 78 2d 3e 73 7a 43 6f  {.    pCtx->szCo
5c20: 6c 2b 2b 3b 0a 20 20 7d 0a 0a 20 20 73 77 69 74  l++;.  }..  swit
5c30: 63 68 28 20 70 43 74 78 2d 3e 70 43 6f 6e 66 69  ch( pCtx->pConfi
5c40: 67 2d 3e 65 44 65 74 61 69 6c 20 29 7b 0a 20 20  g->eDetail ){.  
5c50: 20 20 63 61 73 65 20 46 54 53 35 5f 44 45 54 41    case FTS5_DETA
5c60: 49 4c 5f 46 55 4c 4c 3a 0a 20 20 20 20 20 20 69  IL_FULL:.      i
5c70: 50 6f 73 20 3d 20 70 43 74 78 2d 3e 73 7a 43 6f  Pos = pCtx->szCo
5c80: 6c 2d 31 3b 0a 20 20 20 20 20 20 69 43 6f 6c 20  l-1;.      iCol 
5c90: 3d 20 70 43 74 78 2d 3e 69 43 6f 6c 3b 0a 20 20  = pCtx->iCol;.  
5ca0: 20 20 20 20 62 72 65 61 6b 3b 0a 0a 20 20 20 20      break;..    
5cb0: 63 61 73 65 20 46 54 53 35 5f 44 45 54 41 49 4c  case FTS5_DETAIL
5cc0: 5f 43 4f 4c 55 4d 4e 53 3a 0a 20 20 20 20 20 20  _COLUMNS:.      
5cd0: 69 50 6f 73 20 3d 20 70 43 74 78 2d 3e 69 43 6f  iPos = pCtx->iCo
5ce0: 6c 3b 0a 20 20 20 20 20 20 69 43 6f 6c 20 3d 20  l;.      iCol = 
5cf0: 30 3b 0a 20 20 20 20 20 20 62 72 65 61 6b 3b 0a  0;.      break;.
5d00: 0a 20 20 20 20 64 65 66 61 75 6c 74 3a 0a 20 20  .    default:.  
5d10: 20 20 20 20 61 73 73 65 72 74 28 20 70 43 74 78      assert( pCtx
5d20: 2d 3e 70 43 6f 6e 66 69 67 2d 3e 65 44 65 74 61  ->pConfig->eDeta
5d30: 69 6c 3d 3d 46 54 53 35 5f 44 45 54 41 49 4c 5f  il==FTS5_DETAIL_
5d40: 4e 4f 4e 45 20 29 3b 0a 20 20 20 20 20 20 69 50  NONE );.      iP
5d50: 6f 73 20 3d 20 30 3b 0a 20 20 20 20 20 20 69 43  os = 0;.      iC
5d60: 6f 6c 20 3d 20 30 3b 0a 20 20 20 20 20 20 62 72  ol = 0;.      br
5d70: 65 61 6b 3b 0a 20 20 7d 0a 0a 20 20 72 63 20 3d  eak;.  }..  rc =
5d80: 20 73 71 6c 69 74 65 33 46 74 73 35 54 65 72 6d   sqlite3Fts5Term
5d90: 73 65 74 41 64 64 28 70 54 65 72 6d 73 65 74 2c  setAdd(pTermset,
5da0: 20 30 2c 20 70 54 6f 6b 65 6e 2c 20 6e 54 6f 6b   0, pToken, nTok
5db0: 65 6e 2c 20 26 62 50 72 65 73 65 6e 74 29 3b 0a  en, &bPresent);.
5dc0: 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
5dd0: 5f 4f 4b 20 26 26 20 62 50 72 65 73 65 6e 74 3d  _OK && bPresent=
5de0: 3d 30 20 29 7b 0a 20 20 20 20 70 43 74 78 2d 3e  =0 ){.    pCtx->
5df0: 63 6b 73 75 6d 20 5e 3d 20 73 71 6c 69 74 65 33  cksum ^= sqlite3
5e00: 46 74 73 35 49 6e 64 65 78 45 6e 74 72 79 43 6b  Fts5IndexEntryCk
5e10: 73 75 6d 28 0a 20 20 20 20 20 20 20 20 70 43 74  sum(.        pCt
5e20: 78 2d 3e 69 52 6f 77 69 64 2c 20 69 43 6f 6c 2c  x->iRowid, iCol,
5e30: 20 69 50 6f 73 2c 20 30 2c 20 70 54 6f 6b 65 6e   iPos, 0, pToken
5e40: 2c 20 6e 54 6f 6b 65 6e 0a 20 20 20 20 29 3b 0a  , nToken.    );.
5e50: 20 20 7d 0a 0a 20 20 66 6f 72 28 69 69 3d 30 3b    }..  for(ii=0;
5e60: 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26   rc==SQLITE_OK &
5e70: 26 20 69 69 3c 70 43 74 78 2d 3e 70 43 6f 6e 66  & ii<pCtx->pConf
5e80: 69 67 2d 3e 6e 50 72 65 66 69 78 3b 20 69 69 2b  ig->nPrefix; ii+
5e90: 2b 29 7b 0a 20 20 20 20 63 6f 6e 73 74 20 69 6e  +){.    const in
5ea0: 74 20 6e 43 68 61 72 20 3d 20 70 43 74 78 2d 3e  t nChar = pCtx->
5eb0: 70 43 6f 6e 66 69 67 2d 3e 61 50 72 65 66 69 78  pConfig->aPrefix
5ec0: 5b 69 69 5d 3b 0a 20 20 20 20 69 6e 74 20 6e 42  [ii];.    int nB
5ed0: 79 74 65 20 3d 20 73 71 6c 69 74 65 33 46 74 73  yte = sqlite3Fts
5ee0: 35 49 6e 64 65 78 43 68 61 72 6c 65 6e 54 6f 42  5IndexCharlenToB
5ef0: 79 74 65 6c 65 6e 28 70 54 6f 6b 65 6e 2c 20 6e  ytelen(pToken, n
5f00: 54 6f 6b 65 6e 2c 20 6e 43 68 61 72 29 3b 0a 20  Token, nChar);. 
5f10: 20 20 20 69 66 28 20 6e 42 79 74 65 20 29 7b 0a     if( nByte ){.
5f20: 20 20 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74        rc = sqlit
5f30: 65 33 46 74 73 35 54 65 72 6d 73 65 74 41 64 64  e3Fts5TermsetAdd
5f40: 28 70 54 65 72 6d 73 65 74 2c 20 69 69 2b 31 2c  (pTermset, ii+1,
5f50: 20 70 54 6f 6b 65 6e 2c 20 6e 42 79 74 65 2c 20   pToken, nByte, 
5f60: 26 62 50 72 65 73 65 6e 74 29 3b 0a 20 20 20 20  &bPresent);.    
5f70: 20 20 69 66 28 20 62 50 72 65 73 65 6e 74 3d 3d    if( bPresent==
5f80: 30 20 29 7b 0a 20 20 20 20 20 20 20 20 70 43 74  0 ){.        pCt
5f90: 78 2d 3e 63 6b 73 75 6d 20 5e 3d 20 73 71 6c 69  x->cksum ^= sqli
5fa0: 74 65 33 46 74 73 35 49 6e 64 65 78 45 6e 74 72  te3Fts5IndexEntr
5fb0: 79 43 6b 73 75 6d 28 0a 20 20 20 20 20 20 20 20  yCksum(.        
5fc0: 20 20 20 20 70 43 74 78 2d 3e 69 52 6f 77 69 64      pCtx->iRowid
5fd0: 2c 20 69 43 6f 6c 2c 20 69 50 6f 73 2c 20 69 69  , iCol, iPos, ii
5fe0: 2b 31 2c 20 70 54 6f 6b 65 6e 2c 20 6e 42 79 74  +1, pToken, nByt
5ff0: 65 0a 20 20 20 20 20 20 20 20 29 3b 0a 20 20 20  e.        );.   
6000: 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a     }.    }.  }..
6010: 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a    return rc;.}..
6020: 2f 2a 0a 2a 2a 20 43 68 65 63 6b 20 74 68 61 74  /*.** Check that
6030: 20 74 68 65 20 63 6f 6e 74 65 6e 74 73 20 6f 66   the contents of
6040: 20 74 68 65 20 46 54 53 20 69 6e 64 65 78 20 6d   the FTS index m
6050: 61 74 63 68 20 74 68 61 74 20 6f 66 20 74 68 65  atch that of the
6060: 20 25 5f 63 6f 6e 74 65 6e 74 0a 2a 2a 20 74 61   %_content.** ta
6070: 62 6c 65 2e 20 52 65 74 75 72 6e 20 53 51 4c 49  ble. Return SQLI
6080: 54 45 5f 4f 4b 20 69 66 20 74 68 65 79 20 64 6f  TE_OK if they do
6090: 2c 20 6f 72 20 53 51 4c 49 54 45 5f 43 4f 52 52  , or SQLITE_CORR
60a0: 55 50 54 20 69 66 20 6e 6f 74 2e 20 52 65 74 75  UPT if not. Retu
60b0: 72 6e 0a 2a 2a 20 73 6f 6d 65 20 6f 74 68 65 72  rn.** some other
60c0: 20 53 51 4c 69 74 65 20 65 72 72 6f 72 20 63 6f   SQLite error co
60d0: 64 65 20 69 66 20 61 6e 20 65 72 72 6f 72 20 6f  de if an error o
60e0: 63 63 75 72 73 20 77 68 69 6c 65 20 61 74 74 65  ccurs while atte
60f0: 6d 70 74 69 6e 67 20 74 6f 0a 2a 2a 20 64 65 74  mpting to.** det
6100: 65 72 6d 69 6e 65 20 74 68 69 73 2e 0a 2a 2f 0a  ermine this..*/.
6110: 69 6e 74 20 73 71 6c 69 74 65 33 46 74 73 35 53  int sqlite3Fts5S
6120: 74 6f 72 61 67 65 49 6e 74 65 67 72 69 74 79 28  torageIntegrity(
6130: 46 74 73 35 53 74 6f 72 61 67 65 20 2a 70 29 7b  Fts5Storage *p){
6140: 0a 20 20 46 74 73 35 43 6f 6e 66 69 67 20 2a 70  .  Fts5Config *p
6150: 43 6f 6e 66 69 67 20 3d 20 70 2d 3e 70 43 6f 6e  Config = p->pCon
6160: 66 69 67 3b 0a 20 20 69 6e 74 20 72 63 3b 20 20  fig;.  int rc;  
6170: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6180: 20 20 20 20 20 20 20 2f 2a 20 52 65 74 75 72 6e         /* Return
6190: 20 63 6f 64 65 20 2a 2f 0a 20 20 69 6e 74 20 2a   code */.  int *
61a0: 61 43 6f 6c 53 69 7a 65 3b 20 20 20 20 20 20 20  aColSize;       
61b0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 41 72             /* Ar
61c0: 72 61 79 20 6f 66 20 73 69 7a 65 20 70 43 6f 6e  ray of size pCon
61d0: 66 69 67 2d 3e 6e 43 6f 6c 20 2a 2f 0a 20 20 69  fig->nCol */.  i
61e0: 36 34 20 2a 61 54 6f 74 61 6c 53 69 7a 65 3b 20  64 *aTotalSize; 
61f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
6200: 2a 20 41 72 72 61 79 20 6f 66 20 73 69 7a 65 20  * Array of size 
6210: 70 43 6f 6e 66 69 67 2d 3e 6e 43 6f 6c 20 2a 2f  pConfig->nCol */
6220: 0a 20 20 46 74 73 35 49 6e 74 65 67 72 69 74 79  .  Fts5Integrity
6230: 43 74 78 20 63 74 78 3b 0a 20 20 73 71 6c 69 74  Ctx ctx;.  sqlit
6240: 65 33 5f 73 74 6d 74 20 2a 70 53 63 61 6e 3b 0a  e3_stmt *pScan;.
6250: 0a 20 20 6d 65 6d 73 65 74 28 26 63 74 78 2c 20  .  memset(&ctx, 
6260: 30 2c 20 73 69 7a 65 6f 66 28 46 74 73 35 49 6e  0, sizeof(Fts5In
6270: 74 65 67 72 69 74 79 43 74 78 29 29 3b 0a 20 20  tegrityCtx));.  
6280: 63 74 78 2e 70 43 6f 6e 66 69 67 20 3d 20 70 2d  ctx.pConfig = p-
6290: 3e 70 43 6f 6e 66 69 67 3b 0a 20 20 61 54 6f 74  >pConfig;.  aTot
62a0: 61 6c 53 69 7a 65 20 3d 20 28 69 36 34 2a 29 73  alSize = (i64*)s
62b0: 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63 36 34 28  qlite3_malloc64(
62c0: 70 43 6f 6e 66 69 67 2d 3e 6e 43 6f 6c 2a 28 73  pConfig->nCol*(s
62d0: 69 7a 65 6f 66 28 69 6e 74 29 2b 73 69 7a 65 6f  izeof(int)+sizeo
62e0: 66 28 69 36 34 29 29 29 3b 0a 20 20 69 66 28 20  f(i64)));.  if( 
62f0: 21 61 54 6f 74 61 6c 53 69 7a 65 20 29 20 72 65  !aTotalSize ) re
6300: 74 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45  turn SQLITE_NOME
6310: 4d 3b 0a 20 20 61 43 6f 6c 53 69 7a 65 20 3d 20  M;.  aColSize = 
6320: 28 69 6e 74 2a 29 26 61 54 6f 74 61 6c 53 69 7a  (int*)&aTotalSiz
6330: 65 5b 70 43 6f 6e 66 69 67 2d 3e 6e 43 6f 6c 5d  e[pConfig->nCol]
6340: 3b 0a 20 20 6d 65 6d 73 65 74 28 61 54 6f 74 61  ;.  memset(aTota
6350: 6c 53 69 7a 65 2c 20 30 2c 20 73 69 7a 65 6f 66  lSize, 0, sizeof
6360: 28 69 36 34 29 20 2a 20 70 43 6f 6e 66 69 67 2d  (i64) * pConfig-
6370: 3e 6e 43 6f 6c 29 3b 0a 0a 20 20 2f 2a 20 47 65  >nCol);..  /* Ge
6380: 6e 65 72 61 74 65 20 74 68 65 20 65 78 70 65 63  nerate the expec
6390: 74 65 64 20 69 6e 64 65 78 20 63 68 65 63 6b 73  ted index checks
63a0: 75 6d 20 62 61 73 65 64 20 6f 6e 20 74 68 65 20  um based on the 
63b0: 63 6f 6e 74 65 6e 74 73 20 6f 66 20 74 68 65 0a  contents of the.
63c0: 20 20 2a 2a 20 25 5f 63 6f 6e 74 65 6e 74 20 74    ** %_content t
63d0: 61 62 6c 65 2e 20 54 68 69 73 20 62 6c 6f 63 6b  able. This block
63e0: 20 73 74 6f 72 65 73 20 74 68 65 20 63 68 65 63   stores the chec
63f0: 6b 73 75 6d 20 69 6e 20 63 74 78 2e 63 6b 73 75  ksum in ctx.cksu
6400: 6d 2e 20 2a 2f 0a 20 20 72 63 20 3d 20 66 74 73  m. */.  rc = fts
6410: 35 53 74 6f 72 61 67 65 47 65 74 53 74 6d 74 28  5StorageGetStmt(
6420: 70 2c 20 46 54 53 35 5f 53 54 4d 54 5f 53 43 41  p, FTS5_STMT_SCA
6430: 4e 2c 20 26 70 53 63 61 6e 2c 20 30 29 3b 0a 20  N, &pScan, 0);. 
6440: 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
6450: 4f 4b 20 29 7b 0a 20 20 20 20 69 6e 74 20 72 63  OK ){.    int rc
6460: 32 3b 0a 20 20 20 20 77 68 69 6c 65 28 20 53 51  2;.    while( SQ
6470: 4c 49 54 45 5f 52 4f 57 3d 3d 73 71 6c 69 74 65  LITE_ROW==sqlite
6480: 33 5f 73 74 65 70 28 70 53 63 61 6e 29 20 29 7b  3_step(pScan) ){
6490: 0a 20 20 20 20 20 20 69 6e 74 20 69 3b 0a 20 20  .      int i;.  
64a0: 20 20 20 20 63 74 78 2e 69 52 6f 77 69 64 20 3d      ctx.iRowid =
64b0: 20 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f   sqlite3_column_
64c0: 69 6e 74 36 34 28 70 53 63 61 6e 2c 20 30 29 3b  int64(pScan, 0);
64d0: 0a 20 20 20 20 20 20 63 74 78 2e 73 7a 43 6f 6c  .      ctx.szCol
64e0: 20 3d 20 30 3b 0a 20 20 20 20 20 20 69 66 28 20   = 0;.      if( 
64f0: 70 43 6f 6e 66 69 67 2d 3e 62 43 6f 6c 75 6d 6e  pConfig->bColumn
6500: 73 69 7a 65 20 29 7b 0a 20 20 20 20 20 20 20 20  size ){.        
6510: 72 63 20 3d 20 73 71 6c 69 74 65 33 46 74 73 35  rc = sqlite3Fts5
6520: 53 74 6f 72 61 67 65 44 6f 63 73 69 7a 65 28 70  StorageDocsize(p
6530: 2c 20 63 74 78 2e 69 52 6f 77 69 64 2c 20 61 43  , ctx.iRowid, aC
6540: 6f 6c 53 69 7a 65 29 3b 0a 20 20 20 20 20 20 7d  olSize);.      }
6550: 0a 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d 53  .      if( rc==S
6560: 51 4c 49 54 45 5f 4f 4b 20 26 26 20 70 43 6f 6e  QLITE_OK && pCon
6570: 66 69 67 2d 3e 65 44 65 74 61 69 6c 3d 3d 46 54  fig->eDetail==FT
6580: 53 35 5f 44 45 54 41 49 4c 5f 4e 4f 4e 45 20 29  S5_DETAIL_NONE )
6590: 7b 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20 73  {.        rc = s
65a0: 71 6c 69 74 65 33 46 74 73 35 54 65 72 6d 73 65  qlite3Fts5Termse
65b0: 74 4e 65 77 28 26 63 74 78 2e 70 54 65 72 6d 73  tNew(&ctx.pTerms
65c0: 65 74 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20  et);.      }.   
65d0: 20 20 20 66 6f 72 28 69 3d 30 3b 20 72 63 3d 3d     for(i=0; rc==
65e0: 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20 69 3c 70  SQLITE_OK && i<p
65f0: 43 6f 6e 66 69 67 2d 3e 6e 43 6f 6c 3b 20 69 2b  Config->nCol; i+
6600: 2b 29 7b 0a 20 20 20 20 20 20 20 20 69 66 28 20  +){.        if( 
6610: 70 43 6f 6e 66 69 67 2d 3e 61 62 55 6e 69 6e 64  pConfig->abUnind
6620: 65 78 65 64 5b 69 5d 20 29 20 63 6f 6e 74 69 6e  exed[i] ) contin
6630: 75 65 3b 0a 20 20 20 20 20 20 20 20 63 74 78 2e  ue;.        ctx.
6640: 69 43 6f 6c 20 3d 20 69 3b 0a 20 20 20 20 20 20  iCol = i;.      
6650: 20 20 63 74 78 2e 73 7a 43 6f 6c 20 3d 20 30 3b    ctx.szCol = 0;
6660: 0a 20 20 20 20 20 20 20 20 69 66 28 20 70 43 6f  .        if( pCo
6670: 6e 66 69 67 2d 3e 65 44 65 74 61 69 6c 3d 3d 46  nfig->eDetail==F
6680: 54 53 35 5f 44 45 54 41 49 4c 5f 43 4f 4c 55 4d  TS5_DETAIL_COLUM
6690: 4e 53 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20  NS ){.          
66a0: 72 63 20 3d 20 73 71 6c 69 74 65 33 46 74 73 35  rc = sqlite3Fts5
66b0: 54 65 72 6d 73 65 74 4e 65 77 28 26 63 74 78 2e  TermsetNew(&ctx.
66c0: 70 54 65 72 6d 73 65 74 29 3b 0a 20 20 20 20 20  pTermset);.     
66d0: 20 20 20 7d 0a 20 20 20 20 20 20 20 20 69 66 28     }.        if(
66e0: 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc==SQLITE_OK )
66f0: 7b 0a 20 20 20 20 20 20 20 20 20 20 72 63 20 3d  {.          rc =
6700: 20 73 71 6c 69 74 65 33 46 74 73 35 54 6f 6b 65   sqlite3Fts5Toke
6710: 6e 69 7a 65 28 70 43 6f 6e 66 69 67 2c 20 0a 20  nize(pConfig, . 
6720: 20 20 20 20 20 20 20 20 20 20 20 20 20 46 54 53               FTS
6730: 35 5f 54 4f 4b 45 4e 49 5a 45 5f 44 4f 43 55 4d  5_TOKENIZE_DOCUM
6740: 45 4e 54 2c 0a 20 20 20 20 20 20 20 20 20 20 20  ENT,.           
6750: 20 20 20 28 63 6f 6e 73 74 20 63 68 61 72 2a 29     (const char*)
6760: 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 74  sqlite3_column_t
6770: 65 78 74 28 70 53 63 61 6e 2c 20 69 2b 31 29 2c  ext(pScan, i+1),
6780: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 73  .              s
6790: 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 62 79  qlite3_column_by
67a0: 74 65 73 28 70 53 63 61 6e 2c 20 69 2b 31 29 2c  tes(pScan, i+1),
67b0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 28  .              (
67c0: 76 6f 69 64 2a 29 26 63 74 78 2c 0a 20 20 20 20  void*)&ctx,.    
67d0: 20 20 20 20 20 20 20 20 20 20 66 74 73 35 53 74            fts5St
67e0: 6f 72 61 67 65 49 6e 74 65 67 72 69 74 79 43 61  orageIntegrityCa
67f0: 6c 6c 62 61 63 6b 0a 20 20 20 20 20 20 20 20 20  llback.         
6800: 20 29 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20   );.        }.  
6810: 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51        if( rc==SQ
6820: 4c 49 54 45 5f 4f 4b 20 26 26 20 70 43 6f 6e 66  LITE_OK && pConf
6830: 69 67 2d 3e 62 43 6f 6c 75 6d 6e 73 69 7a 65 20  ig->bColumnsize 
6840: 26 26 20 63 74 78 2e 73 7a 43 6f 6c 21 3d 61 43  && ctx.szCol!=aC
6850: 6f 6c 53 69 7a 65 5b 69 5d 20 29 7b 0a 20 20 20  olSize[i] ){.   
6860: 20 20 20 20 20 20 20 72 63 20 3d 20 46 54 53 35         rc = FTS5
6870: 5f 43 4f 52 52 55 50 54 3b 0a 20 20 20 20 20 20  _CORRUPT;.      
6880: 20 20 7d 0a 20 20 20 20 20 20 20 20 61 54 6f 74    }.        aTot
6890: 61 6c 53 69 7a 65 5b 69 5d 20 2b 3d 20 63 74 78  alSize[i] += ctx
68a0: 2e 73 7a 43 6f 6c 3b 0a 20 20 20 20 20 20 20 20  .szCol;.        
68b0: 69 66 28 20 70 43 6f 6e 66 69 67 2d 3e 65 44 65  if( pConfig->eDe
68c0: 74 61 69 6c 3d 3d 46 54 53 35 5f 44 45 54 41 49  tail==FTS5_DETAI
68d0: 4c 5f 43 4f 4c 55 4d 4e 53 20 29 7b 0a 20 20 20  L_COLUMNS ){.   
68e0: 20 20 20 20 20 20 20 73 71 6c 69 74 65 33 46 74         sqlite3Ft
68f0: 73 35 54 65 72 6d 73 65 74 46 72 65 65 28 63 74  s5TermsetFree(ct
6900: 78 2e 70 54 65 72 6d 73 65 74 29 3b 0a 20 20 20  x.pTermset);.   
6910: 20 20 20 20 20 20 20 63 74 78 2e 70 54 65 72 6d         ctx.pTerm
6920: 73 65 74 20 3d 20 30 3b 0a 20 20 20 20 20 20 20  set = 0;.       
6930: 20 7d 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20   }.      }.     
6940: 20 73 71 6c 69 74 65 33 46 74 73 35 54 65 72 6d   sqlite3Fts5Term
6950: 73 65 74 46 72 65 65 28 63 74 78 2e 70 54 65 72  setFree(ctx.pTer
6960: 6d 73 65 74 29 3b 0a 20 20 20 20 20 20 63 74 78  mset);.      ctx
6970: 2e 70 54 65 72 6d 73 65 74 20 3d 20 30 3b 0a 0a  .pTermset = 0;..
6980: 20 20 20 20 20 20 69 66 28 20 72 63 21 3d 53 51        if( rc!=SQ
6990: 4c 49 54 45 5f 4f 4b 20 29 20 62 72 65 61 6b 3b  LITE_OK ) break;
69a0: 0a 20 20 20 20 7d 0a 20 20 20 20 72 63 32 20 3d  .    }.    rc2 =
69b0: 20 73 71 6c 69 74 65 33 5f 72 65 73 65 74 28 70   sqlite3_reset(p
69c0: 53 63 61 6e 29 3b 0a 20 20 20 20 69 66 28 20 72  Scan);.    if( r
69d0: 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72  c==SQLITE_OK ) r
69e0: 63 20 3d 20 72 63 32 3b 0a 20 20 7d 0a 0a 20 20  c = rc2;.  }..  
69f0: 2f 2a 20 54 65 73 74 20 74 68 61 74 20 74 68 65  /* Test that the
6a00: 20 22 74 6f 74 61 6c 73 22 20 28 73 6f 6d 65 74   "totals" (somet
6a10: 69 6d 65 73 20 63 61 6c 6c 65 64 20 22 61 76 65  imes called "ave
6a20: 72 61 67 65 73 22 29 20 72 65 63 6f 72 64 20 6c  rages") record l
6a30: 6f 6f 6b 73 20 4f 6b 20 2a 2f 0a 20 20 69 66 28  ooks Ok */.  if(
6a40: 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc==SQLITE_OK )
6a50: 7b 0a 20 20 20 20 69 6e 74 20 69 3b 0a 20 20 20  {.    int i;.   
6a60: 20 72 63 20 3d 20 66 74 73 35 53 74 6f 72 61 67   rc = fts5Storag
6a70: 65 4c 6f 61 64 54 6f 74 61 6c 73 28 70 2c 20 30  eLoadTotals(p, 0
6a80: 29 3b 0a 20 20 20 20 66 6f 72 28 69 3d 30 3b 20  );.    for(i=0; 
6a90: 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26  rc==SQLITE_OK &&
6aa0: 20 69 3c 70 43 6f 6e 66 69 67 2d 3e 6e 43 6f 6c   i<pConfig->nCol
6ab0: 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20 69 66  ; i++){.      if
6ac0: 28 20 70 2d 3e 61 54 6f 74 61 6c 53 69 7a 65 5b  ( p->aTotalSize[
6ad0: 69 5d 21 3d 61 54 6f 74 61 6c 53 69 7a 65 5b 69  i]!=aTotalSize[i
6ae0: 5d 20 29 20 72 63 20 3d 20 46 54 53 35 5f 43 4f  ] ) rc = FTS5_CO
6af0: 52 52 55 50 54 3b 0a 20 20 20 20 7d 0a 20 20 7d  RRUPT;.    }.  }
6b00: 0a 0a 20 20 2f 2a 20 43 68 65 63 6b 20 74 68 61  ..  /* Check tha
6b10: 74 20 74 68 65 20 25 5f 64 6f 63 73 69 7a 65 20  t the %_docsize 
6b20: 61 6e 64 20 25 5f 63 6f 6e 74 65 6e 74 20 74 61  and %_content ta
6b30: 62 6c 65 73 20 63 6f 6e 74 61 69 6e 20 74 68 65  bles contain the
6b40: 20 65 78 70 65 63 74 65 64 0a 20 20 2a 2a 20 6e   expected.  ** n
6b50: 75 6d 62 65 72 20 6f 66 20 72 6f 77 73 2e 20 20  umber of rows.  
6b60: 2a 2f 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c  */.  if( rc==SQL
6b70: 49 54 45 5f 4f 4b 20 26 26 20 70 43 6f 6e 66 69  ITE_OK && pConfi
6b80: 67 2d 3e 65 43 6f 6e 74 65 6e 74 3d 3d 46 54 53  g->eContent==FTS
6b90: 35 5f 43 4f 4e 54 45 4e 54 5f 4e 4f 52 4d 41 4c  5_CONTENT_NORMAL
6ba0: 20 29 7b 0a 20 20 20 20 69 36 34 20 6e 52 6f 77   ){.    i64 nRow
6bb0: 20 3d 20 30 3b 0a 20 20 20 20 72 63 20 3d 20 66   = 0;.    rc = f
6bc0: 74 73 35 53 74 6f 72 61 67 65 43 6f 75 6e 74 28  ts5StorageCount(
6bd0: 70 2c 20 22 63 6f 6e 74 65 6e 74 22 2c 20 26 6e  p, "content", &n
6be0: 52 6f 77 29 3b 0a 20 20 20 20 69 66 28 20 72 63  Row);.    if( rc
6bf0: 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20 6e  ==SQLITE_OK && n
6c00: 52 6f 77 21 3d 70 2d 3e 6e 54 6f 74 61 6c 52 6f  Row!=p->nTotalRo
6c10: 77 20 29 20 72 63 20 3d 20 46 54 53 35 5f 43 4f  w ) rc = FTS5_CO
6c20: 52 52 55 50 54 3b 0a 20 20 7d 0a 20 20 69 66 28  RRUPT;.  }.  if(
6c30: 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26   rc==SQLITE_OK &
6c40: 26 20 70 43 6f 6e 66 69 67 2d 3e 62 43 6f 6c 75  & pConfig->bColu
6c50: 6d 6e 73 69 7a 65 20 29 7b 0a 20 20 20 20 69 36  mnsize ){.    i6
6c60: 34 20 6e 52 6f 77 20 3d 20 30 3b 0a 20 20 20 20  4 nRow = 0;.    
6c70: 72 63 20 3d 20 66 74 73 35 53 74 6f 72 61 67 65  rc = fts5Storage
6c80: 43 6f 75 6e 74 28 70 2c 20 22 64 6f 63 73 69 7a  Count(p, "docsiz
6c90: 65 22 2c 20 26 6e 52 6f 77 29 3b 0a 20 20 20 20  e", &nRow);.    
6ca0: 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  if( rc==SQLITE_O
6cb0: 4b 20 26 26 20 6e 52 6f 77 21 3d 70 2d 3e 6e 54  K && nRow!=p->nT
6cc0: 6f 74 61 6c 52 6f 77 20 29 20 72 63 20 3d 20 46  otalRow ) rc = F
6cd0: 54 53 35 5f 43 4f 52 52 55 50 54 3b 0a 20 20 7d  TS5_CORRUPT;.  }
6ce0: 0a 0a 20 20 2f 2a 20 50 61 73 73 20 74 68 65 20  ..  /* Pass the 
6cf0: 65 78 70 65 63 74 65 64 20 63 68 65 63 6b 73 75  expected checksu
6d00: 6d 20 64 6f 77 6e 20 74 6f 20 74 68 65 20 46 54  m down to the FT
6d10: 53 20 69 6e 64 65 78 20 6d 6f 64 75 6c 65 2e 20  S index module. 
6d20: 49 74 20 77 69 6c 6c 0a 20 20 2a 2a 20 76 65 72  It will.  ** ver
6d30: 69 66 79 2c 20 61 6d 6f 6e 67 73 74 20 6f 74 68  ify, amongst oth
6d40: 65 72 20 74 68 69 6e 67 73 2c 20 74 68 61 74 20  er things, that 
6d50: 69 74 20 6d 61 74 63 68 65 73 20 74 68 65 20 63  it matches the c
6d60: 68 65 63 6b 73 75 6d 20 67 65 6e 65 72 61 74 65  hecksum generate
6d70: 64 20 62 79 0a 20 20 2a 2a 20 69 6e 73 70 65 63  d by.  ** inspec
6d80: 74 69 6e 67 20 74 68 65 20 69 6e 64 65 78 20 69  ting the index i
6d90: 74 73 65 6c 66 2e 20 20 2a 2f 0a 20 20 69 66 28  tself.  */.  if(
6da0: 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc==SQLITE_OK )
6db0: 7b 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74  {.    rc = sqlit
6dc0: 65 33 46 74 73 35 49 6e 64 65 78 49 6e 74 65 67  e3Fts5IndexInteg
6dd0: 72 69 74 79 43 68 65 63 6b 28 70 2d 3e 70 49 6e  rityCheck(p->pIn
6de0: 64 65 78 2c 20 63 74 78 2e 63 6b 73 75 6d 29 3b  dex, ctx.cksum);
6df0: 0a 20 20 7d 0a 0a 20 20 73 71 6c 69 74 65 33 5f  .  }..  sqlite3_
6e00: 66 72 65 65 28 61 54 6f 74 61 6c 53 69 7a 65 29  free(aTotalSize)
6e10: 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d  ;.  return rc;.}
6e20: 0a 0a 2f 2a 0a 2a 2a 20 4f 62 74 61 69 6e 20 61  ../*.** Obtain a
6e30: 6e 20 53 51 4c 69 74 65 20 73 74 61 74 65 6d 65  n SQLite stateme
6e40: 6e 74 20 68 61 6e 64 6c 65 20 74 68 61 74 20 6d  nt handle that m
6e50: 61 79 20 62 65 20 75 73 65 64 20 74 6f 20 72 65  ay be used to re
6e60: 61 64 20 64 61 74 61 20 66 72 6f 6d 20 74 68 65  ad data from the
6e70: 0a 2a 2a 20 25 5f 63 6f 6e 74 65 6e 74 20 74 61  .** %_content ta
6e80: 62 6c 65 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69  ble..*/.int sqli
6e90: 74 65 33 46 74 73 35 53 74 6f 72 61 67 65 53 74  te3Fts5StorageSt
6ea0: 6d 74 28 0a 20 20 46 74 73 35 53 74 6f 72 61 67  mt(.  Fts5Storag
6eb0: 65 20 2a 70 2c 20 0a 20 20 69 6e 74 20 65 53 74  e *p, .  int eSt
6ec0: 6d 74 2c 20 0a 20 20 73 71 6c 69 74 65 33 5f 73  mt, .  sqlite3_s
6ed0: 74 6d 74 20 2a 2a 70 70 2c 20 0a 20 20 63 68 61  tmt **pp, .  cha
6ee0: 72 20 2a 2a 70 7a 45 72 72 4d 73 67 0a 29 7b 0a  r **pzErrMsg.){.
6ef0: 20 20 69 6e 74 20 72 63 3b 0a 20 20 61 73 73 65    int rc;.  asse
6f00: 72 74 28 20 65 53 74 6d 74 3d 3d 46 54 53 35 5f  rt( eStmt==FTS5_
6f10: 53 54 4d 54 5f 53 43 41 4e 5f 41 53 43 20 0a 20  STMT_SCAN_ASC . 
6f20: 20 20 20 20 20 20 7c 7c 20 65 53 74 6d 74 3d 3d        || eStmt==
6f30: 46 54 53 35 5f 53 54 4d 54 5f 53 43 41 4e 5f 44  FTS5_STMT_SCAN_D
6f40: 45 53 43 0a 20 20 20 20 20 20 20 7c 7c 20 65 53  ESC.       || eS
6f50: 74 6d 74 3d 3d 46 54 53 35 5f 53 54 4d 54 5f 4c  tmt==FTS5_STMT_L
6f60: 4f 4f 4b 55 50 0a 20 20 29 3b 0a 20 20 72 63 20  OOKUP.  );.  rc 
6f70: 3d 20 66 74 73 35 53 74 6f 72 61 67 65 47 65 74  = fts5StorageGet
6f80: 53 74 6d 74 28 70 2c 20 65 53 74 6d 74 2c 20 70  Stmt(p, eStmt, p
6f90: 70 2c 20 70 7a 45 72 72 4d 73 67 29 3b 0a 20 20  p, pzErrMsg);.  
6fa0: 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  if( rc==SQLITE_O
6fb0: 4b 20 29 7b 0a 20 20 20 20 61 73 73 65 72 74 28  K ){.    assert(
6fc0: 20 70 2d 3e 61 53 74 6d 74 5b 65 53 74 6d 74 5d   p->aStmt[eStmt]
6fd0: 3d 3d 2a 70 70 20 29 3b 0a 20 20 20 20 70 2d 3e  ==*pp );.    p->
6fe0: 61 53 74 6d 74 5b 65 53 74 6d 74 5d 20 3d 20 30  aStmt[eStmt] = 0
6ff0: 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 72  ;.  }.  return r
7000: 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 6c 65  c;.}../*.** Rele
7010: 61 73 65 20 61 6e 20 53 51 4c 69 74 65 20 73 74  ase an SQLite st
7020: 61 74 65 6d 65 6e 74 20 68 61 6e 64 6c 65 20 6f  atement handle o
7030: 62 74 61 69 6e 65 64 20 76 69 61 20 61 6e 20 65  btained via an e
7040: 61 72 6c 69 65 72 20 63 61 6c 6c 20 74 6f 0a 2a  arlier call to.*
7050: 2a 20 73 71 6c 69 74 65 33 46 74 73 35 53 74 6f  * sqlite3Fts5Sto
7060: 72 61 67 65 53 74 6d 74 28 29 2e 20 54 68 65 20  rageStmt(). The 
7070: 65 53 74 6d 74 20 70 61 72 61 6d 65 74 65 72 20  eStmt parameter 
7080: 70 61 73 73 65 64 20 74 6f 20 74 68 69 73 20 66  passed to this f
7090: 75 6e 63 74 69 6f 6e 0a 2a 2a 20 6d 75 73 74 20  unction.** must 
70a0: 6d 61 74 63 68 20 74 68 61 74 20 70 61 73 73 65  match that passe
70b0: 64 20 74 6f 20 74 68 65 20 73 71 6c 69 74 65 33  d to the sqlite3
70c0: 46 74 73 35 53 74 6f 72 61 67 65 53 74 6d 74 28  Fts5StorageStmt(
70d0: 29 20 63 61 6c 6c 2e 0a 2a 2f 0a 76 6f 69 64 20  ) call..*/.void 
70e0: 73 71 6c 69 74 65 33 46 74 73 35 53 74 6f 72 61  sqlite3Fts5Stora
70f0: 67 65 53 74 6d 74 52 65 6c 65 61 73 65 28 0a 20  geStmtRelease(. 
7100: 20 46 74 73 35 53 74 6f 72 61 67 65 20 2a 70 2c   Fts5Storage *p,
7110: 20 0a 20 20 69 6e 74 20 65 53 74 6d 74 2c 20 0a   .  int eStmt, .
7120: 20 20 73 71 6c 69 74 65 33 5f 73 74 6d 74 20 2a    sqlite3_stmt *
7130: 70 53 74 6d 74 0a 29 7b 0a 20 20 61 73 73 65 72  pStmt.){.  asser
7140: 74 28 20 65 53 74 6d 74 3d 3d 46 54 53 35 5f 53  t( eStmt==FTS5_S
7150: 54 4d 54 5f 53 43 41 4e 5f 41 53 43 0a 20 20 20  TMT_SCAN_ASC.   
7160: 20 20 20 20 7c 7c 20 65 53 74 6d 74 3d 3d 46 54      || eStmt==FT
7170: 53 35 5f 53 54 4d 54 5f 53 43 41 4e 5f 44 45 53  S5_STMT_SCAN_DES
7180: 43 0a 20 20 20 20 20 20 20 7c 7c 20 65 53 74 6d  C.       || eStm
7190: 74 3d 3d 46 54 53 35 5f 53 54 4d 54 5f 4c 4f 4f  t==FTS5_STMT_LOO
71a0: 4b 55 50 0a 20 20 29 3b 0a 20 20 69 66 28 20 70  KUP.  );.  if( p
71b0: 2d 3e 61 53 74 6d 74 5b 65 53 74 6d 74 5d 3d 3d  ->aStmt[eStmt]==
71c0: 30 20 29 7b 0a 20 20 20 20 73 71 6c 69 74 65 33  0 ){.    sqlite3
71d0: 5f 72 65 73 65 74 28 70 53 74 6d 74 29 3b 0a 20  _reset(pStmt);. 
71e0: 20 20 20 70 2d 3e 61 53 74 6d 74 5b 65 53 74 6d     p->aStmt[eStm
71f0: 74 5d 20 3d 20 70 53 74 6d 74 3b 0a 20 20 7d 65  t] = pStmt;.  }e
7200: 6c 73 65 7b 0a 20 20 20 20 73 71 6c 69 74 65 33  lse{.    sqlite3
7210: 5f 66 69 6e 61 6c 69 7a 65 28 70 53 74 6d 74 29  _finalize(pStmt)
7220: 3b 0a 20 20 7d 0a 7d 0a 0a 73 74 61 74 69 63 20  ;.  }.}..static 
7230: 69 6e 74 20 66 74 73 35 53 74 6f 72 61 67 65 44  int fts5StorageD
7240: 65 63 6f 64 65 53 69 7a 65 41 72 72 61 79 28 0a  ecodeSizeArray(.
7250: 20 20 69 6e 74 20 2a 61 43 6f 6c 2c 20 69 6e 74    int *aCol, int
7260: 20 6e 43 6f 6c 2c 20 20 20 20 20 20 20 20 20 20   nCol,          
7270: 20 20 2f 2a 20 41 72 72 61 79 20 74 6f 20 70 6f    /* Array to po
7280: 70 75 6c 61 74 65 20 2a 2f 0a 20 20 63 6f 6e 73  pulate */.  cons
7290: 74 20 75 38 20 2a 61 42 6c 6f 62 2c 20 69 6e 74  t u8 *aBlob, int
72a0: 20 6e 42 6c 6f 62 20 20 20 20 20 20 2f 2a 20 52   nBlob      /* R
72b0: 65 63 6f 72 64 20 74 6f 20 72 65 61 64 20 76 61  ecord to read va
72c0: 72 69 6e 74 73 20 66 72 6f 6d 20 2a 2f 0a 29 7b  rints from */.){
72d0: 0a 20 20 69 6e 74 20 69 3b 0a 20 20 69 6e 74 20  .  int i;.  int 
72e0: 69 4f 66 66 20 3d 20 30 3b 0a 20 20 66 6f 72 28  iOff = 0;.  for(
72f0: 69 3d 30 3b 20 69 3c 6e 43 6f 6c 3b 20 69 2b 2b  i=0; i<nCol; i++
7300: 29 7b 0a 20 20 20 20 69 66 28 20 69 4f 66 66 3e  ){.    if( iOff>
7310: 3d 6e 42 6c 6f 62 20 29 20 72 65 74 75 72 6e 20  =nBlob ) return 
7320: 31 3b 0a 20 20 20 20 69 4f 66 66 20 2b 3d 20 66  1;.    iOff += f
7330: 74 73 35 47 65 74 56 61 72 69 6e 74 33 32 28 26  ts5GetVarint32(&
7340: 61 42 6c 6f 62 5b 69 4f 66 66 5d 2c 20 61 43 6f  aBlob[iOff], aCo
7350: 6c 5b 69 5d 29 3b 0a 20 20 7d 0a 20 20 72 65 74  l[i]);.  }.  ret
7360: 75 72 6e 20 28 69 4f 66 66 21 3d 6e 42 6c 6f 62  urn (iOff!=nBlob
7370: 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41 72 67 75  );.}../*.** Argu
7380: 6d 65 6e 74 20 61 43 6f 6c 20 70 6f 69 6e 74 73  ment aCol points
7390: 20 74 6f 20 61 6e 20 61 72 72 61 79 20 6f 66 20   to an array of 
73a0: 69 6e 74 65 67 65 72 73 20 63 6f 6e 74 61 69 6e  integers contain
73b0: 69 6e 67 20 6f 6e 65 20 65 6e 74 72 79 20 66 6f  ing one entry fo
73c0: 72 0a 2a 2a 20 65 61 63 68 20 74 61 62 6c 65 20  r.** each table 
73d0: 63 6f 6c 75 6d 6e 2e 20 54 68 69 73 20 66 75 6e  column. This fun
73e0: 63 74 69 6f 6e 20 72 65 61 64 73 20 74 68 65 20  ction reads the 
73f0: 25 5f 64 6f 63 73 69 7a 65 20 72 65 63 6f 72 64  %_docsize record
7400: 20 66 6f 72 20 74 68 65 0a 2a 2a 20 73 70 65 63   for the.** spec
7410: 69 66 69 65 64 20 72 6f 77 69 64 20 61 6e 64 20  ified rowid and 
7420: 70 6f 70 75 6c 61 74 65 73 20 61 43 6f 6c 5b 5d  populates aCol[]
7430: 20 77 69 74 68 20 74 68 65 20 72 65 73 75 6c 74   with the result
7440: 73 2e 0a 2a 2a 0a 2a 2a 20 41 6e 20 53 51 4c 69  s..**.** An SQLi
7450: 74 65 20 65 72 72 6f 72 20 63 6f 64 65 20 69 73  te error code is
7460: 20 72 65 74 75 72 6e 65 64 20 69 66 20 61 6e 20   returned if an 
7470: 65 72 72 6f 72 20 6f 63 63 75 72 73 2c 20 6f 72  error occurs, or
7480: 20 53 51 4c 49 54 45 5f 4f 4b 0a 2a 2a 20 6f 74   SQLITE_OK.** ot
7490: 68 65 72 77 69 73 65 2e 0a 2a 2f 0a 69 6e 74 20  herwise..*/.int 
74a0: 73 71 6c 69 74 65 33 46 74 73 35 53 74 6f 72 61  sqlite3Fts5Stora
74b0: 67 65 44 6f 63 73 69 7a 65 28 46 74 73 35 53 74  geDocsize(Fts5St
74c0: 6f 72 61 67 65 20 2a 70 2c 20 69 36 34 20 69 52  orage *p, i64 iR
74d0: 6f 77 69 64 2c 20 69 6e 74 20 2a 61 43 6f 6c 29  owid, int *aCol)
74e0: 7b 0a 20 20 69 6e 74 20 6e 43 6f 6c 20 3d 20 70  {.  int nCol = p
74f0: 2d 3e 70 43 6f 6e 66 69 67 2d 3e 6e 43 6f 6c 3b  ->pConfig->nCol;
7500: 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66      /* Number of
7510: 20 75 73 65 72 20 63 6f 6c 75 6d 6e 73 20 69 6e   user columns in
7520: 20 74 61 62 6c 65 20 2a 2f 0a 20 20 73 71 6c 69   table */.  sqli
7530: 74 65 33 5f 73 74 6d 74 20 2a 70 4c 6f 6f 6b 75  te3_stmt *pLooku
7540: 70 20 3d 20 30 3b 20 20 20 20 20 20 2f 2a 20 53  p = 0;      /* S
7550: 74 61 74 65 6d 65 6e 74 20 74 6f 20 71 75 65 72  tatement to quer
7560: 79 20 25 5f 64 6f 63 73 69 7a 65 20 2a 2f 0a 20  y %_docsize */. 
7570: 20 69 6e 74 20 72 63 3b 20 20 20 20 20 20 20 20   int rc;        
7580: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7590: 20 2f 2a 20 52 65 74 75 72 6e 20 43 6f 64 65 20   /* Return Code 
75a0: 2a 2f 0a 0a 20 20 61 73 73 65 72 74 28 20 70 2d  */..  assert( p-
75b0: 3e 70 43 6f 6e 66 69 67 2d 3e 62 43 6f 6c 75 6d  >pConfig->bColum
75c0: 6e 73 69 7a 65 20 29 3b 0a 20 20 72 63 20 3d 20  nsize );.  rc = 
75d0: 66 74 73 35 53 74 6f 72 61 67 65 47 65 74 53 74  fts5StorageGetSt
75e0: 6d 74 28 70 2c 20 46 54 53 35 5f 53 54 4d 54 5f  mt(p, FTS5_STMT_
75f0: 4c 4f 4f 4b 55 50 5f 44 4f 43 53 49 5a 45 2c 20  LOOKUP_DOCSIZE, 
7600: 26 70 4c 6f 6f 6b 75 70 2c 20 30 29 3b 0a 20 20  &pLookup, 0);.  
7610: 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  if( rc==SQLITE_O
7620: 4b 20 29 7b 0a 20 20 20 20 69 6e 74 20 62 43 6f  K ){.    int bCo
7630: 72 72 75 70 74 20 3d 20 31 3b 0a 20 20 20 20 73  rrupt = 1;.    s
7640: 71 6c 69 74 65 33 5f 62 69 6e 64 5f 69 6e 74 36  qlite3_bind_int6
7650: 34 28 70 4c 6f 6f 6b 75 70 2c 20 31 2c 20 69 52  4(pLookup, 1, iR
7660: 6f 77 69 64 29 3b 0a 20 20 20 20 69 66 28 20 53  owid);.    if( S
7670: 51 4c 49 54 45 5f 52 4f 57 3d 3d 73 71 6c 69 74  QLITE_ROW==sqlit
7680: 65 33 5f 73 74 65 70 28 70 4c 6f 6f 6b 75 70 29  e3_step(pLookup)
7690: 20 29 7b 0a 20 20 20 20 20 20 63 6f 6e 73 74 20   ){.      const 
76a0: 75 38 20 2a 61 42 6c 6f 62 20 3d 20 73 71 6c 69  u8 *aBlob = sqli
76b0: 74 65 33 5f 63 6f 6c 75 6d 6e 5f 62 6c 6f 62 28  te3_column_blob(
76c0: 70 4c 6f 6f 6b 75 70 2c 20 30 29 3b 0a 20 20 20  pLookup, 0);.   
76d0: 20 20 20 69 6e 74 20 6e 42 6c 6f 62 20 3d 20 73     int nBlob = s
76e0: 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 62 79  qlite3_column_by
76f0: 74 65 73 28 70 4c 6f 6f 6b 75 70 2c 20 30 29 3b  tes(pLookup, 0);
7700: 0a 20 20 20 20 20 20 69 66 28 20 30 3d 3d 66 74  .      if( 0==ft
7710: 73 35 53 74 6f 72 61 67 65 44 65 63 6f 64 65 53  s5StorageDecodeS
7720: 69 7a 65 41 72 72 61 79 28 61 43 6f 6c 2c 20 6e  izeArray(aCol, n
7730: 43 6f 6c 2c 20 61 42 6c 6f 62 2c 20 6e 42 6c 6f  Col, aBlob, nBlo
7740: 62 29 20 29 7b 0a 20 20 20 20 20 20 20 20 62 43  b) ){.        bC
7750: 6f 72 72 75 70 74 20 3d 20 30 3b 0a 20 20 20 20  orrupt = 0;.    
7760: 20 20 7d 0a 20 20 20 20 7d 0a 20 20 20 20 72 63    }.    }.    rc
7770: 20 3d 20 73 71 6c 69 74 65 33 5f 72 65 73 65 74   = sqlite3_reset
7780: 28 70 4c 6f 6f 6b 75 70 29 3b 0a 20 20 20 20 69  (pLookup);.    i
7790: 66 28 20 62 43 6f 72 72 75 70 74 20 26 26 20 72  f( bCorrupt && r
77a0: 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a  c==SQLITE_OK ){.
77b0: 20 20 20 20 20 20 72 63 20 3d 20 46 54 53 35 5f        rc = FTS5_
77c0: 43 4f 52 52 55 50 54 3b 0a 20 20 20 20 7d 0a 20  CORRUPT;.    }. 
77d0: 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b   }..  return rc;
77e0: 0a 7d 0a 0a 69 6e 74 20 73 71 6c 69 74 65 33 46  .}..int sqlite3F
77f0: 74 73 35 53 74 6f 72 61 67 65 53 69 7a 65 28 46  ts5StorageSize(F
7800: 74 73 35 53 74 6f 72 61 67 65 20 2a 70 2c 20 69  ts5Storage *p, i
7810: 6e 74 20 69 43 6f 6c 2c 20 69 36 34 20 2a 70 6e  nt iCol, i64 *pn
7820: 54 6f 6b 65 6e 29 7b 0a 20 20 69 6e 74 20 72 63  Token){.  int rc
7830: 20 3d 20 66 74 73 35 53 74 6f 72 61 67 65 4c 6f   = fts5StorageLo
7840: 61 64 54 6f 74 61 6c 73 28 70 2c 20 30 29 3b 0a  adTotals(p, 0);.
7850: 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
7860: 5f 4f 4b 20 29 7b 0a 20 20 20 20 2a 70 6e 54 6f  _OK ){.    *pnTo
7870: 6b 65 6e 20 3d 20 30 3b 0a 20 20 20 20 69 66 28  ken = 0;.    if(
7880: 20 69 43 6f 6c 3c 30 20 29 7b 0a 20 20 20 20 20   iCol<0 ){.     
7890: 20 69 6e 74 20 69 3b 0a 20 20 20 20 20 20 66 6f   int i;.      fo
78a0: 72 28 69 3d 30 3b 20 69 3c 70 2d 3e 70 43 6f 6e  r(i=0; i<p->pCon
78b0: 66 69 67 2d 3e 6e 43 6f 6c 3b 20 69 2b 2b 29 7b  fig->nCol; i++){
78c0: 0a 20 20 20 20 20 20 20 20 2a 70 6e 54 6f 6b 65  .        *pnToke
78d0: 6e 20 2b 3d 20 70 2d 3e 61 54 6f 74 61 6c 53 69  n += p->aTotalSi
78e0: 7a 65 5b 69 5d 3b 0a 20 20 20 20 20 20 7d 0a 20  ze[i];.      }. 
78f0: 20 20 20 7d 65 6c 73 65 20 69 66 28 20 69 43 6f     }else if( iCo
7900: 6c 3c 70 2d 3e 70 43 6f 6e 66 69 67 2d 3e 6e 43  l<p->pConfig->nC
7910: 6f 6c 20 29 7b 0a 20 20 20 20 20 20 2a 70 6e 54  ol ){.      *pnT
7920: 6f 6b 65 6e 20 3d 20 70 2d 3e 61 54 6f 74 61 6c  oken = p->aTotal
7930: 53 69 7a 65 5b 69 43 6f 6c 5d 3b 0a 20 20 20 20  Size[iCol];.    
7940: 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 72 63 20  }else{.      rc 
7950: 3d 20 53 51 4c 49 54 45 5f 52 41 4e 47 45 3b 0a  = SQLITE_RANGE;.
7960: 20 20 20 20 7d 0a 20 20 7d 0a 20 20 72 65 74 75      }.  }.  retu
7970: 72 6e 20 72 63 3b 0a 7d 0a 0a 69 6e 74 20 73 71  rn rc;.}..int sq
7980: 6c 69 74 65 33 46 74 73 35 53 74 6f 72 61 67 65  lite3Fts5Storage
7990: 52 6f 77 43 6f 75 6e 74 28 46 74 73 35 53 74 6f  RowCount(Fts5Sto
79a0: 72 61 67 65 20 2a 70 2c 20 69 36 34 20 2a 70 6e  rage *p, i64 *pn
79b0: 52 6f 77 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d  Row){.  int rc =
79c0: 20 66 74 73 35 53 74 6f 72 61 67 65 4c 6f 61 64   fts5StorageLoad
79d0: 54 6f 74 61 6c 73 28 70 2c 20 30 29 3b 0a 20 20  Totals(p, 0);.  
79e0: 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  if( rc==SQLITE_O
79f0: 4b 20 29 7b 0a 20 20 20 20 2f 2a 20 6e 54 6f 74  K ){.    /* nTot
7a00: 61 6c 52 6f 77 20 62 65 69 6e 67 20 7a 65 72 6f  alRow being zero
7a10: 20 64 6f 65 73 20 6e 6f 74 20 6e 65 63 65 73 73   does not necess
7a20: 61 72 69 6c 79 20 69 6e 64 69 63 61 74 65 20 61  arily indicate a
7a30: 20 63 6f 72 72 75 70 74 20 0a 20 20 20 20 2a 2a   corrupt .    **
7a40: 20 64 61 74 61 62 61 73 65 20 2d 20 69 74 20 6d   database - it m
7a50: 69 67 68 74 20 62 65 20 74 68 61 74 20 74 68 65  ight be that the
7a60: 20 46 54 53 35 20 74 61 62 6c 65 20 72 65 61 6c   FTS5 table real
7a70: 6c 79 20 64 6f 65 73 20 63 6f 6e 74 61 69 6e 20  ly does contain 
7a80: 7a 65 72 6f 0a 20 20 20 20 2a 2a 20 72 6f 77 73  zero.    ** rows
7a90: 2e 20 48 6f 77 65 76 65 72 20 74 68 69 73 20 66  . However this f
7aa0: 75 6e 63 74 69 6f 6e 20 69 73 20 6f 6e 6c 79 20  unction is only 
7ab0: 63 61 6c 6c 65 64 20 66 72 6f 6d 20 74 68 65 20  called from the 
7ac0: 78 52 6f 77 43 6f 75 6e 74 28 29 20 41 50 49 2c  xRowCount() API,
7ad0: 0a 20 20 20 20 2a 2a 20 61 6e 64 20 74 68 65 72  .    ** and ther
7ae0: 65 20 69 73 20 6e 6f 20 77 61 79 20 66 6f 72 20  e is no way for 
7af0: 74 68 61 74 20 41 50 49 20 74 6f 20 62 65 20 69  that API to be i
7b00: 6e 76 6f 6b 65 64 20 69 66 20 74 68 65 20 74 61  nvoked if the ta
7b10: 62 6c 65 20 63 6f 6e 74 61 69 6e 73 0a 20 20 20  ble contains.   
7b20: 20 2a 2a 20 6e 6f 20 72 6f 77 73 2e 20 48 65 6e   ** no rows. Hen
7b30: 63 65 20 74 68 65 20 46 54 53 35 5f 43 4f 52 52  ce the FTS5_CORR
7b40: 55 50 54 20 72 65 74 75 72 6e 2e 20 20 2a 2f 0a  UPT return.  */.
7b50: 20 20 20 20 2a 70 6e 52 6f 77 20 3d 20 70 2d 3e      *pnRow = p->
7b60: 6e 54 6f 74 61 6c 52 6f 77 3b 0a 20 20 20 20 69  nTotalRow;.    i
7b70: 66 28 20 70 2d 3e 6e 54 6f 74 61 6c 52 6f 77 3c  f( p->nTotalRow<
7b80: 3d 30 20 29 20 72 63 20 3d 20 46 54 53 35 5f 43  =0 ) rc = FTS5_C
7b90: 4f 52 52 55 50 54 3b 0a 20 20 7d 0a 20 20 72 65  ORRUPT;.  }.  re
7ba0: 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a  turn rc;.}../*.*
7bb0: 2a 20 46 6c 75 73 68 20 61 6e 79 20 64 61 74 61  * Flush any data
7bc0: 20 63 75 72 72 65 6e 74 6c 79 20 68 65 6c 64 20   currently held 
7bd0: 69 6e 2d 6d 65 6d 6f 72 79 20 74 6f 20 64 69 73  in-memory to dis
7be0: 6b 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65  k..*/.int sqlite
7bf0: 33 46 74 73 35 53 74 6f 72 61 67 65 53 79 6e 63  3Fts5StorageSync
7c00: 28 46 74 73 35 53 74 6f 72 61 67 65 20 2a 70 29  (Fts5Storage *p)
7c10: 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c  {.  int rc = SQL
7c20: 49 54 45 5f 4f 4b 3b 0a 20 20 69 36 34 20 69 4c  ITE_OK;.  i64 iL
7c30: 61 73 74 52 6f 77 69 64 20 3d 20 73 71 6c 69 74  astRowid = sqlit
7c40: 65 33 5f 6c 61 73 74 5f 69 6e 73 65 72 74 5f 72  e3_last_insert_r
7c50: 6f 77 69 64 28 70 2d 3e 70 43 6f 6e 66 69 67 2d  owid(p->pConfig-
7c60: 3e 64 62 29 3b 0a 20 20 69 66 28 20 70 2d 3e 62  >db);.  if( p->b
7c70: 54 6f 74 61 6c 73 56 61 6c 69 64 20 29 7b 0a 20  TotalsValid ){. 
7c80: 20 20 20 72 63 20 3d 20 66 74 73 35 53 74 6f 72     rc = fts5Stor
7c90: 61 67 65 53 61 76 65 54 6f 74 61 6c 73 28 70 29  ageSaveTotals(p)
7ca0: 3b 0a 20 20 20 20 70 2d 3e 62 54 6f 74 61 6c 73  ;.    p->bTotals
7cb0: 56 61 6c 69 64 20 3d 20 30 3b 0a 20 20 7d 0a 20  Valid = 0;.  }. 
7cc0: 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
7cd0: 4f 4b 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 73  OK ){.    rc = s
7ce0: 71 6c 69 74 65 33 46 74 73 35 49 6e 64 65 78 53  qlite3Fts5IndexS
7cf0: 79 6e 63 28 70 2d 3e 70 49 6e 64 65 78 29 3b 0a  ync(p->pIndex);.
7d00: 20 20 7d 0a 20 20 73 71 6c 69 74 65 33 5f 73 65    }.  sqlite3_se
7d10: 74 5f 6c 61 73 74 5f 69 6e 73 65 72 74 5f 72 6f  t_last_insert_ro
7d20: 77 69 64 28 70 2d 3e 70 43 6f 6e 66 69 67 2d 3e  wid(p->pConfig->
7d30: 64 62 2c 20 69 4c 61 73 74 52 6f 77 69 64 29 3b  db, iLastRowid);
7d40: 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a  .  return rc;.}.
7d50: 0a 69 6e 74 20 73 71 6c 69 74 65 33 46 74 73 35  .int sqlite3Fts5
7d60: 53 74 6f 72 61 67 65 52 6f 6c 6c 62 61 63 6b 28  StorageRollback(
7d70: 46 74 73 35 53 74 6f 72 61 67 65 20 2a 70 29 7b  Fts5Storage *p){
7d80: 0a 20 20 70 2d 3e 62 54 6f 74 61 6c 73 56 61 6c  .  p->bTotalsVal
7d90: 69 64 20 3d 20 30 3b 0a 20 20 72 65 74 75 72 6e  id = 0;.  return
7da0: 20 73 71 6c 69 74 65 33 46 74 73 35 49 6e 64 65   sqlite3Fts5Inde
7db0: 78 52 6f 6c 6c 62 61 63 6b 28 70 2d 3e 70 49 6e  xRollback(p->pIn
7dc0: 64 65 78 29 3b 0a 7d 0a 0a 69 6e 74 20 73 71 6c  dex);.}..int sql
7dd0: 69 74 65 33 46 74 73 35 53 74 6f 72 61 67 65 43  ite3Fts5StorageC
7de0: 6f 6e 66 69 67 56 61 6c 75 65 28 0a 20 20 46 74  onfigValue(.  Ft
7df0: 73 35 53 74 6f 72 61 67 65 20 2a 70 2c 20 0a 20  s5Storage *p, . 
7e00: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 2c 0a   const char *z,.
7e10: 20 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 20    sqlite3_value 
7e20: 2a 70 56 61 6c 2c 0a 20 20 69 6e 74 20 69 56 61  *pVal,.  int iVa
7e30: 6c 0a 29 7b 0a 20 20 73 71 6c 69 74 65 33 5f 73  l.){.  sqlite3_s
7e40: 74 6d 74 20 2a 70 52 65 70 6c 61 63 65 20 3d 20  tmt *pReplace = 
7e50: 30 3b 0a 20 20 69 6e 74 20 72 63 20 3d 20 66 74  0;.  int rc = ft
7e60: 73 35 53 74 6f 72 61 67 65 47 65 74 53 74 6d 74  s5StorageGetStmt
7e70: 28 70 2c 20 46 54 53 35 5f 53 54 4d 54 5f 52 45  (p, FTS5_STMT_RE
7e80: 50 4c 41 43 45 5f 43 4f 4e 46 49 47 2c 20 26 70  PLACE_CONFIG, &p
7e90: 52 65 70 6c 61 63 65 2c 20 30 29 3b 0a 20 20 69  Replace, 0);.  i
7ea0: 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc==SQLITE_OK
7eb0: 20 29 7b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f   ){.    sqlite3_
7ec0: 62 69 6e 64 5f 74 65 78 74 28 70 52 65 70 6c 61  bind_text(pRepla
7ed0: 63 65 2c 20 31 2c 20 7a 2c 20 2d 31 2c 20 53 51  ce, 1, z, -1, SQ
7ee0: 4c 49 54 45 5f 53 54 41 54 49 43 29 3b 0a 20 20  LITE_STATIC);.  
7ef0: 20 20 69 66 28 20 70 56 61 6c 20 29 7b 0a 20 20    if( pVal ){.  
7f00: 20 20 20 20 73 71 6c 69 74 65 33 5f 62 69 6e 64      sqlite3_bind
7f10: 5f 76 61 6c 75 65 28 70 52 65 70 6c 61 63 65 2c  _value(pReplace,
7f20: 20 32 2c 20 70 56 61 6c 29 3b 0a 20 20 20 20 7d   2, pVal);.    }
7f30: 65 6c 73 65 7b 0a 20 20 20 20 20 20 73 71 6c 69  else{.      sqli
7f40: 74 65 33 5f 62 69 6e 64 5f 69 6e 74 28 70 52 65  te3_bind_int(pRe
7f50: 70 6c 61 63 65 2c 20 32 2c 20 69 56 61 6c 29 3b  place, 2, iVal);
7f60: 0a 20 20 20 20 7d 0a 20 20 20 20 73 71 6c 69 74  .    }.    sqlit
7f70: 65 33 5f 73 74 65 70 28 70 52 65 70 6c 61 63 65  e3_step(pReplace
7f80: 29 3b 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69  );.    rc = sqli
7f90: 74 65 33 5f 72 65 73 65 74 28 70 52 65 70 6c 61  te3_reset(pRepla
7fa0: 63 65 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33  ce);.    sqlite3
7fb0: 5f 62 69 6e 64 5f 6e 75 6c 6c 28 70 52 65 70 6c  _bind_null(pRepl
7fc0: 61 63 65 2c 20 31 29 3b 0a 20 20 7d 0a 20 20 69  ace, 1);.  }.  i
7fd0: 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc==SQLITE_OK
7fe0: 20 26 26 20 70 56 61 6c 20 29 7b 0a 20 20 20 20   && pVal ){.    
7ff0: 69 6e 74 20 69 4e 65 77 20 3d 20 70 2d 3e 70 43  int iNew = p->pC
8000: 6f 6e 66 69 67 2d 3e 69 43 6f 6f 6b 69 65 20 2b  onfig->iCookie +
8010: 20 31 3b 0a 20 20 20 20 72 63 20 3d 20 73 71 6c   1;.    rc = sql
8020: 69 74 65 33 46 74 73 35 49 6e 64 65 78 53 65 74  ite3Fts5IndexSet
8030: 43 6f 6f 6b 69 65 28 70 2d 3e 70 49 6e 64 65 78  Cookie(p->pIndex
8040: 2c 20 69 4e 65 77 29 3b 0a 20 20 20 20 69 66 28  , iNew);.    if(
8050: 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc==SQLITE_OK )
8060: 7b 0a 20 20 20 20 20 20 70 2d 3e 70 43 6f 6e 66  {.      p->pConf
8070: 69 67 2d 3e 69 43 6f 6f 6b 69 65 20 3d 20 69 4e  ig->iCookie = iN
8080: 65 77 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20  ew;.    }.  }.  
8090: 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a           return rc;.}.