/ Hex Artifact Content
Login

Artifact 25e127f0e21f59da24fa33cdbc645851cfb933f1:


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 30 20 32  test8.c,v 1.60 2
0230: 30 30 38 2f 30 32 2f 31 33 20 31 38 3a 32 35 3a  008/02/13 18:25:
0240: 32 37 20 64 61 6e 69 65 6c 6b 31 39 37 37 20 45  27 danielk1977 E
0250: 78 70 20 24 0a 2a 2f 0a 23 69 6e 63 6c 75 64 65  xp $.*/.#include
0260: 20 22 73 71 6c 69 74 65 49 6e 74 2e 68 22 0a 23   "sqliteInt.h".#
0270: 69 6e 63 6c 75 64 65 20 22 74 63 6c 2e 68 22 0a  include "tcl.h".
0280: 23 69 6e 63 6c 75 64 65 20 3c 73 74 64 6c 69 62  #include <stdlib
0290: 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 73 74  .h>.#include <st
02a0: 72 69 6e 67 2e 68 3e 0a 0a 23 69 66 6e 64 65 66  ring.h>..#ifndef
02b0: 20 53 51 4c 49 54 45 5f 4f 4d 49 54 5f 56 49 52   SQLITE_OMIT_VIR
02c0: 54 55 41 4c 54 41 42 4c 45 0a 0a 74 79 70 65 64  TUALTABLE..typed
02d0: 65 66 20 73 74 72 75 63 74 20 65 63 68 6f 5f 76  ef struct echo_v
02e0: 74 61 62 20 65 63 68 6f 5f 76 74 61 62 3b 0a 74  tab echo_vtab;.t
02f0: 79 70 65 64 65 66 20 73 74 72 75 63 74 20 65 63  ypedef struct ec
0300: 68 6f 5f 63 75 72 73 6f 72 20 65 63 68 6f 5f 63  ho_cursor echo_c
0310: 75 72 73 6f 72 3b 0a 0a 2f 2a 0a 2a 2a 20 54 68  ursor;../*.** Th
0320: 65 20 74 65 73 74 20 6d 6f 64 75 6c 65 20 64 65  e test module de
0330: 66 69 6e 65 64 20 69 6e 20 74 68 69 73 20 66 69  fined in this fi
0340: 6c 65 20 75 73 65 73 20 66 6f 75 72 20 67 6c 6f  le uses four glo
0350: 62 61 6c 20 54 63 6c 20 76 61 72 69 61 62 6c 65  bal Tcl variable
0360: 73 20 74 6f 0a 2a 2a 20 63 6f 6d 6d 69 63 61 74  s to.** commicat
0370: 65 20 77 69 74 68 20 74 65 73 74 2d 73 63 72 69  e with test-scri
0380: 70 74 73 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20 24  pts:.**.**     $
0390: 3a 3a 65 63 68 6f 5f 6d 6f 64 75 6c 65 0a 2a 2a  ::echo_module.**
03a0: 20 20 20 20 20 24 3a 3a 65 63 68 6f 5f 6d 6f 64       $::echo_mod
03b0: 75 6c 65 5f 73 79 6e 63 5f 66 61 69 6c 0a 2a 2a  ule_sync_fail.**
03c0: 20 20 20 20 20 24 3a 3a 65 63 68 6f 5f 6d 6f 64       $::echo_mod
03d0: 75 6c 65 5f 62 65 67 69 6e 5f 66 61 69 6c 0a 2a  ule_begin_fail.*
03e0: 2a 20 20 20 20 20 24 3a 3a 65 63 68 6f 5f 6d 6f  *     $::echo_mo
03f0: 64 75 6c 65 5f 63 6f 73 74 0a 2a 2a 0a 2a 2a 20  dule_cost.**.** 
0400: 54 68 65 20 76 61 72 69 61 62 6c 65 20 3a 3a 65  The variable ::e
0410: 63 68 6f 5f 6d 6f 64 75 6c 65 20 69 73 20 61 20  cho_module is a 
0420: 6c 69 73 74 2e 20 45 61 63 68 20 74 69 6d 65 20  list. Each time 
0430: 6f 6e 65 20 6f 66 20 74 68 65 20 66 6f 6c 6c 6f  one of the follo
0440: 77 69 6e 67 0a 2a 2a 20 6d 65 74 68 6f 64 73 20  wing.** methods 
0450: 69 73 20 63 61 6c 6c 65 64 2c 20 6f 6e 65 20 6f  is called, one o
0460: 72 20 6d 6f 72 65 20 65 6c 65 6d 65 6e 74 73 20  r more elements 
0470: 61 72 65 20 61 70 70 65 6e 64 65 64 20 74 6f 20  are appended to 
0480: 74 68 65 20 6c 69 73 74 2e 0a 2a 2a 20 54 68 69  the list..** Thi
0490: 73 20 69 73 20 75 73 65 64 20 66 6f 72 20 61 75  s is used for au
04a0: 74 6f 6d 61 74 65 64 20 74 65 73 74 69 6e 67 20  tomated testing 
04b0: 6f 66 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65  of virtual table
04c0: 20 6d 6f 64 75 6c 65 73 2e 0a 2a 2a 0a 2a 2a 20   modules..**.** 
04d0: 54 68 65 20 3a 3a 65 63 68 6f 5f 6d 6f 64 75 6c  The ::echo_modul
04e0: 65 5f 73 79 6e 63 5f 66 61 69 6c 20 76 61 72 69  e_sync_fail vari
04f0: 61 62 6c 65 20 69 73 20 73 65 74 20 62 79 20 74  able is set by t
0500: 65 73 74 20 73 63 72 69 70 74 73 20 61 6e 64 20  est scripts and 
0510: 72 65 61 64 0a 2a 2a 20 62 79 20 63 6f 64 65 20  read.** by code 
0520: 69 6e 20 74 68 69 73 20 66 69 6c 65 2e 20 49 66  in this file. If
0530: 20 69 74 20 69 73 20 73 65 74 20 74 6f 20 74 68   it is set to th
0540: 65 20 6e 61 6d 65 20 6f 66 20 61 20 72 65 61 6c  e name of a real
0550: 20 74 61 62 6c 65 20 69 6e 20 74 68 65 0a 2a 2a   table in the.**
0560: 20 74 68 65 20 64 61 74 61 62 61 73 65 2c 20 74   the database, t
0570: 68 65 6e 20 61 6c 6c 20 78 53 79 6e 63 20 6f 70  hen all xSync op
0580: 65 72 61 74 69 6f 6e 73 20 6f 6e 20 65 63 68 6f  erations on echo
0590: 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65 73 20   virtual tables 
05a0: 74 68 61 74 0a 2a 2a 20 75 73 65 20 74 68 65 20  that.** use the 
05b0: 6e 61 6d 65 64 20 74 61 62 6c 65 20 61 73 20 61  named table as a
05c0: 20 62 61 63 6b 69 6e 67 20 73 74 6f 72 65 20 77   backing store w
05d0: 69 6c 6c 20 66 61 69 6c 2e 0a 2a 2f 0a 0a 2f 2a  ill fail..*/../*
05e0: 20 0a 2a 2a 20 41 6e 20 65 63 68 6f 20 76 69 72   .** An echo vir
05f0: 74 75 61 6c 2d 74 61 62 6c 65 20 6f 62 6a 65 63  tual-table objec
0600: 74 2e 0a 2a 2a 0a 2a 2a 20 65 63 68 6f 2e 76 74  t..**.** echo.vt
0610: 61 62 2e 61 49 6e 64 65 78 20 69 73 20 61 6e 20  ab.aIndex is an 
0620: 61 72 72 61 79 20 6f 66 20 62 6f 6f 6c 65 61 6e  array of boolean
0630: 73 2e 20 54 68 65 20 6e 74 68 20 65 6e 74 72 79  s. The nth entry
0640: 20 69 73 20 74 72 75 65 20 69 66 20 0a 2a 2a 20   is true if .** 
0650: 74 68 65 20 6e 74 68 20 63 6f 6c 75 6d 6e 20 6f  the nth column o
0660: 66 20 74 68 65 20 72 65 61 6c 20 74 61 62 6c 65  f the real table
0670: 20 69 73 20 74 68 65 20 6c 65 66 74 2d 6d 6f 73   is the left-mos
0680: 74 20 63 6f 6c 75 6d 6e 20 6f 66 20 61 6e 20 69  t column of an i
0690: 6e 64 65 78 0a 2a 2a 20 28 69 6d 70 6c 69 63 69  ndex.** (implici
06a0: 74 20 6f 72 20 6f 74 68 65 72 77 69 73 65 29 2e  t or otherwise).
06b0: 20 49 6e 20 6f 74 68 65 72 20 77 6f 72 64 73 2c   In other words,
06c0: 20 69 66 20 53 51 4c 69 74 65 20 63 61 6e 20 6f   if SQLite can o
06d0: 70 74 69 6d 69 7a 65 0a 2a 2a 20 61 20 71 75 65  ptimize.** a que
06e0: 72 79 20 6c 69 6b 65 20 22 53 45 4c 45 43 54 20  ry like "SELECT 
06f0: 2a 20 46 52 4f 4d 20 72 65 61 6c 5f 74 61 62 6c  * FROM real_tabl
0700: 65 20 57 48 45 52 45 20 63 6f 6c 20 3d 20 3f 22  e WHERE col = ?"
0710: 2e 0a 2a 2a 0a 2a 2a 20 4d 65 6d 62 65 72 20 76  ..**.** Member v
0720: 61 72 69 61 62 6c 65 20 61 43 6f 6c 5b 5d 20 63  ariable aCol[] c
0730: 6f 6e 74 61 69 6e 73 20 63 6f 70 69 65 73 20 6f  ontains copies o
0740: 66 20 74 68 65 20 63 6f 6c 75 6d 6e 20 6e 61 6d  f the column nam
0750: 65 73 20 6f 66 20 74 68 65 20 72 65 61 6c 0a 2a  es of the real.*
0760: 2a 20 74 61 62 6c 65 2e 0a 2a 2f 0a 73 74 72 75  * table..*/.stru
0770: 63 74 20 65 63 68 6f 5f 76 74 61 62 20 7b 0a 20  ct echo_vtab {. 
0780: 20 73 71 6c 69 74 65 33 5f 76 74 61 62 20 62 61   sqlite3_vtab ba
0790: 73 65 3b 0a 20 20 54 63 6c 5f 49 6e 74 65 72 70  se;.  Tcl_Interp
07a0: 20 2a 69 6e 74 65 72 70 3b 20 20 20 20 20 2f 2a   *interp;     /*
07b0: 20 54 63 6c 20 69 6e 74 65 72 70 72 65 74 65 72   Tcl interpreter
07c0: 20 63 6f 6e 74 61 69 6e 69 6e 67 20 64 65 62 75   containing debu
07d0: 67 20 76 61 72 69 61 62 6c 65 73 20 2a 2f 0a 20  g variables */. 
07e0: 20 73 71 6c 69 74 65 33 20 2a 64 62 3b 20 20 20   sqlite3 *db;   
07f0: 20 20 20 20 20 20 20 20 20 2f 2a 20 44 61 74 61           /* Data
0800: 62 61 73 65 20 63 6f 6e 6e 65 63 74 69 6f 6e 20  base connection 
0810: 2a 2f 0a 0a 20 20 69 6e 74 20 69 73 50 61 74 74  */..  int isPatt
0820: 65 72 6e 3b 0a 20 20 63 68 61 72 20 2a 7a 54 68  ern;.  char *zTh
0830: 69 73 3b 20 20 20 20 20 20 20 20 20 20 20 20 2f  is;            /
0840: 2a 20 4e 61 6d 65 20 6f 66 20 74 68 65 20 65 63  * Name of the ec
0850: 68 6f 20 74 61 62 6c 65 20 2a 2f 0a 20 20 63 68  ho table */.  ch
0860: 61 72 20 2a 7a 54 61 62 6c 65 4e 61 6d 65 3b 20  ar *zTableName; 
0870: 20 20 20 20 20 20 2f 2a 20 4e 61 6d 65 20 6f 66        /* Name of
0880: 20 74 68 65 20 72 65 61 6c 20 74 61 62 6c 65 20   the real table 
0890: 2a 2f 0a 20 20 63 68 61 72 20 2a 7a 4c 6f 67 4e  */.  char *zLogN
08a0: 61 6d 65 3b 20 20 20 20 20 20 20 20 20 2f 2a 20  ame;         /* 
08b0: 4e 61 6d 65 20 6f 66 20 74 68 65 20 6c 6f 67 20  Name of the log 
08c0: 74 61 62 6c 65 20 2a 2f 0a 20 20 69 6e 74 20 6e  table */.  int n
08d0: 43 6f 6c 3b 20 20 20 20 20 20 20 20 20 20 20 20  Col;            
08e0: 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20     /* Number of 
08f0: 63 6f 6c 75 6d 6e 73 20 69 6e 20 74 68 65 20 72  columns in the r
0900: 65 61 6c 20 74 61 62 6c 65 20 2a 2f 0a 20 20 69  eal table */.  i
0910: 6e 74 20 2a 61 49 6e 64 65 78 3b 20 20 20 20 20  nt *aIndex;     
0920: 20 20 20 20 20 20 20 2f 2a 20 41 72 72 61 79 20         /* Array 
0930: 6f 66 20 73 69 7a 65 20 6e 43 6f 6c 2e 20 54 72  of size nCol. Tr
0940: 75 65 20 69 66 20 63 6f 6c 75 6d 6e 20 68 61 73  ue if column has
0950: 20 61 6e 20 69 6e 64 65 78 20 2a 2f 0a 20 20 63   an index */.  c
0960: 68 61 72 20 2a 2a 61 43 6f 6c 3b 20 20 20 20 20  har **aCol;     
0970: 20 20 20 20 20 20 20 2f 2a 20 41 72 72 61 79 20         /* Array 
0980: 6f 66 20 73 69 7a 65 20 6e 43 6f 6c 2e 20 43 6f  of size nCol. Co
0990: 6c 75 6d 6e 20 6e 61 6d 65 73 20 2a 2f 0a 7d 3b  lumn names */.};
09a0: 0a 0a 2f 2a 20 41 6e 20 65 63 68 6f 20 63 75 72  ../* An echo cur
09b0: 73 6f 72 20 6f 62 6a 65 63 74 20 2a 2f 0a 73 74  sor object */.st
09c0: 72 75 63 74 20 65 63 68 6f 5f 63 75 72 73 6f 72  ruct echo_cursor
09d0: 20 7b 0a 20 20 73 71 6c 69 74 65 33 5f 76 74 61   {.  sqlite3_vta
09e0: 62 5f 63 75 72 73 6f 72 20 62 61 73 65 3b 0a 20  b_cursor base;. 
09f0: 20 73 71 6c 69 74 65 33 5f 73 74 6d 74 20 2a 70   sqlite3_stmt *p
0a00: 53 74 6d 74 3b 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20  Stmt;.};../*.** 
0a10: 43 6f 6e 76 65 72 74 20 61 6e 20 53 51 4c 2d 73  Convert an SQL-s
0a20: 74 79 6c 65 20 71 75 6f 74 65 64 20 73 74 72 69  tyle quoted stri
0a30: 6e 67 20 69 6e 74 6f 20 61 20 6e 6f 72 6d 61 6c  ng into a normal
0a40: 20 73 74 72 69 6e 67 20 62 79 20 72 65 6d 6f 76   string by remov
0a50: 69 6e 67 0a 2a 2a 20 74 68 65 20 71 75 6f 74 65  ing.** the quote
0a60: 20 63 68 61 72 61 63 74 65 72 73 2e 20 20 54 68   characters.  Th
0a70: 65 20 63 6f 6e 76 65 72 73 69 6f 6e 20 69 73 20  e conversion is 
0a80: 64 6f 6e 65 20 69 6e 2d 70 6c 61 63 65 2e 20 20  done in-place.  
0a90: 49 66 20 74 68 65 0a 2a 2a 20 69 6e 70 75 74 20  If the.** input 
0aa0: 64 6f 65 73 20 6e 6f 74 20 62 65 67 69 6e 20 77  does not begin w
0ab0: 69 74 68 20 61 20 71 75 6f 74 65 20 63 68 61 72  ith a quote char
0ac0: 61 63 74 65 72 2c 20 74 68 65 6e 20 74 68 69 73  acter, then this
0ad0: 20 72 6f 75 74 69 6e 65 0a 2a 2a 20 69 73 20 61   routine.** is a
0ae0: 20 6e 6f 2d 6f 70 2e 0a 2a 2a 0a 2a 2a 20 45 78   no-op..**.** Ex
0af0: 61 6d 70 6c 65 73 3a 0a 2a 2a 0a 2a 2a 20 20 20  amples:.**.**   
0b00: 20 20 22 61 62 63 22 20 20 20 62 65 63 6f 6d 65    "abc"   become
0b10: 73 20 20 20 61 62 63 0a 2a 2a 20 20 20 20 20 27  s   abc.**     '
0b20: 78 79 7a 27 20 20 20 62 65 63 6f 6d 65 73 20 20  xyz'   becomes  
0b30: 20 78 79 7a 0a 2a 2a 20 20 20 20 20 5b 70 71 72   xyz.**     [pqr
0b40: 5d 20 20 20 62 65 63 6f 6d 65 73 20 20 20 70 71  ]   becomes   pq
0b50: 72 0a 2a 2a 20 20 20 20 20 60 6d 6e 6f 60 20 20  r.**     `mno`  
0b60: 20 62 65 63 6f 6d 65 73 20 20 20 6d 6e 6f 0a 2a   becomes   mno.*
0b70: 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 64 65  /.static void de
0b80: 71 75 6f 74 65 53 74 72 69 6e 67 28 63 68 61 72  quoteString(char
0b90: 20 2a 7a 29 7b 0a 20 20 69 6e 74 20 71 75 6f 74   *z){.  int quot
0ba0: 65 3b 0a 20 20 69 6e 74 20 69 2c 20 6a 3b 0a 20  e;.  int i, j;. 
0bb0: 20 69 66 28 20 7a 3d 3d 30 20 29 20 72 65 74 75   if( z==0 ) retu
0bc0: 72 6e 3b 0a 20 20 71 75 6f 74 65 20 3d 20 7a 5b  rn;.  quote = z[
0bd0: 30 5d 3b 0a 20 20 73 77 69 74 63 68 28 20 71 75  0];.  switch( qu
0be0: 6f 74 65 20 29 7b 0a 20 20 20 20 63 61 73 65 20  ote ){.    case 
0bf0: 27 5c 27 27 3a 20 20 62 72 65 61 6b 3b 0a 20 20  '\'':  break;.  
0c00: 20 20 63 61 73 65 20 27 22 27 3a 20 20 20 62 72    case '"':   br
0c10: 65 61 6b 3b 0a 20 20 20 20 63 61 73 65 20 27 60  eak;.    case '`
0c20: 27 3a 20 20 20 62 72 65 61 6b 3b 20 20 20 20 20  ':   break;     
0c30: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46 6f             /* Fo
0c40: 72 20 4d 79 53 51 4c 20 63 6f 6d 70 61 74 69 62  r MySQL compatib
0c50: 69 6c 69 74 79 20 2a 2f 0a 20 20 20 20 63 61 73  ility */.    cas
0c60: 65 20 27 5b 27 3a 20 20 20 71 75 6f 74 65 20 3d  e '[':   quote =
0c70: 20 27 5d 27 3b 20 20 62 72 65 61 6b 3b 20 20 2f   ']';  break;  /
0c80: 2a 20 46 6f 72 20 4d 53 20 53 71 6c 53 65 72 76  * For MS SqlServ
0c90: 65 72 20 63 6f 6d 70 61 74 69 62 69 6c 69 74 79  er compatibility
0ca0: 20 2a 2f 0a 20 20 20 20 64 65 66 61 75 6c 74 3a   */.    default:
0cb0: 20 20 20 20 72 65 74 75 72 6e 3b 0a 20 20 7d 0a      return;.  }.
0cc0: 20 20 66 6f 72 28 69 3d 31 2c 20 6a 3d 30 3b 20    for(i=1, j=0; 
0cd0: 7a 5b 69 5d 3b 20 69 2b 2b 29 7b 0a 20 20 20 20  z[i]; i++){.    
0ce0: 69 66 28 20 7a 5b 69 5d 3d 3d 71 75 6f 74 65 20  if( z[i]==quote 
0cf0: 29 7b 0a 20 20 20 20 20 20 69 66 28 20 7a 5b 69  ){.      if( z[i
0d00: 2b 31 5d 3d 3d 71 75 6f 74 65 20 29 7b 0a 20 20  +1]==quote ){.  
0d10: 20 20 20 20 20 20 7a 5b 6a 2b 2b 5d 20 3d 20 71        z[j++] = q
0d20: 75 6f 74 65 3b 0a 20 20 20 20 20 20 20 20 69 2b  uote;.        i+
0d30: 2b 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a  +;.      }else{.
0d40: 20 20 20 20 20 20 20 20 7a 5b 6a 2b 2b 5d 20 3d          z[j++] =
0d50: 20 30 3b 0a 20 20 20 20 20 20 20 20 62 72 65 61   0;.        brea
0d60: 6b 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d  k;.      }.    }
0d70: 65 6c 73 65 7b 0a 20 20 20 20 20 20 7a 5b 6a 2b  else{.      z[j+
0d80: 2b 5d 20 3d 20 7a 5b 69 5d 3b 0a 20 20 20 20 7d  +] = z[i];.    }
0d90: 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65  .  }.}../*.** Re
0da0: 74 72 69 65 76 65 20 74 68 65 20 63 6f 6c 75 6d  trieve the colum
0db0: 6e 20 6e 61 6d 65 73 20 66 6f 72 20 74 68 65 20  n names for the 
0dc0: 74 61 62 6c 65 20 6e 61 6d 65 64 20 7a 54 61 62  table named zTab
0dd0: 20 76 69 61 20 64 61 74 61 62 61 73 65 0a 2a 2a   via database.**
0de0: 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 64 62 2e 20   connection db. 
0df0: 53 51 4c 49 54 45 5f 4f 4b 20 69 73 20 72 65 74  SQLITE_OK is ret
0e00: 75 72 6e 65 64 20 6f 6e 20 73 75 63 63 65 73 73  urned on success
0e10: 2c 20 6f 72 20 61 6e 20 73 71 6c 69 74 65 20 65  , or an sqlite e
0e20: 72 72 6f 72 0a 2a 2a 20 63 6f 64 65 20 6f 74 68  rror.** code oth
0e30: 65 72 77 69 73 65 2e 0a 2a 2a 0a 2a 2a 20 49 66  erwise..**.** If
0e40: 20 73 75 63 63 65 73 73 66 75 6c 2c 20 74 68 65   successful, the
0e50: 20 6e 75 6d 62 65 72 20 6f 66 20 63 6f 6c 75 6d   number of colum
0e60: 6e 73 20 69 73 20 77 72 69 74 74 65 6e 20 74 6f  ns is written to
0e70: 20 2a 70 6e 43 6f 6c 2e 20 2a 70 61 43 6f 6c 20   *pnCol. *paCol 
0e80: 69 73 0a 2a 2a 20 73 65 74 20 74 6f 20 70 6f 69  is.** set to poi
0e90: 6e 74 20 61 74 20 73 71 6c 69 74 65 33 5f 6d 61  nt at sqlite3_ma
0ea0: 6c 6c 6f 63 28 29 27 64 20 73 70 61 63 65 20 63  lloc()'d space c
0eb0: 6f 6e 74 61 69 6e 69 6e 67 20 74 68 65 20 61 72  ontaining the ar
0ec0: 72 61 79 20 6f 66 0a 2a 2a 20 6e 43 6f 6c 20 63  ray of.** nCol c
0ed0: 6f 6c 75 6d 6e 20 6e 61 6d 65 73 2e 20 54 68 65  olumn names. The
0ee0: 20 63 61 6c 6c 65 72 20 69 73 20 72 65 73 70 6f   caller is respo
0ef0: 6e 73 69 62 6c 65 20 66 6f 72 20 63 61 6c 6c 69  nsible for calli
0f00: 6e 67 20 73 71 6c 69 74 65 33 5f 66 72 65 65 0a  ng sqlite3_free.
0f10: 2a 2a 20 6f 6e 20 2a 70 61 43 6f 6c 2e 0a 2a 2f  ** on *paCol..*/
0f20: 0a 73 74 61 74 69 63 20 69 6e 74 20 67 65 74 43  .static int getC
0f30: 6f 6c 75 6d 6e 4e 61 6d 65 73 28 0a 20 20 73 71  olumnNames(.  sq
0f40: 6c 69 74 65 33 20 2a 64 62 2c 20 0a 20 20 63 6f  lite3 *db, .  co
0f50: 6e 73 74 20 63 68 61 72 20 2a 7a 54 61 62 2c 0a  nst char *zTab,.
0f60: 20 20 63 68 61 72 20 2a 2a 2a 70 61 43 6f 6c 2c    char ***paCol,
0f70: 20 0a 20 20 69 6e 74 20 2a 70 6e 43 6f 6c 0a 29   .  int *pnCol.)
0f80: 7b 0a 20 20 63 68 61 72 20 2a 2a 61 43 6f 6c 20  {.  char **aCol 
0f90: 3d 20 30 3b 0a 20 20 63 68 61 72 20 2a 7a 53 71  = 0;.  char *zSq
0fa0: 6c 3b 0a 20 20 73 71 6c 69 74 65 33 5f 73 74 6d  l;.  sqlite3_stm
0fb0: 74 20 2a 70 53 74 6d 74 20 3d 20 30 3b 0a 20 20  t *pStmt = 0;.  
0fc0: 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f  int rc = SQLITE_
0fd0: 4f 4b 3b 0a 20 20 69 6e 74 20 6e 43 6f 6c 20 3d  OK;.  int nCol =
0fe0: 20 30 3b 0a 0a 20 20 2f 2a 20 50 72 65 70 61 72   0;..  /* Prepar
0ff0: 65 20 74 68 65 20 73 74 61 74 65 6d 65 6e 74 20  e the statement 
1000: 22 53 45 4c 45 43 54 20 2a 20 46 52 4f 4d 20 3c  "SELECT * FROM <
1010: 74 62 6c 3e 22 2e 20 54 68 65 20 63 6f 6c 75 6d  tbl>". The colum
1020: 6e 20 6e 61 6d 65 73 0a 20 20 2a 2a 20 6f 66 20  n names.  ** of 
1030: 74 68 65 20 72 65 73 75 6c 74 20 73 65 74 20 6f  the result set o
1040: 66 20 74 68 65 20 63 6f 6d 70 69 6c 65 64 20 53  f the compiled S
1050: 45 4c 45 43 54 20 77 69 6c 6c 20 62 65 20 74 68  ELECT will be th
1060: 65 20 73 61 6d 65 20 61 73 0a 20 20 2a 2a 20 74  e same as.  ** t
1070: 68 65 20 63 6f 6c 75 6d 6e 20 6e 61 6d 65 73 20  he column names 
1080: 6f 66 20 74 61 62 6c 65 20 3c 74 62 6c 3e 2e 0a  of table <tbl>..
1090: 20 20 2a 2f 0a 20 20 7a 53 71 6c 20 3d 20 73 71    */.  zSql = sq
10a0: 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 22 53  lite3_mprintf("S
10b0: 45 4c 45 43 54 20 2a 20 46 52 4f 4d 20 25 51 22  ELECT * FROM %Q"
10c0: 2c 20 7a 54 61 62 29 3b 0a 20 20 69 66 28 20 21  , zTab);.  if( !
10d0: 7a 53 71 6c 20 29 7b 0a 20 20 20 20 72 63 20 3d  zSql ){.    rc =
10e0: 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20   SQLITE_NOMEM;. 
10f0: 20 20 20 67 6f 74 6f 20 6f 75 74 3b 0a 20 20 7d     goto out;.  }
1100: 0a 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f  .  rc = sqlite3_
1110: 70 72 65 70 61 72 65 28 64 62 2c 20 7a 53 71 6c  prepare(db, zSql
1120: 2c 20 2d 31 2c 20 26 70 53 74 6d 74 2c 20 30 29  , -1, &pStmt, 0)
1130: 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65  ;.  sqlite3_free
1140: 28 7a 53 71 6c 29 3b 0a 0a 20 20 69 66 28 20 72  (zSql);..  if( r
1150: 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a  c==SQLITE_OK ){.
1160: 20 20 20 20 69 6e 74 20 69 69 3b 0a 20 20 20 20      int ii;.    
1170: 69 6e 74 20 6e 42 79 74 65 73 3b 0a 20 20 20 20  int nBytes;.    
1180: 63 68 61 72 20 2a 7a 53 70 61 63 65 3b 0a 20 20  char *zSpace;.  
1190: 20 20 6e 43 6f 6c 20 3d 20 73 71 6c 69 74 65 33    nCol = sqlite3
11a0: 5f 63 6f 6c 75 6d 6e 5f 63 6f 75 6e 74 28 70 53  _column_count(pS
11b0: 74 6d 74 29 3b 0a 0a 20 20 20 20 2f 2a 20 46 69  tmt);..    /* Fi
11c0: 67 75 72 65 20 6f 75 74 20 68 6f 77 20 6d 75 63  gure out how muc
11d0: 68 20 73 70 61 63 65 20 74 6f 20 61 6c 6c 6f 63  h space to alloc
11e0: 61 74 65 20 66 6f 72 20 74 68 65 20 61 72 72 61  ate for the arra
11f0: 79 20 6f 66 20 63 6f 6c 75 6d 6e 20 6e 61 6d 65  y of column name
1200: 73 20 0a 20 20 20 20 2a 2a 20 28 69 6e 63 6c 75  s .    ** (inclu
1210: 64 69 6e 67 20 73 70 61 63 65 20 66 6f 72 20 74  ding space for t
1220: 68 65 20 73 74 72 69 6e 67 73 20 74 68 65 6d 73  he strings thems
1230: 65 6c 76 65 73 29 2e 20 54 68 65 6e 20 61 6c 6c  elves). Then all
1240: 6f 63 61 74 65 20 69 74 2e 0a 20 20 20 20 2a 2f  ocate it..    */
1250: 0a 20 20 20 20 6e 42 79 74 65 73 20 3d 20 73 69  .    nBytes = si
1260: 7a 65 6f 66 28 63 68 61 72 20 2a 29 20 2a 20 6e  zeof(char *) * n
1270: 43 6f 6c 3b 0a 20 20 20 20 66 6f 72 28 69 69 3d  Col;.    for(ii=
1280: 30 3b 20 69 69 3c 6e 43 6f 6c 3b 20 69 69 2b 2b  0; ii<nCol; ii++
1290: 29 7b 0a 20 20 20 20 20 20 63 6f 6e 73 74 20 63  ){.      const c
12a0: 68 61 72 20 2a 7a 4e 61 6d 65 20 3d 20 73 71 6c  har *zName = sql
12b0: 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 6e 61 6d 65  ite3_column_name
12c0: 28 70 53 74 6d 74 2c 20 69 69 29 3b 0a 20 20 20  (pStmt, ii);.   
12d0: 20 20 20 69 66 28 20 21 7a 4e 61 6d 65 20 29 7b     if( !zName ){
12e0: 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20 53 51  .        rc = SQ
12f0: 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20  LITE_NOMEM;.    
1300: 20 20 20 20 67 6f 74 6f 20 6f 75 74 3b 0a 20 20      goto out;.  
1310: 20 20 20 20 7d 0a 20 20 20 20 20 20 6e 42 79 74      }.      nByt
1320: 65 73 20 2b 3d 20 73 74 72 6c 65 6e 28 7a 4e 61  es += strlen(zNa
1330: 6d 65 29 2b 31 3b 0a 20 20 20 20 7d 0a 20 20 20  me)+1;.    }.   
1340: 20 61 43 6f 6c 20 3d 20 28 63 68 61 72 20 2a 2a   aCol = (char **
1350: 29 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63 5a 65  )sqlite3MallocZe
1360: 72 6f 28 6e 42 79 74 65 73 29 3b 0a 20 20 20 20  ro(nBytes);.    
1370: 69 66 28 20 21 61 43 6f 6c 20 29 7b 0a 20 20 20  if( !aCol ){.   
1380: 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4e     rc = SQLITE_N
1390: 4f 4d 45 4d 3b 0a 20 20 20 20 20 20 67 6f 74 6f  OMEM;.      goto
13a0: 20 6f 75 74 3b 0a 20 20 20 20 7d 0a 0a 20 20 20   out;.    }..   
13b0: 20 2f 2a 20 43 6f 70 79 20 74 68 65 20 63 6f 6c   /* Copy the col
13c0: 75 6d 6e 20 6e 61 6d 65 73 20 69 6e 74 6f 20 74  umn names into t
13d0: 68 65 20 61 6c 6c 6f 63 61 74 65 64 20 73 70 61  he allocated spa
13e0: 63 65 20 61 6e 64 20 73 65 74 20 75 70 20 74 68  ce and set up th
13f0: 65 0a 20 20 20 20 2a 2a 20 70 6f 69 6e 74 65 72  e.    ** pointer
1400: 73 20 69 6e 20 74 68 65 20 61 43 6f 6c 5b 5d 20  s in the aCol[] 
1410: 61 72 72 61 79 2e 0a 20 20 20 20 2a 2f 0a 20 20  array..    */.  
1420: 20 20 7a 53 70 61 63 65 20 3d 20 28 63 68 61 72    zSpace = (char
1430: 20 2a 29 28 26 61 43 6f 6c 5b 6e 43 6f 6c 5d 29   *)(&aCol[nCol])
1440: 3b 0a 20 20 20 20 66 6f 72 28 69 69 3d 30 3b 20  ;.    for(ii=0; 
1450: 69 69 3c 6e 43 6f 6c 3b 20 69 69 2b 2b 29 7b 0a  ii<nCol; ii++){.
1460: 20 20 20 20 20 20 61 43 6f 6c 5b 69 69 5d 20 3d        aCol[ii] =
1470: 20 7a 53 70 61 63 65 3b 0a 20 20 20 20 20 20 7a   zSpace;.      z
1480: 53 70 61 63 65 20 2b 3d 20 73 70 72 69 6e 74 66  Space += sprintf
1490: 28 7a 53 70 61 63 65 2c 20 22 25 73 22 2c 20 73  (zSpace, "%s", s
14a0: 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 6e 61  qlite3_column_na
14b0: 6d 65 28 70 53 74 6d 74 2c 20 69 69 29 29 3b 0a  me(pStmt, ii));.
14c0: 20 20 20 20 20 20 7a 53 70 61 63 65 2b 2b 3b 0a        zSpace++;.
14d0: 20 20 20 20 7d 0a 20 20 20 20 61 73 73 65 72 74      }.    assert
14e0: 28 20 28 7a 53 70 61 63 65 2d 6e 42 79 74 65 73  ( (zSpace-nBytes
14f0: 29 3d 3d 28 63 68 61 72 20 2a 29 61 43 6f 6c 20  )==(char *)aCol 
1500: 29 3b 0a 20 20 7d 0a 0a 20 20 2a 70 61 43 6f 6c  );.  }..  *paCol
1510: 20 3d 20 61 43 6f 6c 3b 0a 20 20 2a 70 6e 43 6f   = aCol;.  *pnCo
1520: 6c 20 3d 20 6e 43 6f 6c 3b 0a 0a 6f 75 74 3a 0a  l = nCol;..out:.
1530: 20 20 73 71 6c 69 74 65 33 5f 66 69 6e 61 6c 69    sqlite3_finali
1540: 7a 65 28 70 53 74 6d 74 29 3b 0a 20 20 72 65 74  ze(pStmt);.  ret
1550: 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  urn rc;.}../*.**
1560: 20 50 61 72 61 6d 65 74 65 72 20 7a 54 61 62 20   Parameter zTab 
1570: 69 73 20 74 68 65 20 6e 61 6d 65 20 6f 66 20 61  is the name of a
1580: 20 74 61 62 6c 65 20 69 6e 20 64 61 74 61 62 61   table in databa
1590: 73 65 20 64 62 20 77 69 74 68 20 6e 43 6f 6c 20  se db with nCol 
15a0: 0a 2a 2a 20 63 6f 6c 75 6d 6e 73 2e 20 54 68 69  .** columns. Thi
15b0: 73 20 66 75 6e 63 74 69 6f 6e 20 61 6c 6c 6f 63  s function alloc
15c0: 61 74 65 73 20 61 6e 20 61 72 72 61 79 20 6f 66  ates an array of
15d0: 20 69 6e 74 65 67 65 72 73 20 6e 43 6f 6c 20 69   integers nCol i
15e0: 6e 20 0a 2a 2a 20 73 69 7a 65 20 61 6e 64 20 70  n .** size and p
15f0: 6f 70 75 6c 61 74 65 73 20 69 74 20 61 63 63 6f  opulates it acco
1600: 72 64 69 6e 67 20 74 6f 20 61 6e 79 20 69 6d 70  rding to any imp
1610: 6c 69 63 69 74 20 6f 72 20 65 78 70 6c 69 63 69  licit or explici
1620: 74 20 0a 2a 2a 20 69 6e 64 69 63 65 73 20 6f 6e  t .** indices on
1630: 20 74 61 62 6c 65 20 7a 54 61 62 2e 0a 2a 2a 0a   table zTab..**.
1640: 2a 2a 20 49 66 20 73 75 63 63 65 73 73 66 75 6c  ** If successful
1650: 2c 20 53 51 4c 49 54 45 5f 4f 4b 20 69 73 20 72  , SQLITE_OK is r
1660: 65 74 75 72 6e 65 64 20 61 6e 64 20 2a 70 61 49  eturned and *paI
1670: 6e 64 65 78 20 73 65 74 20 74 6f 20 70 6f 69 6e  ndex set to poin
1680: 74 20 0a 2a 2a 20 61 74 20 74 68 65 20 61 6c 6c  t .** at the all
1690: 6f 63 61 74 65 64 20 61 72 72 61 79 2e 20 4f 74  ocated array. Ot
16a0: 68 65 72 77 69 73 65 2c 20 61 6e 20 65 72 72 6f  herwise, an erro
16b0: 72 20 63 6f 64 65 20 69 73 20 72 65 74 75 72 6e  r code is return
16c0: 65 64 2e 0a 2a 2a 0a 2a 2a 20 53 65 65 20 63 6f  ed..**.** See co
16d0: 6d 6d 65 6e 74 73 20 61 73 73 6f 63 69 61 74 65  mments associate
16e0: 64 20 77 69 74 68 20 74 68 65 20 6d 65 6d 62 65  d with the membe
16f0: 72 20 76 61 72 69 61 62 6c 65 20 61 49 6e 64 65  r variable aInde
1700: 78 20 61 62 6f 76 65 20 0a 2a 2a 20 22 73 74 72  x above .** "str
1710: 75 63 74 20 65 63 68 6f 5f 76 74 61 62 22 20 66  uct echo_vtab" f
1720: 6f 72 20 64 65 74 61 69 6c 73 20 6f 66 20 74 68  or details of th
1730: 65 20 63 6f 6e 74 65 6e 74 73 20 6f 66 20 74 68  e contents of th
1740: 65 20 61 72 72 61 79 2e 0a 2a 2f 0a 73 74 61 74  e array..*/.stat
1750: 69 63 20 69 6e 74 20 67 65 74 49 6e 64 65 78 41  ic int getIndexA
1760: 72 72 61 79 28 0a 20 20 73 71 6c 69 74 65 33 20  rray(.  sqlite3 
1770: 2a 64 62 2c 20 20 20 20 20 20 20 20 20 20 20 20  *db,            
1780: 20 2f 2a 20 44 61 74 61 62 61 73 65 20 63 6f 6e   /* Database con
1790: 6e 65 63 74 69 6f 6e 20 2a 2f 0a 20 20 63 6f 6e  nection */.  con
17a0: 73 74 20 63 68 61 72 20 2a 7a 54 61 62 2c 20 20  st char *zTab,  
17b0: 20 20 20 20 20 20 2f 2a 20 4e 61 6d 65 20 6f 66        /* Name of
17c0: 20 74 61 62 6c 65 20 69 6e 20 64 61 74 61 62 61   table in databa
17d0: 73 65 20 64 62 20 2a 2f 0a 20 20 69 6e 74 20 6e  se db */.  int n
17e0: 43 6f 6c 2c 0a 20 20 69 6e 74 20 2a 2a 70 61 49  Col,.  int **paI
17f0: 6e 64 65 78 0a 29 7b 0a 20 20 73 71 6c 69 74 65  ndex.){.  sqlite
1800: 33 5f 73 74 6d 74 20 2a 70 53 74 6d 74 20 3d 20  3_stmt *pStmt = 
1810: 30 3b 0a 20 20 69 6e 74 20 2a 61 49 6e 64 65 78  0;.  int *aIndex
1820: 20 3d 20 30 3b 0a 20 20 69 6e 74 20 72 63 3b 0a   = 0;.  int rc;.
1830: 20 20 63 68 61 72 20 2a 7a 53 71 6c 3b 0a 0a 20    char *zSql;.. 
1840: 20 2f 2a 20 41 6c 6c 6f 63 61 74 65 20 73 70 61   /* Allocate spa
1850: 63 65 20 66 6f 72 20 74 68 65 20 69 6e 64 65 78  ce for the index
1860: 20 61 72 72 61 79 20 2a 2f 0a 20 20 61 49 6e 64   array */.  aInd
1870: 65 78 20 3d 20 28 69 6e 74 20 2a 29 73 71 6c 69  ex = (int *)sqli
1880: 74 65 33 4d 61 6c 6c 6f 63 5a 65 72 6f 28 73 69  te3MallocZero(si
1890: 7a 65 6f 66 28 69 6e 74 29 20 2a 20 6e 43 6f 6c  zeof(int) * nCol
18a0: 29 3b 0a 20 20 69 66 28 20 21 61 49 6e 64 65 78  );.  if( !aIndex
18b0: 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 53 51 4c   ){.    rc = SQL
18c0: 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 67  ITE_NOMEM;.    g
18d0: 6f 74 6f 20 67 65 74 5f 69 6e 64 65 78 5f 61 72  oto get_index_ar
18e0: 72 61 79 5f 6f 75 74 3b 0a 20 20 7d 0a 0a 20 20  ray_out;.  }..  
18f0: 2f 2a 20 43 6f 6d 70 69 6c 65 20 61 6e 20 73 71  /* Compile an sq
1900: 6c 69 74 65 20 70 72 61 67 6d 61 20 74 6f 20 6c  lite pragma to l
1910: 6f 6f 70 20 74 68 72 6f 75 67 68 20 61 6c 6c 20  oop through all 
1920: 69 6e 64 69 63 65 73 20 6f 6e 20 74 61 62 6c 65  indices on table
1930: 20 7a 54 61 62 20 2a 2f 0a 20 20 7a 53 71 6c 20   zTab */.  zSql 
1940: 3d 20 73 71 6c 69 74 65 33 4d 50 72 69 6e 74 66  = sqlite3MPrintf
1950: 28 30 2c 20 22 50 52 41 47 4d 41 20 69 6e 64 65  (0, "PRAGMA inde
1960: 78 5f 6c 69 73 74 28 25 73 29 22 2c 20 7a 54 61  x_list(%s)", zTa
1970: 62 29 3b 0a 20 20 69 66 28 20 21 7a 53 71 6c 20  b);.  if( !zSql 
1980: 29 7b 0a 20 20 20 20 72 63 20 3d 20 53 51 4c 49  ){.    rc = SQLI
1990: 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 67 6f  TE_NOMEM;.    go
19a0: 74 6f 20 67 65 74 5f 69 6e 64 65 78 5f 61 72 72  to get_index_arr
19b0: 61 79 5f 6f 75 74 3b 0a 20 20 7d 0a 20 20 72 63  ay_out;.  }.  rc
19c0: 20 3d 20 73 71 6c 69 74 65 33 5f 70 72 65 70 61   = sqlite3_prepa
19d0: 72 65 28 64 62 2c 20 7a 53 71 6c 2c 20 2d 31 2c  re(db, zSql, -1,
19e0: 20 26 70 53 74 6d 74 2c 20 30 29 3b 0a 20 20 73   &pStmt, 0);.  s
19f0: 71 6c 69 74 65 33 5f 66 72 65 65 28 7a 53 71 6c  qlite3_free(zSql
1a00: 29 3b 0a 0a 20 20 2f 2a 20 46 6f 72 20 65 61 63  );..  /* For eac
1a10: 68 20 69 6e 64 65 78 2c 20 66 69 67 75 72 65 20  h index, figure 
1a20: 6f 75 74 20 74 68 65 20 6c 65 66 74 2d 6d 6f 73  out the left-mos
1a30: 74 20 63 6f 6c 75 6d 6e 20 61 6e 64 20 73 65 74  t column and set
1a40: 20 74 68 65 20 0a 20 20 2a 2a 20 63 6f 72 72 65   the .  ** corre
1a50: 73 70 6f 6e 64 69 6e 67 20 65 6e 74 72 79 20 69  sponding entry i
1a60: 6e 20 61 49 6e 64 65 78 5b 5d 20 74 6f 20 31 2e  n aIndex[] to 1.
1a70: 0a 20 20 2a 2f 0a 20 20 77 68 69 6c 65 28 20 70  .  */.  while( p
1a80: 53 74 6d 74 20 26 26 20 73 71 6c 69 74 65 33 5f  Stmt && sqlite3_
1a90: 73 74 65 70 28 70 53 74 6d 74 29 3d 3d 53 51 4c  step(pStmt)==SQL
1aa0: 49 54 45 5f 52 4f 57 20 29 7b 0a 20 20 20 20 63  ITE_ROW ){.    c
1ab0: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 49 64 78 20  onst char *zIdx 
1ac0: 3d 20 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 29  = (const char *)
1ad0: 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 74  sqlite3_column_t
1ae0: 65 78 74 28 70 53 74 6d 74 2c 20 31 29 3b 0a 20  ext(pStmt, 1);. 
1af0: 20 20 20 73 71 6c 69 74 65 33 5f 73 74 6d 74 20     sqlite3_stmt 
1b00: 2a 70 53 74 6d 74 32 20 3d 20 30 3b 0a 20 20 20  *pStmt2 = 0;.   
1b10: 20 7a 53 71 6c 20 3d 20 73 71 6c 69 74 65 33 4d   zSql = sqlite3M
1b20: 50 72 69 6e 74 66 28 30 2c 20 22 50 52 41 47 4d  Printf(0, "PRAGM
1b30: 41 20 69 6e 64 65 78 5f 69 6e 66 6f 28 25 73 29  A index_info(%s)
1b40: 22 2c 20 7a 49 64 78 29 3b 0a 20 20 20 20 69 66  ", zIdx);.    if
1b50: 28 20 21 7a 53 71 6c 20 29 7b 0a 20 20 20 20 20  ( !zSql ){.     
1b60: 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d   rc = SQLITE_NOM
1b70: 45 4d 3b 0a 20 20 20 20 20 20 67 6f 74 6f 20 67  EM;.      goto g
1b80: 65 74 5f 69 6e 64 65 78 5f 61 72 72 61 79 5f 6f  et_index_array_o
1b90: 75 74 3b 0a 20 20 20 20 7d 0a 20 20 20 20 72 63  ut;.    }.    rc
1ba0: 20 3d 20 73 71 6c 69 74 65 33 5f 70 72 65 70 61   = sqlite3_prepa
1bb0: 72 65 28 64 62 2c 20 7a 53 71 6c 2c 20 2d 31 2c  re(db, zSql, -1,
1bc0: 20 26 70 53 74 6d 74 32 2c 20 30 29 3b 0a 20 20   &pStmt2, 0);.  
1bd0: 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 7a    sqlite3_free(z
1be0: 53 71 6c 29 3b 0a 20 20 20 20 69 66 28 20 70 53  Sql);.    if( pS
1bf0: 74 6d 74 32 20 26 26 20 73 71 6c 69 74 65 33 5f  tmt2 && sqlite3_
1c00: 73 74 65 70 28 70 53 74 6d 74 32 29 3d 3d 53 51  step(pStmt2)==SQ
1c10: 4c 49 54 45 5f 52 4f 57 20 29 7b 0a 20 20 20 20  LITE_ROW ){.    
1c20: 20 20 69 6e 74 20 63 69 64 20 3d 20 73 71 6c 69    int cid = sqli
1c30: 74 65 33 5f 63 6f 6c 75 6d 6e 5f 69 6e 74 28 70  te3_column_int(p
1c40: 53 74 6d 74 32 2c 20 31 29 3b 0a 20 20 20 20 20  Stmt2, 1);.     
1c50: 20 61 73 73 65 72 74 28 20 63 69 64 3e 3d 30 20   assert( cid>=0 
1c60: 26 26 20 63 69 64 3c 6e 43 6f 6c 20 29 3b 0a 20  && cid<nCol );. 
1c70: 20 20 20 20 20 61 49 6e 64 65 78 5b 63 69 64 5d       aIndex[cid]
1c80: 20 3d 20 31 3b 0a 20 20 20 20 7d 0a 20 20 20 20   = 1;.    }.    
1c90: 69 66 28 20 70 53 74 6d 74 32 20 29 7b 0a 20 20  if( pStmt2 ){.  
1ca0: 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33      rc = sqlite3
1cb0: 5f 66 69 6e 61 6c 69 7a 65 28 70 53 74 6d 74 32  _finalize(pStmt2
1cc0: 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 28  );.    }.    if(
1cd0: 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc!=SQLITE_OK )
1ce0: 7b 0a 20 20 20 20 20 20 67 6f 74 6f 20 67 65 74  {.      goto get
1cf0: 5f 69 6e 64 65 78 5f 61 72 72 61 79 5f 6f 75 74  _index_array_out
1d00: 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 0a 67 65  ;.    }.  }...ge
1d10: 74 5f 69 6e 64 65 78 5f 61 72 72 61 79 5f 6f 75  t_index_array_ou
1d20: 74 3a 0a 20 20 69 66 28 20 70 53 74 6d 74 20 29  t:.  if( pStmt )
1d30: 7b 0a 20 20 20 20 69 6e 74 20 72 63 32 20 3d 20  {.    int rc2 = 
1d40: 73 71 6c 69 74 65 33 5f 66 69 6e 61 6c 69 7a 65  sqlite3_finalize
1d50: 28 70 53 74 6d 74 29 3b 0a 20 20 20 20 69 66 28  (pStmt);.    if(
1d60: 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc==SQLITE_OK )
1d70: 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 72 63 32  {.      rc = rc2
1d80: 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 69 66  ;.    }.  }.  if
1d90: 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc!=SQLITE_OK 
1da0: 29 7b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 66  ){.    sqlite3_f
1db0: 72 65 65 28 61 49 6e 64 65 78 29 3b 0a 20 20 20  ree(aIndex);.   
1dc0: 20 61 49 6e 64 65 78 20 3d 20 30 3b 0a 20 20 7d   aIndex = 0;.  }
1dd0: 0a 20 20 2a 70 61 49 6e 64 65 78 20 3d 20 61 49  .  *paIndex = aI
1de0: 6e 64 65 78 3b 0a 20 20 72 65 74 75 72 6e 20 72  ndex;.  return r
1df0: 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 47 6c 6f 62  c;.}../*.** Glob
1e00: 61 6c 20 54 63 6c 20 76 61 72 69 61 62 6c 65 20  al Tcl variable 
1e10: 24 65 63 68 6f 5f 6d 6f 64 75 6c 65 20 69 73 20  $echo_module is 
1e20: 61 20 6c 69 73 74 2e 20 54 68 69 73 20 72 6f 75  a list. This rou
1e30: 74 69 6e 65 20 61 70 70 65 6e 64 73 0a 2a 2a 20  tine appends.** 
1e40: 74 68 65 20 73 74 72 69 6e 67 20 65 6c 65 6d 65  the string eleme
1e50: 6e 74 20 7a 41 72 67 20 74 6f 20 74 68 61 74 20  nt zArg to that 
1e60: 6c 69 73 74 20 69 6e 20 69 6e 74 65 72 70 72 65  list in interpre
1e70: 74 65 72 20 69 6e 74 65 72 70 2e 0a 2a 2f 0a 73  ter interp..*/.s
1e80: 74 61 74 69 63 20 76 6f 69 64 20 61 70 70 65 6e  tatic void appen
1e90: 64 54 6f 45 63 68 6f 4d 6f 64 75 6c 65 28 54 63  dToEchoModule(Tc
1ea0: 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70  l_Interp *interp
1eb0: 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 41  , const char *zA
1ec0: 72 67 29 7b 0a 20 20 69 6e 74 20 66 6c 61 67 73  rg){.  int flags
1ed0: 20 3d 20 28 54 43 4c 5f 41 50 50 45 4e 44 5f 56   = (TCL_APPEND_V
1ee0: 41 4c 55 45 20 7c 20 54 43 4c 5f 4c 49 53 54 5f  ALUE | TCL_LIST_
1ef0: 45 4c 45 4d 45 4e 54 20 7c 20 54 43 4c 5f 47 4c  ELEMENT | TCL_GL
1f00: 4f 42 41 4c 5f 4f 4e 4c 59 29 3b 0a 20 20 54 63  OBAL_ONLY);.  Tc
1f10: 6c 5f 53 65 74 56 61 72 28 69 6e 74 65 72 70 2c  l_SetVar(interp,
1f20: 20 22 65 63 68 6f 5f 6d 6f 64 75 6c 65 22 2c 20   "echo_module", 
1f30: 28 7a 41 72 67 3f 7a 41 72 67 3a 22 22 29 2c 20  (zArg?zArg:""), 
1f40: 66 6c 61 67 73 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  flags);.}../*.**
1f50: 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 69   This function i
1f60: 73 20 63 61 6c 6c 65 64 20 66 72 6f 6d 20 77 69  s called from wi
1f70: 74 68 69 6e 20 74 68 65 20 65 63 68 6f 2d 6d 6f  thin the echo-mo
1f80: 64 75 6c 65 73 20 78 43 72 65 61 74 65 20 61 6e  dules xCreate an
1f90: 64 0a 2a 2a 20 78 43 6f 6e 6e 65 63 74 20 6d 65  d.** xConnect me
1fa0: 74 68 6f 64 73 2e 20 54 68 65 20 61 72 67 63 20  thods. The argc 
1fb0: 61 6e 64 20 61 72 67 76 20 61 72 67 75 6d 65 6e  and argv argumen
1fc0: 74 73 20 61 72 65 20 63 6f 70 69 65 73 20 6f 66  ts are copies of
1fd0: 20 74 68 6f 73 65 20 0a 2a 2a 20 70 61 73 73 65   those .** passe
1fe0: 64 20 74 6f 20 74 68 65 20 63 61 6c 6c 69 6e 67  d to the calling
1ff0: 20 6d 65 74 68 6f 64 2e 20 54 68 69 73 20 66 75   method. This fu
2000: 6e 63 74 69 6f 6e 20 69 73 20 72 65 73 70 6f 6e  nction is respon
2010: 73 69 62 6c 65 20 66 6f 72 0a 2a 2a 20 63 61 6c  sible for.** cal
2020: 6c 69 6e 67 20 73 71 6c 69 74 65 33 5f 64 65 63  ling sqlite3_dec
2030: 6c 61 72 65 5f 76 74 61 62 28 29 20 74 6f 20 64  lare_vtab() to d
2040: 65 63 6c 61 72 65 20 74 68 65 20 73 63 68 65 6d  eclare the schem
2050: 61 20 6f 66 20 74 68 65 20 76 69 72 74 75 61 6c  a of the virtual
2060: 0a 2a 2a 20 74 61 62 6c 65 20 62 65 69 6e 67 20  .** table being 
2070: 63 72 65 61 74 65 64 20 6f 72 20 63 6f 6e 6e 65  created or conne
2080: 63 74 65 64 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 74  cted..**.** If t
2090: 68 65 20 63 6f 6e 73 74 72 75 63 74 6f 72 20 77  he constructor w
20a0: 61 73 20 70 61 73 73 65 64 20 6a 75 73 74 20 6f  as passed just o
20b0: 6e 65 20 61 72 67 75 6d 65 6e 74 2c 20 69 2e 65  ne argument, i.e
20c0: 2e 3a 0a 2a 2a 0a 2a 2a 20 20 20 43 52 45 41 54  .:.**.**   CREAT
20d0: 45 20 54 41 42 4c 45 20 74 31 20 41 53 20 65 63  E TABLE t1 AS ec
20e0: 68 6f 28 74 32 29 3b 0a 2a 2a 0a 2a 2a 20 54 68  ho(t2);.**.** Th
20f0: 65 6e 20 74 32 20 69 73 20 61 73 73 75 6d 65 64  en t2 is assumed
2100: 20 74 6f 20 62 65 20 74 68 65 20 6e 61 6d 65 20   to be the name 
2110: 6f 66 20 61 20 2a 72 65 61 6c 2a 20 64 61 74 61  of a *real* data
2120: 62 61 73 65 20 74 61 62 6c 65 2e 20 54 68 65 0a  base table. The.
2130: 2a 2a 20 73 63 68 65 6d 61 20 6f 66 20 74 68 65  ** schema of the
2140: 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65 20 69   virtual table i
2150: 73 20 64 65 63 6c 61 72 65 64 20 62 79 20 70 61  s declared by pa
2160: 73 73 69 6e 67 20 61 20 63 6f 70 79 20 6f 66 20  ssing a copy of 
2170: 74 68 65 20 0a 2a 2a 20 43 52 45 41 54 45 20 54  the .** CREATE T
2180: 41 42 4c 45 20 73 74 61 74 65 6d 65 6e 74 20 66  ABLE statement f
2190: 6f 72 20 74 68 65 20 72 65 61 6c 20 74 61 62 6c  or the real tabl
21a0: 65 20 74 6f 20 73 71 6c 69 74 65 33 5f 64 65 63  e to sqlite3_dec
21b0: 6c 61 72 65 5f 76 74 61 62 28 29 2e 0a 2a 2a 20  lare_vtab()..** 
21c0: 48 65 6e 63 65 2c 20 74 68 65 20 76 69 72 74 75  Hence, the virtu
21d0: 61 6c 20 74 61 62 6c 65 20 73 68 6f 75 6c 64 20  al table should 
21e0: 68 61 76 65 20 65 78 61 63 74 6c 79 20 74 68 65  have exactly the
21f0: 20 73 61 6d 65 20 63 6f 6c 75 6d 6e 20 6e 61 6d   same column nam
2200: 65 73 20 61 6e 64 20 0a 2a 2a 20 74 79 70 65 73  es and .** types
2210: 20 61 73 20 74 68 65 20 72 65 61 6c 20 74 61 62   as the real tab
2220: 6c 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  le..*/.static in
2230: 74 20 65 63 68 6f 44 65 63 6c 61 72 65 56 74 61  t echoDeclareVta
2240: 62 28 0a 20 20 65 63 68 6f 5f 76 74 61 62 20 2a  b(.  echo_vtab *
2250: 70 56 74 61 62 2c 20 0a 20 20 73 71 6c 69 74 65  pVtab, .  sqlite
2260: 33 20 2a 64 62 20 0a 29 7b 0a 20 20 69 6e 74 20  3 *db .){.  int 
2270: 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a  rc = SQLITE_OK;.
2280: 0a 20 20 69 66 28 20 70 56 74 61 62 2d 3e 7a 54  .  if( pVtab->zT
2290: 61 62 6c 65 4e 61 6d 65 20 29 7b 0a 20 20 20 20  ableName ){.    
22a0: 73 71 6c 69 74 65 33 5f 73 74 6d 74 20 2a 70 53  sqlite3_stmt *pS
22b0: 74 6d 74 20 3d 20 30 3b 0a 20 20 20 20 72 63 20  tmt = 0;.    rc 
22c0: 3d 20 73 71 6c 69 74 65 33 5f 70 72 65 70 61 72  = sqlite3_prepar
22d0: 65 28 64 62 2c 20 0a 20 20 20 20 20 20 20 20 22  e(db, .        "
22e0: 53 45 4c 45 43 54 20 73 71 6c 20 46 52 4f 4d 20  SELECT sql FROM 
22f0: 73 71 6c 69 74 65 5f 6d 61 73 74 65 72 20 57 48  sqlite_master WH
2300: 45 52 45 20 74 79 70 65 20 3d 20 27 74 61 62 6c  ERE type = 'tabl
2310: 65 27 20 41 4e 44 20 6e 61 6d 65 20 3d 20 3f 22  e' AND name = ?"
2320: 2c 0a 20 20 20 20 20 20 20 20 2d 31 2c 20 26 70  ,.        -1, &p
2330: 53 74 6d 74 2c 20 30 29 3b 0a 20 20 20 20 69 66  Stmt, 0);.    if
2340: 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
2350: 29 7b 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33  ){.      sqlite3
2360: 5f 62 69 6e 64 5f 74 65 78 74 28 70 53 74 6d 74  _bind_text(pStmt
2370: 2c 20 31 2c 20 70 56 74 61 62 2d 3e 7a 54 61 62  , 1, pVtab->zTab
2380: 6c 65 4e 61 6d 65 2c 20 2d 31 2c 20 30 29 3b 0a  leName, -1, 0);.
2390: 20 20 20 20 20 20 69 66 28 20 73 71 6c 69 74 65        if( sqlite
23a0: 33 5f 73 74 65 70 28 70 53 74 6d 74 29 3d 3d 53  3_step(pStmt)==S
23b0: 51 4c 49 54 45 5f 52 4f 57 20 29 7b 0a 20 20 20  QLITE_ROW ){.   
23c0: 20 20 20 20 20 69 6e 74 20 72 63 32 3b 0a 20 20       int rc2;.  
23d0: 20 20 20 20 20 20 63 6f 6e 73 74 20 63 68 61 72        const char
23e0: 20 2a 7a 43 72 65 61 74 65 54 61 62 6c 65 20 3d   *zCreateTable =
23f0: 20 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 29 73   (const char *)s
2400: 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 74 65  qlite3_column_te
2410: 78 74 28 70 53 74 6d 74 2c 20 30 29 3b 0a 20 20  xt(pStmt, 0);.  
2420: 20 20 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74        rc = sqlit
2430: 65 33 5f 64 65 63 6c 61 72 65 5f 76 74 61 62 28  e3_declare_vtab(
2440: 64 62 2c 20 7a 43 72 65 61 74 65 54 61 62 6c 65  db, zCreateTable
2450: 29 3b 0a 20 20 20 20 20 20 20 20 72 63 32 20 3d  );.        rc2 =
2460: 20 73 71 6c 69 74 65 33 5f 66 69 6e 61 6c 69 7a   sqlite3_finaliz
2470: 65 28 70 53 74 6d 74 29 3b 0a 20 20 20 20 20 20  e(pStmt);.      
2480: 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
2490: 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20 20 20  _OK ){.         
24a0: 20 72 63 20 3d 20 72 63 32 3b 0a 20 20 20 20 20   rc = rc2;.     
24b0: 20 20 20 7d 0a 20 20 20 20 20 20 7d 20 65 6c 73     }.      } els
24c0: 65 20 7b 0a 20 20 20 20 20 20 20 20 72 63 20 3d  e {.        rc =
24d0: 20 73 71 6c 69 74 65 33 5f 66 69 6e 61 6c 69 7a   sqlite3_finaliz
24e0: 65 28 70 53 74 6d 74 29 3b 0a 20 20 20 20 20 20  e(pStmt);.      
24f0: 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
2500: 5f 4f 4b 20 29 7b 20 0a 20 20 20 20 20 20 20 20  _OK ){ .        
2510: 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 45 52    rc = SQLITE_ER
2520: 52 4f 52 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20  ROR;.        }. 
2530: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 69 66 28       }.      if(
2540: 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc==SQLITE_OK )
2550: 7b 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20 67  {.        rc = g
2560: 65 74 43 6f 6c 75 6d 6e 4e 61 6d 65 73 28 64 62  etColumnNames(db
2570: 2c 20 70 56 74 61 62 2d 3e 7a 54 61 62 6c 65 4e  , pVtab->zTableN
2580: 61 6d 65 2c 20 26 70 56 74 61 62 2d 3e 61 43 6f  ame, &pVtab->aCo
2590: 6c 2c 20 26 70 56 74 61 62 2d 3e 6e 43 6f 6c 29  l, &pVtab->nCol)
25a0: 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20  ;.      }.      
25b0: 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  if( rc==SQLITE_O
25c0: 4b 20 29 7b 0a 20 20 20 20 20 20 20 20 72 63 20  K ){.        rc 
25d0: 3d 20 67 65 74 49 6e 64 65 78 41 72 72 61 79 28  = getIndexArray(
25e0: 64 62 2c 20 70 56 74 61 62 2d 3e 7a 54 61 62 6c  db, pVtab->zTabl
25f0: 65 4e 61 6d 65 2c 20 70 56 74 61 62 2d 3e 6e 43  eName, pVtab->nC
2600: 6f 6c 2c 20 26 70 56 74 61 62 2d 3e 61 49 6e 64  ol, &pVtab->aInd
2610: 65 78 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20  ex);.      }.   
2620: 20 7d 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e   }.  }..  return
2630: 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68   rc;.}../*.** Th
2640: 69 73 20 66 75 6e 63 74 69 6f 6e 20 66 72 65 65  is function free
2650: 73 20 61 6c 6c 20 72 75 6e 74 69 6d 65 20 73 74  s all runtime st
2660: 72 75 63 74 75 72 65 73 20 61 73 73 6f 63 69 61  ructures associa
2670: 74 65 64 20 77 69 74 68 20 74 68 65 20 76 69 72  ted with the vir
2680: 74 75 61 6c 0a 2a 2a 20 74 61 62 6c 65 20 70 56  tual.** table pV
2690: 74 61 62 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  tab..*/.static i
26a0: 6e 74 20 65 63 68 6f 44 65 73 74 72 75 63 74 6f  nt echoDestructo
26b0: 72 28 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a  r(sqlite3_vtab *
26c0: 70 56 74 61 62 29 7b 0a 20 20 65 63 68 6f 5f 76  pVtab){.  echo_v
26d0: 74 61 62 20 2a 70 20 3d 20 28 65 63 68 6f 5f 76  tab *p = (echo_v
26e0: 74 61 62 2a 29 70 56 74 61 62 3b 0a 20 20 73 71  tab*)pVtab;.  sq
26f0: 6c 69 74 65 33 5f 66 72 65 65 28 70 2d 3e 61 49  lite3_free(p->aI
2700: 6e 64 65 78 29 3b 0a 20 20 73 71 6c 69 74 65 33  ndex);.  sqlite3
2710: 5f 66 72 65 65 28 70 2d 3e 61 43 6f 6c 29 3b 0a  _free(p->aCol);.
2720: 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70    sqlite3_free(p
2730: 2d 3e 7a 54 68 69 73 29 3b 0a 20 20 73 71 6c 69  ->zThis);.  sqli
2740: 74 65 33 5f 66 72 65 65 28 70 2d 3e 7a 54 61 62  te3_free(p->zTab
2750: 6c 65 4e 61 6d 65 29 3b 0a 20 20 73 71 6c 69 74  leName);.  sqlit
2760: 65 33 5f 66 72 65 65 28 70 2d 3e 7a 4c 6f 67 4e  e3_free(p->zLogN
2770: 61 6d 65 29 3b 0a 20 20 73 71 6c 69 74 65 33 5f  ame);.  sqlite3_
2780: 66 72 65 65 28 70 29 3b 0a 20 20 72 65 74 75 72  free(p);.  retur
2790: 6e 20 30 3b 0a 7d 0a 0a 74 79 70 65 64 65 66 20  n 0;.}..typedef 
27a0: 73 74 72 75 63 74 20 45 63 68 6f 4d 6f 64 75 6c  struct EchoModul
27b0: 65 20 45 63 68 6f 4d 6f 64 75 6c 65 3b 0a 73 74  e EchoModule;.st
27c0: 72 75 63 74 20 45 63 68 6f 4d 6f 64 75 6c 65 20  ruct EchoModule 
27d0: 7b 0a 20 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a  {.  Tcl_Interp *
27e0: 69 6e 74 65 72 70 3b 0a 7d 3b 0a 0a 2f 2a 0a 2a  interp;.};../*.*
27f0: 2a 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20  * This function 
2800: 69 73 20 63 61 6c 6c 65 64 20 74 6f 20 64 6f 20  is called to do 
2810: 74 68 65 20 77 6f 72 6b 20 6f 66 20 74 68 65 20  the work of the 
2820: 78 43 6f 6e 6e 65 63 74 28 29 20 6d 65 74 68 6f  xConnect() metho
2830: 64 20 2d 0a 2a 2a 20 74 6f 20 61 6c 6c 6f 63 61  d -.** to alloca
2840: 74 65 20 74 68 65 20 72 65 71 75 69 72 65 64 20  te the required 
2850: 69 6e 2d 6d 65 6d 6f 72 79 20 73 74 72 75 63 74  in-memory struct
2860: 75 72 65 73 20 66 6f 72 20 61 20 6e 65 77 6c 79  ures for a newly
2870: 20 63 6f 6e 6e 65 63 74 65 64 0a 2a 2a 20 76 69   connected.** vi
2880: 72 74 75 61 6c 20 74 61 62 6c 65 2e 0a 2a 2f 0a  rtual table..*/.
2890: 73 74 61 74 69 63 20 69 6e 74 20 65 63 68 6f 43  static int echoC
28a0: 6f 6e 73 74 72 75 63 74 6f 72 28 0a 20 20 73 71  onstructor(.  sq
28b0: 6c 69 74 65 33 20 2a 64 62 2c 0a 20 20 76 6f 69  lite3 *db,.  voi
28c0: 64 20 2a 70 41 75 78 2c 0a 20 20 69 6e 74 20 61  d *pAux,.  int a
28d0: 72 67 63 2c 20 63 6f 6e 73 74 20 63 68 61 72 20  rgc, const char 
28e0: 2a 63 6f 6e 73 74 2a 61 72 67 76 2c 0a 20 20 73  *const*argv,.  s
28f0: 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 2a 70 70  qlite3_vtab **pp
2900: 56 74 61 62 2c 0a 20 20 63 68 61 72 20 2a 2a 70  Vtab,.  char **p
2910: 7a 45 72 72 0a 29 7b 0a 20 20 69 6e 74 20 72 63  zErr.){.  int rc
2920: 3b 0a 20 20 69 6e 74 20 69 3b 0a 20 20 65 63 68  ;.  int i;.  ech
2930: 6f 5f 76 74 61 62 20 2a 70 56 74 61 62 3b 0a 0a  o_vtab *pVtab;..
2940: 20 20 2f 2a 20 41 6c 6c 6f 63 61 74 65 20 74 68    /* Allocate th
2950: 65 20 73 71 6c 69 74 65 33 5f 76 74 61 62 2f 65  e sqlite3_vtab/e
2960: 63 68 6f 5f 76 74 61 62 20 73 74 72 75 63 74 75  cho_vtab structu
2970: 72 65 20 69 74 73 65 6c 66 20 2a 2f 0a 20 20 70  re itself */.  p
2980: 56 74 61 62 20 3d 20 73 71 6c 69 74 65 33 4d 61  Vtab = sqlite3Ma
2990: 6c 6c 6f 63 5a 65 72 6f 28 20 73 69 7a 65 6f 66  llocZero( sizeof
29a0: 28 2a 70 56 74 61 62 29 20 29 3b 0a 20 20 69 66  (*pVtab) );.  if
29b0: 28 20 21 70 56 74 61 62 20 29 7b 0a 20 20 20 20  ( !pVtab ){.    
29c0: 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f  return SQLITE_NO
29d0: 4d 45 4d 3b 0a 20 20 7d 0a 20 20 70 56 74 61 62  MEM;.  }.  pVtab
29e0: 2d 3e 69 6e 74 65 72 70 20 3d 20 28 28 45 63 68  ->interp = ((Ech
29f0: 6f 4d 6f 64 75 6c 65 20 2a 29 70 41 75 78 29 2d  oModule *)pAux)-
2a00: 3e 69 6e 74 65 72 70 3b 0a 20 20 70 56 74 61 62  >interp;.  pVtab
2a10: 2d 3e 64 62 20 3d 20 64 62 3b 0a 0a 20 20 2f 2a  ->db = db;..  /*
2a20: 20 41 6c 6c 6f 63 61 74 65 20 65 63 68 6f 5f 76   Allocate echo_v
2a30: 74 61 62 2e 7a 54 68 69 73 20 2a 2f 0a 20 20 70  tab.zThis */.  p
2a40: 56 74 61 62 2d 3e 7a 54 68 69 73 20 3d 20 73 71  Vtab->zThis = sq
2a50: 6c 69 74 65 33 4d 50 72 69 6e 74 66 28 30 2c 20  lite3MPrintf(0, 
2a60: 22 25 73 22 2c 20 61 72 67 76 5b 32 5d 29 3b 0a  "%s", argv[2]);.
2a70: 20 20 69 66 28 20 21 70 56 74 61 62 2d 3e 7a 54    if( !pVtab->zT
2a80: 68 69 73 20 29 7b 0a 20 20 20 20 65 63 68 6f 44  his ){.    echoD
2a90: 65 73 74 72 75 63 74 6f 72 28 28 73 71 6c 69 74  estructor((sqlit
2aa0: 65 33 5f 76 74 61 62 20 2a 29 70 56 74 61 62 29  e3_vtab *)pVtab)
2ab0: 3b 0a 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c  ;.    return SQL
2ac0: 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 7d 0a 0a  ITE_NOMEM;.  }..
2ad0: 20 20 2f 2a 20 41 6c 6c 6f 63 61 74 65 20 65 63    /* Allocate ec
2ae0: 68 6f 5f 76 74 61 62 2e 7a 54 61 62 6c 65 4e 61  ho_vtab.zTableNa
2af0: 6d 65 20 2a 2f 0a 20 20 69 66 28 20 61 72 67 63  me */.  if( argc
2b00: 3e 33 20 29 7b 0a 20 20 20 20 70 56 74 61 62 2d  >3 ){.    pVtab-
2b10: 3e 7a 54 61 62 6c 65 4e 61 6d 65 20 3d 20 73 71  >zTableName = sq
2b20: 6c 69 74 65 33 4d 50 72 69 6e 74 66 28 30 2c 20  lite3MPrintf(0, 
2b30: 22 25 73 22 2c 20 61 72 67 76 5b 33 5d 29 3b 0a  "%s", argv[3]);.
2b40: 20 20 20 20 64 65 71 75 6f 74 65 53 74 72 69 6e      dequoteStrin
2b50: 67 28 70 56 74 61 62 2d 3e 7a 54 61 62 6c 65 4e  g(pVtab->zTableN
2b60: 61 6d 65 29 3b 0a 20 20 20 20 69 66 28 20 70 56  ame);.    if( pV
2b70: 74 61 62 2d 3e 7a 54 61 62 6c 65 4e 61 6d 65 20  tab->zTableName 
2b80: 26 26 20 70 56 74 61 62 2d 3e 7a 54 61 62 6c 65  && pVtab->zTable
2b90: 4e 61 6d 65 5b 30 5d 3d 3d 27 2a 27 20 29 7b 0a  Name[0]=='*' ){.
2ba0: 20 20 20 20 20 20 63 68 61 72 20 2a 7a 20 3d 20        char *z = 
2bb0: 73 71 6c 69 74 65 33 4d 50 72 69 6e 74 66 28 30  sqlite3MPrintf(0
2bc0: 2c 20 22 25 73 25 73 22 2c 20 61 72 67 76 5b 32  , "%s%s", argv[2
2bd0: 5d 2c 20 26 28 70 56 74 61 62 2d 3e 7a 54 61 62  ], &(pVtab->zTab
2be0: 6c 65 4e 61 6d 65 5b 31 5d 29 29 3b 0a 20 20 20  leName[1]));.   
2bf0: 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28     sqlite3_free(
2c00: 70 56 74 61 62 2d 3e 7a 54 61 62 6c 65 4e 61 6d  pVtab->zTableNam
2c10: 65 29 3b 0a 20 20 20 20 20 20 70 56 74 61 62 2d  e);.      pVtab-
2c20: 3e 7a 54 61 62 6c 65 4e 61 6d 65 20 3d 20 7a 3b  >zTableName = z;
2c30: 0a 20 20 20 20 20 20 70 56 74 61 62 2d 3e 69 73  .      pVtab->is
2c40: 50 61 74 74 65 72 6e 20 3d 20 31 3b 0a 20 20 20  Pattern = 1;.   
2c50: 20 7d 0a 20 20 20 20 69 66 28 20 21 70 56 74 61   }.    if( !pVta
2c60: 62 2d 3e 7a 54 61 62 6c 65 4e 61 6d 65 20 29 7b  b->zTableName ){
2c70: 0a 20 20 20 20 20 20 65 63 68 6f 44 65 73 74 72  .      echoDestr
2c80: 75 63 74 6f 72 28 28 73 71 6c 69 74 65 33 5f 76  uctor((sqlite3_v
2c90: 74 61 62 20 2a 29 70 56 74 61 62 29 3b 0a 20 20  tab *)pVtab);.  
2ca0: 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54      return SQLIT
2cb0: 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 7d 0a 20  E_NOMEM;.    }. 
2cc0: 20 7d 0a 0a 20 20 2f 2a 20 4c 6f 67 20 74 68 65   }..  /* Log the
2cd0: 20 61 72 67 75 6d 65 6e 74 73 20 74 6f 20 74 68   arguments to th
2ce0: 69 73 20 66 75 6e 63 74 69 6f 6e 20 74 6f 20 54  is function to T
2cf0: 63 6c 20 76 61 72 20 3a 3a 65 63 68 6f 5f 6d 6f  cl var ::echo_mo
2d00: 64 75 6c 65 20 2a 2f 0a 20 20 66 6f 72 28 69 3d  dule */.  for(i=
2d10: 30 3b 20 69 3c 61 72 67 63 3b 20 69 2b 2b 29 7b  0; i<argc; i++){
2d20: 0a 20 20 20 20 61 70 70 65 6e 64 54 6f 45 63 68  .    appendToEch
2d30: 6f 4d 6f 64 75 6c 65 28 70 56 74 61 62 2d 3e 69  oModule(pVtab->i
2d40: 6e 74 65 72 70 2c 20 61 72 67 76 5b 69 5d 29 3b  nterp, argv[i]);
2d50: 0a 20 20 7d 0a 0a 20 20 2f 2a 20 49 6e 76 6f 6b  .  }..  /* Invok
2d60: 65 20 73 71 6c 69 74 65 33 5f 64 65 63 6c 61 72  e sqlite3_declar
2d70: 65 5f 76 74 61 62 20 61 6e 64 20 73 65 74 20 75  e_vtab and set u
2d80: 70 20 6f 74 68 65 72 20 6d 65 6d 62 65 72 73 20  p other members 
2d90: 6f 66 20 74 68 65 20 65 63 68 6f 5f 76 74 61 62  of the echo_vtab
2da0: 0a 20 20 2a 2a 20 73 74 72 75 63 74 75 72 65 2e  .  ** structure.
2db0: 20 49 66 20 61 6e 20 65 72 72 6f 72 20 6f 63 63   If an error occ
2dc0: 75 72 73 2c 20 64 65 6c 65 74 65 20 74 68 65 20  urs, delete the 
2dd0: 73 71 6c 69 74 65 33 5f 76 74 61 62 20 73 74 72  sqlite3_vtab str
2de0: 75 63 74 75 72 65 20 61 6e 64 0a 20 20 2a 2a 20  ucture and.  ** 
2df0: 72 65 74 75 72 6e 20 61 6e 20 65 72 72 6f 72 20  return an error 
2e00: 63 6f 64 65 2e 0a 20 20 2a 2f 0a 20 20 72 63 20  code..  */.  rc 
2e10: 3d 20 65 63 68 6f 44 65 63 6c 61 72 65 56 74 61  = echoDeclareVta
2e20: 62 28 70 56 74 61 62 2c 20 64 62 29 3b 0a 20 20  b(pVtab, db);.  
2e30: 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f  if( rc!=SQLITE_O
2e40: 4b 20 29 7b 0a 20 20 20 20 65 63 68 6f 44 65 73  K ){.    echoDes
2e50: 74 72 75 63 74 6f 72 28 28 73 71 6c 69 74 65 33  tructor((sqlite3
2e60: 5f 76 74 61 62 20 2a 29 70 56 74 61 62 29 3b 0a  _vtab *)pVtab);.
2e70: 20 20 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 20      return rc;. 
2e80: 20 7d 0a 0a 20 20 2f 2a 20 53 75 63 63 65 73 73   }..  /* Success
2e90: 2e 20 53 65 74 20 2a 70 70 56 74 61 62 20 61 6e  . Set *ppVtab an
2ea0: 64 20 72 65 74 75 72 6e 20 2a 2f 0a 20 20 2a 70  d return */.  *p
2eb0: 70 56 74 61 62 20 3d 20 26 70 56 74 61 62 2d 3e  pVtab = &pVtab->
2ec0: 62 61 73 65 3b 0a 20 20 72 65 74 75 72 6e 20 53  base;.  return S
2ed0: 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 20  QLITE_OK;.}../* 
2ee0: 0a 2a 2a 20 45 63 68 6f 20 76 69 72 74 75 61 6c  .** Echo virtual
2ef0: 20 74 61 62 6c 65 20 6d 6f 64 75 6c 65 20 78 43   table module xC
2f00: 72 65 61 74 65 20 6d 65 74 68 6f 64 2e 0a 2a 2f  reate method..*/
2f10: 0a 73 74 61 74 69 63 20 69 6e 74 20 65 63 68 6f  .static int echo
2f20: 43 72 65 61 74 65 28 0a 20 20 73 71 6c 69 74 65  Create(.  sqlite
2f30: 33 20 2a 64 62 2c 0a 20 20 76 6f 69 64 20 2a 70  3 *db,.  void *p
2f40: 41 75 78 2c 0a 20 20 69 6e 74 20 61 72 67 63 2c  Aux,.  int argc,
2f50: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 63 6f 6e   const char *con
2f60: 73 74 2a 61 72 67 76 2c 0a 20 20 73 71 6c 69 74  st*argv,.  sqlit
2f70: 65 33 5f 76 74 61 62 20 2a 2a 70 70 56 74 61 62  e3_vtab **ppVtab
2f80: 2c 0a 20 20 63 68 61 72 20 2a 2a 70 7a 45 72 72  ,.  char **pzErr
2f90: 0a 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53  .){.  int rc = S
2fa0: 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 61 70 70 65  QLITE_OK;.  appe
2fb0: 6e 64 54 6f 45 63 68 6f 4d 6f 64 75 6c 65 28 28  ndToEchoModule((
2fc0: 28 45 63 68 6f 4d 6f 64 75 6c 65 20 2a 29 70 41  (EchoModule *)pA
2fd0: 75 78 29 2d 3e 69 6e 74 65 72 70 2c 20 22 78 43  ux)->interp, "xC
2fe0: 72 65 61 74 65 22 29 3b 0a 20 20 72 63 20 3d 20  reate");.  rc = 
2ff0: 65 63 68 6f 43 6f 6e 73 74 72 75 63 74 6f 72 28  echoConstructor(
3000: 64 62 2c 20 70 41 75 78 2c 20 61 72 67 63 2c 20  db, pAux, argc, 
3010: 61 72 67 76 2c 20 70 70 56 74 61 62 2c 20 70 7a  argv, ppVtab, pz
3020: 45 72 72 29 3b 0a 0a 20 20 2f 2a 20 49 66 20 74  Err);..  /* If t
3030: 68 65 72 65 20 77 65 72 65 20 74 77 6f 20 61 72  here were two ar
3040: 67 75 6d 65 6e 74 73 20 70 61 73 73 65 64 20 74  guments passed t
3050: 6f 20 74 68 65 20 6d 6f 64 75 6c 65 20 61 74 20  o the module at 
3060: 74 68 65 20 53 51 4c 20 6c 65 76 65 6c 20 0a 20  the SQL level . 
3070: 20 2a 2a 20 28 69 2e 65 2e 20 22 43 52 45 41 54   ** (i.e. "CREAT
3080: 45 20 56 49 52 54 55 41 4c 20 54 41 42 4c 45 20  E VIRTUAL TABLE 
3090: 74 62 6c 20 55 53 49 4e 47 20 65 63 68 6f 28 61  tbl USING echo(a
30a0: 72 67 31 2c 20 61 72 67 32 29 22 29 2c 20 74 68  rg1, arg2)"), th
30b0: 65 6e 20 0a 20 20 2a 2a 20 74 68 65 20 73 65 63  en .  ** the sec
30c0: 6f 6e 64 20 61 72 67 75 6d 65 6e 74 20 69 73 20  ond argument is 
30d0: 75 73 65 64 20 61 73 20 61 20 74 61 62 6c 65 20  used as a table 
30e0: 6e 61 6d 65 2e 20 41 74 74 65 6d 70 74 20 74 6f  name. Attempt to
30f0: 20 63 72 65 61 74 65 0a 20 20 2a 2a 20 73 75 63   create.  ** suc
3100: 68 20 61 20 74 61 62 6c 65 20 77 69 74 68 20 61  h a table with a
3110: 20 73 69 6e 67 6c 65 20 63 6f 6c 75 6d 6e 2c 20   single column, 
3120: 22 6c 6f 67 6d 73 67 22 2e 20 54 68 69 73 20 74  "logmsg". This t
3130: 61 62 6c 65 20 77 69 6c 6c 0a 20 20 2a 2a 20 62  able will.  ** b
3140: 65 20 75 73 65 64 20 74 6f 20 6c 6f 67 20 63 61  e used to log ca
3150: 6c 6c 73 20 74 6f 20 74 68 65 20 78 55 70 64 61  lls to the xUpda
3160: 74 65 20 6d 65 74 68 6f 64 2e 20 49 74 20 77 69  te method. It wi
3170: 6c 6c 20 62 65 20 64 65 6c 65 74 65 64 0a 20 20  ll be deleted.  
3180: 2a 2a 20 77 68 65 6e 20 74 68 65 20 76 69 72 74  ** when the virt
3190: 75 61 6c 20 74 61 62 6c 65 20 69 73 20 44 52 4f  ual table is DRO
31a0: 50 65 64 2e 0a 20 20 2a 2a 0a 20 20 2a 2a 20 4e  Ped..  **.  ** N
31b0: 6f 74 65 3a 20 54 68 65 20 6d 61 69 6e 20 70 6f  ote: The main po
31c0: 69 6e 74 20 6f 66 20 74 68 69 73 20 69 73 20 74  int of this is t
31d0: 6f 20 74 65 73 74 20 74 68 61 74 20 77 65 20 63  o test that we c
31e0: 61 6e 20 64 72 6f 70 20 74 61 62 6c 65 73 0a 20  an drop tables. 
31f0: 20 2a 2a 20 66 72 6f 6d 20 77 69 74 68 69 6e 20   ** from within 
3200: 61 6e 20 78 44 65 73 74 72 6f 79 20 6d 65 74 68  an xDestroy meth
3210: 6f 64 20 63 61 6c 6c 2e 0a 20 20 2a 2f 0a 20 20  od call..  */.  
3220: 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  if( rc==SQLITE_O
3230: 4b 20 26 26 20 61 72 67 63 3d 3d 35 20 29 7b 0a  K && argc==5 ){.
3240: 20 20 20 20 63 68 61 72 20 2a 7a 53 71 6c 3b 0a      char *zSql;.
3250: 20 20 20 20 65 63 68 6f 5f 76 74 61 62 20 2a 70      echo_vtab *p
3260: 56 74 61 62 20 3d 20 2a 28 65 63 68 6f 5f 76 74  Vtab = *(echo_vt
3270: 61 62 20 2a 2a 29 70 70 56 74 61 62 3b 0a 20 20  ab **)ppVtab;.  
3280: 20 20 70 56 74 61 62 2d 3e 7a 4c 6f 67 4e 61 6d    pVtab->zLogNam
3290: 65 20 3d 20 73 71 6c 69 74 65 33 4d 50 72 69 6e  e = sqlite3MPrin
32a0: 74 66 28 30 2c 20 22 25 73 22 2c 20 61 72 67 76  tf(0, "%s", argv
32b0: 5b 34 5d 29 3b 0a 20 20 20 20 7a 53 71 6c 20 3d  [4]);.    zSql =
32c0: 20 73 71 6c 69 74 65 33 4d 50 72 69 6e 74 66 28   sqlite3MPrintf(
32d0: 30 2c 20 22 43 52 45 41 54 45 20 54 41 42 4c 45  0, "CREATE TABLE
32e0: 20 25 51 28 6c 6f 67 6d 73 67 29 22 2c 20 70 56   %Q(logmsg)", pV
32f0: 74 61 62 2d 3e 7a 4c 6f 67 4e 61 6d 65 29 3b 0a  tab->zLogName);.
3300: 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33      rc = sqlite3
3310: 5f 65 78 65 63 28 64 62 2c 20 7a 53 71 6c 2c 20  _exec(db, zSql, 
3320: 30 2c 20 30 2c 20 30 29 3b 0a 20 20 20 20 73 71  0, 0, 0);.    sq
3330: 6c 69 74 65 33 5f 66 72 65 65 28 7a 53 71 6c 29  lite3_free(zSql)
3340: 3b 0a 20 20 20 20 69 66 28 20 72 63 21 3d 53 51  ;.    if( rc!=SQ
3350: 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20  LITE_OK ){.     
3360: 20 2a 70 7a 45 72 72 20 3d 20 73 71 6c 69 74 65   *pzErr = sqlite
3370: 33 53 74 72 44 75 70 28 73 71 6c 69 74 65 33 5f  3StrDup(sqlite3_
3380: 65 72 72 6d 73 67 28 64 62 29 29 3b 0a 20 20 20  errmsg(db));.   
3390: 20 7d 0a 20 20 7d 0a 0a 20 20 69 66 28 20 2a 70   }.  }..  if( *p
33a0: 70 56 74 61 62 20 26 26 20 72 63 21 3d 53 51 4c  pVtab && rc!=SQL
33b0: 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 65 63  ITE_OK ){.    ec
33c0: 68 6f 44 65 73 74 72 75 63 74 6f 72 28 2a 70 70  hoDestructor(*pp
33d0: 56 74 61 62 29 3b 0a 20 20 20 20 2a 70 70 56 74  Vtab);.    *ppVt
33e0: 61 62 20 3d 20 30 3b 0a 20 20 7d 0a 0a 20 20 72  ab = 0;.  }..  r
33f0: 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 20  eturn rc;.}../* 
3400: 0a 2a 2a 20 45 63 68 6f 20 76 69 72 74 75 61 6c  .** Echo virtual
3410: 20 74 61 62 6c 65 20 6d 6f 64 75 6c 65 20 78 43   table module xC
3420: 6f 6e 6e 65 63 74 20 6d 65 74 68 6f 64 2e 0a 2a  onnect method..*
3430: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 65 63 68  /.static int ech
3440: 6f 43 6f 6e 6e 65 63 74 28 0a 20 20 73 71 6c 69  oConnect(.  sqli
3450: 74 65 33 20 2a 64 62 2c 0a 20 20 76 6f 69 64 20  te3 *db,.  void 
3460: 2a 70 41 75 78 2c 0a 20 20 69 6e 74 20 61 72 67  *pAux,.  int arg
3470: 63 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 63  c, const char *c
3480: 6f 6e 73 74 2a 61 72 67 76 2c 0a 20 20 73 71 6c  onst*argv,.  sql
3490: 69 74 65 33 5f 76 74 61 62 20 2a 2a 70 70 56 74  ite3_vtab **ppVt
34a0: 61 62 2c 0a 20 20 63 68 61 72 20 2a 2a 70 7a 45  ab,.  char **pzE
34b0: 72 72 0a 29 7b 0a 20 20 61 70 70 65 6e 64 54 6f  rr.){.  appendTo
34c0: 45 63 68 6f 4d 6f 64 75 6c 65 28 28 28 45 63 68  EchoModule(((Ech
34d0: 6f 4d 6f 64 75 6c 65 20 2a 29 70 41 75 78 29 2d  oModule *)pAux)-
34e0: 3e 69 6e 74 65 72 70 2c 20 22 78 43 6f 6e 6e 65  >interp, "xConne
34f0: 63 74 22 29 3b 0a 20 20 72 65 74 75 72 6e 20 65  ct");.  return e
3500: 63 68 6f 43 6f 6e 73 74 72 75 63 74 6f 72 28 64  choConstructor(d
3510: 62 2c 20 70 41 75 78 2c 20 61 72 67 63 2c 20 61  b, pAux, argc, a
3520: 72 67 76 2c 20 70 70 56 74 61 62 2c 20 70 7a 45  rgv, ppVtab, pzE
3530: 72 72 29 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 45  rr);.}../* .** E
3540: 63 68 6f 20 76 69 72 74 75 61 6c 20 74 61 62 6c  cho virtual tabl
3550: 65 20 6d 6f 64 75 6c 65 20 78 44 69 73 63 6f 6e  e module xDiscon
3560: 6e 65 63 74 20 6d 65 74 68 6f 64 2e 0a 2a 2f 0a  nect method..*/.
3570: 73 74 61 74 69 63 20 69 6e 74 20 65 63 68 6f 44  static int echoD
3580: 69 73 63 6f 6e 6e 65 63 74 28 73 71 6c 69 74 65  isconnect(sqlite
3590: 33 5f 76 74 61 62 20 2a 70 56 74 61 62 29 7b 0a  3_vtab *pVtab){.
35a0: 20 20 61 70 70 65 6e 64 54 6f 45 63 68 6f 4d 6f    appendToEchoMo
35b0: 64 75 6c 65 28 28 28 65 63 68 6f 5f 76 74 61 62  dule(((echo_vtab
35c0: 20 2a 29 70 56 74 61 62 29 2d 3e 69 6e 74 65 72   *)pVtab)->inter
35d0: 70 2c 20 22 78 44 69 73 63 6f 6e 6e 65 63 74 22  p, "xDisconnect"
35e0: 29 3b 0a 20 20 72 65 74 75 72 6e 20 65 63 68 6f  );.  return echo
35f0: 44 65 73 74 72 75 63 74 6f 72 28 70 56 74 61 62  Destructor(pVtab
3600: 29 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 45 63 68  );.}../* .** Ech
3610: 6f 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65 20  o virtual table 
3620: 6d 6f 64 75 6c 65 20 78 44 65 73 74 72 6f 79 20  module xDestroy 
3630: 6d 65 74 68 6f 64 2e 0a 2a 2f 0a 73 74 61 74 69  method..*/.stati
3640: 63 20 69 6e 74 20 65 63 68 6f 44 65 73 74 72 6f  c int echoDestro
3650: 79 28 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a  y(sqlite3_vtab *
3660: 70 56 74 61 62 29 7b 0a 20 20 69 6e 74 20 72 63  pVtab){.  int rc
3670: 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20   = SQLITE_OK;.  
3680: 65 63 68 6f 5f 76 74 61 62 20 2a 70 20 3d 20 28  echo_vtab *p = (
3690: 65 63 68 6f 5f 76 74 61 62 20 2a 29 70 56 74 61  echo_vtab *)pVta
36a0: 62 3b 0a 20 20 61 70 70 65 6e 64 54 6f 45 63 68  b;.  appendToEch
36b0: 6f 4d 6f 64 75 6c 65 28 28 28 65 63 68 6f 5f 76  oModule(((echo_v
36c0: 74 61 62 20 2a 29 70 56 74 61 62 29 2d 3e 69 6e  tab *)pVtab)->in
36d0: 74 65 72 70 2c 20 22 78 44 65 73 74 72 6f 79 22  terp, "xDestroy"
36e0: 29 3b 0a 0a 20 20 2f 2a 20 44 72 6f 70 20 74 68  );..  /* Drop th
36f0: 65 20 22 6c 6f 67 22 20 74 61 62 6c 65 2c 20 69  e "log" table, i
3700: 66 20 6f 6e 65 20 65 78 69 73 74 73 20 28 73 65  f one exists (se
3710: 65 20 65 63 68 6f 43 72 65 61 74 65 28 29 20 66  e echoCreate() f
3720: 6f 72 20 64 65 74 61 69 6c 73 29 20 2a 2f 0a 20  or details) */. 
3730: 20 69 66 28 20 70 20 26 26 20 70 2d 3e 7a 4c 6f   if( p && p->zLo
3740: 67 4e 61 6d 65 20 29 7b 0a 20 20 20 20 63 68 61  gName ){.    cha
3750: 72 20 2a 7a 53 71 6c 3b 0a 20 20 20 20 7a 53 71  r *zSql;.    zSq
3760: 6c 20 3d 20 73 71 6c 69 74 65 33 4d 50 72 69 6e  l = sqlite3MPrin
3770: 74 66 28 30 2c 20 22 44 52 4f 50 20 54 41 42 4c  tf(0, "DROP TABL
3780: 45 20 25 51 22 2c 20 70 2d 3e 7a 4c 6f 67 4e 61  E %Q", p->zLogNa
3790: 6d 65 29 3b 0a 20 20 20 20 72 63 20 3d 20 73 71  me);.    rc = sq
37a0: 6c 69 74 65 33 5f 65 78 65 63 28 70 2d 3e 64 62  lite3_exec(p->db
37b0: 2c 20 7a 53 71 6c 2c 20 30 2c 20 30 2c 20 30 29  , zSql, 0, 0, 0)
37c0: 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72  ;.    sqlite3_fr
37d0: 65 65 28 7a 53 71 6c 29 3b 0a 20 20 7d 0a 0a 20  ee(zSql);.  }.. 
37e0: 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
37f0: 4f 4b 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 65  OK ){.    rc = e
3800: 63 68 6f 44 65 73 74 72 75 63 74 6f 72 28 70 56  choDestructor(pV
3810: 74 61 62 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75  tab);.  }.  retu
3820: 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a  rn rc;.}../* .**
3830: 20 45 63 68 6f 20 76 69 72 74 75 61 6c 20 74 61   Echo virtual ta
3840: 62 6c 65 20 6d 6f 64 75 6c 65 20 78 4f 70 65 6e  ble module xOpen
3850: 20 6d 65 74 68 6f 64 2e 0a 2a 2f 0a 73 74 61 74   method..*/.stat
3860: 69 63 20 69 6e 74 20 65 63 68 6f 4f 70 65 6e 28  ic int echoOpen(
3870: 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 70 56  sqlite3_vtab *pV
3880: 54 61 62 2c 20 73 71 6c 69 74 65 33 5f 76 74 61  Tab, sqlite3_vta
3890: 62 5f 63 75 72 73 6f 72 20 2a 2a 70 70 43 75 72  b_cursor **ppCur
38a0: 73 6f 72 29 7b 0a 20 20 65 63 68 6f 5f 63 75 72  sor){.  echo_cur
38b0: 73 6f 72 20 2a 70 43 75 72 3b 0a 20 20 70 43 75  sor *pCur;.  pCu
38c0: 72 20 3d 20 73 71 6c 69 74 65 33 4d 61 6c 6c 6f  r = sqlite3Mallo
38d0: 63 5a 65 72 6f 28 73 69 7a 65 6f 66 28 65 63 68  cZero(sizeof(ech
38e0: 6f 5f 63 75 72 73 6f 72 29 29 3b 0a 20 20 2a 70  o_cursor));.  *p
38f0: 70 43 75 72 73 6f 72 20 3d 20 28 73 71 6c 69 74  pCursor = (sqlit
3900: 65 33 5f 76 74 61 62 5f 63 75 72 73 6f 72 20 2a  e3_vtab_cursor *
3910: 29 70 43 75 72 3b 0a 20 20 72 65 74 75 72 6e 20  )pCur;.  return 
3920: 28 70 43 75 72 20 3f 20 53 51 4c 49 54 45 5f 4f  (pCur ? SQLITE_O
3930: 4b 20 3a 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d  K : SQLITE_NOMEM
3940: 29 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 45 63 68  );.}../* .** Ech
3950: 6f 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65 20  o virtual table 
3960: 6d 6f 64 75 6c 65 20 78 43 6c 6f 73 65 20 6d 65  module xClose me
3970: 74 68 6f 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  thod..*/.static 
3980: 69 6e 74 20 65 63 68 6f 43 6c 6f 73 65 28 73 71  int echoClose(sq
3990: 6c 69 74 65 33 5f 76 74 61 62 5f 63 75 72 73 6f  lite3_vtab_curso
39a0: 72 20 2a 63 75 72 29 7b 0a 20 20 69 6e 74 20 72  r *cur){.  int r
39b0: 63 3b 0a 20 20 65 63 68 6f 5f 63 75 72 73 6f 72  c;.  echo_cursor
39c0: 20 2a 70 43 75 72 20 3d 20 28 65 63 68 6f 5f 63   *pCur = (echo_c
39d0: 75 72 73 6f 72 20 2a 29 63 75 72 3b 0a 20 20 73  ursor *)cur;.  s
39e0: 71 6c 69 74 65 33 5f 73 74 6d 74 20 2a 70 53 74  qlite3_stmt *pSt
39f0: 6d 74 20 3d 20 70 43 75 72 2d 3e 70 53 74 6d 74  mt = pCur->pStmt
3a00: 3b 0a 20 20 70 43 75 72 2d 3e 70 53 74 6d 74 20  ;.  pCur->pStmt 
3a10: 3d 20 30 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66  = 0;.  sqlite3_f
3a20: 72 65 65 28 70 43 75 72 29 3b 0a 20 20 72 63 20  ree(pCur);.  rc 
3a30: 3d 20 73 71 6c 69 74 65 33 5f 66 69 6e 61 6c 69  = sqlite3_finali
3a40: 7a 65 28 70 53 74 6d 74 29 3b 0a 20 20 72 65 74  ze(pStmt);.  ret
3a50: 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  urn rc;.}../*.**
3a60: 20 52 65 74 75 72 6e 20 6e 6f 6e 2d 7a 65 72 6f   Return non-zero
3a70: 20 69 66 20 74 68 65 20 63 75 72 73 6f 72 20 64   if the cursor d
3a80: 6f 65 73 20 6e 6f 74 20 63 75 72 72 65 6e 74 6c  oes not currentl
3a90: 79 20 70 6f 69 6e 74 20 74 6f 20 61 20 76 61 6c  y point to a val
3aa0: 69 64 20 72 65 63 6f 72 64 0a 2a 2a 20 28 69 2e  id record.** (i.
3ab0: 65 20 69 66 20 74 68 65 20 73 63 61 6e 20 68 61  e if the scan ha
3ac0: 73 20 66 69 6e 69 73 68 65 64 29 2c 20 6f 72 20  s finished), or 
3ad0: 7a 65 72 6f 20 6f 74 68 65 72 77 69 73 65 2e 0a  zero otherwise..
3ae0: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 65 63  */.static int ec
3af0: 68 6f 45 6f 66 28 73 71 6c 69 74 65 33 5f 76 74  hoEof(sqlite3_vt
3b00: 61 62 5f 63 75 72 73 6f 72 20 2a 63 75 72 29 7b  ab_cursor *cur){
3b10: 0a 20 20 72 65 74 75 72 6e 20 28 28 28 65 63 68  .  return (((ech
3b20: 6f 5f 63 75 72 73 6f 72 20 2a 29 63 75 72 29 2d  o_cursor *)cur)-
3b30: 3e 70 53 74 6d 74 20 3f 20 30 20 3a 20 31 29 3b  >pStmt ? 0 : 1);
3b40: 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 45 63 68 6f 20  .}../* .** Echo 
3b50: 76 69 72 74 75 61 6c 20 74 61 62 6c 65 20 6d 6f  virtual table mo
3b60: 64 75 6c 65 20 78 4e 65 78 74 20 6d 65 74 68 6f  dule xNext metho
3b70: 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  d..*/.static int
3b80: 20 65 63 68 6f 4e 65 78 74 28 73 71 6c 69 74 65   echoNext(sqlite
3b90: 33 5f 76 74 61 62 5f 63 75 72 73 6f 72 20 2a 63  3_vtab_cursor *c
3ba0: 75 72 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20  ur){.  int rc = 
3bb0: 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 65 63 68  SQLITE_OK;.  ech
3bc0: 6f 5f 63 75 72 73 6f 72 20 2a 70 43 75 72 20 3d  o_cursor *pCur =
3bd0: 20 28 65 63 68 6f 5f 63 75 72 73 6f 72 20 2a 29   (echo_cursor *)
3be0: 63 75 72 3b 0a 0a 20 20 69 66 28 20 70 43 75 72  cur;..  if( pCur
3bf0: 2d 3e 70 53 74 6d 74 20 29 7b 0a 20 20 20 20 72  ->pStmt ){.    r
3c00: 63 20 3d 20 73 71 6c 69 74 65 33 5f 73 74 65 70  c = sqlite3_step
3c10: 28 70 43 75 72 2d 3e 70 53 74 6d 74 29 3b 0a 20  (pCur->pStmt);. 
3c20: 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54     if( rc==SQLIT
3c30: 45 5f 52 4f 57 20 29 7b 0a 20 20 20 20 20 20 72  E_ROW ){.      r
3c40: 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20  c = SQLITE_OK;. 
3c50: 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20     }else{.      
3c60: 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 66 69 6e  rc = sqlite3_fin
3c70: 61 6c 69 7a 65 28 70 43 75 72 2d 3e 70 53 74 6d  alize(pCur->pStm
3c80: 74 29 3b 0a 20 20 20 20 20 20 70 43 75 72 2d 3e  t);.      pCur->
3c90: 70 53 74 6d 74 20 3d 20 30 3b 0a 20 20 20 20 7d  pStmt = 0;.    }
3ca0: 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 72  .  }..  return r
3cb0: 63 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 45 63 68  c;.}../* .** Ech
3cc0: 6f 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65 20  o virtual table 
3cd0: 6d 6f 64 75 6c 65 20 78 43 6f 6c 75 6d 6e 20 6d  module xColumn m
3ce0: 65 74 68 6f 64 2e 0a 2a 2f 0a 73 74 61 74 69 63  ethod..*/.static
3cf0: 20 69 6e 74 20 65 63 68 6f 43 6f 6c 75 6d 6e 28   int echoColumn(
3d00: 73 71 6c 69 74 65 33 5f 76 74 61 62 5f 63 75 72  sqlite3_vtab_cur
3d10: 73 6f 72 20 2a 63 75 72 2c 20 73 71 6c 69 74 65  sor *cur, sqlite
3d20: 33 5f 63 6f 6e 74 65 78 74 20 2a 63 74 78 2c 20  3_context *ctx, 
3d30: 69 6e 74 20 69 29 7b 0a 20 20 69 6e 74 20 69 43  int i){.  int iC
3d40: 6f 6c 20 3d 20 69 20 2b 20 31 3b 0a 20 20 73 71  ol = i + 1;.  sq
3d50: 6c 69 74 65 33 5f 73 74 6d 74 20 2a 70 53 74 6d  lite3_stmt *pStm
3d60: 74 20 3d 20 28 28 65 63 68 6f 5f 63 75 72 73 6f  t = ((echo_curso
3d70: 72 20 2a 29 63 75 72 29 2d 3e 70 53 74 6d 74 3b  r *)cur)->pStmt;
3d80: 0a 20 20 69 66 28 20 21 70 53 74 6d 74 20 29 7b  .  if( !pStmt ){
3d90: 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 72 65 73  .    sqlite3_res
3da0: 75 6c 74 5f 6e 75 6c 6c 28 63 74 78 29 3b 0a 20  ult_null(ctx);. 
3db0: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 61 73 73 65   }else{.    asse
3dc0: 72 74 28 20 73 71 6c 69 74 65 33 5f 64 61 74 61  rt( sqlite3_data
3dd0: 5f 63 6f 75 6e 74 28 70 53 74 6d 74 29 3e 69 43  _count(pStmt)>iC
3de0: 6f 6c 20 29 3b 0a 20 20 20 20 73 71 6c 69 74 65  ol );.    sqlite
3df0: 33 5f 72 65 73 75 6c 74 5f 76 61 6c 75 65 28 63  3_result_value(c
3e00: 74 78 2c 20 73 71 6c 69 74 65 33 5f 63 6f 6c 75  tx, sqlite3_colu
3e10: 6d 6e 5f 76 61 6c 75 65 28 70 53 74 6d 74 2c 20  mn_value(pStmt, 
3e20: 69 43 6f 6c 29 29 3b 0a 20 20 7d 0a 20 20 72 65  iCol));.  }.  re
3e30: 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a  turn SQLITE_OK;.
3e40: 7d 0a 0a 2f 2a 20 0a 2a 2a 20 45 63 68 6f 20 76  }../* .** Echo v
3e50: 69 72 74 75 61 6c 20 74 61 62 6c 65 20 6d 6f 64  irtual table mod
3e60: 75 6c 65 20 78 52 6f 77 69 64 20 6d 65 74 68 6f  ule xRowid metho
3e70: 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  d..*/.static int
3e80: 20 65 63 68 6f 52 6f 77 69 64 28 73 71 6c 69 74   echoRowid(sqlit
3e90: 65 33 5f 76 74 61 62 5f 63 75 72 73 6f 72 20 2a  e3_vtab_cursor *
3ea0: 63 75 72 2c 20 73 71 6c 69 74 65 5f 69 6e 74 36  cur, sqlite_int6
3eb0: 34 20 2a 70 52 6f 77 69 64 29 7b 0a 20 20 73 71  4 *pRowid){.  sq
3ec0: 6c 69 74 65 33 5f 73 74 6d 74 20 2a 70 53 74 6d  lite3_stmt *pStm
3ed0: 74 20 3d 20 28 28 65 63 68 6f 5f 63 75 72 73 6f  t = ((echo_curso
3ee0: 72 20 2a 29 63 75 72 29 2d 3e 70 53 74 6d 74 3b  r *)cur)->pStmt;
3ef0: 0a 20 20 2a 70 52 6f 77 69 64 20 3d 20 73 71 6c  .  *pRowid = sql
3f00: 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 69 6e 74 36  ite3_column_int6
3f10: 34 28 70 53 74 6d 74 2c 20 30 29 3b 0a 20 20 72  4(pStmt, 0);.  r
3f20: 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b  eturn SQLITE_OK;
3f30: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 6f 6d 70 75 74  .}../*.** Comput
3f40: 65 20 61 20 73 69 6d 70 6c 65 20 68 61 73 68 20  e a simple hash 
3f50: 6f 66 20 74 68 65 20 6e 75 6c 6c 20 74 65 72 6d  of the null term
3f60: 69 6e 61 74 65 64 20 73 74 72 69 6e 67 20 7a 53  inated string zS
3f70: 74 72 69 6e 67 2e 0a 2a 2a 0a 2a 2a 20 54 68 69  tring..**.** Thi
3f80: 73 20 6d 6f 64 75 6c 65 20 75 73 65 73 20 6f 6e  s module uses on
3f90: 6c 79 20 73 71 6c 69 74 65 33 5f 69 6e 64 65 78  ly sqlite3_index
3fa0: 5f 69 6e 66 6f 2e 69 64 78 53 74 72 2c 20 6e 6f  _info.idxStr, no
3fb0: 74 20 0a 2a 2a 20 73 71 6c 69 74 65 33 5f 69 6e  t .** sqlite3_in
3fc0: 64 65 78 5f 69 6e 66 6f 2e 69 64 78 4e 75 6d 2e  dex_info.idxNum.
3fd0: 20 53 6f 20 74 6f 20 74 65 73 74 20 69 64 78 4e   So to test idxN
3fe0: 75 6d 2c 20 77 68 65 6e 20 69 64 78 53 74 72 20  um, when idxStr 
3ff0: 69 73 20 73 65 74 0a 2a 2a 20 69 6e 20 65 63 68  is set.** in ech
4000: 6f 42 65 73 74 49 6e 64 65 78 28 29 2c 20 69 64  oBestIndex(), id
4010: 78 4e 75 6d 20 69 73 20 73 65 74 20 74 6f 20 74  xNum is set to t
4020: 68 65 20 63 6f 72 72 65 73 70 6f 6e 64 69 6e 67  he corresponding
4030: 20 68 61 73 68 20 76 61 6c 75 65 2e 0a 2a 2a 20   hash value..** 
4040: 49 6e 20 65 63 68 6f 46 69 6c 74 65 72 28 29 2c  In echoFilter(),
4050: 20 63 6f 64 65 20 61 73 73 65 72 74 28 29 73 20   code assert()s 
4060: 74 68 61 74 20 74 68 65 20 73 75 70 70 6c 69 65  that the supplie
4070: 64 20 69 64 78 4e 75 6d 20 76 61 6c 75 65 20 69  d idxNum value i
4080: 73 0a 2a 2a 20 69 6e 64 65 65 64 20 74 68 65 20  s.** indeed the 
4090: 68 61 73 68 20 6f 66 20 74 68 65 20 73 75 70 70  hash of the supp
40a0: 6c 69 65 64 20 69 64 78 53 74 72 2e 0a 2a 2f 0a  lied idxStr..*/.
40b0: 73 74 61 74 69 63 20 69 6e 74 20 68 61 73 68 53  static int hashS
40c0: 74 72 69 6e 67 28 63 6f 6e 73 74 20 63 68 61 72  tring(const char
40d0: 20 2a 7a 53 74 72 69 6e 67 29 7b 0a 20 20 69 6e   *zString){.  in
40e0: 74 20 76 61 6c 20 3d 20 30 3b 0a 20 20 69 6e 74  t val = 0;.  int
40f0: 20 69 69 3b 0a 20 20 66 6f 72 28 69 69 3d 30 3b   ii;.  for(ii=0;
4100: 20 7a 53 74 72 69 6e 67 5b 69 69 5d 3b 20 69 69   zString[ii]; ii
4110: 2b 2b 29 7b 0a 20 20 20 20 76 61 6c 20 3d 20 28  ++){.    val = (
4120: 76 61 6c 20 3c 3c 20 33 29 20 2b 20 28 69 6e 74  val << 3) + (int
4130: 29 7a 53 74 72 69 6e 67 5b 69 69 5d 3b 0a 20 20  )zString[ii];.  
4140: 7d 0a 20 20 72 65 74 75 72 6e 20 76 61 6c 3b 0a  }.  return val;.
4150: 7d 0a 0a 2f 2a 20 0a 2a 2a 20 45 63 68 6f 20 76  }../* .** Echo v
4160: 69 72 74 75 61 6c 20 74 61 62 6c 65 20 6d 6f 64  irtual table mod
4170: 75 6c 65 20 78 46 69 6c 74 65 72 20 6d 65 74 68  ule xFilter meth
4180: 6f 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  od..*/.static in
4190: 74 20 65 63 68 6f 46 69 6c 74 65 72 28 0a 20 20  t echoFilter(.  
41a0: 73 71 6c 69 74 65 33 5f 76 74 61 62 5f 63 75 72  sqlite3_vtab_cur
41b0: 73 6f 72 20 2a 70 56 74 61 62 43 75 72 73 6f 72  sor *pVtabCursor
41c0: 2c 20 0a 20 20 69 6e 74 20 69 64 78 4e 75 6d 2c  , .  int idxNum,
41d0: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 69 64 78   const char *idx
41e0: 53 74 72 2c 0a 20 20 69 6e 74 20 61 72 67 63 2c  Str,.  int argc,
41f0: 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 20 2a   sqlite3_value *
4200: 2a 61 72 67 76 0a 29 7b 0a 20 20 69 6e 74 20 72  *argv.){.  int r
4210: 63 3b 0a 20 20 69 6e 74 20 69 3b 0a 0a 20 20 65  c;.  int i;..  e
4220: 63 68 6f 5f 63 75 72 73 6f 72 20 2a 70 43 75 72  cho_cursor *pCur
4230: 20 3d 20 28 65 63 68 6f 5f 63 75 72 73 6f 72 20   = (echo_cursor 
4240: 2a 29 70 56 74 61 62 43 75 72 73 6f 72 3b 0a 20  *)pVtabCursor;. 
4250: 20 65 63 68 6f 5f 76 74 61 62 20 2a 70 56 74 61   echo_vtab *pVta
4260: 62 20 3d 20 28 65 63 68 6f 5f 76 74 61 62 20 2a  b = (echo_vtab *
4270: 29 70 56 74 61 62 43 75 72 73 6f 72 2d 3e 70 56  )pVtabCursor->pV
4280: 74 61 62 3b 0a 20 20 73 71 6c 69 74 65 33 20 2a  tab;.  sqlite3 *
4290: 64 62 20 3d 20 70 56 74 61 62 2d 3e 64 62 3b 0a  db = pVtab->db;.
42a0: 0a 20 20 2f 2a 20 43 68 65 63 6b 20 74 68 61 74  .  /* Check that
42b0: 20 69 64 78 4e 75 6d 20 6d 61 74 63 68 65 73 20   idxNum matches 
42c0: 69 64 78 53 74 72 20 2a 2f 0a 20 20 61 73 73 65  idxStr */.  asse
42d0: 72 74 28 20 69 64 78 4e 75 6d 3d 3d 68 61 73 68  rt( idxNum==hash
42e0: 53 74 72 69 6e 67 28 69 64 78 53 74 72 29 20 29  String(idxStr) )
42f0: 3b 0a 0a 20 20 2f 2a 20 4c 6f 67 20 61 72 67 75  ;..  /* Log argu
4300: 6d 65 6e 74 73 20 74 6f 20 74 68 65 20 3a 3a 65  ments to the ::e
4310: 63 68 6f 5f 6d 6f 64 75 6c 65 20 54 63 6c 20 76  cho_module Tcl v
4320: 61 72 69 61 62 6c 65 20 2a 2f 0a 20 20 61 70 70  ariable */.  app
4330: 65 6e 64 54 6f 45 63 68 6f 4d 6f 64 75 6c 65 28  endToEchoModule(
4340: 70 56 74 61 62 2d 3e 69 6e 74 65 72 70 2c 20 22  pVtab->interp, "
4350: 78 46 69 6c 74 65 72 22 29 3b 0a 20 20 61 70 70  xFilter");.  app
4360: 65 6e 64 54 6f 45 63 68 6f 4d 6f 64 75 6c 65 28  endToEchoModule(
4370: 70 56 74 61 62 2d 3e 69 6e 74 65 72 70 2c 20 69  pVtab->interp, i
4380: 64 78 53 74 72 29 3b 0a 20 20 66 6f 72 28 69 3d  dxStr);.  for(i=
4390: 30 3b 20 69 3c 61 72 67 63 3b 20 69 2b 2b 29 7b  0; i<argc; i++){
43a0: 0a 20 20 20 20 61 70 70 65 6e 64 54 6f 45 63 68  .    appendToEch
43b0: 6f 4d 6f 64 75 6c 65 28 70 56 74 61 62 2d 3e 69  oModule(pVtab->i
43c0: 6e 74 65 72 70 2c 20 28 63 6f 6e 73 74 20 63 68  nterp, (const ch
43d0: 61 72 2a 29 73 71 6c 69 74 65 33 5f 76 61 6c 75  ar*)sqlite3_valu
43e0: 65 5f 74 65 78 74 28 61 72 67 76 5b 69 5d 29 29  e_text(argv[i]))
43f0: 3b 0a 20 20 7d 0a 0a 20 20 73 71 6c 69 74 65 33  ;.  }..  sqlite3
4400: 5f 66 69 6e 61 6c 69 7a 65 28 70 43 75 72 2d 3e  _finalize(pCur->
4410: 70 53 74 6d 74 29 3b 0a 20 20 70 43 75 72 2d 3e  pStmt);.  pCur->
4420: 70 53 74 6d 74 20 3d 20 30 3b 0a 0a 20 20 2f 2a  pStmt = 0;..  /*
4430: 20 50 72 65 70 61 72 65 20 74 68 65 20 53 51 4c   Prepare the SQL
4440: 20 73 74 61 74 65 6d 65 6e 74 20 63 72 65 61 74   statement creat
4450: 65 64 20 62 79 20 65 63 68 6f 42 65 73 74 49 6e  ed by echoBestIn
4460: 64 65 78 20 61 6e 64 20 62 69 6e 64 20 74 68 65  dex and bind the
4470: 0a 20 20 2a 2a 20 72 75 6e 74 69 6d 65 20 70 61  .  ** runtime pa
4480: 72 61 6d 65 74 65 72 73 20 70 61 73 73 65 64 20  rameters passed 
4490: 74 6f 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e  to this function
44a0: 20 74 6f 20 69 74 2e 0a 20 20 2a 2f 0a 20 20 72   to it..  */.  r
44b0: 63 20 3d 20 73 71 6c 69 74 65 33 5f 70 72 65 70  c = sqlite3_prep
44c0: 61 72 65 28 64 62 2c 20 69 64 78 53 74 72 2c 20  are(db, idxStr, 
44d0: 2d 31 2c 20 26 70 43 75 72 2d 3e 70 53 74 6d 74  -1, &pCur->pStmt
44e0: 2c 20 30 29 3b 0a 20 20 61 73 73 65 72 74 28 20  , 0);.  assert( 
44f0: 70 43 75 72 2d 3e 70 53 74 6d 74 20 7c 7c 20 72  pCur->pStmt || r
4500: 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 3b 0a  c!=SQLITE_OK );.
4510: 20 20 66 6f 72 28 69 3d 30 3b 20 72 63 3d 3d 53    for(i=0; rc==S
4520: 51 4c 49 54 45 5f 4f 4b 20 26 26 20 69 3c 61 72  QLITE_OK && i<ar
4530: 67 63 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 73 71  gc; i++){.    sq
4540: 6c 69 74 65 33 5f 62 69 6e 64 5f 76 61 6c 75 65  lite3_bind_value
4550: 28 70 43 75 72 2d 3e 70 53 74 6d 74 2c 20 69 2b  (pCur->pStmt, i+
4560: 31 2c 20 61 72 67 76 5b 69 5d 29 3b 0a 20 20 7d  1, argv[i]);.  }
4570: 0a 0a 20 20 2f 2a 20 49 66 20 65 76 65 72 79 74  ..  /* If everyt
4580: 68 69 6e 67 20 77 61 73 20 73 75 63 63 65 73 73  hing was success
4590: 66 75 6c 2c 20 61 64 76 61 6e 63 65 20 74 6f 20  ful, advance to 
45a0: 74 68 65 20 66 69 72 73 74 20 72 6f 77 20 6f 66  the first row of
45b0: 20 74 68 65 20 73 63 61 6e 20 2a 2f 0a 20 20 69   the scan */.  i
45c0: 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc==SQLITE_OK
45d0: 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 65 63 68   ){.    rc = ech
45e0: 6f 4e 65 78 74 28 70 56 74 61 62 43 75 72 73 6f  oNext(pVtabCurso
45f0: 72 29 3b 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72  r);.  }..  retur
4600: 6e 20 72 63 3b 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20  n rc;.}.../*.** 
4610: 41 20 68 65 6c 70 65 72 20 66 75 6e 63 74 69 6f  A helper functio
4620: 6e 20 75 73 65 64 20 62 79 20 65 63 68 6f 55 70  n used by echoUp
4630: 64 61 74 65 28 29 20 61 6e 64 20 65 63 68 6f 42  date() and echoB
4640: 65 73 74 49 6e 64 65 78 28 29 20 66 6f 72 0a 2a  estIndex() for.*
4650: 2a 20 6d 61 6e 69 70 75 6c 61 74 69 6e 67 20 73  * manipulating s
4660: 74 72 69 6e 67 73 20 69 6e 20 63 6f 6e 63 65 72  trings in concer
4670: 74 20 77 69 74 68 20 74 68 65 20 73 71 6c 69 74  t with the sqlit
4680: 65 33 5f 6d 70 72 69 6e 74 66 28 29 20 66 75 6e  e3_mprintf() fun
4690: 63 74 69 6f 6e 2e 0a 2a 2a 0a 2a 2a 20 50 61 72  ction..**.** Par
46a0: 61 6d 65 74 65 72 20 70 7a 53 74 72 20 70 6f 69  ameter pzStr poi
46b0: 6e 74 73 20 74 6f 20 61 20 70 6f 69 6e 74 65 72  nts to a pointer
46c0: 20 74 6f 20 61 20 73 74 72 69 6e 67 20 61 6c 6c   to a string all
46d0: 6f 63 61 74 65 64 20 77 69 74 68 0a 2a 2a 20 73  ocated with.** s
46e0: 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 2e 20  qlite3_mprintf. 
46f0: 54 68 65 20 73 65 63 6f 6e 64 20 70 61 72 61 6d  The second param
4700: 65 74 65 72 2c 20 7a 41 70 70 65 6e 64 2c 20 70  eter, zAppend, p
4710: 6f 69 6e 74 73 20 74 6f 20 61 6e 6f 74 68 65 72  oints to another
4720: 0a 2a 2a 20 73 74 72 69 6e 67 2e 20 54 68 65 20  .** string. The 
4730: 74 77 6f 20 73 74 72 69 6e 67 73 20 61 72 65 20  two strings are 
4740: 63 6f 6e 63 61 74 65 6e 61 74 65 64 20 74 6f 67  concatenated tog
4750: 65 74 68 65 72 20 61 6e 64 20 2a 70 7a 53 74 72  ether and *pzStr
4760: 0a 2a 2a 20 73 65 74 20 74 6f 20 70 6f 69 6e 74  .** set to point
4770: 20 61 74 20 74 68 65 20 72 65 73 75 6c 74 2e 20   at the result. 
4780: 54 68 65 20 69 6e 69 74 69 61 6c 20 62 75 66 66  The initial buff
4790: 65 72 20 70 6f 69 6e 74 65 64 20 74 6f 20 62 79  er pointed to by
47a0: 20 2a 70 7a 53 74 72 0a 2a 2a 20 69 73 20 64 65   *pzStr.** is de
47b0: 61 6c 6c 6f 63 61 74 65 64 20 76 69 61 20 73 71  allocated via sq
47c0: 6c 69 74 65 33 5f 66 72 65 65 28 29 2e 0a 2a 2a  lite3_free()..**
47d0: 0a 2a 2a 20 49 66 20 74 68 65 20 74 68 69 72 64  .** If the third
47e0: 20 61 72 67 75 6d 65 6e 74 2c 20 64 6f 46 72 65   argument, doFre
47f0: 65 2c 20 69 73 20 74 72 75 65 2c 20 74 68 65 6e  e, is true, then
4800: 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 29 20   sqlite3_free() 
4810: 69 73 0a 2a 2a 20 61 6c 73 6f 20 63 61 6c 6c 65  is.** also calle
4820: 64 20 74 6f 20 66 72 65 65 20 74 68 65 20 62 75  d to free the bu
4830: 66 66 65 72 20 70 6f 69 6e 74 65 64 20 74 6f 20  ffer pointed to 
4840: 62 79 20 7a 41 70 70 65 6e 64 2e 0a 2a 2f 0a 73  by zAppend..*/.s
4850: 74 61 74 69 63 20 76 6f 69 64 20 73 74 72 69 6e  tatic void strin
4860: 67 5f 63 6f 6e 63 61 74 28 63 68 61 72 20 2a 2a  g_concat(char **
4870: 70 7a 53 74 72 2c 20 63 68 61 72 20 2a 7a 41 70  pzStr, char *zAp
4880: 70 65 6e 64 2c 20 69 6e 74 20 64 6f 46 72 65 65  pend, int doFree
4890: 2c 20 69 6e 74 20 2a 70 52 63 29 7b 0a 20 20 63  , int *pRc){.  c
48a0: 68 61 72 20 2a 7a 49 6e 20 3d 20 2a 70 7a 53 74  har *zIn = *pzSt
48b0: 72 3b 0a 20 20 69 66 28 20 21 7a 41 70 70 65 6e  r;.  if( !zAppen
48c0: 64 20 26 26 20 64 6f 46 72 65 65 20 26 26 20 2a  d && doFree && *
48d0: 70 52 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29  pRc==SQLITE_OK )
48e0: 7b 0a 20 20 20 20 2a 70 52 63 20 3d 20 53 51 4c  {.    *pRc = SQL
48f0: 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 7d 0a 20  ITE_NOMEM;.  }. 
4900: 20 69 66 28 20 2a 70 52 63 21 3d 53 51 4c 49 54   if( *pRc!=SQLIT
4910: 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 73 71 6c 69  E_OK ){.    sqli
4920: 74 65 33 5f 66 72 65 65 28 7a 49 6e 29 3b 0a 20  te3_free(zIn);. 
4930: 20 20 20 7a 49 6e 20 3d 20 30 3b 0a 20 20 7d 65     zIn = 0;.  }e
4940: 6c 73 65 7b 0a 20 20 20 20 69 66 28 20 7a 49 6e  lse{.    if( zIn
4950: 20 29 7b 0a 20 20 20 20 20 20 63 68 61 72 20 2a   ){.      char *
4960: 7a 54 65 6d 70 20 3d 20 7a 49 6e 3b 0a 20 20 20  zTemp = zIn;.   
4970: 20 20 20 7a 49 6e 20 3d 20 73 71 6c 69 74 65 33     zIn = sqlite3
4980: 5f 6d 70 72 69 6e 74 66 28 22 25 73 25 73 22 2c  _mprintf("%s%s",
4990: 20 7a 49 6e 2c 20 7a 41 70 70 65 6e 64 29 3b 0a   zIn, zAppend);.
49a0: 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72        sqlite3_fr
49b0: 65 65 28 7a 54 65 6d 70 29 3b 0a 20 20 20 20 7d  ee(zTemp);.    }
49c0: 65 6c 73 65 7b 0a 20 20 20 20 20 20 7a 49 6e 20  else{.      zIn 
49d0: 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74  = sqlite3_mprint
49e0: 66 28 22 25 73 22 2c 20 7a 41 70 70 65 6e 64 29  f("%s", zAppend)
49f0: 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 28 20  ;.    }.    if( 
4a00: 21 7a 49 6e 20 29 7b 0a 20 20 20 20 20 20 2a 70  !zIn ){.      *p
4a10: 52 63 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45  Rc = SQLITE_NOME
4a20: 4d 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 2a  M;.    }.  }.  *
4a30: 70 7a 53 74 72 20 3d 20 7a 49 6e 3b 0a 20 20 69  pzStr = zIn;.  i
4a40: 66 28 20 64 6f 46 72 65 65 20 29 7b 0a 20 20 20  f( doFree ){.   
4a50: 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 7a 41   sqlite3_free(zA
4a60: 70 70 65 6e 64 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f  ppend);.  }.}../
4a70: 2a 0a 2a 2a 20 54 68 65 20 65 63 68 6f 20 6d 6f  *.** The echo mo
4a80: 64 75 6c 65 20 69 6d 70 6c 65 6d 65 6e 74 73 20  dule implements 
4a90: 74 68 65 20 73 75 62 73 65 74 20 6f 66 20 71 75  the subset of qu
4aa0: 65 72 79 20 63 6f 6e 73 74 72 61 69 6e 74 73 20  ery constraints 
4ab0: 61 6e 64 20 73 6f 72 74 0a 2a 2a 20 6f 72 64 65  and sort.** orde
4ac0: 72 73 20 74 68 61 74 20 6d 61 79 20 74 61 6b 65  rs that may take
4ad0: 20 61 64 76 61 6e 74 61 67 65 20 6f 66 20 53 51   advantage of SQ
4ae0: 4c 69 74 65 20 69 6e 64 69 63 65 73 20 6f 6e 20  Lite indices on 
4af0: 74 68 65 20 75 6e 64 65 72 6c 79 69 6e 67 0a 2a  the underlying.*
4b00: 2a 20 72 65 61 6c 20 74 61 62 6c 65 2e 20 46 6f  * real table. Fo
4b10: 72 20 65 78 61 6d 70 6c 65 2c 20 69 66 20 74 68  r example, if th
4b20: 65 20 72 65 61 6c 20 74 61 62 6c 65 20 69 73 20  e real table is 
4b30: 64 65 63 6c 61 72 65 64 20 61 73 3a 0a 2a 2a 0a  declared as:.**.
4b40: 2a 2a 20 20 20 20 20 43 52 45 41 54 45 20 54 41  **     CREATE TA
4b50: 42 4c 45 20 72 65 61 6c 28 61 2c 20 62 2c 20 63  BLE real(a, b, c
4b60: 29 3b 0a 2a 2a 20 20 20 20 20 43 52 45 41 54 45  );.**     CREATE
4b70: 20 49 4e 44 45 58 20 72 65 61 6c 5f 69 6e 64 65   INDEX real_inde
4b80: 78 20 4f 4e 20 72 65 61 6c 28 62 29 3b 0a 2a 2a  x ON real(b);.**
4b90: 0a 2a 2a 20 74 68 65 6e 20 74 68 65 20 65 63 68  .** then the ech
4ba0: 6f 20 6d 6f 64 75 6c 65 20 68 61 6e 64 6c 65 73  o module handles
4bb0: 20 57 48 45 52 45 20 6f 72 20 4f 52 44 45 52 20   WHERE or ORDER 
4bc0: 42 59 20 63 6c 61 75 73 65 73 20 74 68 61 74 20  BY clauses that 
4bd0: 72 65 66 65 72 0a 2a 2a 20 74 6f 20 74 68 65 20  refer.** to the 
4be0: 63 6f 6c 75 6d 6e 20 22 62 22 2c 20 62 75 74 20  column "b", but 
4bf0: 6e 6f 74 20 22 61 22 20 6f 72 20 22 63 22 2e 20  not "a" or "c". 
4c00: 49 66 20 61 20 6d 75 6c 74 69 2d 63 6f 6c 75 6d  If a multi-colum
4c10: 6e 20 69 6e 64 65 78 20 69 73 0a 2a 2a 20 70 72  n index is.** pr
4c20: 65 73 65 6e 74 2c 20 6f 6e 6c 79 20 69 74 73 20  esent, only its 
4c30: 6c 65 66 74 20 6d 6f 73 74 20 63 6f 6c 75 6d 6e  left most column
4c40: 20 69 73 20 63 6f 6e 73 69 64 65 72 65 64 2e 20   is considered. 
4c50: 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20 78 42 65 73  .**.** This xBes
4c60: 74 49 6e 64 65 78 20 6d 65 74 68 6f 64 20 65 6e  tIndex method en
4c70: 63 6f 64 65 73 20 74 68 65 20 70 72 6f 70 6f 73  codes the propos
4c80: 65 64 20 73 65 61 72 63 68 20 73 74 72 61 74 65  ed search strate
4c90: 67 79 20 61 73 0a 2a 2a 20 61 6e 20 53 51 4c 20  gy as.** an SQL 
4ca0: 71 75 65 72 79 20 6f 6e 20 74 68 65 20 72 65 61  query on the rea
4cb0: 6c 20 74 61 62 6c 65 20 75 6e 64 65 72 6c 79 69  l table underlyi
4cc0: 6e 67 20 74 68 65 20 76 69 72 74 75 61 6c 20 65  ng the virtual e
4cd0: 63 68 6f 20 6d 6f 64 75 6c 65 20 0a 2a 2a 20 74  cho module .** t
4ce0: 61 62 6c 65 20 61 6e 64 20 73 74 6f 72 65 73 20  able and stores 
4cf0: 74 68 65 20 71 75 65 72 79 20 69 6e 20 73 71 6c  the query in sql
4d00: 69 74 65 33 5f 69 6e 64 65 78 5f 69 6e 66 6f 2e  ite3_index_info.
4d10: 69 64 78 53 74 72 2e 20 54 68 65 20 53 51 4c 0a  idxStr. The SQL.
4d20: 2a 2a 20 73 74 61 74 65 6d 65 6e 74 20 69 73 20  ** statement is 
4d30: 6f 66 20 74 68 65 20 66 6f 72 6d 3a 0a 2a 2a 0a  of the form:.**.
4d40: 2a 2a 20 20 20 53 45 4c 45 43 54 20 72 6f 77 69  **   SELECT rowi
4d50: 64 2c 20 2a 20 46 52 4f 4d 20 3c 72 65 61 6c 2d  d, * FROM <real-
4d60: 74 61 62 6c 65 3e 20 3f 3c 77 68 65 72 65 2d 63  table> ?<where-c
4d70: 6c 61 75 73 65 3e 3f 20 3f 3c 6f 72 64 65 72 2d  lause>? ?<order-
4d80: 62 79 2d 63 6c 61 75 73 65 3e 3f 0a 2a 2a 0a 2a  by-clause>?.**.*
4d90: 2a 20 77 68 65 72 65 20 74 68 65 20 3c 77 68 65  * where the <whe
4da0: 72 65 2d 63 6c 61 75 73 65 3e 20 61 6e 64 20 3c  re-clause> and <
4db0: 6f 72 64 65 72 2d 62 79 2d 63 6c 61 75 73 65 3e  order-by-clause>
4dc0: 20 61 72 65 20 64 65 74 65 72 6d 69 6e 65 64 0a   are determined.
4dd0: 2a 2a 20 62 79 20 74 68 65 20 63 6f 6e 74 65 6e  ** by the conten
4de0: 74 73 20 6f 66 20 74 68 65 20 73 74 72 75 63 74  ts of the struct
4df0: 75 72 65 20 70 6f 69 6e 74 65 64 20 74 6f 20 62  ure pointed to b
4e00: 79 20 74 68 65 20 70 49 64 78 49 6e 66 6f 20 61  y the pIdxInfo a
4e10: 72 67 75 6d 65 6e 74 2e 0a 2a 2f 0a 73 74 61 74  rgument..*/.stat
4e20: 69 63 20 69 6e 74 20 65 63 68 6f 42 65 73 74 49  ic int echoBestI
4e30: 6e 64 65 78 28 73 71 6c 69 74 65 33 5f 76 74 61  ndex(sqlite3_vta
4e40: 62 20 2a 74 61 62 2c 20 73 71 6c 69 74 65 33 5f  b *tab, sqlite3_
4e50: 69 6e 64 65 78 5f 69 6e 66 6f 20 2a 70 49 64 78  index_info *pIdx
4e60: 49 6e 66 6f 29 7b 0a 20 20 69 6e 74 20 69 69 3b  Info){.  int ii;
4e70: 0a 20 20 63 68 61 72 20 2a 7a 51 75 65 72 79 20  .  char *zQuery 
4e80: 3d 20 30 3b 0a 20 20 63 68 61 72 20 2a 7a 4e 65  = 0;.  char *zNe
4e90: 77 3b 0a 20 20 69 6e 74 20 6e 41 72 67 20 3d 20  w;.  int nArg = 
4ea0: 30 3b 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20  0;.  const char 
4eb0: 2a 7a 53 65 70 20 3d 20 22 57 48 45 52 45 22 3b  *zSep = "WHERE";
4ec0: 0a 20 20 65 63 68 6f 5f 76 74 61 62 20 2a 70 56  .  echo_vtab *pV
4ed0: 74 61 62 20 3d 20 28 65 63 68 6f 5f 76 74 61 62  tab = (echo_vtab
4ee0: 20 2a 29 74 61 62 3b 0a 20 20 73 71 6c 69 74 65   *)tab;.  sqlite
4ef0: 33 5f 73 74 6d 74 20 2a 70 53 74 6d 74 20 3d 20  3_stmt *pStmt = 
4f00: 30 3b 0a 20 20 54 63 6c 5f 49 6e 74 65 72 70 20  0;.  Tcl_Interp 
4f10: 2a 69 6e 74 65 72 70 20 3d 20 70 56 74 61 62 2d  *interp = pVtab-
4f20: 3e 69 6e 74 65 72 70 3b 0a 0a 20 20 69 6e 74 20  >interp;..  int 
4f30: 6e 52 6f 77 3b 0a 20 20 69 6e 74 20 75 73 65 49  nRow;.  int useI
4f40: 64 78 20 3d 20 30 3b 0a 20 20 69 6e 74 20 72 63  dx = 0;.  int rc
4f50: 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20   = SQLITE_OK;.  
4f60: 69 6e 74 20 75 73 65 43 6f 73 74 20 3d 20 30 3b  int useCost = 0;
4f70: 0a 20 20 64 6f 75 62 6c 65 20 63 6f 73 74 3b 0a  .  double cost;.
4f80: 0a 20 20 2f 2a 20 44 65 74 65 72 6d 69 6e 65 20  .  /* Determine 
4f90: 74 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 72 6f  the number of ro
4fa0: 77 73 20 69 6e 20 74 68 65 20 74 61 62 6c 65 20  ws in the table 
4fb0: 61 6e 64 20 73 74 6f 72 65 20 74 68 69 73 20 76  and store this v
4fc0: 61 6c 75 65 20 69 6e 20 6c 6f 63 61 6c 0a 20 20  alue in local.  
4fd0: 2a 2a 20 76 61 72 69 61 62 6c 65 20 6e 52 6f 77  ** variable nRow
4fe0: 2e 20 54 68 65 20 27 65 73 74 69 6d 61 74 65 64  . The 'estimated
4ff0: 2d 63 6f 73 74 27 20 6f 66 20 74 68 65 20 73 63  -cost' of the sc
5000: 61 6e 20 77 69 6c 6c 20 62 65 20 74 68 65 20 6e  an will be the n
5010: 75 6d 62 65 72 20 6f 66 0a 20 20 2a 2a 20 72 6f  umber of.  ** ro
5020: 77 73 20 69 6e 20 74 68 65 20 74 61 62 6c 65 20  ws in the table 
5030: 66 6f 72 20 61 20 6c 69 6e 65 61 72 20 73 63 61  for a linear sca
5040: 6e 2c 20 6f 72 20 74 68 65 20 6c 6f 67 20 28 62  n, or the log (b
5050: 61 73 65 20 32 29 20 6f 66 20 74 68 65 20 0a 20  ase 2) of the . 
5060: 20 2a 2a 20 6e 75 6d 62 65 72 20 6f 66 20 72 6f   ** number of ro
5070: 77 73 20 69 66 20 74 68 65 20 70 72 6f 70 6f 73  ws if the propos
5080: 65 64 20 73 63 61 6e 20 75 73 65 73 20 61 6e 20  ed scan uses an 
5090: 69 6e 64 65 78 2e 20 20 0a 20 20 2a 2f 0a 20 20  index.  .  */.  
50a0: 69 66 28 20 54 63 6c 5f 47 65 74 56 61 72 28 69  if( Tcl_GetVar(i
50b0: 6e 74 65 72 70 2c 20 22 65 63 68 6f 5f 6d 6f 64  nterp, "echo_mod
50c0: 75 6c 65 5f 63 6f 73 74 22 2c 20 54 43 4c 5f 47  ule_cost", TCL_G
50d0: 4c 4f 42 41 4c 5f 4f 4e 4c 59 29 20 29 7b 0a 20  LOBAL_ONLY) ){. 
50e0: 20 20 20 63 6f 73 74 20 3d 20 61 74 6f 66 28 54     cost = atof(T
50f0: 63 6c 5f 47 65 74 56 61 72 28 69 6e 74 65 72 70  cl_GetVar(interp
5100: 2c 20 22 65 63 68 6f 5f 6d 6f 64 75 6c 65 5f 63  , "echo_module_c
5110: 6f 73 74 22 2c 20 54 43 4c 5f 47 4c 4f 42 41 4c  ost", TCL_GLOBAL
5120: 5f 4f 4e 4c 59 29 29 3b 0a 20 20 20 20 75 73 65  _ONLY));.    use
5130: 43 6f 73 74 20 3d 20 31 3b 0a 20 20 7d 20 65 6c  Cost = 1;.  } el
5140: 73 65 20 7b 0a 20 20 20 20 7a 51 75 65 72 79 20  se {.    zQuery 
5150: 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74  = sqlite3_mprint
5160: 66 28 22 53 45 4c 45 43 54 20 63 6f 75 6e 74 28  f("SELECT count(
5170: 2a 29 20 46 52 4f 4d 20 25 51 22 2c 20 70 56 74  *) FROM %Q", pVt
5180: 61 62 2d 3e 7a 54 61 62 6c 65 4e 61 6d 65 29 3b  ab->zTableName);
5190: 0a 20 20 20 20 69 66 28 20 21 7a 51 75 65 72 79  .    if( !zQuery
51a0: 20 29 7b 0a 20 20 20 20 20 20 72 65 74 75 72 6e   ){.      return
51b0: 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20   SQLITE_NOMEM;. 
51c0: 20 20 20 7d 0a 20 20 20 20 72 63 20 3d 20 73 71     }.    rc = sq
51d0: 6c 69 74 65 33 5f 70 72 65 70 61 72 65 28 70 56  lite3_prepare(pV
51e0: 74 61 62 2d 3e 64 62 2c 20 7a 51 75 65 72 79 2c  tab->db, zQuery,
51f0: 20 2d 31 2c 20 26 70 53 74 6d 74 2c 20 30 29 3b   -1, &pStmt, 0);
5200: 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65  .    sqlite3_fre
5210: 65 28 7a 51 75 65 72 79 29 3b 0a 20 20 20 20 69  e(zQuery);.    i
5220: 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc!=SQLITE_OK
5230: 20 29 7b 0a 20 20 20 20 20 20 72 65 74 75 72 6e   ){.      return
5240: 20 72 63 3b 0a 20 20 20 20 7d 0a 20 20 20 20 73   rc;.    }.    s
5250: 71 6c 69 74 65 33 5f 73 74 65 70 28 70 53 74 6d  qlite3_step(pStm
5260: 74 29 3b 0a 20 20 20 20 6e 52 6f 77 20 3d 20 73  t);.    nRow = s
5270: 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f 69 6e  qlite3_column_in
5280: 74 28 70 53 74 6d 74 2c 20 30 29 3b 0a 20 20 20  t(pStmt, 0);.   
5290: 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 66 69   rc = sqlite3_fi
52a0: 6e 61 6c 69 7a 65 28 70 53 74 6d 74 29 3b 0a 20  nalize(pStmt);. 
52b0: 20 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54     if( rc!=SQLIT
52c0: 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 72 65  E_OK ){.      re
52d0: 74 75 72 6e 20 72 63 3b 0a 20 20 20 20 7d 0a 20  turn rc;.    }. 
52e0: 20 7d 0a 0a 20 20 7a 51 75 65 72 79 20 3d 20 73   }..  zQuery = s
52f0: 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 22  qlite3_mprintf("
5300: 53 45 4c 45 43 54 20 72 6f 77 69 64 2c 20 2a 20  SELECT rowid, * 
5310: 46 52 4f 4d 20 25 51 22 2c 20 70 56 74 61 62 2d  FROM %Q", pVtab-
5320: 3e 7a 54 61 62 6c 65 4e 61 6d 65 29 3b 0a 20 20  >zTableName);.  
5330: 69 66 28 20 21 7a 51 75 65 72 79 20 29 7b 0a 20  if( !zQuery ){. 
5340: 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45     return SQLITE
5350: 5f 4e 4f 4d 45 4d 3b 0a 20 20 7d 0a 20 20 66 6f  _NOMEM;.  }.  fo
5360: 72 28 69 69 3d 30 3b 20 69 69 3c 70 49 64 78 49  r(ii=0; ii<pIdxI
5370: 6e 66 6f 2d 3e 6e 43 6f 6e 73 74 72 61 69 6e 74  nfo->nConstraint
5380: 3b 20 69 69 2b 2b 29 7b 0a 20 20 20 20 63 6f 6e  ; ii++){.    con
5390: 73 74 20 73 74 72 75 63 74 20 73 71 6c 69 74 65  st struct sqlite
53a0: 33 5f 69 6e 64 65 78 5f 63 6f 6e 73 74 72 61 69  3_index_constrai
53b0: 6e 74 20 2a 70 43 6f 6e 73 74 72 61 69 6e 74 3b  nt *pConstraint;
53c0: 0a 20 20 20 20 73 74 72 75 63 74 20 73 71 6c 69  .    struct sqli
53d0: 74 65 33 5f 69 6e 64 65 78 5f 63 6f 6e 73 74 72  te3_index_constr
53e0: 61 69 6e 74 5f 75 73 61 67 65 20 2a 70 55 73 61  aint_usage *pUsa
53f0: 67 65 3b 0a 20 20 20 20 69 6e 74 20 69 43 6f 6c  ge;.    int iCol
5400: 3b 0a 0a 20 20 20 20 70 43 6f 6e 73 74 72 61 69  ;..    pConstrai
5410: 6e 74 20 3d 20 26 70 49 64 78 49 6e 66 6f 2d 3e  nt = &pIdxInfo->
5420: 61 43 6f 6e 73 74 72 61 69 6e 74 5b 69 69 5d 3b  aConstraint[ii];
5430: 0a 20 20 20 20 70 55 73 61 67 65 20 3d 20 26 70  .    pUsage = &p
5440: 49 64 78 49 6e 66 6f 2d 3e 61 43 6f 6e 73 74 72  IdxInfo->aConstr
5450: 61 69 6e 74 55 73 61 67 65 5b 69 69 5d 3b 0a 0a  aintUsage[ii];..
5460: 20 20 20 20 69 43 6f 6c 20 3d 20 70 43 6f 6e 73      iCol = pCons
5470: 74 72 61 69 6e 74 2d 3e 69 43 6f 6c 75 6d 6e 3b  traint->iColumn;
5480: 0a 20 20 20 20 69 66 28 20 70 56 74 61 62 2d 3e  .    if( pVtab->
5490: 61 49 6e 64 65 78 5b 69 43 6f 6c 5d 20 29 7b 0a  aIndex[iCol] ){.
54a0: 20 20 20 20 20 20 63 68 61 72 20 2a 7a 43 6f 6c        char *zCol
54b0: 20 3d 20 70 56 74 61 62 2d 3e 61 43 6f 6c 5b 69   = pVtab->aCol[i
54c0: 43 6f 6c 5d 3b 0a 20 20 20 20 20 20 63 68 61 72  Col];.      char
54d0: 20 2a 7a 4f 70 20 3d 20 30 3b 0a 20 20 20 20 20   *zOp = 0;.     
54e0: 20 75 73 65 49 64 78 20 3d 20 31 3b 0a 20 20 20   useIdx = 1;.   
54f0: 20 20 20 69 66 28 20 69 43 6f 6c 3c 30 20 29 7b     if( iCol<0 ){
5500: 0a 20 20 20 20 20 20 20 20 7a 43 6f 6c 20 3d 20  .        zCol = 
5510: 22 72 6f 77 69 64 22 3b 0a 20 20 20 20 20 20 7d  "rowid";.      }
5520: 0a 20 20 20 20 20 20 73 77 69 74 63 68 28 20 70  .      switch( p
5530: 43 6f 6e 73 74 72 61 69 6e 74 2d 3e 6f 70 20 29  Constraint->op )
5540: 7b 0a 20 20 20 20 20 20 20 20 63 61 73 65 20 53  {.        case S
5550: 51 4c 49 54 45 5f 49 4e 44 45 58 5f 43 4f 4e 53  QLITE_INDEX_CONS
5560: 54 52 41 49 4e 54 5f 45 51 3a 0a 20 20 20 20 20  TRAINT_EQ:.     
5570: 20 20 20 20 20 7a 4f 70 20 3d 20 22 3d 22 3b 20       zOp = "="; 
5580: 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 20 20 63  break;.        c
5590: 61 73 65 20 53 51 4c 49 54 45 5f 49 4e 44 45 58  ase SQLITE_INDEX
55a0: 5f 43 4f 4e 53 54 52 41 49 4e 54 5f 4c 54 3a 0a  _CONSTRAINT_LT:.
55b0: 20 20 20 20 20 20 20 20 20 20 7a 4f 70 20 3d 20            zOp = 
55c0: 22 3c 22 3b 20 62 72 65 61 6b 3b 0a 20 20 20 20  "<"; break;.    
55d0: 20 20 20 20 63 61 73 65 20 53 51 4c 49 54 45 5f      case SQLITE_
55e0: 49 4e 44 45 58 5f 43 4f 4e 53 54 52 41 49 4e 54  INDEX_CONSTRAINT
55f0: 5f 47 54 3a 0a 20 20 20 20 20 20 20 20 20 20 7a  _GT:.          z
5600: 4f 70 20 3d 20 22 3e 22 3b 20 62 72 65 61 6b 3b  Op = ">"; break;
5610: 0a 20 20 20 20 20 20 20 20 63 61 73 65 20 53 51  .        case SQ
5620: 4c 49 54 45 5f 49 4e 44 45 58 5f 43 4f 4e 53 54  LITE_INDEX_CONST
5630: 52 41 49 4e 54 5f 4c 45 3a 0a 20 20 20 20 20 20  RAINT_LE:.      
5640: 20 20 20 20 7a 4f 70 20 3d 20 22 3c 3d 22 3b 20      zOp = "<="; 
5650: 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 20 20 63  break;.        c
5660: 61 73 65 20 53 51 4c 49 54 45 5f 49 4e 44 45 58  ase SQLITE_INDEX
5670: 5f 43 4f 4e 53 54 52 41 49 4e 54 5f 47 45 3a 0a  _CONSTRAINT_GE:.
5680: 20 20 20 20 20 20 20 20 20 20 7a 4f 70 20 3d 20            zOp = 
5690: 22 3e 3d 22 3b 20 62 72 65 61 6b 3b 0a 20 20 20  ">="; break;.   
56a0: 20 20 20 20 20 63 61 73 65 20 53 51 4c 49 54 45       case SQLITE
56b0: 5f 49 4e 44 45 58 5f 43 4f 4e 53 54 52 41 49 4e  _INDEX_CONSTRAIN
56c0: 54 5f 4d 41 54 43 48 3a 0a 20 20 20 20 20 20 20  T_MATCH:.       
56d0: 20 20 20 7a 4f 70 20 3d 20 22 4c 49 4b 45 22 3b     zOp = "LIKE";
56e0: 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 7d 0a   break;.      }.
56f0: 20 20 20 20 20 20 69 66 28 20 7a 4f 70 5b 30 5d        if( zOp[0]
5700: 3d 3d 27 4c 27 20 29 7b 0a 20 20 20 20 20 20 20  =='L' ){.       
5710: 20 7a 4e 65 77 20 3d 20 73 71 6c 69 74 65 33 5f   zNew = sqlite3_
5720: 6d 70 72 69 6e 74 66 28 22 20 25 73 20 25 73 20  mprintf(" %s %s 
5730: 4c 49 4b 45 20 28 53 45 4c 45 43 54 20 27 25 25  LIKE (SELECT '%%
5740: 27 7c 7c 3f 7c 7c 27 25 25 27 29 22 2c 20 0a 20  '||?||'%%')", . 
5750: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5760: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 7a 53                zS
5770: 65 70 2c 20 7a 43 6f 6c 29 3b 0a 20 20 20 20 20  ep, zCol);.     
5780: 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20 20 20   } else {.      
5790: 20 20 7a 4e 65 77 20 3d 20 73 71 6c 69 74 65 33    zNew = sqlite3
57a0: 5f 6d 70 72 69 6e 74 66 28 22 20 25 73 20 25 73  _mprintf(" %s %s
57b0: 20 25 73 20 3f 22 2c 20 7a 53 65 70 2c 20 7a 43   %s ?", zSep, zC
57c0: 6f 6c 2c 20 7a 4f 70 29 3b 0a 20 20 20 20 20 20  ol, zOp);.      
57d0: 7d 0a 20 20 20 20 20 20 73 74 72 69 6e 67 5f 63  }.      string_c
57e0: 6f 6e 63 61 74 28 26 7a 51 75 65 72 79 2c 20 7a  oncat(&zQuery, z
57f0: 4e 65 77 2c 20 31 2c 20 26 72 63 29 3b 0a 0a 20  New, 1, &rc);.. 
5800: 20 20 20 20 20 7a 53 65 70 20 3d 20 22 41 4e 44       zSep = "AND
5810: 22 3b 0a 20 20 20 20 20 20 70 55 73 61 67 65 2d  ";.      pUsage-
5820: 3e 61 72 67 76 49 6e 64 65 78 20 3d 20 2b 2b 6e  >argvIndex = ++n
5830: 41 72 67 3b 0a 20 20 20 20 20 20 70 55 73 61 67  Arg;.      pUsag
5840: 65 2d 3e 6f 6d 69 74 20 3d 20 31 3b 0a 20 20 20  e->omit = 1;.   
5850: 20 7d 0a 20 20 7d 0a 0a 20 20 2f 2a 20 49 66 20   }.  }..  /* If 
5860: 74 68 65 72 65 20 69 73 20 6f 6e 6c 79 20 6f 6e  there is only on
5870: 65 20 74 65 72 6d 20 69 6e 20 74 68 65 20 4f 52  e term in the OR
5880: 44 45 52 20 42 59 20 63 6c 61 75 73 65 2c 20 61  DER BY clause, a
5890: 6e 64 20 69 74 20 69 73 0a 20 20 2a 2a 20 6f 6e  nd it is.  ** on
58a0: 20 61 20 63 6f 6c 75 6d 6e 20 74 68 61 74 20 74   a column that t
58b0: 68 69 73 20 76 69 72 74 75 61 6c 20 74 61 62 6c  his virtual tabl
58c0: 65 20 68 61 73 20 61 6e 20 69 6e 64 65 78 20 66  e has an index f
58d0: 6f 72 2c 20 74 68 65 6e 20 63 6f 6e 73 75 6d 65  or, then consume
58e0: 20 0a 20 20 2a 2a 20 74 68 65 20 4f 52 44 45 52   .  ** the ORDER
58f0: 20 42 59 20 63 6c 61 75 73 65 2e 0a 20 20 2a 2f   BY clause..  */
5900: 0a 20 20 69 66 28 20 70 49 64 78 49 6e 66 6f 2d  .  if( pIdxInfo-
5910: 3e 6e 4f 72 64 65 72 42 79 3d 3d 31 20 26 26 20  >nOrderBy==1 && 
5920: 70 56 74 61 62 2d 3e 61 49 6e 64 65 78 5b 70 49  pVtab->aIndex[pI
5930: 64 78 49 6e 66 6f 2d 3e 61 4f 72 64 65 72 42 79  dxInfo->aOrderBy
5940: 2d 3e 69 43 6f 6c 75 6d 6e 5d 20 29 7b 0a 20 20  ->iColumn] ){.  
5950: 20 20 69 6e 74 20 69 43 6f 6c 20 3d 20 70 49 64    int iCol = pId
5960: 78 49 6e 66 6f 2d 3e 61 4f 72 64 65 72 42 79 2d  xInfo->aOrderBy-
5970: 3e 69 43 6f 6c 75 6d 6e 3b 0a 20 20 20 20 63 68  >iColumn;.    ch
5980: 61 72 20 2a 7a 43 6f 6c 20 3d 20 70 56 74 61 62  ar *zCol = pVtab
5990: 2d 3e 61 43 6f 6c 5b 69 43 6f 6c 5d 3b 0a 20 20  ->aCol[iCol];.  
59a0: 20 20 63 68 61 72 20 2a 7a 44 69 72 20 3d 20 70    char *zDir = p
59b0: 49 64 78 49 6e 66 6f 2d 3e 61 4f 72 64 65 72 42  IdxInfo->aOrderB
59c0: 79 2d 3e 64 65 73 63 3f 22 44 45 53 43 22 3a 22  y->desc?"DESC":"
59d0: 41 53 43 22 3b 0a 20 20 20 20 69 66 28 20 69 43  ASC";.    if( iC
59e0: 6f 6c 3c 30 20 29 7b 0a 20 20 20 20 20 20 7a 43  ol<0 ){.      zC
59f0: 6f 6c 20 3d 20 22 72 6f 77 69 64 22 3b 0a 20 20  ol = "rowid";.  
5a00: 20 20 7d 0a 20 20 20 20 7a 4e 65 77 20 3d 20 73    }.    zNew = s
5a10: 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 22  qlite3_mprintf("
5a20: 20 4f 52 44 45 52 20 42 59 20 25 73 20 25 73 22   ORDER BY %s %s"
5a30: 2c 20 7a 43 6f 6c 2c 20 7a 44 69 72 29 3b 0a 20  , zCol, zDir);. 
5a40: 20 20 20 73 74 72 69 6e 67 5f 63 6f 6e 63 61 74     string_concat
5a50: 28 26 7a 51 75 65 72 79 2c 20 7a 4e 65 77 2c 20  (&zQuery, zNew, 
5a60: 31 2c 20 26 72 63 29 3b 0a 20 20 20 20 70 49 64  1, &rc);.    pId
5a70: 78 49 6e 66 6f 2d 3e 6f 72 64 65 72 42 79 43 6f  xInfo->orderByCo
5a80: 6e 73 75 6d 65 64 20 3d 20 31 3b 0a 20 20 7d 0a  nsumed = 1;.  }.
5a90: 0a 20 20 61 70 70 65 6e 64 54 6f 45 63 68 6f 4d  .  appendToEchoM
5aa0: 6f 64 75 6c 65 28 70 56 74 61 62 2d 3e 69 6e 74  odule(pVtab->int
5ab0: 65 72 70 2c 20 22 78 42 65 73 74 49 6e 64 65 78  erp, "xBestIndex
5ac0: 22 29 3b 3b 0a 20 20 61 70 70 65 6e 64 54 6f 45  ");;.  appendToE
5ad0: 63 68 6f 4d 6f 64 75 6c 65 28 70 56 74 61 62 2d  choModule(pVtab-
5ae0: 3e 69 6e 74 65 72 70 2c 20 7a 51 75 65 72 79 29  >interp, zQuery)
5af0: 3b 0a 0a 20 20 69 66 28 20 21 7a 51 75 65 72 79  ;..  if( !zQuery
5b00: 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 72   ){.    return r
5b10: 63 3b 0a 20 20 7d 0a 20 20 70 49 64 78 49 6e 66  c;.  }.  pIdxInf
5b20: 6f 2d 3e 69 64 78 4e 75 6d 20 3d 20 68 61 73 68  o->idxNum = hash
5b30: 53 74 72 69 6e 67 28 7a 51 75 65 72 79 29 3b 0a  String(zQuery);.
5b40: 20 20 70 49 64 78 49 6e 66 6f 2d 3e 69 64 78 53    pIdxInfo->idxS
5b50: 74 72 20 3d 20 7a 51 75 65 72 79 3b 0a 20 20 70  tr = zQuery;.  p
5b60: 49 64 78 49 6e 66 6f 2d 3e 6e 65 65 64 54 6f 46  IdxInfo->needToF
5b70: 72 65 65 49 64 78 53 74 72 20 3d 20 31 3b 0a 20  reeIdxStr = 1;. 
5b80: 20 69 66 20 28 75 73 65 43 6f 73 74 29 20 7b 0a   if (useCost) {.
5b90: 20 20 20 20 70 49 64 78 49 6e 66 6f 2d 3e 65 73      pIdxInfo->es
5ba0: 74 69 6d 61 74 65 64 43 6f 73 74 20 3d 20 63 6f  timatedCost = co
5bb0: 73 74 3b 0a 20 20 7d 20 65 6c 73 65 20 69 66 28  st;.  } else if(
5bc0: 20 75 73 65 49 64 78 20 29 7b 0a 20 20 20 20 2f   useIdx ){.    /
5bd0: 2a 20 41 70 70 72 6f 78 69 6d 61 74 69 6f 6e 20  * Approximation 
5be0: 6f 66 20 6c 6f 67 32 28 6e 52 6f 77 29 2e 20 2a  of log2(nRow). *
5bf0: 2f 0a 20 20 20 20 66 6f 72 28 20 69 69 3d 30 3b  /.    for( ii=0;
5c00: 20 69 69 3c 28 73 69 7a 65 6f 66 28 69 6e 74 29   ii<(sizeof(int)
5c10: 2a 38 29 3b 20 69 69 2b 2b 20 29 7b 0a 20 20 20  *8); ii++ ){.   
5c20: 20 20 20 69 66 28 20 6e 52 6f 77 20 26 20 28 31     if( nRow & (1
5c30: 3c 3c 69 69 29 20 29 7b 0a 20 20 20 20 20 20 20  <<ii) ){.       
5c40: 20 70 49 64 78 49 6e 66 6f 2d 3e 65 73 74 69 6d   pIdxInfo->estim
5c50: 61 74 65 64 43 6f 73 74 20 3d 20 28 64 6f 75 62  atedCost = (doub
5c60: 6c 65 29 69 69 3b 0a 20 20 20 20 20 20 7d 0a 20  le)ii;.      }. 
5c70: 20 20 20 7d 0a 20 20 7d 20 65 6c 73 65 20 7b 0a     }.  } else {.
5c80: 20 20 20 20 70 49 64 78 49 6e 66 6f 2d 3e 65 73      pIdxInfo->es
5c90: 74 69 6d 61 74 65 64 43 6f 73 74 20 3d 20 28 64  timatedCost = (d
5ca0: 6f 75 62 6c 65 29 6e 52 6f 77 3b 0a 20 20 7d 0a  ouble)nRow;.  }.
5cb0: 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a    return rc;.}..
5cc0: 2f 2a 0a 2a 2a 20 54 68 65 20 78 55 70 64 61 74  /*.** The xUpdat
5cd0: 65 20 6d 65 74 68 6f 64 20 66 6f 72 20 65 63 68  e method for ech
5ce0: 6f 20 6d 6f 64 75 6c 65 20 76 69 72 74 75 61 6c  o module virtual
5cf0: 20 74 61 62 6c 65 73 2e 0a 2a 2a 20 0a 2a 2a 20   tables..** .** 
5d00: 20 20 20 61 70 44 61 74 61 5b 30 5d 20 20 61 70     apData[0]  ap
5d10: 44 61 74 61 5b 31 5d 20 20 61 70 44 61 74 61 5b  Data[1]  apData[
5d20: 32 2e 2e 5d 0a 2a 2a 0a 2a 2a 20 20 20 20 49 4e  2..].**.**    IN
5d30: 54 45 47 45 52 20 20 20 20 20 20 20 20 20 20 20  TEGER           
5d40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5d50: 20 20 20 44 45 4c 45 54 45 20 20 20 20 20 20 20     DELETE       
5d60: 20 20 20 20 20 0a 2a 2a 0a 2a 2a 20 20 20 20 49       .**.**    I
5d70: 4e 54 45 47 45 52 20 20 20 20 4e 55 4c 4c 20 20  NTEGER    NULL  
5d80: 20 20 20 20 20 28 6e 43 6f 6c 20 61 72 67 73 29       (nCol args)
5d90: 20 20 20 20 55 50 44 41 54 45 20 28 64 6f 20 6e      UPDATE (do n
5da0: 6f 74 20 73 65 74 20 72 6f 77 69 64 29 0a 2a 2a  ot set rowid).**
5db0: 20 20 20 20 49 4e 54 45 47 45 52 20 20 20 20 49      INTEGER    I
5dc0: 4e 54 45 47 45 52 20 20 20 20 28 6e 43 6f 6c 20  NTEGER    (nCol 
5dd0: 61 72 67 73 29 20 20 20 20 55 50 44 41 54 45 20  args)    UPDATE 
5de0: 28 77 69 74 68 20 53 45 54 20 72 6f 77 69 64 20  (with SET rowid 
5df0: 3d 20 3c 61 72 67 31 3e 29 0a 2a 2a 0a 2a 2a 20  = <arg1>).**.** 
5e00: 20 20 20 4e 55 4c 4c 20 20 20 20 20 20 20 4e 55     NULL       NU
5e10: 4c 4c 20 20 20 20 20 20 20 28 6e 43 6f 6c 20 61  LL       (nCol a
5e20: 72 67 73 29 20 20 20 20 49 4e 53 45 52 54 20 49  rgs)    INSERT I
5e30: 4e 54 4f 20 28 61 75 74 6f 6d 61 74 69 63 20 72  NTO (automatic r
5e40: 6f 77 69 64 20 76 61 6c 75 65 29 0a 2a 2a 20 20  owid value).**  
5e50: 20 20 4e 55 4c 4c 20 20 20 20 20 20 20 49 4e 54    NULL       INT
5e60: 45 47 45 52 20 20 20 20 28 6e 43 6f 6c 20 61 72  EGER    (nCol ar
5e70: 67 73 29 20 20 20 20 49 4e 53 45 52 54 20 28 69  gs)    INSERT (i
5e80: 6e 63 6c 2e 20 72 6f 77 69 64 20 76 61 6c 75 65  ncl. rowid value
5e90: 29 0a 2a 2a 0a 2a 2f 0a 69 6e 74 20 65 63 68 6f  ).**.*/.int echo
5ea0: 55 70 64 61 74 65 28 0a 20 20 73 71 6c 69 74 65  Update(.  sqlite
5eb0: 33 5f 76 74 61 62 20 2a 74 61 62 2c 20 0a 20 20  3_vtab *tab, .  
5ec0: 69 6e 74 20 6e 44 61 74 61 2c 20 0a 20 20 73 71  int nData, .  sq
5ed0: 6c 69 74 65 33 5f 76 61 6c 75 65 20 2a 2a 61 70  lite3_value **ap
5ee0: 44 61 74 61 2c 20 0a 20 20 73 71 6c 69 74 65 5f  Data, .  sqlite_
5ef0: 69 6e 74 36 34 20 2a 70 52 6f 77 69 64 0a 29 7b  int64 *pRowid.){
5f00: 0a 20 20 65 63 68 6f 5f 76 74 61 62 20 2a 70 56  .  echo_vtab *pV
5f10: 74 61 62 20 3d 20 28 65 63 68 6f 5f 76 74 61 62  tab = (echo_vtab
5f20: 20 2a 29 74 61 62 3b 0a 20 20 73 71 6c 69 74 65   *)tab;.  sqlite
5f30: 33 20 2a 64 62 20 3d 20 70 56 74 61 62 2d 3e 64  3 *db = pVtab->d
5f40: 62 3b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51  b;.  int rc = SQ
5f50: 4c 49 54 45 5f 4f 4b 3b 0a 0a 20 20 73 71 6c 69  LITE_OK;..  sqli
5f60: 74 65 33 5f 73 74 6d 74 20 2a 70 53 74 6d 74 3b  te3_stmt *pStmt;
5f70: 0a 20 20 63 68 61 72 20 2a 7a 20 3d 20 30 3b 20  .  char *z = 0; 
5f80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
5f90: 20 53 51 4c 20 73 74 61 74 65 6d 65 6e 74 20 74   SQL statement t
5fa0: 6f 20 65 78 65 63 75 74 65 20 2a 2f 0a 20 20 69  o execute */.  i
5fb0: 6e 74 20 62 69 6e 64 41 72 67 5a 65 72 6f 20 3d  nt bindArgZero =
5fc0: 20 30 3b 20 20 20 20 20 20 20 2f 2a 20 54 72 75   0;       /* Tru
5fd0: 65 20 74 6f 20 62 69 6e 64 20 61 70 44 61 74 61  e to bind apData
5fe0: 5b 30 5d 20 74 6f 20 73 71 6c 20 76 61 72 20 6e  [0] to sql var n
5ff0: 6f 2e 20 6e 44 61 74 61 20 2a 2f 0a 20 20 69 6e  o. nData */.  in
6000: 74 20 62 69 6e 64 41 72 67 4f 6e 65 20 3d 20 30  t bindArgOne = 0
6010: 3b 20 20 20 20 20 20 20 20 2f 2a 20 54 72 75 65  ;        /* True
6020: 20 74 6f 20 62 69 6e 64 20 61 70 44 61 74 61 5b   to bind apData[
6030: 31 5d 20 74 6f 20 73 71 6c 20 76 61 72 20 6e 6f  1] to sql var no
6040: 2e 20 31 20 2a 2f 0a 20 20 69 6e 74 20 69 3b 20  . 1 */.  int i; 
6050: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6060: 20 20 20 20 2f 2a 20 43 6f 75 6e 74 65 72 20 76      /* Counter v
6070: 61 72 69 61 62 6c 65 20 75 73 65 64 20 62 79 20  ariable used by 
6080: 66 6f 72 20 6c 6f 6f 70 73 20 2a 2f 0a 0a 20 20  for loops */..  
6090: 61 73 73 65 72 74 28 20 6e 44 61 74 61 3d 3d 70  assert( nData==p
60a0: 56 74 61 62 2d 3e 6e 43 6f 6c 2b 32 20 7c 7c 20  Vtab->nCol+2 || 
60b0: 6e 44 61 74 61 3d 3d 31 20 29 3b 0a 0a 20 20 2f  nData==1 );..  /
60c0: 2a 20 49 66 20 61 70 44 61 74 61 5b 30 5d 20 69  * If apData[0] i
60d0: 73 20 61 6e 20 69 6e 74 65 67 65 72 20 61 6e 64  s an integer and
60e0: 20 6e 44 61 74 61 3e 31 20 74 68 65 6e 20 64 6f   nData>1 then do
60f0: 20 61 6e 20 55 50 44 41 54 45 20 2a 2f 0a 20 20   an UPDATE */.  
6100: 69 66 28 20 6e 44 61 74 61 3e 31 20 26 26 20 73  if( nData>1 && s
6110: 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 74 79 70  qlite3_value_typ
6120: 65 28 61 70 44 61 74 61 5b 30 5d 29 3d 3d 53 51  e(apData[0])==SQ
6130: 4c 49 54 45 5f 49 4e 54 45 47 45 52 20 29 7b 0a  LITE_INTEGER ){.
6140: 20 20 20 20 63 68 61 72 20 2a 7a 53 65 70 20 3d      char *zSep =
6150: 20 22 20 53 45 54 22 3b 0a 20 20 20 20 7a 20 3d   " SET";.    z =
6160: 20 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66   sqlite3_mprintf
6170: 28 22 55 50 44 41 54 45 20 25 51 22 2c 20 70 56  ("UPDATE %Q", pV
6180: 74 61 62 2d 3e 7a 54 61 62 6c 65 4e 61 6d 65 29  tab->zTableName)
6190: 3b 0a 20 20 20 20 69 66 28 20 21 7a 20 29 7b 0a  ;.    if( !z ){.
61a0: 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54        rc = SQLIT
61b0: 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 7d 0a 0a  E_NOMEM;.    }..
61c0: 20 20 20 20 62 69 6e 64 41 72 67 4f 6e 65 20 3d      bindArgOne =
61d0: 20 28 61 70 44 61 74 61 5b 31 5d 20 26 26 20 73   (apData[1] && s
61e0: 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 74 79 70  qlite3_value_typ
61f0: 65 28 61 70 44 61 74 61 5b 31 5d 29 3d 3d 53 51  e(apData[1])==SQ
6200: 4c 49 54 45 5f 49 4e 54 45 47 45 52 29 3b 0a 20  LITE_INTEGER);. 
6210: 20 20 20 62 69 6e 64 41 72 67 5a 65 72 6f 20 3d     bindArgZero =
6220: 20 31 3b 0a 0a 20 20 20 20 69 66 28 20 62 69 6e   1;..    if( bin
6230: 64 41 72 67 4f 6e 65 20 29 7b 0a 20 20 20 20 20  dArgOne ){.     
6240: 20 20 73 74 72 69 6e 67 5f 63 6f 6e 63 61 74 28    string_concat(
6250: 26 7a 2c 20 22 20 53 45 54 20 72 6f 77 69 64 3d  &z, " SET rowid=
6260: 3f 31 20 22 2c 20 30 2c 20 26 72 63 29 3b 0a 20  ?1 ", 0, &rc);. 
6270: 20 20 20 20 20 20 7a 53 65 70 20 3d 20 22 2c 22        zSep = ","
6280: 3b 0a 20 20 20 20 7d 0a 20 20 20 20 66 6f 72 28  ;.    }.    for(
6290: 69 3d 32 3b 20 69 3c 6e 44 61 74 61 3b 20 69 2b  i=2; i<nData; i+
62a0: 2b 29 7b 0a 20 20 20 20 20 20 69 66 28 20 61 70  +){.      if( ap
62b0: 44 61 74 61 5b 69 5d 3d 3d 30 20 29 20 63 6f 6e  Data[i]==0 ) con
62c0: 74 69 6e 75 65 3b 0a 20 20 20 20 20 20 73 74 72  tinue;.      str
62d0: 69 6e 67 5f 63 6f 6e 63 61 74 28 26 7a 2c 20 73  ing_concat(&z, s
62e0: 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 0a  qlite3_mprintf(.
62f0: 20 20 20 20 20 20 20 20 20 20 22 25 73 20 25 51            "%s %Q
6300: 3d 3f 25 64 22 2c 20 7a 53 65 70 2c 20 70 56 74  =?%d", zSep, pVt
6310: 61 62 2d 3e 61 43 6f 6c 5b 69 2d 32 5d 2c 20 69  ab->aCol[i-2], i
6320: 29 2c 20 31 2c 20 26 72 63 29 3b 0a 20 20 20 20  ), 1, &rc);.    
6330: 20 20 7a 53 65 70 20 3d 20 22 2c 22 3b 0a 20 20    zSep = ",";.  
6340: 20 20 7d 0a 20 20 20 20 73 74 72 69 6e 67 5f 63    }.    string_c
6350: 6f 6e 63 61 74 28 26 7a 2c 20 73 71 6c 69 74 65  oncat(&z, sqlite
6360: 33 5f 6d 70 72 69 6e 74 66 28 22 20 57 48 45 52  3_mprintf(" WHER
6370: 45 20 72 6f 77 69 64 3d 3f 25 64 22 2c 20 6e 44  E rowid=?%d", nD
6380: 61 74 61 29 2c 20 31 2c 20 26 72 63 29 3b 0a 20  ata), 1, &rc);. 
6390: 20 7d 0a 0a 20 20 2f 2a 20 49 66 20 61 70 44 61   }..  /* If apDa
63a0: 74 61 5b 30 5d 20 69 73 20 61 6e 20 69 6e 74 65  ta[0] is an inte
63b0: 67 65 72 20 61 6e 64 20 6e 44 61 74 61 3d 3d 31  ger and nData==1
63c0: 20 74 68 65 6e 20 64 6f 20 61 20 44 45 4c 45 54   then do a DELET
63d0: 45 20 2a 2f 0a 20 20 65 6c 73 65 20 69 66 28 20  E */.  else if( 
63e0: 6e 44 61 74 61 3d 3d 31 20 26 26 20 73 71 6c 69  nData==1 && sqli
63f0: 74 65 33 5f 76 61 6c 75 65 5f 74 79 70 65 28 61  te3_value_type(a
6400: 70 44 61 74 61 5b 30 5d 29 3d 3d 53 51 4c 49 54  pData[0])==SQLIT
6410: 45 5f 49 4e 54 45 47 45 52 20 29 7b 0a 20 20 20  E_INTEGER ){.   
6420: 20 7a 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72   z = sqlite3_mpr
6430: 69 6e 74 66 28 22 44 45 4c 45 54 45 20 46 52 4f  intf("DELETE FRO
6440: 4d 20 25 51 20 57 48 45 52 45 20 72 6f 77 69 64  M %Q WHERE rowid
6450: 20 3d 20 3f 31 22 2c 20 70 56 74 61 62 2d 3e 7a   = ?1", pVtab->z
6460: 54 61 62 6c 65 4e 61 6d 65 29 3b 0a 20 20 20 20  TableName);.    
6470: 69 66 28 20 21 7a 20 29 7b 0a 20 20 20 20 20 20  if( !z ){.      
6480: 72 63 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45  rc = SQLITE_NOME
6490: 4d 3b 0a 20 20 20 20 7d 0a 20 20 20 20 62 69 6e  M;.    }.    bin
64a0: 64 41 72 67 5a 65 72 6f 20 3d 20 31 3b 0a 20 20  dArgZero = 1;.  
64b0: 7d 0a 0a 20 20 2f 2a 20 49 66 20 74 68 65 20 66  }..  /* If the f
64c0: 69 72 73 74 20 61 72 67 75 6d 65 6e 74 20 69 73  irst argument is
64d0: 20 4e 55 4c 4c 20 61 6e 64 20 74 68 65 72 65 20   NULL and there 
64e0: 61 72 65 20 6d 6f 72 65 20 74 68 61 6e 20 74 77  are more than tw
64f0: 6f 20 61 72 67 73 2c 20 49 4e 53 45 52 54 20 2a  o args, INSERT *
6500: 2f 0a 20 20 65 6c 73 65 20 69 66 28 20 6e 44 61  /.  else if( nDa
6510: 74 61 3e 32 20 26 26 20 73 71 6c 69 74 65 33 5f  ta>2 && sqlite3_
6520: 76 61 6c 75 65 5f 74 79 70 65 28 61 70 44 61 74  value_type(apDat
6530: 61 5b 30 5d 29 3d 3d 53 51 4c 49 54 45 5f 4e 55  a[0])==SQLITE_NU
6540: 4c 4c 20 29 7b 0a 20 20 20 20 69 6e 74 20 69 69  LL ){.    int ii
6550: 3b 0a 20 20 20 20 63 68 61 72 20 2a 7a 49 6e 73  ;.    char *zIns
6560: 65 72 74 20 3d 20 30 3b 0a 20 20 20 20 63 68 61  ert = 0;.    cha
6570: 72 20 2a 7a 56 61 6c 75 65 73 20 3d 20 30 3b 0a  r *zValues = 0;.
6580: 20 20 0a 20 20 20 20 7a 49 6e 73 65 72 74 20 3d    .    zInsert =
6590: 20 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66   sqlite3_mprintf
65a0: 28 22 49 4e 53 45 52 54 20 49 4e 54 4f 20 25 51  ("INSERT INTO %Q
65b0: 20 28 22 2c 20 70 56 74 61 62 2d 3e 7a 54 61 62   (", pVtab->zTab
65c0: 6c 65 4e 61 6d 65 29 3b 0a 20 20 20 20 69 66 28  leName);.    if(
65d0: 20 21 7a 49 6e 73 65 72 74 20 29 7b 0a 20 20 20   !zInsert ){.   
65e0: 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4e     rc = SQLITE_N
65f0: 4f 4d 45 4d 3b 0a 20 20 20 20 7d 0a 20 20 20 20  OMEM;.    }.    
6600: 69 66 28 20 73 71 6c 69 74 65 33 5f 76 61 6c 75  if( sqlite3_valu
6610: 65 5f 74 79 70 65 28 61 70 44 61 74 61 5b 31 5d  e_type(apData[1]
6620: 29 3d 3d 53 51 4c 49 54 45 5f 49 4e 54 45 47 45  )==SQLITE_INTEGE
6630: 52 20 29 7b 0a 20 20 20 20 20 20 62 69 6e 64 41  R ){.      bindA
6640: 72 67 4f 6e 65 20 3d 20 31 3b 0a 20 20 20 20 20  rgOne = 1;.     
6650: 20 7a 56 61 6c 75 65 73 20 3d 20 73 71 6c 69 74   zValues = sqlit
6660: 65 33 5f 6d 70 72 69 6e 74 66 28 22 3f 22 29 3b  e3_mprintf("?");
6670: 0a 20 20 20 20 20 20 73 74 72 69 6e 67 5f 63 6f  .      string_co
6680: 6e 63 61 74 28 26 7a 49 6e 73 65 72 74 2c 20 22  ncat(&zInsert, "
6690: 72 6f 77 69 64 22 2c 20 30 2c 20 26 72 63 29 3b  rowid", 0, &rc);
66a0: 0a 20 20 20 20 7d 0a 0a 20 20 20 20 61 73 73 65  .    }..    asse
66b0: 72 74 28 28 70 56 74 61 62 2d 3e 6e 43 6f 6c 2b  rt((pVtab->nCol+
66c0: 32 29 3d 3d 6e 44 61 74 61 29 3b 0a 20 20 20 20  2)==nData);.    
66d0: 66 6f 72 28 69 69 3d 32 3b 20 69 69 3c 6e 44 61  for(ii=2; ii<nDa
66e0: 74 61 3b 20 69 69 2b 2b 29 7b 0a 20 20 20 20 20  ta; ii++){.     
66f0: 20 73 74 72 69 6e 67 5f 63 6f 6e 63 61 74 28 26   string_concat(&
6700: 7a 49 6e 73 65 72 74 2c 20 0a 20 20 20 20 20 20  zInsert, .      
6710: 20 20 20 20 73 71 6c 69 74 65 33 5f 6d 70 72 69      sqlite3_mpri
6720: 6e 74 66 28 22 25 73 25 51 22 2c 20 7a 56 61 6c  ntf("%s%Q", zVal
6730: 75 65 73 3f 22 2c 20 22 3a 22 22 2c 20 70 56 74  ues?", ":"", pVt
6740: 61 62 2d 3e 61 43 6f 6c 5b 69 69 2d 32 5d 29 2c  ab->aCol[ii-2]),
6750: 20 31 2c 20 26 72 63 29 3b 0a 20 20 20 20 20 20   1, &rc);.      
6760: 73 74 72 69 6e 67 5f 63 6f 6e 63 61 74 28 26 7a  string_concat(&z
6770: 56 61 6c 75 65 73 2c 20 0a 20 20 20 20 20 20 20  Values, .       
6780: 20 20 20 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e     sqlite3_mprin
6790: 74 66 28 22 25 73 3f 25 64 22 2c 20 7a 56 61 6c  tf("%s?%d", zVal
67a0: 75 65 73 3f 22 2c 20 22 3a 22 22 2c 20 69 69 29  ues?", ":"", ii)
67b0: 2c 20 31 2c 20 26 72 63 29 3b 0a 20 20 20 20 7d  , 1, &rc);.    }
67c0: 0a 0a 20 20 20 20 73 74 72 69 6e 67 5f 63 6f 6e  ..    string_con
67d0: 63 61 74 28 26 7a 2c 20 7a 49 6e 73 65 72 74 2c  cat(&z, zInsert,
67e0: 20 31 2c 20 26 72 63 29 3b 0a 20 20 20 20 73 74   1, &rc);.    st
67f0: 72 69 6e 67 5f 63 6f 6e 63 61 74 28 26 7a 2c 20  ring_concat(&z, 
6800: 22 29 20 56 41 4c 55 45 53 28 22 2c 20 30 2c 20  ") VALUES(", 0, 
6810: 26 72 63 29 3b 0a 20 20 20 20 73 74 72 69 6e 67  &rc);.    string
6820: 5f 63 6f 6e 63 61 74 28 26 7a 2c 20 7a 56 61 6c  _concat(&z, zVal
6830: 75 65 73 2c 20 31 2c 20 26 72 63 29 3b 0a 20 20  ues, 1, &rc);.  
6840: 20 20 73 74 72 69 6e 67 5f 63 6f 6e 63 61 74 28    string_concat(
6850: 26 7a 2c 20 22 29 22 2c 20 30 2c 20 26 72 63 29  &z, ")", 0, &rc)
6860: 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 41 6e 79 74  ;.  }..  /* Anyt
6870: 68 69 6e 67 20 65 6c 73 65 20 69 73 20 61 6e 20  hing else is an 
6880: 65 72 72 6f 72 20 2a 2f 0a 20 20 65 6c 73 65 7b  error */.  else{
6890: 0a 20 20 20 20 61 73 73 65 72 74 28 30 29 3b 0a  .    assert(0);.
68a0: 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54      return SQLIT
68b0: 45 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a 0a 20 20  E_ERROR;.  }..  
68c0: 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  if( rc==SQLITE_O
68d0: 4b 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 73 71  K ){.    rc = sq
68e0: 6c 69 74 65 33 5f 70 72 65 70 61 72 65 28 64 62  lite3_prepare(db
68f0: 2c 20 7a 2c 20 2d 31 2c 20 26 70 53 74 6d 74 2c  , z, -1, &pStmt,
6900: 20 30 29 3b 0a 20 20 7d 0a 20 20 61 73 73 65 72   0);.  }.  asser
6910: 74 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b  t( rc!=SQLITE_OK
6920: 20 7c 7c 20 70 53 74 6d 74 20 29 3b 0a 20 20 73   || pStmt );.  s
6930: 71 6c 69 74 65 33 5f 66 72 65 65 28 7a 29 3b 0a  qlite3_free(z);.
6940: 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
6950: 5f 4f 4b 20 29 20 7b 0a 20 20 20 20 69 66 28 20  _OK ) {.    if( 
6960: 62 69 6e 64 41 72 67 5a 65 72 6f 20 29 7b 0a 20  bindArgZero ){. 
6970: 20 20 20 20 20 73 71 6c 69 74 65 33 5f 62 69 6e       sqlite3_bin
6980: 64 5f 76 61 6c 75 65 28 70 53 74 6d 74 2c 20 6e  d_value(pStmt, n
6990: 44 61 74 61 2c 20 61 70 44 61 74 61 5b 30 5d 29  Data, apData[0])
69a0: 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 28 20  ;.    }.    if( 
69b0: 62 69 6e 64 41 72 67 4f 6e 65 20 29 7b 0a 20 20  bindArgOne ){.  
69c0: 20 20 20 20 73 71 6c 69 74 65 33 5f 62 69 6e 64      sqlite3_bind
69d0: 5f 76 61 6c 75 65 28 70 53 74 6d 74 2c 20 31 2c  _value(pStmt, 1,
69e0: 20 61 70 44 61 74 61 5b 31 5d 29 3b 0a 20 20 20   apData[1]);.   
69f0: 20 7d 0a 20 20 20 20 66 6f 72 28 69 3d 32 3b 20   }.    for(i=2; 
6a00: 69 3c 6e 44 61 74 61 20 26 26 20 72 63 3d 3d 53  i<nData && rc==S
6a10: 51 4c 49 54 45 5f 4f 4b 3b 20 69 2b 2b 29 7b 0a  QLITE_OK; i++){.
6a20: 20 20 20 20 20 20 69 66 28 20 61 70 44 61 74 61        if( apData
6a30: 5b 69 5d 20 29 20 72 63 20 3d 20 73 71 6c 69 74  [i] ) rc = sqlit
6a40: 65 33 5f 62 69 6e 64 5f 76 61 6c 75 65 28 70 53  e3_bind_value(pS
6a50: 74 6d 74 2c 20 69 2c 20 61 70 44 61 74 61 5b 69  tmt, i, apData[i
6a60: 5d 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69 66  ]);.    }.    if
6a70: 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
6a80: 29 7b 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33  ){.      sqlite3
6a90: 5f 73 74 65 70 28 70 53 74 6d 74 29 3b 0a 20 20  _step(pStmt);.  
6aa0: 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33      rc = sqlite3
6ab0: 5f 66 69 6e 61 6c 69 7a 65 28 70 53 74 6d 74 29  _finalize(pStmt)
6ac0: 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20  ;.    }else{.   
6ad0: 20 20 20 73 71 6c 69 74 65 33 5f 66 69 6e 61 6c     sqlite3_final
6ae0: 69 7a 65 28 70 53 74 6d 74 29 3b 0a 20 20 20 20  ize(pStmt);.    
6af0: 7d 0a 20 20 7d 0a 0a 20 20 69 66 28 20 70 52 6f  }.  }..  if( pRo
6b00: 77 69 64 20 26 26 20 72 63 3d 3d 53 51 4c 49 54  wid && rc==SQLIT
6b10: 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 2a 70 52 6f  E_OK ){.    *pRo
6b20: 77 69 64 20 3d 20 73 71 6c 69 74 65 33 5f 6c 61  wid = sqlite3_la
6b30: 73 74 5f 69 6e 73 65 72 74 5f 72 6f 77 69 64 28  st_insert_rowid(
6b40: 64 62 29 3b 0a 20 20 7d 0a 0a 20 20 72 65 74 75  db);.  }..  retu
6b50: 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  rn rc;.}../*.** 
6b60: 78 42 65 67 69 6e 2c 20 78 53 79 6e 63 2c 20 78  xBegin, xSync, x
6b70: 43 6f 6d 6d 69 74 20 61 6e 64 20 78 52 6f 6c 6c  Commit and xRoll
6b80: 62 61 63 6b 20 63 61 6c 6c 62 61 63 6b 73 20 66  back callbacks f
6b90: 6f 72 20 65 63 68 6f 20 6d 6f 64 75 6c 65 0a 2a  or echo module.*
6ba0: 2a 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65 73  * virtual tables
6bb0: 2e 20 44 6f 20 6e 6f 74 68 69 6e 67 20 6f 74 68  . Do nothing oth
6bc0: 65 72 20 74 68 61 6e 20 61 64 64 20 74 68 65 20  er than add the 
6bd0: 6e 61 6d 65 20 6f 66 20 74 68 65 20 63 61 6c 6c  name of the call
6be0: 62 61 63 6b 0a 2a 2a 20 74 6f 20 74 68 65 20 24  back.** to the $
6bf0: 3a 3a 65 63 68 6f 5f 6d 6f 64 75 6c 65 20 54 63  ::echo_module Tc
6c00: 6c 20 76 61 72 69 61 62 6c 65 2e 0a 2a 2f 0a 73  l variable..*/.s
6c10: 74 61 74 69 63 20 69 6e 74 20 65 63 68 6f 54 72  tatic int echoTr
6c20: 61 6e 73 61 63 74 69 6f 6e 43 61 6c 6c 28 73 71  ansactionCall(sq
6c30: 6c 69 74 65 33 5f 76 74 61 62 20 2a 74 61 62 2c  lite3_vtab *tab,
6c40: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 43 61   const char *zCa
6c50: 6c 6c 29 7b 0a 20 20 63 68 61 72 20 2a 7a 3b 0a  ll){.  char *z;.
6c60: 20 20 65 63 68 6f 5f 76 74 61 62 20 2a 70 56 74    echo_vtab *pVt
6c70: 61 62 20 3d 20 28 65 63 68 6f 5f 76 74 61 62 20  ab = (echo_vtab 
6c80: 2a 29 74 61 62 3b 0a 20 20 7a 20 3d 20 73 71 6c  *)tab;.  z = sql
6c90: 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 22 65 63  ite3_mprintf("ec
6ca0: 68 6f 28 25 73 29 22 2c 20 70 56 74 61 62 2d 3e  ho(%s)", pVtab->
6cb0: 7a 54 61 62 6c 65 4e 61 6d 65 29 3b 0a 20 20 61  zTableName);.  a
6cc0: 70 70 65 6e 64 54 6f 45 63 68 6f 4d 6f 64 75 6c  ppendToEchoModul
6cd0: 65 28 70 56 74 61 62 2d 3e 69 6e 74 65 72 70 2c  e(pVtab->interp,
6ce0: 20 7a 43 61 6c 6c 29 3b 0a 20 20 61 70 70 65 6e   zCall);.  appen
6cf0: 64 54 6f 45 63 68 6f 4d 6f 64 75 6c 65 28 70 56  dToEchoModule(pV
6d00: 74 61 62 2d 3e 69 6e 74 65 72 70 2c 20 7a 29 3b  tab->interp, z);
6d10: 0a 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28  .  sqlite3_free(
6d20: 7a 29 3b 0a 20 20 72 65 74 75 72 6e 20 28 7a 3f  z);.  return (z?
6d30: 53 51 4c 49 54 45 5f 4f 4b 3a 53 51 4c 49 54 45  SQLITE_OK:SQLITE
6d40: 5f 4e 4f 4d 45 4d 29 3b 0a 7d 0a 73 74 61 74 69  _NOMEM);.}.stati
6d50: 63 20 69 6e 74 20 65 63 68 6f 42 65 67 69 6e 28  c int echoBegin(
6d60: 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 74 61  sqlite3_vtab *ta
6d70: 62 29 7b 0a 20 20 69 6e 74 20 72 63 3b 0a 20 20  b){.  int rc;.  
6d80: 65 63 68 6f 5f 76 74 61 62 20 2a 70 56 74 61 62  echo_vtab *pVtab
6d90: 20 3d 20 28 65 63 68 6f 5f 76 74 61 62 20 2a 29   = (echo_vtab *)
6da0: 74 61 62 3b 0a 20 20 54 63 6c 5f 49 6e 74 65 72  tab;.  Tcl_Inter
6db0: 70 20 2a 69 6e 74 65 72 70 20 3d 20 70 56 74 61  p *interp = pVta
6dc0: 62 2d 3e 69 6e 74 65 72 70 3b 0a 20 20 63 6f 6e  b->interp;.  con
6dd0: 73 74 20 63 68 61 72 20 2a 7a 56 61 6c 3b 20 0a  st char *zVal; .
6de0: 0a 20 20 72 63 20 3d 20 65 63 68 6f 54 72 61 6e  .  rc = echoTran
6df0: 73 61 63 74 69 6f 6e 43 61 6c 6c 28 74 61 62 2c  sactionCall(tab,
6e00: 20 22 78 42 65 67 69 6e 22 29 3b 0a 0a 20 20 69   "xBegin");..  i
6e10: 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc==SQLITE_OK
6e20: 20 29 7b 0a 20 20 20 20 2f 2a 20 43 68 65 63 6b   ){.    /* Check
6e30: 20 69 66 20 74 68 65 20 24 3a 3a 65 63 68 6f 5f   if the $::echo_
6e40: 6d 6f 64 75 6c 65 5f 62 65 67 69 6e 5f 66 61 69  module_begin_fai
6e50: 6c 20 76 61 72 69 61 62 6c 65 20 69 73 20 64 65  l variable is de
6e60: 66 69 6e 65 64 2e 20 49 66 20 69 74 20 69 73 2c  fined. If it is,
6e70: 0a 20 20 20 20 2a 2a 20 61 6e 64 20 69 74 20 69  .    ** and it i
6e80: 73 20 73 65 74 20 74 6f 20 74 68 65 20 6e 61 6d  s set to the nam
6e90: 65 20 6f 66 20 74 68 65 20 72 65 61 6c 20 74 61  e of the real ta
6ea0: 62 6c 65 20 75 6e 64 65 72 6c 79 69 6e 67 20 74  ble underlying t
6eb0: 68 69 73 20 76 69 72 74 75 61 6c 0a 20 20 20 20  his virtual.    
6ec0: 2a 2a 20 65 63 68 6f 20 6d 6f 64 75 6c 65 20 74  ** echo module t
6ed0: 61 62 6c 65 2c 20 74 68 65 6e 20 63 61 75 73 65  able, then cause
6ee0: 20 74 68 69 73 20 78 53 79 6e 63 20 6f 70 65 72   this xSync oper
6ef0: 61 74 69 6f 6e 20 74 6f 20 66 61 69 6c 2e 0a 20  ation to fail.. 
6f00: 20 20 20 2a 2f 0a 20 20 20 20 7a 56 61 6c 20 3d     */.    zVal =
6f10: 20 54 63 6c 5f 47 65 74 56 61 72 28 69 6e 74 65   Tcl_GetVar(inte
6f20: 72 70 2c 20 22 65 63 68 6f 5f 6d 6f 64 75 6c 65  rp, "echo_module
6f30: 5f 62 65 67 69 6e 5f 66 61 69 6c 22 2c 20 54 43  _begin_fail", TC
6f40: 4c 5f 47 4c 4f 42 41 4c 5f 4f 4e 4c 59 29 3b 0a  L_GLOBAL_ONLY);.
6f50: 20 20 20 20 69 66 28 20 7a 56 61 6c 20 26 26 20      if( zVal && 
6f60: 30 3d 3d 73 74 72 63 6d 70 28 7a 56 61 6c 2c 20  0==strcmp(zVal, 
6f70: 70 56 74 61 62 2d 3e 7a 54 61 62 6c 65 4e 61 6d  pVtab->zTableNam
6f80: 65 29 20 29 7b 0a 20 20 20 20 20 20 72 63 20 3d  e) ){.      rc =
6f90: 20 53 51 4c 49 54 45 5f 45 52 52 4f 52 3b 0a 20   SQLITE_ERROR;. 
6fa0: 20 20 20 7d 0a 20 20 7d 0a 20 20 72 65 74 75 72     }.  }.  retur
6fb0: 6e 20 72 63 3b 0a 7d 0a 73 74 61 74 69 63 20 69  n rc;.}.static i
6fc0: 6e 74 20 65 63 68 6f 53 79 6e 63 28 73 71 6c 69  nt echoSync(sqli
6fd0: 74 65 33 5f 76 74 61 62 20 2a 74 61 62 29 7b 0a  te3_vtab *tab){.
6fe0: 20 20 69 6e 74 20 72 63 3b 0a 20 20 65 63 68 6f    int rc;.  echo
6ff0: 5f 76 74 61 62 20 2a 70 56 74 61 62 20 3d 20 28  _vtab *pVtab = (
7000: 65 63 68 6f 5f 76 74 61 62 20 2a 29 74 61 62 3b  echo_vtab *)tab;
7010: 0a 20 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69  .  Tcl_Interp *i
7020: 6e 74 65 72 70 20 3d 20 70 56 74 61 62 2d 3e 69  nterp = pVtab->i
7030: 6e 74 65 72 70 3b 0a 20 20 63 6f 6e 73 74 20 63  nterp;.  const c
7040: 68 61 72 20 2a 7a 56 61 6c 3b 20 0a 0a 20 20 72  har *zVal; ..  r
7050: 63 20 3d 20 65 63 68 6f 54 72 61 6e 73 61 63 74  c = echoTransact
7060: 69 6f 6e 43 61 6c 6c 28 74 61 62 2c 20 22 78 53  ionCall(tab, "xS
7070: 79 6e 63 22 29 3b 0a 0a 20 20 69 66 28 20 72 63  ync");..  if( rc
7080: 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  ==SQLITE_OK ){. 
7090: 20 20 20 2f 2a 20 43 68 65 63 6b 20 69 66 20 74     /* Check if t
70a0: 68 65 20 24 3a 3a 65 63 68 6f 5f 6d 6f 64 75 6c  he $::echo_modul
70b0: 65 5f 73 79 6e 63 5f 66 61 69 6c 20 76 61 72 69  e_sync_fail vari
70c0: 61 62 6c 65 20 69 73 20 64 65 66 69 6e 65 64 2e  able is defined.
70d0: 20 49 66 20 69 74 20 69 73 2c 0a 20 20 20 20 2a   If it is,.    *
70e0: 2a 20 61 6e 64 20 69 74 20 69 73 20 73 65 74 20  * and it is set 
70f0: 74 6f 20 74 68 65 20 6e 61 6d 65 20 6f 66 20 74  to the name of t
7100: 68 65 20 72 65 61 6c 20 74 61 62 6c 65 20 75 6e  he real table un
7110: 64 65 72 6c 79 69 6e 67 20 74 68 69 73 20 76 69  derlying this vi
7120: 72 74 75 61 6c 0a 20 20 20 20 2a 2a 20 65 63 68  rtual.    ** ech
7130: 6f 20 6d 6f 64 75 6c 65 20 74 61 62 6c 65 2c 20  o module table, 
7140: 74 68 65 6e 20 63 61 75 73 65 20 74 68 69 73 20  then cause this 
7150: 78 53 79 6e 63 20 6f 70 65 72 61 74 69 6f 6e 20  xSync operation 
7160: 74 6f 20 66 61 69 6c 2e 0a 20 20 20 20 2a 2f 0a  to fail..    */.
7170: 20 20 20 20 7a 56 61 6c 20 3d 20 54 63 6c 5f 47      zVal = Tcl_G
7180: 65 74 56 61 72 28 69 6e 74 65 72 70 2c 20 22 65  etVar(interp, "e
7190: 63 68 6f 5f 6d 6f 64 75 6c 65 5f 73 79 6e 63 5f  cho_module_sync_
71a0: 66 61 69 6c 22 2c 20 54 43 4c 5f 47 4c 4f 42 41  fail", TCL_GLOBA
71b0: 4c 5f 4f 4e 4c 59 29 3b 0a 20 20 20 20 69 66 28  L_ONLY);.    if(
71c0: 20 7a 56 61 6c 20 26 26 20 30 3d 3d 73 74 72 63   zVal && 0==strc
71d0: 6d 70 28 7a 56 61 6c 2c 20 70 56 74 61 62 2d 3e  mp(zVal, pVtab->
71e0: 7a 54 61 62 6c 65 4e 61 6d 65 29 20 29 7b 0a 20  zTableName) ){. 
71f0: 20 20 20 20 20 72 63 20 3d 20 2d 31 3b 0a 20 20       rc = -1;.  
7200: 20 20 7d 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e    }.  }.  return
7210: 20 72 63 3b 0a 7d 0a 73 74 61 74 69 63 20 69 6e   rc;.}.static in
7220: 74 20 65 63 68 6f 43 6f 6d 6d 69 74 28 73 71 6c  t echoCommit(sql
7230: 69 74 65 33 5f 76 74 61 62 20 2a 74 61 62 29 7b  ite3_vtab *tab){
7240: 0a 20 20 69 6e 74 20 72 63 3b 0a 20 20 73 71 6c  .  int rc;.  sql
7250: 69 74 65 33 46 61 75 6c 74 42 65 6e 69 67 6e 28  ite3FaultBenign(
7260: 53 51 4c 49 54 45 5f 46 41 55 4c 54 49 4e 4a 45  SQLITE_FAULTINJE
7270: 43 54 4f 52 5f 4d 41 4c 4c 4f 43 2c 20 31 29 3b  CTOR_MALLOC, 1);
7280: 0a 20 20 72 63 20 3d 20 65 63 68 6f 54 72 61 6e  .  rc = echoTran
7290: 73 61 63 74 69 6f 6e 43 61 6c 6c 28 74 61 62 2c  sactionCall(tab,
72a0: 20 22 78 43 6f 6d 6d 69 74 22 29 3b 0a 20 20 73   "xCommit");.  s
72b0: 71 6c 69 74 65 33 46 61 75 6c 74 42 65 6e 69 67  qlite3FaultBenig
72c0: 6e 28 53 51 4c 49 54 45 5f 46 41 55 4c 54 49 4e  n(SQLITE_FAULTIN
72d0: 4a 45 43 54 4f 52 5f 4d 41 4c 4c 4f 43 2c 20 30  JECTOR_MALLOC, 0
72e0: 29 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a  );.  return rc;.
72f0: 7d 0a 73 74 61 74 69 63 20 69 6e 74 20 65 63 68  }.static int ech
7300: 6f 52 6f 6c 6c 62 61 63 6b 28 73 71 6c 69 74 65  oRollback(sqlite
7310: 33 5f 76 74 61 62 20 2a 74 61 62 29 7b 0a 20 20  3_vtab *tab){.  
7320: 72 65 74 75 72 6e 20 65 63 68 6f 54 72 61 6e 73  return echoTrans
7330: 61 63 74 69 6f 6e 43 61 6c 6c 28 74 61 62 2c 20  actionCall(tab, 
7340: 22 78 52 6f 6c 6c 62 61 63 6b 22 29 3b 0a 7d 0a  "xRollback");.}.
7350: 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74  ./*.** Implement
7360: 61 74 69 6f 6e 20 6f 66 20 22 47 4c 4f 42 22 20  ation of "GLOB" 
7370: 66 75 6e 63 74 69 6f 6e 20 6f 6e 20 74 68 65 20  function on the 
7380: 65 63 68 6f 20 6d 6f 64 75 6c 65 2e 20 20 50 61  echo module.  Pa
7390: 73 73 0a 2a 2a 20 61 6c 6c 20 61 72 67 75 6d 65  ss.** all argume
73a0: 6e 74 73 20 74 6f 20 74 68 65 20 3a 3a 65 63 68  nts to the ::ech
73b0: 6f 5f 67 6c 6f 62 5f 6f 76 65 72 6c 6f 61 64 20  o_glob_overload 
73c0: 70 72 6f 63 65 64 75 72 65 20 6f 66 20 54 43 4c  procedure of TCL
73d0: 0a 2a 2a 20 61 6e 64 20 72 65 74 75 72 6e 20 74  .** and return t
73e0: 68 65 20 72 65 73 75 6c 74 20 6f 66 20 74 68 61  he result of tha
73f0: 74 20 70 72 6f 63 65 64 75 72 65 20 61 73 20 61  t procedure as a
7400: 20 73 74 72 69 6e 67 2e 0a 2a 2f 0a 73 74 61 74   string..*/.stat
7410: 69 63 20 76 6f 69 64 20 6f 76 65 72 6c 6f 61 64  ic void overload
7420: 65 64 47 6c 6f 62 46 75 6e 63 74 69 6f 6e 28 0a  edGlobFunction(.
7430: 20 20 73 71 6c 69 74 65 33 5f 63 6f 6e 74 65 78    sqlite3_contex
7440: 74 20 2a 70 43 6f 6e 74 65 78 74 2c 0a 20 20 69  t *pContext,.  i
7450: 6e 74 20 6e 41 72 67 2c 0a 20 20 73 71 6c 69 74  nt nArg,.  sqlit
7460: 65 33 5f 76 61 6c 75 65 20 2a 2a 61 70 41 72 67  e3_value **apArg
7470: 0a 29 7b 0a 20 20 54 63 6c 5f 49 6e 74 65 72 70  .){.  Tcl_Interp
7480: 20 2a 69 6e 74 65 72 70 20 3d 20 73 71 6c 69 74   *interp = sqlit
7490: 65 33 5f 75 73 65 72 5f 64 61 74 61 28 70 43 6f  e3_user_data(pCo
74a0: 6e 74 65 78 74 29 3b 0a 20 20 54 63 6c 5f 44 53  ntext);.  Tcl_DS
74b0: 74 72 69 6e 67 20 73 74 72 3b 0a 20 20 69 6e 74  tring str;.  int
74c0: 20 69 3b 0a 20 20 69 6e 74 20 72 63 3b 0a 20 20   i;.  int rc;.  
74d0: 54 63 6c 5f 44 53 74 72 69 6e 67 49 6e 69 74 28  Tcl_DStringInit(
74e0: 26 73 74 72 29 3b 0a 20 20 54 63 6c 5f 44 53 74  &str);.  Tcl_DSt
74f0: 72 69 6e 67 41 70 70 65 6e 64 45 6c 65 6d 65 6e  ringAppendElemen
7500: 74 28 26 73 74 72 2c 20 22 3a 3a 65 63 68 6f 5f  t(&str, "::echo_
7510: 67 6c 6f 62 5f 6f 76 65 72 6c 6f 61 64 22 29 3b  glob_overload");
7520: 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 6e 41  .  for(i=0; i<nA
7530: 72 67 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 54 63  rg; i++){.    Tc
7540: 6c 5f 44 53 74 72 69 6e 67 41 70 70 65 6e 64 45  l_DStringAppendE
7550: 6c 65 6d 65 6e 74 28 26 73 74 72 2c 20 28 63 68  lement(&str, (ch
7560: 61 72 2a 29 73 71 6c 69 74 65 33 5f 76 61 6c 75  ar*)sqlite3_valu
7570: 65 5f 74 65 78 74 28 61 70 41 72 67 5b 69 5d 29  e_text(apArg[i])
7580: 29 3b 0a 20 20 7d 0a 20 20 72 63 20 3d 20 54 63  );.  }.  rc = Tc
7590: 6c 5f 45 76 61 6c 28 69 6e 74 65 72 70 2c 20 54  l_Eval(interp, T
75a0: 63 6c 5f 44 53 74 72 69 6e 67 56 61 6c 75 65 28  cl_DStringValue(
75b0: 26 73 74 72 29 29 3b 0a 20 20 54 63 6c 5f 44 53  &str));.  Tcl_DS
75c0: 74 72 69 6e 67 46 72 65 65 28 26 73 74 72 29 3b  tringFree(&str);
75d0: 0a 20 20 69 66 28 20 72 63 20 29 7b 0a 20 20 20  .  if( rc ){.   
75e0: 20 73 71 6c 69 74 65 33 5f 72 65 73 75 6c 74 5f   sqlite3_result_
75f0: 65 72 72 6f 72 28 70 43 6f 6e 74 65 78 74 2c 20  error(pContext, 
7600: 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73  Tcl_GetStringRes
7610: 75 6c 74 28 69 6e 74 65 72 70 29 2c 20 2d 31 29  ult(interp), -1)
7620: 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 73  ;.  }else{.    s
7630: 71 6c 69 74 65 33 5f 72 65 73 75 6c 74 5f 74 65  qlite3_result_te
7640: 78 74 28 70 43 6f 6e 74 65 78 74 2c 20 54 63 6c  xt(pContext, Tcl
7650: 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74  _GetStringResult
7660: 28 69 6e 74 65 72 70 29 2c 0a 20 20 20 20 20 20  (interp),.      
7670: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7680: 20 20 2d 31 2c 20 53 51 4c 49 54 45 5f 54 52 41    -1, SQLITE_TRA
7690: 4e 53 49 45 4e 54 29 3b 0a 20 20 7d 0a 20 20 54  NSIENT);.  }.  T
76a0: 63 6c 5f 52 65 73 65 74 52 65 73 75 6c 74 28 69  cl_ResetResult(i
76b0: 6e 74 65 72 70 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  nterp);.}../*.**
76c0: 20 54 68 69 73 20 69 73 20 74 68 65 20 78 46 69   This is the xFi
76d0: 6e 64 46 75 6e 63 74 69 6f 6e 20 69 6d 70 6c 65  ndFunction imple
76e0: 6d 65 6e 74 61 74 69 6f 6e 20 66 6f 72 20 74 68  mentation for th
76f0: 65 20 65 63 68 6f 20 6d 6f 64 75 6c 65 2e 0a 2a  e echo module..*
7700: 2a 20 53 51 4c 69 74 65 20 63 61 6c 6c 73 20 74  * SQLite calls t
7710: 68 69 73 20 72 6f 75 74 69 6e 65 20 77 68 65 6e  his routine when
7720: 20 74 68 65 20 66 69 72 73 74 20 61 72 67 75 6d   the first argum
7730: 65 6e 74 20 6f 66 20 61 20 66 75 6e 63 74 69 6f  ent of a functio
7740: 6e 0a 2a 2a 20 69 73 20 61 20 63 6f 6c 75 6d 6e  n.** is a column
7750: 20 6f 66 20 61 6e 20 65 63 68 6f 20 76 69 72 74   of an echo virt
7760: 75 61 6c 20 74 61 62 6c 65 2e 20 20 54 68 69 73  ual table.  This
7770: 20 72 6f 75 74 69 6e 65 20 63 61 6e 20 6f 70 74   routine can opt
7780: 69 6f 6e 61 6c 6c 79 0a 2a 2a 20 6f 76 65 72 72  ionally.** overr
7790: 69 64 65 20 74 68 65 20 69 6d 70 6c 65 6d 65 6e  ide the implemen
77a0: 74 61 74 69 6f 6e 20 6f 66 20 74 68 61 74 20 66  tation of that f
77b0: 75 6e 63 74 69 6f 6e 2e 20 20 49 74 20 77 69 6c  unction.  It wil
77c0: 6c 20 63 68 6f 6f 73 65 20 74 6f 0a 2a 2a 20 64  l choose to.** d
77d0: 6f 20 73 6f 20 69 66 20 74 68 65 20 66 75 6e 63  o so if the func
77e0: 74 69 6f 6e 20 69 73 20 6e 61 6d 65 64 20 22 67  tion is named "g
77f0: 6c 6f 62 22 2c 20 61 6e 64 20 61 20 54 43 4c 20  lob", and a TCL 
7800: 63 6f 6d 6d 61 6e 64 20 6e 61 6d 65 64 0a 2a 2a  command named.**
7810: 20 3a 3a 65 63 68 6f 5f 67 6c 6f 62 5f 6f 76 65   ::echo_glob_ove
7820: 72 6c 6f 61 64 20 65 78 69 73 74 73 2e 0a 2a 2f  rload exists..*/
7830: 0a 73 74 61 74 69 63 20 69 6e 74 20 65 63 68 6f  .static int echo
7840: 46 69 6e 64 46 75 6e 63 74 69 6f 6e 28 0a 20 20  FindFunction(.  
7850: 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 76 74  sqlite3_vtab *vt
7860: 61 62 2c 0a 20 20 69 6e 74 20 6e 41 72 67 2c 0a  ab,.  int nArg,.
7870: 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 46    const char *zF
7880: 75 6e 63 4e 61 6d 65 2c 0a 20 20 76 6f 69 64 20  uncName,.  void 
7890: 28 2a 2a 70 78 46 75 6e 63 29 28 73 71 6c 69 74  (**pxFunc)(sqlit
78a0: 65 33 5f 63 6f 6e 74 65 78 74 2a 2c 69 6e 74 2c  e3_context*,int,
78b0: 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 2a 2a 29  sqlite3_value**)
78c0: 2c 0a 20 20 76 6f 69 64 20 2a 2a 70 70 41 72 67  ,.  void **ppArg
78d0: 0a 29 7b 0a 20 20 65 63 68 6f 5f 76 74 61 62 20  .){.  echo_vtab 
78e0: 2a 70 56 74 61 62 20 3d 20 28 65 63 68 6f 5f 76  *pVtab = (echo_v
78f0: 74 61 62 20 2a 29 76 74 61 62 3b 0a 20 20 54 63  tab *)vtab;.  Tc
7900: 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70  l_Interp *interp
7910: 20 3d 20 70 56 74 61 62 2d 3e 69 6e 74 65 72 70   = pVtab->interp
7920: 3b 0a 20 20 54 63 6c 5f 43 6d 64 49 6e 66 6f 20  ;.  Tcl_CmdInfo 
7930: 69 6e 66 6f 3b 0a 20 20 69 66 28 20 73 74 72 63  info;.  if( strc
7940: 6d 70 28 7a 46 75 6e 63 4e 61 6d 65 2c 22 67 6c  mp(zFuncName,"gl
7950: 6f 62 22 29 21 3d 30 20 29 7b 0a 20 20 20 20 72  ob")!=0 ){.    r
7960: 65 74 75 72 6e 20 30 3b 0a 20 20 7d 0a 20 20 69  eturn 0;.  }.  i
7970: 66 28 20 54 63 6c 5f 47 65 74 43 6f 6d 6d 61 6e  f( Tcl_GetComman
7980: 64 49 6e 66 6f 28 69 6e 74 65 72 70 2c 20 22 3a  dInfo(interp, ":
7990: 3a 65 63 68 6f 5f 67 6c 6f 62 5f 6f 76 65 72 6c  :echo_glob_overl
79a0: 6f 61 64 22 2c 20 26 69 6e 66 6f 29 3d 3d 30 20  oad", &info)==0 
79b0: 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 30 3b  ){.    return 0;
79c0: 0a 20 20 7d 0a 20 20 2a 70 78 46 75 6e 63 20 3d  .  }.  *pxFunc =
79d0: 20 6f 76 65 72 6c 6f 61 64 65 64 47 6c 6f 62 46   overloadedGlobF
79e0: 75 6e 63 74 69 6f 6e 3b 0a 20 20 2a 70 70 41 72  unction;.  *ppAr
79f0: 67 20 3d 20 69 6e 74 65 72 70 3b 0a 20 20 72 65  g = interp;.  re
7a00: 74 75 72 6e 20 31 3b 0a 7d 0a 0a 73 74 61 74 69  turn 1;.}..stati
7a10: 63 20 69 6e 74 20 65 63 68 6f 52 65 6e 61 6d 65  c int echoRename
7a20: 28 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 76  (sqlite3_vtab *v
7a30: 74 61 62 2c 20 63 6f 6e 73 74 20 63 68 61 72 20  tab, const char 
7a40: 2a 7a 4e 65 77 4e 61 6d 65 29 7b 0a 20 20 69 6e  *zNewName){.  in
7a50: 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b  t rc = SQLITE_OK
7a60: 3b 0a 20 20 65 63 68 6f 5f 76 74 61 62 20 2a 70  ;.  echo_vtab *p
7a70: 20 3d 20 28 65 63 68 6f 5f 76 74 61 62 20 2a 29   = (echo_vtab *)
7a80: 76 74 61 62 3b 0a 0a 20 20 69 66 28 20 70 2d 3e  vtab;..  if( p->
7a90: 69 73 50 61 74 74 65 72 6e 20 29 7b 0a 20 20 20  isPattern ){.   
7aa0: 20 69 6e 74 20 6e 54 68 69 73 20 3d 20 73 74 72   int nThis = str
7ab0: 6c 65 6e 28 70 2d 3e 7a 54 68 69 73 29 3b 0a 20  len(p->zThis);. 
7ac0: 20 20 20 63 68 61 72 20 2a 7a 53 71 6c 20 3d 20     char *zSql = 
7ad0: 73 71 6c 69 74 65 33 4d 50 72 69 6e 74 66 28 30  sqlite3MPrintf(0
7ae0: 2c 20 22 41 4c 54 45 52 20 54 41 42 4c 45 20 25  , "ALTER TABLE %
7af0: 73 20 52 45 4e 41 4d 45 20 54 4f 20 25 73 25 73  s RENAME TO %s%s
7b00: 22 2c 20 0a 20 20 20 20 20 20 20 20 70 2d 3e 7a  ", .        p->z
7b10: 54 61 62 6c 65 4e 61 6d 65 2c 20 7a 4e 65 77 4e  TableName, zNewN
7b20: 61 6d 65 2c 20 26 70 2d 3e 7a 54 61 62 6c 65 4e  ame, &p->zTableN
7b30: 61 6d 65 5b 6e 54 68 69 73 5d 0a 20 20 20 20 29  ame[nThis].    )
7b40: 3b 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74  ;.    rc = sqlit
7b50: 65 33 5f 65 78 65 63 28 70 2d 3e 64 62 2c 20 7a  e3_exec(p->db, z
7b60: 53 71 6c 2c 20 30 2c 20 30 2c 20 30 29 3b 0a 20  Sql, 0, 0, 0);. 
7b70: 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28     sqlite3_free(
7b80: 7a 53 71 6c 29 3b 0a 20 20 7d 0a 0a 20 20 72 65  zSql);.  }..  re
7b90: 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a  turn rc;.}../*.*
7ba0: 2a 20 41 20 76 69 72 74 75 61 6c 20 74 61 62 6c  * A virtual tabl
7bb0: 65 20 6d 6f 64 75 6c 65 20 74 68 61 74 20 6d 65  e module that me
7bc0: 72 65 6c 79 20 22 65 63 68 6f 73 22 20 74 68 65  rely "echos" the
7bd0: 20 63 6f 6e 74 65 6e 74 73 20 6f 66 20 61 6e 6f   contents of ano
7be0: 74 68 65 72 0a 2a 2a 20 74 61 62 6c 65 20 28 6c  ther.** table (l
7bf0: 69 6b 65 20 61 6e 20 53 51 4c 20 56 49 45 57 29  ike an SQL VIEW)
7c00: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 73 71 6c 69  ..*/.static sqli
7c10: 74 65 33 5f 6d 6f 64 75 6c 65 20 65 63 68 6f 4d  te3_module echoM
7c20: 6f 64 75 6c 65 20 3d 20 7b 0a 20 20 30 2c 20 20  odule = {.  0,  
7c30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7c40: 20 20 20 20 20 20 20 2f 2a 20 69 56 65 72 73 69         /* iVersi
7c50: 6f 6e 20 2a 2f 0a 20 20 65 63 68 6f 43 72 65 61  on */.  echoCrea
7c60: 74 65 2c 0a 20 20 65 63 68 6f 43 6f 6e 6e 65 63  te,.  echoConnec
7c70: 74 2c 0a 20 20 65 63 68 6f 42 65 73 74 49 6e 64  t,.  echoBestInd
7c80: 65 78 2c 0a 20 20 65 63 68 6f 44 69 73 63 6f 6e  ex,.  echoDiscon
7c90: 6e 65 63 74 2c 20 0a 20 20 65 63 68 6f 44 65 73  nect, .  echoDes
7ca0: 74 72 6f 79 2c 0a 20 20 65 63 68 6f 4f 70 65 6e  troy,.  echoOpen
7cb0: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
7cc0: 20 20 20 2f 2a 20 78 4f 70 65 6e 20 2d 20 6f 70     /* xOpen - op
7cd0: 65 6e 20 61 20 63 75 72 73 6f 72 20 2a 2f 0a 20  en a cursor */. 
7ce0: 20 65 63 68 6f 43 6c 6f 73 65 2c 20 20 20 20 20   echoClose,     
7cf0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78              /* x
7d00: 43 6c 6f 73 65 20 2d 20 63 6c 6f 73 65 20 61 20  Close - close a 
7d10: 63 75 72 73 6f 72 20 2a 2f 0a 20 20 65 63 68 6f  cursor */.  echo
7d20: 46 69 6c 74 65 72 2c 20 20 20 20 20 20 20 20 20  Filter,         
7d30: 20 20 20 20 20 20 20 2f 2a 20 78 46 69 6c 74 65         /* xFilte
7d40: 72 20 2d 20 63 6f 6e 66 69 67 75 72 65 20 73 63  r - configure sc
7d50: 61 6e 20 63 6f 6e 73 74 72 61 69 6e 74 73 20 2a  an constraints *
7d60: 2f 0a 20 20 65 63 68 6f 4e 65 78 74 2c 20 20 20  /.  echoNext,   
7d70: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
7d80: 2a 20 78 4e 65 78 74 20 2d 20 61 64 76 61 6e 63  * xNext - advanc
7d90: 65 20 61 20 63 75 72 73 6f 72 20 2a 2f 0a 20 20  e a cursor */.  
7da0: 65 63 68 6f 45 6f 66 2c 20 20 20 20 20 20 20 20  echoEof,        
7db0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 45             /* xE
7dc0: 6f 66 20 2a 2f 0a 20 20 65 63 68 6f 43 6f 6c 75  of */.  echoColu
7dd0: 6d 6e 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  mn,             
7de0: 20 20 20 2f 2a 20 78 43 6f 6c 75 6d 6e 20 2d 20     /* xColumn - 
7df0: 72 65 61 64 20 64 61 74 61 20 2a 2f 0a 20 20 65  read data */.  e
7e00: 63 68 6f 52 6f 77 69 64 2c 20 20 20 20 20 20 20  choRowid,       
7e10: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 52 6f            /* xRo
7e20: 77 69 64 20 2d 20 72 65 61 64 20 64 61 74 61 20  wid - read data 
7e30: 2a 2f 0a 20 20 65 63 68 6f 55 70 64 61 74 65 2c  */.  echoUpdate,
7e40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7e50: 2f 2a 20 78 55 70 64 61 74 65 20 2d 20 77 72 69  /* xUpdate - wri
7e60: 74 65 20 64 61 74 61 20 2a 2f 0a 20 20 65 63 68  te data */.  ech
7e70: 6f 42 65 67 69 6e 2c 20 20 20 20 20 20 20 20 20  oBegin,         
7e80: 20 20 20 20 20 20 20 20 2f 2a 20 78 42 65 67 69          /* xBegi
7e90: 6e 20 2d 20 62 65 67 69 6e 20 74 72 61 6e 73 61  n - begin transa
7ea0: 63 74 69 6f 6e 20 2a 2f 0a 20 20 65 63 68 6f 53  ction */.  echoS
7eb0: 79 6e 63 2c 20 20 20 20 20 20 20 20 20 20 20 20  ync,            
7ec0: 20 20 20 20 20 20 2f 2a 20 78 53 79 6e 63 20 2d        /* xSync -
7ed0: 20 73 79 6e 63 20 74 72 61 6e 73 61 63 74 69 6f   sync transactio
7ee0: 6e 20 2a 2f 0a 20 20 65 63 68 6f 43 6f 6d 6d 69  n */.  echoCommi
7ef0: 74 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  t,              
7f00: 20 20 2f 2a 20 78 43 6f 6d 6d 69 74 20 2d 20 63    /* xCommit - c
7f10: 6f 6d 6d 69 74 20 74 72 61 6e 73 61 63 74 69 6f  ommit transactio
7f20: 6e 20 2a 2f 0a 20 20 65 63 68 6f 52 6f 6c 6c 62  n */.  echoRollb
7f30: 61 63 6b 2c 20 20 20 20 20 20 20 20 20 20 20 20  ack,            
7f40: 20 20 2f 2a 20 78 52 6f 6c 6c 62 61 63 6b 20 2d    /* xRollback -
7f50: 20 72 6f 6c 6c 62 61 63 6b 20 74 72 61 6e 73 61   rollback transa
7f60: 63 74 69 6f 6e 20 2a 2f 0a 20 20 65 63 68 6f 46  ction */.  echoF
7f70: 69 6e 64 46 75 6e 63 74 69 6f 6e 2c 20 20 20 20  indFunction,    
7f80: 20 20 20 20 20 20 2f 2a 20 78 46 69 6e 64 46 75        /* xFindFu
7f90: 6e 63 74 69 6f 6e 20 2d 20 66 75 6e 63 74 69 6f  nction - functio
7fa0: 6e 20 6f 76 65 72 6c 6f 61 64 69 6e 67 20 2a 2f  n overloading */
7fb0: 0a 20 20 65 63 68 6f 52 65 6e 61 6d 65 2c 20 20  .  echoRename,  
7fc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
7fd0: 20 78 52 65 6e 61 6d 65 20 2d 20 72 65 6e 61 6d   xRename - renam
7fe0: 65 20 74 68 65 20 74 61 62 6c 65 20 2a 2f 0a 7d  e the table */.}
7ff0: 3b 0a 0a 2f 2a 0a 2a 2a 20 44 65 63 6f 64 65 20  ;../*.** Decode 
8000: 61 20 70 6f 69 6e 74 65 72 20 74 6f 20 61 6e 20  a pointer to an 
8010: 73 71 6c 69 74 65 33 20 6f 62 6a 65 63 74 2e 0a  sqlite3 object..
8020: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 67 65  */.static int ge
8030: 74 44 62 50 6f 69 6e 74 65 72 28 54 63 6c 5f 49  tDbPointer(Tcl_I
8040: 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 2c 20 63  nterp *interp, c
8050: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 41 2c 20 73  onst char *zA, s
8060: 71 6c 69 74 65 33 20 2a 2a 70 70 44 62 29 7b 0a  qlite3 **ppDb){.
8070: 20 20 2a 70 70 44 62 20 3d 20 28 73 71 6c 69 74    *ppDb = (sqlit
8080: 65 33 2a 29 73 71 6c 69 74 65 33 54 65 78 74 54  e3*)sqlite3TextT
8090: 6f 50 74 72 28 7a 41 29 3b 0a 20 20 72 65 74 75  oPtr(zA);.  retu
80a0: 72 6e 20 54 43 4c 5f 4f 4b 3b 0a 7d 0a 0a 73 74  rn TCL_OK;.}..st
80b0: 61 74 69 63 20 76 6f 69 64 20 6d 6f 64 75 6c 65  atic void module
80c0: 44 65 73 74 72 6f 79 28 76 6f 69 64 20 2a 70 29  Destroy(void *p)
80d0: 7b 0a 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65  {.  sqlite3_free
80e0: 28 70 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65  (p);.}../*.** Re
80f0: 67 69 73 74 65 72 20 74 68 65 20 65 63 68 6f 20  gister the echo 
8100: 76 69 72 74 75 61 6c 20 74 61 62 6c 65 20 6d 6f  virtual table mo
8110: 64 75 6c 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  dule..*/.static 
8120: 69 6e 74 20 72 65 67 69 73 74 65 72 5f 65 63 68  int register_ech
8130: 6f 5f 6d 6f 64 75 6c 65 28 0a 20 20 43 6c 69 65  o_module(.  Clie
8140: 6e 74 44 61 74 61 20 63 6c 69 65 6e 74 44 61 74  ntData clientDat
8150: 61 2c 20 2f 2a 20 50 6f 69 6e 74 65 72 20 74 6f  a, /* Pointer to
8160: 20 73 71 6c 69 74 65 33 5f 65 6e 61 62 6c 65 5f   sqlite3_enable_
8170: 58 58 58 20 66 75 6e 63 74 69 6f 6e 20 2a 2f 0a  XXX function */.
8180: 20 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e    Tcl_Interp *in
8190: 74 65 72 70 2c 20 20 20 20 2f 2a 20 54 68 65 20  terp,    /* The 
81a0: 54 43 4c 20 69 6e 74 65 72 70 72 65 74 65 72 20  TCL interpreter 
81b0: 74 68 61 74 20 69 6e 76 6f 6b 65 64 20 74 68 69  that invoked thi
81c0: 73 20 63 6f 6d 6d 61 6e 64 20 2a 2f 0a 20 20 69  s command */.  i
81d0: 6e 74 20 6f 62 6a 63 2c 20 20 20 20 20 20 20 20  nt objc,        
81e0: 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20        /* Number 
81f0: 6f 66 20 61 72 67 75 6d 65 6e 74 73 20 2a 2f 0a  of arguments */.
8200: 20 20 54 63 6c 5f 4f 62 6a 20 2a 43 4f 4e 53 54    Tcl_Obj *CONST
8210: 20 6f 62 6a 76 5b 5d 20 20 2f 2a 20 43 6f 6d 6d   objv[]  /* Comm
8220: 61 6e 64 20 61 72 67 75 6d 65 6e 74 73 20 2a 2f  and arguments */
8230: 0a 29 7b 0a 20 20 73 71 6c 69 74 65 33 20 2a 64  .){.  sqlite3 *d
8240: 62 3b 0a 20 20 45 63 68 6f 4d 6f 64 75 6c 65 20  b;.  EchoModule 
8250: 2a 70 4d 6f 64 3b 0a 20 20 69 66 28 20 6f 62 6a  *pMod;.  if( obj
8260: 63 21 3d 32 20 29 7b 0a 20 20 20 20 54 63 6c 5f  c!=2 ){.    Tcl_
8270: 57 72 6f 6e 67 4e 75 6d 41 72 67 73 28 69 6e 74  WrongNumArgs(int
8280: 65 72 70 2c 20 31 2c 20 6f 62 6a 76 2c 20 22 44  erp, 1, objv, "D
8290: 42 22 29 3b 0a 20 20 20 20 72 65 74 75 72 6e 20  B");.    return 
82a0: 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a 20  TCL_ERROR;.  }. 
82b0: 20 69 66 28 20 67 65 74 44 62 50 6f 69 6e 74 65   if( getDbPointe
82c0: 72 28 69 6e 74 65 72 70 2c 20 54 63 6c 5f 47 65  r(interp, Tcl_Ge
82d0: 74 53 74 72 69 6e 67 28 6f 62 6a 76 5b 31 5d 29  tString(objv[1])
82e0: 2c 20 26 64 62 29 20 29 20 72 65 74 75 72 6e 20  , &db) ) return 
82f0: 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 70 4d 6f  TCL_ERROR;.  pMo
8300: 64 20 3d 20 73 71 6c 69 74 65 33 5f 6d 61 6c 6c  d = sqlite3_mall
8310: 6f 63 28 73 69 7a 65 6f 66 28 45 63 68 6f 4d 6f  oc(sizeof(EchoMo
8320: 64 75 6c 65 29 29 3b 0a 20 20 70 4d 6f 64 2d 3e  dule));.  pMod->
8330: 69 6e 74 65 72 70 20 3d 20 69 6e 74 65 72 70 3b  interp = interp;
8340: 0a 20 20 73 71 6c 69 74 65 33 5f 63 72 65 61 74  .  sqlite3_creat
8350: 65 5f 6d 6f 64 75 6c 65 5f 76 32 28 64 62 2c 20  e_module_v2(db, 
8360: 22 65 63 68 6f 22 2c 20 26 65 63 68 6f 4d 6f 64  "echo", &echoMod
8370: 75 6c 65 2c 20 28 76 6f 69 64 2a 29 70 4d 6f 64  ule, (void*)pMod
8380: 2c 20 6d 6f 64 75 6c 65 44 65 73 74 72 6f 79 29  , moduleDestroy)
8390: 3b 0a 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 4f  ;.  return TCL_O
83a0: 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 63 6c 20  K;.}../*.** Tcl 
83b0: 69 6e 74 65 72 66 61 63 65 20 74 6f 20 73 71 6c  interface to sql
83c0: 69 74 65 33 5f 64 65 63 6c 61 72 65 5f 76 74 61  ite3_declare_vta
83d0: 62 2c 20 69 6e 76 6f 6b 65 64 20 61 73 20 66 6f  b, invoked as fo
83e0: 6c 6c 6f 77 73 20 66 72 6f 6d 20 54 63 6c 3a 0a  llows from Tcl:.
83f0: 2a 2a 0a 2a 2a 20 73 71 6c 69 74 65 33 5f 64 65  **.** sqlite3_de
8400: 63 6c 61 72 65 5f 76 74 61 62 20 44 42 20 53 51  clare_vtab DB SQ
8410: 4c 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  L.*/.static int 
8420: 64 65 63 6c 61 72 65 5f 76 74 61 62 28 0a 20 20  declare_vtab(.  
8430: 43 6c 69 65 6e 74 44 61 74 61 20 63 6c 69 65 6e  ClientData clien
8440: 74 44 61 74 61 2c 20 2f 2a 20 50 6f 69 6e 74 65  tData, /* Pointe
8450: 72 20 74 6f 20 73 71 6c 69 74 65 33 5f 65 6e 61  r to sqlite3_ena
8460: 62 6c 65 5f 58 58 58 20 66 75 6e 63 74 69 6f 6e  ble_XXX function
8470: 20 2a 2f 0a 20 20 54 63 6c 5f 49 6e 74 65 72 70   */.  Tcl_Interp
8480: 20 2a 69 6e 74 65 72 70 2c 20 20 20 20 2f 2a 20   *interp,    /* 
8490: 54 68 65 20 54 43 4c 20 69 6e 74 65 72 70 72 65  The TCL interpre
84a0: 74 65 72 20 74 68 61 74 20 69 6e 76 6f 6b 65 64  ter that invoked
84b0: 20 74 68 69 73 20 63 6f 6d 6d 61 6e 64 20 2a 2f   this command */
84c0: 0a 20 20 69 6e 74 20 6f 62 6a 63 2c 20 20 20 20  .  int objc,    
84d0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d            /* Num
84e0: 62 65 72 20 6f 66 20 61 72 67 75 6d 65 6e 74 73  ber of arguments
84f0: 20 2a 2f 0a 20 20 54 63 6c 5f 4f 62 6a 20 2a 43   */.  Tcl_Obj *C
8500: 4f 4e 53 54 20 6f 62 6a 76 5b 5d 20 20 2f 2a 20  ONST objv[]  /* 
8510: 43 6f 6d 6d 61 6e 64 20 61 72 67 75 6d 65 6e 74  Command argument
8520: 73 20 2a 2f 0a 29 7b 0a 20 20 73 71 6c 69 74 65  s */.){.  sqlite
8530: 33 20 2a 64 62 3b 0a 20 20 69 6e 74 20 72 63 3b  3 *db;.  int rc;
8540: 0a 20 20 69 66 28 20 6f 62 6a 63 21 3d 33 20 29  .  if( objc!=3 )
8550: 7b 0a 20 20 20 20 54 63 6c 5f 57 72 6f 6e 67 4e  {.    Tcl_WrongN
8560: 75 6d 41 72 67 73 28 69 6e 74 65 72 70 2c 20 31  umArgs(interp, 1
8570: 2c 20 6f 62 6a 76 2c 20 22 44 42 20 53 51 4c 22  , objv, "DB SQL"
8580: 29 3b 0a 20 20 20 20 72 65 74 75 72 6e 20 54 43  );.    return TC
8590: 4c 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a 20 20 69  L_ERROR;.  }.  i
85a0: 66 28 20 67 65 74 44 62 50 6f 69 6e 74 65 72 28  f( getDbPointer(
85b0: 69 6e 74 65 72 70 2c 20 54 63 6c 5f 47 65 74 53  interp, Tcl_GetS
85c0: 74 72 69 6e 67 28 6f 62 6a 76 5b 31 5d 29 2c 20  tring(objv[1]), 
85d0: 26 64 62 29 20 29 20 72 65 74 75 72 6e 20 54 43  &db) ) return TC
85e0: 4c 5f 45 52 52 4f 52 3b 0a 20 20 72 63 20 3d 20  L_ERROR;.  rc = 
85f0: 73 71 6c 69 74 65 33 5f 64 65 63 6c 61 72 65 5f  sqlite3_declare_
8600: 76 74 61 62 28 64 62 2c 20 54 63 6c 5f 47 65 74  vtab(db, Tcl_Get
8610: 53 74 72 69 6e 67 28 6f 62 6a 76 5b 32 5d 29 29  String(objv[2]))
8620: 3b 0a 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49  ;.  if( rc!=SQLI
8630: 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 54 63 6c  TE_OK ){.    Tcl
8640: 5f 53 65 74 52 65 73 75 6c 74 28 69 6e 74 65 72  _SetResult(inter
8650: 70 2c 20 28 63 68 61 72 20 2a 29 73 71 6c 69 74  p, (char *)sqlit
8660: 65 33 5f 65 72 72 6d 73 67 28 64 62 29 2c 20 54  e3_errmsg(db), T
8670: 43 4c 5f 56 4f 4c 41 54 49 4c 45 29 3b 0a 20 20  CL_VOLATILE);.  
8680: 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52    return TCL_ERR
8690: 4f 52 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e  OR;.  }.  return
86a0: 20 54 43 4c 5f 4f 4b 3b 0a 7d 0a 0a 23 65 6e 64   TCL_OK;.}..#end
86b0: 69 66 20 2f 2a 20 69 66 6e 64 65 66 20 53 51 4c  if /* ifndef SQL
86c0: 49 54 45 5f 4f 4d 49 54 5f 56 49 52 54 55 41 4c  ITE_OMIT_VIRTUAL
86d0: 54 41 42 4c 45 20 2a 2f 0a 0a 2f 2a 0a 2a 2a 20  TABLE */../*.** 
86e0: 52 65 67 69 73 74 65 72 20 63 6f 6d 6d 61 6e 64  Register command
86f0: 73 20 77 69 74 68 20 74 68 65 20 54 43 4c 20 69  s with the TCL i
8700: 6e 74 65 72 70 72 65 74 65 72 2e 0a 2a 2f 0a 69  nterpreter..*/.i
8710: 6e 74 20 53 71 6c 69 74 65 74 65 73 74 38 5f 49  nt Sqlitetest8_I
8720: 6e 69 74 28 54 63 6c 5f 49 6e 74 65 72 70 20 2a  nit(Tcl_Interp *
8730: 69 6e 74 65 72 70 29 7b 0a 20 20 73 74 61 74 69  interp){.  stati
8740: 63 20 73 74 72 75 63 74 20 7b 0a 20 20 20 20 20  c struct {.     
8750: 63 68 61 72 20 2a 7a 4e 61 6d 65 3b 0a 20 20 20  char *zName;.   
8760: 20 20 54 63 6c 5f 4f 62 6a 43 6d 64 50 72 6f 63    Tcl_ObjCmdProc
8770: 20 2a 78 50 72 6f 63 3b 0a 20 20 20 20 20 76 6f   *xProc;.     vo
8780: 69 64 20 2a 63 6c 69 65 6e 74 44 61 74 61 3b 0a  id *clientData;.
8790: 20 20 7d 20 61 4f 62 6a 43 6d 64 5b 5d 20 3d 20    } aObjCmd[] = 
87a0: 7b 0a 23 69 66 6e 64 65 66 20 53 51 4c 49 54 45  {.#ifndef SQLITE
87b0: 5f 4f 4d 49 54 5f 56 49 52 54 55 41 4c 54 41 42  _OMIT_VIRTUALTAB
87c0: 4c 45 0a 20 20 20 20 20 7b 20 22 72 65 67 69 73  LE.     { "regis
87d0: 74 65 72 5f 65 63 68 6f 5f 6d 6f 64 75 6c 65 22  ter_echo_module"
87e0: 2c 20 20 20 72 65 67 69 73 74 65 72 5f 65 63 68  ,   register_ech
87f0: 6f 5f 6d 6f 64 75 6c 65 2c 20 30 20 7d 2c 0a 20  o_module, 0 },. 
8800: 20 20 20 20 7b 20 22 73 71 6c 69 74 65 33 5f 64      { "sqlite3_d
8810: 65 63 6c 61 72 65 5f 76 74 61 62 22 2c 20 20 20  eclare_vtab",   
8820: 64 65 63 6c 61 72 65 5f 76 74 61 62 2c 20 30 20  declare_vtab, 0 
8830: 7d 2c 0a 23 65 6e 64 69 66 0a 20 20 7d 3b 0a 20  },.#endif.  };. 
8840: 20 69 6e 74 20 69 3b 0a 20 20 66 6f 72 28 69 3d   int i;.  for(i=
8850: 30 3b 20 69 3c 73 69 7a 65 6f 66 28 61 4f 62 6a  0; i<sizeof(aObj
8860: 43 6d 64 29 2f 73 69 7a 65 6f 66 28 61 4f 62 6a  Cmd)/sizeof(aObj
8870: 43 6d 64 5b 30 5d 29 3b 20 69 2b 2b 29 7b 0a 20  Cmd[0]); i++){. 
8880: 20 20 20 54 63 6c 5f 43 72 65 61 74 65 4f 62 6a     Tcl_CreateObj
8890: 43 6f 6d 6d 61 6e 64 28 69 6e 74 65 72 70 2c 20  Command(interp, 
88a0: 61 4f 62 6a 43 6d 64 5b 69 5d 2e 7a 4e 61 6d 65  aObjCmd[i].zName
88b0: 2c 20 0a 20 20 20 20 20 20 20 20 61 4f 62 6a 43  , .        aObjC
88c0: 6d 64 5b 69 5d 2e 78 50 72 6f 63 2c 20 61 4f 62  md[i].xProc, aOb
88d0: 6a 43 6d 64 5b 69 5d 2e 63 6c 69 65 6e 74 44 61  jCmd[i].clientDa
88e0: 74 61 2c 20 30 29 3b 0a 20 20 7d 0a 20 20 72 65  ta, 0);.  }.  re
88f0: 74 75 72 6e 20 54 43 4c 5f 4f 4b 3b 0a 7d 0a     turn TCL_OK;.}.