/ Hex Artifact Content
Login

Artifact 7da151778887275c7f62b972363c78a5609f2bd8:


0000: 2f 2a 0a 2a 2a 20 32 30 30 36 20 4a 75 6e 65 20  /*.** 2006 June 
0010: 31 30 0a 2a 2a 0a 2a 2a 20 54 68 65 20 61 75 74  10.**.** The aut
0020: 68 6f 72 20 64 69 73 63 6c 61 69 6d 73 20 63 6f  hor disclaims co
0030: 70 79 72 69 67 68 74 20 74 6f 20 74 68 69 73 20  pyright to this 
0040: 73 6f 75 72 63 65 20 63 6f 64 65 2e 20 20 49 6e  source code.  In
0050: 20 70 6c 61 63 65 20 6f 66 0a 2a 2a 20 61 20 6c   place of.** a l
0060: 65 67 61 6c 20 6e 6f 74 69 63 65 2c 20 68 65 72  egal notice, her
0070: 65 20 69 73 20 61 20 62 6c 65 73 73 69 6e 67 3a  e is a blessing:
0080: 0a 2a 2a 0a 2a 2a 20 20 20 20 4d 61 79 20 79 6f  .**.**    May yo
0090: 75 20 64 6f 20 67 6f 6f 64 20 61 6e 64 20 6e 6f  u do good and no
00a0: 74 20 65 76 69 6c 2e 0a 2a 2a 20 20 20 20 4d 61  t evil..**    Ma
00b0: 79 20 79 6f 75 20 66 69 6e 64 20 66 6f 72 67 69  y you find forgi
00c0: 76 65 6e 65 73 73 20 66 6f 72 20 79 6f 75 72 73  veness for yours
00d0: 65 6c 66 20 61 6e 64 20 66 6f 72 67 69 76 65 20  elf and forgive 
00e0: 6f 74 68 65 72 73 2e 0a 2a 2a 20 20 20 20 4d 61  others..**    Ma
00f0: 79 20 79 6f 75 20 73 68 61 72 65 20 66 72 65 65  y you share free
0100: 6c 79 2c 20 6e 65 76 65 72 20 74 61 6b 69 6e 67  ly, never taking
0110: 20 6d 6f 72 65 20 74 68 61 6e 20 79 6f 75 20 67   more than you g
0120: 69 76 65 2e 0a 2a 2a 0a 2a 2a 2a 2a 2a 2a 2a 2a  ive..**.********
0130: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0140: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0150: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0160: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0170: 2a 0a 2a 2a 20 43 6f 64 65 20 66 6f 72 20 74 65  *.** Code for te
0180: 73 74 69 6e 67 20 74 68 65 20 76 69 72 74 75 61  sting the virtua
0190: 6c 20 74 61 62 6c 65 20 69 6e 74 65 72 66 61 63  l table interfac
01a0: 65 73 2e 20 20 54 68 69 73 20 63 6f 64 65 0a 2a  es.  This code.*
01b0: 2a 20 69 73 20 6e 6f 74 20 69 6e 63 6c 75 64 65  * is not include
01c0: 64 20 69 6e 20 74 68 65 20 53 51 4c 69 74 65 20  d in the SQLite 
01d0: 6c 69 62 72 61 72 79 2e 20 20 49 74 20 69 73 20  library.  It is 
01e0: 75 73 65 64 20 66 6f 72 20 61 75 74 6f 6d 61 74  used for automat
01f0: 65 64 0a 2a 2a 20 74 65 73 74 69 6e 67 20 6f 66  ed.** testing of
0200: 20 74 68 65 20 53 51 4c 69 74 65 20 6c 69 62 72   the SQLite libr
0210: 61 72 79 2e 0a 2a 2a 0a 2a 2a 20 24 49 64 3a 20  ary..**.** $Id: 
0220: 74 65 73 74 38 2e 63 2c 76 20 31 2e 37 33 20 32  test8.c,v 1.73 2
0230: 30 30 38 2f 30 38 2f 31 32 20 31 34 3a 34 38 3a  008/08/12 14:48:
0240: 34 31 20 64 61 6e 69 65 6c 6b 31 39 37 37 20 45  41 danielk1977 E
0250: 78 70 20 24 0a 2a 2f 0a 23 69 6e 63 6c 75 64 65  xp $.*/.#include
0260: 20 22 73 71 6c 69 74 65 49 6e 74 2e 68 22 0a 23   "sqliteInt.h".#
0270: 69 6e 63 6c 75 64 65 20 22 74 63 6c 2e 68 22 0a  include "tcl.h".
0280: 23 69 6e 63 6c 75 64 65 20 3c 73 74 64 6c 69 62  #include <stdlib
0290: 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 73 74  .h>.#include <st
02a0: 72 69 6e 67 2e 68 3e 0a 0a 23 69 66 6e 64 65 66  ring.h>..#ifndef
02b0: 20 53 51 4c 49 54 45 5f 4f 4d 49 54 5f 56 49 52   SQLITE_OMIT_VIR
02c0: 54 55 41 4c 54 41 42 4c 45 0a 0a 74 79 70 65 64  TUALTABLE..typed
02d0: 65 66 20 73 74 72 75 63 74 20 65 63 68 6f 5f 76  ef struct echo_v
02e0: 74 61 62 20 65 63 68 6f 5f 76 74 61 62 3b 0a 74  tab echo_vtab;.t
02f0: 79 70 65 64 65 66 20 73 74 72 75 63 74 20 65 63  ypedef struct ec
0300: 68 6f 5f 63 75 72 73 6f 72 20 65 63 68 6f 5f 63  ho_cursor echo_c
0310: 75 72 73 6f 72 3b 0a 0a 2f 2a 0a 2a 2a 20 54 68  ursor;../*.** Th
0320: 65 20 74 65 73 74 20 6d 6f 64 75 6c 65 20 64 65  e test module de
0330: 66 69 6e 65 64 20 69 6e 20 74 68 69 73 20 66 69  fined in this fi
0340: 6c 65 20 75 73 65 73 20 66 6f 75 72 20 67 6c 6f  le uses four glo
0350: 62 61 6c 20 54 63 6c 20 76 61 72 69 61 62 6c 65  bal Tcl variable
0360: 73 20 74 6f 0a 2a 2a 20 63 6f 6d 6d 69 63 61 74  s to.** commicat
0370: 65 20 77 69 74 68 20 74 65 73 74 2d 73 63 72 69  e with test-scri
0380: 70 74 73 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20 24  pts:.**.**     $
0390: 3a 3a 65 63 68 6f 5f 6d 6f 64 75 6c 65 0a 2a 2a  ::echo_module.**
03a0: 20 20 20 20 20 24 3a 3a 65 63 68 6f 5f 6d 6f 64       $::echo_mod
03b0: 75 6c 65 5f 73 79 6e 63 5f 66 61 69 6c 0a 2a 2a  ule_sync_fail.**
03c0: 20 20 20 20 20 24 3a 3a 65 63 68 6f 5f 6d 6f 64       $::echo_mod
03d0: 75 6c 65 5f 62 65 67 69 6e 5f 66 61 69 6c 0a 2a  ule_begin_fail.*
03e0: 2a 20 20 20 20 20 24 3a 3a 65 63 68 6f 5f 6d 6f  *     $::echo_mo
03f0: 64 75 6c 65 5f 63 6f 73 74 0a 2a 2a 0a 2a 2a 20  dule_cost.**.** 
0400: 54 68 65 20 76 61 72 69 61 62 6c 65 20 3a 3a 65  The variable ::e
0410: 63 68 6f 5f 6d 6f 64 75 6c 65 20 69 73 20 61 20  cho_module is a 
0420: 6c 69 73 74 2e 20 45 61 63 68 20 74 69 6d 65 20  list. Each time 
0430: 6f 6e 65 20 6f 66 20 74 68 65 20 66 6f 6c 6c 6f  one of the follo
0440: 77 69 6e 67 0a 2a 2a 20 6d 65 74 68 6f 64 73 20  wing.** methods 
0450: 69 73 20 63 61 6c 6c 65 64 2c 20 6f 6e 65 20 6f  is called, one o
0460: 72 20 6d 6f 72 65 20 65 6c 65 6d 65 6e 74 73 20  r more elements 
0470: 61 72 65 20 61 70 70 65 6e 64 65 64 20 74 6f 20  are appended to 
0480: 74 68 65 20 6c 69 73 74 2e 0a 2a 2a 20 54 68 69  the list..** Thi
0490: 73 20 69 73 20 75 73 65 64 20 66 6f 72 20 61 75  s is used for au
04a0: 74 6f 6d 61 74 65 64 20 74 65 73 74 69 6e 67 20  tomated testing 
04b0: 6f 66 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65  of virtual table
04c0: 20 6d 6f 64 75 6c 65 73 2e 0a 2a 2a 0a 2a 2a 20   modules..**.** 
04d0: 54 68 65 20 3a 3a 65 63 68 6f 5f 6d 6f 64 75 6c  The ::echo_modul
04e0: 65 5f 73 79 6e 63 5f 66 61 69 6c 20 76 61 72 69  e_sync_fail vari
04f0: 61 62 6c 65 20 69 73 20 73 65 74 20 62 79 20 74  able is set by t
0500: 65 73 74 20 73 63 72 69 70 74 73 20 61 6e 64 20  est scripts and 
0510: 72 65 61 64 0a 2a 2a 20 62 79 20 63 6f 64 65 20  read.** by code 
0520: 69 6e 20 74 68 69 73 20 66 69 6c 65 2e 20 49 66  in this file. If
0530: 20 69 74 20 69 73 20 73 65 74 20 74 6f 20 74 68   it is set to th
0540: 65 20 6e 61 6d 65 20 6f 66 20 61 20 72 65 61 6c  e name of a real
0550: 20 74 61 62 6c 65 20 69 6e 20 74 68 65 0a 2a 2a   table in the.**
0560: 20 74 68 65 20 64 61 74 61 62 61 73 65 2c 20 74   the database, t
0570: 68 65 6e 20 61 6c 6c 20 78 53 79 6e 63 20 6f 70  hen all xSync op
0580: 65 72 61 74 69 6f 6e 73 20 6f 6e 20 65 63 68 6f  erations on echo
0590: 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65 73 20   virtual tables 
05a0: 74 68 61 74 0a 2a 2a 20 75 73 65 20 74 68 65 20  that.** use the 
05b0: 6e 61 6d 65 64 20 74 61 62 6c 65 20 61 73 20 61  named table as a
05c0: 20 62 61 63 6b 69 6e 67 20 73 74 6f 72 65 20 77   backing store w
05d0: 69 6c 6c 20 66 61 69 6c 2e 0a 2a 2f 0a 0a 2f 2a  ill fail..*/../*
05e0: 0a 2a 2a 20 45 72 72 6f 72 73 20 63 61 6e 20 62  .** Errors can b
05f0: 65 20 70 72 6f 76 6f 6b 65 64 20 77 69 74 68 69  e provoked withi
0600: 6e 20 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20  n the following 
0610: 65 63 68 6f 20 76 69 72 74 75 61 6c 20 74 61 62  echo virtual tab
0620: 6c 65 20 6d 65 74 68 6f 64 73 3a 0a 2a 2a 0a 2a  le methods:.**.*
0630: 2a 20 20 20 78 42 65 73 74 49 6e 64 65 78 20 20  *   xBestIndex  
0640: 20 78 4f 70 65 6e 20 20 20 20 20 78 46 69 6c 74   xOpen     xFilt
0650: 65 72 20 20 20 78 4e 65 78 74 20 20 20 0a 2a 2a  er   xNext   .**
0660: 20 20 20 78 43 6f 6c 75 6d 6e 20 20 20 20 20 20     xColumn      
0670: 78 52 6f 77 69 64 20 20 20 20 78 55 70 64 61 74  xRowid    xUpdat
0680: 65 20 20 20 78 53 79 6e 63 20 20 20 0a 2a 2a 20  e   xSync   .** 
0690: 20 20 78 42 65 67 69 6e 20 20 20 20 20 20 20 78    xBegin       x
06a0: 52 65 6e 61 6d 65 0a 2a 2a 0a 2a 2a 20 54 68 69  Rename.**.** Thi
06b0: 73 20 69 73 20 64 6f 6e 65 20 62 79 20 73 65 74  s is done by set
06c0: 74 69 6e 67 20 74 68 65 20 67 6c 6f 62 61 6c 20  ting the global 
06d0: 74 63 6c 20 76 61 72 69 61 62 6c 65 3a 0a 2a 2a  tcl variable:.**
06e0: 0a 2a 2a 20 20 20 65 63 68 6f 5f 6d 6f 64 75 6c  .**   echo_modul
06f0: 65 5f 66 61 69 6c 28 24 6d 65 74 68 6f 64 2c 24  e_fail($method,$
0700: 74 62 6c 29 0a 2a 2a 0a 2a 2a 20 77 68 65 72 65  tbl).**.** where
0710: 20 24 6d 65 74 68 6f 64 20 69 73 20 73 65 74 20   $method is set 
0720: 74 6f 20 74 68 65 20 6e 61 6d 65 20 6f 66 20 74  to the name of t
0730: 68 65 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65  he virtual table
0740: 20 6d 65 74 68 6f 64 20 74 6f 20 66 61 69 6c 0a   method to fail.
0750: 2a 2a 20 28 69 2e 65 2e 20 22 78 42 65 73 74 49  ** (i.e. "xBestI
0760: 6e 64 65 78 22 29 20 61 6e 64 20 24 74 62 6c 20  ndex") and $tbl 
0770: 69 73 20 74 68 65 20 6e 61 6d 65 20 6f 66 20 74  is the name of t
0780: 68 65 20 74 61 62 6c 65 20 62 65 69 6e 67 20 65  he table being e
0790: 63 68 6f 65 64 20 28 6e 6f 74 0a 2a 2a 20 74 68  choed (not.** th
07a0: 65 20 6e 61 6d 65 20 6f 66 20 74 68 65 20 76 69  e name of the vi
07b0: 72 74 75 61 6c 20 74 61 62 6c 65 2c 20 74 68 65  rtual table, the
07c0: 20 6e 61 6d 65 20 6f 66 20 74 68 65 20 75 6e 64   name of the und
07d0: 65 72 6c 79 69 6e 67 20 72 65 61 6c 20 74 61 62  erlying real tab
07e0: 6c 65 29 2e 0a 2a 2f 0a 0a 2f 2a 20 0a 2a 2a 20  le)..*/../* .** 
07f0: 41 6e 20 65 63 68 6f 20 76 69 72 74 75 61 6c 2d  An echo virtual-
0800: 74 61 62 6c 65 20 6f 62 6a 65 63 74 2e 0a 2a 2a  table object..**
0810: 0a 2a 2a 20 65 63 68 6f 2e 76 74 61 62 2e 61 49  .** echo.vtab.aI
0820: 6e 64 65 78 20 69 73 20 61 6e 20 61 72 72 61 79  ndex is an array
0830: 20 6f 66 20 62 6f 6f 6c 65 61 6e 73 2e 20 54 68   of booleans. Th
0840: 65 20 6e 74 68 20 65 6e 74 72 79 20 69 73 20 74  e nth entry is t
0850: 72 75 65 20 69 66 20 0a 2a 2a 20 74 68 65 20 6e  rue if .** the n
0860: 74 68 20 63 6f 6c 75 6d 6e 20 6f 66 20 74 68 65  th column of the
0870: 20 72 65 61 6c 20 74 61 62 6c 65 20 69 73 20 74   real table is t
0880: 68 65 20 6c 65 66 74 2d 6d 6f 73 74 20 63 6f 6c  he left-most col
0890: 75 6d 6e 20 6f 66 20 61 6e 20 69 6e 64 65 78 0a  umn of an index.
08a0: 2a 2a 20 28 69 6d 70 6c 69 63 69 74 20 6f 72 20  ** (implicit or 
08b0: 6f 74 68 65 72 77 69 73 65 29 2e 20 49 6e 20 6f  otherwise). In o
08c0: 74 68 65 72 20 77 6f 72 64 73 2c 20 69 66 20 53  ther words, if S
08d0: 51 4c 69 74 65 20 63 61 6e 20 6f 70 74 69 6d 69  QLite can optimi
08e0: 7a 65 0a 2a 2a 20 61 20 71 75 65 72 79 20 6c 69  ze.** a query li
08f0: 6b 65 20 22 53 45 4c 45 43 54 20 2a 20 46 52 4f  ke "SELECT * FRO
0900: 4d 20 72 65 61 6c 5f 74 61 62 6c 65 20 57 48 45  M real_table WHE
0910: 52 45 20 63 6f 6c 20 3d 20 3f 22 2e 0a 2a 2a 0a  RE col = ?"..**.
0920: 2a 2a 20 4d 65 6d 62 65 72 20 76 61 72 69 61 62  ** Member variab
0930: 6c 65 20 61 43 6f 6c 5b 5d 20 63 6f 6e 74 61 69  le aCol[] contai
0940: 6e 73 20 63 6f 70 69 65 73 20 6f 66 20 74 68 65  ns copies of the
0950: 20 63 6f 6c 75 6d 6e 20 6e 61 6d 65 73 20 6f 66   column names of
0960: 20 74 68 65 20 72 65 61 6c 0a 2a 2a 20 74 61 62   the real.** tab
0970: 6c 65 2e 0a 2a 2f 0a 73 74 72 75 63 74 20 65 63  le..*/.struct ec
0980: 68 6f 5f 76 74 61 62 20 7b 0a 20 20 73 71 6c 69  ho_vtab {.  sqli
0990: 74 65 33 5f 76 74 61 62 20 62 61 73 65 3b 0a 20  te3_vtab base;. 
09a0: 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74   Tcl_Interp *int
09b0: 65 72 70 3b 20 20 20 20 20 2f 2a 20 54 63 6c 20  erp;     /* Tcl 
09c0: 69 6e 74 65 72 70 72 65 74 65 72 20 63 6f 6e 74  interpreter cont
09d0: 61 69 6e 69 6e 67 20 64 65 62 75 67 20 76 61 72  aining debug var
09e0: 69 61 62 6c 65 73 20 2a 2f 0a 20 20 73 71 6c 69  iables */.  sqli
09f0: 74 65 33 20 2a 64 62 3b 20 20 20 20 20 20 20 20  te3 *db;        
0a00: 20 20 20 20 2f 2a 20 44 61 74 61 62 61 73 65 20      /* Database 
0a10: 63 6f 6e 6e 65 63 74 69 6f 6e 20 2a 2f 0a 0a 20  connection */.. 
0a20: 20 69 6e 74 20 69 73 50 61 74 74 65 72 6e 3b 0a   int isPattern;.
0a30: 20 20 69 6e 74 20 69 6e 54 72 61 6e 73 61 63 74    int inTransact
0a40: 69 6f 6e 3b 20 20 20 20 20 20 2f 2a 20 54 72 75  ion;      /* Tru
0a50: 65 20 69 66 20 77 69 74 68 69 6e 20 61 20 74 72  e if within a tr
0a60: 61 6e 73 61 63 74 69 6f 6e 20 2a 2f 0a 20 20 63  ansaction */.  c
0a70: 68 61 72 20 2a 7a 54 68 69 73 3b 20 20 20 20 20  har *zThis;     
0a80: 20 20 20 20 20 20 20 2f 2a 20 4e 61 6d 65 20 6f         /* Name o
0a90: 66 20 74 68 65 20 65 63 68 6f 20 74 61 62 6c 65  f the echo table
0aa0: 20 2a 2f 0a 20 20 63 68 61 72 20 2a 7a 54 61 62   */.  char *zTab
0ab0: 6c 65 4e 61 6d 65 3b 20 20 20 20 20 20 20 2f 2a  leName;       /*
0ac0: 20 4e 61 6d 65 20 6f 66 20 74 68 65 20 72 65 61   Name of the rea
0ad0: 6c 20 74 61 62 6c 65 20 2a 2f 0a 20 20 63 68 61  l table */.  cha
0ae0: 72 20 2a 7a 4c 6f 67 4e 61 6d 65 3b 20 20 20 20  r *zLogName;    
0af0: 20 20 20 20 20 2f 2a 20 4e 61 6d 65 20 6f 66 20       /* Name of 
0b00: 74 68 65 20 6c 6f 67 20 74 61 62 6c 65 20 2a 2f  the log table */
0b10: 0a 20 20 69 6e 74 20 6e 43 6f 6c 3b 20 20 20 20  .  int nCol;    
0b20: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75             /* Nu
0b30: 6d 62 65 72 20 6f 66 20 63 6f 6c 75 6d 6e 73 20  mber of columns 
0b40: 69 6e 20 74 68 65 20 72 65 61 6c 20 74 61 62 6c  in the real tabl
0b50: 65 20 2a 2f 0a 20 20 69 6e 74 20 2a 61 49 6e 64  e */.  int *aInd
0b60: 65 78 3b 20 20 20 20 20 20 20 20 20 20 20 20 2f  ex;            /
0b70: 2a 20 41 72 72 61 79 20 6f 66 20 73 69 7a 65 20  * Array of size 
0b80: 6e 43 6f 6c 2e 20 54 72 75 65 20 69 66 20 63 6f  nCol. True if co
0b90: 6c 75 6d 6e 20 68 61 73 20 61 6e 20 69 6e 64 65  lumn has an inde
0ba0: 78 20 2a 2f 0a 20 20 63 68 61 72 20 2a 2a 61 43  x */.  char **aC
0bb0: 6f 6c 3b 20 20 20 20 20 20 20 20 20 20 20 20 2f  ol;            /
0bc0: 2a 20 41 72 72 61 79 20 6f 66 20 73 69 7a 65 20  * Array of size 
0bd0: 6e 43 6f 6c 2e 20 43 6f 6c 75 6d 6e 20 6e 61 6d  nCol. Column nam
0be0: 65 73 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 20 41 6e 20  es */.};../* An 
0bf0: 65 63 68 6f 20 63 75 72 73 6f 72 20 6f 62 6a 65  echo cursor obje
0c00: 63 74 20 2a 2f 0a 73 74 72 75 63 74 20 65 63 68  ct */.struct ech
0c10: 6f 5f 63 75 72 73 6f 72 20 7b 0a 20 20 73 71 6c  o_cursor {.  sql
0c20: 69 74 65 33 5f 76 74 61 62 5f 63 75 72 73 6f 72  ite3_vtab_cursor
0c30: 20 62 61 73 65 3b 0a 20 20 73 71 6c 69 74 65 33   base;.  sqlite3
0c40: 5f 73 74 6d 74 20 2a 70 53 74 6d 74 3b 0a 7d 3b  _stmt *pStmt;.};
0c50: 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 73 69 6d  ..static int sim
0c60: 75 6c 61 74 65 56 74 61 62 45 72 72 6f 72 28 65  ulateVtabError(e
0c70: 63 68 6f 5f 76 74 61 62 20 2a 70 2c 20 63 6f 6e  cho_vtab *p, con
0c80: 73 74 20 63 68 61 72 20 2a 7a 4d 65 74 68 6f 64  st char *zMethod
0c90: 29 7b 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20  ){.  const char 
0ca0: 2a 7a 45 72 72 3b 0a 20 20 63 68 61 72 20 7a 56  *zErr;.  char zV
0cb0: 61 72 6e 61 6d 65 5b 31 32 38 5d 3b 0a 20 20 7a  arname[128];.  z
0cc0: 56 61 72 6e 61 6d 65 5b 31 32 37 5d 20 3d 20 27  Varname[127] = '
0cd0: 5c 30 27 3b 0a 20 20 73 71 6c 69 74 65 33 5f 73  \0';.  sqlite3_s
0ce0: 6e 70 72 69 6e 74 66 28 31 32 37 2c 20 7a 56 61  nprintf(127, zVa
0cf0: 72 6e 61 6d 65 2c 20 0a 20 20 20 20 20 20 20 20  rname, .        
0d00: 20 20 20 20 20 20 20 20 20 20 20 22 65 63 68 6f             "echo
0d10: 5f 6d 6f 64 75 6c 65 5f 66 61 69 6c 28 25 73 2c  _module_fail(%s,
0d20: 25 73 29 22 2c 20 7a 4d 65 74 68 6f 64 2c 20 70  %s)", zMethod, p
0d30: 2d 3e 7a 54 61 62 6c 65 4e 61 6d 65 29 3b 0a 20  ->zTableName);. 
0d40: 20 7a 45 72 72 20 3d 20 54 63 6c 5f 47 65 74 56   zErr = Tcl_GetV
0d50: 61 72 28 70 2d 3e 69 6e 74 65 72 70 2c 20 7a 56  ar(p->interp, zV
0d60: 61 72 6e 61 6d 65 2c 20 54 43 4c 5f 47 4c 4f 42  arname, TCL_GLOB
0d70: 41 4c 5f 4f 4e 4c 59 29 3b 0a 20 20 69 66 28 20  AL_ONLY);.  if( 
0d80: 7a 45 72 72 20 29 7b 0a 20 20 20 20 70 2d 3e 62  zErr ){.    p->b
0d90: 61 73 65 2e 7a 45 72 72 4d 73 67 20 3d 20 73 71  ase.zErrMsg = sq
0da0: 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 22 65  lite3_mprintf("e
0db0: 63 68 6f 2d 76 74 61 62 2d 65 72 72 6f 72 3a 20  cho-vtab-error: 
0dc0: 25 73 22 2c 20 7a 45 72 72 29 3b 0a 20 20 7d 0a  %s", zErr);.  }.
0dd0: 20 20 72 65 74 75 72 6e 20 28 7a 45 72 72 21 3d    return (zErr!=
0de0: 30 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 6f 6e  0);.}../*.** Con
0df0: 76 65 72 74 20 61 6e 20 53 51 4c 2d 73 74 79 6c  vert an SQL-styl
0e00: 65 20 71 75 6f 74 65 64 20 73 74 72 69 6e 67 20  e quoted string 
0e10: 69 6e 74 6f 20 61 20 6e 6f 72 6d 61 6c 20 73 74  into a normal st
0e20: 72 69 6e 67 20 62 79 20 72 65 6d 6f 76 69 6e 67  ring by removing
0e30: 0a 2a 2a 20 74 68 65 20 71 75 6f 74 65 20 63 68  .** the quote ch
0e40: 61 72 61 63 74 65 72 73 2e 20 20 54 68 65 20 63  aracters.  The c
0e50: 6f 6e 76 65 72 73 69 6f 6e 20 69 73 20 64 6f 6e  onversion is don
0e60: 65 20 69 6e 2d 70 6c 61 63 65 2e 20 20 49 66 20  e in-place.  If 
0e70: 74 68 65 0a 2a 2a 20 69 6e 70 75 74 20 64 6f 65  the.** input doe
0e80: 73 20 6e 6f 74 20 62 65 67 69 6e 20 77 69 74 68  s not begin with
0e90: 20 61 20 71 75 6f 74 65 20 63 68 61 72 61 63 74   a quote charact
0ea0: 65 72 2c 20 74 68 65 6e 20 74 68 69 73 20 72 6f  er, then this ro
0eb0: 75 74 69 6e 65 0a 2a 2a 20 69 73 20 61 20 6e 6f  utine.** is a no
0ec0: 2d 6f 70 2e 0a 2a 2a 0a 2a 2a 20 45 78 61 6d 70  -op..**.** Examp
0ed0: 6c 65 73 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20 22  les:.**.**     "
0ee0: 61 62 63 22 20 20 20 62 65 63 6f 6d 65 73 20 20  abc"   becomes  
0ef0: 20 61 62 63 0a 2a 2a 20 20 20 20 20 27 78 79 7a   abc.**     'xyz
0f00: 27 20 20 20 62 65 63 6f 6d 65 73 20 20 20 78 79  '   becomes   xy
0f10: 7a 0a 2a 2a 20 20 20 20 20 5b 70 71 72 5d 20 20  z.**     [pqr]  
0f20: 20 62 65 63 6f 6d 65 73 20 20 20 70 71 72 0a 2a   becomes   pqr.*
0f30: 2a 20 20 20 20 20 60 6d 6e 6f 60 20 20 20 62 65  *     `mno`   be
0f40: 63 6f 6d 65 73 20 20 20 6d 6e 6f 0a 2a 2f 0a 73  comes   mno.*/.s
0f50: 74 61 74 69 63 20 76 6f 69 64 20 64 65 71 75 6f  tatic void dequo
0f60: 74 65 53 74 72 69 6e 67 28 63 68 61 72 20 2a 7a  teString(char *z
0f70: 29 7b 0a 20 20 69 6e 74 20 71 75 6f 74 65 3b 0a  ){.  int quote;.
0f80: 20 20 69 6e 74 20 69 2c 20 6a 3b 0a 20 20 69 66    int i, j;.  if
0f90: 28 20 7a 3d 3d 30 20 29 20 72 65 74 75 72 6e 3b  ( z==0 ) return;
0fa0: 0a 20 20 71 75 6f 74 65 20 3d 20 7a 5b 30 5d 3b  .  quote = z[0];
0fb0: 0a 20 20 73 77 69 74 63 68 28 20 71 75 6f 74 65  .  switch( quote
0fc0: 20 29 7b 0a 20 20 20 20 63 61 73 65 20 27 5c 27   ){.    case '\'
0fd0: 27 3a 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 63  ':  break;.    c
0fe0: 61 73 65 20 27 22 27 3a 20 20 20 62 72 65 61 6b  ase '"':   break
0ff0: 3b 0a 20 20 20 20 63 61 73 65 20 27 60 27 3a 20  ;.    case '`': 
1000: 20 20 62 72 65 61 6b 3b 20 20 20 20 20 20 20 20    break;        
1010: 20 20 20 20 20 20 20 20 2f 2a 20 46 6f 72 20 4d          /* For M
1020: 79 53 51 4c 20 63 6f 6d 70 61 74 69 62 69 6c 69  ySQL compatibili
1030: 74 79 20 2a 2f 0a 20 20 20 20 63 61 73 65 20 27  ty */.    case '
1040: 5b 27 3a 20 20 20 71 75 6f 74 65 20 3d 20 27 5d  [':   quote = ']
1050: 27 3b 20 20 62 72 65 61 6b 3b 20 20 2f 2a 20 46  ';  break;  /* F
1060: 6f 72 20 4d 53 20 53 71 6c 53 65 72 76 65 72 20  or MS SqlServer 
1070: 63 6f 6d 70 61 74 69 62 69 6c 69 74 79 20 2a 2f  compatibility */
1080: 0a 20 20 20 20 64 65 66 61 75 6c 74 3a 20 20 20  .    default:   
1090: 20 72 65 74 75 72 6e 3b 0a 20 20 7d 0a 20 20 66   return;.  }.  f
10a0: 6f 72 28 69 3d 31 2c 20 6a 3d 30 3b 20 7a 5b 69  or(i=1, j=0; z[i
10b0: 5d 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 69 66 28  ]; i++){.    if(
10c0: 20 7a 5b 69 5d 3d 3d 71 75 6f 74 65 20 29 7b 0a   z[i]==quote ){.
10d0: 20 20 20 20 20 20 69 66 28 20 7a 5b 69 2b 31 5d        if( z[i+1]
10e0: 3d 3d 71 75 6f 74 65 20 29 7b 0a 20 20 20 20 20  ==quote ){.     
10f0: 20 20 20 7a 5b 6a 2b 2b 5d 20 3d 20 71 75 6f 74     z[j++] = quot
1100: 65 3b 0a 20 20 20 20 20 20 20 20 69 2b 2b 3b 0a  e;.        i++;.
1110: 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20        }else{.   
1120: 20 20 20 20 20 7a 5b 6a 2b 2b 5d 20 3d 20 30 3b       z[j++] = 0;
1130: 0a 20 20 20 20 20 20 20 20 62 72 65 61 6b 3b 0a  .        break;.
1140: 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 65 6c 73        }.    }els
1150: 65 7b 0a 20 20 20 20 20 20 7a 5b 6a 2b 2b 5d 20  e{.      z[j++] 
1160: 3d 20 7a 5b 69 5d 3b 0a 20 20 20 20 7d 0a 20 20  = z[i];.    }.  
1170: 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 72 69  }.}../*.** Retri
1180: 65 76 65 20 74 68 65 20 63 6f 6c 75 6d 6e 20 6e  eve the column n
1190: 61 6d 65 73 20 66 6f 72 20 74 68 65 20 74 61 62  ames for the tab
11a0: 6c 65 20 6e 61 6d 65 64 20 7a 54 61 62 20 76 69  le named zTab vi
11b0: 61 20 64 61 74 61 62 61 73 65 0a 2a 2a 20 63 6f  a database.** co
11c0: 6e 6e 65 63 74 69 6f 6e 20 64 62 2e 20 53 51 4c  nnection db. SQL
11d0: 49 54 45 5f 4f 4b 20 69 73 20 72 65 74 75 72 6e  ITE_OK is return
11e0: 65 64 20 6f 6e 20 73 75 63 63 65 73 73 2c 20 6f  ed on success, o
11f0: 72 20 61 6e 20 73 71 6c 69 74 65 20 65 72 72 6f  r an sqlite erro
1200: 72 0a 2a 2a 20 63 6f 64 65 20 6f 74 68 65 72 77  r.** code otherw
1210: 69 73 65 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 73 75  ise..**.** If su
1220: 63 63 65 73 73 66 75 6c 2c 20 74 68 65 20 6e 75  ccessful, the nu
1230: 6d 62 65 72 20 6f 66 20 63 6f 6c 75 6d 6e 73 20  mber of columns 
1240: 69 73 20 77 72 69 74 74 65 6e 20 74 6f 20 2a 70  is written to *p
1250: 6e 43 6f 6c 2e 20 2a 70 61 43 6f 6c 20 69 73 0a  nCol. *paCol is.
1260: 2a 2a 20 73 65 74 20 74 6f 20 70 6f 69 6e 74 20  ** set to point 
1270: 61 74 20 73 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f  at sqlite3_mallo
1280: 63 28 29 27 64 20 73 70 61 63 65 20 63 6f 6e 74  c()'d space cont
1290: 61 69 6e 69 6e 67 20 74 68 65 20 61 72 72 61 79  aining the array
12a0: 20 6f 66 0a 2a 2a 20 6e 43 6f 6c 20 63 6f 6c 75   of.** nCol colu
12b0: 6d 6e 20 6e 61 6d 65 73 2e 20 54 68 65 20 63 61  mn names. The ca
12c0: 6c 6c 65 72 20 69 73 20 72 65 73 70 6f 6e 73 69  ller is responsi
12d0: 62 6c 65 20 66 6f 72 20 63 61 6c 6c 69 6e 67 20  ble for calling 
12e0: 73 71 6c 69 74 65 33 5f 66 72 65 65 0a 2a 2a 20  sqlite3_free.** 
12f0: 6f 6e 20 2a 70 61 43 6f 6c 2e 0a 2a 2f 0a 73 74  on *paCol..*/.st
1300: 61 74 69 63 20 69 6e 74 20 67 65 74 43 6f 6c 75  atic int getColu
1310: 6d 6e 4e 61 6d 65 73 28 0a 20 20 73 71 6c 69 74  mnNames(.  sqlit
1320: 65 33 20 2a 64 62 2c 20 0a 20 20 63 6f 6e 73 74  e3 *db, .  const
1330: 20 63 68 61 72 20 2a 7a 54 61 62 2c 0a 20 20 63   char *zTab,.  c
1340: 68 61 72 20 2a 2a 2a 70 61 43 6f 6c 2c 20 0a 20  har ***paCol, . 
1350: 20 69 6e 74 20 2a 70 6e 43 6f 6c 0a 29 7b 0a 20   int *pnCol.){. 
1360: 20 63 68 61 72 20 2a 2a 61 43 6f 6c 20 3d 20 30   char **aCol = 0
1370: 3b 0a 20 20 63 68 61 72 20 2a 7a 53 71 6c 3b 0a  ;.  char *zSql;.
1380: 20 20 73 71 6c 69 74 65 33 5f 73 74 6d 74 20 2a    sqlite3_stmt *
1390: 70 53 74 6d 74 20 3d 20 30 3b 0a 20 20 69 6e 74  pStmt = 0;.  int
13a0: 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b   rc = SQLITE_OK;
13b0: 0a 20 20 69 6e 74 20 6e 43 6f 6c 20 3d 20 30 3b  .  int nCol = 0;
13c0: 0a 0a 20 20 2f 2a 20 50 72 65 70 61 72 65 20 74  ..  /* Prepare t
13d0: 68 65 20 73 74 61 74 65 6d 65 6e 74 20 22 53 45  he statement "SE
13e0: 4c 45 43 54 20 2a 20 46 52 4f 4d 20 3c 74 62 6c  LECT * FROM <tbl
13f0: 3e 22 2e 20 54 68 65 20 63 6f 6c 75 6d 6e 20 6e  >". The column n
1400: 61 6d 65 73 0a 20 20 2a 2a 20 6f 66 20 74 68 65  ames.  ** of the
1410: 20 72 65 73 75 6c 74 20 73 65 74 20 6f 66 20 74   result set of t
1420: 68 65 20 63 6f 6d 70 69 6c 65 64 20 53 45 4c 45  he compiled SELE
1430: 43 54 20 77 69 6c 6c 20 62 65 20 74 68 65 20 73  CT will be the s
1440: 61 6d 65 20 61 73 0a 20 20 2a 2a 20 74 68 65 20  ame as.  ** the 
1450: 63 6f 6c 75 6d 6e 20 6e 61 6d 65 73 20 6f 66 20  column names of 
1460: 74 61 62 6c 65 20 3c 74 62 6c 3e 2e 0a 20 20 2a  table <tbl>..  *
1470: 2f 0a 20 20 7a 53 71 6c 20 3d 20 73 71 6c 69 74  /.  zSql = sqlit
1480: 65 33 5f 6d 70 72 69 6e 74 66 28 22 53 45 4c 45  e3_mprintf("SELE
1490: 43 54 20 2a 20 46 52 4f 4d 20 25 51 22 2c 20 7a  CT * FROM %Q", z
14a0: 54 61 62 29 3b 0a 20 20 69 66 28 20 21 7a 53 71  Tab);.  if( !zSq
14b0: 6c 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 53 51  l ){.    rc = SQ
14c0: 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20  LITE_NOMEM;.    
14d0: 67 6f 74 6f 20 6f 75 74 3b 0a 20 20 7d 0a 20 20  goto out;.  }.  
14e0: 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 70 72 65  rc = sqlite3_pre
14f0: 70 61 72 65 28 64 62 2c 20 7a 53 71 6c 2c 20 2d  pare(db, zSql, -
1500: 31 2c 20 26 70 53 74 6d 74 2c 20 30 29 3b 0a 20  1, &pStmt, 0);. 
1510: 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 7a 53   sqlite3_free(zS
1520: 71 6c 29 3b 0a 0a 20 20 69 66 28 20 72 63 3d 3d  ql);..  if( rc==
1530: 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20  SQLITE_OK ){.   
1540: 20 69 6e 74 20 69 69 3b 0a 20 20 20 20 69 6e 74   int ii;.    int
1550: 20 6e 42 79 74 65 73 3b 0a 20 20 20 20 63 68 61   nBytes;.    cha
1560: 72 20 2a 7a 53 70 61 63 65 3b 0a 20 20 20 20 6e  r *zSpace;.    n
1570: 43 6f 6c 20 3d 20 73 71 6c 69 74 65 33 5f 63 6f  Col = sqlite3_co
1580: 6c 75 6d 6e 5f 63 6f 75 6e 74 28 70 53 74 6d 74  lumn_count(pStmt
1590: 29 3b 0a 0a 20 20 20 20 2f 2a 20 46 69 67 75 72  );..    /* Figur
15a0: 65 20 6f 75 74 20 68 6f 77 20 6d 75 63 68 20 73  e out how much s
15b0: 70 61 63 65 20 74 6f 20 61 6c 6c 6f 63 61 74 65  pace to allocate
15c0: 20 66 6f 72 20 74 68 65 20 61 72 72 61 79 20 6f   for the array o
15d0: 66 20 63 6f 6c 75 6d 6e 20 6e 61 6d 65 73 20 0a  f column names .
15e0: 20 20 20 20 2a 2a 20 28 69 6e 63 6c 75 64 69 6e      ** (includin
15f0: 67 20 73 70 61 63 65 20 66 6f 72 20 74 68 65 20  g space for the 
1600: 73 74 72 69 6e 67 73 20 74 68 65 6d 73 65 6c 76  strings themselv
1610: 65 73 29 2e 20 54 68 65 6e 20 61 6c 6c 6f 63 61  es). Then alloca
1620: 74 65 20 69 74 2e 0a 20 20 20 20 2a 2f 0a 20 20  te it..    */.  
1630: 20 20 6e 42 79 74 65 73 20 3d 20 73 69 7a 65 6f    nBytes = sizeo
1640: 66 28 63 68 61 72 20 2a 29 20 2a 20 6e 43 6f 6c  f(char *) * nCol
1650: 3b 0a 20 20 20 20 66 6f 72 28 69 69 3d 30 3b 20  ;.    for(ii=0; 
1660: 69 69 3c 6e 43 6f 6c 3b 20 69 69 2b 2b 29 7b 0a  ii<nCol; ii++){.
1670: 20 20 20 20 20 20 63 6f 6e 73 74 20 63 68 61 72        const char
1680: 20 2a 7a 4e 61 6d 65 20 3d 20 73 71 6c 69 74 65   *zName = sqlite
1690: 33 5f 63 6f 6c 75 6d 6e 5f 6e 61 6d 65 28 70 53  3_column_name(pS
16a0: 74 6d 74 2c 20 69 69 29 3b 0a 20 20 20 20 20 20  tmt, ii);.      
16b0: 69 66 28 20 21 7a 4e 61 6d 65 20 29 7b 0a 20 20  if( !zName ){.  
16c0: 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54        rc = SQLIT
16d0: 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 20 20 20  E_NOMEM;.       
16e0: 20 67 6f 74 6f 20 6f 75 74 3b 0a 20 20 20 20 20   goto out;.     
16f0: 20 7d 0a 20 20 20 20 20 20 6e 42 79 74 65 73 20   }.      nBytes 
1700: 2b 3d 20 73 74 72 6c 65 6e 28 7a 4e 61 6d 65 29  += strlen(zName)
1710: 2b 31 3b 0a 20 20 20 20 7d 0a 20 20 20 20 61 43  +1;.    }.    aC
1720: 6f 6c 20 3d 20 28 63 68 61 72 20 2a 2a 29 73 71  ol = (char **)sq
1730: 6c 69 74 65 33 4d 61 6c 6c 6f 63 5a 65 72 6f 28  lite3MallocZero(
1740: 6e 42 79 74 65 73 29 3b 0a 20 20 20 20 69 66 28  nBytes);.    if(
1750: 20 21 61 43 6f 6c 20 29 7b 0a 20 20 20 20 20 20   !aCol ){.      
1760: 72 63 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45  rc = SQLITE_NOME
1770: 4d 3b 0a 20 20 20 20 20 20 67 6f 74 6f 20 6f 75  M;.      goto ou
1780: 74 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 2f 2a  t;.    }..    /*
1790: 20 43 6f 70 79 20 74 68 65 20 63 6f 6c 75 6d 6e   Copy the column
17a0: 20 6e 61 6d 65 73 20 69 6e 74 6f 20 74 68 65 20   names into the 
17b0: 61 6c 6c 6f 63 61 74 65 64 20 73 70 61 63 65 20  allocated space 
17c0: 61 6e 64 20 73 65 74 20 75 70 20 74 68 65 0a 20  and set up the. 
17d0: 20 20 20 2a 2a 20 70 6f 69 6e 74 65 72 73 20 69     ** pointers i
17e0: 6e 20 74 68 65 20 61 43 6f 6c 5b 5d 20 61 72 72  n the aCol[] arr
17f0: 61 79 2e 0a 20 20 20 20 2a 2f 0a 20 20 20 20 7a  ay..    */.    z
1800: 53 70 61 63 65 20 3d 20 28 63 68 61 72 20 2a 29  Space = (char *)
1810: 28 26 61 43 6f 6c 5b 6e 43 6f 6c 5d 29 3b 0a 20  (&aCol[nCol]);. 
1820: 20 20 20 66 6f 72 28 69 69 3d 30 3b 20 69 69 3c     for(ii=0; ii<
1830: 6e 43 6f 6c 3b 20 69 69 2b 2b 29 7b 0a 20 20 20  nCol; ii++){.   
1840: 20 20 20 61 43 6f 6c 5b 69 69 5d 20 3d 20 7a 53     aCol[ii] = zS
1850: 70 61 63 65 3b 0a 20 20 20 20 20 20 7a 53 70 61  pace;.      zSpa
1860: 63 65 20 2b 3d 20 73 70 72 69 6e 74 66 28 7a 53  ce += sprintf(zS
1870: 70 61 63 65 2c 20 22 25 73 22 2c 20 73 71 6c 69  pace, "%s", sqli
1880: 74 65 33 5f 63 6f 6c 75 6d 6e 5f 6e 61 6d 65 28  te3_column_name(
1890: 70 53 74 6d 74 2c 20 69 69 29 29 3b 0a 20 20 20  pStmt, ii));.   
18a0: 20 20 20 7a 53 70 61 63 65 2b 2b 3b 0a 20 20 20     zSpace++;.   
18b0: 20 7d 0a 20 20 20 20 61 73 73 65 72 74 28 20 28   }.    assert( (
18c0: 7a 53 70 61 63 65 2d 6e 42 79 74 65 73 29 3d 3d  zSpace-nBytes)==
18d0: 28 63 68 61 72 20 2a 29 61 43 6f 6c 20 29 3b 0a  (char *)aCol );.
18e0: 20 20 7d 0a 0a 20 20 2a 70 61 43 6f 6c 20 3d 20    }..  *paCol = 
18f0: 61 43 6f 6c 3b 0a 20 20 2a 70 6e 43 6f 6c 20 3d  aCol;.  *pnCol =
1900: 20 6e 43 6f 6c 3b 0a 0a 6f 75 74 3a 0a 20 20 73   nCol;..out:.  s
1910: 71 6c 69 74 65 33 5f 66 69 6e 61 6c 69 7a 65 28  qlite3_finalize(
1920: 70 53 74 6d 74 29 3b 0a 20 20 72 65 74 75 72 6e  pStmt);.  return
1930: 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 50 61   rc;.}../*.** Pa
1940: 72 61 6d 65 74 65 72 20 7a 54 61 62 20 69 73 20  rameter zTab is 
1950: 74 68 65 20 6e 61 6d 65 20 6f 66 20 61 20 74 61  the name of a ta
1960: 62 6c 65 20 69 6e 20 64 61 74 61 62 61 73 65 20  ble in database 
1970: 64 62 20 77 69 74 68 20 6e 43 6f 6c 20 0a 2a 2a  db with nCol .**
1980: 20 63 6f 6c 75 6d 6e 73 2e 20 54 68 69 73 20 66   columns. This f
1990: 75 6e 63 74 69 6f 6e 20 61 6c 6c 6f 63 61 74 65  unction allocate
19a0: 73 20 61 6e 20 61 72 72 61 79 20 6f 66 20 69 6e  s an array of in
19b0: 74 65 67 65 72 73 20 6e 43 6f 6c 20 69 6e 20 0a  tegers nCol in .
19c0: 2a 2a 20 73 69 7a 65 20 61 6e 64 20 70 6f 70 75  ** size and popu
19d0: 6c 61 74 65 73 20 69 74 20 61 63 63 6f 72 64 69  lates it accordi
19e0: 6e 67 20 74 6f 20 61 6e 79 20 69 6d 70 6c 69 63  ng to any implic
19f0: 69 74 20 6f 72 20 65 78 70 6c 69 63 69 74 20 0a  it or explicit .
1a00: 2a 2a 20 69 6e 64 69 63 65 73 20 6f 6e 20 74 61  ** indices on ta
1a10: 62 6c 65 20 7a 54 61 62 2e 0a 2a 2a 0a 2a 2a 20  ble zTab..**.** 
1a20: 49 66 20 73 75 63 63 65 73 73 66 75 6c 2c 20 53  If successful, S
1a30: 51 4c 49 54 45 5f 4f 4b 20 69 73 20 72 65 74 75  QLITE_OK is retu
1a40: 72 6e 65 64 20 61 6e 64 20 2a 70 61 49 6e 64 65  rned and *paInde
1a50: 78 20 73 65 74 20 74 6f 20 70 6f 69 6e 74 20 0a  x set to point .
1a60: 2a 2a 20 61 74 20 74 68 65 20 61 6c 6c 6f 63 61  ** at the alloca
1a70: 74 65 64 20 61 72 72 61 79 2e 20 4f 74 68 65 72  ted array. Other
1a80: 77 69 73 65 2c 20 61 6e 20 65 72 72 6f 72 20 63  wise, an error c
1a90: 6f 64 65 20 69 73 20 72 65 74 75 72 6e 65 64 2e  ode is returned.
1aa0: 0a 2a 2a 0a 2a 2a 20 53 65 65 20 63 6f 6d 6d 65  .**.** See comme
1ab0: 6e 74 73 20 61 73 73 6f 63 69 61 74 65 64 20 77  nts associated w
1ac0: 69 74 68 20 74 68 65 20 6d 65 6d 62 65 72 20 76  ith the member v
1ad0: 61 72 69 61 62 6c 65 20 61 49 6e 64 65 78 20 61  ariable aIndex a
1ae0: 62 6f 76 65 20 0a 2a 2a 20 22 73 74 72 75 63 74  bove .** "struct
1af0: 20 65 63 68 6f 5f 76 74 61 62 22 20 66 6f 72 20   echo_vtab" for 
1b00: 64 65 74 61 69 6c 73 20 6f 66 20 74 68 65 20 63  details of the c
1b10: 6f 6e 74 65 6e 74 73 20 6f 66 20 74 68 65 20 61  ontents of the a
1b20: 72 72 61 79 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  rray..*/.static 
1b30: 69 6e 74 20 67 65 74 49 6e 64 65 78 41 72 72 61  int getIndexArra
1b40: 79 28 0a 20 20 73 71 6c 69 74 65 33 20 2a 64 62  y(.  sqlite3 *db
1b50: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a  ,             /*
1b60: 20 44 61 74 61 62 61 73 65 20 63 6f 6e 6e 65 63   Database connec
1b70: 74 69 6f 6e 20 2a 2f 0a 20 20 63 6f 6e 73 74 20  tion */.  const 
1b80: 63 68 61 72 20 2a 7a 54 61 62 2c 20 20 20 20 20  char *zTab,     
1b90: 20 20 20 2f 2a 20 4e 61 6d 65 20 6f 66 20 74 61     /* Name of ta
1ba0: 62 6c 65 20 69 6e 20 64 61 74 61 62 61 73 65 20  ble in database 
1bb0: 64 62 20 2a 2f 0a 20 20 69 6e 74 20 6e 43 6f 6c  db */.  int nCol
1bc0: 2c 0a 20 20 69 6e 74 20 2a 2a 70 61 49 6e 64 65  ,.  int **paInde
1bd0: 78 0a 29 7b 0a 20 20 73 71 6c 69 74 65 33 5f 73  x.){.  sqlite3_s
1be0: 74 6d 74 20 2a 70 53 74 6d 74 20 3d 20 30 3b 0a  tmt *pStmt = 0;.
1bf0: 20 20 69 6e 74 20 2a 61 49 6e 64 65 78 20 3d 20    int *aIndex = 
1c00: 30 3b 0a 20 20 69 6e 74 20 72 63 3b 0a 20 20 63  0;.  int rc;.  c
1c10: 68 61 72 20 2a 7a 53 71 6c 3b 0a 0a 20 20 2f 2a  har *zSql;..  /*
1c20: 20 41 6c 6c 6f 63 61 74 65 20 73 70 61 63 65 20   Allocate space 
1c30: 66 6f 72 20 74 68 65 20 69 6e 64 65 78 20 61 72  for the index ar
1c40: 72 61 79 20 2a 2f 0a 20 20 61 49 6e 64 65 78 20  ray */.  aIndex 
1c50: 3d 20 28 69 6e 74 20 2a 29 73 71 6c 69 74 65 33  = (int *)sqlite3
1c60: 4d 61 6c 6c 6f 63 5a 65 72 6f 28 73 69 7a 65 6f  MallocZero(sizeo
1c70: 66 28 69 6e 74 29 20 2a 20 6e 43 6f 6c 29 3b 0a  f(int) * nCol);.
1c80: 20 20 69 66 28 20 21 61 49 6e 64 65 78 20 29 7b    if( !aIndex ){
1c90: 0a 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45  .    rc = SQLITE
1ca0: 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 67 6f 74 6f  _NOMEM;.    goto
1cb0: 20 67 65 74 5f 69 6e 64 65 78 5f 61 72 72 61 79   get_index_array
1cc0: 5f 6f 75 74 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20  _out;.  }..  /* 
1cd0: 43 6f 6d 70 69 6c 65 20 61 6e 20 73 71 6c 69 74  Compile an sqlit
1ce0: 65 20 70 72 61 67 6d 61 20 74 6f 20 6c 6f 6f 70  e pragma to loop
1cf0: 20 74 68 72 6f 75 67 68 20 61 6c 6c 20 69 6e 64   through all ind
1d00: 69 63 65 73 20 6f 6e 20 74 61 62 6c 65 20 7a 54  ices on table zT
1d10: 61 62 20 2a 2f 0a 20 20 7a 53 71 6c 20 3d 20 73  ab */.  zSql = s
1d20: 71 6c 69 74 65 33 4d 50 72 69 6e 74 66 28 30 2c  qlite3MPrintf(0,
1d30: 20 22 50 52 41 47 4d 41 20 69 6e 64 65 78 5f 6c   "PRAGMA index_l
1d40: 69 73 74 28 25 73 29 22 2c 20 7a 54 61 62 29 3b  ist(%s)", zTab);
1d50: 0a 20 20 69 66 28 20 21 7a 53 71 6c 20 29 7b 0a  .  if( !zSql ){.
1d60: 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f      rc = SQLITE_
1d70: 4e 4f 4d 45 4d 3b 0a 20 20 20 20 67 6f 74 6f 20  NOMEM;.    goto 
1d80: 67 65 74 5f 69 6e 64 65 78 5f 61 72 72 61 79 5f  get_index_array_
1d90: 6f 75 74 3b 0a 20 20 7d 0a 20 20 72 63 20 3d 20  out;.  }.  rc = 
1da0: 73 71 6c 69 74 65 33 5f 70 72 65 70 61 72 65 28  sqlite3_prepare(
1db0: 64 62 2c 20 7a 53 71 6c 2c 20 2d 31 2c 20 26 70  db, zSql, -1, &p
1dc0: 53 74 6d 74 2c 20 30 29 3b 0a 20 20 73 71 6c 69  Stmt, 0);.  sqli
1dd0: 74 65 33 5f 66 72 65 65 28 7a 53 71 6c 29 3b 0a  te3_free(zSql);.
1de0: 0a 20 20 2f 2a 20 46 6f 72 20 65 61 63 68 20 69  .  /* For each i
1df0: 6e 64 65 78 2c 20 66 69 67 75 72 65 20 6f 75 74  ndex, figure out
1e00: 20 74 68 65 20 6c 65 66 74 2d 6d 6f 73 74 20 63   the left-most c
1e10: 6f 6c 75 6d 6e 20 61 6e 64 20 73 65 74 20 74 68  olumn and set th
1e20: 65 20 0a 20 20 2a 2a 20 63 6f 72 72 65 73 70 6f  e .  ** correspo
1e30: 6e 64 69 6e 67 20 65 6e 74 72 79 20 69 6e 20 61  nding entry in a
1e40: 49 6e 64 65 78 5b 5d 20 74 6f 20 31 2e 0a 20 20  Index[] to 1..  
1e50: 2a 2f 0a 20 20 77 68 69 6c 65 28 20 70 53 74 6d  */.  while( pStm
1e60: 74 20 26 26 20 73 71 6c 69 74 65 33 5f 73 74 65  t && sqlite3_ste
1e70: 70 28 70 53 74 6d 74 29 3d 3d 53 51 4c 49 54 45  p(pStmt)==SQLITE
1e80: 5f 52 4f 57 20 29 7b 0a 20 20 20 20 63 6f 6e 73  _ROW ){.    cons
1e90: 74 20 63 68 61 72 20 2a 7a 49 64 78 20 3d 20 28  t char *zIdx = (
1ea0: 63 6f 6e 73 74 20 63 68 61 72 20 2a 29 73 71 6c  const char *)sql
1eb0: 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 74 65 78 74  ite3_column_text
1ec0: 28 70 53 74 6d 74 2c 20 31 29 3b 0a 20 20 20 20  (pStmt, 1);.    
1ed0: 73 71 6c 69 74 65 33 5f 73 74 6d 74 20 2a 70 53  sqlite3_stmt *pS
1ee0: 74 6d 74 32 20 3d 20 30 3b 0a 20 20 20 20 7a 53  tmt2 = 0;.    zS
1ef0: 71 6c 20 3d 20 73 71 6c 69 74 65 33 4d 50 72 69  ql = sqlite3MPri
1f00: 6e 74 66 28 30 2c 20 22 50 52 41 47 4d 41 20 69  ntf(0, "PRAGMA i
1f10: 6e 64 65 78 5f 69 6e 66 6f 28 25 73 29 22 2c 20  ndex_info(%s)", 
1f20: 7a 49 64 78 29 3b 0a 20 20 20 20 69 66 28 20 21  zIdx);.    if( !
1f30: 7a 53 71 6c 20 29 7b 0a 20 20 20 20 20 20 72 63  zSql ){.      rc
1f40: 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b   = SQLITE_NOMEM;
1f50: 0a 20 20 20 20 20 20 67 6f 74 6f 20 67 65 74 5f  .      goto get_
1f60: 69 6e 64 65 78 5f 61 72 72 61 79 5f 6f 75 74 3b  index_array_out;
1f70: 0a 20 20 20 20 7d 0a 20 20 20 20 72 63 20 3d 20  .    }.    rc = 
1f80: 73 71 6c 69 74 65 33 5f 70 72 65 70 61 72 65 28  sqlite3_prepare(
1f90: 64 62 2c 20 7a 53 71 6c 2c 20 2d 31 2c 20 26 70  db, zSql, -1, &p
1fa0: 53 74 6d 74 32 2c 20 30 29 3b 0a 20 20 20 20 73  Stmt2, 0);.    s
1fb0: 71 6c 69 74 65 33 5f 66 72 65 65 28 7a 53 71 6c  qlite3_free(zSql
1fc0: 29 3b 0a 20 20 20 20 69 66 28 20 70 53 74 6d 74  );.    if( pStmt
1fd0: 32 20 26 26 20 73 71 6c 69 74 65 33 5f 73 74 65  2 && sqlite3_ste
1fe0: 70 28 70 53 74 6d 74 32 29 3d 3d 53 51 4c 49 54  p(pStmt2)==SQLIT
1ff0: 45 5f 52 4f 57 20 29 7b 0a 20 20 20 20 20 20 69  E_ROW ){.      i
2000: 6e 74 20 63 69 64 20 3d 20 73 71 6c 69 74 65 33  nt cid = sqlite3
2010: 5f 63 6f 6c 75 6d 6e 5f 69 6e 74 28 70 53 74 6d  _column_int(pStm
2020: 74 32 2c 20 31 29 3b 0a 20 20 20 20 20 20 61 73  t2, 1);.      as
2030: 73 65 72 74 28 20 63 69 64 3e 3d 30 20 26 26 20  sert( cid>=0 && 
2040: 63 69 64 3c 6e 43 6f 6c 20 29 3b 0a 20 20 20 20  cid<nCol );.    
2050: 20 20 61 49 6e 64 65 78 5b 63 69 64 5d 20 3d 20    aIndex[cid] = 
2060: 31 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 28  1;.    }.    if(
2070: 20 70 53 74 6d 74 32 20 29 7b 0a 20 20 20 20 20   pStmt2 ){.     
2080: 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 66 69   rc = sqlite3_fi
2090: 6e 61 6c 69 7a 65 28 70 53 74 6d 74 32 29 3b 0a  nalize(pStmt2);.
20a0: 20 20 20 20 7d 0a 20 20 20 20 69 66 28 20 72 63      }.    if( rc
20b0: 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  !=SQLITE_OK ){. 
20c0: 20 20 20 20 20 67 6f 74 6f 20 67 65 74 5f 69 6e       goto get_in
20d0: 64 65 78 5f 61 72 72 61 79 5f 6f 75 74 3b 0a 20  dex_array_out;. 
20e0: 20 20 20 7d 0a 20 20 7d 0a 0a 0a 67 65 74 5f 69     }.  }...get_i
20f0: 6e 64 65 78 5f 61 72 72 61 79 5f 6f 75 74 3a 0a  ndex_array_out:.
2100: 20 20 69 66 28 20 70 53 74 6d 74 20 29 7b 0a 20    if( pStmt ){. 
2110: 20 20 20 69 6e 74 20 72 63 32 20 3d 20 73 71 6c     int rc2 = sql
2120: 69 74 65 33 5f 66 69 6e 61 6c 69 7a 65 28 70 53  ite3_finalize(pS
2130: 74 6d 74 29 3b 0a 20 20 20 20 69 66 28 20 72 63  tmt);.    if( rc
2140: 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  ==SQLITE_OK ){. 
2150: 20 20 20 20 20 72 63 20 3d 20 72 63 32 3b 0a 20       rc = rc2;. 
2160: 20 20 20 7d 0a 20 20 7d 0a 20 20 69 66 28 20 72     }.  }.  if( r
2170: 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a  c!=SQLITE_OK ){.
2180: 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65      sqlite3_free
2190: 28 61 49 6e 64 65 78 29 3b 0a 20 20 20 20 61 49  (aIndex);.    aI
21a0: 6e 64 65 78 20 3d 20 30 3b 0a 20 20 7d 0a 20 20  ndex = 0;.  }.  
21b0: 2a 70 61 49 6e 64 65 78 20 3d 20 61 49 6e 64 65  *paIndex = aInde
21c0: 78 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a  x;.  return rc;.
21d0: 7d 0a 0a 2f 2a 0a 2a 2a 20 47 6c 6f 62 61 6c 20  }../*.** Global 
21e0: 54 63 6c 20 76 61 72 69 61 62 6c 65 20 24 65 63  Tcl variable $ec
21f0: 68 6f 5f 6d 6f 64 75 6c 65 20 69 73 20 61 20 6c  ho_module is a l
2200: 69 73 74 2e 20 54 68 69 73 20 72 6f 75 74 69 6e  ist. This routin
2210: 65 20 61 70 70 65 6e 64 73 0a 2a 2a 20 74 68 65  e appends.** the
2220: 20 73 74 72 69 6e 67 20 65 6c 65 6d 65 6e 74 20   string element 
2230: 7a 41 72 67 20 74 6f 20 74 68 61 74 20 6c 69 73  zArg to that lis
2240: 74 20 69 6e 20 69 6e 74 65 72 70 72 65 74 65 72  t in interpreter
2250: 20 69 6e 74 65 72 70 2e 0a 2a 2f 0a 73 74 61 74   interp..*/.stat
2260: 69 63 20 76 6f 69 64 20 61 70 70 65 6e 64 54 6f  ic void appendTo
2270: 45 63 68 6f 4d 6f 64 75 6c 65 28 54 63 6c 5f 49  EchoModule(Tcl_I
2280: 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 2c 20 63  nterp *interp, c
2290: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 41 72 67 29  onst char *zArg)
22a0: 7b 0a 20 20 69 6e 74 20 66 6c 61 67 73 20 3d 20  {.  int flags = 
22b0: 28 54 43 4c 5f 41 50 50 45 4e 44 5f 56 41 4c 55  (TCL_APPEND_VALU
22c0: 45 20 7c 20 54 43 4c 5f 4c 49 53 54 5f 45 4c 45  E | TCL_LIST_ELE
22d0: 4d 45 4e 54 20 7c 20 54 43 4c 5f 47 4c 4f 42 41  MENT | TCL_GLOBA
22e0: 4c 5f 4f 4e 4c 59 29 3b 0a 20 20 54 63 6c 5f 53  L_ONLY);.  Tcl_S
22f0: 65 74 56 61 72 28 69 6e 74 65 72 70 2c 20 22 65  etVar(interp, "e
2300: 63 68 6f 5f 6d 6f 64 75 6c 65 22 2c 20 28 7a 41  cho_module", (zA
2310: 72 67 3f 7a 41 72 67 3a 22 22 29 2c 20 66 6c 61  rg?zArg:""), fla
2320: 67 73 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68  gs);.}../*.** Th
2330: 69 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 63  is function is c
2340: 61 6c 6c 65 64 20 66 72 6f 6d 20 77 69 74 68 69  alled from withi
2350: 6e 20 74 68 65 20 65 63 68 6f 2d 6d 6f 64 75 6c  n the echo-modul
2360: 65 73 20 78 43 72 65 61 74 65 20 61 6e 64 0a 2a  es xCreate and.*
2370: 2a 20 78 43 6f 6e 6e 65 63 74 20 6d 65 74 68 6f  * xConnect metho
2380: 64 73 2e 20 54 68 65 20 61 72 67 63 20 61 6e 64  ds. The argc and
2390: 20 61 72 67 76 20 61 72 67 75 6d 65 6e 74 73 20   argv arguments 
23a0: 61 72 65 20 63 6f 70 69 65 73 20 6f 66 20 74 68  are copies of th
23b0: 6f 73 65 20 0a 2a 2a 20 70 61 73 73 65 64 20 74  ose .** passed t
23c0: 6f 20 74 68 65 20 63 61 6c 6c 69 6e 67 20 6d 65  o the calling me
23d0: 74 68 6f 64 2e 20 54 68 69 73 20 66 75 6e 63 74  thod. This funct
23e0: 69 6f 6e 20 69 73 20 72 65 73 70 6f 6e 73 69 62  ion is responsib
23f0: 6c 65 20 66 6f 72 0a 2a 2a 20 63 61 6c 6c 69 6e  le for.** callin
2400: 67 20 73 71 6c 69 74 65 33 5f 64 65 63 6c 61 72  g sqlite3_declar
2410: 65 5f 76 74 61 62 28 29 20 74 6f 20 64 65 63 6c  e_vtab() to decl
2420: 61 72 65 20 74 68 65 20 73 63 68 65 6d 61 20 6f  are the schema o
2430: 66 20 74 68 65 20 76 69 72 74 75 61 6c 0a 2a 2a  f the virtual.**
2440: 20 74 61 62 6c 65 20 62 65 69 6e 67 20 63 72 65   table being cre
2450: 61 74 65 64 20 6f 72 20 63 6f 6e 6e 65 63 74 65  ated or connecte
2460: 64 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 74 68 65 20  d..**.** If the 
2470: 63 6f 6e 73 74 72 75 63 74 6f 72 20 77 61 73 20  constructor was 
2480: 70 61 73 73 65 64 20 6a 75 73 74 20 6f 6e 65 20  passed just one 
2490: 61 72 67 75 6d 65 6e 74 2c 20 69 2e 65 2e 3a 0a  argument, i.e.:.
24a0: 2a 2a 0a 2a 2a 20 20 20 43 52 45 41 54 45 20 54  **.**   CREATE T
24b0: 41 42 4c 45 20 74 31 20 41 53 20 65 63 68 6f 28  ABLE t1 AS echo(
24c0: 74 32 29 3b 0a 2a 2a 0a 2a 2a 20 54 68 65 6e 20  t2);.**.** Then 
24d0: 74 32 20 69 73 20 61 73 73 75 6d 65 64 20 74 6f  t2 is assumed to
24e0: 20 62 65 20 74 68 65 20 6e 61 6d 65 20 6f 66 20   be the name of 
24f0: 61 20 2a 72 65 61 6c 2a 20 64 61 74 61 62 61 73  a *real* databas
2500: 65 20 74 61 62 6c 65 2e 20 54 68 65 0a 2a 2a 20  e table. The.** 
2510: 73 63 68 65 6d 61 20 6f 66 20 74 68 65 20 76 69  schema of the vi
2520: 72 74 75 61 6c 20 74 61 62 6c 65 20 69 73 20 64  rtual table is d
2530: 65 63 6c 61 72 65 64 20 62 79 20 70 61 73 73 69  eclared by passi
2540: 6e 67 20 61 20 63 6f 70 79 20 6f 66 20 74 68 65  ng a copy of the
2550: 20 0a 2a 2a 20 43 52 45 41 54 45 20 54 41 42 4c   .** CREATE TABL
2560: 45 20 73 74 61 74 65 6d 65 6e 74 20 66 6f 72 20  E statement for 
2570: 74 68 65 20 72 65 61 6c 20 74 61 62 6c 65 20 74  the real table t
2580: 6f 20 73 71 6c 69 74 65 33 5f 64 65 63 6c 61 72  o sqlite3_declar
2590: 65 5f 76 74 61 62 28 29 2e 0a 2a 2a 20 48 65 6e  e_vtab()..** Hen
25a0: 63 65 2c 20 74 68 65 20 76 69 72 74 75 61 6c 20  ce, the virtual 
25b0: 74 61 62 6c 65 20 73 68 6f 75 6c 64 20 68 61 76  table should hav
25c0: 65 20 65 78 61 63 74 6c 79 20 74 68 65 20 73 61  e exactly the sa
25d0: 6d 65 20 63 6f 6c 75 6d 6e 20 6e 61 6d 65 73 20  me column names 
25e0: 61 6e 64 20 0a 2a 2a 20 74 79 70 65 73 20 61 73  and .** types as
25f0: 20 74 68 65 20 72 65 61 6c 20 74 61 62 6c 65 2e   the real table.
2600: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 65  .*/.static int e
2610: 63 68 6f 44 65 63 6c 61 72 65 56 74 61 62 28 0a  choDeclareVtab(.
2620: 20 20 65 63 68 6f 5f 76 74 61 62 20 2a 70 56 74    echo_vtab *pVt
2630: 61 62 2c 20 0a 20 20 73 71 6c 69 74 65 33 20 2a  ab, .  sqlite3 *
2640: 64 62 20 0a 29 7b 0a 20 20 69 6e 74 20 72 63 20  db .){.  int rc 
2650: 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 0a 20 20  = SQLITE_OK;..  
2660: 69 66 28 20 70 56 74 61 62 2d 3e 7a 54 61 62 6c  if( pVtab->zTabl
2670: 65 4e 61 6d 65 20 29 7b 0a 20 20 20 20 73 71 6c  eName ){.    sql
2680: 69 74 65 33 5f 73 74 6d 74 20 2a 70 53 74 6d 74  ite3_stmt *pStmt
2690: 20 3d 20 30 3b 0a 20 20 20 20 72 63 20 3d 20 73   = 0;.    rc = s
26a0: 71 6c 69 74 65 33 5f 70 72 65 70 61 72 65 28 64  qlite3_prepare(d
26b0: 62 2c 20 0a 20 20 20 20 20 20 20 20 22 53 45 4c  b, .        "SEL
26c0: 45 43 54 20 73 71 6c 20 46 52 4f 4d 20 73 71 6c  ECT sql FROM sql
26d0: 69 74 65 5f 6d 61 73 74 65 72 20 57 48 45 52 45  ite_master WHERE
26e0: 20 74 79 70 65 20 3d 20 27 74 61 62 6c 65 27 20   type = 'table' 
26f0: 41 4e 44 20 6e 61 6d 65 20 3d 20 3f 22 2c 0a 20  AND name = ?",. 
2700: 20 20 20 20 20 20 20 2d 31 2c 20 26 70 53 74 6d         -1, &pStm
2710: 74 2c 20 30 29 3b 0a 20 20 20 20 69 66 28 20 72  t, 0);.    if( r
2720: 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a  c==SQLITE_OK ){.
2730: 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 62 69        sqlite3_bi
2740: 6e 64 5f 74 65 78 74 28 70 53 74 6d 74 2c 20 31  nd_text(pStmt, 1
2750: 2c 20 70 56 74 61 62 2d 3e 7a 54 61 62 6c 65 4e  , pVtab->zTableN
2760: 61 6d 65 2c 20 2d 31 2c 20 30 29 3b 0a 20 20 20  ame, -1, 0);.   
2770: 20 20 20 69 66 28 20 73 71 6c 69 74 65 33 5f 73     if( sqlite3_s
2780: 74 65 70 28 70 53 74 6d 74 29 3d 3d 53 51 4c 49  tep(pStmt)==SQLI
2790: 54 45 5f 52 4f 57 20 29 7b 0a 20 20 20 20 20 20  TE_ROW ){.      
27a0: 20 20 69 6e 74 20 72 63 32 3b 0a 20 20 20 20 20    int rc2;.     
27b0: 20 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a     const char *z
27c0: 43 72 65 61 74 65 54 61 62 6c 65 20 3d 20 28 63  CreateTable = (c
27d0: 6f 6e 73 74 20 63 68 61 72 20 2a 29 73 71 6c 69  onst char *)sqli
27e0: 74 65 33 5f 63 6f 6c 75 6d 6e 5f 74 65 78 74 28  te3_column_text(
27f0: 70 53 74 6d 74 2c 20 30 29 3b 0a 20 20 20 20 20  pStmt, 0);.     
2800: 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f     rc = sqlite3_
2810: 64 65 63 6c 61 72 65 5f 76 74 61 62 28 64 62 2c  declare_vtab(db,
2820: 20 7a 43 72 65 61 74 65 54 61 62 6c 65 29 3b 0a   zCreateTable);.
2830: 20 20 20 20 20 20 20 20 72 63 32 20 3d 20 73 71          rc2 = sq
2840: 6c 69 74 65 33 5f 66 69 6e 61 6c 69 7a 65 28 70  lite3_finalize(p
2850: 53 74 6d 74 29 3b 0a 20 20 20 20 20 20 20 20 69  Stmt);.        i
2860: 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc==SQLITE_OK
2870: 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 72 63   ){.          rc
2880: 20 3d 20 72 63 32 3b 0a 20 20 20 20 20 20 20 20   = rc2;.        
2890: 7d 0a 20 20 20 20 20 20 7d 20 65 6c 73 65 20 7b  }.      } else {
28a0: 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20 73 71  .        rc = sq
28b0: 6c 69 74 65 33 5f 66 69 6e 61 6c 69 7a 65 28 70  lite3_finalize(p
28c0: 53 74 6d 74 29 3b 0a 20 20 20 20 20 20 20 20 69  Stmt);.        i
28d0: 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc==SQLITE_OK
28e0: 20 29 7b 20 0a 20 20 20 20 20 20 20 20 20 20 72   ){ .          r
28f0: 63 20 3d 20 53 51 4c 49 54 45 5f 45 52 52 4f 52  c = SQLITE_ERROR
2900: 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20  ;.        }.    
2910: 20 20 7d 0a 20 20 20 20 20 20 69 66 28 20 72 63    }.      if( rc
2920: 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  ==SQLITE_OK ){. 
2930: 20 20 20 20 20 20 20 72 63 20 3d 20 67 65 74 43         rc = getC
2940: 6f 6c 75 6d 6e 4e 61 6d 65 73 28 64 62 2c 20 70  olumnNames(db, p
2950: 56 74 61 62 2d 3e 7a 54 61 62 6c 65 4e 61 6d 65  Vtab->zTableName
2960: 2c 20 26 70 56 74 61 62 2d 3e 61 43 6f 6c 2c 20  , &pVtab->aCol, 
2970: 26 70 56 74 61 62 2d 3e 6e 43 6f 6c 29 3b 0a 20  &pVtab->nCol);. 
2980: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 69 66 28       }.      if(
2990: 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc==SQLITE_OK )
29a0: 7b 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20 67  {.        rc = g
29b0: 65 74 49 6e 64 65 78 41 72 72 61 79 28 64 62 2c  etIndexArray(db,
29c0: 20 70 56 74 61 62 2d 3e 7a 54 61 62 6c 65 4e 61   pVtab->zTableNa
29d0: 6d 65 2c 20 70 56 74 61 62 2d 3e 6e 43 6f 6c 2c  me, pVtab->nCol,
29e0: 20 26 70 56 74 61 62 2d 3e 61 49 6e 64 65 78 29   &pVtab->aIndex)
29f0: 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a  ;.      }.    }.
2a00: 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 72 63    }..  return rc
2a10: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20  ;.}../*.** This 
2a20: 66 75 6e 63 74 69 6f 6e 20 66 72 65 65 73 20 61  function frees a
2a30: 6c 6c 20 72 75 6e 74 69 6d 65 20 73 74 72 75 63  ll runtime struc
2a40: 74 75 72 65 73 20 61 73 73 6f 63 69 61 74 65 64  tures associated
2a50: 20 77 69 74 68 20 74 68 65 20 76 69 72 74 75 61   with the virtua
2a60: 6c 0a 2a 2a 20 74 61 62 6c 65 20 70 56 74 61 62  l.** table pVtab
2a70: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
2a80: 65 63 68 6f 44 65 73 74 72 75 63 74 6f 72 28 73  echoDestructor(s
2a90: 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 70 56 74  qlite3_vtab *pVt
2aa0: 61 62 29 7b 0a 20 20 65 63 68 6f 5f 76 74 61 62  ab){.  echo_vtab
2ab0: 20 2a 70 20 3d 20 28 65 63 68 6f 5f 76 74 61 62   *p = (echo_vtab
2ac0: 2a 29 70 56 74 61 62 3b 0a 20 20 73 71 6c 69 74  *)pVtab;.  sqlit
2ad0: 65 33 5f 66 72 65 65 28 70 2d 3e 61 49 6e 64 65  e3_free(p->aInde
2ae0: 78 29 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66 72  x);.  sqlite3_fr
2af0: 65 65 28 70 2d 3e 61 43 6f 6c 29 3b 0a 20 20 73  ee(p->aCol);.  s
2b00: 71 6c 69 74 65 33 5f 66 72 65 65 28 70 2d 3e 7a  qlite3_free(p->z
2b10: 54 68 69 73 29 3b 0a 20 20 73 71 6c 69 74 65 33  This);.  sqlite3
2b20: 5f 66 72 65 65 28 70 2d 3e 7a 54 61 62 6c 65 4e  _free(p->zTableN
2b30: 61 6d 65 29 3b 0a 20 20 73 71 6c 69 74 65 33 5f  ame);.  sqlite3_
2b40: 66 72 65 65 28 70 2d 3e 7a 4c 6f 67 4e 61 6d 65  free(p->zLogName
2b50: 29 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66 72 65  );.  sqlite3_fre
2b60: 65 28 70 29 3b 0a 20 20 72 65 74 75 72 6e 20 30  e(p);.  return 0
2b70: 3b 0a 7d 0a 0a 74 79 70 65 64 65 66 20 73 74 72  ;.}..typedef str
2b80: 75 63 74 20 45 63 68 6f 4d 6f 64 75 6c 65 20 45  uct EchoModule E
2b90: 63 68 6f 4d 6f 64 75 6c 65 3b 0a 73 74 72 75 63  choModule;.struc
2ba0: 74 20 45 63 68 6f 4d 6f 64 75 6c 65 20 7b 0a 20  t EchoModule {. 
2bb0: 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74   Tcl_Interp *int
2bc0: 65 72 70 3b 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 54  erp;.};../*.** T
2bd0: 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20  his function is 
2be0: 63 61 6c 6c 65 64 20 74 6f 20 64 6f 20 74 68 65  called to do the
2bf0: 20 77 6f 72 6b 20 6f 66 20 74 68 65 20 78 43 6f   work of the xCo
2c00: 6e 6e 65 63 74 28 29 20 6d 65 74 68 6f 64 20 2d  nnect() method -
2c10: 0a 2a 2a 20 74 6f 20 61 6c 6c 6f 63 61 74 65 20  .** to allocate 
2c20: 74 68 65 20 72 65 71 75 69 72 65 64 20 69 6e 2d  the required in-
2c30: 6d 65 6d 6f 72 79 20 73 74 72 75 63 74 75 72 65  memory structure
2c40: 73 20 66 6f 72 20 61 20 6e 65 77 6c 79 20 63 6f  s for a newly co
2c50: 6e 6e 65 63 74 65 64 0a 2a 2a 20 76 69 72 74 75  nnected.** virtu
2c60: 61 6c 20 74 61 62 6c 65 2e 0a 2a 2f 0a 73 74 61  al table..*/.sta
2c70: 74 69 63 20 69 6e 74 20 65 63 68 6f 43 6f 6e 73  tic int echoCons
2c80: 74 72 75 63 74 6f 72 28 0a 20 20 73 71 6c 69 74  tructor(.  sqlit
2c90: 65 33 20 2a 64 62 2c 0a 20 20 76 6f 69 64 20 2a  e3 *db,.  void *
2ca0: 70 41 75 78 2c 0a 20 20 69 6e 74 20 61 72 67 63  pAux,.  int argc
2cb0: 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 63 6f  , const char *co
2cc0: 6e 73 74 2a 61 72 67 76 2c 0a 20 20 73 71 6c 69  nst*argv,.  sqli
2cd0: 74 65 33 5f 76 74 61 62 20 2a 2a 70 70 56 74 61  te3_vtab **ppVta
2ce0: 62 2c 0a 20 20 63 68 61 72 20 2a 2a 70 7a 45 72  b,.  char **pzEr
2cf0: 72 0a 29 7b 0a 20 20 69 6e 74 20 72 63 3b 0a 20  r.){.  int rc;. 
2d00: 20 69 6e 74 20 69 3b 0a 20 20 65 63 68 6f 5f 76   int i;.  echo_v
2d10: 74 61 62 20 2a 70 56 74 61 62 3b 0a 0a 20 20 2f  tab *pVtab;..  /
2d20: 2a 20 41 6c 6c 6f 63 61 74 65 20 74 68 65 20 73  * Allocate the s
2d30: 71 6c 69 74 65 33 5f 76 74 61 62 2f 65 63 68 6f  qlite3_vtab/echo
2d40: 5f 76 74 61 62 20 73 74 72 75 63 74 75 72 65 20  _vtab structure 
2d50: 69 74 73 65 6c 66 20 2a 2f 0a 20 20 70 56 74 61  itself */.  pVta
2d60: 62 20 3d 20 73 71 6c 69 74 65 33 4d 61 6c 6c 6f  b = sqlite3Mallo
2d70: 63 5a 65 72 6f 28 20 73 69 7a 65 6f 66 28 2a 70  cZero( sizeof(*p
2d80: 56 74 61 62 29 20 29 3b 0a 20 20 69 66 28 20 21  Vtab) );.  if( !
2d90: 70 56 74 61 62 20 29 7b 0a 20 20 20 20 72 65 74  pVtab ){.    ret
2da0: 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d  urn SQLITE_NOMEM
2db0: 3b 0a 20 20 7d 0a 20 20 70 56 74 61 62 2d 3e 69  ;.  }.  pVtab->i
2dc0: 6e 74 65 72 70 20 3d 20 28 28 45 63 68 6f 4d 6f  nterp = ((EchoMo
2dd0: 64 75 6c 65 20 2a 29 70 41 75 78 29 2d 3e 69 6e  dule *)pAux)->in
2de0: 74 65 72 70 3b 0a 20 20 70 56 74 61 62 2d 3e 64  terp;.  pVtab->d
2df0: 62 20 3d 20 64 62 3b 0a 0a 20 20 2f 2a 20 41 6c  b = db;..  /* Al
2e00: 6c 6f 63 61 74 65 20 65 63 68 6f 5f 76 74 61 62  locate echo_vtab
2e10: 2e 7a 54 68 69 73 20 2a 2f 0a 20 20 70 56 74 61  .zThis */.  pVta
2e20: 62 2d 3e 7a 54 68 69 73 20 3d 20 73 71 6c 69 74  b->zThis = sqlit
2e30: 65 33 4d 50 72 69 6e 74 66 28 30 2c 20 22 25 73  e3MPrintf(0, "%s
2e40: 22 2c 20 61 72 67 76 5b 32 5d 29 3b 0a 20 20 69  ", argv[2]);.  i
2e50: 66 28 20 21 70 56 74 61 62 2d 3e 7a 54 68 69 73  f( !pVtab->zThis
2e60: 20 29 7b 0a 20 20 20 20 65 63 68 6f 44 65 73 74   ){.    echoDest
2e70: 72 75 63 74 6f 72 28 28 73 71 6c 69 74 65 33 5f  ructor((sqlite3_
2e80: 76 74 61 62 20 2a 29 70 56 74 61 62 29 3b 0a 20  vtab *)pVtab);. 
2e90: 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45     return SQLITE
2ea0: 5f 4e 4f 4d 45 4d 3b 0a 20 20 7d 0a 0a 20 20 2f  _NOMEM;.  }..  /
2eb0: 2a 20 41 6c 6c 6f 63 61 74 65 20 65 63 68 6f 5f  * Allocate echo_
2ec0: 76 74 61 62 2e 7a 54 61 62 6c 65 4e 61 6d 65 20  vtab.zTableName 
2ed0: 2a 2f 0a 20 20 69 66 28 20 61 72 67 63 3e 33 20  */.  if( argc>3 
2ee0: 29 7b 0a 20 20 20 20 70 56 74 61 62 2d 3e 7a 54  ){.    pVtab->zT
2ef0: 61 62 6c 65 4e 61 6d 65 20 3d 20 73 71 6c 69 74  ableName = sqlit
2f00: 65 33 4d 50 72 69 6e 74 66 28 30 2c 20 22 25 73  e3MPrintf(0, "%s
2f10: 22 2c 20 61 72 67 76 5b 33 5d 29 3b 0a 20 20 20  ", argv[3]);.   
2f20: 20 64 65 71 75 6f 74 65 53 74 72 69 6e 67 28 70   dequoteString(p
2f30: 56 74 61 62 2d 3e 7a 54 61 62 6c 65 4e 61 6d 65  Vtab->zTableName
2f40: 29 3b 0a 20 20 20 20 69 66 28 20 70 56 74 61 62  );.    if( pVtab
2f50: 2d 3e 7a 54 61 62 6c 65 4e 61 6d 65 20 26 26 20  ->zTableName && 
2f60: 70 56 74 61 62 2d 3e 7a 54 61 62 6c 65 4e 61 6d  pVtab->zTableNam
2f70: 65 5b 30 5d 3d 3d 27 2a 27 20 29 7b 0a 20 20 20  e[0]=='*' ){.   
2f80: 20 20 20 63 68 61 72 20 2a 7a 20 3d 20 73 71 6c     char *z = sql
2f90: 69 74 65 33 4d 50 72 69 6e 74 66 28 30 2c 20 22  ite3MPrintf(0, "
2fa0: 25 73 25 73 22 2c 20 61 72 67 76 5b 32 5d 2c 20  %s%s", argv[2], 
2fb0: 26 28 70 56 74 61 62 2d 3e 7a 54 61 62 6c 65 4e  &(pVtab->zTableN
2fc0: 61 6d 65 5b 31 5d 29 29 3b 0a 20 20 20 20 20 20  ame[1]));.      
2fd0: 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70 56 74  sqlite3_free(pVt
2fe0: 61 62 2d 3e 7a 54 61 62 6c 65 4e 61 6d 65 29 3b  ab->zTableName);
2ff0: 0a 20 20 20 20 20 20 70 56 74 61 62 2d 3e 7a 54  .      pVtab->zT
3000: 61 62 6c 65 4e 61 6d 65 20 3d 20 7a 3b 0a 20 20  ableName = z;.  
3010: 20 20 20 20 70 56 74 61 62 2d 3e 69 73 50 61 74      pVtab->isPat
3020: 74 65 72 6e 20 3d 20 31 3b 0a 20 20 20 20 7d 0a  tern = 1;.    }.
3030: 20 20 20 20 69 66 28 20 21 70 56 74 61 62 2d 3e      if( !pVtab->
3040: 7a 54 61 62 6c 65 4e 61 6d 65 20 29 7b 0a 20 20  zTableName ){.  
3050: 20 20 20 20 65 63 68 6f 44 65 73 74 72 75 63 74      echoDestruct
3060: 6f 72 28 28 73 71 6c 69 74 65 33 5f 76 74 61 62  or((sqlite3_vtab
3070: 20 2a 29 70 56 74 61 62 29 3b 0a 20 20 20 20 20   *)pVtab);.     
3080: 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4e   return SQLITE_N
3090: 4f 4d 45 4d 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a  OMEM;.    }.  }.
30a0: 0a 20 20 2f 2a 20 4c 6f 67 20 74 68 65 20 61 72  .  /* Log the ar
30b0: 67 75 6d 65 6e 74 73 20 74 6f 20 74 68 69 73 20  guments to this 
30c0: 66 75 6e 63 74 69 6f 6e 20 74 6f 20 54 63 6c 20  function to Tcl 
30d0: 76 61 72 20 3a 3a 65 63 68 6f 5f 6d 6f 64 75 6c  var ::echo_modul
30e0: 65 20 2a 2f 0a 20 20 66 6f 72 28 69 3d 30 3b 20  e */.  for(i=0; 
30f0: 69 3c 61 72 67 63 3b 20 69 2b 2b 29 7b 0a 20 20  i<argc; i++){.  
3100: 20 20 61 70 70 65 6e 64 54 6f 45 63 68 6f 4d 6f    appendToEchoMo
3110: 64 75 6c 65 28 70 56 74 61 62 2d 3e 69 6e 74 65  dule(pVtab->inte
3120: 72 70 2c 20 61 72 67 76 5b 69 5d 29 3b 0a 20 20  rp, argv[i]);.  
3130: 7d 0a 0a 20 20 2f 2a 20 49 6e 76 6f 6b 65 20 73  }..  /* Invoke s
3140: 71 6c 69 74 65 33 5f 64 65 63 6c 61 72 65 5f 76  qlite3_declare_v
3150: 74 61 62 20 61 6e 64 20 73 65 74 20 75 70 20 6f  tab and set up o
3160: 74 68 65 72 20 6d 65 6d 62 65 72 73 20 6f 66 20  ther members of 
3170: 74 68 65 20 65 63 68 6f 5f 76 74 61 62 0a 20 20  the echo_vtab.  
3180: 2a 2a 20 73 74 72 75 63 74 75 72 65 2e 20 49 66  ** structure. If
3190: 20 61 6e 20 65 72 72 6f 72 20 6f 63 63 75 72 73   an error occurs
31a0: 2c 20 64 65 6c 65 74 65 20 74 68 65 20 73 71 6c  , delete the sql
31b0: 69 74 65 33 5f 76 74 61 62 20 73 74 72 75 63 74  ite3_vtab struct
31c0: 75 72 65 20 61 6e 64 0a 20 20 2a 2a 20 72 65 74  ure and.  ** ret
31d0: 75 72 6e 20 61 6e 20 65 72 72 6f 72 20 63 6f 64  urn an error cod
31e0: 65 2e 0a 20 20 2a 2f 0a 20 20 72 63 20 3d 20 65  e..  */.  rc = e
31f0: 63 68 6f 44 65 63 6c 61 72 65 56 74 61 62 28 70  choDeclareVtab(p
3200: 56 74 61 62 2c 20 64 62 29 3b 0a 20 20 69 66 28  Vtab, db);.  if(
3210: 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc!=SQLITE_OK )
3220: 7b 0a 20 20 20 20 65 63 68 6f 44 65 73 74 72 75  {.    echoDestru
3230: 63 74 6f 72 28 28 73 71 6c 69 74 65 33 5f 76 74  ctor((sqlite3_vt
3240: 61 62 20 2a 29 70 56 74 61 62 29 3b 0a 20 20 20  ab *)pVtab);.   
3250: 20 72 65 74 75 72 6e 20 72 63 3b 0a 20 20 7d 0a   return rc;.  }.
3260: 0a 20 20 2f 2a 20 53 75 63 63 65 73 73 2e 20 53  .  /* Success. S
3270: 65 74 20 2a 70 70 56 74 61 62 20 61 6e 64 20 72  et *ppVtab and r
3280: 65 74 75 72 6e 20 2a 2f 0a 20 20 2a 70 70 56 74  eturn */.  *ppVt
3290: 61 62 20 3d 20 26 70 56 74 61 62 2d 3e 62 61 73  ab = &pVtab->bas
32a0: 65 3b 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49  e;.  return SQLI
32b0: 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a  TE_OK;.}../* .**
32c0: 20 45 63 68 6f 20 76 69 72 74 75 61 6c 20 74 61   Echo virtual ta
32d0: 62 6c 65 20 6d 6f 64 75 6c 65 20 78 43 72 65 61  ble module xCrea
32e0: 74 65 20 6d 65 74 68 6f 64 2e 0a 2a 2f 0a 73 74  te method..*/.st
32f0: 61 74 69 63 20 69 6e 74 20 65 63 68 6f 43 72 65  atic int echoCre
3300: 61 74 65 28 0a 20 20 73 71 6c 69 74 65 33 20 2a  ate(.  sqlite3 *
3310: 64 62 2c 0a 20 20 76 6f 69 64 20 2a 70 41 75 78  db,.  void *pAux
3320: 2c 0a 20 20 69 6e 74 20 61 72 67 63 2c 20 63 6f  ,.  int argc, co
3330: 6e 73 74 20 63 68 61 72 20 2a 63 6f 6e 73 74 2a  nst char *const*
3340: 61 72 67 76 2c 0a 20 20 73 71 6c 69 74 65 33 5f  argv,.  sqlite3_
3350: 76 74 61 62 20 2a 2a 70 70 56 74 61 62 2c 0a 20  vtab **ppVtab,. 
3360: 20 63 68 61 72 20 2a 2a 70 7a 45 72 72 0a 29 7b   char **pzErr.){
3370: 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49  .  int rc = SQLI
3380: 54 45 5f 4f 4b 3b 0a 20 20 61 70 70 65 6e 64 54  TE_OK;.  appendT
3390: 6f 45 63 68 6f 4d 6f 64 75 6c 65 28 28 28 45 63  oEchoModule(((Ec
33a0: 68 6f 4d 6f 64 75 6c 65 20 2a 29 70 41 75 78 29  hoModule *)pAux)
33b0: 2d 3e 69 6e 74 65 72 70 2c 20 22 78 43 72 65 61  ->interp, "xCrea
33c0: 74 65 22 29 3b 0a 20 20 72 63 20 3d 20 65 63 68  te");.  rc = ech
33d0: 6f 43 6f 6e 73 74 72 75 63 74 6f 72 28 64 62 2c  oConstructor(db,
33e0: 20 70 41 75 78 2c 20 61 72 67 63 2c 20 61 72 67   pAux, argc, arg
33f0: 76 2c 20 70 70 56 74 61 62 2c 20 70 7a 45 72 72  v, ppVtab, pzErr
3400: 29 3b 0a 0a 20 20 2f 2a 20 49 66 20 74 68 65 72  );..  /* If ther
3410: 65 20 77 65 72 65 20 74 77 6f 20 61 72 67 75 6d  e were two argum
3420: 65 6e 74 73 20 70 61 73 73 65 64 20 74 6f 20 74  ents passed to t
3430: 68 65 20 6d 6f 64 75 6c 65 20 61 74 20 74 68 65  he module at the
3440: 20 53 51 4c 20 6c 65 76 65 6c 20 0a 20 20 2a 2a   SQL level .  **
3450: 20 28 69 2e 65 2e 20 22 43 52 45 41 54 45 20 56   (i.e. "CREATE V
3460: 49 52 54 55 41 4c 20 54 41 42 4c 45 20 74 62 6c  IRTUAL TABLE tbl
3470: 20 55 53 49 4e 47 20 65 63 68 6f 28 61 72 67 31   USING echo(arg1
3480: 2c 20 61 72 67 32 29 22 29 2c 20 74 68 65 6e 20  , arg2)"), then 
3490: 0a 20 20 2a 2a 20 74 68 65 20 73 65 63 6f 6e 64  .  ** the second
34a0: 20 61 72 67 75 6d 65 6e 74 20 69 73 20 75 73 65   argument is use
34b0: 64 20 61 73 20 61 20 74 61 62 6c 65 20 6e 61 6d  d as a table nam
34c0: 65 2e 20 41 74 74 65 6d 70 74 20 74 6f 20 63 72  e. Attempt to cr
34d0: 65 61 74 65 0a 20 20 2a 2a 20 73 75 63 68 20 61  eate.  ** such a
34e0: 20 74 61 62 6c 65 20 77 69 74 68 20 61 20 73 69   table with a si
34f0: 6e 67 6c 65 20 63 6f 6c 75 6d 6e 2c 20 22 6c 6f  ngle column, "lo
3500: 67 6d 73 67 22 2e 20 54 68 69 73 20 74 61 62 6c  gmsg". This tabl
3510: 65 20 77 69 6c 6c 0a 20 20 2a 2a 20 62 65 20 75  e will.  ** be u
3520: 73 65 64 20 74 6f 20 6c 6f 67 20 63 61 6c 6c 73  sed to log calls
3530: 20 74 6f 20 74 68 65 20 78 55 70 64 61 74 65 20   to the xUpdate 
3540: 6d 65 74 68 6f 64 2e 20 49 74 20 77 69 6c 6c 20  method. It will 
3550: 62 65 20 64 65 6c 65 74 65 64 0a 20 20 2a 2a 20  be deleted.  ** 
3560: 77 68 65 6e 20 74 68 65 20 76 69 72 74 75 61 6c  when the virtual
3570: 20 74 61 62 6c 65 20 69 73 20 44 52 4f 50 65 64   table is DROPed
3580: 2e 0a 20 20 2a 2a 0a 20 20 2a 2a 20 4e 6f 74 65  ..  **.  ** Note
3590: 3a 20 54 68 65 20 6d 61 69 6e 20 70 6f 69 6e 74  : The main point
35a0: 20 6f 66 20 74 68 69 73 20 69 73 20 74 6f 20 74   of this is to t
35b0: 65 73 74 20 74 68 61 74 20 77 65 20 63 61 6e 20  est that we can 
35c0: 64 72 6f 70 20 74 61 62 6c 65 73 0a 20 20 2a 2a  drop tables.  **
35d0: 20 66 72 6f 6d 20 77 69 74 68 69 6e 20 61 6e 20   from within an 
35e0: 78 44 65 73 74 72 6f 79 20 6d 65 74 68 6f 64 20  xDestroy method 
35f0: 63 61 6c 6c 2e 0a 20 20 2a 2f 0a 20 20 69 66 28  call..  */.  if(
3600: 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26   rc==SQLITE_OK &
3610: 26 20 61 72 67 63 3d 3d 35 20 29 7b 0a 20 20 20  & argc==5 ){.   
3620: 20 63 68 61 72 20 2a 7a 53 71 6c 3b 0a 20 20 20   char *zSql;.   
3630: 20 65 63 68 6f 5f 76 74 61 62 20 2a 70 56 74 61   echo_vtab *pVta
3640: 62 20 3d 20 2a 28 65 63 68 6f 5f 76 74 61 62 20  b = *(echo_vtab 
3650: 2a 2a 29 70 70 56 74 61 62 3b 0a 20 20 20 20 70  **)ppVtab;.    p
3660: 56 74 61 62 2d 3e 7a 4c 6f 67 4e 61 6d 65 20 3d  Vtab->zLogName =
3670: 20 73 71 6c 69 74 65 33 4d 50 72 69 6e 74 66 28   sqlite3MPrintf(
3680: 30 2c 20 22 25 73 22 2c 20 61 72 67 76 5b 34 5d  0, "%s", argv[4]
3690: 29 3b 0a 20 20 20 20 7a 53 71 6c 20 3d 20 73 71  );.    zSql = sq
36a0: 6c 69 74 65 33 4d 50 72 69 6e 74 66 28 30 2c 20  lite3MPrintf(0, 
36b0: 22 43 52 45 41 54 45 20 54 41 42 4c 45 20 25 51  "CREATE TABLE %Q
36c0: 28 6c 6f 67 6d 73 67 29 22 2c 20 70 56 74 61 62  (logmsg)", pVtab
36d0: 2d 3e 7a 4c 6f 67 4e 61 6d 65 29 3b 0a 20 20 20  ->zLogName);.   
36e0: 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 65 78   rc = sqlite3_ex
36f0: 65 63 28 64 62 2c 20 7a 53 71 6c 2c 20 30 2c 20  ec(db, zSql, 0, 
3700: 30 2c 20 30 29 3b 0a 20 20 20 20 73 71 6c 69 74  0, 0);.    sqlit
3710: 65 33 5f 66 72 65 65 28 7a 53 71 6c 29 3b 0a 20  e3_free(zSql);. 
3720: 20 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54     if( rc!=SQLIT
3730: 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 2a 70  E_OK ){.      *p
3740: 7a 45 72 72 20 3d 20 73 71 6c 69 74 65 33 44 62  zErr = sqlite3Db
3750: 53 74 72 44 75 70 28 30 2c 20 73 71 6c 69 74 65  StrDup(0, sqlite
3760: 33 5f 65 72 72 6d 73 67 28 64 62 29 29 3b 0a 20  3_errmsg(db));. 
3770: 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 69 66 28 20     }.  }..  if( 
3780: 2a 70 70 56 74 61 62 20 26 26 20 72 63 21 3d 53  *ppVtab && rc!=S
3790: 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
37a0: 65 63 68 6f 44 65 73 74 72 75 63 74 6f 72 28 2a  echoDestructor(*
37b0: 70 70 56 74 61 62 29 3b 0a 20 20 20 20 2a 70 70  ppVtab);.    *pp
37c0: 56 74 61 62 20 3d 20 30 3b 0a 20 20 7d 0a 0a 20  Vtab = 0;.  }.. 
37d0: 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
37e0: 4f 4b 20 29 7b 0a 20 20 20 20 28 2a 28 65 63 68  OK ){.    (*(ech
37f0: 6f 5f 76 74 61 62 2a 2a 29 70 70 56 74 61 62 29  o_vtab**)ppVtab)
3800: 2d 3e 69 6e 54 72 61 6e 73 61 63 74 69 6f 6e 20  ->inTransaction 
3810: 3d 20 31 3b 0a 20 20 7d 0a 0a 20 20 72 65 74 75  = 1;.  }..  retu
3820: 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a  rn rc;.}../* .**
3830: 20 45 63 68 6f 20 76 69 72 74 75 61 6c 20 74 61   Echo virtual ta
3840: 62 6c 65 20 6d 6f 64 75 6c 65 20 78 43 6f 6e 6e  ble module xConn
3850: 65 63 74 20 6d 65 74 68 6f 64 2e 0a 2a 2f 0a 73  ect method..*/.s
3860: 74 61 74 69 63 20 69 6e 74 20 65 63 68 6f 43 6f  tatic int echoCo
3870: 6e 6e 65 63 74 28 0a 20 20 73 71 6c 69 74 65 33  nnect(.  sqlite3
3880: 20 2a 64 62 2c 0a 20 20 76 6f 69 64 20 2a 70 41   *db,.  void *pA
3890: 75 78 2c 0a 20 20 69 6e 74 20 61 72 67 63 2c 20  ux,.  int argc, 
38a0: 63 6f 6e 73 74 20 63 68 61 72 20 2a 63 6f 6e 73  const char *cons
38b0: 74 2a 61 72 67 76 2c 0a 20 20 73 71 6c 69 74 65  t*argv,.  sqlite
38c0: 33 5f 76 74 61 62 20 2a 2a 70 70 56 74 61 62 2c  3_vtab **ppVtab,
38d0: 0a 20 20 63 68 61 72 20 2a 2a 70 7a 45 72 72 0a  .  char **pzErr.
38e0: 29 7b 0a 20 20 61 70 70 65 6e 64 54 6f 45 63 68  ){.  appendToEch
38f0: 6f 4d 6f 64 75 6c 65 28 28 28 45 63 68 6f 4d 6f  oModule(((EchoMo
3900: 64 75 6c 65 20 2a 29 70 41 75 78 29 2d 3e 69 6e  dule *)pAux)->in
3910: 74 65 72 70 2c 20 22 78 43 6f 6e 6e 65 63 74 22  terp, "xConnect"
3920: 29 3b 0a 20 20 72 65 74 75 72 6e 20 65 63 68 6f  );.  return echo
3930: 43 6f 6e 73 74 72 75 63 74 6f 72 28 64 62 2c 20  Constructor(db, 
3940: 70 41 75 78 2c 20 61 72 67 63 2c 20 61 72 67 76  pAux, argc, argv
3950: 2c 20 70 70 56 74 61 62 2c 20 70 7a 45 72 72 29  , ppVtab, pzErr)
3960: 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 45 63 68 6f  ;.}../* .** Echo
3970: 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65 20 6d   virtual table m
3980: 6f 64 75 6c 65 20 78 44 69 73 63 6f 6e 6e 65 63  odule xDisconnec
3990: 74 20 6d 65 74 68 6f 64 2e 0a 2a 2f 0a 73 74 61  t method..*/.sta
39a0: 74 69 63 20 69 6e 74 20 65 63 68 6f 44 69 73 63  tic int echoDisc
39b0: 6f 6e 6e 65 63 74 28 73 71 6c 69 74 65 33 5f 76  onnect(sqlite3_v
39c0: 74 61 62 20 2a 70 56 74 61 62 29 7b 0a 20 20 61  tab *pVtab){.  a
39d0: 70 70 65 6e 64 54 6f 45 63 68 6f 4d 6f 64 75 6c  ppendToEchoModul
39e0: 65 28 28 28 65 63 68 6f 5f 76 74 61 62 20 2a 29  e(((echo_vtab *)
39f0: 70 56 74 61 62 29 2d 3e 69 6e 74 65 72 70 2c 20  pVtab)->interp, 
3a00: 22 78 44 69 73 63 6f 6e 6e 65 63 74 22 29 3b 0a  "xDisconnect");.
3a10: 20 20 72 65 74 75 72 6e 20 65 63 68 6f 44 65 73    return echoDes
3a20: 74 72 75 63 74 6f 72 28 70 56 74 61 62 29 3b 0a  tructor(pVtab);.
3a30: 7d 0a 0a 2f 2a 20 0a 2a 2a 20 45 63 68 6f 20 76  }../* .** Echo v
3a40: 69 72 74 75 61 6c 20 74 61 62 6c 65 20 6d 6f 64  irtual table mod
3a50: 75 6c 65 20 78 44 65 73 74 72 6f 79 20 6d 65 74  ule xDestroy met
3a60: 68 6f 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  hod..*/.static i
3a70: 6e 74 20 65 63 68 6f 44 65 73 74 72 6f 79 28 73  nt echoDestroy(s
3a80: 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 70 56 74  qlite3_vtab *pVt
3a90: 61 62 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20  ab){.  int rc = 
3aa0: 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 65 63 68  SQLITE_OK;.  ech
3ab0: 6f 5f 76 74 61 62 20 2a 70 20 3d 20 28 65 63 68  o_vtab *p = (ech
3ac0: 6f 5f 76 74 61 62 20 2a 29 70 56 74 61 62 3b 0a  o_vtab *)pVtab;.
3ad0: 20 20 61 70 70 65 6e 64 54 6f 45 63 68 6f 4d 6f    appendToEchoMo
3ae0: 64 75 6c 65 28 28 28 65 63 68 6f 5f 76 74 61 62  dule(((echo_vtab
3af0: 20 2a 29 70 56 74 61 62 29 2d 3e 69 6e 74 65 72   *)pVtab)->inter
3b00: 70 2c 20 22 78 44 65 73 74 72 6f 79 22 29 3b 0a  p, "xDestroy");.
3b10: 0a 20 20 2f 2a 20 44 72 6f 70 20 74 68 65 20 22  .  /* Drop the "
3b20: 6c 6f 67 22 20 74 61 62 6c 65 2c 20 69 66 20 6f  log" table, if o
3b30: 6e 65 20 65 78 69 73 74 73 20 28 73 65 65 20 65  ne exists (see e
3b40: 63 68 6f 43 72 65 61 74 65 28 29 20 66 6f 72 20  choCreate() for 
3b50: 64 65 74 61 69 6c 73 29 20 2a 2f 0a 20 20 69 66  details) */.  if
3b60: 28 20 70 20 26 26 20 70 2d 3e 7a 4c 6f 67 4e 61  ( p && p->zLogNa
3b70: 6d 65 20 29 7b 0a 20 20 20 20 63 68 61 72 20 2a  me ){.    char *
3b80: 7a 53 71 6c 3b 0a 20 20 20 20 7a 53 71 6c 20 3d  zSql;.    zSql =
3b90: 20 73 71 6c 69 74 65 33 4d 50 72 69 6e 74 66 28   sqlite3MPrintf(
3ba0: 30 2c 20 22 44 52 4f 50 20 54 41 42 4c 45 20 25  0, "DROP TABLE %
3bb0: 51 22 2c 20 70 2d 3e 7a 4c 6f 67 4e 61 6d 65 29  Q", p->zLogName)
3bc0: 3b 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74  ;.    rc = sqlit
3bd0: 65 33 5f 65 78 65 63 28 70 2d 3e 64 62 2c 20 7a  e3_exec(p->db, z
3be0: 53 71 6c 2c 20 30 2c 20 30 2c 20 30 29 3b 0a 20  Sql, 0, 0, 0);. 
3bf0: 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28     sqlite3_free(
3c00: 7a 53 71 6c 29 3b 0a 20 20 7d 0a 0a 20 20 69 66  zSql);.  }..  if
3c10: 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
3c20: 29 7b 0a 20 20 20 20 72 63 20 3d 20 65 63 68 6f  ){.    rc = echo
3c30: 44 65 73 74 72 75 63 74 6f 72 28 70 56 74 61 62  Destructor(pVtab
3c40: 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20  );.  }.  return 
3c50: 72 63 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 45 63  rc;.}../* .** Ec
3c60: 68 6f 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65  ho virtual table
3c70: 20 6d 6f 64 75 6c 65 20 78 4f 70 65 6e 20 6d 65   module xOpen me
3c80: 74 68 6f 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  thod..*/.static 
3c90: 69 6e 74 20 65 63 68 6f 4f 70 65 6e 28 73 71 6c  int echoOpen(sql
3ca0: 69 74 65 33 5f 76 74 61 62 20 2a 70 56 54 61 62  ite3_vtab *pVTab
3cb0: 2c 20 73 71 6c 69 74 65 33 5f 76 74 61 62 5f 63  , sqlite3_vtab_c
3cc0: 75 72 73 6f 72 20 2a 2a 70 70 43 75 72 73 6f 72  ursor **ppCursor
3cd0: 29 7b 0a 20 20 65 63 68 6f 5f 63 75 72 73 6f 72  ){.  echo_cursor
3ce0: 20 2a 70 43 75 72 3b 0a 20 20 69 66 28 20 73 69   *pCur;.  if( si
3cf0: 6d 75 6c 61 74 65 56 74 61 62 45 72 72 6f 72 28  mulateVtabError(
3d00: 28 65 63 68 6f 5f 76 74 61 62 20 2a 29 70 56 54  (echo_vtab *)pVT
3d10: 61 62 2c 20 22 78 4f 70 65 6e 22 29 20 29 7b 0a  ab, "xOpen") ){.
3d20: 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54      return SQLIT
3d30: 45 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a 20 20 70  E_ERROR;.  }.  p
3d40: 43 75 72 20 3d 20 73 71 6c 69 74 65 33 4d 61 6c  Cur = sqlite3Mal
3d50: 6c 6f 63 5a 65 72 6f 28 73 69 7a 65 6f 66 28 65  locZero(sizeof(e
3d60: 63 68 6f 5f 63 75 72 73 6f 72 29 29 3b 0a 20 20  cho_cursor));.  
3d70: 2a 70 70 43 75 72 73 6f 72 20 3d 20 28 73 71 6c  *ppCursor = (sql
3d80: 69 74 65 33 5f 76 74 61 62 5f 63 75 72 73 6f 72  ite3_vtab_cursor
3d90: 20 2a 29 70 43 75 72 3b 0a 20 20 72 65 74 75 72   *)pCur;.  retur
3da0: 6e 20 28 70 43 75 72 20 3f 20 53 51 4c 49 54 45  n (pCur ? SQLITE
3db0: 5f 4f 4b 20 3a 20 53 51 4c 49 54 45 5f 4e 4f 4d  _OK : SQLITE_NOM
3dc0: 45 4d 29 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 45  EM);.}../* .** E
3dd0: 63 68 6f 20 76 69 72 74 75 61 6c 20 74 61 62 6c  cho virtual tabl
3de0: 65 20 6d 6f 64 75 6c 65 20 78 43 6c 6f 73 65 20  e module xClose 
3df0: 6d 65 74 68 6f 64 2e 0a 2a 2f 0a 73 74 61 74 69  method..*/.stati
3e00: 63 20 69 6e 74 20 65 63 68 6f 43 6c 6f 73 65 28  c int echoClose(
3e10: 73 71 6c 69 74 65 33 5f 76 74 61 62 5f 63 75 72  sqlite3_vtab_cur
3e20: 73 6f 72 20 2a 63 75 72 29 7b 0a 20 20 69 6e 74  sor *cur){.  int
3e30: 20 72 63 3b 0a 20 20 65 63 68 6f 5f 63 75 72 73   rc;.  echo_curs
3e40: 6f 72 20 2a 70 43 75 72 20 3d 20 28 65 63 68 6f  or *pCur = (echo
3e50: 5f 63 75 72 73 6f 72 20 2a 29 63 75 72 3b 0a 20  _cursor *)cur;. 
3e60: 20 73 71 6c 69 74 65 33 5f 73 74 6d 74 20 2a 70   sqlite3_stmt *p
3e70: 53 74 6d 74 20 3d 20 70 43 75 72 2d 3e 70 53 74  Stmt = pCur->pSt
3e80: 6d 74 3b 0a 20 20 70 43 75 72 2d 3e 70 53 74 6d  mt;.  pCur->pStm
3e90: 74 20 3d 20 30 3b 0a 20 20 73 71 6c 69 74 65 33  t = 0;.  sqlite3
3ea0: 5f 66 72 65 65 28 70 43 75 72 29 3b 0a 20 20 72  _free(pCur);.  r
3eb0: 63 20 3d 20 73 71 6c 69 74 65 33 5f 66 69 6e 61  c = sqlite3_fina
3ec0: 6c 69 7a 65 28 70 53 74 6d 74 29 3b 0a 20 20 72  lize(pStmt);.  r
3ed0: 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a  eturn rc;.}../*.
3ee0: 2a 2a 20 52 65 74 75 72 6e 20 6e 6f 6e 2d 7a 65  ** Return non-ze
3ef0: 72 6f 20 69 66 20 74 68 65 20 63 75 72 73 6f 72  ro if the cursor
3f00: 20 64 6f 65 73 20 6e 6f 74 20 63 75 72 72 65 6e   does not curren
3f10: 74 6c 79 20 70 6f 69 6e 74 20 74 6f 20 61 20 76  tly point to a v
3f20: 61 6c 69 64 20 72 65 63 6f 72 64 0a 2a 2a 20 28  alid record.** (
3f30: 69 2e 65 20 69 66 20 74 68 65 20 73 63 61 6e 20  i.e if the scan 
3f40: 68 61 73 20 66 69 6e 69 73 68 65 64 29 2c 20 6f  has finished), o
3f50: 72 20 7a 65 72 6f 20 6f 74 68 65 72 77 69 73 65  r zero otherwise
3f60: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
3f70: 65 63 68 6f 45 6f 66 28 73 71 6c 69 74 65 33 5f  echoEof(sqlite3_
3f80: 76 74 61 62 5f 63 75 72 73 6f 72 20 2a 63 75 72  vtab_cursor *cur
3f90: 29 7b 0a 20 20 72 65 74 75 72 6e 20 28 28 28 65  ){.  return (((e
3fa0: 63 68 6f 5f 63 75 72 73 6f 72 20 2a 29 63 75 72  cho_cursor *)cur
3fb0: 29 2d 3e 70 53 74 6d 74 20 3f 20 30 20 3a 20 31  )->pStmt ? 0 : 1
3fc0: 29 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 45 63 68  );.}../* .** Ech
3fd0: 6f 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65 20  o virtual table 
3fe0: 6d 6f 64 75 6c 65 20 78 4e 65 78 74 20 6d 65 74  module xNext met
3ff0: 68 6f 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  hod..*/.static i
4000: 6e 74 20 65 63 68 6f 4e 65 78 74 28 73 71 6c 69  nt echoNext(sqli
4010: 74 65 33 5f 76 74 61 62 5f 63 75 72 73 6f 72 20  te3_vtab_cursor 
4020: 2a 63 75 72 29 7b 0a 20 20 69 6e 74 20 72 63 20  *cur){.  int rc 
4030: 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 65  = SQLITE_OK;.  e
4040: 63 68 6f 5f 63 75 72 73 6f 72 20 2a 70 43 75 72  cho_cursor *pCur
4050: 20 3d 20 28 65 63 68 6f 5f 63 75 72 73 6f 72 20   = (echo_cursor 
4060: 2a 29 63 75 72 3b 0a 0a 20 20 69 66 28 20 73 69  *)cur;..  if( si
4070: 6d 75 6c 61 74 65 56 74 61 62 45 72 72 6f 72 28  mulateVtabError(
4080: 28 65 63 68 6f 5f 76 74 61 62 20 2a 29 28 63 75  (echo_vtab *)(cu
4090: 72 2d 3e 70 56 74 61 62 29 2c 20 22 78 4e 65 78  r->pVtab), "xNex
40a0: 74 22 29 20 29 7b 0a 20 20 20 20 72 65 74 75 72  t") ){.    retur
40b0: 6e 20 53 51 4c 49 54 45 5f 45 52 52 4f 52 3b 0a  n SQLITE_ERROR;.
40c0: 20 20 7d 0a 0a 20 20 69 66 28 20 70 43 75 72 2d    }..  if( pCur-
40d0: 3e 70 53 74 6d 74 20 29 7b 0a 20 20 20 20 72 63  >pStmt ){.    rc
40e0: 20 3d 20 73 71 6c 69 74 65 33 5f 73 74 65 70 28   = sqlite3_step(
40f0: 70 43 75 72 2d 3e 70 53 74 6d 74 29 3b 0a 20 20  pCur->pStmt);.  
4100: 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
4110: 5f 52 4f 57 20 29 7b 0a 20 20 20 20 20 20 72 63  _ROW ){.      rc
4120: 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20   = SQLITE_OK;.  
4130: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 72    }else{.      r
4140: 63 20 3d 20 73 71 6c 69 74 65 33 5f 66 69 6e 61  c = sqlite3_fina
4150: 6c 69 7a 65 28 70 43 75 72 2d 3e 70 53 74 6d 74  lize(pCur->pStmt
4160: 29 3b 0a 20 20 20 20 20 20 70 43 75 72 2d 3e 70  );.      pCur->p
4170: 53 74 6d 74 20 3d 20 30 3b 0a 20 20 20 20 7d 0a  Stmt = 0;.    }.
4180: 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 72 63    }..  return rc
4190: 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 45 63 68 6f  ;.}../* .** Echo
41a0: 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65 20 6d   virtual table m
41b0: 6f 64 75 6c 65 20 78 43 6f 6c 75 6d 6e 20 6d 65  odule xColumn me
41c0: 74 68 6f 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  thod..*/.static 
41d0: 69 6e 74 20 65 63 68 6f 43 6f 6c 75 6d 6e 28 73  int echoColumn(s
41e0: 71 6c 69 74 65 33 5f 76 74 61 62 5f 63 75 72 73  qlite3_vtab_curs
41f0: 6f 72 20 2a 63 75 72 2c 20 73 71 6c 69 74 65 33  or *cur, sqlite3
4200: 5f 63 6f 6e 74 65 78 74 20 2a 63 74 78 2c 20 69  _context *ctx, i
4210: 6e 74 20 69 29 7b 0a 20 20 69 6e 74 20 69 43 6f  nt i){.  int iCo
4220: 6c 20 3d 20 69 20 2b 20 31 3b 0a 20 20 73 71 6c  l = i + 1;.  sql
4230: 69 74 65 33 5f 73 74 6d 74 20 2a 70 53 74 6d 74  ite3_stmt *pStmt
4240: 20 3d 20 28 28 65 63 68 6f 5f 63 75 72 73 6f 72   = ((echo_cursor
4250: 20 2a 29 63 75 72 29 2d 3e 70 53 74 6d 74 3b 0a   *)cur)->pStmt;.
4260: 0a 20 20 69 66 28 20 73 69 6d 75 6c 61 74 65 56  .  if( simulateV
4270: 74 61 62 45 72 72 6f 72 28 28 65 63 68 6f 5f 76  tabError((echo_v
4280: 74 61 62 20 2a 29 28 63 75 72 2d 3e 70 56 74 61  tab *)(cur->pVta
4290: 62 29 2c 20 22 78 43 6f 6c 75 6d 6e 22 29 20 29  b), "xColumn") )
42a0: 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c  {.    return SQL
42b0: 49 54 45 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a 0a  ITE_ERROR;.  }..
42c0: 20 20 69 66 28 20 21 70 53 74 6d 74 20 29 7b 0a    if( !pStmt ){.
42d0: 20 20 20 20 73 71 6c 69 74 65 33 5f 72 65 73 75      sqlite3_resu
42e0: 6c 74 5f 6e 75 6c 6c 28 63 74 78 29 3b 0a 20 20  lt_null(ctx);.  
42f0: 7d 65 6c 73 65 7b 0a 20 20 20 20 61 73 73 65 72  }else{.    asser
4300: 74 28 20 73 71 6c 69 74 65 33 5f 64 61 74 61 5f  t( sqlite3_data_
4310: 63 6f 75 6e 74 28 70 53 74 6d 74 29 3e 69 43 6f  count(pStmt)>iCo
4320: 6c 20 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33  l );.    sqlite3
4330: 5f 72 65 73 75 6c 74 5f 76 61 6c 75 65 28 63 74  _result_value(ct
4340: 78 2c 20 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d  x, sqlite3_colum
4350: 6e 5f 76 61 6c 75 65 28 70 53 74 6d 74 2c 20 69  n_value(pStmt, i
4360: 43 6f 6c 29 29 3b 0a 20 20 7d 0a 20 20 72 65 74  Col));.  }.  ret
4370: 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d  urn SQLITE_OK;.}
4380: 0a 0a 2f 2a 20 0a 2a 2a 20 45 63 68 6f 20 76 69  ../* .** Echo vi
4390: 72 74 75 61 6c 20 74 61 62 6c 65 20 6d 6f 64 75  rtual table modu
43a0: 6c 65 20 78 52 6f 77 69 64 20 6d 65 74 68 6f 64  le xRowid method
43b0: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
43c0: 65 63 68 6f 52 6f 77 69 64 28 73 71 6c 69 74 65  echoRowid(sqlite
43d0: 33 5f 76 74 61 62 5f 63 75 72 73 6f 72 20 2a 63  3_vtab_cursor *c
43e0: 75 72 2c 20 73 71 6c 69 74 65 5f 69 6e 74 36 34  ur, sqlite_int64
43f0: 20 2a 70 52 6f 77 69 64 29 7b 0a 20 20 73 71 6c   *pRowid){.  sql
4400: 69 74 65 33 5f 73 74 6d 74 20 2a 70 53 74 6d 74  ite3_stmt *pStmt
4410: 20 3d 20 28 28 65 63 68 6f 5f 63 75 72 73 6f 72   = ((echo_cursor
4420: 20 2a 29 63 75 72 29 2d 3e 70 53 74 6d 74 3b 0a   *)cur)->pStmt;.
4430: 0a 20 20 69 66 28 20 73 69 6d 75 6c 61 74 65 56  .  if( simulateV
4440: 74 61 62 45 72 72 6f 72 28 28 65 63 68 6f 5f 76  tabError((echo_v
4450: 74 61 62 20 2a 29 28 63 75 72 2d 3e 70 56 74 61  tab *)(cur->pVta
4460: 62 29 2c 20 22 78 52 6f 77 69 64 22 29 20 29 7b  b), "xRowid") ){
4470: 0a 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49  .    return SQLI
4480: 54 45 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a 0a 20  TE_ERROR;.  }.. 
4490: 20 2a 70 52 6f 77 69 64 20 3d 20 73 71 6c 69 74   *pRowid = sqlit
44a0: 65 33 5f 63 6f 6c 75 6d 6e 5f 69 6e 74 36 34 28  e3_column_int64(
44b0: 70 53 74 6d 74 2c 20 30 29 3b 0a 20 20 72 65 74  pStmt, 0);.  ret
44c0: 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d  urn SQLITE_OK;.}
44d0: 0a 0a 2f 2a 0a 2a 2a 20 43 6f 6d 70 75 74 65 20  ../*.** Compute 
44e0: 61 20 73 69 6d 70 6c 65 20 68 61 73 68 20 6f 66  a simple hash of
44f0: 20 74 68 65 20 6e 75 6c 6c 20 74 65 72 6d 69 6e   the null termin
4500: 61 74 65 64 20 73 74 72 69 6e 67 20 7a 53 74 72  ated string zStr
4510: 69 6e 67 2e 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20  ing..**.** This 
4520: 6d 6f 64 75 6c 65 20 75 73 65 73 20 6f 6e 6c 79  module uses only
4530: 20 73 71 6c 69 74 65 33 5f 69 6e 64 65 78 5f 69   sqlite3_index_i
4540: 6e 66 6f 2e 69 64 78 53 74 72 2c 20 6e 6f 74 20  nfo.idxStr, not 
4550: 0a 2a 2a 20 73 71 6c 69 74 65 33 5f 69 6e 64 65  .** sqlite3_inde
4560: 78 5f 69 6e 66 6f 2e 69 64 78 4e 75 6d 2e 20 53  x_info.idxNum. S
4570: 6f 20 74 6f 20 74 65 73 74 20 69 64 78 4e 75 6d  o to test idxNum
4580: 2c 20 77 68 65 6e 20 69 64 78 53 74 72 20 69 73  , when idxStr is
4590: 20 73 65 74 0a 2a 2a 20 69 6e 20 65 63 68 6f 42   set.** in echoB
45a0: 65 73 74 49 6e 64 65 78 28 29 2c 20 69 64 78 4e  estIndex(), idxN
45b0: 75 6d 20 69 73 20 73 65 74 20 74 6f 20 74 68 65  um is set to the
45c0: 20 63 6f 72 72 65 73 70 6f 6e 64 69 6e 67 20 68   corresponding h
45d0: 61 73 68 20 76 61 6c 75 65 2e 0a 2a 2a 20 49 6e  ash value..** In
45e0: 20 65 63 68 6f 46 69 6c 74 65 72 28 29 2c 20 63   echoFilter(), c
45f0: 6f 64 65 20 61 73 73 65 72 74 28 29 73 20 74 68  ode assert()s th
4600: 61 74 20 74 68 65 20 73 75 70 70 6c 69 65 64 20  at the supplied 
4610: 69 64 78 4e 75 6d 20 76 61 6c 75 65 20 69 73 0a  idxNum value is.
4620: 2a 2a 20 69 6e 64 65 65 64 20 74 68 65 20 68 61  ** indeed the ha
4630: 73 68 20 6f 66 20 74 68 65 20 73 75 70 70 6c 69  sh of the suppli
4640: 65 64 20 69 64 78 53 74 72 2e 0a 2a 2f 0a 73 74  ed idxStr..*/.st
4650: 61 74 69 63 20 69 6e 74 20 68 61 73 68 53 74 72  atic int hashStr
4660: 69 6e 67 28 63 6f 6e 73 74 20 63 68 61 72 20 2a  ing(const char *
4670: 7a 53 74 72 69 6e 67 29 7b 0a 20 20 69 6e 74 20  zString){.  int 
4680: 76 61 6c 20 3d 20 30 3b 0a 20 20 69 6e 74 20 69  val = 0;.  int i
4690: 69 3b 0a 20 20 66 6f 72 28 69 69 3d 30 3b 20 7a  i;.  for(ii=0; z
46a0: 53 74 72 69 6e 67 5b 69 69 5d 3b 20 69 69 2b 2b  String[ii]; ii++
46b0: 29 7b 0a 20 20 20 20 76 61 6c 20 3d 20 28 76 61  ){.    val = (va
46c0: 6c 20 3c 3c 20 33 29 20 2b 20 28 69 6e 74 29 7a  l << 3) + (int)z
46d0: 53 74 72 69 6e 67 5b 69 69 5d 3b 0a 20 20 7d 0a  String[ii];.  }.
46e0: 20 20 72 65 74 75 72 6e 20 76 61 6c 3b 0a 7d 0a    return val;.}.
46f0: 0a 2f 2a 20 0a 2a 2a 20 45 63 68 6f 20 76 69 72  ./* .** Echo vir
4700: 74 75 61 6c 20 74 61 62 6c 65 20 6d 6f 64 75 6c  tual table modul
4710: 65 20 78 46 69 6c 74 65 72 20 6d 65 74 68 6f 64  e xFilter method
4720: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
4730: 65 63 68 6f 46 69 6c 74 65 72 28 0a 20 20 73 71  echoFilter(.  sq
4740: 6c 69 74 65 33 5f 76 74 61 62 5f 63 75 72 73 6f  lite3_vtab_curso
4750: 72 20 2a 70 56 74 61 62 43 75 72 73 6f 72 2c 20  r *pVtabCursor, 
4760: 0a 20 20 69 6e 74 20 69 64 78 4e 75 6d 2c 20 63  .  int idxNum, c
4770: 6f 6e 73 74 20 63 68 61 72 20 2a 69 64 78 53 74  onst char *idxSt
4780: 72 2c 0a 20 20 69 6e 74 20 61 72 67 63 2c 20 73  r,.  int argc, s
4790: 71 6c 69 74 65 33 5f 76 61 6c 75 65 20 2a 2a 61  qlite3_value **a
47a0: 72 67 76 0a 29 7b 0a 20 20 69 6e 74 20 72 63 3b  rgv.){.  int rc;
47b0: 0a 20 20 69 6e 74 20 69 3b 0a 0a 20 20 65 63 68  .  int i;..  ech
47c0: 6f 5f 63 75 72 73 6f 72 20 2a 70 43 75 72 20 3d  o_cursor *pCur =
47d0: 20 28 65 63 68 6f 5f 63 75 72 73 6f 72 20 2a 29   (echo_cursor *)
47e0: 70 56 74 61 62 43 75 72 73 6f 72 3b 0a 20 20 65  pVtabCursor;.  e
47f0: 63 68 6f 5f 76 74 61 62 20 2a 70 56 74 61 62 20  cho_vtab *pVtab 
4800: 3d 20 28 65 63 68 6f 5f 76 74 61 62 20 2a 29 70  = (echo_vtab *)p
4810: 56 74 61 62 43 75 72 73 6f 72 2d 3e 70 56 74 61  VtabCursor->pVta
4820: 62 3b 0a 20 20 73 71 6c 69 74 65 33 20 2a 64 62  b;.  sqlite3 *db
4830: 20 3d 20 70 56 74 61 62 2d 3e 64 62 3b 0a 0a 20   = pVtab->db;.. 
4840: 20 69 66 28 20 73 69 6d 75 6c 61 74 65 56 74 61   if( simulateVta
4850: 62 45 72 72 6f 72 28 70 56 74 61 62 2c 20 22 78  bError(pVtab, "x
4860: 46 69 6c 74 65 72 22 29 20 29 7b 0a 20 20 20 20  Filter") ){.    
4870: 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 45 52  return SQLITE_ER
4880: 52 4f 52 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 43  ROR;.  }..  /* C
4890: 68 65 63 6b 20 74 68 61 74 20 69 64 78 4e 75 6d  heck that idxNum
48a0: 20 6d 61 74 63 68 65 73 20 69 64 78 53 74 72 20   matches idxStr 
48b0: 2a 2f 0a 20 20 61 73 73 65 72 74 28 20 69 64 78  */.  assert( idx
48c0: 4e 75 6d 3d 3d 68 61 73 68 53 74 72 69 6e 67 28  Num==hashString(
48d0: 69 64 78 53 74 72 29 20 29 3b 0a 0a 20 20 2f 2a  idxStr) );..  /*
48e0: 20 4c 6f 67 20 61 72 67 75 6d 65 6e 74 73 20 74   Log arguments t
48f0: 6f 20 74 68 65 20 3a 3a 65 63 68 6f 5f 6d 6f 64  o the ::echo_mod
4900: 75 6c 65 20 54 63 6c 20 76 61 72 69 61 62 6c 65  ule Tcl variable
4910: 20 2a 2f 0a 20 20 61 70 70 65 6e 64 54 6f 45 63   */.  appendToEc
4920: 68 6f 4d 6f 64 75 6c 65 28 70 56 74 61 62 2d 3e  hoModule(pVtab->
4930: 69 6e 74 65 72 70 2c 20 22 78 46 69 6c 74 65 72  interp, "xFilter
4940: 22 29 3b 0a 20 20 61 70 70 65 6e 64 54 6f 45 63  ");.  appendToEc
4950: 68 6f 4d 6f 64 75 6c 65 28 70 56 74 61 62 2d 3e  hoModule(pVtab->
4960: 69 6e 74 65 72 70 2c 20 69 64 78 53 74 72 29 3b  interp, idxStr);
4970: 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 61 72  .  for(i=0; i<ar
4980: 67 63 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 61 70  gc; i++){.    ap
4990: 70 65 6e 64 54 6f 45 63 68 6f 4d 6f 64 75 6c 65  pendToEchoModule
49a0: 28 70 56 74 61 62 2d 3e 69 6e 74 65 72 70 2c 20  (pVtab->interp, 
49b0: 28 63 6f 6e 73 74 20 63 68 61 72 2a 29 73 71 6c  (const char*)sql
49c0: 69 74 65 33 5f 76 61 6c 75 65 5f 74 65 78 74 28  ite3_value_text(
49d0: 61 72 67 76 5b 69 5d 29 29 3b 0a 20 20 7d 0a 0a  argv[i]));.  }..
49e0: 20 20 73 71 6c 69 74 65 33 5f 66 69 6e 61 6c 69    sqlite3_finali
49f0: 7a 65 28 70 43 75 72 2d 3e 70 53 74 6d 74 29 3b  ze(pCur->pStmt);
4a00: 0a 20 20 70 43 75 72 2d 3e 70 53 74 6d 74 20 3d  .  pCur->pStmt =
4a10: 20 30 3b 0a 0a 20 20 2f 2a 20 50 72 65 70 61 72   0;..  /* Prepar
4a20: 65 20 74 68 65 20 53 51 4c 20 73 74 61 74 65 6d  e the SQL statem
4a30: 65 6e 74 20 63 72 65 61 74 65 64 20 62 79 20 65  ent created by e
4a40: 63 68 6f 42 65 73 74 49 6e 64 65 78 20 61 6e 64  choBestIndex and
4a50: 20 62 69 6e 64 20 74 68 65 0a 20 20 2a 2a 20 72   bind the.  ** r
4a60: 75 6e 74 69 6d 65 20 70 61 72 61 6d 65 74 65 72  untime parameter
4a70: 73 20 70 61 73 73 65 64 20 74 6f 20 74 68 69 73  s passed to this
4a80: 20 66 75 6e 63 74 69 6f 6e 20 74 6f 20 69 74 2e   function to it.
4a90: 0a 20 20 2a 2f 0a 20 20 72 63 20 3d 20 73 71 6c  .  */.  rc = sql
4aa0: 69 74 65 33 5f 70 72 65 70 61 72 65 28 64 62 2c  ite3_prepare(db,
4ab0: 20 69 64 78 53 74 72 2c 20 2d 31 2c 20 26 70 43   idxStr, -1, &pC
4ac0: 75 72 2d 3e 70 53 74 6d 74 2c 20 30 29 3b 0a 20  ur->pStmt, 0);. 
4ad0: 20 61 73 73 65 72 74 28 20 70 43 75 72 2d 3e 70   assert( pCur->p
4ae0: 53 74 6d 74 20 7c 7c 20 72 63 21 3d 53 51 4c 49  Stmt || rc!=SQLI
4af0: 54 45 5f 4f 4b 20 29 3b 0a 20 20 66 6f 72 28 69  TE_OK );.  for(i
4b00: 3d 30 3b 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  =0; rc==SQLITE_O
4b10: 4b 20 26 26 20 69 3c 61 72 67 63 3b 20 69 2b 2b  K && i<argc; i++
4b20: 29 7b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 62  ){.    sqlite3_b
4b30: 69 6e 64 5f 76 61 6c 75 65 28 70 43 75 72 2d 3e  ind_value(pCur->
4b40: 70 53 74 6d 74 2c 20 69 2b 31 2c 20 61 72 67 76  pStmt, i+1, argv
4b50: 5b 69 5d 29 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20  [i]);.  }..  /* 
4b60: 49 66 20 65 76 65 72 79 74 68 69 6e 67 20 77 61  If everything wa
4b70: 73 20 73 75 63 63 65 73 73 66 75 6c 2c 20 61 64  s successful, ad
4b80: 76 61 6e 63 65 20 74 6f 20 74 68 65 20 66 69 72  vance to the fir
4b90: 73 74 20 72 6f 77 20 6f 66 20 74 68 65 20 73 63  st row of the sc
4ba0: 61 6e 20 2a 2f 0a 20 20 69 66 28 20 72 63 3d 3d  an */.  if( rc==
4bb0: 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20  SQLITE_OK ){.   
4bc0: 20 72 63 20 3d 20 65 63 68 6f 4e 65 78 74 28 70   rc = echoNext(p
4bd0: 56 74 61 62 43 75 72 73 6f 72 29 3b 0a 20 20 7d  VtabCursor);.  }
4be0: 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d  ..  return rc;.}
4bf0: 0a 0a 0a 2f 2a 0a 2a 2a 20 41 20 68 65 6c 70 65  .../*.** A helpe
4c00: 72 20 66 75 6e 63 74 69 6f 6e 20 75 73 65 64 20  r function used 
4c10: 62 79 20 65 63 68 6f 55 70 64 61 74 65 28 29 20  by echoUpdate() 
4c20: 61 6e 64 20 65 63 68 6f 42 65 73 74 49 6e 64 65  and echoBestInde
4c30: 78 28 29 20 66 6f 72 0a 2a 2a 20 6d 61 6e 69 70  x() for.** manip
4c40: 75 6c 61 74 69 6e 67 20 73 74 72 69 6e 67 73 20  ulating strings 
4c50: 69 6e 20 63 6f 6e 63 65 72 74 20 77 69 74 68 20  in concert with 
4c60: 74 68 65 20 73 71 6c 69 74 65 33 5f 6d 70 72 69  the sqlite3_mpri
4c70: 6e 74 66 28 29 20 66 75 6e 63 74 69 6f 6e 2e 0a  ntf() function..
4c80: 2a 2a 0a 2a 2a 20 50 61 72 61 6d 65 74 65 72 20  **.** Parameter 
4c90: 70 7a 53 74 72 20 70 6f 69 6e 74 73 20 74 6f 20  pzStr points to 
4ca0: 61 20 70 6f 69 6e 74 65 72 20 74 6f 20 61 20 73  a pointer to a s
4cb0: 74 72 69 6e 67 20 61 6c 6c 6f 63 61 74 65 64 20  tring allocated 
4cc0: 77 69 74 68 0a 2a 2a 20 73 71 6c 69 74 65 33 5f  with.** sqlite3_
4cd0: 6d 70 72 69 6e 74 66 2e 20 54 68 65 20 73 65 63  mprintf. The sec
4ce0: 6f 6e 64 20 70 61 72 61 6d 65 74 65 72 2c 20 7a  ond parameter, z
4cf0: 41 70 70 65 6e 64 2c 20 70 6f 69 6e 74 73 20 74  Append, points t
4d00: 6f 20 61 6e 6f 74 68 65 72 0a 2a 2a 20 73 74 72  o another.** str
4d10: 69 6e 67 2e 20 54 68 65 20 74 77 6f 20 73 74 72  ing. The two str
4d20: 69 6e 67 73 20 61 72 65 20 63 6f 6e 63 61 74 65  ings are concate
4d30: 6e 61 74 65 64 20 74 6f 67 65 74 68 65 72 20 61  nated together a
4d40: 6e 64 20 2a 70 7a 53 74 72 0a 2a 2a 20 73 65 74  nd *pzStr.** set
4d50: 20 74 6f 20 70 6f 69 6e 74 20 61 74 20 74 68 65   to point at the
4d60: 20 72 65 73 75 6c 74 2e 20 54 68 65 20 69 6e 69   result. The ini
4d70: 74 69 61 6c 20 62 75 66 66 65 72 20 70 6f 69 6e  tial buffer poin
4d80: 74 65 64 20 74 6f 20 62 79 20 2a 70 7a 53 74 72  ted to by *pzStr
4d90: 0a 2a 2a 20 69 73 20 64 65 61 6c 6c 6f 63 61 74  .** is deallocat
4da0: 65 64 20 76 69 61 20 73 71 6c 69 74 65 33 5f 66  ed via sqlite3_f
4db0: 72 65 65 28 29 2e 0a 2a 2a 0a 2a 2a 20 49 66 20  ree()..**.** If 
4dc0: 74 68 65 20 74 68 69 72 64 20 61 72 67 75 6d 65  the third argume
4dd0: 6e 74 2c 20 64 6f 46 72 65 65 2c 20 69 73 20 74  nt, doFree, is t
4de0: 72 75 65 2c 20 74 68 65 6e 20 73 71 6c 69 74 65  rue, then sqlite
4df0: 33 5f 66 72 65 65 28 29 20 69 73 0a 2a 2a 20 61  3_free() is.** a
4e00: 6c 73 6f 20 63 61 6c 6c 65 64 20 74 6f 20 66 72  lso called to fr
4e10: 65 65 20 74 68 65 20 62 75 66 66 65 72 20 70 6f  ee the buffer po
4e20: 69 6e 74 65 64 20 74 6f 20 62 79 20 7a 41 70 70  inted to by zApp
4e30: 65 6e 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76  end..*/.static v
4e40: 6f 69 64 20 73 74 72 69 6e 67 5f 63 6f 6e 63 61  oid string_conca
4e50: 74 28 63 68 61 72 20 2a 2a 70 7a 53 74 72 2c 20  t(char **pzStr, 
4e60: 63 68 61 72 20 2a 7a 41 70 70 65 6e 64 2c 20 69  char *zAppend, i
4e70: 6e 74 20 64 6f 46 72 65 65 2c 20 69 6e 74 20 2a  nt doFree, int *
4e80: 70 52 63 29 7b 0a 20 20 63 68 61 72 20 2a 7a 49  pRc){.  char *zI
4e90: 6e 20 3d 20 2a 70 7a 53 74 72 3b 0a 20 20 69 66  n = *pzStr;.  if
4ea0: 28 20 21 7a 41 70 70 65 6e 64 20 26 26 20 64 6f  ( !zAppend && do
4eb0: 46 72 65 65 20 26 26 20 2a 70 52 63 3d 3d 53 51  Free && *pRc==SQ
4ec0: 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 2a  LITE_OK ){.    *
4ed0: 70 52 63 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d  pRc = SQLITE_NOM
4ee0: 45 4d 3b 0a 20 20 7d 0a 20 20 69 66 28 20 2a 70  EM;.  }.  if( *p
4ef0: 52 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  Rc!=SQLITE_OK ){
4f00: 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65  .    sqlite3_fre
4f10: 65 28 7a 49 6e 29 3b 0a 20 20 20 20 7a 49 6e 20  e(zIn);.    zIn 
4f20: 3d 20 30 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20  = 0;.  }else{.  
4f30: 20 20 69 66 28 20 7a 49 6e 20 29 7b 0a 20 20 20    if( zIn ){.   
4f40: 20 20 20 63 68 61 72 20 2a 7a 54 65 6d 70 20 3d     char *zTemp =
4f50: 20 7a 49 6e 3b 0a 20 20 20 20 20 20 7a 49 6e 20   zIn;.      zIn 
4f60: 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74  = sqlite3_mprint
4f70: 66 28 22 25 73 25 73 22 2c 20 7a 49 6e 2c 20 7a  f("%s%s", zIn, z
4f80: 41 70 70 65 6e 64 29 3b 0a 20 20 20 20 20 20 73  Append);.      s
4f90: 71 6c 69 74 65 33 5f 66 72 65 65 28 7a 54 65 6d  qlite3_free(zTem
4fa0: 70 29 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20  p);.    }else{. 
4fb0: 20 20 20 20 20 7a 49 6e 20 3d 20 73 71 6c 69 74       zIn = sqlit
4fc0: 65 33 5f 6d 70 72 69 6e 74 66 28 22 25 73 22 2c  e3_mprintf("%s",
4fd0: 20 7a 41 70 70 65 6e 64 29 3b 0a 20 20 20 20 7d   zAppend);.    }
4fe0: 0a 20 20 20 20 69 66 28 20 21 7a 49 6e 20 29 7b  .    if( !zIn ){
4ff0: 0a 20 20 20 20 20 20 2a 70 52 63 20 3d 20 53 51  .      *pRc = SQ
5000: 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20  LITE_NOMEM;.    
5010: 7d 0a 20 20 7d 0a 20 20 2a 70 7a 53 74 72 20 3d  }.  }.  *pzStr =
5020: 20 7a 49 6e 3b 0a 20 20 69 66 28 20 64 6f 46 72   zIn;.  if( doFr
5030: 65 65 20 29 7b 0a 20 20 20 20 73 71 6c 69 74 65  ee ){.    sqlite
5040: 33 5f 66 72 65 65 28 7a 41 70 70 65 6e 64 29 3b  3_free(zAppend);
5050: 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68  .  }.}../*.** Th
5060: 65 20 65 63 68 6f 20 6d 6f 64 75 6c 65 20 69 6d  e echo module im
5070: 70 6c 65 6d 65 6e 74 73 20 74 68 65 20 73 75 62  plements the sub
5080: 73 65 74 20 6f 66 20 71 75 65 72 79 20 63 6f 6e  set of query con
5090: 73 74 72 61 69 6e 74 73 20 61 6e 64 20 73 6f 72  straints and sor
50a0: 74 0a 2a 2a 20 6f 72 64 65 72 73 20 74 68 61 74  t.** orders that
50b0: 20 6d 61 79 20 74 61 6b 65 20 61 64 76 61 6e 74   may take advant
50c0: 61 67 65 20 6f 66 20 53 51 4c 69 74 65 20 69 6e  age of SQLite in
50d0: 64 69 63 65 73 20 6f 6e 20 74 68 65 20 75 6e 64  dices on the und
50e0: 65 72 6c 79 69 6e 67 0a 2a 2a 20 72 65 61 6c 20  erlying.** real 
50f0: 74 61 62 6c 65 2e 20 46 6f 72 20 65 78 61 6d 70  table. For examp
5100: 6c 65 2c 20 69 66 20 74 68 65 20 72 65 61 6c 20  le, if the real 
5110: 74 61 62 6c 65 20 69 73 20 64 65 63 6c 61 72 65  table is declare
5120: 64 20 61 73 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20  d as:.**.**     
5130: 43 52 45 41 54 45 20 54 41 42 4c 45 20 72 65 61  CREATE TABLE rea
5140: 6c 28 61 2c 20 62 2c 20 63 29 3b 0a 2a 2a 20 20  l(a, b, c);.**  
5150: 20 20 20 43 52 45 41 54 45 20 49 4e 44 45 58 20     CREATE INDEX 
5160: 72 65 61 6c 5f 69 6e 64 65 78 20 4f 4e 20 72 65  real_index ON re
5170: 61 6c 28 62 29 3b 0a 2a 2a 0a 2a 2a 20 74 68 65  al(b);.**.** the
5180: 6e 20 74 68 65 20 65 63 68 6f 20 6d 6f 64 75 6c  n the echo modul
5190: 65 20 68 61 6e 64 6c 65 73 20 57 48 45 52 45 20  e handles WHERE 
51a0: 6f 72 20 4f 52 44 45 52 20 42 59 20 63 6c 61 75  or ORDER BY clau
51b0: 73 65 73 20 74 68 61 74 20 72 65 66 65 72 0a 2a  ses that refer.*
51c0: 2a 20 74 6f 20 74 68 65 20 63 6f 6c 75 6d 6e 20  * to the column 
51d0: 22 62 22 2c 20 62 75 74 20 6e 6f 74 20 22 61 22  "b", but not "a"
51e0: 20 6f 72 20 22 63 22 2e 20 49 66 20 61 20 6d 75   or "c". If a mu
51f0: 6c 74 69 2d 63 6f 6c 75 6d 6e 20 69 6e 64 65 78  lti-column index
5200: 20 69 73 0a 2a 2a 20 70 72 65 73 65 6e 74 2c 20   is.** present, 
5210: 6f 6e 6c 79 20 69 74 73 20 6c 65 66 74 20 6d 6f  only its left mo
5220: 73 74 20 63 6f 6c 75 6d 6e 20 69 73 20 63 6f 6e  st column is con
5230: 73 69 64 65 72 65 64 2e 20 0a 2a 2a 0a 2a 2a 20  sidered. .**.** 
5240: 54 68 69 73 20 78 42 65 73 74 49 6e 64 65 78 20  This xBestIndex 
5250: 6d 65 74 68 6f 64 20 65 6e 63 6f 64 65 73 20 74  method encodes t
5260: 68 65 20 70 72 6f 70 6f 73 65 64 20 73 65 61 72  he proposed sear
5270: 63 68 20 73 74 72 61 74 65 67 79 20 61 73 0a 2a  ch strategy as.*
5280: 2a 20 61 6e 20 53 51 4c 20 71 75 65 72 79 20 6f  * an SQL query o
5290: 6e 20 74 68 65 20 72 65 61 6c 20 74 61 62 6c 65  n the real table
52a0: 20 75 6e 64 65 72 6c 79 69 6e 67 20 74 68 65 20   underlying the 
52b0: 76 69 72 74 75 61 6c 20 65 63 68 6f 20 6d 6f 64  virtual echo mod
52c0: 75 6c 65 20 0a 2a 2a 20 74 61 62 6c 65 20 61 6e  ule .** table an
52d0: 64 20 73 74 6f 72 65 73 20 74 68 65 20 71 75 65  d stores the que
52e0: 72 79 20 69 6e 20 73 71 6c 69 74 65 33 5f 69 6e  ry in sqlite3_in
52f0: 64 65 78 5f 69 6e 66 6f 2e 69 64 78 53 74 72 2e  dex_info.idxStr.
5300: 20 54 68 65 20 53 51 4c 0a 2a 2a 20 73 74 61 74   The SQL.** stat
5310: 65 6d 65 6e 74 20 69 73 20 6f 66 20 74 68 65 20  ement is of the 
5320: 66 6f 72 6d 3a 0a 2a 2a 0a 2a 2a 20 20 20 53 45  form:.**.**   SE
5330: 4c 45 43 54 20 72 6f 77 69 64 2c 20 2a 20 46 52  LECT rowid, * FR
5340: 4f 4d 20 3c 72 65 61 6c 2d 74 61 62 6c 65 3e 20  OM <real-table> 
5350: 3f 3c 77 68 65 72 65 2d 63 6c 61 75 73 65 3e 3f  ?<where-clause>?
5360: 20 3f 3c 6f 72 64 65 72 2d 62 79 2d 63 6c 61 75   ?<order-by-clau
5370: 73 65 3e 3f 0a 2a 2a 0a 2a 2a 20 77 68 65 72 65  se>?.**.** where
5380: 20 74 68 65 20 3c 77 68 65 72 65 2d 63 6c 61 75   the <where-clau
5390: 73 65 3e 20 61 6e 64 20 3c 6f 72 64 65 72 2d 62  se> and <order-b
53a0: 79 2d 63 6c 61 75 73 65 3e 20 61 72 65 20 64 65  y-clause> are de
53b0: 74 65 72 6d 69 6e 65 64 0a 2a 2a 20 62 79 20 74  termined.** by t
53c0: 68 65 20 63 6f 6e 74 65 6e 74 73 20 6f 66 20 74  he contents of t
53d0: 68 65 20 73 74 72 75 63 74 75 72 65 20 70 6f 69  he structure poi
53e0: 6e 74 65 64 20 74 6f 20 62 79 20 74 68 65 20 70  nted to by the p
53f0: 49 64 78 49 6e 66 6f 20 61 72 67 75 6d 65 6e 74  IdxInfo argument
5400: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
5410: 65 63 68 6f 42 65 73 74 49 6e 64 65 78 28 73 71  echoBestIndex(sq
5420: 6c 69 74 65 33 5f 76 74 61 62 20 2a 74 61 62 2c  lite3_vtab *tab,
5430: 20 73 71 6c 69 74 65 33 5f 69 6e 64 65 78 5f 69   sqlite3_index_i
5440: 6e 66 6f 20 2a 70 49 64 78 49 6e 66 6f 29 7b 0a  nfo *pIdxInfo){.
5450: 20 20 69 6e 74 20 69 69 3b 0a 20 20 63 68 61 72    int ii;.  char
5460: 20 2a 7a 51 75 65 72 79 20 3d 20 30 3b 0a 20 20   *zQuery = 0;.  
5470: 63 68 61 72 20 2a 7a 4e 65 77 3b 0a 20 20 69 6e  char *zNew;.  in
5480: 74 20 6e 41 72 67 20 3d 20 30 3b 0a 20 20 63 6f  t nArg = 0;.  co
5490: 6e 73 74 20 63 68 61 72 20 2a 7a 53 65 70 20 3d  nst char *zSep =
54a0: 20 22 57 48 45 52 45 22 3b 0a 20 20 65 63 68 6f   "WHERE";.  echo
54b0: 5f 76 74 61 62 20 2a 70 56 74 61 62 20 3d 20 28  _vtab *pVtab = (
54c0: 65 63 68 6f 5f 76 74 61 62 20 2a 29 74 61 62 3b  echo_vtab *)tab;
54d0: 0a 20 20 73 71 6c 69 74 65 33 5f 73 74 6d 74 20  .  sqlite3_stmt 
54e0: 2a 70 53 74 6d 74 20 3d 20 30 3b 0a 20 20 54 63  *pStmt = 0;.  Tc
54f0: 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70  l_Interp *interp
5500: 20 3d 20 70 56 74 61 62 2d 3e 69 6e 74 65 72 70   = pVtab->interp
5510: 3b 0a 0a 20 20 69 6e 74 20 6e 52 6f 77 3b 0a 20  ;..  int nRow;. 
5520: 20 69 6e 74 20 75 73 65 49 64 78 20 3d 20 30 3b   int useIdx = 0;
5530: 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49  .  int rc = SQLI
5540: 54 45 5f 4f 4b 3b 0a 20 20 69 6e 74 20 75 73 65  TE_OK;.  int use
5550: 43 6f 73 74 20 3d 20 30 3b 0a 20 20 64 6f 75 62  Cost = 0;.  doub
5560: 6c 65 20 63 6f 73 74 3b 0a 20 20 69 6e 74 20 69  le cost;.  int i
5570: 73 49 67 6e 6f 72 65 55 73 61 62 6c 65 20 3d 20  sIgnoreUsable = 
5580: 30 3b 0a 20 20 69 66 28 20 54 63 6c 5f 47 65 74  0;.  if( Tcl_Get
5590: 56 61 72 28 69 6e 74 65 72 70 2c 20 22 65 63 68  Var(interp, "ech
55a0: 6f 5f 6d 6f 64 75 6c 65 5f 69 67 6e 6f 72 65 5f  o_module_ignore_
55b0: 75 73 61 62 6c 65 22 2c 20 54 43 4c 5f 47 4c 4f  usable", TCL_GLO
55c0: 42 41 4c 5f 4f 4e 4c 59 29 20 29 7b 0a 20 20 20  BAL_ONLY) ){.   
55d0: 20 69 73 49 67 6e 6f 72 65 55 73 61 62 6c 65 20   isIgnoreUsable 
55e0: 3d 20 31 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20  = 1;.  }..  if( 
55f0: 73 69 6d 75 6c 61 74 65 56 74 61 62 45 72 72 6f  simulateVtabErro
5600: 72 28 70 56 74 61 62 2c 20 22 78 42 65 73 74 49  r(pVtab, "xBestI
5610: 6e 64 65 78 22 29 20 29 7b 0a 20 20 20 20 72 65  ndex") ){.    re
5620: 74 75 72 6e 20 53 51 4c 49 54 45 5f 45 52 52 4f  turn SQLITE_ERRO
5630: 52 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 44 65 74  R;.  }..  /* Det
5640: 65 72 6d 69 6e 65 20 74 68 65 20 6e 75 6d 62 65  ermine the numbe
5650: 72 20 6f 66 20 72 6f 77 73 20 69 6e 20 74 68 65  r of rows in the
5660: 20 74 61 62 6c 65 20 61 6e 64 20 73 74 6f 72 65   table and store
5670: 20 74 68 69 73 20 76 61 6c 75 65 20 69 6e 20 6c   this value in l
5680: 6f 63 61 6c 0a 20 20 2a 2a 20 76 61 72 69 61 62  ocal.  ** variab
5690: 6c 65 20 6e 52 6f 77 2e 20 54 68 65 20 27 65 73  le nRow. The 'es
56a0: 74 69 6d 61 74 65 64 2d 63 6f 73 74 27 20 6f 66  timated-cost' of
56b0: 20 74 68 65 20 73 63 61 6e 20 77 69 6c 6c 20 62   the scan will b
56c0: 65 20 74 68 65 20 6e 75 6d 62 65 72 20 6f 66 0a  e the number of.
56d0: 20 20 2a 2a 20 72 6f 77 73 20 69 6e 20 74 68 65    ** rows in the
56e0: 20 74 61 62 6c 65 20 66 6f 72 20 61 20 6c 69 6e   table for a lin
56f0: 65 61 72 20 73 63 61 6e 2c 20 6f 72 20 74 68 65  ear scan, or the
5700: 20 6c 6f 67 20 28 62 61 73 65 20 32 29 20 6f 66   log (base 2) of
5710: 20 74 68 65 20 0a 20 20 2a 2a 20 6e 75 6d 62 65   the .  ** numbe
5720: 72 20 6f 66 20 72 6f 77 73 20 69 66 20 74 68 65  r of rows if the
5730: 20 70 72 6f 70 6f 73 65 64 20 73 63 61 6e 20 75   proposed scan u
5740: 73 65 73 20 61 6e 20 69 6e 64 65 78 2e 20 20 0a  ses an index.  .
5750: 20 20 2a 2f 0a 20 20 69 66 28 20 54 63 6c 5f 47    */.  if( Tcl_G
5760: 65 74 56 61 72 28 69 6e 74 65 72 70 2c 20 22 65  etVar(interp, "e
5770: 63 68 6f 5f 6d 6f 64 75 6c 65 5f 63 6f 73 74 22  cho_module_cost"
5780: 2c 20 54 43 4c 5f 47 4c 4f 42 41 4c 5f 4f 4e 4c  , TCL_GLOBAL_ONL
5790: 59 29 20 29 7b 0a 20 20 20 20 63 6f 73 74 20 3d  Y) ){.    cost =
57a0: 20 61 74 6f 66 28 54 63 6c 5f 47 65 74 56 61 72   atof(Tcl_GetVar
57b0: 28 69 6e 74 65 72 70 2c 20 22 65 63 68 6f 5f 6d  (interp, "echo_m
57c0: 6f 64 75 6c 65 5f 63 6f 73 74 22 2c 20 54 43 4c  odule_cost", TCL
57d0: 5f 47 4c 4f 42 41 4c 5f 4f 4e 4c 59 29 29 3b 0a  _GLOBAL_ONLY));.
57e0: 20 20 20 20 75 73 65 43 6f 73 74 20 3d 20 31 3b      useCost = 1;
57f0: 0a 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20  .  } else {.    
5800: 7a 51 75 65 72 79 20 3d 20 73 71 6c 69 74 65 33  zQuery = sqlite3
5810: 5f 6d 70 72 69 6e 74 66 28 22 53 45 4c 45 43 54  _mprintf("SELECT
5820: 20 63 6f 75 6e 74 28 2a 29 20 46 52 4f 4d 20 25   count(*) FROM %
5830: 51 22 2c 20 70 56 74 61 62 2d 3e 7a 54 61 62 6c  Q", pVtab->zTabl
5840: 65 4e 61 6d 65 29 3b 0a 20 20 20 20 69 66 28 20  eName);.    if( 
5850: 21 7a 51 75 65 72 79 20 29 7b 0a 20 20 20 20 20  !zQuery ){.     
5860: 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4e   return SQLITE_N
5870: 4f 4d 45 4d 3b 0a 20 20 20 20 7d 0a 20 20 20 20  OMEM;.    }.    
5880: 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 70 72 65  rc = sqlite3_pre
5890: 70 61 72 65 28 70 56 74 61 62 2d 3e 64 62 2c 20  pare(pVtab->db, 
58a0: 7a 51 75 65 72 79 2c 20 2d 31 2c 20 26 70 53 74  zQuery, -1, &pSt
58b0: 6d 74 2c 20 30 29 3b 0a 20 20 20 20 73 71 6c 69  mt, 0);.    sqli
58c0: 74 65 33 5f 66 72 65 65 28 7a 51 75 65 72 79 29  te3_free(zQuery)
58d0: 3b 0a 20 20 20 20 69 66 28 20 72 63 21 3d 53 51  ;.    if( rc!=SQ
58e0: 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20  LITE_OK ){.     
58f0: 20 72 65 74 75 72 6e 20 72 63 3b 0a 20 20 20 20   return rc;.    
5900: 7d 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 73 74  }.    sqlite3_st
5910: 65 70 28 70 53 74 6d 74 29 3b 0a 20 20 20 20 6e  ep(pStmt);.    n
5920: 52 6f 77 20 3d 20 73 71 6c 69 74 65 33 5f 63 6f  Row = sqlite3_co
5930: 6c 75 6d 6e 5f 69 6e 74 28 70 53 74 6d 74 2c 20  lumn_int(pStmt, 
5940: 30 29 3b 0a 20 20 20 20 72 63 20 3d 20 73 71 6c  0);.    rc = sql
5950: 69 74 65 33 5f 66 69 6e 61 6c 69 7a 65 28 70 53  ite3_finalize(pS
5960: 74 6d 74 29 3b 0a 20 20 20 20 69 66 28 20 72 63  tmt);.    if( rc
5970: 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  !=SQLITE_OK ){. 
5980: 20 20 20 20 20 72 65 74 75 72 6e 20 72 63 3b 0a       return rc;.
5990: 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 7a 51 75      }.  }..  zQu
59a0: 65 72 79 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70  ery = sqlite3_mp
59b0: 72 69 6e 74 66 28 22 53 45 4c 45 43 54 20 72 6f  rintf("SELECT ro
59c0: 77 69 64 2c 20 2a 20 46 52 4f 4d 20 25 51 22 2c  wid, * FROM %Q",
59d0: 20 70 56 74 61 62 2d 3e 7a 54 61 62 6c 65 4e 61   pVtab->zTableNa
59e0: 6d 65 29 3b 0a 20 20 69 66 28 20 21 7a 51 75 65  me);.  if( !zQue
59f0: 72 79 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e  ry ){.    return
5a00: 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20   SQLITE_NOMEM;. 
5a10: 20 7d 0a 20 20 66 6f 72 28 69 69 3d 30 3b 20 69   }.  for(ii=0; i
5a20: 69 3c 70 49 64 78 49 6e 66 6f 2d 3e 6e 43 6f 6e  i<pIdxInfo->nCon
5a30: 73 74 72 61 69 6e 74 3b 20 69 69 2b 2b 29 7b 0a  straint; ii++){.
5a40: 20 20 20 20 63 6f 6e 73 74 20 73 74 72 75 63 74      const struct
5a50: 20 73 71 6c 69 74 65 33 5f 69 6e 64 65 78 5f 63   sqlite3_index_c
5a60: 6f 6e 73 74 72 61 69 6e 74 20 2a 70 43 6f 6e 73  onstraint *pCons
5a70: 74 72 61 69 6e 74 3b 0a 20 20 20 20 73 74 72 75  traint;.    stru
5a80: 63 74 20 73 71 6c 69 74 65 33 5f 69 6e 64 65 78  ct sqlite3_index
5a90: 5f 63 6f 6e 73 74 72 61 69 6e 74 5f 75 73 61 67  _constraint_usag
5aa0: 65 20 2a 70 55 73 61 67 65 3b 0a 20 20 20 20 69  e *pUsage;.    i
5ab0: 6e 74 20 69 43 6f 6c 3b 0a 0a 20 20 20 20 70 43  nt iCol;..    pC
5ac0: 6f 6e 73 74 72 61 69 6e 74 20 3d 20 26 70 49 64  onstraint = &pId
5ad0: 78 49 6e 66 6f 2d 3e 61 43 6f 6e 73 74 72 61 69  xInfo->aConstrai
5ae0: 6e 74 5b 69 69 5d 3b 0a 20 20 20 20 70 55 73 61  nt[ii];.    pUsa
5af0: 67 65 20 3d 20 26 70 49 64 78 49 6e 66 6f 2d 3e  ge = &pIdxInfo->
5b00: 61 43 6f 6e 73 74 72 61 69 6e 74 55 73 61 67 65  aConstraintUsage
5b10: 5b 69 69 5d 3b 0a 0a 20 20 20 20 69 66 28 20 21  [ii];..    if( !
5b20: 69 73 49 67 6e 6f 72 65 55 73 61 62 6c 65 20 26  isIgnoreUsable &
5b30: 26 20 21 70 43 6f 6e 73 74 72 61 69 6e 74 2d 3e  & !pConstraint->
5b40: 75 73 61 62 6c 65 20 29 20 63 6f 6e 74 69 6e 75  usable ) continu
5b50: 65 3b 0a 0a 20 20 20 20 69 43 6f 6c 20 3d 20 70  e;..    iCol = p
5b60: 43 6f 6e 73 74 72 61 69 6e 74 2d 3e 69 43 6f 6c  Constraint->iCol
5b70: 75 6d 6e 3b 0a 20 20 20 20 69 66 28 20 70 56 74  umn;.    if( pVt
5b80: 61 62 2d 3e 61 49 6e 64 65 78 5b 69 43 6f 6c 5d  ab->aIndex[iCol]
5b90: 20 7c 7c 20 69 43 6f 6c 3c 30 20 29 7b 0a 20 20   || iCol<0 ){.  
5ba0: 20 20 20 20 63 68 61 72 20 2a 7a 43 6f 6c 20 3d      char *zCol =
5bb0: 20 70 56 74 61 62 2d 3e 61 43 6f 6c 5b 69 43 6f   pVtab->aCol[iCo
5bc0: 6c 5d 3b 0a 20 20 20 20 20 20 63 68 61 72 20 2a  l];.      char *
5bd0: 7a 4f 70 20 3d 20 30 3b 0a 20 20 20 20 20 20 75  zOp = 0;.      u
5be0: 73 65 49 64 78 20 3d 20 31 3b 0a 20 20 20 20 20  seIdx = 1;.     
5bf0: 20 69 66 28 20 69 43 6f 6c 3c 30 20 29 7b 0a 20   if( iCol<0 ){. 
5c00: 20 20 20 20 20 20 20 7a 43 6f 6c 20 3d 20 22 72         zCol = "r
5c10: 6f 77 69 64 22 3b 0a 20 20 20 20 20 20 7d 0a 20  owid";.      }. 
5c20: 20 20 20 20 20 73 77 69 74 63 68 28 20 70 43 6f       switch( pCo
5c30: 6e 73 74 72 61 69 6e 74 2d 3e 6f 70 20 29 7b 0a  nstraint->op ){.
5c40: 20 20 20 20 20 20 20 20 63 61 73 65 20 53 51 4c          case SQL
5c50: 49 54 45 5f 49 4e 44 45 58 5f 43 4f 4e 53 54 52  ITE_INDEX_CONSTR
5c60: 41 49 4e 54 5f 45 51 3a 0a 20 20 20 20 20 20 20  AINT_EQ:.       
5c70: 20 20 20 7a 4f 70 20 3d 20 22 3d 22 3b 20 62 72     zOp = "="; br
5c80: 65 61 6b 3b 0a 20 20 20 20 20 20 20 20 63 61 73  eak;.        cas
5c90: 65 20 53 51 4c 49 54 45 5f 49 4e 44 45 58 5f 43  e SQLITE_INDEX_C
5ca0: 4f 4e 53 54 52 41 49 4e 54 5f 4c 54 3a 0a 20 20  ONSTRAINT_LT:.  
5cb0: 20 20 20 20 20 20 20 20 7a 4f 70 20 3d 20 22 3c          zOp = "<
5cc0: 22 3b 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20  "; break;.      
5cd0: 20 20 63 61 73 65 20 53 51 4c 49 54 45 5f 49 4e    case SQLITE_IN
5ce0: 44 45 58 5f 43 4f 4e 53 54 52 41 49 4e 54 5f 47  DEX_CONSTRAINT_G
5cf0: 54 3a 0a 20 20 20 20 20 20 20 20 20 20 7a 4f 70  T:.          zOp
5d00: 20 3d 20 22 3e 22 3b 20 62 72 65 61 6b 3b 0a 20   = ">"; break;. 
5d10: 20 20 20 20 20 20 20 63 61 73 65 20 53 51 4c 49         case SQLI
5d20: 54 45 5f 49 4e 44 45 58 5f 43 4f 4e 53 54 52 41  TE_INDEX_CONSTRA
5d30: 49 4e 54 5f 4c 45 3a 0a 20 20 20 20 20 20 20 20  INT_LE:.        
5d40: 20 20 7a 4f 70 20 3d 20 22 3c 3d 22 3b 20 62 72    zOp = "<="; br
5d50: 65 61 6b 3b 0a 20 20 20 20 20 20 20 20 63 61 73  eak;.        cas
5d60: 65 20 53 51 4c 49 54 45 5f 49 4e 44 45 58 5f 43  e SQLITE_INDEX_C
5d70: 4f 4e 53 54 52 41 49 4e 54 5f 47 45 3a 0a 20 20  ONSTRAINT_GE:.  
5d80: 20 20 20 20 20 20 20 20 7a 4f 70 20 3d 20 22 3e          zOp = ">
5d90: 3d 22 3b 20 62 72 65 61 6b 3b 0a 20 20 20 20 20  ="; break;.     
5da0: 20 20 20 63 61 73 65 20 53 51 4c 49 54 45 5f 49     case SQLITE_I
5db0: 4e 44 45 58 5f 43 4f 4e 53 54 52 41 49 4e 54 5f  NDEX_CONSTRAINT_
5dc0: 4d 41 54 43 48 3a 0a 20 20 20 20 20 20 20 20 20  MATCH:.         
5dd0: 20 7a 4f 70 20 3d 20 22 4c 49 4b 45 22 3b 20 62   zOp = "LIKE"; b
5de0: 72 65 61 6b 3b 0a 20 20 20 20 20 20 7d 0a 20 20  reak;.      }.  
5df0: 20 20 20 20 69 66 28 20 7a 4f 70 5b 30 5d 3d 3d      if( zOp[0]==
5e00: 27 4c 27 20 29 7b 0a 20 20 20 20 20 20 20 20 7a  'L' ){.        z
5e10: 4e 65 77 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70  New = sqlite3_mp
5e20: 72 69 6e 74 66 28 22 20 25 73 20 25 73 20 4c 49  rintf(" %s %s LI
5e30: 4b 45 20 28 53 45 4c 45 43 54 20 27 25 25 27 7c  KE (SELECT '%%'|
5e40: 7c 3f 7c 7c 27 25 25 27 29 22 2c 20 0a 20 20 20  |?||'%%')", .   
5e50: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5e60: 20 20 20 20 20 20 20 20 20 20 20 20 7a 53 65 70              zSep
5e70: 2c 20 7a 43 6f 6c 29 3b 0a 20 20 20 20 20 20 7d  , zCol);.      }
5e80: 20 65 6c 73 65 20 7b 0a 20 20 20 20 20 20 20 20   else {.        
5e90: 7a 4e 65 77 20 3d 20 73 71 6c 69 74 65 33 5f 6d  zNew = sqlite3_m
5ea0: 70 72 69 6e 74 66 28 22 20 25 73 20 25 73 20 25  printf(" %s %s %
5eb0: 73 20 3f 22 2c 20 7a 53 65 70 2c 20 7a 43 6f 6c  s ?", zSep, zCol
5ec0: 2c 20 7a 4f 70 29 3b 0a 20 20 20 20 20 20 7d 0a  , zOp);.      }.
5ed0: 20 20 20 20 20 20 73 74 72 69 6e 67 5f 63 6f 6e        string_con
5ee0: 63 61 74 28 26 7a 51 75 65 72 79 2c 20 7a 4e 65  cat(&zQuery, zNe
5ef0: 77 2c 20 31 2c 20 26 72 63 29 3b 0a 0a 20 20 20  w, 1, &rc);..   
5f00: 20 20 20 7a 53 65 70 20 3d 20 22 41 4e 44 22 3b     zSep = "AND";
5f10: 0a 20 20 20 20 20 20 70 55 73 61 67 65 2d 3e 61  .      pUsage->a
5f20: 72 67 76 49 6e 64 65 78 20 3d 20 2b 2b 6e 41 72  rgvIndex = ++nAr
5f30: 67 3b 0a 20 20 20 20 20 20 70 55 73 61 67 65 2d  g;.      pUsage-
5f40: 3e 6f 6d 69 74 20 3d 20 31 3b 0a 20 20 20 20 7d  >omit = 1;.    }
5f50: 0a 20 20 7d 0a 0a 20 20 2f 2a 20 49 66 20 74 68  .  }..  /* If th
5f60: 65 72 65 20 69 73 20 6f 6e 6c 79 20 6f 6e 65 20  ere is only one 
5f70: 74 65 72 6d 20 69 6e 20 74 68 65 20 4f 52 44 45  term in the ORDE
5f80: 52 20 42 59 20 63 6c 61 75 73 65 2c 20 61 6e 64  R BY clause, and
5f90: 20 69 74 20 69 73 0a 20 20 2a 2a 20 6f 6e 20 61   it is.  ** on a
5fa0: 20 63 6f 6c 75 6d 6e 20 74 68 61 74 20 74 68 69   column that thi
5fb0: 73 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65 20  s virtual table 
5fc0: 68 61 73 20 61 6e 20 69 6e 64 65 78 20 66 6f 72  has an index for
5fd0: 2c 20 74 68 65 6e 20 63 6f 6e 73 75 6d 65 20 0a  , then consume .
5fe0: 20 20 2a 2a 20 74 68 65 20 4f 52 44 45 52 20 42    ** the ORDER B
5ff0: 59 20 63 6c 61 75 73 65 2e 0a 20 20 2a 2f 0a 20  Y clause..  */. 
6000: 20 69 66 28 20 70 49 64 78 49 6e 66 6f 2d 3e 6e   if( pIdxInfo->n
6010: 4f 72 64 65 72 42 79 3d 3d 31 20 26 26 20 70 56  OrderBy==1 && pV
6020: 74 61 62 2d 3e 61 49 6e 64 65 78 5b 70 49 64 78  tab->aIndex[pIdx
6030: 49 6e 66 6f 2d 3e 61 4f 72 64 65 72 42 79 2d 3e  Info->aOrderBy->
6040: 69 43 6f 6c 75 6d 6e 5d 20 29 7b 0a 20 20 20 20  iColumn] ){.    
6050: 69 6e 74 20 69 43 6f 6c 20 3d 20 70 49 64 78 49  int iCol = pIdxI
6060: 6e 66 6f 2d 3e 61 4f 72 64 65 72 42 79 2d 3e 69  nfo->aOrderBy->i
6070: 43 6f 6c 75 6d 6e 3b 0a 20 20 20 20 63 68 61 72  Column;.    char
6080: 20 2a 7a 43 6f 6c 20 3d 20 70 56 74 61 62 2d 3e   *zCol = pVtab->
6090: 61 43 6f 6c 5b 69 43 6f 6c 5d 3b 0a 20 20 20 20  aCol[iCol];.    
60a0: 63 68 61 72 20 2a 7a 44 69 72 20 3d 20 70 49 64  char *zDir = pId
60b0: 78 49 6e 66 6f 2d 3e 61 4f 72 64 65 72 42 79 2d  xInfo->aOrderBy-
60c0: 3e 64 65 73 63 3f 22 44 45 53 43 22 3a 22 41 53  >desc?"DESC":"AS
60d0: 43 22 3b 0a 20 20 20 20 69 66 28 20 69 43 6f 6c  C";.    if( iCol
60e0: 3c 30 20 29 7b 0a 20 20 20 20 20 20 7a 43 6f 6c  <0 ){.      zCol
60f0: 20 3d 20 22 72 6f 77 69 64 22 3b 0a 20 20 20 20   = "rowid";.    
6100: 7d 0a 20 20 20 20 7a 4e 65 77 20 3d 20 73 71 6c  }.    zNew = sql
6110: 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 22 20 4f  ite3_mprintf(" O
6120: 52 44 45 52 20 42 59 20 25 73 20 25 73 22 2c 20  RDER BY %s %s", 
6130: 7a 43 6f 6c 2c 20 7a 44 69 72 29 3b 0a 20 20 20  zCol, zDir);.   
6140: 20 73 74 72 69 6e 67 5f 63 6f 6e 63 61 74 28 26   string_concat(&
6150: 7a 51 75 65 72 79 2c 20 7a 4e 65 77 2c 20 31 2c  zQuery, zNew, 1,
6160: 20 26 72 63 29 3b 0a 20 20 20 20 70 49 64 78 49   &rc);.    pIdxI
6170: 6e 66 6f 2d 3e 6f 72 64 65 72 42 79 43 6f 6e 73  nfo->orderByCons
6180: 75 6d 65 64 20 3d 20 31 3b 0a 20 20 7d 0a 0a 20  umed = 1;.  }.. 
6190: 20 61 70 70 65 6e 64 54 6f 45 63 68 6f 4d 6f 64   appendToEchoMod
61a0: 75 6c 65 28 70 56 74 61 62 2d 3e 69 6e 74 65 72  ule(pVtab->inter
61b0: 70 2c 20 22 78 42 65 73 74 49 6e 64 65 78 22 29  p, "xBestIndex")
61c0: 3b 3b 0a 20 20 61 70 70 65 6e 64 54 6f 45 63 68  ;;.  appendToEch
61d0: 6f 4d 6f 64 75 6c 65 28 70 56 74 61 62 2d 3e 69  oModule(pVtab->i
61e0: 6e 74 65 72 70 2c 20 7a 51 75 65 72 79 29 3b 0a  nterp, zQuery);.
61f0: 0a 20 20 69 66 28 20 21 7a 51 75 65 72 79 20 29  .  if( !zQuery )
6200: 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 72 63 3b  {.    return rc;
6210: 0a 20 20 7d 0a 20 20 70 49 64 78 49 6e 66 6f 2d  .  }.  pIdxInfo-
6220: 3e 69 64 78 4e 75 6d 20 3d 20 68 61 73 68 53 74  >idxNum = hashSt
6230: 72 69 6e 67 28 7a 51 75 65 72 79 29 3b 0a 20 20  ring(zQuery);.  
6240: 70 49 64 78 49 6e 66 6f 2d 3e 69 64 78 53 74 72  pIdxInfo->idxStr
6250: 20 3d 20 7a 51 75 65 72 79 3b 0a 20 20 70 49 64   = zQuery;.  pId
6260: 78 49 6e 66 6f 2d 3e 6e 65 65 64 54 6f 46 72 65  xInfo->needToFre
6270: 65 49 64 78 53 74 72 20 3d 20 31 3b 0a 20 20 69  eIdxStr = 1;.  i
6280: 66 20 28 75 73 65 43 6f 73 74 29 20 7b 0a 20 20  f (useCost) {.  
6290: 20 20 70 49 64 78 49 6e 66 6f 2d 3e 65 73 74 69    pIdxInfo->esti
62a0: 6d 61 74 65 64 43 6f 73 74 20 3d 20 63 6f 73 74  matedCost = cost
62b0: 3b 0a 20 20 7d 20 65 6c 73 65 20 69 66 28 20 75  ;.  } else if( u
62c0: 73 65 49 64 78 20 29 7b 0a 20 20 20 20 2f 2a 20  seIdx ){.    /* 
62d0: 41 70 70 72 6f 78 69 6d 61 74 69 6f 6e 20 6f 66  Approximation of
62e0: 20 6c 6f 67 32 28 6e 52 6f 77 29 2e 20 2a 2f 0a   log2(nRow). */.
62f0: 20 20 20 20 66 6f 72 28 20 69 69 3d 30 3b 20 69      for( ii=0; i
6300: 69 3c 28 73 69 7a 65 6f 66 28 69 6e 74 29 2a 38  i<(sizeof(int)*8
6310: 29 3b 20 69 69 2b 2b 20 29 7b 0a 20 20 20 20 20  ); ii++ ){.     
6320: 20 69 66 28 20 6e 52 6f 77 20 26 20 28 31 3c 3c   if( nRow & (1<<
6330: 69 69 29 20 29 7b 0a 20 20 20 20 20 20 20 20 70  ii) ){.        p
6340: 49 64 78 49 6e 66 6f 2d 3e 65 73 74 69 6d 61 74  IdxInfo->estimat
6350: 65 64 43 6f 73 74 20 3d 20 28 64 6f 75 62 6c 65  edCost = (double
6360: 29 69 69 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20  )ii;.      }.   
6370: 20 7d 0a 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20   }.  } else {.  
6380: 20 20 70 49 64 78 49 6e 66 6f 2d 3e 65 73 74 69    pIdxInfo->esti
6390: 6d 61 74 65 64 43 6f 73 74 20 3d 20 28 64 6f 75  matedCost = (dou
63a0: 62 6c 65 29 6e 52 6f 77 3b 0a 20 20 7d 0a 20 20  ble)nRow;.  }.  
63b0: 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a  return rc;.}../*
63c0: 0a 2a 2a 20 54 68 65 20 78 55 70 64 61 74 65 20  .** The xUpdate 
63d0: 6d 65 74 68 6f 64 20 66 6f 72 20 65 63 68 6f 20  method for echo 
63e0: 6d 6f 64 75 6c 65 20 76 69 72 74 75 61 6c 20 74  module virtual t
63f0: 61 62 6c 65 73 2e 0a 2a 2a 20 0a 2a 2a 20 20 20  ables..** .**   
6400: 20 61 70 44 61 74 61 5b 30 5d 20 20 61 70 44 61   apData[0]  apDa
6410: 74 61 5b 31 5d 20 20 61 70 44 61 74 61 5b 32 2e  ta[1]  apData[2.
6420: 2e 5d 0a 2a 2a 0a 2a 2a 20 20 20 20 49 4e 54 45  .].**.**    INTE
6430: 47 45 52 20 20 20 20 20 20 20 20 20 20 20 20 20  GER             
6440: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6450: 20 44 45 4c 45 54 45 20 20 20 20 20 20 20 20 20   DELETE         
6460: 20 20 20 0a 2a 2a 0a 2a 2a 20 20 20 20 49 4e 54     .**.**    INT
6470: 45 47 45 52 20 20 20 20 4e 55 4c 4c 20 20 20 20  EGER    NULL    
6480: 20 20 20 28 6e 43 6f 6c 20 61 72 67 73 29 20 20     (nCol args)  
6490: 20 20 55 50 44 41 54 45 20 28 64 6f 20 6e 6f 74    UPDATE (do not
64a0: 20 73 65 74 20 72 6f 77 69 64 29 0a 2a 2a 20 20   set rowid).**  
64b0: 20 20 49 4e 54 45 47 45 52 20 20 20 20 49 4e 54    INTEGER    INT
64c0: 45 47 45 52 20 20 20 20 28 6e 43 6f 6c 20 61 72  EGER    (nCol ar
64d0: 67 73 29 20 20 20 20 55 50 44 41 54 45 20 28 77  gs)    UPDATE (w
64e0: 69 74 68 20 53 45 54 20 72 6f 77 69 64 20 3d 20  ith SET rowid = 
64f0: 3c 61 72 67 31 3e 29 0a 2a 2a 0a 2a 2a 20 20 20  <arg1>).**.**   
6500: 20 4e 55 4c 4c 20 20 20 20 20 20 20 4e 55 4c 4c   NULL       NULL
6510: 20 20 20 20 20 20 20 28 6e 43 6f 6c 20 61 72 67         (nCol arg
6520: 73 29 20 20 20 20 49 4e 53 45 52 54 20 49 4e 54  s)    INSERT INT
6530: 4f 20 28 61 75 74 6f 6d 61 74 69 63 20 72 6f 77  O (automatic row
6540: 69 64 20 76 61 6c 75 65 29 0a 2a 2a 20 20 20 20  id value).**    
6550: 4e 55 4c 4c 20 20 20 20 20 20 20 49 4e 54 45 47  NULL       INTEG
6560: 45 52 20 20 20 20 28 6e 43 6f 6c 20 61 72 67 73  ER    (nCol args
6570: 29 20 20 20 20 49 4e 53 45 52 54 20 28 69 6e 63  )    INSERT (inc
6580: 6c 2e 20 72 6f 77 69 64 20 76 61 6c 75 65 29 0a  l. rowid value).
6590: 2a 2a 0a 2a 2f 0a 69 6e 74 20 65 63 68 6f 55 70  **.*/.int echoUp
65a0: 64 61 74 65 28 0a 20 20 73 71 6c 69 74 65 33 5f  date(.  sqlite3_
65b0: 76 74 61 62 20 2a 74 61 62 2c 20 0a 20 20 69 6e  vtab *tab, .  in
65c0: 74 20 6e 44 61 74 61 2c 20 0a 20 20 73 71 6c 69  t nData, .  sqli
65d0: 74 65 33 5f 76 61 6c 75 65 20 2a 2a 61 70 44 61  te3_value **apDa
65e0: 74 61 2c 20 0a 20 20 73 71 6c 69 74 65 5f 69 6e  ta, .  sqlite_in
65f0: 74 36 34 20 2a 70 52 6f 77 69 64 0a 29 7b 0a 20  t64 *pRowid.){. 
6600: 20 65 63 68 6f 5f 76 74 61 62 20 2a 70 56 74 61   echo_vtab *pVta
6610: 62 20 3d 20 28 65 63 68 6f 5f 76 74 61 62 20 2a  b = (echo_vtab *
6620: 29 74 61 62 3b 0a 20 20 73 71 6c 69 74 65 33 20  )tab;.  sqlite3 
6630: 2a 64 62 20 3d 20 70 56 74 61 62 2d 3e 64 62 3b  *db = pVtab->db;
6640: 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49  .  int rc = SQLI
6650: 54 45 5f 4f 4b 3b 0a 0a 20 20 73 71 6c 69 74 65  TE_OK;..  sqlite
6660: 33 5f 73 74 6d 74 20 2a 70 53 74 6d 74 3b 0a 20  3_stmt *pStmt;. 
6670: 20 63 68 61 72 20 2a 7a 20 3d 20 30 3b 20 20 20   char *z = 0;   
6680: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53              /* S
6690: 51 4c 20 73 74 61 74 65 6d 65 6e 74 20 74 6f 20  QL statement to 
66a0: 65 78 65 63 75 74 65 20 2a 2f 0a 20 20 69 6e 74  execute */.  int
66b0: 20 62 69 6e 64 41 72 67 5a 65 72 6f 20 3d 20 30   bindArgZero = 0
66c0: 3b 20 20 20 20 20 20 20 2f 2a 20 54 72 75 65 20  ;       /* True 
66d0: 74 6f 20 62 69 6e 64 20 61 70 44 61 74 61 5b 30  to bind apData[0
66e0: 5d 20 74 6f 20 73 71 6c 20 76 61 72 20 6e 6f 2e  ] to sql var no.
66f0: 20 6e 44 61 74 61 20 2a 2f 0a 20 20 69 6e 74 20   nData */.  int 
6700: 62 69 6e 64 41 72 67 4f 6e 65 20 3d 20 30 3b 20  bindArgOne = 0; 
6710: 20 20 20 20 20 20 20 2f 2a 20 54 72 75 65 20 74         /* True t
6720: 6f 20 62 69 6e 64 20 61 70 44 61 74 61 5b 31 5d  o bind apData[1]
6730: 20 74 6f 20 73 71 6c 20 76 61 72 20 6e 6f 2e 20   to sql var no. 
6740: 31 20 2a 2f 0a 20 20 69 6e 74 20 69 3b 20 20 20  1 */.  int i;   
6750: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6760: 20 20 2f 2a 20 43 6f 75 6e 74 65 72 20 76 61 72    /* Counter var
6770: 69 61 62 6c 65 20 75 73 65 64 20 62 79 20 66 6f  iable used by fo
6780: 72 20 6c 6f 6f 70 73 20 2a 2f 0a 0a 20 20 61 73  r loops */..  as
6790: 73 65 72 74 28 20 6e 44 61 74 61 3d 3d 70 56 74  sert( nData==pVt
67a0: 61 62 2d 3e 6e 43 6f 6c 2b 32 20 7c 7c 20 6e 44  ab->nCol+2 || nD
67b0: 61 74 61 3d 3d 31 20 29 3b 0a 0a 20 20 2f 2a 20  ata==1 );..  /* 
67c0: 54 69 63 6b 65 74 20 23 33 30 38 33 20 2d 20 6d  Ticket #3083 - m
67d0: 61 6b 65 20 73 75 72 65 20 77 65 20 61 6c 77 61  ake sure we alwa
67e0: 79 73 20 73 74 61 72 74 20 61 20 74 72 61 6e 73  ys start a trans
67f0: 61 63 74 69 6f 6e 20 70 72 69 6f 72 20 74 6f 0a  action prior to.
6800: 20 20 2a 2a 20 6d 61 6b 69 6e 67 20 61 6e 79 20    ** making any 
6810: 63 68 61 6e 67 65 73 20 74 6f 20 61 20 76 69 72  changes to a vir
6820: 74 75 61 6c 20 74 61 62 6c 65 20 2a 2f 0a 20 20  tual table */.  
6830: 61 73 73 65 72 74 28 20 70 56 74 61 62 2d 3e 69  assert( pVtab->i
6840: 6e 54 72 61 6e 73 61 63 74 69 6f 6e 20 29 3b 0a  nTransaction );.
6850: 0a 20 20 69 66 28 20 73 69 6d 75 6c 61 74 65 56  .  if( simulateV
6860: 74 61 62 45 72 72 6f 72 28 70 56 74 61 62 2c 20  tabError(pVtab, 
6870: 22 78 55 70 64 61 74 65 22 29 20 29 7b 0a 20 20  "xUpdate") ){.  
6880: 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f    return SQLITE_
6890: 45 52 52 4f 52 3b 0a 20 20 7d 0a 0a 20 20 2f 2a  ERROR;.  }..  /*
68a0: 20 49 66 20 61 70 44 61 74 61 5b 30 5d 20 69 73   If apData[0] is
68b0: 20 61 6e 20 69 6e 74 65 67 65 72 20 61 6e 64 20   an integer and 
68c0: 6e 44 61 74 61 3e 31 20 74 68 65 6e 20 64 6f 20  nData>1 then do 
68d0: 61 6e 20 55 50 44 41 54 45 20 2a 2f 0a 20 20 69  an UPDATE */.  i
68e0: 66 28 20 6e 44 61 74 61 3e 31 20 26 26 20 73 71  f( nData>1 && sq
68f0: 6c 69 74 65 33 5f 76 61 6c 75 65 5f 74 79 70 65  lite3_value_type
6900: 28 61 70 44 61 74 61 5b 30 5d 29 3d 3d 53 51 4c  (apData[0])==SQL
6910: 49 54 45 5f 49 4e 54 45 47 45 52 20 29 7b 0a 20  ITE_INTEGER ){. 
6920: 20 20 20 63 68 61 72 20 2a 7a 53 65 70 20 3d 20     char *zSep = 
6930: 22 20 53 45 54 22 3b 0a 20 20 20 20 7a 20 3d 20  " SET";.    z = 
6940: 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28  sqlite3_mprintf(
6950: 22 55 50 44 41 54 45 20 25 51 22 2c 20 70 56 74  "UPDATE %Q", pVt
6960: 61 62 2d 3e 7a 54 61 62 6c 65 4e 61 6d 65 29 3b  ab->zTableName);
6970: 0a 20 20 20 20 69 66 28 20 21 7a 20 29 7b 0a 20  .    if( !z ){. 
6980: 20 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45       rc = SQLITE
6990: 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 7d 0a 0a 20  _NOMEM;.    }.. 
69a0: 20 20 20 62 69 6e 64 41 72 67 4f 6e 65 20 3d 20     bindArgOne = 
69b0: 28 61 70 44 61 74 61 5b 31 5d 20 26 26 20 73 71  (apData[1] && sq
69c0: 6c 69 74 65 33 5f 76 61 6c 75 65 5f 74 79 70 65  lite3_value_type
69d0: 28 61 70 44 61 74 61 5b 31 5d 29 3d 3d 53 51 4c  (apData[1])==SQL
69e0: 49 54 45 5f 49 4e 54 45 47 45 52 29 3b 0a 20 20  ITE_INTEGER);.  
69f0: 20 20 62 69 6e 64 41 72 67 5a 65 72 6f 20 3d 20    bindArgZero = 
6a00: 31 3b 0a 0a 20 20 20 20 69 66 28 20 62 69 6e 64  1;..    if( bind
6a10: 41 72 67 4f 6e 65 20 29 7b 0a 20 20 20 20 20 20  ArgOne ){.      
6a20: 20 73 74 72 69 6e 67 5f 63 6f 6e 63 61 74 28 26   string_concat(&
6a30: 7a 2c 20 22 20 53 45 54 20 72 6f 77 69 64 3d 3f  z, " SET rowid=?
6a40: 31 20 22 2c 20 30 2c 20 26 72 63 29 3b 0a 20 20  1 ", 0, &rc);.  
6a50: 20 20 20 20 20 7a 53 65 70 20 3d 20 22 2c 22 3b       zSep = ",";
6a60: 0a 20 20 20 20 7d 0a 20 20 20 20 66 6f 72 28 69  .    }.    for(i
6a70: 3d 32 3b 20 69 3c 6e 44 61 74 61 3b 20 69 2b 2b  =2; i<nData; i++
6a80: 29 7b 0a 20 20 20 20 20 20 69 66 28 20 61 70 44  ){.      if( apD
6a90: 61 74 61 5b 69 5d 3d 3d 30 20 29 20 63 6f 6e 74  ata[i]==0 ) cont
6aa0: 69 6e 75 65 3b 0a 20 20 20 20 20 20 73 74 72 69  inue;.      stri
6ab0: 6e 67 5f 63 6f 6e 63 61 74 28 26 7a 2c 20 73 71  ng_concat(&z, sq
6ac0: 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 0a 20  lite3_mprintf(. 
6ad0: 20 20 20 20 20 20 20 20 20 22 25 73 20 25 51 3d           "%s %Q=
6ae0: 3f 25 64 22 2c 20 7a 53 65 70 2c 20 70 56 74 61  ?%d", zSep, pVta
6af0: 62 2d 3e 61 43 6f 6c 5b 69 2d 32 5d 2c 20 69 29  b->aCol[i-2], i)
6b00: 2c 20 31 2c 20 26 72 63 29 3b 0a 20 20 20 20 20  , 1, &rc);.     
6b10: 20 7a 53 65 70 20 3d 20 22 2c 22 3b 0a 20 20 20   zSep = ",";.   
6b20: 20 7d 0a 20 20 20 20 73 74 72 69 6e 67 5f 63 6f   }.    string_co
6b30: 6e 63 61 74 28 26 7a 2c 20 73 71 6c 69 74 65 33  ncat(&z, sqlite3
6b40: 5f 6d 70 72 69 6e 74 66 28 22 20 57 48 45 52 45  _mprintf(" WHERE
6b50: 20 72 6f 77 69 64 3d 3f 25 64 22 2c 20 6e 44 61   rowid=?%d", nDa
6b60: 74 61 29 2c 20 31 2c 20 26 72 63 29 3b 0a 20 20  ta), 1, &rc);.  
6b70: 7d 0a 0a 20 20 2f 2a 20 49 66 20 61 70 44 61 74  }..  /* If apDat
6b80: 61 5b 30 5d 20 69 73 20 61 6e 20 69 6e 74 65 67  a[0] is an integ
6b90: 65 72 20 61 6e 64 20 6e 44 61 74 61 3d 3d 31 20  er and nData==1 
6ba0: 74 68 65 6e 20 64 6f 20 61 20 44 45 4c 45 54 45  then do a DELETE
6bb0: 20 2a 2f 0a 20 20 65 6c 73 65 20 69 66 28 20 6e   */.  else if( n
6bc0: 44 61 74 61 3d 3d 31 20 26 26 20 73 71 6c 69 74  Data==1 && sqlit
6bd0: 65 33 5f 76 61 6c 75 65 5f 74 79 70 65 28 61 70  e3_value_type(ap
6be0: 44 61 74 61 5b 30 5d 29 3d 3d 53 51 4c 49 54 45  Data[0])==SQLITE
6bf0: 5f 49 4e 54 45 47 45 52 20 29 7b 0a 20 20 20 20  _INTEGER ){.    
6c00: 7a 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72 69  z = sqlite3_mpri
6c10: 6e 74 66 28 22 44 45 4c 45 54 45 20 46 52 4f 4d  ntf("DELETE FROM
6c20: 20 25 51 20 57 48 45 52 45 20 72 6f 77 69 64 20   %Q WHERE rowid 
6c30: 3d 20 3f 31 22 2c 20 70 56 74 61 62 2d 3e 7a 54  = ?1", pVtab->zT
6c40: 61 62 6c 65 4e 61 6d 65 29 3b 0a 20 20 20 20 69  ableName);.    i
6c50: 66 28 20 21 7a 20 29 7b 0a 20 20 20 20 20 20 72  f( !z ){.      r
6c60: 63 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d  c = SQLITE_NOMEM
6c70: 3b 0a 20 20 20 20 7d 0a 20 20 20 20 62 69 6e 64  ;.    }.    bind
6c80: 41 72 67 5a 65 72 6f 20 3d 20 31 3b 0a 20 20 7d  ArgZero = 1;.  }
6c90: 0a 0a 20 20 2f 2a 20 49 66 20 74 68 65 20 66 69  ..  /* If the fi
6ca0: 72 73 74 20 61 72 67 75 6d 65 6e 74 20 69 73 20  rst argument is 
6cb0: 4e 55 4c 4c 20 61 6e 64 20 74 68 65 72 65 20 61  NULL and there a
6cc0: 72 65 20 6d 6f 72 65 20 74 68 61 6e 20 74 77 6f  re more than two
6cd0: 20 61 72 67 73 2c 20 49 4e 53 45 52 54 20 2a 2f   args, INSERT */
6ce0: 0a 20 20 65 6c 73 65 20 69 66 28 20 6e 44 61 74  .  else if( nDat
6cf0: 61 3e 32 20 26 26 20 73 71 6c 69 74 65 33 5f 76  a>2 && sqlite3_v
6d00: 61 6c 75 65 5f 74 79 70 65 28 61 70 44 61 74 61  alue_type(apData
6d10: 5b 30 5d 29 3d 3d 53 51 4c 49 54 45 5f 4e 55 4c  [0])==SQLITE_NUL
6d20: 4c 20 29 7b 0a 20 20 20 20 69 6e 74 20 69 69 3b  L ){.    int ii;
6d30: 0a 20 20 20 20 63 68 61 72 20 2a 7a 49 6e 73 65  .    char *zInse
6d40: 72 74 20 3d 20 30 3b 0a 20 20 20 20 63 68 61 72  rt = 0;.    char
6d50: 20 2a 7a 56 61 6c 75 65 73 20 3d 20 30 3b 0a 20   *zValues = 0;. 
6d60: 20 0a 20 20 20 20 7a 49 6e 73 65 72 74 20 3d 20   .    zInsert = 
6d70: 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28  sqlite3_mprintf(
6d80: 22 49 4e 53 45 52 54 20 49 4e 54 4f 20 25 51 20  "INSERT INTO %Q 
6d90: 28 22 2c 20 70 56 74 61 62 2d 3e 7a 54 61 62 6c  (", pVtab->zTabl
6da0: 65 4e 61 6d 65 29 3b 0a 20 20 20 20 69 66 28 20  eName);.    if( 
6db0: 21 7a 49 6e 73 65 72 74 20 29 7b 0a 20 20 20 20  !zInsert ){.    
6dc0: 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4e 4f    rc = SQLITE_NO
6dd0: 4d 45 4d 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69  MEM;.    }.    i
6de0: 66 28 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65  f( sqlite3_value
6df0: 5f 74 79 70 65 28 61 70 44 61 74 61 5b 31 5d 29  _type(apData[1])
6e00: 3d 3d 53 51 4c 49 54 45 5f 49 4e 54 45 47 45 52  ==SQLITE_INTEGER
6e10: 20 29 7b 0a 20 20 20 20 20 20 62 69 6e 64 41 72   ){.      bindAr
6e20: 67 4f 6e 65 20 3d 20 31 3b 0a 20 20 20 20 20 20  gOne = 1;.      
6e30: 7a 56 61 6c 75 65 73 20 3d 20 73 71 6c 69 74 65  zValues = sqlite
6e40: 33 5f 6d 70 72 69 6e 74 66 28 22 3f 22 29 3b 0a  3_mprintf("?");.
6e50: 20 20 20 20 20 20 73 74 72 69 6e 67 5f 63 6f 6e        string_con
6e60: 63 61 74 28 26 7a 49 6e 73 65 72 74 2c 20 22 72  cat(&zInsert, "r
6e70: 6f 77 69 64 22 2c 20 30 2c 20 26 72 63 29 3b 0a  owid", 0, &rc);.
6e80: 20 20 20 20 7d 0a 0a 20 20 20 20 61 73 73 65 72      }..    asser
6e90: 74 28 28 70 56 74 61 62 2d 3e 6e 43 6f 6c 2b 32  t((pVtab->nCol+2
6ea0: 29 3d 3d 6e 44 61 74 61 29 3b 0a 20 20 20 20 66  )==nData);.    f
6eb0: 6f 72 28 69 69 3d 32 3b 20 69 69 3c 6e 44 61 74  or(ii=2; ii<nDat
6ec0: 61 3b 20 69 69 2b 2b 29 7b 0a 20 20 20 20 20 20  a; ii++){.      
6ed0: 73 74 72 69 6e 67 5f 63 6f 6e 63 61 74 28 26 7a  string_concat(&z
6ee0: 49 6e 73 65 72 74 2c 20 0a 20 20 20 20 20 20 20  Insert, .       
6ef0: 20 20 20 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e     sqlite3_mprin
6f00: 74 66 28 22 25 73 25 51 22 2c 20 7a 56 61 6c 75  tf("%s%Q", zValu
6f10: 65 73 3f 22 2c 20 22 3a 22 22 2c 20 70 56 74 61  es?", ":"", pVta
6f20: 62 2d 3e 61 43 6f 6c 5b 69 69 2d 32 5d 29 2c 20  b->aCol[ii-2]), 
6f30: 31 2c 20 26 72 63 29 3b 0a 20 20 20 20 20 20 73  1, &rc);.      s
6f40: 74 72 69 6e 67 5f 63 6f 6e 63 61 74 28 26 7a 56  tring_concat(&zV
6f50: 61 6c 75 65 73 2c 20 0a 20 20 20 20 20 20 20 20  alues, .        
6f60: 20 20 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74    sqlite3_mprint
6f70: 66 28 22 25 73 3f 25 64 22 2c 20 7a 56 61 6c 75  f("%s?%d", zValu
6f80: 65 73 3f 22 2c 20 22 3a 22 22 2c 20 69 69 29 2c  es?", ":"", ii),
6f90: 20 31 2c 20 26 72 63 29 3b 0a 20 20 20 20 7d 0a   1, &rc);.    }.
6fa0: 0a 20 20 20 20 73 74 72 69 6e 67 5f 63 6f 6e 63  .    string_conc
6fb0: 61 74 28 26 7a 2c 20 7a 49 6e 73 65 72 74 2c 20  at(&z, zInsert, 
6fc0: 31 2c 20 26 72 63 29 3b 0a 20 20 20 20 73 74 72  1, &rc);.    str
6fd0: 69 6e 67 5f 63 6f 6e 63 61 74 28 26 7a 2c 20 22  ing_concat(&z, "
6fe0: 29 20 56 41 4c 55 45 53 28 22 2c 20 30 2c 20 26  ) VALUES(", 0, &
6ff0: 72 63 29 3b 0a 20 20 20 20 73 74 72 69 6e 67 5f  rc);.    string_
7000: 63 6f 6e 63 61 74 28 26 7a 2c 20 7a 56 61 6c 75  concat(&z, zValu
7010: 65 73 2c 20 31 2c 20 26 72 63 29 3b 0a 20 20 20  es, 1, &rc);.   
7020: 20 73 74 72 69 6e 67 5f 63 6f 6e 63 61 74 28 26   string_concat(&
7030: 7a 2c 20 22 29 22 2c 20 30 2c 20 26 72 63 29 3b  z, ")", 0, &rc);
7040: 0a 20 20 7d 0a 0a 20 20 2f 2a 20 41 6e 79 74 68  .  }..  /* Anyth
7050: 69 6e 67 20 65 6c 73 65 20 69 73 20 61 6e 20 65  ing else is an e
7060: 72 72 6f 72 20 2a 2f 0a 20 20 65 6c 73 65 7b 0a  rror */.  else{.
7070: 20 20 20 20 61 73 73 65 72 74 28 30 29 3b 0a 20      assert(0);. 
7080: 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45     return SQLITE
7090: 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a 0a 20 20 69  _ERROR;.  }..  i
70a0: 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc==SQLITE_OK
70b0: 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 73 71 6c   ){.    rc = sql
70c0: 69 74 65 33 5f 70 72 65 70 61 72 65 28 64 62 2c  ite3_prepare(db,
70d0: 20 7a 2c 20 2d 31 2c 20 26 70 53 74 6d 74 2c 20   z, -1, &pStmt, 
70e0: 30 29 3b 0a 20 20 7d 0a 20 20 61 73 73 65 72 74  0);.  }.  assert
70f0: 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc!=SQLITE_OK 
7100: 7c 7c 20 70 53 74 6d 74 20 29 3b 0a 20 20 73 71  || pStmt );.  sq
7110: 6c 69 74 65 33 5f 66 72 65 65 28 7a 29 3b 0a 20  lite3_free(z);. 
7120: 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
7130: 4f 4b 20 29 20 7b 0a 20 20 20 20 69 66 28 20 62  OK ) {.    if( b
7140: 69 6e 64 41 72 67 5a 65 72 6f 20 29 7b 0a 20 20  indArgZero ){.  
7150: 20 20 20 20 73 71 6c 69 74 65 33 5f 62 69 6e 64      sqlite3_bind
7160: 5f 76 61 6c 75 65 28 70 53 74 6d 74 2c 20 6e 44  _value(pStmt, nD
7170: 61 74 61 2c 20 61 70 44 61 74 61 5b 30 5d 29 3b  ata, apData[0]);
7180: 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 28 20 62  .    }.    if( b
7190: 69 6e 64 41 72 67 4f 6e 65 20 29 7b 0a 20 20 20  indArgOne ){.   
71a0: 20 20 20 73 71 6c 69 74 65 33 5f 62 69 6e 64 5f     sqlite3_bind_
71b0: 76 61 6c 75 65 28 70 53 74 6d 74 2c 20 31 2c 20  value(pStmt, 1, 
71c0: 61 70 44 61 74 61 5b 31 5d 29 3b 0a 20 20 20 20  apData[1]);.    
71d0: 7d 0a 20 20 20 20 66 6f 72 28 69 3d 32 3b 20 69  }.    for(i=2; i
71e0: 3c 6e 44 61 74 61 20 26 26 20 72 63 3d 3d 53 51  <nData && rc==SQ
71f0: 4c 49 54 45 5f 4f 4b 3b 20 69 2b 2b 29 7b 0a 20  LITE_OK; i++){. 
7200: 20 20 20 20 20 69 66 28 20 61 70 44 61 74 61 5b       if( apData[
7210: 69 5d 20 29 20 72 63 20 3d 20 73 71 6c 69 74 65  i] ) rc = sqlite
7220: 33 5f 62 69 6e 64 5f 76 61 6c 75 65 28 70 53 74  3_bind_value(pSt
7230: 6d 74 2c 20 69 2c 20 61 70 44 61 74 61 5b 69 5d  mt, i, apData[i]
7240: 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 28  );.    }.    if(
7250: 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc==SQLITE_OK )
7260: 7b 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f  {.      sqlite3_
7270: 73 74 65 70 28 70 53 74 6d 74 29 3b 0a 20 20 20  step(pStmt);.   
7280: 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f     rc = sqlite3_
7290: 66 69 6e 61 6c 69 7a 65 28 70 53 74 6d 74 29 3b  finalize(pStmt);
72a0: 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  .    }else{.    
72b0: 20 20 73 71 6c 69 74 65 33 5f 66 69 6e 61 6c 69    sqlite3_finali
72c0: 7a 65 28 70 53 74 6d 74 29 3b 0a 20 20 20 20 7d  ze(pStmt);.    }
72d0: 0a 20 20 7d 0a 0a 20 20 69 66 28 20 70 52 6f 77  .  }..  if( pRow
72e0: 69 64 20 26 26 20 72 63 3d 3d 53 51 4c 49 54 45  id && rc==SQLITE
72f0: 5f 4f 4b 20 29 7b 0a 20 20 20 20 2a 70 52 6f 77  _OK ){.    *pRow
7300: 69 64 20 3d 20 73 71 6c 69 74 65 33 5f 6c 61 73  id = sqlite3_las
7310: 74 5f 69 6e 73 65 72 74 5f 72 6f 77 69 64 28 64  t_insert_rowid(d
7320: 62 29 3b 0a 20 20 7d 0a 20 20 69 66 28 20 72 63  b);.  }.  if( rc
7330: 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  !=SQLITE_OK ){. 
7340: 20 20 20 74 61 62 2d 3e 7a 45 72 72 4d 73 67 20     tab->zErrMsg 
7350: 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74  = sqlite3_mprint
7360: 66 28 22 65 63 68 6f 2d 76 74 61 62 2d 65 72 72  f("echo-vtab-err
7370: 6f 72 3a 20 25 73 22 2c 20 73 71 6c 69 74 65 33  or: %s", sqlite3
7380: 5f 65 72 72 6d 73 67 28 64 62 29 29 3b 0a 20 20  _errmsg(db));.  
7390: 7d 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a  }..  return rc;.
73a0: 7d 0a 0a 2f 2a 0a 2a 2a 20 78 42 65 67 69 6e 2c  }../*.** xBegin,
73b0: 20 78 53 79 6e 63 2c 20 78 43 6f 6d 6d 69 74 20   xSync, xCommit 
73c0: 61 6e 64 20 78 52 6f 6c 6c 62 61 63 6b 20 63 61  and xRollback ca
73d0: 6c 6c 62 61 63 6b 73 20 66 6f 72 20 65 63 68 6f  llbacks for echo
73e0: 20 6d 6f 64 75 6c 65 0a 2a 2a 20 76 69 72 74 75   module.** virtu
73f0: 61 6c 20 74 61 62 6c 65 73 2e 20 44 6f 20 6e 6f  al tables. Do no
7400: 74 68 69 6e 67 20 6f 74 68 65 72 20 74 68 61 6e  thing other than
7410: 20 61 64 64 20 74 68 65 20 6e 61 6d 65 20 6f 66   add the name of
7420: 20 74 68 65 20 63 61 6c 6c 62 61 63 6b 0a 2a 2a   the callback.**
7430: 20 74 6f 20 74 68 65 20 24 3a 3a 65 63 68 6f 5f   to the $::echo_
7440: 6d 6f 64 75 6c 65 20 54 63 6c 20 76 61 72 69 61  module Tcl varia
7450: 62 6c 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  ble..*/.static i
7460: 6e 74 20 65 63 68 6f 54 72 61 6e 73 61 63 74 69  nt echoTransacti
7470: 6f 6e 43 61 6c 6c 28 73 71 6c 69 74 65 33 5f 76  onCall(sqlite3_v
7480: 74 61 62 20 2a 74 61 62 2c 20 63 6f 6e 73 74 20  tab *tab, const 
7490: 63 68 61 72 20 2a 7a 43 61 6c 6c 29 7b 0a 20 20  char *zCall){.  
74a0: 63 68 61 72 20 2a 7a 3b 0a 20 20 65 63 68 6f 5f  char *z;.  echo_
74b0: 76 74 61 62 20 2a 70 56 74 61 62 20 3d 20 28 65  vtab *pVtab = (e
74c0: 63 68 6f 5f 76 74 61 62 20 2a 29 74 61 62 3b 0a  cho_vtab *)tab;.
74d0: 20 20 7a 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70    z = sqlite3_mp
74e0: 72 69 6e 74 66 28 22 65 63 68 6f 28 25 73 29 22  rintf("echo(%s)"
74f0: 2c 20 70 56 74 61 62 2d 3e 7a 54 61 62 6c 65 4e  , pVtab->zTableN
7500: 61 6d 65 29 3b 0a 20 20 69 66 28 20 7a 3d 3d 30  ame);.  if( z==0
7510: 20 29 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45   ) return SQLITE
7520: 5f 4e 4f 4d 45 4d 3b 0a 20 20 61 70 70 65 6e 64  _NOMEM;.  append
7530: 54 6f 45 63 68 6f 4d 6f 64 75 6c 65 28 70 56 74  ToEchoModule(pVt
7540: 61 62 2d 3e 69 6e 74 65 72 70 2c 20 7a 43 61 6c  ab->interp, zCal
7550: 6c 29 3b 0a 20 20 61 70 70 65 6e 64 54 6f 45 63  l);.  appendToEc
7560: 68 6f 4d 6f 64 75 6c 65 28 70 56 74 61 62 2d 3e  hoModule(pVtab->
7570: 69 6e 74 65 72 70 2c 20 7a 29 3b 0a 20 20 73 71  interp, z);.  sq
7580: 6c 69 74 65 33 5f 66 72 65 65 28 7a 29 3b 0a 20  lite3_free(z);. 
7590: 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f   return SQLITE_O
75a0: 4b 3b 0a 7d 0a 73 74 61 74 69 63 20 69 6e 74 20  K;.}.static int 
75b0: 65 63 68 6f 42 65 67 69 6e 28 73 71 6c 69 74 65  echoBegin(sqlite
75c0: 33 5f 76 74 61 62 20 2a 74 61 62 29 7b 0a 20 20  3_vtab *tab){.  
75d0: 69 6e 74 20 72 63 3b 0a 20 20 65 63 68 6f 5f 76  int rc;.  echo_v
75e0: 74 61 62 20 2a 70 56 74 61 62 20 3d 20 28 65 63  tab *pVtab = (ec
75f0: 68 6f 5f 76 74 61 62 20 2a 29 74 61 62 3b 0a 20  ho_vtab *)tab;. 
7600: 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74   Tcl_Interp *int
7610: 65 72 70 20 3d 20 70 56 74 61 62 2d 3e 69 6e 74  erp = pVtab->int
7620: 65 72 70 3b 0a 20 20 63 6f 6e 73 74 20 63 68 61  erp;.  const cha
7630: 72 20 2a 7a 56 61 6c 3b 20 0a 0a 20 20 2f 2a 20  r *zVal; ..  /* 
7640: 54 69 63 6b 65 74 20 23 33 30 38 33 20 2d 20 64  Ticket #3083 - d
7650: 6f 20 6e 6f 74 20 73 74 61 72 74 20 61 20 74 72  o not start a tr
7660: 61 6e 73 61 63 74 69 6f 6e 20 69 66 20 77 65 20  ansaction if we 
7670: 61 72 65 20 61 6c 72 65 61 64 79 20 69 6e 0a 20  are already in. 
7680: 20 2a 2a 20 61 20 74 72 61 6e 73 61 63 74 69 6f   ** a transactio
7690: 6e 20 2a 2f 0a 20 20 61 73 73 65 72 74 28 20 21  n */.  assert( !
76a0: 70 56 74 61 62 2d 3e 69 6e 54 72 61 6e 73 61 63  pVtab->inTransac
76b0: 74 69 6f 6e 20 29 3b 0a 0a 20 20 69 66 28 20 73  tion );..  if( s
76c0: 69 6d 75 6c 61 74 65 56 74 61 62 45 72 72 6f 72  imulateVtabError
76d0: 28 70 56 74 61 62 2c 20 22 78 42 65 67 69 6e 22  (pVtab, "xBegin"
76e0: 29 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20  ) ){.    return 
76f0: 53 51 4c 49 54 45 5f 45 52 52 4f 52 3b 0a 20 20  SQLITE_ERROR;.  
7700: 7d 0a 0a 20 20 72 63 20 3d 20 65 63 68 6f 54 72  }..  rc = echoTr
7710: 61 6e 73 61 63 74 69 6f 6e 43 61 6c 6c 28 74 61  ansactionCall(ta
7720: 62 2c 20 22 78 42 65 67 69 6e 22 29 3b 0a 0a 20  b, "xBegin");.. 
7730: 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
7740: 4f 4b 20 29 7b 0a 20 20 20 20 2f 2a 20 43 68 65  OK ){.    /* Che
7750: 63 6b 20 69 66 20 74 68 65 20 24 3a 3a 65 63 68  ck if the $::ech
7760: 6f 5f 6d 6f 64 75 6c 65 5f 62 65 67 69 6e 5f 66  o_module_begin_f
7770: 61 69 6c 20 76 61 72 69 61 62 6c 65 20 69 73 20  ail variable is 
7780: 64 65 66 69 6e 65 64 2e 20 49 66 20 69 74 20 69  defined. If it i
7790: 73 2c 0a 20 20 20 20 2a 2a 20 61 6e 64 20 69 74  s,.    ** and it
77a0: 20 69 73 20 73 65 74 20 74 6f 20 74 68 65 20 6e   is set to the n
77b0: 61 6d 65 20 6f 66 20 74 68 65 20 72 65 61 6c 20  ame of the real 
77c0: 74 61 62 6c 65 20 75 6e 64 65 72 6c 79 69 6e 67  table underlying
77d0: 20 74 68 69 73 20 76 69 72 74 75 61 6c 0a 20 20   this virtual.  
77e0: 20 20 2a 2a 20 65 63 68 6f 20 6d 6f 64 75 6c 65    ** echo module
77f0: 20 74 61 62 6c 65 2c 20 74 68 65 6e 20 63 61 75   table, then cau
7800: 73 65 20 74 68 69 73 20 78 53 79 6e 63 20 6f 70  se this xSync op
7810: 65 72 61 74 69 6f 6e 20 74 6f 20 66 61 69 6c 2e  eration to fail.
7820: 0a 20 20 20 20 2a 2f 0a 20 20 20 20 7a 56 61 6c  .    */.    zVal
7830: 20 3d 20 54 63 6c 5f 47 65 74 56 61 72 28 69 6e   = Tcl_GetVar(in
7840: 74 65 72 70 2c 20 22 65 63 68 6f 5f 6d 6f 64 75  terp, "echo_modu
7850: 6c 65 5f 62 65 67 69 6e 5f 66 61 69 6c 22 2c 20  le_begin_fail", 
7860: 54 43 4c 5f 47 4c 4f 42 41 4c 5f 4f 4e 4c 59 29  TCL_GLOBAL_ONLY)
7870: 3b 0a 20 20 20 20 69 66 28 20 7a 56 61 6c 20 26  ;.    if( zVal &
7880: 26 20 30 3d 3d 73 74 72 63 6d 70 28 7a 56 61 6c  & 0==strcmp(zVal
7890: 2c 20 70 56 74 61 62 2d 3e 7a 54 61 62 6c 65 4e  , pVtab->zTableN
78a0: 61 6d 65 29 20 29 7b 0a 20 20 20 20 20 20 72 63  ame) ){.      rc
78b0: 20 3d 20 53 51 4c 49 54 45 5f 45 52 52 4f 52 3b   = SQLITE_ERROR;
78c0: 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 69 66 28  .    }.  }.  if(
78d0: 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc==SQLITE_OK )
78e0: 7b 0a 20 20 20 20 70 56 74 61 62 2d 3e 69 6e 54  {.    pVtab->inT
78f0: 72 61 6e 73 61 63 74 69 6f 6e 20 3d 20 31 3b 0a  ransaction = 1;.
7900: 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 72 63 3b    }.  return rc;
7910: 0a 7d 0a 73 74 61 74 69 63 20 69 6e 74 20 65 63  .}.static int ec
7920: 68 6f 53 79 6e 63 28 73 71 6c 69 74 65 33 5f 76  hoSync(sqlite3_v
7930: 74 61 62 20 2a 74 61 62 29 7b 0a 20 20 69 6e 74  tab *tab){.  int
7940: 20 72 63 3b 0a 20 20 65 63 68 6f 5f 76 74 61 62   rc;.  echo_vtab
7950: 20 2a 70 56 74 61 62 20 3d 20 28 65 63 68 6f 5f   *pVtab = (echo_
7960: 76 74 61 62 20 2a 29 74 61 62 3b 0a 20 20 54 63  vtab *)tab;.  Tc
7970: 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70  l_Interp *interp
7980: 20 3d 20 70 56 74 61 62 2d 3e 69 6e 74 65 72 70   = pVtab->interp
7990: 3b 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a  ;.  const char *
79a0: 7a 56 61 6c 3b 20 0a 0a 20 20 2f 2a 20 54 69 63  zVal; ..  /* Tic
79b0: 6b 65 74 20 23 33 30 38 33 20 2d 20 4f 6e 6c 79  ket #3083 - Only
79c0: 20 63 61 6c 6c 20 78 53 79 6e 63 20 69 66 20 77   call xSync if w
79d0: 65 20 68 61 76 65 20 70 72 65 76 69 6f 75 73 6c  e have previousl
79e0: 79 20 73 74 61 72 74 65 64 20 61 0a 20 20 2a 2a  y started a.  **
79f0: 20 74 72 61 6e 73 61 63 74 69 6f 6e 20 2a 2f 0a   transaction */.
7a00: 20 20 61 73 73 65 72 74 28 20 70 56 74 61 62 2d    assert( pVtab-
7a10: 3e 69 6e 54 72 61 6e 73 61 63 74 69 6f 6e 20 29  >inTransaction )
7a20: 3b 0a 0a 20 20 69 66 28 20 73 69 6d 75 6c 61 74  ;..  if( simulat
7a30: 65 56 74 61 62 45 72 72 6f 72 28 70 56 74 61 62  eVtabError(pVtab
7a40: 2c 20 22 78 53 79 6e 63 22 29 20 29 7b 0a 20 20  , "xSync") ){.  
7a50: 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f    return SQLITE_
7a60: 45 52 52 4f 52 3b 0a 20 20 7d 0a 0a 20 20 72 63  ERROR;.  }..  rc
7a70: 20 3d 20 65 63 68 6f 54 72 61 6e 73 61 63 74 69   = echoTransacti
7a80: 6f 6e 43 61 6c 6c 28 74 61 62 2c 20 22 78 53 79  onCall(tab, "xSy
7a90: 6e 63 22 29 3b 0a 0a 20 20 69 66 28 20 72 63 3d  nc");..  if( rc=
7aa0: 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20  =SQLITE_OK ){.  
7ab0: 20 20 2f 2a 20 43 68 65 63 6b 20 69 66 20 74 68    /* Check if th
7ac0: 65 20 24 3a 3a 65 63 68 6f 5f 6d 6f 64 75 6c 65  e $::echo_module
7ad0: 5f 73 79 6e 63 5f 66 61 69 6c 20 76 61 72 69 61  _sync_fail varia
7ae0: 62 6c 65 20 69 73 20 64 65 66 69 6e 65 64 2e 20  ble is defined. 
7af0: 49 66 20 69 74 20 69 73 2c 0a 20 20 20 20 2a 2a  If it is,.    **
7b00: 20 61 6e 64 20 69 74 20 69 73 20 73 65 74 20 74   and it is set t
7b10: 6f 20 74 68 65 20 6e 61 6d 65 20 6f 66 20 74 68  o the name of th
7b20: 65 20 72 65 61 6c 20 74 61 62 6c 65 20 75 6e 64  e real table und
7b30: 65 72 6c 79 69 6e 67 20 74 68 69 73 20 76 69 72  erlying this vir
7b40: 74 75 61 6c 0a 20 20 20 20 2a 2a 20 65 63 68 6f  tual.    ** echo
7b50: 20 6d 6f 64 75 6c 65 20 74 61 62 6c 65 2c 20 74   module table, t
7b60: 68 65 6e 20 63 61 75 73 65 20 74 68 69 73 20 78  hen cause this x
7b70: 53 79 6e 63 20 6f 70 65 72 61 74 69 6f 6e 20 74  Sync operation t
7b80: 6f 20 66 61 69 6c 2e 0a 20 20 20 20 2a 2f 0a 20  o fail..    */. 
7b90: 20 20 20 7a 56 61 6c 20 3d 20 54 63 6c 5f 47 65     zVal = Tcl_Ge
7ba0: 74 56 61 72 28 69 6e 74 65 72 70 2c 20 22 65 63  tVar(interp, "ec
7bb0: 68 6f 5f 6d 6f 64 75 6c 65 5f 73 79 6e 63 5f 66  ho_module_sync_f
7bc0: 61 69 6c 22 2c 20 54 43 4c 5f 47 4c 4f 42 41 4c  ail", TCL_GLOBAL
7bd0: 5f 4f 4e 4c 59 29 3b 0a 20 20 20 20 69 66 28 20  _ONLY);.    if( 
7be0: 7a 56 61 6c 20 26 26 20 30 3d 3d 73 74 72 63 6d  zVal && 0==strcm
7bf0: 70 28 7a 56 61 6c 2c 20 70 56 74 61 62 2d 3e 7a  p(zVal, pVtab->z
7c00: 54 61 62 6c 65 4e 61 6d 65 29 20 29 7b 0a 20 20  TableName) ){.  
7c10: 20 20 20 20 72 63 20 3d 20 2d 31 3b 0a 20 20 20      rc = -1;.   
7c20: 20 7d 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20   }.  }.  return 
7c30: 72 63 3b 0a 7d 0a 73 74 61 74 69 63 20 69 6e 74  rc;.}.static int
7c40: 20 65 63 68 6f 43 6f 6d 6d 69 74 28 73 71 6c 69   echoCommit(sqli
7c50: 74 65 33 5f 76 74 61 62 20 2a 74 61 62 29 7b 0a  te3_vtab *tab){.
7c60: 20 20 65 63 68 6f 5f 76 74 61 62 20 2a 70 56 74    echo_vtab *pVt
7c70: 61 62 20 3d 20 28 65 63 68 6f 5f 76 74 61 62 2a  ab = (echo_vtab*
7c80: 29 74 61 62 3b 0a 20 20 69 6e 74 20 72 63 3b 0a  )tab;.  int rc;.
7c90: 0a 20 20 2f 2a 20 54 69 63 6b 65 74 20 23 33 30  .  /* Ticket #30
7ca0: 38 33 20 2d 20 4f 6e 6c 79 20 63 61 6c 6c 20 78  83 - Only call x
7cb0: 43 6f 6d 6d 69 74 20 69 66 20 77 65 20 68 61 76  Commit if we hav
7cc0: 65 20 70 72 65 76 69 6f 75 73 6c 79 20 73 74 61  e previously sta
7cd0: 72 74 65 64 0a 20 20 2a 2a 20 61 20 74 72 61 6e  rted.  ** a tran
7ce0: 73 61 63 74 69 6f 6e 20 2a 2f 0a 20 20 61 73 73  saction */.  ass
7cf0: 65 72 74 28 20 70 56 74 61 62 2d 3e 69 6e 54 72  ert( pVtab->inTr
7d00: 61 6e 73 61 63 74 69 6f 6e 20 29 3b 0a 0a 20 20  ansaction );..  
7d10: 69 66 28 20 73 69 6d 75 6c 61 74 65 56 74 61 62  if( simulateVtab
7d20: 45 72 72 6f 72 28 70 56 74 61 62 2c 20 22 78 43  Error(pVtab, "xC
7d30: 6f 6d 6d 69 74 22 29 20 29 7b 0a 20 20 20 20 72  ommit") ){.    r
7d40: 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 45 52 52  eturn SQLITE_ERR
7d50: 4f 52 3b 0a 20 20 7d 0a 0a 20 20 73 71 6c 69 74  OR;.  }..  sqlit
7d60: 65 33 42 65 67 69 6e 42 65 6e 69 67 6e 4d 61 6c  e3BeginBenignMal
7d70: 6c 6f 63 28 29 3b 0a 20 20 72 63 20 3d 20 65 63  loc();.  rc = ec
7d80: 68 6f 54 72 61 6e 73 61 63 74 69 6f 6e 43 61 6c  hoTransactionCal
7d90: 6c 28 74 61 62 2c 20 22 78 43 6f 6d 6d 69 74 22  l(tab, "xCommit"
7da0: 29 3b 0a 20 20 73 71 6c 69 74 65 33 45 6e 64 42  );.  sqlite3EndB
7db0: 65 6e 69 67 6e 4d 61 6c 6c 6f 63 28 29 3b 0a 20  enignMalloc();. 
7dc0: 20 70 56 74 61 62 2d 3e 69 6e 54 72 61 6e 73 61   pVtab->inTransa
7dd0: 63 74 69 6f 6e 20 3d 20 30 3b 0a 20 20 72 65 74  ction = 0;.  ret
7de0: 75 72 6e 20 72 63 3b 0a 7d 0a 73 74 61 74 69 63  urn rc;.}.static
7df0: 20 69 6e 74 20 65 63 68 6f 52 6f 6c 6c 62 61 63   int echoRollbac
7e00: 6b 28 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a  k(sqlite3_vtab *
7e10: 74 61 62 29 7b 0a 20 20 69 6e 74 20 72 63 3b 0a  tab){.  int rc;.
7e20: 20 20 65 63 68 6f 5f 76 74 61 62 20 2a 70 56 74    echo_vtab *pVt
7e30: 61 62 20 3d 20 28 65 63 68 6f 5f 76 74 61 62 2a  ab = (echo_vtab*
7e40: 29 74 61 62 3b 0a 0a 20 20 2f 2a 20 54 69 63 6b  )tab;..  /* Tick
7e50: 65 74 20 23 33 30 38 33 20 2d 20 4f 6e 6c 79 20  et #3083 - Only 
7e60: 63 61 6c 6c 20 78 52 6f 6c 6c 62 61 63 6b 20 69  call xRollback i
7e70: 66 20 77 65 20 68 61 76 65 20 70 72 65 76 69 6f  f we have previo
7e80: 75 73 6c 79 20 73 74 61 72 74 65 64 0a 20 20 2a  usly started.  *
7e90: 2a 20 61 20 74 72 61 6e 73 61 63 74 69 6f 6e 20  * a transaction 
7ea0: 2a 2f 0a 20 20 61 73 73 65 72 74 28 20 70 56 74  */.  assert( pVt
7eb0: 61 62 2d 3e 69 6e 54 72 61 6e 73 61 63 74 69 6f  ab->inTransactio
7ec0: 6e 20 29 3b 0a 0a 20 20 72 63 20 3d 20 65 63 68  n );..  rc = ech
7ed0: 6f 54 72 61 6e 73 61 63 74 69 6f 6e 43 61 6c 6c  oTransactionCall
7ee0: 28 74 61 62 2c 20 22 78 52 6f 6c 6c 62 61 63 6b  (tab, "xRollback
7ef0: 22 29 3b 0a 20 20 70 56 74 61 62 2d 3e 69 6e 54  ");.  pVtab->inT
7f00: 72 61 6e 73 61 63 74 69 6f 6e 20 3d 20 30 3b 0a  ransaction = 0;.
7f10: 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a    return rc;.}..
7f20: 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74 61  /*.** Implementa
7f30: 74 69 6f 6e 20 6f 66 20 22 47 4c 4f 42 22 20 66  tion of "GLOB" f
7f40: 75 6e 63 74 69 6f 6e 20 6f 6e 20 74 68 65 20 65  unction on the e
7f50: 63 68 6f 20 6d 6f 64 75 6c 65 2e 20 20 50 61 73  cho module.  Pas
7f60: 73 0a 2a 2a 20 61 6c 6c 20 61 72 67 75 6d 65 6e  s.** all argumen
7f70: 74 73 20 74 6f 20 74 68 65 20 3a 3a 65 63 68 6f  ts to the ::echo
7f80: 5f 67 6c 6f 62 5f 6f 76 65 72 6c 6f 61 64 20 70  _glob_overload p
7f90: 72 6f 63 65 64 75 72 65 20 6f 66 20 54 43 4c 0a  rocedure of TCL.
7fa0: 2a 2a 20 61 6e 64 20 72 65 74 75 72 6e 20 74 68  ** and return th
7fb0: 65 20 72 65 73 75 6c 74 20 6f 66 20 74 68 61 74  e result of that
7fc0: 20 70 72 6f 63 65 64 75 72 65 20 61 73 20 61 20   procedure as a 
7fd0: 73 74 72 69 6e 67 2e 0a 2a 2f 0a 73 74 61 74 69  string..*/.stati
7fe0: 63 20 76 6f 69 64 20 6f 76 65 72 6c 6f 61 64 65  c void overloade
7ff0: 64 47 6c 6f 62 46 75 6e 63 74 69 6f 6e 28 0a 20  dGlobFunction(. 
8000: 20 73 71 6c 69 74 65 33 5f 63 6f 6e 74 65 78 74   sqlite3_context
8010: 20 2a 70 43 6f 6e 74 65 78 74 2c 0a 20 20 69 6e   *pContext,.  in
8020: 74 20 6e 41 72 67 2c 0a 20 20 73 71 6c 69 74 65  t nArg,.  sqlite
8030: 33 5f 76 61 6c 75 65 20 2a 2a 61 70 41 72 67 0a  3_value **apArg.
8040: 29 7b 0a 20 20 54 63 6c 5f 49 6e 74 65 72 70 20  ){.  Tcl_Interp 
8050: 2a 69 6e 74 65 72 70 20 3d 20 73 71 6c 69 74 65  *interp = sqlite
8060: 33 5f 75 73 65 72 5f 64 61 74 61 28 70 43 6f 6e  3_user_data(pCon
8070: 74 65 78 74 29 3b 0a 20 20 54 63 6c 5f 44 53 74  text);.  Tcl_DSt
8080: 72 69 6e 67 20 73 74 72 3b 0a 20 20 69 6e 74 20  ring str;.  int 
8090: 69 3b 0a 20 20 69 6e 74 20 72 63 3b 0a 20 20 54  i;.  int rc;.  T
80a0: 63 6c 5f 44 53 74 72 69 6e 67 49 6e 69 74 28 26  cl_DStringInit(&
80b0: 73 74 72 29 3b 0a 20 20 54 63 6c 5f 44 53 74 72  str);.  Tcl_DStr
80c0: 69 6e 67 41 70 70 65 6e 64 45 6c 65 6d 65 6e 74  ingAppendElement
80d0: 28 26 73 74 72 2c 20 22 3a 3a 65 63 68 6f 5f 67  (&str, "::echo_g
80e0: 6c 6f 62 5f 6f 76 65 72 6c 6f 61 64 22 29 3b 0a  lob_overload");.
80f0: 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 6e 41 72    for(i=0; i<nAr
8100: 67 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 54 63 6c  g; i++){.    Tcl
8110: 5f 44 53 74 72 69 6e 67 41 70 70 65 6e 64 45 6c  _DStringAppendEl
8120: 65 6d 65 6e 74 28 26 73 74 72 2c 20 28 63 68 61  ement(&str, (cha
8130: 72 2a 29 73 71 6c 69 74 65 33 5f 76 61 6c 75 65  r*)sqlite3_value
8140: 5f 74 65 78 74 28 61 70 41 72 67 5b 69 5d 29 29  _text(apArg[i]))
8150: 3b 0a 20 20 7d 0a 20 20 72 63 20 3d 20 54 63 6c  ;.  }.  rc = Tcl
8160: 5f 45 76 61 6c 28 69 6e 74 65 72 70 2c 20 54 63  _Eval(interp, Tc
8170: 6c 5f 44 53 74 72 69 6e 67 56 61 6c 75 65 28 26  l_DStringValue(&
8180: 73 74 72 29 29 3b 0a 20 20 54 63 6c 5f 44 53 74  str));.  Tcl_DSt
8190: 72 69 6e 67 46 72 65 65 28 26 73 74 72 29 3b 0a  ringFree(&str);.
81a0: 20 20 69 66 28 20 72 63 20 29 7b 0a 20 20 20 20    if( rc ){.    
81b0: 73 71 6c 69 74 65 33 5f 72 65 73 75 6c 74 5f 65  sqlite3_result_e
81c0: 72 72 6f 72 28 70 43 6f 6e 74 65 78 74 2c 20 54  rror(pContext, T
81d0: 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75  cl_GetStringResu
81e0: 6c 74 28 69 6e 74 65 72 70 29 2c 20 2d 31 29 3b  lt(interp), -1);
81f0: 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 73 71  .  }else{.    sq
8200: 6c 69 74 65 33 5f 72 65 73 75 6c 74 5f 74 65 78  lite3_result_tex
8210: 74 28 70 43 6f 6e 74 65 78 74 2c 20 54 63 6c 5f  t(pContext, Tcl_
8220: 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28  GetStringResult(
8230: 69 6e 74 65 72 70 29 2c 0a 20 20 20 20 20 20 20  interp),.       
8240: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8250: 20 2d 31 2c 20 53 51 4c 49 54 45 5f 54 52 41 4e   -1, SQLITE_TRAN
8260: 53 49 45 4e 54 29 3b 0a 20 20 7d 0a 20 20 54 63  SIENT);.  }.  Tc
8270: 6c 5f 52 65 73 65 74 52 65 73 75 6c 74 28 69 6e  l_ResetResult(in
8280: 74 65 72 70 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  terp);.}../*.** 
8290: 54 68 69 73 20 69 73 20 74 68 65 20 78 46 69 6e  This is the xFin
82a0: 64 46 75 6e 63 74 69 6f 6e 20 69 6d 70 6c 65 6d  dFunction implem
82b0: 65 6e 74 61 74 69 6f 6e 20 66 6f 72 20 74 68 65  entation for the
82c0: 20 65 63 68 6f 20 6d 6f 64 75 6c 65 2e 0a 2a 2a   echo module..**
82d0: 20 53 51 4c 69 74 65 20 63 61 6c 6c 73 20 74 68   SQLite calls th
82e0: 69 73 20 72 6f 75 74 69 6e 65 20 77 68 65 6e 20  is routine when 
82f0: 74 68 65 20 66 69 72 73 74 20 61 72 67 75 6d 65  the first argume
8300: 6e 74 20 6f 66 20 61 20 66 75 6e 63 74 69 6f 6e  nt of a function
8310: 0a 2a 2a 20 69 73 20 61 20 63 6f 6c 75 6d 6e 20  .** is a column 
8320: 6f 66 20 61 6e 20 65 63 68 6f 20 76 69 72 74 75  of an echo virtu
8330: 61 6c 20 74 61 62 6c 65 2e 20 20 54 68 69 73 20  al table.  This 
8340: 72 6f 75 74 69 6e 65 20 63 61 6e 20 6f 70 74 69  routine can opti
8350: 6f 6e 61 6c 6c 79 0a 2a 2a 20 6f 76 65 72 72 69  onally.** overri
8360: 64 65 20 74 68 65 20 69 6d 70 6c 65 6d 65 6e 74  de the implement
8370: 61 74 69 6f 6e 20 6f 66 20 74 68 61 74 20 66 75  ation of that fu
8380: 6e 63 74 69 6f 6e 2e 20 20 49 74 20 77 69 6c 6c  nction.  It will
8390: 20 63 68 6f 6f 73 65 20 74 6f 0a 2a 2a 20 64 6f   choose to.** do
83a0: 20 73 6f 20 69 66 20 74 68 65 20 66 75 6e 63 74   so if the funct
83b0: 69 6f 6e 20 69 73 20 6e 61 6d 65 64 20 22 67 6c  ion is named "gl
83c0: 6f 62 22 2c 20 61 6e 64 20 61 20 54 43 4c 20 63  ob", and a TCL c
83d0: 6f 6d 6d 61 6e 64 20 6e 61 6d 65 64 0a 2a 2a 20  ommand named.** 
83e0: 3a 3a 65 63 68 6f 5f 67 6c 6f 62 5f 6f 76 65 72  ::echo_glob_over
83f0: 6c 6f 61 64 20 65 78 69 73 74 73 2e 0a 2a 2f 0a  load exists..*/.
8400: 73 74 61 74 69 63 20 69 6e 74 20 65 63 68 6f 46  static int echoF
8410: 69 6e 64 46 75 6e 63 74 69 6f 6e 28 0a 20 20 73  indFunction(.  s
8420: 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 76 74 61  qlite3_vtab *vta
8430: 62 2c 0a 20 20 69 6e 74 20 6e 41 72 67 2c 0a 20  b,.  int nArg,. 
8440: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 46 75   const char *zFu
8450: 6e 63 4e 61 6d 65 2c 0a 20 20 76 6f 69 64 20 28  ncName,.  void (
8460: 2a 2a 70 78 46 75 6e 63 29 28 73 71 6c 69 74 65  **pxFunc)(sqlite
8470: 33 5f 63 6f 6e 74 65 78 74 2a 2c 69 6e 74 2c 73  3_context*,int,s
8480: 71 6c 69 74 65 33 5f 76 61 6c 75 65 2a 2a 29 2c  qlite3_value**),
8490: 0a 20 20 76 6f 69 64 20 2a 2a 70 70 41 72 67 0a  .  void **ppArg.
84a0: 29 7b 0a 20 20 65 63 68 6f 5f 76 74 61 62 20 2a  ){.  echo_vtab *
84b0: 70 56 74 61 62 20 3d 20 28 65 63 68 6f 5f 76 74  pVtab = (echo_vt
84c0: 61 62 20 2a 29 76 74 61 62 3b 0a 20 20 54 63 6c  ab *)vtab;.  Tcl
84d0: 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 20  _Interp *interp 
84e0: 3d 20 70 56 74 61 62 2d 3e 69 6e 74 65 72 70 3b  = pVtab->interp;
84f0: 0a 20 20 54 63 6c 5f 43 6d 64 49 6e 66 6f 20 69  .  Tcl_CmdInfo i
8500: 6e 66 6f 3b 0a 20 20 69 66 28 20 73 74 72 63 6d  nfo;.  if( strcm
8510: 70 28 7a 46 75 6e 63 4e 61 6d 65 2c 22 67 6c 6f  p(zFuncName,"glo
8520: 62 22 29 21 3d 30 20 29 7b 0a 20 20 20 20 72 65  b")!=0 ){.    re
8530: 74 75 72 6e 20 30 3b 0a 20 20 7d 0a 20 20 69 66  turn 0;.  }.  if
8540: 28 20 54 63 6c 5f 47 65 74 43 6f 6d 6d 61 6e 64  ( Tcl_GetCommand
8550: 49 6e 66 6f 28 69 6e 74 65 72 70 2c 20 22 3a 3a  Info(interp, "::
8560: 65 63 68 6f 5f 67 6c 6f 62 5f 6f 76 65 72 6c 6f  echo_glob_overlo
8570: 61 64 22 2c 20 26 69 6e 66 6f 29 3d 3d 30 20 29  ad", &info)==0 )
8580: 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 30 3b 0a  {.    return 0;.
8590: 20 20 7d 0a 20 20 2a 70 78 46 75 6e 63 20 3d 20    }.  *pxFunc = 
85a0: 6f 76 65 72 6c 6f 61 64 65 64 47 6c 6f 62 46 75  overloadedGlobFu
85b0: 6e 63 74 69 6f 6e 3b 0a 20 20 2a 70 70 41 72 67  nction;.  *ppArg
85c0: 20 3d 20 69 6e 74 65 72 70 3b 0a 20 20 72 65 74   = interp;.  ret
85d0: 75 72 6e 20 31 3b 0a 7d 0a 0a 73 74 61 74 69 63  urn 1;.}..static
85e0: 20 69 6e 74 20 65 63 68 6f 52 65 6e 61 6d 65 28   int echoRename(
85f0: 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 76 74  sqlite3_vtab *vt
8600: 61 62 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a  ab, const char *
8610: 7a 4e 65 77 4e 61 6d 65 29 7b 0a 20 20 69 6e 74  zNewName){.  int
8620: 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b   rc = SQLITE_OK;
8630: 0a 20 20 65 63 68 6f 5f 76 74 61 62 20 2a 70 20  .  echo_vtab *p 
8640: 3d 20 28 65 63 68 6f 5f 76 74 61 62 20 2a 29 76  = (echo_vtab *)v
8650: 74 61 62 3b 0a 0a 20 20 69 66 28 20 73 69 6d 75  tab;..  if( simu
8660: 6c 61 74 65 56 74 61 62 45 72 72 6f 72 28 70 2c  lateVtabError(p,
8670: 20 22 78 52 65 6e 61 6d 65 22 29 20 29 7b 0a 20   "xRename") ){. 
8680: 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45     return SQLITE
8690: 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a 0a 20 20 69  _ERROR;.  }..  i
86a0: 66 28 20 70 2d 3e 69 73 50 61 74 74 65 72 6e 20  f( p->isPattern 
86b0: 29 7b 0a 20 20 20 20 69 6e 74 20 6e 54 68 69 73  ){.    int nThis
86c0: 20 3d 20 73 74 72 6c 65 6e 28 70 2d 3e 7a 54 68   = strlen(p->zTh
86d0: 69 73 29 3b 0a 20 20 20 20 63 68 61 72 20 2a 7a  is);.    char *z
86e0: 53 71 6c 20 3d 20 73 71 6c 69 74 65 33 4d 50 72  Sql = sqlite3MPr
86f0: 69 6e 74 66 28 30 2c 20 22 41 4c 54 45 52 20 54  intf(0, "ALTER T
8700: 41 42 4c 45 20 25 73 20 52 45 4e 41 4d 45 20 54  ABLE %s RENAME T
8710: 4f 20 25 73 25 73 22 2c 20 0a 20 20 20 20 20 20  O %s%s", .      
8720: 20 20 70 2d 3e 7a 54 61 62 6c 65 4e 61 6d 65 2c    p->zTableName,
8730: 20 7a 4e 65 77 4e 61 6d 65 2c 20 26 70 2d 3e 7a   zNewName, &p->z
8740: 54 61 62 6c 65 4e 61 6d 65 5b 6e 54 68 69 73 5d  TableName[nThis]
8750: 0a 20 20 20 20 29 3b 0a 20 20 20 20 72 63 20 3d  .    );.    rc =
8760: 20 73 71 6c 69 74 65 33 5f 65 78 65 63 28 70 2d   sqlite3_exec(p-
8770: 3e 64 62 2c 20 7a 53 71 6c 2c 20 30 2c 20 30 2c  >db, zSql, 0, 0,
8780: 20 30 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33   0);.    sqlite3
8790: 5f 66 72 65 65 28 7a 53 71 6c 29 3b 0a 20 20 7d  _free(zSql);.  }
87a0: 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d  ..  return rc;.}
87b0: 0a 0a 2f 2a 0a 2a 2a 20 41 20 76 69 72 74 75 61  ../*.** A virtua
87c0: 6c 20 74 61 62 6c 65 20 6d 6f 64 75 6c 65 20 74  l table module t
87d0: 68 61 74 20 6d 65 72 65 6c 79 20 22 65 63 68 6f  hat merely "echo
87e0: 73 22 20 74 68 65 20 63 6f 6e 74 65 6e 74 73 20  s" the contents 
87f0: 6f 66 20 61 6e 6f 74 68 65 72 0a 2a 2a 20 74 61  of another.** ta
8800: 62 6c 65 20 28 6c 69 6b 65 20 61 6e 20 53 51 4c  ble (like an SQL
8810: 20 56 49 45 57 29 2e 0a 2a 2f 0a 73 74 61 74 69   VIEW)..*/.stati
8820: 63 20 73 71 6c 69 74 65 33 5f 6d 6f 64 75 6c 65  c sqlite3_module
8830: 20 65 63 68 6f 4d 6f 64 75 6c 65 20 3d 20 7b 0a   echoModule = {.
8840: 20 20 30 2c 20 20 20 20 20 20 20 20 20 20 20 20    0,            
8850: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
8860: 69 56 65 72 73 69 6f 6e 20 2a 2f 0a 20 20 65 63  iVersion */.  ec
8870: 68 6f 43 72 65 61 74 65 2c 0a 20 20 65 63 68 6f  hoCreate,.  echo
8880: 43 6f 6e 6e 65 63 74 2c 0a 20 20 65 63 68 6f 42  Connect,.  echoB
8890: 65 73 74 49 6e 64 65 78 2c 0a 20 20 65 63 68 6f  estIndex,.  echo
88a0: 44 69 73 63 6f 6e 6e 65 63 74 2c 20 0a 20 20 65  Disconnect, .  e
88b0: 63 68 6f 44 65 73 74 72 6f 79 2c 0a 20 20 65 63  choDestroy,.  ec
88c0: 68 6f 4f 70 65 6e 2c 20 20 20 20 20 20 20 20 20  hoOpen,         
88d0: 20 20 20 20 20 20 20 20 20 2f 2a 20 78 4f 70 65           /* xOpe
88e0: 6e 20 2d 20 6f 70 65 6e 20 61 20 63 75 72 73 6f  n - open a curso
88f0: 72 20 2a 2f 0a 20 20 65 63 68 6f 43 6c 6f 73 65  r */.  echoClose
8900: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
8910: 20 20 2f 2a 20 78 43 6c 6f 73 65 20 2d 20 63 6c    /* xClose - cl
8920: 6f 73 65 20 61 20 63 75 72 73 6f 72 20 2a 2f 0a  ose a cursor */.
8930: 20 20 65 63 68 6f 46 69 6c 74 65 72 2c 20 20 20    echoFilter,   
8940: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
8950: 78 46 69 6c 74 65 72 20 2d 20 63 6f 6e 66 69 67  xFilter - config
8960: 75 72 65 20 73 63 61 6e 20 63 6f 6e 73 74 72 61  ure scan constra
8970: 69 6e 74 73 20 2a 2f 0a 20 20 65 63 68 6f 4e 65  ints */.  echoNe
8980: 78 74 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  xt,             
8990: 20 20 20 20 20 2f 2a 20 78 4e 65 78 74 20 2d 20       /* xNext - 
89a0: 61 64 76 61 6e 63 65 20 61 20 63 75 72 73 6f 72  advance a cursor
89b0: 20 2a 2f 0a 20 20 65 63 68 6f 45 6f 66 2c 20 20   */.  echoEof,  
89c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
89d0: 20 2f 2a 20 78 45 6f 66 20 2a 2f 0a 20 20 65 63   /* xEof */.  ec
89e0: 68 6f 43 6f 6c 75 6d 6e 2c 20 20 20 20 20 20 20  hoColumn,       
89f0: 20 20 20 20 20 20 20 20 20 2f 2a 20 78 43 6f 6c           /* xCol
8a00: 75 6d 6e 20 2d 20 72 65 61 64 20 64 61 74 61 20  umn - read data 
8a10: 2a 2f 0a 20 20 65 63 68 6f 52 6f 77 69 64 2c 20  */.  echoRowid, 
8a20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8a30: 2f 2a 20 78 52 6f 77 69 64 20 2d 20 72 65 61 64  /* xRowid - read
8a40: 20 64 61 74 61 20 2a 2f 0a 20 20 65 63 68 6f 55   data */.  echoU
8a50: 70 64 61 74 65 2c 20 20 20 20 20 20 20 20 20 20  pdate,          
8a60: 20 20 20 20 20 20 2f 2a 20 78 55 70 64 61 74 65        /* xUpdate
8a70: 20 2d 20 77 72 69 74 65 20 64 61 74 61 20 2a 2f   - write data */
8a80: 0a 20 20 65 63 68 6f 42 65 67 69 6e 2c 20 20 20  .  echoBegin,   
8a90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
8aa0: 20 78 42 65 67 69 6e 20 2d 20 62 65 67 69 6e 20   xBegin - begin 
8ab0: 74 72 61 6e 73 61 63 74 69 6f 6e 20 2a 2f 0a 20  transaction */. 
8ac0: 20 65 63 68 6f 53 79 6e 63 2c 20 20 20 20 20 20   echoSync,      
8ad0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78              /* x
8ae0: 53 79 6e 63 20 2d 20 73 79 6e 63 20 74 72 61 6e  Sync - sync tran
8af0: 73 61 63 74 69 6f 6e 20 2a 2f 0a 20 20 65 63 68  saction */.  ech
8b00: 6f 43 6f 6d 6d 69 74 2c 20 20 20 20 20 20 20 20  oCommit,        
8b10: 20 20 20 20 20 20 20 20 2f 2a 20 78 43 6f 6d 6d          /* xComm
8b20: 69 74 20 2d 20 63 6f 6d 6d 69 74 20 74 72 61 6e  it - commit tran
8b30: 73 61 63 74 69 6f 6e 20 2a 2f 0a 20 20 65 63 68  saction */.  ech
8b40: 6f 52 6f 6c 6c 62 61 63 6b 2c 20 20 20 20 20 20  oRollback,      
8b50: 20 20 20 20 20 20 20 20 2f 2a 20 78 52 6f 6c 6c          /* xRoll
8b60: 62 61 63 6b 20 2d 20 72 6f 6c 6c 62 61 63 6b 20  back - rollback 
8b70: 74 72 61 6e 73 61 63 74 69 6f 6e 20 2a 2f 0a 20  transaction */. 
8b80: 20 65 63 68 6f 46 69 6e 64 46 75 6e 63 74 69 6f   echoFindFunctio
8b90: 6e 2c 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78  n,          /* x
8ba0: 46 69 6e 64 46 75 6e 63 74 69 6f 6e 20 2d 20 66  FindFunction - f
8bb0: 75 6e 63 74 69 6f 6e 20 6f 76 65 72 6c 6f 61 64  unction overload
8bc0: 69 6e 67 20 2a 2f 0a 20 20 65 63 68 6f 52 65 6e  ing */.  echoRen
8bd0: 61 6d 65 2c 20 20 20 20 20 20 20 20 20 20 20 20  ame,            
8be0: 20 20 20 20 2f 2a 20 78 52 65 6e 61 6d 65 20 2d      /* xRename -
8bf0: 20 72 65 6e 61 6d 65 20 74 68 65 20 74 61 62 6c   rename the tabl
8c00: 65 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 44  e */.};../*.** D
8c10: 65 63 6f 64 65 20 61 20 70 6f 69 6e 74 65 72 20  ecode a pointer 
8c20: 74 6f 20 61 6e 20 73 71 6c 69 74 65 33 20 6f 62  to an sqlite3 ob
8c30: 6a 65 63 74 2e 0a 2a 2f 0a 65 78 74 65 72 6e 20  ject..*/.extern 
8c40: 69 6e 74 20 67 65 74 44 62 50 6f 69 6e 74 65 72  int getDbPointer
8c50: 28 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74  (Tcl_Interp *int
8c60: 65 72 70 2c 20 63 6f 6e 73 74 20 63 68 61 72 20  erp, const char 
8c70: 2a 7a 41 2c 20 73 71 6c 69 74 65 33 20 2a 2a 70  *zA, sqlite3 **p
8c80: 70 44 62 29 3b 0a 0a 73 74 61 74 69 63 20 76 6f  pDb);..static vo
8c90: 69 64 20 6d 6f 64 75 6c 65 44 65 73 74 72 6f 79  id moduleDestroy
8ca0: 28 76 6f 69 64 20 2a 70 29 7b 0a 20 20 73 71 6c  (void *p){.  sql
8cb0: 69 74 65 33 5f 66 72 65 65 28 70 29 3b 0a 7d 0a  ite3_free(p);.}.
8cc0: 0a 2f 2a 0a 2a 2a 20 52 65 67 69 73 74 65 72 20  ./*.** Register 
8cd0: 74 68 65 20 65 63 68 6f 20 76 69 72 74 75 61 6c  the echo virtual
8ce0: 20 74 61 62 6c 65 20 6d 6f 64 75 6c 65 2e 0a 2a   table module..*
8cf0: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 72 65 67  /.static int reg
8d00: 69 73 74 65 72 5f 65 63 68 6f 5f 6d 6f 64 75 6c  ister_echo_modul
8d10: 65 28 0a 20 20 43 6c 69 65 6e 74 44 61 74 61 20  e(.  ClientData 
8d20: 63 6c 69 65 6e 74 44 61 74 61 2c 20 2f 2a 20 50  clientData, /* P
8d30: 6f 69 6e 74 65 72 20 74 6f 20 73 71 6c 69 74 65  ointer to sqlite
8d40: 33 5f 65 6e 61 62 6c 65 5f 58 58 58 20 66 75 6e  3_enable_XXX fun
8d50: 63 74 69 6f 6e 20 2a 2f 0a 20 20 54 63 6c 5f 49  ction */.  Tcl_I
8d60: 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 2c 20 20  nterp *interp,  
8d70: 20 20 2f 2a 20 54 68 65 20 54 43 4c 20 69 6e 74    /* The TCL int
8d80: 65 72 70 72 65 74 65 72 20 74 68 61 74 20 69 6e  erpreter that in
8d90: 76 6f 6b 65 64 20 74 68 69 73 20 63 6f 6d 6d 61  voked this comma
8da0: 6e 64 20 2a 2f 0a 20 20 69 6e 74 20 6f 62 6a 63  nd */.  int objc
8db0: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f  ,              /
8dc0: 2a 20 4e 75 6d 62 65 72 20 6f 66 20 61 72 67 75  * Number of argu
8dd0: 6d 65 6e 74 73 20 2a 2f 0a 20 20 54 63 6c 5f 4f  ments */.  Tcl_O
8de0: 62 6a 20 2a 43 4f 4e 53 54 20 6f 62 6a 76 5b 5d  bj *CONST objv[]
8df0: 20 20 2f 2a 20 43 6f 6d 6d 61 6e 64 20 61 72 67    /* Command arg
8e00: 75 6d 65 6e 74 73 20 2a 2f 0a 29 7b 0a 20 20 73  uments */.){.  s
8e10: 71 6c 69 74 65 33 20 2a 64 62 3b 0a 20 20 45 63  qlite3 *db;.  Ec
8e20: 68 6f 4d 6f 64 75 6c 65 20 2a 70 4d 6f 64 3b 0a  hoModule *pMod;.
8e30: 20 20 69 66 28 20 6f 62 6a 63 21 3d 32 20 29 7b    if( objc!=2 ){
8e40: 0a 20 20 20 20 54 63 6c 5f 57 72 6f 6e 67 4e 75  .    Tcl_WrongNu
8e50: 6d 41 72 67 73 28 69 6e 74 65 72 70 2c 20 31 2c  mArgs(interp, 1,
8e60: 20 6f 62 6a 76 2c 20 22 44 42 22 29 3b 0a 20 20   objv, "DB");.  
8e70: 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52    return TCL_ERR
8e80: 4f 52 3b 0a 20 20 7d 0a 20 20 69 66 28 20 67 65  OR;.  }.  if( ge
8e90: 74 44 62 50 6f 69 6e 74 65 72 28 69 6e 74 65 72  tDbPointer(inter
8ea0: 70 2c 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67  p, Tcl_GetString
8eb0: 28 6f 62 6a 76 5b 31 5d 29 2c 20 26 64 62 29 20  (objv[1]), &db) 
8ec0: 29 20 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52  ) return TCL_ERR
8ed0: 4f 52 3b 0a 20 20 70 4d 6f 64 20 3d 20 73 71 6c  OR;.  pMod = sql
8ee0: 69 74 65 33 5f 6d 61 6c 6c 6f 63 28 73 69 7a 65  ite3_malloc(size
8ef0: 6f 66 28 45 63 68 6f 4d 6f 64 75 6c 65 29 29 3b  of(EchoModule));
8f00: 0a 20 20 70 4d 6f 64 2d 3e 69 6e 74 65 72 70 20  .  pMod->interp 
8f10: 3d 20 69 6e 74 65 72 70 3b 0a 20 20 73 71 6c 69  = interp;.  sqli
8f20: 74 65 33 5f 63 72 65 61 74 65 5f 6d 6f 64 75 6c  te3_create_modul
8f30: 65 5f 76 32 28 64 62 2c 20 22 65 63 68 6f 22 2c  e_v2(db, "echo",
8f40: 20 26 65 63 68 6f 4d 6f 64 75 6c 65 2c 20 28 76   &echoModule, (v
8f50: 6f 69 64 2a 29 70 4d 6f 64 2c 20 6d 6f 64 75 6c  oid*)pMod, modul
8f60: 65 44 65 73 74 72 6f 79 29 3b 0a 20 20 72 65 74  eDestroy);.  ret
8f70: 75 72 6e 20 54 43 4c 5f 4f 4b 3b 0a 7d 0a 0a 2f  urn TCL_OK;.}../
8f80: 2a 0a 2a 2a 20 54 63 6c 20 69 6e 74 65 72 66 61  *.** Tcl interfa
8f90: 63 65 20 74 6f 20 73 71 6c 69 74 65 33 5f 64 65  ce to sqlite3_de
8fa0: 63 6c 61 72 65 5f 76 74 61 62 2c 20 69 6e 76 6f  clare_vtab, invo
8fb0: 6b 65 64 20 61 73 20 66 6f 6c 6c 6f 77 73 20 66  ked as follows f
8fc0: 72 6f 6d 20 54 63 6c 3a 0a 2a 2a 0a 2a 2a 20 73  rom Tcl:.**.** s
8fd0: 71 6c 69 74 65 33 5f 64 65 63 6c 61 72 65 5f 76  qlite3_declare_v
8fe0: 74 61 62 20 44 42 20 53 51 4c 0a 2a 2f 0a 73 74  tab DB SQL.*/.st
8ff0: 61 74 69 63 20 69 6e 74 20 64 65 63 6c 61 72 65  atic int declare
9000: 5f 76 74 61 62 28 0a 20 20 43 6c 69 65 6e 74 44  _vtab(.  ClientD
9010: 61 74 61 20 63 6c 69 65 6e 74 44 61 74 61 2c 20  ata clientData, 
9020: 2f 2a 20 50 6f 69 6e 74 65 72 20 74 6f 20 73 71  /* Pointer to sq
9030: 6c 69 74 65 33 5f 65 6e 61 62 6c 65 5f 58 58 58  lite3_enable_XXX
9040: 20 66 75 6e 63 74 69 6f 6e 20 2a 2f 0a 20 20 54   function */.  T
9050: 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72  cl_Interp *inter
9060: 70 2c 20 20 20 20 2f 2a 20 54 68 65 20 54 43 4c  p,    /* The TCL
9070: 20 69 6e 74 65 72 70 72 65 74 65 72 20 74 68 61   interpreter tha
9080: 74 20 69 6e 76 6f 6b 65 64 20 74 68 69 73 20 63  t invoked this c
9090: 6f 6d 6d 61 6e 64 20 2a 2f 0a 20 20 69 6e 74 20  ommand */.  int 
90a0: 6f 62 6a 63 2c 20 20 20 20 20 20 20 20 20 20 20  objc,           
90b0: 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20     /* Number of 
90c0: 61 72 67 75 6d 65 6e 74 73 20 2a 2f 0a 20 20 54  arguments */.  T
90d0: 63 6c 5f 4f 62 6a 20 2a 43 4f 4e 53 54 20 6f 62  cl_Obj *CONST ob
90e0: 6a 76 5b 5d 20 20 2f 2a 20 43 6f 6d 6d 61 6e 64  jv[]  /* Command
90f0: 20 61 72 67 75 6d 65 6e 74 73 20 2a 2f 0a 29 7b   arguments */.){
9100: 0a 20 20 73 71 6c 69 74 65 33 20 2a 64 62 3b 0a  .  sqlite3 *db;.
9110: 20 20 69 6e 74 20 72 63 3b 0a 20 20 69 66 28 20    int rc;.  if( 
9120: 6f 62 6a 63 21 3d 33 20 29 7b 0a 20 20 20 20 54  objc!=3 ){.    T
9130: 63 6c 5f 57 72 6f 6e 67 4e 75 6d 41 72 67 73 28  cl_WrongNumArgs(
9140: 69 6e 74 65 72 70 2c 20 31 2c 20 6f 62 6a 76 2c  interp, 1, objv,
9150: 20 22 44 42 20 53 51 4c 22 29 3b 0a 20 20 20 20   "DB SQL");.    
9160: 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52  return TCL_ERROR
9170: 3b 0a 20 20 7d 0a 20 20 69 66 28 20 67 65 74 44  ;.  }.  if( getD
9180: 62 50 6f 69 6e 74 65 72 28 69 6e 74 65 72 70 2c  bPointer(interp,
9190: 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 28 6f   Tcl_GetString(o
91a0: 62 6a 76 5b 31 5d 29 2c 20 26 64 62 29 20 29 20  bjv[1]), &db) ) 
91b0: 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52  return TCL_ERROR
91c0: 3b 0a 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33  ;.  rc = sqlite3
91d0: 5f 64 65 63 6c 61 72 65 5f 76 74 61 62 28 64 62  _declare_vtab(db
91e0: 2c 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 28  , Tcl_GetString(
91f0: 6f 62 6a 76 5b 32 5d 29 29 3b 0a 20 20 69 66 28  objv[2]));.  if(
9200: 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc!=SQLITE_OK )
9210: 7b 0a 20 20 20 20 54 63 6c 5f 53 65 74 52 65 73  {.    Tcl_SetRes
9220: 75 6c 74 28 69 6e 74 65 72 70 2c 20 28 63 68 61  ult(interp, (cha
9230: 72 20 2a 29 73 71 6c 69 74 65 33 5f 65 72 72 6d  r *)sqlite3_errm
9240: 73 67 28 64 62 29 2c 20 54 43 4c 5f 56 4f 4c 41  sg(db), TCL_VOLA
9250: 54 49 4c 45 29 3b 0a 20 20 20 20 72 65 74 75 72  TILE);.    retur
9260: 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 7d  n TCL_ERROR;.  }
9270: 0a 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 4f 4b  .  return TCL_OK
9280: 3b 0a 7d 0a 0a 23 65 6e 64 69 66 20 2f 2a 20 69  ;.}..#endif /* i
9290: 66 6e 64 65 66 20 53 51 4c 49 54 45 5f 4f 4d 49  fndef SQLITE_OMI
92a0: 54 5f 56 49 52 54 55 41 4c 54 41 42 4c 45 20 2a  T_VIRTUALTABLE *
92b0: 2f 0a 0a 2f 2a 0a 2a 2a 20 52 65 67 69 73 74 65  /../*.** Registe
92c0: 72 20 63 6f 6d 6d 61 6e 64 73 20 77 69 74 68 20  r commands with 
92d0: 74 68 65 20 54 43 4c 20 69 6e 74 65 72 70 72 65  the TCL interpre
92e0: 74 65 72 2e 0a 2a 2f 0a 69 6e 74 20 53 71 6c 69  ter..*/.int Sqli
92f0: 74 65 74 65 73 74 38 5f 49 6e 69 74 28 54 63 6c  tetest8_Init(Tcl
9300: 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 29  _Interp *interp)
9310: 7b 0a 23 69 66 6e 64 65 66 20 53 51 4c 49 54 45  {.#ifndef SQLITE
9320: 5f 4f 4d 49 54 5f 56 49 52 54 55 41 4c 54 41 42  _OMIT_VIRTUALTAB
9330: 4c 45 0a 20 20 73 74 61 74 69 63 20 73 74 72 75  LE.  static stru
9340: 63 74 20 7b 0a 20 20 20 20 20 63 68 61 72 20 2a  ct {.     char *
9350: 7a 4e 61 6d 65 3b 0a 20 20 20 20 20 54 63 6c 5f  zName;.     Tcl_
9360: 4f 62 6a 43 6d 64 50 72 6f 63 20 2a 78 50 72 6f  ObjCmdProc *xPro
9370: 63 3b 0a 20 20 20 20 20 76 6f 69 64 20 2a 63 6c  c;.     void *cl
9380: 69 65 6e 74 44 61 74 61 3b 0a 20 20 7d 20 61 4f  ientData;.  } aO
9390: 62 6a 43 6d 64 5b 5d 20 3d 20 7b 0a 20 20 20 20  bjCmd[] = {.    
93a0: 20 7b 20 22 72 65 67 69 73 74 65 72 5f 65 63 68   { "register_ech
93b0: 6f 5f 6d 6f 64 75 6c 65 22 2c 20 20 20 72 65 67  o_module",   reg
93c0: 69 73 74 65 72 5f 65 63 68 6f 5f 6d 6f 64 75 6c  ister_echo_modul
93d0: 65 2c 20 30 20 7d 2c 0a 20 20 20 20 20 7b 20 22  e, 0 },.     { "
93e0: 73 71 6c 69 74 65 33 5f 64 65 63 6c 61 72 65 5f  sqlite3_declare_
93f0: 76 74 61 62 22 2c 20 20 20 64 65 63 6c 61 72 65  vtab",   declare
9400: 5f 76 74 61 62 2c 20 30 20 7d 2c 0a 20 20 7d 3b  _vtab, 0 },.  };
9410: 0a 20 20 69 6e 74 20 69 3b 0a 20 20 66 6f 72 28  .  int i;.  for(
9420: 69 3d 30 3b 20 69 3c 73 69 7a 65 6f 66 28 61 4f  i=0; i<sizeof(aO
9430: 62 6a 43 6d 64 29 2f 73 69 7a 65 6f 66 28 61 4f  bjCmd)/sizeof(aO
9440: 62 6a 43 6d 64 5b 30 5d 29 3b 20 69 2b 2b 29 7b  bjCmd[0]); i++){
9450: 0a 20 20 20 20 54 63 6c 5f 43 72 65 61 74 65 4f  .    Tcl_CreateO
9460: 62 6a 43 6f 6d 6d 61 6e 64 28 69 6e 74 65 72 70  bjCommand(interp
9470: 2c 20 61 4f 62 6a 43 6d 64 5b 69 5d 2e 7a 4e 61  , aObjCmd[i].zNa
9480: 6d 65 2c 20 0a 20 20 20 20 20 20 20 20 61 4f 62  me, .        aOb
9490: 6a 43 6d 64 5b 69 5d 2e 78 50 72 6f 63 2c 20 61  jCmd[i].xProc, a
94a0: 4f 62 6a 43 6d 64 5b 69 5d 2e 63 6c 69 65 6e 74  ObjCmd[i].client
94b0: 44 61 74 61 2c 20 30 29 3b 0a 20 20 7d 0a 23 65  Data, 0);.  }.#e
94c0: 6e 64 69 66 0a 20 20 72 65 74 75 72 6e 20 54 43  ndif.  return TC
94d0: 4c 5f 4f 4b 3b 0a 7d 0a                          L_OK;.}.