/ Hex Artifact Content
Login

Artifact 8cd3382bca3908c6eaf15af4f25607a648b3cf55:


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 32 20 32  test8.c,v 1.72 2
0230: 30 30 38 2f 30 38 2f 30 35 20 32 31 3a 33 36 3a  008/08/05 21:36:
0240: 30 37 20 64 72 68 20 45 78 70 20 24 0a 2a 2f 0a  07 drh Exp $.*/.
0250: 23 69 6e 63 6c 75 64 65 20 22 73 71 6c 69 74 65  #include "sqlite
0260: 49 6e 74 2e 68 22 0a 23 69 6e 63 6c 75 64 65 20  Int.h".#include 
0270: 22 74 63 6c 2e 68 22 0a 23 69 6e 63 6c 75 64 65  "tcl.h".#include
0280: 20 3c 73 74 64 6c 69 62 2e 68 3e 0a 23 69 6e 63   <stdlib.h>.#inc
0290: 6c 75 64 65 20 3c 73 74 72 69 6e 67 2e 68 3e 0a  lude <string.h>.
02a0: 0a 23 69 66 6e 64 65 66 20 53 51 4c 49 54 45 5f  .#ifndef SQLITE_
02b0: 4f 4d 49 54 5f 56 49 52 54 55 41 4c 54 41 42 4c  OMIT_VIRTUALTABL
02c0: 45 0a 0a 74 79 70 65 64 65 66 20 73 74 72 75 63  E..typedef struc
02d0: 74 20 65 63 68 6f 5f 76 74 61 62 20 65 63 68 6f  t echo_vtab echo
02e0: 5f 76 74 61 62 3b 0a 74 79 70 65 64 65 66 20 73  _vtab;.typedef s
02f0: 74 72 75 63 74 20 65 63 68 6f 5f 63 75 72 73 6f  truct echo_curso
0300: 72 20 65 63 68 6f 5f 63 75 72 73 6f 72 3b 0a 0a  r echo_cursor;..
0310: 2f 2a 0a 2a 2a 20 54 68 65 20 74 65 73 74 20 6d  /*.** The test m
0320: 6f 64 75 6c 65 20 64 65 66 69 6e 65 64 20 69 6e  odule defined in
0330: 20 74 68 69 73 20 66 69 6c 65 20 75 73 65 73 20   this file uses 
0340: 66 6f 75 72 20 67 6c 6f 62 61 6c 20 54 63 6c 20  four global Tcl 
0350: 76 61 72 69 61 62 6c 65 73 20 74 6f 0a 2a 2a 20  variables to.** 
0360: 63 6f 6d 6d 69 63 61 74 65 20 77 69 74 68 20 74  commicate with t
0370: 65 73 74 2d 73 63 72 69 70 74 73 3a 0a 2a 2a 0a  est-scripts:.**.
0380: 2a 2a 20 20 20 20 20 24 3a 3a 65 63 68 6f 5f 6d  **     $::echo_m
0390: 6f 64 75 6c 65 0a 2a 2a 20 20 20 20 20 24 3a 3a  odule.**     $::
03a0: 65 63 68 6f 5f 6d 6f 64 75 6c 65 5f 73 79 6e 63  echo_module_sync
03b0: 5f 66 61 69 6c 0a 2a 2a 20 20 20 20 20 24 3a 3a  _fail.**     $::
03c0: 65 63 68 6f 5f 6d 6f 64 75 6c 65 5f 62 65 67 69  echo_module_begi
03d0: 6e 5f 66 61 69 6c 0a 2a 2a 20 20 20 20 20 24 3a  n_fail.**     $:
03e0: 3a 65 63 68 6f 5f 6d 6f 64 75 6c 65 5f 63 6f 73  :echo_module_cos
03f0: 74 0a 2a 2a 0a 2a 2a 20 54 68 65 20 76 61 72 69  t.**.** The vari
0400: 61 62 6c 65 20 3a 3a 65 63 68 6f 5f 6d 6f 64 75  able ::echo_modu
0410: 6c 65 20 69 73 20 61 20 6c 69 73 74 2e 20 45 61  le is a list. Ea
0420: 63 68 20 74 69 6d 65 20 6f 6e 65 20 6f 66 20 74  ch time one of t
0430: 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 0a 2a 2a 20  he following.** 
0440: 6d 65 74 68 6f 64 73 20 69 73 20 63 61 6c 6c 65  methods is calle
0450: 64 2c 20 6f 6e 65 20 6f 72 20 6d 6f 72 65 20 65  d, one or more e
0460: 6c 65 6d 65 6e 74 73 20 61 72 65 20 61 70 70 65  lements are appe
0470: 6e 64 65 64 20 74 6f 20 74 68 65 20 6c 69 73 74  nded to the list
0480: 2e 0a 2a 2a 20 54 68 69 73 20 69 73 20 75 73 65  ..** This is use
0490: 64 20 66 6f 72 20 61 75 74 6f 6d 61 74 65 64 20  d for automated 
04a0: 74 65 73 74 69 6e 67 20 6f 66 20 76 69 72 74 75  testing of virtu
04b0: 61 6c 20 74 61 62 6c 65 20 6d 6f 64 75 6c 65 73  al table modules
04c0: 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 3a 3a 65 63  ..**.** The ::ec
04d0: 68 6f 5f 6d 6f 64 75 6c 65 5f 73 79 6e 63 5f 66  ho_module_sync_f
04e0: 61 69 6c 20 76 61 72 69 61 62 6c 65 20 69 73 20  ail variable is 
04f0: 73 65 74 20 62 79 20 74 65 73 74 20 73 63 72 69  set by test scri
0500: 70 74 73 20 61 6e 64 20 72 65 61 64 0a 2a 2a 20  pts and read.** 
0510: 62 79 20 63 6f 64 65 20 69 6e 20 74 68 69 73 20  by code in this 
0520: 66 69 6c 65 2e 20 49 66 20 69 74 20 69 73 20 73  file. If it is s
0530: 65 74 20 74 6f 20 74 68 65 20 6e 61 6d 65 20 6f  et to the name o
0540: 66 20 61 20 72 65 61 6c 20 74 61 62 6c 65 20 69  f a real table i
0550: 6e 20 74 68 65 0a 2a 2a 20 74 68 65 20 64 61 74  n the.** the dat
0560: 61 62 61 73 65 2c 20 74 68 65 6e 20 61 6c 6c 20  abase, then all 
0570: 78 53 79 6e 63 20 6f 70 65 72 61 74 69 6f 6e 73  xSync operations
0580: 20 6f 6e 20 65 63 68 6f 20 76 69 72 74 75 61 6c   on echo virtual
0590: 20 74 61 62 6c 65 73 20 74 68 61 74 0a 2a 2a 20   tables that.** 
05a0: 75 73 65 20 74 68 65 20 6e 61 6d 65 64 20 74 61  use the named ta
05b0: 62 6c 65 20 61 73 20 61 20 62 61 63 6b 69 6e 67  ble as a backing
05c0: 20 73 74 6f 72 65 20 77 69 6c 6c 20 66 61 69 6c   store will fail
05d0: 2e 0a 2a 2f 0a 0a 2f 2a 0a 2a 2a 20 45 72 72 6f  ..*/../*.** Erro
05e0: 72 73 20 63 61 6e 20 62 65 20 70 72 6f 76 6f 6b  rs can be provok
05f0: 65 64 20 77 69 74 68 69 6e 20 74 68 65 20 66 6f  ed within the fo
0600: 6c 6c 6f 77 69 6e 67 20 65 63 68 6f 20 76 69 72  llowing echo vir
0610: 74 75 61 6c 20 74 61 62 6c 65 20 6d 65 74 68 6f  tual table metho
0620: 64 73 3a 0a 2a 2a 0a 2a 2a 20 20 20 78 42 65 73  ds:.**.**   xBes
0630: 74 49 6e 64 65 78 20 20 20 78 4f 70 65 6e 20 20  tIndex   xOpen  
0640: 20 20 20 78 46 69 6c 74 65 72 20 20 20 78 4e 65     xFilter   xNe
0650: 78 74 20 20 20 0a 2a 2a 20 20 20 78 43 6f 6c 75  xt   .**   xColu
0660: 6d 6e 20 20 20 20 20 20 78 52 6f 77 69 64 20 20  mn      xRowid  
0670: 20 20 78 55 70 64 61 74 65 20 20 20 78 53 79 6e    xUpdate   xSyn
0680: 63 20 20 20 0a 2a 2a 20 20 20 78 42 65 67 69 6e  c   .**   xBegin
0690: 20 20 20 20 20 20 20 78 52 65 6e 61 6d 65 0a 2a         xRename.*
06a0: 2a 0a 2a 2a 20 54 68 69 73 20 69 73 20 64 6f 6e  *.** This is don
06b0: 65 20 62 79 20 73 65 74 74 69 6e 67 20 74 68 65  e by setting the
06c0: 20 67 6c 6f 62 61 6c 20 74 63 6c 20 76 61 72 69   global tcl vari
06d0: 61 62 6c 65 3a 0a 2a 2a 0a 2a 2a 20 20 20 65 63  able:.**.**   ec
06e0: 68 6f 5f 6d 6f 64 75 6c 65 5f 66 61 69 6c 28 24  ho_module_fail($
06f0: 6d 65 74 68 6f 64 2c 24 74 62 6c 29 0a 2a 2a 0a  method,$tbl).**.
0700: 2a 2a 20 77 68 65 72 65 20 24 6d 65 74 68 6f 64  ** where $method
0710: 20 69 73 20 73 65 74 20 74 6f 20 74 68 65 20 6e   is set to the n
0720: 61 6d 65 20 6f 66 20 74 68 65 20 76 69 72 74 75  ame of the virtu
0730: 61 6c 20 74 61 62 6c 65 20 6d 65 74 68 6f 64 20  al table method 
0740: 74 6f 20 66 61 69 6c 0a 2a 2a 20 28 69 2e 65 2e  to fail.** (i.e.
0750: 20 22 78 42 65 73 74 49 6e 64 65 78 22 29 20 61   "xBestIndex") a
0760: 6e 64 20 24 74 62 6c 20 69 73 20 74 68 65 20 6e  nd $tbl is the n
0770: 61 6d 65 20 6f 66 20 74 68 65 20 74 61 62 6c 65  ame of the table
0780: 20 62 65 69 6e 67 20 65 63 68 6f 65 64 20 28 6e   being echoed (n
0790: 6f 74 0a 2a 2a 20 74 68 65 20 6e 61 6d 65 20 6f  ot.** the name o
07a0: 66 20 74 68 65 20 76 69 72 74 75 61 6c 20 74 61  f the virtual ta
07b0: 62 6c 65 2c 20 74 68 65 20 6e 61 6d 65 20 6f 66  ble, the name of
07c0: 20 74 68 65 20 75 6e 64 65 72 6c 79 69 6e 67 20   the underlying 
07d0: 72 65 61 6c 20 74 61 62 6c 65 29 2e 0a 2a 2f 0a  real table)..*/.
07e0: 0a 2f 2a 20 0a 2a 2a 20 41 6e 20 65 63 68 6f 20  ./* .** An echo 
07f0: 76 69 72 74 75 61 6c 2d 74 61 62 6c 65 20 6f 62  virtual-table ob
0800: 6a 65 63 74 2e 0a 2a 2a 0a 2a 2a 20 65 63 68 6f  ject..**.** echo
0810: 2e 76 74 61 62 2e 61 49 6e 64 65 78 20 69 73 20  .vtab.aIndex is 
0820: 61 6e 20 61 72 72 61 79 20 6f 66 20 62 6f 6f 6c  an array of bool
0830: 65 61 6e 73 2e 20 54 68 65 20 6e 74 68 20 65 6e  eans. The nth en
0840: 74 72 79 20 69 73 20 74 72 75 65 20 69 66 20 0a  try is true if .
0850: 2a 2a 20 74 68 65 20 6e 74 68 20 63 6f 6c 75 6d  ** the nth colum
0860: 6e 20 6f 66 20 74 68 65 20 72 65 61 6c 20 74 61  n of the real ta
0870: 62 6c 65 20 69 73 20 74 68 65 20 6c 65 66 74 2d  ble is the left-
0880: 6d 6f 73 74 20 63 6f 6c 75 6d 6e 20 6f 66 20 61  most column of a
0890: 6e 20 69 6e 64 65 78 0a 2a 2a 20 28 69 6d 70 6c  n index.** (impl
08a0: 69 63 69 74 20 6f 72 20 6f 74 68 65 72 77 69 73  icit or otherwis
08b0: 65 29 2e 20 49 6e 20 6f 74 68 65 72 20 77 6f 72  e). In other wor
08c0: 64 73 2c 20 69 66 20 53 51 4c 69 74 65 20 63 61  ds, if SQLite ca
08d0: 6e 20 6f 70 74 69 6d 69 7a 65 0a 2a 2a 20 61 20  n optimize.** a 
08e0: 71 75 65 72 79 20 6c 69 6b 65 20 22 53 45 4c 45  query like "SELE
08f0: 43 54 20 2a 20 46 52 4f 4d 20 72 65 61 6c 5f 74  CT * FROM real_t
0900: 61 62 6c 65 20 57 48 45 52 45 20 63 6f 6c 20 3d  able WHERE col =
0910: 20 3f 22 2e 0a 2a 2a 0a 2a 2a 20 4d 65 6d 62 65   ?"..**.** Membe
0920: 72 20 76 61 72 69 61 62 6c 65 20 61 43 6f 6c 5b  r variable aCol[
0930: 5d 20 63 6f 6e 74 61 69 6e 73 20 63 6f 70 69 65  ] contains copie
0940: 73 20 6f 66 20 74 68 65 20 63 6f 6c 75 6d 6e 20  s of the column 
0950: 6e 61 6d 65 73 20 6f 66 20 74 68 65 20 72 65 61  names of the rea
0960: 6c 0a 2a 2a 20 74 61 62 6c 65 2e 0a 2a 2f 0a 73  l.** table..*/.s
0970: 74 72 75 63 74 20 65 63 68 6f 5f 76 74 61 62 20  truct echo_vtab 
0980: 7b 0a 20 20 73 71 6c 69 74 65 33 5f 76 74 61 62  {.  sqlite3_vtab
0990: 20 62 61 73 65 3b 0a 20 20 54 63 6c 5f 49 6e 74   base;.  Tcl_Int
09a0: 65 72 70 20 2a 69 6e 74 65 72 70 3b 20 20 20 20  erp *interp;    
09b0: 20 2f 2a 20 54 63 6c 20 69 6e 74 65 72 70 72 65   /* Tcl interpre
09c0: 74 65 72 20 63 6f 6e 74 61 69 6e 69 6e 67 20 64  ter containing d
09d0: 65 62 75 67 20 76 61 72 69 61 62 6c 65 73 20 2a  ebug variables *
09e0: 2f 0a 20 20 73 71 6c 69 74 65 33 20 2a 64 62 3b  /.  sqlite3 *db;
09f0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 44              /* D
0a00: 61 74 61 62 61 73 65 20 63 6f 6e 6e 65 63 74 69  atabase connecti
0a10: 6f 6e 20 2a 2f 0a 0a 20 20 69 6e 74 20 69 73 50  on */..  int isP
0a20: 61 74 74 65 72 6e 3b 0a 20 20 69 6e 74 20 69 6e  attern;.  int in
0a30: 54 72 61 6e 73 61 63 74 69 6f 6e 3b 20 20 20 20  Transaction;    
0a40: 20 20 2f 2a 20 54 72 75 65 20 69 66 20 77 69 74    /* True if wit
0a50: 68 69 6e 20 61 20 74 72 61 6e 73 61 63 74 69 6f  hin a transactio
0a60: 6e 20 2a 2f 0a 20 20 63 68 61 72 20 2a 7a 54 68  n */.  char *zTh
0a70: 69 73 3b 20 20 20 20 20 20 20 20 20 20 20 20 2f  is;            /
0a80: 2a 20 4e 61 6d 65 20 6f 66 20 74 68 65 20 65 63  * Name of the ec
0a90: 68 6f 20 74 61 62 6c 65 20 2a 2f 0a 20 20 63 68  ho table */.  ch
0aa0: 61 72 20 2a 7a 54 61 62 6c 65 4e 61 6d 65 3b 20  ar *zTableName; 
0ab0: 20 20 20 20 20 20 2f 2a 20 4e 61 6d 65 20 6f 66        /* Name of
0ac0: 20 74 68 65 20 72 65 61 6c 20 74 61 62 6c 65 20   the real table 
0ad0: 2a 2f 0a 20 20 63 68 61 72 20 2a 7a 4c 6f 67 4e  */.  char *zLogN
0ae0: 61 6d 65 3b 20 20 20 20 20 20 20 20 20 2f 2a 20  ame;         /* 
0af0: 4e 61 6d 65 20 6f 66 20 74 68 65 20 6c 6f 67 20  Name of the log 
0b00: 74 61 62 6c 65 20 2a 2f 0a 20 20 69 6e 74 20 6e  table */.  int n
0b10: 43 6f 6c 3b 20 20 20 20 20 20 20 20 20 20 20 20  Col;            
0b20: 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20     /* Number of 
0b30: 63 6f 6c 75 6d 6e 73 20 69 6e 20 74 68 65 20 72  columns in the r
0b40: 65 61 6c 20 74 61 62 6c 65 20 2a 2f 0a 20 20 69  eal table */.  i
0b50: 6e 74 20 2a 61 49 6e 64 65 78 3b 20 20 20 20 20  nt *aIndex;     
0b60: 20 20 20 20 20 20 20 2f 2a 20 41 72 72 61 79 20         /* Array 
0b70: 6f 66 20 73 69 7a 65 20 6e 43 6f 6c 2e 20 54 72  of size nCol. Tr
0b80: 75 65 20 69 66 20 63 6f 6c 75 6d 6e 20 68 61 73  ue if column has
0b90: 20 61 6e 20 69 6e 64 65 78 20 2a 2f 0a 20 20 63   an index */.  c
0ba0: 68 61 72 20 2a 2a 61 43 6f 6c 3b 20 20 20 20 20  har **aCol;     
0bb0: 20 20 20 20 20 20 20 2f 2a 20 41 72 72 61 79 20         /* Array 
0bc0: 6f 66 20 73 69 7a 65 20 6e 43 6f 6c 2e 20 43 6f  of size nCol. Co
0bd0: 6c 75 6d 6e 20 6e 61 6d 65 73 20 2a 2f 0a 7d 3b  lumn names */.};
0be0: 0a 0a 2f 2a 20 41 6e 20 65 63 68 6f 20 63 75 72  ../* An echo cur
0bf0: 73 6f 72 20 6f 62 6a 65 63 74 20 2a 2f 0a 73 74  sor object */.st
0c00: 72 75 63 74 20 65 63 68 6f 5f 63 75 72 73 6f 72  ruct echo_cursor
0c10: 20 7b 0a 20 20 73 71 6c 69 74 65 33 5f 76 74 61   {.  sqlite3_vta
0c20: 62 5f 63 75 72 73 6f 72 20 62 61 73 65 3b 0a 20  b_cursor base;. 
0c30: 20 73 71 6c 69 74 65 33 5f 73 74 6d 74 20 2a 70   sqlite3_stmt *p
0c40: 53 74 6d 74 3b 0a 7d 3b 0a 0a 73 74 61 74 69 63  Stmt;.};..static
0c50: 20 69 6e 74 20 73 69 6d 75 6c 61 74 65 56 74 61   int simulateVta
0c60: 62 45 72 72 6f 72 28 65 63 68 6f 5f 76 74 61 62  bError(echo_vtab
0c70: 20 2a 70 2c 20 63 6f 6e 73 74 20 63 68 61 72 20   *p, const char 
0c80: 2a 7a 4d 65 74 68 6f 64 29 7b 0a 20 20 63 6f 6e  *zMethod){.  con
0c90: 73 74 20 63 68 61 72 20 2a 7a 45 72 72 3b 0a 20  st char *zErr;. 
0ca0: 20 63 68 61 72 20 7a 56 61 72 6e 61 6d 65 5b 31   char zVarname[1
0cb0: 32 38 5d 3b 0a 20 20 7a 56 61 72 6e 61 6d 65 5b  28];.  zVarname[
0cc0: 31 32 37 5d 20 3d 20 27 5c 30 27 3b 0a 20 20 73  127] = '\0';.  s
0cd0: 71 6c 69 74 65 33 5f 73 6e 70 72 69 6e 74 66 28  qlite3_snprintf(
0ce0: 31 32 37 2c 20 7a 56 61 72 6e 61 6d 65 2c 20 0a  127, zVarname, .
0cf0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0d00: 20 20 20 22 65 63 68 6f 5f 6d 6f 64 75 6c 65 5f     "echo_module_
0d10: 66 61 69 6c 28 25 73 2c 25 73 29 22 2c 20 7a 4d  fail(%s,%s)", zM
0d20: 65 74 68 6f 64 2c 20 70 2d 3e 7a 54 61 62 6c 65  ethod, p->zTable
0d30: 4e 61 6d 65 29 3b 0a 20 20 7a 45 72 72 20 3d 20  Name);.  zErr = 
0d40: 54 63 6c 5f 47 65 74 56 61 72 28 70 2d 3e 69 6e  Tcl_GetVar(p->in
0d50: 74 65 72 70 2c 20 7a 56 61 72 6e 61 6d 65 2c 20  terp, zVarname, 
0d60: 54 43 4c 5f 47 4c 4f 42 41 4c 5f 4f 4e 4c 59 29  TCL_GLOBAL_ONLY)
0d70: 3b 0a 20 20 69 66 28 20 7a 45 72 72 20 29 7b 0a  ;.  if( zErr ){.
0d80: 20 20 20 20 70 2d 3e 62 61 73 65 2e 7a 45 72 72      p->base.zErr
0d90: 4d 73 67 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70  Msg = sqlite3_mp
0da0: 72 69 6e 74 66 28 22 65 63 68 6f 2d 76 74 61 62  rintf("echo-vtab
0db0: 2d 65 72 72 6f 72 3a 20 25 73 22 2c 20 7a 45 72  -error: %s", zEr
0dc0: 72 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e  r);.  }.  return
0dd0: 20 28 7a 45 72 72 21 3d 30 29 3b 0a 7d 0a 0a 2f   (zErr!=0);.}../
0de0: 2a 0a 2a 2a 20 43 6f 6e 76 65 72 74 20 61 6e 20  *.** Convert an 
0df0: 53 51 4c 2d 73 74 79 6c 65 20 71 75 6f 74 65 64  SQL-style quoted
0e00: 20 73 74 72 69 6e 67 20 69 6e 74 6f 20 61 20 6e   string into a n
0e10: 6f 72 6d 61 6c 20 73 74 72 69 6e 67 20 62 79 20  ormal string by 
0e20: 72 65 6d 6f 76 69 6e 67 0a 2a 2a 20 74 68 65 20  removing.** the 
0e30: 71 75 6f 74 65 20 63 68 61 72 61 63 74 65 72 73  quote characters
0e40: 2e 20 20 54 68 65 20 63 6f 6e 76 65 72 73 69 6f  .  The conversio
0e50: 6e 20 69 73 20 64 6f 6e 65 20 69 6e 2d 70 6c 61  n is done in-pla
0e60: 63 65 2e 20 20 49 66 20 74 68 65 0a 2a 2a 20 69  ce.  If the.** i
0e70: 6e 70 75 74 20 64 6f 65 73 20 6e 6f 74 20 62 65  nput does not be
0e80: 67 69 6e 20 77 69 74 68 20 61 20 71 75 6f 74 65  gin with a quote
0e90: 20 63 68 61 72 61 63 74 65 72 2c 20 74 68 65 6e   character, then
0ea0: 20 74 68 69 73 20 72 6f 75 74 69 6e 65 0a 2a 2a   this routine.**
0eb0: 20 69 73 20 61 20 6e 6f 2d 6f 70 2e 0a 2a 2a 0a   is a no-op..**.
0ec0: 2a 2a 20 45 78 61 6d 70 6c 65 73 3a 0a 2a 2a 0a  ** Examples:.**.
0ed0: 2a 2a 20 20 20 20 20 22 61 62 63 22 20 20 20 62  **     "abc"   b
0ee0: 65 63 6f 6d 65 73 20 20 20 61 62 63 0a 2a 2a 20  ecomes   abc.** 
0ef0: 20 20 20 20 27 78 79 7a 27 20 20 20 62 65 63 6f      'xyz'   beco
0f00: 6d 65 73 20 20 20 78 79 7a 0a 2a 2a 20 20 20 20  mes   xyz.**    
0f10: 20 5b 70 71 72 5d 20 20 20 62 65 63 6f 6d 65 73   [pqr]   becomes
0f20: 20 20 20 70 71 72 0a 2a 2a 20 20 20 20 20 60 6d     pqr.**     `m
0f30: 6e 6f 60 20 20 20 62 65 63 6f 6d 65 73 20 20 20  no`   becomes   
0f40: 6d 6e 6f 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f  mno.*/.static vo
0f50: 69 64 20 64 65 71 75 6f 74 65 53 74 72 69 6e 67  id dequoteString
0f60: 28 63 68 61 72 20 2a 7a 29 7b 0a 20 20 69 6e 74  (char *z){.  int
0f70: 20 71 75 6f 74 65 3b 0a 20 20 69 6e 74 20 69 2c   quote;.  int i,
0f80: 20 6a 3b 0a 20 20 69 66 28 20 7a 3d 3d 30 20 29   j;.  if( z==0 )
0f90: 20 72 65 74 75 72 6e 3b 0a 20 20 71 75 6f 74 65   return;.  quote
0fa0: 20 3d 20 7a 5b 30 5d 3b 0a 20 20 73 77 69 74 63   = z[0];.  switc
0fb0: 68 28 20 71 75 6f 74 65 20 29 7b 0a 20 20 20 20  h( quote ){.    
0fc0: 63 61 73 65 20 27 5c 27 27 3a 20 20 62 72 65 61  case '\'':  brea
0fd0: 6b 3b 0a 20 20 20 20 63 61 73 65 20 27 22 27 3a  k;.    case '"':
0fe0: 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 63 61     break;.    ca
0ff0: 73 65 20 27 60 27 3a 20 20 20 62 72 65 61 6b 3b  se '`':   break;
1000: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1010: 2f 2a 20 46 6f 72 20 4d 79 53 51 4c 20 63 6f 6d  /* For MySQL com
1020: 70 61 74 69 62 69 6c 69 74 79 20 2a 2f 0a 20 20  patibility */.  
1030: 20 20 63 61 73 65 20 27 5b 27 3a 20 20 20 71 75    case '[':   qu
1040: 6f 74 65 20 3d 20 27 5d 27 3b 20 20 62 72 65 61  ote = ']';  brea
1050: 6b 3b 20 20 2f 2a 20 46 6f 72 20 4d 53 20 53 71  k;  /* For MS Sq
1060: 6c 53 65 72 76 65 72 20 63 6f 6d 70 61 74 69 62  lServer compatib
1070: 69 6c 69 74 79 20 2a 2f 0a 20 20 20 20 64 65 66  ility */.    def
1080: 61 75 6c 74 3a 20 20 20 20 72 65 74 75 72 6e 3b  ault:    return;
1090: 0a 20 20 7d 0a 20 20 66 6f 72 28 69 3d 31 2c 20  .  }.  for(i=1, 
10a0: 6a 3d 30 3b 20 7a 5b 69 5d 3b 20 69 2b 2b 29 7b  j=0; z[i]; i++){
10b0: 0a 20 20 20 20 69 66 28 20 7a 5b 69 5d 3d 3d 71  .    if( z[i]==q
10c0: 75 6f 74 65 20 29 7b 0a 20 20 20 20 20 20 69 66  uote ){.      if
10d0: 28 20 7a 5b 69 2b 31 5d 3d 3d 71 75 6f 74 65 20  ( z[i+1]==quote 
10e0: 29 7b 0a 20 20 20 20 20 20 20 20 7a 5b 6a 2b 2b  ){.        z[j++
10f0: 5d 20 3d 20 71 75 6f 74 65 3b 0a 20 20 20 20 20  ] = quote;.     
1100: 20 20 20 69 2b 2b 3b 0a 20 20 20 20 20 20 7d 65     i++;.      }e
1110: 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 7a 5b 6a  lse{.        z[j
1120: 2b 2b 5d 20 3d 20 30 3b 0a 20 20 20 20 20 20 20  ++] = 0;.       
1130: 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 7d 0a   break;.      }.
1140: 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20      }else{.     
1150: 20 7a 5b 6a 2b 2b 5d 20 3d 20 7a 5b 69 5d 3b 0a   z[j++] = z[i];.
1160: 20 20 20 20 7d 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a      }.  }.}../*.
1170: 2a 2a 20 52 65 74 72 69 65 76 65 20 74 68 65 20  ** Retrieve the 
1180: 63 6f 6c 75 6d 6e 20 6e 61 6d 65 73 20 66 6f 72  column names for
1190: 20 74 68 65 20 74 61 62 6c 65 20 6e 61 6d 65 64   the table named
11a0: 20 7a 54 61 62 20 76 69 61 20 64 61 74 61 62 61   zTab via databa
11b0: 73 65 0a 2a 2a 20 63 6f 6e 6e 65 63 74 69 6f 6e  se.** connection
11c0: 20 64 62 2e 20 53 51 4c 49 54 45 5f 4f 4b 20 69   db. SQLITE_OK i
11d0: 73 20 72 65 74 75 72 6e 65 64 20 6f 6e 20 73 75  s returned on su
11e0: 63 63 65 73 73 2c 20 6f 72 20 61 6e 20 73 71 6c  ccess, or an sql
11f0: 69 74 65 20 65 72 72 6f 72 0a 2a 2a 20 63 6f 64  ite error.** cod
1200: 65 20 6f 74 68 65 72 77 69 73 65 2e 0a 2a 2a 0a  e otherwise..**.
1210: 2a 2a 20 49 66 20 73 75 63 63 65 73 73 66 75 6c  ** If successful
1220: 2c 20 74 68 65 20 6e 75 6d 62 65 72 20 6f 66 20  , the number of 
1230: 63 6f 6c 75 6d 6e 73 20 69 73 20 77 72 69 74 74  columns is writt
1240: 65 6e 20 74 6f 20 2a 70 6e 43 6f 6c 2e 20 2a 70  en to *pnCol. *p
1250: 61 43 6f 6c 20 69 73 0a 2a 2a 20 73 65 74 20 74  aCol is.** set t
1260: 6f 20 70 6f 69 6e 74 20 61 74 20 73 71 6c 69 74  o point at sqlit
1270: 65 33 5f 6d 61 6c 6c 6f 63 28 29 27 64 20 73 70  e3_malloc()'d sp
1280: 61 63 65 20 63 6f 6e 74 61 69 6e 69 6e 67 20 74  ace containing t
1290: 68 65 20 61 72 72 61 79 20 6f 66 0a 2a 2a 20 6e  he array of.** n
12a0: 43 6f 6c 20 63 6f 6c 75 6d 6e 20 6e 61 6d 65 73  Col column names
12b0: 2e 20 54 68 65 20 63 61 6c 6c 65 72 20 69 73 20  . The caller is 
12c0: 72 65 73 70 6f 6e 73 69 62 6c 65 20 66 6f 72 20  responsible for 
12d0: 63 61 6c 6c 69 6e 67 20 73 71 6c 69 74 65 33 5f  calling sqlite3_
12e0: 66 72 65 65 0a 2a 2a 20 6f 6e 20 2a 70 61 43 6f  free.** on *paCo
12f0: 6c 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  l..*/.static int
1300: 20 67 65 74 43 6f 6c 75 6d 6e 4e 61 6d 65 73 28   getColumnNames(
1310: 0a 20 20 73 71 6c 69 74 65 33 20 2a 64 62 2c 20  .  sqlite3 *db, 
1320: 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a  .  const char *z
1330: 54 61 62 2c 0a 20 20 63 68 61 72 20 2a 2a 2a 70  Tab,.  char ***p
1340: 61 43 6f 6c 2c 20 0a 20 20 69 6e 74 20 2a 70 6e  aCol, .  int *pn
1350: 43 6f 6c 0a 29 7b 0a 20 20 63 68 61 72 20 2a 2a  Col.){.  char **
1360: 61 43 6f 6c 20 3d 20 30 3b 0a 20 20 63 68 61 72  aCol = 0;.  char
1370: 20 2a 7a 53 71 6c 3b 0a 20 20 73 71 6c 69 74 65   *zSql;.  sqlite
1380: 33 5f 73 74 6d 74 20 2a 70 53 74 6d 74 20 3d 20  3_stmt *pStmt = 
1390: 30 3b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51  0;.  int rc = SQ
13a0: 4c 49 54 45 5f 4f 4b 3b 0a 20 20 69 6e 74 20 6e  LITE_OK;.  int n
13b0: 43 6f 6c 20 3d 20 30 3b 0a 0a 20 20 2f 2a 20 50  Col = 0;..  /* P
13c0: 72 65 70 61 72 65 20 74 68 65 20 73 74 61 74 65  repare the state
13d0: 6d 65 6e 74 20 22 53 45 4c 45 43 54 20 2a 20 46  ment "SELECT * F
13e0: 52 4f 4d 20 3c 74 62 6c 3e 22 2e 20 54 68 65 20  ROM <tbl>". The 
13f0: 63 6f 6c 75 6d 6e 20 6e 61 6d 65 73 0a 20 20 2a  column names.  *
1400: 2a 20 6f 66 20 74 68 65 20 72 65 73 75 6c 74 20  * of the result 
1410: 73 65 74 20 6f 66 20 74 68 65 20 63 6f 6d 70 69  set of the compi
1420: 6c 65 64 20 53 45 4c 45 43 54 20 77 69 6c 6c 20  led SELECT will 
1430: 62 65 20 74 68 65 20 73 61 6d 65 20 61 73 0a 20  be the same as. 
1440: 20 2a 2a 20 74 68 65 20 63 6f 6c 75 6d 6e 20 6e   ** the column n
1450: 61 6d 65 73 20 6f 66 20 74 61 62 6c 65 20 3c 74  ames of table <t
1460: 62 6c 3e 2e 0a 20 20 2a 2f 0a 20 20 7a 53 71 6c  bl>..  */.  zSql
1470: 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e   = sqlite3_mprin
1480: 74 66 28 22 53 45 4c 45 43 54 20 2a 20 46 52 4f  tf("SELECT * FRO
1490: 4d 20 25 51 22 2c 20 7a 54 61 62 29 3b 0a 20 20  M %Q", zTab);.  
14a0: 69 66 28 20 21 7a 53 71 6c 20 29 7b 0a 20 20 20  if( !zSql ){.   
14b0: 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d   rc = SQLITE_NOM
14c0: 45 4d 3b 0a 20 20 20 20 67 6f 74 6f 20 6f 75 74  EM;.    goto out
14d0: 3b 0a 20 20 7d 0a 20 20 72 63 20 3d 20 73 71 6c  ;.  }.  rc = sql
14e0: 69 74 65 33 5f 70 72 65 70 61 72 65 28 64 62 2c  ite3_prepare(db,
14f0: 20 7a 53 71 6c 2c 20 2d 31 2c 20 26 70 53 74 6d   zSql, -1, &pStm
1500: 74 2c 20 30 29 3b 0a 20 20 73 71 6c 69 74 65 33  t, 0);.  sqlite3
1510: 5f 66 72 65 65 28 7a 53 71 6c 29 3b 0a 0a 20 20  _free(zSql);..  
1520: 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  if( rc==SQLITE_O
1530: 4b 20 29 7b 0a 20 20 20 20 69 6e 74 20 69 69 3b  K ){.    int ii;
1540: 0a 20 20 20 20 69 6e 74 20 6e 42 79 74 65 73 3b  .    int nBytes;
1550: 0a 20 20 20 20 63 68 61 72 20 2a 7a 53 70 61 63  .    char *zSpac
1560: 65 3b 0a 20 20 20 20 6e 43 6f 6c 20 3d 20 73 71  e;.    nCol = sq
1570: 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 63 6f 75  lite3_column_cou
1580: 6e 74 28 70 53 74 6d 74 29 3b 0a 0a 20 20 20 20  nt(pStmt);..    
1590: 2f 2a 20 46 69 67 75 72 65 20 6f 75 74 20 68 6f  /* Figure out ho
15a0: 77 20 6d 75 63 68 20 73 70 61 63 65 20 74 6f 20  w much space to 
15b0: 61 6c 6c 6f 63 61 74 65 20 66 6f 72 20 74 68 65  allocate for the
15c0: 20 61 72 72 61 79 20 6f 66 20 63 6f 6c 75 6d 6e   array of column
15d0: 20 6e 61 6d 65 73 20 0a 20 20 20 20 2a 2a 20 28   names .    ** (
15e0: 69 6e 63 6c 75 64 69 6e 67 20 73 70 61 63 65 20  including space 
15f0: 66 6f 72 20 74 68 65 20 73 74 72 69 6e 67 73 20  for the strings 
1600: 74 68 65 6d 73 65 6c 76 65 73 29 2e 20 54 68 65  themselves). The
1610: 6e 20 61 6c 6c 6f 63 61 74 65 20 69 74 2e 0a 20  n allocate it.. 
1620: 20 20 20 2a 2f 0a 20 20 20 20 6e 42 79 74 65 73     */.    nBytes
1630: 20 3d 20 73 69 7a 65 6f 66 28 63 68 61 72 20 2a   = sizeof(char *
1640: 29 20 2a 20 6e 43 6f 6c 3b 0a 20 20 20 20 66 6f  ) * nCol;.    fo
1650: 72 28 69 69 3d 30 3b 20 69 69 3c 6e 43 6f 6c 3b  r(ii=0; ii<nCol;
1660: 20 69 69 2b 2b 29 7b 0a 20 20 20 20 20 20 63 6f   ii++){.      co
1670: 6e 73 74 20 63 68 61 72 20 2a 7a 4e 61 6d 65 20  nst char *zName 
1680: 3d 20 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e  = sqlite3_column
1690: 5f 6e 61 6d 65 28 70 53 74 6d 74 2c 20 69 69 29  _name(pStmt, ii)
16a0: 3b 0a 20 20 20 20 20 20 69 66 28 20 21 7a 4e 61  ;.      if( !zNa
16b0: 6d 65 20 29 7b 0a 20 20 20 20 20 20 20 20 72 63  me ){.        rc
16c0: 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b   = SQLITE_NOMEM;
16d0: 0a 20 20 20 20 20 20 20 20 67 6f 74 6f 20 6f 75  .        goto ou
16e0: 74 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20  t;.      }.     
16f0: 20 6e 42 79 74 65 73 20 2b 3d 20 73 74 72 6c 65   nBytes += strle
1700: 6e 28 7a 4e 61 6d 65 29 2b 31 3b 0a 20 20 20 20  n(zName)+1;.    
1710: 7d 0a 20 20 20 20 61 43 6f 6c 20 3d 20 28 63 68  }.    aCol = (ch
1720: 61 72 20 2a 2a 29 73 71 6c 69 74 65 33 4d 61 6c  ar **)sqlite3Mal
1730: 6c 6f 63 5a 65 72 6f 28 6e 42 79 74 65 73 29 3b  locZero(nBytes);
1740: 0a 20 20 20 20 69 66 28 20 21 61 43 6f 6c 20 29  .    if( !aCol )
1750: 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c  {.      rc = SQL
1760: 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 20  ITE_NOMEM;.     
1770: 20 67 6f 74 6f 20 6f 75 74 3b 0a 20 20 20 20 7d   goto out;.    }
1780: 0a 0a 20 20 20 20 2f 2a 20 43 6f 70 79 20 74 68  ..    /* Copy th
1790: 65 20 63 6f 6c 75 6d 6e 20 6e 61 6d 65 73 20 69  e column names i
17a0: 6e 74 6f 20 74 68 65 20 61 6c 6c 6f 63 61 74 65  nto the allocate
17b0: 64 20 73 70 61 63 65 20 61 6e 64 20 73 65 74 20  d space and set 
17c0: 75 70 20 74 68 65 0a 20 20 20 20 2a 2a 20 70 6f  up the.    ** po
17d0: 69 6e 74 65 72 73 20 69 6e 20 74 68 65 20 61 43  inters in the aC
17e0: 6f 6c 5b 5d 20 61 72 72 61 79 2e 0a 20 20 20 20  ol[] array..    
17f0: 2a 2f 0a 20 20 20 20 7a 53 70 61 63 65 20 3d 20  */.    zSpace = 
1800: 28 63 68 61 72 20 2a 29 28 26 61 43 6f 6c 5b 6e  (char *)(&aCol[n
1810: 43 6f 6c 5d 29 3b 0a 20 20 20 20 66 6f 72 28 69  Col]);.    for(i
1820: 69 3d 30 3b 20 69 69 3c 6e 43 6f 6c 3b 20 69 69  i=0; ii<nCol; ii
1830: 2b 2b 29 7b 0a 20 20 20 20 20 20 61 43 6f 6c 5b  ++){.      aCol[
1840: 69 69 5d 20 3d 20 7a 53 70 61 63 65 3b 0a 20 20  ii] = zSpace;.  
1850: 20 20 20 20 7a 53 70 61 63 65 20 2b 3d 20 73 70      zSpace += sp
1860: 72 69 6e 74 66 28 7a 53 70 61 63 65 2c 20 22 25  rintf(zSpace, "%
1870: 73 22 2c 20 73 71 6c 69 74 65 33 5f 63 6f 6c 75  s", sqlite3_colu
1880: 6d 6e 5f 6e 61 6d 65 28 70 53 74 6d 74 2c 20 69  mn_name(pStmt, i
1890: 69 29 29 3b 0a 20 20 20 20 20 20 7a 53 70 61 63  i));.      zSpac
18a0: 65 2b 2b 3b 0a 20 20 20 20 7d 0a 20 20 20 20 61  e++;.    }.    a
18b0: 73 73 65 72 74 28 20 28 7a 53 70 61 63 65 2d 6e  ssert( (zSpace-n
18c0: 42 79 74 65 73 29 3d 3d 28 63 68 61 72 20 2a 29  Bytes)==(char *)
18d0: 61 43 6f 6c 20 29 3b 0a 20 20 7d 0a 0a 20 20 2a  aCol );.  }..  *
18e0: 70 61 43 6f 6c 20 3d 20 61 43 6f 6c 3b 0a 20 20  paCol = aCol;.  
18f0: 2a 70 6e 43 6f 6c 20 3d 20 6e 43 6f 6c 3b 0a 0a  *pnCol = nCol;..
1900: 6f 75 74 3a 0a 20 20 73 71 6c 69 74 65 33 5f 66  out:.  sqlite3_f
1910: 69 6e 61 6c 69 7a 65 28 70 53 74 6d 74 29 3b 0a  inalize(pStmt);.
1920: 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a    return rc;.}..
1930: 2f 2a 0a 2a 2a 20 50 61 72 61 6d 65 74 65 72 20  /*.** Parameter 
1940: 7a 54 61 62 20 69 73 20 74 68 65 20 6e 61 6d 65  zTab is the name
1950: 20 6f 66 20 61 20 74 61 62 6c 65 20 69 6e 20 64   of a table in d
1960: 61 74 61 62 61 73 65 20 64 62 20 77 69 74 68 20  atabase db with 
1970: 6e 43 6f 6c 20 0a 2a 2a 20 63 6f 6c 75 6d 6e 73  nCol .** columns
1980: 2e 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20  . This function 
1990: 61 6c 6c 6f 63 61 74 65 73 20 61 6e 20 61 72 72  allocates an arr
19a0: 61 79 20 6f 66 20 69 6e 74 65 67 65 72 73 20 6e  ay of integers n
19b0: 43 6f 6c 20 69 6e 20 0a 2a 2a 20 73 69 7a 65 20  Col in .** size 
19c0: 61 6e 64 20 70 6f 70 75 6c 61 74 65 73 20 69 74  and populates it
19d0: 20 61 63 63 6f 72 64 69 6e 67 20 74 6f 20 61 6e   according to an
19e0: 79 20 69 6d 70 6c 69 63 69 74 20 6f 72 20 65 78  y implicit or ex
19f0: 70 6c 69 63 69 74 20 0a 2a 2a 20 69 6e 64 69 63  plicit .** indic
1a00: 65 73 20 6f 6e 20 74 61 62 6c 65 20 7a 54 61 62  es on table zTab
1a10: 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 73 75 63 63 65  ..**.** If succe
1a20: 73 73 66 75 6c 2c 20 53 51 4c 49 54 45 5f 4f 4b  ssful, SQLITE_OK
1a30: 20 69 73 20 72 65 74 75 72 6e 65 64 20 61 6e 64   is returned and
1a40: 20 2a 70 61 49 6e 64 65 78 20 73 65 74 20 74 6f   *paIndex set to
1a50: 20 70 6f 69 6e 74 20 0a 2a 2a 20 61 74 20 74 68   point .** at th
1a60: 65 20 61 6c 6c 6f 63 61 74 65 64 20 61 72 72 61  e allocated arra
1a70: 79 2e 20 4f 74 68 65 72 77 69 73 65 2c 20 61 6e  y. Otherwise, an
1a80: 20 65 72 72 6f 72 20 63 6f 64 65 20 69 73 20 72   error code is r
1a90: 65 74 75 72 6e 65 64 2e 0a 2a 2a 0a 2a 2a 20 53  eturned..**.** S
1aa0: 65 65 20 63 6f 6d 6d 65 6e 74 73 20 61 73 73 6f  ee comments asso
1ab0: 63 69 61 74 65 64 20 77 69 74 68 20 74 68 65 20  ciated with the 
1ac0: 6d 65 6d 62 65 72 20 76 61 72 69 61 62 6c 65 20  member variable 
1ad0: 61 49 6e 64 65 78 20 61 62 6f 76 65 20 0a 2a 2a  aIndex above .**
1ae0: 20 22 73 74 72 75 63 74 20 65 63 68 6f 5f 76 74   "struct echo_vt
1af0: 61 62 22 20 66 6f 72 20 64 65 74 61 69 6c 73 20  ab" for details 
1b00: 6f 66 20 74 68 65 20 63 6f 6e 74 65 6e 74 73 20  of the contents 
1b10: 6f 66 20 74 68 65 20 61 72 72 61 79 2e 0a 2a 2f  of the array..*/
1b20: 0a 73 74 61 74 69 63 20 69 6e 74 20 67 65 74 49  .static int getI
1b30: 6e 64 65 78 41 72 72 61 79 28 0a 20 20 73 71 6c  ndexArray(.  sql
1b40: 69 74 65 33 20 2a 64 62 2c 20 20 20 20 20 20 20  ite3 *db,       
1b50: 20 20 20 20 20 20 2f 2a 20 44 61 74 61 62 61 73        /* Databas
1b60: 65 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 2a 2f 0a  e connection */.
1b70: 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 54    const char *zT
1b80: 61 62 2c 20 20 20 20 20 20 20 20 2f 2a 20 4e 61  ab,        /* Na
1b90: 6d 65 20 6f 66 20 74 61 62 6c 65 20 69 6e 20 64  me of table in d
1ba0: 61 74 61 62 61 73 65 20 64 62 20 2a 2f 0a 20 20  atabase db */.  
1bb0: 69 6e 74 20 6e 43 6f 6c 2c 0a 20 20 69 6e 74 20  int nCol,.  int 
1bc0: 2a 2a 70 61 49 6e 64 65 78 0a 29 7b 0a 20 20 73  **paIndex.){.  s
1bd0: 71 6c 69 74 65 33 5f 73 74 6d 74 20 2a 70 53 74  qlite3_stmt *pSt
1be0: 6d 74 20 3d 20 30 3b 0a 20 20 69 6e 74 20 2a 61  mt = 0;.  int *a
1bf0: 49 6e 64 65 78 20 3d 20 30 3b 0a 20 20 69 6e 74  Index = 0;.  int
1c00: 20 72 63 3b 0a 20 20 63 68 61 72 20 2a 7a 53 71   rc;.  char *zSq
1c10: 6c 3b 0a 0a 20 20 2f 2a 20 41 6c 6c 6f 63 61 74  l;..  /* Allocat
1c20: 65 20 73 70 61 63 65 20 66 6f 72 20 74 68 65 20  e space for the 
1c30: 69 6e 64 65 78 20 61 72 72 61 79 20 2a 2f 0a 20  index array */. 
1c40: 20 61 49 6e 64 65 78 20 3d 20 28 69 6e 74 20 2a   aIndex = (int *
1c50: 29 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63 5a 65  )sqlite3MallocZe
1c60: 72 6f 28 73 69 7a 65 6f 66 28 69 6e 74 29 20 2a  ro(sizeof(int) *
1c70: 20 6e 43 6f 6c 29 3b 0a 20 20 69 66 28 20 21 61   nCol);.  if( !a
1c80: 49 6e 64 65 78 20 29 7b 0a 20 20 20 20 72 63 20  Index ){.    rc 
1c90: 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a  = SQLITE_NOMEM;.
1ca0: 20 20 20 20 67 6f 74 6f 20 67 65 74 5f 69 6e 64      goto get_ind
1cb0: 65 78 5f 61 72 72 61 79 5f 6f 75 74 3b 0a 20 20  ex_array_out;.  
1cc0: 7d 0a 0a 20 20 2f 2a 20 43 6f 6d 70 69 6c 65 20  }..  /* Compile 
1cd0: 61 6e 20 73 71 6c 69 74 65 20 70 72 61 67 6d 61  an sqlite pragma
1ce0: 20 74 6f 20 6c 6f 6f 70 20 74 68 72 6f 75 67 68   to loop through
1cf0: 20 61 6c 6c 20 69 6e 64 69 63 65 73 20 6f 6e 20   all indices on 
1d00: 74 61 62 6c 65 20 7a 54 61 62 20 2a 2f 0a 20 20  table zTab */.  
1d10: 7a 53 71 6c 20 3d 20 73 71 6c 69 74 65 33 4d 50  zSql = sqlite3MP
1d20: 72 69 6e 74 66 28 30 2c 20 22 50 52 41 47 4d 41  rintf(0, "PRAGMA
1d30: 20 69 6e 64 65 78 5f 6c 69 73 74 28 25 73 29 22   index_list(%s)"
1d40: 2c 20 7a 54 61 62 29 3b 0a 20 20 69 66 28 20 21  , zTab);.  if( !
1d50: 7a 53 71 6c 20 29 7b 0a 20 20 20 20 72 63 20 3d  zSql ){.    rc =
1d60: 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20   SQLITE_NOMEM;. 
1d70: 20 20 20 67 6f 74 6f 20 67 65 74 5f 69 6e 64 65     goto get_inde
1d80: 78 5f 61 72 72 61 79 5f 6f 75 74 3b 0a 20 20 7d  x_array_out;.  }
1d90: 0a 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f  .  rc = sqlite3_
1da0: 70 72 65 70 61 72 65 28 64 62 2c 20 7a 53 71 6c  prepare(db, zSql
1db0: 2c 20 2d 31 2c 20 26 70 53 74 6d 74 2c 20 30 29  , -1, &pStmt, 0)
1dc0: 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65  ;.  sqlite3_free
1dd0: 28 7a 53 71 6c 29 3b 0a 0a 20 20 2f 2a 20 46 6f  (zSql);..  /* Fo
1de0: 72 20 65 61 63 68 20 69 6e 64 65 78 2c 20 66 69  r each index, fi
1df0: 67 75 72 65 20 6f 75 74 20 74 68 65 20 6c 65 66  gure out the lef
1e00: 74 2d 6d 6f 73 74 20 63 6f 6c 75 6d 6e 20 61 6e  t-most column an
1e10: 64 20 73 65 74 20 74 68 65 20 0a 20 20 2a 2a 20  d set the .  ** 
1e20: 63 6f 72 72 65 73 70 6f 6e 64 69 6e 67 20 65 6e  corresponding en
1e30: 74 72 79 20 69 6e 20 61 49 6e 64 65 78 5b 5d 20  try in aIndex[] 
1e40: 74 6f 20 31 2e 0a 20 20 2a 2f 0a 20 20 77 68 69  to 1..  */.  whi
1e50: 6c 65 28 20 70 53 74 6d 74 20 26 26 20 73 71 6c  le( pStmt && sql
1e60: 69 74 65 33 5f 73 74 65 70 28 70 53 74 6d 74 29  ite3_step(pStmt)
1e70: 3d 3d 53 51 4c 49 54 45 5f 52 4f 57 20 29 7b 0a  ==SQLITE_ROW ){.
1e80: 20 20 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a      const char *
1e90: 7a 49 64 78 20 3d 20 28 63 6f 6e 73 74 20 63 68  zIdx = (const ch
1ea0: 61 72 20 2a 29 73 71 6c 69 74 65 33 5f 63 6f 6c  ar *)sqlite3_col
1eb0: 75 6d 6e 5f 74 65 78 74 28 70 53 74 6d 74 2c 20  umn_text(pStmt, 
1ec0: 31 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f  1);.    sqlite3_
1ed0: 73 74 6d 74 20 2a 70 53 74 6d 74 32 20 3d 20 30  stmt *pStmt2 = 0
1ee0: 3b 0a 20 20 20 20 7a 53 71 6c 20 3d 20 73 71 6c  ;.    zSql = sql
1ef0: 69 74 65 33 4d 50 72 69 6e 74 66 28 30 2c 20 22  ite3MPrintf(0, "
1f00: 50 52 41 47 4d 41 20 69 6e 64 65 78 5f 69 6e 66  PRAGMA index_inf
1f10: 6f 28 25 73 29 22 2c 20 7a 49 64 78 29 3b 0a 20  o(%s)", zIdx);. 
1f20: 20 20 20 69 66 28 20 21 7a 53 71 6c 20 29 7b 0a     if( !zSql ){.
1f30: 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54        rc = SQLIT
1f40: 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 20 20 67  E_NOMEM;.      g
1f50: 6f 74 6f 20 67 65 74 5f 69 6e 64 65 78 5f 61 72  oto get_index_ar
1f60: 72 61 79 5f 6f 75 74 3b 0a 20 20 20 20 7d 0a 20  ray_out;.    }. 
1f70: 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f     rc = sqlite3_
1f80: 70 72 65 70 61 72 65 28 64 62 2c 20 7a 53 71 6c  prepare(db, zSql
1f90: 2c 20 2d 31 2c 20 26 70 53 74 6d 74 32 2c 20 30  , -1, &pStmt2, 0
1fa0: 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 66  );.    sqlite3_f
1fb0: 72 65 65 28 7a 53 71 6c 29 3b 0a 20 20 20 20 69  ree(zSql);.    i
1fc0: 66 28 20 70 53 74 6d 74 32 20 26 26 20 73 71 6c  f( pStmt2 && sql
1fd0: 69 74 65 33 5f 73 74 65 70 28 70 53 74 6d 74 32  ite3_step(pStmt2
1fe0: 29 3d 3d 53 51 4c 49 54 45 5f 52 4f 57 20 29 7b  )==SQLITE_ROW ){
1ff0: 0a 20 20 20 20 20 20 69 6e 74 20 63 69 64 20 3d  .      int cid =
2000: 20 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f   sqlite3_column_
2010: 69 6e 74 28 70 53 74 6d 74 32 2c 20 31 29 3b 0a  int(pStmt2, 1);.
2020: 20 20 20 20 20 20 61 73 73 65 72 74 28 20 63 69        assert( ci
2030: 64 3e 3d 30 20 26 26 20 63 69 64 3c 6e 43 6f 6c  d>=0 && cid<nCol
2040: 20 29 3b 0a 20 20 20 20 20 20 61 49 6e 64 65 78   );.      aIndex
2050: 5b 63 69 64 5d 20 3d 20 31 3b 0a 20 20 20 20 7d  [cid] = 1;.    }
2060: 0a 20 20 20 20 69 66 28 20 70 53 74 6d 74 32 20  .    if( pStmt2 
2070: 29 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 73 71  ){.      rc = sq
2080: 6c 69 74 65 33 5f 66 69 6e 61 6c 69 7a 65 28 70  lite3_finalize(p
2090: 53 74 6d 74 32 29 3b 0a 20 20 20 20 7d 0a 20 20  Stmt2);.    }.  
20a0: 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45    if( rc!=SQLITE
20b0: 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 67 6f 74  _OK ){.      got
20c0: 6f 20 67 65 74 5f 69 6e 64 65 78 5f 61 72 72 61  o get_index_arra
20d0: 79 5f 6f 75 74 3b 0a 20 20 20 20 7d 0a 20 20 7d  y_out;.    }.  }
20e0: 0a 0a 0a 67 65 74 5f 69 6e 64 65 78 5f 61 72 72  ...get_index_arr
20f0: 61 79 5f 6f 75 74 3a 0a 20 20 69 66 28 20 70 53  ay_out:.  if( pS
2100: 74 6d 74 20 29 7b 0a 20 20 20 20 69 6e 74 20 72  tmt ){.    int r
2110: 63 32 20 3d 20 73 71 6c 69 74 65 33 5f 66 69 6e  c2 = sqlite3_fin
2120: 61 6c 69 7a 65 28 70 53 74 6d 74 29 3b 0a 20 20  alize(pStmt);.  
2130: 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
2140: 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 72 63 20  _OK ){.      rc 
2150: 3d 20 72 63 32 3b 0a 20 20 20 20 7d 0a 20 20 7d  = rc2;.    }.  }
2160: 0a 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54  .  if( rc!=SQLIT
2170: 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 73 71 6c 69  E_OK ){.    sqli
2180: 74 65 33 5f 66 72 65 65 28 61 49 6e 64 65 78 29  te3_free(aIndex)
2190: 3b 0a 20 20 20 20 61 49 6e 64 65 78 20 3d 20 30  ;.    aIndex = 0
21a0: 3b 0a 20 20 7d 0a 20 20 2a 70 61 49 6e 64 65 78  ;.  }.  *paIndex
21b0: 20 3d 20 61 49 6e 64 65 78 3b 0a 20 20 72 65 74   = aIndex;.  ret
21c0: 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  urn rc;.}../*.**
21d0: 20 47 6c 6f 62 61 6c 20 54 63 6c 20 76 61 72 69   Global Tcl vari
21e0: 61 62 6c 65 20 24 65 63 68 6f 5f 6d 6f 64 75 6c  able $echo_modul
21f0: 65 20 69 73 20 61 20 6c 69 73 74 2e 20 54 68 69  e is a list. Thi
2200: 73 20 72 6f 75 74 69 6e 65 20 61 70 70 65 6e 64  s routine append
2210: 73 0a 2a 2a 20 74 68 65 20 73 74 72 69 6e 67 20  s.** the string 
2220: 65 6c 65 6d 65 6e 74 20 7a 41 72 67 20 74 6f 20  element zArg to 
2230: 74 68 61 74 20 6c 69 73 74 20 69 6e 20 69 6e 74  that list in int
2240: 65 72 70 72 65 74 65 72 20 69 6e 74 65 72 70 2e  erpreter interp.
2250: 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20  .*/.static void 
2260: 61 70 70 65 6e 64 54 6f 45 63 68 6f 4d 6f 64 75  appendToEchoModu
2270: 6c 65 28 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69  le(Tcl_Interp *i
2280: 6e 74 65 72 70 2c 20 63 6f 6e 73 74 20 63 68 61  nterp, const cha
2290: 72 20 2a 7a 41 72 67 29 7b 0a 20 20 69 6e 74 20  r *zArg){.  int 
22a0: 66 6c 61 67 73 20 3d 20 28 54 43 4c 5f 41 50 50  flags = (TCL_APP
22b0: 45 4e 44 5f 56 41 4c 55 45 20 7c 20 54 43 4c 5f  END_VALUE | TCL_
22c0: 4c 49 53 54 5f 45 4c 45 4d 45 4e 54 20 7c 20 54  LIST_ELEMENT | T
22d0: 43 4c 5f 47 4c 4f 42 41 4c 5f 4f 4e 4c 59 29 3b  CL_GLOBAL_ONLY);
22e0: 0a 20 20 54 63 6c 5f 53 65 74 56 61 72 28 69 6e  .  Tcl_SetVar(in
22f0: 74 65 72 70 2c 20 22 65 63 68 6f 5f 6d 6f 64 75  terp, "echo_modu
2300: 6c 65 22 2c 20 28 7a 41 72 67 3f 7a 41 72 67 3a  le", (zArg?zArg:
2310: 22 22 29 2c 20 66 6c 61 67 73 29 3b 0a 7d 0a 0a  ""), flags);.}..
2320: 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63 74  /*.** This funct
2330: 69 6f 6e 20 69 73 20 63 61 6c 6c 65 64 20 66 72  ion is called fr
2340: 6f 6d 20 77 69 74 68 69 6e 20 74 68 65 20 65 63  om within the ec
2350: 68 6f 2d 6d 6f 64 75 6c 65 73 20 78 43 72 65 61  ho-modules xCrea
2360: 74 65 20 61 6e 64 0a 2a 2a 20 78 43 6f 6e 6e 65  te and.** xConne
2370: 63 74 20 6d 65 74 68 6f 64 73 2e 20 54 68 65 20  ct methods. The 
2380: 61 72 67 63 20 61 6e 64 20 61 72 67 76 20 61 72  argc and argv ar
2390: 67 75 6d 65 6e 74 73 20 61 72 65 20 63 6f 70 69  guments are copi
23a0: 65 73 20 6f 66 20 74 68 6f 73 65 20 0a 2a 2a 20  es of those .** 
23b0: 70 61 73 73 65 64 20 74 6f 20 74 68 65 20 63 61  passed to the ca
23c0: 6c 6c 69 6e 67 20 6d 65 74 68 6f 64 2e 20 54 68  lling method. Th
23d0: 69 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 72  is function is r
23e0: 65 73 70 6f 6e 73 69 62 6c 65 20 66 6f 72 0a 2a  esponsible for.*
23f0: 2a 20 63 61 6c 6c 69 6e 67 20 73 71 6c 69 74 65  * calling sqlite
2400: 33 5f 64 65 63 6c 61 72 65 5f 76 74 61 62 28 29  3_declare_vtab()
2410: 20 74 6f 20 64 65 63 6c 61 72 65 20 74 68 65 20   to declare the 
2420: 73 63 68 65 6d 61 20 6f 66 20 74 68 65 20 76 69  schema of the vi
2430: 72 74 75 61 6c 0a 2a 2a 20 74 61 62 6c 65 20 62  rtual.** table b
2440: 65 69 6e 67 20 63 72 65 61 74 65 64 20 6f 72 20  eing created or 
2450: 63 6f 6e 6e 65 63 74 65 64 2e 0a 2a 2a 0a 2a 2a  connected..**.**
2460: 20 49 66 20 74 68 65 20 63 6f 6e 73 74 72 75 63   If the construc
2470: 74 6f 72 20 77 61 73 20 70 61 73 73 65 64 20 6a  tor was passed j
2480: 75 73 74 20 6f 6e 65 20 61 72 67 75 6d 65 6e 74  ust one argument
2490: 2c 20 69 2e 65 2e 3a 0a 2a 2a 0a 2a 2a 20 20 20  , i.e.:.**.**   
24a0: 43 52 45 41 54 45 20 54 41 42 4c 45 20 74 31 20  CREATE TABLE t1 
24b0: 41 53 20 65 63 68 6f 28 74 32 29 3b 0a 2a 2a 0a  AS echo(t2);.**.
24c0: 2a 2a 20 54 68 65 6e 20 74 32 20 69 73 20 61 73  ** Then t2 is as
24d0: 73 75 6d 65 64 20 74 6f 20 62 65 20 74 68 65 20  sumed to be the 
24e0: 6e 61 6d 65 20 6f 66 20 61 20 2a 72 65 61 6c 2a  name of a *real*
24f0: 20 64 61 74 61 62 61 73 65 20 74 61 62 6c 65 2e   database table.
2500: 20 54 68 65 0a 2a 2a 20 73 63 68 65 6d 61 20 6f   The.** schema o
2510: 66 20 74 68 65 20 76 69 72 74 75 61 6c 20 74 61  f the virtual ta
2520: 62 6c 65 20 69 73 20 64 65 63 6c 61 72 65 64 20  ble is declared 
2530: 62 79 20 70 61 73 73 69 6e 67 20 61 20 63 6f 70  by passing a cop
2540: 79 20 6f 66 20 74 68 65 20 0a 2a 2a 20 43 52 45  y of the .** CRE
2550: 41 54 45 20 54 41 42 4c 45 20 73 74 61 74 65 6d  ATE TABLE statem
2560: 65 6e 74 20 66 6f 72 20 74 68 65 20 72 65 61 6c  ent for the real
2570: 20 74 61 62 6c 65 20 74 6f 20 73 71 6c 69 74 65   table to sqlite
2580: 33 5f 64 65 63 6c 61 72 65 5f 76 74 61 62 28 29  3_declare_vtab()
2590: 2e 0a 2a 2a 20 48 65 6e 63 65 2c 20 74 68 65 20  ..** Hence, the 
25a0: 76 69 72 74 75 61 6c 20 74 61 62 6c 65 20 73 68  virtual table sh
25b0: 6f 75 6c 64 20 68 61 76 65 20 65 78 61 63 74 6c  ould have exactl
25c0: 79 20 74 68 65 20 73 61 6d 65 20 63 6f 6c 75 6d  y the same colum
25d0: 6e 20 6e 61 6d 65 73 20 61 6e 64 20 0a 2a 2a 20  n names and .** 
25e0: 74 79 70 65 73 20 61 73 20 74 68 65 20 72 65 61  types as the rea
25f0: 6c 20 74 61 62 6c 65 2e 0a 2a 2f 0a 73 74 61 74  l table..*/.stat
2600: 69 63 20 69 6e 74 20 65 63 68 6f 44 65 63 6c 61  ic int echoDecla
2610: 72 65 56 74 61 62 28 0a 20 20 65 63 68 6f 5f 76  reVtab(.  echo_v
2620: 74 61 62 20 2a 70 56 74 61 62 2c 20 0a 20 20 73  tab *pVtab, .  s
2630: 71 6c 69 74 65 33 20 2a 64 62 20 0a 29 7b 0a 20  qlite3 *db .){. 
2640: 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45   int rc = SQLITE
2650: 5f 4f 4b 3b 0a 0a 20 20 69 66 28 20 70 56 74 61  _OK;..  if( pVta
2660: 62 2d 3e 7a 54 61 62 6c 65 4e 61 6d 65 20 29 7b  b->zTableName ){
2670: 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 73 74 6d  .    sqlite3_stm
2680: 74 20 2a 70 53 74 6d 74 20 3d 20 30 3b 0a 20 20  t *pStmt = 0;.  
2690: 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 70    rc = sqlite3_p
26a0: 72 65 70 61 72 65 28 64 62 2c 20 0a 20 20 20 20  repare(db, .    
26b0: 20 20 20 20 22 53 45 4c 45 43 54 20 73 71 6c 20      "SELECT sql 
26c0: 46 52 4f 4d 20 73 71 6c 69 74 65 5f 6d 61 73 74  FROM sqlite_mast
26d0: 65 72 20 57 48 45 52 45 20 74 79 70 65 20 3d 20  er WHERE type = 
26e0: 27 74 61 62 6c 65 27 20 41 4e 44 20 6e 61 6d 65  'table' AND name
26f0: 20 3d 20 3f 22 2c 0a 20 20 20 20 20 20 20 20 2d   = ?",.        -
2700: 31 2c 20 26 70 53 74 6d 74 2c 20 30 29 3b 0a 20  1, &pStmt, 0);. 
2710: 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54     if( rc==SQLIT
2720: 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 73 71  E_OK ){.      sq
2730: 6c 69 74 65 33 5f 62 69 6e 64 5f 74 65 78 74 28  lite3_bind_text(
2740: 70 53 74 6d 74 2c 20 31 2c 20 70 56 74 61 62 2d  pStmt, 1, pVtab-
2750: 3e 7a 54 61 62 6c 65 4e 61 6d 65 2c 20 2d 31 2c  >zTableName, -1,
2760: 20 30 29 3b 0a 20 20 20 20 20 20 69 66 28 20 73   0);.      if( s
2770: 71 6c 69 74 65 33 5f 73 74 65 70 28 70 53 74 6d  qlite3_step(pStm
2780: 74 29 3d 3d 53 51 4c 49 54 45 5f 52 4f 57 20 29  t)==SQLITE_ROW )
2790: 7b 0a 20 20 20 20 20 20 20 20 69 6e 74 20 72 63  {.        int rc
27a0: 32 3b 0a 20 20 20 20 20 20 20 20 63 6f 6e 73 74  2;.        const
27b0: 20 63 68 61 72 20 2a 7a 43 72 65 61 74 65 54 61   char *zCreateTa
27c0: 62 6c 65 20 3d 20 28 63 6f 6e 73 74 20 63 68 61  ble = (const cha
27d0: 72 20 2a 29 73 71 6c 69 74 65 33 5f 63 6f 6c 75  r *)sqlite3_colu
27e0: 6d 6e 5f 74 65 78 74 28 70 53 74 6d 74 2c 20 30  mn_text(pStmt, 0
27f0: 29 3b 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20  );.        rc = 
2800: 73 71 6c 69 74 65 33 5f 64 65 63 6c 61 72 65 5f  sqlite3_declare_
2810: 76 74 61 62 28 64 62 2c 20 7a 43 72 65 61 74 65  vtab(db, zCreate
2820: 54 61 62 6c 65 29 3b 0a 20 20 20 20 20 20 20 20  Table);.        
2830: 72 63 32 20 3d 20 73 71 6c 69 74 65 33 5f 66 69  rc2 = sqlite3_fi
2840: 6e 61 6c 69 7a 65 28 70 53 74 6d 74 29 3b 0a 20  nalize(pStmt);. 
2850: 20 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d 53         if( rc==S
2860: 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
2870: 20 20 20 20 20 20 72 63 20 3d 20 72 63 32 3b 0a        rc = rc2;.
2880: 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20          }.      
2890: 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20 20 20 20  } else {.       
28a0: 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 66 69   rc = sqlite3_fi
28b0: 6e 61 6c 69 7a 65 28 70 53 74 6d 74 29 3b 0a 20  nalize(pStmt);. 
28c0: 20 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d 53         if( rc==S
28d0: 51 4c 49 54 45 5f 4f 4b 20 29 7b 20 0a 20 20 20  QLITE_OK ){ .   
28e0: 20 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c 49         rc = SQLI
28f0: 54 45 5f 45 52 52 4f 52 3b 0a 20 20 20 20 20 20  TE_ERROR;.      
2900: 20 20 7d 0a 20 20 20 20 20 20 7d 0a 20 20 20 20    }.      }.    
2910: 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
2920: 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20 20 72  _OK ){.        r
2930: 63 20 3d 20 67 65 74 43 6f 6c 75 6d 6e 4e 61 6d  c = getColumnNam
2940: 65 73 28 64 62 2c 20 70 56 74 61 62 2d 3e 7a 54  es(db, pVtab->zT
2950: 61 62 6c 65 4e 61 6d 65 2c 20 26 70 56 74 61 62  ableName, &pVtab
2960: 2d 3e 61 43 6f 6c 2c 20 26 70 56 74 61 62 2d 3e  ->aCol, &pVtab->
2970: 6e 43 6f 6c 29 3b 0a 20 20 20 20 20 20 7d 0a 20  nCol);.      }. 
2980: 20 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c       if( rc==SQL
2990: 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20  ITE_OK ){.      
29a0: 20 20 72 63 20 3d 20 67 65 74 49 6e 64 65 78 41    rc = getIndexA
29b0: 72 72 61 79 28 64 62 2c 20 70 56 74 61 62 2d 3e  rray(db, pVtab->
29c0: 7a 54 61 62 6c 65 4e 61 6d 65 2c 20 70 56 74 61  zTableName, pVta
29d0: 62 2d 3e 6e 43 6f 6c 2c 20 26 70 56 74 61 62 2d  b->nCol, &pVtab-
29e0: 3e 61 49 6e 64 65 78 29 3b 0a 20 20 20 20 20 20  >aIndex);.      
29f0: 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 72  }.    }.  }..  r
2a00: 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a  eturn rc;.}../*.
2a10: 2a 2a 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e  ** This function
2a20: 20 66 72 65 65 73 20 61 6c 6c 20 72 75 6e 74 69   frees all runti
2a30: 6d 65 20 73 74 72 75 63 74 75 72 65 73 20 61 73  me structures as
2a40: 73 6f 63 69 61 74 65 64 20 77 69 74 68 20 74 68  sociated with th
2a50: 65 20 76 69 72 74 75 61 6c 0a 2a 2a 20 74 61 62  e virtual.** tab
2a60: 6c 65 20 70 56 74 61 62 2e 0a 2a 2f 0a 73 74 61  le pVtab..*/.sta
2a70: 74 69 63 20 69 6e 74 20 65 63 68 6f 44 65 73 74  tic int echoDest
2a80: 72 75 63 74 6f 72 28 73 71 6c 69 74 65 33 5f 76  ructor(sqlite3_v
2a90: 74 61 62 20 2a 70 56 74 61 62 29 7b 0a 20 20 65  tab *pVtab){.  e
2aa0: 63 68 6f 5f 76 74 61 62 20 2a 70 20 3d 20 28 65  cho_vtab *p = (e
2ab0: 63 68 6f 5f 76 74 61 62 2a 29 70 56 74 61 62 3b  cho_vtab*)pVtab;
2ac0: 0a 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28  .  sqlite3_free(
2ad0: 70 2d 3e 61 49 6e 64 65 78 29 3b 0a 20 20 73 71  p->aIndex);.  sq
2ae0: 6c 69 74 65 33 5f 66 72 65 65 28 70 2d 3e 61 43  lite3_free(p->aC
2af0: 6f 6c 29 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66  ol);.  sqlite3_f
2b00: 72 65 65 28 70 2d 3e 7a 54 68 69 73 29 3b 0a 20  ree(p->zThis);. 
2b10: 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70 2d   sqlite3_free(p-
2b20: 3e 7a 54 61 62 6c 65 4e 61 6d 65 29 3b 0a 20 20  >zTableName);.  
2b30: 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70 2d 3e  sqlite3_free(p->
2b40: 7a 4c 6f 67 4e 61 6d 65 29 3b 0a 20 20 73 71 6c  zLogName);.  sql
2b50: 69 74 65 33 5f 66 72 65 65 28 70 29 3b 0a 20 20  ite3_free(p);.  
2b60: 72 65 74 75 72 6e 20 30 3b 0a 7d 0a 0a 74 79 70  return 0;.}..typ
2b70: 65 64 65 66 20 73 74 72 75 63 74 20 45 63 68 6f  edef struct Echo
2b80: 4d 6f 64 75 6c 65 20 45 63 68 6f 4d 6f 64 75 6c  Module EchoModul
2b90: 65 3b 0a 73 74 72 75 63 74 20 45 63 68 6f 4d 6f  e;.struct EchoMo
2ba0: 64 75 6c 65 20 7b 0a 20 20 54 63 6c 5f 49 6e 74  dule {.  Tcl_Int
2bb0: 65 72 70 20 2a 69 6e 74 65 72 70 3b 0a 7d 3b 0a  erp *interp;.};.
2bc0: 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63  ./*.** This func
2bd0: 74 69 6f 6e 20 69 73 20 63 61 6c 6c 65 64 20 74  tion is called t
2be0: 6f 20 64 6f 20 74 68 65 20 77 6f 72 6b 20 6f 66  o do the work of
2bf0: 20 74 68 65 20 78 43 6f 6e 6e 65 63 74 28 29 20   the xConnect() 
2c00: 6d 65 74 68 6f 64 20 2d 0a 2a 2a 20 74 6f 20 61  method -.** to a
2c10: 6c 6c 6f 63 61 74 65 20 74 68 65 20 72 65 71 75  llocate the requ
2c20: 69 72 65 64 20 69 6e 2d 6d 65 6d 6f 72 79 20 73  ired in-memory s
2c30: 74 72 75 63 74 75 72 65 73 20 66 6f 72 20 61 20  tructures for a 
2c40: 6e 65 77 6c 79 20 63 6f 6e 6e 65 63 74 65 64 0a  newly connected.
2c50: 2a 2a 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65  ** virtual table
2c60: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
2c70: 65 63 68 6f 43 6f 6e 73 74 72 75 63 74 6f 72 28  echoConstructor(
2c80: 0a 20 20 73 71 6c 69 74 65 33 20 2a 64 62 2c 0a  .  sqlite3 *db,.
2c90: 20 20 76 6f 69 64 20 2a 70 41 75 78 2c 0a 20 20    void *pAux,.  
2ca0: 69 6e 74 20 61 72 67 63 2c 20 63 6f 6e 73 74 20  int argc, const 
2cb0: 63 68 61 72 20 2a 63 6f 6e 73 74 2a 61 72 67 76  char *const*argv
2cc0: 2c 0a 20 20 73 71 6c 69 74 65 33 5f 76 74 61 62  ,.  sqlite3_vtab
2cd0: 20 2a 2a 70 70 56 74 61 62 2c 0a 20 20 63 68 61   **ppVtab,.  cha
2ce0: 72 20 2a 2a 70 7a 45 72 72 0a 29 7b 0a 20 20 69  r **pzErr.){.  i
2cf0: 6e 74 20 72 63 3b 0a 20 20 69 6e 74 20 69 3b 0a  nt rc;.  int i;.
2d00: 20 20 65 63 68 6f 5f 76 74 61 62 20 2a 70 56 74    echo_vtab *pVt
2d10: 61 62 3b 0a 0a 20 20 2f 2a 20 41 6c 6c 6f 63 61  ab;..  /* Alloca
2d20: 74 65 20 74 68 65 20 73 71 6c 69 74 65 33 5f 76  te the sqlite3_v
2d30: 74 61 62 2f 65 63 68 6f 5f 76 74 61 62 20 73 74  tab/echo_vtab st
2d40: 72 75 63 74 75 72 65 20 69 74 73 65 6c 66 20 2a  ructure itself *
2d50: 2f 0a 20 20 70 56 74 61 62 20 3d 20 73 71 6c 69  /.  pVtab = sqli
2d60: 74 65 33 4d 61 6c 6c 6f 63 5a 65 72 6f 28 20 73  te3MallocZero( s
2d70: 69 7a 65 6f 66 28 2a 70 56 74 61 62 29 20 29 3b  izeof(*pVtab) );
2d80: 0a 20 20 69 66 28 20 21 70 56 74 61 62 20 29 7b  .  if( !pVtab ){
2d90: 0a 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49  .    return SQLI
2da0: 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 7d 0a 20 20  TE_NOMEM;.  }.  
2db0: 70 56 74 61 62 2d 3e 69 6e 74 65 72 70 20 3d 20  pVtab->interp = 
2dc0: 28 28 45 63 68 6f 4d 6f 64 75 6c 65 20 2a 29 70  ((EchoModule *)p
2dd0: 41 75 78 29 2d 3e 69 6e 74 65 72 70 3b 0a 20 20  Aux)->interp;.  
2de0: 70 56 74 61 62 2d 3e 64 62 20 3d 20 64 62 3b 0a  pVtab->db = db;.
2df0: 0a 20 20 2f 2a 20 41 6c 6c 6f 63 61 74 65 20 65  .  /* Allocate e
2e00: 63 68 6f 5f 76 74 61 62 2e 7a 54 68 69 73 20 2a  cho_vtab.zThis *
2e10: 2f 0a 20 20 70 56 74 61 62 2d 3e 7a 54 68 69 73  /.  pVtab->zThis
2e20: 20 3d 20 73 71 6c 69 74 65 33 4d 50 72 69 6e 74   = sqlite3MPrint
2e30: 66 28 30 2c 20 22 25 73 22 2c 20 61 72 67 76 5b  f(0, "%s", argv[
2e40: 32 5d 29 3b 0a 20 20 69 66 28 20 21 70 56 74 61  2]);.  if( !pVta
2e50: 62 2d 3e 7a 54 68 69 73 20 29 7b 0a 20 20 20 20  b->zThis ){.    
2e60: 65 63 68 6f 44 65 73 74 72 75 63 74 6f 72 28 28  echoDestructor((
2e70: 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 29 70  sqlite3_vtab *)p
2e80: 56 74 61 62 29 3b 0a 20 20 20 20 72 65 74 75 72  Vtab);.    retur
2e90: 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a  n SQLITE_NOMEM;.
2ea0: 20 20 7d 0a 0a 20 20 2f 2a 20 41 6c 6c 6f 63 61    }..  /* Alloca
2eb0: 74 65 20 65 63 68 6f 5f 76 74 61 62 2e 7a 54 61  te echo_vtab.zTa
2ec0: 62 6c 65 4e 61 6d 65 20 2a 2f 0a 20 20 69 66 28  bleName */.  if(
2ed0: 20 61 72 67 63 3e 33 20 29 7b 0a 20 20 20 20 70   argc>3 ){.    p
2ee0: 56 74 61 62 2d 3e 7a 54 61 62 6c 65 4e 61 6d 65  Vtab->zTableName
2ef0: 20 3d 20 73 71 6c 69 74 65 33 4d 50 72 69 6e 74   = sqlite3MPrint
2f00: 66 28 30 2c 20 22 25 73 22 2c 20 61 72 67 76 5b  f(0, "%s", argv[
2f10: 33 5d 29 3b 0a 20 20 20 20 64 65 71 75 6f 74 65  3]);.    dequote
2f20: 53 74 72 69 6e 67 28 70 56 74 61 62 2d 3e 7a 54  String(pVtab->zT
2f30: 61 62 6c 65 4e 61 6d 65 29 3b 0a 20 20 20 20 69  ableName);.    i
2f40: 66 28 20 70 56 74 61 62 2d 3e 7a 54 61 62 6c 65  f( pVtab->zTable
2f50: 4e 61 6d 65 20 26 26 20 70 56 74 61 62 2d 3e 7a  Name && pVtab->z
2f60: 54 61 62 6c 65 4e 61 6d 65 5b 30 5d 3d 3d 27 2a  TableName[0]=='*
2f70: 27 20 29 7b 0a 20 20 20 20 20 20 63 68 61 72 20  ' ){.      char 
2f80: 2a 7a 20 3d 20 73 71 6c 69 74 65 33 4d 50 72 69  *z = sqlite3MPri
2f90: 6e 74 66 28 30 2c 20 22 25 73 25 73 22 2c 20 61  ntf(0, "%s%s", a
2fa0: 72 67 76 5b 32 5d 2c 20 26 28 70 56 74 61 62 2d  rgv[2], &(pVtab-
2fb0: 3e 7a 54 61 62 6c 65 4e 61 6d 65 5b 31 5d 29 29  >zTableName[1]))
2fc0: 3b 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f  ;.      sqlite3_
2fd0: 66 72 65 65 28 70 56 74 61 62 2d 3e 7a 54 61 62  free(pVtab->zTab
2fe0: 6c 65 4e 61 6d 65 29 3b 0a 20 20 20 20 20 20 70  leName);.      p
2ff0: 56 74 61 62 2d 3e 7a 54 61 62 6c 65 4e 61 6d 65  Vtab->zTableName
3000: 20 3d 20 7a 3b 0a 20 20 20 20 20 20 70 56 74 61   = z;.      pVta
3010: 62 2d 3e 69 73 50 61 74 74 65 72 6e 20 3d 20 31  b->isPattern = 1
3020: 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 28 20  ;.    }.    if( 
3030: 21 70 56 74 61 62 2d 3e 7a 54 61 62 6c 65 4e 61  !pVtab->zTableNa
3040: 6d 65 20 29 7b 0a 20 20 20 20 20 20 65 63 68 6f  me ){.      echo
3050: 44 65 73 74 72 75 63 74 6f 72 28 28 73 71 6c 69  Destructor((sqli
3060: 74 65 33 5f 76 74 61 62 20 2a 29 70 56 74 61 62  te3_vtab *)pVtab
3070: 29 3b 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20  );.      return 
3080: 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20  SQLITE_NOMEM;.  
3090: 20 20 7d 0a 20 20 7d 0a 0a 20 20 2f 2a 20 4c 6f    }.  }..  /* Lo
30a0: 67 20 74 68 65 20 61 72 67 75 6d 65 6e 74 73 20  g the arguments 
30b0: 74 6f 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e  to this function
30c0: 20 74 6f 20 54 63 6c 20 76 61 72 20 3a 3a 65 63   to Tcl var ::ec
30d0: 68 6f 5f 6d 6f 64 75 6c 65 20 2a 2f 0a 20 20 66  ho_module */.  f
30e0: 6f 72 28 69 3d 30 3b 20 69 3c 61 72 67 63 3b 20  or(i=0; i<argc; 
30f0: 69 2b 2b 29 7b 0a 20 20 20 20 61 70 70 65 6e 64  i++){.    append
3100: 54 6f 45 63 68 6f 4d 6f 64 75 6c 65 28 70 56 74  ToEchoModule(pVt
3110: 61 62 2d 3e 69 6e 74 65 72 70 2c 20 61 72 67 76  ab->interp, argv
3120: 5b 69 5d 29 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20  [i]);.  }..  /* 
3130: 49 6e 76 6f 6b 65 20 73 71 6c 69 74 65 33 5f 64  Invoke sqlite3_d
3140: 65 63 6c 61 72 65 5f 76 74 61 62 20 61 6e 64 20  eclare_vtab and 
3150: 73 65 74 20 75 70 20 6f 74 68 65 72 20 6d 65 6d  set up other mem
3160: 62 65 72 73 20 6f 66 20 74 68 65 20 65 63 68 6f  bers of the echo
3170: 5f 76 74 61 62 0a 20 20 2a 2a 20 73 74 72 75 63  _vtab.  ** struc
3180: 74 75 72 65 2e 20 49 66 20 61 6e 20 65 72 72 6f  ture. If an erro
3190: 72 20 6f 63 63 75 72 73 2c 20 64 65 6c 65 74 65  r occurs, delete
31a0: 20 74 68 65 20 73 71 6c 69 74 65 33 5f 76 74 61   the sqlite3_vta
31b0: 62 20 73 74 72 75 63 74 75 72 65 20 61 6e 64 0a  b structure and.
31c0: 20 20 2a 2a 20 72 65 74 75 72 6e 20 61 6e 20 65    ** return an e
31d0: 72 72 6f 72 20 63 6f 64 65 2e 0a 20 20 2a 2f 0a  rror code..  */.
31e0: 20 20 72 63 20 3d 20 65 63 68 6f 44 65 63 6c 61    rc = echoDecla
31f0: 72 65 56 74 61 62 28 70 56 74 61 62 2c 20 64 62  reVtab(pVtab, db
3200: 29 3b 0a 20 20 69 66 28 20 72 63 21 3d 53 51 4c  );.  if( rc!=SQL
3210: 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 65 63  ITE_OK ){.    ec
3220: 68 6f 44 65 73 74 72 75 63 74 6f 72 28 28 73 71  hoDestructor((sq
3230: 6c 69 74 65 33 5f 76 74 61 62 20 2a 29 70 56 74  lite3_vtab *)pVt
3240: 61 62 29 3b 0a 20 20 20 20 72 65 74 75 72 6e 20  ab);.    return 
3250: 72 63 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 53 75  rc;.  }..  /* Su
3260: 63 63 65 73 73 2e 20 53 65 74 20 2a 70 70 56 74  ccess. Set *ppVt
3270: 61 62 20 61 6e 64 20 72 65 74 75 72 6e 20 2a 2f  ab and return */
3280: 0a 20 20 2a 70 70 56 74 61 62 20 3d 20 26 70 56  .  *ppVtab = &pV
3290: 74 61 62 2d 3e 62 61 73 65 3b 0a 20 20 72 65 74  tab->base;.  ret
32a0: 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d  urn SQLITE_OK;.}
32b0: 0a 0a 2f 2a 20 0a 2a 2a 20 45 63 68 6f 20 76 69  ../* .** Echo vi
32c0: 72 74 75 61 6c 20 74 61 62 6c 65 20 6d 6f 64 75  rtual table modu
32d0: 6c 65 20 78 43 72 65 61 74 65 20 6d 65 74 68 6f  le xCreate metho
32e0: 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  d..*/.static int
32f0: 20 65 63 68 6f 43 72 65 61 74 65 28 0a 20 20 73   echoCreate(.  s
3300: 71 6c 69 74 65 33 20 2a 64 62 2c 0a 20 20 76 6f  qlite3 *db,.  vo
3310: 69 64 20 2a 70 41 75 78 2c 0a 20 20 69 6e 74 20  id *pAux,.  int 
3320: 61 72 67 63 2c 20 63 6f 6e 73 74 20 63 68 61 72  argc, const char
3330: 20 2a 63 6f 6e 73 74 2a 61 72 67 76 2c 0a 20 20   *const*argv,.  
3340: 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 2a 70  sqlite3_vtab **p
3350: 70 56 74 61 62 2c 0a 20 20 63 68 61 72 20 2a 2a  pVtab,.  char **
3360: 70 7a 45 72 72 0a 29 7b 0a 20 20 69 6e 74 20 72  pzErr.){.  int r
3370: 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20  c = SQLITE_OK;. 
3380: 20 61 70 70 65 6e 64 54 6f 45 63 68 6f 4d 6f 64   appendToEchoMod
3390: 75 6c 65 28 28 28 45 63 68 6f 4d 6f 64 75 6c 65  ule(((EchoModule
33a0: 20 2a 29 70 41 75 78 29 2d 3e 69 6e 74 65 72 70   *)pAux)->interp
33b0: 2c 20 22 78 43 72 65 61 74 65 22 29 3b 0a 20 20  , "xCreate");.  
33c0: 72 63 20 3d 20 65 63 68 6f 43 6f 6e 73 74 72 75  rc = echoConstru
33d0: 63 74 6f 72 28 64 62 2c 20 70 41 75 78 2c 20 61  ctor(db, pAux, a
33e0: 72 67 63 2c 20 61 72 67 76 2c 20 70 70 56 74 61  rgc, argv, ppVta
33f0: 62 2c 20 70 7a 45 72 72 29 3b 0a 0a 20 20 2f 2a  b, pzErr);..  /*
3400: 20 49 66 20 74 68 65 72 65 20 77 65 72 65 20 74   If there were t
3410: 77 6f 20 61 72 67 75 6d 65 6e 74 73 20 70 61 73  wo arguments pas
3420: 73 65 64 20 74 6f 20 74 68 65 20 6d 6f 64 75 6c  sed to the modul
3430: 65 20 61 74 20 74 68 65 20 53 51 4c 20 6c 65 76  e at the SQL lev
3440: 65 6c 20 0a 20 20 2a 2a 20 28 69 2e 65 2e 20 22  el .  ** (i.e. "
3450: 43 52 45 41 54 45 20 56 49 52 54 55 41 4c 20 54  CREATE VIRTUAL T
3460: 41 42 4c 45 20 74 62 6c 20 55 53 49 4e 47 20 65  ABLE tbl USING e
3470: 63 68 6f 28 61 72 67 31 2c 20 61 72 67 32 29 22  cho(arg1, arg2)"
3480: 29 2c 20 74 68 65 6e 20 0a 20 20 2a 2a 20 74 68  ), then .  ** th
3490: 65 20 73 65 63 6f 6e 64 20 61 72 67 75 6d 65 6e  e second argumen
34a0: 74 20 69 73 20 75 73 65 64 20 61 73 20 61 20 74  t is used as a t
34b0: 61 62 6c 65 20 6e 61 6d 65 2e 20 41 74 74 65 6d  able name. Attem
34c0: 70 74 20 74 6f 20 63 72 65 61 74 65 0a 20 20 2a  pt to create.  *
34d0: 2a 20 73 75 63 68 20 61 20 74 61 62 6c 65 20 77  * such a table w
34e0: 69 74 68 20 61 20 73 69 6e 67 6c 65 20 63 6f 6c  ith a single col
34f0: 75 6d 6e 2c 20 22 6c 6f 67 6d 73 67 22 2e 20 54  umn, "logmsg". T
3500: 68 69 73 20 74 61 62 6c 65 20 77 69 6c 6c 0a 20  his table will. 
3510: 20 2a 2a 20 62 65 20 75 73 65 64 20 74 6f 20 6c   ** be used to l
3520: 6f 67 20 63 61 6c 6c 73 20 74 6f 20 74 68 65 20  og calls to the 
3530: 78 55 70 64 61 74 65 20 6d 65 74 68 6f 64 2e 20  xUpdate method. 
3540: 49 74 20 77 69 6c 6c 20 62 65 20 64 65 6c 65 74  It will be delet
3550: 65 64 0a 20 20 2a 2a 20 77 68 65 6e 20 74 68 65  ed.  ** when the
3560: 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65 20 69   virtual table i
3570: 73 20 44 52 4f 50 65 64 2e 0a 20 20 2a 2a 0a 20  s DROPed..  **. 
3580: 20 2a 2a 20 4e 6f 74 65 3a 20 54 68 65 20 6d 61   ** Note: The ma
3590: 69 6e 20 70 6f 69 6e 74 20 6f 66 20 74 68 69 73  in point of this
35a0: 20 69 73 20 74 6f 20 74 65 73 74 20 74 68 61 74   is to test that
35b0: 20 77 65 20 63 61 6e 20 64 72 6f 70 20 74 61 62   we can drop tab
35c0: 6c 65 73 0a 20 20 2a 2a 20 66 72 6f 6d 20 77 69  les.  ** from wi
35d0: 74 68 69 6e 20 61 6e 20 78 44 65 73 74 72 6f 79  thin an xDestroy
35e0: 20 6d 65 74 68 6f 64 20 63 61 6c 6c 2e 0a 20 20   method call..  
35f0: 2a 2f 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c  */.  if( rc==SQL
3600: 49 54 45 5f 4f 4b 20 26 26 20 61 72 67 63 3d 3d  ITE_OK && argc==
3610: 35 20 29 7b 0a 20 20 20 20 63 68 61 72 20 2a 7a  5 ){.    char *z
3620: 53 71 6c 3b 0a 20 20 20 20 65 63 68 6f 5f 76 74  Sql;.    echo_vt
3630: 61 62 20 2a 70 56 74 61 62 20 3d 20 2a 28 65 63  ab *pVtab = *(ec
3640: 68 6f 5f 76 74 61 62 20 2a 2a 29 70 70 56 74 61  ho_vtab **)ppVta
3650: 62 3b 0a 20 20 20 20 70 56 74 61 62 2d 3e 7a 4c  b;.    pVtab->zL
3660: 6f 67 4e 61 6d 65 20 3d 20 73 71 6c 69 74 65 33  ogName = sqlite3
3670: 4d 50 72 69 6e 74 66 28 30 2c 20 22 25 73 22 2c  MPrintf(0, "%s",
3680: 20 61 72 67 76 5b 34 5d 29 3b 0a 20 20 20 20 7a   argv[4]);.    z
3690: 53 71 6c 20 3d 20 73 71 6c 69 74 65 33 4d 50 72  Sql = sqlite3MPr
36a0: 69 6e 74 66 28 30 2c 20 22 43 52 45 41 54 45 20  intf(0, "CREATE 
36b0: 54 41 42 4c 45 20 25 51 28 6c 6f 67 6d 73 67 29  TABLE %Q(logmsg)
36c0: 22 2c 20 70 56 74 61 62 2d 3e 7a 4c 6f 67 4e 61  ", pVtab->zLogNa
36d0: 6d 65 29 3b 0a 20 20 20 20 72 63 20 3d 20 73 71  me);.    rc = sq
36e0: 6c 69 74 65 33 5f 65 78 65 63 28 64 62 2c 20 7a  lite3_exec(db, z
36f0: 53 71 6c 2c 20 30 2c 20 30 2c 20 30 29 3b 0a 20  Sql, 0, 0, 0);. 
3700: 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28     sqlite3_free(
3710: 7a 53 71 6c 29 3b 0a 20 20 20 20 69 66 28 20 72  zSql);.    if( r
3720: 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a  c!=SQLITE_OK ){.
3730: 20 20 20 20 20 20 2a 70 7a 45 72 72 20 3d 20 73        *pzErr = s
3740: 71 6c 69 74 65 33 44 62 53 74 72 44 75 70 28 30  qlite3DbStrDup(0
3750: 2c 20 73 71 6c 69 74 65 33 5f 65 72 72 6d 73 67  , sqlite3_errmsg
3760: 28 64 62 29 29 3b 0a 20 20 20 20 7d 0a 20 20 7d  (db));.    }.  }
3770: 0a 0a 20 20 69 66 28 20 2a 70 70 56 74 61 62 20  ..  if( *ppVtab 
3780: 26 26 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b  && rc!=SQLITE_OK
3790: 20 29 7b 0a 20 20 20 20 65 63 68 6f 44 65 73 74   ){.    echoDest
37a0: 72 75 63 74 6f 72 28 2a 70 70 56 74 61 62 29 3b  ructor(*ppVtab);
37b0: 0a 20 20 20 20 2a 70 70 56 74 61 62 20 3d 20 30  .    *ppVtab = 0
37c0: 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 72 63 3d  ;.  }..  if( rc=
37d0: 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20  =SQLITE_OK ){.  
37e0: 20 20 28 2a 28 65 63 68 6f 5f 76 74 61 62 2a 2a    (*(echo_vtab**
37f0: 29 70 70 56 74 61 62 29 2d 3e 69 6e 54 72 61 6e  )ppVtab)->inTran
3800: 73 61 63 74 69 6f 6e 20 3d 20 31 3b 0a 20 20 7d  saction = 1;.  }
3810: 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d  ..  return rc;.}
3820: 0a 0a 2f 2a 20 0a 2a 2a 20 45 63 68 6f 20 76 69  ../* .** Echo vi
3830: 72 74 75 61 6c 20 74 61 62 6c 65 20 6d 6f 64 75  rtual table modu
3840: 6c 65 20 78 43 6f 6e 6e 65 63 74 20 6d 65 74 68  le xConnect meth
3850: 6f 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  od..*/.static in
3860: 74 20 65 63 68 6f 43 6f 6e 6e 65 63 74 28 0a 20  t echoConnect(. 
3870: 20 73 71 6c 69 74 65 33 20 2a 64 62 2c 0a 20 20   sqlite3 *db,.  
3880: 76 6f 69 64 20 2a 70 41 75 78 2c 0a 20 20 69 6e  void *pAux,.  in
3890: 74 20 61 72 67 63 2c 20 63 6f 6e 73 74 20 63 68  t argc, const ch
38a0: 61 72 20 2a 63 6f 6e 73 74 2a 61 72 67 76 2c 0a  ar *const*argv,.
38b0: 20 20 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a    sqlite3_vtab *
38c0: 2a 70 70 56 74 61 62 2c 0a 20 20 63 68 61 72 20  *ppVtab,.  char 
38d0: 2a 2a 70 7a 45 72 72 0a 29 7b 0a 20 20 61 70 70  **pzErr.){.  app
38e0: 65 6e 64 54 6f 45 63 68 6f 4d 6f 64 75 6c 65 28  endToEchoModule(
38f0: 28 28 45 63 68 6f 4d 6f 64 75 6c 65 20 2a 29 70  ((EchoModule *)p
3900: 41 75 78 29 2d 3e 69 6e 74 65 72 70 2c 20 22 78  Aux)->interp, "x
3910: 43 6f 6e 6e 65 63 74 22 29 3b 0a 20 20 72 65 74  Connect");.  ret
3920: 75 72 6e 20 65 63 68 6f 43 6f 6e 73 74 72 75 63  urn echoConstruc
3930: 74 6f 72 28 64 62 2c 20 70 41 75 78 2c 20 61 72  tor(db, pAux, ar
3940: 67 63 2c 20 61 72 67 76 2c 20 70 70 56 74 61 62  gc, argv, ppVtab
3950: 2c 20 70 7a 45 72 72 29 3b 0a 7d 0a 0a 2f 2a 20  , pzErr);.}../* 
3960: 0a 2a 2a 20 45 63 68 6f 20 76 69 72 74 75 61 6c  .** Echo virtual
3970: 20 74 61 62 6c 65 20 6d 6f 64 75 6c 65 20 78 44   table module xD
3980: 69 73 63 6f 6e 6e 65 63 74 20 6d 65 74 68 6f 64  isconnect method
3990: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
39a0: 65 63 68 6f 44 69 73 63 6f 6e 6e 65 63 74 28 73  echoDisconnect(s
39b0: 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 70 56 74  qlite3_vtab *pVt
39c0: 61 62 29 7b 0a 20 20 61 70 70 65 6e 64 54 6f 45  ab){.  appendToE
39d0: 63 68 6f 4d 6f 64 75 6c 65 28 28 28 65 63 68 6f  choModule(((echo
39e0: 5f 76 74 61 62 20 2a 29 70 56 74 61 62 29 2d 3e  _vtab *)pVtab)->
39f0: 69 6e 74 65 72 70 2c 20 22 78 44 69 73 63 6f 6e  interp, "xDiscon
3a00: 6e 65 63 74 22 29 3b 0a 20 20 72 65 74 75 72 6e  nect");.  return
3a10: 20 65 63 68 6f 44 65 73 74 72 75 63 74 6f 72 28   echoDestructor(
3a20: 70 56 74 61 62 29 3b 0a 7d 0a 0a 2f 2a 20 0a 2a  pVtab);.}../* .*
3a30: 2a 20 45 63 68 6f 20 76 69 72 74 75 61 6c 20 74  * Echo virtual t
3a40: 61 62 6c 65 20 6d 6f 64 75 6c 65 20 78 44 65 73  able module xDes
3a50: 74 72 6f 79 20 6d 65 74 68 6f 64 2e 0a 2a 2f 0a  troy method..*/.
3a60: 73 74 61 74 69 63 20 69 6e 74 20 65 63 68 6f 44  static int echoD
3a70: 65 73 74 72 6f 79 28 73 71 6c 69 74 65 33 5f 76  estroy(sqlite3_v
3a80: 74 61 62 20 2a 70 56 74 61 62 29 7b 0a 20 20 69  tab *pVtab){.  i
3a90: 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f  nt rc = SQLITE_O
3aa0: 4b 3b 0a 20 20 65 63 68 6f 5f 76 74 61 62 20 2a  K;.  echo_vtab *
3ab0: 70 20 3d 20 28 65 63 68 6f 5f 76 74 61 62 20 2a  p = (echo_vtab *
3ac0: 29 70 56 74 61 62 3b 0a 20 20 61 70 70 65 6e 64  )pVtab;.  append
3ad0: 54 6f 45 63 68 6f 4d 6f 64 75 6c 65 28 28 28 65  ToEchoModule(((e
3ae0: 63 68 6f 5f 76 74 61 62 20 2a 29 70 56 74 61 62  cho_vtab *)pVtab
3af0: 29 2d 3e 69 6e 74 65 72 70 2c 20 22 78 44 65 73  )->interp, "xDes
3b00: 74 72 6f 79 22 29 3b 0a 0a 20 20 2f 2a 20 44 72  troy");..  /* Dr
3b10: 6f 70 20 74 68 65 20 22 6c 6f 67 22 20 74 61 62  op the "log" tab
3b20: 6c 65 2c 20 69 66 20 6f 6e 65 20 65 78 69 73 74  le, if one exist
3b30: 73 20 28 73 65 65 20 65 63 68 6f 43 72 65 61 74  s (see echoCreat
3b40: 65 28 29 20 66 6f 72 20 64 65 74 61 69 6c 73 29  e() for details)
3b50: 20 2a 2f 0a 20 20 69 66 28 20 70 20 26 26 20 70   */.  if( p && p
3b60: 2d 3e 7a 4c 6f 67 4e 61 6d 65 20 29 7b 0a 20 20  ->zLogName ){.  
3b70: 20 20 63 68 61 72 20 2a 7a 53 71 6c 3b 0a 20 20    char *zSql;.  
3b80: 20 20 7a 53 71 6c 20 3d 20 73 71 6c 69 74 65 33    zSql = sqlite3
3b90: 4d 50 72 69 6e 74 66 28 30 2c 20 22 44 52 4f 50  MPrintf(0, "DROP
3ba0: 20 54 41 42 4c 45 20 25 51 22 2c 20 70 2d 3e 7a   TABLE %Q", p->z
3bb0: 4c 6f 67 4e 61 6d 65 29 3b 0a 20 20 20 20 72 63  LogName);.    rc
3bc0: 20 3d 20 73 71 6c 69 74 65 33 5f 65 78 65 63 28   = sqlite3_exec(
3bd0: 70 2d 3e 64 62 2c 20 7a 53 71 6c 2c 20 30 2c 20  p->db, zSql, 0, 
3be0: 30 2c 20 30 29 3b 0a 20 20 20 20 73 71 6c 69 74  0, 0);.    sqlit
3bf0: 65 33 5f 66 72 65 65 28 7a 53 71 6c 29 3b 0a 20  e3_free(zSql);. 
3c00: 20 7d 0a 0a 20 20 69 66 28 20 72 63 3d 3d 53 51   }..  if( rc==SQ
3c10: 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 72  LITE_OK ){.    r
3c20: 63 20 3d 20 65 63 68 6f 44 65 73 74 72 75 63 74  c = echoDestruct
3c30: 6f 72 28 70 56 74 61 62 29 3b 0a 20 20 7d 0a 20  or(pVtab);.  }. 
3c40: 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f   return rc;.}../
3c50: 2a 20 0a 2a 2a 20 45 63 68 6f 20 76 69 72 74 75  * .** Echo virtu
3c60: 61 6c 20 74 61 62 6c 65 20 6d 6f 64 75 6c 65 20  al table module 
3c70: 78 4f 70 65 6e 20 6d 65 74 68 6f 64 2e 0a 2a 2f  xOpen method..*/
3c80: 0a 73 74 61 74 69 63 20 69 6e 74 20 65 63 68 6f  .static int echo
3c90: 4f 70 65 6e 28 73 71 6c 69 74 65 33 5f 76 74 61  Open(sqlite3_vta
3ca0: 62 20 2a 70 56 54 61 62 2c 20 73 71 6c 69 74 65  b *pVTab, sqlite
3cb0: 33 5f 76 74 61 62 5f 63 75 72 73 6f 72 20 2a 2a  3_vtab_cursor **
3cc0: 70 70 43 75 72 73 6f 72 29 7b 0a 20 20 65 63 68  ppCursor){.  ech
3cd0: 6f 5f 63 75 72 73 6f 72 20 2a 70 43 75 72 3b 0a  o_cursor *pCur;.
3ce0: 20 20 69 66 28 20 73 69 6d 75 6c 61 74 65 56 74    if( simulateVt
3cf0: 61 62 45 72 72 6f 72 28 28 65 63 68 6f 5f 76 74  abError((echo_vt
3d00: 61 62 20 2a 29 70 56 54 61 62 2c 20 22 78 4f 70  ab *)pVTab, "xOp
3d10: 65 6e 22 29 20 29 7b 0a 20 20 20 20 72 65 74 75  en") ){.    retu
3d20: 72 6e 20 53 51 4c 49 54 45 5f 45 52 52 4f 52 3b  rn SQLITE_ERROR;
3d30: 0a 20 20 7d 0a 20 20 70 43 75 72 20 3d 20 73 71  .  }.  pCur = sq
3d40: 6c 69 74 65 33 4d 61 6c 6c 6f 63 5a 65 72 6f 28  lite3MallocZero(
3d50: 73 69 7a 65 6f 66 28 65 63 68 6f 5f 63 75 72 73  sizeof(echo_curs
3d60: 6f 72 29 29 3b 0a 20 20 2a 70 70 43 75 72 73 6f  or));.  *ppCurso
3d70: 72 20 3d 20 28 73 71 6c 69 74 65 33 5f 76 74 61  r = (sqlite3_vta
3d80: 62 5f 63 75 72 73 6f 72 20 2a 29 70 43 75 72 3b  b_cursor *)pCur;
3d90: 0a 20 20 72 65 74 75 72 6e 20 28 70 43 75 72 20  .  return (pCur 
3da0: 3f 20 53 51 4c 49 54 45 5f 4f 4b 20 3a 20 53 51  ? SQLITE_OK : SQ
3db0: 4c 49 54 45 5f 4e 4f 4d 45 4d 29 3b 0a 7d 0a 0a  LITE_NOMEM);.}..
3dc0: 2f 2a 20 0a 2a 2a 20 45 63 68 6f 20 76 69 72 74  /* .** Echo virt
3dd0: 75 61 6c 20 74 61 62 6c 65 20 6d 6f 64 75 6c 65  ual table module
3de0: 20 78 43 6c 6f 73 65 20 6d 65 74 68 6f 64 2e 0a   xClose method..
3df0: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 65 63  */.static int ec
3e00: 68 6f 43 6c 6f 73 65 28 73 71 6c 69 74 65 33 5f  hoClose(sqlite3_
3e10: 76 74 61 62 5f 63 75 72 73 6f 72 20 2a 63 75 72  vtab_cursor *cur
3e20: 29 7b 0a 20 20 69 6e 74 20 72 63 3b 0a 20 20 65  ){.  int rc;.  e
3e30: 63 68 6f 5f 63 75 72 73 6f 72 20 2a 70 43 75 72  cho_cursor *pCur
3e40: 20 3d 20 28 65 63 68 6f 5f 63 75 72 73 6f 72 20   = (echo_cursor 
3e50: 2a 29 63 75 72 3b 0a 20 20 73 71 6c 69 74 65 33  *)cur;.  sqlite3
3e60: 5f 73 74 6d 74 20 2a 70 53 74 6d 74 20 3d 20 70  _stmt *pStmt = p
3e70: 43 75 72 2d 3e 70 53 74 6d 74 3b 0a 20 20 70 43  Cur->pStmt;.  pC
3e80: 75 72 2d 3e 70 53 74 6d 74 20 3d 20 30 3b 0a 20  ur->pStmt = 0;. 
3e90: 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70 43   sqlite3_free(pC
3ea0: 75 72 29 3b 0a 20 20 72 63 20 3d 20 73 71 6c 69  ur);.  rc = sqli
3eb0: 74 65 33 5f 66 69 6e 61 6c 69 7a 65 28 70 53 74  te3_finalize(pSt
3ec0: 6d 74 29 3b 0a 20 20 72 65 74 75 72 6e 20 72 63  mt);.  return rc
3ed0: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72  ;.}../*.** Retur
3ee0: 6e 20 6e 6f 6e 2d 7a 65 72 6f 20 69 66 20 74 68  n non-zero if th
3ef0: 65 20 63 75 72 73 6f 72 20 64 6f 65 73 20 6e 6f  e cursor does no
3f00: 74 20 63 75 72 72 65 6e 74 6c 79 20 70 6f 69 6e  t currently poin
3f10: 74 20 74 6f 20 61 20 76 61 6c 69 64 20 72 65 63  t to a valid rec
3f20: 6f 72 64 0a 2a 2a 20 28 69 2e 65 20 69 66 20 74  ord.** (i.e if t
3f30: 68 65 20 73 63 61 6e 20 68 61 73 20 66 69 6e 69  he scan has fini
3f40: 73 68 65 64 29 2c 20 6f 72 20 7a 65 72 6f 20 6f  shed), or zero o
3f50: 74 68 65 72 77 69 73 65 2e 0a 2a 2f 0a 73 74 61  therwise..*/.sta
3f60: 74 69 63 20 69 6e 74 20 65 63 68 6f 45 6f 66 28  tic int echoEof(
3f70: 73 71 6c 69 74 65 33 5f 76 74 61 62 5f 63 75 72  sqlite3_vtab_cur
3f80: 73 6f 72 20 2a 63 75 72 29 7b 0a 20 20 72 65 74  sor *cur){.  ret
3f90: 75 72 6e 20 28 28 28 65 63 68 6f 5f 63 75 72 73  urn (((echo_curs
3fa0: 6f 72 20 2a 29 63 75 72 29 2d 3e 70 53 74 6d 74  or *)cur)->pStmt
3fb0: 20 3f 20 30 20 3a 20 31 29 3b 0a 7d 0a 0a 2f 2a   ? 0 : 1);.}../*
3fc0: 20 0a 2a 2a 20 45 63 68 6f 20 76 69 72 74 75 61   .** Echo virtua
3fd0: 6c 20 74 61 62 6c 65 20 6d 6f 64 75 6c 65 20 78  l table module x
3fe0: 4e 65 78 74 20 6d 65 74 68 6f 64 2e 0a 2a 2f 0a  Next method..*/.
3ff0: 73 74 61 74 69 63 20 69 6e 74 20 65 63 68 6f 4e  static int echoN
4000: 65 78 74 28 73 71 6c 69 74 65 33 5f 76 74 61 62  ext(sqlite3_vtab
4010: 5f 63 75 72 73 6f 72 20 2a 63 75 72 29 7b 0a 20  _cursor *cur){. 
4020: 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45   int rc = SQLITE
4030: 5f 4f 4b 3b 0a 20 20 65 63 68 6f 5f 63 75 72 73  _OK;.  echo_curs
4040: 6f 72 20 2a 70 43 75 72 20 3d 20 28 65 63 68 6f  or *pCur = (echo
4050: 5f 63 75 72 73 6f 72 20 2a 29 63 75 72 3b 0a 0a  _cursor *)cur;..
4060: 20 20 69 66 28 20 73 69 6d 75 6c 61 74 65 56 74    if( simulateVt
4070: 61 62 45 72 72 6f 72 28 28 65 63 68 6f 5f 76 74  abError((echo_vt
4080: 61 62 20 2a 29 28 63 75 72 2d 3e 70 56 74 61 62  ab *)(cur->pVtab
4090: 29 2c 20 22 78 4e 65 78 74 22 29 20 29 7b 0a 20  ), "xNext") ){. 
40a0: 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45     return SQLITE
40b0: 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a 0a 20 20 69  _ERROR;.  }..  i
40c0: 66 28 20 70 43 75 72 2d 3e 70 53 74 6d 74 20 29  f( pCur->pStmt )
40d0: 7b 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74  {.    rc = sqlit
40e0: 65 33 5f 73 74 65 70 28 70 43 75 72 2d 3e 70 53  e3_step(pCur->pS
40f0: 74 6d 74 29 3b 0a 20 20 20 20 69 66 28 20 72 63  tmt);.    if( rc
4100: 3d 3d 53 51 4c 49 54 45 5f 52 4f 57 20 29 7b 0a  ==SQLITE_ROW ){.
4110: 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54        rc = SQLIT
4120: 45 5f 4f 4b 3b 0a 20 20 20 20 7d 65 6c 73 65 7b  E_OK;.    }else{
4130: 0a 20 20 20 20 20 20 72 63 20 3d 20 73 71 6c 69  .      rc = sqli
4140: 74 65 33 5f 66 69 6e 61 6c 69 7a 65 28 70 43 75  te3_finalize(pCu
4150: 72 2d 3e 70 53 74 6d 74 29 3b 0a 20 20 20 20 20  r->pStmt);.     
4160: 20 70 43 75 72 2d 3e 70 53 74 6d 74 20 3d 20 30   pCur->pStmt = 0
4170: 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 72  ;.    }.  }..  r
4180: 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 20  eturn rc;.}../* 
4190: 0a 2a 2a 20 45 63 68 6f 20 76 69 72 74 75 61 6c  .** Echo virtual
41a0: 20 74 61 62 6c 65 20 6d 6f 64 75 6c 65 20 78 43   table module xC
41b0: 6f 6c 75 6d 6e 20 6d 65 74 68 6f 64 2e 0a 2a 2f  olumn method..*/
41c0: 0a 73 74 61 74 69 63 20 69 6e 74 20 65 63 68 6f  .static int echo
41d0: 43 6f 6c 75 6d 6e 28 73 71 6c 69 74 65 33 5f 76  Column(sqlite3_v
41e0: 74 61 62 5f 63 75 72 73 6f 72 20 2a 63 75 72 2c  tab_cursor *cur,
41f0: 20 73 71 6c 69 74 65 33 5f 63 6f 6e 74 65 78 74   sqlite3_context
4200: 20 2a 63 74 78 2c 20 69 6e 74 20 69 29 7b 0a 20   *ctx, int i){. 
4210: 20 69 6e 74 20 69 43 6f 6c 20 3d 20 69 20 2b 20   int iCol = i + 
4220: 31 3b 0a 20 20 73 71 6c 69 74 65 33 5f 73 74 6d  1;.  sqlite3_stm
4230: 74 20 2a 70 53 74 6d 74 20 3d 20 28 28 65 63 68  t *pStmt = ((ech
4240: 6f 5f 63 75 72 73 6f 72 20 2a 29 63 75 72 29 2d  o_cursor *)cur)-
4250: 3e 70 53 74 6d 74 3b 0a 0a 20 20 69 66 28 20 73  >pStmt;..  if( s
4260: 69 6d 75 6c 61 74 65 56 74 61 62 45 72 72 6f 72  imulateVtabError
4270: 28 28 65 63 68 6f 5f 76 74 61 62 20 2a 29 28 63  ((echo_vtab *)(c
4280: 75 72 2d 3e 70 56 74 61 62 29 2c 20 22 78 43 6f  ur->pVtab), "xCo
4290: 6c 75 6d 6e 22 29 20 29 7b 0a 20 20 20 20 72 65  lumn") ){.    re
42a0: 74 75 72 6e 20 53 51 4c 49 54 45 5f 45 52 52 4f  turn SQLITE_ERRO
42b0: 52 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 21 70  R;.  }..  if( !p
42c0: 53 74 6d 74 20 29 7b 0a 20 20 20 20 73 71 6c 69  Stmt ){.    sqli
42d0: 74 65 33 5f 72 65 73 75 6c 74 5f 6e 75 6c 6c 28  te3_result_null(
42e0: 63 74 78 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20  ctx);.  }else{. 
42f0: 20 20 20 61 73 73 65 72 74 28 20 73 71 6c 69 74     assert( sqlit
4300: 65 33 5f 64 61 74 61 5f 63 6f 75 6e 74 28 70 53  e3_data_count(pS
4310: 74 6d 74 29 3e 69 43 6f 6c 20 29 3b 0a 20 20 20  tmt)>iCol );.   
4320: 20 73 71 6c 69 74 65 33 5f 72 65 73 75 6c 74 5f   sqlite3_result_
4330: 76 61 6c 75 65 28 63 74 78 2c 20 73 71 6c 69 74  value(ctx, sqlit
4340: 65 33 5f 63 6f 6c 75 6d 6e 5f 76 61 6c 75 65 28  e3_column_value(
4350: 70 53 74 6d 74 2c 20 69 43 6f 6c 29 29 3b 0a 20  pStmt, iCol));. 
4360: 20 7d 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49   }.  return SQLI
4370: 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a  TE_OK;.}../* .**
4380: 20 45 63 68 6f 20 76 69 72 74 75 61 6c 20 74 61   Echo virtual ta
4390: 62 6c 65 20 6d 6f 64 75 6c 65 20 78 52 6f 77 69  ble module xRowi
43a0: 64 20 6d 65 74 68 6f 64 2e 0a 2a 2f 0a 73 74 61  d method..*/.sta
43b0: 74 69 63 20 69 6e 74 20 65 63 68 6f 52 6f 77 69  tic int echoRowi
43c0: 64 28 73 71 6c 69 74 65 33 5f 76 74 61 62 5f 63  d(sqlite3_vtab_c
43d0: 75 72 73 6f 72 20 2a 63 75 72 2c 20 73 71 6c 69  ursor *cur, sqli
43e0: 74 65 5f 69 6e 74 36 34 20 2a 70 52 6f 77 69 64  te_int64 *pRowid
43f0: 29 7b 0a 20 20 73 71 6c 69 74 65 33 5f 73 74 6d  ){.  sqlite3_stm
4400: 74 20 2a 70 53 74 6d 74 20 3d 20 28 28 65 63 68  t *pStmt = ((ech
4410: 6f 5f 63 75 72 73 6f 72 20 2a 29 63 75 72 29 2d  o_cursor *)cur)-
4420: 3e 70 53 74 6d 74 3b 0a 0a 20 20 69 66 28 20 73  >pStmt;..  if( s
4430: 69 6d 75 6c 61 74 65 56 74 61 62 45 72 72 6f 72  imulateVtabError
4440: 28 28 65 63 68 6f 5f 76 74 61 62 20 2a 29 28 63  ((echo_vtab *)(c
4450: 75 72 2d 3e 70 56 74 61 62 29 2c 20 22 78 52 6f  ur->pVtab), "xRo
4460: 77 69 64 22 29 20 29 7b 0a 20 20 20 20 72 65 74  wid") ){.    ret
4470: 75 72 6e 20 53 51 4c 49 54 45 5f 45 52 52 4f 52  urn SQLITE_ERROR
4480: 3b 0a 20 20 7d 0a 0a 20 20 2a 70 52 6f 77 69 64  ;.  }..  *pRowid
4490: 20 3d 20 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d   = sqlite3_colum
44a0: 6e 5f 69 6e 74 36 34 28 70 53 74 6d 74 2c 20 30  n_int64(pStmt, 0
44b0: 29 3b 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49  );.  return SQLI
44c0: 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  TE_OK;.}../*.** 
44d0: 43 6f 6d 70 75 74 65 20 61 20 73 69 6d 70 6c 65  Compute a simple
44e0: 20 68 61 73 68 20 6f 66 20 74 68 65 20 6e 75 6c   hash of the nul
44f0: 6c 20 74 65 72 6d 69 6e 61 74 65 64 20 73 74 72  l terminated str
4500: 69 6e 67 20 7a 53 74 72 69 6e 67 2e 0a 2a 2a 0a  ing zString..**.
4510: 2a 2a 20 54 68 69 73 20 6d 6f 64 75 6c 65 20 75  ** This module u
4520: 73 65 73 20 6f 6e 6c 79 20 73 71 6c 69 74 65 33  ses only sqlite3
4530: 5f 69 6e 64 65 78 5f 69 6e 66 6f 2e 69 64 78 53  _index_info.idxS
4540: 74 72 2c 20 6e 6f 74 20 0a 2a 2a 20 73 71 6c 69  tr, not .** sqli
4550: 74 65 33 5f 69 6e 64 65 78 5f 69 6e 66 6f 2e 69  te3_index_info.i
4560: 64 78 4e 75 6d 2e 20 53 6f 20 74 6f 20 74 65 73  dxNum. So to tes
4570: 74 20 69 64 78 4e 75 6d 2c 20 77 68 65 6e 20 69  t idxNum, when i
4580: 64 78 53 74 72 20 69 73 20 73 65 74 0a 2a 2a 20  dxStr is set.** 
4590: 69 6e 20 65 63 68 6f 42 65 73 74 49 6e 64 65 78  in echoBestIndex
45a0: 28 29 2c 20 69 64 78 4e 75 6d 20 69 73 20 73 65  (), idxNum is se
45b0: 74 20 74 6f 20 74 68 65 20 63 6f 72 72 65 73 70  t to the corresp
45c0: 6f 6e 64 69 6e 67 20 68 61 73 68 20 76 61 6c 75  onding hash valu
45d0: 65 2e 0a 2a 2a 20 49 6e 20 65 63 68 6f 46 69 6c  e..** In echoFil
45e0: 74 65 72 28 29 2c 20 63 6f 64 65 20 61 73 73 65  ter(), code asse
45f0: 72 74 28 29 73 20 74 68 61 74 20 74 68 65 20 73  rt()s that the s
4600: 75 70 70 6c 69 65 64 20 69 64 78 4e 75 6d 20 76  upplied idxNum v
4610: 61 6c 75 65 20 69 73 0a 2a 2a 20 69 6e 64 65 65  alue is.** indee
4620: 64 20 74 68 65 20 68 61 73 68 20 6f 66 20 74 68  d the hash of th
4630: 65 20 73 75 70 70 6c 69 65 64 20 69 64 78 53 74  e supplied idxSt
4640: 72 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  r..*/.static int
4650: 20 68 61 73 68 53 74 72 69 6e 67 28 63 6f 6e 73   hashString(cons
4660: 74 20 63 68 61 72 20 2a 7a 53 74 72 69 6e 67 29  t char *zString)
4670: 7b 0a 20 20 69 6e 74 20 76 61 6c 20 3d 20 30 3b  {.  int val = 0;
4680: 0a 20 20 69 6e 74 20 69 69 3b 0a 20 20 66 6f 72  .  int ii;.  for
4690: 28 69 69 3d 30 3b 20 7a 53 74 72 69 6e 67 5b 69  (ii=0; zString[i
46a0: 69 5d 3b 20 69 69 2b 2b 29 7b 0a 20 20 20 20 76  i]; ii++){.    v
46b0: 61 6c 20 3d 20 28 76 61 6c 20 3c 3c 20 33 29 20  al = (val << 3) 
46c0: 2b 20 28 69 6e 74 29 7a 53 74 72 69 6e 67 5b 69  + (int)zString[i
46d0: 69 5d 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e  i];.  }.  return
46e0: 20 76 61 6c 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20   val;.}../* .** 
46f0: 45 63 68 6f 20 76 69 72 74 75 61 6c 20 74 61 62  Echo virtual tab
4700: 6c 65 20 6d 6f 64 75 6c 65 20 78 46 69 6c 74 65  le module xFilte
4710: 72 20 6d 65 74 68 6f 64 2e 0a 2a 2f 0a 73 74 61  r method..*/.sta
4720: 74 69 63 20 69 6e 74 20 65 63 68 6f 46 69 6c 74  tic int echoFilt
4730: 65 72 28 0a 20 20 73 71 6c 69 74 65 33 5f 76 74  er(.  sqlite3_vt
4740: 61 62 5f 63 75 72 73 6f 72 20 2a 70 56 74 61 62  ab_cursor *pVtab
4750: 43 75 72 73 6f 72 2c 20 0a 20 20 69 6e 74 20 69  Cursor, .  int i
4760: 64 78 4e 75 6d 2c 20 63 6f 6e 73 74 20 63 68 61  dxNum, const cha
4770: 72 20 2a 69 64 78 53 74 72 2c 0a 20 20 69 6e 74  r *idxStr,.  int
4780: 20 61 72 67 63 2c 20 73 71 6c 69 74 65 33 5f 76   argc, sqlite3_v
4790: 61 6c 75 65 20 2a 2a 61 72 67 76 0a 29 7b 0a 20  alue **argv.){. 
47a0: 20 69 6e 74 20 72 63 3b 0a 20 20 69 6e 74 20 69   int rc;.  int i
47b0: 3b 0a 0a 20 20 65 63 68 6f 5f 63 75 72 73 6f 72  ;..  echo_cursor
47c0: 20 2a 70 43 75 72 20 3d 20 28 65 63 68 6f 5f 63   *pCur = (echo_c
47d0: 75 72 73 6f 72 20 2a 29 70 56 74 61 62 43 75 72  ursor *)pVtabCur
47e0: 73 6f 72 3b 0a 20 20 65 63 68 6f 5f 76 74 61 62  sor;.  echo_vtab
47f0: 20 2a 70 56 74 61 62 20 3d 20 28 65 63 68 6f 5f   *pVtab = (echo_
4800: 76 74 61 62 20 2a 29 70 56 74 61 62 43 75 72 73  vtab *)pVtabCurs
4810: 6f 72 2d 3e 70 56 74 61 62 3b 0a 20 20 73 71 6c  or->pVtab;.  sql
4820: 69 74 65 33 20 2a 64 62 20 3d 20 70 56 74 61 62  ite3 *db = pVtab
4830: 2d 3e 64 62 3b 0a 0a 20 20 69 66 28 20 73 69 6d  ->db;..  if( sim
4840: 75 6c 61 74 65 56 74 61 62 45 72 72 6f 72 28 70  ulateVtabError(p
4850: 56 74 61 62 2c 20 22 78 46 69 6c 74 65 72 22 29  Vtab, "xFilter")
4860: 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 53   ){.    return S
4870: 51 4c 49 54 45 5f 45 52 52 4f 52 3b 0a 20 20 7d  QLITE_ERROR;.  }
4880: 0a 0a 20 20 2f 2a 20 43 68 65 63 6b 20 74 68 61  ..  /* Check tha
4890: 74 20 69 64 78 4e 75 6d 20 6d 61 74 63 68 65 73  t idxNum matches
48a0: 20 69 64 78 53 74 72 20 2a 2f 0a 20 20 61 73 73   idxStr */.  ass
48b0: 65 72 74 28 20 69 64 78 4e 75 6d 3d 3d 68 61 73  ert( idxNum==has
48c0: 68 53 74 72 69 6e 67 28 69 64 78 53 74 72 29 20  hString(idxStr) 
48d0: 29 3b 0a 0a 20 20 2f 2a 20 4c 6f 67 20 61 72 67  );..  /* Log arg
48e0: 75 6d 65 6e 74 73 20 74 6f 20 74 68 65 20 3a 3a  uments to the ::
48f0: 65 63 68 6f 5f 6d 6f 64 75 6c 65 20 54 63 6c 20  echo_module Tcl 
4900: 76 61 72 69 61 62 6c 65 20 2a 2f 0a 20 20 61 70  variable */.  ap
4910: 70 65 6e 64 54 6f 45 63 68 6f 4d 6f 64 75 6c 65  pendToEchoModule
4920: 28 70 56 74 61 62 2d 3e 69 6e 74 65 72 70 2c 20  (pVtab->interp, 
4930: 22 78 46 69 6c 74 65 72 22 29 3b 0a 20 20 61 70  "xFilter");.  ap
4940: 70 65 6e 64 54 6f 45 63 68 6f 4d 6f 64 75 6c 65  pendToEchoModule
4950: 28 70 56 74 61 62 2d 3e 69 6e 74 65 72 70 2c 20  (pVtab->interp, 
4960: 69 64 78 53 74 72 29 3b 0a 20 20 66 6f 72 28 69  idxStr);.  for(i
4970: 3d 30 3b 20 69 3c 61 72 67 63 3b 20 69 2b 2b 29  =0; i<argc; i++)
4980: 7b 0a 20 20 20 20 61 70 70 65 6e 64 54 6f 45 63  {.    appendToEc
4990: 68 6f 4d 6f 64 75 6c 65 28 70 56 74 61 62 2d 3e  hoModule(pVtab->
49a0: 69 6e 74 65 72 70 2c 20 28 63 6f 6e 73 74 20 63  interp, (const c
49b0: 68 61 72 2a 29 73 71 6c 69 74 65 33 5f 76 61 6c  har*)sqlite3_val
49c0: 75 65 5f 74 65 78 74 28 61 72 67 76 5b 69 5d 29  ue_text(argv[i])
49d0: 29 3b 0a 20 20 7d 0a 0a 20 20 73 71 6c 69 74 65  );.  }..  sqlite
49e0: 33 5f 66 69 6e 61 6c 69 7a 65 28 70 43 75 72 2d  3_finalize(pCur-
49f0: 3e 70 53 74 6d 74 29 3b 0a 20 20 70 43 75 72 2d  >pStmt);.  pCur-
4a00: 3e 70 53 74 6d 74 20 3d 20 30 3b 0a 0a 20 20 2f  >pStmt = 0;..  /
4a10: 2a 20 50 72 65 70 61 72 65 20 74 68 65 20 53 51  * Prepare the SQ
4a20: 4c 20 73 74 61 74 65 6d 65 6e 74 20 63 72 65 61  L statement crea
4a30: 74 65 64 20 62 79 20 65 63 68 6f 42 65 73 74 49  ted by echoBestI
4a40: 6e 64 65 78 20 61 6e 64 20 62 69 6e 64 20 74 68  ndex and bind th
4a50: 65 0a 20 20 2a 2a 20 72 75 6e 74 69 6d 65 20 70  e.  ** runtime p
4a60: 61 72 61 6d 65 74 65 72 73 20 70 61 73 73 65 64  arameters passed
4a70: 20 74 6f 20 74 68 69 73 20 66 75 6e 63 74 69 6f   to this functio
4a80: 6e 20 74 6f 20 69 74 2e 0a 20 20 2a 2f 0a 20 20  n to it..  */.  
4a90: 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 70 72 65  rc = sqlite3_pre
4aa0: 70 61 72 65 28 64 62 2c 20 69 64 78 53 74 72 2c  pare(db, idxStr,
4ab0: 20 2d 31 2c 20 26 70 43 75 72 2d 3e 70 53 74 6d   -1, &pCur->pStm
4ac0: 74 2c 20 30 29 3b 0a 20 20 61 73 73 65 72 74 28  t, 0);.  assert(
4ad0: 20 70 43 75 72 2d 3e 70 53 74 6d 74 20 7c 7c 20   pCur->pStmt || 
4ae0: 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 3b  rc!=SQLITE_OK );
4af0: 0a 20 20 66 6f 72 28 69 3d 30 3b 20 72 63 3d 3d  .  for(i=0; rc==
4b00: 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20 69 3c 61  SQLITE_OK && i<a
4b10: 72 67 63 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 73  rgc; i++){.    s
4b20: 71 6c 69 74 65 33 5f 62 69 6e 64 5f 76 61 6c 75  qlite3_bind_valu
4b30: 65 28 70 43 75 72 2d 3e 70 53 74 6d 74 2c 20 69  e(pCur->pStmt, i
4b40: 2b 31 2c 20 61 72 67 76 5b 69 5d 29 3b 0a 20 20  +1, argv[i]);.  
4b50: 7d 0a 0a 20 20 2f 2a 20 49 66 20 65 76 65 72 79  }..  /* If every
4b60: 74 68 69 6e 67 20 77 61 73 20 73 75 63 63 65 73  thing was succes
4b70: 73 66 75 6c 2c 20 61 64 76 61 6e 63 65 20 74 6f  sful, advance to
4b80: 20 74 68 65 20 66 69 72 73 74 20 72 6f 77 20 6f   the first row o
4b90: 66 20 74 68 65 20 73 63 61 6e 20 2a 2f 0a 20 20  f the scan */.  
4ba0: 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  if( rc==SQLITE_O
4bb0: 4b 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 65 63  K ){.    rc = ec
4bc0: 68 6f 4e 65 78 74 28 70 56 74 61 62 43 75 72 73  hoNext(pVtabCurs
4bd0: 6f 72 29 3b 0a 20 20 7d 0a 0a 20 20 72 65 74 75  or);.  }..  retu
4be0: 72 6e 20 72 63 3b 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a  rn rc;.}.../*.**
4bf0: 20 41 20 68 65 6c 70 65 72 20 66 75 6e 63 74 69   A helper functi
4c00: 6f 6e 20 75 73 65 64 20 62 79 20 65 63 68 6f 55  on used by echoU
4c10: 70 64 61 74 65 28 29 20 61 6e 64 20 65 63 68 6f  pdate() and echo
4c20: 42 65 73 74 49 6e 64 65 78 28 29 20 66 6f 72 0a  BestIndex() for.
4c30: 2a 2a 20 6d 61 6e 69 70 75 6c 61 74 69 6e 67 20  ** manipulating 
4c40: 73 74 72 69 6e 67 73 20 69 6e 20 63 6f 6e 63 65  strings in conce
4c50: 72 74 20 77 69 74 68 20 74 68 65 20 73 71 6c 69  rt with the sqli
4c60: 74 65 33 5f 6d 70 72 69 6e 74 66 28 29 20 66 75  te3_mprintf() fu
4c70: 6e 63 74 69 6f 6e 2e 0a 2a 2a 0a 2a 2a 20 50 61  nction..**.** Pa
4c80: 72 61 6d 65 74 65 72 20 70 7a 53 74 72 20 70 6f  rameter pzStr po
4c90: 69 6e 74 73 20 74 6f 20 61 20 70 6f 69 6e 74 65  ints to a pointe
4ca0: 72 20 74 6f 20 61 20 73 74 72 69 6e 67 20 61 6c  r to a string al
4cb0: 6c 6f 63 61 74 65 64 20 77 69 74 68 0a 2a 2a 20  located with.** 
4cc0: 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 2e  sqlite3_mprintf.
4cd0: 20 54 68 65 20 73 65 63 6f 6e 64 20 70 61 72 61   The second para
4ce0: 6d 65 74 65 72 2c 20 7a 41 70 70 65 6e 64 2c 20  meter, zAppend, 
4cf0: 70 6f 69 6e 74 73 20 74 6f 20 61 6e 6f 74 68 65  points to anothe
4d00: 72 0a 2a 2a 20 73 74 72 69 6e 67 2e 20 54 68 65  r.** string. The
4d10: 20 74 77 6f 20 73 74 72 69 6e 67 73 20 61 72 65   two strings are
4d20: 20 63 6f 6e 63 61 74 65 6e 61 74 65 64 20 74 6f   concatenated to
4d30: 67 65 74 68 65 72 20 61 6e 64 20 2a 70 7a 53 74  gether and *pzSt
4d40: 72 0a 2a 2a 20 73 65 74 20 74 6f 20 70 6f 69 6e  r.** set to poin
4d50: 74 20 61 74 20 74 68 65 20 72 65 73 75 6c 74 2e  t at the result.
4d60: 20 54 68 65 20 69 6e 69 74 69 61 6c 20 62 75 66   The initial buf
4d70: 66 65 72 20 70 6f 69 6e 74 65 64 20 74 6f 20 62  fer pointed to b
4d80: 79 20 2a 70 7a 53 74 72 0a 2a 2a 20 69 73 20 64  y *pzStr.** is d
4d90: 65 61 6c 6c 6f 63 61 74 65 64 20 76 69 61 20 73  eallocated via s
4da0: 71 6c 69 74 65 33 5f 66 72 65 65 28 29 2e 0a 2a  qlite3_free()..*
4db0: 2a 0a 2a 2a 20 49 66 20 74 68 65 20 74 68 69 72  *.** If the thir
4dc0: 64 20 61 72 67 75 6d 65 6e 74 2c 20 64 6f 46 72  d argument, doFr
4dd0: 65 65 2c 20 69 73 20 74 72 75 65 2c 20 74 68 65  ee, is true, the
4de0: 6e 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 29  n sqlite3_free()
4df0: 20 69 73 0a 2a 2a 20 61 6c 73 6f 20 63 61 6c 6c   is.** also call
4e00: 65 64 20 74 6f 20 66 72 65 65 20 74 68 65 20 62  ed to free the b
4e10: 75 66 66 65 72 20 70 6f 69 6e 74 65 64 20 74 6f  uffer pointed to
4e20: 20 62 79 20 7a 41 70 70 65 6e 64 2e 0a 2a 2f 0a   by zAppend..*/.
4e30: 73 74 61 74 69 63 20 76 6f 69 64 20 73 74 72 69  static void stri
4e40: 6e 67 5f 63 6f 6e 63 61 74 28 63 68 61 72 20 2a  ng_concat(char *
4e50: 2a 70 7a 53 74 72 2c 20 63 68 61 72 20 2a 7a 41  *pzStr, char *zA
4e60: 70 70 65 6e 64 2c 20 69 6e 74 20 64 6f 46 72 65  ppend, int doFre
4e70: 65 2c 20 69 6e 74 20 2a 70 52 63 29 7b 0a 20 20  e, int *pRc){.  
4e80: 63 68 61 72 20 2a 7a 49 6e 20 3d 20 2a 70 7a 53  char *zIn = *pzS
4e90: 74 72 3b 0a 20 20 69 66 28 20 21 7a 41 70 70 65  tr;.  if( !zAppe
4ea0: 6e 64 20 26 26 20 64 6f 46 72 65 65 20 26 26 20  nd && doFree && 
4eb0: 2a 70 52 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  *pRc==SQLITE_OK 
4ec0: 29 7b 0a 20 20 20 20 2a 70 52 63 20 3d 20 53 51  ){.    *pRc = SQ
4ed0: 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 7d 0a  LITE_NOMEM;.  }.
4ee0: 20 20 69 66 28 20 2a 70 52 63 21 3d 53 51 4c 49    if( *pRc!=SQLI
4ef0: 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 73 71 6c  TE_OK ){.    sql
4f00: 69 74 65 33 5f 66 72 65 65 28 7a 49 6e 29 3b 0a  ite3_free(zIn);.
4f10: 20 20 20 20 7a 49 6e 20 3d 20 30 3b 0a 20 20 7d      zIn = 0;.  }
4f20: 65 6c 73 65 7b 0a 20 20 20 20 69 66 28 20 7a 49  else{.    if( zI
4f30: 6e 20 29 7b 0a 20 20 20 20 20 20 63 68 61 72 20  n ){.      char 
4f40: 2a 7a 54 65 6d 70 20 3d 20 7a 49 6e 3b 0a 20 20  *zTemp = zIn;.  
4f50: 20 20 20 20 7a 49 6e 20 3d 20 73 71 6c 69 74 65      zIn = sqlite
4f60: 33 5f 6d 70 72 69 6e 74 66 28 22 25 73 25 73 22  3_mprintf("%s%s"
4f70: 2c 20 7a 49 6e 2c 20 7a 41 70 70 65 6e 64 29 3b  , zIn, zAppend);
4f80: 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 66  .      sqlite3_f
4f90: 72 65 65 28 7a 54 65 6d 70 29 3b 0a 20 20 20 20  ree(zTemp);.    
4fa0: 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 7a 49 6e  }else{.      zIn
4fb0: 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e   = sqlite3_mprin
4fc0: 74 66 28 22 25 73 22 2c 20 7a 41 70 70 65 6e 64  tf("%s", zAppend
4fd0: 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 28  );.    }.    if(
4fe0: 20 21 7a 49 6e 20 29 7b 0a 20 20 20 20 20 20 2a   !zIn ){.      *
4ff0: 70 52 63 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d  pRc = SQLITE_NOM
5000: 45 4d 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20  EM;.    }.  }.  
5010: 2a 70 7a 53 74 72 20 3d 20 7a 49 6e 3b 0a 20 20  *pzStr = zIn;.  
5020: 69 66 28 20 64 6f 46 72 65 65 20 29 7b 0a 20 20  if( doFree ){.  
5030: 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 7a    sqlite3_free(z
5040: 41 70 70 65 6e 64 29 3b 0a 20 20 7d 0a 7d 0a 0a  Append);.  }.}..
5050: 2f 2a 0a 2a 2a 20 54 68 65 20 65 63 68 6f 20 6d  /*.** The echo m
5060: 6f 64 75 6c 65 20 69 6d 70 6c 65 6d 65 6e 74 73  odule implements
5070: 20 74 68 65 20 73 75 62 73 65 74 20 6f 66 20 71   the subset of q
5080: 75 65 72 79 20 63 6f 6e 73 74 72 61 69 6e 74 73  uery constraints
5090: 20 61 6e 64 20 73 6f 72 74 0a 2a 2a 20 6f 72 64   and sort.** ord
50a0: 65 72 73 20 74 68 61 74 20 6d 61 79 20 74 61 6b  ers that may tak
50b0: 65 20 61 64 76 61 6e 74 61 67 65 20 6f 66 20 53  e advantage of S
50c0: 51 4c 69 74 65 20 69 6e 64 69 63 65 73 20 6f 6e  QLite indices on
50d0: 20 74 68 65 20 75 6e 64 65 72 6c 79 69 6e 67 0a   the underlying.
50e0: 2a 2a 20 72 65 61 6c 20 74 61 62 6c 65 2e 20 46  ** real table. F
50f0: 6f 72 20 65 78 61 6d 70 6c 65 2c 20 69 66 20 74  or example, if t
5100: 68 65 20 72 65 61 6c 20 74 61 62 6c 65 20 69 73  he real table is
5110: 20 64 65 63 6c 61 72 65 64 20 61 73 3a 0a 2a 2a   declared as:.**
5120: 0a 2a 2a 20 20 20 20 20 43 52 45 41 54 45 20 54  .**     CREATE T
5130: 41 42 4c 45 20 72 65 61 6c 28 61 2c 20 62 2c 20  ABLE real(a, b, 
5140: 63 29 3b 0a 2a 2a 20 20 20 20 20 43 52 45 41 54  c);.**     CREAT
5150: 45 20 49 4e 44 45 58 20 72 65 61 6c 5f 69 6e 64  E INDEX real_ind
5160: 65 78 20 4f 4e 20 72 65 61 6c 28 62 29 3b 0a 2a  ex ON real(b);.*
5170: 2a 0a 2a 2a 20 74 68 65 6e 20 74 68 65 20 65 63  *.** then the ec
5180: 68 6f 20 6d 6f 64 75 6c 65 20 68 61 6e 64 6c 65  ho module handle
5190: 73 20 57 48 45 52 45 20 6f 72 20 4f 52 44 45 52  s WHERE or ORDER
51a0: 20 42 59 20 63 6c 61 75 73 65 73 20 74 68 61 74   BY clauses that
51b0: 20 72 65 66 65 72 0a 2a 2a 20 74 6f 20 74 68 65   refer.** to the
51c0: 20 63 6f 6c 75 6d 6e 20 22 62 22 2c 20 62 75 74   column "b", but
51d0: 20 6e 6f 74 20 22 61 22 20 6f 72 20 22 63 22 2e   not "a" or "c".
51e0: 20 49 66 20 61 20 6d 75 6c 74 69 2d 63 6f 6c 75   If a multi-colu
51f0: 6d 6e 20 69 6e 64 65 78 20 69 73 0a 2a 2a 20 70  mn index is.** p
5200: 72 65 73 65 6e 74 2c 20 6f 6e 6c 79 20 69 74 73  resent, only its
5210: 20 6c 65 66 74 20 6d 6f 73 74 20 63 6f 6c 75 6d   left most colum
5220: 6e 20 69 73 20 63 6f 6e 73 69 64 65 72 65 64 2e  n is considered.
5230: 20 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20 78 42 65   .**.** This xBe
5240: 73 74 49 6e 64 65 78 20 6d 65 74 68 6f 64 20 65  stIndex method e
5250: 6e 63 6f 64 65 73 20 74 68 65 20 70 72 6f 70 6f  ncodes the propo
5260: 73 65 64 20 73 65 61 72 63 68 20 73 74 72 61 74  sed search strat
5270: 65 67 79 20 61 73 0a 2a 2a 20 61 6e 20 53 51 4c  egy as.** an SQL
5280: 20 71 75 65 72 79 20 6f 6e 20 74 68 65 20 72 65   query on the re
5290: 61 6c 20 74 61 62 6c 65 20 75 6e 64 65 72 6c 79  al table underly
52a0: 69 6e 67 20 74 68 65 20 76 69 72 74 75 61 6c 20  ing the virtual 
52b0: 65 63 68 6f 20 6d 6f 64 75 6c 65 20 0a 2a 2a 20  echo module .** 
52c0: 74 61 62 6c 65 20 61 6e 64 20 73 74 6f 72 65 73  table and stores
52d0: 20 74 68 65 20 71 75 65 72 79 20 69 6e 20 73 71   the query in sq
52e0: 6c 69 74 65 33 5f 69 6e 64 65 78 5f 69 6e 66 6f  lite3_index_info
52f0: 2e 69 64 78 53 74 72 2e 20 54 68 65 20 53 51 4c  .idxStr. The SQL
5300: 0a 2a 2a 20 73 74 61 74 65 6d 65 6e 74 20 69 73  .** statement is
5310: 20 6f 66 20 74 68 65 20 66 6f 72 6d 3a 0a 2a 2a   of the form:.**
5320: 0a 2a 2a 20 20 20 53 45 4c 45 43 54 20 72 6f 77  .**   SELECT row
5330: 69 64 2c 20 2a 20 46 52 4f 4d 20 3c 72 65 61 6c  id, * FROM <real
5340: 2d 74 61 62 6c 65 3e 20 3f 3c 77 68 65 72 65 2d  -table> ?<where-
5350: 63 6c 61 75 73 65 3e 3f 20 3f 3c 6f 72 64 65 72  clause>? ?<order
5360: 2d 62 79 2d 63 6c 61 75 73 65 3e 3f 0a 2a 2a 0a  -by-clause>?.**.
5370: 2a 2a 20 77 68 65 72 65 20 74 68 65 20 3c 77 68  ** where the <wh
5380: 65 72 65 2d 63 6c 61 75 73 65 3e 20 61 6e 64 20  ere-clause> and 
5390: 3c 6f 72 64 65 72 2d 62 79 2d 63 6c 61 75 73 65  <order-by-clause
53a0: 3e 20 61 72 65 20 64 65 74 65 72 6d 69 6e 65 64  > are determined
53b0: 0a 2a 2a 20 62 79 20 74 68 65 20 63 6f 6e 74 65  .** by the conte
53c0: 6e 74 73 20 6f 66 20 74 68 65 20 73 74 72 75 63  nts of the struc
53d0: 74 75 72 65 20 70 6f 69 6e 74 65 64 20 74 6f 20  ture pointed to 
53e0: 62 79 20 74 68 65 20 70 49 64 78 49 6e 66 6f 20  by the pIdxInfo 
53f0: 61 72 67 75 6d 65 6e 74 2e 0a 2a 2f 0a 73 74 61  argument..*/.sta
5400: 74 69 63 20 69 6e 74 20 65 63 68 6f 42 65 73 74  tic int echoBest
5410: 49 6e 64 65 78 28 73 71 6c 69 74 65 33 5f 76 74  Index(sqlite3_vt
5420: 61 62 20 2a 74 61 62 2c 20 73 71 6c 69 74 65 33  ab *tab, sqlite3
5430: 5f 69 6e 64 65 78 5f 69 6e 66 6f 20 2a 70 49 64  _index_info *pId
5440: 78 49 6e 66 6f 29 7b 0a 20 20 69 6e 74 20 69 69  xInfo){.  int ii
5450: 3b 0a 20 20 63 68 61 72 20 2a 7a 51 75 65 72 79  ;.  char *zQuery
5460: 20 3d 20 30 3b 0a 20 20 63 68 61 72 20 2a 7a 4e   = 0;.  char *zN
5470: 65 77 3b 0a 20 20 69 6e 74 20 6e 41 72 67 20 3d  ew;.  int nArg =
5480: 20 30 3b 0a 20 20 63 6f 6e 73 74 20 63 68 61 72   0;.  const char
5490: 20 2a 7a 53 65 70 20 3d 20 22 57 48 45 52 45 22   *zSep = "WHERE"
54a0: 3b 0a 20 20 65 63 68 6f 5f 76 74 61 62 20 2a 70  ;.  echo_vtab *p
54b0: 56 74 61 62 20 3d 20 28 65 63 68 6f 5f 76 74 61  Vtab = (echo_vta
54c0: 62 20 2a 29 74 61 62 3b 0a 20 20 73 71 6c 69 74  b *)tab;.  sqlit
54d0: 65 33 5f 73 74 6d 74 20 2a 70 53 74 6d 74 20 3d  e3_stmt *pStmt =
54e0: 20 30 3b 0a 20 20 54 63 6c 5f 49 6e 74 65 72 70   0;.  Tcl_Interp
54f0: 20 2a 69 6e 74 65 72 70 20 3d 20 70 56 74 61 62   *interp = pVtab
5500: 2d 3e 69 6e 74 65 72 70 3b 0a 0a 20 20 69 6e 74  ->interp;..  int
5510: 20 6e 52 6f 77 3b 0a 20 20 69 6e 74 20 75 73 65   nRow;.  int use
5520: 49 64 78 20 3d 20 30 3b 0a 20 20 69 6e 74 20 72  Idx = 0;.  int r
5530: 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20  c = SQLITE_OK;. 
5540: 20 69 6e 74 20 75 73 65 43 6f 73 74 20 3d 20 30   int useCost = 0
5550: 3b 0a 20 20 64 6f 75 62 6c 65 20 63 6f 73 74 3b  ;.  double cost;
5560: 0a 20 20 69 6e 74 20 69 73 49 67 6e 6f 72 65 55  .  int isIgnoreU
5570: 73 61 62 6c 65 20 3d 20 30 3b 0a 20 20 69 66 28  sable = 0;.  if(
5580: 20 54 63 6c 5f 47 65 74 56 61 72 28 69 6e 74 65   Tcl_GetVar(inte
5590: 72 70 2c 20 22 65 63 68 6f 5f 6d 6f 64 75 6c 65  rp, "echo_module
55a0: 5f 69 67 6e 6f 72 65 5f 75 73 61 62 6c 65 22 2c  _ignore_usable",
55b0: 20 54 43 4c 5f 47 4c 4f 42 41 4c 5f 4f 4e 4c 59   TCL_GLOBAL_ONLY
55c0: 29 20 29 7b 0a 20 20 20 20 69 73 49 67 6e 6f 72  ) ){.    isIgnor
55d0: 65 55 73 61 62 6c 65 20 3d 20 31 3b 0a 20 20 7d  eUsable = 1;.  }
55e0: 0a 0a 20 20 69 66 28 20 73 69 6d 75 6c 61 74 65  ..  if( simulate
55f0: 56 74 61 62 45 72 72 6f 72 28 70 56 74 61 62 2c  VtabError(pVtab,
5600: 20 22 78 42 65 73 74 49 6e 64 65 78 22 29 20 29   "xBestIndex") )
5610: 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c  {.    return SQL
5620: 49 54 45 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a 0a  ITE_ERROR;.  }..
5630: 20 20 2f 2a 20 44 65 74 65 72 6d 69 6e 65 20 74    /* Determine t
5640: 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 72 6f 77  he number of row
5650: 73 20 69 6e 20 74 68 65 20 74 61 62 6c 65 20 61  s in the table a
5660: 6e 64 20 73 74 6f 72 65 20 74 68 69 73 20 76 61  nd store this va
5670: 6c 75 65 20 69 6e 20 6c 6f 63 61 6c 0a 20 20 2a  lue in local.  *
5680: 2a 20 76 61 72 69 61 62 6c 65 20 6e 52 6f 77 2e  * variable nRow.
5690: 20 54 68 65 20 27 65 73 74 69 6d 61 74 65 64 2d   The 'estimated-
56a0: 63 6f 73 74 27 20 6f 66 20 74 68 65 20 73 63 61  cost' of the sca
56b0: 6e 20 77 69 6c 6c 20 62 65 20 74 68 65 20 6e 75  n will be the nu
56c0: 6d 62 65 72 20 6f 66 0a 20 20 2a 2a 20 72 6f 77  mber of.  ** row
56d0: 73 20 69 6e 20 74 68 65 20 74 61 62 6c 65 20 66  s in the table f
56e0: 6f 72 20 61 20 6c 69 6e 65 61 72 20 73 63 61 6e  or a linear scan
56f0: 2c 20 6f 72 20 74 68 65 20 6c 6f 67 20 28 62 61  , or the log (ba
5700: 73 65 20 32 29 20 6f 66 20 74 68 65 20 0a 20 20  se 2) of the .  
5710: 2a 2a 20 6e 75 6d 62 65 72 20 6f 66 20 72 6f 77  ** number of row
5720: 73 20 69 66 20 74 68 65 20 70 72 6f 70 6f 73 65  s if the propose
5730: 64 20 73 63 61 6e 20 75 73 65 73 20 61 6e 20 69  d scan uses an i
5740: 6e 64 65 78 2e 20 20 0a 20 20 2a 2f 0a 20 20 69  ndex.  .  */.  i
5750: 66 28 20 54 63 6c 5f 47 65 74 56 61 72 28 69 6e  f( Tcl_GetVar(in
5760: 74 65 72 70 2c 20 22 65 63 68 6f 5f 6d 6f 64 75  terp, "echo_modu
5770: 6c 65 5f 63 6f 73 74 22 2c 20 54 43 4c 5f 47 4c  le_cost", TCL_GL
5780: 4f 42 41 4c 5f 4f 4e 4c 59 29 20 29 7b 0a 20 20  OBAL_ONLY) ){.  
5790: 20 20 63 6f 73 74 20 3d 20 61 74 6f 66 28 54 63    cost = atof(Tc
57a0: 6c 5f 47 65 74 56 61 72 28 69 6e 74 65 72 70 2c  l_GetVar(interp,
57b0: 20 22 65 63 68 6f 5f 6d 6f 64 75 6c 65 5f 63 6f   "echo_module_co
57c0: 73 74 22 2c 20 54 43 4c 5f 47 4c 4f 42 41 4c 5f  st", TCL_GLOBAL_
57d0: 4f 4e 4c 59 29 29 3b 0a 20 20 20 20 75 73 65 43  ONLY));.    useC
57e0: 6f 73 74 20 3d 20 31 3b 0a 20 20 7d 20 65 6c 73  ost = 1;.  } els
57f0: 65 20 7b 0a 20 20 20 20 7a 51 75 65 72 79 20 3d  e {.    zQuery =
5800: 20 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66   sqlite3_mprintf
5810: 28 22 53 45 4c 45 43 54 20 63 6f 75 6e 74 28 2a  ("SELECT count(*
5820: 29 20 46 52 4f 4d 20 25 51 22 2c 20 70 56 74 61  ) FROM %Q", pVta
5830: 62 2d 3e 7a 54 61 62 6c 65 4e 61 6d 65 29 3b 0a  b->zTableName);.
5840: 20 20 20 20 69 66 28 20 21 7a 51 75 65 72 79 20      if( !zQuery 
5850: 29 7b 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20  ){.      return 
5860: 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20  SQLITE_NOMEM;.  
5870: 20 20 7d 0a 20 20 20 20 72 63 20 3d 20 73 71 6c    }.    rc = sql
5880: 69 74 65 33 5f 70 72 65 70 61 72 65 28 70 56 74  ite3_prepare(pVt
5890: 61 62 2d 3e 64 62 2c 20 7a 51 75 65 72 79 2c 20  ab->db, zQuery, 
58a0: 2d 31 2c 20 26 70 53 74 6d 74 2c 20 30 29 3b 0a  -1, &pStmt, 0);.
58b0: 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65      sqlite3_free
58c0: 28 7a 51 75 65 72 79 29 3b 0a 20 20 20 20 69 66  (zQuery);.    if
58d0: 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc!=SQLITE_OK 
58e0: 29 7b 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20  ){.      return 
58f0: 72 63 3b 0a 20 20 20 20 7d 0a 20 20 20 20 73 71  rc;.    }.    sq
5900: 6c 69 74 65 33 5f 73 74 65 70 28 70 53 74 6d 74  lite3_step(pStmt
5910: 29 3b 0a 20 20 20 20 6e 52 6f 77 20 3d 20 73 71  );.    nRow = sq
5920: 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 69 6e 74  lite3_column_int
5930: 28 70 53 74 6d 74 2c 20 30 29 3b 0a 20 20 20 20  (pStmt, 0);.    
5940: 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 66 69 6e  rc = sqlite3_fin
5950: 61 6c 69 7a 65 28 70 53 74 6d 74 29 3b 0a 20 20  alize(pStmt);.  
5960: 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45    if( rc!=SQLITE
5970: 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 72 65 74  _OK ){.      ret
5980: 75 72 6e 20 72 63 3b 0a 20 20 20 20 7d 0a 20 20  urn rc;.    }.  
5990: 7d 0a 0a 20 20 7a 51 75 65 72 79 20 3d 20 73 71  }..  zQuery = sq
59a0: 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 22 53  lite3_mprintf("S
59b0: 45 4c 45 43 54 20 72 6f 77 69 64 2c 20 2a 20 46  ELECT rowid, * F
59c0: 52 4f 4d 20 25 51 22 2c 20 70 56 74 61 62 2d 3e  ROM %Q", pVtab->
59d0: 7a 54 61 62 6c 65 4e 61 6d 65 29 3b 0a 20 20 69  zTableName);.  i
59e0: 66 28 20 21 7a 51 75 65 72 79 20 29 7b 0a 20 20  f( !zQuery ){.  
59f0: 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f    return SQLITE_
5a00: 4e 4f 4d 45 4d 3b 0a 20 20 7d 0a 20 20 66 6f 72  NOMEM;.  }.  for
5a10: 28 69 69 3d 30 3b 20 69 69 3c 70 49 64 78 49 6e  (ii=0; ii<pIdxIn
5a20: 66 6f 2d 3e 6e 43 6f 6e 73 74 72 61 69 6e 74 3b  fo->nConstraint;
5a30: 20 69 69 2b 2b 29 7b 0a 20 20 20 20 63 6f 6e 73   ii++){.    cons
5a40: 74 20 73 74 72 75 63 74 20 73 71 6c 69 74 65 33  t struct sqlite3
5a50: 5f 69 6e 64 65 78 5f 63 6f 6e 73 74 72 61 69 6e  _index_constrain
5a60: 74 20 2a 70 43 6f 6e 73 74 72 61 69 6e 74 3b 0a  t *pConstraint;.
5a70: 20 20 20 20 73 74 72 75 63 74 20 73 71 6c 69 74      struct sqlit
5a80: 65 33 5f 69 6e 64 65 78 5f 63 6f 6e 73 74 72 61  e3_index_constra
5a90: 69 6e 74 5f 75 73 61 67 65 20 2a 70 55 73 61 67  int_usage *pUsag
5aa0: 65 3b 0a 20 20 20 20 69 6e 74 20 69 43 6f 6c 3b  e;.    int iCol;
5ab0: 0a 0a 20 20 20 20 70 43 6f 6e 73 74 72 61 69 6e  ..    pConstrain
5ac0: 74 20 3d 20 26 70 49 64 78 49 6e 66 6f 2d 3e 61  t = &pIdxInfo->a
5ad0: 43 6f 6e 73 74 72 61 69 6e 74 5b 69 69 5d 3b 0a  Constraint[ii];.
5ae0: 20 20 20 20 70 55 73 61 67 65 20 3d 20 26 70 49      pUsage = &pI
5af0: 64 78 49 6e 66 6f 2d 3e 61 43 6f 6e 73 74 72 61  dxInfo->aConstra
5b00: 69 6e 74 55 73 61 67 65 5b 69 69 5d 3b 0a 0a 20  intUsage[ii];.. 
5b10: 20 20 20 69 66 28 20 21 69 73 49 67 6e 6f 72 65     if( !isIgnore
5b20: 55 73 61 62 6c 65 20 26 26 20 21 70 43 6f 6e 73  Usable && !pCons
5b30: 74 72 61 69 6e 74 2d 3e 75 73 61 62 6c 65 20 29  traint->usable )
5b40: 20 63 6f 6e 74 69 6e 75 65 3b 0a 0a 20 20 20 20   continue;..    
5b50: 69 43 6f 6c 20 3d 20 70 43 6f 6e 73 74 72 61 69  iCol = pConstrai
5b60: 6e 74 2d 3e 69 43 6f 6c 75 6d 6e 3b 0a 20 20 20  nt->iColumn;.   
5b70: 20 69 66 28 20 70 56 74 61 62 2d 3e 61 49 6e 64   if( pVtab->aInd
5b80: 65 78 5b 69 43 6f 6c 5d 20 7c 7c 20 69 43 6f 6c  ex[iCol] || iCol
5b90: 3c 30 20 29 7b 0a 20 20 20 20 20 20 63 68 61 72  <0 ){.      char
5ba0: 20 2a 7a 43 6f 6c 20 3d 20 70 56 74 61 62 2d 3e   *zCol = pVtab->
5bb0: 61 43 6f 6c 5b 69 43 6f 6c 5d 3b 0a 20 20 20 20  aCol[iCol];.    
5bc0: 20 20 63 68 61 72 20 2a 7a 4f 70 20 3d 20 30 3b    char *zOp = 0;
5bd0: 0a 20 20 20 20 20 20 75 73 65 49 64 78 20 3d 20  .      useIdx = 
5be0: 31 3b 0a 20 20 20 20 20 20 69 66 28 20 69 43 6f  1;.      if( iCo
5bf0: 6c 3c 30 20 29 7b 0a 20 20 20 20 20 20 20 20 7a  l<0 ){.        z
5c00: 43 6f 6c 20 3d 20 22 72 6f 77 69 64 22 3b 0a 20  Col = "rowid";. 
5c10: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 73 77 69       }.      swi
5c20: 74 63 68 28 20 70 43 6f 6e 73 74 72 61 69 6e 74  tch( pConstraint
5c30: 2d 3e 6f 70 20 29 7b 0a 20 20 20 20 20 20 20 20  ->op ){.        
5c40: 63 61 73 65 20 53 51 4c 49 54 45 5f 49 4e 44 45  case SQLITE_INDE
5c50: 58 5f 43 4f 4e 53 54 52 41 49 4e 54 5f 45 51 3a  X_CONSTRAINT_EQ:
5c60: 0a 20 20 20 20 20 20 20 20 20 20 7a 4f 70 20 3d  .          zOp =
5c70: 20 22 3d 22 3b 20 62 72 65 61 6b 3b 0a 20 20 20   "="; break;.   
5c80: 20 20 20 20 20 63 61 73 65 20 53 51 4c 49 54 45       case SQLITE
5c90: 5f 49 4e 44 45 58 5f 43 4f 4e 53 54 52 41 49 4e  _INDEX_CONSTRAIN
5ca0: 54 5f 4c 54 3a 0a 20 20 20 20 20 20 20 20 20 20  T_LT:.          
5cb0: 7a 4f 70 20 3d 20 22 3c 22 3b 20 62 72 65 61 6b  zOp = "<"; break
5cc0: 3b 0a 20 20 20 20 20 20 20 20 63 61 73 65 20 53  ;.        case S
5cd0: 51 4c 49 54 45 5f 49 4e 44 45 58 5f 43 4f 4e 53  QLITE_INDEX_CONS
5ce0: 54 52 41 49 4e 54 5f 47 54 3a 0a 20 20 20 20 20  TRAINT_GT:.     
5cf0: 20 20 20 20 20 7a 4f 70 20 3d 20 22 3e 22 3b 20       zOp = ">"; 
5d00: 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 20 20 63  break;.        c
5d10: 61 73 65 20 53 51 4c 49 54 45 5f 49 4e 44 45 58  ase SQLITE_INDEX
5d20: 5f 43 4f 4e 53 54 52 41 49 4e 54 5f 4c 45 3a 0a  _CONSTRAINT_LE:.
5d30: 20 20 20 20 20 20 20 20 20 20 7a 4f 70 20 3d 20            zOp = 
5d40: 22 3c 3d 22 3b 20 62 72 65 61 6b 3b 0a 20 20 20  "<="; break;.   
5d50: 20 20 20 20 20 63 61 73 65 20 53 51 4c 49 54 45       case SQLITE
5d60: 5f 49 4e 44 45 58 5f 43 4f 4e 53 54 52 41 49 4e  _INDEX_CONSTRAIN
5d70: 54 5f 47 45 3a 0a 20 20 20 20 20 20 20 20 20 20  T_GE:.          
5d80: 7a 4f 70 20 3d 20 22 3e 3d 22 3b 20 62 72 65 61  zOp = ">="; brea
5d90: 6b 3b 0a 20 20 20 20 20 20 20 20 63 61 73 65 20  k;.        case 
5da0: 53 51 4c 49 54 45 5f 49 4e 44 45 58 5f 43 4f 4e  SQLITE_INDEX_CON
5db0: 53 54 52 41 49 4e 54 5f 4d 41 54 43 48 3a 0a 20  STRAINT_MATCH:. 
5dc0: 20 20 20 20 20 20 20 20 20 7a 4f 70 20 3d 20 22           zOp = "
5dd0: 4c 49 4b 45 22 3b 20 62 72 65 61 6b 3b 0a 20 20  LIKE"; break;.  
5de0: 20 20 20 20 7d 0a 20 20 20 20 20 20 69 66 28 20      }.      if( 
5df0: 7a 4f 70 5b 30 5d 3d 3d 27 4c 27 20 29 7b 0a 20  zOp[0]=='L' ){. 
5e00: 20 20 20 20 20 20 20 7a 4e 65 77 20 3d 20 73 71         zNew = sq
5e10: 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 22 20  lite3_mprintf(" 
5e20: 25 73 20 25 73 20 4c 49 4b 45 20 28 53 45 4c 45  %s %s LIKE (SELE
5e30: 43 54 20 27 25 25 27 7c 7c 3f 7c 7c 27 25 25 27  CT '%%'||?||'%%'
5e40: 29 22 2c 20 0a 20 20 20 20 20 20 20 20 20 20 20  )", .           
5e50: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5e60: 20 20 20 20 7a 53 65 70 2c 20 7a 43 6f 6c 29 3b      zSep, zCol);
5e70: 0a 20 20 20 20 20 20 7d 20 65 6c 73 65 20 7b 0a  .      } else {.
5e80: 20 20 20 20 20 20 20 20 7a 4e 65 77 20 3d 20 73          zNew = s
5e90: 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 22  qlite3_mprintf("
5ea0: 20 25 73 20 25 73 20 25 73 20 3f 22 2c 20 7a 53   %s %s %s ?", zS
5eb0: 65 70 2c 20 7a 43 6f 6c 2c 20 7a 4f 70 29 3b 0a  ep, zCol, zOp);.
5ec0: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 73 74        }.      st
5ed0: 72 69 6e 67 5f 63 6f 6e 63 61 74 28 26 7a 51 75  ring_concat(&zQu
5ee0: 65 72 79 2c 20 7a 4e 65 77 2c 20 31 2c 20 26 72  ery, zNew, 1, &r
5ef0: 63 29 3b 0a 0a 20 20 20 20 20 20 7a 53 65 70 20  c);..      zSep 
5f00: 3d 20 22 41 4e 44 22 3b 0a 20 20 20 20 20 20 70  = "AND";.      p
5f10: 55 73 61 67 65 2d 3e 61 72 67 76 49 6e 64 65 78  Usage->argvIndex
5f20: 20 3d 20 2b 2b 6e 41 72 67 3b 0a 20 20 20 20 20   = ++nArg;.     
5f30: 20 70 55 73 61 67 65 2d 3e 6f 6d 69 74 20 3d 20   pUsage->omit = 
5f40: 31 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20  1;.    }.  }..  
5f50: 2f 2a 20 49 66 20 74 68 65 72 65 20 69 73 20 6f  /* If there is o
5f60: 6e 6c 79 20 6f 6e 65 20 74 65 72 6d 20 69 6e 20  nly one term in 
5f70: 74 68 65 20 4f 52 44 45 52 20 42 59 20 63 6c 61  the ORDER BY cla
5f80: 75 73 65 2c 20 61 6e 64 20 69 74 20 69 73 0a 20  use, and it is. 
5f90: 20 2a 2a 20 6f 6e 20 61 20 63 6f 6c 75 6d 6e 20   ** on a column 
5fa0: 74 68 61 74 20 74 68 69 73 20 76 69 72 74 75 61  that this virtua
5fb0: 6c 20 74 61 62 6c 65 20 68 61 73 20 61 6e 20 69  l table has an i
5fc0: 6e 64 65 78 20 66 6f 72 2c 20 74 68 65 6e 20 63  ndex for, then c
5fd0: 6f 6e 73 75 6d 65 20 0a 20 20 2a 2a 20 74 68 65  onsume .  ** the
5fe0: 20 4f 52 44 45 52 20 42 59 20 63 6c 61 75 73 65   ORDER BY clause
5ff0: 2e 0a 20 20 2a 2f 0a 20 20 69 66 28 20 70 49 64  ..  */.  if( pId
6000: 78 49 6e 66 6f 2d 3e 6e 4f 72 64 65 72 42 79 3d  xInfo->nOrderBy=
6010: 3d 31 20 26 26 20 70 56 74 61 62 2d 3e 61 49 6e  =1 && pVtab->aIn
6020: 64 65 78 5b 70 49 64 78 49 6e 66 6f 2d 3e 61 4f  dex[pIdxInfo->aO
6030: 72 64 65 72 42 79 2d 3e 69 43 6f 6c 75 6d 6e 5d  rderBy->iColumn]
6040: 20 29 7b 0a 20 20 20 20 69 6e 74 20 69 43 6f 6c   ){.    int iCol
6050: 20 3d 20 70 49 64 78 49 6e 66 6f 2d 3e 61 4f 72   = pIdxInfo->aOr
6060: 64 65 72 42 79 2d 3e 69 43 6f 6c 75 6d 6e 3b 0a  derBy->iColumn;.
6070: 20 20 20 20 63 68 61 72 20 2a 7a 43 6f 6c 20 3d      char *zCol =
6080: 20 70 56 74 61 62 2d 3e 61 43 6f 6c 5b 69 43 6f   pVtab->aCol[iCo
6090: 6c 5d 3b 0a 20 20 20 20 63 68 61 72 20 2a 7a 44  l];.    char *zD
60a0: 69 72 20 3d 20 70 49 64 78 49 6e 66 6f 2d 3e 61  ir = pIdxInfo->a
60b0: 4f 72 64 65 72 42 79 2d 3e 64 65 73 63 3f 22 44  OrderBy->desc?"D
60c0: 45 53 43 22 3a 22 41 53 43 22 3b 0a 20 20 20 20  ESC":"ASC";.    
60d0: 69 66 28 20 69 43 6f 6c 3c 30 20 29 7b 0a 20 20  if( iCol<0 ){.  
60e0: 20 20 20 20 7a 43 6f 6c 20 3d 20 22 72 6f 77 69      zCol = "rowi
60f0: 64 22 3b 0a 20 20 20 20 7d 0a 20 20 20 20 7a 4e  d";.    }.    zN
6100: 65 77 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72  ew = sqlite3_mpr
6110: 69 6e 74 66 28 22 20 4f 52 44 45 52 20 42 59 20  intf(" ORDER BY 
6120: 25 73 20 25 73 22 2c 20 7a 43 6f 6c 2c 20 7a 44  %s %s", zCol, zD
6130: 69 72 29 3b 0a 20 20 20 20 73 74 72 69 6e 67 5f  ir);.    string_
6140: 63 6f 6e 63 61 74 28 26 7a 51 75 65 72 79 2c 20  concat(&zQuery, 
6150: 7a 4e 65 77 2c 20 31 2c 20 26 72 63 29 3b 0a 20  zNew, 1, &rc);. 
6160: 20 20 20 70 49 64 78 49 6e 66 6f 2d 3e 6f 72 64     pIdxInfo->ord
6170: 65 72 42 79 43 6f 6e 73 75 6d 65 64 20 3d 20 31  erByConsumed = 1
6180: 3b 0a 20 20 7d 0a 0a 20 20 61 70 70 65 6e 64 54  ;.  }..  appendT
6190: 6f 45 63 68 6f 4d 6f 64 75 6c 65 28 70 56 74 61  oEchoModule(pVta
61a0: 62 2d 3e 69 6e 74 65 72 70 2c 20 22 78 42 65 73  b->interp, "xBes
61b0: 74 49 6e 64 65 78 22 29 3b 3b 0a 20 20 61 70 70  tIndex");;.  app
61c0: 65 6e 64 54 6f 45 63 68 6f 4d 6f 64 75 6c 65 28  endToEchoModule(
61d0: 70 56 74 61 62 2d 3e 69 6e 74 65 72 70 2c 20 7a  pVtab->interp, z
61e0: 51 75 65 72 79 29 3b 0a 0a 20 20 69 66 28 20 21  Query);..  if( !
61f0: 7a 51 75 65 72 79 20 29 7b 0a 20 20 20 20 72 65  zQuery ){.    re
6200: 74 75 72 6e 20 72 63 3b 0a 20 20 7d 0a 20 20 70  turn rc;.  }.  p
6210: 49 64 78 49 6e 66 6f 2d 3e 69 64 78 4e 75 6d 20  IdxInfo->idxNum 
6220: 3d 20 68 61 73 68 53 74 72 69 6e 67 28 7a 51 75  = hashString(zQu
6230: 65 72 79 29 3b 0a 20 20 70 49 64 78 49 6e 66 6f  ery);.  pIdxInfo
6240: 2d 3e 69 64 78 53 74 72 20 3d 20 7a 51 75 65 72  ->idxStr = zQuer
6250: 79 3b 0a 20 20 70 49 64 78 49 6e 66 6f 2d 3e 6e  y;.  pIdxInfo->n
6260: 65 65 64 54 6f 46 72 65 65 49 64 78 53 74 72 20  eedToFreeIdxStr 
6270: 3d 20 31 3b 0a 20 20 69 66 20 28 75 73 65 43 6f  = 1;.  if (useCo
6280: 73 74 29 20 7b 0a 20 20 20 20 70 49 64 78 49 6e  st) {.    pIdxIn
6290: 66 6f 2d 3e 65 73 74 69 6d 61 74 65 64 43 6f 73  fo->estimatedCos
62a0: 74 20 3d 20 63 6f 73 74 3b 0a 20 20 7d 20 65 6c  t = cost;.  } el
62b0: 73 65 20 69 66 28 20 75 73 65 49 64 78 20 29 7b  se if( useIdx ){
62c0: 0a 20 20 20 20 2f 2a 20 41 70 70 72 6f 78 69 6d  .    /* Approxim
62d0: 61 74 69 6f 6e 20 6f 66 20 6c 6f 67 32 28 6e 52  ation of log2(nR
62e0: 6f 77 29 2e 20 2a 2f 0a 20 20 20 20 66 6f 72 28  ow). */.    for(
62f0: 20 69 69 3d 30 3b 20 69 69 3c 28 73 69 7a 65 6f   ii=0; ii<(sizeo
6300: 66 28 69 6e 74 29 2a 38 29 3b 20 69 69 2b 2b 20  f(int)*8); ii++ 
6310: 29 7b 0a 20 20 20 20 20 20 69 66 28 20 6e 52 6f  ){.      if( nRo
6320: 77 20 26 20 28 31 3c 3c 69 69 29 20 29 7b 0a 20  w & (1<<ii) ){. 
6330: 20 20 20 20 20 20 20 70 49 64 78 49 6e 66 6f 2d         pIdxInfo-
6340: 3e 65 73 74 69 6d 61 74 65 64 43 6f 73 74 20 3d  >estimatedCost =
6350: 20 28 64 6f 75 62 6c 65 29 69 69 3b 0a 20 20 20   (double)ii;.   
6360: 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 20 65     }.    }.  } e
6370: 6c 73 65 20 7b 0a 20 20 20 20 70 49 64 78 49 6e  lse {.    pIdxIn
6380: 66 6f 2d 3e 65 73 74 69 6d 61 74 65 64 43 6f 73  fo->estimatedCos
6390: 74 20 3d 20 28 64 6f 75 62 6c 65 29 6e 52 6f 77  t = (double)nRow
63a0: 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 72  ;.  }.  return r
63b0: 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 65 20  c;.}../*.** The 
63c0: 78 55 70 64 61 74 65 20 6d 65 74 68 6f 64 20 66  xUpdate method f
63d0: 6f 72 20 65 63 68 6f 20 6d 6f 64 75 6c 65 20 76  or echo module v
63e0: 69 72 74 75 61 6c 20 74 61 62 6c 65 73 2e 0a 2a  irtual tables..*
63f0: 2a 20 0a 2a 2a 20 20 20 20 61 70 44 61 74 61 5b  * .**    apData[
6400: 30 5d 20 20 61 70 44 61 74 61 5b 31 5d 20 20 61  0]  apData[1]  a
6410: 70 44 61 74 61 5b 32 2e 2e 5d 0a 2a 2a 0a 2a 2a  pData[2..].**.**
6420: 20 20 20 20 49 4e 54 45 47 45 52 20 20 20 20 20      INTEGER     
6430: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6440: 20 20 20 20 20 20 20 20 20 44 45 4c 45 54 45 20           DELETE 
6450: 20 20 20 20 20 20 20 20 20 20 20 0a 2a 2a 0a 2a             .**.*
6460: 2a 20 20 20 20 49 4e 54 45 47 45 52 20 20 20 20  *    INTEGER    
6470: 4e 55 4c 4c 20 20 20 20 20 20 20 28 6e 43 6f 6c  NULL       (nCol
6480: 20 61 72 67 73 29 20 20 20 20 55 50 44 41 54 45   args)    UPDATE
6490: 20 28 64 6f 20 6e 6f 74 20 73 65 74 20 72 6f 77   (do not set row
64a0: 69 64 29 0a 2a 2a 20 20 20 20 49 4e 54 45 47 45  id).**    INTEGE
64b0: 52 20 20 20 20 49 4e 54 45 47 45 52 20 20 20 20  R    INTEGER    
64c0: 28 6e 43 6f 6c 20 61 72 67 73 29 20 20 20 20 55  (nCol args)    U
64d0: 50 44 41 54 45 20 28 77 69 74 68 20 53 45 54 20  PDATE (with SET 
64e0: 72 6f 77 69 64 20 3d 20 3c 61 72 67 31 3e 29 0a  rowid = <arg1>).
64f0: 2a 2a 0a 2a 2a 20 20 20 20 4e 55 4c 4c 20 20 20  **.**    NULL   
6500: 20 20 20 20 4e 55 4c 4c 20 20 20 20 20 20 20 28      NULL       (
6510: 6e 43 6f 6c 20 61 72 67 73 29 20 20 20 20 49 4e  nCol args)    IN
6520: 53 45 52 54 20 49 4e 54 4f 20 28 61 75 74 6f 6d  SERT INTO (autom
6530: 61 74 69 63 20 72 6f 77 69 64 20 76 61 6c 75 65  atic rowid value
6540: 29 0a 2a 2a 20 20 20 20 4e 55 4c 4c 20 20 20 20  ).**    NULL    
6550: 20 20 20 49 4e 54 45 47 45 52 20 20 20 20 28 6e     INTEGER    (n
6560: 43 6f 6c 20 61 72 67 73 29 20 20 20 20 49 4e 53  Col args)    INS
6570: 45 52 54 20 28 69 6e 63 6c 2e 20 72 6f 77 69 64  ERT (incl. rowid
6580: 20 76 61 6c 75 65 29 0a 2a 2a 0a 2a 2f 0a 69 6e   value).**.*/.in
6590: 74 20 65 63 68 6f 55 70 64 61 74 65 28 0a 20 20  t echoUpdate(.  
65a0: 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 74 61  sqlite3_vtab *ta
65b0: 62 2c 20 0a 20 20 69 6e 74 20 6e 44 61 74 61 2c  b, .  int nData,
65c0: 20 0a 20 20 73 71 6c 69 74 65 33 5f 76 61 6c 75   .  sqlite3_valu
65d0: 65 20 2a 2a 61 70 44 61 74 61 2c 20 0a 20 20 73  e **apData, .  s
65e0: 71 6c 69 74 65 5f 69 6e 74 36 34 20 2a 70 52 6f  qlite_int64 *pRo
65f0: 77 69 64 0a 29 7b 0a 20 20 65 63 68 6f 5f 76 74  wid.){.  echo_vt
6600: 61 62 20 2a 70 56 74 61 62 20 3d 20 28 65 63 68  ab *pVtab = (ech
6610: 6f 5f 76 74 61 62 20 2a 29 74 61 62 3b 0a 20 20  o_vtab *)tab;.  
6620: 73 71 6c 69 74 65 33 20 2a 64 62 20 3d 20 70 56  sqlite3 *db = pV
6630: 74 61 62 2d 3e 64 62 3b 0a 20 20 69 6e 74 20 72  tab->db;.  int r
6640: 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 0a  c = SQLITE_OK;..
6650: 20 20 73 71 6c 69 74 65 33 5f 73 74 6d 74 20 2a    sqlite3_stmt *
6660: 70 53 74 6d 74 3b 0a 20 20 63 68 61 72 20 2a 7a  pStmt;.  char *z
6670: 20 3d 20 30 3b 20 20 20 20 20 20 20 20 20 20 20   = 0;           
6680: 20 20 20 20 2f 2a 20 53 51 4c 20 73 74 61 74 65      /* SQL state
6690: 6d 65 6e 74 20 74 6f 20 65 78 65 63 75 74 65 20  ment to execute 
66a0: 2a 2f 0a 20 20 69 6e 74 20 62 69 6e 64 41 72 67  */.  int bindArg
66b0: 5a 65 72 6f 20 3d 20 30 3b 20 20 20 20 20 20 20  Zero = 0;       
66c0: 2f 2a 20 54 72 75 65 20 74 6f 20 62 69 6e 64 20  /* True to bind 
66d0: 61 70 44 61 74 61 5b 30 5d 20 74 6f 20 73 71 6c  apData[0] to sql
66e0: 20 76 61 72 20 6e 6f 2e 20 6e 44 61 74 61 20 2a   var no. nData *
66f0: 2f 0a 20 20 69 6e 74 20 62 69 6e 64 41 72 67 4f  /.  int bindArgO
6700: 6e 65 20 3d 20 30 3b 20 20 20 20 20 20 20 20 2f  ne = 0;        /
6710: 2a 20 54 72 75 65 20 74 6f 20 62 69 6e 64 20 61  * True to bind a
6720: 70 44 61 74 61 5b 31 5d 20 74 6f 20 73 71 6c 20  pData[1] to sql 
6730: 76 61 72 20 6e 6f 2e 20 31 20 2a 2f 0a 20 20 69  var no. 1 */.  i
6740: 6e 74 20 69 3b 20 20 20 20 20 20 20 20 20 20 20  nt i;           
6750: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43 6f 75            /* Cou
6760: 6e 74 65 72 20 76 61 72 69 61 62 6c 65 20 75 73  nter variable us
6770: 65 64 20 62 79 20 66 6f 72 20 6c 6f 6f 70 73 20  ed by for loops 
6780: 2a 2f 0a 0a 20 20 61 73 73 65 72 74 28 20 6e 44  */..  assert( nD
6790: 61 74 61 3d 3d 70 56 74 61 62 2d 3e 6e 43 6f 6c  ata==pVtab->nCol
67a0: 2b 32 20 7c 7c 20 6e 44 61 74 61 3d 3d 31 20 29  +2 || nData==1 )
67b0: 3b 0a 0a 20 20 2f 2a 20 54 69 63 6b 65 74 20 23  ;..  /* Ticket #
67c0: 33 30 38 33 20 2d 20 6d 61 6b 65 20 73 75 72 65  3083 - make sure
67d0: 20 77 65 20 61 6c 77 61 79 73 20 73 74 61 72 74   we always start
67e0: 20 61 20 74 72 61 6e 73 61 63 74 69 6f 6e 20 70   a transaction p
67f0: 72 69 6f 72 20 74 6f 0a 20 20 2a 2a 20 6d 61 6b  rior to.  ** mak
6800: 69 6e 67 20 61 6e 79 20 63 68 61 6e 67 65 73 20  ing any changes 
6810: 74 6f 20 61 20 76 69 72 74 75 61 6c 20 74 61 62  to a virtual tab
6820: 6c 65 20 2a 2f 0a 20 20 61 73 73 65 72 74 28 20  le */.  assert( 
6830: 70 56 74 61 62 2d 3e 69 6e 54 72 61 6e 73 61 63  pVtab->inTransac
6840: 74 69 6f 6e 20 29 3b 0a 0a 20 20 69 66 28 20 73  tion );..  if( s
6850: 69 6d 75 6c 61 74 65 56 74 61 62 45 72 72 6f 72  imulateVtabError
6860: 28 70 56 74 61 62 2c 20 22 78 55 70 64 61 74 65  (pVtab, "xUpdate
6870: 22 29 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e  ") ){.    return
6880: 20 53 51 4c 49 54 45 5f 45 52 52 4f 52 3b 0a 20   SQLITE_ERROR;. 
6890: 20 7d 0a 0a 20 20 2f 2a 20 49 66 20 61 70 44 61   }..  /* If apDa
68a0: 74 61 5b 30 5d 20 69 73 20 61 6e 20 69 6e 74 65  ta[0] is an inte
68b0: 67 65 72 20 61 6e 64 20 6e 44 61 74 61 3e 31 20  ger and nData>1 
68c0: 74 68 65 6e 20 64 6f 20 61 6e 20 55 50 44 41 54  then do an UPDAT
68d0: 45 20 2a 2f 0a 20 20 69 66 28 20 6e 44 61 74 61  E */.  if( nData
68e0: 3e 31 20 26 26 20 73 71 6c 69 74 65 33 5f 76 61  >1 && sqlite3_va
68f0: 6c 75 65 5f 74 79 70 65 28 61 70 44 61 74 61 5b  lue_type(apData[
6900: 30 5d 29 3d 3d 53 51 4c 49 54 45 5f 49 4e 54 45  0])==SQLITE_INTE
6910: 47 45 52 20 29 7b 0a 20 20 20 20 63 68 61 72 20  GER ){.    char 
6920: 2a 7a 53 65 70 20 3d 20 22 20 53 45 54 22 3b 0a  *zSep = " SET";.
6930: 20 20 20 20 7a 20 3d 20 73 71 6c 69 74 65 33 5f      z = sqlite3_
6940: 6d 70 72 69 6e 74 66 28 22 55 50 44 41 54 45 20  mprintf("UPDATE 
6950: 25 51 22 2c 20 70 56 74 61 62 2d 3e 7a 54 61 62  %Q", pVtab->zTab
6960: 6c 65 4e 61 6d 65 29 3b 0a 20 20 20 20 69 66 28  leName);.    if(
6970: 20 21 7a 20 29 7b 0a 20 20 20 20 20 20 72 63 20   !z ){.      rc 
6980: 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a  = SQLITE_NOMEM;.
6990: 20 20 20 20 7d 0a 0a 20 20 20 20 62 69 6e 64 41      }..    bindA
69a0: 72 67 4f 6e 65 20 3d 20 28 61 70 44 61 74 61 5b  rgOne = (apData[
69b0: 31 5d 20 26 26 20 73 71 6c 69 74 65 33 5f 76 61  1] && sqlite3_va
69c0: 6c 75 65 5f 74 79 70 65 28 61 70 44 61 74 61 5b  lue_type(apData[
69d0: 31 5d 29 3d 3d 53 51 4c 49 54 45 5f 49 4e 54 45  1])==SQLITE_INTE
69e0: 47 45 52 29 3b 0a 20 20 20 20 62 69 6e 64 41 72  GER);.    bindAr
69f0: 67 5a 65 72 6f 20 3d 20 31 3b 0a 0a 20 20 20 20  gZero = 1;..    
6a00: 69 66 28 20 62 69 6e 64 41 72 67 4f 6e 65 20 29  if( bindArgOne )
6a10: 7b 0a 20 20 20 20 20 20 20 73 74 72 69 6e 67 5f  {.       string_
6a20: 63 6f 6e 63 61 74 28 26 7a 2c 20 22 20 53 45 54  concat(&z, " SET
6a30: 20 72 6f 77 69 64 3d 3f 31 20 22 2c 20 30 2c 20   rowid=?1 ", 0, 
6a40: 26 72 63 29 3b 0a 20 20 20 20 20 20 20 7a 53 65  &rc);.       zSe
6a50: 70 20 3d 20 22 2c 22 3b 0a 20 20 20 20 7d 0a 20  p = ",";.    }. 
6a60: 20 20 20 66 6f 72 28 69 3d 32 3b 20 69 3c 6e 44     for(i=2; i<nD
6a70: 61 74 61 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20  ata; i++){.     
6a80: 20 69 66 28 20 61 70 44 61 74 61 5b 69 5d 3d 3d   if( apData[i]==
6a90: 30 20 29 20 63 6f 6e 74 69 6e 75 65 3b 0a 20 20  0 ) continue;.  
6aa0: 20 20 20 20 73 74 72 69 6e 67 5f 63 6f 6e 63 61      string_conca
6ab0: 74 28 26 7a 2c 20 73 71 6c 69 74 65 33 5f 6d 70  t(&z, sqlite3_mp
6ac0: 72 69 6e 74 66 28 0a 20 20 20 20 20 20 20 20 20  rintf(.         
6ad0: 20 22 25 73 20 25 51 3d 3f 25 64 22 2c 20 7a 53   "%s %Q=?%d", zS
6ae0: 65 70 2c 20 70 56 74 61 62 2d 3e 61 43 6f 6c 5b  ep, pVtab->aCol[
6af0: 69 2d 32 5d 2c 20 69 29 2c 20 31 2c 20 26 72 63  i-2], i), 1, &rc
6b00: 29 3b 0a 20 20 20 20 20 20 7a 53 65 70 20 3d 20  );.      zSep = 
6b10: 22 2c 22 3b 0a 20 20 20 20 7d 0a 20 20 20 20 73  ",";.    }.    s
6b20: 74 72 69 6e 67 5f 63 6f 6e 63 61 74 28 26 7a 2c  tring_concat(&z,
6b30: 20 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66   sqlite3_mprintf
6b40: 28 22 20 57 48 45 52 45 20 72 6f 77 69 64 3d 3f  (" WHERE rowid=?
6b50: 25 64 22 2c 20 6e 44 61 74 61 29 2c 20 31 2c 20  %d", nData), 1, 
6b60: 26 72 63 29 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20  &rc);.  }..  /* 
6b70: 49 66 20 61 70 44 61 74 61 5b 30 5d 20 69 73 20  If apData[0] is 
6b80: 61 6e 20 69 6e 74 65 67 65 72 20 61 6e 64 20 6e  an integer and n
6b90: 44 61 74 61 3d 3d 31 20 74 68 65 6e 20 64 6f 20  Data==1 then do 
6ba0: 61 20 44 45 4c 45 54 45 20 2a 2f 0a 20 20 65 6c  a DELETE */.  el
6bb0: 73 65 20 69 66 28 20 6e 44 61 74 61 3d 3d 31 20  se if( nData==1 
6bc0: 26 26 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65  && sqlite3_value
6bd0: 5f 74 79 70 65 28 61 70 44 61 74 61 5b 30 5d 29  _type(apData[0])
6be0: 3d 3d 53 51 4c 49 54 45 5f 49 4e 54 45 47 45 52  ==SQLITE_INTEGER
6bf0: 20 29 7b 0a 20 20 20 20 7a 20 3d 20 73 71 6c 69   ){.    z = sqli
6c00: 74 65 33 5f 6d 70 72 69 6e 74 66 28 22 44 45 4c  te3_mprintf("DEL
6c10: 45 54 45 20 46 52 4f 4d 20 25 51 20 57 48 45 52  ETE FROM %Q WHER
6c20: 45 20 72 6f 77 69 64 20 3d 20 3f 31 22 2c 20 70  E rowid = ?1", p
6c30: 56 74 61 62 2d 3e 7a 54 61 62 6c 65 4e 61 6d 65  Vtab->zTableName
6c40: 29 3b 0a 20 20 20 20 69 66 28 20 21 7a 20 29 7b  );.    if( !z ){
6c50: 0a 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c 49  .      rc = SQLI
6c60: 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 7d 0a  TE_NOMEM;.    }.
6c70: 20 20 20 20 62 69 6e 64 41 72 67 5a 65 72 6f 20      bindArgZero 
6c80: 3d 20 31 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 49  = 1;.  }..  /* I
6c90: 66 20 74 68 65 20 66 69 72 73 74 20 61 72 67 75  f the first argu
6ca0: 6d 65 6e 74 20 69 73 20 4e 55 4c 4c 20 61 6e 64  ment is NULL and
6cb0: 20 74 68 65 72 65 20 61 72 65 20 6d 6f 72 65 20   there are more 
6cc0: 74 68 61 6e 20 74 77 6f 20 61 72 67 73 2c 20 49  than two args, I
6cd0: 4e 53 45 52 54 20 2a 2f 0a 20 20 65 6c 73 65 20  NSERT */.  else 
6ce0: 69 66 28 20 6e 44 61 74 61 3e 32 20 26 26 20 73  if( nData>2 && s
6cf0: 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 74 79 70  qlite3_value_typ
6d00: 65 28 61 70 44 61 74 61 5b 30 5d 29 3d 3d 53 51  e(apData[0])==SQ
6d10: 4c 49 54 45 5f 4e 55 4c 4c 20 29 7b 0a 20 20 20  LITE_NULL ){.   
6d20: 20 69 6e 74 20 69 69 3b 0a 20 20 20 20 63 68 61   int ii;.    cha
6d30: 72 20 2a 7a 49 6e 73 65 72 74 20 3d 20 30 3b 0a  r *zInsert = 0;.
6d40: 20 20 20 20 63 68 61 72 20 2a 7a 56 61 6c 75 65      char *zValue
6d50: 73 20 3d 20 30 3b 0a 20 20 0a 20 20 20 20 7a 49  s = 0;.  .    zI
6d60: 6e 73 65 72 74 20 3d 20 73 71 6c 69 74 65 33 5f  nsert = sqlite3_
6d70: 6d 70 72 69 6e 74 66 28 22 49 4e 53 45 52 54 20  mprintf("INSERT 
6d80: 49 4e 54 4f 20 25 51 20 28 22 2c 20 70 56 74 61  INTO %Q (", pVta
6d90: 62 2d 3e 7a 54 61 62 6c 65 4e 61 6d 65 29 3b 0a  b->zTableName);.
6da0: 20 20 20 20 69 66 28 20 21 7a 49 6e 73 65 72 74      if( !zInsert
6db0: 20 29 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 53   ){.      rc = S
6dc0: 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20  QLITE_NOMEM;.   
6dd0: 20 7d 0a 20 20 20 20 69 66 28 20 73 71 6c 69 74   }.    if( sqlit
6de0: 65 33 5f 76 61 6c 75 65 5f 74 79 70 65 28 61 70  e3_value_type(ap
6df0: 44 61 74 61 5b 31 5d 29 3d 3d 53 51 4c 49 54 45  Data[1])==SQLITE
6e00: 5f 49 4e 54 45 47 45 52 20 29 7b 0a 20 20 20 20  _INTEGER ){.    
6e10: 20 20 62 69 6e 64 41 72 67 4f 6e 65 20 3d 20 31    bindArgOne = 1
6e20: 3b 0a 20 20 20 20 20 20 7a 56 61 6c 75 65 73 20  ;.      zValues 
6e30: 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74  = sqlite3_mprint
6e40: 66 28 22 3f 22 29 3b 0a 20 20 20 20 20 20 73 74  f("?");.      st
6e50: 72 69 6e 67 5f 63 6f 6e 63 61 74 28 26 7a 49 6e  ring_concat(&zIn
6e60: 73 65 72 74 2c 20 22 72 6f 77 69 64 22 2c 20 30  sert, "rowid", 0
6e70: 2c 20 26 72 63 29 3b 0a 20 20 20 20 7d 0a 0a 20  , &rc);.    }.. 
6e80: 20 20 20 61 73 73 65 72 74 28 28 70 56 74 61 62     assert((pVtab
6e90: 2d 3e 6e 43 6f 6c 2b 32 29 3d 3d 6e 44 61 74 61  ->nCol+2)==nData
6ea0: 29 3b 0a 20 20 20 20 66 6f 72 28 69 69 3d 32 3b  );.    for(ii=2;
6eb0: 20 69 69 3c 6e 44 61 74 61 3b 20 69 69 2b 2b 29   ii<nData; ii++)
6ec0: 7b 0a 20 20 20 20 20 20 73 74 72 69 6e 67 5f 63  {.      string_c
6ed0: 6f 6e 63 61 74 28 26 7a 49 6e 73 65 72 74 2c 20  oncat(&zInsert, 
6ee0: 0a 20 20 20 20 20 20 20 20 20 20 73 71 6c 69 74  .          sqlit
6ef0: 65 33 5f 6d 70 72 69 6e 74 66 28 22 25 73 25 51  e3_mprintf("%s%Q
6f00: 22 2c 20 7a 56 61 6c 75 65 73 3f 22 2c 20 22 3a  ", zValues?", ":
6f10: 22 22 2c 20 70 56 74 61 62 2d 3e 61 43 6f 6c 5b  "", pVtab->aCol[
6f20: 69 69 2d 32 5d 29 2c 20 31 2c 20 26 72 63 29 3b  ii-2]), 1, &rc);
6f30: 0a 20 20 20 20 20 20 73 74 72 69 6e 67 5f 63 6f  .      string_co
6f40: 6e 63 61 74 28 26 7a 56 61 6c 75 65 73 2c 20 0a  ncat(&zValues, .
6f50: 20 20 20 20 20 20 20 20 20 20 73 71 6c 69 74 65            sqlite
6f60: 33 5f 6d 70 72 69 6e 74 66 28 22 25 73 3f 25 64  3_mprintf("%s?%d
6f70: 22 2c 20 7a 56 61 6c 75 65 73 3f 22 2c 20 22 3a  ", zValues?", ":
6f80: 22 22 2c 20 69 69 29 2c 20 31 2c 20 26 72 63 29  "", ii), 1, &rc)
6f90: 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 73 74 72  ;.    }..    str
6fa0: 69 6e 67 5f 63 6f 6e 63 61 74 28 26 7a 2c 20 7a  ing_concat(&z, z
6fb0: 49 6e 73 65 72 74 2c 20 31 2c 20 26 72 63 29 3b  Insert, 1, &rc);
6fc0: 0a 20 20 20 20 73 74 72 69 6e 67 5f 63 6f 6e 63  .    string_conc
6fd0: 61 74 28 26 7a 2c 20 22 29 20 56 41 4c 55 45 53  at(&z, ") VALUES
6fe0: 28 22 2c 20 30 2c 20 26 72 63 29 3b 0a 20 20 20  (", 0, &rc);.   
6ff0: 20 73 74 72 69 6e 67 5f 63 6f 6e 63 61 74 28 26   string_concat(&
7000: 7a 2c 20 7a 56 61 6c 75 65 73 2c 20 31 2c 20 26  z, zValues, 1, &
7010: 72 63 29 3b 0a 20 20 20 20 73 74 72 69 6e 67 5f  rc);.    string_
7020: 63 6f 6e 63 61 74 28 26 7a 2c 20 22 29 22 2c 20  concat(&z, ")", 
7030: 30 2c 20 26 72 63 29 3b 0a 20 20 7d 0a 0a 20 20  0, &rc);.  }..  
7040: 2f 2a 20 41 6e 79 74 68 69 6e 67 20 65 6c 73 65  /* Anything else
7050: 20 69 73 20 61 6e 20 65 72 72 6f 72 20 2a 2f 0a   is an error */.
7060: 20 20 65 6c 73 65 7b 0a 20 20 20 20 61 73 73 65    else{.    asse
7070: 72 74 28 30 29 3b 0a 20 20 20 20 72 65 74 75 72  rt(0);.    retur
7080: 6e 20 53 51 4c 49 54 45 5f 45 52 52 4f 52 3b 0a  n SQLITE_ERROR;.
7090: 20 20 7d 0a 0a 20 20 69 66 28 20 72 63 3d 3d 53    }..  if( rc==S
70a0: 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
70b0: 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 70 72 65  rc = sqlite3_pre
70c0: 70 61 72 65 28 64 62 2c 20 7a 2c 20 2d 31 2c 20  pare(db, z, -1, 
70d0: 26 70 53 74 6d 74 2c 20 30 29 3b 0a 20 20 7d 0a  &pStmt, 0);.  }.
70e0: 20 20 61 73 73 65 72 74 28 20 72 63 21 3d 53 51    assert( rc!=SQ
70f0: 4c 49 54 45 5f 4f 4b 20 7c 7c 20 70 53 74 6d 74  LITE_OK || pStmt
7100: 20 29 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66 72   );.  sqlite3_fr
7110: 65 65 28 7a 29 3b 0a 20 20 69 66 28 20 72 63 3d  ee(z);.  if( rc=
7120: 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 7b 0a 20  =SQLITE_OK ) {. 
7130: 20 20 20 69 66 28 20 62 69 6e 64 41 72 67 5a 65     if( bindArgZe
7140: 72 6f 20 29 7b 0a 20 20 20 20 20 20 73 71 6c 69  ro ){.      sqli
7150: 74 65 33 5f 62 69 6e 64 5f 76 61 6c 75 65 28 70  te3_bind_value(p
7160: 53 74 6d 74 2c 20 6e 44 61 74 61 2c 20 61 70 44  Stmt, nData, apD
7170: 61 74 61 5b 30 5d 29 3b 0a 20 20 20 20 7d 0a 20  ata[0]);.    }. 
7180: 20 20 20 69 66 28 20 62 69 6e 64 41 72 67 4f 6e     if( bindArgOn
7190: 65 20 29 7b 0a 20 20 20 20 20 20 73 71 6c 69 74  e ){.      sqlit
71a0: 65 33 5f 62 69 6e 64 5f 76 61 6c 75 65 28 70 53  e3_bind_value(pS
71b0: 74 6d 74 2c 20 31 2c 20 61 70 44 61 74 61 5b 31  tmt, 1, apData[1
71c0: 5d 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 66 6f  ]);.    }.    fo
71d0: 72 28 69 3d 32 3b 20 69 3c 6e 44 61 74 61 20 26  r(i=2; i<nData &
71e0: 26 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 3b  & rc==SQLITE_OK;
71f0: 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20 69 66 28   i++){.      if(
7200: 20 61 70 44 61 74 61 5b 69 5d 20 29 20 72 63 20   apData[i] ) rc 
7210: 3d 20 73 71 6c 69 74 65 33 5f 62 69 6e 64 5f 76  = sqlite3_bind_v
7220: 61 6c 75 65 28 70 53 74 6d 74 2c 20 69 2c 20 61  alue(pStmt, i, a
7230: 70 44 61 74 61 5b 69 5d 29 3b 0a 20 20 20 20 7d  pData[i]);.    }
7240: 0a 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c  .    if( rc==SQL
7250: 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20  ITE_OK ){.      
7260: 73 71 6c 69 74 65 33 5f 73 74 65 70 28 70 53 74  sqlite3_step(pSt
7270: 6d 74 29 3b 0a 20 20 20 20 20 20 72 63 20 3d 20  mt);.      rc = 
7280: 73 71 6c 69 74 65 33 5f 66 69 6e 61 6c 69 7a 65  sqlite3_finalize
7290: 28 70 53 74 6d 74 29 3b 0a 20 20 20 20 7d 65 6c  (pStmt);.    }el
72a0: 73 65 7b 0a 20 20 20 20 20 20 73 71 6c 69 74 65  se{.      sqlite
72b0: 33 5f 66 69 6e 61 6c 69 7a 65 28 70 53 74 6d 74  3_finalize(pStmt
72c0: 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20  );.    }.  }..  
72d0: 69 66 28 20 70 52 6f 77 69 64 20 26 26 20 72 63  if( pRowid && rc
72e0: 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  ==SQLITE_OK ){. 
72f0: 20 20 20 2a 70 52 6f 77 69 64 20 3d 20 73 71 6c     *pRowid = sql
7300: 69 74 65 33 5f 6c 61 73 74 5f 69 6e 73 65 72 74  ite3_last_insert
7310: 5f 72 6f 77 69 64 28 64 62 29 3b 0a 20 20 7d 0a  _rowid(db);.  }.
7320: 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45    if( rc!=SQLITE
7330: 5f 4f 4b 20 29 7b 0a 20 20 20 20 74 61 62 2d 3e  _OK ){.    tab->
7340: 7a 45 72 72 4d 73 67 20 3d 20 73 71 6c 69 74 65  zErrMsg = sqlite
7350: 33 5f 6d 70 72 69 6e 74 66 28 22 65 63 68 6f 2d  3_mprintf("echo-
7360: 76 74 61 62 2d 65 72 72 6f 72 3a 20 25 73 22 2c  vtab-error: %s",
7370: 20 73 71 6c 69 74 65 33 5f 65 72 72 6d 73 67 28   sqlite3_errmsg(
7380: 64 62 29 29 3b 0a 20 20 7d 0a 0a 20 20 72 65 74  db));.  }..  ret
7390: 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  urn rc;.}../*.**
73a0: 20 78 42 65 67 69 6e 2c 20 78 53 79 6e 63 2c 20   xBegin, xSync, 
73b0: 78 43 6f 6d 6d 69 74 20 61 6e 64 20 78 52 6f 6c  xCommit and xRol
73c0: 6c 62 61 63 6b 20 63 61 6c 6c 62 61 63 6b 73 20  lback callbacks 
73d0: 66 6f 72 20 65 63 68 6f 20 6d 6f 64 75 6c 65 0a  for echo module.
73e0: 2a 2a 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65  ** virtual table
73f0: 73 2e 20 44 6f 20 6e 6f 74 68 69 6e 67 20 6f 74  s. Do nothing ot
7400: 68 65 72 20 74 68 61 6e 20 61 64 64 20 74 68 65  her than add the
7410: 20 6e 61 6d 65 20 6f 66 20 74 68 65 20 63 61 6c   name of the cal
7420: 6c 62 61 63 6b 0a 2a 2a 20 74 6f 20 74 68 65 20  lback.** to the 
7430: 24 3a 3a 65 63 68 6f 5f 6d 6f 64 75 6c 65 20 54  $::echo_module T
7440: 63 6c 20 76 61 72 69 61 62 6c 65 2e 0a 2a 2f 0a  cl variable..*/.
7450: 73 74 61 74 69 63 20 69 6e 74 20 65 63 68 6f 54  static int echoT
7460: 72 61 6e 73 61 63 74 69 6f 6e 43 61 6c 6c 28 73  ransactionCall(s
7470: 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 74 61 62  qlite3_vtab *tab
7480: 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 43  , const char *zC
7490: 61 6c 6c 29 7b 0a 20 20 63 68 61 72 20 2a 7a 3b  all){.  char *z;
74a0: 0a 20 20 65 63 68 6f 5f 76 74 61 62 20 2a 70 56  .  echo_vtab *pV
74b0: 74 61 62 20 3d 20 28 65 63 68 6f 5f 76 74 61 62  tab = (echo_vtab
74c0: 20 2a 29 74 61 62 3b 0a 20 20 7a 20 3d 20 73 71   *)tab;.  z = sq
74d0: 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 22 65  lite3_mprintf("e
74e0: 63 68 6f 28 25 73 29 22 2c 20 70 56 74 61 62 2d  cho(%s)", pVtab-
74f0: 3e 7a 54 61 62 6c 65 4e 61 6d 65 29 3b 0a 20 20  >zTableName);.  
7500: 69 66 28 20 7a 3d 3d 30 20 29 20 72 65 74 75 72  if( z==0 ) retur
7510: 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a  n SQLITE_NOMEM;.
7520: 20 20 61 70 70 65 6e 64 54 6f 45 63 68 6f 4d 6f    appendToEchoMo
7530: 64 75 6c 65 28 70 56 74 61 62 2d 3e 69 6e 74 65  dule(pVtab->inte
7540: 72 70 2c 20 7a 43 61 6c 6c 29 3b 0a 20 20 61 70  rp, zCall);.  ap
7550: 70 65 6e 64 54 6f 45 63 68 6f 4d 6f 64 75 6c 65  pendToEchoModule
7560: 28 70 56 74 61 62 2d 3e 69 6e 74 65 72 70 2c 20  (pVtab->interp, 
7570: 7a 29 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66 72  z);.  sqlite3_fr
7580: 65 65 28 7a 29 3b 0a 20 20 72 65 74 75 72 6e 20  ee(z);.  return 
7590: 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 73 74 61  SQLITE_OK;.}.sta
75a0: 74 69 63 20 69 6e 74 20 65 63 68 6f 42 65 67 69  tic int echoBegi
75b0: 6e 28 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a  n(sqlite3_vtab *
75c0: 74 61 62 29 7b 0a 20 20 69 6e 74 20 72 63 3b 0a  tab){.  int rc;.
75d0: 20 20 65 63 68 6f 5f 76 74 61 62 20 2a 70 56 74    echo_vtab *pVt
75e0: 61 62 20 3d 20 28 65 63 68 6f 5f 76 74 61 62 20  ab = (echo_vtab 
75f0: 2a 29 74 61 62 3b 0a 20 20 54 63 6c 5f 49 6e 74  *)tab;.  Tcl_Int
7600: 65 72 70 20 2a 69 6e 74 65 72 70 20 3d 20 70 56  erp *interp = pV
7610: 74 61 62 2d 3e 69 6e 74 65 72 70 3b 0a 20 20 63  tab->interp;.  c
7620: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 56 61 6c 3b  onst char *zVal;
7630: 20 0a 0a 20 20 2f 2a 20 54 69 63 6b 65 74 20 23   ..  /* Ticket #
7640: 33 30 38 33 20 2d 20 64 6f 20 6e 6f 74 20 73 74  3083 - do not st
7650: 61 72 74 20 61 20 74 72 61 6e 73 61 63 74 69 6f  art a transactio
7660: 6e 20 69 66 20 77 65 20 61 72 65 20 61 6c 72 65  n if we are alre
7670: 61 64 79 20 69 6e 0a 20 20 2a 2a 20 61 20 74 72  ady in.  ** a tr
7680: 61 6e 73 61 63 74 69 6f 6e 20 2a 2f 0a 20 20 61  ansaction */.  a
7690: 73 73 65 72 74 28 20 21 70 56 74 61 62 2d 3e 69  ssert( !pVtab->i
76a0: 6e 54 72 61 6e 73 61 63 74 69 6f 6e 20 29 3b 0a  nTransaction );.
76b0: 0a 20 20 69 66 28 20 73 69 6d 75 6c 61 74 65 56  .  if( simulateV
76c0: 74 61 62 45 72 72 6f 72 28 70 56 74 61 62 2c 20  tabError(pVtab, 
76d0: 22 78 42 65 67 69 6e 22 29 20 29 7b 0a 20 20 20  "xBegin") ){.   
76e0: 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 45   return SQLITE_E
76f0: 52 52 4f 52 3b 0a 20 20 7d 0a 0a 20 20 72 63 20  RROR;.  }..  rc 
7700: 3d 20 65 63 68 6f 54 72 61 6e 73 61 63 74 69 6f  = echoTransactio
7710: 6e 43 61 6c 6c 28 74 61 62 2c 20 22 78 42 65 67  nCall(tab, "xBeg
7720: 69 6e 22 29 3b 0a 0a 20 20 69 66 28 20 72 63 3d  in");..  if( rc=
7730: 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20  =SQLITE_OK ){.  
7740: 20 20 2f 2a 20 43 68 65 63 6b 20 69 66 20 74 68    /* Check if th
7750: 65 20 24 3a 3a 65 63 68 6f 5f 6d 6f 64 75 6c 65  e $::echo_module
7760: 5f 62 65 67 69 6e 5f 66 61 69 6c 20 76 61 72 69  _begin_fail vari
7770: 61 62 6c 65 20 69 73 20 64 65 66 69 6e 65 64 2e  able is defined.
7780: 20 49 66 20 69 74 20 69 73 2c 0a 20 20 20 20 2a   If it is,.    *
7790: 2a 20 61 6e 64 20 69 74 20 69 73 20 73 65 74 20  * and it is set 
77a0: 74 6f 20 74 68 65 20 6e 61 6d 65 20 6f 66 20 74  to the name of t
77b0: 68 65 20 72 65 61 6c 20 74 61 62 6c 65 20 75 6e  he real table un
77c0: 64 65 72 6c 79 69 6e 67 20 74 68 69 73 20 76 69  derlying this vi
77d0: 72 74 75 61 6c 0a 20 20 20 20 2a 2a 20 65 63 68  rtual.    ** ech
77e0: 6f 20 6d 6f 64 75 6c 65 20 74 61 62 6c 65 2c 20  o module table, 
77f0: 74 68 65 6e 20 63 61 75 73 65 20 74 68 69 73 20  then cause this 
7800: 78 53 79 6e 63 20 6f 70 65 72 61 74 69 6f 6e 20  xSync operation 
7810: 74 6f 20 66 61 69 6c 2e 0a 20 20 20 20 2a 2f 0a  to fail..    */.
7820: 20 20 20 20 7a 56 61 6c 20 3d 20 54 63 6c 5f 47      zVal = Tcl_G
7830: 65 74 56 61 72 28 69 6e 74 65 72 70 2c 20 22 65  etVar(interp, "e
7840: 63 68 6f 5f 6d 6f 64 75 6c 65 5f 62 65 67 69 6e  cho_module_begin
7850: 5f 66 61 69 6c 22 2c 20 54 43 4c 5f 47 4c 4f 42  _fail", TCL_GLOB
7860: 41 4c 5f 4f 4e 4c 59 29 3b 0a 20 20 20 20 69 66  AL_ONLY);.    if
7870: 28 20 7a 56 61 6c 20 26 26 20 30 3d 3d 73 74 72  ( zVal && 0==str
7880: 63 6d 70 28 7a 56 61 6c 2c 20 70 56 74 61 62 2d  cmp(zVal, pVtab-
7890: 3e 7a 54 61 62 6c 65 4e 61 6d 65 29 20 29 7b 0a  >zTableName) ){.
78a0: 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54        rc = SQLIT
78b0: 45 5f 45 52 52 4f 52 3b 0a 20 20 20 20 7d 0a 20  E_ERROR;.    }. 
78c0: 20 7d 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c   }.  if( rc==SQL
78d0: 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 70 56  ITE_OK ){.    pV
78e0: 74 61 62 2d 3e 69 6e 54 72 61 6e 73 61 63 74 69  tab->inTransacti
78f0: 6f 6e 20 3d 20 31 3b 0a 20 20 7d 0a 20 20 72 65  on = 1;.  }.  re
7900: 74 75 72 6e 20 72 63 3b 0a 7d 0a 73 74 61 74 69  turn rc;.}.stati
7910: 63 20 69 6e 74 20 65 63 68 6f 53 79 6e 63 28 73  c int echoSync(s
7920: 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 74 61 62  qlite3_vtab *tab
7930: 29 7b 0a 20 20 69 6e 74 20 72 63 3b 0a 20 20 65  ){.  int rc;.  e
7940: 63 68 6f 5f 76 74 61 62 20 2a 70 56 74 61 62 20  cho_vtab *pVtab 
7950: 3d 20 28 65 63 68 6f 5f 76 74 61 62 20 2a 29 74  = (echo_vtab *)t
7960: 61 62 3b 0a 20 20 54 63 6c 5f 49 6e 74 65 72 70  ab;.  Tcl_Interp
7970: 20 2a 69 6e 74 65 72 70 20 3d 20 70 56 74 61 62   *interp = pVtab
7980: 2d 3e 69 6e 74 65 72 70 3b 0a 20 20 63 6f 6e 73  ->interp;.  cons
7990: 74 20 63 68 61 72 20 2a 7a 56 61 6c 3b 20 0a 0a  t char *zVal; ..
79a0: 20 20 2f 2a 20 54 69 63 6b 65 74 20 23 33 30 38    /* Ticket #308
79b0: 33 20 2d 20 4f 6e 6c 79 20 63 61 6c 6c 20 78 53  3 - Only call xS
79c0: 79 6e 63 20 69 66 20 77 65 20 68 61 76 65 20 70  ync if we have p
79d0: 72 65 76 69 6f 75 73 6c 79 20 73 74 61 72 74 65  reviously starte
79e0: 64 20 61 0a 20 20 2a 2a 20 74 72 61 6e 73 61 63  d a.  ** transac
79f0: 74 69 6f 6e 20 2a 2f 0a 20 20 61 73 73 65 72 74  tion */.  assert
7a00: 28 20 70 56 74 61 62 2d 3e 69 6e 54 72 61 6e 73  ( pVtab->inTrans
7a10: 61 63 74 69 6f 6e 20 29 3b 0a 0a 20 20 69 66 28  action );..  if(
7a20: 20 73 69 6d 75 6c 61 74 65 56 74 61 62 45 72 72   simulateVtabErr
7a30: 6f 72 28 70 56 74 61 62 2c 20 22 78 53 79 6e 63  or(pVtab, "xSync
7a40: 22 29 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e  ") ){.    return
7a50: 20 53 51 4c 49 54 45 5f 45 52 52 4f 52 3b 0a 20   SQLITE_ERROR;. 
7a60: 20 7d 0a 0a 20 20 72 63 20 3d 20 65 63 68 6f 54   }..  rc = echoT
7a70: 72 61 6e 73 61 63 74 69 6f 6e 43 61 6c 6c 28 74  ransactionCall(t
7a80: 61 62 2c 20 22 78 53 79 6e 63 22 29 3b 0a 0a 20  ab, "xSync");.. 
7a90: 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
7aa0: 4f 4b 20 29 7b 0a 20 20 20 20 2f 2a 20 43 68 65  OK ){.    /* Che
7ab0: 63 6b 20 69 66 20 74 68 65 20 24 3a 3a 65 63 68  ck if the $::ech
7ac0: 6f 5f 6d 6f 64 75 6c 65 5f 73 79 6e 63 5f 66 61  o_module_sync_fa
7ad0: 69 6c 20 76 61 72 69 61 62 6c 65 20 69 73 20 64  il variable is d
7ae0: 65 66 69 6e 65 64 2e 20 49 66 20 69 74 20 69 73  efined. If it is
7af0: 2c 0a 20 20 20 20 2a 2a 20 61 6e 64 20 69 74 20  ,.    ** and it 
7b00: 69 73 20 73 65 74 20 74 6f 20 74 68 65 20 6e 61  is set to the na
7b10: 6d 65 20 6f 66 20 74 68 65 20 72 65 61 6c 20 74  me of the real t
7b20: 61 62 6c 65 20 75 6e 64 65 72 6c 79 69 6e 67 20  able underlying 
7b30: 74 68 69 73 20 76 69 72 74 75 61 6c 0a 20 20 20  this virtual.   
7b40: 20 2a 2a 20 65 63 68 6f 20 6d 6f 64 75 6c 65 20   ** echo module 
7b50: 74 61 62 6c 65 2c 20 74 68 65 6e 20 63 61 75 73  table, then caus
7b60: 65 20 74 68 69 73 20 78 53 79 6e 63 20 6f 70 65  e this xSync ope
7b70: 72 61 74 69 6f 6e 20 74 6f 20 66 61 69 6c 2e 0a  ration to fail..
7b80: 20 20 20 20 2a 2f 0a 20 20 20 20 7a 56 61 6c 20      */.    zVal 
7b90: 3d 20 54 63 6c 5f 47 65 74 56 61 72 28 69 6e 74  = Tcl_GetVar(int
7ba0: 65 72 70 2c 20 22 65 63 68 6f 5f 6d 6f 64 75 6c  erp, "echo_modul
7bb0: 65 5f 73 79 6e 63 5f 66 61 69 6c 22 2c 20 54 43  e_sync_fail", TC
7bc0: 4c 5f 47 4c 4f 42 41 4c 5f 4f 4e 4c 59 29 3b 0a  L_GLOBAL_ONLY);.
7bd0: 20 20 20 20 69 66 28 20 7a 56 61 6c 20 26 26 20      if( zVal && 
7be0: 30 3d 3d 73 74 72 63 6d 70 28 7a 56 61 6c 2c 20  0==strcmp(zVal, 
7bf0: 70 56 74 61 62 2d 3e 7a 54 61 62 6c 65 4e 61 6d  pVtab->zTableNam
7c00: 65 29 20 29 7b 0a 20 20 20 20 20 20 72 63 20 3d  e) ){.      rc =
7c10: 20 2d 31 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20   -1;.    }.  }. 
7c20: 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 73 74   return rc;.}.st
7c30: 61 74 69 63 20 69 6e 74 20 65 63 68 6f 43 6f 6d  atic int echoCom
7c40: 6d 69 74 28 73 71 6c 69 74 65 33 5f 76 74 61 62  mit(sqlite3_vtab
7c50: 20 2a 74 61 62 29 7b 0a 20 20 65 63 68 6f 5f 76   *tab){.  echo_v
7c60: 74 61 62 20 2a 70 56 74 61 62 20 3d 20 28 65 63  tab *pVtab = (ec
7c70: 68 6f 5f 76 74 61 62 2a 29 74 61 62 3b 0a 20 20  ho_vtab*)tab;.  
7c80: 69 6e 74 20 72 63 3b 0a 0a 20 20 2f 2a 20 54 69  int rc;..  /* Ti
7c90: 63 6b 65 74 20 23 33 30 38 33 20 2d 20 4f 6e 6c  cket #3083 - Onl
7ca0: 79 20 63 61 6c 6c 20 78 43 6f 6d 6d 69 74 20 69  y call xCommit i
7cb0: 66 20 77 65 20 68 61 76 65 20 70 72 65 76 69 6f  f we have previo
7cc0: 75 73 6c 79 20 73 74 61 72 74 65 64 0a 20 20 2a  usly started.  *
7cd0: 2a 20 61 20 74 72 61 6e 73 61 63 74 69 6f 6e 20  * a transaction 
7ce0: 2a 2f 0a 20 20 61 73 73 65 72 74 28 20 70 56 74  */.  assert( pVt
7cf0: 61 62 2d 3e 69 6e 54 72 61 6e 73 61 63 74 69 6f  ab->inTransactio
7d00: 6e 20 29 3b 0a 0a 20 20 69 66 28 20 73 69 6d 75  n );..  if( simu
7d10: 6c 61 74 65 56 74 61 62 45 72 72 6f 72 28 70 56  lateVtabError(pV
7d20: 74 61 62 2c 20 22 78 43 6f 6d 6d 69 74 22 29 20  tab, "xCommit") 
7d30: 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 53 51  ){.    return SQ
7d40: 4c 49 54 45 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a  LITE_ERROR;.  }.
7d50: 0a 20 20 73 71 6c 69 74 65 33 42 65 67 69 6e 42  .  sqlite3BeginB
7d60: 65 6e 69 67 6e 4d 61 6c 6c 6f 63 28 29 3b 0a 20  enignMalloc();. 
7d70: 20 72 63 20 3d 20 65 63 68 6f 54 72 61 6e 73 61   rc = echoTransa
7d80: 63 74 69 6f 6e 43 61 6c 6c 28 74 61 62 2c 20 22  ctionCall(tab, "
7d90: 78 43 6f 6d 6d 69 74 22 29 3b 0a 20 20 73 71 6c  xCommit");.  sql
7da0: 69 74 65 33 45 6e 64 42 65 6e 69 67 6e 4d 61 6c  ite3EndBenignMal
7db0: 6c 6f 63 28 29 3b 0a 20 20 70 56 74 61 62 2d 3e  loc();.  pVtab->
7dc0: 69 6e 54 72 61 6e 73 61 63 74 69 6f 6e 20 3d 20  inTransaction = 
7dd0: 30 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a  0;.  return rc;.
7de0: 7d 0a 73 74 61 74 69 63 20 69 6e 74 20 65 63 68  }.static int ech
7df0: 6f 52 6f 6c 6c 62 61 63 6b 28 73 71 6c 69 74 65  oRollback(sqlite
7e00: 33 5f 76 74 61 62 20 2a 74 61 62 29 7b 0a 20 20  3_vtab *tab){.  
7e10: 69 6e 74 20 72 63 3b 0a 20 20 65 63 68 6f 5f 76  int rc;.  echo_v
7e20: 74 61 62 20 2a 70 56 74 61 62 20 3d 20 28 65 63  tab *pVtab = (ec
7e30: 68 6f 5f 76 74 61 62 2a 29 74 61 62 3b 0a 0a 20  ho_vtab*)tab;.. 
7e40: 20 2f 2a 20 54 69 63 6b 65 74 20 23 33 30 38 33   /* Ticket #3083
7e50: 20 2d 20 4f 6e 6c 79 20 63 61 6c 6c 20 78 52 6f   - Only call xRo
7e60: 6c 6c 62 61 63 6b 20 69 66 20 77 65 20 68 61 76  llback if we hav
7e70: 65 20 70 72 65 76 69 6f 75 73 6c 79 20 73 74 61  e previously sta
7e80: 72 74 65 64 0a 20 20 2a 2a 20 61 20 74 72 61 6e  rted.  ** a tran
7e90: 73 61 63 74 69 6f 6e 20 2a 2f 0a 20 20 61 73 73  saction */.  ass
7ea0: 65 72 74 28 20 70 56 74 61 62 2d 3e 69 6e 54 72  ert( pVtab->inTr
7eb0: 61 6e 73 61 63 74 69 6f 6e 20 29 3b 0a 0a 20 20  ansaction );..  
7ec0: 72 63 20 3d 20 65 63 68 6f 54 72 61 6e 73 61 63  rc = echoTransac
7ed0: 74 69 6f 6e 43 61 6c 6c 28 74 61 62 2c 20 22 78  tionCall(tab, "x
7ee0: 52 6f 6c 6c 62 61 63 6b 22 29 3b 0a 20 20 70 56  Rollback");.  pV
7ef0: 74 61 62 2d 3e 69 6e 54 72 61 6e 73 61 63 74 69  tab->inTransacti
7f00: 6f 6e 20 3d 20 30 3b 0a 20 20 72 65 74 75 72 6e  on = 0;.  return
7f10: 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6d   rc;.}../*.** Im
7f20: 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66 20  plementation of 
7f30: 22 47 4c 4f 42 22 20 66 75 6e 63 74 69 6f 6e 20  "GLOB" function 
7f40: 6f 6e 20 74 68 65 20 65 63 68 6f 20 6d 6f 64 75  on the echo modu
7f50: 6c 65 2e 20 20 50 61 73 73 0a 2a 2a 20 61 6c 6c  le.  Pass.** all
7f60: 20 61 72 67 75 6d 65 6e 74 73 20 74 6f 20 74 68   arguments to th
7f70: 65 20 3a 3a 65 63 68 6f 5f 67 6c 6f 62 5f 6f 76  e ::echo_glob_ov
7f80: 65 72 6c 6f 61 64 20 70 72 6f 63 65 64 75 72 65  erload procedure
7f90: 20 6f 66 20 54 43 4c 0a 2a 2a 20 61 6e 64 20 72   of TCL.** and r
7fa0: 65 74 75 72 6e 20 74 68 65 20 72 65 73 75 6c 74  eturn the result
7fb0: 20 6f 66 20 74 68 61 74 20 70 72 6f 63 65 64 75   of that procedu
7fc0: 72 65 20 61 73 20 61 20 73 74 72 69 6e 67 2e 0a  re as a string..
7fd0: 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 6f  */.static void o
7fe0: 76 65 72 6c 6f 61 64 65 64 47 6c 6f 62 46 75 6e  verloadedGlobFun
7ff0: 63 74 69 6f 6e 28 0a 20 20 73 71 6c 69 74 65 33  ction(.  sqlite3
8000: 5f 63 6f 6e 74 65 78 74 20 2a 70 43 6f 6e 74 65  _context *pConte
8010: 78 74 2c 0a 20 20 69 6e 74 20 6e 41 72 67 2c 0a  xt,.  int nArg,.
8020: 20 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 20    sqlite3_value 
8030: 2a 2a 61 70 41 72 67 0a 29 7b 0a 20 20 54 63 6c  **apArg.){.  Tcl
8040: 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 20  _Interp *interp 
8050: 3d 20 73 71 6c 69 74 65 33 5f 75 73 65 72 5f 64  = sqlite3_user_d
8060: 61 74 61 28 70 43 6f 6e 74 65 78 74 29 3b 0a 20  ata(pContext);. 
8070: 20 54 63 6c 5f 44 53 74 72 69 6e 67 20 73 74 72   Tcl_DString str
8080: 3b 0a 20 20 69 6e 74 20 69 3b 0a 20 20 69 6e 74  ;.  int i;.  int
8090: 20 72 63 3b 0a 20 20 54 63 6c 5f 44 53 74 72 69   rc;.  Tcl_DStri
80a0: 6e 67 49 6e 69 74 28 26 73 74 72 29 3b 0a 20 20  ngInit(&str);.  
80b0: 54 63 6c 5f 44 53 74 72 69 6e 67 41 70 70 65 6e  Tcl_DStringAppen
80c0: 64 45 6c 65 6d 65 6e 74 28 26 73 74 72 2c 20 22  dElement(&str, "
80d0: 3a 3a 65 63 68 6f 5f 67 6c 6f 62 5f 6f 76 65 72  ::echo_glob_over
80e0: 6c 6f 61 64 22 29 3b 0a 20 20 66 6f 72 28 69 3d  load");.  for(i=
80f0: 30 3b 20 69 3c 6e 41 72 67 3b 20 69 2b 2b 29 7b  0; i<nArg; i++){
8100: 0a 20 20 20 20 54 63 6c 5f 44 53 74 72 69 6e 67  .    Tcl_DString
8110: 41 70 70 65 6e 64 45 6c 65 6d 65 6e 74 28 26 73  AppendElement(&s
8120: 74 72 2c 20 28 63 68 61 72 2a 29 73 71 6c 69 74  tr, (char*)sqlit
8130: 65 33 5f 76 61 6c 75 65 5f 74 65 78 74 28 61 70  e3_value_text(ap
8140: 41 72 67 5b 69 5d 29 29 3b 0a 20 20 7d 0a 20 20  Arg[i]));.  }.  
8150: 72 63 20 3d 20 54 63 6c 5f 45 76 61 6c 28 69 6e  rc = Tcl_Eval(in
8160: 74 65 72 70 2c 20 54 63 6c 5f 44 53 74 72 69 6e  terp, Tcl_DStrin
8170: 67 56 61 6c 75 65 28 26 73 74 72 29 29 3b 0a 20  gValue(&str));. 
8180: 20 54 63 6c 5f 44 53 74 72 69 6e 67 46 72 65 65   Tcl_DStringFree
8190: 28 26 73 74 72 29 3b 0a 20 20 69 66 28 20 72 63  (&str);.  if( rc
81a0: 20 29 7b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f   ){.    sqlite3_
81b0: 72 65 73 75 6c 74 5f 65 72 72 6f 72 28 70 43 6f  result_error(pCo
81c0: 6e 74 65 78 74 2c 20 54 63 6c 5f 47 65 74 53 74  ntext, Tcl_GetSt
81d0: 72 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72  ringResult(inter
81e0: 70 29 2c 20 2d 31 29 3b 0a 20 20 7d 65 6c 73 65  p), -1);.  }else
81f0: 7b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 72 65  {.    sqlite3_re
8200: 73 75 6c 74 5f 74 65 78 74 28 70 43 6f 6e 74 65  sult_text(pConte
8210: 78 74 2c 20 54 63 6c 5f 47 65 74 53 74 72 69 6e  xt, Tcl_GetStrin
8220: 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29 2c  gResult(interp),
8230: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
8240: 20 20 20 20 20 20 20 20 20 2d 31 2c 20 53 51 4c           -1, SQL
8250: 49 54 45 5f 54 52 41 4e 53 49 45 4e 54 29 3b 0a  ITE_TRANSIENT);.
8260: 20 20 7d 0a 20 20 54 63 6c 5f 52 65 73 65 74 52    }.  Tcl_ResetR
8270: 65 73 75 6c 74 28 69 6e 74 65 72 70 29 3b 0a 7d  esult(interp);.}
8280: 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 69 73 20  ../*.** This is 
8290: 74 68 65 20 78 46 69 6e 64 46 75 6e 63 74 69 6f  the xFindFunctio
82a0: 6e 20 69 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e  n implementation
82b0: 20 66 6f 72 20 74 68 65 20 65 63 68 6f 20 6d 6f   for the echo mo
82c0: 64 75 6c 65 2e 0a 2a 2a 20 53 51 4c 69 74 65 20  dule..** SQLite 
82d0: 63 61 6c 6c 73 20 74 68 69 73 20 72 6f 75 74 69  calls this routi
82e0: 6e 65 20 77 68 65 6e 20 74 68 65 20 66 69 72 73  ne when the firs
82f0: 74 20 61 72 67 75 6d 65 6e 74 20 6f 66 20 61 20  t argument of a 
8300: 66 75 6e 63 74 69 6f 6e 0a 2a 2a 20 69 73 20 61  function.** is a
8310: 20 63 6f 6c 75 6d 6e 20 6f 66 20 61 6e 20 65 63   column of an ec
8320: 68 6f 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65  ho virtual table
8330: 2e 20 20 54 68 69 73 20 72 6f 75 74 69 6e 65 20  .  This routine 
8340: 63 61 6e 20 6f 70 74 69 6f 6e 61 6c 6c 79 0a 2a  can optionally.*
8350: 2a 20 6f 76 65 72 72 69 64 65 20 74 68 65 20 69  * override the i
8360: 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66  mplementation of
8370: 20 74 68 61 74 20 66 75 6e 63 74 69 6f 6e 2e 20   that function. 
8380: 20 49 74 20 77 69 6c 6c 20 63 68 6f 6f 73 65 20   It will choose 
8390: 74 6f 0a 2a 2a 20 64 6f 20 73 6f 20 69 66 20 74  to.** do so if t
83a0: 68 65 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 6e  he function is n
83b0: 61 6d 65 64 20 22 67 6c 6f 62 22 2c 20 61 6e 64  amed "glob", and
83c0: 20 61 20 54 43 4c 20 63 6f 6d 6d 61 6e 64 20 6e   a TCL command n
83d0: 61 6d 65 64 0a 2a 2a 20 3a 3a 65 63 68 6f 5f 67  amed.** ::echo_g
83e0: 6c 6f 62 5f 6f 76 65 72 6c 6f 61 64 20 65 78 69  lob_overload exi
83f0: 73 74 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  sts..*/.static i
8400: 6e 74 20 65 63 68 6f 46 69 6e 64 46 75 6e 63 74  nt echoFindFunct
8410: 69 6f 6e 28 0a 20 20 73 71 6c 69 74 65 33 5f 76  ion(.  sqlite3_v
8420: 74 61 62 20 2a 76 74 61 62 2c 0a 20 20 69 6e 74  tab *vtab,.  int
8430: 20 6e 41 72 67 2c 0a 20 20 63 6f 6e 73 74 20 63   nArg,.  const c
8440: 68 61 72 20 2a 7a 46 75 6e 63 4e 61 6d 65 2c 0a  har *zFuncName,.
8450: 20 20 76 6f 69 64 20 28 2a 2a 70 78 46 75 6e 63    void (**pxFunc
8460: 29 28 73 71 6c 69 74 65 33 5f 63 6f 6e 74 65 78  )(sqlite3_contex
8470: 74 2a 2c 69 6e 74 2c 73 71 6c 69 74 65 33 5f 76  t*,int,sqlite3_v
8480: 61 6c 75 65 2a 2a 29 2c 0a 20 20 76 6f 69 64 20  alue**),.  void 
8490: 2a 2a 70 70 41 72 67 0a 29 7b 0a 20 20 65 63 68  **ppArg.){.  ech
84a0: 6f 5f 76 74 61 62 20 2a 70 56 74 61 62 20 3d 20  o_vtab *pVtab = 
84b0: 28 65 63 68 6f 5f 76 74 61 62 20 2a 29 76 74 61  (echo_vtab *)vta
84c0: 62 3b 0a 20 20 54 63 6c 5f 49 6e 74 65 72 70 20  b;.  Tcl_Interp 
84d0: 2a 69 6e 74 65 72 70 20 3d 20 70 56 74 61 62 2d  *interp = pVtab-
84e0: 3e 69 6e 74 65 72 70 3b 0a 20 20 54 63 6c 5f 43  >interp;.  Tcl_C
84f0: 6d 64 49 6e 66 6f 20 69 6e 66 6f 3b 0a 20 20 69  mdInfo info;.  i
8500: 66 28 20 73 74 72 63 6d 70 28 7a 46 75 6e 63 4e  f( strcmp(zFuncN
8510: 61 6d 65 2c 22 67 6c 6f 62 22 29 21 3d 30 20 29  ame,"glob")!=0 )
8520: 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 30 3b 0a  {.    return 0;.
8530: 20 20 7d 0a 20 20 69 66 28 20 54 63 6c 5f 47 65    }.  if( Tcl_Ge
8540: 74 43 6f 6d 6d 61 6e 64 49 6e 66 6f 28 69 6e 74  tCommandInfo(int
8550: 65 72 70 2c 20 22 3a 3a 65 63 68 6f 5f 67 6c 6f  erp, "::echo_glo
8560: 62 5f 6f 76 65 72 6c 6f 61 64 22 2c 20 26 69 6e  b_overload", &in
8570: 66 6f 29 3d 3d 30 20 29 7b 0a 20 20 20 20 72 65  fo)==0 ){.    re
8580: 74 75 72 6e 20 30 3b 0a 20 20 7d 0a 20 20 2a 70  turn 0;.  }.  *p
8590: 78 46 75 6e 63 20 3d 20 6f 76 65 72 6c 6f 61 64  xFunc = overload
85a0: 65 64 47 6c 6f 62 46 75 6e 63 74 69 6f 6e 3b 0a  edGlobFunction;.
85b0: 20 20 2a 70 70 41 72 67 20 3d 20 69 6e 74 65 72    *ppArg = inter
85c0: 70 3b 0a 20 20 72 65 74 75 72 6e 20 31 3b 0a 7d  p;.  return 1;.}
85d0: 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 65 63 68  ..static int ech
85e0: 6f 52 65 6e 61 6d 65 28 73 71 6c 69 74 65 33 5f  oRename(sqlite3_
85f0: 76 74 61 62 20 2a 76 74 61 62 2c 20 63 6f 6e 73  vtab *vtab, cons
8600: 74 20 63 68 61 72 20 2a 7a 4e 65 77 4e 61 6d 65  t char *zNewName
8610: 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51  ){.  int rc = SQ
8620: 4c 49 54 45 5f 4f 4b 3b 0a 20 20 65 63 68 6f 5f  LITE_OK;.  echo_
8630: 76 74 61 62 20 2a 70 20 3d 20 28 65 63 68 6f 5f  vtab *p = (echo_
8640: 76 74 61 62 20 2a 29 76 74 61 62 3b 0a 0a 20 20  vtab *)vtab;..  
8650: 69 66 28 20 73 69 6d 75 6c 61 74 65 56 74 61 62  if( simulateVtab
8660: 45 72 72 6f 72 28 70 2c 20 22 78 52 65 6e 61 6d  Error(p, "xRenam
8670: 65 22 29 20 29 7b 0a 20 20 20 20 72 65 74 75 72  e") ){.    retur
8680: 6e 20 53 51 4c 49 54 45 5f 45 52 52 4f 52 3b 0a  n SQLITE_ERROR;.
8690: 20 20 7d 0a 0a 20 20 69 66 28 20 70 2d 3e 69 73    }..  if( p->is
86a0: 50 61 74 74 65 72 6e 20 29 7b 0a 20 20 20 20 69  Pattern ){.    i
86b0: 6e 74 20 6e 54 68 69 73 20 3d 20 73 74 72 6c 65  nt nThis = strle
86c0: 6e 28 70 2d 3e 7a 54 68 69 73 29 3b 0a 20 20 20  n(p->zThis);.   
86d0: 20 63 68 61 72 20 2a 7a 53 71 6c 20 3d 20 73 71   char *zSql = sq
86e0: 6c 69 74 65 33 4d 50 72 69 6e 74 66 28 30 2c 20  lite3MPrintf(0, 
86f0: 22 41 4c 54 45 52 20 54 41 42 4c 45 20 25 73 20  "ALTER TABLE %s 
8700: 52 45 4e 41 4d 45 20 54 4f 20 25 73 25 73 22 2c  RENAME TO %s%s",
8710: 20 0a 20 20 20 20 20 20 20 20 70 2d 3e 7a 54 61   .        p->zTa
8720: 62 6c 65 4e 61 6d 65 2c 20 7a 4e 65 77 4e 61 6d  bleName, zNewNam
8730: 65 2c 20 26 70 2d 3e 7a 54 61 62 6c 65 4e 61 6d  e, &p->zTableNam
8740: 65 5b 6e 54 68 69 73 5d 0a 20 20 20 20 29 3b 0a  e[nThis].    );.
8750: 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33      rc = sqlite3
8760: 5f 65 78 65 63 28 70 2d 3e 64 62 2c 20 7a 53 71  _exec(p->db, zSq
8770: 6c 2c 20 30 2c 20 30 2c 20 30 29 3b 0a 20 20 20  l, 0, 0, 0);.   
8780: 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 7a 53   sqlite3_free(zS
8790: 71 6c 29 3b 0a 20 20 7d 0a 0a 20 20 72 65 74 75  ql);.  }..  retu
87a0: 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  rn rc;.}../*.** 
87b0: 41 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65 20  A virtual table 
87c0: 6d 6f 64 75 6c 65 20 74 68 61 74 20 6d 65 72 65  module that mere
87d0: 6c 79 20 22 65 63 68 6f 73 22 20 74 68 65 20 63  ly "echos" the c
87e0: 6f 6e 74 65 6e 74 73 20 6f 66 20 61 6e 6f 74 68  ontents of anoth
87f0: 65 72 0a 2a 2a 20 74 61 62 6c 65 20 28 6c 69 6b  er.** table (lik
8800: 65 20 61 6e 20 53 51 4c 20 56 49 45 57 29 2e 0a  e an SQL VIEW)..
8810: 2a 2f 0a 73 74 61 74 69 63 20 73 71 6c 69 74 65  */.static sqlite
8820: 33 5f 6d 6f 64 75 6c 65 20 65 63 68 6f 4d 6f 64  3_module echoMod
8830: 75 6c 65 20 3d 20 7b 0a 20 20 30 2c 20 20 20 20  ule = {.  0,    
8840: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8850: 20 20 20 20 20 2f 2a 20 69 56 65 72 73 69 6f 6e       /* iVersion
8860: 20 2a 2f 0a 20 20 65 63 68 6f 43 72 65 61 74 65   */.  echoCreate
8870: 2c 0a 20 20 65 63 68 6f 43 6f 6e 6e 65 63 74 2c  ,.  echoConnect,
8880: 0a 20 20 65 63 68 6f 42 65 73 74 49 6e 64 65 78  .  echoBestIndex
8890: 2c 0a 20 20 65 63 68 6f 44 69 73 63 6f 6e 6e 65  ,.  echoDisconne
88a0: 63 74 2c 20 0a 20 20 65 63 68 6f 44 65 73 74 72  ct, .  echoDestr
88b0: 6f 79 2c 0a 20 20 65 63 68 6f 4f 70 65 6e 2c 20  oy,.  echoOpen, 
88c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
88d0: 20 2f 2a 20 78 4f 70 65 6e 20 2d 20 6f 70 65 6e   /* xOpen - open
88e0: 20 61 20 63 75 72 73 6f 72 20 2a 2f 0a 20 20 65   a cursor */.  e
88f0: 63 68 6f 43 6c 6f 73 65 2c 20 20 20 20 20 20 20  choClose,       
8900: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 43 6c            /* xCl
8910: 6f 73 65 20 2d 20 63 6c 6f 73 65 20 61 20 63 75  ose - close a cu
8920: 72 73 6f 72 20 2a 2f 0a 20 20 65 63 68 6f 46 69  rsor */.  echoFi
8930: 6c 74 65 72 2c 20 20 20 20 20 20 20 20 20 20 20  lter,           
8940: 20 20 20 20 20 2f 2a 20 78 46 69 6c 74 65 72 20       /* xFilter 
8950: 2d 20 63 6f 6e 66 69 67 75 72 65 20 73 63 61 6e  - configure scan
8960: 20 63 6f 6e 73 74 72 61 69 6e 74 73 20 2a 2f 0a   constraints */.
8970: 20 20 65 63 68 6f 4e 65 78 74 2c 20 20 20 20 20    echoNext,     
8980: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
8990: 78 4e 65 78 74 20 2d 20 61 64 76 61 6e 63 65 20  xNext - advance 
89a0: 61 20 63 75 72 73 6f 72 20 2a 2f 0a 20 20 65 63  a cursor */.  ec
89b0: 68 6f 45 6f 66 2c 20 20 20 20 20 20 20 20 20 20  hoEof,          
89c0: 20 20 20 20 20 20 20 20 20 2f 2a 20 78 45 6f 66           /* xEof
89d0: 20 2a 2f 0a 20 20 65 63 68 6f 43 6f 6c 75 6d 6e   */.  echoColumn
89e0: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
89f0: 20 2f 2a 20 78 43 6f 6c 75 6d 6e 20 2d 20 72 65   /* xColumn - re
8a00: 61 64 20 64 61 74 61 20 2a 2f 0a 20 20 65 63 68  ad data */.  ech
8a10: 6f 52 6f 77 69 64 2c 20 20 20 20 20 20 20 20 20  oRowid,         
8a20: 20 20 20 20 20 20 20 20 2f 2a 20 78 52 6f 77 69          /* xRowi
8a30: 64 20 2d 20 72 65 61 64 20 64 61 74 61 20 2a 2f  d - read data */
8a40: 0a 20 20 65 63 68 6f 55 70 64 61 74 65 2c 20 20  .  echoUpdate,  
8a50: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
8a60: 20 78 55 70 64 61 74 65 20 2d 20 77 72 69 74 65   xUpdate - write
8a70: 20 64 61 74 61 20 2a 2f 0a 20 20 65 63 68 6f 42   data */.  echoB
8a80: 65 67 69 6e 2c 20 20 20 20 20 20 20 20 20 20 20  egin,           
8a90: 20 20 20 20 20 20 2f 2a 20 78 42 65 67 69 6e 20        /* xBegin 
8aa0: 2d 20 62 65 67 69 6e 20 74 72 61 6e 73 61 63 74  - begin transact
8ab0: 69 6f 6e 20 2a 2f 0a 20 20 65 63 68 6f 53 79 6e  ion */.  echoSyn
8ac0: 63 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  c,              
8ad0: 20 20 20 20 2f 2a 20 78 53 79 6e 63 20 2d 20 73      /* xSync - s
8ae0: 79 6e 63 20 74 72 61 6e 73 61 63 74 69 6f 6e 20  ync transaction 
8af0: 2a 2f 0a 20 20 65 63 68 6f 43 6f 6d 6d 69 74 2c  */.  echoCommit,
8b00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8b10: 2f 2a 20 78 43 6f 6d 6d 69 74 20 2d 20 63 6f 6d  /* xCommit - com
8b20: 6d 69 74 20 74 72 61 6e 73 61 63 74 69 6f 6e 20  mit transaction 
8b30: 2a 2f 0a 20 20 65 63 68 6f 52 6f 6c 6c 62 61 63  */.  echoRollbac
8b40: 6b 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  k,              
8b50: 2f 2a 20 78 52 6f 6c 6c 62 61 63 6b 20 2d 20 72  /* xRollback - r
8b60: 6f 6c 6c 62 61 63 6b 20 74 72 61 6e 73 61 63 74  ollback transact
8b70: 69 6f 6e 20 2a 2f 0a 20 20 65 63 68 6f 46 69 6e  ion */.  echoFin
8b80: 64 46 75 6e 63 74 69 6f 6e 2c 20 20 20 20 20 20  dFunction,      
8b90: 20 20 20 20 2f 2a 20 78 46 69 6e 64 46 75 6e 63      /* xFindFunc
8ba0: 74 69 6f 6e 20 2d 20 66 75 6e 63 74 69 6f 6e 20  tion - function 
8bb0: 6f 76 65 72 6c 6f 61 64 69 6e 67 20 2a 2f 0a 20  overloading */. 
8bc0: 20 65 63 68 6f 52 65 6e 61 6d 65 2c 20 20 20 20   echoRename,    
8bd0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78              /* x
8be0: 52 65 6e 61 6d 65 20 2d 20 72 65 6e 61 6d 65 20  Rename - rename 
8bf0: 74 68 65 20 74 61 62 6c 65 20 2a 2f 0a 7d 3b 0a  the table */.};.
8c00: 0a 2f 2a 0a 2a 2a 20 44 65 63 6f 64 65 20 61 20  ./*.** Decode a 
8c10: 70 6f 69 6e 74 65 72 20 74 6f 20 61 6e 20 73 71  pointer to an sq
8c20: 6c 69 74 65 33 20 6f 62 6a 65 63 74 2e 0a 2a 2f  lite3 object..*/
8c30: 0a 65 78 74 65 72 6e 20 69 6e 74 20 67 65 74 44  .extern int getD
8c40: 62 50 6f 69 6e 74 65 72 28 54 63 6c 5f 49 6e 74  bPointer(Tcl_Int
8c50: 65 72 70 20 2a 69 6e 74 65 72 70 2c 20 63 6f 6e  erp *interp, con
8c60: 73 74 20 63 68 61 72 20 2a 7a 41 2c 20 73 71 6c  st char *zA, sql
8c70: 69 74 65 33 20 2a 2a 70 70 44 62 29 3b 0a 0a 73  ite3 **ppDb);..s
8c80: 74 61 74 69 63 20 76 6f 69 64 20 6d 6f 64 75 6c  tatic void modul
8c90: 65 44 65 73 74 72 6f 79 28 76 6f 69 64 20 2a 70  eDestroy(void *p
8ca0: 29 7b 0a 20 20 73 71 6c 69 74 65 33 5f 66 72 65  ){.  sqlite3_fre
8cb0: 65 28 70 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52  e(p);.}../*.** R
8cc0: 65 67 69 73 74 65 72 20 74 68 65 20 65 63 68 6f  egister the echo
8cd0: 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65 20 6d   virtual table m
8ce0: 6f 64 75 6c 65 2e 0a 2a 2f 0a 73 74 61 74 69 63  odule..*/.static
8cf0: 20 69 6e 74 20 72 65 67 69 73 74 65 72 5f 65 63   int register_ec
8d00: 68 6f 5f 6d 6f 64 75 6c 65 28 0a 20 20 43 6c 69  ho_module(.  Cli
8d10: 65 6e 74 44 61 74 61 20 63 6c 69 65 6e 74 44 61  entData clientDa
8d20: 74 61 2c 20 2f 2a 20 50 6f 69 6e 74 65 72 20 74  ta, /* Pointer t
8d30: 6f 20 73 71 6c 69 74 65 33 5f 65 6e 61 62 6c 65  o sqlite3_enable
8d40: 5f 58 58 58 20 66 75 6e 63 74 69 6f 6e 20 2a 2f  _XXX function */
8d50: 0a 20 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69  .  Tcl_Interp *i
8d60: 6e 74 65 72 70 2c 20 20 20 20 2f 2a 20 54 68 65  nterp,    /* The
8d70: 20 54 43 4c 20 69 6e 74 65 72 70 72 65 74 65 72   TCL interpreter
8d80: 20 74 68 61 74 20 69 6e 76 6f 6b 65 64 20 74 68   that invoked th
8d90: 69 73 20 63 6f 6d 6d 61 6e 64 20 2a 2f 0a 20 20  is command */.  
8da0: 69 6e 74 20 6f 62 6a 63 2c 20 20 20 20 20 20 20  int objc,       
8db0: 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72         /* Number
8dc0: 20 6f 66 20 61 72 67 75 6d 65 6e 74 73 20 2a 2f   of arguments */
8dd0: 0a 20 20 54 63 6c 5f 4f 62 6a 20 2a 43 4f 4e 53  .  Tcl_Obj *CONS
8de0: 54 20 6f 62 6a 76 5b 5d 20 20 2f 2a 20 43 6f 6d  T objv[]  /* Com
8df0: 6d 61 6e 64 20 61 72 67 75 6d 65 6e 74 73 20 2a  mand arguments *
8e00: 2f 0a 29 7b 0a 20 20 73 71 6c 69 74 65 33 20 2a  /.){.  sqlite3 *
8e10: 64 62 3b 0a 20 20 45 63 68 6f 4d 6f 64 75 6c 65  db;.  EchoModule
8e20: 20 2a 70 4d 6f 64 3b 0a 20 20 69 66 28 20 6f 62   *pMod;.  if( ob
8e30: 6a 63 21 3d 32 20 29 7b 0a 20 20 20 20 54 63 6c  jc!=2 ){.    Tcl
8e40: 5f 57 72 6f 6e 67 4e 75 6d 41 72 67 73 28 69 6e  _WrongNumArgs(in
8e50: 74 65 72 70 2c 20 31 2c 20 6f 62 6a 76 2c 20 22  terp, 1, objv, "
8e60: 44 42 22 29 3b 0a 20 20 20 20 72 65 74 75 72 6e  DB");.    return
8e70: 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a   TCL_ERROR;.  }.
8e80: 20 20 69 66 28 20 67 65 74 44 62 50 6f 69 6e 74    if( getDbPoint
8e90: 65 72 28 69 6e 74 65 72 70 2c 20 54 63 6c 5f 47  er(interp, Tcl_G
8ea0: 65 74 53 74 72 69 6e 67 28 6f 62 6a 76 5b 31 5d  etString(objv[1]
8eb0: 29 2c 20 26 64 62 29 20 29 20 72 65 74 75 72 6e  ), &db) ) return
8ec0: 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 70 4d   TCL_ERROR;.  pM
8ed0: 6f 64 20 3d 20 73 71 6c 69 74 65 33 5f 6d 61 6c  od = sqlite3_mal
8ee0: 6c 6f 63 28 73 69 7a 65 6f 66 28 45 63 68 6f 4d  loc(sizeof(EchoM
8ef0: 6f 64 75 6c 65 29 29 3b 0a 20 20 70 4d 6f 64 2d  odule));.  pMod-
8f00: 3e 69 6e 74 65 72 70 20 3d 20 69 6e 74 65 72 70  >interp = interp
8f10: 3b 0a 20 20 73 71 6c 69 74 65 33 5f 63 72 65 61  ;.  sqlite3_crea
8f20: 74 65 5f 6d 6f 64 75 6c 65 5f 76 32 28 64 62 2c  te_module_v2(db,
8f30: 20 22 65 63 68 6f 22 2c 20 26 65 63 68 6f 4d 6f   "echo", &echoMo
8f40: 64 75 6c 65 2c 20 28 76 6f 69 64 2a 29 70 4d 6f  dule, (void*)pMo
8f50: 64 2c 20 6d 6f 64 75 6c 65 44 65 73 74 72 6f 79  d, moduleDestroy
8f60: 29 3b 0a 20 20 72 65 74 75 72 6e 20 54 43 4c 5f  );.  return TCL_
8f70: 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 63 6c  OK;.}../*.** Tcl
8f80: 20 69 6e 74 65 72 66 61 63 65 20 74 6f 20 73 71   interface to sq
8f90: 6c 69 74 65 33 5f 64 65 63 6c 61 72 65 5f 76 74  lite3_declare_vt
8fa0: 61 62 2c 20 69 6e 76 6f 6b 65 64 20 61 73 20 66  ab, invoked as f
8fb0: 6f 6c 6c 6f 77 73 20 66 72 6f 6d 20 54 63 6c 3a  ollows from Tcl:
8fc0: 0a 2a 2a 0a 2a 2a 20 73 71 6c 69 74 65 33 5f 64  .**.** sqlite3_d
8fd0: 65 63 6c 61 72 65 5f 76 74 61 62 20 44 42 20 53  eclare_vtab DB S
8fe0: 51 4c 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  QL.*/.static int
8ff0: 20 64 65 63 6c 61 72 65 5f 76 74 61 62 28 0a 20   declare_vtab(. 
9000: 20 43 6c 69 65 6e 74 44 61 74 61 20 63 6c 69 65   ClientData clie
9010: 6e 74 44 61 74 61 2c 20 2f 2a 20 50 6f 69 6e 74  ntData, /* Point
9020: 65 72 20 74 6f 20 73 71 6c 69 74 65 33 5f 65 6e  er to sqlite3_en
9030: 61 62 6c 65 5f 58 58 58 20 66 75 6e 63 74 69 6f  able_XXX functio
9040: 6e 20 2a 2f 0a 20 20 54 63 6c 5f 49 6e 74 65 72  n */.  Tcl_Inter
9050: 70 20 2a 69 6e 74 65 72 70 2c 20 20 20 20 2f 2a  p *interp,    /*
9060: 20 54 68 65 20 54 43 4c 20 69 6e 74 65 72 70 72   The TCL interpr
9070: 65 74 65 72 20 74 68 61 74 20 69 6e 76 6f 6b 65  eter that invoke
9080: 64 20 74 68 69 73 20 63 6f 6d 6d 61 6e 64 20 2a  d this command *
9090: 2f 0a 20 20 69 6e 74 20 6f 62 6a 63 2c 20 20 20  /.  int objc,   
90a0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75             /* Nu
90b0: 6d 62 65 72 20 6f 66 20 61 72 67 75 6d 65 6e 74  mber of argument
90c0: 73 20 2a 2f 0a 20 20 54 63 6c 5f 4f 62 6a 20 2a  s */.  Tcl_Obj *
90d0: 43 4f 4e 53 54 20 6f 62 6a 76 5b 5d 20 20 2f 2a  CONST objv[]  /*
90e0: 20 43 6f 6d 6d 61 6e 64 20 61 72 67 75 6d 65 6e   Command argumen
90f0: 74 73 20 2a 2f 0a 29 7b 0a 20 20 73 71 6c 69 74  ts */.){.  sqlit
9100: 65 33 20 2a 64 62 3b 0a 20 20 69 6e 74 20 72 63  e3 *db;.  int rc
9110: 3b 0a 20 20 69 66 28 20 6f 62 6a 63 21 3d 33 20  ;.  if( objc!=3 
9120: 29 7b 0a 20 20 20 20 54 63 6c 5f 57 72 6f 6e 67  ){.    Tcl_Wrong
9130: 4e 75 6d 41 72 67 73 28 69 6e 74 65 72 70 2c 20  NumArgs(interp, 
9140: 31 2c 20 6f 62 6a 76 2c 20 22 44 42 20 53 51 4c  1, objv, "DB SQL
9150: 22 29 3b 0a 20 20 20 20 72 65 74 75 72 6e 20 54  ");.    return T
9160: 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a 20 20  CL_ERROR;.  }.  
9170: 69 66 28 20 67 65 74 44 62 50 6f 69 6e 74 65 72  if( getDbPointer
9180: 28 69 6e 74 65 72 70 2c 20 54 63 6c 5f 47 65 74  (interp, Tcl_Get
9190: 53 74 72 69 6e 67 28 6f 62 6a 76 5b 31 5d 29 2c  String(objv[1]),
91a0: 20 26 64 62 29 20 29 20 72 65 74 75 72 6e 20 54   &db) ) return T
91b0: 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 72 63 20 3d  CL_ERROR;.  rc =
91c0: 20 73 71 6c 69 74 65 33 5f 64 65 63 6c 61 72 65   sqlite3_declare
91d0: 5f 76 74 61 62 28 64 62 2c 20 54 63 6c 5f 47 65  _vtab(db, Tcl_Ge
91e0: 74 53 74 72 69 6e 67 28 6f 62 6a 76 5b 32 5d 29  tString(objv[2])
91f0: 29 3b 0a 20 20 69 66 28 20 72 63 21 3d 53 51 4c  );.  if( rc!=SQL
9200: 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 54 63  ITE_OK ){.    Tc
9210: 6c 5f 53 65 74 52 65 73 75 6c 74 28 69 6e 74 65  l_SetResult(inte
9220: 72 70 2c 20 28 63 68 61 72 20 2a 29 73 71 6c 69  rp, (char *)sqli
9230: 74 65 33 5f 65 72 72 6d 73 67 28 64 62 29 2c 20  te3_errmsg(db), 
9240: 54 43 4c 5f 56 4f 4c 41 54 49 4c 45 29 3b 0a 20  TCL_VOLATILE);. 
9250: 20 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 45 52     return TCL_ER
9260: 52 4f 52 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72  ROR;.  }.  retur
9270: 6e 20 54 43 4c 5f 4f 4b 3b 0a 7d 0a 0a 23 65 6e  n TCL_OK;.}..#en
9280: 64 69 66 20 2f 2a 20 69 66 6e 64 65 66 20 53 51  dif /* ifndef SQ
9290: 4c 49 54 45 5f 4f 4d 49 54 5f 56 49 52 54 55 41  LITE_OMIT_VIRTUA
92a0: 4c 54 41 42 4c 45 20 2a 2f 0a 0a 2f 2a 0a 2a 2a  LTABLE */../*.**
92b0: 20 52 65 67 69 73 74 65 72 20 63 6f 6d 6d 61 6e   Register comman
92c0: 64 73 20 77 69 74 68 20 74 68 65 20 54 43 4c 20  ds with the TCL 
92d0: 69 6e 74 65 72 70 72 65 74 65 72 2e 0a 2a 2f 0a  interpreter..*/.
92e0: 69 6e 74 20 53 71 6c 69 74 65 74 65 73 74 38 5f  int Sqlitetest8_
92f0: 49 6e 69 74 28 54 63 6c 5f 49 6e 74 65 72 70 20  Init(Tcl_Interp 
9300: 2a 69 6e 74 65 72 70 29 7b 0a 20 20 73 74 61 74  *interp){.  stat
9310: 69 63 20 73 74 72 75 63 74 20 7b 0a 20 20 20 20  ic struct {.    
9320: 20 63 68 61 72 20 2a 7a 4e 61 6d 65 3b 0a 20 20   char *zName;.  
9330: 20 20 20 54 63 6c 5f 4f 62 6a 43 6d 64 50 72 6f     Tcl_ObjCmdPro
9340: 63 20 2a 78 50 72 6f 63 3b 0a 20 20 20 20 20 76  c *xProc;.     v
9350: 6f 69 64 20 2a 63 6c 69 65 6e 74 44 61 74 61 3b  oid *clientData;
9360: 0a 20 20 7d 20 61 4f 62 6a 43 6d 64 5b 5d 20 3d  .  } aObjCmd[] =
9370: 20 7b 0a 23 69 66 6e 64 65 66 20 53 51 4c 49 54   {.#ifndef SQLIT
9380: 45 5f 4f 4d 49 54 5f 56 49 52 54 55 41 4c 54 41  E_OMIT_VIRTUALTA
9390: 42 4c 45 0a 20 20 20 20 20 7b 20 22 72 65 67 69  BLE.     { "regi
93a0: 73 74 65 72 5f 65 63 68 6f 5f 6d 6f 64 75 6c 65  ster_echo_module
93b0: 22 2c 20 20 20 72 65 67 69 73 74 65 72 5f 65 63  ",   register_ec
93c0: 68 6f 5f 6d 6f 64 75 6c 65 2c 20 30 20 7d 2c 0a  ho_module, 0 },.
93d0: 20 20 20 20 20 7b 20 22 73 71 6c 69 74 65 33 5f       { "sqlite3_
93e0: 64 65 63 6c 61 72 65 5f 76 74 61 62 22 2c 20 20  declare_vtab",  
93f0: 20 64 65 63 6c 61 72 65 5f 76 74 61 62 2c 20 30   declare_vtab, 0
9400: 20 7d 2c 0a 23 65 6e 64 69 66 0a 20 20 7d 3b 0a   },.#endif.  };.
9410: 20 20 69 6e 74 20 69 3b 0a 20 20 66 6f 72 28 69    int i;.  for(i
9420: 3d 30 3b 20 69 3c 73 69 7a 65 6f 66 28 61 4f 62  =0; i<sizeof(aOb
9430: 6a 43 6d 64 29 2f 73 69 7a 65 6f 66 28 61 4f 62  jCmd)/sizeof(aOb
9440: 6a 43 6d 64 5b 30 5d 29 3b 20 69 2b 2b 29 7b 0a  jCmd[0]); i++){.
9450: 20 20 20 20 54 63 6c 5f 43 72 65 61 74 65 4f 62      Tcl_CreateOb
9460: 6a 43 6f 6d 6d 61 6e 64 28 69 6e 74 65 72 70 2c  jCommand(interp,
9470: 20 61 4f 62 6a 43 6d 64 5b 69 5d 2e 7a 4e 61 6d   aObjCmd[i].zNam
9480: 65 2c 20 0a 20 20 20 20 20 20 20 20 61 4f 62 6a  e, .        aObj
9490: 43 6d 64 5b 69 5d 2e 78 50 72 6f 63 2c 20 61 4f  Cmd[i].xProc, aO
94a0: 62 6a 43 6d 64 5b 69 5d 2e 63 6c 69 65 6e 74 44  bjCmd[i].clientD
94b0: 61 74 61 2c 20 30 29 3b 0a 20 20 7d 0a 20 20 72  ata, 0);.  }.  r
94c0: 65 74 75 72 6e 20 54 43 4c 5f 4f 4b 3b 0a 7d 0a  eturn TCL_OK;.}.