/ Hex Artifact Content
Login

Artifact 54ccd7b1df5062f0ecbf50a8f7b618f8b1f13b20:


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 2f 0a 23 69 6e 63 6c 75 64 65  ary..*/.#include
0220: 20 22 73 71 6c 69 74 65 49 6e 74 2e 68 22 0a 23   "sqliteInt.h".#
0230: 69 6e 63 6c 75 64 65 20 22 74 63 6c 2e 68 22 0a  include "tcl.h".
0240: 23 69 6e 63 6c 75 64 65 20 3c 73 74 64 6c 69 62  #include <stdlib
0250: 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 73 74  .h>.#include <st
0260: 72 69 6e 67 2e 68 3e 0a 0a 23 69 66 6e 64 65 66  ring.h>..#ifndef
0270: 20 53 51 4c 49 54 45 5f 4f 4d 49 54 5f 56 49 52   SQLITE_OMIT_VIR
0280: 54 55 41 4c 54 41 42 4c 45 0a 0a 74 79 70 65 64  TUALTABLE..typed
0290: 65 66 20 73 74 72 75 63 74 20 65 63 68 6f 5f 76  ef struct echo_v
02a0: 74 61 62 20 65 63 68 6f 5f 76 74 61 62 3b 0a 74  tab echo_vtab;.t
02b0: 79 70 65 64 65 66 20 73 74 72 75 63 74 20 65 63  ypedef struct ec
02c0: 68 6f 5f 63 75 72 73 6f 72 20 65 63 68 6f 5f 63  ho_cursor echo_c
02d0: 75 72 73 6f 72 3b 0a 0a 2f 2a 0a 2a 2a 20 54 68  ursor;../*.** Th
02e0: 65 20 74 65 73 74 20 6d 6f 64 75 6c 65 20 64 65  e test module de
02f0: 66 69 6e 65 64 20 69 6e 20 74 68 69 73 20 66 69  fined in this fi
0300: 6c 65 20 75 73 65 73 20 66 6f 75 72 20 67 6c 6f  le uses four glo
0310: 62 61 6c 20 54 63 6c 20 76 61 72 69 61 62 6c 65  bal Tcl variable
0320: 73 20 74 6f 0a 2a 2a 20 63 6f 6d 6d 69 63 61 74  s to.** commicat
0330: 65 20 77 69 74 68 20 74 65 73 74 2d 73 63 72 69  e with test-scri
0340: 70 74 73 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20 24  pts:.**.**     $
0350: 3a 3a 65 63 68 6f 5f 6d 6f 64 75 6c 65 0a 2a 2a  ::echo_module.**
0360: 20 20 20 20 20 24 3a 3a 65 63 68 6f 5f 6d 6f 64       $::echo_mod
0370: 75 6c 65 5f 73 79 6e 63 5f 66 61 69 6c 0a 2a 2a  ule_sync_fail.**
0380: 20 20 20 20 20 24 3a 3a 65 63 68 6f 5f 6d 6f 64       $::echo_mod
0390: 75 6c 65 5f 62 65 67 69 6e 5f 66 61 69 6c 0a 2a  ule_begin_fail.*
03a0: 2a 20 20 20 20 20 24 3a 3a 65 63 68 6f 5f 6d 6f  *     $::echo_mo
03b0: 64 75 6c 65 5f 63 6f 73 74 0a 2a 2a 0a 2a 2a 20  dule_cost.**.** 
03c0: 54 68 65 20 76 61 72 69 61 62 6c 65 20 3a 3a 65  The variable ::e
03d0: 63 68 6f 5f 6d 6f 64 75 6c 65 20 69 73 20 61 20  cho_module is a 
03e0: 6c 69 73 74 2e 20 45 61 63 68 20 74 69 6d 65 20  list. Each time 
03f0: 6f 6e 65 20 6f 66 20 74 68 65 20 66 6f 6c 6c 6f  one of the follo
0400: 77 69 6e 67 0a 2a 2a 20 6d 65 74 68 6f 64 73 20  wing.** methods 
0410: 69 73 20 63 61 6c 6c 65 64 2c 20 6f 6e 65 20 6f  is called, one o
0420: 72 20 6d 6f 72 65 20 65 6c 65 6d 65 6e 74 73 20  r more elements 
0430: 61 72 65 20 61 70 70 65 6e 64 65 64 20 74 6f 20  are appended to 
0440: 74 68 65 20 6c 69 73 74 2e 0a 2a 2a 20 54 68 69  the list..** Thi
0450: 73 20 69 73 20 75 73 65 64 20 66 6f 72 20 61 75  s is used for au
0460: 74 6f 6d 61 74 65 64 20 74 65 73 74 69 6e 67 20  tomated testing 
0470: 6f 66 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65  of virtual table
0480: 20 6d 6f 64 75 6c 65 73 2e 0a 2a 2a 0a 2a 2a 20   modules..**.** 
0490: 54 68 65 20 3a 3a 65 63 68 6f 5f 6d 6f 64 75 6c  The ::echo_modul
04a0: 65 5f 73 79 6e 63 5f 66 61 69 6c 20 76 61 72 69  e_sync_fail vari
04b0: 61 62 6c 65 20 69 73 20 73 65 74 20 62 79 20 74  able is set by t
04c0: 65 73 74 20 73 63 72 69 70 74 73 20 61 6e 64 20  est scripts and 
04d0: 72 65 61 64 0a 2a 2a 20 62 79 20 63 6f 64 65 20  read.** by code 
04e0: 69 6e 20 74 68 69 73 20 66 69 6c 65 2e 20 49 66  in this file. If
04f0: 20 69 74 20 69 73 20 73 65 74 20 74 6f 20 74 68   it is set to th
0500: 65 20 6e 61 6d 65 20 6f 66 20 61 20 72 65 61 6c  e name of a real
0510: 20 74 61 62 6c 65 20 69 6e 20 74 68 65 0a 2a 2a   table in the.**
0520: 20 74 68 65 20 64 61 74 61 62 61 73 65 2c 20 74   the database, t
0530: 68 65 6e 20 61 6c 6c 20 78 53 79 6e 63 20 6f 70  hen all xSync op
0540: 65 72 61 74 69 6f 6e 73 20 6f 6e 20 65 63 68 6f  erations on echo
0550: 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65 73 20   virtual tables 
0560: 74 68 61 74 0a 2a 2a 20 75 73 65 20 74 68 65 20  that.** use the 
0570: 6e 61 6d 65 64 20 74 61 62 6c 65 20 61 73 20 61  named table as a
0580: 20 62 61 63 6b 69 6e 67 20 73 74 6f 72 65 20 77   backing store w
0590: 69 6c 6c 20 66 61 69 6c 2e 0a 2a 2f 0a 0a 2f 2a  ill fail..*/../*
05a0: 0a 2a 2a 20 45 72 72 6f 72 73 20 63 61 6e 20 62  .** Errors can b
05b0: 65 20 70 72 6f 76 6f 6b 65 64 20 77 69 74 68 69  e provoked withi
05c0: 6e 20 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20  n the following 
05d0: 65 63 68 6f 20 76 69 72 74 75 61 6c 20 74 61 62  echo virtual tab
05e0: 6c 65 20 6d 65 74 68 6f 64 73 3a 0a 2a 2a 0a 2a  le methods:.**.*
05f0: 2a 20 20 20 78 42 65 73 74 49 6e 64 65 78 20 20  *   xBestIndex  
0600: 20 78 4f 70 65 6e 20 20 20 20 20 78 46 69 6c 74   xOpen     xFilt
0610: 65 72 20 20 20 78 4e 65 78 74 20 20 20 0a 2a 2a  er   xNext   .**
0620: 20 20 20 78 43 6f 6c 75 6d 6e 20 20 20 20 20 20     xColumn      
0630: 78 52 6f 77 69 64 20 20 20 20 78 55 70 64 61 74  xRowid    xUpdat
0640: 65 20 20 20 78 53 79 6e 63 20 20 20 0a 2a 2a 20  e   xSync   .** 
0650: 20 20 78 42 65 67 69 6e 20 20 20 20 20 20 20 78    xBegin       x
0660: 52 65 6e 61 6d 65 0a 2a 2a 0a 2a 2a 20 54 68 69  Rename.**.** Thi
0670: 73 20 69 73 20 64 6f 6e 65 20 62 79 20 73 65 74  s is done by set
0680: 74 69 6e 67 20 74 68 65 20 67 6c 6f 62 61 6c 20  ting the global 
0690: 74 63 6c 20 76 61 72 69 61 62 6c 65 3a 0a 2a 2a  tcl variable:.**
06a0: 0a 2a 2a 20 20 20 65 63 68 6f 5f 6d 6f 64 75 6c  .**   echo_modul
06b0: 65 5f 66 61 69 6c 28 24 6d 65 74 68 6f 64 2c 24  e_fail($method,$
06c0: 74 62 6c 29 0a 2a 2a 0a 2a 2a 20 77 68 65 72 65  tbl).**.** where
06d0: 20 24 6d 65 74 68 6f 64 20 69 73 20 73 65 74 20   $method is set 
06e0: 74 6f 20 74 68 65 20 6e 61 6d 65 20 6f 66 20 74  to the name of t
06f0: 68 65 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65  he virtual table
0700: 20 6d 65 74 68 6f 64 20 74 6f 20 66 61 69 6c 0a   method to fail.
0710: 2a 2a 20 28 69 2e 65 2e 20 22 78 42 65 73 74 49  ** (i.e. "xBestI
0720: 6e 64 65 78 22 29 20 61 6e 64 20 24 74 62 6c 20  ndex") and $tbl 
0730: 69 73 20 74 68 65 20 6e 61 6d 65 20 6f 66 20 74  is the name of t
0740: 68 65 20 74 61 62 6c 65 20 62 65 69 6e 67 20 65  he table being e
0750: 63 68 6f 65 64 20 28 6e 6f 74 0a 2a 2a 20 74 68  choed (not.** th
0760: 65 20 6e 61 6d 65 20 6f 66 20 74 68 65 20 76 69  e name of the vi
0770: 72 74 75 61 6c 20 74 61 62 6c 65 2c 20 74 68 65  rtual table, the
0780: 20 6e 61 6d 65 20 6f 66 20 74 68 65 20 75 6e 64   name of the und
0790: 65 72 6c 79 69 6e 67 20 72 65 61 6c 20 74 61 62  erlying real tab
07a0: 6c 65 29 2e 0a 2a 2f 0a 0a 2f 2a 20 0a 2a 2a 20  le)..*/../* .** 
07b0: 41 6e 20 65 63 68 6f 20 76 69 72 74 75 61 6c 2d  An echo virtual-
07c0: 74 61 62 6c 65 20 6f 62 6a 65 63 74 2e 0a 2a 2a  table object..**
07d0: 0a 2a 2a 20 65 63 68 6f 2e 76 74 61 62 2e 61 49  .** echo.vtab.aI
07e0: 6e 64 65 78 20 69 73 20 61 6e 20 61 72 72 61 79  ndex is an array
07f0: 20 6f 66 20 62 6f 6f 6c 65 61 6e 73 2e 20 54 68   of booleans. Th
0800: 65 20 6e 74 68 20 65 6e 74 72 79 20 69 73 20 74  e nth entry is t
0810: 72 75 65 20 69 66 20 0a 2a 2a 20 74 68 65 20 6e  rue if .** the n
0820: 74 68 20 63 6f 6c 75 6d 6e 20 6f 66 20 74 68 65  th column of the
0830: 20 72 65 61 6c 20 74 61 62 6c 65 20 69 73 20 74   real table is t
0840: 68 65 20 6c 65 66 74 2d 6d 6f 73 74 20 63 6f 6c  he left-most col
0850: 75 6d 6e 20 6f 66 20 61 6e 20 69 6e 64 65 78 0a  umn of an index.
0860: 2a 2a 20 28 69 6d 70 6c 69 63 69 74 20 6f 72 20  ** (implicit or 
0870: 6f 74 68 65 72 77 69 73 65 29 2e 20 49 6e 20 6f  otherwise). In o
0880: 74 68 65 72 20 77 6f 72 64 73 2c 20 69 66 20 53  ther words, if S
0890: 51 4c 69 74 65 20 63 61 6e 20 6f 70 74 69 6d 69  QLite can optimi
08a0: 7a 65 0a 2a 2a 20 61 20 71 75 65 72 79 20 6c 69  ze.** a query li
08b0: 6b 65 20 22 53 45 4c 45 43 54 20 2a 20 46 52 4f  ke "SELECT * FRO
08c0: 4d 20 72 65 61 6c 5f 74 61 62 6c 65 20 57 48 45  M real_table WHE
08d0: 52 45 20 63 6f 6c 20 3d 20 3f 22 2e 0a 2a 2a 0a  RE col = ?"..**.
08e0: 2a 2a 20 4d 65 6d 62 65 72 20 76 61 72 69 61 62  ** Member variab
08f0: 6c 65 20 61 43 6f 6c 5b 5d 20 63 6f 6e 74 61 69  le aCol[] contai
0900: 6e 73 20 63 6f 70 69 65 73 20 6f 66 20 74 68 65  ns copies of the
0910: 20 63 6f 6c 75 6d 6e 20 6e 61 6d 65 73 20 6f 66   column names of
0920: 20 74 68 65 20 72 65 61 6c 0a 2a 2a 20 74 61 62   the real.** tab
0930: 6c 65 2e 0a 2a 2f 0a 73 74 72 75 63 74 20 65 63  le..*/.struct ec
0940: 68 6f 5f 76 74 61 62 20 7b 0a 20 20 73 71 6c 69  ho_vtab {.  sqli
0950: 74 65 33 5f 76 74 61 62 20 62 61 73 65 3b 0a 20  te3_vtab base;. 
0960: 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74   Tcl_Interp *int
0970: 65 72 70 3b 20 20 20 20 20 2f 2a 20 54 63 6c 20  erp;     /* Tcl 
0980: 69 6e 74 65 72 70 72 65 74 65 72 20 63 6f 6e 74  interpreter cont
0990: 61 69 6e 69 6e 67 20 64 65 62 75 67 20 76 61 72  aining debug var
09a0: 69 61 62 6c 65 73 20 2a 2f 0a 20 20 73 71 6c 69  iables */.  sqli
09b0: 74 65 33 20 2a 64 62 3b 20 20 20 20 20 20 20 20  te3 *db;        
09c0: 20 20 20 20 2f 2a 20 44 61 74 61 62 61 73 65 20      /* Database 
09d0: 63 6f 6e 6e 65 63 74 69 6f 6e 20 2a 2f 0a 0a 20  connection */.. 
09e0: 20 69 6e 74 20 69 73 50 61 74 74 65 72 6e 3b 0a   int isPattern;.
09f0: 20 20 69 6e 74 20 69 6e 54 72 61 6e 73 61 63 74    int inTransact
0a00: 69 6f 6e 3b 20 20 20 20 20 20 2f 2a 20 54 72 75  ion;      /* Tru
0a10: 65 20 69 66 20 77 69 74 68 69 6e 20 61 20 74 72  e if within a tr
0a20: 61 6e 73 61 63 74 69 6f 6e 20 2a 2f 0a 20 20 63  ansaction */.  c
0a30: 68 61 72 20 2a 7a 54 68 69 73 3b 20 20 20 20 20  har *zThis;     
0a40: 20 20 20 20 20 20 20 2f 2a 20 4e 61 6d 65 20 6f         /* Name o
0a50: 66 20 74 68 65 20 65 63 68 6f 20 74 61 62 6c 65  f the echo table
0a60: 20 2a 2f 0a 20 20 63 68 61 72 20 2a 7a 54 61 62   */.  char *zTab
0a70: 6c 65 4e 61 6d 65 3b 20 20 20 20 20 20 20 2f 2a  leName;       /*
0a80: 20 4e 61 6d 65 20 6f 66 20 74 68 65 20 72 65 61   Name of the rea
0a90: 6c 20 74 61 62 6c 65 20 2a 2f 0a 20 20 63 68 61  l table */.  cha
0aa0: 72 20 2a 7a 4c 6f 67 4e 61 6d 65 3b 20 20 20 20  r *zLogName;    
0ab0: 20 20 20 20 20 2f 2a 20 4e 61 6d 65 20 6f 66 20       /* Name of 
0ac0: 74 68 65 20 6c 6f 67 20 74 61 62 6c 65 20 2a 2f  the log table */
0ad0: 0a 20 20 69 6e 74 20 6e 43 6f 6c 3b 20 20 20 20  .  int nCol;    
0ae0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75             /* Nu
0af0: 6d 62 65 72 20 6f 66 20 63 6f 6c 75 6d 6e 73 20  mber of columns 
0b00: 69 6e 20 74 68 65 20 72 65 61 6c 20 74 61 62 6c  in the real tabl
0b10: 65 20 2a 2f 0a 20 20 69 6e 74 20 2a 61 49 6e 64  e */.  int *aInd
0b20: 65 78 3b 20 20 20 20 20 20 20 20 20 20 20 20 2f  ex;            /
0b30: 2a 20 41 72 72 61 79 20 6f 66 20 73 69 7a 65 20  * Array of size 
0b40: 6e 43 6f 6c 2e 20 54 72 75 65 20 69 66 20 63 6f  nCol. True if co
0b50: 6c 75 6d 6e 20 68 61 73 20 61 6e 20 69 6e 64 65  lumn has an inde
0b60: 78 20 2a 2f 0a 20 20 63 68 61 72 20 2a 2a 61 43  x */.  char **aC
0b70: 6f 6c 3b 20 20 20 20 20 20 20 20 20 20 20 20 2f  ol;            /
0b80: 2a 20 41 72 72 61 79 20 6f 66 20 73 69 7a 65 20  * Array of size 
0b90: 6e 43 6f 6c 2e 20 43 6f 6c 75 6d 6e 20 6e 61 6d  nCol. Column nam
0ba0: 65 73 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 20 41 6e 20  es */.};../* An 
0bb0: 65 63 68 6f 20 63 75 72 73 6f 72 20 6f 62 6a 65  echo cursor obje
0bc0: 63 74 20 2a 2f 0a 73 74 72 75 63 74 20 65 63 68  ct */.struct ech
0bd0: 6f 5f 63 75 72 73 6f 72 20 7b 0a 20 20 73 71 6c  o_cursor {.  sql
0be0: 69 74 65 33 5f 76 74 61 62 5f 63 75 72 73 6f 72  ite3_vtab_cursor
0bf0: 20 62 61 73 65 3b 0a 20 20 73 71 6c 69 74 65 33   base;.  sqlite3
0c00: 5f 73 74 6d 74 20 2a 70 53 74 6d 74 3b 0a 7d 3b  _stmt *pStmt;.};
0c10: 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 73 69 6d  ..static int sim
0c20: 75 6c 61 74 65 56 74 61 62 45 72 72 6f 72 28 65  ulateVtabError(e
0c30: 63 68 6f 5f 76 74 61 62 20 2a 70 2c 20 63 6f 6e  cho_vtab *p, con
0c40: 73 74 20 63 68 61 72 20 2a 7a 4d 65 74 68 6f 64  st char *zMethod
0c50: 29 7b 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20  ){.  const char 
0c60: 2a 7a 45 72 72 3b 0a 20 20 63 68 61 72 20 7a 56  *zErr;.  char zV
0c70: 61 72 6e 61 6d 65 5b 31 32 38 5d 3b 0a 20 20 7a  arname[128];.  z
0c80: 56 61 72 6e 61 6d 65 5b 31 32 37 5d 20 3d 20 27  Varname[127] = '
0c90: 5c 30 27 3b 0a 20 20 73 71 6c 69 74 65 33 5f 73  \0';.  sqlite3_s
0ca0: 6e 70 72 69 6e 74 66 28 31 32 37 2c 20 7a 56 61  nprintf(127, zVa
0cb0: 72 6e 61 6d 65 2c 20 22 65 63 68 6f 5f 6d 6f 64  rname, "echo_mod
0cc0: 75 6c 65 5f 66 61 69 6c 28 25 73 2c 25 73 29 22  ule_fail(%s,%s)"
0cd0: 2c 20 7a 4d 65 74 68 6f 64 2c 20 70 2d 3e 7a 54  , zMethod, p->zT
0ce0: 61 62 6c 65 4e 61 6d 65 29 3b 0a 20 20 7a 45 72  ableName);.  zEr
0cf0: 72 20 3d 20 54 63 6c 5f 47 65 74 56 61 72 28 70  r = Tcl_GetVar(p
0d00: 2d 3e 69 6e 74 65 72 70 2c 20 7a 56 61 72 6e 61  ->interp, zVarna
0d10: 6d 65 2c 20 54 43 4c 5f 47 4c 4f 42 41 4c 5f 4f  me, TCL_GLOBAL_O
0d20: 4e 4c 59 29 3b 0a 20 20 69 66 28 20 7a 45 72 72  NLY);.  if( zErr
0d30: 20 29 7b 0a 20 20 20 20 70 2d 3e 62 61 73 65 2e   ){.    p->base.
0d40: 7a 45 72 72 4d 73 67 20 3d 20 73 71 6c 69 74 65  zErrMsg = sqlite
0d50: 33 5f 6d 70 72 69 6e 74 66 28 22 65 63 68 6f 2d  3_mprintf("echo-
0d60: 76 74 61 62 2d 65 72 72 6f 72 3a 20 25 73 22 2c  vtab-error: %s",
0d70: 20 7a 45 72 72 29 3b 0a 20 20 7d 0a 20 20 72 65   zErr);.  }.  re
0d80: 74 75 72 6e 20 28 7a 45 72 72 21 3d 30 29 3b 0a  turn (zErr!=0);.
0d90: 7d 0a 0a 2f 2a 0a 2a 2a 20 43 6f 6e 76 65 72 74  }../*.** Convert
0da0: 20 61 6e 20 53 51 4c 2d 73 74 79 6c 65 20 71 75   an SQL-style qu
0db0: 6f 74 65 64 20 73 74 72 69 6e 67 20 69 6e 74 6f  oted string into
0dc0: 20 61 20 6e 6f 72 6d 61 6c 20 73 74 72 69 6e 67   a normal string
0dd0: 20 62 79 20 72 65 6d 6f 76 69 6e 67 0a 2a 2a 20   by removing.** 
0de0: 74 68 65 20 71 75 6f 74 65 20 63 68 61 72 61 63  the quote charac
0df0: 74 65 72 73 2e 20 20 54 68 65 20 63 6f 6e 76 65  ters.  The conve
0e00: 72 73 69 6f 6e 20 69 73 20 64 6f 6e 65 20 69 6e  rsion is done in
0e10: 2d 70 6c 61 63 65 2e 20 20 49 66 20 74 68 65 0a  -place.  If the.
0e20: 2a 2a 20 69 6e 70 75 74 20 64 6f 65 73 20 6e 6f  ** input does no
0e30: 74 20 62 65 67 69 6e 20 77 69 74 68 20 61 20 71  t begin with a q
0e40: 75 6f 74 65 20 63 68 61 72 61 63 74 65 72 2c 20  uote character, 
0e50: 74 68 65 6e 20 74 68 69 73 20 72 6f 75 74 69 6e  then this routin
0e60: 65 0a 2a 2a 20 69 73 20 61 20 6e 6f 2d 6f 70 2e  e.** is a no-op.
0e70: 0a 2a 2a 0a 2a 2a 20 45 78 61 6d 70 6c 65 73 3a  .**.** Examples:
0e80: 0a 2a 2a 0a 2a 2a 20 20 20 20 20 22 61 62 63 22  .**.**     "abc"
0e90: 20 20 20 62 65 63 6f 6d 65 73 20 20 20 61 62 63     becomes   abc
0ea0: 0a 2a 2a 20 20 20 20 20 27 78 79 7a 27 20 20 20  .**     'xyz'   
0eb0: 62 65 63 6f 6d 65 73 20 20 20 78 79 7a 0a 2a 2a  becomes   xyz.**
0ec0: 20 20 20 20 20 5b 70 71 72 5d 20 20 20 62 65 63       [pqr]   bec
0ed0: 6f 6d 65 73 20 20 20 70 71 72 0a 2a 2a 20 20 20  omes   pqr.**   
0ee0: 20 20 60 6d 6e 6f 60 20 20 20 62 65 63 6f 6d 65    `mno`   become
0ef0: 73 20 20 20 6d 6e 6f 0a 2a 2f 0a 73 74 61 74 69  s   mno.*/.stati
0f00: 63 20 76 6f 69 64 20 64 65 71 75 6f 74 65 53 74  c void dequoteSt
0f10: 72 69 6e 67 28 63 68 61 72 20 2a 7a 29 7b 0a 20  ring(char *z){. 
0f20: 20 69 6e 74 20 71 75 6f 74 65 3b 0a 20 20 69 6e   int quote;.  in
0f30: 74 20 69 2c 20 6a 3b 0a 20 20 69 66 28 20 7a 3d  t i, j;.  if( z=
0f40: 3d 30 20 29 20 72 65 74 75 72 6e 3b 0a 20 20 71  =0 ) return;.  q
0f50: 75 6f 74 65 20 3d 20 7a 5b 30 5d 3b 0a 20 20 73  uote = z[0];.  s
0f60: 77 69 74 63 68 28 20 71 75 6f 74 65 20 29 7b 0a  witch( quote ){.
0f70: 20 20 20 20 63 61 73 65 20 27 5c 27 27 3a 20 20      case '\'':  
0f80: 62 72 65 61 6b 3b 0a 20 20 20 20 63 61 73 65 20  break;.    case 
0f90: 27 22 27 3a 20 20 20 62 72 65 61 6b 3b 0a 20 20  '"':   break;.  
0fa0: 20 20 63 61 73 65 20 27 60 27 3a 20 20 20 62 72    case '`':   br
0fb0: 65 61 6b 3b 20 20 20 20 20 20 20 20 20 20 20 20  eak;            
0fc0: 20 20 20 20 2f 2a 20 46 6f 72 20 4d 79 53 51 4c      /* For MySQL
0fd0: 20 63 6f 6d 70 61 74 69 62 69 6c 69 74 79 20 2a   compatibility *
0fe0: 2f 0a 20 20 20 20 63 61 73 65 20 27 5b 27 3a 20  /.    case '[': 
0ff0: 20 20 71 75 6f 74 65 20 3d 20 27 5d 27 3b 20 20    quote = ']';  
1000: 62 72 65 61 6b 3b 20 20 2f 2a 20 46 6f 72 20 4d  break;  /* For M
1010: 53 20 53 71 6c 53 65 72 76 65 72 20 63 6f 6d 70  S SqlServer comp
1020: 61 74 69 62 69 6c 69 74 79 20 2a 2f 0a 20 20 20  atibility */.   
1030: 20 64 65 66 61 75 6c 74 3a 20 20 20 20 72 65 74   default:    ret
1040: 75 72 6e 3b 0a 20 20 7d 0a 20 20 66 6f 72 28 69  urn;.  }.  for(i
1050: 3d 31 2c 20 6a 3d 30 3b 20 7a 5b 69 5d 3b 20 69  =1, j=0; z[i]; i
1060: 2b 2b 29 7b 0a 20 20 20 20 69 66 28 20 7a 5b 69  ++){.    if( z[i
1070: 5d 3d 3d 71 75 6f 74 65 20 29 7b 0a 20 20 20 20  ]==quote ){.    
1080: 20 20 69 66 28 20 7a 5b 69 2b 31 5d 3d 3d 71 75    if( z[i+1]==qu
1090: 6f 74 65 20 29 7b 0a 20 20 20 20 20 20 20 20 7a  ote ){.        z
10a0: 5b 6a 2b 2b 5d 20 3d 20 71 75 6f 74 65 3b 0a 20  [j++] = quote;. 
10b0: 20 20 20 20 20 20 20 69 2b 2b 3b 0a 20 20 20 20         i++;.    
10c0: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20    }else{.       
10d0: 20 7a 5b 6a 2b 2b 5d 20 3d 20 30 3b 0a 20 20 20   z[j++] = 0;.   
10e0: 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20       break;.    
10f0: 20 20 7d 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20    }.    }else{. 
1100: 20 20 20 20 20 7a 5b 6a 2b 2b 5d 20 3d 20 7a 5b       z[j++] = z[
1110: 69 5d 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 7d 0a  i];.    }.  }.}.
1120: 0a 2f 2a 0a 2a 2a 20 52 65 74 72 69 65 76 65 20  ./*.** Retrieve 
1130: 74 68 65 20 63 6f 6c 75 6d 6e 20 6e 61 6d 65 73  the column names
1140: 20 66 6f 72 20 74 68 65 20 74 61 62 6c 65 20 6e   for the table n
1150: 61 6d 65 64 20 7a 54 61 62 20 76 69 61 20 64 61  amed zTab via da
1160: 74 61 62 61 73 65 0a 2a 2a 20 63 6f 6e 6e 65 63  tabase.** connec
1170: 74 69 6f 6e 20 64 62 2e 20 53 51 4c 49 54 45 5f  tion db. SQLITE_
1180: 4f 4b 20 69 73 20 72 65 74 75 72 6e 65 64 20 6f  OK is returned o
1190: 6e 20 73 75 63 63 65 73 73 2c 20 6f 72 20 61 6e  n success, or an
11a0: 20 73 71 6c 69 74 65 20 65 72 72 6f 72 0a 2a 2a   sqlite error.**
11b0: 20 63 6f 64 65 20 6f 74 68 65 72 77 69 73 65 2e   code otherwise.
11c0: 0a 2a 2a 0a 2a 2a 20 49 66 20 73 75 63 63 65 73  .**.** If succes
11d0: 73 66 75 6c 2c 20 74 68 65 20 6e 75 6d 62 65 72  sful, the number
11e0: 20 6f 66 20 63 6f 6c 75 6d 6e 73 20 69 73 20 77   of columns is w
11f0: 72 69 74 74 65 6e 20 74 6f 20 2a 70 6e 43 6f 6c  ritten to *pnCol
1200: 2e 20 2a 70 61 43 6f 6c 20 69 73 0a 2a 2a 20 73  . *paCol is.** s
1210: 65 74 20 74 6f 20 70 6f 69 6e 74 20 61 74 20 73  et to point at s
1220: 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63 28 29 27  qlite3_malloc()'
1230: 64 20 73 70 61 63 65 20 63 6f 6e 74 61 69 6e 69  d space containi
1240: 6e 67 20 74 68 65 20 61 72 72 61 79 20 6f 66 0a  ng the array of.
1250: 2a 2a 20 6e 43 6f 6c 20 63 6f 6c 75 6d 6e 20 6e  ** nCol column n
1260: 61 6d 65 73 2e 20 54 68 65 20 63 61 6c 6c 65 72  ames. The caller
1270: 20 69 73 20 72 65 73 70 6f 6e 73 69 62 6c 65 20   is responsible 
1280: 66 6f 72 20 63 61 6c 6c 69 6e 67 20 73 71 6c 69  for calling sqli
1290: 74 65 33 5f 66 72 65 65 0a 2a 2a 20 6f 6e 20 2a  te3_free.** on *
12a0: 70 61 43 6f 6c 2e 0a 2a 2f 0a 73 74 61 74 69 63  paCol..*/.static
12b0: 20 69 6e 74 20 67 65 74 43 6f 6c 75 6d 6e 4e 61   int getColumnNa
12c0: 6d 65 73 28 0a 20 20 73 71 6c 69 74 65 33 20 2a  mes(.  sqlite3 *
12d0: 64 62 2c 20 0a 20 20 63 6f 6e 73 74 20 63 68 61  db, .  const cha
12e0: 72 20 2a 7a 54 61 62 2c 0a 20 20 63 68 61 72 20  r *zTab,.  char 
12f0: 2a 2a 2a 70 61 43 6f 6c 2c 20 0a 20 20 69 6e 74  ***paCol, .  int
1300: 20 2a 70 6e 43 6f 6c 0a 29 7b 0a 20 20 63 68 61   *pnCol.){.  cha
1310: 72 20 2a 2a 61 43 6f 6c 20 3d 20 30 3b 0a 20 20  r **aCol = 0;.  
1320: 63 68 61 72 20 2a 7a 53 71 6c 3b 0a 20 20 73 71  char *zSql;.  sq
1330: 6c 69 74 65 33 5f 73 74 6d 74 20 2a 70 53 74 6d  lite3_stmt *pStm
1340: 74 20 3d 20 30 3b 0a 20 20 69 6e 74 20 72 63 20  t = 0;.  int rc 
1350: 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 69  = SQLITE_OK;.  i
1360: 6e 74 20 6e 43 6f 6c 20 3d 20 30 3b 0a 0a 20 20  nt nCol = 0;..  
1370: 2f 2a 20 50 72 65 70 61 72 65 20 74 68 65 20 73  /* Prepare the s
1380: 74 61 74 65 6d 65 6e 74 20 22 53 45 4c 45 43 54  tatement "SELECT
1390: 20 2a 20 46 52 4f 4d 20 3c 74 62 6c 3e 22 2e 20   * FROM <tbl>". 
13a0: 54 68 65 20 63 6f 6c 75 6d 6e 20 6e 61 6d 65 73  The column names
13b0: 0a 20 20 2a 2a 20 6f 66 20 74 68 65 20 72 65 73  .  ** of the res
13c0: 75 6c 74 20 73 65 74 20 6f 66 20 74 68 65 20 63  ult set of the c
13d0: 6f 6d 70 69 6c 65 64 20 53 45 4c 45 43 54 20 77  ompiled SELECT w
13e0: 69 6c 6c 20 62 65 20 74 68 65 20 73 61 6d 65 20  ill be the same 
13f0: 61 73 0a 20 20 2a 2a 20 74 68 65 20 63 6f 6c 75  as.  ** the colu
1400: 6d 6e 20 6e 61 6d 65 73 20 6f 66 20 74 61 62 6c  mn names of tabl
1410: 65 20 3c 74 62 6c 3e 2e 0a 20 20 2a 2f 0a 20 20  e <tbl>..  */.  
1420: 7a 53 71 6c 20 3d 20 73 71 6c 69 74 65 33 5f 6d  zSql = sqlite3_m
1430: 70 72 69 6e 74 66 28 22 53 45 4c 45 43 54 20 2a  printf("SELECT *
1440: 20 46 52 4f 4d 20 25 51 22 2c 20 7a 54 61 62 29   FROM %Q", zTab)
1450: 3b 0a 20 20 69 66 28 20 21 7a 53 71 6c 20 29 7b  ;.  if( !zSql ){
1460: 0a 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45  .    rc = SQLITE
1470: 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 67 6f 74 6f  _NOMEM;.    goto
1480: 20 6f 75 74 3b 0a 20 20 7d 0a 20 20 72 63 20 3d   out;.  }.  rc =
1490: 20 73 71 6c 69 74 65 33 5f 70 72 65 70 61 72 65   sqlite3_prepare
14a0: 28 64 62 2c 20 7a 53 71 6c 2c 20 2d 31 2c 20 26  (db, zSql, -1, &
14b0: 70 53 74 6d 74 2c 20 30 29 3b 0a 20 20 73 71 6c  pStmt, 0);.  sql
14c0: 69 74 65 33 5f 66 72 65 65 28 7a 53 71 6c 29 3b  ite3_free(zSql);
14d0: 0a 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49  ..  if( rc==SQLI
14e0: 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 69 6e 74  TE_OK ){.    int
14f0: 20 69 69 3b 0a 20 20 20 20 69 6e 74 20 6e 42 79   ii;.    int nBy
1500: 74 65 73 3b 0a 20 20 20 20 63 68 61 72 20 2a 7a  tes;.    char *z
1510: 53 70 61 63 65 3b 0a 20 20 20 20 6e 43 6f 6c 20  Space;.    nCol 
1520: 3d 20 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e  = sqlite3_column
1530: 5f 63 6f 75 6e 74 28 70 53 74 6d 74 29 3b 0a 0a  _count(pStmt);..
1540: 20 20 20 20 2f 2a 20 46 69 67 75 72 65 20 6f 75      /* Figure ou
1550: 74 20 68 6f 77 20 6d 75 63 68 20 73 70 61 63 65  t how much space
1560: 20 74 6f 20 61 6c 6c 6f 63 61 74 65 20 66 6f 72   to allocate for
1570: 20 74 68 65 20 61 72 72 61 79 20 6f 66 20 63 6f   the array of co
1580: 6c 75 6d 6e 20 6e 61 6d 65 73 20 0a 20 20 20 20  lumn names .    
1590: 2a 2a 20 28 69 6e 63 6c 75 64 69 6e 67 20 73 70  ** (including sp
15a0: 61 63 65 20 66 6f 72 20 74 68 65 20 73 74 72 69  ace for the stri
15b0: 6e 67 73 20 74 68 65 6d 73 65 6c 76 65 73 29 2e  ngs themselves).
15c0: 20 54 68 65 6e 20 61 6c 6c 6f 63 61 74 65 20 69   Then allocate i
15d0: 74 2e 0a 20 20 20 20 2a 2f 0a 20 20 20 20 6e 42  t..    */.    nB
15e0: 79 74 65 73 20 3d 20 73 69 7a 65 6f 66 28 63 68  ytes = sizeof(ch
15f0: 61 72 20 2a 29 20 2a 20 6e 43 6f 6c 3b 0a 20 20  ar *) * nCol;.  
1600: 20 20 66 6f 72 28 69 69 3d 30 3b 20 69 69 3c 6e    for(ii=0; ii<n
1610: 43 6f 6c 3b 20 69 69 2b 2b 29 7b 0a 20 20 20 20  Col; ii++){.    
1620: 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 4e    const char *zN
1630: 61 6d 65 20 3d 20 73 71 6c 69 74 65 33 5f 63 6f  ame = sqlite3_co
1640: 6c 75 6d 6e 5f 6e 61 6d 65 28 70 53 74 6d 74 2c  lumn_name(pStmt,
1650: 20 69 69 29 3b 0a 20 20 20 20 20 20 69 66 28 20   ii);.      if( 
1660: 21 7a 4e 61 6d 65 20 29 7b 0a 20 20 20 20 20 20  !zName ){.      
1670: 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4e 4f    rc = SQLITE_NO
1680: 4d 45 4d 3b 0a 20 20 20 20 20 20 20 20 67 6f 74  MEM;.        got
1690: 6f 20 6f 75 74 3b 0a 20 20 20 20 20 20 7d 0a 20  o out;.      }. 
16a0: 20 20 20 20 20 6e 42 79 74 65 73 20 2b 3d 20 28       nBytes += (
16b0: 69 6e 74 29 73 74 72 6c 65 6e 28 7a 4e 61 6d 65  int)strlen(zName
16c0: 29 2b 31 3b 0a 20 20 20 20 7d 0a 20 20 20 20 61  )+1;.    }.    a
16d0: 43 6f 6c 20 3d 20 28 63 68 61 72 20 2a 2a 29 73  Col = (char **)s
16e0: 71 6c 69 74 65 33 4d 61 6c 6c 6f 63 5a 65 72 6f  qlite3MallocZero
16f0: 28 6e 42 79 74 65 73 29 3b 0a 20 20 20 20 69 66  (nBytes);.    if
1700: 28 20 21 61 43 6f 6c 20 29 7b 0a 20 20 20 20 20  ( !aCol ){.     
1710: 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d   rc = SQLITE_NOM
1720: 45 4d 3b 0a 20 20 20 20 20 20 67 6f 74 6f 20 6f  EM;.      goto o
1730: 75 74 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 2f  ut;.    }..    /
1740: 2a 20 43 6f 70 79 20 74 68 65 20 63 6f 6c 75 6d  * Copy the colum
1750: 6e 20 6e 61 6d 65 73 20 69 6e 74 6f 20 74 68 65  n names into the
1760: 20 61 6c 6c 6f 63 61 74 65 64 20 73 70 61 63 65   allocated space
1770: 20 61 6e 64 20 73 65 74 20 75 70 20 74 68 65 0a   and set up the.
1780: 20 20 20 20 2a 2a 20 70 6f 69 6e 74 65 72 73 20      ** pointers 
1790: 69 6e 20 74 68 65 20 61 43 6f 6c 5b 5d 20 61 72  in the aCol[] ar
17a0: 72 61 79 2e 0a 20 20 20 20 2a 2f 0a 20 20 20 20  ray..    */.    
17b0: 7a 53 70 61 63 65 20 3d 20 28 63 68 61 72 20 2a  zSpace = (char *
17c0: 29 28 26 61 43 6f 6c 5b 6e 43 6f 6c 5d 29 3b 0a  )(&aCol[nCol]);.
17d0: 20 20 20 20 66 6f 72 28 69 69 3d 30 3b 20 69 69      for(ii=0; ii
17e0: 3c 6e 43 6f 6c 3b 20 69 69 2b 2b 29 7b 0a 20 20  <nCol; ii++){.  
17f0: 20 20 20 20 61 43 6f 6c 5b 69 69 5d 20 3d 20 7a      aCol[ii] = z
1800: 53 70 61 63 65 3b 0a 20 20 20 20 20 20 7a 53 70  Space;.      zSp
1810: 61 63 65 20 2b 3d 20 73 70 72 69 6e 74 66 28 7a  ace += sprintf(z
1820: 53 70 61 63 65 2c 20 22 25 73 22 2c 20 73 71 6c  Space, "%s", sql
1830: 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 6e 61 6d 65  ite3_column_name
1840: 28 70 53 74 6d 74 2c 20 69 69 29 29 3b 0a 20 20  (pStmt, ii));.  
1850: 20 20 20 20 7a 53 70 61 63 65 2b 2b 3b 0a 20 20      zSpace++;.  
1860: 20 20 7d 0a 20 20 20 20 61 73 73 65 72 74 28 20    }.    assert( 
1870: 28 7a 53 70 61 63 65 2d 6e 42 79 74 65 73 29 3d  (zSpace-nBytes)=
1880: 3d 28 63 68 61 72 20 2a 29 61 43 6f 6c 20 29 3b  =(char *)aCol );
1890: 0a 20 20 7d 0a 0a 20 20 2a 70 61 43 6f 6c 20 3d  .  }..  *paCol =
18a0: 20 61 43 6f 6c 3b 0a 20 20 2a 70 6e 43 6f 6c 20   aCol;.  *pnCol 
18b0: 3d 20 6e 43 6f 6c 3b 0a 0a 6f 75 74 3a 0a 20 20  = nCol;..out:.  
18c0: 73 71 6c 69 74 65 33 5f 66 69 6e 61 6c 69 7a 65  sqlite3_finalize
18d0: 28 70 53 74 6d 74 29 3b 0a 20 20 72 65 74 75 72  (pStmt);.  retur
18e0: 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 50  n rc;.}../*.** P
18f0: 61 72 61 6d 65 74 65 72 20 7a 54 61 62 20 69 73  arameter zTab is
1900: 20 74 68 65 20 6e 61 6d 65 20 6f 66 20 61 20 74   the name of a t
1910: 61 62 6c 65 20 69 6e 20 64 61 74 61 62 61 73 65  able in database
1920: 20 64 62 20 77 69 74 68 20 6e 43 6f 6c 20 0a 2a   db with nCol .*
1930: 2a 20 63 6f 6c 75 6d 6e 73 2e 20 54 68 69 73 20  * columns. This 
1940: 66 75 6e 63 74 69 6f 6e 20 61 6c 6c 6f 63 61 74  function allocat
1950: 65 73 20 61 6e 20 61 72 72 61 79 20 6f 66 20 69  es an array of i
1960: 6e 74 65 67 65 72 73 20 6e 43 6f 6c 20 69 6e 20  ntegers nCol in 
1970: 0a 2a 2a 20 73 69 7a 65 20 61 6e 64 20 70 6f 70  .** size and pop
1980: 75 6c 61 74 65 73 20 69 74 20 61 63 63 6f 72 64  ulates it accord
1990: 69 6e 67 20 74 6f 20 61 6e 79 20 69 6d 70 6c 69  ing to any impli
19a0: 63 69 74 20 6f 72 20 65 78 70 6c 69 63 69 74 20  cit or explicit 
19b0: 0a 2a 2a 20 69 6e 64 69 63 65 73 20 6f 6e 20 74  .** indices on t
19c0: 61 62 6c 65 20 7a 54 61 62 2e 0a 2a 2a 0a 2a 2a  able zTab..**.**
19d0: 20 49 66 20 73 75 63 63 65 73 73 66 75 6c 2c 20   If successful, 
19e0: 53 51 4c 49 54 45 5f 4f 4b 20 69 73 20 72 65 74  SQLITE_OK is ret
19f0: 75 72 6e 65 64 20 61 6e 64 20 2a 70 61 49 6e 64  urned and *paInd
1a00: 65 78 20 73 65 74 20 74 6f 20 70 6f 69 6e 74 20  ex set to point 
1a10: 0a 2a 2a 20 61 74 20 74 68 65 20 61 6c 6c 6f 63  .** at the alloc
1a20: 61 74 65 64 20 61 72 72 61 79 2e 20 4f 74 68 65  ated array. Othe
1a30: 72 77 69 73 65 2c 20 61 6e 20 65 72 72 6f 72 20  rwise, an error 
1a40: 63 6f 64 65 20 69 73 20 72 65 74 75 72 6e 65 64  code is returned
1a50: 2e 0a 2a 2a 0a 2a 2a 20 53 65 65 20 63 6f 6d 6d  ..**.** See comm
1a60: 65 6e 74 73 20 61 73 73 6f 63 69 61 74 65 64 20  ents associated 
1a70: 77 69 74 68 20 74 68 65 20 6d 65 6d 62 65 72 20  with the member 
1a80: 76 61 72 69 61 62 6c 65 20 61 49 6e 64 65 78 20  variable aIndex 
1a90: 61 62 6f 76 65 20 0a 2a 2a 20 22 73 74 72 75 63  above .** "struc
1aa0: 74 20 65 63 68 6f 5f 76 74 61 62 22 20 66 6f 72  t echo_vtab" for
1ab0: 20 64 65 74 61 69 6c 73 20 6f 66 20 74 68 65 20   details of the 
1ac0: 63 6f 6e 74 65 6e 74 73 20 6f 66 20 74 68 65 20  contents of the 
1ad0: 61 72 72 61 79 2e 0a 2a 2f 0a 73 74 61 74 69 63  array..*/.static
1ae0: 20 69 6e 74 20 67 65 74 49 6e 64 65 78 41 72 72   int getIndexArr
1af0: 61 79 28 0a 20 20 73 71 6c 69 74 65 33 20 2a 64  ay(.  sqlite3 *d
1b00: 62 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 2f  b,             /
1b10: 2a 20 44 61 74 61 62 61 73 65 20 63 6f 6e 6e 65  * Database conne
1b20: 63 74 69 6f 6e 20 2a 2f 0a 20 20 63 6f 6e 73 74  ction */.  const
1b30: 20 63 68 61 72 20 2a 7a 54 61 62 2c 20 20 20 20   char *zTab,    
1b40: 20 20 20 20 2f 2a 20 4e 61 6d 65 20 6f 66 20 74      /* Name of t
1b50: 61 62 6c 65 20 69 6e 20 64 61 74 61 62 61 73 65  able in database
1b60: 20 64 62 20 2a 2f 0a 20 20 69 6e 74 20 6e 43 6f   db */.  int nCo
1b70: 6c 2c 0a 20 20 69 6e 74 20 2a 2a 70 61 49 6e 64  l,.  int **paInd
1b80: 65 78 0a 29 7b 0a 20 20 73 71 6c 69 74 65 33 5f  ex.){.  sqlite3_
1b90: 73 74 6d 74 20 2a 70 53 74 6d 74 20 3d 20 30 3b  stmt *pStmt = 0;
1ba0: 0a 20 20 69 6e 74 20 2a 61 49 6e 64 65 78 20 3d  .  int *aIndex =
1bb0: 20 30 3b 0a 20 20 69 6e 74 20 72 63 3b 0a 20 20   0;.  int rc;.  
1bc0: 63 68 61 72 20 2a 7a 53 71 6c 3b 0a 0a 20 20 2f  char *zSql;..  /
1bd0: 2a 20 41 6c 6c 6f 63 61 74 65 20 73 70 61 63 65  * Allocate space
1be0: 20 66 6f 72 20 74 68 65 20 69 6e 64 65 78 20 61   for the index a
1bf0: 72 72 61 79 20 2a 2f 0a 20 20 61 49 6e 64 65 78  rray */.  aIndex
1c00: 20 3d 20 28 69 6e 74 20 2a 29 73 71 6c 69 74 65   = (int *)sqlite
1c10: 33 4d 61 6c 6c 6f 63 5a 65 72 6f 28 73 69 7a 65  3MallocZero(size
1c20: 6f 66 28 69 6e 74 29 20 2a 20 6e 43 6f 6c 29 3b  of(int) * nCol);
1c30: 0a 20 20 69 66 28 20 21 61 49 6e 64 65 78 20 29  .  if( !aIndex )
1c40: 7b 0a 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54  {.    rc = SQLIT
1c50: 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 67 6f 74  E_NOMEM;.    got
1c60: 6f 20 67 65 74 5f 69 6e 64 65 78 5f 61 72 72 61  o get_index_arra
1c70: 79 5f 6f 75 74 3b 0a 20 20 7d 0a 0a 20 20 2f 2a  y_out;.  }..  /*
1c80: 20 43 6f 6d 70 69 6c 65 20 61 6e 20 73 71 6c 69   Compile an sqli
1c90: 74 65 20 70 72 61 67 6d 61 20 74 6f 20 6c 6f 6f  te pragma to loo
1ca0: 70 20 74 68 72 6f 75 67 68 20 61 6c 6c 20 69 6e  p through all in
1cb0: 64 69 63 65 73 20 6f 6e 20 74 61 62 6c 65 20 7a  dices on table z
1cc0: 54 61 62 20 2a 2f 0a 20 20 7a 53 71 6c 20 3d 20  Tab */.  zSql = 
1cd0: 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28  sqlite3_mprintf(
1ce0: 22 50 52 41 47 4d 41 20 69 6e 64 65 78 5f 6c 69  "PRAGMA index_li
1cf0: 73 74 28 25 73 29 22 2c 20 7a 54 61 62 29 3b 0a  st(%s)", zTab);.
1d00: 20 20 69 66 28 20 21 7a 53 71 6c 20 29 7b 0a 20    if( !zSql ){. 
1d10: 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4e     rc = SQLITE_N
1d20: 4f 4d 45 4d 3b 0a 20 20 20 20 67 6f 74 6f 20 67  OMEM;.    goto g
1d30: 65 74 5f 69 6e 64 65 78 5f 61 72 72 61 79 5f 6f  et_index_array_o
1d40: 75 74 3b 0a 20 20 7d 0a 20 20 72 63 20 3d 20 73  ut;.  }.  rc = s
1d50: 71 6c 69 74 65 33 5f 70 72 65 70 61 72 65 28 64  qlite3_prepare(d
1d60: 62 2c 20 7a 53 71 6c 2c 20 2d 31 2c 20 26 70 53  b, zSql, -1, &pS
1d70: 74 6d 74 2c 20 30 29 3b 0a 20 20 73 71 6c 69 74  tmt, 0);.  sqlit
1d80: 65 33 5f 66 72 65 65 28 7a 53 71 6c 29 3b 0a 0a  e3_free(zSql);..
1d90: 20 20 2f 2a 20 46 6f 72 20 65 61 63 68 20 69 6e    /* For each in
1da0: 64 65 78 2c 20 66 69 67 75 72 65 20 6f 75 74 20  dex, figure out 
1db0: 74 68 65 20 6c 65 66 74 2d 6d 6f 73 74 20 63 6f  the left-most co
1dc0: 6c 75 6d 6e 20 61 6e 64 20 73 65 74 20 74 68 65  lumn and set the
1dd0: 20 0a 20 20 2a 2a 20 63 6f 72 72 65 73 70 6f 6e   .  ** correspon
1de0: 64 69 6e 67 20 65 6e 74 72 79 20 69 6e 20 61 49  ding entry in aI
1df0: 6e 64 65 78 5b 5d 20 74 6f 20 31 2e 0a 20 20 2a  ndex[] to 1..  *
1e00: 2f 0a 20 20 77 68 69 6c 65 28 20 70 53 74 6d 74  /.  while( pStmt
1e10: 20 26 26 20 73 71 6c 69 74 65 33 5f 73 74 65 70   && sqlite3_step
1e20: 28 70 53 74 6d 74 29 3d 3d 53 51 4c 49 54 45 5f  (pStmt)==SQLITE_
1e30: 52 4f 57 20 29 7b 0a 20 20 20 20 63 6f 6e 73 74  ROW ){.    const
1e40: 20 63 68 61 72 20 2a 7a 49 64 78 20 3d 20 28 63   char *zIdx = (c
1e50: 6f 6e 73 74 20 63 68 61 72 20 2a 29 73 71 6c 69  onst char *)sqli
1e60: 74 65 33 5f 63 6f 6c 75 6d 6e 5f 74 65 78 74 28  te3_column_text(
1e70: 70 53 74 6d 74 2c 20 31 29 3b 0a 20 20 20 20 73  pStmt, 1);.    s
1e80: 71 6c 69 74 65 33 5f 73 74 6d 74 20 2a 70 53 74  qlite3_stmt *pSt
1e90: 6d 74 32 20 3d 20 30 3b 0a 20 20 20 20 69 66 28  mt2 = 0;.    if(
1ea0: 20 7a 49 64 78 3d 3d 30 20 29 20 63 6f 6e 74 69   zIdx==0 ) conti
1eb0: 6e 75 65 3b 0a 20 20 20 20 7a 53 71 6c 20 3d 20  nue;.    zSql = 
1ec0: 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28  sqlite3_mprintf(
1ed0: 22 50 52 41 47 4d 41 20 69 6e 64 65 78 5f 69 6e  "PRAGMA index_in
1ee0: 66 6f 28 25 73 29 22 2c 20 7a 49 64 78 29 3b 0a  fo(%s)", zIdx);.
1ef0: 20 20 20 20 69 66 28 20 21 7a 53 71 6c 20 29 7b      if( !zSql ){
1f00: 0a 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c 49  .      rc = SQLI
1f10: 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 20 20  TE_NOMEM;.      
1f20: 67 6f 74 6f 20 67 65 74 5f 69 6e 64 65 78 5f 61  goto get_index_a
1f30: 72 72 61 79 5f 6f 75 74 3b 0a 20 20 20 20 7d 0a  rray_out;.    }.
1f40: 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33      rc = sqlite3
1f50: 5f 70 72 65 70 61 72 65 28 64 62 2c 20 7a 53 71  _prepare(db, zSq
1f60: 6c 2c 20 2d 31 2c 20 26 70 53 74 6d 74 32 2c 20  l, -1, &pStmt2, 
1f70: 30 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f  0);.    sqlite3_
1f80: 66 72 65 65 28 7a 53 71 6c 29 3b 0a 20 20 20 20  free(zSql);.    
1f90: 69 66 28 20 70 53 74 6d 74 32 20 26 26 20 73 71  if( pStmt2 && sq
1fa0: 6c 69 74 65 33 5f 73 74 65 70 28 70 53 74 6d 74  lite3_step(pStmt
1fb0: 32 29 3d 3d 53 51 4c 49 54 45 5f 52 4f 57 20 29  2)==SQLITE_ROW )
1fc0: 7b 0a 20 20 20 20 20 20 69 6e 74 20 63 69 64 20  {.      int cid 
1fd0: 3d 20 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e  = sqlite3_column
1fe0: 5f 69 6e 74 28 70 53 74 6d 74 32 2c 20 31 29 3b  _int(pStmt2, 1);
1ff0: 0a 20 20 20 20 20 20 61 73 73 65 72 74 28 20 63  .      assert( c
2000: 69 64 3e 3d 30 20 26 26 20 63 69 64 3c 6e 43 6f  id>=0 && cid<nCo
2010: 6c 20 29 3b 0a 20 20 20 20 20 20 61 49 6e 64 65  l );.      aInde
2020: 78 5b 63 69 64 5d 20 3d 20 31 3b 0a 20 20 20 20  x[cid] = 1;.    
2030: 7d 0a 20 20 20 20 69 66 28 20 70 53 74 6d 74 32  }.    if( pStmt2
2040: 20 29 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 73   ){.      rc = s
2050: 71 6c 69 74 65 33 5f 66 69 6e 61 6c 69 7a 65 28  qlite3_finalize(
2060: 70 53 74 6d 74 32 29 3b 0a 20 20 20 20 7d 0a 20  pStmt2);.    }. 
2070: 20 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54     if( rc!=SQLIT
2080: 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 67 6f  E_OK ){.      go
2090: 74 6f 20 67 65 74 5f 69 6e 64 65 78 5f 61 72 72  to get_index_arr
20a0: 61 79 5f 6f 75 74 3b 0a 20 20 20 20 7d 0a 20 20  ay_out;.    }.  
20b0: 7d 0a 0a 0a 67 65 74 5f 69 6e 64 65 78 5f 61 72  }...get_index_ar
20c0: 72 61 79 5f 6f 75 74 3a 0a 20 20 69 66 28 20 70  ray_out:.  if( p
20d0: 53 74 6d 74 20 29 7b 0a 20 20 20 20 69 6e 74 20  Stmt ){.    int 
20e0: 72 63 32 20 3d 20 73 71 6c 69 74 65 33 5f 66 69  rc2 = sqlite3_fi
20f0: 6e 61 6c 69 7a 65 28 70 53 74 6d 74 29 3b 0a 20  nalize(pStmt);. 
2100: 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54     if( rc==SQLIT
2110: 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 72 63  E_OK ){.      rc
2120: 20 3d 20 72 63 32 3b 0a 20 20 20 20 7d 0a 20 20   = rc2;.    }.  
2130: 7d 0a 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49  }.  if( rc!=SQLI
2140: 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 73 71 6c  TE_OK ){.    sql
2150: 69 74 65 33 5f 66 72 65 65 28 61 49 6e 64 65 78  ite3_free(aIndex
2160: 29 3b 0a 20 20 20 20 61 49 6e 64 65 78 20 3d 20  );.    aIndex = 
2170: 30 3b 0a 20 20 7d 0a 20 20 2a 70 61 49 6e 64 65  0;.  }.  *paInde
2180: 78 20 3d 20 61 49 6e 64 65 78 3b 0a 20 20 72 65  x = aIndex;.  re
2190: 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a  turn rc;.}../*.*
21a0: 2a 20 47 6c 6f 62 61 6c 20 54 63 6c 20 76 61 72  * Global Tcl var
21b0: 69 61 62 6c 65 20 24 65 63 68 6f 5f 6d 6f 64 75  iable $echo_modu
21c0: 6c 65 20 69 73 20 61 20 6c 69 73 74 2e 20 54 68  le is a list. Th
21d0: 69 73 20 72 6f 75 74 69 6e 65 20 61 70 70 65 6e  is routine appen
21e0: 64 73 0a 2a 2a 20 74 68 65 20 73 74 72 69 6e 67  ds.** the string
21f0: 20 65 6c 65 6d 65 6e 74 20 7a 41 72 67 20 74 6f   element zArg to
2200: 20 74 68 61 74 20 6c 69 73 74 20 69 6e 20 69 6e   that list in in
2210: 74 65 72 70 72 65 74 65 72 20 69 6e 74 65 72 70  terpreter interp
2220: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64  ..*/.static void
2230: 20 61 70 70 65 6e 64 54 6f 45 63 68 6f 4d 6f 64   appendToEchoMod
2240: 75 6c 65 28 54 63 6c 5f 49 6e 74 65 72 70 20 2a  ule(Tcl_Interp *
2250: 69 6e 74 65 72 70 2c 20 63 6f 6e 73 74 20 63 68  interp, const ch
2260: 61 72 20 2a 7a 41 72 67 29 7b 0a 20 20 69 6e 74  ar *zArg){.  int
2270: 20 66 6c 61 67 73 20 3d 20 28 54 43 4c 5f 41 50   flags = (TCL_AP
2280: 50 45 4e 44 5f 56 41 4c 55 45 20 7c 20 54 43 4c  PEND_VALUE | TCL
2290: 5f 4c 49 53 54 5f 45 4c 45 4d 45 4e 54 20 7c 20  _LIST_ELEMENT | 
22a0: 54 43 4c 5f 47 4c 4f 42 41 4c 5f 4f 4e 4c 59 29  TCL_GLOBAL_ONLY)
22b0: 3b 0a 20 20 54 63 6c 5f 53 65 74 56 61 72 28 69  ;.  Tcl_SetVar(i
22c0: 6e 74 65 72 70 2c 20 22 65 63 68 6f 5f 6d 6f 64  nterp, "echo_mod
22d0: 75 6c 65 22 2c 20 28 7a 41 72 67 3f 7a 41 72 67  ule", (zArg?zArg
22e0: 3a 22 22 29 2c 20 66 6c 61 67 73 29 3b 0a 7d 0a  :""), flags);.}.
22f0: 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63  ./*.** This func
2300: 74 69 6f 6e 20 69 73 20 63 61 6c 6c 65 64 20 66  tion is called f
2310: 72 6f 6d 20 77 69 74 68 69 6e 20 74 68 65 20 65  rom within the e
2320: 63 68 6f 2d 6d 6f 64 75 6c 65 73 20 78 43 72 65  cho-modules xCre
2330: 61 74 65 20 61 6e 64 0a 2a 2a 20 78 43 6f 6e 6e  ate and.** xConn
2340: 65 63 74 20 6d 65 74 68 6f 64 73 2e 20 54 68 65  ect methods. The
2350: 20 61 72 67 63 20 61 6e 64 20 61 72 67 76 20 61   argc and argv a
2360: 72 67 75 6d 65 6e 74 73 20 61 72 65 20 63 6f 70  rguments are cop
2370: 69 65 73 20 6f 66 20 74 68 6f 73 65 20 0a 2a 2a  ies of those .**
2380: 20 70 61 73 73 65 64 20 74 6f 20 74 68 65 20 63   passed to the c
2390: 61 6c 6c 69 6e 67 20 6d 65 74 68 6f 64 2e 20 54  alling method. T
23a0: 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20  his function is 
23b0: 72 65 73 70 6f 6e 73 69 62 6c 65 20 66 6f 72 0a  responsible for.
23c0: 2a 2a 20 63 61 6c 6c 69 6e 67 20 73 71 6c 69 74  ** calling sqlit
23d0: 65 33 5f 64 65 63 6c 61 72 65 5f 76 74 61 62 28  e3_declare_vtab(
23e0: 29 20 74 6f 20 64 65 63 6c 61 72 65 20 74 68 65  ) to declare the
23f0: 20 73 63 68 65 6d 61 20 6f 66 20 74 68 65 20 76   schema of the v
2400: 69 72 74 75 61 6c 0a 2a 2a 20 74 61 62 6c 65 20  irtual.** table 
2410: 62 65 69 6e 67 20 63 72 65 61 74 65 64 20 6f 72  being created or
2420: 20 63 6f 6e 6e 65 63 74 65 64 2e 0a 2a 2a 0a 2a   connected..**.*
2430: 2a 20 49 66 20 74 68 65 20 63 6f 6e 73 74 72 75  * If the constru
2440: 63 74 6f 72 20 77 61 73 20 70 61 73 73 65 64 20  ctor was passed 
2450: 6a 75 73 74 20 6f 6e 65 20 61 72 67 75 6d 65 6e  just one argumen
2460: 74 2c 20 69 2e 65 2e 3a 0a 2a 2a 0a 2a 2a 20 20  t, i.e.:.**.**  
2470: 20 43 52 45 41 54 45 20 54 41 42 4c 45 20 74 31   CREATE TABLE t1
2480: 20 41 53 20 65 63 68 6f 28 74 32 29 3b 0a 2a 2a   AS echo(t2);.**
2490: 0a 2a 2a 20 54 68 65 6e 20 74 32 20 69 73 20 61  .** Then t2 is a
24a0: 73 73 75 6d 65 64 20 74 6f 20 62 65 20 74 68 65  ssumed to be the
24b0: 20 6e 61 6d 65 20 6f 66 20 61 20 2a 72 65 61 6c   name of a *real
24c0: 2a 20 64 61 74 61 62 61 73 65 20 74 61 62 6c 65  * database table
24d0: 2e 20 54 68 65 0a 2a 2a 20 73 63 68 65 6d 61 20  . The.** schema 
24e0: 6f 66 20 74 68 65 20 76 69 72 74 75 61 6c 20 74  of the virtual t
24f0: 61 62 6c 65 20 69 73 20 64 65 63 6c 61 72 65 64  able is declared
2500: 20 62 79 20 70 61 73 73 69 6e 67 20 61 20 63 6f   by passing a co
2510: 70 79 20 6f 66 20 74 68 65 20 0a 2a 2a 20 43 52  py of the .** CR
2520: 45 41 54 45 20 54 41 42 4c 45 20 73 74 61 74 65  EATE TABLE state
2530: 6d 65 6e 74 20 66 6f 72 20 74 68 65 20 72 65 61  ment for the rea
2540: 6c 20 74 61 62 6c 65 20 74 6f 20 73 71 6c 69 74  l table to sqlit
2550: 65 33 5f 64 65 63 6c 61 72 65 5f 76 74 61 62 28  e3_declare_vtab(
2560: 29 2e 0a 2a 2a 20 48 65 6e 63 65 2c 20 74 68 65  )..** Hence, the
2570: 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65 20 73   virtual table s
2580: 68 6f 75 6c 64 20 68 61 76 65 20 65 78 61 63 74  hould have exact
2590: 6c 79 20 74 68 65 20 73 61 6d 65 20 63 6f 6c 75  ly the same colu
25a0: 6d 6e 20 6e 61 6d 65 73 20 61 6e 64 20 0a 2a 2a  mn names and .**
25b0: 20 74 79 70 65 73 20 61 73 20 74 68 65 20 72 65   types as the re
25c0: 61 6c 20 74 61 62 6c 65 2e 0a 2a 2f 0a 73 74 61  al table..*/.sta
25d0: 74 69 63 20 69 6e 74 20 65 63 68 6f 44 65 63 6c  tic int echoDecl
25e0: 61 72 65 56 74 61 62 28 0a 20 20 65 63 68 6f 5f  areVtab(.  echo_
25f0: 76 74 61 62 20 2a 70 56 74 61 62 2c 20 0a 20 20  vtab *pVtab, .  
2600: 73 71 6c 69 74 65 33 20 2a 64 62 20 0a 29 7b 0a  sqlite3 *db .){.
2610: 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54    int rc = SQLIT
2620: 45 5f 4f 4b 3b 0a 0a 20 20 69 66 28 20 70 56 74  E_OK;..  if( pVt
2630: 61 62 2d 3e 7a 54 61 62 6c 65 4e 61 6d 65 20 29  ab->zTableName )
2640: 7b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 73 74  {.    sqlite3_st
2650: 6d 74 20 2a 70 53 74 6d 74 20 3d 20 30 3b 0a 20  mt *pStmt = 0;. 
2660: 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f     rc = sqlite3_
2670: 70 72 65 70 61 72 65 28 64 62 2c 20 0a 20 20 20  prepare(db, .   
2680: 20 20 20 20 20 22 53 45 4c 45 43 54 20 73 71 6c       "SELECT sql
2690: 20 46 52 4f 4d 20 73 71 6c 69 74 65 5f 6d 61 73   FROM sqlite_mas
26a0: 74 65 72 20 57 48 45 52 45 20 74 79 70 65 20 3d  ter WHERE type =
26b0: 20 27 74 61 62 6c 65 27 20 41 4e 44 20 6e 61 6d   'table' AND nam
26c0: 65 20 3d 20 3f 22 2c 0a 20 20 20 20 20 20 20 20  e = ?",.        
26d0: 2d 31 2c 20 26 70 53 74 6d 74 2c 20 30 29 3b 0a  -1, &pStmt, 0);.
26e0: 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49      if( rc==SQLI
26f0: 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 73  TE_OK ){.      s
2700: 71 6c 69 74 65 33 5f 62 69 6e 64 5f 74 65 78 74  qlite3_bind_text
2710: 28 70 53 74 6d 74 2c 20 31 2c 20 70 56 74 61 62  (pStmt, 1, pVtab
2720: 2d 3e 7a 54 61 62 6c 65 4e 61 6d 65 2c 20 2d 31  ->zTableName, -1
2730: 2c 20 30 29 3b 0a 20 20 20 20 20 20 69 66 28 20  , 0);.      if( 
2740: 73 71 6c 69 74 65 33 5f 73 74 65 70 28 70 53 74  sqlite3_step(pSt
2750: 6d 74 29 3d 3d 53 51 4c 49 54 45 5f 52 4f 57 20  mt)==SQLITE_ROW 
2760: 29 7b 0a 20 20 20 20 20 20 20 20 69 6e 74 20 72  ){.        int r
2770: 63 32 3b 0a 20 20 20 20 20 20 20 20 63 6f 6e 73  c2;.        cons
2780: 74 20 63 68 61 72 20 2a 7a 43 72 65 61 74 65 54  t char *zCreateT
2790: 61 62 6c 65 20 3d 20 28 63 6f 6e 73 74 20 63 68  able = (const ch
27a0: 61 72 20 2a 29 73 71 6c 69 74 65 33 5f 63 6f 6c  ar *)sqlite3_col
27b0: 75 6d 6e 5f 74 65 78 74 28 70 53 74 6d 74 2c 20  umn_text(pStmt, 
27c0: 30 29 3b 0a 20 20 20 20 20 20 20 20 72 63 20 3d  0);.        rc =
27d0: 20 73 71 6c 69 74 65 33 5f 64 65 63 6c 61 72 65   sqlite3_declare
27e0: 5f 76 74 61 62 28 64 62 2c 20 7a 43 72 65 61 74  _vtab(db, zCreat
27f0: 65 54 61 62 6c 65 29 3b 0a 20 20 20 20 20 20 20  eTable);.       
2800: 20 72 63 32 20 3d 20 73 71 6c 69 74 65 33 5f 66   rc2 = sqlite3_f
2810: 69 6e 61 6c 69 7a 65 28 70 53 74 6d 74 29 3b 0a  inalize(pStmt);.
2820: 20 20 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d          if( rc==
2830: 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20  SQLITE_OK ){.   
2840: 20 20 20 20 20 20 20 72 63 20 3d 20 72 63 32 3b         rc = rc2;
2850: 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20  .        }.     
2860: 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20 20 20   } else {.      
2870: 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 66    rc = sqlite3_f
2880: 69 6e 61 6c 69 7a 65 28 70 53 74 6d 74 29 3b 0a  inalize(pStmt);.
2890: 20 20 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d          if( rc==
28a0: 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 20 0a 20 20  SQLITE_OK ){ .  
28b0: 20 20 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c          rc = SQL
28c0: 49 54 45 5f 45 52 52 4f 52 3b 0a 20 20 20 20 20  ITE_ERROR;.     
28d0: 20 20 20 7d 0a 20 20 20 20 20 20 7d 0a 20 20 20     }.      }.   
28e0: 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54     if( rc==SQLIT
28f0: 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20 20  E_OK ){.        
2900: 72 63 20 3d 20 67 65 74 43 6f 6c 75 6d 6e 4e 61  rc = getColumnNa
2910: 6d 65 73 28 64 62 2c 20 70 56 74 61 62 2d 3e 7a  mes(db, pVtab->z
2920: 54 61 62 6c 65 4e 61 6d 65 2c 20 26 70 56 74 61  TableName, &pVta
2930: 62 2d 3e 61 43 6f 6c 2c 20 26 70 56 74 61 62 2d  b->aCol, &pVtab-
2940: 3e 6e 43 6f 6c 29 3b 0a 20 20 20 20 20 20 7d 0a  >nCol);.      }.
2950: 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51        if( rc==SQ
2960: 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20  LITE_OK ){.     
2970: 20 20 20 72 63 20 3d 20 67 65 74 49 6e 64 65 78     rc = getIndex
2980: 41 72 72 61 79 28 64 62 2c 20 70 56 74 61 62 2d  Array(db, pVtab-
2990: 3e 7a 54 61 62 6c 65 4e 61 6d 65 2c 20 70 56 74  >zTableName, pVt
29a0: 61 62 2d 3e 6e 43 6f 6c 2c 20 26 70 56 74 61 62  ab->nCol, &pVtab
29b0: 2d 3e 61 49 6e 64 65 78 29 3b 0a 20 20 20 20 20  ->aIndex);.     
29c0: 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20   }.    }.  }..  
29d0: 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a  return rc;.}../*
29e0: 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63 74 69 6f  .** This functio
29f0: 6e 20 66 72 65 65 73 20 61 6c 6c 20 72 75 6e 74  n frees all runt
2a00: 69 6d 65 20 73 74 72 75 63 74 75 72 65 73 20 61  ime structures a
2a10: 73 73 6f 63 69 61 74 65 64 20 77 69 74 68 20 74  ssociated with t
2a20: 68 65 20 76 69 72 74 75 61 6c 0a 2a 2a 20 74 61  he virtual.** ta
2a30: 62 6c 65 20 70 56 74 61 62 2e 0a 2a 2f 0a 73 74  ble pVtab..*/.st
2a40: 61 74 69 63 20 69 6e 74 20 65 63 68 6f 44 65 73  atic int echoDes
2a50: 74 72 75 63 74 6f 72 28 73 71 6c 69 74 65 33 5f  tructor(sqlite3_
2a60: 76 74 61 62 20 2a 70 56 74 61 62 29 7b 0a 20 20  vtab *pVtab){.  
2a70: 65 63 68 6f 5f 76 74 61 62 20 2a 70 20 3d 20 28  echo_vtab *p = (
2a80: 65 63 68 6f 5f 76 74 61 62 2a 29 70 56 74 61 62  echo_vtab*)pVtab
2a90: 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65  ;.  sqlite3_free
2aa0: 28 70 2d 3e 61 49 6e 64 65 78 29 3b 0a 20 20 73  (p->aIndex);.  s
2ab0: 71 6c 69 74 65 33 5f 66 72 65 65 28 70 2d 3e 61  qlite3_free(p->a
2ac0: 43 6f 6c 29 3b 0a 20 20 73 71 6c 69 74 65 33 5f  Col);.  sqlite3_
2ad0: 66 72 65 65 28 70 2d 3e 7a 54 68 69 73 29 3b 0a  free(p->zThis);.
2ae0: 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70    sqlite3_free(p
2af0: 2d 3e 7a 54 61 62 6c 65 4e 61 6d 65 29 3b 0a 20  ->zTableName);. 
2b00: 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70 2d   sqlite3_free(p-
2b10: 3e 7a 4c 6f 67 4e 61 6d 65 29 3b 0a 20 20 73 71  >zLogName);.  sq
2b20: 6c 69 74 65 33 5f 66 72 65 65 28 70 29 3b 0a 20  lite3_free(p);. 
2b30: 20 72 65 74 75 72 6e 20 30 3b 0a 7d 0a 0a 74 79   return 0;.}..ty
2b40: 70 65 64 65 66 20 73 74 72 75 63 74 20 45 63 68  pedef struct Ech
2b50: 6f 4d 6f 64 75 6c 65 20 45 63 68 6f 4d 6f 64 75  oModule EchoModu
2b60: 6c 65 3b 0a 73 74 72 75 63 74 20 45 63 68 6f 4d  le;.struct EchoM
2b70: 6f 64 75 6c 65 20 7b 0a 20 20 54 63 6c 5f 49 6e  odule {.  Tcl_In
2b80: 74 65 72 70 20 2a 69 6e 74 65 72 70 3b 0a 7d 3b  terp *interp;.};
2b90: 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e  ../*.** This fun
2ba0: 63 74 69 6f 6e 20 69 73 20 63 61 6c 6c 65 64 20  ction is called 
2bb0: 74 6f 20 64 6f 20 74 68 65 20 77 6f 72 6b 20 6f  to do the work o
2bc0: 66 20 74 68 65 20 78 43 6f 6e 6e 65 63 74 28 29  f the xConnect()
2bd0: 20 6d 65 74 68 6f 64 20 2d 0a 2a 2a 20 74 6f 20   method -.** to 
2be0: 61 6c 6c 6f 63 61 74 65 20 74 68 65 20 72 65 71  allocate the req
2bf0: 75 69 72 65 64 20 69 6e 2d 6d 65 6d 6f 72 79 20  uired in-memory 
2c00: 73 74 72 75 63 74 75 72 65 73 20 66 6f 72 20 61  structures for a
2c10: 20 6e 65 77 6c 79 20 63 6f 6e 6e 65 63 74 65 64   newly connected
2c20: 0a 2a 2a 20 76 69 72 74 75 61 6c 20 74 61 62 6c  .** virtual tabl
2c30: 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  e..*/.static int
2c40: 20 65 63 68 6f 43 6f 6e 73 74 72 75 63 74 6f 72   echoConstructor
2c50: 28 0a 20 20 73 71 6c 69 74 65 33 20 2a 64 62 2c  (.  sqlite3 *db,
2c60: 0a 20 20 76 6f 69 64 20 2a 70 41 75 78 2c 0a 20  .  void *pAux,. 
2c70: 20 69 6e 74 20 61 72 67 63 2c 20 63 6f 6e 73 74   int argc, const
2c80: 20 63 68 61 72 20 2a 63 6f 6e 73 74 2a 61 72 67   char *const*arg
2c90: 76 2c 0a 20 20 73 71 6c 69 74 65 33 5f 76 74 61  v,.  sqlite3_vta
2ca0: 62 20 2a 2a 70 70 56 74 61 62 2c 0a 20 20 63 68  b **ppVtab,.  ch
2cb0: 61 72 20 2a 2a 70 7a 45 72 72 0a 29 7b 0a 20 20  ar **pzErr.){.  
2cc0: 69 6e 74 20 72 63 3b 0a 20 20 69 6e 74 20 69 3b  int rc;.  int i;
2cd0: 0a 20 20 65 63 68 6f 5f 76 74 61 62 20 2a 70 56  .  echo_vtab *pV
2ce0: 74 61 62 3b 0a 0a 20 20 2f 2a 20 41 6c 6c 6f 63  tab;..  /* Alloc
2cf0: 61 74 65 20 74 68 65 20 73 71 6c 69 74 65 33 5f  ate the sqlite3_
2d00: 76 74 61 62 2f 65 63 68 6f 5f 76 74 61 62 20 73  vtab/echo_vtab s
2d10: 74 72 75 63 74 75 72 65 20 69 74 73 65 6c 66 20  tructure itself 
2d20: 2a 2f 0a 20 20 70 56 74 61 62 20 3d 20 73 71 6c  */.  pVtab = sql
2d30: 69 74 65 33 4d 61 6c 6c 6f 63 5a 65 72 6f 28 20  ite3MallocZero( 
2d40: 73 69 7a 65 6f 66 28 2a 70 56 74 61 62 29 20 29  sizeof(*pVtab) )
2d50: 3b 0a 20 20 69 66 28 20 21 70 56 74 61 62 20 29  ;.  if( !pVtab )
2d60: 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c  {.    return SQL
2d70: 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 7d 0a 20  ITE_NOMEM;.  }. 
2d80: 20 70 56 74 61 62 2d 3e 69 6e 74 65 72 70 20 3d   pVtab->interp =
2d90: 20 28 28 45 63 68 6f 4d 6f 64 75 6c 65 20 2a 29   ((EchoModule *)
2da0: 70 41 75 78 29 2d 3e 69 6e 74 65 72 70 3b 0a 20  pAux)->interp;. 
2db0: 20 70 56 74 61 62 2d 3e 64 62 20 3d 20 64 62 3b   pVtab->db = db;
2dc0: 0a 0a 20 20 2f 2a 20 41 6c 6c 6f 63 61 74 65 20  ..  /* Allocate 
2dd0: 65 63 68 6f 5f 76 74 61 62 2e 7a 54 68 69 73 20  echo_vtab.zThis 
2de0: 2a 2f 0a 20 20 70 56 74 61 62 2d 3e 7a 54 68 69  */.  pVtab->zThi
2df0: 73 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72 69  s = sqlite3_mpri
2e00: 6e 74 66 28 22 25 73 22 2c 20 61 72 67 76 5b 32  ntf("%s", argv[2
2e10: 5d 29 3b 0a 20 20 69 66 28 20 21 70 56 74 61 62  ]);.  if( !pVtab
2e20: 2d 3e 7a 54 68 69 73 20 29 7b 0a 20 20 20 20 65  ->zThis ){.    e
2e30: 63 68 6f 44 65 73 74 72 75 63 74 6f 72 28 28 73  choDestructor((s
2e40: 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 29 70 56  qlite3_vtab *)pV
2e50: 74 61 62 29 3b 0a 20 20 20 20 72 65 74 75 72 6e  tab);.    return
2e60: 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20   SQLITE_NOMEM;. 
2e70: 20 7d 0a 0a 20 20 2f 2a 20 41 6c 6c 6f 63 61 74   }..  /* Allocat
2e80: 65 20 65 63 68 6f 5f 76 74 61 62 2e 7a 54 61 62  e echo_vtab.zTab
2e90: 6c 65 4e 61 6d 65 20 2a 2f 0a 20 20 69 66 28 20  leName */.  if( 
2ea0: 61 72 67 63 3e 33 20 29 7b 0a 20 20 20 20 70 56  argc>3 ){.    pV
2eb0: 74 61 62 2d 3e 7a 54 61 62 6c 65 4e 61 6d 65 20  tab->zTableName 
2ec0: 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74  = sqlite3_mprint
2ed0: 66 28 22 25 73 22 2c 20 61 72 67 76 5b 33 5d 29  f("%s", argv[3])
2ee0: 3b 0a 20 20 20 20 64 65 71 75 6f 74 65 53 74 72  ;.    dequoteStr
2ef0: 69 6e 67 28 70 56 74 61 62 2d 3e 7a 54 61 62 6c  ing(pVtab->zTabl
2f00: 65 4e 61 6d 65 29 3b 0a 20 20 20 20 69 66 28 20  eName);.    if( 
2f10: 70 56 74 61 62 2d 3e 7a 54 61 62 6c 65 4e 61 6d  pVtab->zTableNam
2f20: 65 20 26 26 20 70 56 74 61 62 2d 3e 7a 54 61 62  e && pVtab->zTab
2f30: 6c 65 4e 61 6d 65 5b 30 5d 3d 3d 27 2a 27 20 29  leName[0]=='*' )
2f40: 7b 0a 20 20 20 20 20 20 63 68 61 72 20 2a 7a 20  {.      char *z 
2f50: 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74  = sqlite3_mprint
2f60: 66 28 22 25 73 25 73 22 2c 20 61 72 67 76 5b 32  f("%s%s", argv[2
2f70: 5d 2c 20 26 28 70 56 74 61 62 2d 3e 7a 54 61 62  ], &(pVtab->zTab
2f80: 6c 65 4e 61 6d 65 5b 31 5d 29 29 3b 0a 20 20 20  leName[1]));.   
2f90: 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28     sqlite3_free(
2fa0: 70 56 74 61 62 2d 3e 7a 54 61 62 6c 65 4e 61 6d  pVtab->zTableNam
2fb0: 65 29 3b 0a 20 20 20 20 20 20 70 56 74 61 62 2d  e);.      pVtab-
2fc0: 3e 7a 54 61 62 6c 65 4e 61 6d 65 20 3d 20 7a 3b  >zTableName = z;
2fd0: 0a 20 20 20 20 20 20 70 56 74 61 62 2d 3e 69 73  .      pVtab->is
2fe0: 50 61 74 74 65 72 6e 20 3d 20 31 3b 0a 20 20 20  Pattern = 1;.   
2ff0: 20 7d 0a 20 20 20 20 69 66 28 20 21 70 56 74 61   }.    if( !pVta
3000: 62 2d 3e 7a 54 61 62 6c 65 4e 61 6d 65 20 29 7b  b->zTableName ){
3010: 0a 20 20 20 20 20 20 65 63 68 6f 44 65 73 74 72  .      echoDestr
3020: 75 63 74 6f 72 28 28 73 71 6c 69 74 65 33 5f 76  uctor((sqlite3_v
3030: 74 61 62 20 2a 29 70 56 74 61 62 29 3b 0a 20 20  tab *)pVtab);.  
3040: 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54      return SQLIT
3050: 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 7d 0a 20  E_NOMEM;.    }. 
3060: 20 7d 0a 0a 20 20 2f 2a 20 4c 6f 67 20 74 68 65   }..  /* Log the
3070: 20 61 72 67 75 6d 65 6e 74 73 20 74 6f 20 74 68   arguments to th
3080: 69 73 20 66 75 6e 63 74 69 6f 6e 20 74 6f 20 54  is function to T
3090: 63 6c 20 76 61 72 20 3a 3a 65 63 68 6f 5f 6d 6f  cl var ::echo_mo
30a0: 64 75 6c 65 20 2a 2f 0a 20 20 66 6f 72 28 69 3d  dule */.  for(i=
30b0: 30 3b 20 69 3c 61 72 67 63 3b 20 69 2b 2b 29 7b  0; i<argc; i++){
30c0: 0a 20 20 20 20 61 70 70 65 6e 64 54 6f 45 63 68  .    appendToEch
30d0: 6f 4d 6f 64 75 6c 65 28 70 56 74 61 62 2d 3e 69  oModule(pVtab->i
30e0: 6e 74 65 72 70 2c 20 61 72 67 76 5b 69 5d 29 3b  nterp, argv[i]);
30f0: 0a 20 20 7d 0a 0a 20 20 2f 2a 20 49 6e 76 6f 6b  .  }..  /* Invok
3100: 65 20 73 71 6c 69 74 65 33 5f 64 65 63 6c 61 72  e sqlite3_declar
3110: 65 5f 76 74 61 62 20 61 6e 64 20 73 65 74 20 75  e_vtab and set u
3120: 70 20 6f 74 68 65 72 20 6d 65 6d 62 65 72 73 20  p other members 
3130: 6f 66 20 74 68 65 20 65 63 68 6f 5f 76 74 61 62  of the echo_vtab
3140: 0a 20 20 2a 2a 20 73 74 72 75 63 74 75 72 65 2e  .  ** structure.
3150: 20 49 66 20 61 6e 20 65 72 72 6f 72 20 6f 63 63   If an error occ
3160: 75 72 73 2c 20 64 65 6c 65 74 65 20 74 68 65 20  urs, delete the 
3170: 73 71 6c 69 74 65 33 5f 76 74 61 62 20 73 74 72  sqlite3_vtab str
3180: 75 63 74 75 72 65 20 61 6e 64 0a 20 20 2a 2a 20  ucture and.  ** 
3190: 72 65 74 75 72 6e 20 61 6e 20 65 72 72 6f 72 20  return an error 
31a0: 63 6f 64 65 2e 0a 20 20 2a 2f 0a 20 20 72 63 20  code..  */.  rc 
31b0: 3d 20 65 63 68 6f 44 65 63 6c 61 72 65 56 74 61  = echoDeclareVta
31c0: 62 28 70 56 74 61 62 2c 20 64 62 29 3b 0a 20 20  b(pVtab, db);.  
31d0: 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f  if( rc!=SQLITE_O
31e0: 4b 20 29 7b 0a 20 20 20 20 65 63 68 6f 44 65 73  K ){.    echoDes
31f0: 74 72 75 63 74 6f 72 28 28 73 71 6c 69 74 65 33  tructor((sqlite3
3200: 5f 76 74 61 62 20 2a 29 70 56 74 61 62 29 3b 0a  _vtab *)pVtab);.
3210: 20 20 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 20      return rc;. 
3220: 20 7d 0a 0a 20 20 2f 2a 20 53 75 63 63 65 73 73   }..  /* Success
3230: 2e 20 53 65 74 20 2a 70 70 56 74 61 62 20 61 6e  . Set *ppVtab an
3240: 64 20 72 65 74 75 72 6e 20 2a 2f 0a 20 20 2a 70  d return */.  *p
3250: 70 56 74 61 62 20 3d 20 26 70 56 74 61 62 2d 3e  pVtab = &pVtab->
3260: 62 61 73 65 3b 0a 20 20 72 65 74 75 72 6e 20 53  base;.  return S
3270: 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 20  QLITE_OK;.}../* 
3280: 0a 2a 2a 20 45 63 68 6f 20 76 69 72 74 75 61 6c  .** Echo virtual
3290: 20 74 61 62 6c 65 20 6d 6f 64 75 6c 65 20 78 43   table module xC
32a0: 72 65 61 74 65 20 6d 65 74 68 6f 64 2e 0a 2a 2f  reate method..*/
32b0: 0a 73 74 61 74 69 63 20 69 6e 74 20 65 63 68 6f  .static int echo
32c0: 43 72 65 61 74 65 28 0a 20 20 73 71 6c 69 74 65  Create(.  sqlite
32d0: 33 20 2a 64 62 2c 0a 20 20 76 6f 69 64 20 2a 70  3 *db,.  void *p
32e0: 41 75 78 2c 0a 20 20 69 6e 74 20 61 72 67 63 2c  Aux,.  int argc,
32f0: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 63 6f 6e   const char *con
3300: 73 74 2a 61 72 67 76 2c 0a 20 20 73 71 6c 69 74  st*argv,.  sqlit
3310: 65 33 5f 76 74 61 62 20 2a 2a 70 70 56 74 61 62  e3_vtab **ppVtab
3320: 2c 0a 20 20 63 68 61 72 20 2a 2a 70 7a 45 72 72  ,.  char **pzErr
3330: 0a 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53  .){.  int rc = S
3340: 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 61 70 70 65  QLITE_OK;.  appe
3350: 6e 64 54 6f 45 63 68 6f 4d 6f 64 75 6c 65 28 28  ndToEchoModule((
3360: 28 45 63 68 6f 4d 6f 64 75 6c 65 20 2a 29 70 41  (EchoModule *)pA
3370: 75 78 29 2d 3e 69 6e 74 65 72 70 2c 20 22 78 43  ux)->interp, "xC
3380: 72 65 61 74 65 22 29 3b 0a 20 20 72 63 20 3d 20  reate");.  rc = 
3390: 65 63 68 6f 43 6f 6e 73 74 72 75 63 74 6f 72 28  echoConstructor(
33a0: 64 62 2c 20 70 41 75 78 2c 20 61 72 67 63 2c 20  db, pAux, argc, 
33b0: 61 72 67 76 2c 20 70 70 56 74 61 62 2c 20 70 7a  argv, ppVtab, pz
33c0: 45 72 72 29 3b 0a 0a 20 20 2f 2a 20 49 66 20 74  Err);..  /* If t
33d0: 68 65 72 65 20 77 65 72 65 20 74 77 6f 20 61 72  here were two ar
33e0: 67 75 6d 65 6e 74 73 20 70 61 73 73 65 64 20 74  guments passed t
33f0: 6f 20 74 68 65 20 6d 6f 64 75 6c 65 20 61 74 20  o the module at 
3400: 74 68 65 20 53 51 4c 20 6c 65 76 65 6c 20 0a 20  the SQL level . 
3410: 20 2a 2a 20 28 69 2e 65 2e 20 22 43 52 45 41 54   ** (i.e. "CREAT
3420: 45 20 56 49 52 54 55 41 4c 20 54 41 42 4c 45 20  E VIRTUAL TABLE 
3430: 74 62 6c 20 55 53 49 4e 47 20 65 63 68 6f 28 61  tbl USING echo(a
3440: 72 67 31 2c 20 61 72 67 32 29 22 29 2c 20 74 68  rg1, arg2)"), th
3450: 65 6e 20 0a 20 20 2a 2a 20 74 68 65 20 73 65 63  en .  ** the sec
3460: 6f 6e 64 20 61 72 67 75 6d 65 6e 74 20 69 73 20  ond argument is 
3470: 75 73 65 64 20 61 73 20 61 20 74 61 62 6c 65 20  used as a table 
3480: 6e 61 6d 65 2e 20 41 74 74 65 6d 70 74 20 74 6f  name. Attempt to
3490: 20 63 72 65 61 74 65 0a 20 20 2a 2a 20 73 75 63   create.  ** suc
34a0: 68 20 61 20 74 61 62 6c 65 20 77 69 74 68 20 61  h a table with a
34b0: 20 73 69 6e 67 6c 65 20 63 6f 6c 75 6d 6e 2c 20   single column, 
34c0: 22 6c 6f 67 6d 73 67 22 2e 20 54 68 69 73 20 74  "logmsg". This t
34d0: 61 62 6c 65 20 77 69 6c 6c 0a 20 20 2a 2a 20 62  able will.  ** b
34e0: 65 20 75 73 65 64 20 74 6f 20 6c 6f 67 20 63 61  e used to log ca
34f0: 6c 6c 73 20 74 6f 20 74 68 65 20 78 55 70 64 61  lls to the xUpda
3500: 74 65 20 6d 65 74 68 6f 64 2e 20 49 74 20 77 69  te method. It wi
3510: 6c 6c 20 62 65 20 64 65 6c 65 74 65 64 0a 20 20  ll be deleted.  
3520: 2a 2a 20 77 68 65 6e 20 74 68 65 20 76 69 72 74  ** when the virt
3530: 75 61 6c 20 74 61 62 6c 65 20 69 73 20 44 52 4f  ual table is DRO
3540: 50 65 64 2e 0a 20 20 2a 2a 0a 20 20 2a 2a 20 4e  Ped..  **.  ** N
3550: 6f 74 65 3a 20 54 68 65 20 6d 61 69 6e 20 70 6f  ote: The main po
3560: 69 6e 74 20 6f 66 20 74 68 69 73 20 69 73 20 74  int of this is t
3570: 6f 20 74 65 73 74 20 74 68 61 74 20 77 65 20 63  o test that we c
3580: 61 6e 20 64 72 6f 70 20 74 61 62 6c 65 73 0a 20  an drop tables. 
3590: 20 2a 2a 20 66 72 6f 6d 20 77 69 74 68 69 6e 20   ** from within 
35a0: 61 6e 20 78 44 65 73 74 72 6f 79 20 6d 65 74 68  an xDestroy meth
35b0: 6f 64 20 63 61 6c 6c 2e 0a 20 20 2a 2f 0a 20 20  od call..  */.  
35c0: 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  if( rc==SQLITE_O
35d0: 4b 20 26 26 20 61 72 67 63 3d 3d 35 20 29 7b 0a  K && argc==5 ){.
35e0: 20 20 20 20 63 68 61 72 20 2a 7a 53 71 6c 3b 0a      char *zSql;.
35f0: 20 20 20 20 65 63 68 6f 5f 76 74 61 62 20 2a 70      echo_vtab *p
3600: 56 74 61 62 20 3d 20 2a 28 65 63 68 6f 5f 76 74  Vtab = *(echo_vt
3610: 61 62 20 2a 2a 29 70 70 56 74 61 62 3b 0a 20 20  ab **)ppVtab;.  
3620: 20 20 70 56 74 61 62 2d 3e 7a 4c 6f 67 4e 61 6d    pVtab->zLogNam
3630: 65 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72 69  e = sqlite3_mpri
3640: 6e 74 66 28 22 25 73 22 2c 20 61 72 67 76 5b 34  ntf("%s", argv[4
3650: 5d 29 3b 0a 20 20 20 20 7a 53 71 6c 20 3d 20 73  ]);.    zSql = s
3660: 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 22  qlite3_mprintf("
3670: 43 52 45 41 54 45 20 54 41 42 4c 45 20 25 51 28  CREATE TABLE %Q(
3680: 6c 6f 67 6d 73 67 29 22 2c 20 70 56 74 61 62 2d  logmsg)", pVtab-
3690: 3e 7a 4c 6f 67 4e 61 6d 65 29 3b 0a 20 20 20 20  >zLogName);.    
36a0: 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 65 78 65  rc = sqlite3_exe
36b0: 63 28 64 62 2c 20 7a 53 71 6c 2c 20 30 2c 20 30  c(db, zSql, 0, 0
36c0: 2c 20 30 29 3b 0a 20 20 20 20 73 71 6c 69 74 65  , 0);.    sqlite
36d0: 33 5f 66 72 65 65 28 7a 53 71 6c 29 3b 0a 20 20  3_free(zSql);.  
36e0: 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45    if( rc!=SQLITE
36f0: 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 2a 70 7a  _OK ){.      *pz
3700: 45 72 72 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70  Err = sqlite3_mp
3710: 72 69 6e 74 66 28 22 25 73 22 2c 20 73 71 6c 69  rintf("%s", sqli
3720: 74 65 33 5f 65 72 72 6d 73 67 28 64 62 29 29 3b  te3_errmsg(db));
3730: 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 69 66  .    }.  }..  if
3740: 28 20 2a 70 70 56 74 61 62 20 26 26 20 72 63 21  ( *ppVtab && rc!
3750: 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20  =SQLITE_OK ){.  
3760: 20 20 65 63 68 6f 44 65 73 74 72 75 63 74 6f 72    echoDestructor
3770: 28 2a 70 70 56 74 61 62 29 3b 0a 20 20 20 20 2a  (*ppVtab);.    *
3780: 70 70 56 74 61 62 20 3d 20 30 3b 0a 20 20 7d 0a  ppVtab = 0;.  }.
3790: 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54  .  if( rc==SQLIT
37a0: 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 28 2a 28 65  E_OK ){.    (*(e
37b0: 63 68 6f 5f 76 74 61 62 2a 2a 29 70 70 56 74 61  cho_vtab**)ppVta
37c0: 62 29 2d 3e 69 6e 54 72 61 6e 73 61 63 74 69 6f  b)->inTransactio
37d0: 6e 20 3d 20 31 3b 0a 20 20 7d 0a 0a 20 20 72 65  n = 1;.  }..  re
37e0: 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 20 0a  turn rc;.}../* .
37f0: 2a 2a 20 45 63 68 6f 20 76 69 72 74 75 61 6c 20  ** Echo virtual 
3800: 74 61 62 6c 65 20 6d 6f 64 75 6c 65 20 78 43 6f  table module xCo
3810: 6e 6e 65 63 74 20 6d 65 74 68 6f 64 2e 0a 2a 2f  nnect method..*/
3820: 0a 73 74 61 74 69 63 20 69 6e 74 20 65 63 68 6f  .static int echo
3830: 43 6f 6e 6e 65 63 74 28 0a 20 20 73 71 6c 69 74  Connect(.  sqlit
3840: 65 33 20 2a 64 62 2c 0a 20 20 76 6f 69 64 20 2a  e3 *db,.  void *
3850: 70 41 75 78 2c 0a 20 20 69 6e 74 20 61 72 67 63  pAux,.  int argc
3860: 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 63 6f  , const char *co
3870: 6e 73 74 2a 61 72 67 76 2c 0a 20 20 73 71 6c 69  nst*argv,.  sqli
3880: 74 65 33 5f 76 74 61 62 20 2a 2a 70 70 56 74 61  te3_vtab **ppVta
3890: 62 2c 0a 20 20 63 68 61 72 20 2a 2a 70 7a 45 72  b,.  char **pzEr
38a0: 72 0a 29 7b 0a 20 20 61 70 70 65 6e 64 54 6f 45  r.){.  appendToE
38b0: 63 68 6f 4d 6f 64 75 6c 65 28 28 28 45 63 68 6f  choModule(((Echo
38c0: 4d 6f 64 75 6c 65 20 2a 29 70 41 75 78 29 2d 3e  Module *)pAux)->
38d0: 69 6e 74 65 72 70 2c 20 22 78 43 6f 6e 6e 65 63  interp, "xConnec
38e0: 74 22 29 3b 0a 20 20 72 65 74 75 72 6e 20 65 63  t");.  return ec
38f0: 68 6f 43 6f 6e 73 74 72 75 63 74 6f 72 28 64 62  hoConstructor(db
3900: 2c 20 70 41 75 78 2c 20 61 72 67 63 2c 20 61 72  , pAux, argc, ar
3910: 67 76 2c 20 70 70 56 74 61 62 2c 20 70 7a 45 72  gv, ppVtab, pzEr
3920: 72 29 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 45 63  r);.}../* .** Ec
3930: 68 6f 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65  ho virtual table
3940: 20 6d 6f 64 75 6c 65 20 78 44 69 73 63 6f 6e 6e   module xDisconn
3950: 65 63 74 20 6d 65 74 68 6f 64 2e 0a 2a 2f 0a 73  ect method..*/.s
3960: 74 61 74 69 63 20 69 6e 74 20 65 63 68 6f 44 69  tatic int echoDi
3970: 73 63 6f 6e 6e 65 63 74 28 73 71 6c 69 74 65 33  sconnect(sqlite3
3980: 5f 76 74 61 62 20 2a 70 56 74 61 62 29 7b 0a 20  _vtab *pVtab){. 
3990: 20 61 70 70 65 6e 64 54 6f 45 63 68 6f 4d 6f 64   appendToEchoMod
39a0: 75 6c 65 28 28 28 65 63 68 6f 5f 76 74 61 62 20  ule(((echo_vtab 
39b0: 2a 29 70 56 74 61 62 29 2d 3e 69 6e 74 65 72 70  *)pVtab)->interp
39c0: 2c 20 22 78 44 69 73 63 6f 6e 6e 65 63 74 22 29  , "xDisconnect")
39d0: 3b 0a 20 20 72 65 74 75 72 6e 20 65 63 68 6f 44  ;.  return echoD
39e0: 65 73 74 72 75 63 74 6f 72 28 70 56 74 61 62 29  estructor(pVtab)
39f0: 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 45 63 68 6f  ;.}../* .** Echo
3a00: 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65 20 6d   virtual table m
3a10: 6f 64 75 6c 65 20 78 44 65 73 74 72 6f 79 20 6d  odule xDestroy m
3a20: 65 74 68 6f 64 2e 0a 2a 2f 0a 73 74 61 74 69 63  ethod..*/.static
3a30: 20 69 6e 74 20 65 63 68 6f 44 65 73 74 72 6f 79   int echoDestroy
3a40: 28 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 70  (sqlite3_vtab *p
3a50: 56 74 61 62 29 7b 0a 20 20 69 6e 74 20 72 63 20  Vtab){.  int rc 
3a60: 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 65  = SQLITE_OK;.  e
3a70: 63 68 6f 5f 76 74 61 62 20 2a 70 20 3d 20 28 65  cho_vtab *p = (e
3a80: 63 68 6f 5f 76 74 61 62 20 2a 29 70 56 74 61 62  cho_vtab *)pVtab
3a90: 3b 0a 20 20 61 70 70 65 6e 64 54 6f 45 63 68 6f  ;.  appendToEcho
3aa0: 4d 6f 64 75 6c 65 28 28 28 65 63 68 6f 5f 76 74  Module(((echo_vt
3ab0: 61 62 20 2a 29 70 56 74 61 62 29 2d 3e 69 6e 74  ab *)pVtab)->int
3ac0: 65 72 70 2c 20 22 78 44 65 73 74 72 6f 79 22 29  erp, "xDestroy")
3ad0: 3b 0a 0a 20 20 2f 2a 20 44 72 6f 70 20 74 68 65  ;..  /* Drop the
3ae0: 20 22 6c 6f 67 22 20 74 61 62 6c 65 2c 20 69 66   "log" table, if
3af0: 20 6f 6e 65 20 65 78 69 73 74 73 20 28 73 65 65   one exists (see
3b00: 20 65 63 68 6f 43 72 65 61 74 65 28 29 20 66 6f   echoCreate() fo
3b10: 72 20 64 65 74 61 69 6c 73 29 20 2a 2f 0a 20 20  r details) */.  
3b20: 69 66 28 20 70 20 26 26 20 70 2d 3e 7a 4c 6f 67  if( p && p->zLog
3b30: 4e 61 6d 65 20 29 7b 0a 20 20 20 20 63 68 61 72  Name ){.    char
3b40: 20 2a 7a 53 71 6c 3b 0a 20 20 20 20 7a 53 71 6c   *zSql;.    zSql
3b50: 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e   = sqlite3_mprin
3b60: 74 66 28 22 44 52 4f 50 20 54 41 42 4c 45 20 25  tf("DROP TABLE %
3b70: 51 22 2c 20 70 2d 3e 7a 4c 6f 67 4e 61 6d 65 29  Q", p->zLogName)
3b80: 3b 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74  ;.    rc = sqlit
3b90: 65 33 5f 65 78 65 63 28 70 2d 3e 64 62 2c 20 7a  e3_exec(p->db, z
3ba0: 53 71 6c 2c 20 30 2c 20 30 2c 20 30 29 3b 0a 20  Sql, 0, 0, 0);. 
3bb0: 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28     sqlite3_free(
3bc0: 7a 53 71 6c 29 3b 0a 20 20 7d 0a 0a 20 20 69 66  zSql);.  }..  if
3bd0: 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
3be0: 29 7b 0a 20 20 20 20 72 63 20 3d 20 65 63 68 6f  ){.    rc = echo
3bf0: 44 65 73 74 72 75 63 74 6f 72 28 70 56 74 61 62  Destructor(pVtab
3c00: 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20  );.  }.  return 
3c10: 72 63 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 45 63  rc;.}../* .** Ec
3c20: 68 6f 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65  ho virtual table
3c30: 20 6d 6f 64 75 6c 65 20 78 4f 70 65 6e 20 6d 65   module xOpen me
3c40: 74 68 6f 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  thod..*/.static 
3c50: 69 6e 74 20 65 63 68 6f 4f 70 65 6e 28 73 71 6c  int echoOpen(sql
3c60: 69 74 65 33 5f 76 74 61 62 20 2a 70 56 54 61 62  ite3_vtab *pVTab
3c70: 2c 20 73 71 6c 69 74 65 33 5f 76 74 61 62 5f 63  , sqlite3_vtab_c
3c80: 75 72 73 6f 72 20 2a 2a 70 70 43 75 72 73 6f 72  ursor **ppCursor
3c90: 29 7b 0a 20 20 65 63 68 6f 5f 63 75 72 73 6f 72  ){.  echo_cursor
3ca0: 20 2a 70 43 75 72 3b 0a 20 20 69 66 28 20 73 69   *pCur;.  if( si
3cb0: 6d 75 6c 61 74 65 56 74 61 62 45 72 72 6f 72 28  mulateVtabError(
3cc0: 28 65 63 68 6f 5f 76 74 61 62 20 2a 29 70 56 54  (echo_vtab *)pVT
3cd0: 61 62 2c 20 22 78 4f 70 65 6e 22 29 20 29 7b 0a  ab, "xOpen") ){.
3ce0: 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54      return SQLIT
3cf0: 45 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a 20 20 70  E_ERROR;.  }.  p
3d00: 43 75 72 20 3d 20 73 71 6c 69 74 65 33 4d 61 6c  Cur = sqlite3Mal
3d10: 6c 6f 63 5a 65 72 6f 28 73 69 7a 65 6f 66 28 65  locZero(sizeof(e
3d20: 63 68 6f 5f 63 75 72 73 6f 72 29 29 3b 0a 20 20  cho_cursor));.  
3d30: 2a 70 70 43 75 72 73 6f 72 20 3d 20 28 73 71 6c  *ppCursor = (sql
3d40: 69 74 65 33 5f 76 74 61 62 5f 63 75 72 73 6f 72  ite3_vtab_cursor
3d50: 20 2a 29 70 43 75 72 3b 0a 20 20 72 65 74 75 72   *)pCur;.  retur
3d60: 6e 20 28 70 43 75 72 20 3f 20 53 51 4c 49 54 45  n (pCur ? SQLITE
3d70: 5f 4f 4b 20 3a 20 53 51 4c 49 54 45 5f 4e 4f 4d  _OK : SQLITE_NOM
3d80: 45 4d 29 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 45  EM);.}../* .** E
3d90: 63 68 6f 20 76 69 72 74 75 61 6c 20 74 61 62 6c  cho virtual tabl
3da0: 65 20 6d 6f 64 75 6c 65 20 78 43 6c 6f 73 65 20  e module xClose 
3db0: 6d 65 74 68 6f 64 2e 0a 2a 2f 0a 73 74 61 74 69  method..*/.stati
3dc0: 63 20 69 6e 74 20 65 63 68 6f 43 6c 6f 73 65 28  c int echoClose(
3dd0: 73 71 6c 69 74 65 33 5f 76 74 61 62 5f 63 75 72  sqlite3_vtab_cur
3de0: 73 6f 72 20 2a 63 75 72 29 7b 0a 20 20 69 6e 74  sor *cur){.  int
3df0: 20 72 63 3b 0a 20 20 65 63 68 6f 5f 63 75 72 73   rc;.  echo_curs
3e00: 6f 72 20 2a 70 43 75 72 20 3d 20 28 65 63 68 6f  or *pCur = (echo
3e10: 5f 63 75 72 73 6f 72 20 2a 29 63 75 72 3b 0a 20  _cursor *)cur;. 
3e20: 20 73 71 6c 69 74 65 33 5f 73 74 6d 74 20 2a 70   sqlite3_stmt *p
3e30: 53 74 6d 74 20 3d 20 70 43 75 72 2d 3e 70 53 74  Stmt = pCur->pSt
3e40: 6d 74 3b 0a 20 20 70 43 75 72 2d 3e 70 53 74 6d  mt;.  pCur->pStm
3e50: 74 20 3d 20 30 3b 0a 20 20 73 71 6c 69 74 65 33  t = 0;.  sqlite3
3e60: 5f 66 72 65 65 28 70 43 75 72 29 3b 0a 20 20 72  _free(pCur);.  r
3e70: 63 20 3d 20 73 71 6c 69 74 65 33 5f 66 69 6e 61  c = sqlite3_fina
3e80: 6c 69 7a 65 28 70 53 74 6d 74 29 3b 0a 20 20 72  lize(pStmt);.  r
3e90: 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a  eturn rc;.}../*.
3ea0: 2a 2a 20 52 65 74 75 72 6e 20 6e 6f 6e 2d 7a 65  ** Return non-ze
3eb0: 72 6f 20 69 66 20 74 68 65 20 63 75 72 73 6f 72  ro if the cursor
3ec0: 20 64 6f 65 73 20 6e 6f 74 20 63 75 72 72 65 6e   does not curren
3ed0: 74 6c 79 20 70 6f 69 6e 74 20 74 6f 20 61 20 76  tly point to a v
3ee0: 61 6c 69 64 20 72 65 63 6f 72 64 0a 2a 2a 20 28  alid record.** (
3ef0: 69 2e 65 20 69 66 20 74 68 65 20 73 63 61 6e 20  i.e if the scan 
3f00: 68 61 73 20 66 69 6e 69 73 68 65 64 29 2c 20 6f  has finished), o
3f10: 72 20 7a 65 72 6f 20 6f 74 68 65 72 77 69 73 65  r zero otherwise
3f20: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
3f30: 65 63 68 6f 45 6f 66 28 73 71 6c 69 74 65 33 5f  echoEof(sqlite3_
3f40: 76 74 61 62 5f 63 75 72 73 6f 72 20 2a 63 75 72  vtab_cursor *cur
3f50: 29 7b 0a 20 20 72 65 74 75 72 6e 20 28 28 28 65  ){.  return (((e
3f60: 63 68 6f 5f 63 75 72 73 6f 72 20 2a 29 63 75 72  cho_cursor *)cur
3f70: 29 2d 3e 70 53 74 6d 74 20 3f 20 30 20 3a 20 31  )->pStmt ? 0 : 1
3f80: 29 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 45 63 68  );.}../* .** Ech
3f90: 6f 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65 20  o virtual table 
3fa0: 6d 6f 64 75 6c 65 20 78 4e 65 78 74 20 6d 65 74  module xNext met
3fb0: 68 6f 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  hod..*/.static i
3fc0: 6e 74 20 65 63 68 6f 4e 65 78 74 28 73 71 6c 69  nt echoNext(sqli
3fd0: 74 65 33 5f 76 74 61 62 5f 63 75 72 73 6f 72 20  te3_vtab_cursor 
3fe0: 2a 63 75 72 29 7b 0a 20 20 69 6e 74 20 72 63 20  *cur){.  int rc 
3ff0: 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 65  = SQLITE_OK;.  e
4000: 63 68 6f 5f 63 75 72 73 6f 72 20 2a 70 43 75 72  cho_cursor *pCur
4010: 20 3d 20 28 65 63 68 6f 5f 63 75 72 73 6f 72 20   = (echo_cursor 
4020: 2a 29 63 75 72 3b 0a 0a 20 20 69 66 28 20 73 69  *)cur;..  if( si
4030: 6d 75 6c 61 74 65 56 74 61 62 45 72 72 6f 72 28  mulateVtabError(
4040: 28 65 63 68 6f 5f 76 74 61 62 20 2a 29 28 63 75  (echo_vtab *)(cu
4050: 72 2d 3e 70 56 74 61 62 29 2c 20 22 78 4e 65 78  r->pVtab), "xNex
4060: 74 22 29 20 29 7b 0a 20 20 20 20 72 65 74 75 72  t") ){.    retur
4070: 6e 20 53 51 4c 49 54 45 5f 45 52 52 4f 52 3b 0a  n SQLITE_ERROR;.
4080: 20 20 7d 0a 0a 20 20 69 66 28 20 70 43 75 72 2d    }..  if( pCur-
4090: 3e 70 53 74 6d 74 20 29 7b 0a 20 20 20 20 72 63  >pStmt ){.    rc
40a0: 20 3d 20 73 71 6c 69 74 65 33 5f 73 74 65 70 28   = sqlite3_step(
40b0: 70 43 75 72 2d 3e 70 53 74 6d 74 29 3b 0a 20 20  pCur->pStmt);.  
40c0: 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
40d0: 5f 52 4f 57 20 29 7b 0a 20 20 20 20 20 20 72 63  _ROW ){.      rc
40e0: 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20   = SQLITE_OK;.  
40f0: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 72    }else{.      r
4100: 63 20 3d 20 73 71 6c 69 74 65 33 5f 66 69 6e 61  c = sqlite3_fina
4110: 6c 69 7a 65 28 70 43 75 72 2d 3e 70 53 74 6d 74  lize(pCur->pStmt
4120: 29 3b 0a 20 20 20 20 20 20 70 43 75 72 2d 3e 70  );.      pCur->p
4130: 53 74 6d 74 20 3d 20 30 3b 0a 20 20 20 20 7d 0a  Stmt = 0;.    }.
4140: 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 72 63    }..  return rc
4150: 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 45 63 68 6f  ;.}../* .** Echo
4160: 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65 20 6d   virtual table m
4170: 6f 64 75 6c 65 20 78 43 6f 6c 75 6d 6e 20 6d 65  odule xColumn me
4180: 74 68 6f 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  thod..*/.static 
4190: 69 6e 74 20 65 63 68 6f 43 6f 6c 75 6d 6e 28 73  int echoColumn(s
41a0: 71 6c 69 74 65 33 5f 76 74 61 62 5f 63 75 72 73  qlite3_vtab_curs
41b0: 6f 72 20 2a 63 75 72 2c 20 73 71 6c 69 74 65 33  or *cur, sqlite3
41c0: 5f 63 6f 6e 74 65 78 74 20 2a 63 74 78 2c 20 69  _context *ctx, i
41d0: 6e 74 20 69 29 7b 0a 20 20 69 6e 74 20 69 43 6f  nt i){.  int iCo
41e0: 6c 20 3d 20 69 20 2b 20 31 3b 0a 20 20 73 71 6c  l = i + 1;.  sql
41f0: 69 74 65 33 5f 73 74 6d 74 20 2a 70 53 74 6d 74  ite3_stmt *pStmt
4200: 20 3d 20 28 28 65 63 68 6f 5f 63 75 72 73 6f 72   = ((echo_cursor
4210: 20 2a 29 63 75 72 29 2d 3e 70 53 74 6d 74 3b 0a   *)cur)->pStmt;.
4220: 0a 20 20 69 66 28 20 73 69 6d 75 6c 61 74 65 56  .  if( simulateV
4230: 74 61 62 45 72 72 6f 72 28 28 65 63 68 6f 5f 76  tabError((echo_v
4240: 74 61 62 20 2a 29 28 63 75 72 2d 3e 70 56 74 61  tab *)(cur->pVta
4250: 62 29 2c 20 22 78 43 6f 6c 75 6d 6e 22 29 20 29  b), "xColumn") )
4260: 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c  {.    return SQL
4270: 49 54 45 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a 0a  ITE_ERROR;.  }..
4280: 20 20 69 66 28 20 21 70 53 74 6d 74 20 29 7b 0a    if( !pStmt ){.
4290: 20 20 20 20 73 71 6c 69 74 65 33 5f 72 65 73 75      sqlite3_resu
42a0: 6c 74 5f 6e 75 6c 6c 28 63 74 78 29 3b 0a 20 20  lt_null(ctx);.  
42b0: 7d 65 6c 73 65 7b 0a 20 20 20 20 61 73 73 65 72  }else{.    asser
42c0: 74 28 20 73 71 6c 69 74 65 33 5f 64 61 74 61 5f  t( sqlite3_data_
42d0: 63 6f 75 6e 74 28 70 53 74 6d 74 29 3e 69 43 6f  count(pStmt)>iCo
42e0: 6c 20 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33  l );.    sqlite3
42f0: 5f 72 65 73 75 6c 74 5f 76 61 6c 75 65 28 63 74  _result_value(ct
4300: 78 2c 20 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d  x, sqlite3_colum
4310: 6e 5f 76 61 6c 75 65 28 70 53 74 6d 74 2c 20 69  n_value(pStmt, i
4320: 43 6f 6c 29 29 3b 0a 20 20 7d 0a 20 20 72 65 74  Col));.  }.  ret
4330: 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d  urn SQLITE_OK;.}
4340: 0a 0a 2f 2a 20 0a 2a 2a 20 45 63 68 6f 20 76 69  ../* .** Echo vi
4350: 72 74 75 61 6c 20 74 61 62 6c 65 20 6d 6f 64 75  rtual table modu
4360: 6c 65 20 78 52 6f 77 69 64 20 6d 65 74 68 6f 64  le xRowid method
4370: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
4380: 65 63 68 6f 52 6f 77 69 64 28 73 71 6c 69 74 65  echoRowid(sqlite
4390: 33 5f 76 74 61 62 5f 63 75 72 73 6f 72 20 2a 63  3_vtab_cursor *c
43a0: 75 72 2c 20 73 71 6c 69 74 65 5f 69 6e 74 36 34  ur, sqlite_int64
43b0: 20 2a 70 52 6f 77 69 64 29 7b 0a 20 20 73 71 6c   *pRowid){.  sql
43c0: 69 74 65 33 5f 73 74 6d 74 20 2a 70 53 74 6d 74  ite3_stmt *pStmt
43d0: 20 3d 20 28 28 65 63 68 6f 5f 63 75 72 73 6f 72   = ((echo_cursor
43e0: 20 2a 29 63 75 72 29 2d 3e 70 53 74 6d 74 3b 0a   *)cur)->pStmt;.
43f0: 0a 20 20 69 66 28 20 73 69 6d 75 6c 61 74 65 56  .  if( simulateV
4400: 74 61 62 45 72 72 6f 72 28 28 65 63 68 6f 5f 76  tabError((echo_v
4410: 74 61 62 20 2a 29 28 63 75 72 2d 3e 70 56 74 61  tab *)(cur->pVta
4420: 62 29 2c 20 22 78 52 6f 77 69 64 22 29 20 29 7b  b), "xRowid") ){
4430: 0a 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49  .    return SQLI
4440: 54 45 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a 0a 20  TE_ERROR;.  }.. 
4450: 20 2a 70 52 6f 77 69 64 20 3d 20 73 71 6c 69 74   *pRowid = sqlit
4460: 65 33 5f 63 6f 6c 75 6d 6e 5f 69 6e 74 36 34 28  e3_column_int64(
4470: 70 53 74 6d 74 2c 20 30 29 3b 0a 20 20 72 65 74  pStmt, 0);.  ret
4480: 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d  urn SQLITE_OK;.}
4490: 0a 0a 2f 2a 0a 2a 2a 20 43 6f 6d 70 75 74 65 20  ../*.** Compute 
44a0: 61 20 73 69 6d 70 6c 65 20 68 61 73 68 20 6f 66  a simple hash of
44b0: 20 74 68 65 20 6e 75 6c 6c 20 74 65 72 6d 69 6e   the null termin
44c0: 61 74 65 64 20 73 74 72 69 6e 67 20 7a 53 74 72  ated string zStr
44d0: 69 6e 67 2e 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20  ing..**.** This 
44e0: 6d 6f 64 75 6c 65 20 75 73 65 73 20 6f 6e 6c 79  module uses only
44f0: 20 73 71 6c 69 74 65 33 5f 69 6e 64 65 78 5f 69   sqlite3_index_i
4500: 6e 66 6f 2e 69 64 78 53 74 72 2c 20 6e 6f 74 20  nfo.idxStr, not 
4510: 0a 2a 2a 20 73 71 6c 69 74 65 33 5f 69 6e 64 65  .** sqlite3_inde
4520: 78 5f 69 6e 66 6f 2e 69 64 78 4e 75 6d 2e 20 53  x_info.idxNum. S
4530: 6f 20 74 6f 20 74 65 73 74 20 69 64 78 4e 75 6d  o to test idxNum
4540: 2c 20 77 68 65 6e 20 69 64 78 53 74 72 20 69 73  , when idxStr is
4550: 20 73 65 74 0a 2a 2a 20 69 6e 20 65 63 68 6f 42   set.** in echoB
4560: 65 73 74 49 6e 64 65 78 28 29 2c 20 69 64 78 4e  estIndex(), idxN
4570: 75 6d 20 69 73 20 73 65 74 20 74 6f 20 74 68 65  um is set to the
4580: 20 63 6f 72 72 65 73 70 6f 6e 64 69 6e 67 20 68   corresponding h
4590: 61 73 68 20 76 61 6c 75 65 2e 0a 2a 2a 20 49 6e  ash value..** In
45a0: 20 65 63 68 6f 46 69 6c 74 65 72 28 29 2c 20 63   echoFilter(), c
45b0: 6f 64 65 20 61 73 73 65 72 74 28 29 73 20 74 68  ode assert()s th
45c0: 61 74 20 74 68 65 20 73 75 70 70 6c 69 65 64 20  at the supplied 
45d0: 69 64 78 4e 75 6d 20 76 61 6c 75 65 20 69 73 0a  idxNum value is.
45e0: 2a 2a 20 69 6e 64 65 65 64 20 74 68 65 20 68 61  ** indeed the ha
45f0: 73 68 20 6f 66 20 74 68 65 20 73 75 70 70 6c 69  sh of the suppli
4600: 65 64 20 69 64 78 53 74 72 2e 0a 2a 2f 0a 73 74  ed idxStr..*/.st
4610: 61 74 69 63 20 69 6e 74 20 68 61 73 68 53 74 72  atic int hashStr
4620: 69 6e 67 28 63 6f 6e 73 74 20 63 68 61 72 20 2a  ing(const char *
4630: 7a 53 74 72 69 6e 67 29 7b 0a 20 20 69 6e 74 20  zString){.  int 
4640: 76 61 6c 20 3d 20 30 3b 0a 20 20 69 6e 74 20 69  val = 0;.  int i
4650: 69 3b 0a 20 20 66 6f 72 28 69 69 3d 30 3b 20 7a  i;.  for(ii=0; z
4660: 53 74 72 69 6e 67 5b 69 69 5d 3b 20 69 69 2b 2b  String[ii]; ii++
4670: 29 7b 0a 20 20 20 20 76 61 6c 20 3d 20 28 76 61  ){.    val = (va
4680: 6c 20 3c 3c 20 33 29 20 2b 20 28 69 6e 74 29 7a  l << 3) + (int)z
4690: 53 74 72 69 6e 67 5b 69 69 5d 3b 0a 20 20 7d 0a  String[ii];.  }.
46a0: 20 20 72 65 74 75 72 6e 20 76 61 6c 3b 0a 7d 0a    return val;.}.
46b0: 0a 2f 2a 20 0a 2a 2a 20 45 63 68 6f 20 76 69 72  ./* .** Echo vir
46c0: 74 75 61 6c 20 74 61 62 6c 65 20 6d 6f 64 75 6c  tual table modul
46d0: 65 20 78 46 69 6c 74 65 72 20 6d 65 74 68 6f 64  e xFilter method
46e0: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
46f0: 65 63 68 6f 46 69 6c 74 65 72 28 0a 20 20 73 71  echoFilter(.  sq
4700: 6c 69 74 65 33 5f 76 74 61 62 5f 63 75 72 73 6f  lite3_vtab_curso
4710: 72 20 2a 70 56 74 61 62 43 75 72 73 6f 72 2c 20  r *pVtabCursor, 
4720: 0a 20 20 69 6e 74 20 69 64 78 4e 75 6d 2c 20 63  .  int idxNum, c
4730: 6f 6e 73 74 20 63 68 61 72 20 2a 69 64 78 53 74  onst char *idxSt
4740: 72 2c 0a 20 20 69 6e 74 20 61 72 67 63 2c 20 73  r,.  int argc, s
4750: 71 6c 69 74 65 33 5f 76 61 6c 75 65 20 2a 2a 61  qlite3_value **a
4760: 72 67 76 0a 29 7b 0a 20 20 69 6e 74 20 72 63 3b  rgv.){.  int rc;
4770: 0a 20 20 69 6e 74 20 69 3b 0a 0a 20 20 65 63 68  .  int i;..  ech
4780: 6f 5f 63 75 72 73 6f 72 20 2a 70 43 75 72 20 3d  o_cursor *pCur =
4790: 20 28 65 63 68 6f 5f 63 75 72 73 6f 72 20 2a 29   (echo_cursor *)
47a0: 70 56 74 61 62 43 75 72 73 6f 72 3b 0a 20 20 65  pVtabCursor;.  e
47b0: 63 68 6f 5f 76 74 61 62 20 2a 70 56 74 61 62 20  cho_vtab *pVtab 
47c0: 3d 20 28 65 63 68 6f 5f 76 74 61 62 20 2a 29 70  = (echo_vtab *)p
47d0: 56 74 61 62 43 75 72 73 6f 72 2d 3e 70 56 74 61  VtabCursor->pVta
47e0: 62 3b 0a 20 20 73 71 6c 69 74 65 33 20 2a 64 62  b;.  sqlite3 *db
47f0: 20 3d 20 70 56 74 61 62 2d 3e 64 62 3b 0a 0a 20   = pVtab->db;.. 
4800: 20 69 66 28 20 73 69 6d 75 6c 61 74 65 56 74 61   if( simulateVta
4810: 62 45 72 72 6f 72 28 70 56 74 61 62 2c 20 22 78  bError(pVtab, "x
4820: 46 69 6c 74 65 72 22 29 20 29 7b 0a 20 20 20 20  Filter") ){.    
4830: 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 45 52  return SQLITE_ER
4840: 52 4f 52 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 43  ROR;.  }..  /* C
4850: 68 65 63 6b 20 74 68 61 74 20 69 64 78 4e 75 6d  heck that idxNum
4860: 20 6d 61 74 63 68 65 73 20 69 64 78 53 74 72 20   matches idxStr 
4870: 2a 2f 0a 20 20 61 73 73 65 72 74 28 20 69 64 78  */.  assert( idx
4880: 4e 75 6d 3d 3d 68 61 73 68 53 74 72 69 6e 67 28  Num==hashString(
4890: 69 64 78 53 74 72 29 20 29 3b 0a 0a 20 20 2f 2a  idxStr) );..  /*
48a0: 20 4c 6f 67 20 61 72 67 75 6d 65 6e 74 73 20 74   Log arguments t
48b0: 6f 20 74 68 65 20 3a 3a 65 63 68 6f 5f 6d 6f 64  o the ::echo_mod
48c0: 75 6c 65 20 54 63 6c 20 76 61 72 69 61 62 6c 65  ule Tcl variable
48d0: 20 2a 2f 0a 20 20 61 70 70 65 6e 64 54 6f 45 63   */.  appendToEc
48e0: 68 6f 4d 6f 64 75 6c 65 28 70 56 74 61 62 2d 3e  hoModule(pVtab->
48f0: 69 6e 74 65 72 70 2c 20 22 78 46 69 6c 74 65 72  interp, "xFilter
4900: 22 29 3b 0a 20 20 61 70 70 65 6e 64 54 6f 45 63  ");.  appendToEc
4910: 68 6f 4d 6f 64 75 6c 65 28 70 56 74 61 62 2d 3e  hoModule(pVtab->
4920: 69 6e 74 65 72 70 2c 20 69 64 78 53 74 72 29 3b  interp, idxStr);
4930: 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 61 72  .  for(i=0; i<ar
4940: 67 63 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 61 70  gc; i++){.    ap
4950: 70 65 6e 64 54 6f 45 63 68 6f 4d 6f 64 75 6c 65  pendToEchoModule
4960: 28 70 56 74 61 62 2d 3e 69 6e 74 65 72 70 2c 20  (pVtab->interp, 
4970: 28 63 6f 6e 73 74 20 63 68 61 72 2a 29 73 71 6c  (const char*)sql
4980: 69 74 65 33 5f 76 61 6c 75 65 5f 74 65 78 74 28  ite3_value_text(
4990: 61 72 67 76 5b 69 5d 29 29 3b 0a 20 20 7d 0a 0a  argv[i]));.  }..
49a0: 20 20 73 71 6c 69 74 65 33 5f 66 69 6e 61 6c 69    sqlite3_finali
49b0: 7a 65 28 70 43 75 72 2d 3e 70 53 74 6d 74 29 3b  ze(pCur->pStmt);
49c0: 0a 20 20 70 43 75 72 2d 3e 70 53 74 6d 74 20 3d  .  pCur->pStmt =
49d0: 20 30 3b 0a 0a 20 20 2f 2a 20 50 72 65 70 61 72   0;..  /* Prepar
49e0: 65 20 74 68 65 20 53 51 4c 20 73 74 61 74 65 6d  e the SQL statem
49f0: 65 6e 74 20 63 72 65 61 74 65 64 20 62 79 20 65  ent created by e
4a00: 63 68 6f 42 65 73 74 49 6e 64 65 78 20 61 6e 64  choBestIndex and
4a10: 20 62 69 6e 64 20 74 68 65 0a 20 20 2a 2a 20 72   bind the.  ** r
4a20: 75 6e 74 69 6d 65 20 70 61 72 61 6d 65 74 65 72  untime parameter
4a30: 73 20 70 61 73 73 65 64 20 74 6f 20 74 68 69 73  s passed to this
4a40: 20 66 75 6e 63 74 69 6f 6e 20 74 6f 20 69 74 2e   function to it.
4a50: 0a 20 20 2a 2f 0a 20 20 72 63 20 3d 20 73 71 6c  .  */.  rc = sql
4a60: 69 74 65 33 5f 70 72 65 70 61 72 65 28 64 62 2c  ite3_prepare(db,
4a70: 20 69 64 78 53 74 72 2c 20 2d 31 2c 20 26 70 43   idxStr, -1, &pC
4a80: 75 72 2d 3e 70 53 74 6d 74 2c 20 30 29 3b 0a 20  ur->pStmt, 0);. 
4a90: 20 61 73 73 65 72 74 28 20 70 43 75 72 2d 3e 70   assert( pCur->p
4aa0: 53 74 6d 74 20 7c 7c 20 72 63 21 3d 53 51 4c 49  Stmt || rc!=SQLI
4ab0: 54 45 5f 4f 4b 20 29 3b 0a 20 20 66 6f 72 28 69  TE_OK );.  for(i
4ac0: 3d 30 3b 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  =0; rc==SQLITE_O
4ad0: 4b 20 26 26 20 69 3c 61 72 67 63 3b 20 69 2b 2b  K && i<argc; i++
4ae0: 29 7b 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69  ){.    rc = sqli
4af0: 74 65 33 5f 62 69 6e 64 5f 76 61 6c 75 65 28 70  te3_bind_value(p
4b00: 43 75 72 2d 3e 70 53 74 6d 74 2c 20 69 2b 31 2c  Cur->pStmt, i+1,
4b10: 20 61 72 67 76 5b 69 5d 29 3b 0a 20 20 7d 0a 0a   argv[i]);.  }..
4b20: 20 20 2f 2a 20 49 66 20 65 76 65 72 79 74 68 69    /* If everythi
4b30: 6e 67 20 77 61 73 20 73 75 63 63 65 73 73 66 75  ng was successfu
4b40: 6c 2c 20 61 64 76 61 6e 63 65 20 74 6f 20 74 68  l, advance to th
4b50: 65 20 66 69 72 73 74 20 72 6f 77 20 6f 66 20 74  e first row of t
4b60: 68 65 20 73 63 61 6e 20 2a 2f 0a 20 20 69 66 28  he scan */.  if(
4b70: 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc==SQLITE_OK )
4b80: 7b 0a 20 20 20 20 72 63 20 3d 20 65 63 68 6f 4e  {.    rc = echoN
4b90: 65 78 74 28 70 56 74 61 62 43 75 72 73 6f 72 29  ext(pVtabCursor)
4ba0: 3b 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20  ;.  }..  return 
4bb0: 72 63 3b 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 41 20  rc;.}.../*.** A 
4bc0: 68 65 6c 70 65 72 20 66 75 6e 63 74 69 6f 6e 20  helper function 
4bd0: 75 73 65 64 20 62 79 20 65 63 68 6f 55 70 64 61  used by echoUpda
4be0: 74 65 28 29 20 61 6e 64 20 65 63 68 6f 42 65 73  te() and echoBes
4bf0: 74 49 6e 64 65 78 28 29 20 66 6f 72 0a 2a 2a 20  tIndex() for.** 
4c00: 6d 61 6e 69 70 75 6c 61 74 69 6e 67 20 73 74 72  manipulating str
4c10: 69 6e 67 73 20 69 6e 20 63 6f 6e 63 65 72 74 20  ings in concert 
4c20: 77 69 74 68 20 74 68 65 20 73 71 6c 69 74 65 33  with the sqlite3
4c30: 5f 6d 70 72 69 6e 74 66 28 29 20 66 75 6e 63 74  _mprintf() funct
4c40: 69 6f 6e 2e 0a 2a 2a 0a 2a 2a 20 50 61 72 61 6d  ion..**.** Param
4c50: 65 74 65 72 20 70 7a 53 74 72 20 70 6f 69 6e 74  eter pzStr point
4c60: 73 20 74 6f 20 61 20 70 6f 69 6e 74 65 72 20 74  s to a pointer t
4c70: 6f 20 61 20 73 74 72 69 6e 67 20 61 6c 6c 6f 63  o a string alloc
4c80: 61 74 65 64 20 77 69 74 68 0a 2a 2a 20 73 71 6c  ated with.** sql
4c90: 69 74 65 33 5f 6d 70 72 69 6e 74 66 2e 20 54 68  ite3_mprintf. Th
4ca0: 65 20 73 65 63 6f 6e 64 20 70 61 72 61 6d 65 74  e second paramet
4cb0: 65 72 2c 20 7a 41 70 70 65 6e 64 2c 20 70 6f 69  er, zAppend, poi
4cc0: 6e 74 73 20 74 6f 20 61 6e 6f 74 68 65 72 0a 2a  nts to another.*
4cd0: 2a 20 73 74 72 69 6e 67 2e 20 54 68 65 20 74 77  * string. The tw
4ce0: 6f 20 73 74 72 69 6e 67 73 20 61 72 65 20 63 6f  o strings are co
4cf0: 6e 63 61 74 65 6e 61 74 65 64 20 74 6f 67 65 74  ncatenated toget
4d00: 68 65 72 20 61 6e 64 20 2a 70 7a 53 74 72 0a 2a  her and *pzStr.*
4d10: 2a 20 73 65 74 20 74 6f 20 70 6f 69 6e 74 20 61  * set to point a
4d20: 74 20 74 68 65 20 72 65 73 75 6c 74 2e 20 54 68  t the result. Th
4d30: 65 20 69 6e 69 74 69 61 6c 20 62 75 66 66 65 72  e initial buffer
4d40: 20 70 6f 69 6e 74 65 64 20 74 6f 20 62 79 20 2a   pointed to by *
4d50: 70 7a 53 74 72 0a 2a 2a 20 69 73 20 64 65 61 6c  pzStr.** is deal
4d60: 6c 6f 63 61 74 65 64 20 76 69 61 20 73 71 6c 69  located via sqli
4d70: 74 65 33 5f 66 72 65 65 28 29 2e 0a 2a 2a 0a 2a  te3_free()..**.*
4d80: 2a 20 49 66 20 74 68 65 20 74 68 69 72 64 20 61  * If the third a
4d90: 72 67 75 6d 65 6e 74 2c 20 64 6f 46 72 65 65 2c  rgument, doFree,
4da0: 20 69 73 20 74 72 75 65 2c 20 74 68 65 6e 20 73   is true, then s
4db0: 71 6c 69 74 65 33 5f 66 72 65 65 28 29 20 69 73  qlite3_free() is
4dc0: 0a 2a 2a 20 61 6c 73 6f 20 63 61 6c 6c 65 64 20  .** also called 
4dd0: 74 6f 20 66 72 65 65 20 74 68 65 20 62 75 66 66  to free the buff
4de0: 65 72 20 70 6f 69 6e 74 65 64 20 74 6f 20 62 79  er pointed to by
4df0: 20 7a 41 70 70 65 6e 64 2e 0a 2a 2f 0a 73 74 61   zAppend..*/.sta
4e00: 74 69 63 20 76 6f 69 64 20 73 74 72 69 6e 67 5f  tic void string_
4e10: 63 6f 6e 63 61 74 28 63 68 61 72 20 2a 2a 70 7a  concat(char **pz
4e20: 53 74 72 2c 20 63 68 61 72 20 2a 7a 41 70 70 65  Str, char *zAppe
4e30: 6e 64 2c 20 69 6e 74 20 64 6f 46 72 65 65 2c 20  nd, int doFree, 
4e40: 69 6e 74 20 2a 70 52 63 29 7b 0a 20 20 63 68 61  int *pRc){.  cha
4e50: 72 20 2a 7a 49 6e 20 3d 20 2a 70 7a 53 74 72 3b  r *zIn = *pzStr;
4e60: 0a 20 20 69 66 28 20 21 7a 41 70 70 65 6e 64 20  .  if( !zAppend 
4e70: 26 26 20 64 6f 46 72 65 65 20 26 26 20 2a 70 52  && doFree && *pR
4e80: 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a  c==SQLITE_OK ){.
4e90: 20 20 20 20 2a 70 52 63 20 3d 20 53 51 4c 49 54      *pRc = SQLIT
4ea0: 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 7d 0a 20 20 69  E_NOMEM;.  }.  i
4eb0: 66 28 20 2a 70 52 63 21 3d 53 51 4c 49 54 45 5f  f( *pRc!=SQLITE_
4ec0: 4f 4b 20 29 7b 0a 20 20 20 20 73 71 6c 69 74 65  OK ){.    sqlite
4ed0: 33 5f 66 72 65 65 28 7a 49 6e 29 3b 0a 20 20 20  3_free(zIn);.   
4ee0: 20 7a 49 6e 20 3d 20 30 3b 0a 20 20 7d 65 6c 73   zIn = 0;.  }els
4ef0: 65 7b 0a 20 20 20 20 69 66 28 20 7a 49 6e 20 29  e{.    if( zIn )
4f00: 7b 0a 20 20 20 20 20 20 63 68 61 72 20 2a 7a 54  {.      char *zT
4f10: 65 6d 70 20 3d 20 7a 49 6e 3b 0a 20 20 20 20 20  emp = zIn;.     
4f20: 20 7a 49 6e 20 3d 20 73 71 6c 69 74 65 33 5f 6d   zIn = sqlite3_m
4f30: 70 72 69 6e 74 66 28 22 25 73 25 73 22 2c 20 7a  printf("%s%s", z
4f40: 49 6e 2c 20 7a 41 70 70 65 6e 64 29 3b 0a 20 20  In, zAppend);.  
4f50: 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65      sqlite3_free
4f60: 28 7a 54 65 6d 70 29 3b 0a 20 20 20 20 7d 65 6c  (zTemp);.    }el
4f70: 73 65 7b 0a 20 20 20 20 20 20 7a 49 6e 20 3d 20  se{.      zIn = 
4f80: 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28  sqlite3_mprintf(
4f90: 22 25 73 22 2c 20 7a 41 70 70 65 6e 64 29 3b 0a  "%s", zAppend);.
4fa0: 20 20 20 20 7d 0a 20 20 20 20 69 66 28 20 21 7a      }.    if( !z
4fb0: 49 6e 20 29 7b 0a 20 20 20 20 20 20 2a 70 52 63  In ){.      *pRc
4fc0: 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b   = SQLITE_NOMEM;
4fd0: 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 2a 70 7a  .    }.  }.  *pz
4fe0: 53 74 72 20 3d 20 7a 49 6e 3b 0a 20 20 69 66 28  Str = zIn;.  if(
4ff0: 20 64 6f 46 72 65 65 20 29 7b 0a 20 20 20 20 73   doFree ){.    s
5000: 71 6c 69 74 65 33 5f 66 72 65 65 28 7a 41 70 70  qlite3_free(zApp
5010: 65 6e 64 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a  end);.  }.}../*.
5020: 2a 2a 20 54 68 65 20 65 63 68 6f 20 6d 6f 64 75  ** The echo modu
5030: 6c 65 20 69 6d 70 6c 65 6d 65 6e 74 73 20 74 68  le implements th
5040: 65 20 73 75 62 73 65 74 20 6f 66 20 71 75 65 72  e subset of quer
5050: 79 20 63 6f 6e 73 74 72 61 69 6e 74 73 20 61 6e  y constraints an
5060: 64 20 73 6f 72 74 0a 2a 2a 20 6f 72 64 65 72 73  d sort.** orders
5070: 20 74 68 61 74 20 6d 61 79 20 74 61 6b 65 20 61   that may take a
5080: 64 76 61 6e 74 61 67 65 20 6f 66 20 53 51 4c 69  dvantage of SQLi
5090: 74 65 20 69 6e 64 69 63 65 73 20 6f 6e 20 74 68  te indices on th
50a0: 65 20 75 6e 64 65 72 6c 79 69 6e 67 0a 2a 2a 20  e underlying.** 
50b0: 72 65 61 6c 20 74 61 62 6c 65 2e 20 46 6f 72 20  real table. For 
50c0: 65 78 61 6d 70 6c 65 2c 20 69 66 20 74 68 65 20  example, if the 
50d0: 72 65 61 6c 20 74 61 62 6c 65 20 69 73 20 64 65  real table is de
50e0: 63 6c 61 72 65 64 20 61 73 3a 0a 2a 2a 0a 2a 2a  clared as:.**.**
50f0: 20 20 20 20 20 43 52 45 41 54 45 20 54 41 42 4c       CREATE TABL
5100: 45 20 72 65 61 6c 28 61 2c 20 62 2c 20 63 29 3b  E real(a, b, c);
5110: 0a 2a 2a 20 20 20 20 20 43 52 45 41 54 45 20 49  .**     CREATE I
5120: 4e 44 45 58 20 72 65 61 6c 5f 69 6e 64 65 78 20  NDEX real_index 
5130: 4f 4e 20 72 65 61 6c 28 62 29 3b 0a 2a 2a 0a 2a  ON real(b);.**.*
5140: 2a 20 74 68 65 6e 20 74 68 65 20 65 63 68 6f 20  * then the echo 
5150: 6d 6f 64 75 6c 65 20 68 61 6e 64 6c 65 73 20 57  module handles W
5160: 48 45 52 45 20 6f 72 20 4f 52 44 45 52 20 42 59  HERE or ORDER BY
5170: 20 63 6c 61 75 73 65 73 20 74 68 61 74 20 72 65   clauses that re
5180: 66 65 72 0a 2a 2a 20 74 6f 20 74 68 65 20 63 6f  fer.** to the co
5190: 6c 75 6d 6e 20 22 62 22 2c 20 62 75 74 20 6e 6f  lumn "b", but no
51a0: 74 20 22 61 22 20 6f 72 20 22 63 22 2e 20 49 66  t "a" or "c". If
51b0: 20 61 20 6d 75 6c 74 69 2d 63 6f 6c 75 6d 6e 20   a multi-column 
51c0: 69 6e 64 65 78 20 69 73 0a 2a 2a 20 70 72 65 73  index is.** pres
51d0: 65 6e 74 2c 20 6f 6e 6c 79 20 69 74 73 20 6c 65  ent, only its le
51e0: 66 74 20 6d 6f 73 74 20 63 6f 6c 75 6d 6e 20 69  ft most column i
51f0: 73 20 63 6f 6e 73 69 64 65 72 65 64 2e 20 0a 2a  s considered. .*
5200: 2a 0a 2a 2a 20 54 68 69 73 20 78 42 65 73 74 49  *.** This xBestI
5210: 6e 64 65 78 20 6d 65 74 68 6f 64 20 65 6e 63 6f  ndex method enco
5220: 64 65 73 20 74 68 65 20 70 72 6f 70 6f 73 65 64  des the proposed
5230: 20 73 65 61 72 63 68 20 73 74 72 61 74 65 67 79   search strategy
5240: 20 61 73 0a 2a 2a 20 61 6e 20 53 51 4c 20 71 75   as.** an SQL qu
5250: 65 72 79 20 6f 6e 20 74 68 65 20 72 65 61 6c 20  ery on the real 
5260: 74 61 62 6c 65 20 75 6e 64 65 72 6c 79 69 6e 67  table underlying
5270: 20 74 68 65 20 76 69 72 74 75 61 6c 20 65 63 68   the virtual ech
5280: 6f 20 6d 6f 64 75 6c 65 20 0a 2a 2a 20 74 61 62  o module .** tab
5290: 6c 65 20 61 6e 64 20 73 74 6f 72 65 73 20 74 68  le and stores th
52a0: 65 20 71 75 65 72 79 20 69 6e 20 73 71 6c 69 74  e query in sqlit
52b0: 65 33 5f 69 6e 64 65 78 5f 69 6e 66 6f 2e 69 64  e3_index_info.id
52c0: 78 53 74 72 2e 20 54 68 65 20 53 51 4c 0a 2a 2a  xStr. The SQL.**
52d0: 20 73 74 61 74 65 6d 65 6e 74 20 69 73 20 6f 66   statement is of
52e0: 20 74 68 65 20 66 6f 72 6d 3a 0a 2a 2a 0a 2a 2a   the form:.**.**
52f0: 20 20 20 53 45 4c 45 43 54 20 72 6f 77 69 64 2c     SELECT rowid,
5300: 20 2a 20 46 52 4f 4d 20 3c 72 65 61 6c 2d 74 61   * FROM <real-ta
5310: 62 6c 65 3e 20 3f 3c 77 68 65 72 65 2d 63 6c 61  ble> ?<where-cla
5320: 75 73 65 3e 3f 20 3f 3c 6f 72 64 65 72 2d 62 79  use>? ?<order-by
5330: 2d 63 6c 61 75 73 65 3e 3f 0a 2a 2a 0a 2a 2a 20  -clause>?.**.** 
5340: 77 68 65 72 65 20 74 68 65 20 3c 77 68 65 72 65  where the <where
5350: 2d 63 6c 61 75 73 65 3e 20 61 6e 64 20 3c 6f 72  -clause> and <or
5360: 64 65 72 2d 62 79 2d 63 6c 61 75 73 65 3e 20 61  der-by-clause> a
5370: 72 65 20 64 65 74 65 72 6d 69 6e 65 64 0a 2a 2a  re determined.**
5380: 20 62 79 20 74 68 65 20 63 6f 6e 74 65 6e 74 73   by the contents
5390: 20 6f 66 20 74 68 65 20 73 74 72 75 63 74 75 72   of the structur
53a0: 65 20 70 6f 69 6e 74 65 64 20 74 6f 20 62 79 20  e pointed to by 
53b0: 74 68 65 20 70 49 64 78 49 6e 66 6f 20 61 72 67  the pIdxInfo arg
53c0: 75 6d 65 6e 74 2e 0a 2a 2f 0a 73 74 61 74 69 63  ument..*/.static
53d0: 20 69 6e 74 20 65 63 68 6f 42 65 73 74 49 6e 64   int echoBestInd
53e0: 65 78 28 73 71 6c 69 74 65 33 5f 76 74 61 62 20  ex(sqlite3_vtab 
53f0: 2a 74 61 62 2c 20 73 71 6c 69 74 65 33 5f 69 6e  *tab, sqlite3_in
5400: 64 65 78 5f 69 6e 66 6f 20 2a 70 49 64 78 49 6e  dex_info *pIdxIn
5410: 66 6f 29 7b 0a 20 20 69 6e 74 20 69 69 3b 0a 20  fo){.  int ii;. 
5420: 20 63 68 61 72 20 2a 7a 51 75 65 72 79 20 3d 20   char *zQuery = 
5430: 30 3b 0a 20 20 63 68 61 72 20 2a 7a 4e 65 77 3b  0;.  char *zNew;
5440: 0a 20 20 69 6e 74 20 6e 41 72 67 20 3d 20 30 3b  .  int nArg = 0;
5450: 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a  .  const char *z
5460: 53 65 70 20 3d 20 22 57 48 45 52 45 22 3b 0a 20  Sep = "WHERE";. 
5470: 20 65 63 68 6f 5f 76 74 61 62 20 2a 70 56 74 61   echo_vtab *pVta
5480: 62 20 3d 20 28 65 63 68 6f 5f 76 74 61 62 20 2a  b = (echo_vtab *
5490: 29 74 61 62 3b 0a 20 20 73 71 6c 69 74 65 33 5f  )tab;.  sqlite3_
54a0: 73 74 6d 74 20 2a 70 53 74 6d 74 20 3d 20 30 3b  stmt *pStmt = 0;
54b0: 0a 20 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69  .  Tcl_Interp *i
54c0: 6e 74 65 72 70 20 3d 20 70 56 74 61 62 2d 3e 69  nterp = pVtab->i
54d0: 6e 74 65 72 70 3b 0a 0a 20 20 69 6e 74 20 6e 52  nterp;..  int nR
54e0: 6f 77 3b 0a 20 20 69 6e 74 20 75 73 65 49 64 78  ow;.  int useIdx
54f0: 20 3d 20 30 3b 0a 20 20 69 6e 74 20 72 63 20 3d   = 0;.  int rc =
5500: 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 69 6e   SQLITE_OK;.  in
5510: 74 20 75 73 65 43 6f 73 74 20 3d 20 30 3b 0a 20  t useCost = 0;. 
5520: 20 64 6f 75 62 6c 65 20 63 6f 73 74 3b 0a 20 20   double cost;.  
5530: 69 6e 74 20 69 73 49 67 6e 6f 72 65 55 73 61 62  int isIgnoreUsab
5540: 6c 65 20 3d 20 30 3b 0a 20 20 69 66 28 20 54 63  le = 0;.  if( Tc
5550: 6c 5f 47 65 74 56 61 72 28 69 6e 74 65 72 70 2c  l_GetVar(interp,
5560: 20 22 65 63 68 6f 5f 6d 6f 64 75 6c 65 5f 69 67   "echo_module_ig
5570: 6e 6f 72 65 5f 75 73 61 62 6c 65 22 2c 20 54 43  nore_usable", TC
5580: 4c 5f 47 4c 4f 42 41 4c 5f 4f 4e 4c 59 29 20 29  L_GLOBAL_ONLY) )
5590: 7b 0a 20 20 20 20 69 73 49 67 6e 6f 72 65 55 73  {.    isIgnoreUs
55a0: 61 62 6c 65 20 3d 20 31 3b 0a 20 20 7d 0a 0a 20  able = 1;.  }.. 
55b0: 20 69 66 28 20 73 69 6d 75 6c 61 74 65 56 74 61   if( simulateVta
55c0: 62 45 72 72 6f 72 28 70 56 74 61 62 2c 20 22 78  bError(pVtab, "x
55d0: 42 65 73 74 49 6e 64 65 78 22 29 20 29 7b 0a 20  BestIndex") ){. 
55e0: 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45     return SQLITE
55f0: 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a 0a 20 20 2f  _ERROR;.  }..  /
5600: 2a 20 44 65 74 65 72 6d 69 6e 65 20 74 68 65 20  * Determine the 
5610: 6e 75 6d 62 65 72 20 6f 66 20 72 6f 77 73 20 69  number of rows i
5620: 6e 20 74 68 65 20 74 61 62 6c 65 20 61 6e 64 20  n the table and 
5630: 73 74 6f 72 65 20 74 68 69 73 20 76 61 6c 75 65  store this value
5640: 20 69 6e 20 6c 6f 63 61 6c 0a 20 20 2a 2a 20 76   in local.  ** v
5650: 61 72 69 61 62 6c 65 20 6e 52 6f 77 2e 20 54 68  ariable nRow. Th
5660: 65 20 27 65 73 74 69 6d 61 74 65 64 2d 63 6f 73  e 'estimated-cos
5670: 74 27 20 6f 66 20 74 68 65 20 73 63 61 6e 20 77  t' of the scan w
5680: 69 6c 6c 20 62 65 20 74 68 65 20 6e 75 6d 62 65  ill be the numbe
5690: 72 20 6f 66 0a 20 20 2a 2a 20 72 6f 77 73 20 69  r of.  ** rows i
56a0: 6e 20 74 68 65 20 74 61 62 6c 65 20 66 6f 72 20  n the table for 
56b0: 61 20 6c 69 6e 65 61 72 20 73 63 61 6e 2c 20 6f  a linear scan, o
56c0: 72 20 74 68 65 20 6c 6f 67 20 28 62 61 73 65 20  r the log (base 
56d0: 32 29 20 6f 66 20 74 68 65 20 0a 20 20 2a 2a 20  2) of the .  ** 
56e0: 6e 75 6d 62 65 72 20 6f 66 20 72 6f 77 73 20 69  number of rows i
56f0: 66 20 74 68 65 20 70 72 6f 70 6f 73 65 64 20 73  f the proposed s
5700: 63 61 6e 20 75 73 65 73 20 61 6e 20 69 6e 64 65  can uses an inde
5710: 78 2e 20 20 0a 20 20 2a 2f 0a 20 20 69 66 28 20  x.  .  */.  if( 
5720: 54 63 6c 5f 47 65 74 56 61 72 28 69 6e 74 65 72  Tcl_GetVar(inter
5730: 70 2c 20 22 65 63 68 6f 5f 6d 6f 64 75 6c 65 5f  p, "echo_module_
5740: 63 6f 73 74 22 2c 20 54 43 4c 5f 47 4c 4f 42 41  cost", TCL_GLOBA
5750: 4c 5f 4f 4e 4c 59 29 20 29 7b 0a 20 20 20 20 63  L_ONLY) ){.    c
5760: 6f 73 74 20 3d 20 61 74 6f 66 28 54 63 6c 5f 47  ost = atof(Tcl_G
5770: 65 74 56 61 72 28 69 6e 74 65 72 70 2c 20 22 65  etVar(interp, "e
5780: 63 68 6f 5f 6d 6f 64 75 6c 65 5f 63 6f 73 74 22  cho_module_cost"
5790: 2c 20 54 43 4c 5f 47 4c 4f 42 41 4c 5f 4f 4e 4c  , TCL_GLOBAL_ONL
57a0: 59 29 29 3b 0a 20 20 20 20 75 73 65 43 6f 73 74  Y));.    useCost
57b0: 20 3d 20 31 3b 0a 20 20 7d 20 65 6c 73 65 20 7b   = 1;.  } else {
57c0: 0a 20 20 20 20 7a 51 75 65 72 79 20 3d 20 73 71  .    zQuery = sq
57d0: 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 22 53  lite3_mprintf("S
57e0: 45 4c 45 43 54 20 63 6f 75 6e 74 28 2a 29 20 46  ELECT count(*) F
57f0: 52 4f 4d 20 25 51 22 2c 20 70 56 74 61 62 2d 3e  ROM %Q", pVtab->
5800: 7a 54 61 62 6c 65 4e 61 6d 65 29 3b 0a 20 20 20  zTableName);.   
5810: 20 69 66 28 20 21 7a 51 75 65 72 79 20 29 7b 0a   if( !zQuery ){.
5820: 20 20 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c        return SQL
5830: 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 7d  ITE_NOMEM;.    }
5840: 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65  .    rc = sqlite
5850: 33 5f 70 72 65 70 61 72 65 28 70 56 74 61 62 2d  3_prepare(pVtab-
5860: 3e 64 62 2c 20 7a 51 75 65 72 79 2c 20 2d 31 2c  >db, zQuery, -1,
5870: 20 26 70 53 74 6d 74 2c 20 30 29 3b 0a 20 20 20   &pStmt, 0);.   
5880: 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 7a 51   sqlite3_free(zQ
5890: 75 65 72 79 29 3b 0a 20 20 20 20 69 66 28 20 72  uery);.    if( r
58a0: 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a  c!=SQLITE_OK ){.
58b0: 20 20 20 20 20 20 72 65 74 75 72 6e 20 72 63 3b        return rc;
58c0: 0a 20 20 20 20 7d 0a 20 20 20 20 73 71 6c 69 74  .    }.    sqlit
58d0: 65 33 5f 73 74 65 70 28 70 53 74 6d 74 29 3b 0a  e3_step(pStmt);.
58e0: 20 20 20 20 6e 52 6f 77 20 3d 20 73 71 6c 69 74      nRow = sqlit
58f0: 65 33 5f 63 6f 6c 75 6d 6e 5f 69 6e 74 28 70 53  e3_column_int(pS
5900: 74 6d 74 2c 20 30 29 3b 0a 20 20 20 20 72 63 20  tmt, 0);.    rc 
5910: 3d 20 73 71 6c 69 74 65 33 5f 66 69 6e 61 6c 69  = sqlite3_finali
5920: 7a 65 28 70 53 74 6d 74 29 3b 0a 20 20 20 20 69  ze(pStmt);.    i
5930: 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc!=SQLITE_OK
5940: 20 29 7b 0a 20 20 20 20 20 20 72 65 74 75 72 6e   ){.      return
5950: 20 72 63 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a   rc;.    }.  }..
5960: 20 20 7a 51 75 65 72 79 20 3d 20 73 71 6c 69 74    zQuery = sqlit
5970: 65 33 5f 6d 70 72 69 6e 74 66 28 22 53 45 4c 45  e3_mprintf("SELE
5980: 43 54 20 72 6f 77 69 64 2c 20 2a 20 46 52 4f 4d  CT rowid, * FROM
5990: 20 25 51 22 2c 20 70 56 74 61 62 2d 3e 7a 54 61   %Q", pVtab->zTa
59a0: 62 6c 65 4e 61 6d 65 29 3b 0a 20 20 69 66 28 20  bleName);.  if( 
59b0: 21 7a 51 75 65 72 79 20 29 7b 0a 20 20 20 20 72  !zQuery ){.    r
59c0: 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d  eturn SQLITE_NOM
59d0: 45 4d 3b 0a 20 20 7d 0a 20 20 66 6f 72 28 69 69  EM;.  }.  for(ii
59e0: 3d 30 3b 20 69 69 3c 70 49 64 78 49 6e 66 6f 2d  =0; ii<pIdxInfo-
59f0: 3e 6e 43 6f 6e 73 74 72 61 69 6e 74 3b 20 69 69  >nConstraint; ii
5a00: 2b 2b 29 7b 0a 20 20 20 20 63 6f 6e 73 74 20 73  ++){.    const s
5a10: 74 72 75 63 74 20 73 71 6c 69 74 65 33 5f 69 6e  truct sqlite3_in
5a20: 64 65 78 5f 63 6f 6e 73 74 72 61 69 6e 74 20 2a  dex_constraint *
5a30: 70 43 6f 6e 73 74 72 61 69 6e 74 3b 0a 20 20 20  pConstraint;.   
5a40: 20 73 74 72 75 63 74 20 73 71 6c 69 74 65 33 5f   struct sqlite3_
5a50: 69 6e 64 65 78 5f 63 6f 6e 73 74 72 61 69 6e 74  index_constraint
5a60: 5f 75 73 61 67 65 20 2a 70 55 73 61 67 65 3b 0a  _usage *pUsage;.
5a70: 20 20 20 20 69 6e 74 20 69 43 6f 6c 3b 0a 0a 20      int iCol;.. 
5a80: 20 20 20 70 43 6f 6e 73 74 72 61 69 6e 74 20 3d     pConstraint =
5a90: 20 26 70 49 64 78 49 6e 66 6f 2d 3e 61 43 6f 6e   &pIdxInfo->aCon
5aa0: 73 74 72 61 69 6e 74 5b 69 69 5d 3b 0a 20 20 20  straint[ii];.   
5ab0: 20 70 55 73 61 67 65 20 3d 20 26 70 49 64 78 49   pUsage = &pIdxI
5ac0: 6e 66 6f 2d 3e 61 43 6f 6e 73 74 72 61 69 6e 74  nfo->aConstraint
5ad0: 55 73 61 67 65 5b 69 69 5d 3b 0a 0a 20 20 20 20  Usage[ii];..    
5ae0: 69 66 28 20 21 69 73 49 67 6e 6f 72 65 55 73 61  if( !isIgnoreUsa
5af0: 62 6c 65 20 26 26 20 21 70 43 6f 6e 73 74 72 61  ble && !pConstra
5b00: 69 6e 74 2d 3e 75 73 61 62 6c 65 20 29 20 63 6f  int->usable ) co
5b10: 6e 74 69 6e 75 65 3b 0a 0a 20 20 20 20 69 43 6f  ntinue;..    iCo
5b20: 6c 20 3d 20 70 43 6f 6e 73 74 72 61 69 6e 74 2d  l = pConstraint-
5b30: 3e 69 43 6f 6c 75 6d 6e 3b 0a 20 20 20 20 69 66  >iColumn;.    if
5b40: 28 20 69 43 6f 6c 3c 30 20 7c 7c 20 70 56 74 61  ( iCol<0 || pVta
5b50: 62 2d 3e 61 49 6e 64 65 78 5b 69 43 6f 6c 5d 20  b->aIndex[iCol] 
5b60: 29 7b 0a 20 20 20 20 20 20 63 68 61 72 20 2a 7a  ){.      char *z
5b70: 43 6f 6c 20 3d 20 69 43 6f 6c 3e 3d 30 20 3f 20  Col = iCol>=0 ? 
5b80: 70 56 74 61 62 2d 3e 61 43 6f 6c 5b 69 43 6f 6c  pVtab->aCol[iCol
5b90: 5d 20 3a 20 22 72 6f 77 69 64 22 3b 0a 20 20 20  ] : "rowid";.   
5ba0: 20 20 20 63 68 61 72 20 2a 7a 4f 70 20 3d 20 30     char *zOp = 0
5bb0: 3b 0a 20 20 20 20 20 20 75 73 65 49 64 78 20 3d  ;.      useIdx =
5bc0: 20 31 3b 0a 20 20 20 20 20 20 73 77 69 74 63 68   1;.      switch
5bd0: 28 20 70 43 6f 6e 73 74 72 61 69 6e 74 2d 3e 6f  ( pConstraint->o
5be0: 70 20 29 7b 0a 20 20 20 20 20 20 20 20 63 61 73  p ){.        cas
5bf0: 65 20 53 51 4c 49 54 45 5f 49 4e 44 45 58 5f 43  e SQLITE_INDEX_C
5c00: 4f 4e 53 54 52 41 49 4e 54 5f 45 51 3a 0a 20 20  ONSTRAINT_EQ:.  
5c10: 20 20 20 20 20 20 20 20 7a 4f 70 20 3d 20 22 3d          zOp = "=
5c20: 22 3b 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20  "; break;.      
5c30: 20 20 63 61 73 65 20 53 51 4c 49 54 45 5f 49 4e    case SQLITE_IN
5c40: 44 45 58 5f 43 4f 4e 53 54 52 41 49 4e 54 5f 4c  DEX_CONSTRAINT_L
5c50: 54 3a 0a 20 20 20 20 20 20 20 20 20 20 7a 4f 70  T:.          zOp
5c60: 20 3d 20 22 3c 22 3b 20 62 72 65 61 6b 3b 0a 20   = "<"; break;. 
5c70: 20 20 20 20 20 20 20 63 61 73 65 20 53 51 4c 49         case SQLI
5c80: 54 45 5f 49 4e 44 45 58 5f 43 4f 4e 53 54 52 41  TE_INDEX_CONSTRA
5c90: 49 4e 54 5f 47 54 3a 0a 20 20 20 20 20 20 20 20  INT_GT:.        
5ca0: 20 20 7a 4f 70 20 3d 20 22 3e 22 3b 20 62 72 65    zOp = ">"; bre
5cb0: 61 6b 3b 0a 20 20 20 20 20 20 20 20 63 61 73 65  ak;.        case
5cc0: 20 53 51 4c 49 54 45 5f 49 4e 44 45 58 5f 43 4f   SQLITE_INDEX_CO
5cd0: 4e 53 54 52 41 49 4e 54 5f 4c 45 3a 0a 20 20 20  NSTRAINT_LE:.   
5ce0: 20 20 20 20 20 20 20 7a 4f 70 20 3d 20 22 3c 3d         zOp = "<=
5cf0: 22 3b 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20  "; break;.      
5d00: 20 20 63 61 73 65 20 53 51 4c 49 54 45 5f 49 4e    case SQLITE_IN
5d10: 44 45 58 5f 43 4f 4e 53 54 52 41 49 4e 54 5f 47  DEX_CONSTRAINT_G
5d20: 45 3a 0a 20 20 20 20 20 20 20 20 20 20 7a 4f 70  E:.          zOp
5d30: 20 3d 20 22 3e 3d 22 3b 20 62 72 65 61 6b 3b 0a   = ">="; break;.
5d40: 20 20 20 20 20 20 20 20 63 61 73 65 20 53 51 4c          case SQL
5d50: 49 54 45 5f 49 4e 44 45 58 5f 43 4f 4e 53 54 52  ITE_INDEX_CONSTR
5d60: 41 49 4e 54 5f 4d 41 54 43 48 3a 0a 20 20 20 20  AINT_MATCH:.    
5d70: 20 20 20 20 20 20 7a 4f 70 20 3d 20 22 4c 49 4b        zOp = "LIK
5d80: 45 22 3b 20 62 72 65 61 6b 3b 0a 20 20 20 20 20  E"; break;.     
5d90: 20 7d 0a 20 20 20 20 20 20 69 66 28 20 7a 4f 70   }.      if( zOp
5da0: 5b 30 5d 3d 3d 27 4c 27 20 29 7b 0a 20 20 20 20  [0]=='L' ){.    
5db0: 20 20 20 20 7a 4e 65 77 20 3d 20 73 71 6c 69 74      zNew = sqlit
5dc0: 65 33 5f 6d 70 72 69 6e 74 66 28 22 20 25 73 20  e3_mprintf(" %s 
5dd0: 25 73 20 4c 49 4b 45 20 28 53 45 4c 45 43 54 20  %s LIKE (SELECT 
5de0: 27 25 25 27 7c 7c 3f 7c 7c 27 25 25 27 29 22 2c  '%%'||?||'%%')",
5df0: 20 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20   .              
5e00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5e10: 20 7a 53 65 70 2c 20 7a 43 6f 6c 29 3b 0a 20 20   zSep, zCol);.  
5e20: 20 20 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20      } else {.   
5e30: 20 20 20 20 20 7a 4e 65 77 20 3d 20 73 71 6c 69       zNew = sqli
5e40: 74 65 33 5f 6d 70 72 69 6e 74 66 28 22 20 25 73  te3_mprintf(" %s
5e50: 20 25 73 20 25 73 20 3f 22 2c 20 7a 53 65 70 2c   %s %s ?", zSep,
5e60: 20 7a 43 6f 6c 2c 20 7a 4f 70 29 3b 0a 20 20 20   zCol, zOp);.   
5e70: 20 20 20 7d 0a 20 20 20 20 20 20 73 74 72 69 6e     }.      strin
5e80: 67 5f 63 6f 6e 63 61 74 28 26 7a 51 75 65 72 79  g_concat(&zQuery
5e90: 2c 20 7a 4e 65 77 2c 20 31 2c 20 26 72 63 29 3b  , zNew, 1, &rc);
5ea0: 0a 0a 20 20 20 20 20 20 7a 53 65 70 20 3d 20 22  ..      zSep = "
5eb0: 41 4e 44 22 3b 0a 20 20 20 20 20 20 70 55 73 61  AND";.      pUsa
5ec0: 67 65 2d 3e 61 72 67 76 49 6e 64 65 78 20 3d 20  ge->argvIndex = 
5ed0: 2b 2b 6e 41 72 67 3b 0a 20 20 20 20 20 20 70 55  ++nArg;.      pU
5ee0: 73 61 67 65 2d 3e 6f 6d 69 74 20 3d 20 31 3b 0a  sage->omit = 1;.
5ef0: 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 2f 2a 20      }.  }..  /* 
5f00: 49 66 20 74 68 65 72 65 20 69 73 20 6f 6e 6c 79  If there is only
5f10: 20 6f 6e 65 20 74 65 72 6d 20 69 6e 20 74 68 65   one term in the
5f20: 20 4f 52 44 45 52 20 42 59 20 63 6c 61 75 73 65   ORDER BY clause
5f30: 2c 20 61 6e 64 20 69 74 20 69 73 0a 20 20 2a 2a  , and it is.  **
5f40: 20 6f 6e 20 61 20 63 6f 6c 75 6d 6e 20 74 68 61   on a column tha
5f50: 74 20 74 68 69 73 20 76 69 72 74 75 61 6c 20 74  t this virtual t
5f60: 61 62 6c 65 20 68 61 73 20 61 6e 20 69 6e 64 65  able has an inde
5f70: 78 20 66 6f 72 2c 20 74 68 65 6e 20 63 6f 6e 73  x for, then cons
5f80: 75 6d 65 20 0a 20 20 2a 2a 20 74 68 65 20 4f 52  ume .  ** the OR
5f90: 44 45 52 20 42 59 20 63 6c 61 75 73 65 2e 0a 20  DER BY clause.. 
5fa0: 20 2a 2f 0a 20 20 69 66 28 20 70 49 64 78 49 6e   */.  if( pIdxIn
5fb0: 66 6f 2d 3e 6e 4f 72 64 65 72 42 79 3d 3d 31 20  fo->nOrderBy==1 
5fc0: 26 26 20 28 0a 20 20 20 20 20 20 20 20 70 49 64  && (.        pId
5fd0: 78 49 6e 66 6f 2d 3e 61 4f 72 64 65 72 42 79 2d  xInfo->aOrderBy-
5fe0: 3e 69 43 6f 6c 75 6d 6e 3c 30 20 7c 7c 0a 20 20  >iColumn<0 ||.  
5ff0: 20 20 20 20 20 20 70 56 74 61 62 2d 3e 61 49 6e        pVtab->aIn
6000: 64 65 78 5b 70 49 64 78 49 6e 66 6f 2d 3e 61 4f  dex[pIdxInfo->aO
6010: 72 64 65 72 42 79 2d 3e 69 43 6f 6c 75 6d 6e 5d  rderBy->iColumn]
6020: 29 20 29 7b 0a 20 20 20 20 69 6e 74 20 69 43 6f  ) ){.    int iCo
6030: 6c 20 3d 20 70 49 64 78 49 6e 66 6f 2d 3e 61 4f  l = pIdxInfo->aO
6040: 72 64 65 72 42 79 2d 3e 69 43 6f 6c 75 6d 6e 3b  rderBy->iColumn;
6050: 0a 20 20 20 20 63 68 61 72 20 2a 7a 43 6f 6c 20  .    char *zCol 
6060: 3d 20 69 43 6f 6c 3e 3d 30 20 3f 20 70 56 74 61  = iCol>=0 ? pVta
6070: 62 2d 3e 61 43 6f 6c 5b 69 43 6f 6c 5d 20 3a 20  b->aCol[iCol] : 
6080: 22 72 6f 77 69 64 22 3b 0a 20 20 20 20 63 68 61  "rowid";.    cha
6090: 72 20 2a 7a 44 69 72 20 3d 20 70 49 64 78 49 6e  r *zDir = pIdxIn
60a0: 66 6f 2d 3e 61 4f 72 64 65 72 42 79 2d 3e 64 65  fo->aOrderBy->de
60b0: 73 63 3f 22 44 45 53 43 22 3a 22 41 53 43 22 3b  sc?"DESC":"ASC";
60c0: 0a 20 20 20 20 7a 4e 65 77 20 3d 20 73 71 6c 69  .    zNew = sqli
60d0: 74 65 33 5f 6d 70 72 69 6e 74 66 28 22 20 4f 52  te3_mprintf(" OR
60e0: 44 45 52 20 42 59 20 25 73 20 25 73 22 2c 20 7a  DER BY %s %s", z
60f0: 43 6f 6c 2c 20 7a 44 69 72 29 3b 0a 20 20 20 20  Col, zDir);.    
6100: 73 74 72 69 6e 67 5f 63 6f 6e 63 61 74 28 26 7a  string_concat(&z
6110: 51 75 65 72 79 2c 20 7a 4e 65 77 2c 20 31 2c 20  Query, zNew, 1, 
6120: 26 72 63 29 3b 0a 20 20 20 20 70 49 64 78 49 6e  &rc);.    pIdxIn
6130: 66 6f 2d 3e 6f 72 64 65 72 42 79 43 6f 6e 73 75  fo->orderByConsu
6140: 6d 65 64 20 3d 20 31 3b 0a 20 20 7d 0a 0a 20 20  med = 1;.  }..  
6150: 61 70 70 65 6e 64 54 6f 45 63 68 6f 4d 6f 64 75  appendToEchoModu
6160: 6c 65 28 70 56 74 61 62 2d 3e 69 6e 74 65 72 70  le(pVtab->interp
6170: 2c 20 22 78 42 65 73 74 49 6e 64 65 78 22 29 3b  , "xBestIndex");
6180: 3b 0a 20 20 61 70 70 65 6e 64 54 6f 45 63 68 6f  ;.  appendToEcho
6190: 4d 6f 64 75 6c 65 28 70 56 74 61 62 2d 3e 69 6e  Module(pVtab->in
61a0: 74 65 72 70 2c 20 7a 51 75 65 72 79 29 3b 0a 0a  terp, zQuery);..
61b0: 20 20 69 66 28 20 21 7a 51 75 65 72 79 20 29 7b    if( !zQuery ){
61c0: 0a 20 20 20 20 72 65 74 75 72 6e 20 72 63 3b 0a  .    return rc;.
61d0: 20 20 7d 0a 20 20 70 49 64 78 49 6e 66 6f 2d 3e    }.  pIdxInfo->
61e0: 69 64 78 4e 75 6d 20 3d 20 68 61 73 68 53 74 72  idxNum = hashStr
61f0: 69 6e 67 28 7a 51 75 65 72 79 29 3b 0a 20 20 70  ing(zQuery);.  p
6200: 49 64 78 49 6e 66 6f 2d 3e 69 64 78 53 74 72 20  IdxInfo->idxStr 
6210: 3d 20 7a 51 75 65 72 79 3b 0a 20 20 70 49 64 78  = zQuery;.  pIdx
6220: 49 6e 66 6f 2d 3e 6e 65 65 64 54 6f 46 72 65 65  Info->needToFree
6230: 49 64 78 53 74 72 20 3d 20 31 3b 0a 20 20 69 66  IdxStr = 1;.  if
6240: 28 20 75 73 65 43 6f 73 74 20 29 7b 0a 20 20 20  ( useCost ){.   
6250: 20 70 49 64 78 49 6e 66 6f 2d 3e 65 73 74 69 6d   pIdxInfo->estim
6260: 61 74 65 64 43 6f 73 74 20 3d 20 63 6f 73 74 3b  atedCost = cost;
6270: 0a 20 20 7d 65 6c 73 65 20 69 66 28 20 75 73 65  .  }else if( use
6280: 49 64 78 20 29 7b 0a 20 20 20 20 2f 2a 20 41 70  Idx ){.    /* Ap
6290: 70 72 6f 78 69 6d 61 74 69 6f 6e 20 6f 66 20 6c  proximation of l
62a0: 6f 67 32 28 6e 52 6f 77 29 2e 20 2a 2f 0a 20 20  og2(nRow). */.  
62b0: 20 20 66 6f 72 28 20 69 69 3d 30 3b 20 69 69 3c    for( ii=0; ii<
62c0: 28 73 69 7a 65 6f 66 28 69 6e 74 29 2a 38 29 2d  (sizeof(int)*8)-
62d0: 31 3b 20 69 69 2b 2b 20 29 7b 0a 20 20 20 20 20  1; ii++ ){.     
62e0: 20 69 66 28 20 6e 52 6f 77 20 26 20 28 31 3c 3c   if( nRow & (1<<
62f0: 69 69 29 20 29 7b 0a 20 20 20 20 20 20 20 20 70  ii) ){.        p
6300: 49 64 78 49 6e 66 6f 2d 3e 65 73 74 69 6d 61 74  IdxInfo->estimat
6310: 65 64 43 6f 73 74 20 3d 20 28 64 6f 75 62 6c 65  edCost = (double
6320: 29 69 69 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20  )ii;.      }.   
6330: 20 7d 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20   }.  }else{.    
6340: 70 49 64 78 49 6e 66 6f 2d 3e 65 73 74 69 6d 61  pIdxInfo->estima
6350: 74 65 64 43 6f 73 74 20 3d 20 28 64 6f 75 62 6c  tedCost = (doubl
6360: 65 29 6e 52 6f 77 3b 0a 20 20 7d 0a 20 20 72 65  e)nRow;.  }.  re
6370: 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a  turn rc;.}../*.*
6380: 2a 20 54 68 65 20 78 55 70 64 61 74 65 20 6d 65  * The xUpdate me
6390: 74 68 6f 64 20 66 6f 72 20 65 63 68 6f 20 6d 6f  thod for echo mo
63a0: 64 75 6c 65 20 76 69 72 74 75 61 6c 20 74 61 62  dule virtual tab
63b0: 6c 65 73 2e 0a 2a 2a 20 0a 2a 2a 20 20 20 20 61  les..** .**    a
63c0: 70 44 61 74 61 5b 30 5d 20 20 61 70 44 61 74 61  pData[0]  apData
63d0: 5b 31 5d 20 20 61 70 44 61 74 61 5b 32 2e 2e 5d  [1]  apData[2..]
63e0: 0a 2a 2a 0a 2a 2a 20 20 20 20 49 4e 54 45 47 45  .**.**    INTEGE
63f0: 52 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  R               
6400: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 44                 D
6410: 45 4c 45 54 45 20 20 20 20 20 20 20 20 20 20 20  ELETE           
6420: 20 0a 2a 2a 0a 2a 2a 20 20 20 20 49 4e 54 45 47   .**.**    INTEG
6430: 45 52 20 20 20 20 4e 55 4c 4c 20 20 20 20 20 20  ER    NULL      
6440: 20 28 6e 43 6f 6c 20 61 72 67 73 29 20 20 20 20   (nCol args)    
6450: 55 50 44 41 54 45 20 28 64 6f 20 6e 6f 74 20 73  UPDATE (do not s
6460: 65 74 20 72 6f 77 69 64 29 0a 2a 2a 20 20 20 20  et rowid).**    
6470: 49 4e 54 45 47 45 52 20 20 20 20 49 4e 54 45 47  INTEGER    INTEG
6480: 45 52 20 20 20 20 28 6e 43 6f 6c 20 61 72 67 73  ER    (nCol args
6490: 29 20 20 20 20 55 50 44 41 54 45 20 28 77 69 74  )    UPDATE (wit
64a0: 68 20 53 45 54 20 72 6f 77 69 64 20 3d 20 3c 61  h SET rowid = <a
64b0: 72 67 31 3e 29 0a 2a 2a 0a 2a 2a 20 20 20 20 4e  rg1>).**.**    N
64c0: 55 4c 4c 20 20 20 20 20 20 20 4e 55 4c 4c 20 20  ULL       NULL  
64d0: 20 20 20 20 20 28 6e 43 6f 6c 20 61 72 67 73 29       (nCol args)
64e0: 20 20 20 20 49 4e 53 45 52 54 20 49 4e 54 4f 20      INSERT INTO 
64f0: 28 61 75 74 6f 6d 61 74 69 63 20 72 6f 77 69 64  (automatic rowid
6500: 20 76 61 6c 75 65 29 0a 2a 2a 20 20 20 20 4e 55   value).**    NU
6510: 4c 4c 20 20 20 20 20 20 20 49 4e 54 45 47 45 52  LL       INTEGER
6520: 20 20 20 20 28 6e 43 6f 6c 20 61 72 67 73 29 20      (nCol args) 
6530: 20 20 20 49 4e 53 45 52 54 20 28 69 6e 63 6c 2e     INSERT (incl.
6540: 20 72 6f 77 69 64 20 76 61 6c 75 65 29 0a 2a 2a   rowid value).**
6550: 0a 2a 2f 0a 69 6e 74 20 65 63 68 6f 55 70 64 61  .*/.int echoUpda
6560: 74 65 28 0a 20 20 73 71 6c 69 74 65 33 5f 76 74  te(.  sqlite3_vt
6570: 61 62 20 2a 74 61 62 2c 20 0a 20 20 69 6e 74 20  ab *tab, .  int 
6580: 6e 44 61 74 61 2c 20 0a 20 20 73 71 6c 69 74 65  nData, .  sqlite
6590: 33 5f 76 61 6c 75 65 20 2a 2a 61 70 44 61 74 61  3_value **apData
65a0: 2c 20 0a 20 20 73 71 6c 69 74 65 5f 69 6e 74 36  , .  sqlite_int6
65b0: 34 20 2a 70 52 6f 77 69 64 0a 29 7b 0a 20 20 65  4 *pRowid.){.  e
65c0: 63 68 6f 5f 76 74 61 62 20 2a 70 56 74 61 62 20  cho_vtab *pVtab 
65d0: 3d 20 28 65 63 68 6f 5f 76 74 61 62 20 2a 29 74  = (echo_vtab *)t
65e0: 61 62 3b 0a 20 20 73 71 6c 69 74 65 33 20 2a 64  ab;.  sqlite3 *d
65f0: 62 20 3d 20 70 56 74 61 62 2d 3e 64 62 3b 0a 20  b = pVtab->db;. 
6600: 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45   int rc = SQLITE
6610: 5f 4f 4b 3b 0a 0a 20 20 73 71 6c 69 74 65 33 5f  _OK;..  sqlite3_
6620: 73 74 6d 74 20 2a 70 53 74 6d 74 3b 0a 20 20 63  stmt *pStmt;.  c
6630: 68 61 72 20 2a 7a 20 3d 20 30 3b 20 20 20 20 20  har *z = 0;     
6640: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 51 4c            /* SQL
6650: 20 73 74 61 74 65 6d 65 6e 74 20 74 6f 20 65 78   statement to ex
6660: 65 63 75 74 65 20 2a 2f 0a 20 20 69 6e 74 20 62  ecute */.  int b
6670: 69 6e 64 41 72 67 5a 65 72 6f 20 3d 20 30 3b 20  indArgZero = 0; 
6680: 20 20 20 20 20 20 2f 2a 20 54 72 75 65 20 74 6f        /* True to
6690: 20 62 69 6e 64 20 61 70 44 61 74 61 5b 30 5d 20   bind apData[0] 
66a0: 74 6f 20 73 71 6c 20 76 61 72 20 6e 6f 2e 20 6e  to sql var no. n
66b0: 44 61 74 61 20 2a 2f 0a 20 20 69 6e 74 20 62 69  Data */.  int bi
66c0: 6e 64 41 72 67 4f 6e 65 20 3d 20 30 3b 20 20 20  ndArgOne = 0;   
66d0: 20 20 20 20 20 2f 2a 20 54 72 75 65 20 74 6f 20       /* True to 
66e0: 62 69 6e 64 20 61 70 44 61 74 61 5b 31 5d 20 74  bind apData[1] t
66f0: 6f 20 73 71 6c 20 76 61 72 20 6e 6f 2e 20 31 20  o sql var no. 1 
6700: 2a 2f 0a 20 20 69 6e 74 20 69 3b 20 20 20 20 20  */.  int i;     
6710: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6720: 2f 2a 20 43 6f 75 6e 74 65 72 20 76 61 72 69 61  /* Counter varia
6730: 62 6c 65 20 75 73 65 64 20 62 79 20 66 6f 72 20  ble used by for 
6740: 6c 6f 6f 70 73 20 2a 2f 0a 0a 20 20 61 73 73 65  loops */..  asse
6750: 72 74 28 20 6e 44 61 74 61 3d 3d 70 56 74 61 62  rt( nData==pVtab
6760: 2d 3e 6e 43 6f 6c 2b 32 20 7c 7c 20 6e 44 61 74  ->nCol+2 || nDat
6770: 61 3d 3d 31 20 29 3b 0a 0a 20 20 2f 2a 20 54 69  a==1 );..  /* Ti
6780: 63 6b 65 74 20 23 33 30 38 33 20 2d 20 6d 61 6b  cket #3083 - mak
6790: 65 20 73 75 72 65 20 77 65 20 61 6c 77 61 79 73  e sure we always
67a0: 20 73 74 61 72 74 20 61 20 74 72 61 6e 73 61 63   start a transac
67b0: 74 69 6f 6e 20 70 72 69 6f 72 20 74 6f 0a 20 20  tion prior to.  
67c0: 2a 2a 20 6d 61 6b 69 6e 67 20 61 6e 79 20 63 68  ** making any ch
67d0: 61 6e 67 65 73 20 74 6f 20 61 20 76 69 72 74 75  anges to a virtu
67e0: 61 6c 20 74 61 62 6c 65 20 2a 2f 0a 20 20 61 73  al table */.  as
67f0: 73 65 72 74 28 20 70 56 74 61 62 2d 3e 69 6e 54  sert( pVtab->inT
6800: 72 61 6e 73 61 63 74 69 6f 6e 20 29 3b 0a 0a 20  ransaction );.. 
6810: 20 69 66 28 20 73 69 6d 75 6c 61 74 65 56 74 61   if( simulateVta
6820: 62 45 72 72 6f 72 28 70 56 74 61 62 2c 20 22 78  bError(pVtab, "x
6830: 55 70 64 61 74 65 22 29 20 29 7b 0a 20 20 20 20  Update") ){.    
6840: 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 45 52  return SQLITE_ER
6850: 52 4f 52 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 49  ROR;.  }..  /* I
6860: 66 20 61 70 44 61 74 61 5b 30 5d 20 69 73 20 61  f apData[0] is a
6870: 6e 20 69 6e 74 65 67 65 72 20 61 6e 64 20 6e 44  n integer and nD
6880: 61 74 61 3e 31 20 74 68 65 6e 20 64 6f 20 61 6e  ata>1 then do an
6890: 20 55 50 44 41 54 45 20 2a 2f 0a 20 20 69 66 28   UPDATE */.  if(
68a0: 20 6e 44 61 74 61 3e 31 20 26 26 20 73 71 6c 69   nData>1 && sqli
68b0: 74 65 33 5f 76 61 6c 75 65 5f 74 79 70 65 28 61  te3_value_type(a
68c0: 70 44 61 74 61 5b 30 5d 29 3d 3d 53 51 4c 49 54  pData[0])==SQLIT
68d0: 45 5f 49 4e 54 45 47 45 52 20 29 7b 0a 20 20 20  E_INTEGER ){.   
68e0: 20 63 68 61 72 20 2a 7a 53 65 70 20 3d 20 22 20   char *zSep = " 
68f0: 53 45 54 22 3b 0a 20 20 20 20 7a 20 3d 20 73 71  SET";.    z = sq
6900: 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 22 55  lite3_mprintf("U
6910: 50 44 41 54 45 20 25 51 22 2c 20 70 56 74 61 62  PDATE %Q", pVtab
6920: 2d 3e 7a 54 61 62 6c 65 4e 61 6d 65 29 3b 0a 20  ->zTableName);. 
6930: 20 20 20 69 66 28 20 21 7a 20 29 7b 0a 20 20 20     if( !z ){.   
6940: 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4e     rc = SQLITE_N
6950: 4f 4d 45 4d 3b 0a 20 20 20 20 7d 0a 0a 20 20 20  OMEM;.    }..   
6960: 20 62 69 6e 64 41 72 67 4f 6e 65 20 3d 20 28 61   bindArgOne = (a
6970: 70 44 61 74 61 5b 31 5d 20 26 26 20 73 71 6c 69  pData[1] && sqli
6980: 74 65 33 5f 76 61 6c 75 65 5f 74 79 70 65 28 61  te3_value_type(a
6990: 70 44 61 74 61 5b 31 5d 29 3d 3d 53 51 4c 49 54  pData[1])==SQLIT
69a0: 45 5f 49 4e 54 45 47 45 52 29 3b 0a 20 20 20 20  E_INTEGER);.    
69b0: 62 69 6e 64 41 72 67 5a 65 72 6f 20 3d 20 31 3b  bindArgZero = 1;
69c0: 0a 0a 20 20 20 20 69 66 28 20 62 69 6e 64 41 72  ..    if( bindAr
69d0: 67 4f 6e 65 20 29 7b 0a 20 20 20 20 20 20 20 73  gOne ){.       s
69e0: 74 72 69 6e 67 5f 63 6f 6e 63 61 74 28 26 7a 2c  tring_concat(&z,
69f0: 20 22 20 53 45 54 20 72 6f 77 69 64 3d 3f 31 20   " SET rowid=?1 
6a00: 22 2c 20 30 2c 20 26 72 63 29 3b 0a 20 20 20 20  ", 0, &rc);.    
6a10: 20 20 20 7a 53 65 70 20 3d 20 22 2c 22 3b 0a 20     zSep = ",";. 
6a20: 20 20 20 7d 0a 20 20 20 20 66 6f 72 28 69 3d 32     }.    for(i=2
6a30: 3b 20 69 3c 6e 44 61 74 61 3b 20 69 2b 2b 29 7b  ; i<nData; i++){
6a40: 0a 20 20 20 20 20 20 69 66 28 20 61 70 44 61 74  .      if( apDat
6a50: 61 5b 69 5d 3d 3d 30 20 29 20 63 6f 6e 74 69 6e  a[i]==0 ) contin
6a60: 75 65 3b 0a 20 20 20 20 20 20 73 74 72 69 6e 67  ue;.      string
6a70: 5f 63 6f 6e 63 61 74 28 26 7a 2c 20 73 71 6c 69  _concat(&z, sqli
6a80: 74 65 33 5f 6d 70 72 69 6e 74 66 28 0a 20 20 20  te3_mprintf(.   
6a90: 20 20 20 20 20 20 20 22 25 73 20 25 51 3d 3f 25         "%s %Q=?%
6aa0: 64 22 2c 20 7a 53 65 70 2c 20 70 56 74 61 62 2d  d", zSep, pVtab-
6ab0: 3e 61 43 6f 6c 5b 69 2d 32 5d 2c 20 69 29 2c 20  >aCol[i-2], i), 
6ac0: 31 2c 20 26 72 63 29 3b 0a 20 20 20 20 20 20 7a  1, &rc);.      z
6ad0: 53 65 70 20 3d 20 22 2c 22 3b 0a 20 20 20 20 7d  Sep = ",";.    }
6ae0: 0a 20 20 20 20 73 74 72 69 6e 67 5f 63 6f 6e 63  .    string_conc
6af0: 61 74 28 26 7a 2c 20 73 71 6c 69 74 65 33 5f 6d  at(&z, sqlite3_m
6b00: 70 72 69 6e 74 66 28 22 20 57 48 45 52 45 20 72  printf(" WHERE r
6b10: 6f 77 69 64 3d 3f 25 64 22 2c 20 6e 44 61 74 61  owid=?%d", nData
6b20: 29 2c 20 31 2c 20 26 72 63 29 3b 0a 20 20 7d 0a  ), 1, &rc);.  }.
6b30: 0a 20 20 2f 2a 20 49 66 20 61 70 44 61 74 61 5b  .  /* If apData[
6b40: 30 5d 20 69 73 20 61 6e 20 69 6e 74 65 67 65 72  0] is an integer
6b50: 20 61 6e 64 20 6e 44 61 74 61 3d 3d 31 20 74 68   and nData==1 th
6b60: 65 6e 20 64 6f 20 61 20 44 45 4c 45 54 45 20 2a  en do a DELETE *
6b70: 2f 0a 20 20 65 6c 73 65 20 69 66 28 20 6e 44 61  /.  else if( nDa
6b80: 74 61 3d 3d 31 20 26 26 20 73 71 6c 69 74 65 33  ta==1 && sqlite3
6b90: 5f 76 61 6c 75 65 5f 74 79 70 65 28 61 70 44 61  _value_type(apDa
6ba0: 74 61 5b 30 5d 29 3d 3d 53 51 4c 49 54 45 5f 49  ta[0])==SQLITE_I
6bb0: 4e 54 45 47 45 52 20 29 7b 0a 20 20 20 20 7a 20  NTEGER ){.    z 
6bc0: 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74  = sqlite3_mprint
6bd0: 66 28 22 44 45 4c 45 54 45 20 46 52 4f 4d 20 25  f("DELETE FROM %
6be0: 51 20 57 48 45 52 45 20 72 6f 77 69 64 20 3d 20  Q WHERE rowid = 
6bf0: 3f 31 22 2c 20 70 56 74 61 62 2d 3e 7a 54 61 62  ?1", pVtab->zTab
6c00: 6c 65 4e 61 6d 65 29 3b 0a 20 20 20 20 69 66 28  leName);.    if(
6c10: 20 21 7a 20 29 7b 0a 20 20 20 20 20 20 72 63 20   !z ){.      rc 
6c20: 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a  = SQLITE_NOMEM;.
6c30: 20 20 20 20 7d 0a 20 20 20 20 62 69 6e 64 41 72      }.    bindAr
6c40: 67 5a 65 72 6f 20 3d 20 31 3b 0a 20 20 7d 0a 0a  gZero = 1;.  }..
6c50: 20 20 2f 2a 20 49 66 20 74 68 65 20 66 69 72 73    /* If the firs
6c60: 74 20 61 72 67 75 6d 65 6e 74 20 69 73 20 4e 55  t argument is NU
6c70: 4c 4c 20 61 6e 64 20 74 68 65 72 65 20 61 72 65  LL and there are
6c80: 20 6d 6f 72 65 20 74 68 61 6e 20 74 77 6f 20 61   more than two a
6c90: 72 67 73 2c 20 49 4e 53 45 52 54 20 2a 2f 0a 20  rgs, INSERT */. 
6ca0: 20 65 6c 73 65 20 69 66 28 20 6e 44 61 74 61 3e   else if( nData>
6cb0: 32 20 26 26 20 73 71 6c 69 74 65 33 5f 76 61 6c  2 && sqlite3_val
6cc0: 75 65 5f 74 79 70 65 28 61 70 44 61 74 61 5b 30  ue_type(apData[0
6cd0: 5d 29 3d 3d 53 51 4c 49 54 45 5f 4e 55 4c 4c 20  ])==SQLITE_NULL 
6ce0: 29 7b 0a 20 20 20 20 69 6e 74 20 69 69 3b 0a 20  ){.    int ii;. 
6cf0: 20 20 20 63 68 61 72 20 2a 7a 49 6e 73 65 72 74     char *zInsert
6d00: 20 3d 20 30 3b 0a 20 20 20 20 63 68 61 72 20 2a   = 0;.    char *
6d10: 7a 56 61 6c 75 65 73 20 3d 20 30 3b 0a 20 20 0a  zValues = 0;.  .
6d20: 20 20 20 20 7a 49 6e 73 65 72 74 20 3d 20 73 71      zInsert = sq
6d30: 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 22 49  lite3_mprintf("I
6d40: 4e 53 45 52 54 20 49 4e 54 4f 20 25 51 20 28 22  NSERT INTO %Q ("
6d50: 2c 20 70 56 74 61 62 2d 3e 7a 54 61 62 6c 65 4e  , pVtab->zTableN
6d60: 61 6d 65 29 3b 0a 20 20 20 20 69 66 28 20 21 7a  ame);.    if( !z
6d70: 49 6e 73 65 72 74 20 29 7b 0a 20 20 20 20 20 20  Insert ){.      
6d80: 72 63 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45  rc = SQLITE_NOME
6d90: 4d 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 28  M;.    }.    if(
6da0: 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 74   sqlite3_value_t
6db0: 79 70 65 28 61 70 44 61 74 61 5b 31 5d 29 3d 3d  ype(apData[1])==
6dc0: 53 51 4c 49 54 45 5f 49 4e 54 45 47 45 52 20 29  SQLITE_INTEGER )
6dd0: 7b 0a 20 20 20 20 20 20 62 69 6e 64 41 72 67 4f  {.      bindArgO
6de0: 6e 65 20 3d 20 31 3b 0a 20 20 20 20 20 20 7a 56  ne = 1;.      zV
6df0: 61 6c 75 65 73 20 3d 20 73 71 6c 69 74 65 33 5f  alues = sqlite3_
6e00: 6d 70 72 69 6e 74 66 28 22 3f 22 29 3b 0a 20 20  mprintf("?");.  
6e10: 20 20 20 20 73 74 72 69 6e 67 5f 63 6f 6e 63 61      string_conca
6e20: 74 28 26 7a 49 6e 73 65 72 74 2c 20 22 72 6f 77  t(&zInsert, "row
6e30: 69 64 22 2c 20 30 2c 20 26 72 63 29 3b 0a 20 20  id", 0, &rc);.  
6e40: 20 20 7d 0a 0a 20 20 20 20 61 73 73 65 72 74 28    }..    assert(
6e50: 28 70 56 74 61 62 2d 3e 6e 43 6f 6c 2b 32 29 3d  (pVtab->nCol+2)=
6e60: 3d 6e 44 61 74 61 29 3b 0a 20 20 20 20 66 6f 72  =nData);.    for
6e70: 28 69 69 3d 32 3b 20 69 69 3c 6e 44 61 74 61 3b  (ii=2; ii<nData;
6e80: 20 69 69 2b 2b 29 7b 0a 20 20 20 20 20 20 73 74   ii++){.      st
6e90: 72 69 6e 67 5f 63 6f 6e 63 61 74 28 26 7a 49 6e  ring_concat(&zIn
6ea0: 73 65 72 74 2c 20 0a 20 20 20 20 20 20 20 20 20  sert, .         
6eb0: 20 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66   sqlite3_mprintf
6ec0: 28 22 25 73 25 51 22 2c 20 7a 56 61 6c 75 65 73  ("%s%Q", zValues
6ed0: 3f 22 2c 20 22 3a 22 22 2c 20 70 56 74 61 62 2d  ?", ":"", pVtab-
6ee0: 3e 61 43 6f 6c 5b 69 69 2d 32 5d 29 2c 20 31 2c  >aCol[ii-2]), 1,
6ef0: 20 26 72 63 29 3b 0a 20 20 20 20 20 20 73 74 72   &rc);.      str
6f00: 69 6e 67 5f 63 6f 6e 63 61 74 28 26 7a 56 61 6c  ing_concat(&zVal
6f10: 75 65 73 2c 20 0a 20 20 20 20 20 20 20 20 20 20  ues, .          
6f20: 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28  sqlite3_mprintf(
6f30: 22 25 73 3f 25 64 22 2c 20 7a 56 61 6c 75 65 73  "%s?%d", zValues
6f40: 3f 22 2c 20 22 3a 22 22 2c 20 69 69 29 2c 20 31  ?", ":"", ii), 1
6f50: 2c 20 26 72 63 29 3b 0a 20 20 20 20 7d 0a 0a 20  , &rc);.    }.. 
6f60: 20 20 20 73 74 72 69 6e 67 5f 63 6f 6e 63 61 74     string_concat
6f70: 28 26 7a 2c 20 7a 49 6e 73 65 72 74 2c 20 31 2c  (&z, zInsert, 1,
6f80: 20 26 72 63 29 3b 0a 20 20 20 20 73 74 72 69 6e   &rc);.    strin
6f90: 67 5f 63 6f 6e 63 61 74 28 26 7a 2c 20 22 29 20  g_concat(&z, ") 
6fa0: 56 41 4c 55 45 53 28 22 2c 20 30 2c 20 26 72 63  VALUES(", 0, &rc
6fb0: 29 3b 0a 20 20 20 20 73 74 72 69 6e 67 5f 63 6f  );.    string_co
6fc0: 6e 63 61 74 28 26 7a 2c 20 7a 56 61 6c 75 65 73  ncat(&z, zValues
6fd0: 2c 20 31 2c 20 26 72 63 29 3b 0a 20 20 20 20 73  , 1, &rc);.    s
6fe0: 74 72 69 6e 67 5f 63 6f 6e 63 61 74 28 26 7a 2c  tring_concat(&z,
6ff0: 20 22 29 22 2c 20 30 2c 20 26 72 63 29 3b 0a 20   ")", 0, &rc);. 
7000: 20 7d 0a 0a 20 20 2f 2a 20 41 6e 79 74 68 69 6e   }..  /* Anythin
7010: 67 20 65 6c 73 65 20 69 73 20 61 6e 20 65 72 72  g else is an err
7020: 6f 72 20 2a 2f 0a 20 20 65 6c 73 65 7b 0a 20 20  or */.  else{.  
7030: 20 20 61 73 73 65 72 74 28 30 29 3b 0a 20 20 20    assert(0);.   
7040: 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 45   return SQLITE_E
7050: 52 52 4f 52 3b 0a 20 20 7d 0a 0a 20 20 69 66 28  RROR;.  }..  if(
7060: 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc==SQLITE_OK )
7070: 7b 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74  {.    rc = sqlit
7080: 65 33 5f 70 72 65 70 61 72 65 28 64 62 2c 20 7a  e3_prepare(db, z
7090: 2c 20 2d 31 2c 20 26 70 53 74 6d 74 2c 20 30 29  , -1, &pStmt, 0)
70a0: 3b 0a 20 20 7d 0a 20 20 61 73 73 65 72 74 28 20  ;.  }.  assert( 
70b0: 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 7c 7c  rc!=SQLITE_OK ||
70c0: 20 70 53 74 6d 74 20 29 3b 0a 20 20 73 71 6c 69   pStmt );.  sqli
70d0: 74 65 33 5f 66 72 65 65 28 7a 29 3b 0a 20 20 69  te3_free(z);.  i
70e0: 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc==SQLITE_OK
70f0: 20 29 20 7b 0a 20 20 20 20 69 66 28 20 62 69 6e   ) {.    if( bin
7100: 64 41 72 67 5a 65 72 6f 20 29 7b 0a 20 20 20 20  dArgZero ){.    
7110: 20 20 73 71 6c 69 74 65 33 5f 62 69 6e 64 5f 76    sqlite3_bind_v
7120: 61 6c 75 65 28 70 53 74 6d 74 2c 20 6e 44 61 74  alue(pStmt, nDat
7130: 61 2c 20 61 70 44 61 74 61 5b 30 5d 29 3b 0a 20  a, apData[0]);. 
7140: 20 20 20 7d 0a 20 20 20 20 69 66 28 20 62 69 6e     }.    if( bin
7150: 64 41 72 67 4f 6e 65 20 29 7b 0a 20 20 20 20 20  dArgOne ){.     
7160: 20 73 71 6c 69 74 65 33 5f 62 69 6e 64 5f 76 61   sqlite3_bind_va
7170: 6c 75 65 28 70 53 74 6d 74 2c 20 31 2c 20 61 70  lue(pStmt, 1, ap
7180: 44 61 74 61 5b 31 5d 29 3b 0a 20 20 20 20 7d 0a  Data[1]);.    }.
7190: 20 20 20 20 66 6f 72 28 69 3d 32 3b 20 69 3c 6e      for(i=2; i<n
71a0: 44 61 74 61 20 26 26 20 72 63 3d 3d 53 51 4c 49  Data && rc==SQLI
71b0: 54 45 5f 4f 4b 3b 20 69 2b 2b 29 7b 0a 20 20 20  TE_OK; i++){.   
71c0: 20 20 20 69 66 28 20 61 70 44 61 74 61 5b 69 5d     if( apData[i]
71d0: 20 29 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f   ) rc = sqlite3_
71e0: 62 69 6e 64 5f 76 61 6c 75 65 28 70 53 74 6d 74  bind_value(pStmt
71f0: 2c 20 69 2c 20 61 70 44 61 74 61 5b 69 5d 29 3b  , i, apData[i]);
7200: 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 28 20 72  .    }.    if( r
7210: 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a  c==SQLITE_OK ){.
7220: 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 73 74        sqlite3_st
7230: 65 70 28 70 53 74 6d 74 29 3b 0a 20 20 20 20 20  ep(pStmt);.     
7240: 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 66 69   rc = sqlite3_fi
7250: 6e 61 6c 69 7a 65 28 70 53 74 6d 74 29 3b 0a 20  nalize(pStmt);. 
7260: 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20     }else{.      
7270: 73 71 6c 69 74 65 33 5f 66 69 6e 61 6c 69 7a 65  sqlite3_finalize
7280: 28 70 53 74 6d 74 29 3b 0a 20 20 20 20 7d 0a 20  (pStmt);.    }. 
7290: 20 7d 0a 0a 20 20 69 66 28 20 70 52 6f 77 69 64   }..  if( pRowid
72a0: 20 26 26 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f   && rc==SQLITE_O
72b0: 4b 20 29 7b 0a 20 20 20 20 2a 70 52 6f 77 69 64  K ){.    *pRowid
72c0: 20 3d 20 73 71 6c 69 74 65 33 5f 6c 61 73 74 5f   = sqlite3_last_
72d0: 69 6e 73 65 72 74 5f 72 6f 77 69 64 28 64 62 29  insert_rowid(db)
72e0: 3b 0a 20 20 7d 0a 20 20 69 66 28 20 72 63 21 3d  ;.  }.  if( rc!=
72f0: 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20  SQLITE_OK ){.   
7300: 20 74 61 62 2d 3e 7a 45 72 72 4d 73 67 20 3d 20   tab->zErrMsg = 
7310: 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28  sqlite3_mprintf(
7320: 22 65 63 68 6f 2d 76 74 61 62 2d 65 72 72 6f 72  "echo-vtab-error
7330: 3a 20 25 73 22 2c 20 73 71 6c 69 74 65 33 5f 65  : %s", sqlite3_e
7340: 72 72 6d 73 67 28 64 62 29 29 3b 0a 20 20 7d 0a  rrmsg(db));.  }.
7350: 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a  .  return rc;.}.
7360: 0a 2f 2a 0a 2a 2a 20 78 42 65 67 69 6e 2c 20 78  ./*.** xBegin, x
7370: 53 79 6e 63 2c 20 78 43 6f 6d 6d 69 74 20 61 6e  Sync, xCommit an
7380: 64 20 78 52 6f 6c 6c 62 61 63 6b 20 63 61 6c 6c  d xRollback call
7390: 62 61 63 6b 73 20 66 6f 72 20 65 63 68 6f 20 6d  backs for echo m
73a0: 6f 64 75 6c 65 0a 2a 2a 20 76 69 72 74 75 61 6c  odule.** virtual
73b0: 20 74 61 62 6c 65 73 2e 20 44 6f 20 6e 6f 74 68   tables. Do noth
73c0: 69 6e 67 20 6f 74 68 65 72 20 74 68 61 6e 20 61  ing other than a
73d0: 64 64 20 74 68 65 20 6e 61 6d 65 20 6f 66 20 74  dd the name of t
73e0: 68 65 20 63 61 6c 6c 62 61 63 6b 0a 2a 2a 20 74  he callback.** t
73f0: 6f 20 74 68 65 20 24 3a 3a 65 63 68 6f 5f 6d 6f  o the $::echo_mo
7400: 64 75 6c 65 20 54 63 6c 20 76 61 72 69 61 62 6c  dule Tcl variabl
7410: 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  e..*/.static int
7420: 20 65 63 68 6f 54 72 61 6e 73 61 63 74 69 6f 6e   echoTransaction
7430: 43 61 6c 6c 28 73 71 6c 69 74 65 33 5f 76 74 61  Call(sqlite3_vta
7440: 62 20 2a 74 61 62 2c 20 63 6f 6e 73 74 20 63 68  b *tab, const ch
7450: 61 72 20 2a 7a 43 61 6c 6c 29 7b 0a 20 20 63 68  ar *zCall){.  ch
7460: 61 72 20 2a 7a 3b 0a 20 20 65 63 68 6f 5f 76 74  ar *z;.  echo_vt
7470: 61 62 20 2a 70 56 74 61 62 20 3d 20 28 65 63 68  ab *pVtab = (ech
7480: 6f 5f 76 74 61 62 20 2a 29 74 61 62 3b 0a 20 20  o_vtab *)tab;.  
7490: 7a 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72 69  z = sqlite3_mpri
74a0: 6e 74 66 28 22 65 63 68 6f 28 25 73 29 22 2c 20  ntf("echo(%s)", 
74b0: 70 56 74 61 62 2d 3e 7a 54 61 62 6c 65 4e 61 6d  pVtab->zTableNam
74c0: 65 29 3b 0a 20 20 69 66 28 20 7a 3d 3d 30 20 29  e);.  if( z==0 )
74d0: 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4e   return SQLITE_N
74e0: 4f 4d 45 4d 3b 0a 20 20 61 70 70 65 6e 64 54 6f  OMEM;.  appendTo
74f0: 45 63 68 6f 4d 6f 64 75 6c 65 28 70 56 74 61 62  EchoModule(pVtab
7500: 2d 3e 69 6e 74 65 72 70 2c 20 7a 43 61 6c 6c 29  ->interp, zCall)
7510: 3b 0a 20 20 61 70 70 65 6e 64 54 6f 45 63 68 6f  ;.  appendToEcho
7520: 4d 6f 64 75 6c 65 28 70 56 74 61 62 2d 3e 69 6e  Module(pVtab->in
7530: 74 65 72 70 2c 20 7a 29 3b 0a 20 20 73 71 6c 69  terp, z);.  sqli
7540: 74 65 33 5f 66 72 65 65 28 7a 29 3b 0a 20 20 72  te3_free(z);.  r
7550: 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b  eturn SQLITE_OK;
7560: 0a 7d 0a 73 74 61 74 69 63 20 69 6e 74 20 65 63  .}.static int ec
7570: 68 6f 42 65 67 69 6e 28 73 71 6c 69 74 65 33 5f  hoBegin(sqlite3_
7580: 76 74 61 62 20 2a 74 61 62 29 7b 0a 20 20 69 6e  vtab *tab){.  in
7590: 74 20 72 63 3b 0a 20 20 65 63 68 6f 5f 76 74 61  t rc;.  echo_vta
75a0: 62 20 2a 70 56 74 61 62 20 3d 20 28 65 63 68 6f  b *pVtab = (echo
75b0: 5f 76 74 61 62 20 2a 29 74 61 62 3b 0a 20 20 54  _vtab *)tab;.  T
75c0: 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72  cl_Interp *inter
75d0: 70 20 3d 20 70 56 74 61 62 2d 3e 69 6e 74 65 72  p = pVtab->inter
75e0: 70 3b 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20  p;.  const char 
75f0: 2a 7a 56 61 6c 3b 20 0a 0a 20 20 2f 2a 20 54 69  *zVal; ..  /* Ti
7600: 63 6b 65 74 20 23 33 30 38 33 20 2d 20 64 6f 20  cket #3083 - do 
7610: 6e 6f 74 20 73 74 61 72 74 20 61 20 74 72 61 6e  not start a tran
7620: 73 61 63 74 69 6f 6e 20 69 66 20 77 65 20 61 72  saction if we ar
7630: 65 20 61 6c 72 65 61 64 79 20 69 6e 0a 20 20 2a  e already in.  *
7640: 2a 20 61 20 74 72 61 6e 73 61 63 74 69 6f 6e 20  * a transaction 
7650: 2a 2f 0a 20 20 61 73 73 65 72 74 28 20 21 70 56  */.  assert( !pV
7660: 74 61 62 2d 3e 69 6e 54 72 61 6e 73 61 63 74 69  tab->inTransacti
7670: 6f 6e 20 29 3b 0a 0a 20 20 69 66 28 20 73 69 6d  on );..  if( sim
7680: 75 6c 61 74 65 56 74 61 62 45 72 72 6f 72 28 70  ulateVtabError(p
7690: 56 74 61 62 2c 20 22 78 42 65 67 69 6e 22 29 20  Vtab, "xBegin") 
76a0: 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 53 51  ){.    return SQ
76b0: 4c 49 54 45 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a  LITE_ERROR;.  }.
76c0: 0a 20 20 72 63 20 3d 20 65 63 68 6f 54 72 61 6e  .  rc = echoTran
76d0: 73 61 63 74 69 6f 6e 43 61 6c 6c 28 74 61 62 2c  sactionCall(tab,
76e0: 20 22 78 42 65 67 69 6e 22 29 3b 0a 0a 20 20 69   "xBegin");..  i
76f0: 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc==SQLITE_OK
7700: 20 29 7b 0a 20 20 20 20 2f 2a 20 43 68 65 63 6b   ){.    /* Check
7710: 20 69 66 20 74 68 65 20 24 3a 3a 65 63 68 6f 5f   if the $::echo_
7720: 6d 6f 64 75 6c 65 5f 62 65 67 69 6e 5f 66 61 69  module_begin_fai
7730: 6c 20 76 61 72 69 61 62 6c 65 20 69 73 20 64 65  l variable is de
7740: 66 69 6e 65 64 2e 20 49 66 20 69 74 20 69 73 2c  fined. If it is,
7750: 0a 20 20 20 20 2a 2a 20 61 6e 64 20 69 74 20 69  .    ** and it i
7760: 73 20 73 65 74 20 74 6f 20 74 68 65 20 6e 61 6d  s set to the nam
7770: 65 20 6f 66 20 74 68 65 20 72 65 61 6c 20 74 61  e of the real ta
7780: 62 6c 65 20 75 6e 64 65 72 6c 79 69 6e 67 20 74  ble underlying t
7790: 68 69 73 20 76 69 72 74 75 61 6c 0a 20 20 20 20  his virtual.    
77a0: 2a 2a 20 65 63 68 6f 20 6d 6f 64 75 6c 65 20 74  ** echo module t
77b0: 61 62 6c 65 2c 20 74 68 65 6e 20 63 61 75 73 65  able, then cause
77c0: 20 74 68 69 73 20 78 53 79 6e 63 20 6f 70 65 72   this xSync oper
77d0: 61 74 69 6f 6e 20 74 6f 20 66 61 69 6c 2e 0a 20  ation to fail.. 
77e0: 20 20 20 2a 2f 0a 20 20 20 20 7a 56 61 6c 20 3d     */.    zVal =
77f0: 20 54 63 6c 5f 47 65 74 56 61 72 28 69 6e 74 65   Tcl_GetVar(inte
7800: 72 70 2c 20 22 65 63 68 6f 5f 6d 6f 64 75 6c 65  rp, "echo_module
7810: 5f 62 65 67 69 6e 5f 66 61 69 6c 22 2c 20 54 43  _begin_fail", TC
7820: 4c 5f 47 4c 4f 42 41 4c 5f 4f 4e 4c 59 29 3b 0a  L_GLOBAL_ONLY);.
7830: 20 20 20 20 69 66 28 20 7a 56 61 6c 20 26 26 20      if( zVal && 
7840: 30 3d 3d 73 74 72 63 6d 70 28 7a 56 61 6c 2c 20  0==strcmp(zVal, 
7850: 70 56 74 61 62 2d 3e 7a 54 61 62 6c 65 4e 61 6d  pVtab->zTableNam
7860: 65 29 20 29 7b 0a 20 20 20 20 20 20 72 63 20 3d  e) ){.      rc =
7870: 20 53 51 4c 49 54 45 5f 45 52 52 4f 52 3b 0a 20   SQLITE_ERROR;. 
7880: 20 20 20 7d 0a 20 20 7d 0a 20 20 69 66 28 20 72     }.  }.  if( r
7890: 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a  c==SQLITE_OK ){.
78a0: 20 20 20 20 70 56 74 61 62 2d 3e 69 6e 54 72 61      pVtab->inTra
78b0: 6e 73 61 63 74 69 6f 6e 20 3d 20 31 3b 0a 20 20  nsaction = 1;.  
78c0: 7d 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d  }.  return rc;.}
78d0: 0a 73 74 61 74 69 63 20 69 6e 74 20 65 63 68 6f  .static int echo
78e0: 53 79 6e 63 28 73 71 6c 69 74 65 33 5f 76 74 61  Sync(sqlite3_vta
78f0: 62 20 2a 74 61 62 29 7b 0a 20 20 69 6e 74 20 72  b *tab){.  int r
7900: 63 3b 0a 20 20 65 63 68 6f 5f 76 74 61 62 20 2a  c;.  echo_vtab *
7910: 70 56 74 61 62 20 3d 20 28 65 63 68 6f 5f 76 74  pVtab = (echo_vt
7920: 61 62 20 2a 29 74 61 62 3b 0a 20 20 54 63 6c 5f  ab *)tab;.  Tcl_
7930: 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 20 3d  Interp *interp =
7940: 20 70 56 74 61 62 2d 3e 69 6e 74 65 72 70 3b 0a   pVtab->interp;.
7950: 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 56    const char *zV
7960: 61 6c 3b 20 0a 0a 20 20 2f 2a 20 54 69 63 6b 65  al; ..  /* Ticke
7970: 74 20 23 33 30 38 33 20 2d 20 4f 6e 6c 79 20 63  t #3083 - Only c
7980: 61 6c 6c 20 78 53 79 6e 63 20 69 66 20 77 65 20  all xSync if we 
7990: 68 61 76 65 20 70 72 65 76 69 6f 75 73 6c 79 20  have previously 
79a0: 73 74 61 72 74 65 64 20 61 0a 20 20 2a 2a 20 74  started a.  ** t
79b0: 72 61 6e 73 61 63 74 69 6f 6e 20 2a 2f 0a 20 20  ransaction */.  
79c0: 61 73 73 65 72 74 28 20 70 56 74 61 62 2d 3e 69  assert( pVtab->i
79d0: 6e 54 72 61 6e 73 61 63 74 69 6f 6e 20 29 3b 0a  nTransaction );.
79e0: 0a 20 20 69 66 28 20 73 69 6d 75 6c 61 74 65 56  .  if( simulateV
79f0: 74 61 62 45 72 72 6f 72 28 70 56 74 61 62 2c 20  tabError(pVtab, 
7a00: 22 78 53 79 6e 63 22 29 20 29 7b 0a 20 20 20 20  "xSync") ){.    
7a10: 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 45 52  return SQLITE_ER
7a20: 52 4f 52 3b 0a 20 20 7d 0a 0a 20 20 72 63 20 3d  ROR;.  }..  rc =
7a30: 20 65 63 68 6f 54 72 61 6e 73 61 63 74 69 6f 6e   echoTransaction
7a40: 43 61 6c 6c 28 74 61 62 2c 20 22 78 53 79 6e 63  Call(tab, "xSync
7a50: 22 29 3b 0a 0a 20 20 69 66 28 20 72 63 3d 3d 53  ");..  if( rc==S
7a60: 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
7a70: 2f 2a 20 43 68 65 63 6b 20 69 66 20 74 68 65 20  /* Check if the 
7a80: 24 3a 3a 65 63 68 6f 5f 6d 6f 64 75 6c 65 5f 73  $::echo_module_s
7a90: 79 6e 63 5f 66 61 69 6c 20 76 61 72 69 61 62 6c  ync_fail variabl
7aa0: 65 20 69 73 20 64 65 66 69 6e 65 64 2e 20 49 66  e is defined. If
7ab0: 20 69 74 20 69 73 2c 0a 20 20 20 20 2a 2a 20 61   it is,.    ** a
7ac0: 6e 64 20 69 74 20 69 73 20 73 65 74 20 74 6f 20  nd it is set to 
7ad0: 74 68 65 20 6e 61 6d 65 20 6f 66 20 74 68 65 20  the name of the 
7ae0: 72 65 61 6c 20 74 61 62 6c 65 20 75 6e 64 65 72  real table under
7af0: 6c 79 69 6e 67 20 74 68 69 73 20 76 69 72 74 75  lying this virtu
7b00: 61 6c 0a 20 20 20 20 2a 2a 20 65 63 68 6f 20 6d  al.    ** echo m
7b10: 6f 64 75 6c 65 20 74 61 62 6c 65 2c 20 74 68 65  odule table, the
7b20: 6e 20 63 61 75 73 65 20 74 68 69 73 20 78 53 79  n cause this xSy
7b30: 6e 63 20 6f 70 65 72 61 74 69 6f 6e 20 74 6f 20  nc operation to 
7b40: 66 61 69 6c 2e 0a 20 20 20 20 2a 2f 0a 20 20 20  fail..    */.   
7b50: 20 7a 56 61 6c 20 3d 20 54 63 6c 5f 47 65 74 56   zVal = Tcl_GetV
7b60: 61 72 28 69 6e 74 65 72 70 2c 20 22 65 63 68 6f  ar(interp, "echo
7b70: 5f 6d 6f 64 75 6c 65 5f 73 79 6e 63 5f 66 61 69  _module_sync_fai
7b80: 6c 22 2c 20 54 43 4c 5f 47 4c 4f 42 41 4c 5f 4f  l", TCL_GLOBAL_O
7b90: 4e 4c 59 29 3b 0a 20 20 20 20 69 66 28 20 7a 56  NLY);.    if( zV
7ba0: 61 6c 20 26 26 20 30 3d 3d 73 74 72 63 6d 70 28  al && 0==strcmp(
7bb0: 7a 56 61 6c 2c 20 70 56 74 61 62 2d 3e 7a 54 61  zVal, pVtab->zTa
7bc0: 62 6c 65 4e 61 6d 65 29 20 29 7b 0a 20 20 20 20  bleName) ){.    
7bd0: 20 20 72 63 20 3d 20 2d 31 3b 0a 20 20 20 20 7d    rc = -1;.    }
7be0: 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 72 63  .  }.  return rc
7bf0: 3b 0a 7d 0a 73 74 61 74 69 63 20 69 6e 74 20 65  ;.}.static int e
7c00: 63 68 6f 43 6f 6d 6d 69 74 28 73 71 6c 69 74 65  choCommit(sqlite
7c10: 33 5f 76 74 61 62 20 2a 74 61 62 29 7b 0a 20 20  3_vtab *tab){.  
7c20: 65 63 68 6f 5f 76 74 61 62 20 2a 70 56 74 61 62  echo_vtab *pVtab
7c30: 20 3d 20 28 65 63 68 6f 5f 76 74 61 62 2a 29 74   = (echo_vtab*)t
7c40: 61 62 3b 0a 20 20 69 6e 74 20 72 63 3b 0a 0a 20  ab;.  int rc;.. 
7c50: 20 2f 2a 20 54 69 63 6b 65 74 20 23 33 30 38 33   /* Ticket #3083
7c60: 20 2d 20 4f 6e 6c 79 20 63 61 6c 6c 20 78 43 6f   - Only call xCo
7c70: 6d 6d 69 74 20 69 66 20 77 65 20 68 61 76 65 20  mmit if we have 
7c80: 70 72 65 76 69 6f 75 73 6c 79 20 73 74 61 72 74  previously start
7c90: 65 64 0a 20 20 2a 2a 20 61 20 74 72 61 6e 73 61  ed.  ** a transa
7ca0: 63 74 69 6f 6e 20 2a 2f 0a 20 20 61 73 73 65 72  ction */.  asser
7cb0: 74 28 20 70 56 74 61 62 2d 3e 69 6e 54 72 61 6e  t( pVtab->inTran
7cc0: 73 61 63 74 69 6f 6e 20 29 3b 0a 0a 20 20 69 66  saction );..  if
7cd0: 28 20 73 69 6d 75 6c 61 74 65 56 74 61 62 45 72  ( simulateVtabEr
7ce0: 72 6f 72 28 70 56 74 61 62 2c 20 22 78 43 6f 6d  ror(pVtab, "xCom
7cf0: 6d 69 74 22 29 20 29 7b 0a 20 20 20 20 72 65 74  mit") ){.    ret
7d00: 75 72 6e 20 53 51 4c 49 54 45 5f 45 52 52 4f 52  urn SQLITE_ERROR
7d10: 3b 0a 20 20 7d 0a 0a 20 20 73 71 6c 69 74 65 33  ;.  }..  sqlite3
7d20: 42 65 67 69 6e 42 65 6e 69 67 6e 4d 61 6c 6c 6f  BeginBenignMallo
7d30: 63 28 29 3b 0a 20 20 72 63 20 3d 20 65 63 68 6f  c();.  rc = echo
7d40: 54 72 61 6e 73 61 63 74 69 6f 6e 43 61 6c 6c 28  TransactionCall(
7d50: 74 61 62 2c 20 22 78 43 6f 6d 6d 69 74 22 29 3b  tab, "xCommit");
7d60: 0a 20 20 73 71 6c 69 74 65 33 45 6e 64 42 65 6e  .  sqlite3EndBen
7d70: 69 67 6e 4d 61 6c 6c 6f 63 28 29 3b 0a 20 20 70  ignMalloc();.  p
7d80: 56 74 61 62 2d 3e 69 6e 54 72 61 6e 73 61 63 74  Vtab->inTransact
7d90: 69 6f 6e 20 3d 20 30 3b 0a 20 20 72 65 74 75 72  ion = 0;.  retur
7da0: 6e 20 72 63 3b 0a 7d 0a 73 74 61 74 69 63 20 69  n rc;.}.static i
7db0: 6e 74 20 65 63 68 6f 52 6f 6c 6c 62 61 63 6b 28  nt echoRollback(
7dc0: 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 74 61  sqlite3_vtab *ta
7dd0: 62 29 7b 0a 20 20 69 6e 74 20 72 63 3b 0a 20 20  b){.  int rc;.  
7de0: 65 63 68 6f 5f 76 74 61 62 20 2a 70 56 74 61 62  echo_vtab *pVtab
7df0: 20 3d 20 28 65 63 68 6f 5f 76 74 61 62 2a 29 74   = (echo_vtab*)t
7e00: 61 62 3b 0a 0a 20 20 2f 2a 20 54 69 63 6b 65 74  ab;..  /* Ticket
7e10: 20 23 33 30 38 33 20 2d 20 4f 6e 6c 79 20 63 61   #3083 - Only ca
7e20: 6c 6c 20 78 52 6f 6c 6c 62 61 63 6b 20 69 66 20  ll xRollback if 
7e30: 77 65 20 68 61 76 65 20 70 72 65 76 69 6f 75 73  we have previous
7e40: 6c 79 20 73 74 61 72 74 65 64 0a 20 20 2a 2a 20  ly started.  ** 
7e50: 61 20 74 72 61 6e 73 61 63 74 69 6f 6e 20 2a 2f  a transaction */
7e60: 0a 20 20 61 73 73 65 72 74 28 20 70 56 74 61 62  .  assert( pVtab
7e70: 2d 3e 69 6e 54 72 61 6e 73 61 63 74 69 6f 6e 20  ->inTransaction 
7e80: 29 3b 0a 0a 20 20 72 63 20 3d 20 65 63 68 6f 54  );..  rc = echoT
7e90: 72 61 6e 73 61 63 74 69 6f 6e 43 61 6c 6c 28 74  ransactionCall(t
7ea0: 61 62 2c 20 22 78 52 6f 6c 6c 62 61 63 6b 22 29  ab, "xRollback")
7eb0: 3b 0a 20 20 70 56 74 61 62 2d 3e 69 6e 54 72 61  ;.  pVtab->inTra
7ec0: 6e 73 61 63 74 69 6f 6e 20 3d 20 30 3b 0a 20 20  nsaction = 0;.  
7ed0: 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a  return rc;.}../*
7ee0: 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74 61 74 69  .** Implementati
7ef0: 6f 6e 20 6f 66 20 22 47 4c 4f 42 22 20 66 75 6e  on of "GLOB" fun
7f00: 63 74 69 6f 6e 20 6f 6e 20 74 68 65 20 65 63 68  ction on the ech
7f10: 6f 20 6d 6f 64 75 6c 65 2e 20 20 50 61 73 73 0a  o module.  Pass.
7f20: 2a 2a 20 61 6c 6c 20 61 72 67 75 6d 65 6e 74 73  ** all arguments
7f30: 20 74 6f 20 74 68 65 20 3a 3a 65 63 68 6f 5f 67   to the ::echo_g
7f40: 6c 6f 62 5f 6f 76 65 72 6c 6f 61 64 20 70 72 6f  lob_overload pro
7f50: 63 65 64 75 72 65 20 6f 66 20 54 43 4c 0a 2a 2a  cedure of TCL.**
7f60: 20 61 6e 64 20 72 65 74 75 72 6e 20 74 68 65 20   and return the 
7f70: 72 65 73 75 6c 74 20 6f 66 20 74 68 61 74 20 70  result of that p
7f80: 72 6f 63 65 64 75 72 65 20 61 73 20 61 20 73 74  rocedure as a st
7f90: 72 69 6e 67 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  ring..*/.static 
7fa0: 76 6f 69 64 20 6f 76 65 72 6c 6f 61 64 65 64 47  void overloadedG
7fb0: 6c 6f 62 46 75 6e 63 74 69 6f 6e 28 0a 20 20 73  lobFunction(.  s
7fc0: 71 6c 69 74 65 33 5f 63 6f 6e 74 65 78 74 20 2a  qlite3_context *
7fd0: 70 43 6f 6e 74 65 78 74 2c 0a 20 20 69 6e 74 20  pContext,.  int 
7fe0: 6e 41 72 67 2c 0a 20 20 73 71 6c 69 74 65 33 5f  nArg,.  sqlite3_
7ff0: 76 61 6c 75 65 20 2a 2a 61 70 41 72 67 0a 29 7b  value **apArg.){
8000: 0a 20 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69  .  Tcl_Interp *i
8010: 6e 74 65 72 70 20 3d 20 73 71 6c 69 74 65 33 5f  nterp = sqlite3_
8020: 75 73 65 72 5f 64 61 74 61 28 70 43 6f 6e 74 65  user_data(pConte
8030: 78 74 29 3b 0a 20 20 54 63 6c 5f 44 53 74 72 69  xt);.  Tcl_DStri
8040: 6e 67 20 73 74 72 3b 0a 20 20 69 6e 74 20 69 3b  ng str;.  int i;
8050: 0a 20 20 69 6e 74 20 72 63 3b 0a 20 20 54 63 6c  .  int rc;.  Tcl
8060: 5f 44 53 74 72 69 6e 67 49 6e 69 74 28 26 73 74  _DStringInit(&st
8070: 72 29 3b 0a 20 20 54 63 6c 5f 44 53 74 72 69 6e  r);.  Tcl_DStrin
8080: 67 41 70 70 65 6e 64 45 6c 65 6d 65 6e 74 28 26  gAppendElement(&
8090: 73 74 72 2c 20 22 3a 3a 65 63 68 6f 5f 67 6c 6f  str, "::echo_glo
80a0: 62 5f 6f 76 65 72 6c 6f 61 64 22 29 3b 0a 20 20  b_overload");.  
80b0: 66 6f 72 28 69 3d 30 3b 20 69 3c 6e 41 72 67 3b  for(i=0; i<nArg;
80c0: 20 69 2b 2b 29 7b 0a 20 20 20 20 54 63 6c 5f 44   i++){.    Tcl_D
80d0: 53 74 72 69 6e 67 41 70 70 65 6e 64 45 6c 65 6d  StringAppendElem
80e0: 65 6e 74 28 26 73 74 72 2c 20 28 63 68 61 72 2a  ent(&str, (char*
80f0: 29 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 74  )sqlite3_value_t
8100: 65 78 74 28 61 70 41 72 67 5b 69 5d 29 29 3b 0a  ext(apArg[i]));.
8110: 20 20 7d 0a 20 20 72 63 20 3d 20 54 63 6c 5f 45    }.  rc = Tcl_E
8120: 76 61 6c 28 69 6e 74 65 72 70 2c 20 54 63 6c 5f  val(interp, Tcl_
8130: 44 53 74 72 69 6e 67 56 61 6c 75 65 28 26 73 74  DStringValue(&st
8140: 72 29 29 3b 0a 20 20 54 63 6c 5f 44 53 74 72 69  r));.  Tcl_DStri
8150: 6e 67 46 72 65 65 28 26 73 74 72 29 3b 0a 20 20  ngFree(&str);.  
8160: 69 66 28 20 72 63 20 29 7b 0a 20 20 20 20 73 71  if( rc ){.    sq
8170: 6c 69 74 65 33 5f 72 65 73 75 6c 74 5f 65 72 72  lite3_result_err
8180: 6f 72 28 70 43 6f 6e 74 65 78 74 2c 20 54 63 6c  or(pContext, Tcl
8190: 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74  _GetStringResult
81a0: 28 69 6e 74 65 72 70 29 2c 20 2d 31 29 3b 0a 20  (interp), -1);. 
81b0: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 73 71 6c 69   }else{.    sqli
81c0: 74 65 33 5f 72 65 73 75 6c 74 5f 74 65 78 74 28  te3_result_text(
81d0: 70 43 6f 6e 74 65 78 74 2c 20 54 63 6c 5f 47 65  pContext, Tcl_Ge
81e0: 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e  tStringResult(in
81f0: 74 65 72 70 29 2c 0a 20 20 20 20 20 20 20 20 20  terp),.         
8200: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2d                 -
8210: 31 2c 20 53 51 4c 49 54 45 5f 54 52 41 4e 53 49  1, SQLITE_TRANSI
8220: 45 4e 54 29 3b 0a 20 20 7d 0a 20 20 54 63 6c 5f  ENT);.  }.  Tcl_
8230: 52 65 73 65 74 52 65 73 75 6c 74 28 69 6e 74 65  ResetResult(inte
8240: 72 70 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68  rp);.}../*.** Th
8250: 69 73 20 69 73 20 74 68 65 20 78 46 69 6e 64 46  is is the xFindF
8260: 75 6e 63 74 69 6f 6e 20 69 6d 70 6c 65 6d 65 6e  unction implemen
8270: 74 61 74 69 6f 6e 20 66 6f 72 20 74 68 65 20 65  tation for the e
8280: 63 68 6f 20 6d 6f 64 75 6c 65 2e 0a 2a 2a 20 53  cho module..** S
8290: 51 4c 69 74 65 20 63 61 6c 6c 73 20 74 68 69 73  QLite calls this
82a0: 20 72 6f 75 74 69 6e 65 20 77 68 65 6e 20 74 68   routine when th
82b0: 65 20 66 69 72 73 74 20 61 72 67 75 6d 65 6e 74  e first argument
82c0: 20 6f 66 20 61 20 66 75 6e 63 74 69 6f 6e 0a 2a   of a function.*
82d0: 2a 20 69 73 20 61 20 63 6f 6c 75 6d 6e 20 6f 66  * is a column of
82e0: 20 61 6e 20 65 63 68 6f 20 76 69 72 74 75 61 6c   an echo virtual
82f0: 20 74 61 62 6c 65 2e 20 20 54 68 69 73 20 72 6f   table.  This ro
8300: 75 74 69 6e 65 20 63 61 6e 20 6f 70 74 69 6f 6e  utine can option
8310: 61 6c 6c 79 0a 2a 2a 20 6f 76 65 72 72 69 64 65  ally.** override
8320: 20 74 68 65 20 69 6d 70 6c 65 6d 65 6e 74 61 74   the implementat
8330: 69 6f 6e 20 6f 66 20 74 68 61 74 20 66 75 6e 63  ion of that func
8340: 74 69 6f 6e 2e 20 20 49 74 20 77 69 6c 6c 20 63  tion.  It will c
8350: 68 6f 6f 73 65 20 74 6f 0a 2a 2a 20 64 6f 20 73  hoose to.** do s
8360: 6f 20 69 66 20 74 68 65 20 66 75 6e 63 74 69 6f  o if the functio
8370: 6e 20 69 73 20 6e 61 6d 65 64 20 22 67 6c 6f 62  n is named "glob
8380: 22 2c 20 61 6e 64 20 61 20 54 43 4c 20 63 6f 6d  ", and a TCL com
8390: 6d 61 6e 64 20 6e 61 6d 65 64 0a 2a 2a 20 3a 3a  mand named.** ::
83a0: 65 63 68 6f 5f 67 6c 6f 62 5f 6f 76 65 72 6c 6f  echo_glob_overlo
83b0: 61 64 20 65 78 69 73 74 73 2e 0a 2a 2f 0a 73 74  ad exists..*/.st
83c0: 61 74 69 63 20 69 6e 74 20 65 63 68 6f 46 69 6e  atic int echoFin
83d0: 64 46 75 6e 63 74 69 6f 6e 28 0a 20 20 73 71 6c  dFunction(.  sql
83e0: 69 74 65 33 5f 76 74 61 62 20 2a 76 74 61 62 2c  ite3_vtab *vtab,
83f0: 0a 20 20 69 6e 74 20 6e 41 72 67 2c 0a 20 20 63  .  int nArg,.  c
8400: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 46 75 6e 63  onst char *zFunc
8410: 4e 61 6d 65 2c 0a 20 20 76 6f 69 64 20 28 2a 2a  Name,.  void (**
8420: 70 78 46 75 6e 63 29 28 73 71 6c 69 74 65 33 5f  pxFunc)(sqlite3_
8430: 63 6f 6e 74 65 78 74 2a 2c 69 6e 74 2c 73 71 6c  context*,int,sql
8440: 69 74 65 33 5f 76 61 6c 75 65 2a 2a 29 2c 0a 20  ite3_value**),. 
8450: 20 76 6f 69 64 20 2a 2a 70 70 41 72 67 0a 29 7b   void **ppArg.){
8460: 0a 20 20 65 63 68 6f 5f 76 74 61 62 20 2a 70 56  .  echo_vtab *pV
8470: 74 61 62 20 3d 20 28 65 63 68 6f 5f 76 74 61 62  tab = (echo_vtab
8480: 20 2a 29 76 74 61 62 3b 0a 20 20 54 63 6c 5f 49   *)vtab;.  Tcl_I
8490: 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 20 3d 20  nterp *interp = 
84a0: 70 56 74 61 62 2d 3e 69 6e 74 65 72 70 3b 0a 20  pVtab->interp;. 
84b0: 20 54 63 6c 5f 43 6d 64 49 6e 66 6f 20 69 6e 66   Tcl_CmdInfo inf
84c0: 6f 3b 0a 20 20 69 66 28 20 73 74 72 63 6d 70 28  o;.  if( strcmp(
84d0: 7a 46 75 6e 63 4e 61 6d 65 2c 22 67 6c 6f 62 22  zFuncName,"glob"
84e0: 29 21 3d 30 20 29 7b 0a 20 20 20 20 72 65 74 75  )!=0 ){.    retu
84f0: 72 6e 20 30 3b 0a 20 20 7d 0a 20 20 69 66 28 20  rn 0;.  }.  if( 
8500: 54 63 6c 5f 47 65 74 43 6f 6d 6d 61 6e 64 49 6e  Tcl_GetCommandIn
8510: 66 6f 28 69 6e 74 65 72 70 2c 20 22 3a 3a 65 63  fo(interp, "::ec
8520: 68 6f 5f 67 6c 6f 62 5f 6f 76 65 72 6c 6f 61 64  ho_glob_overload
8530: 22 2c 20 26 69 6e 66 6f 29 3d 3d 30 20 29 7b 0a  ", &info)==0 ){.
8540: 20 20 20 20 72 65 74 75 72 6e 20 30 3b 0a 20 20      return 0;.  
8550: 7d 0a 20 20 2a 70 78 46 75 6e 63 20 3d 20 6f 76  }.  *pxFunc = ov
8560: 65 72 6c 6f 61 64 65 64 47 6c 6f 62 46 75 6e 63  erloadedGlobFunc
8570: 74 69 6f 6e 3b 0a 20 20 2a 70 70 41 72 67 20 3d  tion;.  *ppArg =
8580: 20 69 6e 74 65 72 70 3b 0a 20 20 72 65 74 75 72   interp;.  retur
8590: 6e 20 31 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69  n 1;.}..static i
85a0: 6e 74 20 65 63 68 6f 52 65 6e 61 6d 65 28 73 71  nt echoRename(sq
85b0: 6c 69 74 65 33 5f 76 74 61 62 20 2a 76 74 61 62  lite3_vtab *vtab
85c0: 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 4e  , const char *zN
85d0: 65 77 4e 61 6d 65 29 7b 0a 20 20 69 6e 74 20 72  ewName){.  int r
85e0: 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20  c = SQLITE_OK;. 
85f0: 20 65 63 68 6f 5f 76 74 61 62 20 2a 70 20 3d 20   echo_vtab *p = 
8600: 28 65 63 68 6f 5f 76 74 61 62 20 2a 29 76 74 61  (echo_vtab *)vta
8610: 62 3b 0a 0a 20 20 69 66 28 20 73 69 6d 75 6c 61  b;..  if( simula
8620: 74 65 56 74 61 62 45 72 72 6f 72 28 70 2c 20 22  teVtabError(p, "
8630: 78 52 65 6e 61 6d 65 22 29 20 29 7b 0a 20 20 20  xRename") ){.   
8640: 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 45   return SQLITE_E
8650: 52 52 4f 52 3b 0a 20 20 7d 0a 0a 20 20 69 66 28  RROR;.  }..  if(
8660: 20 70 2d 3e 69 73 50 61 74 74 65 72 6e 20 29 7b   p->isPattern ){
8670: 0a 20 20 20 20 69 6e 74 20 6e 54 68 69 73 20 3d  .    int nThis =
8680: 20 28 69 6e 74 29 73 74 72 6c 65 6e 28 70 2d 3e   (int)strlen(p->
8690: 7a 54 68 69 73 29 3b 0a 20 20 20 20 63 68 61 72  zThis);.    char
86a0: 20 2a 7a 53 71 6c 20 3d 20 73 71 6c 69 74 65 33   *zSql = sqlite3
86b0: 5f 6d 70 72 69 6e 74 66 28 22 41 4c 54 45 52 20  _mprintf("ALTER 
86c0: 54 41 42 4c 45 20 25 73 20 52 45 4e 41 4d 45 20  TABLE %s RENAME 
86d0: 54 4f 20 25 73 25 73 22 2c 20 0a 20 20 20 20 20  TO %s%s", .     
86e0: 20 20 20 70 2d 3e 7a 54 61 62 6c 65 4e 61 6d 65     p->zTableName
86f0: 2c 20 7a 4e 65 77 4e 61 6d 65 2c 20 26 70 2d 3e  , zNewName, &p->
8700: 7a 54 61 62 6c 65 4e 61 6d 65 5b 6e 54 68 69 73  zTableName[nThis
8710: 5d 0a 20 20 20 20 29 3b 0a 20 20 20 20 72 63 20  ].    );.    rc 
8720: 3d 20 73 71 6c 69 74 65 33 5f 65 78 65 63 28 70  = sqlite3_exec(p
8730: 2d 3e 64 62 2c 20 7a 53 71 6c 2c 20 30 2c 20 30  ->db, zSql, 0, 0
8740: 2c 20 30 29 3b 0a 20 20 20 20 73 71 6c 69 74 65  , 0);.    sqlite
8750: 33 5f 66 72 65 65 28 7a 53 71 6c 29 3b 0a 20 20  3_free(zSql);.  
8760: 7d 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a  }..  return rc;.
8770: 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 65 63  }..static int ec
8780: 68 6f 53 61 76 65 70 6f 69 6e 74 28 73 71 6c 69  hoSavepoint(sqli
8790: 74 65 33 5f 76 74 61 62 20 2a 70 56 54 61 62 2c  te3_vtab *pVTab,
87a0: 20 69 6e 74 20 69 53 61 76 65 70 6f 69 6e 74 29   int iSavepoint)
87b0: 7b 0a 20 20 61 73 73 65 72 74 28 20 70 56 54 61  {.  assert( pVTa
87c0: 62 20 29 3b 0a 20 20 72 65 74 75 72 6e 20 53 51  b );.  return SQ
87d0: 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 73 74 61 74  LITE_OK;.}..stat
87e0: 69 63 20 69 6e 74 20 65 63 68 6f 52 65 6c 65 61  ic int echoRelea
87f0: 73 65 28 73 71 6c 69 74 65 33 5f 76 74 61 62 20  se(sqlite3_vtab 
8800: 2a 70 56 54 61 62 2c 20 69 6e 74 20 69 53 61 76  *pVTab, int iSav
8810: 65 70 6f 69 6e 74 29 7b 0a 20 20 61 73 73 65 72  epoint){.  asser
8820: 74 28 20 70 56 54 61 62 20 29 3b 0a 20 20 72 65  t( pVTab );.  re
8830: 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a  turn SQLITE_OK;.
8840: 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 65 63  }..static int ec
8850: 68 6f 52 6f 6c 6c 62 61 63 6b 54 6f 28 73 71 6c  hoRollbackTo(sql
8860: 69 74 65 33 5f 76 74 61 62 20 2a 70 56 54 61 62  ite3_vtab *pVTab
8870: 2c 20 69 6e 74 20 69 53 61 76 65 70 6f 69 6e 74  , int iSavepoint
8880: 29 7b 0a 20 20 61 73 73 65 72 74 28 20 70 56 54  ){.  assert( pVT
8890: 61 62 20 29 3b 0a 20 20 72 65 74 75 72 6e 20 53  ab );.  return S
88a0: 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a  QLITE_OK;.}../*.
88b0: 2a 2a 20 41 20 76 69 72 74 75 61 6c 20 74 61 62  ** A virtual tab
88c0: 6c 65 20 6d 6f 64 75 6c 65 20 74 68 61 74 20 6d  le module that m
88d0: 65 72 65 6c 79 20 22 65 63 68 6f 73 22 20 74 68  erely "echos" th
88e0: 65 20 63 6f 6e 74 65 6e 74 73 20 6f 66 20 61 6e  e contents of an
88f0: 6f 74 68 65 72 0a 2a 2a 20 74 61 62 6c 65 20 28  other.** table (
8900: 6c 69 6b 65 20 61 6e 20 53 51 4c 20 56 49 45 57  like an SQL VIEW
8910: 29 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 73 71 6c  )..*/.static sql
8920: 69 74 65 33 5f 6d 6f 64 75 6c 65 20 65 63 68 6f  ite3_module echo
8930: 4d 6f 64 75 6c 65 20 3d 20 7b 0a 20 20 31 2c 20  Module = {.  1, 
8940: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8950: 20 20 20 20 20 20 20 20 2f 2a 20 69 56 65 72 73          /* iVers
8960: 69 6f 6e 20 2a 2f 0a 20 20 65 63 68 6f 43 72 65  ion */.  echoCre
8970: 61 74 65 2c 0a 20 20 65 63 68 6f 43 6f 6e 6e 65  ate,.  echoConne
8980: 63 74 2c 0a 20 20 65 63 68 6f 42 65 73 74 49 6e  ct,.  echoBestIn
8990: 64 65 78 2c 0a 20 20 65 63 68 6f 44 69 73 63 6f  dex,.  echoDisco
89a0: 6e 6e 65 63 74 2c 20 0a 20 20 65 63 68 6f 44 65  nnect, .  echoDe
89b0: 73 74 72 6f 79 2c 0a 20 20 65 63 68 6f 4f 70 65  stroy,.  echoOpe
89c0: 6e 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  n,              
89d0: 20 20 20 20 2f 2a 20 78 4f 70 65 6e 20 2d 20 6f      /* xOpen - o
89e0: 70 65 6e 20 61 20 63 75 72 73 6f 72 20 2a 2f 0a  pen a cursor */.
89f0: 20 20 65 63 68 6f 43 6c 6f 73 65 2c 20 20 20 20    echoClose,    
8a00: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
8a10: 78 43 6c 6f 73 65 20 2d 20 63 6c 6f 73 65 20 61  xClose - close a
8a20: 20 63 75 72 73 6f 72 20 2a 2f 0a 20 20 65 63 68   cursor */.  ech
8a30: 6f 46 69 6c 74 65 72 2c 20 20 20 20 20 20 20 20  oFilter,        
8a40: 20 20 20 20 20 20 20 20 2f 2a 20 78 46 69 6c 74          /* xFilt
8a50: 65 72 20 2d 20 63 6f 6e 66 69 67 75 72 65 20 73  er - configure s
8a60: 63 61 6e 20 63 6f 6e 73 74 72 61 69 6e 74 73 20  can constraints 
8a70: 2a 2f 0a 20 20 65 63 68 6f 4e 65 78 74 2c 20 20  */.  echoNext,  
8a80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8a90: 2f 2a 20 78 4e 65 78 74 20 2d 20 61 64 76 61 6e  /* xNext - advan
8aa0: 63 65 20 61 20 63 75 72 73 6f 72 20 2a 2f 0a 20  ce a cursor */. 
8ab0: 20 65 63 68 6f 45 6f 66 2c 20 20 20 20 20 20 20   echoEof,       
8ac0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78              /* x
8ad0: 45 6f 66 20 2a 2f 0a 20 20 65 63 68 6f 43 6f 6c  Eof */.  echoCol
8ae0: 75 6d 6e 2c 20 20 20 20 20 20 20 20 20 20 20 20  umn,            
8af0: 20 20 20 20 2f 2a 20 78 43 6f 6c 75 6d 6e 20 2d      /* xColumn -
8b00: 20 72 65 61 64 20 64 61 74 61 20 2a 2f 0a 20 20   read data */.  
8b10: 65 63 68 6f 52 6f 77 69 64 2c 20 20 20 20 20 20  echoRowid,      
8b20: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 52             /* xR
8b30: 6f 77 69 64 20 2d 20 72 65 61 64 20 64 61 74 61  owid - read data
8b40: 20 2a 2f 0a 20 20 65 63 68 6f 55 70 64 61 74 65   */.  echoUpdate
8b50: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
8b60: 20 2f 2a 20 78 55 70 64 61 74 65 20 2d 20 77 72   /* xUpdate - wr
8b70: 69 74 65 20 64 61 74 61 20 2a 2f 0a 20 20 65 63  ite data */.  ec
8b80: 68 6f 42 65 67 69 6e 2c 20 20 20 20 20 20 20 20  hoBegin,        
8b90: 20 20 20 20 20 20 20 20 20 2f 2a 20 78 42 65 67           /* xBeg
8ba0: 69 6e 20 2d 20 62 65 67 69 6e 20 74 72 61 6e 73  in - begin trans
8bb0: 61 63 74 69 6f 6e 20 2a 2f 0a 20 20 65 63 68 6f  action */.  echo
8bc0: 53 79 6e 63 2c 20 20 20 20 20 20 20 20 20 20 20  Sync,           
8bd0: 20 20 20 20 20 20 20 2f 2a 20 78 53 79 6e 63 20         /* xSync 
8be0: 2d 20 73 79 6e 63 20 74 72 61 6e 73 61 63 74 69  - sync transacti
8bf0: 6f 6e 20 2a 2f 0a 20 20 65 63 68 6f 43 6f 6d 6d  on */.  echoComm
8c00: 69 74 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  it,             
8c10: 20 20 20 2f 2a 20 78 43 6f 6d 6d 69 74 20 2d 20     /* xCommit - 
8c20: 63 6f 6d 6d 69 74 20 74 72 61 6e 73 61 63 74 69  commit transacti
8c30: 6f 6e 20 2a 2f 0a 20 20 65 63 68 6f 52 6f 6c 6c  on */.  echoRoll
8c40: 62 61 63 6b 2c 20 20 20 20 20 20 20 20 20 20 20  back,           
8c50: 20 20 20 2f 2a 20 78 52 6f 6c 6c 62 61 63 6b 20     /* xRollback 
8c60: 2d 20 72 6f 6c 6c 62 61 63 6b 20 74 72 61 6e 73  - rollback trans
8c70: 61 63 74 69 6f 6e 20 2a 2f 0a 20 20 65 63 68 6f  action */.  echo
8c80: 46 69 6e 64 46 75 6e 63 74 69 6f 6e 2c 20 20 20  FindFunction,   
8c90: 20 20 20 20 20 20 20 2f 2a 20 78 46 69 6e 64 46         /* xFindF
8ca0: 75 6e 63 74 69 6f 6e 20 2d 20 66 75 6e 63 74 69  unction - functi
8cb0: 6f 6e 20 6f 76 65 72 6c 6f 61 64 69 6e 67 20 2a  on overloading *
8cc0: 2f 0a 20 20 65 63 68 6f 52 65 6e 61 6d 65 20 20  /.  echoRename  
8cd0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
8ce0: 2a 20 78 52 65 6e 61 6d 65 20 2d 20 72 65 6e 61  * xRename - rena
8cf0: 6d 65 20 74 68 65 20 74 61 62 6c 65 20 2a 2f 0a  me the table */.
8d00: 7d 3b 0a 0a 73 74 61 74 69 63 20 73 71 6c 69 74  };..static sqlit
8d10: 65 33 5f 6d 6f 64 75 6c 65 20 65 63 68 6f 4d 6f  e3_module echoMo
8d20: 64 75 6c 65 56 32 20 3d 20 7b 0a 20 20 32 2c 20  duleV2 = {.  2, 
8d30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8d40: 20 20 20 20 20 20 20 20 2f 2a 20 69 56 65 72 73          /* iVers
8d50: 69 6f 6e 20 2a 2f 0a 20 20 65 63 68 6f 43 72 65  ion */.  echoCre
8d60: 61 74 65 2c 0a 20 20 65 63 68 6f 43 6f 6e 6e 65  ate,.  echoConne
8d70: 63 74 2c 0a 20 20 65 63 68 6f 42 65 73 74 49 6e  ct,.  echoBestIn
8d80: 64 65 78 2c 0a 20 20 65 63 68 6f 44 69 73 63 6f  dex,.  echoDisco
8d90: 6e 6e 65 63 74 2c 20 0a 20 20 65 63 68 6f 44 65  nnect, .  echoDe
8da0: 73 74 72 6f 79 2c 0a 20 20 65 63 68 6f 4f 70 65  stroy,.  echoOpe
8db0: 6e 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  n,              
8dc0: 20 20 20 20 2f 2a 20 78 4f 70 65 6e 20 2d 20 6f      /* xOpen - o
8dd0: 70 65 6e 20 61 20 63 75 72 73 6f 72 20 2a 2f 0a  pen a cursor */.
8de0: 20 20 65 63 68 6f 43 6c 6f 73 65 2c 20 20 20 20    echoClose,    
8df0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
8e00: 78 43 6c 6f 73 65 20 2d 20 63 6c 6f 73 65 20 61  xClose - close a
8e10: 20 63 75 72 73 6f 72 20 2a 2f 0a 20 20 65 63 68   cursor */.  ech
8e20: 6f 46 69 6c 74 65 72 2c 20 20 20 20 20 20 20 20  oFilter,        
8e30: 20 20 20 20 20 20 20 20 2f 2a 20 78 46 69 6c 74          /* xFilt
8e40: 65 72 20 2d 20 63 6f 6e 66 69 67 75 72 65 20 73  er - configure s
8e50: 63 61 6e 20 63 6f 6e 73 74 72 61 69 6e 74 73 20  can constraints 
8e60: 2a 2f 0a 20 20 65 63 68 6f 4e 65 78 74 2c 20 20  */.  echoNext,  
8e70: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8e80: 2f 2a 20 78 4e 65 78 74 20 2d 20 61 64 76 61 6e  /* xNext - advan
8e90: 63 65 20 61 20 63 75 72 73 6f 72 20 2a 2f 0a 20  ce a cursor */. 
8ea0: 20 65 63 68 6f 45 6f 66 2c 20 20 20 20 20 20 20   echoEof,       
8eb0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78              /* x
8ec0: 45 6f 66 20 2a 2f 0a 20 20 65 63 68 6f 43 6f 6c  Eof */.  echoCol
8ed0: 75 6d 6e 2c 20 20 20 20 20 20 20 20 20 20 20 20  umn,            
8ee0: 20 20 20 20 2f 2a 20 78 43 6f 6c 75 6d 6e 20 2d      /* xColumn -
8ef0: 20 72 65 61 64 20 64 61 74 61 20 2a 2f 0a 20 20   read data */.  
8f00: 65 63 68 6f 52 6f 77 69 64 2c 20 20 20 20 20 20  echoRowid,      
8f10: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 52             /* xR
8f20: 6f 77 69 64 20 2d 20 72 65 61 64 20 64 61 74 61  owid - read data
8f30: 20 2a 2f 0a 20 20 65 63 68 6f 55 70 64 61 74 65   */.  echoUpdate
8f40: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
8f50: 20 2f 2a 20 78 55 70 64 61 74 65 20 2d 20 77 72   /* xUpdate - wr
8f60: 69 74 65 20 64 61 74 61 20 2a 2f 0a 20 20 65 63  ite data */.  ec
8f70: 68 6f 42 65 67 69 6e 2c 20 20 20 20 20 20 20 20  hoBegin,        
8f80: 20 20 20 20 20 20 20 20 20 2f 2a 20 78 42 65 67           /* xBeg
8f90: 69 6e 20 2d 20 62 65 67 69 6e 20 74 72 61 6e 73  in - begin trans
8fa0: 61 63 74 69 6f 6e 20 2a 2f 0a 20 20 65 63 68 6f  action */.  echo
8fb0: 53 79 6e 63 2c 20 20 20 20 20 20 20 20 20 20 20  Sync,           
8fc0: 20 20 20 20 20 20 20 2f 2a 20 78 53 79 6e 63 20         /* xSync 
8fd0: 2d 20 73 79 6e 63 20 74 72 61 6e 73 61 63 74 69  - sync transacti
8fe0: 6f 6e 20 2a 2f 0a 20 20 65 63 68 6f 43 6f 6d 6d  on */.  echoComm
8ff0: 69 74 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  it,             
9000: 20 20 20 2f 2a 20 78 43 6f 6d 6d 69 74 20 2d 20     /* xCommit - 
9010: 63 6f 6d 6d 69 74 20 74 72 61 6e 73 61 63 74 69  commit transacti
9020: 6f 6e 20 2a 2f 0a 20 20 65 63 68 6f 52 6f 6c 6c  on */.  echoRoll
9030: 62 61 63 6b 2c 20 20 20 20 20 20 20 20 20 20 20  back,           
9040: 20 20 20 2f 2a 20 78 52 6f 6c 6c 62 61 63 6b 20     /* xRollback 
9050: 2d 20 72 6f 6c 6c 62 61 63 6b 20 74 72 61 6e 73  - rollback trans
9060: 61 63 74 69 6f 6e 20 2a 2f 0a 20 20 65 63 68 6f  action */.  echo
9070: 46 69 6e 64 46 75 6e 63 74 69 6f 6e 2c 20 20 20  FindFunction,   
9080: 20 20 20 20 20 20 20 2f 2a 20 78 46 69 6e 64 46         /* xFindF
9090: 75 6e 63 74 69 6f 6e 20 2d 20 66 75 6e 63 74 69  unction - functi
90a0: 6f 6e 20 6f 76 65 72 6c 6f 61 64 69 6e 67 20 2a  on overloading *
90b0: 2f 0a 20 20 65 63 68 6f 52 65 6e 61 6d 65 2c 20  /.  echoRename, 
90c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
90d0: 2a 20 78 52 65 6e 61 6d 65 20 2d 20 72 65 6e 61  * xRename - rena
90e0: 6d 65 20 74 68 65 20 74 61 62 6c 65 20 2a 2f 0a  me the table */.
90f0: 20 20 65 63 68 6f 53 61 76 65 70 6f 69 6e 74 2c    echoSavepoint,
9100: 0a 20 20 65 63 68 6f 52 65 6c 65 61 73 65 2c 0a  .  echoRelease,.
9110: 20 20 65 63 68 6f 52 6f 6c 6c 62 61 63 6b 54 6f    echoRollbackTo
9120: 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 44 65 63 6f 64  .};../*.** Decod
9130: 65 20 61 20 70 6f 69 6e 74 65 72 20 74 6f 20 61  e a pointer to a
9140: 6e 20 73 71 6c 69 74 65 33 20 6f 62 6a 65 63 74  n sqlite3 object
9150: 2e 0a 2a 2f 0a 65 78 74 65 72 6e 20 69 6e 74 20  ..*/.extern int 
9160: 67 65 74 44 62 50 6f 69 6e 74 65 72 28 54 63 6c  getDbPointer(Tcl
9170: 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 2c  _Interp *interp,
9180: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 41 2c   const char *zA,
9190: 20 73 71 6c 69 74 65 33 20 2a 2a 70 70 44 62 29   sqlite3 **ppDb)
91a0: 3b 0a 65 78 74 65 72 6e 20 63 6f 6e 73 74 20 63  ;.extern const c
91b0: 68 61 72 20 2a 73 71 6c 69 74 65 33 45 72 72 4e  har *sqlite3ErrN
91c0: 61 6d 65 28 69 6e 74 29 3b 0a 0a 73 74 61 74 69  ame(int);..stati
91d0: 63 20 76 6f 69 64 20 6d 6f 64 75 6c 65 44 65 73  c void moduleDes
91e0: 74 72 6f 79 28 76 6f 69 64 20 2a 70 29 7b 0a 20  troy(void *p){. 
91f0: 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70 29   sqlite3_free(p)
9200: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 67 69 73  ;.}../*.** Regis
9210: 74 65 72 20 74 68 65 20 65 63 68 6f 20 76 69 72  ter the echo vir
9220: 74 75 61 6c 20 74 61 62 6c 65 20 6d 6f 64 75 6c  tual table modul
9230: 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  e..*/.static int
9240: 20 72 65 67 69 73 74 65 72 5f 65 63 68 6f 5f 6d   register_echo_m
9250: 6f 64 75 6c 65 28 0a 20 20 43 6c 69 65 6e 74 44  odule(.  ClientD
9260: 61 74 61 20 63 6c 69 65 6e 74 44 61 74 61 2c 20  ata clientData, 
9270: 2f 2a 20 50 6f 69 6e 74 65 72 20 74 6f 20 73 71  /* Pointer to sq
9280: 6c 69 74 65 33 5f 65 6e 61 62 6c 65 5f 58 58 58  lite3_enable_XXX
9290: 20 66 75 6e 63 74 69 6f 6e 20 2a 2f 0a 20 20 54   function */.  T
92a0: 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72  cl_Interp *inter
92b0: 70 2c 20 20 20 20 2f 2a 20 54 68 65 20 54 43 4c  p,    /* The TCL
92c0: 20 69 6e 74 65 72 70 72 65 74 65 72 20 74 68 61   interpreter tha
92d0: 74 20 69 6e 76 6f 6b 65 64 20 74 68 69 73 20 63  t invoked this c
92e0: 6f 6d 6d 61 6e 64 20 2a 2f 0a 20 20 69 6e 74 20  ommand */.  int 
92f0: 6f 62 6a 63 2c 20 20 20 20 20 20 20 20 20 20 20  objc,           
9300: 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20     /* Number of 
9310: 61 72 67 75 6d 65 6e 74 73 20 2a 2f 0a 20 20 54  arguments */.  T
9320: 63 6c 5f 4f 62 6a 20 2a 43 4f 4e 53 54 20 6f 62  cl_Obj *CONST ob
9330: 6a 76 5b 5d 20 20 2f 2a 20 43 6f 6d 6d 61 6e 64  jv[]  /* Command
9340: 20 61 72 67 75 6d 65 6e 74 73 20 2a 2f 0a 29 7b   arguments */.){
9350: 0a 20 20 69 6e 74 20 72 63 3b 0a 20 20 73 71 6c  .  int rc;.  sql
9360: 69 74 65 33 20 2a 64 62 3b 0a 20 20 45 63 68 6f  ite3 *db;.  Echo
9370: 4d 6f 64 75 6c 65 20 2a 70 4d 6f 64 3b 0a 20 20  Module *pMod;.  
9380: 69 66 28 20 6f 62 6a 63 21 3d 32 20 29 7b 0a 20  if( objc!=2 ){. 
9390: 20 20 20 54 63 6c 5f 57 72 6f 6e 67 4e 75 6d 41     Tcl_WrongNumA
93a0: 72 67 73 28 69 6e 74 65 72 70 2c 20 31 2c 20 6f  rgs(interp, 1, o
93b0: 62 6a 76 2c 20 22 44 42 22 29 3b 0a 20 20 20 20  bjv, "DB");.    
93c0: 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52  return TCL_ERROR
93d0: 3b 0a 20 20 7d 0a 20 20 69 66 28 20 67 65 74 44  ;.  }.  if( getD
93e0: 62 50 6f 69 6e 74 65 72 28 69 6e 74 65 72 70 2c  bPointer(interp,
93f0: 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 28 6f   Tcl_GetString(o
9400: 62 6a 76 5b 31 5d 29 2c 20 26 64 62 29 20 29 20  bjv[1]), &db) ) 
9410: 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52  return TCL_ERROR
9420: 3b 0a 0a 20 20 2f 2a 20 56 69 72 74 75 61 6c 20  ;..  /* Virtual 
9430: 74 61 62 6c 65 20 6d 6f 64 75 6c 65 20 22 65 63  table module "ec
9440: 68 6f 22 20 2a 2f 0a 20 20 70 4d 6f 64 20 3d 20  ho" */.  pMod = 
9450: 73 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63 28 73  sqlite3_malloc(s
9460: 69 7a 65 6f 66 28 45 63 68 6f 4d 6f 64 75 6c 65  izeof(EchoModule
9470: 29 29 3b 0a 20 20 70 4d 6f 64 2d 3e 69 6e 74 65  ));.  pMod->inte
9480: 72 70 20 3d 20 69 6e 74 65 72 70 3b 0a 20 20 72  rp = interp;.  r
9490: 63 20 3d 20 73 71 6c 69 74 65 33 5f 63 72 65 61  c = sqlite3_crea
94a0: 74 65 5f 6d 6f 64 75 6c 65 5f 76 32 28 0a 20 20  te_module_v2(.  
94b0: 20 20 20 20 64 62 2c 20 22 65 63 68 6f 22 2c 20      db, "echo", 
94c0: 26 65 63 68 6f 4d 6f 64 75 6c 65 2c 20 28 76 6f  &echoModule, (vo
94d0: 69 64 2a 29 70 4d 6f 64 2c 20 6d 6f 64 75 6c 65  id*)pMod, module
94e0: 44 65 73 74 72 6f 79 0a 20 20 29 3b 0a 0a 20 20  Destroy.  );..  
94f0: 2f 2a 20 56 69 72 74 75 61 6c 20 74 61 62 6c 65  /* Virtual table
9500: 20 6d 6f 64 75 6c 65 20 22 65 63 68 6f 5f 76 32   module "echo_v2
9510: 22 20 2a 2f 0a 20 20 69 66 28 20 72 63 3d 3d 53  " */.  if( rc==S
9520: 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
9530: 70 4d 6f 64 20 3d 20 73 71 6c 69 74 65 33 5f 6d  pMod = sqlite3_m
9540: 61 6c 6c 6f 63 28 73 69 7a 65 6f 66 28 45 63 68  alloc(sizeof(Ech
9550: 6f 4d 6f 64 75 6c 65 29 29 3b 0a 20 20 20 20 70  oModule));.    p
9560: 4d 6f 64 2d 3e 69 6e 74 65 72 70 20 3d 20 69 6e  Mod->interp = in
9570: 74 65 72 70 3b 0a 20 20 20 20 72 63 20 3d 20 73  terp;.    rc = s
9580: 71 6c 69 74 65 33 5f 63 72 65 61 74 65 5f 6d 6f  qlite3_create_mo
9590: 64 75 6c 65 5f 76 32 28 64 62 2c 20 22 65 63 68  dule_v2(db, "ech
95a0: 6f 5f 76 32 22 2c 20 0a 20 20 20 20 20 20 20 20  o_v2", .        
95b0: 26 65 63 68 6f 4d 6f 64 75 6c 65 56 32 2c 20 28  &echoModuleV2, (
95c0: 76 6f 69 64 2a 29 70 4d 6f 64 2c 20 6d 6f 64 75  void*)pMod, modu
95d0: 6c 65 44 65 73 74 72 6f 79 0a 20 20 20 20 29 3b  leDestroy.    );
95e0: 0a 20 20 7d 0a 0a 20 20 54 63 6c 5f 53 65 74 52  .  }..  Tcl_SetR
95f0: 65 73 75 6c 74 28 69 6e 74 65 72 70 2c 20 28 63  esult(interp, (c
9600: 68 61 72 20 2a 29 73 71 6c 69 74 65 33 45 72 72  har *)sqlite3Err
9610: 4e 61 6d 65 28 72 63 29 2c 20 54 43 4c 5f 53 54  Name(rc), TCL_ST
9620: 41 54 49 43 29 3b 0a 20 20 72 65 74 75 72 6e 20  ATIC);.  return 
9630: 54 43 4c 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  TCL_OK;.}../*.**
9640: 20 54 63 6c 20 69 6e 74 65 72 66 61 63 65 20 74   Tcl interface t
9650: 6f 20 73 71 6c 69 74 65 33 5f 64 65 63 6c 61 72  o sqlite3_declar
9660: 65 5f 76 74 61 62 2c 20 69 6e 76 6f 6b 65 64 20  e_vtab, invoked 
9670: 61 73 20 66 6f 6c 6c 6f 77 73 20 66 72 6f 6d 20  as follows from 
9680: 54 63 6c 3a 0a 2a 2a 0a 2a 2a 20 73 71 6c 69 74  Tcl:.**.** sqlit
9690: 65 33 5f 64 65 63 6c 61 72 65 5f 76 74 61 62 20  e3_declare_vtab 
96a0: 44 42 20 53 51 4c 0a 2a 2f 0a 73 74 61 74 69 63  DB SQL.*/.static
96b0: 20 69 6e 74 20 64 65 63 6c 61 72 65 5f 76 74 61   int declare_vta
96c0: 62 28 0a 20 20 43 6c 69 65 6e 74 44 61 74 61 20  b(.  ClientData 
96d0: 63 6c 69 65 6e 74 44 61 74 61 2c 20 2f 2a 20 50  clientData, /* P
96e0: 6f 69 6e 74 65 72 20 74 6f 20 73 71 6c 69 74 65  ointer to sqlite
96f0: 33 5f 65 6e 61 62 6c 65 5f 58 58 58 20 66 75 6e  3_enable_XXX fun
9700: 63 74 69 6f 6e 20 2a 2f 0a 20 20 54 63 6c 5f 49  ction */.  Tcl_I
9710: 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 2c 20 20  nterp *interp,  
9720: 20 20 2f 2a 20 54 68 65 20 54 43 4c 20 69 6e 74    /* The TCL int
9730: 65 72 70 72 65 74 65 72 20 74 68 61 74 20 69 6e  erpreter that in
9740: 76 6f 6b 65 64 20 74 68 69 73 20 63 6f 6d 6d 61  voked this comma
9750: 6e 64 20 2a 2f 0a 20 20 69 6e 74 20 6f 62 6a 63  nd */.  int objc
9760: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f  ,              /
9770: 2a 20 4e 75 6d 62 65 72 20 6f 66 20 61 72 67 75  * Number of argu
9780: 6d 65 6e 74 73 20 2a 2f 0a 20 20 54 63 6c 5f 4f  ments */.  Tcl_O
9790: 62 6a 20 2a 43 4f 4e 53 54 20 6f 62 6a 76 5b 5d  bj *CONST objv[]
97a0: 20 20 2f 2a 20 43 6f 6d 6d 61 6e 64 20 61 72 67    /* Command arg
97b0: 75 6d 65 6e 74 73 20 2a 2f 0a 29 7b 0a 20 20 73  uments */.){.  s
97c0: 71 6c 69 74 65 33 20 2a 64 62 3b 0a 20 20 69 6e  qlite3 *db;.  in
97d0: 74 20 72 63 3b 0a 20 20 69 66 28 20 6f 62 6a 63  t rc;.  if( objc
97e0: 21 3d 33 20 29 7b 0a 20 20 20 20 54 63 6c 5f 57  !=3 ){.    Tcl_W
97f0: 72 6f 6e 67 4e 75 6d 41 72 67 73 28 69 6e 74 65  rongNumArgs(inte
9800: 72 70 2c 20 31 2c 20 6f 62 6a 76 2c 20 22 44 42  rp, 1, objv, "DB
9810: 20 53 51 4c 22 29 3b 0a 20 20 20 20 72 65 74 75   SQL");.    retu
9820: 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20  rn TCL_ERROR;.  
9830: 7d 0a 20 20 69 66 28 20 67 65 74 44 62 50 6f 69  }.  if( getDbPoi
9840: 6e 74 65 72 28 69 6e 74 65 72 70 2c 20 54 63 6c  nter(interp, Tcl
9850: 5f 47 65 74 53 74 72 69 6e 67 28 6f 62 6a 76 5b  _GetString(objv[
9860: 31 5d 29 2c 20 26 64 62 29 20 29 20 72 65 74 75  1]), &db) ) retu
9870: 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20  rn TCL_ERROR;.  
9880: 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 64 65 63  rc = sqlite3_dec
9890: 6c 61 72 65 5f 76 74 61 62 28 64 62 2c 20 54 63  lare_vtab(db, Tc
98a0: 6c 5f 47 65 74 53 74 72 69 6e 67 28 6f 62 6a 76  l_GetString(objv
98b0: 5b 32 5d 29 29 3b 0a 20 20 69 66 28 20 72 63 21  [2]));.  if( rc!
98c0: 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20  =SQLITE_OK ){.  
98d0: 20 20 54 63 6c 5f 53 65 74 52 65 73 75 6c 74 28    Tcl_SetResult(
98e0: 69 6e 74 65 72 70 2c 20 28 63 68 61 72 20 2a 29  interp, (char *)
98f0: 73 71 6c 69 74 65 33 5f 65 72 72 6d 73 67 28 64  sqlite3_errmsg(d
9900: 62 29 2c 20 54 43 4c 5f 56 4f 4c 41 54 49 4c 45  b), TCL_VOLATILE
9910: 29 3b 0a 20 20 20 20 72 65 74 75 72 6e 20 54 43  );.    return TC
9920: 4c 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a 20 20 72  L_ERROR;.  }.  r
9930: 65 74 75 72 6e 20 54 43 4c 5f 4f 4b 3b 0a 7d 0a  eturn TCL_OK;.}.
9940: 0a 23 65 6e 64 69 66 20 2f 2a 20 69 66 6e 64 65  .#endif /* ifnde
9950: 66 20 53 51 4c 49 54 45 5f 4f 4d 49 54 5f 56 49  f SQLITE_OMIT_VI
9960: 52 54 55 41 4c 54 41 42 4c 45 20 2a 2f 0a 0a 2f  RTUALTABLE */../
9970: 2a 0a 2a 2a 20 52 65 67 69 73 74 65 72 20 63 6f  *.** Register co
9980: 6d 6d 61 6e 64 73 20 77 69 74 68 20 74 68 65 20  mmands with the 
9990: 54 43 4c 20 69 6e 74 65 72 70 72 65 74 65 72 2e  TCL interpreter.
99a0: 0a 2a 2f 0a 69 6e 74 20 53 71 6c 69 74 65 74 65  .*/.int Sqlitete
99b0: 73 74 38 5f 49 6e 69 74 28 54 63 6c 5f 49 6e 74  st8_Init(Tcl_Int
99c0: 65 72 70 20 2a 69 6e 74 65 72 70 29 7b 0a 23 69  erp *interp){.#i
99d0: 66 6e 64 65 66 20 53 51 4c 49 54 45 5f 4f 4d 49  fndef SQLITE_OMI
99e0: 54 5f 56 49 52 54 55 41 4c 54 41 42 4c 45 0a 20  T_VIRTUALTABLE. 
99f0: 20 73 74 61 74 69 63 20 73 74 72 75 63 74 20 7b   static struct {
9a00: 0a 20 20 20 20 20 63 68 61 72 20 2a 7a 4e 61 6d  .     char *zNam
9a10: 65 3b 0a 20 20 20 20 20 54 63 6c 5f 4f 62 6a 43  e;.     Tcl_ObjC
9a20: 6d 64 50 72 6f 63 20 2a 78 50 72 6f 63 3b 0a 20  mdProc *xProc;. 
9a30: 20 20 20 20 76 6f 69 64 20 2a 63 6c 69 65 6e 74      void *client
9a40: 44 61 74 61 3b 0a 20 20 7d 20 61 4f 62 6a 43 6d  Data;.  } aObjCm
9a50: 64 5b 5d 20 3d 20 7b 0a 20 20 20 20 20 7b 20 22  d[] = {.     { "
9a60: 72 65 67 69 73 74 65 72 5f 65 63 68 6f 5f 6d 6f  register_echo_mo
9a70: 64 75 6c 65 22 2c 20 20 20 20 20 20 20 72 65 67  dule",       reg
9a80: 69 73 74 65 72 5f 65 63 68 6f 5f 6d 6f 64 75 6c  ister_echo_modul
9a90: 65 2c 20 30 20 7d 2c 0a 20 20 20 20 20 7b 20 22  e, 0 },.     { "
9aa0: 73 71 6c 69 74 65 33 5f 64 65 63 6c 61 72 65 5f  sqlite3_declare_
9ab0: 76 74 61 62 22 2c 20 20 20 20 20 20 20 64 65 63  vtab",       dec
9ac0: 6c 61 72 65 5f 76 74 61 62 2c 20 30 20 7d 2c 0a  lare_vtab, 0 },.
9ad0: 20 20 7d 3b 0a 20 20 69 6e 74 20 69 3b 0a 20 20    };.  int i;.  
9ae0: 66 6f 72 28 69 3d 30 3b 20 69 3c 73 69 7a 65 6f  for(i=0; i<sizeo
9af0: 66 28 61 4f 62 6a 43 6d 64 29 2f 73 69 7a 65 6f  f(aObjCmd)/sizeo
9b00: 66 28 61 4f 62 6a 43 6d 64 5b 30 5d 29 3b 20 69  f(aObjCmd[0]); i
9b10: 2b 2b 29 7b 0a 20 20 20 20 54 63 6c 5f 43 72 65  ++){.    Tcl_Cre
9b20: 61 74 65 4f 62 6a 43 6f 6d 6d 61 6e 64 28 69 6e  ateObjCommand(in
9b30: 74 65 72 70 2c 20 61 4f 62 6a 43 6d 64 5b 69 5d  terp, aObjCmd[i]
9b40: 2e 7a 4e 61 6d 65 2c 20 0a 20 20 20 20 20 20 20  .zName, .       
9b50: 20 61 4f 62 6a 43 6d 64 5b 69 5d 2e 78 50 72 6f   aObjCmd[i].xPro
9b60: 63 2c 20 61 4f 62 6a 43 6d 64 5b 69 5d 2e 63 6c  c, aObjCmd[i].cl
9b70: 69 65 6e 74 44 61 74 61 2c 20 30 29 3b 0a 20 20  ientData, 0);.  
9b80: 7d 0a 23 65 6e 64 69 66 0a 20 20 72 65 74 75 72  }.#endif.  retur
9b90: 6e 20 54 43 4c 5f 4f 4b 3b 0a 7d 0a              n TCL_OK;.}.