/ Hex Artifact Content
Login
SQLite training in Houston TX on 2019-11-05 (details)
Part of the 2019 Tcl Conference

Artifact 146cb2c2e7e9bac0e30e4890e7880ffe3e223a68:


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 35 36 20 32  test8.c,v 1.56 2
0230: 30 30 37 2f 30 39 2f 30 33 20 31 31 3a 35 31 3a  007/09/03 11:51:
0240: 35 30 20 64 61 6e 69 65 6c 6b 31 39 37 37 20 45  50 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 6e 42 79 74 65 73 20  ){.      nBytes 
12a0: 2b 3d 20 28 73 74 72 6c 65 6e 28 73 71 6c 69 74  += (strlen(sqlit
12b0: 65 33 5f 63 6f 6c 75 6d 6e 5f 6e 61 6d 65 28 70  e3_column_name(p
12c0: 53 74 6d 74 2c 20 69 69 29 29 20 2b 20 31 29 3b  Stmt, ii)) + 1);
12d0: 0a 20 20 20 20 7d 0a 20 20 20 20 61 43 6f 6c 20  .    }.    aCol 
12e0: 3d 20 28 63 68 61 72 20 2a 2a 29 73 71 6c 69 74  = (char **)sqlit
12f0: 65 33 4d 61 6c 6c 6f 63 5a 65 72 6f 28 6e 42 79  e3MallocZero(nBy
1300: 74 65 73 29 3b 0a 20 20 20 20 69 66 28 20 21 61  tes);.    if( !a
1310: 43 6f 6c 20 29 7b 0a 20 20 20 20 20 20 72 63 20  Col ){.      rc 
1320: 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a  = SQLITE_NOMEM;.
1330: 20 20 20 20 20 20 67 6f 74 6f 20 6f 75 74 3b 0a        goto out;.
1340: 20 20 20 20 7d 0a 0a 20 20 20 20 2f 2a 20 43 6f      }..    /* Co
1350: 70 79 20 74 68 65 20 63 6f 6c 75 6d 6e 20 6e 61  py the column na
1360: 6d 65 73 20 69 6e 74 6f 20 74 68 65 20 61 6c 6c  mes into the all
1370: 6f 63 61 74 65 64 20 73 70 61 63 65 20 61 6e 64  ocated space and
1380: 20 73 65 74 20 75 70 20 74 68 65 0a 20 20 20 20   set up the.    
1390: 2a 2a 20 70 6f 69 6e 74 65 72 73 20 69 6e 20 74  ** pointers in t
13a0: 68 65 20 61 43 6f 6c 5b 5d 20 61 72 72 61 79 2e  he aCol[] array.
13b0: 0a 20 20 20 20 2a 2f 0a 20 20 20 20 7a 53 70 61  .    */.    zSpa
13c0: 63 65 20 3d 20 28 63 68 61 72 20 2a 29 28 26 61  ce = (char *)(&a
13d0: 43 6f 6c 5b 6e 43 6f 6c 5d 29 3b 0a 20 20 20 20  Col[nCol]);.    
13e0: 66 6f 72 28 69 69 3d 30 3b 20 69 69 3c 6e 43 6f  for(ii=0; ii<nCo
13f0: 6c 3b 20 69 69 2b 2b 29 7b 0a 20 20 20 20 20 20  l; ii++){.      
1400: 61 43 6f 6c 5b 69 69 5d 20 3d 20 7a 53 70 61 63  aCol[ii] = zSpac
1410: 65 3b 0a 20 20 20 20 20 20 7a 53 70 61 63 65 20  e;.      zSpace 
1420: 2b 3d 20 73 70 72 69 6e 74 66 28 7a 53 70 61 63  += sprintf(zSpac
1430: 65 2c 20 22 25 73 22 2c 20 73 71 6c 69 74 65 33  e, "%s", sqlite3
1440: 5f 63 6f 6c 75 6d 6e 5f 6e 61 6d 65 28 70 53 74  _column_name(pSt
1450: 6d 74 2c 20 69 69 29 29 3b 0a 20 20 20 20 20 20  mt, ii));.      
1460: 7a 53 70 61 63 65 2b 2b 3b 0a 20 20 20 20 7d 0a  zSpace++;.    }.
1470: 20 20 20 20 61 73 73 65 72 74 28 20 28 7a 53 70      assert( (zSp
1480: 61 63 65 2d 6e 42 79 74 65 73 29 3d 3d 28 63 68  ace-nBytes)==(ch
1490: 61 72 20 2a 29 61 43 6f 6c 20 29 3b 0a 20 20 7d  ar *)aCol );.  }
14a0: 0a 0a 20 20 2a 70 61 43 6f 6c 20 3d 20 61 43 6f  ..  *paCol = aCo
14b0: 6c 3b 0a 20 20 2a 70 6e 43 6f 6c 20 3d 20 6e 43  l;.  *pnCol = nC
14c0: 6f 6c 3b 0a 0a 6f 75 74 3a 0a 20 20 73 71 6c 69  ol;..out:.  sqli
14d0: 74 65 33 5f 66 69 6e 61 6c 69 7a 65 28 70 53 74  te3_finalize(pSt
14e0: 6d 74 29 3b 0a 20 20 72 65 74 75 72 6e 20 72 63  mt);.  return rc
14f0: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 50 61 72 61 6d  ;.}../*.** Param
1500: 65 74 65 72 20 7a 54 61 62 20 69 73 20 74 68 65  eter zTab is the
1510: 20 6e 61 6d 65 20 6f 66 20 61 20 74 61 62 6c 65   name of a table
1520: 20 69 6e 20 64 61 74 61 62 61 73 65 20 64 62 20   in database db 
1530: 77 69 74 68 20 6e 43 6f 6c 20 0a 2a 2a 20 63 6f  with nCol .** co
1540: 6c 75 6d 6e 73 2e 20 54 68 69 73 20 66 75 6e 63  lumns. This func
1550: 74 69 6f 6e 20 61 6c 6c 6f 63 61 74 65 73 20 61  tion allocates a
1560: 6e 20 61 72 72 61 79 20 6f 66 20 69 6e 74 65 67  n array of integ
1570: 65 72 73 20 6e 43 6f 6c 20 69 6e 20 0a 2a 2a 20  ers nCol in .** 
1580: 73 69 7a 65 20 61 6e 64 20 70 6f 70 75 6c 61 74  size and populat
1590: 65 73 20 69 74 20 61 63 63 6f 72 64 69 6e 67 20  es it according 
15a0: 74 6f 20 61 6e 79 20 69 6d 70 6c 69 63 69 74 20  to any implicit 
15b0: 6f 72 20 65 78 70 6c 69 63 69 74 20 0a 2a 2a 20  or explicit .** 
15c0: 69 6e 64 69 63 65 73 20 6f 6e 20 74 61 62 6c 65  indices on table
15d0: 20 7a 54 61 62 2e 0a 2a 2a 0a 2a 2a 20 49 66 20   zTab..**.** If 
15e0: 73 75 63 63 65 73 73 66 75 6c 2c 20 53 51 4c 49  successful, SQLI
15f0: 54 45 5f 4f 4b 20 69 73 20 72 65 74 75 72 6e 65  TE_OK is returne
1600: 64 20 61 6e 64 20 2a 70 61 49 6e 64 65 78 20 73  d and *paIndex s
1610: 65 74 20 74 6f 20 70 6f 69 6e 74 20 0a 2a 2a 20  et to point .** 
1620: 61 74 20 74 68 65 20 61 6c 6c 6f 63 61 74 65 64  at the allocated
1630: 20 61 72 72 61 79 2e 20 4f 74 68 65 72 77 69 73   array. Otherwis
1640: 65 2c 20 61 6e 20 65 72 72 6f 72 20 63 6f 64 65  e, an error code
1650: 20 69 73 20 72 65 74 75 72 6e 65 64 2e 0a 2a 2a   is returned..**
1660: 0a 2a 2a 20 53 65 65 20 63 6f 6d 6d 65 6e 74 73  .** See comments
1670: 20 61 73 73 6f 63 69 61 74 65 64 20 77 69 74 68   associated with
1680: 20 74 68 65 20 6d 65 6d 62 65 72 20 76 61 72 69   the member vari
1690: 61 62 6c 65 20 61 49 6e 64 65 78 20 61 62 6f 76  able aIndex abov
16a0: 65 20 0a 2a 2a 20 22 73 74 72 75 63 74 20 65 63  e .** "struct ec
16b0: 68 6f 5f 76 74 61 62 22 20 66 6f 72 20 64 65 74  ho_vtab" for det
16c0: 61 69 6c 73 20 6f 66 20 74 68 65 20 63 6f 6e 74  ails of the cont
16d0: 65 6e 74 73 20 6f 66 20 74 68 65 20 61 72 72 61  ents of the arra
16e0: 79 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  y..*/.static int
16f0: 20 67 65 74 49 6e 64 65 78 41 72 72 61 79 28 0a   getIndexArray(.
1700: 20 20 73 71 6c 69 74 65 33 20 2a 64 62 2c 20 20    sqlite3 *db,  
1710: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 44 61             /* Da
1720: 74 61 62 61 73 65 20 63 6f 6e 6e 65 63 74 69 6f  tabase connectio
1730: 6e 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68 61  n */.  const cha
1740: 72 20 2a 7a 54 61 62 2c 20 20 20 20 20 20 20 20  r *zTab,        
1750: 2f 2a 20 4e 61 6d 65 20 6f 66 20 74 61 62 6c 65  /* Name of table
1760: 20 69 6e 20 64 61 74 61 62 61 73 65 20 64 62 20   in database db 
1770: 2a 2f 0a 20 20 69 6e 74 20 6e 43 6f 6c 2c 0a 20  */.  int nCol,. 
1780: 20 69 6e 74 20 2a 2a 70 61 49 6e 64 65 78 0a 29   int **paIndex.)
1790: 7b 0a 20 20 73 71 6c 69 74 65 33 5f 73 74 6d 74  {.  sqlite3_stmt
17a0: 20 2a 70 53 74 6d 74 20 3d 20 30 3b 0a 20 20 69   *pStmt = 0;.  i
17b0: 6e 74 20 2a 61 49 6e 64 65 78 20 3d 20 30 3b 0a  nt *aIndex = 0;.
17c0: 20 20 69 6e 74 20 72 63 3b 0a 20 20 63 68 61 72    int rc;.  char
17d0: 20 2a 7a 53 71 6c 3b 0a 0a 20 20 2f 2a 20 41 6c   *zSql;..  /* Al
17e0: 6c 6f 63 61 74 65 20 73 70 61 63 65 20 66 6f 72  locate space for
17f0: 20 74 68 65 20 69 6e 64 65 78 20 61 72 72 61 79   the index array
1800: 20 2a 2f 0a 20 20 61 49 6e 64 65 78 20 3d 20 28   */.  aIndex = (
1810: 69 6e 74 20 2a 29 73 71 6c 69 74 65 33 4d 61 6c  int *)sqlite3Mal
1820: 6c 6f 63 5a 65 72 6f 28 73 69 7a 65 6f 66 28 69  locZero(sizeof(i
1830: 6e 74 29 20 2a 20 6e 43 6f 6c 29 3b 0a 20 20 69  nt) * nCol);.  i
1840: 66 28 20 21 61 49 6e 64 65 78 20 29 7b 0a 20 20  f( !aIndex ){.  
1850: 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4e 4f    rc = SQLITE_NO
1860: 4d 45 4d 3b 0a 20 20 20 20 67 6f 74 6f 20 67 65  MEM;.    goto ge
1870: 74 5f 69 6e 64 65 78 5f 61 72 72 61 79 5f 6f 75  t_index_array_ou
1880: 74 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 43 6f 6d  t;.  }..  /* Com
1890: 70 69 6c 65 20 61 6e 20 73 71 6c 69 74 65 20 70  pile an sqlite p
18a0: 72 61 67 6d 61 20 74 6f 20 6c 6f 6f 70 20 74 68  ragma to loop th
18b0: 72 6f 75 67 68 20 61 6c 6c 20 69 6e 64 69 63 65  rough all indice
18c0: 73 20 6f 6e 20 74 61 62 6c 65 20 7a 54 61 62 20  s on table zTab 
18d0: 2a 2f 0a 20 20 7a 53 71 6c 20 3d 20 73 71 6c 69  */.  zSql = sqli
18e0: 74 65 33 4d 50 72 69 6e 74 66 28 30 2c 20 22 50  te3MPrintf(0, "P
18f0: 52 41 47 4d 41 20 69 6e 64 65 78 5f 6c 69 73 74  RAGMA index_list
1900: 28 25 73 29 22 2c 20 7a 54 61 62 29 3b 0a 20 20  (%s)", zTab);.  
1910: 69 66 28 20 21 7a 53 71 6c 20 29 7b 0a 20 20 20  if( !zSql ){.   
1920: 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d   rc = SQLITE_NOM
1930: 45 4d 3b 0a 20 20 20 20 67 6f 74 6f 20 67 65 74  EM;.    goto get
1940: 5f 69 6e 64 65 78 5f 61 72 72 61 79 5f 6f 75 74  _index_array_out
1950: 3b 0a 20 20 7d 0a 20 20 72 63 20 3d 20 73 71 6c  ;.  }.  rc = sql
1960: 69 74 65 33 5f 70 72 65 70 61 72 65 28 64 62 2c  ite3_prepare(db,
1970: 20 7a 53 71 6c 2c 20 2d 31 2c 20 26 70 53 74 6d   zSql, -1, &pStm
1980: 74 2c 20 30 29 3b 0a 20 20 73 71 6c 69 74 65 33  t, 0);.  sqlite3
1990: 5f 66 72 65 65 28 7a 53 71 6c 29 3b 0a 0a 20 20  _free(zSql);..  
19a0: 2f 2a 20 46 6f 72 20 65 61 63 68 20 69 6e 64 65  /* For each inde
19b0: 78 2c 20 66 69 67 75 72 65 20 6f 75 74 20 74 68  x, figure out th
19c0: 65 20 6c 65 66 74 2d 6d 6f 73 74 20 63 6f 6c 75  e left-most colu
19d0: 6d 6e 20 61 6e 64 20 73 65 74 20 74 68 65 20 0a  mn and set the .
19e0: 20 20 2a 2a 20 63 6f 72 72 65 73 70 6f 6e 64 69    ** correspondi
19f0: 6e 67 20 65 6e 74 72 79 20 69 6e 20 61 49 6e 64  ng entry in aInd
1a00: 65 78 5b 5d 20 74 6f 20 31 2e 0a 20 20 2a 2f 0a  ex[] to 1..  */.
1a10: 20 20 77 68 69 6c 65 28 20 70 53 74 6d 74 20 26    while( pStmt &
1a20: 26 20 73 71 6c 69 74 65 33 5f 73 74 65 70 28 70  & sqlite3_step(p
1a30: 53 74 6d 74 29 3d 3d 53 51 4c 49 54 45 5f 52 4f  Stmt)==SQLITE_RO
1a40: 57 20 29 7b 0a 20 20 20 20 63 6f 6e 73 74 20 63  W ){.    const c
1a50: 68 61 72 20 2a 7a 49 64 78 20 3d 20 28 63 6f 6e  har *zIdx = (con
1a60: 73 74 20 63 68 61 72 20 2a 29 73 71 6c 69 74 65  st char *)sqlite
1a70: 33 5f 63 6f 6c 75 6d 6e 5f 74 65 78 74 28 70 53  3_column_text(pS
1a80: 74 6d 74 2c 20 31 29 3b 0a 20 20 20 20 73 71 6c  tmt, 1);.    sql
1a90: 69 74 65 33 5f 73 74 6d 74 20 2a 70 53 74 6d 74  ite3_stmt *pStmt
1aa0: 32 20 3d 20 30 3b 0a 20 20 20 20 7a 53 71 6c 20  2 = 0;.    zSql 
1ab0: 3d 20 73 71 6c 69 74 65 33 4d 50 72 69 6e 74 66  = sqlite3MPrintf
1ac0: 28 30 2c 20 22 50 52 41 47 4d 41 20 69 6e 64 65  (0, "PRAGMA inde
1ad0: 78 5f 69 6e 66 6f 28 25 73 29 22 2c 20 7a 49 64  x_info(%s)", zId
1ae0: 78 29 3b 0a 20 20 20 20 69 66 28 20 21 7a 53 71  x);.    if( !zSq
1af0: 6c 20 29 7b 0a 20 20 20 20 20 20 72 63 20 3d 20  l ){.      rc = 
1b00: 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20  SQLITE_NOMEM;.  
1b10: 20 20 20 20 67 6f 74 6f 20 67 65 74 5f 69 6e 64      goto get_ind
1b20: 65 78 5f 61 72 72 61 79 5f 6f 75 74 3b 0a 20 20  ex_array_out;.  
1b30: 20 20 7d 0a 20 20 20 20 72 63 20 3d 20 73 71 6c    }.    rc = sql
1b40: 69 74 65 33 5f 70 72 65 70 61 72 65 28 64 62 2c  ite3_prepare(db,
1b50: 20 7a 53 71 6c 2c 20 2d 31 2c 20 26 70 53 74 6d   zSql, -1, &pStm
1b60: 74 32 2c 20 30 29 3b 0a 20 20 20 20 73 71 6c 69  t2, 0);.    sqli
1b70: 74 65 33 5f 66 72 65 65 28 7a 53 71 6c 29 3b 0a  te3_free(zSql);.
1b80: 20 20 20 20 69 66 28 20 70 53 74 6d 74 32 20 26      if( pStmt2 &
1b90: 26 20 73 71 6c 69 74 65 33 5f 73 74 65 70 28 70  & sqlite3_step(p
1ba0: 53 74 6d 74 32 29 3d 3d 53 51 4c 49 54 45 5f 52  Stmt2)==SQLITE_R
1bb0: 4f 57 20 29 7b 0a 20 20 20 20 20 20 69 6e 74 20  OW ){.      int 
1bc0: 63 69 64 20 3d 20 73 71 6c 69 74 65 33 5f 63 6f  cid = sqlite3_co
1bd0: 6c 75 6d 6e 5f 69 6e 74 28 70 53 74 6d 74 32 2c  lumn_int(pStmt2,
1be0: 20 31 29 3b 0a 20 20 20 20 20 20 61 73 73 65 72   1);.      asser
1bf0: 74 28 20 63 69 64 3e 3d 30 20 26 26 20 63 69 64  t( cid>=0 && cid
1c00: 3c 6e 43 6f 6c 20 29 3b 0a 20 20 20 20 20 20 61  <nCol );.      a
1c10: 49 6e 64 65 78 5b 63 69 64 5d 20 3d 20 31 3b 0a  Index[cid] = 1;.
1c20: 20 20 20 20 7d 0a 20 20 20 20 69 66 28 20 70 53      }.    if( pS
1c30: 74 6d 74 32 20 29 7b 0a 20 20 20 20 20 20 72 63  tmt2 ){.      rc
1c40: 20 3d 20 73 71 6c 69 74 65 33 5f 66 69 6e 61 6c   = sqlite3_final
1c50: 69 7a 65 28 70 53 74 6d 74 32 29 3b 0a 20 20 20  ize(pStmt2);.   
1c60: 20 7d 0a 20 20 20 20 69 66 28 20 72 63 21 3d 53   }.    if( rc!=S
1c70: 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
1c80: 20 20 67 6f 74 6f 20 67 65 74 5f 69 6e 64 65 78    goto get_index
1c90: 5f 61 72 72 61 79 5f 6f 75 74 3b 0a 20 20 20 20  _array_out;.    
1ca0: 7d 0a 20 20 7d 0a 0a 0a 67 65 74 5f 69 6e 64 65  }.  }...get_inde
1cb0: 78 5f 61 72 72 61 79 5f 6f 75 74 3a 0a 20 20 69  x_array_out:.  i
1cc0: 66 28 20 70 53 74 6d 74 20 29 7b 0a 20 20 20 20  f( pStmt ){.    
1cd0: 69 6e 74 20 72 63 32 20 3d 20 73 71 6c 69 74 65  int rc2 = sqlite
1ce0: 33 5f 66 69 6e 61 6c 69 7a 65 28 70 53 74 6d 74  3_finalize(pStmt
1cf0: 29 3b 0a 20 20 20 20 69 66 28 20 72 63 3d 3d 53  );.    if( rc==S
1d00: 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
1d10: 20 20 72 63 20 3d 20 72 63 32 3b 0a 20 20 20 20    rc = rc2;.    
1d20: 7d 0a 20 20 7d 0a 20 20 69 66 28 20 72 63 21 3d  }.  }.  if( rc!=
1d30: 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20  SQLITE_OK ){.   
1d40: 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 61 49   sqlite3_free(aI
1d50: 6e 64 65 78 29 3b 0a 20 20 20 20 61 49 6e 64 65  ndex);.    aInde
1d60: 78 20 3d 20 30 3b 0a 20 20 7d 0a 20 20 2a 70 61  x = 0;.  }.  *pa
1d70: 49 6e 64 65 78 20 3d 20 61 49 6e 64 65 78 3b 0a  Index = aIndex;.
1d80: 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a    return rc;.}..
1d90: 2f 2a 0a 2a 2a 20 47 6c 6f 62 61 6c 20 54 63 6c  /*.** Global Tcl
1da0: 20 76 61 72 69 61 62 6c 65 20 24 65 63 68 6f 5f   variable $echo_
1db0: 6d 6f 64 75 6c 65 20 69 73 20 61 20 6c 69 73 74  module is a list
1dc0: 2e 20 54 68 69 73 20 72 6f 75 74 69 6e 65 20 61  . This routine a
1dd0: 70 70 65 6e 64 73 0a 2a 2a 20 74 68 65 20 73 74  ppends.** the st
1de0: 72 69 6e 67 20 65 6c 65 6d 65 6e 74 20 7a 41 72  ring element zAr
1df0: 67 20 74 6f 20 74 68 61 74 20 6c 69 73 74 20 69  g to that list i
1e00: 6e 20 69 6e 74 65 72 70 72 65 74 65 72 20 69 6e  n interpreter in
1e10: 74 65 72 70 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  terp..*/.static 
1e20: 76 6f 69 64 20 61 70 70 65 6e 64 54 6f 45 63 68  void appendToEch
1e30: 6f 4d 6f 64 75 6c 65 28 54 63 6c 5f 49 6e 74 65  oModule(Tcl_Inte
1e40: 72 70 20 2a 69 6e 74 65 72 70 2c 20 63 6f 6e 73  rp *interp, cons
1e50: 74 20 63 68 61 72 20 2a 7a 41 72 67 29 7b 0a 20  t char *zArg){. 
1e60: 20 69 6e 74 20 66 6c 61 67 73 20 3d 20 28 54 43   int flags = (TC
1e70: 4c 5f 41 50 50 45 4e 44 5f 56 41 4c 55 45 20 7c  L_APPEND_VALUE |
1e80: 20 54 43 4c 5f 4c 49 53 54 5f 45 4c 45 4d 45 4e   TCL_LIST_ELEMEN
1e90: 54 20 7c 20 54 43 4c 5f 47 4c 4f 42 41 4c 5f 4f  T | TCL_GLOBAL_O
1ea0: 4e 4c 59 29 3b 0a 20 20 54 63 6c 5f 53 65 74 56  NLY);.  Tcl_SetV
1eb0: 61 72 28 69 6e 74 65 72 70 2c 20 22 65 63 68 6f  ar(interp, "echo
1ec0: 5f 6d 6f 64 75 6c 65 22 2c 20 28 7a 41 72 67 3f  _module", (zArg?
1ed0: 7a 41 72 67 3a 22 22 29 2c 20 66 6c 61 67 73 29  zArg:""), flags)
1ee0: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20  ;.}../*.** This 
1ef0: 66 75 6e 63 74 69 6f 6e 20 69 73 20 63 61 6c 6c  function is call
1f00: 65 64 20 66 72 6f 6d 20 77 69 74 68 69 6e 20 74  ed from within t
1f10: 68 65 20 65 63 68 6f 2d 6d 6f 64 75 6c 65 73 20  he echo-modules 
1f20: 78 43 72 65 61 74 65 20 61 6e 64 0a 2a 2a 20 78  xCreate and.** x
1f30: 43 6f 6e 6e 65 63 74 20 6d 65 74 68 6f 64 73 2e  Connect methods.
1f40: 20 54 68 65 20 61 72 67 63 20 61 6e 64 20 61 72   The argc and ar
1f50: 67 76 20 61 72 67 75 6d 65 6e 74 73 20 61 72 65  gv arguments are
1f60: 20 63 6f 70 69 65 73 20 6f 66 20 74 68 6f 73 65   copies of those
1f70: 20 0a 2a 2a 20 70 61 73 73 65 64 20 74 6f 20 74   .** passed to t
1f80: 68 65 20 63 61 6c 6c 69 6e 67 20 6d 65 74 68 6f  he calling metho
1f90: 64 2e 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e  d. This function
1fa0: 20 69 73 20 72 65 73 70 6f 6e 73 69 62 6c 65 20   is responsible 
1fb0: 66 6f 72 0a 2a 2a 20 63 61 6c 6c 69 6e 67 20 73  for.** calling s
1fc0: 71 6c 69 74 65 33 5f 64 65 63 6c 61 72 65 5f 76  qlite3_declare_v
1fd0: 74 61 62 28 29 20 74 6f 20 64 65 63 6c 61 72 65  tab() to declare
1fe0: 20 74 68 65 20 73 63 68 65 6d 61 20 6f 66 20 74   the schema of t
1ff0: 68 65 20 76 69 72 74 75 61 6c 0a 2a 2a 20 74 61  he virtual.** ta
2000: 62 6c 65 20 62 65 69 6e 67 20 63 72 65 61 74 65  ble being create
2010: 64 20 6f 72 20 63 6f 6e 6e 65 63 74 65 64 2e 0a  d or connected..
2020: 2a 2a 0a 2a 2a 20 49 66 20 74 68 65 20 63 6f 6e  **.** If the con
2030: 73 74 72 75 63 74 6f 72 20 77 61 73 20 70 61 73  structor was pas
2040: 73 65 64 20 6a 75 73 74 20 6f 6e 65 20 61 72 67  sed just one arg
2050: 75 6d 65 6e 74 2c 20 69 2e 65 2e 3a 0a 2a 2a 0a  ument, i.e.:.**.
2060: 2a 2a 20 20 20 43 52 45 41 54 45 20 54 41 42 4c  **   CREATE TABL
2070: 45 20 74 31 20 41 53 20 65 63 68 6f 28 74 32 29  E t1 AS echo(t2)
2080: 3b 0a 2a 2a 0a 2a 2a 20 54 68 65 6e 20 74 32 20  ;.**.** Then t2 
2090: 69 73 20 61 73 73 75 6d 65 64 20 74 6f 20 62 65  is assumed to be
20a0: 20 74 68 65 20 6e 61 6d 65 20 6f 66 20 61 20 2a   the name of a *
20b0: 72 65 61 6c 2a 20 64 61 74 61 62 61 73 65 20 74  real* database t
20c0: 61 62 6c 65 2e 20 54 68 65 0a 2a 2a 20 73 63 68  able. The.** sch
20d0: 65 6d 61 20 6f 66 20 74 68 65 20 76 69 72 74 75  ema of the virtu
20e0: 61 6c 20 74 61 62 6c 65 20 69 73 20 64 65 63 6c  al table is decl
20f0: 61 72 65 64 20 62 79 20 70 61 73 73 69 6e 67 20  ared by passing 
2100: 61 20 63 6f 70 79 20 6f 66 20 74 68 65 20 0a 2a  a copy of the .*
2110: 2a 20 43 52 45 41 54 45 20 54 41 42 4c 45 20 73  * CREATE TABLE s
2120: 74 61 74 65 6d 65 6e 74 20 66 6f 72 20 74 68 65  tatement for the
2130: 20 72 65 61 6c 20 74 61 62 6c 65 20 74 6f 20 73   real table to s
2140: 71 6c 69 74 65 33 5f 64 65 63 6c 61 72 65 5f 76  qlite3_declare_v
2150: 74 61 62 28 29 2e 0a 2a 2a 20 48 65 6e 63 65 2c  tab()..** Hence,
2160: 20 74 68 65 20 76 69 72 74 75 61 6c 20 74 61 62   the virtual tab
2170: 6c 65 20 73 68 6f 75 6c 64 20 68 61 76 65 20 65  le should have e
2180: 78 61 63 74 6c 79 20 74 68 65 20 73 61 6d 65 20  xactly the same 
2190: 63 6f 6c 75 6d 6e 20 6e 61 6d 65 73 20 61 6e 64  column names and
21a0: 20 0a 2a 2a 20 74 79 70 65 73 20 61 73 20 74 68   .** types as th
21b0: 65 20 72 65 61 6c 20 74 61 62 6c 65 2e 0a 2a 2f  e real table..*/
21c0: 0a 73 74 61 74 69 63 20 69 6e 74 20 65 63 68 6f  .static int echo
21d0: 44 65 63 6c 61 72 65 56 74 61 62 28 0a 20 20 65  DeclareVtab(.  e
21e0: 63 68 6f 5f 76 74 61 62 20 2a 70 56 74 61 62 2c  cho_vtab *pVtab,
21f0: 20 0a 20 20 73 71 6c 69 74 65 33 20 2a 64 62 20   .  sqlite3 *db 
2200: 0a 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53  .){.  int rc = S
2210: 51 4c 49 54 45 5f 4f 4b 3b 0a 0a 20 20 69 66 28  QLITE_OK;..  if(
2220: 20 70 56 74 61 62 2d 3e 7a 54 61 62 6c 65 4e 61   pVtab->zTableNa
2230: 6d 65 20 29 7b 0a 20 20 20 20 73 71 6c 69 74 65  me ){.    sqlite
2240: 33 5f 73 74 6d 74 20 2a 70 53 74 6d 74 20 3d 20  3_stmt *pStmt = 
2250: 30 3b 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69  0;.    rc = sqli
2260: 74 65 33 5f 70 72 65 70 61 72 65 28 64 62 2c 20  te3_prepare(db, 
2270: 0a 20 20 20 20 20 20 20 20 22 53 45 4c 45 43 54  .        "SELECT
2280: 20 73 71 6c 20 46 52 4f 4d 20 73 71 6c 69 74 65   sql FROM sqlite
2290: 5f 6d 61 73 74 65 72 20 57 48 45 52 45 20 74 79  _master WHERE ty
22a0: 70 65 20 3d 20 27 74 61 62 6c 65 27 20 41 4e 44  pe = 'table' AND
22b0: 20 6e 61 6d 65 20 3d 20 3f 22 2c 0a 20 20 20 20   name = ?",.    
22c0: 20 20 20 20 2d 31 2c 20 26 70 53 74 6d 74 2c 20      -1, &pStmt, 
22d0: 30 29 3b 0a 20 20 20 20 69 66 28 20 72 63 3d 3d  0);.    if( rc==
22e0: 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20  SQLITE_OK ){.   
22f0: 20 20 20 73 71 6c 69 74 65 33 5f 62 69 6e 64 5f     sqlite3_bind_
2300: 74 65 78 74 28 70 53 74 6d 74 2c 20 31 2c 20 70  text(pStmt, 1, p
2310: 56 74 61 62 2d 3e 7a 54 61 62 6c 65 4e 61 6d 65  Vtab->zTableName
2320: 2c 20 2d 31 2c 20 30 29 3b 0a 20 20 20 20 20 20  , -1, 0);.      
2330: 69 66 28 20 73 71 6c 69 74 65 33 5f 73 74 65 70  if( sqlite3_step
2340: 28 70 53 74 6d 74 29 3d 3d 53 51 4c 49 54 45 5f  (pStmt)==SQLITE_
2350: 52 4f 57 20 29 7b 0a 20 20 20 20 20 20 20 20 69  ROW ){.        i
2360: 6e 74 20 72 63 32 3b 0a 20 20 20 20 20 20 20 20  nt rc2;.        
2370: 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 43 72 65  const char *zCre
2380: 61 74 65 54 61 62 6c 65 20 3d 20 28 63 6f 6e 73  ateTable = (cons
2390: 74 20 63 68 61 72 20 2a 29 73 71 6c 69 74 65 33  t char *)sqlite3
23a0: 5f 63 6f 6c 75 6d 6e 5f 74 65 78 74 28 70 53 74  _column_text(pSt
23b0: 6d 74 2c 20 30 29 3b 0a 20 20 20 20 20 20 20 20  mt, 0);.        
23c0: 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 64 65 63  rc = sqlite3_dec
23d0: 6c 61 72 65 5f 76 74 61 62 28 64 62 2c 20 7a 43  lare_vtab(db, zC
23e0: 72 65 61 74 65 54 61 62 6c 65 29 3b 0a 20 20 20  reateTable);.   
23f0: 20 20 20 20 20 72 63 32 20 3d 20 73 71 6c 69 74       rc2 = sqlit
2400: 65 33 5f 66 69 6e 61 6c 69 7a 65 28 70 53 74 6d  e3_finalize(pStm
2410: 74 29 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20  t);.        if( 
2420: 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc==SQLITE_OK ){
2430: 0a 20 20 20 20 20 20 20 20 20 20 72 63 20 3d 20  .          rc = 
2440: 72 63 32 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20  rc2;.        }. 
2450: 20 20 20 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20       } else {.  
2460: 20 20 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74        rc = sqlit
2470: 65 33 5f 66 69 6e 61 6c 69 7a 65 28 70 53 74 6d  e3_finalize(pStm
2480: 74 29 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20  t);.        if( 
2490: 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc==SQLITE_OK ){
24a0: 20 0a 20 20 20 20 20 20 20 20 20 20 72 63 20 3d   .          rc =
24b0: 20 53 51 4c 49 54 45 5f 45 52 52 4f 52 3b 0a 20   SQLITE_ERROR;. 
24c0: 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7d         }.      }
24d0: 0a 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d 53  .      if( rc==S
24e0: 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
24f0: 20 20 20 20 72 63 20 3d 20 67 65 74 43 6f 6c 75      rc = getColu
2500: 6d 6e 4e 61 6d 65 73 28 64 62 2c 20 70 56 74 61  mnNames(db, pVta
2510: 62 2d 3e 7a 54 61 62 6c 65 4e 61 6d 65 2c 20 26  b->zTableName, &
2520: 70 56 74 61 62 2d 3e 61 43 6f 6c 2c 20 26 70 56  pVtab->aCol, &pV
2530: 74 61 62 2d 3e 6e 43 6f 6c 29 3b 0a 20 20 20 20  tab->nCol);.    
2540: 20 20 7d 0a 20 20 20 20 20 20 69 66 28 20 72 63    }.      if( rc
2550: 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  ==SQLITE_OK ){. 
2560: 20 20 20 20 20 20 20 72 63 20 3d 20 67 65 74 49         rc = getI
2570: 6e 64 65 78 41 72 72 61 79 28 64 62 2c 20 70 56  ndexArray(db, pV
2580: 74 61 62 2d 3e 7a 54 61 62 6c 65 4e 61 6d 65 2c  tab->zTableName,
2590: 20 70 56 74 61 62 2d 3e 6e 43 6f 6c 2c 20 26 70   pVtab->nCol, &p
25a0: 56 74 61 62 2d 3e 61 49 6e 64 65 78 29 3b 0a 20  Vtab->aIndex);. 
25b0: 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 7d       }.    }.  }
25c0: 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d  ..  return rc;.}
25d0: 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e  ../*.** This fun
25e0: 63 74 69 6f 6e 20 66 72 65 65 73 20 61 6c 6c 20  ction frees all 
25f0: 72 75 6e 74 69 6d 65 20 73 74 72 75 63 74 75 72  runtime structur
2600: 65 73 20 61 73 73 6f 63 69 61 74 65 64 20 77 69  es associated wi
2610: 74 68 20 74 68 65 20 76 69 72 74 75 61 6c 0a 2a  th the virtual.*
2620: 2a 20 74 61 62 6c 65 20 70 56 74 61 62 2e 0a 2a  * table pVtab..*
2630: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 65 63 68  /.static int ech
2640: 6f 44 65 73 74 72 75 63 74 6f 72 28 73 71 6c 69  oDestructor(sqli
2650: 74 65 33 5f 76 74 61 62 20 2a 70 56 74 61 62 29  te3_vtab *pVtab)
2660: 7b 0a 20 20 65 63 68 6f 5f 76 74 61 62 20 2a 70  {.  echo_vtab *p
2670: 20 3d 20 28 65 63 68 6f 5f 76 74 61 62 2a 29 70   = (echo_vtab*)p
2680: 56 74 61 62 3b 0a 20 20 73 71 6c 69 74 65 33 5f  Vtab;.  sqlite3_
2690: 66 72 65 65 28 70 2d 3e 61 49 6e 64 65 78 29 3b  free(p->aIndex);
26a0: 0a 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28  .  sqlite3_free(
26b0: 70 2d 3e 61 43 6f 6c 29 3b 0a 20 20 73 71 6c 69  p->aCol);.  sqli
26c0: 74 65 33 5f 66 72 65 65 28 70 2d 3e 7a 54 68 69  te3_free(p->zThi
26d0: 73 29 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66 72  s);.  sqlite3_fr
26e0: 65 65 28 70 2d 3e 7a 54 61 62 6c 65 4e 61 6d 65  ee(p->zTableName
26f0: 29 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66 72 65  );.  sqlite3_fre
2700: 65 28 70 2d 3e 7a 4c 6f 67 4e 61 6d 65 29 3b 0a  e(p->zLogName);.
2710: 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70    sqlite3_free(p
2720: 29 3b 0a 20 20 72 65 74 75 72 6e 20 30 3b 0a 7d  );.  return 0;.}
2730: 0a 0a 74 79 70 65 64 65 66 20 73 74 72 75 63 74  ..typedef struct
2740: 20 45 63 68 6f 4d 6f 64 75 6c 65 20 45 63 68 6f   EchoModule Echo
2750: 4d 6f 64 75 6c 65 3b 0a 73 74 72 75 63 74 20 45  Module;.struct E
2760: 63 68 6f 4d 6f 64 75 6c 65 20 7b 0a 20 20 54 63  choModule {.  Tc
2770: 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70  l_Interp *interp
2780: 3b 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73  ;.};../*.** This
2790: 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 63 61 6c   function is cal
27a0: 6c 65 64 20 74 6f 20 64 6f 20 74 68 65 20 77 6f  led to do the wo
27b0: 72 6b 20 6f 66 20 74 68 65 20 78 43 6f 6e 6e 65  rk of the xConne
27c0: 63 74 28 29 20 6d 65 74 68 6f 64 20 2d 0a 2a 2a  ct() method -.**
27d0: 20 74 6f 20 61 6c 6c 6f 63 61 74 65 20 74 68 65   to allocate the
27e0: 20 72 65 71 75 69 72 65 64 20 69 6e 2d 6d 65 6d   required in-mem
27f0: 6f 72 79 20 73 74 72 75 63 74 75 72 65 73 20 66  ory structures f
2800: 6f 72 20 61 20 6e 65 77 6c 79 20 63 6f 6e 6e 65  or a newly conne
2810: 63 74 65 64 0a 2a 2a 20 76 69 72 74 75 61 6c 20  cted.** virtual 
2820: 74 61 62 6c 65 2e 0a 2a 2f 0a 73 74 61 74 69 63  table..*/.static
2830: 20 69 6e 74 20 65 63 68 6f 43 6f 6e 73 74 72 75   int echoConstru
2840: 63 74 6f 72 28 0a 20 20 73 71 6c 69 74 65 33 20  ctor(.  sqlite3 
2850: 2a 64 62 2c 0a 20 20 76 6f 69 64 20 2a 70 41 75  *db,.  void *pAu
2860: 78 2c 0a 20 20 69 6e 74 20 61 72 67 63 2c 20 63  x,.  int argc, c
2870: 6f 6e 73 74 20 63 68 61 72 20 2a 63 6f 6e 73 74  onst char *const
2880: 2a 61 72 67 76 2c 0a 20 20 73 71 6c 69 74 65 33  *argv,.  sqlite3
2890: 5f 76 74 61 62 20 2a 2a 70 70 56 74 61 62 2c 0a  _vtab **ppVtab,.
28a0: 20 20 63 68 61 72 20 2a 2a 70 7a 45 72 72 0a 29    char **pzErr.)
28b0: 7b 0a 20 20 69 6e 74 20 72 63 3b 0a 20 20 69 6e  {.  int rc;.  in
28c0: 74 20 69 3b 0a 20 20 65 63 68 6f 5f 76 74 61 62  t i;.  echo_vtab
28d0: 20 2a 70 56 74 61 62 3b 0a 0a 20 20 2f 2a 20 41   *pVtab;..  /* A
28e0: 6c 6c 6f 63 61 74 65 20 74 68 65 20 73 71 6c 69  llocate the sqli
28f0: 74 65 33 5f 76 74 61 62 2f 65 63 68 6f 5f 76 74  te3_vtab/echo_vt
2900: 61 62 20 73 74 72 75 63 74 75 72 65 20 69 74 73  ab structure its
2910: 65 6c 66 20 2a 2f 0a 20 20 70 56 74 61 62 20 3d  elf */.  pVtab =
2920: 20 73 71 6c 69 74 65 33 4d 61 6c 6c 6f 63 5a 65   sqlite3MallocZe
2930: 72 6f 28 20 73 69 7a 65 6f 66 28 2a 70 56 74 61  ro( sizeof(*pVta
2940: 62 29 20 29 3b 0a 20 20 69 66 28 20 21 70 56 74  b) );.  if( !pVt
2950: 61 62 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e  ab ){.    return
2960: 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20   SQLITE_NOMEM;. 
2970: 20 7d 0a 20 20 70 56 74 61 62 2d 3e 69 6e 74 65   }.  pVtab->inte
2980: 72 70 20 3d 20 28 28 45 63 68 6f 4d 6f 64 75 6c  rp = ((EchoModul
2990: 65 20 2a 29 70 41 75 78 29 2d 3e 69 6e 74 65 72  e *)pAux)->inter
29a0: 70 3b 0a 20 20 70 56 74 61 62 2d 3e 64 62 20 3d  p;.  pVtab->db =
29b0: 20 64 62 3b 0a 0a 20 20 2f 2a 20 41 6c 6c 6f 63   db;..  /* Alloc
29c0: 61 74 65 20 65 63 68 6f 5f 76 74 61 62 2e 7a 54  ate echo_vtab.zT
29d0: 68 69 73 20 2a 2f 0a 20 20 70 56 74 61 62 2d 3e  his */.  pVtab->
29e0: 7a 54 68 69 73 20 3d 20 73 71 6c 69 74 65 33 4d  zThis = sqlite3M
29f0: 50 72 69 6e 74 66 28 30 2c 20 22 25 73 22 2c 20  Printf(0, "%s", 
2a00: 61 72 67 76 5b 32 5d 29 3b 0a 20 20 69 66 28 20  argv[2]);.  if( 
2a10: 21 70 56 74 61 62 2d 3e 7a 54 68 69 73 20 29 7b  !pVtab->zThis ){
2a20: 0a 20 20 20 20 65 63 68 6f 44 65 73 74 72 75 63  .    echoDestruc
2a30: 74 6f 72 28 28 73 71 6c 69 74 65 33 5f 76 74 61  tor((sqlite3_vta
2a40: 62 20 2a 29 70 56 74 61 62 29 3b 0a 20 20 20 20  b *)pVtab);.    
2a50: 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f  return SQLITE_NO
2a60: 4d 45 4d 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 41  MEM;.  }..  /* A
2a70: 6c 6c 6f 63 61 74 65 20 65 63 68 6f 5f 76 74 61  llocate echo_vta
2a80: 62 2e 7a 54 61 62 6c 65 4e 61 6d 65 20 2a 2f 0a  b.zTableName */.
2a90: 20 20 69 66 28 20 61 72 67 63 3e 33 20 29 7b 0a    if( argc>3 ){.
2aa0: 20 20 20 20 70 56 74 61 62 2d 3e 7a 54 61 62 6c      pVtab->zTabl
2ab0: 65 4e 61 6d 65 20 3d 20 73 71 6c 69 74 65 33 4d  eName = sqlite3M
2ac0: 50 72 69 6e 74 66 28 30 2c 20 22 25 73 22 2c 20  Printf(0, "%s", 
2ad0: 61 72 67 76 5b 33 5d 29 3b 0a 20 20 20 20 64 65  argv[3]);.    de
2ae0: 71 75 6f 74 65 53 74 72 69 6e 67 28 70 56 74 61  quoteString(pVta
2af0: 62 2d 3e 7a 54 61 62 6c 65 4e 61 6d 65 29 3b 0a  b->zTableName);.
2b00: 20 20 20 20 69 66 28 20 70 56 74 61 62 2d 3e 7a      if( pVtab->z
2b10: 54 61 62 6c 65 4e 61 6d 65 20 26 26 20 70 56 74  TableName && pVt
2b20: 61 62 2d 3e 7a 54 61 62 6c 65 4e 61 6d 65 5b 30  ab->zTableName[0
2b30: 5d 3d 3d 27 2a 27 20 29 7b 0a 20 20 20 20 20 20  ]=='*' ){.      
2b40: 63 68 61 72 20 2a 7a 20 3d 20 73 71 6c 69 74 65  char *z = sqlite
2b50: 33 4d 50 72 69 6e 74 66 28 30 2c 20 22 25 73 25  3MPrintf(0, "%s%
2b60: 73 22 2c 20 61 72 67 76 5b 32 5d 2c 20 26 28 70  s", argv[2], &(p
2b70: 56 74 61 62 2d 3e 7a 54 61 62 6c 65 4e 61 6d 65  Vtab->zTableName
2b80: 5b 31 5d 29 29 3b 0a 20 20 20 20 20 20 73 71 6c  [1]));.      sql
2b90: 69 74 65 33 5f 66 72 65 65 28 70 56 74 61 62 2d  ite3_free(pVtab-
2ba0: 3e 7a 54 61 62 6c 65 4e 61 6d 65 29 3b 0a 20 20  >zTableName);.  
2bb0: 20 20 20 20 70 56 74 61 62 2d 3e 7a 54 61 62 6c      pVtab->zTabl
2bc0: 65 4e 61 6d 65 20 3d 20 7a 3b 0a 20 20 20 20 20  eName = z;.     
2bd0: 20 70 56 74 61 62 2d 3e 69 73 50 61 74 74 65 72   pVtab->isPatter
2be0: 6e 20 3d 20 31 3b 0a 20 20 20 20 7d 0a 20 20 20  n = 1;.    }.   
2bf0: 20 69 66 28 20 21 70 56 74 61 62 2d 3e 7a 54 61   if( !pVtab->zTa
2c00: 62 6c 65 4e 61 6d 65 20 29 7b 0a 20 20 20 20 20  bleName ){.     
2c10: 20 65 63 68 6f 44 65 73 74 72 75 63 74 6f 72 28   echoDestructor(
2c20: 28 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 29  (sqlite3_vtab *)
2c30: 70 56 74 61 62 29 3b 0a 20 20 20 20 20 20 72 65  pVtab);.      re
2c40: 74 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45  turn SQLITE_NOME
2c50: 4d 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20  M;.    }.  }..  
2c60: 2f 2a 20 4c 6f 67 20 74 68 65 20 61 72 67 75 6d  /* Log the argum
2c70: 65 6e 74 73 20 74 6f 20 74 68 69 73 20 66 75 6e  ents to this fun
2c80: 63 74 69 6f 6e 20 74 6f 20 54 63 6c 20 76 61 72  ction to Tcl var
2c90: 20 3a 3a 65 63 68 6f 5f 6d 6f 64 75 6c 65 20 2a   ::echo_module *
2ca0: 2f 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 61  /.  for(i=0; i<a
2cb0: 72 67 63 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 61  rgc; i++){.    a
2cc0: 70 70 65 6e 64 54 6f 45 63 68 6f 4d 6f 64 75 6c  ppendToEchoModul
2cd0: 65 28 70 56 74 61 62 2d 3e 69 6e 74 65 72 70 2c  e(pVtab->interp,
2ce0: 20 61 72 67 76 5b 69 5d 29 3b 0a 20 20 7d 0a 0a   argv[i]);.  }..
2cf0: 20 20 2f 2a 20 49 6e 76 6f 6b 65 20 73 71 6c 69    /* Invoke sqli
2d00: 74 65 33 5f 64 65 63 6c 61 72 65 5f 76 74 61 62  te3_declare_vtab
2d10: 20 61 6e 64 20 73 65 74 20 75 70 20 6f 74 68 65   and set up othe
2d20: 72 20 6d 65 6d 62 65 72 73 20 6f 66 20 74 68 65  r members of the
2d30: 20 65 63 68 6f 5f 76 74 61 62 0a 20 20 2a 2a 20   echo_vtab.  ** 
2d40: 73 74 72 75 63 74 75 72 65 2e 20 49 66 20 61 6e  structure. If an
2d50: 20 65 72 72 6f 72 20 6f 63 63 75 72 73 2c 20 64   error occurs, d
2d60: 65 6c 65 74 65 20 74 68 65 20 73 71 6c 69 74 65  elete the sqlite
2d70: 33 5f 76 74 61 62 20 73 74 72 75 63 74 75 72 65  3_vtab structure
2d80: 20 61 6e 64 0a 20 20 2a 2a 20 72 65 74 75 72 6e   and.  ** return
2d90: 20 61 6e 20 65 72 72 6f 72 20 63 6f 64 65 2e 0a   an error code..
2da0: 20 20 2a 2f 0a 20 20 72 63 20 3d 20 65 63 68 6f    */.  rc = echo
2db0: 44 65 63 6c 61 72 65 56 74 61 62 28 70 56 74 61  DeclareVtab(pVta
2dc0: 62 2c 20 64 62 29 3b 0a 20 20 69 66 28 20 72 63  b, db);.  if( rc
2dd0: 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  !=SQLITE_OK ){. 
2de0: 20 20 20 65 63 68 6f 44 65 73 74 72 75 63 74 6f     echoDestructo
2df0: 72 28 28 73 71 6c 69 74 65 33 5f 76 74 61 62 20  r((sqlite3_vtab 
2e00: 2a 29 70 56 74 61 62 29 3b 0a 20 20 20 20 72 65  *)pVtab);.    re
2e10: 74 75 72 6e 20 72 63 3b 0a 20 20 7d 0a 0a 20 20  turn rc;.  }..  
2e20: 2f 2a 20 53 75 63 63 65 73 73 2e 20 53 65 74 20  /* Success. Set 
2e30: 2a 70 70 56 74 61 62 20 61 6e 64 20 72 65 74 75  *ppVtab and retu
2e40: 72 6e 20 2a 2f 0a 20 20 2a 70 70 56 74 61 62 20  rn */.  *ppVtab 
2e50: 3d 20 26 70 56 74 61 62 2d 3e 62 61 73 65 3b 0a  = &pVtab->base;.
2e60: 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f    return SQLITE_
2e70: 4f 4b 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 45 63  OK;.}../* .** Ec
2e80: 68 6f 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65  ho virtual table
2e90: 20 6d 6f 64 75 6c 65 20 78 43 72 65 61 74 65 20   module xCreate 
2ea0: 6d 65 74 68 6f 64 2e 0a 2a 2f 0a 73 74 61 74 69  method..*/.stati
2eb0: 63 20 69 6e 74 20 65 63 68 6f 43 72 65 61 74 65  c int echoCreate
2ec0: 28 0a 20 20 73 71 6c 69 74 65 33 20 2a 64 62 2c  (.  sqlite3 *db,
2ed0: 0a 20 20 76 6f 69 64 20 2a 70 41 75 78 2c 0a 20  .  void *pAux,. 
2ee0: 20 69 6e 74 20 61 72 67 63 2c 20 63 6f 6e 73 74   int argc, const
2ef0: 20 63 68 61 72 20 2a 63 6f 6e 73 74 2a 61 72 67   char *const*arg
2f00: 76 2c 0a 20 20 73 71 6c 69 74 65 33 5f 76 74 61  v,.  sqlite3_vta
2f10: 62 20 2a 2a 70 70 56 74 61 62 2c 0a 20 20 63 68  b **ppVtab,.  ch
2f20: 61 72 20 2a 2a 70 7a 45 72 72 0a 29 7b 0a 20 20  ar **pzErr.){.  
2f30: 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f  int rc = SQLITE_
2f40: 4f 4b 3b 0a 20 20 61 70 70 65 6e 64 54 6f 45 63  OK;.  appendToEc
2f50: 68 6f 4d 6f 64 75 6c 65 28 28 28 45 63 68 6f 4d  hoModule(((EchoM
2f60: 6f 64 75 6c 65 20 2a 29 70 41 75 78 29 2d 3e 69  odule *)pAux)->i
2f70: 6e 74 65 72 70 2c 20 22 78 43 72 65 61 74 65 22  nterp, "xCreate"
2f80: 29 3b 0a 20 20 72 63 20 3d 20 65 63 68 6f 43 6f  );.  rc = echoCo
2f90: 6e 73 74 72 75 63 74 6f 72 28 64 62 2c 20 70 41  nstructor(db, pA
2fa0: 75 78 2c 20 61 72 67 63 2c 20 61 72 67 76 2c 20  ux, argc, argv, 
2fb0: 70 70 56 74 61 62 2c 20 70 7a 45 72 72 29 3b 0a  ppVtab, pzErr);.
2fc0: 0a 20 20 2f 2a 20 49 66 20 74 68 65 72 65 20 77  .  /* If there w
2fd0: 65 72 65 20 74 77 6f 20 61 72 67 75 6d 65 6e 74  ere two argument
2fe0: 73 20 70 61 73 73 65 64 20 74 6f 20 74 68 65 20  s passed to the 
2ff0: 6d 6f 64 75 6c 65 20 61 74 20 74 68 65 20 53 51  module at the SQ
3000: 4c 20 6c 65 76 65 6c 20 0a 20 20 2a 2a 20 28 69  L level .  ** (i
3010: 2e 65 2e 20 22 43 52 45 41 54 45 20 56 49 52 54  .e. "CREATE VIRT
3020: 55 41 4c 20 54 41 42 4c 45 20 74 62 6c 20 55 53  UAL TABLE tbl US
3030: 49 4e 47 20 65 63 68 6f 28 61 72 67 31 2c 20 61  ING echo(arg1, a
3040: 72 67 32 29 22 29 2c 20 74 68 65 6e 20 0a 20 20  rg2)"), then .  
3050: 2a 2a 20 74 68 65 20 73 65 63 6f 6e 64 20 61 72  ** the second ar
3060: 67 75 6d 65 6e 74 20 69 73 20 75 73 65 64 20 61  gument is used a
3070: 73 20 61 20 74 61 62 6c 65 20 6e 61 6d 65 2e 20  s a table name. 
3080: 41 74 74 65 6d 70 74 20 74 6f 20 63 72 65 61 74  Attempt to creat
3090: 65 0a 20 20 2a 2a 20 73 75 63 68 20 61 20 74 61  e.  ** such a ta
30a0: 62 6c 65 20 77 69 74 68 20 61 20 73 69 6e 67 6c  ble with a singl
30b0: 65 20 63 6f 6c 75 6d 6e 2c 20 22 6c 6f 67 6d 73  e column, "logms
30c0: 67 22 2e 20 54 68 69 73 20 74 61 62 6c 65 20 77  g". This table w
30d0: 69 6c 6c 0a 20 20 2a 2a 20 62 65 20 75 73 65 64  ill.  ** be used
30e0: 20 74 6f 20 6c 6f 67 20 63 61 6c 6c 73 20 74 6f   to log calls to
30f0: 20 74 68 65 20 78 55 70 64 61 74 65 20 6d 65 74   the xUpdate met
3100: 68 6f 64 2e 20 49 74 20 77 69 6c 6c 20 62 65 20  hod. It will be 
3110: 64 65 6c 65 74 65 64 0a 20 20 2a 2a 20 77 68 65  deleted.  ** whe
3120: 6e 20 74 68 65 20 76 69 72 74 75 61 6c 20 74 61  n the virtual ta
3130: 62 6c 65 20 69 73 20 44 52 4f 50 65 64 2e 0a 20  ble is DROPed.. 
3140: 20 2a 2a 0a 20 20 2a 2a 20 4e 6f 74 65 3a 20 54   **.  ** Note: T
3150: 68 65 20 6d 61 69 6e 20 70 6f 69 6e 74 20 6f 66  he main point of
3160: 20 74 68 69 73 20 69 73 20 74 6f 20 74 65 73 74   this is to test
3170: 20 74 68 61 74 20 77 65 20 63 61 6e 20 64 72 6f   that we can dro
3180: 70 20 74 61 62 6c 65 73 0a 20 20 2a 2a 20 66 72  p tables.  ** fr
3190: 6f 6d 20 77 69 74 68 69 6e 20 61 6e 20 78 44 65  om within an xDe
31a0: 73 74 72 6f 79 20 6d 65 74 68 6f 64 20 63 61 6c  stroy method cal
31b0: 6c 2e 0a 20 20 2a 2f 0a 20 20 69 66 28 20 72 63  l..  */.  if( rc
31c0: 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20 61  ==SQLITE_OK && a
31d0: 72 67 63 3d 3d 35 20 29 7b 0a 20 20 20 20 63 68  rgc==5 ){.    ch
31e0: 61 72 20 2a 7a 53 71 6c 3b 0a 20 20 20 20 65 63  ar *zSql;.    ec
31f0: 68 6f 5f 76 74 61 62 20 2a 70 56 74 61 62 20 3d  ho_vtab *pVtab =
3200: 20 2a 28 65 63 68 6f 5f 76 74 61 62 20 2a 2a 29   *(echo_vtab **)
3210: 70 70 56 74 61 62 3b 0a 20 20 20 20 70 56 74 61  ppVtab;.    pVta
3220: 62 2d 3e 7a 4c 6f 67 4e 61 6d 65 20 3d 20 73 71  b->zLogName = sq
3230: 6c 69 74 65 33 4d 50 72 69 6e 74 66 28 30 2c 20  lite3MPrintf(0, 
3240: 22 25 73 22 2c 20 61 72 67 76 5b 34 5d 29 3b 0a  "%s", argv[4]);.
3250: 20 20 20 20 7a 53 71 6c 20 3d 20 73 71 6c 69 74      zSql = sqlit
3260: 65 33 4d 50 72 69 6e 74 66 28 30 2c 20 22 43 52  e3MPrintf(0, "CR
3270: 45 41 54 45 20 54 41 42 4c 45 20 25 51 28 6c 6f  EATE TABLE %Q(lo
3280: 67 6d 73 67 29 22 2c 20 70 56 74 61 62 2d 3e 7a  gmsg)", pVtab->z
3290: 4c 6f 67 4e 61 6d 65 29 3b 0a 20 20 20 20 72 63  LogName);.    rc
32a0: 20 3d 20 73 71 6c 69 74 65 33 5f 65 78 65 63 28   = sqlite3_exec(
32b0: 64 62 2c 20 7a 53 71 6c 2c 20 30 2c 20 30 2c 20  db, zSql, 0, 0, 
32c0: 30 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f  0);.    sqlite3_
32d0: 66 72 65 65 28 7a 53 71 6c 29 3b 0a 20 20 7d 0a  free(zSql);.  }.
32e0: 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a  .  return rc;.}.
32f0: 0a 2f 2a 20 0a 2a 2a 20 45 63 68 6f 20 76 69 72  ./* .** Echo vir
3300: 74 75 61 6c 20 74 61 62 6c 65 20 6d 6f 64 75 6c  tual table modul
3310: 65 20 78 43 6f 6e 6e 65 63 74 20 6d 65 74 68 6f  e xConnect metho
3320: 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  d..*/.static int
3330: 20 65 63 68 6f 43 6f 6e 6e 65 63 74 28 0a 20 20   echoConnect(.  
3340: 73 71 6c 69 74 65 33 20 2a 64 62 2c 0a 20 20 76  sqlite3 *db,.  v
3350: 6f 69 64 20 2a 70 41 75 78 2c 0a 20 20 69 6e 74  oid *pAux,.  int
3360: 20 61 72 67 63 2c 20 63 6f 6e 73 74 20 63 68 61   argc, const cha
3370: 72 20 2a 63 6f 6e 73 74 2a 61 72 67 76 2c 0a 20  r *const*argv,. 
3380: 20 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 2a   sqlite3_vtab **
3390: 70 70 56 74 61 62 2c 0a 20 20 63 68 61 72 20 2a  ppVtab,.  char *
33a0: 2a 70 7a 45 72 72 0a 29 7b 0a 20 20 61 70 70 65  *pzErr.){.  appe
33b0: 6e 64 54 6f 45 63 68 6f 4d 6f 64 75 6c 65 28 28  ndToEchoModule((
33c0: 28 45 63 68 6f 4d 6f 64 75 6c 65 20 2a 29 70 41  (EchoModule *)pA
33d0: 75 78 29 2d 3e 69 6e 74 65 72 70 2c 20 22 78 43  ux)->interp, "xC
33e0: 6f 6e 6e 65 63 74 22 29 3b 0a 20 20 72 65 74 75  onnect");.  retu
33f0: 72 6e 20 65 63 68 6f 43 6f 6e 73 74 72 75 63 74  rn echoConstruct
3400: 6f 72 28 64 62 2c 20 70 41 75 78 2c 20 61 72 67  or(db, pAux, arg
3410: 63 2c 20 61 72 67 76 2c 20 70 70 56 74 61 62 2c  c, argv, ppVtab,
3420: 20 70 7a 45 72 72 29 3b 0a 7d 0a 0a 2f 2a 20 0a   pzErr);.}../* .
3430: 2a 2a 20 45 63 68 6f 20 76 69 72 74 75 61 6c 20  ** Echo virtual 
3440: 74 61 62 6c 65 20 6d 6f 64 75 6c 65 20 78 44 69  table module xDi
3450: 73 63 6f 6e 6e 65 63 74 20 6d 65 74 68 6f 64 2e  sconnect method.
3460: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 65  .*/.static int e
3470: 63 68 6f 44 69 73 63 6f 6e 6e 65 63 74 28 73 71  choDisconnect(sq
3480: 6c 69 74 65 33 5f 76 74 61 62 20 2a 70 56 74 61  lite3_vtab *pVta
3490: 62 29 7b 0a 20 20 61 70 70 65 6e 64 54 6f 45 63  b){.  appendToEc
34a0: 68 6f 4d 6f 64 75 6c 65 28 28 28 65 63 68 6f 5f  hoModule(((echo_
34b0: 76 74 61 62 20 2a 29 70 56 74 61 62 29 2d 3e 69  vtab *)pVtab)->i
34c0: 6e 74 65 72 70 2c 20 22 78 44 69 73 63 6f 6e 6e  nterp, "xDisconn
34d0: 65 63 74 22 29 3b 0a 20 20 72 65 74 75 72 6e 20  ect");.  return 
34e0: 65 63 68 6f 44 65 73 74 72 75 63 74 6f 72 28 70  echoDestructor(p
34f0: 56 74 61 62 29 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a  Vtab);.}../* .**
3500: 20 45 63 68 6f 20 76 69 72 74 75 61 6c 20 74 61   Echo virtual ta
3510: 62 6c 65 20 6d 6f 64 75 6c 65 20 78 44 65 73 74  ble module xDest
3520: 72 6f 79 20 6d 65 74 68 6f 64 2e 0a 2a 2f 0a 73  roy method..*/.s
3530: 74 61 74 69 63 20 69 6e 74 20 65 63 68 6f 44 65  tatic int echoDe
3540: 73 74 72 6f 79 28 73 71 6c 69 74 65 33 5f 76 74  stroy(sqlite3_vt
3550: 61 62 20 2a 70 56 74 61 62 29 7b 0a 20 20 69 6e  ab *pVtab){.  in
3560: 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b  t rc = SQLITE_OK
3570: 3b 0a 20 20 65 63 68 6f 5f 76 74 61 62 20 2a 70  ;.  echo_vtab *p
3580: 20 3d 20 28 65 63 68 6f 5f 76 74 61 62 20 2a 29   = (echo_vtab *)
3590: 70 56 74 61 62 3b 0a 20 20 61 70 70 65 6e 64 54  pVtab;.  appendT
35a0: 6f 45 63 68 6f 4d 6f 64 75 6c 65 28 28 28 65 63  oEchoModule(((ec
35b0: 68 6f 5f 76 74 61 62 20 2a 29 70 56 74 61 62 29  ho_vtab *)pVtab)
35c0: 2d 3e 69 6e 74 65 72 70 2c 20 22 78 44 65 73 74  ->interp, "xDest
35d0: 72 6f 79 22 29 3b 0a 0a 20 20 2f 2a 20 44 72 6f  roy");..  /* Dro
35e0: 70 20 74 68 65 20 22 6c 6f 67 22 20 74 61 62 6c  p the "log" tabl
35f0: 65 2c 20 69 66 20 6f 6e 65 20 65 78 69 73 74 73  e, if one exists
3600: 20 28 73 65 65 20 65 63 68 6f 43 72 65 61 74 65   (see echoCreate
3610: 28 29 20 66 6f 72 20 64 65 74 61 69 6c 73 29 20  () for details) 
3620: 2a 2f 0a 20 20 69 66 28 20 70 20 26 26 20 70 2d  */.  if( p && p-
3630: 3e 7a 4c 6f 67 4e 61 6d 65 20 29 7b 0a 20 20 20  >zLogName ){.   
3640: 20 63 68 61 72 20 2a 7a 53 71 6c 3b 0a 20 20 20   char *zSql;.   
3650: 20 7a 53 71 6c 20 3d 20 73 71 6c 69 74 65 33 4d   zSql = sqlite3M
3660: 50 72 69 6e 74 66 28 30 2c 20 22 44 52 4f 50 20  Printf(0, "DROP 
3670: 54 41 42 4c 45 20 25 51 22 2c 20 70 2d 3e 7a 4c  TABLE %Q", p->zL
3680: 6f 67 4e 61 6d 65 29 3b 0a 20 20 20 20 72 63 20  ogName);.    rc 
3690: 3d 20 73 71 6c 69 74 65 33 5f 65 78 65 63 28 70  = sqlite3_exec(p
36a0: 2d 3e 64 62 2c 20 7a 53 71 6c 2c 20 30 2c 20 30  ->db, zSql, 0, 0
36b0: 2c 20 30 29 3b 0a 20 20 20 20 73 71 6c 69 74 65  , 0);.    sqlite
36c0: 33 5f 66 72 65 65 28 7a 53 71 6c 29 3b 0a 20 20  3_free(zSql);.  
36d0: 7d 0a 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c  }..  if( rc==SQL
36e0: 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 72 63  ITE_OK ){.    rc
36f0: 20 3d 20 65 63 68 6f 44 65 73 74 72 75 63 74 6f   = echoDestructo
3700: 72 28 70 56 74 61 62 29 3b 0a 20 20 7d 0a 20 20  r(pVtab);.  }.  
3710: 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a  return rc;.}../*
3720: 20 0a 2a 2a 20 45 63 68 6f 20 76 69 72 74 75 61   .** Echo virtua
3730: 6c 20 74 61 62 6c 65 20 6d 6f 64 75 6c 65 20 78  l table module x
3740: 4f 70 65 6e 20 6d 65 74 68 6f 64 2e 0a 2a 2f 0a  Open method..*/.
3750: 73 74 61 74 69 63 20 69 6e 74 20 65 63 68 6f 4f  static int echoO
3760: 70 65 6e 28 73 71 6c 69 74 65 33 5f 76 74 61 62  pen(sqlite3_vtab
3770: 20 2a 70 56 54 61 62 2c 20 73 71 6c 69 74 65 33   *pVTab, sqlite3
3780: 5f 76 74 61 62 5f 63 75 72 73 6f 72 20 2a 2a 70  _vtab_cursor **p
3790: 70 43 75 72 73 6f 72 29 7b 0a 20 20 65 63 68 6f  pCursor){.  echo
37a0: 5f 63 75 72 73 6f 72 20 2a 70 43 75 72 3b 0a 20  _cursor *pCur;. 
37b0: 20 70 43 75 72 20 3d 20 73 71 6c 69 74 65 33 4d   pCur = sqlite3M
37c0: 61 6c 6c 6f 63 5a 65 72 6f 28 73 69 7a 65 6f 66  allocZero(sizeof
37d0: 28 65 63 68 6f 5f 63 75 72 73 6f 72 29 29 3b 0a  (echo_cursor));.
37e0: 20 20 2a 70 70 43 75 72 73 6f 72 20 3d 20 28 73    *ppCursor = (s
37f0: 71 6c 69 74 65 33 5f 76 74 61 62 5f 63 75 72 73  qlite3_vtab_curs
3800: 6f 72 20 2a 29 70 43 75 72 3b 0a 20 20 72 65 74  or *)pCur;.  ret
3810: 75 72 6e 20 28 70 43 75 72 20 3f 20 53 51 4c 49  urn (pCur ? SQLI
3820: 54 45 5f 4f 4b 20 3a 20 53 51 4c 49 54 45 5f 4e  TE_OK : SQLITE_N
3830: 4f 4d 45 4d 29 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a  OMEM);.}../* .**
3840: 20 45 63 68 6f 20 76 69 72 74 75 61 6c 20 74 61   Echo virtual ta
3850: 62 6c 65 20 6d 6f 64 75 6c 65 20 78 43 6c 6f 73  ble module xClos
3860: 65 20 6d 65 74 68 6f 64 2e 0a 2a 2f 0a 73 74 61  e method..*/.sta
3870: 74 69 63 20 69 6e 74 20 65 63 68 6f 43 6c 6f 73  tic int echoClos
3880: 65 28 73 71 6c 69 74 65 33 5f 76 74 61 62 5f 63  e(sqlite3_vtab_c
3890: 75 72 73 6f 72 20 2a 63 75 72 29 7b 0a 20 20 69  ursor *cur){.  i
38a0: 6e 74 20 72 63 3b 0a 20 20 65 63 68 6f 5f 63 75  nt rc;.  echo_cu
38b0: 72 73 6f 72 20 2a 70 43 75 72 20 3d 20 28 65 63  rsor *pCur = (ec
38c0: 68 6f 5f 63 75 72 73 6f 72 20 2a 29 63 75 72 3b  ho_cursor *)cur;
38d0: 0a 20 20 73 71 6c 69 74 65 33 5f 73 74 6d 74 20  .  sqlite3_stmt 
38e0: 2a 70 53 74 6d 74 20 3d 20 70 43 75 72 2d 3e 70  *pStmt = pCur->p
38f0: 53 74 6d 74 3b 0a 20 20 70 43 75 72 2d 3e 70 53  Stmt;.  pCur->pS
3900: 74 6d 74 20 3d 20 30 3b 0a 20 20 73 71 6c 69 74  tmt = 0;.  sqlit
3910: 65 33 5f 66 72 65 65 28 70 43 75 72 29 3b 0a 20  e3_free(pCur);. 
3920: 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 66 69   rc = sqlite3_fi
3930: 6e 61 6c 69 7a 65 28 70 53 74 6d 74 29 3b 0a 20  nalize(pStmt);. 
3940: 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f   return rc;.}../
3950: 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 6e 6f 6e 2d  *.** Return non-
3960: 7a 65 72 6f 20 69 66 20 74 68 65 20 63 75 72 73  zero if the curs
3970: 6f 72 20 64 6f 65 73 20 6e 6f 74 20 63 75 72 72  or does not curr
3980: 65 6e 74 6c 79 20 70 6f 69 6e 74 20 74 6f 20 61  ently point to a
3990: 20 76 61 6c 69 64 20 72 65 63 6f 72 64 0a 2a 2a   valid record.**
39a0: 20 28 69 2e 65 20 69 66 20 74 68 65 20 73 63 61   (i.e if the sca
39b0: 6e 20 68 61 73 20 66 69 6e 69 73 68 65 64 29 2c  n has finished),
39c0: 20 6f 72 20 7a 65 72 6f 20 6f 74 68 65 72 77 69   or zero otherwi
39d0: 73 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  se..*/.static in
39e0: 74 20 65 63 68 6f 45 6f 66 28 73 71 6c 69 74 65  t echoEof(sqlite
39f0: 33 5f 76 74 61 62 5f 63 75 72 73 6f 72 20 2a 63  3_vtab_cursor *c
3a00: 75 72 29 7b 0a 20 20 72 65 74 75 72 6e 20 28 28  ur){.  return ((
3a10: 28 65 63 68 6f 5f 63 75 72 73 6f 72 20 2a 29 63  (echo_cursor *)c
3a20: 75 72 29 2d 3e 70 53 74 6d 74 20 3f 20 30 20 3a  ur)->pStmt ? 0 :
3a30: 20 31 29 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 45   1);.}../* .** E
3a40: 63 68 6f 20 76 69 72 74 75 61 6c 20 74 61 62 6c  cho virtual tabl
3a50: 65 20 6d 6f 64 75 6c 65 20 78 4e 65 78 74 20 6d  e module xNext m
3a60: 65 74 68 6f 64 2e 0a 2a 2f 0a 73 74 61 74 69 63  ethod..*/.static
3a70: 20 69 6e 74 20 65 63 68 6f 4e 65 78 74 28 73 71   int echoNext(sq
3a80: 6c 69 74 65 33 5f 76 74 61 62 5f 63 75 72 73 6f  lite3_vtab_curso
3a90: 72 20 2a 63 75 72 29 7b 0a 20 20 69 6e 74 20 72  r *cur){.  int r
3aa0: 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20  c = SQLITE_OK;. 
3ab0: 20 65 63 68 6f 5f 63 75 72 73 6f 72 20 2a 70 43   echo_cursor *pC
3ac0: 75 72 20 3d 20 28 65 63 68 6f 5f 63 75 72 73 6f  ur = (echo_curso
3ad0: 72 20 2a 29 63 75 72 3b 0a 0a 20 20 69 66 28 20  r *)cur;..  if( 
3ae0: 70 43 75 72 2d 3e 70 53 74 6d 74 20 29 7b 0a 20  pCur->pStmt ){. 
3af0: 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f     rc = sqlite3_
3b00: 73 74 65 70 28 70 43 75 72 2d 3e 70 53 74 6d 74  step(pCur->pStmt
3b10: 29 3b 0a 20 20 20 20 69 66 28 20 72 63 3d 3d 53  );.    if( rc==S
3b20: 51 4c 49 54 45 5f 52 4f 57 20 29 7b 0a 20 20 20  QLITE_ROW ){.   
3b30: 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f     rc = SQLITE_O
3b40: 4b 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20  K;.    }else{.  
3b50: 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33      rc = sqlite3
3b60: 5f 66 69 6e 61 6c 69 7a 65 28 70 43 75 72 2d 3e  _finalize(pCur->
3b70: 70 53 74 6d 74 29 3b 0a 20 20 20 20 20 20 70 43  pStmt);.      pC
3b80: 75 72 2d 3e 70 53 74 6d 74 20 3d 20 30 3b 0a 20  ur->pStmt = 0;. 
3b90: 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 72 65 74 75     }.  }..  retu
3ba0: 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a  rn rc;.}../* .**
3bb0: 20 45 63 68 6f 20 76 69 72 74 75 61 6c 20 74 61   Echo virtual ta
3bc0: 62 6c 65 20 6d 6f 64 75 6c 65 20 78 43 6f 6c 75  ble module xColu
3bd0: 6d 6e 20 6d 65 74 68 6f 64 2e 0a 2a 2f 0a 73 74  mn method..*/.st
3be0: 61 74 69 63 20 69 6e 74 20 65 63 68 6f 43 6f 6c  atic int echoCol
3bf0: 75 6d 6e 28 73 71 6c 69 74 65 33 5f 76 74 61 62  umn(sqlite3_vtab
3c00: 5f 63 75 72 73 6f 72 20 2a 63 75 72 2c 20 73 71  _cursor *cur, sq
3c10: 6c 69 74 65 33 5f 63 6f 6e 74 65 78 74 20 2a 63  lite3_context *c
3c20: 74 78 2c 20 69 6e 74 20 69 29 7b 0a 20 20 69 6e  tx, int i){.  in
3c30: 74 20 69 43 6f 6c 20 3d 20 69 20 2b 20 31 3b 0a  t iCol = i + 1;.
3c40: 20 20 73 71 6c 69 74 65 33 5f 73 74 6d 74 20 2a    sqlite3_stmt *
3c50: 70 53 74 6d 74 20 3d 20 28 28 65 63 68 6f 5f 63  pStmt = ((echo_c
3c60: 75 72 73 6f 72 20 2a 29 63 75 72 29 2d 3e 70 53  ursor *)cur)->pS
3c70: 74 6d 74 3b 0a 20 20 69 66 28 20 21 70 53 74 6d  tmt;.  if( !pStm
3c80: 74 20 29 7b 0a 20 20 20 20 73 71 6c 69 74 65 33  t ){.    sqlite3
3c90: 5f 72 65 73 75 6c 74 5f 6e 75 6c 6c 28 63 74 78  _result_null(ctx
3ca0: 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  );.  }else{.    
3cb0: 61 73 73 65 72 74 28 20 73 71 6c 69 74 65 33 5f  assert( sqlite3_
3cc0: 64 61 74 61 5f 63 6f 75 6e 74 28 70 53 74 6d 74  data_count(pStmt
3cd0: 29 3e 69 43 6f 6c 20 29 3b 0a 20 20 20 20 73 71  )>iCol );.    sq
3ce0: 6c 69 74 65 33 5f 72 65 73 75 6c 74 5f 76 61 6c  lite3_result_val
3cf0: 75 65 28 63 74 78 2c 20 73 71 6c 69 74 65 33 5f  ue(ctx, sqlite3_
3d00: 63 6f 6c 75 6d 6e 5f 76 61 6c 75 65 28 70 53 74  column_value(pSt
3d10: 6d 74 2c 20 69 43 6f 6c 29 29 3b 0a 20 20 7d 0a  mt, iCol));.  }.
3d20: 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f    return SQLITE_
3d30: 4f 4b 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 45 63  OK;.}../* .** Ec
3d40: 68 6f 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65  ho virtual table
3d50: 20 6d 6f 64 75 6c 65 20 78 52 6f 77 69 64 20 6d   module xRowid m
3d60: 65 74 68 6f 64 2e 0a 2a 2f 0a 73 74 61 74 69 63  ethod..*/.static
3d70: 20 69 6e 74 20 65 63 68 6f 52 6f 77 69 64 28 73   int echoRowid(s
3d80: 71 6c 69 74 65 33 5f 76 74 61 62 5f 63 75 72 73  qlite3_vtab_curs
3d90: 6f 72 20 2a 63 75 72 2c 20 73 71 6c 69 74 65 5f  or *cur, sqlite_
3da0: 69 6e 74 36 34 20 2a 70 52 6f 77 69 64 29 7b 0a  int64 *pRowid){.
3db0: 20 20 73 71 6c 69 74 65 33 5f 73 74 6d 74 20 2a    sqlite3_stmt *
3dc0: 70 53 74 6d 74 20 3d 20 28 28 65 63 68 6f 5f 63  pStmt = ((echo_c
3dd0: 75 72 73 6f 72 20 2a 29 63 75 72 29 2d 3e 70 53  ursor *)cur)->pS
3de0: 74 6d 74 3b 0a 20 20 2a 70 52 6f 77 69 64 20 3d  tmt;.  *pRowid =
3df0: 20 73 71 6c 69 74 65 33 5f 63 6f 6c 75 6d 6e 5f   sqlite3_column_
3e00: 69 6e 74 36 34 28 70 53 74 6d 74 2c 20 30 29 3b  int64(pStmt, 0);
3e10: 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45  .  return SQLITE
3e20: 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 6f  _OK;.}../*.** Co
3e30: 6d 70 75 74 65 20 61 20 73 69 6d 70 6c 65 20 68  mpute a simple h
3e40: 61 73 68 20 6f 66 20 74 68 65 20 6e 75 6c 6c 20  ash of the null 
3e50: 74 65 72 6d 69 6e 61 74 65 64 20 73 74 72 69 6e  terminated strin
3e60: 67 20 7a 53 74 72 69 6e 67 2e 0a 2a 2a 0a 2a 2a  g zString..**.**
3e70: 20 54 68 69 73 20 6d 6f 64 75 6c 65 20 75 73 65   This module use
3e80: 73 20 6f 6e 6c 79 20 73 71 6c 69 74 65 33 5f 69  s only sqlite3_i
3e90: 6e 64 65 78 5f 69 6e 66 6f 2e 69 64 78 53 74 72  ndex_info.idxStr
3ea0: 2c 20 6e 6f 74 20 0a 2a 2a 20 73 71 6c 69 74 65  , not .** sqlite
3eb0: 33 5f 69 6e 64 65 78 5f 69 6e 66 6f 2e 69 64 78  3_index_info.idx
3ec0: 4e 75 6d 2e 20 53 6f 20 74 6f 20 74 65 73 74 20  Num. So to test 
3ed0: 69 64 78 4e 75 6d 2c 20 77 68 65 6e 20 69 64 78  idxNum, when idx
3ee0: 53 74 72 20 69 73 20 73 65 74 0a 2a 2a 20 69 6e  Str is set.** in
3ef0: 20 65 63 68 6f 42 65 73 74 49 6e 64 65 78 28 29   echoBestIndex()
3f00: 2c 20 69 64 78 4e 75 6d 20 69 73 20 73 65 74 20  , idxNum is set 
3f10: 74 6f 20 74 68 65 20 63 6f 72 72 65 73 70 6f 6e  to the correspon
3f20: 64 69 6e 67 20 68 61 73 68 20 76 61 6c 75 65 2e  ding hash value.
3f30: 0a 2a 2a 20 49 6e 20 65 63 68 6f 46 69 6c 74 65  .** In echoFilte
3f40: 72 28 29 2c 20 63 6f 64 65 20 61 73 73 65 72 74  r(), code assert
3f50: 28 29 73 20 74 68 61 74 20 74 68 65 20 73 75 70  ()s that the sup
3f60: 70 6c 69 65 64 20 69 64 78 4e 75 6d 20 76 61 6c  plied idxNum val
3f70: 75 65 20 69 73 0a 2a 2a 20 69 6e 64 65 65 64 20  ue is.** indeed 
3f80: 74 68 65 20 68 61 73 68 20 6f 66 20 74 68 65 20  the hash of the 
3f90: 73 75 70 70 6c 69 65 64 20 69 64 78 53 74 72 2e  supplied idxStr.
3fa0: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 68  .*/.static int h
3fb0: 61 73 68 53 74 72 69 6e 67 28 63 6f 6e 73 74 20  ashString(const 
3fc0: 63 68 61 72 20 2a 7a 53 74 72 69 6e 67 29 7b 0a  char *zString){.
3fd0: 20 20 69 6e 74 20 76 61 6c 20 3d 20 30 3b 0a 20    int val = 0;. 
3fe0: 20 69 6e 74 20 69 69 3b 0a 20 20 66 6f 72 28 69   int ii;.  for(i
3ff0: 69 3d 30 3b 20 7a 53 74 72 69 6e 67 5b 69 69 5d  i=0; zString[ii]
4000: 3b 20 69 69 2b 2b 29 7b 0a 20 20 20 20 76 61 6c  ; ii++){.    val
4010: 20 3d 20 28 76 61 6c 20 3c 3c 20 33 29 20 2b 20   = (val << 3) + 
4020: 28 69 6e 74 29 7a 53 74 72 69 6e 67 5b 69 69 5d  (int)zString[ii]
4030: 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 76  ;.  }.  return v
4040: 61 6c 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 45 63  al;.}../* .** Ec
4050: 68 6f 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65  ho virtual table
4060: 20 6d 6f 64 75 6c 65 20 78 46 69 6c 74 65 72 20   module xFilter 
4070: 6d 65 74 68 6f 64 2e 0a 2a 2f 0a 73 74 61 74 69  method..*/.stati
4080: 63 20 69 6e 74 20 65 63 68 6f 46 69 6c 74 65 72  c int echoFilter
4090: 28 0a 20 20 73 71 6c 69 74 65 33 5f 76 74 61 62  (.  sqlite3_vtab
40a0: 5f 63 75 72 73 6f 72 20 2a 70 56 74 61 62 43 75  _cursor *pVtabCu
40b0: 72 73 6f 72 2c 20 0a 20 20 69 6e 74 20 69 64 78  rsor, .  int idx
40c0: 4e 75 6d 2c 20 63 6f 6e 73 74 20 63 68 61 72 20  Num, const char 
40d0: 2a 69 64 78 53 74 72 2c 0a 20 20 69 6e 74 20 61  *idxStr,.  int a
40e0: 72 67 63 2c 20 73 71 6c 69 74 65 33 5f 76 61 6c  rgc, sqlite3_val
40f0: 75 65 20 2a 2a 61 72 67 76 0a 29 7b 0a 20 20 69  ue **argv.){.  i
4100: 6e 74 20 72 63 3b 0a 20 20 69 6e 74 20 69 3b 0a  nt rc;.  int i;.
4110: 0a 20 20 65 63 68 6f 5f 63 75 72 73 6f 72 20 2a  .  echo_cursor *
4120: 70 43 75 72 20 3d 20 28 65 63 68 6f 5f 63 75 72  pCur = (echo_cur
4130: 73 6f 72 20 2a 29 70 56 74 61 62 43 75 72 73 6f  sor *)pVtabCurso
4140: 72 3b 0a 20 20 65 63 68 6f 5f 76 74 61 62 20 2a  r;.  echo_vtab *
4150: 70 56 74 61 62 20 3d 20 28 65 63 68 6f 5f 76 74  pVtab = (echo_vt
4160: 61 62 20 2a 29 70 56 74 61 62 43 75 72 73 6f 72  ab *)pVtabCursor
4170: 2d 3e 70 56 74 61 62 3b 0a 20 20 73 71 6c 69 74  ->pVtab;.  sqlit
4180: 65 33 20 2a 64 62 20 3d 20 70 56 74 61 62 2d 3e  e3 *db = pVtab->
4190: 64 62 3b 0a 0a 20 20 2f 2a 20 43 68 65 63 6b 20  db;..  /* Check 
41a0: 74 68 61 74 20 69 64 78 4e 75 6d 20 6d 61 74 63  that idxNum matc
41b0: 68 65 73 20 69 64 78 53 74 72 20 2a 2f 0a 20 20  hes idxStr */.  
41c0: 61 73 73 65 72 74 28 20 69 64 78 4e 75 6d 3d 3d  assert( idxNum==
41d0: 68 61 73 68 53 74 72 69 6e 67 28 69 64 78 53 74  hashString(idxSt
41e0: 72 29 20 29 3b 0a 0a 20 20 2f 2a 20 4c 6f 67 20  r) );..  /* Log 
41f0: 61 72 67 75 6d 65 6e 74 73 20 74 6f 20 74 68 65  arguments to the
4200: 20 3a 3a 65 63 68 6f 5f 6d 6f 64 75 6c 65 20 54   ::echo_module T
4210: 63 6c 20 76 61 72 69 61 62 6c 65 20 2a 2f 0a 20  cl variable */. 
4220: 20 61 70 70 65 6e 64 54 6f 45 63 68 6f 4d 6f 64   appendToEchoMod
4230: 75 6c 65 28 70 56 74 61 62 2d 3e 69 6e 74 65 72  ule(pVtab->inter
4240: 70 2c 20 22 78 46 69 6c 74 65 72 22 29 3b 0a 20  p, "xFilter");. 
4250: 20 61 70 70 65 6e 64 54 6f 45 63 68 6f 4d 6f 64   appendToEchoMod
4260: 75 6c 65 28 70 56 74 61 62 2d 3e 69 6e 74 65 72  ule(pVtab->inter
4270: 70 2c 20 69 64 78 53 74 72 29 3b 0a 20 20 66 6f  p, idxStr);.  fo
4280: 72 28 69 3d 30 3b 20 69 3c 61 72 67 63 3b 20 69  r(i=0; i<argc; i
4290: 2b 2b 29 7b 0a 20 20 20 20 61 70 70 65 6e 64 54  ++){.    appendT
42a0: 6f 45 63 68 6f 4d 6f 64 75 6c 65 28 70 56 74 61  oEchoModule(pVta
42b0: 62 2d 3e 69 6e 74 65 72 70 2c 20 28 63 6f 6e 73  b->interp, (cons
42c0: 74 20 63 68 61 72 2a 29 73 71 6c 69 74 65 33 5f  t char*)sqlite3_
42d0: 76 61 6c 75 65 5f 74 65 78 74 28 61 72 67 76 5b  value_text(argv[
42e0: 69 5d 29 29 3b 0a 20 20 7d 0a 0a 20 20 73 71 6c  i]));.  }..  sql
42f0: 69 74 65 33 5f 66 69 6e 61 6c 69 7a 65 28 70 43  ite3_finalize(pC
4300: 75 72 2d 3e 70 53 74 6d 74 29 3b 0a 20 20 70 43  ur->pStmt);.  pC
4310: 75 72 2d 3e 70 53 74 6d 74 20 3d 20 30 3b 0a 0a  ur->pStmt = 0;..
4320: 20 20 2f 2a 20 50 72 65 70 61 72 65 20 74 68 65    /* Prepare the
4330: 20 53 51 4c 20 73 74 61 74 65 6d 65 6e 74 20 63   SQL statement c
4340: 72 65 61 74 65 64 20 62 79 20 65 63 68 6f 42 65  reated by echoBe
4350: 73 74 49 6e 64 65 78 20 61 6e 64 20 62 69 6e 64  stIndex and bind
4360: 20 74 68 65 0a 20 20 2a 2a 20 72 75 6e 74 69 6d   the.  ** runtim
4370: 65 20 70 61 72 61 6d 65 74 65 72 73 20 70 61 73  e parameters pas
4380: 73 65 64 20 74 6f 20 74 68 69 73 20 66 75 6e 63  sed to this func
4390: 74 69 6f 6e 20 74 6f 20 69 74 2e 0a 20 20 2a 2f  tion to it..  */
43a0: 0a 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f  .  rc = sqlite3_
43b0: 70 72 65 70 61 72 65 28 64 62 2c 20 69 64 78 53  prepare(db, idxS
43c0: 74 72 2c 20 2d 31 2c 20 26 70 43 75 72 2d 3e 70  tr, -1, &pCur->p
43d0: 53 74 6d 74 2c 20 30 29 3b 0a 20 20 61 73 73 65  Stmt, 0);.  asse
43e0: 72 74 28 20 70 43 75 72 2d 3e 70 53 74 6d 74 20  rt( pCur->pStmt 
43f0: 7c 7c 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b  || rc!=SQLITE_OK
4400: 20 29 3b 0a 20 20 66 6f 72 28 69 3d 30 3b 20 72   );.  for(i=0; r
4410: 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20  c==SQLITE_OK && 
4420: 69 3c 61 72 67 63 3b 20 69 2b 2b 29 7b 0a 20 20  i<argc; i++){.  
4430: 20 20 73 71 6c 69 74 65 33 5f 62 69 6e 64 5f 76    sqlite3_bind_v
4440: 61 6c 75 65 28 70 43 75 72 2d 3e 70 53 74 6d 74  alue(pCur->pStmt
4450: 2c 20 69 2b 31 2c 20 61 72 67 76 5b 69 5d 29 3b  , i+1, argv[i]);
4460: 0a 20 20 7d 0a 0a 20 20 2f 2a 20 49 66 20 65 76  .  }..  /* If ev
4470: 65 72 79 74 68 69 6e 67 20 77 61 73 20 73 75 63  erything was suc
4480: 63 65 73 73 66 75 6c 2c 20 61 64 76 61 6e 63 65  cessful, advance
4490: 20 74 6f 20 74 68 65 20 66 69 72 73 74 20 72 6f   to the first ro
44a0: 77 20 6f 66 20 74 68 65 20 73 63 61 6e 20 2a 2f  w of the scan */
44b0: 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54  .  if( rc==SQLIT
44c0: 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 72 63 20 3d  E_OK ){.    rc =
44d0: 20 65 63 68 6f 4e 65 78 74 28 70 56 74 61 62 43   echoNext(pVtabC
44e0: 75 72 73 6f 72 29 3b 0a 20 20 7d 0a 0a 20 20 72  ursor);.  }..  r
44f0: 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 0a 2f 2a  eturn rc;.}.../*
4500: 0a 2a 2a 20 41 20 68 65 6c 70 65 72 20 66 75 6e  .** A helper fun
4510: 63 74 69 6f 6e 20 75 73 65 64 20 62 79 20 65 63  ction used by ec
4520: 68 6f 55 70 64 61 74 65 28 29 20 61 6e 64 20 65  hoUpdate() and e
4530: 63 68 6f 42 65 73 74 49 6e 64 65 78 28 29 20 66  choBestIndex() f
4540: 6f 72 0a 2a 2a 20 6d 61 6e 69 70 75 6c 61 74 69  or.** manipulati
4550: 6e 67 20 73 74 72 69 6e 67 73 20 69 6e 20 63 6f  ng strings in co
4560: 6e 63 65 72 74 20 77 69 74 68 20 74 68 65 20 73  ncert with the s
4570: 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 29  qlite3_mprintf()
4580: 20 66 75 6e 63 74 69 6f 6e 2e 0a 2a 2a 0a 2a 2a   function..**.**
4590: 20 50 61 72 61 6d 65 74 65 72 20 70 7a 53 74 72   Parameter pzStr
45a0: 20 70 6f 69 6e 74 73 20 74 6f 20 61 20 70 6f 69   points to a poi
45b0: 6e 74 65 72 20 74 6f 20 61 20 73 74 72 69 6e 67  nter to a string
45c0: 20 61 6c 6c 6f 63 61 74 65 64 20 77 69 74 68 0a   allocated with.
45d0: 2a 2a 20 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e  ** sqlite3_mprin
45e0: 74 66 2e 20 54 68 65 20 73 65 63 6f 6e 64 20 70  tf. The second p
45f0: 61 72 61 6d 65 74 65 72 2c 20 7a 41 70 70 65 6e  arameter, zAppen
4600: 64 2c 20 70 6f 69 6e 74 73 20 74 6f 20 61 6e 6f  d, points to ano
4610: 74 68 65 72 0a 2a 2a 20 73 74 72 69 6e 67 2e 20  ther.** string. 
4620: 54 68 65 20 74 77 6f 20 73 74 72 69 6e 67 73 20  The two strings 
4630: 61 72 65 20 63 6f 6e 63 61 74 65 6e 61 74 65 64  are concatenated
4640: 20 74 6f 67 65 74 68 65 72 20 61 6e 64 20 2a 70   together and *p
4650: 7a 53 74 72 0a 2a 2a 20 73 65 74 20 74 6f 20 70  zStr.** set to p
4660: 6f 69 6e 74 20 61 74 20 74 68 65 20 72 65 73 75  oint at the resu
4670: 6c 74 2e 20 54 68 65 20 69 6e 69 74 69 61 6c 20  lt. The initial 
4680: 62 75 66 66 65 72 20 70 6f 69 6e 74 65 64 20 74  buffer pointed t
4690: 6f 20 62 79 20 2a 70 7a 53 74 72 0a 2a 2a 20 69  o by *pzStr.** i
46a0: 73 20 64 65 61 6c 6c 6f 63 61 74 65 64 20 76 69  s deallocated vi
46b0: 61 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 29  a sqlite3_free()
46c0: 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 74 68 65 20 74  ..**.** If the t
46d0: 68 69 72 64 20 61 72 67 75 6d 65 6e 74 2c 20 64  hird argument, d
46e0: 6f 46 72 65 65 2c 20 69 73 20 74 72 75 65 2c 20  oFree, is true, 
46f0: 74 68 65 6e 20 73 71 6c 69 74 65 33 5f 66 72 65  then sqlite3_fre
4700: 65 28 29 20 69 73 0a 2a 2a 20 61 6c 73 6f 20 63  e() is.** also c
4710: 61 6c 6c 65 64 20 74 6f 20 66 72 65 65 20 74 68  alled to free th
4720: 65 20 62 75 66 66 65 72 20 70 6f 69 6e 74 65 64  e buffer pointed
4730: 20 74 6f 20 62 79 20 7a 41 70 70 65 6e 64 2e 0a   to by zAppend..
4740: 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 73  */.static void s
4750: 74 72 69 6e 67 5f 63 6f 6e 63 61 74 28 63 68 61  tring_concat(cha
4760: 72 20 2a 2a 70 7a 53 74 72 2c 20 63 68 61 72 20  r **pzStr, char 
4770: 2a 7a 41 70 70 65 6e 64 2c 20 69 6e 74 20 64 6f  *zAppend, int do
4780: 46 72 65 65 2c 20 69 6e 74 20 2a 70 52 63 29 7b  Free, int *pRc){
4790: 0a 20 20 63 68 61 72 20 2a 7a 49 6e 20 3d 20 2a  .  char *zIn = *
47a0: 70 7a 53 74 72 3b 0a 20 20 69 66 28 20 21 7a 41  pzStr;.  if( !zA
47b0: 70 70 65 6e 64 20 26 26 20 64 6f 46 72 65 65 20  ppend && doFree 
47c0: 26 26 20 2a 70 52 63 3d 3d 53 51 4c 49 54 45 5f  && *pRc==SQLITE_
47d0: 4f 4b 20 29 7b 0a 20 20 20 20 2a 70 52 63 20 3d  OK ){.    *pRc =
47e0: 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20   SQLITE_NOMEM;. 
47f0: 20 7d 0a 20 20 69 66 28 20 2a 70 52 63 21 3d 53   }.  if( *pRc!=S
4800: 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
4810: 73 71 6c 69 74 65 33 5f 66 72 65 65 28 7a 49 6e  sqlite3_free(zIn
4820: 29 3b 0a 20 20 20 20 7a 49 6e 20 3d 20 30 3b 0a  );.    zIn = 0;.
4830: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 69 66 28    }else{.    if(
4840: 20 7a 49 6e 20 29 7b 0a 20 20 20 20 20 20 63 68   zIn ){.      ch
4850: 61 72 20 2a 7a 54 65 6d 70 20 3d 20 7a 49 6e 3b  ar *zTemp = zIn;
4860: 0a 20 20 20 20 20 20 7a 49 6e 20 3d 20 73 71 6c  .      zIn = sql
4870: 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 22 25 73  ite3_mprintf("%s
4880: 25 73 22 2c 20 7a 49 6e 2c 20 7a 41 70 70 65 6e  %s", zIn, zAppen
4890: 64 29 3b 0a 20 20 20 20 20 20 73 71 6c 69 74 65  d);.      sqlite
48a0: 33 5f 66 72 65 65 28 7a 54 65 6d 70 29 3b 0a 20  3_free(zTemp);. 
48b0: 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20     }else{.      
48c0: 7a 49 6e 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70  zIn = sqlite3_mp
48d0: 72 69 6e 74 66 28 22 25 73 22 2c 20 7a 41 70 70  rintf("%s", zApp
48e0: 65 6e 64 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20  end);.    }.    
48f0: 69 66 28 20 21 7a 49 6e 20 29 7b 0a 20 20 20 20  if( !zIn ){.    
4900: 20 20 2a 70 52 63 20 3d 20 53 51 4c 49 54 45 5f    *pRc = SQLITE_
4910: 4e 4f 4d 45 4d 3b 0a 20 20 20 20 7d 0a 20 20 7d  NOMEM;.    }.  }
4920: 0a 20 20 2a 70 7a 53 74 72 20 3d 20 7a 49 6e 3b  .  *pzStr = zIn;
4930: 0a 20 20 69 66 28 20 64 6f 46 72 65 65 20 29 7b  .  if( doFree ){
4940: 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65  .    sqlite3_fre
4950: 65 28 7a 41 70 70 65 6e 64 29 3b 0a 20 20 7d 0a  e(zAppend);.  }.
4960: 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 65 20 65 63 68  }../*.** The ech
4970: 6f 20 6d 6f 64 75 6c 65 20 69 6d 70 6c 65 6d 65  o module impleme
4980: 6e 74 73 20 74 68 65 20 73 75 62 73 65 74 20 6f  nts the subset o
4990: 66 20 71 75 65 72 79 20 63 6f 6e 73 74 72 61 69  f query constrai
49a0: 6e 74 73 20 61 6e 64 20 73 6f 72 74 0a 2a 2a 20  nts and sort.** 
49b0: 6f 72 64 65 72 73 20 74 68 61 74 20 6d 61 79 20  orders that may 
49c0: 74 61 6b 65 20 61 64 76 61 6e 74 61 67 65 20 6f  take advantage o
49d0: 66 20 53 51 4c 69 74 65 20 69 6e 64 69 63 65 73  f SQLite indices
49e0: 20 6f 6e 20 74 68 65 20 75 6e 64 65 72 6c 79 69   on the underlyi
49f0: 6e 67 0a 2a 2a 20 72 65 61 6c 20 74 61 62 6c 65  ng.** real table
4a00: 2e 20 46 6f 72 20 65 78 61 6d 70 6c 65 2c 20 69  . For example, i
4a10: 66 20 74 68 65 20 72 65 61 6c 20 74 61 62 6c 65  f the real table
4a20: 20 69 73 20 64 65 63 6c 61 72 65 64 20 61 73 3a   is declared as:
4a30: 0a 2a 2a 0a 2a 2a 20 20 20 20 20 43 52 45 41 54  .**.**     CREAT
4a40: 45 20 54 41 42 4c 45 20 72 65 61 6c 28 61 2c 20  E TABLE real(a, 
4a50: 62 2c 20 63 29 3b 0a 2a 2a 20 20 20 20 20 43 52  b, c);.**     CR
4a60: 45 41 54 45 20 49 4e 44 45 58 20 72 65 61 6c 5f  EATE INDEX real_
4a70: 69 6e 64 65 78 20 4f 4e 20 72 65 61 6c 28 62 29  index ON real(b)
4a80: 3b 0a 2a 2a 0a 2a 2a 20 74 68 65 6e 20 74 68 65  ;.**.** then the
4a90: 20 65 63 68 6f 20 6d 6f 64 75 6c 65 20 68 61 6e   echo module han
4aa0: 64 6c 65 73 20 57 48 45 52 45 20 6f 72 20 4f 52  dles WHERE or OR
4ab0: 44 45 52 20 42 59 20 63 6c 61 75 73 65 73 20 74  DER BY clauses t
4ac0: 68 61 74 20 72 65 66 65 72 0a 2a 2a 20 74 6f 20  hat refer.** to 
4ad0: 74 68 65 20 63 6f 6c 75 6d 6e 20 22 62 22 2c 20  the column "b", 
4ae0: 62 75 74 20 6e 6f 74 20 22 61 22 20 6f 72 20 22  but not "a" or "
4af0: 63 22 2e 20 49 66 20 61 20 6d 75 6c 74 69 2d 63  c". If a multi-c
4b00: 6f 6c 75 6d 6e 20 69 6e 64 65 78 20 69 73 0a 2a  olumn index is.*
4b10: 2a 20 70 72 65 73 65 6e 74 2c 20 6f 6e 6c 79 20  * present, only 
4b20: 69 74 27 73 20 6c 65 66 74 20 6d 6f 73 74 20 63  it's left most c
4b30: 6f 6c 75 6d 6e 20 69 73 20 63 6f 6e 73 69 64 65  olumn is conside
4b40: 72 65 64 2e 20 0a 2a 2a 0a 2a 2a 20 54 68 69 73  red. .**.** This
4b50: 20 78 42 65 73 74 49 6e 64 65 78 20 6d 65 74 68   xBestIndex meth
4b60: 6f 64 20 65 6e 63 6f 64 65 73 20 74 68 65 20 70  od encodes the p
4b70: 72 6f 70 6f 73 65 64 20 73 65 61 72 63 68 20 73  roposed search s
4b80: 74 72 61 74 65 67 79 20 61 73 0a 2a 2a 20 61 6e  trategy as.** an
4b90: 20 53 51 4c 20 71 75 65 72 79 20 6f 6e 20 74 68   SQL query on th
4ba0: 65 20 72 65 61 6c 20 74 61 62 6c 65 20 75 6e 64  e real table und
4bb0: 65 72 6c 79 69 6e 67 20 74 68 65 20 76 69 72 74  erlying the virt
4bc0: 75 61 6c 20 65 63 68 6f 20 6d 6f 64 75 6c 65 20  ual echo module 
4bd0: 0a 2a 2a 20 74 61 62 6c 65 20 61 6e 64 20 73 74  .** table and st
4be0: 6f 72 65 73 20 74 68 65 20 71 75 65 72 79 20 69  ores the query i
4bf0: 6e 20 73 71 6c 69 74 65 33 5f 69 6e 64 65 78 5f  n sqlite3_index_
4c00: 69 6e 66 6f 2e 69 64 78 53 74 72 2e 20 54 68 65  info.idxStr. The
4c10: 20 53 51 4c 0a 2a 2a 20 73 74 61 74 65 6d 65 6e   SQL.** statemen
4c20: 74 20 69 73 20 6f 66 20 74 68 65 20 66 6f 72 6d  t is of the form
4c30: 3a 0a 2a 2a 0a 2a 2a 20 20 20 53 45 4c 45 43 54  :.**.**   SELECT
4c40: 20 72 6f 77 69 64 2c 20 2a 20 46 52 4f 4d 20 3c   rowid, * FROM <
4c50: 72 65 61 6c 2d 74 61 62 6c 65 3e 20 3f 3c 77 68  real-table> ?<wh
4c60: 65 72 65 2d 63 6c 61 75 73 65 3e 3f 20 3f 3c 6f  ere-clause>? ?<o
4c70: 72 64 65 72 2d 62 79 2d 63 6c 61 75 73 65 3e 3f  rder-by-clause>?
4c80: 0a 2a 2a 0a 2a 2a 20 77 68 65 72 65 20 74 68 65  .**.** where the
4c90: 20 3c 77 68 65 72 65 2d 63 6c 61 75 73 65 3e 20   <where-clause> 
4ca0: 61 6e 64 20 3c 6f 72 64 65 72 2d 62 79 2d 63 6c  and <order-by-cl
4cb0: 61 75 73 65 3e 20 61 72 65 20 64 65 74 65 72 6d  ause> are determ
4cc0: 69 6e 65 64 0a 2a 2a 20 62 79 20 74 68 65 20 63  ined.** by the c
4cd0: 6f 6e 74 65 6e 74 73 20 6f 66 20 74 68 65 20 73  ontents of the s
4ce0: 74 72 75 63 74 75 72 65 20 70 6f 69 6e 74 65 64  tructure pointed
4cf0: 20 74 6f 20 62 79 20 74 68 65 20 70 49 64 78 49   to by the pIdxI
4d00: 6e 66 6f 20 61 72 67 75 6d 65 6e 74 2e 0a 2a 2f  nfo argument..*/
4d10: 0a 73 74 61 74 69 63 20 69 6e 74 20 65 63 68 6f  .static int echo
4d20: 42 65 73 74 49 6e 64 65 78 28 73 71 6c 69 74 65  BestIndex(sqlite
4d30: 33 5f 76 74 61 62 20 2a 74 61 62 2c 20 73 71 6c  3_vtab *tab, sql
4d40: 69 74 65 33 5f 69 6e 64 65 78 5f 69 6e 66 6f 20  ite3_index_info 
4d50: 2a 70 49 64 78 49 6e 66 6f 29 7b 0a 20 20 69 6e  *pIdxInfo){.  in
4d60: 74 20 69 69 3b 0a 20 20 63 68 61 72 20 2a 7a 51  t ii;.  char *zQ
4d70: 75 65 72 79 20 3d 20 30 3b 0a 20 20 63 68 61 72  uery = 0;.  char
4d80: 20 2a 7a 4e 65 77 3b 0a 20 20 69 6e 74 20 6e 41   *zNew;.  int nA
4d90: 72 67 20 3d 20 30 3b 0a 20 20 63 6f 6e 73 74 20  rg = 0;.  const 
4da0: 63 68 61 72 20 2a 7a 53 65 70 20 3d 20 22 57 48  char *zSep = "WH
4db0: 45 52 45 22 3b 0a 20 20 65 63 68 6f 5f 76 74 61  ERE";.  echo_vta
4dc0: 62 20 2a 70 56 74 61 62 20 3d 20 28 65 63 68 6f  b *pVtab = (echo
4dd0: 5f 76 74 61 62 20 2a 29 74 61 62 3b 0a 20 20 73  _vtab *)tab;.  s
4de0: 71 6c 69 74 65 33 5f 73 74 6d 74 20 2a 70 53 74  qlite3_stmt *pSt
4df0: 6d 74 20 3d 20 30 3b 0a 20 20 54 63 6c 5f 49 6e  mt = 0;.  Tcl_In
4e00: 74 65 72 70 20 2a 69 6e 74 65 72 70 20 3d 20 70  terp *interp = p
4e10: 56 74 61 62 2d 3e 69 6e 74 65 72 70 3b 0a 0a 20  Vtab->interp;.. 
4e20: 20 69 6e 74 20 6e 52 6f 77 3b 0a 20 20 69 6e 74   int nRow;.  int
4e30: 20 75 73 65 49 64 78 20 3d 20 30 3b 0a 20 20 69   useIdx = 0;.  i
4e40: 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f  nt rc = SQLITE_O
4e50: 4b 3b 0a 20 20 69 6e 74 20 75 73 65 43 6f 73 74  K;.  int useCost
4e60: 20 3d 20 30 3b 0a 20 20 64 6f 75 62 6c 65 20 63   = 0;.  double c
4e70: 6f 73 74 3b 0a 0a 20 20 2f 2a 20 44 65 74 65 72  ost;..  /* Deter
4e80: 6d 69 6e 65 20 74 68 65 20 6e 75 6d 62 65 72 20  mine the number 
4e90: 6f 66 20 72 6f 77 73 20 69 6e 20 74 68 65 20 74  of rows in the t
4ea0: 61 62 6c 65 20 61 6e 64 20 73 74 6f 72 65 20 74  able and store t
4eb0: 68 69 73 20 76 61 6c 75 65 20 69 6e 20 6c 6f 63  his value in loc
4ec0: 61 6c 0a 20 20 2a 2a 20 76 61 72 69 61 62 6c 65  al.  ** variable
4ed0: 20 6e 52 6f 77 2e 20 54 68 65 20 27 65 73 74 69   nRow. The 'esti
4ee0: 6d 61 74 65 64 2d 63 6f 73 74 27 20 6f 66 20 74  mated-cost' of t
4ef0: 68 65 20 73 63 61 6e 20 77 69 6c 6c 20 62 65 20  he scan will be 
4f00: 74 68 65 20 6e 75 6d 62 65 72 20 6f 66 0a 20 20  the number of.  
4f10: 2a 2a 20 72 6f 77 73 20 69 6e 20 74 68 65 20 74  ** rows in the t
4f20: 61 62 6c 65 20 66 6f 72 20 61 20 6c 69 6e 65 61  able for a linea
4f30: 72 20 73 63 61 6e 2c 20 6f 72 20 74 68 65 20 6c  r scan, or the l
4f40: 6f 67 20 28 62 61 73 65 20 32 29 20 6f 66 20 74  og (base 2) of t
4f50: 68 65 20 0a 20 20 2a 2a 20 6e 75 6d 62 65 72 20  he .  ** number 
4f60: 6f 66 20 72 6f 77 73 20 69 66 20 74 68 65 20 70  of rows if the p
4f70: 72 6f 70 6f 73 65 64 20 73 63 61 6e 20 75 73 65  roposed scan use
4f80: 73 20 61 6e 20 69 6e 64 65 78 2e 20 20 0a 20 20  s an index.  .  
4f90: 2a 2f 0a 20 20 69 66 28 20 54 63 6c 5f 47 65 74  */.  if( Tcl_Get
4fa0: 56 61 72 28 69 6e 74 65 72 70 2c 20 22 65 63 68  Var(interp, "ech
4fb0: 6f 5f 6d 6f 64 75 6c 65 5f 63 6f 73 74 22 2c 20  o_module_cost", 
4fc0: 54 43 4c 5f 47 4c 4f 42 41 4c 5f 4f 4e 4c 59 29  TCL_GLOBAL_ONLY)
4fd0: 20 29 7b 0a 20 20 20 20 63 6f 73 74 20 3d 20 61   ){.    cost = a
4fe0: 74 6f 66 28 54 63 6c 5f 47 65 74 56 61 72 28 69  tof(Tcl_GetVar(i
4ff0: 6e 74 65 72 70 2c 20 22 65 63 68 6f 5f 6d 6f 64  nterp, "echo_mod
5000: 75 6c 65 5f 63 6f 73 74 22 2c 20 54 43 4c 5f 47  ule_cost", TCL_G
5010: 4c 4f 42 41 4c 5f 4f 4e 4c 59 29 29 3b 0a 20 20  LOBAL_ONLY));.  
5020: 20 20 75 73 65 43 6f 73 74 20 3d 20 31 3b 0a 20    useCost = 1;. 
5030: 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20 7a 51   } else {.    zQ
5040: 75 65 72 79 20 3d 20 73 71 6c 69 74 65 33 5f 6d  uery = sqlite3_m
5050: 70 72 69 6e 74 66 28 22 53 45 4c 45 43 54 20 63  printf("SELECT c
5060: 6f 75 6e 74 28 2a 29 20 46 52 4f 4d 20 25 51 22  ount(*) FROM %Q"
5070: 2c 20 70 56 74 61 62 2d 3e 7a 54 61 62 6c 65 4e  , pVtab->zTableN
5080: 61 6d 65 29 3b 0a 20 20 20 20 69 66 28 20 21 7a  ame);.    if( !z
5090: 51 75 65 72 79 20 29 7b 0a 20 20 20 20 20 20 72  Query ){.      r
50a0: 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d  eturn SQLITE_NOM
50b0: 45 4d 3b 0a 20 20 20 20 7d 0a 20 20 20 20 72 63  EM;.    }.    rc
50c0: 20 3d 20 73 71 6c 69 74 65 33 5f 70 72 65 70 61   = sqlite3_prepa
50d0: 72 65 28 70 56 74 61 62 2d 3e 64 62 2c 20 7a 51  re(pVtab->db, zQ
50e0: 75 65 72 79 2c 20 2d 31 2c 20 26 70 53 74 6d 74  uery, -1, &pStmt
50f0: 2c 20 30 29 3b 0a 20 20 20 20 73 71 6c 69 74 65  , 0);.    sqlite
5100: 33 5f 66 72 65 65 28 7a 51 75 65 72 79 29 3b 0a  3_free(zQuery);.
5110: 20 20 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49      if( rc!=SQLI
5120: 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 72  TE_OK ){.      r
5130: 65 74 75 72 6e 20 72 63 3b 0a 20 20 20 20 7d 0a  eturn rc;.    }.
5140: 20 20 20 20 73 71 6c 69 74 65 33 5f 73 74 65 70      sqlite3_step
5150: 28 70 53 74 6d 74 29 3b 0a 20 20 20 20 6e 52 6f  (pStmt);.    nRo
5160: 77 20 3d 20 73 71 6c 69 74 65 33 5f 63 6f 6c 75  w = sqlite3_colu
5170: 6d 6e 5f 69 6e 74 28 70 53 74 6d 74 2c 20 30 29  mn_int(pStmt, 0)
5180: 3b 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74  ;.    rc = sqlit
5190: 65 33 5f 66 69 6e 61 6c 69 7a 65 28 70 53 74 6d  e3_finalize(pStm
51a0: 74 29 3b 0a 20 20 20 20 69 66 28 20 72 63 21 3d  t);.    if( rc!=
51b0: 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20  SQLITE_OK ){.   
51c0: 20 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 20 20     return rc;.  
51d0: 20 20 7d 0a 20 20 7d 0a 0a 20 20 7a 51 75 65 72    }.  }..  zQuer
51e0: 79 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72 69  y = sqlite3_mpri
51f0: 6e 74 66 28 22 53 45 4c 45 43 54 20 72 6f 77 69  ntf("SELECT rowi
5200: 64 2c 20 2a 20 46 52 4f 4d 20 25 51 22 2c 20 70  d, * FROM %Q", p
5210: 56 74 61 62 2d 3e 7a 54 61 62 6c 65 4e 61 6d 65  Vtab->zTableName
5220: 29 3b 0a 20 20 69 66 28 20 21 7a 51 75 65 72 79  );.  if( !zQuery
5230: 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 53   ){.    return S
5240: 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 7d  QLITE_NOMEM;.  }
5250: 0a 20 20 66 6f 72 28 69 69 3d 30 3b 20 69 69 3c  .  for(ii=0; ii<
5260: 70 49 64 78 49 6e 66 6f 2d 3e 6e 43 6f 6e 73 74  pIdxInfo->nConst
5270: 72 61 69 6e 74 3b 20 69 69 2b 2b 29 7b 0a 20 20  raint; ii++){.  
5280: 20 20 63 6f 6e 73 74 20 73 74 72 75 63 74 20 73    const struct s
5290: 71 6c 69 74 65 33 5f 69 6e 64 65 78 5f 63 6f 6e  qlite3_index_con
52a0: 73 74 72 61 69 6e 74 20 2a 70 43 6f 6e 73 74 72  straint *pConstr
52b0: 61 69 6e 74 3b 0a 20 20 20 20 73 74 72 75 63 74  aint;.    struct
52c0: 20 73 71 6c 69 74 65 33 5f 69 6e 64 65 78 5f 63   sqlite3_index_c
52d0: 6f 6e 73 74 72 61 69 6e 74 5f 75 73 61 67 65 20  onstraint_usage 
52e0: 2a 70 55 73 61 67 65 3b 0a 20 20 20 20 69 6e 74  *pUsage;.    int
52f0: 20 69 43 6f 6c 3b 0a 0a 20 20 20 20 70 43 6f 6e   iCol;..    pCon
5300: 73 74 72 61 69 6e 74 20 3d 20 26 70 49 64 78 49  straint = &pIdxI
5310: 6e 66 6f 2d 3e 61 43 6f 6e 73 74 72 61 69 6e 74  nfo->aConstraint
5320: 5b 69 69 5d 3b 0a 20 20 20 20 70 55 73 61 67 65  [ii];.    pUsage
5330: 20 3d 20 26 70 49 64 78 49 6e 66 6f 2d 3e 61 43   = &pIdxInfo->aC
5340: 6f 6e 73 74 72 61 69 6e 74 55 73 61 67 65 5b 69  onstraintUsage[i
5350: 69 5d 3b 0a 0a 20 20 20 20 69 43 6f 6c 20 3d 20  i];..    iCol = 
5360: 70 43 6f 6e 73 74 72 61 69 6e 74 2d 3e 69 43 6f  pConstraint->iCo
5370: 6c 75 6d 6e 3b 0a 20 20 20 20 69 66 28 20 70 56  lumn;.    if( pV
5380: 74 61 62 2d 3e 61 49 6e 64 65 78 5b 69 43 6f 6c  tab->aIndex[iCol
5390: 5d 20 29 7b 0a 20 20 20 20 20 20 63 68 61 72 20  ] ){.      char 
53a0: 2a 7a 43 6f 6c 20 3d 20 70 56 74 61 62 2d 3e 61  *zCol = pVtab->a
53b0: 43 6f 6c 5b 69 43 6f 6c 5d 3b 0a 20 20 20 20 20  Col[iCol];.     
53c0: 20 63 68 61 72 20 2a 7a 4f 70 20 3d 20 30 3b 0a   char *zOp = 0;.
53d0: 20 20 20 20 20 20 75 73 65 49 64 78 20 3d 20 31        useIdx = 1
53e0: 3b 0a 20 20 20 20 20 20 69 66 28 20 69 43 6f 6c  ;.      if( iCol
53f0: 3c 30 20 29 7b 0a 20 20 20 20 20 20 20 20 7a 43  <0 ){.        zC
5400: 6f 6c 20 3d 20 22 72 6f 77 69 64 22 3b 0a 20 20  ol = "rowid";.  
5410: 20 20 20 20 7d 0a 20 20 20 20 20 20 73 77 69 74      }.      swit
5420: 63 68 28 20 70 43 6f 6e 73 74 72 61 69 6e 74 2d  ch( pConstraint-
5430: 3e 6f 70 20 29 7b 0a 20 20 20 20 20 20 20 20 63  >op ){.        c
5440: 61 73 65 20 53 51 4c 49 54 45 5f 49 4e 44 45 58  ase SQLITE_INDEX
5450: 5f 43 4f 4e 53 54 52 41 49 4e 54 5f 45 51 3a 0a  _CONSTRAINT_EQ:.
5460: 20 20 20 20 20 20 20 20 20 20 7a 4f 70 20 3d 20            zOp = 
5470: 22 3d 22 3b 20 62 72 65 61 6b 3b 0a 20 20 20 20  "="; break;.    
5480: 20 20 20 20 63 61 73 65 20 53 51 4c 49 54 45 5f      case SQLITE_
5490: 49 4e 44 45 58 5f 43 4f 4e 53 54 52 41 49 4e 54  INDEX_CONSTRAINT
54a0: 5f 4c 54 3a 0a 20 20 20 20 20 20 20 20 20 20 7a  _LT:.          z
54b0: 4f 70 20 3d 20 22 3c 22 3b 20 62 72 65 61 6b 3b  Op = "<"; break;
54c0: 0a 20 20 20 20 20 20 20 20 63 61 73 65 20 53 51  .        case SQ
54d0: 4c 49 54 45 5f 49 4e 44 45 58 5f 43 4f 4e 53 54  LITE_INDEX_CONST
54e0: 52 41 49 4e 54 5f 47 54 3a 0a 20 20 20 20 20 20  RAINT_GT:.      
54f0: 20 20 20 20 7a 4f 70 20 3d 20 22 3e 22 3b 20 62      zOp = ">"; b
5500: 72 65 61 6b 3b 0a 20 20 20 20 20 20 20 20 63 61  reak;.        ca
5510: 73 65 20 53 51 4c 49 54 45 5f 49 4e 44 45 58 5f  se SQLITE_INDEX_
5520: 43 4f 4e 53 54 52 41 49 4e 54 5f 4c 45 3a 0a 20  CONSTRAINT_LE:. 
5530: 20 20 20 20 20 20 20 20 20 7a 4f 70 20 3d 20 22           zOp = "
5540: 3c 3d 22 3b 20 62 72 65 61 6b 3b 0a 20 20 20 20  <="; break;.    
5550: 20 20 20 20 63 61 73 65 20 53 51 4c 49 54 45 5f      case SQLITE_
5560: 49 4e 44 45 58 5f 43 4f 4e 53 54 52 41 49 4e 54  INDEX_CONSTRAINT
5570: 5f 47 45 3a 0a 20 20 20 20 20 20 20 20 20 20 7a  _GE:.          z
5580: 4f 70 20 3d 20 22 3e 3d 22 3b 20 62 72 65 61 6b  Op = ">="; break
5590: 3b 0a 20 20 20 20 20 20 20 20 63 61 73 65 20 53  ;.        case S
55a0: 51 4c 49 54 45 5f 49 4e 44 45 58 5f 43 4f 4e 53  QLITE_INDEX_CONS
55b0: 54 52 41 49 4e 54 5f 4d 41 54 43 48 3a 0a 20 20  TRAINT_MATCH:.  
55c0: 20 20 20 20 20 20 20 20 7a 4f 70 20 3d 20 22 4c          zOp = "L
55d0: 49 4b 45 22 3b 20 62 72 65 61 6b 3b 0a 20 20 20  IKE"; break;.   
55e0: 20 20 20 7d 0a 20 20 20 20 20 20 69 66 28 20 7a     }.      if( z
55f0: 4f 70 5b 30 5d 3d 3d 27 4c 27 20 29 7b 0a 20 20  Op[0]=='L' ){.  
5600: 20 20 20 20 20 20 7a 4e 65 77 20 3d 20 73 71 6c        zNew = sql
5610: 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 22 20 25  ite3_mprintf(" %
5620: 73 20 25 73 20 4c 49 4b 45 20 28 53 45 4c 45 43  s %s LIKE (SELEC
5630: 54 20 27 25 25 27 7c 7c 3f 7c 7c 27 25 25 27 29  T '%%'||?||'%%')
5640: 22 2c 20 0a 20 20 20 20 20 20 20 20 20 20 20 20  ", .            
5650: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5660: 20 20 20 7a 53 65 70 2c 20 7a 43 6f 6c 29 3b 0a     zSep, zCol);.
5670: 20 20 20 20 20 20 7d 20 65 6c 73 65 20 7b 0a 20        } else {. 
5680: 20 20 20 20 20 20 20 7a 4e 65 77 20 3d 20 73 71         zNew = sq
5690: 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 22 20  lite3_mprintf(" 
56a0: 25 73 20 25 73 20 25 73 20 3f 22 2c 20 7a 53 65  %s %s %s ?", zSe
56b0: 70 2c 20 7a 43 6f 6c 2c 20 7a 4f 70 29 3b 0a 20  p, zCol, zOp);. 
56c0: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 73 74 72       }.      str
56d0: 69 6e 67 5f 63 6f 6e 63 61 74 28 26 7a 51 75 65  ing_concat(&zQue
56e0: 72 79 2c 20 7a 4e 65 77 2c 20 31 2c 20 26 72 63  ry, zNew, 1, &rc
56f0: 29 3b 0a 0a 20 20 20 20 20 20 7a 53 65 70 20 3d  );..      zSep =
5700: 20 22 41 4e 44 22 3b 0a 20 20 20 20 20 20 70 55   "AND";.      pU
5710: 73 61 67 65 2d 3e 61 72 67 76 49 6e 64 65 78 20  sage->argvIndex 
5720: 3d 20 2b 2b 6e 41 72 67 3b 0a 20 20 20 20 20 20  = ++nArg;.      
5730: 70 55 73 61 67 65 2d 3e 6f 6d 69 74 20 3d 20 31  pUsage->omit = 1
5740: 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 2f  ;.    }.  }..  /
5750: 2a 20 49 66 20 74 68 65 72 65 20 69 73 20 6f 6e  * If there is on
5760: 6c 79 20 6f 6e 65 20 74 65 72 6d 20 69 6e 20 74  ly one term in t
5770: 68 65 20 4f 52 44 45 52 20 42 59 20 63 6c 61 75  he ORDER BY clau
5780: 73 65 2c 20 61 6e 64 20 69 74 20 69 73 0a 20 20  se, and it is.  
5790: 2a 2a 20 6f 6e 20 61 20 63 6f 6c 75 6d 6e 20 74  ** on a column t
57a0: 68 61 74 20 74 68 69 73 20 76 69 72 74 75 61 6c  hat this virtual
57b0: 20 74 61 62 6c 65 20 68 61 73 20 61 6e 20 69 6e   table has an in
57c0: 64 65 78 20 66 6f 72 2c 20 74 68 65 6e 20 63 6f  dex for, then co
57d0: 6e 73 75 6d 65 20 0a 20 20 2a 2a 20 74 68 65 20  nsume .  ** the 
57e0: 4f 52 44 45 52 20 42 59 20 63 6c 61 75 73 65 2e  ORDER BY clause.
57f0: 0a 20 20 2a 2f 0a 20 20 69 66 28 20 70 49 64 78  .  */.  if( pIdx
5800: 49 6e 66 6f 2d 3e 6e 4f 72 64 65 72 42 79 3d 3d  Info->nOrderBy==
5810: 31 20 26 26 20 70 56 74 61 62 2d 3e 61 49 6e 64  1 && pVtab->aInd
5820: 65 78 5b 70 49 64 78 49 6e 66 6f 2d 3e 61 4f 72  ex[pIdxInfo->aOr
5830: 64 65 72 42 79 2d 3e 69 43 6f 6c 75 6d 6e 5d 20  derBy->iColumn] 
5840: 29 7b 0a 20 20 20 20 69 6e 74 20 69 43 6f 6c 20  ){.    int iCol 
5850: 3d 20 70 49 64 78 49 6e 66 6f 2d 3e 61 4f 72 64  = pIdxInfo->aOrd
5860: 65 72 42 79 2d 3e 69 43 6f 6c 75 6d 6e 3b 0a 20  erBy->iColumn;. 
5870: 20 20 20 63 68 61 72 20 2a 7a 43 6f 6c 20 3d 20     char *zCol = 
5880: 70 56 74 61 62 2d 3e 61 43 6f 6c 5b 69 43 6f 6c  pVtab->aCol[iCol
5890: 5d 3b 0a 20 20 20 20 63 68 61 72 20 2a 7a 44 69  ];.    char *zDi
58a0: 72 20 3d 20 70 49 64 78 49 6e 66 6f 2d 3e 61 4f  r = pIdxInfo->aO
58b0: 72 64 65 72 42 79 2d 3e 64 65 73 63 3f 22 44 45  rderBy->desc?"DE
58c0: 53 43 22 3a 22 41 53 43 22 3b 0a 20 20 20 20 69  SC":"ASC";.    i
58d0: 66 28 20 69 43 6f 6c 3c 30 20 29 7b 0a 20 20 20  f( iCol<0 ){.   
58e0: 20 20 20 7a 43 6f 6c 20 3d 20 22 72 6f 77 69 64     zCol = "rowid
58f0: 22 3b 0a 20 20 20 20 7d 0a 20 20 20 20 7a 4e 65  ";.    }.    zNe
5900: 77 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72 69  w = sqlite3_mpri
5910: 6e 74 66 28 22 20 4f 52 44 45 52 20 42 59 20 25  ntf(" ORDER BY %
5920: 73 20 25 73 22 2c 20 7a 43 6f 6c 2c 20 7a 44 69  s %s", zCol, zDi
5930: 72 29 3b 0a 20 20 20 20 73 74 72 69 6e 67 5f 63  r);.    string_c
5940: 6f 6e 63 61 74 28 26 7a 51 75 65 72 79 2c 20 7a  oncat(&zQuery, z
5950: 4e 65 77 2c 20 31 2c 20 26 72 63 29 3b 0a 20 20  New, 1, &rc);.  
5960: 20 20 70 49 64 78 49 6e 66 6f 2d 3e 6f 72 64 65    pIdxInfo->orde
5970: 72 42 79 43 6f 6e 73 75 6d 65 64 20 3d 20 31 3b  rByConsumed = 1;
5980: 0a 20 20 7d 0a 0a 20 20 61 70 70 65 6e 64 54 6f  .  }..  appendTo
5990: 45 63 68 6f 4d 6f 64 75 6c 65 28 70 56 74 61 62  EchoModule(pVtab
59a0: 2d 3e 69 6e 74 65 72 70 2c 20 22 78 42 65 73 74  ->interp, "xBest
59b0: 49 6e 64 65 78 22 29 3b 3b 0a 20 20 61 70 70 65  Index");;.  appe
59c0: 6e 64 54 6f 45 63 68 6f 4d 6f 64 75 6c 65 28 70  ndToEchoModule(p
59d0: 56 74 61 62 2d 3e 69 6e 74 65 72 70 2c 20 7a 51  Vtab->interp, zQ
59e0: 75 65 72 79 29 3b 0a 0a 20 20 69 66 28 20 21 7a  uery);..  if( !z
59f0: 51 75 65 72 79 20 29 7b 0a 20 20 20 20 72 65 74  Query ){.    ret
5a00: 75 72 6e 20 72 63 3b 0a 20 20 7d 0a 20 20 70 49  urn rc;.  }.  pI
5a10: 64 78 49 6e 66 6f 2d 3e 69 64 78 4e 75 6d 20 3d  dxInfo->idxNum =
5a20: 20 68 61 73 68 53 74 72 69 6e 67 28 7a 51 75 65   hashString(zQue
5a30: 72 79 29 3b 0a 20 20 70 49 64 78 49 6e 66 6f 2d  ry);.  pIdxInfo-
5a40: 3e 69 64 78 53 74 72 20 3d 20 7a 51 75 65 72 79  >idxStr = zQuery
5a50: 3b 0a 20 20 70 49 64 78 49 6e 66 6f 2d 3e 6e 65  ;.  pIdxInfo->ne
5a60: 65 64 54 6f 46 72 65 65 49 64 78 53 74 72 20 3d  edToFreeIdxStr =
5a70: 20 31 3b 0a 20 20 69 66 20 28 75 73 65 43 6f 73   1;.  if (useCos
5a80: 74 29 20 7b 0a 20 20 20 20 70 49 64 78 49 6e 66  t) {.    pIdxInf
5a90: 6f 2d 3e 65 73 74 69 6d 61 74 65 64 43 6f 73 74  o->estimatedCost
5aa0: 20 3d 20 63 6f 73 74 3b 0a 20 20 7d 20 65 6c 73   = cost;.  } els
5ab0: 65 20 69 66 28 20 75 73 65 49 64 78 20 29 7b 0a  e if( useIdx ){.
5ac0: 20 20 20 20 2f 2a 20 41 70 70 72 6f 78 69 6d 61      /* Approxima
5ad0: 74 69 6f 6e 20 6f 66 20 6c 6f 67 32 28 6e 52 6f  tion of log2(nRo
5ae0: 77 29 2e 20 2a 2f 0a 20 20 20 20 66 6f 72 28 20  w). */.    for( 
5af0: 69 69 3d 30 3b 20 69 69 3c 28 73 69 7a 65 6f 66  ii=0; ii<(sizeof
5b00: 28 69 6e 74 29 2a 38 29 3b 20 69 69 2b 2b 20 29  (int)*8); ii++ )
5b10: 7b 0a 20 20 20 20 20 20 69 66 28 20 6e 52 6f 77  {.      if( nRow
5b20: 20 26 20 28 31 3c 3c 69 69 29 20 29 7b 0a 20 20   & (1<<ii) ){.  
5b30: 20 20 20 20 20 20 70 49 64 78 49 6e 66 6f 2d 3e        pIdxInfo->
5b40: 65 73 74 69 6d 61 74 65 64 43 6f 73 74 20 3d 20  estimatedCost = 
5b50: 28 64 6f 75 62 6c 65 29 69 69 3b 0a 20 20 20 20  (double)ii;.    
5b60: 20 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 20 65 6c    }.    }.  } el
5b70: 73 65 20 7b 0a 20 20 20 20 70 49 64 78 49 6e 66  se {.    pIdxInf
5b80: 6f 2d 3e 65 73 74 69 6d 61 74 65 64 43 6f 73 74  o->estimatedCost
5b90: 20 3d 20 28 64 6f 75 62 6c 65 29 6e 52 6f 77 3b   = (double)nRow;
5ba0: 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 72 63  .  }.  return rc
5bb0: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 65 20 78  ;.}../*.** The x
5bc0: 55 70 64 61 74 65 20 6d 65 74 68 6f 64 20 66 6f  Update method fo
5bd0: 72 20 65 63 68 6f 20 6d 6f 64 75 6c 65 20 76 69  r echo module vi
5be0: 72 74 75 61 6c 20 74 61 62 6c 65 73 2e 0a 2a 2a  rtual tables..**
5bf0: 20 0a 2a 2a 20 20 20 20 61 70 44 61 74 61 5b 30   .**    apData[0
5c00: 5d 20 20 61 70 44 61 74 61 5b 31 5d 20 20 61 70  ]  apData[1]  ap
5c10: 44 61 74 61 5b 32 2e 2e 5d 0a 2a 2a 0a 2a 2a 20  Data[2..].**.** 
5c20: 20 20 20 49 4e 54 45 47 45 52 20 20 20 20 20 20     INTEGER      
5c30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5c40: 20 20 20 20 20 20 20 20 44 45 4c 45 54 45 20 20          DELETE  
5c50: 20 20 20 20 20 20 20 20 20 20 0a 2a 2a 0a 2a 2a            .**.**
5c60: 20 20 20 20 49 4e 54 45 47 45 52 20 20 20 20 4e      INTEGER    N
5c70: 55 4c 4c 20 20 20 20 20 20 20 28 6e 43 6f 6c 20  ULL       (nCol 
5c80: 61 72 67 73 29 20 20 20 20 55 50 44 41 54 45 20  args)    UPDATE 
5c90: 28 64 6f 20 6e 6f 74 20 73 65 74 20 72 6f 77 69  (do not set rowi
5ca0: 64 29 0a 2a 2a 20 20 20 20 49 4e 54 45 47 45 52  d).**    INTEGER
5cb0: 20 20 20 20 49 4e 54 45 47 45 52 20 20 20 20 28      INTEGER    (
5cc0: 6e 43 6f 6c 20 61 72 67 73 29 20 20 20 20 55 50  nCol args)    UP
5cd0: 44 41 54 45 20 28 77 69 74 68 20 53 45 54 20 72  DATE (with SET r
5ce0: 6f 77 69 64 20 3d 20 3c 61 72 67 31 3e 29 0a 2a  owid = <arg1>).*
5cf0: 2a 0a 2a 2a 20 20 20 20 4e 55 4c 4c 20 20 20 20  *.**    NULL    
5d00: 20 20 20 4e 55 4c 4c 20 20 20 20 20 20 20 28 6e     NULL       (n
5d10: 43 6f 6c 20 61 72 67 73 29 20 20 20 20 49 4e 53  Col args)    INS
5d20: 45 52 54 20 49 4e 54 4f 20 28 61 75 74 6f 6d 61  ERT INTO (automa
5d30: 74 69 63 20 72 6f 77 69 64 20 76 61 6c 75 65 29  tic rowid value)
5d40: 0a 2a 2a 20 20 20 20 4e 55 4c 4c 20 20 20 20 20  .**    NULL     
5d50: 20 20 49 4e 54 45 47 45 52 20 20 20 20 28 6e 43    INTEGER    (nC
5d60: 6f 6c 20 61 72 67 73 29 20 20 20 20 49 4e 53 45  ol args)    INSE
5d70: 52 54 20 28 69 6e 63 6c 2e 20 72 6f 77 69 64 20  RT (incl. rowid 
5d80: 76 61 6c 75 65 29 0a 2a 2a 0a 2a 2f 0a 69 6e 74  value).**.*/.int
5d90: 20 65 63 68 6f 55 70 64 61 74 65 28 0a 20 20 73   echoUpdate(.  s
5da0: 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 74 61 62  qlite3_vtab *tab
5db0: 2c 20 0a 20 20 69 6e 74 20 6e 44 61 74 61 2c 20  , .  int nData, 
5dc0: 0a 20 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65  .  sqlite3_value
5dd0: 20 2a 2a 61 70 44 61 74 61 2c 20 0a 20 20 73 71   **apData, .  sq
5de0: 6c 69 74 65 5f 69 6e 74 36 34 20 2a 70 52 6f 77  lite_int64 *pRow
5df0: 69 64 0a 29 7b 0a 20 20 65 63 68 6f 5f 76 74 61  id.){.  echo_vta
5e00: 62 20 2a 70 56 74 61 62 20 3d 20 28 65 63 68 6f  b *pVtab = (echo
5e10: 5f 76 74 61 62 20 2a 29 74 61 62 3b 0a 20 20 73  _vtab *)tab;.  s
5e20: 71 6c 69 74 65 33 20 2a 64 62 20 3d 20 70 56 74  qlite3 *db = pVt
5e30: 61 62 2d 3e 64 62 3b 0a 20 20 69 6e 74 20 72 63  ab->db;.  int rc
5e40: 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 0a 20   = SQLITE_OK;.. 
5e50: 20 73 71 6c 69 74 65 33 5f 73 74 6d 74 20 2a 70   sqlite3_stmt *p
5e60: 53 74 6d 74 3b 0a 20 20 63 68 61 72 20 2a 7a 20  Stmt;.  char *z 
5e70: 3d 20 30 3b 20 20 20 20 20 20 20 20 20 20 20 20  = 0;            
5e80: 20 20 20 2f 2a 20 53 51 4c 20 73 74 61 74 65 6d     /* SQL statem
5e90: 65 6e 74 20 74 6f 20 65 78 65 63 75 74 65 20 2a  ent to execute *
5ea0: 2f 0a 20 20 69 6e 74 20 62 69 6e 64 41 72 67 5a  /.  int bindArgZ
5eb0: 65 72 6f 20 3d 20 30 3b 20 20 20 20 20 20 20 2f  ero = 0;       /
5ec0: 2a 20 54 72 75 65 20 74 6f 20 62 69 6e 64 20 61  * True to bind a
5ed0: 70 44 61 74 61 5b 30 5d 20 74 6f 20 73 71 6c 20  pData[0] to sql 
5ee0: 76 61 72 20 6e 6f 2e 20 6e 44 61 74 61 20 2a 2f  var no. nData */
5ef0: 0a 20 20 69 6e 74 20 62 69 6e 64 41 72 67 4f 6e  .  int bindArgOn
5f00: 65 20 3d 20 30 3b 20 20 20 20 20 20 20 20 2f 2a  e = 0;        /*
5f10: 20 54 72 75 65 20 74 6f 20 62 69 6e 64 20 61 70   True to bind ap
5f20: 44 61 74 61 5b 31 5d 20 74 6f 20 73 71 6c 20 76  Data[1] to sql v
5f30: 61 72 20 6e 6f 2e 20 31 20 2a 2f 0a 20 20 69 6e  ar no. 1 */.  in
5f40: 74 20 69 3b 20 20 20 20 20 20 20 20 20 20 20 20  t i;            
5f50: 20 20 20 20 20 20 20 20 20 2f 2a 20 43 6f 75 6e           /* Coun
5f60: 74 65 72 20 76 61 72 69 61 62 6c 65 20 75 73 65  ter variable use
5f70: 64 20 62 79 20 66 6f 72 20 6c 6f 6f 70 73 20 2a  d by for loops *
5f80: 2f 0a 0a 20 20 61 73 73 65 72 74 28 20 6e 44 61  /..  assert( nDa
5f90: 74 61 3d 3d 70 56 74 61 62 2d 3e 6e 43 6f 6c 2b  ta==pVtab->nCol+
5fa0: 32 20 7c 7c 20 6e 44 61 74 61 3d 3d 31 20 29 3b  2 || nData==1 );
5fb0: 0a 0a 20 20 2f 2a 20 49 66 20 61 70 44 61 74 61  ..  /* If apData
5fc0: 5b 30 5d 20 69 73 20 61 6e 20 69 6e 74 65 67 65  [0] is an intege
5fd0: 72 20 61 6e 64 20 6e 44 61 74 61 3e 31 20 74 68  r and nData>1 th
5fe0: 65 6e 20 64 6f 20 61 6e 20 55 50 44 41 54 45 20  en do an UPDATE 
5ff0: 2a 2f 0a 20 20 69 66 28 20 6e 44 61 74 61 3e 31  */.  if( nData>1
6000: 20 26 26 20 73 71 6c 69 74 65 33 5f 76 61 6c 75   && sqlite3_valu
6010: 65 5f 74 79 70 65 28 61 70 44 61 74 61 5b 30 5d  e_type(apData[0]
6020: 29 3d 3d 53 51 4c 49 54 45 5f 49 4e 54 45 47 45  )==SQLITE_INTEGE
6030: 52 20 29 7b 0a 20 20 20 20 63 68 61 72 20 2a 7a  R ){.    char *z
6040: 53 65 70 20 3d 20 22 20 53 45 54 22 3b 0a 20 20  Sep = " SET";.  
6050: 20 20 7a 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70    z = sqlite3_mp
6060: 72 69 6e 74 66 28 22 55 50 44 41 54 45 20 25 51  rintf("UPDATE %Q
6070: 22 2c 20 70 56 74 61 62 2d 3e 7a 54 61 62 6c 65  ", pVtab->zTable
6080: 4e 61 6d 65 29 3b 0a 20 20 20 20 69 66 28 20 21  Name);.    if( !
6090: 7a 20 29 7b 0a 20 20 20 20 20 20 72 63 20 3d 20  z ){.      rc = 
60a0: 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20  SQLITE_NOMEM;.  
60b0: 20 20 7d 0a 0a 20 20 20 20 62 69 6e 64 41 72 67    }..    bindArg
60c0: 4f 6e 65 20 3d 20 28 61 70 44 61 74 61 5b 31 5d  One = (apData[1]
60d0: 20 26 26 20 73 71 6c 69 74 65 33 5f 76 61 6c 75   && sqlite3_valu
60e0: 65 5f 74 79 70 65 28 61 70 44 61 74 61 5b 31 5d  e_type(apData[1]
60f0: 29 3d 3d 53 51 4c 49 54 45 5f 49 4e 54 45 47 45  )==SQLITE_INTEGE
6100: 52 29 3b 0a 20 20 20 20 62 69 6e 64 41 72 67 5a  R);.    bindArgZ
6110: 65 72 6f 20 3d 20 31 3b 0a 0a 20 20 20 20 69 66  ero = 1;..    if
6120: 28 20 62 69 6e 64 41 72 67 4f 6e 65 20 29 7b 0a  ( bindArgOne ){.
6130: 20 20 20 20 20 20 20 73 74 72 69 6e 67 5f 63 6f         string_co
6140: 6e 63 61 74 28 26 7a 2c 20 22 20 53 45 54 20 72  ncat(&z, " SET r
6150: 6f 77 69 64 3d 3f 31 20 22 2c 20 30 2c 20 26 72  owid=?1 ", 0, &r
6160: 63 29 3b 0a 20 20 20 20 20 20 20 7a 53 65 70 20  c);.       zSep 
6170: 3d 20 22 2c 22 3b 0a 20 20 20 20 7d 0a 20 20 20  = ",";.    }.   
6180: 20 66 6f 72 28 69 3d 32 3b 20 69 3c 6e 44 61 74   for(i=2; i<nDat
6190: 61 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20 69  a; i++){.      i
61a0: 66 28 20 61 70 44 61 74 61 5b 69 5d 3d 3d 30 20  f( apData[i]==0 
61b0: 29 20 63 6f 6e 74 69 6e 75 65 3b 0a 20 20 20 20  ) continue;.    
61c0: 20 20 73 74 72 69 6e 67 5f 63 6f 6e 63 61 74 28    string_concat(
61d0: 26 7a 2c 20 73 71 6c 69 74 65 33 5f 6d 70 72 69  &z, sqlite3_mpri
61e0: 6e 74 66 28 0a 20 20 20 20 20 20 20 20 20 20 22  ntf(.          "
61f0: 25 73 20 25 51 3d 3f 25 64 22 2c 20 7a 53 65 70  %s %Q=?%d", zSep
6200: 2c 20 70 56 74 61 62 2d 3e 61 43 6f 6c 5b 69 2d  , pVtab->aCol[i-
6210: 32 5d 2c 20 69 29 2c 20 31 2c 20 26 72 63 29 3b  2], i), 1, &rc);
6220: 0a 20 20 20 20 20 20 7a 53 65 70 20 3d 20 22 2c  .      zSep = ",
6230: 22 3b 0a 20 20 20 20 7d 0a 20 20 20 20 73 74 72  ";.    }.    str
6240: 69 6e 67 5f 63 6f 6e 63 61 74 28 26 7a 2c 20 73  ing_concat(&z, s
6250: 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 22  qlite3_mprintf("
6260: 20 57 48 45 52 45 20 72 6f 77 69 64 3d 3f 25 64   WHERE rowid=?%d
6270: 22 2c 20 6e 44 61 74 61 29 2c 20 31 2c 20 26 72  ", nData), 1, &r
6280: 63 29 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 49 66  c);.  }..  /* If
6290: 20 61 70 44 61 74 61 5b 30 5d 20 69 73 20 61 6e   apData[0] is an
62a0: 20 69 6e 74 65 67 65 72 20 61 6e 64 20 6e 44 61   integer and nDa
62b0: 74 61 3d 3d 31 20 74 68 65 6e 20 64 6f 20 61 20  ta==1 then do a 
62c0: 44 45 4c 45 54 45 20 2a 2f 0a 20 20 65 6c 73 65  DELETE */.  else
62d0: 20 69 66 28 20 6e 44 61 74 61 3d 3d 31 20 26 26   if( nData==1 &&
62e0: 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 74   sqlite3_value_t
62f0: 79 70 65 28 61 70 44 61 74 61 5b 30 5d 29 3d 3d  ype(apData[0])==
6300: 53 51 4c 49 54 45 5f 49 4e 54 45 47 45 52 20 29  SQLITE_INTEGER )
6310: 7b 0a 20 20 20 20 7a 20 3d 20 73 71 6c 69 74 65  {.    z = sqlite
6320: 33 5f 6d 70 72 69 6e 74 66 28 22 44 45 4c 45 54  3_mprintf("DELET
6330: 45 20 46 52 4f 4d 20 25 51 20 57 48 45 52 45 20  E FROM %Q WHERE 
6340: 72 6f 77 69 64 20 3d 20 3f 31 22 2c 20 70 56 74  rowid = ?1", pVt
6350: 61 62 2d 3e 7a 54 61 62 6c 65 4e 61 6d 65 29 3b  ab->zTableName);
6360: 0a 20 20 20 20 69 66 28 20 21 7a 20 29 7b 0a 20  .    if( !z ){. 
6370: 20 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45       rc = SQLITE
6380: 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 7d 0a 20 20  _NOMEM;.    }.  
6390: 20 20 62 69 6e 64 41 72 67 5a 65 72 6f 20 3d 20    bindArgZero = 
63a0: 31 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 49 66 20  1;.  }..  /* If 
63b0: 74 68 65 20 66 69 72 73 74 20 61 72 67 75 6d 65  the first argume
63c0: 6e 74 20 69 73 20 4e 55 4c 4c 20 61 6e 64 20 74  nt is NULL and t
63d0: 68 65 72 65 20 61 72 65 20 6d 6f 72 65 20 74 68  here are more th
63e0: 61 6e 20 74 77 6f 20 61 72 67 73 2c 20 49 4e 53  an two args, INS
63f0: 45 52 54 20 2a 2f 0a 20 20 65 6c 73 65 20 69 66  ERT */.  else if
6400: 28 20 6e 44 61 74 61 3e 32 20 26 26 20 73 71 6c  ( nData>2 && sql
6410: 69 74 65 33 5f 76 61 6c 75 65 5f 74 79 70 65 28  ite3_value_type(
6420: 61 70 44 61 74 61 5b 30 5d 29 3d 3d 53 51 4c 49  apData[0])==SQLI
6430: 54 45 5f 4e 55 4c 4c 20 29 7b 0a 20 20 20 20 69  TE_NULL ){.    i
6440: 6e 74 20 69 69 3b 0a 20 20 20 20 63 68 61 72 20  nt ii;.    char 
6450: 2a 7a 49 6e 73 65 72 74 20 3d 20 30 3b 0a 20 20  *zInsert = 0;.  
6460: 20 20 63 68 61 72 20 2a 7a 56 61 6c 75 65 73 20    char *zValues 
6470: 3d 20 30 3b 0a 20 20 0a 20 20 20 20 7a 49 6e 73  = 0;.  .    zIns
6480: 65 72 74 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70  ert = sqlite3_mp
6490: 72 69 6e 74 66 28 22 49 4e 53 45 52 54 20 49 4e  rintf("INSERT IN
64a0: 54 4f 20 25 51 20 28 22 2c 20 70 56 74 61 62 2d  TO %Q (", pVtab-
64b0: 3e 7a 54 61 62 6c 65 4e 61 6d 65 29 3b 0a 20 20  >zTableName);.  
64c0: 20 20 69 66 28 20 21 7a 49 6e 73 65 72 74 20 29    if( !zInsert )
64d0: 7b 0a 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c  {.      rc = SQL
64e0: 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 7d  ITE_NOMEM;.    }
64f0: 0a 20 20 20 20 69 66 28 20 73 71 6c 69 74 65 33  .    if( sqlite3
6500: 5f 76 61 6c 75 65 5f 74 79 70 65 28 61 70 44 61  _value_type(apDa
6510: 74 61 5b 31 5d 29 3d 3d 53 51 4c 49 54 45 5f 49  ta[1])==SQLITE_I
6520: 4e 54 45 47 45 52 20 29 7b 0a 20 20 20 20 20 20  NTEGER ){.      
6530: 62 69 6e 64 41 72 67 4f 6e 65 20 3d 20 31 3b 0a  bindArgOne = 1;.
6540: 20 20 20 20 20 20 7a 56 61 6c 75 65 73 20 3d 20        zValues = 
6550: 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28  sqlite3_mprintf(
6560: 22 3f 22 29 3b 0a 20 20 20 20 20 20 73 74 72 69  "?");.      stri
6570: 6e 67 5f 63 6f 6e 63 61 74 28 26 7a 49 6e 73 65  ng_concat(&zInse
6580: 72 74 2c 20 22 72 6f 77 69 64 22 2c 20 30 2c 20  rt, "rowid", 0, 
6590: 26 72 63 29 3b 0a 20 20 20 20 7d 0a 0a 20 20 20  &rc);.    }..   
65a0: 20 61 73 73 65 72 74 28 28 70 56 74 61 62 2d 3e   assert((pVtab->
65b0: 6e 43 6f 6c 2b 32 29 3d 3d 6e 44 61 74 61 29 3b  nCol+2)==nData);
65c0: 0a 20 20 20 20 66 6f 72 28 69 69 3d 32 3b 20 69  .    for(ii=2; i
65d0: 69 3c 6e 44 61 74 61 3b 20 69 69 2b 2b 29 7b 0a  i<nData; ii++){.
65e0: 20 20 20 20 20 20 73 74 72 69 6e 67 5f 63 6f 6e        string_con
65f0: 63 61 74 28 26 7a 49 6e 73 65 72 74 2c 20 0a 20  cat(&zInsert, . 
6600: 20 20 20 20 20 20 20 20 20 73 71 6c 69 74 65 33           sqlite3
6610: 5f 6d 70 72 69 6e 74 66 28 22 25 73 25 51 22 2c  _mprintf("%s%Q",
6620: 20 7a 56 61 6c 75 65 73 3f 22 2c 20 22 3a 22 22   zValues?", ":""
6630: 2c 20 70 56 74 61 62 2d 3e 61 43 6f 6c 5b 69 69  , pVtab->aCol[ii
6640: 2d 32 5d 29 2c 20 31 2c 20 26 72 63 29 3b 0a 20  -2]), 1, &rc);. 
6650: 20 20 20 20 20 73 74 72 69 6e 67 5f 63 6f 6e 63       string_conc
6660: 61 74 28 26 7a 56 61 6c 75 65 73 2c 20 0a 20 20  at(&zValues, .  
6670: 20 20 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f          sqlite3_
6680: 6d 70 72 69 6e 74 66 28 22 25 73 3f 25 64 22 2c  mprintf("%s?%d",
6690: 20 7a 56 61 6c 75 65 73 3f 22 2c 20 22 3a 22 22   zValues?", ":""
66a0: 2c 20 69 69 29 2c 20 31 2c 20 26 72 63 29 3b 0a  , ii), 1, &rc);.
66b0: 20 20 20 20 7d 0a 0a 20 20 20 20 73 74 72 69 6e      }..    strin
66c0: 67 5f 63 6f 6e 63 61 74 28 26 7a 2c 20 7a 49 6e  g_concat(&z, zIn
66d0: 73 65 72 74 2c 20 31 2c 20 26 72 63 29 3b 0a 20  sert, 1, &rc);. 
66e0: 20 20 20 73 74 72 69 6e 67 5f 63 6f 6e 63 61 74     string_concat
66f0: 28 26 7a 2c 20 22 29 20 56 41 4c 55 45 53 28 22  (&z, ") VALUES("
6700: 2c 20 30 2c 20 26 72 63 29 3b 0a 20 20 20 20 73  , 0, &rc);.    s
6710: 74 72 69 6e 67 5f 63 6f 6e 63 61 74 28 26 7a 2c  tring_concat(&z,
6720: 20 7a 56 61 6c 75 65 73 2c 20 31 2c 20 26 72 63   zValues, 1, &rc
6730: 29 3b 0a 20 20 20 20 73 74 72 69 6e 67 5f 63 6f  );.    string_co
6740: 6e 63 61 74 28 26 7a 2c 20 22 29 22 2c 20 30 2c  ncat(&z, ")", 0,
6750: 20 26 72 63 29 3b 0a 20 20 7d 0a 0a 20 20 2f 2a   &rc);.  }..  /*
6760: 20 41 6e 79 74 68 69 6e 67 20 65 6c 73 65 20 69   Anything else i
6770: 73 20 61 6e 20 65 72 72 6f 72 20 2a 2f 0a 20 20  s an error */.  
6780: 65 6c 73 65 7b 0a 20 20 20 20 61 73 73 65 72 74  else{.    assert
6790: 28 30 29 3b 0a 20 20 20 20 72 65 74 75 72 6e 20  (0);.    return 
67a0: 53 51 4c 49 54 45 5f 45 52 52 4f 52 3b 0a 20 20  SQLITE_ERROR;.  
67b0: 7d 0a 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c  }..  if( rc==SQL
67c0: 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 72 63  ITE_OK ){.    rc
67d0: 20 3d 20 73 71 6c 69 74 65 33 5f 70 72 65 70 61   = sqlite3_prepa
67e0: 72 65 28 64 62 2c 20 7a 2c 20 2d 31 2c 20 26 70  re(db, z, -1, &p
67f0: 53 74 6d 74 2c 20 30 29 3b 0a 20 20 7d 0a 20 20  Stmt, 0);.  }.  
6800: 61 73 73 65 72 74 28 20 72 63 21 3d 53 51 4c 49  assert( rc!=SQLI
6810: 54 45 5f 4f 4b 20 7c 7c 20 70 53 74 6d 74 20 29  TE_OK || pStmt )
6820: 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65  ;.  sqlite3_free
6830: 28 7a 29 3b 0a 20 20 69 66 28 20 72 63 3d 3d 53  (z);.  if( rc==S
6840: 51 4c 49 54 45 5f 4f 4b 20 29 20 7b 0a 20 20 20  QLITE_OK ) {.   
6850: 20 69 66 28 20 62 69 6e 64 41 72 67 5a 65 72 6f   if( bindArgZero
6860: 20 29 7b 0a 20 20 20 20 20 20 73 71 6c 69 74 65   ){.      sqlite
6870: 33 5f 62 69 6e 64 5f 76 61 6c 75 65 28 70 53 74  3_bind_value(pSt
6880: 6d 74 2c 20 6e 44 61 74 61 2c 20 61 70 44 61 74  mt, nData, apDat
6890: 61 5b 30 5d 29 3b 0a 20 20 20 20 7d 0a 20 20 20  a[0]);.    }.   
68a0: 20 69 66 28 20 62 69 6e 64 41 72 67 4f 6e 65 20   if( bindArgOne 
68b0: 29 7b 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33  ){.      sqlite3
68c0: 5f 62 69 6e 64 5f 76 61 6c 75 65 28 70 53 74 6d  _bind_value(pStm
68d0: 74 2c 20 31 2c 20 61 70 44 61 74 61 5b 31 5d 29  t, 1, apData[1])
68e0: 3b 0a 20 20 20 20 7d 0a 20 20 20 20 66 6f 72 28  ;.    }.    for(
68f0: 69 3d 32 3b 20 69 3c 6e 44 61 74 61 3b 20 69 2b  i=2; i<nData; i+
6900: 2b 29 7b 0a 20 20 20 20 20 20 69 66 28 20 61 70  +){.      if( ap
6910: 44 61 74 61 5b 69 5d 20 29 20 73 71 6c 69 74 65  Data[i] ) sqlite
6920: 33 5f 62 69 6e 64 5f 76 61 6c 75 65 28 70 53 74  3_bind_value(pSt
6930: 6d 74 2c 20 69 2c 20 61 70 44 61 74 61 5b 69 5d  mt, i, apData[i]
6940: 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 73 71 6c  );.    }.    sql
6950: 69 74 65 33 5f 73 74 65 70 28 70 53 74 6d 74 29  ite3_step(pStmt)
6960: 3b 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74  ;.    rc = sqlit
6970: 65 33 5f 66 69 6e 61 6c 69 7a 65 28 70 53 74 6d  e3_finalize(pStm
6980: 74 29 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 70  t);.  }..  if( p
6990: 52 6f 77 69 64 20 26 26 20 72 63 3d 3d 53 51 4c  Rowid && rc==SQL
69a0: 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 2a 70  ITE_OK ){.    *p
69b0: 52 6f 77 69 64 20 3d 20 73 71 6c 69 74 65 33 5f  Rowid = sqlite3_
69c0: 6c 61 73 74 5f 69 6e 73 65 72 74 5f 72 6f 77 69  last_insert_rowi
69d0: 64 28 64 62 29 3b 0a 20 20 7d 0a 0a 20 20 72 65  d(db);.  }..  re
69e0: 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a  turn rc;.}../*.*
69f0: 2a 20 78 42 65 67 69 6e 2c 20 78 53 79 6e 63 2c  * xBegin, xSync,
6a00: 20 78 43 6f 6d 6d 69 74 20 61 6e 64 20 78 52 6f   xCommit and xRo
6a10: 6c 6c 62 61 63 6b 20 63 61 6c 6c 62 61 63 6b 73  llback callbacks
6a20: 20 66 6f 72 20 65 63 68 6f 20 6d 6f 64 75 6c 65   for echo module
6a30: 0a 2a 2a 20 76 69 72 74 75 61 6c 20 74 61 62 6c  .** virtual tabl
6a40: 65 73 2e 20 44 6f 20 6e 6f 74 68 69 6e 67 20 6f  es. Do nothing o
6a50: 74 68 65 72 20 74 68 61 6e 20 61 64 64 20 74 68  ther than add th
6a60: 65 20 6e 61 6d 65 20 6f 66 20 74 68 65 20 63 61  e name of the ca
6a70: 6c 6c 62 61 63 6b 0a 2a 2a 20 74 6f 20 74 68 65  llback.** to the
6a80: 20 24 3a 3a 65 63 68 6f 5f 6d 6f 64 75 6c 65 20   $::echo_module 
6a90: 54 63 6c 20 76 61 72 69 61 62 6c 65 2e 0a 2a 2f  Tcl variable..*/
6aa0: 0a 73 74 61 74 69 63 20 69 6e 74 20 65 63 68 6f  .static int echo
6ab0: 54 72 61 6e 73 61 63 74 69 6f 6e 43 61 6c 6c 28  TransactionCall(
6ac0: 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 74 61  sqlite3_vtab *ta
6ad0: 62 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a  b, const char *z
6ae0: 43 61 6c 6c 29 7b 0a 20 20 63 68 61 72 20 2a 7a  Call){.  char *z
6af0: 3b 0a 20 20 65 63 68 6f 5f 76 74 61 62 20 2a 70  ;.  echo_vtab *p
6b00: 56 74 61 62 20 3d 20 28 65 63 68 6f 5f 76 74 61  Vtab = (echo_vta
6b10: 62 20 2a 29 74 61 62 3b 0a 20 20 7a 20 3d 20 73  b *)tab;.  z = s
6b20: 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 22  qlite3_mprintf("
6b30: 65 63 68 6f 28 25 73 29 22 2c 20 70 56 74 61 62  echo(%s)", pVtab
6b40: 2d 3e 7a 54 61 62 6c 65 4e 61 6d 65 29 3b 0a 20  ->zTableName);. 
6b50: 20 61 70 70 65 6e 64 54 6f 45 63 68 6f 4d 6f 64   appendToEchoMod
6b60: 75 6c 65 28 70 56 74 61 62 2d 3e 69 6e 74 65 72  ule(pVtab->inter
6b70: 70 2c 20 7a 43 61 6c 6c 29 3b 0a 20 20 61 70 70  p, zCall);.  app
6b80: 65 6e 64 54 6f 45 63 68 6f 4d 6f 64 75 6c 65 28  endToEchoModule(
6b90: 70 56 74 61 62 2d 3e 69 6e 74 65 72 70 2c 20 7a  pVtab->interp, z
6ba0: 29 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66 72 65  );.  sqlite3_fre
6bb0: 65 28 7a 29 3b 0a 20 20 72 65 74 75 72 6e 20 28  e(z);.  return (
6bc0: 7a 3f 53 51 4c 49 54 45 5f 4f 4b 3a 53 51 4c 49  z?SQLITE_OK:SQLI
6bd0: 54 45 5f 4e 4f 4d 45 4d 29 3b 0a 7d 0a 73 74 61  TE_NOMEM);.}.sta
6be0: 74 69 63 20 69 6e 74 20 65 63 68 6f 42 65 67 69  tic int echoBegi
6bf0: 6e 28 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a  n(sqlite3_vtab *
6c00: 74 61 62 29 7b 0a 20 20 69 6e 74 20 72 63 3b 0a  tab){.  int rc;.
6c10: 20 20 65 63 68 6f 5f 76 74 61 62 20 2a 70 56 74    echo_vtab *pVt
6c20: 61 62 20 3d 20 28 65 63 68 6f 5f 76 74 61 62 20  ab = (echo_vtab 
6c30: 2a 29 74 61 62 3b 0a 20 20 54 63 6c 5f 49 6e 74  *)tab;.  Tcl_Int
6c40: 65 72 70 20 2a 69 6e 74 65 72 70 20 3d 20 70 56  erp *interp = pV
6c50: 74 61 62 2d 3e 69 6e 74 65 72 70 3b 0a 20 20 63  tab->interp;.  c
6c60: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 56 61 6c 3b  onst char *zVal;
6c70: 20 0a 0a 20 20 72 63 20 3d 20 65 63 68 6f 54 72   ..  rc = echoTr
6c80: 61 6e 73 61 63 74 69 6f 6e 43 61 6c 6c 28 74 61  ansactionCall(ta
6c90: 62 2c 20 22 78 42 65 67 69 6e 22 29 3b 0a 0a 20  b, "xBegin");.. 
6ca0: 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
6cb0: 4f 4b 20 29 7b 0a 20 20 20 20 2f 2a 20 43 68 65  OK ){.    /* Che
6cc0: 63 6b 20 69 66 20 74 68 65 20 24 3a 3a 65 63 68  ck if the $::ech
6cd0: 6f 5f 6d 6f 64 75 6c 65 5f 62 65 67 69 6e 5f 66  o_module_begin_f
6ce0: 61 69 6c 20 76 61 72 69 61 62 6c 65 20 69 73 20  ail variable is 
6cf0: 64 65 66 69 6e 65 64 2e 20 49 66 20 69 74 20 69  defined. If it i
6d00: 73 2c 0a 20 20 20 20 2a 2a 20 61 6e 64 20 69 74  s,.    ** and it
6d10: 20 69 73 20 73 65 74 20 74 6f 20 74 68 65 20 6e   is set to the n
6d20: 61 6d 65 20 6f 66 20 74 68 65 20 72 65 61 6c 20  ame of the real 
6d30: 74 61 62 6c 65 20 75 6e 64 65 72 6c 79 69 6e 67  table underlying
6d40: 20 74 68 69 73 20 76 69 72 74 75 61 6c 0a 20 20   this virtual.  
6d50: 20 20 2a 2a 20 65 63 68 6f 20 6d 6f 64 75 6c 65    ** echo module
6d60: 20 74 61 62 6c 65 2c 20 74 68 65 6e 20 63 61 75   table, then cau
6d70: 73 65 20 74 68 69 73 20 78 53 79 6e 63 20 6f 70  se this xSync op
6d80: 65 72 61 74 69 6f 6e 20 74 6f 20 66 61 69 6c 2e  eration to fail.
6d90: 0a 20 20 20 20 2a 2f 0a 20 20 20 20 7a 56 61 6c  .    */.    zVal
6da0: 20 3d 20 54 63 6c 5f 47 65 74 56 61 72 28 69 6e   = Tcl_GetVar(in
6db0: 74 65 72 70 2c 20 22 65 63 68 6f 5f 6d 6f 64 75  terp, "echo_modu
6dc0: 6c 65 5f 62 65 67 69 6e 5f 66 61 69 6c 22 2c 20  le_begin_fail", 
6dd0: 54 43 4c 5f 47 4c 4f 42 41 4c 5f 4f 4e 4c 59 29  TCL_GLOBAL_ONLY)
6de0: 3b 0a 20 20 20 20 69 66 28 20 7a 56 61 6c 20 26  ;.    if( zVal &
6df0: 26 20 30 3d 3d 73 74 72 63 6d 70 28 7a 56 61 6c  & 0==strcmp(zVal
6e00: 2c 20 70 56 74 61 62 2d 3e 7a 54 61 62 6c 65 4e  , pVtab->zTableN
6e10: 61 6d 65 29 20 29 7b 0a 20 20 20 20 20 20 72 63  ame) ){.      rc
6e20: 20 3d 20 53 51 4c 49 54 45 5f 45 52 52 4f 52 3b   = SQLITE_ERROR;
6e30: 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 72 65 74  .    }.  }.  ret
6e40: 75 72 6e 20 72 63 3b 0a 7d 0a 73 74 61 74 69 63  urn rc;.}.static
6e50: 20 69 6e 74 20 65 63 68 6f 53 79 6e 63 28 73 71   int echoSync(sq
6e60: 6c 69 74 65 33 5f 76 74 61 62 20 2a 74 61 62 29  lite3_vtab *tab)
6e70: 7b 0a 20 20 69 6e 74 20 72 63 3b 0a 20 20 65 63  {.  int rc;.  ec
6e80: 68 6f 5f 76 74 61 62 20 2a 70 56 74 61 62 20 3d  ho_vtab *pVtab =
6e90: 20 28 65 63 68 6f 5f 76 74 61 62 20 2a 29 74 61   (echo_vtab *)ta
6ea0: 62 3b 0a 20 20 54 63 6c 5f 49 6e 74 65 72 70 20  b;.  Tcl_Interp 
6eb0: 2a 69 6e 74 65 72 70 20 3d 20 70 56 74 61 62 2d  *interp = pVtab-
6ec0: 3e 69 6e 74 65 72 70 3b 0a 20 20 63 6f 6e 73 74  >interp;.  const
6ed0: 20 63 68 61 72 20 2a 7a 56 61 6c 3b 20 0a 0a 20   char *zVal; .. 
6ee0: 20 72 63 20 3d 20 65 63 68 6f 54 72 61 6e 73 61   rc = echoTransa
6ef0: 63 74 69 6f 6e 43 61 6c 6c 28 74 61 62 2c 20 22  ctionCall(tab, "
6f00: 78 53 79 6e 63 22 29 3b 0a 0a 20 20 69 66 28 20  xSync");..  if( 
6f10: 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc==SQLITE_OK ){
6f20: 0a 20 20 20 20 2f 2a 20 43 68 65 63 6b 20 69 66  .    /* Check if
6f30: 20 74 68 65 20 24 3a 3a 65 63 68 6f 5f 6d 6f 64   the $::echo_mod
6f40: 75 6c 65 5f 73 79 6e 63 5f 66 61 69 6c 20 76 61  ule_sync_fail va
6f50: 72 69 61 62 6c 65 20 69 73 20 64 65 66 69 6e 65  riable is define
6f60: 64 2e 20 49 66 20 69 74 20 69 73 2c 0a 20 20 20  d. If it is,.   
6f70: 20 2a 2a 20 61 6e 64 20 69 74 20 69 73 20 73 65   ** and it is se
6f80: 74 20 74 6f 20 74 68 65 20 6e 61 6d 65 20 6f 66  t to the name of
6f90: 20 74 68 65 20 72 65 61 6c 20 74 61 62 6c 65 20   the real table 
6fa0: 75 6e 64 65 72 6c 79 69 6e 67 20 74 68 69 73 20  underlying this 
6fb0: 76 69 72 74 75 61 6c 0a 20 20 20 20 2a 2a 20 65  virtual.    ** e
6fc0: 63 68 6f 20 6d 6f 64 75 6c 65 20 74 61 62 6c 65  cho module table
6fd0: 2c 20 74 68 65 6e 20 63 61 75 73 65 20 74 68 69  , then cause thi
6fe0: 73 20 78 53 79 6e 63 20 6f 70 65 72 61 74 69 6f  s xSync operatio
6ff0: 6e 20 74 6f 20 66 61 69 6c 2e 0a 20 20 20 20 2a  n to fail..    *
7000: 2f 0a 20 20 20 20 7a 56 61 6c 20 3d 20 54 63 6c  /.    zVal = Tcl
7010: 5f 47 65 74 56 61 72 28 69 6e 74 65 72 70 2c 20  _GetVar(interp, 
7020: 22 65 63 68 6f 5f 6d 6f 64 75 6c 65 5f 73 79 6e  "echo_module_syn
7030: 63 5f 66 61 69 6c 22 2c 20 54 43 4c 5f 47 4c 4f  c_fail", TCL_GLO
7040: 42 41 4c 5f 4f 4e 4c 59 29 3b 0a 20 20 20 20 69  BAL_ONLY);.    i
7050: 66 28 20 7a 56 61 6c 20 26 26 20 30 3d 3d 73 74  f( zVal && 0==st
7060: 72 63 6d 70 28 7a 56 61 6c 2c 20 70 56 74 61 62  rcmp(zVal, pVtab
7070: 2d 3e 7a 54 61 62 6c 65 4e 61 6d 65 29 20 29 7b  ->zTableName) ){
7080: 0a 20 20 20 20 20 20 72 63 20 3d 20 2d 31 3b 0a  .      rc = -1;.
7090: 20 20 20 20 7d 0a 20 20 7d 0a 20 20 72 65 74 75      }.  }.  retu
70a0: 72 6e 20 72 63 3b 0a 7d 0a 73 74 61 74 69 63 20  rn rc;.}.static 
70b0: 69 6e 74 20 65 63 68 6f 43 6f 6d 6d 69 74 28 73  int echoCommit(s
70c0: 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 74 61 62  qlite3_vtab *tab
70d0: 29 7b 0a 20 20 73 71 6c 69 74 65 33 4d 61 6c 6c  ){.  sqlite3Mall
70e0: 6f 63 42 65 6e 69 67 6e 46 61 69 6c 75 72 65 28  ocBenignFailure(
70f0: 31 29 3b 0a 20 20 72 65 74 75 72 6e 20 65 63 68  1);.  return ech
7100: 6f 54 72 61 6e 73 61 63 74 69 6f 6e 43 61 6c 6c  oTransactionCall
7110: 28 74 61 62 2c 20 22 78 43 6f 6d 6d 69 74 22 29  (tab, "xCommit")
7120: 3b 0a 7d 0a 73 74 61 74 69 63 20 69 6e 74 20 65  ;.}.static int e
7130: 63 68 6f 52 6f 6c 6c 62 61 63 6b 28 73 71 6c 69  choRollback(sqli
7140: 74 65 33 5f 76 74 61 62 20 2a 74 61 62 29 7b 0a  te3_vtab *tab){.
7150: 20 20 72 65 74 75 72 6e 20 65 63 68 6f 54 72 61    return echoTra
7160: 6e 73 61 63 74 69 6f 6e 43 61 6c 6c 28 74 61 62  nsactionCall(tab
7170: 2c 20 22 78 52 6f 6c 6c 62 61 63 6b 22 29 3b 0a  , "xRollback");.
7180: 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65  }../*.** Impleme
7190: 6e 74 61 74 69 6f 6e 20 6f 66 20 22 47 4c 4f 42  ntation of "GLOB
71a0: 22 20 66 75 6e 63 74 69 6f 6e 20 6f 6e 20 74 68  " function on th
71b0: 65 20 65 63 68 6f 20 6d 6f 64 75 6c 65 2e 20 20  e echo module.  
71c0: 50 61 73 73 0a 2a 2a 20 61 6c 6c 20 61 72 67 75  Pass.** all argu
71d0: 6d 65 6e 74 73 20 74 6f 20 74 68 65 20 3a 3a 65  ments to the ::e
71e0: 63 68 6f 5f 67 6c 6f 62 5f 6f 76 65 72 6c 6f 61  cho_glob_overloa
71f0: 64 20 70 72 6f 63 65 64 75 72 65 20 6f 66 20 54  d procedure of T
7200: 43 4c 0a 2a 2a 20 61 6e 64 20 72 65 74 75 72 6e  CL.** and return
7210: 20 74 68 65 20 72 65 73 75 6c 74 20 6f 66 20 74   the result of t
7220: 68 61 74 20 70 72 6f 63 65 64 75 72 65 20 61 73  hat procedure as
7230: 20 61 20 73 74 72 69 6e 67 2e 0a 2a 2f 0a 73 74   a string..*/.st
7240: 61 74 69 63 20 76 6f 69 64 20 6f 76 65 72 6c 6f  atic void overlo
7250: 61 64 65 64 47 6c 6f 62 46 75 6e 63 74 69 6f 6e  adedGlobFunction
7260: 28 0a 20 20 73 71 6c 69 74 65 33 5f 63 6f 6e 74  (.  sqlite3_cont
7270: 65 78 74 20 2a 70 43 6f 6e 74 65 78 74 2c 0a 20  ext *pContext,. 
7280: 20 69 6e 74 20 6e 41 72 67 2c 0a 20 20 73 71 6c   int nArg,.  sql
7290: 69 74 65 33 5f 76 61 6c 75 65 20 2a 2a 61 70 41  ite3_value **apA
72a0: 72 67 0a 29 7b 0a 20 20 54 63 6c 5f 49 6e 74 65  rg.){.  Tcl_Inte
72b0: 72 70 20 2a 69 6e 74 65 72 70 20 3d 20 73 71 6c  rp *interp = sql
72c0: 69 74 65 33 5f 75 73 65 72 5f 64 61 74 61 28 70  ite3_user_data(p
72d0: 43 6f 6e 74 65 78 74 29 3b 0a 20 20 54 63 6c 5f  Context);.  Tcl_
72e0: 44 53 74 72 69 6e 67 20 73 74 72 3b 0a 20 20 69  DString str;.  i
72f0: 6e 74 20 69 3b 0a 20 20 69 6e 74 20 72 63 3b 0a  nt i;.  int rc;.
7300: 20 20 54 63 6c 5f 44 53 74 72 69 6e 67 49 6e 69    Tcl_DStringIni
7310: 74 28 26 73 74 72 29 3b 0a 20 20 54 63 6c 5f 44  t(&str);.  Tcl_D
7320: 53 74 72 69 6e 67 41 70 70 65 6e 64 45 6c 65 6d  StringAppendElem
7330: 65 6e 74 28 26 73 74 72 2c 20 22 3a 3a 65 63 68  ent(&str, "::ech
7340: 6f 5f 67 6c 6f 62 5f 6f 76 65 72 6c 6f 61 64 22  o_glob_overload"
7350: 29 3b 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c  );.  for(i=0; i<
7360: 6e 41 72 67 3b 20 69 2b 2b 29 7b 0a 20 20 20 20  nArg; i++){.    
7370: 54 63 6c 5f 44 53 74 72 69 6e 67 41 70 70 65 6e  Tcl_DStringAppen
7380: 64 45 6c 65 6d 65 6e 74 28 26 73 74 72 2c 20 28  dElement(&str, (
7390: 63 68 61 72 2a 29 73 71 6c 69 74 65 33 5f 76 61  char*)sqlite3_va
73a0: 6c 75 65 5f 74 65 78 74 28 61 70 41 72 67 5b 69  lue_text(apArg[i
73b0: 5d 29 29 3b 0a 20 20 7d 0a 20 20 72 63 20 3d 20  ]));.  }.  rc = 
73c0: 54 63 6c 5f 45 76 61 6c 28 69 6e 74 65 72 70 2c  Tcl_Eval(interp,
73d0: 20 54 63 6c 5f 44 53 74 72 69 6e 67 56 61 6c 75   Tcl_DStringValu
73e0: 65 28 26 73 74 72 29 29 3b 0a 20 20 54 63 6c 5f  e(&str));.  Tcl_
73f0: 44 53 74 72 69 6e 67 46 72 65 65 28 26 73 74 72  DStringFree(&str
7400: 29 3b 0a 20 20 69 66 28 20 72 63 20 29 7b 0a 20  );.  if( rc ){. 
7410: 20 20 20 73 71 6c 69 74 65 33 5f 72 65 73 75 6c     sqlite3_resul
7420: 74 5f 65 72 72 6f 72 28 70 43 6f 6e 74 65 78 74  t_error(pContext
7430: 2c 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 52  , Tcl_GetStringR
7440: 65 73 75 6c 74 28 69 6e 74 65 72 70 29 2c 20 2d  esult(interp), -
7450: 31 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20  1);.  }else{.   
7460: 20 73 71 6c 69 74 65 33 5f 72 65 73 75 6c 74 5f   sqlite3_result_
7470: 74 65 78 74 28 70 43 6f 6e 74 65 78 74 2c 20 54  text(pContext, T
7480: 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75  cl_GetStringResu
7490: 6c 74 28 69 6e 74 65 72 70 29 2c 0a 20 20 20 20  lt(interp),.    
74a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
74b0: 20 20 20 20 2d 31 2c 20 53 51 4c 49 54 45 5f 54      -1, SQLITE_T
74c0: 52 41 4e 53 49 45 4e 54 29 3b 0a 20 20 7d 0a 20  RANSIENT);.  }. 
74d0: 20 54 63 6c 5f 52 65 73 65 74 52 65 73 75 6c 74   Tcl_ResetResult
74e0: 28 69 6e 74 65 72 70 29 3b 0a 7d 0a 0a 2f 2a 0a  (interp);.}../*.
74f0: 2a 2a 20 54 68 69 73 20 69 73 20 74 68 65 20 78  ** This is the x
7500: 46 69 6e 64 46 75 6e 63 74 69 6f 6e 20 69 6d 70  FindFunction imp
7510: 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 66 6f 72 20  lementation for 
7520: 74 68 65 20 65 63 68 6f 20 6d 6f 64 75 6c 65 2e  the echo module.
7530: 0a 2a 2a 20 53 51 4c 69 74 65 20 63 61 6c 6c 73  .** SQLite calls
7540: 20 74 68 69 73 20 72 6f 75 74 69 6e 65 20 77 68   this routine wh
7550: 65 6e 20 74 68 65 20 66 69 72 73 74 20 61 72 67  en the first arg
7560: 75 6d 65 6e 74 20 6f 66 20 61 20 66 75 6e 63 74  ument of a funct
7570: 69 6f 6e 0a 2a 2a 20 69 73 20 61 20 63 6f 6c 75  ion.** is a colu
7580: 6d 6e 20 6f 66 20 61 6e 20 65 63 68 6f 20 76 69  mn of an echo vi
7590: 72 74 75 61 6c 20 74 61 62 6c 65 2e 20 20 54 68  rtual table.  Th
75a0: 69 73 20 72 6f 75 74 69 6e 65 20 63 61 6e 20 6f  is routine can o
75b0: 70 74 69 6f 6e 61 6c 6c 79 0a 2a 2a 20 6f 76 65  ptionally.** ove
75c0: 72 72 69 64 65 20 74 68 65 20 69 6d 70 6c 65 6d  rride the implem
75d0: 65 6e 74 61 74 69 6f 6e 20 6f 66 20 74 68 61 74  entation of that
75e0: 20 66 75 6e 63 74 69 6f 6e 2e 20 20 49 74 20 77   function.  It w
75f0: 69 6c 6c 20 63 68 6f 6f 73 65 20 74 6f 0a 2a 2a  ill choose to.**
7600: 20 64 6f 20 73 6f 20 69 66 20 74 68 65 20 66 75   do so if the fu
7610: 6e 63 74 69 6f 6e 20 69 73 20 6e 61 6d 65 64 20  nction is named 
7620: 22 67 6c 6f 62 22 2c 20 61 6e 64 20 61 20 54 43  "glob", and a TC
7630: 4c 20 63 6f 6d 6d 61 6e 64 20 6e 61 6d 65 64 0a  L command named.
7640: 2a 2a 20 3a 3a 65 63 68 6f 5f 67 6c 6f 62 5f 6f  ** ::echo_glob_o
7650: 76 65 72 6c 6f 61 64 20 65 78 69 73 74 73 2e 0a  verload exists..
7660: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 65 63  */.static int ec
7670: 68 6f 46 69 6e 64 46 75 6e 63 74 69 6f 6e 28 0a  hoFindFunction(.
7680: 20 20 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a    sqlite3_vtab *
7690: 76 74 61 62 2c 0a 20 20 69 6e 74 20 6e 41 72 67  vtab,.  int nArg
76a0: 2c 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a  ,.  const char *
76b0: 7a 46 75 6e 63 4e 61 6d 65 2c 0a 20 20 76 6f 69  zFuncName,.  voi
76c0: 64 20 28 2a 2a 70 78 46 75 6e 63 29 28 73 71 6c  d (**pxFunc)(sql
76d0: 69 74 65 33 5f 63 6f 6e 74 65 78 74 2a 2c 69 6e  ite3_context*,in
76e0: 74 2c 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 2a  t,sqlite3_value*
76f0: 2a 29 2c 0a 20 20 76 6f 69 64 20 2a 2a 70 70 41  *),.  void **ppA
7700: 72 67 0a 29 7b 0a 20 20 65 63 68 6f 5f 76 74 61  rg.){.  echo_vta
7710: 62 20 2a 70 56 74 61 62 20 3d 20 28 65 63 68 6f  b *pVtab = (echo
7720: 5f 76 74 61 62 20 2a 29 76 74 61 62 3b 0a 20 20  _vtab *)vtab;.  
7730: 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65  Tcl_Interp *inte
7740: 72 70 20 3d 20 70 56 74 61 62 2d 3e 69 6e 74 65  rp = pVtab->inte
7750: 72 70 3b 0a 20 20 54 63 6c 5f 43 6d 64 49 6e 66  rp;.  Tcl_CmdInf
7760: 6f 20 69 6e 66 6f 3b 0a 20 20 69 66 28 20 73 74  o info;.  if( st
7770: 72 63 6d 70 28 7a 46 75 6e 63 4e 61 6d 65 2c 22  rcmp(zFuncName,"
7780: 67 6c 6f 62 22 29 21 3d 30 20 29 7b 0a 20 20 20  glob")!=0 ){.   
7790: 20 72 65 74 75 72 6e 20 30 3b 0a 20 20 7d 0a 20   return 0;.  }. 
77a0: 20 69 66 28 20 54 63 6c 5f 47 65 74 43 6f 6d 6d   if( Tcl_GetComm
77b0: 61 6e 64 49 6e 66 6f 28 69 6e 74 65 72 70 2c 20  andInfo(interp, 
77c0: 22 3a 3a 65 63 68 6f 5f 67 6c 6f 62 5f 6f 76 65  "::echo_glob_ove
77d0: 72 6c 6f 61 64 22 2c 20 26 69 6e 66 6f 29 3d 3d  rload", &info)==
77e0: 30 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20  0 ){.    return 
77f0: 30 3b 0a 20 20 7d 0a 20 20 2a 70 78 46 75 6e 63  0;.  }.  *pxFunc
7800: 20 3d 20 6f 76 65 72 6c 6f 61 64 65 64 47 6c 6f   = overloadedGlo
7810: 62 46 75 6e 63 74 69 6f 6e 3b 0a 20 20 2a 70 70  bFunction;.  *pp
7820: 41 72 67 20 3d 20 69 6e 74 65 72 70 3b 0a 20 20  Arg = interp;.  
7830: 72 65 74 75 72 6e 20 31 3b 0a 7d 0a 0a 73 74 61  return 1;.}..sta
7840: 74 69 63 20 69 6e 74 20 65 63 68 6f 52 65 6e 61  tic int echoRena
7850: 6d 65 28 73 71 6c 69 74 65 33 5f 76 74 61 62 20  me(sqlite3_vtab 
7860: 2a 76 74 61 62 2c 20 63 6f 6e 73 74 20 63 68 61  *vtab, const cha
7870: 72 20 2a 7a 4e 65 77 4e 61 6d 65 29 7b 0a 20 20  r *zNewName){.  
7880: 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f  int rc = SQLITE_
7890: 4f 4b 3b 0a 20 20 65 63 68 6f 5f 76 74 61 62 20  OK;.  echo_vtab 
78a0: 2a 70 20 3d 20 28 65 63 68 6f 5f 76 74 61 62 20  *p = (echo_vtab 
78b0: 2a 29 76 74 61 62 3b 0a 0a 20 20 69 66 28 20 70  *)vtab;..  if( p
78c0: 2d 3e 69 73 50 61 74 74 65 72 6e 20 29 7b 0a 20  ->isPattern ){. 
78d0: 20 20 20 69 6e 74 20 6e 54 68 69 73 20 3d 20 73     int nThis = s
78e0: 74 72 6c 65 6e 28 70 2d 3e 7a 54 68 69 73 29 3b  trlen(p->zThis);
78f0: 0a 20 20 20 20 63 68 61 72 20 2a 7a 53 71 6c 20  .    char *zSql 
7900: 3d 20 73 71 6c 69 74 65 33 4d 50 72 69 6e 74 66  = sqlite3MPrintf
7910: 28 30 2c 20 22 41 4c 54 45 52 20 54 41 42 4c 45  (0, "ALTER TABLE
7920: 20 25 73 20 52 45 4e 41 4d 45 20 54 4f 20 25 73   %s RENAME TO %s
7930: 25 73 22 2c 20 0a 20 20 20 20 20 20 20 20 70 2d  %s", .        p-
7940: 3e 7a 54 61 62 6c 65 4e 61 6d 65 2c 20 7a 4e 65  >zTableName, zNe
7950: 77 4e 61 6d 65 2c 20 26 70 2d 3e 7a 54 61 62 6c  wName, &p->zTabl
7960: 65 4e 61 6d 65 5b 6e 54 68 69 73 5d 0a 20 20 20  eName[nThis].   
7970: 20 29 3b 0a 20 20 20 20 72 63 20 3d 20 73 71 6c   );.    rc = sql
7980: 69 74 65 33 5f 65 78 65 63 28 70 2d 3e 64 62 2c  ite3_exec(p->db,
7990: 20 7a 53 71 6c 2c 20 30 2c 20 30 2c 20 30 29 3b   zSql, 0, 0, 0);
79a0: 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65  .    sqlite3_fre
79b0: 65 28 7a 53 71 6c 29 3b 0a 20 20 7d 0a 0a 20 20  e(zSql);.  }..  
79c0: 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a  return rc;.}../*
79d0: 0a 2a 2a 20 41 20 76 69 72 74 75 61 6c 20 74 61  .** A virtual ta
79e0: 62 6c 65 20 6d 6f 64 75 6c 65 20 74 68 61 74 20  ble module that 
79f0: 6d 65 72 65 6c 79 20 22 65 63 68 6f 73 22 20 74  merely "echos" t
7a00: 68 65 20 63 6f 6e 74 65 6e 74 73 20 6f 66 20 61  he contents of a
7a10: 6e 6f 74 68 65 72 0a 2a 2a 20 74 61 62 6c 65 20  nother.** table 
7a20: 28 6c 69 6b 65 20 61 6e 20 53 51 4c 20 56 49 45  (like an SQL VIE
7a30: 57 29 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 73 71  W)..*/.static sq
7a40: 6c 69 74 65 33 5f 6d 6f 64 75 6c 65 20 65 63 68  lite3_module ech
7a50: 6f 4d 6f 64 75 6c 65 20 3d 20 7b 0a 20 20 30 2c  oModule = {.  0,
7a60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7a70: 20 20 20 20 20 20 20 20 20 2f 2a 20 69 56 65 72           /* iVer
7a80: 73 69 6f 6e 20 2a 2f 0a 20 20 65 63 68 6f 43 72  sion */.  echoCr
7a90: 65 61 74 65 2c 0a 20 20 65 63 68 6f 43 6f 6e 6e  eate,.  echoConn
7aa0: 65 63 74 2c 0a 20 20 65 63 68 6f 42 65 73 74 49  ect,.  echoBestI
7ab0: 6e 64 65 78 2c 0a 20 20 65 63 68 6f 44 69 73 63  ndex,.  echoDisc
7ac0: 6f 6e 6e 65 63 74 2c 20 0a 20 20 65 63 68 6f 44  onnect, .  echoD
7ad0: 65 73 74 72 6f 79 2c 0a 20 20 65 63 68 6f 4f 70  estroy,.  echoOp
7ae0: 65 6e 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  en,             
7af0: 20 20 20 20 20 2f 2a 20 78 4f 70 65 6e 20 2d 20       /* xOpen - 
7b00: 6f 70 65 6e 20 61 20 63 75 72 73 6f 72 20 2a 2f  open a cursor */
7b10: 0a 20 20 65 63 68 6f 43 6c 6f 73 65 2c 20 20 20  .  echoClose,   
7b20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
7b30: 20 78 43 6c 6f 73 65 20 2d 20 63 6c 6f 73 65 20   xClose - close 
7b40: 61 20 63 75 72 73 6f 72 20 2a 2f 0a 20 20 65 63  a cursor */.  ec
7b50: 68 6f 46 69 6c 74 65 72 2c 20 20 20 20 20 20 20  hoFilter,       
7b60: 20 20 20 20 20 20 20 20 20 2f 2a 20 78 46 69 6c           /* xFil
7b70: 74 65 72 20 2d 20 63 6f 6e 66 69 67 75 72 65 20  ter - configure 
7b80: 73 63 61 6e 20 63 6f 6e 73 74 72 61 69 6e 74 73  scan constraints
7b90: 20 2a 2f 0a 20 20 65 63 68 6f 4e 65 78 74 2c 20   */.  echoNext, 
7ba0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7bb0: 20 2f 2a 20 78 4e 65 78 74 20 2d 20 61 64 76 61   /* xNext - adva
7bc0: 6e 63 65 20 61 20 63 75 72 73 6f 72 20 2a 2f 0a  nce a cursor */.
7bd0: 20 20 65 63 68 6f 45 6f 66 2c 20 20 20 20 20 20    echoEof,      
7be0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
7bf0: 78 45 6f 66 20 2a 2f 0a 20 20 65 63 68 6f 43 6f  xEof */.  echoCo
7c00: 6c 75 6d 6e 2c 20 20 20 20 20 20 20 20 20 20 20  lumn,           
7c10: 20 20 20 20 20 2f 2a 20 78 43 6f 6c 75 6d 6e 20       /* xColumn 
7c20: 2d 20 72 65 61 64 20 64 61 74 61 20 2a 2f 0a 20  - read data */. 
7c30: 20 65 63 68 6f 52 6f 77 69 64 2c 20 20 20 20 20   echoRowid,     
7c40: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78              /* x
7c50: 52 6f 77 69 64 20 2d 20 72 65 61 64 20 64 61 74  Rowid - read dat
7c60: 61 20 2a 2f 0a 20 20 65 63 68 6f 55 70 64 61 74  a */.  echoUpdat
7c70: 65 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  e,              
7c80: 20 20 2f 2a 20 78 55 70 64 61 74 65 20 2d 20 77    /* xUpdate - w
7c90: 72 69 74 65 20 64 61 74 61 20 2a 2f 0a 20 20 65  rite data */.  e
7ca0: 63 68 6f 42 65 67 69 6e 2c 20 20 20 20 20 20 20  choBegin,       
7cb0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 42 65            /* xBe
7cc0: 67 69 6e 20 2d 20 62 65 67 69 6e 20 74 72 61 6e  gin - begin tran
7cd0: 73 61 63 74 69 6f 6e 20 2a 2f 0a 20 20 65 63 68  saction */.  ech
7ce0: 6f 53 79 6e 63 2c 20 20 20 20 20 20 20 20 20 20  oSync,          
7cf0: 20 20 20 20 20 20 20 20 2f 2a 20 78 53 79 6e 63          /* xSync
7d00: 20 2d 20 73 79 6e 63 20 74 72 61 6e 73 61 63 74   - sync transact
7d10: 69 6f 6e 20 2a 2f 0a 20 20 65 63 68 6f 43 6f 6d  ion */.  echoCom
7d20: 6d 69 74 2c 20 20 20 20 20 20 20 20 20 20 20 20  mit,            
7d30: 20 20 20 20 2f 2a 20 78 43 6f 6d 6d 69 74 20 2d      /* xCommit -
7d40: 20 63 6f 6d 6d 69 74 20 74 72 61 6e 73 61 63 74   commit transact
7d50: 69 6f 6e 20 2a 2f 0a 20 20 65 63 68 6f 52 6f 6c  ion */.  echoRol
7d60: 6c 62 61 63 6b 2c 20 20 20 20 20 20 20 20 20 20  lback,          
7d70: 20 20 20 20 2f 2a 20 78 52 6f 6c 6c 62 61 63 6b      /* xRollback
7d80: 20 2d 20 72 6f 6c 6c 62 61 63 6b 20 74 72 61 6e   - rollback tran
7d90: 73 61 63 74 69 6f 6e 20 2a 2f 0a 20 20 65 63 68  saction */.  ech
7da0: 6f 46 69 6e 64 46 75 6e 63 74 69 6f 6e 2c 20 20  oFindFunction,  
7db0: 20 20 20 20 20 20 20 20 2f 2a 20 78 46 69 6e 64          /* xFind
7dc0: 46 75 6e 63 74 69 6f 6e 20 2d 20 66 75 6e 63 74  Function - funct
7dd0: 69 6f 6e 20 6f 76 65 72 6c 6f 61 64 69 6e 67 20  ion overloading 
7de0: 2a 2f 0a 20 20 65 63 68 6f 52 65 6e 61 6d 65 2c  */.  echoRename,
7df0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7e00: 2f 2a 20 78 52 65 6e 61 6d 65 20 2d 20 72 65 6e  /* xRename - ren
7e10: 61 6d 65 20 74 68 65 20 74 61 62 6c 65 20 2a 2f  ame the table */
7e20: 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 44 65 63 6f 64  .};../*.** Decod
7e30: 65 20 61 20 70 6f 69 6e 74 65 72 20 74 6f 20 61  e a pointer to a
7e40: 6e 20 73 71 6c 69 74 65 33 20 6f 62 6a 65 63 74  n sqlite3 object
7e50: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
7e60: 67 65 74 44 62 50 6f 69 6e 74 65 72 28 54 63 6c  getDbPointer(Tcl
7e70: 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 2c  _Interp *interp,
7e80: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 41 2c   const char *zA,
7e90: 20 73 71 6c 69 74 65 33 20 2a 2a 70 70 44 62 29   sqlite3 **ppDb)
7ea0: 7b 0a 20 20 2a 70 70 44 62 20 3d 20 28 73 71 6c  {.  *ppDb = (sql
7eb0: 69 74 65 33 2a 29 73 71 6c 69 74 65 33 54 65 78  ite3*)sqlite3Tex
7ec0: 74 54 6f 50 74 72 28 7a 41 29 3b 0a 20 20 72 65  tToPtr(zA);.  re
7ed0: 74 75 72 6e 20 54 43 4c 5f 4f 4b 3b 0a 7d 0a 0a  turn TCL_OK;.}..
7ee0: 73 74 61 74 69 63 20 76 6f 69 64 20 6d 6f 64 75  static void modu
7ef0: 6c 65 44 65 73 74 72 6f 79 28 76 6f 69 64 20 2a  leDestroy(void *
7f00: 70 29 7b 0a 20 20 73 71 6c 69 74 65 33 5f 66 72  p){.  sqlite3_fr
7f10: 65 65 28 70 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  ee(p);.}../*.** 
7f20: 52 65 67 69 73 74 65 72 20 74 68 65 20 65 63 68  Register the ech
7f30: 6f 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65 20  o virtual table 
7f40: 6d 6f 64 75 6c 65 2e 0a 2a 2f 0a 73 74 61 74 69  module..*/.stati
7f50: 63 20 69 6e 74 20 72 65 67 69 73 74 65 72 5f 65  c int register_e
7f60: 63 68 6f 5f 6d 6f 64 75 6c 65 28 0a 20 20 43 6c  cho_module(.  Cl
7f70: 69 65 6e 74 44 61 74 61 20 63 6c 69 65 6e 74 44  ientData clientD
7f80: 61 74 61 2c 20 2f 2a 20 50 6f 69 6e 74 65 72 20  ata, /* Pointer 
7f90: 74 6f 20 73 71 6c 69 74 65 33 5f 65 6e 61 62 6c  to sqlite3_enabl
7fa0: 65 5f 58 58 58 20 66 75 6e 63 74 69 6f 6e 20 2a  e_XXX function *
7fb0: 2f 0a 20 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a  /.  Tcl_Interp *
7fc0: 69 6e 74 65 72 70 2c 20 20 20 20 2f 2a 20 54 68  interp,    /* Th
7fd0: 65 20 54 43 4c 20 69 6e 74 65 72 70 72 65 74 65  e TCL interprete
7fe0: 72 20 74 68 61 74 20 69 6e 76 6f 6b 65 64 20 74  r that invoked t
7ff0: 68 69 73 20 63 6f 6d 6d 61 6e 64 20 2a 2f 0a 20  his command */. 
8000: 20 69 6e 74 20 6f 62 6a 63 2c 20 20 20 20 20 20   int objc,      
8010: 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65          /* Numbe
8020: 72 20 6f 66 20 61 72 67 75 6d 65 6e 74 73 20 2a  r of arguments *
8030: 2f 0a 20 20 54 63 6c 5f 4f 62 6a 20 2a 43 4f 4e  /.  Tcl_Obj *CON
8040: 53 54 20 6f 62 6a 76 5b 5d 20 20 2f 2a 20 43 6f  ST objv[]  /* Co
8050: 6d 6d 61 6e 64 20 61 72 67 75 6d 65 6e 74 73 20  mmand arguments 
8060: 2a 2f 0a 29 7b 0a 20 20 73 71 6c 69 74 65 33 20  */.){.  sqlite3 
8070: 2a 64 62 3b 0a 20 20 45 63 68 6f 4d 6f 64 75 6c  *db;.  EchoModul
8080: 65 20 2a 70 4d 6f 64 3b 0a 20 20 69 66 28 20 6f  e *pMod;.  if( o
8090: 62 6a 63 21 3d 32 20 29 7b 0a 20 20 20 20 54 63  bjc!=2 ){.    Tc
80a0: 6c 5f 57 72 6f 6e 67 4e 75 6d 41 72 67 73 28 69  l_WrongNumArgs(i
80b0: 6e 74 65 72 70 2c 20 31 2c 20 6f 62 6a 76 2c 20  nterp, 1, objv, 
80c0: 22 44 42 22 29 3b 0a 20 20 20 20 72 65 74 75 72  "DB");.    retur
80d0: 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 7d  n TCL_ERROR;.  }
80e0: 0a 20 20 69 66 28 20 67 65 74 44 62 50 6f 69 6e  .  if( getDbPoin
80f0: 74 65 72 28 69 6e 74 65 72 70 2c 20 54 63 6c 5f  ter(interp, Tcl_
8100: 47 65 74 53 74 72 69 6e 67 28 6f 62 6a 76 5b 31  GetString(objv[1
8110: 5d 29 2c 20 26 64 62 29 20 29 20 72 65 74 75 72  ]), &db) ) retur
8120: 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 70  n TCL_ERROR;.  p
8130: 4d 6f 64 20 3d 20 73 71 6c 69 74 65 33 5f 6d 61  Mod = sqlite3_ma
8140: 6c 6c 6f 63 28 73 69 7a 65 6f 66 28 45 63 68 6f  lloc(sizeof(Echo
8150: 4d 6f 64 75 6c 65 29 29 3b 0a 20 20 70 4d 6f 64  Module));.  pMod
8160: 2d 3e 69 6e 74 65 72 70 20 3d 20 69 6e 74 65 72  ->interp = inter
8170: 70 3b 0a 20 20 73 71 6c 69 74 65 33 5f 63 72 65  p;.  sqlite3_cre
8180: 61 74 65 5f 6d 6f 64 75 6c 65 5f 76 32 28 64 62  ate_module_v2(db
8190: 2c 20 22 65 63 68 6f 22 2c 20 26 65 63 68 6f 4d  , "echo", &echoM
81a0: 6f 64 75 6c 65 2c 20 28 76 6f 69 64 2a 29 70 4d  odule, (void*)pM
81b0: 6f 64 2c 20 6d 6f 64 75 6c 65 44 65 73 74 72 6f  od, moduleDestro
81c0: 79 29 3b 0a 20 20 72 65 74 75 72 6e 20 54 43 4c  y);.  return TCL
81d0: 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 63  _OK;.}../*.** Tc
81e0: 6c 20 69 6e 74 65 72 66 61 63 65 20 74 6f 20 73  l interface to s
81f0: 71 6c 69 74 65 33 5f 64 65 63 6c 61 72 65 5f 76  qlite3_declare_v
8200: 74 61 62 2c 20 69 6e 76 6f 6b 65 64 20 61 73 20  tab, invoked as 
8210: 66 6f 6c 6c 6f 77 73 20 66 72 6f 6d 20 54 63 6c  follows from Tcl
8220: 3a 0a 2a 2a 0a 2a 2a 20 73 71 6c 69 74 65 33 5f  :.**.** sqlite3_
8230: 64 65 63 6c 61 72 65 5f 76 74 61 62 20 44 42 20  declare_vtab DB 
8240: 53 51 4c 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  SQL.*/.static in
8250: 74 20 64 65 63 6c 61 72 65 5f 76 74 61 62 28 0a  t declare_vtab(.
8260: 20 20 43 6c 69 65 6e 74 44 61 74 61 20 63 6c 69    ClientData cli
8270: 65 6e 74 44 61 74 61 2c 20 2f 2a 20 50 6f 69 6e  entData, /* Poin
8280: 74 65 72 20 74 6f 20 73 71 6c 69 74 65 33 5f 65  ter to sqlite3_e
8290: 6e 61 62 6c 65 5f 58 58 58 20 66 75 6e 63 74 69  nable_XXX functi
82a0: 6f 6e 20 2a 2f 0a 20 20 54 63 6c 5f 49 6e 74 65  on */.  Tcl_Inte
82b0: 72 70 20 2a 69 6e 74 65 72 70 2c 20 20 20 20 2f  rp *interp,    /
82c0: 2a 20 54 68 65 20 54 43 4c 20 69 6e 74 65 72 70  * The TCL interp
82d0: 72 65 74 65 72 20 74 68 61 74 20 69 6e 76 6f 6b  reter that invok
82e0: 65 64 20 74 68 69 73 20 63 6f 6d 6d 61 6e 64 20  ed this command 
82f0: 2a 2f 0a 20 20 69 6e 74 20 6f 62 6a 63 2c 20 20  */.  int objc,  
8300: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e              /* N
8310: 75 6d 62 65 72 20 6f 66 20 61 72 67 75 6d 65 6e  umber of argumen
8320: 74 73 20 2a 2f 0a 20 20 54 63 6c 5f 4f 62 6a 20  ts */.  Tcl_Obj 
8330: 2a 43 4f 4e 53 54 20 6f 62 6a 76 5b 5d 20 20 2f  *CONST objv[]  /
8340: 2a 20 43 6f 6d 6d 61 6e 64 20 61 72 67 75 6d 65  * Command argume
8350: 6e 74 73 20 2a 2f 0a 29 7b 0a 20 20 73 71 6c 69  nts */.){.  sqli
8360: 74 65 33 20 2a 64 62 3b 0a 20 20 69 6e 74 20 72  te3 *db;.  int r
8370: 63 3b 0a 20 20 69 66 28 20 6f 62 6a 63 21 3d 33  c;.  if( objc!=3
8380: 20 29 7b 0a 20 20 20 20 54 63 6c 5f 57 72 6f 6e   ){.    Tcl_Wron
8390: 67 4e 75 6d 41 72 67 73 28 69 6e 74 65 72 70 2c  gNumArgs(interp,
83a0: 20 31 2c 20 6f 62 6a 76 2c 20 22 44 42 20 53 51   1, objv, "DB SQ
83b0: 4c 22 29 3b 0a 20 20 20 20 72 65 74 75 72 6e 20  L");.    return 
83c0: 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a 20  TCL_ERROR;.  }. 
83d0: 20 69 66 28 20 67 65 74 44 62 50 6f 69 6e 74 65   if( getDbPointe
83e0: 72 28 69 6e 74 65 72 70 2c 20 54 63 6c 5f 47 65  r(interp, Tcl_Ge
83f0: 74 53 74 72 69 6e 67 28 6f 62 6a 76 5b 31 5d 29  tString(objv[1])
8400: 2c 20 26 64 62 29 20 29 20 72 65 74 75 72 6e 20  , &db) ) return 
8410: 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 72 63 20  TCL_ERROR;.  rc 
8420: 3d 20 73 71 6c 69 74 65 33 5f 64 65 63 6c 61 72  = sqlite3_declar
8430: 65 5f 76 74 61 62 28 64 62 2c 20 54 63 6c 5f 47  e_vtab(db, Tcl_G
8440: 65 74 53 74 72 69 6e 67 28 6f 62 6a 76 5b 32 5d  etString(objv[2]
8450: 29 29 3b 0a 20 20 69 66 28 20 72 63 21 3d 53 51  ));.  if( rc!=SQ
8460: 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 54  LITE_OK ){.    T
8470: 63 6c 5f 53 65 74 52 65 73 75 6c 74 28 69 6e 74  cl_SetResult(int
8480: 65 72 70 2c 20 28 63 68 61 72 20 2a 29 73 71 6c  erp, (char *)sql
8490: 69 74 65 33 5f 65 72 72 6d 73 67 28 64 62 29 2c  ite3_errmsg(db),
84a0: 20 54 43 4c 5f 56 4f 4c 41 54 49 4c 45 29 3b 0a   TCL_VOLATILE);.
84b0: 20 20 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 45      return TCL_E
84c0: 52 52 4f 52 3b 0a 20 20 7d 0a 20 20 72 65 74 75  RROR;.  }.  retu
84d0: 72 6e 20 54 43 4c 5f 4f 4b 3b 0a 7d 0a 0a 23 65  rn TCL_OK;.}..#e
84e0: 6e 64 69 66 20 2f 2a 20 69 66 6e 64 65 66 20 53  ndif /* ifndef S
84f0: 51 4c 49 54 45 5f 4f 4d 49 54 5f 56 49 52 54 55  QLITE_OMIT_VIRTU
8500: 41 4c 54 41 42 4c 45 20 2a 2f 0a 0a 2f 2a 0a 2a  ALTABLE */../*.*
8510: 2a 20 52 65 67 69 73 74 65 72 20 63 6f 6d 6d 61  * Register comma
8520: 6e 64 73 20 77 69 74 68 20 74 68 65 20 54 43 4c  nds with the TCL
8530: 20 69 6e 74 65 72 70 72 65 74 65 72 2e 0a 2a 2f   interpreter..*/
8540: 0a 69 6e 74 20 53 71 6c 69 74 65 74 65 73 74 38  .int Sqlitetest8
8550: 5f 49 6e 69 74 28 54 63 6c 5f 49 6e 74 65 72 70  _Init(Tcl_Interp
8560: 20 2a 69 6e 74 65 72 70 29 7b 0a 20 20 73 74 61   *interp){.  sta
8570: 74 69 63 20 73 74 72 75 63 74 20 7b 0a 20 20 20  tic struct {.   
8580: 20 20 63 68 61 72 20 2a 7a 4e 61 6d 65 3b 0a 20    char *zName;. 
8590: 20 20 20 20 54 63 6c 5f 4f 62 6a 43 6d 64 50 72      Tcl_ObjCmdPr
85a0: 6f 63 20 2a 78 50 72 6f 63 3b 0a 20 20 20 20 20  oc *xProc;.     
85b0: 76 6f 69 64 20 2a 63 6c 69 65 6e 74 44 61 74 61  void *clientData
85c0: 3b 0a 20 20 7d 20 61 4f 62 6a 43 6d 64 5b 5d 20  ;.  } aObjCmd[] 
85d0: 3d 20 7b 0a 23 69 66 6e 64 65 66 20 53 51 4c 49  = {.#ifndef SQLI
85e0: 54 45 5f 4f 4d 49 54 5f 56 49 52 54 55 41 4c 54  TE_OMIT_VIRTUALT
85f0: 41 42 4c 45 0a 20 20 20 20 20 7b 20 22 72 65 67  ABLE.     { "reg
8600: 69 73 74 65 72 5f 65 63 68 6f 5f 6d 6f 64 75 6c  ister_echo_modul
8610: 65 22 2c 20 20 20 72 65 67 69 73 74 65 72 5f 65  e",   register_e
8620: 63 68 6f 5f 6d 6f 64 75 6c 65 2c 20 30 20 7d 2c  cho_module, 0 },
8630: 0a 20 20 20 20 20 7b 20 22 73 71 6c 69 74 65 33  .     { "sqlite3
8640: 5f 64 65 63 6c 61 72 65 5f 76 74 61 62 22 2c 20  _declare_vtab", 
8650: 20 20 64 65 63 6c 61 72 65 5f 76 74 61 62 2c 20    declare_vtab, 
8660: 30 20 7d 2c 0a 23 65 6e 64 69 66 0a 20 20 7d 3b  0 },.#endif.  };
8670: 0a 20 20 69 6e 74 20 69 3b 0a 20 20 66 6f 72 28  .  int i;.  for(
8680: 69 3d 30 3b 20 69 3c 73 69 7a 65 6f 66 28 61 4f  i=0; i<sizeof(aO
8690: 62 6a 43 6d 64 29 2f 73 69 7a 65 6f 66 28 61 4f  bjCmd)/sizeof(aO
86a0: 62 6a 43 6d 64 5b 30 5d 29 3b 20 69 2b 2b 29 7b  bjCmd[0]); i++){
86b0: 0a 20 20 20 20 54 63 6c 5f 43 72 65 61 74 65 4f  .    Tcl_CreateO
86c0: 62 6a 43 6f 6d 6d 61 6e 64 28 69 6e 74 65 72 70  bjCommand(interp
86d0: 2c 20 61 4f 62 6a 43 6d 64 5b 69 5d 2e 7a 4e 61  , aObjCmd[i].zNa
86e0: 6d 65 2c 20 0a 20 20 20 20 20 20 20 20 61 4f 62  me, .        aOb
86f0: 6a 43 6d 64 5b 69 5d 2e 78 50 72 6f 63 2c 20 61  jCmd[i].xProc, a
8700: 4f 62 6a 43 6d 64 5b 69 5d 2e 63 6c 69 65 6e 74  ObjCmd[i].client
8710: 44 61 74 61 2c 20 30 29 3b 0a 20 20 7d 0a 20 20  Data, 0);.  }.  
8720: 72 65 74 75 72 6e 20 54 43 4c 5f 4f 4b 3b 0a 7d  return TCL_OK;.}
8730: 0a                                               .