/ Hex Artifact Content
Login

Artifact 9ea0fd1708d714205b2db044d9d1e081182602a1:


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 33 33 20 32  test8.c,v 1.33 2
0230: 30 30 36 2f 30 36 2f 32 33 20 31 31 3a 33 34 3a  006/06/23 11:34:
0240: 35 35 20 64 61 6e 69 65 6c 6b 31 39 37 37 20 45  55 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 0a 2a 2a 20 54 68 65 20  sor;../*.** The 
0310: 74 65 73 74 20 6d 6f 64 75 6c 65 20 64 65 66 69  test module defi
0320: 6e 65 64 20 69 6e 20 74 68 69 73 20 66 69 6c 65  ned in this file
0330: 20 75 73 65 73 20 74 77 6f 20 67 6c 6f 62 61 6c   uses two global
0340: 20 54 63 6c 20 76 61 72 69 61 62 6c 65 73 20 74   Tcl variables t
0350: 6f 0a 2a 2a 20 63 6f 6d 6d 69 63 61 74 65 20 77  o.** commicate w
0360: 69 74 68 20 74 65 73 74 2d 73 63 72 69 70 74 73  ith test-scripts
0370: 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20 24 3a 3a 65  :.**.**     $::e
0380: 63 68 6f 5f 6d 6f 64 75 6c 65 0a 2a 2a 20 20 20  cho_module.**   
0390: 20 20 24 3a 3a 65 63 68 6f 5f 6d 6f 64 75 6c 65    $::echo_module
03a0: 5f 73 79 6e 63 5f 66 61 69 6c 0a 2a 2f 0a 0a 2f  _sync_fail.*/../
03b0: 2a 20 0a 2a 2a 20 41 6e 20 65 63 68 6f 20 76 69  * .** An echo vi
03c0: 72 74 75 61 6c 2d 74 61 62 6c 65 20 6f 62 6a 65  rtual-table obje
03d0: 63 74 2e 0a 2a 2a 0a 2a 2a 20 65 63 68 6f 2e 76  ct..**.** echo.v
03e0: 74 61 62 2e 61 49 6e 64 65 78 20 69 73 20 61 6e  tab.aIndex is an
03f0: 20 61 72 72 61 79 20 6f 66 20 62 6f 6f 6c 65 61   array of boolea
0400: 6e 73 2e 20 54 68 65 20 6e 74 68 20 65 6e 74 72  ns. The nth entr
0410: 79 20 69 73 20 74 72 75 65 20 69 66 20 0a 2a 2a  y is true if .**
0420: 20 74 68 65 20 6e 74 68 20 63 6f 6c 75 6d 6e 20   the nth column 
0430: 6f 66 20 74 68 65 20 72 65 61 6c 20 74 61 62 6c  of the real tabl
0440: 65 20 69 73 20 74 68 65 20 6c 65 66 74 2d 6d 6f  e is the left-mo
0450: 73 74 20 63 6f 6c 75 6d 6e 20 6f 66 20 61 6e 20  st column of an 
0460: 69 6e 64 65 78 0a 2a 2a 20 28 69 6d 70 6c 69 63  index.** (implic
0470: 69 74 20 6f 72 20 6f 74 68 65 72 77 69 73 65 29  it or otherwise)
0480: 2e 20 49 6e 20 6f 74 68 65 72 20 77 6f 72 64 73  . In other words
0490: 2c 20 69 66 20 53 51 4c 69 74 65 20 63 61 6e 20  , if SQLite can 
04a0: 6f 70 74 69 6d 69 7a 65 0a 2a 2a 20 61 20 71 75  optimize.** a qu
04b0: 65 72 79 20 6c 69 6b 65 20 22 53 45 4c 45 43 54  ery like "SELECT
04c0: 20 2a 20 46 52 4f 4d 20 72 65 61 6c 5f 74 61 62   * FROM real_tab
04d0: 6c 65 20 57 48 45 52 45 20 63 6f 6c 20 3d 20 3f  le WHERE col = ?
04e0: 22 2e 0a 2a 2a 0a 2a 2a 20 4d 65 6d 62 65 72 20  "..**.** Member 
04f0: 76 61 72 69 61 62 6c 65 20 61 43 6f 6c 5b 5d 20  variable aCol[] 
0500: 63 6f 6e 74 61 69 6e 73 20 63 6f 70 69 65 73 20  contains copies 
0510: 6f 66 20 74 68 65 20 63 6f 6c 75 6d 6e 20 6e 61  of the column na
0520: 6d 65 73 20 6f 66 20 74 68 65 20 72 65 61 6c 0a  mes of the real.
0530: 2a 2a 20 74 61 62 6c 65 2e 0a 2a 2f 0a 73 74 72  ** table..*/.str
0540: 75 63 74 20 65 63 68 6f 5f 76 74 61 62 20 7b 0a  uct echo_vtab {.
0550: 20 20 73 71 6c 69 74 65 33 5f 76 74 61 62 20 62    sqlite3_vtab b
0560: 61 73 65 3b 0a 20 20 54 63 6c 5f 49 6e 74 65 72  ase;.  Tcl_Inter
0570: 70 20 2a 69 6e 74 65 72 70 3b 0a 20 20 73 71 6c  p *interp;.  sql
0580: 69 74 65 33 20 2a 64 62 3b 0a 0a 20 20 63 68 61  ite3 *db;..  cha
0590: 72 20 2a 7a 54 61 62 6c 65 4e 61 6d 65 3b 20 20  r *zTableName;  
05a0: 20 20 20 20 20 2f 2a 20 4e 61 6d 65 20 6f 66 20       /* Name of 
05b0: 74 68 65 20 72 65 61 6c 20 74 61 62 6c 65 20 2a  the real table *
05c0: 2f 0a 20 20 63 68 61 72 20 2a 7a 4c 6f 67 4e 61  /.  char *zLogNa
05d0: 6d 65 3b 20 20 20 20 20 20 20 20 20 2f 2a 20 4e  me;         /* N
05e0: 61 6d 65 20 6f 66 20 74 68 65 20 6c 6f 67 20 74  ame of the log t
05f0: 61 62 6c 65 20 2a 2f 0a 20 20 69 6e 74 20 6e 43  able */.  int nC
0600: 6f 6c 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  ol;             
0610: 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 63    /* Number of c
0620: 6f 6c 75 6d 6e 73 20 69 6e 20 74 68 65 20 72 65  olumns in the re
0630: 61 6c 20 74 61 62 6c 65 20 2a 2f 0a 20 20 69 6e  al table */.  in
0640: 74 20 2a 61 49 6e 64 65 78 3b 20 20 20 20 20 20  t *aIndex;      
0650: 20 20 20 20 20 20 2f 2a 20 41 72 72 61 79 20 6f        /* Array o
0660: 66 20 73 69 7a 65 20 6e 43 6f 6c 2e 20 54 72 75  f size nCol. Tru
0670: 65 20 69 66 20 63 6f 6c 75 6d 6e 20 68 61 73 20  e if column has 
0680: 61 6e 20 69 6e 64 65 78 20 2a 2f 0a 20 20 63 68  an index */.  ch
0690: 61 72 20 2a 2a 61 43 6f 6c 3b 20 20 20 20 20 20  ar **aCol;      
06a0: 20 20 20 20 20 20 2f 2a 20 41 72 72 61 79 20 6f        /* Array o
06b0: 66 20 73 69 7a 65 20 6e 43 6f 6c 2e 20 43 6f 6c  f size nCol. Col
06c0: 75 6d 6e 20 6e 61 6d 65 73 20 2a 2f 0a 7d 3b 0a  umn names */.};.
06d0: 0a 2f 2a 20 41 6e 20 65 63 68 6f 20 63 75 72 73  ./* An echo curs
06e0: 6f 72 20 6f 62 6a 65 63 74 20 2a 2f 0a 73 74 72  or object */.str
06f0: 75 63 74 20 65 63 68 6f 5f 63 75 72 73 6f 72 20  uct echo_cursor 
0700: 7b 0a 20 20 73 71 6c 69 74 65 33 5f 76 74 61 62  {.  sqlite3_vtab
0710: 5f 63 75 72 73 6f 72 20 62 61 73 65 3b 0a 20 20  _cursor base;.  
0720: 73 71 6c 69 74 65 33 5f 73 74 6d 74 20 2a 70 53  sqlite3_stmt *pS
0730: 74 6d 74 3b 0a 20 20 69 6e 74 20 65 72 72 63 6f  tmt;.  int errco
0740: 64 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  de;             
0750: 20 20 20 20 2f 2a 20 45 72 72 6f 72 20 63 6f 64      /* Error cod
0760: 65 20 2a 2f 0a 7d 3b 0a 0a 73 74 61 74 69 63 20  e */.};..static 
0770: 69 6e 74 20 67 65 74 43 6f 6c 75 6d 6e 4e 61 6d  int getColumnNam
0780: 65 73 28 0a 20 20 73 71 6c 69 74 65 33 20 2a 64  es(.  sqlite3 *d
0790: 62 2c 20 0a 20 20 63 6f 6e 73 74 20 63 68 61 72  b, .  const char
07a0: 20 2a 7a 54 61 62 2c 0a 20 20 63 68 61 72 20 2a   *zTab,.  char *
07b0: 2a 2a 70 61 43 6f 6c 2c 20 0a 20 20 69 6e 74 20  **paCol, .  int 
07c0: 2a 70 6e 43 6f 6c 0a 29 7b 0a 20 20 63 68 61 72  *pnCol.){.  char
07d0: 20 2a 2a 61 43 6f 6c 20 3d 20 30 3b 0a 20 20 63   **aCol = 0;.  c
07e0: 68 61 72 20 7a 42 75 66 5b 31 30 32 34 5d 3b 0a  har zBuf[1024];.
07f0: 20 20 73 71 6c 69 74 65 33 5f 73 74 6d 74 20 2a    sqlite3_stmt *
0800: 70 53 74 6d 74 20 3d 20 30 3b 0a 20 20 69 6e 74  pStmt = 0;.  int
0810: 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b   rc = SQLITE_OK;
0820: 0a 20 20 69 6e 74 20 6e 43 6f 6c 20 3d 20 30 3b  .  int nCol = 0;
0830: 0a 0a 20 20 73 70 72 69 6e 74 66 28 7a 42 75 66  ..  sprintf(zBuf
0840: 2c 20 22 53 45 4c 45 43 54 20 2a 20 46 52 4f 4d  , "SELECT * FROM
0850: 20 25 73 22 2c 20 7a 54 61 62 29 3b 0a 20 20 72   %s", zTab);.  r
0860: 63 20 3d 20 73 71 6c 69 74 65 33 5f 70 72 65 70  c = sqlite3_prep
0870: 61 72 65 28 64 62 2c 20 7a 42 75 66 2c 20 2d 31  are(db, zBuf, -1
0880: 2c 20 26 70 53 74 6d 74 2c 20 30 29 3b 0a 20 20  , &pStmt, 0);.  
0890: 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  if( rc==SQLITE_O
08a0: 4b 20 29 7b 0a 20 20 20 20 69 6e 74 20 69 69 3b  K ){.    int ii;
08b0: 0a 20 20 20 20 6e 43 6f 6c 20 3d 20 73 71 6c 69  .    nCol = sqli
08c0: 74 65 33 5f 63 6f 6c 75 6d 6e 5f 63 6f 75 6e 74  te3_column_count
08d0: 28 70 53 74 6d 74 29 3b 0a 20 20 20 20 61 43 6f  (pStmt);.    aCo
08e0: 6c 20 3d 20 73 71 6c 69 74 65 4d 61 6c 6c 6f 63  l = sqliteMalloc
08f0: 28 73 69 7a 65 6f 66 28 63 68 61 72 20 2a 29 20  (sizeof(char *) 
0900: 2a 20 6e 43 6f 6c 29 3b 0a 20 20 20 20 69 66 28  * nCol);.    if(
0910: 20 21 61 43 6f 6c 20 29 7b 0a 20 20 20 20 20 20   !aCol ){.      
0920: 72 63 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45  rc = SQLITE_NOME
0930: 4d 3b 0a 20 20 20 20 20 20 67 6f 74 6f 20 66 61  M;.      goto fa
0940: 69 6c 3b 0a 20 20 20 20 7d 0a 20 20 20 20 66 6f  il;.    }.    fo
0950: 72 28 69 69 3d 30 3b 20 69 69 3c 6e 43 6f 6c 3b  r(ii=0; ii<nCol;
0960: 20 69 69 2b 2b 29 7b 0a 20 20 20 20 20 20 61 43   ii++){.      aC
0970: 6f 6c 5b 69 69 5d 20 3d 20 73 71 6c 69 74 65 33  ol[ii] = sqlite3
0980: 53 74 72 44 75 70 28 73 71 6c 69 74 65 33 5f 63  StrDup(sqlite3_c
0990: 6f 6c 75 6d 6e 5f 6e 61 6d 65 28 70 53 74 6d 74  olumn_name(pStmt
09a0: 2c 20 69 69 29 29 3b 0a 20 20 20 20 20 20 69 66  , ii));.      if
09b0: 28 20 21 61 43 6f 6c 5b 69 69 5d 20 29 7b 0a 20  ( !aCol[ii] ){. 
09c0: 20 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c 49         rc = SQLI
09d0: 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 20 20  TE_NOMEM;.      
09e0: 20 20 67 6f 74 6f 20 66 61 69 6c 3b 0a 20 20 20    goto fail;.   
09f0: 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a     }.    }.  }..
0a00: 20 20 2a 70 61 43 6f 6c 20 3d 20 61 43 6f 6c 3b    *paCol = aCol;
0a10: 0a 20 20 2a 70 6e 43 6f 6c 20 3d 20 6e 43 6f 6c  .  *pnCol = nCol
0a20: 3b 0a 0a 66 61 69 6c 3a 0a 20 20 73 71 6c 69 74  ;..fail:.  sqlit
0a30: 65 33 5f 66 69 6e 61 6c 69 7a 65 28 70 53 74 6d  e3_finalize(pStm
0a40: 74 29 3b 0a 20 20 69 66 28 20 72 63 21 3d 53 51  t);.  if( rc!=SQ
0a50: 4c 49 54 45 5f 4f 4b 20 26 26 20 61 43 6f 6c 20  LITE_OK && aCol 
0a60: 29 7b 0a 20 20 20 20 69 6e 74 20 69 69 3b 0a 20  ){.    int ii;. 
0a70: 20 20 20 66 6f 72 28 69 69 3d 30 3b 20 69 69 3c     for(ii=0; ii<
0a80: 6e 43 6f 6c 3b 20 69 69 2b 2b 29 7b 0a 20 20 20  nCol; ii++){.   
0a90: 20 20 20 73 71 6c 69 74 65 46 72 65 65 28 61 43     sqliteFree(aC
0aa0: 6f 6c 5b 69 69 5d 29 3b 0a 20 20 20 20 7d 0a 20  ol[ii]);.    }. 
0ab0: 20 20 20 73 71 6c 69 74 65 46 72 65 65 28 61 43     sqliteFree(aC
0ac0: 6f 6c 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72  ol);.  }.  retur
0ad0: 6e 20 72 63 3b 0a 7d 0a 0a 73 74 61 74 69 63 20  n rc;.}..static 
0ae0: 69 6e 74 20 67 65 74 49 6e 64 65 78 41 72 72 61  int getIndexArra
0af0: 79 28 73 71 6c 69 74 65 33 20 2a 64 62 2c 20 63  y(sqlite3 *db, c
0b00: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 54 61 62 2c  onst char *zTab,
0b10: 20 69 6e 74 20 2a 2a 70 61 49 6e 64 65 78 29 7b   int **paIndex){
0b20: 0a 20 20 63 68 61 72 20 7a 42 75 66 5b 31 30 32  .  char zBuf[102
0b30: 34 5d 3b 0a 20 20 73 71 6c 69 74 65 33 5f 73 74  4];.  sqlite3_st
0b40: 6d 74 20 2a 70 53 74 6d 74 20 3d 20 30 3b 0a 20  mt *pStmt = 0;. 
0b50: 20 69 6e 74 20 6e 43 6f 6c 3b 0a 20 20 69 6e 74   int nCol;.  int
0b60: 20 2a 61 49 6e 64 65 78 20 3d 20 30 3b 0a 20 20   *aIndex = 0;.  
0b70: 69 6e 74 20 72 63 3b 0a 0a 20 20 73 70 72 69 6e  int rc;..  sprin
0b80: 74 66 28 7a 42 75 66 2c 20 22 53 45 4c 45 43 54  tf(zBuf, "SELECT
0b90: 20 2a 20 46 52 4f 4d 20 25 73 22 2c 20 7a 54 61   * FROM %s", zTa
0ba0: 62 29 3b 0a 20 20 72 63 20 3d 20 73 71 6c 69 74  b);.  rc = sqlit
0bb0: 65 33 5f 70 72 65 70 61 72 65 28 64 62 2c 20 7a  e3_prepare(db, z
0bc0: 42 75 66 2c 20 2d 31 2c 20 26 70 53 74 6d 74 2c  Buf, -1, &pStmt,
0bd0: 20 30 29 3b 0a 20 20 6e 43 6f 6c 20 3d 20 73 71   0);.  nCol = sq
0be0: 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 63 6f 75  lite3_column_cou
0bf0: 6e 74 28 70 53 74 6d 74 29 3b 0a 0a 20 20 73 71  nt(pStmt);..  sq
0c00: 6c 69 74 65 33 5f 66 69 6e 61 6c 69 7a 65 28 70  lite3_finalize(p
0c10: 53 74 6d 74 29 3b 0a 20 20 70 53 74 6d 74 20 3d  Stmt);.  pStmt =
0c20: 20 30 3b 0a 20 20 69 66 28 20 72 63 21 3d 53 51   0;.  if( rc!=SQ
0c30: 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 67  LITE_OK ){.    g
0c40: 6f 74 6f 20 67 65 74 5f 69 6e 64 65 78 5f 61 72  oto get_index_ar
0c50: 72 61 79 5f 6f 75 74 3b 0a 20 20 7d 0a 0a 20 20  ray_out;.  }..  
0c60: 61 49 6e 64 65 78 20 3d 20 28 69 6e 74 20 2a 29  aIndex = (int *)
0c70: 73 71 6c 69 74 65 4d 61 6c 6c 6f 63 28 73 69 7a  sqliteMalloc(siz
0c80: 65 6f 66 28 69 6e 74 29 20 2a 20 6e 43 6f 6c 29  eof(int) * nCol)
0c90: 3b 0a 20 20 69 66 28 20 21 61 49 6e 64 65 78 20  ;.  if( !aIndex 
0ca0: 29 7b 0a 20 20 20 20 72 63 20 3d 20 53 51 4c 49  ){.    rc = SQLI
0cb0: 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 67 6f  TE_NOMEM;.    go
0cc0: 74 6f 20 67 65 74 5f 69 6e 64 65 78 5f 61 72 72  to get_index_arr
0cd0: 61 79 5f 6f 75 74 3b 0a 20 20 7d 0a 0a 20 20 73  ay_out;.  }..  s
0ce0: 70 72 69 6e 74 66 28 7a 42 75 66 2c 20 22 50 52  printf(zBuf, "PR
0cf0: 41 47 4d 41 20 69 6e 64 65 78 5f 6c 69 73 74 28  AGMA index_list(
0d00: 25 73 29 22 2c 20 7a 54 61 62 29 3b 0a 20 20 72  %s)", zTab);.  r
0d10: 63 20 3d 20 73 71 6c 69 74 65 33 5f 70 72 65 70  c = sqlite3_prep
0d20: 61 72 65 28 64 62 2c 20 7a 42 75 66 2c 20 2d 31  are(db, zBuf, -1
0d30: 2c 20 26 70 53 74 6d 74 2c 20 30 29 3b 0a 0a 20  , &pStmt, 0);.. 
0d40: 20 77 68 69 6c 65 28 20 70 53 74 6d 74 20 26 26   while( pStmt &&
0d50: 20 73 71 6c 69 74 65 33 5f 73 74 65 70 28 70 53   sqlite3_step(pS
0d60: 74 6d 74 29 3d 3d 53 51 4c 49 54 45 5f 52 4f 57  tmt)==SQLITE_ROW
0d70: 20 29 7b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f   ){.    sqlite3_
0d80: 73 74 6d 74 20 2a 70 53 74 6d 74 32 20 3d 20 30  stmt *pStmt2 = 0
0d90: 3b 0a 20 20 20 20 73 70 72 69 6e 74 66 28 7a 42  ;.    sprintf(zB
0da0: 75 66 2c 20 22 50 52 41 47 4d 41 20 69 6e 64 65  uf, "PRAGMA inde
0db0: 78 5f 69 6e 66 6f 28 25 73 29 22 2c 20 73 71 6c  x_info(%s)", sql
0dc0: 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 74 65 78 74  ite3_column_text
0dd0: 28 70 53 74 6d 74 2c 20 31 29 29 3b 0a 20 20 20  (pStmt, 1));.   
0de0: 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 70 72   rc = sqlite3_pr
0df0: 65 70 61 72 65 28 64 62 2c 20 7a 42 75 66 2c 20  epare(db, zBuf, 
0e00: 2d 31 2c 20 26 70 53 74 6d 74 32 2c 20 30 29 3b  -1, &pStmt2, 0);
0e10: 0a 20 20 20 20 69 66 28 20 70 53 74 6d 74 32 20  .    if( pStmt2 
0e20: 26 26 20 73 71 6c 69 74 65 33 5f 73 74 65 70 28  && sqlite3_step(
0e30: 70 53 74 6d 74 32 29 3d 3d 53 51 4c 49 54 45 5f  pStmt2)==SQLITE_
0e40: 52 4f 57 20 29 7b 0a 20 20 20 20 20 20 69 6e 74  ROW ){.      int
0e50: 20 63 69 64 20 3d 20 73 71 6c 69 74 65 33 5f 63   cid = sqlite3_c
0e60: 6f 6c 75 6d 6e 5f 69 6e 74 28 70 53 74 6d 74 32  olumn_int(pStmt2
0e70: 2c 20 31 29 3b 0a 20 20 20 20 20 20 61 73 73 65  , 1);.      asse
0e80: 72 74 28 20 63 69 64 3e 3d 30 20 26 26 20 63 69  rt( cid>=0 && ci
0e90: 64 3c 6e 43 6f 6c 20 29 3b 0a 20 20 20 20 20 20  d<nCol );.      
0ea0: 61 49 6e 64 65 78 5b 63 69 64 5d 20 3d 20 31 3b  aIndex[cid] = 1;
0eb0: 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 28 20 70  .    }.    if( p
0ec0: 53 74 6d 74 32 20 29 7b 0a 20 20 20 20 20 20 72  Stmt2 ){.      r
0ed0: 63 20 3d 20 73 71 6c 69 74 65 33 5f 66 69 6e 61  c = sqlite3_fina
0ee0: 6c 69 7a 65 28 70 53 74 6d 74 32 29 3b 0a 20 20  lize(pStmt2);.  
0ef0: 20 20 7d 0a 20 20 20 20 69 66 28 20 72 63 21 3d    }.    if( rc!=
0f00: 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20  SQLITE_OK ){.   
0f10: 20 20 20 73 71 6c 69 74 65 33 5f 66 69 6e 61 6c     sqlite3_final
0f20: 69 7a 65 28 70 53 74 6d 74 29 3b 0a 20 20 20 20  ize(pStmt);.    
0f30: 20 20 67 6f 74 6f 20 67 65 74 5f 69 6e 64 65 78    goto get_index
0f40: 5f 61 72 72 61 79 5f 6f 75 74 3b 0a 20 20 20 20  _array_out;.    
0f50: 7d 0a 20 20 7d 0a 0a 20 20 69 66 28 20 70 53 74  }.  }..  if( pSt
0f60: 6d 74 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 73  mt ){.    rc = s
0f70: 71 6c 69 74 65 33 5f 66 69 6e 61 6c 69 7a 65 28  qlite3_finalize(
0f80: 70 53 74 6d 74 29 3b 0a 20 20 7d 0a 0a 67 65 74  pStmt);.  }..get
0f90: 5f 69 6e 64 65 78 5f 61 72 72 61 79 5f 6f 75 74  _index_array_out
0fa0: 3a 0a 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49  :.  if( rc!=SQLI
0fb0: 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 73 71 6c  TE_OK ){.    sql
0fc0: 69 74 65 46 72 65 65 28 61 49 6e 64 65 78 29 3b  iteFree(aIndex);
0fd0: 0a 20 20 20 20 61 49 6e 64 65 78 20 3d 20 30 3b  .    aIndex = 0;
0fe0: 0a 20 20 7d 0a 20 20 2a 70 61 49 6e 64 65 78 20  .  }.  *paIndex 
0ff0: 3d 20 61 49 6e 64 65 78 3b 0a 20 20 72 65 74 75  = aIndex;.  retu
1000: 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  rn rc;.}../*.** 
1010: 47 6c 6f 62 61 6c 20 54 63 6c 20 76 61 72 69 61  Global Tcl varia
1020: 62 6c 65 20 24 65 63 68 6f 5f 6d 6f 64 75 6c 65  ble $echo_module
1030: 20 69 73 20 61 20 6c 69 73 74 2e 20 54 68 69 73   is a list. This
1040: 20 72 6f 75 74 69 6e 65 20 61 70 70 65 6e 64 73   routine appends
1050: 0a 2a 2a 20 74 68 65 20 73 74 72 69 6e 67 20 65  .** the string e
1060: 6c 65 6d 65 6e 74 20 7a 41 72 67 20 74 6f 20 74  lement zArg to t
1070: 68 61 74 20 6c 69 73 74 20 69 6e 20 69 6e 74 65  hat list in inte
1080: 72 70 72 65 74 65 72 20 69 6e 74 65 72 70 2e 0a  rpreter interp..
1090: 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 61  */.static void a
10a0: 70 70 65 6e 64 54 6f 45 63 68 6f 4d 6f 64 75 6c  ppendToEchoModul
10b0: 65 28 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e  e(Tcl_Interp *in
10c0: 74 65 72 70 2c 20 63 6f 6e 73 74 20 63 68 61 72  terp, const char
10d0: 20 2a 7a 41 72 67 29 7b 0a 20 20 69 6e 74 20 66   *zArg){.  int f
10e0: 6c 61 67 73 20 3d 20 28 54 43 4c 5f 41 50 50 45  lags = (TCL_APPE
10f0: 4e 44 5f 56 41 4c 55 45 20 7c 20 54 43 4c 5f 4c  ND_VALUE | TCL_L
1100: 49 53 54 5f 45 4c 45 4d 45 4e 54 20 7c 20 54 43  IST_ELEMENT | TC
1110: 4c 5f 47 4c 4f 42 41 4c 5f 4f 4e 4c 59 29 3b 0a  L_GLOBAL_ONLY);.
1120: 20 20 54 63 6c 5f 53 65 74 56 61 72 28 69 6e 74    Tcl_SetVar(int
1130: 65 72 70 2c 20 22 65 63 68 6f 5f 6d 6f 64 75 6c  erp, "echo_modul
1140: 65 22 2c 20 28 7a 41 72 67 3f 7a 41 72 67 3a 22  e", (zArg?zArg:"
1150: 22 29 2c 20 66 6c 61 67 73 29 3b 0a 7d 0a 0a 2f  "), flags);.}../
1160: 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63 74 69  *.** This functi
1170: 6f 6e 20 69 73 20 63 61 6c 6c 65 64 20 66 72 6f  on is called fro
1180: 6d 20 77 69 74 68 69 6e 20 74 68 65 20 65 63 68  m within the ech
1190: 6f 2d 6d 6f 64 75 6c 65 73 20 78 43 72 65 61 74  o-modules xCreat
11a0: 65 20 61 6e 64 0a 2a 2a 20 78 43 6f 6e 6e 65 63  e and.** xConnec
11b0: 74 20 6d 65 74 68 6f 64 73 2e 20 54 68 65 20 61  t methods. The a
11c0: 72 67 63 20 61 6e 64 20 61 72 67 76 20 61 72 67  rgc and argv arg
11d0: 75 6d 65 6e 74 73 20 61 72 65 20 63 6f 70 69 65  uments are copie
11e0: 73 20 6f 66 20 74 68 6f 73 65 20 0a 2a 2a 20 70  s of those .** p
11f0: 61 73 73 65 64 20 74 6f 20 74 68 65 20 63 61 6c  assed to the cal
1200: 6c 69 6e 67 20 6d 65 74 68 6f 64 2e 20 54 68 69  ling method. Thi
1210: 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 72 65  s function is re
1220: 73 70 6f 6e 73 69 62 6c 65 20 66 6f 72 0a 2a 2a  sponsible for.**
1230: 20 63 61 6c 6c 69 6e 67 20 73 71 6c 69 74 65 33   calling sqlite3
1240: 5f 64 65 63 6c 61 72 65 5f 76 74 61 62 28 29 20  _declare_vtab() 
1250: 74 6f 20 64 65 63 6c 61 72 65 20 74 68 65 20 73  to declare the s
1260: 63 68 65 6d 61 20 6f 66 20 74 68 65 20 76 69 72  chema of the vir
1270: 74 75 61 6c 0a 2a 2a 20 74 61 62 6c 65 20 62 65  tual.** table be
1280: 69 6e 67 20 63 72 65 61 74 65 64 20 6f 72 20 63  ing created or c
1290: 6f 6e 6e 65 63 74 65 64 2e 0a 2a 2a 0a 2a 2a 20  onnected..**.** 
12a0: 49 66 20 74 68 65 20 63 6f 6e 73 74 72 75 63 74  If the construct
12b0: 6f 72 20 77 61 73 20 70 61 73 73 65 64 20 6a 75  or was passed ju
12c0: 73 74 20 6f 6e 65 20 61 72 67 75 6d 65 6e 74 2c  st one argument,
12d0: 20 69 2e 65 2e 3a 0a 2a 2a 0a 2a 2a 20 20 20 43   i.e.:.**.**   C
12e0: 52 45 41 54 45 20 54 41 42 4c 45 20 74 31 20 41  REATE TABLE t1 A
12f0: 53 20 65 63 68 6f 28 74 32 29 3b 0a 2a 2a 0a 2a  S echo(t2);.**.*
1300: 2a 20 54 68 65 6e 20 74 32 20 69 73 20 61 73 73  * Then t2 is ass
1310: 75 6d 65 64 20 74 6f 20 62 65 20 74 68 65 20 6e  umed to be the n
1320: 61 6d 65 20 6f 66 20 61 20 2a 72 65 61 6c 2a 20  ame of a *real* 
1330: 64 61 74 61 62 61 73 65 20 74 61 62 6c 65 2e 20  database table. 
1340: 54 68 65 0a 2a 2a 20 73 63 68 65 6d 61 20 6f 66  The.** schema of
1350: 20 74 68 65 20 76 69 72 74 75 61 6c 20 74 61 62   the virtual tab
1360: 6c 65 20 69 73 20 64 65 63 6c 61 72 65 64 20 62  le is declared b
1370: 79 20 70 61 73 73 69 6e 67 20 61 20 63 6f 70 79  y passing a copy
1380: 20 6f 66 20 74 68 65 20 0a 2a 2a 20 43 52 45 41   of the .** CREA
1390: 54 45 20 54 41 42 4c 45 20 73 74 61 74 65 6d 65  TE TABLE stateme
13a0: 6e 74 20 66 6f 72 20 74 68 65 20 72 65 61 6c 20  nt for the real 
13b0: 74 61 62 6c 65 20 74 6f 20 73 71 6c 69 74 65 33  table to sqlite3
13c0: 5f 64 65 63 6c 61 72 65 5f 76 74 61 62 28 29 2e  _declare_vtab().
13d0: 0a 2a 2a 20 48 65 6e 63 65 2c 20 74 68 65 20 76  .** Hence, the v
13e0: 69 72 74 75 61 6c 20 74 61 62 6c 65 20 73 68 6f  irtual table sho
13f0: 75 6c 64 20 68 61 76 65 20 65 78 61 63 74 6c 79  uld have exactly
1400: 20 74 68 65 20 73 61 6d 65 20 63 6f 6c 75 6d 6e   the same column
1410: 20 6e 61 6d 65 73 20 61 6e 64 20 0a 2a 2a 20 74   names and .** t
1420: 79 70 65 73 20 61 73 20 74 68 65 20 72 65 61 6c  ypes as the real
1430: 20 74 61 62 6c 65 2e 0a 2a 2f 0a 73 74 61 74 69   table..*/.stati
1440: 63 20 69 6e 74 20 65 63 68 6f 44 65 63 6c 61 72  c int echoDeclar
1450: 65 56 74 61 62 28 0a 20 20 65 63 68 6f 5f 76 74  eVtab(.  echo_vt
1460: 61 62 20 2a 70 56 74 61 62 2c 20 0a 20 20 73 71  ab *pVtab, .  sq
1470: 6c 69 74 65 33 20 2a 64 62 2c 20 0a 20 20 69 6e  lite3 *db, .  in
1480: 74 20 61 72 67 63 2c 20 0a 20 20 63 68 61 72 20  t argc, .  char 
1490: 2a 2a 61 72 67 76 0a 29 7b 0a 20 20 69 6e 74 20  **argv.){.  int 
14a0: 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a  rc = SQLITE_OK;.
14b0: 0a 20 20 69 66 28 20 61 72 67 63 3e 3d 34 20 29  .  if( argc>=4 )
14c0: 7b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 73 74  {.    sqlite3_st
14d0: 6d 74 20 2a 70 53 74 6d 74 20 3d 20 30 3b 0a 20  mt *pStmt = 0;. 
14e0: 20 20 20 73 71 6c 69 74 65 33 5f 70 72 65 70 61     sqlite3_prepa
14f0: 72 65 28 64 62 2c 20 0a 20 20 20 20 20 20 20 20  re(db, .        
1500: 22 53 45 4c 45 43 54 20 73 71 6c 20 46 52 4f 4d  "SELECT sql FROM
1510: 20 73 71 6c 69 74 65 5f 6d 61 73 74 65 72 20 57   sqlite_master W
1520: 48 45 52 45 20 74 79 70 65 20 3d 20 27 74 61 62  HERE type = 'tab
1530: 6c 65 27 20 41 4e 44 20 6e 61 6d 65 20 3d 20 3f  le' AND name = ?
1540: 22 2c 0a 20 20 20 20 20 20 20 20 2d 31 2c 20 26  ",.        -1, &
1550: 70 53 74 6d 74 2c 20 30 29 3b 0a 20 20 20 20 73  pStmt, 0);.    s
1560: 71 6c 69 74 65 33 5f 62 69 6e 64 5f 74 65 78 74  qlite3_bind_text
1570: 28 70 53 74 6d 74 2c 20 31 2c 20 61 72 67 76 5b  (pStmt, 1, argv[
1580: 33 5d 2c 20 2d 31 2c 20 30 29 3b 0a 20 20 20 20  3], -1, 0);.    
1590: 69 66 28 20 73 71 6c 69 74 65 33 5f 73 74 65 70  if( sqlite3_step
15a0: 28 70 53 74 6d 74 29 3d 3d 53 51 4c 49 54 45 5f  (pStmt)==SQLITE_
15b0: 52 4f 57 20 29 7b 0a 20 20 20 20 20 20 63 6f 6e  ROW ){.      con
15c0: 73 74 20 63 68 61 72 20 2a 7a 43 72 65 61 74 65  st char *zCreate
15d0: 54 61 62 6c 65 20 3d 20 73 71 6c 69 74 65 33 5f  Table = sqlite3_
15e0: 63 6f 6c 75 6d 6e 5f 74 65 78 74 28 70 53 74 6d  column_text(pStm
15f0: 74 2c 20 30 29 3b 0a 23 69 66 6e 64 65 66 20 53  t, 0);.#ifndef S
1600: 51 4c 49 54 45 5f 4f 4d 49 54 5f 56 49 52 54 55  QLITE_OMIT_VIRTU
1610: 41 4c 54 41 42 4c 45 0a 20 20 20 20 20 20 73 71  ALTABLE.      sq
1620: 6c 69 74 65 33 5f 64 65 63 6c 61 72 65 5f 76 74  lite3_declare_vt
1630: 61 62 28 64 62 2c 20 7a 43 72 65 61 74 65 54 61  ab(db, zCreateTa
1640: 62 6c 65 29 3b 0a 23 65 6e 64 69 66 0a 20 20 20  ble);.#endif.   
1650: 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f     rc = sqlite3_
1660: 66 69 6e 61 6c 69 7a 65 28 70 53 74 6d 74 29 3b  finalize(pStmt);
1670: 0a 20 20 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20  .    } else {.  
1680: 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33      rc = sqlite3
1690: 5f 66 69 6e 61 6c 69 7a 65 28 70 53 74 6d 74 29  _finalize(pStmt)
16a0: 3b 0a 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d  ;.      if( rc==
16b0: 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 20 0a 20 20  SQLITE_OK ){ .  
16c0: 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54        rc = SQLIT
16d0: 45 5f 45 52 52 4f 52 3b 0a 20 20 20 20 20 20 7d  E_ERROR;.      }
16e0: 0a 20 20 20 20 7d 0a 0a 20 20 20 20 69 66 28 20  .    }..    if( 
16f0: 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc==SQLITE_OK ){
1700: 0a 20 20 20 20 20 20 72 63 20 3d 20 67 65 74 49  .      rc = getI
1710: 6e 64 65 78 41 72 72 61 79 28 64 62 2c 20 61 72  ndexArray(db, ar
1720: 67 76 5b 33 5d 2c 20 26 70 56 74 61 62 2d 3e 61  gv[3], &pVtab->a
1730: 49 6e 64 65 78 29 3b 0a 20 20 20 20 7d 0a 20 20  Index);.    }.  
1740: 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
1750: 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 72 63 20  _OK ){.      rc 
1760: 3d 20 67 65 74 43 6f 6c 75 6d 6e 4e 61 6d 65 73  = getColumnNames
1770: 28 64 62 2c 20 61 72 67 76 5b 33 5d 2c 20 26 70  (db, argv[3], &p
1780: 56 74 61 62 2d 3e 61 43 6f 6c 2c 20 26 70 56 74  Vtab->aCol, &pVt
1790: 61 62 2d 3e 6e 43 6f 6c 29 3b 0a 20 20 20 20 7d  ab->nCol);.    }
17a0: 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 72  .  }..  return r
17b0: 63 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74  c;.}..static int
17c0: 20 65 63 68 6f 44 65 73 74 72 75 63 74 6f 72 28   echoDestructor(
17d0: 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 70 56  sqlite3_vtab *pV
17e0: 74 61 62 29 7b 0a 20 20 69 6e 74 20 69 69 3b 0a  tab){.  int ii;.
17f0: 20 20 65 63 68 6f 5f 76 74 61 62 20 2a 70 20 3d    echo_vtab *p =
1800: 20 28 65 63 68 6f 5f 76 74 61 62 2a 29 70 56 74   (echo_vtab*)pVt
1810: 61 62 3b 0a 20 20 73 71 6c 69 74 65 46 72 65 65  ab;.  sqliteFree
1820: 28 70 2d 3e 61 49 6e 64 65 78 29 3b 0a 20 20 66  (p->aIndex);.  f
1830: 6f 72 28 69 69 3d 30 3b 20 69 69 3c 70 2d 3e 6e  or(ii=0; ii<p->n
1840: 43 6f 6c 3b 20 69 69 2b 2b 29 7b 0a 20 20 20 20  Col; ii++){.    
1850: 73 71 6c 69 74 65 46 72 65 65 28 70 2d 3e 61 43  sqliteFree(p->aC
1860: 6f 6c 5b 69 69 5d 29 3b 0a 20 20 7d 0a 20 20 73  ol[ii]);.  }.  s
1870: 71 6c 69 74 65 46 72 65 65 28 70 2d 3e 61 43 6f  qliteFree(p->aCo
1880: 6c 29 3b 0a 20 20 73 71 6c 69 74 65 46 72 65 65  l);.  sqliteFree
1890: 28 70 2d 3e 7a 54 61 62 6c 65 4e 61 6d 65 29 3b  (p->zTableName);
18a0: 0a 20 20 73 71 6c 69 74 65 46 72 65 65 28 70 29  .  sqliteFree(p)
18b0: 3b 0a 20 20 72 65 74 75 72 6e 20 30 3b 0a 7d 0a  ;.  return 0;.}.
18c0: 0a 73 74 61 74 69 63 20 69 6e 74 20 65 63 68 6f  .static int echo
18d0: 43 6f 6e 73 74 72 75 63 74 6f 72 28 0a 20 20 73  Constructor(.  s
18e0: 71 6c 69 74 65 33 20 2a 64 62 2c 0a 20 20 76 6f  qlite3 *db,.  vo
18f0: 69 64 20 2a 70 41 75 78 2c 0a 20 20 69 6e 74 20  id *pAux,.  int 
1900: 61 72 67 63 2c 20 63 68 61 72 20 2a 2a 61 72 67  argc, char **arg
1910: 76 2c 0a 20 20 73 71 6c 69 74 65 33 5f 76 74 61  v,.  sqlite3_vta
1920: 62 20 2a 2a 70 70 56 74 61 62 0a 29 7b 0a 20 20  b **ppVtab.){.  
1930: 69 6e 74 20 69 3b 0a 20 20 65 63 68 6f 5f 76 74  int i;.  echo_vt
1940: 61 62 20 2a 70 56 74 61 62 3b 0a 0a 20 20 70 56  ab *pVtab;..  pV
1950: 74 61 62 20 3d 20 73 71 6c 69 74 65 4d 61 6c 6c  tab = sqliteMall
1960: 6f 63 28 20 73 69 7a 65 6f 66 28 2a 70 56 74 61  oc( sizeof(*pVta
1970: 62 29 20 29 3b 0a 20 20 69 66 28 20 21 70 56 74  b) );.  if( !pVt
1980: 61 62 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e  ab ){.    return
1990: 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20   SQLITE_NOMEM;. 
19a0: 20 7d 0a 20 20 70 56 74 61 62 2d 3e 69 6e 74 65   }.  pVtab->inte
19b0: 72 70 20 3d 20 28 54 63 6c 5f 49 6e 74 65 72 70  rp = (Tcl_Interp
19c0: 20 2a 29 70 41 75 78 3b 0a 20 20 70 56 74 61 62   *)pAux;.  pVtab
19d0: 2d 3e 64 62 20 3d 20 64 62 3b 0a 20 20 70 56 74  ->db = db;.  pVt
19e0: 61 62 2d 3e 7a 54 61 62 6c 65 4e 61 6d 65 20 3d  ab->zTableName =
19f0: 20 73 71 6c 69 74 65 33 4d 50 72 69 6e 74 66 28   sqlite3MPrintf(
1a00: 22 25 73 22 2c 20 61 72 67 76 5b 33 5d 29 3b 0a  "%s", argv[3]);.
1a10: 20 20 69 66 28 20 21 70 56 74 61 62 2d 3e 7a 54    if( !pVtab->zT
1a20: 61 62 6c 65 4e 61 6d 65 20 29 7b 0a 20 20 20 20  ableName ){.    
1a30: 65 63 68 6f 44 65 73 74 72 75 63 74 6f 72 28 28  echoDestructor((
1a40: 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 29 70  sqlite3_vtab *)p
1a50: 56 74 61 62 29 3b 0a 20 20 20 20 72 65 74 75 72  Vtab);.    retur
1a60: 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a  n SQLITE_NOMEM;.
1a70: 20 20 7d 0a 0a 20 20 66 6f 72 28 69 3d 30 3b 20    }..  for(i=0; 
1a80: 69 3c 61 72 67 63 3b 20 69 2b 2b 29 7b 0a 20 20  i<argc; i++){.  
1a90: 20 20 61 70 70 65 6e 64 54 6f 45 63 68 6f 4d 6f    appendToEchoMo
1aa0: 64 75 6c 65 28 70 56 74 61 62 2d 3e 69 6e 74 65  dule(pVtab->inte
1ab0: 72 70 2c 20 61 72 67 76 5b 69 5d 29 3b 0a 20 20  rp, argv[i]);.  
1ac0: 7d 0a 0a 20 20 69 66 28 20 65 63 68 6f 44 65 63  }..  if( echoDec
1ad0: 6c 61 72 65 56 74 61 62 28 70 56 74 61 62 2c 20  lareVtab(pVtab, 
1ae0: 64 62 2c 20 61 72 67 63 2c 20 61 72 67 76 29 20  db, argc, argv) 
1af0: 29 7b 0a 20 20 20 20 65 63 68 6f 44 65 73 74 72  ){.    echoDestr
1b00: 75 63 74 6f 72 28 28 73 71 6c 69 74 65 33 5f 76  uctor((sqlite3_v
1b10: 74 61 62 20 2a 29 70 56 74 61 62 29 3b 0a 20 20  tab *)pVtab);.  
1b20: 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f    return SQLITE_
1b30: 45 52 52 4f 52 3b 0a 20 20 7d 0a 0a 20 20 2a 70  ERROR;.  }..  *p
1b40: 70 56 74 61 62 20 3d 20 26 70 56 74 61 62 2d 3e  pVtab = &pVtab->
1b50: 62 61 73 65 3b 0a 20 20 72 65 74 75 72 6e 20 53  base;.  return S
1b60: 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 20  QLITE_OK;.}../* 
1b70: 4d 65 74 68 6f 64 73 20 66 6f 72 20 74 68 65 20  Methods for the 
1b80: 65 63 68 6f 20 6d 6f 64 75 6c 65 20 2a 2f 0a 73  echo module */.s
1b90: 74 61 74 69 63 20 69 6e 74 20 65 63 68 6f 43 72  tatic int echoCr
1ba0: 65 61 74 65 28 0a 20 20 73 71 6c 69 74 65 33 20  eate(.  sqlite3 
1bb0: 2a 64 62 2c 0a 20 20 76 6f 69 64 20 2a 70 41 75  *db,.  void *pAu
1bc0: 78 2c 0a 20 20 69 6e 74 20 61 72 67 63 2c 20 63  x,.  int argc, c
1bd0: 68 61 72 20 2a 2a 61 72 67 76 2c 0a 20 20 73 71  har **argv,.  sq
1be0: 6c 69 74 65 33 5f 76 74 61 62 20 2a 2a 70 70 56  lite3_vtab **ppV
1bf0: 74 61 62 0a 29 7b 0a 20 20 69 6e 74 20 72 63 20  tab.){.  int rc 
1c00: 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 61  = SQLITE_OK;.  a
1c10: 70 70 65 6e 64 54 6f 45 63 68 6f 4d 6f 64 75 6c  ppendToEchoModul
1c20: 65 28 28 54 63 6c 5f 49 6e 74 65 72 70 20 2a 29  e((Tcl_Interp *)
1c30: 28 70 41 75 78 29 2c 20 22 78 43 72 65 61 74 65  (pAux), "xCreate
1c40: 22 29 3b 0a 20 20 72 63 20 3d 20 65 63 68 6f 43  ");.  rc = echoC
1c50: 6f 6e 73 74 72 75 63 74 6f 72 28 64 62 2c 20 70  onstructor(db, p
1c60: 41 75 78 2c 20 61 72 67 63 2c 20 61 72 67 76 2c  Aux, argc, argv,
1c70: 20 70 70 56 74 61 62 29 3b 0a 23 69 66 20 30 0a   ppVtab);.#if 0.
1c80: 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
1c90: 5f 4f 4b 20 26 26 20 61 72 67 63 3d 3d 35 20 29  _OK && argc==5 )
1ca0: 7b 0a 20 20 20 20 63 68 61 72 20 2a 7a 53 71 6c  {.    char *zSql
1cb0: 3b 0a 20 20 20 20 65 63 68 6f 5f 76 74 61 62 20  ;.    echo_vtab 
1cc0: 2a 70 56 74 61 62 20 3d 20 2a 28 65 63 68 6f 5f  *pVtab = *(echo_
1cd0: 76 74 61 62 20 2a 2a 29 70 70 56 74 61 62 3b 0a  vtab **)ppVtab;.
1ce0: 20 20 20 20 70 56 74 61 62 2d 3e 7a 4c 6f 67 4e      pVtab->zLogN
1cf0: 61 6d 65 20 3d 20 73 71 6c 69 74 65 33 4d 50 72  ame = sqlite3MPr
1d00: 69 6e 74 66 28 22 25 73 22 2c 20 61 72 67 76 5b  intf("%s", argv[
1d10: 34 5d 29 3b 0a 20 20 20 20 7a 53 71 6c 20 3d 20  4]);.    zSql = 
1d20: 73 71 6c 69 74 65 33 4d 50 72 69 6e 74 66 28 22  sqlite3MPrintf("
1d30: 43 52 45 41 54 45 20 54 41 42 4c 45 20 25 51 28  CREATE TABLE %Q(
1d40: 6c 6f 67 6d 73 67 29 22 2c 20 70 56 74 61 62 2d  logmsg)", pVtab-
1d50: 3e 7a 4c 6f 67 4e 61 6d 65 29 3b 0a 20 20 20 20  >zLogName);.    
1d60: 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 65 78 65  rc = sqlite3_exe
1d70: 63 28 64 62 2c 20 7a 53 71 6c 2c 20 30 2c 20 30  c(db, zSql, 0, 0
1d80: 2c 20 30 29 3b 0a 20 20 20 20 73 71 6c 69 74 65  , 0);.    sqlite
1d90: 46 72 65 65 28 7a 53 71 6c 29 3b 0a 20 20 7d 0a  Free(zSql);.  }.
1da0: 23 65 6e 64 69 66 0a 20 20 72 65 74 75 72 6e 20  #endif.  return 
1db0: 72 63 3b 0a 7d 0a 73 74 61 74 69 63 20 69 6e 74  rc;.}.static int
1dc0: 20 65 63 68 6f 43 6f 6e 6e 65 63 74 28 0a 20 20   echoConnect(.  
1dd0: 73 71 6c 69 74 65 33 20 2a 64 62 2c 0a 20 20 76  sqlite3 *db,.  v
1de0: 6f 69 64 20 2a 70 41 75 78 2c 0a 20 20 69 6e 74  oid *pAux,.  int
1df0: 20 61 72 67 63 2c 20 63 68 61 72 20 2a 2a 61 72   argc, char **ar
1e00: 67 76 2c 0a 20 20 73 71 6c 69 74 65 33 5f 76 74  gv,.  sqlite3_vt
1e10: 61 62 20 2a 2a 70 70 56 74 61 62 0a 29 7b 0a 20  ab **ppVtab.){. 
1e20: 20 61 70 70 65 6e 64 54 6f 45 63 68 6f 4d 6f 64   appendToEchoMod
1e30: 75 6c 65 28 28 54 63 6c 5f 49 6e 74 65 72 70 20  ule((Tcl_Interp 
1e40: 2a 29 28 70 41 75 78 29 2c 20 22 78 43 6f 6e 6e  *)(pAux), "xConn
1e50: 65 63 74 22 29 3b 0a 20 20 72 65 74 75 72 6e 20  ect");.  return 
1e60: 65 63 68 6f 43 6f 6e 73 74 72 75 63 74 6f 72 28  echoConstructor(
1e70: 64 62 2c 20 70 41 75 78 2c 20 61 72 67 63 2c 20  db, pAux, argc, 
1e80: 61 72 67 76 2c 20 70 70 56 74 61 62 29 3b 0a 7d  argv, ppVtab);.}
1e90: 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 65 63 68  ..static int ech
1ea0: 6f 44 69 73 63 6f 6e 6e 65 63 74 28 73 71 6c 69  oDisconnect(sqli
1eb0: 74 65 33 5f 76 74 61 62 20 2a 70 56 74 61 62 29  te3_vtab *pVtab)
1ec0: 7b 0a 20 20 61 70 70 65 6e 64 54 6f 45 63 68 6f  {.  appendToEcho
1ed0: 4d 6f 64 75 6c 65 28 28 28 65 63 68 6f 5f 76 74  Module(((echo_vt
1ee0: 61 62 20 2a 29 70 56 74 61 62 29 2d 3e 69 6e 74  ab *)pVtab)->int
1ef0: 65 72 70 2c 20 22 78 44 69 73 63 6f 6e 6e 65 63  erp, "xDisconnec
1f00: 74 22 29 3b 0a 20 20 72 65 74 75 72 6e 20 65 63  t");.  return ec
1f10: 68 6f 44 65 73 74 72 75 63 74 6f 72 28 70 56 74  hoDestructor(pVt
1f20: 61 62 29 3b 0a 7d 0a 73 74 61 74 69 63 20 69 6e  ab);.}.static in
1f30: 74 20 65 63 68 6f 44 65 73 74 72 6f 79 28 73 71  t echoDestroy(sq
1f40: 6c 69 74 65 33 5f 76 74 61 62 20 2a 70 56 74 61  lite3_vtab *pVta
1f50: 62 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53  b){.  int rc = S
1f60: 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 65 63 68 6f  QLITE_OK;.  echo
1f70: 5f 76 74 61 62 20 2a 70 20 3d 20 28 65 63 68 6f  _vtab *p = (echo
1f80: 5f 76 74 61 62 20 2a 29 70 56 74 61 62 3b 0a 20  _vtab *)pVtab;. 
1f90: 20 61 70 70 65 6e 64 54 6f 45 63 68 6f 4d 6f 64   appendToEchoMod
1fa0: 75 6c 65 28 28 28 65 63 68 6f 5f 76 74 61 62 20  ule(((echo_vtab 
1fb0: 2a 29 70 56 74 61 62 29 2d 3e 69 6e 74 65 72 70  *)pVtab)->interp
1fc0: 2c 20 22 78 44 65 73 74 72 6f 79 22 29 3b 0a 23  , "xDestroy");.#
1fd0: 69 66 20 30 0a 20 20 69 66 28 20 70 20 26 26 20  if 0.  if( p && 
1fe0: 70 2d 3e 7a 4c 6f 67 4e 61 6d 65 20 29 7b 0a 20  p->zLogName ){. 
1ff0: 20 20 20 63 68 61 72 20 2a 7a 53 71 6c 3b 0a 20     char *zSql;. 
2000: 20 20 20 7a 53 71 6c 20 3d 20 73 71 6c 69 74 65     zSql = sqlite
2010: 33 4d 50 72 69 6e 74 66 28 22 44 52 4f 50 20 54  3MPrintf("DROP T
2020: 41 42 4c 45 20 25 51 22 2c 20 70 2d 3e 7a 4c 6f  ABLE %Q", p->zLo
2030: 67 4e 61 6d 65 29 3b 0a 20 20 20 20 72 63 20 3d  gName);.    rc =
2040: 20 73 71 6c 69 74 65 33 5f 65 78 65 63 28 70 2d   sqlite3_exec(p-
2050: 3e 64 62 2c 20 7a 53 71 6c 2c 20 30 2c 20 30 2c  >db, zSql, 0, 0,
2060: 20 30 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 46   0);.    sqliteF
2070: 72 65 65 28 7a 53 71 6c 29 3b 0a 20 20 7d 0a 23  ree(zSql);.  }.#
2080: 65 6e 64 69 66 0a 20 20 69 66 28 20 72 63 3d 3d  endif.  if( rc==
2090: 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20  SQLITE_OK ){.   
20a0: 20 72 63 20 3d 20 65 63 68 6f 44 65 73 74 72 75   rc = echoDestru
20b0: 63 74 6f 72 28 70 56 74 61 62 29 3b 0a 20 20 7d  ctor(pVtab);.  }
20c0: 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a  .  return rc;.}.
20d0: 0a 73 74 61 74 69 63 20 69 6e 74 20 65 63 68 6f  .static int echo
20e0: 4f 70 65 6e 28 73 71 6c 69 74 65 33 5f 76 74 61  Open(sqlite3_vta
20f0: 62 20 2a 70 56 54 61 62 2c 20 73 71 6c 69 74 65  b *pVTab, sqlite
2100: 33 5f 76 74 61 62 5f 63 75 72 73 6f 72 20 2a 2a  3_vtab_cursor **
2110: 70 70 43 75 72 73 6f 72 29 7b 0a 20 20 65 63 68  ppCursor){.  ech
2120: 6f 5f 63 75 72 73 6f 72 20 2a 70 43 75 72 3b 0a  o_cursor *pCur;.
2130: 20 20 70 43 75 72 20 3d 20 73 71 6c 69 74 65 4d    pCur = sqliteM
2140: 61 6c 6c 6f 63 28 73 69 7a 65 6f 66 28 65 63 68  alloc(sizeof(ech
2150: 6f 5f 63 75 72 73 6f 72 29 29 3b 0a 20 20 2a 70  o_cursor));.  *p
2160: 70 43 75 72 73 6f 72 20 3d 20 28 73 71 6c 69 74  pCursor = (sqlit
2170: 65 33 5f 76 74 61 62 5f 63 75 72 73 6f 72 20 2a  e3_vtab_cursor *
2180: 29 70 43 75 72 3b 0a 20 20 72 65 74 75 72 6e 20  )pCur;.  return 
2190: 28 70 43 75 72 20 3f 20 53 51 4c 49 54 45 5f 4f  (pCur ? SQLITE_O
21a0: 4b 20 3a 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d  K : SQLITE_NOMEM
21b0: 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74  );.}..static int
21c0: 20 65 63 68 6f 43 6c 6f 73 65 28 73 71 6c 69 74   echoClose(sqlit
21d0: 65 33 5f 76 74 61 62 5f 63 75 72 73 6f 72 20 2a  e3_vtab_cursor *
21e0: 63 75 72 29 7b 0a 20 20 69 6e 74 20 72 63 3b 0a  cur){.  int rc;.
21f0: 20 20 65 63 68 6f 5f 63 75 72 73 6f 72 20 2a 70    echo_cursor *p
2200: 43 75 72 20 3d 20 28 65 63 68 6f 5f 63 75 72 73  Cur = (echo_curs
2210: 6f 72 20 2a 29 63 75 72 3b 0a 20 20 73 71 6c 69  or *)cur;.  sqli
2220: 74 65 33 5f 73 74 6d 74 20 2a 70 53 74 6d 74 20  te3_stmt *pStmt 
2230: 3d 20 70 43 75 72 2d 3e 70 53 74 6d 74 3b 0a 20  = pCur->pStmt;. 
2240: 20 70 43 75 72 2d 3e 70 53 74 6d 74 20 3d 20 30   pCur->pStmt = 0
2250: 3b 0a 20 20 73 71 6c 69 74 65 46 72 65 65 28 70  ;.  sqliteFree(p
2260: 43 75 72 29 3b 0a 20 20 72 63 20 3d 20 73 71 6c  Cur);.  rc = sql
2270: 69 74 65 33 5f 66 69 6e 61 6c 69 7a 65 28 70 53  ite3_finalize(pS
2280: 74 6d 74 29 3b 0a 20 20 72 65 74 75 72 6e 20 72  tmt);.  return r
2290: 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75  c;.}../*.** Retu
22a0: 72 6e 20 6e 6f 6e 2d 7a 65 72 6f 20 69 66 20 74  rn non-zero if t
22b0: 68 65 20 63 75 72 73 6f 72 20 64 6f 65 73 20 6e  he cursor does n
22c0: 6f 74 20 63 75 72 72 65 6e 74 6c 79 20 70 6f 69  ot currently poi
22d0: 6e 74 20 74 6f 20 61 20 76 61 6c 69 64 20 72 65  nt to a valid re
22e0: 63 6f 72 64 0a 2a 2a 20 28 69 2e 65 20 69 66 20  cord.** (i.e if 
22f0: 74 68 65 20 73 63 61 6e 20 68 61 73 20 66 69 6e  the scan has fin
2300: 69 73 68 65 64 29 2c 20 6f 72 20 7a 65 72 6f 20  ished), or zero 
2310: 6f 74 68 65 72 77 69 73 65 2e 0a 2a 2f 0a 73 74  otherwise..*/.st
2320: 61 74 69 63 20 69 6e 74 20 65 63 68 6f 45 6f 66  atic int echoEof
2330: 28 73 71 6c 69 74 65 33 5f 76 74 61 62 5f 63 75  (sqlite3_vtab_cu
2340: 72 73 6f 72 20 2a 63 75 72 29 7b 0a 20 20 72 65  rsor *cur){.  re
2350: 74 75 72 6e 20 28 28 28 65 63 68 6f 5f 63 75 72  turn (((echo_cur
2360: 73 6f 72 20 2a 29 63 75 72 29 2d 3e 70 53 74 6d  sor *)cur)->pStm
2370: 74 20 3f 20 30 20 3a 20 31 29 3b 0a 7d 0a 0a 73  t ? 0 : 1);.}..s
2380: 74 61 74 69 63 20 69 6e 74 20 65 63 68 6f 4e 65  tatic int echoNe
2390: 78 74 28 73 71 6c 69 74 65 33 5f 76 74 61 62 5f  xt(sqlite3_vtab_
23a0: 63 75 72 73 6f 72 20 2a 63 75 72 29 7b 0a 20 20  cursor *cur){.  
23b0: 69 6e 74 20 72 63 3b 0a 20 20 65 63 68 6f 5f 63  int rc;.  echo_c
23c0: 75 72 73 6f 72 20 2a 70 43 75 72 20 3d 20 28 65  ursor *pCur = (e
23d0: 63 68 6f 5f 63 75 72 73 6f 72 20 2a 29 63 75 72  cho_cursor *)cur
23e0: 3b 0a 20 20 73 71 6c 69 74 65 33 5f 73 74 6d 74  ;.  sqlite3_stmt
23f0: 20 2a 70 53 74 6d 74 20 3d 20 70 43 75 72 2d 3e   *pStmt = pCur->
2400: 70 53 74 6d 74 3b 0a 20 20 72 63 20 3d 20 73 71  pStmt;.  rc = sq
2410: 6c 69 74 65 33 5f 73 74 65 70 28 70 43 75 72 2d  lite3_step(pCur-
2420: 3e 70 53 74 6d 74 29 3b 0a 0a 20 20 69 66 28 20  >pStmt);..  if( 
2430: 72 63 3d 3d 53 51 4c 49 54 45 5f 52 4f 57 20 29  rc==SQLITE_ROW )
2440: 7b 0a 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54  {.    rc = SQLIT
2450: 45 5f 4f 4b 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20  E_OK;.  }else{. 
2460: 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f     rc = sqlite3_
2470: 66 69 6e 61 6c 69 7a 65 28 70 43 75 72 2d 3e 70  finalize(pCur->p
2480: 53 74 6d 74 29 3b 0a 20 20 20 20 70 43 75 72 2d  Stmt);.    pCur-
2490: 3e 70 53 74 6d 74 20 3d 20 30 3b 0a 20 20 7d 0a  >pStmt = 0;.  }.
24a0: 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a  .  return rc;.}.
24b0: 0a 73 74 61 74 69 63 20 69 6e 74 20 65 63 68 6f  .static int echo
24c0: 43 6f 6c 75 6d 6e 28 73 71 6c 69 74 65 33 5f 76  Column(sqlite3_v
24d0: 74 61 62 5f 63 75 72 73 6f 72 20 2a 63 75 72 2c  tab_cursor *cur,
24e0: 20 73 71 6c 69 74 65 33 5f 63 6f 6e 74 65 78 74   sqlite3_context
24f0: 20 2a 63 74 78 2c 20 69 6e 74 20 69 29 7b 0a 20   *ctx, int i){. 
2500: 20 69 6e 74 20 69 43 6f 6c 20 3d 20 69 20 2b 20   int iCol = i + 
2510: 31 3b 0a 20 20 73 71 6c 69 74 65 33 5f 73 74 6d  1;.  sqlite3_stm
2520: 74 20 2a 70 53 74 6d 74 20 3d 20 28 28 65 63 68  t *pStmt = ((ech
2530: 6f 5f 63 75 72 73 6f 72 20 2a 29 63 75 72 29 2d  o_cursor *)cur)-
2540: 3e 70 53 74 6d 74 3b 0a 20 20 69 66 28 20 28 28  >pStmt;.  if( ((
2550: 65 63 68 6f 5f 63 75 72 73 6f 72 20 2a 29 63 75  echo_cursor *)cu
2560: 72 29 2d 3e 65 72 72 63 6f 64 65 20 29 7b 0a 20  r)->errcode ){. 
2570: 20 20 20 72 65 74 75 72 6e 20 28 28 65 63 68 6f     return ((echo
2580: 5f 63 75 72 73 6f 72 20 2a 29 63 75 72 29 2d 3e  _cursor *)cur)->
2590: 65 72 72 63 6f 64 65 3b 0a 20 20 7d 0a 20 20 69  errcode;.  }.  i
25a0: 66 28 20 21 70 53 74 6d 74 20 29 7b 0a 20 20 20  f( !pStmt ){.   
25b0: 20 73 71 6c 69 74 65 33 5f 72 65 73 75 6c 74 5f   sqlite3_result_
25c0: 6e 75 6c 6c 28 63 74 78 29 3b 0a 20 20 7d 65 6c  null(ctx);.  }el
25d0: 73 65 7b 0a 20 20 20 20 61 73 73 65 72 74 28 20  se{.    assert( 
25e0: 73 71 6c 69 74 65 33 5f 64 61 74 61 5f 63 6f 75  sqlite3_data_cou
25f0: 6e 74 28 70 53 74 6d 74 29 3e 69 43 6f 6c 20 29  nt(pStmt)>iCol )
2600: 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 72 65  ;.    sqlite3_re
2610: 73 75 6c 74 5f 76 61 6c 75 65 28 63 74 78 2c 20  sult_value(ctx, 
2620: 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 76  sqlite3_column_v
2630: 61 6c 75 65 28 70 53 74 6d 74 2c 20 69 43 6f 6c  alue(pStmt, iCol
2640: 29 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e  ));.  }.  return
2650: 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 73   SQLITE_OK;.}..s
2660: 74 61 74 69 63 20 69 6e 74 20 65 63 68 6f 52 6f  tatic int echoRo
2670: 77 69 64 28 73 71 6c 69 74 65 33 5f 76 74 61 62  wid(sqlite3_vtab
2680: 5f 63 75 72 73 6f 72 20 2a 63 75 72 2c 20 73 71  _cursor *cur, sq
2690: 6c 69 74 65 5f 69 6e 74 36 34 20 2a 70 52 6f 77  lite_int64 *pRow
26a0: 69 64 29 7b 0a 20 20 73 71 6c 69 74 65 33 5f 73  id){.  sqlite3_s
26b0: 74 6d 74 20 2a 70 53 74 6d 74 20 3d 20 28 28 65  tmt *pStmt = ((e
26c0: 63 68 6f 5f 63 75 72 73 6f 72 20 2a 29 63 75 72  cho_cursor *)cur
26d0: 29 2d 3e 70 53 74 6d 74 3b 0a 20 20 2a 70 52 6f  )->pStmt;.  *pRo
26e0: 77 69 64 20 3d 20 73 71 6c 69 74 65 33 5f 63 6f  wid = sqlite3_co
26f0: 6c 75 6d 6e 5f 69 6e 74 36 34 28 70 53 74 6d 74  lumn_int64(pStmt
2700: 2c 20 30 29 3b 0a 20 20 72 65 74 75 72 6e 20 53  , 0);.  return S
2710: 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a  QLITE_OK;.}../*.
2720: 2a 2a 20 43 6f 6d 70 75 74 65 20 61 20 73 69 6d  ** Compute a sim
2730: 70 6c 65 20 68 61 73 68 20 6f 66 20 74 68 65 20  ple hash of the 
2740: 6e 75 6c 6c 20 74 65 72 6d 69 6e 61 74 65 64 20  null terminated 
2750: 73 74 72 69 6e 67 20 7a 53 74 72 69 6e 67 2e 0a  string zString..
2760: 2a 2a 0a 2a 2a 20 54 68 69 73 20 6d 6f 64 75 6c  **.** This modul
2770: 65 20 75 73 65 73 20 6f 6e 6c 79 20 73 71 6c 69  e uses only sqli
2780: 74 65 33 5f 69 6e 64 65 78 5f 69 6e 66 6f 2e 69  te3_index_info.i
2790: 64 78 53 74 72 2c 20 6e 6f 74 20 0a 2a 2a 20 73  dxStr, not .** s
27a0: 71 6c 69 74 65 33 5f 69 6e 64 65 78 5f 69 6e 66  qlite3_index_inf
27b0: 6f 2e 69 64 78 4e 75 6d 2e 20 53 6f 20 74 6f 20  o.idxNum. So to 
27c0: 74 65 73 74 20 69 64 78 4e 75 6d 2c 20 77 68 65  test idxNum, whe
27d0: 6e 20 69 64 78 53 74 72 20 69 73 20 73 65 74 0a  n idxStr is set.
27e0: 2a 2a 20 69 6e 20 65 63 68 6f 42 65 73 74 49 6e  ** in echoBestIn
27f0: 64 65 78 28 29 2c 20 69 64 78 4e 75 6d 20 69 73  dex(), idxNum is
2800: 20 73 65 74 20 74 6f 20 74 68 65 20 63 6f 72 72   set to the corr
2810: 65 73 70 6f 6e 64 69 6e 67 20 68 61 73 68 20 76  esponding hash v
2820: 61 6c 75 65 2e 0a 2a 2a 20 49 6e 20 65 63 68 6f  alue..** In echo
2830: 46 69 6c 74 65 72 28 29 2c 20 63 6f 64 65 20 61  Filter(), code a
2840: 73 73 65 72 74 28 29 73 20 74 68 61 74 20 74 68  ssert()s that th
2850: 65 20 73 75 70 70 6c 69 65 64 20 69 64 78 4e 75  e supplied idxNu
2860: 6d 20 76 61 6c 75 65 20 69 73 0a 2a 2a 20 69 6e  m value is.** in
2870: 64 65 65 64 20 74 68 65 20 68 61 73 68 20 6f 66  deed the hash of
2880: 20 74 68 65 20 73 75 70 70 6c 69 65 64 20 69 64   the supplied id
2890: 78 53 74 72 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  xStr..*/.static 
28a0: 69 6e 74 20 68 61 73 68 53 74 72 69 6e 67 28 63  int hashString(c
28b0: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 53 74 72 69  onst char *zStri
28c0: 6e 67 29 7b 0a 20 20 69 6e 74 20 76 61 6c 20 3d  ng){.  int val =
28d0: 20 30 3b 0a 20 20 69 6e 74 20 69 69 3b 0a 20 20   0;.  int ii;.  
28e0: 66 6f 72 28 69 69 3d 30 3b 20 7a 53 74 72 69 6e  for(ii=0; zStrin
28f0: 67 5b 69 69 5d 3b 20 69 69 2b 2b 29 7b 0a 20 20  g[ii]; ii++){.  
2900: 20 20 76 61 6c 20 3d 20 28 76 61 6c 20 3c 3c 20    val = (val << 
2910: 33 29 20 2b 20 28 69 6e 74 29 7a 53 74 72 69 6e  3) + (int)zStrin
2920: 67 5b 69 69 5d 3b 0a 20 20 7d 0a 20 20 72 65 74  g[ii];.  }.  ret
2930: 75 72 6e 20 76 61 6c 3b 0a 7d 0a 0a 0a 73 74 61  urn val;.}...sta
2940: 74 69 63 20 69 6e 74 20 65 63 68 6f 46 69 6c 74  tic int echoFilt
2950: 65 72 28 0a 20 20 73 71 6c 69 74 65 33 5f 76 74  er(.  sqlite3_vt
2960: 61 62 5f 63 75 72 73 6f 72 20 2a 70 56 74 61 62  ab_cursor *pVtab
2970: 43 75 72 73 6f 72 2c 20 0a 20 20 69 6e 74 20 69  Cursor, .  int i
2980: 64 78 4e 75 6d 2c 20 63 6f 6e 73 74 20 63 68 61  dxNum, const cha
2990: 72 20 2a 69 64 78 53 74 72 2c 0a 20 20 69 6e 74  r *idxStr,.  int
29a0: 20 61 72 67 63 2c 20 73 71 6c 69 74 65 33 5f 76   argc, sqlite3_v
29b0: 61 6c 75 65 20 2a 2a 61 72 67 76 0a 29 7b 0a 20  alue **argv.){. 
29c0: 20 69 6e 74 20 72 63 3b 0a 20 20 69 6e 74 20 69   int rc;.  int i
29d0: 3b 0a 0a 20 20 65 63 68 6f 5f 63 75 72 73 6f 72  ;..  echo_cursor
29e0: 20 2a 70 43 75 72 20 3d 20 28 65 63 68 6f 5f 63   *pCur = (echo_c
29f0: 75 72 73 6f 72 20 2a 29 70 56 74 61 62 43 75 72  ursor *)pVtabCur
2a00: 73 6f 72 3b 0a 20 20 65 63 68 6f 5f 76 74 61 62  sor;.  echo_vtab
2a10: 20 2a 70 56 74 61 62 20 3d 20 28 65 63 68 6f 5f   *pVtab = (echo_
2a20: 76 74 61 62 20 2a 29 70 56 74 61 62 43 75 72 73  vtab *)pVtabCurs
2a30: 6f 72 2d 3e 70 56 74 61 62 3b 0a 20 20 73 71 6c  or->pVtab;.  sql
2a40: 69 74 65 33 20 2a 64 62 20 3d 20 70 56 74 61 62  ite3 *db = pVtab
2a50: 2d 3e 64 62 3b 0a 0a 20 20 61 70 70 65 6e 64 54  ->db;..  appendT
2a60: 6f 45 63 68 6f 4d 6f 64 75 6c 65 28 70 56 74 61  oEchoModule(pVta
2a70: 62 2d 3e 69 6e 74 65 72 70 2c 20 22 78 46 69 6c  b->interp, "xFil
2a80: 74 65 72 22 29 3b 0a 20 20 61 70 70 65 6e 64 54  ter");.  appendT
2a90: 6f 45 63 68 6f 4d 6f 64 75 6c 65 28 70 56 74 61  oEchoModule(pVta
2aa0: 62 2d 3e 69 6e 74 65 72 70 2c 20 69 64 78 53 74  b->interp, idxSt
2ab0: 72 29 3b 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69  r);.  for(i=0; i
2ac0: 3c 61 72 67 63 3b 20 69 2b 2b 29 7b 0a 20 20 20  <argc; i++){.   
2ad0: 20 61 70 70 65 6e 64 54 6f 45 63 68 6f 4d 6f 64   appendToEchoMod
2ae0: 75 6c 65 28 70 56 74 61 62 2d 3e 69 6e 74 65 72  ule(pVtab->inter
2af0: 70 2c 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65  p, sqlite3_value
2b00: 5f 74 65 78 74 28 61 72 67 76 5b 69 5d 29 29 3b  _text(argv[i]));
2b10: 0a 20 20 7d 0a 0a 20 20 61 73 73 65 72 74 28 20  .  }..  assert( 
2b20: 69 64 78 4e 75 6d 3d 3d 68 61 73 68 53 74 72 69  idxNum==hashStri
2b30: 6e 67 28 69 64 78 53 74 72 29 20 29 3b 0a 20 20  ng(idxStr) );.  
2b40: 73 71 6c 69 74 65 33 5f 66 69 6e 61 6c 69 7a 65  sqlite3_finalize
2b50: 28 70 43 75 72 2d 3e 70 53 74 6d 74 29 3b 0a 20  (pCur->pStmt);. 
2b60: 20 70 43 75 72 2d 3e 70 53 74 6d 74 20 3d 20 30   pCur->pStmt = 0
2b70: 3b 0a 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33  ;.  rc = sqlite3
2b80: 5f 70 72 65 70 61 72 65 28 64 62 2c 20 69 64 78  _prepare(db, idx
2b90: 53 74 72 2c 20 2d 31 2c 20 26 70 43 75 72 2d 3e  Str, -1, &pCur->
2ba0: 70 53 74 6d 74 2c 20 30 29 3b 0a 20 20 61 73 73  pStmt, 0);.  ass
2bb0: 65 72 74 28 20 70 43 75 72 2d 3e 70 53 74 6d 74  ert( pCur->pStmt
2bc0: 20 7c 7c 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f   || rc!=SQLITE_O
2bd0: 4b 20 29 3b 0a 20 20 66 6f 72 28 69 3d 30 3b 20  K );.  for(i=0; 
2be0: 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26  rc==SQLITE_OK &&
2bf0: 20 69 3c 61 72 67 63 3b 20 69 2b 2b 29 7b 0a 20   i<argc; i++){. 
2c00: 20 20 20 73 77 69 74 63 68 28 20 73 71 6c 69 74     switch( sqlit
2c10: 65 33 5f 76 61 6c 75 65 5f 74 79 70 65 28 61 72  e3_value_type(ar
2c20: 67 76 5b 69 5d 29 20 29 7b 0a 20 20 20 20 20 20  gv[i]) ){.      
2c30: 63 61 73 65 20 53 51 4c 49 54 45 5f 49 4e 54 45  case SQLITE_INTE
2c40: 47 45 52 3a 20 7b 0a 20 20 20 20 20 20 20 20 73  GER: {.        s
2c50: 71 6c 69 74 65 33 5f 62 69 6e 64 5f 69 6e 74 36  qlite3_bind_int6
2c60: 34 28 70 43 75 72 2d 3e 70 53 74 6d 74 2c 20 69  4(pCur->pStmt, i
2c70: 2b 31 2c 20 73 71 6c 69 74 65 33 5f 76 61 6c 75  +1, sqlite3_valu
2c80: 65 5f 69 6e 74 36 34 28 61 72 67 76 5b 69 5d 29  e_int64(argv[i])
2c90: 29 3b 0a 20 20 20 20 20 20 20 20 62 72 65 61 6b  );.        break
2ca0: 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20  ;.      }.      
2cb0: 63 61 73 65 20 53 51 4c 49 54 45 5f 46 4c 4f 41  case SQLITE_FLOA
2cc0: 54 3a 20 7b 0a 20 20 20 20 20 20 20 20 73 71 6c  T: {.        sql
2cd0: 69 74 65 33 5f 62 69 6e 64 5f 64 6f 75 62 6c 65  ite3_bind_double
2ce0: 28 70 43 75 72 2d 3e 70 53 74 6d 74 2c 20 69 2b  (pCur->pStmt, i+
2cf0: 31 2c 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65  1, sqlite3_value
2d00: 5f 64 6f 75 62 6c 65 28 61 72 67 76 5b 69 5d 29  _double(argv[i])
2d10: 29 3b 0a 20 20 20 20 20 20 20 20 62 72 65 61 6b  );.        break
2d20: 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20  ;.      }.      
2d30: 63 61 73 65 20 53 51 4c 49 54 45 5f 4e 55 4c 4c  case SQLITE_NULL
2d40: 3a 20 7b 0a 20 20 20 20 20 20 20 20 73 71 6c 69  : {.        sqli
2d50: 74 65 33 5f 62 69 6e 64 5f 6e 75 6c 6c 28 70 43  te3_bind_null(pC
2d60: 75 72 2d 3e 70 53 74 6d 74 2c 20 69 2b 31 29 3b  ur->pStmt, i+1);
2d70: 0a 20 20 20 20 20 20 20 20 62 72 65 61 6b 3b 0a  .        break;.
2d80: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 63 61        }.      ca
2d90: 73 65 20 53 51 4c 49 54 45 5f 54 45 58 54 3a 20  se SQLITE_TEXT: 
2da0: 7b 0a 20 20 20 20 20 20 20 20 73 71 6c 69 74 65  {.        sqlite
2db0: 33 5f 62 69 6e 64 5f 74 65 78 74 28 70 43 75 72  3_bind_text(pCur
2dc0: 2d 3e 70 53 74 6d 74 2c 20 69 2b 31 2c 20 73 71  ->pStmt, i+1, sq
2dd0: 6c 69 74 65 33 5f 76 61 6c 75 65 5f 74 65 78 74  lite3_value_text
2de0: 28 61 72 67 76 5b 69 5d 29 2c 0a 20 20 20 20 20  (argv[i]),.     
2df0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2e00: 20 20 20 20 20 73 71 6c 69 74 65 33 5f 76 61 6c       sqlite3_val
2e10: 75 65 5f 62 79 74 65 73 28 61 72 67 76 5b 69 5d  ue_bytes(argv[i]
2e20: 29 2c 20 53 51 4c 49 54 45 5f 54 52 41 4e 53 49  ), SQLITE_TRANSI
2e30: 45 4e 54 29 3b 0a 20 20 20 20 20 20 20 20 62 72  ENT);.        br
2e40: 65 61 6b 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20  eak;.      }.   
2e50: 20 20 20 63 61 73 65 20 53 51 4c 49 54 45 5f 42     case SQLITE_B
2e60: 4c 4f 42 3a 20 7b 0a 20 20 20 20 20 20 20 20 73  LOB: {.        s
2e70: 71 6c 69 74 65 33 5f 62 69 6e 64 5f 62 6c 6f 62  qlite3_bind_blob
2e80: 28 70 43 75 72 2d 3e 70 53 74 6d 74 2c 20 69 2b  (pCur->pStmt, i+
2e90: 31 2c 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65  1, sqlite3_value
2ea0: 5f 62 6c 6f 62 28 61 72 67 76 5b 69 5d 29 2c 0a  _blob(argv[i]),.
2eb0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2ec0: 20 20 20 20 20 20 20 20 20 20 73 71 6c 69 74 65            sqlite
2ed0: 33 5f 76 61 6c 75 65 5f 62 79 74 65 73 28 61 72  3_value_bytes(ar
2ee0: 67 76 5b 69 5d 29 2c 20 53 51 4c 49 54 45 5f 54  gv[i]), SQLITE_T
2ef0: 52 41 4e 53 49 45 4e 54 29 3b 0a 20 20 20 20 20  RANSIENT);.     
2f00: 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20     break;.      
2f10: 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 69 66  }.    }.  }.  if
2f20: 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
2f30: 29 7b 0a 20 20 20 20 72 63 20 3d 20 65 63 68 6f  ){.    rc = echo
2f40: 4e 65 78 74 28 70 56 74 61 62 43 75 72 73 6f 72  Next(pVtabCursor
2f50: 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  );.  }else{.    
2f60: 61 73 73 65 72 74 28 20 21 70 43 75 72 2d 3e 70  assert( !pCur->p
2f70: 53 74 6d 74 20 29 3b 0a 20 20 7d 0a 0a 20 20 72  Stmt );.  }..  r
2f80: 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a  eturn rc;.}../*.
2f90: 2a 2a 20 54 68 65 20 65 63 68 6f 20 6d 6f 64 75  ** The echo modu
2fa0: 6c 65 20 69 6d 70 6c 65 6d 65 6e 74 73 20 74 68  le implements th
2fb0: 65 20 73 75 62 73 65 74 20 6f 66 20 71 75 65 72  e subset of quer
2fc0: 79 20 63 6f 6e 73 74 72 61 69 6e 74 73 20 61 6e  y constraints an
2fd0: 64 20 73 6f 72 74 0a 2a 2a 20 6f 72 64 65 72 73  d sort.** orders
2fe0: 20 74 68 61 74 20 6d 61 79 20 74 61 6b 65 20 61   that may take a
2ff0: 64 76 61 6e 74 61 67 65 20 6f 66 20 53 51 4c 69  dvantage of SQLi
3000: 74 65 20 69 6e 64 69 63 65 73 20 6f 6e 20 74 68  te indices on th
3010: 65 20 75 6e 64 65 72 6c 79 69 6e 67 0a 2a 2a 20  e underlying.** 
3020: 72 65 61 6c 20 74 61 62 6c 65 2e 20 46 6f 72 20  real table. For 
3030: 65 78 61 6d 70 6c 65 2c 20 69 66 20 74 68 65 20  example, if the 
3040: 72 65 61 6c 20 74 61 62 6c 65 20 69 73 20 64 65  real table is de
3050: 63 6c 61 72 65 64 20 61 73 3a 0a 2a 2a 0a 2a 2a  clared as:.**.**
3060: 20 20 20 20 20 43 52 45 41 54 45 20 54 41 42 4c       CREATE TABL
3070: 45 20 72 65 61 6c 28 61 2c 20 62 2c 20 63 29 3b  E real(a, b, c);
3080: 0a 2a 2a 20 20 20 20 20 43 52 45 41 54 45 20 49  .**     CREATE I
3090: 4e 44 45 58 20 72 65 61 6c 5f 69 6e 64 65 78 20  NDEX real_index 
30a0: 4f 4e 20 72 65 61 6c 28 62 29 3b 0a 2a 2a 0a 2a  ON real(b);.**.*
30b0: 2a 20 74 68 65 6e 20 74 68 65 20 65 63 68 6f 20  * then the echo 
30c0: 6d 6f 64 75 6c 65 20 68 61 6e 64 6c 65 73 20 57  module handles W
30d0: 48 45 52 45 20 6f 72 20 4f 52 44 45 52 20 42 59  HERE or ORDER BY
30e0: 20 63 6c 61 75 73 65 73 20 74 68 61 74 20 72 65   clauses that re
30f0: 66 65 72 0a 2a 2a 20 74 6f 20 74 68 65 20 63 6f  fer.** to the co
3100: 6c 75 6d 6e 20 22 62 22 2c 20 62 75 74 20 6e 6f  lumn "b", but no
3110: 74 20 22 61 22 20 6f 72 20 22 63 22 2e 20 49 66  t "a" or "c". If
3120: 20 61 20 6d 75 6c 74 69 2d 63 6f 6c 75 6d 6e 20   a multi-column 
3130: 69 6e 64 65 78 20 69 73 0a 2a 2a 20 70 72 65 73  index is.** pres
3140: 65 6e 74 2c 20 6f 6e 6c 79 20 69 74 27 73 20 6c  ent, only it's l
3150: 65 66 74 20 6d 6f 73 74 20 63 6f 6c 75 6d 6e 20  eft most column 
3160: 69 73 20 63 6f 6e 73 69 64 65 72 65 64 2e 20 0a  is considered. .
3170: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 65 63  */.static int ec
3180: 68 6f 42 65 73 74 49 6e 64 65 78 28 73 71 6c 69  hoBestIndex(sqli
3190: 74 65 33 5f 76 74 61 62 20 2a 74 61 62 2c 20 73  te3_vtab *tab, s
31a0: 71 6c 69 74 65 33 5f 69 6e 64 65 78 5f 69 6e 66  qlite3_index_inf
31b0: 6f 20 2a 70 49 64 78 49 6e 66 6f 29 7b 0a 20 20  o *pIdxInfo){.  
31c0: 69 6e 74 20 69 69 3b 0a 20 20 63 68 61 72 20 2a  int ii;.  char *
31d0: 7a 51 75 65 72 79 20 3d 20 30 3b 0a 20 20 63 68  zQuery = 0;.  ch
31e0: 61 72 20 2a 7a 4e 65 77 3b 0a 20 20 69 6e 74 20  ar *zNew;.  int 
31f0: 6e 41 72 67 20 3d 20 30 3b 0a 20 20 63 6f 6e 73  nArg = 0;.  cons
3200: 74 20 63 68 61 72 20 2a 7a 53 65 70 20 3d 20 22  t char *zSep = "
3210: 57 48 45 52 45 22 3b 0a 20 20 65 63 68 6f 5f 76  WHERE";.  echo_v
3220: 74 61 62 20 2a 70 56 74 61 62 20 3d 20 28 65 63  tab *pVtab = (ec
3230: 68 6f 5f 76 74 61 62 20 2a 29 74 61 62 3b 0a 20  ho_vtab *)tab;. 
3240: 20 73 71 6c 69 74 65 33 5f 73 74 6d 74 20 2a 70   sqlite3_stmt *p
3250: 53 74 6d 74 20 3d 20 30 3b 0a 0a 20 20 69 6e 74  Stmt = 0;..  int
3260: 20 6e 52 6f 77 3b 0a 20 20 69 6e 74 20 75 73 65   nRow;.  int use
3270: 49 64 78 20 3d 20 30 3b 0a 20 20 69 6e 74 20 72  Idx = 0;.  int r
3280: 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 0a  c = SQLITE_OK;..
3290: 20 20 2f 2a 20 44 65 74 65 72 6d 69 6e 65 20 74    /* Determine t
32a0: 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 72 6f 77  he number of row
32b0: 73 20 69 6e 20 74 68 65 20 74 61 62 6c 65 20 61  s in the table a
32c0: 6e 64 20 73 74 6f 72 65 20 74 68 69 73 20 76 61  nd store this va
32d0: 6c 75 65 20 69 6e 20 6c 6f 63 61 6c 0a 20 20 2a  lue in local.  *
32e0: 2a 20 76 61 72 69 61 62 6c 65 20 6e 52 6f 77 2e  * variable nRow.
32f0: 20 54 68 65 20 27 65 73 74 69 6d 61 74 65 64 2d   The 'estimated-
3300: 63 6f 73 74 27 20 6f 66 20 74 68 65 20 73 63 61  cost' of the sca
3310: 6e 20 77 69 6c 6c 20 62 65 20 74 68 65 20 6e 75  n will be the nu
3320: 6d 62 65 72 20 6f 66 0a 20 20 2a 2a 20 72 6f 77  mber of.  ** row
3330: 73 20 69 6e 20 74 68 65 20 74 61 62 6c 65 20 66  s in the table f
3340: 6f 72 20 61 20 6c 69 6e 65 61 72 20 73 63 61 6e  or a linear scan
3350: 2c 20 6f 72 20 74 68 65 20 6c 6f 67 20 28 62 61  , or the log (ba
3360: 73 65 20 32 29 20 6f 66 20 74 68 65 20 0a 20 20  se 2) of the .  
3370: 2a 2a 20 6e 75 6d 62 65 72 20 6f 66 20 72 6f 77  ** number of row
3380: 73 20 69 66 20 74 68 65 20 70 72 6f 70 6f 73 65  s if the propose
3390: 64 20 73 63 61 6e 20 75 73 65 73 20 61 6e 20 69  d scan uses an i
33a0: 6e 64 65 78 2e 20 20 0a 20 20 2a 2f 0a 20 20 7a  ndex.  .  */.  z
33b0: 51 75 65 72 79 20 3d 20 73 71 6c 69 74 65 33 5f  Query = sqlite3_
33c0: 6d 70 72 69 6e 74 66 28 22 53 45 4c 45 43 54 20  mprintf("SELECT 
33d0: 63 6f 75 6e 74 28 2a 29 20 46 52 4f 4d 20 25 51  count(*) FROM %Q
33e0: 22 2c 20 70 56 74 61 62 2d 3e 7a 54 61 62 6c 65  ", pVtab->zTable
33f0: 4e 61 6d 65 29 3b 0a 20 20 72 63 20 3d 20 73 71  Name);.  rc = sq
3400: 6c 69 74 65 33 5f 70 72 65 70 61 72 65 28 70 56  lite3_prepare(pV
3410: 74 61 62 2d 3e 64 62 2c 20 7a 51 75 65 72 79 2c  tab->db, zQuery,
3420: 20 2d 31 2c 20 26 70 53 74 6d 74 2c 20 30 29 3b   -1, &pStmt, 0);
3430: 0a 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54  .  if( rc!=SQLIT
3440: 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 72 65 74 75  E_OK ){.    retu
3450: 72 6e 20 72 63 3b 0a 20 20 7d 0a 20 20 73 71 6c  rn rc;.  }.  sql
3460: 69 74 65 33 5f 73 74 65 70 28 70 53 74 6d 74 29  ite3_step(pStmt)
3470: 3b 0a 20 20 6e 52 6f 77 20 3d 20 73 71 6c 69 74  ;.  nRow = sqlit
3480: 65 33 5f 63 6f 6c 75 6d 6e 5f 69 6e 74 28 70 53  e3_column_int(pS
3490: 74 6d 74 2c 20 30 29 3b 0a 20 20 72 63 20 3d 20  tmt, 0);.  rc = 
34a0: 73 71 6c 69 74 65 33 5f 66 69 6e 61 6c 69 7a 65  sqlite3_finalize
34b0: 28 70 53 74 6d 74 29 3b 0a 20 20 69 66 28 20 72  (pStmt);.  if( r
34c0: 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a  c!=SQLITE_OK ){.
34d0: 20 20 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 20      return rc;. 
34e0: 20 7d 0a 0a 20 20 7a 51 75 65 72 79 20 3d 20 73   }..  zQuery = s
34f0: 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 22  qlite3_mprintf("
3500: 53 45 4c 45 43 54 20 72 6f 77 69 64 2c 20 2a 20  SELECT rowid, * 
3510: 46 52 4f 4d 20 25 51 22 2c 20 70 56 74 61 62 2d  FROM %Q", pVtab-
3520: 3e 7a 54 61 62 6c 65 4e 61 6d 65 29 3b 0a 20 20  >zTableName);.  
3530: 66 6f 72 28 69 69 3d 30 3b 20 69 69 3c 70 49 64  for(ii=0; ii<pId
3540: 78 49 6e 66 6f 2d 3e 6e 43 6f 6e 73 74 72 61 69  xInfo->nConstrai
3550: 6e 74 3b 20 69 69 2b 2b 29 7b 0a 20 20 20 20 63  nt; ii++){.    c
3560: 6f 6e 73 74 20 73 74 72 75 63 74 20 73 71 6c 69  onst struct sqli
3570: 74 65 33 5f 69 6e 64 65 78 5f 63 6f 6e 73 74 72  te3_index_constr
3580: 61 69 6e 74 20 2a 70 43 6f 6e 73 74 72 61 69 6e  aint *pConstrain
3590: 74 3b 0a 20 20 20 20 73 74 72 75 63 74 20 73 71  t;.    struct sq
35a0: 6c 69 74 65 33 5f 69 6e 64 65 78 5f 63 6f 6e 73  lite3_index_cons
35b0: 74 72 61 69 6e 74 5f 75 73 61 67 65 20 2a 70 55  traint_usage *pU
35c0: 73 61 67 65 3b 0a 0a 20 20 20 20 70 43 6f 6e 73  sage;..    pCons
35d0: 74 72 61 69 6e 74 20 3d 20 26 70 49 64 78 49 6e  traint = &pIdxIn
35e0: 66 6f 2d 3e 61 43 6f 6e 73 74 72 61 69 6e 74 5b  fo->aConstraint[
35f0: 69 69 5d 3b 0a 20 20 20 20 70 55 73 61 67 65 20  ii];.    pUsage 
3600: 3d 20 26 70 49 64 78 49 6e 66 6f 2d 3e 61 43 6f  = &pIdxInfo->aCo
3610: 6e 73 74 72 61 69 6e 74 55 73 61 67 65 5b 69 69  nstraintUsage[ii
3620: 5d 3b 0a 0a 20 20 20 20 69 6e 74 20 69 43 6f 6c  ];..    int iCol
3630: 20 3d 20 70 43 6f 6e 73 74 72 61 69 6e 74 2d 3e   = pConstraint->
3640: 69 43 6f 6c 75 6d 6e 3b 0a 20 20 20 20 69 66 28  iColumn;.    if(
3650: 20 70 56 74 61 62 2d 3e 61 49 6e 64 65 78 5b 69   pVtab->aIndex[i
3660: 43 6f 6c 5d 20 29 7b 0a 20 20 20 20 20 20 63 68  Col] ){.      ch
3670: 61 72 20 2a 7a 43 6f 6c 20 3d 20 70 56 74 61 62  ar *zCol = pVtab
3680: 2d 3e 61 43 6f 6c 5b 69 43 6f 6c 5d 3b 0a 20 20  ->aCol[iCol];.  
3690: 20 20 20 20 63 68 61 72 20 2a 7a 4f 70 20 3d 20      char *zOp = 
36a0: 30 3b 0a 20 20 20 20 20 20 75 73 65 49 64 78 20  0;.      useIdx 
36b0: 3d 20 31 3b 0a 20 20 20 20 20 20 69 66 28 20 69  = 1;.      if( i
36c0: 43 6f 6c 3c 30 20 29 7b 0a 20 20 20 20 20 20 20  Col<0 ){.       
36d0: 20 7a 43 6f 6c 20 3d 20 22 72 6f 77 69 64 22 3b   zCol = "rowid";
36e0: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 73  .      }.      s
36f0: 77 69 74 63 68 28 20 70 43 6f 6e 73 74 72 61 69  witch( pConstrai
3700: 6e 74 2d 3e 6f 70 20 29 7b 0a 20 20 20 20 20 20  nt->op ){.      
3710: 20 20 63 61 73 65 20 53 51 4c 49 54 45 5f 49 4e    case SQLITE_IN
3720: 44 45 58 5f 43 4f 4e 53 54 52 41 49 4e 54 5f 45  DEX_CONSTRAINT_E
3730: 51 3a 0a 20 20 20 20 20 20 20 20 20 20 7a 4f 70  Q:.          zOp
3740: 20 3d 20 22 3d 22 3b 20 62 72 65 61 6b 3b 0a 20   = "="; break;. 
3750: 20 20 20 20 20 20 20 63 61 73 65 20 53 51 4c 49         case SQLI
3760: 54 45 5f 49 4e 44 45 58 5f 43 4f 4e 53 54 52 41  TE_INDEX_CONSTRA
3770: 49 4e 54 5f 4c 54 3a 0a 20 20 20 20 20 20 20 20  INT_LT:.        
3780: 20 20 7a 4f 70 20 3d 20 22 3c 22 3b 20 62 72 65    zOp = "<"; bre
3790: 61 6b 3b 0a 20 20 20 20 20 20 20 20 63 61 73 65  ak;.        case
37a0: 20 53 51 4c 49 54 45 5f 49 4e 44 45 58 5f 43 4f   SQLITE_INDEX_CO
37b0: 4e 53 54 52 41 49 4e 54 5f 47 54 3a 0a 20 20 20  NSTRAINT_GT:.   
37c0: 20 20 20 20 20 20 20 7a 4f 70 20 3d 20 22 3e 22         zOp = ">"
37d0: 3b 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 20  ; break;.       
37e0: 20 63 61 73 65 20 53 51 4c 49 54 45 5f 49 4e 44   case SQLITE_IND
37f0: 45 58 5f 43 4f 4e 53 54 52 41 49 4e 54 5f 4c 45  EX_CONSTRAINT_LE
3800: 3a 0a 20 20 20 20 20 20 20 20 20 20 7a 4f 70 20  :.          zOp 
3810: 3d 20 22 3c 3d 22 3b 20 62 72 65 61 6b 3b 0a 20  = "<="; break;. 
3820: 20 20 20 20 20 20 20 63 61 73 65 20 53 51 4c 49         case SQLI
3830: 54 45 5f 49 4e 44 45 58 5f 43 4f 4e 53 54 52 41  TE_INDEX_CONSTRA
3840: 49 4e 54 5f 47 45 3a 0a 20 20 20 20 20 20 20 20  INT_GE:.        
3850: 20 20 7a 4f 70 20 3d 20 22 3e 3d 22 3b 20 62 72    zOp = ">="; br
3860: 65 61 6b 3b 0a 20 20 20 20 20 20 20 20 63 61 73  eak;.        cas
3870: 65 20 53 51 4c 49 54 45 5f 49 4e 44 45 58 5f 43  e SQLITE_INDEX_C
3880: 4f 4e 53 54 52 41 49 4e 54 5f 4d 41 54 43 48 3a  ONSTRAINT_MATCH:
3890: 0a 20 20 20 20 20 20 20 20 20 20 7a 4f 70 20 3d  .          zOp =
38a0: 20 22 4c 49 4b 45 22 3b 20 62 72 65 61 6b 3b 0a   "LIKE"; break;.
38b0: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 69 66        }.      if
38c0: 28 20 7a 4f 70 5b 30 5d 3d 3d 27 4c 27 20 29 7b  ( zOp[0]=='L' ){
38d0: 0a 20 20 20 20 20 20 20 20 7a 4e 65 77 20 3d 20  .        zNew = 
38e0: 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28  sqlite3_mprintf(
38f0: 22 25 73 20 25 73 20 25 73 20 4c 49 4b 45 20 28  "%s %s %s LIKE (
3900: 53 45 4c 45 43 54 20 27 25 25 27 7c 7c 3f 7c 7c  SELECT '%%'||?||
3910: 27 25 25 27 29 22 2c 20 0a 20 20 20 20 20 20 20  '%%')", .       
3920: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3930: 20 20 20 20 20 20 20 20 7a 51 75 65 72 79 2c 20          zQuery, 
3940: 7a 53 65 70 2c 20 7a 43 6f 6c 29 3b 0a 20 20 20  zSep, zCol);.   
3950: 20 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20     } else {.    
3960: 20 20 20 20 7a 4e 65 77 20 3d 20 73 71 6c 69 74      zNew = sqlit
3970: 65 33 5f 6d 70 72 69 6e 74 66 28 22 25 73 20 25  e3_mprintf("%s %
3980: 73 20 25 73 20 25 73 20 3f 22 2c 20 7a 51 75 65  s %s %s ?", zQue
3990: 72 79 2c 20 7a 53 65 70 2c 20 7a 43 6f 6c 2c 20  ry, zSep, zCol, 
39a0: 7a 4f 70 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20  zOp);.      }.  
39b0: 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65      sqlite3_free
39c0: 28 7a 51 75 65 72 79 29 3b 0a 20 20 20 20 20 20  (zQuery);.      
39d0: 7a 51 75 65 72 79 20 3d 20 7a 4e 65 77 3b 0a 20  zQuery = zNew;. 
39e0: 20 20 20 20 20 7a 53 65 70 20 3d 20 22 41 4e 44       zSep = "AND
39f0: 22 3b 0a 20 20 20 20 20 20 70 55 73 61 67 65 2d  ";.      pUsage-
3a00: 3e 61 72 67 76 49 6e 64 65 78 20 3d 20 2b 2b 6e  >argvIndex = ++n
3a10: 41 72 67 3b 0a 20 20 20 20 20 20 70 55 73 61 67  Arg;.      pUsag
3a20: 65 2d 3e 6f 6d 69 74 20 3d 20 31 3b 0a 20 20 20  e->omit = 1;.   
3a30: 20 7d 0a 20 20 7d 0a 0a 20 20 2f 2a 20 49 66 20   }.  }..  /* If 
3a40: 74 68 65 72 65 20 69 73 20 6f 6e 6c 79 20 6f 6e  there is only on
3a50: 65 20 74 65 72 6d 20 69 6e 20 74 68 65 20 4f 52  e term in the OR
3a60: 44 45 52 20 42 59 20 63 6c 61 75 73 65 2c 20 61  DER BY clause, a
3a70: 6e 64 20 69 74 20 69 73 0a 20 20 2a 2a 20 6f 6e  nd it is.  ** on
3a80: 20 61 20 63 6f 6c 75 6d 6e 20 74 68 61 74 20 74   a column that t
3a90: 68 69 73 20 76 69 72 74 75 61 6c 20 74 61 62 6c  his virtual tabl
3aa0: 65 20 68 61 73 20 61 6e 20 69 6e 64 65 78 20 66  e has an index f
3ab0: 6f 72 2c 20 74 68 65 6e 20 63 6f 6e 73 75 6d 65  or, then consume
3ac0: 20 0a 20 20 2a 2a 20 74 68 65 20 4f 52 44 45 52   .  ** the ORDER
3ad0: 20 42 59 20 63 6c 61 75 73 65 2e 0a 20 20 2a 2f   BY clause..  */
3ae0: 0a 20 20 69 66 28 20 70 49 64 78 49 6e 66 6f 2d  .  if( pIdxInfo-
3af0: 3e 6e 4f 72 64 65 72 42 79 3d 3d 31 20 26 26 20  >nOrderBy==1 && 
3b00: 70 56 74 61 62 2d 3e 61 49 6e 64 65 78 5b 70 49  pVtab->aIndex[pI
3b10: 64 78 49 6e 66 6f 2d 3e 61 4f 72 64 65 72 42 79  dxInfo->aOrderBy
3b20: 2d 3e 69 43 6f 6c 75 6d 6e 5d 20 29 7b 0a 20 20  ->iColumn] ){.  
3b30: 20 20 63 68 61 72 20 2a 7a 43 6f 6c 20 3d 20 70    char *zCol = p
3b40: 56 74 61 62 2d 3e 61 43 6f 6c 5b 70 49 64 78 49  Vtab->aCol[pIdxI
3b50: 6e 66 6f 2d 3e 61 4f 72 64 65 72 42 79 2d 3e 69  nfo->aOrderBy->i
3b60: 43 6f 6c 75 6d 6e 5d 3b 0a 20 20 20 20 63 68 61  Column];.    cha
3b70: 72 20 2a 7a 44 69 72 20 3d 20 70 49 64 78 49 6e  r *zDir = pIdxIn
3b80: 66 6f 2d 3e 61 4f 72 64 65 72 42 79 2d 3e 64 65  fo->aOrderBy->de
3b90: 73 63 3f 22 44 45 53 43 22 3a 22 41 53 43 22 3b  sc?"DESC":"ASC";
3ba0: 0a 20 20 20 20 7a 4e 65 77 20 3d 20 73 71 6c 69  .    zNew = sqli
3bb0: 74 65 33 5f 6d 70 72 69 6e 74 66 28 22 25 73 20  te3_mprintf("%s 
3bc0: 4f 52 44 45 52 20 42 59 20 25 73 20 25 73 22 2c  ORDER BY %s %s",
3bd0: 20 7a 51 75 65 72 79 2c 20 7a 43 6f 6c 2c 20 7a   zQuery, zCol, z
3be0: 44 69 72 29 3b 0a 20 20 20 20 73 71 6c 69 74 65  Dir);.    sqlite
3bf0: 33 5f 66 72 65 65 28 7a 51 75 65 72 79 29 3b 0a  3_free(zQuery);.
3c00: 20 20 20 20 7a 51 75 65 72 79 20 3d 20 7a 4e 65      zQuery = zNe
3c10: 77 3b 0a 20 20 20 20 70 49 64 78 49 6e 66 6f 2d  w;.    pIdxInfo-
3c20: 3e 6f 72 64 65 72 42 79 43 6f 6e 73 75 6d 65 64  >orderByConsumed
3c30: 20 3d 20 31 3b 0a 20 20 7d 0a 0a 20 20 61 70 70   = 1;.  }..  app
3c40: 65 6e 64 54 6f 45 63 68 6f 4d 6f 64 75 6c 65 28  endToEchoModule(
3c50: 70 56 74 61 62 2d 3e 69 6e 74 65 72 70 2c 20 22  pVtab->interp, "
3c60: 78 42 65 73 74 49 6e 64 65 78 22 29 3b 3b 0a 20  xBestIndex");;. 
3c70: 20 61 70 70 65 6e 64 54 6f 45 63 68 6f 4d 6f 64   appendToEchoMod
3c80: 75 6c 65 28 70 56 74 61 62 2d 3e 69 6e 74 65 72  ule(pVtab->inter
3c90: 70 2c 20 7a 51 75 65 72 79 29 3b 0a 0a 20 20 70  p, zQuery);..  p
3ca0: 49 64 78 49 6e 66 6f 2d 3e 69 64 78 4e 75 6d 20  IdxInfo->idxNum 
3cb0: 3d 20 68 61 73 68 53 74 72 69 6e 67 28 7a 51 75  = hashString(zQu
3cc0: 65 72 79 29 3b 0a 20 20 70 49 64 78 49 6e 66 6f  ery);.  pIdxInfo
3cd0: 2d 3e 69 64 78 53 74 72 20 3d 20 7a 51 75 65 72  ->idxStr = zQuer
3ce0: 79 3b 0a 20 20 70 49 64 78 49 6e 66 6f 2d 3e 6e  y;.  pIdxInfo->n
3cf0: 65 65 64 54 6f 46 72 65 65 49 64 78 53 74 72 20  eedToFreeIdxStr 
3d00: 3d 20 31 3b 0a 20 20 69 66 28 20 75 73 65 49 64  = 1;.  if( useId
3d10: 78 20 29 7b 0a 20 20 20 20 2f 2a 20 41 70 70 72  x ){.    /* Appr
3d20: 6f 78 69 6d 61 74 69 6f 6e 20 6f 66 20 6c 6f 67  oximation of log
3d30: 32 28 6e 52 6f 77 29 2e 20 2a 2f 0a 20 20 20 20  2(nRow). */.    
3d40: 66 6f 72 28 20 69 69 3d 30 3b 20 69 69 3c 28 73  for( ii=0; ii<(s
3d50: 69 7a 65 6f 66 28 69 6e 74 29 2a 38 29 3b 20 69  izeof(int)*8); i
3d60: 69 2b 2b 20 29 7b 0a 20 20 20 20 20 20 69 66 28  i++ ){.      if(
3d70: 20 6e 52 6f 77 20 26 20 28 31 3c 3c 69 69 29 20   nRow & (1<<ii) 
3d80: 29 7b 0a 20 20 20 20 20 20 20 20 70 49 64 78 49  ){.        pIdxI
3d90: 6e 66 6f 2d 3e 65 73 74 69 6d 61 74 65 64 43 6f  nfo->estimatedCo
3da0: 73 74 20 3d 20 28 64 6f 75 62 6c 65 29 69 69 3b  st = (double)ii;
3db0: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20  .      }.    }. 
3dc0: 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20 70 49   } else {.    pI
3dd0: 64 78 49 6e 66 6f 2d 3e 65 73 74 69 6d 61 74 65  dxInfo->estimate
3de0: 64 43 6f 73 74 20 3d 20 28 64 6f 75 62 6c 65 29  dCost = (double)
3df0: 6e 52 6f 77 3b 0a 20 20 7d 0a 20 20 72 65 74 75  nRow;.  }.  retu
3e00: 72 6e 20 72 63 3b 0a 7d 0a 0a 73 74 61 74 69 63  rn rc;.}..static
3e10: 20 76 6f 69 64 20 73 74 72 69 6e 67 5f 63 6f 6e   void string_con
3e20: 63 61 74 28 63 68 61 72 20 2a 2a 70 7a 53 74 72  cat(char **pzStr
3e30: 2c 20 63 68 61 72 20 2a 7a 41 70 70 65 6e 64 2c  , char *zAppend,
3e40: 20 69 6e 74 20 64 6f 46 72 65 65 29 7b 0a 20 20   int doFree){.  
3e50: 63 68 61 72 20 2a 7a 49 6e 20 3d 20 2a 70 7a 53  char *zIn = *pzS
3e60: 74 72 3b 0a 20 20 69 66 28 20 7a 49 6e 20 29 7b  tr;.  if( zIn ){
3e70: 0a 20 20 20 20 63 68 61 72 20 2a 7a 54 65 6d 70  .    char *zTemp
3e80: 20 3d 20 7a 49 6e 3b 0a 20 20 20 20 7a 49 6e 20   = zIn;.    zIn 
3e90: 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74  = sqlite3_mprint
3ea0: 66 28 22 25 73 25 73 22 2c 20 7a 49 6e 2c 20 7a  f("%s%s", zIn, z
3eb0: 41 70 70 65 6e 64 29 3b 0a 20 20 20 20 73 71 6c  Append);.    sql
3ec0: 69 74 65 33 5f 66 72 65 65 28 7a 54 65 6d 70 29  ite3_free(zTemp)
3ed0: 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 7a  ;.  }else{.    z
3ee0: 49 6e 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72  In = sqlite3_mpr
3ef0: 69 6e 74 66 28 22 25 73 22 2c 20 7a 41 70 70 65  intf("%s", zAppe
3f00: 6e 64 29 3b 0a 20 20 7d 0a 20 20 2a 70 7a 53 74  nd);.  }.  *pzSt
3f10: 72 20 3d 20 7a 49 6e 3b 0a 20 20 69 66 28 20 64  r = zIn;.  if( d
3f20: 6f 46 72 65 65 20 29 7b 0a 20 20 20 20 73 71 6c  oFree ){.    sql
3f30: 69 74 65 33 5f 66 72 65 65 28 7a 41 70 70 65 6e  ite3_free(zAppen
3f40: 64 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a  d);.  }.}../*.**
3f50: 20 20 20 20 61 70 44 61 74 61 5b 30 5d 20 20 61      apData[0]  a
3f60: 70 44 61 74 61 5b 31 5d 20 20 61 70 44 61 74 61  pData[1]  apData
3f70: 5b 32 2e 2e 5d 0a 2a 2a 0a 2a 2a 20 20 20 20 49  [2..].**.**    I
3f80: 4e 54 45 47 45 52 20 20 20 20 20 20 20 20 20 20  NTEGER          
3f90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3fa0: 20 20 20 20 44 45 4c 45 54 45 20 20 20 20 20 20      DELETE      
3fb0: 20 20 20 20 20 20 0a 2a 2a 0a 2a 2a 20 20 20 20        .**.**    
3fc0: 49 4e 54 45 47 45 52 20 20 20 20 4e 55 4c 4c 20  INTEGER    NULL 
3fd0: 20 20 20 20 20 20 28 6e 43 6f 6c 20 61 72 67 73        (nCol args
3fe0: 29 20 20 20 20 55 50 44 41 54 45 20 28 64 6f 20  )    UPDATE (do 
3ff0: 6e 6f 74 20 73 65 74 20 72 6f 77 69 64 29 0a 2a  not set rowid).*
4000: 2a 20 20 20 20 49 4e 54 45 47 45 52 20 20 20 20  *    INTEGER    
4010: 49 4e 54 45 47 45 52 20 20 20 20 28 6e 43 6f 6c  INTEGER    (nCol
4020: 20 61 72 67 73 29 20 20 20 20 55 50 44 41 54 45   args)    UPDATE
4030: 20 28 77 69 74 68 20 53 45 54 20 72 6f 77 69 64   (with SET rowid
4040: 20 3d 20 3c 61 72 67 31 3e 29 0a 2a 2a 0a 2a 2a   = <arg1>).**.**
4050: 20 20 20 20 4e 55 4c 4c 20 20 20 20 20 20 20 4e      NULL       N
4060: 55 4c 4c 20 20 20 20 20 20 20 28 6e 43 6f 6c 20  ULL       (nCol 
4070: 61 72 67 73 29 20 20 20 20 49 4e 53 45 52 54 20  args)    INSERT 
4080: 49 4e 54 4f 20 28 61 75 74 6f 6d 61 74 69 63 20  INTO (automatic 
4090: 72 6f 77 69 64 20 76 61 6c 75 65 29 0a 2a 2a 20  rowid value).** 
40a0: 20 20 20 4e 55 4c 4c 20 20 20 20 20 20 20 49 4e     NULL       IN
40b0: 54 45 47 45 52 20 20 20 20 28 6e 43 6f 6c 20 61  TEGER    (nCol a
40c0: 72 67 73 29 20 20 20 20 49 4e 53 45 52 54 20 28  rgs)    INSERT (
40d0: 69 6e 63 6c 2e 20 72 6f 77 69 64 20 76 61 6c 75  incl. rowid valu
40e0: 65 29 0a 2a 2a 0a 2a 2f 0a 69 6e 74 20 65 63 68  e).**.*/.int ech
40f0: 6f 55 70 64 61 74 65 28 0a 20 20 73 71 6c 69 74  oUpdate(.  sqlit
4100: 65 33 5f 76 74 61 62 20 2a 74 61 62 2c 20 0a 20  e3_vtab *tab, . 
4110: 20 69 6e 74 20 6e 44 61 74 61 2c 20 0a 20 20 73   int nData, .  s
4120: 71 6c 69 74 65 33 5f 76 61 6c 75 65 20 2a 2a 61  qlite3_value **a
4130: 70 44 61 74 61 2c 20 0a 20 20 73 71 6c 69 74 65  pData, .  sqlite
4140: 5f 69 6e 74 36 34 20 2a 70 52 6f 77 69 64 0a 29  _int64 *pRowid.)
4150: 7b 0a 20 20 65 63 68 6f 5f 76 74 61 62 20 2a 70  {.  echo_vtab *p
4160: 56 74 61 62 20 3d 20 28 65 63 68 6f 5f 76 74 61  Vtab = (echo_vta
4170: 62 20 2a 29 74 61 62 3b 0a 20 20 73 71 6c 69 74  b *)tab;.  sqlit
4180: 65 33 20 2a 64 62 20 3d 20 70 56 74 61 62 2d 3e  e3 *db = pVtab->
4190: 64 62 3b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53  db;.  int rc = S
41a0: 51 4c 49 54 45 5f 4f 4b 3b 0a 0a 20 20 73 71 6c  QLITE_OK;..  sql
41b0: 69 74 65 33 5f 73 74 6d 74 20 2a 70 53 74 6d 74  ite3_stmt *pStmt
41c0: 3b 0a 20 20 63 68 61 72 20 2a 7a 20 3d 20 30 3b  ;.  char *z = 0;
41d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
41e0: 2a 20 53 51 4c 20 73 74 61 74 65 6d 65 6e 74 20  * SQL statement 
41f0: 74 6f 20 65 78 65 63 75 74 65 20 2a 2f 0a 20 20  to execute */.  
4200: 69 6e 74 20 62 69 6e 64 41 72 67 5a 65 72 6f 20  int bindArgZero 
4210: 3d 20 30 3b 20 20 20 20 20 20 20 2f 2a 20 54 72  = 0;       /* Tr
4220: 75 65 20 74 6f 20 62 69 6e 64 20 61 70 44 61 74  ue to bind apDat
4230: 61 5b 30 5d 20 74 6f 20 73 71 6c 20 76 61 72 20  a[0] to sql var 
4240: 6e 6f 2e 20 6e 44 61 74 61 20 2a 2f 0a 20 20 69  no. nData */.  i
4250: 6e 74 20 62 69 6e 64 41 72 67 4f 6e 65 20 3d 20  nt bindArgOne = 
4260: 30 3b 20 20 20 20 20 20 20 20 2f 2a 20 54 72 75  0;        /* Tru
4270: 65 20 74 6f 20 62 69 6e 64 20 61 70 44 61 74 61  e to bind apData
4280: 5b 31 5d 20 74 6f 20 73 71 6c 20 76 61 72 20 6e  [1] to sql var n
4290: 6f 2e 20 31 20 2a 2f 0a 20 20 69 6e 74 20 69 3b  o. 1 */.  int i;
42a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
42b0: 20 20 20 20 20 2f 2a 20 43 6f 75 6e 74 65 72 20       /* Counter 
42c0: 76 61 72 69 61 62 6c 65 20 75 73 65 64 20 62 79  variable used by
42d0: 20 66 6f 72 20 6c 6f 6f 70 73 20 2a 2f 0a 0a 20   for loops */.. 
42e0: 20 61 73 73 65 72 74 28 20 6e 44 61 74 61 3d 3d   assert( nData==
42f0: 70 56 74 61 62 2d 3e 6e 43 6f 6c 2b 32 20 7c 7c  pVtab->nCol+2 ||
4300: 20 6e 44 61 74 61 3d 3d 31 20 29 3b 0a 0a 20 20   nData==1 );..  
4310: 2f 2a 20 49 66 20 61 70 44 61 74 61 5b 30 5d 20  /* If apData[0] 
4320: 69 73 20 61 6e 20 69 6e 74 65 67 65 72 20 61 6e  is an integer an
4330: 64 20 6e 44 61 74 61 3e 31 20 74 68 65 6e 20 64  d nData>1 then d
4340: 6f 20 61 6e 20 55 50 44 41 54 45 20 2a 2f 0a 20  o an UPDATE */. 
4350: 20 69 66 28 20 6e 44 61 74 61 3e 31 20 26 26 20   if( nData>1 && 
4360: 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 74 79  sqlite3_value_ty
4370: 70 65 28 61 70 44 61 74 61 5b 30 5d 29 3d 3d 53  pe(apData[0])==S
4380: 51 4c 49 54 45 5f 49 4e 54 45 47 45 52 20 29 7b  QLITE_INTEGER ){
4390: 0a 20 20 20 20 7a 20 3d 20 73 71 6c 69 74 65 33  .    z = sqlite3
43a0: 5f 6d 70 72 69 6e 74 66 28 22 55 50 44 41 54 45  _mprintf("UPDATE
43b0: 20 25 51 22 2c 20 70 56 74 61 62 2d 3e 7a 54 61   %Q", pVtab->zTa
43c0: 62 6c 65 4e 61 6d 65 29 3b 0a 20 20 20 20 63 68  bleName);.    ch
43d0: 61 72 20 2a 7a 53 65 70 20 3d 20 22 20 53 45 54  ar *zSep = " SET
43e0: 22 3b 0a 0a 20 20 20 20 62 69 6e 64 41 72 67 4f  ";..    bindArgO
43f0: 6e 65 20 3d 20 28 61 70 44 61 74 61 5b 31 5d 20  ne = (apData[1] 
4400: 26 26 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65  && sqlite3_value
4410: 5f 74 79 70 65 28 61 70 44 61 74 61 5b 31 5d 29  _type(apData[1])
4420: 3d 3d 53 51 4c 49 54 45 5f 49 4e 54 45 47 45 52  ==SQLITE_INTEGER
4430: 29 3b 0a 20 20 20 20 62 69 6e 64 41 72 67 5a 65  );.    bindArgZe
4440: 72 6f 20 3d 20 31 3b 0a 0a 20 20 20 20 69 66 28  ro = 1;..    if(
4450: 20 62 69 6e 64 41 72 67 4f 6e 65 20 29 7b 0a 20   bindArgOne ){. 
4460: 20 20 20 20 20 20 73 74 72 69 6e 67 5f 63 6f 6e        string_con
4470: 63 61 74 28 26 7a 2c 20 22 20 53 45 54 20 72 6f  cat(&z, " SET ro
4480: 77 69 64 3d 3f 31 20 22 2c 20 30 29 3b 0a 20 20  wid=?1 ", 0);.  
4490: 20 20 20 20 20 7a 53 65 70 20 3d 20 22 2c 22 3b       zSep = ",";
44a0: 0a 20 20 20 20 7d 0a 20 20 20 20 66 6f 72 28 69  .    }.    for(i
44b0: 3d 32 3b 20 69 3c 6e 44 61 74 61 3b 20 69 2b 2b  =2; i<nData; i++
44c0: 29 7b 0a 20 20 20 20 20 20 69 66 28 20 61 70 44  ){.      if( apD
44d0: 61 74 61 5b 69 5d 3d 3d 30 20 29 20 63 6f 6e 74  ata[i]==0 ) cont
44e0: 69 6e 75 65 3b 0a 20 20 20 20 20 20 73 74 72 69  inue;.      stri
44f0: 6e 67 5f 63 6f 6e 63 61 74 28 26 7a 2c 20 73 71  ng_concat(&z, sq
4500: 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 0a 20  lite3_mprintf(. 
4510: 20 20 20 20 20 20 20 20 20 22 25 73 20 25 51 3d           "%s %Q=
4520: 3f 25 64 22 2c 20 7a 53 65 70 2c 20 70 56 74 61  ?%d", zSep, pVta
4530: 62 2d 3e 61 43 6f 6c 5b 69 2d 32 5d 2c 20 69 29  b->aCol[i-2], i)
4540: 2c 20 31 29 3b 0a 20 20 20 20 20 20 7a 53 65 70  , 1);.      zSep
4550: 20 3d 20 22 2c 22 3b 0a 20 20 20 20 7d 0a 20 20   = ",";.    }.  
4560: 20 20 73 74 72 69 6e 67 5f 63 6f 6e 63 61 74 28    string_concat(
4570: 26 7a 2c 20 73 71 6c 69 74 65 33 5f 6d 70 72 69  &z, sqlite3_mpri
4580: 6e 74 66 28 22 20 57 48 45 52 45 20 72 6f 77 69  ntf(" WHERE rowi
4590: 64 3d 3f 25 64 22 2c 20 6e 44 61 74 61 29 2c 20  d=?%d", nData), 
45a0: 30 29 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 49 66  0);.  }..  /* If
45b0: 20 61 70 44 61 74 61 5b 30 5d 20 69 73 20 61 6e   apData[0] is an
45c0: 20 69 6e 74 65 67 65 72 20 61 6e 64 20 6e 44 61   integer and nDa
45d0: 74 61 3d 3d 31 20 74 68 65 6e 20 64 6f 20 61 20  ta==1 then do a 
45e0: 44 45 4c 45 54 45 20 2a 2f 0a 20 20 65 6c 73 65  DELETE */.  else
45f0: 20 69 66 28 20 6e 44 61 74 61 3d 3d 31 20 26 26   if( nData==1 &&
4600: 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 74   sqlite3_value_t
4610: 79 70 65 28 61 70 44 61 74 61 5b 30 5d 29 3d 3d  ype(apData[0])==
4620: 53 51 4c 49 54 45 5f 49 4e 54 45 47 45 52 20 29  SQLITE_INTEGER )
4630: 7b 0a 20 20 20 20 7a 20 3d 20 73 71 6c 69 74 65  {.    z = sqlite
4640: 33 5f 6d 70 72 69 6e 74 66 28 22 44 45 4c 45 54  3_mprintf("DELET
4650: 45 20 46 52 4f 4d 20 25 51 20 57 48 45 52 45 20  E FROM %Q WHERE 
4660: 72 6f 77 69 64 20 3d 20 3f 31 22 2c 20 70 56 74  rowid = ?1", pVt
4670: 61 62 2d 3e 7a 54 61 62 6c 65 4e 61 6d 65 29 3b  ab->zTableName);
4680: 0a 20 20 20 20 62 69 6e 64 41 72 67 5a 65 72 6f  .    bindArgZero
4690: 20 3d 20 31 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20   = 1;.  }..  /* 
46a0: 49 66 20 74 68 65 20 66 69 72 73 74 20 61 72 67  If the first arg
46b0: 75 6d 65 6e 74 20 69 73 20 4e 55 4c 4c 20 61 6e  ument is NULL an
46c0: 64 20 74 68 65 72 65 20 61 72 65 20 6d 6f 72 65  d there are more
46d0: 20 74 68 61 6e 20 74 77 6f 20 61 72 67 73 2c 20   than two args, 
46e0: 49 4e 53 45 52 54 20 2a 2f 0a 20 20 65 6c 73 65  INSERT */.  else
46f0: 20 69 66 28 20 6e 44 61 74 61 3e 32 20 26 26 20   if( nData>2 && 
4700: 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 74 79  sqlite3_value_ty
4710: 70 65 28 61 70 44 61 74 61 5b 30 5d 29 3d 3d 53  pe(apData[0])==S
4720: 51 4c 49 54 45 5f 4e 55 4c 4c 20 29 7b 0a 20 20  QLITE_NULL ){.  
4730: 20 20 69 6e 74 20 69 69 3b 0a 20 20 20 20 63 68    int ii;.    ch
4740: 61 72 20 2a 7a 49 6e 73 65 72 74 20 3d 20 30 3b  ar *zInsert = 0;
4750: 0a 20 20 20 20 63 68 61 72 20 2a 7a 56 61 6c 75  .    char *zValu
4760: 65 73 20 3d 20 30 3b 0a 20 20 0a 20 20 20 20 7a  es = 0;.  .    z
4770: 49 6e 73 65 72 74 20 3d 20 73 71 6c 69 74 65 33  Insert = sqlite3
4780: 5f 6d 70 72 69 6e 74 66 28 22 49 4e 53 45 52 54  _mprintf("INSERT
4790: 20 49 4e 54 4f 20 25 51 20 28 22 2c 20 70 56 74   INTO %Q (", pVt
47a0: 61 62 2d 3e 7a 54 61 62 6c 65 4e 61 6d 65 29 3b  ab->zTableName);
47b0: 0a 20 20 20 20 69 66 28 20 73 71 6c 69 74 65 33  .    if( sqlite3
47c0: 5f 76 61 6c 75 65 5f 74 79 70 65 28 61 70 44 61  _value_type(apDa
47d0: 74 61 5b 31 5d 29 3d 3d 53 51 4c 49 54 45 5f 49  ta[1])==SQLITE_I
47e0: 4e 54 45 47 45 52 20 29 7b 0a 20 20 20 20 20 20  NTEGER ){.      
47f0: 62 69 6e 64 41 72 67 4f 6e 65 20 3d 20 31 3b 0a  bindArgOne = 1;.
4800: 20 20 20 20 20 20 7a 56 61 6c 75 65 73 20 3d 20        zValues = 
4810: 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28  sqlite3_mprintf(
4820: 22 3f 22 29 3b 0a 20 20 20 20 20 20 73 74 72 69  "?");.      stri
4830: 6e 67 5f 63 6f 6e 63 61 74 28 26 7a 49 6e 73 65  ng_concat(&zInse
4840: 72 74 2c 20 22 72 6f 77 69 64 22 2c 20 30 29 3b  rt, "rowid", 0);
4850: 0a 20 20 20 20 7d 0a 0a 20 20 20 20 61 73 73 65  .    }..    asse
4860: 72 74 28 28 70 56 74 61 62 2d 3e 6e 43 6f 6c 2b  rt((pVtab->nCol+
4870: 32 29 3d 3d 6e 44 61 74 61 29 3b 0a 20 20 20 20  2)==nData);.    
4880: 66 6f 72 28 69 69 3d 32 3b 20 69 69 3c 6e 44 61  for(ii=2; ii<nDa
4890: 74 61 3b 20 69 69 2b 2b 29 7b 0a 20 20 20 20 20  ta; ii++){.     
48a0: 20 73 74 72 69 6e 67 5f 63 6f 6e 63 61 74 28 26   string_concat(&
48b0: 7a 49 6e 73 65 72 74 2c 20 0a 20 20 20 20 20 20  zInsert, .      
48c0: 20 20 20 20 73 71 6c 69 74 65 33 5f 6d 70 72 69      sqlite3_mpri
48d0: 6e 74 66 28 22 25 73 25 51 22 2c 20 7a 56 61 6c  ntf("%s%Q", zVal
48e0: 75 65 73 3f 22 2c 20 22 3a 22 22 2c 20 70 56 74  ues?", ":"", pVt
48f0: 61 62 2d 3e 61 43 6f 6c 5b 69 69 2d 32 5d 29 2c  ab->aCol[ii-2]),
4900: 20 31 29 3b 0a 20 20 20 20 20 20 73 74 72 69 6e   1);.      strin
4910: 67 5f 63 6f 6e 63 61 74 28 26 7a 56 61 6c 75 65  g_concat(&zValue
4920: 73 2c 20 0a 20 20 20 20 20 20 20 20 20 20 73 71  s, .          sq
4930: 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 22 25  lite3_mprintf("%
4940: 73 3f 25 64 22 2c 20 7a 56 61 6c 75 65 73 3f 22  s?%d", zValues?"
4950: 2c 20 22 3a 22 22 2c 20 69 69 29 2c 20 31 29 3b  , ":"", ii), 1);
4960: 0a 20 20 20 20 7d 0a 0a 20 20 20 20 73 74 72 69  .    }..    stri
4970: 6e 67 5f 63 6f 6e 63 61 74 28 26 7a 2c 20 7a 49  ng_concat(&z, zI
4980: 6e 73 65 72 74 2c 20 31 29 3b 0a 20 20 20 20 73  nsert, 1);.    s
4990: 74 72 69 6e 67 5f 63 6f 6e 63 61 74 28 26 7a 2c  tring_concat(&z,
49a0: 20 22 29 20 56 41 4c 55 45 53 28 22 2c 20 30 29   ") VALUES(", 0)
49b0: 3b 0a 20 20 20 20 73 74 72 69 6e 67 5f 63 6f 6e  ;.    string_con
49c0: 63 61 74 28 26 7a 2c 20 7a 56 61 6c 75 65 73 2c  cat(&z, zValues,
49d0: 20 31 29 3b 0a 20 20 20 20 73 74 72 69 6e 67 5f   1);.    string_
49e0: 63 6f 6e 63 61 74 28 26 7a 2c 20 22 29 22 2c 20  concat(&z, ")", 
49f0: 30 29 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 41 6e  0);.  }..  /* An
4a00: 79 74 68 69 6e 67 20 65 6c 73 65 20 69 73 20 61  ything else is a
4a10: 6e 20 65 72 72 6f 72 20 2a 2f 0a 20 20 65 6c 73  n error */.  els
4a20: 65 7b 0a 20 20 20 20 61 73 73 65 72 74 28 30 29  e{.    assert(0)
4a30: 3b 0a 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c  ;.    return SQL
4a40: 49 54 45 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a 0a  ITE_ERROR;.  }..
4a50: 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 70    rc = sqlite3_p
4a60: 72 65 70 61 72 65 28 64 62 2c 20 7a 2c 20 2d 31  repare(db, z, -1
4a70: 2c 20 26 70 53 74 6d 74 2c 20 30 29 3b 0a 20 20  , &pStmt, 0);.  
4a80: 61 73 73 65 72 74 28 20 72 63 21 3d 53 51 4c 49  assert( rc!=SQLI
4a90: 54 45 5f 4f 4b 20 7c 7c 20 70 53 74 6d 74 20 29  TE_OK || pStmt )
4aa0: 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65  ;.  sqlite3_free
4ab0: 28 7a 29 3b 0a 20 20 69 66 28 20 72 63 3d 3d 53  (z);.  if( rc==S
4ac0: 51 4c 49 54 45 5f 4f 4b 20 29 20 7b 0a 20 20 20  QLITE_OK ) {.   
4ad0: 20 69 66 28 20 62 69 6e 64 41 72 67 5a 65 72 6f   if( bindArgZero
4ae0: 20 29 7b 0a 20 20 20 20 20 20 73 71 6c 69 74 65   ){.      sqlite
4af0: 33 5f 62 69 6e 64 5f 76 61 6c 75 65 28 70 53 74  3_bind_value(pSt
4b00: 6d 74 2c 20 6e 44 61 74 61 2c 20 61 70 44 61 74  mt, nData, apDat
4b10: 61 5b 30 5d 29 3b 0a 20 20 20 20 7d 0a 20 20 20  a[0]);.    }.   
4b20: 20 69 66 28 20 62 69 6e 64 41 72 67 4f 6e 65 20   if( bindArgOne 
4b30: 29 7b 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33  ){.      sqlite3
4b40: 5f 62 69 6e 64 5f 76 61 6c 75 65 28 70 53 74 6d  _bind_value(pStm
4b50: 74 2c 20 31 2c 20 61 70 44 61 74 61 5b 31 5d 29  t, 1, apData[1])
4b60: 3b 0a 20 20 20 20 7d 0a 20 20 20 20 66 6f 72 28  ;.    }.    for(
4b70: 69 3d 32 3b 20 69 3c 6e 44 61 74 61 3b 20 69 2b  i=2; i<nData; i+
4b80: 2b 29 7b 0a 20 20 20 20 20 20 69 66 28 20 61 70  +){.      if( ap
4b90: 44 61 74 61 5b 69 5d 20 29 20 73 71 6c 69 74 65  Data[i] ) sqlite
4ba0: 33 5f 62 69 6e 64 5f 76 61 6c 75 65 28 70 53 74  3_bind_value(pSt
4bb0: 6d 74 2c 20 69 2c 20 61 70 44 61 74 61 5b 69 5d  mt, i, apData[i]
4bc0: 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 73 71 6c  );.    }.    sql
4bd0: 69 74 65 33 5f 73 74 65 70 28 70 53 74 6d 74 29  ite3_step(pStmt)
4be0: 3b 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74  ;.    rc = sqlit
4bf0: 65 33 5f 66 69 6e 61 6c 69 7a 65 28 70 53 74 6d  e3_finalize(pStm
4c00: 74 29 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 70  t);.  }..  if( p
4c10: 52 6f 77 69 64 20 26 26 20 72 63 3d 3d 53 51 4c  Rowid && rc==SQL
4c20: 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 2a 70  ITE_OK ){.    *p
4c30: 52 6f 77 69 64 20 3d 20 73 71 6c 69 74 65 33 5f  Rowid = sqlite3_
4c40: 6c 61 73 74 5f 69 6e 73 65 72 74 5f 72 6f 77 69  last_insert_rowi
4c50: 64 28 64 62 29 3b 0a 20 20 7d 0a 0a 20 20 72 65  d(db);.  }..  re
4c60: 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a  turn rc;.}../*.*
4c70: 2a 20 78 42 65 67 69 6e 2c 20 78 53 79 6e 63 2c  * xBegin, xSync,
4c80: 20 78 43 6f 6d 6d 69 74 20 61 6e 64 20 78 52 6f   xCommit and xRo
4c90: 6c 6c 62 61 63 6b 20 63 61 6c 6c 62 61 63 6b 73  llback callbacks
4ca0: 20 66 6f 72 20 65 63 68 6f 20 6d 6f 64 75 6c 65   for echo module
4cb0: 0a 2a 2a 20 76 69 72 74 75 61 6c 20 74 61 62 6c  .** virtual tabl
4cc0: 65 73 2e 20 44 6f 20 6e 6f 74 68 69 6e 67 20 6f  es. Do nothing o
4cd0: 74 68 65 72 20 74 68 61 6e 20 61 64 64 20 74 68  ther than add th
4ce0: 65 20 6e 61 6d 65 20 6f 66 20 74 68 65 20 63 61  e name of the ca
4cf0: 6c 6c 62 61 63 6b 0a 2a 2a 20 74 6f 20 74 68 65  llback.** to the
4d00: 20 24 3a 3a 65 63 68 6f 5f 6d 6f 64 75 6c 65 20   $::echo_module 
4d10: 54 63 6c 20 76 61 72 69 61 62 6c 65 2e 0a 2a 2f  Tcl variable..*/
4d20: 0a 73 74 61 74 69 63 20 69 6e 74 20 65 63 68 6f  .static int echo
4d30: 54 72 61 6e 73 61 63 74 69 6f 6e 43 61 6c 6c 28  TransactionCall(
4d40: 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 74 61  sqlite3_vtab *ta
4d50: 62 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a  b, const char *z
4d60: 43 61 6c 6c 29 7b 0a 20 20 63 68 61 72 20 2a 7a  Call){.  char *z
4d70: 3b 0a 20 20 65 63 68 6f 5f 76 74 61 62 20 2a 70  ;.  echo_vtab *p
4d80: 56 74 61 62 20 3d 20 28 65 63 68 6f 5f 76 74 61  Vtab = (echo_vta
4d90: 62 20 2a 29 74 61 62 3b 0a 20 20 7a 20 3d 20 73  b *)tab;.  z = s
4da0: 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 22  qlite3_mprintf("
4db0: 65 63 68 6f 28 25 73 29 22 2c 20 70 56 74 61 62  echo(%s)", pVtab
4dc0: 2d 3e 7a 54 61 62 6c 65 4e 61 6d 65 29 3b 0a 20  ->zTableName);. 
4dd0: 20 61 70 70 65 6e 64 54 6f 45 63 68 6f 4d 6f 64   appendToEchoMod
4de0: 75 6c 65 28 70 56 74 61 62 2d 3e 69 6e 74 65 72  ule(pVtab->inter
4df0: 70 2c 20 7a 43 61 6c 6c 29 3b 0a 20 20 61 70 70  p, zCall);.  app
4e00: 65 6e 64 54 6f 45 63 68 6f 4d 6f 64 75 6c 65 28  endToEchoModule(
4e10: 70 56 74 61 62 2d 3e 69 6e 74 65 72 70 2c 20 7a  pVtab->interp, z
4e20: 29 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66 72 65  );.  sqlite3_fre
4e30: 65 28 7a 29 3b 0a 20 20 72 65 74 75 72 6e 20 53  e(z);.  return S
4e40: 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 73 74 61 74  QLITE_OK;.}.stat
4e50: 69 63 20 69 6e 74 20 65 63 68 6f 42 65 67 69 6e  ic int echoBegin
4e60: 28 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 74  (sqlite3_vtab *t
4e70: 61 62 29 7b 0a 20 20 72 65 74 75 72 6e 20 65 63  ab){.  return ec
4e80: 68 6f 54 72 61 6e 73 61 63 74 69 6f 6e 43 61 6c  hoTransactionCal
4e90: 6c 28 74 61 62 2c 20 22 78 42 65 67 69 6e 22 29  l(tab, "xBegin")
4ea0: 3b 0a 7d 0a 73 74 61 74 69 63 20 69 6e 74 20 65  ;.}.static int e
4eb0: 63 68 6f 53 79 6e 63 28 73 71 6c 69 74 65 33 5f  choSync(sqlite3_
4ec0: 76 74 61 62 20 2a 74 61 62 29 7b 0a 20 20 65 63  vtab *tab){.  ec
4ed0: 68 6f 5f 76 74 61 62 20 2a 70 56 74 61 62 20 3d  ho_vtab *pVtab =
4ee0: 20 28 65 63 68 6f 5f 76 74 61 62 20 2a 29 74 61   (echo_vtab *)ta
4ef0: 62 3b 0a 20 20 54 63 6c 5f 49 6e 74 65 72 70 20  b;.  Tcl_Interp 
4f00: 2a 69 6e 74 65 72 70 20 3d 20 70 56 74 61 62 2d  *interp = pVtab-
4f10: 3e 69 6e 74 65 72 70 3b 0a 20 20 63 6f 6e 73 74  >interp;.  const
4f20: 20 63 68 61 72 20 2a 7a 56 61 6c 3b 20 0a 0a 20   char *zVal; .. 
4f30: 20 65 63 68 6f 54 72 61 6e 73 61 63 74 69 6f 6e   echoTransaction
4f40: 43 61 6c 6c 28 74 61 62 2c 20 22 78 53 79 6e 63  Call(tab, "xSync
4f50: 22 29 3b 0a 0a 20 20 2f 2a 20 43 68 65 63 6b 20  ");..  /* Check 
4f60: 69 66 20 74 68 65 20 24 3a 3a 65 63 68 6f 5f 6d  if the $::echo_m
4f70: 6f 64 75 6c 65 5f 73 79 6e 63 5f 66 61 69 6c 20  odule_sync_fail 
4f80: 76 61 72 69 61 62 6c 65 20 69 73 20 64 65 66 69  variable is defi
4f90: 6e 65 64 2e 20 49 66 20 69 74 20 69 73 2c 0a 20  ned. If it is,. 
4fa0: 20 2a 2a 20 61 6e 64 20 69 74 20 69 73 20 73 65   ** and it is se
4fb0: 74 20 74 6f 20 74 68 65 20 6e 61 6d 65 20 6f 66  t to the name of
4fc0: 20 74 68 65 20 72 65 61 6c 20 74 61 62 6c 65 20   the real table 
4fd0: 75 6e 64 65 72 6c 79 69 6e 67 20 74 68 69 73 20  underlying this 
4fe0: 76 69 72 74 75 61 6c 0a 20 20 2a 2a 20 65 63 68  virtual.  ** ech
4ff0: 6f 20 6d 6f 64 75 6c 65 20 74 61 62 6c 65 2c 20  o module table, 
5000: 74 68 65 6e 20 63 61 75 73 65 20 74 68 69 73 20  then cause this 
5010: 78 53 79 6e 63 20 6f 70 65 72 61 74 69 6f 6e 20  xSync operation 
5020: 74 6f 20 66 61 69 6c 2e 0a 20 20 2a 2f 0a 20 20  to fail..  */.  
5030: 7a 56 61 6c 20 3d 20 54 63 6c 5f 47 65 74 56 61  zVal = Tcl_GetVa
5040: 72 28 69 6e 74 65 72 70 2c 20 22 65 63 68 6f 5f  r(interp, "echo_
5050: 6d 6f 64 75 6c 65 5f 73 79 6e 63 5f 66 61 69 6c  module_sync_fail
5060: 22 2c 20 54 43 4c 5f 47 4c 4f 42 41 4c 5f 4f 4e  ", TCL_GLOBAL_ON
5070: 4c 59 29 3b 0a 20 20 69 66 28 20 7a 56 61 6c 20  LY);.  if( zVal 
5080: 26 26 20 30 3d 3d 73 74 72 63 6d 70 28 7a 56 61  && 0==strcmp(zVa
5090: 6c 2c 20 70 56 74 61 62 2d 3e 7a 54 61 62 6c 65  l, pVtab->zTable
50a0: 4e 61 6d 65 29 20 29 7b 0a 20 20 20 20 72 65 74  Name) ){.    ret
50b0: 75 72 6e 20 2d 31 3b 0a 20 20 7d 0a 20 20 72 65  urn -1;.  }.  re
50c0: 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a  turn SQLITE_OK;.
50d0: 7d 0a 73 74 61 74 69 63 20 69 6e 74 20 65 63 68  }.static int ech
50e0: 6f 43 6f 6d 6d 69 74 28 73 71 6c 69 74 65 33 5f  oCommit(sqlite3_
50f0: 76 74 61 62 20 2a 74 61 62 29 7b 0a 20 20 72 65  vtab *tab){.  re
5100: 74 75 72 6e 20 65 63 68 6f 54 72 61 6e 73 61 63  turn echoTransac
5110: 74 69 6f 6e 43 61 6c 6c 28 74 61 62 2c 20 22 78  tionCall(tab, "x
5120: 43 6f 6d 6d 69 74 22 29 3b 0a 7d 0a 73 74 61 74  Commit");.}.stat
5130: 69 63 20 69 6e 74 20 65 63 68 6f 52 6f 6c 6c 62  ic int echoRollb
5140: 61 63 6b 28 73 71 6c 69 74 65 33 5f 76 74 61 62  ack(sqlite3_vtab
5150: 20 2a 74 61 62 29 7b 0a 20 20 72 65 74 75 72 6e   *tab){.  return
5160: 20 65 63 68 6f 54 72 61 6e 73 61 63 74 69 6f 6e   echoTransaction
5170: 43 61 6c 6c 28 74 61 62 2c 20 22 78 52 6f 6c 6c  Call(tab, "xRoll
5180: 62 61 63 6b 22 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  back");.}../*.**
5190: 20 41 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65   A virtual table
51a0: 20 6d 6f 64 75 6c 65 20 74 68 61 74 20 6d 65 72   module that mer
51b0: 65 6c 79 20 65 63 68 6f 73 20 6d 65 74 68 6f 64  ely echos method
51c0: 20 63 61 6c 6c 73 20 69 6e 74 6f 20 54 43 4c 0a   calls into TCL.
51d0: 2a 2a 20 76 61 72 69 61 62 6c 65 73 2e 0a 2a 2f  ** variables..*/
51e0: 0a 73 74 61 74 69 63 20 73 71 6c 69 74 65 33 5f  .static sqlite3_
51f0: 6d 6f 64 75 6c 65 20 65 63 68 6f 4d 6f 64 75 6c  module echoModul
5200: 65 20 3d 20 7b 0a 20 20 30 2c 20 20 20 20 20 20  e = {.  0,      
5210: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5220: 20 20 20 2f 2a 20 69 56 65 72 73 69 6f 6e 20 2a     /* iVersion *
5230: 2f 0a 20 20 22 65 63 68 6f 22 2c 20 20 20 20 20  /.  "echo",     
5240: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
5250: 2a 20 7a 4e 61 6d 65 20 2a 2f 0a 20 20 65 63 68  * zName */.  ech
5260: 6f 43 72 65 61 74 65 2c 0a 20 20 65 63 68 6f 43  oCreate,.  echoC
5270: 6f 6e 6e 65 63 74 2c 0a 20 20 65 63 68 6f 42 65  onnect,.  echoBe
5280: 73 74 49 6e 64 65 78 2c 0a 20 20 65 63 68 6f 44  stIndex,.  echoD
5290: 69 73 63 6f 6e 6e 65 63 74 2c 20 0a 20 20 65 63  isconnect, .  ec
52a0: 68 6f 44 65 73 74 72 6f 79 2c 0a 20 20 65 63 68  hoDestroy,.  ech
52b0: 6f 4f 70 65 6e 2c 20 20 20 20 20 20 20 20 20 20  oOpen,          
52c0: 20 20 20 20 20 20 20 20 2f 2a 20 78 4f 70 65 6e          /* xOpen
52d0: 20 2d 20 6f 70 65 6e 20 61 20 63 75 72 73 6f 72   - open a cursor
52e0: 20 2a 2f 0a 20 20 65 63 68 6f 43 6c 6f 73 65 2c   */.  echoClose,
52f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5300: 20 2f 2a 20 78 43 6c 6f 73 65 20 2d 20 63 6c 6f   /* xClose - clo
5310: 73 65 20 61 20 63 75 72 73 6f 72 20 2a 2f 0a 20  se a cursor */. 
5320: 20 65 63 68 6f 46 69 6c 74 65 72 2c 20 20 20 20   echoFilter,    
5330: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78              /* x
5340: 46 69 6c 74 65 72 20 2d 20 63 6f 6e 66 69 67 75  Filter - configu
5350: 72 65 20 73 63 61 6e 20 63 6f 6e 73 74 72 61 69  re scan constrai
5360: 6e 74 73 20 2a 2f 0a 20 20 65 63 68 6f 4e 65 78  nts */.  echoNex
5370: 74 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  t,              
5380: 20 20 20 20 2f 2a 20 78 4e 65 78 74 20 2d 20 61      /* xNext - a
5390: 64 76 61 6e 63 65 20 61 20 63 75 72 73 6f 72 20  dvance a cursor 
53a0: 2a 2f 0a 20 20 65 63 68 6f 45 6f 66 2c 20 20 20  */.  echoEof,   
53b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
53c0: 2f 2a 20 78 45 6f 66 20 2a 2f 0a 20 20 65 63 68  /* xEof */.  ech
53d0: 6f 43 6f 6c 75 6d 6e 2c 20 20 20 20 20 20 20 20  oColumn,        
53e0: 20 20 20 20 20 20 20 20 2f 2a 20 78 43 6f 6c 75          /* xColu
53f0: 6d 6e 20 2d 20 72 65 61 64 20 64 61 74 61 20 2a  mn - read data *
5400: 2f 0a 20 20 65 63 68 6f 52 6f 77 69 64 2c 20 20  /.  echoRowid,  
5410: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
5420: 2a 20 78 52 6f 77 69 64 20 2d 20 72 65 61 64 20  * xRowid - read 
5430: 64 61 74 61 20 2a 2f 0a 20 20 65 63 68 6f 55 70  data */.  echoUp
5440: 64 61 74 65 2c 20 20 20 20 20 20 20 20 20 20 20  date,           
5450: 20 20 20 20 20 2f 2a 20 78 55 70 64 61 74 65 20       /* xUpdate 
5460: 2d 20 77 72 69 74 65 20 64 61 74 61 20 2a 2f 0a  - write data */.
5470: 20 20 65 63 68 6f 42 65 67 69 6e 2c 20 20 20 20    echoBegin,    
5480: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
5490: 78 42 65 67 69 6e 20 2d 20 62 65 67 69 6e 20 74  xBegin - begin t
54a0: 72 61 6e 73 61 63 74 69 6f 6e 20 2a 2f 0a 20 20  ransaction */.  
54b0: 65 63 68 6f 53 79 6e 63 2c 20 20 20 20 20 20 20  echoSync,       
54c0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 53             /* xS
54d0: 79 6e 63 20 2d 20 73 79 6e 63 20 74 72 61 6e 73  ync - sync trans
54e0: 61 63 74 69 6f 6e 20 2a 2f 0a 20 20 65 63 68 6f  action */.  echo
54f0: 43 6f 6d 6d 69 74 2c 20 20 20 20 20 20 20 20 20  Commit,         
5500: 20 20 20 20 20 20 20 2f 2a 20 78 43 6f 6d 6d 69         /* xCommi
5510: 74 20 2d 20 63 6f 6d 6d 69 74 20 74 72 61 6e 73  t - commit trans
5520: 61 63 74 69 6f 6e 20 2a 2f 0a 20 20 65 63 68 6f  action */.  echo
5530: 52 6f 6c 6c 62 61 63 6b 20 20 20 20 20 20 20 20  Rollback        
5540: 20 20 20 20 20 20 20 2f 2a 20 78 52 6f 6c 6c 62         /* xRollb
5550: 61 63 6b 20 2d 20 72 6f 6c 6c 62 61 63 6b 20 74  ack - rollback t
5560: 72 61 6e 73 61 63 74 69 6f 6e 20 2a 2f 0a 7d 3b  ransaction */.};
5570: 0a 0a 2f 2a 0a 2a 2a 20 44 65 63 6f 64 65 20 61  ../*.** Decode a
5580: 20 70 6f 69 6e 74 65 72 20 74 6f 20 61 6e 20 73   pointer to an s
5590: 71 6c 69 74 65 33 20 6f 62 6a 65 63 74 2e 0a 2a  qlite3 object..*
55a0: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 67 65 74  /.static int get
55b0: 44 62 50 6f 69 6e 74 65 72 28 54 63 6c 5f 49 6e  DbPointer(Tcl_In
55c0: 74 65 72 70 20 2a 69 6e 74 65 72 70 2c 20 63 6f  terp *interp, co
55d0: 6e 73 74 20 63 68 61 72 20 2a 7a 41 2c 20 73 71  nst char *zA, sq
55e0: 6c 69 74 65 33 20 2a 2a 70 70 44 62 29 7b 0a 20  lite3 **ppDb){. 
55f0: 20 2a 70 70 44 62 20 3d 20 28 73 71 6c 69 74 65   *ppDb = (sqlite
5600: 33 2a 29 73 71 6c 69 74 65 33 54 65 78 74 54 6f  3*)sqlite3TextTo
5610: 50 74 72 28 7a 41 29 3b 0a 20 20 72 65 74 75 72  Ptr(zA);.  retur
5620: 6e 20 54 43 4c 5f 4f 4b 3b 0a 7d 0a 0a 0a 2f 2a  n TCL_OK;.}.../*
5630: 0a 2a 2a 20 52 65 67 69 73 74 65 72 20 74 68 65  .** Register the
5640: 20 65 63 68 6f 20 76 69 72 74 75 61 6c 20 74 61   echo virtual ta
5650: 62 6c 65 20 6d 6f 64 75 6c 65 2e 0a 2a 2f 0a 73  ble module..*/.s
5660: 74 61 74 69 63 20 69 6e 74 20 72 65 67 69 73 74  tatic int regist
5670: 65 72 5f 65 63 68 6f 5f 6d 6f 64 75 6c 65 28 0a  er_echo_module(.
5680: 20 20 43 6c 69 65 6e 74 44 61 74 61 20 63 6c 69    ClientData cli
5690: 65 6e 74 44 61 74 61 2c 20 2f 2a 20 50 6f 69 6e  entData, /* Poin
56a0: 74 65 72 20 74 6f 20 73 71 6c 69 74 65 33 5f 65  ter to sqlite3_e
56b0: 6e 61 62 6c 65 5f 58 58 58 20 66 75 6e 63 74 69  nable_XXX functi
56c0: 6f 6e 20 2a 2f 0a 20 20 54 63 6c 5f 49 6e 74 65  on */.  Tcl_Inte
56d0: 72 70 20 2a 69 6e 74 65 72 70 2c 20 20 20 20 2f  rp *interp,    /
56e0: 2a 20 54 68 65 20 54 43 4c 20 69 6e 74 65 72 70  * The TCL interp
56f0: 72 65 74 65 72 20 74 68 61 74 20 69 6e 76 6f 6b  reter that invok
5700: 65 64 20 74 68 69 73 20 63 6f 6d 6d 61 6e 64 20  ed this command 
5710: 2a 2f 0a 20 20 69 6e 74 20 6f 62 6a 63 2c 20 20  */.  int objc,  
5720: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e              /* N
5730: 75 6d 62 65 72 20 6f 66 20 61 72 67 75 6d 65 6e  umber of argumen
5740: 74 73 20 2a 2f 0a 20 20 54 63 6c 5f 4f 62 6a 20  ts */.  Tcl_Obj 
5750: 2a 43 4f 4e 53 54 20 6f 62 6a 76 5b 5d 20 20 2f  *CONST objv[]  /
5760: 2a 20 43 6f 6d 6d 61 6e 64 20 61 72 67 75 6d 65  * Command argume
5770: 6e 74 73 20 2a 2f 0a 29 7b 0a 20 20 73 71 6c 69  nts */.){.  sqli
5780: 74 65 33 20 2a 64 62 3b 0a 20 20 69 66 28 20 6f  te3 *db;.  if( o
5790: 62 6a 63 21 3d 32 20 29 7b 0a 20 20 20 20 54 63  bjc!=2 ){.    Tc
57a0: 6c 5f 57 72 6f 6e 67 4e 75 6d 41 72 67 73 28 69  l_WrongNumArgs(i
57b0: 6e 74 65 72 70 2c 20 31 2c 20 6f 62 6a 76 2c 20  nterp, 1, objv, 
57c0: 22 44 42 22 29 3b 0a 20 20 20 20 72 65 74 75 72  "DB");.    retur
57d0: 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 7d  n TCL_ERROR;.  }
57e0: 0a 20 20 69 66 28 20 67 65 74 44 62 50 6f 69 6e  .  if( getDbPoin
57f0: 74 65 72 28 69 6e 74 65 72 70 2c 20 54 63 6c 5f  ter(interp, Tcl_
5800: 47 65 74 53 74 72 69 6e 67 28 6f 62 6a 76 5b 31  GetString(objv[1
5810: 5d 29 2c 20 26 64 62 29 20 29 20 72 65 74 75 72  ]), &db) ) retur
5820: 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 23 69 66  n TCL_ERROR;.#if
5830: 6e 64 65 66 20 53 51 4c 49 54 45 5f 4f 4d 49 54  ndef SQLITE_OMIT
5840: 5f 56 49 52 54 55 41 4c 54 41 42 4c 45 0a 20 20  _VIRTUALTABLE.  
5850: 73 71 6c 69 74 65 33 5f 63 72 65 61 74 65 5f 6d  sqlite3_create_m
5860: 6f 64 75 6c 65 28 64 62 2c 20 22 65 63 68 6f 22  odule(db, "echo"
5870: 2c 20 26 65 63 68 6f 4d 6f 64 75 6c 65 2c 20 28  , &echoModule, (
5880: 76 6f 69 64 20 2a 29 69 6e 74 65 72 70 29 3b 0a  void *)interp);.
5890: 23 65 6e 64 69 66 0a 20 20 72 65 74 75 72 6e 20  #endif.  return 
58a0: 54 43 4c 5f 4f 4b 3b 0a 7d 0a 0a 0a 2f 2a 0a 2a  TCL_OK;.}.../*.*
58b0: 2a 20 52 65 67 69 73 74 65 72 20 63 6f 6d 6d 61  * Register comma
58c0: 6e 64 73 20 77 69 74 68 20 74 68 65 20 54 43 4c  nds with the TCL
58d0: 20 69 6e 74 65 72 70 72 65 74 65 72 2e 0a 2a 2f   interpreter..*/
58e0: 0a 69 6e 74 20 53 71 6c 69 74 65 74 65 73 74 38  .int Sqlitetest8
58f0: 5f 49 6e 69 74 28 54 63 6c 5f 49 6e 74 65 72 70  _Init(Tcl_Interp
5900: 20 2a 69 6e 74 65 72 70 29 7b 0a 20 20 73 74 61   *interp){.  sta
5910: 74 69 63 20 73 74 72 75 63 74 20 7b 0a 20 20 20  tic struct {.   
5920: 20 20 63 68 61 72 20 2a 7a 4e 61 6d 65 3b 0a 20    char *zName;. 
5930: 20 20 20 20 54 63 6c 5f 4f 62 6a 43 6d 64 50 72      Tcl_ObjCmdPr
5940: 6f 63 20 2a 78 50 72 6f 63 3b 0a 20 20 20 20 20  oc *xProc;.     
5950: 76 6f 69 64 20 2a 63 6c 69 65 6e 74 44 61 74 61  void *clientData
5960: 3b 0a 20 20 7d 20 61 4f 62 6a 43 6d 64 5b 5d 20  ;.  } aObjCmd[] 
5970: 3d 20 7b 0a 20 20 20 20 20 7b 20 22 72 65 67 69  = {.     { "regi
5980: 73 74 65 72 5f 65 63 68 6f 5f 6d 6f 64 75 6c 65  ster_echo_module
5990: 22 2c 20 20 20 72 65 67 69 73 74 65 72 5f 65 63  ",   register_ec
59a0: 68 6f 5f 6d 6f 64 75 6c 65 2c 20 30 20 7d 2c 0a  ho_module, 0 },.
59b0: 20 20 7d 3b 0a 20 20 69 6e 74 20 69 3b 0a 20 20    };.  int i;.  
59c0: 66 6f 72 28 69 3d 30 3b 20 69 3c 73 69 7a 65 6f  for(i=0; i<sizeo
59d0: 66 28 61 4f 62 6a 43 6d 64 29 2f 73 69 7a 65 6f  f(aObjCmd)/sizeo
59e0: 66 28 61 4f 62 6a 43 6d 64 5b 30 5d 29 3b 20 69  f(aObjCmd[0]); i
59f0: 2b 2b 29 7b 0a 20 20 20 20 54 63 6c 5f 43 72 65  ++){.    Tcl_Cre
5a00: 61 74 65 4f 62 6a 43 6f 6d 6d 61 6e 64 28 69 6e  ateObjCommand(in
5a10: 74 65 72 70 2c 20 61 4f 62 6a 43 6d 64 5b 69 5d  terp, aObjCmd[i]
5a20: 2e 7a 4e 61 6d 65 2c 20 0a 20 20 20 20 20 20 20  .zName, .       
5a30: 20 61 4f 62 6a 43 6d 64 5b 69 5d 2e 78 50 72 6f   aObjCmd[i].xPro
5a40: 63 2c 20 61 4f 62 6a 43 6d 64 5b 69 5d 2e 63 6c  c, aObjCmd[i].cl
5a50: 69 65 6e 74 44 61 74 61 2c 20 30 29 3b 0a 20 20  ientData, 0);.  
5a60: 7d 0a 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 4f  }.  return TCL_O
5a70: 4b 3b 0a 7d 0a                                   K;.}.