/ Hex Artifact Content
Login

Artifact cc541736127cb95fe6966120f546c051e1c8aed8:


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 38 20 32  test8.c,v 1.68 2
0230: 30 30 38 2f 30 37 2f 32 33 20 31 38 3a 31 37 3a  008/07/23 18:17:
0240: 33 32 20 64 72 68 20 45 78 70 20 24 0a 2a 2f 0a  32 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 53 74 72 44 75 70 28 73 71 6c  qlite3StrDup(sql
33b0: 69 74 65 33 5f 65 72 72 6d 73 67 28 64 62 29 29  ite3_errmsg(db))
33c0: 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 69  ;.    }.  }..  i
33d0: 66 28 20 2a 70 70 56 74 61 62 20 26 26 20 72 63  f( *ppVtab && rc
33e0: 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  !=SQLITE_OK ){. 
33f0: 20 20 20 65 63 68 6f 44 65 73 74 72 75 63 74 6f     echoDestructo
3400: 72 28 2a 70 70 56 74 61 62 29 3b 0a 20 20 20 20  r(*ppVtab);.    
3410: 2a 70 70 56 74 61 62 20 3d 20 30 3b 0a 20 20 7d  *ppVtab = 0;.  }
3420: 0a 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49  ..  if( rc==SQLI
3430: 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 28 2a 28  TE_OK ){.    (*(
3440: 65 63 68 6f 5f 76 74 61 62 2a 2a 29 70 70 56 74  echo_vtab**)ppVt
3450: 61 62 29 2d 3e 69 6e 54 72 61 6e 73 61 63 74 69  ab)->inTransacti
3460: 6f 6e 20 3d 20 31 3b 0a 20 20 7d 0a 0a 20 20 72  on = 1;.  }..  r
3470: 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 20  eturn rc;.}../* 
3480: 0a 2a 2a 20 45 63 68 6f 20 76 69 72 74 75 61 6c  .** Echo virtual
3490: 20 74 61 62 6c 65 20 6d 6f 64 75 6c 65 20 78 43   table module xC
34a0: 6f 6e 6e 65 63 74 20 6d 65 74 68 6f 64 2e 0a 2a  onnect method..*
34b0: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 65 63 68  /.static int ech
34c0: 6f 43 6f 6e 6e 65 63 74 28 0a 20 20 73 71 6c 69  oConnect(.  sqli
34d0: 74 65 33 20 2a 64 62 2c 0a 20 20 76 6f 69 64 20  te3 *db,.  void 
34e0: 2a 70 41 75 78 2c 0a 20 20 69 6e 74 20 61 72 67  *pAux,.  int arg
34f0: 63 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 63  c, const char *c
3500: 6f 6e 73 74 2a 61 72 67 76 2c 0a 20 20 73 71 6c  onst*argv,.  sql
3510: 69 74 65 33 5f 76 74 61 62 20 2a 2a 70 70 56 74  ite3_vtab **ppVt
3520: 61 62 2c 0a 20 20 63 68 61 72 20 2a 2a 70 7a 45  ab,.  char **pzE
3530: 72 72 0a 29 7b 0a 20 20 61 70 70 65 6e 64 54 6f  rr.){.  appendTo
3540: 45 63 68 6f 4d 6f 64 75 6c 65 28 28 28 45 63 68  EchoModule(((Ech
3550: 6f 4d 6f 64 75 6c 65 20 2a 29 70 41 75 78 29 2d  oModule *)pAux)-
3560: 3e 69 6e 74 65 72 70 2c 20 22 78 43 6f 6e 6e 65  >interp, "xConne
3570: 63 74 22 29 3b 0a 20 20 72 65 74 75 72 6e 20 65  ct");.  return e
3580: 63 68 6f 43 6f 6e 73 74 72 75 63 74 6f 72 28 64  choConstructor(d
3590: 62 2c 20 70 41 75 78 2c 20 61 72 67 63 2c 20 61  b, pAux, argc, a
35a0: 72 67 76 2c 20 70 70 56 74 61 62 2c 20 70 7a 45  rgv, ppVtab, pzE
35b0: 72 72 29 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 45  rr);.}../* .** E
35c0: 63 68 6f 20 76 69 72 74 75 61 6c 20 74 61 62 6c  cho virtual tabl
35d0: 65 20 6d 6f 64 75 6c 65 20 78 44 69 73 63 6f 6e  e module xDiscon
35e0: 6e 65 63 74 20 6d 65 74 68 6f 64 2e 0a 2a 2f 0a  nect method..*/.
35f0: 73 74 61 74 69 63 20 69 6e 74 20 65 63 68 6f 44  static int echoD
3600: 69 73 63 6f 6e 6e 65 63 74 28 73 71 6c 69 74 65  isconnect(sqlite
3610: 33 5f 76 74 61 62 20 2a 70 56 74 61 62 29 7b 0a  3_vtab *pVtab){.
3620: 20 20 61 70 70 65 6e 64 54 6f 45 63 68 6f 4d 6f    appendToEchoMo
3630: 64 75 6c 65 28 28 28 65 63 68 6f 5f 76 74 61 62  dule(((echo_vtab
3640: 20 2a 29 70 56 74 61 62 29 2d 3e 69 6e 74 65 72   *)pVtab)->inter
3650: 70 2c 20 22 78 44 69 73 63 6f 6e 6e 65 63 74 22  p, "xDisconnect"
3660: 29 3b 0a 20 20 72 65 74 75 72 6e 20 65 63 68 6f  );.  return echo
3670: 44 65 73 74 72 75 63 74 6f 72 28 70 56 74 61 62  Destructor(pVtab
3680: 29 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 45 63 68  );.}../* .** Ech
3690: 6f 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65 20  o virtual table 
36a0: 6d 6f 64 75 6c 65 20 78 44 65 73 74 72 6f 79 20  module xDestroy 
36b0: 6d 65 74 68 6f 64 2e 0a 2a 2f 0a 73 74 61 74 69  method..*/.stati
36c0: 63 20 69 6e 74 20 65 63 68 6f 44 65 73 74 72 6f  c int echoDestro
36d0: 79 28 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a  y(sqlite3_vtab *
36e0: 70 56 74 61 62 29 7b 0a 20 20 69 6e 74 20 72 63  pVtab){.  int rc
36f0: 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20   = SQLITE_OK;.  
3700: 65 63 68 6f 5f 76 74 61 62 20 2a 70 20 3d 20 28  echo_vtab *p = (
3710: 65 63 68 6f 5f 76 74 61 62 20 2a 29 70 56 74 61  echo_vtab *)pVta
3720: 62 3b 0a 20 20 61 70 70 65 6e 64 54 6f 45 63 68  b;.  appendToEch
3730: 6f 4d 6f 64 75 6c 65 28 28 28 65 63 68 6f 5f 76  oModule(((echo_v
3740: 74 61 62 20 2a 29 70 56 74 61 62 29 2d 3e 69 6e  tab *)pVtab)->in
3750: 74 65 72 70 2c 20 22 78 44 65 73 74 72 6f 79 22  terp, "xDestroy"
3760: 29 3b 0a 0a 20 20 2f 2a 20 44 72 6f 70 20 74 68  );..  /* Drop th
3770: 65 20 22 6c 6f 67 22 20 74 61 62 6c 65 2c 20 69  e "log" table, i
3780: 66 20 6f 6e 65 20 65 78 69 73 74 73 20 28 73 65  f one exists (se
3790: 65 20 65 63 68 6f 43 72 65 61 74 65 28 29 20 66  e echoCreate() f
37a0: 6f 72 20 64 65 74 61 69 6c 73 29 20 2a 2f 0a 20  or details) */. 
37b0: 20 69 66 28 20 70 20 26 26 20 70 2d 3e 7a 4c 6f   if( p && p->zLo
37c0: 67 4e 61 6d 65 20 29 7b 0a 20 20 20 20 63 68 61  gName ){.    cha
37d0: 72 20 2a 7a 53 71 6c 3b 0a 20 20 20 20 7a 53 71  r *zSql;.    zSq
37e0: 6c 20 3d 20 73 71 6c 69 74 65 33 4d 50 72 69 6e  l = sqlite3MPrin
37f0: 74 66 28 30 2c 20 22 44 52 4f 50 20 54 41 42 4c  tf(0, "DROP TABL
3800: 45 20 25 51 22 2c 20 70 2d 3e 7a 4c 6f 67 4e 61  E %Q", p->zLogNa
3810: 6d 65 29 3b 0a 20 20 20 20 72 63 20 3d 20 73 71  me);.    rc = sq
3820: 6c 69 74 65 33 5f 65 78 65 63 28 70 2d 3e 64 62  lite3_exec(p->db
3830: 2c 20 7a 53 71 6c 2c 20 30 2c 20 30 2c 20 30 29  , zSql, 0, 0, 0)
3840: 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72  ;.    sqlite3_fr
3850: 65 65 28 7a 53 71 6c 29 3b 0a 20 20 7d 0a 0a 20  ee(zSql);.  }.. 
3860: 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
3870: 4f 4b 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 65  OK ){.    rc = e
3880: 63 68 6f 44 65 73 74 72 75 63 74 6f 72 28 70 56  choDestructor(pV
3890: 74 61 62 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75  tab);.  }.  retu
38a0: 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a  rn rc;.}../* .**
38b0: 20 45 63 68 6f 20 76 69 72 74 75 61 6c 20 74 61   Echo virtual ta
38c0: 62 6c 65 20 6d 6f 64 75 6c 65 20 78 4f 70 65 6e  ble module xOpen
38d0: 20 6d 65 74 68 6f 64 2e 0a 2a 2f 0a 73 74 61 74   method..*/.stat
38e0: 69 63 20 69 6e 74 20 65 63 68 6f 4f 70 65 6e 28  ic int echoOpen(
38f0: 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 70 56  sqlite3_vtab *pV
3900: 54 61 62 2c 20 73 71 6c 69 74 65 33 5f 76 74 61  Tab, sqlite3_vta
3910: 62 5f 63 75 72 73 6f 72 20 2a 2a 70 70 43 75 72  b_cursor **ppCur
3920: 73 6f 72 29 7b 0a 20 20 65 63 68 6f 5f 63 75 72  sor){.  echo_cur
3930: 73 6f 72 20 2a 70 43 75 72 3b 0a 20 20 70 43 75  sor *pCur;.  pCu
3940: 72 20 3d 20 73 71 6c 69 74 65 33 4d 61 6c 6c 6f  r = sqlite3Mallo
3950: 63 5a 65 72 6f 28 73 69 7a 65 6f 66 28 65 63 68  cZero(sizeof(ech
3960: 6f 5f 63 75 72 73 6f 72 29 29 3b 0a 20 20 2a 70  o_cursor));.  *p
3970: 70 43 75 72 73 6f 72 20 3d 20 28 73 71 6c 69 74  pCursor = (sqlit
3980: 65 33 5f 76 74 61 62 5f 63 75 72 73 6f 72 20 2a  e3_vtab_cursor *
3990: 29 70 43 75 72 3b 0a 20 20 72 65 74 75 72 6e 20  )pCur;.  return 
39a0: 28 70 43 75 72 20 3f 20 53 51 4c 49 54 45 5f 4f  (pCur ? SQLITE_O
39b0: 4b 20 3a 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d  K : SQLITE_NOMEM
39c0: 29 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 45 63 68  );.}../* .** Ech
39d0: 6f 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65 20  o virtual table 
39e0: 6d 6f 64 75 6c 65 20 78 43 6c 6f 73 65 20 6d 65  module xClose me
39f0: 74 68 6f 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  thod..*/.static 
3a00: 69 6e 74 20 65 63 68 6f 43 6c 6f 73 65 28 73 71  int echoClose(sq
3a10: 6c 69 74 65 33 5f 76 74 61 62 5f 63 75 72 73 6f  lite3_vtab_curso
3a20: 72 20 2a 63 75 72 29 7b 0a 20 20 69 6e 74 20 72  r *cur){.  int r
3a30: 63 3b 0a 20 20 65 63 68 6f 5f 63 75 72 73 6f 72  c;.  echo_cursor
3a40: 20 2a 70 43 75 72 20 3d 20 28 65 63 68 6f 5f 63   *pCur = (echo_c
3a50: 75 72 73 6f 72 20 2a 29 63 75 72 3b 0a 20 20 73  ursor *)cur;.  s
3a60: 71 6c 69 74 65 33 5f 73 74 6d 74 20 2a 70 53 74  qlite3_stmt *pSt
3a70: 6d 74 20 3d 20 70 43 75 72 2d 3e 70 53 74 6d 74  mt = pCur->pStmt
3a80: 3b 0a 20 20 70 43 75 72 2d 3e 70 53 74 6d 74 20  ;.  pCur->pStmt 
3a90: 3d 20 30 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66  = 0;.  sqlite3_f
3aa0: 72 65 65 28 70 43 75 72 29 3b 0a 20 20 72 63 20  ree(pCur);.  rc 
3ab0: 3d 20 73 71 6c 69 74 65 33 5f 66 69 6e 61 6c 69  = sqlite3_finali
3ac0: 7a 65 28 70 53 74 6d 74 29 3b 0a 20 20 72 65 74  ze(pStmt);.  ret
3ad0: 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  urn rc;.}../*.**
3ae0: 20 52 65 74 75 72 6e 20 6e 6f 6e 2d 7a 65 72 6f   Return non-zero
3af0: 20 69 66 20 74 68 65 20 63 75 72 73 6f 72 20 64   if the cursor d
3b00: 6f 65 73 20 6e 6f 74 20 63 75 72 72 65 6e 74 6c  oes not currentl
3b10: 79 20 70 6f 69 6e 74 20 74 6f 20 61 20 76 61 6c  y point to a val
3b20: 69 64 20 72 65 63 6f 72 64 0a 2a 2a 20 28 69 2e  id record.** (i.
3b30: 65 20 69 66 20 74 68 65 20 73 63 61 6e 20 68 61  e if the scan ha
3b40: 73 20 66 69 6e 69 73 68 65 64 29 2c 20 6f 72 20  s finished), or 
3b50: 7a 65 72 6f 20 6f 74 68 65 72 77 69 73 65 2e 0a  zero otherwise..
3b60: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 65 63  */.static int ec
3b70: 68 6f 45 6f 66 28 73 71 6c 69 74 65 33 5f 76 74  hoEof(sqlite3_vt
3b80: 61 62 5f 63 75 72 73 6f 72 20 2a 63 75 72 29 7b  ab_cursor *cur){
3b90: 0a 20 20 72 65 74 75 72 6e 20 28 28 28 65 63 68  .  return (((ech
3ba0: 6f 5f 63 75 72 73 6f 72 20 2a 29 63 75 72 29 2d  o_cursor *)cur)-
3bb0: 3e 70 53 74 6d 74 20 3f 20 30 20 3a 20 31 29 3b  >pStmt ? 0 : 1);
3bc0: 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 45 63 68 6f 20  .}../* .** Echo 
3bd0: 76 69 72 74 75 61 6c 20 74 61 62 6c 65 20 6d 6f  virtual table mo
3be0: 64 75 6c 65 20 78 4e 65 78 74 20 6d 65 74 68 6f  dule xNext metho
3bf0: 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  d..*/.static int
3c00: 20 65 63 68 6f 4e 65 78 74 28 73 71 6c 69 74 65   echoNext(sqlite
3c10: 33 5f 76 74 61 62 5f 63 75 72 73 6f 72 20 2a 63  3_vtab_cursor *c
3c20: 75 72 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20  ur){.  int rc = 
3c30: 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 65 63 68  SQLITE_OK;.  ech
3c40: 6f 5f 63 75 72 73 6f 72 20 2a 70 43 75 72 20 3d  o_cursor *pCur =
3c50: 20 28 65 63 68 6f 5f 63 75 72 73 6f 72 20 2a 29   (echo_cursor *)
3c60: 63 75 72 3b 0a 0a 20 20 69 66 28 20 70 43 75 72  cur;..  if( pCur
3c70: 2d 3e 70 53 74 6d 74 20 29 7b 0a 20 20 20 20 72  ->pStmt ){.    r
3c80: 63 20 3d 20 73 71 6c 69 74 65 33 5f 73 74 65 70  c = sqlite3_step
3c90: 28 70 43 75 72 2d 3e 70 53 74 6d 74 29 3b 0a 20  (pCur->pStmt);. 
3ca0: 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54     if( rc==SQLIT
3cb0: 45 5f 52 4f 57 20 29 7b 0a 20 20 20 20 20 20 72  E_ROW ){.      r
3cc0: 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20  c = SQLITE_OK;. 
3cd0: 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20     }else{.      
3ce0: 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 66 69 6e  rc = sqlite3_fin
3cf0: 61 6c 69 7a 65 28 70 43 75 72 2d 3e 70 53 74 6d  alize(pCur->pStm
3d00: 74 29 3b 0a 20 20 20 20 20 20 70 43 75 72 2d 3e  t);.      pCur->
3d10: 70 53 74 6d 74 20 3d 20 30 3b 0a 20 20 20 20 7d  pStmt = 0;.    }
3d20: 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 72  .  }..  return r
3d30: 63 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 45 63 68  c;.}../* .** Ech
3d40: 6f 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65 20  o virtual table 
3d50: 6d 6f 64 75 6c 65 20 78 43 6f 6c 75 6d 6e 20 6d  module xColumn m
3d60: 65 74 68 6f 64 2e 0a 2a 2f 0a 73 74 61 74 69 63  ethod..*/.static
3d70: 20 69 6e 74 20 65 63 68 6f 43 6f 6c 75 6d 6e 28   int echoColumn(
3d80: 73 71 6c 69 74 65 33 5f 76 74 61 62 5f 63 75 72  sqlite3_vtab_cur
3d90: 73 6f 72 20 2a 63 75 72 2c 20 73 71 6c 69 74 65  sor *cur, sqlite
3da0: 33 5f 63 6f 6e 74 65 78 74 20 2a 63 74 78 2c 20  3_context *ctx, 
3db0: 69 6e 74 20 69 29 7b 0a 20 20 69 6e 74 20 69 43  int i){.  int iC
3dc0: 6f 6c 20 3d 20 69 20 2b 20 31 3b 0a 20 20 73 71  ol = i + 1;.  sq
3dd0: 6c 69 74 65 33 5f 73 74 6d 74 20 2a 70 53 74 6d  lite3_stmt *pStm
3de0: 74 20 3d 20 28 28 65 63 68 6f 5f 63 75 72 73 6f  t = ((echo_curso
3df0: 72 20 2a 29 63 75 72 29 2d 3e 70 53 74 6d 74 3b  r *)cur)->pStmt;
3e00: 0a 20 20 69 66 28 20 21 70 53 74 6d 74 20 29 7b  .  if( !pStmt ){
3e10: 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 72 65 73  .    sqlite3_res
3e20: 75 6c 74 5f 6e 75 6c 6c 28 63 74 78 29 3b 0a 20  ult_null(ctx);. 
3e30: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 61 73 73 65   }else{.    asse
3e40: 72 74 28 20 73 71 6c 69 74 65 33 5f 64 61 74 61  rt( sqlite3_data
3e50: 5f 63 6f 75 6e 74 28 70 53 74 6d 74 29 3e 69 43  _count(pStmt)>iC
3e60: 6f 6c 20 29 3b 0a 20 20 20 20 73 71 6c 69 74 65  ol );.    sqlite
3e70: 33 5f 72 65 73 75 6c 74 5f 76 61 6c 75 65 28 63  3_result_value(c
3e80: 74 78 2c 20 73 71 6c 69 74 65 33 5f 63 6f 6c 75  tx, sqlite3_colu
3e90: 6d 6e 5f 76 61 6c 75 65 28 70 53 74 6d 74 2c 20  mn_value(pStmt, 
3ea0: 69 43 6f 6c 29 29 3b 0a 20 20 7d 0a 20 20 72 65  iCol));.  }.  re
3eb0: 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a  turn SQLITE_OK;.
3ec0: 7d 0a 0a 2f 2a 20 0a 2a 2a 20 45 63 68 6f 20 76  }../* .** Echo v
3ed0: 69 72 74 75 61 6c 20 74 61 62 6c 65 20 6d 6f 64  irtual table mod
3ee0: 75 6c 65 20 78 52 6f 77 69 64 20 6d 65 74 68 6f  ule xRowid metho
3ef0: 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  d..*/.static int
3f00: 20 65 63 68 6f 52 6f 77 69 64 28 73 71 6c 69 74   echoRowid(sqlit
3f10: 65 33 5f 76 74 61 62 5f 63 75 72 73 6f 72 20 2a  e3_vtab_cursor *
3f20: 63 75 72 2c 20 73 71 6c 69 74 65 5f 69 6e 74 36  cur, sqlite_int6
3f30: 34 20 2a 70 52 6f 77 69 64 29 7b 0a 20 20 73 71  4 *pRowid){.  sq
3f40: 6c 69 74 65 33 5f 73 74 6d 74 20 2a 70 53 74 6d  lite3_stmt *pStm
3f50: 74 20 3d 20 28 28 65 63 68 6f 5f 63 75 72 73 6f  t = ((echo_curso
3f60: 72 20 2a 29 63 75 72 29 2d 3e 70 53 74 6d 74 3b  r *)cur)->pStmt;
3f70: 0a 20 20 2a 70 52 6f 77 69 64 20 3d 20 73 71 6c  .  *pRowid = sql
3f80: 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 69 6e 74 36  ite3_column_int6
3f90: 34 28 70 53 74 6d 74 2c 20 30 29 3b 0a 20 20 72  4(pStmt, 0);.  r
3fa0: 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b  eturn SQLITE_OK;
3fb0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 6f 6d 70 75 74  .}../*.** Comput
3fc0: 65 20 61 20 73 69 6d 70 6c 65 20 68 61 73 68 20  e a simple hash 
3fd0: 6f 66 20 74 68 65 20 6e 75 6c 6c 20 74 65 72 6d  of the null term
3fe0: 69 6e 61 74 65 64 20 73 74 72 69 6e 67 20 7a 53  inated string zS
3ff0: 74 72 69 6e 67 2e 0a 2a 2a 0a 2a 2a 20 54 68 69  tring..**.** Thi
4000: 73 20 6d 6f 64 75 6c 65 20 75 73 65 73 20 6f 6e  s module uses on
4010: 6c 79 20 73 71 6c 69 74 65 33 5f 69 6e 64 65 78  ly sqlite3_index
4020: 5f 69 6e 66 6f 2e 69 64 78 53 74 72 2c 20 6e 6f  _info.idxStr, no
4030: 74 20 0a 2a 2a 20 73 71 6c 69 74 65 33 5f 69 6e  t .** sqlite3_in
4040: 64 65 78 5f 69 6e 66 6f 2e 69 64 78 4e 75 6d 2e  dex_info.idxNum.
4050: 20 53 6f 20 74 6f 20 74 65 73 74 20 69 64 78 4e   So to test idxN
4060: 75 6d 2c 20 77 68 65 6e 20 69 64 78 53 74 72 20  um, when idxStr 
4070: 69 73 20 73 65 74 0a 2a 2a 20 69 6e 20 65 63 68  is set.** in ech
4080: 6f 42 65 73 74 49 6e 64 65 78 28 29 2c 20 69 64  oBestIndex(), id
4090: 78 4e 75 6d 20 69 73 20 73 65 74 20 74 6f 20 74  xNum is set to t
40a0: 68 65 20 63 6f 72 72 65 73 70 6f 6e 64 69 6e 67  he corresponding
40b0: 20 68 61 73 68 20 76 61 6c 75 65 2e 0a 2a 2a 20   hash value..** 
40c0: 49 6e 20 65 63 68 6f 46 69 6c 74 65 72 28 29 2c  In echoFilter(),
40d0: 20 63 6f 64 65 20 61 73 73 65 72 74 28 29 73 20   code assert()s 
40e0: 74 68 61 74 20 74 68 65 20 73 75 70 70 6c 69 65  that the supplie
40f0: 64 20 69 64 78 4e 75 6d 20 76 61 6c 75 65 20 69  d idxNum value i
4100: 73 0a 2a 2a 20 69 6e 64 65 65 64 20 74 68 65 20  s.** indeed the 
4110: 68 61 73 68 20 6f 66 20 74 68 65 20 73 75 70 70  hash of the supp
4120: 6c 69 65 64 20 69 64 78 53 74 72 2e 0a 2a 2f 0a  lied idxStr..*/.
4130: 73 74 61 74 69 63 20 69 6e 74 20 68 61 73 68 53  static int hashS
4140: 74 72 69 6e 67 28 63 6f 6e 73 74 20 63 68 61 72  tring(const char
4150: 20 2a 7a 53 74 72 69 6e 67 29 7b 0a 20 20 69 6e   *zString){.  in
4160: 74 20 76 61 6c 20 3d 20 30 3b 0a 20 20 69 6e 74  t val = 0;.  int
4170: 20 69 69 3b 0a 20 20 66 6f 72 28 69 69 3d 30 3b   ii;.  for(ii=0;
4180: 20 7a 53 74 72 69 6e 67 5b 69 69 5d 3b 20 69 69   zString[ii]; ii
4190: 2b 2b 29 7b 0a 20 20 20 20 76 61 6c 20 3d 20 28  ++){.    val = (
41a0: 76 61 6c 20 3c 3c 20 33 29 20 2b 20 28 69 6e 74  val << 3) + (int
41b0: 29 7a 53 74 72 69 6e 67 5b 69 69 5d 3b 0a 20 20  )zString[ii];.  
41c0: 7d 0a 20 20 72 65 74 75 72 6e 20 76 61 6c 3b 0a  }.  return val;.
41d0: 7d 0a 0a 2f 2a 20 0a 2a 2a 20 45 63 68 6f 20 76  }../* .** Echo v
41e0: 69 72 74 75 61 6c 20 74 61 62 6c 65 20 6d 6f 64  irtual table mod
41f0: 75 6c 65 20 78 46 69 6c 74 65 72 20 6d 65 74 68  ule xFilter meth
4200: 6f 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  od..*/.static in
4210: 74 20 65 63 68 6f 46 69 6c 74 65 72 28 0a 20 20  t echoFilter(.  
4220: 73 71 6c 69 74 65 33 5f 76 74 61 62 5f 63 75 72  sqlite3_vtab_cur
4230: 73 6f 72 20 2a 70 56 74 61 62 43 75 72 73 6f 72  sor *pVtabCursor
4240: 2c 20 0a 20 20 69 6e 74 20 69 64 78 4e 75 6d 2c  , .  int idxNum,
4250: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 69 64 78   const char *idx
4260: 53 74 72 2c 0a 20 20 69 6e 74 20 61 72 67 63 2c  Str,.  int argc,
4270: 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 20 2a   sqlite3_value *
4280: 2a 61 72 67 76 0a 29 7b 0a 20 20 69 6e 74 20 72  *argv.){.  int r
4290: 63 3b 0a 20 20 69 6e 74 20 69 3b 0a 0a 20 20 65  c;.  int i;..  e
42a0: 63 68 6f 5f 63 75 72 73 6f 72 20 2a 70 43 75 72  cho_cursor *pCur
42b0: 20 3d 20 28 65 63 68 6f 5f 63 75 72 73 6f 72 20   = (echo_cursor 
42c0: 2a 29 70 56 74 61 62 43 75 72 73 6f 72 3b 0a 20  *)pVtabCursor;. 
42d0: 20 65 63 68 6f 5f 76 74 61 62 20 2a 70 56 74 61   echo_vtab *pVta
42e0: 62 20 3d 20 28 65 63 68 6f 5f 76 74 61 62 20 2a  b = (echo_vtab *
42f0: 29 70 56 74 61 62 43 75 72 73 6f 72 2d 3e 70 56  )pVtabCursor->pV
4300: 74 61 62 3b 0a 20 20 73 71 6c 69 74 65 33 20 2a  tab;.  sqlite3 *
4310: 64 62 20 3d 20 70 56 74 61 62 2d 3e 64 62 3b 0a  db = pVtab->db;.
4320: 0a 20 20 2f 2a 20 43 68 65 63 6b 20 74 68 61 74  .  /* Check that
4330: 20 69 64 78 4e 75 6d 20 6d 61 74 63 68 65 73 20   idxNum matches 
4340: 69 64 78 53 74 72 20 2a 2f 0a 20 20 61 73 73 65  idxStr */.  asse
4350: 72 74 28 20 69 64 78 4e 75 6d 3d 3d 68 61 73 68  rt( idxNum==hash
4360: 53 74 72 69 6e 67 28 69 64 78 53 74 72 29 20 29  String(idxStr) )
4370: 3b 0a 0a 20 20 2f 2a 20 4c 6f 67 20 61 72 67 75  ;..  /* Log argu
4380: 6d 65 6e 74 73 20 74 6f 20 74 68 65 20 3a 3a 65  ments to the ::e
4390: 63 68 6f 5f 6d 6f 64 75 6c 65 20 54 63 6c 20 76  cho_module Tcl v
43a0: 61 72 69 61 62 6c 65 20 2a 2f 0a 20 20 61 70 70  ariable */.  app
43b0: 65 6e 64 54 6f 45 63 68 6f 4d 6f 64 75 6c 65 28  endToEchoModule(
43c0: 70 56 74 61 62 2d 3e 69 6e 74 65 72 70 2c 20 22  pVtab->interp, "
43d0: 78 46 69 6c 74 65 72 22 29 3b 0a 20 20 61 70 70  xFilter");.  app
43e0: 65 6e 64 54 6f 45 63 68 6f 4d 6f 64 75 6c 65 28  endToEchoModule(
43f0: 70 56 74 61 62 2d 3e 69 6e 74 65 72 70 2c 20 69  pVtab->interp, i
4400: 64 78 53 74 72 29 3b 0a 20 20 66 6f 72 28 69 3d  dxStr);.  for(i=
4410: 30 3b 20 69 3c 61 72 67 63 3b 20 69 2b 2b 29 7b  0; i<argc; i++){
4420: 0a 20 20 20 20 61 70 70 65 6e 64 54 6f 45 63 68  .    appendToEch
4430: 6f 4d 6f 64 75 6c 65 28 70 56 74 61 62 2d 3e 69  oModule(pVtab->i
4440: 6e 74 65 72 70 2c 20 28 63 6f 6e 73 74 20 63 68  nterp, (const ch
4450: 61 72 2a 29 73 71 6c 69 74 65 33 5f 76 61 6c 75  ar*)sqlite3_valu
4460: 65 5f 74 65 78 74 28 61 72 67 76 5b 69 5d 29 29  e_text(argv[i]))
4470: 3b 0a 20 20 7d 0a 0a 20 20 73 71 6c 69 74 65 33  ;.  }..  sqlite3
4480: 5f 66 69 6e 61 6c 69 7a 65 28 70 43 75 72 2d 3e  _finalize(pCur->
4490: 70 53 74 6d 74 29 3b 0a 20 20 70 43 75 72 2d 3e  pStmt);.  pCur->
44a0: 70 53 74 6d 74 20 3d 20 30 3b 0a 0a 20 20 2f 2a  pStmt = 0;..  /*
44b0: 20 50 72 65 70 61 72 65 20 74 68 65 20 53 51 4c   Prepare the SQL
44c0: 20 73 74 61 74 65 6d 65 6e 74 20 63 72 65 61 74   statement creat
44d0: 65 64 20 62 79 20 65 63 68 6f 42 65 73 74 49 6e  ed by echoBestIn
44e0: 64 65 78 20 61 6e 64 20 62 69 6e 64 20 74 68 65  dex and bind the
44f0: 0a 20 20 2a 2a 20 72 75 6e 74 69 6d 65 20 70 61  .  ** runtime pa
4500: 72 61 6d 65 74 65 72 73 20 70 61 73 73 65 64 20  rameters passed 
4510: 74 6f 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e  to this function
4520: 20 74 6f 20 69 74 2e 0a 20 20 2a 2f 0a 20 20 72   to it..  */.  r
4530: 63 20 3d 20 73 71 6c 69 74 65 33 5f 70 72 65 70  c = sqlite3_prep
4540: 61 72 65 28 64 62 2c 20 69 64 78 53 74 72 2c 20  are(db, idxStr, 
4550: 2d 31 2c 20 26 70 43 75 72 2d 3e 70 53 74 6d 74  -1, &pCur->pStmt
4560: 2c 20 30 29 3b 0a 20 20 61 73 73 65 72 74 28 20  , 0);.  assert( 
4570: 70 43 75 72 2d 3e 70 53 74 6d 74 20 7c 7c 20 72  pCur->pStmt || r
4580: 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 3b 0a  c!=SQLITE_OK );.
4590: 20 20 66 6f 72 28 69 3d 30 3b 20 72 63 3d 3d 53    for(i=0; rc==S
45a0: 51 4c 49 54 45 5f 4f 4b 20 26 26 20 69 3c 61 72  QLITE_OK && i<ar
45b0: 67 63 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 73 71  gc; i++){.    sq
45c0: 6c 69 74 65 33 5f 62 69 6e 64 5f 76 61 6c 75 65  lite3_bind_value
45d0: 28 70 43 75 72 2d 3e 70 53 74 6d 74 2c 20 69 2b  (pCur->pStmt, i+
45e0: 31 2c 20 61 72 67 76 5b 69 5d 29 3b 0a 20 20 7d  1, argv[i]);.  }
45f0: 0a 0a 20 20 2f 2a 20 49 66 20 65 76 65 72 79 74  ..  /* If everyt
4600: 68 69 6e 67 20 77 61 73 20 73 75 63 63 65 73 73  hing was success
4610: 66 75 6c 2c 20 61 64 76 61 6e 63 65 20 74 6f 20  ful, advance to 
4620: 74 68 65 20 66 69 72 73 74 20 72 6f 77 20 6f 66  the first row of
4630: 20 74 68 65 20 73 63 61 6e 20 2a 2f 0a 20 20 69   the scan */.  i
4640: 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc==SQLITE_OK
4650: 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 65 63 68   ){.    rc = ech
4660: 6f 4e 65 78 74 28 70 56 74 61 62 43 75 72 73 6f  oNext(pVtabCurso
4670: 72 29 3b 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72  r);.  }..  retur
4680: 6e 20 72 63 3b 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20  n rc;.}.../*.** 
4690: 41 20 68 65 6c 70 65 72 20 66 75 6e 63 74 69 6f  A helper functio
46a0: 6e 20 75 73 65 64 20 62 79 20 65 63 68 6f 55 70  n used by echoUp
46b0: 64 61 74 65 28 29 20 61 6e 64 20 65 63 68 6f 42  date() and echoB
46c0: 65 73 74 49 6e 64 65 78 28 29 20 66 6f 72 0a 2a  estIndex() for.*
46d0: 2a 20 6d 61 6e 69 70 75 6c 61 74 69 6e 67 20 73  * manipulating s
46e0: 74 72 69 6e 67 73 20 69 6e 20 63 6f 6e 63 65 72  trings in concer
46f0: 74 20 77 69 74 68 20 74 68 65 20 73 71 6c 69 74  t with the sqlit
4700: 65 33 5f 6d 70 72 69 6e 74 66 28 29 20 66 75 6e  e3_mprintf() fun
4710: 63 74 69 6f 6e 2e 0a 2a 2a 0a 2a 2a 20 50 61 72  ction..**.** Par
4720: 61 6d 65 74 65 72 20 70 7a 53 74 72 20 70 6f 69  ameter pzStr poi
4730: 6e 74 73 20 74 6f 20 61 20 70 6f 69 6e 74 65 72  nts to a pointer
4740: 20 74 6f 20 61 20 73 74 72 69 6e 67 20 61 6c 6c   to a string all
4750: 6f 63 61 74 65 64 20 77 69 74 68 0a 2a 2a 20 73  ocated with.** s
4760: 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 2e 20  qlite3_mprintf. 
4770: 54 68 65 20 73 65 63 6f 6e 64 20 70 61 72 61 6d  The second param
4780: 65 74 65 72 2c 20 7a 41 70 70 65 6e 64 2c 20 70  eter, zAppend, p
4790: 6f 69 6e 74 73 20 74 6f 20 61 6e 6f 74 68 65 72  oints to another
47a0: 0a 2a 2a 20 73 74 72 69 6e 67 2e 20 54 68 65 20  .** string. The 
47b0: 74 77 6f 20 73 74 72 69 6e 67 73 20 61 72 65 20  two strings are 
47c0: 63 6f 6e 63 61 74 65 6e 61 74 65 64 20 74 6f 67  concatenated tog
47d0: 65 74 68 65 72 20 61 6e 64 20 2a 70 7a 53 74 72  ether and *pzStr
47e0: 0a 2a 2a 20 73 65 74 20 74 6f 20 70 6f 69 6e 74  .** set to point
47f0: 20 61 74 20 74 68 65 20 72 65 73 75 6c 74 2e 20   at the result. 
4800: 54 68 65 20 69 6e 69 74 69 61 6c 20 62 75 66 66  The initial buff
4810: 65 72 20 70 6f 69 6e 74 65 64 20 74 6f 20 62 79  er pointed to by
4820: 20 2a 70 7a 53 74 72 0a 2a 2a 20 69 73 20 64 65   *pzStr.** is de
4830: 61 6c 6c 6f 63 61 74 65 64 20 76 69 61 20 73 71  allocated via sq
4840: 6c 69 74 65 33 5f 66 72 65 65 28 29 2e 0a 2a 2a  lite3_free()..**
4850: 0a 2a 2a 20 49 66 20 74 68 65 20 74 68 69 72 64  .** If the third
4860: 20 61 72 67 75 6d 65 6e 74 2c 20 64 6f 46 72 65   argument, doFre
4870: 65 2c 20 69 73 20 74 72 75 65 2c 20 74 68 65 6e  e, is true, then
4880: 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 29 20   sqlite3_free() 
4890: 69 73 0a 2a 2a 20 61 6c 73 6f 20 63 61 6c 6c 65  is.** also calle
48a0: 64 20 74 6f 20 66 72 65 65 20 74 68 65 20 62 75  d to free the bu
48b0: 66 66 65 72 20 70 6f 69 6e 74 65 64 20 74 6f 20  ffer pointed to 
48c0: 62 79 20 7a 41 70 70 65 6e 64 2e 0a 2a 2f 0a 73  by zAppend..*/.s
48d0: 74 61 74 69 63 20 76 6f 69 64 20 73 74 72 69 6e  tatic void strin
48e0: 67 5f 63 6f 6e 63 61 74 28 63 68 61 72 20 2a 2a  g_concat(char **
48f0: 70 7a 53 74 72 2c 20 63 68 61 72 20 2a 7a 41 70  pzStr, char *zAp
4900: 70 65 6e 64 2c 20 69 6e 74 20 64 6f 46 72 65 65  pend, int doFree
4910: 2c 20 69 6e 74 20 2a 70 52 63 29 7b 0a 20 20 63  , int *pRc){.  c
4920: 68 61 72 20 2a 7a 49 6e 20 3d 20 2a 70 7a 53 74  har *zIn = *pzSt
4930: 72 3b 0a 20 20 69 66 28 20 21 7a 41 70 70 65 6e  r;.  if( !zAppen
4940: 64 20 26 26 20 64 6f 46 72 65 65 20 26 26 20 2a  d && doFree && *
4950: 70 52 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29  pRc==SQLITE_OK )
4960: 7b 0a 20 20 20 20 2a 70 52 63 20 3d 20 53 51 4c  {.    *pRc = SQL
4970: 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 7d 0a 20  ITE_NOMEM;.  }. 
4980: 20 69 66 28 20 2a 70 52 63 21 3d 53 51 4c 49 54   if( *pRc!=SQLIT
4990: 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 73 71 6c 69  E_OK ){.    sqli
49a0: 74 65 33 5f 66 72 65 65 28 7a 49 6e 29 3b 0a 20  te3_free(zIn);. 
49b0: 20 20 20 7a 49 6e 20 3d 20 30 3b 0a 20 20 7d 65     zIn = 0;.  }e
49c0: 6c 73 65 7b 0a 20 20 20 20 69 66 28 20 7a 49 6e  lse{.    if( zIn
49d0: 20 29 7b 0a 20 20 20 20 20 20 63 68 61 72 20 2a   ){.      char *
49e0: 7a 54 65 6d 70 20 3d 20 7a 49 6e 3b 0a 20 20 20  zTemp = zIn;.   
49f0: 20 20 20 7a 49 6e 20 3d 20 73 71 6c 69 74 65 33     zIn = sqlite3
4a00: 5f 6d 70 72 69 6e 74 66 28 22 25 73 25 73 22 2c  _mprintf("%s%s",
4a10: 20 7a 49 6e 2c 20 7a 41 70 70 65 6e 64 29 3b 0a   zIn, zAppend);.
4a20: 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72        sqlite3_fr
4a30: 65 65 28 7a 54 65 6d 70 29 3b 0a 20 20 20 20 7d  ee(zTemp);.    }
4a40: 65 6c 73 65 7b 0a 20 20 20 20 20 20 7a 49 6e 20  else{.      zIn 
4a50: 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74  = sqlite3_mprint
4a60: 66 28 22 25 73 22 2c 20 7a 41 70 70 65 6e 64 29  f("%s", zAppend)
4a70: 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 28 20  ;.    }.    if( 
4a80: 21 7a 49 6e 20 29 7b 0a 20 20 20 20 20 20 2a 70  !zIn ){.      *p
4a90: 52 63 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45  Rc = SQLITE_NOME
4aa0: 4d 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 2a  M;.    }.  }.  *
4ab0: 70 7a 53 74 72 20 3d 20 7a 49 6e 3b 0a 20 20 69  pzStr = zIn;.  i
4ac0: 66 28 20 64 6f 46 72 65 65 20 29 7b 0a 20 20 20  f( doFree ){.   
4ad0: 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 7a 41   sqlite3_free(zA
4ae0: 70 70 65 6e 64 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f  ppend);.  }.}../
4af0: 2a 0a 2a 2a 20 54 68 65 20 65 63 68 6f 20 6d 6f  *.** The echo mo
4b00: 64 75 6c 65 20 69 6d 70 6c 65 6d 65 6e 74 73 20  dule implements 
4b10: 74 68 65 20 73 75 62 73 65 74 20 6f 66 20 71 75  the subset of qu
4b20: 65 72 79 20 63 6f 6e 73 74 72 61 69 6e 74 73 20  ery constraints 
4b30: 61 6e 64 20 73 6f 72 74 0a 2a 2a 20 6f 72 64 65  and sort.** orde
4b40: 72 73 20 74 68 61 74 20 6d 61 79 20 74 61 6b 65  rs that may take
4b50: 20 61 64 76 61 6e 74 61 67 65 20 6f 66 20 53 51   advantage of SQ
4b60: 4c 69 74 65 20 69 6e 64 69 63 65 73 20 6f 6e 20  Lite indices on 
4b70: 74 68 65 20 75 6e 64 65 72 6c 79 69 6e 67 0a 2a  the underlying.*
4b80: 2a 20 72 65 61 6c 20 74 61 62 6c 65 2e 20 46 6f  * real table. Fo
4b90: 72 20 65 78 61 6d 70 6c 65 2c 20 69 66 20 74 68  r example, if th
4ba0: 65 20 72 65 61 6c 20 74 61 62 6c 65 20 69 73 20  e real table is 
4bb0: 64 65 63 6c 61 72 65 64 20 61 73 3a 0a 2a 2a 0a  declared as:.**.
4bc0: 2a 2a 20 20 20 20 20 43 52 45 41 54 45 20 54 41  **     CREATE TA
4bd0: 42 4c 45 20 72 65 61 6c 28 61 2c 20 62 2c 20 63  BLE real(a, b, c
4be0: 29 3b 0a 2a 2a 20 20 20 20 20 43 52 45 41 54 45  );.**     CREATE
4bf0: 20 49 4e 44 45 58 20 72 65 61 6c 5f 69 6e 64 65   INDEX real_inde
4c00: 78 20 4f 4e 20 72 65 61 6c 28 62 29 3b 0a 2a 2a  x ON real(b);.**
4c10: 0a 2a 2a 20 74 68 65 6e 20 74 68 65 20 65 63 68  .** then the ech
4c20: 6f 20 6d 6f 64 75 6c 65 20 68 61 6e 64 6c 65 73  o module handles
4c30: 20 57 48 45 52 45 20 6f 72 20 4f 52 44 45 52 20   WHERE or ORDER 
4c40: 42 59 20 63 6c 61 75 73 65 73 20 74 68 61 74 20  BY clauses that 
4c50: 72 65 66 65 72 0a 2a 2a 20 74 6f 20 74 68 65 20  refer.** to the 
4c60: 63 6f 6c 75 6d 6e 20 22 62 22 2c 20 62 75 74 20  column "b", but 
4c70: 6e 6f 74 20 22 61 22 20 6f 72 20 22 63 22 2e 20  not "a" or "c". 
4c80: 49 66 20 61 20 6d 75 6c 74 69 2d 63 6f 6c 75 6d  If a multi-colum
4c90: 6e 20 69 6e 64 65 78 20 69 73 0a 2a 2a 20 70 72  n index is.** pr
4ca0: 65 73 65 6e 74 2c 20 6f 6e 6c 79 20 69 74 73 20  esent, only its 
4cb0: 6c 65 66 74 20 6d 6f 73 74 20 63 6f 6c 75 6d 6e  left most column
4cc0: 20 69 73 20 63 6f 6e 73 69 64 65 72 65 64 2e 20   is considered. 
4cd0: 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20 78 42 65 73  .**.** This xBes
4ce0: 74 49 6e 64 65 78 20 6d 65 74 68 6f 64 20 65 6e  tIndex method en
4cf0: 63 6f 64 65 73 20 74 68 65 20 70 72 6f 70 6f 73  codes the propos
4d00: 65 64 20 73 65 61 72 63 68 20 73 74 72 61 74 65  ed search strate
4d10: 67 79 20 61 73 0a 2a 2a 20 61 6e 20 53 51 4c 20  gy as.** an SQL 
4d20: 71 75 65 72 79 20 6f 6e 20 74 68 65 20 72 65 61  query on the rea
4d30: 6c 20 74 61 62 6c 65 20 75 6e 64 65 72 6c 79 69  l table underlyi
4d40: 6e 67 20 74 68 65 20 76 69 72 74 75 61 6c 20 65  ng the virtual e
4d50: 63 68 6f 20 6d 6f 64 75 6c 65 20 0a 2a 2a 20 74  cho module .** t
4d60: 61 62 6c 65 20 61 6e 64 20 73 74 6f 72 65 73 20  able and stores 
4d70: 74 68 65 20 71 75 65 72 79 20 69 6e 20 73 71 6c  the query in sql
4d80: 69 74 65 33 5f 69 6e 64 65 78 5f 69 6e 66 6f 2e  ite3_index_info.
4d90: 69 64 78 53 74 72 2e 20 54 68 65 20 53 51 4c 0a  idxStr. The SQL.
4da0: 2a 2a 20 73 74 61 74 65 6d 65 6e 74 20 69 73 20  ** statement is 
4db0: 6f 66 20 74 68 65 20 66 6f 72 6d 3a 0a 2a 2a 0a  of the form:.**.
4dc0: 2a 2a 20 20 20 53 45 4c 45 43 54 20 72 6f 77 69  **   SELECT rowi
4dd0: 64 2c 20 2a 20 46 52 4f 4d 20 3c 72 65 61 6c 2d  d, * FROM <real-
4de0: 74 61 62 6c 65 3e 20 3f 3c 77 68 65 72 65 2d 63  table> ?<where-c
4df0: 6c 61 75 73 65 3e 3f 20 3f 3c 6f 72 64 65 72 2d  lause>? ?<order-
4e00: 62 79 2d 63 6c 61 75 73 65 3e 3f 0a 2a 2a 0a 2a  by-clause>?.**.*
4e10: 2a 20 77 68 65 72 65 20 74 68 65 20 3c 77 68 65  * where the <whe
4e20: 72 65 2d 63 6c 61 75 73 65 3e 20 61 6e 64 20 3c  re-clause> and <
4e30: 6f 72 64 65 72 2d 62 79 2d 63 6c 61 75 73 65 3e  order-by-clause>
4e40: 20 61 72 65 20 64 65 74 65 72 6d 69 6e 65 64 0a   are determined.
4e50: 2a 2a 20 62 79 20 74 68 65 20 63 6f 6e 74 65 6e  ** by the conten
4e60: 74 73 20 6f 66 20 74 68 65 20 73 74 72 75 63 74  ts of the struct
4e70: 75 72 65 20 70 6f 69 6e 74 65 64 20 74 6f 20 62  ure pointed to b
4e80: 79 20 74 68 65 20 70 49 64 78 49 6e 66 6f 20 61  y the pIdxInfo a
4e90: 72 67 75 6d 65 6e 74 2e 0a 2a 2f 0a 73 74 61 74  rgument..*/.stat
4ea0: 69 63 20 69 6e 74 20 65 63 68 6f 42 65 73 74 49  ic int echoBestI
4eb0: 6e 64 65 78 28 73 71 6c 69 74 65 33 5f 76 74 61  ndex(sqlite3_vta
4ec0: 62 20 2a 74 61 62 2c 20 73 71 6c 69 74 65 33 5f  b *tab, sqlite3_
4ed0: 69 6e 64 65 78 5f 69 6e 66 6f 20 2a 70 49 64 78  index_info *pIdx
4ee0: 49 6e 66 6f 29 7b 0a 20 20 69 6e 74 20 69 69 3b  Info){.  int ii;
4ef0: 0a 20 20 63 68 61 72 20 2a 7a 51 75 65 72 79 20  .  char *zQuery 
4f00: 3d 20 30 3b 0a 20 20 63 68 61 72 20 2a 7a 4e 65  = 0;.  char *zNe
4f10: 77 3b 0a 20 20 69 6e 74 20 6e 41 72 67 20 3d 20  w;.  int nArg = 
4f20: 30 3b 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20  0;.  const char 
4f30: 2a 7a 53 65 70 20 3d 20 22 57 48 45 52 45 22 3b  *zSep = "WHERE";
4f40: 0a 20 20 65 63 68 6f 5f 76 74 61 62 20 2a 70 56  .  echo_vtab *pV
4f50: 74 61 62 20 3d 20 28 65 63 68 6f 5f 76 74 61 62  tab = (echo_vtab
4f60: 20 2a 29 74 61 62 3b 0a 20 20 73 71 6c 69 74 65   *)tab;.  sqlite
4f70: 33 5f 73 74 6d 74 20 2a 70 53 74 6d 74 20 3d 20  3_stmt *pStmt = 
4f80: 30 3b 0a 20 20 54 63 6c 5f 49 6e 74 65 72 70 20  0;.  Tcl_Interp 
4f90: 2a 69 6e 74 65 72 70 20 3d 20 70 56 74 61 62 2d  *interp = pVtab-
4fa0: 3e 69 6e 74 65 72 70 3b 0a 0a 20 20 69 6e 74 20  >interp;..  int 
4fb0: 6e 52 6f 77 3b 0a 20 20 69 6e 74 20 75 73 65 49  nRow;.  int useI
4fc0: 64 78 20 3d 20 30 3b 0a 20 20 69 6e 74 20 72 63  dx = 0;.  int rc
4fd0: 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20   = SQLITE_OK;.  
4fe0: 69 6e 74 20 75 73 65 43 6f 73 74 20 3d 20 30 3b  int useCost = 0;
4ff0: 0a 20 20 64 6f 75 62 6c 65 20 63 6f 73 74 3b 0a  .  double cost;.
5000: 0a 20 20 69 6e 74 20 69 73 49 67 6e 6f 72 65 55  .  int isIgnoreU
5010: 73 61 62 6c 65 20 3d 20 30 3b 0a 20 20 69 66 28  sable = 0;.  if(
5020: 20 54 63 6c 5f 47 65 74 56 61 72 28 69 6e 74 65   Tcl_GetVar(inte
5030: 72 70 2c 20 22 65 63 68 6f 5f 6d 6f 64 75 6c 65  rp, "echo_module
5040: 5f 69 67 6e 6f 72 65 5f 75 73 61 62 6c 65 22 2c  _ignore_usable",
5050: 20 54 43 4c 5f 47 4c 4f 42 41 4c 5f 4f 4e 4c 59   TCL_GLOBAL_ONLY
5060: 29 20 29 7b 0a 20 20 20 20 69 73 49 67 6e 6f 72  ) ){.    isIgnor
5070: 65 55 73 61 62 6c 65 20 3d 20 31 3b 0a 20 20 7d  eUsable = 1;.  }
5080: 0a 0a 20 20 2f 2a 20 44 65 74 65 72 6d 69 6e 65  ..  /* Determine
5090: 20 74 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 72   the number of r
50a0: 6f 77 73 20 69 6e 20 74 68 65 20 74 61 62 6c 65  ows in the table
50b0: 20 61 6e 64 20 73 74 6f 72 65 20 74 68 69 73 20   and store this 
50c0: 76 61 6c 75 65 20 69 6e 20 6c 6f 63 61 6c 0a 20  value in local. 
50d0: 20 2a 2a 20 76 61 72 69 61 62 6c 65 20 6e 52 6f   ** variable nRo
50e0: 77 2e 20 54 68 65 20 27 65 73 74 69 6d 61 74 65  w. The 'estimate
50f0: 64 2d 63 6f 73 74 27 20 6f 66 20 74 68 65 20 73  d-cost' of the s
5100: 63 61 6e 20 77 69 6c 6c 20 62 65 20 74 68 65 20  can will be the 
5110: 6e 75 6d 62 65 72 20 6f 66 0a 20 20 2a 2a 20 72  number of.  ** r
5120: 6f 77 73 20 69 6e 20 74 68 65 20 74 61 62 6c 65  ows in the table
5130: 20 66 6f 72 20 61 20 6c 69 6e 65 61 72 20 73 63   for a linear sc
5140: 61 6e 2c 20 6f 72 20 74 68 65 20 6c 6f 67 20 28  an, or the log (
5150: 62 61 73 65 20 32 29 20 6f 66 20 74 68 65 20 0a  base 2) of the .
5160: 20 20 2a 2a 20 6e 75 6d 62 65 72 20 6f 66 20 72    ** number of r
5170: 6f 77 73 20 69 66 20 74 68 65 20 70 72 6f 70 6f  ows if the propo
5180: 73 65 64 20 73 63 61 6e 20 75 73 65 73 20 61 6e  sed scan uses an
5190: 20 69 6e 64 65 78 2e 20 20 0a 20 20 2a 2f 0a 20   index.  .  */. 
51a0: 20 69 66 28 20 54 63 6c 5f 47 65 74 56 61 72 28   if( Tcl_GetVar(
51b0: 69 6e 74 65 72 70 2c 20 22 65 63 68 6f 5f 6d 6f  interp, "echo_mo
51c0: 64 75 6c 65 5f 63 6f 73 74 22 2c 20 54 43 4c 5f  dule_cost", TCL_
51d0: 47 4c 4f 42 41 4c 5f 4f 4e 4c 59 29 20 29 7b 0a  GLOBAL_ONLY) ){.
51e0: 20 20 20 20 63 6f 73 74 20 3d 20 61 74 6f 66 28      cost = atof(
51f0: 54 63 6c 5f 47 65 74 56 61 72 28 69 6e 74 65 72  Tcl_GetVar(inter
5200: 70 2c 20 22 65 63 68 6f 5f 6d 6f 64 75 6c 65 5f  p, "echo_module_
5210: 63 6f 73 74 22 2c 20 54 43 4c 5f 47 4c 4f 42 41  cost", TCL_GLOBA
5220: 4c 5f 4f 4e 4c 59 29 29 3b 0a 20 20 20 20 75 73  L_ONLY));.    us
5230: 65 43 6f 73 74 20 3d 20 31 3b 0a 20 20 7d 20 65  eCost = 1;.  } e
5240: 6c 73 65 20 7b 0a 20 20 20 20 7a 51 75 65 72 79  lse {.    zQuery
5250: 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e   = sqlite3_mprin
5260: 74 66 28 22 53 45 4c 45 43 54 20 63 6f 75 6e 74  tf("SELECT count
5270: 28 2a 29 20 46 52 4f 4d 20 25 51 22 2c 20 70 56  (*) FROM %Q", pV
5280: 74 61 62 2d 3e 7a 54 61 62 6c 65 4e 61 6d 65 29  tab->zTableName)
5290: 3b 0a 20 20 20 20 69 66 28 20 21 7a 51 75 65 72  ;.    if( !zQuer
52a0: 79 20 29 7b 0a 20 20 20 20 20 20 72 65 74 75 72  y ){.      retur
52b0: 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a  n SQLITE_NOMEM;.
52c0: 20 20 20 20 7d 0a 20 20 20 20 72 63 20 3d 20 73      }.    rc = s
52d0: 71 6c 69 74 65 33 5f 70 72 65 70 61 72 65 28 70  qlite3_prepare(p
52e0: 56 74 61 62 2d 3e 64 62 2c 20 7a 51 75 65 72 79  Vtab->db, zQuery
52f0: 2c 20 2d 31 2c 20 26 70 53 74 6d 74 2c 20 30 29  , -1, &pStmt, 0)
5300: 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72  ;.    sqlite3_fr
5310: 65 65 28 7a 51 75 65 72 79 29 3b 0a 20 20 20 20  ee(zQuery);.    
5320: 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f  if( rc!=SQLITE_O
5330: 4b 20 29 7b 0a 20 20 20 20 20 20 72 65 74 75 72  K ){.      retur
5340: 6e 20 72 63 3b 0a 20 20 20 20 7d 0a 20 20 20 20  n rc;.    }.    
5350: 73 71 6c 69 74 65 33 5f 73 74 65 70 28 70 53 74  sqlite3_step(pSt
5360: 6d 74 29 3b 0a 20 20 20 20 6e 52 6f 77 20 3d 20  mt);.    nRow = 
5370: 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 69  sqlite3_column_i
5380: 6e 74 28 70 53 74 6d 74 2c 20 30 29 3b 0a 20 20  nt(pStmt, 0);.  
5390: 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 66    rc = sqlite3_f
53a0: 69 6e 61 6c 69 7a 65 28 70 53 74 6d 74 29 3b 0a  inalize(pStmt);.
53b0: 20 20 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49      if( rc!=SQLI
53c0: 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 72  TE_OK ){.      r
53d0: 65 74 75 72 6e 20 72 63 3b 0a 20 20 20 20 7d 0a  eturn rc;.    }.
53e0: 20 20 7d 0a 0a 20 20 7a 51 75 65 72 79 20 3d 20    }..  zQuery = 
53f0: 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28  sqlite3_mprintf(
5400: 22 53 45 4c 45 43 54 20 72 6f 77 69 64 2c 20 2a  "SELECT rowid, *
5410: 20 46 52 4f 4d 20 25 51 22 2c 20 70 56 74 61 62   FROM %Q", pVtab
5420: 2d 3e 7a 54 61 62 6c 65 4e 61 6d 65 29 3b 0a 20  ->zTableName);. 
5430: 20 69 66 28 20 21 7a 51 75 65 72 79 20 29 7b 0a   if( !zQuery ){.
5440: 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54      return SQLIT
5450: 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 7d 0a 20 20 66  E_NOMEM;.  }.  f
5460: 6f 72 28 69 69 3d 30 3b 20 69 69 3c 70 49 64 78  or(ii=0; ii<pIdx
5470: 49 6e 66 6f 2d 3e 6e 43 6f 6e 73 74 72 61 69 6e  Info->nConstrain
5480: 74 3b 20 69 69 2b 2b 29 7b 0a 20 20 20 20 63 6f  t; ii++){.    co
5490: 6e 73 74 20 73 74 72 75 63 74 20 73 71 6c 69 74  nst struct sqlit
54a0: 65 33 5f 69 6e 64 65 78 5f 63 6f 6e 73 74 72 61  e3_index_constra
54b0: 69 6e 74 20 2a 70 43 6f 6e 73 74 72 61 69 6e 74  int *pConstraint
54c0: 3b 0a 20 20 20 20 73 74 72 75 63 74 20 73 71 6c  ;.    struct sql
54d0: 69 74 65 33 5f 69 6e 64 65 78 5f 63 6f 6e 73 74  ite3_index_const
54e0: 72 61 69 6e 74 5f 75 73 61 67 65 20 2a 70 55 73  raint_usage *pUs
54f0: 61 67 65 3b 0a 20 20 20 20 69 6e 74 20 69 43 6f  age;.    int iCo
5500: 6c 3b 0a 0a 20 20 20 20 70 43 6f 6e 73 74 72 61  l;..    pConstra
5510: 69 6e 74 20 3d 20 26 70 49 64 78 49 6e 66 6f 2d  int = &pIdxInfo-
5520: 3e 61 43 6f 6e 73 74 72 61 69 6e 74 5b 69 69 5d  >aConstraint[ii]
5530: 3b 0a 20 20 20 20 70 55 73 61 67 65 20 3d 20 26  ;.    pUsage = &
5540: 70 49 64 78 49 6e 66 6f 2d 3e 61 43 6f 6e 73 74  pIdxInfo->aConst
5550: 72 61 69 6e 74 55 73 61 67 65 5b 69 69 5d 3b 0a  raintUsage[ii];.
5560: 0a 20 20 20 20 69 66 28 20 21 69 73 49 67 6e 6f  .    if( !isIgno
5570: 72 65 55 73 61 62 6c 65 20 26 26 20 21 70 43 6f  reUsable && !pCo
5580: 6e 73 74 72 61 69 6e 74 2d 3e 75 73 61 62 6c 65  nstraint->usable
5590: 20 29 20 63 6f 6e 74 69 6e 75 65 3b 0a 0a 20 20   ) continue;..  
55a0: 20 20 69 43 6f 6c 20 3d 20 70 43 6f 6e 73 74 72    iCol = pConstr
55b0: 61 69 6e 74 2d 3e 69 43 6f 6c 75 6d 6e 3b 0a 20  aint->iColumn;. 
55c0: 20 20 20 69 66 28 20 70 56 74 61 62 2d 3e 61 49     if( pVtab->aI
55d0: 6e 64 65 78 5b 69 43 6f 6c 5d 20 7c 7c 20 69 43  ndex[iCol] || iC
55e0: 6f 6c 3c 30 20 29 7b 0a 20 20 20 20 20 20 63 68  ol<0 ){.      ch
55f0: 61 72 20 2a 7a 43 6f 6c 20 3d 20 70 56 74 61 62  ar *zCol = pVtab
5600: 2d 3e 61 43 6f 6c 5b 69 43 6f 6c 5d 3b 0a 20 20  ->aCol[iCol];.  
5610: 20 20 20 20 63 68 61 72 20 2a 7a 4f 70 20 3d 20      char *zOp = 
5620: 30 3b 0a 20 20 20 20 20 20 75 73 65 49 64 78 20  0;.      useIdx 
5630: 3d 20 31 3b 0a 20 20 20 20 20 20 69 66 28 20 69  = 1;.      if( i
5640: 43 6f 6c 3c 30 20 29 7b 0a 20 20 20 20 20 20 20  Col<0 ){.       
5650: 20 7a 43 6f 6c 20 3d 20 22 72 6f 77 69 64 22 3b   zCol = "rowid";
5660: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 73  .      }.      s
5670: 77 69 74 63 68 28 20 70 43 6f 6e 73 74 72 61 69  witch( pConstrai
5680: 6e 74 2d 3e 6f 70 20 29 7b 0a 20 20 20 20 20 20  nt->op ){.      
5690: 20 20 63 61 73 65 20 53 51 4c 49 54 45 5f 49 4e    case SQLITE_IN
56a0: 44 45 58 5f 43 4f 4e 53 54 52 41 49 4e 54 5f 45  DEX_CONSTRAINT_E
56b0: 51 3a 0a 20 20 20 20 20 20 20 20 20 20 7a 4f 70  Q:.          zOp
56c0: 20 3d 20 22 3d 22 3b 20 62 72 65 61 6b 3b 0a 20   = "="; break;. 
56d0: 20 20 20 20 20 20 20 63 61 73 65 20 53 51 4c 49         case SQLI
56e0: 54 45 5f 49 4e 44 45 58 5f 43 4f 4e 53 54 52 41  TE_INDEX_CONSTRA
56f0: 49 4e 54 5f 4c 54 3a 0a 20 20 20 20 20 20 20 20  INT_LT:.        
5700: 20 20 7a 4f 70 20 3d 20 22 3c 22 3b 20 62 72 65    zOp = "<"; bre
5710: 61 6b 3b 0a 20 20 20 20 20 20 20 20 63 61 73 65  ak;.        case
5720: 20 53 51 4c 49 54 45 5f 49 4e 44 45 58 5f 43 4f   SQLITE_INDEX_CO
5730: 4e 53 54 52 41 49 4e 54 5f 47 54 3a 0a 20 20 20  NSTRAINT_GT:.   
5740: 20 20 20 20 20 20 20 7a 4f 70 20 3d 20 22 3e 22         zOp = ">"
5750: 3b 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 20  ; break;.       
5760: 20 63 61 73 65 20 53 51 4c 49 54 45 5f 49 4e 44   case SQLITE_IND
5770: 45 58 5f 43 4f 4e 53 54 52 41 49 4e 54 5f 4c 45  EX_CONSTRAINT_LE
5780: 3a 0a 20 20 20 20 20 20 20 20 20 20 7a 4f 70 20  :.          zOp 
5790: 3d 20 22 3c 3d 22 3b 20 62 72 65 61 6b 3b 0a 20  = "<="; break;. 
57a0: 20 20 20 20 20 20 20 63 61 73 65 20 53 51 4c 49         case SQLI
57b0: 54 45 5f 49 4e 44 45 58 5f 43 4f 4e 53 54 52 41  TE_INDEX_CONSTRA
57c0: 49 4e 54 5f 47 45 3a 0a 20 20 20 20 20 20 20 20  INT_GE:.        
57d0: 20 20 7a 4f 70 20 3d 20 22 3e 3d 22 3b 20 62 72    zOp = ">="; br
57e0: 65 61 6b 3b 0a 20 20 20 20 20 20 20 20 63 61 73  eak;.        cas
57f0: 65 20 53 51 4c 49 54 45 5f 49 4e 44 45 58 5f 43  e SQLITE_INDEX_C
5800: 4f 4e 53 54 52 41 49 4e 54 5f 4d 41 54 43 48 3a  ONSTRAINT_MATCH:
5810: 0a 20 20 20 20 20 20 20 20 20 20 7a 4f 70 20 3d  .          zOp =
5820: 20 22 4c 49 4b 45 22 3b 20 62 72 65 61 6b 3b 0a   "LIKE"; break;.
5830: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 69 66        }.      if
5840: 28 20 7a 4f 70 5b 30 5d 3d 3d 27 4c 27 20 29 7b  ( zOp[0]=='L' ){
5850: 0a 20 20 20 20 20 20 20 20 7a 4e 65 77 20 3d 20  .        zNew = 
5860: 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28  sqlite3_mprintf(
5870: 22 20 25 73 20 25 73 20 4c 49 4b 45 20 28 53 45  " %s %s LIKE (SE
5880: 4c 45 43 54 20 27 25 25 27 7c 7c 3f 7c 7c 27 25  LECT '%%'||?||'%
5890: 25 27 29 22 2c 20 0a 20 20 20 20 20 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 7a 53 65 70 2c 20 7a 43 6f 6c        zSep, zCol
58c0: 29 3b 0a 20 20 20 20 20 20 7d 20 65 6c 73 65 20  );.      } else 
58d0: 7b 0a 20 20 20 20 20 20 20 20 7a 4e 65 77 20 3d  {.        zNew =
58e0: 20 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66   sqlite3_mprintf
58f0: 28 22 20 25 73 20 25 73 20 25 73 20 3f 22 2c 20  (" %s %s %s ?", 
5900: 7a 53 65 70 2c 20 7a 43 6f 6c 2c 20 7a 4f 70 29  zSep, zCol, zOp)
5910: 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20  ;.      }.      
5920: 73 74 72 69 6e 67 5f 63 6f 6e 63 61 74 28 26 7a  string_concat(&z
5930: 51 75 65 72 79 2c 20 7a 4e 65 77 2c 20 31 2c 20  Query, zNew, 1, 
5940: 26 72 63 29 3b 0a 0a 20 20 20 20 20 20 7a 53 65  &rc);..      zSe
5950: 70 20 3d 20 22 41 4e 44 22 3b 0a 20 20 20 20 20  p = "AND";.     
5960: 20 70 55 73 61 67 65 2d 3e 61 72 67 76 49 6e 64   pUsage->argvInd
5970: 65 78 20 3d 20 2b 2b 6e 41 72 67 3b 0a 20 20 20  ex = ++nArg;.   
5980: 20 20 20 70 55 73 61 67 65 2d 3e 6f 6d 69 74 20     pUsage->omit 
5990: 3d 20 31 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a  = 1;.    }.  }..
59a0: 20 20 2f 2a 20 49 66 20 74 68 65 72 65 20 69 73    /* If there is
59b0: 20 6f 6e 6c 79 20 6f 6e 65 20 74 65 72 6d 20 69   only one term i
59c0: 6e 20 74 68 65 20 4f 52 44 45 52 20 42 59 20 63  n the ORDER BY c
59d0: 6c 61 75 73 65 2c 20 61 6e 64 20 69 74 20 69 73  lause, and it is
59e0: 0a 20 20 2a 2a 20 6f 6e 20 61 20 63 6f 6c 75 6d  .  ** on a colum
59f0: 6e 20 74 68 61 74 20 74 68 69 73 20 76 69 72 74  n that this virt
5a00: 75 61 6c 20 74 61 62 6c 65 20 68 61 73 20 61 6e  ual table has an
5a10: 20 69 6e 64 65 78 20 66 6f 72 2c 20 74 68 65 6e   index for, then
5a20: 20 63 6f 6e 73 75 6d 65 20 0a 20 20 2a 2a 20 74   consume .  ** t
5a30: 68 65 20 4f 52 44 45 52 20 42 59 20 63 6c 61 75  he ORDER BY clau
5a40: 73 65 2e 0a 20 20 2a 2f 0a 20 20 69 66 28 20 70  se..  */.  if( p
5a50: 49 64 78 49 6e 66 6f 2d 3e 6e 4f 72 64 65 72 42  IdxInfo->nOrderB
5a60: 79 3d 3d 31 20 26 26 20 70 56 74 61 62 2d 3e 61  y==1 && pVtab->a
5a70: 49 6e 64 65 78 5b 70 49 64 78 49 6e 66 6f 2d 3e  Index[pIdxInfo->
5a80: 61 4f 72 64 65 72 42 79 2d 3e 69 43 6f 6c 75 6d  aOrderBy->iColum
5a90: 6e 5d 20 29 7b 0a 20 20 20 20 69 6e 74 20 69 43  n] ){.    int iC
5aa0: 6f 6c 20 3d 20 70 49 64 78 49 6e 66 6f 2d 3e 61  ol = pIdxInfo->a
5ab0: 4f 72 64 65 72 42 79 2d 3e 69 43 6f 6c 75 6d 6e  OrderBy->iColumn
5ac0: 3b 0a 20 20 20 20 63 68 61 72 20 2a 7a 43 6f 6c  ;.    char *zCol
5ad0: 20 3d 20 70 56 74 61 62 2d 3e 61 43 6f 6c 5b 69   = pVtab->aCol[i
5ae0: 43 6f 6c 5d 3b 0a 20 20 20 20 63 68 61 72 20 2a  Col];.    char *
5af0: 7a 44 69 72 20 3d 20 70 49 64 78 49 6e 66 6f 2d  zDir = pIdxInfo-
5b00: 3e 61 4f 72 64 65 72 42 79 2d 3e 64 65 73 63 3f  >aOrderBy->desc?
5b10: 22 44 45 53 43 22 3a 22 41 53 43 22 3b 0a 20 20  "DESC":"ASC";.  
5b20: 20 20 69 66 28 20 69 43 6f 6c 3c 30 20 29 7b 0a    if( iCol<0 ){.
5b30: 20 20 20 20 20 20 7a 43 6f 6c 20 3d 20 22 72 6f        zCol = "ro
5b40: 77 69 64 22 3b 0a 20 20 20 20 7d 0a 20 20 20 20  wid";.    }.    
5b50: 7a 4e 65 77 20 3d 20 73 71 6c 69 74 65 33 5f 6d  zNew = sqlite3_m
5b60: 70 72 69 6e 74 66 28 22 20 4f 52 44 45 52 20 42  printf(" ORDER B
5b70: 59 20 25 73 20 25 73 22 2c 20 7a 43 6f 6c 2c 20  Y %s %s", zCol, 
5b80: 7a 44 69 72 29 3b 0a 20 20 20 20 73 74 72 69 6e  zDir);.    strin
5b90: 67 5f 63 6f 6e 63 61 74 28 26 7a 51 75 65 72 79  g_concat(&zQuery
5ba0: 2c 20 7a 4e 65 77 2c 20 31 2c 20 26 72 63 29 3b  , zNew, 1, &rc);
5bb0: 0a 20 20 20 20 70 49 64 78 49 6e 66 6f 2d 3e 6f  .    pIdxInfo->o
5bc0: 72 64 65 72 42 79 43 6f 6e 73 75 6d 65 64 20 3d  rderByConsumed =
5bd0: 20 31 3b 0a 20 20 7d 0a 0a 20 20 61 70 70 65 6e   1;.  }..  appen
5be0: 64 54 6f 45 63 68 6f 4d 6f 64 75 6c 65 28 70 56  dToEchoModule(pV
5bf0: 74 61 62 2d 3e 69 6e 74 65 72 70 2c 20 22 78 42  tab->interp, "xB
5c00: 65 73 74 49 6e 64 65 78 22 29 3b 3b 0a 20 20 61  estIndex");;.  a
5c10: 70 70 65 6e 64 54 6f 45 63 68 6f 4d 6f 64 75 6c  ppendToEchoModul
5c20: 65 28 70 56 74 61 62 2d 3e 69 6e 74 65 72 70 2c  e(pVtab->interp,
5c30: 20 7a 51 75 65 72 79 29 3b 0a 0a 20 20 69 66 28   zQuery);..  if(
5c40: 20 21 7a 51 75 65 72 79 20 29 7b 0a 20 20 20 20   !zQuery ){.    
5c50: 72 65 74 75 72 6e 20 72 63 3b 0a 20 20 7d 0a 20  return rc;.  }. 
5c60: 20 70 49 64 78 49 6e 66 6f 2d 3e 69 64 78 4e 75   pIdxInfo->idxNu
5c70: 6d 20 3d 20 68 61 73 68 53 74 72 69 6e 67 28 7a  m = hashString(z
5c80: 51 75 65 72 79 29 3b 0a 20 20 70 49 64 78 49 6e  Query);.  pIdxIn
5c90: 66 6f 2d 3e 69 64 78 53 74 72 20 3d 20 7a 51 75  fo->idxStr = zQu
5ca0: 65 72 79 3b 0a 20 20 70 49 64 78 49 6e 66 6f 2d  ery;.  pIdxInfo-
5cb0: 3e 6e 65 65 64 54 6f 46 72 65 65 49 64 78 53 74  >needToFreeIdxSt
5cc0: 72 20 3d 20 31 3b 0a 20 20 69 66 20 28 75 73 65  r = 1;.  if (use
5cd0: 43 6f 73 74 29 20 7b 0a 20 20 20 20 70 49 64 78  Cost) {.    pIdx
5ce0: 49 6e 66 6f 2d 3e 65 73 74 69 6d 61 74 65 64 43  Info->estimatedC
5cf0: 6f 73 74 20 3d 20 63 6f 73 74 3b 0a 20 20 7d 20  ost = cost;.  } 
5d00: 65 6c 73 65 20 69 66 28 20 75 73 65 49 64 78 20  else if( useIdx 
5d10: 29 7b 0a 20 20 20 20 2f 2a 20 41 70 70 72 6f 78  ){.    /* Approx
5d20: 69 6d 61 74 69 6f 6e 20 6f 66 20 6c 6f 67 32 28  imation of log2(
5d30: 6e 52 6f 77 29 2e 20 2a 2f 0a 20 20 20 20 66 6f  nRow). */.    fo
5d40: 72 28 20 69 69 3d 30 3b 20 69 69 3c 28 73 69 7a  r( ii=0; ii<(siz
5d50: 65 6f 66 28 69 6e 74 29 2a 38 29 3b 20 69 69 2b  eof(int)*8); ii+
5d60: 2b 20 29 7b 0a 20 20 20 20 20 20 69 66 28 20 6e  + ){.      if( n
5d70: 52 6f 77 20 26 20 28 31 3c 3c 69 69 29 20 29 7b  Row & (1<<ii) ){
5d80: 0a 20 20 20 20 20 20 20 20 70 49 64 78 49 6e 66  .        pIdxInf
5d90: 6f 2d 3e 65 73 74 69 6d 61 74 65 64 43 6f 73 74  o->estimatedCost
5da0: 20 3d 20 28 64 6f 75 62 6c 65 29 69 69 3b 0a 20   = (double)ii;. 
5db0: 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 7d       }.    }.  }
5dc0: 20 65 6c 73 65 20 7b 0a 20 20 20 20 70 49 64 78   else {.    pIdx
5dd0: 49 6e 66 6f 2d 3e 65 73 74 69 6d 61 74 65 64 43  Info->estimatedC
5de0: 6f 73 74 20 3d 20 28 64 6f 75 62 6c 65 29 6e 52  ost = (double)nR
5df0: 6f 77 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e  ow;.  }.  return
5e00: 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68   rc;.}../*.** Th
5e10: 65 20 78 55 70 64 61 74 65 20 6d 65 74 68 6f 64  e xUpdate method
5e20: 20 66 6f 72 20 65 63 68 6f 20 6d 6f 64 75 6c 65   for echo module
5e30: 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65 73 2e   virtual tables.
5e40: 0a 2a 2a 20 0a 2a 2a 20 20 20 20 61 70 44 61 74  .** .**    apDat
5e50: 61 5b 30 5d 20 20 61 70 44 61 74 61 5b 31 5d 20  a[0]  apData[1] 
5e60: 20 61 70 44 61 74 61 5b 32 2e 2e 5d 0a 2a 2a 0a   apData[2..].**.
5e70: 2a 2a 20 20 20 20 49 4e 54 45 47 45 52 20 20 20  **    INTEGER   
5e80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5e90: 20 20 20 20 20 20 20 20 20 20 20 44 45 4c 45 54             DELET
5ea0: 45 20 20 20 20 20 20 20 20 20 20 20 20 0a 2a 2a  E            .**
5eb0: 0a 2a 2a 20 20 20 20 49 4e 54 45 47 45 52 20 20  .**    INTEGER  
5ec0: 20 20 4e 55 4c 4c 20 20 20 20 20 20 20 28 6e 43    NULL       (nC
5ed0: 6f 6c 20 61 72 67 73 29 20 20 20 20 55 50 44 41  ol args)    UPDA
5ee0: 54 45 20 28 64 6f 20 6e 6f 74 20 73 65 74 20 72  TE (do not set r
5ef0: 6f 77 69 64 29 0a 2a 2a 20 20 20 20 49 4e 54 45  owid).**    INTE
5f00: 47 45 52 20 20 20 20 49 4e 54 45 47 45 52 20 20  GER    INTEGER  
5f10: 20 20 28 6e 43 6f 6c 20 61 72 67 73 29 20 20 20    (nCol args)   
5f20: 20 55 50 44 41 54 45 20 28 77 69 74 68 20 53 45   UPDATE (with SE
5f30: 54 20 72 6f 77 69 64 20 3d 20 3c 61 72 67 31 3e  T rowid = <arg1>
5f40: 29 0a 2a 2a 0a 2a 2a 20 20 20 20 4e 55 4c 4c 20  ).**.**    NULL 
5f50: 20 20 20 20 20 20 4e 55 4c 4c 20 20 20 20 20 20        NULL      
5f60: 20 28 6e 43 6f 6c 20 61 72 67 73 29 20 20 20 20   (nCol args)    
5f70: 49 4e 53 45 52 54 20 49 4e 54 4f 20 28 61 75 74  INSERT INTO (aut
5f80: 6f 6d 61 74 69 63 20 72 6f 77 69 64 20 76 61 6c  omatic rowid val
5f90: 75 65 29 0a 2a 2a 20 20 20 20 4e 55 4c 4c 20 20  ue).**    NULL  
5fa0: 20 20 20 20 20 49 4e 54 45 47 45 52 20 20 20 20       INTEGER    
5fb0: 28 6e 43 6f 6c 20 61 72 67 73 29 20 20 20 20 49  (nCol args)    I
5fc0: 4e 53 45 52 54 20 28 69 6e 63 6c 2e 20 72 6f 77  NSERT (incl. row
5fd0: 69 64 20 76 61 6c 75 65 29 0a 2a 2a 0a 2a 2f 0a  id value).**.*/.
5fe0: 69 6e 74 20 65 63 68 6f 55 70 64 61 74 65 28 0a  int echoUpdate(.
5ff0: 20 20 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a    sqlite3_vtab *
6000: 74 61 62 2c 20 0a 20 20 69 6e 74 20 6e 44 61 74  tab, .  int nDat
6010: 61 2c 20 0a 20 20 73 71 6c 69 74 65 33 5f 76 61  a, .  sqlite3_va
6020: 6c 75 65 20 2a 2a 61 70 44 61 74 61 2c 20 0a 20  lue **apData, . 
6030: 20 73 71 6c 69 74 65 5f 69 6e 74 36 34 20 2a 70   sqlite_int64 *p
6040: 52 6f 77 69 64 0a 29 7b 0a 20 20 65 63 68 6f 5f  Rowid.){.  echo_
6050: 76 74 61 62 20 2a 70 56 74 61 62 20 3d 20 28 65  vtab *pVtab = (e
6060: 63 68 6f 5f 76 74 61 62 20 2a 29 74 61 62 3b 0a  cho_vtab *)tab;.
6070: 20 20 73 71 6c 69 74 65 33 20 2a 64 62 20 3d 20    sqlite3 *db = 
6080: 70 56 74 61 62 2d 3e 64 62 3b 0a 20 20 69 6e 74  pVtab->db;.  int
6090: 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b   rc = SQLITE_OK;
60a0: 0a 0a 20 20 73 71 6c 69 74 65 33 5f 73 74 6d 74  ..  sqlite3_stmt
60b0: 20 2a 70 53 74 6d 74 3b 0a 20 20 63 68 61 72 20   *pStmt;.  char 
60c0: 2a 7a 20 3d 20 30 3b 20 20 20 20 20 20 20 20 20  *z = 0;         
60d0: 20 20 20 20 20 20 2f 2a 20 53 51 4c 20 73 74 61        /* SQL sta
60e0: 74 65 6d 65 6e 74 20 74 6f 20 65 78 65 63 75 74  tement to execut
60f0: 65 20 2a 2f 0a 20 20 69 6e 74 20 62 69 6e 64 41  e */.  int bindA
6100: 72 67 5a 65 72 6f 20 3d 20 30 3b 20 20 20 20 20  rgZero = 0;     
6110: 20 20 2f 2a 20 54 72 75 65 20 74 6f 20 62 69 6e    /* True to bin
6120: 64 20 61 70 44 61 74 61 5b 30 5d 20 74 6f 20 73  d apData[0] to s
6130: 71 6c 20 76 61 72 20 6e 6f 2e 20 6e 44 61 74 61  ql var no. nData
6140: 20 2a 2f 0a 20 20 69 6e 74 20 62 69 6e 64 41 72   */.  int bindAr
6150: 67 4f 6e 65 20 3d 20 30 3b 20 20 20 20 20 20 20  gOne = 0;       
6160: 20 2f 2a 20 54 72 75 65 20 74 6f 20 62 69 6e 64   /* True to bind
6170: 20 61 70 44 61 74 61 5b 31 5d 20 74 6f 20 73 71   apData[1] to sq
6180: 6c 20 76 61 72 20 6e 6f 2e 20 31 20 2a 2f 0a 20  l var no. 1 */. 
6190: 20 69 6e 74 20 69 3b 20 20 20 20 20 20 20 20 20   int i;         
61a0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43              /* C
61b0: 6f 75 6e 74 65 72 20 76 61 72 69 61 62 6c 65 20  ounter variable 
61c0: 75 73 65 64 20 62 79 20 66 6f 72 20 6c 6f 6f 70  used by for loop
61d0: 73 20 2a 2f 0a 0a 20 20 61 73 73 65 72 74 28 20  s */..  assert( 
61e0: 6e 44 61 74 61 3d 3d 70 56 74 61 62 2d 3e 6e 43  nData==pVtab->nC
61f0: 6f 6c 2b 32 20 7c 7c 20 6e 44 61 74 61 3d 3d 31  ol+2 || nData==1
6200: 20 29 3b 0a 0a 20 20 2f 2a 20 54 69 63 6b 65 74   );..  /* Ticket
6210: 20 23 33 30 38 33 20 2d 20 6d 61 6b 65 20 73 75   #3083 - make su
6220: 72 65 20 77 65 20 61 6c 77 61 79 73 20 73 74 61  re we always sta
6230: 72 74 20 61 20 74 72 61 6e 73 61 63 74 69 6f 6e  rt a transaction
6240: 20 70 72 69 6f 72 20 74 6f 0a 20 20 2a 2a 20 6d   prior to.  ** m
6250: 61 6b 69 6e 67 20 61 6e 79 20 63 68 61 6e 67 65  aking any change
6260: 73 20 74 6f 20 61 20 76 69 72 74 75 61 6c 20 74  s to a virtual t
6270: 61 62 6c 65 20 2a 2f 0a 20 20 61 73 73 65 72 74  able */.  assert
6280: 28 20 70 56 74 61 62 2d 3e 69 6e 54 72 61 6e 73  ( pVtab->inTrans
6290: 61 63 74 69 6f 6e 20 29 3b 0a 0a 20 20 2f 2a 20  action );..  /* 
62a0: 49 66 20 61 70 44 61 74 61 5b 30 5d 20 69 73 20  If apData[0] is 
62b0: 61 6e 20 69 6e 74 65 67 65 72 20 61 6e 64 20 6e  an integer and n
62c0: 44 61 74 61 3e 31 20 74 68 65 6e 20 64 6f 20 61  Data>1 then do a
62d0: 6e 20 55 50 44 41 54 45 20 2a 2f 0a 20 20 69 66  n UPDATE */.  if
62e0: 28 20 6e 44 61 74 61 3e 31 20 26 26 20 73 71 6c  ( nData>1 && sql
62f0: 69 74 65 33 5f 76 61 6c 75 65 5f 74 79 70 65 28  ite3_value_type(
6300: 61 70 44 61 74 61 5b 30 5d 29 3d 3d 53 51 4c 49  apData[0])==SQLI
6310: 54 45 5f 49 4e 54 45 47 45 52 20 29 7b 0a 20 20  TE_INTEGER ){.  
6320: 20 20 63 68 61 72 20 2a 7a 53 65 70 20 3d 20 22    char *zSep = "
6330: 20 53 45 54 22 3b 0a 20 20 20 20 7a 20 3d 20 73   SET";.    z = s
6340: 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 22  qlite3_mprintf("
6350: 55 50 44 41 54 45 20 25 51 22 2c 20 70 56 74 61  UPDATE %Q", pVta
6360: 62 2d 3e 7a 54 61 62 6c 65 4e 61 6d 65 29 3b 0a  b->zTableName);.
6370: 20 20 20 20 69 66 28 20 21 7a 20 29 7b 0a 20 20      if( !z ){.  
6380: 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f      rc = SQLITE_
6390: 4e 4f 4d 45 4d 3b 0a 20 20 20 20 7d 0a 0a 20 20  NOMEM;.    }..  
63a0: 20 20 62 69 6e 64 41 72 67 4f 6e 65 20 3d 20 28    bindArgOne = (
63b0: 61 70 44 61 74 61 5b 31 5d 20 26 26 20 73 71 6c  apData[1] && sql
63c0: 69 74 65 33 5f 76 61 6c 75 65 5f 74 79 70 65 28  ite3_value_type(
63d0: 61 70 44 61 74 61 5b 31 5d 29 3d 3d 53 51 4c 49  apData[1])==SQLI
63e0: 54 45 5f 49 4e 54 45 47 45 52 29 3b 0a 20 20 20  TE_INTEGER);.   
63f0: 20 62 69 6e 64 41 72 67 5a 65 72 6f 20 3d 20 31   bindArgZero = 1
6400: 3b 0a 0a 20 20 20 20 69 66 28 20 62 69 6e 64 41  ;..    if( bindA
6410: 72 67 4f 6e 65 20 29 7b 0a 20 20 20 20 20 20 20  rgOne ){.       
6420: 73 74 72 69 6e 67 5f 63 6f 6e 63 61 74 28 26 7a  string_concat(&z
6430: 2c 20 22 20 53 45 54 20 72 6f 77 69 64 3d 3f 31  , " SET rowid=?1
6440: 20 22 2c 20 30 2c 20 26 72 63 29 3b 0a 20 20 20   ", 0, &rc);.   
6450: 20 20 20 20 7a 53 65 70 20 3d 20 22 2c 22 3b 0a      zSep = ",";.
6460: 20 20 20 20 7d 0a 20 20 20 20 66 6f 72 28 69 3d      }.    for(i=
6470: 32 3b 20 69 3c 6e 44 61 74 61 3b 20 69 2b 2b 29  2; i<nData; i++)
6480: 7b 0a 20 20 20 20 20 20 69 66 28 20 61 70 44 61  {.      if( apDa
6490: 74 61 5b 69 5d 3d 3d 30 20 29 20 63 6f 6e 74 69  ta[i]==0 ) conti
64a0: 6e 75 65 3b 0a 20 20 20 20 20 20 73 74 72 69 6e  nue;.      strin
64b0: 67 5f 63 6f 6e 63 61 74 28 26 7a 2c 20 73 71 6c  g_concat(&z, sql
64c0: 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 0a 20 20  ite3_mprintf(.  
64d0: 20 20 20 20 20 20 20 20 22 25 73 20 25 51 3d 3f          "%s %Q=?
64e0: 25 64 22 2c 20 7a 53 65 70 2c 20 70 56 74 61 62  %d", zSep, pVtab
64f0: 2d 3e 61 43 6f 6c 5b 69 2d 32 5d 2c 20 69 29 2c  ->aCol[i-2], i),
6500: 20 31 2c 20 26 72 63 29 3b 0a 20 20 20 20 20 20   1, &rc);.      
6510: 7a 53 65 70 20 3d 20 22 2c 22 3b 0a 20 20 20 20  zSep = ",";.    
6520: 7d 0a 20 20 20 20 73 74 72 69 6e 67 5f 63 6f 6e  }.    string_con
6530: 63 61 74 28 26 7a 2c 20 73 71 6c 69 74 65 33 5f  cat(&z, sqlite3_
6540: 6d 70 72 69 6e 74 66 28 22 20 57 48 45 52 45 20  mprintf(" WHERE 
6550: 72 6f 77 69 64 3d 3f 25 64 22 2c 20 6e 44 61 74  rowid=?%d", nDat
6560: 61 29 2c 20 31 2c 20 26 72 63 29 3b 0a 20 20 7d  a), 1, &rc);.  }
6570: 0a 0a 20 20 2f 2a 20 49 66 20 61 70 44 61 74 61  ..  /* If apData
6580: 5b 30 5d 20 69 73 20 61 6e 20 69 6e 74 65 67 65  [0] is an intege
6590: 72 20 61 6e 64 20 6e 44 61 74 61 3d 3d 31 20 74  r and nData==1 t
65a0: 68 65 6e 20 64 6f 20 61 20 44 45 4c 45 54 45 20  hen do a DELETE 
65b0: 2a 2f 0a 20 20 65 6c 73 65 20 69 66 28 20 6e 44  */.  else if( nD
65c0: 61 74 61 3d 3d 31 20 26 26 20 73 71 6c 69 74 65  ata==1 && sqlite
65d0: 33 5f 76 61 6c 75 65 5f 74 79 70 65 28 61 70 44  3_value_type(apD
65e0: 61 74 61 5b 30 5d 29 3d 3d 53 51 4c 49 54 45 5f  ata[0])==SQLITE_
65f0: 49 4e 54 45 47 45 52 20 29 7b 0a 20 20 20 20 7a  INTEGER ){.    z
6600: 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e   = sqlite3_mprin
6610: 74 66 28 22 44 45 4c 45 54 45 20 46 52 4f 4d 20  tf("DELETE FROM 
6620: 25 51 20 57 48 45 52 45 20 72 6f 77 69 64 20 3d  %Q WHERE rowid =
6630: 20 3f 31 22 2c 20 70 56 74 61 62 2d 3e 7a 54 61   ?1", pVtab->zTa
6640: 62 6c 65 4e 61 6d 65 29 3b 0a 20 20 20 20 69 66  bleName);.    if
6650: 28 20 21 7a 20 29 7b 0a 20 20 20 20 20 20 72 63  ( !z ){.      rc
6660: 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b   = SQLITE_NOMEM;
6670: 0a 20 20 20 20 7d 0a 20 20 20 20 62 69 6e 64 41  .    }.    bindA
6680: 72 67 5a 65 72 6f 20 3d 20 31 3b 0a 20 20 7d 0a  rgZero = 1;.  }.
6690: 0a 20 20 2f 2a 20 49 66 20 74 68 65 20 66 69 72  .  /* If the fir
66a0: 73 74 20 61 72 67 75 6d 65 6e 74 20 69 73 20 4e  st argument is N
66b0: 55 4c 4c 20 61 6e 64 20 74 68 65 72 65 20 61 72  ULL and there ar
66c0: 65 20 6d 6f 72 65 20 74 68 61 6e 20 74 77 6f 20  e more than two 
66d0: 61 72 67 73 2c 20 49 4e 53 45 52 54 20 2a 2f 0a  args, INSERT */.
66e0: 20 20 65 6c 73 65 20 69 66 28 20 6e 44 61 74 61    else if( nData
66f0: 3e 32 20 26 26 20 73 71 6c 69 74 65 33 5f 76 61  >2 && sqlite3_va
6700: 6c 75 65 5f 74 79 70 65 28 61 70 44 61 74 61 5b  lue_type(apData[
6710: 30 5d 29 3d 3d 53 51 4c 49 54 45 5f 4e 55 4c 4c  0])==SQLITE_NULL
6720: 20 29 7b 0a 20 20 20 20 69 6e 74 20 69 69 3b 0a   ){.    int ii;.
6730: 20 20 20 20 63 68 61 72 20 2a 7a 49 6e 73 65 72      char *zInser
6740: 74 20 3d 20 30 3b 0a 20 20 20 20 63 68 61 72 20  t = 0;.    char 
6750: 2a 7a 56 61 6c 75 65 73 20 3d 20 30 3b 0a 20 20  *zValues = 0;.  
6760: 0a 20 20 20 20 7a 49 6e 73 65 72 74 20 3d 20 73  .    zInsert = s
6770: 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 22  qlite3_mprintf("
6780: 49 4e 53 45 52 54 20 49 4e 54 4f 20 25 51 20 28  INSERT INTO %Q (
6790: 22 2c 20 70 56 74 61 62 2d 3e 7a 54 61 62 6c 65  ", pVtab->zTable
67a0: 4e 61 6d 65 29 3b 0a 20 20 20 20 69 66 28 20 21  Name);.    if( !
67b0: 7a 49 6e 73 65 72 74 20 29 7b 0a 20 20 20 20 20  zInsert ){.     
67c0: 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d   rc = SQLITE_NOM
67d0: 45 4d 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69 66  EM;.    }.    if
67e0: 28 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f  ( sqlite3_value_
67f0: 74 79 70 65 28 61 70 44 61 74 61 5b 31 5d 29 3d  type(apData[1])=
6800: 3d 53 51 4c 49 54 45 5f 49 4e 54 45 47 45 52 20  =SQLITE_INTEGER 
6810: 29 7b 0a 20 20 20 20 20 20 62 69 6e 64 41 72 67  ){.      bindArg
6820: 4f 6e 65 20 3d 20 31 3b 0a 20 20 20 20 20 20 7a  One = 1;.      z
6830: 56 61 6c 75 65 73 20 3d 20 73 71 6c 69 74 65 33  Values = sqlite3
6840: 5f 6d 70 72 69 6e 74 66 28 22 3f 22 29 3b 0a 20  _mprintf("?");. 
6850: 20 20 20 20 20 73 74 72 69 6e 67 5f 63 6f 6e 63       string_conc
6860: 61 74 28 26 7a 49 6e 73 65 72 74 2c 20 22 72 6f  at(&zInsert, "ro
6870: 77 69 64 22 2c 20 30 2c 20 26 72 63 29 3b 0a 20  wid", 0, &rc);. 
6880: 20 20 20 7d 0a 0a 20 20 20 20 61 73 73 65 72 74     }..    assert
6890: 28 28 70 56 74 61 62 2d 3e 6e 43 6f 6c 2b 32 29  ((pVtab->nCol+2)
68a0: 3d 3d 6e 44 61 74 61 29 3b 0a 20 20 20 20 66 6f  ==nData);.    fo
68b0: 72 28 69 69 3d 32 3b 20 69 69 3c 6e 44 61 74 61  r(ii=2; ii<nData
68c0: 3b 20 69 69 2b 2b 29 7b 0a 20 20 20 20 20 20 73  ; ii++){.      s
68d0: 74 72 69 6e 67 5f 63 6f 6e 63 61 74 28 26 7a 49  tring_concat(&zI
68e0: 6e 73 65 72 74 2c 20 0a 20 20 20 20 20 20 20 20  nsert, .        
68f0: 20 20 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74    sqlite3_mprint
6900: 66 28 22 25 73 25 51 22 2c 20 7a 56 61 6c 75 65  f("%s%Q", zValue
6910: 73 3f 22 2c 20 22 3a 22 22 2c 20 70 56 74 61 62  s?", ":"", pVtab
6920: 2d 3e 61 43 6f 6c 5b 69 69 2d 32 5d 29 2c 20 31  ->aCol[ii-2]), 1
6930: 2c 20 26 72 63 29 3b 0a 20 20 20 20 20 20 73 74  , &rc);.      st
6940: 72 69 6e 67 5f 63 6f 6e 63 61 74 28 26 7a 56 61  ring_concat(&zVa
6950: 6c 75 65 73 2c 20 0a 20 20 20 20 20 20 20 20 20  lues, .         
6960: 20 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66   sqlite3_mprintf
6970: 28 22 25 73 3f 25 64 22 2c 20 7a 56 61 6c 75 65  ("%s?%d", zValue
6980: 73 3f 22 2c 20 22 3a 22 22 2c 20 69 69 29 2c 20  s?", ":"", ii), 
6990: 31 2c 20 26 72 63 29 3b 0a 20 20 20 20 7d 0a 0a  1, &rc);.    }..
69a0: 20 20 20 20 73 74 72 69 6e 67 5f 63 6f 6e 63 61      string_conca
69b0: 74 28 26 7a 2c 20 7a 49 6e 73 65 72 74 2c 20 31  t(&z, zInsert, 1
69c0: 2c 20 26 72 63 29 3b 0a 20 20 20 20 73 74 72 69  , &rc);.    stri
69d0: 6e 67 5f 63 6f 6e 63 61 74 28 26 7a 2c 20 22 29  ng_concat(&z, ")
69e0: 20 56 41 4c 55 45 53 28 22 2c 20 30 2c 20 26 72   VALUES(", 0, &r
69f0: 63 29 3b 0a 20 20 20 20 73 74 72 69 6e 67 5f 63  c);.    string_c
6a00: 6f 6e 63 61 74 28 26 7a 2c 20 7a 56 61 6c 75 65  oncat(&z, zValue
6a10: 73 2c 20 31 2c 20 26 72 63 29 3b 0a 20 20 20 20  s, 1, &rc);.    
6a20: 73 74 72 69 6e 67 5f 63 6f 6e 63 61 74 28 26 7a  string_concat(&z
6a30: 2c 20 22 29 22 2c 20 30 2c 20 26 72 63 29 3b 0a  , ")", 0, &rc);.
6a40: 20 20 7d 0a 0a 20 20 2f 2a 20 41 6e 79 74 68 69    }..  /* Anythi
6a50: 6e 67 20 65 6c 73 65 20 69 73 20 61 6e 20 65 72  ng else is an er
6a60: 72 6f 72 20 2a 2f 0a 20 20 65 6c 73 65 7b 0a 20  ror */.  else{. 
6a70: 20 20 20 61 73 73 65 72 74 28 30 29 3b 0a 20 20     assert(0);.  
6a80: 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f    return SQLITE_
6a90: 45 52 52 4f 52 3b 0a 20 20 7d 0a 0a 20 20 69 66  ERROR;.  }..  if
6aa0: 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
6ab0: 29 7b 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69  ){.    rc = sqli
6ac0: 74 65 33 5f 70 72 65 70 61 72 65 28 64 62 2c 20  te3_prepare(db, 
6ad0: 7a 2c 20 2d 31 2c 20 26 70 53 74 6d 74 2c 20 30  z, -1, &pStmt, 0
6ae0: 29 3b 0a 20 20 7d 0a 20 20 61 73 73 65 72 74 28  );.  }.  assert(
6af0: 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 7c   rc!=SQLITE_OK |
6b00: 7c 20 70 53 74 6d 74 20 29 3b 0a 20 20 73 71 6c  | pStmt );.  sql
6b10: 69 74 65 33 5f 66 72 65 65 28 7a 29 3b 0a 20 20  ite3_free(z);.  
6b20: 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  if( rc==SQLITE_O
6b30: 4b 20 29 20 7b 0a 20 20 20 20 69 66 28 20 62 69  K ) {.    if( bi
6b40: 6e 64 41 72 67 5a 65 72 6f 20 29 7b 0a 20 20 20  ndArgZero ){.   
6b50: 20 20 20 73 71 6c 69 74 65 33 5f 62 69 6e 64 5f     sqlite3_bind_
6b60: 76 61 6c 75 65 28 70 53 74 6d 74 2c 20 6e 44 61  value(pStmt, nDa
6b70: 74 61 2c 20 61 70 44 61 74 61 5b 30 5d 29 3b 0a  ta, apData[0]);.
6b80: 20 20 20 20 7d 0a 20 20 20 20 69 66 28 20 62 69      }.    if( bi
6b90: 6e 64 41 72 67 4f 6e 65 20 29 7b 0a 20 20 20 20  ndArgOne ){.    
6ba0: 20 20 73 71 6c 69 74 65 33 5f 62 69 6e 64 5f 76    sqlite3_bind_v
6bb0: 61 6c 75 65 28 70 53 74 6d 74 2c 20 31 2c 20 61  alue(pStmt, 1, a
6bc0: 70 44 61 74 61 5b 31 5d 29 3b 0a 20 20 20 20 7d  pData[1]);.    }
6bd0: 0a 20 20 20 20 66 6f 72 28 69 3d 32 3b 20 69 3c  .    for(i=2; i<
6be0: 6e 44 61 74 61 20 26 26 20 72 63 3d 3d 53 51 4c  nData && rc==SQL
6bf0: 49 54 45 5f 4f 4b 3b 20 69 2b 2b 29 7b 0a 20 20  ITE_OK; i++){.  
6c00: 20 20 20 20 69 66 28 20 61 70 44 61 74 61 5b 69      if( apData[i
6c10: 5d 20 29 20 72 63 20 3d 20 73 71 6c 69 74 65 33  ] ) rc = sqlite3
6c20: 5f 62 69 6e 64 5f 76 61 6c 75 65 28 70 53 74 6d  _bind_value(pStm
6c30: 74 2c 20 69 2c 20 61 70 44 61 74 61 5b 69 5d 29  t, i, apData[i])
6c40: 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 28 20  ;.    }.    if( 
6c50: 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc==SQLITE_OK ){
6c60: 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 73  .      sqlite3_s
6c70: 74 65 70 28 70 53 74 6d 74 29 3b 0a 20 20 20 20  tep(pStmt);.    
6c80: 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 66    rc = sqlite3_f
6c90: 69 6e 61 6c 69 7a 65 28 70 53 74 6d 74 29 3b 0a  inalize(pStmt);.
6ca0: 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20      }else{.     
6cb0: 20 73 71 6c 69 74 65 33 5f 66 69 6e 61 6c 69 7a   sqlite3_finaliz
6cc0: 65 28 70 53 74 6d 74 29 3b 0a 20 20 20 20 7d 0a  e(pStmt);.    }.
6cd0: 20 20 7d 0a 0a 20 20 69 66 28 20 70 52 6f 77 69    }..  if( pRowi
6ce0: 64 20 26 26 20 72 63 3d 3d 53 51 4c 49 54 45 5f  d && rc==SQLITE_
6cf0: 4f 4b 20 29 7b 0a 20 20 20 20 2a 70 52 6f 77 69  OK ){.    *pRowi
6d00: 64 20 3d 20 73 71 6c 69 74 65 33 5f 6c 61 73 74  d = sqlite3_last
6d10: 5f 69 6e 73 65 72 74 5f 72 6f 77 69 64 28 64 62  _insert_rowid(db
6d20: 29 3b 0a 20 20 7d 0a 20 20 69 66 28 20 72 63 21  );.  }.  if( rc!
6d30: 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20  =SQLITE_OK ){.  
6d40: 20 20 74 61 62 2d 3e 7a 45 72 72 4d 73 67 20 3d    tab->zErrMsg =
6d50: 20 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66   sqlite3_mprintf
6d60: 28 22 65 63 68 6f 2d 76 74 61 62 2d 65 72 72 6f  ("echo-vtab-erro
6d70: 72 3a 20 25 73 22 2c 20 73 71 6c 69 74 65 33 5f  r: %s", sqlite3_
6d80: 65 72 72 6d 73 67 28 64 62 29 29 3b 0a 20 20 7d  errmsg(db));.  }
6d90: 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d  ..  return rc;.}
6da0: 0a 0a 2f 2a 0a 2a 2a 20 78 42 65 67 69 6e 2c 20  ../*.** xBegin, 
6db0: 78 53 79 6e 63 2c 20 78 43 6f 6d 6d 69 74 20 61  xSync, xCommit a
6dc0: 6e 64 20 78 52 6f 6c 6c 62 61 63 6b 20 63 61 6c  nd xRollback cal
6dd0: 6c 62 61 63 6b 73 20 66 6f 72 20 65 63 68 6f 20  lbacks for echo 
6de0: 6d 6f 64 75 6c 65 0a 2a 2a 20 76 69 72 74 75 61  module.** virtua
6df0: 6c 20 74 61 62 6c 65 73 2e 20 44 6f 20 6e 6f 74  l tables. Do not
6e00: 68 69 6e 67 20 6f 74 68 65 72 20 74 68 61 6e 20  hing other than 
6e10: 61 64 64 20 74 68 65 20 6e 61 6d 65 20 6f 66 20  add the name of 
6e20: 74 68 65 20 63 61 6c 6c 62 61 63 6b 0a 2a 2a 20  the callback.** 
6e30: 74 6f 20 74 68 65 20 24 3a 3a 65 63 68 6f 5f 6d  to the $::echo_m
6e40: 6f 64 75 6c 65 20 54 63 6c 20 76 61 72 69 61 62  odule Tcl variab
6e50: 6c 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  le..*/.static in
6e60: 74 20 65 63 68 6f 54 72 61 6e 73 61 63 74 69 6f  t echoTransactio
6e70: 6e 43 61 6c 6c 28 73 71 6c 69 74 65 33 5f 76 74  nCall(sqlite3_vt
6e80: 61 62 20 2a 74 61 62 2c 20 63 6f 6e 73 74 20 63  ab *tab, const c
6e90: 68 61 72 20 2a 7a 43 61 6c 6c 29 7b 0a 20 20 63  har *zCall){.  c
6ea0: 68 61 72 20 2a 7a 3b 0a 20 20 65 63 68 6f 5f 76  har *z;.  echo_v
6eb0: 74 61 62 20 2a 70 56 74 61 62 20 3d 20 28 65 63  tab *pVtab = (ec
6ec0: 68 6f 5f 76 74 61 62 20 2a 29 74 61 62 3b 0a 20  ho_vtab *)tab;. 
6ed0: 20 7a 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72   z = sqlite3_mpr
6ee0: 69 6e 74 66 28 22 65 63 68 6f 28 25 73 29 22 2c  intf("echo(%s)",
6ef0: 20 70 56 74 61 62 2d 3e 7a 54 61 62 6c 65 4e 61   pVtab->zTableNa
6f00: 6d 65 29 3b 0a 20 20 69 66 28 20 7a 3d 3d 30 20  me);.  if( z==0 
6f10: 29 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f  ) return SQLITE_
6f20: 4e 4f 4d 45 4d 3b 0a 20 20 61 70 70 65 6e 64 54  NOMEM;.  appendT
6f30: 6f 45 63 68 6f 4d 6f 64 75 6c 65 28 70 56 74 61  oEchoModule(pVta
6f40: 62 2d 3e 69 6e 74 65 72 70 2c 20 7a 43 61 6c 6c  b->interp, zCall
6f50: 29 3b 0a 20 20 61 70 70 65 6e 64 54 6f 45 63 68  );.  appendToEch
6f60: 6f 4d 6f 64 75 6c 65 28 70 56 74 61 62 2d 3e 69  oModule(pVtab->i
6f70: 6e 74 65 72 70 2c 20 7a 29 3b 0a 20 20 73 71 6c  nterp, z);.  sql
6f80: 69 74 65 33 5f 66 72 65 65 28 7a 29 3b 0a 20 20  ite3_free(z);.  
6f90: 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b  return SQLITE_OK
6fa0: 3b 0a 7d 0a 73 74 61 74 69 63 20 69 6e 74 20 65  ;.}.static int e
6fb0: 63 68 6f 42 65 67 69 6e 28 73 71 6c 69 74 65 33  choBegin(sqlite3
6fc0: 5f 76 74 61 62 20 2a 74 61 62 29 7b 0a 20 20 69  _vtab *tab){.  i
6fd0: 6e 74 20 72 63 3b 0a 20 20 65 63 68 6f 5f 76 74  nt rc;.  echo_vt
6fe0: 61 62 20 2a 70 56 74 61 62 20 3d 20 28 65 63 68  ab *pVtab = (ech
6ff0: 6f 5f 76 74 61 62 20 2a 29 74 61 62 3b 0a 20 20  o_vtab *)tab;.  
7000: 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65  Tcl_Interp *inte
7010: 72 70 20 3d 20 70 56 74 61 62 2d 3e 69 6e 74 65  rp = pVtab->inte
7020: 72 70 3b 0a 20 20 63 6f 6e 73 74 20 63 68 61 72  rp;.  const char
7030: 20 2a 7a 56 61 6c 3b 20 0a 0a 20 20 2f 2a 20 54   *zVal; ..  /* T
7040: 69 63 6b 65 74 20 23 33 30 38 33 20 2d 20 64 6f  icket #3083 - do
7050: 20 6e 6f 74 20 73 74 61 72 74 20 61 20 74 72 61   not start a tra
7060: 6e 73 61 63 74 69 6f 6e 20 69 66 20 77 65 20 61  nsaction if we a
7070: 72 65 20 61 6c 72 65 61 64 79 20 69 6e 0a 20 20  re already in.  
7080: 2a 2a 20 61 20 74 72 61 6e 73 61 63 74 69 6f 6e  ** a transaction
7090: 20 2a 2f 0a 20 20 61 73 73 65 72 74 28 20 21 70   */.  assert( !p
70a0: 56 74 61 62 2d 3e 69 6e 54 72 61 6e 73 61 63 74  Vtab->inTransact
70b0: 69 6f 6e 20 29 3b 0a 0a 20 20 72 63 20 3d 20 65  ion );..  rc = e
70c0: 63 68 6f 54 72 61 6e 73 61 63 74 69 6f 6e 43 61  choTransactionCa
70d0: 6c 6c 28 74 61 62 2c 20 22 78 42 65 67 69 6e 22  ll(tab, "xBegin"
70e0: 29 3b 0a 0a 20 20 69 66 28 20 72 63 3d 3d 53 51  );..  if( rc==SQ
70f0: 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 2f  LITE_OK ){.    /
7100: 2a 20 43 68 65 63 6b 20 69 66 20 74 68 65 20 24  * Check if the $
7110: 3a 3a 65 63 68 6f 5f 6d 6f 64 75 6c 65 5f 62 65  ::echo_module_be
7120: 67 69 6e 5f 66 61 69 6c 20 76 61 72 69 61 62 6c  gin_fail variabl
7130: 65 20 69 73 20 64 65 66 69 6e 65 64 2e 20 49 66  e is defined. If
7140: 20 69 74 20 69 73 2c 0a 20 20 20 20 2a 2a 20 61   it is,.    ** a
7150: 6e 64 20 69 74 20 69 73 20 73 65 74 20 74 6f 20  nd it is set to 
7160: 74 68 65 20 6e 61 6d 65 20 6f 66 20 74 68 65 20  the name of the 
7170: 72 65 61 6c 20 74 61 62 6c 65 20 75 6e 64 65 72  real table under
7180: 6c 79 69 6e 67 20 74 68 69 73 20 76 69 72 74 75  lying this virtu
7190: 61 6c 0a 20 20 20 20 2a 2a 20 65 63 68 6f 20 6d  al.    ** echo m
71a0: 6f 64 75 6c 65 20 74 61 62 6c 65 2c 20 74 68 65  odule table, the
71b0: 6e 20 63 61 75 73 65 20 74 68 69 73 20 78 53 79  n cause this xSy
71c0: 6e 63 20 6f 70 65 72 61 74 69 6f 6e 20 74 6f 20  nc operation to 
71d0: 66 61 69 6c 2e 0a 20 20 20 20 2a 2f 0a 20 20 20  fail..    */.   
71e0: 20 7a 56 61 6c 20 3d 20 54 63 6c 5f 47 65 74 56   zVal = Tcl_GetV
71f0: 61 72 28 69 6e 74 65 72 70 2c 20 22 65 63 68 6f  ar(interp, "echo
7200: 5f 6d 6f 64 75 6c 65 5f 62 65 67 69 6e 5f 66 61  _module_begin_fa
7210: 69 6c 22 2c 20 54 43 4c 5f 47 4c 4f 42 41 4c 5f  il", TCL_GLOBAL_
7220: 4f 4e 4c 59 29 3b 0a 20 20 20 20 69 66 28 20 7a  ONLY);.    if( z
7230: 56 61 6c 20 26 26 20 30 3d 3d 73 74 72 63 6d 70  Val && 0==strcmp
7240: 28 7a 56 61 6c 2c 20 70 56 74 61 62 2d 3e 7a 54  (zVal, pVtab->zT
7250: 61 62 6c 65 4e 61 6d 65 29 20 29 7b 0a 20 20 20  ableName) ){.   
7260: 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 45     rc = SQLITE_E
7270: 52 52 4f 52 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a  RROR;.    }.  }.
7280: 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
7290: 5f 4f 4b 20 29 7b 0a 20 20 20 20 70 56 74 61 62  _OK ){.    pVtab
72a0: 2d 3e 69 6e 54 72 61 6e 73 61 63 74 69 6f 6e 20  ->inTransaction 
72b0: 3d 20 31 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72  = 1;.  }.  retur
72c0: 6e 20 72 63 3b 0a 7d 0a 73 74 61 74 69 63 20 69  n rc;.}.static i
72d0: 6e 74 20 65 63 68 6f 53 79 6e 63 28 73 71 6c 69  nt echoSync(sqli
72e0: 74 65 33 5f 76 74 61 62 20 2a 74 61 62 29 7b 0a  te3_vtab *tab){.
72f0: 20 20 69 6e 74 20 72 63 3b 0a 20 20 65 63 68 6f    int rc;.  echo
7300: 5f 76 74 61 62 20 2a 70 56 74 61 62 20 3d 20 28  _vtab *pVtab = (
7310: 65 63 68 6f 5f 76 74 61 62 20 2a 29 74 61 62 3b  echo_vtab *)tab;
7320: 0a 20 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69  .  Tcl_Interp *i
7330: 6e 74 65 72 70 20 3d 20 70 56 74 61 62 2d 3e 69  nterp = pVtab->i
7340: 6e 74 65 72 70 3b 0a 20 20 63 6f 6e 73 74 20 63  nterp;.  const c
7350: 68 61 72 20 2a 7a 56 61 6c 3b 20 0a 0a 20 20 2f  har *zVal; ..  /
7360: 2a 20 54 69 63 6b 65 74 20 23 33 30 38 33 20 2d  * Ticket #3083 -
7370: 20 4f 6e 6c 79 20 63 61 6c 6c 20 78 53 79 6e 63   Only call xSync
7380: 20 69 66 20 77 65 20 68 61 76 65 20 70 72 65 76   if we have prev
7390: 69 6f 75 73 6c 79 20 73 74 61 72 74 65 64 20 61  iously started a
73a0: 0a 20 20 2a 2a 20 74 72 61 6e 73 61 63 74 69 6f  .  ** transactio
73b0: 6e 20 2a 2f 0a 20 20 61 73 73 65 72 74 28 20 70  n */.  assert( p
73c0: 56 74 61 62 2d 3e 69 6e 54 72 61 6e 73 61 63 74  Vtab->inTransact
73d0: 69 6f 6e 20 29 3b 0a 0a 20 20 72 63 20 3d 20 65  ion );..  rc = e
73e0: 63 68 6f 54 72 61 6e 73 61 63 74 69 6f 6e 43 61  choTransactionCa
73f0: 6c 6c 28 74 61 62 2c 20 22 78 53 79 6e 63 22 29  ll(tab, "xSync")
7400: 3b 0a 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c  ;..  if( rc==SQL
7410: 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 2f 2a  ITE_OK ){.    /*
7420: 20 43 68 65 63 6b 20 69 66 20 74 68 65 20 24 3a   Check if the $:
7430: 3a 65 63 68 6f 5f 6d 6f 64 75 6c 65 5f 73 79 6e  :echo_module_syn
7440: 63 5f 66 61 69 6c 20 76 61 72 69 61 62 6c 65 20  c_fail variable 
7450: 69 73 20 64 65 66 69 6e 65 64 2e 20 49 66 20 69  is defined. If i
7460: 74 20 69 73 2c 0a 20 20 20 20 2a 2a 20 61 6e 64  t is,.    ** and
7470: 20 69 74 20 69 73 20 73 65 74 20 74 6f 20 74 68   it is set to th
7480: 65 20 6e 61 6d 65 20 6f 66 20 74 68 65 20 72 65  e name of the re
7490: 61 6c 20 74 61 62 6c 65 20 75 6e 64 65 72 6c 79  al table underly
74a0: 69 6e 67 20 74 68 69 73 20 76 69 72 74 75 61 6c  ing this virtual
74b0: 0a 20 20 20 20 2a 2a 20 65 63 68 6f 20 6d 6f 64  .    ** echo mod
74c0: 75 6c 65 20 74 61 62 6c 65 2c 20 74 68 65 6e 20  ule table, then 
74d0: 63 61 75 73 65 20 74 68 69 73 20 78 53 79 6e 63  cause this xSync
74e0: 20 6f 70 65 72 61 74 69 6f 6e 20 74 6f 20 66 61   operation to fa
74f0: 69 6c 2e 0a 20 20 20 20 2a 2f 0a 20 20 20 20 7a  il..    */.    z
7500: 56 61 6c 20 3d 20 54 63 6c 5f 47 65 74 56 61 72  Val = Tcl_GetVar
7510: 28 69 6e 74 65 72 70 2c 20 22 65 63 68 6f 5f 6d  (interp, "echo_m
7520: 6f 64 75 6c 65 5f 73 79 6e 63 5f 66 61 69 6c 22  odule_sync_fail"
7530: 2c 20 54 43 4c 5f 47 4c 4f 42 41 4c 5f 4f 4e 4c  , TCL_GLOBAL_ONL
7540: 59 29 3b 0a 20 20 20 20 69 66 28 20 7a 56 61 6c  Y);.    if( zVal
7550: 20 26 26 20 30 3d 3d 73 74 72 63 6d 70 28 7a 56   && 0==strcmp(zV
7560: 61 6c 2c 20 70 56 74 61 62 2d 3e 7a 54 61 62 6c  al, pVtab->zTabl
7570: 65 4e 61 6d 65 29 20 29 7b 0a 20 20 20 20 20 20  eName) ){.      
7580: 72 63 20 3d 20 2d 31 3b 0a 20 20 20 20 7d 0a 20  rc = -1;.    }. 
7590: 20 7d 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a   }.  return rc;.
75a0: 7d 0a 73 74 61 74 69 63 20 69 6e 74 20 65 63 68  }.static int ech
75b0: 6f 43 6f 6d 6d 69 74 28 73 71 6c 69 74 65 33 5f  oCommit(sqlite3_
75c0: 76 74 61 62 20 2a 74 61 62 29 7b 0a 20 20 65 63  vtab *tab){.  ec
75d0: 68 6f 5f 76 74 61 62 20 2a 70 56 74 61 62 20 3d  ho_vtab *pVtab =
75e0: 20 28 65 63 68 6f 5f 76 74 61 62 2a 29 74 61 62   (echo_vtab*)tab
75f0: 3b 0a 20 20 69 6e 74 20 72 63 3b 0a 0a 20 20 2f  ;.  int rc;..  /
7600: 2a 20 54 69 63 6b 65 74 20 23 33 30 38 33 20 2d  * Ticket #3083 -
7610: 20 4f 6e 6c 79 20 63 61 6c 6c 20 78 43 6f 6d 6d   Only call xComm
7620: 69 74 20 69 66 20 77 65 20 68 61 76 65 20 70 72  it if we have pr
7630: 65 76 69 6f 75 73 6c 79 20 73 74 61 72 74 65 64  eviously started
7640: 0a 20 20 2a 2a 20 61 20 74 72 61 6e 73 61 63 74  .  ** a transact
7650: 69 6f 6e 20 2a 2f 0a 20 20 61 73 73 65 72 74 28  ion */.  assert(
7660: 20 70 56 74 61 62 2d 3e 69 6e 54 72 61 6e 73 61   pVtab->inTransa
7670: 63 74 69 6f 6e 20 29 3b 0a 0a 20 20 73 71 6c 69  ction );..  sqli
7680: 74 65 33 42 65 67 69 6e 42 65 6e 69 67 6e 4d 61  te3BeginBenignMa
7690: 6c 6c 6f 63 28 29 3b 0a 20 20 72 63 20 3d 20 65  lloc();.  rc = e
76a0: 63 68 6f 54 72 61 6e 73 61 63 74 69 6f 6e 43 61  choTransactionCa
76b0: 6c 6c 28 74 61 62 2c 20 22 78 43 6f 6d 6d 69 74  ll(tab, "xCommit
76c0: 22 29 3b 0a 20 20 73 71 6c 69 74 65 33 45 6e 64  ");.  sqlite3End
76d0: 42 65 6e 69 67 6e 4d 61 6c 6c 6f 63 28 29 3b 0a  BenignMalloc();.
76e0: 20 20 70 56 74 61 62 2d 3e 69 6e 54 72 61 6e 73    pVtab->inTrans
76f0: 61 63 74 69 6f 6e 20 3d 20 30 3b 0a 20 20 72 65  action = 0;.  re
7700: 74 75 72 6e 20 72 63 3b 0a 7d 0a 73 74 61 74 69  turn rc;.}.stati
7710: 63 20 69 6e 74 20 65 63 68 6f 52 6f 6c 6c 62 61  c int echoRollba
7720: 63 6b 28 73 71 6c 69 74 65 33 5f 76 74 61 62 20  ck(sqlite3_vtab 
7730: 2a 74 61 62 29 7b 0a 20 20 69 6e 74 20 72 63 3b  *tab){.  int rc;
7740: 0a 20 20 65 63 68 6f 5f 76 74 61 62 20 2a 70 56  .  echo_vtab *pV
7750: 74 61 62 20 3d 20 28 65 63 68 6f 5f 76 74 61 62  tab = (echo_vtab
7760: 2a 29 74 61 62 3b 0a 0a 20 20 2f 2a 20 54 69 63  *)tab;..  /* Tic
7770: 6b 65 74 20 23 33 30 38 33 20 2d 20 4f 6e 6c 79  ket #3083 - Only
7780: 20 63 61 6c 6c 20 78 52 6f 6c 6c 62 61 63 6b 20   call xRollback 
7790: 69 66 20 77 65 20 68 61 76 65 20 70 72 65 76 69  if we have previ
77a0: 6f 75 73 6c 79 20 73 74 61 72 74 65 64 0a 20 20  ously started.  
77b0: 2a 2a 20 61 20 74 72 61 6e 73 61 63 74 69 6f 6e  ** a transaction
77c0: 20 2a 2f 0a 20 20 61 73 73 65 72 74 28 20 70 56   */.  assert( pV
77d0: 74 61 62 2d 3e 69 6e 54 72 61 6e 73 61 63 74 69  tab->inTransacti
77e0: 6f 6e 20 29 3b 0a 0a 20 20 72 63 20 3d 20 65 63  on );..  rc = ec
77f0: 68 6f 54 72 61 6e 73 61 63 74 69 6f 6e 43 61 6c  hoTransactionCal
7800: 6c 28 74 61 62 2c 20 22 78 52 6f 6c 6c 62 61 63  l(tab, "xRollbac
7810: 6b 22 29 3b 0a 20 20 70 56 74 61 62 2d 3e 69 6e  k");.  pVtab->in
7820: 54 72 61 6e 73 61 63 74 69 6f 6e 20 3d 20 30 3b  Transaction = 0;
7830: 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a  .  return rc;.}.
7840: 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74  ./*.** Implement
7850: 61 74 69 6f 6e 20 6f 66 20 22 47 4c 4f 42 22 20  ation of "GLOB" 
7860: 66 75 6e 63 74 69 6f 6e 20 6f 6e 20 74 68 65 20  function on the 
7870: 65 63 68 6f 20 6d 6f 64 75 6c 65 2e 20 20 50 61  echo module.  Pa
7880: 73 73 0a 2a 2a 20 61 6c 6c 20 61 72 67 75 6d 65  ss.** all argume
7890: 6e 74 73 20 74 6f 20 74 68 65 20 3a 3a 65 63 68  nts to the ::ech
78a0: 6f 5f 67 6c 6f 62 5f 6f 76 65 72 6c 6f 61 64 20  o_glob_overload 
78b0: 70 72 6f 63 65 64 75 72 65 20 6f 66 20 54 43 4c  procedure of TCL
78c0: 0a 2a 2a 20 61 6e 64 20 72 65 74 75 72 6e 20 74  .** and return t
78d0: 68 65 20 72 65 73 75 6c 74 20 6f 66 20 74 68 61  he result of tha
78e0: 74 20 70 72 6f 63 65 64 75 72 65 20 61 73 20 61  t procedure as a
78f0: 20 73 74 72 69 6e 67 2e 0a 2a 2f 0a 73 74 61 74   string..*/.stat
7900: 69 63 20 76 6f 69 64 20 6f 76 65 72 6c 6f 61 64  ic void overload
7910: 65 64 47 6c 6f 62 46 75 6e 63 74 69 6f 6e 28 0a  edGlobFunction(.
7920: 20 20 73 71 6c 69 74 65 33 5f 63 6f 6e 74 65 78    sqlite3_contex
7930: 74 20 2a 70 43 6f 6e 74 65 78 74 2c 0a 20 20 69  t *pContext,.  i
7940: 6e 74 20 6e 41 72 67 2c 0a 20 20 73 71 6c 69 74  nt nArg,.  sqlit
7950: 65 33 5f 76 61 6c 75 65 20 2a 2a 61 70 41 72 67  e3_value **apArg
7960: 0a 29 7b 0a 20 20 54 63 6c 5f 49 6e 74 65 72 70  .){.  Tcl_Interp
7970: 20 2a 69 6e 74 65 72 70 20 3d 20 73 71 6c 69 74   *interp = sqlit
7980: 65 33 5f 75 73 65 72 5f 64 61 74 61 28 70 43 6f  e3_user_data(pCo
7990: 6e 74 65 78 74 29 3b 0a 20 20 54 63 6c 5f 44 53  ntext);.  Tcl_DS
79a0: 74 72 69 6e 67 20 73 74 72 3b 0a 20 20 69 6e 74  tring str;.  int
79b0: 20 69 3b 0a 20 20 69 6e 74 20 72 63 3b 0a 20 20   i;.  int rc;.  
79c0: 54 63 6c 5f 44 53 74 72 69 6e 67 49 6e 69 74 28  Tcl_DStringInit(
79d0: 26 73 74 72 29 3b 0a 20 20 54 63 6c 5f 44 53 74  &str);.  Tcl_DSt
79e0: 72 69 6e 67 41 70 70 65 6e 64 45 6c 65 6d 65 6e  ringAppendElemen
79f0: 74 28 26 73 74 72 2c 20 22 3a 3a 65 63 68 6f 5f  t(&str, "::echo_
7a00: 67 6c 6f 62 5f 6f 76 65 72 6c 6f 61 64 22 29 3b  glob_overload");
7a10: 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 6e 41  .  for(i=0; i<nA
7a20: 72 67 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 54 63  rg; i++){.    Tc
7a30: 6c 5f 44 53 74 72 69 6e 67 41 70 70 65 6e 64 45  l_DStringAppendE
7a40: 6c 65 6d 65 6e 74 28 26 73 74 72 2c 20 28 63 68  lement(&str, (ch
7a50: 61 72 2a 29 73 71 6c 69 74 65 33 5f 76 61 6c 75  ar*)sqlite3_valu
7a60: 65 5f 74 65 78 74 28 61 70 41 72 67 5b 69 5d 29  e_text(apArg[i])
7a70: 29 3b 0a 20 20 7d 0a 20 20 72 63 20 3d 20 54 63  );.  }.  rc = Tc
7a80: 6c 5f 45 76 61 6c 28 69 6e 74 65 72 70 2c 20 54  l_Eval(interp, T
7a90: 63 6c 5f 44 53 74 72 69 6e 67 56 61 6c 75 65 28  cl_DStringValue(
7aa0: 26 73 74 72 29 29 3b 0a 20 20 54 63 6c 5f 44 53  &str));.  Tcl_DS
7ab0: 74 72 69 6e 67 46 72 65 65 28 26 73 74 72 29 3b  tringFree(&str);
7ac0: 0a 20 20 69 66 28 20 72 63 20 29 7b 0a 20 20 20  .  if( rc ){.   
7ad0: 20 73 71 6c 69 74 65 33 5f 72 65 73 75 6c 74 5f   sqlite3_result_
7ae0: 65 72 72 6f 72 28 70 43 6f 6e 74 65 78 74 2c 20  error(pContext, 
7af0: 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73  Tcl_GetStringRes
7b00: 75 6c 74 28 69 6e 74 65 72 70 29 2c 20 2d 31 29  ult(interp), -1)
7b10: 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 73  ;.  }else{.    s
7b20: 71 6c 69 74 65 33 5f 72 65 73 75 6c 74 5f 74 65  qlite3_result_te
7b30: 78 74 28 70 43 6f 6e 74 65 78 74 2c 20 54 63 6c  xt(pContext, Tcl
7b40: 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74  _GetStringResult
7b50: 28 69 6e 74 65 72 70 29 2c 0a 20 20 20 20 20 20  (interp),.      
7b60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7b70: 20 20 2d 31 2c 20 53 51 4c 49 54 45 5f 54 52 41    -1, SQLITE_TRA
7b80: 4e 53 49 45 4e 54 29 3b 0a 20 20 7d 0a 20 20 54  NSIENT);.  }.  T
7b90: 63 6c 5f 52 65 73 65 74 52 65 73 75 6c 74 28 69  cl_ResetResult(i
7ba0: 6e 74 65 72 70 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  nterp);.}../*.**
7bb0: 20 54 68 69 73 20 69 73 20 74 68 65 20 78 46 69   This is the xFi
7bc0: 6e 64 46 75 6e 63 74 69 6f 6e 20 69 6d 70 6c 65  ndFunction imple
7bd0: 6d 65 6e 74 61 74 69 6f 6e 20 66 6f 72 20 74 68  mentation for th
7be0: 65 20 65 63 68 6f 20 6d 6f 64 75 6c 65 2e 0a 2a  e echo module..*
7bf0: 2a 20 53 51 4c 69 74 65 20 63 61 6c 6c 73 20 74  * SQLite calls t
7c00: 68 69 73 20 72 6f 75 74 69 6e 65 20 77 68 65 6e  his routine when
7c10: 20 74 68 65 20 66 69 72 73 74 20 61 72 67 75 6d   the first argum
7c20: 65 6e 74 20 6f 66 20 61 20 66 75 6e 63 74 69 6f  ent of a functio
7c30: 6e 0a 2a 2a 20 69 73 20 61 20 63 6f 6c 75 6d 6e  n.** is a column
7c40: 20 6f 66 20 61 6e 20 65 63 68 6f 20 76 69 72 74   of an echo virt
7c50: 75 61 6c 20 74 61 62 6c 65 2e 20 20 54 68 69 73  ual table.  This
7c60: 20 72 6f 75 74 69 6e 65 20 63 61 6e 20 6f 70 74   routine can opt
7c70: 69 6f 6e 61 6c 6c 79 0a 2a 2a 20 6f 76 65 72 72  ionally.** overr
7c80: 69 64 65 20 74 68 65 20 69 6d 70 6c 65 6d 65 6e  ide the implemen
7c90: 74 61 74 69 6f 6e 20 6f 66 20 74 68 61 74 20 66  tation of that f
7ca0: 75 6e 63 74 69 6f 6e 2e 20 20 49 74 20 77 69 6c  unction.  It wil
7cb0: 6c 20 63 68 6f 6f 73 65 20 74 6f 0a 2a 2a 20 64  l choose to.** d
7cc0: 6f 20 73 6f 20 69 66 20 74 68 65 20 66 75 6e 63  o so if the func
7cd0: 74 69 6f 6e 20 69 73 20 6e 61 6d 65 64 20 22 67  tion is named "g
7ce0: 6c 6f 62 22 2c 20 61 6e 64 20 61 20 54 43 4c 20  lob", and a TCL 
7cf0: 63 6f 6d 6d 61 6e 64 20 6e 61 6d 65 64 0a 2a 2a  command named.**
7d00: 20 3a 3a 65 63 68 6f 5f 67 6c 6f 62 5f 6f 76 65   ::echo_glob_ove
7d10: 72 6c 6f 61 64 20 65 78 69 73 74 73 2e 0a 2a 2f  rload exists..*/
7d20: 0a 73 74 61 74 69 63 20 69 6e 74 20 65 63 68 6f  .static int echo
7d30: 46 69 6e 64 46 75 6e 63 74 69 6f 6e 28 0a 20 20  FindFunction(.  
7d40: 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 76 74  sqlite3_vtab *vt
7d50: 61 62 2c 0a 20 20 69 6e 74 20 6e 41 72 67 2c 0a  ab,.  int nArg,.
7d60: 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 46    const char *zF
7d70: 75 6e 63 4e 61 6d 65 2c 0a 20 20 76 6f 69 64 20  uncName,.  void 
7d80: 28 2a 2a 70 78 46 75 6e 63 29 28 73 71 6c 69 74  (**pxFunc)(sqlit
7d90: 65 33 5f 63 6f 6e 74 65 78 74 2a 2c 69 6e 74 2c  e3_context*,int,
7da0: 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 2a 2a 29  sqlite3_value**)
7db0: 2c 0a 20 20 76 6f 69 64 20 2a 2a 70 70 41 72 67  ,.  void **ppArg
7dc0: 0a 29 7b 0a 20 20 65 63 68 6f 5f 76 74 61 62 20  .){.  echo_vtab 
7dd0: 2a 70 56 74 61 62 20 3d 20 28 65 63 68 6f 5f 76  *pVtab = (echo_v
7de0: 74 61 62 20 2a 29 76 74 61 62 3b 0a 20 20 54 63  tab *)vtab;.  Tc
7df0: 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70  l_Interp *interp
7e00: 20 3d 20 70 56 74 61 62 2d 3e 69 6e 74 65 72 70   = pVtab->interp
7e10: 3b 0a 20 20 54 63 6c 5f 43 6d 64 49 6e 66 6f 20  ;.  Tcl_CmdInfo 
7e20: 69 6e 66 6f 3b 0a 20 20 69 66 28 20 73 74 72 63  info;.  if( strc
7e30: 6d 70 28 7a 46 75 6e 63 4e 61 6d 65 2c 22 67 6c  mp(zFuncName,"gl
7e40: 6f 62 22 29 21 3d 30 20 29 7b 0a 20 20 20 20 72  ob")!=0 ){.    r
7e50: 65 74 75 72 6e 20 30 3b 0a 20 20 7d 0a 20 20 69  eturn 0;.  }.  i
7e60: 66 28 20 54 63 6c 5f 47 65 74 43 6f 6d 6d 61 6e  f( Tcl_GetComman
7e70: 64 49 6e 66 6f 28 69 6e 74 65 72 70 2c 20 22 3a  dInfo(interp, ":
7e80: 3a 65 63 68 6f 5f 67 6c 6f 62 5f 6f 76 65 72 6c  :echo_glob_overl
7e90: 6f 61 64 22 2c 20 26 69 6e 66 6f 29 3d 3d 30 20  oad", &info)==0 
7ea0: 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 30 3b  ){.    return 0;
7eb0: 0a 20 20 7d 0a 20 20 2a 70 78 46 75 6e 63 20 3d  .  }.  *pxFunc =
7ec0: 20 6f 76 65 72 6c 6f 61 64 65 64 47 6c 6f 62 46   overloadedGlobF
7ed0: 75 6e 63 74 69 6f 6e 3b 0a 20 20 2a 70 70 41 72  unction;.  *ppAr
7ee0: 67 20 3d 20 69 6e 74 65 72 70 3b 0a 20 20 72 65  g = interp;.  re
7ef0: 74 75 72 6e 20 31 3b 0a 7d 0a 0a 73 74 61 74 69  turn 1;.}..stati
7f00: 63 20 69 6e 74 20 65 63 68 6f 52 65 6e 61 6d 65  c int echoRename
7f10: 28 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 76  (sqlite3_vtab *v
7f20: 74 61 62 2c 20 63 6f 6e 73 74 20 63 68 61 72 20  tab, const char 
7f30: 2a 7a 4e 65 77 4e 61 6d 65 29 7b 0a 20 20 69 6e  *zNewName){.  in
7f40: 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b  t rc = SQLITE_OK
7f50: 3b 0a 20 20 65 63 68 6f 5f 76 74 61 62 20 2a 70  ;.  echo_vtab *p
7f60: 20 3d 20 28 65 63 68 6f 5f 76 74 61 62 20 2a 29   = (echo_vtab *)
7f70: 76 74 61 62 3b 0a 0a 20 20 69 66 28 20 70 2d 3e  vtab;..  if( p->
7f80: 69 73 50 61 74 74 65 72 6e 20 29 7b 0a 20 20 20  isPattern ){.   
7f90: 20 69 6e 74 20 6e 54 68 69 73 20 3d 20 73 74 72   int nThis = str
7fa0: 6c 65 6e 28 70 2d 3e 7a 54 68 69 73 29 3b 0a 20  len(p->zThis);. 
7fb0: 20 20 20 63 68 61 72 20 2a 7a 53 71 6c 20 3d 20     char *zSql = 
7fc0: 73 71 6c 69 74 65 33 4d 50 72 69 6e 74 66 28 30  sqlite3MPrintf(0
7fd0: 2c 20 22 41 4c 54 45 52 20 54 41 42 4c 45 20 25  , "ALTER TABLE %
7fe0: 73 20 52 45 4e 41 4d 45 20 54 4f 20 25 73 25 73  s RENAME TO %s%s
7ff0: 22 2c 20 0a 20 20 20 20 20 20 20 20 70 2d 3e 7a  ", .        p->z
8000: 54 61 62 6c 65 4e 61 6d 65 2c 20 7a 4e 65 77 4e  TableName, zNewN
8010: 61 6d 65 2c 20 26 70 2d 3e 7a 54 61 62 6c 65 4e  ame, &p->zTableN
8020: 61 6d 65 5b 6e 54 68 69 73 5d 0a 20 20 20 20 29  ame[nThis].    )
8030: 3b 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74  ;.    rc = sqlit
8040: 65 33 5f 65 78 65 63 28 70 2d 3e 64 62 2c 20 7a  e3_exec(p->db, z
8050: 53 71 6c 2c 20 30 2c 20 30 2c 20 30 29 3b 0a 20  Sql, 0, 0, 0);. 
8060: 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28     sqlite3_free(
8070: 7a 53 71 6c 29 3b 0a 20 20 7d 0a 0a 20 20 72 65  zSql);.  }..  re
8080: 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a  turn rc;.}../*.*
8090: 2a 20 41 20 76 69 72 74 75 61 6c 20 74 61 62 6c  * A virtual tabl
80a0: 65 20 6d 6f 64 75 6c 65 20 74 68 61 74 20 6d 65  e module that me
80b0: 72 65 6c 79 20 22 65 63 68 6f 73 22 20 74 68 65  rely "echos" the
80c0: 20 63 6f 6e 74 65 6e 74 73 20 6f 66 20 61 6e 6f   contents of ano
80d0: 74 68 65 72 0a 2a 2a 20 74 61 62 6c 65 20 28 6c  ther.** table (l
80e0: 69 6b 65 20 61 6e 20 53 51 4c 20 56 49 45 57 29  ike an SQL VIEW)
80f0: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 73 71 6c 69  ..*/.static sqli
8100: 74 65 33 5f 6d 6f 64 75 6c 65 20 65 63 68 6f 4d  te3_module echoM
8110: 6f 64 75 6c 65 20 3d 20 7b 0a 20 20 30 2c 20 20  odule = {.  0,  
8120: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8130: 20 20 20 20 20 20 20 2f 2a 20 69 56 65 72 73 69         /* iVersi
8140: 6f 6e 20 2a 2f 0a 20 20 65 63 68 6f 43 72 65 61  on */.  echoCrea
8150: 74 65 2c 0a 20 20 65 63 68 6f 43 6f 6e 6e 65 63  te,.  echoConnec
8160: 74 2c 0a 20 20 65 63 68 6f 42 65 73 74 49 6e 64  t,.  echoBestInd
8170: 65 78 2c 0a 20 20 65 63 68 6f 44 69 73 63 6f 6e  ex,.  echoDiscon
8180: 6e 65 63 74 2c 20 0a 20 20 65 63 68 6f 44 65 73  nect, .  echoDes
8190: 74 72 6f 79 2c 0a 20 20 65 63 68 6f 4f 70 65 6e  troy,.  echoOpen
81a0: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
81b0: 20 20 20 2f 2a 20 78 4f 70 65 6e 20 2d 20 6f 70     /* xOpen - op
81c0: 65 6e 20 61 20 63 75 72 73 6f 72 20 2a 2f 0a 20  en a cursor */. 
81d0: 20 65 63 68 6f 43 6c 6f 73 65 2c 20 20 20 20 20   echoClose,     
81e0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78              /* x
81f0: 43 6c 6f 73 65 20 2d 20 63 6c 6f 73 65 20 61 20  Close - close a 
8200: 63 75 72 73 6f 72 20 2a 2f 0a 20 20 65 63 68 6f  cursor */.  echo
8210: 46 69 6c 74 65 72 2c 20 20 20 20 20 20 20 20 20  Filter,         
8220: 20 20 20 20 20 20 20 2f 2a 20 78 46 69 6c 74 65         /* xFilte
8230: 72 20 2d 20 63 6f 6e 66 69 67 75 72 65 20 73 63  r - configure sc
8240: 61 6e 20 63 6f 6e 73 74 72 61 69 6e 74 73 20 2a  an constraints *
8250: 2f 0a 20 20 65 63 68 6f 4e 65 78 74 2c 20 20 20  /.  echoNext,   
8260: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
8270: 2a 20 78 4e 65 78 74 20 2d 20 61 64 76 61 6e 63  * xNext - advanc
8280: 65 20 61 20 63 75 72 73 6f 72 20 2a 2f 0a 20 20  e a cursor */.  
8290: 65 63 68 6f 45 6f 66 2c 20 20 20 20 20 20 20 20  echoEof,        
82a0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 45             /* xE
82b0: 6f 66 20 2a 2f 0a 20 20 65 63 68 6f 43 6f 6c 75  of */.  echoColu
82c0: 6d 6e 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  mn,             
82d0: 20 20 20 2f 2a 20 78 43 6f 6c 75 6d 6e 20 2d 20     /* xColumn - 
82e0: 72 65 61 64 20 64 61 74 61 20 2a 2f 0a 20 20 65  read data */.  e
82f0: 63 68 6f 52 6f 77 69 64 2c 20 20 20 20 20 20 20  choRowid,       
8300: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 52 6f            /* xRo
8310: 77 69 64 20 2d 20 72 65 61 64 20 64 61 74 61 20  wid - read data 
8320: 2a 2f 0a 20 20 65 63 68 6f 55 70 64 61 74 65 2c  */.  echoUpdate,
8330: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8340: 2f 2a 20 78 55 70 64 61 74 65 20 2d 20 77 72 69  /* xUpdate - wri
8350: 74 65 20 64 61 74 61 20 2a 2f 0a 20 20 65 63 68  te data */.  ech
8360: 6f 42 65 67 69 6e 2c 20 20 20 20 20 20 20 20 20  oBegin,         
8370: 20 20 20 20 20 20 20 20 2f 2a 20 78 42 65 67 69          /* xBegi
8380: 6e 20 2d 20 62 65 67 69 6e 20 74 72 61 6e 73 61  n - begin transa
8390: 63 74 69 6f 6e 20 2a 2f 0a 20 20 65 63 68 6f 53  ction */.  echoS
83a0: 79 6e 63 2c 20 20 20 20 20 20 20 20 20 20 20 20  ync,            
83b0: 20 20 20 20 20 20 2f 2a 20 78 53 79 6e 63 20 2d        /* xSync -
83c0: 20 73 79 6e 63 20 74 72 61 6e 73 61 63 74 69 6f   sync transactio
83d0: 6e 20 2a 2f 0a 20 20 65 63 68 6f 43 6f 6d 6d 69  n */.  echoCommi
83e0: 74 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  t,              
83f0: 20 20 2f 2a 20 78 43 6f 6d 6d 69 74 20 2d 20 63    /* xCommit - c
8400: 6f 6d 6d 69 74 20 74 72 61 6e 73 61 63 74 69 6f  ommit transactio
8410: 6e 20 2a 2f 0a 20 20 65 63 68 6f 52 6f 6c 6c 62  n */.  echoRollb
8420: 61 63 6b 2c 20 20 20 20 20 20 20 20 20 20 20 20  ack,            
8430: 20 20 2f 2a 20 78 52 6f 6c 6c 62 61 63 6b 20 2d    /* xRollback -
8440: 20 72 6f 6c 6c 62 61 63 6b 20 74 72 61 6e 73 61   rollback transa
8450: 63 74 69 6f 6e 20 2a 2f 0a 20 20 65 63 68 6f 46  ction */.  echoF
8460: 69 6e 64 46 75 6e 63 74 69 6f 6e 2c 20 20 20 20  indFunction,    
8470: 20 20 20 20 20 20 2f 2a 20 78 46 69 6e 64 46 75        /* xFindFu
8480: 6e 63 74 69 6f 6e 20 2d 20 66 75 6e 63 74 69 6f  nction - functio
8490: 6e 20 6f 76 65 72 6c 6f 61 64 69 6e 67 20 2a 2f  n overloading */
84a0: 0a 20 20 65 63 68 6f 52 65 6e 61 6d 65 2c 20 20  .  echoRename,  
84b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
84c0: 20 78 52 65 6e 61 6d 65 20 2d 20 72 65 6e 61 6d   xRename - renam
84d0: 65 20 74 68 65 20 74 61 62 6c 65 20 2a 2f 0a 7d  e the table */.}
84e0: 3b 0a 0a 2f 2a 0a 2a 2a 20 44 65 63 6f 64 65 20  ;../*.** Decode 
84f0: 61 20 70 6f 69 6e 74 65 72 20 74 6f 20 61 6e 20  a pointer to an 
8500: 73 71 6c 69 74 65 33 20 6f 62 6a 65 63 74 2e 0a  sqlite3 object..
8510: 2a 2f 0a 65 78 74 65 72 6e 20 69 6e 74 20 67 65  */.extern int ge
8520: 74 44 62 50 6f 69 6e 74 65 72 28 54 63 6c 5f 49  tDbPointer(Tcl_I
8530: 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 2c 20 63  nterp *interp, c
8540: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 41 2c 20 73  onst char *zA, s
8550: 71 6c 69 74 65 33 20 2a 2a 70 70 44 62 29 3b 0a  qlite3 **ppDb);.
8560: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 6d 6f 64  .static void mod
8570: 75 6c 65 44 65 73 74 72 6f 79 28 76 6f 69 64 20  uleDestroy(void 
8580: 2a 70 29 7b 0a 20 20 73 71 6c 69 74 65 33 5f 66  *p){.  sqlite3_f
8590: 72 65 65 28 70 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  ree(p);.}../*.**
85a0: 20 52 65 67 69 73 74 65 72 20 74 68 65 20 65 63   Register the ec
85b0: 68 6f 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65  ho virtual table
85c0: 20 6d 6f 64 75 6c 65 2e 0a 2a 2f 0a 73 74 61 74   module..*/.stat
85d0: 69 63 20 69 6e 74 20 72 65 67 69 73 74 65 72 5f  ic int register_
85e0: 65 63 68 6f 5f 6d 6f 64 75 6c 65 28 0a 20 20 43  echo_module(.  C
85f0: 6c 69 65 6e 74 44 61 74 61 20 63 6c 69 65 6e 74  lientData client
8600: 44 61 74 61 2c 20 2f 2a 20 50 6f 69 6e 74 65 72  Data, /* Pointer
8610: 20 74 6f 20 73 71 6c 69 74 65 33 5f 65 6e 61 62   to sqlite3_enab
8620: 6c 65 5f 58 58 58 20 66 75 6e 63 74 69 6f 6e 20  le_XXX function 
8630: 2a 2f 0a 20 20 54 63 6c 5f 49 6e 74 65 72 70 20  */.  Tcl_Interp 
8640: 2a 69 6e 74 65 72 70 2c 20 20 20 20 2f 2a 20 54  *interp,    /* T
8650: 68 65 20 54 43 4c 20 69 6e 74 65 72 70 72 65 74  he TCL interpret
8660: 65 72 20 74 68 61 74 20 69 6e 76 6f 6b 65 64 20  er that invoked 
8670: 74 68 69 73 20 63 6f 6d 6d 61 6e 64 20 2a 2f 0a  this command */.
8680: 20 20 69 6e 74 20 6f 62 6a 63 2c 20 20 20 20 20    int objc,     
8690: 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62           /* Numb
86a0: 65 72 20 6f 66 20 61 72 67 75 6d 65 6e 74 73 20  er of arguments 
86b0: 2a 2f 0a 20 20 54 63 6c 5f 4f 62 6a 20 2a 43 4f  */.  Tcl_Obj *CO
86c0: 4e 53 54 20 6f 62 6a 76 5b 5d 20 20 2f 2a 20 43  NST objv[]  /* C
86d0: 6f 6d 6d 61 6e 64 20 61 72 67 75 6d 65 6e 74 73  ommand arguments
86e0: 20 2a 2f 0a 29 7b 0a 20 20 73 71 6c 69 74 65 33   */.){.  sqlite3
86f0: 20 2a 64 62 3b 0a 20 20 45 63 68 6f 4d 6f 64 75   *db;.  EchoModu
8700: 6c 65 20 2a 70 4d 6f 64 3b 0a 20 20 69 66 28 20  le *pMod;.  if( 
8710: 6f 62 6a 63 21 3d 32 20 29 7b 0a 20 20 20 20 54  objc!=2 ){.    T
8720: 63 6c 5f 57 72 6f 6e 67 4e 75 6d 41 72 67 73 28  cl_WrongNumArgs(
8730: 69 6e 74 65 72 70 2c 20 31 2c 20 6f 62 6a 76 2c  interp, 1, objv,
8740: 20 22 44 42 22 29 3b 0a 20 20 20 20 72 65 74 75   "DB");.    retu
8750: 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20  rn TCL_ERROR;.  
8760: 7d 0a 20 20 69 66 28 20 67 65 74 44 62 50 6f 69  }.  if( getDbPoi
8770: 6e 74 65 72 28 69 6e 74 65 72 70 2c 20 54 63 6c  nter(interp, Tcl
8780: 5f 47 65 74 53 74 72 69 6e 67 28 6f 62 6a 76 5b  _GetString(objv[
8790: 31 5d 29 2c 20 26 64 62 29 20 29 20 72 65 74 75  1]), &db) ) retu
87a0: 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20  rn TCL_ERROR;.  
87b0: 70 4d 6f 64 20 3d 20 73 71 6c 69 74 65 33 5f 6d  pMod = sqlite3_m
87c0: 61 6c 6c 6f 63 28 73 69 7a 65 6f 66 28 45 63 68  alloc(sizeof(Ech
87d0: 6f 4d 6f 64 75 6c 65 29 29 3b 0a 20 20 70 4d 6f  oModule));.  pMo
87e0: 64 2d 3e 69 6e 74 65 72 70 20 3d 20 69 6e 74 65  d->interp = inte
87f0: 72 70 3b 0a 20 20 73 71 6c 69 74 65 33 5f 63 72  rp;.  sqlite3_cr
8800: 65 61 74 65 5f 6d 6f 64 75 6c 65 5f 76 32 28 64  eate_module_v2(d
8810: 62 2c 20 22 65 63 68 6f 22 2c 20 26 65 63 68 6f  b, "echo", &echo
8820: 4d 6f 64 75 6c 65 2c 20 28 76 6f 69 64 2a 29 70  Module, (void*)p
8830: 4d 6f 64 2c 20 6d 6f 64 75 6c 65 44 65 73 74 72  Mod, moduleDestr
8840: 6f 79 29 3b 0a 20 20 72 65 74 75 72 6e 20 54 43  oy);.  return TC
8850: 4c 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54  L_OK;.}../*.** T
8860: 63 6c 20 69 6e 74 65 72 66 61 63 65 20 74 6f 20  cl interface to 
8870: 73 71 6c 69 74 65 33 5f 64 65 63 6c 61 72 65 5f  sqlite3_declare_
8880: 76 74 61 62 2c 20 69 6e 76 6f 6b 65 64 20 61 73  vtab, invoked as
8890: 20 66 6f 6c 6c 6f 77 73 20 66 72 6f 6d 20 54 63   follows from Tc
88a0: 6c 3a 0a 2a 2a 0a 2a 2a 20 73 71 6c 69 74 65 33  l:.**.** sqlite3
88b0: 5f 64 65 63 6c 61 72 65 5f 76 74 61 62 20 44 42  _declare_vtab DB
88c0: 20 53 51 4c 0a 2a 2f 0a 73 74 61 74 69 63 20 69   SQL.*/.static i
88d0: 6e 74 20 64 65 63 6c 61 72 65 5f 76 74 61 62 28  nt declare_vtab(
88e0: 0a 20 20 43 6c 69 65 6e 74 44 61 74 61 20 63 6c  .  ClientData cl
88f0: 69 65 6e 74 44 61 74 61 2c 20 2f 2a 20 50 6f 69  ientData, /* Poi
8900: 6e 74 65 72 20 74 6f 20 73 71 6c 69 74 65 33 5f  nter to sqlite3_
8910: 65 6e 61 62 6c 65 5f 58 58 58 20 66 75 6e 63 74  enable_XXX funct
8920: 69 6f 6e 20 2a 2f 0a 20 20 54 63 6c 5f 49 6e 74  ion */.  Tcl_Int
8930: 65 72 70 20 2a 69 6e 74 65 72 70 2c 20 20 20 20  erp *interp,    
8940: 2f 2a 20 54 68 65 20 54 43 4c 20 69 6e 74 65 72  /* The TCL inter
8950: 70 72 65 74 65 72 20 74 68 61 74 20 69 6e 76 6f  preter that invo
8960: 6b 65 64 20 74 68 69 73 20 63 6f 6d 6d 61 6e 64  ked this command
8970: 20 2a 2f 0a 20 20 69 6e 74 20 6f 62 6a 63 2c 20   */.  int objc, 
8980: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
8990: 4e 75 6d 62 65 72 20 6f 66 20 61 72 67 75 6d 65  Number of argume
89a0: 6e 74 73 20 2a 2f 0a 20 20 54 63 6c 5f 4f 62 6a  nts */.  Tcl_Obj
89b0: 20 2a 43 4f 4e 53 54 20 6f 62 6a 76 5b 5d 20 20   *CONST objv[]  
89c0: 2f 2a 20 43 6f 6d 6d 61 6e 64 20 61 72 67 75 6d  /* Command argum
89d0: 65 6e 74 73 20 2a 2f 0a 29 7b 0a 20 20 73 71 6c  ents */.){.  sql
89e0: 69 74 65 33 20 2a 64 62 3b 0a 20 20 69 6e 74 20  ite3 *db;.  int 
89f0: 72 63 3b 0a 20 20 69 66 28 20 6f 62 6a 63 21 3d  rc;.  if( objc!=
8a00: 33 20 29 7b 0a 20 20 20 20 54 63 6c 5f 57 72 6f  3 ){.    Tcl_Wro
8a10: 6e 67 4e 75 6d 41 72 67 73 28 69 6e 74 65 72 70  ngNumArgs(interp
8a20: 2c 20 31 2c 20 6f 62 6a 76 2c 20 22 44 42 20 53  , 1, objv, "DB S
8a30: 51 4c 22 29 3b 0a 20 20 20 20 72 65 74 75 72 6e  QL");.    return
8a40: 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a   TCL_ERROR;.  }.
8a50: 20 20 69 66 28 20 67 65 74 44 62 50 6f 69 6e 74    if( getDbPoint
8a60: 65 72 28 69 6e 74 65 72 70 2c 20 54 63 6c 5f 47  er(interp, Tcl_G
8a70: 65 74 53 74 72 69 6e 67 28 6f 62 6a 76 5b 31 5d  etString(objv[1]
8a80: 29 2c 20 26 64 62 29 20 29 20 72 65 74 75 72 6e  ), &db) ) return
8a90: 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 72 63   TCL_ERROR;.  rc
8aa0: 20 3d 20 73 71 6c 69 74 65 33 5f 64 65 63 6c 61   = sqlite3_decla
8ab0: 72 65 5f 76 74 61 62 28 64 62 2c 20 54 63 6c 5f  re_vtab(db, Tcl_
8ac0: 47 65 74 53 74 72 69 6e 67 28 6f 62 6a 76 5b 32  GetString(objv[2
8ad0: 5d 29 29 3b 0a 20 20 69 66 28 20 72 63 21 3d 53  ]));.  if( rc!=S
8ae0: 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
8af0: 54 63 6c 5f 53 65 74 52 65 73 75 6c 74 28 69 6e  Tcl_SetResult(in
8b00: 74 65 72 70 2c 20 28 63 68 61 72 20 2a 29 73 71  terp, (char *)sq
8b10: 6c 69 74 65 33 5f 65 72 72 6d 73 67 28 64 62 29  lite3_errmsg(db)
8b20: 2c 20 54 43 4c 5f 56 4f 4c 41 54 49 4c 45 29 3b  , TCL_VOLATILE);
8b30: 0a 20 20 20 20 72 65 74 75 72 6e 20 54 43 4c 5f  .    return TCL_
8b40: 45 52 52 4f 52 3b 0a 20 20 7d 0a 20 20 72 65 74  ERROR;.  }.  ret
8b50: 75 72 6e 20 54 43 4c 5f 4f 4b 3b 0a 7d 0a 0a 23  urn TCL_OK;.}..#
8b60: 65 6e 64 69 66 20 2f 2a 20 69 66 6e 64 65 66 20  endif /* ifndef 
8b70: 53 51 4c 49 54 45 5f 4f 4d 49 54 5f 56 49 52 54  SQLITE_OMIT_VIRT
8b80: 55 41 4c 54 41 42 4c 45 20 2a 2f 0a 0a 2f 2a 0a  UALTABLE */../*.
8b90: 2a 2a 20 52 65 67 69 73 74 65 72 20 63 6f 6d 6d  ** Register comm
8ba0: 61 6e 64 73 20 77 69 74 68 20 74 68 65 20 54 43  ands with the TC
8bb0: 4c 20 69 6e 74 65 72 70 72 65 74 65 72 2e 0a 2a  L interpreter..*
8bc0: 2f 0a 69 6e 74 20 53 71 6c 69 74 65 74 65 73 74  /.int Sqlitetest
8bd0: 38 5f 49 6e 69 74 28 54 63 6c 5f 49 6e 74 65 72  8_Init(Tcl_Inter
8be0: 70 20 2a 69 6e 74 65 72 70 29 7b 0a 20 20 73 74  p *interp){.  st
8bf0: 61 74 69 63 20 73 74 72 75 63 74 20 7b 0a 20 20  atic struct {.  
8c00: 20 20 20 63 68 61 72 20 2a 7a 4e 61 6d 65 3b 0a     char *zName;.
8c10: 20 20 20 20 20 54 63 6c 5f 4f 62 6a 43 6d 64 50       Tcl_ObjCmdP
8c20: 72 6f 63 20 2a 78 50 72 6f 63 3b 0a 20 20 20 20  roc *xProc;.    
8c30: 20 76 6f 69 64 20 2a 63 6c 69 65 6e 74 44 61 74   void *clientDat
8c40: 61 3b 0a 20 20 7d 20 61 4f 62 6a 43 6d 64 5b 5d  a;.  } aObjCmd[]
8c50: 20 3d 20 7b 0a 23 69 66 6e 64 65 66 20 53 51 4c   = {.#ifndef SQL
8c60: 49 54 45 5f 4f 4d 49 54 5f 56 49 52 54 55 41 4c  ITE_OMIT_VIRTUAL
8c70: 54 41 42 4c 45 0a 20 20 20 20 20 7b 20 22 72 65  TABLE.     { "re
8c80: 67 69 73 74 65 72 5f 65 63 68 6f 5f 6d 6f 64 75  gister_echo_modu
8c90: 6c 65 22 2c 20 20 20 72 65 67 69 73 74 65 72 5f  le",   register_
8ca0: 65 63 68 6f 5f 6d 6f 64 75 6c 65 2c 20 30 20 7d  echo_module, 0 }
8cb0: 2c 0a 20 20 20 20 20 7b 20 22 73 71 6c 69 74 65  ,.     { "sqlite
8cc0: 33 5f 64 65 63 6c 61 72 65 5f 76 74 61 62 22 2c  3_declare_vtab",
8cd0: 20 20 20 64 65 63 6c 61 72 65 5f 76 74 61 62 2c     declare_vtab,
8ce0: 20 30 20 7d 2c 0a 23 65 6e 64 69 66 0a 20 20 7d   0 },.#endif.  }
8cf0: 3b 0a 20 20 69 6e 74 20 69 3b 0a 20 20 66 6f 72  ;.  int i;.  for
8d00: 28 69 3d 30 3b 20 69 3c 73 69 7a 65 6f 66 28 61  (i=0; i<sizeof(a
8d10: 4f 62 6a 43 6d 64 29 2f 73 69 7a 65 6f 66 28 61  ObjCmd)/sizeof(a
8d20: 4f 62 6a 43 6d 64 5b 30 5d 29 3b 20 69 2b 2b 29  ObjCmd[0]); i++)
8d30: 7b 0a 20 20 20 20 54 63 6c 5f 43 72 65 61 74 65  {.    Tcl_Create
8d40: 4f 62 6a 43 6f 6d 6d 61 6e 64 28 69 6e 74 65 72  ObjCommand(inter
8d50: 70 2c 20 61 4f 62 6a 43 6d 64 5b 69 5d 2e 7a 4e  p, aObjCmd[i].zN
8d60: 61 6d 65 2c 20 0a 20 20 20 20 20 20 20 20 61 4f  ame, .        aO
8d70: 62 6a 43 6d 64 5b 69 5d 2e 78 50 72 6f 63 2c 20  bjCmd[i].xProc, 
8d80: 61 4f 62 6a 43 6d 64 5b 69 5d 2e 63 6c 69 65 6e  aObjCmd[i].clien
8d90: 74 44 61 74 61 2c 20 30 29 3b 0a 20 20 7d 0a 20  tData, 0);.  }. 
8da0: 20 72 65 74 75 72 6e 20 54 43 4c 5f 4f 4b 3b 0a   return TCL_OK;.
8db0: 7d 0a                                            }.