/ Hex Artifact Content
Login

Artifact ae09a70c009097561d0d21e0291d383ad059d3f8:


0000: 2f 2a 0a 2a 2a 20 32 30 30 36 20 4a 75 6e 65 20  /*.** 2006 June 
0010: 31 30 0a 2a 2a 0a 2a 2a 20 54 68 65 20 61 75 74  10.**.** The aut
0020: 68 6f 72 20 64 69 73 63 6c 61 69 6d 73 20 63 6f  hor disclaims co
0030: 70 79 72 69 67 68 74 20 74 6f 20 74 68 69 73 20  pyright to this 
0040: 73 6f 75 72 63 65 20 63 6f 64 65 2e 20 20 49 6e  source code.  In
0050: 20 70 6c 61 63 65 20 6f 66 0a 2a 2a 20 61 20 6c   place of.** a l
0060: 65 67 61 6c 20 6e 6f 74 69 63 65 2c 20 68 65 72  egal notice, her
0070: 65 20 69 73 20 61 20 62 6c 65 73 73 69 6e 67 3a  e is a blessing:
0080: 0a 2a 2a 0a 2a 2a 20 20 20 20 4d 61 79 20 79 6f  .**.**    May yo
0090: 75 20 64 6f 20 67 6f 6f 64 20 61 6e 64 20 6e 6f  u do good and no
00a0: 74 20 65 76 69 6c 2e 0a 2a 2a 20 20 20 20 4d 61  t evil..**    Ma
00b0: 79 20 79 6f 75 20 66 69 6e 64 20 66 6f 72 67 69  y you find forgi
00c0: 76 65 6e 65 73 73 20 66 6f 72 20 79 6f 75 72 73  veness for yours
00d0: 65 6c 66 20 61 6e 64 20 66 6f 72 67 69 76 65 20  elf and forgive 
00e0: 6f 74 68 65 72 73 2e 0a 2a 2a 20 20 20 20 4d 61  others..**    Ma
00f0: 79 20 79 6f 75 20 73 68 61 72 65 20 66 72 65 65  y you share free
0100: 6c 79 2c 20 6e 65 76 65 72 20 74 61 6b 69 6e 67  ly, never taking
0110: 20 6d 6f 72 65 20 74 68 61 6e 20 79 6f 75 20 67   more than you g
0120: 69 76 65 2e 0a 2a 2a 0a 2a 2a 2a 2a 2a 2a 2a 2a  ive..**.********
0130: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0140: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0150: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0160: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0170: 2a 0a 2a 2a 20 43 6f 64 65 20 66 6f 72 20 74 65  *.** Code for te
0180: 73 74 69 6e 67 20 74 68 65 20 76 69 72 74 75 61  sting the virtua
0190: 6c 20 74 61 62 6c 65 20 69 6e 74 65 72 66 61 63  l table interfac
01a0: 65 73 2e 20 20 54 68 69 73 20 63 6f 64 65 0a 2a  es.  This code.*
01b0: 2a 20 69 73 20 6e 6f 74 20 69 6e 63 6c 75 64 65  * is not include
01c0: 64 20 69 6e 20 74 68 65 20 53 51 4c 69 74 65 20  d in the SQLite 
01d0: 6c 69 62 72 61 72 79 2e 20 20 49 74 20 69 73 20  library.  It is 
01e0: 75 73 65 64 20 66 6f 72 20 61 75 74 6f 6d 61 74  used for automat
01f0: 65 64 0a 2a 2a 20 74 65 73 74 69 6e 67 20 6f 66  ed.** testing of
0200: 20 74 68 65 20 53 51 4c 69 74 65 20 6c 69 62 72   the SQLite libr
0210: 61 72 79 2e 0a 2a 2a 0a 2a 2a 20 24 49 64 3a 20  ary..**.** $Id: 
0220: 74 65 73 74 38 2e 63 2c 76 20 31 2e 36 39 20 32  test8.c,v 1.69 2
0230: 30 30 38 2f 30 37 2f 32 38 20 31 39 3a 33 34 3a  008/07/28 19:34:
0240: 35 34 20 64 72 68 20 45 78 70 20 24 0a 2a 2f 0a  54 drh Exp $.*/.
0250: 23 69 6e 63 6c 75 64 65 20 22 73 71 6c 69 74 65  #include "sqlite
0260: 49 6e 74 2e 68 22 0a 23 69 6e 63 6c 75 64 65 20  Int.h".#include 
0270: 22 74 63 6c 2e 68 22 0a 23 69 6e 63 6c 75 64 65  "tcl.h".#include
0280: 20 3c 73 74 64 6c 69 62 2e 68 3e 0a 23 69 6e 63   <stdlib.h>.#inc
0290: 6c 75 64 65 20 3c 73 74 72 69 6e 67 2e 68 3e 0a  lude <string.h>.
02a0: 0a 23 69 66 6e 64 65 66 20 53 51 4c 49 54 45 5f  .#ifndef SQLITE_
02b0: 4f 4d 49 54 5f 56 49 52 54 55 41 4c 54 41 42 4c  OMIT_VIRTUALTABL
02c0: 45 0a 0a 74 79 70 65 64 65 66 20 73 74 72 75 63  E..typedef struc
02d0: 74 20 65 63 68 6f 5f 76 74 61 62 20 65 63 68 6f  t echo_vtab echo
02e0: 5f 76 74 61 62 3b 0a 74 79 70 65 64 65 66 20 73  _vtab;.typedef s
02f0: 74 72 75 63 74 20 65 63 68 6f 5f 63 75 72 73 6f  truct echo_curso
0300: 72 20 65 63 68 6f 5f 63 75 72 73 6f 72 3b 0a 0a  r echo_cursor;..
0310: 2f 2a 0a 2a 2a 20 54 68 65 20 74 65 73 74 20 6d  /*.** The test m
0320: 6f 64 75 6c 65 20 64 65 66 69 6e 65 64 20 69 6e  odule defined in
0330: 20 74 68 69 73 20 66 69 6c 65 20 75 73 65 73 20   this file uses 
0340: 66 6f 75 72 20 67 6c 6f 62 61 6c 20 54 63 6c 20  four global Tcl 
0350: 76 61 72 69 61 62 6c 65 73 20 74 6f 0a 2a 2a 20  variables to.** 
0360: 63 6f 6d 6d 69 63 61 74 65 20 77 69 74 68 20 74  commicate with t
0370: 65 73 74 2d 73 63 72 69 70 74 73 3a 0a 2a 2a 0a  est-scripts:.**.
0380: 2a 2a 20 20 20 20 20 24 3a 3a 65 63 68 6f 5f 6d  **     $::echo_m
0390: 6f 64 75 6c 65 0a 2a 2a 20 20 20 20 20 24 3a 3a  odule.**     $::
03a0: 65 63 68 6f 5f 6d 6f 64 75 6c 65 5f 73 79 6e 63  echo_module_sync
03b0: 5f 66 61 69 6c 0a 2a 2a 20 20 20 20 20 24 3a 3a  _fail.**     $::
03c0: 65 63 68 6f 5f 6d 6f 64 75 6c 65 5f 62 65 67 69  echo_module_begi
03d0: 6e 5f 66 61 69 6c 0a 2a 2a 20 20 20 20 20 24 3a  n_fail.**     $:
03e0: 3a 65 63 68 6f 5f 6d 6f 64 75 6c 65 5f 63 6f 73  :echo_module_cos
03f0: 74 0a 2a 2a 0a 2a 2a 20 54 68 65 20 76 61 72 69  t.**.** The vari
0400: 61 62 6c 65 20 3a 3a 65 63 68 6f 5f 6d 6f 64 75  able ::echo_modu
0410: 6c 65 20 69 73 20 61 20 6c 69 73 74 2e 20 45 61  le is a list. Ea
0420: 63 68 20 74 69 6d 65 20 6f 6e 65 20 6f 66 20 74  ch time one of t
0430: 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 0a 2a 2a 20  he following.** 
0440: 6d 65 74 68 6f 64 73 20 69 73 20 63 61 6c 6c 65  methods is calle
0450: 64 2c 20 6f 6e 65 20 6f 72 20 6d 6f 72 65 20 65  d, one or more e
0460: 6c 65 6d 65 6e 74 73 20 61 72 65 20 61 70 70 65  lements are appe
0470: 6e 64 65 64 20 74 6f 20 74 68 65 20 6c 69 73 74  nded to the list
0480: 2e 0a 2a 2a 20 54 68 69 73 20 69 73 20 75 73 65  ..** This is use
0490: 64 20 66 6f 72 20 61 75 74 6f 6d 61 74 65 64 20  d for automated 
04a0: 74 65 73 74 69 6e 67 20 6f 66 20 76 69 72 74 75  testing of virtu
04b0: 61 6c 20 74 61 62 6c 65 20 6d 6f 64 75 6c 65 73  al table modules
04c0: 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 3a 3a 65 63  ..**.** The ::ec
04d0: 68 6f 5f 6d 6f 64 75 6c 65 5f 73 79 6e 63 5f 66  ho_module_sync_f
04e0: 61 69 6c 20 76 61 72 69 61 62 6c 65 20 69 73 20  ail variable is 
04f0: 73 65 74 20 62 79 20 74 65 73 74 20 73 63 72 69  set by test scri
0500: 70 74 73 20 61 6e 64 20 72 65 61 64 0a 2a 2a 20  pts and read.** 
0510: 62 79 20 63 6f 64 65 20 69 6e 20 74 68 69 73 20  by code in this 
0520: 66 69 6c 65 2e 20 49 66 20 69 74 20 69 73 20 73  file. If it is s
0530: 65 74 20 74 6f 20 74 68 65 20 6e 61 6d 65 20 6f  et to the name o
0540: 66 20 61 20 72 65 61 6c 20 74 61 62 6c 65 20 69  f a real table i
0550: 6e 20 74 68 65 0a 2a 2a 20 74 68 65 20 64 61 74  n the.** the dat
0560: 61 62 61 73 65 2c 20 74 68 65 6e 20 61 6c 6c 20  abase, then all 
0570: 78 53 79 6e 63 20 6f 70 65 72 61 74 69 6f 6e 73  xSync operations
0580: 20 6f 6e 20 65 63 68 6f 20 76 69 72 74 75 61 6c   on echo virtual
0590: 20 74 61 62 6c 65 73 20 74 68 61 74 0a 2a 2a 20   tables that.** 
05a0: 75 73 65 20 74 68 65 20 6e 61 6d 65 64 20 74 61  use the named ta
05b0: 62 6c 65 20 61 73 20 61 20 62 61 63 6b 69 6e 67  ble as a backing
05c0: 20 73 74 6f 72 65 20 77 69 6c 6c 20 66 61 69 6c   store will fail
05d0: 2e 0a 2a 2f 0a 0a 2f 2a 20 0a 2a 2a 20 41 6e 20  ..*/../* .** An 
05e0: 65 63 68 6f 20 76 69 72 74 75 61 6c 2d 74 61 62  echo virtual-tab
05f0: 6c 65 20 6f 62 6a 65 63 74 2e 0a 2a 2a 0a 2a 2a  le object..**.**
0600: 20 65 63 68 6f 2e 76 74 61 62 2e 61 49 6e 64 65   echo.vtab.aInde
0610: 78 20 69 73 20 61 6e 20 61 72 72 61 79 20 6f 66  x is an array of
0620: 20 62 6f 6f 6c 65 61 6e 73 2e 20 54 68 65 20 6e   booleans. The n
0630: 74 68 20 65 6e 74 72 79 20 69 73 20 74 72 75 65  th entry is true
0640: 20 69 66 20 0a 2a 2a 20 74 68 65 20 6e 74 68 20   if .** the nth 
0650: 63 6f 6c 75 6d 6e 20 6f 66 20 74 68 65 20 72 65  column of the re
0660: 61 6c 20 74 61 62 6c 65 20 69 73 20 74 68 65 20  al table is the 
0670: 6c 65 66 74 2d 6d 6f 73 74 20 63 6f 6c 75 6d 6e  left-most column
0680: 20 6f 66 20 61 6e 20 69 6e 64 65 78 0a 2a 2a 20   of an index.** 
0690: 28 69 6d 70 6c 69 63 69 74 20 6f 72 20 6f 74 68  (implicit or oth
06a0: 65 72 77 69 73 65 29 2e 20 49 6e 20 6f 74 68 65  erwise). In othe
06b0: 72 20 77 6f 72 64 73 2c 20 69 66 20 53 51 4c 69  r words, if SQLi
06c0: 74 65 20 63 61 6e 20 6f 70 74 69 6d 69 7a 65 0a  te can optimize.
06d0: 2a 2a 20 61 20 71 75 65 72 79 20 6c 69 6b 65 20  ** a query like 
06e0: 22 53 45 4c 45 43 54 20 2a 20 46 52 4f 4d 20 72  "SELECT * FROM r
06f0: 65 61 6c 5f 74 61 62 6c 65 20 57 48 45 52 45 20  eal_table WHERE 
0700: 63 6f 6c 20 3d 20 3f 22 2e 0a 2a 2a 0a 2a 2a 20  col = ?"..**.** 
0710: 4d 65 6d 62 65 72 20 76 61 72 69 61 62 6c 65 20  Member variable 
0720: 61 43 6f 6c 5b 5d 20 63 6f 6e 74 61 69 6e 73 20  aCol[] contains 
0730: 63 6f 70 69 65 73 20 6f 66 20 74 68 65 20 63 6f  copies of the co
0740: 6c 75 6d 6e 20 6e 61 6d 65 73 20 6f 66 20 74 68  lumn names of th
0750: 65 20 72 65 61 6c 0a 2a 2a 20 74 61 62 6c 65 2e  e real.** table.
0760: 0a 2a 2f 0a 73 74 72 75 63 74 20 65 63 68 6f 5f  .*/.struct echo_
0770: 76 74 61 62 20 7b 0a 20 20 73 71 6c 69 74 65 33  vtab {.  sqlite3
0780: 5f 76 74 61 62 20 62 61 73 65 3b 0a 20 20 54 63  _vtab base;.  Tc
0790: 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70  l_Interp *interp
07a0: 3b 20 20 20 20 20 2f 2a 20 54 63 6c 20 69 6e 74  ;     /* Tcl int
07b0: 65 72 70 72 65 74 65 72 20 63 6f 6e 74 61 69 6e  erpreter contain
07c0: 69 6e 67 20 64 65 62 75 67 20 76 61 72 69 61 62  ing debug variab
07d0: 6c 65 73 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33  les */.  sqlite3
07e0: 20 2a 64 62 3b 20 20 20 20 20 20 20 20 20 20 20   *db;           
07f0: 20 2f 2a 20 44 61 74 61 62 61 73 65 20 63 6f 6e   /* Database con
0800: 6e 65 63 74 69 6f 6e 20 2a 2f 0a 0a 20 20 69 6e  nection */..  in
0810: 74 20 69 73 50 61 74 74 65 72 6e 3b 0a 20 20 69  t isPattern;.  i
0820: 6e 74 20 69 6e 54 72 61 6e 73 61 63 74 69 6f 6e  nt inTransaction
0830: 3b 20 20 20 20 20 20 2f 2a 20 54 72 75 65 20 69  ;      /* True i
0840: 66 20 77 69 74 68 69 6e 20 61 20 74 72 61 6e 73  f within a trans
0850: 61 63 74 69 6f 6e 20 2a 2f 0a 20 20 63 68 61 72  action */.  char
0860: 20 2a 7a 54 68 69 73 3b 20 20 20 20 20 20 20 20   *zThis;        
0870: 20 20 20 20 2f 2a 20 4e 61 6d 65 20 6f 66 20 74      /* Name of t
0880: 68 65 20 65 63 68 6f 20 74 61 62 6c 65 20 2a 2f  he echo table */
0890: 0a 20 20 63 68 61 72 20 2a 7a 54 61 62 6c 65 4e  .  char *zTableN
08a0: 61 6d 65 3b 20 20 20 20 20 20 20 2f 2a 20 4e 61  ame;       /* Na
08b0: 6d 65 20 6f 66 20 74 68 65 20 72 65 61 6c 20 74  me of the real t
08c0: 61 62 6c 65 20 2a 2f 0a 20 20 63 68 61 72 20 2a  able */.  char *
08d0: 7a 4c 6f 67 4e 61 6d 65 3b 20 20 20 20 20 20 20  zLogName;       
08e0: 20 20 2f 2a 20 4e 61 6d 65 20 6f 66 20 74 68 65    /* Name of the
08f0: 20 6c 6f 67 20 74 61 62 6c 65 20 2a 2f 0a 20 20   log table */.  
0900: 69 6e 74 20 6e 43 6f 6c 3b 20 20 20 20 20 20 20  int nCol;       
0910: 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65          /* Numbe
0920: 72 20 6f 66 20 63 6f 6c 75 6d 6e 73 20 69 6e 20  r of columns in 
0930: 74 68 65 20 72 65 61 6c 20 74 61 62 6c 65 20 2a  the real table *
0940: 2f 0a 20 20 69 6e 74 20 2a 61 49 6e 64 65 78 3b  /.  int *aIndex;
0950: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 41              /* A
0960: 72 72 61 79 20 6f 66 20 73 69 7a 65 20 6e 43 6f  rray of size nCo
0970: 6c 2e 20 54 72 75 65 20 69 66 20 63 6f 6c 75 6d  l. True if colum
0980: 6e 20 68 61 73 20 61 6e 20 69 6e 64 65 78 20 2a  n has an index *
0990: 2f 0a 20 20 63 68 61 72 20 2a 2a 61 43 6f 6c 3b  /.  char **aCol;
09a0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 41              /* A
09b0: 72 72 61 79 20 6f 66 20 73 69 7a 65 20 6e 43 6f  rray of size nCo
09c0: 6c 2e 20 43 6f 6c 75 6d 6e 20 6e 61 6d 65 73 20  l. Column names 
09d0: 2a 2f 0a 7d 3b 0a 0a 2f 2a 20 41 6e 20 65 63 68  */.};../* An ech
09e0: 6f 20 63 75 72 73 6f 72 20 6f 62 6a 65 63 74 20  o cursor object 
09f0: 2a 2f 0a 73 74 72 75 63 74 20 65 63 68 6f 5f 63  */.struct echo_c
0a00: 75 72 73 6f 72 20 7b 0a 20 20 73 71 6c 69 74 65  ursor {.  sqlite
0a10: 33 5f 76 74 61 62 5f 63 75 72 73 6f 72 20 62 61  3_vtab_cursor ba
0a20: 73 65 3b 0a 20 20 73 71 6c 69 74 65 33 5f 73 74  se;.  sqlite3_st
0a30: 6d 74 20 2a 70 53 74 6d 74 3b 0a 7d 3b 0a 0a 2f  mt *pStmt;.};../
0a40: 2a 0a 2a 2a 20 43 6f 6e 76 65 72 74 20 61 6e 20  *.** Convert an 
0a50: 53 51 4c 2d 73 74 79 6c 65 20 71 75 6f 74 65 64  SQL-style quoted
0a60: 20 73 74 72 69 6e 67 20 69 6e 74 6f 20 61 20 6e   string into a n
0a70: 6f 72 6d 61 6c 20 73 74 72 69 6e 67 20 62 79 20  ormal string by 
0a80: 72 65 6d 6f 76 69 6e 67 0a 2a 2a 20 74 68 65 20  removing.** the 
0a90: 71 75 6f 74 65 20 63 68 61 72 61 63 74 65 72 73  quote characters
0aa0: 2e 20 20 54 68 65 20 63 6f 6e 76 65 72 73 69 6f  .  The conversio
0ab0: 6e 20 69 73 20 64 6f 6e 65 20 69 6e 2d 70 6c 61  n is done in-pla
0ac0: 63 65 2e 20 20 49 66 20 74 68 65 0a 2a 2a 20 69  ce.  If the.** i
0ad0: 6e 70 75 74 20 64 6f 65 73 20 6e 6f 74 20 62 65  nput does not be
0ae0: 67 69 6e 20 77 69 74 68 20 61 20 71 75 6f 74 65  gin with a quote
0af0: 20 63 68 61 72 61 63 74 65 72 2c 20 74 68 65 6e   character, then
0b00: 20 74 68 69 73 20 72 6f 75 74 69 6e 65 0a 2a 2a   this routine.**
0b10: 20 69 73 20 61 20 6e 6f 2d 6f 70 2e 0a 2a 2a 0a   is a no-op..**.
0b20: 2a 2a 20 45 78 61 6d 70 6c 65 73 3a 0a 2a 2a 0a  ** Examples:.**.
0b30: 2a 2a 20 20 20 20 20 22 61 62 63 22 20 20 20 62  **     "abc"   b
0b40: 65 63 6f 6d 65 73 20 20 20 61 62 63 0a 2a 2a 20  ecomes   abc.** 
0b50: 20 20 20 20 27 78 79 7a 27 20 20 20 62 65 63 6f      'xyz'   beco
0b60: 6d 65 73 20 20 20 78 79 7a 0a 2a 2a 20 20 20 20  mes   xyz.**    
0b70: 20 5b 70 71 72 5d 20 20 20 62 65 63 6f 6d 65 73   [pqr]   becomes
0b80: 20 20 20 70 71 72 0a 2a 2a 20 20 20 20 20 60 6d     pqr.**     `m
0b90: 6e 6f 60 20 20 20 62 65 63 6f 6d 65 73 20 20 20  no`   becomes   
0ba0: 6d 6e 6f 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f  mno.*/.static vo
0bb0: 69 64 20 64 65 71 75 6f 74 65 53 74 72 69 6e 67  id dequoteString
0bc0: 28 63 68 61 72 20 2a 7a 29 7b 0a 20 20 69 6e 74  (char *z){.  int
0bd0: 20 71 75 6f 74 65 3b 0a 20 20 69 6e 74 20 69 2c   quote;.  int i,
0be0: 20 6a 3b 0a 20 20 69 66 28 20 7a 3d 3d 30 20 29   j;.  if( z==0 )
0bf0: 20 72 65 74 75 72 6e 3b 0a 20 20 71 75 6f 74 65   return;.  quote
0c00: 20 3d 20 7a 5b 30 5d 3b 0a 20 20 73 77 69 74 63   = z[0];.  switc
0c10: 68 28 20 71 75 6f 74 65 20 29 7b 0a 20 20 20 20  h( quote ){.    
0c20: 63 61 73 65 20 27 5c 27 27 3a 20 20 62 72 65 61  case '\'':  brea
0c30: 6b 3b 0a 20 20 20 20 63 61 73 65 20 27 22 27 3a  k;.    case '"':
0c40: 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 63 61     break;.    ca
0c50: 73 65 20 27 60 27 3a 20 20 20 62 72 65 61 6b 3b  se '`':   break;
0c60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0c70: 2f 2a 20 46 6f 72 20 4d 79 53 51 4c 20 63 6f 6d  /* For MySQL com
0c80: 70 61 74 69 62 69 6c 69 74 79 20 2a 2f 0a 20 20  patibility */.  
0c90: 20 20 63 61 73 65 20 27 5b 27 3a 20 20 20 71 75    case '[':   qu
0ca0: 6f 74 65 20 3d 20 27 5d 27 3b 20 20 62 72 65 61  ote = ']';  brea
0cb0: 6b 3b 20 20 2f 2a 20 46 6f 72 20 4d 53 20 53 71  k;  /* For MS Sq
0cc0: 6c 53 65 72 76 65 72 20 63 6f 6d 70 61 74 69 62  lServer compatib
0cd0: 69 6c 69 74 79 20 2a 2f 0a 20 20 20 20 64 65 66  ility */.    def
0ce0: 61 75 6c 74 3a 20 20 20 20 72 65 74 75 72 6e 3b  ault:    return;
0cf0: 0a 20 20 7d 0a 20 20 66 6f 72 28 69 3d 31 2c 20  .  }.  for(i=1, 
0d00: 6a 3d 30 3b 20 7a 5b 69 5d 3b 20 69 2b 2b 29 7b  j=0; z[i]; i++){
0d10: 0a 20 20 20 20 69 66 28 20 7a 5b 69 5d 3d 3d 71  .    if( z[i]==q
0d20: 75 6f 74 65 20 29 7b 0a 20 20 20 20 20 20 69 66  uote ){.      if
0d30: 28 20 7a 5b 69 2b 31 5d 3d 3d 71 75 6f 74 65 20  ( z[i+1]==quote 
0d40: 29 7b 0a 20 20 20 20 20 20 20 20 7a 5b 6a 2b 2b  ){.        z[j++
0d50: 5d 20 3d 20 71 75 6f 74 65 3b 0a 20 20 20 20 20  ] = quote;.     
0d60: 20 20 20 69 2b 2b 3b 0a 20 20 20 20 20 20 7d 65     i++;.      }e
0d70: 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 7a 5b 6a  lse{.        z[j
0d80: 2b 2b 5d 20 3d 20 30 3b 0a 20 20 20 20 20 20 20  ++] = 0;.       
0d90: 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 7d 0a   break;.      }.
0da0: 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20      }else{.     
0db0: 20 7a 5b 6a 2b 2b 5d 20 3d 20 7a 5b 69 5d 3b 0a   z[j++] = z[i];.
0dc0: 20 20 20 20 7d 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a      }.  }.}../*.
0dd0: 2a 2a 20 52 65 74 72 69 65 76 65 20 74 68 65 20  ** Retrieve the 
0de0: 63 6f 6c 75 6d 6e 20 6e 61 6d 65 73 20 66 6f 72  column names for
0df0: 20 74 68 65 20 74 61 62 6c 65 20 6e 61 6d 65 64   the table named
0e00: 20 7a 54 61 62 20 76 69 61 20 64 61 74 61 62 61   zTab via databa
0e10: 73 65 0a 2a 2a 20 63 6f 6e 6e 65 63 74 69 6f 6e  se.** connection
0e20: 20 64 62 2e 20 53 51 4c 49 54 45 5f 4f 4b 20 69   db. SQLITE_OK i
0e30: 73 20 72 65 74 75 72 6e 65 64 20 6f 6e 20 73 75  s returned on su
0e40: 63 63 65 73 73 2c 20 6f 72 20 61 6e 20 73 71 6c  ccess, or an sql
0e50: 69 74 65 20 65 72 72 6f 72 0a 2a 2a 20 63 6f 64  ite error.** cod
0e60: 65 20 6f 74 68 65 72 77 69 73 65 2e 0a 2a 2a 0a  e otherwise..**.
0e70: 2a 2a 20 49 66 20 73 75 63 63 65 73 73 66 75 6c  ** If successful
0e80: 2c 20 74 68 65 20 6e 75 6d 62 65 72 20 6f 66 20  , the number of 
0e90: 63 6f 6c 75 6d 6e 73 20 69 73 20 77 72 69 74 74  columns is writt
0ea0: 65 6e 20 74 6f 20 2a 70 6e 43 6f 6c 2e 20 2a 70  en to *pnCol. *p
0eb0: 61 43 6f 6c 20 69 73 0a 2a 2a 20 73 65 74 20 74  aCol is.** set t
0ec0: 6f 20 70 6f 69 6e 74 20 61 74 20 73 71 6c 69 74  o point at sqlit
0ed0: 65 33 5f 6d 61 6c 6c 6f 63 28 29 27 64 20 73 70  e3_malloc()'d sp
0ee0: 61 63 65 20 63 6f 6e 74 61 69 6e 69 6e 67 20 74  ace containing t
0ef0: 68 65 20 61 72 72 61 79 20 6f 66 0a 2a 2a 20 6e  he array of.** n
0f00: 43 6f 6c 20 63 6f 6c 75 6d 6e 20 6e 61 6d 65 73  Col column names
0f10: 2e 20 54 68 65 20 63 61 6c 6c 65 72 20 69 73 20  . The caller is 
0f20: 72 65 73 70 6f 6e 73 69 62 6c 65 20 66 6f 72 20  responsible for 
0f30: 63 61 6c 6c 69 6e 67 20 73 71 6c 69 74 65 33 5f  calling sqlite3_
0f40: 66 72 65 65 0a 2a 2a 20 6f 6e 20 2a 70 61 43 6f  free.** on *paCo
0f50: 6c 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  l..*/.static int
0f60: 20 67 65 74 43 6f 6c 75 6d 6e 4e 61 6d 65 73 28   getColumnNames(
0f70: 0a 20 20 73 71 6c 69 74 65 33 20 2a 64 62 2c 20  .  sqlite3 *db, 
0f80: 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a  .  const char *z
0f90: 54 61 62 2c 0a 20 20 63 68 61 72 20 2a 2a 2a 70  Tab,.  char ***p
0fa0: 61 43 6f 6c 2c 20 0a 20 20 69 6e 74 20 2a 70 6e  aCol, .  int *pn
0fb0: 43 6f 6c 0a 29 7b 0a 20 20 63 68 61 72 20 2a 2a  Col.){.  char **
0fc0: 61 43 6f 6c 20 3d 20 30 3b 0a 20 20 63 68 61 72  aCol = 0;.  char
0fd0: 20 2a 7a 53 71 6c 3b 0a 20 20 73 71 6c 69 74 65   *zSql;.  sqlite
0fe0: 33 5f 73 74 6d 74 20 2a 70 53 74 6d 74 20 3d 20  3_stmt *pStmt = 
0ff0: 30 3b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51  0;.  int rc = SQ
1000: 4c 49 54 45 5f 4f 4b 3b 0a 20 20 69 6e 74 20 6e  LITE_OK;.  int n
1010: 43 6f 6c 20 3d 20 30 3b 0a 0a 20 20 2f 2a 20 50  Col = 0;..  /* P
1020: 72 65 70 61 72 65 20 74 68 65 20 73 74 61 74 65  repare the state
1030: 6d 65 6e 74 20 22 53 45 4c 45 43 54 20 2a 20 46  ment "SELECT * F
1040: 52 4f 4d 20 3c 74 62 6c 3e 22 2e 20 54 68 65 20  ROM <tbl>". The 
1050: 63 6f 6c 75 6d 6e 20 6e 61 6d 65 73 0a 20 20 2a  column names.  *
1060: 2a 20 6f 66 20 74 68 65 20 72 65 73 75 6c 74 20  * of the result 
1070: 73 65 74 20 6f 66 20 74 68 65 20 63 6f 6d 70 69  set of the compi
1080: 6c 65 64 20 53 45 4c 45 43 54 20 77 69 6c 6c 20  led SELECT will 
1090: 62 65 20 74 68 65 20 73 61 6d 65 20 61 73 0a 20  be the same as. 
10a0: 20 2a 2a 20 74 68 65 20 63 6f 6c 75 6d 6e 20 6e   ** the column n
10b0: 61 6d 65 73 20 6f 66 20 74 61 62 6c 65 20 3c 74  ames of table <t
10c0: 62 6c 3e 2e 0a 20 20 2a 2f 0a 20 20 7a 53 71 6c  bl>..  */.  zSql
10d0: 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e   = sqlite3_mprin
10e0: 74 66 28 22 53 45 4c 45 43 54 20 2a 20 46 52 4f  tf("SELECT * FRO
10f0: 4d 20 25 51 22 2c 20 7a 54 61 62 29 3b 0a 20 20  M %Q", zTab);.  
1100: 69 66 28 20 21 7a 53 71 6c 20 29 7b 0a 20 20 20  if( !zSql ){.   
1110: 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d   rc = SQLITE_NOM
1120: 45 4d 3b 0a 20 20 20 20 67 6f 74 6f 20 6f 75 74  EM;.    goto out
1130: 3b 0a 20 20 7d 0a 20 20 72 63 20 3d 20 73 71 6c  ;.  }.  rc = sql
1140: 69 74 65 33 5f 70 72 65 70 61 72 65 28 64 62 2c  ite3_prepare(db,
1150: 20 7a 53 71 6c 2c 20 2d 31 2c 20 26 70 53 74 6d   zSql, -1, &pStm
1160: 74 2c 20 30 29 3b 0a 20 20 73 71 6c 69 74 65 33  t, 0);.  sqlite3
1170: 5f 66 72 65 65 28 7a 53 71 6c 29 3b 0a 0a 20 20  _free(zSql);..  
1180: 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  if( rc==SQLITE_O
1190: 4b 20 29 7b 0a 20 20 20 20 69 6e 74 20 69 69 3b  K ){.    int ii;
11a0: 0a 20 20 20 20 69 6e 74 20 6e 42 79 74 65 73 3b  .    int nBytes;
11b0: 0a 20 20 20 20 63 68 61 72 20 2a 7a 53 70 61 63  .    char *zSpac
11c0: 65 3b 0a 20 20 20 20 6e 43 6f 6c 20 3d 20 73 71  e;.    nCol = sq
11d0: 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 63 6f 75  lite3_column_cou
11e0: 6e 74 28 70 53 74 6d 74 29 3b 0a 0a 20 20 20 20  nt(pStmt);..    
11f0: 2f 2a 20 46 69 67 75 72 65 20 6f 75 74 20 68 6f  /* Figure out ho
1200: 77 20 6d 75 63 68 20 73 70 61 63 65 20 74 6f 20  w much space to 
1210: 61 6c 6c 6f 63 61 74 65 20 66 6f 72 20 74 68 65  allocate for the
1220: 20 61 72 72 61 79 20 6f 66 20 63 6f 6c 75 6d 6e   array of column
1230: 20 6e 61 6d 65 73 20 0a 20 20 20 20 2a 2a 20 28   names .    ** (
1240: 69 6e 63 6c 75 64 69 6e 67 20 73 70 61 63 65 20  including space 
1250: 66 6f 72 20 74 68 65 20 73 74 72 69 6e 67 73 20  for the strings 
1260: 74 68 65 6d 73 65 6c 76 65 73 29 2e 20 54 68 65  themselves). The
1270: 6e 20 61 6c 6c 6f 63 61 74 65 20 69 74 2e 0a 20  n allocate it.. 
1280: 20 20 20 2a 2f 0a 20 20 20 20 6e 42 79 74 65 73     */.    nBytes
1290: 20 3d 20 73 69 7a 65 6f 66 28 63 68 61 72 20 2a   = sizeof(char *
12a0: 29 20 2a 20 6e 43 6f 6c 3b 0a 20 20 20 20 66 6f  ) * nCol;.    fo
12b0: 72 28 69 69 3d 30 3b 20 69 69 3c 6e 43 6f 6c 3b  r(ii=0; ii<nCol;
12c0: 20 69 69 2b 2b 29 7b 0a 20 20 20 20 20 20 63 6f   ii++){.      co
12d0: 6e 73 74 20 63 68 61 72 20 2a 7a 4e 61 6d 65 20  nst char *zName 
12e0: 3d 20 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e  = sqlite3_column
12f0: 5f 6e 61 6d 65 28 70 53 74 6d 74 2c 20 69 69 29  _name(pStmt, ii)
1300: 3b 0a 20 20 20 20 20 20 69 66 28 20 21 7a 4e 61  ;.      if( !zNa
1310: 6d 65 20 29 7b 0a 20 20 20 20 20 20 20 20 72 63  me ){.        rc
1320: 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b   = SQLITE_NOMEM;
1330: 0a 20 20 20 20 20 20 20 20 67 6f 74 6f 20 6f 75  .        goto ou
1340: 74 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20  t;.      }.     
1350: 20 6e 42 79 74 65 73 20 2b 3d 20 73 74 72 6c 65   nBytes += strle
1360: 6e 28 7a 4e 61 6d 65 29 2b 31 3b 0a 20 20 20 20  n(zName)+1;.    
1370: 7d 0a 20 20 20 20 61 43 6f 6c 20 3d 20 28 63 68  }.    aCol = (ch
1380: 61 72 20 2a 2a 29 73 71 6c 69 74 65 33 4d 61 6c  ar **)sqlite3Mal
1390: 6c 6f 63 5a 65 72 6f 28 6e 42 79 74 65 73 29 3b  locZero(nBytes);
13a0: 0a 20 20 20 20 69 66 28 20 21 61 43 6f 6c 20 29  .    if( !aCol )
13b0: 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c  {.      rc = SQL
13c0: 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 20  ITE_NOMEM;.     
13d0: 20 67 6f 74 6f 20 6f 75 74 3b 0a 20 20 20 20 7d   goto out;.    }
13e0: 0a 0a 20 20 20 20 2f 2a 20 43 6f 70 79 20 74 68  ..    /* Copy th
13f0: 65 20 63 6f 6c 75 6d 6e 20 6e 61 6d 65 73 20 69  e column names i
1400: 6e 74 6f 20 74 68 65 20 61 6c 6c 6f 63 61 74 65  nto the allocate
1410: 64 20 73 70 61 63 65 20 61 6e 64 20 73 65 74 20  d space and set 
1420: 75 70 20 74 68 65 0a 20 20 20 20 2a 2a 20 70 6f  up the.    ** po
1430: 69 6e 74 65 72 73 20 69 6e 20 74 68 65 20 61 43  inters in the aC
1440: 6f 6c 5b 5d 20 61 72 72 61 79 2e 0a 20 20 20 20  ol[] array..    
1450: 2a 2f 0a 20 20 20 20 7a 53 70 61 63 65 20 3d 20  */.    zSpace = 
1460: 28 63 68 61 72 20 2a 29 28 26 61 43 6f 6c 5b 6e  (char *)(&aCol[n
1470: 43 6f 6c 5d 29 3b 0a 20 20 20 20 66 6f 72 28 69  Col]);.    for(i
1480: 69 3d 30 3b 20 69 69 3c 6e 43 6f 6c 3b 20 69 69  i=0; ii<nCol; ii
1490: 2b 2b 29 7b 0a 20 20 20 20 20 20 61 43 6f 6c 5b  ++){.      aCol[
14a0: 69 69 5d 20 3d 20 7a 53 70 61 63 65 3b 0a 20 20  ii] = zSpace;.  
14b0: 20 20 20 20 7a 53 70 61 63 65 20 2b 3d 20 73 70      zSpace += sp
14c0: 72 69 6e 74 66 28 7a 53 70 61 63 65 2c 20 22 25  rintf(zSpace, "%
14d0: 73 22 2c 20 73 71 6c 69 74 65 33 5f 63 6f 6c 75  s", sqlite3_colu
14e0: 6d 6e 5f 6e 61 6d 65 28 70 53 74 6d 74 2c 20 69  mn_name(pStmt, i
14f0: 69 29 29 3b 0a 20 20 20 20 20 20 7a 53 70 61 63  i));.      zSpac
1500: 65 2b 2b 3b 0a 20 20 20 20 7d 0a 20 20 20 20 61  e++;.    }.    a
1510: 73 73 65 72 74 28 20 28 7a 53 70 61 63 65 2d 6e  ssert( (zSpace-n
1520: 42 79 74 65 73 29 3d 3d 28 63 68 61 72 20 2a 29  Bytes)==(char *)
1530: 61 43 6f 6c 20 29 3b 0a 20 20 7d 0a 0a 20 20 2a  aCol );.  }..  *
1540: 70 61 43 6f 6c 20 3d 20 61 43 6f 6c 3b 0a 20 20  paCol = aCol;.  
1550: 2a 70 6e 43 6f 6c 20 3d 20 6e 43 6f 6c 3b 0a 0a  *pnCol = nCol;..
1560: 6f 75 74 3a 0a 20 20 73 71 6c 69 74 65 33 5f 66  out:.  sqlite3_f
1570: 69 6e 61 6c 69 7a 65 28 70 53 74 6d 74 29 3b 0a  inalize(pStmt);.
1580: 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a    return rc;.}..
1590: 2f 2a 0a 2a 2a 20 50 61 72 61 6d 65 74 65 72 20  /*.** Parameter 
15a0: 7a 54 61 62 20 69 73 20 74 68 65 20 6e 61 6d 65  zTab is the name
15b0: 20 6f 66 20 61 20 74 61 62 6c 65 20 69 6e 20 64   of a table in d
15c0: 61 74 61 62 61 73 65 20 64 62 20 77 69 74 68 20  atabase db with 
15d0: 6e 43 6f 6c 20 0a 2a 2a 20 63 6f 6c 75 6d 6e 73  nCol .** columns
15e0: 2e 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20  . This function 
15f0: 61 6c 6c 6f 63 61 74 65 73 20 61 6e 20 61 72 72  allocates an arr
1600: 61 79 20 6f 66 20 69 6e 74 65 67 65 72 73 20 6e  ay of integers n
1610: 43 6f 6c 20 69 6e 20 0a 2a 2a 20 73 69 7a 65 20  Col in .** size 
1620: 61 6e 64 20 70 6f 70 75 6c 61 74 65 73 20 69 74  and populates it
1630: 20 61 63 63 6f 72 64 69 6e 67 20 74 6f 20 61 6e   according to an
1640: 79 20 69 6d 70 6c 69 63 69 74 20 6f 72 20 65 78  y implicit or ex
1650: 70 6c 69 63 69 74 20 0a 2a 2a 20 69 6e 64 69 63  plicit .** indic
1660: 65 73 20 6f 6e 20 74 61 62 6c 65 20 7a 54 61 62  es on table zTab
1670: 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 73 75 63 63 65  ..**.** If succe
1680: 73 73 66 75 6c 2c 20 53 51 4c 49 54 45 5f 4f 4b  ssful, SQLITE_OK
1690: 20 69 73 20 72 65 74 75 72 6e 65 64 20 61 6e 64   is returned and
16a0: 20 2a 70 61 49 6e 64 65 78 20 73 65 74 20 74 6f   *paIndex set to
16b0: 20 70 6f 69 6e 74 20 0a 2a 2a 20 61 74 20 74 68   point .** at th
16c0: 65 20 61 6c 6c 6f 63 61 74 65 64 20 61 72 72 61  e allocated arra
16d0: 79 2e 20 4f 74 68 65 72 77 69 73 65 2c 20 61 6e  y. Otherwise, an
16e0: 20 65 72 72 6f 72 20 63 6f 64 65 20 69 73 20 72   error code is r
16f0: 65 74 75 72 6e 65 64 2e 0a 2a 2a 0a 2a 2a 20 53  eturned..**.** S
1700: 65 65 20 63 6f 6d 6d 65 6e 74 73 20 61 73 73 6f  ee comments asso
1710: 63 69 61 74 65 64 20 77 69 74 68 20 74 68 65 20  ciated with the 
1720: 6d 65 6d 62 65 72 20 76 61 72 69 61 62 6c 65 20  member variable 
1730: 61 49 6e 64 65 78 20 61 62 6f 76 65 20 0a 2a 2a  aIndex above .**
1740: 20 22 73 74 72 75 63 74 20 65 63 68 6f 5f 76 74   "struct echo_vt
1750: 61 62 22 20 66 6f 72 20 64 65 74 61 69 6c 73 20  ab" for details 
1760: 6f 66 20 74 68 65 20 63 6f 6e 74 65 6e 74 73 20  of the contents 
1770: 6f 66 20 74 68 65 20 61 72 72 61 79 2e 0a 2a 2f  of the array..*/
1780: 0a 73 74 61 74 69 63 20 69 6e 74 20 67 65 74 49  .static int getI
1790: 6e 64 65 78 41 72 72 61 79 28 0a 20 20 73 71 6c  ndexArray(.  sql
17a0: 69 74 65 33 20 2a 64 62 2c 20 20 20 20 20 20 20  ite3 *db,       
17b0: 20 20 20 20 20 20 2f 2a 20 44 61 74 61 62 61 73        /* Databas
17c0: 65 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 2a 2f 0a  e connection */.
17d0: 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 54    const char *zT
17e0: 61 62 2c 20 20 20 20 20 20 20 20 2f 2a 20 4e 61  ab,        /* Na
17f0: 6d 65 20 6f 66 20 74 61 62 6c 65 20 69 6e 20 64  me of table in d
1800: 61 74 61 62 61 73 65 20 64 62 20 2a 2f 0a 20 20  atabase db */.  
1810: 69 6e 74 20 6e 43 6f 6c 2c 0a 20 20 69 6e 74 20  int nCol,.  int 
1820: 2a 2a 70 61 49 6e 64 65 78 0a 29 7b 0a 20 20 73  **paIndex.){.  s
1830: 71 6c 69 74 65 33 5f 73 74 6d 74 20 2a 70 53 74  qlite3_stmt *pSt
1840: 6d 74 20 3d 20 30 3b 0a 20 20 69 6e 74 20 2a 61  mt = 0;.  int *a
1850: 49 6e 64 65 78 20 3d 20 30 3b 0a 20 20 69 6e 74  Index = 0;.  int
1860: 20 72 63 3b 0a 20 20 63 68 61 72 20 2a 7a 53 71   rc;.  char *zSq
1870: 6c 3b 0a 0a 20 20 2f 2a 20 41 6c 6c 6f 63 61 74  l;..  /* Allocat
1880: 65 20 73 70 61 63 65 20 66 6f 72 20 74 68 65 20  e space for the 
1890: 69 6e 64 65 78 20 61 72 72 61 79 20 2a 2f 0a 20  index array */. 
18a0: 20 61 49 6e 64 65 78 20 3d 20 28 69 6e 74 20 2a   aIndex = (int *
18b0: 29 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63 5a 65  )sqlite3MallocZe
18c0: 72 6f 28 73 69 7a 65 6f 66 28 69 6e 74 29 20 2a  ro(sizeof(int) *
18d0: 20 6e 43 6f 6c 29 3b 0a 20 20 69 66 28 20 21 61   nCol);.  if( !a
18e0: 49 6e 64 65 78 20 29 7b 0a 20 20 20 20 72 63 20  Index ){.    rc 
18f0: 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a  = SQLITE_NOMEM;.
1900: 20 20 20 20 67 6f 74 6f 20 67 65 74 5f 69 6e 64      goto get_ind
1910: 65 78 5f 61 72 72 61 79 5f 6f 75 74 3b 0a 20 20  ex_array_out;.  
1920: 7d 0a 0a 20 20 2f 2a 20 43 6f 6d 70 69 6c 65 20  }..  /* Compile 
1930: 61 6e 20 73 71 6c 69 74 65 20 70 72 61 67 6d 61  an sqlite pragma
1940: 20 74 6f 20 6c 6f 6f 70 20 74 68 72 6f 75 67 68   to loop through
1950: 20 61 6c 6c 20 69 6e 64 69 63 65 73 20 6f 6e 20   all indices on 
1960: 74 61 62 6c 65 20 7a 54 61 62 20 2a 2f 0a 20 20  table zTab */.  
1970: 7a 53 71 6c 20 3d 20 73 71 6c 69 74 65 33 4d 50  zSql = sqlite3MP
1980: 72 69 6e 74 66 28 30 2c 20 22 50 52 41 47 4d 41  rintf(0, "PRAGMA
1990: 20 69 6e 64 65 78 5f 6c 69 73 74 28 25 73 29 22   index_list(%s)"
19a0: 2c 20 7a 54 61 62 29 3b 0a 20 20 69 66 28 20 21  , zTab);.  if( !
19b0: 7a 53 71 6c 20 29 7b 0a 20 20 20 20 72 63 20 3d  zSql ){.    rc =
19c0: 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20   SQLITE_NOMEM;. 
19d0: 20 20 20 67 6f 74 6f 20 67 65 74 5f 69 6e 64 65     goto get_inde
19e0: 78 5f 61 72 72 61 79 5f 6f 75 74 3b 0a 20 20 7d  x_array_out;.  }
19f0: 0a 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f  .  rc = sqlite3_
1a00: 70 72 65 70 61 72 65 28 64 62 2c 20 7a 53 71 6c  prepare(db, zSql
1a10: 2c 20 2d 31 2c 20 26 70 53 74 6d 74 2c 20 30 29  , -1, &pStmt, 0)
1a20: 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65  ;.  sqlite3_free
1a30: 28 7a 53 71 6c 29 3b 0a 0a 20 20 2f 2a 20 46 6f  (zSql);..  /* Fo
1a40: 72 20 65 61 63 68 20 69 6e 64 65 78 2c 20 66 69  r each index, fi
1a50: 67 75 72 65 20 6f 75 74 20 74 68 65 20 6c 65 66  gure out the lef
1a60: 74 2d 6d 6f 73 74 20 63 6f 6c 75 6d 6e 20 61 6e  t-most column an
1a70: 64 20 73 65 74 20 74 68 65 20 0a 20 20 2a 2a 20  d set the .  ** 
1a80: 63 6f 72 72 65 73 70 6f 6e 64 69 6e 67 20 65 6e  corresponding en
1a90: 74 72 79 20 69 6e 20 61 49 6e 64 65 78 5b 5d 20  try in aIndex[] 
1aa0: 74 6f 20 31 2e 0a 20 20 2a 2f 0a 20 20 77 68 69  to 1..  */.  whi
1ab0: 6c 65 28 20 70 53 74 6d 74 20 26 26 20 73 71 6c  le( pStmt && sql
1ac0: 69 74 65 33 5f 73 74 65 70 28 70 53 74 6d 74 29  ite3_step(pStmt)
1ad0: 3d 3d 53 51 4c 49 54 45 5f 52 4f 57 20 29 7b 0a  ==SQLITE_ROW ){.
1ae0: 20 20 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a      const char *
1af0: 7a 49 64 78 20 3d 20 28 63 6f 6e 73 74 20 63 68  zIdx = (const ch
1b00: 61 72 20 2a 29 73 71 6c 69 74 65 33 5f 63 6f 6c  ar *)sqlite3_col
1b10: 75 6d 6e 5f 74 65 78 74 28 70 53 74 6d 74 2c 20  umn_text(pStmt, 
1b20: 31 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f  1);.    sqlite3_
1b30: 73 74 6d 74 20 2a 70 53 74 6d 74 32 20 3d 20 30  stmt *pStmt2 = 0
1b40: 3b 0a 20 20 20 20 7a 53 71 6c 20 3d 20 73 71 6c  ;.    zSql = sql
1b50: 69 74 65 33 4d 50 72 69 6e 74 66 28 30 2c 20 22  ite3MPrintf(0, "
1b60: 50 52 41 47 4d 41 20 69 6e 64 65 78 5f 69 6e 66  PRAGMA index_inf
1b70: 6f 28 25 73 29 22 2c 20 7a 49 64 78 29 3b 0a 20  o(%s)", zIdx);. 
1b80: 20 20 20 69 66 28 20 21 7a 53 71 6c 20 29 7b 0a     if( !zSql ){.
1b90: 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54        rc = SQLIT
1ba0: 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 20 20 67  E_NOMEM;.      g
1bb0: 6f 74 6f 20 67 65 74 5f 69 6e 64 65 78 5f 61 72  oto get_index_ar
1bc0: 72 61 79 5f 6f 75 74 3b 0a 20 20 20 20 7d 0a 20  ray_out;.    }. 
1bd0: 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f     rc = sqlite3_
1be0: 70 72 65 70 61 72 65 28 64 62 2c 20 7a 53 71 6c  prepare(db, zSql
1bf0: 2c 20 2d 31 2c 20 26 70 53 74 6d 74 32 2c 20 30  , -1, &pStmt2, 0
1c00: 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 66  );.    sqlite3_f
1c10: 72 65 65 28 7a 53 71 6c 29 3b 0a 20 20 20 20 69  ree(zSql);.    i
1c20: 66 28 20 70 53 74 6d 74 32 20 26 26 20 73 71 6c  f( pStmt2 && sql
1c30: 69 74 65 33 5f 73 74 65 70 28 70 53 74 6d 74 32  ite3_step(pStmt2
1c40: 29 3d 3d 53 51 4c 49 54 45 5f 52 4f 57 20 29 7b  )==SQLITE_ROW ){
1c50: 0a 20 20 20 20 20 20 69 6e 74 20 63 69 64 20 3d  .      int cid =
1c60: 20 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f   sqlite3_column_
1c70: 69 6e 74 28 70 53 74 6d 74 32 2c 20 31 29 3b 0a  int(pStmt2, 1);.
1c80: 20 20 20 20 20 20 61 73 73 65 72 74 28 20 63 69        assert( ci
1c90: 64 3e 3d 30 20 26 26 20 63 69 64 3c 6e 43 6f 6c  d>=0 && cid<nCol
1ca0: 20 29 3b 0a 20 20 20 20 20 20 61 49 6e 64 65 78   );.      aIndex
1cb0: 5b 63 69 64 5d 20 3d 20 31 3b 0a 20 20 20 20 7d  [cid] = 1;.    }
1cc0: 0a 20 20 20 20 69 66 28 20 70 53 74 6d 74 32 20  .    if( pStmt2 
1cd0: 29 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 73 71  ){.      rc = sq
1ce0: 6c 69 74 65 33 5f 66 69 6e 61 6c 69 7a 65 28 70  lite3_finalize(p
1cf0: 53 74 6d 74 32 29 3b 0a 20 20 20 20 7d 0a 20 20  Stmt2);.    }.  
1d00: 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45    if( rc!=SQLITE
1d10: 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 67 6f 74  _OK ){.      got
1d20: 6f 20 67 65 74 5f 69 6e 64 65 78 5f 61 72 72 61  o get_index_arra
1d30: 79 5f 6f 75 74 3b 0a 20 20 20 20 7d 0a 20 20 7d  y_out;.    }.  }
1d40: 0a 0a 0a 67 65 74 5f 69 6e 64 65 78 5f 61 72 72  ...get_index_arr
1d50: 61 79 5f 6f 75 74 3a 0a 20 20 69 66 28 20 70 53  ay_out:.  if( pS
1d60: 74 6d 74 20 29 7b 0a 20 20 20 20 69 6e 74 20 72  tmt ){.    int r
1d70: 63 32 20 3d 20 73 71 6c 69 74 65 33 5f 66 69 6e  c2 = sqlite3_fin
1d80: 61 6c 69 7a 65 28 70 53 74 6d 74 29 3b 0a 20 20  alize(pStmt);.  
1d90: 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
1da0: 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 72 63 20  _OK ){.      rc 
1db0: 3d 20 72 63 32 3b 0a 20 20 20 20 7d 0a 20 20 7d  = rc2;.    }.  }
1dc0: 0a 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54  .  if( rc!=SQLIT
1dd0: 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 73 71 6c 69  E_OK ){.    sqli
1de0: 74 65 33 5f 66 72 65 65 28 61 49 6e 64 65 78 29  te3_free(aIndex)
1df0: 3b 0a 20 20 20 20 61 49 6e 64 65 78 20 3d 20 30  ;.    aIndex = 0
1e00: 3b 0a 20 20 7d 0a 20 20 2a 70 61 49 6e 64 65 78  ;.  }.  *paIndex
1e10: 20 3d 20 61 49 6e 64 65 78 3b 0a 20 20 72 65 74   = aIndex;.  ret
1e20: 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  urn rc;.}../*.**
1e30: 20 47 6c 6f 62 61 6c 20 54 63 6c 20 76 61 72 69   Global Tcl vari
1e40: 61 62 6c 65 20 24 65 63 68 6f 5f 6d 6f 64 75 6c  able $echo_modul
1e50: 65 20 69 73 20 61 20 6c 69 73 74 2e 20 54 68 69  e is a list. Thi
1e60: 73 20 72 6f 75 74 69 6e 65 20 61 70 70 65 6e 64  s routine append
1e70: 73 0a 2a 2a 20 74 68 65 20 73 74 72 69 6e 67 20  s.** the string 
1e80: 65 6c 65 6d 65 6e 74 20 7a 41 72 67 20 74 6f 20  element zArg to 
1e90: 74 68 61 74 20 6c 69 73 74 20 69 6e 20 69 6e 74  that list in int
1ea0: 65 72 70 72 65 74 65 72 20 69 6e 74 65 72 70 2e  erpreter interp.
1eb0: 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20  .*/.static void 
1ec0: 61 70 70 65 6e 64 54 6f 45 63 68 6f 4d 6f 64 75  appendToEchoModu
1ed0: 6c 65 28 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69  le(Tcl_Interp *i
1ee0: 6e 74 65 72 70 2c 20 63 6f 6e 73 74 20 63 68 61  nterp, const cha
1ef0: 72 20 2a 7a 41 72 67 29 7b 0a 20 20 69 6e 74 20  r *zArg){.  int 
1f00: 66 6c 61 67 73 20 3d 20 28 54 43 4c 5f 41 50 50  flags = (TCL_APP
1f10: 45 4e 44 5f 56 41 4c 55 45 20 7c 20 54 43 4c 5f  END_VALUE | TCL_
1f20: 4c 49 53 54 5f 45 4c 45 4d 45 4e 54 20 7c 20 54  LIST_ELEMENT | T
1f30: 43 4c 5f 47 4c 4f 42 41 4c 5f 4f 4e 4c 59 29 3b  CL_GLOBAL_ONLY);
1f40: 0a 20 20 54 63 6c 5f 53 65 74 56 61 72 28 69 6e  .  Tcl_SetVar(in
1f50: 74 65 72 70 2c 20 22 65 63 68 6f 5f 6d 6f 64 75  terp, "echo_modu
1f60: 6c 65 22 2c 20 28 7a 41 72 67 3f 7a 41 72 67 3a  le", (zArg?zArg:
1f70: 22 22 29 2c 20 66 6c 61 67 73 29 3b 0a 7d 0a 0a  ""), flags);.}..
1f80: 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63 74  /*.** This funct
1f90: 69 6f 6e 20 69 73 20 63 61 6c 6c 65 64 20 66 72  ion is called fr
1fa0: 6f 6d 20 77 69 74 68 69 6e 20 74 68 65 20 65 63  om within the ec
1fb0: 68 6f 2d 6d 6f 64 75 6c 65 73 20 78 43 72 65 61  ho-modules xCrea
1fc0: 74 65 20 61 6e 64 0a 2a 2a 20 78 43 6f 6e 6e 65  te and.** xConne
1fd0: 63 74 20 6d 65 74 68 6f 64 73 2e 20 54 68 65 20  ct methods. The 
1fe0: 61 72 67 63 20 61 6e 64 20 61 72 67 76 20 61 72  argc and argv ar
1ff0: 67 75 6d 65 6e 74 73 20 61 72 65 20 63 6f 70 69  guments are copi
2000: 65 73 20 6f 66 20 74 68 6f 73 65 20 0a 2a 2a 20  es of those .** 
2010: 70 61 73 73 65 64 20 74 6f 20 74 68 65 20 63 61  passed to the ca
2020: 6c 6c 69 6e 67 20 6d 65 74 68 6f 64 2e 20 54 68  lling method. Th
2030: 69 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 72  is function is r
2040: 65 73 70 6f 6e 73 69 62 6c 65 20 66 6f 72 0a 2a  esponsible for.*
2050: 2a 20 63 61 6c 6c 69 6e 67 20 73 71 6c 69 74 65  * calling sqlite
2060: 33 5f 64 65 63 6c 61 72 65 5f 76 74 61 62 28 29  3_declare_vtab()
2070: 20 74 6f 20 64 65 63 6c 61 72 65 20 74 68 65 20   to declare the 
2080: 73 63 68 65 6d 61 20 6f 66 20 74 68 65 20 76 69  schema of the vi
2090: 72 74 75 61 6c 0a 2a 2a 20 74 61 62 6c 65 20 62  rtual.** table b
20a0: 65 69 6e 67 20 63 72 65 61 74 65 64 20 6f 72 20  eing created or 
20b0: 63 6f 6e 6e 65 63 74 65 64 2e 0a 2a 2a 0a 2a 2a  connected..**.**
20c0: 20 49 66 20 74 68 65 20 63 6f 6e 73 74 72 75 63   If the construc
20d0: 74 6f 72 20 77 61 73 20 70 61 73 73 65 64 20 6a  tor was passed j
20e0: 75 73 74 20 6f 6e 65 20 61 72 67 75 6d 65 6e 74  ust one argument
20f0: 2c 20 69 2e 65 2e 3a 0a 2a 2a 0a 2a 2a 20 20 20  , i.e.:.**.**   
2100: 43 52 45 41 54 45 20 54 41 42 4c 45 20 74 31 20  CREATE TABLE t1 
2110: 41 53 20 65 63 68 6f 28 74 32 29 3b 0a 2a 2a 0a  AS echo(t2);.**.
2120: 2a 2a 20 54 68 65 6e 20 74 32 20 69 73 20 61 73  ** Then t2 is as
2130: 73 75 6d 65 64 20 74 6f 20 62 65 20 74 68 65 20  sumed to be the 
2140: 6e 61 6d 65 20 6f 66 20 61 20 2a 72 65 61 6c 2a  name of a *real*
2150: 20 64 61 74 61 62 61 73 65 20 74 61 62 6c 65 2e   database table.
2160: 20 54 68 65 0a 2a 2a 20 73 63 68 65 6d 61 20 6f   The.** schema o
2170: 66 20 74 68 65 20 76 69 72 74 75 61 6c 20 74 61  f the virtual ta
2180: 62 6c 65 20 69 73 20 64 65 63 6c 61 72 65 64 20  ble is declared 
2190: 62 79 20 70 61 73 73 69 6e 67 20 61 20 63 6f 70  by passing a cop
21a0: 79 20 6f 66 20 74 68 65 20 0a 2a 2a 20 43 52 45  y of the .** CRE
21b0: 41 54 45 20 54 41 42 4c 45 20 73 74 61 74 65 6d  ATE TABLE statem
21c0: 65 6e 74 20 66 6f 72 20 74 68 65 20 72 65 61 6c  ent for the real
21d0: 20 74 61 62 6c 65 20 74 6f 20 73 71 6c 69 74 65   table to sqlite
21e0: 33 5f 64 65 63 6c 61 72 65 5f 76 74 61 62 28 29  3_declare_vtab()
21f0: 2e 0a 2a 2a 20 48 65 6e 63 65 2c 20 74 68 65 20  ..** Hence, the 
2200: 76 69 72 74 75 61 6c 20 74 61 62 6c 65 20 73 68  virtual table sh
2210: 6f 75 6c 64 20 68 61 76 65 20 65 78 61 63 74 6c  ould have exactl
2220: 79 20 74 68 65 20 73 61 6d 65 20 63 6f 6c 75 6d  y the same colum
2230: 6e 20 6e 61 6d 65 73 20 61 6e 64 20 0a 2a 2a 20  n names and .** 
2240: 74 79 70 65 73 20 61 73 20 74 68 65 20 72 65 61  types as the rea
2250: 6c 20 74 61 62 6c 65 2e 0a 2a 2f 0a 73 74 61 74  l table..*/.stat
2260: 69 63 20 69 6e 74 20 65 63 68 6f 44 65 63 6c 61  ic int echoDecla
2270: 72 65 56 74 61 62 28 0a 20 20 65 63 68 6f 5f 76  reVtab(.  echo_v
2280: 74 61 62 20 2a 70 56 74 61 62 2c 20 0a 20 20 73  tab *pVtab, .  s
2290: 71 6c 69 74 65 33 20 2a 64 62 20 0a 29 7b 0a 20  qlite3 *db .){. 
22a0: 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45   int rc = SQLITE
22b0: 5f 4f 4b 3b 0a 0a 20 20 69 66 28 20 70 56 74 61  _OK;..  if( pVta
22c0: 62 2d 3e 7a 54 61 62 6c 65 4e 61 6d 65 20 29 7b  b->zTableName ){
22d0: 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 73 74 6d  .    sqlite3_stm
22e0: 74 20 2a 70 53 74 6d 74 20 3d 20 30 3b 0a 20 20  t *pStmt = 0;.  
22f0: 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 70    rc = sqlite3_p
2300: 72 65 70 61 72 65 28 64 62 2c 20 0a 20 20 20 20  repare(db, .    
2310: 20 20 20 20 22 53 45 4c 45 43 54 20 73 71 6c 20      "SELECT sql 
2320: 46 52 4f 4d 20 73 71 6c 69 74 65 5f 6d 61 73 74  FROM sqlite_mast
2330: 65 72 20 57 48 45 52 45 20 74 79 70 65 20 3d 20  er WHERE type = 
2340: 27 74 61 62 6c 65 27 20 41 4e 44 20 6e 61 6d 65  'table' AND name
2350: 20 3d 20 3f 22 2c 0a 20 20 20 20 20 20 20 20 2d   = ?",.        -
2360: 31 2c 20 26 70 53 74 6d 74 2c 20 30 29 3b 0a 20  1, &pStmt, 0);. 
2370: 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54     if( rc==SQLIT
2380: 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 73 71  E_OK ){.      sq
2390: 6c 69 74 65 33 5f 62 69 6e 64 5f 74 65 78 74 28  lite3_bind_text(
23a0: 70 53 74 6d 74 2c 20 31 2c 20 70 56 74 61 62 2d  pStmt, 1, pVtab-
23b0: 3e 7a 54 61 62 6c 65 4e 61 6d 65 2c 20 2d 31 2c  >zTableName, -1,
23c0: 20 30 29 3b 0a 20 20 20 20 20 20 69 66 28 20 73   0);.      if( s
23d0: 71 6c 69 74 65 33 5f 73 74 65 70 28 70 53 74 6d  qlite3_step(pStm
23e0: 74 29 3d 3d 53 51 4c 49 54 45 5f 52 4f 57 20 29  t)==SQLITE_ROW )
23f0: 7b 0a 20 20 20 20 20 20 20 20 69 6e 74 20 72 63  {.        int rc
2400: 32 3b 0a 20 20 20 20 20 20 20 20 63 6f 6e 73 74  2;.        const
2410: 20 63 68 61 72 20 2a 7a 43 72 65 61 74 65 54 61   char *zCreateTa
2420: 62 6c 65 20 3d 20 28 63 6f 6e 73 74 20 63 68 61  ble = (const cha
2430: 72 20 2a 29 73 71 6c 69 74 65 33 5f 63 6f 6c 75  r *)sqlite3_colu
2440: 6d 6e 5f 74 65 78 74 28 70 53 74 6d 74 2c 20 30  mn_text(pStmt, 0
2450: 29 3b 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20  );.        rc = 
2460: 73 71 6c 69 74 65 33 5f 64 65 63 6c 61 72 65 5f  sqlite3_declare_
2470: 76 74 61 62 28 64 62 2c 20 7a 43 72 65 61 74 65  vtab(db, zCreate
2480: 54 61 62 6c 65 29 3b 0a 20 20 20 20 20 20 20 20  Table);.        
2490: 72 63 32 20 3d 20 73 71 6c 69 74 65 33 5f 66 69  rc2 = sqlite3_fi
24a0: 6e 61 6c 69 7a 65 28 70 53 74 6d 74 29 3b 0a 20  nalize(pStmt);. 
24b0: 20 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d 53         if( rc==S
24c0: 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
24d0: 20 20 20 20 20 20 72 63 20 3d 20 72 63 32 3b 0a        rc = rc2;.
24e0: 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20          }.      
24f0: 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20 20 20 20  } else {.       
2500: 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 66 69   rc = sqlite3_fi
2510: 6e 61 6c 69 7a 65 28 70 53 74 6d 74 29 3b 0a 20  nalize(pStmt);. 
2520: 20 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d 53         if( rc==S
2530: 51 4c 49 54 45 5f 4f 4b 20 29 7b 20 0a 20 20 20  QLITE_OK ){ .   
2540: 20 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c 49         rc = SQLI
2550: 54 45 5f 45 52 52 4f 52 3b 0a 20 20 20 20 20 20  TE_ERROR;.      
2560: 20 20 7d 0a 20 20 20 20 20 20 7d 0a 20 20 20 20    }.      }.    
2570: 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
2580: 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20 20 72  _OK ){.        r
2590: 63 20 3d 20 67 65 74 43 6f 6c 75 6d 6e 4e 61 6d  c = getColumnNam
25a0: 65 73 28 64 62 2c 20 70 56 74 61 62 2d 3e 7a 54  es(db, pVtab->zT
25b0: 61 62 6c 65 4e 61 6d 65 2c 20 26 70 56 74 61 62  ableName, &pVtab
25c0: 2d 3e 61 43 6f 6c 2c 20 26 70 56 74 61 62 2d 3e  ->aCol, &pVtab->
25d0: 6e 43 6f 6c 29 3b 0a 20 20 20 20 20 20 7d 0a 20  nCol);.      }. 
25e0: 20 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c       if( rc==SQL
25f0: 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20  ITE_OK ){.      
2600: 20 20 72 63 20 3d 20 67 65 74 49 6e 64 65 78 41    rc = getIndexA
2610: 72 72 61 79 28 64 62 2c 20 70 56 74 61 62 2d 3e  rray(db, pVtab->
2620: 7a 54 61 62 6c 65 4e 61 6d 65 2c 20 70 56 74 61  zTableName, pVta
2630: 62 2d 3e 6e 43 6f 6c 2c 20 26 70 56 74 61 62 2d  b->nCol, &pVtab-
2640: 3e 61 49 6e 64 65 78 29 3b 0a 20 20 20 20 20 20  >aIndex);.      
2650: 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 72  }.    }.  }..  r
2660: 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a  eturn rc;.}../*.
2670: 2a 2a 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e  ** This function
2680: 20 66 72 65 65 73 20 61 6c 6c 20 72 75 6e 74 69   frees all runti
2690: 6d 65 20 73 74 72 75 63 74 75 72 65 73 20 61 73  me structures as
26a0: 73 6f 63 69 61 74 65 64 20 77 69 74 68 20 74 68  sociated with th
26b0: 65 20 76 69 72 74 75 61 6c 0a 2a 2a 20 74 61 62  e virtual.** tab
26c0: 6c 65 20 70 56 74 61 62 2e 0a 2a 2f 0a 73 74 61  le pVtab..*/.sta
26d0: 74 69 63 20 69 6e 74 20 65 63 68 6f 44 65 73 74  tic int echoDest
26e0: 72 75 63 74 6f 72 28 73 71 6c 69 74 65 33 5f 76  ructor(sqlite3_v
26f0: 74 61 62 20 2a 70 56 74 61 62 29 7b 0a 20 20 65  tab *pVtab){.  e
2700: 63 68 6f 5f 76 74 61 62 20 2a 70 20 3d 20 28 65  cho_vtab *p = (e
2710: 63 68 6f 5f 76 74 61 62 2a 29 70 56 74 61 62 3b  cho_vtab*)pVtab;
2720: 0a 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28  .  sqlite3_free(
2730: 70 2d 3e 61 49 6e 64 65 78 29 3b 0a 20 20 73 71  p->aIndex);.  sq
2740: 6c 69 74 65 33 5f 66 72 65 65 28 70 2d 3e 61 43  lite3_free(p->aC
2750: 6f 6c 29 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66  ol);.  sqlite3_f
2760: 72 65 65 28 70 2d 3e 7a 54 68 69 73 29 3b 0a 20  ree(p->zThis);. 
2770: 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70 2d   sqlite3_free(p-
2780: 3e 7a 54 61 62 6c 65 4e 61 6d 65 29 3b 0a 20 20  >zTableName);.  
2790: 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70 2d 3e  sqlite3_free(p->
27a0: 7a 4c 6f 67 4e 61 6d 65 29 3b 0a 20 20 73 71 6c  zLogName);.  sql
27b0: 69 74 65 33 5f 66 72 65 65 28 70 29 3b 0a 20 20  ite3_free(p);.  
27c0: 72 65 74 75 72 6e 20 30 3b 0a 7d 0a 0a 74 79 70  return 0;.}..typ
27d0: 65 64 65 66 20 73 74 72 75 63 74 20 45 63 68 6f  edef struct Echo
27e0: 4d 6f 64 75 6c 65 20 45 63 68 6f 4d 6f 64 75 6c  Module EchoModul
27f0: 65 3b 0a 73 74 72 75 63 74 20 45 63 68 6f 4d 6f  e;.struct EchoMo
2800: 64 75 6c 65 20 7b 0a 20 20 54 63 6c 5f 49 6e 74  dule {.  Tcl_Int
2810: 65 72 70 20 2a 69 6e 74 65 72 70 3b 0a 7d 3b 0a  erp *interp;.};.
2820: 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63  ./*.** This func
2830: 74 69 6f 6e 20 69 73 20 63 61 6c 6c 65 64 20 74  tion is called t
2840: 6f 20 64 6f 20 74 68 65 20 77 6f 72 6b 20 6f 66  o do the work of
2850: 20 74 68 65 20 78 43 6f 6e 6e 65 63 74 28 29 20   the xConnect() 
2860: 6d 65 74 68 6f 64 20 2d 0a 2a 2a 20 74 6f 20 61  method -.** to a
2870: 6c 6c 6f 63 61 74 65 20 74 68 65 20 72 65 71 75  llocate the requ
2880: 69 72 65 64 20 69 6e 2d 6d 65 6d 6f 72 79 20 73  ired in-memory s
2890: 74 72 75 63 74 75 72 65 73 20 66 6f 72 20 61 20  tructures for a 
28a0: 6e 65 77 6c 79 20 63 6f 6e 6e 65 63 74 65 64 0a  newly connected.
28b0: 2a 2a 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65  ** virtual table
28c0: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
28d0: 65 63 68 6f 43 6f 6e 73 74 72 75 63 74 6f 72 28  echoConstructor(
28e0: 0a 20 20 73 71 6c 69 74 65 33 20 2a 64 62 2c 0a  .  sqlite3 *db,.
28f0: 20 20 76 6f 69 64 20 2a 70 41 75 78 2c 0a 20 20    void *pAux,.  
2900: 69 6e 74 20 61 72 67 63 2c 20 63 6f 6e 73 74 20  int argc, const 
2910: 63 68 61 72 20 2a 63 6f 6e 73 74 2a 61 72 67 76  char *const*argv
2920: 2c 0a 20 20 73 71 6c 69 74 65 33 5f 76 74 61 62  ,.  sqlite3_vtab
2930: 20 2a 2a 70 70 56 74 61 62 2c 0a 20 20 63 68 61   **ppVtab,.  cha
2940: 72 20 2a 2a 70 7a 45 72 72 0a 29 7b 0a 20 20 69  r **pzErr.){.  i
2950: 6e 74 20 72 63 3b 0a 20 20 69 6e 74 20 69 3b 0a  nt rc;.  int i;.
2960: 20 20 65 63 68 6f 5f 76 74 61 62 20 2a 70 56 74    echo_vtab *pVt
2970: 61 62 3b 0a 0a 20 20 2f 2a 20 41 6c 6c 6f 63 61  ab;..  /* Alloca
2980: 74 65 20 74 68 65 20 73 71 6c 69 74 65 33 5f 76  te the sqlite3_v
2990: 74 61 62 2f 65 63 68 6f 5f 76 74 61 62 20 73 74  tab/echo_vtab st
29a0: 72 75 63 74 75 72 65 20 69 74 73 65 6c 66 20 2a  ructure itself *
29b0: 2f 0a 20 20 70 56 74 61 62 20 3d 20 73 71 6c 69  /.  pVtab = sqli
29c0: 74 65 33 4d 61 6c 6c 6f 63 5a 65 72 6f 28 20 73  te3MallocZero( s
29d0: 69 7a 65 6f 66 28 2a 70 56 74 61 62 29 20 29 3b  izeof(*pVtab) );
29e0: 0a 20 20 69 66 28 20 21 70 56 74 61 62 20 29 7b  .  if( !pVtab ){
29f0: 0a 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49  .    return SQLI
2a00: 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 7d 0a 20 20  TE_NOMEM;.  }.  
2a10: 70 56 74 61 62 2d 3e 69 6e 74 65 72 70 20 3d 20  pVtab->interp = 
2a20: 28 28 45 63 68 6f 4d 6f 64 75 6c 65 20 2a 29 70  ((EchoModule *)p
2a30: 41 75 78 29 2d 3e 69 6e 74 65 72 70 3b 0a 20 20  Aux)->interp;.  
2a40: 70 56 74 61 62 2d 3e 64 62 20 3d 20 64 62 3b 0a  pVtab->db = db;.
2a50: 0a 20 20 2f 2a 20 41 6c 6c 6f 63 61 74 65 20 65  .  /* Allocate e
2a60: 63 68 6f 5f 76 74 61 62 2e 7a 54 68 69 73 20 2a  cho_vtab.zThis *
2a70: 2f 0a 20 20 70 56 74 61 62 2d 3e 7a 54 68 69 73  /.  pVtab->zThis
2a80: 20 3d 20 73 71 6c 69 74 65 33 4d 50 72 69 6e 74   = sqlite3MPrint
2a90: 66 28 30 2c 20 22 25 73 22 2c 20 61 72 67 76 5b  f(0, "%s", argv[
2aa0: 32 5d 29 3b 0a 20 20 69 66 28 20 21 70 56 74 61  2]);.  if( !pVta
2ab0: 62 2d 3e 7a 54 68 69 73 20 29 7b 0a 20 20 20 20  b->zThis ){.    
2ac0: 65 63 68 6f 44 65 73 74 72 75 63 74 6f 72 28 28  echoDestructor((
2ad0: 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 29 70  sqlite3_vtab *)p
2ae0: 56 74 61 62 29 3b 0a 20 20 20 20 72 65 74 75 72  Vtab);.    retur
2af0: 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a  n SQLITE_NOMEM;.
2b00: 20 20 7d 0a 0a 20 20 2f 2a 20 41 6c 6c 6f 63 61    }..  /* Alloca
2b10: 74 65 20 65 63 68 6f 5f 76 74 61 62 2e 7a 54 61  te echo_vtab.zTa
2b20: 62 6c 65 4e 61 6d 65 20 2a 2f 0a 20 20 69 66 28  bleName */.  if(
2b30: 20 61 72 67 63 3e 33 20 29 7b 0a 20 20 20 20 70   argc>3 ){.    p
2b40: 56 74 61 62 2d 3e 7a 54 61 62 6c 65 4e 61 6d 65  Vtab->zTableName
2b50: 20 3d 20 73 71 6c 69 74 65 33 4d 50 72 69 6e 74   = sqlite3MPrint
2b60: 66 28 30 2c 20 22 25 73 22 2c 20 61 72 67 76 5b  f(0, "%s", argv[
2b70: 33 5d 29 3b 0a 20 20 20 20 64 65 71 75 6f 74 65  3]);.    dequote
2b80: 53 74 72 69 6e 67 28 70 56 74 61 62 2d 3e 7a 54  String(pVtab->zT
2b90: 61 62 6c 65 4e 61 6d 65 29 3b 0a 20 20 20 20 69  ableName);.    i
2ba0: 66 28 20 70 56 74 61 62 2d 3e 7a 54 61 62 6c 65  f( pVtab->zTable
2bb0: 4e 61 6d 65 20 26 26 20 70 56 74 61 62 2d 3e 7a  Name && pVtab->z
2bc0: 54 61 62 6c 65 4e 61 6d 65 5b 30 5d 3d 3d 27 2a  TableName[0]=='*
2bd0: 27 20 29 7b 0a 20 20 20 20 20 20 63 68 61 72 20  ' ){.      char 
2be0: 2a 7a 20 3d 20 73 71 6c 69 74 65 33 4d 50 72 69  *z = sqlite3MPri
2bf0: 6e 74 66 28 30 2c 20 22 25 73 25 73 22 2c 20 61  ntf(0, "%s%s", a
2c00: 72 67 76 5b 32 5d 2c 20 26 28 70 56 74 61 62 2d  rgv[2], &(pVtab-
2c10: 3e 7a 54 61 62 6c 65 4e 61 6d 65 5b 31 5d 29 29  >zTableName[1]))
2c20: 3b 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f  ;.      sqlite3_
2c30: 66 72 65 65 28 70 56 74 61 62 2d 3e 7a 54 61 62  free(pVtab->zTab
2c40: 6c 65 4e 61 6d 65 29 3b 0a 20 20 20 20 20 20 70  leName);.      p
2c50: 56 74 61 62 2d 3e 7a 54 61 62 6c 65 4e 61 6d 65  Vtab->zTableName
2c60: 20 3d 20 7a 3b 0a 20 20 20 20 20 20 70 56 74 61   = z;.      pVta
2c70: 62 2d 3e 69 73 50 61 74 74 65 72 6e 20 3d 20 31  b->isPattern = 1
2c80: 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 28 20  ;.    }.    if( 
2c90: 21 70 56 74 61 62 2d 3e 7a 54 61 62 6c 65 4e 61  !pVtab->zTableNa
2ca0: 6d 65 20 29 7b 0a 20 20 20 20 20 20 65 63 68 6f  me ){.      echo
2cb0: 44 65 73 74 72 75 63 74 6f 72 28 28 73 71 6c 69  Destructor((sqli
2cc0: 74 65 33 5f 76 74 61 62 20 2a 29 70 56 74 61 62  te3_vtab *)pVtab
2cd0: 29 3b 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20  );.      return 
2ce0: 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20  SQLITE_NOMEM;.  
2cf0: 20 20 7d 0a 20 20 7d 0a 0a 20 20 2f 2a 20 4c 6f    }.  }..  /* Lo
2d00: 67 20 74 68 65 20 61 72 67 75 6d 65 6e 74 73 20  g the arguments 
2d10: 74 6f 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e  to this function
2d20: 20 74 6f 20 54 63 6c 20 76 61 72 20 3a 3a 65 63   to Tcl var ::ec
2d30: 68 6f 5f 6d 6f 64 75 6c 65 20 2a 2f 0a 20 20 66  ho_module */.  f
2d40: 6f 72 28 69 3d 30 3b 20 69 3c 61 72 67 63 3b 20  or(i=0; i<argc; 
2d50: 69 2b 2b 29 7b 0a 20 20 20 20 61 70 70 65 6e 64  i++){.    append
2d60: 54 6f 45 63 68 6f 4d 6f 64 75 6c 65 28 70 56 74  ToEchoModule(pVt
2d70: 61 62 2d 3e 69 6e 74 65 72 70 2c 20 61 72 67 76  ab->interp, argv
2d80: 5b 69 5d 29 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20  [i]);.  }..  /* 
2d90: 49 6e 76 6f 6b 65 20 73 71 6c 69 74 65 33 5f 64  Invoke sqlite3_d
2da0: 65 63 6c 61 72 65 5f 76 74 61 62 20 61 6e 64 20  eclare_vtab and 
2db0: 73 65 74 20 75 70 20 6f 74 68 65 72 20 6d 65 6d  set up other mem
2dc0: 62 65 72 73 20 6f 66 20 74 68 65 20 65 63 68 6f  bers of the echo
2dd0: 5f 76 74 61 62 0a 20 20 2a 2a 20 73 74 72 75 63  _vtab.  ** struc
2de0: 74 75 72 65 2e 20 49 66 20 61 6e 20 65 72 72 6f  ture. If an erro
2df0: 72 20 6f 63 63 75 72 73 2c 20 64 65 6c 65 74 65  r occurs, delete
2e00: 20 74 68 65 20 73 71 6c 69 74 65 33 5f 76 74 61   the sqlite3_vta
2e10: 62 20 73 74 72 75 63 74 75 72 65 20 61 6e 64 0a  b structure and.
2e20: 20 20 2a 2a 20 72 65 74 75 72 6e 20 61 6e 20 65    ** return an e
2e30: 72 72 6f 72 20 63 6f 64 65 2e 0a 20 20 2a 2f 0a  rror code..  */.
2e40: 20 20 72 63 20 3d 20 65 63 68 6f 44 65 63 6c 61    rc = echoDecla
2e50: 72 65 56 74 61 62 28 70 56 74 61 62 2c 20 64 62  reVtab(pVtab, db
2e60: 29 3b 0a 20 20 69 66 28 20 72 63 21 3d 53 51 4c  );.  if( rc!=SQL
2e70: 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 65 63  ITE_OK ){.    ec
2e80: 68 6f 44 65 73 74 72 75 63 74 6f 72 28 28 73 71  hoDestructor((sq
2e90: 6c 69 74 65 33 5f 76 74 61 62 20 2a 29 70 56 74  lite3_vtab *)pVt
2ea0: 61 62 29 3b 0a 20 20 20 20 72 65 74 75 72 6e 20  ab);.    return 
2eb0: 72 63 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 53 75  rc;.  }..  /* Su
2ec0: 63 63 65 73 73 2e 20 53 65 74 20 2a 70 70 56 74  ccess. Set *ppVt
2ed0: 61 62 20 61 6e 64 20 72 65 74 75 72 6e 20 2a 2f  ab and return */
2ee0: 0a 20 20 2a 70 70 56 74 61 62 20 3d 20 26 70 56  .  *ppVtab = &pV
2ef0: 74 61 62 2d 3e 62 61 73 65 3b 0a 20 20 72 65 74  tab->base;.  ret
2f00: 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d  urn SQLITE_OK;.}
2f10: 0a 0a 2f 2a 20 0a 2a 2a 20 45 63 68 6f 20 76 69  ../* .** Echo vi
2f20: 72 74 75 61 6c 20 74 61 62 6c 65 20 6d 6f 64 75  rtual table modu
2f30: 6c 65 20 78 43 72 65 61 74 65 20 6d 65 74 68 6f  le xCreate metho
2f40: 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  d..*/.static int
2f50: 20 65 63 68 6f 43 72 65 61 74 65 28 0a 20 20 73   echoCreate(.  s
2f60: 71 6c 69 74 65 33 20 2a 64 62 2c 0a 20 20 76 6f  qlite3 *db,.  vo
2f70: 69 64 20 2a 70 41 75 78 2c 0a 20 20 69 6e 74 20  id *pAux,.  int 
2f80: 61 72 67 63 2c 20 63 6f 6e 73 74 20 63 68 61 72  argc, const char
2f90: 20 2a 63 6f 6e 73 74 2a 61 72 67 76 2c 0a 20 20   *const*argv,.  
2fa0: 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 2a 70  sqlite3_vtab **p
2fb0: 70 56 74 61 62 2c 0a 20 20 63 68 61 72 20 2a 2a  pVtab,.  char **
2fc0: 70 7a 45 72 72 0a 29 7b 0a 20 20 69 6e 74 20 72  pzErr.){.  int r
2fd0: 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20  c = SQLITE_OK;. 
2fe0: 20 61 70 70 65 6e 64 54 6f 45 63 68 6f 4d 6f 64   appendToEchoMod
2ff0: 75 6c 65 28 28 28 45 63 68 6f 4d 6f 64 75 6c 65  ule(((EchoModule
3000: 20 2a 29 70 41 75 78 29 2d 3e 69 6e 74 65 72 70   *)pAux)->interp
3010: 2c 20 22 78 43 72 65 61 74 65 22 29 3b 0a 20 20  , "xCreate");.  
3020: 72 63 20 3d 20 65 63 68 6f 43 6f 6e 73 74 72 75  rc = echoConstru
3030: 63 74 6f 72 28 64 62 2c 20 70 41 75 78 2c 20 61  ctor(db, pAux, a
3040: 72 67 63 2c 20 61 72 67 76 2c 20 70 70 56 74 61  rgc, argv, ppVta
3050: 62 2c 20 70 7a 45 72 72 29 3b 0a 0a 20 20 2f 2a  b, pzErr);..  /*
3060: 20 49 66 20 74 68 65 72 65 20 77 65 72 65 20 74   If there were t
3070: 77 6f 20 61 72 67 75 6d 65 6e 74 73 20 70 61 73  wo arguments pas
3080: 73 65 64 20 74 6f 20 74 68 65 20 6d 6f 64 75 6c  sed to the modul
3090: 65 20 61 74 20 74 68 65 20 53 51 4c 20 6c 65 76  e at the SQL lev
30a0: 65 6c 20 0a 20 20 2a 2a 20 28 69 2e 65 2e 20 22  el .  ** (i.e. "
30b0: 43 52 45 41 54 45 20 56 49 52 54 55 41 4c 20 54  CREATE VIRTUAL T
30c0: 41 42 4c 45 20 74 62 6c 20 55 53 49 4e 47 20 65  ABLE tbl USING e
30d0: 63 68 6f 28 61 72 67 31 2c 20 61 72 67 32 29 22  cho(arg1, arg2)"
30e0: 29 2c 20 74 68 65 6e 20 0a 20 20 2a 2a 20 74 68  ), then .  ** th
30f0: 65 20 73 65 63 6f 6e 64 20 61 72 67 75 6d 65 6e  e second argumen
3100: 74 20 69 73 20 75 73 65 64 20 61 73 20 61 20 74  t is used as a t
3110: 61 62 6c 65 20 6e 61 6d 65 2e 20 41 74 74 65 6d  able name. Attem
3120: 70 74 20 74 6f 20 63 72 65 61 74 65 0a 20 20 2a  pt to create.  *
3130: 2a 20 73 75 63 68 20 61 20 74 61 62 6c 65 20 77  * such a table w
3140: 69 74 68 20 61 20 73 69 6e 67 6c 65 20 63 6f 6c  ith a single col
3150: 75 6d 6e 2c 20 22 6c 6f 67 6d 73 67 22 2e 20 54  umn, "logmsg". T
3160: 68 69 73 20 74 61 62 6c 65 20 77 69 6c 6c 0a 20  his table will. 
3170: 20 2a 2a 20 62 65 20 75 73 65 64 20 74 6f 20 6c   ** be used to l
3180: 6f 67 20 63 61 6c 6c 73 20 74 6f 20 74 68 65 20  og calls to the 
3190: 78 55 70 64 61 74 65 20 6d 65 74 68 6f 64 2e 20  xUpdate method. 
31a0: 49 74 20 77 69 6c 6c 20 62 65 20 64 65 6c 65 74  It will be delet
31b0: 65 64 0a 20 20 2a 2a 20 77 68 65 6e 20 74 68 65  ed.  ** when the
31c0: 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65 20 69   virtual table i
31d0: 73 20 44 52 4f 50 65 64 2e 0a 20 20 2a 2a 0a 20  s DROPed..  **. 
31e0: 20 2a 2a 20 4e 6f 74 65 3a 20 54 68 65 20 6d 61   ** Note: The ma
31f0: 69 6e 20 70 6f 69 6e 74 20 6f 66 20 74 68 69 73  in point of this
3200: 20 69 73 20 74 6f 20 74 65 73 74 20 74 68 61 74   is to test that
3210: 20 77 65 20 63 61 6e 20 64 72 6f 70 20 74 61 62   we can drop tab
3220: 6c 65 73 0a 20 20 2a 2a 20 66 72 6f 6d 20 77 69  les.  ** from wi
3230: 74 68 69 6e 20 61 6e 20 78 44 65 73 74 72 6f 79  thin an xDestroy
3240: 20 6d 65 74 68 6f 64 20 63 61 6c 6c 2e 0a 20 20   method call..  
3250: 2a 2f 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c  */.  if( rc==SQL
3260: 49 54 45 5f 4f 4b 20 26 26 20 61 72 67 63 3d 3d  ITE_OK && argc==
3270: 35 20 29 7b 0a 20 20 20 20 63 68 61 72 20 2a 7a  5 ){.    char *z
3280: 53 71 6c 3b 0a 20 20 20 20 65 63 68 6f 5f 76 74  Sql;.    echo_vt
3290: 61 62 20 2a 70 56 74 61 62 20 3d 20 2a 28 65 63  ab *pVtab = *(ec
32a0: 68 6f 5f 76 74 61 62 20 2a 2a 29 70 70 56 74 61  ho_vtab **)ppVta
32b0: 62 3b 0a 20 20 20 20 70 56 74 61 62 2d 3e 7a 4c  b;.    pVtab->zL
32c0: 6f 67 4e 61 6d 65 20 3d 20 73 71 6c 69 74 65 33  ogName = sqlite3
32d0: 4d 50 72 69 6e 74 66 28 30 2c 20 22 25 73 22 2c  MPrintf(0, "%s",
32e0: 20 61 72 67 76 5b 34 5d 29 3b 0a 20 20 20 20 7a   argv[4]);.    z
32f0: 53 71 6c 20 3d 20 73 71 6c 69 74 65 33 4d 50 72  Sql = sqlite3MPr
3300: 69 6e 74 66 28 30 2c 20 22 43 52 45 41 54 45 20  intf(0, "CREATE 
3310: 54 41 42 4c 45 20 25 51 28 6c 6f 67 6d 73 67 29  TABLE %Q(logmsg)
3320: 22 2c 20 70 56 74 61 62 2d 3e 7a 4c 6f 67 4e 61  ", pVtab->zLogNa
3330: 6d 65 29 3b 0a 20 20 20 20 72 63 20 3d 20 73 71  me);.    rc = sq
3340: 6c 69 74 65 33 5f 65 78 65 63 28 64 62 2c 20 7a  lite3_exec(db, z
3350: 53 71 6c 2c 20 30 2c 20 30 2c 20 30 29 3b 0a 20  Sql, 0, 0, 0);. 
3360: 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28     sqlite3_free(
3370: 7a 53 71 6c 29 3b 0a 20 20 20 20 69 66 28 20 72  zSql);.    if( r
3380: 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a  c!=SQLITE_OK ){.
3390: 20 20 20 20 20 20 2a 70 7a 45 72 72 20 3d 20 73        *pzErr = s
33a0: 71 6c 69 74 65 33 44 62 53 74 72 44 75 70 28 30  qlite3DbStrDup(0
33b0: 2c 20 73 71 6c 69 74 65 33 5f 65 72 72 6d 73 67  , sqlite3_errmsg
33c0: 28 64 62 29 29 3b 0a 20 20 20 20 7d 0a 20 20 7d  (db));.    }.  }
33d0: 0a 0a 20 20 69 66 28 20 2a 70 70 56 74 61 62 20  ..  if( *ppVtab 
33e0: 26 26 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b  && rc!=SQLITE_OK
33f0: 20 29 7b 0a 20 20 20 20 65 63 68 6f 44 65 73 74   ){.    echoDest
3400: 72 75 63 74 6f 72 28 2a 70 70 56 74 61 62 29 3b  ructor(*ppVtab);
3410: 0a 20 20 20 20 2a 70 70 56 74 61 62 20 3d 20 30  .    *ppVtab = 0
3420: 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 72 63 3d  ;.  }..  if( rc=
3430: 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20  =SQLITE_OK ){.  
3440: 20 20 28 2a 28 65 63 68 6f 5f 76 74 61 62 2a 2a    (*(echo_vtab**
3450: 29 70 70 56 74 61 62 29 2d 3e 69 6e 54 72 61 6e  )ppVtab)->inTran
3460: 73 61 63 74 69 6f 6e 20 3d 20 31 3b 0a 20 20 7d  saction = 1;.  }
3470: 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d  ..  return rc;.}
3480: 0a 0a 2f 2a 20 0a 2a 2a 20 45 63 68 6f 20 76 69  ../* .** Echo vi
3490: 72 74 75 61 6c 20 74 61 62 6c 65 20 6d 6f 64 75  rtual table modu
34a0: 6c 65 20 78 43 6f 6e 6e 65 63 74 20 6d 65 74 68  le xConnect meth
34b0: 6f 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  od..*/.static in
34c0: 74 20 65 63 68 6f 43 6f 6e 6e 65 63 74 28 0a 20  t echoConnect(. 
34d0: 20 73 71 6c 69 74 65 33 20 2a 64 62 2c 0a 20 20   sqlite3 *db,.  
34e0: 76 6f 69 64 20 2a 70 41 75 78 2c 0a 20 20 69 6e  void *pAux,.  in
34f0: 74 20 61 72 67 63 2c 20 63 6f 6e 73 74 20 63 68  t argc, const ch
3500: 61 72 20 2a 63 6f 6e 73 74 2a 61 72 67 76 2c 0a  ar *const*argv,.
3510: 20 20 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a    sqlite3_vtab *
3520: 2a 70 70 56 74 61 62 2c 0a 20 20 63 68 61 72 20  *ppVtab,.  char 
3530: 2a 2a 70 7a 45 72 72 0a 29 7b 0a 20 20 61 70 70  **pzErr.){.  app
3540: 65 6e 64 54 6f 45 63 68 6f 4d 6f 64 75 6c 65 28  endToEchoModule(
3550: 28 28 45 63 68 6f 4d 6f 64 75 6c 65 20 2a 29 70  ((EchoModule *)p
3560: 41 75 78 29 2d 3e 69 6e 74 65 72 70 2c 20 22 78  Aux)->interp, "x
3570: 43 6f 6e 6e 65 63 74 22 29 3b 0a 20 20 72 65 74  Connect");.  ret
3580: 75 72 6e 20 65 63 68 6f 43 6f 6e 73 74 72 75 63  urn echoConstruc
3590: 74 6f 72 28 64 62 2c 20 70 41 75 78 2c 20 61 72  tor(db, pAux, ar
35a0: 67 63 2c 20 61 72 67 76 2c 20 70 70 56 74 61 62  gc, argv, ppVtab
35b0: 2c 20 70 7a 45 72 72 29 3b 0a 7d 0a 0a 2f 2a 20  , pzErr);.}../* 
35c0: 0a 2a 2a 20 45 63 68 6f 20 76 69 72 74 75 61 6c  .** Echo virtual
35d0: 20 74 61 62 6c 65 20 6d 6f 64 75 6c 65 20 78 44   table module xD
35e0: 69 73 63 6f 6e 6e 65 63 74 20 6d 65 74 68 6f 64  isconnect method
35f0: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
3600: 65 63 68 6f 44 69 73 63 6f 6e 6e 65 63 74 28 73  echoDisconnect(s
3610: 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 70 56 74  qlite3_vtab *pVt
3620: 61 62 29 7b 0a 20 20 61 70 70 65 6e 64 54 6f 45  ab){.  appendToE
3630: 63 68 6f 4d 6f 64 75 6c 65 28 28 28 65 63 68 6f  choModule(((echo
3640: 5f 76 74 61 62 20 2a 29 70 56 74 61 62 29 2d 3e  _vtab *)pVtab)->
3650: 69 6e 74 65 72 70 2c 20 22 78 44 69 73 63 6f 6e  interp, "xDiscon
3660: 6e 65 63 74 22 29 3b 0a 20 20 72 65 74 75 72 6e  nect");.  return
3670: 20 65 63 68 6f 44 65 73 74 72 75 63 74 6f 72 28   echoDestructor(
3680: 70 56 74 61 62 29 3b 0a 7d 0a 0a 2f 2a 20 0a 2a  pVtab);.}../* .*
3690: 2a 20 45 63 68 6f 20 76 69 72 74 75 61 6c 20 74  * Echo virtual t
36a0: 61 62 6c 65 20 6d 6f 64 75 6c 65 20 78 44 65 73  able module xDes
36b0: 74 72 6f 79 20 6d 65 74 68 6f 64 2e 0a 2a 2f 0a  troy method..*/.
36c0: 73 74 61 74 69 63 20 69 6e 74 20 65 63 68 6f 44  static int echoD
36d0: 65 73 74 72 6f 79 28 73 71 6c 69 74 65 33 5f 76  estroy(sqlite3_v
36e0: 74 61 62 20 2a 70 56 74 61 62 29 7b 0a 20 20 69  tab *pVtab){.  i
36f0: 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f  nt rc = SQLITE_O
3700: 4b 3b 0a 20 20 65 63 68 6f 5f 76 74 61 62 20 2a  K;.  echo_vtab *
3710: 70 20 3d 20 28 65 63 68 6f 5f 76 74 61 62 20 2a  p = (echo_vtab *
3720: 29 70 56 74 61 62 3b 0a 20 20 61 70 70 65 6e 64  )pVtab;.  append
3730: 54 6f 45 63 68 6f 4d 6f 64 75 6c 65 28 28 28 65  ToEchoModule(((e
3740: 63 68 6f 5f 76 74 61 62 20 2a 29 70 56 74 61 62  cho_vtab *)pVtab
3750: 29 2d 3e 69 6e 74 65 72 70 2c 20 22 78 44 65 73  )->interp, "xDes
3760: 74 72 6f 79 22 29 3b 0a 0a 20 20 2f 2a 20 44 72  troy");..  /* Dr
3770: 6f 70 20 74 68 65 20 22 6c 6f 67 22 20 74 61 62  op the "log" tab
3780: 6c 65 2c 20 69 66 20 6f 6e 65 20 65 78 69 73 74  le, if one exist
3790: 73 20 28 73 65 65 20 65 63 68 6f 43 72 65 61 74  s (see echoCreat
37a0: 65 28 29 20 66 6f 72 20 64 65 74 61 69 6c 73 29  e() for details)
37b0: 20 2a 2f 0a 20 20 69 66 28 20 70 20 26 26 20 70   */.  if( p && p
37c0: 2d 3e 7a 4c 6f 67 4e 61 6d 65 20 29 7b 0a 20 20  ->zLogName ){.  
37d0: 20 20 63 68 61 72 20 2a 7a 53 71 6c 3b 0a 20 20    char *zSql;.  
37e0: 20 20 7a 53 71 6c 20 3d 20 73 71 6c 69 74 65 33    zSql = sqlite3
37f0: 4d 50 72 69 6e 74 66 28 30 2c 20 22 44 52 4f 50  MPrintf(0, "DROP
3800: 20 54 41 42 4c 45 20 25 51 22 2c 20 70 2d 3e 7a   TABLE %Q", p->z
3810: 4c 6f 67 4e 61 6d 65 29 3b 0a 20 20 20 20 72 63  LogName);.    rc
3820: 20 3d 20 73 71 6c 69 74 65 33 5f 65 78 65 63 28   = sqlite3_exec(
3830: 70 2d 3e 64 62 2c 20 7a 53 71 6c 2c 20 30 2c 20  p->db, zSql, 0, 
3840: 30 2c 20 30 29 3b 0a 20 20 20 20 73 71 6c 69 74  0, 0);.    sqlit
3850: 65 33 5f 66 72 65 65 28 7a 53 71 6c 29 3b 0a 20  e3_free(zSql);. 
3860: 20 7d 0a 0a 20 20 69 66 28 20 72 63 3d 3d 53 51   }..  if( rc==SQ
3870: 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 72  LITE_OK ){.    r
3880: 63 20 3d 20 65 63 68 6f 44 65 73 74 72 75 63 74  c = echoDestruct
3890: 6f 72 28 70 56 74 61 62 29 3b 0a 20 20 7d 0a 20  or(pVtab);.  }. 
38a0: 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f   return rc;.}../
38b0: 2a 20 0a 2a 2a 20 45 63 68 6f 20 76 69 72 74 75  * .** Echo virtu
38c0: 61 6c 20 74 61 62 6c 65 20 6d 6f 64 75 6c 65 20  al table module 
38d0: 78 4f 70 65 6e 20 6d 65 74 68 6f 64 2e 0a 2a 2f  xOpen method..*/
38e0: 0a 73 74 61 74 69 63 20 69 6e 74 20 65 63 68 6f  .static int echo
38f0: 4f 70 65 6e 28 73 71 6c 69 74 65 33 5f 76 74 61  Open(sqlite3_vta
3900: 62 20 2a 70 56 54 61 62 2c 20 73 71 6c 69 74 65  b *pVTab, sqlite
3910: 33 5f 76 74 61 62 5f 63 75 72 73 6f 72 20 2a 2a  3_vtab_cursor **
3920: 70 70 43 75 72 73 6f 72 29 7b 0a 20 20 65 63 68  ppCursor){.  ech
3930: 6f 5f 63 75 72 73 6f 72 20 2a 70 43 75 72 3b 0a  o_cursor *pCur;.
3940: 20 20 70 43 75 72 20 3d 20 73 71 6c 69 74 65 33    pCur = sqlite3
3950: 4d 61 6c 6c 6f 63 5a 65 72 6f 28 73 69 7a 65 6f  MallocZero(sizeo
3960: 66 28 65 63 68 6f 5f 63 75 72 73 6f 72 29 29 3b  f(echo_cursor));
3970: 0a 20 20 2a 70 70 43 75 72 73 6f 72 20 3d 20 28  .  *ppCursor = (
3980: 73 71 6c 69 74 65 33 5f 76 74 61 62 5f 63 75 72  sqlite3_vtab_cur
3990: 73 6f 72 20 2a 29 70 43 75 72 3b 0a 20 20 72 65  sor *)pCur;.  re
39a0: 74 75 72 6e 20 28 70 43 75 72 20 3f 20 53 51 4c  turn (pCur ? SQL
39b0: 49 54 45 5f 4f 4b 20 3a 20 53 51 4c 49 54 45 5f  ITE_OK : SQLITE_
39c0: 4e 4f 4d 45 4d 29 3b 0a 7d 0a 0a 2f 2a 20 0a 2a  NOMEM);.}../* .*
39d0: 2a 20 45 63 68 6f 20 76 69 72 74 75 61 6c 20 74  * Echo virtual t
39e0: 61 62 6c 65 20 6d 6f 64 75 6c 65 20 78 43 6c 6f  able module xClo
39f0: 73 65 20 6d 65 74 68 6f 64 2e 0a 2a 2f 0a 73 74  se method..*/.st
3a00: 61 74 69 63 20 69 6e 74 20 65 63 68 6f 43 6c 6f  atic int echoClo
3a10: 73 65 28 73 71 6c 69 74 65 33 5f 76 74 61 62 5f  se(sqlite3_vtab_
3a20: 63 75 72 73 6f 72 20 2a 63 75 72 29 7b 0a 20 20  cursor *cur){.  
3a30: 69 6e 74 20 72 63 3b 0a 20 20 65 63 68 6f 5f 63  int rc;.  echo_c
3a40: 75 72 73 6f 72 20 2a 70 43 75 72 20 3d 20 28 65  ursor *pCur = (e
3a50: 63 68 6f 5f 63 75 72 73 6f 72 20 2a 29 63 75 72  cho_cursor *)cur
3a60: 3b 0a 20 20 73 71 6c 69 74 65 33 5f 73 74 6d 74  ;.  sqlite3_stmt
3a70: 20 2a 70 53 74 6d 74 20 3d 20 70 43 75 72 2d 3e   *pStmt = pCur->
3a80: 70 53 74 6d 74 3b 0a 20 20 70 43 75 72 2d 3e 70  pStmt;.  pCur->p
3a90: 53 74 6d 74 20 3d 20 30 3b 0a 20 20 73 71 6c 69  Stmt = 0;.  sqli
3aa0: 74 65 33 5f 66 72 65 65 28 70 43 75 72 29 3b 0a  te3_free(pCur);.
3ab0: 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 66    rc = sqlite3_f
3ac0: 69 6e 61 6c 69 7a 65 28 70 53 74 6d 74 29 3b 0a  inalize(pStmt);.
3ad0: 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a    return rc;.}..
3ae0: 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 6e 6f 6e  /*.** Return non
3af0: 2d 7a 65 72 6f 20 69 66 20 74 68 65 20 63 75 72  -zero if the cur
3b00: 73 6f 72 20 64 6f 65 73 20 6e 6f 74 20 63 75 72  sor does not cur
3b10: 72 65 6e 74 6c 79 20 70 6f 69 6e 74 20 74 6f 20  rently point to 
3b20: 61 20 76 61 6c 69 64 20 72 65 63 6f 72 64 0a 2a  a valid record.*
3b30: 2a 20 28 69 2e 65 20 69 66 20 74 68 65 20 73 63  * (i.e if the sc
3b40: 61 6e 20 68 61 73 20 66 69 6e 69 73 68 65 64 29  an has finished)
3b50: 2c 20 6f 72 20 7a 65 72 6f 20 6f 74 68 65 72 77  , or zero otherw
3b60: 69 73 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  ise..*/.static i
3b70: 6e 74 20 65 63 68 6f 45 6f 66 28 73 71 6c 69 74  nt echoEof(sqlit
3b80: 65 33 5f 76 74 61 62 5f 63 75 72 73 6f 72 20 2a  e3_vtab_cursor *
3b90: 63 75 72 29 7b 0a 20 20 72 65 74 75 72 6e 20 28  cur){.  return (
3ba0: 28 28 65 63 68 6f 5f 63 75 72 73 6f 72 20 2a 29  ((echo_cursor *)
3bb0: 63 75 72 29 2d 3e 70 53 74 6d 74 20 3f 20 30 20  cur)->pStmt ? 0 
3bc0: 3a 20 31 29 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20  : 1);.}../* .** 
3bd0: 45 63 68 6f 20 76 69 72 74 75 61 6c 20 74 61 62  Echo virtual tab
3be0: 6c 65 20 6d 6f 64 75 6c 65 20 78 4e 65 78 74 20  le module xNext 
3bf0: 6d 65 74 68 6f 64 2e 0a 2a 2f 0a 73 74 61 74 69  method..*/.stati
3c00: 63 20 69 6e 74 20 65 63 68 6f 4e 65 78 74 28 73  c int echoNext(s
3c10: 71 6c 69 74 65 33 5f 76 74 61 62 5f 63 75 72 73  qlite3_vtab_curs
3c20: 6f 72 20 2a 63 75 72 29 7b 0a 20 20 69 6e 74 20  or *cur){.  int 
3c30: 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a  rc = SQLITE_OK;.
3c40: 20 20 65 63 68 6f 5f 63 75 72 73 6f 72 20 2a 70    echo_cursor *p
3c50: 43 75 72 20 3d 20 28 65 63 68 6f 5f 63 75 72 73  Cur = (echo_curs
3c60: 6f 72 20 2a 29 63 75 72 3b 0a 0a 20 20 69 66 28  or *)cur;..  if(
3c70: 20 70 43 75 72 2d 3e 70 53 74 6d 74 20 29 7b 0a   pCur->pStmt ){.
3c80: 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33      rc = sqlite3
3c90: 5f 73 74 65 70 28 70 43 75 72 2d 3e 70 53 74 6d  _step(pCur->pStm
3ca0: 74 29 3b 0a 20 20 20 20 69 66 28 20 72 63 3d 3d  t);.    if( rc==
3cb0: 53 51 4c 49 54 45 5f 52 4f 57 20 29 7b 0a 20 20  SQLITE_ROW ){.  
3cc0: 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f      rc = SQLITE_
3cd0: 4f 4b 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20  OK;.    }else{. 
3ce0: 20 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65       rc = sqlite
3cf0: 33 5f 66 69 6e 61 6c 69 7a 65 28 70 43 75 72 2d  3_finalize(pCur-
3d00: 3e 70 53 74 6d 74 29 3b 0a 20 20 20 20 20 20 70  >pStmt);.      p
3d10: 43 75 72 2d 3e 70 53 74 6d 74 20 3d 20 30 3b 0a  Cur->pStmt = 0;.
3d20: 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 72 65 74      }.  }..  ret
3d30: 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 20 0a 2a  urn rc;.}../* .*
3d40: 2a 20 45 63 68 6f 20 76 69 72 74 75 61 6c 20 74  * Echo virtual t
3d50: 61 62 6c 65 20 6d 6f 64 75 6c 65 20 78 43 6f 6c  able module xCol
3d60: 75 6d 6e 20 6d 65 74 68 6f 64 2e 0a 2a 2f 0a 73  umn method..*/.s
3d70: 74 61 74 69 63 20 69 6e 74 20 65 63 68 6f 43 6f  tatic int echoCo
3d80: 6c 75 6d 6e 28 73 71 6c 69 74 65 33 5f 76 74 61  lumn(sqlite3_vta
3d90: 62 5f 63 75 72 73 6f 72 20 2a 63 75 72 2c 20 73  b_cursor *cur, s
3da0: 71 6c 69 74 65 33 5f 63 6f 6e 74 65 78 74 20 2a  qlite3_context *
3db0: 63 74 78 2c 20 69 6e 74 20 69 29 7b 0a 20 20 69  ctx, int i){.  i
3dc0: 6e 74 20 69 43 6f 6c 20 3d 20 69 20 2b 20 31 3b  nt iCol = i + 1;
3dd0: 0a 20 20 73 71 6c 69 74 65 33 5f 73 74 6d 74 20  .  sqlite3_stmt 
3de0: 2a 70 53 74 6d 74 20 3d 20 28 28 65 63 68 6f 5f  *pStmt = ((echo_
3df0: 63 75 72 73 6f 72 20 2a 29 63 75 72 29 2d 3e 70  cursor *)cur)->p
3e00: 53 74 6d 74 3b 0a 20 20 69 66 28 20 21 70 53 74  Stmt;.  if( !pSt
3e10: 6d 74 20 29 7b 0a 20 20 20 20 73 71 6c 69 74 65  mt ){.    sqlite
3e20: 33 5f 72 65 73 75 6c 74 5f 6e 75 6c 6c 28 63 74  3_result_null(ct
3e30: 78 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20  x);.  }else{.   
3e40: 20 61 73 73 65 72 74 28 20 73 71 6c 69 74 65 33   assert( sqlite3
3e50: 5f 64 61 74 61 5f 63 6f 75 6e 74 28 70 53 74 6d  _data_count(pStm
3e60: 74 29 3e 69 43 6f 6c 20 29 3b 0a 20 20 20 20 73  t)>iCol );.    s
3e70: 71 6c 69 74 65 33 5f 72 65 73 75 6c 74 5f 76 61  qlite3_result_va
3e80: 6c 75 65 28 63 74 78 2c 20 73 71 6c 69 74 65 33  lue(ctx, sqlite3
3e90: 5f 63 6f 6c 75 6d 6e 5f 76 61 6c 75 65 28 70 53  _column_value(pS
3ea0: 74 6d 74 2c 20 69 43 6f 6c 29 29 3b 0a 20 20 7d  tmt, iCol));.  }
3eb0: 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45  .  return SQLITE
3ec0: 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 45  _OK;.}../* .** E
3ed0: 63 68 6f 20 76 69 72 74 75 61 6c 20 74 61 62 6c  cho virtual tabl
3ee0: 65 20 6d 6f 64 75 6c 65 20 78 52 6f 77 69 64 20  e module xRowid 
3ef0: 6d 65 74 68 6f 64 2e 0a 2a 2f 0a 73 74 61 74 69  method..*/.stati
3f00: 63 20 69 6e 74 20 65 63 68 6f 52 6f 77 69 64 28  c int echoRowid(
3f10: 73 71 6c 69 74 65 33 5f 76 74 61 62 5f 63 75 72  sqlite3_vtab_cur
3f20: 73 6f 72 20 2a 63 75 72 2c 20 73 71 6c 69 74 65  sor *cur, sqlite
3f30: 5f 69 6e 74 36 34 20 2a 70 52 6f 77 69 64 29 7b  _int64 *pRowid){
3f40: 0a 20 20 73 71 6c 69 74 65 33 5f 73 74 6d 74 20  .  sqlite3_stmt 
3f50: 2a 70 53 74 6d 74 20 3d 20 28 28 65 63 68 6f 5f  *pStmt = ((echo_
3f60: 63 75 72 73 6f 72 20 2a 29 63 75 72 29 2d 3e 70  cursor *)cur)->p
3f70: 53 74 6d 74 3b 0a 20 20 2a 70 52 6f 77 69 64 20  Stmt;.  *pRowid 
3f80: 3d 20 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e  = sqlite3_column
3f90: 5f 69 6e 74 36 34 28 70 53 74 6d 74 2c 20 30 29  _int64(pStmt, 0)
3fa0: 3b 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54  ;.  return SQLIT
3fb0: 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43  E_OK;.}../*.** C
3fc0: 6f 6d 70 75 74 65 20 61 20 73 69 6d 70 6c 65 20  ompute a simple 
3fd0: 68 61 73 68 20 6f 66 20 74 68 65 20 6e 75 6c 6c  hash of the null
3fe0: 20 74 65 72 6d 69 6e 61 74 65 64 20 73 74 72 69   terminated stri
3ff0: 6e 67 20 7a 53 74 72 69 6e 67 2e 0a 2a 2a 0a 2a  ng zString..**.*
4000: 2a 20 54 68 69 73 20 6d 6f 64 75 6c 65 20 75 73  * This module us
4010: 65 73 20 6f 6e 6c 79 20 73 71 6c 69 74 65 33 5f  es only sqlite3_
4020: 69 6e 64 65 78 5f 69 6e 66 6f 2e 69 64 78 53 74  index_info.idxSt
4030: 72 2c 20 6e 6f 74 20 0a 2a 2a 20 73 71 6c 69 74  r, not .** sqlit
4040: 65 33 5f 69 6e 64 65 78 5f 69 6e 66 6f 2e 69 64  e3_index_info.id
4050: 78 4e 75 6d 2e 20 53 6f 20 74 6f 20 74 65 73 74  xNum. So to test
4060: 20 69 64 78 4e 75 6d 2c 20 77 68 65 6e 20 69 64   idxNum, when id
4070: 78 53 74 72 20 69 73 20 73 65 74 0a 2a 2a 20 69  xStr is set.** i
4080: 6e 20 65 63 68 6f 42 65 73 74 49 6e 64 65 78 28  n echoBestIndex(
4090: 29 2c 20 69 64 78 4e 75 6d 20 69 73 20 73 65 74  ), idxNum is set
40a0: 20 74 6f 20 74 68 65 20 63 6f 72 72 65 73 70 6f   to the correspo
40b0: 6e 64 69 6e 67 20 68 61 73 68 20 76 61 6c 75 65  nding hash value
40c0: 2e 0a 2a 2a 20 49 6e 20 65 63 68 6f 46 69 6c 74  ..** In echoFilt
40d0: 65 72 28 29 2c 20 63 6f 64 65 20 61 73 73 65 72  er(), code asser
40e0: 74 28 29 73 20 74 68 61 74 20 74 68 65 20 73 75  t()s that the su
40f0: 70 70 6c 69 65 64 20 69 64 78 4e 75 6d 20 76 61  pplied idxNum va
4100: 6c 75 65 20 69 73 0a 2a 2a 20 69 6e 64 65 65 64  lue is.** indeed
4110: 20 74 68 65 20 68 61 73 68 20 6f 66 20 74 68 65   the hash of the
4120: 20 73 75 70 70 6c 69 65 64 20 69 64 78 53 74 72   supplied idxStr
4130: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
4140: 68 61 73 68 53 74 72 69 6e 67 28 63 6f 6e 73 74  hashString(const
4150: 20 63 68 61 72 20 2a 7a 53 74 72 69 6e 67 29 7b   char *zString){
4160: 0a 20 20 69 6e 74 20 76 61 6c 20 3d 20 30 3b 0a  .  int val = 0;.
4170: 20 20 69 6e 74 20 69 69 3b 0a 20 20 66 6f 72 28    int ii;.  for(
4180: 69 69 3d 30 3b 20 7a 53 74 72 69 6e 67 5b 69 69  ii=0; zString[ii
4190: 5d 3b 20 69 69 2b 2b 29 7b 0a 20 20 20 20 76 61  ]; ii++){.    va
41a0: 6c 20 3d 20 28 76 61 6c 20 3c 3c 20 33 29 20 2b  l = (val << 3) +
41b0: 20 28 69 6e 74 29 7a 53 74 72 69 6e 67 5b 69 69   (int)zString[ii
41c0: 5d 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20  ];.  }.  return 
41d0: 76 61 6c 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 45  val;.}../* .** E
41e0: 63 68 6f 20 76 69 72 74 75 61 6c 20 74 61 62 6c  cho virtual tabl
41f0: 65 20 6d 6f 64 75 6c 65 20 78 46 69 6c 74 65 72  e module xFilter
4200: 20 6d 65 74 68 6f 64 2e 0a 2a 2f 0a 73 74 61 74   method..*/.stat
4210: 69 63 20 69 6e 74 20 65 63 68 6f 46 69 6c 74 65  ic int echoFilte
4220: 72 28 0a 20 20 73 71 6c 69 74 65 33 5f 76 74 61  r(.  sqlite3_vta
4230: 62 5f 63 75 72 73 6f 72 20 2a 70 56 74 61 62 43  b_cursor *pVtabC
4240: 75 72 73 6f 72 2c 20 0a 20 20 69 6e 74 20 69 64  ursor, .  int id
4250: 78 4e 75 6d 2c 20 63 6f 6e 73 74 20 63 68 61 72  xNum, const char
4260: 20 2a 69 64 78 53 74 72 2c 0a 20 20 69 6e 74 20   *idxStr,.  int 
4270: 61 72 67 63 2c 20 73 71 6c 69 74 65 33 5f 76 61  argc, sqlite3_va
4280: 6c 75 65 20 2a 2a 61 72 67 76 0a 29 7b 0a 20 20  lue **argv.){.  
4290: 69 6e 74 20 72 63 3b 0a 20 20 69 6e 74 20 69 3b  int rc;.  int i;
42a0: 0a 0a 20 20 65 63 68 6f 5f 63 75 72 73 6f 72 20  ..  echo_cursor 
42b0: 2a 70 43 75 72 20 3d 20 28 65 63 68 6f 5f 63 75  *pCur = (echo_cu
42c0: 72 73 6f 72 20 2a 29 70 56 74 61 62 43 75 72 73  rsor *)pVtabCurs
42d0: 6f 72 3b 0a 20 20 65 63 68 6f 5f 76 74 61 62 20  or;.  echo_vtab 
42e0: 2a 70 56 74 61 62 20 3d 20 28 65 63 68 6f 5f 76  *pVtab = (echo_v
42f0: 74 61 62 20 2a 29 70 56 74 61 62 43 75 72 73 6f  tab *)pVtabCurso
4300: 72 2d 3e 70 56 74 61 62 3b 0a 20 20 73 71 6c 69  r->pVtab;.  sqli
4310: 74 65 33 20 2a 64 62 20 3d 20 70 56 74 61 62 2d  te3 *db = pVtab-
4320: 3e 64 62 3b 0a 0a 20 20 2f 2a 20 43 68 65 63 6b  >db;..  /* Check
4330: 20 74 68 61 74 20 69 64 78 4e 75 6d 20 6d 61 74   that idxNum mat
4340: 63 68 65 73 20 69 64 78 53 74 72 20 2a 2f 0a 20  ches idxStr */. 
4350: 20 61 73 73 65 72 74 28 20 69 64 78 4e 75 6d 3d   assert( idxNum=
4360: 3d 68 61 73 68 53 74 72 69 6e 67 28 69 64 78 53  =hashString(idxS
4370: 74 72 29 20 29 3b 0a 0a 20 20 2f 2a 20 4c 6f 67  tr) );..  /* Log
4380: 20 61 72 67 75 6d 65 6e 74 73 20 74 6f 20 74 68   arguments to th
4390: 65 20 3a 3a 65 63 68 6f 5f 6d 6f 64 75 6c 65 20  e ::echo_module 
43a0: 54 63 6c 20 76 61 72 69 61 62 6c 65 20 2a 2f 0a  Tcl variable */.
43b0: 20 20 61 70 70 65 6e 64 54 6f 45 63 68 6f 4d 6f    appendToEchoMo
43c0: 64 75 6c 65 28 70 56 74 61 62 2d 3e 69 6e 74 65  dule(pVtab->inte
43d0: 72 70 2c 20 22 78 46 69 6c 74 65 72 22 29 3b 0a  rp, "xFilter");.
43e0: 20 20 61 70 70 65 6e 64 54 6f 45 63 68 6f 4d 6f    appendToEchoMo
43f0: 64 75 6c 65 28 70 56 74 61 62 2d 3e 69 6e 74 65  dule(pVtab->inte
4400: 72 70 2c 20 69 64 78 53 74 72 29 3b 0a 20 20 66  rp, idxStr);.  f
4410: 6f 72 28 69 3d 30 3b 20 69 3c 61 72 67 63 3b 20  or(i=0; i<argc; 
4420: 69 2b 2b 29 7b 0a 20 20 20 20 61 70 70 65 6e 64  i++){.    append
4430: 54 6f 45 63 68 6f 4d 6f 64 75 6c 65 28 70 56 74  ToEchoModule(pVt
4440: 61 62 2d 3e 69 6e 74 65 72 70 2c 20 28 63 6f 6e  ab->interp, (con
4450: 73 74 20 63 68 61 72 2a 29 73 71 6c 69 74 65 33  st char*)sqlite3
4460: 5f 76 61 6c 75 65 5f 74 65 78 74 28 61 72 67 76  _value_text(argv
4470: 5b 69 5d 29 29 3b 0a 20 20 7d 0a 0a 20 20 73 71  [i]));.  }..  sq
4480: 6c 69 74 65 33 5f 66 69 6e 61 6c 69 7a 65 28 70  lite3_finalize(p
4490: 43 75 72 2d 3e 70 53 74 6d 74 29 3b 0a 20 20 70  Cur->pStmt);.  p
44a0: 43 75 72 2d 3e 70 53 74 6d 74 20 3d 20 30 3b 0a  Cur->pStmt = 0;.
44b0: 0a 20 20 2f 2a 20 50 72 65 70 61 72 65 20 74 68  .  /* Prepare th
44c0: 65 20 53 51 4c 20 73 74 61 74 65 6d 65 6e 74 20  e SQL statement 
44d0: 63 72 65 61 74 65 64 20 62 79 20 65 63 68 6f 42  created by echoB
44e0: 65 73 74 49 6e 64 65 78 20 61 6e 64 20 62 69 6e  estIndex and bin
44f0: 64 20 74 68 65 0a 20 20 2a 2a 20 72 75 6e 74 69  d the.  ** runti
4500: 6d 65 20 70 61 72 61 6d 65 74 65 72 73 20 70 61  me parameters pa
4510: 73 73 65 64 20 74 6f 20 74 68 69 73 20 66 75 6e  ssed to this fun
4520: 63 74 69 6f 6e 20 74 6f 20 69 74 2e 0a 20 20 2a  ction to it..  *
4530: 2f 0a 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33  /.  rc = sqlite3
4540: 5f 70 72 65 70 61 72 65 28 64 62 2c 20 69 64 78  _prepare(db, idx
4550: 53 74 72 2c 20 2d 31 2c 20 26 70 43 75 72 2d 3e  Str, -1, &pCur->
4560: 70 53 74 6d 74 2c 20 30 29 3b 0a 20 20 61 73 73  pStmt, 0);.  ass
4570: 65 72 74 28 20 70 43 75 72 2d 3e 70 53 74 6d 74  ert( pCur->pStmt
4580: 20 7c 7c 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f   || rc!=SQLITE_O
4590: 4b 20 29 3b 0a 20 20 66 6f 72 28 69 3d 30 3b 20  K );.  for(i=0; 
45a0: 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26  rc==SQLITE_OK &&
45b0: 20 69 3c 61 72 67 63 3b 20 69 2b 2b 29 7b 0a 20   i<argc; i++){. 
45c0: 20 20 20 73 71 6c 69 74 65 33 5f 62 69 6e 64 5f     sqlite3_bind_
45d0: 76 61 6c 75 65 28 70 43 75 72 2d 3e 70 53 74 6d  value(pCur->pStm
45e0: 74 2c 20 69 2b 31 2c 20 61 72 67 76 5b 69 5d 29  t, i+1, argv[i])
45f0: 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 49 66 20 65  ;.  }..  /* If e
4600: 76 65 72 79 74 68 69 6e 67 20 77 61 73 20 73 75  verything was su
4610: 63 63 65 73 73 66 75 6c 2c 20 61 64 76 61 6e 63  ccessful, advanc
4620: 65 20 74 6f 20 74 68 65 20 66 69 72 73 74 20 72  e to the first r
4630: 6f 77 20 6f 66 20 74 68 65 20 73 63 61 6e 20 2a  ow of the scan *
4640: 2f 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49  /.  if( rc==SQLI
4650: 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 72 63 20  TE_OK ){.    rc 
4660: 3d 20 65 63 68 6f 4e 65 78 74 28 70 56 74 61 62  = echoNext(pVtab
4670: 43 75 72 73 6f 72 29 3b 0a 20 20 7d 0a 0a 20 20  Cursor);.  }..  
4680: 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 0a 2f  return rc;.}.../
4690: 2a 0a 2a 2a 20 41 20 68 65 6c 70 65 72 20 66 75  *.** A helper fu
46a0: 6e 63 74 69 6f 6e 20 75 73 65 64 20 62 79 20 65  nction used by e
46b0: 63 68 6f 55 70 64 61 74 65 28 29 20 61 6e 64 20  choUpdate() and 
46c0: 65 63 68 6f 42 65 73 74 49 6e 64 65 78 28 29 20  echoBestIndex() 
46d0: 66 6f 72 0a 2a 2a 20 6d 61 6e 69 70 75 6c 61 74  for.** manipulat
46e0: 69 6e 67 20 73 74 72 69 6e 67 73 20 69 6e 20 63  ing strings in c
46f0: 6f 6e 63 65 72 74 20 77 69 74 68 20 74 68 65 20  oncert with the 
4700: 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28  sqlite3_mprintf(
4710: 29 20 66 75 6e 63 74 69 6f 6e 2e 0a 2a 2a 0a 2a  ) function..**.*
4720: 2a 20 50 61 72 61 6d 65 74 65 72 20 70 7a 53 74  * Parameter pzSt
4730: 72 20 70 6f 69 6e 74 73 20 74 6f 20 61 20 70 6f  r points to a po
4740: 69 6e 74 65 72 20 74 6f 20 61 20 73 74 72 69 6e  inter to a strin
4750: 67 20 61 6c 6c 6f 63 61 74 65 64 20 77 69 74 68  g allocated with
4760: 0a 2a 2a 20 73 71 6c 69 74 65 33 5f 6d 70 72 69  .** sqlite3_mpri
4770: 6e 74 66 2e 20 54 68 65 20 73 65 63 6f 6e 64 20  ntf. The second 
4780: 70 61 72 61 6d 65 74 65 72 2c 20 7a 41 70 70 65  parameter, zAppe
4790: 6e 64 2c 20 70 6f 69 6e 74 73 20 74 6f 20 61 6e  nd, points to an
47a0: 6f 74 68 65 72 0a 2a 2a 20 73 74 72 69 6e 67 2e  other.** string.
47b0: 20 54 68 65 20 74 77 6f 20 73 74 72 69 6e 67 73   The two strings
47c0: 20 61 72 65 20 63 6f 6e 63 61 74 65 6e 61 74 65   are concatenate
47d0: 64 20 74 6f 67 65 74 68 65 72 20 61 6e 64 20 2a  d together and *
47e0: 70 7a 53 74 72 0a 2a 2a 20 73 65 74 20 74 6f 20  pzStr.** set to 
47f0: 70 6f 69 6e 74 20 61 74 20 74 68 65 20 72 65 73  point at the res
4800: 75 6c 74 2e 20 54 68 65 20 69 6e 69 74 69 61 6c  ult. The initial
4810: 20 62 75 66 66 65 72 20 70 6f 69 6e 74 65 64 20   buffer pointed 
4820: 74 6f 20 62 79 20 2a 70 7a 53 74 72 0a 2a 2a 20  to by *pzStr.** 
4830: 69 73 20 64 65 61 6c 6c 6f 63 61 74 65 64 20 76  is deallocated v
4840: 69 61 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28  ia sqlite3_free(
4850: 29 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 74 68 65 20  )..**.** If the 
4860: 74 68 69 72 64 20 61 72 67 75 6d 65 6e 74 2c 20  third argument, 
4870: 64 6f 46 72 65 65 2c 20 69 73 20 74 72 75 65 2c  doFree, is true,
4880: 20 74 68 65 6e 20 73 71 6c 69 74 65 33 5f 66 72   then sqlite3_fr
4890: 65 65 28 29 20 69 73 0a 2a 2a 20 61 6c 73 6f 20  ee() is.** also 
48a0: 63 61 6c 6c 65 64 20 74 6f 20 66 72 65 65 20 74  called to free t
48b0: 68 65 20 62 75 66 66 65 72 20 70 6f 69 6e 74 65  he buffer pointe
48c0: 64 20 74 6f 20 62 79 20 7a 41 70 70 65 6e 64 2e  d to by zAppend.
48d0: 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20  .*/.static void 
48e0: 73 74 72 69 6e 67 5f 63 6f 6e 63 61 74 28 63 68  string_concat(ch
48f0: 61 72 20 2a 2a 70 7a 53 74 72 2c 20 63 68 61 72  ar **pzStr, char
4900: 20 2a 7a 41 70 70 65 6e 64 2c 20 69 6e 74 20 64   *zAppend, int d
4910: 6f 46 72 65 65 2c 20 69 6e 74 20 2a 70 52 63 29  oFree, int *pRc)
4920: 7b 0a 20 20 63 68 61 72 20 2a 7a 49 6e 20 3d 20  {.  char *zIn = 
4930: 2a 70 7a 53 74 72 3b 0a 20 20 69 66 28 20 21 7a  *pzStr;.  if( !z
4940: 41 70 70 65 6e 64 20 26 26 20 64 6f 46 72 65 65  Append && doFree
4950: 20 26 26 20 2a 70 52 63 3d 3d 53 51 4c 49 54 45   && *pRc==SQLITE
4960: 5f 4f 4b 20 29 7b 0a 20 20 20 20 2a 70 52 63 20  _OK ){.    *pRc 
4970: 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a  = SQLITE_NOMEM;.
4980: 20 20 7d 0a 20 20 69 66 28 20 2a 70 52 63 21 3d    }.  if( *pRc!=
4990: 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20  SQLITE_OK ){.   
49a0: 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 7a 49   sqlite3_free(zI
49b0: 6e 29 3b 0a 20 20 20 20 7a 49 6e 20 3d 20 30 3b  n);.    zIn = 0;
49c0: 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 69 66  .  }else{.    if
49d0: 28 20 7a 49 6e 20 29 7b 0a 20 20 20 20 20 20 63  ( zIn ){.      c
49e0: 68 61 72 20 2a 7a 54 65 6d 70 20 3d 20 7a 49 6e  har *zTemp = zIn
49f0: 3b 0a 20 20 20 20 20 20 7a 49 6e 20 3d 20 73 71  ;.      zIn = sq
4a00: 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 22 25  lite3_mprintf("%
4a10: 73 25 73 22 2c 20 7a 49 6e 2c 20 7a 41 70 70 65  s%s", zIn, zAppe
4a20: 6e 64 29 3b 0a 20 20 20 20 20 20 73 71 6c 69 74  nd);.      sqlit
4a30: 65 33 5f 66 72 65 65 28 7a 54 65 6d 70 29 3b 0a  e3_free(zTemp);.
4a40: 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20      }else{.     
4a50: 20 7a 49 6e 20 3d 20 73 71 6c 69 74 65 33 5f 6d   zIn = sqlite3_m
4a60: 70 72 69 6e 74 66 28 22 25 73 22 2c 20 7a 41 70  printf("%s", zAp
4a70: 70 65 6e 64 29 3b 0a 20 20 20 20 7d 0a 20 20 20  pend);.    }.   
4a80: 20 69 66 28 20 21 7a 49 6e 20 29 7b 0a 20 20 20   if( !zIn ){.   
4a90: 20 20 20 2a 70 52 63 20 3d 20 53 51 4c 49 54 45     *pRc = SQLITE
4aa0: 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 7d 0a 20 20  _NOMEM;.    }.  
4ab0: 7d 0a 20 20 2a 70 7a 53 74 72 20 3d 20 7a 49 6e  }.  *pzStr = zIn
4ac0: 3b 0a 20 20 69 66 28 20 64 6f 46 72 65 65 20 29  ;.  if( doFree )
4ad0: 7b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72  {.    sqlite3_fr
4ae0: 65 65 28 7a 41 70 70 65 6e 64 29 3b 0a 20 20 7d  ee(zAppend);.  }
4af0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 65 20 65 63  .}../*.** The ec
4b00: 68 6f 20 6d 6f 64 75 6c 65 20 69 6d 70 6c 65 6d  ho module implem
4b10: 65 6e 74 73 20 74 68 65 20 73 75 62 73 65 74 20  ents the subset 
4b20: 6f 66 20 71 75 65 72 79 20 63 6f 6e 73 74 72 61  of query constra
4b30: 69 6e 74 73 20 61 6e 64 20 73 6f 72 74 0a 2a 2a  ints and sort.**
4b40: 20 6f 72 64 65 72 73 20 74 68 61 74 20 6d 61 79   orders that may
4b50: 20 74 61 6b 65 20 61 64 76 61 6e 74 61 67 65 20   take advantage 
4b60: 6f 66 20 53 51 4c 69 74 65 20 69 6e 64 69 63 65  of SQLite indice
4b70: 73 20 6f 6e 20 74 68 65 20 75 6e 64 65 72 6c 79  s on the underly
4b80: 69 6e 67 0a 2a 2a 20 72 65 61 6c 20 74 61 62 6c  ing.** real tabl
4b90: 65 2e 20 46 6f 72 20 65 78 61 6d 70 6c 65 2c 20  e. For example, 
4ba0: 69 66 20 74 68 65 20 72 65 61 6c 20 74 61 62 6c  if the real tabl
4bb0: 65 20 69 73 20 64 65 63 6c 61 72 65 64 20 61 73  e is declared as
4bc0: 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20 43 52 45 41  :.**.**     CREA
4bd0: 54 45 20 54 41 42 4c 45 20 72 65 61 6c 28 61 2c  TE TABLE real(a,
4be0: 20 62 2c 20 63 29 3b 0a 2a 2a 20 20 20 20 20 43   b, c);.**     C
4bf0: 52 45 41 54 45 20 49 4e 44 45 58 20 72 65 61 6c  REATE INDEX real
4c00: 5f 69 6e 64 65 78 20 4f 4e 20 72 65 61 6c 28 62  _index ON real(b
4c10: 29 3b 0a 2a 2a 0a 2a 2a 20 74 68 65 6e 20 74 68  );.**.** then th
4c20: 65 20 65 63 68 6f 20 6d 6f 64 75 6c 65 20 68 61  e echo module ha
4c30: 6e 64 6c 65 73 20 57 48 45 52 45 20 6f 72 20 4f  ndles WHERE or O
4c40: 52 44 45 52 20 42 59 20 63 6c 61 75 73 65 73 20  RDER BY clauses 
4c50: 74 68 61 74 20 72 65 66 65 72 0a 2a 2a 20 74 6f  that refer.** to
4c60: 20 74 68 65 20 63 6f 6c 75 6d 6e 20 22 62 22 2c   the column "b",
4c70: 20 62 75 74 20 6e 6f 74 20 22 61 22 20 6f 72 20   but not "a" or 
4c80: 22 63 22 2e 20 49 66 20 61 20 6d 75 6c 74 69 2d  "c". If a multi-
4c90: 63 6f 6c 75 6d 6e 20 69 6e 64 65 78 20 69 73 0a  column index is.
4ca0: 2a 2a 20 70 72 65 73 65 6e 74 2c 20 6f 6e 6c 79  ** present, only
4cb0: 20 69 74 73 20 6c 65 66 74 20 6d 6f 73 74 20 63   its left most c
4cc0: 6f 6c 75 6d 6e 20 69 73 20 63 6f 6e 73 69 64 65  olumn is conside
4cd0: 72 65 64 2e 20 0a 2a 2a 0a 2a 2a 20 54 68 69 73  red. .**.** This
4ce0: 20 78 42 65 73 74 49 6e 64 65 78 20 6d 65 74 68   xBestIndex meth
4cf0: 6f 64 20 65 6e 63 6f 64 65 73 20 74 68 65 20 70  od encodes the p
4d00: 72 6f 70 6f 73 65 64 20 73 65 61 72 63 68 20 73  roposed search s
4d10: 74 72 61 74 65 67 79 20 61 73 0a 2a 2a 20 61 6e  trategy as.** an
4d20: 20 53 51 4c 20 71 75 65 72 79 20 6f 6e 20 74 68   SQL query on th
4d30: 65 20 72 65 61 6c 20 74 61 62 6c 65 20 75 6e 64  e real table und
4d40: 65 72 6c 79 69 6e 67 20 74 68 65 20 76 69 72 74  erlying the virt
4d50: 75 61 6c 20 65 63 68 6f 20 6d 6f 64 75 6c 65 20  ual echo module 
4d60: 0a 2a 2a 20 74 61 62 6c 65 20 61 6e 64 20 73 74  .** table and st
4d70: 6f 72 65 73 20 74 68 65 20 71 75 65 72 79 20 69  ores the query i
4d80: 6e 20 73 71 6c 69 74 65 33 5f 69 6e 64 65 78 5f  n sqlite3_index_
4d90: 69 6e 66 6f 2e 69 64 78 53 74 72 2e 20 54 68 65  info.idxStr. The
4da0: 20 53 51 4c 0a 2a 2a 20 73 74 61 74 65 6d 65 6e   SQL.** statemen
4db0: 74 20 69 73 20 6f 66 20 74 68 65 20 66 6f 72 6d  t is of the form
4dc0: 3a 0a 2a 2a 0a 2a 2a 20 20 20 53 45 4c 45 43 54  :.**.**   SELECT
4dd0: 20 72 6f 77 69 64 2c 20 2a 20 46 52 4f 4d 20 3c   rowid, * FROM <
4de0: 72 65 61 6c 2d 74 61 62 6c 65 3e 20 3f 3c 77 68  real-table> ?<wh
4df0: 65 72 65 2d 63 6c 61 75 73 65 3e 3f 20 3f 3c 6f  ere-clause>? ?<o
4e00: 72 64 65 72 2d 62 79 2d 63 6c 61 75 73 65 3e 3f  rder-by-clause>?
4e10: 0a 2a 2a 0a 2a 2a 20 77 68 65 72 65 20 74 68 65  .**.** where the
4e20: 20 3c 77 68 65 72 65 2d 63 6c 61 75 73 65 3e 20   <where-clause> 
4e30: 61 6e 64 20 3c 6f 72 64 65 72 2d 62 79 2d 63 6c  and <order-by-cl
4e40: 61 75 73 65 3e 20 61 72 65 20 64 65 74 65 72 6d  ause> are determ
4e50: 69 6e 65 64 0a 2a 2a 20 62 79 20 74 68 65 20 63  ined.** by the c
4e60: 6f 6e 74 65 6e 74 73 20 6f 66 20 74 68 65 20 73  ontents of the s
4e70: 74 72 75 63 74 75 72 65 20 70 6f 69 6e 74 65 64  tructure pointed
4e80: 20 74 6f 20 62 79 20 74 68 65 20 70 49 64 78 49   to by the pIdxI
4e90: 6e 66 6f 20 61 72 67 75 6d 65 6e 74 2e 0a 2a 2f  nfo argument..*/
4ea0: 0a 73 74 61 74 69 63 20 69 6e 74 20 65 63 68 6f  .static int echo
4eb0: 42 65 73 74 49 6e 64 65 78 28 73 71 6c 69 74 65  BestIndex(sqlite
4ec0: 33 5f 76 74 61 62 20 2a 74 61 62 2c 20 73 71 6c  3_vtab *tab, sql
4ed0: 69 74 65 33 5f 69 6e 64 65 78 5f 69 6e 66 6f 20  ite3_index_info 
4ee0: 2a 70 49 64 78 49 6e 66 6f 29 7b 0a 20 20 69 6e  *pIdxInfo){.  in
4ef0: 74 20 69 69 3b 0a 20 20 63 68 61 72 20 2a 7a 51  t ii;.  char *zQ
4f00: 75 65 72 79 20 3d 20 30 3b 0a 20 20 63 68 61 72  uery = 0;.  char
4f10: 20 2a 7a 4e 65 77 3b 0a 20 20 69 6e 74 20 6e 41   *zNew;.  int nA
4f20: 72 67 20 3d 20 30 3b 0a 20 20 63 6f 6e 73 74 20  rg = 0;.  const 
4f30: 63 68 61 72 20 2a 7a 53 65 70 20 3d 20 22 57 48  char *zSep = "WH
4f40: 45 52 45 22 3b 0a 20 20 65 63 68 6f 5f 76 74 61  ERE";.  echo_vta
4f50: 62 20 2a 70 56 74 61 62 20 3d 20 28 65 63 68 6f  b *pVtab = (echo
4f60: 5f 76 74 61 62 20 2a 29 74 61 62 3b 0a 20 20 73  _vtab *)tab;.  s
4f70: 71 6c 69 74 65 33 5f 73 74 6d 74 20 2a 70 53 74  qlite3_stmt *pSt
4f80: 6d 74 20 3d 20 30 3b 0a 20 20 54 63 6c 5f 49 6e  mt = 0;.  Tcl_In
4f90: 74 65 72 70 20 2a 69 6e 74 65 72 70 20 3d 20 70  terp *interp = p
4fa0: 56 74 61 62 2d 3e 69 6e 74 65 72 70 3b 0a 0a 20  Vtab->interp;.. 
4fb0: 20 69 6e 74 20 6e 52 6f 77 3b 0a 20 20 69 6e 74   int nRow;.  int
4fc0: 20 75 73 65 49 64 78 20 3d 20 30 3b 0a 20 20 69   useIdx = 0;.  i
4fd0: 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f  nt rc = SQLITE_O
4fe0: 4b 3b 0a 20 20 69 6e 74 20 75 73 65 43 6f 73 74  K;.  int useCost
4ff0: 20 3d 20 30 3b 0a 20 20 64 6f 75 62 6c 65 20 63   = 0;.  double c
5000: 6f 73 74 3b 0a 0a 20 20 69 6e 74 20 69 73 49 67  ost;..  int isIg
5010: 6e 6f 72 65 55 73 61 62 6c 65 20 3d 20 30 3b 0a  noreUsable = 0;.
5020: 20 20 69 66 28 20 54 63 6c 5f 47 65 74 56 61 72    if( Tcl_GetVar
5030: 28 69 6e 74 65 72 70 2c 20 22 65 63 68 6f 5f 6d  (interp, "echo_m
5040: 6f 64 75 6c 65 5f 69 67 6e 6f 72 65 5f 75 73 61  odule_ignore_usa
5050: 62 6c 65 22 2c 20 54 43 4c 5f 47 4c 4f 42 41 4c  ble", TCL_GLOBAL
5060: 5f 4f 4e 4c 59 29 20 29 7b 0a 20 20 20 20 69 73  _ONLY) ){.    is
5070: 49 67 6e 6f 72 65 55 73 61 62 6c 65 20 3d 20 31  IgnoreUsable = 1
5080: 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 44 65 74 65  ;.  }..  /* Dete
5090: 72 6d 69 6e 65 20 74 68 65 20 6e 75 6d 62 65 72  rmine the number
50a0: 20 6f 66 20 72 6f 77 73 20 69 6e 20 74 68 65 20   of rows in the 
50b0: 74 61 62 6c 65 20 61 6e 64 20 73 74 6f 72 65 20  table and store 
50c0: 74 68 69 73 20 76 61 6c 75 65 20 69 6e 20 6c 6f  this value in lo
50d0: 63 61 6c 0a 20 20 2a 2a 20 76 61 72 69 61 62 6c  cal.  ** variabl
50e0: 65 20 6e 52 6f 77 2e 20 54 68 65 20 27 65 73 74  e nRow. The 'est
50f0: 69 6d 61 74 65 64 2d 63 6f 73 74 27 20 6f 66 20  imated-cost' of 
5100: 74 68 65 20 73 63 61 6e 20 77 69 6c 6c 20 62 65  the scan will be
5110: 20 74 68 65 20 6e 75 6d 62 65 72 20 6f 66 0a 20   the number of. 
5120: 20 2a 2a 20 72 6f 77 73 20 69 6e 20 74 68 65 20   ** rows in the 
5130: 74 61 62 6c 65 20 66 6f 72 20 61 20 6c 69 6e 65  table for a line
5140: 61 72 20 73 63 61 6e 2c 20 6f 72 20 74 68 65 20  ar scan, or the 
5150: 6c 6f 67 20 28 62 61 73 65 20 32 29 20 6f 66 20  log (base 2) of 
5160: 74 68 65 20 0a 20 20 2a 2a 20 6e 75 6d 62 65 72  the .  ** number
5170: 20 6f 66 20 72 6f 77 73 20 69 66 20 74 68 65 20   of rows if the 
5180: 70 72 6f 70 6f 73 65 64 20 73 63 61 6e 20 75 73  proposed scan us
5190: 65 73 20 61 6e 20 69 6e 64 65 78 2e 20 20 0a 20  es an index.  . 
51a0: 20 2a 2f 0a 20 20 69 66 28 20 54 63 6c 5f 47 65   */.  if( Tcl_Ge
51b0: 74 56 61 72 28 69 6e 74 65 72 70 2c 20 22 65 63  tVar(interp, "ec
51c0: 68 6f 5f 6d 6f 64 75 6c 65 5f 63 6f 73 74 22 2c  ho_module_cost",
51d0: 20 54 43 4c 5f 47 4c 4f 42 41 4c 5f 4f 4e 4c 59   TCL_GLOBAL_ONLY
51e0: 29 20 29 7b 0a 20 20 20 20 63 6f 73 74 20 3d 20  ) ){.    cost = 
51f0: 61 74 6f 66 28 54 63 6c 5f 47 65 74 56 61 72 28  atof(Tcl_GetVar(
5200: 69 6e 74 65 72 70 2c 20 22 65 63 68 6f 5f 6d 6f  interp, "echo_mo
5210: 64 75 6c 65 5f 63 6f 73 74 22 2c 20 54 43 4c 5f  dule_cost", TCL_
5220: 47 4c 4f 42 41 4c 5f 4f 4e 4c 59 29 29 3b 0a 20  GLOBAL_ONLY));. 
5230: 20 20 20 75 73 65 43 6f 73 74 20 3d 20 31 3b 0a     useCost = 1;.
5240: 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20 7a    } else {.    z
5250: 51 75 65 72 79 20 3d 20 73 71 6c 69 74 65 33 5f  Query = sqlite3_
5260: 6d 70 72 69 6e 74 66 28 22 53 45 4c 45 43 54 20  mprintf("SELECT 
5270: 63 6f 75 6e 74 28 2a 29 20 46 52 4f 4d 20 25 51  count(*) FROM %Q
5280: 22 2c 20 70 56 74 61 62 2d 3e 7a 54 61 62 6c 65  ", pVtab->zTable
5290: 4e 61 6d 65 29 3b 0a 20 20 20 20 69 66 28 20 21  Name);.    if( !
52a0: 7a 51 75 65 72 79 20 29 7b 0a 20 20 20 20 20 20  zQuery ){.      
52b0: 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f  return SQLITE_NO
52c0: 4d 45 4d 3b 0a 20 20 20 20 7d 0a 20 20 20 20 72  MEM;.    }.    r
52d0: 63 20 3d 20 73 71 6c 69 74 65 33 5f 70 72 65 70  c = sqlite3_prep
52e0: 61 72 65 28 70 56 74 61 62 2d 3e 64 62 2c 20 7a  are(pVtab->db, z
52f0: 51 75 65 72 79 2c 20 2d 31 2c 20 26 70 53 74 6d  Query, -1, &pStm
5300: 74 2c 20 30 29 3b 0a 20 20 20 20 73 71 6c 69 74  t, 0);.    sqlit
5310: 65 33 5f 66 72 65 65 28 7a 51 75 65 72 79 29 3b  e3_free(zQuery);
5320: 0a 20 20 20 20 69 66 28 20 72 63 21 3d 53 51 4c  .    if( rc!=SQL
5330: 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20  ITE_OK ){.      
5340: 72 65 74 75 72 6e 20 72 63 3b 0a 20 20 20 20 7d  return rc;.    }
5350: 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 73 74 65  .    sqlite3_ste
5360: 70 28 70 53 74 6d 74 29 3b 0a 20 20 20 20 6e 52  p(pStmt);.    nR
5370: 6f 77 20 3d 20 73 71 6c 69 74 65 33 5f 63 6f 6c  ow = sqlite3_col
5380: 75 6d 6e 5f 69 6e 74 28 70 53 74 6d 74 2c 20 30  umn_int(pStmt, 0
5390: 29 3b 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69  );.    rc = sqli
53a0: 74 65 33 5f 66 69 6e 61 6c 69 7a 65 28 70 53 74  te3_finalize(pSt
53b0: 6d 74 29 3b 0a 20 20 20 20 69 66 28 20 72 63 21  mt);.    if( rc!
53c0: 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20  =SQLITE_OK ){.  
53d0: 20 20 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 20      return rc;. 
53e0: 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 7a 51 75 65     }.  }..  zQue
53f0: 72 79 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72  ry = sqlite3_mpr
5400: 69 6e 74 66 28 22 53 45 4c 45 43 54 20 72 6f 77  intf("SELECT row
5410: 69 64 2c 20 2a 20 46 52 4f 4d 20 25 51 22 2c 20  id, * FROM %Q", 
5420: 70 56 74 61 62 2d 3e 7a 54 61 62 6c 65 4e 61 6d  pVtab->zTableNam
5430: 65 29 3b 0a 20 20 69 66 28 20 21 7a 51 75 65 72  e);.  if( !zQuer
5440: 79 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20  y ){.    return 
5450: 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20  SQLITE_NOMEM;.  
5460: 7d 0a 20 20 66 6f 72 28 69 69 3d 30 3b 20 69 69  }.  for(ii=0; ii
5470: 3c 70 49 64 78 49 6e 66 6f 2d 3e 6e 43 6f 6e 73  <pIdxInfo->nCons
5480: 74 72 61 69 6e 74 3b 20 69 69 2b 2b 29 7b 0a 20  traint; ii++){. 
5490: 20 20 20 63 6f 6e 73 74 20 73 74 72 75 63 74 20     const struct 
54a0: 73 71 6c 69 74 65 33 5f 69 6e 64 65 78 5f 63 6f  sqlite3_index_co
54b0: 6e 73 74 72 61 69 6e 74 20 2a 70 43 6f 6e 73 74  nstraint *pConst
54c0: 72 61 69 6e 74 3b 0a 20 20 20 20 73 74 72 75 63  raint;.    struc
54d0: 74 20 73 71 6c 69 74 65 33 5f 69 6e 64 65 78 5f  t sqlite3_index_
54e0: 63 6f 6e 73 74 72 61 69 6e 74 5f 75 73 61 67 65  constraint_usage
54f0: 20 2a 70 55 73 61 67 65 3b 0a 20 20 20 20 69 6e   *pUsage;.    in
5500: 74 20 69 43 6f 6c 3b 0a 0a 20 20 20 20 70 43 6f  t iCol;..    pCo
5510: 6e 73 74 72 61 69 6e 74 20 3d 20 26 70 49 64 78  nstraint = &pIdx
5520: 49 6e 66 6f 2d 3e 61 43 6f 6e 73 74 72 61 69 6e  Info->aConstrain
5530: 74 5b 69 69 5d 3b 0a 20 20 20 20 70 55 73 61 67  t[ii];.    pUsag
5540: 65 20 3d 20 26 70 49 64 78 49 6e 66 6f 2d 3e 61  e = &pIdxInfo->a
5550: 43 6f 6e 73 74 72 61 69 6e 74 55 73 61 67 65 5b  ConstraintUsage[
5560: 69 69 5d 3b 0a 0a 20 20 20 20 69 66 28 20 21 69  ii];..    if( !i
5570: 73 49 67 6e 6f 72 65 55 73 61 62 6c 65 20 26 26  sIgnoreUsable &&
5580: 20 21 70 43 6f 6e 73 74 72 61 69 6e 74 2d 3e 75   !pConstraint->u
5590: 73 61 62 6c 65 20 29 20 63 6f 6e 74 69 6e 75 65  sable ) continue
55a0: 3b 0a 0a 20 20 20 20 69 43 6f 6c 20 3d 20 70 43  ;..    iCol = pC
55b0: 6f 6e 73 74 72 61 69 6e 74 2d 3e 69 43 6f 6c 75  onstraint->iColu
55c0: 6d 6e 3b 0a 20 20 20 20 69 66 28 20 70 56 74 61  mn;.    if( pVta
55d0: 62 2d 3e 61 49 6e 64 65 78 5b 69 43 6f 6c 5d 20  b->aIndex[iCol] 
55e0: 7c 7c 20 69 43 6f 6c 3c 30 20 29 7b 0a 20 20 20  || iCol<0 ){.   
55f0: 20 20 20 63 68 61 72 20 2a 7a 43 6f 6c 20 3d 20     char *zCol = 
5600: 70 56 74 61 62 2d 3e 61 43 6f 6c 5b 69 43 6f 6c  pVtab->aCol[iCol
5610: 5d 3b 0a 20 20 20 20 20 20 63 68 61 72 20 2a 7a  ];.      char *z
5620: 4f 70 20 3d 20 30 3b 0a 20 20 20 20 20 20 75 73  Op = 0;.      us
5630: 65 49 64 78 20 3d 20 31 3b 0a 20 20 20 20 20 20  eIdx = 1;.      
5640: 69 66 28 20 69 43 6f 6c 3c 30 20 29 7b 0a 20 20  if( iCol<0 ){.  
5650: 20 20 20 20 20 20 7a 43 6f 6c 20 3d 20 22 72 6f        zCol = "ro
5660: 77 69 64 22 3b 0a 20 20 20 20 20 20 7d 0a 20 20  wid";.      }.  
5670: 20 20 20 20 73 77 69 74 63 68 28 20 70 43 6f 6e      switch( pCon
5680: 73 74 72 61 69 6e 74 2d 3e 6f 70 20 29 7b 0a 20  straint->op ){. 
5690: 20 20 20 20 20 20 20 63 61 73 65 20 53 51 4c 49         case SQLI
56a0: 54 45 5f 49 4e 44 45 58 5f 43 4f 4e 53 54 52 41  TE_INDEX_CONSTRA
56b0: 49 4e 54 5f 45 51 3a 0a 20 20 20 20 20 20 20 20  INT_EQ:.        
56c0: 20 20 7a 4f 70 20 3d 20 22 3d 22 3b 20 62 72 65    zOp = "="; bre
56d0: 61 6b 3b 0a 20 20 20 20 20 20 20 20 63 61 73 65  ak;.        case
56e0: 20 53 51 4c 49 54 45 5f 49 4e 44 45 58 5f 43 4f   SQLITE_INDEX_CO
56f0: 4e 53 54 52 41 49 4e 54 5f 4c 54 3a 0a 20 20 20  NSTRAINT_LT:.   
5700: 20 20 20 20 20 20 20 7a 4f 70 20 3d 20 22 3c 22         zOp = "<"
5710: 3b 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 20  ; break;.       
5720: 20 63 61 73 65 20 53 51 4c 49 54 45 5f 49 4e 44   case SQLITE_IND
5730: 45 58 5f 43 4f 4e 53 54 52 41 49 4e 54 5f 47 54  EX_CONSTRAINT_GT
5740: 3a 0a 20 20 20 20 20 20 20 20 20 20 7a 4f 70 20  :.          zOp 
5750: 3d 20 22 3e 22 3b 20 62 72 65 61 6b 3b 0a 20 20  = ">"; break;.  
5760: 20 20 20 20 20 20 63 61 73 65 20 53 51 4c 49 54        case SQLIT
5770: 45 5f 49 4e 44 45 58 5f 43 4f 4e 53 54 52 41 49  E_INDEX_CONSTRAI
5780: 4e 54 5f 4c 45 3a 0a 20 20 20 20 20 20 20 20 20  NT_LE:.         
5790: 20 7a 4f 70 20 3d 20 22 3c 3d 22 3b 20 62 72 65   zOp = "<="; bre
57a0: 61 6b 3b 0a 20 20 20 20 20 20 20 20 63 61 73 65  ak;.        case
57b0: 20 53 51 4c 49 54 45 5f 49 4e 44 45 58 5f 43 4f   SQLITE_INDEX_CO
57c0: 4e 53 54 52 41 49 4e 54 5f 47 45 3a 0a 20 20 20  NSTRAINT_GE:.   
57d0: 20 20 20 20 20 20 20 7a 4f 70 20 3d 20 22 3e 3d         zOp = ">=
57e0: 22 3b 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20  "; break;.      
57f0: 20 20 63 61 73 65 20 53 51 4c 49 54 45 5f 49 4e    case SQLITE_IN
5800: 44 45 58 5f 43 4f 4e 53 54 52 41 49 4e 54 5f 4d  DEX_CONSTRAINT_M
5810: 41 54 43 48 3a 0a 20 20 20 20 20 20 20 20 20 20  ATCH:.          
5820: 7a 4f 70 20 3d 20 22 4c 49 4b 45 22 3b 20 62 72  zOp = "LIKE"; br
5830: 65 61 6b 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20  eak;.      }.   
5840: 20 20 20 69 66 28 20 7a 4f 70 5b 30 5d 3d 3d 27     if( zOp[0]=='
5850: 4c 27 20 29 7b 0a 20 20 20 20 20 20 20 20 7a 4e  L' ){.        zN
5860: 65 77 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72  ew = sqlite3_mpr
5870: 69 6e 74 66 28 22 20 25 73 20 25 73 20 4c 49 4b  intf(" %s %s LIK
5880: 45 20 28 53 45 4c 45 43 54 20 27 25 25 27 7c 7c  E (SELECT '%%'||
5890: 3f 7c 7c 27 25 25 27 29 22 2c 20 0a 20 20 20 20  ?||'%%')", .    
58a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
58b0: 20 20 20 20 20 20 20 20 20 20 20 7a 53 65 70 2c             zSep,
58c0: 20 7a 43 6f 6c 29 3b 0a 20 20 20 20 20 20 7d 20   zCol);.      } 
58d0: 65 6c 73 65 20 7b 0a 20 20 20 20 20 20 20 20 7a  else {.        z
58e0: 4e 65 77 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70  New = sqlite3_mp
58f0: 72 69 6e 74 66 28 22 20 25 73 20 25 73 20 25 73  rintf(" %s %s %s
5900: 20 3f 22 2c 20 7a 53 65 70 2c 20 7a 43 6f 6c 2c   ?", zSep, zCol,
5910: 20 7a 4f 70 29 3b 0a 20 20 20 20 20 20 7d 0a 20   zOp);.      }. 
5920: 20 20 20 20 20 73 74 72 69 6e 67 5f 63 6f 6e 63       string_conc
5930: 61 74 28 26 7a 51 75 65 72 79 2c 20 7a 4e 65 77  at(&zQuery, zNew
5940: 2c 20 31 2c 20 26 72 63 29 3b 0a 0a 20 20 20 20  , 1, &rc);..    
5950: 20 20 7a 53 65 70 20 3d 20 22 41 4e 44 22 3b 0a    zSep = "AND";.
5960: 20 20 20 20 20 20 70 55 73 61 67 65 2d 3e 61 72        pUsage->ar
5970: 67 76 49 6e 64 65 78 20 3d 20 2b 2b 6e 41 72 67  gvIndex = ++nArg
5980: 3b 0a 20 20 20 20 20 20 70 55 73 61 67 65 2d 3e  ;.      pUsage->
5990: 6f 6d 69 74 20 3d 20 31 3b 0a 20 20 20 20 7d 0a  omit = 1;.    }.
59a0: 20 20 7d 0a 0a 20 20 2f 2a 20 49 66 20 74 68 65    }..  /* If the
59b0: 72 65 20 69 73 20 6f 6e 6c 79 20 6f 6e 65 20 74  re is only one t
59c0: 65 72 6d 20 69 6e 20 74 68 65 20 4f 52 44 45 52  erm in the ORDER
59d0: 20 42 59 20 63 6c 61 75 73 65 2c 20 61 6e 64 20   BY clause, and 
59e0: 69 74 20 69 73 0a 20 20 2a 2a 20 6f 6e 20 61 20  it is.  ** on a 
59f0: 63 6f 6c 75 6d 6e 20 74 68 61 74 20 74 68 69 73  column that this
5a00: 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65 20 68   virtual table h
5a10: 61 73 20 61 6e 20 69 6e 64 65 78 20 66 6f 72 2c  as an index for,
5a20: 20 74 68 65 6e 20 63 6f 6e 73 75 6d 65 20 0a 20   then consume . 
5a30: 20 2a 2a 20 74 68 65 20 4f 52 44 45 52 20 42 59   ** the ORDER BY
5a40: 20 63 6c 61 75 73 65 2e 0a 20 20 2a 2f 0a 20 20   clause..  */.  
5a50: 69 66 28 20 70 49 64 78 49 6e 66 6f 2d 3e 6e 4f  if( pIdxInfo->nO
5a60: 72 64 65 72 42 79 3d 3d 31 20 26 26 20 70 56 74  rderBy==1 && pVt
5a70: 61 62 2d 3e 61 49 6e 64 65 78 5b 70 49 64 78 49  ab->aIndex[pIdxI
5a80: 6e 66 6f 2d 3e 61 4f 72 64 65 72 42 79 2d 3e 69  nfo->aOrderBy->i
5a90: 43 6f 6c 75 6d 6e 5d 20 29 7b 0a 20 20 20 20 69  Column] ){.    i
5aa0: 6e 74 20 69 43 6f 6c 20 3d 20 70 49 64 78 49 6e  nt iCol = pIdxIn
5ab0: 66 6f 2d 3e 61 4f 72 64 65 72 42 79 2d 3e 69 43  fo->aOrderBy->iC
5ac0: 6f 6c 75 6d 6e 3b 0a 20 20 20 20 63 68 61 72 20  olumn;.    char 
5ad0: 2a 7a 43 6f 6c 20 3d 20 70 56 74 61 62 2d 3e 61  *zCol = pVtab->a
5ae0: 43 6f 6c 5b 69 43 6f 6c 5d 3b 0a 20 20 20 20 63  Col[iCol];.    c
5af0: 68 61 72 20 2a 7a 44 69 72 20 3d 20 70 49 64 78  har *zDir = pIdx
5b00: 49 6e 66 6f 2d 3e 61 4f 72 64 65 72 42 79 2d 3e  Info->aOrderBy->
5b10: 64 65 73 63 3f 22 44 45 53 43 22 3a 22 41 53 43  desc?"DESC":"ASC
5b20: 22 3b 0a 20 20 20 20 69 66 28 20 69 43 6f 6c 3c  ";.    if( iCol<
5b30: 30 20 29 7b 0a 20 20 20 20 20 20 7a 43 6f 6c 20  0 ){.      zCol 
5b40: 3d 20 22 72 6f 77 69 64 22 3b 0a 20 20 20 20 7d  = "rowid";.    }
5b50: 0a 20 20 20 20 7a 4e 65 77 20 3d 20 73 71 6c 69  .    zNew = sqli
5b60: 74 65 33 5f 6d 70 72 69 6e 74 66 28 22 20 4f 52  te3_mprintf(" OR
5b70: 44 45 52 20 42 59 20 25 73 20 25 73 22 2c 20 7a  DER BY %s %s", z
5b80: 43 6f 6c 2c 20 7a 44 69 72 29 3b 0a 20 20 20 20  Col, zDir);.    
5b90: 73 74 72 69 6e 67 5f 63 6f 6e 63 61 74 28 26 7a  string_concat(&z
5ba0: 51 75 65 72 79 2c 20 7a 4e 65 77 2c 20 31 2c 20  Query, zNew, 1, 
5bb0: 26 72 63 29 3b 0a 20 20 20 20 70 49 64 78 49 6e  &rc);.    pIdxIn
5bc0: 66 6f 2d 3e 6f 72 64 65 72 42 79 43 6f 6e 73 75  fo->orderByConsu
5bd0: 6d 65 64 20 3d 20 31 3b 0a 20 20 7d 0a 0a 20 20  med = 1;.  }..  
5be0: 61 70 70 65 6e 64 54 6f 45 63 68 6f 4d 6f 64 75  appendToEchoModu
5bf0: 6c 65 28 70 56 74 61 62 2d 3e 69 6e 74 65 72 70  le(pVtab->interp
5c00: 2c 20 22 78 42 65 73 74 49 6e 64 65 78 22 29 3b  , "xBestIndex");
5c10: 3b 0a 20 20 61 70 70 65 6e 64 54 6f 45 63 68 6f  ;.  appendToEcho
5c20: 4d 6f 64 75 6c 65 28 70 56 74 61 62 2d 3e 69 6e  Module(pVtab->in
5c30: 74 65 72 70 2c 20 7a 51 75 65 72 79 29 3b 0a 0a  terp, zQuery);..
5c40: 20 20 69 66 28 20 21 7a 51 75 65 72 79 20 29 7b    if( !zQuery ){
5c50: 0a 20 20 20 20 72 65 74 75 72 6e 20 72 63 3b 0a  .    return rc;.
5c60: 20 20 7d 0a 20 20 70 49 64 78 49 6e 66 6f 2d 3e    }.  pIdxInfo->
5c70: 69 64 78 4e 75 6d 20 3d 20 68 61 73 68 53 74 72  idxNum = hashStr
5c80: 69 6e 67 28 7a 51 75 65 72 79 29 3b 0a 20 20 70  ing(zQuery);.  p
5c90: 49 64 78 49 6e 66 6f 2d 3e 69 64 78 53 74 72 20  IdxInfo->idxStr 
5ca0: 3d 20 7a 51 75 65 72 79 3b 0a 20 20 70 49 64 78  = zQuery;.  pIdx
5cb0: 49 6e 66 6f 2d 3e 6e 65 65 64 54 6f 46 72 65 65  Info->needToFree
5cc0: 49 64 78 53 74 72 20 3d 20 31 3b 0a 20 20 69 66  IdxStr = 1;.  if
5cd0: 20 28 75 73 65 43 6f 73 74 29 20 7b 0a 20 20 20   (useCost) {.   
5ce0: 20 70 49 64 78 49 6e 66 6f 2d 3e 65 73 74 69 6d   pIdxInfo->estim
5cf0: 61 74 65 64 43 6f 73 74 20 3d 20 63 6f 73 74 3b  atedCost = cost;
5d00: 0a 20 20 7d 20 65 6c 73 65 20 69 66 28 20 75 73  .  } else if( us
5d10: 65 49 64 78 20 29 7b 0a 20 20 20 20 2f 2a 20 41  eIdx ){.    /* A
5d20: 70 70 72 6f 78 69 6d 61 74 69 6f 6e 20 6f 66 20  pproximation of 
5d30: 6c 6f 67 32 28 6e 52 6f 77 29 2e 20 2a 2f 0a 20  log2(nRow). */. 
5d40: 20 20 20 66 6f 72 28 20 69 69 3d 30 3b 20 69 69     for( ii=0; ii
5d50: 3c 28 73 69 7a 65 6f 66 28 69 6e 74 29 2a 38 29  <(sizeof(int)*8)
5d60: 3b 20 69 69 2b 2b 20 29 7b 0a 20 20 20 20 20 20  ; ii++ ){.      
5d70: 69 66 28 20 6e 52 6f 77 20 26 20 28 31 3c 3c 69  if( nRow & (1<<i
5d80: 69 29 20 29 7b 0a 20 20 20 20 20 20 20 20 70 49  i) ){.        pI
5d90: 64 78 49 6e 66 6f 2d 3e 65 73 74 69 6d 61 74 65  dxInfo->estimate
5da0: 64 43 6f 73 74 20 3d 20 28 64 6f 75 62 6c 65 29  dCost = (double)
5db0: 69 69 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20  ii;.      }.    
5dc0: 7d 0a 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20  }.  } else {.   
5dd0: 20 70 49 64 78 49 6e 66 6f 2d 3e 65 73 74 69 6d   pIdxInfo->estim
5de0: 61 74 65 64 43 6f 73 74 20 3d 20 28 64 6f 75 62  atedCost = (doub
5df0: 6c 65 29 6e 52 6f 77 3b 0a 20 20 7d 0a 20 20 72  le)nRow;.  }.  r
5e00: 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a  eturn rc;.}../*.
5e10: 2a 2a 20 54 68 65 20 78 55 70 64 61 74 65 20 6d  ** The xUpdate m
5e20: 65 74 68 6f 64 20 66 6f 72 20 65 63 68 6f 20 6d  ethod for echo m
5e30: 6f 64 75 6c 65 20 76 69 72 74 75 61 6c 20 74 61  odule virtual ta
5e40: 62 6c 65 73 2e 0a 2a 2a 20 0a 2a 2a 20 20 20 20  bles..** .**    
5e50: 61 70 44 61 74 61 5b 30 5d 20 20 61 70 44 61 74  apData[0]  apDat
5e60: 61 5b 31 5d 20 20 61 70 44 61 74 61 5b 32 2e 2e  a[1]  apData[2..
5e70: 5d 0a 2a 2a 0a 2a 2a 20 20 20 20 49 4e 54 45 47  ].**.**    INTEG
5e80: 45 52 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ER              
5e90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5ea0: 44 45 4c 45 54 45 20 20 20 20 20 20 20 20 20 20  DELETE          
5eb0: 20 20 0a 2a 2a 0a 2a 2a 20 20 20 20 49 4e 54 45    .**.**    INTE
5ec0: 47 45 52 20 20 20 20 4e 55 4c 4c 20 20 20 20 20  GER    NULL     
5ed0: 20 20 28 6e 43 6f 6c 20 61 72 67 73 29 20 20 20    (nCol args)   
5ee0: 20 55 50 44 41 54 45 20 28 64 6f 20 6e 6f 74 20   UPDATE (do not 
5ef0: 73 65 74 20 72 6f 77 69 64 29 0a 2a 2a 20 20 20  set rowid).**   
5f00: 20 49 4e 54 45 47 45 52 20 20 20 20 49 4e 54 45   INTEGER    INTE
5f10: 47 45 52 20 20 20 20 28 6e 43 6f 6c 20 61 72 67  GER    (nCol arg
5f20: 73 29 20 20 20 20 55 50 44 41 54 45 20 28 77 69  s)    UPDATE (wi
5f30: 74 68 20 53 45 54 20 72 6f 77 69 64 20 3d 20 3c  th SET rowid = <
5f40: 61 72 67 31 3e 29 0a 2a 2a 0a 2a 2a 20 20 20 20  arg1>).**.**    
5f50: 4e 55 4c 4c 20 20 20 20 20 20 20 4e 55 4c 4c 20  NULL       NULL 
5f60: 20 20 20 20 20 20 28 6e 43 6f 6c 20 61 72 67 73        (nCol args
5f70: 29 20 20 20 20 49 4e 53 45 52 54 20 49 4e 54 4f  )    INSERT INTO
5f80: 20 28 61 75 74 6f 6d 61 74 69 63 20 72 6f 77 69   (automatic rowi
5f90: 64 20 76 61 6c 75 65 29 0a 2a 2a 20 20 20 20 4e  d value).**    N
5fa0: 55 4c 4c 20 20 20 20 20 20 20 49 4e 54 45 47 45  ULL       INTEGE
5fb0: 52 20 20 20 20 28 6e 43 6f 6c 20 61 72 67 73 29  R    (nCol args)
5fc0: 20 20 20 20 49 4e 53 45 52 54 20 28 69 6e 63 6c      INSERT (incl
5fd0: 2e 20 72 6f 77 69 64 20 76 61 6c 75 65 29 0a 2a  . rowid value).*
5fe0: 2a 0a 2a 2f 0a 69 6e 74 20 65 63 68 6f 55 70 64  *.*/.int echoUpd
5ff0: 61 74 65 28 0a 20 20 73 71 6c 69 74 65 33 5f 76  ate(.  sqlite3_v
6000: 74 61 62 20 2a 74 61 62 2c 20 0a 20 20 69 6e 74  tab *tab, .  int
6010: 20 6e 44 61 74 61 2c 20 0a 20 20 73 71 6c 69 74   nData, .  sqlit
6020: 65 33 5f 76 61 6c 75 65 20 2a 2a 61 70 44 61 74  e3_value **apDat
6030: 61 2c 20 0a 20 20 73 71 6c 69 74 65 5f 69 6e 74  a, .  sqlite_int
6040: 36 34 20 2a 70 52 6f 77 69 64 0a 29 7b 0a 20 20  64 *pRowid.){.  
6050: 65 63 68 6f 5f 76 74 61 62 20 2a 70 56 74 61 62  echo_vtab *pVtab
6060: 20 3d 20 28 65 63 68 6f 5f 76 74 61 62 20 2a 29   = (echo_vtab *)
6070: 74 61 62 3b 0a 20 20 73 71 6c 69 74 65 33 20 2a  tab;.  sqlite3 *
6080: 64 62 20 3d 20 70 56 74 61 62 2d 3e 64 62 3b 0a  db = pVtab->db;.
6090: 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54    int rc = SQLIT
60a0: 45 5f 4f 4b 3b 0a 0a 20 20 73 71 6c 69 74 65 33  E_OK;..  sqlite3
60b0: 5f 73 74 6d 74 20 2a 70 53 74 6d 74 3b 0a 20 20  _stmt *pStmt;.  
60c0: 63 68 61 72 20 2a 7a 20 3d 20 30 3b 20 20 20 20  char *z = 0;    
60d0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 51             /* SQ
60e0: 4c 20 73 74 61 74 65 6d 65 6e 74 20 74 6f 20 65  L statement to e
60f0: 78 65 63 75 74 65 20 2a 2f 0a 20 20 69 6e 74 20  xecute */.  int 
6100: 62 69 6e 64 41 72 67 5a 65 72 6f 20 3d 20 30 3b  bindArgZero = 0;
6110: 20 20 20 20 20 20 20 2f 2a 20 54 72 75 65 20 74         /* True t
6120: 6f 20 62 69 6e 64 20 61 70 44 61 74 61 5b 30 5d  o bind apData[0]
6130: 20 74 6f 20 73 71 6c 20 76 61 72 20 6e 6f 2e 20   to sql var no. 
6140: 6e 44 61 74 61 20 2a 2f 0a 20 20 69 6e 74 20 62  nData */.  int b
6150: 69 6e 64 41 72 67 4f 6e 65 20 3d 20 30 3b 20 20  indArgOne = 0;  
6160: 20 20 20 20 20 20 2f 2a 20 54 72 75 65 20 74 6f        /* True to
6170: 20 62 69 6e 64 20 61 70 44 61 74 61 5b 31 5d 20   bind apData[1] 
6180: 74 6f 20 73 71 6c 20 76 61 72 20 6e 6f 2e 20 31  to sql var no. 1
6190: 20 2a 2f 0a 20 20 69 6e 74 20 69 3b 20 20 20 20   */.  int i;    
61a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
61b0: 20 2f 2a 20 43 6f 75 6e 74 65 72 20 76 61 72 69   /* Counter vari
61c0: 61 62 6c 65 20 75 73 65 64 20 62 79 20 66 6f 72  able used by for
61d0: 20 6c 6f 6f 70 73 20 2a 2f 0a 0a 20 20 61 73 73   loops */..  ass
61e0: 65 72 74 28 20 6e 44 61 74 61 3d 3d 70 56 74 61  ert( nData==pVta
61f0: 62 2d 3e 6e 43 6f 6c 2b 32 20 7c 7c 20 6e 44 61  b->nCol+2 || nDa
6200: 74 61 3d 3d 31 20 29 3b 0a 0a 20 20 2f 2a 20 54  ta==1 );..  /* T
6210: 69 63 6b 65 74 20 23 33 30 38 33 20 2d 20 6d 61  icket #3083 - ma
6220: 6b 65 20 73 75 72 65 20 77 65 20 61 6c 77 61 79  ke sure we alway
6230: 73 20 73 74 61 72 74 20 61 20 74 72 61 6e 73 61  s start a transa
6240: 63 74 69 6f 6e 20 70 72 69 6f 72 20 74 6f 0a 20  ction prior to. 
6250: 20 2a 2a 20 6d 61 6b 69 6e 67 20 61 6e 79 20 63   ** making any c
6260: 68 61 6e 67 65 73 20 74 6f 20 61 20 76 69 72 74  hanges to a virt
6270: 75 61 6c 20 74 61 62 6c 65 20 2a 2f 0a 20 20 61  ual table */.  a
6280: 73 73 65 72 74 28 20 70 56 74 61 62 2d 3e 69 6e  ssert( pVtab->in
6290: 54 72 61 6e 73 61 63 74 69 6f 6e 20 29 3b 0a 0a  Transaction );..
62a0: 20 20 2f 2a 20 49 66 20 61 70 44 61 74 61 5b 30    /* If apData[0
62b0: 5d 20 69 73 20 61 6e 20 69 6e 74 65 67 65 72 20  ] is an integer 
62c0: 61 6e 64 20 6e 44 61 74 61 3e 31 20 74 68 65 6e  and nData>1 then
62d0: 20 64 6f 20 61 6e 20 55 50 44 41 54 45 20 2a 2f   do an UPDATE */
62e0: 0a 20 20 69 66 28 20 6e 44 61 74 61 3e 31 20 26  .  if( nData>1 &
62f0: 26 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f  & sqlite3_value_
6300: 74 79 70 65 28 61 70 44 61 74 61 5b 30 5d 29 3d  type(apData[0])=
6310: 3d 53 51 4c 49 54 45 5f 49 4e 54 45 47 45 52 20  =SQLITE_INTEGER 
6320: 29 7b 0a 20 20 20 20 63 68 61 72 20 2a 7a 53 65  ){.    char *zSe
6330: 70 20 3d 20 22 20 53 45 54 22 3b 0a 20 20 20 20  p = " SET";.    
6340: 7a 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72 69  z = sqlite3_mpri
6350: 6e 74 66 28 22 55 50 44 41 54 45 20 25 51 22 2c  ntf("UPDATE %Q",
6360: 20 70 56 74 61 62 2d 3e 7a 54 61 62 6c 65 4e 61   pVtab->zTableNa
6370: 6d 65 29 3b 0a 20 20 20 20 69 66 28 20 21 7a 20  me);.    if( !z 
6380: 29 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 53 51  ){.      rc = SQ
6390: 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20  LITE_NOMEM;.    
63a0: 7d 0a 0a 20 20 20 20 62 69 6e 64 41 72 67 4f 6e  }..    bindArgOn
63b0: 65 20 3d 20 28 61 70 44 61 74 61 5b 31 5d 20 26  e = (apData[1] &
63c0: 26 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f  & sqlite3_value_
63d0: 74 79 70 65 28 61 70 44 61 74 61 5b 31 5d 29 3d  type(apData[1])=
63e0: 3d 53 51 4c 49 54 45 5f 49 4e 54 45 47 45 52 29  =SQLITE_INTEGER)
63f0: 3b 0a 20 20 20 20 62 69 6e 64 41 72 67 5a 65 72  ;.    bindArgZer
6400: 6f 20 3d 20 31 3b 0a 0a 20 20 20 20 69 66 28 20  o = 1;..    if( 
6410: 62 69 6e 64 41 72 67 4f 6e 65 20 29 7b 0a 20 20  bindArgOne ){.  
6420: 20 20 20 20 20 73 74 72 69 6e 67 5f 63 6f 6e 63       string_conc
6430: 61 74 28 26 7a 2c 20 22 20 53 45 54 20 72 6f 77  at(&z, " SET row
6440: 69 64 3d 3f 31 20 22 2c 20 30 2c 20 26 72 63 29  id=?1 ", 0, &rc)
6450: 3b 0a 20 20 20 20 20 20 20 7a 53 65 70 20 3d 20  ;.       zSep = 
6460: 22 2c 22 3b 0a 20 20 20 20 7d 0a 20 20 20 20 66  ",";.    }.    f
6470: 6f 72 28 69 3d 32 3b 20 69 3c 6e 44 61 74 61 3b  or(i=2; i<nData;
6480: 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20 69 66 28   i++){.      if(
6490: 20 61 70 44 61 74 61 5b 69 5d 3d 3d 30 20 29 20   apData[i]==0 ) 
64a0: 63 6f 6e 74 69 6e 75 65 3b 0a 20 20 20 20 20 20  continue;.      
64b0: 73 74 72 69 6e 67 5f 63 6f 6e 63 61 74 28 26 7a  string_concat(&z
64c0: 2c 20 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74  , sqlite3_mprint
64d0: 66 28 0a 20 20 20 20 20 20 20 20 20 20 22 25 73  f(.          "%s
64e0: 20 25 51 3d 3f 25 64 22 2c 20 7a 53 65 70 2c 20   %Q=?%d", zSep, 
64f0: 70 56 74 61 62 2d 3e 61 43 6f 6c 5b 69 2d 32 5d  pVtab->aCol[i-2]
6500: 2c 20 69 29 2c 20 31 2c 20 26 72 63 29 3b 0a 20  , i), 1, &rc);. 
6510: 20 20 20 20 20 7a 53 65 70 20 3d 20 22 2c 22 3b       zSep = ",";
6520: 0a 20 20 20 20 7d 0a 20 20 20 20 73 74 72 69 6e  .    }.    strin
6530: 67 5f 63 6f 6e 63 61 74 28 26 7a 2c 20 73 71 6c  g_concat(&z, sql
6540: 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 22 20 57  ite3_mprintf(" W
6550: 48 45 52 45 20 72 6f 77 69 64 3d 3f 25 64 22 2c  HERE rowid=?%d",
6560: 20 6e 44 61 74 61 29 2c 20 31 2c 20 26 72 63 29   nData), 1, &rc)
6570: 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 49 66 20 61  ;.  }..  /* If a
6580: 70 44 61 74 61 5b 30 5d 20 69 73 20 61 6e 20 69  pData[0] is an i
6590: 6e 74 65 67 65 72 20 61 6e 64 20 6e 44 61 74 61  nteger and nData
65a0: 3d 3d 31 20 74 68 65 6e 20 64 6f 20 61 20 44 45  ==1 then do a DE
65b0: 4c 45 54 45 20 2a 2f 0a 20 20 65 6c 73 65 20 69  LETE */.  else i
65c0: 66 28 20 6e 44 61 74 61 3d 3d 31 20 26 26 20 73  f( nData==1 && s
65d0: 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 74 79 70  qlite3_value_typ
65e0: 65 28 61 70 44 61 74 61 5b 30 5d 29 3d 3d 53 51  e(apData[0])==SQ
65f0: 4c 49 54 45 5f 49 4e 54 45 47 45 52 20 29 7b 0a  LITE_INTEGER ){.
6600: 20 20 20 20 7a 20 3d 20 73 71 6c 69 74 65 33 5f      z = sqlite3_
6610: 6d 70 72 69 6e 74 66 28 22 44 45 4c 45 54 45 20  mprintf("DELETE 
6620: 46 52 4f 4d 20 25 51 20 57 48 45 52 45 20 72 6f  FROM %Q WHERE ro
6630: 77 69 64 20 3d 20 3f 31 22 2c 20 70 56 74 61 62  wid = ?1", pVtab
6640: 2d 3e 7a 54 61 62 6c 65 4e 61 6d 65 29 3b 0a 20  ->zTableName);. 
6650: 20 20 20 69 66 28 20 21 7a 20 29 7b 0a 20 20 20     if( !z ){.   
6660: 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4e     rc = SQLITE_N
6670: 4f 4d 45 4d 3b 0a 20 20 20 20 7d 0a 20 20 20 20  OMEM;.    }.    
6680: 62 69 6e 64 41 72 67 5a 65 72 6f 20 3d 20 31 3b  bindArgZero = 1;
6690: 0a 20 20 7d 0a 0a 20 20 2f 2a 20 49 66 20 74 68  .  }..  /* If th
66a0: 65 20 66 69 72 73 74 20 61 72 67 75 6d 65 6e 74  e first argument
66b0: 20 69 73 20 4e 55 4c 4c 20 61 6e 64 20 74 68 65   is NULL and the
66c0: 72 65 20 61 72 65 20 6d 6f 72 65 20 74 68 61 6e  re are more than
66d0: 20 74 77 6f 20 61 72 67 73 2c 20 49 4e 53 45 52   two args, INSER
66e0: 54 20 2a 2f 0a 20 20 65 6c 73 65 20 69 66 28 20  T */.  else if( 
66f0: 6e 44 61 74 61 3e 32 20 26 26 20 73 71 6c 69 74  nData>2 && sqlit
6700: 65 33 5f 76 61 6c 75 65 5f 74 79 70 65 28 61 70  e3_value_type(ap
6710: 44 61 74 61 5b 30 5d 29 3d 3d 53 51 4c 49 54 45  Data[0])==SQLITE
6720: 5f 4e 55 4c 4c 20 29 7b 0a 20 20 20 20 69 6e 74  _NULL ){.    int
6730: 20 69 69 3b 0a 20 20 20 20 63 68 61 72 20 2a 7a   ii;.    char *z
6740: 49 6e 73 65 72 74 20 3d 20 30 3b 0a 20 20 20 20  Insert = 0;.    
6750: 63 68 61 72 20 2a 7a 56 61 6c 75 65 73 20 3d 20  char *zValues = 
6760: 30 3b 0a 20 20 0a 20 20 20 20 7a 49 6e 73 65 72  0;.  .    zInser
6770: 74 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72 69  t = sqlite3_mpri
6780: 6e 74 66 28 22 49 4e 53 45 52 54 20 49 4e 54 4f  ntf("INSERT INTO
6790: 20 25 51 20 28 22 2c 20 70 56 74 61 62 2d 3e 7a   %Q (", pVtab->z
67a0: 54 61 62 6c 65 4e 61 6d 65 29 3b 0a 20 20 20 20  TableName);.    
67b0: 69 66 28 20 21 7a 49 6e 73 65 72 74 20 29 7b 0a  if( !zInsert ){.
67c0: 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54        rc = SQLIT
67d0: 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 7d 0a 20  E_NOMEM;.    }. 
67e0: 20 20 20 69 66 28 20 73 71 6c 69 74 65 33 5f 76     if( sqlite3_v
67f0: 61 6c 75 65 5f 74 79 70 65 28 61 70 44 61 74 61  alue_type(apData
6800: 5b 31 5d 29 3d 3d 53 51 4c 49 54 45 5f 49 4e 54  [1])==SQLITE_INT
6810: 45 47 45 52 20 29 7b 0a 20 20 20 20 20 20 62 69  EGER ){.      bi
6820: 6e 64 41 72 67 4f 6e 65 20 3d 20 31 3b 0a 20 20  ndArgOne = 1;.  
6830: 20 20 20 20 7a 56 61 6c 75 65 73 20 3d 20 73 71      zValues = sq
6840: 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 22 3f  lite3_mprintf("?
6850: 22 29 3b 0a 20 20 20 20 20 20 73 74 72 69 6e 67  ");.      string
6860: 5f 63 6f 6e 63 61 74 28 26 7a 49 6e 73 65 72 74  _concat(&zInsert
6870: 2c 20 22 72 6f 77 69 64 22 2c 20 30 2c 20 26 72  , "rowid", 0, &r
6880: 63 29 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 61  c);.    }..    a
6890: 73 73 65 72 74 28 28 70 56 74 61 62 2d 3e 6e 43  ssert((pVtab->nC
68a0: 6f 6c 2b 32 29 3d 3d 6e 44 61 74 61 29 3b 0a 20  ol+2)==nData);. 
68b0: 20 20 20 66 6f 72 28 69 69 3d 32 3b 20 69 69 3c     for(ii=2; ii<
68c0: 6e 44 61 74 61 3b 20 69 69 2b 2b 29 7b 0a 20 20  nData; ii++){.  
68d0: 20 20 20 20 73 74 72 69 6e 67 5f 63 6f 6e 63 61      string_conca
68e0: 74 28 26 7a 49 6e 73 65 72 74 2c 20 0a 20 20 20  t(&zInsert, .   
68f0: 20 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 6d         sqlite3_m
6900: 70 72 69 6e 74 66 28 22 25 73 25 51 22 2c 20 7a  printf("%s%Q", z
6910: 56 61 6c 75 65 73 3f 22 2c 20 22 3a 22 22 2c 20  Values?", ":"", 
6920: 70 56 74 61 62 2d 3e 61 43 6f 6c 5b 69 69 2d 32  pVtab->aCol[ii-2
6930: 5d 29 2c 20 31 2c 20 26 72 63 29 3b 0a 20 20 20  ]), 1, &rc);.   
6940: 20 20 20 73 74 72 69 6e 67 5f 63 6f 6e 63 61 74     string_concat
6950: 28 26 7a 56 61 6c 75 65 73 2c 20 0a 20 20 20 20  (&zValues, .    
6960: 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 6d 70        sqlite3_mp
6970: 72 69 6e 74 66 28 22 25 73 3f 25 64 22 2c 20 7a  rintf("%s?%d", z
6980: 56 61 6c 75 65 73 3f 22 2c 20 22 3a 22 22 2c 20  Values?", ":"", 
6990: 69 69 29 2c 20 31 2c 20 26 72 63 29 3b 0a 20 20  ii), 1, &rc);.  
69a0: 20 20 7d 0a 0a 20 20 20 20 73 74 72 69 6e 67 5f    }..    string_
69b0: 63 6f 6e 63 61 74 28 26 7a 2c 20 7a 49 6e 73 65  concat(&z, zInse
69c0: 72 74 2c 20 31 2c 20 26 72 63 29 3b 0a 20 20 20  rt, 1, &rc);.   
69d0: 20 73 74 72 69 6e 67 5f 63 6f 6e 63 61 74 28 26   string_concat(&
69e0: 7a 2c 20 22 29 20 56 41 4c 55 45 53 28 22 2c 20  z, ") VALUES(", 
69f0: 30 2c 20 26 72 63 29 3b 0a 20 20 20 20 73 74 72  0, &rc);.    str
6a00: 69 6e 67 5f 63 6f 6e 63 61 74 28 26 7a 2c 20 7a  ing_concat(&z, z
6a10: 56 61 6c 75 65 73 2c 20 31 2c 20 26 72 63 29 3b  Values, 1, &rc);
6a20: 0a 20 20 20 20 73 74 72 69 6e 67 5f 63 6f 6e 63  .    string_conc
6a30: 61 74 28 26 7a 2c 20 22 29 22 2c 20 30 2c 20 26  at(&z, ")", 0, &
6a40: 72 63 29 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 41  rc);.  }..  /* A
6a50: 6e 79 74 68 69 6e 67 20 65 6c 73 65 20 69 73 20  nything else is 
6a60: 61 6e 20 65 72 72 6f 72 20 2a 2f 0a 20 20 65 6c  an error */.  el
6a70: 73 65 7b 0a 20 20 20 20 61 73 73 65 72 74 28 30  se{.    assert(0
6a80: 29 3b 0a 20 20 20 20 72 65 74 75 72 6e 20 53 51  );.    return SQ
6a90: 4c 49 54 45 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a  LITE_ERROR;.  }.
6aa0: 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54  .  if( rc==SQLIT
6ab0: 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 72 63 20 3d  E_OK ){.    rc =
6ac0: 20 73 71 6c 69 74 65 33 5f 70 72 65 70 61 72 65   sqlite3_prepare
6ad0: 28 64 62 2c 20 7a 2c 20 2d 31 2c 20 26 70 53 74  (db, z, -1, &pSt
6ae0: 6d 74 2c 20 30 29 3b 0a 20 20 7d 0a 20 20 61 73  mt, 0);.  }.  as
6af0: 73 65 72 74 28 20 72 63 21 3d 53 51 4c 49 54 45  sert( rc!=SQLITE
6b00: 5f 4f 4b 20 7c 7c 20 70 53 74 6d 74 20 29 3b 0a  _OK || pStmt );.
6b10: 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 7a    sqlite3_free(z
6b20: 29 3b 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c  );.  if( rc==SQL
6b30: 49 54 45 5f 4f 4b 20 29 20 7b 0a 20 20 20 20 69  ITE_OK ) {.    i
6b40: 66 28 20 62 69 6e 64 41 72 67 5a 65 72 6f 20 29  f( bindArgZero )
6b50: 7b 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f  {.      sqlite3_
6b60: 62 69 6e 64 5f 76 61 6c 75 65 28 70 53 74 6d 74  bind_value(pStmt
6b70: 2c 20 6e 44 61 74 61 2c 20 61 70 44 61 74 61 5b  , nData, apData[
6b80: 30 5d 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69  0]);.    }.    i
6b90: 66 28 20 62 69 6e 64 41 72 67 4f 6e 65 20 29 7b  f( bindArgOne ){
6ba0: 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 62  .      sqlite3_b
6bb0: 69 6e 64 5f 76 61 6c 75 65 28 70 53 74 6d 74 2c  ind_value(pStmt,
6bc0: 20 31 2c 20 61 70 44 61 74 61 5b 31 5d 29 3b 0a   1, apData[1]);.
6bd0: 20 20 20 20 7d 0a 20 20 20 20 66 6f 72 28 69 3d      }.    for(i=
6be0: 32 3b 20 69 3c 6e 44 61 74 61 20 26 26 20 72 63  2; i<nData && rc
6bf0: 3d 3d 53 51 4c 49 54 45 5f 4f 4b 3b 20 69 2b 2b  ==SQLITE_OK; i++
6c00: 29 7b 0a 20 20 20 20 20 20 69 66 28 20 61 70 44  ){.      if( apD
6c10: 61 74 61 5b 69 5d 20 29 20 72 63 20 3d 20 73 71  ata[i] ) rc = sq
6c20: 6c 69 74 65 33 5f 62 69 6e 64 5f 76 61 6c 75 65  lite3_bind_value
6c30: 28 70 53 74 6d 74 2c 20 69 2c 20 61 70 44 61 74  (pStmt, i, apDat
6c40: 61 5b 69 5d 29 3b 0a 20 20 20 20 7d 0a 20 20 20  a[i]);.    }.   
6c50: 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
6c60: 4f 4b 20 29 7b 0a 20 20 20 20 20 20 73 71 6c 69  OK ){.      sqli
6c70: 74 65 33 5f 73 74 65 70 28 70 53 74 6d 74 29 3b  te3_step(pStmt);
6c80: 0a 20 20 20 20 20 20 72 63 20 3d 20 73 71 6c 69  .      rc = sqli
6c90: 74 65 33 5f 66 69 6e 61 6c 69 7a 65 28 70 53 74  te3_finalize(pSt
6ca0: 6d 74 29 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a  mt);.    }else{.
6cb0: 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 66 69        sqlite3_fi
6cc0: 6e 61 6c 69 7a 65 28 70 53 74 6d 74 29 3b 0a 20  nalize(pStmt);. 
6cd0: 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 69 66 28 20     }.  }..  if( 
6ce0: 70 52 6f 77 69 64 20 26 26 20 72 63 3d 3d 53 51  pRowid && rc==SQ
6cf0: 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 2a  LITE_OK ){.    *
6d00: 70 52 6f 77 69 64 20 3d 20 73 71 6c 69 74 65 33  pRowid = sqlite3
6d10: 5f 6c 61 73 74 5f 69 6e 73 65 72 74 5f 72 6f 77  _last_insert_row
6d20: 69 64 28 64 62 29 3b 0a 20 20 7d 0a 20 20 69 66  id(db);.  }.  if
6d30: 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc!=SQLITE_OK 
6d40: 29 7b 0a 20 20 20 20 74 61 62 2d 3e 7a 45 72 72  ){.    tab->zErr
6d50: 4d 73 67 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70  Msg = sqlite3_mp
6d60: 72 69 6e 74 66 28 22 65 63 68 6f 2d 76 74 61 62  rintf("echo-vtab
6d70: 2d 65 72 72 6f 72 3a 20 25 73 22 2c 20 73 71 6c  -error: %s", sql
6d80: 69 74 65 33 5f 65 72 72 6d 73 67 28 64 62 29 29  ite3_errmsg(db))
6d90: 3b 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20  ;.  }..  return 
6da0: 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 78 42 65  rc;.}../*.** xBe
6db0: 67 69 6e 2c 20 78 53 79 6e 63 2c 20 78 43 6f 6d  gin, xSync, xCom
6dc0: 6d 69 74 20 61 6e 64 20 78 52 6f 6c 6c 62 61 63  mit and xRollbac
6dd0: 6b 20 63 61 6c 6c 62 61 63 6b 73 20 66 6f 72 20  k callbacks for 
6de0: 65 63 68 6f 20 6d 6f 64 75 6c 65 0a 2a 2a 20 76  echo module.** v
6df0: 69 72 74 75 61 6c 20 74 61 62 6c 65 73 2e 20 44  irtual tables. D
6e00: 6f 20 6e 6f 74 68 69 6e 67 20 6f 74 68 65 72 20  o nothing other 
6e10: 74 68 61 6e 20 61 64 64 20 74 68 65 20 6e 61 6d  than add the nam
6e20: 65 20 6f 66 20 74 68 65 20 63 61 6c 6c 62 61 63  e of the callbac
6e30: 6b 0a 2a 2a 20 74 6f 20 74 68 65 20 24 3a 3a 65  k.** to the $::e
6e40: 63 68 6f 5f 6d 6f 64 75 6c 65 20 54 63 6c 20 76  cho_module Tcl v
6e50: 61 72 69 61 62 6c 65 2e 0a 2a 2f 0a 73 74 61 74  ariable..*/.stat
6e60: 69 63 20 69 6e 74 20 65 63 68 6f 54 72 61 6e 73  ic int echoTrans
6e70: 61 63 74 69 6f 6e 43 61 6c 6c 28 73 71 6c 69 74  actionCall(sqlit
6e80: 65 33 5f 76 74 61 62 20 2a 74 61 62 2c 20 63 6f  e3_vtab *tab, co
6e90: 6e 73 74 20 63 68 61 72 20 2a 7a 43 61 6c 6c 29  nst char *zCall)
6ea0: 7b 0a 20 20 63 68 61 72 20 2a 7a 3b 0a 20 20 65  {.  char *z;.  e
6eb0: 63 68 6f 5f 76 74 61 62 20 2a 70 56 74 61 62 20  cho_vtab *pVtab 
6ec0: 3d 20 28 65 63 68 6f 5f 76 74 61 62 20 2a 29 74  = (echo_vtab *)t
6ed0: 61 62 3b 0a 20 20 7a 20 3d 20 73 71 6c 69 74 65  ab;.  z = sqlite
6ee0: 33 5f 6d 70 72 69 6e 74 66 28 22 65 63 68 6f 28  3_mprintf("echo(
6ef0: 25 73 29 22 2c 20 70 56 74 61 62 2d 3e 7a 54 61  %s)", pVtab->zTa
6f00: 62 6c 65 4e 61 6d 65 29 3b 0a 20 20 69 66 28 20  bleName);.  if( 
6f10: 7a 3d 3d 30 20 29 20 72 65 74 75 72 6e 20 53 51  z==0 ) return SQ
6f20: 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 61 70  LITE_NOMEM;.  ap
6f30: 70 65 6e 64 54 6f 45 63 68 6f 4d 6f 64 75 6c 65  pendToEchoModule
6f40: 28 70 56 74 61 62 2d 3e 69 6e 74 65 72 70 2c 20  (pVtab->interp, 
6f50: 7a 43 61 6c 6c 29 3b 0a 20 20 61 70 70 65 6e 64  zCall);.  append
6f60: 54 6f 45 63 68 6f 4d 6f 64 75 6c 65 28 70 56 74  ToEchoModule(pVt
6f70: 61 62 2d 3e 69 6e 74 65 72 70 2c 20 7a 29 3b 0a  ab->interp, z);.
6f80: 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 7a    sqlite3_free(z
6f90: 29 3b 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49  );.  return SQLI
6fa0: 54 45 5f 4f 4b 3b 0a 7d 0a 73 74 61 74 69 63 20  TE_OK;.}.static 
6fb0: 69 6e 74 20 65 63 68 6f 42 65 67 69 6e 28 73 71  int echoBegin(sq
6fc0: 6c 69 74 65 33 5f 76 74 61 62 20 2a 74 61 62 29  lite3_vtab *tab)
6fd0: 7b 0a 20 20 69 6e 74 20 72 63 3b 0a 20 20 65 63  {.  int rc;.  ec
6fe0: 68 6f 5f 76 74 61 62 20 2a 70 56 74 61 62 20 3d  ho_vtab *pVtab =
6ff0: 20 28 65 63 68 6f 5f 76 74 61 62 20 2a 29 74 61   (echo_vtab *)ta
7000: 62 3b 0a 20 20 54 63 6c 5f 49 6e 74 65 72 70 20  b;.  Tcl_Interp 
7010: 2a 69 6e 74 65 72 70 20 3d 20 70 56 74 61 62 2d  *interp = pVtab-
7020: 3e 69 6e 74 65 72 70 3b 0a 20 20 63 6f 6e 73 74  >interp;.  const
7030: 20 63 68 61 72 20 2a 7a 56 61 6c 3b 20 0a 0a 20   char *zVal; .. 
7040: 20 2f 2a 20 54 69 63 6b 65 74 20 23 33 30 38 33   /* Ticket #3083
7050: 20 2d 20 64 6f 20 6e 6f 74 20 73 74 61 72 74 20   - do not start 
7060: 61 20 74 72 61 6e 73 61 63 74 69 6f 6e 20 69 66  a transaction if
7070: 20 77 65 20 61 72 65 20 61 6c 72 65 61 64 79 20   we are already 
7080: 69 6e 0a 20 20 2a 2a 20 61 20 74 72 61 6e 73 61  in.  ** a transa
7090: 63 74 69 6f 6e 20 2a 2f 0a 20 20 61 73 73 65 72  ction */.  asser
70a0: 74 28 20 21 70 56 74 61 62 2d 3e 69 6e 54 72 61  t( !pVtab->inTra
70b0: 6e 73 61 63 74 69 6f 6e 20 29 3b 0a 0a 20 20 72  nsaction );..  r
70c0: 63 20 3d 20 65 63 68 6f 54 72 61 6e 73 61 63 74  c = echoTransact
70d0: 69 6f 6e 43 61 6c 6c 28 74 61 62 2c 20 22 78 42  ionCall(tab, "xB
70e0: 65 67 69 6e 22 29 3b 0a 0a 20 20 69 66 28 20 72  egin");..  if( r
70f0: 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a  c==SQLITE_OK ){.
7100: 20 20 20 20 2f 2a 20 43 68 65 63 6b 20 69 66 20      /* Check if 
7110: 74 68 65 20 24 3a 3a 65 63 68 6f 5f 6d 6f 64 75  the $::echo_modu
7120: 6c 65 5f 62 65 67 69 6e 5f 66 61 69 6c 20 76 61  le_begin_fail va
7130: 72 69 61 62 6c 65 20 69 73 20 64 65 66 69 6e 65  riable is define
7140: 64 2e 20 49 66 20 69 74 20 69 73 2c 0a 20 20 20  d. If it is,.   
7150: 20 2a 2a 20 61 6e 64 20 69 74 20 69 73 20 73 65   ** and it is se
7160: 74 20 74 6f 20 74 68 65 20 6e 61 6d 65 20 6f 66  t to the name of
7170: 20 74 68 65 20 72 65 61 6c 20 74 61 62 6c 65 20   the real table 
7180: 75 6e 64 65 72 6c 79 69 6e 67 20 74 68 69 73 20  underlying this 
7190: 76 69 72 74 75 61 6c 0a 20 20 20 20 2a 2a 20 65  virtual.    ** e
71a0: 63 68 6f 20 6d 6f 64 75 6c 65 20 74 61 62 6c 65  cho module table
71b0: 2c 20 74 68 65 6e 20 63 61 75 73 65 20 74 68 69  , then cause thi
71c0: 73 20 78 53 79 6e 63 20 6f 70 65 72 61 74 69 6f  s xSync operatio
71d0: 6e 20 74 6f 20 66 61 69 6c 2e 0a 20 20 20 20 2a  n to fail..    *
71e0: 2f 0a 20 20 20 20 7a 56 61 6c 20 3d 20 54 63 6c  /.    zVal = Tcl
71f0: 5f 47 65 74 56 61 72 28 69 6e 74 65 72 70 2c 20  _GetVar(interp, 
7200: 22 65 63 68 6f 5f 6d 6f 64 75 6c 65 5f 62 65 67  "echo_module_beg
7210: 69 6e 5f 66 61 69 6c 22 2c 20 54 43 4c 5f 47 4c  in_fail", TCL_GL
7220: 4f 42 41 4c 5f 4f 4e 4c 59 29 3b 0a 20 20 20 20  OBAL_ONLY);.    
7230: 69 66 28 20 7a 56 61 6c 20 26 26 20 30 3d 3d 73  if( zVal && 0==s
7240: 74 72 63 6d 70 28 7a 56 61 6c 2c 20 70 56 74 61  trcmp(zVal, pVta
7250: 62 2d 3e 7a 54 61 62 6c 65 4e 61 6d 65 29 20 29  b->zTableName) )
7260: 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c  {.      rc = SQL
7270: 49 54 45 5f 45 52 52 4f 52 3b 0a 20 20 20 20 7d  ITE_ERROR;.    }
7280: 0a 20 20 7d 0a 20 20 69 66 28 20 72 63 3d 3d 53  .  }.  if( rc==S
7290: 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
72a0: 70 56 74 61 62 2d 3e 69 6e 54 72 61 6e 73 61 63  pVtab->inTransac
72b0: 74 69 6f 6e 20 3d 20 31 3b 0a 20 20 7d 0a 20 20  tion = 1;.  }.  
72c0: 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 73 74 61  return rc;.}.sta
72d0: 74 69 63 20 69 6e 74 20 65 63 68 6f 53 79 6e 63  tic int echoSync
72e0: 28 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 74  (sqlite3_vtab *t
72f0: 61 62 29 7b 0a 20 20 69 6e 74 20 72 63 3b 0a 20  ab){.  int rc;. 
7300: 20 65 63 68 6f 5f 76 74 61 62 20 2a 70 56 74 61   echo_vtab *pVta
7310: 62 20 3d 20 28 65 63 68 6f 5f 76 74 61 62 20 2a  b = (echo_vtab *
7320: 29 74 61 62 3b 0a 20 20 54 63 6c 5f 49 6e 74 65  )tab;.  Tcl_Inte
7330: 72 70 20 2a 69 6e 74 65 72 70 20 3d 20 70 56 74  rp *interp = pVt
7340: 61 62 2d 3e 69 6e 74 65 72 70 3b 0a 20 20 63 6f  ab->interp;.  co
7350: 6e 73 74 20 63 68 61 72 20 2a 7a 56 61 6c 3b 20  nst char *zVal; 
7360: 0a 0a 20 20 2f 2a 20 54 69 63 6b 65 74 20 23 33  ..  /* Ticket #3
7370: 30 38 33 20 2d 20 4f 6e 6c 79 20 63 61 6c 6c 20  083 - Only call 
7380: 78 53 79 6e 63 20 69 66 20 77 65 20 68 61 76 65  xSync if we have
7390: 20 70 72 65 76 69 6f 75 73 6c 79 20 73 74 61 72   previously star
73a0: 74 65 64 20 61 0a 20 20 2a 2a 20 74 72 61 6e 73  ted a.  ** trans
73b0: 61 63 74 69 6f 6e 20 2a 2f 0a 20 20 61 73 73 65  action */.  asse
73c0: 72 74 28 20 70 56 74 61 62 2d 3e 69 6e 54 72 61  rt( pVtab->inTra
73d0: 6e 73 61 63 74 69 6f 6e 20 29 3b 0a 0a 20 20 72  nsaction );..  r
73e0: 63 20 3d 20 65 63 68 6f 54 72 61 6e 73 61 63 74  c = echoTransact
73f0: 69 6f 6e 43 61 6c 6c 28 74 61 62 2c 20 22 78 53  ionCall(tab, "xS
7400: 79 6e 63 22 29 3b 0a 0a 20 20 69 66 28 20 72 63  ync");..  if( rc
7410: 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  ==SQLITE_OK ){. 
7420: 20 20 20 2f 2a 20 43 68 65 63 6b 20 69 66 20 74     /* Check if t
7430: 68 65 20 24 3a 3a 65 63 68 6f 5f 6d 6f 64 75 6c  he $::echo_modul
7440: 65 5f 73 79 6e 63 5f 66 61 69 6c 20 76 61 72 69  e_sync_fail vari
7450: 61 62 6c 65 20 69 73 20 64 65 66 69 6e 65 64 2e  able is defined.
7460: 20 49 66 20 69 74 20 69 73 2c 0a 20 20 20 20 2a   If it is,.    *
7470: 2a 20 61 6e 64 20 69 74 20 69 73 20 73 65 74 20  * and it is set 
7480: 74 6f 20 74 68 65 20 6e 61 6d 65 20 6f 66 20 74  to the name of t
7490: 68 65 20 72 65 61 6c 20 74 61 62 6c 65 20 75 6e  he real table un
74a0: 64 65 72 6c 79 69 6e 67 20 74 68 69 73 20 76 69  derlying this vi
74b0: 72 74 75 61 6c 0a 20 20 20 20 2a 2a 20 65 63 68  rtual.    ** ech
74c0: 6f 20 6d 6f 64 75 6c 65 20 74 61 62 6c 65 2c 20  o module table, 
74d0: 74 68 65 6e 20 63 61 75 73 65 20 74 68 69 73 20  then cause this 
74e0: 78 53 79 6e 63 20 6f 70 65 72 61 74 69 6f 6e 20  xSync operation 
74f0: 74 6f 20 66 61 69 6c 2e 0a 20 20 20 20 2a 2f 0a  to fail..    */.
7500: 20 20 20 20 7a 56 61 6c 20 3d 20 54 63 6c 5f 47      zVal = Tcl_G
7510: 65 74 56 61 72 28 69 6e 74 65 72 70 2c 20 22 65  etVar(interp, "e
7520: 63 68 6f 5f 6d 6f 64 75 6c 65 5f 73 79 6e 63 5f  cho_module_sync_
7530: 66 61 69 6c 22 2c 20 54 43 4c 5f 47 4c 4f 42 41  fail", TCL_GLOBA
7540: 4c 5f 4f 4e 4c 59 29 3b 0a 20 20 20 20 69 66 28  L_ONLY);.    if(
7550: 20 7a 56 61 6c 20 26 26 20 30 3d 3d 73 74 72 63   zVal && 0==strc
7560: 6d 70 28 7a 56 61 6c 2c 20 70 56 74 61 62 2d 3e  mp(zVal, pVtab->
7570: 7a 54 61 62 6c 65 4e 61 6d 65 29 20 29 7b 0a 20  zTableName) ){. 
7580: 20 20 20 20 20 72 63 20 3d 20 2d 31 3b 0a 20 20       rc = -1;.  
7590: 20 20 7d 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e    }.  }.  return
75a0: 20 72 63 3b 0a 7d 0a 73 74 61 74 69 63 20 69 6e   rc;.}.static in
75b0: 74 20 65 63 68 6f 43 6f 6d 6d 69 74 28 73 71 6c  t echoCommit(sql
75c0: 69 74 65 33 5f 76 74 61 62 20 2a 74 61 62 29 7b  ite3_vtab *tab){
75d0: 0a 20 20 65 63 68 6f 5f 76 74 61 62 20 2a 70 56  .  echo_vtab *pV
75e0: 74 61 62 20 3d 20 28 65 63 68 6f 5f 76 74 61 62  tab = (echo_vtab
75f0: 2a 29 74 61 62 3b 0a 20 20 69 6e 74 20 72 63 3b  *)tab;.  int rc;
7600: 0a 0a 20 20 2f 2a 20 54 69 63 6b 65 74 20 23 33  ..  /* Ticket #3
7610: 30 38 33 20 2d 20 4f 6e 6c 79 20 63 61 6c 6c 20  083 - Only call 
7620: 78 43 6f 6d 6d 69 74 20 69 66 20 77 65 20 68 61  xCommit if we ha
7630: 76 65 20 70 72 65 76 69 6f 75 73 6c 79 20 73 74  ve previously st
7640: 61 72 74 65 64 0a 20 20 2a 2a 20 61 20 74 72 61  arted.  ** a tra
7650: 6e 73 61 63 74 69 6f 6e 20 2a 2f 0a 20 20 61 73  nsaction */.  as
7660: 73 65 72 74 28 20 70 56 74 61 62 2d 3e 69 6e 54  sert( pVtab->inT
7670: 72 61 6e 73 61 63 74 69 6f 6e 20 29 3b 0a 0a 20  ransaction );.. 
7680: 20 73 71 6c 69 74 65 33 42 65 67 69 6e 42 65 6e   sqlite3BeginBen
7690: 69 67 6e 4d 61 6c 6c 6f 63 28 29 3b 0a 20 20 72  ignMalloc();.  r
76a0: 63 20 3d 20 65 63 68 6f 54 72 61 6e 73 61 63 74  c = echoTransact
76b0: 69 6f 6e 43 61 6c 6c 28 74 61 62 2c 20 22 78 43  ionCall(tab, "xC
76c0: 6f 6d 6d 69 74 22 29 3b 0a 20 20 73 71 6c 69 74  ommit");.  sqlit
76d0: 65 33 45 6e 64 42 65 6e 69 67 6e 4d 61 6c 6c 6f  e3EndBenignMallo
76e0: 63 28 29 3b 0a 20 20 70 56 74 61 62 2d 3e 69 6e  c();.  pVtab->in
76f0: 54 72 61 6e 73 61 63 74 69 6f 6e 20 3d 20 30 3b  Transaction = 0;
7700: 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a  .  return rc;.}.
7710: 73 74 61 74 69 63 20 69 6e 74 20 65 63 68 6f 52  static int echoR
7720: 6f 6c 6c 62 61 63 6b 28 73 71 6c 69 74 65 33 5f  ollback(sqlite3_
7730: 76 74 61 62 20 2a 74 61 62 29 7b 0a 20 20 69 6e  vtab *tab){.  in
7740: 74 20 72 63 3b 0a 20 20 65 63 68 6f 5f 76 74 61  t rc;.  echo_vta
7750: 62 20 2a 70 56 74 61 62 20 3d 20 28 65 63 68 6f  b *pVtab = (echo
7760: 5f 76 74 61 62 2a 29 74 61 62 3b 0a 0a 20 20 2f  _vtab*)tab;..  /
7770: 2a 20 54 69 63 6b 65 74 20 23 33 30 38 33 20 2d  * Ticket #3083 -
7780: 20 4f 6e 6c 79 20 63 61 6c 6c 20 78 52 6f 6c 6c   Only call xRoll
7790: 62 61 63 6b 20 69 66 20 77 65 20 68 61 76 65 20  back if we have 
77a0: 70 72 65 76 69 6f 75 73 6c 79 20 73 74 61 72 74  previously start
77b0: 65 64 0a 20 20 2a 2a 20 61 20 74 72 61 6e 73 61  ed.  ** a transa
77c0: 63 74 69 6f 6e 20 2a 2f 0a 20 20 61 73 73 65 72  ction */.  asser
77d0: 74 28 20 70 56 74 61 62 2d 3e 69 6e 54 72 61 6e  t( pVtab->inTran
77e0: 73 61 63 74 69 6f 6e 20 29 3b 0a 0a 20 20 72 63  saction );..  rc
77f0: 20 3d 20 65 63 68 6f 54 72 61 6e 73 61 63 74 69   = echoTransacti
7800: 6f 6e 43 61 6c 6c 28 74 61 62 2c 20 22 78 52 6f  onCall(tab, "xRo
7810: 6c 6c 62 61 63 6b 22 29 3b 0a 20 20 70 56 74 61  llback");.  pVta
7820: 62 2d 3e 69 6e 54 72 61 6e 73 61 63 74 69 6f 6e  b->inTransaction
7830: 20 3d 20 30 3b 0a 20 20 72 65 74 75 72 6e 20 72   = 0;.  return r
7840: 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c  c;.}../*.** Impl
7850: 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66 20 22 47  ementation of "G
7860: 4c 4f 42 22 20 66 75 6e 63 74 69 6f 6e 20 6f 6e  LOB" function on
7870: 20 74 68 65 20 65 63 68 6f 20 6d 6f 64 75 6c 65   the echo module
7880: 2e 20 20 50 61 73 73 0a 2a 2a 20 61 6c 6c 20 61  .  Pass.** all a
7890: 72 67 75 6d 65 6e 74 73 20 74 6f 20 74 68 65 20  rguments to the 
78a0: 3a 3a 65 63 68 6f 5f 67 6c 6f 62 5f 6f 76 65 72  ::echo_glob_over
78b0: 6c 6f 61 64 20 70 72 6f 63 65 64 75 72 65 20 6f  load procedure o
78c0: 66 20 54 43 4c 0a 2a 2a 20 61 6e 64 20 72 65 74  f TCL.** and ret
78d0: 75 72 6e 20 74 68 65 20 72 65 73 75 6c 74 20 6f  urn the result o
78e0: 66 20 74 68 61 74 20 70 72 6f 63 65 64 75 72 65  f that procedure
78f0: 20 61 73 20 61 20 73 74 72 69 6e 67 2e 0a 2a 2f   as a string..*/
7900: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 6f 76 65  .static void ove
7910: 72 6c 6f 61 64 65 64 47 6c 6f 62 46 75 6e 63 74  rloadedGlobFunct
7920: 69 6f 6e 28 0a 20 20 73 71 6c 69 74 65 33 5f 63  ion(.  sqlite3_c
7930: 6f 6e 74 65 78 74 20 2a 70 43 6f 6e 74 65 78 74  ontext *pContext
7940: 2c 0a 20 20 69 6e 74 20 6e 41 72 67 2c 0a 20 20  ,.  int nArg,.  
7950: 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 20 2a 2a  sqlite3_value **
7960: 61 70 41 72 67 0a 29 7b 0a 20 20 54 63 6c 5f 49  apArg.){.  Tcl_I
7970: 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 20 3d 20  nterp *interp = 
7980: 73 71 6c 69 74 65 33 5f 75 73 65 72 5f 64 61 74  sqlite3_user_dat
7990: 61 28 70 43 6f 6e 74 65 78 74 29 3b 0a 20 20 54  a(pContext);.  T
79a0: 63 6c 5f 44 53 74 72 69 6e 67 20 73 74 72 3b 0a  cl_DString str;.
79b0: 20 20 69 6e 74 20 69 3b 0a 20 20 69 6e 74 20 72    int i;.  int r
79c0: 63 3b 0a 20 20 54 63 6c 5f 44 53 74 72 69 6e 67  c;.  Tcl_DString
79d0: 49 6e 69 74 28 26 73 74 72 29 3b 0a 20 20 54 63  Init(&str);.  Tc
79e0: 6c 5f 44 53 74 72 69 6e 67 41 70 70 65 6e 64 45  l_DStringAppendE
79f0: 6c 65 6d 65 6e 74 28 26 73 74 72 2c 20 22 3a 3a  lement(&str, "::
7a00: 65 63 68 6f 5f 67 6c 6f 62 5f 6f 76 65 72 6c 6f  echo_glob_overlo
7a10: 61 64 22 29 3b 0a 20 20 66 6f 72 28 69 3d 30 3b  ad");.  for(i=0;
7a20: 20 69 3c 6e 41 72 67 3b 20 69 2b 2b 29 7b 0a 20   i<nArg; i++){. 
7a30: 20 20 20 54 63 6c 5f 44 53 74 72 69 6e 67 41 70     Tcl_DStringAp
7a40: 70 65 6e 64 45 6c 65 6d 65 6e 74 28 26 73 74 72  pendElement(&str
7a50: 2c 20 28 63 68 61 72 2a 29 73 71 6c 69 74 65 33  , (char*)sqlite3
7a60: 5f 76 61 6c 75 65 5f 74 65 78 74 28 61 70 41 72  _value_text(apAr
7a70: 67 5b 69 5d 29 29 3b 0a 20 20 7d 0a 20 20 72 63  g[i]));.  }.  rc
7a80: 20 3d 20 54 63 6c 5f 45 76 61 6c 28 69 6e 74 65   = Tcl_Eval(inte
7a90: 72 70 2c 20 54 63 6c 5f 44 53 74 72 69 6e 67 56  rp, Tcl_DStringV
7aa0: 61 6c 75 65 28 26 73 74 72 29 29 3b 0a 20 20 54  alue(&str));.  T
7ab0: 63 6c 5f 44 53 74 72 69 6e 67 46 72 65 65 28 26  cl_DStringFree(&
7ac0: 73 74 72 29 3b 0a 20 20 69 66 28 20 72 63 20 29  str);.  if( rc )
7ad0: 7b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 72 65  {.    sqlite3_re
7ae0: 73 75 6c 74 5f 65 72 72 6f 72 28 70 43 6f 6e 74  sult_error(pCont
7af0: 65 78 74 2c 20 54 63 6c 5f 47 65 74 53 74 72 69  ext, Tcl_GetStri
7b00: 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29  ngResult(interp)
7b10: 2c 20 2d 31 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a  , -1);.  }else{.
7b20: 20 20 20 20 73 71 6c 69 74 65 33 5f 72 65 73 75      sqlite3_resu
7b30: 6c 74 5f 74 65 78 74 28 70 43 6f 6e 74 65 78 74  lt_text(pContext
7b40: 2c 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 52  , Tcl_GetStringR
7b50: 65 73 75 6c 74 28 69 6e 74 65 72 70 29 2c 0a 20  esult(interp),. 
7b60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7b70: 20 20 20 20 20 20 20 2d 31 2c 20 53 51 4c 49 54         -1, SQLIT
7b80: 45 5f 54 52 41 4e 53 49 45 4e 54 29 3b 0a 20 20  E_TRANSIENT);.  
7b90: 7d 0a 20 20 54 63 6c 5f 52 65 73 65 74 52 65 73  }.  Tcl_ResetRes
7ba0: 75 6c 74 28 69 6e 74 65 72 70 29 3b 0a 7d 0a 0a  ult(interp);.}..
7bb0: 2f 2a 0a 2a 2a 20 54 68 69 73 20 69 73 20 74 68  /*.** This is th
7bc0: 65 20 78 46 69 6e 64 46 75 6e 63 74 69 6f 6e 20  e xFindFunction 
7bd0: 69 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 66  implementation f
7be0: 6f 72 20 74 68 65 20 65 63 68 6f 20 6d 6f 64 75  or the echo modu
7bf0: 6c 65 2e 0a 2a 2a 20 53 51 4c 69 74 65 20 63 61  le..** SQLite ca
7c00: 6c 6c 73 20 74 68 69 73 20 72 6f 75 74 69 6e 65  lls this routine
7c10: 20 77 68 65 6e 20 74 68 65 20 66 69 72 73 74 20   when the first 
7c20: 61 72 67 75 6d 65 6e 74 20 6f 66 20 61 20 66 75  argument of a fu
7c30: 6e 63 74 69 6f 6e 0a 2a 2a 20 69 73 20 61 20 63  nction.** is a c
7c40: 6f 6c 75 6d 6e 20 6f 66 20 61 6e 20 65 63 68 6f  olumn of an echo
7c50: 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65 2e 20   virtual table. 
7c60: 20 54 68 69 73 20 72 6f 75 74 69 6e 65 20 63 61   This routine ca
7c70: 6e 20 6f 70 74 69 6f 6e 61 6c 6c 79 0a 2a 2a 20  n optionally.** 
7c80: 6f 76 65 72 72 69 64 65 20 74 68 65 20 69 6d 70  override the imp
7c90: 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f 66 20 74  lementation of t
7ca0: 68 61 74 20 66 75 6e 63 74 69 6f 6e 2e 20 20 49  hat function.  I
7cb0: 74 20 77 69 6c 6c 20 63 68 6f 6f 73 65 20 74 6f  t will choose to
7cc0: 0a 2a 2a 20 64 6f 20 73 6f 20 69 66 20 74 68 65  .** do so if the
7cd0: 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 6e 61 6d   function is nam
7ce0: 65 64 20 22 67 6c 6f 62 22 2c 20 61 6e 64 20 61  ed "glob", and a
7cf0: 20 54 43 4c 20 63 6f 6d 6d 61 6e 64 20 6e 61 6d   TCL command nam
7d00: 65 64 0a 2a 2a 20 3a 3a 65 63 68 6f 5f 67 6c 6f  ed.** ::echo_glo
7d10: 62 5f 6f 76 65 72 6c 6f 61 64 20 65 78 69 73 74  b_overload exist
7d20: 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  s..*/.static int
7d30: 20 65 63 68 6f 46 69 6e 64 46 75 6e 63 74 69 6f   echoFindFunctio
7d40: 6e 28 0a 20 20 73 71 6c 69 74 65 33 5f 76 74 61  n(.  sqlite3_vta
7d50: 62 20 2a 76 74 61 62 2c 0a 20 20 69 6e 74 20 6e  b *vtab,.  int n
7d60: 41 72 67 2c 0a 20 20 63 6f 6e 73 74 20 63 68 61  Arg,.  const cha
7d70: 72 20 2a 7a 46 75 6e 63 4e 61 6d 65 2c 0a 20 20  r *zFuncName,.  
7d80: 76 6f 69 64 20 28 2a 2a 70 78 46 75 6e 63 29 28  void (**pxFunc)(
7d90: 73 71 6c 69 74 65 33 5f 63 6f 6e 74 65 78 74 2a  sqlite3_context*
7da0: 2c 69 6e 74 2c 73 71 6c 69 74 65 33 5f 76 61 6c  ,int,sqlite3_val
7db0: 75 65 2a 2a 29 2c 0a 20 20 76 6f 69 64 20 2a 2a  ue**),.  void **
7dc0: 70 70 41 72 67 0a 29 7b 0a 20 20 65 63 68 6f 5f  ppArg.){.  echo_
7dd0: 76 74 61 62 20 2a 70 56 74 61 62 20 3d 20 28 65  vtab *pVtab = (e
7de0: 63 68 6f 5f 76 74 61 62 20 2a 29 76 74 61 62 3b  cho_vtab *)vtab;
7df0: 0a 20 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69  .  Tcl_Interp *i
7e00: 6e 74 65 72 70 20 3d 20 70 56 74 61 62 2d 3e 69  nterp = pVtab->i
7e10: 6e 74 65 72 70 3b 0a 20 20 54 63 6c 5f 43 6d 64  nterp;.  Tcl_Cmd
7e20: 49 6e 66 6f 20 69 6e 66 6f 3b 0a 20 20 69 66 28  Info info;.  if(
7e30: 20 73 74 72 63 6d 70 28 7a 46 75 6e 63 4e 61 6d   strcmp(zFuncNam
7e40: 65 2c 22 67 6c 6f 62 22 29 21 3d 30 20 29 7b 0a  e,"glob")!=0 ){.
7e50: 20 20 20 20 72 65 74 75 72 6e 20 30 3b 0a 20 20      return 0;.  
7e60: 7d 0a 20 20 69 66 28 20 54 63 6c 5f 47 65 74 43  }.  if( Tcl_GetC
7e70: 6f 6d 6d 61 6e 64 49 6e 66 6f 28 69 6e 74 65 72  ommandInfo(inter
7e80: 70 2c 20 22 3a 3a 65 63 68 6f 5f 67 6c 6f 62 5f  p, "::echo_glob_
7e90: 6f 76 65 72 6c 6f 61 64 22 2c 20 26 69 6e 66 6f  overload", &info
7ea0: 29 3d 3d 30 20 29 7b 0a 20 20 20 20 72 65 74 75  )==0 ){.    retu
7eb0: 72 6e 20 30 3b 0a 20 20 7d 0a 20 20 2a 70 78 46  rn 0;.  }.  *pxF
7ec0: 75 6e 63 20 3d 20 6f 76 65 72 6c 6f 61 64 65 64  unc = overloaded
7ed0: 47 6c 6f 62 46 75 6e 63 74 69 6f 6e 3b 0a 20 20  GlobFunction;.  
7ee0: 2a 70 70 41 72 67 20 3d 20 69 6e 74 65 72 70 3b  *ppArg = interp;
7ef0: 0a 20 20 72 65 74 75 72 6e 20 31 3b 0a 7d 0a 0a  .  return 1;.}..
7f00: 73 74 61 74 69 63 20 69 6e 74 20 65 63 68 6f 52  static int echoR
7f10: 65 6e 61 6d 65 28 73 71 6c 69 74 65 33 5f 76 74  ename(sqlite3_vt
7f20: 61 62 20 2a 76 74 61 62 2c 20 63 6f 6e 73 74 20  ab *vtab, const 
7f30: 63 68 61 72 20 2a 7a 4e 65 77 4e 61 6d 65 29 7b  char *zNewName){
7f40: 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49  .  int rc = SQLI
7f50: 54 45 5f 4f 4b 3b 0a 20 20 65 63 68 6f 5f 76 74  TE_OK;.  echo_vt
7f60: 61 62 20 2a 70 20 3d 20 28 65 63 68 6f 5f 76 74  ab *p = (echo_vt
7f70: 61 62 20 2a 29 76 74 61 62 3b 0a 0a 20 20 69 66  ab *)vtab;..  if
7f80: 28 20 70 2d 3e 69 73 50 61 74 74 65 72 6e 20 29  ( p->isPattern )
7f90: 7b 0a 20 20 20 20 69 6e 74 20 6e 54 68 69 73 20  {.    int nThis 
7fa0: 3d 20 73 74 72 6c 65 6e 28 70 2d 3e 7a 54 68 69  = strlen(p->zThi
7fb0: 73 29 3b 0a 20 20 20 20 63 68 61 72 20 2a 7a 53  s);.    char *zS
7fc0: 71 6c 20 3d 20 73 71 6c 69 74 65 33 4d 50 72 69  ql = sqlite3MPri
7fd0: 6e 74 66 28 30 2c 20 22 41 4c 54 45 52 20 54 41  ntf(0, "ALTER TA
7fe0: 42 4c 45 20 25 73 20 52 45 4e 41 4d 45 20 54 4f  BLE %s RENAME TO
7ff0: 20 25 73 25 73 22 2c 20 0a 20 20 20 20 20 20 20   %s%s", .       
8000: 20 70 2d 3e 7a 54 61 62 6c 65 4e 61 6d 65 2c 20   p->zTableName, 
8010: 7a 4e 65 77 4e 61 6d 65 2c 20 26 70 2d 3e 7a 54  zNewName, &p->zT
8020: 61 62 6c 65 4e 61 6d 65 5b 6e 54 68 69 73 5d 0a  ableName[nThis].
8030: 20 20 20 20 29 3b 0a 20 20 20 20 72 63 20 3d 20      );.    rc = 
8040: 73 71 6c 69 74 65 33 5f 65 78 65 63 28 70 2d 3e  sqlite3_exec(p->
8050: 64 62 2c 20 7a 53 71 6c 2c 20 30 2c 20 30 2c 20  db, zSql, 0, 0, 
8060: 30 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f  0);.    sqlite3_
8070: 66 72 65 65 28 7a 53 71 6c 29 3b 0a 20 20 7d 0a  free(zSql);.  }.
8080: 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a  .  return rc;.}.
8090: 0a 2f 2a 0a 2a 2a 20 41 20 76 69 72 74 75 61 6c  ./*.** A virtual
80a0: 20 74 61 62 6c 65 20 6d 6f 64 75 6c 65 20 74 68   table module th
80b0: 61 74 20 6d 65 72 65 6c 79 20 22 65 63 68 6f 73  at merely "echos
80c0: 22 20 74 68 65 20 63 6f 6e 74 65 6e 74 73 20 6f  " the contents o
80d0: 66 20 61 6e 6f 74 68 65 72 0a 2a 2a 20 74 61 62  f another.** tab
80e0: 6c 65 20 28 6c 69 6b 65 20 61 6e 20 53 51 4c 20  le (like an SQL 
80f0: 56 49 45 57 29 2e 0a 2a 2f 0a 73 74 61 74 69 63  VIEW)..*/.static
8100: 20 73 71 6c 69 74 65 33 5f 6d 6f 64 75 6c 65 20   sqlite3_module 
8110: 65 63 68 6f 4d 6f 64 75 6c 65 20 3d 20 7b 0a 20  echoModule = {. 
8120: 20 30 2c 20 20 20 20 20 20 20 20 20 20 20 20 20   0,             
8130: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 69              /* i
8140: 56 65 72 73 69 6f 6e 20 2a 2f 0a 20 20 65 63 68  Version */.  ech
8150: 6f 43 72 65 61 74 65 2c 0a 20 20 65 63 68 6f 43  oCreate,.  echoC
8160: 6f 6e 6e 65 63 74 2c 0a 20 20 65 63 68 6f 42 65  onnect,.  echoBe
8170: 73 74 49 6e 64 65 78 2c 0a 20 20 65 63 68 6f 44  stIndex,.  echoD
8180: 69 73 63 6f 6e 6e 65 63 74 2c 20 0a 20 20 65 63  isconnect, .  ec
8190: 68 6f 44 65 73 74 72 6f 79 2c 0a 20 20 65 63 68  hoDestroy,.  ech
81a0: 6f 4f 70 65 6e 2c 20 20 20 20 20 20 20 20 20 20  oOpen,          
81b0: 20 20 20 20 20 20 20 20 2f 2a 20 78 4f 70 65 6e          /* xOpen
81c0: 20 2d 20 6f 70 65 6e 20 61 20 63 75 72 73 6f 72   - open a cursor
81d0: 20 2a 2f 0a 20 20 65 63 68 6f 43 6c 6f 73 65 2c   */.  echoClose,
81e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
81f0: 20 2f 2a 20 78 43 6c 6f 73 65 20 2d 20 63 6c 6f   /* xClose - clo
8200: 73 65 20 61 20 63 75 72 73 6f 72 20 2a 2f 0a 20  se a cursor */. 
8210: 20 65 63 68 6f 46 69 6c 74 65 72 2c 20 20 20 20   echoFilter,    
8220: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78              /* x
8230: 46 69 6c 74 65 72 20 2d 20 63 6f 6e 66 69 67 75  Filter - configu
8240: 72 65 20 73 63 61 6e 20 63 6f 6e 73 74 72 61 69  re scan constrai
8250: 6e 74 73 20 2a 2f 0a 20 20 65 63 68 6f 4e 65 78  nts */.  echoNex
8260: 74 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  t,              
8270: 20 20 20 20 2f 2a 20 78 4e 65 78 74 20 2d 20 61      /* xNext - a
8280: 64 76 61 6e 63 65 20 61 20 63 75 72 73 6f 72 20  dvance a cursor 
8290: 2a 2f 0a 20 20 65 63 68 6f 45 6f 66 2c 20 20 20  */.  echoEof,   
82a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
82b0: 2f 2a 20 78 45 6f 66 20 2a 2f 0a 20 20 65 63 68  /* xEof */.  ech
82c0: 6f 43 6f 6c 75 6d 6e 2c 20 20 20 20 20 20 20 20  oColumn,        
82d0: 20 20 20 20 20 20 20 20 2f 2a 20 78 43 6f 6c 75          /* xColu
82e0: 6d 6e 20 2d 20 72 65 61 64 20 64 61 74 61 20 2a  mn - read data *
82f0: 2f 0a 20 20 65 63 68 6f 52 6f 77 69 64 2c 20 20  /.  echoRowid,  
8300: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
8310: 2a 20 78 52 6f 77 69 64 20 2d 20 72 65 61 64 20  * xRowid - read 
8320: 64 61 74 61 20 2a 2f 0a 20 20 65 63 68 6f 55 70  data */.  echoUp
8330: 64 61 74 65 2c 20 20 20 20 20 20 20 20 20 20 20  date,           
8340: 20 20 20 20 20 2f 2a 20 78 55 70 64 61 74 65 20       /* xUpdate 
8350: 2d 20 77 72 69 74 65 20 64 61 74 61 20 2a 2f 0a  - write data */.
8360: 20 20 65 63 68 6f 42 65 67 69 6e 2c 20 20 20 20    echoBegin,    
8370: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
8380: 78 42 65 67 69 6e 20 2d 20 62 65 67 69 6e 20 74  xBegin - begin t
8390: 72 61 6e 73 61 63 74 69 6f 6e 20 2a 2f 0a 20 20  ransaction */.  
83a0: 65 63 68 6f 53 79 6e 63 2c 20 20 20 20 20 20 20  echoSync,       
83b0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 53             /* xS
83c0: 79 6e 63 20 2d 20 73 79 6e 63 20 74 72 61 6e 73  ync - sync trans
83d0: 61 63 74 69 6f 6e 20 2a 2f 0a 20 20 65 63 68 6f  action */.  echo
83e0: 43 6f 6d 6d 69 74 2c 20 20 20 20 20 20 20 20 20  Commit,         
83f0: 20 20 20 20 20 20 20 2f 2a 20 78 43 6f 6d 6d 69         /* xCommi
8400: 74 20 2d 20 63 6f 6d 6d 69 74 20 74 72 61 6e 73  t - commit trans
8410: 61 63 74 69 6f 6e 20 2a 2f 0a 20 20 65 63 68 6f  action */.  echo
8420: 52 6f 6c 6c 62 61 63 6b 2c 20 20 20 20 20 20 20  Rollback,       
8430: 20 20 20 20 20 20 20 2f 2a 20 78 52 6f 6c 6c 62         /* xRollb
8440: 61 63 6b 20 2d 20 72 6f 6c 6c 62 61 63 6b 20 74  ack - rollback t
8450: 72 61 6e 73 61 63 74 69 6f 6e 20 2a 2f 0a 20 20  ransaction */.  
8460: 65 63 68 6f 46 69 6e 64 46 75 6e 63 74 69 6f 6e  echoFindFunction
8470: 2c 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 46  ,          /* xF
8480: 69 6e 64 46 75 6e 63 74 69 6f 6e 20 2d 20 66 75  indFunction - fu
8490: 6e 63 74 69 6f 6e 20 6f 76 65 72 6c 6f 61 64 69  nction overloadi
84a0: 6e 67 20 2a 2f 0a 20 20 65 63 68 6f 52 65 6e 61  ng */.  echoRena
84b0: 6d 65 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  me,             
84c0: 20 20 20 2f 2a 20 78 52 65 6e 61 6d 65 20 2d 20     /* xRename - 
84d0: 72 65 6e 61 6d 65 20 74 68 65 20 74 61 62 6c 65  rename the table
84e0: 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 44 65   */.};../*.** De
84f0: 63 6f 64 65 20 61 20 70 6f 69 6e 74 65 72 20 74  code a pointer t
8500: 6f 20 61 6e 20 73 71 6c 69 74 65 33 20 6f 62 6a  o an sqlite3 obj
8510: 65 63 74 2e 0a 2a 2f 0a 65 78 74 65 72 6e 20 69  ect..*/.extern i
8520: 6e 74 20 67 65 74 44 62 50 6f 69 6e 74 65 72 28  nt getDbPointer(
8530: 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65  Tcl_Interp *inte
8540: 72 70 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a  rp, const char *
8550: 7a 41 2c 20 73 71 6c 69 74 65 33 20 2a 2a 70 70  zA, sqlite3 **pp
8560: 44 62 29 3b 0a 0a 73 74 61 74 69 63 20 76 6f 69  Db);..static voi
8570: 64 20 6d 6f 64 75 6c 65 44 65 73 74 72 6f 79 28  d moduleDestroy(
8580: 76 6f 69 64 20 2a 70 29 7b 0a 20 20 73 71 6c 69  void *p){.  sqli
8590: 74 65 33 5f 66 72 65 65 28 70 29 3b 0a 7d 0a 0a  te3_free(p);.}..
85a0: 2f 2a 0a 2a 2a 20 52 65 67 69 73 74 65 72 20 74  /*.** Register t
85b0: 68 65 20 65 63 68 6f 20 76 69 72 74 75 61 6c 20  he echo virtual 
85c0: 74 61 62 6c 65 20 6d 6f 64 75 6c 65 2e 0a 2a 2f  table module..*/
85d0: 0a 73 74 61 74 69 63 20 69 6e 74 20 72 65 67 69  .static int regi
85e0: 73 74 65 72 5f 65 63 68 6f 5f 6d 6f 64 75 6c 65  ster_echo_module
85f0: 28 0a 20 20 43 6c 69 65 6e 74 44 61 74 61 20 63  (.  ClientData c
8600: 6c 69 65 6e 74 44 61 74 61 2c 20 2f 2a 20 50 6f  lientData, /* Po
8610: 69 6e 74 65 72 20 74 6f 20 73 71 6c 69 74 65 33  inter to sqlite3
8620: 5f 65 6e 61 62 6c 65 5f 58 58 58 20 66 75 6e 63  _enable_XXX func
8630: 74 69 6f 6e 20 2a 2f 0a 20 20 54 63 6c 5f 49 6e  tion */.  Tcl_In
8640: 74 65 72 70 20 2a 69 6e 74 65 72 70 2c 20 20 20  terp *interp,   
8650: 20 2f 2a 20 54 68 65 20 54 43 4c 20 69 6e 74 65   /* The TCL inte
8660: 72 70 72 65 74 65 72 20 74 68 61 74 20 69 6e 76  rpreter that inv
8670: 6f 6b 65 64 20 74 68 69 73 20 63 6f 6d 6d 61 6e  oked this comman
8680: 64 20 2a 2f 0a 20 20 69 6e 74 20 6f 62 6a 63 2c  d */.  int objc,
8690: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
86a0: 20 4e 75 6d 62 65 72 20 6f 66 20 61 72 67 75 6d   Number of argum
86b0: 65 6e 74 73 20 2a 2f 0a 20 20 54 63 6c 5f 4f 62  ents */.  Tcl_Ob
86c0: 6a 20 2a 43 4f 4e 53 54 20 6f 62 6a 76 5b 5d 20  j *CONST objv[] 
86d0: 20 2f 2a 20 43 6f 6d 6d 61 6e 64 20 61 72 67 75   /* Command argu
86e0: 6d 65 6e 74 73 20 2a 2f 0a 29 7b 0a 20 20 73 71  ments */.){.  sq
86f0: 6c 69 74 65 33 20 2a 64 62 3b 0a 20 20 45 63 68  lite3 *db;.  Ech
8700: 6f 4d 6f 64 75 6c 65 20 2a 70 4d 6f 64 3b 0a 20  oModule *pMod;. 
8710: 20 69 66 28 20 6f 62 6a 63 21 3d 32 20 29 7b 0a   if( objc!=2 ){.
8720: 20 20 20 20 54 63 6c 5f 57 72 6f 6e 67 4e 75 6d      Tcl_WrongNum
8730: 41 72 67 73 28 69 6e 74 65 72 70 2c 20 31 2c 20  Args(interp, 1, 
8740: 6f 62 6a 76 2c 20 22 44 42 22 29 3b 0a 20 20 20  objv, "DB");.   
8750: 20 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f   return TCL_ERRO
8760: 52 3b 0a 20 20 7d 0a 20 20 69 66 28 20 67 65 74  R;.  }.  if( get
8770: 44 62 50 6f 69 6e 74 65 72 28 69 6e 74 65 72 70  DbPointer(interp
8780: 2c 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 28  , Tcl_GetString(
8790: 6f 62 6a 76 5b 31 5d 29 2c 20 26 64 62 29 20 29  objv[1]), &db) )
87a0: 20 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f   return TCL_ERRO
87b0: 52 3b 0a 20 20 70 4d 6f 64 20 3d 20 73 71 6c 69  R;.  pMod = sqli
87c0: 74 65 33 5f 6d 61 6c 6c 6f 63 28 73 69 7a 65 6f  te3_malloc(sizeo
87d0: 66 28 45 63 68 6f 4d 6f 64 75 6c 65 29 29 3b 0a  f(EchoModule));.
87e0: 20 20 70 4d 6f 64 2d 3e 69 6e 74 65 72 70 20 3d    pMod->interp =
87f0: 20 69 6e 74 65 72 70 3b 0a 20 20 73 71 6c 69 74   interp;.  sqlit
8800: 65 33 5f 63 72 65 61 74 65 5f 6d 6f 64 75 6c 65  e3_create_module
8810: 5f 76 32 28 64 62 2c 20 22 65 63 68 6f 22 2c 20  _v2(db, "echo", 
8820: 26 65 63 68 6f 4d 6f 64 75 6c 65 2c 20 28 76 6f  &echoModule, (vo
8830: 69 64 2a 29 70 4d 6f 64 2c 20 6d 6f 64 75 6c 65  id*)pMod, module
8840: 44 65 73 74 72 6f 79 29 3b 0a 20 20 72 65 74 75  Destroy);.  retu
8850: 72 6e 20 54 43 4c 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a  rn TCL_OK;.}../*
8860: 0a 2a 2a 20 54 63 6c 20 69 6e 74 65 72 66 61 63  .** Tcl interfac
8870: 65 20 74 6f 20 73 71 6c 69 74 65 33 5f 64 65 63  e to sqlite3_dec
8880: 6c 61 72 65 5f 76 74 61 62 2c 20 69 6e 76 6f 6b  lare_vtab, invok
8890: 65 64 20 61 73 20 66 6f 6c 6c 6f 77 73 20 66 72  ed as follows fr
88a0: 6f 6d 20 54 63 6c 3a 0a 2a 2a 0a 2a 2a 20 73 71  om Tcl:.**.** sq
88b0: 6c 69 74 65 33 5f 64 65 63 6c 61 72 65 5f 76 74  lite3_declare_vt
88c0: 61 62 20 44 42 20 53 51 4c 0a 2a 2f 0a 73 74 61  ab DB SQL.*/.sta
88d0: 74 69 63 20 69 6e 74 20 64 65 63 6c 61 72 65 5f  tic int declare_
88e0: 76 74 61 62 28 0a 20 20 43 6c 69 65 6e 74 44 61  vtab(.  ClientDa
88f0: 74 61 20 63 6c 69 65 6e 74 44 61 74 61 2c 20 2f  ta clientData, /
8900: 2a 20 50 6f 69 6e 74 65 72 20 74 6f 20 73 71 6c  * Pointer to sql
8910: 69 74 65 33 5f 65 6e 61 62 6c 65 5f 58 58 58 20  ite3_enable_XXX 
8920: 66 75 6e 63 74 69 6f 6e 20 2a 2f 0a 20 20 54 63  function */.  Tc
8930: 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70  l_Interp *interp
8940: 2c 20 20 20 20 2f 2a 20 54 68 65 20 54 43 4c 20  ,    /* The TCL 
8950: 69 6e 74 65 72 70 72 65 74 65 72 20 74 68 61 74  interpreter that
8960: 20 69 6e 76 6f 6b 65 64 20 74 68 69 73 20 63 6f   invoked this co
8970: 6d 6d 61 6e 64 20 2a 2f 0a 20 20 69 6e 74 20 6f  mmand */.  int o
8980: 62 6a 63 2c 20 20 20 20 20 20 20 20 20 20 20 20  bjc,            
8990: 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 61    /* Number of a
89a0: 72 67 75 6d 65 6e 74 73 20 2a 2f 0a 20 20 54 63  rguments */.  Tc
89b0: 6c 5f 4f 62 6a 20 2a 43 4f 4e 53 54 20 6f 62 6a  l_Obj *CONST obj
89c0: 76 5b 5d 20 20 2f 2a 20 43 6f 6d 6d 61 6e 64 20  v[]  /* Command 
89d0: 61 72 67 75 6d 65 6e 74 73 20 2a 2f 0a 29 7b 0a  arguments */.){.
89e0: 20 20 73 71 6c 69 74 65 33 20 2a 64 62 3b 0a 20    sqlite3 *db;. 
89f0: 20 69 6e 74 20 72 63 3b 0a 20 20 69 66 28 20 6f   int rc;.  if( o
8a00: 62 6a 63 21 3d 33 20 29 7b 0a 20 20 20 20 54 63  bjc!=3 ){.    Tc
8a10: 6c 5f 57 72 6f 6e 67 4e 75 6d 41 72 67 73 28 69  l_WrongNumArgs(i
8a20: 6e 74 65 72 70 2c 20 31 2c 20 6f 62 6a 76 2c 20  nterp, 1, objv, 
8a30: 22 44 42 20 53 51 4c 22 29 3b 0a 20 20 20 20 72  "DB SQL");.    r
8a40: 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b  eturn TCL_ERROR;
8a50: 0a 20 20 7d 0a 20 20 69 66 28 20 67 65 74 44 62  .  }.  if( getDb
8a60: 50 6f 69 6e 74 65 72 28 69 6e 74 65 72 70 2c 20  Pointer(interp, 
8a70: 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 28 6f 62  Tcl_GetString(ob
8a80: 6a 76 5b 31 5d 29 2c 20 26 64 62 29 20 29 20 72  jv[1]), &db) ) r
8a90: 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b  eturn TCL_ERROR;
8aa0: 0a 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f  .  rc = sqlite3_
8ab0: 64 65 63 6c 61 72 65 5f 76 74 61 62 28 64 62 2c  declare_vtab(db,
8ac0: 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 28 6f   Tcl_GetString(o
8ad0: 62 6a 76 5b 32 5d 29 29 3b 0a 20 20 69 66 28 20  bjv[2]));.  if( 
8ae0: 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc!=SQLITE_OK ){
8af0: 0a 20 20 20 20 54 63 6c 5f 53 65 74 52 65 73 75  .    Tcl_SetResu
8b00: 6c 74 28 69 6e 74 65 72 70 2c 20 28 63 68 61 72  lt(interp, (char
8b10: 20 2a 29 73 71 6c 69 74 65 33 5f 65 72 72 6d 73   *)sqlite3_errms
8b20: 67 28 64 62 29 2c 20 54 43 4c 5f 56 4f 4c 41 54  g(db), TCL_VOLAT
8b30: 49 4c 45 29 3b 0a 20 20 20 20 72 65 74 75 72 6e  ILE);.    return
8b40: 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a   TCL_ERROR;.  }.
8b50: 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 4f 4b 3b    return TCL_OK;
8b60: 0a 7d 0a 0a 23 65 6e 64 69 66 20 2f 2a 20 69 66  .}..#endif /* if
8b70: 6e 64 65 66 20 53 51 4c 49 54 45 5f 4f 4d 49 54  ndef SQLITE_OMIT
8b80: 5f 56 49 52 54 55 41 4c 54 41 42 4c 45 20 2a 2f  _VIRTUALTABLE */
8b90: 0a 0a 2f 2a 0a 2a 2a 20 52 65 67 69 73 74 65 72  ../*.** Register
8ba0: 20 63 6f 6d 6d 61 6e 64 73 20 77 69 74 68 20 74   commands with t
8bb0: 68 65 20 54 43 4c 20 69 6e 74 65 72 70 72 65 74  he TCL interpret
8bc0: 65 72 2e 0a 2a 2f 0a 69 6e 74 20 53 71 6c 69 74  er..*/.int Sqlit
8bd0: 65 74 65 73 74 38 5f 49 6e 69 74 28 54 63 6c 5f  etest8_Init(Tcl_
8be0: 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 29 7b  Interp *interp){
8bf0: 0a 20 20 73 74 61 74 69 63 20 73 74 72 75 63 74  .  static struct
8c00: 20 7b 0a 20 20 20 20 20 63 68 61 72 20 2a 7a 4e   {.     char *zN
8c10: 61 6d 65 3b 0a 20 20 20 20 20 54 63 6c 5f 4f 62  ame;.     Tcl_Ob
8c20: 6a 43 6d 64 50 72 6f 63 20 2a 78 50 72 6f 63 3b  jCmdProc *xProc;
8c30: 0a 20 20 20 20 20 76 6f 69 64 20 2a 63 6c 69 65  .     void *clie
8c40: 6e 74 44 61 74 61 3b 0a 20 20 7d 20 61 4f 62 6a  ntData;.  } aObj
8c50: 43 6d 64 5b 5d 20 3d 20 7b 0a 23 69 66 6e 64 65  Cmd[] = {.#ifnde
8c60: 66 20 53 51 4c 49 54 45 5f 4f 4d 49 54 5f 56 49  f SQLITE_OMIT_VI
8c70: 52 54 55 41 4c 54 41 42 4c 45 0a 20 20 20 20 20  RTUALTABLE.     
8c80: 7b 20 22 72 65 67 69 73 74 65 72 5f 65 63 68 6f  { "register_echo
8c90: 5f 6d 6f 64 75 6c 65 22 2c 20 20 20 72 65 67 69  _module",   regi
8ca0: 73 74 65 72 5f 65 63 68 6f 5f 6d 6f 64 75 6c 65  ster_echo_module
8cb0: 2c 20 30 20 7d 2c 0a 20 20 20 20 20 7b 20 22 73  , 0 },.     { "s
8cc0: 71 6c 69 74 65 33 5f 64 65 63 6c 61 72 65 5f 76  qlite3_declare_v
8cd0: 74 61 62 22 2c 20 20 20 64 65 63 6c 61 72 65 5f  tab",   declare_
8ce0: 76 74 61 62 2c 20 30 20 7d 2c 0a 23 65 6e 64 69  vtab, 0 },.#endi
8cf0: 66 0a 20 20 7d 3b 0a 20 20 69 6e 74 20 69 3b 0a  f.  };.  int i;.
8d00: 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 73 69 7a    for(i=0; i<siz
8d10: 65 6f 66 28 61 4f 62 6a 43 6d 64 29 2f 73 69 7a  eof(aObjCmd)/siz
8d20: 65 6f 66 28 61 4f 62 6a 43 6d 64 5b 30 5d 29 3b  eof(aObjCmd[0]);
8d30: 20 69 2b 2b 29 7b 0a 20 20 20 20 54 63 6c 5f 43   i++){.    Tcl_C
8d40: 72 65 61 74 65 4f 62 6a 43 6f 6d 6d 61 6e 64 28  reateObjCommand(
8d50: 69 6e 74 65 72 70 2c 20 61 4f 62 6a 43 6d 64 5b  interp, aObjCmd[
8d60: 69 5d 2e 7a 4e 61 6d 65 2c 20 0a 20 20 20 20 20  i].zName, .     
8d70: 20 20 20 61 4f 62 6a 43 6d 64 5b 69 5d 2e 78 50     aObjCmd[i].xP
8d80: 72 6f 63 2c 20 61 4f 62 6a 43 6d 64 5b 69 5d 2e  roc, aObjCmd[i].
8d90: 63 6c 69 65 6e 74 44 61 74 61 2c 20 30 29 3b 0a  clientData, 0);.
8da0: 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 54 43 4c    }.  return TCL
8db0: 5f 4f 4b 3b 0a 7d 0a                             _OK;.}.