/ Hex Artifact Content
Login

Artifact 3637439424d0d21ff2dcf9b015c30fcc1e7bcb24:


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 35 20 32  test8.c,v 1.75 2
0230: 30 30 38 2f 30 38 2f 33 31 20 30 30 3a 32 39 3a  008/08/31 00:29:
0240: 30 38 20 73 68 61 6e 65 20 45 78 70 20 24 0a 2a  08 shane Exp $.*
0250: 2f 0a 23 69 6e 63 6c 75 64 65 20 22 73 71 6c 69  /.#include "sqli
0260: 74 65 49 6e 74 2e 68 22 0a 23 69 6e 63 6c 75 64  teInt.h".#includ
0270: 65 20 22 74 63 6c 2e 68 22 0a 23 69 6e 63 6c 75  e "tcl.h".#inclu
0280: 64 65 20 3c 73 74 64 6c 69 62 2e 68 3e 0a 23 69  de <stdlib.h>.#i
0290: 6e 63 6c 75 64 65 20 3c 73 74 72 69 6e 67 2e 68  nclude <string.h
02a0: 3e 0a 0a 23 69 66 6e 64 65 66 20 53 51 4c 49 54  >..#ifndef SQLIT
02b0: 45 5f 4f 4d 49 54 5f 56 49 52 54 55 41 4c 54 41  E_OMIT_VIRTUALTA
02c0: 42 4c 45 0a 0a 74 79 70 65 64 65 66 20 73 74 72  BLE..typedef str
02d0: 75 63 74 20 65 63 68 6f 5f 76 74 61 62 20 65 63  uct echo_vtab ec
02e0: 68 6f 5f 76 74 61 62 3b 0a 74 79 70 65 64 65 66  ho_vtab;.typedef
02f0: 20 73 74 72 75 63 74 20 65 63 68 6f 5f 63 75 72   struct echo_cur
0300: 73 6f 72 20 65 63 68 6f 5f 63 75 72 73 6f 72 3b  sor echo_cursor;
0310: 0a 0a 2f 2a 0a 2a 2a 20 54 68 65 20 74 65 73 74  ../*.** The test
0320: 20 6d 6f 64 75 6c 65 20 64 65 66 69 6e 65 64 20   module defined 
0330: 69 6e 20 74 68 69 73 20 66 69 6c 65 20 75 73 65  in this file use
0340: 73 20 66 6f 75 72 20 67 6c 6f 62 61 6c 20 54 63  s four global Tc
0350: 6c 20 76 61 72 69 61 62 6c 65 73 20 74 6f 0a 2a  l variables to.*
0360: 2a 20 63 6f 6d 6d 69 63 61 74 65 20 77 69 74 68  * commicate with
0370: 20 74 65 73 74 2d 73 63 72 69 70 74 73 3a 0a 2a   test-scripts:.*
0380: 2a 0a 2a 2a 20 20 20 20 20 24 3a 3a 65 63 68 6f  *.**     $::echo
0390: 5f 6d 6f 64 75 6c 65 0a 2a 2a 20 20 20 20 20 24  _module.**     $
03a0: 3a 3a 65 63 68 6f 5f 6d 6f 64 75 6c 65 5f 73 79  ::echo_module_sy
03b0: 6e 63 5f 66 61 69 6c 0a 2a 2a 20 20 20 20 20 24  nc_fail.**     $
03c0: 3a 3a 65 63 68 6f 5f 6d 6f 64 75 6c 65 5f 62 65  ::echo_module_be
03d0: 67 69 6e 5f 66 61 69 6c 0a 2a 2a 20 20 20 20 20  gin_fail.**     
03e0: 24 3a 3a 65 63 68 6f 5f 6d 6f 64 75 6c 65 5f 63  $::echo_module_c
03f0: 6f 73 74 0a 2a 2a 0a 2a 2a 20 54 68 65 20 76 61  ost.**.** The va
0400: 72 69 61 62 6c 65 20 3a 3a 65 63 68 6f 5f 6d 6f  riable ::echo_mo
0410: 64 75 6c 65 20 69 73 20 61 20 6c 69 73 74 2e 20  dule is a list. 
0420: 45 61 63 68 20 74 69 6d 65 20 6f 6e 65 20 6f 66  Each time one of
0430: 20 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 0a 2a   the following.*
0440: 2a 20 6d 65 74 68 6f 64 73 20 69 73 20 63 61 6c  * methods is cal
0450: 6c 65 64 2c 20 6f 6e 65 20 6f 72 20 6d 6f 72 65  led, one or more
0460: 20 65 6c 65 6d 65 6e 74 73 20 61 72 65 20 61 70   elements are ap
0470: 70 65 6e 64 65 64 20 74 6f 20 74 68 65 20 6c 69  pended to the li
0480: 73 74 2e 0a 2a 2a 20 54 68 69 73 20 69 73 20 75  st..** This is u
0490: 73 65 64 20 66 6f 72 20 61 75 74 6f 6d 61 74 65  sed for automate
04a0: 64 20 74 65 73 74 69 6e 67 20 6f 66 20 76 69 72  d testing of vir
04b0: 74 75 61 6c 20 74 61 62 6c 65 20 6d 6f 64 75 6c  tual table modul
04c0: 65 73 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 3a 3a  es..**.** The ::
04d0: 65 63 68 6f 5f 6d 6f 64 75 6c 65 5f 73 79 6e 63  echo_module_sync
04e0: 5f 66 61 69 6c 20 76 61 72 69 61 62 6c 65 20 69  _fail variable i
04f0: 73 20 73 65 74 20 62 79 20 74 65 73 74 20 73 63  s set by test sc
0500: 72 69 70 74 73 20 61 6e 64 20 72 65 61 64 0a 2a  ripts and read.*
0510: 2a 20 62 79 20 63 6f 64 65 20 69 6e 20 74 68 69  * by code in thi
0520: 73 20 66 69 6c 65 2e 20 49 66 20 69 74 20 69 73  s file. If it is
0530: 20 73 65 74 20 74 6f 20 74 68 65 20 6e 61 6d 65   set to the name
0540: 20 6f 66 20 61 20 72 65 61 6c 20 74 61 62 6c 65   of a real table
0550: 20 69 6e 20 74 68 65 0a 2a 2a 20 74 68 65 20 64   in the.** the d
0560: 61 74 61 62 61 73 65 2c 20 74 68 65 6e 20 61 6c  atabase, then al
0570: 6c 20 78 53 79 6e 63 20 6f 70 65 72 61 74 69 6f  l xSync operatio
0580: 6e 73 20 6f 6e 20 65 63 68 6f 20 76 69 72 74 75  ns on echo virtu
0590: 61 6c 20 74 61 62 6c 65 73 20 74 68 61 74 0a 2a  al tables that.*
05a0: 2a 20 75 73 65 20 74 68 65 20 6e 61 6d 65 64 20  * use the named 
05b0: 74 61 62 6c 65 20 61 73 20 61 20 62 61 63 6b 69  table as a backi
05c0: 6e 67 20 73 74 6f 72 65 20 77 69 6c 6c 20 66 61  ng store will fa
05d0: 69 6c 2e 0a 2a 2f 0a 0a 2f 2a 0a 2a 2a 20 45 72  il..*/../*.** Er
05e0: 72 6f 72 73 20 63 61 6e 20 62 65 20 70 72 6f 76  rors can be prov
05f0: 6f 6b 65 64 20 77 69 74 68 69 6e 20 74 68 65 20  oked within the 
0600: 66 6f 6c 6c 6f 77 69 6e 67 20 65 63 68 6f 20 76  following echo v
0610: 69 72 74 75 61 6c 20 74 61 62 6c 65 20 6d 65 74  irtual table met
0620: 68 6f 64 73 3a 0a 2a 2a 0a 2a 2a 20 20 20 78 42  hods:.**.**   xB
0630: 65 73 74 49 6e 64 65 78 20 20 20 78 4f 70 65 6e  estIndex   xOpen
0640: 20 20 20 20 20 78 46 69 6c 74 65 72 20 20 20 78       xFilter   x
0650: 4e 65 78 74 20 20 20 0a 2a 2a 20 20 20 78 43 6f  Next   .**   xCo
0660: 6c 75 6d 6e 20 20 20 20 20 20 78 52 6f 77 69 64  lumn      xRowid
0670: 20 20 20 20 78 55 70 64 61 74 65 20 20 20 78 53      xUpdate   xS
0680: 79 6e 63 20 20 20 0a 2a 2a 20 20 20 78 42 65 67  ync   .**   xBeg
0690: 69 6e 20 20 20 20 20 20 20 78 52 65 6e 61 6d 65  in       xRename
06a0: 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20 69 73 20 64  .**.** This is d
06b0: 6f 6e 65 20 62 79 20 73 65 74 74 69 6e 67 20 74  one by setting t
06c0: 68 65 20 67 6c 6f 62 61 6c 20 74 63 6c 20 76 61  he global tcl va
06d0: 72 69 61 62 6c 65 3a 0a 2a 2a 0a 2a 2a 20 20 20  riable:.**.**   
06e0: 65 63 68 6f 5f 6d 6f 64 75 6c 65 5f 66 61 69 6c  echo_module_fail
06f0: 28 24 6d 65 74 68 6f 64 2c 24 74 62 6c 29 0a 2a  ($method,$tbl).*
0700: 2a 0a 2a 2a 20 77 68 65 72 65 20 24 6d 65 74 68  *.** where $meth
0710: 6f 64 20 69 73 20 73 65 74 20 74 6f 20 74 68 65  od is set to the
0720: 20 6e 61 6d 65 20 6f 66 20 74 68 65 20 76 69 72   name of the vir
0730: 74 75 61 6c 20 74 61 62 6c 65 20 6d 65 74 68 6f  tual table metho
0740: 64 20 74 6f 20 66 61 69 6c 0a 2a 2a 20 28 69 2e  d to fail.** (i.
0750: 65 2e 20 22 78 42 65 73 74 49 6e 64 65 78 22 29  e. "xBestIndex")
0760: 20 61 6e 64 20 24 74 62 6c 20 69 73 20 74 68 65   and $tbl is the
0770: 20 6e 61 6d 65 20 6f 66 20 74 68 65 20 74 61 62   name of the tab
0780: 6c 65 20 62 65 69 6e 67 20 65 63 68 6f 65 64 20  le being echoed 
0790: 28 6e 6f 74 0a 2a 2a 20 74 68 65 20 6e 61 6d 65  (not.** the name
07a0: 20 6f 66 20 74 68 65 20 76 69 72 74 75 61 6c 20   of the virtual 
07b0: 74 61 62 6c 65 2c 20 74 68 65 20 6e 61 6d 65 20  table, the name 
07c0: 6f 66 20 74 68 65 20 75 6e 64 65 72 6c 79 69 6e  of the underlyin
07d0: 67 20 72 65 61 6c 20 74 61 62 6c 65 29 2e 0a 2a  g real table)..*
07e0: 2f 0a 0a 2f 2a 20 0a 2a 2a 20 41 6e 20 65 63 68  /../* .** An ech
07f0: 6f 20 76 69 72 74 75 61 6c 2d 74 61 62 6c 65 20  o virtual-table 
0800: 6f 62 6a 65 63 74 2e 0a 2a 2a 0a 2a 2a 20 65 63  object..**.** ec
0810: 68 6f 2e 76 74 61 62 2e 61 49 6e 64 65 78 20 69  ho.vtab.aIndex i
0820: 73 20 61 6e 20 61 72 72 61 79 20 6f 66 20 62 6f  s an array of bo
0830: 6f 6c 65 61 6e 73 2e 20 54 68 65 20 6e 74 68 20  oleans. The nth 
0840: 65 6e 74 72 79 20 69 73 20 74 72 75 65 20 69 66  entry is true if
0850: 20 0a 2a 2a 20 74 68 65 20 6e 74 68 20 63 6f 6c   .** the nth col
0860: 75 6d 6e 20 6f 66 20 74 68 65 20 72 65 61 6c 20  umn of the real 
0870: 74 61 62 6c 65 20 69 73 20 74 68 65 20 6c 65 66  table is the lef
0880: 74 2d 6d 6f 73 74 20 63 6f 6c 75 6d 6e 20 6f 66  t-most column of
0890: 20 61 6e 20 69 6e 64 65 78 0a 2a 2a 20 28 69 6d   an index.** (im
08a0: 70 6c 69 63 69 74 20 6f 72 20 6f 74 68 65 72 77  plicit or otherw
08b0: 69 73 65 29 2e 20 49 6e 20 6f 74 68 65 72 20 77  ise). In other w
08c0: 6f 72 64 73 2c 20 69 66 20 53 51 4c 69 74 65 20  ords, if SQLite 
08d0: 63 61 6e 20 6f 70 74 69 6d 69 7a 65 0a 2a 2a 20  can optimize.** 
08e0: 61 20 71 75 65 72 79 20 6c 69 6b 65 20 22 53 45  a query like "SE
08f0: 4c 45 43 54 20 2a 20 46 52 4f 4d 20 72 65 61 6c  LECT * FROM real
0900: 5f 74 61 62 6c 65 20 57 48 45 52 45 20 63 6f 6c  _table WHERE col
0910: 20 3d 20 3f 22 2e 0a 2a 2a 0a 2a 2a 20 4d 65 6d   = ?"..**.** Mem
0920: 62 65 72 20 76 61 72 69 61 62 6c 65 20 61 43 6f  ber variable aCo
0930: 6c 5b 5d 20 63 6f 6e 74 61 69 6e 73 20 63 6f 70  l[] contains cop
0940: 69 65 73 20 6f 66 20 74 68 65 20 63 6f 6c 75 6d  ies of the colum
0950: 6e 20 6e 61 6d 65 73 20 6f 66 20 74 68 65 20 72  n names of the r
0960: 65 61 6c 0a 2a 2a 20 74 61 62 6c 65 2e 0a 2a 2f  eal.** table..*/
0970: 0a 73 74 72 75 63 74 20 65 63 68 6f 5f 76 74 61  .struct echo_vta
0980: 62 20 7b 0a 20 20 73 71 6c 69 74 65 33 5f 76 74  b {.  sqlite3_vt
0990: 61 62 20 62 61 73 65 3b 0a 20 20 54 63 6c 5f 49  ab base;.  Tcl_I
09a0: 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 3b 20 20  nterp *interp;  
09b0: 20 20 20 2f 2a 20 54 63 6c 20 69 6e 74 65 72 70     /* Tcl interp
09c0: 72 65 74 65 72 20 63 6f 6e 74 61 69 6e 69 6e 67  reter containing
09d0: 20 64 65 62 75 67 20 76 61 72 69 61 62 6c 65 73   debug variables
09e0: 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 20 2a 64   */.  sqlite3 *d
09f0: 62 3b 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a  b;            /*
0a00: 20 44 61 74 61 62 61 73 65 20 63 6f 6e 6e 65 63   Database connec
0a10: 74 69 6f 6e 20 2a 2f 0a 0a 20 20 69 6e 74 20 69  tion */..  int i
0a20: 73 50 61 74 74 65 72 6e 3b 0a 20 20 69 6e 74 20  sPattern;.  int 
0a30: 69 6e 54 72 61 6e 73 61 63 74 69 6f 6e 3b 20 20  inTransaction;  
0a40: 20 20 20 20 2f 2a 20 54 72 75 65 20 69 66 20 77      /* True if w
0a50: 69 74 68 69 6e 20 61 20 74 72 61 6e 73 61 63 74  ithin a transact
0a60: 69 6f 6e 20 2a 2f 0a 20 20 63 68 61 72 20 2a 7a  ion */.  char *z
0a70: 54 68 69 73 3b 20 20 20 20 20 20 20 20 20 20 20  This;           
0a80: 20 2f 2a 20 4e 61 6d 65 20 6f 66 20 74 68 65 20   /* Name of the 
0a90: 65 63 68 6f 20 74 61 62 6c 65 20 2a 2f 0a 20 20  echo table */.  
0aa0: 63 68 61 72 20 2a 7a 54 61 62 6c 65 4e 61 6d 65  char *zTableName
0ab0: 3b 20 20 20 20 20 20 20 2f 2a 20 4e 61 6d 65 20  ;       /* Name 
0ac0: 6f 66 20 74 68 65 20 72 65 61 6c 20 74 61 62 6c  of the real tabl
0ad0: 65 20 2a 2f 0a 20 20 63 68 61 72 20 2a 7a 4c 6f  e */.  char *zLo
0ae0: 67 4e 61 6d 65 3b 20 20 20 20 20 20 20 20 20 2f  gName;         /
0af0: 2a 20 4e 61 6d 65 20 6f 66 20 74 68 65 20 6c 6f  * Name of the lo
0b00: 67 20 74 61 62 6c 65 20 2a 2f 0a 20 20 69 6e 74  g table */.  int
0b10: 20 6e 43 6f 6c 3b 20 20 20 20 20 20 20 20 20 20   nCol;          
0b20: 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f       /* Number o
0b30: 66 20 63 6f 6c 75 6d 6e 73 20 69 6e 20 74 68 65  f columns in the
0b40: 20 72 65 61 6c 20 74 61 62 6c 65 20 2a 2f 0a 20   real table */. 
0b50: 20 69 6e 74 20 2a 61 49 6e 64 65 78 3b 20 20 20   int *aIndex;   
0b60: 20 20 20 20 20 20 20 20 20 2f 2a 20 41 72 72 61           /* Arra
0b70: 79 20 6f 66 20 73 69 7a 65 20 6e 43 6f 6c 2e 20  y of size nCol. 
0b80: 54 72 75 65 20 69 66 20 63 6f 6c 75 6d 6e 20 68  True if column h
0b90: 61 73 20 61 6e 20 69 6e 64 65 78 20 2a 2f 0a 20  as an index */. 
0ba0: 20 63 68 61 72 20 2a 2a 61 43 6f 6c 3b 20 20 20   char **aCol;   
0bb0: 20 20 20 20 20 20 20 20 20 2f 2a 20 41 72 72 61           /* Arra
0bc0: 79 20 6f 66 20 73 69 7a 65 20 6e 43 6f 6c 2e 20  y of size nCol. 
0bd0: 43 6f 6c 75 6d 6e 20 6e 61 6d 65 73 20 2a 2f 0a  Column names */.
0be0: 7d 3b 0a 0a 2f 2a 20 41 6e 20 65 63 68 6f 20 63  };../* An echo c
0bf0: 75 72 73 6f 72 20 6f 62 6a 65 63 74 20 2a 2f 0a  ursor object */.
0c00: 73 74 72 75 63 74 20 65 63 68 6f 5f 63 75 72 73  struct echo_curs
0c10: 6f 72 20 7b 0a 20 20 73 71 6c 69 74 65 33 5f 76  or {.  sqlite3_v
0c20: 74 61 62 5f 63 75 72 73 6f 72 20 62 61 73 65 3b  tab_cursor base;
0c30: 0a 20 20 73 71 6c 69 74 65 33 5f 73 74 6d 74 20  .  sqlite3_stmt 
0c40: 2a 70 53 74 6d 74 3b 0a 7d 3b 0a 0a 73 74 61 74  *pStmt;.};..stat
0c50: 69 63 20 69 6e 74 20 73 69 6d 75 6c 61 74 65 56  ic int simulateV
0c60: 74 61 62 45 72 72 6f 72 28 65 63 68 6f 5f 76 74  tabError(echo_vt
0c70: 61 62 20 2a 70 2c 20 63 6f 6e 73 74 20 63 68 61  ab *p, const cha
0c80: 72 20 2a 7a 4d 65 74 68 6f 64 29 7b 0a 20 20 63  r *zMethod){.  c
0c90: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 45 72 72 3b  onst char *zErr;
0ca0: 0a 20 20 63 68 61 72 20 7a 56 61 72 6e 61 6d 65  .  char zVarname
0cb0: 5b 31 32 38 5d 3b 0a 20 20 7a 56 61 72 6e 61 6d  [128];.  zVarnam
0cc0: 65 5b 31 32 37 5d 20 3d 20 27 5c 30 27 3b 0a 20  e[127] = '\0';. 
0cd0: 20 73 71 6c 69 74 65 33 5f 73 6e 70 72 69 6e 74   sqlite3_snprint
0ce0: 66 28 31 32 37 2c 20 7a 56 61 72 6e 61 6d 65 2c  f(127, zVarname,
0cf0: 20 22 65 63 68 6f 5f 6d 6f 64 75 6c 65 5f 66 61   "echo_module_fa
0d00: 69 6c 28 25 73 2c 25 73 29 22 2c 20 7a 4d 65 74  il(%s,%s)", zMet
0d10: 68 6f 64 2c 20 70 2d 3e 7a 54 61 62 6c 65 4e 61  hod, p->zTableNa
0d20: 6d 65 29 3b 0a 20 20 7a 45 72 72 20 3d 20 54 63  me);.  zErr = Tc
0d30: 6c 5f 47 65 74 56 61 72 28 70 2d 3e 69 6e 74 65  l_GetVar(p->inte
0d40: 72 70 2c 20 7a 56 61 72 6e 61 6d 65 2c 20 54 43  rp, zVarname, TC
0d50: 4c 5f 47 4c 4f 42 41 4c 5f 4f 4e 4c 59 29 3b 0a  L_GLOBAL_ONLY);.
0d60: 20 20 69 66 28 20 7a 45 72 72 20 29 7b 0a 20 20    if( zErr ){.  
0d70: 20 20 70 2d 3e 62 61 73 65 2e 7a 45 72 72 4d 73    p->base.zErrMs
0d80: 67 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72 69  g = sqlite3_mpri
0d90: 6e 74 66 28 22 65 63 68 6f 2d 76 74 61 62 2d 65  ntf("echo-vtab-e
0da0: 72 72 6f 72 3a 20 25 73 22 2c 20 7a 45 72 72 29  rror: %s", zErr)
0db0: 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 28  ;.  }.  return (
0dc0: 7a 45 72 72 21 3d 30 29 3b 0a 7d 0a 0a 2f 2a 0a  zErr!=0);.}../*.
0dd0: 2a 2a 20 43 6f 6e 76 65 72 74 20 61 6e 20 53 51  ** Convert an SQ
0de0: 4c 2d 73 74 79 6c 65 20 71 75 6f 74 65 64 20 73  L-style quoted s
0df0: 74 72 69 6e 67 20 69 6e 74 6f 20 61 20 6e 6f 72  tring into a nor
0e00: 6d 61 6c 20 73 74 72 69 6e 67 20 62 79 20 72 65  mal string by re
0e10: 6d 6f 76 69 6e 67 0a 2a 2a 20 74 68 65 20 71 75  moving.** the qu
0e20: 6f 74 65 20 63 68 61 72 61 63 74 65 72 73 2e 20  ote characters. 
0e30: 20 54 68 65 20 63 6f 6e 76 65 72 73 69 6f 6e 20   The conversion 
0e40: 69 73 20 64 6f 6e 65 20 69 6e 2d 70 6c 61 63 65  is done in-place
0e50: 2e 20 20 49 66 20 74 68 65 0a 2a 2a 20 69 6e 70  .  If the.** inp
0e60: 75 74 20 64 6f 65 73 20 6e 6f 74 20 62 65 67 69  ut does not begi
0e70: 6e 20 77 69 74 68 20 61 20 71 75 6f 74 65 20 63  n with a quote c
0e80: 68 61 72 61 63 74 65 72 2c 20 74 68 65 6e 20 74  haracter, then t
0e90: 68 69 73 20 72 6f 75 74 69 6e 65 0a 2a 2a 20 69  his routine.** i
0ea0: 73 20 61 20 6e 6f 2d 6f 70 2e 0a 2a 2a 0a 2a 2a  s a no-op..**.**
0eb0: 20 45 78 61 6d 70 6c 65 73 3a 0a 2a 2a 0a 2a 2a   Examples:.**.**
0ec0: 20 20 20 20 20 22 61 62 63 22 20 20 20 62 65 63       "abc"   bec
0ed0: 6f 6d 65 73 20 20 20 61 62 63 0a 2a 2a 20 20 20  omes   abc.**   
0ee0: 20 20 27 78 79 7a 27 20 20 20 62 65 63 6f 6d 65    'xyz'   become
0ef0: 73 20 20 20 78 79 7a 0a 2a 2a 20 20 20 20 20 5b  s   xyz.**     [
0f00: 70 71 72 5d 20 20 20 62 65 63 6f 6d 65 73 20 20  pqr]   becomes  
0f10: 20 70 71 72 0a 2a 2a 20 20 20 20 20 60 6d 6e 6f   pqr.**     `mno
0f20: 60 20 20 20 62 65 63 6f 6d 65 73 20 20 20 6d 6e  `   becomes   mn
0f30: 6f 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64  o.*/.static void
0f40: 20 64 65 71 75 6f 74 65 53 74 72 69 6e 67 28 63   dequoteString(c
0f50: 68 61 72 20 2a 7a 29 7b 0a 20 20 69 6e 74 20 71  har *z){.  int q
0f60: 75 6f 74 65 3b 0a 20 20 69 6e 74 20 69 2c 20 6a  uote;.  int i, j
0f70: 3b 0a 20 20 69 66 28 20 7a 3d 3d 30 20 29 20 72  ;.  if( z==0 ) r
0f80: 65 74 75 72 6e 3b 0a 20 20 71 75 6f 74 65 20 3d  eturn;.  quote =
0f90: 20 7a 5b 30 5d 3b 0a 20 20 73 77 69 74 63 68 28   z[0];.  switch(
0fa0: 20 71 75 6f 74 65 20 29 7b 0a 20 20 20 20 63 61   quote ){.    ca
0fb0: 73 65 20 27 5c 27 27 3a 20 20 62 72 65 61 6b 3b  se '\'':  break;
0fc0: 0a 20 20 20 20 63 61 73 65 20 27 22 27 3a 20 20  .    case '"':  
0fd0: 20 62 72 65 61 6b 3b 0a 20 20 20 20 63 61 73 65   break;.    case
0fe0: 20 27 60 27 3a 20 20 20 62 72 65 61 6b 3b 20 20   '`':   break;  
0ff0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
1000: 20 46 6f 72 20 4d 79 53 51 4c 20 63 6f 6d 70 61   For MySQL compa
1010: 74 69 62 69 6c 69 74 79 20 2a 2f 0a 20 20 20 20  tibility */.    
1020: 63 61 73 65 20 27 5b 27 3a 20 20 20 71 75 6f 74  case '[':   quot
1030: 65 20 3d 20 27 5d 27 3b 20 20 62 72 65 61 6b 3b  e = ']';  break;
1040: 20 20 2f 2a 20 46 6f 72 20 4d 53 20 53 71 6c 53    /* For MS SqlS
1050: 65 72 76 65 72 20 63 6f 6d 70 61 74 69 62 69 6c  erver compatibil
1060: 69 74 79 20 2a 2f 0a 20 20 20 20 64 65 66 61 75  ity */.    defau
1070: 6c 74 3a 20 20 20 20 72 65 74 75 72 6e 3b 0a 20  lt:    return;. 
1080: 20 7d 0a 20 20 66 6f 72 28 69 3d 31 2c 20 6a 3d   }.  for(i=1, j=
1090: 30 3b 20 7a 5b 69 5d 3b 20 69 2b 2b 29 7b 0a 20  0; z[i]; i++){. 
10a0: 20 20 20 69 66 28 20 7a 5b 69 5d 3d 3d 71 75 6f     if( z[i]==quo
10b0: 74 65 20 29 7b 0a 20 20 20 20 20 20 69 66 28 20  te ){.      if( 
10c0: 7a 5b 69 2b 31 5d 3d 3d 71 75 6f 74 65 20 29 7b  z[i+1]==quote ){
10d0: 0a 20 20 20 20 20 20 20 20 7a 5b 6a 2b 2b 5d 20  .        z[j++] 
10e0: 3d 20 71 75 6f 74 65 3b 0a 20 20 20 20 20 20 20  = quote;.       
10f0: 20 69 2b 2b 3b 0a 20 20 20 20 20 20 7d 65 6c 73   i++;.      }els
1100: 65 7b 0a 20 20 20 20 20 20 20 20 7a 5b 6a 2b 2b  e{.        z[j++
1110: 5d 20 3d 20 30 3b 0a 20 20 20 20 20 20 20 20 62  ] = 0;.        b
1120: 72 65 61 6b 3b 0a 20 20 20 20 20 20 7d 0a 20 20  reak;.      }.  
1130: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 7a    }else{.      z
1140: 5b 6a 2b 2b 5d 20 3d 20 7a 5b 69 5d 3b 0a 20 20  [j++] = z[i];.  
1150: 20 20 7d 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a    }.  }.}../*.**
1160: 20 52 65 74 72 69 65 76 65 20 74 68 65 20 63 6f   Retrieve the co
1170: 6c 75 6d 6e 20 6e 61 6d 65 73 20 66 6f 72 20 74  lumn names for t
1180: 68 65 20 74 61 62 6c 65 20 6e 61 6d 65 64 20 7a  he table named z
1190: 54 61 62 20 76 69 61 20 64 61 74 61 62 61 73 65  Tab via database
11a0: 0a 2a 2a 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 64  .** connection d
11b0: 62 2e 20 53 51 4c 49 54 45 5f 4f 4b 20 69 73 20  b. SQLITE_OK is 
11c0: 72 65 74 75 72 6e 65 64 20 6f 6e 20 73 75 63 63  returned on succ
11d0: 65 73 73 2c 20 6f 72 20 61 6e 20 73 71 6c 69 74  ess, or an sqlit
11e0: 65 20 65 72 72 6f 72 0a 2a 2a 20 63 6f 64 65 20  e error.** code 
11f0: 6f 74 68 65 72 77 69 73 65 2e 0a 2a 2a 0a 2a 2a  otherwise..**.**
1200: 20 49 66 20 73 75 63 63 65 73 73 66 75 6c 2c 20   If successful, 
1210: 74 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 63 6f  the number of co
1220: 6c 75 6d 6e 73 20 69 73 20 77 72 69 74 74 65 6e  lumns is written
1230: 20 74 6f 20 2a 70 6e 43 6f 6c 2e 20 2a 70 61 43   to *pnCol. *paC
1240: 6f 6c 20 69 73 0a 2a 2a 20 73 65 74 20 74 6f 20  ol is.** set to 
1250: 70 6f 69 6e 74 20 61 74 20 73 71 6c 69 74 65 33  point at sqlite3
1260: 5f 6d 61 6c 6c 6f 63 28 29 27 64 20 73 70 61 63  _malloc()'d spac
1270: 65 20 63 6f 6e 74 61 69 6e 69 6e 67 20 74 68 65  e containing the
1280: 20 61 72 72 61 79 20 6f 66 0a 2a 2a 20 6e 43 6f   array of.** nCo
1290: 6c 20 63 6f 6c 75 6d 6e 20 6e 61 6d 65 73 2e 20  l column names. 
12a0: 54 68 65 20 63 61 6c 6c 65 72 20 69 73 20 72 65  The caller is re
12b0: 73 70 6f 6e 73 69 62 6c 65 20 66 6f 72 20 63 61  sponsible for ca
12c0: 6c 6c 69 6e 67 20 73 71 6c 69 74 65 33 5f 66 72  lling sqlite3_fr
12d0: 65 65 0a 2a 2a 20 6f 6e 20 2a 70 61 43 6f 6c 2e  ee.** on *paCol.
12e0: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 67  .*/.static int g
12f0: 65 74 43 6f 6c 75 6d 6e 4e 61 6d 65 73 28 0a 20  etColumnNames(. 
1300: 20 73 71 6c 69 74 65 33 20 2a 64 62 2c 20 0a 20   sqlite3 *db, . 
1310: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 54 61   const char *zTa
1320: 62 2c 0a 20 20 63 68 61 72 20 2a 2a 2a 70 61 43  b,.  char ***paC
1330: 6f 6c 2c 20 0a 20 20 69 6e 74 20 2a 70 6e 43 6f  ol, .  int *pnCo
1340: 6c 0a 29 7b 0a 20 20 63 68 61 72 20 2a 2a 61 43  l.){.  char **aC
1350: 6f 6c 20 3d 20 30 3b 0a 20 20 63 68 61 72 20 2a  ol = 0;.  char *
1360: 7a 53 71 6c 3b 0a 20 20 73 71 6c 69 74 65 33 5f  zSql;.  sqlite3_
1370: 73 74 6d 74 20 2a 70 53 74 6d 74 20 3d 20 30 3b  stmt *pStmt = 0;
1380: 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49  .  int rc = SQLI
1390: 54 45 5f 4f 4b 3b 0a 20 20 69 6e 74 20 6e 43 6f  TE_OK;.  int nCo
13a0: 6c 20 3d 20 30 3b 0a 0a 20 20 2f 2a 20 50 72 65  l = 0;..  /* Pre
13b0: 70 61 72 65 20 74 68 65 20 73 74 61 74 65 6d 65  pare the stateme
13c0: 6e 74 20 22 53 45 4c 45 43 54 20 2a 20 46 52 4f  nt "SELECT * FRO
13d0: 4d 20 3c 74 62 6c 3e 22 2e 20 54 68 65 20 63 6f  M <tbl>". The co
13e0: 6c 75 6d 6e 20 6e 61 6d 65 73 0a 20 20 2a 2a 20  lumn names.  ** 
13f0: 6f 66 20 74 68 65 20 72 65 73 75 6c 74 20 73 65  of the result se
1400: 74 20 6f 66 20 74 68 65 20 63 6f 6d 70 69 6c 65  t of the compile
1410: 64 20 53 45 4c 45 43 54 20 77 69 6c 6c 20 62 65  d SELECT will be
1420: 20 74 68 65 20 73 61 6d 65 20 61 73 0a 20 20 2a   the same as.  *
1430: 2a 20 74 68 65 20 63 6f 6c 75 6d 6e 20 6e 61 6d  * the column nam
1440: 65 73 20 6f 66 20 74 61 62 6c 65 20 3c 74 62 6c  es of table <tbl
1450: 3e 2e 0a 20 20 2a 2f 0a 20 20 7a 53 71 6c 20 3d  >..  */.  zSql =
1460: 20 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66   sqlite3_mprintf
1470: 28 22 53 45 4c 45 43 54 20 2a 20 46 52 4f 4d 20  ("SELECT * FROM 
1480: 25 51 22 2c 20 7a 54 61 62 29 3b 0a 20 20 69 66  %Q", zTab);.  if
1490: 28 20 21 7a 53 71 6c 20 29 7b 0a 20 20 20 20 72  ( !zSql ){.    r
14a0: 63 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d  c = SQLITE_NOMEM
14b0: 3b 0a 20 20 20 20 67 6f 74 6f 20 6f 75 74 3b 0a  ;.    goto out;.
14c0: 20 20 7d 0a 20 20 72 63 20 3d 20 73 71 6c 69 74    }.  rc = sqlit
14d0: 65 33 5f 70 72 65 70 61 72 65 28 64 62 2c 20 7a  e3_prepare(db, z
14e0: 53 71 6c 2c 20 2d 31 2c 20 26 70 53 74 6d 74 2c  Sql, -1, &pStmt,
14f0: 20 30 29 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66   0);.  sqlite3_f
1500: 72 65 65 28 7a 53 71 6c 29 3b 0a 0a 20 20 69 66  ree(zSql);..  if
1510: 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
1520: 29 7b 0a 20 20 20 20 69 6e 74 20 69 69 3b 0a 20  ){.    int ii;. 
1530: 20 20 20 69 6e 74 20 6e 42 79 74 65 73 3b 0a 20     int nBytes;. 
1540: 20 20 20 63 68 61 72 20 2a 7a 53 70 61 63 65 3b     char *zSpace;
1550: 0a 20 20 20 20 6e 43 6f 6c 20 3d 20 73 71 6c 69  .    nCol = sqli
1560: 74 65 33 5f 63 6f 6c 75 6d 6e 5f 63 6f 75 6e 74  te3_column_count
1570: 28 70 53 74 6d 74 29 3b 0a 0a 20 20 20 20 2f 2a  (pStmt);..    /*
1580: 20 46 69 67 75 72 65 20 6f 75 74 20 68 6f 77 20   Figure out how 
1590: 6d 75 63 68 20 73 70 61 63 65 20 74 6f 20 61 6c  much space to al
15a0: 6c 6f 63 61 74 65 20 66 6f 72 20 74 68 65 20 61  locate for the a
15b0: 72 72 61 79 20 6f 66 20 63 6f 6c 75 6d 6e 20 6e  rray of column n
15c0: 61 6d 65 73 20 0a 20 20 20 20 2a 2a 20 28 69 6e  ames .    ** (in
15d0: 63 6c 75 64 69 6e 67 20 73 70 61 63 65 20 66 6f  cluding space fo
15e0: 72 20 74 68 65 20 73 74 72 69 6e 67 73 20 74 68  r the strings th
15f0: 65 6d 73 65 6c 76 65 73 29 2e 20 54 68 65 6e 20  emselves). Then 
1600: 61 6c 6c 6f 63 61 74 65 20 69 74 2e 0a 20 20 20  allocate it..   
1610: 20 2a 2f 0a 20 20 20 20 6e 42 79 74 65 73 20 3d   */.    nBytes =
1620: 20 73 69 7a 65 6f 66 28 63 68 61 72 20 2a 29 20   sizeof(char *) 
1630: 2a 20 6e 43 6f 6c 3b 0a 20 20 20 20 66 6f 72 28  * nCol;.    for(
1640: 69 69 3d 30 3b 20 69 69 3c 6e 43 6f 6c 3b 20 69  ii=0; ii<nCol; i
1650: 69 2b 2b 29 7b 0a 20 20 20 20 20 20 63 6f 6e 73  i++){.      cons
1660: 74 20 63 68 61 72 20 2a 7a 4e 61 6d 65 20 3d 20  t char *zName = 
1670: 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 6e  sqlite3_column_n
1680: 61 6d 65 28 70 53 74 6d 74 2c 20 69 69 29 3b 0a  ame(pStmt, ii);.
1690: 20 20 20 20 20 20 69 66 28 20 21 7a 4e 61 6d 65        if( !zName
16a0: 20 29 7b 0a 20 20 20 20 20 20 20 20 72 63 20 3d   ){.        rc =
16b0: 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20   SQLITE_NOMEM;. 
16c0: 20 20 20 20 20 20 20 67 6f 74 6f 20 6f 75 74 3b         goto out;
16d0: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 6e  .      }.      n
16e0: 42 79 74 65 73 20 2b 3d 20 73 74 72 6c 65 6e 28  Bytes += strlen(
16f0: 7a 4e 61 6d 65 29 2b 31 3b 0a 20 20 20 20 7d 0a  zName)+1;.    }.
1700: 20 20 20 20 61 43 6f 6c 20 3d 20 28 63 68 61 72      aCol = (char
1710: 20 2a 2a 29 73 71 6c 69 74 65 33 4d 61 6c 6c 6f   **)sqlite3Mallo
1720: 63 5a 65 72 6f 28 6e 42 79 74 65 73 29 3b 0a 20  cZero(nBytes);. 
1730: 20 20 20 69 66 28 20 21 61 43 6f 6c 20 29 7b 0a     if( !aCol ){.
1740: 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54        rc = SQLIT
1750: 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 20 20 67  E_NOMEM;.      g
1760: 6f 74 6f 20 6f 75 74 3b 0a 20 20 20 20 7d 0a 0a  oto out;.    }..
1770: 20 20 20 20 2f 2a 20 43 6f 70 79 20 74 68 65 20      /* Copy the 
1780: 63 6f 6c 75 6d 6e 20 6e 61 6d 65 73 20 69 6e 74  column names int
1790: 6f 20 74 68 65 20 61 6c 6c 6f 63 61 74 65 64 20  o the allocated 
17a0: 73 70 61 63 65 20 61 6e 64 20 73 65 74 20 75 70  space and set up
17b0: 20 74 68 65 0a 20 20 20 20 2a 2a 20 70 6f 69 6e   the.    ** poin
17c0: 74 65 72 73 20 69 6e 20 74 68 65 20 61 43 6f 6c  ters in the aCol
17d0: 5b 5d 20 61 72 72 61 79 2e 0a 20 20 20 20 2a 2f  [] array..    */
17e0: 0a 20 20 20 20 7a 53 70 61 63 65 20 3d 20 28 63  .    zSpace = (c
17f0: 68 61 72 20 2a 29 28 26 61 43 6f 6c 5b 6e 43 6f  har *)(&aCol[nCo
1800: 6c 5d 29 3b 0a 20 20 20 20 66 6f 72 28 69 69 3d  l]);.    for(ii=
1810: 30 3b 20 69 69 3c 6e 43 6f 6c 3b 20 69 69 2b 2b  0; ii<nCol; ii++
1820: 29 7b 0a 20 20 20 20 20 20 61 43 6f 6c 5b 69 69  ){.      aCol[ii
1830: 5d 20 3d 20 7a 53 70 61 63 65 3b 0a 20 20 20 20  ] = zSpace;.    
1840: 20 20 7a 53 70 61 63 65 20 2b 3d 20 73 70 72 69    zSpace += spri
1850: 6e 74 66 28 7a 53 70 61 63 65 2c 20 22 25 73 22  ntf(zSpace, "%s"
1860: 2c 20 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e  , sqlite3_column
1870: 5f 6e 61 6d 65 28 70 53 74 6d 74 2c 20 69 69 29  _name(pStmt, ii)
1880: 29 3b 0a 20 20 20 20 20 20 7a 53 70 61 63 65 2b  );.      zSpace+
1890: 2b 3b 0a 20 20 20 20 7d 0a 20 20 20 20 61 73 73  +;.    }.    ass
18a0: 65 72 74 28 20 28 7a 53 70 61 63 65 2d 6e 42 79  ert( (zSpace-nBy
18b0: 74 65 73 29 3d 3d 28 63 68 61 72 20 2a 29 61 43  tes)==(char *)aC
18c0: 6f 6c 20 29 3b 0a 20 20 7d 0a 0a 20 20 2a 70 61  ol );.  }..  *pa
18d0: 43 6f 6c 20 3d 20 61 43 6f 6c 3b 0a 20 20 2a 70  Col = aCol;.  *p
18e0: 6e 43 6f 6c 20 3d 20 6e 43 6f 6c 3b 0a 0a 6f 75  nCol = nCol;..ou
18f0: 74 3a 0a 20 20 73 71 6c 69 74 65 33 5f 66 69 6e  t:.  sqlite3_fin
1900: 61 6c 69 7a 65 28 70 53 74 6d 74 29 3b 0a 20 20  alize(pStmt);.  
1910: 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a  return rc;.}../*
1920: 0a 2a 2a 20 50 61 72 61 6d 65 74 65 72 20 7a 54  .** Parameter zT
1930: 61 62 20 69 73 20 74 68 65 20 6e 61 6d 65 20 6f  ab is the name o
1940: 66 20 61 20 74 61 62 6c 65 20 69 6e 20 64 61 74  f a table in dat
1950: 61 62 61 73 65 20 64 62 20 77 69 74 68 20 6e 43  abase db with nC
1960: 6f 6c 20 0a 2a 2a 20 63 6f 6c 75 6d 6e 73 2e 20  ol .** columns. 
1970: 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 61 6c  This function al
1980: 6c 6f 63 61 74 65 73 20 61 6e 20 61 72 72 61 79  locates an array
1990: 20 6f 66 20 69 6e 74 65 67 65 72 73 20 6e 43 6f   of integers nCo
19a0: 6c 20 69 6e 20 0a 2a 2a 20 73 69 7a 65 20 61 6e  l in .** size an
19b0: 64 20 70 6f 70 75 6c 61 74 65 73 20 69 74 20 61  d populates it a
19c0: 63 63 6f 72 64 69 6e 67 20 74 6f 20 61 6e 79 20  ccording to any 
19d0: 69 6d 70 6c 69 63 69 74 20 6f 72 20 65 78 70 6c  implicit or expl
19e0: 69 63 69 74 20 0a 2a 2a 20 69 6e 64 69 63 65 73  icit .** indices
19f0: 20 6f 6e 20 74 61 62 6c 65 20 7a 54 61 62 2e 0a   on table zTab..
1a00: 2a 2a 0a 2a 2a 20 49 66 20 73 75 63 63 65 73 73  **.** If success
1a10: 66 75 6c 2c 20 53 51 4c 49 54 45 5f 4f 4b 20 69  ful, SQLITE_OK i
1a20: 73 20 72 65 74 75 72 6e 65 64 20 61 6e 64 20 2a  s returned and *
1a30: 70 61 49 6e 64 65 78 20 73 65 74 20 74 6f 20 70  paIndex set to p
1a40: 6f 69 6e 74 20 0a 2a 2a 20 61 74 20 74 68 65 20  oint .** at the 
1a50: 61 6c 6c 6f 63 61 74 65 64 20 61 72 72 61 79 2e  allocated array.
1a60: 20 4f 74 68 65 72 77 69 73 65 2c 20 61 6e 20 65   Otherwise, an e
1a70: 72 72 6f 72 20 63 6f 64 65 20 69 73 20 72 65 74  rror code is ret
1a80: 75 72 6e 65 64 2e 0a 2a 2a 0a 2a 2a 20 53 65 65  urned..**.** See
1a90: 20 63 6f 6d 6d 65 6e 74 73 20 61 73 73 6f 63 69   comments associ
1aa0: 61 74 65 64 20 77 69 74 68 20 74 68 65 20 6d 65  ated with the me
1ab0: 6d 62 65 72 20 76 61 72 69 61 62 6c 65 20 61 49  mber variable aI
1ac0: 6e 64 65 78 20 61 62 6f 76 65 20 0a 2a 2a 20 22  ndex above .** "
1ad0: 73 74 72 75 63 74 20 65 63 68 6f 5f 76 74 61 62  struct echo_vtab
1ae0: 22 20 66 6f 72 20 64 65 74 61 69 6c 73 20 6f 66  " for details of
1af0: 20 74 68 65 20 63 6f 6e 74 65 6e 74 73 20 6f 66   the contents of
1b00: 20 74 68 65 20 61 72 72 61 79 2e 0a 2a 2f 0a 73   the array..*/.s
1b10: 74 61 74 69 63 20 69 6e 74 20 67 65 74 49 6e 64  tatic int getInd
1b20: 65 78 41 72 72 61 79 28 0a 20 20 73 71 6c 69 74  exArray(.  sqlit
1b30: 65 33 20 2a 64 62 2c 20 20 20 20 20 20 20 20 20  e3 *db,         
1b40: 20 20 20 20 2f 2a 20 44 61 74 61 62 61 73 65 20      /* Database 
1b50: 63 6f 6e 6e 65 63 74 69 6f 6e 20 2a 2f 0a 20 20  connection */.  
1b60: 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 54 61 62  const char *zTab
1b70: 2c 20 20 20 20 20 20 20 20 2f 2a 20 4e 61 6d 65  ,        /* Name
1b80: 20 6f 66 20 74 61 62 6c 65 20 69 6e 20 64 61 74   of table in dat
1b90: 61 62 61 73 65 20 64 62 20 2a 2f 0a 20 20 69 6e  abase db */.  in
1ba0: 74 20 6e 43 6f 6c 2c 0a 20 20 69 6e 74 20 2a 2a  t nCol,.  int **
1bb0: 70 61 49 6e 64 65 78 0a 29 7b 0a 20 20 73 71 6c  paIndex.){.  sql
1bc0: 69 74 65 33 5f 73 74 6d 74 20 2a 70 53 74 6d 74  ite3_stmt *pStmt
1bd0: 20 3d 20 30 3b 0a 20 20 69 6e 74 20 2a 61 49 6e   = 0;.  int *aIn
1be0: 64 65 78 20 3d 20 30 3b 0a 20 20 69 6e 74 20 72  dex = 0;.  int r
1bf0: 63 3b 0a 20 20 63 68 61 72 20 2a 7a 53 71 6c 3b  c;.  char *zSql;
1c00: 0a 0a 20 20 2f 2a 20 41 6c 6c 6f 63 61 74 65 20  ..  /* Allocate 
1c10: 73 70 61 63 65 20 66 6f 72 20 74 68 65 20 69 6e  space for the in
1c20: 64 65 78 20 61 72 72 61 79 20 2a 2f 0a 20 20 61  dex array */.  a
1c30: 49 6e 64 65 78 20 3d 20 28 69 6e 74 20 2a 29 73  Index = (int *)s
1c40: 71 6c 69 74 65 33 4d 61 6c 6c 6f 63 5a 65 72 6f  qlite3MallocZero
1c50: 28 73 69 7a 65 6f 66 28 69 6e 74 29 20 2a 20 6e  (sizeof(int) * n
1c60: 43 6f 6c 29 3b 0a 20 20 69 66 28 20 21 61 49 6e  Col);.  if( !aIn
1c70: 64 65 78 20 29 7b 0a 20 20 20 20 72 63 20 3d 20  dex ){.    rc = 
1c80: 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20  SQLITE_NOMEM;.  
1c90: 20 20 67 6f 74 6f 20 67 65 74 5f 69 6e 64 65 78    goto get_index
1ca0: 5f 61 72 72 61 79 5f 6f 75 74 3b 0a 20 20 7d 0a  _array_out;.  }.
1cb0: 0a 20 20 2f 2a 20 43 6f 6d 70 69 6c 65 20 61 6e  .  /* Compile an
1cc0: 20 73 71 6c 69 74 65 20 70 72 61 67 6d 61 20 74   sqlite pragma t
1cd0: 6f 20 6c 6f 6f 70 20 74 68 72 6f 75 67 68 20 61  o loop through a
1ce0: 6c 6c 20 69 6e 64 69 63 65 73 20 6f 6e 20 74 61  ll indices on ta
1cf0: 62 6c 65 20 7a 54 61 62 20 2a 2f 0a 20 20 7a 53  ble zTab */.  zS
1d00: 71 6c 20 3d 20 73 71 6c 69 74 65 33 4d 50 72 69  ql = sqlite3MPri
1d10: 6e 74 66 28 30 2c 20 22 50 52 41 47 4d 41 20 69  ntf(0, "PRAGMA i
1d20: 6e 64 65 78 5f 6c 69 73 74 28 25 73 29 22 2c 20  ndex_list(%s)", 
1d30: 7a 54 61 62 29 3b 0a 20 20 69 66 28 20 21 7a 53  zTab);.  if( !zS
1d40: 71 6c 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 53  ql ){.    rc = S
1d50: 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20  QLITE_NOMEM;.   
1d60: 20 67 6f 74 6f 20 67 65 74 5f 69 6e 64 65 78 5f   goto get_index_
1d70: 61 72 72 61 79 5f 6f 75 74 3b 0a 20 20 7d 0a 20  array_out;.  }. 
1d80: 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 70 72   rc = sqlite3_pr
1d90: 65 70 61 72 65 28 64 62 2c 20 7a 53 71 6c 2c 20  epare(db, zSql, 
1da0: 2d 31 2c 20 26 70 53 74 6d 74 2c 20 30 29 3b 0a  -1, &pStmt, 0);.
1db0: 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 7a    sqlite3_free(z
1dc0: 53 71 6c 29 3b 0a 0a 20 20 2f 2a 20 46 6f 72 20  Sql);..  /* For 
1dd0: 65 61 63 68 20 69 6e 64 65 78 2c 20 66 69 67 75  each index, figu
1de0: 72 65 20 6f 75 74 20 74 68 65 20 6c 65 66 74 2d  re out the left-
1df0: 6d 6f 73 74 20 63 6f 6c 75 6d 6e 20 61 6e 64 20  most column and 
1e00: 73 65 74 20 74 68 65 20 0a 20 20 2a 2a 20 63 6f  set the .  ** co
1e10: 72 72 65 73 70 6f 6e 64 69 6e 67 20 65 6e 74 72  rresponding entr
1e20: 79 20 69 6e 20 61 49 6e 64 65 78 5b 5d 20 74 6f  y in aIndex[] to
1e30: 20 31 2e 0a 20 20 2a 2f 0a 20 20 77 68 69 6c 65   1..  */.  while
1e40: 28 20 70 53 74 6d 74 20 26 26 20 73 71 6c 69 74  ( pStmt && sqlit
1e50: 65 33 5f 73 74 65 70 28 70 53 74 6d 74 29 3d 3d  e3_step(pStmt)==
1e60: 53 51 4c 49 54 45 5f 52 4f 57 20 29 7b 0a 20 20  SQLITE_ROW ){.  
1e70: 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 49    const char *zI
1e80: 64 78 20 3d 20 28 63 6f 6e 73 74 20 63 68 61 72  dx = (const char
1e90: 20 2a 29 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d   *)sqlite3_colum
1ea0: 6e 5f 74 65 78 74 28 70 53 74 6d 74 2c 20 31 29  n_text(pStmt, 1)
1eb0: 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 73 74  ;.    sqlite3_st
1ec0: 6d 74 20 2a 70 53 74 6d 74 32 20 3d 20 30 3b 0a  mt *pStmt2 = 0;.
1ed0: 20 20 20 20 7a 53 71 6c 20 3d 20 73 71 6c 69 74      zSql = sqlit
1ee0: 65 33 4d 50 72 69 6e 74 66 28 30 2c 20 22 50 52  e3MPrintf(0, "PR
1ef0: 41 47 4d 41 20 69 6e 64 65 78 5f 69 6e 66 6f 28  AGMA index_info(
1f00: 25 73 29 22 2c 20 7a 49 64 78 29 3b 0a 20 20 20  %s)", zIdx);.   
1f10: 20 69 66 28 20 21 7a 53 71 6c 20 29 7b 0a 20 20   if( !zSql ){.  
1f20: 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f      rc = SQLITE_
1f30: 4e 4f 4d 45 4d 3b 0a 20 20 20 20 20 20 67 6f 74  NOMEM;.      got
1f40: 6f 20 67 65 74 5f 69 6e 64 65 78 5f 61 72 72 61  o get_index_arra
1f50: 79 5f 6f 75 74 3b 0a 20 20 20 20 7d 0a 20 20 20  y_out;.    }.   
1f60: 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 70 72   rc = sqlite3_pr
1f70: 65 70 61 72 65 28 64 62 2c 20 7a 53 71 6c 2c 20  epare(db, zSql, 
1f80: 2d 31 2c 20 26 70 53 74 6d 74 32 2c 20 30 29 3b  -1, &pStmt2, 0);
1f90: 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65  .    sqlite3_fre
1fa0: 65 28 7a 53 71 6c 29 3b 0a 20 20 20 20 69 66 28  e(zSql);.    if(
1fb0: 20 70 53 74 6d 74 32 20 26 26 20 73 71 6c 69 74   pStmt2 && sqlit
1fc0: 65 33 5f 73 74 65 70 28 70 53 74 6d 74 32 29 3d  e3_step(pStmt2)=
1fd0: 3d 53 51 4c 49 54 45 5f 52 4f 57 20 29 7b 0a 20  =SQLITE_ROW ){. 
1fe0: 20 20 20 20 20 69 6e 74 20 63 69 64 20 3d 20 73       int cid = s
1ff0: 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 69 6e  qlite3_column_in
2000: 74 28 70 53 74 6d 74 32 2c 20 31 29 3b 0a 20 20  t(pStmt2, 1);.  
2010: 20 20 20 20 61 73 73 65 72 74 28 20 63 69 64 3e      assert( cid>
2020: 3d 30 20 26 26 20 63 69 64 3c 6e 43 6f 6c 20 29  =0 && cid<nCol )
2030: 3b 0a 20 20 20 20 20 20 61 49 6e 64 65 78 5b 63  ;.      aIndex[c
2040: 69 64 5d 20 3d 20 31 3b 0a 20 20 20 20 7d 0a 20  id] = 1;.    }. 
2050: 20 20 20 69 66 28 20 70 53 74 6d 74 32 20 29 7b     if( pStmt2 ){
2060: 0a 20 20 20 20 20 20 72 63 20 3d 20 73 71 6c 69  .      rc = sqli
2070: 74 65 33 5f 66 69 6e 61 6c 69 7a 65 28 70 53 74  te3_finalize(pSt
2080: 6d 74 32 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20  mt2);.    }.    
2090: 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f  if( rc!=SQLITE_O
20a0: 4b 20 29 7b 0a 20 20 20 20 20 20 67 6f 74 6f 20  K ){.      goto 
20b0: 67 65 74 5f 69 6e 64 65 78 5f 61 72 72 61 79 5f  get_index_array_
20c0: 6f 75 74 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a  out;.    }.  }..
20d0: 0a 67 65 74 5f 69 6e 64 65 78 5f 61 72 72 61 79  .get_index_array
20e0: 5f 6f 75 74 3a 0a 20 20 69 66 28 20 70 53 74 6d  _out:.  if( pStm
20f0: 74 20 29 7b 0a 20 20 20 20 69 6e 74 20 72 63 32  t ){.    int rc2
2100: 20 3d 20 73 71 6c 69 74 65 33 5f 66 69 6e 61 6c   = sqlite3_final
2110: 69 7a 65 28 70 53 74 6d 74 29 3b 0a 20 20 20 20  ize(pStmt);.    
2120: 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  if( rc==SQLITE_O
2130: 4b 20 29 7b 0a 20 20 20 20 20 20 72 63 20 3d 20  K ){.      rc = 
2140: 72 63 32 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20  rc2;.    }.  }. 
2150: 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f   if( rc!=SQLITE_
2160: 4f 4b 20 29 7b 0a 20 20 20 20 73 71 6c 69 74 65  OK ){.    sqlite
2170: 33 5f 66 72 65 65 28 61 49 6e 64 65 78 29 3b 0a  3_free(aIndex);.
2180: 20 20 20 20 61 49 6e 64 65 78 20 3d 20 30 3b 0a      aIndex = 0;.
2190: 20 20 7d 0a 20 20 2a 70 61 49 6e 64 65 78 20 3d    }.  *paIndex =
21a0: 20 61 49 6e 64 65 78 3b 0a 20 20 72 65 74 75 72   aIndex;.  retur
21b0: 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 47  n rc;.}../*.** G
21c0: 6c 6f 62 61 6c 20 54 63 6c 20 76 61 72 69 61 62  lobal Tcl variab
21d0: 6c 65 20 24 65 63 68 6f 5f 6d 6f 64 75 6c 65 20  le $echo_module 
21e0: 69 73 20 61 20 6c 69 73 74 2e 20 54 68 69 73 20  is a list. This 
21f0: 72 6f 75 74 69 6e 65 20 61 70 70 65 6e 64 73 0a  routine appends.
2200: 2a 2a 20 74 68 65 20 73 74 72 69 6e 67 20 65 6c  ** the string el
2210: 65 6d 65 6e 74 20 7a 41 72 67 20 74 6f 20 74 68  ement zArg to th
2220: 61 74 20 6c 69 73 74 20 69 6e 20 69 6e 74 65 72  at list in inter
2230: 70 72 65 74 65 72 20 69 6e 74 65 72 70 2e 0a 2a  preter interp..*
2240: 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 61 70  /.static void ap
2250: 70 65 6e 64 54 6f 45 63 68 6f 4d 6f 64 75 6c 65  pendToEchoModule
2260: 28 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74  (Tcl_Interp *int
2270: 65 72 70 2c 20 63 6f 6e 73 74 20 63 68 61 72 20  erp, const char 
2280: 2a 7a 41 72 67 29 7b 0a 20 20 69 6e 74 20 66 6c  *zArg){.  int fl
2290: 61 67 73 20 3d 20 28 54 43 4c 5f 41 50 50 45 4e  ags = (TCL_APPEN
22a0: 44 5f 56 41 4c 55 45 20 7c 20 54 43 4c 5f 4c 49  D_VALUE | TCL_LI
22b0: 53 54 5f 45 4c 45 4d 45 4e 54 20 7c 20 54 43 4c  ST_ELEMENT | TCL
22c0: 5f 47 4c 4f 42 41 4c 5f 4f 4e 4c 59 29 3b 0a 20  _GLOBAL_ONLY);. 
22d0: 20 54 63 6c 5f 53 65 74 56 61 72 28 69 6e 74 65   Tcl_SetVar(inte
22e0: 72 70 2c 20 22 65 63 68 6f 5f 6d 6f 64 75 6c 65  rp, "echo_module
22f0: 22 2c 20 28 7a 41 72 67 3f 7a 41 72 67 3a 22 22  ", (zArg?zArg:""
2300: 29 2c 20 66 6c 61 67 73 29 3b 0a 7d 0a 0a 2f 2a  ), flags);.}../*
2310: 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63 74 69 6f  .** This functio
2320: 6e 20 69 73 20 63 61 6c 6c 65 64 20 66 72 6f 6d  n is called from
2330: 20 77 69 74 68 69 6e 20 74 68 65 20 65 63 68 6f   within the echo
2340: 2d 6d 6f 64 75 6c 65 73 20 78 43 72 65 61 74 65  -modules xCreate
2350: 20 61 6e 64 0a 2a 2a 20 78 43 6f 6e 6e 65 63 74   and.** xConnect
2360: 20 6d 65 74 68 6f 64 73 2e 20 54 68 65 20 61 72   methods. The ar
2370: 67 63 20 61 6e 64 20 61 72 67 76 20 61 72 67 75  gc and argv argu
2380: 6d 65 6e 74 73 20 61 72 65 20 63 6f 70 69 65 73  ments are copies
2390: 20 6f 66 20 74 68 6f 73 65 20 0a 2a 2a 20 70 61   of those .** pa
23a0: 73 73 65 64 20 74 6f 20 74 68 65 20 63 61 6c 6c  ssed to the call
23b0: 69 6e 67 20 6d 65 74 68 6f 64 2e 20 54 68 69 73  ing method. This
23c0: 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 72 65 73   function is res
23d0: 70 6f 6e 73 69 62 6c 65 20 66 6f 72 0a 2a 2a 20  ponsible for.** 
23e0: 63 61 6c 6c 69 6e 67 20 73 71 6c 69 74 65 33 5f  calling sqlite3_
23f0: 64 65 63 6c 61 72 65 5f 76 74 61 62 28 29 20 74  declare_vtab() t
2400: 6f 20 64 65 63 6c 61 72 65 20 74 68 65 20 73 63  o declare the sc
2410: 68 65 6d 61 20 6f 66 20 74 68 65 20 76 69 72 74  hema of the virt
2420: 75 61 6c 0a 2a 2a 20 74 61 62 6c 65 20 62 65 69  ual.** table bei
2430: 6e 67 20 63 72 65 61 74 65 64 20 6f 72 20 63 6f  ng created or co
2440: 6e 6e 65 63 74 65 64 2e 0a 2a 2a 0a 2a 2a 20 49  nnected..**.** I
2450: 66 20 74 68 65 20 63 6f 6e 73 74 72 75 63 74 6f  f the constructo
2460: 72 20 77 61 73 20 70 61 73 73 65 64 20 6a 75 73  r was passed jus
2470: 74 20 6f 6e 65 20 61 72 67 75 6d 65 6e 74 2c 20  t one argument, 
2480: 69 2e 65 2e 3a 0a 2a 2a 0a 2a 2a 20 20 20 43 52  i.e.:.**.**   CR
2490: 45 41 54 45 20 54 41 42 4c 45 20 74 31 20 41 53  EATE TABLE t1 AS
24a0: 20 65 63 68 6f 28 74 32 29 3b 0a 2a 2a 0a 2a 2a   echo(t2);.**.**
24b0: 20 54 68 65 6e 20 74 32 20 69 73 20 61 73 73 75   Then t2 is assu
24c0: 6d 65 64 20 74 6f 20 62 65 20 74 68 65 20 6e 61  med to be the na
24d0: 6d 65 20 6f 66 20 61 20 2a 72 65 61 6c 2a 20 64  me of a *real* d
24e0: 61 74 61 62 61 73 65 20 74 61 62 6c 65 2e 20 54  atabase table. T
24f0: 68 65 0a 2a 2a 20 73 63 68 65 6d 61 20 6f 66 20  he.** schema of 
2500: 74 68 65 20 76 69 72 74 75 61 6c 20 74 61 62 6c  the virtual tabl
2510: 65 20 69 73 20 64 65 63 6c 61 72 65 64 20 62 79  e is declared by
2520: 20 70 61 73 73 69 6e 67 20 61 20 63 6f 70 79 20   passing a copy 
2530: 6f 66 20 74 68 65 20 0a 2a 2a 20 43 52 45 41 54  of the .** CREAT
2540: 45 20 54 41 42 4c 45 20 73 74 61 74 65 6d 65 6e  E TABLE statemen
2550: 74 20 66 6f 72 20 74 68 65 20 72 65 61 6c 20 74  t for the real t
2560: 61 62 6c 65 20 74 6f 20 73 71 6c 69 74 65 33 5f  able to sqlite3_
2570: 64 65 63 6c 61 72 65 5f 76 74 61 62 28 29 2e 0a  declare_vtab()..
2580: 2a 2a 20 48 65 6e 63 65 2c 20 74 68 65 20 76 69  ** Hence, the vi
2590: 72 74 75 61 6c 20 74 61 62 6c 65 20 73 68 6f 75  rtual table shou
25a0: 6c 64 20 68 61 76 65 20 65 78 61 63 74 6c 79 20  ld have exactly 
25b0: 74 68 65 20 73 61 6d 65 20 63 6f 6c 75 6d 6e 20  the same column 
25c0: 6e 61 6d 65 73 20 61 6e 64 20 0a 2a 2a 20 74 79  names and .** ty
25d0: 70 65 73 20 61 73 20 74 68 65 20 72 65 61 6c 20  pes as the real 
25e0: 74 61 62 6c 65 2e 0a 2a 2f 0a 73 74 61 74 69 63  table..*/.static
25f0: 20 69 6e 74 20 65 63 68 6f 44 65 63 6c 61 72 65   int echoDeclare
2600: 56 74 61 62 28 0a 20 20 65 63 68 6f 5f 76 74 61  Vtab(.  echo_vta
2610: 62 20 2a 70 56 74 61 62 2c 20 0a 20 20 73 71 6c  b *pVtab, .  sql
2620: 69 74 65 33 20 2a 64 62 20 0a 29 7b 0a 20 20 69  ite3 *db .){.  i
2630: 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f  nt rc = SQLITE_O
2640: 4b 3b 0a 0a 20 20 69 66 28 20 70 56 74 61 62 2d  K;..  if( pVtab-
2650: 3e 7a 54 61 62 6c 65 4e 61 6d 65 20 29 7b 0a 20  >zTableName ){. 
2660: 20 20 20 73 71 6c 69 74 65 33 5f 73 74 6d 74 20     sqlite3_stmt 
2670: 2a 70 53 74 6d 74 20 3d 20 30 3b 0a 20 20 20 20  *pStmt = 0;.    
2680: 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 70 72 65  rc = sqlite3_pre
2690: 70 61 72 65 28 64 62 2c 20 0a 20 20 20 20 20 20  pare(db, .      
26a0: 20 20 22 53 45 4c 45 43 54 20 73 71 6c 20 46 52    "SELECT sql FR
26b0: 4f 4d 20 73 71 6c 69 74 65 5f 6d 61 73 74 65 72  OM sqlite_master
26c0: 20 57 48 45 52 45 20 74 79 70 65 20 3d 20 27 74   WHERE type = 't
26d0: 61 62 6c 65 27 20 41 4e 44 20 6e 61 6d 65 20 3d  able' AND name =
26e0: 20 3f 22 2c 0a 20 20 20 20 20 20 20 20 2d 31 2c   ?",.        -1,
26f0: 20 26 70 53 74 6d 74 2c 20 30 29 3b 0a 20 20 20   &pStmt, 0);.   
2700: 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
2710: 4f 4b 20 29 7b 0a 20 20 20 20 20 20 73 71 6c 69  OK ){.      sqli
2720: 74 65 33 5f 62 69 6e 64 5f 74 65 78 74 28 70 53  te3_bind_text(pS
2730: 74 6d 74 2c 20 31 2c 20 70 56 74 61 62 2d 3e 7a  tmt, 1, pVtab->z
2740: 54 61 62 6c 65 4e 61 6d 65 2c 20 2d 31 2c 20 30  TableName, -1, 0
2750: 29 3b 0a 20 20 20 20 20 20 69 66 28 20 73 71 6c  );.      if( sql
2760: 69 74 65 33 5f 73 74 65 70 28 70 53 74 6d 74 29  ite3_step(pStmt)
2770: 3d 3d 53 51 4c 49 54 45 5f 52 4f 57 20 29 7b 0a  ==SQLITE_ROW ){.
2780: 20 20 20 20 20 20 20 20 69 6e 74 20 72 63 32 3b          int rc2;
2790: 0a 20 20 20 20 20 20 20 20 63 6f 6e 73 74 20 63  .        const c
27a0: 68 61 72 20 2a 7a 43 72 65 61 74 65 54 61 62 6c  har *zCreateTabl
27b0: 65 20 3d 20 28 63 6f 6e 73 74 20 63 68 61 72 20  e = (const char 
27c0: 2a 29 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e  *)sqlite3_column
27d0: 5f 74 65 78 74 28 70 53 74 6d 74 2c 20 30 29 3b  _text(pStmt, 0);
27e0: 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20 73 71  .        rc = sq
27f0: 6c 69 74 65 33 5f 64 65 63 6c 61 72 65 5f 76 74  lite3_declare_vt
2800: 61 62 28 64 62 2c 20 7a 43 72 65 61 74 65 54 61  ab(db, zCreateTa
2810: 62 6c 65 29 3b 0a 20 20 20 20 20 20 20 20 72 63  ble);.        rc
2820: 32 20 3d 20 73 71 6c 69 74 65 33 5f 66 69 6e 61  2 = sqlite3_fina
2830: 6c 69 7a 65 28 70 53 74 6d 74 29 3b 0a 20 20 20  lize(pStmt);.   
2840: 20 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c       if( rc==SQL
2850: 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20  ITE_OK ){.      
2860: 20 20 20 20 72 63 20 3d 20 72 63 32 3b 0a 20 20      rc = rc2;.  
2870: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7d 20        }.      } 
2880: 65 6c 73 65 20 7b 0a 20 20 20 20 20 20 20 20 72  else {.        r
2890: 63 20 3d 20 73 71 6c 69 74 65 33 5f 66 69 6e 61  c = sqlite3_fina
28a0: 6c 69 7a 65 28 70 53 74 6d 74 29 3b 0a 20 20 20  lize(pStmt);.   
28b0: 20 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c       if( rc==SQL
28c0: 49 54 45 5f 4f 4b 20 29 7b 20 0a 20 20 20 20 20  ITE_OK ){ .     
28d0: 20 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45       rc = SQLITE
28e0: 5f 45 52 52 4f 52 3b 0a 20 20 20 20 20 20 20 20  _ERROR;.        
28f0: 7d 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20  }.      }.      
2900: 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  if( rc==SQLITE_O
2910: 4b 20 29 7b 0a 20 20 20 20 20 20 20 20 72 63 20  K ){.        rc 
2920: 3d 20 67 65 74 43 6f 6c 75 6d 6e 4e 61 6d 65 73  = getColumnNames
2930: 28 64 62 2c 20 70 56 74 61 62 2d 3e 7a 54 61 62  (db, pVtab->zTab
2940: 6c 65 4e 61 6d 65 2c 20 26 70 56 74 61 62 2d 3e  leName, &pVtab->
2950: 61 43 6f 6c 2c 20 26 70 56 74 61 62 2d 3e 6e 43  aCol, &pVtab->nC
2960: 6f 6c 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20  ol);.      }.   
2970: 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54     if( rc==SQLIT
2980: 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20 20  E_OK ){.        
2990: 72 63 20 3d 20 67 65 74 49 6e 64 65 78 41 72 72  rc = getIndexArr
29a0: 61 79 28 64 62 2c 20 70 56 74 61 62 2d 3e 7a 54  ay(db, pVtab->zT
29b0: 61 62 6c 65 4e 61 6d 65 2c 20 70 56 74 61 62 2d  ableName, pVtab-
29c0: 3e 6e 43 6f 6c 2c 20 26 70 56 74 61 62 2d 3e 61  >nCol, &pVtab->a
29d0: 49 6e 64 65 78 29 3b 0a 20 20 20 20 20 20 7d 0a  Index);.      }.
29e0: 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 72 65 74      }.  }..  ret
29f0: 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  urn rc;.}../*.**
2a00: 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 66   This function f
2a10: 72 65 65 73 20 61 6c 6c 20 72 75 6e 74 69 6d 65  rees all runtime
2a20: 20 73 74 72 75 63 74 75 72 65 73 20 61 73 73 6f   structures asso
2a30: 63 69 61 74 65 64 20 77 69 74 68 20 74 68 65 20  ciated with the 
2a40: 76 69 72 74 75 61 6c 0a 2a 2a 20 74 61 62 6c 65  virtual.** table
2a50: 20 70 56 74 61 62 2e 0a 2a 2f 0a 73 74 61 74 69   pVtab..*/.stati
2a60: 63 20 69 6e 74 20 65 63 68 6f 44 65 73 74 72 75  c int echoDestru
2a70: 63 74 6f 72 28 73 71 6c 69 74 65 33 5f 76 74 61  ctor(sqlite3_vta
2a80: 62 20 2a 70 56 74 61 62 29 7b 0a 20 20 65 63 68  b *pVtab){.  ech
2a90: 6f 5f 76 74 61 62 20 2a 70 20 3d 20 28 65 63 68  o_vtab *p = (ech
2aa0: 6f 5f 76 74 61 62 2a 29 70 56 74 61 62 3b 0a 20  o_vtab*)pVtab;. 
2ab0: 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70 2d   sqlite3_free(p-
2ac0: 3e 61 49 6e 64 65 78 29 3b 0a 20 20 73 71 6c 69  >aIndex);.  sqli
2ad0: 74 65 33 5f 66 72 65 65 28 70 2d 3e 61 43 6f 6c  te3_free(p->aCol
2ae0: 29 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66 72 65  );.  sqlite3_fre
2af0: 65 28 70 2d 3e 7a 54 68 69 73 29 3b 0a 20 20 73  e(p->zThis);.  s
2b00: 71 6c 69 74 65 33 5f 66 72 65 65 28 70 2d 3e 7a  qlite3_free(p->z
2b10: 54 61 62 6c 65 4e 61 6d 65 29 3b 0a 20 20 73 71  TableName);.  sq
2b20: 6c 69 74 65 33 5f 66 72 65 65 28 70 2d 3e 7a 4c  lite3_free(p->zL
2b30: 6f 67 4e 61 6d 65 29 3b 0a 20 20 73 71 6c 69 74  ogName);.  sqlit
2b40: 65 33 5f 66 72 65 65 28 70 29 3b 0a 20 20 72 65  e3_free(p);.  re
2b50: 74 75 72 6e 20 30 3b 0a 7d 0a 0a 74 79 70 65 64  turn 0;.}..typed
2b60: 65 66 20 73 74 72 75 63 74 20 45 63 68 6f 4d 6f  ef struct EchoMo
2b70: 64 75 6c 65 20 45 63 68 6f 4d 6f 64 75 6c 65 3b  dule EchoModule;
2b80: 0a 73 74 72 75 63 74 20 45 63 68 6f 4d 6f 64 75  .struct EchoModu
2b90: 6c 65 20 7b 0a 20 20 54 63 6c 5f 49 6e 74 65 72  le {.  Tcl_Inter
2ba0: 70 20 2a 69 6e 74 65 72 70 3b 0a 7d 3b 0a 0a 2f  p *interp;.};../
2bb0: 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63 74 69  *.** This functi
2bc0: 6f 6e 20 69 73 20 63 61 6c 6c 65 64 20 74 6f 20  on is called to 
2bd0: 64 6f 20 74 68 65 20 77 6f 72 6b 20 6f 66 20 74  do the work of t
2be0: 68 65 20 78 43 6f 6e 6e 65 63 74 28 29 20 6d 65  he xConnect() me
2bf0: 74 68 6f 64 20 2d 0a 2a 2a 20 74 6f 20 61 6c 6c  thod -.** to all
2c00: 6f 63 61 74 65 20 74 68 65 20 72 65 71 75 69 72  ocate the requir
2c10: 65 64 20 69 6e 2d 6d 65 6d 6f 72 79 20 73 74 72  ed in-memory str
2c20: 75 63 74 75 72 65 73 20 66 6f 72 20 61 20 6e 65  uctures for a ne
2c30: 77 6c 79 20 63 6f 6e 6e 65 63 74 65 64 0a 2a 2a  wly connected.**
2c40: 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65 2e 0a   virtual table..
2c50: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 65 63  */.static int ec
2c60: 68 6f 43 6f 6e 73 74 72 75 63 74 6f 72 28 0a 20  hoConstructor(. 
2c70: 20 73 71 6c 69 74 65 33 20 2a 64 62 2c 0a 20 20   sqlite3 *db,.  
2c80: 76 6f 69 64 20 2a 70 41 75 78 2c 0a 20 20 69 6e  void *pAux,.  in
2c90: 74 20 61 72 67 63 2c 20 63 6f 6e 73 74 20 63 68  t argc, const ch
2ca0: 61 72 20 2a 63 6f 6e 73 74 2a 61 72 67 76 2c 0a  ar *const*argv,.
2cb0: 20 20 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a    sqlite3_vtab *
2cc0: 2a 70 70 56 74 61 62 2c 0a 20 20 63 68 61 72 20  *ppVtab,.  char 
2cd0: 2a 2a 70 7a 45 72 72 0a 29 7b 0a 20 20 69 6e 74  **pzErr.){.  int
2ce0: 20 72 63 3b 0a 20 20 69 6e 74 20 69 3b 0a 20 20   rc;.  int i;.  
2cf0: 65 63 68 6f 5f 76 74 61 62 20 2a 70 56 74 61 62  echo_vtab *pVtab
2d00: 3b 0a 0a 20 20 2f 2a 20 41 6c 6c 6f 63 61 74 65  ;..  /* Allocate
2d10: 20 74 68 65 20 73 71 6c 69 74 65 33 5f 76 74 61   the sqlite3_vta
2d20: 62 2f 65 63 68 6f 5f 76 74 61 62 20 73 74 72 75  b/echo_vtab stru
2d30: 63 74 75 72 65 20 69 74 73 65 6c 66 20 2a 2f 0a  cture itself */.
2d40: 20 20 70 56 74 61 62 20 3d 20 73 71 6c 69 74 65    pVtab = sqlite
2d50: 33 4d 61 6c 6c 6f 63 5a 65 72 6f 28 20 73 69 7a  3MallocZero( siz
2d60: 65 6f 66 28 2a 70 56 74 61 62 29 20 29 3b 0a 20  eof(*pVtab) );. 
2d70: 20 69 66 28 20 21 70 56 74 61 62 20 29 7b 0a 20   if( !pVtab ){. 
2d80: 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45     return SQLITE
2d90: 5f 4e 4f 4d 45 4d 3b 0a 20 20 7d 0a 20 20 70 56  _NOMEM;.  }.  pV
2da0: 74 61 62 2d 3e 69 6e 74 65 72 70 20 3d 20 28 28  tab->interp = ((
2db0: 45 63 68 6f 4d 6f 64 75 6c 65 20 2a 29 70 41 75  EchoModule *)pAu
2dc0: 78 29 2d 3e 69 6e 74 65 72 70 3b 0a 20 20 70 56  x)->interp;.  pV
2dd0: 74 61 62 2d 3e 64 62 20 3d 20 64 62 3b 0a 0a 20  tab->db = db;.. 
2de0: 20 2f 2a 20 41 6c 6c 6f 63 61 74 65 20 65 63 68   /* Allocate ech
2df0: 6f 5f 76 74 61 62 2e 7a 54 68 69 73 20 2a 2f 0a  o_vtab.zThis */.
2e00: 20 20 70 56 74 61 62 2d 3e 7a 54 68 69 73 20 3d    pVtab->zThis =
2e10: 20 73 71 6c 69 74 65 33 4d 50 72 69 6e 74 66 28   sqlite3MPrintf(
2e20: 30 2c 20 22 25 73 22 2c 20 61 72 67 76 5b 32 5d  0, "%s", argv[2]
2e30: 29 3b 0a 20 20 69 66 28 20 21 70 56 74 61 62 2d  );.  if( !pVtab-
2e40: 3e 7a 54 68 69 73 20 29 7b 0a 20 20 20 20 65 63  >zThis ){.    ec
2e50: 68 6f 44 65 73 74 72 75 63 74 6f 72 28 28 73 71  hoDestructor((sq
2e60: 6c 69 74 65 33 5f 76 74 61 62 20 2a 29 70 56 74  lite3_vtab *)pVt
2e70: 61 62 29 3b 0a 20 20 20 20 72 65 74 75 72 6e 20  ab);.    return 
2e80: 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20  SQLITE_NOMEM;.  
2e90: 7d 0a 0a 20 20 2f 2a 20 41 6c 6c 6f 63 61 74 65  }..  /* Allocate
2ea0: 20 65 63 68 6f 5f 76 74 61 62 2e 7a 54 61 62 6c   echo_vtab.zTabl
2eb0: 65 4e 61 6d 65 20 2a 2f 0a 20 20 69 66 28 20 61  eName */.  if( a
2ec0: 72 67 63 3e 33 20 29 7b 0a 20 20 20 20 70 56 74  rgc>3 ){.    pVt
2ed0: 61 62 2d 3e 7a 54 61 62 6c 65 4e 61 6d 65 20 3d  ab->zTableName =
2ee0: 20 73 71 6c 69 74 65 33 4d 50 72 69 6e 74 66 28   sqlite3MPrintf(
2ef0: 30 2c 20 22 25 73 22 2c 20 61 72 67 76 5b 33 5d  0, "%s", argv[3]
2f00: 29 3b 0a 20 20 20 20 64 65 71 75 6f 74 65 53 74  );.    dequoteSt
2f10: 72 69 6e 67 28 70 56 74 61 62 2d 3e 7a 54 61 62  ring(pVtab->zTab
2f20: 6c 65 4e 61 6d 65 29 3b 0a 20 20 20 20 69 66 28  leName);.    if(
2f30: 20 70 56 74 61 62 2d 3e 7a 54 61 62 6c 65 4e 61   pVtab->zTableNa
2f40: 6d 65 20 26 26 20 70 56 74 61 62 2d 3e 7a 54 61  me && pVtab->zTa
2f50: 62 6c 65 4e 61 6d 65 5b 30 5d 3d 3d 27 2a 27 20  bleName[0]=='*' 
2f60: 29 7b 0a 20 20 20 20 20 20 63 68 61 72 20 2a 7a  ){.      char *z
2f70: 20 3d 20 73 71 6c 69 74 65 33 4d 50 72 69 6e 74   = sqlite3MPrint
2f80: 66 28 30 2c 20 22 25 73 25 73 22 2c 20 61 72 67  f(0, "%s%s", arg
2f90: 76 5b 32 5d 2c 20 26 28 70 56 74 61 62 2d 3e 7a  v[2], &(pVtab->z
2fa0: 54 61 62 6c 65 4e 61 6d 65 5b 31 5d 29 29 3b 0a  TableName[1]));.
2fb0: 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72        sqlite3_fr
2fc0: 65 65 28 70 56 74 61 62 2d 3e 7a 54 61 62 6c 65  ee(pVtab->zTable
2fd0: 4e 61 6d 65 29 3b 0a 20 20 20 20 20 20 70 56 74  Name);.      pVt
2fe0: 61 62 2d 3e 7a 54 61 62 6c 65 4e 61 6d 65 20 3d  ab->zTableName =
2ff0: 20 7a 3b 0a 20 20 20 20 20 20 70 56 74 61 62 2d   z;.      pVtab-
3000: 3e 69 73 50 61 74 74 65 72 6e 20 3d 20 31 3b 0a  >isPattern = 1;.
3010: 20 20 20 20 7d 0a 20 20 20 20 69 66 28 20 21 70      }.    if( !p
3020: 56 74 61 62 2d 3e 7a 54 61 62 6c 65 4e 61 6d 65  Vtab->zTableName
3030: 20 29 7b 0a 20 20 20 20 20 20 65 63 68 6f 44 65   ){.      echoDe
3040: 73 74 72 75 63 74 6f 72 28 28 73 71 6c 69 74 65  structor((sqlite
3050: 33 5f 76 74 61 62 20 2a 29 70 56 74 61 62 29 3b  3_vtab *)pVtab);
3060: 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20 53 51  .      return SQ
3070: 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20  LITE_NOMEM;.    
3080: 7d 0a 20 20 7d 0a 0a 20 20 2f 2a 20 4c 6f 67 20  }.  }..  /* Log 
3090: 74 68 65 20 61 72 67 75 6d 65 6e 74 73 20 74 6f  the arguments to
30a0: 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 74   this function t
30b0: 6f 20 54 63 6c 20 76 61 72 20 3a 3a 65 63 68 6f  o Tcl var ::echo
30c0: 5f 6d 6f 64 75 6c 65 20 2a 2f 0a 20 20 66 6f 72  _module */.  for
30d0: 28 69 3d 30 3b 20 69 3c 61 72 67 63 3b 20 69 2b  (i=0; i<argc; i+
30e0: 2b 29 7b 0a 20 20 20 20 61 70 70 65 6e 64 54 6f  +){.    appendTo
30f0: 45 63 68 6f 4d 6f 64 75 6c 65 28 70 56 74 61 62  EchoModule(pVtab
3100: 2d 3e 69 6e 74 65 72 70 2c 20 61 72 67 76 5b 69  ->interp, argv[i
3110: 5d 29 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 49 6e  ]);.  }..  /* In
3120: 76 6f 6b 65 20 73 71 6c 69 74 65 33 5f 64 65 63  voke sqlite3_dec
3130: 6c 61 72 65 5f 76 74 61 62 20 61 6e 64 20 73 65  lare_vtab and se
3140: 74 20 75 70 20 6f 74 68 65 72 20 6d 65 6d 62 65  t up other membe
3150: 72 73 20 6f 66 20 74 68 65 20 65 63 68 6f 5f 76  rs of the echo_v
3160: 74 61 62 0a 20 20 2a 2a 20 73 74 72 75 63 74 75  tab.  ** structu
3170: 72 65 2e 20 49 66 20 61 6e 20 65 72 72 6f 72 20  re. If an error 
3180: 6f 63 63 75 72 73 2c 20 64 65 6c 65 74 65 20 74  occurs, delete t
3190: 68 65 20 73 71 6c 69 74 65 33 5f 76 74 61 62 20  he sqlite3_vtab 
31a0: 73 74 72 75 63 74 75 72 65 20 61 6e 64 0a 20 20  structure and.  
31b0: 2a 2a 20 72 65 74 75 72 6e 20 61 6e 20 65 72 72  ** return an err
31c0: 6f 72 20 63 6f 64 65 2e 0a 20 20 2a 2f 0a 20 20  or code..  */.  
31d0: 72 63 20 3d 20 65 63 68 6f 44 65 63 6c 61 72 65  rc = echoDeclare
31e0: 56 74 61 62 28 70 56 74 61 62 2c 20 64 62 29 3b  Vtab(pVtab, db);
31f0: 0a 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54  .  if( rc!=SQLIT
3200: 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 65 63 68 6f  E_OK ){.    echo
3210: 44 65 73 74 72 75 63 74 6f 72 28 28 73 71 6c 69  Destructor((sqli
3220: 74 65 33 5f 76 74 61 62 20 2a 29 70 56 74 61 62  te3_vtab *)pVtab
3230: 29 3b 0a 20 20 20 20 72 65 74 75 72 6e 20 72 63  );.    return rc
3240: 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 53 75 63 63  ;.  }..  /* Succ
3250: 65 73 73 2e 20 53 65 74 20 2a 70 70 56 74 61 62  ess. Set *ppVtab
3260: 20 61 6e 64 20 72 65 74 75 72 6e 20 2a 2f 0a 20   and return */. 
3270: 20 2a 70 70 56 74 61 62 20 3d 20 26 70 56 74 61   *ppVtab = &pVta
3280: 62 2d 3e 62 61 73 65 3b 0a 20 20 72 65 74 75 72  b->base;.  retur
3290: 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a  n SQLITE_OK;.}..
32a0: 2f 2a 20 0a 2a 2a 20 45 63 68 6f 20 76 69 72 74  /* .** Echo virt
32b0: 75 61 6c 20 74 61 62 6c 65 20 6d 6f 64 75 6c 65  ual table module
32c0: 20 78 43 72 65 61 74 65 20 6d 65 74 68 6f 64 2e   xCreate method.
32d0: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 65  .*/.static int e
32e0: 63 68 6f 43 72 65 61 74 65 28 0a 20 20 73 71 6c  choCreate(.  sql
32f0: 69 74 65 33 20 2a 64 62 2c 0a 20 20 76 6f 69 64  ite3 *db,.  void
3300: 20 2a 70 41 75 78 2c 0a 20 20 69 6e 74 20 61 72   *pAux,.  int ar
3310: 67 63 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a  gc, const char *
3320: 63 6f 6e 73 74 2a 61 72 67 76 2c 0a 20 20 73 71  const*argv,.  sq
3330: 6c 69 74 65 33 5f 76 74 61 62 20 2a 2a 70 70 56  lite3_vtab **ppV
3340: 74 61 62 2c 0a 20 20 63 68 61 72 20 2a 2a 70 7a  tab,.  char **pz
3350: 45 72 72 0a 29 7b 0a 20 20 69 6e 74 20 72 63 20  Err.){.  int rc 
3360: 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 61  = SQLITE_OK;.  a
3370: 70 70 65 6e 64 54 6f 45 63 68 6f 4d 6f 64 75 6c  ppendToEchoModul
3380: 65 28 28 28 45 63 68 6f 4d 6f 64 75 6c 65 20 2a  e(((EchoModule *
3390: 29 70 41 75 78 29 2d 3e 69 6e 74 65 72 70 2c 20  )pAux)->interp, 
33a0: 22 78 43 72 65 61 74 65 22 29 3b 0a 20 20 72 63  "xCreate");.  rc
33b0: 20 3d 20 65 63 68 6f 43 6f 6e 73 74 72 75 63 74   = echoConstruct
33c0: 6f 72 28 64 62 2c 20 70 41 75 78 2c 20 61 72 67  or(db, pAux, arg
33d0: 63 2c 20 61 72 67 76 2c 20 70 70 56 74 61 62 2c  c, argv, ppVtab,
33e0: 20 70 7a 45 72 72 29 3b 0a 0a 20 20 2f 2a 20 49   pzErr);..  /* I
33f0: 66 20 74 68 65 72 65 20 77 65 72 65 20 74 77 6f  f there were two
3400: 20 61 72 67 75 6d 65 6e 74 73 20 70 61 73 73 65   arguments passe
3410: 64 20 74 6f 20 74 68 65 20 6d 6f 64 75 6c 65 20  d to the module 
3420: 61 74 20 74 68 65 20 53 51 4c 20 6c 65 76 65 6c  at the SQL level
3430: 20 0a 20 20 2a 2a 20 28 69 2e 65 2e 20 22 43 52   .  ** (i.e. "CR
3440: 45 41 54 45 20 56 49 52 54 55 41 4c 20 54 41 42  EATE VIRTUAL TAB
3450: 4c 45 20 74 62 6c 20 55 53 49 4e 47 20 65 63 68  LE tbl USING ech
3460: 6f 28 61 72 67 31 2c 20 61 72 67 32 29 22 29 2c  o(arg1, arg2)"),
3470: 20 74 68 65 6e 20 0a 20 20 2a 2a 20 74 68 65 20   then .  ** the 
3480: 73 65 63 6f 6e 64 20 61 72 67 75 6d 65 6e 74 20  second argument 
3490: 69 73 20 75 73 65 64 20 61 73 20 61 20 74 61 62  is used as a tab
34a0: 6c 65 20 6e 61 6d 65 2e 20 41 74 74 65 6d 70 74  le name. Attempt
34b0: 20 74 6f 20 63 72 65 61 74 65 0a 20 20 2a 2a 20   to create.  ** 
34c0: 73 75 63 68 20 61 20 74 61 62 6c 65 20 77 69 74  such a table wit
34d0: 68 20 61 20 73 69 6e 67 6c 65 20 63 6f 6c 75 6d  h a single colum
34e0: 6e 2c 20 22 6c 6f 67 6d 73 67 22 2e 20 54 68 69  n, "logmsg". Thi
34f0: 73 20 74 61 62 6c 65 20 77 69 6c 6c 0a 20 20 2a  s table will.  *
3500: 2a 20 62 65 20 75 73 65 64 20 74 6f 20 6c 6f 67  * be used to log
3510: 20 63 61 6c 6c 73 20 74 6f 20 74 68 65 20 78 55   calls to the xU
3520: 70 64 61 74 65 20 6d 65 74 68 6f 64 2e 20 49 74  pdate method. It
3530: 20 77 69 6c 6c 20 62 65 20 64 65 6c 65 74 65 64   will be deleted
3540: 0a 20 20 2a 2a 20 77 68 65 6e 20 74 68 65 20 76  .  ** when the v
3550: 69 72 74 75 61 6c 20 74 61 62 6c 65 20 69 73 20  irtual table is 
3560: 44 52 4f 50 65 64 2e 0a 20 20 2a 2a 0a 20 20 2a  DROPed..  **.  *
3570: 2a 20 4e 6f 74 65 3a 20 54 68 65 20 6d 61 69 6e  * Note: The main
3580: 20 70 6f 69 6e 74 20 6f 66 20 74 68 69 73 20 69   point of this i
3590: 73 20 74 6f 20 74 65 73 74 20 74 68 61 74 20 77  s to test that w
35a0: 65 20 63 61 6e 20 64 72 6f 70 20 74 61 62 6c 65  e can drop table
35b0: 73 0a 20 20 2a 2a 20 66 72 6f 6d 20 77 69 74 68  s.  ** from with
35c0: 69 6e 20 61 6e 20 78 44 65 73 74 72 6f 79 20 6d  in an xDestroy m
35d0: 65 74 68 6f 64 20 63 61 6c 6c 2e 0a 20 20 2a 2f  ethod call..  */
35e0: 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54  .  if( rc==SQLIT
35f0: 45 5f 4f 4b 20 26 26 20 61 72 67 63 3d 3d 35 20  E_OK && argc==5 
3600: 29 7b 0a 20 20 20 20 63 68 61 72 20 2a 7a 53 71  ){.    char *zSq
3610: 6c 3b 0a 20 20 20 20 65 63 68 6f 5f 76 74 61 62  l;.    echo_vtab
3620: 20 2a 70 56 74 61 62 20 3d 20 2a 28 65 63 68 6f   *pVtab = *(echo
3630: 5f 76 74 61 62 20 2a 2a 29 70 70 56 74 61 62 3b  _vtab **)ppVtab;
3640: 0a 20 20 20 20 70 56 74 61 62 2d 3e 7a 4c 6f 67  .    pVtab->zLog
3650: 4e 61 6d 65 20 3d 20 73 71 6c 69 74 65 33 4d 50  Name = sqlite3MP
3660: 72 69 6e 74 66 28 30 2c 20 22 25 73 22 2c 20 61  rintf(0, "%s", a
3670: 72 67 76 5b 34 5d 29 3b 0a 20 20 20 20 7a 53 71  rgv[4]);.    zSq
3680: 6c 20 3d 20 73 71 6c 69 74 65 33 4d 50 72 69 6e  l = sqlite3MPrin
3690: 74 66 28 30 2c 20 22 43 52 45 41 54 45 20 54 41  tf(0, "CREATE TA
36a0: 42 4c 45 20 25 51 28 6c 6f 67 6d 73 67 29 22 2c  BLE %Q(logmsg)",
36b0: 20 70 56 74 61 62 2d 3e 7a 4c 6f 67 4e 61 6d 65   pVtab->zLogName
36c0: 29 3b 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69  );.    rc = sqli
36d0: 74 65 33 5f 65 78 65 63 28 64 62 2c 20 7a 53 71  te3_exec(db, zSq
36e0: 6c 2c 20 30 2c 20 30 2c 20 30 29 3b 0a 20 20 20  l, 0, 0, 0);.   
36f0: 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 7a 53   sqlite3_free(zS
3700: 71 6c 29 3b 0a 20 20 20 20 69 66 28 20 72 63 21  ql);.    if( rc!
3710: 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20  =SQLITE_OK ){.  
3720: 20 20 20 20 2a 70 7a 45 72 72 20 3d 20 73 71 6c      *pzErr = sql
3730: 69 74 65 33 44 62 53 74 72 44 75 70 28 30 2c 20  ite3DbStrDup(0, 
3740: 73 71 6c 69 74 65 33 5f 65 72 72 6d 73 67 28 64  sqlite3_errmsg(d
3750: 62 29 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a  b));.    }.  }..
3760: 20 20 69 66 28 20 2a 70 70 56 74 61 62 20 26 26    if( *ppVtab &&
3770: 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc!=SQLITE_OK )
3780: 7b 0a 20 20 20 20 65 63 68 6f 44 65 73 74 72 75  {.    echoDestru
3790: 63 74 6f 72 28 2a 70 70 56 74 61 62 29 3b 0a 20  ctor(*ppVtab);. 
37a0: 20 20 20 2a 70 70 56 74 61 62 20 3d 20 30 3b 0a     *ppVtab = 0;.
37b0: 20 20 7d 0a 0a 20 20 69 66 28 20 72 63 3d 3d 53    }..  if( rc==S
37c0: 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
37d0: 28 2a 28 65 63 68 6f 5f 76 74 61 62 2a 2a 29 70  (*(echo_vtab**)p
37e0: 70 56 74 61 62 29 2d 3e 69 6e 54 72 61 6e 73 61  pVtab)->inTransa
37f0: 63 74 69 6f 6e 20 3d 20 31 3b 0a 20 20 7d 0a 0a  ction = 1;.  }..
3800: 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a    return rc;.}..
3810: 2f 2a 20 0a 2a 2a 20 45 63 68 6f 20 76 69 72 74  /* .** Echo virt
3820: 75 61 6c 20 74 61 62 6c 65 20 6d 6f 64 75 6c 65  ual table module
3830: 20 78 43 6f 6e 6e 65 63 74 20 6d 65 74 68 6f 64   xConnect method
3840: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
3850: 65 63 68 6f 43 6f 6e 6e 65 63 74 28 0a 20 20 73  echoConnect(.  s
3860: 71 6c 69 74 65 33 20 2a 64 62 2c 0a 20 20 76 6f  qlite3 *db,.  vo
3870: 69 64 20 2a 70 41 75 78 2c 0a 20 20 69 6e 74 20  id *pAux,.  int 
3880: 61 72 67 63 2c 20 63 6f 6e 73 74 20 63 68 61 72  argc, const char
3890: 20 2a 63 6f 6e 73 74 2a 61 72 67 76 2c 0a 20 20   *const*argv,.  
38a0: 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 2a 70  sqlite3_vtab **p
38b0: 70 56 74 61 62 2c 0a 20 20 63 68 61 72 20 2a 2a  pVtab,.  char **
38c0: 70 7a 45 72 72 0a 29 7b 0a 20 20 61 70 70 65 6e  pzErr.){.  appen
38d0: 64 54 6f 45 63 68 6f 4d 6f 64 75 6c 65 28 28 28  dToEchoModule(((
38e0: 45 63 68 6f 4d 6f 64 75 6c 65 20 2a 29 70 41 75  EchoModule *)pAu
38f0: 78 29 2d 3e 69 6e 74 65 72 70 2c 20 22 78 43 6f  x)->interp, "xCo
3900: 6e 6e 65 63 74 22 29 3b 0a 20 20 72 65 74 75 72  nnect");.  retur
3910: 6e 20 65 63 68 6f 43 6f 6e 73 74 72 75 63 74 6f  n echoConstructo
3920: 72 28 64 62 2c 20 70 41 75 78 2c 20 61 72 67 63  r(db, pAux, argc
3930: 2c 20 61 72 67 76 2c 20 70 70 56 74 61 62 2c 20  , argv, ppVtab, 
3940: 70 7a 45 72 72 29 3b 0a 7d 0a 0a 2f 2a 20 0a 2a  pzErr);.}../* .*
3950: 2a 20 45 63 68 6f 20 76 69 72 74 75 61 6c 20 74  * Echo virtual t
3960: 61 62 6c 65 20 6d 6f 64 75 6c 65 20 78 44 69 73  able module xDis
3970: 63 6f 6e 6e 65 63 74 20 6d 65 74 68 6f 64 2e 0a  connect method..
3980: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 65 63  */.static int ec
3990: 68 6f 44 69 73 63 6f 6e 6e 65 63 74 28 73 71 6c  hoDisconnect(sql
39a0: 69 74 65 33 5f 76 74 61 62 20 2a 70 56 74 61 62  ite3_vtab *pVtab
39b0: 29 7b 0a 20 20 61 70 70 65 6e 64 54 6f 45 63 68  ){.  appendToEch
39c0: 6f 4d 6f 64 75 6c 65 28 28 28 65 63 68 6f 5f 76  oModule(((echo_v
39d0: 74 61 62 20 2a 29 70 56 74 61 62 29 2d 3e 69 6e  tab *)pVtab)->in
39e0: 74 65 72 70 2c 20 22 78 44 69 73 63 6f 6e 6e 65  terp, "xDisconne
39f0: 63 74 22 29 3b 0a 20 20 72 65 74 75 72 6e 20 65  ct");.  return e
3a00: 63 68 6f 44 65 73 74 72 75 63 74 6f 72 28 70 56  choDestructor(pV
3a10: 74 61 62 29 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20  tab);.}../* .** 
3a20: 45 63 68 6f 20 76 69 72 74 75 61 6c 20 74 61 62  Echo virtual tab
3a30: 6c 65 20 6d 6f 64 75 6c 65 20 78 44 65 73 74 72  le module xDestr
3a40: 6f 79 20 6d 65 74 68 6f 64 2e 0a 2a 2f 0a 73 74  oy method..*/.st
3a50: 61 74 69 63 20 69 6e 74 20 65 63 68 6f 44 65 73  atic int echoDes
3a60: 74 72 6f 79 28 73 71 6c 69 74 65 33 5f 76 74 61  troy(sqlite3_vta
3a70: 62 20 2a 70 56 74 61 62 29 7b 0a 20 20 69 6e 74  b *pVtab){.  int
3a80: 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b   rc = SQLITE_OK;
3a90: 0a 20 20 65 63 68 6f 5f 76 74 61 62 20 2a 70 20  .  echo_vtab *p 
3aa0: 3d 20 28 65 63 68 6f 5f 76 74 61 62 20 2a 29 70  = (echo_vtab *)p
3ab0: 56 74 61 62 3b 0a 20 20 61 70 70 65 6e 64 54 6f  Vtab;.  appendTo
3ac0: 45 63 68 6f 4d 6f 64 75 6c 65 28 28 28 65 63 68  EchoModule(((ech
3ad0: 6f 5f 76 74 61 62 20 2a 29 70 56 74 61 62 29 2d  o_vtab *)pVtab)-
3ae0: 3e 69 6e 74 65 72 70 2c 20 22 78 44 65 73 74 72  >interp, "xDestr
3af0: 6f 79 22 29 3b 0a 0a 20 20 2f 2a 20 44 72 6f 70  oy");..  /* Drop
3b00: 20 74 68 65 20 22 6c 6f 67 22 20 74 61 62 6c 65   the "log" table
3b10: 2c 20 69 66 20 6f 6e 65 20 65 78 69 73 74 73 20  , if one exists 
3b20: 28 73 65 65 20 65 63 68 6f 43 72 65 61 74 65 28  (see echoCreate(
3b30: 29 20 66 6f 72 20 64 65 74 61 69 6c 73 29 20 2a  ) for details) *
3b40: 2f 0a 20 20 69 66 28 20 70 20 26 26 20 70 2d 3e  /.  if( p && p->
3b50: 7a 4c 6f 67 4e 61 6d 65 20 29 7b 0a 20 20 20 20  zLogName ){.    
3b60: 63 68 61 72 20 2a 7a 53 71 6c 3b 0a 20 20 20 20  char *zSql;.    
3b70: 7a 53 71 6c 20 3d 20 73 71 6c 69 74 65 33 4d 50  zSql = sqlite3MP
3b80: 72 69 6e 74 66 28 30 2c 20 22 44 52 4f 50 20 54  rintf(0, "DROP T
3b90: 41 42 4c 45 20 25 51 22 2c 20 70 2d 3e 7a 4c 6f  ABLE %Q", p->zLo
3ba0: 67 4e 61 6d 65 29 3b 0a 20 20 20 20 72 63 20 3d  gName);.    rc =
3bb0: 20 73 71 6c 69 74 65 33 5f 65 78 65 63 28 70 2d   sqlite3_exec(p-
3bc0: 3e 64 62 2c 20 7a 53 71 6c 2c 20 30 2c 20 30 2c  >db, zSql, 0, 0,
3bd0: 20 30 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33   0);.    sqlite3
3be0: 5f 66 72 65 65 28 7a 53 71 6c 29 3b 0a 20 20 7d  _free(zSql);.  }
3bf0: 0a 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49  ..  if( rc==SQLI
3c00: 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 72 63 20  TE_OK ){.    rc 
3c10: 3d 20 65 63 68 6f 44 65 73 74 72 75 63 74 6f 72  = echoDestructor
3c20: 28 70 56 74 61 62 29 3b 0a 20 20 7d 0a 20 20 72  (pVtab);.  }.  r
3c30: 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 20  eturn rc;.}../* 
3c40: 0a 2a 2a 20 45 63 68 6f 20 76 69 72 74 75 61 6c  .** Echo virtual
3c50: 20 74 61 62 6c 65 20 6d 6f 64 75 6c 65 20 78 4f   table module xO
3c60: 70 65 6e 20 6d 65 74 68 6f 64 2e 0a 2a 2f 0a 73  pen method..*/.s
3c70: 74 61 74 69 63 20 69 6e 74 20 65 63 68 6f 4f 70  tatic int echoOp
3c80: 65 6e 28 73 71 6c 69 74 65 33 5f 76 74 61 62 20  en(sqlite3_vtab 
3c90: 2a 70 56 54 61 62 2c 20 73 71 6c 69 74 65 33 5f  *pVTab, sqlite3_
3ca0: 76 74 61 62 5f 63 75 72 73 6f 72 20 2a 2a 70 70  vtab_cursor **pp
3cb0: 43 75 72 73 6f 72 29 7b 0a 20 20 65 63 68 6f 5f  Cursor){.  echo_
3cc0: 63 75 72 73 6f 72 20 2a 70 43 75 72 3b 0a 20 20  cursor *pCur;.  
3cd0: 69 66 28 20 73 69 6d 75 6c 61 74 65 56 74 61 62  if( simulateVtab
3ce0: 45 72 72 6f 72 28 28 65 63 68 6f 5f 76 74 61 62  Error((echo_vtab
3cf0: 20 2a 29 70 56 54 61 62 2c 20 22 78 4f 70 65 6e   *)pVTab, "xOpen
3d00: 22 29 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e  ") ){.    return
3d10: 20 53 51 4c 49 54 45 5f 45 52 52 4f 52 3b 0a 20   SQLITE_ERROR;. 
3d20: 20 7d 0a 20 20 70 43 75 72 20 3d 20 73 71 6c 69   }.  pCur = sqli
3d30: 74 65 33 4d 61 6c 6c 6f 63 5a 65 72 6f 28 73 69  te3MallocZero(si
3d40: 7a 65 6f 66 28 65 63 68 6f 5f 63 75 72 73 6f 72  zeof(echo_cursor
3d50: 29 29 3b 0a 20 20 2a 70 70 43 75 72 73 6f 72 20  ));.  *ppCursor 
3d60: 3d 20 28 73 71 6c 69 74 65 33 5f 76 74 61 62 5f  = (sqlite3_vtab_
3d70: 63 75 72 73 6f 72 20 2a 29 70 43 75 72 3b 0a 20  cursor *)pCur;. 
3d80: 20 72 65 74 75 72 6e 20 28 70 43 75 72 20 3f 20   return (pCur ? 
3d90: 53 51 4c 49 54 45 5f 4f 4b 20 3a 20 53 51 4c 49  SQLITE_OK : SQLI
3da0: 54 45 5f 4e 4f 4d 45 4d 29 3b 0a 7d 0a 0a 2f 2a  TE_NOMEM);.}../*
3db0: 20 0a 2a 2a 20 45 63 68 6f 20 76 69 72 74 75 61   .** Echo virtua
3dc0: 6c 20 74 61 62 6c 65 20 6d 6f 64 75 6c 65 20 78  l table module x
3dd0: 43 6c 6f 73 65 20 6d 65 74 68 6f 64 2e 0a 2a 2f  Close method..*/
3de0: 0a 73 74 61 74 69 63 20 69 6e 74 20 65 63 68 6f  .static int echo
3df0: 43 6c 6f 73 65 28 73 71 6c 69 74 65 33 5f 76 74  Close(sqlite3_vt
3e00: 61 62 5f 63 75 72 73 6f 72 20 2a 63 75 72 29 7b  ab_cursor *cur){
3e10: 0a 20 20 69 6e 74 20 72 63 3b 0a 20 20 65 63 68  .  int rc;.  ech
3e20: 6f 5f 63 75 72 73 6f 72 20 2a 70 43 75 72 20 3d  o_cursor *pCur =
3e30: 20 28 65 63 68 6f 5f 63 75 72 73 6f 72 20 2a 29   (echo_cursor *)
3e40: 63 75 72 3b 0a 20 20 73 71 6c 69 74 65 33 5f 73  cur;.  sqlite3_s
3e50: 74 6d 74 20 2a 70 53 74 6d 74 20 3d 20 70 43 75  tmt *pStmt = pCu
3e60: 72 2d 3e 70 53 74 6d 74 3b 0a 20 20 70 43 75 72  r->pStmt;.  pCur
3e70: 2d 3e 70 53 74 6d 74 20 3d 20 30 3b 0a 20 20 73  ->pStmt = 0;.  s
3e80: 71 6c 69 74 65 33 5f 66 72 65 65 28 70 43 75 72  qlite3_free(pCur
3e90: 29 3b 0a 20 20 72 63 20 3d 20 73 71 6c 69 74 65  );.  rc = sqlite
3ea0: 33 5f 66 69 6e 61 6c 69 7a 65 28 70 53 74 6d 74  3_finalize(pStmt
3eb0: 29 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a  );.  return rc;.
3ec0: 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20  }../*.** Return 
3ed0: 6e 6f 6e 2d 7a 65 72 6f 20 69 66 20 74 68 65 20  non-zero if the 
3ee0: 63 75 72 73 6f 72 20 64 6f 65 73 20 6e 6f 74 20  cursor does not 
3ef0: 63 75 72 72 65 6e 74 6c 79 20 70 6f 69 6e 74 20  currently point 
3f00: 74 6f 20 61 20 76 61 6c 69 64 20 72 65 63 6f 72  to a valid recor
3f10: 64 0a 2a 2a 20 28 69 2e 65 20 69 66 20 74 68 65  d.** (i.e if the
3f20: 20 73 63 61 6e 20 68 61 73 20 66 69 6e 69 73 68   scan has finish
3f30: 65 64 29 2c 20 6f 72 20 7a 65 72 6f 20 6f 74 68  ed), or zero oth
3f40: 65 72 77 69 73 65 2e 0a 2a 2f 0a 73 74 61 74 69  erwise..*/.stati
3f50: 63 20 69 6e 74 20 65 63 68 6f 45 6f 66 28 73 71  c int echoEof(sq
3f60: 6c 69 74 65 33 5f 76 74 61 62 5f 63 75 72 73 6f  lite3_vtab_curso
3f70: 72 20 2a 63 75 72 29 7b 0a 20 20 72 65 74 75 72  r *cur){.  retur
3f80: 6e 20 28 28 28 65 63 68 6f 5f 63 75 72 73 6f 72  n (((echo_cursor
3f90: 20 2a 29 63 75 72 29 2d 3e 70 53 74 6d 74 20 3f   *)cur)->pStmt ?
3fa0: 20 30 20 3a 20 31 29 3b 0a 7d 0a 0a 2f 2a 20 0a   0 : 1);.}../* .
3fb0: 2a 2a 20 45 63 68 6f 20 76 69 72 74 75 61 6c 20  ** Echo virtual 
3fc0: 74 61 62 6c 65 20 6d 6f 64 75 6c 65 20 78 4e 65  table module xNe
3fd0: 78 74 20 6d 65 74 68 6f 64 2e 0a 2a 2f 0a 73 74  xt method..*/.st
3fe0: 61 74 69 63 20 69 6e 74 20 65 63 68 6f 4e 65 78  atic int echoNex
3ff0: 74 28 73 71 6c 69 74 65 33 5f 76 74 61 62 5f 63  t(sqlite3_vtab_c
4000: 75 72 73 6f 72 20 2a 63 75 72 29 7b 0a 20 20 69  ursor *cur){.  i
4010: 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f  nt rc = SQLITE_O
4020: 4b 3b 0a 20 20 65 63 68 6f 5f 63 75 72 73 6f 72  K;.  echo_cursor
4030: 20 2a 70 43 75 72 20 3d 20 28 65 63 68 6f 5f 63   *pCur = (echo_c
4040: 75 72 73 6f 72 20 2a 29 63 75 72 3b 0a 0a 20 20  ursor *)cur;..  
4050: 69 66 28 20 73 69 6d 75 6c 61 74 65 56 74 61 62  if( simulateVtab
4060: 45 72 72 6f 72 28 28 65 63 68 6f 5f 76 74 61 62  Error((echo_vtab
4070: 20 2a 29 28 63 75 72 2d 3e 70 56 74 61 62 29 2c   *)(cur->pVtab),
4080: 20 22 78 4e 65 78 74 22 29 20 29 7b 0a 20 20 20   "xNext") ){.   
4090: 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 45   return SQLITE_E
40a0: 52 52 4f 52 3b 0a 20 20 7d 0a 0a 20 20 69 66 28  RROR;.  }..  if(
40b0: 20 70 43 75 72 2d 3e 70 53 74 6d 74 20 29 7b 0a   pCur->pStmt ){.
40c0: 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33      rc = sqlite3
40d0: 5f 73 74 65 70 28 70 43 75 72 2d 3e 70 53 74 6d  _step(pCur->pStm
40e0: 74 29 3b 0a 20 20 20 20 69 66 28 20 72 63 3d 3d  t);.    if( rc==
40f0: 53 51 4c 49 54 45 5f 52 4f 57 20 29 7b 0a 20 20  SQLITE_ROW ){.  
4100: 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f      rc = SQLITE_
4110: 4f 4b 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20  OK;.    }else{. 
4120: 20 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65       rc = sqlite
4130: 33 5f 66 69 6e 61 6c 69 7a 65 28 70 43 75 72 2d  3_finalize(pCur-
4140: 3e 70 53 74 6d 74 29 3b 0a 20 20 20 20 20 20 70  >pStmt);.      p
4150: 43 75 72 2d 3e 70 53 74 6d 74 20 3d 20 30 3b 0a  Cur->pStmt = 0;.
4160: 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 72 65 74      }.  }..  ret
4170: 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 20 0a 2a  urn rc;.}../* .*
4180: 2a 20 45 63 68 6f 20 76 69 72 74 75 61 6c 20 74  * Echo virtual t
4190: 61 62 6c 65 20 6d 6f 64 75 6c 65 20 78 43 6f 6c  able module xCol
41a0: 75 6d 6e 20 6d 65 74 68 6f 64 2e 0a 2a 2f 0a 73  umn method..*/.s
41b0: 74 61 74 69 63 20 69 6e 74 20 65 63 68 6f 43 6f  tatic int echoCo
41c0: 6c 75 6d 6e 28 73 71 6c 69 74 65 33 5f 76 74 61  lumn(sqlite3_vta
41d0: 62 5f 63 75 72 73 6f 72 20 2a 63 75 72 2c 20 73  b_cursor *cur, s
41e0: 71 6c 69 74 65 33 5f 63 6f 6e 74 65 78 74 20 2a  qlite3_context *
41f0: 63 74 78 2c 20 69 6e 74 20 69 29 7b 0a 20 20 69  ctx, int i){.  i
4200: 6e 74 20 69 43 6f 6c 20 3d 20 69 20 2b 20 31 3b  nt iCol = i + 1;
4210: 0a 20 20 73 71 6c 69 74 65 33 5f 73 74 6d 74 20  .  sqlite3_stmt 
4220: 2a 70 53 74 6d 74 20 3d 20 28 28 65 63 68 6f 5f  *pStmt = ((echo_
4230: 63 75 72 73 6f 72 20 2a 29 63 75 72 29 2d 3e 70  cursor *)cur)->p
4240: 53 74 6d 74 3b 0a 0a 20 20 69 66 28 20 73 69 6d  Stmt;..  if( sim
4250: 75 6c 61 74 65 56 74 61 62 45 72 72 6f 72 28 28  ulateVtabError((
4260: 65 63 68 6f 5f 76 74 61 62 20 2a 29 28 63 75 72  echo_vtab *)(cur
4270: 2d 3e 70 56 74 61 62 29 2c 20 22 78 43 6f 6c 75  ->pVtab), "xColu
4280: 6d 6e 22 29 20 29 7b 0a 20 20 20 20 72 65 74 75  mn") ){.    retu
4290: 72 6e 20 53 51 4c 49 54 45 5f 45 52 52 4f 52 3b  rn SQLITE_ERROR;
42a0: 0a 20 20 7d 0a 0a 20 20 69 66 28 20 21 70 53 74  .  }..  if( !pSt
42b0: 6d 74 20 29 7b 0a 20 20 20 20 73 71 6c 69 74 65  mt ){.    sqlite
42c0: 33 5f 72 65 73 75 6c 74 5f 6e 75 6c 6c 28 63 74  3_result_null(ct
42d0: 78 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20  x);.  }else{.   
42e0: 20 61 73 73 65 72 74 28 20 73 71 6c 69 74 65 33   assert( sqlite3
42f0: 5f 64 61 74 61 5f 63 6f 75 6e 74 28 70 53 74 6d  _data_count(pStm
4300: 74 29 3e 69 43 6f 6c 20 29 3b 0a 20 20 20 20 73  t)>iCol );.    s
4310: 71 6c 69 74 65 33 5f 72 65 73 75 6c 74 5f 76 61  qlite3_result_va
4320: 6c 75 65 28 63 74 78 2c 20 73 71 6c 69 74 65 33  lue(ctx, sqlite3
4330: 5f 63 6f 6c 75 6d 6e 5f 76 61 6c 75 65 28 70 53  _column_value(pS
4340: 74 6d 74 2c 20 69 43 6f 6c 29 29 3b 0a 20 20 7d  tmt, iCol));.  }
4350: 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45  .  return SQLITE
4360: 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 45  _OK;.}../* .** E
4370: 63 68 6f 20 76 69 72 74 75 61 6c 20 74 61 62 6c  cho virtual tabl
4380: 65 20 6d 6f 64 75 6c 65 20 78 52 6f 77 69 64 20  e module xRowid 
4390: 6d 65 74 68 6f 64 2e 0a 2a 2f 0a 73 74 61 74 69  method..*/.stati
43a0: 63 20 69 6e 74 20 65 63 68 6f 52 6f 77 69 64 28  c int echoRowid(
43b0: 73 71 6c 69 74 65 33 5f 76 74 61 62 5f 63 75 72  sqlite3_vtab_cur
43c0: 73 6f 72 20 2a 63 75 72 2c 20 73 71 6c 69 74 65  sor *cur, sqlite
43d0: 5f 69 6e 74 36 34 20 2a 70 52 6f 77 69 64 29 7b  _int64 *pRowid){
43e0: 0a 20 20 73 71 6c 69 74 65 33 5f 73 74 6d 74 20  .  sqlite3_stmt 
43f0: 2a 70 53 74 6d 74 20 3d 20 28 28 65 63 68 6f 5f  *pStmt = ((echo_
4400: 63 75 72 73 6f 72 20 2a 29 63 75 72 29 2d 3e 70  cursor *)cur)->p
4410: 53 74 6d 74 3b 0a 0a 20 20 69 66 28 20 73 69 6d  Stmt;..  if( sim
4420: 75 6c 61 74 65 56 74 61 62 45 72 72 6f 72 28 28  ulateVtabError((
4430: 65 63 68 6f 5f 76 74 61 62 20 2a 29 28 63 75 72  echo_vtab *)(cur
4440: 2d 3e 70 56 74 61 62 29 2c 20 22 78 52 6f 77 69  ->pVtab), "xRowi
4450: 64 22 29 20 29 7b 0a 20 20 20 20 72 65 74 75 72  d") ){.    retur
4460: 6e 20 53 51 4c 49 54 45 5f 45 52 52 4f 52 3b 0a  n SQLITE_ERROR;.
4470: 20 20 7d 0a 0a 20 20 2a 70 52 6f 77 69 64 20 3d    }..  *pRowid =
4480: 20 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f   sqlite3_column_
4490: 69 6e 74 36 34 28 70 53 74 6d 74 2c 20 30 29 3b  int64(pStmt, 0);
44a0: 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45  .  return SQLITE
44b0: 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 6f  _OK;.}../*.** Co
44c0: 6d 70 75 74 65 20 61 20 73 69 6d 70 6c 65 20 68  mpute a simple h
44d0: 61 73 68 20 6f 66 20 74 68 65 20 6e 75 6c 6c 20  ash of the null 
44e0: 74 65 72 6d 69 6e 61 74 65 64 20 73 74 72 69 6e  terminated strin
44f0: 67 20 7a 53 74 72 69 6e 67 2e 0a 2a 2a 0a 2a 2a  g zString..**.**
4500: 20 54 68 69 73 20 6d 6f 64 75 6c 65 20 75 73 65   This module use
4510: 73 20 6f 6e 6c 79 20 73 71 6c 69 74 65 33 5f 69  s only sqlite3_i
4520: 6e 64 65 78 5f 69 6e 66 6f 2e 69 64 78 53 74 72  ndex_info.idxStr
4530: 2c 20 6e 6f 74 20 0a 2a 2a 20 73 71 6c 69 74 65  , not .** sqlite
4540: 33 5f 69 6e 64 65 78 5f 69 6e 66 6f 2e 69 64 78  3_index_info.idx
4550: 4e 75 6d 2e 20 53 6f 20 74 6f 20 74 65 73 74 20  Num. So to test 
4560: 69 64 78 4e 75 6d 2c 20 77 68 65 6e 20 69 64 78  idxNum, when idx
4570: 53 74 72 20 69 73 20 73 65 74 0a 2a 2a 20 69 6e  Str is set.** in
4580: 20 65 63 68 6f 42 65 73 74 49 6e 64 65 78 28 29   echoBestIndex()
4590: 2c 20 69 64 78 4e 75 6d 20 69 73 20 73 65 74 20  , idxNum is set 
45a0: 74 6f 20 74 68 65 20 63 6f 72 72 65 73 70 6f 6e  to the correspon
45b0: 64 69 6e 67 20 68 61 73 68 20 76 61 6c 75 65 2e  ding hash value.
45c0: 0a 2a 2a 20 49 6e 20 65 63 68 6f 46 69 6c 74 65  .** In echoFilte
45d0: 72 28 29 2c 20 63 6f 64 65 20 61 73 73 65 72 74  r(), code assert
45e0: 28 29 73 20 74 68 61 74 20 74 68 65 20 73 75 70  ()s that the sup
45f0: 70 6c 69 65 64 20 69 64 78 4e 75 6d 20 76 61 6c  plied idxNum val
4600: 75 65 20 69 73 0a 2a 2a 20 69 6e 64 65 65 64 20  ue is.** indeed 
4610: 74 68 65 20 68 61 73 68 20 6f 66 20 74 68 65 20  the hash of the 
4620: 73 75 70 70 6c 69 65 64 20 69 64 78 53 74 72 2e  supplied idxStr.
4630: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 68  .*/.static int h
4640: 61 73 68 53 74 72 69 6e 67 28 63 6f 6e 73 74 20  ashString(const 
4650: 63 68 61 72 20 2a 7a 53 74 72 69 6e 67 29 7b 0a  char *zString){.
4660: 20 20 69 6e 74 20 76 61 6c 20 3d 20 30 3b 0a 20    int val = 0;. 
4670: 20 69 6e 74 20 69 69 3b 0a 20 20 66 6f 72 28 69   int ii;.  for(i
4680: 69 3d 30 3b 20 7a 53 74 72 69 6e 67 5b 69 69 5d  i=0; zString[ii]
4690: 3b 20 69 69 2b 2b 29 7b 0a 20 20 20 20 76 61 6c  ; ii++){.    val
46a0: 20 3d 20 28 76 61 6c 20 3c 3c 20 33 29 20 2b 20   = (val << 3) + 
46b0: 28 69 6e 74 29 7a 53 74 72 69 6e 67 5b 69 69 5d  (int)zString[ii]
46c0: 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 76  ;.  }.  return v
46d0: 61 6c 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 45 63  al;.}../* .** Ec
46e0: 68 6f 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65  ho virtual table
46f0: 20 6d 6f 64 75 6c 65 20 78 46 69 6c 74 65 72 20   module xFilter 
4700: 6d 65 74 68 6f 64 2e 0a 2a 2f 0a 73 74 61 74 69  method..*/.stati
4710: 63 20 69 6e 74 20 65 63 68 6f 46 69 6c 74 65 72  c int echoFilter
4720: 28 0a 20 20 73 71 6c 69 74 65 33 5f 76 74 61 62  (.  sqlite3_vtab
4730: 5f 63 75 72 73 6f 72 20 2a 70 56 74 61 62 43 75  _cursor *pVtabCu
4740: 72 73 6f 72 2c 20 0a 20 20 69 6e 74 20 69 64 78  rsor, .  int idx
4750: 4e 75 6d 2c 20 63 6f 6e 73 74 20 63 68 61 72 20  Num, const char 
4760: 2a 69 64 78 53 74 72 2c 0a 20 20 69 6e 74 20 61  *idxStr,.  int a
4770: 72 67 63 2c 20 73 71 6c 69 74 65 33 5f 76 61 6c  rgc, sqlite3_val
4780: 75 65 20 2a 2a 61 72 67 76 0a 29 7b 0a 20 20 69  ue **argv.){.  i
4790: 6e 74 20 72 63 3b 0a 20 20 69 6e 74 20 69 3b 0a  nt rc;.  int i;.
47a0: 0a 20 20 65 63 68 6f 5f 63 75 72 73 6f 72 20 2a  .  echo_cursor *
47b0: 70 43 75 72 20 3d 20 28 65 63 68 6f 5f 63 75 72  pCur = (echo_cur
47c0: 73 6f 72 20 2a 29 70 56 74 61 62 43 75 72 73 6f  sor *)pVtabCurso
47d0: 72 3b 0a 20 20 65 63 68 6f 5f 76 74 61 62 20 2a  r;.  echo_vtab *
47e0: 70 56 74 61 62 20 3d 20 28 65 63 68 6f 5f 76 74  pVtab = (echo_vt
47f0: 61 62 20 2a 29 70 56 74 61 62 43 75 72 73 6f 72  ab *)pVtabCursor
4800: 2d 3e 70 56 74 61 62 3b 0a 20 20 73 71 6c 69 74  ->pVtab;.  sqlit
4810: 65 33 20 2a 64 62 20 3d 20 70 56 74 61 62 2d 3e  e3 *db = pVtab->
4820: 64 62 3b 0a 0a 20 20 69 66 28 20 73 69 6d 75 6c  db;..  if( simul
4830: 61 74 65 56 74 61 62 45 72 72 6f 72 28 70 56 74  ateVtabError(pVt
4840: 61 62 2c 20 22 78 46 69 6c 74 65 72 22 29 20 29  ab, "xFilter") )
4850: 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c  {.    return SQL
4860: 49 54 45 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a 0a  ITE_ERROR;.  }..
4870: 20 20 2f 2a 20 43 68 65 63 6b 20 74 68 61 74 20    /* Check that 
4880: 69 64 78 4e 75 6d 20 6d 61 74 63 68 65 73 20 69  idxNum matches i
4890: 64 78 53 74 72 20 2a 2f 0a 20 20 61 73 73 65 72  dxStr */.  asser
48a0: 74 28 20 69 64 78 4e 75 6d 3d 3d 68 61 73 68 53  t( idxNum==hashS
48b0: 74 72 69 6e 67 28 69 64 78 53 74 72 29 20 29 3b  tring(idxStr) );
48c0: 0a 0a 20 20 2f 2a 20 4c 6f 67 20 61 72 67 75 6d  ..  /* Log argum
48d0: 65 6e 74 73 20 74 6f 20 74 68 65 20 3a 3a 65 63  ents to the ::ec
48e0: 68 6f 5f 6d 6f 64 75 6c 65 20 54 63 6c 20 76 61  ho_module Tcl va
48f0: 72 69 61 62 6c 65 20 2a 2f 0a 20 20 61 70 70 65  riable */.  appe
4900: 6e 64 54 6f 45 63 68 6f 4d 6f 64 75 6c 65 28 70  ndToEchoModule(p
4910: 56 74 61 62 2d 3e 69 6e 74 65 72 70 2c 20 22 78  Vtab->interp, "x
4920: 46 69 6c 74 65 72 22 29 3b 0a 20 20 61 70 70 65  Filter");.  appe
4930: 6e 64 54 6f 45 63 68 6f 4d 6f 64 75 6c 65 28 70  ndToEchoModule(p
4940: 56 74 61 62 2d 3e 69 6e 74 65 72 70 2c 20 69 64  Vtab->interp, id
4950: 78 53 74 72 29 3b 0a 20 20 66 6f 72 28 69 3d 30  xStr);.  for(i=0
4960: 3b 20 69 3c 61 72 67 63 3b 20 69 2b 2b 29 7b 0a  ; i<argc; i++){.
4970: 20 20 20 20 61 70 70 65 6e 64 54 6f 45 63 68 6f      appendToEcho
4980: 4d 6f 64 75 6c 65 28 70 56 74 61 62 2d 3e 69 6e  Module(pVtab->in
4990: 74 65 72 70 2c 20 28 63 6f 6e 73 74 20 63 68 61  terp, (const cha
49a0: 72 2a 29 73 71 6c 69 74 65 33 5f 76 61 6c 75 65  r*)sqlite3_value
49b0: 5f 74 65 78 74 28 61 72 67 76 5b 69 5d 29 29 3b  _text(argv[i]));
49c0: 0a 20 20 7d 0a 0a 20 20 73 71 6c 69 74 65 33 5f  .  }..  sqlite3_
49d0: 66 69 6e 61 6c 69 7a 65 28 70 43 75 72 2d 3e 70  finalize(pCur->p
49e0: 53 74 6d 74 29 3b 0a 20 20 70 43 75 72 2d 3e 70  Stmt);.  pCur->p
49f0: 53 74 6d 74 20 3d 20 30 3b 0a 0a 20 20 2f 2a 20  Stmt = 0;..  /* 
4a00: 50 72 65 70 61 72 65 20 74 68 65 20 53 51 4c 20  Prepare the SQL 
4a10: 73 74 61 74 65 6d 65 6e 74 20 63 72 65 61 74 65  statement create
4a20: 64 20 62 79 20 65 63 68 6f 42 65 73 74 49 6e 64  d by echoBestInd
4a30: 65 78 20 61 6e 64 20 62 69 6e 64 20 74 68 65 0a  ex and bind the.
4a40: 20 20 2a 2a 20 72 75 6e 74 69 6d 65 20 70 61 72    ** runtime par
4a50: 61 6d 65 74 65 72 73 20 70 61 73 73 65 64 20 74  ameters passed t
4a60: 6f 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e 20  o this function 
4a70: 74 6f 20 69 74 2e 0a 20 20 2a 2f 0a 20 20 72 63  to it..  */.  rc
4a80: 20 3d 20 73 71 6c 69 74 65 33 5f 70 72 65 70 61   = sqlite3_prepa
4a90: 72 65 28 64 62 2c 20 69 64 78 53 74 72 2c 20 2d  re(db, idxStr, -
4aa0: 31 2c 20 26 70 43 75 72 2d 3e 70 53 74 6d 74 2c  1, &pCur->pStmt,
4ab0: 20 30 29 3b 0a 20 20 61 73 73 65 72 74 28 20 70   0);.  assert( p
4ac0: 43 75 72 2d 3e 70 53 74 6d 74 20 7c 7c 20 72 63  Cur->pStmt || rc
4ad0: 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 3b 0a 20  !=SQLITE_OK );. 
4ae0: 20 66 6f 72 28 69 3d 30 3b 20 72 63 3d 3d 53 51   for(i=0; rc==SQ
4af0: 4c 49 54 45 5f 4f 4b 20 26 26 20 69 3c 61 72 67  LITE_OK && i<arg
4b00: 63 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 73 71 6c  c; i++){.    sql
4b10: 69 74 65 33 5f 62 69 6e 64 5f 76 61 6c 75 65 28  ite3_bind_value(
4b20: 70 43 75 72 2d 3e 70 53 74 6d 74 2c 20 69 2b 31  pCur->pStmt, i+1
4b30: 2c 20 61 72 67 76 5b 69 5d 29 3b 0a 20 20 7d 0a  , argv[i]);.  }.
4b40: 0a 20 20 2f 2a 20 49 66 20 65 76 65 72 79 74 68  .  /* If everyth
4b50: 69 6e 67 20 77 61 73 20 73 75 63 63 65 73 73 66  ing was successf
4b60: 75 6c 2c 20 61 64 76 61 6e 63 65 20 74 6f 20 74  ul, advance to t
4b70: 68 65 20 66 69 72 73 74 20 72 6f 77 20 6f 66 20  he first row of 
4b80: 74 68 65 20 73 63 61 6e 20 2a 2f 0a 20 20 69 66  the scan */.  if
4b90: 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
4ba0: 29 7b 0a 20 20 20 20 72 63 20 3d 20 65 63 68 6f  ){.    rc = echo
4bb0: 4e 65 78 74 28 70 56 74 61 62 43 75 72 73 6f 72  Next(pVtabCursor
4bc0: 29 3b 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e  );.  }..  return
4bd0: 20 72 63 3b 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 41   rc;.}.../*.** A
4be0: 20 68 65 6c 70 65 72 20 66 75 6e 63 74 69 6f 6e   helper function
4bf0: 20 75 73 65 64 20 62 79 20 65 63 68 6f 55 70 64   used by echoUpd
4c00: 61 74 65 28 29 20 61 6e 64 20 65 63 68 6f 42 65  ate() and echoBe
4c10: 73 74 49 6e 64 65 78 28 29 20 66 6f 72 0a 2a 2a  stIndex() for.**
4c20: 20 6d 61 6e 69 70 75 6c 61 74 69 6e 67 20 73 74   manipulating st
4c30: 72 69 6e 67 73 20 69 6e 20 63 6f 6e 63 65 72 74  rings in concert
4c40: 20 77 69 74 68 20 74 68 65 20 73 71 6c 69 74 65   with the sqlite
4c50: 33 5f 6d 70 72 69 6e 74 66 28 29 20 66 75 6e 63  3_mprintf() func
4c60: 74 69 6f 6e 2e 0a 2a 2a 0a 2a 2a 20 50 61 72 61  tion..**.** Para
4c70: 6d 65 74 65 72 20 70 7a 53 74 72 20 70 6f 69 6e  meter pzStr poin
4c80: 74 73 20 74 6f 20 61 20 70 6f 69 6e 74 65 72 20  ts to a pointer 
4c90: 74 6f 20 61 20 73 74 72 69 6e 67 20 61 6c 6c 6f  to a string allo
4ca0: 63 61 74 65 64 20 77 69 74 68 0a 2a 2a 20 73 71  cated with.** sq
4cb0: 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 2e 20 54  lite3_mprintf. T
4cc0: 68 65 20 73 65 63 6f 6e 64 20 70 61 72 61 6d 65  he second parame
4cd0: 74 65 72 2c 20 7a 41 70 70 65 6e 64 2c 20 70 6f  ter, zAppend, po
4ce0: 69 6e 74 73 20 74 6f 20 61 6e 6f 74 68 65 72 0a  ints to another.
4cf0: 2a 2a 20 73 74 72 69 6e 67 2e 20 54 68 65 20 74  ** string. The t
4d00: 77 6f 20 73 74 72 69 6e 67 73 20 61 72 65 20 63  wo strings are c
4d10: 6f 6e 63 61 74 65 6e 61 74 65 64 20 74 6f 67 65  oncatenated toge
4d20: 74 68 65 72 20 61 6e 64 20 2a 70 7a 53 74 72 0a  ther and *pzStr.
4d30: 2a 2a 20 73 65 74 20 74 6f 20 70 6f 69 6e 74 20  ** set to point 
4d40: 61 74 20 74 68 65 20 72 65 73 75 6c 74 2e 20 54  at the result. T
4d50: 68 65 20 69 6e 69 74 69 61 6c 20 62 75 66 66 65  he initial buffe
4d60: 72 20 70 6f 69 6e 74 65 64 20 74 6f 20 62 79 20  r pointed to by 
4d70: 2a 70 7a 53 74 72 0a 2a 2a 20 69 73 20 64 65 61  *pzStr.** is dea
4d80: 6c 6c 6f 63 61 74 65 64 20 76 69 61 20 73 71 6c  llocated via sql
4d90: 69 74 65 33 5f 66 72 65 65 28 29 2e 0a 2a 2a 0a  ite3_free()..**.
4da0: 2a 2a 20 49 66 20 74 68 65 20 74 68 69 72 64 20  ** If the third 
4db0: 61 72 67 75 6d 65 6e 74 2c 20 64 6f 46 72 65 65  argument, doFree
4dc0: 2c 20 69 73 20 74 72 75 65 2c 20 74 68 65 6e 20  , is true, then 
4dd0: 73 71 6c 69 74 65 33 5f 66 72 65 65 28 29 20 69  sqlite3_free() i
4de0: 73 0a 2a 2a 20 61 6c 73 6f 20 63 61 6c 6c 65 64  s.** also called
4df0: 20 74 6f 20 66 72 65 65 20 74 68 65 20 62 75 66   to free the buf
4e00: 66 65 72 20 70 6f 69 6e 74 65 64 20 74 6f 20 62  fer pointed to b
4e10: 79 20 7a 41 70 70 65 6e 64 2e 0a 2a 2f 0a 73 74  y zAppend..*/.st
4e20: 61 74 69 63 20 76 6f 69 64 20 73 74 72 69 6e 67  atic void string
4e30: 5f 63 6f 6e 63 61 74 28 63 68 61 72 20 2a 2a 70  _concat(char **p
4e40: 7a 53 74 72 2c 20 63 68 61 72 20 2a 7a 41 70 70  zStr, char *zApp
4e50: 65 6e 64 2c 20 69 6e 74 20 64 6f 46 72 65 65 2c  end, int doFree,
4e60: 20 69 6e 74 20 2a 70 52 63 29 7b 0a 20 20 63 68   int *pRc){.  ch
4e70: 61 72 20 2a 7a 49 6e 20 3d 20 2a 70 7a 53 74 72  ar *zIn = *pzStr
4e80: 3b 0a 20 20 69 66 28 20 21 7a 41 70 70 65 6e 64  ;.  if( !zAppend
4e90: 20 26 26 20 64 6f 46 72 65 65 20 26 26 20 2a 70   && doFree && *p
4ea0: 52 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  Rc==SQLITE_OK ){
4eb0: 0a 20 20 20 20 2a 70 52 63 20 3d 20 53 51 4c 49  .    *pRc = SQLI
4ec0: 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 7d 0a 20 20  TE_NOMEM;.  }.  
4ed0: 69 66 28 20 2a 70 52 63 21 3d 53 51 4c 49 54 45  if( *pRc!=SQLITE
4ee0: 5f 4f 4b 20 29 7b 0a 20 20 20 20 73 71 6c 69 74  _OK ){.    sqlit
4ef0: 65 33 5f 66 72 65 65 28 7a 49 6e 29 3b 0a 20 20  e3_free(zIn);.  
4f00: 20 20 7a 49 6e 20 3d 20 30 3b 0a 20 20 7d 65 6c    zIn = 0;.  }el
4f10: 73 65 7b 0a 20 20 20 20 69 66 28 20 7a 49 6e 20  se{.    if( zIn 
4f20: 29 7b 0a 20 20 20 20 20 20 63 68 61 72 20 2a 7a  ){.      char *z
4f30: 54 65 6d 70 20 3d 20 7a 49 6e 3b 0a 20 20 20 20  Temp = zIn;.    
4f40: 20 20 7a 49 6e 20 3d 20 73 71 6c 69 74 65 33 5f    zIn = sqlite3_
4f50: 6d 70 72 69 6e 74 66 28 22 25 73 25 73 22 2c 20  mprintf("%s%s", 
4f60: 7a 49 6e 2c 20 7a 41 70 70 65 6e 64 29 3b 0a 20  zIn, zAppend);. 
4f70: 20 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65       sqlite3_fre
4f80: 65 28 7a 54 65 6d 70 29 3b 0a 20 20 20 20 7d 65  e(zTemp);.    }e
4f90: 6c 73 65 7b 0a 20 20 20 20 20 20 7a 49 6e 20 3d  lse{.      zIn =
4fa0: 20 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66   sqlite3_mprintf
4fb0: 28 22 25 73 22 2c 20 7a 41 70 70 65 6e 64 29 3b  ("%s", zAppend);
4fc0: 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 28 20 21  .    }.    if( !
4fd0: 7a 49 6e 20 29 7b 0a 20 20 20 20 20 20 2a 70 52  zIn ){.      *pR
4fe0: 63 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d  c = SQLITE_NOMEM
4ff0: 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 2a 70  ;.    }.  }.  *p
5000: 7a 53 74 72 20 3d 20 7a 49 6e 3b 0a 20 20 69 66  zStr = zIn;.  if
5010: 28 20 64 6f 46 72 65 65 20 29 7b 0a 20 20 20 20  ( doFree ){.    
5020: 73 71 6c 69 74 65 33 5f 66 72 65 65 28 7a 41 70  sqlite3_free(zAp
5030: 70 65 6e 64 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a  pend);.  }.}../*
5040: 0a 2a 2a 20 54 68 65 20 65 63 68 6f 20 6d 6f 64  .** The echo mod
5050: 75 6c 65 20 69 6d 70 6c 65 6d 65 6e 74 73 20 74  ule implements t
5060: 68 65 20 73 75 62 73 65 74 20 6f 66 20 71 75 65  he subset of que
5070: 72 79 20 63 6f 6e 73 74 72 61 69 6e 74 73 20 61  ry constraints a
5080: 6e 64 20 73 6f 72 74 0a 2a 2a 20 6f 72 64 65 72  nd sort.** order
5090: 73 20 74 68 61 74 20 6d 61 79 20 74 61 6b 65 20  s that may take 
50a0: 61 64 76 61 6e 74 61 67 65 20 6f 66 20 53 51 4c  advantage of SQL
50b0: 69 74 65 20 69 6e 64 69 63 65 73 20 6f 6e 20 74  ite indices on t
50c0: 68 65 20 75 6e 64 65 72 6c 79 69 6e 67 0a 2a 2a  he underlying.**
50d0: 20 72 65 61 6c 20 74 61 62 6c 65 2e 20 46 6f 72   real table. For
50e0: 20 65 78 61 6d 70 6c 65 2c 20 69 66 20 74 68 65   example, if the
50f0: 20 72 65 61 6c 20 74 61 62 6c 65 20 69 73 20 64   real table is d
5100: 65 63 6c 61 72 65 64 20 61 73 3a 0a 2a 2a 0a 2a  eclared as:.**.*
5110: 2a 20 20 20 20 20 43 52 45 41 54 45 20 54 41 42  *     CREATE TAB
5120: 4c 45 20 72 65 61 6c 28 61 2c 20 62 2c 20 63 29  LE real(a, b, c)
5130: 3b 0a 2a 2a 20 20 20 20 20 43 52 45 41 54 45 20  ;.**     CREATE 
5140: 49 4e 44 45 58 20 72 65 61 6c 5f 69 6e 64 65 78  INDEX real_index
5150: 20 4f 4e 20 72 65 61 6c 28 62 29 3b 0a 2a 2a 0a   ON real(b);.**.
5160: 2a 2a 20 74 68 65 6e 20 74 68 65 20 65 63 68 6f  ** then the echo
5170: 20 6d 6f 64 75 6c 65 20 68 61 6e 64 6c 65 73 20   module handles 
5180: 57 48 45 52 45 20 6f 72 20 4f 52 44 45 52 20 42  WHERE or ORDER B
5190: 59 20 63 6c 61 75 73 65 73 20 74 68 61 74 20 72  Y clauses that r
51a0: 65 66 65 72 0a 2a 2a 20 74 6f 20 74 68 65 20 63  efer.** to the c
51b0: 6f 6c 75 6d 6e 20 22 62 22 2c 20 62 75 74 20 6e  olumn "b", but n
51c0: 6f 74 20 22 61 22 20 6f 72 20 22 63 22 2e 20 49  ot "a" or "c". I
51d0: 66 20 61 20 6d 75 6c 74 69 2d 63 6f 6c 75 6d 6e  f a multi-column
51e0: 20 69 6e 64 65 78 20 69 73 0a 2a 2a 20 70 72 65   index is.** pre
51f0: 73 65 6e 74 2c 20 6f 6e 6c 79 20 69 74 73 20 6c  sent, only its l
5200: 65 66 74 20 6d 6f 73 74 20 63 6f 6c 75 6d 6e 20  eft most column 
5210: 69 73 20 63 6f 6e 73 69 64 65 72 65 64 2e 20 0a  is considered. .
5220: 2a 2a 0a 2a 2a 20 54 68 69 73 20 78 42 65 73 74  **.** This xBest
5230: 49 6e 64 65 78 20 6d 65 74 68 6f 64 20 65 6e 63  Index method enc
5240: 6f 64 65 73 20 74 68 65 20 70 72 6f 70 6f 73 65  odes the propose
5250: 64 20 73 65 61 72 63 68 20 73 74 72 61 74 65 67  d search strateg
5260: 79 20 61 73 0a 2a 2a 20 61 6e 20 53 51 4c 20 71  y as.** an SQL q
5270: 75 65 72 79 20 6f 6e 20 74 68 65 20 72 65 61 6c  uery on the real
5280: 20 74 61 62 6c 65 20 75 6e 64 65 72 6c 79 69 6e   table underlyin
5290: 67 20 74 68 65 20 76 69 72 74 75 61 6c 20 65 63  g the virtual ec
52a0: 68 6f 20 6d 6f 64 75 6c 65 20 0a 2a 2a 20 74 61  ho module .** ta
52b0: 62 6c 65 20 61 6e 64 20 73 74 6f 72 65 73 20 74  ble and stores t
52c0: 68 65 20 71 75 65 72 79 20 69 6e 20 73 71 6c 69  he query in sqli
52d0: 74 65 33 5f 69 6e 64 65 78 5f 69 6e 66 6f 2e 69  te3_index_info.i
52e0: 64 78 53 74 72 2e 20 54 68 65 20 53 51 4c 0a 2a  dxStr. The SQL.*
52f0: 2a 20 73 74 61 74 65 6d 65 6e 74 20 69 73 20 6f  * statement is o
5300: 66 20 74 68 65 20 66 6f 72 6d 3a 0a 2a 2a 0a 2a  f the form:.**.*
5310: 2a 20 20 20 53 45 4c 45 43 54 20 72 6f 77 69 64  *   SELECT rowid
5320: 2c 20 2a 20 46 52 4f 4d 20 3c 72 65 61 6c 2d 74  , * FROM <real-t
5330: 61 62 6c 65 3e 20 3f 3c 77 68 65 72 65 2d 63 6c  able> ?<where-cl
5340: 61 75 73 65 3e 3f 20 3f 3c 6f 72 64 65 72 2d 62  ause>? ?<order-b
5350: 79 2d 63 6c 61 75 73 65 3e 3f 0a 2a 2a 0a 2a 2a  y-clause>?.**.**
5360: 20 77 68 65 72 65 20 74 68 65 20 3c 77 68 65 72   where the <wher
5370: 65 2d 63 6c 61 75 73 65 3e 20 61 6e 64 20 3c 6f  e-clause> and <o
5380: 72 64 65 72 2d 62 79 2d 63 6c 61 75 73 65 3e 20  rder-by-clause> 
5390: 61 72 65 20 64 65 74 65 72 6d 69 6e 65 64 0a 2a  are determined.*
53a0: 2a 20 62 79 20 74 68 65 20 63 6f 6e 74 65 6e 74  * by the content
53b0: 73 20 6f 66 20 74 68 65 20 73 74 72 75 63 74 75  s of the structu
53c0: 72 65 20 70 6f 69 6e 74 65 64 20 74 6f 20 62 79  re pointed to by
53d0: 20 74 68 65 20 70 49 64 78 49 6e 66 6f 20 61 72   the pIdxInfo ar
53e0: 67 75 6d 65 6e 74 2e 0a 2a 2f 0a 73 74 61 74 69  gument..*/.stati
53f0: 63 20 69 6e 74 20 65 63 68 6f 42 65 73 74 49 6e  c int echoBestIn
5400: 64 65 78 28 73 71 6c 69 74 65 33 5f 76 74 61 62  dex(sqlite3_vtab
5410: 20 2a 74 61 62 2c 20 73 71 6c 69 74 65 33 5f 69   *tab, sqlite3_i
5420: 6e 64 65 78 5f 69 6e 66 6f 20 2a 70 49 64 78 49  ndex_info *pIdxI
5430: 6e 66 6f 29 7b 0a 20 20 69 6e 74 20 69 69 3b 0a  nfo){.  int ii;.
5440: 20 20 63 68 61 72 20 2a 7a 51 75 65 72 79 20 3d    char *zQuery =
5450: 20 30 3b 0a 20 20 63 68 61 72 20 2a 7a 4e 65 77   0;.  char *zNew
5460: 3b 0a 20 20 69 6e 74 20 6e 41 72 67 20 3d 20 30  ;.  int nArg = 0
5470: 3b 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a  ;.  const char *
5480: 7a 53 65 70 20 3d 20 22 57 48 45 52 45 22 3b 0a  zSep = "WHERE";.
5490: 20 20 65 63 68 6f 5f 76 74 61 62 20 2a 70 56 74    echo_vtab *pVt
54a0: 61 62 20 3d 20 28 65 63 68 6f 5f 76 74 61 62 20  ab = (echo_vtab 
54b0: 2a 29 74 61 62 3b 0a 20 20 73 71 6c 69 74 65 33  *)tab;.  sqlite3
54c0: 5f 73 74 6d 74 20 2a 70 53 74 6d 74 20 3d 20 30  _stmt *pStmt = 0
54d0: 3b 0a 20 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a  ;.  Tcl_Interp *
54e0: 69 6e 74 65 72 70 20 3d 20 70 56 74 61 62 2d 3e  interp = pVtab->
54f0: 69 6e 74 65 72 70 3b 0a 0a 20 20 69 6e 74 20 6e  interp;..  int n
5500: 52 6f 77 3b 0a 20 20 69 6e 74 20 75 73 65 49 64  Row;.  int useId
5510: 78 20 3d 20 30 3b 0a 20 20 69 6e 74 20 72 63 20  x = 0;.  int rc 
5520: 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 69  = SQLITE_OK;.  i
5530: 6e 74 20 75 73 65 43 6f 73 74 20 3d 20 30 3b 0a  nt useCost = 0;.
5540: 20 20 64 6f 75 62 6c 65 20 63 6f 73 74 3b 0a 20    double cost;. 
5550: 20 69 6e 74 20 69 73 49 67 6e 6f 72 65 55 73 61   int isIgnoreUsa
5560: 62 6c 65 20 3d 20 30 3b 0a 20 20 69 66 28 20 54  ble = 0;.  if( T
5570: 63 6c 5f 47 65 74 56 61 72 28 69 6e 74 65 72 70  cl_GetVar(interp
5580: 2c 20 22 65 63 68 6f 5f 6d 6f 64 75 6c 65 5f 69  , "echo_module_i
5590: 67 6e 6f 72 65 5f 75 73 61 62 6c 65 22 2c 20 54  gnore_usable", T
55a0: 43 4c 5f 47 4c 4f 42 41 4c 5f 4f 4e 4c 59 29 20  CL_GLOBAL_ONLY) 
55b0: 29 7b 0a 20 20 20 20 69 73 49 67 6e 6f 72 65 55  ){.    isIgnoreU
55c0: 73 61 62 6c 65 20 3d 20 31 3b 0a 20 20 7d 0a 0a  sable = 1;.  }..
55d0: 20 20 69 66 28 20 73 69 6d 75 6c 61 74 65 56 74    if( simulateVt
55e0: 61 62 45 72 72 6f 72 28 70 56 74 61 62 2c 20 22  abError(pVtab, "
55f0: 78 42 65 73 74 49 6e 64 65 78 22 29 20 29 7b 0a  xBestIndex") ){.
5600: 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54      return SQLIT
5610: 45 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a 0a 20 20  E_ERROR;.  }..  
5620: 2f 2a 20 44 65 74 65 72 6d 69 6e 65 20 74 68 65  /* Determine the
5630: 20 6e 75 6d 62 65 72 20 6f 66 20 72 6f 77 73 20   number of rows 
5640: 69 6e 20 74 68 65 20 74 61 62 6c 65 20 61 6e 64  in the table and
5650: 20 73 74 6f 72 65 20 74 68 69 73 20 76 61 6c 75   store this valu
5660: 65 20 69 6e 20 6c 6f 63 61 6c 0a 20 20 2a 2a 20  e in local.  ** 
5670: 76 61 72 69 61 62 6c 65 20 6e 52 6f 77 2e 20 54  variable nRow. T
5680: 68 65 20 27 65 73 74 69 6d 61 74 65 64 2d 63 6f  he 'estimated-co
5690: 73 74 27 20 6f 66 20 74 68 65 20 73 63 61 6e 20  st' of the scan 
56a0: 77 69 6c 6c 20 62 65 20 74 68 65 20 6e 75 6d 62  will be the numb
56b0: 65 72 20 6f 66 0a 20 20 2a 2a 20 72 6f 77 73 20  er of.  ** rows 
56c0: 69 6e 20 74 68 65 20 74 61 62 6c 65 20 66 6f 72  in the table for
56d0: 20 61 20 6c 69 6e 65 61 72 20 73 63 61 6e 2c 20   a linear scan, 
56e0: 6f 72 20 74 68 65 20 6c 6f 67 20 28 62 61 73 65  or the log (base
56f0: 20 32 29 20 6f 66 20 74 68 65 20 0a 20 20 2a 2a   2) of the .  **
5700: 20 6e 75 6d 62 65 72 20 6f 66 20 72 6f 77 73 20   number of rows 
5710: 69 66 20 74 68 65 20 70 72 6f 70 6f 73 65 64 20  if the proposed 
5720: 73 63 61 6e 20 75 73 65 73 20 61 6e 20 69 6e 64  scan uses an ind
5730: 65 78 2e 20 20 0a 20 20 2a 2f 0a 20 20 69 66 28  ex.  .  */.  if(
5740: 20 54 63 6c 5f 47 65 74 56 61 72 28 69 6e 74 65   Tcl_GetVar(inte
5750: 72 70 2c 20 22 65 63 68 6f 5f 6d 6f 64 75 6c 65  rp, "echo_module
5760: 5f 63 6f 73 74 22 2c 20 54 43 4c 5f 47 4c 4f 42  _cost", TCL_GLOB
5770: 41 4c 5f 4f 4e 4c 59 29 20 29 7b 0a 20 20 20 20  AL_ONLY) ){.    
5780: 63 6f 73 74 20 3d 20 61 74 6f 66 28 54 63 6c 5f  cost = atof(Tcl_
5790: 47 65 74 56 61 72 28 69 6e 74 65 72 70 2c 20 22  GetVar(interp, "
57a0: 65 63 68 6f 5f 6d 6f 64 75 6c 65 5f 63 6f 73 74  echo_module_cost
57b0: 22 2c 20 54 43 4c 5f 47 4c 4f 42 41 4c 5f 4f 4e  ", TCL_GLOBAL_ON
57c0: 4c 59 29 29 3b 0a 20 20 20 20 75 73 65 43 6f 73  LY));.    useCos
57d0: 74 20 3d 20 31 3b 0a 20 20 7d 20 65 6c 73 65 20  t = 1;.  } else 
57e0: 7b 0a 20 20 20 20 7a 51 75 65 72 79 20 3d 20 73  {.    zQuery = s
57f0: 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 22  qlite3_mprintf("
5800: 53 45 4c 45 43 54 20 63 6f 75 6e 74 28 2a 29 20  SELECT count(*) 
5810: 46 52 4f 4d 20 25 51 22 2c 20 70 56 74 61 62 2d  FROM %Q", pVtab-
5820: 3e 7a 54 61 62 6c 65 4e 61 6d 65 29 3b 0a 20 20  >zTableName);.  
5830: 20 20 69 66 28 20 21 7a 51 75 65 72 79 20 29 7b    if( !zQuery ){
5840: 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20 53 51  .      return SQ
5850: 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20  LITE_NOMEM;.    
5860: 7d 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74  }.    rc = sqlit
5870: 65 33 5f 70 72 65 70 61 72 65 28 70 56 74 61 62  e3_prepare(pVtab
5880: 2d 3e 64 62 2c 20 7a 51 75 65 72 79 2c 20 2d 31  ->db, zQuery, -1
5890: 2c 20 26 70 53 74 6d 74 2c 20 30 29 3b 0a 20 20  , &pStmt, 0);.  
58a0: 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 7a    sqlite3_free(z
58b0: 51 75 65 72 79 29 3b 0a 20 20 20 20 69 66 28 20  Query);.    if( 
58c0: 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc!=SQLITE_OK ){
58d0: 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20 72 63  .      return rc
58e0: 3b 0a 20 20 20 20 7d 0a 20 20 20 20 73 71 6c 69  ;.    }.    sqli
58f0: 74 65 33 5f 73 74 65 70 28 70 53 74 6d 74 29 3b  te3_step(pStmt);
5900: 0a 20 20 20 20 6e 52 6f 77 20 3d 20 73 71 6c 69  .    nRow = sqli
5910: 74 65 33 5f 63 6f 6c 75 6d 6e 5f 69 6e 74 28 70  te3_column_int(p
5920: 53 74 6d 74 2c 20 30 29 3b 0a 20 20 20 20 72 63  Stmt, 0);.    rc
5930: 20 3d 20 73 71 6c 69 74 65 33 5f 66 69 6e 61 6c   = sqlite3_final
5940: 69 7a 65 28 70 53 74 6d 74 29 3b 0a 20 20 20 20  ize(pStmt);.    
5950: 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f  if( rc!=SQLITE_O
5960: 4b 20 29 7b 0a 20 20 20 20 20 20 72 65 74 75 72  K ){.      retur
5970: 6e 20 72 63 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a  n rc;.    }.  }.
5980: 0a 20 20 7a 51 75 65 72 79 20 3d 20 73 71 6c 69  .  zQuery = sqli
5990: 74 65 33 5f 6d 70 72 69 6e 74 66 28 22 53 45 4c  te3_mprintf("SEL
59a0: 45 43 54 20 72 6f 77 69 64 2c 20 2a 20 46 52 4f  ECT rowid, * FRO
59b0: 4d 20 25 51 22 2c 20 70 56 74 61 62 2d 3e 7a 54  M %Q", pVtab->zT
59c0: 61 62 6c 65 4e 61 6d 65 29 3b 0a 20 20 69 66 28  ableName);.  if(
59d0: 20 21 7a 51 75 65 72 79 20 29 7b 0a 20 20 20 20   !zQuery ){.    
59e0: 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f  return SQLITE_NO
59f0: 4d 45 4d 3b 0a 20 20 7d 0a 20 20 66 6f 72 28 69  MEM;.  }.  for(i
5a00: 69 3d 30 3b 20 69 69 3c 70 49 64 78 49 6e 66 6f  i=0; ii<pIdxInfo
5a10: 2d 3e 6e 43 6f 6e 73 74 72 61 69 6e 74 3b 20 69  ->nConstraint; i
5a20: 69 2b 2b 29 7b 0a 20 20 20 20 63 6f 6e 73 74 20  i++){.    const 
5a30: 73 74 72 75 63 74 20 73 71 6c 69 74 65 33 5f 69  struct sqlite3_i
5a40: 6e 64 65 78 5f 63 6f 6e 73 74 72 61 69 6e 74 20  ndex_constraint 
5a50: 2a 70 43 6f 6e 73 74 72 61 69 6e 74 3b 0a 20 20  *pConstraint;.  
5a60: 20 20 73 74 72 75 63 74 20 73 71 6c 69 74 65 33    struct sqlite3
5a70: 5f 69 6e 64 65 78 5f 63 6f 6e 73 74 72 61 69 6e  _index_constrain
5a80: 74 5f 75 73 61 67 65 20 2a 70 55 73 61 67 65 3b  t_usage *pUsage;
5a90: 0a 20 20 20 20 69 6e 74 20 69 43 6f 6c 3b 0a 0a  .    int iCol;..
5aa0: 20 20 20 20 70 43 6f 6e 73 74 72 61 69 6e 74 20      pConstraint 
5ab0: 3d 20 26 70 49 64 78 49 6e 66 6f 2d 3e 61 43 6f  = &pIdxInfo->aCo
5ac0: 6e 73 74 72 61 69 6e 74 5b 69 69 5d 3b 0a 20 20  nstraint[ii];.  
5ad0: 20 20 70 55 73 61 67 65 20 3d 20 26 70 49 64 78    pUsage = &pIdx
5ae0: 49 6e 66 6f 2d 3e 61 43 6f 6e 73 74 72 61 69 6e  Info->aConstrain
5af0: 74 55 73 61 67 65 5b 69 69 5d 3b 0a 0a 20 20 20  tUsage[ii];..   
5b00: 20 69 66 28 20 21 69 73 49 67 6e 6f 72 65 55 73   if( !isIgnoreUs
5b10: 61 62 6c 65 20 26 26 20 21 70 43 6f 6e 73 74 72  able && !pConstr
5b20: 61 69 6e 74 2d 3e 75 73 61 62 6c 65 20 29 20 63  aint->usable ) c
5b30: 6f 6e 74 69 6e 75 65 3b 0a 0a 20 20 20 20 69 43  ontinue;..    iC
5b40: 6f 6c 20 3d 20 70 43 6f 6e 73 74 72 61 69 6e 74  ol = pConstraint
5b50: 2d 3e 69 43 6f 6c 75 6d 6e 3b 0a 20 20 20 20 69  ->iColumn;.    i
5b60: 66 28 20 70 56 74 61 62 2d 3e 61 49 6e 64 65 78  f( pVtab->aIndex
5b70: 5b 69 43 6f 6c 5d 20 7c 7c 20 69 43 6f 6c 3c 30  [iCol] || iCol<0
5b80: 20 29 7b 0a 20 20 20 20 20 20 63 68 61 72 20 2a   ){.      char *
5b90: 7a 43 6f 6c 20 3d 20 70 56 74 61 62 2d 3e 61 43  zCol = pVtab->aC
5ba0: 6f 6c 5b 69 43 6f 6c 5d 3b 0a 20 20 20 20 20 20  ol[iCol];.      
5bb0: 63 68 61 72 20 2a 7a 4f 70 20 3d 20 30 3b 0a 20  char *zOp = 0;. 
5bc0: 20 20 20 20 20 75 73 65 49 64 78 20 3d 20 31 3b       useIdx = 1;
5bd0: 0a 20 20 20 20 20 20 69 66 28 20 69 43 6f 6c 3c  .      if( iCol<
5be0: 30 20 29 7b 0a 20 20 20 20 20 20 20 20 7a 43 6f  0 ){.        zCo
5bf0: 6c 20 3d 20 22 72 6f 77 69 64 22 3b 0a 20 20 20  l = "rowid";.   
5c00: 20 20 20 7d 0a 20 20 20 20 20 20 73 77 69 74 63     }.      switc
5c10: 68 28 20 70 43 6f 6e 73 74 72 61 69 6e 74 2d 3e  h( pConstraint->
5c20: 6f 70 20 29 7b 0a 20 20 20 20 20 20 20 20 63 61  op ){.        ca
5c30: 73 65 20 53 51 4c 49 54 45 5f 49 4e 44 45 58 5f  se SQLITE_INDEX_
5c40: 43 4f 4e 53 54 52 41 49 4e 54 5f 45 51 3a 0a 20  CONSTRAINT_EQ:. 
5c50: 20 20 20 20 20 20 20 20 20 7a 4f 70 20 3d 20 22           zOp = "
5c60: 3d 22 3b 20 62 72 65 61 6b 3b 0a 20 20 20 20 20  ="; break;.     
5c70: 20 20 20 63 61 73 65 20 53 51 4c 49 54 45 5f 49     case SQLITE_I
5c80: 4e 44 45 58 5f 43 4f 4e 53 54 52 41 49 4e 54 5f  NDEX_CONSTRAINT_
5c90: 4c 54 3a 0a 20 20 20 20 20 20 20 20 20 20 7a 4f  LT:.          zO
5ca0: 70 20 3d 20 22 3c 22 3b 20 62 72 65 61 6b 3b 0a  p = "<"; break;.
5cb0: 20 20 20 20 20 20 20 20 63 61 73 65 20 53 51 4c          case SQL
5cc0: 49 54 45 5f 49 4e 44 45 58 5f 43 4f 4e 53 54 52  ITE_INDEX_CONSTR
5cd0: 41 49 4e 54 5f 47 54 3a 0a 20 20 20 20 20 20 20  AINT_GT:.       
5ce0: 20 20 20 7a 4f 70 20 3d 20 22 3e 22 3b 20 62 72     zOp = ">"; br
5cf0: 65 61 6b 3b 0a 20 20 20 20 20 20 20 20 63 61 73  eak;.        cas
5d00: 65 20 53 51 4c 49 54 45 5f 49 4e 44 45 58 5f 43  e SQLITE_INDEX_C
5d10: 4f 4e 53 54 52 41 49 4e 54 5f 4c 45 3a 0a 20 20  ONSTRAINT_LE:.  
5d20: 20 20 20 20 20 20 20 20 7a 4f 70 20 3d 20 22 3c          zOp = "<
5d30: 3d 22 3b 20 62 72 65 61 6b 3b 0a 20 20 20 20 20  ="; break;.     
5d40: 20 20 20 63 61 73 65 20 53 51 4c 49 54 45 5f 49     case SQLITE_I
5d50: 4e 44 45 58 5f 43 4f 4e 53 54 52 41 49 4e 54 5f  NDEX_CONSTRAINT_
5d60: 47 45 3a 0a 20 20 20 20 20 20 20 20 20 20 7a 4f  GE:.          zO
5d70: 70 20 3d 20 22 3e 3d 22 3b 20 62 72 65 61 6b 3b  p = ">="; break;
5d80: 0a 20 20 20 20 20 20 20 20 63 61 73 65 20 53 51  .        case SQ
5d90: 4c 49 54 45 5f 49 4e 44 45 58 5f 43 4f 4e 53 54  LITE_INDEX_CONST
5da0: 52 41 49 4e 54 5f 4d 41 54 43 48 3a 0a 20 20 20  RAINT_MATCH:.   
5db0: 20 20 20 20 20 20 20 7a 4f 70 20 3d 20 22 4c 49         zOp = "LI
5dc0: 4b 45 22 3b 20 62 72 65 61 6b 3b 0a 20 20 20 20  KE"; break;.    
5dd0: 20 20 7d 0a 20 20 20 20 20 20 69 66 28 20 7a 4f    }.      if( zO
5de0: 70 5b 30 5d 3d 3d 27 4c 27 20 29 7b 0a 20 20 20  p[0]=='L' ){.   
5df0: 20 20 20 20 20 7a 4e 65 77 20 3d 20 73 71 6c 69       zNew = sqli
5e00: 74 65 33 5f 6d 70 72 69 6e 74 66 28 22 20 25 73  te3_mprintf(" %s
5e10: 20 25 73 20 4c 49 4b 45 20 28 53 45 4c 45 43 54   %s LIKE (SELECT
5e20: 20 27 25 25 27 7c 7c 3f 7c 7c 27 25 25 27 29 22   '%%'||?||'%%')"
5e30: 2c 20 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  , .             
5e40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5e50: 20 20 7a 53 65 70 2c 20 7a 43 6f 6c 29 3b 0a 20    zSep, zCol);. 
5e60: 20 20 20 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20       } else {.  
5e70: 20 20 20 20 20 20 7a 4e 65 77 20 3d 20 73 71 6c        zNew = sql
5e80: 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 22 20 25  ite3_mprintf(" %
5e90: 73 20 25 73 20 25 73 20 3f 22 2c 20 7a 53 65 70  s %s %s ?", zSep
5ea0: 2c 20 7a 43 6f 6c 2c 20 7a 4f 70 29 3b 0a 20 20  , zCol, zOp);.  
5eb0: 20 20 20 20 7d 0a 20 20 20 20 20 20 73 74 72 69      }.      stri
5ec0: 6e 67 5f 63 6f 6e 63 61 74 28 26 7a 51 75 65 72  ng_concat(&zQuer
5ed0: 79 2c 20 7a 4e 65 77 2c 20 31 2c 20 26 72 63 29  y, zNew, 1, &rc)
5ee0: 3b 0a 0a 20 20 20 20 20 20 7a 53 65 70 20 3d 20  ;..      zSep = 
5ef0: 22 41 4e 44 22 3b 0a 20 20 20 20 20 20 70 55 73  "AND";.      pUs
5f00: 61 67 65 2d 3e 61 72 67 76 49 6e 64 65 78 20 3d  age->argvIndex =
5f10: 20 2b 2b 6e 41 72 67 3b 0a 20 20 20 20 20 20 70   ++nArg;.      p
5f20: 55 73 61 67 65 2d 3e 6f 6d 69 74 20 3d 20 31 3b  Usage->omit = 1;
5f30: 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 2f 2a  .    }.  }..  /*
5f40: 20 49 66 20 74 68 65 72 65 20 69 73 20 6f 6e 6c   If there is onl
5f50: 79 20 6f 6e 65 20 74 65 72 6d 20 69 6e 20 74 68  y one term in th
5f60: 65 20 4f 52 44 45 52 20 42 59 20 63 6c 61 75 73  e ORDER BY claus
5f70: 65 2c 20 61 6e 64 20 69 74 20 69 73 0a 20 20 2a  e, and it is.  *
5f80: 2a 20 6f 6e 20 61 20 63 6f 6c 75 6d 6e 20 74 68  * on a column th
5f90: 61 74 20 74 68 69 73 20 76 69 72 74 75 61 6c 20  at this virtual 
5fa0: 74 61 62 6c 65 20 68 61 73 20 61 6e 20 69 6e 64  table has an ind
5fb0: 65 78 20 66 6f 72 2c 20 74 68 65 6e 20 63 6f 6e  ex for, then con
5fc0: 73 75 6d 65 20 0a 20 20 2a 2a 20 74 68 65 20 4f  sume .  ** the O
5fd0: 52 44 45 52 20 42 59 20 63 6c 61 75 73 65 2e 0a  RDER BY clause..
5fe0: 20 20 2a 2f 0a 20 20 69 66 28 20 70 49 64 78 49    */.  if( pIdxI
5ff0: 6e 66 6f 2d 3e 6e 4f 72 64 65 72 42 79 3d 3d 31  nfo->nOrderBy==1
6000: 20 26 26 20 70 56 74 61 62 2d 3e 61 49 6e 64 65   && pVtab->aInde
6010: 78 5b 70 49 64 78 49 6e 66 6f 2d 3e 61 4f 72 64  x[pIdxInfo->aOrd
6020: 65 72 42 79 2d 3e 69 43 6f 6c 75 6d 6e 5d 20 29  erBy->iColumn] )
6030: 7b 0a 20 20 20 20 69 6e 74 20 69 43 6f 6c 20 3d  {.    int iCol =
6040: 20 70 49 64 78 49 6e 66 6f 2d 3e 61 4f 72 64 65   pIdxInfo->aOrde
6050: 72 42 79 2d 3e 69 43 6f 6c 75 6d 6e 3b 0a 20 20  rBy->iColumn;.  
6060: 20 20 63 68 61 72 20 2a 7a 43 6f 6c 20 3d 20 70    char *zCol = p
6070: 56 74 61 62 2d 3e 61 43 6f 6c 5b 69 43 6f 6c 5d  Vtab->aCol[iCol]
6080: 3b 0a 20 20 20 20 63 68 61 72 20 2a 7a 44 69 72  ;.    char *zDir
6090: 20 3d 20 70 49 64 78 49 6e 66 6f 2d 3e 61 4f 72   = pIdxInfo->aOr
60a0: 64 65 72 42 79 2d 3e 64 65 73 63 3f 22 44 45 53  derBy->desc?"DES
60b0: 43 22 3a 22 41 53 43 22 3b 0a 20 20 20 20 69 66  C":"ASC";.    if
60c0: 28 20 69 43 6f 6c 3c 30 20 29 7b 0a 20 20 20 20  ( iCol<0 ){.    
60d0: 20 20 7a 43 6f 6c 20 3d 20 22 72 6f 77 69 64 22    zCol = "rowid"
60e0: 3b 0a 20 20 20 20 7d 0a 20 20 20 20 7a 4e 65 77  ;.    }.    zNew
60f0: 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e   = sqlite3_mprin
6100: 74 66 28 22 20 4f 52 44 45 52 20 42 59 20 25 73  tf(" ORDER BY %s
6110: 20 25 73 22 2c 20 7a 43 6f 6c 2c 20 7a 44 69 72   %s", zCol, zDir
6120: 29 3b 0a 20 20 20 20 73 74 72 69 6e 67 5f 63 6f  );.    string_co
6130: 6e 63 61 74 28 26 7a 51 75 65 72 79 2c 20 7a 4e  ncat(&zQuery, zN
6140: 65 77 2c 20 31 2c 20 26 72 63 29 3b 0a 20 20 20  ew, 1, &rc);.   
6150: 20 70 49 64 78 49 6e 66 6f 2d 3e 6f 72 64 65 72   pIdxInfo->order
6160: 42 79 43 6f 6e 73 75 6d 65 64 20 3d 20 31 3b 0a  ByConsumed = 1;.
6170: 20 20 7d 0a 0a 20 20 61 70 70 65 6e 64 54 6f 45    }..  appendToE
6180: 63 68 6f 4d 6f 64 75 6c 65 28 70 56 74 61 62 2d  choModule(pVtab-
6190: 3e 69 6e 74 65 72 70 2c 20 22 78 42 65 73 74 49  >interp, "xBestI
61a0: 6e 64 65 78 22 29 3b 3b 0a 20 20 61 70 70 65 6e  ndex");;.  appen
61b0: 64 54 6f 45 63 68 6f 4d 6f 64 75 6c 65 28 70 56  dToEchoModule(pV
61c0: 74 61 62 2d 3e 69 6e 74 65 72 70 2c 20 7a 51 75  tab->interp, zQu
61d0: 65 72 79 29 3b 0a 0a 20 20 69 66 28 20 21 7a 51  ery);..  if( !zQ
61e0: 75 65 72 79 20 29 7b 0a 20 20 20 20 72 65 74 75  uery ){.    retu
61f0: 72 6e 20 72 63 3b 0a 20 20 7d 0a 20 20 70 49 64  rn rc;.  }.  pId
6200: 78 49 6e 66 6f 2d 3e 69 64 78 4e 75 6d 20 3d 20  xInfo->idxNum = 
6210: 68 61 73 68 53 74 72 69 6e 67 28 7a 51 75 65 72  hashString(zQuer
6220: 79 29 3b 0a 20 20 70 49 64 78 49 6e 66 6f 2d 3e  y);.  pIdxInfo->
6230: 69 64 78 53 74 72 20 3d 20 7a 51 75 65 72 79 3b  idxStr = zQuery;
6240: 0a 20 20 70 49 64 78 49 6e 66 6f 2d 3e 6e 65 65  .  pIdxInfo->nee
6250: 64 54 6f 46 72 65 65 49 64 78 53 74 72 20 3d 20  dToFreeIdxStr = 
6260: 31 3b 0a 20 20 69 66 20 28 75 73 65 43 6f 73 74  1;.  if (useCost
6270: 29 20 7b 0a 20 20 20 20 70 49 64 78 49 6e 66 6f  ) {.    pIdxInfo
6280: 2d 3e 65 73 74 69 6d 61 74 65 64 43 6f 73 74 20  ->estimatedCost 
6290: 3d 20 63 6f 73 74 3b 0a 20 20 7d 20 65 6c 73 65  = cost;.  } else
62a0: 20 69 66 28 20 75 73 65 49 64 78 20 29 7b 0a 20   if( useIdx ){. 
62b0: 20 20 20 2f 2a 20 41 70 70 72 6f 78 69 6d 61 74     /* Approximat
62c0: 69 6f 6e 20 6f 66 20 6c 6f 67 32 28 6e 52 6f 77  ion of log2(nRow
62d0: 29 2e 20 2a 2f 0a 20 20 20 20 66 6f 72 28 20 69  ). */.    for( i
62e0: 69 3d 30 3b 20 69 69 3c 28 73 69 7a 65 6f 66 28  i=0; ii<(sizeof(
62f0: 69 6e 74 29 2a 38 29 3b 20 69 69 2b 2b 20 29 7b  int)*8); ii++ ){
6300: 0a 20 20 20 20 20 20 69 66 28 20 6e 52 6f 77 20  .      if( nRow 
6310: 26 20 28 31 3c 3c 69 69 29 20 29 7b 0a 20 20 20  & (1<<ii) ){.   
6320: 20 20 20 20 20 70 49 64 78 49 6e 66 6f 2d 3e 65       pIdxInfo->e
6330: 73 74 69 6d 61 74 65 64 43 6f 73 74 20 3d 20 28  stimatedCost = (
6340: 64 6f 75 62 6c 65 29 69 69 3b 0a 20 20 20 20 20  double)ii;.     
6350: 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 20 65 6c 73   }.    }.  } els
6360: 65 20 7b 0a 20 20 20 20 70 49 64 78 49 6e 66 6f  e {.    pIdxInfo
6370: 2d 3e 65 73 74 69 6d 61 74 65 64 43 6f 73 74 20  ->estimatedCost 
6380: 3d 20 28 64 6f 75 62 6c 65 29 6e 52 6f 77 3b 0a  = (double)nRow;.
6390: 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 72 63 3b    }.  return rc;
63a0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 65 20 78 55  .}../*.** The xU
63b0: 70 64 61 74 65 20 6d 65 74 68 6f 64 20 66 6f 72  pdate method for
63c0: 20 65 63 68 6f 20 6d 6f 64 75 6c 65 20 76 69 72   echo module vir
63d0: 74 75 61 6c 20 74 61 62 6c 65 73 2e 0a 2a 2a 20  tual tables..** 
63e0: 0a 2a 2a 20 20 20 20 61 70 44 61 74 61 5b 30 5d  .**    apData[0]
63f0: 20 20 61 70 44 61 74 61 5b 31 5d 20 20 61 70 44    apData[1]  apD
6400: 61 74 61 5b 32 2e 2e 5d 0a 2a 2a 0a 2a 2a 20 20  ata[2..].**.**  
6410: 20 20 49 4e 54 45 47 45 52 20 20 20 20 20 20 20    INTEGER       
6420: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6430: 20 20 20 20 20 20 20 44 45 4c 45 54 45 20 20 20         DELETE   
6440: 20 20 20 20 20 20 20 20 20 0a 2a 2a 0a 2a 2a 20           .**.** 
6450: 20 20 20 49 4e 54 45 47 45 52 20 20 20 20 4e 55     INTEGER    NU
6460: 4c 4c 20 20 20 20 20 20 20 28 6e 43 6f 6c 20 61  LL       (nCol a
6470: 72 67 73 29 20 20 20 20 55 50 44 41 54 45 20 28  rgs)    UPDATE (
6480: 64 6f 20 6e 6f 74 20 73 65 74 20 72 6f 77 69 64  do not set rowid
6490: 29 0a 2a 2a 20 20 20 20 49 4e 54 45 47 45 52 20  ).**    INTEGER 
64a0: 20 20 20 49 4e 54 45 47 45 52 20 20 20 20 28 6e     INTEGER    (n
64b0: 43 6f 6c 20 61 72 67 73 29 20 20 20 20 55 50 44  Col args)    UPD
64c0: 41 54 45 20 28 77 69 74 68 20 53 45 54 20 72 6f  ATE (with SET ro
64d0: 77 69 64 20 3d 20 3c 61 72 67 31 3e 29 0a 2a 2a  wid = <arg1>).**
64e0: 0a 2a 2a 20 20 20 20 4e 55 4c 4c 20 20 20 20 20  .**    NULL     
64f0: 20 20 4e 55 4c 4c 20 20 20 20 20 20 20 28 6e 43    NULL       (nC
6500: 6f 6c 20 61 72 67 73 29 20 20 20 20 49 4e 53 45  ol args)    INSE
6510: 52 54 20 49 4e 54 4f 20 28 61 75 74 6f 6d 61 74  RT INTO (automat
6520: 69 63 20 72 6f 77 69 64 20 76 61 6c 75 65 29 0a  ic rowid value).
6530: 2a 2a 20 20 20 20 4e 55 4c 4c 20 20 20 20 20 20  **    NULL      
6540: 20 49 4e 54 45 47 45 52 20 20 20 20 28 6e 43 6f   INTEGER    (nCo
6550: 6c 20 61 72 67 73 29 20 20 20 20 49 4e 53 45 52  l args)    INSER
6560: 54 20 28 69 6e 63 6c 2e 20 72 6f 77 69 64 20 76  T (incl. rowid v
6570: 61 6c 75 65 29 0a 2a 2a 0a 2a 2f 0a 69 6e 74 20  alue).**.*/.int 
6580: 65 63 68 6f 55 70 64 61 74 65 28 0a 20 20 73 71  echoUpdate(.  sq
6590: 6c 69 74 65 33 5f 76 74 61 62 20 2a 74 61 62 2c  lite3_vtab *tab,
65a0: 20 0a 20 20 69 6e 74 20 6e 44 61 74 61 2c 20 0a   .  int nData, .
65b0: 20 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 20    sqlite3_value 
65c0: 2a 2a 61 70 44 61 74 61 2c 20 0a 20 20 73 71 6c  **apData, .  sql
65d0: 69 74 65 5f 69 6e 74 36 34 20 2a 70 52 6f 77 69  ite_int64 *pRowi
65e0: 64 0a 29 7b 0a 20 20 65 63 68 6f 5f 76 74 61 62  d.){.  echo_vtab
65f0: 20 2a 70 56 74 61 62 20 3d 20 28 65 63 68 6f 5f   *pVtab = (echo_
6600: 76 74 61 62 20 2a 29 74 61 62 3b 0a 20 20 73 71  vtab *)tab;.  sq
6610: 6c 69 74 65 33 20 2a 64 62 20 3d 20 70 56 74 61  lite3 *db = pVta
6620: 62 2d 3e 64 62 3b 0a 20 20 69 6e 74 20 72 63 20  b->db;.  int rc 
6630: 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 0a 20 20  = SQLITE_OK;..  
6640: 73 71 6c 69 74 65 33 5f 73 74 6d 74 20 2a 70 53  sqlite3_stmt *pS
6650: 74 6d 74 3b 0a 20 20 63 68 61 72 20 2a 7a 20 3d  tmt;.  char *z =
6660: 20 30 3b 20 20 20 20 20 20 20 20 20 20 20 20 20   0;             
6670: 20 20 2f 2a 20 53 51 4c 20 73 74 61 74 65 6d 65    /* SQL stateme
6680: 6e 74 20 74 6f 20 65 78 65 63 75 74 65 20 2a 2f  nt to execute */
6690: 0a 20 20 69 6e 74 20 62 69 6e 64 41 72 67 5a 65  .  int bindArgZe
66a0: 72 6f 20 3d 20 30 3b 20 20 20 20 20 20 20 2f 2a  ro = 0;       /*
66b0: 20 54 72 75 65 20 74 6f 20 62 69 6e 64 20 61 70   True to bind ap
66c0: 44 61 74 61 5b 30 5d 20 74 6f 20 73 71 6c 20 76  Data[0] to sql v
66d0: 61 72 20 6e 6f 2e 20 6e 44 61 74 61 20 2a 2f 0a  ar no. nData */.
66e0: 20 20 69 6e 74 20 62 69 6e 64 41 72 67 4f 6e 65    int bindArgOne
66f0: 20 3d 20 30 3b 20 20 20 20 20 20 20 20 2f 2a 20   = 0;        /* 
6700: 54 72 75 65 20 74 6f 20 62 69 6e 64 20 61 70 44  True to bind apD
6710: 61 74 61 5b 31 5d 20 74 6f 20 73 71 6c 20 76 61  ata[1] to sql va
6720: 72 20 6e 6f 2e 20 31 20 2a 2f 0a 20 20 69 6e 74  r no. 1 */.  int
6730: 20 69 3b 20 20 20 20 20 20 20 20 20 20 20 20 20   i;             
6740: 20 20 20 20 20 20 20 20 2f 2a 20 43 6f 75 6e 74          /* Count
6750: 65 72 20 76 61 72 69 61 62 6c 65 20 75 73 65 64  er variable used
6760: 20 62 79 20 66 6f 72 20 6c 6f 6f 70 73 20 2a 2f   by for loops */
6770: 0a 0a 20 20 61 73 73 65 72 74 28 20 6e 44 61 74  ..  assert( nDat
6780: 61 3d 3d 70 56 74 61 62 2d 3e 6e 43 6f 6c 2b 32  a==pVtab->nCol+2
6790: 20 7c 7c 20 6e 44 61 74 61 3d 3d 31 20 29 3b 0a   || nData==1 );.
67a0: 0a 20 20 2f 2a 20 54 69 63 6b 65 74 20 23 33 30  .  /* Ticket #30
67b0: 38 33 20 2d 20 6d 61 6b 65 20 73 75 72 65 20 77  83 - make sure w
67c0: 65 20 61 6c 77 61 79 73 20 73 74 61 72 74 20 61  e always start a
67d0: 20 74 72 61 6e 73 61 63 74 69 6f 6e 20 70 72 69   transaction pri
67e0: 6f 72 20 74 6f 0a 20 20 2a 2a 20 6d 61 6b 69 6e  or to.  ** makin
67f0: 67 20 61 6e 79 20 63 68 61 6e 67 65 73 20 74 6f  g any changes to
6800: 20 61 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65   a virtual table
6810: 20 2a 2f 0a 20 20 61 73 73 65 72 74 28 20 70 56   */.  assert( pV
6820: 74 61 62 2d 3e 69 6e 54 72 61 6e 73 61 63 74 69  tab->inTransacti
6830: 6f 6e 20 29 3b 0a 0a 20 20 69 66 28 20 73 69 6d  on );..  if( sim
6840: 75 6c 61 74 65 56 74 61 62 45 72 72 6f 72 28 70  ulateVtabError(p
6850: 56 74 61 62 2c 20 22 78 55 70 64 61 74 65 22 29  Vtab, "xUpdate")
6860: 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 53   ){.    return S
6870: 51 4c 49 54 45 5f 45 52 52 4f 52 3b 0a 20 20 7d  QLITE_ERROR;.  }
6880: 0a 0a 20 20 2f 2a 20 49 66 20 61 70 44 61 74 61  ..  /* If apData
6890: 5b 30 5d 20 69 73 20 61 6e 20 69 6e 74 65 67 65  [0] is an intege
68a0: 72 20 61 6e 64 20 6e 44 61 74 61 3e 31 20 74 68  r and nData>1 th
68b0: 65 6e 20 64 6f 20 61 6e 20 55 50 44 41 54 45 20  en do an UPDATE 
68c0: 2a 2f 0a 20 20 69 66 28 20 6e 44 61 74 61 3e 31  */.  if( nData>1
68d0: 20 26 26 20 73 71 6c 69 74 65 33 5f 76 61 6c 75   && sqlite3_valu
68e0: 65 5f 74 79 70 65 28 61 70 44 61 74 61 5b 30 5d  e_type(apData[0]
68f0: 29 3d 3d 53 51 4c 49 54 45 5f 49 4e 54 45 47 45  )==SQLITE_INTEGE
6900: 52 20 29 7b 0a 20 20 20 20 63 68 61 72 20 2a 7a  R ){.    char *z
6910: 53 65 70 20 3d 20 22 20 53 45 54 22 3b 0a 20 20  Sep = " SET";.  
6920: 20 20 7a 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70    z = sqlite3_mp
6930: 72 69 6e 74 66 28 22 55 50 44 41 54 45 20 25 51  rintf("UPDATE %Q
6940: 22 2c 20 70 56 74 61 62 2d 3e 7a 54 61 62 6c 65  ", pVtab->zTable
6950: 4e 61 6d 65 29 3b 0a 20 20 20 20 69 66 28 20 21  Name);.    if( !
6960: 7a 20 29 7b 0a 20 20 20 20 20 20 72 63 20 3d 20  z ){.      rc = 
6970: 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20  SQLITE_NOMEM;.  
6980: 20 20 7d 0a 0a 20 20 20 20 62 69 6e 64 41 72 67    }..    bindArg
6990: 4f 6e 65 20 3d 20 28 61 70 44 61 74 61 5b 31 5d  One = (apData[1]
69a0: 20 26 26 20 73 71 6c 69 74 65 33 5f 76 61 6c 75   && sqlite3_valu
69b0: 65 5f 74 79 70 65 28 61 70 44 61 74 61 5b 31 5d  e_type(apData[1]
69c0: 29 3d 3d 53 51 4c 49 54 45 5f 49 4e 54 45 47 45  )==SQLITE_INTEGE
69d0: 52 29 3b 0a 20 20 20 20 62 69 6e 64 41 72 67 5a  R);.    bindArgZ
69e0: 65 72 6f 20 3d 20 31 3b 0a 0a 20 20 20 20 69 66  ero = 1;..    if
69f0: 28 20 62 69 6e 64 41 72 67 4f 6e 65 20 29 7b 0a  ( bindArgOne ){.
6a00: 20 20 20 20 20 20 20 73 74 72 69 6e 67 5f 63 6f         string_co
6a10: 6e 63 61 74 28 26 7a 2c 20 22 20 53 45 54 20 72  ncat(&z, " SET r
6a20: 6f 77 69 64 3d 3f 31 20 22 2c 20 30 2c 20 26 72  owid=?1 ", 0, &r
6a30: 63 29 3b 0a 20 20 20 20 20 20 20 7a 53 65 70 20  c);.       zSep 
6a40: 3d 20 22 2c 22 3b 0a 20 20 20 20 7d 0a 20 20 20  = ",";.    }.   
6a50: 20 66 6f 72 28 69 3d 32 3b 20 69 3c 6e 44 61 74   for(i=2; i<nDat
6a60: 61 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20 69  a; i++){.      i
6a70: 66 28 20 61 70 44 61 74 61 5b 69 5d 3d 3d 30 20  f( apData[i]==0 
6a80: 29 20 63 6f 6e 74 69 6e 75 65 3b 0a 20 20 20 20  ) continue;.    
6a90: 20 20 73 74 72 69 6e 67 5f 63 6f 6e 63 61 74 28    string_concat(
6aa0: 26 7a 2c 20 73 71 6c 69 74 65 33 5f 6d 70 72 69  &z, sqlite3_mpri
6ab0: 6e 74 66 28 0a 20 20 20 20 20 20 20 20 20 20 22  ntf(.          "
6ac0: 25 73 20 25 51 3d 3f 25 64 22 2c 20 7a 53 65 70  %s %Q=?%d", zSep
6ad0: 2c 20 70 56 74 61 62 2d 3e 61 43 6f 6c 5b 69 2d  , pVtab->aCol[i-
6ae0: 32 5d 2c 20 69 29 2c 20 31 2c 20 26 72 63 29 3b  2], i), 1, &rc);
6af0: 0a 20 20 20 20 20 20 7a 53 65 70 20 3d 20 22 2c  .      zSep = ",
6b00: 22 3b 0a 20 20 20 20 7d 0a 20 20 20 20 73 74 72  ";.    }.    str
6b10: 69 6e 67 5f 63 6f 6e 63 61 74 28 26 7a 2c 20 73  ing_concat(&z, s
6b20: 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 22  qlite3_mprintf("
6b30: 20 57 48 45 52 45 20 72 6f 77 69 64 3d 3f 25 64   WHERE rowid=?%d
6b40: 22 2c 20 6e 44 61 74 61 29 2c 20 31 2c 20 26 72  ", nData), 1, &r
6b50: 63 29 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 49 66  c);.  }..  /* If
6b60: 20 61 70 44 61 74 61 5b 30 5d 20 69 73 20 61 6e   apData[0] is an
6b70: 20 69 6e 74 65 67 65 72 20 61 6e 64 20 6e 44 61   integer and nDa
6b80: 74 61 3d 3d 31 20 74 68 65 6e 20 64 6f 20 61 20  ta==1 then do a 
6b90: 44 45 4c 45 54 45 20 2a 2f 0a 20 20 65 6c 73 65  DELETE */.  else
6ba0: 20 69 66 28 20 6e 44 61 74 61 3d 3d 31 20 26 26   if( nData==1 &&
6bb0: 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 74   sqlite3_value_t
6bc0: 79 70 65 28 61 70 44 61 74 61 5b 30 5d 29 3d 3d  ype(apData[0])==
6bd0: 53 51 4c 49 54 45 5f 49 4e 54 45 47 45 52 20 29  SQLITE_INTEGER )
6be0: 7b 0a 20 20 20 20 7a 20 3d 20 73 71 6c 69 74 65  {.    z = sqlite
6bf0: 33 5f 6d 70 72 69 6e 74 66 28 22 44 45 4c 45 54  3_mprintf("DELET
6c00: 45 20 46 52 4f 4d 20 25 51 20 57 48 45 52 45 20  E FROM %Q WHERE 
6c10: 72 6f 77 69 64 20 3d 20 3f 31 22 2c 20 70 56 74  rowid = ?1", pVt
6c20: 61 62 2d 3e 7a 54 61 62 6c 65 4e 61 6d 65 29 3b  ab->zTableName);
6c30: 0a 20 20 20 20 69 66 28 20 21 7a 20 29 7b 0a 20  .    if( !z ){. 
6c40: 20 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45       rc = SQLITE
6c50: 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 7d 0a 20 20  _NOMEM;.    }.  
6c60: 20 20 62 69 6e 64 41 72 67 5a 65 72 6f 20 3d 20    bindArgZero = 
6c70: 31 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 49 66 20  1;.  }..  /* If 
6c80: 74 68 65 20 66 69 72 73 74 20 61 72 67 75 6d 65  the first argume
6c90: 6e 74 20 69 73 20 4e 55 4c 4c 20 61 6e 64 20 74  nt is NULL and t
6ca0: 68 65 72 65 20 61 72 65 20 6d 6f 72 65 20 74 68  here are more th
6cb0: 61 6e 20 74 77 6f 20 61 72 67 73 2c 20 49 4e 53  an two args, INS
6cc0: 45 52 54 20 2a 2f 0a 20 20 65 6c 73 65 20 69 66  ERT */.  else if
6cd0: 28 20 6e 44 61 74 61 3e 32 20 26 26 20 73 71 6c  ( nData>2 && sql
6ce0: 69 74 65 33 5f 76 61 6c 75 65 5f 74 79 70 65 28  ite3_value_type(
6cf0: 61 70 44 61 74 61 5b 30 5d 29 3d 3d 53 51 4c 49  apData[0])==SQLI
6d00: 54 45 5f 4e 55 4c 4c 20 29 7b 0a 20 20 20 20 69  TE_NULL ){.    i
6d10: 6e 74 20 69 69 3b 0a 20 20 20 20 63 68 61 72 20  nt ii;.    char 
6d20: 2a 7a 49 6e 73 65 72 74 20 3d 20 30 3b 0a 20 20  *zInsert = 0;.  
6d30: 20 20 63 68 61 72 20 2a 7a 56 61 6c 75 65 73 20    char *zValues 
6d40: 3d 20 30 3b 0a 20 20 0a 20 20 20 20 7a 49 6e 73  = 0;.  .    zIns
6d50: 65 72 74 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70  ert = sqlite3_mp
6d60: 72 69 6e 74 66 28 22 49 4e 53 45 52 54 20 49 4e  rintf("INSERT IN
6d70: 54 4f 20 25 51 20 28 22 2c 20 70 56 74 61 62 2d  TO %Q (", pVtab-
6d80: 3e 7a 54 61 62 6c 65 4e 61 6d 65 29 3b 0a 20 20  >zTableName);.  
6d90: 20 20 69 66 28 20 21 7a 49 6e 73 65 72 74 20 29    if( !zInsert )
6da0: 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c  {.      rc = SQL
6db0: 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 7d  ITE_NOMEM;.    }
6dc0: 0a 20 20 20 20 69 66 28 20 73 71 6c 69 74 65 33  .    if( sqlite3
6dd0: 5f 76 61 6c 75 65 5f 74 79 70 65 28 61 70 44 61  _value_type(apDa
6de0: 74 61 5b 31 5d 29 3d 3d 53 51 4c 49 54 45 5f 49  ta[1])==SQLITE_I
6df0: 4e 54 45 47 45 52 20 29 7b 0a 20 20 20 20 20 20  NTEGER ){.      
6e00: 62 69 6e 64 41 72 67 4f 6e 65 20 3d 20 31 3b 0a  bindArgOne = 1;.
6e10: 20 20 20 20 20 20 7a 56 61 6c 75 65 73 20 3d 20        zValues = 
6e20: 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28  sqlite3_mprintf(
6e30: 22 3f 22 29 3b 0a 20 20 20 20 20 20 73 74 72 69  "?");.      stri
6e40: 6e 67 5f 63 6f 6e 63 61 74 28 26 7a 49 6e 73 65  ng_concat(&zInse
6e50: 72 74 2c 20 22 72 6f 77 69 64 22 2c 20 30 2c 20  rt, "rowid", 0, 
6e60: 26 72 63 29 3b 0a 20 20 20 20 7d 0a 0a 20 20 20  &rc);.    }..   
6e70: 20 61 73 73 65 72 74 28 28 70 56 74 61 62 2d 3e   assert((pVtab->
6e80: 6e 43 6f 6c 2b 32 29 3d 3d 6e 44 61 74 61 29 3b  nCol+2)==nData);
6e90: 0a 20 20 20 20 66 6f 72 28 69 69 3d 32 3b 20 69  .    for(ii=2; i
6ea0: 69 3c 6e 44 61 74 61 3b 20 69 69 2b 2b 29 7b 0a  i<nData; ii++){.
6eb0: 20 20 20 20 20 20 73 74 72 69 6e 67 5f 63 6f 6e        string_con
6ec0: 63 61 74 28 26 7a 49 6e 73 65 72 74 2c 20 0a 20  cat(&zInsert, . 
6ed0: 20 20 20 20 20 20 20 20 20 73 71 6c 69 74 65 33           sqlite3
6ee0: 5f 6d 70 72 69 6e 74 66 28 22 25 73 25 51 22 2c  _mprintf("%s%Q",
6ef0: 20 7a 56 61 6c 75 65 73 3f 22 2c 20 22 3a 22 22   zValues?", ":""
6f00: 2c 20 70 56 74 61 62 2d 3e 61 43 6f 6c 5b 69 69  , pVtab->aCol[ii
6f10: 2d 32 5d 29 2c 20 31 2c 20 26 72 63 29 3b 0a 20  -2]), 1, &rc);. 
6f20: 20 20 20 20 20 73 74 72 69 6e 67 5f 63 6f 6e 63       string_conc
6f30: 61 74 28 26 7a 56 61 6c 75 65 73 2c 20 0a 20 20  at(&zValues, .  
6f40: 20 20 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f          sqlite3_
6f50: 6d 70 72 69 6e 74 66 28 22 25 73 3f 25 64 22 2c  mprintf("%s?%d",
6f60: 20 7a 56 61 6c 75 65 73 3f 22 2c 20 22 3a 22 22   zValues?", ":""
6f70: 2c 20 69 69 29 2c 20 31 2c 20 26 72 63 29 3b 0a  , ii), 1, &rc);.
6f80: 20 20 20 20 7d 0a 0a 20 20 20 20 73 74 72 69 6e      }..    strin
6f90: 67 5f 63 6f 6e 63 61 74 28 26 7a 2c 20 7a 49 6e  g_concat(&z, zIn
6fa0: 73 65 72 74 2c 20 31 2c 20 26 72 63 29 3b 0a 20  sert, 1, &rc);. 
6fb0: 20 20 20 73 74 72 69 6e 67 5f 63 6f 6e 63 61 74     string_concat
6fc0: 28 26 7a 2c 20 22 29 20 56 41 4c 55 45 53 28 22  (&z, ") VALUES("
6fd0: 2c 20 30 2c 20 26 72 63 29 3b 0a 20 20 20 20 73  , 0, &rc);.    s
6fe0: 74 72 69 6e 67 5f 63 6f 6e 63 61 74 28 26 7a 2c  tring_concat(&z,
6ff0: 20 7a 56 61 6c 75 65 73 2c 20 31 2c 20 26 72 63   zValues, 1, &rc
7000: 29 3b 0a 20 20 20 20 73 74 72 69 6e 67 5f 63 6f  );.    string_co
7010: 6e 63 61 74 28 26 7a 2c 20 22 29 22 2c 20 30 2c  ncat(&z, ")", 0,
7020: 20 26 72 63 29 3b 0a 20 20 7d 0a 0a 20 20 2f 2a   &rc);.  }..  /*
7030: 20 41 6e 79 74 68 69 6e 67 20 65 6c 73 65 20 69   Anything else i
7040: 73 20 61 6e 20 65 72 72 6f 72 20 2a 2f 0a 20 20  s an error */.  
7050: 65 6c 73 65 7b 0a 20 20 20 20 61 73 73 65 72 74  else{.    assert
7060: 28 30 29 3b 0a 20 20 20 20 72 65 74 75 72 6e 20  (0);.    return 
7070: 53 51 4c 49 54 45 5f 45 52 52 4f 52 3b 0a 20 20  SQLITE_ERROR;.  
7080: 7d 0a 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c  }..  if( rc==SQL
7090: 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 72 63  ITE_OK ){.    rc
70a0: 20 3d 20 73 71 6c 69 74 65 33 5f 70 72 65 70 61   = sqlite3_prepa
70b0: 72 65 28 64 62 2c 20 7a 2c 20 2d 31 2c 20 26 70  re(db, z, -1, &p
70c0: 53 74 6d 74 2c 20 30 29 3b 0a 20 20 7d 0a 20 20  Stmt, 0);.  }.  
70d0: 61 73 73 65 72 74 28 20 72 63 21 3d 53 51 4c 49  assert( rc!=SQLI
70e0: 54 45 5f 4f 4b 20 7c 7c 20 70 53 74 6d 74 20 29  TE_OK || pStmt )
70f0: 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65  ;.  sqlite3_free
7100: 28 7a 29 3b 0a 20 20 69 66 28 20 72 63 3d 3d 53  (z);.  if( rc==S
7110: 51 4c 49 54 45 5f 4f 4b 20 29 20 7b 0a 20 20 20  QLITE_OK ) {.   
7120: 20 69 66 28 20 62 69 6e 64 41 72 67 5a 65 72 6f   if( bindArgZero
7130: 20 29 7b 0a 20 20 20 20 20 20 73 71 6c 69 74 65   ){.      sqlite
7140: 33 5f 62 69 6e 64 5f 76 61 6c 75 65 28 70 53 74  3_bind_value(pSt
7150: 6d 74 2c 20 6e 44 61 74 61 2c 20 61 70 44 61 74  mt, nData, apDat
7160: 61 5b 30 5d 29 3b 0a 20 20 20 20 7d 0a 20 20 20  a[0]);.    }.   
7170: 20 69 66 28 20 62 69 6e 64 41 72 67 4f 6e 65 20   if( bindArgOne 
7180: 29 7b 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33  ){.      sqlite3
7190: 5f 62 69 6e 64 5f 76 61 6c 75 65 28 70 53 74 6d  _bind_value(pStm
71a0: 74 2c 20 31 2c 20 61 70 44 61 74 61 5b 31 5d 29  t, 1, apData[1])
71b0: 3b 0a 20 20 20 20 7d 0a 20 20 20 20 66 6f 72 28  ;.    }.    for(
71c0: 69 3d 32 3b 20 69 3c 6e 44 61 74 61 20 26 26 20  i=2; i<nData && 
71d0: 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 3b 20 69  rc==SQLITE_OK; i
71e0: 2b 2b 29 7b 0a 20 20 20 20 20 20 69 66 28 20 61  ++){.      if( a
71f0: 70 44 61 74 61 5b 69 5d 20 29 20 72 63 20 3d 20  pData[i] ) rc = 
7200: 73 71 6c 69 74 65 33 5f 62 69 6e 64 5f 76 61 6c  sqlite3_bind_val
7210: 75 65 28 70 53 74 6d 74 2c 20 69 2c 20 61 70 44  ue(pStmt, i, apD
7220: 61 74 61 5b 69 5d 29 3b 0a 20 20 20 20 7d 0a 20  ata[i]);.    }. 
7230: 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54     if( rc==SQLIT
7240: 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 73 71  E_OK ){.      sq
7250: 6c 69 74 65 33 5f 73 74 65 70 28 70 53 74 6d 74  lite3_step(pStmt
7260: 29 3b 0a 20 20 20 20 20 20 72 63 20 3d 20 73 71  );.      rc = sq
7270: 6c 69 74 65 33 5f 66 69 6e 61 6c 69 7a 65 28 70  lite3_finalize(p
7280: 53 74 6d 74 29 3b 0a 20 20 20 20 7d 65 6c 73 65  Stmt);.    }else
7290: 7b 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f  {.      sqlite3_
72a0: 66 69 6e 61 6c 69 7a 65 28 70 53 74 6d 74 29 3b  finalize(pStmt);
72b0: 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 69 66  .    }.  }..  if
72c0: 28 20 70 52 6f 77 69 64 20 26 26 20 72 63 3d 3d  ( pRowid && rc==
72d0: 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20  SQLITE_OK ){.   
72e0: 20 2a 70 52 6f 77 69 64 20 3d 20 73 71 6c 69 74   *pRowid = sqlit
72f0: 65 33 5f 6c 61 73 74 5f 69 6e 73 65 72 74 5f 72  e3_last_insert_r
7300: 6f 77 69 64 28 64 62 29 3b 0a 20 20 7d 0a 20 20  owid(db);.  }.  
7310: 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f  if( rc!=SQLITE_O
7320: 4b 20 29 7b 0a 20 20 20 20 74 61 62 2d 3e 7a 45  K ){.    tab->zE
7330: 72 72 4d 73 67 20 3d 20 73 71 6c 69 74 65 33 5f  rrMsg = sqlite3_
7340: 6d 70 72 69 6e 74 66 28 22 65 63 68 6f 2d 76 74  mprintf("echo-vt
7350: 61 62 2d 65 72 72 6f 72 3a 20 25 73 22 2c 20 73  ab-error: %s", s
7360: 71 6c 69 74 65 33 5f 65 72 72 6d 73 67 28 64 62  qlite3_errmsg(db
7370: 29 29 3b 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72  ));.  }..  retur
7380: 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 78  n rc;.}../*.** x
7390: 42 65 67 69 6e 2c 20 78 53 79 6e 63 2c 20 78 43  Begin, xSync, xC
73a0: 6f 6d 6d 69 74 20 61 6e 64 20 78 52 6f 6c 6c 62  ommit and xRollb
73b0: 61 63 6b 20 63 61 6c 6c 62 61 63 6b 73 20 66 6f  ack callbacks fo
73c0: 72 20 65 63 68 6f 20 6d 6f 64 75 6c 65 0a 2a 2a  r echo module.**
73d0: 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65 73 2e   virtual tables.
73e0: 20 44 6f 20 6e 6f 74 68 69 6e 67 20 6f 74 68 65   Do nothing othe
73f0: 72 20 74 68 61 6e 20 61 64 64 20 74 68 65 20 6e  r than add the n
7400: 61 6d 65 20 6f 66 20 74 68 65 20 63 61 6c 6c 62  ame of the callb
7410: 61 63 6b 0a 2a 2a 20 74 6f 20 74 68 65 20 24 3a  ack.** to the $:
7420: 3a 65 63 68 6f 5f 6d 6f 64 75 6c 65 20 54 63 6c  :echo_module Tcl
7430: 20 76 61 72 69 61 62 6c 65 2e 0a 2a 2f 0a 73 74   variable..*/.st
7440: 61 74 69 63 20 69 6e 74 20 65 63 68 6f 54 72 61  atic int echoTra
7450: 6e 73 61 63 74 69 6f 6e 43 61 6c 6c 28 73 71 6c  nsactionCall(sql
7460: 69 74 65 33 5f 76 74 61 62 20 2a 74 61 62 2c 20  ite3_vtab *tab, 
7470: 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 43 61 6c  const char *zCal
7480: 6c 29 7b 0a 20 20 63 68 61 72 20 2a 7a 3b 0a 20  l){.  char *z;. 
7490: 20 65 63 68 6f 5f 76 74 61 62 20 2a 70 56 74 61   echo_vtab *pVta
74a0: 62 20 3d 20 28 65 63 68 6f 5f 76 74 61 62 20 2a  b = (echo_vtab *
74b0: 29 74 61 62 3b 0a 20 20 7a 20 3d 20 73 71 6c 69  )tab;.  z = sqli
74c0: 74 65 33 5f 6d 70 72 69 6e 74 66 28 22 65 63 68  te3_mprintf("ech
74d0: 6f 28 25 73 29 22 2c 20 70 56 74 61 62 2d 3e 7a  o(%s)", pVtab->z
74e0: 54 61 62 6c 65 4e 61 6d 65 29 3b 0a 20 20 69 66  TableName);.  if
74f0: 28 20 7a 3d 3d 30 20 29 20 72 65 74 75 72 6e 20  ( z==0 ) return 
7500: 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20  SQLITE_NOMEM;.  
7510: 61 70 70 65 6e 64 54 6f 45 63 68 6f 4d 6f 64 75  appendToEchoModu
7520: 6c 65 28 70 56 74 61 62 2d 3e 69 6e 74 65 72 70  le(pVtab->interp
7530: 2c 20 7a 43 61 6c 6c 29 3b 0a 20 20 61 70 70 65  , zCall);.  appe
7540: 6e 64 54 6f 45 63 68 6f 4d 6f 64 75 6c 65 28 70  ndToEchoModule(p
7550: 56 74 61 62 2d 3e 69 6e 74 65 72 70 2c 20 7a 29  Vtab->interp, z)
7560: 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65  ;.  sqlite3_free
7570: 28 7a 29 3b 0a 20 20 72 65 74 75 72 6e 20 53 51  (z);.  return SQ
7580: 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 73 74 61 74 69  LITE_OK;.}.stati
7590: 63 20 69 6e 74 20 65 63 68 6f 42 65 67 69 6e 28  c int echoBegin(
75a0: 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 74 61  sqlite3_vtab *ta
75b0: 62 29 7b 0a 20 20 69 6e 74 20 72 63 3b 0a 20 20  b){.  int rc;.  
75c0: 65 63 68 6f 5f 76 74 61 62 20 2a 70 56 74 61 62  echo_vtab *pVtab
75d0: 20 3d 20 28 65 63 68 6f 5f 76 74 61 62 20 2a 29   = (echo_vtab *)
75e0: 74 61 62 3b 0a 20 20 54 63 6c 5f 49 6e 74 65 72  tab;.  Tcl_Inter
75f0: 70 20 2a 69 6e 74 65 72 70 20 3d 20 70 56 74 61  p *interp = pVta
7600: 62 2d 3e 69 6e 74 65 72 70 3b 0a 20 20 63 6f 6e  b->interp;.  con
7610: 73 74 20 63 68 61 72 20 2a 7a 56 61 6c 3b 20 0a  st char *zVal; .
7620: 0a 20 20 2f 2a 20 54 69 63 6b 65 74 20 23 33 30  .  /* Ticket #30
7630: 38 33 20 2d 20 64 6f 20 6e 6f 74 20 73 74 61 72  83 - do not star
7640: 74 20 61 20 74 72 61 6e 73 61 63 74 69 6f 6e 20  t a transaction 
7650: 69 66 20 77 65 20 61 72 65 20 61 6c 72 65 61 64  if we are alread
7660: 79 20 69 6e 0a 20 20 2a 2a 20 61 20 74 72 61 6e  y in.  ** a tran
7670: 73 61 63 74 69 6f 6e 20 2a 2f 0a 20 20 61 73 73  saction */.  ass
7680: 65 72 74 28 20 21 70 56 74 61 62 2d 3e 69 6e 54  ert( !pVtab->inT
7690: 72 61 6e 73 61 63 74 69 6f 6e 20 29 3b 0a 0a 20  ransaction );.. 
76a0: 20 69 66 28 20 73 69 6d 75 6c 61 74 65 56 74 61   if( simulateVta
76b0: 62 45 72 72 6f 72 28 70 56 74 61 62 2c 20 22 78  bError(pVtab, "x
76c0: 42 65 67 69 6e 22 29 20 29 7b 0a 20 20 20 20 72  Begin") ){.    r
76d0: 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 45 52 52  eturn SQLITE_ERR
76e0: 4f 52 3b 0a 20 20 7d 0a 0a 20 20 72 63 20 3d 20  OR;.  }..  rc = 
76f0: 65 63 68 6f 54 72 61 6e 73 61 63 74 69 6f 6e 43  echoTransactionC
7700: 61 6c 6c 28 74 61 62 2c 20 22 78 42 65 67 69 6e  all(tab, "xBegin
7710: 22 29 3b 0a 0a 20 20 69 66 28 20 72 63 3d 3d 53  ");..  if( rc==S
7720: 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
7730: 2f 2a 20 43 68 65 63 6b 20 69 66 20 74 68 65 20  /* Check if the 
7740: 24 3a 3a 65 63 68 6f 5f 6d 6f 64 75 6c 65 5f 62  $::echo_module_b
7750: 65 67 69 6e 5f 66 61 69 6c 20 76 61 72 69 61 62  egin_fail variab
7760: 6c 65 20 69 73 20 64 65 66 69 6e 65 64 2e 20 49  le is defined. I
7770: 66 20 69 74 20 69 73 2c 0a 20 20 20 20 2a 2a 20  f it is,.    ** 
7780: 61 6e 64 20 69 74 20 69 73 20 73 65 74 20 74 6f  and it is set to
7790: 20 74 68 65 20 6e 61 6d 65 20 6f 66 20 74 68 65   the name of the
77a0: 20 72 65 61 6c 20 74 61 62 6c 65 20 75 6e 64 65   real table unde
77b0: 72 6c 79 69 6e 67 20 74 68 69 73 20 76 69 72 74  rlying this virt
77c0: 75 61 6c 0a 20 20 20 20 2a 2a 20 65 63 68 6f 20  ual.    ** echo 
77d0: 6d 6f 64 75 6c 65 20 74 61 62 6c 65 2c 20 74 68  module table, th
77e0: 65 6e 20 63 61 75 73 65 20 74 68 69 73 20 78 53  en cause this xS
77f0: 79 6e 63 20 6f 70 65 72 61 74 69 6f 6e 20 74 6f  ync operation to
7800: 20 66 61 69 6c 2e 0a 20 20 20 20 2a 2f 0a 20 20   fail..    */.  
7810: 20 20 7a 56 61 6c 20 3d 20 54 63 6c 5f 47 65 74    zVal = Tcl_Get
7820: 56 61 72 28 69 6e 74 65 72 70 2c 20 22 65 63 68  Var(interp, "ech
7830: 6f 5f 6d 6f 64 75 6c 65 5f 62 65 67 69 6e 5f 66  o_module_begin_f
7840: 61 69 6c 22 2c 20 54 43 4c 5f 47 4c 4f 42 41 4c  ail", TCL_GLOBAL
7850: 5f 4f 4e 4c 59 29 3b 0a 20 20 20 20 69 66 28 20  _ONLY);.    if( 
7860: 7a 56 61 6c 20 26 26 20 30 3d 3d 73 74 72 63 6d  zVal && 0==strcm
7870: 70 28 7a 56 61 6c 2c 20 70 56 74 61 62 2d 3e 7a  p(zVal, pVtab->z
7880: 54 61 62 6c 65 4e 61 6d 65 29 20 29 7b 0a 20 20  TableName) ){.  
7890: 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f      rc = SQLITE_
78a0: 45 52 52 4f 52 3b 0a 20 20 20 20 7d 0a 20 20 7d  ERROR;.    }.  }
78b0: 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54  .  if( rc==SQLIT
78c0: 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 70 56 74 61  E_OK ){.    pVta
78d0: 62 2d 3e 69 6e 54 72 61 6e 73 61 63 74 69 6f 6e  b->inTransaction
78e0: 20 3d 20 31 3b 0a 20 20 7d 0a 20 20 72 65 74 75   = 1;.  }.  retu
78f0: 72 6e 20 72 63 3b 0a 7d 0a 73 74 61 74 69 63 20  rn rc;.}.static 
7900: 69 6e 74 20 65 63 68 6f 53 79 6e 63 28 73 71 6c  int echoSync(sql
7910: 69 74 65 33 5f 76 74 61 62 20 2a 74 61 62 29 7b  ite3_vtab *tab){
7920: 0a 20 20 69 6e 74 20 72 63 3b 0a 20 20 65 63 68  .  int rc;.  ech
7930: 6f 5f 76 74 61 62 20 2a 70 56 74 61 62 20 3d 20  o_vtab *pVtab = 
7940: 28 65 63 68 6f 5f 76 74 61 62 20 2a 29 74 61 62  (echo_vtab *)tab
7950: 3b 0a 20 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a  ;.  Tcl_Interp *
7960: 69 6e 74 65 72 70 20 3d 20 70 56 74 61 62 2d 3e  interp = pVtab->
7970: 69 6e 74 65 72 70 3b 0a 20 20 63 6f 6e 73 74 20  interp;.  const 
7980: 63 68 61 72 20 2a 7a 56 61 6c 3b 20 0a 0a 20 20  char *zVal; ..  
7990: 2f 2a 20 54 69 63 6b 65 74 20 23 33 30 38 33 20  /* Ticket #3083 
79a0: 2d 20 4f 6e 6c 79 20 63 61 6c 6c 20 78 53 79 6e  - Only call xSyn
79b0: 63 20 69 66 20 77 65 20 68 61 76 65 20 70 72 65  c if we have pre
79c0: 76 69 6f 75 73 6c 79 20 73 74 61 72 74 65 64 20  viously started 
79d0: 61 0a 20 20 2a 2a 20 74 72 61 6e 73 61 63 74 69  a.  ** transacti
79e0: 6f 6e 20 2a 2f 0a 20 20 61 73 73 65 72 74 28 20  on */.  assert( 
79f0: 70 56 74 61 62 2d 3e 69 6e 54 72 61 6e 73 61 63  pVtab->inTransac
7a00: 74 69 6f 6e 20 29 3b 0a 0a 20 20 69 66 28 20 73  tion );..  if( s
7a10: 69 6d 75 6c 61 74 65 56 74 61 62 45 72 72 6f 72  imulateVtabError
7a20: 28 70 56 74 61 62 2c 20 22 78 53 79 6e 63 22 29  (pVtab, "xSync")
7a30: 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 53   ){.    return S
7a40: 51 4c 49 54 45 5f 45 52 52 4f 52 3b 0a 20 20 7d  QLITE_ERROR;.  }
7a50: 0a 0a 20 20 72 63 20 3d 20 65 63 68 6f 54 72 61  ..  rc = echoTra
7a60: 6e 73 61 63 74 69 6f 6e 43 61 6c 6c 28 74 61 62  nsactionCall(tab
7a70: 2c 20 22 78 53 79 6e 63 22 29 3b 0a 0a 20 20 69  , "xSync");..  i
7a80: 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc==SQLITE_OK
7a90: 20 29 7b 0a 20 20 20 20 2f 2a 20 43 68 65 63 6b   ){.    /* Check
7aa0: 20 69 66 20 74 68 65 20 24 3a 3a 65 63 68 6f 5f   if the $::echo_
7ab0: 6d 6f 64 75 6c 65 5f 73 79 6e 63 5f 66 61 69 6c  module_sync_fail
7ac0: 20 76 61 72 69 61 62 6c 65 20 69 73 20 64 65 66   variable is def
7ad0: 69 6e 65 64 2e 20 49 66 20 69 74 20 69 73 2c 0a  ined. If it is,.
7ae0: 20 20 20 20 2a 2a 20 61 6e 64 20 69 74 20 69 73      ** and it is
7af0: 20 73 65 74 20 74 6f 20 74 68 65 20 6e 61 6d 65   set to the name
7b00: 20 6f 66 20 74 68 65 20 72 65 61 6c 20 74 61 62   of the real tab
7b10: 6c 65 20 75 6e 64 65 72 6c 79 69 6e 67 20 74 68  le underlying th
7b20: 69 73 20 76 69 72 74 75 61 6c 0a 20 20 20 20 2a  is virtual.    *
7b30: 2a 20 65 63 68 6f 20 6d 6f 64 75 6c 65 20 74 61  * echo module ta
7b40: 62 6c 65 2c 20 74 68 65 6e 20 63 61 75 73 65 20  ble, then cause 
7b50: 74 68 69 73 20 78 53 79 6e 63 20 6f 70 65 72 61  this xSync opera
7b60: 74 69 6f 6e 20 74 6f 20 66 61 69 6c 2e 0a 20 20  tion to fail..  
7b70: 20 20 2a 2f 0a 20 20 20 20 7a 56 61 6c 20 3d 20    */.    zVal = 
7b80: 54 63 6c 5f 47 65 74 56 61 72 28 69 6e 74 65 72  Tcl_GetVar(inter
7b90: 70 2c 20 22 65 63 68 6f 5f 6d 6f 64 75 6c 65 5f  p, "echo_module_
7ba0: 73 79 6e 63 5f 66 61 69 6c 22 2c 20 54 43 4c 5f  sync_fail", TCL_
7bb0: 47 4c 4f 42 41 4c 5f 4f 4e 4c 59 29 3b 0a 20 20  GLOBAL_ONLY);.  
7bc0: 20 20 69 66 28 20 7a 56 61 6c 20 26 26 20 30 3d    if( zVal && 0=
7bd0: 3d 73 74 72 63 6d 70 28 7a 56 61 6c 2c 20 70 56  =strcmp(zVal, pV
7be0: 74 61 62 2d 3e 7a 54 61 62 6c 65 4e 61 6d 65 29  tab->zTableName)
7bf0: 20 29 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 2d   ){.      rc = -
7c00: 31 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 72  1;.    }.  }.  r
7c10: 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 73 74 61 74  eturn rc;.}.stat
7c20: 69 63 20 69 6e 74 20 65 63 68 6f 43 6f 6d 6d 69  ic int echoCommi
7c30: 74 28 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a  t(sqlite3_vtab *
7c40: 74 61 62 29 7b 0a 20 20 65 63 68 6f 5f 76 74 61  tab){.  echo_vta
7c50: 62 20 2a 70 56 74 61 62 20 3d 20 28 65 63 68 6f  b *pVtab = (echo
7c60: 5f 76 74 61 62 2a 29 74 61 62 3b 0a 20 20 69 6e  _vtab*)tab;.  in
7c70: 74 20 72 63 3b 0a 0a 20 20 2f 2a 20 54 69 63 6b  t rc;..  /* Tick
7c80: 65 74 20 23 33 30 38 33 20 2d 20 4f 6e 6c 79 20  et #3083 - Only 
7c90: 63 61 6c 6c 20 78 43 6f 6d 6d 69 74 20 69 66 20  call xCommit if 
7ca0: 77 65 20 68 61 76 65 20 70 72 65 76 69 6f 75 73  we have previous
7cb0: 6c 79 20 73 74 61 72 74 65 64 0a 20 20 2a 2a 20  ly started.  ** 
7cc0: 61 20 74 72 61 6e 73 61 63 74 69 6f 6e 20 2a 2f  a transaction */
7cd0: 0a 20 20 61 73 73 65 72 74 28 20 70 56 74 61 62  .  assert( pVtab
7ce0: 2d 3e 69 6e 54 72 61 6e 73 61 63 74 69 6f 6e 20  ->inTransaction 
7cf0: 29 3b 0a 0a 20 20 69 66 28 20 73 69 6d 75 6c 61  );..  if( simula
7d00: 74 65 56 74 61 62 45 72 72 6f 72 28 70 56 74 61  teVtabError(pVta
7d10: 62 2c 20 22 78 43 6f 6d 6d 69 74 22 29 20 29 7b  b, "xCommit") ){
7d20: 0a 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49  .    return SQLI
7d30: 54 45 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a 0a 20  TE_ERROR;.  }.. 
7d40: 20 73 71 6c 69 74 65 33 42 65 67 69 6e 42 65 6e   sqlite3BeginBen
7d50: 69 67 6e 4d 61 6c 6c 6f 63 28 29 3b 0a 20 20 72  ignMalloc();.  r
7d60: 63 20 3d 20 65 63 68 6f 54 72 61 6e 73 61 63 74  c = echoTransact
7d70: 69 6f 6e 43 61 6c 6c 28 74 61 62 2c 20 22 78 43  ionCall(tab, "xC
7d80: 6f 6d 6d 69 74 22 29 3b 0a 20 20 73 71 6c 69 74  ommit");.  sqlit
7d90: 65 33 45 6e 64 42 65 6e 69 67 6e 4d 61 6c 6c 6f  e3EndBenignMallo
7da0: 63 28 29 3b 0a 20 20 70 56 74 61 62 2d 3e 69 6e  c();.  pVtab->in
7db0: 54 72 61 6e 73 61 63 74 69 6f 6e 20 3d 20 30 3b  Transaction = 0;
7dc0: 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a  .  return rc;.}.
7dd0: 73 74 61 74 69 63 20 69 6e 74 20 65 63 68 6f 52  static int echoR
7de0: 6f 6c 6c 62 61 63 6b 28 73 71 6c 69 74 65 33 5f  ollback(sqlite3_
7df0: 76 74 61 62 20 2a 74 61 62 29 7b 0a 20 20 69 6e  vtab *tab){.  in
7e00: 74 20 72 63 3b 0a 20 20 65 63 68 6f 5f 76 74 61  t rc;.  echo_vta
7e10: 62 20 2a 70 56 74 61 62 20 3d 20 28 65 63 68 6f  b *pVtab = (echo
7e20: 5f 76 74 61 62 2a 29 74 61 62 3b 0a 0a 20 20 2f  _vtab*)tab;..  /
7e30: 2a 20 54 69 63 6b 65 74 20 23 33 30 38 33 20 2d  * Ticket #3083 -
7e40: 20 4f 6e 6c 79 20 63 61 6c 6c 20 78 52 6f 6c 6c   Only call xRoll
7e50: 62 61 63 6b 20 69 66 20 77 65 20 68 61 76 65 20  back if we have 
7e60: 70 72 65 76 69 6f 75 73 6c 79 20 73 74 61 72 74  previously start
7e70: 65 64 0a 20 20 2a 2a 20 61 20 74 72 61 6e 73 61  ed.  ** a transa
7e80: 63 74 69 6f 6e 20 2a 2f 0a 20 20 61 73 73 65 72  ction */.  asser
7e90: 74 28 20 70 56 74 61 62 2d 3e 69 6e 54 72 61 6e  t( pVtab->inTran
7ea0: 73 61 63 74 69 6f 6e 20 29 3b 0a 0a 20 20 72 63  saction );..  rc
7eb0: 20 3d 20 65 63 68 6f 54 72 61 6e 73 61 63 74 69   = echoTransacti
7ec0: 6f 6e 43 61 6c 6c 28 74 61 62 2c 20 22 78 52 6f  onCall(tab, "xRo
7ed0: 6c 6c 62 61 63 6b 22 29 3b 0a 20 20 70 56 74 61  llback");.  pVta
7ee0: 62 2d 3e 69 6e 54 72 61 6e 73 61 63 74 69 6f 6e  b->inTransaction
7ef0: 20 3d 20 30 3b 0a 20 20 72 65 74 75 72 6e 20 72   = 0;.  return r
7f00: 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c  c;.}../*.** Impl
7f10: 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66 20 22 47  ementation of "G
7f20: 4c 4f 42 22 20 66 75 6e 63 74 69 6f 6e 20 6f 6e  LOB" function on
7f30: 20 74 68 65 20 65 63 68 6f 20 6d 6f 64 75 6c 65   the echo module
7f40: 2e 20 20 50 61 73 73 0a 2a 2a 20 61 6c 6c 20 61  .  Pass.** all a
7f50: 72 67 75 6d 65 6e 74 73 20 74 6f 20 74 68 65 20  rguments to the 
7f60: 3a 3a 65 63 68 6f 5f 67 6c 6f 62 5f 6f 76 65 72  ::echo_glob_over
7f70: 6c 6f 61 64 20 70 72 6f 63 65 64 75 72 65 20 6f  load procedure o
7f80: 66 20 54 43 4c 0a 2a 2a 20 61 6e 64 20 72 65 74  f TCL.** and ret
7f90: 75 72 6e 20 74 68 65 20 72 65 73 75 6c 74 20 6f  urn the result o
7fa0: 66 20 74 68 61 74 20 70 72 6f 63 65 64 75 72 65  f that procedure
7fb0: 20 61 73 20 61 20 73 74 72 69 6e 67 2e 0a 2a 2f   as a string..*/
7fc0: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 6f 76 65  .static void ove
7fd0: 72 6c 6f 61 64 65 64 47 6c 6f 62 46 75 6e 63 74  rloadedGlobFunct
7fe0: 69 6f 6e 28 0a 20 20 73 71 6c 69 74 65 33 5f 63  ion(.  sqlite3_c
7ff0: 6f 6e 74 65 78 74 20 2a 70 43 6f 6e 74 65 78 74  ontext *pContext
8000: 2c 0a 20 20 69 6e 74 20 6e 41 72 67 2c 0a 20 20  ,.  int nArg,.  
8010: 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 20 2a 2a  sqlite3_value **
8020: 61 70 41 72 67 0a 29 7b 0a 20 20 54 63 6c 5f 49  apArg.){.  Tcl_I
8030: 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 20 3d 20  nterp *interp = 
8040: 73 71 6c 69 74 65 33 5f 75 73 65 72 5f 64 61 74  sqlite3_user_dat
8050: 61 28 70 43 6f 6e 74 65 78 74 29 3b 0a 20 20 54  a(pContext);.  T
8060: 63 6c 5f 44 53 74 72 69 6e 67 20 73 74 72 3b 0a  cl_DString str;.
8070: 20 20 69 6e 74 20 69 3b 0a 20 20 69 6e 74 20 72    int i;.  int r
8080: 63 3b 0a 20 20 54 63 6c 5f 44 53 74 72 69 6e 67  c;.  Tcl_DString
8090: 49 6e 69 74 28 26 73 74 72 29 3b 0a 20 20 54 63  Init(&str);.  Tc
80a0: 6c 5f 44 53 74 72 69 6e 67 41 70 70 65 6e 64 45  l_DStringAppendE
80b0: 6c 65 6d 65 6e 74 28 26 73 74 72 2c 20 22 3a 3a  lement(&str, "::
80c0: 65 63 68 6f 5f 67 6c 6f 62 5f 6f 76 65 72 6c 6f  echo_glob_overlo
80d0: 61 64 22 29 3b 0a 20 20 66 6f 72 28 69 3d 30 3b  ad");.  for(i=0;
80e0: 20 69 3c 6e 41 72 67 3b 20 69 2b 2b 29 7b 0a 20   i<nArg; i++){. 
80f0: 20 20 20 54 63 6c 5f 44 53 74 72 69 6e 67 41 70     Tcl_DStringAp
8100: 70 65 6e 64 45 6c 65 6d 65 6e 74 28 26 73 74 72  pendElement(&str
8110: 2c 20 28 63 68 61 72 2a 29 73 71 6c 69 74 65 33  , (char*)sqlite3
8120: 5f 76 61 6c 75 65 5f 74 65 78 74 28 61 70 41 72  _value_text(apAr
8130: 67 5b 69 5d 29 29 3b 0a 20 20 7d 0a 20 20 72 63  g[i]));.  }.  rc
8140: 20 3d 20 54 63 6c 5f 45 76 61 6c 28 69 6e 74 65   = Tcl_Eval(inte
8150: 72 70 2c 20 54 63 6c 5f 44 53 74 72 69 6e 67 56  rp, Tcl_DStringV
8160: 61 6c 75 65 28 26 73 74 72 29 29 3b 0a 20 20 54  alue(&str));.  T
8170: 63 6c 5f 44 53 74 72 69 6e 67 46 72 65 65 28 26  cl_DStringFree(&
8180: 73 74 72 29 3b 0a 20 20 69 66 28 20 72 63 20 29  str);.  if( rc )
8190: 7b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 72 65  {.    sqlite3_re
81a0: 73 75 6c 74 5f 65 72 72 6f 72 28 70 43 6f 6e 74  sult_error(pCont
81b0: 65 78 74 2c 20 54 63 6c 5f 47 65 74 53 74 72 69  ext, Tcl_GetStri
81c0: 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29  ngResult(interp)
81d0: 2c 20 2d 31 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a  , -1);.  }else{.
81e0: 20 20 20 20 73 71 6c 69 74 65 33 5f 72 65 73 75      sqlite3_resu
81f0: 6c 74 5f 74 65 78 74 28 70 43 6f 6e 74 65 78 74  lt_text(pContext
8200: 2c 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 52  , Tcl_GetStringR
8210: 65 73 75 6c 74 28 69 6e 74 65 72 70 29 2c 0a 20  esult(interp),. 
8220: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8230: 20 20 20 20 20 20 20 2d 31 2c 20 53 51 4c 49 54         -1, SQLIT
8240: 45 5f 54 52 41 4e 53 49 45 4e 54 29 3b 0a 20 20  E_TRANSIENT);.  
8250: 7d 0a 20 20 54 63 6c 5f 52 65 73 65 74 52 65 73  }.  Tcl_ResetRes
8260: 75 6c 74 28 69 6e 74 65 72 70 29 3b 0a 7d 0a 0a  ult(interp);.}..
8270: 2f 2a 0a 2a 2a 20 54 68 69 73 20 69 73 20 74 68  /*.** This is th
8280: 65 20 78 46 69 6e 64 46 75 6e 63 74 69 6f 6e 20  e xFindFunction 
8290: 69 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 66  implementation f
82a0: 6f 72 20 74 68 65 20 65 63 68 6f 20 6d 6f 64 75  or the echo modu
82b0: 6c 65 2e 0a 2a 2a 20 53 51 4c 69 74 65 20 63 61  le..** SQLite ca
82c0: 6c 6c 73 20 74 68 69 73 20 72 6f 75 74 69 6e 65  lls this routine
82d0: 20 77 68 65 6e 20 74 68 65 20 66 69 72 73 74 20   when the first 
82e0: 61 72 67 75 6d 65 6e 74 20 6f 66 20 61 20 66 75  argument of a fu
82f0: 6e 63 74 69 6f 6e 0a 2a 2a 20 69 73 20 61 20 63  nction.** is a c
8300: 6f 6c 75 6d 6e 20 6f 66 20 61 6e 20 65 63 68 6f  olumn of an echo
8310: 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65 2e 20   virtual table. 
8320: 20 54 68 69 73 20 72 6f 75 74 69 6e 65 20 63 61   This routine ca
8330: 6e 20 6f 70 74 69 6f 6e 61 6c 6c 79 0a 2a 2a 20  n optionally.** 
8340: 6f 76 65 72 72 69 64 65 20 74 68 65 20 69 6d 70  override the imp
8350: 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66 20 74  lementation of t
8360: 68 61 74 20 66 75 6e 63 74 69 6f 6e 2e 20 20 49  hat function.  I
8370: 74 20 77 69 6c 6c 20 63 68 6f 6f 73 65 20 74 6f  t will choose to
8380: 0a 2a 2a 20 64 6f 20 73 6f 20 69 66 20 74 68 65  .** do so if the
8390: 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 6e 61 6d   function is nam
83a0: 65 64 20 22 67 6c 6f 62 22 2c 20 61 6e 64 20 61  ed "glob", and a
83b0: 20 54 43 4c 20 63 6f 6d 6d 61 6e 64 20 6e 61 6d   TCL command nam
83c0: 65 64 0a 2a 2a 20 3a 3a 65 63 68 6f 5f 67 6c 6f  ed.** ::echo_glo
83d0: 62 5f 6f 76 65 72 6c 6f 61 64 20 65 78 69 73 74  b_overload exist
83e0: 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  s..*/.static int
83f0: 20 65 63 68 6f 46 69 6e 64 46 75 6e 63 74 69 6f   echoFindFunctio
8400: 6e 28 0a 20 20 73 71 6c 69 74 65 33 5f 76 74 61  n(.  sqlite3_vta
8410: 62 20 2a 76 74 61 62 2c 0a 20 20 69 6e 74 20 6e  b *vtab,.  int n
8420: 41 72 67 2c 0a 20 20 63 6f 6e 73 74 20 63 68 61  Arg,.  const cha
8430: 72 20 2a 7a 46 75 6e 63 4e 61 6d 65 2c 0a 20 20  r *zFuncName,.  
8440: 76 6f 69 64 20 28 2a 2a 70 78 46 75 6e 63 29 28  void (**pxFunc)(
8450: 73 71 6c 69 74 65 33 5f 63 6f 6e 74 65 78 74 2a  sqlite3_context*
8460: 2c 69 6e 74 2c 73 71 6c 69 74 65 33 5f 76 61 6c  ,int,sqlite3_val
8470: 75 65 2a 2a 29 2c 0a 20 20 76 6f 69 64 20 2a 2a  ue**),.  void **
8480: 70 70 41 72 67 0a 29 7b 0a 20 20 65 63 68 6f 5f  ppArg.){.  echo_
8490: 76 74 61 62 20 2a 70 56 74 61 62 20 3d 20 28 65  vtab *pVtab = (e
84a0: 63 68 6f 5f 76 74 61 62 20 2a 29 76 74 61 62 3b  cho_vtab *)vtab;
84b0: 0a 20 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69  .  Tcl_Interp *i
84c0: 6e 74 65 72 70 20 3d 20 70 56 74 61 62 2d 3e 69  nterp = pVtab->i
84d0: 6e 74 65 72 70 3b 0a 20 20 54 63 6c 5f 43 6d 64  nterp;.  Tcl_Cmd
84e0: 49 6e 66 6f 20 69 6e 66 6f 3b 0a 20 20 69 66 28  Info info;.  if(
84f0: 20 73 74 72 63 6d 70 28 7a 46 75 6e 63 4e 61 6d   strcmp(zFuncNam
8500: 65 2c 22 67 6c 6f 62 22 29 21 3d 30 20 29 7b 0a  e,"glob")!=0 ){.
8510: 20 20 20 20 72 65 74 75 72 6e 20 30 3b 0a 20 20      return 0;.  
8520: 7d 0a 20 20 69 66 28 20 54 63 6c 5f 47 65 74 43  }.  if( Tcl_GetC
8530: 6f 6d 6d 61 6e 64 49 6e 66 6f 28 69 6e 74 65 72  ommandInfo(inter
8540: 70 2c 20 22 3a 3a 65 63 68 6f 5f 67 6c 6f 62 5f  p, "::echo_glob_
8550: 6f 76 65 72 6c 6f 61 64 22 2c 20 26 69 6e 66 6f  overload", &info
8560: 29 3d 3d 30 20 29 7b 0a 20 20 20 20 72 65 74 75  )==0 ){.    retu
8570: 72 6e 20 30 3b 0a 20 20 7d 0a 20 20 2a 70 78 46  rn 0;.  }.  *pxF
8580: 75 6e 63 20 3d 20 6f 76 65 72 6c 6f 61 64 65 64  unc = overloaded
8590: 47 6c 6f 62 46 75 6e 63 74 69 6f 6e 3b 0a 20 20  GlobFunction;.  
85a0: 2a 70 70 41 72 67 20 3d 20 69 6e 74 65 72 70 3b  *ppArg = interp;
85b0: 0a 20 20 72 65 74 75 72 6e 20 31 3b 0a 7d 0a 0a  .  return 1;.}..
85c0: 73 74 61 74 69 63 20 69 6e 74 20 65 63 68 6f 52  static int echoR
85d0: 65 6e 61 6d 65 28 73 71 6c 69 74 65 33 5f 76 74  ename(sqlite3_vt
85e0: 61 62 20 2a 76 74 61 62 2c 20 63 6f 6e 73 74 20  ab *vtab, const 
85f0: 63 68 61 72 20 2a 7a 4e 65 77 4e 61 6d 65 29 7b  char *zNewName){
8600: 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49  .  int rc = SQLI
8610: 54 45 5f 4f 4b 3b 0a 20 20 65 63 68 6f 5f 76 74  TE_OK;.  echo_vt
8620: 61 62 20 2a 70 20 3d 20 28 65 63 68 6f 5f 76 74  ab *p = (echo_vt
8630: 61 62 20 2a 29 76 74 61 62 3b 0a 0a 20 20 69 66  ab *)vtab;..  if
8640: 28 20 73 69 6d 75 6c 61 74 65 56 74 61 62 45 72  ( simulateVtabEr
8650: 72 6f 72 28 70 2c 20 22 78 52 65 6e 61 6d 65 22  ror(p, "xRename"
8660: 29 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20  ) ){.    return 
8670: 53 51 4c 49 54 45 5f 45 52 52 4f 52 3b 0a 20 20  SQLITE_ERROR;.  
8680: 7d 0a 0a 20 20 69 66 28 20 70 2d 3e 69 73 50 61  }..  if( p->isPa
8690: 74 74 65 72 6e 20 29 7b 0a 20 20 20 20 69 6e 74  ttern ){.    int
86a0: 20 6e 54 68 69 73 20 3d 20 73 74 72 6c 65 6e 28   nThis = strlen(
86b0: 70 2d 3e 7a 54 68 69 73 29 3b 0a 20 20 20 20 63  p->zThis);.    c
86c0: 68 61 72 20 2a 7a 53 71 6c 20 3d 20 73 71 6c 69  har *zSql = sqli
86d0: 74 65 33 4d 50 72 69 6e 74 66 28 30 2c 20 22 41  te3MPrintf(0, "A
86e0: 4c 54 45 52 20 54 41 42 4c 45 20 25 73 20 52 45  LTER TABLE %s RE
86f0: 4e 41 4d 45 20 54 4f 20 25 73 25 73 22 2c 20 0a  NAME TO %s%s", .
8700: 20 20 20 20 20 20 20 20 70 2d 3e 7a 54 61 62 6c          p->zTabl
8710: 65 4e 61 6d 65 2c 20 7a 4e 65 77 4e 61 6d 65 2c  eName, zNewName,
8720: 20 26 70 2d 3e 7a 54 61 62 6c 65 4e 61 6d 65 5b   &p->zTableName[
8730: 6e 54 68 69 73 5d 0a 20 20 20 20 29 3b 0a 20 20  nThis].    );.  
8740: 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 65    rc = sqlite3_e
8750: 78 65 63 28 70 2d 3e 64 62 2c 20 7a 53 71 6c 2c  xec(p->db, zSql,
8760: 20 30 2c 20 30 2c 20 30 29 3b 0a 20 20 20 20 73   0, 0, 0);.    s
8770: 71 6c 69 74 65 33 5f 66 72 65 65 28 7a 53 71 6c  qlite3_free(zSql
8780: 29 3b 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e  );.  }..  return
8790: 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41 20   rc;.}../*.** A 
87a0: 76 69 72 74 75 61 6c 20 74 61 62 6c 65 20 6d 6f  virtual table mo
87b0: 64 75 6c 65 20 74 68 61 74 20 6d 65 72 65 6c 79  dule that merely
87c0: 20 22 65 63 68 6f 73 22 20 74 68 65 20 63 6f 6e   "echos" the con
87d0: 74 65 6e 74 73 20 6f 66 20 61 6e 6f 74 68 65 72  tents of another
87e0: 0a 2a 2a 20 74 61 62 6c 65 20 28 6c 69 6b 65 20  .** table (like 
87f0: 61 6e 20 53 51 4c 20 56 49 45 57 29 2e 0a 2a 2f  an SQL VIEW)..*/
8800: 0a 73 74 61 74 69 63 20 73 71 6c 69 74 65 33 5f  .static sqlite3_
8810: 6d 6f 64 75 6c 65 20 65 63 68 6f 4d 6f 64 75 6c  module echoModul
8820: 65 20 3d 20 7b 0a 20 20 30 2c 20 20 20 20 20 20  e = {.  0,      
8830: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8840: 20 20 20 2f 2a 20 69 56 65 72 73 69 6f 6e 20 2a     /* iVersion *
8850: 2f 0a 20 20 65 63 68 6f 43 72 65 61 74 65 2c 0a  /.  echoCreate,.
8860: 20 20 65 63 68 6f 43 6f 6e 6e 65 63 74 2c 0a 20    echoConnect,. 
8870: 20 65 63 68 6f 42 65 73 74 49 6e 64 65 78 2c 0a   echoBestIndex,.
8880: 20 20 65 63 68 6f 44 69 73 63 6f 6e 6e 65 63 74    echoDisconnect
8890: 2c 20 0a 20 20 65 63 68 6f 44 65 73 74 72 6f 79  , .  echoDestroy
88a0: 2c 0a 20 20 65 63 68 6f 4f 70 65 6e 2c 20 20 20  ,.  echoOpen,   
88b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
88c0: 2a 20 78 4f 70 65 6e 20 2d 20 6f 70 65 6e 20 61  * xOpen - open a
88d0: 20 63 75 72 73 6f 72 20 2a 2f 0a 20 20 65 63 68   cursor */.  ech
88e0: 6f 43 6c 6f 73 65 2c 20 20 20 20 20 20 20 20 20  oClose,         
88f0: 20 20 20 20 20 20 20 20 2f 2a 20 78 43 6c 6f 73          /* xClos
8900: 65 20 2d 20 63 6c 6f 73 65 20 61 20 63 75 72 73  e - close a curs
8910: 6f 72 20 2a 2f 0a 20 20 65 63 68 6f 46 69 6c 74  or */.  echoFilt
8920: 65 72 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  er,             
8930: 20 20 20 2f 2a 20 78 46 69 6c 74 65 72 20 2d 20     /* xFilter - 
8940: 63 6f 6e 66 69 67 75 72 65 20 73 63 61 6e 20 63  configure scan c
8950: 6f 6e 73 74 72 61 69 6e 74 73 20 2a 2f 0a 20 20  onstraints */.  
8960: 65 63 68 6f 4e 65 78 74 2c 20 20 20 20 20 20 20  echoNext,       
8970: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 4e             /* xN
8980: 65 78 74 20 2d 20 61 64 76 61 6e 63 65 20 61 20  ext - advance a 
8990: 63 75 72 73 6f 72 20 2a 2f 0a 20 20 65 63 68 6f  cursor */.  echo
89a0: 45 6f 66 2c 20 20 20 20 20 20 20 20 20 20 20 20  Eof,            
89b0: 20 20 20 20 20 20 20 2f 2a 20 78 45 6f 66 20 2a         /* xEof *
89c0: 2f 0a 20 20 65 63 68 6f 43 6f 6c 75 6d 6e 2c 20  /.  echoColumn, 
89d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
89e0: 2a 20 78 43 6f 6c 75 6d 6e 20 2d 20 72 65 61 64  * xColumn - read
89f0: 20 64 61 74 61 20 2a 2f 0a 20 20 65 63 68 6f 52   data */.  echoR
8a00: 6f 77 69 64 2c 20 20 20 20 20 20 20 20 20 20 20  owid,           
8a10: 20 20 20 20 20 20 2f 2a 20 78 52 6f 77 69 64 20        /* xRowid 
8a20: 2d 20 72 65 61 64 20 64 61 74 61 20 2a 2f 0a 20  - read data */. 
8a30: 20 65 63 68 6f 55 70 64 61 74 65 2c 20 20 20 20   echoUpdate,    
8a40: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78              /* x
8a50: 55 70 64 61 74 65 20 2d 20 77 72 69 74 65 20 64  Update - write d
8a60: 61 74 61 20 2a 2f 0a 20 20 65 63 68 6f 42 65 67  ata */.  echoBeg
8a70: 69 6e 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  in,             
8a80: 20 20 20 20 2f 2a 20 78 42 65 67 69 6e 20 2d 20      /* xBegin - 
8a90: 62 65 67 69 6e 20 74 72 61 6e 73 61 63 74 69 6f  begin transactio
8aa0: 6e 20 2a 2f 0a 20 20 65 63 68 6f 53 79 6e 63 2c  n */.  echoSync,
8ab0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8ac0: 20 20 2f 2a 20 78 53 79 6e 63 20 2d 20 73 79 6e    /* xSync - syn
8ad0: 63 20 74 72 61 6e 73 61 63 74 69 6f 6e 20 2a 2f  c transaction */
8ae0: 0a 20 20 65 63 68 6f 43 6f 6d 6d 69 74 2c 20 20  .  echoCommit,  
8af0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
8b00: 20 78 43 6f 6d 6d 69 74 20 2d 20 63 6f 6d 6d 69   xCommit - commi
8b10: 74 20 74 72 61 6e 73 61 63 74 69 6f 6e 20 2a 2f  t transaction */
8b20: 0a 20 20 65 63 68 6f 52 6f 6c 6c 62 61 63 6b 2c  .  echoRollback,
8b30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
8b40: 20 78 52 6f 6c 6c 62 61 63 6b 20 2d 20 72 6f 6c   xRollback - rol
8b50: 6c 62 61 63 6b 20 74 72 61 6e 73 61 63 74 69 6f  lback transactio
8b60: 6e 20 2a 2f 0a 20 20 65 63 68 6f 46 69 6e 64 46  n */.  echoFindF
8b70: 75 6e 63 74 69 6f 6e 2c 20 20 20 20 20 20 20 20  unction,        
8b80: 20 20 2f 2a 20 78 46 69 6e 64 46 75 6e 63 74 69    /* xFindFuncti
8b90: 6f 6e 20 2d 20 66 75 6e 63 74 69 6f 6e 20 6f 76  on - function ov
8ba0: 65 72 6c 6f 61 64 69 6e 67 20 2a 2f 0a 20 20 65  erloading */.  e
8bb0: 63 68 6f 52 65 6e 61 6d 65 2c 20 20 20 20 20 20  choRename,      
8bc0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 52 65            /* xRe
8bd0: 6e 61 6d 65 20 2d 20 72 65 6e 61 6d 65 20 74 68  name - rename th
8be0: 65 20 74 61 62 6c 65 20 2a 2f 0a 7d 3b 0a 0a 2f  e table */.};../
8bf0: 2a 0a 2a 2a 20 44 65 63 6f 64 65 20 61 20 70 6f  *.** Decode a po
8c00: 69 6e 74 65 72 20 74 6f 20 61 6e 20 73 71 6c 69  inter to an sqli
8c10: 74 65 33 20 6f 62 6a 65 63 74 2e 0a 2a 2f 0a 65  te3 object..*/.e
8c20: 78 74 65 72 6e 20 69 6e 74 20 67 65 74 44 62 50  xtern int getDbP
8c30: 6f 69 6e 74 65 72 28 54 63 6c 5f 49 6e 74 65 72  ointer(Tcl_Inter
8c40: 70 20 2a 69 6e 74 65 72 70 2c 20 63 6f 6e 73 74  p *interp, const
8c50: 20 63 68 61 72 20 2a 7a 41 2c 20 73 71 6c 69 74   char *zA, sqlit
8c60: 65 33 20 2a 2a 70 70 44 62 29 3b 0a 0a 73 74 61  e3 **ppDb);..sta
8c70: 74 69 63 20 76 6f 69 64 20 6d 6f 64 75 6c 65 44  tic void moduleD
8c80: 65 73 74 72 6f 79 28 76 6f 69 64 20 2a 70 29 7b  estroy(void *p){
8c90: 0a 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28  .  sqlite3_free(
8ca0: 70 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 67  p);.}../*.** Reg
8cb0: 69 73 74 65 72 20 74 68 65 20 65 63 68 6f 20 76  ister the echo v
8cc0: 69 72 74 75 61 6c 20 74 61 62 6c 65 20 6d 6f 64  irtual table mod
8cd0: 75 6c 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  ule..*/.static i
8ce0: 6e 74 20 72 65 67 69 73 74 65 72 5f 65 63 68 6f  nt register_echo
8cf0: 5f 6d 6f 64 75 6c 65 28 0a 20 20 43 6c 69 65 6e  _module(.  Clien
8d00: 74 44 61 74 61 20 63 6c 69 65 6e 74 44 61 74 61  tData clientData
8d10: 2c 20 2f 2a 20 50 6f 69 6e 74 65 72 20 74 6f 20  , /* Pointer to 
8d20: 73 71 6c 69 74 65 33 5f 65 6e 61 62 6c 65 5f 58  sqlite3_enable_X
8d30: 58 58 20 66 75 6e 63 74 69 6f 6e 20 2a 2f 0a 20  XX function */. 
8d40: 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74   Tcl_Interp *int
8d50: 65 72 70 2c 20 20 20 20 2f 2a 20 54 68 65 20 54  erp,    /* The T
8d60: 43 4c 20 69 6e 74 65 72 70 72 65 74 65 72 20 74  CL interpreter t
8d70: 68 61 74 20 69 6e 76 6f 6b 65 64 20 74 68 69 73  hat invoked this
8d80: 20 63 6f 6d 6d 61 6e 64 20 2a 2f 0a 20 20 69 6e   command */.  in
8d90: 74 20 6f 62 6a 63 2c 20 20 20 20 20 20 20 20 20  t objc,         
8da0: 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f       /* Number o
8db0: 66 20 61 72 67 75 6d 65 6e 74 73 20 2a 2f 0a 20  f arguments */. 
8dc0: 20 54 63 6c 5f 4f 62 6a 20 2a 43 4f 4e 53 54 20   Tcl_Obj *CONST 
8dd0: 6f 62 6a 76 5b 5d 20 20 2f 2a 20 43 6f 6d 6d 61  objv[]  /* Comma
8de0: 6e 64 20 61 72 67 75 6d 65 6e 74 73 20 2a 2f 0a  nd arguments */.
8df0: 29 7b 0a 20 20 73 71 6c 69 74 65 33 20 2a 64 62  ){.  sqlite3 *db
8e00: 3b 0a 20 20 45 63 68 6f 4d 6f 64 75 6c 65 20 2a  ;.  EchoModule *
8e10: 70 4d 6f 64 3b 0a 20 20 69 66 28 20 6f 62 6a 63  pMod;.  if( objc
8e20: 21 3d 32 20 29 7b 0a 20 20 20 20 54 63 6c 5f 57  !=2 ){.    Tcl_W
8e30: 72 6f 6e 67 4e 75 6d 41 72 67 73 28 69 6e 74 65  rongNumArgs(inte
8e40: 72 70 2c 20 31 2c 20 6f 62 6a 76 2c 20 22 44 42  rp, 1, objv, "DB
8e50: 22 29 3b 0a 20 20 20 20 72 65 74 75 72 6e 20 54  ");.    return T
8e60: 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a 20 20  CL_ERROR;.  }.  
8e70: 69 66 28 20 67 65 74 44 62 50 6f 69 6e 74 65 72  if( getDbPointer
8e80: 28 69 6e 74 65 72 70 2c 20 54 63 6c 5f 47 65 74  (interp, Tcl_Get
8e90: 53 74 72 69 6e 67 28 6f 62 6a 76 5b 31 5d 29 2c  String(objv[1]),
8ea0: 20 26 64 62 29 20 29 20 72 65 74 75 72 6e 20 54   &db) ) return T
8eb0: 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 70 4d 6f 64  CL_ERROR;.  pMod
8ec0: 20 3d 20 73 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f   = sqlite3_mallo
8ed0: 63 28 73 69 7a 65 6f 66 28 45 63 68 6f 4d 6f 64  c(sizeof(EchoMod
8ee0: 75 6c 65 29 29 3b 0a 20 20 70 4d 6f 64 2d 3e 69  ule));.  pMod->i
8ef0: 6e 74 65 72 70 20 3d 20 69 6e 74 65 72 70 3b 0a  nterp = interp;.
8f00: 20 20 73 71 6c 69 74 65 33 5f 63 72 65 61 74 65    sqlite3_create
8f10: 5f 6d 6f 64 75 6c 65 5f 76 32 28 64 62 2c 20 22  _module_v2(db, "
8f20: 65 63 68 6f 22 2c 20 26 65 63 68 6f 4d 6f 64 75  echo", &echoModu
8f30: 6c 65 2c 20 28 76 6f 69 64 2a 29 70 4d 6f 64 2c  le, (void*)pMod,
8f40: 20 6d 6f 64 75 6c 65 44 65 73 74 72 6f 79 29 3b   moduleDestroy);
8f50: 0a 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 4f 4b  .  return TCL_OK
8f60: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 63 6c 20 69  ;.}../*.** Tcl i
8f70: 6e 74 65 72 66 61 63 65 20 74 6f 20 73 71 6c 69  nterface to sqli
8f80: 74 65 33 5f 64 65 63 6c 61 72 65 5f 76 74 61 62  te3_declare_vtab
8f90: 2c 20 69 6e 76 6f 6b 65 64 20 61 73 20 66 6f 6c  , invoked as fol
8fa0: 6c 6f 77 73 20 66 72 6f 6d 20 54 63 6c 3a 0a 2a  lows from Tcl:.*
8fb0: 2a 0a 2a 2a 20 73 71 6c 69 74 65 33 5f 64 65 63  *.** sqlite3_dec
8fc0: 6c 61 72 65 5f 76 74 61 62 20 44 42 20 53 51 4c  lare_vtab DB SQL
8fd0: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 64  .*/.static int d
8fe0: 65 63 6c 61 72 65 5f 76 74 61 62 28 0a 20 20 43  eclare_vtab(.  C
8ff0: 6c 69 65 6e 74 44 61 74 61 20 63 6c 69 65 6e 74  lientData client
9000: 44 61 74 61 2c 20 2f 2a 20 50 6f 69 6e 74 65 72  Data, /* Pointer
9010: 20 74 6f 20 73 71 6c 69 74 65 33 5f 65 6e 61 62   to sqlite3_enab
9020: 6c 65 5f 58 58 58 20 66 75 6e 63 74 69 6f 6e 20  le_XXX function 
9030: 2a 2f 0a 20 20 54 63 6c 5f 49 6e 74 65 72 70 20  */.  Tcl_Interp 
9040: 2a 69 6e 74 65 72 70 2c 20 20 20 20 2f 2a 20 54  *interp,    /* T
9050: 68 65 20 54 43 4c 20 69 6e 74 65 72 70 72 65 74  he TCL interpret
9060: 65 72 20 74 68 61 74 20 69 6e 76 6f 6b 65 64 20  er that invoked 
9070: 74 68 69 73 20 63 6f 6d 6d 61 6e 64 20 2a 2f 0a  this command */.
9080: 20 20 69 6e 74 20 6f 62 6a 63 2c 20 20 20 20 20    int objc,     
9090: 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62           /* Numb
90a0: 65 72 20 6f 66 20 61 72 67 75 6d 65 6e 74 73 20  er of arguments 
90b0: 2a 2f 0a 20 20 54 63 6c 5f 4f 62 6a 20 2a 43 4f  */.  Tcl_Obj *CO
90c0: 4e 53 54 20 6f 62 6a 76 5b 5d 20 20 2f 2a 20 43  NST objv[]  /* C
90d0: 6f 6d 6d 61 6e 64 20 61 72 67 75 6d 65 6e 74 73  ommand arguments
90e0: 20 2a 2f 0a 29 7b 0a 20 20 73 71 6c 69 74 65 33   */.){.  sqlite3
90f0: 20 2a 64 62 3b 0a 20 20 69 6e 74 20 72 63 3b 0a   *db;.  int rc;.
9100: 20 20 69 66 28 20 6f 62 6a 63 21 3d 33 20 29 7b    if( objc!=3 ){
9110: 0a 20 20 20 20 54 63 6c 5f 57 72 6f 6e 67 4e 75  .    Tcl_WrongNu
9120: 6d 41 72 67 73 28 69 6e 74 65 72 70 2c 20 31 2c  mArgs(interp, 1,
9130: 20 6f 62 6a 76 2c 20 22 44 42 20 53 51 4c 22 29   objv, "DB SQL")
9140: 3b 0a 20 20 20 20 72 65 74 75 72 6e 20 54 43 4c  ;.    return TCL
9150: 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a 20 20 69 66  _ERROR;.  }.  if
9160: 28 20 67 65 74 44 62 50 6f 69 6e 74 65 72 28 69  ( getDbPointer(i
9170: 6e 74 65 72 70 2c 20 54 63 6c 5f 47 65 74 53 74  nterp, Tcl_GetSt
9180: 72 69 6e 67 28 6f 62 6a 76 5b 31 5d 29 2c 20 26  ring(objv[1]), &
9190: 64 62 29 20 29 20 72 65 74 75 72 6e 20 54 43 4c  db) ) return TCL
91a0: 5f 45 52 52 4f 52 3b 0a 20 20 72 63 20 3d 20 73  _ERROR;.  rc = s
91b0: 71 6c 69 74 65 33 5f 64 65 63 6c 61 72 65 5f 76  qlite3_declare_v
91c0: 74 61 62 28 64 62 2c 20 54 63 6c 5f 47 65 74 53  tab(db, Tcl_GetS
91d0: 74 72 69 6e 67 28 6f 62 6a 76 5b 32 5d 29 29 3b  tring(objv[2]));
91e0: 0a 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54  .  if( rc!=SQLIT
91f0: 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 54 63 6c 5f  E_OK ){.    Tcl_
9200: 53 65 74 52 65 73 75 6c 74 28 69 6e 74 65 72 70  SetResult(interp
9210: 2c 20 28 63 68 61 72 20 2a 29 73 71 6c 69 74 65  , (char *)sqlite
9220: 33 5f 65 72 72 6d 73 67 28 64 62 29 2c 20 54 43  3_errmsg(db), TC
9230: 4c 5f 56 4f 4c 41 54 49 4c 45 29 3b 0a 20 20 20  L_VOLATILE);.   
9240: 20 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f   return TCL_ERRO
9250: 52 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20  R;.  }.  return 
9260: 54 43 4c 5f 4f 4b 3b 0a 7d 0a 0a 23 65 6e 64 69  TCL_OK;.}..#endi
9270: 66 20 2f 2a 20 69 66 6e 64 65 66 20 53 51 4c 49  f /* ifndef SQLI
9280: 54 45 5f 4f 4d 49 54 5f 56 49 52 54 55 41 4c 54  TE_OMIT_VIRTUALT
9290: 41 42 4c 45 20 2a 2f 0a 0a 2f 2a 0a 2a 2a 20 52  ABLE */../*.** R
92a0: 65 67 69 73 74 65 72 20 63 6f 6d 6d 61 6e 64 73  egister commands
92b0: 20 77 69 74 68 20 74 68 65 20 54 43 4c 20 69 6e   with the TCL in
92c0: 74 65 72 70 72 65 74 65 72 2e 0a 2a 2f 0a 69 6e  terpreter..*/.in
92d0: 74 20 53 71 6c 69 74 65 74 65 73 74 38 5f 49 6e  t Sqlitetest8_In
92e0: 69 74 28 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69  it(Tcl_Interp *i
92f0: 6e 74 65 72 70 29 7b 0a 23 69 66 6e 64 65 66 20  nterp){.#ifndef 
9300: 53 51 4c 49 54 45 5f 4f 4d 49 54 5f 56 49 52 54  SQLITE_OMIT_VIRT
9310: 55 41 4c 54 41 42 4c 45 0a 20 20 73 74 61 74 69  UALTABLE.  stati
9320: 63 20 73 74 72 75 63 74 20 7b 0a 20 20 20 20 20  c struct {.     
9330: 63 68 61 72 20 2a 7a 4e 61 6d 65 3b 0a 20 20 20  char *zName;.   
9340: 20 20 54 63 6c 5f 4f 62 6a 43 6d 64 50 72 6f 63    Tcl_ObjCmdProc
9350: 20 2a 78 50 72 6f 63 3b 0a 20 20 20 20 20 76 6f   *xProc;.     vo
9360: 69 64 20 2a 63 6c 69 65 6e 74 44 61 74 61 3b 0a  id *clientData;.
9370: 20 20 7d 20 61 4f 62 6a 43 6d 64 5b 5d 20 3d 20    } aObjCmd[] = 
9380: 7b 0a 20 20 20 20 20 7b 20 22 72 65 67 69 73 74  {.     { "regist
9390: 65 72 5f 65 63 68 6f 5f 6d 6f 64 75 6c 65 22 2c  er_echo_module",
93a0: 20 20 20 72 65 67 69 73 74 65 72 5f 65 63 68 6f     register_echo
93b0: 5f 6d 6f 64 75 6c 65 2c 20 30 20 7d 2c 0a 20 20  _module, 0 },.  
93c0: 20 20 20 7b 20 22 73 71 6c 69 74 65 33 5f 64 65     { "sqlite3_de
93d0: 63 6c 61 72 65 5f 76 74 61 62 22 2c 20 20 20 64  clare_vtab",   d
93e0: 65 63 6c 61 72 65 5f 76 74 61 62 2c 20 30 20 7d  eclare_vtab, 0 }
93f0: 2c 0a 20 20 7d 3b 0a 20 20 69 6e 74 20 69 3b 0a  ,.  };.  int i;.
9400: 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 73 69 7a    for(i=0; i<siz
9410: 65 6f 66 28 61 4f 62 6a 43 6d 64 29 2f 73 69 7a  eof(aObjCmd)/siz
9420: 65 6f 66 28 61 4f 62 6a 43 6d 64 5b 30 5d 29 3b  eof(aObjCmd[0]);
9430: 20 69 2b 2b 29 7b 0a 20 20 20 20 54 63 6c 5f 43   i++){.    Tcl_C
9440: 72 65 61 74 65 4f 62 6a 43 6f 6d 6d 61 6e 64 28  reateObjCommand(
9450: 69 6e 74 65 72 70 2c 20 61 4f 62 6a 43 6d 64 5b  interp, aObjCmd[
9460: 69 5d 2e 7a 4e 61 6d 65 2c 20 0a 20 20 20 20 20  i].zName, .     
9470: 20 20 20 61 4f 62 6a 43 6d 64 5b 69 5d 2e 78 50     aObjCmd[i].xP
9480: 72 6f 63 2c 20 61 4f 62 6a 43 6d 64 5b 69 5d 2e  roc, aObjCmd[i].
9490: 63 6c 69 65 6e 74 44 61 74 61 2c 20 30 29 3b 0a  clientData, 0);.
94a0: 20 20 7d 0a 23 65 6e 64 69 66 0a 20 20 72 65 74    }.#endif.  ret
94b0: 75 72 6e 20 54 43 4c 5f 4f 4b 3b 0a 7d 0a        urn TCL_OK;.}.