/ Hex Artifact Content
Login

Artifact 3f7d0cc4e12e06832ba3db4455cb16867ccadafa602eb6ff5fcf097bffce56ed:


0000: 2f 2a 0a 2a 2a 20 32 30 30 36 20 4a 75 6e 65 20  /*.** 2006 June 
0010: 31 30 0a 2a 2a 0a 2a 2a 20 54 68 65 20 61 75 74  10.**.** The aut
0020: 68 6f 72 20 64 69 73 63 6c 61 69 6d 73 20 63 6f  hor disclaims co
0030: 70 79 72 69 67 68 74 20 74 6f 20 74 68 69 73 20  pyright to this 
0040: 73 6f 75 72 63 65 20 63 6f 64 65 2e 20 20 49 6e  source code.  In
0050: 20 70 6c 61 63 65 20 6f 66 0a 2a 2a 20 61 20 6c   place of.** a l
0060: 65 67 61 6c 20 6e 6f 74 69 63 65 2c 20 68 65 72  egal notice, her
0070: 65 20 69 73 20 61 20 62 6c 65 73 73 69 6e 67 3a  e is a blessing:
0080: 0a 2a 2a 0a 2a 2a 20 20 20 20 4d 61 79 20 79 6f  .**.**    May yo
0090: 75 20 64 6f 20 67 6f 6f 64 20 61 6e 64 20 6e 6f  u do good and no
00a0: 74 20 65 76 69 6c 2e 0a 2a 2a 20 20 20 20 4d 61  t evil..**    Ma
00b0: 79 20 79 6f 75 20 66 69 6e 64 20 66 6f 72 67 69  y you find forgi
00c0: 76 65 6e 65 73 73 20 66 6f 72 20 79 6f 75 72 73  veness for yours
00d0: 65 6c 66 20 61 6e 64 20 66 6f 72 67 69 76 65 20  elf and forgive 
00e0: 6f 74 68 65 72 73 2e 0a 2a 2a 20 20 20 20 4d 61  others..**    Ma
00f0: 79 20 79 6f 75 20 73 68 61 72 65 20 66 72 65 65  y you share free
0100: 6c 79 2c 20 6e 65 76 65 72 20 74 61 6b 69 6e 67  ly, never taking
0110: 20 6d 6f 72 65 20 74 68 61 6e 20 79 6f 75 20 67   more than you g
0120: 69 76 65 2e 0a 2a 2a 0a 2a 2a 2a 2a 2a 2a 2a 2a  ive..**.********
0130: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0140: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0150: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0160: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0170: 2a 0a 2a 2a 20 43 6f 64 65 20 66 6f 72 20 74 65  *.** Code for te
0180: 73 74 69 6e 67 20 74 68 65 20 76 69 72 74 75 61  sting the virtua
0190: 6c 20 74 61 62 6c 65 20 69 6e 74 65 72 66 61 63  l table interfac
01a0: 65 73 2e 20 20 54 68 69 73 20 63 6f 64 65 0a 2a  es.  This code.*
01b0: 2a 20 69 73 20 6e 6f 74 20 69 6e 63 6c 75 64 65  * is not include
01c0: 64 20 69 6e 20 74 68 65 20 53 51 4c 69 74 65 20  d in the SQLite 
01d0: 6c 69 62 72 61 72 79 2e 20 20 49 74 20 69 73 20  library.  It is 
01e0: 75 73 65 64 20 66 6f 72 20 61 75 74 6f 6d 61 74  used for automat
01f0: 65 64 0a 2a 2a 20 74 65 73 74 69 6e 67 20 6f 66  ed.** testing of
0200: 20 74 68 65 20 53 51 4c 69 74 65 20 6c 69 62 72   the SQLite libr
0210: 61 72 79 2e 0a 2a 2f 0a 23 69 6e 63 6c 75 64 65  ary..*/.#include
0220: 20 22 73 71 6c 69 74 65 49 6e 74 2e 68 22 0a 23   "sqliteInt.h".#
0230: 69 66 20 64 65 66 69 6e 65 64 28 49 4e 43 4c 55  if defined(INCLU
0240: 44 45 5f 53 51 4c 49 54 45 5f 54 43 4c 5f 48 29  DE_SQLITE_TCL_H)
0250: 0a 23 20 20 69 6e 63 6c 75 64 65 20 22 73 71 6c  .#  include "sql
0260: 69 74 65 5f 74 63 6c 2e 68 22 0a 23 65 6c 73 65  ite_tcl.h".#else
0270: 0a 23 20 20 69 6e 63 6c 75 64 65 20 22 74 63 6c  .#  include "tcl
0280: 2e 68 22 0a 23 65 6e 64 69 66 0a 23 69 6e 63 6c  .h".#endif.#incl
0290: 75 64 65 20 3c 73 74 64 6c 69 62 2e 68 3e 0a 23  ude <stdlib.h>.#
02a0: 69 6e 63 6c 75 64 65 20 3c 73 74 72 69 6e 67 2e  include <string.
02b0: 68 3e 0a 0a 23 69 66 6e 64 65 66 20 53 51 4c 49  h>..#ifndef SQLI
02c0: 54 45 5f 4f 4d 49 54 5f 56 49 52 54 55 41 4c 54  TE_OMIT_VIRTUALT
02d0: 41 42 4c 45 0a 0a 74 79 70 65 64 65 66 20 73 74  ABLE..typedef st
02e0: 72 75 63 74 20 65 63 68 6f 5f 76 74 61 62 20 65  ruct echo_vtab e
02f0: 63 68 6f 5f 76 74 61 62 3b 0a 74 79 70 65 64 65  cho_vtab;.typede
0300: 66 20 73 74 72 75 63 74 20 65 63 68 6f 5f 63 75  f struct echo_cu
0310: 72 73 6f 72 20 65 63 68 6f 5f 63 75 72 73 6f 72  rsor echo_cursor
0320: 3b 0a 0a 2f 2a 0a 2a 2a 20 54 68 65 20 74 65 73  ;../*.** The tes
0330: 74 20 6d 6f 64 75 6c 65 20 64 65 66 69 6e 65 64  t module defined
0340: 20 69 6e 20 74 68 69 73 20 66 69 6c 65 20 75 73   in this file us
0350: 65 73 20 66 6f 75 72 20 67 6c 6f 62 61 6c 20 54  es four global T
0360: 63 6c 20 76 61 72 69 61 62 6c 65 73 20 74 6f 0a  cl variables to.
0370: 2a 2a 20 63 6f 6d 6d 69 63 61 74 65 20 77 69 74  ** commicate wit
0380: 68 20 74 65 73 74 2d 73 63 72 69 70 74 73 3a 0a  h test-scripts:.
0390: 2a 2a 0a 2a 2a 20 20 20 20 20 24 3a 3a 65 63 68  **.**     $::ech
03a0: 6f 5f 6d 6f 64 75 6c 65 0a 2a 2a 20 20 20 20 20  o_module.**     
03b0: 24 3a 3a 65 63 68 6f 5f 6d 6f 64 75 6c 65 5f 73  $::echo_module_s
03c0: 79 6e 63 5f 66 61 69 6c 0a 2a 2a 20 20 20 20 20  ync_fail.**     
03d0: 24 3a 3a 65 63 68 6f 5f 6d 6f 64 75 6c 65 5f 62  $::echo_module_b
03e0: 65 67 69 6e 5f 66 61 69 6c 0a 2a 2a 20 20 20 20  egin_fail.**    
03f0: 20 24 3a 3a 65 63 68 6f 5f 6d 6f 64 75 6c 65 5f   $::echo_module_
0400: 63 6f 73 74 0a 2a 2a 0a 2a 2a 20 54 68 65 20 76  cost.**.** The v
0410: 61 72 69 61 62 6c 65 20 3a 3a 65 63 68 6f 5f 6d  ariable ::echo_m
0420: 6f 64 75 6c 65 20 69 73 20 61 20 6c 69 73 74 2e  odule is a list.
0430: 20 45 61 63 68 20 74 69 6d 65 20 6f 6e 65 20 6f   Each time one o
0440: 66 20 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 0a  f the following.
0450: 2a 2a 20 6d 65 74 68 6f 64 73 20 69 73 20 63 61  ** methods is ca
0460: 6c 6c 65 64 2c 20 6f 6e 65 20 6f 72 20 6d 6f 72  lled, one or mor
0470: 65 20 65 6c 65 6d 65 6e 74 73 20 61 72 65 20 61  e elements are a
0480: 70 70 65 6e 64 65 64 20 74 6f 20 74 68 65 20 6c  ppended to the l
0490: 69 73 74 2e 0a 2a 2a 20 54 68 69 73 20 69 73 20  ist..** This is 
04a0: 75 73 65 64 20 66 6f 72 20 61 75 74 6f 6d 61 74  used for automat
04b0: 65 64 20 74 65 73 74 69 6e 67 20 6f 66 20 76 69  ed testing of vi
04c0: 72 74 75 61 6c 20 74 61 62 6c 65 20 6d 6f 64 75  rtual table modu
04d0: 6c 65 73 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 3a  les..**.** The :
04e0: 3a 65 63 68 6f 5f 6d 6f 64 75 6c 65 5f 73 79 6e  :echo_module_syn
04f0: 63 5f 66 61 69 6c 20 76 61 72 69 61 62 6c 65 20  c_fail variable 
0500: 69 73 20 73 65 74 20 62 79 20 74 65 73 74 20 73  is set by test s
0510: 63 72 69 70 74 73 20 61 6e 64 20 72 65 61 64 0a  cripts and read.
0520: 2a 2a 20 62 79 20 63 6f 64 65 20 69 6e 20 74 68  ** by code in th
0530: 69 73 20 66 69 6c 65 2e 20 49 66 20 69 74 20 69  is file. If it i
0540: 73 20 73 65 74 20 74 6f 20 74 68 65 20 6e 61 6d  s set to the nam
0550: 65 20 6f 66 20 61 20 72 65 61 6c 20 74 61 62 6c  e of a real tabl
0560: 65 20 69 6e 20 74 68 65 0a 2a 2a 20 74 68 65 20  e in the.** the 
0570: 64 61 74 61 62 61 73 65 2c 20 74 68 65 6e 20 61  database, then a
0580: 6c 6c 20 78 53 79 6e 63 20 6f 70 65 72 61 74 69  ll xSync operati
0590: 6f 6e 73 20 6f 6e 20 65 63 68 6f 20 76 69 72 74  ons on echo virt
05a0: 75 61 6c 20 74 61 62 6c 65 73 20 74 68 61 74 0a  ual tables that.
05b0: 2a 2a 20 75 73 65 20 74 68 65 20 6e 61 6d 65 64  ** use the named
05c0: 20 74 61 62 6c 65 20 61 73 20 61 20 62 61 63 6b   table as a back
05d0: 69 6e 67 20 73 74 6f 72 65 20 77 69 6c 6c 20 66  ing store will f
05e0: 61 69 6c 2e 0a 2a 2f 0a 0a 2f 2a 0a 2a 2a 20 45  ail..*/../*.** E
05f0: 72 72 6f 72 73 20 63 61 6e 20 62 65 20 70 72 6f  rrors can be pro
0600: 76 6f 6b 65 64 20 77 69 74 68 69 6e 20 74 68 65  voked within the
0610: 20 66 6f 6c 6c 6f 77 69 6e 67 20 65 63 68 6f 20   following echo 
0620: 76 69 72 74 75 61 6c 20 74 61 62 6c 65 20 6d 65  virtual table me
0630: 74 68 6f 64 73 3a 0a 2a 2a 0a 2a 2a 20 20 20 78  thods:.**.**   x
0640: 42 65 73 74 49 6e 64 65 78 20 20 20 78 4f 70 65  BestIndex   xOpe
0650: 6e 20 20 20 20 20 78 46 69 6c 74 65 72 20 20 20  n     xFilter   
0660: 78 4e 65 78 74 20 20 20 0a 2a 2a 20 20 20 78 43  xNext   .**   xC
0670: 6f 6c 75 6d 6e 20 20 20 20 20 20 78 52 6f 77 69  olumn      xRowi
0680: 64 20 20 20 20 78 55 70 64 61 74 65 20 20 20 78  d    xUpdate   x
0690: 53 79 6e 63 20 20 20 0a 2a 2a 20 20 20 78 42 65  Sync   .**   xBe
06a0: 67 69 6e 20 20 20 20 20 20 20 78 52 65 6e 61 6d  gin       xRenam
06b0: 65 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20 69 73 20  e.**.** This is 
06c0: 64 6f 6e 65 20 62 79 20 73 65 74 74 69 6e 67 20  done by setting 
06d0: 74 68 65 20 67 6c 6f 62 61 6c 20 74 63 6c 20 76  the global tcl v
06e0: 61 72 69 61 62 6c 65 3a 0a 2a 2a 0a 2a 2a 20 20  ariable:.**.**  
06f0: 20 65 63 68 6f 5f 6d 6f 64 75 6c 65 5f 66 61 69   echo_module_fai
0700: 6c 28 24 6d 65 74 68 6f 64 2c 24 74 62 6c 29 0a  l($method,$tbl).
0710: 2a 2a 0a 2a 2a 20 77 68 65 72 65 20 24 6d 65 74  **.** where $met
0720: 68 6f 64 20 69 73 20 73 65 74 20 74 6f 20 74 68  hod is set to th
0730: 65 20 6e 61 6d 65 20 6f 66 20 74 68 65 20 76 69  e name of the vi
0740: 72 74 75 61 6c 20 74 61 62 6c 65 20 6d 65 74 68  rtual table meth
0750: 6f 64 20 74 6f 20 66 61 69 6c 0a 2a 2a 20 28 69  od to fail.** (i
0760: 2e 65 2e 20 22 78 42 65 73 74 49 6e 64 65 78 22  .e. "xBestIndex"
0770: 29 20 61 6e 64 20 24 74 62 6c 20 69 73 20 74 68  ) and $tbl is th
0780: 65 20 6e 61 6d 65 20 6f 66 20 74 68 65 20 74 61  e name of the ta
0790: 62 6c 65 20 62 65 69 6e 67 20 65 63 68 6f 65 64  ble being echoed
07a0: 20 28 6e 6f 74 0a 2a 2a 20 74 68 65 20 6e 61 6d   (not.** the nam
07b0: 65 20 6f 66 20 74 68 65 20 76 69 72 74 75 61 6c  e of the virtual
07c0: 20 74 61 62 6c 65 2c 20 74 68 65 20 6e 61 6d 65   table, the name
07d0: 20 6f 66 20 74 68 65 20 75 6e 64 65 72 6c 79 69   of the underlyi
07e0: 6e 67 20 72 65 61 6c 20 74 61 62 6c 65 29 2e 0a  ng real table)..
07f0: 2a 2f 0a 0a 2f 2a 20 0a 2a 2a 20 41 6e 20 65 63  */../* .** An ec
0800: 68 6f 20 76 69 72 74 75 61 6c 2d 74 61 62 6c 65  ho virtual-table
0810: 20 6f 62 6a 65 63 74 2e 0a 2a 2a 0a 2a 2a 20 65   object..**.** e
0820: 63 68 6f 2e 76 74 61 62 2e 61 49 6e 64 65 78 20  cho.vtab.aIndex 
0830: 69 73 20 61 6e 20 61 72 72 61 79 20 6f 66 20 62  is an array of b
0840: 6f 6f 6c 65 61 6e 73 2e 20 54 68 65 20 6e 74 68  ooleans. The nth
0850: 20 65 6e 74 72 79 20 69 73 20 74 72 75 65 20 69   entry is true i
0860: 66 20 0a 2a 2a 20 74 68 65 20 6e 74 68 20 63 6f  f .** the nth co
0870: 6c 75 6d 6e 20 6f 66 20 74 68 65 20 72 65 61 6c  lumn of the real
0880: 20 74 61 62 6c 65 20 69 73 20 74 68 65 20 6c 65   table is the le
0890: 66 74 2d 6d 6f 73 74 20 63 6f 6c 75 6d 6e 20 6f  ft-most column o
08a0: 66 20 61 6e 20 69 6e 64 65 78 0a 2a 2a 20 28 69  f an index.** (i
08b0: 6d 70 6c 69 63 69 74 20 6f 72 20 6f 74 68 65 72  mplicit or other
08c0: 77 69 73 65 29 2e 20 49 6e 20 6f 74 68 65 72 20  wise). In other 
08d0: 77 6f 72 64 73 2c 20 69 66 20 53 51 4c 69 74 65  words, if SQLite
08e0: 20 63 61 6e 20 6f 70 74 69 6d 69 7a 65 0a 2a 2a   can optimize.**
08f0: 20 61 20 71 75 65 72 79 20 6c 69 6b 65 20 22 53   a query like "S
0900: 45 4c 45 43 54 20 2a 20 46 52 4f 4d 20 72 65 61  ELECT * FROM rea
0910: 6c 5f 74 61 62 6c 65 20 57 48 45 52 45 20 63 6f  l_table WHERE co
0920: 6c 20 3d 20 3f 22 2e 0a 2a 2a 0a 2a 2a 20 4d 65  l = ?"..**.** Me
0930: 6d 62 65 72 20 76 61 72 69 61 62 6c 65 20 61 43  mber variable aC
0940: 6f 6c 5b 5d 20 63 6f 6e 74 61 69 6e 73 20 63 6f  ol[] contains co
0950: 70 69 65 73 20 6f 66 20 74 68 65 20 63 6f 6c 75  pies of the colu
0960: 6d 6e 20 6e 61 6d 65 73 20 6f 66 20 74 68 65 20  mn names of the 
0970: 72 65 61 6c 0a 2a 2a 20 74 61 62 6c 65 2e 0a 2a  real.** table..*
0980: 2f 0a 73 74 72 75 63 74 20 65 63 68 6f 5f 76 74  /.struct echo_vt
0990: 61 62 20 7b 0a 20 20 73 71 6c 69 74 65 33 5f 76  ab {.  sqlite3_v
09a0: 74 61 62 20 62 61 73 65 3b 0a 20 20 54 63 6c 5f  tab base;.  Tcl_
09b0: 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 3b 20  Interp *interp; 
09c0: 20 20 20 20 2f 2a 20 54 63 6c 20 69 6e 74 65 72      /* Tcl inter
09d0: 70 72 65 74 65 72 20 63 6f 6e 74 61 69 6e 69 6e  preter containin
09e0: 67 20 64 65 62 75 67 20 76 61 72 69 61 62 6c 65  g debug variable
09f0: 73 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 20 2a  s */.  sqlite3 *
0a00: 64 62 3b 20 20 20 20 20 20 20 20 20 20 20 20 2f  db;            /
0a10: 2a 20 44 61 74 61 62 61 73 65 20 63 6f 6e 6e 65  * Database conne
0a20: 63 74 69 6f 6e 20 2a 2f 0a 0a 20 20 69 6e 74 20  ction */..  int 
0a30: 69 73 50 61 74 74 65 72 6e 3b 0a 20 20 69 6e 74  isPattern;.  int
0a40: 20 69 6e 54 72 61 6e 73 61 63 74 69 6f 6e 3b 20   inTransaction; 
0a50: 20 20 20 20 20 2f 2a 20 54 72 75 65 20 69 66 20       /* True if 
0a60: 77 69 74 68 69 6e 20 61 20 74 72 61 6e 73 61 63  within a transac
0a70: 74 69 6f 6e 20 2a 2f 0a 20 20 63 68 61 72 20 2a  tion */.  char *
0a80: 7a 54 68 69 73 3b 20 20 20 20 20 20 20 20 20 20  zThis;          
0a90: 20 20 2f 2a 20 4e 61 6d 65 20 6f 66 20 74 68 65    /* Name of the
0aa0: 20 65 63 68 6f 20 74 61 62 6c 65 20 2a 2f 0a 20   echo table */. 
0ab0: 20 63 68 61 72 20 2a 7a 54 61 62 6c 65 4e 61 6d   char *zTableNam
0ac0: 65 3b 20 20 20 20 20 20 20 2f 2a 20 4e 61 6d 65  e;       /* Name
0ad0: 20 6f 66 20 74 68 65 20 72 65 61 6c 20 74 61 62   of the real tab
0ae0: 6c 65 20 2a 2f 0a 20 20 63 68 61 72 20 2a 7a 4c  le */.  char *zL
0af0: 6f 67 4e 61 6d 65 3b 20 20 20 20 20 20 20 20 20  ogName;         
0b00: 2f 2a 20 4e 61 6d 65 20 6f 66 20 74 68 65 20 6c  /* Name of the l
0b10: 6f 67 20 74 61 62 6c 65 20 2a 2f 0a 20 20 69 6e  og table */.  in
0b20: 74 20 6e 43 6f 6c 3b 20 20 20 20 20 20 20 20 20  t nCol;         
0b30: 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20        /* Number 
0b40: 6f 66 20 63 6f 6c 75 6d 6e 73 20 69 6e 20 74 68  of columns in th
0b50: 65 20 72 65 61 6c 20 74 61 62 6c 65 20 2a 2f 0a  e real table */.
0b60: 20 20 69 6e 74 20 2a 61 49 6e 64 65 78 3b 20 20    int *aIndex;  
0b70: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 41 72 72            /* Arr
0b80: 61 79 20 6f 66 20 73 69 7a 65 20 6e 43 6f 6c 2e  ay of size nCol.
0b90: 20 54 72 75 65 20 69 66 20 63 6f 6c 75 6d 6e 20   True if column 
0ba0: 68 61 73 20 61 6e 20 69 6e 64 65 78 20 2a 2f 0a  has an index */.
0bb0: 20 20 63 68 61 72 20 2a 2a 61 43 6f 6c 3b 20 20    char **aCol;  
0bc0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 41 72 72            /* Arr
0bd0: 61 79 20 6f 66 20 73 69 7a 65 20 6e 43 6f 6c 2e  ay of size nCol.
0be0: 20 43 6f 6c 75 6d 6e 20 6e 61 6d 65 73 20 2a 2f   Column names */
0bf0: 0a 7d 3b 0a 0a 2f 2a 20 41 6e 20 65 63 68 6f 20  .};../* An echo 
0c00: 63 75 72 73 6f 72 20 6f 62 6a 65 63 74 20 2a 2f  cursor object */
0c10: 0a 73 74 72 75 63 74 20 65 63 68 6f 5f 63 75 72  .struct echo_cur
0c20: 73 6f 72 20 7b 0a 20 20 73 71 6c 69 74 65 33 5f  sor {.  sqlite3_
0c30: 76 74 61 62 5f 63 75 72 73 6f 72 20 62 61 73 65  vtab_cursor base
0c40: 3b 0a 20 20 73 71 6c 69 74 65 33 5f 73 74 6d 74  ;.  sqlite3_stmt
0c50: 20 2a 70 53 74 6d 74 3b 0a 7d 3b 0a 0a 73 74 61   *pStmt;.};..sta
0c60: 74 69 63 20 69 6e 74 20 73 69 6d 75 6c 61 74 65  tic int simulate
0c70: 56 74 61 62 45 72 72 6f 72 28 65 63 68 6f 5f 76  VtabError(echo_v
0c80: 74 61 62 20 2a 70 2c 20 63 6f 6e 73 74 20 63 68  tab *p, const ch
0c90: 61 72 20 2a 7a 4d 65 74 68 6f 64 29 7b 0a 20 20  ar *zMethod){.  
0ca0: 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 45 72 72  const char *zErr
0cb0: 3b 0a 20 20 63 68 61 72 20 7a 56 61 72 6e 61 6d  ;.  char zVarnam
0cc0: 65 5b 31 32 38 5d 3b 0a 20 20 7a 56 61 72 6e 61  e[128];.  zVarna
0cd0: 6d 65 5b 31 32 37 5d 20 3d 20 27 5c 30 27 3b 0a  me[127] = '\0';.
0ce0: 20 20 73 71 6c 69 74 65 33 5f 73 6e 70 72 69 6e    sqlite3_snprin
0cf0: 74 66 28 31 32 37 2c 20 7a 56 61 72 6e 61 6d 65  tf(127, zVarname
0d00: 2c 20 22 65 63 68 6f 5f 6d 6f 64 75 6c 65 5f 66  , "echo_module_f
0d10: 61 69 6c 28 25 73 2c 25 73 29 22 2c 20 7a 4d 65  ail(%s,%s)", zMe
0d20: 74 68 6f 64 2c 20 70 2d 3e 7a 54 61 62 6c 65 4e  thod, p->zTableN
0d30: 61 6d 65 29 3b 0a 20 20 7a 45 72 72 20 3d 20 54  ame);.  zErr = T
0d40: 63 6c 5f 47 65 74 56 61 72 28 70 2d 3e 69 6e 74  cl_GetVar(p->int
0d50: 65 72 70 2c 20 7a 56 61 72 6e 61 6d 65 2c 20 54  erp, zVarname, T
0d60: 43 4c 5f 47 4c 4f 42 41 4c 5f 4f 4e 4c 59 29 3b  CL_GLOBAL_ONLY);
0d70: 0a 20 20 69 66 28 20 7a 45 72 72 20 29 7b 0a 20  .  if( zErr ){. 
0d80: 20 20 20 70 2d 3e 62 61 73 65 2e 7a 45 72 72 4d     p->base.zErrM
0d90: 73 67 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72  sg = sqlite3_mpr
0da0: 69 6e 74 66 28 22 65 63 68 6f 2d 76 74 61 62 2d  intf("echo-vtab-
0db0: 65 72 72 6f 72 3a 20 25 73 22 2c 20 7a 45 72 72  error: %s", zErr
0dc0: 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20  );.  }.  return 
0dd0: 28 7a 45 72 72 21 3d 30 29 3b 0a 7d 0a 0a 2f 2a  (zErr!=0);.}../*
0de0: 0a 2a 2a 20 43 6f 6e 76 65 72 74 20 61 6e 20 53  .** Convert an S
0df0: 51 4c 2d 73 74 79 6c 65 20 71 75 6f 74 65 64 20  QL-style quoted 
0e00: 73 74 72 69 6e 67 20 69 6e 74 6f 20 61 20 6e 6f  string into a no
0e10: 72 6d 61 6c 20 73 74 72 69 6e 67 20 62 79 20 72  rmal string by r
0e20: 65 6d 6f 76 69 6e 67 0a 2a 2a 20 74 68 65 20 71  emoving.** the q
0e30: 75 6f 74 65 20 63 68 61 72 61 63 74 65 72 73 2e  uote characters.
0e40: 20 20 54 68 65 20 63 6f 6e 76 65 72 73 69 6f 6e    The conversion
0e50: 20 69 73 20 64 6f 6e 65 20 69 6e 2d 70 6c 61 63   is done in-plac
0e60: 65 2e 20 20 49 66 20 74 68 65 0a 2a 2a 20 69 6e  e.  If the.** in
0e70: 70 75 74 20 64 6f 65 73 20 6e 6f 74 20 62 65 67  put does not beg
0e80: 69 6e 20 77 69 74 68 20 61 20 71 75 6f 74 65 20  in with a quote 
0e90: 63 68 61 72 61 63 74 65 72 2c 20 74 68 65 6e 20  character, then 
0ea0: 74 68 69 73 20 72 6f 75 74 69 6e 65 0a 2a 2a 20  this routine.** 
0eb0: 69 73 20 61 20 6e 6f 2d 6f 70 2e 0a 2a 2a 0a 2a  is a no-op..**.*
0ec0: 2a 20 45 78 61 6d 70 6c 65 73 3a 0a 2a 2a 0a 2a  * Examples:.**.*
0ed0: 2a 20 20 20 20 20 22 61 62 63 22 20 20 20 62 65  *     "abc"   be
0ee0: 63 6f 6d 65 73 20 20 20 61 62 63 0a 2a 2a 20 20  comes   abc.**  
0ef0: 20 20 20 27 78 79 7a 27 20 20 20 62 65 63 6f 6d     'xyz'   becom
0f00: 65 73 20 20 20 78 79 7a 0a 2a 2a 20 20 20 20 20  es   xyz.**     
0f10: 5b 70 71 72 5d 20 20 20 62 65 63 6f 6d 65 73 20  [pqr]   becomes 
0f20: 20 20 70 71 72 0a 2a 2a 20 20 20 20 20 60 6d 6e    pqr.**     `mn
0f30: 6f 60 20 20 20 62 65 63 6f 6d 65 73 20 20 20 6d  o`   becomes   m
0f40: 6e 6f 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69  no.*/.static voi
0f50: 64 20 64 65 71 75 6f 74 65 53 74 72 69 6e 67 28  d dequoteString(
0f60: 63 68 61 72 20 2a 7a 29 7b 0a 20 20 69 6e 74 20  char *z){.  int 
0f70: 71 75 6f 74 65 3b 0a 20 20 69 6e 74 20 69 2c 20  quote;.  int i, 
0f80: 6a 3b 0a 20 20 69 66 28 20 7a 3d 3d 30 20 29 20  j;.  if( z==0 ) 
0f90: 72 65 74 75 72 6e 3b 0a 20 20 71 75 6f 74 65 20  return;.  quote 
0fa0: 3d 20 7a 5b 30 5d 3b 0a 20 20 73 77 69 74 63 68  = z[0];.  switch
0fb0: 28 20 71 75 6f 74 65 20 29 7b 0a 20 20 20 20 63  ( quote ){.    c
0fc0: 61 73 65 20 27 5c 27 27 3a 20 20 62 72 65 61 6b  ase '\'':  break
0fd0: 3b 0a 20 20 20 20 63 61 73 65 20 27 22 27 3a 20  ;.    case '"': 
0fe0: 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 63 61 73    break;.    cas
0ff0: 65 20 27 60 27 3a 20 20 20 62 72 65 61 6b 3b 20  e '`':   break; 
1000: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
1010: 2a 20 46 6f 72 20 4d 79 53 51 4c 20 63 6f 6d 70  * For MySQL comp
1020: 61 74 69 62 69 6c 69 74 79 20 2a 2f 0a 20 20 20  atibility */.   
1030: 20 63 61 73 65 20 27 5b 27 3a 20 20 20 71 75 6f   case '[':   quo
1040: 74 65 20 3d 20 27 5d 27 3b 20 20 62 72 65 61 6b  te = ']';  break
1050: 3b 20 20 2f 2a 20 46 6f 72 20 4d 53 20 53 71 6c  ;  /* For MS Sql
1060: 53 65 72 76 65 72 20 63 6f 6d 70 61 74 69 62 69  Server compatibi
1070: 6c 69 74 79 20 2a 2f 0a 20 20 20 20 64 65 66 61  lity */.    defa
1080: 75 6c 74 3a 20 20 20 20 72 65 74 75 72 6e 3b 0a  ult:    return;.
1090: 20 20 7d 0a 20 20 66 6f 72 28 69 3d 31 2c 20 6a    }.  for(i=1, j
10a0: 3d 30 3b 20 7a 5b 69 5d 3b 20 69 2b 2b 29 7b 0a  =0; z[i]; i++){.
10b0: 20 20 20 20 69 66 28 20 7a 5b 69 5d 3d 3d 71 75      if( z[i]==qu
10c0: 6f 74 65 20 29 7b 0a 20 20 20 20 20 20 69 66 28  ote ){.      if(
10d0: 20 7a 5b 69 2b 31 5d 3d 3d 71 75 6f 74 65 20 29   z[i+1]==quote )
10e0: 7b 0a 20 20 20 20 20 20 20 20 7a 5b 6a 2b 2b 5d  {.        z[j++]
10f0: 20 3d 20 71 75 6f 74 65 3b 0a 20 20 20 20 20 20   = quote;.      
1100: 20 20 69 2b 2b 3b 0a 20 20 20 20 20 20 7d 65 6c    i++;.      }el
1110: 73 65 7b 0a 20 20 20 20 20 20 20 20 7a 5b 6a 2b  se{.        z[j+
1120: 2b 5d 20 3d 20 30 3b 0a 20 20 20 20 20 20 20 20  +] = 0;.        
1130: 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 7d 0a 20  break;.      }. 
1140: 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20     }else{.      
1150: 7a 5b 6a 2b 2b 5d 20 3d 20 7a 5b 69 5d 3b 0a 20  z[j++] = z[i];. 
1160: 20 20 20 7d 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a     }.  }.}../*.*
1170: 2a 20 52 65 74 72 69 65 76 65 20 74 68 65 20 63  * Retrieve the c
1180: 6f 6c 75 6d 6e 20 6e 61 6d 65 73 20 66 6f 72 20  olumn names for 
1190: 74 68 65 20 74 61 62 6c 65 20 6e 61 6d 65 64 20  the table named 
11a0: 7a 54 61 62 20 76 69 61 20 64 61 74 61 62 61 73  zTab via databas
11b0: 65 0a 2a 2a 20 63 6f 6e 6e 65 63 74 69 6f 6e 20  e.** connection 
11c0: 64 62 2e 20 53 51 4c 49 54 45 5f 4f 4b 20 69 73  db. SQLITE_OK is
11d0: 20 72 65 74 75 72 6e 65 64 20 6f 6e 20 73 75 63   returned on suc
11e0: 63 65 73 73 2c 20 6f 72 20 61 6e 20 73 71 6c 69  cess, or an sqli
11f0: 74 65 20 65 72 72 6f 72 0a 2a 2a 20 63 6f 64 65  te error.** code
1200: 20 6f 74 68 65 72 77 69 73 65 2e 0a 2a 2a 0a 2a   otherwise..**.*
1210: 2a 20 49 66 20 73 75 63 63 65 73 73 66 75 6c 2c  * If successful,
1220: 20 74 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 63   the number of c
1230: 6f 6c 75 6d 6e 73 20 69 73 20 77 72 69 74 74 65  olumns is writte
1240: 6e 20 74 6f 20 2a 70 6e 43 6f 6c 2e 20 2a 70 61  n to *pnCol. *pa
1250: 43 6f 6c 20 69 73 0a 2a 2a 20 73 65 74 20 74 6f  Col is.** set to
1260: 20 70 6f 69 6e 74 20 61 74 20 73 71 6c 69 74 65   point at sqlite
1270: 33 5f 6d 61 6c 6c 6f 63 28 29 27 64 20 73 70 61  3_malloc()'d spa
1280: 63 65 20 63 6f 6e 74 61 69 6e 69 6e 67 20 74 68  ce containing th
1290: 65 20 61 72 72 61 79 20 6f 66 0a 2a 2a 20 6e 43  e array of.** nC
12a0: 6f 6c 20 63 6f 6c 75 6d 6e 20 6e 61 6d 65 73 2e  ol column names.
12b0: 20 54 68 65 20 63 61 6c 6c 65 72 20 69 73 20 72   The caller is r
12c0: 65 73 70 6f 6e 73 69 62 6c 65 20 66 6f 72 20 63  esponsible for c
12d0: 61 6c 6c 69 6e 67 20 73 71 6c 69 74 65 33 5f 66  alling sqlite3_f
12e0: 72 65 65 0a 2a 2a 20 6f 6e 20 2a 70 61 43 6f 6c  ree.** on *paCol
12f0: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
1300: 67 65 74 43 6f 6c 75 6d 6e 4e 61 6d 65 73 28 0a  getColumnNames(.
1310: 20 20 73 71 6c 69 74 65 33 20 2a 64 62 2c 20 0a    sqlite3 *db, .
1320: 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 54    const char *zT
1330: 61 62 2c 0a 20 20 63 68 61 72 20 2a 2a 2a 70 61  ab,.  char ***pa
1340: 43 6f 6c 2c 20 0a 20 20 69 6e 74 20 2a 70 6e 43  Col, .  int *pnC
1350: 6f 6c 0a 29 7b 0a 20 20 63 68 61 72 20 2a 2a 61  ol.){.  char **a
1360: 43 6f 6c 20 3d 20 30 3b 0a 20 20 63 68 61 72 20  Col = 0;.  char 
1370: 2a 7a 53 71 6c 3b 0a 20 20 73 71 6c 69 74 65 33  *zSql;.  sqlite3
1380: 5f 73 74 6d 74 20 2a 70 53 74 6d 74 20 3d 20 30  _stmt *pStmt = 0
1390: 3b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c  ;.  int rc = SQL
13a0: 49 54 45 5f 4f 4b 3b 0a 20 20 69 6e 74 20 6e 43  ITE_OK;.  int nC
13b0: 6f 6c 20 3d 20 30 3b 0a 0a 20 20 2f 2a 20 50 72  ol = 0;..  /* Pr
13c0: 65 70 61 72 65 20 74 68 65 20 73 74 61 74 65 6d  epare the statem
13d0: 65 6e 74 20 22 53 45 4c 45 43 54 20 2a 20 46 52  ent "SELECT * FR
13e0: 4f 4d 20 3c 74 62 6c 3e 22 2e 20 54 68 65 20 63  OM <tbl>". The c
13f0: 6f 6c 75 6d 6e 20 6e 61 6d 65 73 0a 20 20 2a 2a  olumn names.  **
1400: 20 6f 66 20 74 68 65 20 72 65 73 75 6c 74 20 73   of the result s
1410: 65 74 20 6f 66 20 74 68 65 20 63 6f 6d 70 69 6c  et of the compil
1420: 65 64 20 53 45 4c 45 43 54 20 77 69 6c 6c 20 62  ed SELECT will b
1430: 65 20 74 68 65 20 73 61 6d 65 20 61 73 0a 20 20  e the same as.  
1440: 2a 2a 20 74 68 65 20 63 6f 6c 75 6d 6e 20 6e 61  ** the column na
1450: 6d 65 73 20 6f 66 20 74 61 62 6c 65 20 3c 74 62  mes of table <tb
1460: 6c 3e 2e 0a 20 20 2a 2f 0a 20 20 7a 53 71 6c 20  l>..  */.  zSql 
1470: 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74  = sqlite3_mprint
1480: 66 28 22 53 45 4c 45 43 54 20 2a 20 46 52 4f 4d  f("SELECT * FROM
1490: 20 25 51 22 2c 20 7a 54 61 62 29 3b 0a 20 20 69   %Q", zTab);.  i
14a0: 66 28 20 21 7a 53 71 6c 20 29 7b 0a 20 20 20 20  f( !zSql ){.    
14b0: 72 63 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45  rc = SQLITE_NOME
14c0: 4d 3b 0a 20 20 20 20 67 6f 74 6f 20 6f 75 74 3b  M;.    goto out;
14d0: 0a 20 20 7d 0a 20 20 72 63 20 3d 20 73 71 6c 69  .  }.  rc = sqli
14e0: 74 65 33 5f 70 72 65 70 61 72 65 28 64 62 2c 20  te3_prepare(db, 
14f0: 7a 53 71 6c 2c 20 2d 31 2c 20 26 70 53 74 6d 74  zSql, -1, &pStmt
1500: 2c 20 30 29 3b 0a 20 20 73 71 6c 69 74 65 33 5f  , 0);.  sqlite3_
1510: 66 72 65 65 28 7a 53 71 6c 29 3b 0a 0a 20 20 69  free(zSql);..  i
1520: 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc==SQLITE_OK
1530: 20 29 7b 0a 20 20 20 20 69 6e 74 20 69 69 3b 0a   ){.    int ii;.
1540: 20 20 20 20 69 6e 74 20 6e 42 79 74 65 73 3b 0a      int nBytes;.
1550: 20 20 20 20 63 68 61 72 20 2a 7a 53 70 61 63 65      char *zSpace
1560: 3b 0a 20 20 20 20 6e 43 6f 6c 20 3d 20 73 71 6c  ;.    nCol = sql
1570: 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 63 6f 75 6e  ite3_column_coun
1580: 74 28 70 53 74 6d 74 29 3b 0a 0a 20 20 20 20 2f  t(pStmt);..    /
1590: 2a 20 46 69 67 75 72 65 20 6f 75 74 20 68 6f 77  * Figure out how
15a0: 20 6d 75 63 68 20 73 70 61 63 65 20 74 6f 20 61   much space to a
15b0: 6c 6c 6f 63 61 74 65 20 66 6f 72 20 74 68 65 20  llocate for the 
15c0: 61 72 72 61 79 20 6f 66 20 63 6f 6c 75 6d 6e 20  array of column 
15d0: 6e 61 6d 65 73 20 0a 20 20 20 20 2a 2a 20 28 69  names .    ** (i
15e0: 6e 63 6c 75 64 69 6e 67 20 73 70 61 63 65 20 66  ncluding space f
15f0: 6f 72 20 74 68 65 20 73 74 72 69 6e 67 73 20 74  or the strings t
1600: 68 65 6d 73 65 6c 76 65 73 29 2e 20 54 68 65 6e  hemselves). Then
1610: 20 61 6c 6c 6f 63 61 74 65 20 69 74 2e 0a 20 20   allocate it..  
1620: 20 20 2a 2f 0a 20 20 20 20 6e 42 79 74 65 73 20    */.    nBytes 
1630: 3d 20 73 69 7a 65 6f 66 28 63 68 61 72 20 2a 29  = sizeof(char *)
1640: 20 2a 20 6e 43 6f 6c 3b 0a 20 20 20 20 66 6f 72   * nCol;.    for
1650: 28 69 69 3d 30 3b 20 69 69 3c 6e 43 6f 6c 3b 20  (ii=0; ii<nCol; 
1660: 69 69 2b 2b 29 7b 0a 20 20 20 20 20 20 63 6f 6e  ii++){.      con
1670: 73 74 20 63 68 61 72 20 2a 7a 4e 61 6d 65 20 3d  st char *zName =
1680: 20 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f   sqlite3_column_
1690: 6e 61 6d 65 28 70 53 74 6d 74 2c 20 69 69 29 3b  name(pStmt, ii);
16a0: 0a 20 20 20 20 20 20 69 66 28 20 21 7a 4e 61 6d  .      if( !zNam
16b0: 65 20 29 7b 0a 20 20 20 20 20 20 20 20 72 63 20  e ){.        rc 
16c0: 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a  = SQLITE_NOMEM;.
16d0: 20 20 20 20 20 20 20 20 67 6f 74 6f 20 6f 75 74          goto out
16e0: 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20  ;.      }.      
16f0: 6e 42 79 74 65 73 20 2b 3d 20 28 69 6e 74 29 73  nBytes += (int)s
1700: 74 72 6c 65 6e 28 7a 4e 61 6d 65 29 2b 31 3b 0a  trlen(zName)+1;.
1710: 20 20 20 20 7d 0a 20 20 20 20 61 43 6f 6c 20 3d      }.    aCol =
1720: 20 28 63 68 61 72 20 2a 2a 29 73 71 6c 69 74 65   (char **)sqlite
1730: 33 4d 61 6c 6c 6f 63 5a 65 72 6f 28 6e 42 79 74  3MallocZero(nByt
1740: 65 73 29 3b 0a 20 20 20 20 69 66 28 20 21 61 43  es);.    if( !aC
1750: 6f 6c 20 29 7b 0a 20 20 20 20 20 20 72 63 20 3d  ol ){.      rc =
1760: 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20   SQLITE_NOMEM;. 
1770: 20 20 20 20 20 67 6f 74 6f 20 6f 75 74 3b 0a 20       goto out;. 
1780: 20 20 20 7d 0a 0a 20 20 20 20 2f 2a 20 43 6f 70     }..    /* Cop
1790: 79 20 74 68 65 20 63 6f 6c 75 6d 6e 20 6e 61 6d  y the column nam
17a0: 65 73 20 69 6e 74 6f 20 74 68 65 20 61 6c 6c 6f  es into the allo
17b0: 63 61 74 65 64 20 73 70 61 63 65 20 61 6e 64 20  cated space and 
17c0: 73 65 74 20 75 70 20 74 68 65 0a 20 20 20 20 2a  set up the.    *
17d0: 2a 20 70 6f 69 6e 74 65 72 73 20 69 6e 20 74 68  * pointers in th
17e0: 65 20 61 43 6f 6c 5b 5d 20 61 72 72 61 79 2e 0a  e aCol[] array..
17f0: 20 20 20 20 2a 2f 0a 20 20 20 20 7a 53 70 61 63      */.    zSpac
1800: 65 20 3d 20 28 63 68 61 72 20 2a 29 28 26 61 43  e = (char *)(&aC
1810: 6f 6c 5b 6e 43 6f 6c 5d 29 3b 0a 20 20 20 20 66  ol[nCol]);.    f
1820: 6f 72 28 69 69 3d 30 3b 20 69 69 3c 6e 43 6f 6c  or(ii=0; ii<nCol
1830: 3b 20 69 69 2b 2b 29 7b 0a 20 20 20 20 20 20 61  ; ii++){.      a
1840: 43 6f 6c 5b 69 69 5d 20 3d 20 7a 53 70 61 63 65  Col[ii] = zSpace
1850: 3b 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f  ;.      sqlite3_
1860: 73 6e 70 72 69 6e 74 66 28 6e 42 79 74 65 73 2c  snprintf(nBytes,
1870: 20 7a 53 70 61 63 65 2c 20 22 25 73 22 2c 20 73   zSpace, "%s", s
1880: 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 6e 61  qlite3_column_na
1890: 6d 65 28 70 53 74 6d 74 2c 69 69 29 29 3b 0a 20  me(pStmt,ii));. 
18a0: 20 20 20 20 20 7a 53 70 61 63 65 20 2b 3d 20 28       zSpace += (
18b0: 69 6e 74 29 73 74 72 6c 65 6e 28 7a 53 70 61 63  int)strlen(zSpac
18c0: 65 29 20 2b 20 31 3b 0a 20 20 20 20 7d 0a 20 20  e) + 1;.    }.  
18d0: 20 20 61 73 73 65 72 74 28 20 28 7a 53 70 61 63    assert( (zSpac
18e0: 65 2d 6e 42 79 74 65 73 29 3d 3d 28 63 68 61 72  e-nBytes)==(char
18f0: 20 2a 29 61 43 6f 6c 20 29 3b 0a 20 20 7d 0a 0a   *)aCol );.  }..
1900: 20 20 2a 70 61 43 6f 6c 20 3d 20 61 43 6f 6c 3b    *paCol = aCol;
1910: 0a 20 20 2a 70 6e 43 6f 6c 20 3d 20 6e 43 6f 6c  .  *pnCol = nCol
1920: 3b 0a 0a 6f 75 74 3a 0a 20 20 73 71 6c 69 74 65  ;..out:.  sqlite
1930: 33 5f 66 69 6e 61 6c 69 7a 65 28 70 53 74 6d 74  3_finalize(pStmt
1940: 29 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a  );.  return rc;.
1950: 7d 0a 0a 2f 2a 0a 2a 2a 20 50 61 72 61 6d 65 74  }../*.** Paramet
1960: 65 72 20 7a 54 61 62 20 69 73 20 74 68 65 20 6e  er zTab is the n
1970: 61 6d 65 20 6f 66 20 61 20 74 61 62 6c 65 20 69  ame of a table i
1980: 6e 20 64 61 74 61 62 61 73 65 20 64 62 20 77 69  n database db wi
1990: 74 68 20 6e 43 6f 6c 20 0a 2a 2a 20 63 6f 6c 75  th nCol .** colu
19a0: 6d 6e 73 2e 20 54 68 69 73 20 66 75 6e 63 74 69  mns. This functi
19b0: 6f 6e 20 61 6c 6c 6f 63 61 74 65 73 20 61 6e 20  on allocates an 
19c0: 61 72 72 61 79 20 6f 66 20 69 6e 74 65 67 65 72  array of integer
19d0: 73 20 6e 43 6f 6c 20 69 6e 20 0a 2a 2a 20 73 69  s nCol in .** si
19e0: 7a 65 20 61 6e 64 20 70 6f 70 75 6c 61 74 65 73  ze and populates
19f0: 20 69 74 20 61 63 63 6f 72 64 69 6e 67 20 74 6f   it according to
1a00: 20 61 6e 79 20 69 6d 70 6c 69 63 69 74 20 6f 72   any implicit or
1a10: 20 65 78 70 6c 69 63 69 74 20 0a 2a 2a 20 69 6e   explicit .** in
1a20: 64 69 63 65 73 20 6f 6e 20 74 61 62 6c 65 20 7a  dices on table z
1a30: 54 61 62 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 73 75  Tab..**.** If su
1a40: 63 63 65 73 73 66 75 6c 2c 20 53 51 4c 49 54 45  ccessful, SQLITE
1a50: 5f 4f 4b 20 69 73 20 72 65 74 75 72 6e 65 64 20  _OK is returned 
1a60: 61 6e 64 20 2a 70 61 49 6e 64 65 78 20 73 65 74  and *paIndex set
1a70: 20 74 6f 20 70 6f 69 6e 74 20 0a 2a 2a 20 61 74   to point .** at
1a80: 20 74 68 65 20 61 6c 6c 6f 63 61 74 65 64 20 61   the allocated a
1a90: 72 72 61 79 2e 20 4f 74 68 65 72 77 69 73 65 2c  rray. Otherwise,
1aa0: 20 61 6e 20 65 72 72 6f 72 20 63 6f 64 65 20 69   an error code i
1ab0: 73 20 72 65 74 75 72 6e 65 64 2e 0a 2a 2a 0a 2a  s returned..**.*
1ac0: 2a 20 53 65 65 20 63 6f 6d 6d 65 6e 74 73 20 61  * See comments a
1ad0: 73 73 6f 63 69 61 74 65 64 20 77 69 74 68 20 74  ssociated with t
1ae0: 68 65 20 6d 65 6d 62 65 72 20 76 61 72 69 61 62  he member variab
1af0: 6c 65 20 61 49 6e 64 65 78 20 61 62 6f 76 65 20  le aIndex above 
1b00: 0a 2a 2a 20 22 73 74 72 75 63 74 20 65 63 68 6f  .** "struct echo
1b10: 5f 76 74 61 62 22 20 66 6f 72 20 64 65 74 61 69  _vtab" for detai
1b20: 6c 73 20 6f 66 20 74 68 65 20 63 6f 6e 74 65 6e  ls of the conten
1b30: 74 73 20 6f 66 20 74 68 65 20 61 72 72 61 79 2e  ts of the array.
1b40: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 67  .*/.static int g
1b50: 65 74 49 6e 64 65 78 41 72 72 61 79 28 0a 20 20  etIndexArray(.  
1b60: 73 71 6c 69 74 65 33 20 2a 64 62 2c 20 20 20 20  sqlite3 *db,    
1b70: 20 20 20 20 20 20 20 20 20 2f 2a 20 44 61 74 61           /* Data
1b80: 62 61 73 65 20 63 6f 6e 6e 65 63 74 69 6f 6e 20  base connection 
1b90: 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20  */.  const char 
1ba0: 2a 7a 54 61 62 2c 20 20 20 20 20 20 20 20 2f 2a  *zTab,        /*
1bb0: 20 4e 61 6d 65 20 6f 66 20 74 61 62 6c 65 20 69   Name of table i
1bc0: 6e 20 64 61 74 61 62 61 73 65 20 64 62 20 2a 2f  n database db */
1bd0: 0a 20 20 69 6e 74 20 6e 43 6f 6c 2c 0a 20 20 69  .  int nCol,.  i
1be0: 6e 74 20 2a 2a 70 61 49 6e 64 65 78 0a 29 7b 0a  nt **paIndex.){.
1bf0: 20 20 73 71 6c 69 74 65 33 5f 73 74 6d 74 20 2a    sqlite3_stmt *
1c00: 70 53 74 6d 74 20 3d 20 30 3b 0a 20 20 69 6e 74  pStmt = 0;.  int
1c10: 20 2a 61 49 6e 64 65 78 20 3d 20 30 3b 0a 20 20   *aIndex = 0;.  
1c20: 69 6e 74 20 72 63 3b 0a 20 20 63 68 61 72 20 2a  int rc;.  char *
1c30: 7a 53 71 6c 3b 0a 0a 20 20 2f 2a 20 41 6c 6c 6f  zSql;..  /* Allo
1c40: 63 61 74 65 20 73 70 61 63 65 20 66 6f 72 20 74  cate space for t
1c50: 68 65 20 69 6e 64 65 78 20 61 72 72 61 79 20 2a  he index array *
1c60: 2f 0a 20 20 61 49 6e 64 65 78 20 3d 20 28 69 6e  /.  aIndex = (in
1c70: 74 20 2a 29 73 71 6c 69 74 65 33 4d 61 6c 6c 6f  t *)sqlite3Mallo
1c80: 63 5a 65 72 6f 28 73 69 7a 65 6f 66 28 69 6e 74  cZero(sizeof(int
1c90: 29 20 2a 20 6e 43 6f 6c 29 3b 0a 20 20 69 66 28  ) * nCol);.  if(
1ca0: 20 21 61 49 6e 64 65 78 20 29 7b 0a 20 20 20 20   !aIndex ){.    
1cb0: 72 63 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45  rc = SQLITE_NOME
1cc0: 4d 3b 0a 20 20 20 20 67 6f 74 6f 20 67 65 74 5f  M;.    goto get_
1cd0: 69 6e 64 65 78 5f 61 72 72 61 79 5f 6f 75 74 3b  index_array_out;
1ce0: 0a 20 20 7d 0a 0a 20 20 2f 2a 20 43 6f 6d 70 69  .  }..  /* Compi
1cf0: 6c 65 20 61 6e 20 73 71 6c 69 74 65 20 70 72 61  le an sqlite pra
1d00: 67 6d 61 20 74 6f 20 6c 6f 6f 70 20 74 68 72 6f  gma to loop thro
1d10: 75 67 68 20 61 6c 6c 20 69 6e 64 69 63 65 73 20  ugh all indices 
1d20: 6f 6e 20 74 61 62 6c 65 20 7a 54 61 62 20 2a 2f  on table zTab */
1d30: 0a 20 20 7a 53 71 6c 20 3d 20 73 71 6c 69 74 65  .  zSql = sqlite
1d40: 33 5f 6d 70 72 69 6e 74 66 28 22 50 52 41 47 4d  3_mprintf("PRAGM
1d50: 41 20 69 6e 64 65 78 5f 6c 69 73 74 28 25 73 29  A index_list(%s)
1d60: 22 2c 20 7a 54 61 62 29 3b 0a 20 20 69 66 28 20  ", zTab);.  if( 
1d70: 21 7a 53 71 6c 20 29 7b 0a 20 20 20 20 72 63 20  !zSql ){.    rc 
1d80: 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a  = SQLITE_NOMEM;.
1d90: 20 20 20 20 67 6f 74 6f 20 67 65 74 5f 69 6e 64      goto get_ind
1da0: 65 78 5f 61 72 72 61 79 5f 6f 75 74 3b 0a 20 20  ex_array_out;.  
1db0: 7d 0a 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33  }.  rc = sqlite3
1dc0: 5f 70 72 65 70 61 72 65 28 64 62 2c 20 7a 53 71  _prepare(db, zSq
1dd0: 6c 2c 20 2d 31 2c 20 26 70 53 74 6d 74 2c 20 30  l, -1, &pStmt, 0
1de0: 29 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66 72 65  );.  sqlite3_fre
1df0: 65 28 7a 53 71 6c 29 3b 0a 0a 20 20 2f 2a 20 46  e(zSql);..  /* F
1e00: 6f 72 20 65 61 63 68 20 69 6e 64 65 78 2c 20 66  or each index, f
1e10: 69 67 75 72 65 20 6f 75 74 20 74 68 65 20 6c 65  igure out the le
1e20: 66 74 2d 6d 6f 73 74 20 63 6f 6c 75 6d 6e 20 61  ft-most column a
1e30: 6e 64 20 73 65 74 20 74 68 65 20 0a 20 20 2a 2a  nd set the .  **
1e40: 20 63 6f 72 72 65 73 70 6f 6e 64 69 6e 67 20 65   corresponding e
1e50: 6e 74 72 79 20 69 6e 20 61 49 6e 64 65 78 5b 5d  ntry in aIndex[]
1e60: 20 74 6f 20 31 2e 0a 20 20 2a 2f 0a 20 20 77 68   to 1..  */.  wh
1e70: 69 6c 65 28 20 70 53 74 6d 74 20 26 26 20 73 71  ile( pStmt && sq
1e80: 6c 69 74 65 33 5f 73 74 65 70 28 70 53 74 6d 74  lite3_step(pStmt
1e90: 29 3d 3d 53 51 4c 49 54 45 5f 52 4f 57 20 29 7b  )==SQLITE_ROW ){
1ea0: 0a 20 20 20 20 63 6f 6e 73 74 20 63 68 61 72 20  .    const char 
1eb0: 2a 7a 49 64 78 20 3d 20 28 63 6f 6e 73 74 20 63  *zIdx = (const c
1ec0: 68 61 72 20 2a 29 73 71 6c 69 74 65 33 5f 63 6f  har *)sqlite3_co
1ed0: 6c 75 6d 6e 5f 74 65 78 74 28 70 53 74 6d 74 2c  lumn_text(pStmt,
1ee0: 20 31 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33   1);.    sqlite3
1ef0: 5f 73 74 6d 74 20 2a 70 53 74 6d 74 32 20 3d 20  _stmt *pStmt2 = 
1f00: 30 3b 0a 20 20 20 20 69 66 28 20 7a 49 64 78 3d  0;.    if( zIdx=
1f10: 3d 30 20 29 20 63 6f 6e 74 69 6e 75 65 3b 0a 20  =0 ) continue;. 
1f20: 20 20 20 7a 53 71 6c 20 3d 20 73 71 6c 69 74 65     zSql = sqlite
1f30: 33 5f 6d 70 72 69 6e 74 66 28 22 50 52 41 47 4d  3_mprintf("PRAGM
1f40: 41 20 69 6e 64 65 78 5f 69 6e 66 6f 28 25 73 29  A index_info(%s)
1f50: 22 2c 20 7a 49 64 78 29 3b 0a 20 20 20 20 69 66  ", zIdx);.    if
1f60: 28 20 21 7a 53 71 6c 20 29 7b 0a 20 20 20 20 20  ( !zSql ){.     
1f70: 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d   rc = SQLITE_NOM
1f80: 45 4d 3b 0a 20 20 20 20 20 20 67 6f 74 6f 20 67  EM;.      goto g
1f90: 65 74 5f 69 6e 64 65 78 5f 61 72 72 61 79 5f 6f  et_index_array_o
1fa0: 75 74 3b 0a 20 20 20 20 7d 0a 20 20 20 20 72 63  ut;.    }.    rc
1fb0: 20 3d 20 73 71 6c 69 74 65 33 5f 70 72 65 70 61   = sqlite3_prepa
1fc0: 72 65 28 64 62 2c 20 7a 53 71 6c 2c 20 2d 31 2c  re(db, zSql, -1,
1fd0: 20 26 70 53 74 6d 74 32 2c 20 30 29 3b 0a 20 20   &pStmt2, 0);.  
1fe0: 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 7a    sqlite3_free(z
1ff0: 53 71 6c 29 3b 0a 20 20 20 20 69 66 28 20 70 53  Sql);.    if( pS
2000: 74 6d 74 32 20 26 26 20 73 71 6c 69 74 65 33 5f  tmt2 && sqlite3_
2010: 73 74 65 70 28 70 53 74 6d 74 32 29 3d 3d 53 51  step(pStmt2)==SQ
2020: 4c 49 54 45 5f 52 4f 57 20 29 7b 0a 20 20 20 20  LITE_ROW ){.    
2030: 20 20 69 6e 74 20 63 69 64 20 3d 20 73 71 6c 69    int cid = sqli
2040: 74 65 33 5f 63 6f 6c 75 6d 6e 5f 69 6e 74 28 70  te3_column_int(p
2050: 53 74 6d 74 32 2c 20 31 29 3b 0a 20 20 20 20 20  Stmt2, 1);.     
2060: 20 61 73 73 65 72 74 28 20 63 69 64 3e 3d 30 20   assert( cid>=0 
2070: 26 26 20 63 69 64 3c 6e 43 6f 6c 20 29 3b 0a 20  && cid<nCol );. 
2080: 20 20 20 20 20 61 49 6e 64 65 78 5b 63 69 64 5d       aIndex[cid]
2090: 20 3d 20 31 3b 0a 20 20 20 20 7d 0a 20 20 20 20   = 1;.    }.    
20a0: 69 66 28 20 70 53 74 6d 74 32 20 29 7b 0a 20 20  if( pStmt2 ){.  
20b0: 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33      rc = sqlite3
20c0: 5f 66 69 6e 61 6c 69 7a 65 28 70 53 74 6d 74 32  _finalize(pStmt2
20d0: 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 28  );.    }.    if(
20e0: 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc!=SQLITE_OK )
20f0: 7b 0a 20 20 20 20 20 20 67 6f 74 6f 20 67 65 74  {.      goto get
2100: 5f 69 6e 64 65 78 5f 61 72 72 61 79 5f 6f 75 74  _index_array_out
2110: 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 0a 67 65  ;.    }.  }...ge
2120: 74 5f 69 6e 64 65 78 5f 61 72 72 61 79 5f 6f 75  t_index_array_ou
2130: 74 3a 0a 20 20 69 66 28 20 70 53 74 6d 74 20 29  t:.  if( pStmt )
2140: 7b 0a 20 20 20 20 69 6e 74 20 72 63 32 20 3d 20  {.    int rc2 = 
2150: 73 71 6c 69 74 65 33 5f 66 69 6e 61 6c 69 7a 65  sqlite3_finalize
2160: 28 70 53 74 6d 74 29 3b 0a 20 20 20 20 69 66 28  (pStmt);.    if(
2170: 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc==SQLITE_OK )
2180: 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 72 63 32  {.      rc = rc2
2190: 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 69 66  ;.    }.  }.  if
21a0: 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc!=SQLITE_OK 
21b0: 29 7b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 66  ){.    sqlite3_f
21c0: 72 65 65 28 61 49 6e 64 65 78 29 3b 0a 20 20 20  ree(aIndex);.   
21d0: 20 61 49 6e 64 65 78 20 3d 20 30 3b 0a 20 20 7d   aIndex = 0;.  }
21e0: 0a 20 20 2a 70 61 49 6e 64 65 78 20 3d 20 61 49  .  *paIndex = aI
21f0: 6e 64 65 78 3b 0a 20 20 72 65 74 75 72 6e 20 72  ndex;.  return r
2200: 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 47 6c 6f 62  c;.}../*.** Glob
2210: 61 6c 20 54 63 6c 20 76 61 72 69 61 62 6c 65 20  al Tcl variable 
2220: 24 65 63 68 6f 5f 6d 6f 64 75 6c 65 20 69 73 20  $echo_module is 
2230: 61 20 6c 69 73 74 2e 20 54 68 69 73 20 72 6f 75  a list. This rou
2240: 74 69 6e 65 20 61 70 70 65 6e 64 73 0a 2a 2a 20  tine appends.** 
2250: 74 68 65 20 73 74 72 69 6e 67 20 65 6c 65 6d 65  the string eleme
2260: 6e 74 20 7a 41 72 67 20 74 6f 20 74 68 61 74 20  nt zArg to that 
2270: 6c 69 73 74 20 69 6e 20 69 6e 74 65 72 70 72 65  list in interpre
2280: 74 65 72 20 69 6e 74 65 72 70 2e 0a 2a 2f 0a 73  ter interp..*/.s
2290: 74 61 74 69 63 20 76 6f 69 64 20 61 70 70 65 6e  tatic void appen
22a0: 64 54 6f 45 63 68 6f 4d 6f 64 75 6c 65 28 54 63  dToEchoModule(Tc
22b0: 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70  l_Interp *interp
22c0: 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 41  , const char *zA
22d0: 72 67 29 7b 0a 20 20 69 6e 74 20 66 6c 61 67 73  rg){.  int flags
22e0: 20 3d 20 28 54 43 4c 5f 41 50 50 45 4e 44 5f 56   = (TCL_APPEND_V
22f0: 41 4c 55 45 20 7c 20 54 43 4c 5f 4c 49 53 54 5f  ALUE | TCL_LIST_
2300: 45 4c 45 4d 45 4e 54 20 7c 20 54 43 4c 5f 47 4c  ELEMENT | TCL_GL
2310: 4f 42 41 4c 5f 4f 4e 4c 59 29 3b 0a 20 20 54 63  OBAL_ONLY);.  Tc
2320: 6c 5f 53 65 74 56 61 72 28 69 6e 74 65 72 70 2c  l_SetVar(interp,
2330: 20 22 65 63 68 6f 5f 6d 6f 64 75 6c 65 22 2c 20   "echo_module", 
2340: 28 7a 41 72 67 3f 7a 41 72 67 3a 22 22 29 2c 20  (zArg?zArg:""), 
2350: 66 6c 61 67 73 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  flags);.}../*.**
2360: 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 69   This function i
2370: 73 20 63 61 6c 6c 65 64 20 66 72 6f 6d 20 77 69  s called from wi
2380: 74 68 69 6e 20 74 68 65 20 65 63 68 6f 2d 6d 6f  thin the echo-mo
2390: 64 75 6c 65 73 20 78 43 72 65 61 74 65 20 61 6e  dules xCreate an
23a0: 64 0a 2a 2a 20 78 43 6f 6e 6e 65 63 74 20 6d 65  d.** xConnect me
23b0: 74 68 6f 64 73 2e 20 54 68 65 20 61 72 67 63 20  thods. The argc 
23c0: 61 6e 64 20 61 72 67 76 20 61 72 67 75 6d 65 6e  and argv argumen
23d0: 74 73 20 61 72 65 20 63 6f 70 69 65 73 20 6f 66  ts are copies of
23e0: 20 74 68 6f 73 65 20 0a 2a 2a 20 70 61 73 73 65   those .** passe
23f0: 64 20 74 6f 20 74 68 65 20 63 61 6c 6c 69 6e 67  d to the calling
2400: 20 6d 65 74 68 6f 64 2e 20 54 68 69 73 20 66 75   method. This fu
2410: 6e 63 74 69 6f 6e 20 69 73 20 72 65 73 70 6f 6e  nction is respon
2420: 73 69 62 6c 65 20 66 6f 72 0a 2a 2a 20 63 61 6c  sible for.** cal
2430: 6c 69 6e 67 20 73 71 6c 69 74 65 33 5f 64 65 63  ling sqlite3_dec
2440: 6c 61 72 65 5f 76 74 61 62 28 29 20 74 6f 20 64  lare_vtab() to d
2450: 65 63 6c 61 72 65 20 74 68 65 20 73 63 68 65 6d  eclare the schem
2460: 61 20 6f 66 20 74 68 65 20 76 69 72 74 75 61 6c  a of the virtual
2470: 0a 2a 2a 20 74 61 62 6c 65 20 62 65 69 6e 67 20  .** table being 
2480: 63 72 65 61 74 65 64 20 6f 72 20 63 6f 6e 6e 65  created or conne
2490: 63 74 65 64 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 74  cted..**.** If t
24a0: 68 65 20 63 6f 6e 73 74 72 75 63 74 6f 72 20 77  he constructor w
24b0: 61 73 20 70 61 73 73 65 64 20 6a 75 73 74 20 6f  as passed just o
24c0: 6e 65 20 61 72 67 75 6d 65 6e 74 2c 20 69 2e 65  ne argument, i.e
24d0: 2e 3a 0a 2a 2a 0a 2a 2a 20 20 20 43 52 45 41 54  .:.**.**   CREAT
24e0: 45 20 54 41 42 4c 45 20 74 31 20 41 53 20 65 63  E TABLE t1 AS ec
24f0: 68 6f 28 74 32 29 3b 0a 2a 2a 0a 2a 2a 20 54 68  ho(t2);.**.** Th
2500: 65 6e 20 74 32 20 69 73 20 61 73 73 75 6d 65 64  en t2 is assumed
2510: 20 74 6f 20 62 65 20 74 68 65 20 6e 61 6d 65 20   to be the name 
2520: 6f 66 20 61 20 2a 72 65 61 6c 2a 20 64 61 74 61  of a *real* data
2530: 62 61 73 65 20 74 61 62 6c 65 2e 20 54 68 65 0a  base table. The.
2540: 2a 2a 20 73 63 68 65 6d 61 20 6f 66 20 74 68 65  ** schema of the
2550: 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65 20 69   virtual table i
2560: 73 20 64 65 63 6c 61 72 65 64 20 62 79 20 70 61  s declared by pa
2570: 73 73 69 6e 67 20 61 20 63 6f 70 79 20 6f 66 20  ssing a copy of 
2580: 74 68 65 20 0a 2a 2a 20 43 52 45 41 54 45 20 54  the .** CREATE T
2590: 41 42 4c 45 20 73 74 61 74 65 6d 65 6e 74 20 66  ABLE statement f
25a0: 6f 72 20 74 68 65 20 72 65 61 6c 20 74 61 62 6c  or the real tabl
25b0: 65 20 74 6f 20 73 71 6c 69 74 65 33 5f 64 65 63  e to sqlite3_dec
25c0: 6c 61 72 65 5f 76 74 61 62 28 29 2e 0a 2a 2a 20  lare_vtab()..** 
25d0: 48 65 6e 63 65 2c 20 74 68 65 20 76 69 72 74 75  Hence, the virtu
25e0: 61 6c 20 74 61 62 6c 65 20 73 68 6f 75 6c 64 20  al table should 
25f0: 68 61 76 65 20 65 78 61 63 74 6c 79 20 74 68 65  have exactly the
2600: 20 73 61 6d 65 20 63 6f 6c 75 6d 6e 20 6e 61 6d   same column nam
2610: 65 73 20 61 6e 64 20 0a 2a 2a 20 74 79 70 65 73  es and .** types
2620: 20 61 73 20 74 68 65 20 72 65 61 6c 20 74 61 62   as the real tab
2630: 6c 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  le..*/.static in
2640: 74 20 65 63 68 6f 44 65 63 6c 61 72 65 56 74 61  t echoDeclareVta
2650: 62 28 0a 20 20 65 63 68 6f 5f 76 74 61 62 20 2a  b(.  echo_vtab *
2660: 70 56 74 61 62 2c 20 0a 20 20 73 71 6c 69 74 65  pVtab, .  sqlite
2670: 33 20 2a 64 62 20 0a 29 7b 0a 20 20 69 6e 74 20  3 *db .){.  int 
2680: 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a  rc = SQLITE_OK;.
2690: 0a 20 20 69 66 28 20 70 56 74 61 62 2d 3e 7a 54  .  if( pVtab->zT
26a0: 61 62 6c 65 4e 61 6d 65 20 29 7b 0a 20 20 20 20  ableName ){.    
26b0: 73 71 6c 69 74 65 33 5f 73 74 6d 74 20 2a 70 53  sqlite3_stmt *pS
26c0: 74 6d 74 20 3d 20 30 3b 0a 20 20 20 20 72 63 20  tmt = 0;.    rc 
26d0: 3d 20 73 71 6c 69 74 65 33 5f 70 72 65 70 61 72  = sqlite3_prepar
26e0: 65 28 64 62 2c 20 0a 20 20 20 20 20 20 20 20 22  e(db, .        "
26f0: 53 45 4c 45 43 54 20 73 71 6c 20 46 52 4f 4d 20  SELECT sql FROM 
2700: 73 71 6c 69 74 65 5f 6d 61 73 74 65 72 20 57 48  sqlite_master WH
2710: 45 52 45 20 74 79 70 65 20 3d 20 27 74 61 62 6c  ERE type = 'tabl
2720: 65 27 20 41 4e 44 20 6e 61 6d 65 20 3d 20 3f 22  e' AND name = ?"
2730: 2c 0a 20 20 20 20 20 20 20 20 2d 31 2c 20 26 70  ,.        -1, &p
2740: 53 74 6d 74 2c 20 30 29 3b 0a 20 20 20 20 69 66  Stmt, 0);.    if
2750: 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
2760: 29 7b 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33  ){.      sqlite3
2770: 5f 62 69 6e 64 5f 74 65 78 74 28 70 53 74 6d 74  _bind_text(pStmt
2780: 2c 20 31 2c 20 70 56 74 61 62 2d 3e 7a 54 61 62  , 1, pVtab->zTab
2790: 6c 65 4e 61 6d 65 2c 20 2d 31 2c 20 30 29 3b 0a  leName, -1, 0);.
27a0: 20 20 20 20 20 20 69 66 28 20 73 71 6c 69 74 65        if( sqlite
27b0: 33 5f 73 74 65 70 28 70 53 74 6d 74 29 3d 3d 53  3_step(pStmt)==S
27c0: 51 4c 49 54 45 5f 52 4f 57 20 29 7b 0a 20 20 20  QLITE_ROW ){.   
27d0: 20 20 20 20 20 69 6e 74 20 72 63 32 3b 0a 20 20       int rc2;.  
27e0: 20 20 20 20 20 20 63 6f 6e 73 74 20 63 68 61 72        const char
27f0: 20 2a 7a 43 72 65 61 74 65 54 61 62 6c 65 20 3d   *zCreateTable =
2800: 20 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 29 73   (const char *)s
2810: 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 74 65  qlite3_column_te
2820: 78 74 28 70 53 74 6d 74 2c 20 30 29 3b 0a 20 20  xt(pStmt, 0);.  
2830: 20 20 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74        rc = sqlit
2840: 65 33 5f 64 65 63 6c 61 72 65 5f 76 74 61 62 28  e3_declare_vtab(
2850: 64 62 2c 20 7a 43 72 65 61 74 65 54 61 62 6c 65  db, zCreateTable
2860: 29 3b 0a 20 20 20 20 20 20 20 20 72 63 32 20 3d  );.        rc2 =
2870: 20 73 71 6c 69 74 65 33 5f 66 69 6e 61 6c 69 7a   sqlite3_finaliz
2880: 65 28 70 53 74 6d 74 29 3b 0a 20 20 20 20 20 20  e(pStmt);.      
2890: 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
28a0: 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20 20 20  _OK ){.         
28b0: 20 72 63 20 3d 20 72 63 32 3b 0a 20 20 20 20 20   rc = rc2;.     
28c0: 20 20 20 7d 0a 20 20 20 20 20 20 7d 20 65 6c 73     }.      } els
28d0: 65 20 7b 0a 20 20 20 20 20 20 20 20 72 63 20 3d  e {.        rc =
28e0: 20 73 71 6c 69 74 65 33 5f 66 69 6e 61 6c 69 7a   sqlite3_finaliz
28f0: 65 28 70 53 74 6d 74 29 3b 0a 20 20 20 20 20 20  e(pStmt);.      
2900: 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
2910: 5f 4f 4b 20 29 7b 20 0a 20 20 20 20 20 20 20 20  _OK ){ .        
2920: 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 45 52    rc = SQLITE_ER
2930: 52 4f 52 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20  ROR;.        }. 
2940: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 69 66 28       }.      if(
2950: 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc==SQLITE_OK )
2960: 7b 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20 67  {.        rc = g
2970: 65 74 43 6f 6c 75 6d 6e 4e 61 6d 65 73 28 64 62  etColumnNames(db
2980: 2c 20 70 56 74 61 62 2d 3e 7a 54 61 62 6c 65 4e  , pVtab->zTableN
2990: 61 6d 65 2c 20 26 70 56 74 61 62 2d 3e 61 43 6f  ame, &pVtab->aCo
29a0: 6c 2c 20 26 70 56 74 61 62 2d 3e 6e 43 6f 6c 29  l, &pVtab->nCol)
29b0: 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20  ;.      }.      
29c0: 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  if( rc==SQLITE_O
29d0: 4b 20 29 7b 0a 20 20 20 20 20 20 20 20 72 63 20  K ){.        rc 
29e0: 3d 20 67 65 74 49 6e 64 65 78 41 72 72 61 79 28  = getIndexArray(
29f0: 64 62 2c 20 70 56 74 61 62 2d 3e 7a 54 61 62 6c  db, pVtab->zTabl
2a00: 65 4e 61 6d 65 2c 20 70 56 74 61 62 2d 3e 6e 43  eName, pVtab->nC
2a10: 6f 6c 2c 20 26 70 56 74 61 62 2d 3e 61 49 6e 64  ol, &pVtab->aInd
2a20: 65 78 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20  ex);.      }.   
2a30: 20 7d 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e   }.  }..  return
2a40: 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68   rc;.}../*.** Th
2a50: 69 73 20 66 75 6e 63 74 69 6f 6e 20 66 72 65 65  is function free
2a60: 73 20 61 6c 6c 20 72 75 6e 74 69 6d 65 20 73 74  s all runtime st
2a70: 72 75 63 74 75 72 65 73 20 61 73 73 6f 63 69 61  ructures associa
2a80: 74 65 64 20 77 69 74 68 20 74 68 65 20 76 69 72  ted with the vir
2a90: 74 75 61 6c 0a 2a 2a 20 74 61 62 6c 65 20 70 56  tual.** table pV
2aa0: 74 61 62 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  tab..*/.static i
2ab0: 6e 74 20 65 63 68 6f 44 65 73 74 72 75 63 74 6f  nt echoDestructo
2ac0: 72 28 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a  r(sqlite3_vtab *
2ad0: 70 56 74 61 62 29 7b 0a 20 20 65 63 68 6f 5f 76  pVtab){.  echo_v
2ae0: 74 61 62 20 2a 70 20 3d 20 28 65 63 68 6f 5f 76  tab *p = (echo_v
2af0: 74 61 62 2a 29 70 56 74 61 62 3b 0a 20 20 73 71  tab*)pVtab;.  sq
2b00: 6c 69 74 65 33 5f 66 72 65 65 28 70 2d 3e 61 49  lite3_free(p->aI
2b10: 6e 64 65 78 29 3b 0a 20 20 73 71 6c 69 74 65 33  ndex);.  sqlite3
2b20: 5f 66 72 65 65 28 70 2d 3e 61 43 6f 6c 29 3b 0a  _free(p->aCol);.
2b30: 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70    sqlite3_free(p
2b40: 2d 3e 7a 54 68 69 73 29 3b 0a 20 20 73 71 6c 69  ->zThis);.  sqli
2b50: 74 65 33 5f 66 72 65 65 28 70 2d 3e 7a 54 61 62  te3_free(p->zTab
2b60: 6c 65 4e 61 6d 65 29 3b 0a 20 20 73 71 6c 69 74  leName);.  sqlit
2b70: 65 33 5f 66 72 65 65 28 70 2d 3e 7a 4c 6f 67 4e  e3_free(p->zLogN
2b80: 61 6d 65 29 3b 0a 20 20 73 71 6c 69 74 65 33 5f  ame);.  sqlite3_
2b90: 66 72 65 65 28 70 29 3b 0a 20 20 72 65 74 75 72  free(p);.  retur
2ba0: 6e 20 30 3b 0a 7d 0a 0a 74 79 70 65 64 65 66 20  n 0;.}..typedef 
2bb0: 73 74 72 75 63 74 20 45 63 68 6f 4d 6f 64 75 6c  struct EchoModul
2bc0: 65 20 45 63 68 6f 4d 6f 64 75 6c 65 3b 0a 73 74  e EchoModule;.st
2bd0: 72 75 63 74 20 45 63 68 6f 4d 6f 64 75 6c 65 20  ruct EchoModule 
2be0: 7b 0a 20 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a  {.  Tcl_Interp *
2bf0: 69 6e 74 65 72 70 3b 0a 7d 3b 0a 0a 2f 2a 0a 2a  interp;.};../*.*
2c00: 2a 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20  * This function 
2c10: 69 73 20 63 61 6c 6c 65 64 20 74 6f 20 64 6f 20  is called to do 
2c20: 74 68 65 20 77 6f 72 6b 20 6f 66 20 74 68 65 20  the work of the 
2c30: 78 43 6f 6e 6e 65 63 74 28 29 20 6d 65 74 68 6f  xConnect() metho
2c40: 64 20 2d 0a 2a 2a 20 74 6f 20 61 6c 6c 6f 63 61  d -.** to alloca
2c50: 74 65 20 74 68 65 20 72 65 71 75 69 72 65 64 20  te the required 
2c60: 69 6e 2d 6d 65 6d 6f 72 79 20 73 74 72 75 63 74  in-memory struct
2c70: 75 72 65 73 20 66 6f 72 20 61 20 6e 65 77 6c 79  ures for a newly
2c80: 20 63 6f 6e 6e 65 63 74 65 64 0a 2a 2a 20 76 69   connected.** vi
2c90: 72 74 75 61 6c 20 74 61 62 6c 65 2e 0a 2a 2f 0a  rtual table..*/.
2ca0: 73 74 61 74 69 63 20 69 6e 74 20 65 63 68 6f 43  static int echoC
2cb0: 6f 6e 73 74 72 75 63 74 6f 72 28 0a 20 20 73 71  onstructor(.  sq
2cc0: 6c 69 74 65 33 20 2a 64 62 2c 0a 20 20 76 6f 69  lite3 *db,.  voi
2cd0: 64 20 2a 70 41 75 78 2c 0a 20 20 69 6e 74 20 61  d *pAux,.  int a
2ce0: 72 67 63 2c 20 63 6f 6e 73 74 20 63 68 61 72 20  rgc, const char 
2cf0: 2a 63 6f 6e 73 74 2a 61 72 67 76 2c 0a 20 20 73  *const*argv,.  s
2d00: 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 2a 70 70  qlite3_vtab **pp
2d10: 56 74 61 62 2c 0a 20 20 63 68 61 72 20 2a 2a 70  Vtab,.  char **p
2d20: 7a 45 72 72 0a 29 7b 0a 20 20 69 6e 74 20 72 63  zErr.){.  int rc
2d30: 3b 0a 20 20 69 6e 74 20 69 3b 0a 20 20 65 63 68  ;.  int i;.  ech
2d40: 6f 5f 76 74 61 62 20 2a 70 56 74 61 62 3b 0a 0a  o_vtab *pVtab;..
2d50: 20 20 2f 2a 20 41 6c 6c 6f 63 61 74 65 20 74 68    /* Allocate th
2d60: 65 20 73 71 6c 69 74 65 33 5f 76 74 61 62 2f 65  e sqlite3_vtab/e
2d70: 63 68 6f 5f 76 74 61 62 20 73 74 72 75 63 74 75  cho_vtab structu
2d80: 72 65 20 69 74 73 65 6c 66 20 2a 2f 0a 20 20 70  re itself */.  p
2d90: 56 74 61 62 20 3d 20 73 71 6c 69 74 65 33 4d 61  Vtab = sqlite3Ma
2da0: 6c 6c 6f 63 5a 65 72 6f 28 20 73 69 7a 65 6f 66  llocZero( sizeof
2db0: 28 2a 70 56 74 61 62 29 20 29 3b 0a 20 20 69 66  (*pVtab) );.  if
2dc0: 28 20 21 70 56 74 61 62 20 29 7b 0a 20 20 20 20  ( !pVtab ){.    
2dd0: 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f  return SQLITE_NO
2de0: 4d 45 4d 3b 0a 20 20 7d 0a 20 20 70 56 74 61 62  MEM;.  }.  pVtab
2df0: 2d 3e 69 6e 74 65 72 70 20 3d 20 28 28 45 63 68  ->interp = ((Ech
2e00: 6f 4d 6f 64 75 6c 65 20 2a 29 70 41 75 78 29 2d  oModule *)pAux)-
2e10: 3e 69 6e 74 65 72 70 3b 0a 20 20 70 56 74 61 62  >interp;.  pVtab
2e20: 2d 3e 64 62 20 3d 20 64 62 3b 0a 0a 20 20 2f 2a  ->db = db;..  /*
2e30: 20 41 6c 6c 6f 63 61 74 65 20 65 63 68 6f 5f 76   Allocate echo_v
2e40: 74 61 62 2e 7a 54 68 69 73 20 2a 2f 0a 20 20 70  tab.zThis */.  p
2e50: 56 74 61 62 2d 3e 7a 54 68 69 73 20 3d 20 73 71  Vtab->zThis = sq
2e60: 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 22 25  lite3_mprintf("%
2e70: 73 22 2c 20 61 72 67 76 5b 32 5d 29 3b 0a 20 20  s", argv[2]);.  
2e80: 69 66 28 20 21 70 56 74 61 62 2d 3e 7a 54 68 69  if( !pVtab->zThi
2e90: 73 20 29 7b 0a 20 20 20 20 65 63 68 6f 44 65 73  s ){.    echoDes
2ea0: 74 72 75 63 74 6f 72 28 28 73 71 6c 69 74 65 33  tructor((sqlite3
2eb0: 5f 76 74 61 62 20 2a 29 70 56 74 61 62 29 3b 0a  _vtab *)pVtab);.
2ec0: 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54      return SQLIT
2ed0: 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 7d 0a 0a 20 20  E_NOMEM;.  }..  
2ee0: 2f 2a 20 41 6c 6c 6f 63 61 74 65 20 65 63 68 6f  /* Allocate echo
2ef0: 5f 76 74 61 62 2e 7a 54 61 62 6c 65 4e 61 6d 65  _vtab.zTableName
2f00: 20 2a 2f 0a 20 20 69 66 28 20 61 72 67 63 3e 33   */.  if( argc>3
2f10: 20 29 7b 0a 20 20 20 20 70 56 74 61 62 2d 3e 7a   ){.    pVtab->z
2f20: 54 61 62 6c 65 4e 61 6d 65 20 3d 20 73 71 6c 69  TableName = sqli
2f30: 74 65 33 5f 6d 70 72 69 6e 74 66 28 22 25 73 22  te3_mprintf("%s"
2f40: 2c 20 61 72 67 76 5b 33 5d 29 3b 0a 20 20 20 20  , argv[3]);.    
2f50: 64 65 71 75 6f 74 65 53 74 72 69 6e 67 28 70 56  dequoteString(pV
2f60: 74 61 62 2d 3e 7a 54 61 62 6c 65 4e 61 6d 65 29  tab->zTableName)
2f70: 3b 0a 20 20 20 20 69 66 28 20 70 56 74 61 62 2d  ;.    if( pVtab-
2f80: 3e 7a 54 61 62 6c 65 4e 61 6d 65 20 26 26 20 70  >zTableName && p
2f90: 56 74 61 62 2d 3e 7a 54 61 62 6c 65 4e 61 6d 65  Vtab->zTableName
2fa0: 5b 30 5d 3d 3d 27 2a 27 20 29 7b 0a 20 20 20 20  [0]=='*' ){.    
2fb0: 20 20 63 68 61 72 20 2a 7a 20 3d 20 73 71 6c 69    char *z = sqli
2fc0: 74 65 33 5f 6d 70 72 69 6e 74 66 28 22 25 73 25  te3_mprintf("%s%
2fd0: 73 22 2c 20 61 72 67 76 5b 32 5d 2c 20 26 28 70  s", argv[2], &(p
2fe0: 56 74 61 62 2d 3e 7a 54 61 62 6c 65 4e 61 6d 65  Vtab->zTableName
2ff0: 5b 31 5d 29 29 3b 0a 20 20 20 20 20 20 73 71 6c  [1]));.      sql
3000: 69 74 65 33 5f 66 72 65 65 28 70 56 74 61 62 2d  ite3_free(pVtab-
3010: 3e 7a 54 61 62 6c 65 4e 61 6d 65 29 3b 0a 20 20  >zTableName);.  
3020: 20 20 20 20 70 56 74 61 62 2d 3e 7a 54 61 62 6c      pVtab->zTabl
3030: 65 4e 61 6d 65 20 3d 20 7a 3b 0a 20 20 20 20 20  eName = z;.     
3040: 20 70 56 74 61 62 2d 3e 69 73 50 61 74 74 65 72   pVtab->isPatter
3050: 6e 20 3d 20 31 3b 0a 20 20 20 20 7d 0a 20 20 20  n = 1;.    }.   
3060: 20 69 66 28 20 21 70 56 74 61 62 2d 3e 7a 54 61   if( !pVtab->zTa
3070: 62 6c 65 4e 61 6d 65 20 29 7b 0a 20 20 20 20 20  bleName ){.     
3080: 20 65 63 68 6f 44 65 73 74 72 75 63 74 6f 72 28   echoDestructor(
3090: 28 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 29  (sqlite3_vtab *)
30a0: 70 56 74 61 62 29 3b 0a 20 20 20 20 20 20 72 65  pVtab);.      re
30b0: 74 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45  turn SQLITE_NOME
30c0: 4d 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20  M;.    }.  }..  
30d0: 2f 2a 20 4c 6f 67 20 74 68 65 20 61 72 67 75 6d  /* Log the argum
30e0: 65 6e 74 73 20 74 6f 20 74 68 69 73 20 66 75 6e  ents to this fun
30f0: 63 74 69 6f 6e 20 74 6f 20 54 63 6c 20 76 61 72  ction to Tcl var
3100: 20 3a 3a 65 63 68 6f 5f 6d 6f 64 75 6c 65 20 2a   ::echo_module *
3110: 2f 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 61  /.  for(i=0; i<a
3120: 72 67 63 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 61  rgc; i++){.    a
3130: 70 70 65 6e 64 54 6f 45 63 68 6f 4d 6f 64 75 6c  ppendToEchoModul
3140: 65 28 70 56 74 61 62 2d 3e 69 6e 74 65 72 70 2c  e(pVtab->interp,
3150: 20 61 72 67 76 5b 69 5d 29 3b 0a 20 20 7d 0a 0a   argv[i]);.  }..
3160: 20 20 2f 2a 20 49 6e 76 6f 6b 65 20 73 71 6c 69    /* Invoke sqli
3170: 74 65 33 5f 64 65 63 6c 61 72 65 5f 76 74 61 62  te3_declare_vtab
3180: 20 61 6e 64 20 73 65 74 20 75 70 20 6f 74 68 65   and set up othe
3190: 72 20 6d 65 6d 62 65 72 73 20 6f 66 20 74 68 65  r members of the
31a0: 20 65 63 68 6f 5f 76 74 61 62 0a 20 20 2a 2a 20   echo_vtab.  ** 
31b0: 73 74 72 75 63 74 75 72 65 2e 20 49 66 20 61 6e  structure. If an
31c0: 20 65 72 72 6f 72 20 6f 63 63 75 72 73 2c 20 64   error occurs, d
31d0: 65 6c 65 74 65 20 74 68 65 20 73 71 6c 69 74 65  elete the sqlite
31e0: 33 5f 76 74 61 62 20 73 74 72 75 63 74 75 72 65  3_vtab structure
31f0: 20 61 6e 64 0a 20 20 2a 2a 20 72 65 74 75 72 6e   and.  ** return
3200: 20 61 6e 20 65 72 72 6f 72 20 63 6f 64 65 2e 0a   an error code..
3210: 20 20 2a 2f 0a 20 20 72 63 20 3d 20 65 63 68 6f    */.  rc = echo
3220: 44 65 63 6c 61 72 65 56 74 61 62 28 70 56 74 61  DeclareVtab(pVta
3230: 62 2c 20 64 62 29 3b 0a 20 20 69 66 28 20 72 63  b, db);.  if( rc
3240: 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  !=SQLITE_OK ){. 
3250: 20 20 20 65 63 68 6f 44 65 73 74 72 75 63 74 6f     echoDestructo
3260: 72 28 28 73 71 6c 69 74 65 33 5f 76 74 61 62 20  r((sqlite3_vtab 
3270: 2a 29 70 56 74 61 62 29 3b 0a 20 20 20 20 72 65  *)pVtab);.    re
3280: 74 75 72 6e 20 72 63 3b 0a 20 20 7d 0a 0a 20 20  turn rc;.  }..  
3290: 2f 2a 20 53 75 63 63 65 73 73 2e 20 53 65 74 20  /* Success. Set 
32a0: 2a 70 70 56 74 61 62 20 61 6e 64 20 72 65 74 75  *ppVtab and retu
32b0: 72 6e 20 2a 2f 0a 20 20 2a 70 70 56 74 61 62 20  rn */.  *ppVtab 
32c0: 3d 20 26 70 56 74 61 62 2d 3e 62 61 73 65 3b 0a  = &pVtab->base;.
32d0: 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f    return SQLITE_
32e0: 4f 4b 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 45 63  OK;.}../* .** Ec
32f0: 68 6f 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65  ho virtual table
3300: 20 6d 6f 64 75 6c 65 20 78 43 72 65 61 74 65 20   module xCreate 
3310: 6d 65 74 68 6f 64 2e 0a 2a 2f 0a 73 74 61 74 69  method..*/.stati
3320: 63 20 69 6e 74 20 65 63 68 6f 43 72 65 61 74 65  c int echoCreate
3330: 28 0a 20 20 73 71 6c 69 74 65 33 20 2a 64 62 2c  (.  sqlite3 *db,
3340: 0a 20 20 76 6f 69 64 20 2a 70 41 75 78 2c 0a 20  .  void *pAux,. 
3350: 20 69 6e 74 20 61 72 67 63 2c 20 63 6f 6e 73 74   int argc, const
3360: 20 63 68 61 72 20 2a 63 6f 6e 73 74 2a 61 72 67   char *const*arg
3370: 76 2c 0a 20 20 73 71 6c 69 74 65 33 5f 76 74 61  v,.  sqlite3_vta
3380: 62 20 2a 2a 70 70 56 74 61 62 2c 0a 20 20 63 68  b **ppVtab,.  ch
3390: 61 72 20 2a 2a 70 7a 45 72 72 0a 29 7b 0a 20 20  ar **pzErr.){.  
33a0: 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f  int rc = SQLITE_
33b0: 4f 4b 3b 0a 20 20 61 70 70 65 6e 64 54 6f 45 63  OK;.  appendToEc
33c0: 68 6f 4d 6f 64 75 6c 65 28 28 28 45 63 68 6f 4d  hoModule(((EchoM
33d0: 6f 64 75 6c 65 20 2a 29 70 41 75 78 29 2d 3e 69  odule *)pAux)->i
33e0: 6e 74 65 72 70 2c 20 22 78 43 72 65 61 74 65 22  nterp, "xCreate"
33f0: 29 3b 0a 20 20 72 63 20 3d 20 65 63 68 6f 43 6f  );.  rc = echoCo
3400: 6e 73 74 72 75 63 74 6f 72 28 64 62 2c 20 70 41  nstructor(db, pA
3410: 75 78 2c 20 61 72 67 63 2c 20 61 72 67 76 2c 20  ux, argc, argv, 
3420: 70 70 56 74 61 62 2c 20 70 7a 45 72 72 29 3b 0a  ppVtab, pzErr);.
3430: 0a 20 20 2f 2a 20 49 66 20 74 68 65 72 65 20 77  .  /* If there w
3440: 65 72 65 20 74 77 6f 20 61 72 67 75 6d 65 6e 74  ere two argument
3450: 73 20 70 61 73 73 65 64 20 74 6f 20 74 68 65 20  s passed to the 
3460: 6d 6f 64 75 6c 65 20 61 74 20 74 68 65 20 53 51  module at the SQ
3470: 4c 20 6c 65 76 65 6c 20 0a 20 20 2a 2a 20 28 69  L level .  ** (i
3480: 2e 65 2e 20 22 43 52 45 41 54 45 20 56 49 52 54  .e. "CREATE VIRT
3490: 55 41 4c 20 54 41 42 4c 45 20 74 62 6c 20 55 53  UAL TABLE tbl US
34a0: 49 4e 47 20 65 63 68 6f 28 61 72 67 31 2c 20 61  ING echo(arg1, a
34b0: 72 67 32 29 22 29 2c 20 74 68 65 6e 20 0a 20 20  rg2)"), then .  
34c0: 2a 2a 20 74 68 65 20 73 65 63 6f 6e 64 20 61 72  ** the second ar
34d0: 67 75 6d 65 6e 74 20 69 73 20 75 73 65 64 20 61  gument is used a
34e0: 73 20 61 20 74 61 62 6c 65 20 6e 61 6d 65 2e 20  s a table name. 
34f0: 41 74 74 65 6d 70 74 20 74 6f 20 63 72 65 61 74  Attempt to creat
3500: 65 0a 20 20 2a 2a 20 73 75 63 68 20 61 20 74 61  e.  ** such a ta
3510: 62 6c 65 20 77 69 74 68 20 61 20 73 69 6e 67 6c  ble with a singl
3520: 65 20 63 6f 6c 75 6d 6e 2c 20 22 6c 6f 67 6d 73  e column, "logms
3530: 67 22 2e 20 54 68 69 73 20 74 61 62 6c 65 20 77  g". This table w
3540: 69 6c 6c 0a 20 20 2a 2a 20 62 65 20 75 73 65 64  ill.  ** be used
3550: 20 74 6f 20 6c 6f 67 20 63 61 6c 6c 73 20 74 6f   to log calls to
3560: 20 74 68 65 20 78 55 70 64 61 74 65 20 6d 65 74   the xUpdate met
3570: 68 6f 64 2e 20 49 74 20 77 69 6c 6c 20 62 65 20  hod. It will be 
3580: 64 65 6c 65 74 65 64 0a 20 20 2a 2a 20 77 68 65  deleted.  ** whe
3590: 6e 20 74 68 65 20 76 69 72 74 75 61 6c 20 74 61  n the virtual ta
35a0: 62 6c 65 20 69 73 20 44 52 4f 50 65 64 2e 0a 20  ble is DROPed.. 
35b0: 20 2a 2a 0a 20 20 2a 2a 20 4e 6f 74 65 3a 20 54   **.  ** Note: T
35c0: 68 65 20 6d 61 69 6e 20 70 6f 69 6e 74 20 6f 66  he main point of
35d0: 20 74 68 69 73 20 69 73 20 74 6f 20 74 65 73 74   this is to test
35e0: 20 74 68 61 74 20 77 65 20 63 61 6e 20 64 72 6f   that we can dro
35f0: 70 20 74 61 62 6c 65 73 0a 20 20 2a 2a 20 66 72  p tables.  ** fr
3600: 6f 6d 20 77 69 74 68 69 6e 20 61 6e 20 78 44 65  om within an xDe
3610: 73 74 72 6f 79 20 6d 65 74 68 6f 64 20 63 61 6c  stroy method cal
3620: 6c 2e 0a 20 20 2a 2f 0a 20 20 69 66 28 20 72 63  l..  */.  if( rc
3630: 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20 61  ==SQLITE_OK && a
3640: 72 67 63 3d 3d 35 20 29 7b 0a 20 20 20 20 63 68  rgc==5 ){.    ch
3650: 61 72 20 2a 7a 53 71 6c 3b 0a 20 20 20 20 65 63  ar *zSql;.    ec
3660: 68 6f 5f 76 74 61 62 20 2a 70 56 74 61 62 20 3d  ho_vtab *pVtab =
3670: 20 2a 28 65 63 68 6f 5f 76 74 61 62 20 2a 2a 29   *(echo_vtab **)
3680: 70 70 56 74 61 62 3b 0a 20 20 20 20 70 56 74 61  ppVtab;.    pVta
3690: 62 2d 3e 7a 4c 6f 67 4e 61 6d 65 20 3d 20 73 71  b->zLogName = sq
36a0: 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 22 25  lite3_mprintf("%
36b0: 73 22 2c 20 61 72 67 76 5b 34 5d 29 3b 0a 20 20  s", argv[4]);.  
36c0: 20 20 7a 53 71 6c 20 3d 20 73 71 6c 69 74 65 33    zSql = sqlite3
36d0: 5f 6d 70 72 69 6e 74 66 28 22 43 52 45 41 54 45  _mprintf("CREATE
36e0: 20 54 41 42 4c 45 20 25 51 28 6c 6f 67 6d 73 67   TABLE %Q(logmsg
36f0: 29 22 2c 20 70 56 74 61 62 2d 3e 7a 4c 6f 67 4e  )", pVtab->zLogN
3700: 61 6d 65 29 3b 0a 20 20 20 20 72 63 20 3d 20 73  ame);.    rc = s
3710: 71 6c 69 74 65 33 5f 65 78 65 63 28 64 62 2c 20  qlite3_exec(db, 
3720: 7a 53 71 6c 2c 20 30 2c 20 30 2c 20 30 29 3b 0a  zSql, 0, 0, 0);.
3730: 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65      sqlite3_free
3740: 28 7a 53 71 6c 29 3b 0a 20 20 20 20 69 66 28 20  (zSql);.    if( 
3750: 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc!=SQLITE_OK ){
3760: 0a 20 20 20 20 20 20 2a 70 7a 45 72 72 20 3d 20  .      *pzErr = 
3770: 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28  sqlite3_mprintf(
3780: 22 25 73 22 2c 20 73 71 6c 69 74 65 33 5f 65 72  "%s", sqlite3_er
3790: 72 6d 73 67 28 64 62 29 29 3b 0a 20 20 20 20 7d  rmsg(db));.    }
37a0: 0a 20 20 7d 0a 0a 20 20 69 66 28 20 2a 70 70 56  .  }..  if( *ppV
37b0: 74 61 62 20 26 26 20 72 63 21 3d 53 51 4c 49 54  tab && rc!=SQLIT
37c0: 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 65 63 68 6f  E_OK ){.    echo
37d0: 44 65 73 74 72 75 63 74 6f 72 28 2a 70 70 56 74  Destructor(*ppVt
37e0: 61 62 29 3b 0a 20 20 20 20 2a 70 70 56 74 61 62  ab);.    *ppVtab
37f0: 20 3d 20 30 3b 0a 20 20 7d 0a 0a 20 20 69 66 28   = 0;.  }..  if(
3800: 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc==SQLITE_OK )
3810: 7b 0a 20 20 20 20 28 2a 28 65 63 68 6f 5f 76 74  {.    (*(echo_vt
3820: 61 62 2a 2a 29 70 70 56 74 61 62 29 2d 3e 69 6e  ab**)ppVtab)->in
3830: 54 72 61 6e 73 61 63 74 69 6f 6e 20 3d 20 31 3b  Transaction = 1;
3840: 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 72  .  }..  return r
3850: 63 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 45 63 68  c;.}../* .** Ech
3860: 6f 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65 20  o virtual table 
3870: 6d 6f 64 75 6c 65 20 78 43 6f 6e 6e 65 63 74 20  module xConnect 
3880: 6d 65 74 68 6f 64 2e 0a 2a 2f 0a 73 74 61 74 69  method..*/.stati
3890: 63 20 69 6e 74 20 65 63 68 6f 43 6f 6e 6e 65 63  c int echoConnec
38a0: 74 28 0a 20 20 73 71 6c 69 74 65 33 20 2a 64 62  t(.  sqlite3 *db
38b0: 2c 0a 20 20 76 6f 69 64 20 2a 70 41 75 78 2c 0a  ,.  void *pAux,.
38c0: 20 20 69 6e 74 20 61 72 67 63 2c 20 63 6f 6e 73    int argc, cons
38d0: 74 20 63 68 61 72 20 2a 63 6f 6e 73 74 2a 61 72  t char *const*ar
38e0: 67 76 2c 0a 20 20 73 71 6c 69 74 65 33 5f 76 74  gv,.  sqlite3_vt
38f0: 61 62 20 2a 2a 70 70 56 74 61 62 2c 0a 20 20 63  ab **ppVtab,.  c
3900: 68 61 72 20 2a 2a 70 7a 45 72 72 0a 29 7b 0a 20  har **pzErr.){. 
3910: 20 61 70 70 65 6e 64 54 6f 45 63 68 6f 4d 6f 64   appendToEchoMod
3920: 75 6c 65 28 28 28 45 63 68 6f 4d 6f 64 75 6c 65  ule(((EchoModule
3930: 20 2a 29 70 41 75 78 29 2d 3e 69 6e 74 65 72 70   *)pAux)->interp
3940: 2c 20 22 78 43 6f 6e 6e 65 63 74 22 29 3b 0a 20  , "xConnect");. 
3950: 20 72 65 74 75 72 6e 20 65 63 68 6f 43 6f 6e 73   return echoCons
3960: 74 72 75 63 74 6f 72 28 64 62 2c 20 70 41 75 78  tructor(db, pAux
3970: 2c 20 61 72 67 63 2c 20 61 72 67 76 2c 20 70 70  , argc, argv, pp
3980: 56 74 61 62 2c 20 70 7a 45 72 72 29 3b 0a 7d 0a  Vtab, pzErr);.}.
3990: 0a 2f 2a 20 0a 2a 2a 20 45 63 68 6f 20 76 69 72  ./* .** Echo vir
39a0: 74 75 61 6c 20 74 61 62 6c 65 20 6d 6f 64 75 6c  tual table modul
39b0: 65 20 78 44 69 73 63 6f 6e 6e 65 63 74 20 6d 65  e xDisconnect me
39c0: 74 68 6f 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  thod..*/.static 
39d0: 69 6e 74 20 65 63 68 6f 44 69 73 63 6f 6e 6e 65  int echoDisconne
39e0: 63 74 28 73 71 6c 69 74 65 33 5f 76 74 61 62 20  ct(sqlite3_vtab 
39f0: 2a 70 56 74 61 62 29 7b 0a 20 20 61 70 70 65 6e  *pVtab){.  appen
3a00: 64 54 6f 45 63 68 6f 4d 6f 64 75 6c 65 28 28 28  dToEchoModule(((
3a10: 65 63 68 6f 5f 76 74 61 62 20 2a 29 70 56 74 61  echo_vtab *)pVta
3a20: 62 29 2d 3e 69 6e 74 65 72 70 2c 20 22 78 44 69  b)->interp, "xDi
3a30: 73 63 6f 6e 6e 65 63 74 22 29 3b 0a 20 20 72 65  sconnect");.  re
3a40: 74 75 72 6e 20 65 63 68 6f 44 65 73 74 72 75 63  turn echoDestruc
3a50: 74 6f 72 28 70 56 74 61 62 29 3b 0a 7d 0a 0a 2f  tor(pVtab);.}../
3a60: 2a 20 0a 2a 2a 20 45 63 68 6f 20 76 69 72 74 75  * .** Echo virtu
3a70: 61 6c 20 74 61 62 6c 65 20 6d 6f 64 75 6c 65 20  al table module 
3a80: 78 44 65 73 74 72 6f 79 20 6d 65 74 68 6f 64 2e  xDestroy method.
3a90: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 65  .*/.static int e
3aa0: 63 68 6f 44 65 73 74 72 6f 79 28 73 71 6c 69 74  choDestroy(sqlit
3ab0: 65 33 5f 76 74 61 62 20 2a 70 56 74 61 62 29 7b  e3_vtab *pVtab){
3ac0: 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49  .  int rc = SQLI
3ad0: 54 45 5f 4f 4b 3b 0a 20 20 65 63 68 6f 5f 76 74  TE_OK;.  echo_vt
3ae0: 61 62 20 2a 70 20 3d 20 28 65 63 68 6f 5f 76 74  ab *p = (echo_vt
3af0: 61 62 20 2a 29 70 56 74 61 62 3b 0a 20 20 61 70  ab *)pVtab;.  ap
3b00: 70 65 6e 64 54 6f 45 63 68 6f 4d 6f 64 75 6c 65  pendToEchoModule
3b10: 28 28 28 65 63 68 6f 5f 76 74 61 62 20 2a 29 70  (((echo_vtab *)p
3b20: 56 74 61 62 29 2d 3e 69 6e 74 65 72 70 2c 20 22  Vtab)->interp, "
3b30: 78 44 65 73 74 72 6f 79 22 29 3b 0a 0a 20 20 2f  xDestroy");..  /
3b40: 2a 20 44 72 6f 70 20 74 68 65 20 22 6c 6f 67 22  * Drop the "log"
3b50: 20 74 61 62 6c 65 2c 20 69 66 20 6f 6e 65 20 65   table, if one e
3b60: 78 69 73 74 73 20 28 73 65 65 20 65 63 68 6f 43  xists (see echoC
3b70: 72 65 61 74 65 28 29 20 66 6f 72 20 64 65 74 61  reate() for deta
3b80: 69 6c 73 29 20 2a 2f 0a 20 20 69 66 28 20 70 20  ils) */.  if( p 
3b90: 26 26 20 70 2d 3e 7a 4c 6f 67 4e 61 6d 65 20 29  && p->zLogName )
3ba0: 7b 0a 20 20 20 20 63 68 61 72 20 2a 7a 53 71 6c  {.    char *zSql
3bb0: 3b 0a 20 20 20 20 7a 53 71 6c 20 3d 20 73 71 6c  ;.    zSql = sql
3bc0: 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 22 44 52  ite3_mprintf("DR
3bd0: 4f 50 20 54 41 42 4c 45 20 25 51 22 2c 20 70 2d  OP TABLE %Q", p-
3be0: 3e 7a 4c 6f 67 4e 61 6d 65 29 3b 0a 20 20 20 20  >zLogName);.    
3bf0: 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 65 78 65  rc = sqlite3_exe
3c00: 63 28 70 2d 3e 64 62 2c 20 7a 53 71 6c 2c 20 30  c(p->db, zSql, 0
3c10: 2c 20 30 2c 20 30 29 3b 0a 20 20 20 20 73 71 6c  , 0, 0);.    sql
3c20: 69 74 65 33 5f 66 72 65 65 28 7a 53 71 6c 29 3b  ite3_free(zSql);
3c30: 0a 20 20 7d 0a 0a 20 20 69 66 28 20 72 63 3d 3d  .  }..  if( rc==
3c40: 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20  SQLITE_OK ){.   
3c50: 20 72 63 20 3d 20 65 63 68 6f 44 65 73 74 72 75   rc = echoDestru
3c60: 63 74 6f 72 28 70 56 74 61 62 29 3b 0a 20 20 7d  ctor(pVtab);.  }
3c70: 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a  .  return rc;.}.
3c80: 0a 2f 2a 20 0a 2a 2a 20 45 63 68 6f 20 76 69 72  ./* .** Echo vir
3c90: 74 75 61 6c 20 74 61 62 6c 65 20 6d 6f 64 75 6c  tual table modul
3ca0: 65 20 78 4f 70 65 6e 20 6d 65 74 68 6f 64 2e 0a  e xOpen method..
3cb0: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 65 63  */.static int ec
3cc0: 68 6f 4f 70 65 6e 28 73 71 6c 69 74 65 33 5f 76  hoOpen(sqlite3_v
3cd0: 74 61 62 20 2a 70 56 54 61 62 2c 20 73 71 6c 69  tab *pVTab, sqli
3ce0: 74 65 33 5f 76 74 61 62 5f 63 75 72 73 6f 72 20  te3_vtab_cursor 
3cf0: 2a 2a 70 70 43 75 72 73 6f 72 29 7b 0a 20 20 65  **ppCursor){.  e
3d00: 63 68 6f 5f 63 75 72 73 6f 72 20 2a 70 43 75 72  cho_cursor *pCur
3d10: 3b 0a 20 20 69 66 28 20 73 69 6d 75 6c 61 74 65  ;.  if( simulate
3d20: 56 74 61 62 45 72 72 6f 72 28 28 65 63 68 6f 5f  VtabError((echo_
3d30: 76 74 61 62 20 2a 29 70 56 54 61 62 2c 20 22 78  vtab *)pVTab, "x
3d40: 4f 70 65 6e 22 29 20 29 7b 0a 20 20 20 20 72 65  Open") ){.    re
3d50: 74 75 72 6e 20 53 51 4c 49 54 45 5f 45 52 52 4f  turn SQLITE_ERRO
3d60: 52 3b 0a 20 20 7d 0a 20 20 70 43 75 72 20 3d 20  R;.  }.  pCur = 
3d70: 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63 5a 65 72  sqlite3MallocZer
3d80: 6f 28 73 69 7a 65 6f 66 28 65 63 68 6f 5f 63 75  o(sizeof(echo_cu
3d90: 72 73 6f 72 29 29 3b 0a 20 20 2a 70 70 43 75 72  rsor));.  *ppCur
3da0: 73 6f 72 20 3d 20 28 73 71 6c 69 74 65 33 5f 76  sor = (sqlite3_v
3db0: 74 61 62 5f 63 75 72 73 6f 72 20 2a 29 70 43 75  tab_cursor *)pCu
3dc0: 72 3b 0a 20 20 72 65 74 75 72 6e 20 28 70 43 75  r;.  return (pCu
3dd0: 72 20 3f 20 53 51 4c 49 54 45 5f 4f 4b 20 3a 20  r ? SQLITE_OK : 
3de0: 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 29 3b 0a 7d  SQLITE_NOMEM);.}
3df0: 0a 0a 2f 2a 20 0a 2a 2a 20 45 63 68 6f 20 76 69  ../* .** Echo vi
3e00: 72 74 75 61 6c 20 74 61 62 6c 65 20 6d 6f 64 75  rtual table modu
3e10: 6c 65 20 78 43 6c 6f 73 65 20 6d 65 74 68 6f 64  le xClose method
3e20: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
3e30: 65 63 68 6f 43 6c 6f 73 65 28 73 71 6c 69 74 65  echoClose(sqlite
3e40: 33 5f 76 74 61 62 5f 63 75 72 73 6f 72 20 2a 63  3_vtab_cursor *c
3e50: 75 72 29 7b 0a 20 20 69 6e 74 20 72 63 3b 0a 20  ur){.  int rc;. 
3e60: 20 65 63 68 6f 5f 63 75 72 73 6f 72 20 2a 70 43   echo_cursor *pC
3e70: 75 72 20 3d 20 28 65 63 68 6f 5f 63 75 72 73 6f  ur = (echo_curso
3e80: 72 20 2a 29 63 75 72 3b 0a 20 20 73 71 6c 69 74  r *)cur;.  sqlit
3e90: 65 33 5f 73 74 6d 74 20 2a 70 53 74 6d 74 20 3d  e3_stmt *pStmt =
3ea0: 20 70 43 75 72 2d 3e 70 53 74 6d 74 3b 0a 20 20   pCur->pStmt;.  
3eb0: 70 43 75 72 2d 3e 70 53 74 6d 74 20 3d 20 30 3b  pCur->pStmt = 0;
3ec0: 0a 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28  .  sqlite3_free(
3ed0: 70 43 75 72 29 3b 0a 20 20 72 63 20 3d 20 73 71  pCur);.  rc = sq
3ee0: 6c 69 74 65 33 5f 66 69 6e 61 6c 69 7a 65 28 70  lite3_finalize(p
3ef0: 53 74 6d 74 29 3b 0a 20 20 72 65 74 75 72 6e 20  Stmt);.  return 
3f00: 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74  rc;.}../*.** Ret
3f10: 75 72 6e 20 6e 6f 6e 2d 7a 65 72 6f 20 69 66 20  urn non-zero if 
3f20: 74 68 65 20 63 75 72 73 6f 72 20 64 6f 65 73 20  the cursor does 
3f30: 6e 6f 74 20 63 75 72 72 65 6e 74 6c 79 20 70 6f  not currently po
3f40: 69 6e 74 20 74 6f 20 61 20 76 61 6c 69 64 20 72  int to a valid r
3f50: 65 63 6f 72 64 0a 2a 2a 20 28 69 2e 65 20 69 66  ecord.** (i.e if
3f60: 20 74 68 65 20 73 63 61 6e 20 68 61 73 20 66 69   the scan has fi
3f70: 6e 69 73 68 65 64 29 2c 20 6f 72 20 7a 65 72 6f  nished), or zero
3f80: 20 6f 74 68 65 72 77 69 73 65 2e 0a 2a 2f 0a 73   otherwise..*/.s
3f90: 74 61 74 69 63 20 69 6e 74 20 65 63 68 6f 45 6f  tatic int echoEo
3fa0: 66 28 73 71 6c 69 74 65 33 5f 76 74 61 62 5f 63  f(sqlite3_vtab_c
3fb0: 75 72 73 6f 72 20 2a 63 75 72 29 7b 0a 20 20 72  ursor *cur){.  r
3fc0: 65 74 75 72 6e 20 28 28 28 65 63 68 6f 5f 63 75  eturn (((echo_cu
3fd0: 72 73 6f 72 20 2a 29 63 75 72 29 2d 3e 70 53 74  rsor *)cur)->pSt
3fe0: 6d 74 20 3f 20 30 20 3a 20 31 29 3b 0a 7d 0a 0a  mt ? 0 : 1);.}..
3ff0: 2f 2a 20 0a 2a 2a 20 45 63 68 6f 20 76 69 72 74  /* .** Echo virt
4000: 75 61 6c 20 74 61 62 6c 65 20 6d 6f 64 75 6c 65  ual table module
4010: 20 78 4e 65 78 74 20 6d 65 74 68 6f 64 2e 0a 2a   xNext method..*
4020: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 65 63 68  /.static int ech
4030: 6f 4e 65 78 74 28 73 71 6c 69 74 65 33 5f 76 74  oNext(sqlite3_vt
4040: 61 62 5f 63 75 72 73 6f 72 20 2a 63 75 72 29 7b  ab_cursor *cur){
4050: 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49  .  int rc = SQLI
4060: 54 45 5f 4f 4b 3b 0a 20 20 65 63 68 6f 5f 63 75  TE_OK;.  echo_cu
4070: 72 73 6f 72 20 2a 70 43 75 72 20 3d 20 28 65 63  rsor *pCur = (ec
4080: 68 6f 5f 63 75 72 73 6f 72 20 2a 29 63 75 72 3b  ho_cursor *)cur;
4090: 0a 0a 20 20 69 66 28 20 73 69 6d 75 6c 61 74 65  ..  if( simulate
40a0: 56 74 61 62 45 72 72 6f 72 28 28 65 63 68 6f 5f  VtabError((echo_
40b0: 76 74 61 62 20 2a 29 28 63 75 72 2d 3e 70 56 74  vtab *)(cur->pVt
40c0: 61 62 29 2c 20 22 78 4e 65 78 74 22 29 20 29 7b  ab), "xNext") ){
40d0: 0a 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49  .    return SQLI
40e0: 54 45 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a 0a 20  TE_ERROR;.  }.. 
40f0: 20 69 66 28 20 70 43 75 72 2d 3e 70 53 74 6d 74   if( pCur->pStmt
4100: 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 73 71 6c   ){.    rc = sql
4110: 69 74 65 33 5f 73 74 65 70 28 70 43 75 72 2d 3e  ite3_step(pCur->
4120: 70 53 74 6d 74 29 3b 0a 20 20 20 20 69 66 28 20  pStmt);.    if( 
4130: 72 63 3d 3d 53 51 4c 49 54 45 5f 52 4f 57 20 29  rc==SQLITE_ROW )
4140: 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c  {.      rc = SQL
4150: 49 54 45 5f 4f 4b 3b 0a 20 20 20 20 7d 65 6c 73  ITE_OK;.    }els
4160: 65 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 73 71  e{.      rc = sq
4170: 6c 69 74 65 33 5f 66 69 6e 61 6c 69 7a 65 28 70  lite3_finalize(p
4180: 43 75 72 2d 3e 70 53 74 6d 74 29 3b 0a 20 20 20  Cur->pStmt);.   
4190: 20 20 20 70 43 75 72 2d 3e 70 53 74 6d 74 20 3d     pCur->pStmt =
41a0: 20 30 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20   0;.    }.  }.. 
41b0: 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f   return rc;.}../
41c0: 2a 20 0a 2a 2a 20 45 63 68 6f 20 76 69 72 74 75  * .** Echo virtu
41d0: 61 6c 20 74 61 62 6c 65 20 6d 6f 64 75 6c 65 20  al table module 
41e0: 78 43 6f 6c 75 6d 6e 20 6d 65 74 68 6f 64 2e 0a  xColumn method..
41f0: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 65 63  */.static int ec
4200: 68 6f 43 6f 6c 75 6d 6e 28 73 71 6c 69 74 65 33  hoColumn(sqlite3
4210: 5f 76 74 61 62 5f 63 75 72 73 6f 72 20 2a 63 75  _vtab_cursor *cu
4220: 72 2c 20 73 71 6c 69 74 65 33 5f 63 6f 6e 74 65  r, sqlite3_conte
4230: 78 74 20 2a 63 74 78 2c 20 69 6e 74 20 69 29 7b  xt *ctx, int i){
4240: 0a 20 20 69 6e 74 20 69 43 6f 6c 20 3d 20 69 20  .  int iCol = i 
4250: 2b 20 31 3b 0a 20 20 73 71 6c 69 74 65 33 5f 73  + 1;.  sqlite3_s
4260: 74 6d 74 20 2a 70 53 74 6d 74 20 3d 20 28 28 65  tmt *pStmt = ((e
4270: 63 68 6f 5f 63 75 72 73 6f 72 20 2a 29 63 75 72  cho_cursor *)cur
4280: 29 2d 3e 70 53 74 6d 74 3b 0a 0a 20 20 69 66 28  )->pStmt;..  if(
4290: 20 73 69 6d 75 6c 61 74 65 56 74 61 62 45 72 72   simulateVtabErr
42a0: 6f 72 28 28 65 63 68 6f 5f 76 74 61 62 20 2a 29  or((echo_vtab *)
42b0: 28 63 75 72 2d 3e 70 56 74 61 62 29 2c 20 22 78  (cur->pVtab), "x
42c0: 43 6f 6c 75 6d 6e 22 29 20 29 7b 0a 20 20 20 20  Column") ){.    
42d0: 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 45 52  return SQLITE_ER
42e0: 52 4f 52 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20  ROR;.  }..  if( 
42f0: 21 70 53 74 6d 74 20 29 7b 0a 20 20 20 20 73 71  !pStmt ){.    sq
4300: 6c 69 74 65 33 5f 72 65 73 75 6c 74 5f 6e 75 6c  lite3_result_nul
4310: 6c 28 63 74 78 29 3b 0a 20 20 7d 65 6c 73 65 7b  l(ctx);.  }else{
4320: 0a 20 20 20 20 61 73 73 65 72 74 28 20 73 71 6c  .    assert( sql
4330: 69 74 65 33 5f 64 61 74 61 5f 63 6f 75 6e 74 28  ite3_data_count(
4340: 70 53 74 6d 74 29 3e 69 43 6f 6c 20 29 3b 0a 20  pStmt)>iCol );. 
4350: 20 20 20 73 71 6c 69 74 65 33 5f 72 65 73 75 6c     sqlite3_resul
4360: 74 5f 76 61 6c 75 65 28 63 74 78 2c 20 73 71 6c  t_value(ctx, sql
4370: 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 76 61 6c 75  ite3_column_valu
4380: 65 28 70 53 74 6d 74 2c 20 69 43 6f 6c 29 29 3b  e(pStmt, iCol));
4390: 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 53 51  .  }.  return SQ
43a0: 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 20 0a  LITE_OK;.}../* .
43b0: 2a 2a 20 45 63 68 6f 20 76 69 72 74 75 61 6c 20  ** Echo virtual 
43c0: 74 61 62 6c 65 20 6d 6f 64 75 6c 65 20 78 52 6f  table module xRo
43d0: 77 69 64 20 6d 65 74 68 6f 64 2e 0a 2a 2f 0a 73  wid method..*/.s
43e0: 74 61 74 69 63 20 69 6e 74 20 65 63 68 6f 52 6f  tatic int echoRo
43f0: 77 69 64 28 73 71 6c 69 74 65 33 5f 76 74 61 62  wid(sqlite3_vtab
4400: 5f 63 75 72 73 6f 72 20 2a 63 75 72 2c 20 73 71  _cursor *cur, sq
4410: 6c 69 74 65 5f 69 6e 74 36 34 20 2a 70 52 6f 77  lite_int64 *pRow
4420: 69 64 29 7b 0a 20 20 73 71 6c 69 74 65 33 5f 73  id){.  sqlite3_s
4430: 74 6d 74 20 2a 70 53 74 6d 74 20 3d 20 28 28 65  tmt *pStmt = ((e
4440: 63 68 6f 5f 63 75 72 73 6f 72 20 2a 29 63 75 72  cho_cursor *)cur
4450: 29 2d 3e 70 53 74 6d 74 3b 0a 0a 20 20 69 66 28  )->pStmt;..  if(
4460: 20 73 69 6d 75 6c 61 74 65 56 74 61 62 45 72 72   simulateVtabErr
4470: 6f 72 28 28 65 63 68 6f 5f 76 74 61 62 20 2a 29  or((echo_vtab *)
4480: 28 63 75 72 2d 3e 70 56 74 61 62 29 2c 20 22 78  (cur->pVtab), "x
4490: 52 6f 77 69 64 22 29 20 29 7b 0a 20 20 20 20 72  Rowid") ){.    r
44a0: 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 45 52 52  eturn SQLITE_ERR
44b0: 4f 52 3b 0a 20 20 7d 0a 0a 20 20 2a 70 52 6f 77  OR;.  }..  *pRow
44c0: 69 64 20 3d 20 73 71 6c 69 74 65 33 5f 63 6f 6c  id = sqlite3_col
44d0: 75 6d 6e 5f 69 6e 74 36 34 28 70 53 74 6d 74 2c  umn_int64(pStmt,
44e0: 20 30 29 3b 0a 20 20 72 65 74 75 72 6e 20 53 51   0);.  return SQ
44f0: 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a  LITE_OK;.}../*.*
4500: 2a 20 43 6f 6d 70 75 74 65 20 61 20 73 69 6d 70  * Compute a simp
4510: 6c 65 20 68 61 73 68 20 6f 66 20 74 68 65 20 6e  le hash of the n
4520: 75 6c 6c 20 74 65 72 6d 69 6e 61 74 65 64 20 73  ull terminated s
4530: 74 72 69 6e 67 20 7a 53 74 72 69 6e 67 2e 0a 2a  tring zString..*
4540: 2a 0a 2a 2a 20 54 68 69 73 20 6d 6f 64 75 6c 65  *.** This module
4550: 20 75 73 65 73 20 6f 6e 6c 79 20 73 71 6c 69 74   uses only sqlit
4560: 65 33 5f 69 6e 64 65 78 5f 69 6e 66 6f 2e 69 64  e3_index_info.id
4570: 78 53 74 72 2c 20 6e 6f 74 20 0a 2a 2a 20 73 71  xStr, not .** sq
4580: 6c 69 74 65 33 5f 69 6e 64 65 78 5f 69 6e 66 6f  lite3_index_info
4590: 2e 69 64 78 4e 75 6d 2e 20 53 6f 20 74 6f 20 74  .idxNum. So to t
45a0: 65 73 74 20 69 64 78 4e 75 6d 2c 20 77 68 65 6e  est idxNum, when
45b0: 20 69 64 78 53 74 72 20 69 73 20 73 65 74 0a 2a   idxStr is set.*
45c0: 2a 20 69 6e 20 65 63 68 6f 42 65 73 74 49 6e 64  * in echoBestInd
45d0: 65 78 28 29 2c 20 69 64 78 4e 75 6d 20 69 73 20  ex(), idxNum is 
45e0: 73 65 74 20 74 6f 20 74 68 65 20 63 6f 72 72 65  set to the corre
45f0: 73 70 6f 6e 64 69 6e 67 20 68 61 73 68 20 76 61  sponding hash va
4600: 6c 75 65 2e 0a 2a 2a 20 49 6e 20 65 63 68 6f 46  lue..** In echoF
4610: 69 6c 74 65 72 28 29 2c 20 63 6f 64 65 20 61 73  ilter(), code as
4620: 73 65 72 74 28 29 73 20 74 68 61 74 20 74 68 65  sert()s that the
4630: 20 73 75 70 70 6c 69 65 64 20 69 64 78 4e 75 6d   supplied idxNum
4640: 20 76 61 6c 75 65 20 69 73 0a 2a 2a 20 69 6e 64   value is.** ind
4650: 65 65 64 20 74 68 65 20 68 61 73 68 20 6f 66 20  eed the hash of 
4660: 74 68 65 20 73 75 70 70 6c 69 65 64 20 69 64 78  the supplied idx
4670: 53 74 72 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  Str..*/.static i
4680: 6e 74 20 68 61 73 68 53 74 72 69 6e 67 28 63 6f  nt hashString(co
4690: 6e 73 74 20 63 68 61 72 20 2a 7a 53 74 72 69 6e  nst char *zStrin
46a0: 67 29 7b 0a 20 20 75 33 32 20 76 61 6c 20 3d 20  g){.  u32 val = 
46b0: 30 3b 0a 20 20 69 6e 74 20 69 69 3b 0a 20 20 66  0;.  int ii;.  f
46c0: 6f 72 28 69 69 3d 30 3b 20 7a 53 74 72 69 6e 67  or(ii=0; zString
46d0: 5b 69 69 5d 3b 20 69 69 2b 2b 29 7b 0a 20 20 20  [ii]; ii++){.   
46e0: 20 76 61 6c 20 3d 20 28 76 61 6c 20 3c 3c 20 33   val = (val << 3
46f0: 29 20 2b 20 28 69 6e 74 29 7a 53 74 72 69 6e 67  ) + (int)zString
4700: 5b 69 69 5d 3b 0a 20 20 7d 0a 20 20 72 65 74 75  [ii];.  }.  retu
4710: 72 6e 20 28 69 6e 74 29 28 76 61 6c 26 30 78 37  rn (int)(val&0x7
4720: 66 66 66 66 66 66 66 29 3b 0a 7d 0a 0a 2f 2a 20  fffffff);.}../* 
4730: 0a 2a 2a 20 45 63 68 6f 20 76 69 72 74 75 61 6c  .** Echo virtual
4740: 20 74 61 62 6c 65 20 6d 6f 64 75 6c 65 20 78 46   table module xF
4750: 69 6c 74 65 72 20 6d 65 74 68 6f 64 2e 0a 2a 2f  ilter method..*/
4760: 0a 73 74 61 74 69 63 20 69 6e 74 20 65 63 68 6f  .static int echo
4770: 46 69 6c 74 65 72 28 0a 20 20 73 71 6c 69 74 65  Filter(.  sqlite
4780: 33 5f 76 74 61 62 5f 63 75 72 73 6f 72 20 2a 70  3_vtab_cursor *p
4790: 56 74 61 62 43 75 72 73 6f 72 2c 20 0a 20 20 69  VtabCursor, .  i
47a0: 6e 74 20 69 64 78 4e 75 6d 2c 20 63 6f 6e 73 74  nt idxNum, const
47b0: 20 63 68 61 72 20 2a 69 64 78 53 74 72 2c 0a 20   char *idxStr,. 
47c0: 20 69 6e 74 20 61 72 67 63 2c 20 73 71 6c 69 74   int argc, sqlit
47d0: 65 33 5f 76 61 6c 75 65 20 2a 2a 61 72 67 76 0a  e3_value **argv.
47e0: 29 7b 0a 20 20 69 6e 74 20 72 63 3b 0a 20 20 69  ){.  int rc;.  i
47f0: 6e 74 20 69 3b 0a 0a 20 20 65 63 68 6f 5f 63 75  nt i;..  echo_cu
4800: 72 73 6f 72 20 2a 70 43 75 72 20 3d 20 28 65 63  rsor *pCur = (ec
4810: 68 6f 5f 63 75 72 73 6f 72 20 2a 29 70 56 74 61  ho_cursor *)pVta
4820: 62 43 75 72 73 6f 72 3b 0a 20 20 65 63 68 6f 5f  bCursor;.  echo_
4830: 76 74 61 62 20 2a 70 56 74 61 62 20 3d 20 28 65  vtab *pVtab = (e
4840: 63 68 6f 5f 76 74 61 62 20 2a 29 70 56 74 61 62  cho_vtab *)pVtab
4850: 43 75 72 73 6f 72 2d 3e 70 56 74 61 62 3b 0a 20  Cursor->pVtab;. 
4860: 20 73 71 6c 69 74 65 33 20 2a 64 62 20 3d 20 70   sqlite3 *db = p
4870: 56 74 61 62 2d 3e 64 62 3b 0a 0a 20 20 69 66 28  Vtab->db;..  if(
4880: 20 73 69 6d 75 6c 61 74 65 56 74 61 62 45 72 72   simulateVtabErr
4890: 6f 72 28 70 56 74 61 62 2c 20 22 78 46 69 6c 74  or(pVtab, "xFilt
48a0: 65 72 22 29 20 29 7b 0a 20 20 20 20 72 65 74 75  er") ){.    retu
48b0: 72 6e 20 53 51 4c 49 54 45 5f 45 52 52 4f 52 3b  rn SQLITE_ERROR;
48c0: 0a 20 20 7d 0a 0a 20 20 2f 2a 20 43 68 65 63 6b  .  }..  /* Check
48d0: 20 74 68 61 74 20 69 64 78 4e 75 6d 20 6d 61 74   that idxNum mat
48e0: 63 68 65 73 20 69 64 78 53 74 72 20 2a 2f 0a 20  ches idxStr */. 
48f0: 20 61 73 73 65 72 74 28 20 69 64 78 4e 75 6d 3d   assert( idxNum=
4900: 3d 68 61 73 68 53 74 72 69 6e 67 28 69 64 78 53  =hashString(idxS
4910: 74 72 29 20 29 3b 0a 0a 20 20 2f 2a 20 4c 6f 67  tr) );..  /* Log
4920: 20 61 72 67 75 6d 65 6e 74 73 20 74 6f 20 74 68   arguments to th
4930: 65 20 3a 3a 65 63 68 6f 5f 6d 6f 64 75 6c 65 20  e ::echo_module 
4940: 54 63 6c 20 76 61 72 69 61 62 6c 65 20 2a 2f 0a  Tcl variable */.
4950: 20 20 61 70 70 65 6e 64 54 6f 45 63 68 6f 4d 6f    appendToEchoMo
4960: 64 75 6c 65 28 70 56 74 61 62 2d 3e 69 6e 74 65  dule(pVtab->inte
4970: 72 70 2c 20 22 78 46 69 6c 74 65 72 22 29 3b 0a  rp, "xFilter");.
4980: 20 20 61 70 70 65 6e 64 54 6f 45 63 68 6f 4d 6f    appendToEchoMo
4990: 64 75 6c 65 28 70 56 74 61 62 2d 3e 69 6e 74 65  dule(pVtab->inte
49a0: 72 70 2c 20 69 64 78 53 74 72 29 3b 0a 20 20 66  rp, idxStr);.  f
49b0: 6f 72 28 69 3d 30 3b 20 69 3c 61 72 67 63 3b 20  or(i=0; i<argc; 
49c0: 69 2b 2b 29 7b 0a 20 20 20 20 61 70 70 65 6e 64  i++){.    append
49d0: 54 6f 45 63 68 6f 4d 6f 64 75 6c 65 28 70 56 74  ToEchoModule(pVt
49e0: 61 62 2d 3e 69 6e 74 65 72 70 2c 20 28 63 6f 6e  ab->interp, (con
49f0: 73 74 20 63 68 61 72 2a 29 73 71 6c 69 74 65 33  st char*)sqlite3
4a00: 5f 76 61 6c 75 65 5f 74 65 78 74 28 61 72 67 76  _value_text(argv
4a10: 5b 69 5d 29 29 3b 0a 20 20 7d 0a 0a 20 20 73 71  [i]));.  }..  sq
4a20: 6c 69 74 65 33 5f 66 69 6e 61 6c 69 7a 65 28 70  lite3_finalize(p
4a30: 43 75 72 2d 3e 70 53 74 6d 74 29 3b 0a 20 20 70  Cur->pStmt);.  p
4a40: 43 75 72 2d 3e 70 53 74 6d 74 20 3d 20 30 3b 0a  Cur->pStmt = 0;.
4a50: 0a 20 20 2f 2a 20 50 72 65 70 61 72 65 20 74 68  .  /* Prepare th
4a60: 65 20 53 51 4c 20 73 74 61 74 65 6d 65 6e 74 20  e SQL statement 
4a70: 63 72 65 61 74 65 64 20 62 79 20 65 63 68 6f 42  created by echoB
4a80: 65 73 74 49 6e 64 65 78 20 61 6e 64 20 62 69 6e  estIndex and bin
4a90: 64 20 74 68 65 0a 20 20 2a 2a 20 72 75 6e 74 69  d the.  ** runti
4aa0: 6d 65 20 70 61 72 61 6d 65 74 65 72 73 20 70 61  me parameters pa
4ab0: 73 73 65 64 20 74 6f 20 74 68 69 73 20 66 75 6e  ssed to this fun
4ac0: 63 74 69 6f 6e 20 74 6f 20 69 74 2e 0a 20 20 2a  ction to it..  *
4ad0: 2f 0a 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33  /.  rc = sqlite3
4ae0: 5f 70 72 65 70 61 72 65 28 64 62 2c 20 69 64 78  _prepare(db, idx
4af0: 53 74 72 2c 20 2d 31 2c 20 26 70 43 75 72 2d 3e  Str, -1, &pCur->
4b00: 70 53 74 6d 74 2c 20 30 29 3b 0a 20 20 61 73 73  pStmt, 0);.  ass
4b10: 65 72 74 28 20 70 43 75 72 2d 3e 70 53 74 6d 74  ert( pCur->pStmt
4b20: 20 7c 7c 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f   || rc!=SQLITE_O
4b30: 4b 20 29 3b 0a 20 20 66 6f 72 28 69 3d 30 3b 20  K );.  for(i=0; 
4b40: 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26  rc==SQLITE_OK &&
4b50: 20 69 3c 61 72 67 63 3b 20 69 2b 2b 29 7b 0a 20   i<argc; i++){. 
4b60: 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f     rc = sqlite3_
4b70: 62 69 6e 64 5f 76 61 6c 75 65 28 70 43 75 72 2d  bind_value(pCur-
4b80: 3e 70 53 74 6d 74 2c 20 69 2b 31 2c 20 61 72 67  >pStmt, i+1, arg
4b90: 76 5b 69 5d 29 3b 0a 20 20 7d 0a 0a 20 20 2f 2a  v[i]);.  }..  /*
4ba0: 20 49 66 20 65 76 65 72 79 74 68 69 6e 67 20 77   If everything w
4bb0: 61 73 20 73 75 63 63 65 73 73 66 75 6c 2c 20 61  as successful, a
4bc0: 64 76 61 6e 63 65 20 74 6f 20 74 68 65 20 66 69  dvance to the fi
4bd0: 72 73 74 20 72 6f 77 20 6f 66 20 74 68 65 20 73  rst row of the s
4be0: 63 61 6e 20 2a 2f 0a 20 20 69 66 28 20 72 63 3d  can */.  if( rc=
4bf0: 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20  =SQLITE_OK ){.  
4c00: 20 20 72 63 20 3d 20 65 63 68 6f 4e 65 78 74 28    rc = echoNext(
4c10: 70 56 74 61 62 43 75 72 73 6f 72 29 3b 0a 20 20  pVtabCursor);.  
4c20: 7d 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a  }..  return rc;.
4c30: 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 41 20 68 65 6c 70  }.../*.** A help
4c40: 65 72 20 66 75 6e 63 74 69 6f 6e 20 75 73 65 64  er function used
4c50: 20 62 79 20 65 63 68 6f 55 70 64 61 74 65 28 29   by echoUpdate()
4c60: 20 61 6e 64 20 65 63 68 6f 42 65 73 74 49 6e 64   and echoBestInd
4c70: 65 78 28 29 20 66 6f 72 0a 2a 2a 20 6d 61 6e 69  ex() for.** mani
4c80: 70 75 6c 61 74 69 6e 67 20 73 74 72 69 6e 67 73  pulating strings
4c90: 20 69 6e 20 63 6f 6e 63 65 72 74 20 77 69 74 68   in concert with
4ca0: 20 74 68 65 20 73 71 6c 69 74 65 33 5f 6d 70 72   the sqlite3_mpr
4cb0: 69 6e 74 66 28 29 20 66 75 6e 63 74 69 6f 6e 2e  intf() function.
4cc0: 0a 2a 2a 0a 2a 2a 20 50 61 72 61 6d 65 74 65 72  .**.** Parameter
4cd0: 20 70 7a 53 74 72 20 70 6f 69 6e 74 73 20 74 6f   pzStr points to
4ce0: 20 61 20 70 6f 69 6e 74 65 72 20 74 6f 20 61 20   a pointer to a 
4cf0: 73 74 72 69 6e 67 20 61 6c 6c 6f 63 61 74 65 64  string allocated
4d00: 20 77 69 74 68 0a 2a 2a 20 73 71 6c 69 74 65 33   with.** sqlite3
4d10: 5f 6d 70 72 69 6e 74 66 2e 20 54 68 65 20 73 65  _mprintf. The se
4d20: 63 6f 6e 64 20 70 61 72 61 6d 65 74 65 72 2c 20  cond parameter, 
4d30: 7a 41 70 70 65 6e 64 2c 20 70 6f 69 6e 74 73 20  zAppend, points 
4d40: 74 6f 20 61 6e 6f 74 68 65 72 0a 2a 2a 20 73 74  to another.** st
4d50: 72 69 6e 67 2e 20 54 68 65 20 74 77 6f 20 73 74  ring. The two st
4d60: 72 69 6e 67 73 20 61 72 65 20 63 6f 6e 63 61 74  rings are concat
4d70: 65 6e 61 74 65 64 20 74 6f 67 65 74 68 65 72 20  enated together 
4d80: 61 6e 64 20 2a 70 7a 53 74 72 0a 2a 2a 20 73 65  and *pzStr.** se
4d90: 74 20 74 6f 20 70 6f 69 6e 74 20 61 74 20 74 68  t to point at th
4da0: 65 20 72 65 73 75 6c 74 2e 20 54 68 65 20 69 6e  e result. The in
4db0: 69 74 69 61 6c 20 62 75 66 66 65 72 20 70 6f 69  itial buffer poi
4dc0: 6e 74 65 64 20 74 6f 20 62 79 20 2a 70 7a 53 74  nted to by *pzSt
4dd0: 72 0a 2a 2a 20 69 73 20 64 65 61 6c 6c 6f 63 61  r.** is dealloca
4de0: 74 65 64 20 76 69 61 20 73 71 6c 69 74 65 33 5f  ted via sqlite3_
4df0: 66 72 65 65 28 29 2e 0a 2a 2a 0a 2a 2a 20 49 66  free()..**.** If
4e00: 20 74 68 65 20 74 68 69 72 64 20 61 72 67 75 6d   the third argum
4e10: 65 6e 74 2c 20 64 6f 46 72 65 65 2c 20 69 73 20  ent, doFree, is 
4e20: 74 72 75 65 2c 20 74 68 65 6e 20 73 71 6c 69 74  true, then sqlit
4e30: 65 33 5f 66 72 65 65 28 29 20 69 73 0a 2a 2a 20  e3_free() is.** 
4e40: 61 6c 73 6f 20 63 61 6c 6c 65 64 20 74 6f 20 66  also called to f
4e50: 72 65 65 20 74 68 65 20 62 75 66 66 65 72 20 70  ree the buffer p
4e60: 6f 69 6e 74 65 64 20 74 6f 20 62 79 20 7a 41 70  ointed to by zAp
4e70: 70 65 6e 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  pend..*/.static 
4e80: 76 6f 69 64 20 73 74 72 69 6e 67 5f 63 6f 6e 63  void string_conc
4e90: 61 74 28 63 68 61 72 20 2a 2a 70 7a 53 74 72 2c  at(char **pzStr,
4ea0: 20 63 68 61 72 20 2a 7a 41 70 70 65 6e 64 2c 20   char *zAppend, 
4eb0: 69 6e 74 20 64 6f 46 72 65 65 2c 20 69 6e 74 20  int doFree, int 
4ec0: 2a 70 52 63 29 7b 0a 20 20 63 68 61 72 20 2a 7a  *pRc){.  char *z
4ed0: 49 6e 20 3d 20 2a 70 7a 53 74 72 3b 0a 20 20 69  In = *pzStr;.  i
4ee0: 66 28 20 21 7a 41 70 70 65 6e 64 20 26 26 20 64  f( !zAppend && d
4ef0: 6f 46 72 65 65 20 26 26 20 2a 70 52 63 3d 3d 53  oFree && *pRc==S
4f00: 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
4f10: 2a 70 52 63 20 3d 20 53 51 4c 49 54 45 5f 4e 4f  *pRc = SQLITE_NO
4f20: 4d 45 4d 3b 0a 20 20 7d 0a 20 20 69 66 28 20 2a  MEM;.  }.  if( *
4f30: 70 52 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29  pRc!=SQLITE_OK )
4f40: 7b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72  {.    sqlite3_fr
4f50: 65 65 28 7a 49 6e 29 3b 0a 20 20 20 20 7a 49 6e  ee(zIn);.    zIn
4f60: 20 3d 20 30 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20   = 0;.  }else{. 
4f70: 20 20 20 69 66 28 20 7a 49 6e 20 29 7b 0a 20 20     if( zIn ){.  
4f80: 20 20 20 20 63 68 61 72 20 2a 7a 54 65 6d 70 20      char *zTemp 
4f90: 3d 20 7a 49 6e 3b 0a 20 20 20 20 20 20 7a 49 6e  = zIn;.      zIn
4fa0: 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e   = sqlite3_mprin
4fb0: 74 66 28 22 25 73 25 73 22 2c 20 7a 49 6e 2c 20  tf("%s%s", zIn, 
4fc0: 7a 41 70 70 65 6e 64 29 3b 0a 20 20 20 20 20 20  zAppend);.      
4fd0: 73 71 6c 69 74 65 33 5f 66 72 65 65 28 7a 54 65  sqlite3_free(zTe
4fe0: 6d 70 29 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a  mp);.    }else{.
4ff0: 20 20 20 20 20 20 7a 49 6e 20 3d 20 73 71 6c 69        zIn = sqli
5000: 74 65 33 5f 6d 70 72 69 6e 74 66 28 22 25 73 22  te3_mprintf("%s"
5010: 2c 20 7a 41 70 70 65 6e 64 29 3b 0a 20 20 20 20  , zAppend);.    
5020: 7d 0a 20 20 20 20 69 66 28 20 21 7a 49 6e 20 29  }.    if( !zIn )
5030: 7b 0a 20 20 20 20 20 20 2a 70 52 63 20 3d 20 53  {.      *pRc = S
5040: 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20  QLITE_NOMEM;.   
5050: 20 7d 0a 20 20 7d 0a 20 20 2a 70 7a 53 74 72 20   }.  }.  *pzStr 
5060: 3d 20 7a 49 6e 3b 0a 20 20 69 66 28 20 64 6f 46  = zIn;.  if( doF
5070: 72 65 65 20 29 7b 0a 20 20 20 20 73 71 6c 69 74  ree ){.    sqlit
5080: 65 33 5f 66 72 65 65 28 7a 41 70 70 65 6e 64 29  e3_free(zAppend)
5090: 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54  ;.  }.}../*.** T
50a0: 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 72 65 74  his function ret
50b0: 75 72 6e 73 20 61 20 70 6f 69 6e 74 65 72 20 74  urns a pointer t
50c0: 6f 20 61 6e 20 73 71 6c 69 74 65 33 5f 6d 61 6c  o an sqlite3_mal
50d0: 6c 6f 63 28 29 65 64 20 62 75 66 66 65 72 20 0a  loc()ed buffer .
50e0: 2a 2a 20 63 6f 6e 74 61 69 6e 69 6e 67 20 74 68  ** containing th
50f0: 65 20 73 65 6c 65 63 74 2d 6c 69 73 74 20 28 74  e select-list (t
5100: 68 65 20 74 68 69 6e 67 20 62 65 74 77 65 65 6e  he thing between
5110: 20 6b 65 79 77 6f 72 64 73 20 53 45 4c 45 43 54   keywords SELECT
5120: 20 61 6e 64 20 46 52 4f 4d 29 0a 2a 2a 20 74 6f   and FROM).** to
5130: 20 71 75 65 72 79 20 74 68 65 20 75 6e 64 65 72   query the under
5140: 6c 79 69 6e 67 20 72 65 61 6c 20 74 61 62 6c 65  lying real table
5150: 20 77 69 74 68 20 66 6f 72 20 74 68 65 20 73 63   with for the sc
5160: 61 6e 20 64 65 73 63 72 69 62 65 64 20 62 79 0a  an described by.
5170: 2a 2a 20 61 72 67 75 6d 65 6e 74 20 70 49 64 78  ** argument pIdx
5180: 49 6e 66 6f 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 74  Info..**.** If t
5190: 68 65 20 63 75 72 72 65 6e 74 20 53 51 4c 69 74  he current SQLit
51a0: 65 20 76 65 72 73 69 6f 6e 20 69 73 20 65 61 72  e version is ear
51b0: 6c 69 65 72 20 74 68 61 6e 20 33 2e 31 30 2e 30  lier than 3.10.0
51c0: 2c 20 74 68 69 73 20 69 73 20 6a 75 73 74 20 22  , this is just "
51d0: 2a 22 0a 2a 2a 20 28 73 65 6c 65 63 74 20 61 6c  *".** (select al
51e0: 6c 20 63 6f 6c 75 6d 6e 73 29 2e 20 4f 72 2c 20  l columns). Or, 
51f0: 66 6f 72 20 76 65 72 73 69 6f 6e 20 33 2e 31 30  for version 3.10
5200: 2e 30 20 61 6e 64 20 67 72 65 61 74 65 72 2c 20  .0 and greater, 
5210: 74 68 65 20 6c 69 73 74 20 6f 66 0a 2a 2a 20 63  the list of.** c
5220: 6f 6c 75 6d 6e 73 20 69 64 65 6e 74 69 66 69 65  olumns identifie
5230: 64 20 62 79 20 74 68 65 20 70 49 64 78 49 6e 66  d by the pIdxInf
5240: 6f 2d 3e 63 6f 6c 55 73 65 64 20 6d 61 73 6b 2e  o->colUsed mask.
5250: 0a 2a 2f 0a 73 74 61 74 69 63 20 63 68 61 72 20  .*/.static char 
5260: 2a 65 63 68 6f 53 65 6c 65 63 74 4c 69 73 74 28  *echoSelectList(
5270: 65 63 68 6f 5f 76 74 61 62 20 2a 70 54 61 62 2c  echo_vtab *pTab,
5280: 20 73 71 6c 69 74 65 33 5f 69 6e 64 65 78 5f 69   sqlite3_index_i
5290: 6e 66 6f 20 2a 70 49 64 78 49 6e 66 6f 29 7b 0a  nfo *pIdxInfo){.
52a0: 20 20 63 68 61 72 20 2a 7a 52 65 74 20 3d 20 30    char *zRet = 0
52b0: 3b 0a 20 20 69 66 28 20 73 71 6c 69 74 65 33 5f  ;.  if( sqlite3_
52c0: 6c 69 62 76 65 72 73 69 6f 6e 5f 6e 75 6d 62 65  libversion_numbe
52d0: 72 28 29 3c 33 30 31 30 30 30 30 20 29 7b 0a 20  r()<3010000 ){. 
52e0: 20 20 20 7a 52 65 74 20 3d 20 73 71 6c 69 74 65     zRet = sqlite
52f0: 33 5f 6d 70 72 69 6e 74 66 28 22 2c 20 2a 22 29  3_mprintf(", *")
5300: 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 69  ;.  }else{.    i
5310: 6e 74 20 69 3b 0a 20 20 20 20 66 6f 72 28 69 3d  nt i;.    for(i=
5320: 30 3b 20 69 3c 70 54 61 62 2d 3e 6e 43 6f 6c 3b  0; i<pTab->nCol;
5330: 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20 69 66 28   i++){.      if(
5340: 20 70 49 64 78 49 6e 66 6f 2d 3e 63 6f 6c 55 73   pIdxInfo->colUs
5350: 65 64 20 26 20 28 28 73 71 6c 69 74 65 33 5f 75  ed & ((sqlite3_u
5360: 69 6e 74 36 34 29 31 20 3c 3c 20 28 69 3e 3d 36  int64)1 << (i>=6
5370: 33 20 3f 20 36 33 20 3a 20 69 29 29 20 29 7b 0a  3 ? 63 : i)) ){.
5380: 20 20 20 20 20 20 20 20 7a 52 65 74 20 3d 20 73          zRet = s
5390: 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 22  qlite3_mprintf("
53a0: 25 7a 2c 20 25 73 22 2c 20 7a 52 65 74 2c 20 70  %z, %s", zRet, p
53b0: 54 61 62 2d 3e 61 43 6f 6c 5b 69 5d 29 3b 0a 20  Tab->aCol[i]);. 
53c0: 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20       }else{.    
53d0: 20 20 20 20 7a 52 65 74 20 3d 20 73 71 6c 69 74      zRet = sqlit
53e0: 65 33 5f 6d 70 72 69 6e 74 66 28 22 25 7a 2c 20  e3_mprintf("%z, 
53f0: 4e 55 4c 4c 22 2c 20 7a 52 65 74 29 3b 0a 20 20  NULL", zRet);.  
5400: 20 20 20 20 7d 0a 20 20 20 20 20 20 69 66 28 20      }.      if( 
5410: 21 7a 52 65 74 20 29 20 62 72 65 61 6b 3b 0a 20  !zRet ) break;. 
5420: 20 20 20 7d 0a 20 20 7d 0a 20 20 72 65 74 75 72     }.  }.  retur
5430: 6e 20 7a 52 65 74 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  n zRet;.}../*.**
5440: 20 54 68 65 20 65 63 68 6f 20 6d 6f 64 75 6c 65   The echo module
5450: 20 69 6d 70 6c 65 6d 65 6e 74 73 20 74 68 65 20   implements the 
5460: 73 75 62 73 65 74 20 6f 66 20 71 75 65 72 79 20  subset of query 
5470: 63 6f 6e 73 74 72 61 69 6e 74 73 20 61 6e 64 20  constraints and 
5480: 73 6f 72 74 0a 2a 2a 20 6f 72 64 65 72 73 20 74  sort.** orders t
5490: 68 61 74 20 6d 61 79 20 74 61 6b 65 20 61 64 76  hat may take adv
54a0: 61 6e 74 61 67 65 20 6f 66 20 53 51 4c 69 74 65  antage of SQLite
54b0: 20 69 6e 64 69 63 65 73 20 6f 6e 20 74 68 65 20   indices on the 
54c0: 75 6e 64 65 72 6c 79 69 6e 67 0a 2a 2a 20 72 65  underlying.** re
54d0: 61 6c 20 74 61 62 6c 65 2e 20 46 6f 72 20 65 78  al table. For ex
54e0: 61 6d 70 6c 65 2c 20 69 66 20 74 68 65 20 72 65  ample, if the re
54f0: 61 6c 20 74 61 62 6c 65 20 69 73 20 64 65 63 6c  al table is decl
5500: 61 72 65 64 20 61 73 3a 0a 2a 2a 0a 2a 2a 20 20  ared as:.**.**  
5510: 20 20 20 43 52 45 41 54 45 20 54 41 42 4c 45 20     CREATE TABLE 
5520: 72 65 61 6c 28 61 2c 20 62 2c 20 63 29 3b 0a 2a  real(a, b, c);.*
5530: 2a 20 20 20 20 20 43 52 45 41 54 45 20 49 4e 44  *     CREATE IND
5540: 45 58 20 72 65 61 6c 5f 69 6e 64 65 78 20 4f 4e  EX real_index ON
5550: 20 72 65 61 6c 28 62 29 3b 0a 2a 2a 0a 2a 2a 20   real(b);.**.** 
5560: 74 68 65 6e 20 74 68 65 20 65 63 68 6f 20 6d 6f  then the echo mo
5570: 64 75 6c 65 20 68 61 6e 64 6c 65 73 20 57 48 45  dule handles WHE
5580: 52 45 20 6f 72 20 4f 52 44 45 52 20 42 59 20 63  RE or ORDER BY c
5590: 6c 61 75 73 65 73 20 74 68 61 74 20 72 65 66 65  lauses that refe
55a0: 72 0a 2a 2a 20 74 6f 20 74 68 65 20 63 6f 6c 75  r.** to the colu
55b0: 6d 6e 20 22 62 22 2c 20 62 75 74 20 6e 6f 74 20  mn "b", but not 
55c0: 22 61 22 20 6f 72 20 22 63 22 2e 20 49 66 20 61  "a" or "c". If a
55d0: 20 6d 75 6c 74 69 2d 63 6f 6c 75 6d 6e 20 69 6e   multi-column in
55e0: 64 65 78 20 69 73 0a 2a 2a 20 70 72 65 73 65 6e  dex is.** presen
55f0: 74 2c 20 6f 6e 6c 79 20 69 74 73 20 6c 65 66 74  t, only its left
5600: 20 6d 6f 73 74 20 63 6f 6c 75 6d 6e 20 69 73 20   most column is 
5610: 63 6f 6e 73 69 64 65 72 65 64 2e 20 0a 2a 2a 0a  considered. .**.
5620: 2a 2a 20 54 68 69 73 20 78 42 65 73 74 49 6e 64  ** This xBestInd
5630: 65 78 20 6d 65 74 68 6f 64 20 65 6e 63 6f 64 65  ex method encode
5640: 73 20 74 68 65 20 70 72 6f 70 6f 73 65 64 20 73  s the proposed s
5650: 65 61 72 63 68 20 73 74 72 61 74 65 67 79 20 61  earch strategy a
5660: 73 0a 2a 2a 20 61 6e 20 53 51 4c 20 71 75 65 72  s.** an SQL quer
5670: 79 20 6f 6e 20 74 68 65 20 72 65 61 6c 20 74 61  y on the real ta
5680: 62 6c 65 20 75 6e 64 65 72 6c 79 69 6e 67 20 74  ble underlying t
5690: 68 65 20 76 69 72 74 75 61 6c 20 65 63 68 6f 20  he virtual echo 
56a0: 6d 6f 64 75 6c 65 20 0a 2a 2a 20 74 61 62 6c 65  module .** table
56b0: 20 61 6e 64 20 73 74 6f 72 65 73 20 74 68 65 20   and stores the 
56c0: 71 75 65 72 79 20 69 6e 20 73 71 6c 69 74 65 33  query in sqlite3
56d0: 5f 69 6e 64 65 78 5f 69 6e 66 6f 2e 69 64 78 53  _index_info.idxS
56e0: 74 72 2e 20 54 68 65 20 53 51 4c 0a 2a 2a 20 73  tr. The SQL.** s
56f0: 74 61 74 65 6d 65 6e 74 20 69 73 20 6f 66 20 74  tatement is of t
5700: 68 65 20 66 6f 72 6d 3a 0a 2a 2a 0a 2a 2a 20 20  he form:.**.**  
5710: 20 53 45 4c 45 43 54 20 72 6f 77 69 64 2c 20 2a   SELECT rowid, *
5720: 20 46 52 4f 4d 20 3c 72 65 61 6c 2d 74 61 62 6c   FROM <real-tabl
5730: 65 3e 20 3f 3c 77 68 65 72 65 2d 63 6c 61 75 73  e> ?<where-claus
5740: 65 3e 3f 20 3f 3c 6f 72 64 65 72 2d 62 79 2d 63  e>? ?<order-by-c
5750: 6c 61 75 73 65 3e 3f 0a 2a 2a 0a 2a 2a 20 77 68  lause>?.**.** wh
5760: 65 72 65 20 74 68 65 20 3c 77 68 65 72 65 2d 63  ere the <where-c
5770: 6c 61 75 73 65 3e 20 61 6e 64 20 3c 6f 72 64 65  lause> and <orde
5780: 72 2d 62 79 2d 63 6c 61 75 73 65 3e 20 61 72 65  r-by-clause> are
5790: 20 64 65 74 65 72 6d 69 6e 65 64 0a 2a 2a 20 62   determined.** b
57a0: 79 20 74 68 65 20 63 6f 6e 74 65 6e 74 73 20 6f  y the contents o
57b0: 66 20 74 68 65 20 73 74 72 75 63 74 75 72 65 20  f the structure 
57c0: 70 6f 69 6e 74 65 64 20 74 6f 20 62 79 20 74 68  pointed to by th
57d0: 65 20 70 49 64 78 49 6e 66 6f 20 61 72 67 75 6d  e pIdxInfo argum
57e0: 65 6e 74 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  ent..*/.static i
57f0: 6e 74 20 65 63 68 6f 42 65 73 74 49 6e 64 65 78  nt echoBestIndex
5800: 28 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 74  (sqlite3_vtab *t
5810: 61 62 2c 20 73 71 6c 69 74 65 33 5f 69 6e 64 65  ab, sqlite3_inde
5820: 78 5f 69 6e 66 6f 20 2a 70 49 64 78 49 6e 66 6f  x_info *pIdxInfo
5830: 29 7b 0a 20 20 69 6e 74 20 69 69 3b 0a 20 20 63  ){.  int ii;.  c
5840: 68 61 72 20 2a 7a 51 75 65 72 79 20 3d 20 30 3b  har *zQuery = 0;
5850: 0a 20 20 63 68 61 72 20 2a 7a 43 6f 6c 20 3d 20  .  char *zCol = 
5860: 30 3b 0a 20 20 63 68 61 72 20 2a 7a 4e 65 77 3b  0;.  char *zNew;
5870: 0a 20 20 69 6e 74 20 6e 41 72 67 20 3d 20 30 3b  .  int nArg = 0;
5880: 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a  .  const char *z
5890: 53 65 70 20 3d 20 22 57 48 45 52 45 22 3b 0a 20  Sep = "WHERE";. 
58a0: 20 65 63 68 6f 5f 76 74 61 62 20 2a 70 56 74 61   echo_vtab *pVta
58b0: 62 20 3d 20 28 65 63 68 6f 5f 76 74 61 62 20 2a  b = (echo_vtab *
58c0: 29 74 61 62 3b 0a 20 20 73 71 6c 69 74 65 33 5f  )tab;.  sqlite3_
58d0: 73 74 6d 74 20 2a 70 53 74 6d 74 20 3d 20 30 3b  stmt *pStmt = 0;
58e0: 0a 20 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69  .  Tcl_Interp *i
58f0: 6e 74 65 72 70 20 3d 20 70 56 74 61 62 2d 3e 69  nterp = pVtab->i
5900: 6e 74 65 72 70 3b 0a 0a 20 20 69 6e 74 20 6e 52  nterp;..  int nR
5910: 6f 77 20 3d 20 30 3b 0a 20 20 69 6e 74 20 75 73  ow = 0;.  int us
5920: 65 49 64 78 20 3d 20 30 3b 0a 20 20 69 6e 74 20  eIdx = 0;.  int 
5930: 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a  rc = SQLITE_OK;.
5940: 20 20 69 6e 74 20 75 73 65 43 6f 73 74 20 3d 20    int useCost = 
5950: 30 3b 0a 20 20 64 6f 75 62 6c 65 20 63 6f 73 74  0;.  double cost
5960: 20 3d 20 30 3b 0a 20 20 69 6e 74 20 69 73 49 67   = 0;.  int isIg
5970: 6e 6f 72 65 55 73 61 62 6c 65 20 3d 20 30 3b 0a  noreUsable = 0;.
5980: 20 20 69 66 28 20 54 63 6c 5f 47 65 74 56 61 72    if( Tcl_GetVar
5990: 28 69 6e 74 65 72 70 2c 20 22 65 63 68 6f 5f 6d  (interp, "echo_m
59a0: 6f 64 75 6c 65 5f 69 67 6e 6f 72 65 5f 75 73 61  odule_ignore_usa
59b0: 62 6c 65 22 2c 20 54 43 4c 5f 47 4c 4f 42 41 4c  ble", TCL_GLOBAL
59c0: 5f 4f 4e 4c 59 29 20 29 7b 0a 20 20 20 20 69 73  _ONLY) ){.    is
59d0: 49 67 6e 6f 72 65 55 73 61 62 6c 65 20 3d 20 31  IgnoreUsable = 1
59e0: 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 73 69 6d  ;.  }..  if( sim
59f0: 75 6c 61 74 65 56 74 61 62 45 72 72 6f 72 28 70  ulateVtabError(p
5a00: 56 74 61 62 2c 20 22 78 42 65 73 74 49 6e 64 65  Vtab, "xBestInde
5a10: 78 22 29 20 29 7b 0a 20 20 20 20 72 65 74 75 72  x") ){.    retur
5a20: 6e 20 53 51 4c 49 54 45 5f 45 52 52 4f 52 3b 0a  n SQLITE_ERROR;.
5a30: 20 20 7d 0a 0a 20 20 2f 2a 20 44 65 74 65 72 6d    }..  /* Determ
5a40: 69 6e 65 20 74 68 65 20 6e 75 6d 62 65 72 20 6f  ine the number o
5a50: 66 20 72 6f 77 73 20 69 6e 20 74 68 65 20 74 61  f rows in the ta
5a60: 62 6c 65 20 61 6e 64 20 73 74 6f 72 65 20 74 68  ble and store th
5a70: 69 73 20 76 61 6c 75 65 20 69 6e 20 6c 6f 63 61  is value in loca
5a80: 6c 0a 20 20 2a 2a 20 76 61 72 69 61 62 6c 65 20  l.  ** variable 
5a90: 6e 52 6f 77 2e 20 54 68 65 20 27 65 73 74 69 6d  nRow. The 'estim
5aa0: 61 74 65 64 2d 63 6f 73 74 27 20 6f 66 20 74 68  ated-cost' of th
5ab0: 65 20 73 63 61 6e 20 77 69 6c 6c 20 62 65 20 74  e scan will be t
5ac0: 68 65 20 6e 75 6d 62 65 72 20 6f 66 0a 20 20 2a  he number of.  *
5ad0: 2a 20 72 6f 77 73 20 69 6e 20 74 68 65 20 74 61  * rows in the ta
5ae0: 62 6c 65 20 66 6f 72 20 61 20 6c 69 6e 65 61 72  ble for a linear
5af0: 20 73 63 61 6e 2c 20 6f 72 20 74 68 65 20 6c 6f   scan, or the lo
5b00: 67 20 28 62 61 73 65 20 32 29 20 6f 66 20 74 68  g (base 2) of th
5b10: 65 20 0a 20 20 2a 2a 20 6e 75 6d 62 65 72 20 6f  e .  ** number o
5b20: 66 20 72 6f 77 73 20 69 66 20 74 68 65 20 70 72  f rows if the pr
5b30: 6f 70 6f 73 65 64 20 73 63 61 6e 20 75 73 65 73  oposed scan uses
5b40: 20 61 6e 20 69 6e 64 65 78 2e 20 20 0a 20 20 2a   an index.  .  *
5b50: 2f 0a 20 20 69 66 28 20 54 63 6c 5f 47 65 74 56  /.  if( Tcl_GetV
5b60: 61 72 28 69 6e 74 65 72 70 2c 20 22 65 63 68 6f  ar(interp, "echo
5b70: 5f 6d 6f 64 75 6c 65 5f 63 6f 73 74 22 2c 20 54  _module_cost", T
5b80: 43 4c 5f 47 4c 4f 42 41 4c 5f 4f 4e 4c 59 29 20  CL_GLOBAL_ONLY) 
5b90: 29 7b 0a 20 20 20 20 63 6f 73 74 20 3d 20 61 74  ){.    cost = at
5ba0: 6f 66 28 54 63 6c 5f 47 65 74 56 61 72 28 69 6e  of(Tcl_GetVar(in
5bb0: 74 65 72 70 2c 20 22 65 63 68 6f 5f 6d 6f 64 75  terp, "echo_modu
5bc0: 6c 65 5f 63 6f 73 74 22 2c 20 54 43 4c 5f 47 4c  le_cost", TCL_GL
5bd0: 4f 42 41 4c 5f 4f 4e 4c 59 29 29 3b 0a 20 20 20  OBAL_ONLY));.   
5be0: 20 75 73 65 43 6f 73 74 20 3d 20 31 3b 0a 20 20   useCost = 1;.  
5bf0: 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20 7a 51 75  } else {.    zQu
5c00: 65 72 79 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70  ery = sqlite3_mp
5c10: 72 69 6e 74 66 28 22 53 45 4c 45 43 54 20 63 6f  rintf("SELECT co
5c20: 75 6e 74 28 2a 29 20 46 52 4f 4d 20 25 51 22 2c  unt(*) FROM %Q",
5c30: 20 70 56 74 61 62 2d 3e 7a 54 61 62 6c 65 4e 61   pVtab->zTableNa
5c40: 6d 65 29 3b 0a 20 20 20 20 69 66 28 20 21 7a 51  me);.    if( !zQ
5c50: 75 65 72 79 20 29 7b 0a 20 20 20 20 20 20 72 65  uery ){.      re
5c60: 74 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45  turn SQLITE_NOME
5c70: 4d 3b 0a 20 20 20 20 7d 0a 20 20 20 20 72 63 20  M;.    }.    rc 
5c80: 3d 20 73 71 6c 69 74 65 33 5f 70 72 65 70 61 72  = sqlite3_prepar
5c90: 65 28 70 56 74 61 62 2d 3e 64 62 2c 20 7a 51 75  e(pVtab->db, zQu
5ca0: 65 72 79 2c 20 2d 31 2c 20 26 70 53 74 6d 74 2c  ery, -1, &pStmt,
5cb0: 20 30 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33   0);.    sqlite3
5cc0: 5f 66 72 65 65 28 7a 51 75 65 72 79 29 3b 0a 20  _free(zQuery);. 
5cd0: 20 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54     if( rc!=SQLIT
5ce0: 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 72 65  E_OK ){.      re
5cf0: 74 75 72 6e 20 72 63 3b 0a 20 20 20 20 7d 0a 20  turn rc;.    }. 
5d00: 20 20 20 73 71 6c 69 74 65 33 5f 73 74 65 70 28     sqlite3_step(
5d10: 70 53 74 6d 74 29 3b 0a 20 20 20 20 6e 52 6f 77  pStmt);.    nRow
5d20: 20 3d 20 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d   = sqlite3_colum
5d30: 6e 5f 69 6e 74 28 70 53 74 6d 74 2c 20 30 29 3b  n_int(pStmt, 0);
5d40: 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65  .    rc = sqlite
5d50: 33 5f 66 69 6e 61 6c 69 7a 65 28 70 53 74 6d 74  3_finalize(pStmt
5d60: 29 3b 0a 20 20 20 20 69 66 28 20 72 63 21 3d 53  );.    if( rc!=S
5d70: 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
5d80: 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 20 20 20    return rc;.   
5d90: 20 7d 0a 20 20 7d 0a 0a 20 20 7a 43 6f 6c 20 3d   }.  }..  zCol =
5da0: 20 65 63 68 6f 53 65 6c 65 63 74 4c 69 73 74 28   echoSelectList(
5db0: 70 56 74 61 62 2c 20 70 49 64 78 49 6e 66 6f 29  pVtab, pIdxInfo)
5dc0: 3b 0a 20 20 69 66 28 20 21 7a 43 6f 6c 20 29 20  ;.  if( !zCol ) 
5dd0: 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f  return SQLITE_NO
5de0: 4d 45 4d 3b 0a 20 20 7a 51 75 65 72 79 20 3d 20  MEM;.  zQuery = 
5df0: 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28  sqlite3_mprintf(
5e00: 22 53 45 4c 45 43 54 20 72 6f 77 69 64 25 7a 20  "SELECT rowid%z 
5e10: 46 52 4f 4d 20 25 51 22 2c 20 7a 43 6f 6c 2c 20  FROM %Q", zCol, 
5e20: 70 56 74 61 62 2d 3e 7a 54 61 62 6c 65 4e 61 6d  pVtab->zTableNam
5e30: 65 29 3b 0a 20 20 69 66 28 20 21 7a 51 75 65 72  e);.  if( !zQuer
5e40: 79 20 29 20 72 65 74 75 72 6e 20 53 51 4c 49 54  y ) return SQLIT
5e50: 45 5f 4e 4f 4d 45 4d 3b 0a 0a 20 20 66 6f 72 28  E_NOMEM;..  for(
5e60: 69 69 3d 30 3b 20 69 69 3c 70 49 64 78 49 6e 66  ii=0; ii<pIdxInf
5e70: 6f 2d 3e 6e 43 6f 6e 73 74 72 61 69 6e 74 3b 20  o->nConstraint; 
5e80: 69 69 2b 2b 29 7b 0a 20 20 20 20 63 6f 6e 73 74  ii++){.    const
5e90: 20 73 74 72 75 63 74 20 73 71 6c 69 74 65 33 5f   struct sqlite3_
5ea0: 69 6e 64 65 78 5f 63 6f 6e 73 74 72 61 69 6e 74  index_constraint
5eb0: 20 2a 70 43 6f 6e 73 74 72 61 69 6e 74 3b 0a 20   *pConstraint;. 
5ec0: 20 20 20 73 74 72 75 63 74 20 73 71 6c 69 74 65     struct sqlite
5ed0: 33 5f 69 6e 64 65 78 5f 63 6f 6e 73 74 72 61 69  3_index_constrai
5ee0: 6e 74 5f 75 73 61 67 65 20 2a 70 55 73 61 67 65  nt_usage *pUsage
5ef0: 3b 0a 20 20 20 20 69 6e 74 20 69 43 6f 6c 3b 0a  ;.    int iCol;.
5f00: 0a 20 20 20 20 70 43 6f 6e 73 74 72 61 69 6e 74  .    pConstraint
5f10: 20 3d 20 26 70 49 64 78 49 6e 66 6f 2d 3e 61 43   = &pIdxInfo->aC
5f20: 6f 6e 73 74 72 61 69 6e 74 5b 69 69 5d 3b 0a 20  onstraint[ii];. 
5f30: 20 20 20 70 55 73 61 67 65 20 3d 20 26 70 49 64     pUsage = &pId
5f40: 78 49 6e 66 6f 2d 3e 61 43 6f 6e 73 74 72 61 69  xInfo->aConstrai
5f50: 6e 74 55 73 61 67 65 5b 69 69 5d 3b 0a 0a 20 20  ntUsage[ii];..  
5f60: 20 20 69 66 28 20 21 69 73 49 67 6e 6f 72 65 55    if( !isIgnoreU
5f70: 73 61 62 6c 65 20 26 26 20 21 70 43 6f 6e 73 74  sable && !pConst
5f80: 72 61 69 6e 74 2d 3e 75 73 61 62 6c 65 20 29 20  raint->usable ) 
5f90: 63 6f 6e 74 69 6e 75 65 3b 0a 0a 20 20 20 20 69  continue;..    i
5fa0: 43 6f 6c 20 3d 20 70 43 6f 6e 73 74 72 61 69 6e  Col = pConstrain
5fb0: 74 2d 3e 69 43 6f 6c 75 6d 6e 3b 0a 20 20 20 20  t->iColumn;.    
5fc0: 69 66 28 20 69 43 6f 6c 3c 30 20 7c 7c 20 70 56  if( iCol<0 || pV
5fd0: 74 61 62 2d 3e 61 49 6e 64 65 78 5b 69 43 6f 6c  tab->aIndex[iCol
5fe0: 5d 20 29 7b 0a 20 20 20 20 20 20 63 68 61 72 20  ] ){.      char 
5ff0: 2a 7a 4e 65 77 43 6f 6c 20 3d 20 69 43 6f 6c 3e  *zNewCol = iCol>
6000: 3d 30 20 3f 20 70 56 74 61 62 2d 3e 61 43 6f 6c  =0 ? pVtab->aCol
6010: 5b 69 43 6f 6c 5d 20 3a 20 22 72 6f 77 69 64 22  [iCol] : "rowid"
6020: 3b 0a 20 20 20 20 20 20 63 68 61 72 20 2a 7a 4f  ;.      char *zO
6030: 70 20 3d 20 30 3b 0a 20 20 20 20 20 20 75 73 65  p = 0;.      use
6040: 49 64 78 20 3d 20 31 3b 0a 20 20 20 20 20 20 73  Idx = 1;.      s
6050: 77 69 74 63 68 28 20 70 43 6f 6e 73 74 72 61 69  witch( pConstrai
6060: 6e 74 2d 3e 6f 70 20 29 7b 0a 20 20 20 20 20 20  nt->op ){.      
6070: 20 20 63 61 73 65 20 53 51 4c 49 54 45 5f 49 4e    case SQLITE_IN
6080: 44 45 58 5f 43 4f 4e 53 54 52 41 49 4e 54 5f 45  DEX_CONSTRAINT_E
6090: 51 3a 0a 20 20 20 20 20 20 20 20 20 20 7a 4f 70  Q:.          zOp
60a0: 20 3d 20 22 3d 22 3b 20 62 72 65 61 6b 3b 0a 20   = "="; break;. 
60b0: 20 20 20 20 20 20 20 63 61 73 65 20 53 51 4c 49         case SQLI
60c0: 54 45 5f 49 4e 44 45 58 5f 43 4f 4e 53 54 52 41  TE_INDEX_CONSTRA
60d0: 49 4e 54 5f 4c 54 3a 0a 20 20 20 20 20 20 20 20  INT_LT:.        
60e0: 20 20 7a 4f 70 20 3d 20 22 3c 22 3b 20 62 72 65    zOp = "<"; bre
60f0: 61 6b 3b 0a 20 20 20 20 20 20 20 20 63 61 73 65  ak;.        case
6100: 20 53 51 4c 49 54 45 5f 49 4e 44 45 58 5f 43 4f   SQLITE_INDEX_CO
6110: 4e 53 54 52 41 49 4e 54 5f 47 54 3a 0a 20 20 20  NSTRAINT_GT:.   
6120: 20 20 20 20 20 20 20 7a 4f 70 20 3d 20 22 3e 22         zOp = ">"
6130: 3b 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 20  ; break;.       
6140: 20 63 61 73 65 20 53 51 4c 49 54 45 5f 49 4e 44   case SQLITE_IND
6150: 45 58 5f 43 4f 4e 53 54 52 41 49 4e 54 5f 4c 45  EX_CONSTRAINT_LE
6160: 3a 0a 20 20 20 20 20 20 20 20 20 20 7a 4f 70 20  :.          zOp 
6170: 3d 20 22 3c 3d 22 3b 20 62 72 65 61 6b 3b 0a 20  = "<="; break;. 
6180: 20 20 20 20 20 20 20 63 61 73 65 20 53 51 4c 49         case SQLI
6190: 54 45 5f 49 4e 44 45 58 5f 43 4f 4e 53 54 52 41  TE_INDEX_CONSTRA
61a0: 49 4e 54 5f 47 45 3a 0a 20 20 20 20 20 20 20 20  INT_GE:.        
61b0: 20 20 7a 4f 70 20 3d 20 22 3e 3d 22 3b 20 62 72    zOp = ">="; br
61c0: 65 61 6b 3b 0a 20 20 20 20 20 20 20 20 63 61 73  eak;.        cas
61d0: 65 20 53 51 4c 49 54 45 5f 49 4e 44 45 58 5f 43  e SQLITE_INDEX_C
61e0: 4f 4e 53 54 52 41 49 4e 54 5f 4d 41 54 43 48 3a  ONSTRAINT_MATCH:
61f0: 0a 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50 75  .          /* Pu
6200: 72 70 6f 73 65 6c 79 20 74 72 61 6e 73 6c 61 74  rposely translat
6210: 65 20 74 68 65 20 4d 41 54 43 48 20 6f 70 65 72  e the MATCH oper
6220: 61 74 6f 72 20 69 6e 74 6f 20 61 20 4c 49 4b 45  ator into a LIKE
6230: 2c 20 77 68 69 63 68 0a 20 20 20 20 20 20 20 20  , which.        
6240: 20 20 2a 2a 20 77 69 6c 6c 20 62 65 20 75 73 65    ** will be use
6250: 64 20 62 79 20 74 68 65 20 6e 65 78 74 20 62 6c  d by the next bl
6260: 6f 63 6b 20 6f 66 20 63 6f 64 65 20 74 6f 20 63  ock of code to c
6270: 6f 6e 73 74 72 75 63 74 20 61 20 6e 65 77 0a 20  onstruct a new. 
6280: 20 20 20 20 20 20 20 20 20 2a 2a 20 71 75 65 72           ** quer
6290: 79 2e 20 20 49 74 20 73 68 6f 75 6c 64 20 61 6c  y.  It should al
62a0: 73 6f 20 62 65 20 6e 6f 74 65 64 20 68 65 72 65  so be noted here
62b0: 20 74 68 61 74 20 74 68 65 20 6e 65 78 74 20 62   that the next b
62c0: 6c 6f 63 6b 0a 20 20 20 20 20 20 20 20 20 20 2a  lock.          *
62d0: 2a 20 6f 66 20 63 6f 64 65 20 72 65 71 75 69 72  * of code requir
62e0: 65 73 20 74 68 65 20 66 69 72 73 74 20 6c 65 74  es the first let
62f0: 74 65 72 20 6f 66 20 74 68 69 73 20 6f 70 65 72  ter of this oper
6300: 61 74 6f 72 20 74 6f 20 62 65 0a 20 20 20 20 20  ator to be.     
6310: 20 20 20 20 20 2a 2a 20 69 6e 20 75 70 70 65 72       ** in upper
6320: 2d 63 61 73 65 20 74 6f 20 74 72 69 67 67 65 72  -case to trigger
6330: 20 74 68 65 20 73 70 65 63 69 61 6c 20 4d 41 54   the special MAT
6340: 43 48 20 68 61 6e 64 6c 69 6e 67 20 28 69 2e 65  CH handling (i.e
6350: 2e 0a 20 20 20 20 20 20 20 20 20 20 2a 2a 20 77  ..          ** w
6360: 72 61 70 70 69 6e 67 20 74 68 65 20 62 6f 75 6e  rapping the boun
6370: 64 20 70 61 72 61 6d 65 74 65 72 20 77 69 74 68  d parameter with
6380: 20 6c 69 74 65 72 61 6c 20 27 25 27 73 29 2e 0a   literal '%'s)..
6390: 20 20 20 20 20 20 20 20 20 20 2a 2f 0a 20 20 20            */.   
63a0: 20 20 20 20 20 20 20 7a 4f 70 20 3d 20 22 4c 49         zOp = "LI
63b0: 4b 45 22 3b 20 62 72 65 61 6b 3b 0a 20 20 20 20  KE"; break;.    
63c0: 20 20 20 20 63 61 73 65 20 53 51 4c 49 54 45 5f      case SQLITE_
63d0: 49 4e 44 45 58 5f 43 4f 4e 53 54 52 41 49 4e 54  INDEX_CONSTRAINT
63e0: 5f 4c 49 4b 45 3a 0a 20 20 20 20 20 20 20 20 20  _LIKE:.         
63f0: 20 7a 4f 70 20 3d 20 22 6c 69 6b 65 22 3b 20 62   zOp = "like"; b
6400: 72 65 61 6b 3b 0a 20 20 20 20 20 20 20 20 63 61  reak;.        ca
6410: 73 65 20 53 51 4c 49 54 45 5f 49 4e 44 45 58 5f  se SQLITE_INDEX_
6420: 43 4f 4e 53 54 52 41 49 4e 54 5f 47 4c 4f 42 3a  CONSTRAINT_GLOB:
6430: 0a 20 20 20 20 20 20 20 20 20 20 7a 4f 70 20 3d  .          zOp =
6440: 20 22 67 6c 6f 62 22 3b 20 62 72 65 61 6b 3b 0a   "glob"; break;.
6450: 20 20 20 20 20 20 20 20 63 61 73 65 20 53 51 4c          case SQL
6460: 49 54 45 5f 49 4e 44 45 58 5f 43 4f 4e 53 54 52  ITE_INDEX_CONSTR
6470: 41 49 4e 54 5f 52 45 47 45 58 50 3a 0a 20 20 20  AINT_REGEXP:.   
6480: 20 20 20 20 20 20 20 7a 4f 70 20 3d 20 22 72 65         zOp = "re
6490: 67 65 78 70 22 3b 20 62 72 65 61 6b 3b 0a 20 20  gexp"; break;.  
64a0: 20 20 20 20 7d 0a 20 20 20 20 20 20 69 66 28 20      }.      if( 
64b0: 7a 4f 70 20 29 7b 0a 20 20 20 20 20 20 20 20 69  zOp ){.        i
64c0: 66 28 20 7a 4f 70 5b 30 5d 3d 3d 27 4c 27 20 29  f( zOp[0]=='L' )
64d0: 7b 0a 20 20 20 20 20 20 20 20 20 20 7a 4e 65 77  {.          zNew
64e0: 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e   = sqlite3_mprin
64f0: 74 66 28 22 20 25 73 20 25 73 20 4c 49 4b 45 20  tf(" %s %s LIKE 
6500: 28 53 45 4c 45 43 54 20 27 25 25 27 7c 7c 3f 7c  (SELECT '%%'||?|
6510: 7c 27 25 25 27 29 22 2c 20 0a 20 20 20 20 20 20  |'%%')", .      
6520: 20 20 20 20 20 20 20 20 7a 53 65 70 2c 20 7a 4e          zSep, zN
6530: 65 77 43 6f 6c 29 3b 0a 20 20 20 20 20 20 20 20  ewCol);.        
6540: 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20 20 20 20  } else {.       
6550: 20 20 20 7a 4e 65 77 20 3d 20 73 71 6c 69 74 65     zNew = sqlite
6560: 33 5f 6d 70 72 69 6e 74 66 28 22 20 25 73 20 25  3_mprintf(" %s %
6570: 73 20 25 73 20 3f 22 2c 20 7a 53 65 70 2c 20 7a  s %s ?", zSep, z
6580: 4e 65 77 43 6f 6c 2c 20 7a 4f 70 29 3b 0a 20 20  NewCol, zOp);.  
6590: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20        }.        
65a0: 73 74 72 69 6e 67 5f 63 6f 6e 63 61 74 28 26 7a  string_concat(&z
65b0: 51 75 65 72 79 2c 20 7a 4e 65 77 2c 20 31 2c 20  Query, zNew, 1, 
65c0: 26 72 63 29 3b 0a 20 20 20 20 20 20 20 20 7a 53  &rc);.        zS
65d0: 65 70 20 3d 20 22 41 4e 44 22 3b 0a 20 20 20 20  ep = "AND";.    
65e0: 20 20 20 20 70 55 73 61 67 65 2d 3e 61 72 67 76      pUsage->argv
65f0: 49 6e 64 65 78 20 3d 20 2b 2b 6e 41 72 67 3b 0a  Index = ++nArg;.
6600: 20 20 20 20 20 20 20 20 70 55 73 61 67 65 2d 3e          pUsage->
6610: 6f 6d 69 74 20 3d 20 31 3b 0a 20 20 20 20 20 20  omit = 1;.      
6620: 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 2f  }.    }.  }..  /
6630: 2a 20 49 66 20 74 68 65 72 65 20 69 73 20 6f 6e  * If there is on
6640: 6c 79 20 6f 6e 65 20 74 65 72 6d 20 69 6e 20 74  ly one term in t
6650: 68 65 20 4f 52 44 45 52 20 42 59 20 63 6c 61 75  he ORDER BY clau
6660: 73 65 2c 20 61 6e 64 20 69 74 20 69 73 0a 20 20  se, and it is.  
6670: 2a 2a 20 6f 6e 20 61 20 63 6f 6c 75 6d 6e 20 74  ** on a column t
6680: 68 61 74 20 74 68 69 73 20 76 69 72 74 75 61 6c  hat this virtual
6690: 20 74 61 62 6c 65 20 68 61 73 20 61 6e 20 69 6e   table has an in
66a0: 64 65 78 20 66 6f 72 2c 20 74 68 65 6e 20 63 6f  dex for, then co
66b0: 6e 73 75 6d 65 20 0a 20 20 2a 2a 20 74 68 65 20  nsume .  ** the 
66c0: 4f 52 44 45 52 20 42 59 20 63 6c 61 75 73 65 2e  ORDER BY clause.
66d0: 0a 20 20 2a 2f 0a 20 20 69 66 28 20 70 49 64 78  .  */.  if( pIdx
66e0: 49 6e 66 6f 2d 3e 6e 4f 72 64 65 72 42 79 3d 3d  Info->nOrderBy==
66f0: 31 20 26 26 20 28 0a 20 20 20 20 20 20 20 20 70  1 && (.        p
6700: 49 64 78 49 6e 66 6f 2d 3e 61 4f 72 64 65 72 42  IdxInfo->aOrderB
6710: 79 2d 3e 69 43 6f 6c 75 6d 6e 3c 30 20 7c 7c 0a  y->iColumn<0 ||.
6720: 20 20 20 20 20 20 20 20 70 56 74 61 62 2d 3e 61          pVtab->a
6730: 49 6e 64 65 78 5b 70 49 64 78 49 6e 66 6f 2d 3e  Index[pIdxInfo->
6740: 61 4f 72 64 65 72 42 79 2d 3e 69 43 6f 6c 75 6d  aOrderBy->iColum
6750: 6e 5d 29 20 29 7b 0a 20 20 20 20 69 6e 74 20 69  n]) ){.    int i
6760: 43 6f 6c 20 3d 20 70 49 64 78 49 6e 66 6f 2d 3e  Col = pIdxInfo->
6770: 61 4f 72 64 65 72 42 79 2d 3e 69 43 6f 6c 75 6d  aOrderBy->iColum
6780: 6e 3b 0a 20 20 20 20 63 68 61 72 20 2a 7a 4e 65  n;.    char *zNe
6790: 77 43 6f 6c 20 3d 20 69 43 6f 6c 3e 3d 30 20 3f  wCol = iCol>=0 ?
67a0: 20 70 56 74 61 62 2d 3e 61 43 6f 6c 5b 69 43 6f   pVtab->aCol[iCo
67b0: 6c 5d 20 3a 20 22 72 6f 77 69 64 22 3b 0a 20 20  l] : "rowid";.  
67c0: 20 20 63 68 61 72 20 2a 7a 44 69 72 20 3d 20 70    char *zDir = p
67d0: 49 64 78 49 6e 66 6f 2d 3e 61 4f 72 64 65 72 42  IdxInfo->aOrderB
67e0: 79 2d 3e 64 65 73 63 3f 22 44 45 53 43 22 3a 22  y->desc?"DESC":"
67f0: 41 53 43 22 3b 0a 20 20 20 20 7a 4e 65 77 20 3d  ASC";.    zNew =
6800: 20 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66   sqlite3_mprintf
6810: 28 22 20 4f 52 44 45 52 20 42 59 20 25 73 20 25  (" ORDER BY %s %
6820: 73 22 2c 20 7a 4e 65 77 43 6f 6c 2c 20 7a 44 69  s", zNewCol, zDi
6830: 72 29 3b 0a 20 20 20 20 73 74 72 69 6e 67 5f 63  r);.    string_c
6840: 6f 6e 63 61 74 28 26 7a 51 75 65 72 79 2c 20 7a  oncat(&zQuery, z
6850: 4e 65 77 2c 20 31 2c 20 26 72 63 29 3b 0a 20 20  New, 1, &rc);.  
6860: 20 20 70 49 64 78 49 6e 66 6f 2d 3e 6f 72 64 65    pIdxInfo->orde
6870: 72 42 79 43 6f 6e 73 75 6d 65 64 20 3d 20 31 3b  rByConsumed = 1;
6880: 0a 20 20 7d 0a 0a 20 20 61 70 70 65 6e 64 54 6f  .  }..  appendTo
6890: 45 63 68 6f 4d 6f 64 75 6c 65 28 70 56 74 61 62  EchoModule(pVtab
68a0: 2d 3e 69 6e 74 65 72 70 2c 20 22 78 42 65 73 74  ->interp, "xBest
68b0: 49 6e 64 65 78 22 29 3b 3b 0a 20 20 61 70 70 65  Index");;.  appe
68c0: 6e 64 54 6f 45 63 68 6f 4d 6f 64 75 6c 65 28 70  ndToEchoModule(p
68d0: 56 74 61 62 2d 3e 69 6e 74 65 72 70 2c 20 7a 51  Vtab->interp, zQ
68e0: 75 65 72 79 29 3b 0a 0a 20 20 69 66 28 20 21 7a  uery);..  if( !z
68f0: 51 75 65 72 79 20 29 7b 0a 20 20 20 20 72 65 74  Query ){.    ret
6900: 75 72 6e 20 72 63 3b 0a 20 20 7d 0a 20 20 70 49  urn rc;.  }.  pI
6910: 64 78 49 6e 66 6f 2d 3e 69 64 78 4e 75 6d 20 3d  dxInfo->idxNum =
6920: 20 68 61 73 68 53 74 72 69 6e 67 28 7a 51 75 65   hashString(zQue
6930: 72 79 29 3b 0a 20 20 70 49 64 78 49 6e 66 6f 2d  ry);.  pIdxInfo-
6940: 3e 69 64 78 53 74 72 20 3d 20 7a 51 75 65 72 79  >idxStr = zQuery
6950: 3b 0a 20 20 70 49 64 78 49 6e 66 6f 2d 3e 6e 65  ;.  pIdxInfo->ne
6960: 65 64 54 6f 46 72 65 65 49 64 78 53 74 72 20 3d  edToFreeIdxStr =
6970: 20 31 3b 0a 20 20 69 66 28 20 75 73 65 43 6f 73   1;.  if( useCos
6980: 74 20 29 7b 0a 20 20 20 20 70 49 64 78 49 6e 66  t ){.    pIdxInf
6990: 6f 2d 3e 65 73 74 69 6d 61 74 65 64 43 6f 73 74  o->estimatedCost
69a0: 20 3d 20 63 6f 73 74 3b 0a 20 20 7d 65 6c 73 65   = cost;.  }else
69b0: 20 69 66 28 20 75 73 65 49 64 78 20 29 7b 0a 20   if( useIdx ){. 
69c0: 20 20 20 2f 2a 20 41 70 70 72 6f 78 69 6d 61 74     /* Approximat
69d0: 69 6f 6e 20 6f 66 20 6c 6f 67 32 28 6e 52 6f 77  ion of log2(nRow
69e0: 29 2e 20 2a 2f 0a 20 20 20 20 66 6f 72 28 20 69  ). */.    for( i
69f0: 69 3d 30 3b 20 69 69 3c 28 73 69 7a 65 6f 66 28  i=0; ii<(sizeof(
6a00: 69 6e 74 29 2a 38 29 2d 31 3b 20 69 69 2b 2b 20  int)*8)-1; ii++ 
6a10: 29 7b 0a 20 20 20 20 20 20 69 66 28 20 6e 52 6f  ){.      if( nRo
6a20: 77 20 26 20 28 31 3c 3c 69 69 29 20 29 7b 0a 20  w & (1<<ii) ){. 
6a30: 20 20 20 20 20 20 20 70 49 64 78 49 6e 66 6f 2d         pIdxInfo-
6a40: 3e 65 73 74 69 6d 61 74 65 64 43 6f 73 74 20 3d  >estimatedCost =
6a50: 20 28 64 6f 75 62 6c 65 29 69 69 3b 0a 20 20 20   (double)ii;.   
6a60: 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 65 6c     }.    }.  }el
6a70: 73 65 7b 0a 20 20 20 20 70 49 64 78 49 6e 66 6f  se{.    pIdxInfo
6a80: 2d 3e 65 73 74 69 6d 61 74 65 64 43 6f 73 74 20  ->estimatedCost 
6a90: 3d 20 28 64 6f 75 62 6c 65 29 6e 52 6f 77 3b 0a  = (double)nRow;.
6aa0: 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 72 63 3b    }.  return rc;
6ab0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 65 20 78 55  .}../*.** The xU
6ac0: 70 64 61 74 65 20 6d 65 74 68 6f 64 20 66 6f 72  pdate method for
6ad0: 20 65 63 68 6f 20 6d 6f 64 75 6c 65 20 76 69 72   echo module vir
6ae0: 74 75 61 6c 20 74 61 62 6c 65 73 2e 0a 2a 2a 20  tual tables..** 
6af0: 0a 2a 2a 20 20 20 20 61 70 44 61 74 61 5b 30 5d  .**    apData[0]
6b00: 20 20 61 70 44 61 74 61 5b 31 5d 20 20 61 70 44    apData[1]  apD
6b10: 61 74 61 5b 32 2e 2e 5d 0a 2a 2a 0a 2a 2a 20 20  ata[2..].**.**  
6b20: 20 20 49 4e 54 45 47 45 52 20 20 20 20 20 20 20    INTEGER       
6b30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6b40: 20 20 20 20 20 20 20 44 45 4c 45 54 45 20 20 20         DELETE   
6b50: 20 20 20 20 20 20 20 20 20 0a 2a 2a 0a 2a 2a 20           .**.** 
6b60: 20 20 20 49 4e 54 45 47 45 52 20 20 20 20 4e 55     INTEGER    NU
6b70: 4c 4c 20 20 20 20 20 20 20 28 6e 43 6f 6c 20 61  LL       (nCol a
6b80: 72 67 73 29 20 20 20 20 55 50 44 41 54 45 20 28  rgs)    UPDATE (
6b90: 64 6f 20 6e 6f 74 20 73 65 74 20 72 6f 77 69 64  do not set rowid
6ba0: 29 0a 2a 2a 20 20 20 20 49 4e 54 45 47 45 52 20  ).**    INTEGER 
6bb0: 20 20 20 49 4e 54 45 47 45 52 20 20 20 20 28 6e     INTEGER    (n
6bc0: 43 6f 6c 20 61 72 67 73 29 20 20 20 20 55 50 44  Col args)    UPD
6bd0: 41 54 45 20 28 77 69 74 68 20 53 45 54 20 72 6f  ATE (with SET ro
6be0: 77 69 64 20 3d 20 3c 61 72 67 31 3e 29 0a 2a 2a  wid = <arg1>).**
6bf0: 0a 2a 2a 20 20 20 20 4e 55 4c 4c 20 20 20 20 20  .**    NULL     
6c00: 20 20 4e 55 4c 4c 20 20 20 20 20 20 20 28 6e 43    NULL       (nC
6c10: 6f 6c 20 61 72 67 73 29 20 20 20 20 49 4e 53 45  ol args)    INSE
6c20: 52 54 20 49 4e 54 4f 20 28 61 75 74 6f 6d 61 74  RT INTO (automat
6c30: 69 63 20 72 6f 77 69 64 20 76 61 6c 75 65 29 0a  ic rowid value).
6c40: 2a 2a 20 20 20 20 4e 55 4c 4c 20 20 20 20 20 20  **    NULL      
6c50: 20 49 4e 54 45 47 45 52 20 20 20 20 28 6e 43 6f   INTEGER    (nCo
6c60: 6c 20 61 72 67 73 29 20 20 20 20 49 4e 53 45 52  l args)    INSER
6c70: 54 20 28 69 6e 63 6c 2e 20 72 6f 77 69 64 20 76  T (incl. rowid v
6c80: 61 6c 75 65 29 0a 2a 2a 0a 2a 2f 0a 69 6e 74 20  alue).**.*/.int 
6c90: 65 63 68 6f 55 70 64 61 74 65 28 0a 20 20 73 71  echoUpdate(.  sq
6ca0: 6c 69 74 65 33 5f 76 74 61 62 20 2a 74 61 62 2c  lite3_vtab *tab,
6cb0: 20 0a 20 20 69 6e 74 20 6e 44 61 74 61 2c 20 0a   .  int nData, .
6cc0: 20 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 20    sqlite3_value 
6cd0: 2a 2a 61 70 44 61 74 61 2c 20 0a 20 20 73 71 6c  **apData, .  sql
6ce0: 69 74 65 5f 69 6e 74 36 34 20 2a 70 52 6f 77 69  ite_int64 *pRowi
6cf0: 64 0a 29 7b 0a 20 20 65 63 68 6f 5f 76 74 61 62  d.){.  echo_vtab
6d00: 20 2a 70 56 74 61 62 20 3d 20 28 65 63 68 6f 5f   *pVtab = (echo_
6d10: 76 74 61 62 20 2a 29 74 61 62 3b 0a 20 20 73 71  vtab *)tab;.  sq
6d20: 6c 69 74 65 33 20 2a 64 62 20 3d 20 70 56 74 61  lite3 *db = pVta
6d30: 62 2d 3e 64 62 3b 0a 20 20 69 6e 74 20 72 63 20  b->db;.  int rc 
6d40: 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 0a 20 20  = SQLITE_OK;..  
6d50: 73 71 6c 69 74 65 33 5f 73 74 6d 74 20 2a 70 53  sqlite3_stmt *pS
6d60: 74 6d 74 20 3d 20 30 3b 0a 20 20 63 68 61 72 20  tmt = 0;.  char 
6d70: 2a 7a 20 3d 20 30 3b 20 20 20 20 20 20 20 20 20  *z = 0;         
6d80: 20 20 20 20 20 20 2f 2a 20 53 51 4c 20 73 74 61        /* SQL sta
6d90: 74 65 6d 65 6e 74 20 74 6f 20 65 78 65 63 75 74  tement to execut
6da0: 65 20 2a 2f 0a 20 20 69 6e 74 20 62 69 6e 64 41  e */.  int bindA
6db0: 72 67 5a 65 72 6f 20 3d 20 30 3b 20 20 20 20 20  rgZero = 0;     
6dc0: 20 20 2f 2a 20 54 72 75 65 20 74 6f 20 62 69 6e    /* True to bin
6dd0: 64 20 61 70 44 61 74 61 5b 30 5d 20 74 6f 20 73  d apData[0] to s
6de0: 71 6c 20 76 61 72 20 6e 6f 2e 20 6e 44 61 74 61  ql var no. nData
6df0: 20 2a 2f 0a 20 20 69 6e 74 20 62 69 6e 64 41 72   */.  int bindAr
6e00: 67 4f 6e 65 20 3d 20 30 3b 20 20 20 20 20 20 20  gOne = 0;       
6e10: 20 2f 2a 20 54 72 75 65 20 74 6f 20 62 69 6e 64   /* True to bind
6e20: 20 61 70 44 61 74 61 5b 31 5d 20 74 6f 20 73 71   apData[1] to sq
6e30: 6c 20 76 61 72 20 6e 6f 2e 20 31 20 2a 2f 0a 20  l var no. 1 */. 
6e40: 20 69 6e 74 20 69 3b 20 20 20 20 20 20 20 20 20   int i;         
6e50: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43              /* C
6e60: 6f 75 6e 74 65 72 20 76 61 72 69 61 62 6c 65 20  ounter variable 
6e70: 75 73 65 64 20 62 79 20 66 6f 72 20 6c 6f 6f 70  used by for loop
6e80: 73 20 2a 2f 0a 0a 20 20 61 73 73 65 72 74 28 20  s */..  assert( 
6e90: 6e 44 61 74 61 3d 3d 70 56 74 61 62 2d 3e 6e 43  nData==pVtab->nC
6ea0: 6f 6c 2b 32 20 7c 7c 20 6e 44 61 74 61 3d 3d 31  ol+2 || nData==1
6eb0: 20 29 3b 0a 0a 20 20 2f 2a 20 54 69 63 6b 65 74   );..  /* Ticket
6ec0: 20 23 33 30 38 33 20 2d 20 6d 61 6b 65 20 73 75   #3083 - make su
6ed0: 72 65 20 77 65 20 61 6c 77 61 79 73 20 73 74 61  re we always sta
6ee0: 72 74 20 61 20 74 72 61 6e 73 61 63 74 69 6f 6e  rt a transaction
6ef0: 20 70 72 69 6f 72 20 74 6f 0a 20 20 2a 2a 20 6d   prior to.  ** m
6f00: 61 6b 69 6e 67 20 61 6e 79 20 63 68 61 6e 67 65  aking any change
6f10: 73 20 74 6f 20 61 20 76 69 72 74 75 61 6c 20 74  s to a virtual t
6f20: 61 62 6c 65 20 2a 2f 0a 20 20 61 73 73 65 72 74  able */.  assert
6f30: 28 20 70 56 74 61 62 2d 3e 69 6e 54 72 61 6e 73  ( pVtab->inTrans
6f40: 61 63 74 69 6f 6e 20 29 3b 0a 0a 20 20 69 66 28  action );..  if(
6f50: 20 73 69 6d 75 6c 61 74 65 56 74 61 62 45 72 72   simulateVtabErr
6f60: 6f 72 28 70 56 74 61 62 2c 20 22 78 55 70 64 61  or(pVtab, "xUpda
6f70: 74 65 22 29 20 29 7b 0a 20 20 20 20 72 65 74 75  te") ){.    retu
6f80: 72 6e 20 53 51 4c 49 54 45 5f 45 52 52 4f 52 3b  rn SQLITE_ERROR;
6f90: 0a 20 20 7d 0a 0a 20 20 2f 2a 20 49 66 20 61 70  .  }..  /* If ap
6fa0: 44 61 74 61 5b 30 5d 20 69 73 20 61 6e 20 69 6e  Data[0] is an in
6fb0: 74 65 67 65 72 20 61 6e 64 20 6e 44 61 74 61 3e  teger and nData>
6fc0: 31 20 74 68 65 6e 20 64 6f 20 61 6e 20 55 50 44  1 then do an UPD
6fd0: 41 54 45 20 2a 2f 0a 20 20 69 66 28 20 6e 44 61  ATE */.  if( nDa
6fe0: 74 61 3e 31 20 26 26 20 73 71 6c 69 74 65 33 5f  ta>1 && sqlite3_
6ff0: 76 61 6c 75 65 5f 74 79 70 65 28 61 70 44 61 74  value_type(apDat
7000: 61 5b 30 5d 29 3d 3d 53 51 4c 49 54 45 5f 49 4e  a[0])==SQLITE_IN
7010: 54 45 47 45 52 20 29 7b 0a 20 20 20 20 63 68 61  TEGER ){.    cha
7020: 72 20 2a 7a 53 65 70 20 3d 20 22 20 53 45 54 22  r *zSep = " SET"
7030: 3b 0a 20 20 20 20 7a 20 3d 20 73 71 6c 69 74 65  ;.    z = sqlite
7040: 33 5f 6d 70 72 69 6e 74 66 28 22 55 50 44 41 54  3_mprintf("UPDAT
7050: 45 20 25 51 22 2c 20 70 56 74 61 62 2d 3e 7a 54  E %Q", pVtab->zT
7060: 61 62 6c 65 4e 61 6d 65 29 3b 0a 20 20 20 20 69  ableName);.    i
7070: 66 28 20 21 7a 20 29 7b 0a 20 20 20 20 20 20 72  f( !z ){.      r
7080: 63 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d  c = SQLITE_NOMEM
7090: 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 62 69 6e  ;.    }..    bin
70a0: 64 41 72 67 4f 6e 65 20 3d 20 28 61 70 44 61 74  dArgOne = (apDat
70b0: 61 5b 31 5d 20 26 26 20 73 71 6c 69 74 65 33 5f  a[1] && sqlite3_
70c0: 76 61 6c 75 65 5f 74 79 70 65 28 61 70 44 61 74  value_type(apDat
70d0: 61 5b 31 5d 29 3d 3d 53 51 4c 49 54 45 5f 49 4e  a[1])==SQLITE_IN
70e0: 54 45 47 45 52 29 3b 0a 20 20 20 20 62 69 6e 64  TEGER);.    bind
70f0: 41 72 67 5a 65 72 6f 20 3d 20 31 3b 0a 0a 20 20  ArgZero = 1;..  
7100: 20 20 69 66 28 20 62 69 6e 64 41 72 67 4f 6e 65    if( bindArgOne
7110: 20 29 7b 0a 20 20 20 20 20 20 20 73 74 72 69 6e   ){.       strin
7120: 67 5f 63 6f 6e 63 61 74 28 26 7a 2c 20 22 20 53  g_concat(&z, " S
7130: 45 54 20 72 6f 77 69 64 3d 3f 31 20 22 2c 20 30  ET rowid=?1 ", 0
7140: 2c 20 26 72 63 29 3b 0a 20 20 20 20 20 20 20 7a  , &rc);.       z
7150: 53 65 70 20 3d 20 22 2c 22 3b 0a 20 20 20 20 7d  Sep = ",";.    }
7160: 0a 20 20 20 20 66 6f 72 28 69 3d 32 3b 20 69 3c  .    for(i=2; i<
7170: 6e 44 61 74 61 3b 20 69 2b 2b 29 7b 0a 20 20 20  nData; i++){.   
7180: 20 20 20 69 66 28 20 61 70 44 61 74 61 5b 69 5d     if( apData[i]
7190: 3d 3d 30 20 29 20 63 6f 6e 74 69 6e 75 65 3b 0a  ==0 ) continue;.
71a0: 20 20 20 20 20 20 73 74 72 69 6e 67 5f 63 6f 6e        string_con
71b0: 63 61 74 28 26 7a 2c 20 73 71 6c 69 74 65 33 5f  cat(&z, sqlite3_
71c0: 6d 70 72 69 6e 74 66 28 0a 20 20 20 20 20 20 20  mprintf(.       
71d0: 20 20 20 22 25 73 20 25 51 3d 3f 25 64 22 2c 20     "%s %Q=?%d", 
71e0: 7a 53 65 70 2c 20 70 56 74 61 62 2d 3e 61 43 6f  zSep, pVtab->aCo
71f0: 6c 5b 69 2d 32 5d 2c 20 69 29 2c 20 31 2c 20 26  l[i-2], i), 1, &
7200: 72 63 29 3b 0a 20 20 20 20 20 20 7a 53 65 70 20  rc);.      zSep 
7210: 3d 20 22 2c 22 3b 0a 20 20 20 20 7d 0a 20 20 20  = ",";.    }.   
7220: 20 73 74 72 69 6e 67 5f 63 6f 6e 63 61 74 28 26   string_concat(&
7230: 7a 2c 20 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e  z, sqlite3_mprin
7240: 74 66 28 22 20 57 48 45 52 45 20 72 6f 77 69 64  tf(" WHERE rowid
7250: 3d 3f 25 64 22 2c 20 6e 44 61 74 61 29 2c 20 31  =?%d", nData), 1
7260: 2c 20 26 72 63 29 3b 0a 20 20 7d 0a 0a 20 20 2f  , &rc);.  }..  /
7270: 2a 20 49 66 20 61 70 44 61 74 61 5b 30 5d 20 69  * If apData[0] i
7280: 73 20 61 6e 20 69 6e 74 65 67 65 72 20 61 6e 64  s an integer and
7290: 20 6e 44 61 74 61 3d 3d 31 20 74 68 65 6e 20 64   nData==1 then d
72a0: 6f 20 61 20 44 45 4c 45 54 45 20 2a 2f 0a 20 20  o a DELETE */.  
72b0: 65 6c 73 65 20 69 66 28 20 6e 44 61 74 61 3d 3d  else if( nData==
72c0: 31 20 26 26 20 73 71 6c 69 74 65 33 5f 76 61 6c  1 && sqlite3_val
72d0: 75 65 5f 74 79 70 65 28 61 70 44 61 74 61 5b 30  ue_type(apData[0
72e0: 5d 29 3d 3d 53 51 4c 49 54 45 5f 49 4e 54 45 47  ])==SQLITE_INTEG
72f0: 45 52 20 29 7b 0a 20 20 20 20 7a 20 3d 20 73 71  ER ){.    z = sq
7300: 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 22 44  lite3_mprintf("D
7310: 45 4c 45 54 45 20 46 52 4f 4d 20 25 51 20 57 48  ELETE FROM %Q WH
7320: 45 52 45 20 72 6f 77 69 64 20 3d 20 3f 31 22 2c  ERE rowid = ?1",
7330: 20 70 56 74 61 62 2d 3e 7a 54 61 62 6c 65 4e 61   pVtab->zTableNa
7340: 6d 65 29 3b 0a 20 20 20 20 69 66 28 20 21 7a 20  me);.    if( !z 
7350: 29 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 53 51  ){.      rc = SQ
7360: 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20  LITE_NOMEM;.    
7370: 7d 0a 20 20 20 20 62 69 6e 64 41 72 67 5a 65 72  }.    bindArgZer
7380: 6f 20 3d 20 31 3b 0a 20 20 7d 0a 0a 20 20 2f 2a  o = 1;.  }..  /*
7390: 20 49 66 20 74 68 65 20 66 69 72 73 74 20 61 72   If the first ar
73a0: 67 75 6d 65 6e 74 20 69 73 20 4e 55 4c 4c 20 61  gument is NULL a
73b0: 6e 64 20 74 68 65 72 65 20 61 72 65 20 6d 6f 72  nd there are mor
73c0: 65 20 74 68 61 6e 20 74 77 6f 20 61 72 67 73 2c  e than two args,
73d0: 20 49 4e 53 45 52 54 20 2a 2f 0a 20 20 65 6c 73   INSERT */.  els
73e0: 65 20 69 66 28 20 6e 44 61 74 61 3e 32 20 26 26  e if( nData>2 &&
73f0: 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 74   sqlite3_value_t
7400: 79 70 65 28 61 70 44 61 74 61 5b 30 5d 29 3d 3d  ype(apData[0])==
7410: 53 51 4c 49 54 45 5f 4e 55 4c 4c 20 29 7b 0a 20  SQLITE_NULL ){. 
7420: 20 20 20 69 6e 74 20 69 69 3b 0a 20 20 20 20 63     int ii;.    c
7430: 68 61 72 20 2a 7a 49 6e 73 65 72 74 20 3d 20 30  har *zInsert = 0
7440: 3b 0a 20 20 20 20 63 68 61 72 20 2a 7a 56 61 6c  ;.    char *zVal
7450: 75 65 73 20 3d 20 30 3b 0a 20 20 0a 20 20 20 20  ues = 0;.  .    
7460: 7a 49 6e 73 65 72 74 20 3d 20 73 71 6c 69 74 65  zInsert = sqlite
7470: 33 5f 6d 70 72 69 6e 74 66 28 22 49 4e 53 45 52  3_mprintf("INSER
7480: 54 20 49 4e 54 4f 20 25 51 20 28 22 2c 20 70 56  T INTO %Q (", pV
7490: 74 61 62 2d 3e 7a 54 61 62 6c 65 4e 61 6d 65 29  tab->zTableName)
74a0: 3b 0a 20 20 20 20 69 66 28 20 21 7a 49 6e 73 65  ;.    if( !zInse
74b0: 72 74 20 29 7b 0a 20 20 20 20 20 20 72 63 20 3d  rt ){.      rc =
74c0: 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20   SQLITE_NOMEM;. 
74d0: 20 20 20 7d 0a 20 20 20 20 69 66 28 20 73 71 6c     }.    if( sql
74e0: 69 74 65 33 5f 76 61 6c 75 65 5f 74 79 70 65 28  ite3_value_type(
74f0: 61 70 44 61 74 61 5b 31 5d 29 3d 3d 53 51 4c 49  apData[1])==SQLI
7500: 54 45 5f 49 4e 54 45 47 45 52 20 29 7b 0a 20 20  TE_INTEGER ){.  
7510: 20 20 20 20 62 69 6e 64 41 72 67 4f 6e 65 20 3d      bindArgOne =
7520: 20 31 3b 0a 20 20 20 20 20 20 7a 56 61 6c 75 65   1;.      zValue
7530: 73 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72 69  s = sqlite3_mpri
7540: 6e 74 66 28 22 3f 22 29 3b 0a 20 20 20 20 20 20  ntf("?");.      
7550: 73 74 72 69 6e 67 5f 63 6f 6e 63 61 74 28 26 7a  string_concat(&z
7560: 49 6e 73 65 72 74 2c 20 22 72 6f 77 69 64 22 2c  Insert, "rowid",
7570: 20 30 2c 20 26 72 63 29 3b 0a 20 20 20 20 7d 0a   0, &rc);.    }.
7580: 0a 20 20 20 20 61 73 73 65 72 74 28 28 70 56 74  .    assert((pVt
7590: 61 62 2d 3e 6e 43 6f 6c 2b 32 29 3d 3d 6e 44 61  ab->nCol+2)==nDa
75a0: 74 61 29 3b 0a 20 20 20 20 66 6f 72 28 69 69 3d  ta);.    for(ii=
75b0: 32 3b 20 69 69 3c 6e 44 61 74 61 3b 20 69 69 2b  2; ii<nData; ii+
75c0: 2b 29 7b 0a 20 20 20 20 20 20 73 74 72 69 6e 67  +){.      string
75d0: 5f 63 6f 6e 63 61 74 28 26 7a 49 6e 73 65 72 74  _concat(&zInsert
75e0: 2c 20 0a 20 20 20 20 20 20 20 20 20 20 73 71 6c  , .          sql
75f0: 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 22 25 73  ite3_mprintf("%s
7600: 25 51 22 2c 20 7a 56 61 6c 75 65 73 3f 22 2c 20  %Q", zValues?", 
7610: 22 3a 22 22 2c 20 70 56 74 61 62 2d 3e 61 43 6f  ":"", pVtab->aCo
7620: 6c 5b 69 69 2d 32 5d 29 2c 20 31 2c 20 26 72 63  l[ii-2]), 1, &rc
7630: 29 3b 0a 20 20 20 20 20 20 73 74 72 69 6e 67 5f  );.      string_
7640: 63 6f 6e 63 61 74 28 26 7a 56 61 6c 75 65 73 2c  concat(&zValues,
7650: 20 0a 20 20 20 20 20 20 20 20 20 20 73 71 6c 69   .          sqli
7660: 74 65 33 5f 6d 70 72 69 6e 74 66 28 22 25 73 3f  te3_mprintf("%s?
7670: 25 64 22 2c 20 7a 56 61 6c 75 65 73 3f 22 2c 20  %d", zValues?", 
7680: 22 3a 22 22 2c 20 69 69 29 2c 20 31 2c 20 26 72  ":"", ii), 1, &r
7690: 63 29 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 73  c);.    }..    s
76a0: 74 72 69 6e 67 5f 63 6f 6e 63 61 74 28 26 7a 2c  tring_concat(&z,
76b0: 20 7a 49 6e 73 65 72 74 2c 20 31 2c 20 26 72 63   zInsert, 1, &rc
76c0: 29 3b 0a 20 20 20 20 73 74 72 69 6e 67 5f 63 6f  );.    string_co
76d0: 6e 63 61 74 28 26 7a 2c 20 22 29 20 56 41 4c 55  ncat(&z, ") VALU
76e0: 45 53 28 22 2c 20 30 2c 20 26 72 63 29 3b 0a 20  ES(", 0, &rc);. 
76f0: 20 20 20 73 74 72 69 6e 67 5f 63 6f 6e 63 61 74     string_concat
7700: 28 26 7a 2c 20 7a 56 61 6c 75 65 73 2c 20 31 2c  (&z, zValues, 1,
7710: 20 26 72 63 29 3b 0a 20 20 20 20 73 74 72 69 6e   &rc);.    strin
7720: 67 5f 63 6f 6e 63 61 74 28 26 7a 2c 20 22 29 22  g_concat(&z, ")"
7730: 2c 20 30 2c 20 26 72 63 29 3b 0a 20 20 7d 0a 0a  , 0, &rc);.  }..
7740: 20 20 2f 2a 20 41 6e 79 74 68 69 6e 67 20 65 6c    /* Anything el
7750: 73 65 20 69 73 20 61 6e 20 65 72 72 6f 72 20 2a  se is an error *
7760: 2f 0a 20 20 65 6c 73 65 7b 0a 20 20 20 20 61 73  /.  else{.    as
7770: 73 65 72 74 28 30 29 3b 0a 20 20 20 20 72 65 74  sert(0);.    ret
7780: 75 72 6e 20 53 51 4c 49 54 45 5f 45 52 52 4f 52  urn SQLITE_ERROR
7790: 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 72 63 3d  ;.  }..  if( rc=
77a0: 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20  =SQLITE_OK ){.  
77b0: 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 70    rc = sqlite3_p
77c0: 72 65 70 61 72 65 28 64 62 2c 20 7a 2c 20 2d 31  repare(db, z, -1
77d0: 2c 20 26 70 53 74 6d 74 2c 20 30 29 3b 0a 20 20  , &pStmt, 0);.  
77e0: 7d 0a 20 20 61 73 73 65 72 74 28 20 72 63 21 3d  }.  assert( rc!=
77f0: 53 51 4c 49 54 45 5f 4f 4b 20 7c 7c 20 70 53 74  SQLITE_OK || pSt
7800: 6d 74 20 29 3b 0a 20 20 73 71 6c 69 74 65 33 5f  mt );.  sqlite3_
7810: 66 72 65 65 28 7a 29 3b 0a 20 20 69 66 28 20 72  free(z);.  if( r
7820: 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 7b  c==SQLITE_OK ) {
7830: 0a 20 20 20 20 69 66 28 20 62 69 6e 64 41 72 67  .    if( bindArg
7840: 5a 65 72 6f 20 29 7b 0a 20 20 20 20 20 20 73 71  Zero ){.      sq
7850: 6c 69 74 65 33 5f 62 69 6e 64 5f 76 61 6c 75 65  lite3_bind_value
7860: 28 70 53 74 6d 74 2c 20 6e 44 61 74 61 2c 20 61  (pStmt, nData, a
7870: 70 44 61 74 61 5b 30 5d 29 3b 0a 20 20 20 20 7d  pData[0]);.    }
7880: 0a 20 20 20 20 69 66 28 20 62 69 6e 64 41 72 67  .    if( bindArg
7890: 4f 6e 65 20 29 7b 0a 20 20 20 20 20 20 73 71 6c  One ){.      sql
78a0: 69 74 65 33 5f 62 69 6e 64 5f 76 61 6c 75 65 28  ite3_bind_value(
78b0: 70 53 74 6d 74 2c 20 31 2c 20 61 70 44 61 74 61  pStmt, 1, apData
78c0: 5b 31 5d 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20  [1]);.    }.    
78d0: 66 6f 72 28 69 3d 32 3b 20 69 3c 6e 44 61 74 61  for(i=2; i<nData
78e0: 20 26 26 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f   && rc==SQLITE_O
78f0: 4b 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20 69  K; i++){.      i
7900: 66 28 20 61 70 44 61 74 61 5b 69 5d 20 29 20 72  f( apData[i] ) r
7910: 63 20 3d 20 73 71 6c 69 74 65 33 5f 62 69 6e 64  c = sqlite3_bind
7920: 5f 76 61 6c 75 65 28 70 53 74 6d 74 2c 20 69 2c  _value(pStmt, i,
7930: 20 61 70 44 61 74 61 5b 69 5d 29 3b 0a 20 20 20   apData[i]);.   
7940: 20 7d 0a 20 20 20 20 69 66 28 20 72 63 3d 3d 53   }.    if( rc==S
7950: 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
7960: 20 20 73 71 6c 69 74 65 33 5f 73 74 65 70 28 70    sqlite3_step(p
7970: 53 74 6d 74 29 3b 0a 20 20 20 20 20 20 72 63 20  Stmt);.      rc 
7980: 3d 20 73 71 6c 69 74 65 33 5f 66 69 6e 61 6c 69  = sqlite3_finali
7990: 7a 65 28 70 53 74 6d 74 29 3b 0a 20 20 20 20 7d  ze(pStmt);.    }
79a0: 65 6c 73 65 7b 0a 20 20 20 20 20 20 73 71 6c 69  else{.      sqli
79b0: 74 65 33 5f 66 69 6e 61 6c 69 7a 65 28 70 53 74  te3_finalize(pSt
79c0: 6d 74 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a  mt);.    }.  }..
79d0: 20 20 69 66 28 20 70 52 6f 77 69 64 20 26 26 20    if( pRowid && 
79e0: 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc==SQLITE_OK ){
79f0: 0a 20 20 20 20 2a 70 52 6f 77 69 64 20 3d 20 73  .    *pRowid = s
7a00: 71 6c 69 74 65 33 5f 6c 61 73 74 5f 69 6e 73 65  qlite3_last_inse
7a10: 72 74 5f 72 6f 77 69 64 28 64 62 29 3b 0a 20 20  rt_rowid(db);.  
7a20: 7d 0a 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49  }.  if( rc!=SQLI
7a30: 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 74 61 62  TE_OK ){.    tab
7a40: 2d 3e 7a 45 72 72 4d 73 67 20 3d 20 73 71 6c 69  ->zErrMsg = sqli
7a50: 74 65 33 5f 6d 70 72 69 6e 74 66 28 22 65 63 68  te3_mprintf("ech
7a60: 6f 2d 76 74 61 62 2d 65 72 72 6f 72 3a 20 25 73  o-vtab-error: %s
7a70: 22 2c 20 73 71 6c 69 74 65 33 5f 65 72 72 6d 73  ", sqlite3_errms
7a80: 67 28 64 62 29 29 3b 0a 20 20 7d 0a 0a 20 20 72  g(db));.  }..  r
7a90: 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a  eturn rc;.}../*.
7aa0: 2a 2a 20 78 42 65 67 69 6e 2c 20 78 53 79 6e 63  ** xBegin, xSync
7ab0: 2c 20 78 43 6f 6d 6d 69 74 20 61 6e 64 20 78 52  , xCommit and xR
7ac0: 6f 6c 6c 62 61 63 6b 20 63 61 6c 6c 62 61 63 6b  ollback callback
7ad0: 73 20 66 6f 72 20 65 63 68 6f 20 6d 6f 64 75 6c  s for echo modul
7ae0: 65 0a 2a 2a 20 76 69 72 74 75 61 6c 20 74 61 62  e.** virtual tab
7af0: 6c 65 73 2e 20 44 6f 20 6e 6f 74 68 69 6e 67 20  les. Do nothing 
7b00: 6f 74 68 65 72 20 74 68 61 6e 20 61 64 64 20 74  other than add t
7b10: 68 65 20 6e 61 6d 65 20 6f 66 20 74 68 65 20 63  he name of the c
7b20: 61 6c 6c 62 61 63 6b 0a 2a 2a 20 74 6f 20 74 68  allback.** to th
7b30: 65 20 24 3a 3a 65 63 68 6f 5f 6d 6f 64 75 6c 65  e $::echo_module
7b40: 20 54 63 6c 20 76 61 72 69 61 62 6c 65 2e 0a 2a   Tcl variable..*
7b50: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 65 63 68  /.static int ech
7b60: 6f 54 72 61 6e 73 61 63 74 69 6f 6e 43 61 6c 6c  oTransactionCall
7b70: 28 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 74  (sqlite3_vtab *t
7b80: 61 62 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a  ab, const char *
7b90: 7a 43 61 6c 6c 29 7b 0a 20 20 63 68 61 72 20 2a  zCall){.  char *
7ba0: 7a 3b 0a 20 20 65 63 68 6f 5f 76 74 61 62 20 2a  z;.  echo_vtab *
7bb0: 70 56 74 61 62 20 3d 20 28 65 63 68 6f 5f 76 74  pVtab = (echo_vt
7bc0: 61 62 20 2a 29 74 61 62 3b 0a 20 20 7a 20 3d 20  ab *)tab;.  z = 
7bd0: 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28  sqlite3_mprintf(
7be0: 22 65 63 68 6f 28 25 73 29 22 2c 20 70 56 74 61  "echo(%s)", pVta
7bf0: 62 2d 3e 7a 54 61 62 6c 65 4e 61 6d 65 29 3b 0a  b->zTableName);.
7c00: 20 20 69 66 28 20 7a 3d 3d 30 20 29 20 72 65 74    if( z==0 ) ret
7c10: 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d  urn SQLITE_NOMEM
7c20: 3b 0a 20 20 61 70 70 65 6e 64 54 6f 45 63 68 6f  ;.  appendToEcho
7c30: 4d 6f 64 75 6c 65 28 70 56 74 61 62 2d 3e 69 6e  Module(pVtab->in
7c40: 74 65 72 70 2c 20 7a 43 61 6c 6c 29 3b 0a 20 20  terp, zCall);.  
7c50: 61 70 70 65 6e 64 54 6f 45 63 68 6f 4d 6f 64 75  appendToEchoModu
7c60: 6c 65 28 70 56 74 61 62 2d 3e 69 6e 74 65 72 70  le(pVtab->interp
7c70: 2c 20 7a 29 3b 0a 20 20 73 71 6c 69 74 65 33 5f  , z);.  sqlite3_
7c80: 66 72 65 65 28 7a 29 3b 0a 20 20 72 65 74 75 72  free(z);.  retur
7c90: 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 73  n SQLITE_OK;.}.s
7ca0: 74 61 74 69 63 20 69 6e 74 20 65 63 68 6f 42 65  tatic int echoBe
7cb0: 67 69 6e 28 73 71 6c 69 74 65 33 5f 76 74 61 62  gin(sqlite3_vtab
7cc0: 20 2a 74 61 62 29 7b 0a 20 20 69 6e 74 20 72 63   *tab){.  int rc
7cd0: 3b 0a 20 20 65 63 68 6f 5f 76 74 61 62 20 2a 70  ;.  echo_vtab *p
7ce0: 56 74 61 62 20 3d 20 28 65 63 68 6f 5f 76 74 61  Vtab = (echo_vta
7cf0: 62 20 2a 29 74 61 62 3b 0a 20 20 54 63 6c 5f 49  b *)tab;.  Tcl_I
7d00: 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 20 3d 20  nterp *interp = 
7d10: 70 56 74 61 62 2d 3e 69 6e 74 65 72 70 3b 0a 20  pVtab->interp;. 
7d20: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 56 61   const char *zVa
7d30: 6c 3b 20 0a 0a 20 20 2f 2a 20 54 69 63 6b 65 74  l; ..  /* Ticket
7d40: 20 23 33 30 38 33 20 2d 20 64 6f 20 6e 6f 74 20   #3083 - do not 
7d50: 73 74 61 72 74 20 61 20 74 72 61 6e 73 61 63 74  start a transact
7d60: 69 6f 6e 20 69 66 20 77 65 20 61 72 65 20 61 6c  ion if we are al
7d70: 72 65 61 64 79 20 69 6e 0a 20 20 2a 2a 20 61 20  ready in.  ** a 
7d80: 74 72 61 6e 73 61 63 74 69 6f 6e 20 2a 2f 0a 20  transaction */. 
7d90: 20 61 73 73 65 72 74 28 20 21 70 56 74 61 62 2d   assert( !pVtab-
7da0: 3e 69 6e 54 72 61 6e 73 61 63 74 69 6f 6e 20 29  >inTransaction )
7db0: 3b 0a 0a 20 20 69 66 28 20 73 69 6d 75 6c 61 74  ;..  if( simulat
7dc0: 65 56 74 61 62 45 72 72 6f 72 28 70 56 74 61 62  eVtabError(pVtab
7dd0: 2c 20 22 78 42 65 67 69 6e 22 29 20 29 7b 0a 20  , "xBegin") ){. 
7de0: 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45     return SQLITE
7df0: 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a 0a 20 20 72  _ERROR;.  }..  r
7e00: 63 20 3d 20 65 63 68 6f 54 72 61 6e 73 61 63 74  c = echoTransact
7e10: 69 6f 6e 43 61 6c 6c 28 74 61 62 2c 20 22 78 42  ionCall(tab, "xB
7e20: 65 67 69 6e 22 29 3b 0a 0a 20 20 69 66 28 20 72  egin");..  if( r
7e30: 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a  c==SQLITE_OK ){.
7e40: 20 20 20 20 2f 2a 20 43 68 65 63 6b 20 69 66 20      /* Check if 
7e50: 74 68 65 20 24 3a 3a 65 63 68 6f 5f 6d 6f 64 75  the $::echo_modu
7e60: 6c 65 5f 62 65 67 69 6e 5f 66 61 69 6c 20 76 61  le_begin_fail va
7e70: 72 69 61 62 6c 65 20 69 73 20 64 65 66 69 6e 65  riable is define
7e80: 64 2e 20 49 66 20 69 74 20 69 73 2c 0a 20 20 20  d. If it is,.   
7e90: 20 2a 2a 20 61 6e 64 20 69 74 20 69 73 20 73 65   ** and it is se
7ea0: 74 20 74 6f 20 74 68 65 20 6e 61 6d 65 20 6f 66  t to the name of
7eb0: 20 74 68 65 20 72 65 61 6c 20 74 61 62 6c 65 20   the real table 
7ec0: 75 6e 64 65 72 6c 79 69 6e 67 20 74 68 69 73 20  underlying this 
7ed0: 76 69 72 74 75 61 6c 0a 20 20 20 20 2a 2a 20 65  virtual.    ** e
7ee0: 63 68 6f 20 6d 6f 64 75 6c 65 20 74 61 62 6c 65  cho module table
7ef0: 2c 20 74 68 65 6e 20 63 61 75 73 65 20 74 68 69  , then cause thi
7f00: 73 20 78 53 79 6e 63 20 6f 70 65 72 61 74 69 6f  s xSync operatio
7f10: 6e 20 74 6f 20 66 61 69 6c 2e 0a 20 20 20 20 2a  n to fail..    *
7f20: 2f 0a 20 20 20 20 7a 56 61 6c 20 3d 20 54 63 6c  /.    zVal = Tcl
7f30: 5f 47 65 74 56 61 72 28 69 6e 74 65 72 70 2c 20  _GetVar(interp, 
7f40: 22 65 63 68 6f 5f 6d 6f 64 75 6c 65 5f 62 65 67  "echo_module_beg
7f50: 69 6e 5f 66 61 69 6c 22 2c 20 54 43 4c 5f 47 4c  in_fail", TCL_GL
7f60: 4f 42 41 4c 5f 4f 4e 4c 59 29 3b 0a 20 20 20 20  OBAL_ONLY);.    
7f70: 69 66 28 20 7a 56 61 6c 20 26 26 20 30 3d 3d 73  if( zVal && 0==s
7f80: 74 72 63 6d 70 28 7a 56 61 6c 2c 20 70 56 74 61  trcmp(zVal, pVta
7f90: 62 2d 3e 7a 54 61 62 6c 65 4e 61 6d 65 29 20 29  b->zTableName) )
7fa0: 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c  {.      rc = SQL
7fb0: 49 54 45 5f 45 52 52 4f 52 3b 0a 20 20 20 20 7d  ITE_ERROR;.    }
7fc0: 0a 20 20 7d 0a 20 20 69 66 28 20 72 63 3d 3d 53  .  }.  if( rc==S
7fd0: 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
7fe0: 70 56 74 61 62 2d 3e 69 6e 54 72 61 6e 73 61 63  pVtab->inTransac
7ff0: 74 69 6f 6e 20 3d 20 31 3b 0a 20 20 7d 0a 20 20  tion = 1;.  }.  
8000: 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 73 74 61  return rc;.}.sta
8010: 74 69 63 20 69 6e 74 20 65 63 68 6f 53 79 6e 63  tic int echoSync
8020: 28 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 74  (sqlite3_vtab *t
8030: 61 62 29 7b 0a 20 20 69 6e 74 20 72 63 3b 0a 20  ab){.  int rc;. 
8040: 20 65 63 68 6f 5f 76 74 61 62 20 2a 70 56 74 61   echo_vtab *pVta
8050: 62 20 3d 20 28 65 63 68 6f 5f 76 74 61 62 20 2a  b = (echo_vtab *
8060: 29 74 61 62 3b 0a 20 20 54 63 6c 5f 49 6e 74 65  )tab;.  Tcl_Inte
8070: 72 70 20 2a 69 6e 74 65 72 70 20 3d 20 70 56 74  rp *interp = pVt
8080: 61 62 2d 3e 69 6e 74 65 72 70 3b 0a 20 20 63 6f  ab->interp;.  co
8090: 6e 73 74 20 63 68 61 72 20 2a 7a 56 61 6c 3b 20  nst char *zVal; 
80a0: 0a 0a 20 20 2f 2a 20 54 69 63 6b 65 74 20 23 33  ..  /* Ticket #3
80b0: 30 38 33 20 2d 20 4f 6e 6c 79 20 63 61 6c 6c 20  083 - Only call 
80c0: 78 53 79 6e 63 20 69 66 20 77 65 20 68 61 76 65  xSync if we have
80d0: 20 70 72 65 76 69 6f 75 73 6c 79 20 73 74 61 72   previously star
80e0: 74 65 64 20 61 0a 20 20 2a 2a 20 74 72 61 6e 73  ted a.  ** trans
80f0: 61 63 74 69 6f 6e 20 2a 2f 0a 20 20 61 73 73 65  action */.  asse
8100: 72 74 28 20 70 56 74 61 62 2d 3e 69 6e 54 72 61  rt( pVtab->inTra
8110: 6e 73 61 63 74 69 6f 6e 20 29 3b 0a 0a 20 20 69  nsaction );..  i
8120: 66 28 20 73 69 6d 75 6c 61 74 65 56 74 61 62 45  f( simulateVtabE
8130: 72 72 6f 72 28 70 56 74 61 62 2c 20 22 78 53 79  rror(pVtab, "xSy
8140: 6e 63 22 29 20 29 7b 0a 20 20 20 20 72 65 74 75  nc") ){.    retu
8150: 72 6e 20 53 51 4c 49 54 45 5f 45 52 52 4f 52 3b  rn SQLITE_ERROR;
8160: 0a 20 20 7d 0a 0a 20 20 72 63 20 3d 20 65 63 68  .  }..  rc = ech
8170: 6f 54 72 61 6e 73 61 63 74 69 6f 6e 43 61 6c 6c  oTransactionCall
8180: 28 74 61 62 2c 20 22 78 53 79 6e 63 22 29 3b 0a  (tab, "xSync");.
8190: 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54  .  if( rc==SQLIT
81a0: 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 2f 2a 20 43  E_OK ){.    /* C
81b0: 68 65 63 6b 20 69 66 20 74 68 65 20 24 3a 3a 65  heck if the $::e
81c0: 63 68 6f 5f 6d 6f 64 75 6c 65 5f 73 79 6e 63 5f  cho_module_sync_
81d0: 66 61 69 6c 20 76 61 72 69 61 62 6c 65 20 69 73  fail variable is
81e0: 20 64 65 66 69 6e 65 64 2e 20 49 66 20 69 74 20   defined. If it 
81f0: 69 73 2c 0a 20 20 20 20 2a 2a 20 61 6e 64 20 69  is,.    ** and i
8200: 74 20 69 73 20 73 65 74 20 74 6f 20 74 68 65 20  t is set to the 
8210: 6e 61 6d 65 20 6f 66 20 74 68 65 20 72 65 61 6c  name of the real
8220: 20 74 61 62 6c 65 20 75 6e 64 65 72 6c 79 69 6e   table underlyin
8230: 67 20 74 68 69 73 20 76 69 72 74 75 61 6c 0a 20  g this virtual. 
8240: 20 20 20 2a 2a 20 65 63 68 6f 20 6d 6f 64 75 6c     ** echo modul
8250: 65 20 74 61 62 6c 65 2c 20 74 68 65 6e 20 63 61  e table, then ca
8260: 75 73 65 20 74 68 69 73 20 78 53 79 6e 63 20 6f  use this xSync o
8270: 70 65 72 61 74 69 6f 6e 20 74 6f 20 66 61 69 6c  peration to fail
8280: 2e 0a 20 20 20 20 2a 2f 0a 20 20 20 20 7a 56 61  ..    */.    zVa
8290: 6c 20 3d 20 54 63 6c 5f 47 65 74 56 61 72 28 69  l = Tcl_GetVar(i
82a0: 6e 74 65 72 70 2c 20 22 65 63 68 6f 5f 6d 6f 64  nterp, "echo_mod
82b0: 75 6c 65 5f 73 79 6e 63 5f 66 61 69 6c 22 2c 20  ule_sync_fail", 
82c0: 54 43 4c 5f 47 4c 4f 42 41 4c 5f 4f 4e 4c 59 29  TCL_GLOBAL_ONLY)
82d0: 3b 0a 20 20 20 20 69 66 28 20 7a 56 61 6c 20 26  ;.    if( zVal &
82e0: 26 20 30 3d 3d 73 74 72 63 6d 70 28 7a 56 61 6c  & 0==strcmp(zVal
82f0: 2c 20 70 56 74 61 62 2d 3e 7a 54 61 62 6c 65 4e  , pVtab->zTableN
8300: 61 6d 65 29 20 29 7b 0a 20 20 20 20 20 20 72 63  ame) ){.      rc
8310: 20 3d 20 2d 31 3b 0a 20 20 20 20 7d 0a 20 20 7d   = -1;.    }.  }
8320: 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a  .  return rc;.}.
8330: 73 74 61 74 69 63 20 69 6e 74 20 65 63 68 6f 43  static int echoC
8340: 6f 6d 6d 69 74 28 73 71 6c 69 74 65 33 5f 76 74  ommit(sqlite3_vt
8350: 61 62 20 2a 74 61 62 29 7b 0a 20 20 65 63 68 6f  ab *tab){.  echo
8360: 5f 76 74 61 62 20 2a 70 56 74 61 62 20 3d 20 28  _vtab *pVtab = (
8370: 65 63 68 6f 5f 76 74 61 62 2a 29 74 61 62 3b 0a  echo_vtab*)tab;.
8380: 20 20 69 6e 74 20 72 63 3b 0a 0a 20 20 2f 2a 20    int rc;..  /* 
8390: 54 69 63 6b 65 74 20 23 33 30 38 33 20 2d 20 4f  Ticket #3083 - O
83a0: 6e 6c 79 20 63 61 6c 6c 20 78 43 6f 6d 6d 69 74  nly call xCommit
83b0: 20 69 66 20 77 65 20 68 61 76 65 20 70 72 65 76   if we have prev
83c0: 69 6f 75 73 6c 79 20 73 74 61 72 74 65 64 0a 20  iously started. 
83d0: 20 2a 2a 20 61 20 74 72 61 6e 73 61 63 74 69 6f   ** a transactio
83e0: 6e 20 2a 2f 0a 20 20 61 73 73 65 72 74 28 20 70  n */.  assert( p
83f0: 56 74 61 62 2d 3e 69 6e 54 72 61 6e 73 61 63 74  Vtab->inTransact
8400: 69 6f 6e 20 29 3b 0a 0a 20 20 69 66 28 20 73 69  ion );..  if( si
8410: 6d 75 6c 61 74 65 56 74 61 62 45 72 72 6f 72 28  mulateVtabError(
8420: 70 56 74 61 62 2c 20 22 78 43 6f 6d 6d 69 74 22  pVtab, "xCommit"
8430: 29 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20  ) ){.    return 
8440: 53 51 4c 49 54 45 5f 45 52 52 4f 52 3b 0a 20 20  SQLITE_ERROR;.  
8450: 7d 0a 0a 20 20 73 71 6c 69 74 65 33 42 65 67 69  }..  sqlite3Begi
8460: 6e 42 65 6e 69 67 6e 4d 61 6c 6c 6f 63 28 29 3b  nBenignMalloc();
8470: 0a 20 20 72 63 20 3d 20 65 63 68 6f 54 72 61 6e  .  rc = echoTran
8480: 73 61 63 74 69 6f 6e 43 61 6c 6c 28 74 61 62 2c  sactionCall(tab,
8490: 20 22 78 43 6f 6d 6d 69 74 22 29 3b 0a 20 20 73   "xCommit");.  s
84a0: 71 6c 69 74 65 33 45 6e 64 42 65 6e 69 67 6e 4d  qlite3EndBenignM
84b0: 61 6c 6c 6f 63 28 29 3b 0a 20 20 70 56 74 61 62  alloc();.  pVtab
84c0: 2d 3e 69 6e 54 72 61 6e 73 61 63 74 69 6f 6e 20  ->inTransaction 
84d0: 3d 20 30 3b 0a 20 20 72 65 74 75 72 6e 20 72 63  = 0;.  return rc
84e0: 3b 0a 7d 0a 73 74 61 74 69 63 20 69 6e 74 20 65  ;.}.static int e
84f0: 63 68 6f 52 6f 6c 6c 62 61 63 6b 28 73 71 6c 69  choRollback(sqli
8500: 74 65 33 5f 76 74 61 62 20 2a 74 61 62 29 7b 0a  te3_vtab *tab){.
8510: 20 20 69 6e 74 20 72 63 3b 0a 20 20 65 63 68 6f    int rc;.  echo
8520: 5f 76 74 61 62 20 2a 70 56 74 61 62 20 3d 20 28  _vtab *pVtab = (
8530: 65 63 68 6f 5f 76 74 61 62 2a 29 74 61 62 3b 0a  echo_vtab*)tab;.
8540: 0a 20 20 2f 2a 20 54 69 63 6b 65 74 20 23 33 30  .  /* Ticket #30
8550: 38 33 20 2d 20 4f 6e 6c 79 20 63 61 6c 6c 20 78  83 - Only call x
8560: 52 6f 6c 6c 62 61 63 6b 20 69 66 20 77 65 20 68  Rollback if we h
8570: 61 76 65 20 70 72 65 76 69 6f 75 73 6c 79 20 73  ave previously s
8580: 74 61 72 74 65 64 0a 20 20 2a 2a 20 61 20 74 72  tarted.  ** a tr
8590: 61 6e 73 61 63 74 69 6f 6e 20 2a 2f 0a 20 20 61  ansaction */.  a
85a0: 73 73 65 72 74 28 20 70 56 74 61 62 2d 3e 69 6e  ssert( pVtab->in
85b0: 54 72 61 6e 73 61 63 74 69 6f 6e 20 29 3b 0a 0a  Transaction );..
85c0: 20 20 72 63 20 3d 20 65 63 68 6f 54 72 61 6e 73    rc = echoTrans
85d0: 61 63 74 69 6f 6e 43 61 6c 6c 28 74 61 62 2c 20  actionCall(tab, 
85e0: 22 78 52 6f 6c 6c 62 61 63 6b 22 29 3b 0a 20 20  "xRollback");.  
85f0: 70 56 74 61 62 2d 3e 69 6e 54 72 61 6e 73 61 63  pVtab->inTransac
8600: 74 69 6f 6e 20 3d 20 30 3b 0a 20 20 72 65 74 75  tion = 0;.  retu
8610: 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  rn rc;.}../*.** 
8620: 49 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f  Implementation o
8630: 66 20 22 47 4c 4f 42 22 20 66 75 6e 63 74 69 6f  f "GLOB" functio
8640: 6e 20 6f 6e 20 74 68 65 20 65 63 68 6f 20 6d 6f  n on the echo mo
8650: 64 75 6c 65 2e 20 20 50 61 73 73 0a 2a 2a 20 61  dule.  Pass.** a
8660: 6c 6c 20 61 72 67 75 6d 65 6e 74 73 20 74 6f 20  ll arguments to 
8670: 74 68 65 20 3a 3a 65 63 68 6f 5f 67 6c 6f 62 5f  the ::echo_glob_
8680: 6f 76 65 72 6c 6f 61 64 20 70 72 6f 63 65 64 75  overload procedu
8690: 72 65 20 6f 66 20 54 43 4c 0a 2a 2a 20 61 6e 64  re of TCL.** and
86a0: 20 72 65 74 75 72 6e 20 74 68 65 20 72 65 73 75   return the resu
86b0: 6c 74 20 6f 66 20 74 68 61 74 20 70 72 6f 63 65  lt of that proce
86c0: 64 75 72 65 20 61 73 20 61 20 73 74 72 69 6e 67  dure as a string
86d0: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64  ..*/.static void
86e0: 20 6f 76 65 72 6c 6f 61 64 65 64 47 6c 6f 62 46   overloadedGlobF
86f0: 75 6e 63 74 69 6f 6e 28 0a 20 20 73 71 6c 69 74  unction(.  sqlit
8700: 65 33 5f 63 6f 6e 74 65 78 74 20 2a 70 43 6f 6e  e3_context *pCon
8710: 74 65 78 74 2c 0a 20 20 69 6e 74 20 6e 41 72 67  text,.  int nArg
8720: 2c 0a 20 20 73 71 6c 69 74 65 33 5f 76 61 6c 75  ,.  sqlite3_valu
8730: 65 20 2a 2a 61 70 41 72 67 0a 29 7b 0a 20 20 54  e **apArg.){.  T
8740: 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72  cl_Interp *inter
8750: 70 20 3d 20 73 71 6c 69 74 65 33 5f 75 73 65 72  p = sqlite3_user
8760: 5f 64 61 74 61 28 70 43 6f 6e 74 65 78 74 29 3b  _data(pContext);
8770: 0a 20 20 54 63 6c 5f 44 53 74 72 69 6e 67 20 73  .  Tcl_DString s
8780: 74 72 3b 0a 20 20 69 6e 74 20 69 3b 0a 20 20 69  tr;.  int i;.  i
8790: 6e 74 20 72 63 3b 0a 20 20 54 63 6c 5f 44 53 74  nt rc;.  Tcl_DSt
87a0: 72 69 6e 67 49 6e 69 74 28 26 73 74 72 29 3b 0a  ringInit(&str);.
87b0: 20 20 54 63 6c 5f 44 53 74 72 69 6e 67 41 70 70    Tcl_DStringApp
87c0: 65 6e 64 45 6c 65 6d 65 6e 74 28 26 73 74 72 2c  endElement(&str,
87d0: 20 22 3a 3a 65 63 68 6f 5f 67 6c 6f 62 5f 6f 76   "::echo_glob_ov
87e0: 65 72 6c 6f 61 64 22 29 3b 0a 20 20 66 6f 72 28  erload");.  for(
87f0: 69 3d 30 3b 20 69 3c 6e 41 72 67 3b 20 69 2b 2b  i=0; i<nArg; i++
8800: 29 7b 0a 20 20 20 20 54 63 6c 5f 44 53 74 72 69  ){.    Tcl_DStri
8810: 6e 67 41 70 70 65 6e 64 45 6c 65 6d 65 6e 74 28  ngAppendElement(
8820: 26 73 74 72 2c 20 28 63 68 61 72 2a 29 73 71 6c  &str, (char*)sql
8830: 69 74 65 33 5f 76 61 6c 75 65 5f 74 65 78 74 28  ite3_value_text(
8840: 61 70 41 72 67 5b 69 5d 29 29 3b 0a 20 20 7d 0a  apArg[i]));.  }.
8850: 20 20 72 63 20 3d 20 54 63 6c 5f 45 76 61 6c 28    rc = Tcl_Eval(
8860: 69 6e 74 65 72 70 2c 20 54 63 6c 5f 44 53 74 72  interp, Tcl_DStr
8870: 69 6e 67 56 61 6c 75 65 28 26 73 74 72 29 29 3b  ingValue(&str));
8880: 0a 20 20 54 63 6c 5f 44 53 74 72 69 6e 67 46 72  .  Tcl_DStringFr
8890: 65 65 28 26 73 74 72 29 3b 0a 20 20 69 66 28 20  ee(&str);.  if( 
88a0: 72 63 20 29 7b 0a 20 20 20 20 73 71 6c 69 74 65  rc ){.    sqlite
88b0: 33 5f 72 65 73 75 6c 74 5f 65 72 72 6f 72 28 70  3_result_error(p
88c0: 43 6f 6e 74 65 78 74 2c 20 54 63 6c 5f 47 65 74  Context, Tcl_Get
88d0: 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e 74  StringResult(int
88e0: 65 72 70 29 2c 20 2d 31 29 3b 0a 20 20 7d 65 6c  erp), -1);.  }el
88f0: 73 65 7b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f  se{.    sqlite3_
8900: 72 65 73 75 6c 74 5f 74 65 78 74 28 70 43 6f 6e  result_text(pCon
8910: 74 65 78 74 2c 20 54 63 6c 5f 47 65 74 53 74 72  text, Tcl_GetStr
8920: 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70  ingResult(interp
8930: 29 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  ),.             
8940: 20 20 20 20 20 20 20 20 20 20 20 2d 31 2c 20 53             -1, S
8950: 51 4c 49 54 45 5f 54 52 41 4e 53 49 45 4e 54 29  QLITE_TRANSIENT)
8960: 3b 0a 20 20 7d 0a 20 20 54 63 6c 5f 52 65 73 65  ;.  }.  Tcl_Rese
8970: 74 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29 3b  tResult(interp);
8980: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 69  .}../*.** This i
8990: 73 20 74 68 65 20 78 46 69 6e 64 46 75 6e 63 74  s the xFindFunct
89a0: 69 6f 6e 20 69 6d 70 6c 65 6d 65 6e 74 61 74 69  ion implementati
89b0: 6f 6e 20 66 6f 72 20 74 68 65 20 65 63 68 6f 20  on for the echo 
89c0: 6d 6f 64 75 6c 65 2e 0a 2a 2a 20 53 51 4c 69 74  module..** SQLit
89d0: 65 20 63 61 6c 6c 73 20 74 68 69 73 20 72 6f 75  e calls this rou
89e0: 74 69 6e 65 20 77 68 65 6e 20 74 68 65 20 66 69  tine when the fi
89f0: 72 73 74 20 61 72 67 75 6d 65 6e 74 20 6f 66 20  rst argument of 
8a00: 61 20 66 75 6e 63 74 69 6f 6e 0a 2a 2a 20 69 73  a function.** is
8a10: 20 61 20 63 6f 6c 75 6d 6e 20 6f 66 20 61 6e 20   a column of an 
8a20: 65 63 68 6f 20 76 69 72 74 75 61 6c 20 74 61 62  echo virtual tab
8a30: 6c 65 2e 20 20 54 68 69 73 20 72 6f 75 74 69 6e  le.  This routin
8a40: 65 20 63 61 6e 20 6f 70 74 69 6f 6e 61 6c 6c 79  e can optionally
8a50: 0a 2a 2a 20 6f 76 65 72 72 69 64 65 20 74 68 65  .** override the
8a60: 20 69 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20   implementation 
8a70: 6f 66 20 74 68 61 74 20 66 75 6e 63 74 69 6f 6e  of that function
8a80: 2e 20 20 49 74 20 77 69 6c 6c 20 63 68 6f 6f 73  .  It will choos
8a90: 65 20 74 6f 0a 2a 2a 20 64 6f 20 73 6f 20 69 66  e to.** do so if
8aa0: 20 74 68 65 20 66 75 6e 63 74 69 6f 6e 20 69 73   the function is
8ab0: 20 6e 61 6d 65 64 20 22 67 6c 6f 62 22 2c 20 61   named "glob", a
8ac0: 6e 64 20 61 20 54 43 4c 20 63 6f 6d 6d 61 6e 64  nd a TCL command
8ad0: 20 6e 61 6d 65 64 0a 2a 2a 20 3a 3a 65 63 68 6f   named.** ::echo
8ae0: 5f 67 6c 6f 62 5f 6f 76 65 72 6c 6f 61 64 20 65  _glob_overload e
8af0: 78 69 73 74 73 2e 0a 2a 2f 0a 73 74 61 74 69 63  xists..*/.static
8b00: 20 69 6e 74 20 65 63 68 6f 46 69 6e 64 46 75 6e   int echoFindFun
8b10: 63 74 69 6f 6e 28 0a 20 20 73 71 6c 69 74 65 33  ction(.  sqlite3
8b20: 5f 76 74 61 62 20 2a 76 74 61 62 2c 0a 20 20 69  _vtab *vtab,.  i
8b30: 6e 74 20 6e 41 72 67 2c 0a 20 20 63 6f 6e 73 74  nt nArg,.  const
8b40: 20 63 68 61 72 20 2a 7a 46 75 6e 63 4e 61 6d 65   char *zFuncName
8b50: 2c 0a 20 20 76 6f 69 64 20 28 2a 2a 70 78 46 75  ,.  void (**pxFu
8b60: 6e 63 29 28 73 71 6c 69 74 65 33 5f 63 6f 6e 74  nc)(sqlite3_cont
8b70: 65 78 74 2a 2c 69 6e 74 2c 73 71 6c 69 74 65 33  ext*,int,sqlite3
8b80: 5f 76 61 6c 75 65 2a 2a 29 2c 0a 20 20 76 6f 69  _value**),.  voi
8b90: 64 20 2a 2a 70 70 41 72 67 0a 29 7b 0a 20 20 65  d **ppArg.){.  e
8ba0: 63 68 6f 5f 76 74 61 62 20 2a 70 56 74 61 62 20  cho_vtab *pVtab 
8bb0: 3d 20 28 65 63 68 6f 5f 76 74 61 62 20 2a 29 76  = (echo_vtab *)v
8bc0: 74 61 62 3b 0a 20 20 54 63 6c 5f 49 6e 74 65 72  tab;.  Tcl_Inter
8bd0: 70 20 2a 69 6e 74 65 72 70 20 3d 20 70 56 74 61  p *interp = pVta
8be0: 62 2d 3e 69 6e 74 65 72 70 3b 0a 20 20 54 63 6c  b->interp;.  Tcl
8bf0: 5f 43 6d 64 49 6e 66 6f 20 69 6e 66 6f 3b 0a 20  _CmdInfo info;. 
8c00: 20 69 66 28 20 73 74 72 63 6d 70 28 7a 46 75 6e   if( strcmp(zFun
8c10: 63 4e 61 6d 65 2c 22 67 6c 6f 62 22 29 21 3d 30  cName,"glob")!=0
8c20: 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 30   ){.    return 0
8c30: 3b 0a 20 20 7d 0a 20 20 69 66 28 20 54 63 6c 5f  ;.  }.  if( Tcl_
8c40: 47 65 74 43 6f 6d 6d 61 6e 64 49 6e 66 6f 28 69  GetCommandInfo(i
8c50: 6e 74 65 72 70 2c 20 22 3a 3a 65 63 68 6f 5f 67  nterp, "::echo_g
8c60: 6c 6f 62 5f 6f 76 65 72 6c 6f 61 64 22 2c 20 26  lob_overload", &
8c70: 69 6e 66 6f 29 3d 3d 30 20 29 7b 0a 20 20 20 20  info)==0 ){.    
8c80: 72 65 74 75 72 6e 20 30 3b 0a 20 20 7d 0a 20 20  return 0;.  }.  
8c90: 2a 70 78 46 75 6e 63 20 3d 20 6f 76 65 72 6c 6f  *pxFunc = overlo
8ca0: 61 64 65 64 47 6c 6f 62 46 75 6e 63 74 69 6f 6e  adedGlobFunction
8cb0: 3b 0a 20 20 2a 70 70 41 72 67 20 3d 20 69 6e 74  ;.  *ppArg = int
8cc0: 65 72 70 3b 0a 20 20 72 65 74 75 72 6e 20 31 3b  erp;.  return 1;
8cd0: 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 65  .}..static int e
8ce0: 63 68 6f 52 65 6e 61 6d 65 28 73 71 6c 69 74 65  choRename(sqlite
8cf0: 33 5f 76 74 61 62 20 2a 76 74 61 62 2c 20 63 6f  3_vtab *vtab, co
8d00: 6e 73 74 20 63 68 61 72 20 2a 7a 4e 65 77 4e 61  nst char *zNewNa
8d10: 6d 65 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20  me){.  int rc = 
8d20: 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 65 63 68  SQLITE_OK;.  ech
8d30: 6f 5f 76 74 61 62 20 2a 70 20 3d 20 28 65 63 68  o_vtab *p = (ech
8d40: 6f 5f 76 74 61 62 20 2a 29 76 74 61 62 3b 0a 0a  o_vtab *)vtab;..
8d50: 20 20 69 66 28 20 73 69 6d 75 6c 61 74 65 56 74    if( simulateVt
8d60: 61 62 45 72 72 6f 72 28 70 2c 20 22 78 52 65 6e  abError(p, "xRen
8d70: 61 6d 65 22 29 20 29 7b 0a 20 20 20 20 72 65 74  ame") ){.    ret
8d80: 75 72 6e 20 53 51 4c 49 54 45 5f 45 52 52 4f 52  urn SQLITE_ERROR
8d90: 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 70 2d 3e  ;.  }..  if( p->
8da0: 69 73 50 61 74 74 65 72 6e 20 29 7b 0a 20 20 20  isPattern ){.   
8db0: 20 69 6e 74 20 6e 54 68 69 73 20 3d 20 28 69 6e   int nThis = (in
8dc0: 74 29 73 74 72 6c 65 6e 28 70 2d 3e 7a 54 68 69  t)strlen(p->zThi
8dd0: 73 29 3b 0a 20 20 20 20 63 68 61 72 20 2a 7a 53  s);.    char *zS
8de0: 71 6c 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72  ql = sqlite3_mpr
8df0: 69 6e 74 66 28 22 41 4c 54 45 52 20 54 41 42 4c  intf("ALTER TABL
8e00: 45 20 25 73 20 52 45 4e 41 4d 45 20 54 4f 20 25  E %s RENAME TO %
8e10: 73 25 73 22 2c 20 0a 20 20 20 20 20 20 20 20 70  s%s", .        p
8e20: 2d 3e 7a 54 61 62 6c 65 4e 61 6d 65 2c 20 7a 4e  ->zTableName, zN
8e30: 65 77 4e 61 6d 65 2c 20 26 70 2d 3e 7a 54 61 62  ewName, &p->zTab
8e40: 6c 65 4e 61 6d 65 5b 6e 54 68 69 73 5d 0a 20 20  leName[nThis].  
8e50: 20 20 29 3b 0a 20 20 20 20 72 63 20 3d 20 73 71    );.    rc = sq
8e60: 6c 69 74 65 33 5f 65 78 65 63 28 70 2d 3e 64 62  lite3_exec(p->db
8e70: 2c 20 7a 53 71 6c 2c 20 30 2c 20 30 2c 20 30 29  , zSql, 0, 0, 0)
8e80: 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72  ;.    sqlite3_fr
8e90: 65 65 28 7a 53 71 6c 29 3b 0a 20 20 7d 0a 0a 20  ee(zSql);.  }.. 
8ea0: 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 73   return rc;.}..s
8eb0: 74 61 74 69 63 20 69 6e 74 20 65 63 68 6f 53 61  tatic int echoSa
8ec0: 76 65 70 6f 69 6e 74 28 73 71 6c 69 74 65 33 5f  vepoint(sqlite3_
8ed0: 76 74 61 62 20 2a 70 56 54 61 62 2c 20 69 6e 74  vtab *pVTab, int
8ee0: 20 69 53 61 76 65 70 6f 69 6e 74 29 7b 0a 20 20   iSavepoint){.  
8ef0: 61 73 73 65 72 74 28 20 70 56 54 61 62 20 29 3b  assert( pVTab );
8f00: 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45  .  return SQLITE
8f10: 5f 4f 4b 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69  _OK;.}..static i
8f20: 6e 74 20 65 63 68 6f 52 65 6c 65 61 73 65 28 73  nt echoRelease(s
8f30: 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 70 56 54  qlite3_vtab *pVT
8f40: 61 62 2c 20 69 6e 74 20 69 53 61 76 65 70 6f 69  ab, int iSavepoi
8f50: 6e 74 29 7b 0a 20 20 61 73 73 65 72 74 28 20 70  nt){.  assert( p
8f60: 56 54 61 62 20 29 3b 0a 20 20 72 65 74 75 72 6e  VTab );.  return
8f70: 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 73   SQLITE_OK;.}..s
8f80: 74 61 74 69 63 20 69 6e 74 20 65 63 68 6f 52 6f  tatic int echoRo
8f90: 6c 6c 62 61 63 6b 54 6f 28 73 71 6c 69 74 65 33  llbackTo(sqlite3
8fa0: 5f 76 74 61 62 20 2a 70 56 54 61 62 2c 20 69 6e  _vtab *pVTab, in
8fb0: 74 20 69 53 61 76 65 70 6f 69 6e 74 29 7b 0a 20  t iSavepoint){. 
8fc0: 20 61 73 73 65 72 74 28 20 70 56 54 61 62 20 29   assert( pVTab )
8fd0: 3b 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54  ;.  return SQLIT
8fe0: 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41  E_OK;.}../*.** A
8ff0: 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65 20 6d   virtual table m
9000: 6f 64 75 6c 65 20 74 68 61 74 20 6d 65 72 65 6c  odule that merel
9010: 79 20 22 65 63 68 6f 73 22 20 74 68 65 20 63 6f  y "echos" the co
9020: 6e 74 65 6e 74 73 20 6f 66 20 61 6e 6f 74 68 65  ntents of anothe
9030: 72 0a 2a 2a 20 74 61 62 6c 65 20 28 6c 69 6b 65  r.** table (like
9040: 20 61 6e 20 53 51 4c 20 56 49 45 57 29 2e 0a 2a   an SQL VIEW)..*
9050: 2f 0a 73 74 61 74 69 63 20 73 71 6c 69 74 65 33  /.static sqlite3
9060: 5f 6d 6f 64 75 6c 65 20 65 63 68 6f 4d 6f 64 75  _module echoModu
9070: 6c 65 20 3d 20 7b 0a 20 20 31 2c 20 20 20 20 20  le = {.  1,     
9080: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9090: 20 20 20 20 2f 2a 20 69 56 65 72 73 69 6f 6e 20      /* iVersion 
90a0: 2a 2f 0a 20 20 65 63 68 6f 43 72 65 61 74 65 2c  */.  echoCreate,
90b0: 0a 20 20 65 63 68 6f 43 6f 6e 6e 65 63 74 2c 0a  .  echoConnect,.
90c0: 20 20 65 63 68 6f 42 65 73 74 49 6e 64 65 78 2c    echoBestIndex,
90d0: 0a 20 20 65 63 68 6f 44 69 73 63 6f 6e 6e 65 63  .  echoDisconnec
90e0: 74 2c 20 0a 20 20 65 63 68 6f 44 65 73 74 72 6f  t, .  echoDestro
90f0: 79 2c 0a 20 20 65 63 68 6f 4f 70 65 6e 2c 20 20  y,.  echoOpen,  
9100: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9110: 2f 2a 20 78 4f 70 65 6e 20 2d 20 6f 70 65 6e 20  /* xOpen - open 
9120: 61 20 63 75 72 73 6f 72 20 2a 2f 0a 20 20 65 63  a cursor */.  ec
9130: 68 6f 43 6c 6f 73 65 2c 20 20 20 20 20 20 20 20  hoClose,        
9140: 20 20 20 20 20 20 20 20 20 2f 2a 20 78 43 6c 6f           /* xClo
9150: 73 65 20 2d 20 63 6c 6f 73 65 20 61 20 63 75 72  se - close a cur
9160: 73 6f 72 20 2a 2f 0a 20 20 65 63 68 6f 46 69 6c  sor */.  echoFil
9170: 74 65 72 2c 20 20 20 20 20 20 20 20 20 20 20 20  ter,            
9180: 20 20 20 20 2f 2a 20 78 46 69 6c 74 65 72 20 2d      /* xFilter -
9190: 20 63 6f 6e 66 69 67 75 72 65 20 73 63 61 6e 20   configure scan 
91a0: 63 6f 6e 73 74 72 61 69 6e 74 73 20 2a 2f 0a 20  constraints */. 
91b0: 20 65 63 68 6f 4e 65 78 74 2c 20 20 20 20 20 20   echoNext,      
91c0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78              /* x
91d0: 4e 65 78 74 20 2d 20 61 64 76 61 6e 63 65 20 61  Next - advance a
91e0: 20 63 75 72 73 6f 72 20 2a 2f 0a 20 20 65 63 68   cursor */.  ech
91f0: 6f 45 6f 66 2c 20 20 20 20 20 20 20 20 20 20 20  oEof,           
9200: 20 20 20 20 20 20 20 20 2f 2a 20 78 45 6f 66 20          /* xEof 
9210: 2a 2f 0a 20 20 65 63 68 6f 43 6f 6c 75 6d 6e 2c  */.  echoColumn,
9220: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9230: 2f 2a 20 78 43 6f 6c 75 6d 6e 20 2d 20 72 65 61  /* xColumn - rea
9240: 64 20 64 61 74 61 20 2a 2f 0a 20 20 65 63 68 6f  d data */.  echo
9250: 52 6f 77 69 64 2c 20 20 20 20 20 20 20 20 20 20  Rowid,          
9260: 20 20 20 20 20 20 20 2f 2a 20 78 52 6f 77 69 64         /* xRowid
9270: 20 2d 20 72 65 61 64 20 64 61 74 61 20 2a 2f 0a   - read data */.
9280: 20 20 65 63 68 6f 55 70 64 61 74 65 2c 20 20 20    echoUpdate,   
9290: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
92a0: 78 55 70 64 61 74 65 20 2d 20 77 72 69 74 65 20  xUpdate - write 
92b0: 64 61 74 61 20 2a 2f 0a 20 20 65 63 68 6f 42 65  data */.  echoBe
92c0: 67 69 6e 2c 20 20 20 20 20 20 20 20 20 20 20 20  gin,            
92d0: 20 20 20 20 20 2f 2a 20 78 42 65 67 69 6e 20 2d       /* xBegin -
92e0: 20 62 65 67 69 6e 20 74 72 61 6e 73 61 63 74 69   begin transacti
92f0: 6f 6e 20 2a 2f 0a 20 20 65 63 68 6f 53 79 6e 63  on */.  echoSync
9300: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
9310: 20 20 20 2f 2a 20 78 53 79 6e 63 20 2d 20 73 79     /* xSync - sy
9320: 6e 63 20 74 72 61 6e 73 61 63 74 69 6f 6e 20 2a  nc transaction *
9330: 2f 0a 20 20 65 63 68 6f 43 6f 6d 6d 69 74 2c 20  /.  echoCommit, 
9340: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
9350: 2a 20 78 43 6f 6d 6d 69 74 20 2d 20 63 6f 6d 6d  * xCommit - comm
9360: 69 74 20 74 72 61 6e 73 61 63 74 69 6f 6e 20 2a  it transaction *
9370: 2f 0a 20 20 65 63 68 6f 52 6f 6c 6c 62 61 63 6b  /.  echoRollback
9380: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f  ,              /
9390: 2a 20 78 52 6f 6c 6c 62 61 63 6b 20 2d 20 72 6f  * xRollback - ro
93a0: 6c 6c 62 61 63 6b 20 74 72 61 6e 73 61 63 74 69  llback transacti
93b0: 6f 6e 20 2a 2f 0a 20 20 65 63 68 6f 46 69 6e 64  on */.  echoFind
93c0: 46 75 6e 63 74 69 6f 6e 2c 20 20 20 20 20 20 20  Function,       
93d0: 20 20 20 2f 2a 20 78 46 69 6e 64 46 75 6e 63 74     /* xFindFunct
93e0: 69 6f 6e 20 2d 20 66 75 6e 63 74 69 6f 6e 20 6f  ion - function o
93f0: 76 65 72 6c 6f 61 64 69 6e 67 20 2a 2f 0a 20 20  verloading */.  
9400: 65 63 68 6f 52 65 6e 61 6d 65 20 20 20 20 20 20  echoRename      
9410: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 52             /* xR
9420: 65 6e 61 6d 65 20 2d 20 72 65 6e 61 6d 65 20 74  ename - rename t
9430: 68 65 20 74 61 62 6c 65 20 2a 2f 0a 7d 3b 0a 0a  he table */.};..
9440: 73 74 61 74 69 63 20 73 71 6c 69 74 65 33 5f 6d  static sqlite3_m
9450: 6f 64 75 6c 65 20 65 63 68 6f 4d 6f 64 75 6c 65  odule echoModule
9460: 56 32 20 3d 20 7b 0a 20 20 32 2c 20 20 20 20 20  V2 = {.  2,     
9470: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9480: 20 20 20 20 2f 2a 20 69 56 65 72 73 69 6f 6e 20      /* iVersion 
9490: 2a 2f 0a 20 20 65 63 68 6f 43 72 65 61 74 65 2c  */.  echoCreate,
94a0: 0a 20 20 65 63 68 6f 43 6f 6e 6e 65 63 74 2c 0a  .  echoConnect,.
94b0: 20 20 65 63 68 6f 42 65 73 74 49 6e 64 65 78 2c    echoBestIndex,
94c0: 0a 20 20 65 63 68 6f 44 69 73 63 6f 6e 6e 65 63  .  echoDisconnec
94d0: 74 2c 20 0a 20 20 65 63 68 6f 44 65 73 74 72 6f  t, .  echoDestro
94e0: 79 2c 0a 20 20 65 63 68 6f 4f 70 65 6e 2c 20 20  y,.  echoOpen,  
94f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9500: 2f 2a 20 78 4f 70 65 6e 20 2d 20 6f 70 65 6e 20  /* xOpen - open 
9510: 61 20 63 75 72 73 6f 72 20 2a 2f 0a 20 20 65 63  a cursor */.  ec
9520: 68 6f 43 6c 6f 73 65 2c 20 20 20 20 20 20 20 20  hoClose,        
9530: 20 20 20 20 20 20 20 20 20 2f 2a 20 78 43 6c 6f           /* xClo
9540: 73 65 20 2d 20 63 6c 6f 73 65 20 61 20 63 75 72  se - close a cur
9550: 73 6f 72 20 2a 2f 0a 20 20 65 63 68 6f 46 69 6c  sor */.  echoFil
9560: 74 65 72 2c 20 20 20 20 20 20 20 20 20 20 20 20  ter,            
9570: 20 20 20 20 2f 2a 20 78 46 69 6c 74 65 72 20 2d      /* xFilter -
9580: 20 63 6f 6e 66 69 67 75 72 65 20 73 63 61 6e 20   configure scan 
9590: 63 6f 6e 73 74 72 61 69 6e 74 73 20 2a 2f 0a 20  constraints */. 
95a0: 20 65 63 68 6f 4e 65 78 74 2c 20 20 20 20 20 20   echoNext,      
95b0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78              /* x
95c0: 4e 65 78 74 20 2d 20 61 64 76 61 6e 63 65 20 61  Next - advance a
95d0: 20 63 75 72 73 6f 72 20 2a 2f 0a 20 20 65 63 68   cursor */.  ech
95e0: 6f 45 6f 66 2c 20 20 20 20 20 20 20 20 20 20 20  oEof,           
95f0: 20 20 20 20 20 20 20 20 2f 2a 20 78 45 6f 66 20          /* xEof 
9600: 2a 2f 0a 20 20 65 63 68 6f 43 6f 6c 75 6d 6e 2c  */.  echoColumn,
9610: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9620: 2f 2a 20 78 43 6f 6c 75 6d 6e 20 2d 20 72 65 61  /* xColumn - rea
9630: 64 20 64 61 74 61 20 2a 2f 0a 20 20 65 63 68 6f  d data */.  echo
9640: 52 6f 77 69 64 2c 20 20 20 20 20 20 20 20 20 20  Rowid,          
9650: 20 20 20 20 20 20 20 2f 2a 20 78 52 6f 77 69 64         /* xRowid
9660: 20 2d 20 72 65 61 64 20 64 61 74 61 20 2a 2f 0a   - read data */.
9670: 20 20 65 63 68 6f 55 70 64 61 74 65 2c 20 20 20    echoUpdate,   
9680: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
9690: 78 55 70 64 61 74 65 20 2d 20 77 72 69 74 65 20  xUpdate - write 
96a0: 64 61 74 61 20 2a 2f 0a 20 20 65 63 68 6f 42 65  data */.  echoBe
96b0: 67 69 6e 2c 20 20 20 20 20 20 20 20 20 20 20 20  gin,            
96c0: 20 20 20 20 20 2f 2a 20 78 42 65 67 69 6e 20 2d       /* xBegin -
96d0: 20 62 65 67 69 6e 20 74 72 61 6e 73 61 63 74 69   begin transacti
96e0: 6f 6e 20 2a 2f 0a 20 20 65 63 68 6f 53 79 6e 63  on */.  echoSync
96f0: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
9700: 20 20 20 2f 2a 20 78 53 79 6e 63 20 2d 20 73 79     /* xSync - sy
9710: 6e 63 20 74 72 61 6e 73 61 63 74 69 6f 6e 20 2a  nc transaction *
9720: 2f 0a 20 20 65 63 68 6f 43 6f 6d 6d 69 74 2c 20  /.  echoCommit, 
9730: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
9740: 2a 20 78 43 6f 6d 6d 69 74 20 2d 20 63 6f 6d 6d  * xCommit - comm
9750: 69 74 20 74 72 61 6e 73 61 63 74 69 6f 6e 20 2a  it transaction *
9760: 2f 0a 20 20 65 63 68 6f 52 6f 6c 6c 62 61 63 6b  /.  echoRollback
9770: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f  ,              /
9780: 2a 20 78 52 6f 6c 6c 62 61 63 6b 20 2d 20 72 6f  * xRollback - ro
9790: 6c 6c 62 61 63 6b 20 74 72 61 6e 73 61 63 74 69  llback transacti
97a0: 6f 6e 20 2a 2f 0a 20 20 65 63 68 6f 46 69 6e 64  on */.  echoFind
97b0: 46 75 6e 63 74 69 6f 6e 2c 20 20 20 20 20 20 20  Function,       
97c0: 20 20 20 2f 2a 20 78 46 69 6e 64 46 75 6e 63 74     /* xFindFunct
97d0: 69 6f 6e 20 2d 20 66 75 6e 63 74 69 6f 6e 20 6f  ion - function o
97e0: 76 65 72 6c 6f 61 64 69 6e 67 20 2a 2f 0a 20 20  verloading */.  
97f0: 65 63 68 6f 52 65 6e 61 6d 65 2c 20 20 20 20 20  echoRename,     
9800: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 52             /* xR
9810: 65 6e 61 6d 65 20 2d 20 72 65 6e 61 6d 65 20 74  ename - rename t
9820: 68 65 20 74 61 62 6c 65 20 2a 2f 0a 20 20 65 63  he table */.  ec
9830: 68 6f 53 61 76 65 70 6f 69 6e 74 2c 0a 20 20 65  hoSavepoint,.  e
9840: 63 68 6f 52 65 6c 65 61 73 65 2c 0a 20 20 65 63  choRelease,.  ec
9850: 68 6f 52 6f 6c 6c 62 61 63 6b 54 6f 0a 7d 3b 0a  hoRollbackTo.};.
9860: 0a 2f 2a 0a 2a 2a 20 44 65 63 6f 64 65 20 61 20  ./*.** Decode a 
9870: 70 6f 69 6e 74 65 72 20 74 6f 20 61 6e 20 73 71  pointer to an sq
9880: 6c 69 74 65 33 20 6f 62 6a 65 63 74 2e 0a 2a 2f  lite3 object..*/
9890: 0a 65 78 74 65 72 6e 20 69 6e 74 20 67 65 74 44  .extern int getD
98a0: 62 50 6f 69 6e 74 65 72 28 54 63 6c 5f 49 6e 74  bPointer(Tcl_Int
98b0: 65 72 70 20 2a 69 6e 74 65 72 70 2c 20 63 6f 6e  erp *interp, con
98c0: 73 74 20 63 68 61 72 20 2a 7a 41 2c 20 73 71 6c  st char *zA, sql
98d0: 69 74 65 33 20 2a 2a 70 70 44 62 29 3b 0a 65 78  ite3 **ppDb);.ex
98e0: 74 65 72 6e 20 63 6f 6e 73 74 20 63 68 61 72 20  tern const char 
98f0: 2a 73 71 6c 69 74 65 33 45 72 72 4e 61 6d 65 28  *sqlite3ErrName(
9900: 69 6e 74 29 3b 0a 0a 73 74 61 74 69 63 20 76 6f  int);..static vo
9910: 69 64 20 6d 6f 64 75 6c 65 44 65 73 74 72 6f 79  id moduleDestroy
9920: 28 76 6f 69 64 20 2a 70 29 7b 0a 20 20 73 71 6c  (void *p){.  sql
9930: 69 74 65 33 5f 66 72 65 65 28 70 29 3b 0a 7d 0a  ite3_free(p);.}.
9940: 0a 2f 2a 0a 2a 2a 20 52 65 67 69 73 74 65 72 20  ./*.** Register 
9950: 74 68 65 20 65 63 68 6f 20 76 69 72 74 75 61 6c  the echo virtual
9960: 20 74 61 62 6c 65 20 6d 6f 64 75 6c 65 2e 0a 2a   table module..*
9970: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 53 51 4c  /.static int SQL
9980: 49 54 45 5f 54 43 4c 41 50 49 20 72 65 67 69 73  ITE_TCLAPI regis
9990: 74 65 72 5f 65 63 68 6f 5f 6d 6f 64 75 6c 65 28  ter_echo_module(
99a0: 0a 20 20 43 6c 69 65 6e 74 44 61 74 61 20 63 6c  .  ClientData cl
99b0: 69 65 6e 74 44 61 74 61 2c 20 2f 2a 20 50 6f 69  ientData, /* Poi
99c0: 6e 74 65 72 20 74 6f 20 73 71 6c 69 74 65 33 5f  nter to sqlite3_
99d0: 65 6e 61 62 6c 65 5f 58 58 58 20 66 75 6e 63 74  enable_XXX funct
99e0: 69 6f 6e 20 2a 2f 0a 20 20 54 63 6c 5f 49 6e 74  ion */.  Tcl_Int
99f0: 65 72 70 20 2a 69 6e 74 65 72 70 2c 20 20 20 20  erp *interp,    
9a00: 2f 2a 20 54 68 65 20 54 43 4c 20 69 6e 74 65 72  /* The TCL inter
9a10: 70 72 65 74 65 72 20 74 68 61 74 20 69 6e 76 6f  preter that invo
9a20: 6b 65 64 20 74 68 69 73 20 63 6f 6d 6d 61 6e 64  ked this command
9a30: 20 2a 2f 0a 20 20 69 6e 74 20 6f 62 6a 63 2c 20   */.  int objc, 
9a40: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
9a50: 4e 75 6d 62 65 72 20 6f 66 20 61 72 67 75 6d 65  Number of argume
9a60: 6e 74 73 20 2a 2f 0a 20 20 54 63 6c 5f 4f 62 6a  nts */.  Tcl_Obj
9a70: 20 2a 43 4f 4e 53 54 20 6f 62 6a 76 5b 5d 20 20   *CONST objv[]  
9a80: 2f 2a 20 43 6f 6d 6d 61 6e 64 20 61 72 67 75 6d  /* Command argum
9a90: 65 6e 74 73 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74  ents */.){.  int
9aa0: 20 72 63 3b 0a 20 20 73 71 6c 69 74 65 33 20 2a   rc;.  sqlite3 *
9ab0: 64 62 3b 0a 20 20 45 63 68 6f 4d 6f 64 75 6c 65  db;.  EchoModule
9ac0: 20 2a 70 4d 6f 64 3b 0a 20 20 69 66 28 20 6f 62   *pMod;.  if( ob
9ad0: 6a 63 21 3d 32 20 29 7b 0a 20 20 20 20 54 63 6c  jc!=2 ){.    Tcl
9ae0: 5f 57 72 6f 6e 67 4e 75 6d 41 72 67 73 28 69 6e  _WrongNumArgs(in
9af0: 74 65 72 70 2c 20 31 2c 20 6f 62 6a 76 2c 20 22  terp, 1, objv, "
9b00: 44 42 22 29 3b 0a 20 20 20 20 72 65 74 75 72 6e  DB");.    return
9b10: 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a   TCL_ERROR;.  }.
9b20: 20 20 69 66 28 20 67 65 74 44 62 50 6f 69 6e 74    if( getDbPoint
9b30: 65 72 28 69 6e 74 65 72 70 2c 20 54 63 6c 5f 47  er(interp, Tcl_G
9b40: 65 74 53 74 72 69 6e 67 28 6f 62 6a 76 5b 31 5d  etString(objv[1]
9b50: 29 2c 20 26 64 62 29 20 29 20 72 65 74 75 72 6e  ), &db) ) return
9b60: 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 0a 20 20 2f   TCL_ERROR;..  /
9b70: 2a 20 56 69 72 74 75 61 6c 20 74 61 62 6c 65 20  * Virtual table 
9b80: 6d 6f 64 75 6c 65 20 22 65 63 68 6f 22 20 2a 2f  module "echo" */
9b90: 0a 20 20 70 4d 6f 64 20 3d 20 73 71 6c 69 74 65  .  pMod = sqlite
9ba0: 33 5f 6d 61 6c 6c 6f 63 28 73 69 7a 65 6f 66 28  3_malloc(sizeof(
9bb0: 45 63 68 6f 4d 6f 64 75 6c 65 29 29 3b 0a 20 20  EchoModule));.  
9bc0: 70 4d 6f 64 2d 3e 69 6e 74 65 72 70 20 3d 20 69  pMod->interp = i
9bd0: 6e 74 65 72 70 3b 0a 20 20 72 63 20 3d 20 73 71  nterp;.  rc = sq
9be0: 6c 69 74 65 33 5f 63 72 65 61 74 65 5f 6d 6f 64  lite3_create_mod
9bf0: 75 6c 65 5f 76 32 28 0a 20 20 20 20 20 20 64 62  ule_v2(.      db
9c00: 2c 20 22 65 63 68 6f 22 2c 20 26 65 63 68 6f 4d  , "echo", &echoM
9c10: 6f 64 75 6c 65 2c 20 28 76 6f 69 64 2a 29 70 4d  odule, (void*)pM
9c20: 6f 64 2c 20 6d 6f 64 75 6c 65 44 65 73 74 72 6f  od, moduleDestro
9c30: 79 0a 20 20 29 3b 0a 0a 20 20 2f 2a 20 56 69 72  y.  );..  /* Vir
9c40: 74 75 61 6c 20 74 61 62 6c 65 20 6d 6f 64 75 6c  tual table modul
9c50: 65 20 22 65 63 68 6f 5f 76 32 22 20 2a 2f 0a 20  e "echo_v2" */. 
9c60: 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
9c70: 4f 4b 20 29 7b 0a 20 20 20 20 70 4d 6f 64 20 3d  OK ){.    pMod =
9c80: 20 73 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63 28   sqlite3_malloc(
9c90: 73 69 7a 65 6f 66 28 45 63 68 6f 4d 6f 64 75 6c  sizeof(EchoModul
9ca0: 65 29 29 3b 0a 20 20 20 20 70 4d 6f 64 2d 3e 69  e));.    pMod->i
9cb0: 6e 74 65 72 70 20 3d 20 69 6e 74 65 72 70 3b 0a  nterp = interp;.
9cc0: 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33      rc = sqlite3
9cd0: 5f 63 72 65 61 74 65 5f 6d 6f 64 75 6c 65 5f 76  _create_module_v
9ce0: 32 28 64 62 2c 20 22 65 63 68 6f 5f 76 32 22 2c  2(db, "echo_v2",
9cf0: 20 0a 20 20 20 20 20 20 20 20 26 65 63 68 6f 4d   .        &echoM
9d00: 6f 64 75 6c 65 56 32 2c 20 28 76 6f 69 64 2a 29  oduleV2, (void*)
9d10: 70 4d 6f 64 2c 20 6d 6f 64 75 6c 65 44 65 73 74  pMod, moduleDest
9d20: 72 6f 79 0a 20 20 20 20 29 3b 0a 20 20 7d 0a 0a  roy.    );.  }..
9d30: 20 20 54 63 6c 5f 53 65 74 52 65 73 75 6c 74 28    Tcl_SetResult(
9d40: 69 6e 74 65 72 70 2c 20 28 63 68 61 72 20 2a 29  interp, (char *)
9d50: 73 71 6c 69 74 65 33 45 72 72 4e 61 6d 65 28 72  sqlite3ErrName(r
9d60: 63 29 2c 20 54 43 4c 5f 53 54 41 54 49 43 29 3b  c), TCL_STATIC);
9d70: 0a 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 4f 4b  .  return TCL_OK
9d80: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 63 6c 20 69  ;.}../*.** Tcl i
9d90: 6e 74 65 72 66 61 63 65 20 74 6f 20 73 71 6c 69  nterface to sqli
9da0: 74 65 33 5f 64 65 63 6c 61 72 65 5f 76 74 61 62  te3_declare_vtab
9db0: 2c 20 69 6e 76 6f 6b 65 64 20 61 73 20 66 6f 6c  , invoked as fol
9dc0: 6c 6f 77 73 20 66 72 6f 6d 20 54 63 6c 3a 0a 2a  lows from Tcl:.*
9dd0: 2a 0a 2a 2a 20 73 71 6c 69 74 65 33 5f 64 65 63  *.** sqlite3_dec
9de0: 6c 61 72 65 5f 76 74 61 62 20 44 42 20 53 51 4c  lare_vtab DB SQL
9df0: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 53  .*/.static int S
9e00: 51 4c 49 54 45 5f 54 43 4c 41 50 49 20 64 65 63  QLITE_TCLAPI dec
9e10: 6c 61 72 65 5f 76 74 61 62 28 0a 20 20 43 6c 69  lare_vtab(.  Cli
9e20: 65 6e 74 44 61 74 61 20 63 6c 69 65 6e 74 44 61  entData clientDa
9e30: 74 61 2c 20 2f 2a 20 50 6f 69 6e 74 65 72 20 74  ta, /* Pointer t
9e40: 6f 20 73 71 6c 69 74 65 33 5f 65 6e 61 62 6c 65  o sqlite3_enable
9e50: 5f 58 58 58 20 66 75 6e 63 74 69 6f 6e 20 2a 2f  _XXX function */
9e60: 0a 20 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69  .  Tcl_Interp *i
9e70: 6e 74 65 72 70 2c 20 20 20 20 2f 2a 20 54 68 65  nterp,    /* The
9e80: 20 54 43 4c 20 69 6e 74 65 72 70 72 65 74 65 72   TCL interpreter
9e90: 20 74 68 61 74 20 69 6e 76 6f 6b 65 64 20 74 68   that invoked th
9ea0: 69 73 20 63 6f 6d 6d 61 6e 64 20 2a 2f 0a 20 20  is command */.  
9eb0: 69 6e 74 20 6f 62 6a 63 2c 20 20 20 20 20 20 20  int objc,       
9ec0: 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72         /* Number
9ed0: 20 6f 66 20 61 72 67 75 6d 65 6e 74 73 20 2a 2f   of arguments */
9ee0: 0a 20 20 54 63 6c 5f 4f 62 6a 20 2a 43 4f 4e 53  .  Tcl_Obj *CONS
9ef0: 54 20 6f 62 6a 76 5b 5d 20 20 2f 2a 20 43 6f 6d  T objv[]  /* Com
9f00: 6d 61 6e 64 20 61 72 67 75 6d 65 6e 74 73 20 2a  mand arguments *
9f10: 2f 0a 29 7b 0a 20 20 73 71 6c 69 74 65 33 20 2a  /.){.  sqlite3 *
9f20: 64 62 3b 0a 20 20 69 6e 74 20 72 63 3b 0a 20 20  db;.  int rc;.  
9f30: 69 66 28 20 6f 62 6a 63 21 3d 33 20 29 7b 0a 20  if( objc!=3 ){. 
9f40: 20 20 20 54 63 6c 5f 57 72 6f 6e 67 4e 75 6d 41     Tcl_WrongNumA
9f50: 72 67 73 28 69 6e 74 65 72 70 2c 20 31 2c 20 6f  rgs(interp, 1, o
9f60: 62 6a 76 2c 20 22 44 42 20 53 51 4c 22 29 3b 0a  bjv, "DB SQL");.
9f70: 20 20 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 45      return TCL_E
9f80: 52 52 4f 52 3b 0a 20 20 7d 0a 20 20 69 66 28 20  RROR;.  }.  if( 
9f90: 67 65 74 44 62 50 6f 69 6e 74 65 72 28 69 6e 74  getDbPointer(int
9fa0: 65 72 70 2c 20 54 63 6c 5f 47 65 74 53 74 72 69  erp, Tcl_GetStri
9fb0: 6e 67 28 6f 62 6a 76 5b 31 5d 29 2c 20 26 64 62  ng(objv[1]), &db
9fc0: 29 20 29 20 72 65 74 75 72 6e 20 54 43 4c 5f 45  ) ) return TCL_E
9fd0: 52 52 4f 52 3b 0a 20 20 72 63 20 3d 20 73 71 6c  RROR;.  rc = sql
9fe0: 69 74 65 33 5f 64 65 63 6c 61 72 65 5f 76 74 61  ite3_declare_vta
9ff0: 62 28 64 62 2c 20 54 63 6c 5f 47 65 74 53 74 72  b(db, Tcl_GetStr
a000: 69 6e 67 28 6f 62 6a 76 5b 32 5d 29 29 3b 0a 20  ing(objv[2]));. 
a010: 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f   if( rc!=SQLITE_
a020: 4f 4b 20 29 7b 0a 20 20 20 20 54 63 6c 5f 53 65  OK ){.    Tcl_Se
a030: 74 52 65 73 75 6c 74 28 69 6e 74 65 72 70 2c 20  tResult(interp, 
a040: 28 63 68 61 72 20 2a 29 73 71 6c 69 74 65 33 5f  (char *)sqlite3_
a050: 65 72 72 6d 73 67 28 64 62 29 2c 20 54 43 4c 5f  errmsg(db), TCL_
a060: 56 4f 4c 41 54 49 4c 45 29 3b 0a 20 20 20 20 72  VOLATILE);.    r
a070: 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b  eturn TCL_ERROR;
a080: 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 54 43  .  }.  return TC
a090: 4c 5f 4f 4b 3b 0a 7d 0a 0a 23 65 6e 64 69 66 20  L_OK;.}..#endif 
a0a0: 2f 2a 20 69 66 6e 64 65 66 20 53 51 4c 49 54 45  /* ifndef SQLITE
a0b0: 5f 4f 4d 49 54 5f 56 49 52 54 55 41 4c 54 41 42  _OMIT_VIRTUALTAB
a0c0: 4c 45 20 2a 2f 0a 0a 2f 2a 0a 2a 2a 20 52 65 67  LE */../*.** Reg
a0d0: 69 73 74 65 72 20 63 6f 6d 6d 61 6e 64 73 20 77  ister commands w
a0e0: 69 74 68 20 74 68 65 20 54 43 4c 20 69 6e 74 65  ith the TCL inte
a0f0: 72 70 72 65 74 65 72 2e 0a 2a 2f 0a 69 6e 74 20  rpreter..*/.int 
a100: 53 71 6c 69 74 65 74 65 73 74 38 5f 49 6e 69 74  Sqlitetest8_Init
a110: 28 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74  (Tcl_Interp *int
a120: 65 72 70 29 7b 0a 23 69 66 6e 64 65 66 20 53 51  erp){.#ifndef SQ
a130: 4c 49 54 45 5f 4f 4d 49 54 5f 56 49 52 54 55 41  LITE_OMIT_VIRTUA
a140: 4c 54 41 42 4c 45 0a 20 20 73 74 61 74 69 63 20  LTABLE.  static 
a150: 73 74 72 75 63 74 20 7b 0a 20 20 20 20 20 63 68  struct {.     ch
a160: 61 72 20 2a 7a 4e 61 6d 65 3b 0a 20 20 20 20 20  ar *zName;.     
a170: 54 63 6c 5f 4f 62 6a 43 6d 64 50 72 6f 63 20 2a  Tcl_ObjCmdProc *
a180: 78 50 72 6f 63 3b 0a 20 20 20 20 20 76 6f 69 64  xProc;.     void
a190: 20 2a 63 6c 69 65 6e 74 44 61 74 61 3b 0a 20 20   *clientData;.  
a1a0: 7d 20 61 4f 62 6a 43 6d 64 5b 5d 20 3d 20 7b 0a  } aObjCmd[] = {.
a1b0: 20 20 20 20 20 7b 20 22 72 65 67 69 73 74 65 72       { "register
a1c0: 5f 65 63 68 6f 5f 6d 6f 64 75 6c 65 22 2c 20 20  _echo_module",  
a1d0: 20 20 20 20 20 72 65 67 69 73 74 65 72 5f 65 63       register_ec
a1e0: 68 6f 5f 6d 6f 64 75 6c 65 2c 20 30 20 7d 2c 0a  ho_module, 0 },.
a1f0: 20 20 20 20 20 7b 20 22 73 71 6c 69 74 65 33 5f       { "sqlite3_
a200: 64 65 63 6c 61 72 65 5f 76 74 61 62 22 2c 20 20  declare_vtab",  
a210: 20 20 20 20 20 64 65 63 6c 61 72 65 5f 76 74 61       declare_vta
a220: 62 2c 20 30 20 7d 2c 0a 20 20 7d 3b 0a 20 20 69  b, 0 },.  };.  i
a230: 6e 74 20 69 3b 0a 20 20 66 6f 72 28 69 3d 30 3b  nt i;.  for(i=0;
a240: 20 69 3c 73 69 7a 65 6f 66 28 61 4f 62 6a 43 6d   i<sizeof(aObjCm
a250: 64 29 2f 73 69 7a 65 6f 66 28 61 4f 62 6a 43 6d  d)/sizeof(aObjCm
a260: 64 5b 30 5d 29 3b 20 69 2b 2b 29 7b 0a 20 20 20  d[0]); i++){.   
a270: 20 54 63 6c 5f 43 72 65 61 74 65 4f 62 6a 43 6f   Tcl_CreateObjCo
a280: 6d 6d 61 6e 64 28 69 6e 74 65 72 70 2c 20 61 4f  mmand(interp, aO
a290: 62 6a 43 6d 64 5b 69 5d 2e 7a 4e 61 6d 65 2c 20  bjCmd[i].zName, 
a2a0: 0a 20 20 20 20 20 20 20 20 61 4f 62 6a 43 6d 64  .        aObjCmd
a2b0: 5b 69 5d 2e 78 50 72 6f 63 2c 20 61 4f 62 6a 43  [i].xProc, aObjC
a2c0: 6d 64 5b 69 5d 2e 63 6c 69 65 6e 74 44 61 74 61  md[i].clientData
a2d0: 2c 20 30 29 3b 0a 20 20 7d 0a 23 65 6e 64 69 66  , 0);.  }.#endif
a2e0: 0a 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 4f 4b  .  return TCL_OK
a2f0: 3b 0a 7d 0a                                      ;.}.