/ Hex Artifact Content
Login

Artifact beca53180c42ee388c0c882a529739d3d1001f99:


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 36 33 20 32  test8.c,v 1.63 2
0230: 30 30 38 2f 30 35 2f 30 35 20 31 33 3a 32 33 3a  008/05/05 13:23:
0240: 30 34 20 64 72 68 20 45 78 70 20 24 0a 2a 2f 0a  04 drh Exp $.*/.
0250: 23 69 6e 63 6c 75 64 65 20 22 73 71 6c 69 74 65  #include "sqlite
0260: 49 6e 74 2e 68 22 0a 23 69 6e 63 6c 75 64 65 20  Int.h".#include 
0270: 22 74 63 6c 2e 68 22 0a 23 69 6e 63 6c 75 64 65  "tcl.h".#include
0280: 20 3c 73 74 64 6c 69 62 2e 68 3e 0a 23 69 6e 63   <stdlib.h>.#inc
0290: 6c 75 64 65 20 3c 73 74 72 69 6e 67 2e 68 3e 0a  lude <string.h>.
02a0: 0a 23 69 66 6e 64 65 66 20 53 51 4c 49 54 45 5f  .#ifndef SQLITE_
02b0: 4f 4d 49 54 5f 56 49 52 54 55 41 4c 54 41 42 4c  OMIT_VIRTUALTABL
02c0: 45 0a 0a 74 79 70 65 64 65 66 20 73 74 72 75 63  E..typedef struc
02d0: 74 20 65 63 68 6f 5f 76 74 61 62 20 65 63 68 6f  t echo_vtab echo
02e0: 5f 76 74 61 62 3b 0a 74 79 70 65 64 65 66 20 73  _vtab;.typedef s
02f0: 74 72 75 63 74 20 65 63 68 6f 5f 63 75 72 73 6f  truct echo_curso
0300: 72 20 65 63 68 6f 5f 63 75 72 73 6f 72 3b 0a 0a  r echo_cursor;..
0310: 2f 2a 0a 2a 2a 20 54 68 65 20 74 65 73 74 20 6d  /*.** The test m
0320: 6f 64 75 6c 65 20 64 65 66 69 6e 65 64 20 69 6e  odule defined in
0330: 20 74 68 69 73 20 66 69 6c 65 20 75 73 65 73 20   this file uses 
0340: 66 6f 75 72 20 67 6c 6f 62 61 6c 20 54 63 6c 20  four global Tcl 
0350: 76 61 72 69 61 62 6c 65 73 20 74 6f 0a 2a 2a 20  variables to.** 
0360: 63 6f 6d 6d 69 63 61 74 65 20 77 69 74 68 20 74  commicate with t
0370: 65 73 74 2d 73 63 72 69 70 74 73 3a 0a 2a 2a 0a  est-scripts:.**.
0380: 2a 2a 20 20 20 20 20 24 3a 3a 65 63 68 6f 5f 6d  **     $::echo_m
0390: 6f 64 75 6c 65 0a 2a 2a 20 20 20 20 20 24 3a 3a  odule.**     $::
03a0: 65 63 68 6f 5f 6d 6f 64 75 6c 65 5f 73 79 6e 63  echo_module_sync
03b0: 5f 66 61 69 6c 0a 2a 2a 20 20 20 20 20 24 3a 3a  _fail.**     $::
03c0: 65 63 68 6f 5f 6d 6f 64 75 6c 65 5f 62 65 67 69  echo_module_begi
03d0: 6e 5f 66 61 69 6c 0a 2a 2a 20 20 20 20 20 24 3a  n_fail.**     $:
03e0: 3a 65 63 68 6f 5f 6d 6f 64 75 6c 65 5f 63 6f 73  :echo_module_cos
03f0: 74 0a 2a 2a 0a 2a 2a 20 54 68 65 20 76 61 72 69  t.**.** The vari
0400: 61 62 6c 65 20 3a 3a 65 63 68 6f 5f 6d 6f 64 75  able ::echo_modu
0410: 6c 65 20 69 73 20 61 20 6c 69 73 74 2e 20 45 61  le is a list. Ea
0420: 63 68 20 74 69 6d 65 20 6f 6e 65 20 6f 66 20 74  ch time one of t
0430: 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 0a 2a 2a 20  he following.** 
0440: 6d 65 74 68 6f 64 73 20 69 73 20 63 61 6c 6c 65  methods is calle
0450: 64 2c 20 6f 6e 65 20 6f 72 20 6d 6f 72 65 20 65  d, one or more e
0460: 6c 65 6d 65 6e 74 73 20 61 72 65 20 61 70 70 65  lements are appe
0470: 6e 64 65 64 20 74 6f 20 74 68 65 20 6c 69 73 74  nded to the list
0480: 2e 0a 2a 2a 20 54 68 69 73 20 69 73 20 75 73 65  ..** This is use
0490: 64 20 66 6f 72 20 61 75 74 6f 6d 61 74 65 64 20  d for automated 
04a0: 74 65 73 74 69 6e 67 20 6f 66 20 76 69 72 74 75  testing of virtu
04b0: 61 6c 20 74 61 62 6c 65 20 6d 6f 64 75 6c 65 73  al table modules
04c0: 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 3a 3a 65 63  ..**.** The ::ec
04d0: 68 6f 5f 6d 6f 64 75 6c 65 5f 73 79 6e 63 5f 66  ho_module_sync_f
04e0: 61 69 6c 20 76 61 72 69 61 62 6c 65 20 69 73 20  ail variable is 
04f0: 73 65 74 20 62 79 20 74 65 73 74 20 73 63 72 69  set by test scri
0500: 70 74 73 20 61 6e 64 20 72 65 61 64 0a 2a 2a 20  pts and read.** 
0510: 62 79 20 63 6f 64 65 20 69 6e 20 74 68 69 73 20  by code in this 
0520: 66 69 6c 65 2e 20 49 66 20 69 74 20 69 73 20 73  file. If it is s
0530: 65 74 20 74 6f 20 74 68 65 20 6e 61 6d 65 20 6f  et to the name o
0540: 66 20 61 20 72 65 61 6c 20 74 61 62 6c 65 20 69  f a real table i
0550: 6e 20 74 68 65 0a 2a 2a 20 74 68 65 20 64 61 74  n the.** the dat
0560: 61 62 61 73 65 2c 20 74 68 65 6e 20 61 6c 6c 20  abase, then all 
0570: 78 53 79 6e 63 20 6f 70 65 72 61 74 69 6f 6e 73  xSync operations
0580: 20 6f 6e 20 65 63 68 6f 20 76 69 72 74 75 61 6c   on echo virtual
0590: 20 74 61 62 6c 65 73 20 74 68 61 74 0a 2a 2a 20   tables that.** 
05a0: 75 73 65 20 74 68 65 20 6e 61 6d 65 64 20 74 61  use the named ta
05b0: 62 6c 65 20 61 73 20 61 20 62 61 63 6b 69 6e 67  ble as a backing
05c0: 20 73 74 6f 72 65 20 77 69 6c 6c 20 66 61 69 6c   store will fail
05d0: 2e 0a 2a 2f 0a 0a 2f 2a 20 0a 2a 2a 20 41 6e 20  ..*/../* .** An 
05e0: 65 63 68 6f 20 76 69 72 74 75 61 6c 2d 74 61 62  echo virtual-tab
05f0: 6c 65 20 6f 62 6a 65 63 74 2e 0a 2a 2a 0a 2a 2a  le object..**.**
0600: 20 65 63 68 6f 2e 76 74 61 62 2e 61 49 6e 64 65   echo.vtab.aInde
0610: 78 20 69 73 20 61 6e 20 61 72 72 61 79 20 6f 66  x is an array of
0620: 20 62 6f 6f 6c 65 61 6e 73 2e 20 54 68 65 20 6e   booleans. The n
0630: 74 68 20 65 6e 74 72 79 20 69 73 20 74 72 75 65  th entry is true
0640: 20 69 66 20 0a 2a 2a 20 74 68 65 20 6e 74 68 20   if .** the nth 
0650: 63 6f 6c 75 6d 6e 20 6f 66 20 74 68 65 20 72 65  column of the re
0660: 61 6c 20 74 61 62 6c 65 20 69 73 20 74 68 65 20  al table is the 
0670: 6c 65 66 74 2d 6d 6f 73 74 20 63 6f 6c 75 6d 6e  left-most column
0680: 20 6f 66 20 61 6e 20 69 6e 64 65 78 0a 2a 2a 20   of an index.** 
0690: 28 69 6d 70 6c 69 63 69 74 20 6f 72 20 6f 74 68  (implicit or oth
06a0: 65 72 77 69 73 65 29 2e 20 49 6e 20 6f 74 68 65  erwise). In othe
06b0: 72 20 77 6f 72 64 73 2c 20 69 66 20 53 51 4c 69  r words, if SQLi
06c0: 74 65 20 63 61 6e 20 6f 70 74 69 6d 69 7a 65 0a  te can optimize.
06d0: 2a 2a 20 61 20 71 75 65 72 79 20 6c 69 6b 65 20  ** a query like 
06e0: 22 53 45 4c 45 43 54 20 2a 20 46 52 4f 4d 20 72  "SELECT * FROM r
06f0: 65 61 6c 5f 74 61 62 6c 65 20 57 48 45 52 45 20  eal_table WHERE 
0700: 63 6f 6c 20 3d 20 3f 22 2e 0a 2a 2a 0a 2a 2a 20  col = ?"..**.** 
0710: 4d 65 6d 62 65 72 20 76 61 72 69 61 62 6c 65 20  Member variable 
0720: 61 43 6f 6c 5b 5d 20 63 6f 6e 74 61 69 6e 73 20  aCol[] contains 
0730: 63 6f 70 69 65 73 20 6f 66 20 74 68 65 20 63 6f  copies of the co
0740: 6c 75 6d 6e 20 6e 61 6d 65 73 20 6f 66 20 74 68  lumn names of th
0750: 65 20 72 65 61 6c 0a 2a 2a 20 74 61 62 6c 65 2e  e real.** table.
0760: 0a 2a 2f 0a 73 74 72 75 63 74 20 65 63 68 6f 5f  .*/.struct echo_
0770: 76 74 61 62 20 7b 0a 20 20 73 71 6c 69 74 65 33  vtab {.  sqlite3
0780: 5f 76 74 61 62 20 62 61 73 65 3b 0a 20 20 54 63  _vtab base;.  Tc
0790: 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70  l_Interp *interp
07a0: 3b 20 20 20 20 20 2f 2a 20 54 63 6c 20 69 6e 74  ;     /* Tcl int
07b0: 65 72 70 72 65 74 65 72 20 63 6f 6e 74 61 69 6e  erpreter contain
07c0: 69 6e 67 20 64 65 62 75 67 20 76 61 72 69 61 62  ing debug variab
07d0: 6c 65 73 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33  les */.  sqlite3
07e0: 20 2a 64 62 3b 20 20 20 20 20 20 20 20 20 20 20   *db;           
07f0: 20 2f 2a 20 44 61 74 61 62 61 73 65 20 63 6f 6e   /* Database con
0800: 6e 65 63 74 69 6f 6e 20 2a 2f 0a 0a 20 20 69 6e  nection */..  in
0810: 74 20 69 73 50 61 74 74 65 72 6e 3b 0a 20 20 69  t isPattern;.  i
0820: 6e 74 20 69 6e 54 72 61 6e 73 61 63 74 69 6f 6e  nt inTransaction
0830: 3b 20 20 20 20 20 20 2f 2a 20 54 72 75 65 20 69  ;      /* True i
0840: 66 20 77 69 74 68 69 6e 20 61 20 74 72 61 6e 73  f within a trans
0850: 61 63 74 69 6f 6e 20 2a 2f 0a 20 20 63 68 61 72  action */.  char
0860: 20 2a 7a 54 68 69 73 3b 20 20 20 20 20 20 20 20   *zThis;        
0870: 20 20 20 20 2f 2a 20 4e 61 6d 65 20 6f 66 20 74      /* Name of t
0880: 68 65 20 65 63 68 6f 20 74 61 62 6c 65 20 2a 2f  he echo table */
0890: 0a 20 20 63 68 61 72 20 2a 7a 54 61 62 6c 65 4e  .  char *zTableN
08a0: 61 6d 65 3b 20 20 20 20 20 20 20 2f 2a 20 4e 61  ame;       /* Na
08b0: 6d 65 20 6f 66 20 74 68 65 20 72 65 61 6c 20 74  me of the real t
08c0: 61 62 6c 65 20 2a 2f 0a 20 20 63 68 61 72 20 2a  able */.  char *
08d0: 7a 4c 6f 67 4e 61 6d 65 3b 20 20 20 20 20 20 20  zLogName;       
08e0: 20 20 2f 2a 20 4e 61 6d 65 20 6f 66 20 74 68 65    /* Name of the
08f0: 20 6c 6f 67 20 74 61 62 6c 65 20 2a 2f 0a 20 20   log table */.  
0900: 69 6e 74 20 6e 43 6f 6c 3b 20 20 20 20 20 20 20  int nCol;       
0910: 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65          /* Numbe
0920: 72 20 6f 66 20 63 6f 6c 75 6d 6e 73 20 69 6e 20  r of columns in 
0930: 74 68 65 20 72 65 61 6c 20 74 61 62 6c 65 20 2a  the real table *
0940: 2f 0a 20 20 69 6e 74 20 2a 61 49 6e 64 65 78 3b  /.  int *aIndex;
0950: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 41              /* A
0960: 72 72 61 79 20 6f 66 20 73 69 7a 65 20 6e 43 6f  rray of size nCo
0970: 6c 2e 20 54 72 75 65 20 69 66 20 63 6f 6c 75 6d  l. True if colum
0980: 6e 20 68 61 73 20 61 6e 20 69 6e 64 65 78 20 2a  n has an index *
0990: 2f 0a 20 20 63 68 61 72 20 2a 2a 61 43 6f 6c 3b  /.  char **aCol;
09a0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 41              /* A
09b0: 72 72 61 79 20 6f 66 20 73 69 7a 65 20 6e 43 6f  rray of size nCo
09c0: 6c 2e 20 43 6f 6c 75 6d 6e 20 6e 61 6d 65 73 20  l. Column names 
09d0: 2a 2f 0a 7d 3b 0a 0a 2f 2a 20 41 6e 20 65 63 68  */.};../* An ech
09e0: 6f 20 63 75 72 73 6f 72 20 6f 62 6a 65 63 74 20  o cursor object 
09f0: 2a 2f 0a 73 74 72 75 63 74 20 65 63 68 6f 5f 63  */.struct echo_c
0a00: 75 72 73 6f 72 20 7b 0a 20 20 73 71 6c 69 74 65  ursor {.  sqlite
0a10: 33 5f 76 74 61 62 5f 63 75 72 73 6f 72 20 62 61  3_vtab_cursor ba
0a20: 73 65 3b 0a 20 20 73 71 6c 69 74 65 33 5f 73 74  se;.  sqlite3_st
0a30: 6d 74 20 2a 70 53 74 6d 74 3b 0a 7d 3b 0a 0a 2f  mt *pStmt;.};../
0a40: 2a 0a 2a 2a 20 43 6f 6e 76 65 72 74 20 61 6e 20  *.** Convert an 
0a50: 53 51 4c 2d 73 74 79 6c 65 20 71 75 6f 74 65 64  SQL-style quoted
0a60: 20 73 74 72 69 6e 67 20 69 6e 74 6f 20 61 20 6e   string into a n
0a70: 6f 72 6d 61 6c 20 73 74 72 69 6e 67 20 62 79 20  ormal string by 
0a80: 72 65 6d 6f 76 69 6e 67 0a 2a 2a 20 74 68 65 20  removing.** the 
0a90: 71 75 6f 74 65 20 63 68 61 72 61 63 74 65 72 73  quote characters
0aa0: 2e 20 20 54 68 65 20 63 6f 6e 76 65 72 73 69 6f  .  The conversio
0ab0: 6e 20 69 73 20 64 6f 6e 65 20 69 6e 2d 70 6c 61  n is done in-pla
0ac0: 63 65 2e 20 20 49 66 20 74 68 65 0a 2a 2a 20 69  ce.  If the.** i
0ad0: 6e 70 75 74 20 64 6f 65 73 20 6e 6f 74 20 62 65  nput does not be
0ae0: 67 69 6e 20 77 69 74 68 20 61 20 71 75 6f 74 65  gin with a quote
0af0: 20 63 68 61 72 61 63 74 65 72 2c 20 74 68 65 6e   character, then
0b00: 20 74 68 69 73 20 72 6f 75 74 69 6e 65 0a 2a 2a   this routine.**
0b10: 20 69 73 20 61 20 6e 6f 2d 6f 70 2e 0a 2a 2a 0a   is a no-op..**.
0b20: 2a 2a 20 45 78 61 6d 70 6c 65 73 3a 0a 2a 2a 0a  ** Examples:.**.
0b30: 2a 2a 20 20 20 20 20 22 61 62 63 22 20 20 20 62  **     "abc"   b
0b40: 65 63 6f 6d 65 73 20 20 20 61 62 63 0a 2a 2a 20  ecomes   abc.** 
0b50: 20 20 20 20 27 78 79 7a 27 20 20 20 62 65 63 6f      'xyz'   beco
0b60: 6d 65 73 20 20 20 78 79 7a 0a 2a 2a 20 20 20 20  mes   xyz.**    
0b70: 20 5b 70 71 72 5d 20 20 20 62 65 63 6f 6d 65 73   [pqr]   becomes
0b80: 20 20 20 70 71 72 0a 2a 2a 20 20 20 20 20 60 6d     pqr.**     `m
0b90: 6e 6f 60 20 20 20 62 65 63 6f 6d 65 73 20 20 20  no`   becomes   
0ba0: 6d 6e 6f 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f  mno.*/.static vo
0bb0: 69 64 20 64 65 71 75 6f 74 65 53 74 72 69 6e 67  id dequoteString
0bc0: 28 63 68 61 72 20 2a 7a 29 7b 0a 20 20 69 6e 74  (char *z){.  int
0bd0: 20 71 75 6f 74 65 3b 0a 20 20 69 6e 74 20 69 2c   quote;.  int i,
0be0: 20 6a 3b 0a 20 20 69 66 28 20 7a 3d 3d 30 20 29   j;.  if( z==0 )
0bf0: 20 72 65 74 75 72 6e 3b 0a 20 20 71 75 6f 74 65   return;.  quote
0c00: 20 3d 20 7a 5b 30 5d 3b 0a 20 20 73 77 69 74 63   = z[0];.  switc
0c10: 68 28 20 71 75 6f 74 65 20 29 7b 0a 20 20 20 20  h( quote ){.    
0c20: 63 61 73 65 20 27 5c 27 27 3a 20 20 62 72 65 61  case '\'':  brea
0c30: 6b 3b 0a 20 20 20 20 63 61 73 65 20 27 22 27 3a  k;.    case '"':
0c40: 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 63 61     break;.    ca
0c50: 73 65 20 27 60 27 3a 20 20 20 62 72 65 61 6b 3b  se '`':   break;
0c60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0c70: 2f 2a 20 46 6f 72 20 4d 79 53 51 4c 20 63 6f 6d  /* For MySQL com
0c80: 70 61 74 69 62 69 6c 69 74 79 20 2a 2f 0a 20 20  patibility */.  
0c90: 20 20 63 61 73 65 20 27 5b 27 3a 20 20 20 71 75    case '[':   qu
0ca0: 6f 74 65 20 3d 20 27 5d 27 3b 20 20 62 72 65 61  ote = ']';  brea
0cb0: 6b 3b 20 20 2f 2a 20 46 6f 72 20 4d 53 20 53 71  k;  /* For MS Sq
0cc0: 6c 53 65 72 76 65 72 20 63 6f 6d 70 61 74 69 62  lServer compatib
0cd0: 69 6c 69 74 79 20 2a 2f 0a 20 20 20 20 64 65 66  ility */.    def
0ce0: 61 75 6c 74 3a 20 20 20 20 72 65 74 75 72 6e 3b  ault:    return;
0cf0: 0a 20 20 7d 0a 20 20 66 6f 72 28 69 3d 31 2c 20  .  }.  for(i=1, 
0d00: 6a 3d 30 3b 20 7a 5b 69 5d 3b 20 69 2b 2b 29 7b  j=0; z[i]; i++){
0d10: 0a 20 20 20 20 69 66 28 20 7a 5b 69 5d 3d 3d 71  .    if( z[i]==q
0d20: 75 6f 74 65 20 29 7b 0a 20 20 20 20 20 20 69 66  uote ){.      if
0d30: 28 20 7a 5b 69 2b 31 5d 3d 3d 71 75 6f 74 65 20  ( z[i+1]==quote 
0d40: 29 7b 0a 20 20 20 20 20 20 20 20 7a 5b 6a 2b 2b  ){.        z[j++
0d50: 5d 20 3d 20 71 75 6f 74 65 3b 0a 20 20 20 20 20  ] = quote;.     
0d60: 20 20 20 69 2b 2b 3b 0a 20 20 20 20 20 20 7d 65     i++;.      }e
0d70: 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 7a 5b 6a  lse{.        z[j
0d80: 2b 2b 5d 20 3d 20 30 3b 0a 20 20 20 20 20 20 20  ++] = 0;.       
0d90: 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 7d 0a   break;.      }.
0da0: 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20      }else{.     
0db0: 20 7a 5b 6a 2b 2b 5d 20 3d 20 7a 5b 69 5d 3b 0a   z[j++] = z[i];.
0dc0: 20 20 20 20 7d 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a      }.  }.}../*.
0dd0: 2a 2a 20 52 65 74 72 69 65 76 65 20 74 68 65 20  ** Retrieve the 
0de0: 63 6f 6c 75 6d 6e 20 6e 61 6d 65 73 20 66 6f 72  column names for
0df0: 20 74 68 65 20 74 61 62 6c 65 20 6e 61 6d 65 64   the table named
0e00: 20 7a 54 61 62 20 76 69 61 20 64 61 74 61 62 61   zTab via databa
0e10: 73 65 0a 2a 2a 20 63 6f 6e 6e 65 63 74 69 6f 6e  se.** connection
0e20: 20 64 62 2e 20 53 51 4c 49 54 45 5f 4f 4b 20 69   db. SQLITE_OK i
0e30: 73 20 72 65 74 75 72 6e 65 64 20 6f 6e 20 73 75  s returned on su
0e40: 63 63 65 73 73 2c 20 6f 72 20 61 6e 20 73 71 6c  ccess, or an sql
0e50: 69 74 65 20 65 72 72 6f 72 0a 2a 2a 20 63 6f 64  ite error.** cod
0e60: 65 20 6f 74 68 65 72 77 69 73 65 2e 0a 2a 2a 0a  e otherwise..**.
0e70: 2a 2a 20 49 66 20 73 75 63 63 65 73 73 66 75 6c  ** If successful
0e80: 2c 20 74 68 65 20 6e 75 6d 62 65 72 20 6f 66 20  , the number of 
0e90: 63 6f 6c 75 6d 6e 73 20 69 73 20 77 72 69 74 74  columns is writt
0ea0: 65 6e 20 74 6f 20 2a 70 6e 43 6f 6c 2e 20 2a 70  en to *pnCol. *p
0eb0: 61 43 6f 6c 20 69 73 0a 2a 2a 20 73 65 74 20 74  aCol is.** set t
0ec0: 6f 20 70 6f 69 6e 74 20 61 74 20 73 71 6c 69 74  o point at sqlit
0ed0: 65 33 5f 6d 61 6c 6c 6f 63 28 29 27 64 20 73 70  e3_malloc()'d sp
0ee0: 61 63 65 20 63 6f 6e 74 61 69 6e 69 6e 67 20 74  ace containing t
0ef0: 68 65 20 61 72 72 61 79 20 6f 66 0a 2a 2a 20 6e  he array of.** n
0f00: 43 6f 6c 20 63 6f 6c 75 6d 6e 20 6e 61 6d 65 73  Col column names
0f10: 2e 20 54 68 65 20 63 61 6c 6c 65 72 20 69 73 20  . The caller is 
0f20: 72 65 73 70 6f 6e 73 69 62 6c 65 20 66 6f 72 20  responsible for 
0f30: 63 61 6c 6c 69 6e 67 20 73 71 6c 69 74 65 33 5f  calling sqlite3_
0f40: 66 72 65 65 0a 2a 2a 20 6f 6e 20 2a 70 61 43 6f  free.** on *paCo
0f50: 6c 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  l..*/.static int
0f60: 20 67 65 74 43 6f 6c 75 6d 6e 4e 61 6d 65 73 28   getColumnNames(
0f70: 0a 20 20 73 71 6c 69 74 65 33 20 2a 64 62 2c 20  .  sqlite3 *db, 
0f80: 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a  .  const char *z
0f90: 54 61 62 2c 0a 20 20 63 68 61 72 20 2a 2a 2a 70  Tab,.  char ***p
0fa0: 61 43 6f 6c 2c 20 0a 20 20 69 6e 74 20 2a 70 6e  aCol, .  int *pn
0fb0: 43 6f 6c 0a 29 7b 0a 20 20 63 68 61 72 20 2a 2a  Col.){.  char **
0fc0: 61 43 6f 6c 20 3d 20 30 3b 0a 20 20 63 68 61 72  aCol = 0;.  char
0fd0: 20 2a 7a 53 71 6c 3b 0a 20 20 73 71 6c 69 74 65   *zSql;.  sqlite
0fe0: 33 5f 73 74 6d 74 20 2a 70 53 74 6d 74 20 3d 20  3_stmt *pStmt = 
0ff0: 30 3b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51  0;.  int rc = SQ
1000: 4c 49 54 45 5f 4f 4b 3b 0a 20 20 69 6e 74 20 6e  LITE_OK;.  int n
1010: 43 6f 6c 20 3d 20 30 3b 0a 0a 20 20 2f 2a 20 50  Col = 0;..  /* P
1020: 72 65 70 61 72 65 20 74 68 65 20 73 74 61 74 65  repare the state
1030: 6d 65 6e 74 20 22 53 45 4c 45 43 54 20 2a 20 46  ment "SELECT * F
1040: 52 4f 4d 20 3c 74 62 6c 3e 22 2e 20 54 68 65 20  ROM <tbl>". The 
1050: 63 6f 6c 75 6d 6e 20 6e 61 6d 65 73 0a 20 20 2a  column names.  *
1060: 2a 20 6f 66 20 74 68 65 20 72 65 73 75 6c 74 20  * of the result 
1070: 73 65 74 20 6f 66 20 74 68 65 20 63 6f 6d 70 69  set of the compi
1080: 6c 65 64 20 53 45 4c 45 43 54 20 77 69 6c 6c 20  led SELECT will 
1090: 62 65 20 74 68 65 20 73 61 6d 65 20 61 73 0a 20  be the same as. 
10a0: 20 2a 2a 20 74 68 65 20 63 6f 6c 75 6d 6e 20 6e   ** the column n
10b0: 61 6d 65 73 20 6f 66 20 74 61 62 6c 65 20 3c 74  ames of table <t
10c0: 62 6c 3e 2e 0a 20 20 2a 2f 0a 20 20 7a 53 71 6c  bl>..  */.  zSql
10d0: 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e   = sqlite3_mprin
10e0: 74 66 28 22 53 45 4c 45 43 54 20 2a 20 46 52 4f  tf("SELECT * FRO
10f0: 4d 20 25 51 22 2c 20 7a 54 61 62 29 3b 0a 20 20  M %Q", zTab);.  
1100: 69 66 28 20 21 7a 53 71 6c 20 29 7b 0a 20 20 20  if( !zSql ){.   
1110: 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d   rc = SQLITE_NOM
1120: 45 4d 3b 0a 20 20 20 20 67 6f 74 6f 20 6f 75 74  EM;.    goto out
1130: 3b 0a 20 20 7d 0a 20 20 72 63 20 3d 20 73 71 6c  ;.  }.  rc = sql
1140: 69 74 65 33 5f 70 72 65 70 61 72 65 28 64 62 2c  ite3_prepare(db,
1150: 20 7a 53 71 6c 2c 20 2d 31 2c 20 26 70 53 74 6d   zSql, -1, &pStm
1160: 74 2c 20 30 29 3b 0a 20 20 73 71 6c 69 74 65 33  t, 0);.  sqlite3
1170: 5f 66 72 65 65 28 7a 53 71 6c 29 3b 0a 0a 20 20  _free(zSql);..  
1180: 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  if( rc==SQLITE_O
1190: 4b 20 29 7b 0a 20 20 20 20 69 6e 74 20 69 69 3b  K ){.    int ii;
11a0: 0a 20 20 20 20 69 6e 74 20 6e 42 79 74 65 73 3b  .    int nBytes;
11b0: 0a 20 20 20 20 63 68 61 72 20 2a 7a 53 70 61 63  .    char *zSpac
11c0: 65 3b 0a 20 20 20 20 6e 43 6f 6c 20 3d 20 73 71  e;.    nCol = sq
11d0: 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 63 6f 75  lite3_column_cou
11e0: 6e 74 28 70 53 74 6d 74 29 3b 0a 0a 20 20 20 20  nt(pStmt);..    
11f0: 2f 2a 20 46 69 67 75 72 65 20 6f 75 74 20 68 6f  /* Figure out ho
1200: 77 20 6d 75 63 68 20 73 70 61 63 65 20 74 6f 20  w much space to 
1210: 61 6c 6c 6f 63 61 74 65 20 66 6f 72 20 74 68 65  allocate for the
1220: 20 61 72 72 61 79 20 6f 66 20 63 6f 6c 75 6d 6e   array of column
1230: 20 6e 61 6d 65 73 20 0a 20 20 20 20 2a 2a 20 28   names .    ** (
1240: 69 6e 63 6c 75 64 69 6e 67 20 73 70 61 63 65 20  including space 
1250: 66 6f 72 20 74 68 65 20 73 74 72 69 6e 67 73 20  for the strings 
1260: 74 68 65 6d 73 65 6c 76 65 73 29 2e 20 54 68 65  themselves). The
1270: 6e 20 61 6c 6c 6f 63 61 74 65 20 69 74 2e 0a 20  n allocate it.. 
1280: 20 20 20 2a 2f 0a 20 20 20 20 6e 42 79 74 65 73     */.    nBytes
1290: 20 3d 20 73 69 7a 65 6f 66 28 63 68 61 72 20 2a   = sizeof(char *
12a0: 29 20 2a 20 6e 43 6f 6c 3b 0a 20 20 20 20 66 6f  ) * nCol;.    fo
12b0: 72 28 69 69 3d 30 3b 20 69 69 3c 6e 43 6f 6c 3b  r(ii=0; ii<nCol;
12c0: 20 69 69 2b 2b 29 7b 0a 20 20 20 20 20 20 63 6f   ii++){.      co
12d0: 6e 73 74 20 63 68 61 72 20 2a 7a 4e 61 6d 65 20  nst char *zName 
12e0: 3d 20 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e  = sqlite3_column
12f0: 5f 6e 61 6d 65 28 70 53 74 6d 74 2c 20 69 69 29  _name(pStmt, ii)
1300: 3b 0a 20 20 20 20 20 20 69 66 28 20 21 7a 4e 61  ;.      if( !zNa
1310: 6d 65 20 29 7b 0a 20 20 20 20 20 20 20 20 72 63  me ){.        rc
1320: 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b   = SQLITE_NOMEM;
1330: 0a 20 20 20 20 20 20 20 20 67 6f 74 6f 20 6f 75  .        goto ou
1340: 74 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20  t;.      }.     
1350: 20 6e 42 79 74 65 73 20 2b 3d 20 73 74 72 6c 65   nBytes += strle
1360: 6e 28 7a 4e 61 6d 65 29 2b 31 3b 0a 20 20 20 20  n(zName)+1;.    
1370: 7d 0a 20 20 20 20 61 43 6f 6c 20 3d 20 28 63 68  }.    aCol = (ch
1380: 61 72 20 2a 2a 29 73 71 6c 69 74 65 33 4d 61 6c  ar **)sqlite3Mal
1390: 6c 6f 63 5a 65 72 6f 28 6e 42 79 74 65 73 29 3b  locZero(nBytes);
13a0: 0a 20 20 20 20 69 66 28 20 21 61 43 6f 6c 20 29  .    if( !aCol )
13b0: 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c  {.      rc = SQL
13c0: 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 20  ITE_NOMEM;.     
13d0: 20 67 6f 74 6f 20 6f 75 74 3b 0a 20 20 20 20 7d   goto out;.    }
13e0: 0a 0a 20 20 20 20 2f 2a 20 43 6f 70 79 20 74 68  ..    /* Copy th
13f0: 65 20 63 6f 6c 75 6d 6e 20 6e 61 6d 65 73 20 69  e column names i
1400: 6e 74 6f 20 74 68 65 20 61 6c 6c 6f 63 61 74 65  nto the allocate
1410: 64 20 73 70 61 63 65 20 61 6e 64 20 73 65 74 20  d space and set 
1420: 75 70 20 74 68 65 0a 20 20 20 20 2a 2a 20 70 6f  up the.    ** po
1430: 69 6e 74 65 72 73 20 69 6e 20 74 68 65 20 61 43  inters in the aC
1440: 6f 6c 5b 5d 20 61 72 72 61 79 2e 0a 20 20 20 20  ol[] array..    
1450: 2a 2f 0a 20 20 20 20 7a 53 70 61 63 65 20 3d 20  */.    zSpace = 
1460: 28 63 68 61 72 20 2a 29 28 26 61 43 6f 6c 5b 6e  (char *)(&aCol[n
1470: 43 6f 6c 5d 29 3b 0a 20 20 20 20 66 6f 72 28 69  Col]);.    for(i
1480: 69 3d 30 3b 20 69 69 3c 6e 43 6f 6c 3b 20 69 69  i=0; ii<nCol; ii
1490: 2b 2b 29 7b 0a 20 20 20 20 20 20 61 43 6f 6c 5b  ++){.      aCol[
14a0: 69 69 5d 20 3d 20 7a 53 70 61 63 65 3b 0a 20 20  ii] = zSpace;.  
14b0: 20 20 20 20 7a 53 70 61 63 65 20 2b 3d 20 73 70      zSpace += sp
14c0: 72 69 6e 74 66 28 7a 53 70 61 63 65 2c 20 22 25  rintf(zSpace, "%
14d0: 73 22 2c 20 73 71 6c 69 74 65 33 5f 63 6f 6c 75  s", sqlite3_colu
14e0: 6d 6e 5f 6e 61 6d 65 28 70 53 74 6d 74 2c 20 69  mn_name(pStmt, i
14f0: 69 29 29 3b 0a 20 20 20 20 20 20 7a 53 70 61 63  i));.      zSpac
1500: 65 2b 2b 3b 0a 20 20 20 20 7d 0a 20 20 20 20 61  e++;.    }.    a
1510: 73 73 65 72 74 28 20 28 7a 53 70 61 63 65 2d 6e  ssert( (zSpace-n
1520: 42 79 74 65 73 29 3d 3d 28 63 68 61 72 20 2a 29  Bytes)==(char *)
1530: 61 43 6f 6c 20 29 3b 0a 20 20 7d 0a 0a 20 20 2a  aCol );.  }..  *
1540: 70 61 43 6f 6c 20 3d 20 61 43 6f 6c 3b 0a 20 20  paCol = aCol;.  
1550: 2a 70 6e 43 6f 6c 20 3d 20 6e 43 6f 6c 3b 0a 0a  *pnCol = nCol;..
1560: 6f 75 74 3a 0a 20 20 73 71 6c 69 74 65 33 5f 66  out:.  sqlite3_f
1570: 69 6e 61 6c 69 7a 65 28 70 53 74 6d 74 29 3b 0a  inalize(pStmt);.
1580: 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a    return rc;.}..
1590: 2f 2a 0a 2a 2a 20 50 61 72 61 6d 65 74 65 72 20  /*.** Parameter 
15a0: 7a 54 61 62 20 69 73 20 74 68 65 20 6e 61 6d 65  zTab is the name
15b0: 20 6f 66 20 61 20 74 61 62 6c 65 20 69 6e 20 64   of a table in d
15c0: 61 74 61 62 61 73 65 20 64 62 20 77 69 74 68 20  atabase db with 
15d0: 6e 43 6f 6c 20 0a 2a 2a 20 63 6f 6c 75 6d 6e 73  nCol .** columns
15e0: 2e 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20  . This function 
15f0: 61 6c 6c 6f 63 61 74 65 73 20 61 6e 20 61 72 72  allocates an arr
1600: 61 79 20 6f 66 20 69 6e 74 65 67 65 72 73 20 6e  ay of integers n
1610: 43 6f 6c 20 69 6e 20 0a 2a 2a 20 73 69 7a 65 20  Col in .** size 
1620: 61 6e 64 20 70 6f 70 75 6c 61 74 65 73 20 69 74  and populates it
1630: 20 61 63 63 6f 72 64 69 6e 67 20 74 6f 20 61 6e   according to an
1640: 79 20 69 6d 70 6c 69 63 69 74 20 6f 72 20 65 78  y implicit or ex
1650: 70 6c 69 63 69 74 20 0a 2a 2a 20 69 6e 64 69 63  plicit .** indic
1660: 65 73 20 6f 6e 20 74 61 62 6c 65 20 7a 54 61 62  es on table zTab
1670: 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 73 75 63 63 65  ..**.** If succe
1680: 73 73 66 75 6c 2c 20 53 51 4c 49 54 45 5f 4f 4b  ssful, SQLITE_OK
1690: 20 69 73 20 72 65 74 75 72 6e 65 64 20 61 6e 64   is returned and
16a0: 20 2a 70 61 49 6e 64 65 78 20 73 65 74 20 74 6f   *paIndex set to
16b0: 20 70 6f 69 6e 74 20 0a 2a 2a 20 61 74 20 74 68   point .** at th
16c0: 65 20 61 6c 6c 6f 63 61 74 65 64 20 61 72 72 61  e allocated arra
16d0: 79 2e 20 4f 74 68 65 72 77 69 73 65 2c 20 61 6e  y. Otherwise, an
16e0: 20 65 72 72 6f 72 20 63 6f 64 65 20 69 73 20 72   error code is r
16f0: 65 74 75 72 6e 65 64 2e 0a 2a 2a 0a 2a 2a 20 53  eturned..**.** S
1700: 65 65 20 63 6f 6d 6d 65 6e 74 73 20 61 73 73 6f  ee comments asso
1710: 63 69 61 74 65 64 20 77 69 74 68 20 74 68 65 20  ciated with the 
1720: 6d 65 6d 62 65 72 20 76 61 72 69 61 62 6c 65 20  member variable 
1730: 61 49 6e 64 65 78 20 61 62 6f 76 65 20 0a 2a 2a  aIndex above .**
1740: 20 22 73 74 72 75 63 74 20 65 63 68 6f 5f 76 74   "struct echo_vt
1750: 61 62 22 20 66 6f 72 20 64 65 74 61 69 6c 73 20  ab" for details 
1760: 6f 66 20 74 68 65 20 63 6f 6e 74 65 6e 74 73 20  of the contents 
1770: 6f 66 20 74 68 65 20 61 72 72 61 79 2e 0a 2a 2f  of the array..*/
1780: 0a 73 74 61 74 69 63 20 69 6e 74 20 67 65 74 49  .static int getI
1790: 6e 64 65 78 41 72 72 61 79 28 0a 20 20 73 71 6c  ndexArray(.  sql
17a0: 69 74 65 33 20 2a 64 62 2c 20 20 20 20 20 20 20  ite3 *db,       
17b0: 20 20 20 20 20 20 2f 2a 20 44 61 74 61 62 61 73        /* Databas
17c0: 65 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 2a 2f 0a  e connection */.
17d0: 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 54    const char *zT
17e0: 61 62 2c 20 20 20 20 20 20 20 20 2f 2a 20 4e 61  ab,        /* Na
17f0: 6d 65 20 6f 66 20 74 61 62 6c 65 20 69 6e 20 64  me of table in d
1800: 61 74 61 62 61 73 65 20 64 62 20 2a 2f 0a 20 20  atabase db */.  
1810: 69 6e 74 20 6e 43 6f 6c 2c 0a 20 20 69 6e 74 20  int nCol,.  int 
1820: 2a 2a 70 61 49 6e 64 65 78 0a 29 7b 0a 20 20 73  **paIndex.){.  s
1830: 71 6c 69 74 65 33 5f 73 74 6d 74 20 2a 70 53 74  qlite3_stmt *pSt
1840: 6d 74 20 3d 20 30 3b 0a 20 20 69 6e 74 20 2a 61  mt = 0;.  int *a
1850: 49 6e 64 65 78 20 3d 20 30 3b 0a 20 20 69 6e 74  Index = 0;.  int
1860: 20 72 63 3b 0a 20 20 63 68 61 72 20 2a 7a 53 71   rc;.  char *zSq
1870: 6c 3b 0a 0a 20 20 2f 2a 20 41 6c 6c 6f 63 61 74  l;..  /* Allocat
1880: 65 20 73 70 61 63 65 20 66 6f 72 20 74 68 65 20  e space for the 
1890: 69 6e 64 65 78 20 61 72 72 61 79 20 2a 2f 0a 20  index array */. 
18a0: 20 61 49 6e 64 65 78 20 3d 20 28 69 6e 74 20 2a   aIndex = (int *
18b0: 29 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63 5a 65  )sqlite3MallocZe
18c0: 72 6f 28 73 69 7a 65 6f 66 28 69 6e 74 29 20 2a  ro(sizeof(int) *
18d0: 20 6e 43 6f 6c 29 3b 0a 20 20 69 66 28 20 21 61   nCol);.  if( !a
18e0: 49 6e 64 65 78 20 29 7b 0a 20 20 20 20 72 63 20  Index ){.    rc 
18f0: 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a  = SQLITE_NOMEM;.
1900: 20 20 20 20 67 6f 74 6f 20 67 65 74 5f 69 6e 64      goto get_ind
1910: 65 78 5f 61 72 72 61 79 5f 6f 75 74 3b 0a 20 20  ex_array_out;.  
1920: 7d 0a 0a 20 20 2f 2a 20 43 6f 6d 70 69 6c 65 20  }..  /* Compile 
1930: 61 6e 20 73 71 6c 69 74 65 20 70 72 61 67 6d 61  an sqlite pragma
1940: 20 74 6f 20 6c 6f 6f 70 20 74 68 72 6f 75 67 68   to loop through
1950: 20 61 6c 6c 20 69 6e 64 69 63 65 73 20 6f 6e 20   all indices on 
1960: 74 61 62 6c 65 20 7a 54 61 62 20 2a 2f 0a 20 20  table zTab */.  
1970: 7a 53 71 6c 20 3d 20 73 71 6c 69 74 65 33 4d 50  zSql = sqlite3MP
1980: 72 69 6e 74 66 28 30 2c 20 22 50 52 41 47 4d 41  rintf(0, "PRAGMA
1990: 20 69 6e 64 65 78 5f 6c 69 73 74 28 25 73 29 22   index_list(%s)"
19a0: 2c 20 7a 54 61 62 29 3b 0a 20 20 69 66 28 20 21  , zTab);.  if( !
19b0: 7a 53 71 6c 20 29 7b 0a 20 20 20 20 72 63 20 3d  zSql ){.    rc =
19c0: 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20   SQLITE_NOMEM;. 
19d0: 20 20 20 67 6f 74 6f 20 67 65 74 5f 69 6e 64 65     goto get_inde
19e0: 78 5f 61 72 72 61 79 5f 6f 75 74 3b 0a 20 20 7d  x_array_out;.  }
19f0: 0a 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f  .  rc = sqlite3_
1a00: 70 72 65 70 61 72 65 28 64 62 2c 20 7a 53 71 6c  prepare(db, zSql
1a10: 2c 20 2d 31 2c 20 26 70 53 74 6d 74 2c 20 30 29  , -1, &pStmt, 0)
1a20: 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65  ;.  sqlite3_free
1a30: 28 7a 53 71 6c 29 3b 0a 0a 20 20 2f 2a 20 46 6f  (zSql);..  /* Fo
1a40: 72 20 65 61 63 68 20 69 6e 64 65 78 2c 20 66 69  r each index, fi
1a50: 67 75 72 65 20 6f 75 74 20 74 68 65 20 6c 65 66  gure out the lef
1a60: 74 2d 6d 6f 73 74 20 63 6f 6c 75 6d 6e 20 61 6e  t-most column an
1a70: 64 20 73 65 74 20 74 68 65 20 0a 20 20 2a 2a 20  d set the .  ** 
1a80: 63 6f 72 72 65 73 70 6f 6e 64 69 6e 67 20 65 6e  corresponding en
1a90: 74 72 79 20 69 6e 20 61 49 6e 64 65 78 5b 5d 20  try in aIndex[] 
1aa0: 74 6f 20 31 2e 0a 20 20 2a 2f 0a 20 20 77 68 69  to 1..  */.  whi
1ab0: 6c 65 28 20 70 53 74 6d 74 20 26 26 20 73 71 6c  le( pStmt && sql
1ac0: 69 74 65 33 5f 73 74 65 70 28 70 53 74 6d 74 29  ite3_step(pStmt)
1ad0: 3d 3d 53 51 4c 49 54 45 5f 52 4f 57 20 29 7b 0a  ==SQLITE_ROW ){.
1ae0: 20 20 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a      const char *
1af0: 7a 49 64 78 20 3d 20 28 63 6f 6e 73 74 20 63 68  zIdx = (const ch
1b00: 61 72 20 2a 29 73 71 6c 69 74 65 33 5f 63 6f 6c  ar *)sqlite3_col
1b10: 75 6d 6e 5f 74 65 78 74 28 70 53 74 6d 74 2c 20  umn_text(pStmt, 
1b20: 31 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f  1);.    sqlite3_
1b30: 73 74 6d 74 20 2a 70 53 74 6d 74 32 20 3d 20 30  stmt *pStmt2 = 0
1b40: 3b 0a 20 20 20 20 7a 53 71 6c 20 3d 20 73 71 6c  ;.    zSql = sql
1b50: 69 74 65 33 4d 50 72 69 6e 74 66 28 30 2c 20 22  ite3MPrintf(0, "
1b60: 50 52 41 47 4d 41 20 69 6e 64 65 78 5f 69 6e 66  PRAGMA index_inf
1b70: 6f 28 25 73 29 22 2c 20 7a 49 64 78 29 3b 0a 20  o(%s)", zIdx);. 
1b80: 20 20 20 69 66 28 20 21 7a 53 71 6c 20 29 7b 0a     if( !zSql ){.
1b90: 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54        rc = SQLIT
1ba0: 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 20 20 67  E_NOMEM;.      g
1bb0: 6f 74 6f 20 67 65 74 5f 69 6e 64 65 78 5f 61 72  oto get_index_ar
1bc0: 72 61 79 5f 6f 75 74 3b 0a 20 20 20 20 7d 0a 20  ray_out;.    }. 
1bd0: 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f     rc = sqlite3_
1be0: 70 72 65 70 61 72 65 28 64 62 2c 20 7a 53 71 6c  prepare(db, zSql
1bf0: 2c 20 2d 31 2c 20 26 70 53 74 6d 74 32 2c 20 30  , -1, &pStmt2, 0
1c00: 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 66  );.    sqlite3_f
1c10: 72 65 65 28 7a 53 71 6c 29 3b 0a 20 20 20 20 69  ree(zSql);.    i
1c20: 66 28 20 70 53 74 6d 74 32 20 26 26 20 73 71 6c  f( pStmt2 && sql
1c30: 69 74 65 33 5f 73 74 65 70 28 70 53 74 6d 74 32  ite3_step(pStmt2
1c40: 29 3d 3d 53 51 4c 49 54 45 5f 52 4f 57 20 29 7b  )==SQLITE_ROW ){
1c50: 0a 20 20 20 20 20 20 69 6e 74 20 63 69 64 20 3d  .      int cid =
1c60: 20 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f   sqlite3_column_
1c70: 69 6e 74 28 70 53 74 6d 74 32 2c 20 31 29 3b 0a  int(pStmt2, 1);.
1c80: 20 20 20 20 20 20 61 73 73 65 72 74 28 20 63 69        assert( ci
1c90: 64 3e 3d 30 20 26 26 20 63 69 64 3c 6e 43 6f 6c  d>=0 && cid<nCol
1ca0: 20 29 3b 0a 20 20 20 20 20 20 61 49 6e 64 65 78   );.      aIndex
1cb0: 5b 63 69 64 5d 20 3d 20 31 3b 0a 20 20 20 20 7d  [cid] = 1;.    }
1cc0: 0a 20 20 20 20 69 66 28 20 70 53 74 6d 74 32 20  .    if( pStmt2 
1cd0: 29 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 73 71  ){.      rc = sq
1ce0: 6c 69 74 65 33 5f 66 69 6e 61 6c 69 7a 65 28 70  lite3_finalize(p
1cf0: 53 74 6d 74 32 29 3b 0a 20 20 20 20 7d 0a 20 20  Stmt2);.    }.  
1d00: 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45    if( rc!=SQLITE
1d10: 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 67 6f 74  _OK ){.      got
1d20: 6f 20 67 65 74 5f 69 6e 64 65 78 5f 61 72 72 61  o get_index_arra
1d30: 79 5f 6f 75 74 3b 0a 20 20 20 20 7d 0a 20 20 7d  y_out;.    }.  }
1d40: 0a 0a 0a 67 65 74 5f 69 6e 64 65 78 5f 61 72 72  ...get_index_arr
1d50: 61 79 5f 6f 75 74 3a 0a 20 20 69 66 28 20 70 53  ay_out:.  if( pS
1d60: 74 6d 74 20 29 7b 0a 20 20 20 20 69 6e 74 20 72  tmt ){.    int r
1d70: 63 32 20 3d 20 73 71 6c 69 74 65 33 5f 66 69 6e  c2 = sqlite3_fin
1d80: 61 6c 69 7a 65 28 70 53 74 6d 74 29 3b 0a 20 20  alize(pStmt);.  
1d90: 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
1da0: 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 72 63 20  _OK ){.      rc 
1db0: 3d 20 72 63 32 3b 0a 20 20 20 20 7d 0a 20 20 7d  = rc2;.    }.  }
1dc0: 0a 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54  .  if( rc!=SQLIT
1dd0: 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 73 71 6c 69  E_OK ){.    sqli
1de0: 74 65 33 5f 66 72 65 65 28 61 49 6e 64 65 78 29  te3_free(aIndex)
1df0: 3b 0a 20 20 20 20 61 49 6e 64 65 78 20 3d 20 30  ;.    aIndex = 0
1e00: 3b 0a 20 20 7d 0a 20 20 2a 70 61 49 6e 64 65 78  ;.  }.  *paIndex
1e10: 20 3d 20 61 49 6e 64 65 78 3b 0a 20 20 72 65 74   = aIndex;.  ret
1e20: 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  urn rc;.}../*.**
1e30: 20 47 6c 6f 62 61 6c 20 54 63 6c 20 76 61 72 69   Global Tcl vari
1e40: 61 62 6c 65 20 24 65 63 68 6f 5f 6d 6f 64 75 6c  able $echo_modul
1e50: 65 20 69 73 20 61 20 6c 69 73 74 2e 20 54 68 69  e is a list. Thi
1e60: 73 20 72 6f 75 74 69 6e 65 20 61 70 70 65 6e 64  s routine append
1e70: 73 0a 2a 2a 20 74 68 65 20 73 74 72 69 6e 67 20  s.** the string 
1e80: 65 6c 65 6d 65 6e 74 20 7a 41 72 67 20 74 6f 20  element zArg to 
1e90: 74 68 61 74 20 6c 69 73 74 20 69 6e 20 69 6e 74  that list in int
1ea0: 65 72 70 72 65 74 65 72 20 69 6e 74 65 72 70 2e  erpreter interp.
1eb0: 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20  .*/.static void 
1ec0: 61 70 70 65 6e 64 54 6f 45 63 68 6f 4d 6f 64 75  appendToEchoModu
1ed0: 6c 65 28 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69  le(Tcl_Interp *i
1ee0: 6e 74 65 72 70 2c 20 63 6f 6e 73 74 20 63 68 61  nterp, const cha
1ef0: 72 20 2a 7a 41 72 67 29 7b 0a 20 20 69 6e 74 20  r *zArg){.  int 
1f00: 66 6c 61 67 73 20 3d 20 28 54 43 4c 5f 41 50 50  flags = (TCL_APP
1f10: 45 4e 44 5f 56 41 4c 55 45 20 7c 20 54 43 4c 5f  END_VALUE | TCL_
1f20: 4c 49 53 54 5f 45 4c 45 4d 45 4e 54 20 7c 20 54  LIST_ELEMENT | T
1f30: 43 4c 5f 47 4c 4f 42 41 4c 5f 4f 4e 4c 59 29 3b  CL_GLOBAL_ONLY);
1f40: 0a 20 20 54 63 6c 5f 53 65 74 56 61 72 28 69 6e  .  Tcl_SetVar(in
1f50: 74 65 72 70 2c 20 22 65 63 68 6f 5f 6d 6f 64 75  terp, "echo_modu
1f60: 6c 65 22 2c 20 28 7a 41 72 67 3f 7a 41 72 67 3a  le", (zArg?zArg:
1f70: 22 22 29 2c 20 66 6c 61 67 73 29 3b 0a 7d 0a 0a  ""), flags);.}..
1f80: 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63 74  /*.** This funct
1f90: 69 6f 6e 20 69 73 20 63 61 6c 6c 65 64 20 66 72  ion is called fr
1fa0: 6f 6d 20 77 69 74 68 69 6e 20 74 68 65 20 65 63  om within the ec
1fb0: 68 6f 2d 6d 6f 64 75 6c 65 73 20 78 43 72 65 61  ho-modules xCrea
1fc0: 74 65 20 61 6e 64 0a 2a 2a 20 78 43 6f 6e 6e 65  te and.** xConne
1fd0: 63 74 20 6d 65 74 68 6f 64 73 2e 20 54 68 65 20  ct methods. The 
1fe0: 61 72 67 63 20 61 6e 64 20 61 72 67 76 20 61 72  argc and argv ar
1ff0: 67 75 6d 65 6e 74 73 20 61 72 65 20 63 6f 70 69  guments are copi
2000: 65 73 20 6f 66 20 74 68 6f 73 65 20 0a 2a 2a 20  es of those .** 
2010: 70 61 73 73 65 64 20 74 6f 20 74 68 65 20 63 61  passed to the ca
2020: 6c 6c 69 6e 67 20 6d 65 74 68 6f 64 2e 20 54 68  lling method. Th
2030: 69 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 72  is function is r
2040: 65 73 70 6f 6e 73 69 62 6c 65 20 66 6f 72 0a 2a  esponsible for.*
2050: 2a 20 63 61 6c 6c 69 6e 67 20 73 71 6c 69 74 65  * calling sqlite
2060: 33 5f 64 65 63 6c 61 72 65 5f 76 74 61 62 28 29  3_declare_vtab()
2070: 20 74 6f 20 64 65 63 6c 61 72 65 20 74 68 65 20   to declare the 
2080: 73 63 68 65 6d 61 20 6f 66 20 74 68 65 20 76 69  schema of the vi
2090: 72 74 75 61 6c 0a 2a 2a 20 74 61 62 6c 65 20 62  rtual.** table b
20a0: 65 69 6e 67 20 63 72 65 61 74 65 64 20 6f 72 20  eing created or 
20b0: 63 6f 6e 6e 65 63 74 65 64 2e 0a 2a 2a 0a 2a 2a  connected..**.**
20c0: 20 49 66 20 74 68 65 20 63 6f 6e 73 74 72 75 63   If the construc
20d0: 74 6f 72 20 77 61 73 20 70 61 73 73 65 64 20 6a  tor was passed j
20e0: 75 73 74 20 6f 6e 65 20 61 72 67 75 6d 65 6e 74  ust one argument
20f0: 2c 20 69 2e 65 2e 3a 0a 2a 2a 0a 2a 2a 20 20 20  , i.e.:.**.**   
2100: 43 52 45 41 54 45 20 54 41 42 4c 45 20 74 31 20  CREATE TABLE t1 
2110: 41 53 20 65 63 68 6f 28 74 32 29 3b 0a 2a 2a 0a  AS echo(t2);.**.
2120: 2a 2a 20 54 68 65 6e 20 74 32 20 69 73 20 61 73  ** Then t2 is as
2130: 73 75 6d 65 64 20 74 6f 20 62 65 20 74 68 65 20  sumed to be the 
2140: 6e 61 6d 65 20 6f 66 20 61 20 2a 72 65 61 6c 2a  name of a *real*
2150: 20 64 61 74 61 62 61 73 65 20 74 61 62 6c 65 2e   database table.
2160: 20 54 68 65 0a 2a 2a 20 73 63 68 65 6d 61 20 6f   The.** schema o
2170: 66 20 74 68 65 20 76 69 72 74 75 61 6c 20 74 61  f the virtual ta
2180: 62 6c 65 20 69 73 20 64 65 63 6c 61 72 65 64 20  ble is declared 
2190: 62 79 20 70 61 73 73 69 6e 67 20 61 20 63 6f 70  by passing a cop
21a0: 79 20 6f 66 20 74 68 65 20 0a 2a 2a 20 43 52 45  y of the .** CRE
21b0: 41 54 45 20 54 41 42 4c 45 20 73 74 61 74 65 6d  ATE TABLE statem
21c0: 65 6e 74 20 66 6f 72 20 74 68 65 20 72 65 61 6c  ent for the real
21d0: 20 74 61 62 6c 65 20 74 6f 20 73 71 6c 69 74 65   table to sqlite
21e0: 33 5f 64 65 63 6c 61 72 65 5f 76 74 61 62 28 29  3_declare_vtab()
21f0: 2e 0a 2a 2a 20 48 65 6e 63 65 2c 20 74 68 65 20  ..** Hence, the 
2200: 76 69 72 74 75 61 6c 20 74 61 62 6c 65 20 73 68  virtual table sh
2210: 6f 75 6c 64 20 68 61 76 65 20 65 78 61 63 74 6c  ould have exactl
2220: 79 20 74 68 65 20 73 61 6d 65 20 63 6f 6c 75 6d  y the same colum
2230: 6e 20 6e 61 6d 65 73 20 61 6e 64 20 0a 2a 2a 20  n names and .** 
2240: 74 79 70 65 73 20 61 73 20 74 68 65 20 72 65 61  types as the rea
2250: 6c 20 74 61 62 6c 65 2e 0a 2a 2f 0a 73 74 61 74  l table..*/.stat
2260: 69 63 20 69 6e 74 20 65 63 68 6f 44 65 63 6c 61  ic int echoDecla
2270: 72 65 56 74 61 62 28 0a 20 20 65 63 68 6f 5f 76  reVtab(.  echo_v
2280: 74 61 62 20 2a 70 56 74 61 62 2c 20 0a 20 20 73  tab *pVtab, .  s
2290: 71 6c 69 74 65 33 20 2a 64 62 20 0a 29 7b 0a 20  qlite3 *db .){. 
22a0: 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45   int rc = SQLITE
22b0: 5f 4f 4b 3b 0a 0a 20 20 69 66 28 20 70 56 74 61  _OK;..  if( pVta
22c0: 62 2d 3e 7a 54 61 62 6c 65 4e 61 6d 65 20 29 7b  b->zTableName ){
22d0: 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 73 74 6d  .    sqlite3_stm
22e0: 74 20 2a 70 53 74 6d 74 20 3d 20 30 3b 0a 20 20  t *pStmt = 0;.  
22f0: 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 70    rc = sqlite3_p
2300: 72 65 70 61 72 65 28 64 62 2c 20 0a 20 20 20 20  repare(db, .    
2310: 20 20 20 20 22 53 45 4c 45 43 54 20 73 71 6c 20      "SELECT sql 
2320: 46 52 4f 4d 20 73 71 6c 69 74 65 5f 6d 61 73 74  FROM sqlite_mast
2330: 65 72 20 57 48 45 52 45 20 74 79 70 65 20 3d 20  er WHERE type = 
2340: 27 74 61 62 6c 65 27 20 41 4e 44 20 6e 61 6d 65  'table' AND name
2350: 20 3d 20 3f 22 2c 0a 20 20 20 20 20 20 20 20 2d   = ?",.        -
2360: 31 2c 20 26 70 53 74 6d 74 2c 20 30 29 3b 0a 20  1, &pStmt, 0);. 
2370: 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54     if( rc==SQLIT
2380: 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 73 71  E_OK ){.      sq
2390: 6c 69 74 65 33 5f 62 69 6e 64 5f 74 65 78 74 28  lite3_bind_text(
23a0: 70 53 74 6d 74 2c 20 31 2c 20 70 56 74 61 62 2d  pStmt, 1, pVtab-
23b0: 3e 7a 54 61 62 6c 65 4e 61 6d 65 2c 20 2d 31 2c  >zTableName, -1,
23c0: 20 30 29 3b 0a 20 20 20 20 20 20 69 66 28 20 73   0);.      if( s
23d0: 71 6c 69 74 65 33 5f 73 74 65 70 28 70 53 74 6d  qlite3_step(pStm
23e0: 74 29 3d 3d 53 51 4c 49 54 45 5f 52 4f 57 20 29  t)==SQLITE_ROW )
23f0: 7b 0a 20 20 20 20 20 20 20 20 69 6e 74 20 72 63  {.        int rc
2400: 32 3b 0a 20 20 20 20 20 20 20 20 63 6f 6e 73 74  2;.        const
2410: 20 63 68 61 72 20 2a 7a 43 72 65 61 74 65 54 61   char *zCreateTa
2420: 62 6c 65 20 3d 20 28 63 6f 6e 73 74 20 63 68 61  ble = (const cha
2430: 72 20 2a 29 73 71 6c 69 74 65 33 5f 63 6f 6c 75  r *)sqlite3_colu
2440: 6d 6e 5f 74 65 78 74 28 70 53 74 6d 74 2c 20 30  mn_text(pStmt, 0
2450: 29 3b 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20  );.        rc = 
2460: 73 71 6c 69 74 65 33 5f 64 65 63 6c 61 72 65 5f  sqlite3_declare_
2470: 76 74 61 62 28 64 62 2c 20 7a 43 72 65 61 74 65  vtab(db, zCreate
2480: 54 61 62 6c 65 29 3b 0a 20 20 20 20 20 20 20 20  Table);.        
2490: 72 63 32 20 3d 20 73 71 6c 69 74 65 33 5f 66 69  rc2 = sqlite3_fi
24a0: 6e 61 6c 69 7a 65 28 70 53 74 6d 74 29 3b 0a 20  nalize(pStmt);. 
24b0: 20 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d 53         if( rc==S
24c0: 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
24d0: 20 20 20 20 20 20 72 63 20 3d 20 72 63 32 3b 0a        rc = rc2;.
24e0: 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20          }.      
24f0: 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20 20 20 20  } else {.       
2500: 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 66 69   rc = sqlite3_fi
2510: 6e 61 6c 69 7a 65 28 70 53 74 6d 74 29 3b 0a 20  nalize(pStmt);. 
2520: 20 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d 53         if( rc==S
2530: 51 4c 49 54 45 5f 4f 4b 20 29 7b 20 0a 20 20 20  QLITE_OK ){ .   
2540: 20 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c 49         rc = SQLI
2550: 54 45 5f 45 52 52 4f 52 3b 0a 20 20 20 20 20 20  TE_ERROR;.      
2560: 20 20 7d 0a 20 20 20 20 20 20 7d 0a 20 20 20 20    }.      }.    
2570: 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
2580: 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20 20 72  _OK ){.        r
2590: 63 20 3d 20 67 65 74 43 6f 6c 75 6d 6e 4e 61 6d  c = getColumnNam
25a0: 65 73 28 64 62 2c 20 70 56 74 61 62 2d 3e 7a 54  es(db, pVtab->zT
25b0: 61 62 6c 65 4e 61 6d 65 2c 20 26 70 56 74 61 62  ableName, &pVtab
25c0: 2d 3e 61 43 6f 6c 2c 20 26 70 56 74 61 62 2d 3e  ->aCol, &pVtab->
25d0: 6e 43 6f 6c 29 3b 0a 20 20 20 20 20 20 7d 0a 20  nCol);.      }. 
25e0: 20 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c       if( rc==SQL
25f0: 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20  ITE_OK ){.      
2600: 20 20 72 63 20 3d 20 67 65 74 49 6e 64 65 78 41    rc = getIndexA
2610: 72 72 61 79 28 64 62 2c 20 70 56 74 61 62 2d 3e  rray(db, pVtab->
2620: 7a 54 61 62 6c 65 4e 61 6d 65 2c 20 70 56 74 61  zTableName, pVta
2630: 62 2d 3e 6e 43 6f 6c 2c 20 26 70 56 74 61 62 2d  b->nCol, &pVtab-
2640: 3e 61 49 6e 64 65 78 29 3b 0a 20 20 20 20 20 20  >aIndex);.      
2650: 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 72  }.    }.  }..  r
2660: 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a  eturn rc;.}../*.
2670: 2a 2a 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e  ** This function
2680: 20 66 72 65 65 73 20 61 6c 6c 20 72 75 6e 74 69   frees all runti
2690: 6d 65 20 73 74 72 75 63 74 75 72 65 73 20 61 73  me structures as
26a0: 73 6f 63 69 61 74 65 64 20 77 69 74 68 20 74 68  sociated with th
26b0: 65 20 76 69 72 74 75 61 6c 0a 2a 2a 20 74 61 62  e virtual.** tab
26c0: 6c 65 20 70 56 74 61 62 2e 0a 2a 2f 0a 73 74 61  le pVtab..*/.sta
26d0: 74 69 63 20 69 6e 74 20 65 63 68 6f 44 65 73 74  tic int echoDest
26e0: 72 75 63 74 6f 72 28 73 71 6c 69 74 65 33 5f 76  ructor(sqlite3_v
26f0: 74 61 62 20 2a 70 56 74 61 62 29 7b 0a 20 20 65  tab *pVtab){.  e
2700: 63 68 6f 5f 76 74 61 62 20 2a 70 20 3d 20 28 65  cho_vtab *p = (e
2710: 63 68 6f 5f 76 74 61 62 2a 29 70 56 74 61 62 3b  cho_vtab*)pVtab;
2720: 0a 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28  .  sqlite3_free(
2730: 70 2d 3e 61 49 6e 64 65 78 29 3b 0a 20 20 73 71  p->aIndex);.  sq
2740: 6c 69 74 65 33 5f 66 72 65 65 28 70 2d 3e 61 43  lite3_free(p->aC
2750: 6f 6c 29 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66  ol);.  sqlite3_f
2760: 72 65 65 28 70 2d 3e 7a 54 68 69 73 29 3b 0a 20  ree(p->zThis);. 
2770: 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70 2d   sqlite3_free(p-
2780: 3e 7a 54 61 62 6c 65 4e 61 6d 65 29 3b 0a 20 20  >zTableName);.  
2790: 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70 2d 3e  sqlite3_free(p->
27a0: 7a 4c 6f 67 4e 61 6d 65 29 3b 0a 20 20 73 71 6c  zLogName);.  sql
27b0: 69 74 65 33 5f 66 72 65 65 28 70 29 3b 0a 20 20  ite3_free(p);.  
27c0: 72 65 74 75 72 6e 20 30 3b 0a 7d 0a 0a 74 79 70  return 0;.}..typ
27d0: 65 64 65 66 20 73 74 72 75 63 74 20 45 63 68 6f  edef struct Echo
27e0: 4d 6f 64 75 6c 65 20 45 63 68 6f 4d 6f 64 75 6c  Module EchoModul
27f0: 65 3b 0a 73 74 72 75 63 74 20 45 63 68 6f 4d 6f  e;.struct EchoMo
2800: 64 75 6c 65 20 7b 0a 20 20 54 63 6c 5f 49 6e 74  dule {.  Tcl_Int
2810: 65 72 70 20 2a 69 6e 74 65 72 70 3b 0a 7d 3b 0a  erp *interp;.};.
2820: 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63  ./*.** This func
2830: 74 69 6f 6e 20 69 73 20 63 61 6c 6c 65 64 20 74  tion is called t
2840: 6f 20 64 6f 20 74 68 65 20 77 6f 72 6b 20 6f 66  o do the work of
2850: 20 74 68 65 20 78 43 6f 6e 6e 65 63 74 28 29 20   the xConnect() 
2860: 6d 65 74 68 6f 64 20 2d 0a 2a 2a 20 74 6f 20 61  method -.** to a
2870: 6c 6c 6f 63 61 74 65 20 74 68 65 20 72 65 71 75  llocate the requ
2880: 69 72 65 64 20 69 6e 2d 6d 65 6d 6f 72 79 20 73  ired in-memory s
2890: 74 72 75 63 74 75 72 65 73 20 66 6f 72 20 61 20  tructures for a 
28a0: 6e 65 77 6c 79 20 63 6f 6e 6e 65 63 74 65 64 0a  newly connected.
28b0: 2a 2a 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65  ** virtual table
28c0: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
28d0: 65 63 68 6f 43 6f 6e 73 74 72 75 63 74 6f 72 28  echoConstructor(
28e0: 0a 20 20 73 71 6c 69 74 65 33 20 2a 64 62 2c 0a  .  sqlite3 *db,.
28f0: 20 20 76 6f 69 64 20 2a 70 41 75 78 2c 0a 20 20    void *pAux,.  
2900: 69 6e 74 20 61 72 67 63 2c 20 63 6f 6e 73 74 20  int argc, const 
2910: 63 68 61 72 20 2a 63 6f 6e 73 74 2a 61 72 67 76  char *const*argv
2920: 2c 0a 20 20 73 71 6c 69 74 65 33 5f 76 74 61 62  ,.  sqlite3_vtab
2930: 20 2a 2a 70 70 56 74 61 62 2c 0a 20 20 63 68 61   **ppVtab,.  cha
2940: 72 20 2a 2a 70 7a 45 72 72 0a 29 7b 0a 20 20 69  r **pzErr.){.  i
2950: 6e 74 20 72 63 3b 0a 20 20 69 6e 74 20 69 3b 0a  nt rc;.  int i;.
2960: 20 20 65 63 68 6f 5f 76 74 61 62 20 2a 70 56 74    echo_vtab *pVt
2970: 61 62 3b 0a 0a 20 20 2f 2a 20 41 6c 6c 6f 63 61  ab;..  /* Alloca
2980: 74 65 20 74 68 65 20 73 71 6c 69 74 65 33 5f 76  te the sqlite3_v
2990: 74 61 62 2f 65 63 68 6f 5f 76 74 61 62 20 73 74  tab/echo_vtab st
29a0: 72 75 63 74 75 72 65 20 69 74 73 65 6c 66 20 2a  ructure itself *
29b0: 2f 0a 20 20 70 56 74 61 62 20 3d 20 73 71 6c 69  /.  pVtab = sqli
29c0: 74 65 33 4d 61 6c 6c 6f 63 5a 65 72 6f 28 20 73  te3MallocZero( s
29d0: 69 7a 65 6f 66 28 2a 70 56 74 61 62 29 20 29 3b  izeof(*pVtab) );
29e0: 0a 20 20 69 66 28 20 21 70 56 74 61 62 20 29 7b  .  if( !pVtab ){
29f0: 0a 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49  .    return SQLI
2a00: 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 7d 0a 20 20  TE_NOMEM;.  }.  
2a10: 70 56 74 61 62 2d 3e 69 6e 74 65 72 70 20 3d 20  pVtab->interp = 
2a20: 28 28 45 63 68 6f 4d 6f 64 75 6c 65 20 2a 29 70  ((EchoModule *)p
2a30: 41 75 78 29 2d 3e 69 6e 74 65 72 70 3b 0a 20 20  Aux)->interp;.  
2a40: 70 56 74 61 62 2d 3e 64 62 20 3d 20 64 62 3b 0a  pVtab->db = db;.
2a50: 0a 20 20 2f 2a 20 41 6c 6c 6f 63 61 74 65 20 65  .  /* Allocate e
2a60: 63 68 6f 5f 76 74 61 62 2e 7a 54 68 69 73 20 2a  cho_vtab.zThis *
2a70: 2f 0a 20 20 70 56 74 61 62 2d 3e 7a 54 68 69 73  /.  pVtab->zThis
2a80: 20 3d 20 73 71 6c 69 74 65 33 4d 50 72 69 6e 74   = sqlite3MPrint
2a90: 66 28 30 2c 20 22 25 73 22 2c 20 61 72 67 76 5b  f(0, "%s", argv[
2aa0: 32 5d 29 3b 0a 20 20 69 66 28 20 21 70 56 74 61  2]);.  if( !pVta
2ab0: 62 2d 3e 7a 54 68 69 73 20 29 7b 0a 20 20 20 20  b->zThis ){.    
2ac0: 65 63 68 6f 44 65 73 74 72 75 63 74 6f 72 28 28  echoDestructor((
2ad0: 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 29 70  sqlite3_vtab *)p
2ae0: 56 74 61 62 29 3b 0a 20 20 20 20 72 65 74 75 72  Vtab);.    retur
2af0: 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a  n SQLITE_NOMEM;.
2b00: 20 20 7d 0a 0a 20 20 2f 2a 20 41 6c 6c 6f 63 61    }..  /* Alloca
2b10: 74 65 20 65 63 68 6f 5f 76 74 61 62 2e 7a 54 61  te echo_vtab.zTa
2b20: 62 6c 65 4e 61 6d 65 20 2a 2f 0a 20 20 69 66 28  bleName */.  if(
2b30: 20 61 72 67 63 3e 33 20 29 7b 0a 20 20 20 20 70   argc>3 ){.    p
2b40: 56 74 61 62 2d 3e 7a 54 61 62 6c 65 4e 61 6d 65  Vtab->zTableName
2b50: 20 3d 20 73 71 6c 69 74 65 33 4d 50 72 69 6e 74   = sqlite3MPrint
2b60: 66 28 30 2c 20 22 25 73 22 2c 20 61 72 67 76 5b  f(0, "%s", argv[
2b70: 33 5d 29 3b 0a 20 20 20 20 64 65 71 75 6f 74 65  3]);.    dequote
2b80: 53 74 72 69 6e 67 28 70 56 74 61 62 2d 3e 7a 54  String(pVtab->zT
2b90: 61 62 6c 65 4e 61 6d 65 29 3b 0a 20 20 20 20 69  ableName);.    i
2ba0: 66 28 20 70 56 74 61 62 2d 3e 7a 54 61 62 6c 65  f( pVtab->zTable
2bb0: 4e 61 6d 65 20 26 26 20 70 56 74 61 62 2d 3e 7a  Name && pVtab->z
2bc0: 54 61 62 6c 65 4e 61 6d 65 5b 30 5d 3d 3d 27 2a  TableName[0]=='*
2bd0: 27 20 29 7b 0a 20 20 20 20 20 20 63 68 61 72 20  ' ){.      char 
2be0: 2a 7a 20 3d 20 73 71 6c 69 74 65 33 4d 50 72 69  *z = sqlite3MPri
2bf0: 6e 74 66 28 30 2c 20 22 25 73 25 73 22 2c 20 61  ntf(0, "%s%s", a
2c00: 72 67 76 5b 32 5d 2c 20 26 28 70 56 74 61 62 2d  rgv[2], &(pVtab-
2c10: 3e 7a 54 61 62 6c 65 4e 61 6d 65 5b 31 5d 29 29  >zTableName[1]))
2c20: 3b 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f  ;.      sqlite3_
2c30: 66 72 65 65 28 70 56 74 61 62 2d 3e 7a 54 61 62  free(pVtab->zTab
2c40: 6c 65 4e 61 6d 65 29 3b 0a 20 20 20 20 20 20 70  leName);.      p
2c50: 56 74 61 62 2d 3e 7a 54 61 62 6c 65 4e 61 6d 65  Vtab->zTableName
2c60: 20 3d 20 7a 3b 0a 20 20 20 20 20 20 70 56 74 61   = z;.      pVta
2c70: 62 2d 3e 69 73 50 61 74 74 65 72 6e 20 3d 20 31  b->isPattern = 1
2c80: 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 28 20  ;.    }.    if( 
2c90: 21 70 56 74 61 62 2d 3e 7a 54 61 62 6c 65 4e 61  !pVtab->zTableNa
2ca0: 6d 65 20 29 7b 0a 20 20 20 20 20 20 65 63 68 6f  me ){.      echo
2cb0: 44 65 73 74 72 75 63 74 6f 72 28 28 73 71 6c 69  Destructor((sqli
2cc0: 74 65 33 5f 76 74 61 62 20 2a 29 70 56 74 61 62  te3_vtab *)pVtab
2cd0: 29 3b 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20  );.      return 
2ce0: 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20  SQLITE_NOMEM;.  
2cf0: 20 20 7d 0a 20 20 7d 0a 0a 20 20 2f 2a 20 4c 6f    }.  }..  /* Lo
2d00: 67 20 74 68 65 20 61 72 67 75 6d 65 6e 74 73 20  g the arguments 
2d10: 74 6f 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e  to this function
2d20: 20 74 6f 20 54 63 6c 20 76 61 72 20 3a 3a 65 63   to Tcl var ::ec
2d30: 68 6f 5f 6d 6f 64 75 6c 65 20 2a 2f 0a 20 20 66  ho_module */.  f
2d40: 6f 72 28 69 3d 30 3b 20 69 3c 61 72 67 63 3b 20  or(i=0; i<argc; 
2d50: 69 2b 2b 29 7b 0a 20 20 20 20 61 70 70 65 6e 64  i++){.    append
2d60: 54 6f 45 63 68 6f 4d 6f 64 75 6c 65 28 70 56 74  ToEchoModule(pVt
2d70: 61 62 2d 3e 69 6e 74 65 72 70 2c 20 61 72 67 76  ab->interp, argv
2d80: 5b 69 5d 29 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20  [i]);.  }..  /* 
2d90: 49 6e 76 6f 6b 65 20 73 71 6c 69 74 65 33 5f 64  Invoke sqlite3_d
2da0: 65 63 6c 61 72 65 5f 76 74 61 62 20 61 6e 64 20  eclare_vtab and 
2db0: 73 65 74 20 75 70 20 6f 74 68 65 72 20 6d 65 6d  set up other mem
2dc0: 62 65 72 73 20 6f 66 20 74 68 65 20 65 63 68 6f  bers of the echo
2dd0: 5f 76 74 61 62 0a 20 20 2a 2a 20 73 74 72 75 63  _vtab.  ** struc
2de0: 74 75 72 65 2e 20 49 66 20 61 6e 20 65 72 72 6f  ture. If an erro
2df0: 72 20 6f 63 63 75 72 73 2c 20 64 65 6c 65 74 65  r occurs, delete
2e00: 20 74 68 65 20 73 71 6c 69 74 65 33 5f 76 74 61   the sqlite3_vta
2e10: 62 20 73 74 72 75 63 74 75 72 65 20 61 6e 64 0a  b structure and.
2e20: 20 20 2a 2a 20 72 65 74 75 72 6e 20 61 6e 20 65    ** return an e
2e30: 72 72 6f 72 20 63 6f 64 65 2e 0a 20 20 2a 2f 0a  rror code..  */.
2e40: 20 20 72 63 20 3d 20 65 63 68 6f 44 65 63 6c 61    rc = echoDecla
2e50: 72 65 56 74 61 62 28 70 56 74 61 62 2c 20 64 62  reVtab(pVtab, db
2e60: 29 3b 0a 20 20 69 66 28 20 72 63 21 3d 53 51 4c  );.  if( rc!=SQL
2e70: 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 65 63  ITE_OK ){.    ec
2e80: 68 6f 44 65 73 74 72 75 63 74 6f 72 28 28 73 71  hoDestructor((sq
2e90: 6c 69 74 65 33 5f 76 74 61 62 20 2a 29 70 56 74  lite3_vtab *)pVt
2ea0: 61 62 29 3b 0a 20 20 20 20 72 65 74 75 72 6e 20  ab);.    return 
2eb0: 72 63 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 53 75  rc;.  }..  /* Su
2ec0: 63 63 65 73 73 2e 20 53 65 74 20 2a 70 70 56 74  ccess. Set *ppVt
2ed0: 61 62 20 61 6e 64 20 72 65 74 75 72 6e 20 2a 2f  ab and return */
2ee0: 0a 20 20 2a 70 70 56 74 61 62 20 3d 20 26 70 56  .  *ppVtab = &pV
2ef0: 74 61 62 2d 3e 62 61 73 65 3b 0a 20 20 72 65 74  tab->base;.  ret
2f00: 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d  urn SQLITE_OK;.}
2f10: 0a 0a 2f 2a 20 0a 2a 2a 20 45 63 68 6f 20 76 69  ../* .** Echo vi
2f20: 72 74 75 61 6c 20 74 61 62 6c 65 20 6d 6f 64 75  rtual table modu
2f30: 6c 65 20 78 43 72 65 61 74 65 20 6d 65 74 68 6f  le xCreate metho
2f40: 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  d..*/.static int
2f50: 20 65 63 68 6f 43 72 65 61 74 65 28 0a 20 20 73   echoCreate(.  s
2f60: 71 6c 69 74 65 33 20 2a 64 62 2c 0a 20 20 76 6f  qlite3 *db,.  vo
2f70: 69 64 20 2a 70 41 75 78 2c 0a 20 20 69 6e 74 20  id *pAux,.  int 
2f80: 61 72 67 63 2c 20 63 6f 6e 73 74 20 63 68 61 72  argc, const char
2f90: 20 2a 63 6f 6e 73 74 2a 61 72 67 76 2c 0a 20 20   *const*argv,.  
2fa0: 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 2a 70  sqlite3_vtab **p
2fb0: 70 56 74 61 62 2c 0a 20 20 63 68 61 72 20 2a 2a  pVtab,.  char **
2fc0: 70 7a 45 72 72 0a 29 7b 0a 20 20 69 6e 74 20 72  pzErr.){.  int r
2fd0: 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20  c = SQLITE_OK;. 
2fe0: 20 61 70 70 65 6e 64 54 6f 45 63 68 6f 4d 6f 64   appendToEchoMod
2ff0: 75 6c 65 28 28 28 45 63 68 6f 4d 6f 64 75 6c 65  ule(((EchoModule
3000: 20 2a 29 70 41 75 78 29 2d 3e 69 6e 74 65 72 70   *)pAux)->interp
3010: 2c 20 22 78 43 72 65 61 74 65 22 29 3b 0a 20 20  , "xCreate");.  
3020: 72 63 20 3d 20 65 63 68 6f 43 6f 6e 73 74 72 75  rc = echoConstru
3030: 63 74 6f 72 28 64 62 2c 20 70 41 75 78 2c 20 61  ctor(db, pAux, a
3040: 72 67 63 2c 20 61 72 67 76 2c 20 70 70 56 74 61  rgc, argv, ppVta
3050: 62 2c 20 70 7a 45 72 72 29 3b 0a 0a 20 20 2f 2a  b, pzErr);..  /*
3060: 20 49 66 20 74 68 65 72 65 20 77 65 72 65 20 74   If there were t
3070: 77 6f 20 61 72 67 75 6d 65 6e 74 73 20 70 61 73  wo arguments pas
3080: 73 65 64 20 74 6f 20 74 68 65 20 6d 6f 64 75 6c  sed to the modul
3090: 65 20 61 74 20 74 68 65 20 53 51 4c 20 6c 65 76  e at the SQL lev
30a0: 65 6c 20 0a 20 20 2a 2a 20 28 69 2e 65 2e 20 22  el .  ** (i.e. "
30b0: 43 52 45 41 54 45 20 56 49 52 54 55 41 4c 20 54  CREATE VIRTUAL T
30c0: 41 42 4c 45 20 74 62 6c 20 55 53 49 4e 47 20 65  ABLE tbl USING e
30d0: 63 68 6f 28 61 72 67 31 2c 20 61 72 67 32 29 22  cho(arg1, arg2)"
30e0: 29 2c 20 74 68 65 6e 20 0a 20 20 2a 2a 20 74 68  ), then .  ** th
30f0: 65 20 73 65 63 6f 6e 64 20 61 72 67 75 6d 65 6e  e second argumen
3100: 74 20 69 73 20 75 73 65 64 20 61 73 20 61 20 74  t is used as a t
3110: 61 62 6c 65 20 6e 61 6d 65 2e 20 41 74 74 65 6d  able name. Attem
3120: 70 74 20 74 6f 20 63 72 65 61 74 65 0a 20 20 2a  pt to create.  *
3130: 2a 20 73 75 63 68 20 61 20 74 61 62 6c 65 20 77  * such a table w
3140: 69 74 68 20 61 20 73 69 6e 67 6c 65 20 63 6f 6c  ith a single col
3150: 75 6d 6e 2c 20 22 6c 6f 67 6d 73 67 22 2e 20 54  umn, "logmsg". T
3160: 68 69 73 20 74 61 62 6c 65 20 77 69 6c 6c 0a 20  his table will. 
3170: 20 2a 2a 20 62 65 20 75 73 65 64 20 74 6f 20 6c   ** be used to l
3180: 6f 67 20 63 61 6c 6c 73 20 74 6f 20 74 68 65 20  og calls to the 
3190: 78 55 70 64 61 74 65 20 6d 65 74 68 6f 64 2e 20  xUpdate method. 
31a0: 49 74 20 77 69 6c 6c 20 62 65 20 64 65 6c 65 74  It will be delet
31b0: 65 64 0a 20 20 2a 2a 20 77 68 65 6e 20 74 68 65  ed.  ** when the
31c0: 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65 20 69   virtual table i
31d0: 73 20 44 52 4f 50 65 64 2e 0a 20 20 2a 2a 0a 20  s DROPed..  **. 
31e0: 20 2a 2a 20 4e 6f 74 65 3a 20 54 68 65 20 6d 61   ** Note: The ma
31f0: 69 6e 20 70 6f 69 6e 74 20 6f 66 20 74 68 69 73  in point of this
3200: 20 69 73 20 74 6f 20 74 65 73 74 20 74 68 61 74   is to test that
3210: 20 77 65 20 63 61 6e 20 64 72 6f 70 20 74 61 62   we can drop tab
3220: 6c 65 73 0a 20 20 2a 2a 20 66 72 6f 6d 20 77 69  les.  ** from wi
3230: 74 68 69 6e 20 61 6e 20 78 44 65 73 74 72 6f 79  thin an xDestroy
3240: 20 6d 65 74 68 6f 64 20 63 61 6c 6c 2e 0a 20 20   method call..  
3250: 2a 2f 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c  */.  if( rc==SQL
3260: 49 54 45 5f 4f 4b 20 26 26 20 61 72 67 63 3d 3d  ITE_OK && argc==
3270: 35 20 29 7b 0a 20 20 20 20 63 68 61 72 20 2a 7a  5 ){.    char *z
3280: 53 71 6c 3b 0a 20 20 20 20 65 63 68 6f 5f 76 74  Sql;.    echo_vt
3290: 61 62 20 2a 70 56 74 61 62 20 3d 20 2a 28 65 63  ab *pVtab = *(ec
32a0: 68 6f 5f 76 74 61 62 20 2a 2a 29 70 70 56 74 61  ho_vtab **)ppVta
32b0: 62 3b 0a 20 20 20 20 70 56 74 61 62 2d 3e 7a 4c  b;.    pVtab->zL
32c0: 6f 67 4e 61 6d 65 20 3d 20 73 71 6c 69 74 65 33  ogName = sqlite3
32d0: 4d 50 72 69 6e 74 66 28 30 2c 20 22 25 73 22 2c  MPrintf(0, "%s",
32e0: 20 61 72 67 76 5b 34 5d 29 3b 0a 20 20 20 20 7a   argv[4]);.    z
32f0: 53 71 6c 20 3d 20 73 71 6c 69 74 65 33 4d 50 72  Sql = sqlite3MPr
3300: 69 6e 74 66 28 30 2c 20 22 43 52 45 41 54 45 20  intf(0, "CREATE 
3310: 54 41 42 4c 45 20 25 51 28 6c 6f 67 6d 73 67 29  TABLE %Q(logmsg)
3320: 22 2c 20 70 56 74 61 62 2d 3e 7a 4c 6f 67 4e 61  ", pVtab->zLogNa
3330: 6d 65 29 3b 0a 20 20 20 20 72 63 20 3d 20 73 71  me);.    rc = sq
3340: 6c 69 74 65 33 5f 65 78 65 63 28 64 62 2c 20 7a  lite3_exec(db, z
3350: 53 71 6c 2c 20 30 2c 20 30 2c 20 30 29 3b 0a 20  Sql, 0, 0, 0);. 
3360: 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28     sqlite3_free(
3370: 7a 53 71 6c 29 3b 0a 20 20 20 20 69 66 28 20 72  zSql);.    if( r
3380: 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a  c!=SQLITE_OK ){.
3390: 20 20 20 20 20 20 2a 70 7a 45 72 72 20 3d 20 73        *pzErr = s
33a0: 71 6c 69 74 65 33 53 74 72 44 75 70 28 73 71 6c  qlite3StrDup(sql
33b0: 69 74 65 33 5f 65 72 72 6d 73 67 28 64 62 29 29  ite3_errmsg(db))
33c0: 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 69  ;.    }.  }..  i
33d0: 66 28 20 2a 70 70 56 74 61 62 20 26 26 20 72 63  f( *ppVtab && rc
33e0: 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  !=SQLITE_OK ){. 
33f0: 20 20 20 65 63 68 6f 44 65 73 74 72 75 63 74 6f     echoDestructo
3400: 72 28 2a 70 70 56 74 61 62 29 3b 0a 20 20 20 20  r(*ppVtab);.    
3410: 2a 70 70 56 74 61 62 20 3d 20 30 3b 0a 20 20 7d  *ppVtab = 0;.  }
3420: 0a 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49  ..  if( rc==SQLI
3430: 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 28 2a 28  TE_OK ){.    (*(
3440: 65 63 68 6f 5f 76 74 61 62 2a 2a 29 70 70 56 74  echo_vtab**)ppVt
3450: 61 62 29 2d 3e 69 6e 54 72 61 6e 73 61 63 74 69  ab)->inTransacti
3460: 6f 6e 20 3d 20 31 3b 0a 20 20 7d 0a 0a 20 20 72  on = 1;.  }..  r
3470: 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 20  eturn rc;.}../* 
3480: 0a 2a 2a 20 45 63 68 6f 20 76 69 72 74 75 61 6c  .** Echo virtual
3490: 20 74 61 62 6c 65 20 6d 6f 64 75 6c 65 20 78 43   table module xC
34a0: 6f 6e 6e 65 63 74 20 6d 65 74 68 6f 64 2e 0a 2a  onnect method..*
34b0: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 65 63 68  /.static int ech
34c0: 6f 43 6f 6e 6e 65 63 74 28 0a 20 20 73 71 6c 69  oConnect(.  sqli
34d0: 74 65 33 20 2a 64 62 2c 0a 20 20 76 6f 69 64 20  te3 *db,.  void 
34e0: 2a 70 41 75 78 2c 0a 20 20 69 6e 74 20 61 72 67  *pAux,.  int arg
34f0: 63 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 63  c, const char *c
3500: 6f 6e 73 74 2a 61 72 67 76 2c 0a 20 20 73 71 6c  onst*argv,.  sql
3510: 69 74 65 33 5f 76 74 61 62 20 2a 2a 70 70 56 74  ite3_vtab **ppVt
3520: 61 62 2c 0a 20 20 63 68 61 72 20 2a 2a 70 7a 45  ab,.  char **pzE
3530: 72 72 0a 29 7b 0a 20 20 61 70 70 65 6e 64 54 6f  rr.){.  appendTo
3540: 45 63 68 6f 4d 6f 64 75 6c 65 28 28 28 45 63 68  EchoModule(((Ech
3550: 6f 4d 6f 64 75 6c 65 20 2a 29 70 41 75 78 29 2d  oModule *)pAux)-
3560: 3e 69 6e 74 65 72 70 2c 20 22 78 43 6f 6e 6e 65  >interp, "xConne
3570: 63 74 22 29 3b 0a 20 20 72 65 74 75 72 6e 20 65  ct");.  return e
3580: 63 68 6f 43 6f 6e 73 74 72 75 63 74 6f 72 28 64  choConstructor(d
3590: 62 2c 20 70 41 75 78 2c 20 61 72 67 63 2c 20 61  b, pAux, argc, a
35a0: 72 67 76 2c 20 70 70 56 74 61 62 2c 20 70 7a 45  rgv, ppVtab, pzE
35b0: 72 72 29 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 45  rr);.}../* .** E
35c0: 63 68 6f 20 76 69 72 74 75 61 6c 20 74 61 62 6c  cho virtual tabl
35d0: 65 20 6d 6f 64 75 6c 65 20 78 44 69 73 63 6f 6e  e module xDiscon
35e0: 6e 65 63 74 20 6d 65 74 68 6f 64 2e 0a 2a 2f 0a  nect method..*/.
35f0: 73 74 61 74 69 63 20 69 6e 74 20 65 63 68 6f 44  static int echoD
3600: 69 73 63 6f 6e 6e 65 63 74 28 73 71 6c 69 74 65  isconnect(sqlite
3610: 33 5f 76 74 61 62 20 2a 70 56 74 61 62 29 7b 0a  3_vtab *pVtab){.
3620: 20 20 61 70 70 65 6e 64 54 6f 45 63 68 6f 4d 6f    appendToEchoMo
3630: 64 75 6c 65 28 28 28 65 63 68 6f 5f 76 74 61 62  dule(((echo_vtab
3640: 20 2a 29 70 56 74 61 62 29 2d 3e 69 6e 74 65 72   *)pVtab)->inter
3650: 70 2c 20 22 78 44 69 73 63 6f 6e 6e 65 63 74 22  p, "xDisconnect"
3660: 29 3b 0a 20 20 72 65 74 75 72 6e 20 65 63 68 6f  );.  return echo
3670: 44 65 73 74 72 75 63 74 6f 72 28 70 56 74 61 62  Destructor(pVtab
3680: 29 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 45 63 68  );.}../* .** Ech
3690: 6f 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65 20  o virtual table 
36a0: 6d 6f 64 75 6c 65 20 78 44 65 73 74 72 6f 79 20  module xDestroy 
36b0: 6d 65 74 68 6f 64 2e 0a 2a 2f 0a 73 74 61 74 69  method..*/.stati
36c0: 63 20 69 6e 74 20 65 63 68 6f 44 65 73 74 72 6f  c int echoDestro
36d0: 79 28 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a  y(sqlite3_vtab *
36e0: 70 56 74 61 62 29 7b 0a 20 20 69 6e 74 20 72 63  pVtab){.  int rc
36f0: 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20   = SQLITE_OK;.  
3700: 65 63 68 6f 5f 76 74 61 62 20 2a 70 20 3d 20 28  echo_vtab *p = (
3710: 65 63 68 6f 5f 76 74 61 62 20 2a 29 70 56 74 61  echo_vtab *)pVta
3720: 62 3b 0a 20 20 61 70 70 65 6e 64 54 6f 45 63 68  b;.  appendToEch
3730: 6f 4d 6f 64 75 6c 65 28 28 28 65 63 68 6f 5f 76  oModule(((echo_v
3740: 74 61 62 20 2a 29 70 56 74 61 62 29 2d 3e 69 6e  tab *)pVtab)->in
3750: 74 65 72 70 2c 20 22 78 44 65 73 74 72 6f 79 22  terp, "xDestroy"
3760: 29 3b 0a 0a 20 20 2f 2a 20 44 72 6f 70 20 74 68  );..  /* Drop th
3770: 65 20 22 6c 6f 67 22 20 74 61 62 6c 65 2c 20 69  e "log" table, i
3780: 66 20 6f 6e 65 20 65 78 69 73 74 73 20 28 73 65  f one exists (se
3790: 65 20 65 63 68 6f 43 72 65 61 74 65 28 29 20 66  e echoCreate() f
37a0: 6f 72 20 64 65 74 61 69 6c 73 29 20 2a 2f 0a 20  or details) */. 
37b0: 20 69 66 28 20 70 20 26 26 20 70 2d 3e 7a 4c 6f   if( p && p->zLo
37c0: 67 4e 61 6d 65 20 29 7b 0a 20 20 20 20 63 68 61  gName ){.    cha
37d0: 72 20 2a 7a 53 71 6c 3b 0a 20 20 20 20 7a 53 71  r *zSql;.    zSq
37e0: 6c 20 3d 20 73 71 6c 69 74 65 33 4d 50 72 69 6e  l = sqlite3MPrin
37f0: 74 66 28 30 2c 20 22 44 52 4f 50 20 54 41 42 4c  tf(0, "DROP TABL
3800: 45 20 25 51 22 2c 20 70 2d 3e 7a 4c 6f 67 4e 61  E %Q", p->zLogNa
3810: 6d 65 29 3b 0a 20 20 20 20 72 63 20 3d 20 73 71  me);.    rc = sq
3820: 6c 69 74 65 33 5f 65 78 65 63 28 70 2d 3e 64 62  lite3_exec(p->db
3830: 2c 20 7a 53 71 6c 2c 20 30 2c 20 30 2c 20 30 29  , zSql, 0, 0, 0)
3840: 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72  ;.    sqlite3_fr
3850: 65 65 28 7a 53 71 6c 29 3b 0a 20 20 7d 0a 0a 20  ee(zSql);.  }.. 
3860: 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
3870: 4f 4b 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 65  OK ){.    rc = e
3880: 63 68 6f 44 65 73 74 72 75 63 74 6f 72 28 70 56  choDestructor(pV
3890: 74 61 62 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75  tab);.  }.  retu
38a0: 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a  rn rc;.}../* .**
38b0: 20 45 63 68 6f 20 76 69 72 74 75 61 6c 20 74 61   Echo virtual ta
38c0: 62 6c 65 20 6d 6f 64 75 6c 65 20 78 4f 70 65 6e  ble module xOpen
38d0: 20 6d 65 74 68 6f 64 2e 0a 2a 2f 0a 73 74 61 74   method..*/.stat
38e0: 69 63 20 69 6e 74 20 65 63 68 6f 4f 70 65 6e 28  ic int echoOpen(
38f0: 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 70 56  sqlite3_vtab *pV
3900: 54 61 62 2c 20 73 71 6c 69 74 65 33 5f 76 74 61  Tab, sqlite3_vta
3910: 62 5f 63 75 72 73 6f 72 20 2a 2a 70 70 43 75 72  b_cursor **ppCur
3920: 73 6f 72 29 7b 0a 20 20 65 63 68 6f 5f 63 75 72  sor){.  echo_cur
3930: 73 6f 72 20 2a 70 43 75 72 3b 0a 20 20 70 43 75  sor *pCur;.  pCu
3940: 72 20 3d 20 73 71 6c 69 74 65 33 4d 61 6c 6c 6f  r = sqlite3Mallo
3950: 63 5a 65 72 6f 28 73 69 7a 65 6f 66 28 65 63 68  cZero(sizeof(ech
3960: 6f 5f 63 75 72 73 6f 72 29 29 3b 0a 20 20 2a 70  o_cursor));.  *p
3970: 70 43 75 72 73 6f 72 20 3d 20 28 73 71 6c 69 74  pCursor = (sqlit
3980: 65 33 5f 76 74 61 62 5f 63 75 72 73 6f 72 20 2a  e3_vtab_cursor *
3990: 29 70 43 75 72 3b 0a 20 20 72 65 74 75 72 6e 20  )pCur;.  return 
39a0: 28 70 43 75 72 20 3f 20 53 51 4c 49 54 45 5f 4f  (pCur ? SQLITE_O
39b0: 4b 20 3a 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d  K : SQLITE_NOMEM
39c0: 29 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 45 63 68  );.}../* .** Ech
39d0: 6f 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65 20  o virtual table 
39e0: 6d 6f 64 75 6c 65 20 78 43 6c 6f 73 65 20 6d 65  module xClose me
39f0: 74 68 6f 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  thod..*/.static 
3a00: 69 6e 74 20 65 63 68 6f 43 6c 6f 73 65 28 73 71  int echoClose(sq
3a10: 6c 69 74 65 33 5f 76 74 61 62 5f 63 75 72 73 6f  lite3_vtab_curso
3a20: 72 20 2a 63 75 72 29 7b 0a 20 20 69 6e 74 20 72  r *cur){.  int r
3a30: 63 3b 0a 20 20 65 63 68 6f 5f 63 75 72 73 6f 72  c;.  echo_cursor
3a40: 20 2a 70 43 75 72 20 3d 20 28 65 63 68 6f 5f 63   *pCur = (echo_c
3a50: 75 72 73 6f 72 20 2a 29 63 75 72 3b 0a 20 20 73  ursor *)cur;.  s
3a60: 71 6c 69 74 65 33 5f 73 74 6d 74 20 2a 70 53 74  qlite3_stmt *pSt
3a70: 6d 74 20 3d 20 70 43 75 72 2d 3e 70 53 74 6d 74  mt = pCur->pStmt
3a80: 3b 0a 20 20 70 43 75 72 2d 3e 70 53 74 6d 74 20  ;.  pCur->pStmt 
3a90: 3d 20 30 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66  = 0;.  sqlite3_f
3aa0: 72 65 65 28 70 43 75 72 29 3b 0a 20 20 72 63 20  ree(pCur);.  rc 
3ab0: 3d 20 73 71 6c 69 74 65 33 5f 66 69 6e 61 6c 69  = sqlite3_finali
3ac0: 7a 65 28 70 53 74 6d 74 29 3b 0a 20 20 72 65 74  ze(pStmt);.  ret
3ad0: 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  urn rc;.}../*.**
3ae0: 20 52 65 74 75 72 6e 20 6e 6f 6e 2d 7a 65 72 6f   Return non-zero
3af0: 20 69 66 20 74 68 65 20 63 75 72 73 6f 72 20 64   if the cursor d
3b00: 6f 65 73 20 6e 6f 74 20 63 75 72 72 65 6e 74 6c  oes not currentl
3b10: 79 20 70 6f 69 6e 74 20 74 6f 20 61 20 76 61 6c  y point to a val
3b20: 69 64 20 72 65 63 6f 72 64 0a 2a 2a 20 28 69 2e  id record.** (i.
3b30: 65 20 69 66 20 74 68 65 20 73 63 61 6e 20 68 61  e if the scan ha
3b40: 73 20 66 69 6e 69 73 68 65 64 29 2c 20 6f 72 20  s finished), or 
3b50: 7a 65 72 6f 20 6f 74 68 65 72 77 69 73 65 2e 0a  zero otherwise..
3b60: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 65 63  */.static int ec
3b70: 68 6f 45 6f 66 28 73 71 6c 69 74 65 33 5f 76 74  hoEof(sqlite3_vt
3b80: 61 62 5f 63 75 72 73 6f 72 20 2a 63 75 72 29 7b  ab_cursor *cur){
3b90: 0a 20 20 72 65 74 75 72 6e 20 28 28 28 65 63 68  .  return (((ech
3ba0: 6f 5f 63 75 72 73 6f 72 20 2a 29 63 75 72 29 2d  o_cursor *)cur)-
3bb0: 3e 70 53 74 6d 74 20 3f 20 30 20 3a 20 31 29 3b  >pStmt ? 0 : 1);
3bc0: 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 45 63 68 6f 20  .}../* .** Echo 
3bd0: 76 69 72 74 75 61 6c 20 74 61 62 6c 65 20 6d 6f  virtual table mo
3be0: 64 75 6c 65 20 78 4e 65 78 74 20 6d 65 74 68 6f  dule xNext metho
3bf0: 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  d..*/.static int
3c00: 20 65 63 68 6f 4e 65 78 74 28 73 71 6c 69 74 65   echoNext(sqlite
3c10: 33 5f 76 74 61 62 5f 63 75 72 73 6f 72 20 2a 63  3_vtab_cursor *c
3c20: 75 72 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20  ur){.  int rc = 
3c30: 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 65 63 68  SQLITE_OK;.  ech
3c40: 6f 5f 63 75 72 73 6f 72 20 2a 70 43 75 72 20 3d  o_cursor *pCur =
3c50: 20 28 65 63 68 6f 5f 63 75 72 73 6f 72 20 2a 29   (echo_cursor *)
3c60: 63 75 72 3b 0a 0a 20 20 69 66 28 20 70 43 75 72  cur;..  if( pCur
3c70: 2d 3e 70 53 74 6d 74 20 29 7b 0a 20 20 20 20 72  ->pStmt ){.    r
3c80: 63 20 3d 20 73 71 6c 69 74 65 33 5f 73 74 65 70  c = sqlite3_step
3c90: 28 70 43 75 72 2d 3e 70 53 74 6d 74 29 3b 0a 20  (pCur->pStmt);. 
3ca0: 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54     if( rc==SQLIT
3cb0: 45 5f 52 4f 57 20 29 7b 0a 20 20 20 20 20 20 72  E_ROW ){.      r
3cc0: 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20  c = SQLITE_OK;. 
3cd0: 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20     }else{.      
3ce0: 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 66 69 6e  rc = sqlite3_fin
3cf0: 61 6c 69 7a 65 28 70 43 75 72 2d 3e 70 53 74 6d  alize(pCur->pStm
3d00: 74 29 3b 0a 20 20 20 20 20 20 70 43 75 72 2d 3e  t);.      pCur->
3d10: 70 53 74 6d 74 20 3d 20 30 3b 0a 20 20 20 20 7d  pStmt = 0;.    }
3d20: 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 72  .  }..  return r
3d30: 63 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 45 63 68  c;.}../* .** Ech
3d40: 6f 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65 20  o virtual table 
3d50: 6d 6f 64 75 6c 65 20 78 43 6f 6c 75 6d 6e 20 6d  module xColumn m
3d60: 65 74 68 6f 64 2e 0a 2a 2f 0a 73 74 61 74 69 63  ethod..*/.static
3d70: 20 69 6e 74 20 65 63 68 6f 43 6f 6c 75 6d 6e 28   int echoColumn(
3d80: 73 71 6c 69 74 65 33 5f 76 74 61 62 5f 63 75 72  sqlite3_vtab_cur
3d90: 73 6f 72 20 2a 63 75 72 2c 20 73 71 6c 69 74 65  sor *cur, sqlite
3da0: 33 5f 63 6f 6e 74 65 78 74 20 2a 63 74 78 2c 20  3_context *ctx, 
3db0: 69 6e 74 20 69 29 7b 0a 20 20 69 6e 74 20 69 43  int i){.  int iC
3dc0: 6f 6c 20 3d 20 69 20 2b 20 31 3b 0a 20 20 73 71  ol = i + 1;.  sq
3dd0: 6c 69 74 65 33 5f 73 74 6d 74 20 2a 70 53 74 6d  lite3_stmt *pStm
3de0: 74 20 3d 20 28 28 65 63 68 6f 5f 63 75 72 73 6f  t = ((echo_curso
3df0: 72 20 2a 29 63 75 72 29 2d 3e 70 53 74 6d 74 3b  r *)cur)->pStmt;
3e00: 0a 20 20 69 66 28 20 21 70 53 74 6d 74 20 29 7b  .  if( !pStmt ){
3e10: 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 72 65 73  .    sqlite3_res
3e20: 75 6c 74 5f 6e 75 6c 6c 28 63 74 78 29 3b 0a 20  ult_null(ctx);. 
3e30: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 61 73 73 65   }else{.    asse
3e40: 72 74 28 20 73 71 6c 69 74 65 33 5f 64 61 74 61  rt( sqlite3_data
3e50: 5f 63 6f 75 6e 74 28 70 53 74 6d 74 29 3e 69 43  _count(pStmt)>iC
3e60: 6f 6c 20 29 3b 0a 20 20 20 20 73 71 6c 69 74 65  ol );.    sqlite
3e70: 33 5f 72 65 73 75 6c 74 5f 76 61 6c 75 65 28 63  3_result_value(c
3e80: 74 78 2c 20 73 71 6c 69 74 65 33 5f 63 6f 6c 75  tx, sqlite3_colu
3e90: 6d 6e 5f 76 61 6c 75 65 28 70 53 74 6d 74 2c 20  mn_value(pStmt, 
3ea0: 69 43 6f 6c 29 29 3b 0a 20 20 7d 0a 20 20 72 65  iCol));.  }.  re
3eb0: 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a  turn SQLITE_OK;.
3ec0: 7d 0a 0a 2f 2a 20 0a 2a 2a 20 45 63 68 6f 20 76  }../* .** Echo v
3ed0: 69 72 74 75 61 6c 20 74 61 62 6c 65 20 6d 6f 64  irtual table mod
3ee0: 75 6c 65 20 78 52 6f 77 69 64 20 6d 65 74 68 6f  ule xRowid metho
3ef0: 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  d..*/.static int
3f00: 20 65 63 68 6f 52 6f 77 69 64 28 73 71 6c 69 74   echoRowid(sqlit
3f10: 65 33 5f 76 74 61 62 5f 63 75 72 73 6f 72 20 2a  e3_vtab_cursor *
3f20: 63 75 72 2c 20 73 71 6c 69 74 65 5f 69 6e 74 36  cur, sqlite_int6
3f30: 34 20 2a 70 52 6f 77 69 64 29 7b 0a 20 20 73 71  4 *pRowid){.  sq
3f40: 6c 69 74 65 33 5f 73 74 6d 74 20 2a 70 53 74 6d  lite3_stmt *pStm
3f50: 74 20 3d 20 28 28 65 63 68 6f 5f 63 75 72 73 6f  t = ((echo_curso
3f60: 72 20 2a 29 63 75 72 29 2d 3e 70 53 74 6d 74 3b  r *)cur)->pStmt;
3f70: 0a 20 20 2a 70 52 6f 77 69 64 20 3d 20 73 71 6c  .  *pRowid = sql
3f80: 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 69 6e 74 36  ite3_column_int6
3f90: 34 28 70 53 74 6d 74 2c 20 30 29 3b 0a 20 20 72  4(pStmt, 0);.  r
3fa0: 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b  eturn SQLITE_OK;
3fb0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 6f 6d 70 75 74  .}../*.** Comput
3fc0: 65 20 61 20 73 69 6d 70 6c 65 20 68 61 73 68 20  e a simple hash 
3fd0: 6f 66 20 74 68 65 20 6e 75 6c 6c 20 74 65 72 6d  of the null term
3fe0: 69 6e 61 74 65 64 20 73 74 72 69 6e 67 20 7a 53  inated string zS
3ff0: 74 72 69 6e 67 2e 0a 2a 2a 0a 2a 2a 20 54 68 69  tring..**.** Thi
4000: 73 20 6d 6f 64 75 6c 65 20 75 73 65 73 20 6f 6e  s module uses on
4010: 6c 79 20 73 71 6c 69 74 65 33 5f 69 6e 64 65 78  ly sqlite3_index
4020: 5f 69 6e 66 6f 2e 69 64 78 53 74 72 2c 20 6e 6f  _info.idxStr, no
4030: 74 20 0a 2a 2a 20 73 71 6c 69 74 65 33 5f 69 6e  t .** sqlite3_in
4040: 64 65 78 5f 69 6e 66 6f 2e 69 64 78 4e 75 6d 2e  dex_info.idxNum.
4050: 20 53 6f 20 74 6f 20 74 65 73 74 20 69 64 78 4e   So to test idxN
4060: 75 6d 2c 20 77 68 65 6e 20 69 64 78 53 74 72 20  um, when idxStr 
4070: 69 73 20 73 65 74 0a 2a 2a 20 69 6e 20 65 63 68  is set.** in ech
4080: 6f 42 65 73 74 49 6e 64 65 78 28 29 2c 20 69 64  oBestIndex(), id
4090: 78 4e 75 6d 20 69 73 20 73 65 74 20 74 6f 20 74  xNum is set to t
40a0: 68 65 20 63 6f 72 72 65 73 70 6f 6e 64 69 6e 67  he corresponding
40b0: 20 68 61 73 68 20 76 61 6c 75 65 2e 0a 2a 2a 20   hash value..** 
40c0: 49 6e 20 65 63 68 6f 46 69 6c 74 65 72 28 29 2c  In echoFilter(),
40d0: 20 63 6f 64 65 20 61 73 73 65 72 74 28 29 73 20   code assert()s 
40e0: 74 68 61 74 20 74 68 65 20 73 75 70 70 6c 69 65  that the supplie
40f0: 64 20 69 64 78 4e 75 6d 20 76 61 6c 75 65 20 69  d idxNum value i
4100: 73 0a 2a 2a 20 69 6e 64 65 65 64 20 74 68 65 20  s.** indeed the 
4110: 68 61 73 68 20 6f 66 20 74 68 65 20 73 75 70 70  hash of the supp
4120: 6c 69 65 64 20 69 64 78 53 74 72 2e 0a 2a 2f 0a  lied idxStr..*/.
4130: 73 74 61 74 69 63 20 69 6e 74 20 68 61 73 68 53  static int hashS
4140: 74 72 69 6e 67 28 63 6f 6e 73 74 20 63 68 61 72  tring(const char
4150: 20 2a 7a 53 74 72 69 6e 67 29 7b 0a 20 20 69 6e   *zString){.  in
4160: 74 20 76 61 6c 20 3d 20 30 3b 0a 20 20 69 6e 74  t val = 0;.  int
4170: 20 69 69 3b 0a 20 20 66 6f 72 28 69 69 3d 30 3b   ii;.  for(ii=0;
4180: 20 7a 53 74 72 69 6e 67 5b 69 69 5d 3b 20 69 69   zString[ii]; ii
4190: 2b 2b 29 7b 0a 20 20 20 20 76 61 6c 20 3d 20 28  ++){.    val = (
41a0: 76 61 6c 20 3c 3c 20 33 29 20 2b 20 28 69 6e 74  val << 3) + (int
41b0: 29 7a 53 74 72 69 6e 67 5b 69 69 5d 3b 0a 20 20  )zString[ii];.  
41c0: 7d 0a 20 20 72 65 74 75 72 6e 20 76 61 6c 3b 0a  }.  return val;.
41d0: 7d 0a 0a 2f 2a 20 0a 2a 2a 20 45 63 68 6f 20 76  }../* .** Echo v
41e0: 69 72 74 75 61 6c 20 74 61 62 6c 65 20 6d 6f 64  irtual table mod
41f0: 75 6c 65 20 78 46 69 6c 74 65 72 20 6d 65 74 68  ule xFilter meth
4200: 6f 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  od..*/.static in
4210: 74 20 65 63 68 6f 46 69 6c 74 65 72 28 0a 20 20  t echoFilter(.  
4220: 73 71 6c 69 74 65 33 5f 76 74 61 62 5f 63 75 72  sqlite3_vtab_cur
4230: 73 6f 72 20 2a 70 56 74 61 62 43 75 72 73 6f 72  sor *pVtabCursor
4240: 2c 20 0a 20 20 69 6e 74 20 69 64 78 4e 75 6d 2c  , .  int idxNum,
4250: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 69 64 78   const char *idx
4260: 53 74 72 2c 0a 20 20 69 6e 74 20 61 72 67 63 2c  Str,.  int argc,
4270: 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 20 2a   sqlite3_value *
4280: 2a 61 72 67 76 0a 29 7b 0a 20 20 69 6e 74 20 72  *argv.){.  int r
4290: 63 3b 0a 20 20 69 6e 74 20 69 3b 0a 0a 20 20 65  c;.  int i;..  e
42a0: 63 68 6f 5f 63 75 72 73 6f 72 20 2a 70 43 75 72  cho_cursor *pCur
42b0: 20 3d 20 28 65 63 68 6f 5f 63 75 72 73 6f 72 20   = (echo_cursor 
42c0: 2a 29 70 56 74 61 62 43 75 72 73 6f 72 3b 0a 20  *)pVtabCursor;. 
42d0: 20 65 63 68 6f 5f 76 74 61 62 20 2a 70 56 74 61   echo_vtab *pVta
42e0: 62 20 3d 20 28 65 63 68 6f 5f 76 74 61 62 20 2a  b = (echo_vtab *
42f0: 29 70 56 74 61 62 43 75 72 73 6f 72 2d 3e 70 56  )pVtabCursor->pV
4300: 74 61 62 3b 0a 20 20 73 71 6c 69 74 65 33 20 2a  tab;.  sqlite3 *
4310: 64 62 20 3d 20 70 56 74 61 62 2d 3e 64 62 3b 0a  db = pVtab->db;.
4320: 0a 20 20 2f 2a 20 43 68 65 63 6b 20 74 68 61 74  .  /* Check that
4330: 20 69 64 78 4e 75 6d 20 6d 61 74 63 68 65 73 20   idxNum matches 
4340: 69 64 78 53 74 72 20 2a 2f 0a 20 20 61 73 73 65  idxStr */.  asse
4350: 72 74 28 20 69 64 78 4e 75 6d 3d 3d 68 61 73 68  rt( idxNum==hash
4360: 53 74 72 69 6e 67 28 69 64 78 53 74 72 29 20 29  String(idxStr) )
4370: 3b 0a 0a 20 20 2f 2a 20 4c 6f 67 20 61 72 67 75  ;..  /* Log argu
4380: 6d 65 6e 74 73 20 74 6f 20 74 68 65 20 3a 3a 65  ments to the ::e
4390: 63 68 6f 5f 6d 6f 64 75 6c 65 20 54 63 6c 20 76  cho_module Tcl v
43a0: 61 72 69 61 62 6c 65 20 2a 2f 0a 20 20 61 70 70  ariable */.  app
43b0: 65 6e 64 54 6f 45 63 68 6f 4d 6f 64 75 6c 65 28  endToEchoModule(
43c0: 70 56 74 61 62 2d 3e 69 6e 74 65 72 70 2c 20 22  pVtab->interp, "
43d0: 78 46 69 6c 74 65 72 22 29 3b 0a 20 20 61 70 70  xFilter");.  app
43e0: 65 6e 64 54 6f 45 63 68 6f 4d 6f 64 75 6c 65 28  endToEchoModule(
43f0: 70 56 74 61 62 2d 3e 69 6e 74 65 72 70 2c 20 69  pVtab->interp, i
4400: 64 78 53 74 72 29 3b 0a 20 20 66 6f 72 28 69 3d  dxStr);.  for(i=
4410: 30 3b 20 69 3c 61 72 67 63 3b 20 69 2b 2b 29 7b  0; i<argc; i++){
4420: 0a 20 20 20 20 61 70 70 65 6e 64 54 6f 45 63 68  .    appendToEch
4430: 6f 4d 6f 64 75 6c 65 28 70 56 74 61 62 2d 3e 69  oModule(pVtab->i
4440: 6e 74 65 72 70 2c 20 28 63 6f 6e 73 74 20 63 68  nterp, (const ch
4450: 61 72 2a 29 73 71 6c 69 74 65 33 5f 76 61 6c 75  ar*)sqlite3_valu
4460: 65 5f 74 65 78 74 28 61 72 67 76 5b 69 5d 29 29  e_text(argv[i]))
4470: 3b 0a 20 20 7d 0a 0a 20 20 73 71 6c 69 74 65 33  ;.  }..  sqlite3
4480: 5f 66 69 6e 61 6c 69 7a 65 28 70 43 75 72 2d 3e  _finalize(pCur->
4490: 70 53 74 6d 74 29 3b 0a 20 20 70 43 75 72 2d 3e  pStmt);.  pCur->
44a0: 70 53 74 6d 74 20 3d 20 30 3b 0a 0a 20 20 2f 2a  pStmt = 0;..  /*
44b0: 20 50 72 65 70 61 72 65 20 74 68 65 20 53 51 4c   Prepare the SQL
44c0: 20 73 74 61 74 65 6d 65 6e 74 20 63 72 65 61 74   statement creat
44d0: 65 64 20 62 79 20 65 63 68 6f 42 65 73 74 49 6e  ed by echoBestIn
44e0: 64 65 78 20 61 6e 64 20 62 69 6e 64 20 74 68 65  dex and bind the
44f0: 0a 20 20 2a 2a 20 72 75 6e 74 69 6d 65 20 70 61  .  ** runtime pa
4500: 72 61 6d 65 74 65 72 73 20 70 61 73 73 65 64 20  rameters passed 
4510: 74 6f 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e  to this function
4520: 20 74 6f 20 69 74 2e 0a 20 20 2a 2f 0a 20 20 72   to it..  */.  r
4530: 63 20 3d 20 73 71 6c 69 74 65 33 5f 70 72 65 70  c = sqlite3_prep
4540: 61 72 65 28 64 62 2c 20 69 64 78 53 74 72 2c 20  are(db, idxStr, 
4550: 2d 31 2c 20 26 70 43 75 72 2d 3e 70 53 74 6d 74  -1, &pCur->pStmt
4560: 2c 20 30 29 3b 0a 20 20 61 73 73 65 72 74 28 20  , 0);.  assert( 
4570: 70 43 75 72 2d 3e 70 53 74 6d 74 20 7c 7c 20 72  pCur->pStmt || r
4580: 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 3b 0a  c!=SQLITE_OK );.
4590: 20 20 66 6f 72 28 69 3d 30 3b 20 72 63 3d 3d 53    for(i=0; rc==S
45a0: 51 4c 49 54 45 5f 4f 4b 20 26 26 20 69 3c 61 72  QLITE_OK && i<ar
45b0: 67 63 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 73 71  gc; i++){.    sq
45c0: 6c 69 74 65 33 5f 62 69 6e 64 5f 76 61 6c 75 65  lite3_bind_value
45d0: 28 70 43 75 72 2d 3e 70 53 74 6d 74 2c 20 69 2b  (pCur->pStmt, i+
45e0: 31 2c 20 61 72 67 76 5b 69 5d 29 3b 0a 20 20 7d  1, argv[i]);.  }
45f0: 0a 0a 20 20 2f 2a 20 49 66 20 65 76 65 72 79 74  ..  /* If everyt
4600: 68 69 6e 67 20 77 61 73 20 73 75 63 63 65 73 73  hing was success
4610: 66 75 6c 2c 20 61 64 76 61 6e 63 65 20 74 6f 20  ful, advance to 
4620: 74 68 65 20 66 69 72 73 74 20 72 6f 77 20 6f 66  the first row of
4630: 20 74 68 65 20 73 63 61 6e 20 2a 2f 0a 20 20 69   the scan */.  i
4640: 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc==SQLITE_OK
4650: 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 65 63 68   ){.    rc = ech
4660: 6f 4e 65 78 74 28 70 56 74 61 62 43 75 72 73 6f  oNext(pVtabCurso
4670: 72 29 3b 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72  r);.  }..  retur
4680: 6e 20 72 63 3b 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20  n rc;.}.../*.** 
4690: 41 20 68 65 6c 70 65 72 20 66 75 6e 63 74 69 6f  A helper functio
46a0: 6e 20 75 73 65 64 20 62 79 20 65 63 68 6f 55 70  n used by echoUp
46b0: 64 61 74 65 28 29 20 61 6e 64 20 65 63 68 6f 42  date() and echoB
46c0: 65 73 74 49 6e 64 65 78 28 29 20 66 6f 72 0a 2a  estIndex() for.*
46d0: 2a 20 6d 61 6e 69 70 75 6c 61 74 69 6e 67 20 73  * manipulating s
46e0: 74 72 69 6e 67 73 20 69 6e 20 63 6f 6e 63 65 72  trings in concer
46f0: 74 20 77 69 74 68 20 74 68 65 20 73 71 6c 69 74  t with the sqlit
4700: 65 33 5f 6d 70 72 69 6e 74 66 28 29 20 66 75 6e  e3_mprintf() fun
4710: 63 74 69 6f 6e 2e 0a 2a 2a 0a 2a 2a 20 50 61 72  ction..**.** Par
4720: 61 6d 65 74 65 72 20 70 7a 53 74 72 20 70 6f 69  ameter pzStr poi
4730: 6e 74 73 20 74 6f 20 61 20 70 6f 69 6e 74 65 72  nts to a pointer
4740: 20 74 6f 20 61 20 73 74 72 69 6e 67 20 61 6c 6c   to a string all
4750: 6f 63 61 74 65 64 20 77 69 74 68 0a 2a 2a 20 73  ocated with.** s
4760: 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 2e 20  qlite3_mprintf. 
4770: 54 68 65 20 73 65 63 6f 6e 64 20 70 61 72 61 6d  The second param
4780: 65 74 65 72 2c 20 7a 41 70 70 65 6e 64 2c 20 70  eter, zAppend, p
4790: 6f 69 6e 74 73 20 74 6f 20 61 6e 6f 74 68 65 72  oints to another
47a0: 0a 2a 2a 20 73 74 72 69 6e 67 2e 20 54 68 65 20  .** string. The 
47b0: 74 77 6f 20 73 74 72 69 6e 67 73 20 61 72 65 20  two strings are 
47c0: 63 6f 6e 63 61 74 65 6e 61 74 65 64 20 74 6f 67  concatenated tog
47d0: 65 74 68 65 72 20 61 6e 64 20 2a 70 7a 53 74 72  ether and *pzStr
47e0: 0a 2a 2a 20 73 65 74 20 74 6f 20 70 6f 69 6e 74  .** set to point
47f0: 20 61 74 20 74 68 65 20 72 65 73 75 6c 74 2e 20   at the result. 
4800: 54 68 65 20 69 6e 69 74 69 61 6c 20 62 75 66 66  The initial buff
4810: 65 72 20 70 6f 69 6e 74 65 64 20 74 6f 20 62 79  er pointed to by
4820: 20 2a 70 7a 53 74 72 0a 2a 2a 20 69 73 20 64 65   *pzStr.** is de
4830: 61 6c 6c 6f 63 61 74 65 64 20 76 69 61 20 73 71  allocated via sq
4840: 6c 69 74 65 33 5f 66 72 65 65 28 29 2e 0a 2a 2a  lite3_free()..**
4850: 0a 2a 2a 20 49 66 20 74 68 65 20 74 68 69 72 64  .** If the third
4860: 20 61 72 67 75 6d 65 6e 74 2c 20 64 6f 46 72 65   argument, doFre
4870: 65 2c 20 69 73 20 74 72 75 65 2c 20 74 68 65 6e  e, is true, then
4880: 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 29 20   sqlite3_free() 
4890: 69 73 0a 2a 2a 20 61 6c 73 6f 20 63 61 6c 6c 65  is.** also calle
48a0: 64 20 74 6f 20 66 72 65 65 20 74 68 65 20 62 75  d to free the bu
48b0: 66 66 65 72 20 70 6f 69 6e 74 65 64 20 74 6f 20  ffer pointed to 
48c0: 62 79 20 7a 41 70 70 65 6e 64 2e 0a 2a 2f 0a 73  by zAppend..*/.s
48d0: 74 61 74 69 63 20 76 6f 69 64 20 73 74 72 69 6e  tatic void strin
48e0: 67 5f 63 6f 6e 63 61 74 28 63 68 61 72 20 2a 2a  g_concat(char **
48f0: 70 7a 53 74 72 2c 20 63 68 61 72 20 2a 7a 41 70  pzStr, char *zAp
4900: 70 65 6e 64 2c 20 69 6e 74 20 64 6f 46 72 65 65  pend, int doFree
4910: 2c 20 69 6e 74 20 2a 70 52 63 29 7b 0a 20 20 63  , int *pRc){.  c
4920: 68 61 72 20 2a 7a 49 6e 20 3d 20 2a 70 7a 53 74  har *zIn = *pzSt
4930: 72 3b 0a 20 20 69 66 28 20 21 7a 41 70 70 65 6e  r;.  if( !zAppen
4940: 64 20 26 26 20 64 6f 46 72 65 65 20 26 26 20 2a  d && doFree && *
4950: 70 52 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29  pRc==SQLITE_OK )
4960: 7b 0a 20 20 20 20 2a 70 52 63 20 3d 20 53 51 4c  {.    *pRc = SQL
4970: 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 7d 0a 20  ITE_NOMEM;.  }. 
4980: 20 69 66 28 20 2a 70 52 63 21 3d 53 51 4c 49 54   if( *pRc!=SQLIT
4990: 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 73 71 6c 69  E_OK ){.    sqli
49a0: 74 65 33 5f 66 72 65 65 28 7a 49 6e 29 3b 0a 20  te3_free(zIn);. 
49b0: 20 20 20 7a 49 6e 20 3d 20 30 3b 0a 20 20 7d 65     zIn = 0;.  }e
49c0: 6c 73 65 7b 0a 20 20 20 20 69 66 28 20 7a 49 6e  lse{.    if( zIn
49d0: 20 29 7b 0a 20 20 20 20 20 20 63 68 61 72 20 2a   ){.      char *
49e0: 7a 54 65 6d 70 20 3d 20 7a 49 6e 3b 0a 20 20 20  zTemp = zIn;.   
49f0: 20 20 20 7a 49 6e 20 3d 20 73 71 6c 69 74 65 33     zIn = sqlite3
4a00: 5f 6d 70 72 69 6e 74 66 28 22 25 73 25 73 22 2c  _mprintf("%s%s",
4a10: 20 7a 49 6e 2c 20 7a 41 70 70 65 6e 64 29 3b 0a   zIn, zAppend);.
4a20: 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72        sqlite3_fr
4a30: 65 65 28 7a 54 65 6d 70 29 3b 0a 20 20 20 20 7d  ee(zTemp);.    }
4a40: 65 6c 73 65 7b 0a 20 20 20 20 20 20 7a 49 6e 20  else{.      zIn 
4a50: 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74  = sqlite3_mprint
4a60: 66 28 22 25 73 22 2c 20 7a 41 70 70 65 6e 64 29  f("%s", zAppend)
4a70: 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 28 20  ;.    }.    if( 
4a80: 21 7a 49 6e 20 29 7b 0a 20 20 20 20 20 20 2a 70  !zIn ){.      *p
4a90: 52 63 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45  Rc = SQLITE_NOME
4aa0: 4d 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 2a  M;.    }.  }.  *
4ab0: 70 7a 53 74 72 20 3d 20 7a 49 6e 3b 0a 20 20 69  pzStr = zIn;.  i
4ac0: 66 28 20 64 6f 46 72 65 65 20 29 7b 0a 20 20 20  f( doFree ){.   
4ad0: 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 7a 41   sqlite3_free(zA
4ae0: 70 70 65 6e 64 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f  ppend);.  }.}../
4af0: 2a 0a 2a 2a 20 54 68 65 20 65 63 68 6f 20 6d 6f  *.** The echo mo
4b00: 64 75 6c 65 20 69 6d 70 6c 65 6d 65 6e 74 73 20  dule implements 
4b10: 74 68 65 20 73 75 62 73 65 74 20 6f 66 20 71 75  the subset of qu
4b20: 65 72 79 20 63 6f 6e 73 74 72 61 69 6e 74 73 20  ery constraints 
4b30: 61 6e 64 20 73 6f 72 74 0a 2a 2a 20 6f 72 64 65  and sort.** orde
4b40: 72 73 20 74 68 61 74 20 6d 61 79 20 74 61 6b 65  rs that may take
4b50: 20 61 64 76 61 6e 74 61 67 65 20 6f 66 20 53 51   advantage of SQ
4b60: 4c 69 74 65 20 69 6e 64 69 63 65 73 20 6f 6e 20  Lite indices on 
4b70: 74 68 65 20 75 6e 64 65 72 6c 79 69 6e 67 0a 2a  the underlying.*
4b80: 2a 20 72 65 61 6c 20 74 61 62 6c 65 2e 20 46 6f  * real table. Fo
4b90: 72 20 65 78 61 6d 70 6c 65 2c 20 69 66 20 74 68  r example, if th
4ba0: 65 20 72 65 61 6c 20 74 61 62 6c 65 20 69 73 20  e real table is 
4bb0: 64 65 63 6c 61 72 65 64 20 61 73 3a 0a 2a 2a 0a  declared as:.**.
4bc0: 2a 2a 20 20 20 20 20 43 52 45 41 54 45 20 54 41  **     CREATE TA
4bd0: 42 4c 45 20 72 65 61 6c 28 61 2c 20 62 2c 20 63  BLE real(a, b, c
4be0: 29 3b 0a 2a 2a 20 20 20 20 20 43 52 45 41 54 45  );.**     CREATE
4bf0: 20 49 4e 44 45 58 20 72 65 61 6c 5f 69 6e 64 65   INDEX real_inde
4c00: 78 20 4f 4e 20 72 65 61 6c 28 62 29 3b 0a 2a 2a  x ON real(b);.**
4c10: 0a 2a 2a 20 74 68 65 6e 20 74 68 65 20 65 63 68  .** then the ech
4c20: 6f 20 6d 6f 64 75 6c 65 20 68 61 6e 64 6c 65 73  o module handles
4c30: 20 57 48 45 52 45 20 6f 72 20 4f 52 44 45 52 20   WHERE or ORDER 
4c40: 42 59 20 63 6c 61 75 73 65 73 20 74 68 61 74 20  BY clauses that 
4c50: 72 65 66 65 72 0a 2a 2a 20 74 6f 20 74 68 65 20  refer.** to the 
4c60: 63 6f 6c 75 6d 6e 20 22 62 22 2c 20 62 75 74 20  column "b", but 
4c70: 6e 6f 74 20 22 61 22 20 6f 72 20 22 63 22 2e 20  not "a" or "c". 
4c80: 49 66 20 61 20 6d 75 6c 74 69 2d 63 6f 6c 75 6d  If a multi-colum
4c90: 6e 20 69 6e 64 65 78 20 69 73 0a 2a 2a 20 70 72  n index is.** pr
4ca0: 65 73 65 6e 74 2c 20 6f 6e 6c 79 20 69 74 73 20  esent, only its 
4cb0: 6c 65 66 74 20 6d 6f 73 74 20 63 6f 6c 75 6d 6e  left most column
4cc0: 20 69 73 20 63 6f 6e 73 69 64 65 72 65 64 2e 20   is considered. 
4cd0: 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20 78 42 65 73  .**.** This xBes
4ce0: 74 49 6e 64 65 78 20 6d 65 74 68 6f 64 20 65 6e  tIndex method en
4cf0: 63 6f 64 65 73 20 74 68 65 20 70 72 6f 70 6f 73  codes the propos
4d00: 65 64 20 73 65 61 72 63 68 20 73 74 72 61 74 65  ed search strate
4d10: 67 79 20 61 73 0a 2a 2a 20 61 6e 20 53 51 4c 20  gy as.** an SQL 
4d20: 71 75 65 72 79 20 6f 6e 20 74 68 65 20 72 65 61  query on the rea
4d30: 6c 20 74 61 62 6c 65 20 75 6e 64 65 72 6c 79 69  l table underlyi
4d40: 6e 67 20 74 68 65 20 76 69 72 74 75 61 6c 20 65  ng the virtual e
4d50: 63 68 6f 20 6d 6f 64 75 6c 65 20 0a 2a 2a 20 74  cho module .** t
4d60: 61 62 6c 65 20 61 6e 64 20 73 74 6f 72 65 73 20  able and stores 
4d70: 74 68 65 20 71 75 65 72 79 20 69 6e 20 73 71 6c  the query in sql
4d80: 69 74 65 33 5f 69 6e 64 65 78 5f 69 6e 66 6f 2e  ite3_index_info.
4d90: 69 64 78 53 74 72 2e 20 54 68 65 20 53 51 4c 0a  idxStr. The SQL.
4da0: 2a 2a 20 73 74 61 74 65 6d 65 6e 74 20 69 73 20  ** statement is 
4db0: 6f 66 20 74 68 65 20 66 6f 72 6d 3a 0a 2a 2a 0a  of the form:.**.
4dc0: 2a 2a 20 20 20 53 45 4c 45 43 54 20 72 6f 77 69  **   SELECT rowi
4dd0: 64 2c 20 2a 20 46 52 4f 4d 20 3c 72 65 61 6c 2d  d, * FROM <real-
4de0: 74 61 62 6c 65 3e 20 3f 3c 77 68 65 72 65 2d 63  table> ?<where-c
4df0: 6c 61 75 73 65 3e 3f 20 3f 3c 6f 72 64 65 72 2d  lause>? ?<order-
4e00: 62 79 2d 63 6c 61 75 73 65 3e 3f 0a 2a 2a 0a 2a  by-clause>?.**.*
4e10: 2a 20 77 68 65 72 65 20 74 68 65 20 3c 77 68 65  * where the <whe
4e20: 72 65 2d 63 6c 61 75 73 65 3e 20 61 6e 64 20 3c  re-clause> and <
4e30: 6f 72 64 65 72 2d 62 79 2d 63 6c 61 75 73 65 3e  order-by-clause>
4e40: 20 61 72 65 20 64 65 74 65 72 6d 69 6e 65 64 0a   are determined.
4e50: 2a 2a 20 62 79 20 74 68 65 20 63 6f 6e 74 65 6e  ** by the conten
4e60: 74 73 20 6f 66 20 74 68 65 20 73 74 72 75 63 74  ts of the struct
4e70: 75 72 65 20 70 6f 69 6e 74 65 64 20 74 6f 20 62  ure pointed to b
4e80: 79 20 74 68 65 20 70 49 64 78 49 6e 66 6f 20 61  y the pIdxInfo a
4e90: 72 67 75 6d 65 6e 74 2e 0a 2a 2f 0a 73 74 61 74  rgument..*/.stat
4ea0: 69 63 20 69 6e 74 20 65 63 68 6f 42 65 73 74 49  ic int echoBestI
4eb0: 6e 64 65 78 28 73 71 6c 69 74 65 33 5f 76 74 61  ndex(sqlite3_vta
4ec0: 62 20 2a 74 61 62 2c 20 73 71 6c 69 74 65 33 5f  b *tab, sqlite3_
4ed0: 69 6e 64 65 78 5f 69 6e 66 6f 20 2a 70 49 64 78  index_info *pIdx
4ee0: 49 6e 66 6f 29 7b 0a 20 20 69 6e 74 20 69 69 3b  Info){.  int ii;
4ef0: 0a 20 20 63 68 61 72 20 2a 7a 51 75 65 72 79 20  .  char *zQuery 
4f00: 3d 20 30 3b 0a 20 20 63 68 61 72 20 2a 7a 4e 65  = 0;.  char *zNe
4f10: 77 3b 0a 20 20 69 6e 74 20 6e 41 72 67 20 3d 20  w;.  int nArg = 
4f20: 30 3b 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20  0;.  const char 
4f30: 2a 7a 53 65 70 20 3d 20 22 57 48 45 52 45 22 3b  *zSep = "WHERE";
4f40: 0a 20 20 65 63 68 6f 5f 76 74 61 62 20 2a 70 56  .  echo_vtab *pV
4f50: 74 61 62 20 3d 20 28 65 63 68 6f 5f 76 74 61 62  tab = (echo_vtab
4f60: 20 2a 29 74 61 62 3b 0a 20 20 73 71 6c 69 74 65   *)tab;.  sqlite
4f70: 33 5f 73 74 6d 74 20 2a 70 53 74 6d 74 20 3d 20  3_stmt *pStmt = 
4f80: 30 3b 0a 20 20 54 63 6c 5f 49 6e 74 65 72 70 20  0;.  Tcl_Interp 
4f90: 2a 69 6e 74 65 72 70 20 3d 20 70 56 74 61 62 2d  *interp = pVtab-
4fa0: 3e 69 6e 74 65 72 70 3b 0a 0a 20 20 69 6e 74 20  >interp;..  int 
4fb0: 6e 52 6f 77 3b 0a 20 20 69 6e 74 20 75 73 65 49  nRow;.  int useI
4fc0: 64 78 20 3d 20 30 3b 0a 20 20 69 6e 74 20 72 63  dx = 0;.  int rc
4fd0: 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20   = SQLITE_OK;.  
4fe0: 69 6e 74 20 75 73 65 43 6f 73 74 20 3d 20 30 3b  int useCost = 0;
4ff0: 0a 20 20 64 6f 75 62 6c 65 20 63 6f 73 74 3b 0a  .  double cost;.
5000: 0a 20 20 69 6e 74 20 69 73 49 67 6e 6f 72 65 55  .  int isIgnoreU
5010: 73 61 62 6c 65 20 3d 20 30 3b 0a 20 20 69 66 28  sable = 0;.  if(
5020: 20 54 63 6c 5f 47 65 74 56 61 72 28 69 6e 74 65   Tcl_GetVar(inte
5030: 72 70 2c 20 22 65 63 68 6f 5f 6d 6f 64 75 6c 65  rp, "echo_module
5040: 5f 69 67 6e 6f 72 65 5f 75 73 61 62 6c 65 22 2c  _ignore_usable",
5050: 20 54 43 4c 5f 47 4c 4f 42 41 4c 5f 4f 4e 4c 59   TCL_GLOBAL_ONLY
5060: 29 20 29 7b 0a 20 20 20 20 69 73 49 67 6e 6f 72  ) ){.    isIgnor
5070: 65 55 73 61 62 6c 65 20 3d 20 31 3b 0a 20 20 7d  eUsable = 1;.  }
5080: 0a 0a 20 20 2f 2a 20 44 65 74 65 72 6d 69 6e 65  ..  /* Determine
5090: 20 74 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 72   the number of r
50a0: 6f 77 73 20 69 6e 20 74 68 65 20 74 61 62 6c 65  ows in the table
50b0: 20 61 6e 64 20 73 74 6f 72 65 20 74 68 69 73 20   and store this 
50c0: 76 61 6c 75 65 20 69 6e 20 6c 6f 63 61 6c 0a 20  value in local. 
50d0: 20 2a 2a 20 76 61 72 69 61 62 6c 65 20 6e 52 6f   ** variable nRo
50e0: 77 2e 20 54 68 65 20 27 65 73 74 69 6d 61 74 65  w. The 'estimate
50f0: 64 2d 63 6f 73 74 27 20 6f 66 20 74 68 65 20 73  d-cost' of the s
5100: 63 61 6e 20 77 69 6c 6c 20 62 65 20 74 68 65 20  can will be the 
5110: 6e 75 6d 62 65 72 20 6f 66 0a 20 20 2a 2a 20 72  number of.  ** r
5120: 6f 77 73 20 69 6e 20 74 68 65 20 74 61 62 6c 65  ows in the table
5130: 20 66 6f 72 20 61 20 6c 69 6e 65 61 72 20 73 63   for a linear sc
5140: 61 6e 2c 20 6f 72 20 74 68 65 20 6c 6f 67 20 28  an, or the log (
5150: 62 61 73 65 20 32 29 20 6f 66 20 74 68 65 20 0a  base 2) of the .
5160: 20 20 2a 2a 20 6e 75 6d 62 65 72 20 6f 66 20 72    ** number of r
5170: 6f 77 73 20 69 66 20 74 68 65 20 70 72 6f 70 6f  ows if the propo
5180: 73 65 64 20 73 63 61 6e 20 75 73 65 73 20 61 6e  sed scan uses an
5190: 20 69 6e 64 65 78 2e 20 20 0a 20 20 2a 2f 0a 20   index.  .  */. 
51a0: 20 69 66 28 20 54 63 6c 5f 47 65 74 56 61 72 28   if( Tcl_GetVar(
51b0: 69 6e 74 65 72 70 2c 20 22 65 63 68 6f 5f 6d 6f  interp, "echo_mo
51c0: 64 75 6c 65 5f 63 6f 73 74 22 2c 20 54 43 4c 5f  dule_cost", TCL_
51d0: 47 4c 4f 42 41 4c 5f 4f 4e 4c 59 29 20 29 7b 0a  GLOBAL_ONLY) ){.
51e0: 20 20 20 20 63 6f 73 74 20 3d 20 61 74 6f 66 28      cost = atof(
51f0: 54 63 6c 5f 47 65 74 56 61 72 28 69 6e 74 65 72  Tcl_GetVar(inter
5200: 70 2c 20 22 65 63 68 6f 5f 6d 6f 64 75 6c 65 5f  p, "echo_module_
5210: 63 6f 73 74 22 2c 20 54 43 4c 5f 47 4c 4f 42 41  cost", TCL_GLOBA
5220: 4c 5f 4f 4e 4c 59 29 29 3b 0a 20 20 20 20 75 73  L_ONLY));.    us
5230: 65 43 6f 73 74 20 3d 20 31 3b 0a 20 20 7d 20 65  eCost = 1;.  } e
5240: 6c 73 65 20 7b 0a 20 20 20 20 7a 51 75 65 72 79  lse {.    zQuery
5250: 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e   = sqlite3_mprin
5260: 74 66 28 22 53 45 4c 45 43 54 20 63 6f 75 6e 74  tf("SELECT count
5270: 28 2a 29 20 46 52 4f 4d 20 25 51 22 2c 20 70 56  (*) FROM %Q", pV
5280: 74 61 62 2d 3e 7a 54 61 62 6c 65 4e 61 6d 65 29  tab->zTableName)
5290: 3b 0a 20 20 20 20 69 66 28 20 21 7a 51 75 65 72  ;.    if( !zQuer
52a0: 79 20 29 7b 0a 20 20 20 20 20 20 72 65 74 75 72  y ){.      retur
52b0: 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a  n SQLITE_NOMEM;.
52c0: 20 20 20 20 7d 0a 20 20 20 20 72 63 20 3d 20 73      }.    rc = s
52d0: 71 6c 69 74 65 33 5f 70 72 65 70 61 72 65 28 70  qlite3_prepare(p
52e0: 56 74 61 62 2d 3e 64 62 2c 20 7a 51 75 65 72 79  Vtab->db, zQuery
52f0: 2c 20 2d 31 2c 20 26 70 53 74 6d 74 2c 20 30 29  , -1, &pStmt, 0)
5300: 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72  ;.    sqlite3_fr
5310: 65 65 28 7a 51 75 65 72 79 29 3b 0a 20 20 20 20  ee(zQuery);.    
5320: 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f  if( rc!=SQLITE_O
5330: 4b 20 29 7b 0a 20 20 20 20 20 20 72 65 74 75 72  K ){.      retur
5340: 6e 20 72 63 3b 0a 20 20 20 20 7d 0a 20 20 20 20  n rc;.    }.    
5350: 73 71 6c 69 74 65 33 5f 73 74 65 70 28 70 53 74  sqlite3_step(pSt
5360: 6d 74 29 3b 0a 20 20 20 20 6e 52 6f 77 20 3d 20  mt);.    nRow = 
5370: 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 69  sqlite3_column_i
5380: 6e 74 28 70 53 74 6d 74 2c 20 30 29 3b 0a 20 20  nt(pStmt, 0);.  
5390: 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 66    rc = sqlite3_f
53a0: 69 6e 61 6c 69 7a 65 28 70 53 74 6d 74 29 3b 0a  inalize(pStmt);.
53b0: 20 20 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49      if( rc!=SQLI
53c0: 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 72  TE_OK ){.      r
53d0: 65 74 75 72 6e 20 72 63 3b 0a 20 20 20 20 7d 0a  eturn rc;.    }.
53e0: 20 20 7d 0a 0a 20 20 7a 51 75 65 72 79 20 3d 20    }..  zQuery = 
53f0: 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28  sqlite3_mprintf(
5400: 22 53 45 4c 45 43 54 20 72 6f 77 69 64 2c 20 2a  "SELECT rowid, *
5410: 20 46 52 4f 4d 20 25 51 22 2c 20 70 56 74 61 62   FROM %Q", pVtab
5420: 2d 3e 7a 54 61 62 6c 65 4e 61 6d 65 29 3b 0a 20  ->zTableName);. 
5430: 20 69 66 28 20 21 7a 51 75 65 72 79 20 29 7b 0a   if( !zQuery ){.
5440: 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54      return SQLIT
5450: 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 7d 0a 20 20 66  E_NOMEM;.  }.  f
5460: 6f 72 28 69 69 3d 30 3b 20 69 69 3c 70 49 64 78  or(ii=0; ii<pIdx
5470: 49 6e 66 6f 2d 3e 6e 43 6f 6e 73 74 72 61 69 6e  Info->nConstrain
5480: 74 3b 20 69 69 2b 2b 29 7b 0a 20 20 20 20 63 6f  t; ii++){.    co
5490: 6e 73 74 20 73 74 72 75 63 74 20 73 71 6c 69 74  nst struct sqlit
54a0: 65 33 5f 69 6e 64 65 78 5f 63 6f 6e 73 74 72 61  e3_index_constra
54b0: 69 6e 74 20 2a 70 43 6f 6e 73 74 72 61 69 6e 74  int *pConstraint
54c0: 3b 0a 20 20 20 20 73 74 72 75 63 74 20 73 71 6c  ;.    struct sql
54d0: 69 74 65 33 5f 69 6e 64 65 78 5f 63 6f 6e 73 74  ite3_index_const
54e0: 72 61 69 6e 74 5f 75 73 61 67 65 20 2a 70 55 73  raint_usage *pUs
54f0: 61 67 65 3b 0a 20 20 20 20 69 6e 74 20 69 43 6f  age;.    int iCo
5500: 6c 3b 0a 0a 20 20 20 20 70 43 6f 6e 73 74 72 61  l;..    pConstra
5510: 69 6e 74 20 3d 20 26 70 49 64 78 49 6e 66 6f 2d  int = &pIdxInfo-
5520: 3e 61 43 6f 6e 73 74 72 61 69 6e 74 5b 69 69 5d  >aConstraint[ii]
5530: 3b 0a 20 20 20 20 70 55 73 61 67 65 20 3d 20 26  ;.    pUsage = &
5540: 70 49 64 78 49 6e 66 6f 2d 3e 61 43 6f 6e 73 74  pIdxInfo->aConst
5550: 72 61 69 6e 74 55 73 61 67 65 5b 69 69 5d 3b 0a  raintUsage[ii];.
5560: 0a 20 20 20 20 69 66 28 20 21 69 73 49 67 6e 6f  .    if( !isIgno
5570: 72 65 55 73 61 62 6c 65 20 26 26 20 21 70 43 6f  reUsable && !pCo
5580: 6e 73 74 72 61 69 6e 74 2d 3e 75 73 61 62 6c 65  nstraint->usable
5590: 20 29 20 63 6f 6e 74 69 6e 75 65 3b 0a 0a 20 20   ) continue;..  
55a0: 20 20 69 43 6f 6c 20 3d 20 70 43 6f 6e 73 74 72    iCol = pConstr
55b0: 61 69 6e 74 2d 3e 69 43 6f 6c 75 6d 6e 3b 0a 20  aint->iColumn;. 
55c0: 20 20 20 69 66 28 20 70 56 74 61 62 2d 3e 61 49     if( pVtab->aI
55d0: 6e 64 65 78 5b 69 43 6f 6c 5d 20 29 7b 0a 20 20  ndex[iCol] ){.  
55e0: 20 20 20 20 63 68 61 72 20 2a 7a 43 6f 6c 20 3d      char *zCol =
55f0: 20 70 56 74 61 62 2d 3e 61 43 6f 6c 5b 69 43 6f   pVtab->aCol[iCo
5600: 6c 5d 3b 0a 20 20 20 20 20 20 63 68 61 72 20 2a  l];.      char *
5610: 7a 4f 70 20 3d 20 30 3b 0a 20 20 20 20 20 20 75  zOp = 0;.      u
5620: 73 65 49 64 78 20 3d 20 31 3b 0a 20 20 20 20 20  seIdx = 1;.     
5630: 20 69 66 28 20 69 43 6f 6c 3c 30 20 29 7b 0a 20   if( iCol<0 ){. 
5640: 20 20 20 20 20 20 20 7a 43 6f 6c 20 3d 20 22 72         zCol = "r
5650: 6f 77 69 64 22 3b 0a 20 20 20 20 20 20 7d 0a 20  owid";.      }. 
5660: 20 20 20 20 20 73 77 69 74 63 68 28 20 70 43 6f       switch( pCo
5670: 6e 73 74 72 61 69 6e 74 2d 3e 6f 70 20 29 7b 0a  nstraint->op ){.
5680: 20 20 20 20 20 20 20 20 63 61 73 65 20 53 51 4c          case SQL
5690: 49 54 45 5f 49 4e 44 45 58 5f 43 4f 4e 53 54 52  ITE_INDEX_CONSTR
56a0: 41 49 4e 54 5f 45 51 3a 0a 20 20 20 20 20 20 20  AINT_EQ:.       
56b0: 20 20 20 7a 4f 70 20 3d 20 22 3d 22 3b 20 62 72     zOp = "="; br
56c0: 65 61 6b 3b 0a 20 20 20 20 20 20 20 20 63 61 73  eak;.        cas
56d0: 65 20 53 51 4c 49 54 45 5f 49 4e 44 45 58 5f 43  e SQLITE_INDEX_C
56e0: 4f 4e 53 54 52 41 49 4e 54 5f 4c 54 3a 0a 20 20  ONSTRAINT_LT:.  
56f0: 20 20 20 20 20 20 20 20 7a 4f 70 20 3d 20 22 3c          zOp = "<
5700: 22 3b 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20  "; break;.      
5710: 20 20 63 61 73 65 20 53 51 4c 49 54 45 5f 49 4e    case SQLITE_IN
5720: 44 45 58 5f 43 4f 4e 53 54 52 41 49 4e 54 5f 47  DEX_CONSTRAINT_G
5730: 54 3a 0a 20 20 20 20 20 20 20 20 20 20 7a 4f 70  T:.          zOp
5740: 20 3d 20 22 3e 22 3b 20 62 72 65 61 6b 3b 0a 20   = ">"; break;. 
5750: 20 20 20 20 20 20 20 63 61 73 65 20 53 51 4c 49         case SQLI
5760: 54 45 5f 49 4e 44 45 58 5f 43 4f 4e 53 54 52 41  TE_INDEX_CONSTRA
5770: 49 4e 54 5f 4c 45 3a 0a 20 20 20 20 20 20 20 20  INT_LE:.        
5780: 20 20 7a 4f 70 20 3d 20 22 3c 3d 22 3b 20 62 72    zOp = "<="; br
5790: 65 61 6b 3b 0a 20 20 20 20 20 20 20 20 63 61 73  eak;.        cas
57a0: 65 20 53 51 4c 49 54 45 5f 49 4e 44 45 58 5f 43  e SQLITE_INDEX_C
57b0: 4f 4e 53 54 52 41 49 4e 54 5f 47 45 3a 0a 20 20  ONSTRAINT_GE:.  
57c0: 20 20 20 20 20 20 20 20 7a 4f 70 20 3d 20 22 3e          zOp = ">
57d0: 3d 22 3b 20 62 72 65 61 6b 3b 0a 20 20 20 20 20  ="; break;.     
57e0: 20 20 20 63 61 73 65 20 53 51 4c 49 54 45 5f 49     case SQLITE_I
57f0: 4e 44 45 58 5f 43 4f 4e 53 54 52 41 49 4e 54 5f  NDEX_CONSTRAINT_
5800: 4d 41 54 43 48 3a 0a 20 20 20 20 20 20 20 20 20  MATCH:.         
5810: 20 7a 4f 70 20 3d 20 22 4c 49 4b 45 22 3b 20 62   zOp = "LIKE"; b
5820: 72 65 61 6b 3b 0a 20 20 20 20 20 20 7d 0a 20 20  reak;.      }.  
5830: 20 20 20 20 69 66 28 20 7a 4f 70 5b 30 5d 3d 3d      if( zOp[0]==
5840: 27 4c 27 20 29 7b 0a 20 20 20 20 20 20 20 20 7a  'L' ){.        z
5850: 4e 65 77 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70  New = sqlite3_mp
5860: 72 69 6e 74 66 28 22 20 25 73 20 25 73 20 4c 49  rintf(" %s %s LI
5870: 4b 45 20 28 53 45 4c 45 43 54 20 27 25 25 27 7c  KE (SELECT '%%'|
5880: 7c 3f 7c 7c 27 25 25 27 29 22 2c 20 0a 20 20 20  |?||'%%')", .   
5890: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
58a0: 20 20 20 20 20 20 20 20 20 20 20 20 7a 53 65 70              zSep
58b0: 2c 20 7a 43 6f 6c 29 3b 0a 20 20 20 20 20 20 7d  , zCol);.      }
58c0: 20 65 6c 73 65 20 7b 0a 20 20 20 20 20 20 20 20   else {.        
58d0: 7a 4e 65 77 20 3d 20 73 71 6c 69 74 65 33 5f 6d  zNew = sqlite3_m
58e0: 70 72 69 6e 74 66 28 22 20 25 73 20 25 73 20 25  printf(" %s %s %
58f0: 73 20 3f 22 2c 20 7a 53 65 70 2c 20 7a 43 6f 6c  s ?", zSep, zCol
5900: 2c 20 7a 4f 70 29 3b 0a 20 20 20 20 20 20 7d 0a  , zOp);.      }.
5910: 20 20 20 20 20 20 73 74 72 69 6e 67 5f 63 6f 6e        string_con
5920: 63 61 74 28 26 7a 51 75 65 72 79 2c 20 7a 4e 65  cat(&zQuery, zNe
5930: 77 2c 20 31 2c 20 26 72 63 29 3b 0a 0a 20 20 20  w, 1, &rc);..   
5940: 20 20 20 7a 53 65 70 20 3d 20 22 41 4e 44 22 3b     zSep = "AND";
5950: 0a 20 20 20 20 20 20 70 55 73 61 67 65 2d 3e 61  .      pUsage->a
5960: 72 67 76 49 6e 64 65 78 20 3d 20 2b 2b 6e 41 72  rgvIndex = ++nAr
5970: 67 3b 0a 20 20 20 20 20 20 70 55 73 61 67 65 2d  g;.      pUsage-
5980: 3e 6f 6d 69 74 20 3d 20 31 3b 0a 20 20 20 20 7d  >omit = 1;.    }
5990: 0a 20 20 7d 0a 0a 20 20 2f 2a 20 49 66 20 74 68  .  }..  /* If th
59a0: 65 72 65 20 69 73 20 6f 6e 6c 79 20 6f 6e 65 20  ere is only one 
59b0: 74 65 72 6d 20 69 6e 20 74 68 65 20 4f 52 44 45  term in the ORDE
59c0: 52 20 42 59 20 63 6c 61 75 73 65 2c 20 61 6e 64  R BY clause, and
59d0: 20 69 74 20 69 73 0a 20 20 2a 2a 20 6f 6e 20 61   it is.  ** on a
59e0: 20 63 6f 6c 75 6d 6e 20 74 68 61 74 20 74 68 69   column that thi
59f0: 73 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65 20  s virtual table 
5a00: 68 61 73 20 61 6e 20 69 6e 64 65 78 20 66 6f 72  has an index for
5a10: 2c 20 74 68 65 6e 20 63 6f 6e 73 75 6d 65 20 0a  , then consume .
5a20: 20 20 2a 2a 20 74 68 65 20 4f 52 44 45 52 20 42    ** the ORDER B
5a30: 59 20 63 6c 61 75 73 65 2e 0a 20 20 2a 2f 0a 20  Y clause..  */. 
5a40: 20 69 66 28 20 70 49 64 78 49 6e 66 6f 2d 3e 6e   if( pIdxInfo->n
5a50: 4f 72 64 65 72 42 79 3d 3d 31 20 26 26 20 70 56  OrderBy==1 && pV
5a60: 74 61 62 2d 3e 61 49 6e 64 65 78 5b 70 49 64 78  tab->aIndex[pIdx
5a70: 49 6e 66 6f 2d 3e 61 4f 72 64 65 72 42 79 2d 3e  Info->aOrderBy->
5a80: 69 43 6f 6c 75 6d 6e 5d 20 29 7b 0a 20 20 20 20  iColumn] ){.    
5a90: 69 6e 74 20 69 43 6f 6c 20 3d 20 70 49 64 78 49  int iCol = pIdxI
5aa0: 6e 66 6f 2d 3e 61 4f 72 64 65 72 42 79 2d 3e 69  nfo->aOrderBy->i
5ab0: 43 6f 6c 75 6d 6e 3b 0a 20 20 20 20 63 68 61 72  Column;.    char
5ac0: 20 2a 7a 43 6f 6c 20 3d 20 70 56 74 61 62 2d 3e   *zCol = pVtab->
5ad0: 61 43 6f 6c 5b 69 43 6f 6c 5d 3b 0a 20 20 20 20  aCol[iCol];.    
5ae0: 63 68 61 72 20 2a 7a 44 69 72 20 3d 20 70 49 64  char *zDir = pId
5af0: 78 49 6e 66 6f 2d 3e 61 4f 72 64 65 72 42 79 2d  xInfo->aOrderBy-
5b00: 3e 64 65 73 63 3f 22 44 45 53 43 22 3a 22 41 53  >desc?"DESC":"AS
5b10: 43 22 3b 0a 20 20 20 20 69 66 28 20 69 43 6f 6c  C";.    if( iCol
5b20: 3c 30 20 29 7b 0a 20 20 20 20 20 20 7a 43 6f 6c  <0 ){.      zCol
5b30: 20 3d 20 22 72 6f 77 69 64 22 3b 0a 20 20 20 20   = "rowid";.    
5b40: 7d 0a 20 20 20 20 7a 4e 65 77 20 3d 20 73 71 6c  }.    zNew = sql
5b50: 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 22 20 4f  ite3_mprintf(" O
5b60: 52 44 45 52 20 42 59 20 25 73 20 25 73 22 2c 20  RDER BY %s %s", 
5b70: 7a 43 6f 6c 2c 20 7a 44 69 72 29 3b 0a 20 20 20  zCol, zDir);.   
5b80: 20 73 74 72 69 6e 67 5f 63 6f 6e 63 61 74 28 26   string_concat(&
5b90: 7a 51 75 65 72 79 2c 20 7a 4e 65 77 2c 20 31 2c  zQuery, zNew, 1,
5ba0: 20 26 72 63 29 3b 0a 20 20 20 20 70 49 64 78 49   &rc);.    pIdxI
5bb0: 6e 66 6f 2d 3e 6f 72 64 65 72 42 79 43 6f 6e 73  nfo->orderByCons
5bc0: 75 6d 65 64 20 3d 20 31 3b 0a 20 20 7d 0a 0a 20  umed = 1;.  }.. 
5bd0: 20 61 70 70 65 6e 64 54 6f 45 63 68 6f 4d 6f 64   appendToEchoMod
5be0: 75 6c 65 28 70 56 74 61 62 2d 3e 69 6e 74 65 72  ule(pVtab->inter
5bf0: 70 2c 20 22 78 42 65 73 74 49 6e 64 65 78 22 29  p, "xBestIndex")
5c00: 3b 3b 0a 20 20 61 70 70 65 6e 64 54 6f 45 63 68  ;;.  appendToEch
5c10: 6f 4d 6f 64 75 6c 65 28 70 56 74 61 62 2d 3e 69  oModule(pVtab->i
5c20: 6e 74 65 72 70 2c 20 7a 51 75 65 72 79 29 3b 0a  nterp, zQuery);.
5c30: 0a 20 20 69 66 28 20 21 7a 51 75 65 72 79 20 29  .  if( !zQuery )
5c40: 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 72 63 3b  {.    return rc;
5c50: 0a 20 20 7d 0a 20 20 70 49 64 78 49 6e 66 6f 2d  .  }.  pIdxInfo-
5c60: 3e 69 64 78 4e 75 6d 20 3d 20 68 61 73 68 53 74  >idxNum = hashSt
5c70: 72 69 6e 67 28 7a 51 75 65 72 79 29 3b 0a 20 20  ring(zQuery);.  
5c80: 70 49 64 78 49 6e 66 6f 2d 3e 69 64 78 53 74 72  pIdxInfo->idxStr
5c90: 20 3d 20 7a 51 75 65 72 79 3b 0a 20 20 70 49 64   = zQuery;.  pId
5ca0: 78 49 6e 66 6f 2d 3e 6e 65 65 64 54 6f 46 72 65  xInfo->needToFre
5cb0: 65 49 64 78 53 74 72 20 3d 20 31 3b 0a 20 20 69  eIdxStr = 1;.  i
5cc0: 66 20 28 75 73 65 43 6f 73 74 29 20 7b 0a 20 20  f (useCost) {.  
5cd0: 20 20 70 49 64 78 49 6e 66 6f 2d 3e 65 73 74 69    pIdxInfo->esti
5ce0: 6d 61 74 65 64 43 6f 73 74 20 3d 20 63 6f 73 74  matedCost = cost
5cf0: 3b 0a 20 20 7d 20 65 6c 73 65 20 69 66 28 20 75  ;.  } else if( u
5d00: 73 65 49 64 78 20 29 7b 0a 20 20 20 20 2f 2a 20  seIdx ){.    /* 
5d10: 41 70 70 72 6f 78 69 6d 61 74 69 6f 6e 20 6f 66  Approximation of
5d20: 20 6c 6f 67 32 28 6e 52 6f 77 29 2e 20 2a 2f 0a   log2(nRow). */.
5d30: 20 20 20 20 66 6f 72 28 20 69 69 3d 30 3b 20 69      for( ii=0; i
5d40: 69 3c 28 73 69 7a 65 6f 66 28 69 6e 74 29 2a 38  i<(sizeof(int)*8
5d50: 29 3b 20 69 69 2b 2b 20 29 7b 0a 20 20 20 20 20  ); ii++ ){.     
5d60: 20 69 66 28 20 6e 52 6f 77 20 26 20 28 31 3c 3c   if( nRow & (1<<
5d70: 69 69 29 20 29 7b 0a 20 20 20 20 20 20 20 20 70  ii) ){.        p
5d80: 49 64 78 49 6e 66 6f 2d 3e 65 73 74 69 6d 61 74  IdxInfo->estimat
5d90: 65 64 43 6f 73 74 20 3d 20 28 64 6f 75 62 6c 65  edCost = (double
5da0: 29 69 69 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20  )ii;.      }.   
5db0: 20 7d 0a 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20   }.  } else {.  
5dc0: 20 20 70 49 64 78 49 6e 66 6f 2d 3e 65 73 74 69    pIdxInfo->esti
5dd0: 6d 61 74 65 64 43 6f 73 74 20 3d 20 28 64 6f 75  matedCost = (dou
5de0: 62 6c 65 29 6e 52 6f 77 3b 0a 20 20 7d 0a 20 20  ble)nRow;.  }.  
5df0: 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a  return rc;.}../*
5e00: 0a 2a 2a 20 54 68 65 20 78 55 70 64 61 74 65 20  .** The xUpdate 
5e10: 6d 65 74 68 6f 64 20 66 6f 72 20 65 63 68 6f 20  method for echo 
5e20: 6d 6f 64 75 6c 65 20 76 69 72 74 75 61 6c 20 74  module virtual t
5e30: 61 62 6c 65 73 2e 0a 2a 2a 20 0a 2a 2a 20 20 20  ables..** .**   
5e40: 20 61 70 44 61 74 61 5b 30 5d 20 20 61 70 44 61   apData[0]  apDa
5e50: 74 61 5b 31 5d 20 20 61 70 44 61 74 61 5b 32 2e  ta[1]  apData[2.
5e60: 2e 5d 0a 2a 2a 0a 2a 2a 20 20 20 20 49 4e 54 45  .].**.**    INTE
5e70: 47 45 52 20 20 20 20 20 20 20 20 20 20 20 20 20  GER             
5e80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5e90: 20 44 45 4c 45 54 45 20 20 20 20 20 20 20 20 20   DELETE         
5ea0: 20 20 20 0a 2a 2a 0a 2a 2a 20 20 20 20 49 4e 54     .**.**    INT
5eb0: 45 47 45 52 20 20 20 20 4e 55 4c 4c 20 20 20 20  EGER    NULL    
5ec0: 20 20 20 28 6e 43 6f 6c 20 61 72 67 73 29 20 20     (nCol args)  
5ed0: 20 20 55 50 44 41 54 45 20 28 64 6f 20 6e 6f 74    UPDATE (do not
5ee0: 20 73 65 74 20 72 6f 77 69 64 29 0a 2a 2a 20 20   set rowid).**  
5ef0: 20 20 49 4e 54 45 47 45 52 20 20 20 20 49 4e 54    INTEGER    INT
5f00: 45 47 45 52 20 20 20 20 28 6e 43 6f 6c 20 61 72  EGER    (nCol ar
5f10: 67 73 29 20 20 20 20 55 50 44 41 54 45 20 28 77  gs)    UPDATE (w
5f20: 69 74 68 20 53 45 54 20 72 6f 77 69 64 20 3d 20  ith SET rowid = 
5f30: 3c 61 72 67 31 3e 29 0a 2a 2a 0a 2a 2a 20 20 20  <arg1>).**.**   
5f40: 20 4e 55 4c 4c 20 20 20 20 20 20 20 4e 55 4c 4c   NULL       NULL
5f50: 20 20 20 20 20 20 20 28 6e 43 6f 6c 20 61 72 67         (nCol arg
5f60: 73 29 20 20 20 20 49 4e 53 45 52 54 20 49 4e 54  s)    INSERT INT
5f70: 4f 20 28 61 75 74 6f 6d 61 74 69 63 20 72 6f 77  O (automatic row
5f80: 69 64 20 76 61 6c 75 65 29 0a 2a 2a 20 20 20 20  id value).**    
5f90: 4e 55 4c 4c 20 20 20 20 20 20 20 49 4e 54 45 47  NULL       INTEG
5fa0: 45 52 20 20 20 20 28 6e 43 6f 6c 20 61 72 67 73  ER    (nCol args
5fb0: 29 20 20 20 20 49 4e 53 45 52 54 20 28 69 6e 63  )    INSERT (inc
5fc0: 6c 2e 20 72 6f 77 69 64 20 76 61 6c 75 65 29 0a  l. rowid value).
5fd0: 2a 2a 0a 2a 2f 0a 69 6e 74 20 65 63 68 6f 55 70  **.*/.int echoUp
5fe0: 64 61 74 65 28 0a 20 20 73 71 6c 69 74 65 33 5f  date(.  sqlite3_
5ff0: 76 74 61 62 20 2a 74 61 62 2c 20 0a 20 20 69 6e  vtab *tab, .  in
6000: 74 20 6e 44 61 74 61 2c 20 0a 20 20 73 71 6c 69  t nData, .  sqli
6010: 74 65 33 5f 76 61 6c 75 65 20 2a 2a 61 70 44 61  te3_value **apDa
6020: 74 61 2c 20 0a 20 20 73 71 6c 69 74 65 5f 69 6e  ta, .  sqlite_in
6030: 74 36 34 20 2a 70 52 6f 77 69 64 0a 29 7b 0a 20  t64 *pRowid.){. 
6040: 20 65 63 68 6f 5f 76 74 61 62 20 2a 70 56 74 61   echo_vtab *pVta
6050: 62 20 3d 20 28 65 63 68 6f 5f 76 74 61 62 20 2a  b = (echo_vtab *
6060: 29 74 61 62 3b 0a 20 20 73 71 6c 69 74 65 33 20  )tab;.  sqlite3 
6070: 2a 64 62 20 3d 20 70 56 74 61 62 2d 3e 64 62 3b  *db = pVtab->db;
6080: 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49  .  int rc = SQLI
6090: 54 45 5f 4f 4b 3b 0a 0a 20 20 73 71 6c 69 74 65  TE_OK;..  sqlite
60a0: 33 5f 73 74 6d 74 20 2a 70 53 74 6d 74 3b 0a 20  3_stmt *pStmt;. 
60b0: 20 63 68 61 72 20 2a 7a 20 3d 20 30 3b 20 20 20   char *z = 0;   
60c0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53              /* S
60d0: 51 4c 20 73 74 61 74 65 6d 65 6e 74 20 74 6f 20  QL statement to 
60e0: 65 78 65 63 75 74 65 20 2a 2f 0a 20 20 69 6e 74  execute */.  int
60f0: 20 62 69 6e 64 41 72 67 5a 65 72 6f 20 3d 20 30   bindArgZero = 0
6100: 3b 20 20 20 20 20 20 20 2f 2a 20 54 72 75 65 20  ;       /* True 
6110: 74 6f 20 62 69 6e 64 20 61 70 44 61 74 61 5b 30  to bind apData[0
6120: 5d 20 74 6f 20 73 71 6c 20 76 61 72 20 6e 6f 2e  ] to sql var no.
6130: 20 6e 44 61 74 61 20 2a 2f 0a 20 20 69 6e 74 20   nData */.  int 
6140: 62 69 6e 64 41 72 67 4f 6e 65 20 3d 20 30 3b 20  bindArgOne = 0; 
6150: 20 20 20 20 20 20 20 2f 2a 20 54 72 75 65 20 74         /* True t
6160: 6f 20 62 69 6e 64 20 61 70 44 61 74 61 5b 31 5d  o bind apData[1]
6170: 20 74 6f 20 73 71 6c 20 76 61 72 20 6e 6f 2e 20   to sql var no. 
6180: 31 20 2a 2f 0a 20 20 69 6e 74 20 69 3b 20 20 20  1 */.  int i;   
6190: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
61a0: 20 20 2f 2a 20 43 6f 75 6e 74 65 72 20 76 61 72    /* Counter var
61b0: 69 61 62 6c 65 20 75 73 65 64 20 62 79 20 66 6f  iable used by fo
61c0: 72 20 6c 6f 6f 70 73 20 2a 2f 0a 0a 20 20 61 73  r loops */..  as
61d0: 73 65 72 74 28 20 6e 44 61 74 61 3d 3d 70 56 74  sert( nData==pVt
61e0: 61 62 2d 3e 6e 43 6f 6c 2b 32 20 7c 7c 20 6e 44  ab->nCol+2 || nD
61f0: 61 74 61 3d 3d 31 20 29 3b 0a 0a 20 20 2f 2a 20  ata==1 );..  /* 
6200: 54 69 63 6b 65 74 20 23 33 30 38 33 20 2d 20 6d  Ticket #3083 - m
6210: 61 6b 65 20 73 75 72 65 20 77 65 20 61 6c 77 61  ake sure we alwa
6220: 79 73 20 73 74 61 72 74 20 61 20 74 72 61 6e 73  ys start a trans
6230: 61 63 74 69 6f 6e 20 70 72 69 6f 72 20 74 6f 0a  action prior to.
6240: 20 20 2a 2a 20 6d 61 6b 69 6e 67 20 61 6e 79 20    ** making any 
6250: 63 68 61 6e 67 65 73 20 74 6f 20 61 20 76 69 72  changes to a vir
6260: 74 75 61 6c 20 74 61 62 6c 65 20 2a 2f 0a 20 20  tual table */.  
6270: 61 73 73 65 72 74 28 20 70 56 74 61 62 2d 3e 69  assert( pVtab->i
6280: 6e 54 72 61 6e 73 61 63 74 69 6f 6e 20 29 3b 0a  nTransaction );.
6290: 0a 20 20 2f 2a 20 49 66 20 61 70 44 61 74 61 5b  .  /* If apData[
62a0: 30 5d 20 69 73 20 61 6e 20 69 6e 74 65 67 65 72  0] is an integer
62b0: 20 61 6e 64 20 6e 44 61 74 61 3e 31 20 74 68 65   and nData>1 the
62c0: 6e 20 64 6f 20 61 6e 20 55 50 44 41 54 45 20 2a  n do an UPDATE *
62d0: 2f 0a 20 20 69 66 28 20 6e 44 61 74 61 3e 31 20  /.  if( nData>1 
62e0: 26 26 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65  && sqlite3_value
62f0: 5f 74 79 70 65 28 61 70 44 61 74 61 5b 30 5d 29  _type(apData[0])
6300: 3d 3d 53 51 4c 49 54 45 5f 49 4e 54 45 47 45 52  ==SQLITE_INTEGER
6310: 20 29 7b 0a 20 20 20 20 63 68 61 72 20 2a 7a 53   ){.    char *zS
6320: 65 70 20 3d 20 22 20 53 45 54 22 3b 0a 20 20 20  ep = " SET";.   
6330: 20 7a 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72   z = sqlite3_mpr
6340: 69 6e 74 66 28 22 55 50 44 41 54 45 20 25 51 22  intf("UPDATE %Q"
6350: 2c 20 70 56 74 61 62 2d 3e 7a 54 61 62 6c 65 4e  , pVtab->zTableN
6360: 61 6d 65 29 3b 0a 20 20 20 20 69 66 28 20 21 7a  ame);.    if( !z
6370: 20 29 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 53   ){.      rc = S
6380: 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20  QLITE_NOMEM;.   
6390: 20 7d 0a 0a 20 20 20 20 62 69 6e 64 41 72 67 4f   }..    bindArgO
63a0: 6e 65 20 3d 20 28 61 70 44 61 74 61 5b 31 5d 20  ne = (apData[1] 
63b0: 26 26 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65  && sqlite3_value
63c0: 5f 74 79 70 65 28 61 70 44 61 74 61 5b 31 5d 29  _type(apData[1])
63d0: 3d 3d 53 51 4c 49 54 45 5f 49 4e 54 45 47 45 52  ==SQLITE_INTEGER
63e0: 29 3b 0a 20 20 20 20 62 69 6e 64 41 72 67 5a 65  );.    bindArgZe
63f0: 72 6f 20 3d 20 31 3b 0a 0a 20 20 20 20 69 66 28  ro = 1;..    if(
6400: 20 62 69 6e 64 41 72 67 4f 6e 65 20 29 7b 0a 20   bindArgOne ){. 
6410: 20 20 20 20 20 20 73 74 72 69 6e 67 5f 63 6f 6e        string_con
6420: 63 61 74 28 26 7a 2c 20 22 20 53 45 54 20 72 6f  cat(&z, " SET ro
6430: 77 69 64 3d 3f 31 20 22 2c 20 30 2c 20 26 72 63  wid=?1 ", 0, &rc
6440: 29 3b 0a 20 20 20 20 20 20 20 7a 53 65 70 20 3d  );.       zSep =
6450: 20 22 2c 22 3b 0a 20 20 20 20 7d 0a 20 20 20 20   ",";.    }.    
6460: 66 6f 72 28 69 3d 32 3b 20 69 3c 6e 44 61 74 61  for(i=2; i<nData
6470: 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20 69 66  ; i++){.      if
6480: 28 20 61 70 44 61 74 61 5b 69 5d 3d 3d 30 20 29  ( apData[i]==0 )
6490: 20 63 6f 6e 74 69 6e 75 65 3b 0a 20 20 20 20 20   continue;.     
64a0: 20 73 74 72 69 6e 67 5f 63 6f 6e 63 61 74 28 26   string_concat(&
64b0: 7a 2c 20 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e  z, sqlite3_mprin
64c0: 74 66 28 0a 20 20 20 20 20 20 20 20 20 20 22 25  tf(.          "%
64d0: 73 20 25 51 3d 3f 25 64 22 2c 20 7a 53 65 70 2c  s %Q=?%d", zSep,
64e0: 20 70 56 74 61 62 2d 3e 61 43 6f 6c 5b 69 2d 32   pVtab->aCol[i-2
64f0: 5d 2c 20 69 29 2c 20 31 2c 20 26 72 63 29 3b 0a  ], i), 1, &rc);.
6500: 20 20 20 20 20 20 7a 53 65 70 20 3d 20 22 2c 22        zSep = ","
6510: 3b 0a 20 20 20 20 7d 0a 20 20 20 20 73 74 72 69  ;.    }.    stri
6520: 6e 67 5f 63 6f 6e 63 61 74 28 26 7a 2c 20 73 71  ng_concat(&z, sq
6530: 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 22 20  lite3_mprintf(" 
6540: 57 48 45 52 45 20 72 6f 77 69 64 3d 3f 25 64 22  WHERE rowid=?%d"
6550: 2c 20 6e 44 61 74 61 29 2c 20 31 2c 20 26 72 63  , nData), 1, &rc
6560: 29 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 49 66 20  );.  }..  /* If 
6570: 61 70 44 61 74 61 5b 30 5d 20 69 73 20 61 6e 20  apData[0] is an 
6580: 69 6e 74 65 67 65 72 20 61 6e 64 20 6e 44 61 74  integer and nDat
6590: 61 3d 3d 31 20 74 68 65 6e 20 64 6f 20 61 20 44  a==1 then do a D
65a0: 45 4c 45 54 45 20 2a 2f 0a 20 20 65 6c 73 65 20  ELETE */.  else 
65b0: 69 66 28 20 6e 44 61 74 61 3d 3d 31 20 26 26 20  if( nData==1 && 
65c0: 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 74 79  sqlite3_value_ty
65d0: 70 65 28 61 70 44 61 74 61 5b 30 5d 29 3d 3d 53  pe(apData[0])==S
65e0: 51 4c 49 54 45 5f 49 4e 54 45 47 45 52 20 29 7b  QLITE_INTEGER ){
65f0: 0a 20 20 20 20 7a 20 3d 20 73 71 6c 69 74 65 33  .    z = sqlite3
6600: 5f 6d 70 72 69 6e 74 66 28 22 44 45 4c 45 54 45  _mprintf("DELETE
6610: 20 46 52 4f 4d 20 25 51 20 57 48 45 52 45 20 72   FROM %Q WHERE r
6620: 6f 77 69 64 20 3d 20 3f 31 22 2c 20 70 56 74 61  owid = ?1", pVta
6630: 62 2d 3e 7a 54 61 62 6c 65 4e 61 6d 65 29 3b 0a  b->zTableName);.
6640: 20 20 20 20 69 66 28 20 21 7a 20 29 7b 0a 20 20      if( !z ){.  
6650: 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f      rc = SQLITE_
6660: 4e 4f 4d 45 4d 3b 0a 20 20 20 20 7d 0a 20 20 20  NOMEM;.    }.   
6670: 20 62 69 6e 64 41 72 67 5a 65 72 6f 20 3d 20 31   bindArgZero = 1
6680: 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 49 66 20 74  ;.  }..  /* If t
6690: 68 65 20 66 69 72 73 74 20 61 72 67 75 6d 65 6e  he first argumen
66a0: 74 20 69 73 20 4e 55 4c 4c 20 61 6e 64 20 74 68  t is NULL and th
66b0: 65 72 65 20 61 72 65 20 6d 6f 72 65 20 74 68 61  ere are more tha
66c0: 6e 20 74 77 6f 20 61 72 67 73 2c 20 49 4e 53 45  n two args, INSE
66d0: 52 54 20 2a 2f 0a 20 20 65 6c 73 65 20 69 66 28  RT */.  else if(
66e0: 20 6e 44 61 74 61 3e 32 20 26 26 20 73 71 6c 69   nData>2 && sqli
66f0: 74 65 33 5f 76 61 6c 75 65 5f 74 79 70 65 28 61  te3_value_type(a
6700: 70 44 61 74 61 5b 30 5d 29 3d 3d 53 51 4c 49 54  pData[0])==SQLIT
6710: 45 5f 4e 55 4c 4c 20 29 7b 0a 20 20 20 20 69 6e  E_NULL ){.    in
6720: 74 20 69 69 3b 0a 20 20 20 20 63 68 61 72 20 2a  t ii;.    char *
6730: 7a 49 6e 73 65 72 74 20 3d 20 30 3b 0a 20 20 20  zInsert = 0;.   
6740: 20 63 68 61 72 20 2a 7a 56 61 6c 75 65 73 20 3d   char *zValues =
6750: 20 30 3b 0a 20 20 0a 20 20 20 20 7a 49 6e 73 65   0;.  .    zInse
6760: 72 74 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72  rt = sqlite3_mpr
6770: 69 6e 74 66 28 22 49 4e 53 45 52 54 20 49 4e 54  intf("INSERT INT
6780: 4f 20 25 51 20 28 22 2c 20 70 56 74 61 62 2d 3e  O %Q (", pVtab->
6790: 7a 54 61 62 6c 65 4e 61 6d 65 29 3b 0a 20 20 20  zTableName);.   
67a0: 20 69 66 28 20 21 7a 49 6e 73 65 72 74 20 29 7b   if( !zInsert ){
67b0: 0a 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c 49  .      rc = SQLI
67c0: 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 7d 0a  TE_NOMEM;.    }.
67d0: 20 20 20 20 69 66 28 20 73 71 6c 69 74 65 33 5f      if( sqlite3_
67e0: 76 61 6c 75 65 5f 74 79 70 65 28 61 70 44 61 74  value_type(apDat
67f0: 61 5b 31 5d 29 3d 3d 53 51 4c 49 54 45 5f 49 4e  a[1])==SQLITE_IN
6800: 54 45 47 45 52 20 29 7b 0a 20 20 20 20 20 20 62  TEGER ){.      b
6810: 69 6e 64 41 72 67 4f 6e 65 20 3d 20 31 3b 0a 20  indArgOne = 1;. 
6820: 20 20 20 20 20 7a 56 61 6c 75 65 73 20 3d 20 73       zValues = s
6830: 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 22  qlite3_mprintf("
6840: 3f 22 29 3b 0a 20 20 20 20 20 20 73 74 72 69 6e  ?");.      strin
6850: 67 5f 63 6f 6e 63 61 74 28 26 7a 49 6e 73 65 72  g_concat(&zInser
6860: 74 2c 20 22 72 6f 77 69 64 22 2c 20 30 2c 20 26  t, "rowid", 0, &
6870: 72 63 29 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20  rc);.    }..    
6880: 61 73 73 65 72 74 28 28 70 56 74 61 62 2d 3e 6e  assert((pVtab->n
6890: 43 6f 6c 2b 32 29 3d 3d 6e 44 61 74 61 29 3b 0a  Col+2)==nData);.
68a0: 20 20 20 20 66 6f 72 28 69 69 3d 32 3b 20 69 69      for(ii=2; ii
68b0: 3c 6e 44 61 74 61 3b 20 69 69 2b 2b 29 7b 0a 20  <nData; ii++){. 
68c0: 20 20 20 20 20 73 74 72 69 6e 67 5f 63 6f 6e 63       string_conc
68d0: 61 74 28 26 7a 49 6e 73 65 72 74 2c 20 0a 20 20  at(&zInsert, .  
68e0: 20 20 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f          sqlite3_
68f0: 6d 70 72 69 6e 74 66 28 22 25 73 25 51 22 2c 20  mprintf("%s%Q", 
6900: 7a 56 61 6c 75 65 73 3f 22 2c 20 22 3a 22 22 2c  zValues?", ":"",
6910: 20 70 56 74 61 62 2d 3e 61 43 6f 6c 5b 69 69 2d   pVtab->aCol[ii-
6920: 32 5d 29 2c 20 31 2c 20 26 72 63 29 3b 0a 20 20  2]), 1, &rc);.  
6930: 20 20 20 20 73 74 72 69 6e 67 5f 63 6f 6e 63 61      string_conca
6940: 74 28 26 7a 56 61 6c 75 65 73 2c 20 0a 20 20 20  t(&zValues, .   
6950: 20 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 6d         sqlite3_m
6960: 70 72 69 6e 74 66 28 22 25 73 3f 25 64 22 2c 20  printf("%s?%d", 
6970: 7a 56 61 6c 75 65 73 3f 22 2c 20 22 3a 22 22 2c  zValues?", ":"",
6980: 20 69 69 29 2c 20 31 2c 20 26 72 63 29 3b 0a 20   ii), 1, &rc);. 
6990: 20 20 20 7d 0a 0a 20 20 20 20 73 74 72 69 6e 67     }..    string
69a0: 5f 63 6f 6e 63 61 74 28 26 7a 2c 20 7a 49 6e 73  _concat(&z, zIns
69b0: 65 72 74 2c 20 31 2c 20 26 72 63 29 3b 0a 20 20  ert, 1, &rc);.  
69c0: 20 20 73 74 72 69 6e 67 5f 63 6f 6e 63 61 74 28    string_concat(
69d0: 26 7a 2c 20 22 29 20 56 41 4c 55 45 53 28 22 2c  &z, ") VALUES(",
69e0: 20 30 2c 20 26 72 63 29 3b 0a 20 20 20 20 73 74   0, &rc);.    st
69f0: 72 69 6e 67 5f 63 6f 6e 63 61 74 28 26 7a 2c 20  ring_concat(&z, 
6a00: 7a 56 61 6c 75 65 73 2c 20 31 2c 20 26 72 63 29  zValues, 1, &rc)
6a10: 3b 0a 20 20 20 20 73 74 72 69 6e 67 5f 63 6f 6e  ;.    string_con
6a20: 63 61 74 28 26 7a 2c 20 22 29 22 2c 20 30 2c 20  cat(&z, ")", 0, 
6a30: 26 72 63 29 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20  &rc);.  }..  /* 
6a40: 41 6e 79 74 68 69 6e 67 20 65 6c 73 65 20 69 73  Anything else is
6a50: 20 61 6e 20 65 72 72 6f 72 20 2a 2f 0a 20 20 65   an error */.  e
6a60: 6c 73 65 7b 0a 20 20 20 20 61 73 73 65 72 74 28  lse{.    assert(
6a70: 30 29 3b 0a 20 20 20 20 72 65 74 75 72 6e 20 53  0);.    return S
6a80: 51 4c 49 54 45 5f 45 52 52 4f 52 3b 0a 20 20 7d  QLITE_ERROR;.  }
6a90: 0a 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49  ..  if( rc==SQLI
6aa0: 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 72 63 20  TE_OK ){.    rc 
6ab0: 3d 20 73 71 6c 69 74 65 33 5f 70 72 65 70 61 72  = sqlite3_prepar
6ac0: 65 28 64 62 2c 20 7a 2c 20 2d 31 2c 20 26 70 53  e(db, z, -1, &pS
6ad0: 74 6d 74 2c 20 30 29 3b 0a 20 20 7d 0a 20 20 61  tmt, 0);.  }.  a
6ae0: 73 73 65 72 74 28 20 72 63 21 3d 53 51 4c 49 54  ssert( rc!=SQLIT
6af0: 45 5f 4f 4b 20 7c 7c 20 70 53 74 6d 74 20 29 3b  E_OK || pStmt );
6b00: 0a 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28  .  sqlite3_free(
6b10: 7a 29 3b 0a 20 20 69 66 28 20 72 63 3d 3d 53 51  z);.  if( rc==SQ
6b20: 4c 49 54 45 5f 4f 4b 20 29 20 7b 0a 20 20 20 20  LITE_OK ) {.    
6b30: 69 66 28 20 62 69 6e 64 41 72 67 5a 65 72 6f 20  if( bindArgZero 
6b40: 29 7b 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33  ){.      sqlite3
6b50: 5f 62 69 6e 64 5f 76 61 6c 75 65 28 70 53 74 6d  _bind_value(pStm
6b60: 74 2c 20 6e 44 61 74 61 2c 20 61 70 44 61 74 61  t, nData, apData
6b70: 5b 30 5d 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20  [0]);.    }.    
6b80: 69 66 28 20 62 69 6e 64 41 72 67 4f 6e 65 20 29  if( bindArgOne )
6b90: 7b 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f  {.      sqlite3_
6ba0: 62 69 6e 64 5f 76 61 6c 75 65 28 70 53 74 6d 74  bind_value(pStmt
6bb0: 2c 20 31 2c 20 61 70 44 61 74 61 5b 31 5d 29 3b  , 1, apData[1]);
6bc0: 0a 20 20 20 20 7d 0a 20 20 20 20 66 6f 72 28 69  .    }.    for(i
6bd0: 3d 32 3b 20 69 3c 6e 44 61 74 61 20 26 26 20 72  =2; i<nData && r
6be0: 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 3b 20 69 2b  c==SQLITE_OK; i+
6bf0: 2b 29 7b 0a 20 20 20 20 20 20 69 66 28 20 61 70  +){.      if( ap
6c00: 44 61 74 61 5b 69 5d 20 29 20 72 63 20 3d 20 73  Data[i] ) rc = s
6c10: 71 6c 69 74 65 33 5f 62 69 6e 64 5f 76 61 6c 75  qlite3_bind_valu
6c20: 65 28 70 53 74 6d 74 2c 20 69 2c 20 61 70 44 61  e(pStmt, i, apDa
6c30: 74 61 5b 69 5d 29 3b 0a 20 20 20 20 7d 0a 20 20  ta[i]);.    }.  
6c40: 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
6c50: 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 73 71 6c  _OK ){.      sql
6c60: 69 74 65 33 5f 73 74 65 70 28 70 53 74 6d 74 29  ite3_step(pStmt)
6c70: 3b 0a 20 20 20 20 20 20 72 63 20 3d 20 73 71 6c  ;.      rc = sql
6c80: 69 74 65 33 5f 66 69 6e 61 6c 69 7a 65 28 70 53  ite3_finalize(pS
6c90: 74 6d 74 29 3b 0a 20 20 20 20 7d 65 6c 73 65 7b  tmt);.    }else{
6ca0: 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 66  .      sqlite3_f
6cb0: 69 6e 61 6c 69 7a 65 28 70 53 74 6d 74 29 3b 0a  inalize(pStmt);.
6cc0: 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 69 66 28      }.  }..  if(
6cd0: 20 70 52 6f 77 69 64 20 26 26 20 72 63 3d 3d 53   pRowid && rc==S
6ce0: 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
6cf0: 2a 70 52 6f 77 69 64 20 3d 20 73 71 6c 69 74 65  *pRowid = sqlite
6d00: 33 5f 6c 61 73 74 5f 69 6e 73 65 72 74 5f 72 6f  3_last_insert_ro
6d10: 77 69 64 28 64 62 29 3b 0a 20 20 7d 0a 0a 20 20  wid(db);.  }..  
6d20: 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a  return rc;.}../*
6d30: 0a 2a 2a 20 78 42 65 67 69 6e 2c 20 78 53 79 6e  .** xBegin, xSyn
6d40: 63 2c 20 78 43 6f 6d 6d 69 74 20 61 6e 64 20 78  c, xCommit and x
6d50: 52 6f 6c 6c 62 61 63 6b 20 63 61 6c 6c 62 61 63  Rollback callbac
6d60: 6b 73 20 66 6f 72 20 65 63 68 6f 20 6d 6f 64 75  ks for echo modu
6d70: 6c 65 0a 2a 2a 20 76 69 72 74 75 61 6c 20 74 61  le.** virtual ta
6d80: 62 6c 65 73 2e 20 44 6f 20 6e 6f 74 68 69 6e 67  bles. Do nothing
6d90: 20 6f 74 68 65 72 20 74 68 61 6e 20 61 64 64 20   other than add 
6da0: 74 68 65 20 6e 61 6d 65 20 6f 66 20 74 68 65 20  the name of the 
6db0: 63 61 6c 6c 62 61 63 6b 0a 2a 2a 20 74 6f 20 74  callback.** to t
6dc0: 68 65 20 24 3a 3a 65 63 68 6f 5f 6d 6f 64 75 6c  he $::echo_modul
6dd0: 65 20 54 63 6c 20 76 61 72 69 61 62 6c 65 2e 0a  e Tcl variable..
6de0: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 65 63  */.static int ec
6df0: 68 6f 54 72 61 6e 73 61 63 74 69 6f 6e 43 61 6c  hoTransactionCal
6e00: 6c 28 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a  l(sqlite3_vtab *
6e10: 74 61 62 2c 20 63 6f 6e 73 74 20 63 68 61 72 20  tab, const char 
6e20: 2a 7a 43 61 6c 6c 29 7b 0a 20 20 63 68 61 72 20  *zCall){.  char 
6e30: 2a 7a 3b 0a 20 20 65 63 68 6f 5f 76 74 61 62 20  *z;.  echo_vtab 
6e40: 2a 70 56 74 61 62 20 3d 20 28 65 63 68 6f 5f 76  *pVtab = (echo_v
6e50: 74 61 62 20 2a 29 74 61 62 3b 0a 20 20 7a 20 3d  tab *)tab;.  z =
6e60: 20 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66   sqlite3_mprintf
6e70: 28 22 65 63 68 6f 28 25 73 29 22 2c 20 70 56 74  ("echo(%s)", pVt
6e80: 61 62 2d 3e 7a 54 61 62 6c 65 4e 61 6d 65 29 3b  ab->zTableName);
6e90: 0a 20 20 69 66 28 20 7a 3d 3d 30 20 29 20 72 65  .  if( z==0 ) re
6ea0: 74 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45  turn SQLITE_NOME
6eb0: 4d 3b 0a 20 20 61 70 70 65 6e 64 54 6f 45 63 68  M;.  appendToEch
6ec0: 6f 4d 6f 64 75 6c 65 28 70 56 74 61 62 2d 3e 69  oModule(pVtab->i
6ed0: 6e 74 65 72 70 2c 20 7a 43 61 6c 6c 29 3b 0a 20  nterp, zCall);. 
6ee0: 20 61 70 70 65 6e 64 54 6f 45 63 68 6f 4d 6f 64   appendToEchoMod
6ef0: 75 6c 65 28 70 56 74 61 62 2d 3e 69 6e 74 65 72  ule(pVtab->inter
6f00: 70 2c 20 7a 29 3b 0a 20 20 73 71 6c 69 74 65 33  p, z);.  sqlite3
6f10: 5f 66 72 65 65 28 7a 29 3b 0a 20 20 72 65 74 75  _free(z);.  retu
6f20: 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a  rn SQLITE_OK;.}.
6f30: 73 74 61 74 69 63 20 69 6e 74 20 65 63 68 6f 42  static int echoB
6f40: 65 67 69 6e 28 73 71 6c 69 74 65 33 5f 76 74 61  egin(sqlite3_vta
6f50: 62 20 2a 74 61 62 29 7b 0a 20 20 69 6e 74 20 72  b *tab){.  int r
6f60: 63 3b 0a 20 20 65 63 68 6f 5f 76 74 61 62 20 2a  c;.  echo_vtab *
6f70: 70 56 74 61 62 20 3d 20 28 65 63 68 6f 5f 76 74  pVtab = (echo_vt
6f80: 61 62 20 2a 29 74 61 62 3b 0a 20 20 54 63 6c 5f  ab *)tab;.  Tcl_
6f90: 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 20 3d  Interp *interp =
6fa0: 20 70 56 74 61 62 2d 3e 69 6e 74 65 72 70 3b 0a   pVtab->interp;.
6fb0: 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 56    const char *zV
6fc0: 61 6c 3b 20 0a 0a 20 20 2f 2a 20 54 69 63 6b 65  al; ..  /* Ticke
6fd0: 74 20 23 33 30 38 33 20 2d 20 64 6f 20 6e 6f 74  t #3083 - do not
6fe0: 20 73 74 61 72 74 20 61 20 74 72 61 6e 73 61 63   start a transac
6ff0: 74 69 6f 6e 20 69 66 20 77 65 20 61 72 65 20 61  tion if we are a
7000: 6c 72 65 61 64 79 20 69 6e 0a 20 20 2a 2a 20 61  lready in.  ** a
7010: 20 74 72 61 6e 73 61 63 74 69 6f 6e 20 2a 2f 0a   transaction */.
7020: 20 20 61 73 73 65 72 74 28 20 21 70 56 74 61 62    assert( !pVtab
7030: 2d 3e 69 6e 54 72 61 6e 73 61 63 74 69 6f 6e 20  ->inTransaction 
7040: 29 3b 0a 0a 20 20 72 63 20 3d 20 65 63 68 6f 54  );..  rc = echoT
7050: 72 61 6e 73 61 63 74 69 6f 6e 43 61 6c 6c 28 74  ransactionCall(t
7060: 61 62 2c 20 22 78 42 65 67 69 6e 22 29 3b 0a 0a  ab, "xBegin");..
7070: 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
7080: 5f 4f 4b 20 29 7b 0a 20 20 20 20 2f 2a 20 43 68  _OK ){.    /* Ch
7090: 65 63 6b 20 69 66 20 74 68 65 20 24 3a 3a 65 63  eck if the $::ec
70a0: 68 6f 5f 6d 6f 64 75 6c 65 5f 62 65 67 69 6e 5f  ho_module_begin_
70b0: 66 61 69 6c 20 76 61 72 69 61 62 6c 65 20 69 73  fail variable is
70c0: 20 64 65 66 69 6e 65 64 2e 20 49 66 20 69 74 20   defined. If it 
70d0: 69 73 2c 0a 20 20 20 20 2a 2a 20 61 6e 64 20 69  is,.    ** and i
70e0: 74 20 69 73 20 73 65 74 20 74 6f 20 74 68 65 20  t is set to the 
70f0: 6e 61 6d 65 20 6f 66 20 74 68 65 20 72 65 61 6c  name of the real
7100: 20 74 61 62 6c 65 20 75 6e 64 65 72 6c 79 69 6e   table underlyin
7110: 67 20 74 68 69 73 20 76 69 72 74 75 61 6c 0a 20  g this virtual. 
7120: 20 20 20 2a 2a 20 65 63 68 6f 20 6d 6f 64 75 6c     ** echo modul
7130: 65 20 74 61 62 6c 65 2c 20 74 68 65 6e 20 63 61  e table, then ca
7140: 75 73 65 20 74 68 69 73 20 78 53 79 6e 63 20 6f  use this xSync o
7150: 70 65 72 61 74 69 6f 6e 20 74 6f 20 66 61 69 6c  peration to fail
7160: 2e 0a 20 20 20 20 2a 2f 0a 20 20 20 20 7a 56 61  ..    */.    zVa
7170: 6c 20 3d 20 54 63 6c 5f 47 65 74 56 61 72 28 69  l = Tcl_GetVar(i
7180: 6e 74 65 72 70 2c 20 22 65 63 68 6f 5f 6d 6f 64  nterp, "echo_mod
7190: 75 6c 65 5f 62 65 67 69 6e 5f 66 61 69 6c 22 2c  ule_begin_fail",
71a0: 20 54 43 4c 5f 47 4c 4f 42 41 4c 5f 4f 4e 4c 59   TCL_GLOBAL_ONLY
71b0: 29 3b 0a 20 20 20 20 69 66 28 20 7a 56 61 6c 20  );.    if( zVal 
71c0: 26 26 20 30 3d 3d 73 74 72 63 6d 70 28 7a 56 61  && 0==strcmp(zVa
71d0: 6c 2c 20 70 56 74 61 62 2d 3e 7a 54 61 62 6c 65  l, pVtab->zTable
71e0: 4e 61 6d 65 29 20 29 7b 0a 20 20 20 20 20 20 72  Name) ){.      r
71f0: 63 20 3d 20 53 51 4c 49 54 45 5f 45 52 52 4f 52  c = SQLITE_ERROR
7200: 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 69 66  ;.    }.  }.  if
7210: 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
7220: 29 7b 0a 20 20 20 20 70 56 74 61 62 2d 3e 69 6e  ){.    pVtab->in
7230: 54 72 61 6e 73 61 63 74 69 6f 6e 20 3d 20 31 3b  Transaction = 1;
7240: 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 72 63  .  }.  return rc
7250: 3b 0a 7d 0a 73 74 61 74 69 63 20 69 6e 74 20 65  ;.}.static int e
7260: 63 68 6f 53 79 6e 63 28 73 71 6c 69 74 65 33 5f  choSync(sqlite3_
7270: 76 74 61 62 20 2a 74 61 62 29 7b 0a 20 20 69 6e  vtab *tab){.  in
7280: 74 20 72 63 3b 0a 20 20 65 63 68 6f 5f 76 74 61  t rc;.  echo_vta
7290: 62 20 2a 70 56 74 61 62 20 3d 20 28 65 63 68 6f  b *pVtab = (echo
72a0: 5f 76 74 61 62 20 2a 29 74 61 62 3b 0a 20 20 54  _vtab *)tab;.  T
72b0: 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72  cl_Interp *inter
72c0: 70 20 3d 20 70 56 74 61 62 2d 3e 69 6e 74 65 72  p = pVtab->inter
72d0: 70 3b 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20  p;.  const char 
72e0: 2a 7a 56 61 6c 3b 20 0a 0a 20 20 2f 2a 20 54 69  *zVal; ..  /* Ti
72f0: 63 6b 65 74 20 23 33 30 38 33 20 2d 20 4f 6e 6c  cket #3083 - Onl
7300: 79 20 63 61 6c 6c 20 78 53 79 6e 63 20 69 66 20  y call xSync if 
7310: 77 65 20 68 61 76 65 20 70 72 65 76 69 6f 75 73  we have previous
7320: 6c 79 20 73 74 61 72 74 65 64 20 61 0a 20 20 2a  ly started a.  *
7330: 2a 20 74 72 61 6e 73 61 63 74 69 6f 6e 20 2a 2f  * transaction */
7340: 0a 20 20 61 73 73 65 72 74 28 20 70 56 74 61 62  .  assert( pVtab
7350: 2d 3e 69 6e 54 72 61 6e 73 61 63 74 69 6f 6e 20  ->inTransaction 
7360: 29 3b 0a 0a 20 20 72 63 20 3d 20 65 63 68 6f 54  );..  rc = echoT
7370: 72 61 6e 73 61 63 74 69 6f 6e 43 61 6c 6c 28 74  ransactionCall(t
7380: 61 62 2c 20 22 78 53 79 6e 63 22 29 3b 0a 0a 20  ab, "xSync");.. 
7390: 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
73a0: 4f 4b 20 29 7b 0a 20 20 20 20 2f 2a 20 43 68 65  OK ){.    /* Che
73b0: 63 6b 20 69 66 20 74 68 65 20 24 3a 3a 65 63 68  ck if the $::ech
73c0: 6f 5f 6d 6f 64 75 6c 65 5f 73 79 6e 63 5f 66 61  o_module_sync_fa
73d0: 69 6c 20 76 61 72 69 61 62 6c 65 20 69 73 20 64  il variable is d
73e0: 65 66 69 6e 65 64 2e 20 49 66 20 69 74 20 69 73  efined. If it is
73f0: 2c 0a 20 20 20 20 2a 2a 20 61 6e 64 20 69 74 20  ,.    ** and it 
7400: 69 73 20 73 65 74 20 74 6f 20 74 68 65 20 6e 61  is set to the na
7410: 6d 65 20 6f 66 20 74 68 65 20 72 65 61 6c 20 74  me of the real t
7420: 61 62 6c 65 20 75 6e 64 65 72 6c 79 69 6e 67 20  able underlying 
7430: 74 68 69 73 20 76 69 72 74 75 61 6c 0a 20 20 20  this virtual.   
7440: 20 2a 2a 20 65 63 68 6f 20 6d 6f 64 75 6c 65 20   ** echo module 
7450: 74 61 62 6c 65 2c 20 74 68 65 6e 20 63 61 75 73  table, then caus
7460: 65 20 74 68 69 73 20 78 53 79 6e 63 20 6f 70 65  e this xSync ope
7470: 72 61 74 69 6f 6e 20 74 6f 20 66 61 69 6c 2e 0a  ration to fail..
7480: 20 20 20 20 2a 2f 0a 20 20 20 20 7a 56 61 6c 20      */.    zVal 
7490: 3d 20 54 63 6c 5f 47 65 74 56 61 72 28 69 6e 74  = Tcl_GetVar(int
74a0: 65 72 70 2c 20 22 65 63 68 6f 5f 6d 6f 64 75 6c  erp, "echo_modul
74b0: 65 5f 73 79 6e 63 5f 66 61 69 6c 22 2c 20 54 43  e_sync_fail", TC
74c0: 4c 5f 47 4c 4f 42 41 4c 5f 4f 4e 4c 59 29 3b 0a  L_GLOBAL_ONLY);.
74d0: 20 20 20 20 69 66 28 20 7a 56 61 6c 20 26 26 20      if( zVal && 
74e0: 30 3d 3d 73 74 72 63 6d 70 28 7a 56 61 6c 2c 20  0==strcmp(zVal, 
74f0: 70 56 74 61 62 2d 3e 7a 54 61 62 6c 65 4e 61 6d  pVtab->zTableNam
7500: 65 29 20 29 7b 0a 20 20 20 20 20 20 72 63 20 3d  e) ){.      rc =
7510: 20 2d 31 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20   -1;.    }.  }. 
7520: 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 73 74   return rc;.}.st
7530: 61 74 69 63 20 69 6e 74 20 65 63 68 6f 43 6f 6d  atic int echoCom
7540: 6d 69 74 28 73 71 6c 69 74 65 33 5f 76 74 61 62  mit(sqlite3_vtab
7550: 20 2a 74 61 62 29 7b 0a 20 20 65 63 68 6f 5f 76   *tab){.  echo_v
7560: 74 61 62 20 2a 70 56 74 61 62 20 3d 20 28 65 63  tab *pVtab = (ec
7570: 68 6f 5f 76 74 61 62 2a 29 74 61 62 3b 0a 20 20  ho_vtab*)tab;.  
7580: 69 6e 74 20 72 63 3b 0a 0a 20 20 2f 2a 20 54 69  int rc;..  /* Ti
7590: 63 6b 65 74 20 23 33 30 38 33 20 2d 20 4f 6e 6c  cket #3083 - Onl
75a0: 79 20 63 61 6c 6c 20 78 43 6f 6d 6d 69 74 20 69  y call xCommit i
75b0: 66 20 77 65 20 68 61 76 65 20 70 72 65 76 69 6f  f we have previo
75c0: 75 73 6c 79 20 73 74 61 72 74 65 64 0a 20 20 2a  usly started.  *
75d0: 2a 20 61 20 74 72 61 6e 73 61 63 74 69 6f 6e 20  * a transaction 
75e0: 2a 2f 0a 20 20 61 73 73 65 72 74 28 20 70 56 74  */.  assert( pVt
75f0: 61 62 2d 3e 69 6e 54 72 61 6e 73 61 63 74 69 6f  ab->inTransactio
7600: 6e 20 29 3b 0a 0a 20 20 73 71 6c 69 74 65 33 46  n );..  sqlite3F
7610: 61 75 6c 74 42 65 6e 69 67 6e 28 53 51 4c 49 54  aultBenign(SQLIT
7620: 45 5f 46 41 55 4c 54 49 4e 4a 45 43 54 4f 52 5f  E_FAULTINJECTOR_
7630: 4d 41 4c 4c 4f 43 2c 20 31 29 3b 0a 20 20 72 63  MALLOC, 1);.  rc
7640: 20 3d 20 65 63 68 6f 54 72 61 6e 73 61 63 74 69   = echoTransacti
7650: 6f 6e 43 61 6c 6c 28 74 61 62 2c 20 22 78 43 6f  onCall(tab, "xCo
7660: 6d 6d 69 74 22 29 3b 0a 20 20 73 71 6c 69 74 65  mmit");.  sqlite
7670: 33 46 61 75 6c 74 42 65 6e 69 67 6e 28 53 51 4c  3FaultBenign(SQL
7680: 49 54 45 5f 46 41 55 4c 54 49 4e 4a 45 43 54 4f  ITE_FAULTINJECTO
7690: 52 5f 4d 41 4c 4c 4f 43 2c 20 30 29 3b 0a 20 20  R_MALLOC, 0);.  
76a0: 70 56 74 61 62 2d 3e 69 6e 54 72 61 6e 73 61 63  pVtab->inTransac
76b0: 74 69 6f 6e 20 3d 20 30 3b 0a 20 20 72 65 74 75  tion = 0;.  retu
76c0: 72 6e 20 72 63 3b 0a 7d 0a 73 74 61 74 69 63 20  rn rc;.}.static 
76d0: 69 6e 74 20 65 63 68 6f 52 6f 6c 6c 62 61 63 6b  int echoRollback
76e0: 28 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 74  (sqlite3_vtab *t
76f0: 61 62 29 7b 0a 20 20 69 6e 74 20 72 63 3b 0a 20  ab){.  int rc;. 
7700: 20 65 63 68 6f 5f 76 74 61 62 20 2a 70 56 74 61   echo_vtab *pVta
7710: 62 20 3d 20 28 65 63 68 6f 5f 76 74 61 62 2a 29  b = (echo_vtab*)
7720: 74 61 62 3b 0a 0a 20 20 2f 2a 20 54 69 63 6b 65  tab;..  /* Ticke
7730: 74 20 23 33 30 38 33 20 2d 20 4f 6e 6c 79 20 63  t #3083 - Only c
7740: 61 6c 6c 20 78 52 6f 6c 6c 62 61 63 6b 20 69 66  all xRollback if
7750: 20 77 65 20 68 61 76 65 20 70 72 65 76 69 6f 75   we have previou
7760: 73 6c 79 20 73 74 61 72 74 65 64 0a 20 20 2a 2a  sly started.  **
7770: 20 61 20 74 72 61 6e 73 61 63 74 69 6f 6e 20 2a   a transaction *
7780: 2f 0a 20 20 61 73 73 65 72 74 28 20 70 56 74 61  /.  assert( pVta
7790: 62 2d 3e 69 6e 54 72 61 6e 73 61 63 74 69 6f 6e  b->inTransaction
77a0: 20 29 3b 0a 0a 20 20 72 63 20 3d 20 65 63 68 6f   );..  rc = echo
77b0: 54 72 61 6e 73 61 63 74 69 6f 6e 43 61 6c 6c 28  TransactionCall(
77c0: 74 61 62 2c 20 22 78 52 6f 6c 6c 62 61 63 6b 22  tab, "xRollback"
77d0: 29 3b 0a 20 20 70 56 74 61 62 2d 3e 69 6e 54 72  );.  pVtab->inTr
77e0: 61 6e 73 61 63 74 69 6f 6e 20 3d 20 30 3b 0a 20  ansaction = 0;. 
77f0: 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f   return rc;.}../
7800: 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74 61 74  *.** Implementat
7810: 69 6f 6e 20 6f 66 20 22 47 4c 4f 42 22 20 66 75  ion of "GLOB" fu
7820: 6e 63 74 69 6f 6e 20 6f 6e 20 74 68 65 20 65 63  nction on the ec
7830: 68 6f 20 6d 6f 64 75 6c 65 2e 20 20 50 61 73 73  ho module.  Pass
7840: 0a 2a 2a 20 61 6c 6c 20 61 72 67 75 6d 65 6e 74  .** all argument
7850: 73 20 74 6f 20 74 68 65 20 3a 3a 65 63 68 6f 5f  s to the ::echo_
7860: 67 6c 6f 62 5f 6f 76 65 72 6c 6f 61 64 20 70 72  glob_overload pr
7870: 6f 63 65 64 75 72 65 20 6f 66 20 54 43 4c 0a 2a  ocedure of TCL.*
7880: 2a 20 61 6e 64 20 72 65 74 75 72 6e 20 74 68 65  * and return the
7890: 20 72 65 73 75 6c 74 20 6f 66 20 74 68 61 74 20   result of that 
78a0: 70 72 6f 63 65 64 75 72 65 20 61 73 20 61 20 73  procedure as a s
78b0: 74 72 69 6e 67 2e 0a 2a 2f 0a 73 74 61 74 69 63  tring..*/.static
78c0: 20 76 6f 69 64 20 6f 76 65 72 6c 6f 61 64 65 64   void overloaded
78d0: 47 6c 6f 62 46 75 6e 63 74 69 6f 6e 28 0a 20 20  GlobFunction(.  
78e0: 73 71 6c 69 74 65 33 5f 63 6f 6e 74 65 78 74 20  sqlite3_context 
78f0: 2a 70 43 6f 6e 74 65 78 74 2c 0a 20 20 69 6e 74  *pContext,.  int
7900: 20 6e 41 72 67 2c 0a 20 20 73 71 6c 69 74 65 33   nArg,.  sqlite3
7910: 5f 76 61 6c 75 65 20 2a 2a 61 70 41 72 67 0a 29  _value **apArg.)
7920: 7b 0a 20 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a  {.  Tcl_Interp *
7930: 69 6e 74 65 72 70 20 3d 20 73 71 6c 69 74 65 33  interp = sqlite3
7940: 5f 75 73 65 72 5f 64 61 74 61 28 70 43 6f 6e 74  _user_data(pCont
7950: 65 78 74 29 3b 0a 20 20 54 63 6c 5f 44 53 74 72  ext);.  Tcl_DStr
7960: 69 6e 67 20 73 74 72 3b 0a 20 20 69 6e 74 20 69  ing str;.  int i
7970: 3b 0a 20 20 69 6e 74 20 72 63 3b 0a 20 20 54 63  ;.  int rc;.  Tc
7980: 6c 5f 44 53 74 72 69 6e 67 49 6e 69 74 28 26 73  l_DStringInit(&s
7990: 74 72 29 3b 0a 20 20 54 63 6c 5f 44 53 74 72 69  tr);.  Tcl_DStri
79a0: 6e 67 41 70 70 65 6e 64 45 6c 65 6d 65 6e 74 28  ngAppendElement(
79b0: 26 73 74 72 2c 20 22 3a 3a 65 63 68 6f 5f 67 6c  &str, "::echo_gl
79c0: 6f 62 5f 6f 76 65 72 6c 6f 61 64 22 29 3b 0a 20  ob_overload");. 
79d0: 20 66 6f 72 28 69 3d 30 3b 20 69 3c 6e 41 72 67   for(i=0; i<nArg
79e0: 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 54 63 6c 5f  ; i++){.    Tcl_
79f0: 44 53 74 72 69 6e 67 41 70 70 65 6e 64 45 6c 65  DStringAppendEle
7a00: 6d 65 6e 74 28 26 73 74 72 2c 20 28 63 68 61 72  ment(&str, (char
7a10: 2a 29 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f  *)sqlite3_value_
7a20: 74 65 78 74 28 61 70 41 72 67 5b 69 5d 29 29 3b  text(apArg[i]));
7a30: 0a 20 20 7d 0a 20 20 72 63 20 3d 20 54 63 6c 5f  .  }.  rc = Tcl_
7a40: 45 76 61 6c 28 69 6e 74 65 72 70 2c 20 54 63 6c  Eval(interp, Tcl
7a50: 5f 44 53 74 72 69 6e 67 56 61 6c 75 65 28 26 73  _DStringValue(&s
7a60: 74 72 29 29 3b 0a 20 20 54 63 6c 5f 44 53 74 72  tr));.  Tcl_DStr
7a70: 69 6e 67 46 72 65 65 28 26 73 74 72 29 3b 0a 20  ingFree(&str);. 
7a80: 20 69 66 28 20 72 63 20 29 7b 0a 20 20 20 20 73   if( rc ){.    s
7a90: 71 6c 69 74 65 33 5f 72 65 73 75 6c 74 5f 65 72  qlite3_result_er
7aa0: 72 6f 72 28 70 43 6f 6e 74 65 78 74 2c 20 54 63  ror(pContext, Tc
7ab0: 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c  l_GetStringResul
7ac0: 74 28 69 6e 74 65 72 70 29 2c 20 2d 31 29 3b 0a  t(interp), -1);.
7ad0: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 73 71 6c    }else{.    sql
7ae0: 69 74 65 33 5f 72 65 73 75 6c 74 5f 74 65 78 74  ite3_result_text
7af0: 28 70 43 6f 6e 74 65 78 74 2c 20 54 63 6c 5f 47  (pContext, Tcl_G
7b00: 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69  etStringResult(i
7b10: 6e 74 65 72 70 29 2c 0a 20 20 20 20 20 20 20 20  nterp),.        
7b20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7b30: 2d 31 2c 20 53 51 4c 49 54 45 5f 54 52 41 4e 53  -1, SQLITE_TRANS
7b40: 49 45 4e 54 29 3b 0a 20 20 7d 0a 20 20 54 63 6c  IENT);.  }.  Tcl
7b50: 5f 52 65 73 65 74 52 65 73 75 6c 74 28 69 6e 74  _ResetResult(int
7b60: 65 72 70 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54  erp);.}../*.** T
7b70: 68 69 73 20 69 73 20 74 68 65 20 78 46 69 6e 64  his is the xFind
7b80: 46 75 6e 63 74 69 6f 6e 20 69 6d 70 6c 65 6d 65  Function impleme
7b90: 6e 74 61 74 69 6f 6e 20 66 6f 72 20 74 68 65 20  ntation for the 
7ba0: 65 63 68 6f 20 6d 6f 64 75 6c 65 2e 0a 2a 2a 20  echo module..** 
7bb0: 53 51 4c 69 74 65 20 63 61 6c 6c 73 20 74 68 69  SQLite calls thi
7bc0: 73 20 72 6f 75 74 69 6e 65 20 77 68 65 6e 20 74  s routine when t
7bd0: 68 65 20 66 69 72 73 74 20 61 72 67 75 6d 65 6e  he first argumen
7be0: 74 20 6f 66 20 61 20 66 75 6e 63 74 69 6f 6e 0a  t of a function.
7bf0: 2a 2a 20 69 73 20 61 20 63 6f 6c 75 6d 6e 20 6f  ** is a column o
7c00: 66 20 61 6e 20 65 63 68 6f 20 76 69 72 74 75 61  f an echo virtua
7c10: 6c 20 74 61 62 6c 65 2e 20 20 54 68 69 73 20 72  l table.  This r
7c20: 6f 75 74 69 6e 65 20 63 61 6e 20 6f 70 74 69 6f  outine can optio
7c30: 6e 61 6c 6c 79 0a 2a 2a 20 6f 76 65 72 72 69 64  nally.** overrid
7c40: 65 20 74 68 65 20 69 6d 70 6c 65 6d 65 6e 74 61  e the implementa
7c50: 74 69 6f 6e 20 6f 66 20 74 68 61 74 20 66 75 6e  tion of that fun
7c60: 63 74 69 6f 6e 2e 20 20 49 74 20 77 69 6c 6c 20  ction.  It will 
7c70: 63 68 6f 6f 73 65 20 74 6f 0a 2a 2a 20 64 6f 20  choose to.** do 
7c80: 73 6f 20 69 66 20 74 68 65 20 66 75 6e 63 74 69  so if the functi
7c90: 6f 6e 20 69 73 20 6e 61 6d 65 64 20 22 67 6c 6f  on is named "glo
7ca0: 62 22 2c 20 61 6e 64 20 61 20 54 43 4c 20 63 6f  b", and a TCL co
7cb0: 6d 6d 61 6e 64 20 6e 61 6d 65 64 0a 2a 2a 20 3a  mmand named.** :
7cc0: 3a 65 63 68 6f 5f 67 6c 6f 62 5f 6f 76 65 72 6c  :echo_glob_overl
7cd0: 6f 61 64 20 65 78 69 73 74 73 2e 0a 2a 2f 0a 73  oad exists..*/.s
7ce0: 74 61 74 69 63 20 69 6e 74 20 65 63 68 6f 46 69  tatic int echoFi
7cf0: 6e 64 46 75 6e 63 74 69 6f 6e 28 0a 20 20 73 71  ndFunction(.  sq
7d00: 6c 69 74 65 33 5f 76 74 61 62 20 2a 76 74 61 62  lite3_vtab *vtab
7d10: 2c 0a 20 20 69 6e 74 20 6e 41 72 67 2c 0a 20 20  ,.  int nArg,.  
7d20: 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 46 75 6e  const char *zFun
7d30: 63 4e 61 6d 65 2c 0a 20 20 76 6f 69 64 20 28 2a  cName,.  void (*
7d40: 2a 70 78 46 75 6e 63 29 28 73 71 6c 69 74 65 33  *pxFunc)(sqlite3
7d50: 5f 63 6f 6e 74 65 78 74 2a 2c 69 6e 74 2c 73 71  _context*,int,sq
7d60: 6c 69 74 65 33 5f 76 61 6c 75 65 2a 2a 29 2c 0a  lite3_value**),.
7d70: 20 20 76 6f 69 64 20 2a 2a 70 70 41 72 67 0a 29    void **ppArg.)
7d80: 7b 0a 20 20 65 63 68 6f 5f 76 74 61 62 20 2a 70  {.  echo_vtab *p
7d90: 56 74 61 62 20 3d 20 28 65 63 68 6f 5f 76 74 61  Vtab = (echo_vta
7da0: 62 20 2a 29 76 74 61 62 3b 0a 20 20 54 63 6c 5f  b *)vtab;.  Tcl_
7db0: 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 20 3d  Interp *interp =
7dc0: 20 70 56 74 61 62 2d 3e 69 6e 74 65 72 70 3b 0a   pVtab->interp;.
7dd0: 20 20 54 63 6c 5f 43 6d 64 49 6e 66 6f 20 69 6e    Tcl_CmdInfo in
7de0: 66 6f 3b 0a 20 20 69 66 28 20 73 74 72 63 6d 70  fo;.  if( strcmp
7df0: 28 7a 46 75 6e 63 4e 61 6d 65 2c 22 67 6c 6f 62  (zFuncName,"glob
7e00: 22 29 21 3d 30 20 29 7b 0a 20 20 20 20 72 65 74  ")!=0 ){.    ret
7e10: 75 72 6e 20 30 3b 0a 20 20 7d 0a 20 20 69 66 28  urn 0;.  }.  if(
7e20: 20 54 63 6c 5f 47 65 74 43 6f 6d 6d 61 6e 64 49   Tcl_GetCommandI
7e30: 6e 66 6f 28 69 6e 74 65 72 70 2c 20 22 3a 3a 65  nfo(interp, "::e
7e40: 63 68 6f 5f 67 6c 6f 62 5f 6f 76 65 72 6c 6f 61  cho_glob_overloa
7e50: 64 22 2c 20 26 69 6e 66 6f 29 3d 3d 30 20 29 7b  d", &info)==0 ){
7e60: 0a 20 20 20 20 72 65 74 75 72 6e 20 30 3b 0a 20  .    return 0;. 
7e70: 20 7d 0a 20 20 2a 70 78 46 75 6e 63 20 3d 20 6f   }.  *pxFunc = o
7e80: 76 65 72 6c 6f 61 64 65 64 47 6c 6f 62 46 75 6e  verloadedGlobFun
7e90: 63 74 69 6f 6e 3b 0a 20 20 2a 70 70 41 72 67 20  ction;.  *ppArg 
7ea0: 3d 20 69 6e 74 65 72 70 3b 0a 20 20 72 65 74 75  = interp;.  retu
7eb0: 72 6e 20 31 3b 0a 7d 0a 0a 73 74 61 74 69 63 20  rn 1;.}..static 
7ec0: 69 6e 74 20 65 63 68 6f 52 65 6e 61 6d 65 28 73  int echoRename(s
7ed0: 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 76 74 61  qlite3_vtab *vta
7ee0: 62 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a  b, const char *z
7ef0: 4e 65 77 4e 61 6d 65 29 7b 0a 20 20 69 6e 74 20  NewName){.  int 
7f00: 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a  rc = SQLITE_OK;.
7f10: 20 20 65 63 68 6f 5f 76 74 61 62 20 2a 70 20 3d    echo_vtab *p =
7f20: 20 28 65 63 68 6f 5f 76 74 61 62 20 2a 29 76 74   (echo_vtab *)vt
7f30: 61 62 3b 0a 0a 20 20 69 66 28 20 70 2d 3e 69 73  ab;..  if( p->is
7f40: 50 61 74 74 65 72 6e 20 29 7b 0a 20 20 20 20 69  Pattern ){.    i
7f50: 6e 74 20 6e 54 68 69 73 20 3d 20 73 74 72 6c 65  nt nThis = strle
7f60: 6e 28 70 2d 3e 7a 54 68 69 73 29 3b 0a 20 20 20  n(p->zThis);.   
7f70: 20 63 68 61 72 20 2a 7a 53 71 6c 20 3d 20 73 71   char *zSql = sq
7f80: 6c 69 74 65 33 4d 50 72 69 6e 74 66 28 30 2c 20  lite3MPrintf(0, 
7f90: 22 41 4c 54 45 52 20 54 41 42 4c 45 20 25 73 20  "ALTER TABLE %s 
7fa0: 52 45 4e 41 4d 45 20 54 4f 20 25 73 25 73 22 2c  RENAME TO %s%s",
7fb0: 20 0a 20 20 20 20 20 20 20 20 70 2d 3e 7a 54 61   .        p->zTa
7fc0: 62 6c 65 4e 61 6d 65 2c 20 7a 4e 65 77 4e 61 6d  bleName, zNewNam
7fd0: 65 2c 20 26 70 2d 3e 7a 54 61 62 6c 65 4e 61 6d  e, &p->zTableNam
7fe0: 65 5b 6e 54 68 69 73 5d 0a 20 20 20 20 29 3b 0a  e[nThis].    );.
7ff0: 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33      rc = sqlite3
8000: 5f 65 78 65 63 28 70 2d 3e 64 62 2c 20 7a 53 71  _exec(p->db, zSq
8010: 6c 2c 20 30 2c 20 30 2c 20 30 29 3b 0a 20 20 20  l, 0, 0, 0);.   
8020: 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 7a 53   sqlite3_free(zS
8030: 71 6c 29 3b 0a 20 20 7d 0a 0a 20 20 72 65 74 75  ql);.  }..  retu
8040: 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  rn rc;.}../*.** 
8050: 41 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65 20  A virtual table 
8060: 6d 6f 64 75 6c 65 20 74 68 61 74 20 6d 65 72 65  module that mere
8070: 6c 79 20 22 65 63 68 6f 73 22 20 74 68 65 20 63  ly "echos" the c
8080: 6f 6e 74 65 6e 74 73 20 6f 66 20 61 6e 6f 74 68  ontents of anoth
8090: 65 72 0a 2a 2a 20 74 61 62 6c 65 20 28 6c 69 6b  er.** table (lik
80a0: 65 20 61 6e 20 53 51 4c 20 56 49 45 57 29 2e 0a  e an SQL VIEW)..
80b0: 2a 2f 0a 73 74 61 74 69 63 20 73 71 6c 69 74 65  */.static sqlite
80c0: 33 5f 6d 6f 64 75 6c 65 20 65 63 68 6f 4d 6f 64  3_module echoMod
80d0: 75 6c 65 20 3d 20 7b 0a 20 20 30 2c 20 20 20 20  ule = {.  0,    
80e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
80f0: 20 20 20 20 20 2f 2a 20 69 56 65 72 73 69 6f 6e       /* iVersion
8100: 20 2a 2f 0a 20 20 65 63 68 6f 43 72 65 61 74 65   */.  echoCreate
8110: 2c 0a 20 20 65 63 68 6f 43 6f 6e 6e 65 63 74 2c  ,.  echoConnect,
8120: 0a 20 20 65 63 68 6f 42 65 73 74 49 6e 64 65 78  .  echoBestIndex
8130: 2c 0a 20 20 65 63 68 6f 44 69 73 63 6f 6e 6e 65  ,.  echoDisconne
8140: 63 74 2c 20 0a 20 20 65 63 68 6f 44 65 73 74 72  ct, .  echoDestr
8150: 6f 79 2c 0a 20 20 65 63 68 6f 4f 70 65 6e 2c 20  oy,.  echoOpen, 
8160: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8170: 20 2f 2a 20 78 4f 70 65 6e 20 2d 20 6f 70 65 6e   /* xOpen - open
8180: 20 61 20 63 75 72 73 6f 72 20 2a 2f 0a 20 20 65   a cursor */.  e
8190: 63 68 6f 43 6c 6f 73 65 2c 20 20 20 20 20 20 20  choClose,       
81a0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 43 6c            /* xCl
81b0: 6f 73 65 20 2d 20 63 6c 6f 73 65 20 61 20 63 75  ose - close a cu
81c0: 72 73 6f 72 20 2a 2f 0a 20 20 65 63 68 6f 46 69  rsor */.  echoFi
81d0: 6c 74 65 72 2c 20 20 20 20 20 20 20 20 20 20 20  lter,           
81e0: 20 20 20 20 20 2f 2a 20 78 46 69 6c 74 65 72 20       /* xFilter 
81f0: 2d 20 63 6f 6e 66 69 67 75 72 65 20 73 63 61 6e  - configure scan
8200: 20 63 6f 6e 73 74 72 61 69 6e 74 73 20 2a 2f 0a   constraints */.
8210: 20 20 65 63 68 6f 4e 65 78 74 2c 20 20 20 20 20    echoNext,     
8220: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
8230: 78 4e 65 78 74 20 2d 20 61 64 76 61 6e 63 65 20  xNext - advance 
8240: 61 20 63 75 72 73 6f 72 20 2a 2f 0a 20 20 65 63  a cursor */.  ec
8250: 68 6f 45 6f 66 2c 20 20 20 20 20 20 20 20 20 20  hoEof,          
8260: 20 20 20 20 20 20 20 20 20 2f 2a 20 78 45 6f 66           /* xEof
8270: 20 2a 2f 0a 20 20 65 63 68 6f 43 6f 6c 75 6d 6e   */.  echoColumn
8280: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
8290: 20 2f 2a 20 78 43 6f 6c 75 6d 6e 20 2d 20 72 65   /* xColumn - re
82a0: 61 64 20 64 61 74 61 20 2a 2f 0a 20 20 65 63 68  ad data */.  ech
82b0: 6f 52 6f 77 69 64 2c 20 20 20 20 20 20 20 20 20  oRowid,         
82c0: 20 20 20 20 20 20 20 20 2f 2a 20 78 52 6f 77 69          /* xRowi
82d0: 64 20 2d 20 72 65 61 64 20 64 61 74 61 20 2a 2f  d - read data */
82e0: 0a 20 20 65 63 68 6f 55 70 64 61 74 65 2c 20 20  .  echoUpdate,  
82f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
8300: 20 78 55 70 64 61 74 65 20 2d 20 77 72 69 74 65   xUpdate - write
8310: 20 64 61 74 61 20 2a 2f 0a 20 20 65 63 68 6f 42   data */.  echoB
8320: 65 67 69 6e 2c 20 20 20 20 20 20 20 20 20 20 20  egin,           
8330: 20 20 20 20 20 20 2f 2a 20 78 42 65 67 69 6e 20        /* xBegin 
8340: 2d 20 62 65 67 69 6e 20 74 72 61 6e 73 61 63 74  - begin transact
8350: 69 6f 6e 20 2a 2f 0a 20 20 65 63 68 6f 53 79 6e  ion */.  echoSyn
8360: 63 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  c,              
8370: 20 20 20 20 2f 2a 20 78 53 79 6e 63 20 2d 20 73      /* xSync - s
8380: 79 6e 63 20 74 72 61 6e 73 61 63 74 69 6f 6e 20  ync transaction 
8390: 2a 2f 0a 20 20 65 63 68 6f 43 6f 6d 6d 69 74 2c  */.  echoCommit,
83a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
83b0: 2f 2a 20 78 43 6f 6d 6d 69 74 20 2d 20 63 6f 6d  /* xCommit - com
83c0: 6d 69 74 20 74 72 61 6e 73 61 63 74 69 6f 6e 20  mit transaction 
83d0: 2a 2f 0a 20 20 65 63 68 6f 52 6f 6c 6c 62 61 63  */.  echoRollbac
83e0: 6b 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  k,              
83f0: 2f 2a 20 78 52 6f 6c 6c 62 61 63 6b 20 2d 20 72  /* xRollback - r
8400: 6f 6c 6c 62 61 63 6b 20 74 72 61 6e 73 61 63 74  ollback transact
8410: 69 6f 6e 20 2a 2f 0a 20 20 65 63 68 6f 46 69 6e  ion */.  echoFin
8420: 64 46 75 6e 63 74 69 6f 6e 2c 20 20 20 20 20 20  dFunction,      
8430: 20 20 20 20 2f 2a 20 78 46 69 6e 64 46 75 6e 63      /* xFindFunc
8440: 74 69 6f 6e 20 2d 20 66 75 6e 63 74 69 6f 6e 20  tion - function 
8450: 6f 76 65 72 6c 6f 61 64 69 6e 67 20 2a 2f 0a 20  overloading */. 
8460: 20 65 63 68 6f 52 65 6e 61 6d 65 2c 20 20 20 20   echoRename,    
8470: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78              /* x
8480: 52 65 6e 61 6d 65 20 2d 20 72 65 6e 61 6d 65 20  Rename - rename 
8490: 74 68 65 20 74 61 62 6c 65 20 2a 2f 0a 7d 3b 0a  the table */.};.
84a0: 0a 2f 2a 0a 2a 2a 20 44 65 63 6f 64 65 20 61 20  ./*.** Decode a 
84b0: 70 6f 69 6e 74 65 72 20 74 6f 20 61 6e 20 73 71  pointer to an sq
84c0: 6c 69 74 65 33 20 6f 62 6a 65 63 74 2e 0a 2a 2f  lite3 object..*/
84d0: 0a 73 74 61 74 69 63 20 69 6e 74 20 67 65 74 44  .static int getD
84e0: 62 50 6f 69 6e 74 65 72 28 54 63 6c 5f 49 6e 74  bPointer(Tcl_Int
84f0: 65 72 70 20 2a 69 6e 74 65 72 70 2c 20 63 6f 6e  erp *interp, con
8500: 73 74 20 63 68 61 72 20 2a 7a 41 2c 20 73 71 6c  st char *zA, sql
8510: 69 74 65 33 20 2a 2a 70 70 44 62 29 7b 0a 20 20  ite3 **ppDb){.  
8520: 2a 70 70 44 62 20 3d 20 28 73 71 6c 69 74 65 33  *ppDb = (sqlite3
8530: 2a 29 73 71 6c 69 74 65 33 54 65 78 74 54 6f 50  *)sqlite3TextToP
8540: 74 72 28 7a 41 29 3b 0a 20 20 72 65 74 75 72 6e  tr(zA);.  return
8550: 20 54 43 4c 5f 4f 4b 3b 0a 7d 0a 0a 73 74 61 74   TCL_OK;.}..stat
8560: 69 63 20 76 6f 69 64 20 6d 6f 64 75 6c 65 44 65  ic void moduleDe
8570: 73 74 72 6f 79 28 76 6f 69 64 20 2a 70 29 7b 0a  stroy(void *p){.
8580: 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70    sqlite3_free(p
8590: 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 67 69  );.}../*.** Regi
85a0: 73 74 65 72 20 74 68 65 20 65 63 68 6f 20 76 69  ster the echo vi
85b0: 72 74 75 61 6c 20 74 61 62 6c 65 20 6d 6f 64 75  rtual table modu
85c0: 6c 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  le..*/.static in
85d0: 74 20 72 65 67 69 73 74 65 72 5f 65 63 68 6f 5f  t register_echo_
85e0: 6d 6f 64 75 6c 65 28 0a 20 20 43 6c 69 65 6e 74  module(.  Client
85f0: 44 61 74 61 20 63 6c 69 65 6e 74 44 61 74 61 2c  Data clientData,
8600: 20 2f 2a 20 50 6f 69 6e 74 65 72 20 74 6f 20 73   /* Pointer to s
8610: 71 6c 69 74 65 33 5f 65 6e 61 62 6c 65 5f 58 58  qlite3_enable_XX
8620: 58 20 66 75 6e 63 74 69 6f 6e 20 2a 2f 0a 20 20  X function */.  
8630: 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65  Tcl_Interp *inte
8640: 72 70 2c 20 20 20 20 2f 2a 20 54 68 65 20 54 43  rp,    /* The TC
8650: 4c 20 69 6e 74 65 72 70 72 65 74 65 72 20 74 68  L interpreter th
8660: 61 74 20 69 6e 76 6f 6b 65 64 20 74 68 69 73 20  at invoked this 
8670: 63 6f 6d 6d 61 6e 64 20 2a 2f 0a 20 20 69 6e 74  command */.  int
8680: 20 6f 62 6a 63 2c 20 20 20 20 20 20 20 20 20 20   objc,          
8690: 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66      /* Number of
86a0: 20 61 72 67 75 6d 65 6e 74 73 20 2a 2f 0a 20 20   arguments */.  
86b0: 54 63 6c 5f 4f 62 6a 20 2a 43 4f 4e 53 54 20 6f  Tcl_Obj *CONST o
86c0: 62 6a 76 5b 5d 20 20 2f 2a 20 43 6f 6d 6d 61 6e  bjv[]  /* Comman
86d0: 64 20 61 72 67 75 6d 65 6e 74 73 20 2a 2f 0a 29  d arguments */.)
86e0: 7b 0a 20 20 73 71 6c 69 74 65 33 20 2a 64 62 3b  {.  sqlite3 *db;
86f0: 0a 20 20 45 63 68 6f 4d 6f 64 75 6c 65 20 2a 70  .  EchoModule *p
8700: 4d 6f 64 3b 0a 20 20 69 66 28 20 6f 62 6a 63 21  Mod;.  if( objc!
8710: 3d 32 20 29 7b 0a 20 20 20 20 54 63 6c 5f 57 72  =2 ){.    Tcl_Wr
8720: 6f 6e 67 4e 75 6d 41 72 67 73 28 69 6e 74 65 72  ongNumArgs(inter
8730: 70 2c 20 31 2c 20 6f 62 6a 76 2c 20 22 44 42 22  p, 1, objv, "DB"
8740: 29 3b 0a 20 20 20 20 72 65 74 75 72 6e 20 54 43  );.    return TC
8750: 4c 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a 20 20 69  L_ERROR;.  }.  i
8760: 66 28 20 67 65 74 44 62 50 6f 69 6e 74 65 72 28  f( getDbPointer(
8770: 69 6e 74 65 72 70 2c 20 54 63 6c 5f 47 65 74 53  interp, Tcl_GetS
8780: 74 72 69 6e 67 28 6f 62 6a 76 5b 31 5d 29 2c 20  tring(objv[1]), 
8790: 26 64 62 29 20 29 20 72 65 74 75 72 6e 20 54 43  &db) ) return TC
87a0: 4c 5f 45 52 52 4f 52 3b 0a 20 20 70 4d 6f 64 20  L_ERROR;.  pMod 
87b0: 3d 20 73 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63  = sqlite3_malloc
87c0: 28 73 69 7a 65 6f 66 28 45 63 68 6f 4d 6f 64 75  (sizeof(EchoModu
87d0: 6c 65 29 29 3b 0a 20 20 70 4d 6f 64 2d 3e 69 6e  le));.  pMod->in
87e0: 74 65 72 70 20 3d 20 69 6e 74 65 72 70 3b 0a 20  terp = interp;. 
87f0: 20 73 71 6c 69 74 65 33 5f 63 72 65 61 74 65 5f   sqlite3_create_
8800: 6d 6f 64 75 6c 65 5f 76 32 28 64 62 2c 20 22 65  module_v2(db, "e
8810: 63 68 6f 22 2c 20 26 65 63 68 6f 4d 6f 64 75 6c  cho", &echoModul
8820: 65 2c 20 28 76 6f 69 64 2a 29 70 4d 6f 64 2c 20  e, (void*)pMod, 
8830: 6d 6f 64 75 6c 65 44 65 73 74 72 6f 79 29 3b 0a  moduleDestroy);.
8840: 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 4f 4b 3b    return TCL_OK;
8850: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 63 6c 20 69 6e  .}../*.** Tcl in
8860: 74 65 72 66 61 63 65 20 74 6f 20 73 71 6c 69 74  terface to sqlit
8870: 65 33 5f 64 65 63 6c 61 72 65 5f 76 74 61 62 2c  e3_declare_vtab,
8880: 20 69 6e 76 6f 6b 65 64 20 61 73 20 66 6f 6c 6c   invoked as foll
8890: 6f 77 73 20 66 72 6f 6d 20 54 63 6c 3a 0a 2a 2a  ows from Tcl:.**
88a0: 0a 2a 2a 20 73 71 6c 69 74 65 33 5f 64 65 63 6c  .** sqlite3_decl
88b0: 61 72 65 5f 76 74 61 62 20 44 42 20 53 51 4c 0a  are_vtab DB SQL.
88c0: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 64 65  */.static int de
88d0: 63 6c 61 72 65 5f 76 74 61 62 28 0a 20 20 43 6c  clare_vtab(.  Cl
88e0: 69 65 6e 74 44 61 74 61 20 63 6c 69 65 6e 74 44  ientData clientD
88f0: 61 74 61 2c 20 2f 2a 20 50 6f 69 6e 74 65 72 20  ata, /* Pointer 
8900: 74 6f 20 73 71 6c 69 74 65 33 5f 65 6e 61 62 6c  to sqlite3_enabl
8910: 65 5f 58 58 58 20 66 75 6e 63 74 69 6f 6e 20 2a  e_XXX function *
8920: 2f 0a 20 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a  /.  Tcl_Interp *
8930: 69 6e 74 65 72 70 2c 20 20 20 20 2f 2a 20 54 68  interp,    /* Th
8940: 65 20 54 43 4c 20 69 6e 74 65 72 70 72 65 74 65  e TCL interprete
8950: 72 20 74 68 61 74 20 69 6e 76 6f 6b 65 64 20 74  r that invoked t
8960: 68 69 73 20 63 6f 6d 6d 61 6e 64 20 2a 2f 0a 20  his command */. 
8970: 20 69 6e 74 20 6f 62 6a 63 2c 20 20 20 20 20 20   int objc,      
8980: 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65          /* Numbe
8990: 72 20 6f 66 20 61 72 67 75 6d 65 6e 74 73 20 2a  r of arguments *
89a0: 2f 0a 20 20 54 63 6c 5f 4f 62 6a 20 2a 43 4f 4e  /.  Tcl_Obj *CON
89b0: 53 54 20 6f 62 6a 76 5b 5d 20 20 2f 2a 20 43 6f  ST objv[]  /* Co
89c0: 6d 6d 61 6e 64 20 61 72 67 75 6d 65 6e 74 73 20  mmand arguments 
89d0: 2a 2f 0a 29 7b 0a 20 20 73 71 6c 69 74 65 33 20  */.){.  sqlite3 
89e0: 2a 64 62 3b 0a 20 20 69 6e 74 20 72 63 3b 0a 20  *db;.  int rc;. 
89f0: 20 69 66 28 20 6f 62 6a 63 21 3d 33 20 29 7b 0a   if( objc!=3 ){.
8a00: 20 20 20 20 54 63 6c 5f 57 72 6f 6e 67 4e 75 6d      Tcl_WrongNum
8a10: 41 72 67 73 28 69 6e 74 65 72 70 2c 20 31 2c 20  Args(interp, 1, 
8a20: 6f 62 6a 76 2c 20 22 44 42 20 53 51 4c 22 29 3b  objv, "DB SQL");
8a30: 0a 20 20 20 20 72 65 74 75 72 6e 20 54 43 4c 5f  .    return TCL_
8a40: 45 52 52 4f 52 3b 0a 20 20 7d 0a 20 20 69 66 28  ERROR;.  }.  if(
8a50: 20 67 65 74 44 62 50 6f 69 6e 74 65 72 28 69 6e   getDbPointer(in
8a60: 74 65 72 70 2c 20 54 63 6c 5f 47 65 74 53 74 72  terp, Tcl_GetStr
8a70: 69 6e 67 28 6f 62 6a 76 5b 31 5d 29 2c 20 26 64  ing(objv[1]), &d
8a80: 62 29 20 29 20 72 65 74 75 72 6e 20 54 43 4c 5f  b) ) return TCL_
8a90: 45 52 52 4f 52 3b 0a 20 20 72 63 20 3d 20 73 71  ERROR;.  rc = sq
8aa0: 6c 69 74 65 33 5f 64 65 63 6c 61 72 65 5f 76 74  lite3_declare_vt
8ab0: 61 62 28 64 62 2c 20 54 63 6c 5f 47 65 74 53 74  ab(db, Tcl_GetSt
8ac0: 72 69 6e 67 28 6f 62 6a 76 5b 32 5d 29 29 3b 0a  ring(objv[2]));.
8ad0: 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45    if( rc!=SQLITE
8ae0: 5f 4f 4b 20 29 7b 0a 20 20 20 20 54 63 6c 5f 53  _OK ){.    Tcl_S
8af0: 65 74 52 65 73 75 6c 74 28 69 6e 74 65 72 70 2c  etResult(interp,
8b00: 20 28 63 68 61 72 20 2a 29 73 71 6c 69 74 65 33   (char *)sqlite3
8b10: 5f 65 72 72 6d 73 67 28 64 62 29 2c 20 54 43 4c  _errmsg(db), TCL
8b20: 5f 56 4f 4c 41 54 49 4c 45 29 3b 0a 20 20 20 20  _VOLATILE);.    
8b30: 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52  return TCL_ERROR
8b40: 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 54  ;.  }.  return T
8b50: 43 4c 5f 4f 4b 3b 0a 7d 0a 0a 23 65 6e 64 69 66  CL_OK;.}..#endif
8b60: 20 2f 2a 20 69 66 6e 64 65 66 20 53 51 4c 49 54   /* ifndef SQLIT
8b70: 45 5f 4f 4d 49 54 5f 56 49 52 54 55 41 4c 54 41  E_OMIT_VIRTUALTA
8b80: 42 4c 45 20 2a 2f 0a 0a 2f 2a 0a 2a 2a 20 52 65  BLE */../*.** Re
8b90: 67 69 73 74 65 72 20 63 6f 6d 6d 61 6e 64 73 20  gister commands 
8ba0: 77 69 74 68 20 74 68 65 20 54 43 4c 20 69 6e 74  with the TCL int
8bb0: 65 72 70 72 65 74 65 72 2e 0a 2a 2f 0a 69 6e 74  erpreter..*/.int
8bc0: 20 53 71 6c 69 74 65 74 65 73 74 38 5f 49 6e 69   Sqlitetest8_Ini
8bd0: 74 28 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e  t(Tcl_Interp *in
8be0: 74 65 72 70 29 7b 0a 20 20 73 74 61 74 69 63 20  terp){.  static 
8bf0: 73 74 72 75 63 74 20 7b 0a 20 20 20 20 20 63 68  struct {.     ch
8c00: 61 72 20 2a 7a 4e 61 6d 65 3b 0a 20 20 20 20 20  ar *zName;.     
8c10: 54 63 6c 5f 4f 62 6a 43 6d 64 50 72 6f 63 20 2a  Tcl_ObjCmdProc *
8c20: 78 50 72 6f 63 3b 0a 20 20 20 20 20 76 6f 69 64  xProc;.     void
8c30: 20 2a 63 6c 69 65 6e 74 44 61 74 61 3b 0a 20 20   *clientData;.  
8c40: 7d 20 61 4f 62 6a 43 6d 64 5b 5d 20 3d 20 7b 0a  } aObjCmd[] = {.
8c50: 23 69 66 6e 64 65 66 20 53 51 4c 49 54 45 5f 4f  #ifndef SQLITE_O
8c60: 4d 49 54 5f 56 49 52 54 55 41 4c 54 41 42 4c 45  MIT_VIRTUALTABLE
8c70: 0a 20 20 20 20 20 7b 20 22 72 65 67 69 73 74 65  .     { "registe
8c80: 72 5f 65 63 68 6f 5f 6d 6f 64 75 6c 65 22 2c 20  r_echo_module", 
8c90: 20 20 72 65 67 69 73 74 65 72 5f 65 63 68 6f 5f    register_echo_
8ca0: 6d 6f 64 75 6c 65 2c 20 30 20 7d 2c 0a 20 20 20  module, 0 },.   
8cb0: 20 20 7b 20 22 73 71 6c 69 74 65 33 5f 64 65 63    { "sqlite3_dec
8cc0: 6c 61 72 65 5f 76 74 61 62 22 2c 20 20 20 64 65  lare_vtab",   de
8cd0: 63 6c 61 72 65 5f 76 74 61 62 2c 20 30 20 7d 2c  clare_vtab, 0 },
8ce0: 0a 23 65 6e 64 69 66 0a 20 20 7d 3b 0a 20 20 69  .#endif.  };.  i
8cf0: 6e 74 20 69 3b 0a 20 20 66 6f 72 28 69 3d 30 3b  nt i;.  for(i=0;
8d00: 20 69 3c 73 69 7a 65 6f 66 28 61 4f 62 6a 43 6d   i<sizeof(aObjCm
8d10: 64 29 2f 73 69 7a 65 6f 66 28 61 4f 62 6a 43 6d  d)/sizeof(aObjCm
8d20: 64 5b 30 5d 29 3b 20 69 2b 2b 29 7b 0a 20 20 20  d[0]); i++){.   
8d30: 20 54 63 6c 5f 43 72 65 61 74 65 4f 62 6a 43 6f   Tcl_CreateObjCo
8d40: 6d 6d 61 6e 64 28 69 6e 74 65 72 70 2c 20 61 4f  mmand(interp, aO
8d50: 62 6a 43 6d 64 5b 69 5d 2e 7a 4e 61 6d 65 2c 20  bjCmd[i].zName, 
8d60: 0a 20 20 20 20 20 20 20 20 61 4f 62 6a 43 6d 64  .        aObjCmd
8d70: 5b 69 5d 2e 78 50 72 6f 63 2c 20 61 4f 62 6a 43  [i].xProc, aObjC
8d80: 6d 64 5b 69 5d 2e 63 6c 69 65 6e 74 44 61 74 61  md[i].clientData
8d90: 2c 20 30 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75  , 0);.  }.  retu
8da0: 72 6e 20 54 43 4c 5f 4f 4b 3b 0a 7d 0a           rn TCL_OK;.}.