/ Hex Artifact Content
Login

Artifact 75d9ef60e12ea8a281ab6cd9643992a5a99b2c6a:


0000: 2f 2a 0a 2a 2a 20 32 30 30 36 20 4a 75 6e 65 20  /*.** 2006 June 
0010: 31 30 0a 2a 2a 0a 2a 2a 20 54 68 65 20 61 75 74  10.**.** The aut
0020: 68 6f 72 20 64 69 73 63 6c 61 69 6d 73 20 63 6f  hor disclaims co
0030: 70 79 72 69 67 68 74 20 74 6f 20 74 68 69 73 20  pyright to this 
0040: 73 6f 75 72 63 65 20 63 6f 64 65 2e 20 20 49 6e  source code.  In
0050: 20 70 6c 61 63 65 20 6f 66 0a 2a 2a 20 61 20 6c   place of.** a l
0060: 65 67 61 6c 20 6e 6f 74 69 63 65 2c 20 68 65 72  egal notice, her
0070: 65 20 69 73 20 61 20 62 6c 65 73 73 69 6e 67 3a  e is a blessing:
0080: 0a 2a 2a 0a 2a 2a 20 20 20 20 4d 61 79 20 79 6f  .**.**    May yo
0090: 75 20 64 6f 20 67 6f 6f 64 20 61 6e 64 20 6e 6f  u do good and no
00a0: 74 20 65 76 69 6c 2e 0a 2a 2a 20 20 20 20 4d 61  t evil..**    Ma
00b0: 79 20 79 6f 75 20 66 69 6e 64 20 66 6f 72 67 69  y you find forgi
00c0: 76 65 6e 65 73 73 20 66 6f 72 20 79 6f 75 72 73  veness for yours
00d0: 65 6c 66 20 61 6e 64 20 66 6f 72 67 69 76 65 20  elf and forgive 
00e0: 6f 74 68 65 72 73 2e 0a 2a 2a 20 20 20 20 4d 61  others..**    Ma
00f0: 79 20 79 6f 75 20 73 68 61 72 65 20 66 72 65 65  y you share free
0100: 6c 79 2c 20 6e 65 76 65 72 20 74 61 6b 69 6e 67  ly, never taking
0110: 20 6d 6f 72 65 20 74 68 61 6e 20 79 6f 75 20 67   more than you g
0120: 69 76 65 2e 0a 2a 2a 0a 2a 2a 2a 2a 2a 2a 2a 2a  ive..**.********
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 0a 2a 2a 20 43 6f 64 65 20 66 6f 72 20 74 65  *.** Code for te
0180: 73 74 69 6e 67 20 74 68 65 20 76 69 72 74 75 61  sting the virtua
0190: 6c 20 74 61 62 6c 65 20 69 6e 74 65 72 66 61 63  l table interfac
01a0: 65 73 2e 20 20 54 68 69 73 20 63 6f 64 65 0a 2a  es.  This code.*
01b0: 2a 20 69 73 20 6e 6f 74 20 69 6e 63 6c 75 64 65  * is not include
01c0: 64 20 69 6e 20 74 68 65 20 53 51 4c 69 74 65 20  d in the SQLite 
01d0: 6c 69 62 72 61 72 79 2e 20 20 49 74 20 69 73 20  library.  It is 
01e0: 75 73 65 64 20 66 6f 72 20 61 75 74 6f 6d 61 74  used for automat
01f0: 65 64 0a 2a 2a 20 74 65 73 74 69 6e 67 20 6f 66  ed.** testing of
0200: 20 74 68 65 20 53 51 4c 69 74 65 20 6c 69 62 72   the SQLite libr
0210: 61 72 79 2e 0a 2a 2a 0a 2a 2a 20 24 49 64 3a 20  ary..**.** $Id: 
0220: 74 65 73 74 38 2e 63 2c 76 20 31 2e 32 34 20 32  test8.c,v 1.24 2
0230: 30 30 36 2f 30 36 2f 31 36 20 30 36 3a 31 37 3a  006/06/16 06:17:
0240: 34 37 20 64 61 6e 69 65 6c 6b 31 39 37 37 20 45  47 danielk1977 E
0250: 78 70 20 24 0a 2a 2f 0a 23 69 6e 63 6c 75 64 65  xp $.*/.#include
0260: 20 22 73 71 6c 69 74 65 49 6e 74 2e 68 22 0a 23   "sqliteInt.h".#
0270: 69 6e 63 6c 75 64 65 20 22 74 63 6c 2e 68 22 0a  include "tcl.h".
0280: 23 69 6e 63 6c 75 64 65 20 22 6f 73 2e 68 22 0a  #include "os.h".
0290: 23 69 6e 63 6c 75 64 65 20 3c 73 74 64 6c 69 62  #include <stdlib
02a0: 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 73 74  .h>.#include <st
02b0: 72 69 6e 67 2e 68 3e 0a 0a 74 79 70 65 64 65 66  ring.h>..typedef
02c0: 20 73 74 72 75 63 74 20 65 63 68 6f 5f 76 74 61   struct echo_vta
02d0: 62 20 65 63 68 6f 5f 76 74 61 62 3b 0a 74 79 70  b echo_vtab;.typ
02e0: 65 64 65 66 20 73 74 72 75 63 74 20 65 63 68 6f  edef struct echo
02f0: 5f 63 75 72 73 6f 72 20 65 63 68 6f 5f 63 75 72  _cursor echo_cur
0300: 73 6f 72 3b 0a 0a 2f 2a 20 0a 2a 2a 20 41 6e 20  sor;../* .** An 
0310: 65 63 68 6f 20 76 69 72 74 75 61 6c 2d 74 61 62  echo virtual-tab
0320: 6c 65 20 6f 62 6a 65 63 74 2e 0a 2a 2a 0a 2a 2a  le object..**.**
0330: 20 65 63 68 6f 2e 76 74 61 62 2e 61 49 6e 64 65   echo.vtab.aInde
0340: 78 20 69 73 20 61 6e 20 61 72 72 61 79 20 6f 66  x is an array of
0350: 20 62 6f 6f 6c 65 61 6e 73 2e 20 54 68 65 20 6e   booleans. The n
0360: 74 68 20 65 6e 74 72 79 20 69 73 20 74 72 75 65  th entry is true
0370: 20 69 66 20 0a 2a 2a 20 74 68 65 20 6e 74 68 20   if .** the nth 
0380: 63 6f 6c 75 6d 6e 20 6f 66 20 74 68 65 20 72 65  column of the re
0390: 61 6c 20 74 61 62 6c 65 20 69 73 20 74 68 65 20  al table is the 
03a0: 6c 65 66 74 2d 6d 6f 73 74 20 63 6f 6c 75 6d 6e  left-most column
03b0: 20 6f 66 20 61 6e 20 69 6e 64 65 78 0a 2a 2a 20   of an index.** 
03c0: 28 69 6d 70 6c 69 63 69 74 20 6f 72 20 6f 74 68  (implicit or oth
03d0: 65 72 77 69 73 65 29 2e 20 49 6e 20 6f 74 68 65  erwise). In othe
03e0: 72 20 77 6f 72 64 73 2c 20 69 66 20 53 51 4c 69  r words, if SQLi
03f0: 74 65 20 63 61 6e 20 6f 70 74 69 6d 69 7a 65 0a  te can optimize.
0400: 2a 2a 20 61 20 71 75 65 72 79 20 6c 69 6b 65 20  ** a query like 
0410: 22 53 45 4c 45 43 54 20 2a 20 46 52 4f 4d 20 72  "SELECT * FROM r
0420: 65 61 6c 5f 74 61 62 6c 65 20 57 48 45 52 45 20  eal_table WHERE 
0430: 63 6f 6c 20 3d 20 3f 22 2e 0a 2a 2a 0a 2a 2a 20  col = ?"..**.** 
0440: 4d 65 6d 62 65 72 20 76 61 72 69 61 62 6c 65 20  Member variable 
0450: 63 6f 6e 74 61 69 6e 73 20 63 6f 70 69 65 73 20  contains copies 
0460: 6f 66 20 74 68 65 20 63 6f 6c 75 6d 6e 20 6e 61  of the column na
0470: 6d 65 73 20 6f 66 20 74 68 65 20 72 65 61 6c 20  mes of the real 
0480: 74 61 62 6c 65 2e 0a 2a 2f 0a 73 74 72 75 63 74  table..*/.struct
0490: 20 65 63 68 6f 5f 76 74 61 62 20 7b 0a 20 20 73   echo_vtab {.  s
04a0: 71 6c 69 74 65 33 5f 76 74 61 62 20 62 61 73 65  qlite3_vtab base
04b0: 3b 0a 20 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a  ;.  Tcl_Interp *
04c0: 69 6e 74 65 72 70 3b 0a 20 20 73 71 6c 69 74 65  interp;.  sqlite
04d0: 33 20 2a 64 62 3b 0a 0a 20 20 63 68 61 72 20 2a  3 *db;..  char *
04e0: 7a 54 61 62 6c 65 4e 61 6d 65 3b 20 20 20 20 20  zTableName;     
04f0: 20 20 2f 2a 20 4e 61 6d 65 20 6f 66 20 74 68 65    /* Name of the
0500: 20 72 65 61 6c 20 74 61 62 6c 65 20 2a 2f 0a 20   real table */. 
0510: 20 69 6e 74 20 6e 43 6f 6c 3b 20 20 20 20 20 20   int nCol;      
0520: 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62           /* Numb
0530: 65 72 20 6f 66 20 63 6f 6c 75 6d 6e 73 20 69 6e  er of columns in
0540: 20 74 68 65 20 72 65 61 6c 20 74 61 62 6c 65 20   the real table 
0550: 2a 2f 0a 20 20 69 6e 74 20 2a 61 49 6e 64 65 78  */.  int *aIndex
0560: 3b 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20  ;            /* 
0570: 41 72 72 61 79 20 6f 66 20 73 69 7a 65 20 6e 43  Array of size nC
0580: 6f 6c 2e 20 54 72 75 65 20 69 66 20 63 6f 6c 75  ol. True if colu
0590: 6d 6e 20 68 61 73 20 61 6e 20 69 6e 64 65 78 20  mn has an index 
05a0: 2a 2f 0a 20 20 63 68 61 72 20 2a 2a 61 43 6f 6c  */.  char **aCol
05b0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20  ;            /* 
05c0: 41 72 72 61 79 20 6f 66 20 73 69 7a 65 20 6e 43  Array of size nC
05d0: 6f 6c 2e 20 43 6f 6c 75 6d 6e 20 6e 61 6d 65 73  ol. Column names
05e0: 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 20 41 6e 20 65 63   */.};../* An ec
05f0: 68 6f 20 63 75 72 73 6f 72 20 6f 62 6a 65 63 74  ho cursor object
0600: 20 2a 2f 0a 73 74 72 75 63 74 20 65 63 68 6f 5f   */.struct echo_
0610: 63 75 72 73 6f 72 20 7b 0a 20 20 73 71 6c 69 74  cursor {.  sqlit
0620: 65 33 5f 76 74 61 62 5f 63 75 72 73 6f 72 20 62  e3_vtab_cursor b
0630: 61 73 65 3b 0a 20 20 73 71 6c 69 74 65 33 5f 73  ase;.  sqlite3_s
0640: 74 6d 74 20 2a 70 53 74 6d 74 3b 0a 20 20 69 6e  tmt *pStmt;.  in
0650: 74 20 65 72 72 63 6f 64 65 3b 20 20 20 20 20 20  t errcode;      
0660: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 45 72             /* Er
0670: 72 6f 72 20 63 6f 64 65 20 2a 2f 0a 7d 3b 0a 0a  ror code */.};..
0680: 73 74 61 74 69 63 20 69 6e 74 20 67 65 74 43 6f  static int getCo
0690: 6c 75 6d 6e 4e 61 6d 65 73 28 0a 20 20 73 71 6c  lumnNames(.  sql
06a0: 69 74 65 33 20 2a 64 62 2c 20 0a 20 20 63 6f 6e  ite3 *db, .  con
06b0: 73 74 20 63 68 61 72 20 2a 7a 54 61 62 2c 0a 20  st char *zTab,. 
06c0: 20 63 68 61 72 20 2a 2a 2a 70 61 43 6f 6c 2c 20   char ***paCol, 
06d0: 0a 20 20 69 6e 74 20 2a 70 6e 43 6f 6c 0a 29 7b  .  int *pnCol.){
06e0: 0a 20 20 63 68 61 72 20 2a 2a 61 43 6f 6c 20 3d  .  char **aCol =
06f0: 20 30 3b 0a 20 20 63 68 61 72 20 7a 42 75 66 5b   0;.  char zBuf[
0700: 31 30 32 34 5d 3b 0a 20 20 73 71 6c 69 74 65 33  1024];.  sqlite3
0710: 5f 73 74 6d 74 20 2a 70 53 74 6d 74 20 3d 20 30  _stmt *pStmt = 0
0720: 3b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c  ;.  int rc = SQL
0730: 49 54 45 5f 4f 4b 3b 0a 20 20 69 6e 74 20 6e 43  ITE_OK;.  int nC
0740: 6f 6c 3b 0a 0a 20 20 73 70 72 69 6e 74 66 28 7a  ol;..  sprintf(z
0750: 42 75 66 2c 20 22 53 45 4c 45 43 54 20 2a 20 46  Buf, "SELECT * F
0760: 52 4f 4d 20 25 73 22 2c 20 7a 54 61 62 29 3b 0a  ROM %s", zTab);.
0770: 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 70    rc = sqlite3_p
0780: 72 65 70 61 72 65 28 64 62 2c 20 7a 42 75 66 2c  repare(db, zBuf,
0790: 20 2d 31 2c 20 26 70 53 74 6d 74 2c 20 30 29 3b   -1, &pStmt, 0);
07a0: 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54  .  if( rc==SQLIT
07b0: 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 69 6e 74 20  E_OK ){.    int 
07c0: 69 69 3b 0a 20 20 20 20 6e 43 6f 6c 20 3d 20 73  ii;.    nCol = s
07d0: 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 63 6f  qlite3_column_co
07e0: 75 6e 74 28 70 53 74 6d 74 29 3b 0a 20 20 20 20  unt(pStmt);.    
07f0: 61 43 6f 6c 20 3d 20 73 71 6c 69 74 65 4d 61 6c  aCol = sqliteMal
0800: 6c 6f 63 28 73 69 7a 65 6f 66 28 63 68 61 72 20  loc(sizeof(char 
0810: 2a 29 20 2a 20 6e 43 6f 6c 29 3b 0a 20 20 20 20  *) * nCol);.    
0820: 69 66 28 20 21 61 43 6f 6c 20 29 7b 0a 20 20 20  if( !aCol ){.   
0830: 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4e     rc = SQLITE_N
0840: 4f 4d 45 4d 3b 0a 20 20 20 20 20 20 67 6f 74 6f  OMEM;.      goto
0850: 20 66 61 69 6c 3b 0a 20 20 20 20 7d 0a 20 20 20   fail;.    }.   
0860: 20 66 6f 72 28 69 69 3d 30 3b 20 69 69 3c 6e 43   for(ii=0; ii<nC
0870: 6f 6c 3b 20 69 69 2b 2b 29 7b 0a 20 20 20 20 20  ol; ii++){.     
0880: 20 61 43 6f 6c 5b 69 69 5d 20 3d 20 73 71 6c 69   aCol[ii] = sqli
0890: 74 65 33 53 74 72 44 75 70 28 73 71 6c 69 74 65  te3StrDup(sqlite
08a0: 33 5f 63 6f 6c 75 6d 6e 5f 6e 61 6d 65 28 70 53  3_column_name(pS
08b0: 74 6d 74 2c 20 69 69 29 29 3b 0a 20 20 20 20 20  tmt, ii));.     
08c0: 20 69 66 28 20 21 61 43 6f 6c 5b 69 69 5d 20 29   if( !aCol[ii] )
08d0: 7b 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20 53  {.        rc = S
08e0: 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20  QLITE_NOMEM;.   
08f0: 20 20 20 20 20 67 6f 74 6f 20 66 61 69 6c 3b 0a       goto fail;.
0900: 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20        }.    }.  
0910: 7d 0a 0a 20 20 2a 70 61 43 6f 6c 20 3d 20 61 43  }..  *paCol = aC
0920: 6f 6c 3b 0a 20 20 2a 70 6e 43 6f 6c 20 3d 20 6e  ol;.  *pnCol = n
0930: 43 6f 6c 3b 0a 0a 66 61 69 6c 3a 0a 20 20 73 71  Col;..fail:.  sq
0940: 6c 69 74 65 33 5f 66 69 6e 61 6c 69 7a 65 28 70  lite3_finalize(p
0950: 53 74 6d 74 29 3b 0a 20 20 69 66 28 20 72 63 21  Stmt);.  if( rc!
0960: 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20 61 43  =SQLITE_OK && aC
0970: 6f 6c 20 29 7b 0a 20 20 20 20 69 6e 74 20 69 69  ol ){.    int ii
0980: 3b 0a 20 20 20 20 66 6f 72 28 69 69 3d 30 3b 20  ;.    for(ii=0; 
0990: 69 69 3c 6e 43 6f 6c 3b 20 69 69 2b 2b 29 7b 0a  ii<nCol; ii++){.
09a0: 20 20 20 20 20 20 73 71 6c 69 74 65 46 72 65 65        sqliteFree
09b0: 28 61 43 6f 6c 5b 69 69 5d 29 3b 0a 20 20 20 20  (aCol[ii]);.    
09c0: 7d 0a 20 20 20 20 73 71 6c 69 74 65 46 72 65 65  }.    sqliteFree
09d0: 28 61 43 6f 6c 29 3b 0a 20 20 7d 0a 20 20 72 65  (aCol);.  }.  re
09e0: 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 73 74 61 74  turn rc;.}..stat
09f0: 69 63 20 69 6e 74 20 67 65 74 49 6e 64 65 78 41  ic int getIndexA
0a00: 72 72 61 79 28 73 71 6c 69 74 65 33 20 2a 64 62  rray(sqlite3 *db
0a10: 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 54  , const char *zT
0a20: 61 62 2c 20 69 6e 74 20 2a 2a 70 61 49 6e 64 65  ab, int **paInde
0a30: 78 29 7b 0a 20 20 63 68 61 72 20 7a 42 75 66 5b  x){.  char zBuf[
0a40: 31 30 32 34 5d 3b 0a 20 20 73 71 6c 69 74 65 33  1024];.  sqlite3
0a50: 5f 73 74 6d 74 20 2a 70 53 74 6d 74 20 3d 20 30  _stmt *pStmt = 0
0a60: 3b 0a 20 20 69 6e 74 20 6e 43 6f 6c 3b 0a 20 20  ;.  int nCol;.  
0a70: 69 6e 74 20 2a 61 49 6e 64 65 78 20 3d 20 30 3b  int *aIndex = 0;
0a80: 0a 20 20 69 6e 74 20 72 63 3b 0a 0a 20 20 73 70  .  int rc;..  sp
0a90: 72 69 6e 74 66 28 7a 42 75 66 2c 20 22 53 45 4c  rintf(zBuf, "SEL
0aa0: 45 43 54 20 2a 20 46 52 4f 4d 20 25 73 22 2c 20  ECT * FROM %s", 
0ab0: 7a 54 61 62 29 3b 0a 20 20 72 63 20 3d 20 73 71  zTab);.  rc = sq
0ac0: 6c 69 74 65 33 5f 70 72 65 70 61 72 65 28 64 62  lite3_prepare(db
0ad0: 2c 20 7a 42 75 66 2c 20 2d 31 2c 20 26 70 53 74  , zBuf, -1, &pSt
0ae0: 6d 74 2c 20 30 29 3b 0a 20 20 6e 43 6f 6c 20 3d  mt, 0);.  nCol =
0af0: 20 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f   sqlite3_column_
0b00: 63 6f 75 6e 74 28 70 53 74 6d 74 29 3b 0a 0a 20  count(pStmt);.. 
0b10: 20 73 71 6c 69 74 65 33 5f 66 69 6e 61 6c 69 7a   sqlite3_finaliz
0b20: 65 28 70 53 74 6d 74 29 3b 0a 20 20 70 53 74 6d  e(pStmt);.  pStm
0b30: 74 20 3d 20 30 3b 0a 20 20 69 66 28 20 72 63 21  t = 0;.  if( rc!
0b40: 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20  =SQLITE_OK ){.  
0b50: 20 20 67 6f 74 6f 20 67 65 74 5f 69 6e 64 65 78    goto get_index
0b60: 5f 61 72 72 61 79 5f 6f 75 74 3b 0a 20 20 7d 0a  _array_out;.  }.
0b70: 0a 20 20 61 49 6e 64 65 78 20 3d 20 28 69 6e 74  .  aIndex = (int
0b80: 20 2a 29 73 71 6c 69 74 65 4d 61 6c 6c 6f 63 28   *)sqliteMalloc(
0b90: 73 69 7a 65 6f 66 28 69 6e 74 29 20 2a 20 6e 43  sizeof(int) * nC
0ba0: 6f 6c 29 3b 0a 20 20 69 66 28 20 21 61 49 6e 64  ol);.  if( !aInd
0bb0: 65 78 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 53  ex ){.    rc = S
0bc0: 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20  QLITE_NOMEM;.   
0bd0: 20 67 6f 74 6f 20 67 65 74 5f 69 6e 64 65 78 5f   goto get_index_
0be0: 61 72 72 61 79 5f 6f 75 74 3b 0a 20 20 7d 0a 0a  array_out;.  }..
0bf0: 20 20 73 70 72 69 6e 74 66 28 7a 42 75 66 2c 20    sprintf(zBuf, 
0c00: 22 50 52 41 47 4d 41 20 69 6e 64 65 78 5f 6c 69  "PRAGMA index_li
0c10: 73 74 28 25 73 29 22 2c 20 7a 54 61 62 29 3b 0a  st(%s)", zTab);.
0c20: 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 70    rc = sqlite3_p
0c30: 72 65 70 61 72 65 28 64 62 2c 20 7a 42 75 66 2c  repare(db, zBuf,
0c40: 20 2d 31 2c 20 26 70 53 74 6d 74 2c 20 30 29 3b   -1, &pStmt, 0);
0c50: 0a 0a 20 20 77 68 69 6c 65 28 20 70 53 74 6d 74  ..  while( pStmt
0c60: 20 26 26 20 73 71 6c 69 74 65 33 5f 73 74 65 70   && sqlite3_step
0c70: 28 70 53 74 6d 74 29 3d 3d 53 51 4c 49 54 45 5f  (pStmt)==SQLITE_
0c80: 52 4f 57 20 29 7b 0a 20 20 20 20 73 71 6c 69 74  ROW ){.    sqlit
0c90: 65 33 5f 73 74 6d 74 20 2a 70 53 74 6d 74 32 20  e3_stmt *pStmt2 
0ca0: 3d 20 30 3b 0a 20 20 20 20 73 70 72 69 6e 74 66  = 0;.    sprintf
0cb0: 28 7a 42 75 66 2c 20 22 50 52 41 47 4d 41 20 69  (zBuf, "PRAGMA i
0cc0: 6e 64 65 78 5f 69 6e 66 6f 28 25 73 29 22 2c 20  ndex_info(%s)", 
0cd0: 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 74  sqlite3_column_t
0ce0: 65 78 74 28 70 53 74 6d 74 2c 20 31 29 29 3b 0a  ext(pStmt, 1));.
0cf0: 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33      rc = sqlite3
0d00: 5f 70 72 65 70 61 72 65 28 64 62 2c 20 7a 42 75  _prepare(db, zBu
0d10: 66 2c 20 2d 31 2c 20 26 70 53 74 6d 74 32 2c 20  f, -1, &pStmt2, 
0d20: 30 29 3b 0a 20 20 20 20 69 66 28 20 70 53 74 6d  0);.    if( pStm
0d30: 74 32 20 26 26 20 73 71 6c 69 74 65 33 5f 73 74  t2 && sqlite3_st
0d40: 65 70 28 70 53 74 6d 74 32 29 3d 3d 53 51 4c 49  ep(pStmt2)==SQLI
0d50: 54 45 5f 52 4f 57 20 29 7b 0a 20 20 20 20 20 20  TE_ROW ){.      
0d60: 69 6e 74 20 63 69 64 20 3d 20 73 71 6c 69 74 65  int cid = sqlite
0d70: 33 5f 63 6f 6c 75 6d 6e 5f 69 6e 74 28 70 53 74  3_column_int(pSt
0d80: 6d 74 32 2c 20 31 29 3b 0a 20 20 20 20 20 20 61  mt2, 1);.      a
0d90: 73 73 65 72 74 28 20 63 69 64 3e 3d 30 20 26 26  ssert( cid>=0 &&
0da0: 20 63 69 64 3c 6e 43 6f 6c 20 29 3b 0a 20 20 20   cid<nCol );.   
0db0: 20 20 20 61 49 6e 64 65 78 5b 63 69 64 5d 20 3d     aIndex[cid] =
0dc0: 20 31 3b 0a 20 20 20 20 7d 0a 20 20 20 20 72 63   1;.    }.    rc
0dd0: 20 3d 20 73 71 6c 69 74 65 33 5f 66 69 6e 61 6c   = sqlite3_final
0de0: 69 7a 65 28 70 53 74 6d 74 32 29 3b 0a 20 20 20  ize(pStmt2);.   
0df0: 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f   if( rc!=SQLITE_
0e00: 4f 4b 20 29 7b 0a 20 20 20 20 20 20 73 71 6c 69  OK ){.      sqli
0e10: 74 65 33 5f 66 69 6e 61 6c 69 7a 65 28 70 53 74  te3_finalize(pSt
0e20: 6d 74 29 3b 0a 20 20 20 20 20 20 67 6f 74 6f 20  mt);.      goto 
0e30: 67 65 74 5f 69 6e 64 65 78 5f 61 72 72 61 79 5f  get_index_array_
0e40: 6f 75 74 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a  out;.    }.  }..
0e50: 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 66    rc = sqlite3_f
0e60: 69 6e 61 6c 69 7a 65 28 70 53 74 6d 74 29 3b 0a  inalize(pStmt);.
0e70: 0a 67 65 74 5f 69 6e 64 65 78 5f 61 72 72 61 79  .get_index_array
0e80: 5f 6f 75 74 3a 0a 20 20 69 66 28 20 72 63 21 3d  _out:.  if( rc!=
0e90: 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20  SQLITE_OK ){.   
0ea0: 20 73 71 6c 69 74 65 46 72 65 65 28 61 49 6e 64   sqliteFree(aInd
0eb0: 65 78 29 3b 0a 20 20 20 20 61 49 6e 64 65 78 20  ex);.    aIndex 
0ec0: 3d 20 30 3b 0a 20 20 7d 0a 20 20 2a 70 61 49 6e  = 0;.  }.  *paIn
0ed0: 64 65 78 20 3d 20 61 49 6e 64 65 78 3b 0a 20 20  dex = aIndex;.  
0ee0: 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a  return rc;.}../*
0ef0: 0a 2a 2a 20 47 6c 6f 62 61 6c 20 54 63 6c 20 76  .** Global Tcl v
0f00: 61 72 69 61 62 6c 65 20 24 65 63 68 6f 5f 6d 6f  ariable $echo_mo
0f10: 64 75 6c 65 20 69 73 20 61 20 6c 69 73 74 2e 20  dule is a list. 
0f20: 54 68 69 73 20 72 6f 75 74 69 6e 65 20 61 70 70  This routine app
0f30: 65 6e 64 73 0a 2a 2a 20 74 68 65 20 73 74 72 69  ends.** the stri
0f40: 6e 67 20 65 6c 65 6d 65 6e 74 20 7a 41 72 67 20  ng element zArg 
0f50: 74 6f 20 74 68 61 74 20 6c 69 73 74 20 69 6e 20  to that list in 
0f60: 69 6e 74 65 72 70 72 65 74 65 72 20 69 6e 74 65  interpreter inte
0f70: 72 70 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f  rp..*/.static vo
0f80: 69 64 20 61 70 70 65 6e 64 54 6f 45 63 68 6f 4d  id appendToEchoM
0f90: 6f 64 75 6c 65 28 54 63 6c 5f 49 6e 74 65 72 70  odule(Tcl_Interp
0fa0: 20 2a 69 6e 74 65 72 70 2c 20 63 6f 6e 73 74 20   *interp, const 
0fb0: 63 68 61 72 20 2a 7a 41 72 67 29 7b 0a 20 20 69  char *zArg){.  i
0fc0: 6e 74 20 66 6c 61 67 73 20 3d 20 28 54 43 4c 5f  nt flags = (TCL_
0fd0: 41 50 50 45 4e 44 5f 56 41 4c 55 45 20 7c 20 54  APPEND_VALUE | T
0fe0: 43 4c 5f 4c 49 53 54 5f 45 4c 45 4d 45 4e 54 20  CL_LIST_ELEMENT 
0ff0: 7c 20 54 43 4c 5f 47 4c 4f 42 41 4c 5f 4f 4e 4c  | TCL_GLOBAL_ONL
1000: 59 29 3b 0a 20 20 54 63 6c 5f 53 65 74 56 61 72  Y);.  Tcl_SetVar
1010: 28 69 6e 74 65 72 70 2c 20 22 65 63 68 6f 5f 6d  (interp, "echo_m
1020: 6f 64 75 6c 65 22 2c 20 28 7a 41 72 67 3f 7a 41  odule", (zArg?zA
1030: 72 67 3a 22 22 29 2c 20 66 6c 61 67 73 29 3b 0a  rg:""), flags);.
1040: 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75  }../*.** This fu
1050: 6e 63 74 69 6f 6e 20 69 73 20 63 61 6c 6c 65 64  nction is called
1060: 20 66 72 6f 6d 20 77 69 74 68 69 6e 20 74 68 65   from within the
1070: 20 65 63 68 6f 2d 6d 6f 64 75 6c 65 73 20 78 43   echo-modules xC
1080: 72 65 61 74 65 20 61 6e 64 0a 2a 2a 20 78 43 6f  reate and.** xCo
1090: 6e 6e 65 63 74 20 6d 65 74 68 6f 64 73 2e 20 54  nnect methods. T
10a0: 68 65 20 61 72 67 63 20 61 6e 64 20 61 72 67 76  he argc and argv
10b0: 20 61 72 67 75 6d 65 6e 74 73 20 61 72 65 20 63   arguments are c
10c0: 6f 70 69 65 73 20 6f 66 20 74 68 6f 73 65 20 0a  opies of those .
10d0: 2a 2a 20 70 61 73 73 65 64 20 74 6f 20 74 68 65  ** passed to the
10e0: 20 63 61 6c 6c 69 6e 67 20 6d 65 74 68 6f 64 2e   calling method.
10f0: 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 69   This function i
1100: 73 20 72 65 73 70 6f 6e 73 69 62 6c 65 20 66 6f  s responsible fo
1110: 72 0a 2a 2a 20 63 61 6c 6c 69 6e 67 20 73 71 6c  r.** calling sql
1120: 69 74 65 33 5f 64 65 63 6c 61 72 65 5f 76 74 61  ite3_declare_vta
1130: 62 28 29 20 74 6f 20 64 65 63 6c 61 72 65 20 74  b() to declare t
1140: 68 65 20 73 63 68 65 6d 61 20 6f 66 20 74 68 65  he schema of the
1150: 20 76 69 72 74 75 61 6c 0a 2a 2a 20 74 61 62 6c   virtual.** tabl
1160: 65 20 62 65 69 6e 67 20 63 72 65 61 74 65 64 20  e being created 
1170: 6f 72 20 63 6f 6e 6e 65 63 74 65 64 2e 0a 2a 2a  or connected..**
1180: 0a 2a 2a 20 49 66 20 74 68 65 20 63 6f 6e 73 74  .** If the const
1190: 72 75 63 74 6f 72 20 77 61 73 20 70 61 73 73 65  ructor was passe
11a0: 64 20 6a 75 73 74 20 6f 6e 65 20 61 72 67 75 6d  d just one argum
11b0: 65 6e 74 2c 20 69 2e 65 2e 3a 0a 2a 2a 0a 2a 2a  ent, i.e.:.**.**
11c0: 20 20 20 43 52 45 41 54 45 20 54 41 42 4c 45 20     CREATE TABLE 
11d0: 74 31 20 41 53 20 65 63 68 6f 28 74 32 29 3b 0a  t1 AS echo(t2);.
11e0: 2a 2a 0a 2a 2a 20 54 68 65 6e 20 74 32 20 69 73  **.** Then t2 is
11f0: 20 61 73 73 75 6d 65 64 20 74 6f 20 62 65 20 74   assumed to be t
1200: 68 65 20 6e 61 6d 65 20 6f 66 20 61 20 2a 72 65  he name of a *re
1210: 61 6c 2a 20 64 61 74 61 62 61 73 65 20 74 61 62  al* database tab
1220: 6c 65 2e 20 54 68 65 0a 2a 2a 20 73 63 68 65 6d  le. The.** schem
1230: 61 20 6f 66 20 74 68 65 20 76 69 72 74 75 61 6c  a of the virtual
1240: 20 74 61 62 6c 65 20 69 73 20 64 65 63 6c 61 72   table is declar
1250: 65 64 20 62 79 20 70 61 73 73 69 6e 67 20 61 20  ed by passing a 
1260: 63 6f 70 79 20 6f 66 20 74 68 65 20 0a 2a 2a 20  copy of the .** 
1270: 43 52 45 41 54 45 20 54 41 42 4c 45 20 73 74 61  CREATE TABLE sta
1280: 74 65 6d 65 6e 74 20 66 6f 72 20 74 68 65 20 72  tement for the r
1290: 65 61 6c 20 74 61 62 6c 65 20 74 6f 20 73 71 6c  eal table to sql
12a0: 69 74 65 33 5f 64 65 63 6c 61 72 65 5f 76 74 61  ite3_declare_vta
12b0: 62 28 29 2e 0a 2a 2a 20 48 65 6e 63 65 2c 20 74  b()..** Hence, t
12c0: 68 65 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65  he virtual table
12d0: 20 73 68 6f 75 6c 64 20 68 61 76 65 20 65 78 61   should have exa
12e0: 63 74 6c 79 20 74 68 65 20 73 61 6d 65 20 63 6f  ctly the same co
12f0: 6c 75 6d 6e 20 6e 61 6d 65 73 20 61 6e 64 20 0a  lumn names and .
1300: 2a 2a 20 74 79 70 65 73 20 61 73 20 74 68 65 20  ** types as the 
1310: 72 65 61 6c 20 74 61 62 6c 65 2e 0a 2a 2f 0a 73  real table..*/.s
1320: 74 61 74 69 63 20 69 6e 74 20 65 63 68 6f 44 65  tatic int echoDe
1330: 63 6c 61 72 65 56 74 61 62 28 0a 20 20 65 63 68  clareVtab(.  ech
1340: 6f 5f 76 74 61 62 20 2a 70 56 74 61 62 2c 20 0a  o_vtab *pVtab, .
1350: 20 20 73 71 6c 69 74 65 33 20 2a 64 62 2c 20 0a    sqlite3 *db, .
1360: 20 20 69 6e 74 20 61 72 67 63 2c 20 0a 20 20 63    int argc, .  c
1370: 68 61 72 20 2a 2a 61 72 67 76 0a 29 7b 0a 20 20  har **argv.){.  
1380: 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f  int rc = SQLITE_
1390: 4f 4b 3b 0a 0a 20 20 69 66 28 20 61 72 67 63 3d  OK;..  if( argc=
13a0: 3d 32 20 29 7b 0a 20 20 20 20 73 71 6c 69 74 65  =2 ){.    sqlite
13b0: 33 5f 73 74 6d 74 20 2a 70 53 74 6d 74 20 3d 20  3_stmt *pStmt = 
13c0: 30 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 70  0;.    sqlite3_p
13d0: 72 65 70 61 72 65 28 64 62 2c 20 0a 20 20 20 20  repare(db, .    
13e0: 20 20 20 20 22 53 45 4c 45 43 54 20 73 71 6c 20      "SELECT sql 
13f0: 46 52 4f 4d 20 73 71 6c 69 74 65 5f 6d 61 73 74  FROM sqlite_mast
1400: 65 72 20 57 48 45 52 45 20 74 79 70 65 20 3d 20  er WHERE type = 
1410: 27 74 61 62 6c 65 27 20 41 4e 44 20 6e 61 6d 65  'table' AND name
1420: 20 3d 20 3f 22 2c 0a 20 20 20 20 20 20 20 20 2d   = ?",.        -
1430: 31 2c 20 26 70 53 74 6d 74 2c 20 30 29 3b 0a 20  1, &pStmt, 0);. 
1440: 20 20 20 73 71 6c 69 74 65 33 5f 62 69 6e 64 5f     sqlite3_bind_
1450: 74 65 78 74 28 70 53 74 6d 74 2c 20 31 2c 20 61  text(pStmt, 1, a
1460: 72 67 76 5b 31 5d 2c 20 2d 31 2c 20 30 29 3b 0a  rgv[1], -1, 0);.
1470: 20 20 20 20 69 66 28 20 73 71 6c 69 74 65 33 5f      if( sqlite3_
1480: 73 74 65 70 28 70 53 74 6d 74 29 3d 3d 53 51 4c  step(pStmt)==SQL
1490: 49 54 45 5f 52 4f 57 20 29 7b 0a 20 20 20 20 20  ITE_ROW ){.     
14a0: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 43 72   const char *zCr
14b0: 65 61 74 65 54 61 62 6c 65 20 3d 20 73 71 6c 69  eateTable = sqli
14c0: 74 65 33 5f 63 6f 6c 75 6d 6e 5f 74 65 78 74 28  te3_column_text(
14d0: 70 53 74 6d 74 2c 20 30 29 3b 0a 23 69 66 6e 64  pStmt, 0);.#ifnd
14e0: 65 66 20 53 51 4c 49 54 45 5f 4f 4d 49 54 5f 56  ef SQLITE_OMIT_V
14f0: 49 52 54 55 41 4c 54 41 42 4c 45 0a 20 20 20 20  IRTUALTABLE.    
1500: 20 20 73 71 6c 69 74 65 33 5f 64 65 63 6c 61 72    sqlite3_declar
1510: 65 5f 76 74 61 62 28 64 62 2c 20 7a 43 72 65 61  e_vtab(db, zCrea
1520: 74 65 54 61 62 6c 65 29 3b 0a 23 65 6e 64 69 66  teTable);.#endif
1530: 0a 20 20 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20  .    } else {.  
1540: 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f      rc = SQLITE_
1550: 45 52 52 4f 52 3b 0a 20 20 20 20 7d 0a 20 20 20  ERROR;.    }.   
1560: 20 73 71 6c 69 74 65 33 5f 66 69 6e 61 6c 69 7a   sqlite3_finaliz
1570: 65 28 70 53 74 6d 74 29 3b 0a 20 20 20 20 69 66  e(pStmt);.    if
1580: 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
1590: 29 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 67 65  ){.      rc = ge
15a0: 74 49 6e 64 65 78 41 72 72 61 79 28 64 62 2c 20  tIndexArray(db, 
15b0: 61 72 67 76 5b 31 5d 2c 20 26 70 56 74 61 62 2d  argv[1], &pVtab-
15c0: 3e 61 49 6e 64 65 78 29 3b 0a 20 20 20 20 7d 0a  >aIndex);.    }.
15d0: 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49      if( rc==SQLI
15e0: 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 72  TE_OK ){.      r
15f0: 63 20 3d 20 67 65 74 43 6f 6c 75 6d 6e 4e 61 6d  c = getColumnNam
1600: 65 73 28 64 62 2c 20 61 72 67 76 5b 31 5d 2c 20  es(db, argv[1], 
1610: 26 70 56 74 61 62 2d 3e 61 43 6f 6c 2c 20 26 70  &pVtab->aCol, &p
1620: 56 74 61 62 2d 3e 6e 43 6f 6c 29 3b 0a 20 20 20  Vtab->nCol);.   
1630: 20 7d 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e   }.  }..  return
1640: 20 72 63 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69   rc;.}..static i
1650: 6e 74 20 65 63 68 6f 44 65 73 74 72 75 63 74 6f  nt echoDestructo
1660: 72 28 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a  r(sqlite3_vtab *
1670: 70 56 74 61 62 29 7b 0a 20 20 69 6e 74 20 69 69  pVtab){.  int ii
1680: 3b 0a 20 20 65 63 68 6f 5f 76 74 61 62 20 2a 70  ;.  echo_vtab *p
1690: 20 3d 20 28 65 63 68 6f 5f 76 74 61 62 2a 29 70   = (echo_vtab*)p
16a0: 56 74 61 62 3b 0a 20 20 73 71 6c 69 74 65 46 72  Vtab;.  sqliteFr
16b0: 65 65 28 70 2d 3e 61 49 6e 64 65 78 29 3b 0a 20  ee(p->aIndex);. 
16c0: 20 66 6f 72 28 69 69 3d 30 3b 20 69 69 3c 70 2d   for(ii=0; ii<p-
16d0: 3e 6e 43 6f 6c 3b 20 69 69 2b 2b 29 7b 0a 20 20  >nCol; ii++){.  
16e0: 20 20 73 71 6c 69 74 65 46 72 65 65 28 70 2d 3e    sqliteFree(p->
16f0: 61 43 6f 6c 5b 69 69 5d 29 3b 0a 20 20 7d 0a 20  aCol[ii]);.  }. 
1700: 20 73 71 6c 69 74 65 46 72 65 65 28 70 2d 3e 61   sqliteFree(p->a
1710: 43 6f 6c 29 3b 0a 20 20 73 71 6c 69 74 65 46 72  Col);.  sqliteFr
1720: 65 65 28 70 2d 3e 7a 54 61 62 6c 65 4e 61 6d 65  ee(p->zTableName
1730: 29 3b 0a 20 20 73 71 6c 69 74 65 46 72 65 65 28  );.  sqliteFree(
1740: 70 29 3b 0a 20 20 72 65 74 75 72 6e 20 30 3b 0a  p);.  return 0;.
1750: 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 65 63  }..static int ec
1760: 68 6f 43 6f 6e 73 74 72 75 63 74 6f 72 28 0a 20  hoConstructor(. 
1770: 20 73 71 6c 69 74 65 33 20 2a 64 62 2c 0a 20 20   sqlite3 *db,.  
1780: 76 6f 69 64 20 2a 70 41 75 78 2c 0a 20 20 69 6e  void *pAux,.  in
1790: 74 20 61 72 67 63 2c 20 63 68 61 72 20 2a 2a 61  t argc, char **a
17a0: 72 67 76 2c 0a 20 20 73 71 6c 69 74 65 33 5f 76  rgv,.  sqlite3_v
17b0: 74 61 62 20 2a 2a 70 70 56 74 61 62 0a 29 7b 0a  tab **ppVtab.){.
17c0: 20 20 69 6e 74 20 69 3b 0a 20 20 65 63 68 6f 5f    int i;.  echo_
17d0: 76 74 61 62 20 2a 70 56 74 61 62 3b 0a 0a 20 20  vtab *pVtab;..  
17e0: 70 56 74 61 62 20 3d 20 73 71 6c 69 74 65 4d 61  pVtab = sqliteMa
17f0: 6c 6c 6f 63 28 20 73 69 7a 65 6f 66 28 2a 70 56  lloc( sizeof(*pV
1800: 74 61 62 29 20 29 3b 0a 20 20 70 56 74 61 62 2d  tab) );.  pVtab-
1810: 3e 69 6e 74 65 72 70 20 3d 20 28 54 63 6c 5f 49  >interp = (Tcl_I
1820: 6e 74 65 72 70 20 2a 29 70 41 75 78 3b 0a 20 20  nterp *)pAux;.  
1830: 70 56 74 61 62 2d 3e 64 62 20 3d 20 64 62 3b 0a  pVtab->db = db;.
1840: 20 20 70 56 74 61 62 2d 3e 7a 54 61 62 6c 65 4e    pVtab->zTableN
1850: 61 6d 65 20 3d 20 73 71 6c 69 74 65 33 4d 50 72  ame = sqlite3MPr
1860: 69 6e 74 66 28 22 25 73 22 2c 20 61 72 67 76 5b  intf("%s", argv[
1870: 31 5d 29 3b 0a 20 20 66 6f 72 28 69 3d 30 3b 20  1]);.  for(i=0; 
1880: 69 3c 61 72 67 63 3b 20 69 2b 2b 29 7b 0a 20 20  i<argc; i++){.  
1890: 20 20 61 70 70 65 6e 64 54 6f 45 63 68 6f 4d 6f    appendToEchoMo
18a0: 64 75 6c 65 28 70 56 74 61 62 2d 3e 69 6e 74 65  dule(pVtab->inte
18b0: 72 70 2c 20 61 72 67 76 5b 69 5d 29 3b 0a 20 20  rp, argv[i]);.  
18c0: 7d 0a 0a 20 20 69 66 28 20 65 63 68 6f 44 65 63  }..  if( echoDec
18d0: 6c 61 72 65 56 74 61 62 28 70 56 74 61 62 2c 20  lareVtab(pVtab, 
18e0: 64 62 2c 20 61 72 67 63 2c 20 61 72 67 76 29 20  db, argc, argv) 
18f0: 29 7b 0a 20 20 20 20 65 63 68 6f 44 65 73 74 72  ){.    echoDestr
1900: 75 63 74 6f 72 28 28 73 71 6c 69 74 65 33 5f 76  uctor((sqlite3_v
1910: 74 61 62 20 2a 29 70 56 74 61 62 29 3b 0a 20 20  tab *)pVtab);.  
1920: 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f    return SQLITE_
1930: 45 52 52 4f 52 3b 0a 20 20 7d 0a 0a 20 20 2a 70  ERROR;.  }..  *p
1940: 70 56 74 61 62 20 3d 20 26 70 56 74 61 62 2d 3e  pVtab = &pVtab->
1950: 62 61 73 65 3b 0a 20 20 72 65 74 75 72 6e 20 53  base;.  return S
1960: 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 20  QLITE_OK;.}../* 
1970: 4d 65 74 68 6f 64 73 20 66 6f 72 20 74 68 65 20  Methods for the 
1980: 65 63 68 6f 20 6d 6f 64 75 6c 65 20 2a 2f 0a 73  echo module */.s
1990: 74 61 74 69 63 20 69 6e 74 20 65 63 68 6f 43 72  tatic int echoCr
19a0: 65 61 74 65 28 0a 20 20 73 71 6c 69 74 65 33 20  eate(.  sqlite3 
19b0: 2a 64 62 2c 0a 20 20 76 6f 69 64 20 2a 70 41 75  *db,.  void *pAu
19c0: 78 2c 0a 20 20 69 6e 74 20 61 72 67 63 2c 20 63  x,.  int argc, c
19d0: 68 61 72 20 2a 2a 61 72 67 76 2c 0a 20 20 73 71  har **argv,.  sq
19e0: 6c 69 74 65 33 5f 76 74 61 62 20 2a 2a 70 70 56  lite3_vtab **ppV
19f0: 74 61 62 0a 29 7b 0a 20 20 61 70 70 65 6e 64 54  tab.){.  appendT
1a00: 6f 45 63 68 6f 4d 6f 64 75 6c 65 28 28 54 63 6c  oEchoModule((Tcl
1a10: 5f 49 6e 74 65 72 70 20 2a 29 28 70 41 75 78 29  _Interp *)(pAux)
1a20: 2c 20 22 78 43 72 65 61 74 65 22 29 3b 0a 20 20  , "xCreate");.  
1a30: 72 65 74 75 72 6e 20 65 63 68 6f 43 6f 6e 73 74  return echoConst
1a40: 72 75 63 74 6f 72 28 64 62 2c 20 70 41 75 78 2c  ructor(db, pAux,
1a50: 20 61 72 67 63 2c 20 61 72 67 76 2c 20 70 70 56   argc, argv, ppV
1a60: 74 61 62 29 3b 0a 7d 0a 73 74 61 74 69 63 20 69  tab);.}.static i
1a70: 6e 74 20 65 63 68 6f 43 6f 6e 6e 65 63 74 28 0a  nt echoConnect(.
1a80: 20 20 73 71 6c 69 74 65 33 20 2a 64 62 2c 0a 20    sqlite3 *db,. 
1a90: 20 76 6f 69 64 20 2a 70 41 75 78 2c 0a 20 20 69   void *pAux,.  i
1aa0: 6e 74 20 61 72 67 63 2c 20 63 68 61 72 20 2a 2a  nt argc, char **
1ab0: 61 72 67 76 2c 0a 20 20 73 71 6c 69 74 65 33 5f  argv,.  sqlite3_
1ac0: 76 74 61 62 20 2a 2a 70 70 56 74 61 62 0a 29 7b  vtab **ppVtab.){
1ad0: 0a 20 20 61 70 70 65 6e 64 54 6f 45 63 68 6f 4d  .  appendToEchoM
1ae0: 6f 64 75 6c 65 28 28 54 63 6c 5f 49 6e 74 65 72  odule((Tcl_Inter
1af0: 70 20 2a 29 28 70 41 75 78 29 2c 20 22 78 43 6f  p *)(pAux), "xCo
1b00: 6e 6e 65 63 74 22 29 3b 0a 20 20 72 65 74 75 72  nnect");.  retur
1b10: 6e 20 65 63 68 6f 43 6f 6e 73 74 72 75 63 74 6f  n echoConstructo
1b20: 72 28 64 62 2c 20 70 41 75 78 2c 20 61 72 67 63  r(db, pAux, argc
1b30: 2c 20 61 72 67 76 2c 20 70 70 56 74 61 62 29 3b  , argv, ppVtab);
1b40: 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 65  .}..static int e
1b50: 63 68 6f 44 69 73 63 6f 6e 6e 65 63 74 28 73 71  choDisconnect(sq
1b60: 6c 69 74 65 33 5f 76 74 61 62 20 2a 70 56 74 61  lite3_vtab *pVta
1b70: 62 29 7b 0a 20 20 61 70 70 65 6e 64 54 6f 45 63  b){.  appendToEc
1b80: 68 6f 4d 6f 64 75 6c 65 28 28 28 65 63 68 6f 5f  hoModule(((echo_
1b90: 76 74 61 62 20 2a 29 70 56 74 61 62 29 2d 3e 69  vtab *)pVtab)->i
1ba0: 6e 74 65 72 70 2c 20 22 78 44 69 73 63 6f 6e 6e  nterp, "xDisconn
1bb0: 65 63 74 22 29 3b 0a 20 20 72 65 74 75 72 6e 20  ect");.  return 
1bc0: 65 63 68 6f 44 65 73 74 72 75 63 74 6f 72 28 70  echoDestructor(p
1bd0: 56 74 61 62 29 3b 0a 7d 0a 73 74 61 74 69 63 20  Vtab);.}.static 
1be0: 69 6e 74 20 65 63 68 6f 44 65 73 74 72 6f 79 28  int echoDestroy(
1bf0: 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 70 56  sqlite3_vtab *pV
1c00: 74 61 62 29 7b 0a 20 20 61 70 70 65 6e 64 54 6f  tab){.  appendTo
1c10: 45 63 68 6f 4d 6f 64 75 6c 65 28 28 28 65 63 68  EchoModule(((ech
1c20: 6f 5f 76 74 61 62 20 2a 29 70 56 74 61 62 29 2d  o_vtab *)pVtab)-
1c30: 3e 69 6e 74 65 72 70 2c 20 22 78 44 65 73 74 72  >interp, "xDestr
1c40: 6f 79 22 29 3b 0a 20 20 72 65 74 75 72 6e 20 65  oy");.  return e
1c50: 63 68 6f 44 65 73 74 72 75 63 74 6f 72 28 70 56  choDestructor(pV
1c60: 74 61 62 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20  tab);.}..static 
1c70: 69 6e 74 20 65 63 68 6f 4f 70 65 6e 28 73 71 6c  int echoOpen(sql
1c80: 69 74 65 33 5f 76 74 61 62 20 2a 70 56 54 61 62  ite3_vtab *pVTab
1c90: 2c 20 73 71 6c 69 74 65 33 5f 76 74 61 62 5f 63  , sqlite3_vtab_c
1ca0: 75 72 73 6f 72 20 2a 2a 70 70 43 75 72 73 6f 72  ursor **ppCursor
1cb0: 29 7b 0a 20 20 65 63 68 6f 5f 63 75 72 73 6f 72  ){.  echo_cursor
1cc0: 20 2a 70 43 75 72 3b 0a 20 20 70 43 75 72 20 3d   *pCur;.  pCur =
1cd0: 20 73 71 6c 69 74 65 4d 61 6c 6c 6f 63 28 73 69   sqliteMalloc(si
1ce0: 7a 65 6f 66 28 65 63 68 6f 5f 63 75 72 73 6f 72  zeof(echo_cursor
1cf0: 29 29 3b 0a 20 20 2a 70 70 43 75 72 73 6f 72 20  ));.  *ppCursor 
1d00: 3d 20 28 73 71 6c 69 74 65 33 5f 76 74 61 62 5f  = (sqlite3_vtab_
1d10: 63 75 72 73 6f 72 20 2a 29 70 43 75 72 3b 0a 20  cursor *)pCur;. 
1d20: 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f   return SQLITE_O
1d30: 4b 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74  K;.}..static int
1d40: 20 65 63 68 6f 43 6c 6f 73 65 28 73 71 6c 69 74   echoClose(sqlit
1d50: 65 33 5f 76 74 61 62 5f 63 75 72 73 6f 72 20 2a  e3_vtab_cursor *
1d60: 63 75 72 29 7b 0a 20 20 65 63 68 6f 5f 63 75 72  cur){.  echo_cur
1d70: 73 6f 72 20 2a 70 43 75 72 20 3d 20 28 65 63 68  sor *pCur = (ech
1d80: 6f 5f 63 75 72 73 6f 72 20 2a 29 63 75 72 3b 0a  o_cursor *)cur;.
1d90: 20 20 73 71 6c 69 74 65 33 5f 66 69 6e 61 6c 69    sqlite3_finali
1da0: 7a 65 28 70 43 75 72 2d 3e 70 53 74 6d 74 29 3b  ze(pCur->pStmt);
1db0: 0a 20 20 73 71 6c 69 74 65 46 72 65 65 28 70 43  .  sqliteFree(pC
1dc0: 75 72 29 3b 0a 20 20 72 65 74 75 72 6e 20 53 51  ur);.  return SQ
1dd0: 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 73 74 61 74  LITE_OK;.}..stat
1de0: 69 63 20 69 6e 74 20 65 63 68 6f 4e 65 78 74 28  ic int echoNext(
1df0: 73 71 6c 69 74 65 33 5f 76 74 61 62 5f 63 75 72  sqlite3_vtab_cur
1e00: 73 6f 72 20 2a 63 75 72 29 7b 0a 20 20 69 6e 74  sor *cur){.  int
1e10: 20 72 63 3b 0a 20 20 65 63 68 6f 5f 63 75 72 73   rc;.  echo_curs
1e20: 6f 72 20 2a 70 43 75 72 20 3d 20 28 65 63 68 6f  or *pCur = (echo
1e30: 5f 63 75 72 73 6f 72 20 2a 29 63 75 72 3b 0a 0a  _cursor *)cur;..
1e40: 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 73    rc = sqlite3_s
1e50: 74 65 70 28 70 43 75 72 2d 3e 70 53 74 6d 74 29  tep(pCur->pStmt)
1e60: 3b 0a 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c  ;..  if( rc==SQL
1e70: 49 54 45 5f 52 4f 57 20 29 7b 0a 20 20 20 20 72  ITE_ROW ){.    r
1e80: 63 20 3d 20 31 3b 0a 20 20 7d 20 65 6c 73 65 20  c = 1;.  } else 
1e90: 7b 0a 20 20 20 20 70 43 75 72 2d 3e 65 72 72 63  {.    pCur->errc
1ea0: 6f 64 65 20 3d 20 73 71 6c 69 74 65 33 5f 66 69  ode = sqlite3_fi
1eb0: 6e 61 6c 69 7a 65 28 70 43 75 72 2d 3e 70 53 74  nalize(pCur->pSt
1ec0: 6d 74 29 3b 0a 20 20 20 20 70 43 75 72 2d 3e 70  mt);.    pCur->p
1ed0: 53 74 6d 74 20 3d 20 30 3b 0a 20 20 20 20 72 63  Stmt = 0;.    rc
1ee0: 20 3d 20 30 3b 0a 20 20 7d 0a 0a 20 20 72 65 74   = 0;.  }..  ret
1ef0: 75 72 6e 20 72 63 3b 0a 7d 0a 0a 73 74 61 74 69  urn rc;.}..stati
1f00: 63 20 69 6e 74 20 65 63 68 6f 43 6f 6c 75 6d 6e  c int echoColumn
1f10: 28 73 71 6c 69 74 65 33 5f 76 74 61 62 5f 63 75  (sqlite3_vtab_cu
1f20: 72 73 6f 72 20 2a 63 75 72 2c 20 73 71 6c 69 74  rsor *cur, sqlit
1f30: 65 33 5f 63 6f 6e 74 65 78 74 20 2a 63 74 78 2c  e3_context *ctx,
1f40: 20 69 6e 74 20 69 29 7b 0a 20 20 69 6e 74 20 69   int i){.  int i
1f50: 43 6f 6c 20 3d 20 69 20 2b 20 31 3b 0a 20 20 73  Col = i + 1;.  s
1f60: 71 6c 69 74 65 33 5f 73 74 6d 74 20 2a 70 53 74  qlite3_stmt *pSt
1f70: 6d 74 20 3d 20 28 28 65 63 68 6f 5f 63 75 72 73  mt = ((echo_curs
1f80: 6f 72 20 2a 29 63 75 72 29 2d 3e 70 53 74 6d 74  or *)cur)->pStmt
1f90: 3b 0a 0a 20 20 61 73 73 65 72 74 28 20 73 71 6c  ;..  assert( sql
1fa0: 69 74 65 33 5f 64 61 74 61 5f 63 6f 75 6e 74 28  ite3_data_count(
1fb0: 70 53 74 6d 74 29 3e 69 43 6f 6c 20 29 3b 0a 20  pStmt)>iCol );. 
1fc0: 20 73 71 6c 69 74 65 33 5f 72 65 73 75 6c 74 5f   sqlite3_result_
1fd0: 76 61 6c 75 65 28 63 74 78 2c 20 73 71 6c 69 74  value(ctx, sqlit
1fe0: 65 33 5f 63 6f 6c 75 6d 6e 5f 76 61 6c 75 65 28  e3_column_value(
1ff0: 70 53 74 6d 74 2c 20 69 43 6f 6c 29 29 3b 0a 20  pStmt, iCol));. 
2000: 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f   return SQLITE_O
2010: 4b 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74  K;.}..static int
2020: 20 65 63 68 6f 52 6f 77 69 64 28 73 71 6c 69 74   echoRowid(sqlit
2030: 65 33 5f 76 74 61 62 5f 63 75 72 73 6f 72 20 2a  e3_vtab_cursor *
2040: 63 75 72 2c 20 73 71 6c 69 74 65 5f 69 6e 74 36  cur, sqlite_int6
2050: 34 20 2a 70 52 6f 77 69 64 29 7b 0a 20 20 73 71  4 *pRowid){.  sq
2060: 6c 69 74 65 33 5f 73 74 6d 74 20 2a 70 53 74 6d  lite3_stmt *pStm
2070: 74 20 3d 20 28 28 65 63 68 6f 5f 63 75 72 73 6f  t = ((echo_curso
2080: 72 20 2a 29 63 75 72 29 2d 3e 70 53 74 6d 74 3b  r *)cur)->pStmt;
2090: 0a 20 20 2a 70 52 6f 77 69 64 20 3d 20 73 71 6c  .  *pRowid = sql
20a0: 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 69 6e 74 36  ite3_column_int6
20b0: 34 28 70 53 74 6d 74 2c 20 30 29 3b 0a 20 20 72  4(pStmt, 0);.  r
20c0: 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b  eturn SQLITE_OK;
20d0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 6f 6d 70 75 74  .}../*.** Comput
20e0: 65 20 61 20 73 69 6d 70 6c 65 20 68 61 73 68 20  e a simple hash 
20f0: 6f 66 20 74 68 65 20 6e 75 6c 6c 20 74 65 72 6d  of the null term
2100: 69 6e 61 74 65 64 20 73 74 72 69 6e 67 20 7a 53  inated string zS
2110: 74 72 69 6e 67 2e 0a 2a 2a 0a 2a 2a 20 54 68 69  tring..**.** Thi
2120: 73 20 6d 6f 64 75 6c 65 20 75 73 65 73 20 6f 6e  s module uses on
2130: 6c 79 20 73 71 6c 69 74 65 33 5f 69 6e 64 65 78  ly sqlite3_index
2140: 5f 69 6e 66 6f 2e 69 64 78 53 74 72 2c 20 6e 6f  _info.idxStr, no
2150: 74 20 0a 2a 2a 20 73 71 6c 69 74 65 33 5f 69 6e  t .** sqlite3_in
2160: 64 65 78 5f 69 6e 66 6f 2e 69 64 78 4e 75 6d 2e  dex_info.idxNum.
2170: 20 53 6f 20 74 6f 20 74 65 73 74 20 69 64 78 4e   So to test idxN
2180: 75 6d 2c 20 77 68 65 6e 20 69 64 78 53 74 72 20  um, when idxStr 
2190: 69 73 20 73 65 74 0a 2a 2a 20 69 6e 20 65 63 68  is set.** in ech
21a0: 6f 42 65 73 74 49 6e 64 65 78 28 29 2c 20 69 64  oBestIndex(), id
21b0: 78 4e 75 6d 20 69 73 20 73 65 74 20 74 6f 20 74  xNum is set to t
21c0: 68 65 20 63 6f 72 72 65 73 70 6f 6e 64 69 6e 67  he corresponding
21d0: 20 68 61 73 68 20 76 61 6c 75 65 2e 0a 2a 2a 20   hash value..** 
21e0: 49 6e 20 65 63 68 6f 46 69 6c 74 65 72 28 29 2c  In echoFilter(),
21f0: 20 63 6f 64 65 20 61 73 73 65 72 74 28 29 73 20   code assert()s 
2200: 74 68 61 74 20 74 68 65 20 73 75 70 70 6c 69 65  that the supplie
2210: 64 20 69 64 78 4e 75 6d 20 76 61 6c 75 65 20 69  d idxNum value i
2220: 73 0a 2a 2a 20 69 6e 64 65 65 64 20 74 68 65 20  s.** indeed the 
2230: 68 61 73 68 20 6f 66 20 74 68 65 20 73 75 70 70  hash of the supp
2240: 6c 69 65 64 20 69 64 78 53 74 72 2e 0a 2a 2f 0a  lied idxStr..*/.
2250: 73 74 61 74 69 63 20 69 6e 74 20 68 61 73 68 53  static int hashS
2260: 74 72 69 6e 67 28 63 6f 6e 73 74 20 63 68 61 72  tring(const char
2270: 20 2a 7a 53 74 72 69 6e 67 29 7b 0a 20 20 69 6e   *zString){.  in
2280: 74 20 76 61 6c 20 3d 20 30 3b 0a 20 20 69 6e 74  t val = 0;.  int
2290: 20 69 69 3b 0a 20 20 66 6f 72 28 69 69 3d 30 3b   ii;.  for(ii=0;
22a0: 20 7a 53 74 72 69 6e 67 5b 69 69 5d 3b 20 69 69   zString[ii]; ii
22b0: 2b 2b 29 7b 0a 20 20 20 20 76 61 6c 20 3d 20 28  ++){.    val = (
22c0: 76 61 6c 20 3c 3c 20 33 29 20 2b 20 28 69 6e 74  val << 3) + (int
22d0: 29 7a 53 74 72 69 6e 67 5b 69 69 5d 3b 0a 20 20  )zString[ii];.  
22e0: 7d 0a 20 20 72 65 74 75 72 6e 20 76 61 6c 3b 0a  }.  return val;.
22f0: 7d 0a 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 65  }...static int e
2300: 63 68 6f 46 69 6c 74 65 72 28 0a 20 20 73 71 6c  choFilter(.  sql
2310: 69 74 65 33 5f 76 74 61 62 5f 63 75 72 73 6f 72  ite3_vtab_cursor
2320: 20 2a 70 56 74 61 62 43 75 72 73 6f 72 2c 20 0a   *pVtabCursor, .
2330: 20 20 69 6e 74 20 69 64 78 4e 75 6d 2c 20 63 6f    int idxNum, co
2340: 6e 73 74 20 63 68 61 72 20 2a 69 64 78 53 74 72  nst char *idxStr
2350: 2c 0a 20 20 69 6e 74 20 61 72 67 63 2c 20 73 71  ,.  int argc, sq
2360: 6c 69 74 65 33 5f 76 61 6c 75 65 20 2a 2a 61 72  lite3_value **ar
2370: 67 76 0a 29 7b 0a 20 20 69 6e 74 20 72 63 3b 0a  gv.){.  int rc;.
2380: 20 20 69 6e 74 20 69 3b 0a 0a 20 20 65 63 68 6f    int i;..  echo
2390: 5f 63 75 72 73 6f 72 20 2a 70 43 75 72 20 3d 20  _cursor *pCur = 
23a0: 28 65 63 68 6f 5f 63 75 72 73 6f 72 20 2a 29 70  (echo_cursor *)p
23b0: 56 74 61 62 43 75 72 73 6f 72 3b 0a 20 20 65 63  VtabCursor;.  ec
23c0: 68 6f 5f 76 74 61 62 20 2a 70 56 74 61 62 20 3d  ho_vtab *pVtab =
23d0: 20 28 65 63 68 6f 5f 76 74 61 62 20 2a 29 70 56   (echo_vtab *)pV
23e0: 74 61 62 43 75 72 73 6f 72 2d 3e 70 56 74 61 62  tabCursor->pVtab
23f0: 3b 0a 20 20 73 71 6c 69 74 65 33 20 2a 64 62 20  ;.  sqlite3 *db 
2400: 3d 20 70 56 74 61 62 2d 3e 64 62 3b 0a 0a 20 20  = pVtab->db;..  
2410: 61 73 73 65 72 74 28 20 69 64 78 4e 75 6d 3d 3d  assert( idxNum==
2420: 68 61 73 68 53 74 72 69 6e 67 28 69 64 78 53 74  hashString(idxSt
2430: 72 29 20 29 3b 0a 20 20 73 71 6c 69 74 65 33 5f  r) );.  sqlite3_
2440: 66 69 6e 61 6c 69 7a 65 28 70 43 75 72 2d 3e 70  finalize(pCur->p
2450: 53 74 6d 74 29 3b 0a 20 20 70 43 75 72 2d 3e 70  Stmt);.  pCur->p
2460: 53 74 6d 74 20 3d 20 30 3b 0a 20 20 72 63 20 3d  Stmt = 0;.  rc =
2470: 20 73 71 6c 69 74 65 33 5f 70 72 65 70 61 72 65   sqlite3_prepare
2480: 28 64 62 2c 20 69 64 78 53 74 72 2c 20 2d 31 2c  (db, idxStr, -1,
2490: 20 26 70 43 75 72 2d 3e 70 53 74 6d 74 2c 20 30   &pCur->pStmt, 0
24a0: 29 3b 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c  );.  for(i=0; i<
24b0: 61 72 67 63 3b 20 69 2b 2b 29 7b 0a 20 20 20 20  argc; i++){.    
24c0: 73 77 69 74 63 68 28 20 73 71 6c 69 74 65 33 5f  switch( sqlite3_
24d0: 76 61 6c 75 65 5f 74 79 70 65 28 61 72 67 76 5b  value_type(argv[
24e0: 69 5d 29 20 29 7b 0a 20 20 20 20 20 20 63 61 73  i]) ){.      cas
24f0: 65 20 53 51 4c 49 54 45 5f 49 4e 54 45 47 45 52  e SQLITE_INTEGER
2500: 3a 20 7b 0a 20 20 20 20 20 20 20 20 73 71 6c 69  : {.        sqli
2510: 74 65 33 5f 62 69 6e 64 5f 69 6e 74 36 34 28 70  te3_bind_int64(p
2520: 43 75 72 2d 3e 70 53 74 6d 74 2c 20 69 2b 31 2c  Cur->pStmt, i+1,
2530: 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 69   sqlite3_value_i
2540: 6e 74 36 34 28 61 72 67 76 5b 69 5d 29 29 3b 0a  nt64(argv[i]));.
2550: 20 20 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20          break;. 
2560: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 63 61 73       }.      cas
2570: 65 20 53 51 4c 49 54 45 5f 46 4c 4f 41 54 3a 20  e SQLITE_FLOAT: 
2580: 7b 0a 20 20 20 20 20 20 20 20 73 71 6c 69 74 65  {.        sqlite
2590: 33 5f 62 69 6e 64 5f 64 6f 75 62 6c 65 28 70 43  3_bind_double(pC
25a0: 75 72 2d 3e 70 53 74 6d 74 2c 20 69 2b 31 2c 20  ur->pStmt, i+1, 
25b0: 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 64 6f  sqlite3_value_do
25c0: 75 62 6c 65 28 61 72 67 76 5b 69 5d 29 29 3b 0a  uble(argv[i]));.
25d0: 20 20 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20          break;. 
25e0: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 63 61 73       }.      cas
25f0: 65 20 53 51 4c 49 54 45 5f 4e 55 4c 4c 3a 20 7b  e SQLITE_NULL: {
2600: 0a 20 20 20 20 20 20 20 20 73 71 6c 69 74 65 33  .        sqlite3
2610: 5f 62 69 6e 64 5f 6e 75 6c 6c 28 70 43 75 72 2d  _bind_null(pCur-
2620: 3e 70 53 74 6d 74 2c 20 69 2b 31 29 3b 0a 20 20  >pStmt, i+1);.  
2630: 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20        break;.   
2640: 20 20 20 7d 0a 20 20 20 20 20 20 63 61 73 65 20     }.      case 
2650: 53 51 4c 49 54 45 5f 54 45 58 54 3a 20 7b 0a 20  SQLITE_TEXT: {. 
2660: 20 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 62         sqlite3_b
2670: 69 6e 64 5f 74 65 78 74 28 70 43 75 72 2d 3e 70  ind_text(pCur->p
2680: 53 74 6d 74 2c 20 69 2b 31 2c 20 73 71 6c 69 74  Stmt, i+1, sqlit
2690: 65 33 5f 76 61 6c 75 65 5f 74 65 78 74 28 61 72  e3_value_text(ar
26a0: 67 76 5b 69 5d 29 2c 0a 20 20 20 20 20 20 20 20  gv[i]),.        
26b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
26c0: 20 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f    sqlite3_value_
26d0: 62 79 74 65 73 28 61 72 67 76 5b 69 5d 29 2c 20  bytes(argv[i]), 
26e0: 53 51 4c 49 54 45 5f 54 52 41 4e 53 49 45 4e 54  SQLITE_TRANSIENT
26f0: 29 3b 0a 20 20 20 20 20 20 20 20 62 72 65 61 6b  );.        break
2700: 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20  ;.      }.      
2710: 63 61 73 65 20 53 51 4c 49 54 45 5f 42 4c 4f 42  case SQLITE_BLOB
2720: 3a 20 7b 0a 20 20 20 20 20 20 20 20 73 71 6c 69  : {.        sqli
2730: 74 65 33 5f 62 69 6e 64 5f 62 6c 6f 62 28 70 43  te3_bind_blob(pC
2740: 75 72 2d 3e 70 53 74 6d 74 2c 20 69 2b 31 2c 20  ur->pStmt, i+1, 
2750: 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 62 6c  sqlite3_value_bl
2760: 6f 62 28 61 72 67 76 5b 69 5d 29 2c 0a 20 20 20  ob(argv[i]),.   
2770: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2780: 20 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 76         sqlite3_v
2790: 61 6c 75 65 5f 62 79 74 65 73 28 61 72 67 76 5b  alue_bytes(argv[
27a0: 69 5d 29 2c 20 53 51 4c 49 54 45 5f 54 52 41 4e  i]), SQLITE_TRAN
27b0: 53 49 45 4e 54 29 3b 0a 20 20 20 20 20 20 20 20  SIENT);.        
27c0: 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 7d 0a 20  break;.      }. 
27d0: 20 20 20 7d 0a 20 20 7d 0a 20 20 69 66 28 20 72     }.  }.  if( r
27e0: 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a  c==SQLITE_OK ){.
27f0: 20 20 20 20 72 63 20 3d 20 65 63 68 6f 4e 65 78      rc = echoNex
2800: 74 28 70 56 74 61 62 43 75 72 73 6f 72 29 3b 0a  t(pVtabCursor);.
2810: 20 20 7d 0a 0a 20 20 61 70 70 65 6e 64 54 6f 45    }..  appendToE
2820: 63 68 6f 4d 6f 64 75 6c 65 28 70 56 74 61 62 2d  choModule(pVtab-
2830: 3e 69 6e 74 65 72 70 2c 20 22 78 46 69 6c 74 65  >interp, "xFilte
2840: 72 22 29 3b 0a 20 20 61 70 70 65 6e 64 54 6f 45  r");.  appendToE
2850: 63 68 6f 4d 6f 64 75 6c 65 28 70 56 74 61 62 2d  choModule(pVtab-
2860: 3e 69 6e 74 65 72 70 2c 20 69 64 78 53 74 72 29  >interp, idxStr)
2870: 3b 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 61  ;.  for(i=0; i<a
2880: 72 67 63 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 61  rgc; i++){.    a
2890: 70 70 65 6e 64 54 6f 45 63 68 6f 4d 6f 64 75 6c  ppendToEchoModul
28a0: 65 28 70 56 74 61 62 2d 3e 69 6e 74 65 72 70 2c  e(pVtab->interp,
28b0: 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 74   sqlite3_value_t
28c0: 65 78 74 28 61 72 67 76 5b 69 5d 29 29 3b 0a 20  ext(argv[i]));. 
28d0: 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b   }..  return rc;
28e0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 65 20 65 63  .}../*.** The ec
28f0: 68 6f 20 6d 6f 64 75 6c 65 20 69 6d 70 6c 65 6d  ho module implem
2900: 65 6e 74 73 20 74 68 65 20 73 75 62 73 65 74 20  ents the subset 
2910: 6f 66 20 71 75 65 72 79 20 63 6f 6e 73 74 72 61  of query constra
2920: 69 6e 74 73 20 61 6e 64 20 73 6f 72 74 0a 2a 2a  ints and sort.**
2930: 20 6f 72 64 65 72 73 20 74 68 61 74 20 6d 61 79   orders that may
2940: 20 74 61 6b 65 20 61 64 76 61 6e 74 61 67 65 20   take advantage 
2950: 6f 66 20 53 51 4c 69 74 65 20 69 6e 64 69 63 65  of SQLite indice
2960: 73 20 6f 6e 20 74 68 65 20 75 6e 64 65 72 6c 79  s on the underly
2970: 69 6e 67 0a 2a 2a 20 72 65 61 6c 20 74 61 62 6c  ing.** real tabl
2980: 65 2e 20 46 6f 72 20 65 78 61 6d 70 6c 65 2c 20  e. For example, 
2990: 69 66 20 74 68 65 20 72 65 61 6c 20 74 61 62 6c  if the real tabl
29a0: 65 20 69 73 20 64 65 63 6c 61 72 65 64 20 61 73  e is declared as
29b0: 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20 43 52 45 41  :.**.**     CREA
29c0: 54 45 20 54 41 42 4c 45 20 72 65 61 6c 28 61 2c  TE TABLE real(a,
29d0: 20 62 2c 20 63 29 3b 0a 2a 2a 20 20 20 20 20 43   b, c);.**     C
29e0: 52 45 41 54 45 20 49 4e 44 45 58 20 72 65 61 6c  REATE INDEX real
29f0: 5f 69 6e 64 65 78 20 4f 4e 20 72 65 61 6c 28 62  _index ON real(b
2a00: 29 3b 0a 2a 2a 0a 2a 2a 20 74 68 65 6e 20 74 68  );.**.** then th
2a10: 65 20 65 63 68 6f 20 6d 6f 64 75 6c 65 20 68 61  e echo module ha
2a20: 6e 64 6c 65 73 20 57 48 45 52 45 20 6f 72 20 4f  ndles WHERE or O
2a30: 52 44 45 52 20 42 59 20 63 6c 61 75 73 65 73 20  RDER BY clauses 
2a40: 74 68 61 74 20 72 65 66 65 72 0a 2a 2a 20 74 6f  that refer.** to
2a50: 20 74 68 65 20 63 6f 6c 75 6d 6e 20 22 62 22 2c   the column "b",
2a60: 20 62 75 74 20 6e 6f 74 20 22 61 22 20 6f 72 20   but not "a" or 
2a70: 22 63 22 2e 20 49 66 20 61 20 6d 75 6c 74 69 2d  "c". If a multi-
2a80: 63 6f 6c 75 6d 6e 20 69 6e 64 65 78 20 69 73 0a  column index is.
2a90: 2a 2a 20 70 72 65 73 65 6e 74 2c 20 6f 6e 6c 79  ** present, only
2aa0: 20 69 74 27 73 20 6c 65 66 74 20 6d 6f 73 74 20   it's left most 
2ab0: 63 6f 6c 75 6d 6e 20 69 73 20 63 6f 6e 73 69 64  column is consid
2ac0: 65 72 65 64 2e 20 0a 2a 2f 0a 73 74 61 74 69 63  ered. .*/.static
2ad0: 20 69 6e 74 20 65 63 68 6f 42 65 73 74 49 6e 64   int echoBestInd
2ae0: 65 78 28 73 71 6c 69 74 65 33 5f 76 74 61 62 20  ex(sqlite3_vtab 
2af0: 2a 74 61 62 2c 20 73 71 6c 69 74 65 33 5f 69 6e  *tab, sqlite3_in
2b00: 64 65 78 5f 69 6e 66 6f 20 2a 70 49 64 78 49 6e  dex_info *pIdxIn
2b10: 66 6f 29 7b 0a 20 20 69 6e 74 20 69 69 3b 0a 20  fo){.  int ii;. 
2b20: 20 63 68 61 72 20 2a 7a 51 75 65 72 79 20 3d 20   char *zQuery = 
2b30: 30 3b 0a 20 20 63 68 61 72 20 2a 7a 4e 65 77 3b  0;.  char *zNew;
2b40: 0a 20 20 69 6e 74 20 6e 41 72 67 20 3d 20 30 3b  .  int nArg = 0;
2b50: 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a  .  const char *z
2b60: 53 65 70 20 3d 20 22 57 48 45 52 45 22 3b 0a 20  Sep = "WHERE";. 
2b70: 20 65 63 68 6f 5f 76 74 61 62 20 2a 70 56 74 61   echo_vtab *pVta
2b80: 62 20 3d 20 28 65 63 68 6f 5f 76 74 61 62 20 2a  b = (echo_vtab *
2b90: 29 74 61 62 3b 0a 0a 20 20 7a 51 75 65 72 79 20  )tab;..  zQuery 
2ba0: 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74  = sqlite3_mprint
2bb0: 66 28 22 53 45 4c 45 43 54 20 72 6f 77 69 64 2c  f("SELECT rowid,
2bc0: 20 2a 20 46 52 4f 4d 20 25 51 22 2c 20 70 56 74   * FROM %Q", pVt
2bd0: 61 62 2d 3e 7a 54 61 62 6c 65 4e 61 6d 65 29 3b  ab->zTableName);
2be0: 0a 20 20 66 6f 72 28 69 69 3d 30 3b 20 69 69 3c  .  for(ii=0; ii<
2bf0: 70 49 64 78 49 6e 66 6f 2d 3e 6e 43 6f 6e 73 74  pIdxInfo->nConst
2c00: 72 61 69 6e 74 3b 20 69 69 2b 2b 29 7b 0a 20 20  raint; ii++){.  
2c10: 20 20 63 6f 6e 73 74 20 73 74 72 75 63 74 20 73    const struct s
2c20: 71 6c 69 74 65 33 5f 69 6e 64 65 78 5f 63 6f 6e  qlite3_index_con
2c30: 73 74 72 61 69 6e 74 20 2a 70 43 6f 6e 73 74 72  straint *pConstr
2c40: 61 69 6e 74 3b 0a 20 20 20 20 73 74 72 75 63 74  aint;.    struct
2c50: 20 73 71 6c 69 74 65 33 5f 69 6e 64 65 78 5f 63   sqlite3_index_c
2c60: 6f 6e 73 74 72 61 69 6e 74 5f 75 73 61 67 65 20  onstraint_usage 
2c70: 2a 70 55 73 61 67 65 3b 0a 0a 20 20 20 20 70 43  *pUsage;..    pC
2c80: 6f 6e 73 74 72 61 69 6e 74 20 3d 20 26 70 49 64  onstraint = &pId
2c90: 78 49 6e 66 6f 2d 3e 61 43 6f 6e 73 74 72 61 69  xInfo->aConstrai
2ca0: 6e 74 5b 69 69 5d 3b 0a 20 20 20 20 70 55 73 61  nt[ii];.    pUsa
2cb0: 67 65 20 3d 20 26 70 49 64 78 49 6e 66 6f 2d 3e  ge = &pIdxInfo->
2cc0: 61 43 6f 6e 73 74 72 61 69 6e 74 55 73 61 67 65  aConstraintUsage
2cd0: 5b 69 69 5d 3b 0a 0a 20 20 20 20 69 6e 74 20 69  [ii];..    int i
2ce0: 43 6f 6c 20 3d 20 70 43 6f 6e 73 74 72 61 69 6e  Col = pConstrain
2cf0: 74 2d 3e 69 43 6f 6c 75 6d 6e 3b 0a 20 20 20 20  t->iColumn;.    
2d00: 69 66 28 20 70 56 74 61 62 2d 3e 61 49 6e 64 65  if( pVtab->aInde
2d10: 78 5b 69 43 6f 6c 5d 20 29 7b 0a 20 20 20 20 20  x[iCol] ){.     
2d20: 20 63 68 61 72 20 2a 7a 43 6f 6c 20 3d 20 70 56   char *zCol = pV
2d30: 74 61 62 2d 3e 61 43 6f 6c 5b 69 43 6f 6c 5d 3b  tab->aCol[iCol];
2d40: 0a 20 20 20 20 20 20 63 68 61 72 20 2a 7a 4f 70  .      char *zOp
2d50: 20 3d 20 30 3b 0a 20 20 20 20 20 20 69 66 28 20   = 0;.      if( 
2d60: 69 43 6f 6c 3c 30 20 29 7b 0a 20 20 20 20 20 20  iCol<0 ){.      
2d70: 20 20 7a 43 6f 6c 20 3d 20 22 72 6f 77 69 64 22    zCol = "rowid"
2d80: 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20  ;.      }.      
2d90: 73 77 69 74 63 68 28 20 70 43 6f 6e 73 74 72 61  switch( pConstra
2da0: 69 6e 74 2d 3e 6f 70 20 29 7b 0a 20 20 20 20 20  int->op ){.     
2db0: 20 20 20 63 61 73 65 20 53 51 4c 49 54 45 5f 49     case SQLITE_I
2dc0: 4e 44 45 58 5f 43 4f 4e 53 54 52 41 49 4e 54 5f  NDEX_CONSTRAINT_
2dd0: 45 51 3a 0a 20 20 20 20 20 20 20 20 20 20 7a 4f  EQ:.          zO
2de0: 70 20 3d 20 22 3d 22 3b 20 62 72 65 61 6b 3b 0a  p = "="; break;.
2df0: 20 20 20 20 20 20 20 20 63 61 73 65 20 53 51 4c          case SQL
2e00: 49 54 45 5f 49 4e 44 45 58 5f 43 4f 4e 53 54 52  ITE_INDEX_CONSTR
2e10: 41 49 4e 54 5f 4c 54 3a 0a 20 20 20 20 20 20 20  AINT_LT:.       
2e20: 20 20 20 7a 4f 70 20 3d 20 22 3c 22 3b 20 62 72     zOp = "<"; br
2e30: 65 61 6b 3b 0a 20 20 20 20 20 20 20 20 63 61 73  eak;.        cas
2e40: 65 20 53 51 4c 49 54 45 5f 49 4e 44 45 58 5f 43  e SQLITE_INDEX_C
2e50: 4f 4e 53 54 52 41 49 4e 54 5f 47 54 3a 0a 20 20  ONSTRAINT_GT:.  
2e60: 20 20 20 20 20 20 20 20 7a 4f 70 20 3d 20 22 3e          zOp = ">
2e70: 22 3b 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20  "; break;.      
2e80: 20 20 63 61 73 65 20 53 51 4c 49 54 45 5f 49 4e    case SQLITE_IN
2e90: 44 45 58 5f 43 4f 4e 53 54 52 41 49 4e 54 5f 4c  DEX_CONSTRAINT_L
2ea0: 45 3a 0a 20 20 20 20 20 20 20 20 20 20 7a 4f 70  E:.          zOp
2eb0: 20 3d 20 22 3c 3d 22 3b 20 62 72 65 61 6b 3b 0a   = "<="; break;.
2ec0: 20 20 20 20 20 20 20 20 63 61 73 65 20 53 51 4c          case SQL
2ed0: 49 54 45 5f 49 4e 44 45 58 5f 43 4f 4e 53 54 52  ITE_INDEX_CONSTR
2ee0: 41 49 4e 54 5f 47 45 3a 0a 20 20 20 20 20 20 20  AINT_GE:.       
2ef0: 20 20 20 7a 4f 70 20 3d 20 22 3e 3d 22 3b 20 62     zOp = ">="; b
2f00: 72 65 61 6b 3b 0a 20 20 20 20 20 20 20 20 63 61  reak;.        ca
2f10: 73 65 20 53 51 4c 49 54 45 5f 49 4e 44 45 58 5f  se SQLITE_INDEX_
2f20: 43 4f 4e 53 54 52 41 49 4e 54 5f 4d 41 54 43 48  CONSTRAINT_MATCH
2f30: 3a 0a 20 20 20 20 20 20 20 20 20 20 7a 4f 70 20  :.          zOp 
2f40: 3d 20 22 4c 49 4b 45 22 3b 20 62 72 65 61 6b 3b  = "LIKE"; break;
2f50: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 69  .      }.      i
2f60: 66 28 20 7a 4f 70 5b 30 5d 3d 3d 27 4c 27 20 29  f( zOp[0]=='L' )
2f70: 7b 0a 20 20 20 20 20 20 20 20 7a 4e 65 77 20 3d  {.        zNew =
2f80: 20 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66   sqlite3_mprintf
2f90: 28 22 25 73 20 25 73 20 25 73 20 4c 49 4b 45 20  ("%s %s %s LIKE 
2fa0: 28 53 45 4c 45 43 54 20 27 25 25 27 7c 7c 3f 7c  (SELECT '%%'||?|
2fb0: 7c 27 25 25 27 29 22 2c 20 0a 20 20 20 20 20 20  |'%%')", .      
2fc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2fd0: 20 20 20 20 20 20 20 20 20 7a 51 75 65 72 79 2c           zQuery,
2fe0: 20 7a 53 65 70 2c 20 7a 43 6f 6c 29 3b 0a 20 20   zSep, zCol);.  
2ff0: 20 20 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20      } else {.   
3000: 20 20 20 20 20 7a 4e 65 77 20 3d 20 73 71 6c 69       zNew = sqli
3010: 74 65 33 5f 6d 70 72 69 6e 74 66 28 22 25 73 20  te3_mprintf("%s 
3020: 25 73 20 25 73 20 25 73 20 3f 22 2c 20 7a 51 75  %s %s %s ?", zQu
3030: 65 72 79 2c 20 7a 53 65 70 2c 20 7a 43 6f 6c 2c  ery, zSep, zCol,
3040: 20 7a 4f 70 29 3b 0a 20 20 20 20 20 20 7d 0a 20   zOp);.      }. 
3050: 20 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65       sqlite3_fre
3060: 65 28 7a 51 75 65 72 79 29 3b 0a 20 20 20 20 20  e(zQuery);.     
3070: 20 7a 51 75 65 72 79 20 3d 20 7a 4e 65 77 3b 0a   zQuery = zNew;.
3080: 20 20 20 20 20 20 7a 53 65 70 20 3d 20 22 41 4e        zSep = "AN
3090: 44 22 3b 0a 20 20 20 20 20 20 70 55 73 61 67 65  D";.      pUsage
30a0: 2d 3e 61 72 67 76 49 6e 64 65 78 20 3d 20 2b 2b  ->argvIndex = ++
30b0: 6e 41 72 67 3b 0a 20 20 20 20 20 20 70 55 73 61  nArg;.      pUsa
30c0: 67 65 2d 3e 6f 6d 69 74 20 3d 20 31 3b 0a 20 20  ge->omit = 1;.  
30d0: 20 20 7d 0a 20 20 7d 0a 0a 20 20 2f 2a 20 49 66    }.  }..  /* If
30e0: 20 74 68 65 72 65 20 69 73 20 6f 6e 6c 79 20 6f   there is only o
30f0: 6e 65 20 74 65 72 6d 20 69 6e 20 74 68 65 20 4f  ne term in the O
3100: 52 44 45 52 20 42 59 20 63 6c 61 75 73 65 2c 20  RDER BY clause, 
3110: 61 6e 64 20 69 74 20 69 73 0a 20 20 2a 2a 20 6f  and it is.  ** o
3120: 6e 20 61 20 63 6f 6c 75 6d 6e 20 74 68 61 74 20  n a column that 
3130: 74 68 69 73 20 76 69 72 74 75 61 6c 20 74 61 62  this virtual tab
3140: 6c 65 20 68 61 73 20 61 6e 20 69 6e 64 65 78 20  le has an index 
3150: 66 6f 72 2c 20 74 68 65 6e 20 63 6f 6e 73 75 6d  for, then consum
3160: 65 20 0a 20 20 2a 2a 20 74 68 65 20 4f 52 44 45  e .  ** the ORDE
3170: 52 20 42 59 20 63 6c 61 75 73 65 2e 0a 20 20 2a  R BY clause..  *
3180: 2f 0a 20 20 69 66 28 20 70 49 64 78 49 6e 66 6f  /.  if( pIdxInfo
3190: 2d 3e 6e 4f 72 64 65 72 42 79 3d 3d 31 20 26 26  ->nOrderBy==1 &&
31a0: 20 70 56 74 61 62 2d 3e 61 49 6e 64 65 78 5b 70   pVtab->aIndex[p
31b0: 49 64 78 49 6e 66 6f 2d 3e 61 4f 72 64 65 72 42  IdxInfo->aOrderB
31c0: 79 2d 3e 69 43 6f 6c 75 6d 6e 5d 20 29 7b 0a 20  y->iColumn] ){. 
31d0: 20 20 20 63 68 61 72 20 2a 7a 43 6f 6c 20 3d 20     char *zCol = 
31e0: 70 56 74 61 62 2d 3e 61 43 6f 6c 5b 70 49 64 78  pVtab->aCol[pIdx
31f0: 49 6e 66 6f 2d 3e 61 4f 72 64 65 72 42 79 2d 3e  Info->aOrderBy->
3200: 69 43 6f 6c 75 6d 6e 5d 3b 0a 20 20 20 20 63 68  iColumn];.    ch
3210: 61 72 20 2a 7a 44 69 72 20 3d 20 70 49 64 78 49  ar *zDir = pIdxI
3220: 6e 66 6f 2d 3e 61 4f 72 64 65 72 42 79 2d 3e 64  nfo->aOrderBy->d
3230: 65 73 63 3f 22 44 45 53 43 22 3a 22 41 53 43 22  esc?"DESC":"ASC"
3240: 3b 0a 20 20 20 20 7a 4e 65 77 20 3d 20 73 71 6c  ;.    zNew = sql
3250: 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 22 25 73  ite3_mprintf("%s
3260: 20 4f 52 44 45 52 20 42 59 20 25 73 20 25 73 22   ORDER BY %s %s"
3270: 2c 20 7a 51 75 65 72 79 2c 20 7a 43 6f 6c 2c 20  , zQuery, zCol, 
3280: 7a 44 69 72 29 3b 0a 20 20 20 20 73 71 6c 69 74  zDir);.    sqlit
3290: 65 33 5f 66 72 65 65 28 7a 51 75 65 72 79 29 3b  e3_free(zQuery);
32a0: 0a 20 20 20 20 7a 51 75 65 72 79 20 3d 20 7a 4e  .    zQuery = zN
32b0: 65 77 3b 0a 20 20 20 20 70 49 64 78 49 6e 66 6f  ew;.    pIdxInfo
32c0: 2d 3e 6f 72 64 65 72 42 79 43 6f 6e 73 75 6d 65  ->orderByConsume
32d0: 64 20 3d 20 31 3b 0a 20 20 7d 0a 0a 20 20 61 70  d = 1;.  }..  ap
32e0: 70 65 6e 64 54 6f 45 63 68 6f 4d 6f 64 75 6c 65  pendToEchoModule
32f0: 28 70 56 74 61 62 2d 3e 69 6e 74 65 72 70 2c 20  (pVtab->interp, 
3300: 22 78 42 65 73 74 49 6e 64 65 78 22 29 3b 3b 0a  "xBestIndex");;.
3310: 20 20 61 70 70 65 6e 64 54 6f 45 63 68 6f 4d 6f    appendToEchoMo
3320: 64 75 6c 65 28 70 56 74 61 62 2d 3e 69 6e 74 65  dule(pVtab->inte
3330: 72 70 2c 20 7a 51 75 65 72 79 29 3b 0a 0a 20 20  rp, zQuery);..  
3340: 70 49 64 78 49 6e 66 6f 2d 3e 69 64 78 4e 75 6d  pIdxInfo->idxNum
3350: 20 3d 20 68 61 73 68 53 74 72 69 6e 67 28 7a 51   = hashString(zQ
3360: 75 65 72 79 29 3b 0a 20 20 70 49 64 78 49 6e 66  uery);.  pIdxInf
3370: 6f 2d 3e 69 64 78 53 74 72 20 3d 20 7a 51 75 65  o->idxStr = zQue
3380: 72 79 3b 0a 20 20 70 49 64 78 49 6e 66 6f 2d 3e  ry;.  pIdxInfo->
3390: 6e 65 65 64 54 6f 46 72 65 65 49 64 78 53 74 72  needToFreeIdxStr
33a0: 20 3d 20 31 3b 0a 20 20 70 49 64 78 49 6e 66 6f   = 1;.  pIdxInfo
33b0: 2d 3e 65 73 74 69 6d 61 74 65 64 43 6f 73 74 20  ->estimatedCost 
33c0: 3d 20 31 2e 30 3b 0a 20 20 72 65 74 75 72 6e 20  = 1.0;.  return 
33d0: 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 73 74  SQLITE_OK;.}..st
33e0: 61 74 69 63 20 76 6f 69 64 20 73 74 72 69 6e 67  atic void string
33f0: 5f 63 6f 6e 63 61 74 28 63 68 61 72 20 2a 2a 70  _concat(char **p
3400: 7a 53 74 72 2c 20 63 68 61 72 20 2a 7a 41 70 70  zStr, char *zApp
3410: 65 6e 64 2c 20 69 6e 74 20 64 6f 46 72 65 65 29  end, int doFree)
3420: 7b 0a 20 20 63 68 61 72 20 2a 7a 49 6e 20 3d 20  {.  char *zIn = 
3430: 2a 70 7a 53 74 72 3b 0a 20 20 69 66 28 20 7a 49  *pzStr;.  if( zI
3440: 6e 20 29 7b 0a 20 20 20 20 63 68 61 72 20 2a 7a  n ){.    char *z
3450: 54 65 6d 70 20 3d 20 7a 49 6e 3b 0a 20 20 20 20  Temp = zIn;.    
3460: 7a 49 6e 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70  zIn = sqlite3_mp
3470: 72 69 6e 74 66 28 22 25 73 25 73 22 2c 20 7a 49  rintf("%s%s", zI
3480: 6e 2c 20 7a 41 70 70 65 6e 64 29 3b 0a 20 20 20  n, zAppend);.   
3490: 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 7a 54   sqlite3_free(zT
34a0: 65 6d 70 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20  emp);.  }else{. 
34b0: 20 20 20 7a 49 6e 20 3d 20 73 71 6c 69 74 65 33     zIn = sqlite3
34c0: 5f 6d 70 72 69 6e 74 66 28 22 25 73 22 2c 20 7a  _mprintf("%s", z
34d0: 41 70 70 65 6e 64 29 3b 0a 20 20 7d 0a 20 20 2a  Append);.  }.  *
34e0: 70 7a 53 74 72 20 3d 20 7a 49 6e 3b 0a 20 20 69  pzStr = zIn;.  i
34f0: 66 28 20 64 6f 46 72 65 65 20 29 7b 0a 20 20 20  f( doFree ){.   
3500: 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 7a 41   sqlite3_free(zA
3510: 70 70 65 6e 64 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f  ppend);.  }.}../
3520: 2a 0a 2a 2a 20 20 20 20 61 70 44 61 74 61 5b 30  *.**    apData[0
3530: 5d 20 20 61 70 44 61 74 61 5b 31 5d 20 20 61 70  ]  apData[1]  ap
3540: 44 61 74 61 5b 32 2e 2e 5d 0a 2a 2a 0a 2a 2a 20  Data[2..].**.** 
3550: 20 20 20 49 4e 54 45 47 45 52 20 20 20 20 20 20     INTEGER      
3560: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3570: 20 20 20 20 20 20 20 20 44 45 4c 45 54 45 20 20          DELETE  
3580: 20 20 20 20 20 20 20 20 20 20 0a 2a 2a 0a 2a 2a            .**.**
3590: 20 20 20 20 49 4e 54 45 47 45 52 20 20 20 20 4e      INTEGER    N
35a0: 55 4c 4c 20 20 20 20 20 20 20 28 6e 43 6f 6c 20  ULL       (nCol 
35b0: 61 72 67 73 29 20 20 20 20 55 50 44 41 54 45 20  args)    UPDATE 
35c0: 28 64 6f 20 6e 6f 74 20 73 65 74 20 72 6f 77 69  (do not set rowi
35d0: 64 29 0a 2a 2a 20 20 20 20 49 4e 54 45 47 45 52  d).**    INTEGER
35e0: 20 20 20 20 49 4e 54 45 47 45 52 20 20 20 20 28      INTEGER    (
35f0: 6e 43 6f 6c 20 61 72 67 73 29 20 20 20 20 55 50  nCol args)    UP
3600: 44 41 54 45 20 28 77 69 74 68 20 53 45 54 20 72  DATE (with SET r
3610: 6f 77 69 64 20 3d 20 3c 61 72 67 31 3e 29 0a 2a  owid = <arg1>).*
3620: 2a 0a 2a 2a 20 20 20 20 4e 55 4c 4c 20 20 20 20  *.**    NULL    
3630: 20 20 20 4e 55 4c 4c 20 20 20 20 20 20 20 28 6e     NULL       (n
3640: 43 6f 6c 20 61 72 67 73 29 20 20 20 20 49 4e 53  Col args)    INS
3650: 45 52 54 20 49 4e 54 4f 20 28 61 75 74 6f 6d 61  ERT INTO (automa
3660: 74 69 63 20 72 6f 77 69 64 20 76 61 6c 75 65 29  tic rowid value)
3670: 0a 2a 2a 20 20 20 20 4e 55 4c 4c 20 20 20 20 20  .**    NULL     
3680: 20 20 49 4e 54 45 47 45 52 20 20 20 20 28 6e 43    INTEGER    (nC
3690: 6f 6c 20 61 72 67 73 29 20 20 20 20 49 4e 53 45  ol args)    INSE
36a0: 52 54 20 28 69 6e 63 6c 2e 20 72 6f 77 69 64 20  RT (incl. rowid 
36b0: 76 61 6c 75 65 29 0a 2a 2a 0a 2a 2f 0a 69 6e 74  value).**.*/.int
36c0: 20 65 63 68 6f 55 70 64 61 74 65 28 0a 20 20 73   echoUpdate(.  s
36d0: 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 74 61 62  qlite3_vtab *tab
36e0: 2c 20 0a 20 20 69 6e 74 20 6e 44 61 74 61 2c 20  , .  int nData, 
36f0: 0a 20 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65  .  sqlite3_value
3700: 20 2a 2a 61 70 44 61 74 61 2c 20 0a 20 20 73 71   **apData, .  sq
3710: 6c 69 74 65 5f 69 6e 74 36 34 20 2a 70 52 6f 77  lite_int64 *pRow
3720: 69 64 0a 29 7b 0a 20 20 65 63 68 6f 5f 76 74 61  id.){.  echo_vta
3730: 62 20 2a 70 56 74 61 62 20 3d 20 28 65 63 68 6f  b *pVtab = (echo
3740: 5f 76 74 61 62 20 2a 29 74 61 62 3b 0a 20 20 73  _vtab *)tab;.  s
3750: 71 6c 69 74 65 33 20 2a 64 62 20 3d 20 70 56 74  qlite3 *db = pVt
3760: 61 62 2d 3e 64 62 3b 0a 20 20 69 6e 74 20 72 63  ab->db;.  int rc
3770: 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 0a 20   = SQLITE_OK;.. 
3780: 20 73 71 6c 69 74 65 33 5f 73 74 6d 74 20 2a 70   sqlite3_stmt *p
3790: 53 74 6d 74 3b 0a 20 20 63 68 61 72 20 2a 7a 20  Stmt;.  char *z 
37a0: 3d 20 30 3b 20 20 20 20 20 20 20 20 20 20 20 20  = 0;            
37b0: 20 20 20 2f 2a 20 53 51 4c 20 73 74 61 74 65 6d     /* SQL statem
37c0: 65 6e 74 20 74 6f 20 65 78 65 63 75 74 65 20 2a  ent to execute *
37d0: 2f 0a 20 20 69 6e 74 20 62 69 6e 64 41 72 67 5a  /.  int bindArgZ
37e0: 65 72 6f 20 3d 20 30 3b 20 20 20 20 20 20 20 2f  ero = 0;       /
37f0: 2a 20 54 72 75 65 20 74 6f 20 62 69 6e 64 20 61  * True to bind a
3800: 70 44 61 74 61 5b 30 5d 20 74 6f 20 73 71 6c 20  pData[0] to sql 
3810: 76 61 72 20 6e 6f 2e 20 6e 44 61 74 61 20 2a 2f  var no. nData */
3820: 0a 20 20 69 6e 74 20 62 69 6e 64 41 72 67 4f 6e  .  int bindArgOn
3830: 65 20 3d 20 30 3b 20 20 20 20 20 20 20 20 2f 2a  e = 0;        /*
3840: 20 54 72 75 65 20 74 6f 20 62 69 6e 64 20 61 70   True to bind ap
3850: 44 61 74 61 5b 31 5d 20 74 6f 20 73 71 6c 20 76  Data[1] to sql v
3860: 61 72 20 6e 6f 2e 20 31 20 2a 2f 0a 20 20 69 6e  ar no. 1 */.  in
3870: 74 20 69 3b 20 20 20 20 20 20 20 20 20 20 20 20  t i;            
3880: 20 20 20 20 20 20 20 20 20 2f 2a 20 43 6f 75 6e           /* Coun
3890: 74 65 72 20 76 61 72 69 61 62 6c 65 20 75 73 65  ter variable use
38a0: 64 20 62 79 20 66 6f 72 20 6c 6f 6f 70 73 20 2a  d by for loops *
38b0: 2f 0a 0a 20 20 61 73 73 65 72 74 28 20 6e 44 61  /..  assert( nDa
38c0: 74 61 3d 3d 70 56 74 61 62 2d 3e 6e 43 6f 6c 2b  ta==pVtab->nCol+
38d0: 32 20 7c 7c 20 6e 44 61 74 61 3d 3d 31 20 29 3b  2 || nData==1 );
38e0: 0a 0a 20 20 2f 2a 20 49 66 20 61 70 44 61 74 61  ..  /* If apData
38f0: 5b 30 5d 20 69 73 20 61 6e 20 69 6e 74 65 67 65  [0] is an intege
3900: 72 20 61 6e 64 20 6e 44 61 74 61 3e 31 20 74 68  r and nData>1 th
3910: 65 6e 20 64 6f 20 61 6e 20 55 50 44 41 54 45 20  en do an UPDATE 
3920: 2a 2f 0a 20 20 69 66 28 20 6e 44 61 74 61 3e 31  */.  if( nData>1
3930: 20 26 26 20 73 71 6c 69 74 65 33 5f 76 61 6c 75   && sqlite3_valu
3940: 65 5f 74 79 70 65 28 61 70 44 61 74 61 5b 30 5d  e_type(apData[0]
3950: 29 3d 3d 53 51 4c 49 54 45 5f 49 4e 54 45 47 45  )==SQLITE_INTEGE
3960: 52 20 29 7b 0a 20 20 20 20 7a 20 3d 20 73 71 6c  R ){.    z = sql
3970: 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 22 55 50  ite3_mprintf("UP
3980: 44 41 54 45 20 25 51 22 2c 20 70 56 74 61 62 2d  DATE %Q", pVtab-
3990: 3e 7a 54 61 62 6c 65 4e 61 6d 65 29 3b 0a 20 20  >zTableName);.  
39a0: 20 20 63 68 61 72 20 2a 7a 53 65 70 20 3d 20 22    char *zSep = "
39b0: 20 53 45 54 22 3b 0a 0a 20 20 20 20 62 69 6e 64   SET";..    bind
39c0: 41 72 67 4f 6e 65 20 3d 20 28 61 70 44 61 74 61  ArgOne = (apData
39d0: 5b 31 5d 20 26 26 20 73 71 6c 69 74 65 33 5f 76  [1] && sqlite3_v
39e0: 61 6c 75 65 5f 74 79 70 65 28 61 70 44 61 74 61  alue_type(apData
39f0: 5b 31 5d 29 3d 3d 53 51 4c 49 54 45 5f 49 4e 54  [1])==SQLITE_INT
3a00: 45 47 45 52 29 3b 0a 20 20 20 20 62 69 6e 64 41  EGER);.    bindA
3a10: 72 67 5a 65 72 6f 20 3d 20 31 3b 0a 0a 20 20 20  rgZero = 1;..   
3a20: 20 69 66 28 20 62 69 6e 64 41 72 67 4f 6e 65 20   if( bindArgOne 
3a30: 29 7b 0a 20 20 20 20 20 20 20 73 74 72 69 6e 67  ){.       string
3a40: 5f 63 6f 6e 63 61 74 28 26 7a 2c 20 22 20 53 45  _concat(&z, " SE
3a50: 54 20 72 6f 77 69 64 3d 3f 31 20 22 2c 20 30 29  T rowid=?1 ", 0)
3a60: 3b 0a 20 20 20 20 20 20 20 7a 53 65 70 20 3d 20  ;.       zSep = 
3a70: 22 2c 22 3b 0a 20 20 20 20 7d 0a 20 20 20 20 66  ",";.    }.    f
3a80: 6f 72 28 69 3d 32 3b 20 69 3c 6e 44 61 74 61 3b  or(i=2; i<nData;
3a90: 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20 69 66 28   i++){.      if(
3aa0: 20 61 70 44 61 74 61 5b 69 5d 3d 3d 30 20 29 20   apData[i]==0 ) 
3ab0: 63 6f 6e 74 69 6e 75 65 3b 0a 20 20 20 20 20 20  continue;.      
3ac0: 73 74 72 69 6e 67 5f 63 6f 6e 63 61 74 28 26 7a  string_concat(&z
3ad0: 2c 20 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74  , sqlite3_mprint
3ae0: 66 28 0a 20 20 20 20 20 20 20 20 20 20 22 25 73  f(.          "%s
3af0: 20 25 51 3d 3f 25 64 22 2c 20 7a 53 65 70 2c 20   %Q=?%d", zSep, 
3b00: 70 56 74 61 62 2d 3e 61 43 6f 6c 5b 69 2d 32 5d  pVtab->aCol[i-2]
3b10: 2c 20 69 29 2c 20 31 29 3b 0a 20 20 20 20 20 20  , i), 1);.      
3b20: 7a 53 65 70 20 3d 20 22 2c 22 3b 0a 20 20 20 20  zSep = ",";.    
3b30: 7d 0a 20 20 20 20 73 74 72 69 6e 67 5f 63 6f 6e  }.    string_con
3b40: 63 61 74 28 26 7a 2c 20 73 71 6c 69 74 65 33 5f  cat(&z, sqlite3_
3b50: 6d 70 72 69 6e 74 66 28 22 20 57 48 45 52 45 20  mprintf(" WHERE 
3b60: 72 6f 77 69 64 3d 3f 25 64 22 2c 20 6e 44 61 74  rowid=?%d", nDat
3b70: 61 29 2c 20 30 29 3b 0a 20 20 7d 0a 0a 20 20 2f  a), 0);.  }..  /
3b80: 2a 20 49 66 20 61 70 44 61 74 61 5b 30 5d 20 69  * If apData[0] i
3b90: 73 20 61 6e 20 69 6e 74 65 67 65 72 20 61 6e 64  s an integer and
3ba0: 20 6e 44 61 74 61 3d 3d 31 20 74 68 65 6e 20 64   nData==1 then d
3bb0: 6f 20 61 20 44 45 4c 45 54 45 20 2a 2f 0a 20 20  o a DELETE */.  
3bc0: 65 6c 73 65 20 69 66 28 20 6e 44 61 74 61 3d 3d  else if( nData==
3bd0: 31 20 26 26 20 73 71 6c 69 74 65 33 5f 76 61 6c  1 && sqlite3_val
3be0: 75 65 5f 74 79 70 65 28 61 70 44 61 74 61 5b 30  ue_type(apData[0
3bf0: 5d 29 3d 3d 53 51 4c 49 54 45 5f 49 4e 54 45 47  ])==SQLITE_INTEG
3c00: 45 52 20 29 7b 0a 20 20 20 20 7a 20 3d 20 73 71  ER ){.    z = sq
3c10: 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 22 44  lite3_mprintf("D
3c20: 45 4c 45 54 45 20 46 52 4f 4d 20 25 51 20 57 48  ELETE FROM %Q WH
3c30: 45 52 45 20 72 6f 77 69 64 20 3d 20 3f 31 22 2c  ERE rowid = ?1",
3c40: 20 70 56 74 61 62 2d 3e 7a 54 61 62 6c 65 4e 61   pVtab->zTableNa
3c50: 6d 65 29 3b 0a 20 20 20 20 62 69 6e 64 41 72 67  me);.    bindArg
3c60: 5a 65 72 6f 20 3d 20 31 3b 0a 20 20 7d 0a 0a 20  Zero = 1;.  }.. 
3c70: 20 2f 2a 20 49 66 20 74 68 65 20 66 69 72 73 74   /* If the first
3c80: 20 61 72 67 75 6d 65 6e 74 20 69 73 20 4e 55 4c   argument is NUL
3c90: 4c 20 61 6e 64 20 74 68 65 72 65 20 61 72 65 20  L and there are 
3ca0: 6d 6f 72 65 20 74 68 61 6e 20 74 77 6f 20 61 72  more than two ar
3cb0: 67 73 2c 20 49 4e 53 45 52 54 20 2a 2f 0a 20 20  gs, INSERT */.  
3cc0: 65 6c 73 65 20 69 66 28 20 6e 44 61 74 61 3e 32  else if( nData>2
3cd0: 20 26 26 20 73 71 6c 69 74 65 33 5f 76 61 6c 75   && sqlite3_valu
3ce0: 65 5f 74 79 70 65 28 61 70 44 61 74 61 5b 30 5d  e_type(apData[0]
3cf0: 29 3d 3d 53 51 4c 49 54 45 5f 4e 55 4c 4c 20 29  )==SQLITE_NULL )
3d00: 7b 0a 20 20 20 20 69 6e 74 20 69 69 3b 0a 20 20  {.    int ii;.  
3d10: 20 20 63 68 61 72 20 2a 7a 49 6e 73 65 72 74 20    char *zInsert 
3d20: 3d 20 30 3b 0a 20 20 20 20 63 68 61 72 20 2a 7a  = 0;.    char *z
3d30: 56 61 6c 75 65 73 20 3d 20 30 3b 0a 20 20 0a 20  Values = 0;.  . 
3d40: 20 20 20 7a 49 6e 73 65 72 74 20 3d 20 73 71 6c     zInsert = sql
3d50: 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 22 49 4e  ite3_mprintf("IN
3d60: 53 45 52 54 20 4f 52 20 52 45 50 4c 41 43 45 20  SERT OR REPLACE 
3d70: 49 4e 54 4f 20 25 51 20 28 22 2c 20 70 56 74 61  INTO %Q (", pVta
3d80: 62 2d 3e 7a 54 61 62 6c 65 4e 61 6d 65 29 3b 0a  b->zTableName);.
3d90: 20 20 20 20 69 66 28 20 73 71 6c 69 74 65 33 5f      if( sqlite3_
3da0: 76 61 6c 75 65 5f 74 79 70 65 28 61 70 44 61 74  value_type(apDat
3db0: 61 5b 31 5d 29 3d 3d 53 51 4c 49 54 45 5f 49 4e  a[1])==SQLITE_IN
3dc0: 54 45 47 45 52 20 29 7b 0a 20 20 20 20 20 20 62  TEGER ){.      b
3dd0: 69 6e 64 41 72 67 4f 6e 65 20 3d 20 31 3b 0a 20  indArgOne = 1;. 
3de0: 20 20 20 20 20 7a 56 61 6c 75 65 73 20 3d 20 73       zValues = s
3df0: 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 22  qlite3_mprintf("
3e00: 3f 22 29 3b 0a 20 20 20 20 20 20 73 74 72 69 6e  ?");.      strin
3e10: 67 5f 63 6f 6e 63 61 74 28 26 7a 49 6e 73 65 72  g_concat(&zInser
3e20: 74 2c 20 22 72 6f 77 69 64 22 2c 20 30 29 3b 0a  t, "rowid", 0);.
3e30: 20 20 20 20 7d 0a 0a 20 20 20 20 61 73 73 65 72      }..    asser
3e40: 74 28 28 70 56 74 61 62 2d 3e 6e 43 6f 6c 2b 32  t((pVtab->nCol+2
3e50: 29 3d 3d 6e 44 61 74 61 29 3b 0a 20 20 20 20 66  )==nData);.    f
3e60: 6f 72 28 69 69 3d 32 3b 20 69 69 3c 6e 44 61 74  or(ii=2; ii<nDat
3e70: 61 3b 20 69 69 2b 2b 29 7b 0a 20 20 20 20 20 20  a; ii++){.      
3e80: 73 74 72 69 6e 67 5f 63 6f 6e 63 61 74 28 26 7a  string_concat(&z
3e90: 49 6e 73 65 72 74 2c 20 0a 20 20 20 20 20 20 20  Insert, .       
3ea0: 20 20 20 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e     sqlite3_mprin
3eb0: 74 66 28 22 25 73 25 51 22 2c 20 7a 56 61 6c 75  tf("%s%Q", zValu
3ec0: 65 73 3f 22 2c 20 22 3a 22 22 2c 20 70 56 74 61  es?", ":"", pVta
3ed0: 62 2d 3e 61 43 6f 6c 5b 69 69 2d 32 5d 29 2c 20  b->aCol[ii-2]), 
3ee0: 31 29 3b 0a 20 20 20 20 20 20 73 74 72 69 6e 67  1);.      string
3ef0: 5f 63 6f 6e 63 61 74 28 26 7a 56 61 6c 75 65 73  _concat(&zValues
3f00: 2c 20 0a 20 20 20 20 20 20 20 20 20 20 73 71 6c  , .          sql
3f10: 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 22 25 73  ite3_mprintf("%s
3f20: 3f 25 64 22 2c 20 7a 56 61 6c 75 65 73 3f 22 2c  ?%d", zValues?",
3f30: 20 22 3a 22 22 2c 20 69 69 29 2c 20 31 29 3b 0a   ":"", ii), 1);.
3f40: 20 20 20 20 7d 0a 0a 20 20 20 20 73 74 72 69 6e      }..    strin
3f50: 67 5f 63 6f 6e 63 61 74 28 26 7a 2c 20 7a 49 6e  g_concat(&z, zIn
3f60: 73 65 72 74 2c 20 31 29 3b 0a 20 20 20 20 73 74  sert, 1);.    st
3f70: 72 69 6e 67 5f 63 6f 6e 63 61 74 28 26 7a 2c 20  ring_concat(&z, 
3f80: 22 29 20 56 41 4c 55 45 53 28 22 2c 20 30 29 3b  ") VALUES(", 0);
3f90: 0a 20 20 20 20 73 74 72 69 6e 67 5f 63 6f 6e 63  .    string_conc
3fa0: 61 74 28 26 7a 2c 20 7a 56 61 6c 75 65 73 2c 20  at(&z, zValues, 
3fb0: 31 29 3b 0a 20 20 20 20 73 74 72 69 6e 67 5f 63  1);.    string_c
3fc0: 6f 6e 63 61 74 28 26 7a 2c 20 22 29 22 2c 20 30  oncat(&z, ")", 0
3fd0: 29 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 41 6e 79  );.  }..  /* Any
3fe0: 74 68 69 6e 67 20 65 6c 73 65 20 69 73 20 61 6e  thing else is an
3ff0: 20 65 72 72 6f 72 20 2a 2f 0a 20 20 65 6c 73 65   error */.  else
4000: 7b 0a 20 20 20 20 61 73 73 65 72 74 28 30 29 3b  {.    assert(0);
4010: 0a 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49  .    return SQLI
4020: 54 45 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a 0a 20  TE_ERROR;.  }.. 
4030: 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 70 72   rc = sqlite3_pr
4040: 65 70 61 72 65 28 64 62 2c 20 7a 2c 20 2d 31 2c  epare(db, z, -1,
4050: 20 26 70 53 74 6d 74 2c 20 30 29 3b 0a 20 20 61   &pStmt, 0);.  a
4060: 73 73 65 72 74 28 20 72 63 21 3d 53 51 4c 49 54  ssert( rc!=SQLIT
4070: 45 5f 4f 4b 20 7c 7c 20 70 53 74 6d 74 20 29 3b  E_OK || pStmt );
4080: 0a 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28  .  sqlite3_free(
4090: 7a 29 3b 0a 20 20 69 66 28 20 72 63 3d 3d 53 51  z);.  if( rc==SQ
40a0: 4c 49 54 45 5f 4f 4b 20 29 20 7b 0a 20 20 20 20  LITE_OK ) {.    
40b0: 69 66 28 20 62 69 6e 64 41 72 67 5a 65 72 6f 20  if( bindArgZero 
40c0: 29 7b 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33  ){.      sqlite3
40d0: 5f 62 69 6e 64 5f 76 61 6c 75 65 28 70 53 74 6d  _bind_value(pStm
40e0: 74 2c 20 6e 44 61 74 61 2c 20 61 70 44 61 74 61  t, nData, apData
40f0: 5b 30 5d 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20  [0]);.    }.    
4100: 69 66 28 20 62 69 6e 64 41 72 67 4f 6e 65 20 29  if( bindArgOne )
4110: 7b 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f  {.      sqlite3_
4120: 62 69 6e 64 5f 76 61 6c 75 65 28 70 53 74 6d 74  bind_value(pStmt
4130: 2c 20 31 2c 20 61 70 44 61 74 61 5b 31 5d 29 3b  , 1, apData[1]);
4140: 0a 20 20 20 20 7d 0a 20 20 20 20 66 6f 72 28 69  .    }.    for(i
4150: 3d 32 3b 20 69 3c 6e 44 61 74 61 3b 20 69 2b 2b  =2; i<nData; i++
4160: 29 7b 0a 20 20 20 20 20 20 69 66 28 20 61 70 44  ){.      if( apD
4170: 61 74 61 5b 69 5d 20 29 20 73 71 6c 69 74 65 33  ata[i] ) sqlite3
4180: 5f 62 69 6e 64 5f 76 61 6c 75 65 28 70 53 74 6d  _bind_value(pStm
4190: 74 2c 20 69 2c 20 61 70 44 61 74 61 5b 69 5d 29  t, i, apData[i])
41a0: 3b 0a 20 20 20 20 7d 0a 20 20 20 20 73 71 6c 69  ;.    }.    sqli
41b0: 74 65 33 5f 73 74 65 70 28 70 53 74 6d 74 29 3b  te3_step(pStmt);
41c0: 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65  .    rc = sqlite
41d0: 33 5f 66 69 6e 61 6c 69 7a 65 28 70 53 74 6d 74  3_finalize(pStmt
41e0: 29 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 70 52  );.  }..  if( pR
41f0: 6f 77 69 64 20 26 26 20 72 63 3d 3d 53 51 4c 49  owid && rc==SQLI
4200: 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 2a 70 52  TE_OK ){.    *pR
4210: 6f 77 69 64 20 3d 20 73 71 6c 69 74 65 33 5f 6c  owid = sqlite3_l
4220: 61 73 74 5f 69 6e 73 65 72 74 5f 72 6f 77 69 64  ast_insert_rowid
4230: 28 64 62 29 3b 0a 20 20 7d 0a 0a 20 20 72 65 74  (db);.  }..  ret
4240: 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  urn rc;.}../*.**
4250: 20 41 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65   A virtual table
4260: 20 6d 6f 64 75 6c 65 20 74 68 61 74 20 6d 65 72   module that mer
4270: 65 6c 79 20 65 63 68 6f 73 20 6d 65 74 68 6f 64  ely echos method
4280: 20 63 61 6c 6c 73 20 69 6e 74 6f 20 54 43 4c 0a   calls into TCL.
4290: 2a 2a 20 76 61 72 69 61 62 6c 65 73 2e 0a 2a 2f  ** variables..*/
42a0: 0a 73 74 61 74 69 63 20 73 71 6c 69 74 65 33 5f  .static sqlite3_
42b0: 6d 6f 64 75 6c 65 20 65 63 68 6f 4d 6f 64 75 6c  module echoModul
42c0: 65 20 3d 20 7b 0a 20 20 30 2c 20 20 20 20 20 20  e = {.  0,      
42d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
42e0: 20 20 20 2f 2a 20 69 56 65 72 73 69 6f 6e 20 2a     /* iVersion *
42f0: 2f 0a 20 20 22 65 63 68 6f 22 2c 20 20 20 20 20  /.  "echo",     
4300: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
4310: 2a 20 7a 4e 61 6d 65 20 2a 2f 0a 20 20 65 63 68  * zName */.  ech
4320: 6f 43 72 65 61 74 65 2c 0a 20 20 65 63 68 6f 43  oCreate,.  echoC
4330: 6f 6e 6e 65 63 74 2c 0a 20 20 65 63 68 6f 42 65  onnect,.  echoBe
4340: 73 74 49 6e 64 65 78 2c 0a 20 20 65 63 68 6f 44  stIndex,.  echoD
4350: 69 73 63 6f 6e 6e 65 63 74 2c 20 0a 20 20 65 63  isconnect, .  ec
4360: 68 6f 44 65 73 74 72 6f 79 2c 0a 20 20 65 63 68  hoDestroy,.  ech
4370: 6f 4f 70 65 6e 2c 20 20 20 20 20 20 20 20 20 20  oOpen,          
4380: 20 20 20 20 20 20 20 20 2f 2a 20 78 4f 70 65 6e          /* xOpen
4390: 20 2d 20 6f 70 65 6e 20 61 20 63 75 72 73 6f 72   - open a cursor
43a0: 20 2a 2f 0a 20 20 65 63 68 6f 43 6c 6f 73 65 2c   */.  echoClose,
43b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
43c0: 20 2f 2a 20 78 43 6c 6f 73 65 20 2d 20 63 6c 6f   /* xClose - clo
43d0: 73 65 20 61 20 63 75 72 73 6f 72 20 2a 2f 0a 20  se a cursor */. 
43e0: 20 65 63 68 6f 46 69 6c 74 65 72 2c 20 20 20 20   echoFilter,    
43f0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78              /* x
4400: 46 69 6c 74 65 72 20 2d 20 63 6f 6e 66 69 67 75  Filter - configu
4410: 72 65 20 73 63 61 6e 20 63 6f 6e 73 74 72 61 69  re scan constrai
4420: 6e 74 73 20 2a 2f 0a 20 20 65 63 68 6f 4e 65 78  nts */.  echoNex
4430: 74 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  t,              
4440: 20 20 20 20 2f 2a 20 78 4e 65 78 74 20 2d 20 61      /* xNext - a
4450: 64 76 61 6e 63 65 20 61 20 63 75 72 73 6f 72 20  dvance a cursor 
4460: 2a 2f 0a 20 20 65 63 68 6f 43 6f 6c 75 6d 6e 2c  */.  echoColumn,
4470: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4480: 2f 2a 20 78 43 6f 6c 75 6d 6e 20 2d 20 72 65 61  /* xColumn - rea
4490: 64 20 64 61 74 61 20 2a 2f 0a 20 20 65 63 68 6f  d data */.  echo
44a0: 52 6f 77 69 64 2c 20 20 20 20 20 20 20 20 20 20  Rowid,          
44b0: 20 20 20 20 20 20 20 2f 2a 20 78 52 6f 77 69 64         /* xRowid
44c0: 20 2d 20 72 65 61 64 20 64 61 74 61 20 2a 2f 0a   - read data */.
44d0: 20 20 65 63 68 6f 55 70 64 61 74 65 20 20 20 20    echoUpdate    
44e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
44f0: 78 55 70 64 61 74 65 20 2d 20 77 72 69 74 65 20  xUpdate - write 
4500: 64 61 74 61 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a  data */.};../*.*
4510: 2a 20 44 65 63 6f 64 65 20 61 20 70 6f 69 6e 74  * Decode a point
4520: 65 72 20 74 6f 20 61 6e 20 73 71 6c 69 74 65 33  er to an sqlite3
4530: 20 6f 62 6a 65 63 74 2e 0a 2a 2f 0a 73 74 61 74   object..*/.stat
4540: 69 63 20 69 6e 74 20 67 65 74 44 62 50 6f 69 6e  ic int getDbPoin
4550: 74 65 72 28 54 63 6c 5f 49 6e 74 65 72 70 20 2a  ter(Tcl_Interp *
4560: 69 6e 74 65 72 70 2c 20 63 6f 6e 73 74 20 63 68  interp, const ch
4570: 61 72 20 2a 7a 41 2c 20 73 71 6c 69 74 65 33 20  ar *zA, sqlite3 
4580: 2a 2a 70 70 44 62 29 7b 0a 20 20 2a 70 70 44 62  **ppDb){.  *ppDb
4590: 20 3d 20 28 73 71 6c 69 74 65 33 2a 29 73 71 6c   = (sqlite3*)sql
45a0: 69 74 65 33 54 65 78 74 54 6f 50 74 72 28 7a 41  ite3TextToPtr(zA
45b0: 29 3b 0a 20 20 72 65 74 75 72 6e 20 54 43 4c 5f  );.  return TCL_
45c0: 4f 4b 3b 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 52 65  OK;.}.../*.** Re
45d0: 67 69 73 74 65 72 20 74 68 65 20 65 63 68 6f 20  gister the echo 
45e0: 76 69 72 74 75 61 6c 20 74 61 62 6c 65 20 6d 6f  virtual table mo
45f0: 64 75 6c 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  dule..*/.static 
4600: 69 6e 74 20 72 65 67 69 73 74 65 72 5f 65 63 68  int register_ech
4610: 6f 5f 6d 6f 64 75 6c 65 28 0a 20 20 43 6c 69 65  o_module(.  Clie
4620: 6e 74 44 61 74 61 20 63 6c 69 65 6e 74 44 61 74  ntData clientDat
4630: 61 2c 20 2f 2a 20 50 6f 69 6e 74 65 72 20 74 6f  a, /* Pointer to
4640: 20 73 71 6c 69 74 65 33 5f 65 6e 61 62 6c 65 5f   sqlite3_enable_
4650: 58 58 58 20 66 75 6e 63 74 69 6f 6e 20 2a 2f 0a  XXX function */.
4660: 20 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e    Tcl_Interp *in
4670: 74 65 72 70 2c 20 20 20 20 2f 2a 20 54 68 65 20  terp,    /* The 
4680: 54 43 4c 20 69 6e 74 65 72 70 72 65 74 65 72 20  TCL interpreter 
4690: 74 68 61 74 20 69 6e 76 6f 6b 65 64 20 74 68 69  that invoked thi
46a0: 73 20 63 6f 6d 6d 61 6e 64 20 2a 2f 0a 20 20 69  s command */.  i
46b0: 6e 74 20 6f 62 6a 63 2c 20 20 20 20 20 20 20 20  nt objc,        
46c0: 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20        /* Number 
46d0: 6f 66 20 61 72 67 75 6d 65 6e 74 73 20 2a 2f 0a  of arguments */.
46e0: 20 20 54 63 6c 5f 4f 62 6a 20 2a 43 4f 4e 53 54    Tcl_Obj *CONST
46f0: 20 6f 62 6a 76 5b 5d 20 20 2f 2a 20 43 6f 6d 6d   objv[]  /* Comm
4700: 61 6e 64 20 61 72 67 75 6d 65 6e 74 73 20 2a 2f  and arguments */
4710: 0a 29 7b 0a 20 20 73 71 6c 69 74 65 33 20 2a 64  .){.  sqlite3 *d
4720: 62 3b 0a 20 20 69 66 28 20 6f 62 6a 63 21 3d 32  b;.  if( objc!=2
4730: 20 29 7b 0a 20 20 20 20 54 63 6c 5f 57 72 6f 6e   ){.    Tcl_Wron
4740: 67 4e 75 6d 41 72 67 73 28 69 6e 74 65 72 70 2c  gNumArgs(interp,
4750: 20 31 2c 20 6f 62 6a 76 2c 20 22 44 42 22 29 3b   1, objv, "DB");
4760: 0a 20 20 20 20 72 65 74 75 72 6e 20 54 43 4c 5f  .    return TCL_
4770: 45 52 52 4f 52 3b 0a 20 20 7d 0a 20 20 69 66 28  ERROR;.  }.  if(
4780: 20 67 65 74 44 62 50 6f 69 6e 74 65 72 28 69 6e   getDbPointer(in
4790: 74 65 72 70 2c 20 54 63 6c 5f 47 65 74 53 74 72  terp, Tcl_GetStr
47a0: 69 6e 67 28 6f 62 6a 76 5b 31 5d 29 2c 20 26 64  ing(objv[1]), &d
47b0: 62 29 20 29 20 72 65 74 75 72 6e 20 54 43 4c 5f  b) ) return TCL_
47c0: 45 52 52 4f 52 3b 0a 23 69 66 6e 64 65 66 20 53  ERROR;.#ifndef S
47d0: 51 4c 49 54 45 5f 4f 4d 49 54 5f 56 49 52 54 55  QLITE_OMIT_VIRTU
47e0: 41 4c 54 41 42 4c 45 0a 20 20 73 71 6c 69 74 65  ALTABLE.  sqlite
47f0: 33 5f 63 72 65 61 74 65 5f 6d 6f 64 75 6c 65 28  3_create_module(
4800: 64 62 2c 20 22 65 63 68 6f 22 2c 20 26 65 63 68  db, "echo", &ech
4810: 6f 4d 6f 64 75 6c 65 2c 20 28 76 6f 69 64 20 2a  oModule, (void *
4820: 29 69 6e 74 65 72 70 29 3b 0a 23 65 6e 64 69 66  )interp);.#endif
4830: 0a 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 4f 4b  .  return TCL_OK
4840: 3b 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 52 65 67 69  ;.}.../*.** Regi
4850: 73 74 65 72 20 63 6f 6d 6d 61 6e 64 73 20 77 69  ster commands wi
4860: 74 68 20 74 68 65 20 54 43 4c 20 69 6e 74 65 72  th the TCL inter
4870: 70 72 65 74 65 72 2e 0a 2a 2f 0a 69 6e 74 20 53  preter..*/.int S
4880: 71 6c 69 74 65 74 65 73 74 38 5f 49 6e 69 74 28  qlitetest8_Init(
4890: 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65  Tcl_Interp *inte
48a0: 72 70 29 7b 0a 20 20 73 74 61 74 69 63 20 73 74  rp){.  static st
48b0: 72 75 63 74 20 7b 0a 20 20 20 20 20 63 68 61 72  ruct {.     char
48c0: 20 2a 7a 4e 61 6d 65 3b 0a 20 20 20 20 20 54 63   *zName;.     Tc
48d0: 6c 5f 4f 62 6a 43 6d 64 50 72 6f 63 20 2a 78 50  l_ObjCmdProc *xP
48e0: 72 6f 63 3b 0a 20 20 20 20 20 76 6f 69 64 20 2a  roc;.     void *
48f0: 63 6c 69 65 6e 74 44 61 74 61 3b 0a 20 20 7d 20  clientData;.  } 
4900: 61 4f 62 6a 43 6d 64 5b 5d 20 3d 20 7b 0a 20 20  aObjCmd[] = {.  
4910: 20 20 20 7b 20 22 72 65 67 69 73 74 65 72 5f 65     { "register_e
4920: 63 68 6f 5f 6d 6f 64 75 6c 65 22 2c 20 20 20 72  cho_module",   r
4930: 65 67 69 73 74 65 72 5f 65 63 68 6f 5f 6d 6f 64  egister_echo_mod
4940: 75 6c 65 2c 20 30 20 7d 2c 0a 20 20 7d 3b 0a 20  ule, 0 },.  };. 
4950: 20 69 6e 74 20 69 3b 0a 20 20 66 6f 72 28 69 3d   int i;.  for(i=
4960: 30 3b 20 69 3c 73 69 7a 65 6f 66 28 61 4f 62 6a  0; i<sizeof(aObj
4970: 43 6d 64 29 2f 73 69 7a 65 6f 66 28 61 4f 62 6a  Cmd)/sizeof(aObj
4980: 43 6d 64 5b 30 5d 29 3b 20 69 2b 2b 29 7b 0a 20  Cmd[0]); i++){. 
4990: 20 20 20 54 63 6c 5f 43 72 65 61 74 65 4f 62 6a     Tcl_CreateObj
49a0: 43 6f 6d 6d 61 6e 64 28 69 6e 74 65 72 70 2c 20  Command(interp, 
49b0: 61 4f 62 6a 43 6d 64 5b 69 5d 2e 7a 4e 61 6d 65  aObjCmd[i].zName
49c0: 2c 20 0a 20 20 20 20 20 20 20 20 61 4f 62 6a 43  , .        aObjC
49d0: 6d 64 5b 69 5d 2e 78 50 72 6f 63 2c 20 61 4f 62  md[i].xProc, aOb
49e0: 6a 43 6d 64 5b 69 5d 2e 63 6c 69 65 6e 74 44 61  jCmd[i].clientDa
49f0: 74 61 2c 20 30 29 3b 0a 20 20 7d 0a 20 20 72 65  ta, 0);.  }.  re
4a00: 74 75 72 6e 20 54 43 4c 5f 4f 4b 3b 0a 7d 0a     turn TCL_OK;.}.