/ Hex Artifact Content
Login

Artifact 06c0a7b6057b8733f8ef94e9eae815b32141c143:


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 31 33 20 32  test8.c,v 1.13 2
0230: 30 30 36 2f 30 36 2f 31 34 20 30 36 3a 35 38 3a  006/06/14 06:58:
0240: 31 36 20 64 61 6e 69 65 6c 6b 31 39 37 37 20 45  16 danielk1977 E
0250: 78 70 20 24 0a 2a 2f 0a 23 69 6e 63 6c 75 64 65  xp $.*/.#include
0260: 20 22 73 71 6c 69 74 65 49 6e 74 2e 68 22 0a 23   "sqliteInt.h".#
0270: 69 6e 63 6c 75 64 65 20 22 74 63 6c 2e 68 22 0a  include "tcl.h".
0280: 23 69 6e 63 6c 75 64 65 20 22 6f 73 2e 68 22 0a  #include "os.h".
0290: 23 69 6e 63 6c 75 64 65 20 3c 73 74 64 6c 69 62  #include <stdlib
02a0: 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 73 74  .h>.#include <st
02b0: 72 69 6e 67 2e 68 3e 0a 0a 74 79 70 65 64 65 66  ring.h>..typedef
02c0: 20 73 74 72 75 63 74 20 65 63 68 6f 5f 76 74 61   struct echo_vta
02d0: 62 20 65 63 68 6f 5f 76 74 61 62 3b 0a 74 79 70  b echo_vtab;.typ
02e0: 65 64 65 66 20 73 74 72 75 63 74 20 65 63 68 6f  edef struct echo
02f0: 5f 63 75 72 73 6f 72 20 65 63 68 6f 5f 63 75 72  _cursor echo_cur
0300: 73 6f 72 3b 0a 0a 2f 2a 20 0a 2a 2a 20 41 6e 20  sor;../* .** An 
0310: 65 63 68 6f 20 76 69 72 74 75 61 6c 2d 74 61 62  echo virtual-tab
0320: 6c 65 20 6f 62 6a 65 63 74 20 0a 2a 2a 0a 2a 2a  le object .**.**
0330: 20 49 66 20 69 74 20 69 73 20 6e 6f 74 20 4e 55   If it is not NU
0340: 4c 4c 2c 20 74 68 65 20 61 48 61 73 49 6e 64 65  LL, the aHasInde
0350: 78 20 61 72 72 61 79 20 69 73 20 61 6c 6c 6f 63  x array is alloc
0360: 61 74 65 64 20 73 6f 20 74 68 61 74 20 69 74 20  ated so that it 
0370: 68 61 73 0a 2a 2a 20 74 68 65 20 73 61 6d 65 20  has.** the same 
0380: 6e 75 6d 62 65 72 20 6f 66 20 65 6e 74 72 69 65  number of entrie
0390: 73 20 61 73 20 74 68 65 72 65 20 61 72 65 20 63  s as there are c
03a0: 6f 6c 75 6d 6e 73 20 69 6e 20 74 68 65 20 75 6e  olumns in the un
03b0: 64 65 72 6c 79 69 6e 67 0a 2a 2a 20 72 65 61 6c  derlying.** real
03c0: 20 74 61 62 6c 65 2e 0a 2a 2f 0a 73 74 72 75 63   table..*/.struc
03d0: 74 20 65 63 68 6f 5f 76 74 61 62 20 7b 0a 20 20  t echo_vtab {.  
03e0: 73 71 6c 69 74 65 33 5f 76 74 61 62 20 62 61 73  sqlite3_vtab bas
03f0: 65 3b 0a 20 20 54 63 6c 5f 49 6e 74 65 72 70 20  e;.  Tcl_Interp 
0400: 2a 69 6e 74 65 72 70 3b 0a 20 20 73 71 6c 69 74  *interp;.  sqlit
0410: 65 33 20 2a 64 62 3b 0a 0a 20 20 63 68 61 72 20  e3 *db;..  char 
0420: 2a 7a 54 61 62 6c 65 4e 61 6d 65 3b 20 20 20 20  *zTableName;    
0430: 20 20 20 2f 2a 20 4e 61 6d 65 20 6f 66 20 74 68     /* Name of th
0440: 65 20 72 65 61 6c 20 74 61 62 6c 65 20 2a 2f 0a  e real table */.
0450: 20 20 69 6e 74 20 6e 43 6f 6c 3b 20 20 20 20 20    int nCol;     
0460: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d            /* Num
0470: 62 65 72 20 6f 66 20 63 6f 6c 75 6d 6e 73 20 69  ber of columns i
0480: 6e 20 74 68 65 20 72 65 61 6c 20 74 61 62 6c 65  n the real table
0490: 20 2a 2f 0a 20 20 69 6e 74 20 2a 61 49 6e 64 65   */.  int *aInde
04a0: 78 3b 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a  x;            /*
04b0: 20 41 72 72 61 79 20 6f 66 20 73 69 7a 65 20 6e   Array of size n
04c0: 43 6f 6c 2e 20 54 72 75 65 20 69 66 20 63 6f 6c  Col. True if col
04d0: 75 6d 6e 20 68 61 73 20 61 6e 20 69 6e 64 65 78  umn has an index
04e0: 20 2a 2f 0a 20 20 63 68 61 72 20 2a 2a 61 43 6f   */.  char **aCo
04f0: 6c 3b 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a  l;            /*
0500: 20 41 72 72 61 79 20 6f 66 20 73 69 7a 65 20 6e   Array of size n
0510: 43 6f 6c 2e 20 43 6f 6c 75 6d 6e 20 6e 61 6d 65  Col. Column name
0520: 73 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 20 41 6e 20 65  s */.};../* An e
0530: 63 68 6f 20 63 75 72 73 6f 72 20 6f 62 6a 65 63  cho cursor objec
0540: 74 20 2a 2f 0a 73 74 72 75 63 74 20 65 63 68 6f  t */.struct echo
0550: 5f 63 75 72 73 6f 72 20 7b 0a 20 20 73 71 6c 69  _cursor {.  sqli
0560: 74 65 33 5f 76 74 61 62 5f 63 75 72 73 6f 72 20  te3_vtab_cursor 
0570: 62 61 73 65 3b 0a 20 20 73 71 6c 69 74 65 33 5f  base;.  sqlite3_
0580: 73 74 6d 74 20 2a 70 53 74 6d 74 3b 0a 20 20 69  stmt *pStmt;.  i
0590: 6e 74 20 65 72 72 63 6f 64 65 3b 20 20 20 20 20  nt errcode;     
05a0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 45              /* E
05b0: 72 72 6f 72 20 63 6f 64 65 20 2a 2f 0a 7d 3b 0a  rror code */.};.
05c0: 0a 73 74 61 74 69 63 20 69 6e 74 20 67 65 74 43  .static int getC
05d0: 6f 6c 75 6d 6e 4e 61 6d 65 73 28 0a 20 20 73 71  olumnNames(.  sq
05e0: 6c 69 74 65 33 20 2a 64 62 2c 20 0a 20 20 63 6f  lite3 *db, .  co
05f0: 6e 73 74 20 63 68 61 72 20 2a 7a 54 61 62 2c 0a  nst char *zTab,.
0600: 20 20 63 68 61 72 20 2a 2a 2a 70 61 43 6f 6c 2c    char ***paCol,
0610: 20 0a 20 20 69 6e 74 20 2a 70 6e 43 6f 6c 0a 29   .  int *pnCol.)
0620: 7b 0a 20 20 63 68 61 72 20 2a 2a 61 43 6f 6c 20  {.  char **aCol 
0630: 3d 20 30 3b 0a 20 20 63 68 61 72 20 7a 42 75 66  = 0;.  char zBuf
0640: 5b 31 30 32 34 5d 3b 0a 20 20 73 71 6c 69 74 65  [1024];.  sqlite
0650: 33 5f 73 74 6d 74 20 2a 70 53 74 6d 74 20 3d 20  3_stmt *pStmt = 
0660: 30 3b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51  0;.  int rc = SQ
0670: 4c 49 54 45 5f 4f 4b 3b 0a 20 20 69 6e 74 20 6e  LITE_OK;.  int n
0680: 43 6f 6c 3b 0a 0a 20 20 73 70 72 69 6e 74 66 28  Col;..  sprintf(
0690: 7a 42 75 66 2c 20 22 53 45 4c 45 43 54 20 2a 20  zBuf, "SELECT * 
06a0: 46 52 4f 4d 20 25 73 22 2c 20 7a 54 61 62 29 3b  FROM %s", zTab);
06b0: 0a 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f  .  rc = sqlite3_
06c0: 70 72 65 70 61 72 65 28 64 62 2c 20 7a 42 75 66  prepare(db, zBuf
06d0: 2c 20 2d 31 2c 20 26 70 53 74 6d 74 2c 20 30 29  , -1, &pStmt, 0)
06e0: 3b 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49  ;.  if( rc==SQLI
06f0: 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 69 6e 74  TE_OK ){.    int
0700: 20 69 69 3b 0a 20 20 20 20 6e 43 6f 6c 20 3d 20   ii;.    nCol = 
0710: 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 63  sqlite3_column_c
0720: 6f 75 6e 74 28 70 53 74 6d 74 29 3b 0a 20 20 20  ount(pStmt);.   
0730: 20 61 43 6f 6c 20 3d 20 73 71 6c 69 74 65 4d 61   aCol = sqliteMa
0740: 6c 6c 6f 63 28 73 69 7a 65 6f 66 28 63 68 61 72  lloc(sizeof(char
0750: 20 2a 29 20 2a 20 6e 43 6f 6c 29 3b 0a 20 20 20   *) * nCol);.   
0760: 20 69 66 28 20 21 61 43 6f 6c 20 29 7b 0a 20 20   if( !aCol ){.  
0770: 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f      rc = SQLITE_
0780: 4e 4f 4d 45 4d 3b 0a 20 20 20 20 20 20 67 6f 74  NOMEM;.      got
0790: 6f 20 66 61 69 6c 3b 0a 20 20 20 20 7d 0a 20 20  o fail;.    }.  
07a0: 20 20 66 6f 72 28 69 69 3d 30 3b 20 69 69 3c 6e    for(ii=0; ii<n
07b0: 43 6f 6c 3b 20 69 69 2b 2b 29 7b 0a 20 20 20 20  Col; ii++){.    
07c0: 20 20 61 43 6f 6c 5b 69 69 5d 20 3d 20 73 71 6c    aCol[ii] = sql
07d0: 69 74 65 33 53 74 72 44 75 70 28 73 71 6c 69 74  ite3StrDup(sqlit
07e0: 65 33 5f 63 6f 6c 75 6d 6e 5f 6e 61 6d 65 28 70  e3_column_name(p
07f0: 53 74 6d 74 2c 20 69 69 29 29 3b 0a 20 20 20 20  Stmt, ii));.    
0800: 20 20 69 66 28 20 21 61 43 6f 6c 5b 69 69 5d 20    if( !aCol[ii] 
0810: 29 7b 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20  ){.        rc = 
0820: 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20  SQLITE_NOMEM;.  
0830: 20 20 20 20 20 20 67 6f 74 6f 20 66 61 69 6c 3b        goto fail;
0840: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20  .      }.    }. 
0850: 20 7d 0a 0a 20 20 2a 70 61 43 6f 6c 20 3d 20 61   }..  *paCol = a
0860: 43 6f 6c 3b 0a 20 20 2a 70 6e 43 6f 6c 20 3d 20  Col;.  *pnCol = 
0870: 6e 43 6f 6c 3b 0a 0a 66 61 69 6c 3a 0a 20 20 73  nCol;..fail:.  s
0880: 71 6c 69 74 65 33 5f 66 69 6e 61 6c 69 7a 65 28  qlite3_finalize(
0890: 70 53 74 6d 74 29 3b 0a 20 20 69 66 28 20 72 63  pStmt);.  if( rc
08a0: 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20 61  !=SQLITE_OK && a
08b0: 43 6f 6c 20 29 7b 0a 20 20 20 20 69 6e 74 20 69  Col ){.    int i
08c0: 69 3b 0a 20 20 20 20 66 6f 72 28 69 69 3d 30 3b  i;.    for(ii=0;
08d0: 20 69 69 3c 6e 43 6f 6c 3b 20 69 69 2b 2b 29 7b   ii<nCol; ii++){
08e0: 0a 20 20 20 20 20 20 73 71 6c 69 74 65 46 72 65  .      sqliteFre
08f0: 65 28 61 43 6f 6c 5b 69 69 5d 29 3b 0a 20 20 20  e(aCol[ii]);.   
0900: 20 7d 0a 20 20 20 20 73 71 6c 69 74 65 46 72 65   }.    sqliteFre
0910: 65 28 61 43 6f 6c 29 3b 0a 20 20 7d 0a 20 20 72  e(aCol);.  }.  r
0920: 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 73 74 61  eturn rc;.}..sta
0930: 74 69 63 20 69 6e 74 20 67 65 74 49 6e 64 65 78  tic int getIndex
0940: 41 72 72 61 79 28 73 71 6c 69 74 65 33 20 2a 64  Array(sqlite3 *d
0950: 62 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a  b, const char *z
0960: 54 61 62 2c 20 69 6e 74 20 2a 2a 70 61 49 6e 64  Tab, int **paInd
0970: 65 78 29 7b 0a 20 20 63 68 61 72 20 7a 42 75 66  ex){.  char zBuf
0980: 5b 31 30 32 34 5d 3b 0a 20 20 73 71 6c 69 74 65  [1024];.  sqlite
0990: 33 5f 73 74 6d 74 20 2a 70 53 74 6d 74 20 3d 20  3_stmt *pStmt = 
09a0: 30 3b 0a 20 20 69 6e 74 20 6e 43 6f 6c 3b 0a 20  0;.  int nCol;. 
09b0: 20 69 6e 74 20 2a 61 49 6e 64 65 78 20 3d 20 30   int *aIndex = 0
09c0: 3b 0a 20 20 69 6e 74 20 72 63 3b 0a 0a 20 20 73  ;.  int rc;..  s
09d0: 70 72 69 6e 74 66 28 7a 42 75 66 2c 20 22 53 45  printf(zBuf, "SE
09e0: 4c 45 43 54 20 2a 20 46 52 4f 4d 20 25 73 22 2c  LECT * FROM %s",
09f0: 20 7a 54 61 62 29 3b 0a 20 20 72 63 20 3d 20 73   zTab);.  rc = s
0a00: 71 6c 69 74 65 33 5f 70 72 65 70 61 72 65 28 64  qlite3_prepare(d
0a10: 62 2c 20 7a 42 75 66 2c 20 2d 31 2c 20 26 70 53  b, zBuf, -1, &pS
0a20: 74 6d 74 2c 20 30 29 3b 0a 20 20 6e 43 6f 6c 20  tmt, 0);.  nCol 
0a30: 3d 20 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e  = sqlite3_column
0a40: 5f 63 6f 75 6e 74 28 70 53 74 6d 74 29 3b 0a 0a  _count(pStmt);..
0a50: 20 20 73 71 6c 69 74 65 33 5f 66 69 6e 61 6c 69    sqlite3_finali
0a60: 7a 65 28 70 53 74 6d 74 29 3b 0a 20 20 70 53 74  ze(pStmt);.  pSt
0a70: 6d 74 20 3d 20 30 3b 0a 20 20 69 66 28 20 72 63  mt = 0;.  if( rc
0a80: 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  !=SQLITE_OK ){. 
0a90: 20 20 20 67 6f 74 6f 20 67 65 74 5f 69 6e 64 65     goto get_inde
0aa0: 78 5f 61 72 72 61 79 5f 6f 75 74 3b 0a 20 20 7d  x_array_out;.  }
0ab0: 0a 0a 20 20 61 49 6e 64 65 78 20 3d 20 28 69 6e  ..  aIndex = (in
0ac0: 74 20 2a 29 73 71 6c 69 74 65 4d 61 6c 6c 6f 63  t *)sqliteMalloc
0ad0: 28 73 69 7a 65 6f 66 28 69 6e 74 29 20 2a 20 6e  (sizeof(int) * n
0ae0: 43 6f 6c 29 3b 0a 20 20 69 66 28 20 21 61 49 6e  Col);.  if( !aIn
0af0: 64 65 78 20 29 7b 0a 20 20 20 20 72 63 20 3d 20  dex ){.    rc = 
0b00: 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20  SQLITE_NOMEM;.  
0b10: 20 20 67 6f 74 6f 20 67 65 74 5f 69 6e 64 65 78    goto get_index
0b20: 5f 61 72 72 61 79 5f 6f 75 74 3b 0a 20 20 7d 0a  _array_out;.  }.
0b30: 0a 20 20 73 70 72 69 6e 74 66 28 7a 42 75 66 2c  .  sprintf(zBuf,
0b40: 20 22 50 52 41 47 4d 41 20 69 6e 64 65 78 5f 6c   "PRAGMA index_l
0b50: 69 73 74 28 25 73 29 22 2c 20 7a 54 61 62 29 3b  ist(%s)", zTab);
0b60: 0a 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f  .  rc = sqlite3_
0b70: 70 72 65 70 61 72 65 28 64 62 2c 20 7a 42 75 66  prepare(db, zBuf
0b80: 2c 20 2d 31 2c 20 26 70 53 74 6d 74 2c 20 30 29  , -1, &pStmt, 0)
0b90: 3b 0a 0a 20 20 77 68 69 6c 65 28 20 70 53 74 6d  ;..  while( pStm
0ba0: 74 20 26 26 20 73 71 6c 69 74 65 33 5f 73 74 65  t && sqlite3_ste
0bb0: 70 28 70 53 74 6d 74 29 3d 3d 53 51 4c 49 54 45  p(pStmt)==SQLITE
0bc0: 5f 52 4f 57 20 29 7b 0a 20 20 20 20 73 71 6c 69  _ROW ){.    sqli
0bd0: 74 65 33 5f 73 74 6d 74 20 2a 70 53 74 6d 74 32  te3_stmt *pStmt2
0be0: 20 3d 20 30 3b 0a 20 20 20 20 73 70 72 69 6e 74   = 0;.    sprint
0bf0: 66 28 7a 42 75 66 2c 20 22 50 52 41 47 4d 41 20  f(zBuf, "PRAGMA 
0c00: 69 6e 64 65 78 5f 69 6e 66 6f 28 25 73 29 22 2c  index_info(%s)",
0c10: 20 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f   sqlite3_column_
0c20: 74 65 78 74 28 70 53 74 6d 74 2c 20 31 29 29 3b  text(pStmt, 1));
0c30: 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65  .    rc = sqlite
0c40: 33 5f 70 72 65 70 61 72 65 28 64 62 2c 20 7a 42  3_prepare(db, zB
0c50: 75 66 2c 20 2d 31 2c 20 26 70 53 74 6d 74 32 2c  uf, -1, &pStmt2,
0c60: 20 30 29 3b 0a 20 20 20 20 69 66 28 20 70 53 74   0);.    if( pSt
0c70: 6d 74 32 20 26 26 20 73 71 6c 69 74 65 33 5f 73  mt2 && sqlite3_s
0c80: 74 65 70 28 70 53 74 6d 74 32 29 3d 3d 53 51 4c  tep(pStmt2)==SQL
0c90: 49 54 45 5f 52 4f 57 20 29 7b 0a 20 20 20 20 20  ITE_ROW ){.     
0ca0: 20 69 6e 74 20 63 69 64 20 3d 20 73 71 6c 69 74   int cid = sqlit
0cb0: 65 33 5f 63 6f 6c 75 6d 6e 5f 69 6e 74 28 70 53  e3_column_int(pS
0cc0: 74 6d 74 32 2c 20 31 29 3b 0a 20 20 20 20 20 20  tmt2, 1);.      
0cd0: 61 73 73 65 72 74 28 20 63 69 64 3e 3d 30 20 26  assert( cid>=0 &
0ce0: 26 20 63 69 64 3c 6e 43 6f 6c 20 29 3b 0a 20 20  & cid<nCol );.  
0cf0: 20 20 20 20 61 49 6e 64 65 78 5b 63 69 64 5d 20      aIndex[cid] 
0d00: 3d 20 31 3b 0a 20 20 20 20 7d 0a 20 20 20 20 72  = 1;.    }.    r
0d10: 63 20 3d 20 73 71 6c 69 74 65 33 5f 66 69 6e 61  c = sqlite3_fina
0d20: 6c 69 7a 65 28 70 53 74 6d 74 32 29 3b 0a 20 20  lize(pStmt2);.  
0d30: 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45    if( rc!=SQLITE
0d40: 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 73 71 6c  _OK ){.      sql
0d50: 69 74 65 33 5f 66 69 6e 61 6c 69 7a 65 28 70 53  ite3_finalize(pS
0d60: 74 6d 74 29 3b 0a 20 20 20 20 20 20 67 6f 74 6f  tmt);.      goto
0d70: 20 67 65 74 5f 69 6e 64 65 78 5f 61 72 72 61 79   get_index_array
0d80: 5f 6f 75 74 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a  _out;.    }.  }.
0d90: 0a 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f  .  rc = sqlite3_
0da0: 66 69 6e 61 6c 69 7a 65 28 70 53 74 6d 74 29 3b  finalize(pStmt);
0db0: 0a 0a 67 65 74 5f 69 6e 64 65 78 5f 61 72 72 61  ..get_index_arra
0dc0: 79 5f 6f 75 74 3a 0a 20 20 69 66 28 20 72 63 21  y_out:.  if( rc!
0dd0: 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20  =SQLITE_OK ){.  
0de0: 20 20 73 71 6c 69 74 65 46 72 65 65 28 61 49 6e    sqliteFree(aIn
0df0: 64 65 78 29 3b 0a 20 20 20 20 61 49 6e 64 65 78  dex);.    aIndex
0e00: 20 3d 20 30 3b 0a 20 20 7d 0a 20 20 2a 70 61 49   = 0;.  }.  *paI
0e10: 6e 64 65 78 20 3d 20 61 49 6e 64 65 78 3b 0a 20  ndex = aIndex;. 
0e20: 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f   return rc;.}../
0e30: 2a 0a 2a 2a 20 47 6c 6f 62 61 6c 20 54 63 6c 20  *.** Global Tcl 
0e40: 76 61 72 69 61 62 6c 65 20 24 65 63 68 6f 5f 6d  variable $echo_m
0e50: 6f 64 75 6c 65 20 69 73 20 61 20 6c 69 73 74 2e  odule is a list.
0e60: 20 54 68 69 73 20 72 6f 75 74 69 6e 65 20 61 70   This routine ap
0e70: 70 65 6e 64 73 0a 2a 2a 20 74 68 65 20 73 74 72  pends.** the str
0e80: 69 6e 67 20 65 6c 65 6d 65 6e 74 20 7a 41 72 67  ing element zArg
0e90: 20 74 6f 20 74 68 61 74 20 6c 69 73 74 20 69 6e   to that list in
0ea0: 20 69 6e 74 65 72 70 72 65 74 65 72 20 69 6e 74   interpreter int
0eb0: 65 72 70 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76  erp..*/.static v
0ec0: 6f 69 64 20 61 70 70 65 6e 64 54 6f 45 63 68 6f  oid appendToEcho
0ed0: 4d 6f 64 75 6c 65 28 54 63 6c 5f 49 6e 74 65 72  Module(Tcl_Inter
0ee0: 70 20 2a 69 6e 74 65 72 70 2c 20 63 6f 6e 73 74  p *interp, const
0ef0: 20 63 68 61 72 20 2a 7a 41 72 67 29 7b 0a 20 20   char *zArg){.  
0f00: 69 6e 74 20 66 6c 61 67 73 20 3d 20 28 54 43 4c  int flags = (TCL
0f10: 5f 41 50 50 45 4e 44 5f 56 41 4c 55 45 20 7c 20  _APPEND_VALUE | 
0f20: 54 43 4c 5f 4c 49 53 54 5f 45 4c 45 4d 45 4e 54  TCL_LIST_ELEMENT
0f30: 20 7c 20 54 43 4c 5f 47 4c 4f 42 41 4c 5f 4f 4e   | TCL_GLOBAL_ON
0f40: 4c 59 29 3b 0a 20 20 54 63 6c 5f 53 65 74 56 61  LY);.  Tcl_SetVa
0f50: 72 28 69 6e 74 65 72 70 2c 20 22 65 63 68 6f 5f  r(interp, "echo_
0f60: 6d 6f 64 75 6c 65 22 2c 20 28 7a 41 72 67 3f 7a  module", (zArg?z
0f70: 41 72 67 3a 22 22 29 2c 20 66 6c 61 67 73 29 3b  Arg:""), flags);
0f80: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 66  .}../*.** This f
0f90: 75 6e 63 74 69 6f 6e 20 69 73 20 63 61 6c 6c 65  unction is calle
0fa0: 64 20 66 72 6f 6d 20 77 69 74 68 69 6e 20 74 68  d from within th
0fb0: 65 20 65 63 68 6f 2d 6d 6f 64 75 6c 65 73 20 78  e echo-modules x
0fc0: 43 72 65 61 74 65 20 61 6e 64 0a 2a 2a 20 78 43  Create and.** xC
0fd0: 6f 6e 6e 65 63 74 20 6d 65 74 68 6f 64 73 2e 20  onnect methods. 
0fe0: 54 68 65 20 61 72 67 63 20 61 6e 64 20 61 72 67  The argc and arg
0ff0: 76 20 61 72 67 75 6d 65 6e 74 73 20 61 72 65 20  v arguments are 
1000: 63 6f 70 69 65 73 20 6f 66 20 74 68 6f 73 65 20  copies of those 
1010: 0a 2a 2a 20 70 61 73 73 65 64 20 74 6f 20 74 68  .** passed to th
1020: 65 20 63 61 6c 6c 69 6e 67 20 6d 65 74 68 6f 64  e calling method
1030: 2e 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20  . This function 
1040: 69 73 20 72 65 73 70 6f 6e 73 69 62 6c 65 20 66  is responsible f
1050: 6f 72 0a 2a 2a 20 63 61 6c 6c 69 6e 67 20 73 71  or.** calling sq
1060: 6c 69 74 65 33 5f 64 65 63 6c 61 72 65 5f 76 74  lite3_declare_vt
1070: 61 62 28 29 20 74 6f 20 64 65 63 6c 61 72 65 20  ab() to declare 
1080: 74 68 65 20 73 63 68 65 6d 61 20 6f 66 20 74 68  the schema of th
1090: 65 20 76 69 72 74 75 61 6c 0a 2a 2a 20 74 61 62  e virtual.** tab
10a0: 6c 65 20 62 65 69 6e 67 20 63 72 65 61 74 65 64  le being created
10b0: 20 6f 72 20 63 6f 6e 6e 65 63 74 65 64 2e 0a 2a   or connected..*
10c0: 2a 0a 2a 2a 20 49 66 20 74 68 65 20 63 6f 6e 73  *.** If the cons
10d0: 74 72 75 63 74 6f 72 20 77 61 73 20 70 61 73 73  tructor was pass
10e0: 65 64 20 6a 75 73 74 20 6f 6e 65 20 61 72 67 75  ed just one argu
10f0: 6d 65 6e 74 2c 20 69 2e 65 2e 3a 0a 2a 2a 0a 2a  ment, i.e.:.**.*
1100: 2a 20 20 20 43 52 45 41 54 45 20 54 41 42 4c 45  *   CREATE TABLE
1110: 20 74 31 20 41 53 20 65 63 68 6f 28 74 32 29 3b   t1 AS echo(t2);
1120: 0a 2a 2a 0a 2a 2a 20 54 68 65 6e 20 74 32 20 69  .**.** Then t2 i
1130: 73 20 61 73 73 75 6d 65 64 20 74 6f 20 62 65 20  s assumed to be 
1140: 74 68 65 20 6e 61 6d 65 20 6f 66 20 61 20 2a 72  the name of a *r
1150: 65 61 6c 2a 20 64 61 74 61 62 61 73 65 20 74 61  eal* database ta
1160: 62 6c 65 2e 20 54 68 65 0a 2a 2a 20 73 63 68 65  ble. The.** sche
1170: 6d 61 20 6f 66 20 74 68 65 20 76 69 72 74 75 61  ma of the virtua
1180: 6c 20 74 61 62 6c 65 20 69 73 20 64 65 63 6c 61  l table is decla
1190: 72 65 64 20 62 79 20 70 61 73 73 69 6e 67 20 61  red by passing a
11a0: 20 63 6f 70 79 20 6f 66 20 74 68 65 20 0a 2a 2a   copy of the .**
11b0: 20 43 52 45 41 54 45 20 54 41 42 4c 45 20 73 74   CREATE TABLE st
11c0: 61 74 65 6d 65 6e 74 20 66 6f 72 20 74 68 65 20  atement for the 
11d0: 72 65 61 6c 20 74 61 62 6c 65 20 74 6f 20 73 71  real table to sq
11e0: 6c 69 74 65 33 5f 64 65 63 6c 61 72 65 5f 76 74  lite3_declare_vt
11f0: 61 62 28 29 2e 0a 2a 2a 20 48 65 6e 63 65 2c 20  ab()..** Hence, 
1200: 74 68 65 20 76 69 72 74 75 61 6c 20 74 61 62 6c  the virtual tabl
1210: 65 20 73 68 6f 75 6c 64 20 68 61 76 65 20 65 78  e should have ex
1220: 61 63 74 6c 79 20 74 68 65 20 73 61 6d 65 20 63  actly the same c
1230: 6f 6c 75 6d 6e 20 6e 61 6d 65 73 20 61 6e 64 20  olumn names and 
1240: 0a 2a 2a 20 74 79 70 65 73 20 61 73 20 74 68 65  .** types as the
1250: 20 72 65 61 6c 20 74 61 62 6c 65 2e 0a 2a 2f 0a   real table..*/.
1260: 73 74 61 74 69 63 20 69 6e 74 20 65 63 68 6f 44  static int echoD
1270: 65 63 6c 61 72 65 56 74 61 62 28 0a 20 20 65 63  eclareVtab(.  ec
1280: 68 6f 5f 76 74 61 62 20 2a 70 56 74 61 62 2c 20  ho_vtab *pVtab, 
1290: 0a 20 20 73 71 6c 69 74 65 33 20 2a 64 62 2c 20  .  sqlite3 *db, 
12a0: 0a 20 20 69 6e 74 20 61 72 67 63 2c 20 0a 20 20  .  int argc, .  
12b0: 63 68 61 72 20 2a 2a 61 72 67 76 0a 29 7b 0a 20  char **argv.){. 
12c0: 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45   int rc = SQLITE
12d0: 5f 4f 4b 3b 0a 0a 20 20 69 66 28 20 61 72 67 63  _OK;..  if( argc
12e0: 3d 3d 32 20 29 7b 0a 20 20 20 20 73 71 6c 69 74  ==2 ){.    sqlit
12f0: 65 33 5f 73 74 6d 74 20 2a 70 53 74 6d 74 20 3d  e3_stmt *pStmt =
1300: 20 30 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f   0;.    sqlite3_
1310: 70 72 65 70 61 72 65 28 64 62 2c 20 0a 20 20 20  prepare(db, .   
1320: 20 20 20 20 20 22 53 45 4c 45 43 54 20 73 71 6c       "SELECT sql
1330: 20 46 52 4f 4d 20 73 71 6c 69 74 65 5f 6d 61 73   FROM sqlite_mas
1340: 74 65 72 20 57 48 45 52 45 20 74 79 70 65 20 3d  ter WHERE type =
1350: 20 27 74 61 62 6c 65 27 20 41 4e 44 20 6e 61 6d   'table' AND nam
1360: 65 20 3d 20 3f 22 2c 0a 20 20 20 20 20 20 20 20  e = ?",.        
1370: 2d 31 2c 20 26 70 53 74 6d 74 2c 20 30 29 3b 0a  -1, &pStmt, 0);.
1380: 20 20 20 20 73 71 6c 69 74 65 33 5f 62 69 6e 64      sqlite3_bind
1390: 5f 74 65 78 74 28 70 53 74 6d 74 2c 20 31 2c 20  _text(pStmt, 1, 
13a0: 61 72 67 76 5b 31 5d 2c 20 2d 31 2c 20 30 29 3b  argv[1], -1, 0);
13b0: 0a 20 20 20 20 69 66 28 20 73 71 6c 69 74 65 33  .    if( sqlite3
13c0: 5f 73 74 65 70 28 70 53 74 6d 74 29 3d 3d 53 51  _step(pStmt)==SQ
13d0: 4c 49 54 45 5f 52 4f 57 20 29 7b 0a 20 20 20 20  LITE_ROW ){.    
13e0: 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 43    const char *zC
13f0: 72 65 61 74 65 54 61 62 6c 65 20 3d 20 73 71 6c  reateTable = sql
1400: 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 74 65 78 74  ite3_column_text
1410: 28 70 53 74 6d 74 2c 20 30 29 3b 0a 23 69 66 6e  (pStmt, 0);.#ifn
1420: 64 65 66 20 53 51 4c 49 54 45 5f 4f 4d 49 54 5f  def SQLITE_OMIT_
1430: 56 49 52 54 55 41 4c 54 41 42 4c 45 0a 20 20 20  VIRTUALTABLE.   
1440: 20 20 20 73 71 6c 69 74 65 33 5f 64 65 63 6c 61     sqlite3_decla
1450: 72 65 5f 76 74 61 62 28 64 62 2c 20 7a 43 72 65  re_vtab(db, zCre
1460: 61 74 65 54 61 62 6c 65 29 3b 0a 23 65 6e 64 69  ateTable);.#endi
1470: 66 0a 20 20 20 20 7d 20 65 6c 73 65 20 7b 0a 20  f.    } else {. 
1480: 20 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45       rc = SQLITE
1490: 5f 45 52 52 4f 52 3b 0a 20 20 20 20 7d 0a 20 20  _ERROR;.    }.  
14a0: 20 20 73 71 6c 69 74 65 33 5f 66 69 6e 61 6c 69    sqlite3_finali
14b0: 7a 65 28 70 53 74 6d 74 29 3b 0a 20 20 20 20 69  ze(pStmt);.    i
14c0: 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc==SQLITE_OK
14d0: 20 29 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 67   ){.      rc = g
14e0: 65 74 49 6e 64 65 78 41 72 72 61 79 28 64 62 2c  etIndexArray(db,
14f0: 20 61 72 67 76 5b 31 5d 2c 20 26 70 56 74 61 62   argv[1], &pVtab
1500: 2d 3e 61 49 6e 64 65 78 29 3b 0a 20 20 20 20 7d  ->aIndex);.    }
1510: 0a 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c  .    if( rc==SQL
1520: 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20  ITE_OK ){.      
1530: 72 63 20 3d 20 67 65 74 43 6f 6c 75 6d 6e 4e 61  rc = getColumnNa
1540: 6d 65 73 28 64 62 2c 20 61 72 67 76 5b 31 5d 2c  mes(db, argv[1],
1550: 20 26 70 56 74 61 62 2d 3e 61 43 6f 6c 2c 20 26   &pVtab->aCol, &
1560: 70 56 74 61 62 2d 3e 6e 43 6f 6c 29 3b 0a 20 20  pVtab->nCol);.  
1570: 20 20 7d 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72    }.  }..  retur
1580: 6e 20 72 63 3b 0a 7d 0a 0a 73 74 61 74 69 63 20  n rc;.}..static 
1590: 69 6e 74 20 65 63 68 6f 44 65 73 74 72 75 63 74  int echoDestruct
15a0: 6f 72 28 73 71 6c 69 74 65 33 5f 76 74 61 62 20  or(sqlite3_vtab 
15b0: 2a 70 56 74 61 62 29 7b 0a 20 20 69 6e 74 20 69  *pVtab){.  int i
15c0: 69 3b 0a 20 20 65 63 68 6f 5f 76 74 61 62 20 2a  i;.  echo_vtab *
15d0: 70 20 3d 20 28 65 63 68 6f 5f 76 74 61 62 2a 29  p = (echo_vtab*)
15e0: 70 56 74 61 62 3b 0a 20 20 73 71 6c 69 74 65 46  pVtab;.  sqliteF
15f0: 72 65 65 28 70 2d 3e 61 49 6e 64 65 78 29 3b 0a  ree(p->aIndex);.
1600: 20 20 66 6f 72 28 69 69 3d 30 3b 20 69 69 3c 70    for(ii=0; ii<p
1610: 2d 3e 6e 43 6f 6c 3b 20 69 69 2b 2b 29 7b 0a 20  ->nCol; ii++){. 
1620: 20 20 20 73 71 6c 69 74 65 46 72 65 65 28 70 2d     sqliteFree(p-
1630: 3e 61 43 6f 6c 5b 69 69 5d 29 3b 0a 20 20 7d 0a  >aCol[ii]);.  }.
1640: 20 20 73 71 6c 69 74 65 46 72 65 65 28 70 2d 3e    sqliteFree(p->
1650: 61 43 6f 6c 29 3b 0a 20 20 73 71 6c 69 74 65 46  aCol);.  sqliteF
1660: 72 65 65 28 70 2d 3e 7a 54 61 62 6c 65 4e 61 6d  ree(p->zTableNam
1670: 65 29 3b 0a 20 20 73 71 6c 69 74 65 46 72 65 65  e);.  sqliteFree
1680: 28 70 29 3b 0a 20 20 72 65 74 75 72 6e 20 30 3b  (p);.  return 0;
1690: 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 65  .}..static int e
16a0: 63 68 6f 43 6f 6e 73 74 72 75 63 74 6f 72 28 0a  choConstructor(.
16b0: 20 20 73 71 6c 69 74 65 33 20 2a 64 62 2c 0a 20    sqlite3 *db,. 
16c0: 20 76 6f 69 64 20 2a 70 41 75 78 2c 0a 20 20 69   void *pAux,.  i
16d0: 6e 74 20 61 72 67 63 2c 20 63 68 61 72 20 2a 2a  nt argc, char **
16e0: 61 72 67 76 2c 0a 20 20 73 71 6c 69 74 65 33 5f  argv,.  sqlite3_
16f0: 76 74 61 62 20 2a 2a 70 70 56 74 61 62 0a 29 7b  vtab **ppVtab.){
1700: 0a 20 20 69 6e 74 20 69 3b 0a 20 20 65 63 68 6f  .  int i;.  echo
1710: 5f 76 74 61 62 20 2a 70 56 74 61 62 3b 0a 0a 20  _vtab *pVtab;.. 
1720: 20 70 56 74 61 62 20 3d 20 73 71 6c 69 74 65 4d   pVtab = sqliteM
1730: 61 6c 6c 6f 63 28 20 73 69 7a 65 6f 66 28 2a 70  alloc( sizeof(*p
1740: 56 74 61 62 29 20 29 3b 0a 20 20 70 56 74 61 62  Vtab) );.  pVtab
1750: 2d 3e 69 6e 74 65 72 70 20 3d 20 28 54 63 6c 5f  ->interp = (Tcl_
1760: 49 6e 74 65 72 70 20 2a 29 70 41 75 78 3b 0a 20  Interp *)pAux;. 
1770: 20 70 56 74 61 62 2d 3e 64 62 20 3d 20 64 62 3b   pVtab->db = db;
1780: 0a 20 20 70 56 74 61 62 2d 3e 7a 54 61 62 6c 65  .  pVtab->zTable
1790: 4e 61 6d 65 20 3d 20 73 71 6c 69 74 65 33 4d 50  Name = sqlite3MP
17a0: 72 69 6e 74 66 28 22 25 73 22 2c 20 61 72 67 76  rintf("%s", argv
17b0: 5b 31 5d 29 3b 0a 20 20 66 6f 72 28 69 3d 30 3b  [1]);.  for(i=0;
17c0: 20 69 3c 61 72 67 63 3b 20 69 2b 2b 29 7b 0a 20   i<argc; i++){. 
17d0: 20 20 20 61 70 70 65 6e 64 54 6f 45 63 68 6f 4d     appendToEchoM
17e0: 6f 64 75 6c 65 28 70 56 74 61 62 2d 3e 69 6e 74  odule(pVtab->int
17f0: 65 72 70 2c 20 61 72 67 76 5b 69 5d 29 3b 0a 20  erp, argv[i]);. 
1800: 20 7d 0a 0a 20 20 69 66 28 20 65 63 68 6f 44 65   }..  if( echoDe
1810: 63 6c 61 72 65 56 74 61 62 28 70 56 74 61 62 2c  clareVtab(pVtab,
1820: 20 64 62 2c 20 61 72 67 63 2c 20 61 72 67 76 29   db, argc, argv)
1830: 20 29 7b 0a 20 20 20 20 65 63 68 6f 44 65 73 74   ){.    echoDest
1840: 72 75 63 74 6f 72 28 28 73 71 6c 69 74 65 33 5f  ructor((sqlite3_
1850: 76 74 61 62 20 2a 29 70 56 74 61 62 29 3b 0a 20  vtab *)pVtab);. 
1860: 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45     return SQLITE
1870: 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a 0a 20 20 2a  _ERROR;.  }..  *
1880: 70 70 56 74 61 62 20 3d 20 26 70 56 74 61 62 2d  ppVtab = &pVtab-
1890: 3e 62 61 73 65 3b 0a 20 20 72 65 74 75 72 6e 20  >base;.  return 
18a0: 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a  SQLITE_OK;.}../*
18b0: 20 4d 65 74 68 6f 64 73 20 66 6f 72 20 74 68 65   Methods for the
18c0: 20 65 63 68 6f 20 6d 6f 64 75 6c 65 20 2a 2f 0a   echo module */.
18d0: 73 74 61 74 69 63 20 69 6e 74 20 65 63 68 6f 43  static int echoC
18e0: 72 65 61 74 65 28 0a 20 20 73 71 6c 69 74 65 33  reate(.  sqlite3
18f0: 20 2a 64 62 2c 0a 20 20 76 6f 69 64 20 2a 70 41   *db,.  void *pA
1900: 75 78 2c 0a 20 20 69 6e 74 20 61 72 67 63 2c 20  ux,.  int argc, 
1910: 63 68 61 72 20 2a 2a 61 72 67 76 2c 0a 20 20 73  char **argv,.  s
1920: 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 2a 70 70  qlite3_vtab **pp
1930: 56 74 61 62 0a 29 7b 0a 20 20 61 70 70 65 6e 64  Vtab.){.  append
1940: 54 6f 45 63 68 6f 4d 6f 64 75 6c 65 28 28 54 63  ToEchoModule((Tc
1950: 6c 5f 49 6e 74 65 72 70 20 2a 29 28 70 41 75 78  l_Interp *)(pAux
1960: 29 2c 20 22 78 43 72 65 61 74 65 22 29 3b 0a 20  ), "xCreate");. 
1970: 20 72 65 74 75 72 6e 20 65 63 68 6f 43 6f 6e 73   return echoCons
1980: 74 72 75 63 74 6f 72 28 64 62 2c 20 70 41 75 78  tructor(db, pAux
1990: 2c 20 61 72 67 63 2c 20 61 72 67 76 2c 20 70 70  , argc, argv, pp
19a0: 56 74 61 62 29 3b 0a 7d 0a 73 74 61 74 69 63 20  Vtab);.}.static 
19b0: 69 6e 74 20 65 63 68 6f 43 6f 6e 6e 65 63 74 28  int echoConnect(
19c0: 0a 20 20 73 71 6c 69 74 65 33 20 2a 64 62 2c 0a  .  sqlite3 *db,.
19d0: 20 20 76 6f 69 64 20 2a 70 41 75 78 2c 0a 20 20    void *pAux,.  
19e0: 69 6e 74 20 61 72 67 63 2c 20 63 68 61 72 20 2a  int argc, char *
19f0: 2a 61 72 67 76 2c 0a 20 20 73 71 6c 69 74 65 33  *argv,.  sqlite3
1a00: 5f 76 74 61 62 20 2a 2a 70 70 56 74 61 62 0a 29  _vtab **ppVtab.)
1a10: 7b 0a 20 20 61 70 70 65 6e 64 54 6f 45 63 68 6f  {.  appendToEcho
1a20: 4d 6f 64 75 6c 65 28 28 54 63 6c 5f 49 6e 74 65  Module((Tcl_Inte
1a30: 72 70 20 2a 29 28 70 41 75 78 29 2c 20 22 78 43  rp *)(pAux), "xC
1a40: 6f 6e 6e 65 63 74 22 29 3b 0a 20 20 72 65 74 75  onnect");.  retu
1a50: 72 6e 20 65 63 68 6f 43 6f 6e 73 74 72 75 63 74  rn echoConstruct
1a60: 6f 72 28 64 62 2c 20 70 41 75 78 2c 20 61 72 67  or(db, pAux, arg
1a70: 63 2c 20 61 72 67 76 2c 20 70 70 56 74 61 62 29  c, argv, ppVtab)
1a80: 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20  ;.}..static int 
1a90: 65 63 68 6f 44 69 73 63 6f 6e 6e 65 63 74 28 73  echoDisconnect(s
1aa0: 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 70 56 74  qlite3_vtab *pVt
1ab0: 61 62 29 7b 0a 20 20 61 70 70 65 6e 64 54 6f 45  ab){.  appendToE
1ac0: 63 68 6f 4d 6f 64 75 6c 65 28 28 28 65 63 68 6f  choModule(((echo
1ad0: 5f 76 74 61 62 20 2a 29 70 56 74 61 62 29 2d 3e  _vtab *)pVtab)->
1ae0: 69 6e 74 65 72 70 2c 20 22 78 44 69 73 63 6f 6e  interp, "xDiscon
1af0: 6e 65 63 74 22 29 3b 0a 20 20 72 65 74 75 72 6e  nect");.  return
1b00: 20 65 63 68 6f 44 65 73 74 72 75 63 74 6f 72 28   echoDestructor(
1b10: 70 56 74 61 62 29 3b 0a 7d 0a 73 74 61 74 69 63  pVtab);.}.static
1b20: 20 69 6e 74 20 65 63 68 6f 44 65 73 74 72 6f 79   int echoDestroy
1b30: 28 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 70  (sqlite3_vtab *p
1b40: 56 74 61 62 29 7b 0a 20 20 61 70 70 65 6e 64 54  Vtab){.  appendT
1b50: 6f 45 63 68 6f 4d 6f 64 75 6c 65 28 28 28 65 63  oEchoModule(((ec
1b60: 68 6f 5f 76 74 61 62 20 2a 29 70 56 74 61 62 29  ho_vtab *)pVtab)
1b70: 2d 3e 69 6e 74 65 72 70 2c 20 22 78 44 65 73 74  ->interp, "xDest
1b80: 72 6f 79 22 29 3b 0a 20 20 72 65 74 75 72 6e 20  roy");.  return 
1b90: 65 63 68 6f 44 65 73 74 72 75 63 74 6f 72 28 70  echoDestructor(p
1ba0: 56 74 61 62 29 3b 0a 7d 0a 0a 73 74 61 74 69 63  Vtab);.}..static
1bb0: 20 69 6e 74 20 65 63 68 6f 4f 70 65 6e 28 73 71   int echoOpen(sq
1bc0: 6c 69 74 65 33 5f 76 74 61 62 20 2a 70 56 54 61  lite3_vtab *pVTa
1bd0: 62 2c 20 73 71 6c 69 74 65 33 5f 76 74 61 62 5f  b, sqlite3_vtab_
1be0: 63 75 72 73 6f 72 20 2a 2a 70 70 43 75 72 73 6f  cursor **ppCurso
1bf0: 72 29 7b 0a 20 20 65 63 68 6f 5f 63 75 72 73 6f  r){.  echo_curso
1c00: 72 20 2a 70 43 75 72 3b 0a 20 20 70 43 75 72 20  r *pCur;.  pCur 
1c10: 3d 20 73 71 6c 69 74 65 4d 61 6c 6c 6f 63 28 73  = sqliteMalloc(s
1c20: 69 7a 65 6f 66 28 65 63 68 6f 5f 63 75 72 73 6f  izeof(echo_curso
1c30: 72 29 29 3b 0a 20 20 2a 70 70 43 75 72 73 6f 72  r));.  *ppCursor
1c40: 20 3d 20 28 73 71 6c 69 74 65 33 5f 76 74 61 62   = (sqlite3_vtab
1c50: 5f 63 75 72 73 6f 72 20 2a 29 70 43 75 72 3b 0a  _cursor *)pCur;.
1c60: 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f    return SQLITE_
1c70: 4f 4b 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e  OK;.}..static in
1c80: 74 20 65 63 68 6f 43 6c 6f 73 65 28 73 71 6c 69  t echoClose(sqli
1c90: 74 65 33 5f 76 74 61 62 5f 63 75 72 73 6f 72 20  te3_vtab_cursor 
1ca0: 2a 63 75 72 29 7b 0a 20 20 65 63 68 6f 5f 63 75  *cur){.  echo_cu
1cb0: 72 73 6f 72 20 2a 70 43 75 72 20 3d 20 28 65 63  rsor *pCur = (ec
1cc0: 68 6f 5f 63 75 72 73 6f 72 20 2a 29 63 75 72 3b  ho_cursor *)cur;
1cd0: 0a 20 20 73 71 6c 69 74 65 33 5f 66 69 6e 61 6c  .  sqlite3_final
1ce0: 69 7a 65 28 70 43 75 72 2d 3e 70 53 74 6d 74 29  ize(pCur->pStmt)
1cf0: 3b 0a 20 20 73 71 6c 69 74 65 46 72 65 65 28 70  ;.  sqliteFree(p
1d00: 43 75 72 29 3b 0a 20 20 72 65 74 75 72 6e 20 53  Cur);.  return S
1d10: 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 73 74 61  QLITE_OK;.}..sta
1d20: 74 69 63 20 69 6e 74 20 65 63 68 6f 4e 65 78 74  tic int echoNext
1d30: 28 73 71 6c 69 74 65 33 5f 76 74 61 62 5f 63 75  (sqlite3_vtab_cu
1d40: 72 73 6f 72 20 2a 63 75 72 29 7b 0a 20 20 69 6e  rsor *cur){.  in
1d50: 74 20 72 63 3b 0a 20 20 65 63 68 6f 5f 63 75 72  t rc;.  echo_cur
1d60: 73 6f 72 20 2a 70 43 75 72 20 3d 20 28 65 63 68  sor *pCur = (ech
1d70: 6f 5f 63 75 72 73 6f 72 20 2a 29 63 75 72 3b 0a  o_cursor *)cur;.
1d80: 0a 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f  .  rc = sqlite3_
1d90: 73 74 65 70 28 70 43 75 72 2d 3e 70 53 74 6d 74  step(pCur->pStmt
1da0: 29 3b 0a 0a 20 20 69 66 28 20 72 63 3d 3d 53 51  );..  if( rc==SQ
1db0: 4c 49 54 45 5f 52 4f 57 20 29 7b 0a 20 20 20 20  LITE_ROW ){.    
1dc0: 72 63 20 3d 20 31 3b 0a 20 20 7d 20 65 6c 73 65  rc = 1;.  } else
1dd0: 20 7b 0a 20 20 20 20 70 43 75 72 2d 3e 65 72 72   {.    pCur->err
1de0: 63 6f 64 65 20 3d 20 73 71 6c 69 74 65 33 5f 66  code = sqlite3_f
1df0: 69 6e 61 6c 69 7a 65 28 70 43 75 72 2d 3e 70 53  inalize(pCur->pS
1e00: 74 6d 74 29 3b 0a 20 20 20 20 70 43 75 72 2d 3e  tmt);.    pCur->
1e10: 70 53 74 6d 74 20 3d 20 30 3b 0a 20 20 20 20 72  pStmt = 0;.    r
1e20: 63 20 3d 20 30 3b 0a 20 20 7d 0a 0a 20 20 72 65  c = 0;.  }..  re
1e30: 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 73 74 61 74  turn rc;.}..stat
1e40: 69 63 20 69 6e 74 20 65 63 68 6f 43 6f 6c 75 6d  ic int echoColum
1e50: 6e 28 73 71 6c 69 74 65 33 5f 76 74 61 62 5f 63  n(sqlite3_vtab_c
1e60: 75 72 73 6f 72 20 2a 63 75 72 2c 20 73 71 6c 69  ursor *cur, sqli
1e70: 74 65 33 5f 63 6f 6e 74 65 78 74 20 2a 63 74 78  te3_context *ctx
1e80: 2c 20 69 6e 74 20 69 29 7b 0a 20 20 69 6e 74 20  , int i){.  int 
1e90: 69 43 6f 6c 20 3d 20 69 20 2b 20 31 3b 0a 20 20  iCol = i + 1;.  
1ea0: 73 71 6c 69 74 65 33 5f 73 74 6d 74 20 2a 70 53  sqlite3_stmt *pS
1eb0: 74 6d 74 20 3d 20 28 28 65 63 68 6f 5f 63 75 72  tmt = ((echo_cur
1ec0: 73 6f 72 20 2a 29 63 75 72 29 2d 3e 70 53 74 6d  sor *)cur)->pStm
1ed0: 74 3b 0a 0a 20 20 61 73 73 65 72 74 28 20 73 71  t;..  assert( sq
1ee0: 6c 69 74 65 33 5f 64 61 74 61 5f 63 6f 75 6e 74  lite3_data_count
1ef0: 28 70 53 74 6d 74 29 3e 69 43 6f 6c 20 29 3b 0a  (pStmt)>iCol );.
1f00: 20 20 73 71 6c 69 74 65 33 5f 72 65 73 75 6c 74    sqlite3_result
1f10: 5f 76 61 6c 75 65 28 63 74 78 2c 20 73 71 6c 69  _value(ctx, sqli
1f20: 74 65 33 5f 63 6f 6c 75 6d 6e 5f 76 61 6c 75 65  te3_column_value
1f30: 28 70 53 74 6d 74 2c 20 69 43 6f 6c 29 29 3b 0a  (pStmt, iCol));.
1f40: 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f    return SQLITE_
1f50: 4f 4b 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e  OK;.}..static in
1f60: 74 20 65 63 68 6f 52 6f 77 69 64 28 73 71 6c 69  t echoRowid(sqli
1f70: 74 65 33 5f 76 74 61 62 5f 63 75 72 73 6f 72 20  te3_vtab_cursor 
1f80: 2a 63 75 72 2c 20 73 71 6c 69 74 65 5f 69 6e 74  *cur, sqlite_int
1f90: 36 34 20 2a 70 52 6f 77 69 64 29 7b 0a 20 20 73  64 *pRowid){.  s
1fa0: 71 6c 69 74 65 33 5f 73 74 6d 74 20 2a 70 53 74  qlite3_stmt *pSt
1fb0: 6d 74 20 3d 20 28 28 65 63 68 6f 5f 63 75 72 73  mt = ((echo_curs
1fc0: 6f 72 20 2a 29 63 75 72 29 2d 3e 70 53 74 6d 74  or *)cur)->pStmt
1fd0: 3b 0a 20 20 2a 70 52 6f 77 69 64 20 3d 20 73 71  ;.  *pRowid = sq
1fe0: 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 69 6e 74  lite3_column_int
1ff0: 36 34 28 70 53 74 6d 74 2c 20 30 29 3b 0a 20 20  64(pStmt, 0);.  
2000: 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b  return SQLITE_OK
2010: 3b 0a 7d 0a 0a 0a 73 74 61 74 69 63 20 69 6e 74  ;.}...static int
2020: 20 65 63 68 6f 46 69 6c 74 65 72 28 0a 20 20 73   echoFilter(.  s
2030: 71 6c 69 74 65 33 5f 76 74 61 62 5f 63 75 72 73  qlite3_vtab_curs
2040: 6f 72 20 2a 70 56 74 61 62 43 75 72 73 6f 72 2c  or *pVtabCursor,
2050: 20 0a 20 20 69 6e 74 20 69 64 78 4e 75 6d 2c 20   .  int idxNum, 
2060: 63 6f 6e 73 74 20 63 68 61 72 20 2a 69 64 78 53  const char *idxS
2070: 74 72 2c 0a 20 20 69 6e 74 20 61 72 67 63 2c 20  tr,.  int argc, 
2080: 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 20 2a 2a  sqlite3_value **
2090: 61 72 67 76 0a 29 7b 0a 20 20 69 6e 74 20 72 63  argv.){.  int rc
20a0: 3b 0a 20 20 69 6e 74 20 69 3b 0a 0a 20 20 65 63  ;.  int i;..  ec
20b0: 68 6f 5f 63 75 72 73 6f 72 20 2a 70 43 75 72 20  ho_cursor *pCur 
20c0: 3d 20 28 65 63 68 6f 5f 63 75 72 73 6f 72 20 2a  = (echo_cursor *
20d0: 29 70 56 74 61 62 43 75 72 73 6f 72 3b 0a 20 20  )pVtabCursor;.  
20e0: 65 63 68 6f 5f 76 74 61 62 20 2a 70 56 74 61 62  echo_vtab *pVtab
20f0: 20 3d 20 28 65 63 68 6f 5f 76 74 61 62 20 2a 29   = (echo_vtab *)
2100: 70 56 74 61 62 43 75 72 73 6f 72 2d 3e 70 56 74  pVtabCursor->pVt
2110: 61 62 3b 0a 20 20 73 71 6c 69 74 65 33 20 2a 64  ab;.  sqlite3 *d
2120: 62 20 3d 20 70 56 74 61 62 2d 3e 64 62 3b 0a 0a  b = pVtab->db;..
2130: 20 20 73 71 6c 69 74 65 33 5f 66 69 6e 61 6c 69    sqlite3_finali
2140: 7a 65 28 70 43 75 72 2d 3e 70 53 74 6d 74 29 3b  ze(pCur->pStmt);
2150: 0a 20 20 70 43 75 72 2d 3e 70 53 74 6d 74 20 3d  .  pCur->pStmt =
2160: 20 30 3b 0a 20 20 72 63 20 3d 20 73 71 6c 69 74   0;.  rc = sqlit
2170: 65 33 5f 70 72 65 70 61 72 65 28 64 62 2c 20 69  e3_prepare(db, i
2180: 64 78 53 74 72 2c 20 2d 31 2c 20 26 70 43 75 72  dxStr, -1, &pCur
2190: 2d 3e 70 53 74 6d 74 2c 20 30 29 3b 0a 20 20 66  ->pStmt, 0);.  f
21a0: 6f 72 28 69 3d 30 3b 20 69 3c 61 72 67 63 3b 20  or(i=0; i<argc; 
21b0: 69 2b 2b 29 7b 0a 20 20 20 20 73 77 69 74 63 68  i++){.    switch
21c0: 28 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f  ( sqlite3_value_
21d0: 74 79 70 65 28 61 72 67 76 5b 69 5d 29 20 29 7b  type(argv[i]) ){
21e0: 0a 20 20 20 20 20 20 63 61 73 65 20 53 51 4c 49  .      case SQLI
21f0: 54 45 5f 49 4e 54 45 47 45 52 3a 20 7b 0a 20 20  TE_INTEGER: {.  
2200: 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 62 69        sqlite3_bi
2210: 6e 64 5f 69 6e 74 36 34 28 70 43 75 72 2d 3e 70  nd_int64(pCur->p
2220: 53 74 6d 74 2c 20 69 2b 31 2c 20 73 71 6c 69 74  Stmt, i+1, sqlit
2230: 65 33 5f 76 61 6c 75 65 5f 69 6e 74 36 34 28 61  e3_value_int64(a
2240: 72 67 76 5b 69 5d 29 29 3b 0a 20 20 20 20 20 20  rgv[i]));.      
2250: 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 7d    break;.      }
2260: 0a 20 20 20 20 20 20 63 61 73 65 20 53 51 4c 49  .      case SQLI
2270: 54 45 5f 46 4c 4f 41 54 3a 20 7b 0a 20 20 20 20  TE_FLOAT: {.    
2280: 20 20 20 20 73 71 6c 69 74 65 33 5f 62 69 6e 64      sqlite3_bind
2290: 5f 64 6f 75 62 6c 65 28 70 43 75 72 2d 3e 70 53  _double(pCur->pS
22a0: 74 6d 74 2c 20 69 2b 31 2c 20 73 71 6c 69 74 65  tmt, i+1, sqlite
22b0: 33 5f 76 61 6c 75 65 5f 64 6f 75 62 6c 65 28 61  3_value_double(a
22c0: 72 67 76 5b 69 5d 29 29 3b 0a 20 20 20 20 20 20  rgv[i]));.      
22d0: 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 7d    break;.      }
22e0: 0a 20 20 20 20 20 20 63 61 73 65 20 53 51 4c 49  .      case SQLI
22f0: 54 45 5f 4e 55 4c 4c 3a 20 7b 0a 20 20 20 20 20  TE_NULL: {.     
2300: 20 20 20 73 71 6c 69 74 65 33 5f 62 69 6e 64 5f     sqlite3_bind_
2310: 6e 75 6c 6c 28 70 43 75 72 2d 3e 70 53 74 6d 74  null(pCur->pStmt
2320: 2c 20 69 2b 31 29 3b 0a 20 20 20 20 20 20 20 20  , i+1);.        
2330: 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 7d 0a 20  break;.      }. 
2340: 20 20 20 20 20 63 61 73 65 20 53 51 4c 49 54 45       case SQLITE
2350: 5f 54 45 58 54 3a 20 7b 0a 20 20 20 20 20 20 20  _TEXT: {.       
2360: 20 73 71 6c 69 74 65 33 5f 62 69 6e 64 5f 74 65   sqlite3_bind_te
2370: 78 74 28 70 43 75 72 2d 3e 70 53 74 6d 74 2c 20  xt(pCur->pStmt, 
2380: 69 2b 31 2c 20 73 71 6c 69 74 65 33 5f 76 61 6c  i+1, sqlite3_val
2390: 75 65 5f 74 65 78 74 28 61 72 67 76 5b 69 5d 29  ue_text(argv[i])
23a0: 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,.              
23b0: 20 20 20 20 20 20 20 20 20 20 20 20 73 71 6c 69              sqli
23c0: 74 65 33 5f 76 61 6c 75 65 5f 62 79 74 65 73 28  te3_value_bytes(
23d0: 61 72 67 76 5b 69 5d 29 2c 20 53 51 4c 49 54 45  argv[i]), SQLITE
23e0: 5f 54 52 41 4e 53 49 45 4e 54 29 3b 0a 20 20 20  _TRANSIENT);.   
23f0: 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20       break;.    
2400: 20 20 7d 0a 20 20 20 20 20 20 63 61 73 65 20 53    }.      case S
2410: 51 4c 49 54 45 5f 42 4c 4f 42 3a 20 7b 0a 20 20  QLITE_BLOB: {.  
2420: 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 62 69        sqlite3_bi
2430: 6e 64 5f 62 6c 6f 62 28 70 43 75 72 2d 3e 70 53  nd_blob(pCur->pS
2440: 74 6d 74 2c 20 69 2b 31 2c 20 73 71 6c 69 74 65  tmt, i+1, sqlite
2450: 33 5f 76 61 6c 75 65 5f 62 6c 6f 62 28 61 72 67  3_value_blob(arg
2460: 76 5b 69 5d 29 2c 0a 20 20 20 20 20 20 20 20 20  v[i]),.         
2470: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2480: 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 62   sqlite3_value_b
2490: 79 74 65 73 28 61 72 67 76 5b 69 5d 29 2c 20 53  ytes(argv[i]), S
24a0: 51 4c 49 54 45 5f 54 52 41 4e 53 49 45 4e 54 29  QLITE_TRANSIENT)
24b0: 3b 0a 20 20 20 20 20 20 20 20 62 72 65 61 6b 3b  ;.        break;
24c0: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20  .      }.    }. 
24d0: 20 7d 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c   }.  if( rc==SQL
24e0: 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 72 63  ITE_OK ){.    rc
24f0: 20 3d 20 65 63 68 6f 4e 65 78 74 28 70 56 74 61   = echoNext(pVta
2500: 62 43 75 72 73 6f 72 29 3b 0a 20 20 7d 0a 0a 20  bCursor);.  }.. 
2510: 20 61 70 70 65 6e 64 54 6f 45 63 68 6f 4d 6f 64   appendToEchoMod
2520: 75 6c 65 28 70 56 74 61 62 2d 3e 69 6e 74 65 72  ule(pVtab->inter
2530: 70 2c 20 22 78 46 69 6c 74 65 72 22 29 3b 0a 20  p, "xFilter");. 
2540: 20 61 70 70 65 6e 64 54 6f 45 63 68 6f 4d 6f 64   appendToEchoMod
2550: 75 6c 65 28 70 56 74 61 62 2d 3e 69 6e 74 65 72  ule(pVtab->inter
2560: 70 2c 20 69 64 78 53 74 72 29 3b 0a 20 20 66 6f  p, idxStr);.  fo
2570: 72 28 69 3d 30 3b 20 69 3c 61 72 67 63 3b 20 69  r(i=0; i<argc; i
2580: 2b 2b 29 7b 0a 20 20 20 20 61 70 70 65 6e 64 54  ++){.    appendT
2590: 6f 45 63 68 6f 4d 6f 64 75 6c 65 28 70 56 74 61  oEchoModule(pVta
25a0: 62 2d 3e 69 6e 74 65 72 70 2c 20 73 71 6c 69 74  b->interp, sqlit
25b0: 65 33 5f 76 61 6c 75 65 5f 74 65 78 74 28 61 72  e3_value_text(ar
25c0: 67 76 5b 69 5d 29 29 3b 0a 20 20 7d 0a 0a 20 20  gv[i]));.  }..  
25d0: 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a  return rc;.}../*
25e0: 0a 2a 2a 20 54 68 65 20 65 63 68 6f 20 6d 6f 64  .** The echo mod
25f0: 75 6c 65 20 69 6d 70 6c 65 6d 65 6e 74 73 20 74  ule implements t
2600: 68 65 20 73 75 62 73 65 74 20 6f 66 20 71 75 65  he subset of que
2610: 72 79 20 63 6f 6e 73 74 72 61 69 6e 74 73 20 61  ry constraints a
2620: 6e 64 20 73 6f 72 74 0a 2a 2a 20 6f 72 64 65 72  nd sort.** order
2630: 73 20 74 68 61 74 20 6d 61 79 20 74 61 6b 65 20  s that may take 
2640: 61 64 76 61 6e 74 61 67 65 20 6f 66 20 53 51 4c  advantage of SQL
2650: 69 74 65 20 69 6e 64 69 63 65 73 20 6f 6e 20 74  ite indices on t
2660: 68 65 20 75 6e 64 65 72 6c 79 69 6e 67 0a 2a 2a  he underlying.**
2670: 20 72 65 61 6c 20 74 61 62 6c 65 2e 20 46 6f 72   real table. For
2680: 20 65 78 61 6d 70 6c 65 2c 20 69 66 20 74 68 65   example, if the
2690: 20 72 65 61 6c 20 74 61 62 6c 65 20 69 73 20 64   real table is d
26a0: 65 63 6c 61 72 65 64 20 61 73 3a 0a 2a 2a 0a 2a  eclared as:.**.*
26b0: 2a 20 20 20 20 20 43 52 45 41 54 45 20 54 41 42  *     CREATE TAB
26c0: 4c 45 20 72 65 61 6c 28 61 2c 20 62 2c 20 63 29  LE real(a, b, c)
26d0: 3b 0a 2a 2a 20 20 20 20 20 43 52 45 41 54 45 20  ;.**     CREATE 
26e0: 49 4e 44 45 58 20 72 65 61 6c 5f 69 6e 64 65 78  INDEX real_index
26f0: 20 4f 4e 20 72 65 61 6c 28 62 29 3b 0a 2a 2a 0a   ON real(b);.**.
2700: 2a 2a 20 74 68 65 6e 20 74 68 65 20 65 63 68 6f  ** then the echo
2710: 20 6d 6f 64 75 6c 65 20 68 61 6e 64 6c 65 73 20   module handles 
2720: 57 48 45 52 45 20 6f 72 20 4f 52 44 45 52 20 42  WHERE or ORDER B
2730: 59 20 63 6c 61 75 73 65 73 20 74 68 61 74 20 72  Y clauses that r
2740: 65 66 65 72 0a 2a 2a 20 74 6f 20 74 68 65 20 63  efer.** to the c
2750: 6f 6c 75 6d 6e 20 22 62 22 2c 20 62 75 74 20 6e  olumn "b", but n
2760: 6f 74 20 22 61 22 20 6f 72 20 22 63 22 2e 20 49  ot "a" or "c". I
2770: 66 20 61 20 6d 75 6c 74 69 2d 63 6f 6c 75 6d 6e  f a multi-column
2780: 20 69 6e 64 65 78 20 69 73 0a 2a 2a 20 70 72 65   index is.** pre
2790: 73 65 6e 74 2c 20 6f 6e 6c 79 20 69 74 27 73 20  sent, only it's 
27a0: 6c 65 66 74 20 6d 6f 73 74 20 63 6f 6c 75 6d 6e  left most column
27b0: 20 69 73 20 63 6f 6e 73 69 64 65 72 65 64 2e 20   is considered. 
27c0: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 65  .*/.static int e
27d0: 63 68 6f 42 65 73 74 49 6e 64 65 78 28 73 71 6c  choBestIndex(sql
27e0: 69 74 65 33 5f 76 74 61 62 20 2a 74 61 62 2c 20  ite3_vtab *tab, 
27f0: 73 71 6c 69 74 65 33 5f 69 6e 64 65 78 5f 69 6e  sqlite3_index_in
2800: 66 6f 20 2a 70 49 64 78 49 6e 66 6f 29 7b 0a 20  fo *pIdxInfo){. 
2810: 20 69 6e 74 20 69 69 3b 0a 20 20 63 68 61 72 20   int ii;.  char 
2820: 2a 7a 51 75 65 72 79 20 3d 20 30 3b 0a 20 20 63  *zQuery = 0;.  c
2830: 68 61 72 20 2a 7a 4e 65 77 3b 0a 20 20 69 6e 74  har *zNew;.  int
2840: 20 6e 41 72 67 20 3d 20 30 3b 0a 20 20 63 6f 6e   nArg = 0;.  con
2850: 73 74 20 63 68 61 72 20 2a 7a 53 65 70 20 3d 20  st char *zSep = 
2860: 22 57 48 45 52 45 22 3b 0a 20 20 65 63 68 6f 5f  "WHERE";.  echo_
2870: 76 74 61 62 20 2a 70 56 74 61 62 20 3d 20 28 65  vtab *pVtab = (e
2880: 63 68 6f 5f 76 74 61 62 20 2a 29 74 61 62 3b 0a  cho_vtab *)tab;.
2890: 0a 20 20 7a 51 75 65 72 79 20 3d 20 73 71 6c 69  .  zQuery = sqli
28a0: 74 65 33 5f 6d 70 72 69 6e 74 66 28 22 53 45 4c  te3_mprintf("SEL
28b0: 45 43 54 20 72 6f 77 69 64 2c 20 2a 20 46 52 4f  ECT rowid, * FRO
28c0: 4d 20 25 51 22 2c 20 70 56 74 61 62 2d 3e 7a 54  M %Q", pVtab->zT
28d0: 61 62 6c 65 4e 61 6d 65 29 3b 0a 20 20 66 6f 72  ableName);.  for
28e0: 28 69 69 3d 30 3b 20 69 69 3c 70 49 64 78 49 6e  (ii=0; ii<pIdxIn
28f0: 66 6f 2d 3e 6e 43 6f 6e 73 74 72 61 69 6e 74 3b  fo->nConstraint;
2900: 20 69 69 2b 2b 29 7b 0a 20 20 20 20 63 6f 6e 73   ii++){.    cons
2910: 74 20 73 74 72 75 63 74 20 73 71 6c 69 74 65 33  t struct sqlite3
2920: 5f 69 6e 64 65 78 5f 63 6f 6e 73 74 72 61 69 6e  _index_constrain
2930: 74 20 2a 70 43 6f 6e 73 74 72 61 69 6e 74 3b 0a  t *pConstraint;.
2940: 20 20 20 20 73 74 72 75 63 74 20 73 71 6c 69 74      struct sqlit
2950: 65 33 5f 69 6e 64 65 78 5f 63 6f 6e 73 74 72 61  e3_index_constra
2960: 69 6e 74 5f 75 73 61 67 65 20 2a 70 55 73 61 67  int_usage *pUsag
2970: 65 3b 0a 0a 20 20 20 20 70 43 6f 6e 73 74 72 61  e;..    pConstra
2980: 69 6e 74 20 3d 20 26 70 49 64 78 49 6e 66 6f 2d  int = &pIdxInfo-
2990: 3e 61 43 6f 6e 73 74 72 61 69 6e 74 5b 69 69 5d  >aConstraint[ii]
29a0: 3b 0a 20 20 20 20 70 55 73 61 67 65 20 3d 20 26  ;.    pUsage = &
29b0: 70 49 64 78 49 6e 66 6f 2d 3e 61 43 6f 6e 73 74  pIdxInfo->aConst
29c0: 72 61 69 6e 74 55 73 61 67 65 5b 69 69 5d 3b 0a  raintUsage[ii];.
29d0: 0a 20 20 20 20 69 6e 74 20 69 43 6f 6c 20 3d 20  .    int iCol = 
29e0: 70 43 6f 6e 73 74 72 61 69 6e 74 2d 3e 69 43 6f  pConstraint->iCo
29f0: 6c 75 6d 6e 3b 0a 20 20 20 20 69 66 28 20 70 56  lumn;.    if( pV
2a00: 74 61 62 2d 3e 61 49 6e 64 65 78 5b 69 43 6f 6c  tab->aIndex[iCol
2a10: 5d 20 29 7b 0a 20 20 20 20 20 20 63 68 61 72 20  ] ){.      char 
2a20: 2a 7a 43 6f 6c 20 3d 20 70 56 74 61 62 2d 3e 61  *zCol = pVtab->a
2a30: 43 6f 6c 5b 69 43 6f 6c 5d 3b 0a 20 20 20 20 20  Col[iCol];.     
2a40: 20 63 68 61 72 20 2a 7a 4f 70 20 3d 20 30 3b 0a   char *zOp = 0;.
2a50: 20 20 20 20 20 20 73 77 69 74 63 68 28 20 70 43        switch( pC
2a60: 6f 6e 73 74 72 61 69 6e 74 2d 3e 6f 70 20 29 7b  onstraint->op ){
2a70: 0a 20 20 20 20 20 20 20 20 63 61 73 65 20 53 51  .        case SQ
2a80: 4c 49 54 45 5f 49 4e 44 45 58 5f 43 4f 4e 53 54  LITE_INDEX_CONST
2a90: 52 41 49 4e 54 5f 45 51 3a 0a 20 20 20 20 20 20  RAINT_EQ:.      
2aa0: 20 20 20 20 7a 4f 70 20 3d 20 22 3d 22 3b 20 62      zOp = "="; b
2ab0: 72 65 61 6b 3b 0a 20 20 20 20 20 20 20 20 63 61  reak;.        ca
2ac0: 73 65 20 53 51 4c 49 54 45 5f 49 4e 44 45 58 5f  se SQLITE_INDEX_
2ad0: 43 4f 4e 53 54 52 41 49 4e 54 5f 4c 54 3a 0a 20  CONSTRAINT_LT:. 
2ae0: 20 20 20 20 20 20 20 20 20 7a 4f 70 20 3d 20 22           zOp = "
2af0: 3c 22 3b 20 62 72 65 61 6b 3b 0a 20 20 20 20 20  <"; break;.     
2b00: 20 20 20 63 61 73 65 20 53 51 4c 49 54 45 5f 49     case SQLITE_I
2b10: 4e 44 45 58 5f 43 4f 4e 53 54 52 41 49 4e 54 5f  NDEX_CONSTRAINT_
2b20: 47 54 3a 0a 20 20 20 20 20 20 20 20 20 20 7a 4f  GT:.          zO
2b30: 70 20 3d 20 22 3e 22 3b 20 62 72 65 61 6b 3b 0a  p = ">"; break;.
2b40: 20 20 20 20 20 20 20 20 63 61 73 65 20 53 51 4c          case SQL
2b50: 49 54 45 5f 49 4e 44 45 58 5f 43 4f 4e 53 54 52  ITE_INDEX_CONSTR
2b60: 41 49 4e 54 5f 4c 45 3a 0a 20 20 20 20 20 20 20  AINT_LE:.       
2b70: 20 20 20 7a 4f 70 20 3d 20 22 3c 3d 22 3b 20 62     zOp = "<="; b
2b80: 72 65 61 6b 3b 0a 20 20 20 20 20 20 20 20 63 61  reak;.        ca
2b90: 73 65 20 53 51 4c 49 54 45 5f 49 4e 44 45 58 5f  se SQLITE_INDEX_
2ba0: 43 4f 4e 53 54 52 41 49 4e 54 5f 47 45 3a 0a 20  CONSTRAINT_GE:. 
2bb0: 20 20 20 20 20 20 20 20 20 7a 4f 70 20 3d 20 22           zOp = "
2bc0: 3e 3d 22 3b 20 62 72 65 61 6b 3b 0a 20 20 20 20  >="; break;.    
2bd0: 20 20 20 20 63 61 73 65 20 53 51 4c 49 54 45 5f      case SQLITE_
2be0: 49 4e 44 45 58 5f 43 4f 4e 53 54 52 41 49 4e 54  INDEX_CONSTRAINT
2bf0: 5f 4d 41 54 43 48 3a 0a 20 20 20 20 20 20 20 20  _MATCH:.        
2c00: 20 20 7a 4f 70 20 3d 20 22 4d 41 54 43 48 22 3b    zOp = "MATCH";
2c10: 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 7d 0a   break;.      }.
2c20: 20 20 20 20 20 20 7a 4e 65 77 20 3d 20 73 71 6c        zNew = sql
2c30: 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 22 25 73  ite3_mprintf("%s
2c40: 20 25 73 20 25 73 20 25 73 20 3f 22 2c 20 7a 51   %s %s %s ?", zQ
2c50: 75 65 72 79 2c 20 7a 53 65 70 2c 20 7a 43 6f 6c  uery, zSep, zCol
2c60: 2c 20 7a 4f 70 29 3b 0a 20 20 20 20 20 20 73 71  , zOp);.      sq
2c70: 6c 69 74 65 33 5f 66 72 65 65 28 7a 51 75 65 72  lite3_free(zQuer
2c80: 79 29 3b 0a 20 20 20 20 20 20 7a 51 75 65 72 79  y);.      zQuery
2c90: 20 3d 20 7a 4e 65 77 3b 0a 20 20 20 20 20 20 7a   = zNew;.      z
2ca0: 53 65 70 20 3d 20 22 41 4e 44 22 3b 0a 20 20 20  Sep = "AND";.   
2cb0: 20 20 20 70 55 73 61 67 65 2d 3e 61 72 67 76 49     pUsage->argvI
2cc0: 6e 64 65 78 20 3d 20 2b 2b 6e 41 72 67 3b 0a 20  ndex = ++nArg;. 
2cd0: 20 20 20 20 20 70 55 73 61 67 65 2d 3e 6f 6d 69       pUsage->omi
2ce0: 74 20 3d 20 31 3b 0a 20 20 20 20 7d 0a 20 20 7d  t = 1;.    }.  }
2cf0: 0a 20 20 61 70 70 65 6e 64 54 6f 45 63 68 6f 4d  .  appendToEchoM
2d00: 6f 64 75 6c 65 28 70 56 74 61 62 2d 3e 69 6e 74  odule(pVtab->int
2d10: 65 72 70 2c 20 22 78 42 65 73 74 49 6e 64 65 78  erp, "xBestIndex
2d20: 22 29 3b 3b 0a 20 20 61 70 70 65 6e 64 54 6f 45  ");;.  appendToE
2d30: 63 68 6f 4d 6f 64 75 6c 65 28 70 56 74 61 62 2d  choModule(pVtab-
2d40: 3e 69 6e 74 65 72 70 2c 20 7a 51 75 65 72 79 29  >interp, zQuery)
2d50: 3b 0a 0a 20 20 70 49 64 78 49 6e 66 6f 2d 3e 69  ;..  pIdxInfo->i
2d60: 64 78 53 74 72 20 3d 20 7a 51 75 65 72 79 3b 0a  dxStr = zQuery;.
2d70: 20 20 70 49 64 78 49 6e 66 6f 2d 3e 6e 65 65 64    pIdxInfo->need
2d80: 54 6f 46 72 65 65 49 64 78 53 74 72 20 3d 20 31  ToFreeIdxStr = 1
2d90: 3b 0a 20 20 70 49 64 78 49 6e 66 6f 2d 3e 65 73  ;.  pIdxInfo->es
2da0: 74 69 6d 61 74 65 64 43 6f 73 74 20 3d 20 31 2e  timatedCost = 1.
2db0: 30 3b 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49  0;.  return SQLI
2dc0: 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  TE_OK;.}../*.** 
2dd0: 41 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65 20  A virtual table 
2de0: 6d 6f 64 75 6c 65 20 74 68 61 74 20 6d 65 72 65  module that mere
2df0: 6c 79 20 65 63 68 6f 73 20 6d 65 74 68 6f 64 20  ly echos method 
2e00: 63 61 6c 6c 73 20 69 6e 74 6f 20 54 43 4c 0a 2a  calls into TCL.*
2e10: 2a 20 76 61 72 69 61 62 6c 65 73 2e 0a 2a 2f 0a  * variables..*/.
2e20: 73 74 61 74 69 63 20 73 71 6c 69 74 65 33 5f 6d  static sqlite3_m
2e30: 6f 64 75 6c 65 20 65 63 68 6f 4d 6f 64 75 6c 65  odule echoModule
2e40: 20 3d 20 7b 0a 20 20 30 2c 20 20 20 20 20 20 20   = {.  0,       
2e50: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2e60: 20 20 2f 2a 20 69 56 65 72 73 69 6f 6e 20 2a 2f    /* iVersion */
2e70: 0a 20 20 22 65 63 68 6f 22 2c 20 20 20 20 20 20  .  "echo",      
2e80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
2e90: 20 7a 4e 61 6d 65 20 2a 2f 0a 20 20 30 2c 20 20   zName */.  0,  
2ea0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2eb0: 20 20 20 20 20 20 20 2f 2a 20 70 41 75 78 20 2a         /* pAux *
2ec0: 2f 0a 20 20 65 63 68 6f 43 72 65 61 74 65 2c 0a  /.  echoCreate,.
2ed0: 20 20 65 63 68 6f 43 6f 6e 6e 65 63 74 2c 0a 20    echoConnect,. 
2ee0: 20 65 63 68 6f 42 65 73 74 49 6e 64 65 78 2c 0a   echoBestIndex,.
2ef0: 20 20 65 63 68 6f 44 69 73 63 6f 6e 6e 65 63 74    echoDisconnect
2f00: 2c 20 0a 20 20 65 63 68 6f 44 65 73 74 72 6f 79  , .  echoDestroy
2f10: 2c 0a 20 20 65 63 68 6f 4f 70 65 6e 2c 20 20 20  ,.  echoOpen,   
2f20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
2f30: 2a 20 78 4f 70 65 6e 20 2d 20 6f 70 65 6e 20 61  * xOpen - open a
2f40: 20 63 75 72 73 6f 72 20 2a 2f 0a 20 20 65 63 68   cursor */.  ech
2f50: 6f 43 6c 6f 73 65 2c 20 20 20 20 20 20 20 20 20  oClose,         
2f60: 20 20 20 20 20 20 20 20 2f 2a 20 78 43 6c 6f 73          /* xClos
2f70: 65 20 2d 20 63 6c 6f 73 65 20 61 20 63 75 72 73  e - close a curs
2f80: 6f 72 20 2a 2f 0a 20 20 65 63 68 6f 46 69 6c 74  or */.  echoFilt
2f90: 65 72 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  er,             
2fa0: 20 20 20 2f 2a 20 78 46 69 6c 74 65 72 20 2d 20     /* xFilter - 
2fb0: 63 6f 6e 66 69 67 75 72 65 20 73 63 61 6e 20 63  configure scan c
2fc0: 6f 6e 73 74 72 61 69 6e 74 73 20 2a 2f 0a 20 20  onstraints */.  
2fd0: 65 63 68 6f 4e 65 78 74 2c 20 20 20 20 20 20 20  echoNext,       
2fe0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 4e             /* xN
2ff0: 65 78 74 20 2d 20 61 64 76 61 6e 63 65 20 61 20  ext - advance a 
3000: 63 75 72 73 6f 72 20 2a 2f 0a 20 20 65 63 68 6f  cursor */.  echo
3010: 43 6f 6c 75 6d 6e 2c 20 20 20 20 20 20 20 20 20  Column,         
3020: 20 20 20 20 20 20 20 2f 2a 20 78 43 6f 6c 75 6d         /* xColum
3030: 6e 20 2d 20 72 65 61 64 20 64 61 74 61 20 2a 2f  n - read data */
3040: 0a 20 20 65 63 68 6f 52 6f 77 69 64 20 20 20 20  .  echoRowid    
3050: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
3060: 20 78 52 6f 77 69 64 20 2d 20 72 65 61 64 20 64   xRowid - read d
3070: 61 74 61 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a  ata */.};../*.**
3080: 20 44 65 63 6f 64 65 20 61 20 70 6f 69 6e 74 65   Decode a pointe
3090: 72 20 74 6f 20 61 6e 20 73 71 6c 69 74 65 33 20  r to an sqlite3 
30a0: 6f 62 6a 65 63 74 2e 0a 2a 2f 0a 73 74 61 74 69  object..*/.stati
30b0: 63 20 69 6e 74 20 67 65 74 44 62 50 6f 69 6e 74  c int getDbPoint
30c0: 65 72 28 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69  er(Tcl_Interp *i
30d0: 6e 74 65 72 70 2c 20 63 6f 6e 73 74 20 63 68 61  nterp, const cha
30e0: 72 20 2a 7a 41 2c 20 73 71 6c 69 74 65 33 20 2a  r *zA, sqlite3 *
30f0: 2a 70 70 44 62 29 7b 0a 20 20 2a 70 70 44 62 20  *ppDb){.  *ppDb 
3100: 3d 20 28 73 71 6c 69 74 65 33 2a 29 73 71 6c 69  = (sqlite3*)sqli
3110: 74 65 33 54 65 78 74 54 6f 50 74 72 28 7a 41 29  te3TextToPtr(zA)
3120: 3b 0a 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 4f  ;.  return TCL_O
3130: 4b 3b 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 52 65 67  K;.}.../*.** Reg
3140: 69 73 74 65 72 20 74 68 65 20 65 63 68 6f 20 76  ister the echo v
3150: 69 72 74 75 61 6c 20 74 61 62 6c 65 20 6d 6f 64  irtual table mod
3160: 75 6c 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  ule..*/.static i
3170: 6e 74 20 72 65 67 69 73 74 65 72 5f 65 63 68 6f  nt register_echo
3180: 5f 6d 6f 64 75 6c 65 28 0a 20 20 43 6c 69 65 6e  _module(.  Clien
3190: 74 44 61 74 61 20 63 6c 69 65 6e 74 44 61 74 61  tData clientData
31a0: 2c 20 2f 2a 20 50 6f 69 6e 74 65 72 20 74 6f 20  , /* Pointer to 
31b0: 73 71 6c 69 74 65 33 5f 65 6e 61 62 6c 65 5f 58  sqlite3_enable_X
31c0: 58 58 20 66 75 6e 63 74 69 6f 6e 20 2a 2f 0a 20  XX function */. 
31d0: 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74   Tcl_Interp *int
31e0: 65 72 70 2c 20 20 20 20 2f 2a 20 54 68 65 20 54  erp,    /* The T
31f0: 43 4c 20 69 6e 74 65 72 70 72 65 74 65 72 20 74  CL interpreter t
3200: 68 61 74 20 69 6e 76 6f 6b 65 64 20 74 68 69 73  hat invoked this
3210: 20 63 6f 6d 6d 61 6e 64 20 2a 2f 0a 20 20 69 6e   command */.  in
3220: 74 20 6f 62 6a 63 2c 20 20 20 20 20 20 20 20 20  t objc,         
3230: 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f       /* Number o
3240: 66 20 61 72 67 75 6d 65 6e 74 73 20 2a 2f 0a 20  f arguments */. 
3250: 20 54 63 6c 5f 4f 62 6a 20 2a 43 4f 4e 53 54 20   Tcl_Obj *CONST 
3260: 6f 62 6a 76 5b 5d 20 20 2f 2a 20 43 6f 6d 6d 61  objv[]  /* Comma
3270: 6e 64 20 61 72 67 75 6d 65 6e 74 73 20 2a 2f 0a  nd arguments */.
3280: 29 7b 0a 20 20 73 71 6c 69 74 65 33 20 2a 64 62  ){.  sqlite3 *db
3290: 3b 0a 20 20 69 66 28 20 6f 62 6a 63 21 3d 32 20  ;.  if( objc!=2 
32a0: 29 7b 0a 20 20 20 20 54 63 6c 5f 57 72 6f 6e 67  ){.    Tcl_Wrong
32b0: 4e 75 6d 41 72 67 73 28 69 6e 74 65 72 70 2c 20  NumArgs(interp, 
32c0: 31 2c 20 6f 62 6a 76 2c 20 22 44 42 22 29 3b 0a  1, objv, "DB");.
32d0: 20 20 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 45      return TCL_E
32e0: 52 52 4f 52 3b 0a 20 20 7d 0a 20 20 69 66 28 20  RROR;.  }.  if( 
32f0: 67 65 74 44 62 50 6f 69 6e 74 65 72 28 69 6e 74  getDbPointer(int
3300: 65 72 70 2c 20 54 63 6c 5f 47 65 74 53 74 72 69  erp, Tcl_GetStri
3310: 6e 67 28 6f 62 6a 76 5b 31 5d 29 2c 20 26 64 62  ng(objv[1]), &db
3320: 29 20 29 20 72 65 74 75 72 6e 20 54 43 4c 5f 45  ) ) return TCL_E
3330: 52 52 4f 52 3b 0a 20 20 65 63 68 6f 4d 6f 64 75  RROR;.  echoModu
3340: 6c 65 2e 70 41 75 78 20 3d 20 69 6e 74 65 72 70  le.pAux = interp
3350: 3b 0a 23 69 66 6e 64 65 66 20 53 51 4c 49 54 45  ;.#ifndef SQLITE
3360: 5f 4f 4d 49 54 5f 56 49 52 54 55 41 4c 54 41 42  _OMIT_VIRTUALTAB
3370: 4c 45 0a 20 20 73 71 6c 69 74 65 33 5f 63 72 65  LE.  sqlite3_cre
3380: 61 74 65 5f 6d 6f 64 75 6c 65 28 64 62 2c 20 22  ate_module(db, "
3390: 65 63 68 6f 22 2c 20 26 65 63 68 6f 4d 6f 64 75  echo", &echoModu
33a0: 6c 65 29 3b 0a 23 65 6e 64 69 66 0a 20 20 72 65  le);.#endif.  re
33b0: 74 75 72 6e 20 54 43 4c 5f 4f 4b 3b 0a 7d 0a 0a  turn TCL_OK;.}..
33c0: 0a 2f 2a 0a 2a 2a 20 52 65 67 69 73 74 65 72 20  ./*.** Register 
33d0: 63 6f 6d 6d 61 6e 64 73 20 77 69 74 68 20 74 68  commands with th
33e0: 65 20 54 43 4c 20 69 6e 74 65 72 70 72 65 74 65  e TCL interprete
33f0: 72 2e 0a 2a 2f 0a 69 6e 74 20 53 71 6c 69 74 65  r..*/.int Sqlite
3400: 74 65 73 74 38 5f 49 6e 69 74 28 54 63 6c 5f 49  test8_Init(Tcl_I
3410: 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 29 7b 0a  nterp *interp){.
3420: 20 20 73 74 61 74 69 63 20 73 74 72 75 63 74 20    static struct 
3430: 7b 0a 20 20 20 20 20 63 68 61 72 20 2a 7a 4e 61  {.     char *zNa
3440: 6d 65 3b 0a 20 20 20 20 20 54 63 6c 5f 4f 62 6a  me;.     Tcl_Obj
3450: 43 6d 64 50 72 6f 63 20 2a 78 50 72 6f 63 3b 0a  CmdProc *xProc;.
3460: 20 20 20 20 20 76 6f 69 64 20 2a 63 6c 69 65 6e       void *clien
3470: 74 44 61 74 61 3b 0a 20 20 7d 20 61 4f 62 6a 43  tData;.  } aObjC
3480: 6d 64 5b 5d 20 3d 20 7b 0a 20 20 20 20 20 7b 20  md[] = {.     { 
3490: 22 72 65 67 69 73 74 65 72 5f 65 63 68 6f 5f 6d  "register_echo_m
34a0: 6f 64 75 6c 65 22 2c 20 20 20 72 65 67 69 73 74  odule",   regist
34b0: 65 72 5f 65 63 68 6f 5f 6d 6f 64 75 6c 65 2c 20  er_echo_module, 
34c0: 30 20 7d 2c 0a 20 20 7d 3b 0a 20 20 69 6e 74 20  0 },.  };.  int 
34d0: 69 3b 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c  i;.  for(i=0; i<
34e0: 73 69 7a 65 6f 66 28 61 4f 62 6a 43 6d 64 29 2f  sizeof(aObjCmd)/
34f0: 73 69 7a 65 6f 66 28 61 4f 62 6a 43 6d 64 5b 30  sizeof(aObjCmd[0
3500: 5d 29 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 54 63  ]); i++){.    Tc
3510: 6c 5f 43 72 65 61 74 65 4f 62 6a 43 6f 6d 6d 61  l_CreateObjComma
3520: 6e 64 28 69 6e 74 65 72 70 2c 20 61 4f 62 6a 43  nd(interp, aObjC
3530: 6d 64 5b 69 5d 2e 7a 4e 61 6d 65 2c 20 0a 20 20  md[i].zName, .  
3540: 20 20 20 20 20 20 61 4f 62 6a 43 6d 64 5b 69 5d        aObjCmd[i]
3550: 2e 78 50 72 6f 63 2c 20 61 4f 62 6a 43 6d 64 5b  .xProc, aObjCmd[
3560: 69 5d 2e 63 6c 69 65 6e 74 44 61 74 61 2c 20 30  i].clientData, 0
3570: 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20  );.  }.  return 
3580: 54 43 4c 5f 4f 4b 3b 0a 7d 0a                    TCL_OK;.}.