/ Hex Artifact Content
Login

Artifact 5ecbffe6712da81d5d10454e9d77d6c5bac95fe8:


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 7a 53 71  mt2 = 0;.    zSq
1ea0: 6c 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72 69  l = sqlite3_mpri
1eb0: 6e 74 66 28 22 50 52 41 47 4d 41 20 69 6e 64 65  ntf("PRAGMA inde
1ec0: 78 5f 69 6e 66 6f 28 25 73 29 22 2c 20 7a 49 64  x_info(%s)", zId
1ed0: 78 29 3b 0a 20 20 20 20 69 66 28 20 21 7a 53 71  x);.    if( !zSq
1ee0: 6c 20 29 7b 0a 20 20 20 20 20 20 72 63 20 3d 20  l ){.      rc = 
1ef0: 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20  SQLITE_NOMEM;.  
1f00: 20 20 20 20 67 6f 74 6f 20 67 65 74 5f 69 6e 64      goto get_ind
1f10: 65 78 5f 61 72 72 61 79 5f 6f 75 74 3b 0a 20 20  ex_array_out;.  
1f20: 20 20 7d 0a 20 20 20 20 72 63 20 3d 20 73 71 6c    }.    rc = sql
1f30: 69 74 65 33 5f 70 72 65 70 61 72 65 28 64 62 2c  ite3_prepare(db,
1f40: 20 7a 53 71 6c 2c 20 2d 31 2c 20 26 70 53 74 6d   zSql, -1, &pStm
1f50: 74 32 2c 20 30 29 3b 0a 20 20 20 20 73 71 6c 69  t2, 0);.    sqli
1f60: 74 65 33 5f 66 72 65 65 28 7a 53 71 6c 29 3b 0a  te3_free(zSql);.
1f70: 20 20 20 20 69 66 28 20 70 53 74 6d 74 32 20 26      if( pStmt2 &
1f80: 26 20 73 71 6c 69 74 65 33 5f 73 74 65 70 28 70  & sqlite3_step(p
1f90: 53 74 6d 74 32 29 3d 3d 53 51 4c 49 54 45 5f 52  Stmt2)==SQLITE_R
1fa0: 4f 57 20 29 7b 0a 20 20 20 20 20 20 69 6e 74 20  OW ){.      int 
1fb0: 63 69 64 20 3d 20 73 71 6c 69 74 65 33 5f 63 6f  cid = sqlite3_co
1fc0: 6c 75 6d 6e 5f 69 6e 74 28 70 53 74 6d 74 32 2c  lumn_int(pStmt2,
1fd0: 20 31 29 3b 0a 20 20 20 20 20 20 61 73 73 65 72   1);.      asser
1fe0: 74 28 20 63 69 64 3e 3d 30 20 26 26 20 63 69 64  t( cid>=0 && cid
1ff0: 3c 6e 43 6f 6c 20 29 3b 0a 20 20 20 20 20 20 61  <nCol );.      a
2000: 49 6e 64 65 78 5b 63 69 64 5d 20 3d 20 31 3b 0a  Index[cid] = 1;.
2010: 20 20 20 20 7d 0a 20 20 20 20 69 66 28 20 70 53      }.    if( pS
2020: 74 6d 74 32 20 29 7b 0a 20 20 20 20 20 20 72 63  tmt2 ){.      rc
2030: 20 3d 20 73 71 6c 69 74 65 33 5f 66 69 6e 61 6c   = sqlite3_final
2040: 69 7a 65 28 70 53 74 6d 74 32 29 3b 0a 20 20 20  ize(pStmt2);.   
2050: 20 7d 0a 20 20 20 20 69 66 28 20 72 63 21 3d 53   }.    if( rc!=S
2060: 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
2070: 20 20 67 6f 74 6f 20 67 65 74 5f 69 6e 64 65 78    goto get_index
2080: 5f 61 72 72 61 79 5f 6f 75 74 3b 0a 20 20 20 20  _array_out;.    
2090: 7d 0a 20 20 7d 0a 0a 0a 67 65 74 5f 69 6e 64 65  }.  }...get_inde
20a0: 78 5f 61 72 72 61 79 5f 6f 75 74 3a 0a 20 20 69  x_array_out:.  i
20b0: 66 28 20 70 53 74 6d 74 20 29 7b 0a 20 20 20 20  f( pStmt ){.    
20c0: 69 6e 74 20 72 63 32 20 3d 20 73 71 6c 69 74 65  int rc2 = sqlite
20d0: 33 5f 66 69 6e 61 6c 69 7a 65 28 70 53 74 6d 74  3_finalize(pStmt
20e0: 29 3b 0a 20 20 20 20 69 66 28 20 72 63 3d 3d 53  );.    if( rc==S
20f0: 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
2100: 20 20 72 63 20 3d 20 72 63 32 3b 0a 20 20 20 20    rc = rc2;.    
2110: 7d 0a 20 20 7d 0a 20 20 69 66 28 20 72 63 21 3d  }.  }.  if( rc!=
2120: 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20  SQLITE_OK ){.   
2130: 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 61 49   sqlite3_free(aI
2140: 6e 64 65 78 29 3b 0a 20 20 20 20 61 49 6e 64 65  ndex);.    aInde
2150: 78 20 3d 20 30 3b 0a 20 20 7d 0a 20 20 2a 70 61  x = 0;.  }.  *pa
2160: 49 6e 64 65 78 20 3d 20 61 49 6e 64 65 78 3b 0a  Index = aIndex;.
2170: 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a    return rc;.}..
2180: 2f 2a 0a 2a 2a 20 47 6c 6f 62 61 6c 20 54 63 6c  /*.** Global Tcl
2190: 20 76 61 72 69 61 62 6c 65 20 24 65 63 68 6f 5f   variable $echo_
21a0: 6d 6f 64 75 6c 65 20 69 73 20 61 20 6c 69 73 74  module is a list
21b0: 2e 20 54 68 69 73 20 72 6f 75 74 69 6e 65 20 61  . This routine a
21c0: 70 70 65 6e 64 73 0a 2a 2a 20 74 68 65 20 73 74  ppends.** the st
21d0: 72 69 6e 67 20 65 6c 65 6d 65 6e 74 20 7a 41 72  ring element zAr
21e0: 67 20 74 6f 20 74 68 61 74 20 6c 69 73 74 20 69  g to that list i
21f0: 6e 20 69 6e 74 65 72 70 72 65 74 65 72 20 69 6e  n interpreter in
2200: 74 65 72 70 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  terp..*/.static 
2210: 76 6f 69 64 20 61 70 70 65 6e 64 54 6f 45 63 68  void appendToEch
2220: 6f 4d 6f 64 75 6c 65 28 54 63 6c 5f 49 6e 74 65  oModule(Tcl_Inte
2230: 72 70 20 2a 69 6e 74 65 72 70 2c 20 63 6f 6e 73  rp *interp, cons
2240: 74 20 63 68 61 72 20 2a 7a 41 72 67 29 7b 0a 20  t char *zArg){. 
2250: 20 69 6e 74 20 66 6c 61 67 73 20 3d 20 28 54 43   int flags = (TC
2260: 4c 5f 41 50 50 45 4e 44 5f 56 41 4c 55 45 20 7c  L_APPEND_VALUE |
2270: 20 54 43 4c 5f 4c 49 53 54 5f 45 4c 45 4d 45 4e   TCL_LIST_ELEMEN
2280: 54 20 7c 20 54 43 4c 5f 47 4c 4f 42 41 4c 5f 4f  T | TCL_GLOBAL_O
2290: 4e 4c 59 29 3b 0a 20 20 54 63 6c 5f 53 65 74 56  NLY);.  Tcl_SetV
22a0: 61 72 28 69 6e 74 65 72 70 2c 20 22 65 63 68 6f  ar(interp, "echo
22b0: 5f 6d 6f 64 75 6c 65 22 2c 20 28 7a 41 72 67 3f  _module", (zArg?
22c0: 7a 41 72 67 3a 22 22 29 2c 20 66 6c 61 67 73 29  zArg:""), flags)
22d0: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20  ;.}../*.** This 
22e0: 66 75 6e 63 74 69 6f 6e 20 69 73 20 63 61 6c 6c  function is call
22f0: 65 64 20 66 72 6f 6d 20 77 69 74 68 69 6e 20 74  ed from within t
2300: 68 65 20 65 63 68 6f 2d 6d 6f 64 75 6c 65 73 20  he echo-modules 
2310: 78 43 72 65 61 74 65 20 61 6e 64 0a 2a 2a 20 78  xCreate and.** x
2320: 43 6f 6e 6e 65 63 74 20 6d 65 74 68 6f 64 73 2e  Connect methods.
2330: 20 54 68 65 20 61 72 67 63 20 61 6e 64 20 61 72   The argc and ar
2340: 67 76 20 61 72 67 75 6d 65 6e 74 73 20 61 72 65  gv arguments are
2350: 20 63 6f 70 69 65 73 20 6f 66 20 74 68 6f 73 65   copies of those
2360: 20 0a 2a 2a 20 70 61 73 73 65 64 20 74 6f 20 74   .** passed to t
2370: 68 65 20 63 61 6c 6c 69 6e 67 20 6d 65 74 68 6f  he calling metho
2380: 64 2e 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e  d. This function
2390: 20 69 73 20 72 65 73 70 6f 6e 73 69 62 6c 65 20   is responsible 
23a0: 66 6f 72 0a 2a 2a 20 63 61 6c 6c 69 6e 67 20 73  for.** calling s
23b0: 71 6c 69 74 65 33 5f 64 65 63 6c 61 72 65 5f 76  qlite3_declare_v
23c0: 74 61 62 28 29 20 74 6f 20 64 65 63 6c 61 72 65  tab() to declare
23d0: 20 74 68 65 20 73 63 68 65 6d 61 20 6f 66 20 74   the schema of t
23e0: 68 65 20 76 69 72 74 75 61 6c 0a 2a 2a 20 74 61  he virtual.** ta
23f0: 62 6c 65 20 62 65 69 6e 67 20 63 72 65 61 74 65  ble being create
2400: 64 20 6f 72 20 63 6f 6e 6e 65 63 74 65 64 2e 0a  d or connected..
2410: 2a 2a 0a 2a 2a 20 49 66 20 74 68 65 20 63 6f 6e  **.** If the con
2420: 73 74 72 75 63 74 6f 72 20 77 61 73 20 70 61 73  structor was pas
2430: 73 65 64 20 6a 75 73 74 20 6f 6e 65 20 61 72 67  sed just one arg
2440: 75 6d 65 6e 74 2c 20 69 2e 65 2e 3a 0a 2a 2a 0a  ument, i.e.:.**.
2450: 2a 2a 20 20 20 43 52 45 41 54 45 20 54 41 42 4c  **   CREATE TABL
2460: 45 20 74 31 20 41 53 20 65 63 68 6f 28 74 32 29  E t1 AS echo(t2)
2470: 3b 0a 2a 2a 0a 2a 2a 20 54 68 65 6e 20 74 32 20  ;.**.** Then t2 
2480: 69 73 20 61 73 73 75 6d 65 64 20 74 6f 20 62 65  is assumed to be
2490: 20 74 68 65 20 6e 61 6d 65 20 6f 66 20 61 20 2a   the name of a *
24a0: 72 65 61 6c 2a 20 64 61 74 61 62 61 73 65 20 74  real* database t
24b0: 61 62 6c 65 2e 20 54 68 65 0a 2a 2a 20 73 63 68  able. The.** sch
24c0: 65 6d 61 20 6f 66 20 74 68 65 20 76 69 72 74 75  ema of the virtu
24d0: 61 6c 20 74 61 62 6c 65 20 69 73 20 64 65 63 6c  al table is decl
24e0: 61 72 65 64 20 62 79 20 70 61 73 73 69 6e 67 20  ared by passing 
24f0: 61 20 63 6f 70 79 20 6f 66 20 74 68 65 20 0a 2a  a copy of the .*
2500: 2a 20 43 52 45 41 54 45 20 54 41 42 4c 45 20 73  * CREATE TABLE s
2510: 74 61 74 65 6d 65 6e 74 20 66 6f 72 20 74 68 65  tatement for the
2520: 20 72 65 61 6c 20 74 61 62 6c 65 20 74 6f 20 73   real table to s
2530: 71 6c 69 74 65 33 5f 64 65 63 6c 61 72 65 5f 76  qlite3_declare_v
2540: 74 61 62 28 29 2e 0a 2a 2a 20 48 65 6e 63 65 2c  tab()..** Hence,
2550: 20 74 68 65 20 76 69 72 74 75 61 6c 20 74 61 62   the virtual tab
2560: 6c 65 20 73 68 6f 75 6c 64 20 68 61 76 65 20 65  le should have e
2570: 78 61 63 74 6c 79 20 74 68 65 20 73 61 6d 65 20  xactly the same 
2580: 63 6f 6c 75 6d 6e 20 6e 61 6d 65 73 20 61 6e 64  column names and
2590: 20 0a 2a 2a 20 74 79 70 65 73 20 61 73 20 74 68   .** types as th
25a0: 65 20 72 65 61 6c 20 74 61 62 6c 65 2e 0a 2a 2f  e real table..*/
25b0: 0a 73 74 61 74 69 63 20 69 6e 74 20 65 63 68 6f  .static int echo
25c0: 44 65 63 6c 61 72 65 56 74 61 62 28 0a 20 20 65  DeclareVtab(.  e
25d0: 63 68 6f 5f 76 74 61 62 20 2a 70 56 74 61 62 2c  cho_vtab *pVtab,
25e0: 20 0a 20 20 73 71 6c 69 74 65 33 20 2a 64 62 20   .  sqlite3 *db 
25f0: 0a 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53  .){.  int rc = S
2600: 51 4c 49 54 45 5f 4f 4b 3b 0a 0a 20 20 69 66 28  QLITE_OK;..  if(
2610: 20 70 56 74 61 62 2d 3e 7a 54 61 62 6c 65 4e 61   pVtab->zTableNa
2620: 6d 65 20 29 7b 0a 20 20 20 20 73 71 6c 69 74 65  me ){.    sqlite
2630: 33 5f 73 74 6d 74 20 2a 70 53 74 6d 74 20 3d 20  3_stmt *pStmt = 
2640: 30 3b 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69  0;.    rc = sqli
2650: 74 65 33 5f 70 72 65 70 61 72 65 28 64 62 2c 20  te3_prepare(db, 
2660: 0a 20 20 20 20 20 20 20 20 22 53 45 4c 45 43 54  .        "SELECT
2670: 20 73 71 6c 20 46 52 4f 4d 20 73 71 6c 69 74 65   sql FROM sqlite
2680: 5f 6d 61 73 74 65 72 20 57 48 45 52 45 20 74 79  _master WHERE ty
2690: 70 65 20 3d 20 27 74 61 62 6c 65 27 20 41 4e 44  pe = 'table' AND
26a0: 20 6e 61 6d 65 20 3d 20 3f 22 2c 0a 20 20 20 20   name = ?",.    
26b0: 20 20 20 20 2d 31 2c 20 26 70 53 74 6d 74 2c 20      -1, &pStmt, 
26c0: 30 29 3b 0a 20 20 20 20 69 66 28 20 72 63 3d 3d  0);.    if( rc==
26d0: 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20  SQLITE_OK ){.   
26e0: 20 20 20 73 71 6c 69 74 65 33 5f 62 69 6e 64 5f     sqlite3_bind_
26f0: 74 65 78 74 28 70 53 74 6d 74 2c 20 31 2c 20 70  text(pStmt, 1, p
2700: 56 74 61 62 2d 3e 7a 54 61 62 6c 65 4e 61 6d 65  Vtab->zTableName
2710: 2c 20 2d 31 2c 20 30 29 3b 0a 20 20 20 20 20 20  , -1, 0);.      
2720: 69 66 28 20 73 71 6c 69 74 65 33 5f 73 74 65 70  if( sqlite3_step
2730: 28 70 53 74 6d 74 29 3d 3d 53 51 4c 49 54 45 5f  (pStmt)==SQLITE_
2740: 52 4f 57 20 29 7b 0a 20 20 20 20 20 20 20 20 69  ROW ){.        i
2750: 6e 74 20 72 63 32 3b 0a 20 20 20 20 20 20 20 20  nt rc2;.        
2760: 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 43 72 65  const char *zCre
2770: 61 74 65 54 61 62 6c 65 20 3d 20 28 63 6f 6e 73  ateTable = (cons
2780: 74 20 63 68 61 72 20 2a 29 73 71 6c 69 74 65 33  t char *)sqlite3
2790: 5f 63 6f 6c 75 6d 6e 5f 74 65 78 74 28 70 53 74  _column_text(pSt
27a0: 6d 74 2c 20 30 29 3b 0a 20 20 20 20 20 20 20 20  mt, 0);.        
27b0: 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 64 65 63  rc = sqlite3_dec
27c0: 6c 61 72 65 5f 76 74 61 62 28 64 62 2c 20 7a 43  lare_vtab(db, zC
27d0: 72 65 61 74 65 54 61 62 6c 65 29 3b 0a 20 20 20  reateTable);.   
27e0: 20 20 20 20 20 72 63 32 20 3d 20 73 71 6c 69 74       rc2 = sqlit
27f0: 65 33 5f 66 69 6e 61 6c 69 7a 65 28 70 53 74 6d  e3_finalize(pStm
2800: 74 29 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20  t);.        if( 
2810: 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc==SQLITE_OK ){
2820: 0a 20 20 20 20 20 20 20 20 20 20 72 63 20 3d 20  .          rc = 
2830: 72 63 32 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20  rc2;.        }. 
2840: 20 20 20 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20       } else {.  
2850: 20 20 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74        rc = sqlit
2860: 65 33 5f 66 69 6e 61 6c 69 7a 65 28 70 53 74 6d  e3_finalize(pStm
2870: 74 29 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20  t);.        if( 
2880: 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc==SQLITE_OK ){
2890: 20 0a 20 20 20 20 20 20 20 20 20 20 72 63 20 3d   .          rc =
28a0: 20 53 51 4c 49 54 45 5f 45 52 52 4f 52 3b 0a 20   SQLITE_ERROR;. 
28b0: 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7d         }.      }
28c0: 0a 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d 53  .      if( rc==S
28d0: 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
28e0: 20 20 20 20 72 63 20 3d 20 67 65 74 43 6f 6c 75      rc = getColu
28f0: 6d 6e 4e 61 6d 65 73 28 64 62 2c 20 70 56 74 61  mnNames(db, pVta
2900: 62 2d 3e 7a 54 61 62 6c 65 4e 61 6d 65 2c 20 26  b->zTableName, &
2910: 70 56 74 61 62 2d 3e 61 43 6f 6c 2c 20 26 70 56  pVtab->aCol, &pV
2920: 74 61 62 2d 3e 6e 43 6f 6c 29 3b 0a 20 20 20 20  tab->nCol);.    
2930: 20 20 7d 0a 20 20 20 20 20 20 69 66 28 20 72 63    }.      if( rc
2940: 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  ==SQLITE_OK ){. 
2950: 20 20 20 20 20 20 20 72 63 20 3d 20 67 65 74 49         rc = getI
2960: 6e 64 65 78 41 72 72 61 79 28 64 62 2c 20 70 56  ndexArray(db, pV
2970: 74 61 62 2d 3e 7a 54 61 62 6c 65 4e 61 6d 65 2c  tab->zTableName,
2980: 20 70 56 74 61 62 2d 3e 6e 43 6f 6c 2c 20 26 70   pVtab->nCol, &p
2990: 56 74 61 62 2d 3e 61 49 6e 64 65 78 29 3b 0a 20  Vtab->aIndex);. 
29a0: 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 7d       }.    }.  }
29b0: 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d  ..  return rc;.}
29c0: 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e  ../*.** This fun
29d0: 63 74 69 6f 6e 20 66 72 65 65 73 20 61 6c 6c 20  ction frees all 
29e0: 72 75 6e 74 69 6d 65 20 73 74 72 75 63 74 75 72  runtime structur
29f0: 65 73 20 61 73 73 6f 63 69 61 74 65 64 20 77 69  es associated wi
2a00: 74 68 20 74 68 65 20 76 69 72 74 75 61 6c 0a 2a  th the virtual.*
2a10: 2a 20 74 61 62 6c 65 20 70 56 74 61 62 2e 0a 2a  * table pVtab..*
2a20: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 65 63 68  /.static int ech
2a30: 6f 44 65 73 74 72 75 63 74 6f 72 28 73 71 6c 69  oDestructor(sqli
2a40: 74 65 33 5f 76 74 61 62 20 2a 70 56 74 61 62 29  te3_vtab *pVtab)
2a50: 7b 0a 20 20 65 63 68 6f 5f 76 74 61 62 20 2a 70  {.  echo_vtab *p
2a60: 20 3d 20 28 65 63 68 6f 5f 76 74 61 62 2a 29 70   = (echo_vtab*)p
2a70: 56 74 61 62 3b 0a 20 20 73 71 6c 69 74 65 33 5f  Vtab;.  sqlite3_
2a80: 66 72 65 65 28 70 2d 3e 61 49 6e 64 65 78 29 3b  free(p->aIndex);
2a90: 0a 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28  .  sqlite3_free(
2aa0: 70 2d 3e 61 43 6f 6c 29 3b 0a 20 20 73 71 6c 69  p->aCol);.  sqli
2ab0: 74 65 33 5f 66 72 65 65 28 70 2d 3e 7a 54 68 69  te3_free(p->zThi
2ac0: 73 29 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66 72  s);.  sqlite3_fr
2ad0: 65 65 28 70 2d 3e 7a 54 61 62 6c 65 4e 61 6d 65  ee(p->zTableName
2ae0: 29 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66 72 65  );.  sqlite3_fre
2af0: 65 28 70 2d 3e 7a 4c 6f 67 4e 61 6d 65 29 3b 0a  e(p->zLogName);.
2b00: 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70    sqlite3_free(p
2b10: 29 3b 0a 20 20 72 65 74 75 72 6e 20 30 3b 0a 7d  );.  return 0;.}
2b20: 0a 0a 74 79 70 65 64 65 66 20 73 74 72 75 63 74  ..typedef struct
2b30: 20 45 63 68 6f 4d 6f 64 75 6c 65 20 45 63 68 6f   EchoModule Echo
2b40: 4d 6f 64 75 6c 65 3b 0a 73 74 72 75 63 74 20 45  Module;.struct E
2b50: 63 68 6f 4d 6f 64 75 6c 65 20 7b 0a 20 20 54 63  choModule {.  Tc
2b60: 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70  l_Interp *interp
2b70: 3b 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73  ;.};../*.** This
2b80: 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 63 61 6c   function is cal
2b90: 6c 65 64 20 74 6f 20 64 6f 20 74 68 65 20 77 6f  led to do the wo
2ba0: 72 6b 20 6f 66 20 74 68 65 20 78 43 6f 6e 6e 65  rk of the xConne
2bb0: 63 74 28 29 20 6d 65 74 68 6f 64 20 2d 0a 2a 2a  ct() method -.**
2bc0: 20 74 6f 20 61 6c 6c 6f 63 61 74 65 20 74 68 65   to allocate the
2bd0: 20 72 65 71 75 69 72 65 64 20 69 6e 2d 6d 65 6d   required in-mem
2be0: 6f 72 79 20 73 74 72 75 63 74 75 72 65 73 20 66  ory structures f
2bf0: 6f 72 20 61 20 6e 65 77 6c 79 20 63 6f 6e 6e 65  or a newly conne
2c00: 63 74 65 64 0a 2a 2a 20 76 69 72 74 75 61 6c 20  cted.** virtual 
2c10: 74 61 62 6c 65 2e 0a 2a 2f 0a 73 74 61 74 69 63  table..*/.static
2c20: 20 69 6e 74 20 65 63 68 6f 43 6f 6e 73 74 72 75   int echoConstru
2c30: 63 74 6f 72 28 0a 20 20 73 71 6c 69 74 65 33 20  ctor(.  sqlite3 
2c40: 2a 64 62 2c 0a 20 20 76 6f 69 64 20 2a 70 41 75  *db,.  void *pAu
2c50: 78 2c 0a 20 20 69 6e 74 20 61 72 67 63 2c 20 63  x,.  int argc, c
2c60: 6f 6e 73 74 20 63 68 61 72 20 2a 63 6f 6e 73 74  onst char *const
2c70: 2a 61 72 67 76 2c 0a 20 20 73 71 6c 69 74 65 33  *argv,.  sqlite3
2c80: 5f 76 74 61 62 20 2a 2a 70 70 56 74 61 62 2c 0a  _vtab **ppVtab,.
2c90: 20 20 63 68 61 72 20 2a 2a 70 7a 45 72 72 0a 29    char **pzErr.)
2ca0: 7b 0a 20 20 69 6e 74 20 72 63 3b 0a 20 20 69 6e  {.  int rc;.  in
2cb0: 74 20 69 3b 0a 20 20 65 63 68 6f 5f 76 74 61 62  t i;.  echo_vtab
2cc0: 20 2a 70 56 74 61 62 3b 0a 0a 20 20 2f 2a 20 41   *pVtab;..  /* A
2cd0: 6c 6c 6f 63 61 74 65 20 74 68 65 20 73 71 6c 69  llocate the sqli
2ce0: 74 65 33 5f 76 74 61 62 2f 65 63 68 6f 5f 76 74  te3_vtab/echo_vt
2cf0: 61 62 20 73 74 72 75 63 74 75 72 65 20 69 74 73  ab structure its
2d00: 65 6c 66 20 2a 2f 0a 20 20 70 56 74 61 62 20 3d  elf */.  pVtab =
2d10: 20 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63 5a 65   sqlite3MallocZe
2d20: 72 6f 28 20 73 69 7a 65 6f 66 28 2a 70 56 74 61  ro( sizeof(*pVta
2d30: 62 29 20 29 3b 0a 20 20 69 66 28 20 21 70 56 74  b) );.  if( !pVt
2d40: 61 62 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e  ab ){.    return
2d50: 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20   SQLITE_NOMEM;. 
2d60: 20 7d 0a 20 20 70 56 74 61 62 2d 3e 69 6e 74 65   }.  pVtab->inte
2d70: 72 70 20 3d 20 28 28 45 63 68 6f 4d 6f 64 75 6c  rp = ((EchoModul
2d80: 65 20 2a 29 70 41 75 78 29 2d 3e 69 6e 74 65 72  e *)pAux)->inter
2d90: 70 3b 0a 20 20 70 56 74 61 62 2d 3e 64 62 20 3d  p;.  pVtab->db =
2da0: 20 64 62 3b 0a 0a 20 20 2f 2a 20 41 6c 6c 6f 63   db;..  /* Alloc
2db0: 61 74 65 20 65 63 68 6f 5f 76 74 61 62 2e 7a 54  ate echo_vtab.zT
2dc0: 68 69 73 20 2a 2f 0a 20 20 70 56 74 61 62 2d 3e  his */.  pVtab->
2dd0: 7a 54 68 69 73 20 3d 20 73 71 6c 69 74 65 33 5f  zThis = sqlite3_
2de0: 6d 70 72 69 6e 74 66 28 22 25 73 22 2c 20 61 72  mprintf("%s", ar
2df0: 67 76 5b 32 5d 29 3b 0a 20 20 69 66 28 20 21 70  gv[2]);.  if( !p
2e00: 56 74 61 62 2d 3e 7a 54 68 69 73 20 29 7b 0a 20  Vtab->zThis ){. 
2e10: 20 20 20 65 63 68 6f 44 65 73 74 72 75 63 74 6f     echoDestructo
2e20: 72 28 28 73 71 6c 69 74 65 33 5f 76 74 61 62 20  r((sqlite3_vtab 
2e30: 2a 29 70 56 74 61 62 29 3b 0a 20 20 20 20 72 65  *)pVtab);.    re
2e40: 74 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45  turn SQLITE_NOME
2e50: 4d 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 41 6c 6c  M;.  }..  /* All
2e60: 6f 63 61 74 65 20 65 63 68 6f 5f 76 74 61 62 2e  ocate echo_vtab.
2e70: 7a 54 61 62 6c 65 4e 61 6d 65 20 2a 2f 0a 20 20  zTableName */.  
2e80: 69 66 28 20 61 72 67 63 3e 33 20 29 7b 0a 20 20  if( argc>3 ){.  
2e90: 20 20 70 56 74 61 62 2d 3e 7a 54 61 62 6c 65 4e    pVtab->zTableN
2ea0: 61 6d 65 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70  ame = sqlite3_mp
2eb0: 72 69 6e 74 66 28 22 25 73 22 2c 20 61 72 67 76  rintf("%s", argv
2ec0: 5b 33 5d 29 3b 0a 20 20 20 20 64 65 71 75 6f 74  [3]);.    dequot
2ed0: 65 53 74 72 69 6e 67 28 70 56 74 61 62 2d 3e 7a  eString(pVtab->z
2ee0: 54 61 62 6c 65 4e 61 6d 65 29 3b 0a 20 20 20 20  TableName);.    
2ef0: 69 66 28 20 70 56 74 61 62 2d 3e 7a 54 61 62 6c  if( pVtab->zTabl
2f00: 65 4e 61 6d 65 20 26 26 20 70 56 74 61 62 2d 3e  eName && pVtab->
2f10: 7a 54 61 62 6c 65 4e 61 6d 65 5b 30 5d 3d 3d 27  zTableName[0]=='
2f20: 2a 27 20 29 7b 0a 20 20 20 20 20 20 63 68 61 72  *' ){.      char
2f30: 20 2a 7a 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70   *z = sqlite3_mp
2f40: 72 69 6e 74 66 28 22 25 73 25 73 22 2c 20 61 72  rintf("%s%s", ar
2f50: 67 76 5b 32 5d 2c 20 26 28 70 56 74 61 62 2d 3e  gv[2], &(pVtab->
2f60: 7a 54 61 62 6c 65 4e 61 6d 65 5b 31 5d 29 29 3b  zTableName[1]));
2f70: 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 66  .      sqlite3_f
2f80: 72 65 65 28 70 56 74 61 62 2d 3e 7a 54 61 62 6c  ree(pVtab->zTabl
2f90: 65 4e 61 6d 65 29 3b 0a 20 20 20 20 20 20 70 56  eName);.      pV
2fa0: 74 61 62 2d 3e 7a 54 61 62 6c 65 4e 61 6d 65 20  tab->zTableName 
2fb0: 3d 20 7a 3b 0a 20 20 20 20 20 20 70 56 74 61 62  = z;.      pVtab
2fc0: 2d 3e 69 73 50 61 74 74 65 72 6e 20 3d 20 31 3b  ->isPattern = 1;
2fd0: 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 28 20 21  .    }.    if( !
2fe0: 70 56 74 61 62 2d 3e 7a 54 61 62 6c 65 4e 61 6d  pVtab->zTableNam
2ff0: 65 20 29 7b 0a 20 20 20 20 20 20 65 63 68 6f 44  e ){.      echoD
3000: 65 73 74 72 75 63 74 6f 72 28 28 73 71 6c 69 74  estructor((sqlit
3010: 65 33 5f 76 74 61 62 20 2a 29 70 56 74 61 62 29  e3_vtab *)pVtab)
3020: 3b 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20 53  ;.      return S
3030: 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20  QLITE_NOMEM;.   
3040: 20 7d 0a 20 20 7d 0a 0a 20 20 2f 2a 20 4c 6f 67   }.  }..  /* Log
3050: 20 74 68 65 20 61 72 67 75 6d 65 6e 74 73 20 74   the arguments t
3060: 6f 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e 20  o this function 
3070: 74 6f 20 54 63 6c 20 76 61 72 20 3a 3a 65 63 68  to Tcl var ::ech
3080: 6f 5f 6d 6f 64 75 6c 65 20 2a 2f 0a 20 20 66 6f  o_module */.  fo
3090: 72 28 69 3d 30 3b 20 69 3c 61 72 67 63 3b 20 69  r(i=0; i<argc; i
30a0: 2b 2b 29 7b 0a 20 20 20 20 61 70 70 65 6e 64 54  ++){.    appendT
30b0: 6f 45 63 68 6f 4d 6f 64 75 6c 65 28 70 56 74 61  oEchoModule(pVta
30c0: 62 2d 3e 69 6e 74 65 72 70 2c 20 61 72 67 76 5b  b->interp, argv[
30d0: 69 5d 29 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 49  i]);.  }..  /* I
30e0: 6e 76 6f 6b 65 20 73 71 6c 69 74 65 33 5f 64 65  nvoke sqlite3_de
30f0: 63 6c 61 72 65 5f 76 74 61 62 20 61 6e 64 20 73  clare_vtab and s
3100: 65 74 20 75 70 20 6f 74 68 65 72 20 6d 65 6d 62  et up other memb
3110: 65 72 73 20 6f 66 20 74 68 65 20 65 63 68 6f 5f  ers of the echo_
3120: 76 74 61 62 0a 20 20 2a 2a 20 73 74 72 75 63 74  vtab.  ** struct
3130: 75 72 65 2e 20 49 66 20 61 6e 20 65 72 72 6f 72  ure. If an error
3140: 20 6f 63 63 75 72 73 2c 20 64 65 6c 65 74 65 20   occurs, delete 
3150: 74 68 65 20 73 71 6c 69 74 65 33 5f 76 74 61 62  the sqlite3_vtab
3160: 20 73 74 72 75 63 74 75 72 65 20 61 6e 64 0a 20   structure and. 
3170: 20 2a 2a 20 72 65 74 75 72 6e 20 61 6e 20 65 72   ** return an er
3180: 72 6f 72 20 63 6f 64 65 2e 0a 20 20 2a 2f 0a 20  ror code..  */. 
3190: 20 72 63 20 3d 20 65 63 68 6f 44 65 63 6c 61 72   rc = echoDeclar
31a0: 65 56 74 61 62 28 70 56 74 61 62 2c 20 64 62 29  eVtab(pVtab, db)
31b0: 3b 0a 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49  ;.  if( rc!=SQLI
31c0: 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 65 63 68  TE_OK ){.    ech
31d0: 6f 44 65 73 74 72 75 63 74 6f 72 28 28 73 71 6c  oDestructor((sql
31e0: 69 74 65 33 5f 76 74 61 62 20 2a 29 70 56 74 61  ite3_vtab *)pVta
31f0: 62 29 3b 0a 20 20 20 20 72 65 74 75 72 6e 20 72  b);.    return r
3200: 63 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 53 75 63  c;.  }..  /* Suc
3210: 63 65 73 73 2e 20 53 65 74 20 2a 70 70 56 74 61  cess. Set *ppVta
3220: 62 20 61 6e 64 20 72 65 74 75 72 6e 20 2a 2f 0a  b and return */.
3230: 20 20 2a 70 70 56 74 61 62 20 3d 20 26 70 56 74    *ppVtab = &pVt
3240: 61 62 2d 3e 62 61 73 65 3b 0a 20 20 72 65 74 75  ab->base;.  retu
3250: 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a  rn SQLITE_OK;.}.
3260: 0a 2f 2a 20 0a 2a 2a 20 45 63 68 6f 20 76 69 72  ./* .** Echo vir
3270: 74 75 61 6c 20 74 61 62 6c 65 20 6d 6f 64 75 6c  tual table modul
3280: 65 20 78 43 72 65 61 74 65 20 6d 65 74 68 6f 64  e xCreate method
3290: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
32a0: 65 63 68 6f 43 72 65 61 74 65 28 0a 20 20 73 71  echoCreate(.  sq
32b0: 6c 69 74 65 33 20 2a 64 62 2c 0a 20 20 76 6f 69  lite3 *db,.  voi
32c0: 64 20 2a 70 41 75 78 2c 0a 20 20 69 6e 74 20 61  d *pAux,.  int a
32d0: 72 67 63 2c 20 63 6f 6e 73 74 20 63 68 61 72 20  rgc, const char 
32e0: 2a 63 6f 6e 73 74 2a 61 72 67 76 2c 0a 20 20 73  *const*argv,.  s
32f0: 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 2a 70 70  qlite3_vtab **pp
3300: 56 74 61 62 2c 0a 20 20 63 68 61 72 20 2a 2a 70  Vtab,.  char **p
3310: 7a 45 72 72 0a 29 7b 0a 20 20 69 6e 74 20 72 63  zErr.){.  int rc
3320: 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20   = SQLITE_OK;.  
3330: 61 70 70 65 6e 64 54 6f 45 63 68 6f 4d 6f 64 75  appendToEchoModu
3340: 6c 65 28 28 28 45 63 68 6f 4d 6f 64 75 6c 65 20  le(((EchoModule 
3350: 2a 29 70 41 75 78 29 2d 3e 69 6e 74 65 72 70 2c  *)pAux)->interp,
3360: 20 22 78 43 72 65 61 74 65 22 29 3b 0a 20 20 72   "xCreate");.  r
3370: 63 20 3d 20 65 63 68 6f 43 6f 6e 73 74 72 75 63  c = echoConstruc
3380: 74 6f 72 28 64 62 2c 20 70 41 75 78 2c 20 61 72  tor(db, pAux, ar
3390: 67 63 2c 20 61 72 67 76 2c 20 70 70 56 74 61 62  gc, argv, ppVtab
33a0: 2c 20 70 7a 45 72 72 29 3b 0a 0a 20 20 2f 2a 20  , pzErr);..  /* 
33b0: 49 66 20 74 68 65 72 65 20 77 65 72 65 20 74 77  If there were tw
33c0: 6f 20 61 72 67 75 6d 65 6e 74 73 20 70 61 73 73  o arguments pass
33d0: 65 64 20 74 6f 20 74 68 65 20 6d 6f 64 75 6c 65  ed to the module
33e0: 20 61 74 20 74 68 65 20 53 51 4c 20 6c 65 76 65   at the SQL leve
33f0: 6c 20 0a 20 20 2a 2a 20 28 69 2e 65 2e 20 22 43  l .  ** (i.e. "C
3400: 52 45 41 54 45 20 56 49 52 54 55 41 4c 20 54 41  REATE VIRTUAL TA
3410: 42 4c 45 20 74 62 6c 20 55 53 49 4e 47 20 65 63  BLE tbl USING ec
3420: 68 6f 28 61 72 67 31 2c 20 61 72 67 32 29 22 29  ho(arg1, arg2)")
3430: 2c 20 74 68 65 6e 20 0a 20 20 2a 2a 20 74 68 65  , then .  ** the
3440: 20 73 65 63 6f 6e 64 20 61 72 67 75 6d 65 6e 74   second argument
3450: 20 69 73 20 75 73 65 64 20 61 73 20 61 20 74 61   is used as a ta
3460: 62 6c 65 20 6e 61 6d 65 2e 20 41 74 74 65 6d 70  ble name. Attemp
3470: 74 20 74 6f 20 63 72 65 61 74 65 0a 20 20 2a 2a  t to create.  **
3480: 20 73 75 63 68 20 61 20 74 61 62 6c 65 20 77 69   such a table wi
3490: 74 68 20 61 20 73 69 6e 67 6c 65 20 63 6f 6c 75  th a single colu
34a0: 6d 6e 2c 20 22 6c 6f 67 6d 73 67 22 2e 20 54 68  mn, "logmsg". Th
34b0: 69 73 20 74 61 62 6c 65 20 77 69 6c 6c 0a 20 20  is table will.  
34c0: 2a 2a 20 62 65 20 75 73 65 64 20 74 6f 20 6c 6f  ** be used to lo
34d0: 67 20 63 61 6c 6c 73 20 74 6f 20 74 68 65 20 78  g calls to the x
34e0: 55 70 64 61 74 65 20 6d 65 74 68 6f 64 2e 20 49  Update method. I
34f0: 74 20 77 69 6c 6c 20 62 65 20 64 65 6c 65 74 65  t will be delete
3500: 64 0a 20 20 2a 2a 20 77 68 65 6e 20 74 68 65 20  d.  ** when the 
3510: 76 69 72 74 75 61 6c 20 74 61 62 6c 65 20 69 73  virtual table is
3520: 20 44 52 4f 50 65 64 2e 0a 20 20 2a 2a 0a 20 20   DROPed..  **.  
3530: 2a 2a 20 4e 6f 74 65 3a 20 54 68 65 20 6d 61 69  ** Note: The mai
3540: 6e 20 70 6f 69 6e 74 20 6f 66 20 74 68 69 73 20  n point of this 
3550: 69 73 20 74 6f 20 74 65 73 74 20 74 68 61 74 20  is to test that 
3560: 77 65 20 63 61 6e 20 64 72 6f 70 20 74 61 62 6c  we can drop tabl
3570: 65 73 0a 20 20 2a 2a 20 66 72 6f 6d 20 77 69 74  es.  ** from wit
3580: 68 69 6e 20 61 6e 20 78 44 65 73 74 72 6f 79 20  hin an xDestroy 
3590: 6d 65 74 68 6f 64 20 63 61 6c 6c 2e 0a 20 20 2a  method call..  *
35a0: 2f 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49  /.  if( rc==SQLI
35b0: 54 45 5f 4f 4b 20 26 26 20 61 72 67 63 3d 3d 35  TE_OK && argc==5
35c0: 20 29 7b 0a 20 20 20 20 63 68 61 72 20 2a 7a 53   ){.    char *zS
35d0: 71 6c 3b 0a 20 20 20 20 65 63 68 6f 5f 76 74 61  ql;.    echo_vta
35e0: 62 20 2a 70 56 74 61 62 20 3d 20 2a 28 65 63 68  b *pVtab = *(ech
35f0: 6f 5f 76 74 61 62 20 2a 2a 29 70 70 56 74 61 62  o_vtab **)ppVtab
3600: 3b 0a 20 20 20 20 70 56 74 61 62 2d 3e 7a 4c 6f  ;.    pVtab->zLo
3610: 67 4e 61 6d 65 20 3d 20 73 71 6c 69 74 65 33 5f  gName = sqlite3_
3620: 6d 70 72 69 6e 74 66 28 22 25 73 22 2c 20 61 72  mprintf("%s", ar
3630: 67 76 5b 34 5d 29 3b 0a 20 20 20 20 7a 53 71 6c  gv[4]);.    zSql
3640: 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e   = sqlite3_mprin
3650: 74 66 28 22 43 52 45 41 54 45 20 54 41 42 4c 45  tf("CREATE TABLE
3660: 20 25 51 28 6c 6f 67 6d 73 67 29 22 2c 20 70 56   %Q(logmsg)", pV
3670: 74 61 62 2d 3e 7a 4c 6f 67 4e 61 6d 65 29 3b 0a  tab->zLogName);.
3680: 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33      rc = sqlite3
3690: 5f 65 78 65 63 28 64 62 2c 20 7a 53 71 6c 2c 20  _exec(db, zSql, 
36a0: 30 2c 20 30 2c 20 30 29 3b 0a 20 20 20 20 73 71  0, 0, 0);.    sq
36b0: 6c 69 74 65 33 5f 66 72 65 65 28 7a 53 71 6c 29  lite3_free(zSql)
36c0: 3b 0a 20 20 20 20 69 66 28 20 72 63 21 3d 53 51  ;.    if( rc!=SQ
36d0: 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20  LITE_OK ){.     
36e0: 20 2a 70 7a 45 72 72 20 3d 20 73 71 6c 69 74 65   *pzErr = sqlite
36f0: 33 5f 6d 70 72 69 6e 74 66 28 22 25 73 22 2c 20  3_mprintf("%s", 
3700: 73 71 6c 69 74 65 33 5f 65 72 72 6d 73 67 28 64  sqlite3_errmsg(d
3710: 62 29 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a  b));.    }.  }..
3720: 20 20 69 66 28 20 2a 70 70 56 74 61 62 20 26 26    if( *ppVtab &&
3730: 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc!=SQLITE_OK )
3740: 7b 0a 20 20 20 20 65 63 68 6f 44 65 73 74 72 75  {.    echoDestru
3750: 63 74 6f 72 28 2a 70 70 56 74 61 62 29 3b 0a 20  ctor(*ppVtab);. 
3760: 20 20 20 2a 70 70 56 74 61 62 20 3d 20 30 3b 0a     *ppVtab = 0;.
3770: 20 20 7d 0a 0a 20 20 69 66 28 20 72 63 3d 3d 53    }..  if( rc==S
3780: 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
3790: 28 2a 28 65 63 68 6f 5f 76 74 61 62 2a 2a 29 70  (*(echo_vtab**)p
37a0: 70 56 74 61 62 29 2d 3e 69 6e 54 72 61 6e 73 61  pVtab)->inTransa
37b0: 63 74 69 6f 6e 20 3d 20 31 3b 0a 20 20 7d 0a 0a  ction = 1;.  }..
37c0: 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a    return rc;.}..
37d0: 2f 2a 20 0a 2a 2a 20 45 63 68 6f 20 76 69 72 74  /* .** Echo virt
37e0: 75 61 6c 20 74 61 62 6c 65 20 6d 6f 64 75 6c 65  ual table module
37f0: 20 78 43 6f 6e 6e 65 63 74 20 6d 65 74 68 6f 64   xConnect method
3800: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
3810: 65 63 68 6f 43 6f 6e 6e 65 63 74 28 0a 20 20 73  echoConnect(.  s
3820: 71 6c 69 74 65 33 20 2a 64 62 2c 0a 20 20 76 6f  qlite3 *db,.  vo
3830: 69 64 20 2a 70 41 75 78 2c 0a 20 20 69 6e 74 20  id *pAux,.  int 
3840: 61 72 67 63 2c 20 63 6f 6e 73 74 20 63 68 61 72  argc, const char
3850: 20 2a 63 6f 6e 73 74 2a 61 72 67 76 2c 0a 20 20   *const*argv,.  
3860: 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 2a 70  sqlite3_vtab **p
3870: 70 56 74 61 62 2c 0a 20 20 63 68 61 72 20 2a 2a  pVtab,.  char **
3880: 70 7a 45 72 72 0a 29 7b 0a 20 20 61 70 70 65 6e  pzErr.){.  appen
3890: 64 54 6f 45 63 68 6f 4d 6f 64 75 6c 65 28 28 28  dToEchoModule(((
38a0: 45 63 68 6f 4d 6f 64 75 6c 65 20 2a 29 70 41 75  EchoModule *)pAu
38b0: 78 29 2d 3e 69 6e 74 65 72 70 2c 20 22 78 43 6f  x)->interp, "xCo
38c0: 6e 6e 65 63 74 22 29 3b 0a 20 20 72 65 74 75 72  nnect");.  retur
38d0: 6e 20 65 63 68 6f 43 6f 6e 73 74 72 75 63 74 6f  n echoConstructo
38e0: 72 28 64 62 2c 20 70 41 75 78 2c 20 61 72 67 63  r(db, pAux, argc
38f0: 2c 20 61 72 67 76 2c 20 70 70 56 74 61 62 2c 20  , argv, ppVtab, 
3900: 70 7a 45 72 72 29 3b 0a 7d 0a 0a 2f 2a 20 0a 2a  pzErr);.}../* .*
3910: 2a 20 45 63 68 6f 20 76 69 72 74 75 61 6c 20 74  * Echo virtual t
3920: 61 62 6c 65 20 6d 6f 64 75 6c 65 20 78 44 69 73  able module xDis
3930: 63 6f 6e 6e 65 63 74 20 6d 65 74 68 6f 64 2e 0a  connect method..
3940: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 65 63  */.static int ec
3950: 68 6f 44 69 73 63 6f 6e 6e 65 63 74 28 73 71 6c  hoDisconnect(sql
3960: 69 74 65 33 5f 76 74 61 62 20 2a 70 56 74 61 62  ite3_vtab *pVtab
3970: 29 7b 0a 20 20 61 70 70 65 6e 64 54 6f 45 63 68  ){.  appendToEch
3980: 6f 4d 6f 64 75 6c 65 28 28 28 65 63 68 6f 5f 76  oModule(((echo_v
3990: 74 61 62 20 2a 29 70 56 74 61 62 29 2d 3e 69 6e  tab *)pVtab)->in
39a0: 74 65 72 70 2c 20 22 78 44 69 73 63 6f 6e 6e 65  terp, "xDisconne
39b0: 63 74 22 29 3b 0a 20 20 72 65 74 75 72 6e 20 65  ct");.  return e
39c0: 63 68 6f 44 65 73 74 72 75 63 74 6f 72 28 70 56  choDestructor(pV
39d0: 74 61 62 29 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20  tab);.}../* .** 
39e0: 45 63 68 6f 20 76 69 72 74 75 61 6c 20 74 61 62  Echo virtual tab
39f0: 6c 65 20 6d 6f 64 75 6c 65 20 78 44 65 73 74 72  le module xDestr
3a00: 6f 79 20 6d 65 74 68 6f 64 2e 0a 2a 2f 0a 73 74  oy method..*/.st
3a10: 61 74 69 63 20 69 6e 74 20 65 63 68 6f 44 65 73  atic int echoDes
3a20: 74 72 6f 79 28 73 71 6c 69 74 65 33 5f 76 74 61  troy(sqlite3_vta
3a30: 62 20 2a 70 56 74 61 62 29 7b 0a 20 20 69 6e 74  b *pVtab){.  int
3a40: 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b   rc = SQLITE_OK;
3a50: 0a 20 20 65 63 68 6f 5f 76 74 61 62 20 2a 70 20  .  echo_vtab *p 
3a60: 3d 20 28 65 63 68 6f 5f 76 74 61 62 20 2a 29 70  = (echo_vtab *)p
3a70: 56 74 61 62 3b 0a 20 20 61 70 70 65 6e 64 54 6f  Vtab;.  appendTo
3a80: 45 63 68 6f 4d 6f 64 75 6c 65 28 28 28 65 63 68  EchoModule(((ech
3a90: 6f 5f 76 74 61 62 20 2a 29 70 56 74 61 62 29 2d  o_vtab *)pVtab)-
3aa0: 3e 69 6e 74 65 72 70 2c 20 22 78 44 65 73 74 72  >interp, "xDestr
3ab0: 6f 79 22 29 3b 0a 0a 20 20 2f 2a 20 44 72 6f 70  oy");..  /* Drop
3ac0: 20 74 68 65 20 22 6c 6f 67 22 20 74 61 62 6c 65   the "log" table
3ad0: 2c 20 69 66 20 6f 6e 65 20 65 78 69 73 74 73 20  , if one exists 
3ae0: 28 73 65 65 20 65 63 68 6f 43 72 65 61 74 65 28  (see echoCreate(
3af0: 29 20 66 6f 72 20 64 65 74 61 69 6c 73 29 20 2a  ) for details) *
3b00: 2f 0a 20 20 69 66 28 20 70 20 26 26 20 70 2d 3e  /.  if( p && p->
3b10: 7a 4c 6f 67 4e 61 6d 65 20 29 7b 0a 20 20 20 20  zLogName ){.    
3b20: 63 68 61 72 20 2a 7a 53 71 6c 3b 0a 20 20 20 20  char *zSql;.    
3b30: 7a 53 71 6c 20 3d 20 73 71 6c 69 74 65 33 5f 6d  zSql = sqlite3_m
3b40: 70 72 69 6e 74 66 28 22 44 52 4f 50 20 54 41 42  printf("DROP TAB
3b50: 4c 45 20 25 51 22 2c 20 70 2d 3e 7a 4c 6f 67 4e  LE %Q", p->zLogN
3b60: 61 6d 65 29 3b 0a 20 20 20 20 72 63 20 3d 20 73  ame);.    rc = s
3b70: 71 6c 69 74 65 33 5f 65 78 65 63 28 70 2d 3e 64  qlite3_exec(p->d
3b80: 62 2c 20 7a 53 71 6c 2c 20 30 2c 20 30 2c 20 30  b, zSql, 0, 0, 0
3b90: 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 66  );.    sqlite3_f
3ba0: 72 65 65 28 7a 53 71 6c 29 3b 0a 20 20 7d 0a 0a  ree(zSql);.  }..
3bb0: 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
3bc0: 5f 4f 4b 20 29 7b 0a 20 20 20 20 72 63 20 3d 20  _OK ){.    rc = 
3bd0: 65 63 68 6f 44 65 73 74 72 75 63 74 6f 72 28 70  echoDestructor(p
3be0: 56 74 61 62 29 3b 0a 20 20 7d 0a 20 20 72 65 74  Vtab);.  }.  ret
3bf0: 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 20 0a 2a  urn rc;.}../* .*
3c00: 2a 20 45 63 68 6f 20 76 69 72 74 75 61 6c 20 74  * Echo virtual t
3c10: 61 62 6c 65 20 6d 6f 64 75 6c 65 20 78 4f 70 65  able module xOpe
3c20: 6e 20 6d 65 74 68 6f 64 2e 0a 2a 2f 0a 73 74 61  n method..*/.sta
3c30: 74 69 63 20 69 6e 74 20 65 63 68 6f 4f 70 65 6e  tic int echoOpen
3c40: 28 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 70  (sqlite3_vtab *p
3c50: 56 54 61 62 2c 20 73 71 6c 69 74 65 33 5f 76 74  VTab, sqlite3_vt
3c60: 61 62 5f 63 75 72 73 6f 72 20 2a 2a 70 70 43 75  ab_cursor **ppCu
3c70: 72 73 6f 72 29 7b 0a 20 20 65 63 68 6f 5f 63 75  rsor){.  echo_cu
3c80: 72 73 6f 72 20 2a 70 43 75 72 3b 0a 20 20 69 66  rsor *pCur;.  if
3c90: 28 20 73 69 6d 75 6c 61 74 65 56 74 61 62 45 72  ( simulateVtabEr
3ca0: 72 6f 72 28 28 65 63 68 6f 5f 76 74 61 62 20 2a  ror((echo_vtab *
3cb0: 29 70 56 54 61 62 2c 20 22 78 4f 70 65 6e 22 29  )pVTab, "xOpen")
3cc0: 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 53   ){.    return S
3cd0: 51 4c 49 54 45 5f 45 52 52 4f 52 3b 0a 20 20 7d  QLITE_ERROR;.  }
3ce0: 0a 20 20 70 43 75 72 20 3d 20 73 71 6c 69 74 65  .  pCur = sqlite
3cf0: 33 4d 61 6c 6c 6f 63 5a 65 72 6f 28 73 69 7a 65  3MallocZero(size
3d00: 6f 66 28 65 63 68 6f 5f 63 75 72 73 6f 72 29 29  of(echo_cursor))
3d10: 3b 0a 20 20 2a 70 70 43 75 72 73 6f 72 20 3d 20  ;.  *ppCursor = 
3d20: 28 73 71 6c 69 74 65 33 5f 76 74 61 62 5f 63 75  (sqlite3_vtab_cu
3d30: 72 73 6f 72 20 2a 29 70 43 75 72 3b 0a 20 20 72  rsor *)pCur;.  r
3d40: 65 74 75 72 6e 20 28 70 43 75 72 20 3f 20 53 51  eturn (pCur ? SQ
3d50: 4c 49 54 45 5f 4f 4b 20 3a 20 53 51 4c 49 54 45  LITE_OK : SQLITE
3d60: 5f 4e 4f 4d 45 4d 29 3b 0a 7d 0a 0a 2f 2a 20 0a  _NOMEM);.}../* .
3d70: 2a 2a 20 45 63 68 6f 20 76 69 72 74 75 61 6c 20  ** Echo virtual 
3d80: 74 61 62 6c 65 20 6d 6f 64 75 6c 65 20 78 43 6c  table module xCl
3d90: 6f 73 65 20 6d 65 74 68 6f 64 2e 0a 2a 2f 0a 73  ose method..*/.s
3da0: 74 61 74 69 63 20 69 6e 74 20 65 63 68 6f 43 6c  tatic int echoCl
3db0: 6f 73 65 28 73 71 6c 69 74 65 33 5f 76 74 61 62  ose(sqlite3_vtab
3dc0: 5f 63 75 72 73 6f 72 20 2a 63 75 72 29 7b 0a 20  _cursor *cur){. 
3dd0: 20 69 6e 74 20 72 63 3b 0a 20 20 65 63 68 6f 5f   int rc;.  echo_
3de0: 63 75 72 73 6f 72 20 2a 70 43 75 72 20 3d 20 28  cursor *pCur = (
3df0: 65 63 68 6f 5f 63 75 72 73 6f 72 20 2a 29 63 75  echo_cursor *)cu
3e00: 72 3b 0a 20 20 73 71 6c 69 74 65 33 5f 73 74 6d  r;.  sqlite3_stm
3e10: 74 20 2a 70 53 74 6d 74 20 3d 20 70 43 75 72 2d  t *pStmt = pCur-
3e20: 3e 70 53 74 6d 74 3b 0a 20 20 70 43 75 72 2d 3e  >pStmt;.  pCur->
3e30: 70 53 74 6d 74 20 3d 20 30 3b 0a 20 20 73 71 6c  pStmt = 0;.  sql
3e40: 69 74 65 33 5f 66 72 65 65 28 70 43 75 72 29 3b  ite3_free(pCur);
3e50: 0a 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f  .  rc = sqlite3_
3e60: 66 69 6e 61 6c 69 7a 65 28 70 53 74 6d 74 29 3b  finalize(pStmt);
3e70: 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a  .  return rc;.}.
3e80: 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 6e 6f  ./*.** Return no
3e90: 6e 2d 7a 65 72 6f 20 69 66 20 74 68 65 20 63 75  n-zero if the cu
3ea0: 72 73 6f 72 20 64 6f 65 73 20 6e 6f 74 20 63 75  rsor does not cu
3eb0: 72 72 65 6e 74 6c 79 20 70 6f 69 6e 74 20 74 6f  rrently point to
3ec0: 20 61 20 76 61 6c 69 64 20 72 65 63 6f 72 64 0a   a valid record.
3ed0: 2a 2a 20 28 69 2e 65 20 69 66 20 74 68 65 20 73  ** (i.e if the s
3ee0: 63 61 6e 20 68 61 73 20 66 69 6e 69 73 68 65 64  can has finished
3ef0: 29 2c 20 6f 72 20 7a 65 72 6f 20 6f 74 68 65 72  ), or zero other
3f00: 77 69 73 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  wise..*/.static 
3f10: 69 6e 74 20 65 63 68 6f 45 6f 66 28 73 71 6c 69  int echoEof(sqli
3f20: 74 65 33 5f 76 74 61 62 5f 63 75 72 73 6f 72 20  te3_vtab_cursor 
3f30: 2a 63 75 72 29 7b 0a 20 20 72 65 74 75 72 6e 20  *cur){.  return 
3f40: 28 28 28 65 63 68 6f 5f 63 75 72 73 6f 72 20 2a  (((echo_cursor *
3f50: 29 63 75 72 29 2d 3e 70 53 74 6d 74 20 3f 20 30  )cur)->pStmt ? 0
3f60: 20 3a 20 31 29 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a   : 1);.}../* .**
3f70: 20 45 63 68 6f 20 76 69 72 74 75 61 6c 20 74 61   Echo virtual ta
3f80: 62 6c 65 20 6d 6f 64 75 6c 65 20 78 4e 65 78 74  ble module xNext
3f90: 20 6d 65 74 68 6f 64 2e 0a 2a 2f 0a 73 74 61 74   method..*/.stat
3fa0: 69 63 20 69 6e 74 20 65 63 68 6f 4e 65 78 74 28  ic int echoNext(
3fb0: 73 71 6c 69 74 65 33 5f 76 74 61 62 5f 63 75 72  sqlite3_vtab_cur
3fc0: 73 6f 72 20 2a 63 75 72 29 7b 0a 20 20 69 6e 74  sor *cur){.  int
3fd0: 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b   rc = SQLITE_OK;
3fe0: 0a 20 20 65 63 68 6f 5f 63 75 72 73 6f 72 20 2a  .  echo_cursor *
3ff0: 70 43 75 72 20 3d 20 28 65 63 68 6f 5f 63 75 72  pCur = (echo_cur
4000: 73 6f 72 20 2a 29 63 75 72 3b 0a 0a 20 20 69 66  sor *)cur;..  if
4010: 28 20 73 69 6d 75 6c 61 74 65 56 74 61 62 45 72  ( simulateVtabEr
4020: 72 6f 72 28 28 65 63 68 6f 5f 76 74 61 62 20 2a  ror((echo_vtab *
4030: 29 28 63 75 72 2d 3e 70 56 74 61 62 29 2c 20 22  )(cur->pVtab), "
4040: 78 4e 65 78 74 22 29 20 29 7b 0a 20 20 20 20 72  xNext") ){.    r
4050: 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 45 52 52  eturn SQLITE_ERR
4060: 4f 52 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 70  OR;.  }..  if( p
4070: 43 75 72 2d 3e 70 53 74 6d 74 20 29 7b 0a 20 20  Cur->pStmt ){.  
4080: 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 73    rc = sqlite3_s
4090: 74 65 70 28 70 43 75 72 2d 3e 70 53 74 6d 74 29  tep(pCur->pStmt)
40a0: 3b 0a 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51  ;.    if( rc==SQ
40b0: 4c 49 54 45 5f 52 4f 57 20 29 7b 0a 20 20 20 20  LITE_ROW ){.    
40c0: 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b    rc = SQLITE_OK
40d0: 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20  ;.    }else{.   
40e0: 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f     rc = sqlite3_
40f0: 66 69 6e 61 6c 69 7a 65 28 70 43 75 72 2d 3e 70  finalize(pCur->p
4100: 53 74 6d 74 29 3b 0a 20 20 20 20 20 20 70 43 75  Stmt);.      pCu
4110: 72 2d 3e 70 53 74 6d 74 20 3d 20 30 3b 0a 20 20  r->pStmt = 0;.  
4120: 20 20 7d 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72    }.  }..  retur
4130: 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20  n rc;.}../* .** 
4140: 45 63 68 6f 20 76 69 72 74 75 61 6c 20 74 61 62  Echo virtual tab
4150: 6c 65 20 6d 6f 64 75 6c 65 20 78 43 6f 6c 75 6d  le module xColum
4160: 6e 20 6d 65 74 68 6f 64 2e 0a 2a 2f 0a 73 74 61  n method..*/.sta
4170: 74 69 63 20 69 6e 74 20 65 63 68 6f 43 6f 6c 75  tic int echoColu
4180: 6d 6e 28 73 71 6c 69 74 65 33 5f 76 74 61 62 5f  mn(sqlite3_vtab_
4190: 63 75 72 73 6f 72 20 2a 63 75 72 2c 20 73 71 6c  cursor *cur, sql
41a0: 69 74 65 33 5f 63 6f 6e 74 65 78 74 20 2a 63 74  ite3_context *ct
41b0: 78 2c 20 69 6e 74 20 69 29 7b 0a 20 20 69 6e 74  x, int i){.  int
41c0: 20 69 43 6f 6c 20 3d 20 69 20 2b 20 31 3b 0a 20   iCol = i + 1;. 
41d0: 20 73 71 6c 69 74 65 33 5f 73 74 6d 74 20 2a 70   sqlite3_stmt *p
41e0: 53 74 6d 74 20 3d 20 28 28 65 63 68 6f 5f 63 75  Stmt = ((echo_cu
41f0: 72 73 6f 72 20 2a 29 63 75 72 29 2d 3e 70 53 74  rsor *)cur)->pSt
4200: 6d 74 3b 0a 0a 20 20 69 66 28 20 73 69 6d 75 6c  mt;..  if( simul
4210: 61 74 65 56 74 61 62 45 72 72 6f 72 28 28 65 63  ateVtabError((ec
4220: 68 6f 5f 76 74 61 62 20 2a 29 28 63 75 72 2d 3e  ho_vtab *)(cur->
4230: 70 56 74 61 62 29 2c 20 22 78 43 6f 6c 75 6d 6e  pVtab), "xColumn
4240: 22 29 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e  ") ){.    return
4250: 20 53 51 4c 49 54 45 5f 45 52 52 4f 52 3b 0a 20   SQLITE_ERROR;. 
4260: 20 7d 0a 0a 20 20 69 66 28 20 21 70 53 74 6d 74   }..  if( !pStmt
4270: 20 29 7b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f   ){.    sqlite3_
4280: 72 65 73 75 6c 74 5f 6e 75 6c 6c 28 63 74 78 29  result_null(ctx)
4290: 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 61  ;.  }else{.    a
42a0: 73 73 65 72 74 28 20 73 71 6c 69 74 65 33 5f 64  ssert( sqlite3_d
42b0: 61 74 61 5f 63 6f 75 6e 74 28 70 53 74 6d 74 29  ata_count(pStmt)
42c0: 3e 69 43 6f 6c 20 29 3b 0a 20 20 20 20 73 71 6c  >iCol );.    sql
42d0: 69 74 65 33 5f 72 65 73 75 6c 74 5f 76 61 6c 75  ite3_result_valu
42e0: 65 28 63 74 78 2c 20 73 71 6c 69 74 65 33 5f 63  e(ctx, sqlite3_c
42f0: 6f 6c 75 6d 6e 5f 76 61 6c 75 65 28 70 53 74 6d  olumn_value(pStm
4300: 74 2c 20 69 43 6f 6c 29 29 3b 0a 20 20 7d 0a 20  t, iCol));.  }. 
4310: 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f   return SQLITE_O
4320: 4b 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 45 63 68  K;.}../* .** Ech
4330: 6f 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65 20  o virtual table 
4340: 6d 6f 64 75 6c 65 20 78 52 6f 77 69 64 20 6d 65  module xRowid me
4350: 74 68 6f 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  thod..*/.static 
4360: 69 6e 74 20 65 63 68 6f 52 6f 77 69 64 28 73 71  int echoRowid(sq
4370: 6c 69 74 65 33 5f 76 74 61 62 5f 63 75 72 73 6f  lite3_vtab_curso
4380: 72 20 2a 63 75 72 2c 20 73 71 6c 69 74 65 5f 69  r *cur, sqlite_i
4390: 6e 74 36 34 20 2a 70 52 6f 77 69 64 29 7b 0a 20  nt64 *pRowid){. 
43a0: 20 73 71 6c 69 74 65 33 5f 73 74 6d 74 20 2a 70   sqlite3_stmt *p
43b0: 53 74 6d 74 20 3d 20 28 28 65 63 68 6f 5f 63 75  Stmt = ((echo_cu
43c0: 72 73 6f 72 20 2a 29 63 75 72 29 2d 3e 70 53 74  rsor *)cur)->pSt
43d0: 6d 74 3b 0a 0a 20 20 69 66 28 20 73 69 6d 75 6c  mt;..  if( simul
43e0: 61 74 65 56 74 61 62 45 72 72 6f 72 28 28 65 63  ateVtabError((ec
43f0: 68 6f 5f 76 74 61 62 20 2a 29 28 63 75 72 2d 3e  ho_vtab *)(cur->
4400: 70 56 74 61 62 29 2c 20 22 78 52 6f 77 69 64 22  pVtab), "xRowid"
4410: 29 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20  ) ){.    return 
4420: 53 51 4c 49 54 45 5f 45 52 52 4f 52 3b 0a 20 20  SQLITE_ERROR;.  
4430: 7d 0a 0a 20 20 2a 70 52 6f 77 69 64 20 3d 20 73  }..  *pRowid = s
4440: 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 69 6e  qlite3_column_in
4450: 74 36 34 28 70 53 74 6d 74 2c 20 30 29 3b 0a 20  t64(pStmt, 0);. 
4460: 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f   return SQLITE_O
4470: 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 6f 6d 70  K;.}../*.** Comp
4480: 75 74 65 20 61 20 73 69 6d 70 6c 65 20 68 61 73  ute a simple has
4490: 68 20 6f 66 20 74 68 65 20 6e 75 6c 6c 20 74 65  h of the null te
44a0: 72 6d 69 6e 61 74 65 64 20 73 74 72 69 6e 67 20  rminated string 
44b0: 7a 53 74 72 69 6e 67 2e 0a 2a 2a 0a 2a 2a 20 54  zString..**.** T
44c0: 68 69 73 20 6d 6f 64 75 6c 65 20 75 73 65 73 20  his module uses 
44d0: 6f 6e 6c 79 20 73 71 6c 69 74 65 33 5f 69 6e 64  only sqlite3_ind
44e0: 65 78 5f 69 6e 66 6f 2e 69 64 78 53 74 72 2c 20  ex_info.idxStr, 
44f0: 6e 6f 74 20 0a 2a 2a 20 73 71 6c 69 74 65 33 5f  not .** sqlite3_
4500: 69 6e 64 65 78 5f 69 6e 66 6f 2e 69 64 78 4e 75  index_info.idxNu
4510: 6d 2e 20 53 6f 20 74 6f 20 74 65 73 74 20 69 64  m. So to test id
4520: 78 4e 75 6d 2c 20 77 68 65 6e 20 69 64 78 53 74  xNum, when idxSt
4530: 72 20 69 73 20 73 65 74 0a 2a 2a 20 69 6e 20 65  r is set.** in e
4540: 63 68 6f 42 65 73 74 49 6e 64 65 78 28 29 2c 20  choBestIndex(), 
4550: 69 64 78 4e 75 6d 20 69 73 20 73 65 74 20 74 6f  idxNum is set to
4560: 20 74 68 65 20 63 6f 72 72 65 73 70 6f 6e 64 69   the correspondi
4570: 6e 67 20 68 61 73 68 20 76 61 6c 75 65 2e 0a 2a  ng hash value..*
4580: 2a 20 49 6e 20 65 63 68 6f 46 69 6c 74 65 72 28  * In echoFilter(
4590: 29 2c 20 63 6f 64 65 20 61 73 73 65 72 74 28 29  ), code assert()
45a0: 73 20 74 68 61 74 20 74 68 65 20 73 75 70 70 6c  s that the suppl
45b0: 69 65 64 20 69 64 78 4e 75 6d 20 76 61 6c 75 65  ied idxNum value
45c0: 20 69 73 0a 2a 2a 20 69 6e 64 65 65 64 20 74 68   is.** indeed th
45d0: 65 20 68 61 73 68 20 6f 66 20 74 68 65 20 73 75  e hash of the su
45e0: 70 70 6c 69 65 64 20 69 64 78 53 74 72 2e 0a 2a  pplied idxStr..*
45f0: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 68 61 73  /.static int has
4600: 68 53 74 72 69 6e 67 28 63 6f 6e 73 74 20 63 68  hString(const ch
4610: 61 72 20 2a 7a 53 74 72 69 6e 67 29 7b 0a 20 20  ar *zString){.  
4620: 69 6e 74 20 76 61 6c 20 3d 20 30 3b 0a 20 20 69  int val = 0;.  i
4630: 6e 74 20 69 69 3b 0a 20 20 66 6f 72 28 69 69 3d  nt ii;.  for(ii=
4640: 30 3b 20 7a 53 74 72 69 6e 67 5b 69 69 5d 3b 20  0; zString[ii]; 
4650: 69 69 2b 2b 29 7b 0a 20 20 20 20 76 61 6c 20 3d  ii++){.    val =
4660: 20 28 76 61 6c 20 3c 3c 20 33 29 20 2b 20 28 69   (val << 3) + (i
4670: 6e 74 29 7a 53 74 72 69 6e 67 5b 69 69 5d 3b 0a  nt)zString[ii];.
4680: 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 76 61 6c    }.  return val
4690: 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 45 63 68 6f  ;.}../* .** Echo
46a0: 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65 20 6d   virtual table m
46b0: 6f 64 75 6c 65 20 78 46 69 6c 74 65 72 20 6d 65  odule xFilter me
46c0: 74 68 6f 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  thod..*/.static 
46d0: 69 6e 74 20 65 63 68 6f 46 69 6c 74 65 72 28 0a  int echoFilter(.
46e0: 20 20 73 71 6c 69 74 65 33 5f 76 74 61 62 5f 63    sqlite3_vtab_c
46f0: 75 72 73 6f 72 20 2a 70 56 74 61 62 43 75 72 73  ursor *pVtabCurs
4700: 6f 72 2c 20 0a 20 20 69 6e 74 20 69 64 78 4e 75  or, .  int idxNu
4710: 6d 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 69  m, const char *i
4720: 64 78 53 74 72 2c 0a 20 20 69 6e 74 20 61 72 67  dxStr,.  int arg
4730: 63 2c 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65  c, sqlite3_value
4740: 20 2a 2a 61 72 67 76 0a 29 7b 0a 20 20 69 6e 74   **argv.){.  int
4750: 20 72 63 3b 0a 20 20 69 6e 74 20 69 3b 0a 0a 20   rc;.  int i;.. 
4760: 20 65 63 68 6f 5f 63 75 72 73 6f 72 20 2a 70 43   echo_cursor *pC
4770: 75 72 20 3d 20 28 65 63 68 6f 5f 63 75 72 73 6f  ur = (echo_curso
4780: 72 20 2a 29 70 56 74 61 62 43 75 72 73 6f 72 3b  r *)pVtabCursor;
4790: 0a 20 20 65 63 68 6f 5f 76 74 61 62 20 2a 70 56  .  echo_vtab *pV
47a0: 74 61 62 20 3d 20 28 65 63 68 6f 5f 76 74 61 62  tab = (echo_vtab
47b0: 20 2a 29 70 56 74 61 62 43 75 72 73 6f 72 2d 3e   *)pVtabCursor->
47c0: 70 56 74 61 62 3b 0a 20 20 73 71 6c 69 74 65 33  pVtab;.  sqlite3
47d0: 20 2a 64 62 20 3d 20 70 56 74 61 62 2d 3e 64 62   *db = pVtab->db
47e0: 3b 0a 0a 20 20 69 66 28 20 73 69 6d 75 6c 61 74  ;..  if( simulat
47f0: 65 56 74 61 62 45 72 72 6f 72 28 70 56 74 61 62  eVtabError(pVtab
4800: 2c 20 22 78 46 69 6c 74 65 72 22 29 20 29 7b 0a  , "xFilter") ){.
4810: 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54      return SQLIT
4820: 45 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a 0a 20 20  E_ERROR;.  }..  
4830: 2f 2a 20 43 68 65 63 6b 20 74 68 61 74 20 69 64  /* Check that id
4840: 78 4e 75 6d 20 6d 61 74 63 68 65 73 20 69 64 78  xNum matches idx
4850: 53 74 72 20 2a 2f 0a 20 20 61 73 73 65 72 74 28  Str */.  assert(
4860: 20 69 64 78 4e 75 6d 3d 3d 68 61 73 68 53 74 72   idxNum==hashStr
4870: 69 6e 67 28 69 64 78 53 74 72 29 20 29 3b 0a 0a  ing(idxStr) );..
4880: 20 20 2f 2a 20 4c 6f 67 20 61 72 67 75 6d 65 6e    /* Log argumen
4890: 74 73 20 74 6f 20 74 68 65 20 3a 3a 65 63 68 6f  ts to the ::echo
48a0: 5f 6d 6f 64 75 6c 65 20 54 63 6c 20 76 61 72 69  _module Tcl vari
48b0: 61 62 6c 65 20 2a 2f 0a 20 20 61 70 70 65 6e 64  able */.  append
48c0: 54 6f 45 63 68 6f 4d 6f 64 75 6c 65 28 70 56 74  ToEchoModule(pVt
48d0: 61 62 2d 3e 69 6e 74 65 72 70 2c 20 22 78 46 69  ab->interp, "xFi
48e0: 6c 74 65 72 22 29 3b 0a 20 20 61 70 70 65 6e 64  lter");.  append
48f0: 54 6f 45 63 68 6f 4d 6f 64 75 6c 65 28 70 56 74  ToEchoModule(pVt
4900: 61 62 2d 3e 69 6e 74 65 72 70 2c 20 69 64 78 53  ab->interp, idxS
4910: 74 72 29 3b 0a 20 20 66 6f 72 28 69 3d 30 3b 20  tr);.  for(i=0; 
4920: 69 3c 61 72 67 63 3b 20 69 2b 2b 29 7b 0a 20 20  i<argc; i++){.  
4930: 20 20 61 70 70 65 6e 64 54 6f 45 63 68 6f 4d 6f    appendToEchoMo
4940: 64 75 6c 65 28 70 56 74 61 62 2d 3e 69 6e 74 65  dule(pVtab->inte
4950: 72 70 2c 20 28 63 6f 6e 73 74 20 63 68 61 72 2a  rp, (const char*
4960: 29 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 74  )sqlite3_value_t
4970: 65 78 74 28 61 72 67 76 5b 69 5d 29 29 3b 0a 20  ext(argv[i]));. 
4980: 20 7d 0a 0a 20 20 73 71 6c 69 74 65 33 5f 66 69   }..  sqlite3_fi
4990: 6e 61 6c 69 7a 65 28 70 43 75 72 2d 3e 70 53 74  nalize(pCur->pSt
49a0: 6d 74 29 3b 0a 20 20 70 43 75 72 2d 3e 70 53 74  mt);.  pCur->pSt
49b0: 6d 74 20 3d 20 30 3b 0a 0a 20 20 2f 2a 20 50 72  mt = 0;..  /* Pr
49c0: 65 70 61 72 65 20 74 68 65 20 53 51 4c 20 73 74  epare the SQL st
49d0: 61 74 65 6d 65 6e 74 20 63 72 65 61 74 65 64 20  atement created 
49e0: 62 79 20 65 63 68 6f 42 65 73 74 49 6e 64 65 78  by echoBestIndex
49f0: 20 61 6e 64 20 62 69 6e 64 20 74 68 65 0a 20 20   and bind the.  
4a00: 2a 2a 20 72 75 6e 74 69 6d 65 20 70 61 72 61 6d  ** runtime param
4a10: 65 74 65 72 73 20 70 61 73 73 65 64 20 74 6f 20  eters passed to 
4a20: 74 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 74 6f  this function to
4a30: 20 69 74 2e 0a 20 20 2a 2f 0a 20 20 72 63 20 3d   it..  */.  rc =
4a40: 20 73 71 6c 69 74 65 33 5f 70 72 65 70 61 72 65   sqlite3_prepare
4a50: 28 64 62 2c 20 69 64 78 53 74 72 2c 20 2d 31 2c  (db, idxStr, -1,
4a60: 20 26 70 43 75 72 2d 3e 70 53 74 6d 74 2c 20 30   &pCur->pStmt, 0
4a70: 29 3b 0a 20 20 61 73 73 65 72 74 28 20 70 43 75  );.  assert( pCu
4a80: 72 2d 3e 70 53 74 6d 74 20 7c 7c 20 72 63 21 3d  r->pStmt || rc!=
4a90: 53 51 4c 49 54 45 5f 4f 4b 20 29 3b 0a 20 20 66  SQLITE_OK );.  f
4aa0: 6f 72 28 69 3d 30 3b 20 72 63 3d 3d 53 51 4c 49  or(i=0; rc==SQLI
4ab0: 54 45 5f 4f 4b 20 26 26 20 69 3c 61 72 67 63 3b  TE_OK && i<argc;
4ac0: 20 69 2b 2b 29 7b 0a 20 20 20 20 72 63 20 3d 20   i++){.    rc = 
4ad0: 73 71 6c 69 74 65 33 5f 62 69 6e 64 5f 76 61 6c  sqlite3_bind_val
4ae0: 75 65 28 70 43 75 72 2d 3e 70 53 74 6d 74 2c 20  ue(pCur->pStmt, 
4af0: 69 2b 31 2c 20 61 72 67 76 5b 69 5d 29 3b 0a 20  i+1, argv[i]);. 
4b00: 20 7d 0a 0a 20 20 2f 2a 20 49 66 20 65 76 65 72   }..  /* If ever
4b10: 79 74 68 69 6e 67 20 77 61 73 20 73 75 63 63 65  ything was succe
4b20: 73 73 66 75 6c 2c 20 61 64 76 61 6e 63 65 20 74  ssful, advance t
4b30: 6f 20 74 68 65 20 66 69 72 73 74 20 72 6f 77 20  o the first row 
4b40: 6f 66 20 74 68 65 20 73 63 61 6e 20 2a 2f 0a 20  of the scan */. 
4b50: 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
4b60: 4f 4b 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 65  OK ){.    rc = e
4b70: 63 68 6f 4e 65 78 74 28 70 56 74 61 62 43 75 72  choNext(pVtabCur
4b80: 73 6f 72 29 3b 0a 20 20 7d 0a 0a 20 20 72 65 74  sor);.  }..  ret
4b90: 75 72 6e 20 72 63 3b 0a 7d 0a 0a 0a 2f 2a 0a 2a  urn rc;.}.../*.*
4ba0: 2a 20 41 20 68 65 6c 70 65 72 20 66 75 6e 63 74  * A helper funct
4bb0: 69 6f 6e 20 75 73 65 64 20 62 79 20 65 63 68 6f  ion used by echo
4bc0: 55 70 64 61 74 65 28 29 20 61 6e 64 20 65 63 68  Update() and ech
4bd0: 6f 42 65 73 74 49 6e 64 65 78 28 29 20 66 6f 72  oBestIndex() for
4be0: 0a 2a 2a 20 6d 61 6e 69 70 75 6c 61 74 69 6e 67  .** manipulating
4bf0: 20 73 74 72 69 6e 67 73 20 69 6e 20 63 6f 6e 63   strings in conc
4c00: 65 72 74 20 77 69 74 68 20 74 68 65 20 73 71 6c  ert with the sql
4c10: 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 29 20 66  ite3_mprintf() f
4c20: 75 6e 63 74 69 6f 6e 2e 0a 2a 2a 0a 2a 2a 20 50  unction..**.** P
4c30: 61 72 61 6d 65 74 65 72 20 70 7a 53 74 72 20 70  arameter pzStr p
4c40: 6f 69 6e 74 73 20 74 6f 20 61 20 70 6f 69 6e 74  oints to a point
4c50: 65 72 20 74 6f 20 61 20 73 74 72 69 6e 67 20 61  er to a string a
4c60: 6c 6c 6f 63 61 74 65 64 20 77 69 74 68 0a 2a 2a  llocated with.**
4c70: 20 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66   sqlite3_mprintf
4c80: 2e 20 54 68 65 20 73 65 63 6f 6e 64 20 70 61 72  . The second par
4c90: 61 6d 65 74 65 72 2c 20 7a 41 70 70 65 6e 64 2c  ameter, zAppend,
4ca0: 20 70 6f 69 6e 74 73 20 74 6f 20 61 6e 6f 74 68   points to anoth
4cb0: 65 72 0a 2a 2a 20 73 74 72 69 6e 67 2e 20 54 68  er.** string. Th
4cc0: 65 20 74 77 6f 20 73 74 72 69 6e 67 73 20 61 72  e two strings ar
4cd0: 65 20 63 6f 6e 63 61 74 65 6e 61 74 65 64 20 74  e concatenated t
4ce0: 6f 67 65 74 68 65 72 20 61 6e 64 20 2a 70 7a 53  ogether and *pzS
4cf0: 74 72 0a 2a 2a 20 73 65 74 20 74 6f 20 70 6f 69  tr.** set to poi
4d00: 6e 74 20 61 74 20 74 68 65 20 72 65 73 75 6c 74  nt at the result
4d10: 2e 20 54 68 65 20 69 6e 69 74 69 61 6c 20 62 75  . The initial bu
4d20: 66 66 65 72 20 70 6f 69 6e 74 65 64 20 74 6f 20  ffer pointed to 
4d30: 62 79 20 2a 70 7a 53 74 72 0a 2a 2a 20 69 73 20  by *pzStr.** is 
4d40: 64 65 61 6c 6c 6f 63 61 74 65 64 20 76 69 61 20  deallocated via 
4d50: 73 71 6c 69 74 65 33 5f 66 72 65 65 28 29 2e 0a  sqlite3_free()..
4d60: 2a 2a 0a 2a 2a 20 49 66 20 74 68 65 20 74 68 69  **.** If the thi
4d70: 72 64 20 61 72 67 75 6d 65 6e 74 2c 20 64 6f 46  rd argument, doF
4d80: 72 65 65 2c 20 69 73 20 74 72 75 65 2c 20 74 68  ree, is true, th
4d90: 65 6e 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28  en sqlite3_free(
4da0: 29 20 69 73 0a 2a 2a 20 61 6c 73 6f 20 63 61 6c  ) is.** also cal
4db0: 6c 65 64 20 74 6f 20 66 72 65 65 20 74 68 65 20  led to free the 
4dc0: 62 75 66 66 65 72 20 70 6f 69 6e 74 65 64 20 74  buffer pointed t
4dd0: 6f 20 62 79 20 7a 41 70 70 65 6e 64 2e 0a 2a 2f  o by zAppend..*/
4de0: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 73 74 72  .static void str
4df0: 69 6e 67 5f 63 6f 6e 63 61 74 28 63 68 61 72 20  ing_concat(char 
4e00: 2a 2a 70 7a 53 74 72 2c 20 63 68 61 72 20 2a 7a  **pzStr, char *z
4e10: 41 70 70 65 6e 64 2c 20 69 6e 74 20 64 6f 46 72  Append, int doFr
4e20: 65 65 2c 20 69 6e 74 20 2a 70 52 63 29 7b 0a 20  ee, int *pRc){. 
4e30: 20 63 68 61 72 20 2a 7a 49 6e 20 3d 20 2a 70 7a   char *zIn = *pz
4e40: 53 74 72 3b 0a 20 20 69 66 28 20 21 7a 41 70 70  Str;.  if( !zApp
4e50: 65 6e 64 20 26 26 20 64 6f 46 72 65 65 20 26 26  end && doFree &&
4e60: 20 2a 70 52 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b   *pRc==SQLITE_OK
4e70: 20 29 7b 0a 20 20 20 20 2a 70 52 63 20 3d 20 53   ){.    *pRc = S
4e80: 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 7d  QLITE_NOMEM;.  }
4e90: 0a 20 20 69 66 28 20 2a 70 52 63 21 3d 53 51 4c  .  if( *pRc!=SQL
4ea0: 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 73 71  ITE_OK ){.    sq
4eb0: 6c 69 74 65 33 5f 66 72 65 65 28 7a 49 6e 29 3b  lite3_free(zIn);
4ec0: 0a 20 20 20 20 7a 49 6e 20 3d 20 30 3b 0a 20 20  .    zIn = 0;.  
4ed0: 7d 65 6c 73 65 7b 0a 20 20 20 20 69 66 28 20 7a  }else{.    if( z
4ee0: 49 6e 20 29 7b 0a 20 20 20 20 20 20 63 68 61 72  In ){.      char
4ef0: 20 2a 7a 54 65 6d 70 20 3d 20 7a 49 6e 3b 0a 20   *zTemp = zIn;. 
4f00: 20 20 20 20 20 7a 49 6e 20 3d 20 73 71 6c 69 74       zIn = sqlit
4f10: 65 33 5f 6d 70 72 69 6e 74 66 28 22 25 73 25 73  e3_mprintf("%s%s
4f20: 22 2c 20 7a 49 6e 2c 20 7a 41 70 70 65 6e 64 29  ", zIn, zAppend)
4f30: 3b 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f  ;.      sqlite3_
4f40: 66 72 65 65 28 7a 54 65 6d 70 29 3b 0a 20 20 20  free(zTemp);.   
4f50: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 7a 49   }else{.      zI
4f60: 6e 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72 69  n = sqlite3_mpri
4f70: 6e 74 66 28 22 25 73 22 2c 20 7a 41 70 70 65 6e  ntf("%s", zAppen
4f80: 64 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69 66  d);.    }.    if
4f90: 28 20 21 7a 49 6e 20 29 7b 0a 20 20 20 20 20 20  ( !zIn ){.      
4fa0: 2a 70 52 63 20 3d 20 53 51 4c 49 54 45 5f 4e 4f  *pRc = SQLITE_NO
4fb0: 4d 45 4d 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20  MEM;.    }.  }. 
4fc0: 20 2a 70 7a 53 74 72 20 3d 20 7a 49 6e 3b 0a 20   *pzStr = zIn;. 
4fd0: 20 69 66 28 20 64 6f 46 72 65 65 20 29 7b 0a 20   if( doFree ){. 
4fe0: 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28     sqlite3_free(
4ff0: 7a 41 70 70 65 6e 64 29 3b 0a 20 20 7d 0a 7d 0a  zAppend);.  }.}.
5000: 0a 2f 2a 0a 2a 2a 20 54 68 65 20 65 63 68 6f 20  ./*.** The echo 
5010: 6d 6f 64 75 6c 65 20 69 6d 70 6c 65 6d 65 6e 74  module implement
5020: 73 20 74 68 65 20 73 75 62 73 65 74 20 6f 66 20  s the subset of 
5030: 71 75 65 72 79 20 63 6f 6e 73 74 72 61 69 6e 74  query constraint
5040: 73 20 61 6e 64 20 73 6f 72 74 0a 2a 2a 20 6f 72  s and sort.** or
5050: 64 65 72 73 20 74 68 61 74 20 6d 61 79 20 74 61  ders that may ta
5060: 6b 65 20 61 64 76 61 6e 74 61 67 65 20 6f 66 20  ke advantage of 
5070: 53 51 4c 69 74 65 20 69 6e 64 69 63 65 73 20 6f  SQLite indices o
5080: 6e 20 74 68 65 20 75 6e 64 65 72 6c 79 69 6e 67  n the underlying
5090: 0a 2a 2a 20 72 65 61 6c 20 74 61 62 6c 65 2e 20  .** real table. 
50a0: 46 6f 72 20 65 78 61 6d 70 6c 65 2c 20 69 66 20  For example, if 
50b0: 74 68 65 20 72 65 61 6c 20 74 61 62 6c 65 20 69  the real table i
50c0: 73 20 64 65 63 6c 61 72 65 64 20 61 73 3a 0a 2a  s declared as:.*
50d0: 2a 0a 2a 2a 20 20 20 20 20 43 52 45 41 54 45 20  *.**     CREATE 
50e0: 54 41 42 4c 45 20 72 65 61 6c 28 61 2c 20 62 2c  TABLE real(a, b,
50f0: 20 63 29 3b 0a 2a 2a 20 20 20 20 20 43 52 45 41   c);.**     CREA
5100: 54 45 20 49 4e 44 45 58 20 72 65 61 6c 5f 69 6e  TE INDEX real_in
5110: 64 65 78 20 4f 4e 20 72 65 61 6c 28 62 29 3b 0a  dex ON real(b);.
5120: 2a 2a 0a 2a 2a 20 74 68 65 6e 20 74 68 65 20 65  **.** then the e
5130: 63 68 6f 20 6d 6f 64 75 6c 65 20 68 61 6e 64 6c  cho module handl
5140: 65 73 20 57 48 45 52 45 20 6f 72 20 4f 52 44 45  es WHERE or ORDE
5150: 52 20 42 59 20 63 6c 61 75 73 65 73 20 74 68 61  R BY clauses tha
5160: 74 20 72 65 66 65 72 0a 2a 2a 20 74 6f 20 74 68  t refer.** to th
5170: 65 20 63 6f 6c 75 6d 6e 20 22 62 22 2c 20 62 75  e column "b", bu
5180: 74 20 6e 6f 74 20 22 61 22 20 6f 72 20 22 63 22  t not "a" or "c"
5190: 2e 20 49 66 20 61 20 6d 75 6c 74 69 2d 63 6f 6c  . If a multi-col
51a0: 75 6d 6e 20 69 6e 64 65 78 20 69 73 0a 2a 2a 20  umn index is.** 
51b0: 70 72 65 73 65 6e 74 2c 20 6f 6e 6c 79 20 69 74  present, only it
51c0: 73 20 6c 65 66 74 20 6d 6f 73 74 20 63 6f 6c 75  s left most colu
51d0: 6d 6e 20 69 73 20 63 6f 6e 73 69 64 65 72 65 64  mn is considered
51e0: 2e 20 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20 78 42  . .**.** This xB
51f0: 65 73 74 49 6e 64 65 78 20 6d 65 74 68 6f 64 20  estIndex method 
5200: 65 6e 63 6f 64 65 73 20 74 68 65 20 70 72 6f 70  encodes the prop
5210: 6f 73 65 64 20 73 65 61 72 63 68 20 73 74 72 61  osed search stra
5220: 74 65 67 79 20 61 73 0a 2a 2a 20 61 6e 20 53 51  tegy as.** an SQ
5230: 4c 20 71 75 65 72 79 20 6f 6e 20 74 68 65 20 72  L query on the r
5240: 65 61 6c 20 74 61 62 6c 65 20 75 6e 64 65 72 6c  eal table underl
5250: 79 69 6e 67 20 74 68 65 20 76 69 72 74 75 61 6c  ying the virtual
5260: 20 65 63 68 6f 20 6d 6f 64 75 6c 65 20 0a 2a 2a   echo module .**
5270: 20 74 61 62 6c 65 20 61 6e 64 20 73 74 6f 72 65   table and store
5280: 73 20 74 68 65 20 71 75 65 72 79 20 69 6e 20 73  s the query in s
5290: 71 6c 69 74 65 33 5f 69 6e 64 65 78 5f 69 6e 66  qlite3_index_inf
52a0: 6f 2e 69 64 78 53 74 72 2e 20 54 68 65 20 53 51  o.idxStr. The SQ
52b0: 4c 0a 2a 2a 20 73 74 61 74 65 6d 65 6e 74 20 69  L.** statement i
52c0: 73 20 6f 66 20 74 68 65 20 66 6f 72 6d 3a 0a 2a  s of the form:.*
52d0: 2a 0a 2a 2a 20 20 20 53 45 4c 45 43 54 20 72 6f  *.**   SELECT ro
52e0: 77 69 64 2c 20 2a 20 46 52 4f 4d 20 3c 72 65 61  wid, * FROM <rea
52f0: 6c 2d 74 61 62 6c 65 3e 20 3f 3c 77 68 65 72 65  l-table> ?<where
5300: 2d 63 6c 61 75 73 65 3e 3f 20 3f 3c 6f 72 64 65  -clause>? ?<orde
5310: 72 2d 62 79 2d 63 6c 61 75 73 65 3e 3f 0a 2a 2a  r-by-clause>?.**
5320: 0a 2a 2a 20 77 68 65 72 65 20 74 68 65 20 3c 77  .** where the <w
5330: 68 65 72 65 2d 63 6c 61 75 73 65 3e 20 61 6e 64  here-clause> and
5340: 20 3c 6f 72 64 65 72 2d 62 79 2d 63 6c 61 75 73   <order-by-claus
5350: 65 3e 20 61 72 65 20 64 65 74 65 72 6d 69 6e 65  e> are determine
5360: 64 0a 2a 2a 20 62 79 20 74 68 65 20 63 6f 6e 74  d.** by the cont
5370: 65 6e 74 73 20 6f 66 20 74 68 65 20 73 74 72 75  ents of the stru
5380: 63 74 75 72 65 20 70 6f 69 6e 74 65 64 20 74 6f  cture pointed to
5390: 20 62 79 20 74 68 65 20 70 49 64 78 49 6e 66 6f   by the pIdxInfo
53a0: 20 61 72 67 75 6d 65 6e 74 2e 0a 2a 2f 0a 73 74   argument..*/.st
53b0: 61 74 69 63 20 69 6e 74 20 65 63 68 6f 42 65 73  atic int echoBes
53c0: 74 49 6e 64 65 78 28 73 71 6c 69 74 65 33 5f 76  tIndex(sqlite3_v
53d0: 74 61 62 20 2a 74 61 62 2c 20 73 71 6c 69 74 65  tab *tab, sqlite
53e0: 33 5f 69 6e 64 65 78 5f 69 6e 66 6f 20 2a 70 49  3_index_info *pI
53f0: 64 78 49 6e 66 6f 29 7b 0a 20 20 69 6e 74 20 69  dxInfo){.  int i
5400: 69 3b 0a 20 20 63 68 61 72 20 2a 7a 51 75 65 72  i;.  char *zQuer
5410: 79 20 3d 20 30 3b 0a 20 20 63 68 61 72 20 2a 7a  y = 0;.  char *z
5420: 4e 65 77 3b 0a 20 20 69 6e 74 20 6e 41 72 67 20  New;.  int nArg 
5430: 3d 20 30 3b 0a 20 20 63 6f 6e 73 74 20 63 68 61  = 0;.  const cha
5440: 72 20 2a 7a 53 65 70 20 3d 20 22 57 48 45 52 45  r *zSep = "WHERE
5450: 22 3b 0a 20 20 65 63 68 6f 5f 76 74 61 62 20 2a  ";.  echo_vtab *
5460: 70 56 74 61 62 20 3d 20 28 65 63 68 6f 5f 76 74  pVtab = (echo_vt
5470: 61 62 20 2a 29 74 61 62 3b 0a 20 20 73 71 6c 69  ab *)tab;.  sqli
5480: 74 65 33 5f 73 74 6d 74 20 2a 70 53 74 6d 74 20  te3_stmt *pStmt 
5490: 3d 20 30 3b 0a 20 20 54 63 6c 5f 49 6e 74 65 72  = 0;.  Tcl_Inter
54a0: 70 20 2a 69 6e 74 65 72 70 20 3d 20 70 56 74 61  p *interp = pVta
54b0: 62 2d 3e 69 6e 74 65 72 70 3b 0a 0a 20 20 69 6e  b->interp;..  in
54c0: 74 20 6e 52 6f 77 3b 0a 20 20 69 6e 74 20 75 73  t nRow;.  int us
54d0: 65 49 64 78 20 3d 20 30 3b 0a 20 20 69 6e 74 20  eIdx = 0;.  int 
54e0: 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a  rc = SQLITE_OK;.
54f0: 20 20 69 6e 74 20 75 73 65 43 6f 73 74 20 3d 20    int useCost = 
5500: 30 3b 0a 20 20 64 6f 75 62 6c 65 20 63 6f 73 74  0;.  double cost
5510: 3b 0a 20 20 69 6e 74 20 69 73 49 67 6e 6f 72 65  ;.  int isIgnore
5520: 55 73 61 62 6c 65 20 3d 20 30 3b 0a 20 20 69 66  Usable = 0;.  if
5530: 28 20 54 63 6c 5f 47 65 74 56 61 72 28 69 6e 74  ( Tcl_GetVar(int
5540: 65 72 70 2c 20 22 65 63 68 6f 5f 6d 6f 64 75 6c  erp, "echo_modul
5550: 65 5f 69 67 6e 6f 72 65 5f 75 73 61 62 6c 65 22  e_ignore_usable"
5560: 2c 20 54 43 4c 5f 47 4c 4f 42 41 4c 5f 4f 4e 4c  , TCL_GLOBAL_ONL
5570: 59 29 20 29 7b 0a 20 20 20 20 69 73 49 67 6e 6f  Y) ){.    isIgno
5580: 72 65 55 73 61 62 6c 65 20 3d 20 31 3b 0a 20 20  reUsable = 1;.  
5590: 7d 0a 0a 20 20 69 66 28 20 73 69 6d 75 6c 61 74  }..  if( simulat
55a0: 65 56 74 61 62 45 72 72 6f 72 28 70 56 74 61 62  eVtabError(pVtab
55b0: 2c 20 22 78 42 65 73 74 49 6e 64 65 78 22 29 20  , "xBestIndex") 
55c0: 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 53 51  ){.    return SQ
55d0: 4c 49 54 45 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a  LITE_ERROR;.  }.
55e0: 0a 20 20 2f 2a 20 44 65 74 65 72 6d 69 6e 65 20  .  /* Determine 
55f0: 74 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 72 6f  the number of ro
5600: 77 73 20 69 6e 20 74 68 65 20 74 61 62 6c 65 20  ws in the table 
5610: 61 6e 64 20 73 74 6f 72 65 20 74 68 69 73 20 76  and store this v
5620: 61 6c 75 65 20 69 6e 20 6c 6f 63 61 6c 0a 20 20  alue in local.  
5630: 2a 2a 20 76 61 72 69 61 62 6c 65 20 6e 52 6f 77  ** variable nRow
5640: 2e 20 54 68 65 20 27 65 73 74 69 6d 61 74 65 64  . The 'estimated
5650: 2d 63 6f 73 74 27 20 6f 66 20 74 68 65 20 73 63  -cost' of the sc
5660: 61 6e 20 77 69 6c 6c 20 62 65 20 74 68 65 20 6e  an will be the n
5670: 75 6d 62 65 72 20 6f 66 0a 20 20 2a 2a 20 72 6f  umber of.  ** ro
5680: 77 73 20 69 6e 20 74 68 65 20 74 61 62 6c 65 20  ws in the table 
5690: 66 6f 72 20 61 20 6c 69 6e 65 61 72 20 73 63 61  for a linear sca
56a0: 6e 2c 20 6f 72 20 74 68 65 20 6c 6f 67 20 28 62  n, or the log (b
56b0: 61 73 65 20 32 29 20 6f 66 20 74 68 65 20 0a 20  ase 2) of the . 
56c0: 20 2a 2a 20 6e 75 6d 62 65 72 20 6f 66 20 72 6f   ** number of ro
56d0: 77 73 20 69 66 20 74 68 65 20 70 72 6f 70 6f 73  ws if the propos
56e0: 65 64 20 73 63 61 6e 20 75 73 65 73 20 61 6e 20  ed scan uses an 
56f0: 69 6e 64 65 78 2e 20 20 0a 20 20 2a 2f 0a 20 20  index.  .  */.  
5700: 69 66 28 20 54 63 6c 5f 47 65 74 56 61 72 28 69  if( Tcl_GetVar(i
5710: 6e 74 65 72 70 2c 20 22 65 63 68 6f 5f 6d 6f 64  nterp, "echo_mod
5720: 75 6c 65 5f 63 6f 73 74 22 2c 20 54 43 4c 5f 47  ule_cost", TCL_G
5730: 4c 4f 42 41 4c 5f 4f 4e 4c 59 29 20 29 7b 0a 20  LOBAL_ONLY) ){. 
5740: 20 20 20 63 6f 73 74 20 3d 20 61 74 6f 66 28 54     cost = atof(T
5750: 63 6c 5f 47 65 74 56 61 72 28 69 6e 74 65 72 70  cl_GetVar(interp
5760: 2c 20 22 65 63 68 6f 5f 6d 6f 64 75 6c 65 5f 63  , "echo_module_c
5770: 6f 73 74 22 2c 20 54 43 4c 5f 47 4c 4f 42 41 4c  ost", TCL_GLOBAL
5780: 5f 4f 4e 4c 59 29 29 3b 0a 20 20 20 20 75 73 65  _ONLY));.    use
5790: 43 6f 73 74 20 3d 20 31 3b 0a 20 20 7d 20 65 6c  Cost = 1;.  } el
57a0: 73 65 20 7b 0a 20 20 20 20 7a 51 75 65 72 79 20  se {.    zQuery 
57b0: 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74  = sqlite3_mprint
57c0: 66 28 22 53 45 4c 45 43 54 20 63 6f 75 6e 74 28  f("SELECT count(
57d0: 2a 29 20 46 52 4f 4d 20 25 51 22 2c 20 70 56 74  *) FROM %Q", pVt
57e0: 61 62 2d 3e 7a 54 61 62 6c 65 4e 61 6d 65 29 3b  ab->zTableName);
57f0: 0a 20 20 20 20 69 66 28 20 21 7a 51 75 65 72 79  .    if( !zQuery
5800: 20 29 7b 0a 20 20 20 20 20 20 72 65 74 75 72 6e   ){.      return
5810: 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20   SQLITE_NOMEM;. 
5820: 20 20 20 7d 0a 20 20 20 20 72 63 20 3d 20 73 71     }.    rc = sq
5830: 6c 69 74 65 33 5f 70 72 65 70 61 72 65 28 70 56  lite3_prepare(pV
5840: 74 61 62 2d 3e 64 62 2c 20 7a 51 75 65 72 79 2c  tab->db, zQuery,
5850: 20 2d 31 2c 20 26 70 53 74 6d 74 2c 20 30 29 3b   -1, &pStmt, 0);
5860: 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65  .    sqlite3_fre
5870: 65 28 7a 51 75 65 72 79 29 3b 0a 20 20 20 20 69  e(zQuery);.    i
5880: 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc!=SQLITE_OK
5890: 20 29 7b 0a 20 20 20 20 20 20 72 65 74 75 72 6e   ){.      return
58a0: 20 72 63 3b 0a 20 20 20 20 7d 0a 20 20 20 20 73   rc;.    }.    s
58b0: 71 6c 69 74 65 33 5f 73 74 65 70 28 70 53 74 6d  qlite3_step(pStm
58c0: 74 29 3b 0a 20 20 20 20 6e 52 6f 77 20 3d 20 73  t);.    nRow = s
58d0: 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 69 6e  qlite3_column_in
58e0: 74 28 70 53 74 6d 74 2c 20 30 29 3b 0a 20 20 20  t(pStmt, 0);.   
58f0: 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 66 69   rc = sqlite3_fi
5900: 6e 61 6c 69 7a 65 28 70 53 74 6d 74 29 3b 0a 20  nalize(pStmt);. 
5910: 20 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54     if( rc!=SQLIT
5920: 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 72 65  E_OK ){.      re
5930: 74 75 72 6e 20 72 63 3b 0a 20 20 20 20 7d 0a 20  turn rc;.    }. 
5940: 20 7d 0a 0a 20 20 7a 51 75 65 72 79 20 3d 20 73   }..  zQuery = s
5950: 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 22  qlite3_mprintf("
5960: 53 45 4c 45 43 54 20 72 6f 77 69 64 2c 20 2a 20  SELECT rowid, * 
5970: 46 52 4f 4d 20 25 51 22 2c 20 70 56 74 61 62 2d  FROM %Q", pVtab-
5980: 3e 7a 54 61 62 6c 65 4e 61 6d 65 29 3b 0a 20 20  >zTableName);.  
5990: 69 66 28 20 21 7a 51 75 65 72 79 20 29 7b 0a 20  if( !zQuery ){. 
59a0: 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45     return SQLITE
59b0: 5f 4e 4f 4d 45 4d 3b 0a 20 20 7d 0a 20 20 66 6f  _NOMEM;.  }.  fo
59c0: 72 28 69 69 3d 30 3b 20 69 69 3c 70 49 64 78 49  r(ii=0; ii<pIdxI
59d0: 6e 66 6f 2d 3e 6e 43 6f 6e 73 74 72 61 69 6e 74  nfo->nConstraint
59e0: 3b 20 69 69 2b 2b 29 7b 0a 20 20 20 20 63 6f 6e  ; ii++){.    con
59f0: 73 74 20 73 74 72 75 63 74 20 73 71 6c 69 74 65  st struct sqlite
5a00: 33 5f 69 6e 64 65 78 5f 63 6f 6e 73 74 72 61 69  3_index_constrai
5a10: 6e 74 20 2a 70 43 6f 6e 73 74 72 61 69 6e 74 3b  nt *pConstraint;
5a20: 0a 20 20 20 20 73 74 72 75 63 74 20 73 71 6c 69  .    struct sqli
5a30: 74 65 33 5f 69 6e 64 65 78 5f 63 6f 6e 73 74 72  te3_index_constr
5a40: 61 69 6e 74 5f 75 73 61 67 65 20 2a 70 55 73 61  aint_usage *pUsa
5a50: 67 65 3b 0a 20 20 20 20 69 6e 74 20 69 43 6f 6c  ge;.    int iCol
5a60: 3b 0a 0a 20 20 20 20 70 43 6f 6e 73 74 72 61 69  ;..    pConstrai
5a70: 6e 74 20 3d 20 26 70 49 64 78 49 6e 66 6f 2d 3e  nt = &pIdxInfo->
5a80: 61 43 6f 6e 73 74 72 61 69 6e 74 5b 69 69 5d 3b  aConstraint[ii];
5a90: 0a 20 20 20 20 70 55 73 61 67 65 20 3d 20 26 70  .    pUsage = &p
5aa0: 49 64 78 49 6e 66 6f 2d 3e 61 43 6f 6e 73 74 72  IdxInfo->aConstr
5ab0: 61 69 6e 74 55 73 61 67 65 5b 69 69 5d 3b 0a 0a  aintUsage[ii];..
5ac0: 20 20 20 20 69 66 28 20 21 69 73 49 67 6e 6f 72      if( !isIgnor
5ad0: 65 55 73 61 62 6c 65 20 26 26 20 21 70 43 6f 6e  eUsable && !pCon
5ae0: 73 74 72 61 69 6e 74 2d 3e 75 73 61 62 6c 65 20  straint->usable 
5af0: 29 20 63 6f 6e 74 69 6e 75 65 3b 0a 0a 20 20 20  ) continue;..   
5b00: 20 69 43 6f 6c 20 3d 20 70 43 6f 6e 73 74 72 61   iCol = pConstra
5b10: 69 6e 74 2d 3e 69 43 6f 6c 75 6d 6e 3b 0a 20 20  int->iColumn;.  
5b20: 20 20 69 66 28 20 69 43 6f 6c 3c 30 20 7c 7c 20    if( iCol<0 || 
5b30: 70 56 74 61 62 2d 3e 61 49 6e 64 65 78 5b 69 43  pVtab->aIndex[iC
5b40: 6f 6c 5d 20 29 7b 0a 20 20 20 20 20 20 63 68 61  ol] ){.      cha
5b50: 72 20 2a 7a 43 6f 6c 20 3d 20 69 43 6f 6c 3e 3d  r *zCol = iCol>=
5b60: 30 20 3f 20 70 56 74 61 62 2d 3e 61 43 6f 6c 5b  0 ? pVtab->aCol[
5b70: 69 43 6f 6c 5d 20 3a 20 22 72 6f 77 69 64 22 3b  iCol] : "rowid";
5b80: 0a 20 20 20 20 20 20 63 68 61 72 20 2a 7a 4f 70  .      char *zOp
5b90: 20 3d 20 30 3b 0a 20 20 20 20 20 20 75 73 65 49   = 0;.      useI
5ba0: 64 78 20 3d 20 31 3b 0a 20 20 20 20 20 20 73 77  dx = 1;.      sw
5bb0: 69 74 63 68 28 20 70 43 6f 6e 73 74 72 61 69 6e  itch( pConstrain
5bc0: 74 2d 3e 6f 70 20 29 7b 0a 20 20 20 20 20 20 20  t->op ){.       
5bd0: 20 63 61 73 65 20 53 51 4c 49 54 45 5f 49 4e 44   case SQLITE_IND
5be0: 45 58 5f 43 4f 4e 53 54 52 41 49 4e 54 5f 45 51  EX_CONSTRAINT_EQ
5bf0: 3a 0a 20 20 20 20 20 20 20 20 20 20 7a 4f 70 20  :.          zOp 
5c00: 3d 20 22 3d 22 3b 20 62 72 65 61 6b 3b 0a 20 20  = "="; break;.  
5c10: 20 20 20 20 20 20 63 61 73 65 20 53 51 4c 49 54        case SQLIT
5c20: 45 5f 49 4e 44 45 58 5f 43 4f 4e 53 54 52 41 49  E_INDEX_CONSTRAI
5c30: 4e 54 5f 4c 54 3a 0a 20 20 20 20 20 20 20 20 20  NT_LT:.         
5c40: 20 7a 4f 70 20 3d 20 22 3c 22 3b 20 62 72 65 61   zOp = "<"; brea
5c50: 6b 3b 0a 20 20 20 20 20 20 20 20 63 61 73 65 20  k;.        case 
5c60: 53 51 4c 49 54 45 5f 49 4e 44 45 58 5f 43 4f 4e  SQLITE_INDEX_CON
5c70: 53 54 52 41 49 4e 54 5f 47 54 3a 0a 20 20 20 20  STRAINT_GT:.    
5c80: 20 20 20 20 20 20 7a 4f 70 20 3d 20 22 3e 22 3b        zOp = ">";
5c90: 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 20 20   break;.        
5ca0: 63 61 73 65 20 53 51 4c 49 54 45 5f 49 4e 44 45  case SQLITE_INDE
5cb0: 58 5f 43 4f 4e 53 54 52 41 49 4e 54 5f 4c 45 3a  X_CONSTRAINT_LE:
5cc0: 0a 20 20 20 20 20 20 20 20 20 20 7a 4f 70 20 3d  .          zOp =
5cd0: 20 22 3c 3d 22 3b 20 62 72 65 61 6b 3b 0a 20 20   "<="; break;.  
5ce0: 20 20 20 20 20 20 63 61 73 65 20 53 51 4c 49 54        case SQLIT
5cf0: 45 5f 49 4e 44 45 58 5f 43 4f 4e 53 54 52 41 49  E_INDEX_CONSTRAI
5d00: 4e 54 5f 47 45 3a 0a 20 20 20 20 20 20 20 20 20  NT_GE:.         
5d10: 20 7a 4f 70 20 3d 20 22 3e 3d 22 3b 20 62 72 65   zOp = ">="; bre
5d20: 61 6b 3b 0a 20 20 20 20 20 20 20 20 63 61 73 65  ak;.        case
5d30: 20 53 51 4c 49 54 45 5f 49 4e 44 45 58 5f 43 4f   SQLITE_INDEX_CO
5d40: 4e 53 54 52 41 49 4e 54 5f 4d 41 54 43 48 3a 0a  NSTRAINT_MATCH:.
5d50: 20 20 20 20 20 20 20 20 20 20 7a 4f 70 20 3d 20            zOp = 
5d60: 22 4c 49 4b 45 22 3b 20 62 72 65 61 6b 3b 0a 20  "LIKE"; break;. 
5d70: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 69 66 28       }.      if(
5d80: 20 7a 4f 70 5b 30 5d 3d 3d 27 4c 27 20 29 7b 0a   zOp[0]=='L' ){.
5d90: 20 20 20 20 20 20 20 20 7a 4e 65 77 20 3d 20 73          zNew = s
5da0: 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 22  qlite3_mprintf("
5db0: 20 25 73 20 25 73 20 4c 49 4b 45 20 28 53 45 4c   %s %s LIKE (SEL
5dc0: 45 43 54 20 27 25 25 27 7c 7c 3f 7c 7c 27 25 25  ECT '%%'||?||'%%
5dd0: 27 29 22 2c 20 0a 20 20 20 20 20 20 20 20 20 20  ')", .          
5de0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5df0: 20 20 20 20 20 7a 53 65 70 2c 20 7a 43 6f 6c 29       zSep, zCol)
5e00: 3b 0a 20 20 20 20 20 20 7d 20 65 6c 73 65 20 7b  ;.      } else {
5e10: 0a 20 20 20 20 20 20 20 20 7a 4e 65 77 20 3d 20  .        zNew = 
5e20: 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28  sqlite3_mprintf(
5e30: 22 20 25 73 20 25 73 20 25 73 20 3f 22 2c 20 7a  " %s %s %s ?", z
5e40: 53 65 70 2c 20 7a 43 6f 6c 2c 20 7a 4f 70 29 3b  Sep, zCol, zOp);
5e50: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 73  .      }.      s
5e60: 74 72 69 6e 67 5f 63 6f 6e 63 61 74 28 26 7a 51  tring_concat(&zQ
5e70: 75 65 72 79 2c 20 7a 4e 65 77 2c 20 31 2c 20 26  uery, zNew, 1, &
5e80: 72 63 29 3b 0a 0a 20 20 20 20 20 20 7a 53 65 70  rc);..      zSep
5e90: 20 3d 20 22 41 4e 44 22 3b 0a 20 20 20 20 20 20   = "AND";.      
5ea0: 70 55 73 61 67 65 2d 3e 61 72 67 76 49 6e 64 65  pUsage->argvInde
5eb0: 78 20 3d 20 2b 2b 6e 41 72 67 3b 0a 20 20 20 20  x = ++nArg;.    
5ec0: 20 20 70 55 73 61 67 65 2d 3e 6f 6d 69 74 20 3d    pUsage->omit =
5ed0: 20 31 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20   1;.    }.  }.. 
5ee0: 20 2f 2a 20 49 66 20 74 68 65 72 65 20 69 73 20   /* If there is 
5ef0: 6f 6e 6c 79 20 6f 6e 65 20 74 65 72 6d 20 69 6e  only one term in
5f00: 20 74 68 65 20 4f 52 44 45 52 20 42 59 20 63 6c   the ORDER BY cl
5f10: 61 75 73 65 2c 20 61 6e 64 20 69 74 20 69 73 0a  ause, and it is.
5f20: 20 20 2a 2a 20 6f 6e 20 61 20 63 6f 6c 75 6d 6e    ** on a column
5f30: 20 74 68 61 74 20 74 68 69 73 20 76 69 72 74 75   that this virtu
5f40: 61 6c 20 74 61 62 6c 65 20 68 61 73 20 61 6e 20  al table has an 
5f50: 69 6e 64 65 78 20 66 6f 72 2c 20 74 68 65 6e 20  index for, then 
5f60: 63 6f 6e 73 75 6d 65 20 0a 20 20 2a 2a 20 74 68  consume .  ** th
5f70: 65 20 4f 52 44 45 52 20 42 59 20 63 6c 61 75 73  e ORDER BY claus
5f80: 65 2e 0a 20 20 2a 2f 0a 20 20 69 66 28 20 70 49  e..  */.  if( pI
5f90: 64 78 49 6e 66 6f 2d 3e 6e 4f 72 64 65 72 42 79  dxInfo->nOrderBy
5fa0: 3d 3d 31 20 26 26 20 28 0a 20 20 20 20 20 20 20  ==1 && (.       
5fb0: 20 70 49 64 78 49 6e 66 6f 2d 3e 61 4f 72 64 65   pIdxInfo->aOrde
5fc0: 72 42 79 2d 3e 69 43 6f 6c 75 6d 6e 3c 30 20 7c  rBy->iColumn<0 |
5fd0: 7c 0a 20 20 20 20 20 20 20 20 70 56 74 61 62 2d  |.        pVtab-
5fe0: 3e 61 49 6e 64 65 78 5b 70 49 64 78 49 6e 66 6f  >aIndex[pIdxInfo
5ff0: 2d 3e 61 4f 72 64 65 72 42 79 2d 3e 69 43 6f 6c  ->aOrderBy->iCol
6000: 75 6d 6e 5d 29 20 29 7b 0a 20 20 20 20 69 6e 74  umn]) ){.    int
6010: 20 69 43 6f 6c 20 3d 20 70 49 64 78 49 6e 66 6f   iCol = pIdxInfo
6020: 2d 3e 61 4f 72 64 65 72 42 79 2d 3e 69 43 6f 6c  ->aOrderBy->iCol
6030: 75 6d 6e 3b 0a 20 20 20 20 63 68 61 72 20 2a 7a  umn;.    char *z
6040: 43 6f 6c 20 3d 20 69 43 6f 6c 3e 3d 30 20 3f 20  Col = iCol>=0 ? 
6050: 70 56 74 61 62 2d 3e 61 43 6f 6c 5b 69 43 6f 6c  pVtab->aCol[iCol
6060: 5d 20 3a 20 22 72 6f 77 69 64 22 3b 0a 20 20 20  ] : "rowid";.   
6070: 20 63 68 61 72 20 2a 7a 44 69 72 20 3d 20 70 49   char *zDir = pI
6080: 64 78 49 6e 66 6f 2d 3e 61 4f 72 64 65 72 42 79  dxInfo->aOrderBy
6090: 2d 3e 64 65 73 63 3f 22 44 45 53 43 22 3a 22 41  ->desc?"DESC":"A
60a0: 53 43 22 3b 0a 20 20 20 20 7a 4e 65 77 20 3d 20  SC";.    zNew = 
60b0: 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28  sqlite3_mprintf(
60c0: 22 20 4f 52 44 45 52 20 42 59 20 25 73 20 25 73  " ORDER BY %s %s
60d0: 22 2c 20 7a 43 6f 6c 2c 20 7a 44 69 72 29 3b 0a  ", zCol, zDir);.
60e0: 20 20 20 20 73 74 72 69 6e 67 5f 63 6f 6e 63 61      string_conca
60f0: 74 28 26 7a 51 75 65 72 79 2c 20 7a 4e 65 77 2c  t(&zQuery, zNew,
6100: 20 31 2c 20 26 72 63 29 3b 0a 20 20 20 20 70 49   1, &rc);.    pI
6110: 64 78 49 6e 66 6f 2d 3e 6f 72 64 65 72 42 79 43  dxInfo->orderByC
6120: 6f 6e 73 75 6d 65 64 20 3d 20 31 3b 0a 20 20 7d  onsumed = 1;.  }
6130: 0a 0a 20 20 61 70 70 65 6e 64 54 6f 45 63 68 6f  ..  appendToEcho
6140: 4d 6f 64 75 6c 65 28 70 56 74 61 62 2d 3e 69 6e  Module(pVtab->in
6150: 74 65 72 70 2c 20 22 78 42 65 73 74 49 6e 64 65  terp, "xBestInde
6160: 78 22 29 3b 3b 0a 20 20 61 70 70 65 6e 64 54 6f  x");;.  appendTo
6170: 45 63 68 6f 4d 6f 64 75 6c 65 28 70 56 74 61 62  EchoModule(pVtab
6180: 2d 3e 69 6e 74 65 72 70 2c 20 7a 51 75 65 72 79  ->interp, zQuery
6190: 29 3b 0a 0a 20 20 69 66 28 20 21 7a 51 75 65 72  );..  if( !zQuer
61a0: 79 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20  y ){.    return 
61b0: 72 63 3b 0a 20 20 7d 0a 20 20 70 49 64 78 49 6e  rc;.  }.  pIdxIn
61c0: 66 6f 2d 3e 69 64 78 4e 75 6d 20 3d 20 68 61 73  fo->idxNum = has
61d0: 68 53 74 72 69 6e 67 28 7a 51 75 65 72 79 29 3b  hString(zQuery);
61e0: 0a 20 20 70 49 64 78 49 6e 66 6f 2d 3e 69 64 78  .  pIdxInfo->idx
61f0: 53 74 72 20 3d 20 7a 51 75 65 72 79 3b 0a 20 20  Str = zQuery;.  
6200: 70 49 64 78 49 6e 66 6f 2d 3e 6e 65 65 64 54 6f  pIdxInfo->needTo
6210: 46 72 65 65 49 64 78 53 74 72 20 3d 20 31 3b 0a  FreeIdxStr = 1;.
6220: 20 20 69 66 28 20 75 73 65 43 6f 73 74 20 29 7b    if( useCost ){
6230: 0a 20 20 20 20 70 49 64 78 49 6e 66 6f 2d 3e 65  .    pIdxInfo->e
6240: 73 74 69 6d 61 74 65 64 43 6f 73 74 20 3d 20 63  stimatedCost = c
6250: 6f 73 74 3b 0a 20 20 7d 65 6c 73 65 20 69 66 28  ost;.  }else if(
6260: 20 75 73 65 49 64 78 20 29 7b 0a 20 20 20 20 2f   useIdx ){.    /
6270: 2a 20 41 70 70 72 6f 78 69 6d 61 74 69 6f 6e 20  * Approximation 
6280: 6f 66 20 6c 6f 67 32 28 6e 52 6f 77 29 2e 20 2a  of log2(nRow). *
6290: 2f 0a 20 20 20 20 66 6f 72 28 20 69 69 3d 30 3b  /.    for( ii=0;
62a0: 20 69 69 3c 28 73 69 7a 65 6f 66 28 69 6e 74 29   ii<(sizeof(int)
62b0: 2a 38 29 3b 20 69 69 2b 2b 20 29 7b 0a 20 20 20  *8); ii++ ){.   
62c0: 20 20 20 69 66 28 20 6e 52 6f 77 20 26 20 28 31     if( nRow & (1
62d0: 3c 3c 69 69 29 20 29 7b 0a 20 20 20 20 20 20 20  <<ii) ){.       
62e0: 20 70 49 64 78 49 6e 66 6f 2d 3e 65 73 74 69 6d   pIdxInfo->estim
62f0: 61 74 65 64 43 6f 73 74 20 3d 20 28 64 6f 75 62  atedCost = (doub
6300: 6c 65 29 69 69 3b 0a 20 20 20 20 20 20 7d 0a 20  le)ii;.      }. 
6310: 20 20 20 7d 0a 20 20 7d 65 6c 73 65 7b 0a 20 20     }.  }else{.  
6320: 20 20 70 49 64 78 49 6e 66 6f 2d 3e 65 73 74 69    pIdxInfo->esti
6330: 6d 61 74 65 64 43 6f 73 74 20 3d 20 28 64 6f 75  matedCost = (dou
6340: 62 6c 65 29 6e 52 6f 77 3b 0a 20 20 7d 0a 20 20  ble)nRow;.  }.  
6350: 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a  return rc;.}../*
6360: 0a 2a 2a 20 54 68 65 20 78 55 70 64 61 74 65 20  .** The xUpdate 
6370: 6d 65 74 68 6f 64 20 66 6f 72 20 65 63 68 6f 20  method for echo 
6380: 6d 6f 64 75 6c 65 20 76 69 72 74 75 61 6c 20 74  module virtual t
6390: 61 62 6c 65 73 2e 0a 2a 2a 20 0a 2a 2a 20 20 20  ables..** .**   
63a0: 20 61 70 44 61 74 61 5b 30 5d 20 20 61 70 44 61   apData[0]  apDa
63b0: 74 61 5b 31 5d 20 20 61 70 44 61 74 61 5b 32 2e  ta[1]  apData[2.
63c0: 2e 5d 0a 2a 2a 0a 2a 2a 20 20 20 20 49 4e 54 45  .].**.**    INTE
63d0: 47 45 52 20 20 20 20 20 20 20 20 20 20 20 20 20  GER             
63e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
63f0: 20 44 45 4c 45 54 45 20 20 20 20 20 20 20 20 20   DELETE         
6400: 20 20 20 0a 2a 2a 0a 2a 2a 20 20 20 20 49 4e 54     .**.**    INT
6410: 45 47 45 52 20 20 20 20 4e 55 4c 4c 20 20 20 20  EGER    NULL    
6420: 20 20 20 28 6e 43 6f 6c 20 61 72 67 73 29 20 20     (nCol args)  
6430: 20 20 55 50 44 41 54 45 20 28 64 6f 20 6e 6f 74    UPDATE (do not
6440: 20 73 65 74 20 72 6f 77 69 64 29 0a 2a 2a 20 20   set rowid).**  
6450: 20 20 49 4e 54 45 47 45 52 20 20 20 20 49 4e 54    INTEGER    INT
6460: 45 47 45 52 20 20 20 20 28 6e 43 6f 6c 20 61 72  EGER    (nCol ar
6470: 67 73 29 20 20 20 20 55 50 44 41 54 45 20 28 77  gs)    UPDATE (w
6480: 69 74 68 20 53 45 54 20 72 6f 77 69 64 20 3d 20  ith SET rowid = 
6490: 3c 61 72 67 31 3e 29 0a 2a 2a 0a 2a 2a 20 20 20  <arg1>).**.**   
64a0: 20 4e 55 4c 4c 20 20 20 20 20 20 20 4e 55 4c 4c   NULL       NULL
64b0: 20 20 20 20 20 20 20 28 6e 43 6f 6c 20 61 72 67         (nCol arg
64c0: 73 29 20 20 20 20 49 4e 53 45 52 54 20 49 4e 54  s)    INSERT INT
64d0: 4f 20 28 61 75 74 6f 6d 61 74 69 63 20 72 6f 77  O (automatic row
64e0: 69 64 20 76 61 6c 75 65 29 0a 2a 2a 20 20 20 20  id value).**    
64f0: 4e 55 4c 4c 20 20 20 20 20 20 20 49 4e 54 45 47  NULL       INTEG
6500: 45 52 20 20 20 20 28 6e 43 6f 6c 20 61 72 67 73  ER    (nCol args
6510: 29 20 20 20 20 49 4e 53 45 52 54 20 28 69 6e 63  )    INSERT (inc
6520: 6c 2e 20 72 6f 77 69 64 20 76 61 6c 75 65 29 0a  l. rowid value).
6530: 2a 2a 0a 2a 2f 0a 69 6e 74 20 65 63 68 6f 55 70  **.*/.int echoUp
6540: 64 61 74 65 28 0a 20 20 73 71 6c 69 74 65 33 5f  date(.  sqlite3_
6550: 76 74 61 62 20 2a 74 61 62 2c 20 0a 20 20 69 6e  vtab *tab, .  in
6560: 74 20 6e 44 61 74 61 2c 20 0a 20 20 73 71 6c 69  t nData, .  sqli
6570: 74 65 33 5f 76 61 6c 75 65 20 2a 2a 61 70 44 61  te3_value **apDa
6580: 74 61 2c 20 0a 20 20 73 71 6c 69 74 65 5f 69 6e  ta, .  sqlite_in
6590: 74 36 34 20 2a 70 52 6f 77 69 64 0a 29 7b 0a 20  t64 *pRowid.){. 
65a0: 20 65 63 68 6f 5f 76 74 61 62 20 2a 70 56 74 61   echo_vtab *pVta
65b0: 62 20 3d 20 28 65 63 68 6f 5f 76 74 61 62 20 2a  b = (echo_vtab *
65c0: 29 74 61 62 3b 0a 20 20 73 71 6c 69 74 65 33 20  )tab;.  sqlite3 
65d0: 2a 64 62 20 3d 20 70 56 74 61 62 2d 3e 64 62 3b  *db = pVtab->db;
65e0: 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49  .  int rc = SQLI
65f0: 54 45 5f 4f 4b 3b 0a 0a 20 20 73 71 6c 69 74 65  TE_OK;..  sqlite
6600: 33 5f 73 74 6d 74 20 2a 70 53 74 6d 74 3b 0a 20  3_stmt *pStmt;. 
6610: 20 63 68 61 72 20 2a 7a 20 3d 20 30 3b 20 20 20   char *z = 0;   
6620: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53              /* S
6630: 51 4c 20 73 74 61 74 65 6d 65 6e 74 20 74 6f 20  QL statement to 
6640: 65 78 65 63 75 74 65 20 2a 2f 0a 20 20 69 6e 74  execute */.  int
6650: 20 62 69 6e 64 41 72 67 5a 65 72 6f 20 3d 20 30   bindArgZero = 0
6660: 3b 20 20 20 20 20 20 20 2f 2a 20 54 72 75 65 20  ;       /* True 
6670: 74 6f 20 62 69 6e 64 20 61 70 44 61 74 61 5b 30  to bind apData[0
6680: 5d 20 74 6f 20 73 71 6c 20 76 61 72 20 6e 6f 2e  ] to sql var no.
6690: 20 6e 44 61 74 61 20 2a 2f 0a 20 20 69 6e 74 20   nData */.  int 
66a0: 62 69 6e 64 41 72 67 4f 6e 65 20 3d 20 30 3b 20  bindArgOne = 0; 
66b0: 20 20 20 20 20 20 20 2f 2a 20 54 72 75 65 20 74         /* True t
66c0: 6f 20 62 69 6e 64 20 61 70 44 61 74 61 5b 31 5d  o bind apData[1]
66d0: 20 74 6f 20 73 71 6c 20 76 61 72 20 6e 6f 2e 20   to sql var no. 
66e0: 31 20 2a 2f 0a 20 20 69 6e 74 20 69 3b 20 20 20  1 */.  int i;   
66f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6700: 20 20 2f 2a 20 43 6f 75 6e 74 65 72 20 76 61 72    /* Counter var
6710: 69 61 62 6c 65 20 75 73 65 64 20 62 79 20 66 6f  iable used by fo
6720: 72 20 6c 6f 6f 70 73 20 2a 2f 0a 0a 20 20 61 73  r loops */..  as
6730: 73 65 72 74 28 20 6e 44 61 74 61 3d 3d 70 56 74  sert( nData==pVt
6740: 61 62 2d 3e 6e 43 6f 6c 2b 32 20 7c 7c 20 6e 44  ab->nCol+2 || nD
6750: 61 74 61 3d 3d 31 20 29 3b 0a 0a 20 20 2f 2a 20  ata==1 );..  /* 
6760: 54 69 63 6b 65 74 20 23 33 30 38 33 20 2d 20 6d  Ticket #3083 - m
6770: 61 6b 65 20 73 75 72 65 20 77 65 20 61 6c 77 61  ake sure we alwa
6780: 79 73 20 73 74 61 72 74 20 61 20 74 72 61 6e 73  ys start a trans
6790: 61 63 74 69 6f 6e 20 70 72 69 6f 72 20 74 6f 0a  action prior to.
67a0: 20 20 2a 2a 20 6d 61 6b 69 6e 67 20 61 6e 79 20    ** making any 
67b0: 63 68 61 6e 67 65 73 20 74 6f 20 61 20 76 69 72  changes to a vir
67c0: 74 75 61 6c 20 74 61 62 6c 65 20 2a 2f 0a 20 20  tual table */.  
67d0: 61 73 73 65 72 74 28 20 70 56 74 61 62 2d 3e 69  assert( pVtab->i
67e0: 6e 54 72 61 6e 73 61 63 74 69 6f 6e 20 29 3b 0a  nTransaction );.
67f0: 0a 20 20 69 66 28 20 73 69 6d 75 6c 61 74 65 56  .  if( simulateV
6800: 74 61 62 45 72 72 6f 72 28 70 56 74 61 62 2c 20  tabError(pVtab, 
6810: 22 78 55 70 64 61 74 65 22 29 20 29 7b 0a 20 20  "xUpdate") ){.  
6820: 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f    return SQLITE_
6830: 45 52 52 4f 52 3b 0a 20 20 7d 0a 0a 20 20 2f 2a  ERROR;.  }..  /*
6840: 20 49 66 20 61 70 44 61 74 61 5b 30 5d 20 69 73   If apData[0] is
6850: 20 61 6e 20 69 6e 74 65 67 65 72 20 61 6e 64 20   an integer and 
6860: 6e 44 61 74 61 3e 31 20 74 68 65 6e 20 64 6f 20  nData>1 then do 
6870: 61 6e 20 55 50 44 41 54 45 20 2a 2f 0a 20 20 69  an UPDATE */.  i
6880: 66 28 20 6e 44 61 74 61 3e 31 20 26 26 20 73 71  f( nData>1 && sq
6890: 6c 69 74 65 33 5f 76 61 6c 75 65 5f 74 79 70 65  lite3_value_type
68a0: 28 61 70 44 61 74 61 5b 30 5d 29 3d 3d 53 51 4c  (apData[0])==SQL
68b0: 49 54 45 5f 49 4e 54 45 47 45 52 20 29 7b 0a 20  ITE_INTEGER ){. 
68c0: 20 20 20 63 68 61 72 20 2a 7a 53 65 70 20 3d 20     char *zSep = 
68d0: 22 20 53 45 54 22 3b 0a 20 20 20 20 7a 20 3d 20  " SET";.    z = 
68e0: 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28  sqlite3_mprintf(
68f0: 22 55 50 44 41 54 45 20 25 51 22 2c 20 70 56 74  "UPDATE %Q", pVt
6900: 61 62 2d 3e 7a 54 61 62 6c 65 4e 61 6d 65 29 3b  ab->zTableName);
6910: 0a 20 20 20 20 69 66 28 20 21 7a 20 29 7b 0a 20  .    if( !z ){. 
6920: 20 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45       rc = SQLITE
6930: 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 7d 0a 0a 20  _NOMEM;.    }.. 
6940: 20 20 20 62 69 6e 64 41 72 67 4f 6e 65 20 3d 20     bindArgOne = 
6950: 28 61 70 44 61 74 61 5b 31 5d 20 26 26 20 73 71  (apData[1] && sq
6960: 6c 69 74 65 33 5f 76 61 6c 75 65 5f 74 79 70 65  lite3_value_type
6970: 28 61 70 44 61 74 61 5b 31 5d 29 3d 3d 53 51 4c  (apData[1])==SQL
6980: 49 54 45 5f 49 4e 54 45 47 45 52 29 3b 0a 20 20  ITE_INTEGER);.  
6990: 20 20 62 69 6e 64 41 72 67 5a 65 72 6f 20 3d 20    bindArgZero = 
69a0: 31 3b 0a 0a 20 20 20 20 69 66 28 20 62 69 6e 64  1;..    if( bind
69b0: 41 72 67 4f 6e 65 20 29 7b 0a 20 20 20 20 20 20  ArgOne ){.      
69c0: 20 73 74 72 69 6e 67 5f 63 6f 6e 63 61 74 28 26   string_concat(&
69d0: 7a 2c 20 22 20 53 45 54 20 72 6f 77 69 64 3d 3f  z, " SET rowid=?
69e0: 31 20 22 2c 20 30 2c 20 26 72 63 29 3b 0a 20 20  1 ", 0, &rc);.  
69f0: 20 20 20 20 20 7a 53 65 70 20 3d 20 22 2c 22 3b       zSep = ",";
6a00: 0a 20 20 20 20 7d 0a 20 20 20 20 66 6f 72 28 69  .    }.    for(i
6a10: 3d 32 3b 20 69 3c 6e 44 61 74 61 3b 20 69 2b 2b  =2; i<nData; i++
6a20: 29 7b 0a 20 20 20 20 20 20 69 66 28 20 61 70 44  ){.      if( apD
6a30: 61 74 61 5b 69 5d 3d 3d 30 20 29 20 63 6f 6e 74  ata[i]==0 ) cont
6a40: 69 6e 75 65 3b 0a 20 20 20 20 20 20 73 74 72 69  inue;.      stri
6a50: 6e 67 5f 63 6f 6e 63 61 74 28 26 7a 2c 20 73 71  ng_concat(&z, sq
6a60: 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 0a 20  lite3_mprintf(. 
6a70: 20 20 20 20 20 20 20 20 20 22 25 73 20 25 51 3d           "%s %Q=
6a80: 3f 25 64 22 2c 20 7a 53 65 70 2c 20 70 56 74 61  ?%d", zSep, pVta
6a90: 62 2d 3e 61 43 6f 6c 5b 69 2d 32 5d 2c 20 69 29  b->aCol[i-2], i)
6aa0: 2c 20 31 2c 20 26 72 63 29 3b 0a 20 20 20 20 20  , 1, &rc);.     
6ab0: 20 7a 53 65 70 20 3d 20 22 2c 22 3b 0a 20 20 20   zSep = ",";.   
6ac0: 20 7d 0a 20 20 20 20 73 74 72 69 6e 67 5f 63 6f   }.    string_co
6ad0: 6e 63 61 74 28 26 7a 2c 20 73 71 6c 69 74 65 33  ncat(&z, sqlite3
6ae0: 5f 6d 70 72 69 6e 74 66 28 22 20 57 48 45 52 45  _mprintf(" WHERE
6af0: 20 72 6f 77 69 64 3d 3f 25 64 22 2c 20 6e 44 61   rowid=?%d", nDa
6b00: 74 61 29 2c 20 31 2c 20 26 72 63 29 3b 0a 20 20  ta), 1, &rc);.  
6b10: 7d 0a 0a 20 20 2f 2a 20 49 66 20 61 70 44 61 74  }..  /* If apDat
6b20: 61 5b 30 5d 20 69 73 20 61 6e 20 69 6e 74 65 67  a[0] is an integ
6b30: 65 72 20 61 6e 64 20 6e 44 61 74 61 3d 3d 31 20  er and nData==1 
6b40: 74 68 65 6e 20 64 6f 20 61 20 44 45 4c 45 54 45  then do a DELETE
6b50: 20 2a 2f 0a 20 20 65 6c 73 65 20 69 66 28 20 6e   */.  else if( n
6b60: 44 61 74 61 3d 3d 31 20 26 26 20 73 71 6c 69 74  Data==1 && sqlit
6b70: 65 33 5f 76 61 6c 75 65 5f 74 79 70 65 28 61 70  e3_value_type(ap
6b80: 44 61 74 61 5b 30 5d 29 3d 3d 53 51 4c 49 54 45  Data[0])==SQLITE
6b90: 5f 49 4e 54 45 47 45 52 20 29 7b 0a 20 20 20 20  _INTEGER ){.    
6ba0: 7a 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72 69  z = sqlite3_mpri
6bb0: 6e 74 66 28 22 44 45 4c 45 54 45 20 46 52 4f 4d  ntf("DELETE FROM
6bc0: 20 25 51 20 57 48 45 52 45 20 72 6f 77 69 64 20   %Q WHERE rowid 
6bd0: 3d 20 3f 31 22 2c 20 70 56 74 61 62 2d 3e 7a 54  = ?1", pVtab->zT
6be0: 61 62 6c 65 4e 61 6d 65 29 3b 0a 20 20 20 20 69  ableName);.    i
6bf0: 66 28 20 21 7a 20 29 7b 0a 20 20 20 20 20 20 72  f( !z ){.      r
6c00: 63 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d  c = SQLITE_NOMEM
6c10: 3b 0a 20 20 20 20 7d 0a 20 20 20 20 62 69 6e 64  ;.    }.    bind
6c20: 41 72 67 5a 65 72 6f 20 3d 20 31 3b 0a 20 20 7d  ArgZero = 1;.  }
6c30: 0a 0a 20 20 2f 2a 20 49 66 20 74 68 65 20 66 69  ..  /* If the fi
6c40: 72 73 74 20 61 72 67 75 6d 65 6e 74 20 69 73 20  rst argument is 
6c50: 4e 55 4c 4c 20 61 6e 64 20 74 68 65 72 65 20 61  NULL and there a
6c60: 72 65 20 6d 6f 72 65 20 74 68 61 6e 20 74 77 6f  re more than two
6c70: 20 61 72 67 73 2c 20 49 4e 53 45 52 54 20 2a 2f   args, INSERT */
6c80: 0a 20 20 65 6c 73 65 20 69 66 28 20 6e 44 61 74  .  else if( nDat
6c90: 61 3e 32 20 26 26 20 73 71 6c 69 74 65 33 5f 76  a>2 && sqlite3_v
6ca0: 61 6c 75 65 5f 74 79 70 65 28 61 70 44 61 74 61  alue_type(apData
6cb0: 5b 30 5d 29 3d 3d 53 51 4c 49 54 45 5f 4e 55 4c  [0])==SQLITE_NUL
6cc0: 4c 20 29 7b 0a 20 20 20 20 69 6e 74 20 69 69 3b  L ){.    int ii;
6cd0: 0a 20 20 20 20 63 68 61 72 20 2a 7a 49 6e 73 65  .    char *zInse
6ce0: 72 74 20 3d 20 30 3b 0a 20 20 20 20 63 68 61 72  rt = 0;.    char
6cf0: 20 2a 7a 56 61 6c 75 65 73 20 3d 20 30 3b 0a 20   *zValues = 0;. 
6d00: 20 0a 20 20 20 20 7a 49 6e 73 65 72 74 20 3d 20   .    zInsert = 
6d10: 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28  sqlite3_mprintf(
6d20: 22 49 4e 53 45 52 54 20 49 4e 54 4f 20 25 51 20  "INSERT INTO %Q 
6d30: 28 22 2c 20 70 56 74 61 62 2d 3e 7a 54 61 62 6c  (", pVtab->zTabl
6d40: 65 4e 61 6d 65 29 3b 0a 20 20 20 20 69 66 28 20  eName);.    if( 
6d50: 21 7a 49 6e 73 65 72 74 20 29 7b 0a 20 20 20 20  !zInsert ){.    
6d60: 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4e 4f    rc = SQLITE_NO
6d70: 4d 45 4d 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69  MEM;.    }.    i
6d80: 66 28 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65  f( sqlite3_value
6d90: 5f 74 79 70 65 28 61 70 44 61 74 61 5b 31 5d 29  _type(apData[1])
6da0: 3d 3d 53 51 4c 49 54 45 5f 49 4e 54 45 47 45 52  ==SQLITE_INTEGER
6db0: 20 29 7b 0a 20 20 20 20 20 20 62 69 6e 64 41 72   ){.      bindAr
6dc0: 67 4f 6e 65 20 3d 20 31 3b 0a 20 20 20 20 20 20  gOne = 1;.      
6dd0: 7a 56 61 6c 75 65 73 20 3d 20 73 71 6c 69 74 65  zValues = sqlite
6de0: 33 5f 6d 70 72 69 6e 74 66 28 22 3f 22 29 3b 0a  3_mprintf("?");.
6df0: 20 20 20 20 20 20 73 74 72 69 6e 67 5f 63 6f 6e        string_con
6e00: 63 61 74 28 26 7a 49 6e 73 65 72 74 2c 20 22 72  cat(&zInsert, "r
6e10: 6f 77 69 64 22 2c 20 30 2c 20 26 72 63 29 3b 0a  owid", 0, &rc);.
6e20: 20 20 20 20 7d 0a 0a 20 20 20 20 61 73 73 65 72      }..    asser
6e30: 74 28 28 70 56 74 61 62 2d 3e 6e 43 6f 6c 2b 32  t((pVtab->nCol+2
6e40: 29 3d 3d 6e 44 61 74 61 29 3b 0a 20 20 20 20 66  )==nData);.    f
6e50: 6f 72 28 69 69 3d 32 3b 20 69 69 3c 6e 44 61 74  or(ii=2; ii<nDat
6e60: 61 3b 20 69 69 2b 2b 29 7b 0a 20 20 20 20 20 20  a; ii++){.      
6e70: 73 74 72 69 6e 67 5f 63 6f 6e 63 61 74 28 26 7a  string_concat(&z
6e80: 49 6e 73 65 72 74 2c 20 0a 20 20 20 20 20 20 20  Insert, .       
6e90: 20 20 20 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e     sqlite3_mprin
6ea0: 74 66 28 22 25 73 25 51 22 2c 20 7a 56 61 6c 75  tf("%s%Q", zValu
6eb0: 65 73 3f 22 2c 20 22 3a 22 22 2c 20 70 56 74 61  es?", ":"", pVta
6ec0: 62 2d 3e 61 43 6f 6c 5b 69 69 2d 32 5d 29 2c 20  b->aCol[ii-2]), 
6ed0: 31 2c 20 26 72 63 29 3b 0a 20 20 20 20 20 20 73  1, &rc);.      s
6ee0: 74 72 69 6e 67 5f 63 6f 6e 63 61 74 28 26 7a 56  tring_concat(&zV
6ef0: 61 6c 75 65 73 2c 20 0a 20 20 20 20 20 20 20 20  alues, .        
6f00: 20 20 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74    sqlite3_mprint
6f10: 66 28 22 25 73 3f 25 64 22 2c 20 7a 56 61 6c 75  f("%s?%d", zValu
6f20: 65 73 3f 22 2c 20 22 3a 22 22 2c 20 69 69 29 2c  es?", ":"", ii),
6f30: 20 31 2c 20 26 72 63 29 3b 0a 20 20 20 20 7d 0a   1, &rc);.    }.
6f40: 0a 20 20 20 20 73 74 72 69 6e 67 5f 63 6f 6e 63  .    string_conc
6f50: 61 74 28 26 7a 2c 20 7a 49 6e 73 65 72 74 2c 20  at(&z, zInsert, 
6f60: 31 2c 20 26 72 63 29 3b 0a 20 20 20 20 73 74 72  1, &rc);.    str
6f70: 69 6e 67 5f 63 6f 6e 63 61 74 28 26 7a 2c 20 22  ing_concat(&z, "
6f80: 29 20 56 41 4c 55 45 53 28 22 2c 20 30 2c 20 26  ) VALUES(", 0, &
6f90: 72 63 29 3b 0a 20 20 20 20 73 74 72 69 6e 67 5f  rc);.    string_
6fa0: 63 6f 6e 63 61 74 28 26 7a 2c 20 7a 56 61 6c 75  concat(&z, zValu
6fb0: 65 73 2c 20 31 2c 20 26 72 63 29 3b 0a 20 20 20  es, 1, &rc);.   
6fc0: 20 73 74 72 69 6e 67 5f 63 6f 6e 63 61 74 28 26   string_concat(&
6fd0: 7a 2c 20 22 29 22 2c 20 30 2c 20 26 72 63 29 3b  z, ")", 0, &rc);
6fe0: 0a 20 20 7d 0a 0a 20 20 2f 2a 20 41 6e 79 74 68  .  }..  /* Anyth
6ff0: 69 6e 67 20 65 6c 73 65 20 69 73 20 61 6e 20 65  ing else is an e
7000: 72 72 6f 72 20 2a 2f 0a 20 20 65 6c 73 65 7b 0a  rror */.  else{.
7010: 20 20 20 20 61 73 73 65 72 74 28 30 29 3b 0a 20      assert(0);. 
7020: 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45     return SQLITE
7030: 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a 0a 20 20 69  _ERROR;.  }..  i
7040: 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc==SQLITE_OK
7050: 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 73 71 6c   ){.    rc = sql
7060: 69 74 65 33 5f 70 72 65 70 61 72 65 28 64 62 2c  ite3_prepare(db,
7070: 20 7a 2c 20 2d 31 2c 20 26 70 53 74 6d 74 2c 20   z, -1, &pStmt, 
7080: 30 29 3b 0a 20 20 7d 0a 20 20 61 73 73 65 72 74  0);.  }.  assert
7090: 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc!=SQLITE_OK 
70a0: 7c 7c 20 70 53 74 6d 74 20 29 3b 0a 20 20 73 71  || pStmt );.  sq
70b0: 6c 69 74 65 33 5f 66 72 65 65 28 7a 29 3b 0a 20  lite3_free(z);. 
70c0: 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
70d0: 4f 4b 20 29 20 7b 0a 20 20 20 20 69 66 28 20 62  OK ) {.    if( b
70e0: 69 6e 64 41 72 67 5a 65 72 6f 20 29 7b 0a 20 20  indArgZero ){.  
70f0: 20 20 20 20 73 71 6c 69 74 65 33 5f 62 69 6e 64      sqlite3_bind
7100: 5f 76 61 6c 75 65 28 70 53 74 6d 74 2c 20 6e 44  _value(pStmt, nD
7110: 61 74 61 2c 20 61 70 44 61 74 61 5b 30 5d 29 3b  ata, apData[0]);
7120: 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 28 20 62  .    }.    if( b
7130: 69 6e 64 41 72 67 4f 6e 65 20 29 7b 0a 20 20 20  indArgOne ){.   
7140: 20 20 20 73 71 6c 69 74 65 33 5f 62 69 6e 64 5f     sqlite3_bind_
7150: 76 61 6c 75 65 28 70 53 74 6d 74 2c 20 31 2c 20  value(pStmt, 1, 
7160: 61 70 44 61 74 61 5b 31 5d 29 3b 0a 20 20 20 20  apData[1]);.    
7170: 7d 0a 20 20 20 20 66 6f 72 28 69 3d 32 3b 20 69  }.    for(i=2; i
7180: 3c 6e 44 61 74 61 20 26 26 20 72 63 3d 3d 53 51  <nData && rc==SQ
7190: 4c 49 54 45 5f 4f 4b 3b 20 69 2b 2b 29 7b 0a 20  LITE_OK; i++){. 
71a0: 20 20 20 20 20 69 66 28 20 61 70 44 61 74 61 5b       if( apData[
71b0: 69 5d 20 29 20 72 63 20 3d 20 73 71 6c 69 74 65  i] ) rc = sqlite
71c0: 33 5f 62 69 6e 64 5f 76 61 6c 75 65 28 70 53 74  3_bind_value(pSt
71d0: 6d 74 2c 20 69 2c 20 61 70 44 61 74 61 5b 69 5d  mt, i, apData[i]
71e0: 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 28  );.    }.    if(
71f0: 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc==SQLITE_OK )
7200: 7b 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f  {.      sqlite3_
7210: 73 74 65 70 28 70 53 74 6d 74 29 3b 0a 20 20 20  step(pStmt);.   
7220: 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f     rc = sqlite3_
7230: 66 69 6e 61 6c 69 7a 65 28 70 53 74 6d 74 29 3b  finalize(pStmt);
7240: 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  .    }else{.    
7250: 20 20 73 71 6c 69 74 65 33 5f 66 69 6e 61 6c 69    sqlite3_finali
7260: 7a 65 28 70 53 74 6d 74 29 3b 0a 20 20 20 20 7d  ze(pStmt);.    }
7270: 0a 20 20 7d 0a 0a 20 20 69 66 28 20 70 52 6f 77  .  }..  if( pRow
7280: 69 64 20 26 26 20 72 63 3d 3d 53 51 4c 49 54 45  id && rc==SQLITE
7290: 5f 4f 4b 20 29 7b 0a 20 20 20 20 2a 70 52 6f 77  _OK ){.    *pRow
72a0: 69 64 20 3d 20 73 71 6c 69 74 65 33 5f 6c 61 73  id = sqlite3_las
72b0: 74 5f 69 6e 73 65 72 74 5f 72 6f 77 69 64 28 64  t_insert_rowid(d
72c0: 62 29 3b 0a 20 20 7d 0a 20 20 69 66 28 20 72 63  b);.  }.  if( rc
72d0: 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  !=SQLITE_OK ){. 
72e0: 20 20 20 74 61 62 2d 3e 7a 45 72 72 4d 73 67 20     tab->zErrMsg 
72f0: 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74  = sqlite3_mprint
7300: 66 28 22 65 63 68 6f 2d 76 74 61 62 2d 65 72 72  f("echo-vtab-err
7310: 6f 72 3a 20 25 73 22 2c 20 73 71 6c 69 74 65 33  or: %s", sqlite3
7320: 5f 65 72 72 6d 73 67 28 64 62 29 29 3b 0a 20 20  _errmsg(db));.  
7330: 7d 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a  }..  return rc;.
7340: 7d 0a 0a 2f 2a 0a 2a 2a 20 78 42 65 67 69 6e 2c  }../*.** xBegin,
7350: 20 78 53 79 6e 63 2c 20 78 43 6f 6d 6d 69 74 20   xSync, xCommit 
7360: 61 6e 64 20 78 52 6f 6c 6c 62 61 63 6b 20 63 61  and xRollback ca
7370: 6c 6c 62 61 63 6b 73 20 66 6f 72 20 65 63 68 6f  llbacks for echo
7380: 20 6d 6f 64 75 6c 65 0a 2a 2a 20 76 69 72 74 75   module.** virtu
7390: 61 6c 20 74 61 62 6c 65 73 2e 20 44 6f 20 6e 6f  al tables. Do no
73a0: 74 68 69 6e 67 20 6f 74 68 65 72 20 74 68 61 6e  thing other than
73b0: 20 61 64 64 20 74 68 65 20 6e 61 6d 65 20 6f 66   add the name of
73c0: 20 74 68 65 20 63 61 6c 6c 62 61 63 6b 0a 2a 2a   the callback.**
73d0: 20 74 6f 20 74 68 65 20 24 3a 3a 65 63 68 6f 5f   to the $::echo_
73e0: 6d 6f 64 75 6c 65 20 54 63 6c 20 76 61 72 69 61  module Tcl varia
73f0: 62 6c 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  ble..*/.static i
7400: 6e 74 20 65 63 68 6f 54 72 61 6e 73 61 63 74 69  nt echoTransacti
7410: 6f 6e 43 61 6c 6c 28 73 71 6c 69 74 65 33 5f 76  onCall(sqlite3_v
7420: 74 61 62 20 2a 74 61 62 2c 20 63 6f 6e 73 74 20  tab *tab, const 
7430: 63 68 61 72 20 2a 7a 43 61 6c 6c 29 7b 0a 20 20  char *zCall){.  
7440: 63 68 61 72 20 2a 7a 3b 0a 20 20 65 63 68 6f 5f  char *z;.  echo_
7450: 76 74 61 62 20 2a 70 56 74 61 62 20 3d 20 28 65  vtab *pVtab = (e
7460: 63 68 6f 5f 76 74 61 62 20 2a 29 74 61 62 3b 0a  cho_vtab *)tab;.
7470: 20 20 7a 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70    z = sqlite3_mp
7480: 72 69 6e 74 66 28 22 65 63 68 6f 28 25 73 29 22  rintf("echo(%s)"
7490: 2c 20 70 56 74 61 62 2d 3e 7a 54 61 62 6c 65 4e  , pVtab->zTableN
74a0: 61 6d 65 29 3b 0a 20 20 69 66 28 20 7a 3d 3d 30  ame);.  if( z==0
74b0: 20 29 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45   ) return SQLITE
74c0: 5f 4e 4f 4d 45 4d 3b 0a 20 20 61 70 70 65 6e 64  _NOMEM;.  append
74d0: 54 6f 45 63 68 6f 4d 6f 64 75 6c 65 28 70 56 74  ToEchoModule(pVt
74e0: 61 62 2d 3e 69 6e 74 65 72 70 2c 20 7a 43 61 6c  ab->interp, zCal
74f0: 6c 29 3b 0a 20 20 61 70 70 65 6e 64 54 6f 45 63  l);.  appendToEc
7500: 68 6f 4d 6f 64 75 6c 65 28 70 56 74 61 62 2d 3e  hoModule(pVtab->
7510: 69 6e 74 65 72 70 2c 20 7a 29 3b 0a 20 20 73 71  interp, z);.  sq
7520: 6c 69 74 65 33 5f 66 72 65 65 28 7a 29 3b 0a 20  lite3_free(z);. 
7530: 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f   return SQLITE_O
7540: 4b 3b 0a 7d 0a 73 74 61 74 69 63 20 69 6e 74 20  K;.}.static int 
7550: 65 63 68 6f 42 65 67 69 6e 28 73 71 6c 69 74 65  echoBegin(sqlite
7560: 33 5f 76 74 61 62 20 2a 74 61 62 29 7b 0a 20 20  3_vtab *tab){.  
7570: 69 6e 74 20 72 63 3b 0a 20 20 65 63 68 6f 5f 76  int rc;.  echo_v
7580: 74 61 62 20 2a 70 56 74 61 62 20 3d 20 28 65 63  tab *pVtab = (ec
7590: 68 6f 5f 76 74 61 62 20 2a 29 74 61 62 3b 0a 20  ho_vtab *)tab;. 
75a0: 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74   Tcl_Interp *int
75b0: 65 72 70 20 3d 20 70 56 74 61 62 2d 3e 69 6e 74  erp = pVtab->int
75c0: 65 72 70 3b 0a 20 20 63 6f 6e 73 74 20 63 68 61  erp;.  const cha
75d0: 72 20 2a 7a 56 61 6c 3b 20 0a 0a 20 20 2f 2a 20  r *zVal; ..  /* 
75e0: 54 69 63 6b 65 74 20 23 33 30 38 33 20 2d 20 64  Ticket #3083 - d
75f0: 6f 20 6e 6f 74 20 73 74 61 72 74 20 61 20 74 72  o not start a tr
7600: 61 6e 73 61 63 74 69 6f 6e 20 69 66 20 77 65 20  ansaction if we 
7610: 61 72 65 20 61 6c 72 65 61 64 79 20 69 6e 0a 20  are already in. 
7620: 20 2a 2a 20 61 20 74 72 61 6e 73 61 63 74 69 6f   ** a transactio
7630: 6e 20 2a 2f 0a 20 20 61 73 73 65 72 74 28 20 21  n */.  assert( !
7640: 70 56 74 61 62 2d 3e 69 6e 54 72 61 6e 73 61 63  pVtab->inTransac
7650: 74 69 6f 6e 20 29 3b 0a 0a 20 20 69 66 28 20 73  tion );..  if( s
7660: 69 6d 75 6c 61 74 65 56 74 61 62 45 72 72 6f 72  imulateVtabError
7670: 28 70 56 74 61 62 2c 20 22 78 42 65 67 69 6e 22  (pVtab, "xBegin"
7680: 29 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20  ) ){.    return 
7690: 53 51 4c 49 54 45 5f 45 52 52 4f 52 3b 0a 20 20  SQLITE_ERROR;.  
76a0: 7d 0a 0a 20 20 72 63 20 3d 20 65 63 68 6f 54 72  }..  rc = echoTr
76b0: 61 6e 73 61 63 74 69 6f 6e 43 61 6c 6c 28 74 61  ansactionCall(ta
76c0: 62 2c 20 22 78 42 65 67 69 6e 22 29 3b 0a 0a 20  b, "xBegin");.. 
76d0: 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
76e0: 4f 4b 20 29 7b 0a 20 20 20 20 2f 2a 20 43 68 65  OK ){.    /* Che
76f0: 63 6b 20 69 66 20 74 68 65 20 24 3a 3a 65 63 68  ck if the $::ech
7700: 6f 5f 6d 6f 64 75 6c 65 5f 62 65 67 69 6e 5f 66  o_module_begin_f
7710: 61 69 6c 20 76 61 72 69 61 62 6c 65 20 69 73 20  ail variable is 
7720: 64 65 66 69 6e 65 64 2e 20 49 66 20 69 74 20 69  defined. If it i
7730: 73 2c 0a 20 20 20 20 2a 2a 20 61 6e 64 20 69 74  s,.    ** and it
7740: 20 69 73 20 73 65 74 20 74 6f 20 74 68 65 20 6e   is set to the n
7750: 61 6d 65 20 6f 66 20 74 68 65 20 72 65 61 6c 20  ame of the real 
7760: 74 61 62 6c 65 20 75 6e 64 65 72 6c 79 69 6e 67  table underlying
7770: 20 74 68 69 73 20 76 69 72 74 75 61 6c 0a 20 20   this virtual.  
7780: 20 20 2a 2a 20 65 63 68 6f 20 6d 6f 64 75 6c 65    ** echo module
7790: 20 74 61 62 6c 65 2c 20 74 68 65 6e 20 63 61 75   table, then cau
77a0: 73 65 20 74 68 69 73 20 78 53 79 6e 63 20 6f 70  se this xSync op
77b0: 65 72 61 74 69 6f 6e 20 74 6f 20 66 61 69 6c 2e  eration to fail.
77c0: 0a 20 20 20 20 2a 2f 0a 20 20 20 20 7a 56 61 6c  .    */.    zVal
77d0: 20 3d 20 54 63 6c 5f 47 65 74 56 61 72 28 69 6e   = Tcl_GetVar(in
77e0: 74 65 72 70 2c 20 22 65 63 68 6f 5f 6d 6f 64 75  terp, "echo_modu
77f0: 6c 65 5f 62 65 67 69 6e 5f 66 61 69 6c 22 2c 20  le_begin_fail", 
7800: 54 43 4c 5f 47 4c 4f 42 41 4c 5f 4f 4e 4c 59 29  TCL_GLOBAL_ONLY)
7810: 3b 0a 20 20 20 20 69 66 28 20 7a 56 61 6c 20 26  ;.    if( zVal &
7820: 26 20 30 3d 3d 73 74 72 63 6d 70 28 7a 56 61 6c  & 0==strcmp(zVal
7830: 2c 20 70 56 74 61 62 2d 3e 7a 54 61 62 6c 65 4e  , pVtab->zTableN
7840: 61 6d 65 29 20 29 7b 0a 20 20 20 20 20 20 72 63  ame) ){.      rc
7850: 20 3d 20 53 51 4c 49 54 45 5f 45 52 52 4f 52 3b   = SQLITE_ERROR;
7860: 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 69 66 28  .    }.  }.  if(
7870: 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc==SQLITE_OK )
7880: 7b 0a 20 20 20 20 70 56 74 61 62 2d 3e 69 6e 54  {.    pVtab->inT
7890: 72 61 6e 73 61 63 74 69 6f 6e 20 3d 20 31 3b 0a  ransaction = 1;.
78a0: 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 72 63 3b    }.  return rc;
78b0: 0a 7d 0a 73 74 61 74 69 63 20 69 6e 74 20 65 63  .}.static int ec
78c0: 68 6f 53 79 6e 63 28 73 71 6c 69 74 65 33 5f 76  hoSync(sqlite3_v
78d0: 74 61 62 20 2a 74 61 62 29 7b 0a 20 20 69 6e 74  tab *tab){.  int
78e0: 20 72 63 3b 0a 20 20 65 63 68 6f 5f 76 74 61 62   rc;.  echo_vtab
78f0: 20 2a 70 56 74 61 62 20 3d 20 28 65 63 68 6f 5f   *pVtab = (echo_
7900: 76 74 61 62 20 2a 29 74 61 62 3b 0a 20 20 54 63  vtab *)tab;.  Tc
7910: 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70  l_Interp *interp
7920: 20 3d 20 70 56 74 61 62 2d 3e 69 6e 74 65 72 70   = pVtab->interp
7930: 3b 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a  ;.  const char *
7940: 7a 56 61 6c 3b 20 0a 0a 20 20 2f 2a 20 54 69 63  zVal; ..  /* Tic
7950: 6b 65 74 20 23 33 30 38 33 20 2d 20 4f 6e 6c 79  ket #3083 - Only
7960: 20 63 61 6c 6c 20 78 53 79 6e 63 20 69 66 20 77   call xSync if w
7970: 65 20 68 61 76 65 20 70 72 65 76 69 6f 75 73 6c  e have previousl
7980: 79 20 73 74 61 72 74 65 64 20 61 0a 20 20 2a 2a  y started a.  **
7990: 20 74 72 61 6e 73 61 63 74 69 6f 6e 20 2a 2f 0a   transaction */.
79a0: 20 20 61 73 73 65 72 74 28 20 70 56 74 61 62 2d    assert( pVtab-
79b0: 3e 69 6e 54 72 61 6e 73 61 63 74 69 6f 6e 20 29  >inTransaction )
79c0: 3b 0a 0a 20 20 69 66 28 20 73 69 6d 75 6c 61 74  ;..  if( simulat
79d0: 65 56 74 61 62 45 72 72 6f 72 28 70 56 74 61 62  eVtabError(pVtab
79e0: 2c 20 22 78 53 79 6e 63 22 29 20 29 7b 0a 20 20  , "xSync") ){.  
79f0: 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f    return SQLITE_
7a00: 45 52 52 4f 52 3b 0a 20 20 7d 0a 0a 20 20 72 63  ERROR;.  }..  rc
7a10: 20 3d 20 65 63 68 6f 54 72 61 6e 73 61 63 74 69   = echoTransacti
7a20: 6f 6e 43 61 6c 6c 28 74 61 62 2c 20 22 78 53 79  onCall(tab, "xSy
7a30: 6e 63 22 29 3b 0a 0a 20 20 69 66 28 20 72 63 3d  nc");..  if( rc=
7a40: 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20  =SQLITE_OK ){.  
7a50: 20 20 2f 2a 20 43 68 65 63 6b 20 69 66 20 74 68    /* Check if th
7a60: 65 20 24 3a 3a 65 63 68 6f 5f 6d 6f 64 75 6c 65  e $::echo_module
7a70: 5f 73 79 6e 63 5f 66 61 69 6c 20 76 61 72 69 61  _sync_fail varia
7a80: 62 6c 65 20 69 73 20 64 65 66 69 6e 65 64 2e 20  ble is defined. 
7a90: 49 66 20 69 74 20 69 73 2c 0a 20 20 20 20 2a 2a  If it is,.    **
7aa0: 20 61 6e 64 20 69 74 20 69 73 20 73 65 74 20 74   and it is set t
7ab0: 6f 20 74 68 65 20 6e 61 6d 65 20 6f 66 20 74 68  o the name of th
7ac0: 65 20 72 65 61 6c 20 74 61 62 6c 65 20 75 6e 64  e real table und
7ad0: 65 72 6c 79 69 6e 67 20 74 68 69 73 20 76 69 72  erlying this vir
7ae0: 74 75 61 6c 0a 20 20 20 20 2a 2a 20 65 63 68 6f  tual.    ** echo
7af0: 20 6d 6f 64 75 6c 65 20 74 61 62 6c 65 2c 20 74   module table, t
7b00: 68 65 6e 20 63 61 75 73 65 20 74 68 69 73 20 78  hen cause this x
7b10: 53 79 6e 63 20 6f 70 65 72 61 74 69 6f 6e 20 74  Sync operation t
7b20: 6f 20 66 61 69 6c 2e 0a 20 20 20 20 2a 2f 0a 20  o fail..    */. 
7b30: 20 20 20 7a 56 61 6c 20 3d 20 54 63 6c 5f 47 65     zVal = Tcl_Ge
7b40: 74 56 61 72 28 69 6e 74 65 72 70 2c 20 22 65 63  tVar(interp, "ec
7b50: 68 6f 5f 6d 6f 64 75 6c 65 5f 73 79 6e 63 5f 66  ho_module_sync_f
7b60: 61 69 6c 22 2c 20 54 43 4c 5f 47 4c 4f 42 41 4c  ail", TCL_GLOBAL
7b70: 5f 4f 4e 4c 59 29 3b 0a 20 20 20 20 69 66 28 20  _ONLY);.    if( 
7b80: 7a 56 61 6c 20 26 26 20 30 3d 3d 73 74 72 63 6d  zVal && 0==strcm
7b90: 70 28 7a 56 61 6c 2c 20 70 56 74 61 62 2d 3e 7a  p(zVal, pVtab->z
7ba0: 54 61 62 6c 65 4e 61 6d 65 29 20 29 7b 0a 20 20  TableName) ){.  
7bb0: 20 20 20 20 72 63 20 3d 20 2d 31 3b 0a 20 20 20      rc = -1;.   
7bc0: 20 7d 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20   }.  }.  return 
7bd0: 72 63 3b 0a 7d 0a 73 74 61 74 69 63 20 69 6e 74  rc;.}.static int
7be0: 20 65 63 68 6f 43 6f 6d 6d 69 74 28 73 71 6c 69   echoCommit(sqli
7bf0: 74 65 33 5f 76 74 61 62 20 2a 74 61 62 29 7b 0a  te3_vtab *tab){.
7c00: 20 20 65 63 68 6f 5f 76 74 61 62 20 2a 70 56 74    echo_vtab *pVt
7c10: 61 62 20 3d 20 28 65 63 68 6f 5f 76 74 61 62 2a  ab = (echo_vtab*
7c20: 29 74 61 62 3b 0a 20 20 69 6e 74 20 72 63 3b 0a  )tab;.  int rc;.
7c30: 0a 20 20 2f 2a 20 54 69 63 6b 65 74 20 23 33 30  .  /* Ticket #30
7c40: 38 33 20 2d 20 4f 6e 6c 79 20 63 61 6c 6c 20 78  83 - Only call x
7c50: 43 6f 6d 6d 69 74 20 69 66 20 77 65 20 68 61 76  Commit if we hav
7c60: 65 20 70 72 65 76 69 6f 75 73 6c 79 20 73 74 61  e previously sta
7c70: 72 74 65 64 0a 20 20 2a 2a 20 61 20 74 72 61 6e  rted.  ** a tran
7c80: 73 61 63 74 69 6f 6e 20 2a 2f 0a 20 20 61 73 73  saction */.  ass
7c90: 65 72 74 28 20 70 56 74 61 62 2d 3e 69 6e 54 72  ert( pVtab->inTr
7ca0: 61 6e 73 61 63 74 69 6f 6e 20 29 3b 0a 0a 20 20  ansaction );..  
7cb0: 69 66 28 20 73 69 6d 75 6c 61 74 65 56 74 61 62  if( simulateVtab
7cc0: 45 72 72 6f 72 28 70 56 74 61 62 2c 20 22 78 43  Error(pVtab, "xC
7cd0: 6f 6d 6d 69 74 22 29 20 29 7b 0a 20 20 20 20 72  ommit") ){.    r
7ce0: 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 45 52 52  eturn SQLITE_ERR
7cf0: 4f 52 3b 0a 20 20 7d 0a 0a 20 20 73 71 6c 69 74  OR;.  }..  sqlit
7d00: 65 33 42 65 67 69 6e 42 65 6e 69 67 6e 4d 61 6c  e3BeginBenignMal
7d10: 6c 6f 63 28 29 3b 0a 20 20 72 63 20 3d 20 65 63  loc();.  rc = ec
7d20: 68 6f 54 72 61 6e 73 61 63 74 69 6f 6e 43 61 6c  hoTransactionCal
7d30: 6c 28 74 61 62 2c 20 22 78 43 6f 6d 6d 69 74 22  l(tab, "xCommit"
7d40: 29 3b 0a 20 20 73 71 6c 69 74 65 33 45 6e 64 42  );.  sqlite3EndB
7d50: 65 6e 69 67 6e 4d 61 6c 6c 6f 63 28 29 3b 0a 20  enignMalloc();. 
7d60: 20 70 56 74 61 62 2d 3e 69 6e 54 72 61 6e 73 61   pVtab->inTransa
7d70: 63 74 69 6f 6e 20 3d 20 30 3b 0a 20 20 72 65 74  ction = 0;.  ret
7d80: 75 72 6e 20 72 63 3b 0a 7d 0a 73 74 61 74 69 63  urn rc;.}.static
7d90: 20 69 6e 74 20 65 63 68 6f 52 6f 6c 6c 62 61 63   int echoRollbac
7da0: 6b 28 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a  k(sqlite3_vtab *
7db0: 74 61 62 29 7b 0a 20 20 69 6e 74 20 72 63 3b 0a  tab){.  int rc;.
7dc0: 20 20 65 63 68 6f 5f 76 74 61 62 20 2a 70 56 74    echo_vtab *pVt
7dd0: 61 62 20 3d 20 28 65 63 68 6f 5f 76 74 61 62 2a  ab = (echo_vtab*
7de0: 29 74 61 62 3b 0a 0a 20 20 2f 2a 20 54 69 63 6b  )tab;..  /* Tick
7df0: 65 74 20 23 33 30 38 33 20 2d 20 4f 6e 6c 79 20  et #3083 - Only 
7e00: 63 61 6c 6c 20 78 52 6f 6c 6c 62 61 63 6b 20 69  call xRollback i
7e10: 66 20 77 65 20 68 61 76 65 20 70 72 65 76 69 6f  f we have previo
7e20: 75 73 6c 79 20 73 74 61 72 74 65 64 0a 20 20 2a  usly started.  *
7e30: 2a 20 61 20 74 72 61 6e 73 61 63 74 69 6f 6e 20  * a transaction 
7e40: 2a 2f 0a 20 20 61 73 73 65 72 74 28 20 70 56 74  */.  assert( pVt
7e50: 61 62 2d 3e 69 6e 54 72 61 6e 73 61 63 74 69 6f  ab->inTransactio
7e60: 6e 20 29 3b 0a 0a 20 20 72 63 20 3d 20 65 63 68  n );..  rc = ech
7e70: 6f 54 72 61 6e 73 61 63 74 69 6f 6e 43 61 6c 6c  oTransactionCall
7e80: 28 74 61 62 2c 20 22 78 52 6f 6c 6c 62 61 63 6b  (tab, "xRollback
7e90: 22 29 3b 0a 20 20 70 56 74 61 62 2d 3e 69 6e 54  ");.  pVtab->inT
7ea0: 72 61 6e 73 61 63 74 69 6f 6e 20 3d 20 30 3b 0a  ransaction = 0;.
7eb0: 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a    return rc;.}..
7ec0: 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74 61  /*.** Implementa
7ed0: 74 69 6f 6e 20 6f 66 20 22 47 4c 4f 42 22 20 66  tion of "GLOB" f
7ee0: 75 6e 63 74 69 6f 6e 20 6f 6e 20 74 68 65 20 65  unction on the e
7ef0: 63 68 6f 20 6d 6f 64 75 6c 65 2e 20 20 50 61 73  cho module.  Pas
7f00: 73 0a 2a 2a 20 61 6c 6c 20 61 72 67 75 6d 65 6e  s.** all argumen
7f10: 74 73 20 74 6f 20 74 68 65 20 3a 3a 65 63 68 6f  ts to the ::echo
7f20: 5f 67 6c 6f 62 5f 6f 76 65 72 6c 6f 61 64 20 70  _glob_overload p
7f30: 72 6f 63 65 64 75 72 65 20 6f 66 20 54 43 4c 0a  rocedure of TCL.
7f40: 2a 2a 20 61 6e 64 20 72 65 74 75 72 6e 20 74 68  ** and return th
7f50: 65 20 72 65 73 75 6c 74 20 6f 66 20 74 68 61 74  e result of that
7f60: 20 70 72 6f 63 65 64 75 72 65 20 61 73 20 61 20   procedure as a 
7f70: 73 74 72 69 6e 67 2e 0a 2a 2f 0a 73 74 61 74 69  string..*/.stati
7f80: 63 20 76 6f 69 64 20 6f 76 65 72 6c 6f 61 64 65  c void overloade
7f90: 64 47 6c 6f 62 46 75 6e 63 74 69 6f 6e 28 0a 20  dGlobFunction(. 
7fa0: 20 73 71 6c 69 74 65 33 5f 63 6f 6e 74 65 78 74   sqlite3_context
7fb0: 20 2a 70 43 6f 6e 74 65 78 74 2c 0a 20 20 69 6e   *pContext,.  in
7fc0: 74 20 6e 41 72 67 2c 0a 20 20 73 71 6c 69 74 65  t nArg,.  sqlite
7fd0: 33 5f 76 61 6c 75 65 20 2a 2a 61 70 41 72 67 0a  3_value **apArg.
7fe0: 29 7b 0a 20 20 54 63 6c 5f 49 6e 74 65 72 70 20  ){.  Tcl_Interp 
7ff0: 2a 69 6e 74 65 72 70 20 3d 20 73 71 6c 69 74 65  *interp = sqlite
8000: 33 5f 75 73 65 72 5f 64 61 74 61 28 70 43 6f 6e  3_user_data(pCon
8010: 74 65 78 74 29 3b 0a 20 20 54 63 6c 5f 44 53 74  text);.  Tcl_DSt
8020: 72 69 6e 67 20 73 74 72 3b 0a 20 20 69 6e 74 20  ring str;.  int 
8030: 69 3b 0a 20 20 69 6e 74 20 72 63 3b 0a 20 20 54  i;.  int rc;.  T
8040: 63 6c 5f 44 53 74 72 69 6e 67 49 6e 69 74 28 26  cl_DStringInit(&
8050: 73 74 72 29 3b 0a 20 20 54 63 6c 5f 44 53 74 72  str);.  Tcl_DStr
8060: 69 6e 67 41 70 70 65 6e 64 45 6c 65 6d 65 6e 74  ingAppendElement
8070: 28 26 73 74 72 2c 20 22 3a 3a 65 63 68 6f 5f 67  (&str, "::echo_g
8080: 6c 6f 62 5f 6f 76 65 72 6c 6f 61 64 22 29 3b 0a  lob_overload");.
8090: 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 6e 41 72    for(i=0; i<nAr
80a0: 67 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 54 63 6c  g; i++){.    Tcl
80b0: 5f 44 53 74 72 69 6e 67 41 70 70 65 6e 64 45 6c  _DStringAppendEl
80c0: 65 6d 65 6e 74 28 26 73 74 72 2c 20 28 63 68 61  ement(&str, (cha
80d0: 72 2a 29 73 71 6c 69 74 65 33 5f 76 61 6c 75 65  r*)sqlite3_value
80e0: 5f 74 65 78 74 28 61 70 41 72 67 5b 69 5d 29 29  _text(apArg[i]))
80f0: 3b 0a 20 20 7d 0a 20 20 72 63 20 3d 20 54 63 6c  ;.  }.  rc = Tcl
8100: 5f 45 76 61 6c 28 69 6e 74 65 72 70 2c 20 54 63  _Eval(interp, Tc
8110: 6c 5f 44 53 74 72 69 6e 67 56 61 6c 75 65 28 26  l_DStringValue(&
8120: 73 74 72 29 29 3b 0a 20 20 54 63 6c 5f 44 53 74  str));.  Tcl_DSt
8130: 72 69 6e 67 46 72 65 65 28 26 73 74 72 29 3b 0a  ringFree(&str);.
8140: 20 20 69 66 28 20 72 63 20 29 7b 0a 20 20 20 20    if( rc ){.    
8150: 73 71 6c 69 74 65 33 5f 72 65 73 75 6c 74 5f 65  sqlite3_result_e
8160: 72 72 6f 72 28 70 43 6f 6e 74 65 78 74 2c 20 54  rror(pContext, T
8170: 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75  cl_GetStringResu
8180: 6c 74 28 69 6e 74 65 72 70 29 2c 20 2d 31 29 3b  lt(interp), -1);
8190: 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 73 71  .  }else{.    sq
81a0: 6c 69 74 65 33 5f 72 65 73 75 6c 74 5f 74 65 78  lite3_result_tex
81b0: 74 28 70 43 6f 6e 74 65 78 74 2c 20 54 63 6c 5f  t(pContext, Tcl_
81c0: 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28  GetStringResult(
81d0: 69 6e 74 65 72 70 29 2c 0a 20 20 20 20 20 20 20  interp),.       
81e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
81f0: 20 2d 31 2c 20 53 51 4c 49 54 45 5f 54 52 41 4e   -1, SQLITE_TRAN
8200: 53 49 45 4e 54 29 3b 0a 20 20 7d 0a 20 20 54 63  SIENT);.  }.  Tc
8210: 6c 5f 52 65 73 65 74 52 65 73 75 6c 74 28 69 6e  l_ResetResult(in
8220: 74 65 72 70 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  terp);.}../*.** 
8230: 54 68 69 73 20 69 73 20 74 68 65 20 78 46 69 6e  This is the xFin
8240: 64 46 75 6e 63 74 69 6f 6e 20 69 6d 70 6c 65 6d  dFunction implem
8250: 65 6e 74 61 74 69 6f 6e 20 66 6f 72 20 74 68 65  entation for the
8260: 20 65 63 68 6f 20 6d 6f 64 75 6c 65 2e 0a 2a 2a   echo module..**
8270: 20 53 51 4c 69 74 65 20 63 61 6c 6c 73 20 74 68   SQLite calls th
8280: 69 73 20 72 6f 75 74 69 6e 65 20 77 68 65 6e 20  is routine when 
8290: 74 68 65 20 66 69 72 73 74 20 61 72 67 75 6d 65  the first argume
82a0: 6e 74 20 6f 66 20 61 20 66 75 6e 63 74 69 6f 6e  nt of a function
82b0: 0a 2a 2a 20 69 73 20 61 20 63 6f 6c 75 6d 6e 20  .** is a column 
82c0: 6f 66 20 61 6e 20 65 63 68 6f 20 76 69 72 74 75  of an echo virtu
82d0: 61 6c 20 74 61 62 6c 65 2e 20 20 54 68 69 73 20  al table.  This 
82e0: 72 6f 75 74 69 6e 65 20 63 61 6e 20 6f 70 74 69  routine can opti
82f0: 6f 6e 61 6c 6c 79 0a 2a 2a 20 6f 76 65 72 72 69  onally.** overri
8300: 64 65 20 74 68 65 20 69 6d 70 6c 65 6d 65 6e 74  de the implement
8310: 61 74 69 6f 6e 20 6f 66 20 74 68 61 74 20 66 75  ation of that fu
8320: 6e 63 74 69 6f 6e 2e 20 20 49 74 20 77 69 6c 6c  nction.  It will
8330: 20 63 68 6f 6f 73 65 20 74 6f 0a 2a 2a 20 64 6f   choose to.** do
8340: 20 73 6f 20 69 66 20 74 68 65 20 66 75 6e 63 74   so if the funct
8350: 69 6f 6e 20 69 73 20 6e 61 6d 65 64 20 22 67 6c  ion is named "gl
8360: 6f 62 22 2c 20 61 6e 64 20 61 20 54 43 4c 20 63  ob", and a TCL c
8370: 6f 6d 6d 61 6e 64 20 6e 61 6d 65 64 0a 2a 2a 20  ommand named.** 
8380: 3a 3a 65 63 68 6f 5f 67 6c 6f 62 5f 6f 76 65 72  ::echo_glob_over
8390: 6c 6f 61 64 20 65 78 69 73 74 73 2e 0a 2a 2f 0a  load exists..*/.
83a0: 73 74 61 74 69 63 20 69 6e 74 20 65 63 68 6f 46  static int echoF
83b0: 69 6e 64 46 75 6e 63 74 69 6f 6e 28 0a 20 20 73  indFunction(.  s
83c0: 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 76 74 61  qlite3_vtab *vta
83d0: 62 2c 0a 20 20 69 6e 74 20 6e 41 72 67 2c 0a 20  b,.  int nArg,. 
83e0: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 46 75   const char *zFu
83f0: 6e 63 4e 61 6d 65 2c 0a 20 20 76 6f 69 64 20 28  ncName,.  void (
8400: 2a 2a 70 78 46 75 6e 63 29 28 73 71 6c 69 74 65  **pxFunc)(sqlite
8410: 33 5f 63 6f 6e 74 65 78 74 2a 2c 69 6e 74 2c 73  3_context*,int,s
8420: 71 6c 69 74 65 33 5f 76 61 6c 75 65 2a 2a 29 2c  qlite3_value**),
8430: 0a 20 20 76 6f 69 64 20 2a 2a 70 70 41 72 67 0a  .  void **ppArg.
8440: 29 7b 0a 20 20 65 63 68 6f 5f 76 74 61 62 20 2a  ){.  echo_vtab *
8450: 70 56 74 61 62 20 3d 20 28 65 63 68 6f 5f 76 74  pVtab = (echo_vt
8460: 61 62 20 2a 29 76 74 61 62 3b 0a 20 20 54 63 6c  ab *)vtab;.  Tcl
8470: 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 20  _Interp *interp 
8480: 3d 20 70 56 74 61 62 2d 3e 69 6e 74 65 72 70 3b  = pVtab->interp;
8490: 0a 20 20 54 63 6c 5f 43 6d 64 49 6e 66 6f 20 69  .  Tcl_CmdInfo i
84a0: 6e 66 6f 3b 0a 20 20 69 66 28 20 73 74 72 63 6d  nfo;.  if( strcm
84b0: 70 28 7a 46 75 6e 63 4e 61 6d 65 2c 22 67 6c 6f  p(zFuncName,"glo
84c0: 62 22 29 21 3d 30 20 29 7b 0a 20 20 20 20 72 65  b")!=0 ){.    re
84d0: 74 75 72 6e 20 30 3b 0a 20 20 7d 0a 20 20 69 66  turn 0;.  }.  if
84e0: 28 20 54 63 6c 5f 47 65 74 43 6f 6d 6d 61 6e 64  ( Tcl_GetCommand
84f0: 49 6e 66 6f 28 69 6e 74 65 72 70 2c 20 22 3a 3a  Info(interp, "::
8500: 65 63 68 6f 5f 67 6c 6f 62 5f 6f 76 65 72 6c 6f  echo_glob_overlo
8510: 61 64 22 2c 20 26 69 6e 66 6f 29 3d 3d 30 20 29  ad", &info)==0 )
8520: 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 30 3b 0a  {.    return 0;.
8530: 20 20 7d 0a 20 20 2a 70 78 46 75 6e 63 20 3d 20    }.  *pxFunc = 
8540: 6f 76 65 72 6c 6f 61 64 65 64 47 6c 6f 62 46 75  overloadedGlobFu
8550: 6e 63 74 69 6f 6e 3b 0a 20 20 2a 70 70 41 72 67  nction;.  *ppArg
8560: 20 3d 20 69 6e 74 65 72 70 3b 0a 20 20 72 65 74   = interp;.  ret
8570: 75 72 6e 20 31 3b 0a 7d 0a 0a 73 74 61 74 69 63  urn 1;.}..static
8580: 20 69 6e 74 20 65 63 68 6f 52 65 6e 61 6d 65 28   int echoRename(
8590: 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 76 74  sqlite3_vtab *vt
85a0: 61 62 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a  ab, const char *
85b0: 7a 4e 65 77 4e 61 6d 65 29 7b 0a 20 20 69 6e 74  zNewName){.  int
85c0: 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b   rc = SQLITE_OK;
85d0: 0a 20 20 65 63 68 6f 5f 76 74 61 62 20 2a 70 20  .  echo_vtab *p 
85e0: 3d 20 28 65 63 68 6f 5f 76 74 61 62 20 2a 29 76  = (echo_vtab *)v
85f0: 74 61 62 3b 0a 0a 20 20 69 66 28 20 73 69 6d 75  tab;..  if( simu
8600: 6c 61 74 65 56 74 61 62 45 72 72 6f 72 28 70 2c  lateVtabError(p,
8610: 20 22 78 52 65 6e 61 6d 65 22 29 20 29 7b 0a 20   "xRename") ){. 
8620: 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45     return SQLITE
8630: 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a 0a 20 20 69  _ERROR;.  }..  i
8640: 66 28 20 70 2d 3e 69 73 50 61 74 74 65 72 6e 20  f( p->isPattern 
8650: 29 7b 0a 20 20 20 20 69 6e 74 20 6e 54 68 69 73  ){.    int nThis
8660: 20 3d 20 28 69 6e 74 29 73 74 72 6c 65 6e 28 70   = (int)strlen(p
8670: 2d 3e 7a 54 68 69 73 29 3b 0a 20 20 20 20 63 68  ->zThis);.    ch
8680: 61 72 20 2a 7a 53 71 6c 20 3d 20 73 71 6c 69 74  ar *zSql = sqlit
8690: 65 33 5f 6d 70 72 69 6e 74 66 28 22 41 4c 54 45  e3_mprintf("ALTE
86a0: 52 20 54 41 42 4c 45 20 25 73 20 52 45 4e 41 4d  R TABLE %s RENAM
86b0: 45 20 54 4f 20 25 73 25 73 22 2c 20 0a 20 20 20  E TO %s%s", .   
86c0: 20 20 20 20 20 70 2d 3e 7a 54 61 62 6c 65 4e 61       p->zTableNa
86d0: 6d 65 2c 20 7a 4e 65 77 4e 61 6d 65 2c 20 26 70  me, zNewName, &p
86e0: 2d 3e 7a 54 61 62 6c 65 4e 61 6d 65 5b 6e 54 68  ->zTableName[nTh
86f0: 69 73 5d 0a 20 20 20 20 29 3b 0a 20 20 20 20 72  is].    );.    r
8700: 63 20 3d 20 73 71 6c 69 74 65 33 5f 65 78 65 63  c = sqlite3_exec
8710: 28 70 2d 3e 64 62 2c 20 7a 53 71 6c 2c 20 30 2c  (p->db, zSql, 0,
8720: 20 30 2c 20 30 29 3b 0a 20 20 20 20 73 71 6c 69   0, 0);.    sqli
8730: 74 65 33 5f 66 72 65 65 28 7a 53 71 6c 29 3b 0a  te3_free(zSql);.
8740: 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 72 63    }..  return rc
8750: 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20  ;.}..static int 
8760: 65 63 68 6f 53 61 76 65 70 6f 69 6e 74 28 73 71  echoSavepoint(sq
8770: 6c 69 74 65 33 5f 76 74 61 62 20 2a 70 56 54 61  lite3_vtab *pVTa
8780: 62 2c 20 69 6e 74 20 69 53 61 76 65 70 6f 69 6e  b, int iSavepoin
8790: 74 29 7b 0a 20 20 61 73 73 65 72 74 28 20 70 56  t){.  assert( pV
87a0: 54 61 62 20 29 3b 0a 20 20 72 65 74 75 72 6e 20  Tab );.  return 
87b0: 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 73 74  SQLITE_OK;.}..st
87c0: 61 74 69 63 20 69 6e 74 20 65 63 68 6f 52 65 6c  atic int echoRel
87d0: 65 61 73 65 28 73 71 6c 69 74 65 33 5f 76 74 61  ease(sqlite3_vta
87e0: 62 20 2a 70 56 54 61 62 2c 20 69 6e 74 20 69 53  b *pVTab, int iS
87f0: 61 76 65 70 6f 69 6e 74 29 7b 0a 20 20 61 73 73  avepoint){.  ass
8800: 65 72 74 28 20 70 56 54 61 62 20 29 3b 0a 20 20  ert( pVTab );.  
8810: 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b  return SQLITE_OK
8820: 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20  ;.}..static int 
8830: 65 63 68 6f 52 6f 6c 6c 62 61 63 6b 54 6f 28 73  echoRollbackTo(s
8840: 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 70 56 54  qlite3_vtab *pVT
8850: 61 62 2c 20 69 6e 74 20 69 53 61 76 65 70 6f 69  ab, int iSavepoi
8860: 6e 74 29 7b 0a 20 20 61 73 73 65 72 74 28 20 70  nt){.  assert( p
8870: 56 54 61 62 20 29 3b 0a 20 20 72 65 74 75 72 6e  VTab );.  return
8880: 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f   SQLITE_OK;.}../
8890: 2a 0a 2a 2a 20 41 20 76 69 72 74 75 61 6c 20 74  *.** A virtual t
88a0: 61 62 6c 65 20 6d 6f 64 75 6c 65 20 74 68 61 74  able module that
88b0: 20 6d 65 72 65 6c 79 20 22 65 63 68 6f 73 22 20   merely "echos" 
88c0: 74 68 65 20 63 6f 6e 74 65 6e 74 73 20 6f 66 20  the contents of 
88d0: 61 6e 6f 74 68 65 72 0a 2a 2a 20 74 61 62 6c 65  another.** table
88e0: 20 28 6c 69 6b 65 20 61 6e 20 53 51 4c 20 56 49   (like an SQL VI
88f0: 45 57 29 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 73  EW)..*/.static s
8900: 71 6c 69 74 65 33 5f 6d 6f 64 75 6c 65 20 65 63  qlite3_module ec
8910: 68 6f 4d 6f 64 75 6c 65 20 3d 20 7b 0a 20 20 31  hoModule = {.  1
8920: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
8930: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 69 56 65            /* iVe
8940: 72 73 69 6f 6e 20 2a 2f 0a 20 20 65 63 68 6f 43  rsion */.  echoC
8950: 72 65 61 74 65 2c 0a 20 20 65 63 68 6f 43 6f 6e  reate,.  echoCon
8960: 6e 65 63 74 2c 0a 20 20 65 63 68 6f 42 65 73 74  nect,.  echoBest
8970: 49 6e 64 65 78 2c 0a 20 20 65 63 68 6f 44 69 73  Index,.  echoDis
8980: 63 6f 6e 6e 65 63 74 2c 20 0a 20 20 65 63 68 6f  connect, .  echo
8990: 44 65 73 74 72 6f 79 2c 0a 20 20 65 63 68 6f 4f  Destroy,.  echoO
89a0: 70 65 6e 2c 20 20 20 20 20 20 20 20 20 20 20 20  pen,            
89b0: 20 20 20 20 20 20 2f 2a 20 78 4f 70 65 6e 20 2d        /* xOpen -
89c0: 20 6f 70 65 6e 20 61 20 63 75 72 73 6f 72 20 2a   open a cursor *
89d0: 2f 0a 20 20 65 63 68 6f 43 6c 6f 73 65 2c 20 20  /.  echoClose,  
89e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
89f0: 2a 20 78 43 6c 6f 73 65 20 2d 20 63 6c 6f 73 65  * xClose - close
8a00: 20 61 20 63 75 72 73 6f 72 20 2a 2f 0a 20 20 65   a cursor */.  e
8a10: 63 68 6f 46 69 6c 74 65 72 2c 20 20 20 20 20 20  choFilter,      
8a20: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 46 69            /* xFi
8a30: 6c 74 65 72 20 2d 20 63 6f 6e 66 69 67 75 72 65  lter - configure
8a40: 20 73 63 61 6e 20 63 6f 6e 73 74 72 61 69 6e 74   scan constraint
8a50: 73 20 2a 2f 0a 20 20 65 63 68 6f 4e 65 78 74 2c  s */.  echoNext,
8a60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8a70: 20 20 2f 2a 20 78 4e 65 78 74 20 2d 20 61 64 76    /* xNext - adv
8a80: 61 6e 63 65 20 61 20 63 75 72 73 6f 72 20 2a 2f  ance a cursor */
8a90: 0a 20 20 65 63 68 6f 45 6f 66 2c 20 20 20 20 20  .  echoEof,     
8aa0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
8ab0: 20 78 45 6f 66 20 2a 2f 0a 20 20 65 63 68 6f 43   xEof */.  echoC
8ac0: 6f 6c 75 6d 6e 2c 20 20 20 20 20 20 20 20 20 20  olumn,          
8ad0: 20 20 20 20 20 20 2f 2a 20 78 43 6f 6c 75 6d 6e        /* xColumn
8ae0: 20 2d 20 72 65 61 64 20 64 61 74 61 20 2a 2f 0a   - read data */.
8af0: 20 20 65 63 68 6f 52 6f 77 69 64 2c 20 20 20 20    echoRowid,    
8b00: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
8b10: 78 52 6f 77 69 64 20 2d 20 72 65 61 64 20 64 61  xRowid - read da
8b20: 74 61 20 2a 2f 0a 20 20 65 63 68 6f 55 70 64 61  ta */.  echoUpda
8b30: 74 65 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  te,             
8b40: 20 20 20 2f 2a 20 78 55 70 64 61 74 65 20 2d 20     /* xUpdate - 
8b50: 77 72 69 74 65 20 64 61 74 61 20 2a 2f 0a 20 20  write data */.  
8b60: 65 63 68 6f 42 65 67 69 6e 2c 20 20 20 20 20 20  echoBegin,      
8b70: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 42             /* xB
8b80: 65 67 69 6e 20 2d 20 62 65 67 69 6e 20 74 72 61  egin - begin tra
8b90: 6e 73 61 63 74 69 6f 6e 20 2a 2f 0a 20 20 65 63  nsaction */.  ec
8ba0: 68 6f 53 79 6e 63 2c 20 20 20 20 20 20 20 20 20  hoSync,         
8bb0: 20 20 20 20 20 20 20 20 20 2f 2a 20 78 53 79 6e           /* xSyn
8bc0: 63 20 2d 20 73 79 6e 63 20 74 72 61 6e 73 61 63  c - sync transac
8bd0: 74 69 6f 6e 20 2a 2f 0a 20 20 65 63 68 6f 43 6f  tion */.  echoCo
8be0: 6d 6d 69 74 2c 20 20 20 20 20 20 20 20 20 20 20  mmit,           
8bf0: 20 20 20 20 20 2f 2a 20 78 43 6f 6d 6d 69 74 20       /* xCommit 
8c00: 2d 20 63 6f 6d 6d 69 74 20 74 72 61 6e 73 61 63  - commit transac
8c10: 74 69 6f 6e 20 2a 2f 0a 20 20 65 63 68 6f 52 6f  tion */.  echoRo
8c20: 6c 6c 62 61 63 6b 2c 20 20 20 20 20 20 20 20 20  llback,         
8c30: 20 20 20 20 20 2f 2a 20 78 52 6f 6c 6c 62 61 63       /* xRollbac
8c40: 6b 20 2d 20 72 6f 6c 6c 62 61 63 6b 20 74 72 61  k - rollback tra
8c50: 6e 73 61 63 74 69 6f 6e 20 2a 2f 0a 20 20 65 63  nsaction */.  ec
8c60: 68 6f 46 69 6e 64 46 75 6e 63 74 69 6f 6e 2c 20  hoFindFunction, 
8c70: 20 20 20 20 20 20 20 20 20 2f 2a 20 78 46 69 6e           /* xFin
8c80: 64 46 75 6e 63 74 69 6f 6e 20 2d 20 66 75 6e 63  dFunction - func
8c90: 74 69 6f 6e 20 6f 76 65 72 6c 6f 61 64 69 6e 67  tion overloading
8ca0: 20 2a 2f 0a 20 20 65 63 68 6f 52 65 6e 61 6d 65   */.  echoRename
8cb0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8cc0: 20 2f 2a 20 78 52 65 6e 61 6d 65 20 2d 20 72 65   /* xRename - re
8cd0: 6e 61 6d 65 20 74 68 65 20 74 61 62 6c 65 20 2a  name the table *
8ce0: 2f 0a 7d 3b 0a 0a 73 74 61 74 69 63 20 73 71 6c  /.};..static sql
8cf0: 69 74 65 33 5f 6d 6f 64 75 6c 65 20 65 63 68 6f  ite3_module echo
8d00: 4d 6f 64 75 6c 65 56 32 20 3d 20 7b 0a 20 20 32  ModuleV2 = {.  2
8d10: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
8d20: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 69 56 65            /* iVe
8d30: 72 73 69 6f 6e 20 2a 2f 0a 20 20 65 63 68 6f 43  rsion */.  echoC
8d40: 72 65 61 74 65 2c 0a 20 20 65 63 68 6f 43 6f 6e  reate,.  echoCon
8d50: 6e 65 63 74 2c 0a 20 20 65 63 68 6f 42 65 73 74  nect,.  echoBest
8d60: 49 6e 64 65 78 2c 0a 20 20 65 63 68 6f 44 69 73  Index,.  echoDis
8d70: 63 6f 6e 6e 65 63 74 2c 20 0a 20 20 65 63 68 6f  connect, .  echo
8d80: 44 65 73 74 72 6f 79 2c 0a 20 20 65 63 68 6f 4f  Destroy,.  echoO
8d90: 70 65 6e 2c 20 20 20 20 20 20 20 20 20 20 20 20  pen,            
8da0: 20 20 20 20 20 20 2f 2a 20 78 4f 70 65 6e 20 2d        /* xOpen -
8db0: 20 6f 70 65 6e 20 61 20 63 75 72 73 6f 72 20 2a   open a cursor *
8dc0: 2f 0a 20 20 65 63 68 6f 43 6c 6f 73 65 2c 20 20  /.  echoClose,  
8dd0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
8de0: 2a 20 78 43 6c 6f 73 65 20 2d 20 63 6c 6f 73 65  * xClose - close
8df0: 20 61 20 63 75 72 73 6f 72 20 2a 2f 0a 20 20 65   a cursor */.  e
8e00: 63 68 6f 46 69 6c 74 65 72 2c 20 20 20 20 20 20  choFilter,      
8e10: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 46 69            /* xFi
8e20: 6c 74 65 72 20 2d 20 63 6f 6e 66 69 67 75 72 65  lter - configure
8e30: 20 73 63 61 6e 20 63 6f 6e 73 74 72 61 69 6e 74   scan constraint
8e40: 73 20 2a 2f 0a 20 20 65 63 68 6f 4e 65 78 74 2c  s */.  echoNext,
8e50: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8e60: 20 20 2f 2a 20 78 4e 65 78 74 20 2d 20 61 64 76    /* xNext - adv
8e70: 61 6e 63 65 20 61 20 63 75 72 73 6f 72 20 2a 2f  ance a cursor */
8e80: 0a 20 20 65 63 68 6f 45 6f 66 2c 20 20 20 20 20  .  echoEof,     
8e90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
8ea0: 20 78 45 6f 66 20 2a 2f 0a 20 20 65 63 68 6f 43   xEof */.  echoC
8eb0: 6f 6c 75 6d 6e 2c 20 20 20 20 20 20 20 20 20 20  olumn,          
8ec0: 20 20 20 20 20 20 2f 2a 20 78 43 6f 6c 75 6d 6e        /* xColumn
8ed0: 20 2d 20 72 65 61 64 20 64 61 74 61 20 2a 2f 0a   - read data */.
8ee0: 20 20 65 63 68 6f 52 6f 77 69 64 2c 20 20 20 20    echoRowid,    
8ef0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
8f00: 78 52 6f 77 69 64 20 2d 20 72 65 61 64 20 64 61  xRowid - read da
8f10: 74 61 20 2a 2f 0a 20 20 65 63 68 6f 55 70 64 61  ta */.  echoUpda
8f20: 74 65 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  te,             
8f30: 20 20 20 2f 2a 20 78 55 70 64 61 74 65 20 2d 20     /* xUpdate - 
8f40: 77 72 69 74 65 20 64 61 74 61 20 2a 2f 0a 20 20  write data */.  
8f50: 65 63 68 6f 42 65 67 69 6e 2c 20 20 20 20 20 20  echoBegin,      
8f60: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 42             /* xB
8f70: 65 67 69 6e 20 2d 20 62 65 67 69 6e 20 74 72 61  egin - begin tra
8f80: 6e 73 61 63 74 69 6f 6e 20 2a 2f 0a 20 20 65 63  nsaction */.  ec
8f90: 68 6f 53 79 6e 63 2c 20 20 20 20 20 20 20 20 20  hoSync,         
8fa0: 20 20 20 20 20 20 20 20 20 2f 2a 20 78 53 79 6e           /* xSyn
8fb0: 63 20 2d 20 73 79 6e 63 20 74 72 61 6e 73 61 63  c - sync transac
8fc0: 74 69 6f 6e 20 2a 2f 0a 20 20 65 63 68 6f 43 6f  tion */.  echoCo
8fd0: 6d 6d 69 74 2c 20 20 20 20 20 20 20 20 20 20 20  mmit,           
8fe0: 20 20 20 20 20 2f 2a 20 78 43 6f 6d 6d 69 74 20       /* xCommit 
8ff0: 2d 20 63 6f 6d 6d 69 74 20 74 72 61 6e 73 61 63  - commit transac
9000: 74 69 6f 6e 20 2a 2f 0a 20 20 65 63 68 6f 52 6f  tion */.  echoRo
9010: 6c 6c 62 61 63 6b 2c 20 20 20 20 20 20 20 20 20  llback,         
9020: 20 20 20 20 20 2f 2a 20 78 52 6f 6c 6c 62 61 63       /* xRollbac
9030: 6b 20 2d 20 72 6f 6c 6c 62 61 63 6b 20 74 72 61  k - rollback tra
9040: 6e 73 61 63 74 69 6f 6e 20 2a 2f 0a 20 20 65 63  nsaction */.  ec
9050: 68 6f 46 69 6e 64 46 75 6e 63 74 69 6f 6e 2c 20  hoFindFunction, 
9060: 20 20 20 20 20 20 20 20 20 2f 2a 20 78 46 69 6e           /* xFin
9070: 64 46 75 6e 63 74 69 6f 6e 20 2d 20 66 75 6e 63  dFunction - func
9080: 74 69 6f 6e 20 6f 76 65 72 6c 6f 61 64 69 6e 67  tion overloading
9090: 20 2a 2f 0a 20 20 65 63 68 6f 52 65 6e 61 6d 65   */.  echoRename
90a0: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
90b0: 20 2f 2a 20 78 52 65 6e 61 6d 65 20 2d 20 72 65   /* xRename - re
90c0: 6e 61 6d 65 20 74 68 65 20 74 61 62 6c 65 20 2a  name the table *
90d0: 2f 0a 20 20 65 63 68 6f 53 61 76 65 70 6f 69 6e  /.  echoSavepoin
90e0: 74 2c 0a 20 20 65 63 68 6f 52 65 6c 65 61 73 65  t,.  echoRelease
90f0: 2c 0a 20 20 65 63 68 6f 52 6f 6c 6c 62 61 63 6b  ,.  echoRollback
9100: 54 6f 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 44 65 63  To.};../*.** Dec
9110: 6f 64 65 20 61 20 70 6f 69 6e 74 65 72 20 74 6f  ode a pointer to
9120: 20 61 6e 20 73 71 6c 69 74 65 33 20 6f 62 6a 65   an sqlite3 obje
9130: 63 74 2e 0a 2a 2f 0a 65 78 74 65 72 6e 20 69 6e  ct..*/.extern in
9140: 74 20 67 65 74 44 62 50 6f 69 6e 74 65 72 28 54  t getDbPointer(T
9150: 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72  cl_Interp *inter
9160: 70 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a  p, const char *z
9170: 41 2c 20 73 71 6c 69 74 65 33 20 2a 2a 70 70 44  A, sqlite3 **ppD
9180: 62 29 3b 0a 0a 73 74 61 74 69 63 20 76 6f 69 64  b);..static void
9190: 20 6d 6f 64 75 6c 65 44 65 73 74 72 6f 79 28 76   moduleDestroy(v
91a0: 6f 69 64 20 2a 70 29 7b 0a 20 20 73 71 6c 69 74  oid *p){.  sqlit
91b0: 65 33 5f 66 72 65 65 28 70 29 3b 0a 7d 0a 0a 2f  e3_free(p);.}../
91c0: 2a 0a 2a 2a 20 52 65 67 69 73 74 65 72 20 74 68  *.** Register th
91d0: 65 20 65 63 68 6f 20 76 69 72 74 75 61 6c 20 74  e echo virtual t
91e0: 61 62 6c 65 20 6d 6f 64 75 6c 65 2e 0a 2a 2f 0a  able module..*/.
91f0: 73 74 61 74 69 63 20 69 6e 74 20 72 65 67 69 73  static int regis
9200: 74 65 72 5f 65 63 68 6f 5f 6d 6f 64 75 6c 65 28  ter_echo_module(
9210: 0a 20 20 43 6c 69 65 6e 74 44 61 74 61 20 63 6c  .  ClientData cl
9220: 69 65 6e 74 44 61 74 61 2c 20 2f 2a 20 50 6f 69  ientData, /* Poi
9230: 6e 74 65 72 20 74 6f 20 73 71 6c 69 74 65 33 5f  nter to sqlite3_
9240: 65 6e 61 62 6c 65 5f 58 58 58 20 66 75 6e 63 74  enable_XXX funct
9250: 69 6f 6e 20 2a 2f 0a 20 20 54 63 6c 5f 49 6e 74  ion */.  Tcl_Int
9260: 65 72 70 20 2a 69 6e 74 65 72 70 2c 20 20 20 20  erp *interp,    
9270: 2f 2a 20 54 68 65 20 54 43 4c 20 69 6e 74 65 72  /* The TCL inter
9280: 70 72 65 74 65 72 20 74 68 61 74 20 69 6e 76 6f  preter that invo
9290: 6b 65 64 20 74 68 69 73 20 63 6f 6d 6d 61 6e 64  ked this command
92a0: 20 2a 2f 0a 20 20 69 6e 74 20 6f 62 6a 63 2c 20   */.  int objc, 
92b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
92c0: 4e 75 6d 62 65 72 20 6f 66 20 61 72 67 75 6d 65  Number of argume
92d0: 6e 74 73 20 2a 2f 0a 20 20 54 63 6c 5f 4f 62 6a  nts */.  Tcl_Obj
92e0: 20 2a 43 4f 4e 53 54 20 6f 62 6a 76 5b 5d 20 20   *CONST objv[]  
92f0: 2f 2a 20 43 6f 6d 6d 61 6e 64 20 61 72 67 75 6d  /* Command argum
9300: 65 6e 74 73 20 2a 2f 0a 29 7b 0a 20 20 73 71 6c  ents */.){.  sql
9310: 69 74 65 33 20 2a 64 62 3b 0a 20 20 45 63 68 6f  ite3 *db;.  Echo
9320: 4d 6f 64 75 6c 65 20 2a 70 4d 6f 64 3b 0a 20 20  Module *pMod;.  
9330: 69 66 28 20 6f 62 6a 63 21 3d 32 20 29 7b 0a 20  if( objc!=2 ){. 
9340: 20 20 20 54 63 6c 5f 57 72 6f 6e 67 4e 75 6d 41     Tcl_WrongNumA
9350: 72 67 73 28 69 6e 74 65 72 70 2c 20 31 2c 20 6f  rgs(interp, 1, o
9360: 62 6a 76 2c 20 22 44 42 22 29 3b 0a 20 20 20 20  bjv, "DB");.    
9370: 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52  return TCL_ERROR
9380: 3b 0a 20 20 7d 0a 20 20 69 66 28 20 67 65 74 44  ;.  }.  if( getD
9390: 62 50 6f 69 6e 74 65 72 28 69 6e 74 65 72 70 2c  bPointer(interp,
93a0: 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 28 6f   Tcl_GetString(o
93b0: 62 6a 76 5b 31 5d 29 2c 20 26 64 62 29 20 29 20  bjv[1]), &db) ) 
93c0: 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52  return TCL_ERROR
93d0: 3b 0a 0a 20 20 2f 2a 20 56 69 72 74 75 61 6c 20  ;..  /* Virtual 
93e0: 74 61 62 6c 65 20 6d 6f 64 75 6c 65 20 22 65 63  table module "ec
93f0: 68 6f 22 20 2a 2f 0a 20 20 70 4d 6f 64 20 3d 20  ho" */.  pMod = 
9400: 73 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63 28 73  sqlite3_malloc(s
9410: 69 7a 65 6f 66 28 45 63 68 6f 4d 6f 64 75 6c 65  izeof(EchoModule
9420: 29 29 3b 0a 20 20 70 4d 6f 64 2d 3e 69 6e 74 65  ));.  pMod->inte
9430: 72 70 20 3d 20 69 6e 74 65 72 70 3b 0a 20 20 73  rp = interp;.  s
9440: 71 6c 69 74 65 33 5f 63 72 65 61 74 65 5f 6d 6f  qlite3_create_mo
9450: 64 75 6c 65 5f 76 32 28 64 62 2c 20 22 65 63 68  dule_v2(db, "ech
9460: 6f 22 2c 20 26 65 63 68 6f 4d 6f 64 75 6c 65 2c  o", &echoModule,
9470: 20 28 76 6f 69 64 2a 29 70 4d 6f 64 2c 20 6d 6f   (void*)pMod, mo
9480: 64 75 6c 65 44 65 73 74 72 6f 79 29 3b 0a 0a 20  duleDestroy);.. 
9490: 20 2f 2a 20 56 69 72 74 75 61 6c 20 74 61 62 6c   /* Virtual tabl
94a0: 65 20 6d 6f 64 75 6c 65 20 22 65 63 68 6f 5f 76  e module "echo_v
94b0: 32 22 20 2a 2f 0a 20 20 70 4d 6f 64 20 3d 20 73  2" */.  pMod = s
94c0: 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63 28 73 69  qlite3_malloc(si
94d0: 7a 65 6f 66 28 45 63 68 6f 4d 6f 64 75 6c 65 29  zeof(EchoModule)
94e0: 29 3b 0a 20 20 70 4d 6f 64 2d 3e 69 6e 74 65 72  );.  pMod->inter
94f0: 70 20 3d 20 69 6e 74 65 72 70 3b 0a 20 20 73 71  p = interp;.  sq
9500: 6c 69 74 65 33 5f 63 72 65 61 74 65 5f 6d 6f 64  lite3_create_mod
9510: 75 6c 65 5f 76 32 28 64 62 2c 20 22 65 63 68 6f  ule_v2(db, "echo
9520: 5f 76 32 22 2c 20 0a 20 20 20 20 20 20 26 65 63  _v2", .      &ec
9530: 68 6f 4d 6f 64 75 6c 65 56 32 2c 20 28 76 6f 69  hoModuleV2, (voi
9540: 64 2a 29 70 4d 6f 64 2c 20 6d 6f 64 75 6c 65 44  d*)pMod, moduleD
9550: 65 73 74 72 6f 79 0a 20 20 29 3b 0a 20 20 72 65  estroy.  );.  re
9560: 74 75 72 6e 20 54 43 4c 5f 4f 4b 3b 0a 7d 0a 0a  turn TCL_OK;.}..
9570: 2f 2a 0a 2a 2a 20 54 63 6c 20 69 6e 74 65 72 66  /*.** Tcl interf
9580: 61 63 65 20 74 6f 20 73 71 6c 69 74 65 33 5f 64  ace to sqlite3_d
9590: 65 63 6c 61 72 65 5f 76 74 61 62 2c 20 69 6e 76  eclare_vtab, inv
95a0: 6f 6b 65 64 20 61 73 20 66 6f 6c 6c 6f 77 73 20  oked as follows 
95b0: 66 72 6f 6d 20 54 63 6c 3a 0a 2a 2a 0a 2a 2a 20  from Tcl:.**.** 
95c0: 73 71 6c 69 74 65 33 5f 64 65 63 6c 61 72 65 5f  sqlite3_declare_
95d0: 76 74 61 62 20 44 42 20 53 51 4c 0a 2a 2f 0a 73  vtab DB SQL.*/.s
95e0: 74 61 74 69 63 20 69 6e 74 20 64 65 63 6c 61 72  tatic int declar
95f0: 65 5f 76 74 61 62 28 0a 20 20 43 6c 69 65 6e 74  e_vtab(.  Client
9600: 44 61 74 61 20 63 6c 69 65 6e 74 44 61 74 61 2c  Data clientData,
9610: 20 2f 2a 20 50 6f 69 6e 74 65 72 20 74 6f 20 73   /* Pointer to s
9620: 71 6c 69 74 65 33 5f 65 6e 61 62 6c 65 5f 58 58  qlite3_enable_XX
9630: 58 20 66 75 6e 63 74 69 6f 6e 20 2a 2f 0a 20 20  X function */.  
9640: 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65  Tcl_Interp *inte
9650: 72 70 2c 20 20 20 20 2f 2a 20 54 68 65 20 54 43  rp,    /* The TC
9660: 4c 20 69 6e 74 65 72 70 72 65 74 65 72 20 74 68  L interpreter th
9670: 61 74 20 69 6e 76 6f 6b 65 64 20 74 68 69 73 20  at invoked this 
9680: 63 6f 6d 6d 61 6e 64 20 2a 2f 0a 20 20 69 6e 74  command */.  int
9690: 20 6f 62 6a 63 2c 20 20 20 20 20 20 20 20 20 20   objc,          
96a0: 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66      /* Number of
96b0: 20 61 72 67 75 6d 65 6e 74 73 20 2a 2f 0a 20 20   arguments */.  
96c0: 54 63 6c 5f 4f 62 6a 20 2a 43 4f 4e 53 54 20 6f  Tcl_Obj *CONST o
96d0: 62 6a 76 5b 5d 20 20 2f 2a 20 43 6f 6d 6d 61 6e  bjv[]  /* Comman
96e0: 64 20 61 72 67 75 6d 65 6e 74 73 20 2a 2f 0a 29  d arguments */.)
96f0: 7b 0a 20 20 73 71 6c 69 74 65 33 20 2a 64 62 3b  {.  sqlite3 *db;
9700: 0a 20 20 69 6e 74 20 72 63 3b 0a 20 20 69 66 28  .  int rc;.  if(
9710: 20 6f 62 6a 63 21 3d 33 20 29 7b 0a 20 20 20 20   objc!=3 ){.    
9720: 54 63 6c 5f 57 72 6f 6e 67 4e 75 6d 41 72 67 73  Tcl_WrongNumArgs
9730: 28 69 6e 74 65 72 70 2c 20 31 2c 20 6f 62 6a 76  (interp, 1, objv
9740: 2c 20 22 44 42 20 53 51 4c 22 29 3b 0a 20 20 20  , "DB SQL");.   
9750: 20 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f   return TCL_ERRO
9760: 52 3b 0a 20 20 7d 0a 20 20 69 66 28 20 67 65 74  R;.  }.  if( get
9770: 44 62 50 6f 69 6e 74 65 72 28 69 6e 74 65 72 70  DbPointer(interp
9780: 2c 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 28  , Tcl_GetString(
9790: 6f 62 6a 76 5b 31 5d 29 2c 20 26 64 62 29 20 29  objv[1]), &db) )
97a0: 20 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f   return TCL_ERRO
97b0: 52 3b 0a 20 20 72 63 20 3d 20 73 71 6c 69 74 65  R;.  rc = sqlite
97c0: 33 5f 64 65 63 6c 61 72 65 5f 76 74 61 62 28 64  3_declare_vtab(d
97d0: 62 2c 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67  b, Tcl_GetString
97e0: 28 6f 62 6a 76 5b 32 5d 29 29 3b 0a 20 20 69 66  (objv[2]));.  if
97f0: 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc!=SQLITE_OK 
9800: 29 7b 0a 20 20 20 20 54 63 6c 5f 53 65 74 52 65  ){.    Tcl_SetRe
9810: 73 75 6c 74 28 69 6e 74 65 72 70 2c 20 28 63 68  sult(interp, (ch
9820: 61 72 20 2a 29 73 71 6c 69 74 65 33 5f 65 72 72  ar *)sqlite3_err
9830: 6d 73 67 28 64 62 29 2c 20 54 43 4c 5f 56 4f 4c  msg(db), TCL_VOL
9840: 41 54 49 4c 45 29 3b 0a 20 20 20 20 72 65 74 75  ATILE);.    retu
9850: 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20  rn TCL_ERROR;.  
9860: 7d 0a 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 4f  }.  return TCL_O
9870: 4b 3b 0a 7d 0a 0a 23 65 6e 64 69 66 20 2f 2a 20  K;.}..#endif /* 
9880: 69 66 6e 64 65 66 20 53 51 4c 49 54 45 5f 4f 4d  ifndef SQLITE_OM
9890: 49 54 5f 56 49 52 54 55 41 4c 54 41 42 4c 45 20  IT_VIRTUALTABLE 
98a0: 2a 2f 0a 0a 2f 2a 0a 2a 2a 20 52 65 67 69 73 74  */../*.** Regist
98b0: 65 72 20 63 6f 6d 6d 61 6e 64 73 20 77 69 74 68  er commands with
98c0: 20 74 68 65 20 54 43 4c 20 69 6e 74 65 72 70 72   the TCL interpr
98d0: 65 74 65 72 2e 0a 2a 2f 0a 69 6e 74 20 53 71 6c  eter..*/.int Sql
98e0: 69 74 65 74 65 73 74 38 5f 49 6e 69 74 28 54 63  itetest8_Init(Tc
98f0: 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70  l_Interp *interp
9900: 29 7b 0a 23 69 66 6e 64 65 66 20 53 51 4c 49 54  ){.#ifndef SQLIT
9910: 45 5f 4f 4d 49 54 5f 56 49 52 54 55 41 4c 54 41  E_OMIT_VIRTUALTA
9920: 42 4c 45 0a 20 20 73 74 61 74 69 63 20 73 74 72  BLE.  static str
9930: 75 63 74 20 7b 0a 20 20 20 20 20 63 68 61 72 20  uct {.     char 
9940: 2a 7a 4e 61 6d 65 3b 0a 20 20 20 20 20 54 63 6c  *zName;.     Tcl
9950: 5f 4f 62 6a 43 6d 64 50 72 6f 63 20 2a 78 50 72  _ObjCmdProc *xPr
9960: 6f 63 3b 0a 20 20 20 20 20 76 6f 69 64 20 2a 63  oc;.     void *c
9970: 6c 69 65 6e 74 44 61 74 61 3b 0a 20 20 7d 20 61  lientData;.  } a
9980: 4f 62 6a 43 6d 64 5b 5d 20 3d 20 7b 0a 20 20 20  ObjCmd[] = {.   
9990: 20 20 7b 20 22 72 65 67 69 73 74 65 72 5f 65 63    { "register_ec
99a0: 68 6f 5f 6d 6f 64 75 6c 65 22 2c 20 20 20 72 65  ho_module",   re
99b0: 67 69 73 74 65 72 5f 65 63 68 6f 5f 6d 6f 64 75  gister_echo_modu
99c0: 6c 65 2c 20 30 20 7d 2c 0a 20 20 20 20 20 7b 20  le, 0 },.     { 
99d0: 22 73 71 6c 69 74 65 33 5f 64 65 63 6c 61 72 65  "sqlite3_declare
99e0: 5f 76 74 61 62 22 2c 20 20 20 64 65 63 6c 61 72  _vtab",   declar
99f0: 65 5f 76 74 61 62 2c 20 30 20 7d 2c 0a 20 20 7d  e_vtab, 0 },.  }
9a00: 3b 0a 20 20 69 6e 74 20 69 3b 0a 20 20 66 6f 72  ;.  int i;.  for
9a10: 28 69 3d 30 3b 20 69 3c 73 69 7a 65 6f 66 28 61  (i=0; i<sizeof(a
9a20: 4f 62 6a 43 6d 64 29 2f 73 69 7a 65 6f 66 28 61  ObjCmd)/sizeof(a
9a30: 4f 62 6a 43 6d 64 5b 30 5d 29 3b 20 69 2b 2b 29  ObjCmd[0]); i++)
9a40: 7b 0a 20 20 20 20 54 63 6c 5f 43 72 65 61 74 65  {.    Tcl_Create
9a50: 4f 62 6a 43 6f 6d 6d 61 6e 64 28 69 6e 74 65 72  ObjCommand(inter
9a60: 70 2c 20 61 4f 62 6a 43 6d 64 5b 69 5d 2e 7a 4e  p, aObjCmd[i].zN
9a70: 61 6d 65 2c 20 0a 20 20 20 20 20 20 20 20 61 4f  ame, .        aO
9a80: 62 6a 43 6d 64 5b 69 5d 2e 78 50 72 6f 63 2c 20  bjCmd[i].xProc, 
9a90: 61 4f 62 6a 43 6d 64 5b 69 5d 2e 63 6c 69 65 6e  aObjCmd[i].clien
9aa0: 74 44 61 74 61 2c 20 30 29 3b 0a 20 20 7d 0a 23  tData, 0);.  }.#
9ab0: 65 6e 64 69 66 0a 20 20 72 65 74 75 72 6e 20 54  endif.  return T
9ac0: 43 4c 5f 4f 4b 3b 0a 7d 0a                       CL_OK;.}.